Imported Upstream version 2.1.0 upstream/2.1.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 06:59:53 +0000 (15:59 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 06:59:53 +0000 (15:59 +0900)
639 files changed:
.gitignore
ABOUT-NLS
AUTHORS
ChangeLog-2011
Makefile.am
NEWS
README
README.GIT
README.maint
THANKS
acinclude.m4
agent/ChangeLog-2011
agent/Makefile.am
agent/agent.h
agent/cache.c
agent/call-pinentry.c
agent/call-scd.c
agent/command-ssh.c
agent/command.c
agent/cvt-openpgp.c [new file with mode: 0644]
agent/cvt-openpgp.h [new file with mode: 0644]
agent/divert-scd.c
agent/findkey.c
agent/genkey.c
agent/gpg-agent.c
agent/keyformat.txt
agent/learncard.c
agent/pkdecrypt.c
agent/pksign.c
agent/preset-passphrase.c
agent/protect-tool.c
agent/protect.c
agent/t-protect.c
agent/trustlist.c
agent/w32main.c
am/cmacros.am
announce.txt [deleted file]
artwork/gnupg-badge-128x128.png [new file with mode: 0644]
artwork/gnupg-lock-20x25tr.png [new file with mode: 0644]
artwork/gnupg-lock-80x100tr.png [new file with mode: 0644]
artwork/gnupg-logo-180x59tr.png [new file with mode: 0644]
artwork/gnupg-logo-320x100tr.png [new file with mode: 0644]
artwork/gnupg-logo-420x135tr.png [new file with mode: 0644]
artwork/gnupg-logo-80x25tr.png [new file with mode: 0644]
autogen.rc [new file with mode: 0644]
autogen.sh
build-aux/ChangeLog-2011 [moved from scripts/ChangeLog-2011 with 66% similarity]
build-aux/build-all.sh [new file with mode: 0755]
build-aux/compile [new file with mode: 0755]
build-aux/config.guess [moved from scripts/config.guess with 85% similarity]
build-aux/config.rpath [moved from scripts/config.rpath with 88% similarity]
build-aux/config.sub [moved from scripts/config.sub with 91% similarity]
build-aux/depcomp [new file with mode: 0755]
build-aux/getswdb.sh [new file with mode: 0755]
build-aux/git-hooks/commit-msg [moved from scripts/git-hooks/commit-msg with 100% similarity]
build-aux/git-log-fix [new file with mode: 0644]
build-aux/git-log-footer [moved from scripts/git-log-footer with 67% similarity]
build-aux/gitlog-to-changelog [new file with mode: 0755]
build-aux/install-sh [moved from scripts/install-sh with 69% similarity]
build-aux/mail-to-translators [moved from scripts/mail-to-translators with 75% similarity]
build-aux/mdate-sh [moved from scripts/mdate-sh with 80% similarity]
build-aux/missing [new file with mode: 0755]
build-aux/mkinstalldirs [moved from scripts/mkinstalldirs with 93% similarity]
build-aux/potomo [new file with mode: 0755]
build-aux/speedo.mk [new file with mode: 0644]
build-aux/speedo/patches/atk-1.32.0.patch [new file with mode: 0755]
build-aux/speedo/patches/libiconv-1.14.patch [new file with mode: 0755]
build-aux/speedo/patches/pango-1.29.4.patch [new file with mode: 0755]
build-aux/speedo/w32/README.txt [new file with mode: 0644]
build-aux/speedo/w32/exdll.h [new file with mode: 0644]
build-aux/speedo/w32/g4wihelp.c [new file with mode: 0644]
build-aux/speedo/w32/gdk-pixbuf-loaders.cache [new file with mode: 0755]
build-aux/speedo/w32/inst-options.ini [new file with mode: 0644]
build-aux/speedo/w32/inst.nsi [new file with mode: 0644]
build-aux/speedo/w32/pango.modules [new file with mode: 0755]
build-aux/speedo/w32/pkg-copyright.txt [new file with mode: 0644]
build-aux/speedo/zlib.pc [new file with mode: 0644]
build-aux/texinfo.tex [moved from scripts/texinfo.tex with 99% similarity]
common/ChangeLog-2011
common/ChangeLog-2011.include [moved from include/ChangeLog-2011 with 95% similarity]
common/ChangeLog.jnlib [moved from jnlib/ChangeLog-2011 with 90% similarity]
common/Makefile.am
common/README.jnlib [new file with mode: 0644]
common/agent-opt.c [new file with mode: 0644]
common/argparse.c [moved from jnlib/argparse.c with 87% similarity]
common/argparse.h [moved from jnlib/argparse.h with 88% similarity]
common/asshelp.c
common/asshelp.h
common/asshelp2.c [new file with mode: 0644]
common/audit.c
common/audit.h
common/b64dec.c
common/b64enc.c
common/convert.c
common/dns-cert.c
common/dns-cert.h
common/dotlock.c [new file with mode: 0644]
common/dotlock.h [new file with mode: 0644]
common/dynload.h [new file with mode: 0644]
common/estream-printf.c [deleted file]
common/estream-printf.h [deleted file]
common/estream.c [deleted file]
common/estream.h [deleted file]
common/exaudit.awk
common/exechelp-posix.c [new file with mode: 0644]
common/exechelp-w32.c [moved from common/exechelp.c with 50% similarity]
common/exechelp-w32ce.c [new file with mode: 0644]
common/exechelp.h
common/exstatus.awk
common/gc-opt-flags.h
common/get-passphrase.c
common/get-passphrase.h
common/gettime.c
common/gettime.h [new file with mode: 0644]
common/gpgrlhelp.c
common/helpfile.c
common/homedir.c
common/host2net.h [moved from include/host2net.h with 51% similarity]
common/http.c
common/http.h
common/i18n.c
common/i18n.h
common/init.c
common/init.h
common/iobuf.c
common/iobuf.h
common/keyserver.h
common/libjnlib-config.h [moved from jnlib/libjnlib-config.h with 64% similarity]
common/localename.c
common/logging.c [new file with mode: 0644]
common/logging.h [moved from jnlib/logging.h with 66% similarity]
common/mapstrings.c [new file with mode: 0644]
common/membuf.c
common/membuf.h
common/miscellaneous.c
common/mischelp.c [moved from jnlib/mischelp.c with 55% similarity]
common/mischelp.h [moved from jnlib/mischelp.h with 66% similarity]
common/mkerrors
common/mkerrtok
common/mkstrtable.awk
common/openpgp-oid.c [new file with mode: 0644]
common/openpgpdefs.h
common/percent.c
common/pka.c
common/pka.h
common/session-env.c
common/session-env.h
common/sexp-parse.h
common/sexputil.c
common/shareddefs.h [new file with mode: 0644]
common/signal.c
common/simple-pwquery.c
common/simple-pwquery.h
common/srv.c
common/srv.h
common/ssh-utils.c
common/ssh-utils.h
common/status.c
common/status.h
common/stringhelp.c [moved from jnlib/stringhelp.c with 83% similarity]
common/stringhelp.h [moved from jnlib/stringhelp.h with 79% similarity]
common/strlist.c [moved from jnlib/strlist.c with 75% similarity]
common/strlist.h [moved from jnlib/strlist.h with 59% similarity]
common/sysutils.c
common/sysutils.h
common/t-b64.c
common/t-convert.c
common/t-dns-cert.c [new file with mode: 0644]
common/t-dotlock.c [new file with mode: 0644]
common/t-exechelp.c
common/t-gettime.c
common/t-helpfile.c
common/t-http.c [new file with mode: 0644]
common/t-mapstrings.c [new file with mode: 0644]
common/t-openpgp-oid.c [new file with mode: 0644]
common/t-percent.c
common/t-session-env.c
common/t-sexputil.c
common/t-ssh-utils.c
common/t-stringhelp.c [moved from jnlib/t-stringhelp.c with 80% similarity]
common/t-support.c [moved from jnlib/t-support.c with 71% similarity]
common/t-support.h [moved from jnlib/t-support.h with 57% similarity]
common/t-sysutils.c
common/t-timestuff.c [new file with mode: 0644]
common/t-w32-reg.c [new file with mode: 0644]
common/t-zb32.c [new file with mode: 0644]
common/tls-ca.pem [new file with mode: 0644]
common/tlv.c
common/tlv.h
common/ttyio.c
common/ttyio.h
common/types.h [moved from jnlib/types.h with 60% similarity]
common/userids.c [new file with mode: 0644]
common/userids.h [new file with mode: 0644]
common/utf8conv.c [moved from jnlib/utf8conv.c with 81% similarity]
common/utf8conv.h [moved from jnlib/utf8conv.h with 53% similarity]
common/util.h
common/w32-afunix.c [moved from jnlib/w32-afunix.c with 72% similarity]
common/w32-afunix.h [moved from jnlib/w32-afunix.h with 55% similarity]
common/w32-reg.c [moved from jnlib/w32-reg.c with 61% similarity]
common/w32help.h [new file with mode: 0644]
common/xasprintf.c
common/xmalloc.c [moved from jnlib/xmalloc.c with 69% similarity]
common/xmalloc.h [new file with mode: 0644]
common/xreadline.c
common/yesno.c
configure.ac
dirmngr/ChangeLog-2011 [new file with mode: 0644]
dirmngr/ChangeLog.1 [new file with mode: 0644]
dirmngr/Makefile.am [new file with mode: 0644]
dirmngr/OAUTHORS [new file with mode: 0644]
dirmngr/ONEWS [new file with mode: 0644]
dirmngr/cdb.h [new file with mode: 0644]
dirmngr/cdblib.c [new file with mode: 0644]
dirmngr/certcache.c [new file with mode: 0644]
dirmngr/certcache.h [new file with mode: 0644]
dirmngr/crlcache.c [new file with mode: 0644]
dirmngr/crlcache.h [new file with mode: 0644]
dirmngr/crlfetch.c [new file with mode: 0644]
dirmngr/crlfetch.h [new file with mode: 0644]
dirmngr/dirmngr-client.c [new file with mode: 0644]
dirmngr/dirmngr-err.h [new file with mode: 0644]
dirmngr/dirmngr.c [new file with mode: 0644]
dirmngr/dirmngr.h [new file with mode: 0644]
dirmngr/dirmngr_ldap.c [new file with mode: 0644]
dirmngr/ks-action.c [new file with mode: 0644]
dirmngr/ks-action.h [new file with mode: 0644]
dirmngr/ks-engine-finger.c [new file with mode: 0644]
dirmngr/ks-engine-hkp.c [new file with mode: 0644]
dirmngr/ks-engine-http.c [new file with mode: 0644]
dirmngr/ks-engine-kdns.c [new file with mode: 0644]
dirmngr/ks-engine.h [new file with mode: 0644]
dirmngr/ldap-url.c [new file with mode: 0644]
dirmngr/ldap-url.h [new file with mode: 0644]
dirmngr/ldap-wrapper-ce.c [new file with mode: 0644]
dirmngr/ldap-wrapper.c [new file with mode: 0644]
dirmngr/ldap-wrapper.h [new file with mode: 0644]
dirmngr/ldap.c [new file with mode: 0644]
dirmngr/ldapserver.c [new file with mode: 0644]
dirmngr/ldapserver.h [new file with mode: 0644]
dirmngr/misc.c [new file with mode: 0644]
dirmngr/misc.h [new file with mode: 0644]
dirmngr/ocsp.c [new file with mode: 0644]
dirmngr/ocsp.h [new file with mode: 0644]
dirmngr/server.c [new file with mode: 0644]
dirmngr/sks-keyservers.netCA.pem [new file with mode: 0644]
dirmngr/validate.c [new file with mode: 0644]
dirmngr/validate.h [new file with mode: 0644]
dirmngr/w32-ldap-help.h [new file with mode: 0644]
doc/ChangeLog-2011
doc/DCO [new file with mode: 0644]
doc/DETAILS
doc/HACKING
doc/Makefile.am
doc/OpenPGP
doc/TRANSLATE
doc/com-certs.pem
doc/debugging.texi
doc/dirmngr.texi [new file with mode: 0644]
doc/faq.org [new file with mode: 0644]
doc/faq.raw [deleted file]
doc/gnupg-logo-tr.png [new file with mode: 0644]
doc/gnupg-logo.pdf
doc/gnupg-logo.png
doc/gnupg.texi
doc/gpg-agent.texi
doc/gpg.texi
doc/gpgsm.texi
doc/gpgv.texi
doc/help.ru.txt
doc/instguide.texi
doc/mksamplekeys [new file with mode: 0755]
doc/opt-homedir.texi
doc/scdaemon.texi
doc/specify-user-id.texi
doc/texi.css [new file with mode: 0644]
doc/tools.texi
doc/vuln-announce-2010-kbx-realloc.txt [new file with mode: 0644]
doc/whats-new-in-2.1.txt [new file with mode: 0644]
doc/yat2m.c
g10/ChangeLog-2011
g10/Makefile.am
g10/armor.c
g10/build-packet.c
g10/call-agent.c
g10/call-agent.h
g10/call-dirmngr.c [new file with mode: 0644]
g10/call-dirmngr.h [new file with mode: 0644]
g10/card-util.c
g10/cipher.c
g10/comment.c
g10/compress-bz2.c
g10/compress.c
g10/cpr.c
g10/dearmor.c
g10/decrypt-data.c [moved from g10/encr-data.c with 72% similarity]
g10/decrypt.c
g10/dek.h [new file with mode: 0644]
g10/delkey.c
g10/distsigkey.gpg [new file with mode: 0644]
g10/ecdh.c [new file with mode: 0644]
g10/encode.c [deleted file]
g10/encrypt.c [new file with mode: 0644]
g10/exec.c
g10/export.c
g10/filter.h
g10/free-packet.c
g10/getkey.c
g10/gpg.c
g10/gpg.h
g10/gpgv.c
g10/helptext.c
g10/import.c
g10/kbnode.c
g10/keydb.c
g10/keydb.h
g10/keyedit.c
g10/keygen.c
g10/keyid.c
g10/keylist.c
g10/keyring.c
g10/keyring.h
g10/keyserver-internal.h
g10/keyserver.c
g10/main.h
g10/mainproc.c
g10/mdfilter.c
g10/migrate.c [new file with mode: 0644]
g10/misc.c
g10/openfile.c
g10/options.h
g10/options.skel
g10/packet.h
g10/parse-packet.c
g10/passphrase.c
g10/photoid.c
g10/photoid.h
g10/pkclist.c
g10/pkglue.c
g10/pkglue.h
g10/plaintext.c
g10/progress.c
g10/pubkey-enc.c
g10/revoke.c
g10/rmd160.c
g10/seckey-cert.c
g10/server.c
g10/seskey.c
g10/sig-check.c
g10/sign.c
g10/signal.c
g10/skclist.c
g10/t-rmd160.c
g10/tdbdump.c
g10/tdbio.c
g10/textfilter.c
g10/trust.c [new file with mode: 0644]
g10/trustdb.c
g10/trustdb.h
g10/verify.c
g10/zlib-riscos.h [moved from include/zlib-riscos.h with 100% similarity]
g13/ChangeLog-2011 [new file with mode: 0644]
g13/Makefile.am [new file with mode: 0644]
g13/backend.c [new file with mode: 0644]
g13/backend.h [new file with mode: 0644]
g13/be-encfs.c [new file with mode: 0644]
g13/be-encfs.h [new file with mode: 0644]
g13/be-truecrypt.c [new file with mode: 0644]
g13/be-truecrypt.h [new file with mode: 0644]
g13/call-gpg.c [new file with mode: 0644]
g13/call-gpg.h [new file with mode: 0644]
g13/create.c [new file with mode: 0644]
g13/create.h [new file with mode: 0644]
g13/encfs-1.5_annotate.diff [new file with mode: 0644]
g13/encfs-1.7.3_annotate.diff [new file with mode: 0644]
g13/g13.c [new file with mode: 0644]
g13/g13.h [new file with mode: 0644]
g13/keyblob.h [new file with mode: 0644]
g13/mount.c [new file with mode: 0644]
g13/mount.h [new file with mode: 0644]
g13/mountinfo.c [new file with mode: 0644]
g13/mountinfo.h [new file with mode: 0644]
g13/runner.c [new file with mode: 0644]
g13/runner.h [new file with mode: 0644]
g13/server.c [new file with mode: 0644]
g13/server.h [new file with mode: 0644]
g13/utils.c [new file with mode: 0644]
g13/utils.h [new file with mode: 0644]
gl/Makefile.am
gl/mkdtemp.c
gl/setenv.c
gl/stdint_.h
gl/unsetenv.c
include/Makefile.am [deleted file]
include/_regex.h [deleted file]
include/cipher.h [deleted file]
include/types.h [deleted file]
jnlib/Makefile.am [deleted file]
jnlib/README [deleted file]
jnlib/dotlock.c [deleted file]
jnlib/dotlock.h [deleted file]
jnlib/dynload.h [deleted file]
jnlib/logging.c [deleted file]
jnlib/w32-gettext.c [deleted file]
jnlib/w32help.h [deleted file]
jnlib/xmalloc.h [deleted file]
kbx/ChangeLog-2011
kbx/Makefile.am
kbx/kbxutil.c
kbx/keybox-blob.c
kbx/keybox-defs.h
kbx/keybox-dump.c
kbx/keybox-errors.c
kbx/keybox-file.c
kbx/keybox-init.c
kbx/keybox-openpgp.c
kbx/keybox-search-desc.h
kbx/keybox-search.c
kbx/keybox-update.c
kbx/keybox-util.c
kbx/keybox.h
kbx/mkerrors
keyserver/ChangeLog-2011
keyserver/Makefile.am [deleted file]
keyserver/curl-shim.c
keyserver/curl-shim.h
keyserver/gpgkeys_curl.c
keyserver/gpgkeys_finger.c
keyserver/gpgkeys_hkp.c
keyserver/gpgkeys_kdns.c
keyserver/gpgkeys_ldap.c
keyserver/ksutil.c
m4/ChangeLog-2011
m4/Makefile.am
m4/estream.m4 [deleted file]
m4/gettext.m4
m4/gnupg-pth.m4
m4/gpg-error.m4
m4/iconv.m4
m4/ldap.m4
m4/lib-ld.m4
m4/lib-link.m4
m4/lib-prefix.m4
m4/libcurl.m4
m4/nls.m4
m4/npth.m4 [new file with mode: 0644]
m4/ntbtls.m4 [new file with mode: 0644]
m4/po.m4
m4/progtest.m4
m4/readline.m4
po/ChangeLog-2011
po/LINGUAS
po/Makefile.in.in
po/Makevars
po/Makevars.template [new file with mode: 0644]
po/POTFILES.in
po/Rules-quot
po/be.po
po/ca.po
po/cs.po
po/da.po
po/de.po
po/el.po
po/eo.po
po/es.po
po/et.po
po/fi.po
po/fr.po
po/gl.po
po/hu.po
po/id.po
po/it.po
po/ja.po
po/nb.po
po/nl.po [deleted file]
po/pl.po
po/pt.po
po/pt_BR.po
po/ro.po
po/ru.po
po/sk.po
po/sv.po
po/tr.po
po/uk.po
po/zh_CN.po
po/zh_TW.po
scd/ChangeLog-2011
scd/Makefile.am
scd/apdu.c
scd/apdu.h
scd/app-common.h
scd/app-dinsig.c
scd/app-geldkarte.c
scd/app-help.c
scd/app-nks.c
scd/app-openpgp.c
scd/app-p15.c
scd/app-sc-hsm.c [new file with mode: 0644]
scd/app.c
scd/atr.c
scd/atr.h
scd/card-common.h
scd/card-dinsig.c
scd/card-p15.c
scd/card.c
scd/ccid-driver.c
scd/ccid-driver.h
scd/command.c
scd/iso7816.c
scd/iso7816.h
scd/pcsc-wrapper.c
scd/sc-copykeys.c
scd/scdaemon.c
scd/scdaemon.h
scripts/compile [deleted file]
scripts/depcomp [deleted file]
scripts/git-log-fix [deleted file]
scripts/missing [deleted file]
sm/ChangeLog-2011
sm/Makefile.am
sm/base64.c
sm/call-agent.c
sm/call-dirmngr.c
sm/certchain.c
sm/certcheck.c
sm/certdump.c
sm/certlist.c
sm/certreqgen-ui.c
sm/certreqgen.c
sm/decrypt.c
sm/delete.c
sm/encrypt.c
sm/export.c
sm/fingerprint.c
sm/gpgsm.c
sm/gpgsm.h
sm/import.c
sm/keydb.c
sm/keydb.h
sm/keylist.c
sm/minip12.c [moved from agent/minip12.c with 80% similarity]
sm/minip12.h [moved from agent/minip12.h with 82% similarity]
sm/misc.c
sm/qualified.c
sm/server.c
sm/sign.c
sm/verify.c
tests/ChangeLog-2011
tests/Makefile.am
tests/asschk.c
tests/inittests
tests/openpgp/ChangeLog-2011
tests/openpgp/Makefile.am
tests/openpgp/armencrypt.test
tests/openpgp/armencryptp.test
tests/openpgp/armor.test
tests/openpgp/armsignencrypt.test
tests/openpgp/bug1223-bogus.asc [new file with mode: 0644]
tests/openpgp/bug1223-good.asc [new file with mode: 0644]
tests/openpgp/clearsig.test
tests/openpgp/conventional-mdc.test
tests/openpgp/conventional.test
tests/openpgp/decrypt-dsa.test
tests/openpgp/decrypt.test
tests/openpgp/defs.inc
tests/openpgp/ecc.test [new file with mode: 0755]
tests/openpgp/encrypt-dsa.test
tests/openpgp/encrypt.test
tests/openpgp/encryptp.test
tests/openpgp/finish.test [new file with mode: 0755]
tests/openpgp/genkey1024.test
tests/openpgp/gpg-agent.conf.tmpl
tests/openpgp/gpg.conf.tmpl
tests/openpgp/import.test
tests/openpgp/mds.test
tests/openpgp/mkdemodirs
tests/openpgp/multisig.test
tests/openpgp/pinentry.sh [new file with mode: 0755]
tests/openpgp/privkeys/0D6F6AD4C4C803B25470F9104E9F4E6A4CA64255.asc [new file with mode: 0644]
tests/openpgp/privkeys/0DD40284FF992CD24DC4AAC367037E066FCEE26A.asc [new file with mode: 0644]
tests/openpgp/privkeys/13FDB8809B17C5547779F9D205C45F47CE0217CE.asc [new file with mode: 0644]
tests/openpgp/privkeys/343D8AF79796EE107D645A2787A9D9252F924E6F.asc [new file with mode: 0644]
tests/openpgp/privkeys/50B2D4FA4122C212611048BC5FC31BD44393626E.asc [new file with mode: 0644]
tests/openpgp/privkeys/76F7E2B35832976B50A27A282D9B87E44577EB66.asc [new file with mode: 0644]
tests/openpgp/privkeys/7E201E28B6FEB2927B321F443205F4724EBE637E.asc [new file with mode: 0644]
tests/openpgp/privkeys/8B5ABF3EF9EB8D96B91A0B8C2C4401C91C834C34.asc [new file with mode: 0644]
tests/openpgp/privkeys/A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD.asc [new file with mode: 0644]
tests/openpgp/privkeys/FD692BD59D6640A84C8422573D469F84F3B98E53.asc [new file with mode: 0644]
tests/openpgp/samplekeys/README
tests/openpgp/samplekeys/dda252ebb8ebe1af-1.asc [new file with mode: 0644]
tests/openpgp/samplekeys/dda252ebb8ebe1af-2.asc [new file with mode: 0644]
tests/openpgp/samplekeys/ecc-sample-1-pub.asc [new file with mode: 0644]
tests/openpgp/samplekeys/ecc-sample-1-sec.asc [new file with mode: 0644]
tests/openpgp/samplekeys/ecc-sample-2-pub.asc [new file with mode: 0644]
tests/openpgp/samplekeys/ecc-sample-2-sec.asc [new file with mode: 0644]
tests/openpgp/samplekeys/ecc-sample-3-pub.asc [new file with mode: 0644]
tests/openpgp/samplekeys/ecc-sample-3-sec.asc [new file with mode: 0644]
tests/openpgp/samplekeys/eddsa-sample-1-pub.asc [new file with mode: 0644]
tests/openpgp/samplekeys/eddsa-sample-1-sec.asc [new file with mode: 0644]
tests/openpgp/seat.test
tests/openpgp/signencrypt-dsa.test
tests/openpgp/signencrypt.test
tests/openpgp/sigs-dsa.test
tests/openpgp/sigs.test
tests/openpgp/version.test
tests/pkits/ChangeLog-2011
tests/pkits/PKITS_data.tar.bz2 [new file with mode: 0644]
tests/runtest
tests/samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key [new file with mode: 0644]
tests/samplekeys/README
tests/samplekeys/cert-with-117-akas.pem [new file with mode: 0644]
tests/samplekeys/steed-self-signing-nonthority.pem [new file with mode: 0644]
tools/ChangeLog-2011
tools/Makefile.am
tools/addgnupghome
tools/applygnupgdefaults
tools/ccidmon.c
tools/clean-sat.c
tools/gpg-check-pattern.c
tools/gpg-connect-agent.c
tools/gpgconf-comp.c
tools/gpgconf.c
tools/gpgconf.h
tools/gpgkey2ssh.c
tools/gpgparsemail.c
tools/gpgsplit.c
tools/gpgtar-create.c
tools/gpgtar-extract.c
tools/gpgtar-list.c
tools/gpgtar.c
tools/gpgtar.h
tools/mail-signed-keys
tools/mk-tdata.c
tools/no-libgcrypt.c
tools/rfc822parse.c
tools/rfc822parse.h
tools/sockprox.c
tools/symcryptrun.c
tools/watchgnupg.c

index 65141e3..a525f14 100644 (file)
@@ -21,6 +21,7 @@ keyserver/gpg2keys_test
 tools/gpg-zip
 
 # Files created by make when not using a VPATH build
+PLAY/
 *.o
 po/en@boldquot.insert-header
 po/en@boldquot.po
@@ -28,11 +29,11 @@ po/en@quot.insert-header
 po/en@quot.po
 po/stamp-po
 po/remove-potcdate.sed
+po/gnupg.pot
 agent/gpg-agent
 agent/gpg-preset-passphrase
 agent/gpg-protect-tool
 agent/t-protect
-agent/t-ssh-utils
 common/libcommon.a
 common/libcommonpth.a
 common/libgpgrl.a
@@ -46,7 +47,11 @@ common/t-percent
 common/t-session-env
 common/t-sexputil
 common/t-sysutils
+common/t-stringhelp
+common/t-timestuff
 common/t-ssh-utils
+common/t-dns-cert
+common/t-openpgp-oid
 doc/addgnupghome.8
 doc/applygnupgdefaults.8
 doc/faq.html
@@ -66,6 +71,8 @@ doc/gpgsm-gencert.sh.1
 doc/gpgsm.1
 doc/gpgv2.1
 doc/scdaemon.1
+doc/dirmngr-client.1
+doc/dirmngr.8
 doc/symcryptrun.1
 doc/watchgnupg.1
 doc/yat2m
@@ -87,10 +94,20 @@ keyserver/gpg2keys_ldap
 scd/gnupg-pcsc-wrapper
 scd/scdaemon
 sm/gpgsm
+g13/g13
+dirmngr/dirmngr
+dirmngr/dirmngr-client
+dirmngr/dirmngr_ldap
+dirmngr/no-libgcrypt.c
 tests/asschk
 tests/gpg-agent.conf
+tests/gpg.conf
 tests/gpgsm.conf
 tests/inittests.stamp
+tests/private-keys-v1.d/
+tests/pubring.kbx
+tests/testdir.stamp
+tests/trustlist.txt
 tests/openpgp/data-32000
 tests/openpgp/data-500
 tests/openpgp/data-80000
@@ -106,11 +123,12 @@ tests/openpgp/pubring.gpg
 tests/openpgp/pubring.pkr
 tests/openpgp/secring.gpg
 tests/openpgp/secring.skr
+tests/openpgp/private-keys-v1.d/
 tests/openpgp/*.log
 tests/openpgp/trustdb.gpg
-tests/openpgp/z
 tests/openpgp/gpg.conf
 tests/openpgp/random_seed
+tests/openpgp/z
 tests/pkits/ReadMe.txt
 tests/pkits/certpairs/
 tests/pkits/certs/
@@ -125,10 +143,6 @@ tests/pkits/policies.txt
 tests/pkits/smime/
 tests/pkits/testdir.stamp
 tests/pkits/trustlist.txt
-tests/private-keys-v1.d/
-tests/pubring.kbx
-tests/testdir.stamp
-tests/trustlist.txt
 tools/clean-sat
 tools/gpg-check-pattern
 tools/gpg-connect-agent
@@ -141,5 +155,8 @@ tools/mk-tdata
 tools/symcryptrun
 tools/watchgnupg
 tools/gpgtar
-/doc/gnupg1.info
-/po/gnupg.pot
+private-keys-v1.d/
+x.parm
+/VERSION
+/swdb.lst
+/swdb.lst.sig
index b1de1b6..83bc72e 100644 (file)
--- a/ABOUT-NLS
+++ b/ABOUT-NLS
@@ -18,7 +18,35 @@ explain how users should proceed for getting the programs to use the
 available translations.  They tell how people wanting to contribute and
 work on translations can contact the appropriate team.
 
-1.1 INSTALL Matters
+   When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used.  The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+1.1 Quick configuration advice
+==============================
+
+If you want to exploit the full power of internationalization, you
+should configure it using
+
+     ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed.  So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias, message inheritance, automatic
+charset conversion or plural form handling) as the implementation here.
+It is also not possible to offer this additional functionality on top
+of a `catgets' implementation.  Future versions of GNU `gettext' will
+very likely convey even more functionality.  So it might be a good idea
+to change to GNU `gettext' as soon as possible.
+
+   So you need _not_ provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+1.2 INSTALL Matters
 ===================
 
 Some packages are "localizable" when properly installed; the programs
@@ -28,19 +56,36 @@ internationalization, predating GNU `gettext'.
 
    By default, this package will be installed to allow translation of
 messages.  It will automatically detect whether the system already
-provides the GNU `gettext' functions.  Installers may use special
-options at configuration time for changing the default behaviour.  The
-command:
+provides the GNU `gettext' functions.  If not, the included GNU
+`gettext' library will be used.  This library is wholly contained
+within this package, usually in the `intl/' subdirectory, so prior
+installation of the GNU `gettext' package is _not_ required.
+Installers may use special options at configuration time for changing
+the default behaviour.  The commands:
 
+     ./configure --with-included-gettext
      ./configure --disable-nls
 
-will _totally_ disable translation of messages.
+will, respectively, bypass any pre-existing `gettext' to use the
+internationalizing routines provided within this package, or else,
+_totally_ disable translation of messages.
 
    When you already have GNU `gettext' installed on your system and run
 configure without an option for your new package, `configure' will
-probably detect the previously built and installed `libintl' library
-and will decide to use it.  If not, you may have to to use the
-`--with-libintl-prefix' option to tell `configure' where to look for it.
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this.  This might not be desirable.  You should use
+the more recent version of the GNU `gettext' library.  I.e. if the file
+`intl/VERSION' shows that the library which comes with this package is
+more recent, you should use
+
+     ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+   The configuration process will not test for the `catgets' function
+and therefore it will not be used.  The reason is that even an
+emulation of `gettext' on top of `catgets' could not provide all the
+extensions of the GNU `gettext' library.
 
    Internationalized packages usually have many `po/LL.po' files, where
 LL gives an ISO 639 two-letter code identifying the language.  Unless
@@ -51,7 +96,7 @@ may be set, prior to configuration, to limit the installed set.
 `LINGUAS' should then contain a space separated list of two-letter
 codes, stating which languages are allowed.
 
-1.2 Using This Package
+1.3 Using This Package
 ======================
 
 As a user, if your language has been installed for this package, you
@@ -103,7 +148,7 @@ to denote the language's main dialect.  For example, `de' is equivalent
 to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
 (Portuguese as spoken in Portugal) in this context.
 
-1.3 Translating Teams
+1.4 Translating Teams
 =====================
 
 For the Free Translation Project to be a success, we need interested
@@ -132,1118 +177,859 @@ reach the coordinator for all translator teams.
 the terminology in use.  Proven linguistic skills are praised more than
 programming skills, here.
 
-1.4 Available Packages
+1.5 Available Packages
 ======================
 
 Languages are not equally supported in all packages.  The following
-matrix shows the current state of internationalization, as of June
-2010.  The matrix shows, in regard of each package, for which languages
+matrix shows the current state of internationalization, as of November
+2007.  The matrix shows, in regard of each package, for which languages
 PO files have been submitted to translation coordination, with a
 translation percentage of at least 50%.
 
-     Ready PO files       af am an ar as ast az be be@latin bg bn_IN bs ca
+     Ready PO files       af am ar az be bg bs ca cs cy da de el en en_GB eo
+                        +----------------------------------------------------+
+     Compendium         |                      []       [] []        []      |
+     a2ps               |             []                [] [] []     []      |
+     aegis              |                                  ()                |
+     ant-phone          |                                  ()                |
+     anubis             |                                  []                |
+     ap-utils           |                                                    |
+     aspell             |                      [] []    [] []        []      |
+     bash               |                                                 [] |
+     bfd                |                                                    |
+     bibshelf           |                                  []                |
+     binutils           |                                                    |
+     bison              |                               [] []                |
+     bison-runtime      |                                  []                |
+     bluez-pin          | []                      []       [] []          [] |
+     cflow              |                               []                   |
+     clisp              |                               [] []    []          |
+     console-tools      |                         []       []                |
+     coreutils          |                []    [] []       []                |
+     cpio               |                                                    |
+     cpplib             |                      []       [] []                |
+     cryptonit          |                                  []                |
+     dialog             |                                                    |
+     diffutils          |                      [] []    [] [] []          [] |
+     doodle             |                                  []                |
+     e2fsprogs          |                         []       []                |
+     enscript           |                      []       [] []        []      |
+     fetchmail          |                      []       [] () []     []      |
+     findutils          |                []                                  |
+     findutils_stable   |                []    []       []                   |
+     flex               |                      []       [] []                |
+     fslint             |                                                    |
+     gas                |                                                    |
+     gawk               |                      []       [] []                |
+     gcal               |                      []                            |
+     gcc                |                                  []                |
+     gettext-examples   | []                   []          [] []          [] |
+     gettext-runtime    |             []       []       [] []             [] |
+     gettext-tools      |                      []          []                |
+     gip                |                []                                  |
+     gliv               |                []                []                |
+     glunarclock        |                []                                  |
+     gmult              | []                               []                |
+     gnubiff            |                                  ()                |
+     gnucash            |                      [] []       () ()     []      |
+     gnuedu             |                                                    |
+     gnulib             |                []                                  |
+     gnunet             |                                                    |
+     gnunet-gtk         |                                                    |
+     gnutls             |                                  []                |
+     gpe-aerial         |                         []       []                |
+     gpe-beam           |                         []       []                |
+     gpe-calendar       |                                                    |
+     gpe-clock          |                         []       []                |
+     gpe-conf           |                         []       []                |
+     gpe-contacts       |                                                    |
+     gpe-edit           |                         []                         |
+     gpe-filemanager    |                                                    |
+     gpe-go             |                         []                         |
+     gpe-login          |                         []       []                |
+     gpe-ownerinfo      |                         []       []                |
+     gpe-package        |                                                    |
+     gpe-sketchbook     |                         []       []                |
+     gpe-su             |                         []       []                |
+     gpe-taskmanager    |                         []       []                |
+     gpe-timesheet      |                         []                         |
+     gpe-today          |                         []       []                |
+     gpe-todo           |                                                    |
+     gphoto2            |                         []    [] []        []      |
+     gprof              |                               [] []                |
+     gpsdrive           |                                                    |
+     gramadoir          | []                               []                |
+     grep               |                         []                      [] |
+     gretl              |                                  ()                |
+     gsasl              |                                                    |
+     gss                |                                                    |
+     gst-plugins-bad    |                []             []                   |
+     gst-plugins-base   |                []             []                   |
+     gst-plugins-good   |                []    []       []                   |
+     gst-plugins-ugly   |                []             []                   |
+     gstreamer          | []             []    [] []    [] []        []      |
+     gtick              |                                  ()                |
+     gtkam              |             []          []    [] []                |
+     gtkorphan          |                []                []                |
+     gtkspell           |             []                   [] []          [] |
+     gutenprint         |                               []                   |
+     hello              |                []    []       [] []             [] |
+     herrie             |                                  []                |
+     hylafax            |                                                    |
+     idutils            |                               [] []                |
+     indent             |                      [] []       []             [] |
+     iso_15924          |                                                    |
+     iso_3166           |       []    [] [] [] [] [] [] [] [] []          [] |
+     iso_3166_2         |                                                    |
+     iso_4217           |                         []    [] []                |
+     iso_639            |                         []    [] []             [] |
+     jpilot             |                         []                         |
+     jtag               |                                                    |
+     jwhois             |                                                    |
+     kbd                |                         []    [] [] []             |
+     keytouch           |                      []          []                |
+     keytouch-editor    |                                  []                |
+     keytouch-keyboa... |                      []                            |
+     latrine            |                                  ()                |
+     ld                 |                               []                   |
+     leafpad            |                []    [] []       [] []             |
+     libc               |                      [] []    [] []                |
+     libexif            |                                  []                |
+     libextractor       |                                  []                |
+     libgpewidget       |                         []    [] []                |
+     libgpg-error       |                                  []                |
+     libgphoto2         |                               [] []                |
+     libgphoto2_port    |                               [] []                |
+     libgsasl           |                                                    |
+     libiconv           |                                  []             [] |
+     libidn             |                         []    []                [] |
+     lifelines          |                               [] ()                |
+     lilypond           |                                  []                |
+     lingoteach         |                                                    |
+     lprng              |                                                    |
+     lynx               |                      [] []    [] []                |
+     m4                 |                         []    [] [] []             |
+     mailfromd          |                                                    |
+     mailutils          |                      []                            |
+     make               |                               [] []                |
+     man-db             |                      []       [] []                |
+     minicom            |                         []    [] []                |
+     nano               |                []    []          []                |
+     opcodes            |                                  []                |
+     parted             |                         []       []                |
+     pilot-qof          |                                                    |
+     popt               |                         []    [] []                |
+     psmisc             |                []                                  |
+     pwdutils           |                                                    |
+     qof                |                                                    |
+     radius             |                      []                            |
+     recode             |             []       []       [] [] []          [] |
+     rpm                |                               []                   |
+     screem             |                                                    |
+     scrollkeeper       |          [] []       [] [] [] [] []        []      |
+     sed                |                      []          []             [] |
+     shared-mime-info   |                []    [] []    [] () []     []   [] |
+     sharutils          |                []    [] []    [] [] []             |
+     shishi             |                                                    |
+     skencil            |                               [] ()                |
+     solfege            |                                                    |
+     soundtracker       |                               [] []                |
+     sp                 |                                  []                |
+     system-tools-ba... |       []       [] [] [] []    [] [] []     []      |
+     tar                |                []                []                |
+     texinfo            |                               [] []             [] |
+     tin                |                                  ()        ()      |
+     tuxpaint           | []             []             [] []        []   [] |
+     unicode-han-tra... |                                                    |
+     unicode-transla... |                                                    |
+     util-linux         |                      [] []    [] []                |
+     util-linux-ng      |                      [] []    [] []                |
+     vorbis-tools       |                         []                         |
+     wastesedge         |                                  ()                |
+     wdiff              |                      []       [] []        []      |
+     wget               |                      [] []       []                |
+     xchat              |             [] []    [] []       [] []     []      |
+     xkeyboard-config   |                []                                  |
+     xpad               |                []             []           []      |
+                        +----------------------------------------------------+
+                          af am ar az be bg bs ca cs cy da de el en en_GB eo
+                           6  0  2  1  8 26  2 40 48  2 56 88 15  1  15   18
+
+                          es et eu fa fi fr  ga gl gu he hi hr hu id is it
                         +--------------------------------------------------+
-     a2ps               |                       []                      [] |
+     Compendium         | []          [] []  []                []          |
+     a2ps               |    []       [] []                             () |
      aegis              |                                                  |
-     ant-phone          |                                                  |
-     anubis             |                                                  |
-     aspell             |                []                             [] |
-     bash               |                                                  |
+     ant-phone          |                []                                |
+     anubis             |                []                                |
+     ap-utils           |             [] []                                |
+     aspell             |                []  []                         [] |
+     bash               | []                                               |
+     bfd                | []          []                                   |
+     bibshelf           | []                 []                         [] |
+     binutils           | []          [] []                                |
+     bison              | [] []          []  []                   []    [] |
+     bison-runtime      |    []          []  []                   []    [] |
+     bluez-pin          |             [] []  []                [] []       |
+     cflow              |                    []                            |
+     clisp              | []             []                                |
+     console-tools      |                                                  |
+     coreutils          | [] []       [] []  []                []          |
+     cpio               | []             []  []                            |
+     cpplib             | []             []                                |
+     cryptonit          |                []                                |
+     dialog             |       []           []                         [] |
+     diffutils          | []          [] []  [] []    []       [] []    [] |
+     doodle             |                    []                         [] |
+     e2fsprogs          | []             []                             [] |
+     enscript           |                []  []             []             |
+     fetchmail          | []                                               |
+     findutils          |    []              []                []          |
+     findutils_stable   |    []          []  []                []          |
+     flex               | []             []  []                            |
+     fslint             |                                                  |
+     gas                | []             []                                |
+     gawk               | []             []  []       []                () |
+     gcal               | []             []                                |
+     gcc                | []                                               |
+     gettext-examples   | []          [] []  []                [] []    [] |
+     gettext-runtime    | []          [] []  []                   []    [] |
+     gettext-tools      | []    []       []                             [] |
+     gip                | []    []       []  []                            |
+     gliv               |                ()                                |
+     glunarclock        |             []     []                []          |
+     gmult              |       []       []                             [] |
+     gnubiff            |                ()                             () |
+     gnucash            | ()             ()                    ()          |
+     gnuedu             | []                                               |
+     gnulib             | [] []              []                            |
+     gnunet             |                                                  |
+     gnunet-gtk         |                                                  |
+     gnutls             |                                                  |
+     gpe-aerial         | []             []                                |
+     gpe-beam           | []             []                                |
+     gpe-calendar       |                                                  |
+     gpe-clock          | []          [] []                    []          |
+     gpe-conf           |                []                                |
+     gpe-contacts       | []             []                                |
+     gpe-edit           | []             []                    [] []       |
+     gpe-filemanager    | []                                               |
+     gpe-go             | []             []                    []          |
+     gpe-login          | []             []                    []          |
+     gpe-ownerinfo      | []          [] []                    [] []       |
+     gpe-package        | []                                               |
+     gpe-sketchbook     | []             []                                |
+     gpe-su             | []          [] []                    []          |
+     gpe-taskmanager    | []          [] []                                |
+     gpe-timesheet      | []             []  []                   []       |
+     gpe-today          | []          [] []  []                            |
+     gpe-todo           | []                                               |
+     gphoto2            | []          [] []                    []       [] |
+     gprof              | []          [] []  []                   []       |
+     gpsdrive           |    []                                            |
+     gramadoir          |                []  []                            |
+     grep               | []          []     []                            |
+     gretl              | []    []       []                             () |
+     gsasl              |                    []                   []       |
+     gss                |                []  []                            |
+     gst-plugins-bad    | []          []                       []       [] |
+     gst-plugins-base   | []          []                       []       [] |
+     gst-plugins-good   | []    []    []                       []       [] |
+     gst-plugins-ugly   | []          []                       []       [] |
+     gstreamer          |             []                       []       [] |
+     gtick              |             []     []                         [] |
+     gtkam              | []             []                    []       [] |
+     gtkorphan          |                []                             [] |
+     gtkspell           | []    []    [] []  []                []       [] |
+     gutenprint         |                                      []          |
+     hello              | [] [] [] [] [] []  [] []    []    [] [] []    [] |
+     herrie             |                    []                            |
+     hylafax            |                                                  |
+     idutils            |                []  []                [] []    [] |
+     indent             | [] [] []    [] []  [] []             [] []    [] |
+     iso_15924          |                []                                |
+     iso_3166           | [] [] []    [] []     [] [] [] [] [] [] []    [] |
+     iso_3166_2         |                []                                |
+     iso_4217           | [] []       [] []                    []       [] |
+     iso_639            | []       [] [] []  []                []          |
+     jpilot             | []             []                                |
+     jtag               |                []                                |
+     jwhois             | []             []                    [] []    [] |
+     kbd                | []             []                                |
+     keytouch           |                []  []                         [] |
+     keytouch-editor    |                    []                            |
+     keytouch-keyboa... |                    []                         [] |
+     latrine            |                    []                         [] |
+     ld                 | []          [] []  []                            |
+     leafpad            | []             []  []       []       []       [] |
+     libc               | []          [] []     []             []          |
+     libexif            | []                                               |
+     libextractor       |                    []                            |
+     libgpewidget       | []             []  []                [] []       |
+     libgpg-error       |                []                                |
+     libgphoto2         | []             []                             [] |
+     libgphoto2_port    |                []                             [] |
+     libgsasl           |                []  []                            |
+     libiconv           |    []       []     []                            |
+     libidn             |                []                             [] |
+     lifelines          |                ()                                |
+     lilypond           | []          [] []                                |
+     lingoteach         |                []                       []    [] |
+     lprng              |                                                  |
+     lynx               |    []                                []       [] |
+     m4                 |                []  [] []                []       |
+     mailfromd          |                                                  |
+     mailutils          | []             []                                |
+     make               | []          [] []  [] []    []    []    []       |
+     man-db             |                                               [] |
+     minicom            | []          [] []                    []          |
+     nano               | []    []       []  [] []             []       [] |
+     opcodes            | []          [] []  []                            |
+     parted             |                []                       []    [] |
+     pilot-qof          |                                                  |
+     popt               |                []  [] []                   []    |
+     psmisc             |                                      []       [] |
+     pwdutils           |                                                  |
+     qof                |                                         []       |
+     radius             | []             []                                |
+     recode             | []             []  [] []    []       [] []    [] |
+     rpm                |                []                       []       |
+     screem             |                                                  |
+     scrollkeeper       | []          []                       []          |
+     sed                | [] []          []  []                []          |
+     shared-mime-info   | []    []    [] []                    []       [] |
+     sharutils          | [] []       [] []  [] []             []       [] |
+     shishi             |                []                                |
+     skencil            | []             []                                |
+     solfege            |                                               [] |
+     soundtracker       | []             []                             [] |
+     sp                 |                []                                |
+     system-tools-ba... | []    []    [] []  []             [] [] []    [] |
+     tar                |    [] []    []     []                []          |
+     texinfo            |                []           []       []          |
+     tin                |    []          ()                                |
+     tuxpaint           |                    []                []          |
+     unicode-han-tra... |                                                  |
+     unicode-transla... |                []  []                            |
+     util-linux         | [] []       [] []                    [] []    [] |
+     util-linux-ng      | [] []       [] []                    [] []    [] |
+     vorbis-tools       |                                                  |
+     wastesedge         |                ()                                |
+     wdiff              | [] []          []  [] []             [] []    [] |
+     wget               |    []       [] []  []             [] [] []    [] |
+     xchat              | []          [] []        []    []    []       [] |
+     xkeyboard-config   | []          [] []                    []          |
+     xpad               | []                 []                []          |
+                        +--------------------------------------------------+
+                          es et eu fa fi fr  ga gl gu he hi hr hu id is it
+                          85 22 14  2 48 101 61 12  2  8  2  6 53 29  1 52
+
+                          ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl  nn
+                        +--------------------------------------------------+
+     Compendium         |                                           []     |
+     a2ps               |       ()                      []          []     |
+     aegis              |                                           ()     |
+     ant-phone          |                                           []     |
+     anubis             |                               []    []    []     |
+     ap-utils           |                               []                 |
+     aspell             |                            []             []     |
+     bash               |                                           []     |
      bfd                |                                                  |
-     bibshelf           |                []                                |
+     bibshelf           |                               []                 |
      binutils           |                                                  |
-     bison              |                                                  |
-     bison-runtime      |                []                                |
-     bluez-pin          | []             []                                |
-     bombono-dvd        |                                                  |
-     buzztard           |                                                  |
+     bison              |                               []    []    []     |
+     bison-runtime      |                               []    []    []     |
+     bluez-pin          |          []                   []          []     |
      cflow              |                                                  |
-     clisp              |                                                  |
-     coreutils          |                                   []          [] |
-     cpio               |                                                  |
-     cppi               |                                                  |
-     cpplib             |                                               [] |
-     cryptsetup         |                                                  |
-     dfarc              |                                                  |
-     dialog             |                             []                [] |
-     dico               |                                                  |
-     diffutils          |                                               [] |
-     dink               |                                                  |
+     clisp              |                                           []     |
+     console-tools      |                                                  |
+     coreutils          |                                           []     |
+     cpio               |                                           []     |
+     cpplib             |                                           []     |
+     cryptonit          |                                           []     |
+     dialog             |                               []          []     |
+     diffutils          | []                            []          []     |
      doodle             |                                                  |
-     e2fsprogs          |                                               [] |
-     enscript           |                                               [] |
-     exif               |                                                  |
-     fetchmail          |                                               [] |
-     findutils          |                                   []             |
-     flex               |                                               [] |
-     freedink           |                                                  |
+     e2fsprogs          |                                           []     |
+     enscript           |                                           []     |
+     fetchmail          | []                                        []     |
+     findutils          |                                           []     |
+     findutils_stable   |                                           []     |
+     flex               |       []                                  []     |
+     fslint             |                                                  |
      gas                |                                                  |
-     gawk               |                []                             [] |
-     gcal               |                                               [] |
+     gawk               | []                                        []     |
+     gcal               |                                                  |
      gcc                |                                                  |
-     gettext-examples   | []             []                 []          [] |
-     gettext-runtime    |                                   []          [] |
-     gettext-tools      |                                   []          [] |
-     gip                |                                   []             |
-     gjay               |                                                  |
-     gliv               |                                   []             |
-     glunarclock        |                []                 []             |
+     gettext-examples   | []                            []          []     |
+     gettext-runtime    | []    []                                  []     |
+     gettext-tools      | []    []                                         |
+     gip                |                               []          []     |
+     gliv               |                                           []     |
+     glunarclock        |                               []          []     |
+     gmult              | []                            []          []     |
      gnubiff            |                                                  |
-     gnucash            |                                               [] |
+     gnucash            | ()                                  () ()        |
      gnuedu             |                                                  |
-     gnulib             |                                                  |
+     gnulib             | []                                        []     |
      gnunet             |                                                  |
      gnunet-gtk         |                                                  |
-     gnutls             |                                                  |
-     gold               |                                                  |
-     gpe-aerial         |                                                  |
-     gpe-beam           |                                                  |
-     gpe-bluetooth      |                                                  |
-     gpe-calendar       |                                                  |
-     gpe-clock          |                []                                |
-     gpe-conf           |                                                  |
-     gpe-contacts       |                                                  |
-     gpe-edit           |                                                  |
-     gpe-filemanager    |                                                  |
-     gpe-go             |                                                  |
-     gpe-login          |                                                  |
-     gpe-ownerinfo      |                []                                |
-     gpe-package        |                                                  |
-     gpe-sketchbook     |                                                  |
-     gpe-su             |                []                                |
-     gpe-taskmanager    |                []                                |
-     gpe-timesheet      |                []                                |
-     gpe-today          |                []                                |
-     gpe-todo           |                                                  |
-     gphoto2            |                                                  |
-     gprof              |                                   []             |
-     gpsdrive           |                                                  |
-     gramadoir          |                                                  |
-     grep               |                                                  |
-     grub               |                []                             [] |
-     gsasl              |                                                  |
+     gnutls             |                               []                 |
+     gpe-aerial         |                                           []     |
+     gpe-beam           |                                           []     |
+     gpe-calendar       | []                                               |
+     gpe-clock          | []    []                                  []     |
+     gpe-conf           | []    []                                  []     |
+     gpe-contacts       |       []                                         |
+     gpe-edit           | []    []                                  []     |
+     gpe-filemanager    | []    []                                         |
+     gpe-go             | []    []                                  []     |
+     gpe-login          | []    []                                  []     |
+     gpe-ownerinfo      | []                                        []     |
+     gpe-package        | []    []                                         |
+     gpe-sketchbook     |       []                                  []     |
+     gpe-su             | []    []                                  []     |
+     gpe-taskmanager    | []    [] []                               []     |
+     gpe-timesheet      |                                           []     |
+     gpe-today          | []                                        []     |
+     gpe-todo           | []                                               |
+     gphoto2            | []                                        []     |
+     gprof              |                               []                 |
+     gpsdrive           |                                           []     |
+     gramadoir          |                                           ()     |
+     grep               |             []                            []     |
+     gretl              |                                                  |
+     gsasl              |                                           []     |
      gss                |                                                  |
-     gst-plugins-bad    |                                   []             |
-     gst-plugins-base   |                                   []             |
-     gst-plugins-good   |                                   []             |
-     gst-plugins-ugly   |                                   []             |
-     gstreamer          | []                                []          [] |
-     gtick              |                                                  |
-     gtkam              |                       []                         |
-     gtkorphan          |                                   []             |
-     gtkspell           | []             []     []                         |
-     gutenprint         |                                                  |
-     hello              |                                   []             |
-     help2man           |                                                  |
+     gst-plugins-bad    |                                           []     |
+     gst-plugins-base   |                                           []     |
+     gst-plugins-good   |                                           []     |
+     gst-plugins-ugly   |                                           []     |
+     gstreamer          |                                           []     |
+     gtick              |                                           []     |
+     gtkam              | []                                        []     |
+     gtkorphan          |                                           []     |
+     gtkspell           |                            []             []     |
+     gutenprint         |                                           []     |
+     hello              | [] [] []                      []    []    []  [] |
+     herrie             |                                           []     |
      hylafax            |                                                  |
-     idutils            |                                                  |
-     indent             |                                   []          [] |
-     iso_15924          |                                                  |
-     iso_3166           | []          []        []          []  []   [] [] |
-     iso_3166_2         |                                                  |
-     iso_4217           |                                                  |
-     iso_639            |             [] []     []              []         |
-     iso_639_3          |                                                  |
-     jwhois             |                                                  |
-     kbd                |                                                  |
-     keytouch           |                                               [] |
-     keytouch-editor    |                                                  |
-     keytouch-keyboa... |                                               [] |
-     klavaro            |          []                                      |
-     latrine            |                                                  |
-     ld                 |                                   []             |
-     leafpad            |                                   []          [] |
-     libc               |                                   []          [] |
-     libexif            |                       ()                         |
+     idutils            |                                           []     |
+     indent             | []                                        []     |
+     iso_15924          |                                           []     |
+     iso_3166           | []    [] []       []    []          []    []  [] |
+     iso_3166_2         |                                           []     |
+     iso_4217           | []                []                      []     |
+     iso_639            | []                []                      []  [] |
+     jpilot             | ()                                        ()     |
+     jtag               |                                                  |
+     jwhois             |                                           []     |
+     kbd                |                                           []     |
+     keytouch           |                                           []     |
+     keytouch-editor    |                                           []     |
+     keytouch-keyboa... |                                                  |
+     latrine            |                                           []     |
+     ld                 |                                                  |
+     leafpad            | []                []                             |
+     libc               | []    []                                  []     |
+     libexif            |                                                  |
      libextractor       |                                                  |
-     libgnutls          |                                                  |
-     libgpewidget       |                                                  |
+     libgpewidget       |                                           []     |
      libgpg-error       |                                                  |
-     libgphoto2         |                                                  |
-     libgphoto2_port    |                                                  |
-     libgsasl           |                                                  |
-     libiconv           |                                   []             |
-     libidn             |                                                  |
-     lifelines          |                                                  |
-     liferea            |                             []                [] |
-     lilypond           |                                                  |
-     linkdr             |          []                                      |
-     lordsawar          |                                                  |
+     libgphoto2         | []                                               |
+     libgphoto2_port    | []                                               |
+     libgsasl           |                                           []     |
+     libiconv           |                                           []     |
+     libidn             | []                                        []     |
+     lifelines          |                                           []     |
+     lilypond           |                                           []     |
+     lingoteach         |                                           []     |
      lprng              |                                                  |
-     lynx               |                                               [] |
-     m4                 |                                                  |
+     lynx               | []                                        []     |
+     m4                 | []                                        []     |
      mailfromd          |                                                  |
      mailutils          |                                                  |
-     make               |                                                  |
+     make               | []    []                                  []     |
      man-db             |                                                  |
-     man-db-manpages    |                                                  |
-     minicom            |                                                  |
-     mkisofs            |                                                  |
-     myserver           |                                                  |
-     nano               |                                   []          [] |
-     opcodes            |                                                  |
-     parted             |                                                  |
-     pies               |                                                  |
-     popt               |                                                  |
-     psmisc             |                                                  |
-     pspp               |                                               [] |
+     minicom            | []                                               |
+     nano               |                               []    []    []     |
+     opcodes            |                                           []     |
+     parted             | []                                        []     |
+     pilot-qof          |                                                  |
+     popt               | []    []                                  []     |
+     psmisc             | []                                  []    []     |
      pwdutils           |                                                  |
-     radius             |                                               [] |
-     recode             |                       []                      [] |
-     rosegarden         |                                                  |
-     rpm                |                                                  |
-     rush               |                                                  |
-     sarg               |                                                  |
-     screem             |                                                  |
-     scrollkeeper       |                    [] []                      [] |
-     sed                |                []                             [] |
-     sharutils          |                                   []          [] |
+     qof                |                                                  |
+     radius             |                                                  |
+     recode             |                                           []     |
+     rpm                | []    []                                         |
+     screem             | []                                               |
+     scrollkeeper       |                                     [] [] []  [] |
+     sed                | []                                        []     |
+     shared-mime-info   | []    []          []          []    []    []  [] |
+     sharutils          | []                                        []     |
      shishi             |                                                  |
      skencil            |                                                  |
-     solfege            |                                                  |
-     solfege-manual     |                                                  |
+     solfege            |                                     ()        () |
      soundtracker       |                                                  |
-     sp                 |                                                  |
-     sysstat            |                                                  |
-     tar                |                                   []             |
-     texinfo            |                                                  |
+     sp                 | ()                                               |
+     system-tools-ba... | []    []          []                      []     |
+     tar                | []          []                            []     |
+     texinfo            |                                     []    []     |
      tin                |                                                  |
+     tuxpaint           |                                     ()    []  [] |
      unicode-han-tra... |                                                  |
      unicode-transla... |                                                  |
-     util-linux-ng      |                                               [] |
-     vice               |                                                  |
-     vmm                |                                                  |
+     util-linux         | []                                        []     |
+     util-linux-ng      | []                                        []     |
      vorbis-tools       |                                                  |
-     wastesedge         |                                                  |
-     wdiff              |                                                  |
-     wget               |                       []                      [] |
-     wyslij-po          |                                                  |
-     xchat              |                []     []          []          [] |
-     xdg-user-dirs      | []    []    [] []     []    []    []  []      [] |
-     xkeyboard-config   |                                   []          [] |
+     wastesedge         |                                           []     |
+     wdiff              |                               []    []           |
+     wget               | []                                        []     |
+     xchat              | []    []                []                []     |
+     xkeyboard-config   |    [] []                                  []     |
+     xpad               |       []                      []          []     |
                         +--------------------------------------------------+
-                          af am an ar as ast az be be@latin bg bn_IN bs ca
-                           6  0  1  2  3 19   1 10     3    28   3    1 38
-
-                          crh cs da  de  el en en_GB en_ZA eo es et eu fa
-                        +-------------------------------------------------+
-     a2ps               |     [] []  []  []     []            [] []       |
-     aegis              |        []  []                       []          |
-     ant-phone          |        []  ()                                   |
-     anubis             |        []  []                                   |
-     aspell             |     [] []  []         []            []          |
-     bash               |     []                           [] []          |
-     bfd                |                                     []          |
-     bibshelf           |        []  []                       []          |
-     binutils           |                                     []          |
-     bison              |            []  []                               |
-     bison-runtime      |        []  []  []                      []       |
-     bluez-pin          |     [] []  []  []                [] []          |
-     bombono-dvd        |        []                                       |
-     buzztard           |     [] []  []                                   |
-     cflow              |        []  []                                   |
-     clisp              |        []  []     []                []          |
-     coreutils          |     [] []  []                          []       |
-     cpio               |                                                 |
-     cppi               |                                                 |
-     cpplib             |        []  []                       []          |
-     cryptsetup         |            []                                   |
-     dfarc              |        []  []                       []          |
-     dialog             |        []  []                    [] []    []    |
-     dico               |                                                 |
-     diffutils          |     [] []  []  []                [] []          |
-     dink               |        []  []                       []          |
-     doodle             |            []                                   |
-     e2fsprogs          |     []     []                       []          |
-     enscript           |        []  []         []                        |
-     exif               |     () []  []                                   |
-     fetchmail          |     [] []  ()  []     []            []          |
-     findutils          |     [] []  []                                   |
-     flex               |            []                       []          |
-     freedink           |        []  []                       []          |
-     gas                |                                     []          |
-     gawk               |        []  []                       []          |
-     gcal               |                                     []          |
-     gcc                |            []                       []          |
-     gettext-examples   |            []  []                [] []          |
-     gettext-runtime    |        []  []                    [] []          |
-     gettext-tools      |            []                       []    []    |
-     gip                |        []  []                       []    []    |
-     gjay               |            []                                   |
-     gliv               |     [] []  []                                   |
-     glunarclock        |        []  []                                   |
-     gnubiff            |            ()                                   |
-     gnucash            |     []     ()  ()     ()            ()          |
-     gnuedu             |        []                           []          |
-     gnulib             |            []                       []          |
-     gnunet             |                                                 |
-     gnunet-gtk         |        []                                       |
-     gnutls             |     []     []                                   |
-     gold               |                                     []          |
-     gpe-aerial         |     [] []  []                       []          |
-     gpe-beam           |     [] []  []                       []          |
-     gpe-bluetooth      |        []  []                                   |
-     gpe-calendar       |        []                                       |
-     gpe-clock          |     [] []  []                       []          |
-     gpe-conf           |     [] []  []                                   |
-     gpe-contacts       |        []  []                       []          |
-     gpe-edit           |        []  []                                   |
-     gpe-filemanager    |        []  []                       []          |
-     gpe-go             |     [] []  []                       []          |
-     gpe-login          |        []  []                                   |
-     gpe-ownerinfo      |     [] []  []                       []          |
-     gpe-package        |        []  []                       []          |
-     gpe-sketchbook     |     [] []  []                       []          |
-     gpe-su             |     [] []  []                       []          |
-     gpe-taskmanager    |     [] []  []                       []          |
-     gpe-timesheet      |     [] []  []                       []          |
-     gpe-today          |     [] []  []                       []          |
-     gpe-todo           |        []  []                       []          |
-     gphoto2            |     [] []  ()         []            []    []    |
-     gprof              |        []  []                       []          |
-     gpsdrive           |        []                           [] []       |
-     gramadoir          |        []  []                    []             |
-     grep               |     []                                          |
-     grub               |        []  []                                   |
-     gsasl              |            []                                   |
-     gss                |                                                 |
-     gst-plugins-bad    |     [] []  []                       []    []    |
-     gst-plugins-base   |     [] []  []                       []    []    |
-     gst-plugins-good   |     [] []  []  []                   []    []    |
-     gst-plugins-ugly   |     [] []  []  []                   []    []    |
-     gstreamer          |     [] []  []                       []    []    |
-     gtick              |        []  ()                    []             |
-     gtkam              |     [] []  ()                    [] []          |
-     gtkorphan          |     [] []  []                    []             |
-     gtkspell           |     [] []  []  []                [] []    []    |
-     gutenprint         |        []  []         []                        |
-     hello              |        []  []                    [] []          |
-     help2man           |            []                                   |
-     hylafax            |            []                       []          |
-     idutils            |        []  []                                   |
-     indent             |     [] []  []                    [] [] [] []    |
-     iso_15924          |        []      ()                [] []          |
-     iso_3166           | []  [] []  []  ()                [] [] [] ()    |
-     iso_3166_2         |                ()                               |
-     iso_4217           |     [] []  []  ()                   [] []       |
-     iso_639            | []  [] []  []  ()                [] []          |
-     iso_639_3          | []                                              |
-     jwhois             |                                     []          |
-     kbd                |     [] []  []  []                   []          |
-     keytouch           |        []  []                                   |
-     keytouch-editor    |        []  []                                   |
-     keytouch-keyboa... |        []                                       |
-     klavaro            |     [] []  []                    []             |
-     latrine            |        []  ()                                   |
-     ld                 |        []                           []          |
-     leafpad            |     [] []  []  []                   []    []    |
-     libc               |     [] []  []                       []          |
-     libexif            |        []  []         ()                        |
-     libextractor       |                                                 |
-     libgnutls          |     []                                          |
-     libgpewidget       |        []  []                                   |
-     libgpg-error       |     []     []                                   |
-     libgphoto2         |        []  ()                                   |
-     libgphoto2_port    |        []  ()                             []    |
-     libgsasl           |                                                 |
-     libiconv           |     [] []  []                    []    []       |
-     libidn             |     []     []                    []             |
-     lifelines          |        []  ()                                   |
-     liferea            |     []     []  []                   []    []    |
-     lilypond           |     []     []                       []          |
-     linkdr             |        []  []                       []          |
-     lordsawar          |        []                                       |
-     lprng              |                                                 |
-     lynx               |     [] []  []                          []       |
-     m4                 |     [] []  []  []                               |
-     mailfromd          |                                                 |
-     mailutils          |                                     []          |
-     make               |        []  []                       []          |
-     man-db             |                                                 |
-     man-db-manpages    |                                                 |
-     minicom            |     [] []  []                       []          |
-     mkisofs            |                                                 |
-     myserver           |                                                 |
-     nano               |            []                       []    []    |
-     opcodes            |            []                       []          |
-     parted             |     []     []                                   |
-     pies               |                                                 |
-     popt               |     [] []  []                    [] []          |
-     psmisc             |     []     []                             []    |
-     pspp               |                                     []          |
-     pwdutils           |        []                                       |
-     radius             |                                     []          |
-     recode             |     [] []  []  []                [] []          |
-     rosegarden         |     ()     ()                       ()          |
-     rpm                |        []  []                       []          |
-     rush               |                                                 |
-     sarg               |                                                 |
-     screem             |                                                 |
-     scrollkeeper       |     [] []  []         []            []          |
-     sed                |     []     []  []                [] [] []       |
-     sharutils          |        []  []                       [] []       |
-     shishi             |                                                 |
-     skencil            |        []  ()                       []          |
-     solfege            |            []                    []    []       |
-     solfege-manual     |                                  []    []       |
-     soundtracker       |        []  []                       []          |
-     sp                 |            []                                   |
-     sysstat            |        []  []                             []    |
-     tar                |     []     []                          [] []    |
-     texinfo            |            []                    [] []          |
-     tin                |            []                          []       |
-     unicode-han-tra... |                                                 |
-     unicode-transla... |                                                 |
-     util-linux-ng      |     [] []  []                       []          |
-     vice               |        ()  ()                                   |
-     vmm                |            []                                   |
-     vorbis-tools       |     []                           []             |
-     wastesedge         |        []                                       |
-     wdiff              |            []                       []          |
-     wget               |     []     []                          []       |
-     wyslij-po          |                                                 |
-     xchat              |     []     []  []                   [] []       |
-     xdg-user-dirs      | []  [] []  []  []                [] [] [] []    |
-     xkeyboard-config   | []  [] []  []                    [] []          |
-                        +-------------------------------------------------+
-                          crh cs da  de  el en en_GB en_ZA eo es et eu fa
-                           5  64 105 117 18  1   8     0   28 89 18 19  0
-
-                          fi  fr  ga gl gu he hi hr hu hy id  is it ja ka kn
-                        +----------------------------------------------------+
-     a2ps               | []  []                          []        []       |
-     aegis              |     []                                 []          |
-     ant-phone          |     []                                 []          |
-     anubis             | []  []                          []     []          |
-     aspell             |     []  []                      []     []          |
-     bash               | []  []                          []        []       |
-     bfd                | []  []                          []                 |
-     bibshelf           | []  []  []                      []     []          |
-     binutils           | []  []                          []                 |
-     bison              | []  []  []                      []                 |
-     bison-runtime      | []  []  []                      []     [] []       |
-     bluez-pin          | []  []  []                [] [] []  []    []       |
-     bombono-dvd        | []                                                 |
-     buzztard           |                                 []                 |
-     cflow              | []      []                      []                 |
-     clisp              |     []                                             |
-     coreutils          |     []  []                []    []     []          |
-     cpio               | []  []  []                      []                 |
-     cppi               | []  []                                             |
-     cpplib             | []  []                          []                 |
-     cryptsetup         |     []                          []     []          |
-     dfarc              | []  []                                 []          |
-     dialog             |     []  [] []                   []  [] [] []       |
-     dico               |                                                    |
-     diffutils          | []  []  [] []    []       []    []     [] []       |
-     dink               |     []                                             |
-     doodle             |         []                             []          |
-     e2fsprogs          |     []                          []                 |
-     enscript           |     []  []             []       []                 |
-     exif               | []  []                          []  [] [] []       |
-     fetchmail          |     []                          []     [] []       |
-     findutils          | []  []  []                []    []     []          |
-     flex               | []  []  []                                         |
-     freedink           | []  []                          []                 |
-     gas                |     []                          []                 |
-     gawk               |     []  []       []             []     () []       |
-     gcal               |     []                                             |
-     gcc                |                                 []                 |
-     gettext-examples   | []  []  []                []    []     [] []       |
-     gettext-runtime    | []  []  []                      []     [] []       |
-     gettext-tools      |     []                          []     [] []       |
-     gip                | []  []  [] []                   []        []       |
-     gjay               | []                                                 |
-     gliv               | []  ()                                             |
-     glunarclock        | []      []                []    []                 |
-     gnubiff            |     ()                          []     ()          |
-     gnucash            | ()  ()           ()       ()           () []       |
-     gnuedu             |     []                                 []          |
-     gnulib             | []  []  []                []           [] []       |
-     gnunet             |                                                    |
-     gnunet-gtk         |     []                                             |
-     gnutls             |     []                                 []          |
-     gold               | []                              []                 |
-     gpe-aerial         | []  []                          []                 |
-     gpe-beam           | []  []                          []        []       |
-     gpe-bluetooth      | []                              []     [] []       |
-     gpe-calendar       | []                                        []       |
-     gpe-clock          | []  []                    []    []        []       |
-     gpe-conf           | []  []                          []        []       |
-     gpe-contacts       | []  []                          []        []       |
-     gpe-edit           | []                              []        []       |
-     gpe-filemanager    | []                        []    []        []       |
-     gpe-go             | []  []                    []    []        []       |
-     gpe-login          | []                              []        []       |
-     gpe-ownerinfo      | []  []                    []    []        []       |
-     gpe-package        | []                              []        []       |
-     gpe-sketchbook     | []  []                          []        []       |
-     gpe-su             | []  []     []             []    []        []       |
-     gpe-taskmanager    | []  []                    []    []        []       |
-     gpe-timesheet      | []  []  []                      []        []       |
-     gpe-today          | []  []  [] []             []    []        []       |
-     gpe-todo           | []                              []        []       |
-     gphoto2            | []  []                    []    []     [] []       |
-     gprof              | []  []  []                      []                 |
-     gpsdrive           |            []                   []     []          |
-     gramadoir          |     []  []                      []                 |
-     grep               | []                                     []          |
-     grub               | []                        []    []     []          |
-     gsasl              | []  []  []                      []     []          |
-     gss                | []  []  []                      []     []          |
-     gst-plugins-bad    | []  []                    []    []     [] []       |
-     gst-plugins-base   | []  []                    []    []     [] []       |
-     gst-plugins-good   | []  []                    []    []     [] []       |
-     gst-plugins-ugly   | []  []                    []    []     [] []       |
-     gstreamer          | []  []                    []    []     []          |
-     gtick              | []  []  []                      []     []          |
-     gtkam              |     []                    []    []     [] []       |
-     gtkorphan          |     []                          []     []          |
-     gtkspell           | []  []  [] []             [] [] []     [] []       |
-     gutenprint         | []  []                    []           []          |
-     hello              | []      []                      []                 |
-     help2man           | []  []                                             |
-     hylafax            |                                 []                 |
-     idutils            | []  []  []                []    []     []          |
-     indent             | []  []  [] []             []    []     [] []       |
-     iso_15924          | []  ()                          []     []          |
-     iso_3166           | []  ()  [] [] [] [] [] [] []    []     [] []       |
-     iso_3166_2         |     ()                    []    []     []          |
-     iso_4217           | []  ()                    []    []     [] []       |
-     iso_639            | []  ()  []    []          []    []     [] []    [] |
-     iso_639_3          |     ()                                 []       [] |
-     jwhois             | []  []                    []    []     []          |
-     kbd                |     []                          []                 |
-     keytouch           | []  []  []                []    []     []          |
-     keytouch-editor    | []      []                []    []     []          |
-     keytouch-keyboa... | []      []                []    []     []          |
-     klavaro            |            []             []                       |
-     latrine            | []                              []     []          |
-     ld                 | []  []  []                      []                 |
-     leafpad            | []  []  []       []       []    []     [] ()       |
-     libc               | []  []     []                   []        []       |
-     libexif            |                                        []          |
-     libextractor       |                                                    |
-     libgnutls          |     []                                 []          |
-     libgpewidget       | []      []                      []        []       |
-     libgpg-error       |     []                                 []          |
-     libgphoto2         |     []                                 [] []       |
-     libgphoto2_port    |     []                                 [] []       |
-     libgsasl           | []  []  []                      []     []          |
-     libiconv           | []  []  []                      []     [] []       |
-     libidn             | []  []                          []     []          |
-     lifelines          |     ()                                             |
-     liferea            |     []                    []           [] []       |
-     lilypond           | []  []                                             |
-     linkdr             | []               []    [] []           []          |
-     lordsawar          |                                                    |
-     lprng              |                                 []                 |
-     lynx               |     []                    []    []     [] []       |
-     m4                 | []  []  [] []                   []        []       |
-     mailfromd          |                                                    |
-     mailutils          |     []                          []                 |
-     make               | []  []  [] []    []    []       []     [] []       |
-     man-db             |                                 []     []          |
-     man-db-manpages    |                                 []                 |
-     minicom            | []  []                    []    []        []       |
-     mkisofs            | []  []                          []     []          |
-     myserver           |                                                    |
-     nano               | []  []  [] []             []           []          |
-     opcodes            | []  []  []                      []                 |
-     parted             |     []                          []     [] []       |
-     pies               |                                                    |
-     popt               | []  []  [] []             []    []  [] [] []       |
-     psmisc             | []  []                          []                 |
-     pspp               |                                                    |
-     pwdutils           |     []                          []                 |
-     radius             |     []                          []                 |
-     recode             | []  []  [] []    []       []    []     []          |
-     rosegarden         | ()  ()                          ()     () ()       |
-     rpm                |                                 []        []       |
-     rush               |                                                    |
-     sarg               |     []                                             |
-     screem             |                                        [] []       |
-     scrollkeeper       | []                        []    []     []          |
-     sed                | []  []  [] []             []    []     [] []       |
-     sharutils          | []  []  []                []    []     [] []       |
-     shishi             |     []                                             |
-     skencil            |     []                                             |
-     solfege            | []  []     []                          []          |
-     solfege-manual     |     []     []                                      |
-     soundtracker       |     []                                 []          |
-     sp                 |     []                                    ()       |
-     sysstat            | []  []                          []     [] []       |
-     tar                | []  []  []                []    []     [] []       |
-     texinfo            |     []                          []     [] []       |
-     tin                |     []                                             |
-     unicode-han-tra... |                                                    |
-     unicode-transla... |     []  []                                         |
-     util-linux-ng      | []  []                    []    []     [] []       |
-     vice               |     ()                    ()           ()          |
-     vmm                |     []                                             |
-     vorbis-tools       |                                 []                 |
-     wastesedge         |     ()                                 ()          |
-     wdiff              | []                                                 |
-     wget               | []  []  []             [] []    []     [] []       |
-     wyslij-po          | []  []                          []                 |
-     xchat              | []  []        []    []    []    []     [] []    [] |
-     xdg-user-dirs      | []  []  [] [] [] [] []    []    []  [] [] []    [] |
-     xkeyboard-config   | []  []                    []    []     []          |
-                        +----------------------------------------------------+
-                          fi  fr  ga gl gu he hi hr hu hy id  is it ja ka kn
-                          105 121 53 20  4  8  3  5 53  2 120  5 84 67  0  4
-
-                          ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne
-                        +-----------------------------------------------+
-     a2ps               |                               []              |
-     aegis              |                                               |
-     ant-phone          |                                               |
-     anubis             |                               []    []        |
-     aspell             |                         []                    |
-     bash               |                                               |
-     bfd                |                                               |
-     bibshelf           |                []             []              |
-     binutils           |                                               |
-     bison              |                               []              |
-     bison-runtime      |       []    [] []             []    []        |
-     bluez-pin          |    [] []    [] []             []              |
-     bombono-dvd        |                                               |
-     buzztard           |                                               |
-     cflow              |                                               |
-     clisp              |                                               |
-     coreutils          |          []                                   |
-     cpio               |                                               |
-     cppi               |                                               |
-     cpplib             |                                               |
-     cryptsetup         |                                               |
-     dfarc              |                   []                          |
-     dialog             |    []       [] []             []    []        |
-     dico               |                                               |
-     diffutils          |                []             []              |
-     dink               |                                               |
-     doodle             |                                               |
-     e2fsprogs          |                                               |
-     enscript           |                                               |
-     exif               |                []                             |
-     fetchmail          |                                               |
-     findutils          |                                               |
-     flex               |                                               |
-     freedink           |                                     []        |
-     gas                |                                               |
-     gawk               |                                               |
-     gcal               |                                               |
-     gcc                |                                               |
-     gettext-examples   |       []       []             [] []           |
-     gettext-runtime    | []                                            |
-     gettext-tools      | []                                            |
-     gip                |                []             []              |
-     gjay               |                                               |
-     gliv               |                                               |
-     glunarclock        |                []                             |
-     gnubiff            |                                               |
-     gnucash            | ()          ()                      ()     () |
-     gnuedu             |                                               |
-     gnulib             |                                               |
-     gnunet             |                                               |
-     gnunet-gtk         |                                               |
-     gnutls             |                               []              |
-     gold               |                                               |
-     gpe-aerial         |                []                             |
-     gpe-beam           |                []                             |
-     gpe-bluetooth      |                []                []           |
-     gpe-calendar       |                []                             |
-     gpe-clock          | []    []       []             [] []           |
-     gpe-conf           | []             []                             |
-     gpe-contacts       | []             []                             |
-     gpe-edit           |                []                             |
-     gpe-filemanager    | []             []                             |
-     gpe-go             | []             []                []           |
-     gpe-login          |                []                             |
-     gpe-ownerinfo      |                []             []              |
-     gpe-package        | []             []                             |
-     gpe-sketchbook     | []             []                             |
-     gpe-su             | []    []       []             [] [] []        |
-     gpe-taskmanager    | [] [] []       []             [] []           |
-     gpe-timesheet      |                []             []              |
-     gpe-today          |       []       []             [] []           |
-     gpe-todo           |                []                   []        |
-     gphoto2            |                                               |
-     gprof              |                               []              |
-     gpsdrive           |                                               |
-     gramadoir          |                                               |
-     grep               |                                               |
-     grub               |                                               |
-     gsasl              |                                               |
-     gss                |                                               |
-     gst-plugins-bad    |             [] []                [] []        |
-     gst-plugins-base   |             [] []                             |
-     gst-plugins-good   |                []                []           |
-     gst-plugins-ugly   |             [] []             [] [] []        |
-     gstreamer          |                                               |
-     gtick              |                                               |
-     gtkam              |                                     []        |
-     gtkorphan          |                []                      []     |
-     gtkspell           |       []    [] []       []    []    [] []     |
-     gutenprint         |                                               |
-     hello              | []             []             []              |
-     help2man           |                                               |
-     hylafax            |                                               |
-     idutils            |                                               |
-     indent             |                                               |
-     iso_15924          |             [] []                             |
-     iso_3166           | [] []       () [] [] []    []       []        |
-     iso_3166_2         |                                               |
-     iso_4217           |             []                      []        |
-     iso_639            |                      []    []                 |
-     iso_639_3          |                            []                 |
-     jwhois             |                []                             |
-     kbd                |                                               |
-     keytouch           |                []                             |
-     keytouch-editor    |                []                             |
-     keytouch-keyboa... |                []                             |
-     klavaro            |                                     []        |
-     latrine            |                []                             |
-     ld                 |                                               |
-     leafpad            | []          [] []                             |
-     libc               | []                                            |
-     libexif            |                                               |
-     libextractor       |                                               |
-     libgnutls          |                               []              |
-     libgpewidget       |                []             []              |
-     libgpg-error       |                                               |
-     libgphoto2         |                                               |
-     libgphoto2_port    |                                               |
-     libgsasl           |                                               |
-     libiconv           |                                               |
-     libidn             |                                               |
-     lifelines          |                                               |
-     liferea            |                                               |
-     lilypond           |                                               |
-     linkdr             |                                               |
-     lordsawar          |                                               |
-     lprng              |                                               |
-     lynx               |                                               |
-     m4                 |                                               |
-     mailfromd          |                                               |
-     mailutils          |                                               |
-     make               | []                                            |
-     man-db             |                                               |
-     man-db-manpages    |                                               |
-     minicom            |                                     []        |
-     mkisofs            |                                               |
-     myserver           |                                               |
-     nano               |                               []    []        |
-     opcodes            |                                               |
-     parted             |                                               |
-     pies               |                                               |
-     popt               | []             []                   []        |
-     psmisc             |                                               |
-     pspp               |                                               |
-     pwdutils           |                                               |
-     radius             |                                               |
-     recode             |                                               |
-     rosegarden         |                                               |
-     rpm                |                                               |
-     rush               |                                               |
-     sarg               |                                               |
-     screem             |                                               |
-     scrollkeeper       |                                     []     [] |
-     sed                |                                               |
-     sharutils          |                                               |
-     shishi             |                                               |
-     skencil            |                                               |
-     solfege            |                                     []        |
-     solfege-manual     |                                               |
-     soundtracker       |                                               |
-     sp                 |                                               |
-     sysstat            |                []                             |
-     tar                |       []                                      |
-     texinfo            |                                     []        |
-     tin                |                                               |
-     unicode-han-tra... |                                               |
-     unicode-transla... |                                               |
-     util-linux-ng      |                                               |
-     vice               |                                               |
-     vmm                |                                               |
-     vorbis-tools       |                                               |
-     wastesedge         |                                               |
-     wdiff              |                                               |
-     wget               |             []                                |
-     wyslij-po          |                                               |
-     xchat              | []             [] []                          |
-     xdg-user-dirs      | [] []       [] [] []       []       [] []     |
-     xkeyboard-config   | []    []    []                                |
-                        +-----------------------------------------------+
-                          ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne
-                          20  5 10  1 13 48  4  2  2  4 24 10 20  3   1
+                          ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl  nn
+                          51  2 25  3  2  0  6  0  2  2 20  0 11  1 103  6
 
-                          nl  nn or pa pl  ps pt pt_BR ro ru rw sk sl sq sr
-                        +---------------------------------------------------+
-     a2ps               | []           []     []  []   [] []       []    [] |
-     aegis              | []                      []      []                |
-     ant-phone          |                         []   []                   |
-     anubis             | []           []                 []                |
-     aspell             | []                           [] []    [] []       |
-     bash               | []                                    []          |
-     bfd                |                                 []                |
-     bibshelf           | []  []                                            |
-     binutils           |                                 []    []          |
-     bison              | []           []                 []                |
-     bison-runtime      | []           []     []  []   [] []       []       |
-     bluez-pin          | []           []         []   [] []    [] []    [] |
-     bombono-dvd        |     []                          ()                |
-     buzztard           | []  []                                            |
-     cflow              |              []                                   |
-     clisp              | []                              []                |
-     coreutils          | []           []     []  []      []       []       |
-     cpio               | []           []                 []                |
-     cppi               |              []                                   |
-     cpplib             | []                                                |
-     cryptsetup         | []                                                |
-     dfarc              |              []                                   |
-     dialog             | []           []         []      []                |
-     dico               |              []                                   |
-     diffutils          | []           []         []   [] []             [] |
-     dink               | ()                                                |
-     doodle             | []                                          []    |
-     e2fsprogs          | []           []                                   |
-     enscript           | []                      []   [] []       []       |
-     exif               | []           []              [] ()    []          |
-     fetchmail          | []           []                 []          []    |
-     findutils          | []           []     []          []       []       |
-     flex               | []           []         []   [] []                |
-     freedink           | []           []                                   |
-     gas                |                                                   |
-     gawk               | []           []         []   []                   |
-     gcal               |                                                   |
-     gcc                |                                                [] |
-     gettext-examples   | []           []     []       [] []    [] []    [] |
-     gettext-runtime    | []  []       []     []       [] []    [] []    [] |
-     gettext-tools      |              []              [] []    [] []    [] |
-     gip                | []           []                 []    []       [] |
-     gjay               |                                                   |
-     gliv               | []           []         []   [] []    []          |
-     glunarclock        | []                      []   []       []       [] |
-     gnubiff            | []                           ()                   |
-     gnucash            | []           ()         ()      ()                |
-     gnuedu             | []                                                |
-     gnulib             | []           []                 []       []       |
-     gnunet             |                                                   |
-     gnunet-gtk         |                                                   |
-     gnutls             | []           []                                   |
-     gold               |                                                   |
-     gpe-aerial         | []                  []  []   [] []       []    [] |
-     gpe-beam           | []                  []  []   [] []       []    [] |
-     gpe-bluetooth      | []                      []                        |
-     gpe-calendar       |                         []      []       []    [] |
-     gpe-clock          | []                  []  []   [] []    [] []    [] |
-     gpe-conf           | []                  []  []   [] []    [] []       |
-     gpe-contacts       |                         []   [] []       []    [] |
-     gpe-edit           | []           []                          []       |
-     gpe-filemanager    | []                              []       []       |
-     gpe-go             | []           []         []   [] []    [] []    [] |
-     gpe-login          | []                      []                        |
-     gpe-ownerinfo      | []                  []  []   [] []    [] []    [] |
-     gpe-package        | []                                       []       |
-     gpe-sketchbook     | []                  []  []   [] []       []    [] |
-     gpe-su             | []                  []  []   [] []    [] []    [] |
-     gpe-taskmanager    | []                  []  []   [] []    [] []    [] |
-     gpe-timesheet      | []                  []  []   [] []    [] []    [] |
-     gpe-today          | []                  []  []   [] []    [] []    [] |
-     gpe-todo           | []                      []      []       []    [] |
-     gphoto2            | []        [] []         []   [] []    []       [] |
-     gprof              | []                      []   []                   |
-     gpsdrive           | []                              []                |
-     gramadoir          | []                                    []          |
-     grep               | []           []                 []    []          |
-     grub               | []           []                 []                |
-     gsasl              | []           []                       []       [] |
-     gss                |              []              []       []          |
-     gst-plugins-bad    | []           []         []      []    []    []    |
-     gst-plugins-base   | []           []         []      []    []          |
-     gst-plugins-good   | []           []         []      []    []          |
-     gst-plugins-ugly   | []           []         []      []    [] []       |
-     gstreamer          | []           []         []      []    []          |
-     gtick              | []                              []    []          |
-     gtkam              | []        [] []         []      []    []          |
-     gtkorphan          | []                                                |
-     gtkspell           | []           []     []  []   [] []    [] [] [] [] |
-     gutenprint         | []                              []                |
-     hello              | []           []                       [] []       |
-     help2man           |              []                 []                |
-     hylafax            | []                                                |
-     idutils            | []           []         []   [] []                |
-     indent             | []           []         []   [] []    []       [] |
-     iso_15924          | []           []                 []       []       |
-     iso_3166           | []  [] [] [] []     ()  []   [] [] [] [] [] [] [] |
-     iso_3166_2         | []           []                          []       |
-     iso_4217           | []  []       []     []          [] []    []    [] |
-     iso_639            | []     [] [] []                 [] [] [] []    [] |
-     iso_639_3          |        [] []                                      |
-     jwhois             | []           []         []   []                   |
-     kbd                | []           []              []                   |
-     keytouch           | []           []                       []          |
-     keytouch-editor    | []           []                       []          |
-     keytouch-keyboa... | []           []                       []          |
-     klavaro            | []                      []                        |
-     latrine            |              []                 []                |
-     ld                 |                                                   |
-     leafpad            | []  []       []     []  []      []    [] []    [] |
-     libc               | []           []                 []    []          |
-     libexif            | []           []         ()            []          |
-     libextractor       |                                                   |
-     libgnutls          | []           []                                   |
-     libgpewidget       | []           []                          []       |
-     libgpg-error       |              []              []                   |
-     libgphoto2         | []           []                                   |
-     libgphoto2_port    | []           []         []      []    []          |
-     libgsasl           | []           []              []       []       [] |
-     libiconv           | []           []                       [] []    [] |
-     libidn             | []           []                                   |
-     lifelines          | []           []                                   |
-     liferea            | []           []     []  []   [] ()    ()    []    |
-     lilypond           | []                                                |
-     linkdr             | []                  []          []                |
-     lordsawar          |                                                   |
-     lprng              |              []                                   |
-     lynx               | []                      []      []                |
-     m4                 | []           []         []   [] []                |
-     mailfromd          |              []                                   |
-     mailutils          |              []                                   |
-     make               | []           []         []      []                |
-     man-db             | []           []                 []                |
-     man-db-manpages    | []           []                 []                |
-     minicom            |              []         []   [] []                |
-     mkisofs            | []           []                 []                |
-     myserver           |                                                   |
-     nano               | []           []         []      []                |
-     opcodes            | []                           []                   |
-     parted             | []           []                 []    []          |
-     pies               |              []                                   |
-     popt               | []           []     []          []                |
-     psmisc             | []           []                 []                |
-     pspp               | []                      []                        |
-     pwdutils           |              []                                   |
-     radius             | []           []                 []                |
-     recode             | []           []     []  []   [] []    [] []       |
-     rosegarden         |              ()                 ()                |
-     rpm                | []           []     []                            |
-     rush               | []           []                                   |
-     sarg               |                                                   |
-     screem             |                                                   |
-     scrollkeeper       | []  []       []              [] []    []    [] [] |
-     sed                | []           []     []  []   [] []    [] []    [] |
-     sharutils          | []           []                 []             [] |
-     shishi             |              []                                   |
-     skencil            |                     []  []                        |
-     solfege            | []           []         []      []                |
-     solfege-manual     | []           []         []                        |
-     soundtracker       |                                       []          |
-     sp                 |                                                   |
-     sysstat            | []           []         []      []                |
-     tar                | []           []                 []       []       |
-     texinfo            | []           []              [] []                |
-     tin                |                                 []                |
-     unicode-han-tra... |                                                   |
-     unicode-transla... |                                                   |
-     util-linux-ng      | []           []         []      []       []       |
-     vice               | []                                                |
-     vmm                | []                                                |
-     vorbis-tools       | []           []                                   |
-     wastesedge         | []                                                |
-     wdiff              | []           []                                   |
-     wget               | []           []     []  []      []    [] []       |
-     wyslij-po          | []  []       []                                   |
-     xchat              | []        [] []     []          []    [] [] [] [] |
-     xdg-user-dirs      | []  [] [] [] []  [] []  []   [] []    [] [] [] [] |
-     xkeyboard-config   | []           []                 []                |
-                        +---------------------------------------------------+
-                          nl  nn or pa pl  ps pt pt_BR ro ru rw sk sl sq sr
-                          135 10  4  7 105  1 29  62   47 91  3 54 46  9 37
+                          or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv  ta
+                        +--------------------------------------------------+
+     Compendium         |          []  []      []       []          []     |
+     a2ps               |       ()     []      [] []       []    [] []     |
+     aegis              |                      () ()                       |
+     ant-phone          |                      []                   []     |
+     anubis             |       []             [] []                       |
+     ap-utils           |       ()                                         |
+     aspell             |                      [] []    []                 |
+     bash               |       []                      []                 |
+     bfd                |                                                  |
+     bibshelf           |                                           []     |
+     binutils           |                         []    []                 |
+     bison              |       []     []      [] []                []     |
+     bison-runtime      |       []     []      []          []       []     |
+     bluez-pin          |       []     []   [] [] []    [] []    [] []     |
+     cflow              |       []                                         |
+     clisp              |                         []                       |
+     console-tools      |                         []                       |
+     coreutils          |       []                []       []       []     |
+     cpio               |       []                []                []     |
+     cpplib             |                                           []     |
+     cryptonit          |              []                           []     |
+     dialog             |                                           []     |
+     diffutils          |       []     []      [] []             [] []     |
+     doodle             |                                     []    []     |
+     e2fsprogs          |       []                                  []     |
+     enscript           |              []      [] []       []       []     |
+     fetchmail          |       []                []          []           |
+     findutils          |       [] []                               []     |
+     findutils_stable   |       [] []          []       [] []       []     |
+     flex               |       []     []      [] []                []     |
+     fslint             |                                           []     |
+     gas                |                                                  |
+     gawk               |       []     []      []                   []     |
+     gcal               |                                           []     |
+     gcc                |                                        [] []     |
+     gettext-examples   |       [] []          [] []    [] []    [] []     |
+     gettext-runtime    |       [] []          [] []    [] []    [] []     |
+     gettext-tools      |       []             [] []    [] []    [] []     |
+     gip                |                   []          []       [] []     |
+     gliv               |       []     []      [] []    []          []     |
+     glunarclock        |              []      [] []    []       [] []     |
+     gmult              |                   [] []                [] []     |
+     gnubiff            |                      ()                   []     |
+     gnucash            |       ()                                  []     |
+     gnuedu             |                                                  |
+     gnulib             |       []                         []       []     |
+     gnunet             |                                                  |
+     gnunet-gtk         |                                           []     |
+     gnutls             |       []                                  []     |
+     gpe-aerial         |          []  []      [] []       []    [] []     |
+     gpe-beam           |          []  []      [] []       []    [] []     |
+     gpe-calendar       |                         []       []    [] []     |
+     gpe-clock          |          []  []      [] []    [] []    [] []     |
+     gpe-conf           |          []  []      [] []    [] []       []     |
+     gpe-contacts       |                      [] []       []    [] []     |
+     gpe-edit           |       [] []  []      [] []    [] []    [] []     |
+     gpe-filemanager    |                                  []       []     |
+     gpe-go             |       []     []      [] []    [] []    [] []     |
+     gpe-login          |          []  []      [] []    [] []    [] []     |
+     gpe-ownerinfo      |          []  []      [] []    [] []    [] []     |
+     gpe-package        |                                  []       []     |
+     gpe-sketchbook     |          []  []      [] []    [] []    [] []     |
+     gpe-su             |          []  []      [] []    [] []    [] []     |
+     gpe-taskmanager    |          []  []      [] []    [] []    [] []     |
+     gpe-timesheet      |          []  []      [] []    [] []    [] []     |
+     gpe-today          |          []  []      [] []    [] []    [] []     |
+     gpe-todo           |                         []       []    [] []     |
+     gphoto2            |    [] []             []       []       [] []     |
+     gprof              |              []      []                   []     |
+     gpsdrive           |                         []                []     |
+     gramadoir          |                               []          []     |
+     grep               |       []                      [] []       []     |
+     gretl              |       [] []  []                                  |
+     gsasl              |       []                               [] []     |
+     gss                |       []             []       []          []     |
+     gst-plugins-bad    |       []     []                           []     |
+     gst-plugins-base   |       []                                  []     |
+     gst-plugins-good   |       []                                  []     |
+     gst-plugins-ugly   |       []     []                           []     |
+     gstreamer          |       []                            [] [] []     |
+     gtick              |                         []                       |
+     gtkam              |    [] []     []         []                []     |
+     gtkorphan          |                                           []     |
+     gtkspell           |              []   [] [] []    [] []    [] []     |
+     gutenprint         |                                           []     |
+     hello              |       []     []      [] []    [] []    [] []     |
+     herrie             |       []                []                []     |
+     hylafax            |                                                  |
+     idutils            |       []     []      [] []                []     |
+     indent             |       []     []      [] []    []       [] []     |
+     iso_15924          |                                                  |
+     iso_3166           |    [] [] []  []      [] [] [] [] [] [] [] []  [] |
+     iso_3166_2         |                                                  |
+     iso_4217           |       [] []             [] []    []    [] []     |
+     iso_639            |       []                [] [] [] []    [] []     |
+     jpilot             |                                                  |
+     jtag               |                               []                 |
+     jwhois             |       []     []      []                   []     |
+     kbd                |       []             []                   []     |
+     keytouch           |                                           []     |
+     keytouch-editor    |                                           []     |
+     keytouch-keyboa... |                                           []     |
+     latrine            |                                                  |
+     ld                 |                                           []     |
+     leafpad            |       [] []             []    []          []  [] |
+     libc               |       []                []    []          []     |
+     libexif            |       []                      []                 |
+     libextractor       |                      []                   []     |
+     libgpewidget       |       [] []  []      []       [] []    [] []     |
+     libgpg-error       |       []             []                   []     |
+     libgphoto2         |       []                                         |
+     libgphoto2_port    |       []                []                []     |
+     libgsasl           |       []             []                [] []     |
+     libiconv           |                                  []    [] []     |
+     libidn             |       []                               [] ()     |
+     lifelines          |       []                                  []     |
+     lilypond           |                                                  |
+     lingoteach         |              []                                  |
+     lprng              |       []                                         |
+     lynx               |              []         []                []     |
+     m4                 |       []     []      [] []                []     |
+     mailfromd          |       []                                         |
+     mailutils          |       []                []                []     |
+     make               |       []     []         []                []     |
+     man-db             |       []             [] []                []     |
+     minicom            |       []     []      [] []                []     |
+     nano               |              []      [] []                []     |
+     opcodes            |                      []                   []     |
+     parted             |       []                                         |
+     pilot-qof          |                                                  |
+     popt               |       [] []             []                []     |
+     psmisc             |       []                                  []     |
+     pwdutils           |       []                                  []     |
+     qof                |              []                           []     |
+     radius             |       []                []                       |
+     recode             |       [] []  []      [] []       []       []     |
+     rpm                |       [] []             []                []     |
+     screem             |                                                  |
+     scrollkeeper       |       []             [] []    []    [] [] []     |
+     sed                |       [] []  []      [] []    [] []    [] []     |
+     shared-mime-info   |       [] []  []                     [] [] []     |
+     sharutils          |       []                []             [] []     |
+     shishi             |       []                                         |
+     skencil            |          []  []                           []     |
+     solfege            |              []                                  |
+     soundtracker       |                               []          []     |
+     sp                 |                                                  |
+     system-tools-ba... |    [] [] []  []      []             [] [] []  [] |
+     tar                |       []                []       []       []     |
+     texinfo            |       []             [] []                []     |
+     tin                |                         ()                       |
+     tuxpaint           |       [] []                      [] [] [] []     |
+     unicode-han-tra... |                                                  |
+     unicode-transla... |                                                  |
+     util-linux         |              []         []       []       []     |
+     util-linux-ng      |              []         []       []       []     |
+     vorbis-tools       |                         []                       |
+     wastesedge         |                                                  |
+     wdiff              |       []     []      [] []    [] []       []     |
+     wget               |          []             []    []          []     |
+     xchat              |    []                   []    [] [] [] [] []     |
+     xkeyboard-config   |                               [] []       []     |
+     xpad               |                               [] []       []     |
+                        +--------------------------------------------------+
+                          or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv  ta
+                           0  5 77 31  53    4 58 72  3 45 46  9 45 122  3
 
-                          sv  sw ta te tg th tr uk vi  wa zh_CN zh_HK zh_TW
+                          tg th tk tr uk ven vi  wa xh zh_CN zh_HK zh_TW zu
                         +---------------------------------------------------+
-     a2ps               | []              [] [] [] []                       | 27
-     aegis              |                          []                       |  9
-     ant-phone          | []                 []    []      []               |  9
-     anubis             | []                 [] [] []                       | 15
-     aspell             |                       [] []  []                   | 20
-     bash               | []                    [] []                       | 12
-     bfd                |                          []                       |  6
-     bibshelf           | []                       []      []               | 16
-     binutils           |                       [] []                       |  8
-     bison              | []                       []                       | 12
-     bison-runtime      | []              []    [] []      []          []   | 29
-     bluez-pin          | []              [] [] [] []  []  []          []   | 37
-     bombono-dvd        |                          []                       |  4
-     buzztard           |                          []                       |  7
-     cflow              |                       [] []      []               |  9
-     clisp              |                                                   | 10
-     coreutils          | []                    [] []      []               | 22
-     cpio               | []                 [] [] []      []          []   | 13
-     cppi               |                       [] []                       |  5
-     cpplib             | []                 [] [] []      []          []   | 14
-     cryptsetup         | []                       []                       |  7
-     dfarc              |                          []                       |  9
-     dialog             | []  []          []       []  []  []          []   | 30
-     dico               |                       []                          |  2
-     diffutils          | []                 [] [] []      []          []   | 30
-     dink               |                                                   |  4
-     doodle             | []                       []                       |  7
-     e2fsprogs          | []                 []    []                       | 11
-     enscript           | []                 [] [] []                       | 17
-     exif               | []                       []      []               | 16
-     fetchmail          |                    []    []      []               | 17
-     findutils          | []                 [] [] []      []               | 20
-     flex               | []                 []    []                  []   | 15
-     freedink           |                          []                       | 10
-     gas                |                    []                             |  4
-     gawk               | []                 []    []      []               | 18
-     gcal               | []                 []                             |  5
-     gcc                | []                 []            []               |  7
-     gettext-examples   | []                 [] [] []      []    []    []   | 34
-     gettext-runtime    | []                 [] [] []      []    []    []   | 29
-     gettext-tools      | []                 [] [] []      []          []   | 22
-     gip                | []                       []      []          []   | 22
-     gjay               |                          []                       |  3
-     gliv               | []                 []    []                       | 14
-     glunarclock        | []                       []  []  []          []   | 19
-     gnubiff            | []                       []                       |  4
-     gnucash            |                    () [] ()      []          ()   | 10
-     gnuedu             |                          []                  []   |  7
-     gnulib             | []                    [] []      []               | 16
-     gnunet             |                          []                       |  1
-     gnunet-gtk         | []                 []    []                       |  5
-     gnutls             | []                       []      []               | 10
-     gold               |                          []                       |  4
-     gpe-aerial         | []                       []      []               | 18
-     gpe-beam           | []                       []      []               | 19
-     gpe-bluetooth      | []                       []      []               | 13
-     gpe-calendar       | []                       []  []  []               | 12
-     gpe-clock          | []                 []    []  []  []               | 28
-     gpe-conf           | []                       []  []  []               | 20
-     gpe-contacts       | []                       []      []               | 17
-     gpe-edit           | []                       []      []               | 12
-     gpe-filemanager    | []                       []  []  []               | 16
-     gpe-go             | []                 []    []  []  []               | 25
-     gpe-login          | []                       []      []               | 11
-     gpe-ownerinfo      | []                 []    []      []          []   | 25
-     gpe-package        | []                       []      []               | 13
-     gpe-sketchbook     | []                       []      []               | 20
-     gpe-su             | []                 []    []  []  []               | 30
-     gpe-taskmanager    | []                 []    []  []  []               | 29
-     gpe-timesheet      | []                 []    []      []          []   | 25
-     gpe-today          | []                 []    []  []  []          []   | 30
-     gpe-todo           | []                       []  []  []               | 17
-     gphoto2            | []                    [] []      []          []   | 24
-     gprof              | []                 []    []                       | 15
-     gpsdrive           | []                       []      []               | 11
-     gramadoir          | []                       []      []               | 11
-     grep               |                 []       []      []               | 10
-     grub               | []                       []      []               | 14
-     gsasl              | []                       []      []          []   | 14
-     gss                | []                       []      []               | 11
-     gst-plugins-bad    | []                 []    []      []               | 26
-     gst-plugins-base   | []                 [] [] []      []               | 24
-     gst-plugins-good   | []                 []    []      []               | 24
-     gst-plugins-ugly   | []                 [] [] []      []               | 29
-     gstreamer          | []                    [] []      []               | 22
-     gtick              |                       [] []      []               | 13
-     gtkam              | []                       []      []               | 20
-     gtkorphan          | []                       []      []               | 14
-     gtkspell           | []              [] [] [] []  []  []    []    []   | 45
-     gutenprint         | []                                                | 10
-     hello              | []              [] []    []      []          []   | 21
-     help2man           | []                       []                       |  7
-     hylafax            |                          []                       |  5
-     idutils            | []                 []    []      []               | 17
-     indent             | []                 [] [] []      []          []   | 30
-     iso_15924          |                 ()    [] ()      []          []   | 16
-     iso_3166           | []        []    () [] [] ()  []  []    []    ()   | 53
-     iso_3166_2         |                 ()    [] ()      []               |  9
-     iso_4217           | []              () [] [] ()      []    []         | 26
-     iso_639            | []     [] []    ()    [] ()  []  []    []    []   | 38
-     iso_639_3          |        []                ()                       |  8
-     jwhois             | []                 []    []      []          []   | 16
-     kbd                | []                 [] [] []      []               | 15
-     keytouch           | []                       []      []               | 16
-     keytouch-editor    | []                       []      []               | 14
-     keytouch-keyboa... | []                       []      []               | 14
-     klavaro            |                          []                       | 11
-     latrine            |                    []    []      []               | 10
-     ld                 | []                 []    []                  []   | 11
-     leafpad            | []                 [] [] []      []          []   | 33
-     libc               | []                 []    []      []          []   | 21
-     libexif            |                          []      ()               |  7
-     libextractor       |                          []                       |  1
-     libgnutls          | []                       []      []               |  9
-     libgpewidget       | []                       []      []               | 14
-     libgpg-error       | []                       []      []               |  9
-     libgphoto2         |                       [] []                       |  8
-     libgphoto2_port    | []                    [] []                  []   | 14
-     libgsasl           | []                       []      []               | 13
-     libiconv           | []                       []  []  []               | 21
-     libidn             | ()                       []      []               | 11
-     lifelines          | []                                                |  4
-     liferea            | []                 []            []               | 21
-     lilypond           |                          []                       |  7
-     linkdr             | []                 []    []      []          []   | 17
-     lordsawar          |                                                   |  1
-     lprng              |                          []                       |  3
-     lynx               | []                 [] [] []                       | 17
-     m4                 | []                       []      []          []   | 19
-     mailfromd          |                       [] []                       |  3
-     mailutils          |                          []                       |  5
-     make               | []                 []    []      []               | 21
-     man-db             | []                       []      []               |  8
-     man-db-manpages    |                                                   |  4
-     minicom            | []                       []                       | 16
-     mkisofs            |                          []      []               |  9
-     myserver           |                                                   |  0
-     nano               | []                       []      []          []   | 21
-     opcodes            | []                 []    []                       | 11
-     parted             | []                 [] [] []                  []   | 15
-     pies               |                       [] []                       |  3
-     popt               | []              [] []    []      []          []   | 27
-     psmisc             | []                       []                       | 11
-     pspp               |                                                   |  4
-     pwdutils           | []                       []                       |  6
-     radius             |                       [] []                       |  9
-     recode             | []                 []    []      []               | 28
-     rosegarden         | ()                                                |  0
-     rpm                | []                       []                  []   | 11
-     rush               |                       [] []                       |  4
-     sarg               |                                                   |  1
-     screem             |                          []                       |  3
-     scrollkeeper       | []                 [] [] []                  []   | 27
-     sed                | []                 []    []      []          []   | 30
-     sharutils          | []                 []    []      []          []   | 22
-     shishi             |                          []                       |  3
-     skencil            | []                       []                       |  7
-     solfege            | []                 []    []      []               | 16
-     solfege-manual     |                    []                             |  8
-     soundtracker       | []                 []    []                       |  9
-     sp                 |                    []                             |  3
-     sysstat            |                          []      []               | 15
-     tar                | []                 [] [] []      []          []   | 23
-     texinfo            | []                 [] [] []      []               | 17
-     tin                |                                                   |  4
+     Compendium         |          []        []         []          []      | 19
+     a2ps               |          [] []     []                             | 19
+     aegis              |                    []                             |  1
+     ant-phone          |          []        []                             |  6
+     anubis             |          [] []     []                             | 11
+     ap-utils           |             ()     []                             |  4
+     aspell             |             []     []  []                         | 16
+     bash               |          []                                       |  6
+     bfd                |                                                   |  2
+     bibshelf           |                    []                             |  7
+     binutils           |          [] []     []                     []      |  9
+     bison              |          [] []     []                     []      | 20
+     bison-runtime      |             []     []         []          []      | 18
+     bluez-pin          |          [] []     []  []     []          []      | 28
+     cflow              |             []     []                             |  5
+     clisp              |                                                   |  9
+     console-tools      |          []        []                             |  5
+     coreutils          |          [] []     []                             | 18
+     cpio               |          [] []     []         []                  | 11
+     cpplib             |          [] []     []         []          []      | 12
+     cryptonit          |                    []                             |  6
+     dialog             |                    []  []     []                  |  9
+     diffutils          |          [] []     []         []          []      | 29
+     doodle             |                    []                             |  6
+     e2fsprogs          |          []        []                             | 10
+     enscript           |          [] []     []                             | 16
+     fetchmail          |          []        []                             | 12
+     findutils          |          [] []     []                             | 11
+     findutils_stable   |          [] []     []                     []      | 18
+     flex               |          []        []                             | 15
+     fslint             |                    []                             |  2
+     gas                |          []                                       |  3
+     gawk               |          []        []         []                  | 16
+     gcal               |          []                                       |  5
+     gcc                |          []                   []          []      |  7
+     gettext-examples   |          [] []     []         []    []    []      | 29
+     gettext-runtime    |          [] []     []         []    []    []      | 28
+     gettext-tools      |          [] []     []         []          []      | 20
+     gip                |                    []                     []      | 13
+     gliv               |          []        []                             | 11
+     glunarclock        |                    []  []                 []      | 15
+     gmult              |          []        []         []          []      | 16
+     gnubiff            |                    []                             |  2
+     gnucash            |          () []                                    |  5
+     gnuedu             |                    []                             |  2
+     gnulib             |                    []                             | 10
+     gnunet             |                                                   |  0
+     gnunet-gtk         |          []        []                             |  3
+     gnutls             |                                                   |  4
+     gpe-aerial         |                    []         []                  | 14
+     gpe-beam           |                    []         []                  | 14
+     gpe-calendar       |                    []  []                         |  7
+     gpe-clock          |          []        []  []     []                  | 21
+     gpe-conf           |                    []  []     []                  | 16
+     gpe-contacts       |                    []         []                  | 10
+     gpe-edit           |          []        []  []     []          []      | 22
+     gpe-filemanager    |                    []  []                         |  7
+     gpe-go             |          []        []  []     []                  | 19
+     gpe-login          |          []        []  []     []          []      | 21
+     gpe-ownerinfo      |          []        []         []          []      | 21
+     gpe-package        |                    []                             |  6
+     gpe-sketchbook     |          []        []                             | 16
+     gpe-su             |          []        []  []     []                  | 21
+     gpe-taskmanager    |          []        []  []     []                  | 21
+     gpe-timesheet      |          []        []         []          []      | 18
+     gpe-today          |          []        []  []     []          []      | 21
+     gpe-todo           |                    []  []                         |  8
+     gphoto2            |             []     []         []          []      | 21
+     gprof              |          []        []                             | 13
+     gpsdrive           |                    []                             |  5
+     gramadoir          |                    []                             |  7
+     grep               |                    []                             | 12
+     gretl              |                                                   |  6
+     gsasl              |                    []         []          []      |  9
+     gss                |                    []                             |  7
+     gst-plugins-bad    |             []     []         []                  | 13
+     gst-plugins-base   |             []     []                             | 11
+     gst-plugins-good   |             []     []         []    []    []      | 16
+     gst-plugins-ugly   |             []     []         []                  | 13
+     gstreamer          |          [] []     []                             | 18
+     gtick              |             []     []                             |  7
+     gtkam              |                    []                             | 16
+     gtkorphan          |                    []                             |  7
+     gtkspell           |             []     []  []     []    []    []      | 27
+     gutenprint         |                                                   |  4
+     hello              |          [] []     []         []          []      | 38
+     herrie             |          []        []                             |  8
+     hylafax            |                                                   |  0
+     idutils            |          []        []                             | 15
+     indent             |          [] []     []         []          []      | 28
+     iso_15924          |                    []         []                  |  4
+     iso_3166           |    [] [] [] []     []  []     []    []    []      | 54
+     iso_3166_2         |                    []         []                  |  4
+     iso_4217           |    []    []        []         []    []            | 24
+     iso_639            |             []     []  []     []    []            | 26
+     jpilot             |          [] []     []         []                  |  7
+     jtag               |                    []                             |  3
+     jwhois             |          []        []                     []      | 13
+     kbd                |          [] []     []                             | 13
+     keytouch           |                    []                             |  8
+     keytouch-editor    |                    []                             |  5
+     keytouch-keyboa... |                    []                             |  5
+     latrine            |          []        []                             |  5
+     ld                 |          []        []         []          []      | 10
+     leafpad            |          [] []     []         []          []      | 24
+     libc               |          []                   []          []      | 19
+     libexif            |                    []                             |  5
+     libextractor       |                    []                             |  5
+     libgpewidget       |                    []  []     []                  | 20
+     libgpg-error       |                    []                             |  6
+     libgphoto2         |             []     []                             |  9
+     libgphoto2_port    |             []     []                     []      | 11
+     libgsasl           |                    []                             |  8
+     libiconv           |                    []  []                         | 11
+     libidn             |                    []         []                  | 11
+     lifelines          |                                                   |  4
+     lilypond           |                    []                             |  6
+     lingoteach         |                    []                             |  6
+     lprng              |                    []                             |  2
+     lynx               |          [] []     []                             | 15
+     m4                 |                    []         []          []      | 18
+     mailfromd          |             []     []                             |  3
+     mailutils          |             []     []                             |  8
+     make               |          []        []         []                  | 20
+     man-db             |                    []                             |  9
+     minicom            |                    []                             | 14
+     nano               |                    []         []          []      | 20
+     opcodes            |          []        []                             | 10
+     parted             |          [] []                            []      | 11
+     pilot-qof          |                    []                             |  1
+     popt               |          []        []         []          []      | 18
+     psmisc             |                    []         []                  | 10
+     pwdutils           |                    []                             |  3
+     qof                |                    []                             |  4
+     radius             |             []     []                             |  7
+     recode             |          []        []         []                  | 25
+     rpm                |          [] []     []                     []      | 13
+     screem             |                    []                             |  2
+     scrollkeeper       |          [] []     []                     []      | 26
+     sed                |          []        []         []          []      | 23
+     shared-mime-info   |             []     []         []                  | 29
+     sharutils          |          []        []                     []      | 23
+     shishi             |                    []                             |  3
+     skencil            |                    []                             |  7
+     solfege            |                    []                             |  3
+     soundtracker       |          []        []                             |  9
+     sp                 |          []                                       |  3
+     system-tools-ba... |    []    [] []     []     []  []          []      | 38
+     tar                |          [] []     []                             | 17
+     texinfo            |          []        []         []                  | 15
+     tin                |                                                   |  1
+     tuxpaint           |                    []  []                 []      | 19
      unicode-han-tra... |                                                   |  0
      unicode-transla... |                                                   |  2
-     util-linux-ng      | []                 [] [] []                       | 20
-     vice               | ()                 ()                             |  1
-     vmm                |                          []                       |  4
-     vorbis-tools       |                          []                       |  6
-     wastesedge         |                                                   |  2
-     wdiff              | []                       []                       |  7
-     wget               | []                 []    []      []          []   | 26
-     wyslij-po          |                       [] []                       |  8
-     xchat              | []              []    [] []      []          []   | 36
-     xdg-user-dirs      | []     [] []    [] [] [] []      []    []    []   | 63
-     xkeyboard-config   | []                    [] []                       | 22
+     util-linux         |          [] []     []                             | 20
+     util-linux-ng      |          [] []     []                             | 20
+     vorbis-tools       |             []     []                             |  4
+     wastesedge         |                                                   |  1
+     wdiff              |          []        []                             | 23
+     wget               |          []        []                     []      | 20
+     xchat              |             []     []         []          []      | 29
+     xkeyboard-config   |          [] []     []                             | 14
+     xpad               |                    []         []          []      | 15
                         +---------------------------------------------------+
-       85 teams           sv  sw ta te tg th tr uk vi  wa zh_CN zh_HK zh_TW
-      178 domains         119  1  3  3  0 10 65 51 155 17  98     7    41    2618
+       76 teams           tg th tk tr uk ven vi  wa xh zh_CN zh_HK zh_TW zu
+      163 domains          0  3  1 74 51  0  143 21  1  57     7    45    0  2036
 
    Some counters in the preceding matrix are higher than the number of
 visible blocks let us expect.  This is because a few extra PO files are
@@ -1256,12 +1042,12 @@ distributed as such by its maintainer.  There might be an observable
 lag between the mere existence a PO file and its wide availability in a
 distribution.
 
-   If June 2010 seems to be old, you may fetch a more recent copy of
-this `ABOUT-NLS' file on most GNU archive sites.  The most up-to-date
-matrix with full percentage details can be found at
+   If November 2007 seems to be old, you may fetch a more recent copy
+of this `ABOUT-NLS' file on most GNU archive sites.  The most
+up-to-date matrix with full percentage details can be found at
 `http://translationproject.org/extra/matrix.html'.
 
-1.5 Using `gettext' in new packages
+1.6 Using `gettext' in new packages
 ===================================
 
 If you are writing a freely available program and want to
diff --git a/AUTHORS b/AUTHORS
index 7e97c85..eb42043 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,9 +1,10 @@
 Program: GnuPG
 Homepage: https://www.gnupg.org
+Download: ftp://ftp.gnupg.org/gcrypt/gnupg/
+Repository: git://git.gnupg.org/gnupg.git
 Maintainer: Werner Koch <wk@gnupg.org>
 Bug reports: http://bugs.gnupg.org
 Security related bug reports: <security@gnupg.org>
-End-of-life: 2017-12-31
 License: GPLv3+
 
 GnuPG is free software.  See the files COPYING for copying conditions.
@@ -11,12 +12,37 @@ License copyright years may be listed using range notation, e.g.,
 2000-2013, indicating that every year in the range, inclusive, is a
 copyrightable year that would otherwise be listed individually.
 
+List of Copyright holders
+=========================
+
+  Copyright (C) 1997-2014 Werner Koch
+  Copyright (C) 1994-2013 Free Software Foundation, Inc.
+  Copyright (C) 2003-2013 g10 Code GmbH
+  Copyright (C) 2002 Klarälvdalens Datakonsult AB
+  Copyright (C) 1995-1997, 2000-2007 Ulrich Drepper <drepper@gnu.ai.mit.edu>
+  Copyright (C) 1994 X Consortium
+  Copyright (C) 1998 by The Internet Society.
+  Copyright (C) 1998-2004 The OpenLDAP Foundation
+  Copyright (C) 1998-2004 Kurt D. Zeilenga.
+  Copyright (C) 1998-2004 Net Boolean Incorporated.
+  Copyright (C) 2001-2004 IBM Corporation.
+  Copyright (C) 1999-2003 Howard Y.H. Chu.
+  Copyright (C) 1999-2003 Symas Corporation.
+  Copyright (C) 1998-2003 Hallvard B. Furuseth.
+  Copyright (C) 1992-1996 Regents of the University of Michigan.
+
+
 
 Authors with a FSF copyright assignment
 =======================================
 
 Ales Nyakhaychyk <nyakhaychyk@i1fn.linux.by> Translations [be]
 
+Andrey Jivsov <openpgp@brainhub.org>  Assigns past and future changes for ECC.
+    (g10/ecdh.c.  other changes to support ECC)
+
+Ben Kibbey  <bjk@luxsci.net>  Assigns past and future changes.
+
 Birger Langkjer <birger.langkjer@image.dk> Translations [da]
 
 Maxim Britov <maxim.britov@gmail.com> Translations [ru]
@@ -99,8 +125,6 @@ Pavel I. Shajdo <pshajdo@gmail.com> Translations [ru]
 
 Pedro Morais <morais@poli.org> Translations [pt_PT]
 
-Petr Pisar <petr.pisar@atlas.cz> Translations [cs]
-
 Rémi Guyomarch        <rguyom@mail.dotcom.fr> Assigns past and future changes.
     (g10/compress.c, g10/encr-data.c,
      g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
@@ -130,12 +154,39 @@ Yosiaki IIDA <iida@ring.gr.jp> Translations [ja]
 
 Yuri Chornoivan, yurchor at ukr dot net: Translations [uk]
 
+Yutaka Niibe   Assigns Past and Future Changes
+     (scd/)
+
 
 Authors with a DCO
 ==================
 
-The list of authors who signed the Developer's Certificate of Origin
-is kept in the GIT master branch's copy of this file.
+Andre Heinecke <aheinecke@intevation.de>
+2014-09-19:4525694.FcpLvWDUFT@esus:
+
+Andreas Schwier <andreas.schwier@cardcontact.de>
+2014-07-22:53CED1D8.1010306@cardcontact.de:
+
+Christian Aistleitner <christian@quelltextlich.at>
+2013-05-26:20130626112332.GA2228@quelltextlich.at:
+
+Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+2014-09-24:87oau6w9q7.fsf@alice.fifthhorseman.net:
+
+Hans of Guardian <hans@guardianproject.info>
+2013-06-26:D84473D7-F3F7-43D5-A9CE-16580B88D574@guardianproject.info:
+
+Jonas Borgström <jonas@borgstrom.se>
+2013-08-29:521F1E7A.5080602@borgstrom.se:
+
+Kyle Butt <kylebutt@gmail.com>
+2013-05-29:CAAODAYLbCtqOG6msLLL0UTdASKWT6u2ptxsgUQ1JpusBESBoNQ@mail.gmail.com:
+
+Stefan Tomanek <tomanek@internet-sicherheit.de>
+2014-01-30:20140129234449.GY30808@zirkel.wertarbyte.de:
+
+Werner Koch <wk@gnupg.org>
+2013-03-29:87620ahchj.fsf@vigenere.g10code.de:
 
 
 Other authors
@@ -145,10 +196,6 @@ The need for copyright assignments to the FSF has been waived on
 2013-03-29; the need for copyright disclaimers for translations
 already in December 2012.
 
-The files common/libestream.[ch] are maintained as a separate project
-by g10 Code GmbH.  These files, as used here, are considered part of
-GnuPG.
-
 The RPM specs file scripts/gnupg.spec has been contributed by
 several people.
 
@@ -163,29 +210,18 @@ Copyright
 =========
 
 GnuPG is distributed under the GNU General Public License, version 3
-or later.  A few files are under the Lesser General Public License, a
-few other files carry the all permissive license note as found at the
-bottom of this file.  Certain files in keyserver/ allow one specific
-exception:
-
-  In addition, as a special exception, the Free Software Foundation
-  gives permission to link the code of the keyserver helper tools:
-  gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
-  project's "OpenSSL" library (or with modified versions of it that
-  use the same license as the "OpenSSL" library), and distribute the
-  linked executables.  You must obey the GNU General Public License
-  in all respects for all of the code used other than "OpenSSL".  If
-  you modify this file, you may extend this exception to your version
-  of the file, but you are not obligated to do so.  If you do not
-  wish to do so, delete this exception statement from your version.
-
-Note that the gpgkeys_* binaries are currently installed under the
-name gpg2keys_*.
+or later.
+
+Note that some files are under a combination of the GNU Lesser General
+Public License, version 3 and the GNU General Public License, version
+2.  A few other files carry the all permissive license note as found
+at the bottom of this file.
+
 
 =========
 
- Copyright 1997-2015 Werner Koch
  Copyright 1998-2013 Free Software Foundation, Inc.
+ Copyright 1997-2014 Werner Koch
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without
@@ -194,4 +230,3 @@ name gpg2keys_*.
  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.
-
index 46320b2..cfba8f4 100644 (file)
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-11-29  Werner Koch  <wk@g10code.com>
 
-       Release 2.0.18.
+       * autogen.sh: Make sure HOME et al have no unsafe characters.
 
-       * configure.ac: Fix usage of AC_LANG_PROGRAM.
-       (AC_CHECK_HEADERS): Check for utmp.h.
+2011-11-28  Jim Meyering  <meyering@redhat.com>
+
+       accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix
+       * m4/gpg-error.m4: Update from git master.
+
+2011-09-23  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Remove check for gcry_kdf_derive.
+
+2011-08-10  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Fix new autoconf warnings.
+
+2011-05-20  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Require libgpg-error 1.10.
+
+2011-03-08  Werner Koch  <wk@g10code.com>
+
+       Release 2.1.0beta2.
+
+       * configure.ac: Require libgcrypt 1.5.0.
+       (HAVE_GCRY_PK_ECDH, HAVE_GCRY_PK_GET_CURVE): Remove.
+       (utmp.h): Check for header.
+
+2011-02-25  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Require libksba 1.2.
 
 2011-02-04  Werner Koch  <wk@g10code.com>
 
        * autogen.sh: Ensure that the git pre-commit hoom has been
        enabled.  Add a cleanpo filter if not yet set.
 
-2011-01-13  Werner Koch  <wk@g10code.com>
+2011-02-03  Werner Koch  <wk@g10code.com>
 
-       Release 2.0.17.
+       * configure.ac (HAVE_GCRY_PK_GET_CURVE): Use AC_TRY_LINK.
 
-2011-01-11  Werner Koch  <wk@g10code.com>
+2011-02-01  Werner Koch  <wk@g10code.com>
 
-       * configure.ac: Add option --enable-gpgtar.
-       (AC_CHECK_FUNCS): Add stat.
+       * configure.ac (HAVE_GCRY_PK_GET_CURVE): Define if availabale.
+
+2011-01-20  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (AC_CONFIG_FILES): Remove keyserver/.
+
+2011-01-19  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add new option --enable-gpg2-is-gpg.
+       (NAME_OF_INSTALLED_GPG): New ac_define.
+       * autogen.sh [--build-w32ce]: Use --enable-gpg2-is-gpg.
+
+2011-01-21  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP.
+       (HAVE_GCRY_PK_ECDH): Add new test.
+
+2011-01-03  Werner Koch  <wk@g10code.com>
+
+       * README.SVN:  Rename to README.GIT.
+       * Makefile.am (EXTRA_DIST): Adjust for that change.
+
+2010-12-14  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (BUILD_WITH_GPG, BUILD_WITH_GPGSM)
+       (BUILD_WITH_AGENT, BUILD_WITH_SCDAEMON, BUILD_WITH_DIRMNGR)
+       (BUILD_WITH_G13): New defines.
+
+2010-11-23  Werner Koch  <wk@g10code.com>
+
+       * am/cmacros.am (extra_bin_ldflags): New.  For W32CE set the stack
+       size to 256k.
+
+2010-11-17  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (ENABLE_CARD_SUPPORT): Define.
+
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * acinclude.m4 (GNUPG_TIME_T_UNSIGNED): New.
+       * configure.ac (AC_HEADER_TIME): Include before checking time_t.
+       (GNUPG_TIME_T_UNSIGNED): Add.
+
+2010-10-26  Werner Koch  <wk@g10code.com>
+
+       Release 2.1.0beta1.
+
+2010-10-18  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (install-data-hook): Add W32 specific hook.
+
+2010-10-08  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add option --enable-dirmngr-auto-start.
+       (USE_DIRMNGR_AUTO_START): New ac_define.
+       * autogen.sh <--build-w32ce>: Use new option.
+
+2010-10-06  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Make --enable-standard-socket the default.
+
+2010-10-04  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (GNUPG_CHECK_FAQPROG): Remove.
+
+2010-08-19  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (AH_BOTTOM): Define GPG_ERR_ENABLE_ERRNO_MACROS.
+
+2010-08-09  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (inet_pton): Check for it.
+
+2010-08-05  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (AH_BOTTOM): Remove HTTP_USE_ESTREAM.
 
-       * autogen.sh <w32>: Remove superfluous --without-included-gettext.
+2010-08-02  Werner Koch  <wk@g10code.com>
 
-2011-01-10  Werner Koch  <wk@g10code.com>
+       * configure.ac: Require libksba 1.1.0 due to the use of
+       ksba_reader_set_release_notify.
 
-       * configure.ac: Support a git_revision string.
+2010-07-30  Werner Koch  <wk@g10code.com>
 
-2010-07-19  Werner Koch  <wk@g10code.com>
+       * configure.ac (GNUPG_PTH_PATH) [W32]: Require version 2.0.3.
 
-       Release 2.0.16.
+2010-07-25  Werner Koch  <wk@g10code.com>
 
-       * configure.ac: Require libgpg-error 1.7 and libksba 1.0.7 to
-       force building with more recent versions.
+       * configure.ac (USE_LDAPWRAPPER): AC_DEFINE and AM_CONDITIONAL it.
 
-2010-05-04  Werner Koch  <wk@g10code.com>
+2010-06-09  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (GNUPG_DIRMNGR_LDAP_PGM): Add option
+       --with-dirmngr-ldap-pgm.
+
+       * am/cmacros.am (-DGNUPG_LOCALSTATEDIR): New.
+       (GNUPG_DEFAULT_DIRMNGR_LDAP): New.
+
+2010-06-08  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add build support for dirmngr.
+       (try_ldap): Rename to try_ks_ldap.
+       (GNUPG_CHECK_LDAP): Also test if dirmngr is to be build.
+
+       * Makefile.am (SUBDIRS): Add dirmngr.
+
+2010-06-07  Werner Koch  <wk@g10code.com>
+
+       * dirmngr/: New.
+
+       * configure.ac: Add option --enable-gpgtar.
+
+2010-05-31  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (AC_CHECK_FUNCS): Check for lstat.
+
+2010-04-30  Werner Koch  <wk@g10code.com>
 
        * configure.ac: Add option --enable-standard-socket.
+       (USE_STANDARD_SOCKET): ac_define it.
 
-2010-03-09  Werner Koch  <wk@g10code.com>
+2010-04-14  Werner Koch  <wk@g10code.com>
 
-       Release 2.0.15.
+       * Makefile.am (keyserver) [W32CE]: Do not build for now.
 
-       * configure.ac: Add option --disable-ccid-driver.
+       * configure.ac (use_zip): New.
+       (--disable-zip): New option.
+       (HAVE_ZIP): New.
+       * autogen.sh <build-w32ce>: Disable ZIP.
 
-2010-02-18  Werner Koch  <wk@g10code.com>
+2010-04-07  Werner Koch  <wk@g10code.com>
 
-       Release 2.0.15rc1.
+       * autogen.sh: Take a .gnupg-autogen.rc file in account.
 
-       * configure.ac: Remove double check for libassuan.
+       * gl/mkdtemp.c (getpid) [W32CE]: New macro.
 
-2010-02-11  Marcus Brinkmann  <marcus@g10code.de>
+2010-03-24  Werner Koch  <wk@g10code.com>
 
-       From trunk 2009-10-16:
+       * configure.ac (AH_BOTTOM): Use /gnupg as the default homedir on
+       dosish systems which don't support drive letters (e.g. W32CE).
 
-       * configure.ac: Check for libassuan instead of libassuan-pth.
+       * am/cmacros.am (extra_sys_libs): New.
 
-2009-10-12  Werner Koch  <wk@g10code.com>
+2010-03-23  Werner Koch  <wk@g10code.com>
 
-       From trunk 2009-09-23:
+       * configure.ac (W32SOCKLIBS): Change value for W32CE.
 
-       * configure.ac (NEED_LIBASSUAN_API, NEED_LIBASSUAN_VERSION):
-       Update to new API (2, 1.1.0).
+2010-03-12  Werner Koch  <wk@g10code.com>
 
-2009-12-21  Werner Koch  <wk@g10code.com>
+       * configure.ac (AC_INIT): Prepare for using git.
 
-       Release 2.0.14.
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * jnlib/: Move all code to common/.
+       * Makefile.am (SUBDIRS): Remove jnlib.
+       * configure.ac (AC_CONFIG_FILES): Remove jnlib/Makefile.
+
+       * configure.ac (AM_PATH_LIBASSUAN): Remove double test.
+       * acinclude.m4 (GNUPG_CHECK_ENDIAN): Remove bogus warning.
+
+2010-03-09  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add option --disable-ccid-driver.
+       (AH_BOTTOM): Define GPG_ERR_ENABLE_GETTEXT_MACROS.
+
+2010-02-26  Werner Koch  <wk@g10code.com>
+
+       * gl/mkdtemp.c (__set_errno) [W32CE]: Use gpg_err_set_errno.
+       * gl/setenv.c (__set_errno) [W32CE]: Ditto.
+       * gl/unsetenv.c (__set_errno) [W32CE]: Ditto.
+
+       * configure.ac (HAVE_W32CE_SYSTEM): New ac_define and
+       am_conditional.
+       (signal.h, getenv): Check for them.
+
+       * autogen.sh: New option --build-w32ce.  Remove obsolete option
+       --without-included-gettext.
 
 2009-12-08  Werner Koch  <wk@g10code.com>
 
-       * configure.ac (USE_DNS_CERT): Support via ADNS.
+       * configure.ac (USE_DNS_CERT): Support ADNS.
 
 2009-12-07  Werner Koch  <wk@g10code.com>
 
        resolver.
        (USE_ADNS): Fallback macro for PKA and CERT lookups.
 
+2009-10-20  Marcus Brinkmann  <marcus@g10code.com>
+
+       * configure.ac: Check for fusermount and encfs.
+
+2009-10-16  Marcus Brinkmann  <marcus@g10code.com>
+
+       * configure.ac: Check for libassuan instead of libassuan-pth.
+
+2009-10-12  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Use -O3 because newer gcc versions require that
+       for uninitialized variable warnings.
+
+2009-09-23  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Remove test.
+       (_ASSUAN_ONLY_GPG_ERRORS): Remove.
+
+2009-09-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac (NEED_LIBASSUAN_API, NEED_LIBASSUAN_VERSION):
+       Update to new API (2, 1.1.0).
+
+2009-09-21  Werner Koch  <wk@g10code.com>
+
+       Start a new development branch in the SVN trunk.  The stable one
+       is now known in the SVN as branches/GNUPG-STABLE-2-0.
+
 2009-09-04  Werner Koch  <wk@g10code.com>
 
        Release 2.0.13.
 2006-09-06  Werner Koch  <wk@g10code.com>
 
        * configure.ac: Define _ASSUAN_ONLY_GPG_ERRORS.  Require Assuan
-       0.9 and libgpg-error 1.4
+       0.9 and libgpg-error 1.4.
 
 2006-08-31  Werner Koch  <wk@g10code.com>
 
 2002-05-14  Werner Koch  <wk@gnupg.org>
 
        * doc/: New
-       * configure.ac, Makefile.am:  Added doc/
+       * configure.ac, Makefile.am:  Added doc/.
 
 2002-05-03  Werner Koch  <wk@gnupg.org>
 
        * configure.ac (HAVE_JNLIB_LOGGING): always define it.
 
 
- Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007.
           2010 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 8cf7ff9..466c011 100644 (file)
@@ -1,5 +1,5 @@
-# Makefile.am - Top level makefile for GnuPG
-#      Copyright (C) 2001, 2004, 2012 Free Software Foundation, Inc.
+# Makefile.am - main makefile for GnuPG
+#      Copyright (C) 2001, 2004, 2010 Free Software Foundation, Inc.
 #
 # This file is part of GnuPG.
 #
@@ -23,8 +23,25 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun --enable-mailto --enable-gpgtar
 
 GITLOG_TO_CHANGELOG=gitlog-to-changelog
 
-EXTRA_DIST = scripts/config.rpath autogen.sh README.GIT              \
-            ChangeLog-2011 po/ChangeLog-2011 scripts/ChangeLog-2011
+EXTRA_DIST = build-aux/config.rpath build-aux/potomo autogen.sh autogen.rc \
+            ChangeLog-2011 po/ChangeLog-2011 build-aux/ChangeLog-2011 \
+            VERSION README.GIT build-aux/gitlog-to-changelog \
+            build-aux/git-log-fix build-aux/git-log-footer \
+            build-aux/getswdb.sh                           \
+            build-aux/speedo.mk                            \
+             build-aux/speedo/zlib.pc                      \
+             build-aux/speedo/w32/inst-options.ini         \
+             build-aux/speedo/w32/inst.nsi                 \
+             build-aux/speedo/w32/pkg-copyright.txt        \
+             build-aux/speedo/w32/g4wihelp.c               \
+             build-aux/speedo/w32/pango.modules                    \
+             build-aux/speedo/w32/gdk-pixbuf-loaders.cache  \
+             build-aux/speedo/w32/exdll.h                  \
+             build-aux/speedo/w32/README.txt               \
+             build-aux/speedo/patches/atk-1.32.0.patch     \
+             build-aux/speedo/patches/libiconv-1.14.patch   \
+             build-aux/speedo/patches/pango-1.29.4.patch
+
 
 DISTCLEANFILES = g10defs.h
 
@@ -37,10 +54,8 @@ endif
 
 if BUILD_GPG
 gpg = g10
-keyserver = keyserver
 else
 gpg =
-keyserver =
 endif
 if BUILD_GPGSM
 sm = sm
@@ -57,6 +72,16 @@ scd = scd
 else
 scd =
 endif
+if BUILD_G13
+g13 = g13
+else
+g13 =
+endif
+if BUILD_DIRMNGR
+dirmngr = dirmngr
+else
+dirmngr =
+endif
 if BUILD_TOOLS
 tools = tools
 else
@@ -68,46 +93,44 @@ else
 doc =
 endif
 
-if HAVE_W32_SYSTEM
-tests =
-else
+if RUN_TESTS
 tests = tests
+else
+tests =
 endif
 
-SUBDIRS = m4 gl include jnlib common ${kbx} \
- ${gpg} ${keyserver} ${sm} ${agent} ${scd} ${tools} po ${doc} ${tests}
+SUBDIRS = m4 gl common ${kbx} \
+          ${gpg} ${sm} ${agent} ${scd} ${g13} ${dirmngr} \
+          ${tools} po ${doc} ${tests}
 
 dist_doc_DATA = README
 
 
 dist-hook: gen-ChangeLog
-       echo "$(VERSION)" > $(distdir)/VERSION
-
-distcheck-hook:
-       set -e; ( \
-       pref="#+macro: gnupg_" ;\
-       reldate="$$(date -u +%Y-%m-%d)" ;\
-        echo "$${pref}ver  $(PACKAGE_VERSION)"  ;\
-        echo "$${pref}date $${reldate}" ;\
-        list='$(DIST_ARCHIVES)'; for i in $$list; do \
-         case "$$i" in *.tar.bz2) \
-            echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\
-           echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\
-           echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\
-         esac;\
-       done ) | tee $(distdir).swdb
+
+if HAVE_W32_SYSTEM
+install-data-hook:
+       set -e; \
+       for i in $$($(top_srcdir)/build-aux/potomo \
+                     --get-linguas $(top_srcdir)/po) ; do \
+           $(MKDIR_P) "$(DESTDIR)$(localedir)/$$i/LC_MESSAGES" || true; \
+           rm -f "$(DESTDIR)$(localedir)/$$i/LC_MESSAGES/gnupg2.mo" \
+                                                 2>/dev/null || true; \
+           $(top_srcdir)/build-aux/potomo $(top_srcdir)/po/$$i.po \
+              "$(DESTDIR)$(localedir)/$$i/LC_MESSAGES/gnupg2.mo" ; \
+       done
+endif
 
 
 gen_start_date = 2011-12-01T06:00:00
 .PHONY: gen-ChangeLog
 gen-ChangeLog:
-       set -e;                                                         \
-       if test -e $(top_srcdir)/.git; then                             \
+       if test -d $(top_srcdir)/.git; then                             \
          (cd $(top_srcdir) &&                                          \
            $(GITLOG_TO_CHANGELOG) --append-dot --tear-off              \
-           --amend=scripts/git-log-fix                                 \
+           --amend=build-aux/git-log-fix                               \
            --since=$(gen_start_date) ) > $(distdir)/cl-t;              \
-          cat $(top_srcdir)/scripts/git-log-footer >> $(distdir)/cl-t;  \
+          cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;  \
          rm -f $(distdir)/ChangeLog;                                   \
          mv $(distdir)/cl-t $(distdir)/ChangeLog;                      \
        fi
diff --git a/NEWS b/NEWS
index cdf2352..802e26e 100644 (file)
--- a/NEWS
+++ b/NEWS
-Noteworthy changes in version 2.0.31 (2017-12-29)
--------------------------------------------------
+Noteworthy changes in version 2.1.0 (2014-11-06)
+------------------------------------------------
 
- This 2.0 branch has reached end-of-life.  Please upgrade to 2.2.
+ This release introduces a lot of changes.  Most of them are internal
+ and thus not user visible.  However, some long standing behavior has
+ slightly changed and it is strongly suggested that an existing
+ "~/.gnupg" directory is backed up before this version is used.
 
- * Minor changes collected over the last 21 months
+ A verbose description of the major new features and changes can be
+ found in the file doc/whats-new-in-2.1.txt.
 
+ * gpg: All support for v3 (PGP 2) keys has been dropped.  All
+   signatures are now created as v4 signatures.  v3 keys will be
+   removed from the keyring.
 
-Noteworthy changes in version 2.0.30 (2016-03-31)
--------------------------------------------------
+ * gpg: With pinentry-0.9.0 the passphrase "enter again" prompt shows
+   up in the same window as the "new passphrase" prompt.
 
- * gpg: Avoid too early timeout during key generation with 2.1 cards.
+ * gpg: Allow importing keys with duplicated long key ids.
 
- * agent: Fixed printing of ssh fingerprints for 384 bit ECDSA keys.
+ * dirmngr: May now be build without support for LDAP.
 
- * agent: Fixed an alignment bug related to the passphrase
-   confirmation.
+ * For a complete list of changes see the lists of changes for the
+   2.1.0 beta versions below.  Note that all relevant fixes from
+   versions 2.0.14 to 2.0.26 are also applied to this version.
 
- * scdaemon: Fixed a "conflicting usage" bug.
 
- * scdaemon: Fixed usb card reader removal problem on Windows 8 and
-   later.
+ [Noteworthy changes in version 2.1.0-beta864 (2014-10-03)]
 
- * Fixed a problem on AIX due to peculiarity with RLIMIT_NOFILE.
+ * gpg: Removed the GPG_AGENT_INFO related code.  GnuPG does now
+   always use a fixed socket name in its home directory.
 
- * Updated the Japanese and Dutch translations.
+ * gpg: Renamed --gen-key to --full-gen-key and re-added a --gen-key
+   command with less choices.
 
- * Fixed a few other bugs.
+ * gpg: Use SHA-256 for all signature types also on RSA keys.
 
+ * gpg: Default keyring is now created with a .kbx suffix.
 
-Noteworthy changes in version 2.0.29 (2015-09-08)
--------------------------------------------------
+ * gpg: Add a shortcut to the key capabilies menu (e.g. "=e" sets the
+   encryption capabilities).
 
- * gpg: Print a PGP-2 fingerprint again instead of a row of "0".
+ * gpg: Fixed obsolete options parsing.
 
- * gpg: Fixed a race condition from multiple several "gpg --verify".
+ * Further improvements for the alternative speedo build system.
 
- * gpg: Print FAILURE status lines to help GPGME.
 
- * gpgsm: Fixed a regression in CSR generation.
+ [Noteworthy changes in version 2.1.0-beta834 (2014-09-18)]
 
- * scdaemon: Fixed problems with some pinpads.
+ * gpg: Improved passphrase caching.
 
- * Fixed a few other bugs.
+ * gpg: Switched to algorithm number 22 for EdDSA.
 
+ * gpg: Removed CAST5 from the default preferences.
 
-Noteworthy changes in version 2.0.28 (2015-06-02)
--------------------------------------------------
+ * gpg: Order SHA-1 last in the hash preferences.
 
- * agent: Added support for an external password manager.
+ * gpg: Changed default cipher for --symmetric to AES-128.
 
- * gpg: New command --list-gcrypt-config.
+ * gpg: Fixed export of ECC keys and import of EdDSA keys.
 
- * gpg: Issue NEWSIG status lines during signature verification.
+ * dirmngr: Fixed the KS_FETCH command.
 
- * gpgsm: The default hash algo for a CSR is now SHA-256 and the
-   default encryption algo is AES-128.
+ * The speedo build system now downloads related packages and works
+   for non-Windows platforms.
 
- * scdaemon: Allow PC/SC reader selection by partial name match.
 
- * gpgtar: Fix extracting files with a size of a multiple of 512.
+ [Noteworthy changes in version 2.1.0-beta783 (2014-08-14)]
 
- * Fixed several other bugs.
+ * gpg: Add command --quick-gen-key.
 
- * Libgcrypt 1.5 is now required.
+ * gpg: Make --quick-sign-key promote local key signatures.
 
+ * gpg: Added "show-usage" sub-option to --list-options.
 
-Noteworthy changes in version 2.0.27 (2015-02-18)
--------------------------------------------------
+ * gpg: Screen keyserver responses to avoid importing unwanted keys
+   from rogue servers.
+
+ * gpg: Removed the option --pgp2 and --rfc1991 and the ability to
+   create PGP-2 compatible messages.
 
- * gpg: Detect faulty use of --verify on detached signatures.
+ * gpg: Removed options --compress-keys and --compress-sigs.
 
- * gpg: New import option "keep-ownertrust".
+ * gpg: Cap attribute packets at 16MB.
 
- * gpg: Uses SHA-256 for all signature types also on RSA keys.
+ * gpg: Improved output of --list-packets.
 
- * gpg: Added support for algo names when generating keys using the
-   --command-fd method.
+ * gpg: Make with-colons output of --search-keys work again.
 
- * gpg: Unless --allow-weak-digest-algos is used the insecure MD5
-   based fingerprints are shown as all zeroe
+ * gpgsm: Auto-create the ".gnupg" directory like gpg does.
 
- * gpg: Fixed DoS based on bogus and overlong key packets.
+ * agent: Fold new passphrase warning prompts into one.
 
- * gpg: Better error reporting for keyserver problems.
+ * scdaemon: Add support for the Smartcard-HSM card.
 
- * Fixed several bugs related to bogus keyrings and improved some
-   other code.
+ * scdaemon: Remove the use of the pcsc-wrapper.
 
 
-Noteworthy changes in version 2.0.26 (2014-08-12)
--------------------------------------------------
+ [Noteworthy changes in version 2.1.0-beta751 (2014-07-03)]
 
- * gpg: Fix a regression in 2.0.24 if a subkey id is given
-   to --recv-keys et al.
+ * gpg: Create revocation certificates during key generation.
 
- * gpg: Cap attribute packets at 16MB.
+ * gpg: Create exported secret keys and revocation certifciates with
+   mode 0700
 
- * gpgsm: Auto-create the ".gnupg" home directory in the same
-   way gpg does.
+ * gpg: The validity of user ids is now shown by default.  To revert
+   this add "list-options no-show-uid-validity" to gpg.conf.
 
- * scdaemon: Allow for certificates > 1024 when using PC/SC.
+ * gpg: Make export of secret keys work again.
 
+ * gpg: The output of --list-packets does now print the offset of the
+   packet and information about the packet header.
 
-Noteworthy changes in version 2.0.25 (2014-06-30)
--------------------------------------------------
+ * gpg: Avoid DoS due to garbled compressed data packets. [CVE-2014-4617]
 
- * gpg: Fix a regression in 2.0.24 if more than one keyid is given
-   to --recv-keys et al.
+ * gpg: Print more specific reason codes with the INV_RECP status.
 
  * gpg: Cap RSA and Elgamal keysize at 4096 bit also for unattended
    key generation.
 
- * gpgsm: Fix a DISPLAY related problem with --export-secret-key-p12.
+ * scdaemon: Support reader Gemalto IDBridge CT30 and pinpad of SCT
+   cyberJack go.
 
- * scdaemon: Support reader Gemalto IDBridge CT30.
+ * The speedo build system has been improved.  It is now also possible
+   to build a partly working installer for Windows.
 
 
-Noteworthy changes in version 2.0.24 (2014-06-24)
--------------------------------------------------
+ [Noteworthy changes in version 2.1.0-beta442 (2014-06-05)]
 
- * gpg: Avoid DoS due to garbled compressed data packets. [CVE-2014-4617]
+ * gpg: Changed the format of key listings.  To revert to the old
+   format the option --legacy-list-mode is available.
 
- * gpg: Screen keyserver responses to avoid importing unwanted keys
-   from rogue servers.
+ * gpg: Add experimental signature support using curve Ed25519 and
+   with a patched Libgcrypt also encryption support with Curve25519.
+   [Update: this encryption support has been removed from 2.1.0 until
+   we have agreed on a suitable format.]
 
- * gpg: The validity of user ids is now shown by default.  To revert
-   this add "list-options no-show-uid-validity" to gpg.conf.
+ * gpg: Allow use of Brainpool curves.
 
- * gpg: Print more specific reason codes with the INV_RECP status.
+ * gpg: Accepts a space separated fingerprint as user ID.  This
+   allows to copy and paste the fingerprint from the key listing.
 
- * gpg: Allow loading of a cert only key to an OpenPGP card.
+ * gpg: The hash algorithm is now printed for signature records in key
+   listings.
 
- * gpg-agent: Make ssh support for ECDSA keys work with Libgcrypt 1.6.
+ * gpg: Reject signatures made using the MD5 hash algorithm unless the
+   new option --allow-weak-digest-algos or --pgp2 are given.
 
+ * gpg: Print a warning if the Gnome-Keyring-Daemon intercepts the
+   communication with the gpg-agent.
 
-Noteworthy changes in version 2.0.23 (2014-06-03)
--------------------------------------------------
+ * gpg: New option --pinentry-mode.
 
- * gpg: Reject signatures made using the MD5 hash algorithm unless the
-   new option --allow-weak-digest-algos or --pgp2 are given.
+ * gpg: Fixed decryption using an OpenPGP card.
 
- * gpg: Do not create a trustdb file if --trust-model=always is used.
+ * gpg: Fixed bug with deeply nested compressed packets.
 
  * gpg: Only the major version number is by default included in the
    armored output.
 
- * gpg: Print a warning if the Gnome-Keyring-Daemon intercepts the
-   communication with the gpg-agent.
+ * gpg: Do not create a trustdb file if --trust-model=always is used.
 
- * gpg: The format of the fallback key listing ("gpg KEYFILE") is now more
-   aligned to the regular key listing ("gpg -k").
+ * gpg: Protect against rogue keyservers sending secret keys.
+
+ * gpg: The format of the fallback key listing ("gpg KEYFILE") is now
+   more aligned to the regular key listing ("gpg -k").
 
  * gpg: The option--show-session-key prints its output now before the
    decryption of the bulk message starts.
 
  * gpg: New %U expando for the photo viewer.
 
- * gpgsm: Improved handling of re-issued CA certificates.
+ * gpg,gpgsm: New option --with-secret.
 
- * scdaemon: Various fixes for pinpad equipped card readers.
-
* Minor bug fixes.
+ * gpgsm: By default the users are now asked via the Pinentry whether
+   they trust an X.509 root key.  To prohibit interactive marking of
  such keys, the new option --no-allow-mark-trusted may be used.
 
+ * gpgsm: New commands to export a secret RSA key in PKCS#1 or PKCS#8
+   format.
 
-Noteworthy changes in version 2.0.22 (2013-10-04)
--------------------------------------------------
+ * gpgsm: Improved handling of re-issued CA certificates.
 
- * Fixed possible infinite recursion in the compressed packet
-   parser. [CVE-2013-4402]
+ * agent: The included ssh agent does now support ECDSA keys.
 
- * Improved support for some card readers.
+ * agent: New option --enable-putty-support to allow gpg-agent on
+   Windows to act as a Pageant replacement with full smartcard support.
 
- * Prepared building with the forthcoming Libgcrypt 1.6.
+ * scdaemon: New option --enable-pinpad-varlen.
 
- * Protect against rogue keyservers sending secret keys.
+ * scdaemon: Various fixes for pinpad equipped card readers.
 
+ * scdaemon: Rename option --disable-pinpad (was --disable-keypad).
 
-Noteworthy changes in version 2.0.21 (2013-08-19)
--------------------------------------------------
+ * scdaemon: Better support fo CCID readers.  Now, internal CCID
+   driver supports readers with no auto configuration feature.
 
- * gpg-agent: By default the users are now asked via the Pinentry
-   whether they trust an X.509 root key.  To prohibit interactive
-   marking of such keys, the new option --no-allow-mark-trusted may
-   be used.
+ * dirmngr: Removed support for the original HKP keyserver which is
+   not anymore used by any site.
 
- * gpg-agent: The command KEYINFO has options to add info from
-   sshcontrol.
+ * dirmngr: Improved support for keyserver pools.
 
- * The included ssh agent does now support ECDSA keys.
+ * tools: New option --dirmngr for gpg-connect-agent.
 
- * The new option --enable-putty-support allows gpg-agent to act on
-   Windows as a Pageant replacement with full smartcard support.
+ * The GNU Pth library has been replaced by the new nPth library.
 
  * Support installation as portable application under Windows.
 
+ * All kind of other improvements - see the git log.
 
-Noteworthy changes in version 2.0.20 (2013-05-10)
--------------------------------------------------
-
- * Decryption using smartcards keys > 3072 bit does now work.
-
- * New meta option ignore-invalid-option to allow using the same
-   option file by other GnuPG versions.
-
- * gpg: The hash algorithm is now printed for sig records in key listings.
-
- * gpg: Skip invalid keyblock packets during import to avoid a DoS.
-
- * gpg: Correctly handle ports from DNS SRV records.
-
- * keyserver: Improve use of SRV records
-
- * gpg-agent: Avoid tty corruption when killing pinentry.
-
- * scdaemon: Improve detection of card insertion and removal.
-
- * scdaemon: Rename option --disable-keypad to --disable-pinpad.
-
- * scdaemon: Better support for CCID readers.  Now, the internal CCID
-   driver supports readers without the auto configuration feature.
 
- * scdaemon: Add pinpad input for PC/SC, if your reader has pinpad and
-   it supports variable length PIN input, and you specify
-   --enable-pinpad-varlen option.
+ [Noteworthy changes in version 2.1.0beta3 (2011-12-20)]
 
- * scdaemon: New option --enable-pinpad-varlen.
+ * gpg: Fixed regression in the secret key export function.
 
- * scdaemon: Install into libexecdir to avoid accidental execution
-   from the command line.
+ * gpg: Allow generation of card keys up to 4096 bit.
 
- * Support building using w64-mingw32.
+ * gpgsm: Preliminary support for the validation model "steed".
 
- * Assorted bug fixes.
+ * gpgsm: Improved certificate creation.
 
+ * agent: Support the SSH confirm flag.
 
-Noteworthy changes in version 2.0.19 (2012-03-27)
--------------------------------------------------
+ * agent: New option to select a passphrase mode.  The loopback
+   mode may be used to bypass Pinentry.
 
- * GPG now accepts a space separated fingerprint as a user ID.  This
-   allows to copy and paste the fingerprint from the key listing.
+ * agent: The Assuan commands KILLAGENT and KILLSCD are working again.
 
- * GPG now uses the longest key ID available.  Removed support for the
-   original HKP keyserver which is not anymore used by any site.
+ * scdaemon: Does not anymore block after changing a card (regression
+   fix).
 
- * Rebuild the trustdb after changing the option --min-cert-level.
+ * tools: gpg-connect-agent does now proberly display the help output
+   for "SCD HELP" commands.
 
- * Ukrainian translation.
 
- * Honor option --cert-digest-algo when creating a cert.
+ [Noteworthy changes in version 2.1.0beta2 (2011-03-08)]
 
- * Emit a DECRYPTION_INFO status line.
+ * gpg: ECC support as described by draft-jivsov-openpgp-ecc-06.txt
+   [Update: now known as RFC-6637].
 
- * Improved detection of JPEG files.
+ * gpg: Print "AES128" instead of "AES".  This change introduces a
+   little incompatibility for tools using "gpg --list-config".  We
+   hope that these tools are written robust enough to accept this new
+   algorithm name as well.
 
+ * gpgsm: New feature to create certificates from a parameter file.
+   Add prompt to the --gen-key UI to create self-signed certificates.
 
-Noteworthy changes in version 2.0.18 (2011-08-04)
--------------------------------------------------
+ * agent: TMPDIR is now also honored when creating a socket using
+   the --no-standard-socket option and with symcryptrun's temp files.
 
- * Bug fix for newer versions of Libgcrypt.
+ * scdaemon: Fixed a bug where scdaemon sends a signal to gpg-agent
+   running in non-daemon mode.
 
- * Support the SSH confirm flag and show SSH fingerprints in ssh
-   related pinentries.
+ * dirmngr: Fixed CRL loading under W32 (bug#1010).
 
- * Improved dirmngr/gpgsm interaction for OCSP.
+ * Dirmngr has taken over the function of the keyserver helpers.  Thus
+   we now have a specified direct interface to keyservers via Dirmngr.
+   LDAP, DNS and mail backends are not yet implemented.
 
- * Allow generation of card keys up to 4096 bit.
+ * Fixed TTY management for pinentries and session variable update
+   problem.
 
 
-Noteworthy changes in version 2.0.17 (2011-01-13)
--------------------------------------------------
+ [Noteworthy changes in version 2.1.0beta1 (2010-10-26)]
 
- * Allow more hash algorithms with the OpenPGP v2 card.
+ * gpg: secring.gpg is not anymore used but all secret key operations
+   are delegated to gpg-agent.  The import command moves secret keys
+   to the agent.
 
- * The gpg-agent now tests for a new gpg-agent.conf on a HUP.
+ * gpg: The OpenPGP import command is now able to merge secret keys.
 
- * Fixed output of "gpgconf --check-options".
+ * gpg: Encrypted OpenPGP messages with trailing data (e.g. other
+   OpenPGP packets) are now correctly parsed.
 
- * Fixed a bug where Scdaemon sends a signal to Gpg-agent running in
-   non-daemon mode.
+ * gpg: Given sufficient permissions Dirmngr is started automagically.
 
- * Fixed TTY management for pinentries and session variable update
-   problem.
+ * gpg: Fixed output of "gpgconf --check-options".
 
+ * gpg: Removed options --export-options(export-secret-subkey-passwd)
+   and --simple-sk-checksum.
 
-Noteworthy changes in version 2.0.16 (2010-07-19)
--------------------------------------------------
+ * gpg: New options --try-secret-key.
 
- * If the agent's --use-standard-socket option is active, all tools
-   try to start and daemonize the agent on the fly.  In the past this
-   was only supported on W32; on non-W32 systems the new configure
-   option --enable-standard-socket may now be used to use this feature
-   by default.
+ * gpg: Support DNS lookups for SRV, PKA and CERT on W32.
 
- * The gpg-agent commands KILLAGENT and RELOADAGENT are now available
-   on all platforms.
-
- * Minor bug fixes.
+ * gpgsm: The --audit-log feature is now more complete.
 
+ * gpgsm: The default for --include-cert is now to include all
+   certificates in the chain except for the root certificate.
 
-Noteworthy changes in version 2.0.15 (2010-03-09)
--------------------------------------------------
+ * gpgsm: New option --ignore-cert-extension.
 
- * New command --passwd for GPG.
+ * g13: The G13 tool for disk encryption key management has been
+   added.
 
- * Fixes a regression in 2.0.14 which prevented unprotection of new
-   or changed gpg-agent passphrases.
+ * agent: If the agent's --use-standard-socket option is active, all
+   tools try to start and daemonize the agent on the fly.  In the past
+   this was only supported on W32; on non-W32 systems the new
+   configure option --disable-standard-socket may now be used to
+   disable this new default.
 
- * Make use of libassuan 2.0 which is available as a DSO.
+ * agent: New and changed passphrases are now created with an
+   iteration count requiring about 100ms of CPU work.
 
+ * dirmngr: Dirmngr is now a part of this package.  It is now also
+   expected to run as a system service and the configuration
+   directories are changed to the GnuPG name space. [Update: 2.1.0
+   starts dirmngr on demand as user daemon.]
 
-Noteworthy changes in version 2.0.14 (2009-12-21)
--------------------------------------------------
-
- * The default for --include-cert is now to include all certificates
-   in the chain except for the root certificate.
+ * Support for Windows CE. [Update: This has not been tested for the
+   2.1.0 release]
 
  * Numerical values may now be used as an alternative to the
    debug-level keywords.
 
- * The GPGSM --audit-log feature is now more complete.
-
- * GPG now supports DNS lookups for SRV, PKA and CERT on W32.
-
- * New GPGSM option --ignore-cert-extension.
-
- * New and changed passphrases are now created with an iteration count
-   requiring about 100ms of CPU work.
-
 
 Noteworthy changes in version 2.0.13 (2009-09-04)
 -------------------------------------------------
@@ -1047,8 +1034,8 @@ Noteworthy changes in version 1.9.0 (2003-08-05)
    development branch.
 
 
- Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-           2010, 2011  Free Software Foundation, Inc.
+ Copyright 2002, 2003, 2004, 2005, 2006, 2007,
+           2008, 2009, 2010, 2011  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
diff --git a/README b/README
index 087f7ac..fef57aa 100644 (file)
--- a/README
+++ b/README
-                       The GNU Privacy Guard
-                      =======================
-                            Version 2.0
+                       The GNU Privacy Guard 2
+                      =========================
+                             Version 2.1
 
-   Copyright 1997-2015 Werner Koch
-   Copyright 1998-2015 Free Software Foundation, Inc.
+          Copyright 1997-2014 Werner Koch
+          Copyright 1998-2013 Free Software Foundation, Inc.
 
 
-NOTE: This branch is not anymore supported.
-      Please upgrade to version 2.2
+* INTRODUCTION
 
+  GnuPG is a complete and free implementation of the OpenPGP standard
+  as defined by RFC4880 (also known as PGP).  GnuPG allows to encrypt
+  and sign data and communication, features a versatile key management
+  system as well as access modules for public key directories.
 
-INTRODUCTION
-============
+  GnuPG, also known as GPG, is a command line tool with features for
+  easy integration with other applications.  A wealth of frontend
+  applications and libraries making use of GnuPG are available.  Since
+  version 2 GnuPG provides support for S/MIME and Secure Shell in
+  addition to OpenPGP.
 
-GnuPG is GNU's tool for secure communication and data storage.  It can
-be used to encrypt data and to create digital signatures.  It includes
-an advanced key management facility and is compliant with the proposed
-OpenPGP Internet standard as described in RFC4880 and the S/MIME
-standard as described by several RFCs.
+  GnuPG is Free Software (meaning that it respects your freedom). It
+  can be freely used, modified and distributed under the terms of the
+  GNU General Public License.
 
-GnuPG is distributed under the terms of the GNU General Public
-License.  See the file COPYING for details.  GnuPG works best on
-GNU/Linux or *BSD systems.  Most other Unices are also supported but
-are not as well tested as the Free Unices.
+  We are currently maintaining three branches of GnuPG:
 
-GnuPG 2.0 is the stable version of GnuPG integrating support for
-OpenPGP and S/MIME.  It does not conflict with an installed 1.4
-OpenPGP-only version.
+  - 2.1 (i.e. this release) is the latest development with a lot of
+    new features.
 
+  - 2.0 is the current stable version for general use.
 
+  - 1.4 is the old standalone version which is most suitable for older
+    or embedded platforms.
 
-BUILD INSTRUCTIONS
-==================
+  You may not install 2.1 and 2.0 at the same time.  However, it is
+  possible to install 1.4 along with any of the 2.x versions.
 
-GnuPG 2.0 depends on the following packages:
 
-  libgpg-error     (ftp://ftp.gnupg.org/gcrypt/libgpg-error/)
-  libgcrypt        (ftp://ftp.gnupg.org/gcrypt/libgcrypt/)
-  libksba          (ftp://ftp.gnupg.org/gcrypt/libksba/)
-  libassuan >= 2.0 (ftp://ftp.gnupg.org/gcrypt/libassuan/)
+* BUILD INSTRUCTIONS
 
-You also need the Pinentry package for most function of GnuPG; however
-it is not a build requirement.  Pinentry is available at
-ftp://ftp.gnupg.org/gcrypt/pinentry/ .
+  GnuPG 2.1 depends on the following GnuPG related packages:
 
-You should get the latest versions of course, the GnuPG configure
-script complains if a version is not sufficient.
+    npth         (ftp://ftp.gnupg.org/gcrypt/npth/)
+    libgpg-error (ftp://ftp.gnupg.org/gcrypt/libgpg-error/)
+    libgcrypt    (ftp://ftp.gnupg.org/gcrypt/libgcrypt/)
+    libksba      (ftp://ftp.gnupg.org/gcrypt/libksba/)
+    libassuan    (ftp://ftp.gnupg.org/gcrypt/libassuan/)
 
-After building and installing the above packages in the order as given
-above, you may now continue with GnuPG installation (you may also just
-try to build GnuPG to see whether your already installed versions are
-sufficient).
+  You should get the latest versions of course, the GnuPG configure
+  script complains if a version is not sufficient.
 
-As with all packages, you just have to do
+  For some advanced features several other libraries are required.
+  The configure script prints diagnostic messages if one of these
+  libraries is not available and a feature will not be available..
 
- ./configure
- make
- make install
+  You also need the Pinentry package for most functions of GnuPG;
+  however it is not a build requirement.  Pinentry is available at
+  ftp://ftp.gnupg.org/gcrypt/pinentry/ .
 
-(Before doing install you might need to become root.)
+  After building and installing the above packages in the order as
+  given above, you may continue with GnuPG installation (you may also
+  just try to build GnuPG to see whether your already installed
+  versions are sufficient).
 
-If everything succeeds, you have a working GnuPG with support for
-S/MIME and smartcards.  Note that there is no binary gpg but a gpg2 so
-that this package won't conflict with a GnuPG 1.4 installation.  gpg2
-behaves just like gpg.
+  As with all packages, you just have to do
 
-In case of problem please ask on gnupg-users@gnupg.org for advise.
+    ./configure
+    make
+    make install
 
-Note that the PKITS tests are always skipped unless you copy the PKITS
-test data file into the tests/pkits directory.
+  (Before doing install you might need to become root.)
 
+  If everything succeeds, you have a working GnuPG with support for
+  OpenPGP, S/MIME, ssh-agent, and smartcards.  Note that there is no
+  binary gpg but a gpg2 so that this package won't conflict with a
+  GnuPG 1.4 installation.  gpg2 behaves just like gpg.
 
-INCOMPATIBLE CHANGES
-====================
+  In case of problem please ask on the gnupg-users@gnupg.org mailing
+  list for advise.
 
-- With 2.0.20 the scdaemon option 'disable-keypad' has been renamed to
-  'disable-pinpad'.  If you are using this option in scdaemon.conf you
-  should rename it there.  In case you are using this option to work
-  around a problem with your card reader, you may want to test whether
-  this version of GnuPG works better with your reader.
+  Instruction on how to build for Windows can be found in the file
+  doc/HACKING in the section "How to build an installer for Windows".
+  This requires some experience as developer.
 
+  Note that the PKITS tests are always skipped unless you copy the
+  PKITS test data file into the tests/pkits directory.  There is no
+  need to run these test and some of them may even fail because the
+  test scripts are not yet complete.
 
-DOCUMENTATION
-=============
+  You may run
 
-The complete documentation is in the texinfo manual named
-`gnupg.info'.  Run "info gnupg" to read it.  If you want a a printable
-copy of the manual, change to the "doc" directory and enter "make pdf"
-For a HTML version enter "make html" and point your browser to
-gnupg.html/index.html.  Standard man pages for all components are
-provided as well.  An online version of the manual is available at
-https://gnupg.org/documentation/manuals/gnupg/ .  A version of the
-manual pertaining to the current development snapshot is at
-https://gnupg.org/documentation/manuals/gnupg-devel/ .
+    gpgconf --list-dirs
 
+  to view the default directories used by GnuPG.
 
-GNUPG 1.4 AND GNUPG 2.0
-=======================
+  To quickly build all required software without installing it, the
+  Speedo method may be used:
 
-GnuPG 2.0 is a newer version of GnuPG with additional support for
-S/MIME.  It has a different design philosophy that splits
-functionality up into several modules.  Both versions may be installed
-simultaneously without any conflict (gpg is called gpg2 in GnuPG 2).
-In fact, the gpg version from GnuPG 1.4 is able to make use of the
-gpg-agent as included in GnuPG 2 and allows for seamless passphrase
-caching.  The advantage of GnuPG 1.4 is its smaller size and no
-dependency on other modules at run and build time.
+    make -f build-aux/speedo.mk  native
 
+  This method downloads all required libraries and does a native build
+  of GnuPG to PLAY/inst/.  GNU make is required and you need to set
+  LD_LIBRARY_PATH to $(pwd)/PLAY/inst/lib to test the binaries.
 
-HOW TO GET MORE INFORMATION
-===========================
+** Specific build problems on some machines:
 
-The primary WWW page is "https://gnupg.org"
-           or using TOR "http://ic6au7wa3f6naxjq.onion"
-The primary FTP site is "ftp://ftp.gnupg.org/gcrypt/"
+*** Apple OSX 10.x using XCode
 
-See https://gnupg.org/download/mirrors.html for a list of mirrors and
-use them if possible.  You may also find GnuPG mirrored on some of the
-regular GNU mirrors.
+  On some versions the correct location of a header file can't be
+  detected by configure.  To fix that you should run configure like
+  this
 
-We have some mailing lists dedicated to GnuPG:
+    ./configure  gl_cv_absolute_stdint_h=/usr/include/stdint.h
 
-   gnupg-announce@gnupg.org   For important announcements like new
-                              versions and such stuff.  This is a
-                              moderated list and has very low traffic.
-                              Do not post to this list.
+  Add other options as needed.
 
-   gnupg-users@gnupg.org      For general user discussion and
-                              help (English).
 
-   gnupg-de@gnupg.org         German speaking counterpart of
-                              gnupg-users.
+* MIGRATION from 1.4 or 2.0 to 2.1
 
-   gnupg-ru@gnupg.org         Russian speaking counterpart of
-                              gnupg-users.
+  The major change in 2.1 is gpg-agent taking care of the OpenPGP
+  secret keys (those managed by GPG).  The former file "secring.gpg"
+  will not be used anymore.  Newly generated keys are stored in the
+  agent's key store directory "~/.gnupg/private-keys-v1.d/".  The
+  first time gpg needs a secret key it checks whether a "secring.gpg"
+  exists and copies them to the new store.  The old secring.gpg is
+  kept for use by older versions of gpg.
 
-   gnupg-devel@gnupg.org      GnuPG developers main forum.
+  Note that gpg-agent now uses a fixed socket.  All tools will start
+  the gpg-agent as needed.  The formerly used environment variable
+  GPG_AGENT_INFO is ignored by 2.1.  The SSH_AUTH_SOCK environment
+  variable should be set to a fixed value.
 
-You subscribe to one of the list by sending mail with a subject of
-"subscribe" to x-request@gnupg.org, where x is the name of the mailing
-list (gnupg-announce, gnupg-users, etc.).  An archive of the mailing
-lists is available at <https://gnupg.org/documentation/mailing-lists.html>.
+  The Dirmngr is now part of GnuPG proper and also used to access
+  OpenPGP keyservers.  The directory layout of Dirmngr changed to make
+  use of the GnuPG directories.  Dirmngr is started by gpg or gpgsm as
+  needed. There is no more need to install a separate Dirmngr package.
 
-Please direct bug reports to http://bugs.gnupg.org or post them direct
-to the mailing list <gnupg-devel@gnupg.org>.
 
-Please direct questions about GnuPG to the users mailing list or one
-of the pgp newsgroups; please do not direct questions to one of the
-authors directly as we are busy working on improvements and bug fixes.
-The English and German mailing lists are watched by the authors and we
-try to answer questions when time allows us to do so.
+* DOCUMENTATION
 
-Commercial grade support for GnuPG is available; for a listing of
-offers see https://gnupg.org/service.html .  Maintaining and
-improving GnuPG is costly.  For more than a decade, g10 Code GmbH, a
-German company owned and headed by GnuPG's principal author Werner
-Koch, is bearing the majority of these costs.  To help them carry on
-this work, they need your support.  See https://gnupg.org/donate/ .
+  The complete documentation is in the texinfo manual named
+  `gnupg.info'.  Run "info gnupg" to read it.  If you want a a
+  printable copy of the manual, change to the "doc" directory and
+  enter "make pdf" For a HTML version enter "make html" and point your
+  browser to gnupg.html/index.html.  Standard man pages for all
+  components are provided as well.  An online version of the manual is
+  available at http://www.gnupg.org/documentation/manuals/gnupg/ .  A
+  version of the manual pertaining to the current development snapshot
+  is at http://www.gnupg.org/documentation/manuals/gnupg-devel/ .
 
 
-  This file is Free Software; as a special exception the authors gives
-  unlimited permission to copy and/or distribute it, with or without
-  modifications, as long as this notice is preserved. For conditions
-  of the whole package, please see the file COPYING.  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.
+* GnuPG 1.4 and GnuPG 2.0
+
+  GnuPG 2.0 is a newer version of GnuPG with additional support for
+  S/MIME.  It has a different design philosophy that splits
+  functionality up into several modules.  Both versions may be
+  installed simultaneously without any conflict (gpg is called gpg2 in
+  GnuPG 2).  In fact, the gpg version from GnuPG 1.4 is able to make
+  use of the gpg-agent as included in GnuPG 2 and allows for seamless
+  passphrase caching.  The advantage of GnuPG 1.4 is its smaller size
+  and no dependency on other modules at run and build time.
+
+
+* HOW TO GET MORE INFORMATION
+
+  A description of new features and changes in version 2.1 can be
+  found in the file "doc/whats-new-in-2.1.txt" and online at
+  "https://gnupg.org/faq/whats-new-in-2.1.html" .
+
+  The primary WWW page is "https://www.gnupg.org"
+             or using TOR "http://ic6au7wa3f6naxjq.onion"
+  The primary FTP site is "ftp://ftp.gnupg.org/gcrypt/"
+
+  See https://www.gnupg.org/download/mirrors.html for a list of
+  mirrors and use them if possible.  You may also find GnuPG mirrored
+  on some of the regular GNU mirrors.
+
+  We have some mailing lists dedicated to GnuPG:
+
+     gnupg-announce@gnupg.org   For important announcements like new
+                                versions and such stuff.  This is a
+                                moderated list and has very low traffic.
+                                Do not post to this list.
+
+     gnupg-users@gnupg.org      For general user discussion and
+                                help (English).
+
+     gnupg-de@gnupg.org         German speaking counterpart of
+                                gnupg-users.
+
+     gnupg-ru@gnupg.org         Russian speaking counterpart of
+                                gnupg-users.
+
+     gnupg-devel@gnupg.org      GnuPG developers main forum.
+
+  You subscribe to one of the list by sending mail with a subject of
+  "subscribe" to x-request@gnupg.org, where x is the name of the
+  mailing list (gnupg-announce, gnupg-users, etc.). See
+  https://www.gnupg.org/documentation/mailing-lists.html for archives
+  of the mailing lists.
+
+  Please direct bug reports to http://bugs.gnupg.org or post them
+  direct to the mailing list <gnupg-devel@gnupg.org>.
+
+  Please direct questions about GnuPG to the users mailing list or one
+  of the PGP newsgroups; please do not direct questions to one of the
+  authors directly as we are busy working on improvements and bug
+  fixes.  The English and German mailing lists are watched by the
+  authors and we try to answer questions when time allows us.
+
+  Commercial grade support for GnuPG is available; for a listing of
+  offers see https://www.gnupg.org/service.html .  Maintaining and
+  improving GnuPG requires a lot of time.  Since 2001, g10 Code GmbH,
+  a German company owned and headed by GnuPG's principal author Werner
+  Koch, is bearing the majority of these costs.  To keep GnuPG in a
+  healthy state, they need your support.
+
+  Please consider to donate at https://gnupg.org/donate/ .
+
+
+# This file is Free Software; as a special exception the authors gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved. For conditions
+# of the whole package, please see the file COPYING.  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.
+#
+# Local Variables:
+# mode:org
+# End:
index 57dab7a..ee2c638 100644 (file)
@@ -17,8 +17,8 @@ variables to override the default tool names:
 
  AUTOMAKE_SUFFIX  is used as a suffix for all tools from the automake
                   package.  For example
-                     AUTOMAKE_SUFFIX="-1.14" ./autogen.sh
-                  uses "automake-1.14" and "aclocal-1.14.
+                     AUTOMAKE_SUFFIX="-1.7" ./autogen.sh
+                  uses "automake-1.7" and "aclocal-1.7.
  AUTOMAKE_PREFIX  is used as a prefix for all tools from the automake
                   page and may be combined with AUTOMAKE_SUFFIX. e.g.:
                     AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh
index d1286ef..9af6029 100644 (file)
@@ -1,4 +1,85 @@
             Notes for the GnuPG maintainer  (GIT only)
            ============================================
 
-    Please see GIT master for the current version of this file.
+Here are some notes on how to maintain GnuPG.
+
+Release Planning:
+=================
+
+If you are planning a new release and strings have changed you should
+send a notification to all translators, so that they have time to
+update their translations.  scripts/mail-to-translators is useful for
+this.  It might need some tweaking and it needs to be armored for
+actual sending.  Running it as is to see what will happen is a good
+idea, though.
+
+
+
+Release process:
+================
+
+  * Make sure that all new PO files are checked in.
+
+  * Decide whether you want to update the automake standard files
+    (Mainly config.guess and config.sub).
+
+  * [2.0] Copy needed texinfo files from master:
+      make -C doc update-source
+
+  * Run:
+      make -C po update-po
+
+  * Write NEWS entries and set the release date in NEWS.
+
+  * Commit all changes to GIT with a message of "Release n.m.o."
+
+  * Create a signed tag with the name "gnupg-x.y.z".
+
+  * Run "./autogen.sh --force"
+    (--force is required for the git magic in configure.ac and a good
+    idea in any case)
+
+  * Run "configure --enable-maintainer-mode".
+
+  * Run "make distcheck".
+
+  * Build and test the new tarball (best on a different machine).
+
+  * Build and test the W32 version.
+
+  * [2.x only] Using the final test build run a "make -C doc online".
+
+  * Sign the tarball
+
+  * Get the previous tarball and run "mkdiff gnupg".
+    You might need to set a different signature key than mine.  mkdiff
+    has an option for this.
+
+  * Push the git changes and the tag.
+
+  * Copy the files to the FTP server
+
+  * Update the webpages - at least the file swdb.mac needs an update.
+
+  * Add a new headline to NEWS.
+
+  * Bump the version number in configure.ac up, add an empty NEWS
+    entry, commit, and push that.
+
+  * Write an announcement.
+
+  * Update https://savannah.gnu.org/projects/gnupg .
+
+
+
+Gotchas
+=======
+
+- If during "make distcheck" you get an error about a permission
+  problem moving foo.new.po to foo.po; this is caused by a check
+  whether the po files can be re-created.  Now if the first tarball
+  has been created in a different top directory and if there exists a
+  no distributed file with the string "GNU gnupg" (e.g. a log file
+  from running make) you end up with different comments in the po
+  files.  Check out /usr/lib/gettext/project-id for that silliness.
+  As a hack we added this string into configure.ac.
diff --git a/THANKS b/THANKS
index 7a87406..d366707 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -105,11 +105,12 @@ Holger Smolinski     smolinsk at de.ibm.com
 Holger Trapp              Holger.Trapp at informatik.tu-chemnitz.de
 Hugh Daniel               hugh at toad.com
 Huy Le                    huyle at ugcs.caltech.edu
+Ian Abbott                 abbotti at mev.co.uk
 Ian McKellar              imckellar at harvestroad.com.au
 Ingo Klöcker               kloecker at kde.org
 Ivo Timmermans            itimmermans at bigfoot.com
 Jan Krueger               max at physics.otago.ac.nz
-Jan Niehusmann             jan at gondor.com  
+Jan Niehusmann             jan at gondor.com
 Jan-0liver Wagner          jan @ intevation.de
 Janusz A. Urbanowicz      alex at bofh.torun.pl
 James Troup               james at nocrew.org
@@ -141,20 +142,21 @@ Karl Fogel                   kfogel at guanabana.onshore.com
 Karsten Thygesen          karthy at kom.auc.dk
 Katsuhiro Kondou          kondou at nec.co.jp
 Kazu Yamamoto              kazu at iij.ad.jp
-Kazuyoshi Kakihara         
+Kazuyoshi Kakihara
 Keith Clayton              keith at claytons.org
 Ken Takusagawa             ken.takusagawa.2  at gmail.com
 Kevin Ryde                 user42 at zip.com.au
 Kiss Gabor                 kissg at ssg.ki.iif.hu
+Klaus Flittner             klaus at flittner org
 Klaus Singvogel            ks at caldera.de
 Kurt Garloff               garloff at suse.de
 Lars Kellogg-Stedman      lars at bu.edu
 L. Sassaman               rabbi at quickie.net
-M Taylor                   mctaylor at privacy.nb.ca                 
+M Taylor                   mctaylor at privacy.nb.ca
 Marcel Waldvogel           mwa at arl.wustl.edu
 Marco d'Itri               md at linux.it
 Marco Parrone              marc0 at autistici.org
-Marcus Brinkmann           Marcus.Brinkmann at ruhr-uni-bochum.de      
+Marcus Brinkmann           Marcus.Brinkmann at ruhr-uni-bochum.de
 Mark Adler                madler at alumni.caltech.edu
 Mark Elbrecht             snowball3 at bigfoot.com
 Mark Pettit                pettit at yahoo-inc.com
index d8f2e17..7c264a4 100644 (file)
@@ -7,12 +7,12 @@ dnl GnuPG is free software; you can redistribute it and/or modify
 dnl it under the terms of the GNU General Public License as published by
 dnl the Free Software Foundation; either version 3 of the License, or
 dnl (at your option) any later version.
-dnl 
+dnl
 dnl GnuPG is distributed in the hope that it will be useful,
 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 dnl GNU General Public License for more details.
-dnl 
+dnl
 dnl You should have received a copy of the GNU General Public License
 dnl along with this program; if not, see <http://www.gnu.org/licenses/>.
 
@@ -38,7 +38,7 @@ AC_DEFUN([GNUPG_CHECK_TYPEDEF],
 dnl GNUPG_CHECK_GNUMAKE
 dnl
 AC_DEFUN([GNUPG_CHECK_GNUMAKE],
-  [ 
+  [
     if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then
         :
     else
@@ -59,7 +59,7 @@ AC_DEFUN([GNUPG_CHECK_FAQPROG],
     if faqprog.pl -V 2>/dev/null | grep '^faqprog.pl ' >/dev/null 2>&1; then
         working_faqprog=yes
         FAQPROG="faqprog.pl"
-    else 
+    else
        working_faqprog=no
         FAQPROG=": "
     fi
@@ -77,7 +77,7 @@ dnl ***    ftp://ftp.gnupg.org/gcrypt/contrib/faqprog.pl )
 dnl *** No need to worry about this warning.
 dnl ***]])
 dnl     fi
-   ])       
+   ])
 
 dnl GNUPG_CHECK_DOCBOOK_TO_TEXI
 dnl
@@ -93,7 +93,7 @@ AC_DEFUN([GNUPG_CHECK_DOCBOOK_TO_TEXI],
     fi
     AC_MSG_RESULT($working_sgmltotexi)
     AM_CONDITIONAL(HAVE_DOCBOOK_TO_TEXI, test "$working_sgmltotexi" = "yes" )
-   ])       
+   ])
 
 
 
@@ -103,6 +103,7 @@ dnl
 AC_DEFUN([GNUPG_CHECK_ENDIAN],
   [
     tmp_assumed_endian=big
+    tmp_assume_warn=""
     if test "$cross_compiling" = yes; then
       case "$host_cpu" in
          i@<:@345678@:>@* )
@@ -111,7 +112,6 @@ AC_DEFUN([GNUPG_CHECK_ENDIAN],
          *)
             ;;
       esac
-      AC_MSG_WARN(cross compiling; assuming $tmp_assumed_endian endianess)
     fi
     AC_MSG_CHECKING(endianess)
     AC_CACHE_VAL(gnupg_cv_c_endian,
@@ -141,10 +141,11 @@ AC_DEFUN([GNUPG_CHECK_ENDIAN],
               gnupg_cv_c_endian=little,
               gnupg_cv_c_endian=big,
               gnupg_cv_c_endian=$tmp_assumed_endian
+              tmp_assumed_warn=" (assumed)"
             )
         fi
       ])
-    AC_MSG_RESULT([$gnupg_cv_c_endian])
+    AC_MSG_RESULT([${gnupg_cv_c_endian}${tmp_assumed_warn}])
     if test "$gnupg_cv_c_endian" = little; then
       AC_DEFINE(LITTLE_ENDIAN_HOST,1,
                 [Defined if the host has little endian byte ordering])
@@ -161,7 +162,7 @@ AC_DEFUN([GNUPG_CHECK_ENDIAN],
 # Add a --enable-NAME option to configure an set the
 # shell variable build_NAME either to "yes" or "no".  DEFAULT must
 # either be "yes" or "no" and decided on the default value for
-# build_NAME and whether --enable-NAME or --disable-NAME is shown with 
+# build_NAME and whether --enable-NAME or --disable-NAME is shown with
 # ./configure --help
 AC_DEFUN([GNUPG_BUILD_PROGRAM],
   [build_$1=$2
@@ -177,7 +178,7 @@ AC_DEFUN([GNUPG_BUILD_PROGRAM],
    case "$build_$1" in
          no|yes)
            ;;
-         *) 
+         *)
            AC_MSG_ERROR([only yes or no allowed for feature --enable-$1])
            ;;
    esac
@@ -185,6 +186,23 @@ AC_DEFUN([GNUPG_BUILD_PROGRAM],
 
 
 
+# GNUPG_DISABLE_GPG_ALGO(NAME,DESCRIPTION)
+#
+# Add a --disable-gpg-NAME option and the corresponding ac_define
+# GPG_USE_<NAME>.
+AC_DEFUN([GNUPG_GPG_DISABLE_ALGO],
+  [AC_MSG_CHECKING([whether to enable the $2 for gpg])
+   AC_ARG_ENABLE([gpg-$1], AC_HELP_STRING([--disable-gpg-$1],
+                                          [disable the $2 algorithm in gpg]),
+                                          , enableval=yes)
+   AC_MSG_RESULT($enableval)
+   if test x"$enableval" = xyes ; then
+     AC_DEFINE(GPG_USE_[]m4_toupper($1), 1, [Define to support the $2])
+   fi
+  ])
+
+
+
 
 # Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock
 # is not called from uid 0 (not tested whether uid 0 works)
@@ -304,5 +322,28 @@ fi
 ])
 
 
-
-
+# GNUPG_TIME_T_UNSIGNED
+# Check whether time_t is unsigned
+#
+AC_DEFUN([GNUPG_TIME_T_UNSIGNED],
+  [ AC_CACHE_CHECK(whether time_t is unsigned, gnupg_cv_time_t_unsigned,
+     [AC_REQUIRE([AC_HEADER_TIME])dnl
+      AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY(
+       [AC_INCLUDES_DEFAULT([])
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+],
+       [((time_t)-1) < 0])],
+       gnupg_cv_time_t_unsigned=no, gnupg_cv_time_t_unsigned=yes)])
+    if test $gnupg_cv_time_t_unsigned = yes; then
+      AC_DEFINE(HAVE_UNSIGNED_TIME_T,1,[Defined if time_t is an unsigned type])
+    fi
+])# GNUPG_TIME_T_UNSIGNED
index f543f27..f56be1f 100644 (file)
@@ -1,14 +1,64 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-11-28  Werner Koch  <wk@g10code.com>
 
-       * command.c (cmd_keyinfo, do_one_keyinfo): Support options --data
-       and --ssh-fpr.
+       * command-ssh.c (card_key_available): Change wording of no key
+       diagnostic.
+       (ssh_handler_request_identities): Do not call card_key_available
+       if the scdaemon is disabled.
+
+2011-09-12  Ben Kibbey <bjk@luxsci.net>
+
+       * genkey.c (agent_ask_new_passphrase): Allow for an empty passphrase
+       (no protection) in PINENTRY_MODE_LOOPBACK.
+
+2011-09-10  Ben Kibbey <bjk@luxsci.net>
+
+       * agent.h (pinentry_loopback): New prototype.
+       * command.c (pinentry_loopback): New function to inquire a passphrase
+       from the client. For use with pinentry-mode=loopback.
+       * call-pinentry.c (agent_askpin): Handle PINENTRY_MODE_LOOPBACK.
+       * call-pinentry.c (agent_get_passphrase): Ditto.
+       * genkey.c (agent_ask_new_passphrase): Ditto.
+
+2011-08-10  Werner Koch  <wk@g10code.com>
+
+       * genkey.c (check_passphrase_pattern): Use gpg_strerror instead of
+       strerror.
+       * command-ssh.c (ssh_receive_mpint_list): Remove unused var
+       ELEMS_PUBLIC_N.
+       * gpg-agent.c (main): Remove unused var MAY_COREDUMP.
+
+2011-08-09  Ben Kibbey <bjk@luxsci.net>
+
+       * command.c (option_handler): Have option s2k-count match the
+       documentation.
+
+2011-07-27  Werner Koch  <wk@g10code.com>
+
+       * call-scd.c (struct inq_needpin_s): Add field ANY_INQ_SEEN.
+       (inq_needpin): Set it.
+       (agent_card_scd): Send the cancel only if an inquire was actually
+       used.
+
+2011-07-09  Ben Kibbey <bjk@luxsci.net>
+
+       * call-scd.c (agent_card_scd): Send the CANCEL command back to SCD
+       when the SCD command is cancelled from the client.
+
+2011-07-22  Werner Koch  <wk@g10code.com>
+
+       * command-ssh.c (ssh_receive_key): Do not init comment to an empty
+       static string; in the error case it would be freed.
+
+2011-07-20  Werner Koch  <wk@g10code.com>
+
+       * command.c (do_one_keyinfo, cmd_keyinfo): Support option --ssh-fpr.
 
        * command-ssh.c (ssh_identity_register): Display the ssh
        fingerprint in the prompt.
        (search_control_file): Add new arg R_CONFIRM and enhance parser.
        * findkey.c (agent_raw_key_from_file): New.
        (modify_description): Add format letter %F.
-
        * findkey.c (agent_key_from_file): Simplify comment extraction by
        using gcry_sexp_nth_string.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-06-28  Ben Kibbey <bjk@luxsci.net>
 
-       * genkey.c (check_passphrase_pattern): Use gpg_strerror.
+       * command.c (option_handler): Add option s2k-count.
+       * agent.h (server_control_s): Add member s2k_count.
+       * genkey.c (store_key): Add parameter s2k_count.
+       * protect.c (agent_protect): Add parameter s2k_count.
+       * protect.c (do_encryption): Add parameter s2k_count.
 
-       * command-ssh.c (ssh_receive_mpint_list): Remove set but unused
-       var ELEMS_PUBLIC_N.
+2011-06-01  Marcus Brinkmann  <mb@g10code.com>
 
-       * gpg-agent.c (main): Remove set but unused var MAY_COREDUMP.
+       * cvt-openpgp.c (convert_to_openpgp): Change type of N to unsigned
+       int.
 
-2011-07-22  Werner Koch  <wk@g10code.com>
+2011-04-26  Werner Koch  <wk@g10code.com>
 
-       * command-ssh.c (ssh_receive_key): Do not init comment to an empty
-       static string; in the error case it would be freed.
+       * cvt-openpgp.c (convert_to_openpgp): Use rfc4880 encoded S2K count.
+       * protect.c (get_standard_s2k_count_rfc4880): New.
+       (S2K_DECODE_COUNT): New.
+       (s2k_hash_passphrase): Use the new macro.
+
+2011-04-21  Werner Koch  <wk@g10code.com>
+
+       * agent.h (server_control_s): Add field cache_ttl_opt_preset.
+       * gpg-agent.c (agent_init_default_ctrl): Init this field.
+       * genkey.c (agent_genkey): Use this new variable.
+       * command.c (cmd_passwd): Ditto.
+       (option_handler): Add new option cache-ttl-opt-preset.
+
+2011-04-20  Marcus Brinkmann  <mb@g10code.com>
+
+       * command.c (cmd_import_key): Release key from failed import
+        before converting openpgp private key in the openpgp-private-key
+        case.
+
+2011-04-17  Ben Kibbey <bjk@luxsci.net>
+
+       * command.c (cmd_passwd): Check for an error before presetting.
+
+2011-04-12  Ben Kibbey <bjk@luxsci.net>
+
+       * command.c (cmd_passwd): Fixed --preset when not previously cached.
+
+2011-04-12  Werner Koch  <wk@g10code.com>
+
+       * agent.h (CACHE_TTL_NONCE, CACHE_TTL_OPT_PRESET): New.
+       * command.c (cmd_passwd, cmd_import_key): Use new macros.
+       * genkey.c (agent_genkey): Ditto.
+
+2011-04-10  Ben Kibbey <bjk@luxsci.net>
+
+       * command.c (cmd_passwd): Add option --preset.
+       * command.c (cmd_genkey): Add option --preset.
+       * genkey.c (agent_genkey): Add parameter preset.
+
+2011-04-06  Ben Kibbey <bjk@luxsci.net>
+
+       * command.c (do_one_keyinfo): Add protection type field.
+
+2011-03-10  Werner Koch  <wk@g10code.com>
+
+       * protect.c (hash_passphrase): Use the new gcry_kdf_derive.
+
+2011-03-08  Werner Koch  <wk@g10code.com>
+
+       * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: Remove.
+
+2011-03-03  Ben Kibbey  <bjk@luxsci.net>
+
+       * command.c (cmd_preset_passphrase): Add option --inquire.
+
+2011-03-03  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c: Add option --allow-loopback-pinentry.
+       * command.c (option_handler): Add option pinentry-mode.
+       * agent.h (pinentry_mode_t): New enum.
+       (struct server_local_s): Add PINENTRY_MODE.
+       (struct opt): Add ALLOW_LOOPBACK_PINENTRY.
+       * call-pinentry.c (agent_askpin): Implement ask, cancel and error
+       pinentry modes.
+       (agent_get_passphrase, agent_get_confirmation): Ditto.
+       (agent_show_message): Return cancel if pinentry mode is not "ask".
+       (agent_popup_message_start): Ditto.
+
+2011-03-02  Werner Koch  <wk@g10code.com>
+
+       * call-scd.c (hash_algo_option): New.
+       (agent_card_pksign): Use it with PKSIGN.
+
+2011-03-02  Ben Kibbey  <bjk@luxsci.net>  (wk)
+
+       * command.c (cmd_clear_passphrase): Add option --mode=normal.
+       (cmd_keyinfo): Add option --data.
+        (do_one_keyinfo): Return CACHED status.  Add arg DATA.
+
+2011-02-07  Werner Koch  <wk@g10code.com>
+
+       * pksign.c (do_encode_dsa): Enforce multipe of 8 bits only for DSA.
+
+2011-02-03  Werner Koch  <wk@g10code.com>
+
+       * protect.c (protect_info): Support ECC algos.
+
+       * pksign.c (do_encode_dsa): Map public key algo number.  Extend
+       DSA size check for ECDSA.
+
+       * gpg-agent.c: Include cipher.h.
+       (map_pk_openpgp_to_gcry): New.
+
+       * findkey.c (key_parms_from_sexp): Support ECDH.
+
+       * cvt-openpgp.c (get_keygrip): Support ECC algorithms.
+       (convert_secret_key): Ditto.
+       (do_unprotect): Ditto.
+
+2011-02-02  Werner Koch  <wk@g10code.com>
+
+       * cvt-openpgp.c (convert_secret_key): Remove algo mapping.
+
+2011-01-31  Werner Koch  <wk@g10code.com>
 
-2011-04-29  Werner Koch  <wk@g10code.com>
+       * cvt-openpgp.c (convert_to_openpgp): Adjust to reverted Libgcrypt
+       ABI.
 
-       * gpg-agent.c: Include estream.h
-       (main): s/pth_kill/es_pth_kill/.
+       * protect.c (protect_info): Adjust ECDSA and ECDH parameter names.
+       Add "ecc".
+       * findkey.c (key_parms_from_sexp): Ditto.
+
+2011-01-19  Werner Koch  <wk@g10code.com>
+
+       * trustlist.c (read_one_trustfile): Also chop an CR.
+
+2011-01-21  Werner Koch  <wk@g10code.com>
+
+       * pksign.c (do_encode_dsa): Compare MDLEN to bytes.
+
+       * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New.
+
+2010-12-02  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (CHECK_OWN_SOCKET_INTERVAL) [W32CE]: Set to 60
+       seconds.
+
+2010-11-29  Werner Koch  <wk@g10code.com>
+
+       * cache.c (initialize_module_cache): Factor code out to ...
+       (init_encryption): new.
+       (new_data, agent_get_cache): Init encryption on on the fly.
+
+2010-11-26  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (CHECK_OWN_SOCKET_INTERVAL): New.
+       (handle_tick) [W32CE]: Don't check own socket.
+
+2010-11-23  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (gpg_agent_LDFLAGS): Add extra_bin_ldflags.
 
 2010-11-11  Werner Koch  <wk@g10code.com>
 
        * gpg-agent.c (handle_connections): Set that flag.
        * call-scd.c (start_scd): Enable events depending on this flag.
 
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (create_socket_name): Use TMPDIR.  Change callers.
+
+2010-10-26  Werner Koch  <wk@g10code.com>
+
+       * cache.c (agent_put_cache): Allow deletion even if TTL is passwd
+       as 0.
+
+       * genkey.c (agent_protect_and_store): Add arg PASSPHRASE_ADDR.
+       * command.c (cmd_passwd): Add option --passwd-nonce.
+       (struct server_local_s): Add LAST_CACHE_NONCE and LAST_PASSWD_NONCE.
+       (clear_nonce_cache): New.
+       (reset_notify): Clear the nonce cache.
+       (start_command_handler): Ditto.
+
+2010-10-25  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_export_key): Free CACHE_NONCE.
+       (cmd_passwd): Add option --cache-nonce.
+
+2010-10-18  Werner Koch  <wk@g10code.com>
+
+       * call-pinentry.c (start_pinentry): Print name of pinentry on
+       connect error.
+
+       * call-scd.c (agent_card_pksign): Make sure to return an unsigned
+       number.
+
+2010-10-14  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_genkey): Add option --no-protection.
+       * genkey.c (agent_genkey): Add arg NO_PROTECTION.
+
+2010-10-13  Werner Koch  <wk@g10code.com>
+
+       * call-pinentry.c (agent_get_passphrase): Support the close_button.
+
+       * gpg-agent.c (create_server_socket): Switch back to stderr
+       logging if we are not starting a agent.
+
+       * command.c (cmd_passwd, cmd_export_key): Move mapping of
+       GPG_ERR_FULLY_CANCELED to ..
+       (leave_cmd): .. here.
+       (option_handler): Add option agent-awareness.
+       * protect-tool.c (get_passphrase): Take care of
+       GPG_ERR_FULLY_CANCELED.
+       * findkey.c (try_unprotect_cb): Ditto.
+       (unprotect): Remove the fully_canceled hack.
+       * call-pinentry.c (start_pinentry): Ditto.
+       (agent_askpin): Ditto.
+       * pkdecrypt.c (agent_pkdecrypt): Ditto
+       * pksign.c (agent_pksign_do): Ditto.
+       * genkey.c (agent_ask_new_passphrase): Remove arg CANCEL_ALL.
+
+2010-10-06  Werner Koch  <wk@g10code.com>
+
+       * cvt-openpgp.c (convert_secret_key): Add missing break.
+
+2010-10-05  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (main): Don't set SSH_AGENT_PID so that ssh-agent -k
+       won't kill out gpg-agent.
+
 2010-09-30  Werner Koch  <wk@g10code.com>
 
+       * gpg-agent.c (agent_exit): Run cleanup.
+       (cleanup): Run only once.
+
+       * call-pinentry.c (close_button_status_cb): New.
+       (agent_askpin): Add arg R_CANCEL_ALL.  Change all callers.
+       * genkey.c (agent_ask_new_passphrase): Ditto.
+       * findkey.c (unprotect): Return GPG_ERR_FULLY_CANCELED if needed.
+
+       * command.c (cmd_export_key): Add support for OpenPGP keys.
+       * findkey.c (unprotect): Add optional arg R_PASSPHRASE.
+       (agent_key_from_file): Ditto.  Change all callers.
+
        * findkey.c (unprotect): Do not put the passphrase into the cache
        if it has been changed.
 
+       * cvt-openpgp.c (convert_to_openpgp, apply_protection)
+       (key_from_sexp): New.
+
+2010-09-29  Werner Koch  <wk@g10code.com>
+
+       * cvt-openpgp.c (convert_openpgp): Rename to convert_from_openpgp.
+
+       * command.c (has_option): Stop at "--".
+       (has_option_name, option_value): Ditto.
+       (skip_options): Skip initial spaces.
+
 2010-09-24  Werner Koch  <wk@g10code.com>
 
        * gpg-agent.c (main, reread_configuration): Always test whether
        the default configuration file has been created in the meantime.
        Fixes bug#1285.
 
+2010-09-17  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_havekey): Allow testing of several keygrips.
+
+2010-09-15  Werner Koch  <wk@g10code.com>
+
+       * protect.c (calculate_mic): Take care of shared secret format.
+
+       * agent.h (PROTECTED_SHARED_SECRET): New.
+
+2010-09-02  Werner Koch  <wk@g10code.com>
+
+       * cache.c (new_data): Change arg and callers to use a string and
+       explicity return an error code.  We never used raw binary data and
+       thus it is easier to use a string.  Adjust callers.
+       (initialize_module_cache, deinitialize_module_cache): New.
+       (new_data): Encrypt the cached data.
+       (struct cache_item_s): Remove field LOCKCOUNT.  Change all users
+       accordingly.
+       (agent_unlock_cache_entry): Remove.
+       (agent_get_cache): Return an allocated string and remove CACHE_ID.
+       * genkey.c (agent_genkey): Remove cache marker stuff.
+       * findkey.c (unprotect): Ditto.
+       * cvt-openpgp.c (convert_openpgp): Ditto.
+       * command.c (cmd_get_passphrase): Ditto.
+       * gpg-agent.c (main, cleanup): Initialize and deinitialize the
+       cache module.
+
+2010-09-01  Werner Koch  <wk@g10code.com>
+
+       * call-pinentry.c (start_pinentry): Disable pinentry logging.
+
+       * command.c (cmd_import_key, cmd_genkey, cmd_pksign): Add CACHE
+       handling.
+       * cvt-openpgp.c (convert_openpgp): Add arg CACHE_NONCE and try the
+       cached nonce first.
+       * genkey.c (agent_genkey): Add arg CACHE_NONCE.
+       * cache.c (agent_get_cache): Require user and nonce cache modes
+       to match the requested mode.
+       (agent_put_cache): Ditto.
+       * agent.h (CACHE_MODE_NONCE): New.
+       * pksign.c (agent_pksign_do, agent_pksign): Add arg CACHE_NONCE.
+       * findkey.c (agent_key_from_file): Ditto.
+       (unprotect): Implement it.
+
+2010-08-31  Werner Koch  <wk@g10code.com>
+
+       * pksign.c (do_encode_dsa): Fix sign problem.
+       * findkey.c (agent_is_dsa_key): Adjust to actual usage.
+
+2010-08-30  Werner Koch  <wk@g10code.com>
+
+       * protect.c (s2k_hash_passphrase): New public function.
+
+2010-08-27  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_import_key): Support OpenPGP keys.
+       * cvt-openpgp.h, cvt-openpgp.c: New.  Some of the code is based on
+       code taken from g10/seckey-cert.c.
+
+2010-08-26  Werner Koch  <wk@g10code.com>
+
+       * command-ssh.c (open_control_file): Use estream to create the file.
+
+       * findkey.c (agent_write_private_key): Explicitly create file with
+       mode 600.
+       * gpg-agent.c (main): Ditto.
+       * trustlist.c (agent_marktrusted): Explicitly create file with
+       mode 640.
+
+2010-08-16  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c: Replace remaining printf by es_printf.
+
 2010-08-11  Werner Koch  <wk@g10code.com>
 
-       * call-pinentry.c (agent_askpin, agent_get_passphrase): Fix
+       * call-pinentry.c (agent_get_passphrase, agent_askpin): Fix
        setting of confidential flag.
 
        * call-scd.c (agent_card_scd): Pass assuan comment lines to the
        caller.
        (ASSUAN_CONVEY_COMMENTS): Provide replacement if needed.
 
+2010-08-09  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (t_common_ldadd): Add NETLIBS for sake of the TCP
+       logging.
+
+2010-06-24  Werner Koch  <wk@g10code.com>
+
+       * genkey.c (check_passphrase_pattern): Use HANG option for
+       gnupg_wait_progress.  Fixes regression from 2010-06-09.
+
+2010-06-21  Werner Koch  <wk@g10code.com>
+
+       * protect-tool.c (export_p12_file, import_p12_cert_cb)
+       (import_p12_file, sexp_to_kparms, store_private_key): Remove
+       unused code.
+
+2010-06-18  Werner Koch  <wk@g10code.com>
+
+       * protect-tool.c (store_private_key, rsa_key_check): Remove.
+
+       * command.c (cmd_export_key): New.
+
+2010-06-15  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_keywrap_key, cmd_import_key): New.
+
+       * genkey.c (agent_genkey, agent_protect_and_store): Factor common
+       code out to...
+       (agent_ask_new_passphrase): .. new.
+
+       * findkey.c (agent_write_private_key): Return GPG_ERR_EEXIST
+       instead of GPG_ERR_GENERAL.
+
+2010-06-14  Werner Koch  <wk@g10code.com>
+
+       * protect-tool.c: Remove commands --p12-import and --p12-export.
+       * minip12.c, minip12.h: Move to ../sm.
+       * Makefile.am (gpg_protect_tool_SOURCES): Remove them.
+       * preset-passphrase.c: Remove unneeded minip12.h.
+
+       * command.c (cmd_keywrap_key): New.
+
+       * command.c (leave_cmd): New.
+       (cmd_istrusted, cmd_listtrusted, cmd_marktrusted, cmd_pksign)
+       (cmd_pkdecrypt, cmd_genkey, cmd_readkey, cmd_keyinfo)
+       (cmd_get_passphrase, cmd_get_confirmation, cmd_learn)
+       (cmd_passwd, cmd_preset_passphrase, cmd_getval, cmd_putval): Use it.
+
 2010-05-12  Werner Koch  <wk@g10code.com>
 
        * preset-passphrase.c (forget_passphrase): Actually implement
        this.  Fixes bug#1198.
 
-       * gpg-agent.c (handle_tick): Do not print die message with option -q.
-
 2010-05-11  Werner Koch  <wk@g10code.com>
 
        * agent.h (opt): Add field USE_STANDARD_SOCKET.
        for non-W32 platforms.
        (cmd_getinfo): New subcommands std_session_env and std_startup_env.
 
-2010-05-04  Werner Koch  <wk@g10code.com>
-
-       * gpg-agent.c (main): Add command --use-standard-socket-p.
-
 2010-05-03  Werner Koch  <wk@g10code.com>
 
        * gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME
        too early.
 
-2010-03-17  Werner Koch  <wk@g10code.com>
+2010-04-30  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (main): Add command --use-standard-socket-p.
+
+2010-04-26  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (create_server_socket) [W32]: Also check for EEXIST.
+
+2010-04-19  Werner Koch  <wk@g10code.com>
 
-       * call-scd.c (unlock_scd): Send a BYE under certain conditions.
+       * pksign.c (get_dsa_qbits, do_encode_dsa): New.
+       (agent_pksign_do): Detect DSA keys and use do_encode_dsa.
+       * findkey.c (agent_public_key_from_file): Factor some code out to ..
+       (key_parms_from_sexp): New.
+       (agent_is_dsa_key): New.
 
-2010-02-19  Werner Koch  <wk@g10code.com>
+       * command.c (cmd_sethash): Clear digeest.RAW_VALUE.
 
-       * call-pinentry.c (start_pinentry): Remove a translation prefix.
+2010-04-14  Werner Koch  <wk@g10code.com>
 
-2010-02-18  Werner Koch  <wk@g10code.com>
+       * Makefile.am (libexec_PROGRAMS) [W32CE]: Do not build
+       gpg-preset-passphrase for now.
+       (pwquery_libs) [W32CE]: Set to empty.
 
-       * protect.c (agent_unprotect): Initialize CLEARTEXT.
+       * trustlist.c (read_one_trustfile): Use estream.
 
-       * command.c (register_commands): Unconditionally use
-       assuan_register_post_cmd_notify.
-       (start_command_handler): Undocumented use assuan_set_io_monitor.
+2010-04-13  Werner Koch  <wk@g10code.com>
+
+       * findkey.c (read_key_file): Use estream.
+       (agent_write_private_key): Ditto.
+
+2010-04-07  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (handle_connections) [W32]: Assume that PTh support
+       the handle event.  Use a dummy event for W32CE.
+       (get_agent_scd_notify_event) [W32CE]: Do not build.
+
+       * call-pinentry.c: Remove setenv.h.  Include sysutils.h.
+       (atfork_cb): s/setenv/gnupg_setenv/.
+
+       * gpg-agent.c: Do not include setenv.h.
+       (main): s/unsetenv/gnupg_unsetenv/.
+
+       * protect.c (calibrate_get_time) [W32CE]: Use GetThreadTimes.
+
+2010-04-06  Werner Koch  <wk@g10code.com>
+
+       * call-scd.c [!HAVE_SIGNAL_H]: Do not include signal.h.
+
+       * findkey.c (agent_write_private_key): s/remove/gnupg_remove/.
+
+       * command-ssh.c (search_control_file): Replace rewind by fseek and
+       clearerr.
+       * genkey.c (check_passphrase_pattern): Ditto.
+
+       * gpg-agent.c [!HAVE_SIGNAL_H]: Do not include signal.h.
+       (remove_socket): s/remove/gnupg_remove/.
+       (create_private_keys_directory): Use gnupg_mkdir.
+
+2010-03-11  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c: Include "asshelp.h".
+       (main): Remove assuan_set_assuan_log_prefix.  Add
+       assuan_set_log_cb.
+       (handle_signal): Disable pth ctrl dumping.
+       (parse_rereadable_options, main): Remove assuan_set_assuan_log_stream.
+       * call-scd.c (start_scd): Remove assuan_set_log_stream.
+
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (common_libs): Remove libjnlib.a.
+
+       * trustlist.c, protect-tool.c, command-ssh.c: Remove estream.h.
 
 2010-02-17  Werner Koch  <wk@g10code.com>
 
        * call-pinentry.c (start_pinentry): Always free OPTSTR.  Send
        default-xxx strings.
 
-2010-02-11  Marcus Brinkmann  <marcus@g10code.de>
+2010-01-26  Werner Koch  <wk@g10code.com>
+
+       * protect.c (do_encryption): Encode the s2kcount and no not use a
+       static value of 96.
+
+2009-12-21  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_getinfo): Add sub-command s2k_count.
+
+2009-12-14  Werner Koch  <wk@g10code.com>
+
+       * protect.c (agent_unprotect): Decode the S2K count here and take
+       care of the new unencoded values.  Add a lower limit sanity check.
+       (hash_passphrase): Do not decode here.
+       (get_standard_s2k_count, calibrate_s2k_count): New.
+       (calibrate_get_time, calibrate_elapsed_time): New.
+       (do_encryption): Use get_standard_s2k_count.
+
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * protect.c (agent_unprotect): Avoid compiler warning.
+
+2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       * call-pinentry.c (start_pinentry): Convert posix fd to assuan fd.
+       * call-scd.c (start_scd): Likewise.
+
+2009-12-03  Werner Koch  <wk@g10code.com>
+
+       * gpg-agent.c (set_debug): Allow for numerical debug leveles.  Print
+       active debug flags.
 
-       From trunk 2009-09-23, 2009-11-02, 2009-11-04, 2009-11-05, 2009-11-25,
-       2009-12-08:
+2009-12-02  Werner Koch  <wk@g10code.com>
 
-       * Makefile.am (gpg_agent_CFLAGS, gpg_agent_LDADD): Use libassuan
-       instead of libassuan-pth.
+       * trustlist.c (read_trustfiles): Store the pointer returned from
+       shrinking the memory and not the orginal one.  Fixes bug#1163.
+       Reported by TAKAHASHI Tamotsu.  Also return correct error after
+       memory failure.
+
+2009-11-27  Marcus Brinkmann  <marcus@g10code.de>
+
+       * command.c (start_command_handler): Do not call
+       assuan_set_log_stream anymore.
+       * gpg-agent.c (main): But call assuan_set_assuan_log_stream here.
+
+2009-11-25  Marcus Brinkmann  <marcus@g10code.de>
+
+       * command.c (start_command_handler): Use assuan_fd_t and
+       assuan_fdopen on fds.
+
+2009-11-05  Marcus Brinkmann  <marcus@g10code.de>
+
+       * call-pinentry.c (start_pinentry): Call assuan_pipe_connect, not
+       assuan_pipe_connect_ext.
+       * command.c (start_command_handler): Change
+       assuan_init_socket_server_ext into assuan_init_socket_server.
+       * call-scd.c (start_scd): Update use of assuan_socket_connect and
+       assuan_pipe_connect.
+       * gpg-agent.c (check_own_socket_thread, check_for_running_agent):
+       Update use of assuan_socket_connect.
+
+2009-11-04  Werner Koch  <wk@g10code.com>
+
+       * command.c (register_commands): Add help arg to
+       assuan_register_command.  Convert all command comments to help
+       strings.
+
+2009-11-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * command.c (reset_notify): Take LINE arg and return error.
+       (register_commands): Use assuan_handler_t type.
+
+2009-10-16  Marcus Brinkmann  <marcus@g10code.com>
+
+       * gpg_agent_CFLAGS, gpg_agent_LDADD: Use libassuan instead of
+       libassuan-pth.
        * gpg-agent.c: Invoke ASSUAN_SYSTEM_PTH_IMPL.
-       (main): Update to new API.  Call assuan_set_system_hooks and
-       assuan_sock_init.  Fix invocation of assuan_socket_connect.
-       Call assuan_set_assuan_log_stream here.
-       (parse_rereadable_options): Don't set global assuan log
-       file (there ain't one anymore).
+       (main): Call assuan_set_system_hooks and assuan_sock_init.
+       Fix invocation of assuan_socket_connect.
+
+2009-09-23  Werner Koch  <wk@g10code.com>
+
+       * command.c (register_commands) [HAVE_ASSUAN_SET_IO_MONITOR]:
+       Remove cpp condition.
+       (start_command_handler) [HAVE_ASSUAN_SET_IO_MONITOR]: Ditto.
+
+2009-09-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpg-agent.c (parse_rereadable_options): Don't set global assuan
+       log file (there ain't one anymore).
+       (main): Update to new API.
        (check_own_socket_pid_cb): Return gpg_error_t instead of int.
        (check_own_socket_thread, check_for_running_agent): Create assuan
-       context before connecting to server.  Update use of
-       assuan_socket_connect.
+       context before connecting to server.
        * command.c: Include "scdaemon.h" before <assuan.h> because of
        GPG_ERR_SOURCE_DEFAULT check.
        (write_and_clear_outbuf): Use gpg_error_t instead of
        (post_cmd_notify): Change type of ERR to gpg_error_t from int.
        (io_monitor): Add hook argument.  Use symbols for constants.
        (register_commands): Change return type of HANDLER to gpg_error_t.
-       Use assuan_handler_t type.  Add NULL arg to assuan_register_command.
-       Add help arg to assuan_register_command.  Convert all command
-       comments to help strings.
        (start_command_handler): Allocate assuan context before starting
-       server.  Change assuan_init_socket_server_ext into
-       assuan_init_socket_server. Use assuan_fd_t and assuan_fdopen on fds.
-       Do not call assuan_set_log_stream anymore.
-       (reset_notify): Take LINE arg and return error.
+       server.
        * call-pinentry.c: Include "scdaemon.h" before <assuan.h> because
        of GPG_ERR_SOURCE_DEFAULT check.
        (unlock_pinentry): Call assuan_release instead of
        assuan_disconnect.
        (getinfo_pid_cb, getpin_cb): Return gpg_error_t instead of int.
        (start_pinentry): Allocate assuan context before connecting to
-       server.  Call assuan_pipe_connect, notassuan_pipe_connect_ext.
-       Convert posix fd to assuan fd.
+       server.
        * call-scd.c (membuf_data_cb, learn_status_cb, get_serialno_cb)
        (membuf_data_cb, inq_needpin, card_getattr_cb, pass_status_thru)
        (pass_data_thru): Change return type to gpg_error_t.
        (start_scd): Allocate assuan context before connecting to server.
-       Update use of assuan_socket_connect and assuan_pipe_connect.
-       Convert posix fd to assuan fd.
-
-2010-01-26  Werner Koch  <wk@g10code.com>
-
-       * protect.c (do_encryption): Encode the s2kcount and do not use a
-       static value of 96.
-
-2009-12-21  Werner Koch  <wk@g10code.com>
-
-       * command.c (cmd_getinfo): Add sub-command "s2k_count".
-
-2009-12-14  Werner Koch  <wk@g10code.com>
-
-       * protect.c (agent_unprotect): Decode the S2K count here and take
-       care of the new unencoded values.  Add a lower limit sanity check.
-       (hash_passphrase): Do not decode here.
-       (get_standard_s2k_count, calibrate_s2k_count): New.
-       (calibrate_get_time, calibrate_elapsed_time): New.
-       (do_encryption): Use get_standard_s2k_count.
-
-2009-12-03  Werner Koch  <wk@g10code.com>
-
-       * gpg-agent.c (set_debug): Allow for numerical debug leveles.  Print
-       active debug flags.
-
-2009-12-02  Werner Koch  <wk@g10code.com>
-
-       * trustlist.c (read_trustfiles): Store the pointer returned from
-       shrinking the memory and not the orginal one.  Fixes bug#1163.
-       Reported by TAKAHASHI Tamotsu.  Also return correct error after
-       memory failure.
 
 2009-09-04  Marcus Brinkmann  <marcus@g10code.com>
 
@@ -2606,7 +3092,7 @@ Fri Aug 18 14:27:14 CEST 2000  Werner Koch  <wk@openit.de>
 
 
  Copyright 2001, 2002, 2003, 2004, 2005,
-          2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+          2007, 2008, 2009, 2010, 2011 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
@@ -2615,3 +3101,7 @@ Fri Aug 18 14:27:14 CEST 2000  Werner Koch  <wk@openit.de>
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 55c374c..ff15d03 100644 (file)
 ## Process this file with automake to produce Makefile.in
 
 bin_PROGRAMS = gpg-agent
-libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase
+libexec_PROGRAMS = gpg-protect-tool
+if !HAVE_W32CE_SYSTEM
+# fixme: Do no use simple-pwquery for preset-passphrase.
+libexec_PROGRAMS += gpg-preset-passphrase
+endif
 noinst_PROGRAMS = $(TESTS)
 
 EXTRA_DIST = ChangeLog-2011 gpg-agent-w32info.rc
 
+
 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl
 
 include $(top_srcdir)/am/cmacros.am
@@ -31,7 +36,7 @@ if HAVE_W32_SYSTEM
 resource_objs += gpg-agent-w32info.o
 endif
 
-AM_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS)
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
 
 gpg_agent_SOURCES = \
        gpg-agent.c agent.h \
@@ -46,24 +51,30 @@ gpg_agent_SOURCES = \
        protect.c \
        trustlist.c \
        divert-scd.c \
+       cvt-openpgp.c cvt-openpgp.h \
        call-scd.c \
        learncard.c
 
-common_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a
-commonpth_libs = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a
+common_libs = $(libcommon) ../gl/libgnu.a
+commonpth_libs = $(libcommonpth) ../gl/libgnu.a
+if HAVE_W32CE_SYSTEM
+pwquery_libs =
+else
 pwquery_libs = ../common/libsimple-pwquery.a
+endif
 
 
-gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS)
+gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
 gpg_agent_LDADD = $(commonpth_libs) \
-                $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \
+                $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
                $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
                $(resource_objs)
+gpg_agent_LDFLAGS = $(extra_bin_ldflags)
+gpg_agent_DEPENDENCIES = $(resource_objs)
 
 gpg_protect_tool_SOURCES = \
        protect-tool.c \
-       protect.c \
-       minip12.c minip12.h
+       protect.c
 
 gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS)
 gpg_protect_tool_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \
@@ -89,8 +100,8 @@ $(PROGRAMS): $(common_libs) $(commonpth_libs) $(pwquery_libs)
 #
 TESTS = t-protect
 
-t_common_ldadd = $(common_libs) \
-                 $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
+t_common_ldadd = $(common_libs)  $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
+                 $(LIBINTL) $(LIBICONV) $(NETLIBS)
 
 t_protect_SOURCES = t-protect.c protect.c
 t_protect_LDADD = $(t_common_ldadd)
index f81743f..b80c6a0 100644 (file)
@@ -1,5 +1,5 @@
 /* agent.h - Global definitions for the agent
- *     Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2005, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -34,6 +34,7 @@
 #include "../common/membuf.h"
 #include "../common/sysutils.h" /* (gnupg_fd_t) */
 #include "../common/session-env.h"
+#include "../common/shareddefs.h"
 
 /* To convey some special hash algorithms we use algorithm numbers
    reserved for application use. */
@@ -45,6 +46,8 @@
 /* Maximum length of a digest.  */
 #define MAX_DIGEST_LEN 64
 
+
+
 /* A large struct name "opt" to keep global flags */
 struct
 {
@@ -55,23 +58,23 @@ struct
   int batch;           /* Batch mode */
   const char *homedir; /* Configuration directory name */
 
-  /* Environment setting gathered at program start or changed using the
+  /* True if we handle sigusr2.  */
+  int sigusr2_enabled;
+
+  /* Environment settings gathered at program start or changed using the
      Assuan command UPDATESTARTUPTTY. */
   session_env_t startup_env;
   char *startup_lc_ctype;
   char *startup_lc_messages;
 
-  /* True if we are listening on the standard socket.  */
-  int use_standard_socket;
+  /* Filename of the program to start as pinentry.  */
+  const char *pinentry_program;
 
-  /* True if we handle sigusr2.  */
-  int sigusr2_enabled;
+  /* Filename of the program to handle smartcard tasks.  */
+  const char *scdaemon_program;
 
-  const char *pinentry_program; /* Filename of the program to start as
-                                   pinentry.  */
-  const char *scdaemon_program; /* Filename of the program to handle
-                                   smartcard tasks.  */
   int disable_scdaemon;         /* Never use the SCdaemon. */
+
   int no_grab;         /* Don't let the pinentry grab the keyboard */
 
   /* The name of the file pinentry shall tocuh before exiting.  If
@@ -86,36 +89,51 @@ struct
 
   /* Flag disallowing bypassing of the warning.  */
   int enforce_passphrase_constraints;
+
   /* The require minmum length of a passphrase. */
   unsigned int min_passphrase_len;
+
   /* The minimum number of non-alpha characters in a passphrase.  */
   unsigned int min_passphrase_nonalpha;
+
   /* File name with a patternfile or NULL if not enabled.  */
   const char *check_passphrase_pattern;
+
   /* If not 0 the user is asked to change his passphrase after these
      number of days.  */
   unsigned int max_passphrase_days;
+
   /* If set, a passphrase history will be written and checked at each
      passphrase change.  */
   int enable_passhrase_history;
 
   int running_detached; /* We are running detached from the tty. */
 
+  /* If this global option is true, the passphrase cache is ignored
+     for signing operations.  */
   int ignore_cache_for_signing;
+
+  /* If this global option is true, the user is allowed to
+     interactively mark certificate in trustlist.txt as trusted. */
   int allow_mark_trusted;
+
+  /* If this global option is true, the Assuan command
+     PRESET_PASSPHRASE is allowed.  */
   int allow_preset_passphrase;
 
-  /* Allow the use of an external password cache.  If this option is
-     enabled (which is the default) we send an option to Pinentry
-     to allow it to enable such a cache.  */
-  int allow_external_cache;
+  /* If this global option is true, the Assuan option
+     pinentry-mode=loopback is allowed.  */
+  int allow_loopback_pinentry;
 
   int keep_tty;      /* Don't switch the TTY (for pinentry) on request */
   int keep_display;  /* Don't switch the DISPLAY (for pinentry) on request */
-  int ssh_support;   /* Enable ssh-agent emulation.  */
+
+  /* This global option enables the ssh-agent subsystem.  */
+  int ssh_support;
 } opt;
 
 
+/* Bit values for the --debug option.  */
 #define DBG_COMMAND_VALUE 1    /* debug commands i/o */
 #define DBG_MPI_VALUE    2     /* debug mpi details */
 #define DBG_CRYPTO_VALUE  4    /* debug low level crypto */
@@ -123,8 +141,9 @@ struct
 #define DBG_CACHE_VALUE   64   /* debug the caching */
 #define DBG_MEMSTAT_VALUE 128  /* show memory statistics */
 #define DBG_HASHING_VALUE 512  /* debug hashing operations */
-#define DBG_ASSUAN_VALUE 1024
+#define DBG_ASSUAN_VALUE 1024   /* Enable Assuan debugging.  */
 
+/* Test macros for the debug option.  */
 #define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE)
 #define DBG_CRYPTO  (opt.debug & DBG_CRYPTO_VALUE)
 #define DBG_MEMORY  (opt.debug & DBG_MEMORY_VALUE)
@@ -146,7 +165,8 @@ struct scd_local_s;
 struct server_control_s
 {
   /* Private data used to fire up the connection thread.  We use this
-     structure do avoid an extra allocation for just a few bytes. */
+     structure do avoid an extra allocation for only a few bytes while
+     spawning a new connection thread.  */
   struct {
     gnupg_fd_t fd;
   } thread_startup;
@@ -157,10 +177,18 @@ struct server_control_s
   /* Private data of the SCdaemon (call-scd.c). */
   struct scd_local_s *scd_local;
 
+  /* Environment settings for the connection.  */
   session_env_t session_env;
   char *lc_ctype;
   char *lc_messages;
 
+  /* The current pinentry mode.  */
+  pinentry_mode_t pinentry_mode;
+
+  /* The TTL used for the --preset option of certain commands.  */
+  int cache_ttl_opt_preset;
+
+  /* Information on the currently used digest (for signing commands).  */
   struct {
     int algo;
     unsigned char value[MAX_DIGEST_LEN];
@@ -170,34 +198,49 @@ struct server_control_s
   unsigned char keygrip[20];
   int have_keygrip;
 
-  int use_auth_call; /* Hack to send the PKAUTH command instead of the
-                        PKSIGN command to the scdaemon.  */
-  int in_passwd;     /* Hack to inhibit enforced passphrase change
-                        during an explicit passwd command.  */
+  /* A flag to enable a hack to send the PKAUTH command instead of the
+     PKSIGN command to the scdaemon.  */
+  int use_auth_call;
+
+  /* A flag to inhibit enforced passphrase change during an explicit
+     passwd command.  */
+  int in_passwd;
+
+  /* The current S2K which might be different from the calibrated
+     count. */
+  unsigned long s2k_count;
 };
 
 
+/* Information pertaining to pinentry requests.  */
 struct pin_entry_info_s
 {
   int min_digits; /* min. number of digits required or 0 for freeform entry */
   int max_digits; /* max. number of allowed digits allowed*/
-  int max_tries;
-  int failed_tries;
+  int max_tries;  /* max. number of allowed tries.  */
+  int failed_tries; /* Number of tries so far failed.  */
   int with_qualitybar; /* Set if the quality bar should be displayed.  */
+  int with_repeat;  /* Request repetition of the passphrase.  */
+  int repeat_okay;  /* Repetition worked. */
   int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */
   void *check_cb_arg;  /* optional argument which might be of use in the CB */
-  const char *cb_errtext; /* used by the cb to displaye a specific error */
-  size_t max_length; /* allocated length of the buffer */
-  char pin[1];
+  const char *cb_errtext; /* used by the cb to display a specific error */
+  size_t max_length;   /* Allocated length of the buffer PIN. */
+  char pin[1];         /* The buffer to hold the PIN or passphrase.
+                          It's actual allocated length is given by
+                          MAX_LENGTH (above).  */
 };
 
 
+/* Types of the private keys.  */
 enum
   {
-    PRIVATE_KEY_UNKNOWN = 0,
-    PRIVATE_KEY_CLEAR = 1,
-    PRIVATE_KEY_PROTECTED = 2,
-    PRIVATE_KEY_SHADOWED = 3
+    PRIVATE_KEY_UNKNOWN = 0,      /* Type of key is not known.  */
+    PRIVATE_KEY_CLEAR = 1,        /* The key is not protected.  */
+    PRIVATE_KEY_PROTECTED = 2,    /* The key is protected.  */
+    PRIVATE_KEY_SHADOWED = 3,     /* The key is a stub for a smartcard
+                                     based key.  */
+    PROTECTED_SHARED_SECRET = 4   /* RFU.  */
   };
 
 
@@ -208,10 +251,18 @@ typedef enum
     CACHE_MODE_ANY,        /* Any mode except ignore matches. */
     CACHE_MODE_NORMAL,     /* Normal cache (gpg-agent). */
     CACHE_MODE_USER,       /* GET_PASSPHRASE related cache. */
-    CACHE_MODE_SSH         /* SSH related cache. */
+    CACHE_MODE_SSH,        /* SSH related cache. */
+    CACHE_MODE_NONCE       /* This is a non-predictable nonce.  */
   }
 cache_mode_t;
 
+/* The TTL is seconds used for adding a new nonce mode cache item.  */
+#define CACHE_TTL_NONCE 120
+
+/* The TTL in seconds used by the --preset option of some commands.
+   This is the default value changeable by an OPTION command.  */
+#define CACHE_TTL_OPT_PRESET 900
+
 
 /* The type of a function to lookup a TTL by a keygrip.  */
 typedef int (*lookup_ttl_t)(const char *hexgrip);
@@ -225,14 +276,22 @@ const char *get_agent_ssh_socket_name (void);
 void *get_agent_scd_notify_event (void);
 #endif
 void agent_sighup_action (void);
+int map_pk_openpgp_to_gcry (int openpgp_algo);
 
 /*-- command.c --*/
 gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid);
 gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...)
      GNUPG_GCC_A_SENTINEL(0);
+gpg_error_t agent_print_status (ctrl_t ctrl, const char *keyword,
+                                const char *format, ...)
+     JNLIB_GCC_A_PRINTF(3,4);
 void bump_key_eventcounter (void);
 void bump_card_eventcounter (void);
 void start_command_handler (ctrl_t, gnupg_fd_t, gnupg_fd_t);
+gpg_error_t pinentry_loopback (ctrl_t, const char *keyword,
+                              unsigned char **buffer, size_t *size,
+                              size_t max_length);
+
 #ifdef HAVE_W32_SYSTEM
 int serve_mmapped_ssh_request (ctrl_t ctrl,
                                unsigned char *request, size_t maxreqlen);
@@ -255,21 +314,27 @@ void start_command_handler_ssh (ctrl_t, gnupg_fd_t);
 int agent_write_private_key (const unsigned char *grip,
                              const void *buffer, size_t length, int force);
 gpg_error_t agent_key_from_file (ctrl_t ctrl,
+                                 const char *cache_nonce,
                                  const char *desc_text,
                                  const unsigned char *grip,
                                  unsigned char **shadow_info,
                                  cache_mode_t cache_mode,
                                  lookup_ttl_t lookup_ttl,
-                                 gcry_sexp_t *result);
+                                 gcry_sexp_t *result,
+                                 char **r_passphrase);
 gpg_error_t agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
                                      gcry_sexp_t *result);
 gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
                                         const unsigned char *grip,
                                         gcry_sexp_t *result);
+int agent_is_dsa_key (gcry_sexp_t s_key);
+int agent_is_eddsa_key (gcry_sexp_t s_key);
 int agent_key_available (const unsigned char *grip);
 gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
                                       int *r_keytype,
                                       unsigned char **r_shadow_info);
+gpg_error_t agent_delete_key (ctrl_t ctrl, const char *desc_text,
+                              const unsigned char *grip);
 
 /*-- call-pinentry.c --*/
 void initialize_module_call_pinentry (void);
@@ -279,54 +344,61 @@ int pinentry_active_p (ctrl_t ctrl, int waitseconds);
 int agent_askpin (ctrl_t ctrl,
                   const char *desc_text, const char *prompt_text,
                   const char *inital_errtext,
-                  struct pin_entry_info_s *pininfo,
-                  const char *keyinfo, cache_mode_t cache_mode);
+                  struct pin_entry_info_s *pininfo);
 int agent_get_passphrase (ctrl_t ctrl, char **retpass,
                           const char *desc, const char *prompt,
-                          const char *errtext, int with_qualitybar,
-                         const char *keyinfo, cache_mode_t cache_mode);
+                          const char *errtext, int with_qualitybar);
 int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok,
                            const char *notokay, int with_cancel);
 int agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn);
 int agent_popup_message_start (ctrl_t ctrl,
                                const char *desc, const char *ok_btn);
 void agent_popup_message_stop (ctrl_t ctrl);
-int agent_clear_passphrase (ctrl_t ctrl,
-                           const char *keyinfo, cache_mode_t cache_mode);
 
 
 /*-- cache.c --*/
+void initialize_module_cache (void);
+void deinitialize_module_cache (void);
 void agent_flush_cache (void);
 int agent_put_cache (const char *key, cache_mode_t cache_mode,
                      const char *data, int ttl);
-const char *agent_get_cache (const char *key, cache_mode_t cache_mode,
-                             void **cache_id);
-void agent_unlock_cache_entry (void **cache_id);
+char *agent_get_cache (const char *key, cache_mode_t cache_mode);
+void agent_store_cache_hit (const char *key);
 
 
 /*-- pksign.c --*/
-int agent_pksign_do (ctrl_t ctrl, const char *desc_text,
+int agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
+                     const char *desc_text,
                     gcry_sexp_t *signature_sexp,
-                     cache_mode_t cache_mode, lookup_ttl_t lookup_ttl);
-int agent_pksign (ctrl_t ctrl, const char *desc_text,
+                     cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
+                     const void *overridedata, size_t overridedatalen);
+int agent_pksign (ctrl_t ctrl, const char *cache_nonce,
+                  const char *desc_text,
                   membuf_t *outbuf, cache_mode_t cache_mode);
 
 /*-- pkdecrypt.c --*/
 int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
                      const unsigned char *ciphertext, size_t ciphertextlen,
-                     membuf_t *outbuf);
+                     membuf_t *outbuf, int *r_padding);
 
 /*-- genkey.c --*/
 int check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent);
-int agent_genkey (ctrl_t ctrl,
-                  const char *keyparam, size_t keyparmlen, membuf_t *outbuf);
-int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey);
+gpg_error_t agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
+                                      char **r_passphrase);
+int agent_genkey (ctrl_t ctrl, const char *cache_nonce,
+                  const char *keyparam, size_t keyparmlen,
+                  int no_protection, int preset, membuf_t *outbuf);
+gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
+                                     char **passphrase_addr);
 
 /*-- protect.c --*/
 unsigned long get_standard_s2k_count (void);
+unsigned char get_standard_s2k_count_rfc4880 (void);
 int agent_protect (const unsigned char *plainkey, const char *passphrase,
-                   unsigned char **result, size_t *resultlen);
-int agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
+                   unsigned char **result, size_t *resultlen,
+                  unsigned long s2k_count);
+int agent_unprotect (ctrl_t ctrl,
+                     const unsigned char *protectedkey, const char *passphrase,
                      gnupg_isotime_t protected_at,
                      unsigned char **result, size_t *resultlen);
 int agent_private_key_type (const unsigned char *privatekey);
@@ -337,7 +409,12 @@ int agent_shadow_key (const unsigned char *pubkey,
 int agent_get_shadow_info (const unsigned char *shadowkey,
                            unsigned char const **shadow_info);
 gpg_error_t parse_shadow_info (const unsigned char *shadow_info,
-                               char **r_hexsn, char **r_idstr);
+                               char **r_hexsn, char **r_idstr, int *r_pinlen);
+gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo,
+                                 int s2kmode,
+                                 const unsigned char *s2ksalt,
+                                 unsigned int s2kcount,
+                                 unsigned char *key, size_t keylen);
 
 
 /*-- trustlist.c --*/
@@ -352,13 +429,16 @@ void agent_reload_trustlist (void);
 /*-- divert-scd.c --*/
 int divert_pksign (ctrl_t ctrl,
                    const unsigned char *digest, size_t digestlen, int algo,
-                   const unsigned char *shadow_info, unsigned char **r_sig);
+                   const unsigned char *shadow_info, unsigned char **r_sig,
+                   size_t *r_siglen);
 int divert_pkdecrypt (ctrl_t ctrl,
                       const unsigned char *cipher,
                       const unsigned char *shadow_info,
-                      char **r_buf, size_t *r_len);
+                      char **r_buf, size_t *r_len, int *r_padding);
 int divert_generic_cmd (ctrl_t ctrl,
                         const char *cmdline, void *assuan_context);
+int divert_writekey (ctrl_t ctrl, int force, const char *serialno,
+                     const char *id, const char *keydata, size_t keydatalen);
 
 
 /*-- call-scd.c --*/
@@ -380,6 +460,7 @@ int agent_card_pksign (ctrl_t ctrl,
                        const char *keyid,
                        int (*getpin_cb)(void *, const char *, char*, size_t),
                        void *getpin_cb_arg,
+                       int mdalgo,
                        const unsigned char *indata, size_t indatalen,
                        unsigned char **r_buf, size_t *r_buflen);
 int agent_card_pkdecrypt (ctrl_t ctrl,
@@ -387,10 +468,15 @@ int agent_card_pkdecrypt (ctrl_t ctrl,
                           int (*getpin_cb)(void *, const char *, char*,size_t),
                           void *getpin_cb_arg,
                           const unsigned char *indata, size_t indatalen,
-                          char **r_buf, size_t *r_buflen);
+                          char **r_buf, size_t *r_buflen, int *r_padding);
 int agent_card_readcert (ctrl_t ctrl,
                          const char *id, char **r_buf, size_t *r_buflen);
 int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf);
+int agent_card_writekey (ctrl_t ctrl, int force, const char *serialno,
+                         const char *id, const char *keydata,
+                         size_t keydatalen,
+                         int (*getpin_cb)(void *, const char *, char*, size_t),
+                         void *getpin_cb_arg);
 gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result);
 int agent_card_scd (ctrl_t ctrl, const char *cmdline,
                     int (*getpin_cb)(void *, const char *, char*, size_t),
index 10f9ef6..49402e4 100644 (file)
@@ -1,5 +1,5 @@
 /* cache.c - keep a cache of passphrases
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <string.h>
 #include <time.h>
 #include <assert.h>
+#include <npth.h>
 
 #include "agent.h"
 
+/* The size of the encryption key in bytes.  */
+#define ENCRYPTION_KEYSIZE (128/8)
+
+/* A mutex used to protect the encryption.  This is required because
+   we use one context to do all encryption and decryption.  */
+static npth_mutex_t encryption_lock;
+/* The encryption context.  This is the only place where the
+   encryption key for all cached entries is available.  It would be nice
+   to keep this (or just the key) in some hardware device, for example
+   a TPM.  Libgcrypt could be extended to provide such a service.
+   With the current scheme it is easy to retrieve the cached entries
+   if access to Libgcrypt's memory is available.  The encryption
+   merely avoids grepping for clear texts in the memory.  Nevertheless
+   the encryption provides the necessary infrastructure to make it
+   more secure.  */
+static gcry_cipher_hd_t encryption_handle;
+
+
 struct secret_data_s {
-  int  totallen; /* this includes the padding */
-  int  datalen;  /* actual data length */
-  char data[1];
+  int  totallen; /* This includes the padding and space for AESWRAP. */
+  char data[1];  /* A string.  */
 };
 
 typedef struct cache_item_s *ITEM;
@@ -39,15 +57,90 @@ struct cache_item_s {
   time_t created;
   time_t accessed;
   int ttl;  /* max. lifetime given in seconds, -1 one means infinite */
-  int lockcount;
   struct secret_data_s *pw;
   cache_mode_t cache_mode;
   char key[1];
 };
 
-
+/* The cache himself.  */
 static ITEM thecache;
 
+/* NULL or the last cache key stored by agent_store_cache_hit.  */
+static char *last_stored_cache_key;
+
+
+/* This function must be called once to initialize this module. It
+   has to be done before a second thread is spawned.  */
+void
+initialize_module_cache (void)
+{
+  int err;
+
+  err = npth_mutex_init (&encryption_lock, NULL);
+
+  if (err)
+    log_fatal ("error initializing cache module: %s\n", strerror (err));
+}
+
+
+void
+deinitialize_module_cache (void)
+{
+  gcry_cipher_close (encryption_handle);
+  encryption_handle = NULL;
+}
+
+
+/* We do the encryption init on the fly.  We can't do it in the module
+   init code because that is run before we listen for connections and
+   in case we are started on demand by gpg etc. it will only wait for
+   a few seconds to decide whether the agent may now accept
+   connections.  Thus we should get into listen state as soon as
+   possible.  */
+static gpg_error_t
+init_encryption (void)
+{
+  gpg_error_t err;
+  void *key;
+  int res;
+
+  if (encryption_handle)
+    return 0; /* Shortcut - Already initialized.  */
+
+  res = npth_mutex_lock (&encryption_lock);
+  if (res)
+    log_fatal ("failed to acquire cache encryption mutex: %s\n", strerror (res));
+
+  err = gcry_cipher_open (&encryption_handle, GCRY_CIPHER_AES128,
+                          GCRY_CIPHER_MODE_AESWRAP, GCRY_CIPHER_SECURE);
+  if (!err)
+    {
+      key = gcry_random_bytes (ENCRYPTION_KEYSIZE, GCRY_STRONG_RANDOM);
+      if (!key)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          err = gcry_cipher_setkey (encryption_handle, key, ENCRYPTION_KEYSIZE);
+          xfree (key);
+        }
+      if (err)
+        {
+          gcry_cipher_close (encryption_handle);
+          encryption_handle = NULL;
+        }
+    }
+  if (err)
+    log_error ("error initializing cache encryption context: %s\n",
+               gpg_strerror (err));
+
+  res = npth_mutex_unlock (&encryption_lock);
+  if (res)
+    log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
+
+  return err? gpg_error (GPG_ERR_NOT_INITIALIZED) : 0;
+}
+
+
 
 static void
 release_data (struct secret_data_s *data)
@@ -55,31 +148,67 @@ release_data (struct secret_data_s *data)
    xfree (data);
 }
 
-static struct secret_data_s *
-new_data (const void *data, size_t length)
+static gpg_error_t
+new_data (const char *string, struct secret_data_s **r_data)
 {
-  struct secret_data_s *d;
+  gpg_error_t err;
+  struct secret_data_s *d, *d_enc;
+  size_t length;
   int total;
+  int res;
+
+  *r_data = NULL;
 
-  /* we pad the data to 32 bytes so that it get more complicated
+  err = init_encryption ();
+  if (err)
+    return err;
+
+  length = strlen (string) + 1;
+
+  /* We pad the data to 32 bytes so that it get more complicated
      finding something out by watching allocation patterns.  This is
-     usally not possible but we better assume nothing about our
-     secure storage provider*/
-  total = length + 32 - (length % 32);
+     usally not possible but we better assume nothing about our secure
+     storage provider.  To support the AESWRAP mode we need to add 8
+     extra bytes as well. */
+  total = (length + 8) + 32 - ((length+8) % 32);
+
+  d = xtrymalloc_secure (sizeof *d + total - 1);
+  if (!d)
+    return gpg_error_from_syserror ();
+  memcpy (d->data, string, length);
+
+  d_enc = xtrymalloc (sizeof *d_enc + total - 1);
+  if (!d_enc)
+    {
+      err = gpg_error_from_syserror ();
+      xfree (d);
+      return err;
+    }
 
-  d = gcry_malloc_secure (sizeof *d + total - 1);
-  if (d)
+  d_enc->totallen = total;
+  res = npth_mutex_lock (&encryption_lock);
+  if (res)
+    log_fatal ("failed to acquire cache encryption mutex: %s\n",
+               strerror (res));
+
+  err = gcry_cipher_encrypt (encryption_handle, d_enc->data, total,
+                             d->data, total - 8);
+  xfree (d);
+  res = npth_mutex_unlock (&encryption_lock);
+  if (res)
+    log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
+  if (err)
     {
-      d->totallen = total;
-      d->datalen  = length;
-      memcpy (d->data, data, length);
+      xfree (d_enc);
+      return err;
     }
-  return d;
+  *r_data = d_enc;
+  return 0;
 }
 
 
 
-/* check whether there are items to expire */
+/* Check whether there are items to expire.  */
 static void
 housekeeping (void)
 {
@@ -89,11 +218,10 @@ housekeeping (void)
   /* First expire the actual data */
   for (r=thecache; r; r = r->next)
     {
-      if (!r->lockcount && r->pw
-         && r->ttl >= 0 && r->accessed + r->ttl < current)
+      if (r->pw && r->ttl >= 0 && r->accessed + r->ttl < current)
         {
           if (DBG_CACHE)
-            log_debug ("  expired `%s' (%ds after last access)\n",
+            log_debug ("  expired '%s' (%ds after last access)\n",
                        r->key, r->ttl);
           release_data (r->pw);
           r->pw = NULL;
@@ -106,16 +234,16 @@ housekeeping (void)
   for (r=thecache; r; r = r->next)
     {
       unsigned long maxttl;
-      
+
       switch (r->cache_mode)
         {
         case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break;
         default: maxttl = opt.max_cache_ttl; break;
         }
-      if (!r->lockcount && r->pw && r->created + maxttl < current)
+      if (r->pw && r->created + maxttl < current)
         {
           if (DBG_CACHE)
-            log_debug ("  expired `%s' (%lus after creation)\n",
+            log_debug ("  expired '%s' (%lus after creation)\n",
                        r->key, opt.max_cache_ttl);
           release_data (r->pw);
           r->pw = NULL;
@@ -129,27 +257,16 @@ housekeeping (void)
     {
       if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current)
         {
-          if (r->lockcount)
-            {
-              log_error ("can't remove unused cache entry `%s' due to"
-                         " lockcount=%d\n",
-                         r->key, r->lockcount);
-              r->accessed += 60*10; /* next error message in 10 minutes */
-              rprev = r;
-              r = r->next;
-            }
+          ITEM r2 = r->next;
+          if (DBG_CACHE)
+            log_debug ("  removed '%s' (mode %d) (slot not used for 30m)\n",
+                       r->key, r->cache_mode);
+          xfree (r);
+          if (!rprev)
+            thecache = r2;
           else
-            {
-              ITEM r2 = r->next;
-              if (DBG_CACHE)
-                log_debug ("  removed `%s' (slot not used for 30m)\n", r->key);
-              xfree (r);
-              if (!rprev)
-                thecache = r2;
-              else
-                rprev->next = r2;
-              r = r2;
-            }
+            rprev->next = r2;
+          r = r2;
         }
       else
         {
@@ -170,41 +287,35 @@ agent_flush_cache (void)
 
   for (r=thecache; r; r = r->next)
     {
-      if (!r->lockcount && r->pw)
+      if (r->pw)
         {
           if (DBG_CACHE)
-            log_debug ("  flushing `%s'\n", r->key);
+            log_debug ("  flushing '%s'\n", r->key);
           release_data (r->pw);
           r->pw = NULL;
           r->accessed = 0;
         }
-      else if (r->lockcount && r->pw)
-        {
-          if (DBG_CACHE)
-            log_debug ("    marked `%s' for flushing\n", r->key);
-          r->accessed = 0;
-          r->ttl = 0;
-        }
     }
 }
 
 
 
-/* Store DATA of length DATALEN in the cache under KEY and mark it
-   with a maximum lifetime of TTL seconds.  If there is already data
-   under this key, it will be replaced.  Using a DATA of NULL deletes
-   the entry.  A TTL of 0 is replaced by the default TTL and a TTL of
-   -1 set infinite timeout.  CACHE_MODE is stored with the cache entry
+/* Store the string DATA in the cache under KEY and mark it with a
+   maximum lifetime of TTL seconds.  If there is already data under
+   this key, it will be replaced.  Using a DATA of NULL deletes the
+   entry.  A TTL of 0 is replaced by the default TTL and a TTL of -1
+   set infinite timeout.  CACHE_MODE is stored with the cache entry
    and used to select different timeouts.  */
 int
 agent_put_cache (const char *key, cache_mode_t cache_mode,
                  const char *data, int ttl)
 {
+  gpg_error_t err = 0;
   ITEM r;
 
   if (DBG_CACHE)
-    log_debug ("agent_put_cache `%s' requested ttl=%d mode=%d\n",
-               key, ttl, cache_mode);
+    log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n",
+               key, cache_mode, ttl);
   housekeeping ();
 
   if (!ttl)
@@ -215,16 +326,19 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
         default: ttl = opt.def_cache_ttl; break;
         }
     }
-  if (!ttl || cache_mode == CACHE_MODE_IGNORE)
+  if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE)
     return 0;
 
   for (r=thecache; r; r = r->next)
     {
-      if (!r->lockcount && !strcmp (r->key, key))
+      if (((cache_mode != CACHE_MODE_USER
+            && cache_mode != CACHE_MODE_NONCE)
+           || r->cache_mode == cache_mode)
+          && !strcmp (r->key, key))
         break;
     }
-  if (r)
-    { /* replace */
+  if (r) /* Replace.  */
+    {
       if (r->pw)
         {
           release_data (r->pw);
@@ -232,109 +346,126 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
         }
       if (data)
         {
-          r->created = r->accessed = gnupg_get_time (); 
+          r->created = r->accessed = gnupg_get_time ();
           r->ttl = ttl;
           r->cache_mode = cache_mode;
-          r->pw = new_data (data, strlen (data)+1);
-          if (!r->pw)
-            log_error ("out of core while allocating new cache item\n");
+          err = new_data (data, &r->pw);
+          if (err)
+            log_error ("error replacing cache item: %s\n", gpg_strerror (err));
         }
     }
-  else if (data)
-    { /* simply insert */
+  else if (data) /* Insert.  */
+    {
       r = xtrycalloc (1, sizeof *r + strlen (key));
       if (!r)
-        log_error ("out of core while allocating new cache control\n");
+        err = gpg_error_from_syserror ();
       else
         {
           strcpy (r->key, key);
-          r->created = r->accessed = gnupg_get_time (); 
+          r->created = r->accessed = gnupg_get_time ();
           r->ttl = ttl;
           r->cache_mode = cache_mode;
-          r->pw = new_data (data, strlen (data)+1);
-          if (!r->pw)
-            {
-              log_error ("out of core while allocating new cache item\n");
-              xfree (r);
-            }
+          err = new_data (data, &r->pw);
+          if (err)
+            xfree (r);
           else
             {
               r->next = thecache;
               thecache = r;
             }
         }
+      if (err)
+        log_error ("error inserting cache item: %s\n", gpg_strerror (err));
     }
-  return 0;
+  return err;
 }
 
 
 /* Try to find an item in the cache.  Note that we currently don't
-   make use of CACHE_MODE.  */
-const char *
-agent_get_cache (const char *key, cache_mode_t cache_mode, void **cache_id)
+   make use of CACHE_MODE except for CACHE_MODE_NONCE and
+   CACHE_MODE_USER.  */
+char *
+agent_get_cache (const char *key, cache_mode_t cache_mode)
 {
+  gpg_error_t err;
   ITEM r;
+  char *value = NULL;
+  int res;
+  int last_stored = 0;
 
   if (cache_mode == CACHE_MODE_IGNORE)
     return NULL;
 
+  if (!key)
+    {
+      key = last_stored_cache_key;
+      if (!key)
+        return NULL;
+      last_stored = 1;
+    }
+
+
   if (DBG_CACHE)
-    log_debug ("agent_get_cache `%s'...\n", key);
+    log_debug ("agent_get_cache '%s' (mode %d)%s ...\n",
+               key, cache_mode,
+               last_stored? " (stored cache key)":"");
   housekeeping ();
 
-  /* first try to find one with no locks - this is an updated cache
-     entry: We might have entries with a lockcount and without a
-     lockcount. */
   for (r=thecache; r; r = r->next)
     {
-      if (!r->lockcount && r->pw && !strcmp (r->key, key))
+      if (r->pw
+          && ((cache_mode != CACHE_MODE_USER
+               && cache_mode != CACHE_MODE_NONCE)
+              || r->cache_mode == cache_mode)
+          && !strcmp (r->key, key))
         {
-          /* put_cache does only put strings into the cache, so we
-             don't need the lengths */
+          /* Note: To avoid races KEY may not be accessed anymore below.  */
           r->accessed = gnupg_get_time ();
           if (DBG_CACHE)
             log_debug ("... hit\n");
-          r->lockcount++;
-          *cache_id = r;
-          return r->pw->data;
-        }
-    }
-  /* again, but this time get even one with a lockcount set */
-  for (r=thecache; r; r = r->next)
-    {
-      if (r->pw && !strcmp (r->key, key))
-        {
-          r->accessed = gnupg_get_time ();
-          if (DBG_CACHE)
-            log_debug ("... hit (locked)\n");
-          r->lockcount++;
-          *cache_id = r;
-          return r->pw->data;
+          if (r->pw->totallen < 32)
+            err = gpg_error (GPG_ERR_INV_LENGTH);
+          else if ((err = init_encryption ()))
+            ;
+          else if (!(value = xtrymalloc_secure (r->pw->totallen - 8)))
+            err = gpg_error_from_syserror ();
+          else
+            {
+              res = npth_mutex_lock (&encryption_lock);
+              if (res)
+                log_fatal ("failed to acquire cache encryption mutex: %s\n",
+                          strerror (res));
+              err = gcry_cipher_decrypt (encryption_handle,
+                                         value, r->pw->totallen - 8,
+                                         r->pw->data, r->pw->totallen);
+              res = npth_mutex_unlock (&encryption_lock);
+              if (res)
+                log_fatal ("failed to release cache encryption mutex: %s\n",
+                          strerror (res));
+            }
+          if (err)
+            {
+              xfree (value);
+              value = NULL;
+              log_error ("retrieving cache entry '%s' failed: %s\n",
+                         key, gpg_strerror (err));
+            }
+          return value;
         }
     }
   if (DBG_CACHE)
     log_debug ("... miss\n");
 
-  *cache_id = NULL;
   return NULL;
 }
 
 
+/* Store the key for the last successful cache hit.  That value is
+   used by agent_get_cache if the requested KEY is given as NULL.
+   NULL may be used to remove that key. */
 void
-agent_unlock_cache_entry (void **cache_id)
+agent_store_cache_hit (const char *key)
 {
-  ITEM r;
-
-  for (r=thecache; r; r = r->next)
-    {
-      if (r == *cache_id)
-        {
-          if (!r->lockcount)
-            log_error ("trying to unlock non-locked cache entry `%s'\n",
-                       r->key);
-          else
-            r->lockcount--;
-          return;
-        }
-    }
+  xfree (last_stored_cache_key);
+  last_stored_cache_key = key? xtrystrdup (key) : NULL;
 }
index 5686998..e5977ad 100644 (file)
 # include <sys/types.h>
 # include <signal.h>
 #endif
-#include <pth.h>
+#include <npth.h>
 
 #include "agent.h"
 #include <assuan.h>
-#include "setenv.h"
+#include "sysutils.h"
 #include "i18n.h"
 
 #ifdef _POSIX_OPEN_MAX
@@ -62,10 +62,10 @@ static assuan_context_t entry_ctx;
 static ctrl_t entry_owner;
 
 /* A mutex used to serialize access to the pinentry. */
-static pth_mutex_t entry_lock;
+static npth_mutex_t entry_lock;
 
 /* The thread ID of the popup working thread. */
-static pth_t  popup_tid;
+static npth_t  popup_tid;
 
 /* A flag used in communication between the popup working thread and
    its stop function. */
@@ -95,40 +95,20 @@ initialize_module_call_pinentry (void)
 
   if (!initialized)
     {
-      if (pth_mutex_init (&entry_lock))
+      if (npth_mutex_init (&entry_lock, NULL))
         initialized = 1;
     }
 }
 
 
 
-static void
-dump_mutex_state (pth_mutex_t *m)
-{
-#ifdef _W32_PTH_H
-  (void)m;
-  log_printf ("unknown under W32");
-#else
-  if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
-    log_printf ("not_initialized");
-  else if (!(m->mx_state & PTH_MUTEX_LOCKED))
-    log_printf ("not_locked");
-  else
-    log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
-#endif
-}
-
-
 /* This function may be called to print infromation pertaining to the
    current state of this module to the log. */
 void
 agent_query_dump_state (void)
 {
-  log_info ("agent_query_dump_state: entry_lock=");
-  dump_mutex_state (&entry_lock);
-  log_printf ("\n");
   log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
-            entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid);
+            entry_ctx, (long)assuan_get_pid (entry_ctx), (void*)popup_tid);
 }
 
 /* Called to make sure that a popup window owned by the current
@@ -151,13 +131,15 @@ static int
 unlock_pinentry (int rc)
 {
   assuan_context_t ctx = entry_ctx;
+  int err;
 
   entry_ctx = NULL;
-  if (!pth_mutex_release (&entry_lock))
+  err = npth_mutex_unlock (&entry_lock);
+  if (err)
     {
-      log_error ("failed to release the entry lock\n");
+      log_error ("failed to release the entry lock: %s\n", strerror (err));
       if (!rc)
-        rc = gpg_error (GPG_ERR_INTERNAL);
+        rc = gpg_error_from_errno (err);
     }
   assuan_release (ctx);
   return rc;
@@ -170,16 +152,6 @@ static void
 atfork_cb (void *opaque, int where)
 {
   ctrl_t ctrl = opaque;
-#ifndef HAVE_W32_SYSTEM
-  struct sigaction sa;
-
-  /* Pop up message should be able to be killed by SIGINT.  */
-  sigemptyset (&sa.sa_mask);
-  sa.sa_handler = SIG_DFL;
-  sa.sa_flags = 0;
-  sigaction (SIGINT, &sa, NULL);
-  sigprocmask (SIG_SETMASK, &sa.sa_mask, NULL); /* Unblock all signals.  */
-#endif
 
   if (!where)
     {
@@ -200,7 +172,7 @@ atfork_cb (void *opaque, int where)
             {
               value = session_env_getenv (ctrl->session_env, name);
               if (value)
-                setenv (name, value, 1);
+                gnupg_setenv (name, value, 1);
             }
         }
     }
@@ -232,30 +204,31 @@ getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
 static int
 start_pinentry (ctrl_t ctrl)
 {
-  int rc;
+  int rc = 0;
   const char *pgmname;
   assuan_context_t ctx;
   const char *argv[5];
-  int no_close_list[3];
+  assuan_fd_t no_close_list[3];
   int i;
-  pth_event_t evt;
   const char *tmpstr;
   unsigned long pinentry_pid;
   const char *value;
+  struct timespec abstime;
+  int err;
 
-  evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
-  if (!pth_mutex_acquire (&entry_lock, 0, evt))
+  npth_clock_gettime (&abstime);
+  abstime.tv_sec += LOCK_TIMEOUT;
+  err = npth_mutex_timedlock (&entry_lock, &abstime);
+  if (err)
     {
-      if (pth_event_occurred (evt))
-        rc = gpg_error (GPG_ERR_TIMEOUT);
+      if (err == ETIMEDOUT)
+       rc = gpg_error (GPG_ERR_TIMEOUT);
       else
-        rc = gpg_error (GPG_ERR_INTERNAL);
-      pth_event_free (evt, PTH_FREE_THIS);
+       rc = gpg_error_from_errno (rc);
       log_error (_("failed to acquire the pinentry lock: %s\n"),
                  gpg_strerror (rc));
       return rc;
     }
-  pth_event_free (evt, PTH_FREE_THIS);
 
   entry_owner = ctrl;
 
@@ -286,7 +259,7 @@ start_pinentry (ctrl_t ctrl)
 
   if (!opt.pinentry_program || !*opt.pinentry_program)
     opt.pinentry_program = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY);
-    pgmname = opt.pinentry_program;
+  pgmname = opt.pinentry_program;
   if ( !(pgmname = strrchr (opt.pinentry_program, '/')))
     pgmname = opt.pinentry_program;
   else
@@ -318,7 +291,7 @@ start_pinentry (ctrl_t ctrl)
         no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
       no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
     }
-  no_close_list[i] = -1;
+  no_close_list[i] = ASSUAN_INVALID_FD;
 
   rc = assuan_new (&ctx);
   if (rc)
@@ -326,6 +299,12 @@ start_pinentry (ctrl_t ctrl)
       log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
       return rc;
     }
+  /* We don't want to log the pinentry communication to make the logs
+     easier to read.  We might want to add a new debug option to enable
+     pinentry logging.  */
+#ifdef ASSUAN_NO_LOGGING
+  assuan_set_flag (ctx, ASSUAN_NO_LOGGING, 1);
+#endif
 
   /* Connect to the pinentry and perform initial handshaking.  Note
      that atfork is used to change the environment for pinentry.  We
@@ -336,8 +315,8 @@ start_pinentry (ctrl_t ctrl)
                            ASSUAN_PIPE_CONNECT_DETACHED);
   if (rc)
     {
-      log_error ("can't connect to the PIN entry module: %s\n",
-                 gpg_strerror (rc));
+      log_error ("can't connect to the PIN entry module '%s': %s\n",
+                 opt.pinentry_program, gpg_strerror (rc));
       assuan_release (ctx);
       return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
     }
@@ -352,7 +331,6 @@ start_pinentry (ctrl_t ctrl)
   if (rc)
     return unlock_pinentry (rc);
 
-
   value = session_env_getenv (ctrl->session_env, "GPG_TTY");
   if (value)
     {
@@ -400,26 +378,10 @@ start_pinentry (ctrl_t ctrl)
        return unlock_pinentry (rc);
     }
 
-  if (opt.allow_external_cache)
-    {
-      /* Indicate to the pinentry that it may read from an external cache.
-
-         It is essential that the pinentry respect this.  If the
-         cached password is not up to date and retry == 1, then, using
-         a version of GPG Agent that doesn't support this, won't issue
-         another pin request and the user won't get a chance to
-         correct the password.  */
-      rc = assuan_transact (entry_ctx, "OPTION allow-external-password-cache",
-                            NULL, NULL, NULL, NULL, NULL, NULL);
-      if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
-        return unlock_pinentry (rc);
-    }
-
-
   {
     /* Provide a few default strings for use by the pinentries.  This
        may help a pinentry to avoid implementing localization code.  */
-    static struct { const char *key, *value; int mode; } tbl[] = {
+    static struct { const char *key, *value; } tbl[] = {
       /* TRANSLATORS: These are labels for buttons etc used in
          Pinentries.  An underscore indicates that the next letter
          should be used as an accelerator.  Double the underscore for
@@ -427,14 +389,7 @@ start_pinentry (ctrl_t ctrl)
          the second vertical bar.  */
       { "ok",     N_("|pinentry-label|_OK") },
       { "cancel", N_("|pinentry-label|_Cancel") },
-      { "yes",    N_("|pinentry-label|_Yes") },
-      { "no",     N_("|pinentry-label|_No") },
       { "prompt", N_("|pinentry-label|PIN:") },
-      { "pwmngr", N_("|pinentry-label|_Save in password manager") },
-      { "cf-visi",N_("Do you really want to make your "
-                     "passphrase visible on the screen?") },
-      { "tt-visi",N_("|pinentry-tt|Make passphrase visible") },
-      { "tt-hide",N_("|pinentry-tt|Hide passphrase") },
       { NULL, NULL}
     };
     char *optstr;
@@ -495,8 +450,10 @@ start_pinentry (ctrl_t ctrl)
   else
     {
       rc = agent_inq_pinentry_launched (ctrl, pinentry_pid);
-      if (gpg_err_code (rc) == GPG_ERR_CANCELED)
-        return unlock_pinentry (gpg_error (GPG_ERR_CANCELED));
+      if (gpg_err_code (rc) == GPG_ERR_CANCELED
+          || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
+        return unlock_pinentry (gpg_err_make (GPG_ERR_SOURCE_DEFAULT,
+                                              gpg_err_code (rc)));
       rc = 0;
     }
 
@@ -510,33 +467,37 @@ start_pinentry (ctrl_t ctrl)
 int
 pinentry_active_p (ctrl_t ctrl, int waitseconds)
 {
+  int err;
   (void)ctrl;
 
   if (waitseconds > 0)
     {
-      pth_event_t evt;
+      struct timespec abstime;
       int rc;
 
-      evt = pth_event (PTH_EVENT_TIME, pth_timeout (waitseconds, 0));
-      if (!pth_mutex_acquire (&entry_lock, 0, evt))
+      npth_clock_gettime (&abstime);
+      abstime.tv_sec += waitseconds;
+      err = npth_mutex_timedlock (&entry_lock, &abstime);
+      if (err)
         {
-          if (pth_event_occurred (evt))
+          if (err == ETIMEDOUT)
             rc = gpg_error (GPG_ERR_TIMEOUT);
           else
             rc = gpg_error (GPG_ERR_INTERNAL);
-          pth_event_free (evt, PTH_FREE_THIS);
           return rc;
         }
-      pth_event_free (evt, PTH_FREE_THIS);
     }
   else
     {
-      if (!pth_mutex_acquire (&entry_lock, 1, NULL))
+      err = npth_mutex_trylock (&entry_lock);
+      if (err)
         return gpg_error (GPG_ERR_LOCKED);
     }
 
-  if (!pth_mutex_release (&entry_lock))
-    log_error ("failed to release the entry lock at %d\n", __LINE__);
+  err = npth_mutex_unlock (&entry_lock);
+  if (err)
+    log_error ("failed to release the entry lock at %d: %s\n", __LINE__,
+              strerror (errno));
   return 0;
 }
 
@@ -635,18 +596,15 @@ static gpg_error_t
 inq_quality (void *opaque, const char *line)
 {
   assuan_context_t ctx = opaque;
+  const char *s;
   char *pin;
   int rc;
   int percent;
   char numbuf[20];
 
-  if (!strncmp (line, "QUALITY", 7) && (line[7] == ' ' || !line[7]))
+  if ((s = has_leading_keyword (line, "QUALITY")))
     {
-      line += 7;
-      while (*line == ' ')
-        line++;
-
-      pin = unescape_passphrase_string (line);
+      pin = unescape_passphrase_string (s);
       if (!pin)
         rc = gpg_error_from_syserror ();
       else
@@ -661,7 +619,7 @@ inq_quality (void *opaque, const char *line)
     }
   else
     {
-      log_error ("unsupported inquiry `%s' from pinentry\n", line);
+      log_error ("unsupported inquiry '%s' from pinentry\n", line);
       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
     }
 
@@ -724,36 +682,38 @@ setup_qualitybar (void)
 }
 
 
-enum
-  {
-    PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9
-  };
-
 /* Check the button_info line for a close action.  Also check for the
    PIN_REPEATED flag.  */
 static gpg_error_t
-pinentry_status_cb (void *opaque, const char *line)
+close_button_status_cb (void *opaque, const char *line)
 {
   unsigned int *flag = opaque;
+  const char *args;
 
-  if (strcmp (line, "PASSWORD_FROM_CACHE") == 0)
+  if ((args = has_leading_keyword (line, "BUTTON_INFO")))
+    {
+      if (!strcmp (args, "close"))
+        *flag = 1;
+    }
+  else if (has_leading_keyword (line, "PIN_REPEATED"))
     {
-      *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE;
+      *flag |= 256;
     }
 
   return 0;
 }
+
+
+
 \f
 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
    number here and repeat it as long as we have invalid formed
-   numbers.  KEYINFO and CACHEMODE are used to tell pinentry something
-   about the key. */
+   numbers. */
 int
 agent_askpin (ctrl_t ctrl,
               const char *desc_text, const char *prompt_text,
               const char *initial_errtext,
-              struct pin_entry_info_s *pininfo,
-              const char *keyinfo, cache_mode_t cache_mode)
+              struct pin_entry_info_s *pininfo)
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
@@ -761,11 +721,40 @@ agent_askpin (ctrl_t ctrl,
   const char *errtext = NULL;
   int is_pin = 0;
   int saveflag;
-  unsigned int pinentry_status;
+  unsigned int close_button;
 
   if (opt.batch)
     return 0; /* fixme: we should return BAD PIN */
 
+  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
+    {
+      if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
+        return gpg_error (GPG_ERR_CANCELED);
+      if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
+        {
+         unsigned char *passphrase;
+         size_t size;
+
+         *pininfo->pin = 0; /* Reset the PIN. */
+         rc = pinentry_loopback(ctrl, "PASSPHRASE", &passphrase, &size,
+                 pininfo->max_length);
+         if (rc)
+           return rc;
+
+         memcpy(&pininfo->pin, passphrase, size);
+         xfree(passphrase);
+         pininfo->pin[size] = 0;
+         if (pininfo->check_cb)
+           {
+             /* More checks by utilizing the optional callback. */
+             pininfo->cb_errtext = NULL;
+             rc = pininfo->check_cb (pininfo);
+           }
+         return rc;
+       }
+      return gpg_error(GPG_ERR_NO_PIN_ENTRY);
+    }
+
   if (!pininfo || pininfo->max_length < 1)
     return gpg_error (GPG_ERR_INV_VALUE);
   if (!desc_text && pininfo->min_digits)
@@ -784,25 +773,6 @@ agent_askpin (ctrl_t ctrl,
   if (rc)
     return rc;
 
-  /* If we have a KEYINFO string and are normal, user, or ssh cache
-     mode, we tell that the Pinentry so it may use it for own caching
-     purposes.  Most pinentries won't have this implemented and thus
-     we do not error out in this case.  */
-  if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
-                  || cache_mode == CACHE_MODE_USER
-                  || cache_mode == CACHE_MODE_SSH))
-    snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
-             cache_mode == CACHE_MODE_USER? 'u' :
-             cache_mode == CACHE_MODE_SSH? 's' : 'n',
-             keyinfo);
-  else
-    snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
-
-  rc = assuan_transact (entry_ctx, line,
-                       NULL, NULL, NULL, NULL, NULL, NULL);
-  if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
-    return unlock_pinentry (rc);
-
   snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
   line[DIM(line)-1] = 0;
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -836,6 +806,18 @@ agent_askpin (ctrl_t ctrl,
         return unlock_pinentry (rc);
     }
 
+  if (pininfo->with_repeat)
+    {
+      snprintf (line, DIM(line)-1, "SETREPEATERROR %s",
+                _("does not match - try again"));
+      line[DIM(line)-1] = 0;
+      rc = assuan_transact (entry_ctx, line,
+                            NULL, NULL, NULL, NULL, NULL, NULL);
+      if (rc)
+        pininfo->with_repeat = 0; /* Pinentry does not support it.  */
+    }
+  pininfo->repeat_okay = 0;
+
   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
     {
       memset (&parm, 0, sizeof parm);
@@ -858,12 +840,22 @@ agent_askpin (ctrl_t ctrl,
           errtext = NULL;
         }
 
+      if (pininfo->with_repeat)
+        {
+          snprintf (line, DIM(line)-1, "SETREPEAT %s", _("Repeat:"));
+          line[DIM(line)-1] = 0;
+          rc = assuan_transact (entry_ctx, line,
+                                NULL, NULL, NULL, NULL, NULL, NULL);
+          if (rc)
+            return unlock_pinentry (rc);
+        }
+
       saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
       assuan_begin_confidential (entry_ctx);
-      pinentry_status = 0;
+      close_button = 0;
       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
                             inq_quality, entry_ctx,
-                           pinentry_status_cb, &pinentry_status);
+                            close_button_status_cb, &close_button);
       assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
       /* Most pinentries out in the wild return the old Assuan error code
          for canceled which gets translated to an assuan Cancel error and
@@ -872,6 +864,12 @@ agent_askpin (ctrl_t ctrl,
           && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
 
+
+      /* Change error code in case the window close button was clicked
+         to cancel the operation.  */
+      if ((close_button & 1) && gpg_err_code (rc) == GPG_ERR_CANCELED)
+        rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
+
       if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
         errtext = is_pin? _("PIN too long")
                         : _("Passphrase too long");
@@ -906,12 +904,11 @@ agent_askpin (ctrl_t ctrl,
         }
 
       if (!errtext)
-        return unlock_pinentry (0); /* okay, got a PIN or passphrase */
-
-      if ((pinentry_status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
-       /* The password was read from the cache.  Don't count this
-          against the retry count.  */
-       pininfo->failed_tries --;
+        {
+          if (pininfo->with_repeat && (close_button & 256))
+            pininfo->repeat_okay = 1;
+          return unlock_pinentry (0); /* okay, got a PIN or passphrase */
+        }
     }
 
   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
@@ -921,23 +918,47 @@ agent_askpin (ctrl_t ctrl,
 
 \f
 /* Ask for the passphrase using the supplied arguments.  The returned
-   passphrase needs to be freed by the caller.  */
+   passphrase needs to be freed by the caller. */
 int
 agent_get_passphrase (ctrl_t ctrl,
                       char **retpass, const char *desc, const char *prompt,
-                      const char *errtext, int with_qualitybar,
-                     const char *keyinfo, cache_mode_t cache_mode)
+                      const char *errtext, int with_qualitybar)
 {
 
   int rc;
   char line[ASSUAN_LINELENGTH];
   struct entry_parm_s parm;
   int saveflag;
+  unsigned int close_button;
 
   *retpass = NULL;
   if (opt.batch)
     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
 
+  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
+    {
+      if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
+        return gpg_error (GPG_ERR_CANCELED);
+
+      if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
+        {
+         size_t size;
+         size_t len = ASSUAN_LINELENGTH/2;
+         unsigned char *buffer = gcry_malloc_secure (len);
+
+         rc = pinentry_loopback(ctrl, "PASSPHRASE", &buffer, &size, len);
+         if (rc)
+           xfree(buffer);
+         else
+           {
+             buffer[size] = 0;
+             *retpass = buffer;
+           }
+         return rc;
+        }
+      return gpg_error (GPG_ERR_NO_PIN_ENTRY);
+    }
+
   rc = start_pinentry (ctrl);
   if (rc)
     return rc;
@@ -946,26 +967,6 @@ agent_get_passphrase (ctrl_t ctrl,
     prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
 
 
-  /* If we have a KEYINFO string and are normal, user, or ssh cache
-     mode, we tell that the Pinentry so it may use it for own caching
-     purposes.  Most pinentries won't have this implemented and thus
-     we do not error out in this case.  */
-  if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
-                  || cache_mode == CACHE_MODE_USER
-                  || cache_mode == CACHE_MODE_SSH))
-    snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
-             cache_mode == CACHE_MODE_USER? 'u' :
-             cache_mode == CACHE_MODE_SSH? 's' : 'n',
-             keyinfo);
-  else
-    snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
-
-  rc = assuan_transact (entry_ctx, line,
-                       NULL, NULL, NULL, NULL, NULL, NULL);
-  if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
-    return unlock_pinentry (rc);
-
-
   if (desc)
     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
   else
@@ -1005,14 +1006,21 @@ agent_get_passphrase (ctrl_t ctrl,
 
   saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
   assuan_begin_confidential (entry_ctx);
+  close_button = 0;
   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
-                        inq_quality, entry_ctx, NULL, NULL);
+                        inq_quality, entry_ctx,
+                        close_button_status_cb, &close_button);
   assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
   /* Most pinentries out in the wild return the old Assuan error code
      for canceled which gets translated to an assuan Cancel error and
      not to the code for a user cancel.  Fix this here. */
   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
+  /* Change error code in case the window close button was clicked
+     to cancel the operation.  */
+  if ((close_button & 1) && gpg_err_code (rc) == GPG_ERR_CANCELED)
+    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
+
   if (rc)
     xfree (parm.buffer);
   else
@@ -1037,6 +1045,14 @@ agent_get_confirmation (ctrl_t ctrl,
   int rc;
   char line[ASSUAN_LINELENGTH];
 
+  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
+    {
+      if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
+        return gpg_error (GPG_ERR_CANCELED);
+
+      return gpg_error (GPG_ERR_NO_PIN_ENTRY);
+    }
+
   rc = start_pinentry (ctrl);
   if (rc)
     return rc;
@@ -1102,7 +1118,7 @@ agent_get_confirmation (ctrl_t ctrl,
 
 \f
 /* Pop up the PINentry, display the text DESC and a button with the
-   text OK_BTN (which may be NULL to use the default of "OK") and waut
+   text OK_BTN (which may be NULL to use the default of "OK") and wait
    for the user to hit this button.  The return value is not
    relevant.  */
 int
@@ -1111,6 +1127,9 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
   int rc;
   char line[ASSUAN_LINELENGTH];
 
+  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
+    return gpg_error (GPG_ERR_CANCELED);
+
   rc = start_pinentry (ctrl);
   if (rc)
     return rc;
@@ -1177,7 +1196,11 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
-  pth_attr_t tattr;
+  npth_attr_t tattr;
+  int err;
+
+  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
+    return gpg_error (GPG_ERR_CANCELED);
 
   rc = start_pinentry (ctrl);
   if (rc)
@@ -1201,22 +1224,22 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
         return unlock_pinentry (rc);
     }
 
-  tattr = pth_attr_new();
-  pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
-  pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
-  pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message");
+  err = npth_attr_init (&tattr);
+  if (err)
+    return unlock_pinentry (gpg_error_from_errno (err));
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
 
   popup_finished = 0;
-  popup_tid = pth_spawn (tattr, popup_message_thread, NULL);
-  if (!popup_tid)
+  err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL);
+  npth_attr_destroy (&tattr);
+  if (err)
     {
-      rc = gpg_error_from_syserror ();
+      rc = gpg_error_from_errno (err);
       log_error ("error spawning popup message handler: %s\n",
-                 strerror (errno) );
-      pth_attr_destroy (tattr);
+                 strerror (err) );
       return unlock_pinentry (rc);
     }
-  pth_attr_destroy (tattr);
+  npth_setname_np (popup_tid, "popup-message");
 
   return 0;
 }
@@ -1266,40 +1289,15 @@ agent_popup_message_stop (ctrl_t ctrl)
 #endif
 
   /* Now wait for the thread to terminate. */
-  rc = pth_join (popup_tid, NULL);
-  if (!rc)
+  rc = npth_join (popup_tid, NULL);
+  if (rc)
     log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
-               strerror (errno));
-  popup_tid = NULL;
+               strerror (rc));
+  /* Thread IDs are opaque, but we try our best here by resetting it
+     to the same content that a static global variable has.  */
+  memset (&popup_tid, '\0', sizeof (popup_tid));
   entry_owner = NULL;
 
   /* Now we can close the connection. */
   unlock_pinentry (0);
 }
-
-
-int
-agent_clear_passphrase (ctrl_t ctrl,
-                       const char *keyinfo, cache_mode_t cache_mode)
-{
-  int rc;
-  char line[ASSUAN_LINELENGTH];
-
-  if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
-                    || cache_mode == CACHE_MODE_USER
-                    || cache_mode == CACHE_MODE_SSH)))
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  rc = start_pinentry (ctrl);
-  if (rc)
-    return rc;
-
-  snprintf (line, DIM(line)-1, "CLEARPASSPHRASE %c/%s",
-           cache_mode == CACHE_MODE_USER? 'u' :
-           cache_mode == CACHE_MODE_SSH? 's' : 'n',
-           keyinfo);
-  rc = assuan_transact (entry_ctx, line,
-                       NULL, NULL, NULL, NULL, NULL, NULL);
-
-  return unlock_pinentry (rc);
-}
index 9a2e65e..289b2d9 100644 (file)
@@ -1,5 +1,7 @@
 /* call-scd.c - fork of the scdaemon to do SC operations
- *     Copyright (C) 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2005, 2007, 2010,
+ *               2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include <ctype.h>
 #include <assert.h>
 #include <unistd.h>
-#include <signal.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 #include <sys/stat.h>
 #include <sys/types.h>
 #ifndef HAVE_W32_SYSTEM
 #include <sys/wait.h>
 #endif
-#include <pth.h>
+#include <npth.h>
 
 #include "agent.h"
 #include <assuan.h>
 #define MAX_OPEN_FDS 20
 #endif
 
-/* This Assuan flag is only available since libassuan 2.0.2.  Because
-   comments lines are comments anyway we can use a replacement which
-   might not do anything.  assuan_{g,s}et_flag don't return an error
-   thus there won't be any ABI problem.  */
-#ifndef ASSUAN_CONVEY_COMMENTS
-#define ASSUAN_CONVEY_COMMENTS 4
-#endif
-
-
 /* Definition of module local data of the CTRL structure.  */
 struct scd_local_s
 {
@@ -83,13 +78,14 @@ struct learn_parm_s
   void *sinfo_cb_arg;
 };
 
-struct inq_needpin_s 
+struct inq_needpin_s
 {
   assuan_context_t ctx;
   int (*getpin_cb)(void *, const char *, char*, size_t);
   void *getpin_cb_arg;
   assuan_context_t passthru;  /* If not NULL, pass unknown inquiries
                                  up to the caller.  */
+  int any_inq_seen;
 };
 
 
@@ -98,7 +94,7 @@ struct inq_needpin_s
 static struct scd_local_s *scd_local_list;
 
 /* A Mutex used inside the start_scd function. */
-static pth_mutex_t start_scd_lock;
+static npth_mutex_t start_scd_lock;
 
 /* A malloced string with the name of the socket to be used for
    additional connections.  May be NULL if not provided by
@@ -125,53 +121,35 @@ static gpg_error_t membuf_data_cb (void *opaque,
 \f
 /* This function must be called once to initialize this module.  This
    has to be done before a second thread is spawned.  We can't do the
-   static initialization because Pth emulation code might not be able
+   static initialization because NPth emulation code might not be able
    to do a static init; in particular, it is not possible for W32. */
 void
 initialize_module_call_scd (void)
 {
   static int initialized;
+  int err;
 
   if (!initialized)
     {
-      if (!pth_mutex_init (&start_scd_lock))
-        log_fatal ("error initializing mutex: %s\n", strerror (errno));
+      err = npth_mutex_init (&start_scd_lock, NULL);
+      if (err)
+       log_fatal ("error initializing mutex: %s\n", strerror (err));
       initialized = 1;
     }
 }
 
 
-static void
-dump_mutex_state (pth_mutex_t *m)
-{
-#ifdef _W32_PTH_H
-  (void)m;
-  log_printf ("unknown under W32");
-#else
-  if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
-    log_printf ("not_initialized");
-  else if (!(m->mx_state & PTH_MUTEX_LOCKED))
-    log_printf ("not_locked");
-  else
-    log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
-#endif
-}
-
-
 /* This function may be called to print infromation pertaining to the
    current state of this module to the log. */
 void
 agent_scd_dump_state (void)
 {
-  log_info ("agent_scd_dump_state: scd_lock=");
-  dump_mutex_state (&start_scd_lock);
-  log_printf ("\n");
   log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
-            primary_scd_ctx, 
+            primary_scd_ctx,
             (long)assuan_get_pid (primary_scd_ctx),
             primary_scd_ctx_reusable);
   if (socket_name)
-    log_info ("agent_scd_dump_state: socket=`%s'\n", socket_name);
+    log_info ("agent_scd_dump_state: socket='%s'\n", socket_name);
 }
 
 
@@ -182,20 +160,9 @@ agent_scd_dump_state (void)
    called and error checked before any SCD operation.  CTRL is the
    usual connection context and RC the error code to be passed trhough
    the function. */
-static int 
+static int
 unlock_scd (ctrl_t ctrl, int rc)
 {
-  if (gpg_err_code (rc) == GPG_ERR_NOT_OPERATIONAL
-      && gpg_err_source (rc) == GPG_ERR_SOURCE_SCD)
-    {
-      /* If the SCdaemon returned this error, it detected a major
-         problem, like no reader connected.  To finish this we need to
-         stop the connection.  This simulates an explicit killing of
-         the SCdaemon.  */
-      assuan_transact (primary_scd_ctx, "BYE",
-                       NULL, NULL, NULL, NULL, NULL, NULL);
-    }
-      
   if (ctrl->scd_local->locked != 1)
     {
       log_error ("unlock_scd: invalid lock count (%d)\n",
@@ -231,7 +198,7 @@ start_scd (ctrl_t ctrl)
   const char *pgmname;
   assuan_context_t ctx = NULL;
   const char *argv[3];
-  int no_close_list[3];
+  assuan_fd_t no_close_list[3];
   int i;
   int rc;
 
@@ -269,10 +236,11 @@ start_scd (ctrl_t ctrl)
 
 
   /* We need to protect the following code. */
-  if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
+  rc = npth_mutex_lock (&start_scd_lock);
+  if (rc)
     {
       log_error ("failed to acquire the start_scd lock: %s\n",
-                 strerror (errno));
+                 strerror (rc));
       return gpg_error (GPG_ERR_INTERNAL);
     }
 
@@ -301,7 +269,7 @@ start_scd (ctrl_t ctrl)
       rc = assuan_socket_connect (ctx, socket_name, 0, 0);
       if (rc)
         {
-          log_error ("can't connect to socket `%s': %s\n",
+          log_error ("can't connect to socket '%s': %s\n",
                      socket_name, gpg_strerror (rc));
           err = gpg_error (GPG_ERR_NO_SCDAEMON);
           goto leave;
@@ -322,7 +290,7 @@ start_scd (ctrl_t ctrl)
   /* Nope, it has not been started.  Fire it up now. */
   if (opt.verbose)
     log_info ("no running SCdaemon - starting it\n");
-      
+
   if (fflush (NULL))
     {
 #ifndef HAVE_W32_SYSTEM
@@ -356,7 +324,7 @@ start_scd (ctrl_t ctrl)
         no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
       no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
     }
-  no_close_list[i] = -1;
+  no_close_list[i] = ASSUAN_INVALID_FD;
 
   /* Connect to the pinentry and perform initial handshaking.  Use
      detached flag (128) so that under W32 SCDAEMON does not show up a
@@ -374,8 +342,6 @@ start_scd (ctrl_t ctrl)
   if (opt.verbose)
     log_debug ("first connection to SCdaemon established\n");
 
-  if (DBG_ASSUAN)
-    assuan_set_log_stream (ctx, log_get_stream ());
 
   /* Get the name of the additional socket opened by scdaemon. */
   {
@@ -401,25 +367,28 @@ start_scd (ctrl_t ctrl)
             memcpy (socket_name, databuf, datalen);
             socket_name[datalen] = 0;
             if (DBG_ASSUAN)
-              log_debug ("additional connections at `%s'\n", socket_name);
+              log_debug ("additional connections at '%s'\n", socket_name);
           }
       }
     xfree (databuf);
   }
 
-  /* Tell the scdaemon we want him to send us an event signal. */
+  /* Tell the scdaemon we want him to send us an event signal.  We
+     don't support this for W32CE.  */
+#ifndef HAVE_W32CE_SYSTEM
   if (opt.sigusr2_enabled)
     {
       char buf[100];
-      
+
 #ifdef HAVE_W32_SYSTEM
-      snprintf (buf, sizeof buf, "OPTION event-signal=%lx", 
+      snprintf (buf, sizeof buf, "OPTION event-signal=%lx",
                 (unsigned long)get_agent_scd_notify_event ());
 #else
       snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2);
 #endif
       assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
     }
+#endif /*HAVE_W32CE_SYSTEM*/
 
   primary_scd_ctx = ctx;
   primary_scd_ctx_reusable = 0;
@@ -430,13 +399,14 @@ start_scd (ctrl_t ctrl)
       unlock_scd (ctrl, err);
       if (ctx)
        assuan_release (ctx);
-    } 
+    }
   else
     {
       ctrl->scd_local->ctx = ctx;
     }
-  if (!pth_mutex_release (&start_scd_lock))
-    log_error ("failed to release the start_scd lock: %s\n", strerror (errno));
+  rc = npth_mutex_unlock (&start_scd_lock);
+  if (rc)
+    log_error ("failed to release the start_scd lock: %s\n", strerror (rc));
   return err;
 }
 
@@ -455,35 +425,36 @@ agent_scd_check_running (void)
 void
 agent_scd_check_aliveness (void)
 {
-  pth_event_t evt;
   pid_t pid;
 #ifdef HAVE_W32_SYSTEM
   DWORD rc;
 #else
   int rc;
 #endif
+  struct timespec abstime;
+  int err;
 
   if (!primary_scd_ctx)
     return; /* No scdaemon running. */
 
   /* This is not a critical function so we use a short timeout while
      acquiring the lock.  */
-  evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
-  if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
+  npth_clock_gettime (&abstime);
+  abstime.tv_sec += 1;
+  err = npth_mutex_timedlock (&start_scd_lock, &abstime);
+  if (err)
     {
-      if (pth_event_occurred (evt))
+      if (err == ETIMEDOUT)
         {
           if (opt.verbose > 1)
             log_info ("failed to acquire the start_scd lock while"
-                      " doing an aliveness check: %s\n", "timeout");
+                      " doing an aliveness check: %s\n", strerror (err));
         }
       else
         log_error ("failed to acquire the start_scd lock while"
-                   " doing an aliveness check: %s\n", strerror (errno));
-      pth_event_free (evt, PTH_FREE_THIS);
+                   " doing an aliveness check: %s\n", strerror (err));
       return;
     }
-  pth_event_free (evt, PTH_FREE_THIS);
 
   if (primary_scd_ctx)
     {
@@ -519,7 +490,7 @@ agent_scd_check_aliveness (void)
                   sl->ctx = NULL;
                 }
             }
-          
+
           primary_scd_ctx = NULL;
           primary_scd_ctx_reusable = 0;
 
@@ -528,9 +499,10 @@ agent_scd_check_aliveness (void)
         }
     }
 
-  if (!pth_mutex_release (&start_scd_lock))
+  err = npth_mutex_unlock (&start_scd_lock);
+  if (err)
     log_error ("failed to release the start_scd lock while"
-               " doing the aliveness check: %s\n", strerror (errno));
+               " doing the aliveness check: %s\n", strerror (err));
 }
 
 
@@ -568,7 +540,7 @@ agent_reset_scd (ctrl_t ctrl)
             assuan_release (ctrl->scd_local->ctx);
           ctrl->scd_local->ctx = NULL;
         }
-      
+
       /* Remove the local context from our list and release it. */
       if (!scd_local_list)
         BUG ();
@@ -577,7 +549,7 @@ agent_reset_scd (ctrl_t ctrl)
       else
         {
           struct scd_local_s *sl;
-      
+
           for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
             if (sl->next_local == ctrl->scd_local)
               break;
@@ -617,7 +589,7 @@ learn_status_cb (void *opaque, const char *line)
     {
       parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
     }
-  
+
   return 0;
 }
 
@@ -684,7 +656,7 @@ get_serialno_cb (void *opaque, const char *line)
       memcpy (*serialno, line, n);
       (*serialno)[n] = 0;
     }
-  
+
   return 0;
 }
 
@@ -724,22 +696,21 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
     put_membuf (data, buffer, length);
   return 0;
 }
-  
+
 /* Handle the NEEDPIN inquiry. */
 static gpg_error_t
 inq_needpin (void *opaque, const char *line)
 {
   struct inq_needpin_s *parm = opaque;
+  const char *s;
   char *pin;
   size_t pinlen;
   int rc;
 
-  if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
+  parm->any_inq_seen = 1;
+  if ((s = has_leading_keyword (line, "NEEDPIN")))
     {
-      line += 7;
-      while (*line == ' ')
-        line++;
-      
+      line = s;
       pinlen = 90;
       pin = gcry_malloc_secure (pinlen);
       if (!pin)
@@ -750,17 +721,11 @@ inq_needpin (void *opaque, const char *line)
         rc = assuan_send_data (parm->ctx, pin, pinlen);
       xfree (pin);
     }
-  else if (!strncmp (line, "POPUPPINPADPROMPT", 17)
-           && (line[17] == ' ' || !line[17]))
+  else if ((s = has_leading_keyword (line, "POPUPPINPADPROMPT")))
     {
-      line += 17;
-      while (*line == ' ')
-        line++;
-      
-      rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
+      rc = parm->getpin_cb (parm->getpin_cb_arg, s, NULL, 1);
     }
-  else if (!strncmp (line, "DISMISSPINPADPROMPT", 19)
-           && (line[19] == ' ' || !line[19]))
+  else if ((s = has_leading_keyword (line, "DISMISSPINPADPROMPT")))
     {
       rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
     }
@@ -782,7 +747,7 @@ inq_needpin (void *opaque, const char *line)
         assuan_end_confidential (parm->passthru);
       if (!rc)
         {
-          if ((rest = (needrest 
+          if ((rest = (needrest
                        && !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL))))
             assuan_begin_confidential (parm->ctx);
           rc = assuan_send_data (parm->ctx, value, valuelen);
@@ -791,12 +756,12 @@ inq_needpin (void *opaque, const char *line)
           xfree (value);
         }
       else
-        log_error ("error forwarding inquiry `%s': %s\n", 
+        log_error ("error forwarding inquiry '%s': %s\n",
                    line, gpg_strerror (rc));
     }
   else
     {
-      log_error ("unsupported inquiry `%s'\n", line);
+      log_error ("unsupported inquiry '%s'\n", line);
       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
     }
 
@@ -804,13 +769,56 @@ inq_needpin (void *opaque, const char *line)
 }
 
 
+/* Helper returning a command option to describe the used hash
+   algorithm.  See scd/command.c:cmd_pksign.  */
+static const char *
+hash_algo_option (int algo)
+{
+  switch (algo)
+    {
+    case GCRY_MD_MD5   : return "--hash=md5";
+    case GCRY_MD_RMD160: return "--hash=rmd160";
+    case GCRY_MD_SHA1  : return "--hash=sha1";
+    case GCRY_MD_SHA224: return "--hash=sha224";
+    case GCRY_MD_SHA256: return "--hash=sha256";
+    case GCRY_MD_SHA384: return "--hash=sha384";
+    case GCRY_MD_SHA512: return "--hash=sha512";
+    default:             return "";
+    }
+}
+
+
+static gpg_error_t
+cancel_inquire (ctrl_t ctrl, gpg_error_t rc)
+{
+  gpg_error_t oldrc = rc;
+
+  /* The inquire callback was called and transact returned a
+     cancel error.  We assume that the inquired process sent a
+     CANCEL.  The passthrough code is not able to pass on the
+     CANCEL and thus scdaemon would stuck on this.  As a
+     workaround we send a CANCEL now.  */
+  rc = assuan_write_line (ctrl->scd_local->ctx, "CAN");
+  if (!rc) {
+    char *line;
+    size_t len;
+
+    rc = assuan_read_line (ctrl->scd_local->ctx, &line, &len);
+    if (!rc)
+      rc = oldrc;
+  }
+
+  return rc;
+}
 
-/* Create a signature using the current card */
+/* Create a signature using the current card.  MDALGO is either 0 or
+   gives the digest algorithm.  */
 int
 agent_card_pksign (ctrl_t ctrl,
                    const char *keyid,
                    int (*getpin_cb)(void *, const char *, char*, size_t),
                    void *getpin_cb_arg,
+                   int mdalgo,
                    const unsigned char *indata, size_t indatalen,
                    unsigned char **r_buf, size_t *r_buflen)
 {
@@ -818,9 +826,6 @@ agent_card_pksign (ctrl_t ctrl,
   char *p, line[ASSUAN_LINELENGTH];
   membuf_t data;
   struct inq_needpin_s inqparm;
-  size_t len;
-  unsigned char *sigbuf;
-  size_t sigbuflen;
 
   *r_buf = NULL;
   rc = start_scd (ctrl);
@@ -844,47 +849,62 @@ agent_card_pksign (ctrl_t ctrl,
   inqparm.getpin_cb = getpin_cb;
   inqparm.getpin_cb_arg = getpin_cb_arg;
   inqparm.passthru = 0;
-  snprintf (line, DIM(line)-1, 
-            ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
-  line[DIM(line)-1] = 0;
+  inqparm.any_inq_seen = 0;
+  if (ctrl->use_auth_call)
+    snprintf (line, sizeof line, "PKAUTH %s", keyid);
+  else
+    snprintf (line, sizeof line, "PKSIGN %s %s",
+              hash_algo_option (mdalgo), keyid);
   rc = assuan_transact (ctrl->scd_local->ctx, line,
                         membuf_data_cb, &data,
                         inq_needpin, &inqparm,
                         NULL, NULL);
+  if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
+       gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
+    rc = cancel_inquire (ctrl, rc);
+
   if (rc)
     {
+      size_t len;
+
       xfree (get_membuf (&data, &len));
       return unlock_scd (ctrl, rc);
     }
-  sigbuf = get_membuf (&data, &sigbuflen);
-
-  /* Create an S-expression from it which is formatted like this:
-     "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
-  *r_buflen = 21 + 11 + sigbuflen + 4;
-  p = xtrymalloc (*r_buflen);
-  *r_buf = (unsigned char*)p;
-  if (!p)
-    return unlock_scd (ctrl, out_of_core ());
-  p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
-  sprintf (p, "%u:", (unsigned int)sigbuflen);
-  p += strlen (p);
-  memcpy (p, sigbuf, sigbuflen);
-  p += sigbuflen;
-  strcpy (p, ")))");
-  xfree (sigbuf);
-
-  assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
+
+  *r_buf = get_membuf (&data, r_buflen);
   return unlock_scd (ctrl, 0);
 }
 
-/* Decipher INDATA using the current card. Note that the returned value is */
+
+
+\f
+/* Check whether there is any padding info from scdaemon.  */
+static gpg_error_t
+padding_info_cb (void *opaque, const char *line)
+{
+  int *r_padding = opaque;
+  const char *s;
+
+  if ((s=has_leading_keyword (line, "PADDING")))
+    {
+      *r_padding = atoi (s);
+    }
+
+  return 0;
+}
+
+
+/* Decipher INDATA using the current card.  Note that the returned
+   value is not an s-expression but the raw data as returned by
+   scdaemon.  The padding information is stored at R_PADDING with -1
+   for not known.  */
 int
 agent_card_pkdecrypt (ctrl_t ctrl,
                       const char *keyid,
                       int (*getpin_cb)(void *, const char *, char*, size_t),
                       void *getpin_cb_arg,
                       const unsigned char *indata, size_t indatalen,
-                      char **r_buf, size_t *r_buflen)
+                      char **r_buf, size_t *r_buflen, int *r_padding)
 {
   int rc, i;
   char *p, line[ASSUAN_LINELENGTH];
@@ -893,34 +913,45 @@ agent_card_pkdecrypt (ctrl_t ctrl,
   size_t len;
 
   *r_buf = NULL;
+  *r_padding = -1; /* Unknown.  */
   rc = start_scd (ctrl);
   if (rc)
     return rc;
 
   /* FIXME: use secure memory where appropriate */
-  if (indatalen*2 + 50 > DIM(line))
-    return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
 
-  sprintf (line, "SETDATA ");
-  p = line + strlen (line);
-  for (i=0; i < indatalen ; i++, p += 2 )
-    sprintf (p, "%02X", indata[i]);
-  rc = assuan_transact (ctrl->scd_local->ctx, line,
-                        NULL, NULL, NULL, NULL, NULL, NULL);
-  if (rc)
-    return unlock_scd (ctrl, rc);
+  for (len = 0; len < indatalen;)
+    {
+      p = stpcpy (line, "SETDATA ");
+      if (len)
+        p = stpcpy (p, "--append ");
+      for (i=0; len < indatalen && (i*2 < DIM(line)-50); i++, len++)
+        {
+          sprintf (p, "%02X", indata[len]);
+          p += 2;
+        }
+      rc = assuan_transact (ctrl->scd_local->ctx, line,
+                            NULL, NULL, NULL, NULL, NULL, NULL);
+      if (rc)
+        return unlock_scd (ctrl, rc);
+    }
 
   init_membuf (&data, 1024);
   inqparm.ctx = ctrl->scd_local->ctx;
   inqparm.getpin_cb = getpin_cb;
   inqparm.getpin_cb_arg = getpin_cb_arg;
   inqparm.passthru = 0;
+  inqparm.any_inq_seen = 0;
   snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
   line[DIM(line)-1] = 0;
   rc = assuan_transact (ctrl->scd_local->ctx, line,
                         membuf_data_cb, &data,
                         inq_needpin, &inqparm,
-                        NULL, NULL);
+                        padding_info_cb, r_padding);
+  if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
+       gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
+    rc = cancel_inquire (ctrl, rc);
+
   if (rc)
     {
       xfree (get_membuf (&data, &len));
@@ -1012,6 +1043,64 @@ agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
 }
 
 
+struct writekey_parm_s
+{
+  assuan_context_t ctx;
+  int (*getpin_cb)(void *, const char *, char*, size_t);
+  void *getpin_cb_arg;
+  assuan_context_t passthru;
+  int any_inq_seen;
+  /**/
+  const unsigned char *keydata;
+  size_t keydatalen;
+};
+
+/* Handle a KEYDATA inquiry.  Note, we only send the data,
+   assuan_transact takes care of flushing and writing the end */
+static gpg_error_t
+inq_writekey_parms (void *opaque, const char *line)
+{
+  struct writekey_parm_s *parm = opaque;
+
+  if (has_leading_keyword (line, "KEYDATA"))
+    return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
+  else
+    return inq_needpin (opaque, line);
+}
+
+
+int
+agent_card_writekey (ctrl_t ctrl,  int force, const char *serialno,
+                     const char *id, const char *keydata, size_t keydatalen,
+                     int (*getpin_cb)(void *, const char *, char*, size_t),
+                     void *getpin_cb_arg)
+{
+  int rc;
+  char line[ASSUAN_LINELENGTH];
+  struct writekey_parm_s parms;
+
+  (void)serialno;
+  rc = start_scd (ctrl);
+  if (rc)
+    return rc;
+
+  snprintf (line, DIM(line)-1, "WRITEKEY %s%s", force ? "--force " : "", id);
+  line[DIM(line)-1] = 0;
+  parms.ctx = ctrl->scd_local->ctx;
+  parms.getpin_cb = getpin_cb;
+  parms.getpin_cb_arg = getpin_cb_arg;
+  parms.passthru = 0;
+  parms.any_inq_seen = 0;
+  parms.keydata = keydata;
+  parms.keydatalen = keydatalen;
+
+  rc = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL,
+                        inq_writekey_parms, &parms, NULL, NULL);
+  if (parms.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
+                             gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
+    rc = cancel_inquire (ctrl, rc);
+  return unlock_scd (ctrl, rc);
+}
 \f
 /* Type used with the card_getattr_cb.  */
 struct card_getattr_parm_s {
@@ -1044,7 +1133,7 @@ card_getattr_cb (void *opaque, const char *line)
       if (!parm->data)
         parm->error = errno;
     }
-  
+
   return 0;
 }
 
@@ -1072,7 +1161,7 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
   /* We assume that NAME does not need escaping. */
   if (8 + strlen (name) > DIM(line)-1)
     return gpg_error (GPG_ERR_TOO_LARGE);
-  stpcpy (stpcpy (line, "GETATTR "), name); 
+  stpcpy (stpcpy (line, "GETATTR "), name);
 
   err = start_scd (ctrl);
   if (err)
@@ -1083,10 +1172,10 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
                          card_getattr_cb, &parm);
   if (!err && parm.error)
     err = gpg_error_from_errno (parm.error);
-  
+
   if (!err && !parm.data)
     err = gpg_error (GPG_ERR_NO_DATA);
-  
+
   if (!err)
     *result = parm.data;
   else
@@ -1105,16 +1194,28 @@ pass_status_thru (void *opaque, const char *line)
   char keyword[200];
   int i;
 
-  for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
-    keyword[i] = *line;
-  keyword[i] = 0;
-  /* truncate any remaining keyword stuff. */
-  for (; *line && !spacep (line); line++)
-    ;
-  while (spacep (line))
-    line++;
+  if (line[0] == '#' && (!line[1] || spacep (line+1)))
+    {
+      /* We are called in convey comments mode.  Now, if we see a
+         comment marker as keyword we forward the line verbatim to the
+         the caller.  This way the comment lines from scdaemon won't
+         appear as status lines with keyword '#'.  */
+      assuan_write_line (ctx, line);
+    }
+  else
+    {
+      for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
+        keyword[i] = *line;
+      keyword[i] = 0;
 
-  assuan_write_status (ctx, keyword, line);
+      /* Truncate any remaining keyword stuff.  */
+      for (; *line && !spacep (line); line++)
+        ;
+      while (spacep (line))
+        line++;
+
+      assuan_write_status (ctx, keyword, line);
+    }
   return 0;
 }
 
@@ -1149,12 +1250,16 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
   inqparm.getpin_cb = getpin_cb;
   inqparm.getpin_cb_arg = getpin_cb_arg;
   inqparm.passthru = assuan_context;
+  inqparm.any_inq_seen = 0;
   saveflag = assuan_get_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS);
   assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, 1);
   rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
                         pass_data_thru, assuan_context,
                         inq_needpin, &inqparm,
                         pass_status_thru, assuan_context);
+  if (inqparm.any_inq_seen && gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)
+    rc = cancel_inquire (ctrl, rc);
+
   assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, saveflag);
   if (rc)
     {
@@ -1163,5 +1268,3 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
 
   return unlock_scd (ctrl, 0);
 }
-
-
index 0a12bb6..493011c 100644 (file)
@@ -1,6 +1,6 @@
 /* command-ssh.c - gpg-agent's ssh-agent emulation layer
- * Copyright (C) 2004, 2005, 2006, 2009, 2012 Free Software Foundation, Inc.
- * Copyright (C) 2013 Werner Koch
+ * Copyright (C) 2004-2006, 2009, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2004-2006, 2009, 2012-2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -43,7 +43,6 @@
 
 #include "agent.h"
 
-#include "estream.h"
 #include "i18n.h"
 #include "../common/ssh-utils.h"
 
@@ -75,6 +74,7 @@
 #define SSH_DSA_SIGNATURE_ELEMS    2
 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
 #define SPEC_FLAG_IS_ECDSA    (1 << 1)
+#define SPEC_FLAG_IS_EdDSA    (1 << 2)  /*(lowercase 'd' on purpose.)*/
 
 /* The name of the control file.  */
 #define SSH_CONTROL_FILE_NAME "sshcontrol"
@@ -139,7 +139,7 @@ typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
    functions are necessary.  */
 typedef gpg_error_t (*ssh_signature_encoder_t) (ssh_key_type_spec_t *spec,
                                                 estream_t signature_blob,
-                                               gcry_mpi_t *mpis);
+                                               gcry_sexp_t sig);
 
 /* Type, which is used for boundling all the algorithm specific
    information together in a single object.  */
@@ -148,6 +148,9 @@ struct ssh_key_type_spec
   /* Algorithm identifier as used by OpenSSH.  */
   const char *ssh_identifier;
 
+  /* Human readable name of the algorithm.  */
+  const char *name;
+
   /* Algorithm identifier as used by GnuPG.  */
   const char *identifier;
 
@@ -230,13 +233,17 @@ static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
 static gpg_error_t ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
                                               estream_t signature_blob,
-                                              gcry_mpi_t *mpis);
+                                              gcry_sexp_t signature);
 static gpg_error_t ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
                                               estream_t signature_blob,
-                                              gcry_mpi_t *mpis);
+                                              gcry_sexp_t signature);
 static gpg_error_t ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
                                                 estream_t signature_blob,
-                                                gcry_mpi_t *mpis);
+                                                gcry_sexp_t signature);
+static gpg_error_t ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
+                                                estream_t signature_blob,
+                                                gcry_sexp_t signature);
+static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
 
 
 
@@ -267,31 +274,35 @@ static ssh_request_spec_t request_specs[] =
 static ssh_key_type_spec_t ssh_key_types[] =
   {
     {
-      "ssh-rsa", "rsa", "nedupq", "en",   "s",  "nedpqu",
+      "ssh-ed25519", "Ed25519", "ecc", "qd",  "q", "rs", "qd",
+      NULL,                 ssh_signature_encoder_eddsa,
+      "Ed25519", 0,               SPEC_FLAG_IS_EdDSA
+    },
+    {
+      "ssh-rsa", "RSA", "rsa", "nedupq", "en",   "s",  "nedpqu",
       ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
-      NULL, 0, SPEC_FLAG_USE_PKCS1V2
+      NULL, 0,                    SPEC_FLAG_USE_PKCS1V2
     },
     {
-      "ssh-dss", "dsa", "pqgyx",  "pqgy", "rs", "pqgyx",
+      "ssh-dss", "DSA", "dsa", "pqgyx",  "pqgy", "rs", "pqgyx",
       NULL,                 ssh_signature_encoder_dsa,
       NULL, 0, 0
     },
     {
-      "ecdsa-sha2-nistp256", "ecdsa", "qd",  "q", "rs", "qd",
+      "ecdsa-sha2-nistp256", "ECDSA", "ecdsa", "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
       "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA
     },
     {
-      "ecdsa-sha2-nistp384", "ecdsa", "qd",  "q", "rs", "qd",
+      "ecdsa-sha2-nistp384", "ECDSA", "ecdsa", "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
       "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA
     },
     {
-      "ecdsa-sha2-nistp521", "ecdsa", "qd",  "q", "rs", "qd",
+      "ecdsa-sha2-nistp521", "ECDSA", "ecdsa", "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
       "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA
     }
-
   };
 
 \f
@@ -337,7 +348,20 @@ make_cstring (const char *data, size_t data_n)
   return s;
 }
 
+/* Lookup the ssh-identifier for the ECC curve CURVE_NAME.  Returns
+   NULL if not found.  */
+static const char *
+ssh_identifier_from_curve_name (const char *curve_name)
+{
+  int i;
+
+  for (i = 0; i < DIM (ssh_key_types); i++)
+    if (ssh_key_types[i].curve_name
+        && !strcmp (ssh_key_types[i].curve_name, curve_name))
+      return ssh_key_types[i].ssh_identifier;
 
+  return NULL;
+}
 
 
 /*
@@ -460,6 +484,34 @@ stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
   return err;
 }
 
+/* Skip over SIZE bytes from STREAM.  */
+static gpg_error_t
+stream_read_skip (estream_t stream, size_t size)
+{
+  char buffer[128];
+  size_t bytes_to_read, bytes_read;
+  int ret;
+
+  do
+    {
+      bytes_to_read = size;
+      if (bytes_to_read > sizeof buffer)
+        bytes_to_read = sizeof buffer;
+
+      ret = es_read (stream, buffer, bytes_to_read, &bytes_read);
+      if (ret)
+        return gpg_error_from_syserror ();
+      else if (bytes_read != bytes_to_read)
+        return gpg_error (GPG_ERR_EOF);
+      else
+        size -= bytes_to_read;
+    }
+  while (size);
+
+  return 0;
+}
+
+
 /* Write SIZE bytes from BUFFER to STREAM.  */
 static gpg_error_t
 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
@@ -488,6 +540,9 @@ stream_read_string (estream_t stream, unsigned int secure,
   unsigned char *buffer = NULL;
   u32 length = 0;
 
+  if (string_size)
+    *string_size = 0;
+
   /* Read string length.  */
   err = stream_read_uint32 (stream, &length);
   if (err)
@@ -523,21 +578,68 @@ stream_read_string (estream_t stream, unsigned int secure,
   return err;
 }
 
-/* Read a C-string from STREAM, store copy in STRING.  */
+
+/* Read a binary string from STREAM and store it as an opaque MPI at
+   R_MPI.  Depending on SECURE use secure memory.  If the string is
+   too large for key material return an error.  */
 static gpg_error_t
-stream_read_cstring (estream_t stream, char **string)
+stream_read_blob (estream_t stream, unsigned int secure, gcry_mpi_t *r_mpi)
 {
-  unsigned char *buffer;
   gpg_error_t err;
+  unsigned char *buffer = NULL;
+  u32 length = 0;
 
-  err = stream_read_string (stream, 0, &buffer, NULL);
+  *r_mpi = NULL;
+
+  /* Read string length.  */
+  err = stream_read_uint32 (stream, &length);
   if (err)
-    goto out;
+    goto leave;
+
+  /* To avoid excessive use of secure memory we check that an MPI is
+     not too large. */
+  if (length > (4096/8) + 8)
+    {
+      log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
+      err = GPG_ERR_TOO_LARGE;
+      goto leave;
+    }
 
-  *string = (char *) buffer;
+  /* Allocate space.  */
+  if (secure)
+    buffer = xtrymalloc_secure (length? length:1);
+  else
+    buffer = xtrymalloc (length?length:1);
+  if (!buffer)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
 
- out:
+  /* Read data.  */
+  err = stream_read_data (stream, buffer, length);
+  if (err)
+    goto leave;
+
+  *r_mpi = gcry_mpi_set_opaque (NULL, buffer, 8*length);
+  buffer = NULL;
+
+ leave:
+  xfree (buffer);
+  return err;
+}
+
+
+/* Read a C-string from STREAM, store copy in STRING.  */
+static gpg_error_t
+stream_read_cstring (estream_t stream, char **string)
+{
+  gpg_error_t err;
+  unsigned char *buffer;
 
+  err = stream_read_string (stream, 0, &buffer, NULL);
+  if (!err)
+    *string = (char *)buffer;
   return err;
 }
 
@@ -633,6 +735,7 @@ stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
   return err;
 }
 
+
 /* Copy data from SRC to DST until EOF is reached.  */
 static gpg_error_t
 stream_copy (estream_t dst, estream_t src)
@@ -751,7 +854,7 @@ open_control_file (ssh_control_file_t *r_cf, int append)
       err = gpg_error_from_syserror ();
       goto leave;
     }
-  /* FIXME: With "a+" we are not able to check whether this will will
+  /* FIXME: With "a+" we are not able to check whether this will
      be created and thus the blurb needs to be written first.  */
   cf->fp = fopen (cf->fname, append? "a+":"r");
   if (!cf->fp && errno == ENOENT)
@@ -760,7 +863,7 @@ open_control_file (ssh_control_file_t *r_cf, int append)
       if (!stream)
         {
           err = gpg_error_from_syserror ();
-          log_error (_("can't create `%s': %s\n"),
+          log_error (_("can't create '%s': %s\n"),
                      cf->fname, gpg_strerror (err));
           goto leave;
         }
@@ -772,7 +875,7 @@ open_control_file (ssh_control_file_t *r_cf, int append)
   if (!cf->fp)
     {
       err = gpg_error_from_syserror ();
-      log_error (_("can't open `%s': %s\n"),
+      log_error (_("can't open '%s': %s\n"),
                  cf->fname, gpg_strerror (err));
       goto leave;
     }
@@ -928,7 +1031,8 @@ search_control_file (ssh_control_file_t cf, const char *hexgrip,
 
   assert (strlen (hexgrip) == 40 );
 
-  *r_disabled = 0;
+  if (r_disabled)
+    *r_disabled = 0;
   if (r_ttl)
     *r_ttl = 0;
   if (r_confirm)
@@ -944,7 +1048,8 @@ search_control_file (ssh_control_file_t cf, const char *hexgrip,
     }
   if (!err)
     {
-      *r_disabled = cf->item.disabled;
+      if (r_disabled)
+        *r_disabled = cf->item.disabled;
       if (r_ttl)
         *r_ttl = cf->item.ttl;
       if (r_confirm)
@@ -961,7 +1066,8 @@ search_control_file (ssh_control_file_t cf, const char *hexgrip,
    general used to add a key received through the ssh-add function.
    We can assume that the user wants to allow ssh using this key. */
 static gpg_error_t
-add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
+add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+                   const char *hexgrip, const char *fmtfpr,
                    int ttl, int confirm)
 {
   gpg_error_t err;
@@ -984,9 +1090,10 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
          opened in append mode, we simply need to write to it.  */
       tp = localtime (&atime);
       fprintf (cf->fp,
-               ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
-                "# Fingerprint:  %s\n"
+               ("# %s key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
+                "# MD5 Fingerprint:  %s\n"
                 "%s %d%s\n"),
+               spec->name,
                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
                tp->tm_hour, tp->tm_min, tp->tm_sec,
                fmtfpr, hexgrip, ttl, confirm? " confirm":"");
@@ -1113,7 +1220,7 @@ ssh_search_control_file (ssh_control_file_t cf,
   /* We need to make sure that HEXGRIP is all uppercase.  The easiest
      way to do this and also check its length is by copying to a
      second buffer. */
-  for (i=0, s=hexgrip; i < 40 && *s; s++, i++)
+  for (i=0, s=hexgrip; i < 40; s++, i++)
     uphexgrip[i] = *s >= 'a'? (*s & 0xdf): *s;
   uphexgrip[i] = 0;
   if (i != 40)
@@ -1243,15 +1350,63 @@ ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
 /* Signature encoder function for RSA.  */
 static gpg_error_t
 ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
-                           estream_t signature_blob, gcry_mpi_t *mpis)
+                           estream_t signature_blob,
+                           gcry_sexp_t s_signature)
 {
+  gpg_error_t err = 0;
+  gcry_sexp_t valuelist = NULL;
+  gcry_sexp_t sublist = NULL;
+  gcry_mpi_t sig_value = NULL;
+  gcry_mpi_t *mpis = NULL;
+  const char *elems;
+  size_t elems_n;
+  int i;
+
   unsigned char *data;
   size_t data_n;
-  gpg_error_t err;
   gcry_mpi_t s;
 
-  (void)spec;
+  valuelist = gcry_sexp_nth (s_signature, 1);
+  if (!valuelist)
+    {
+      err = gpg_error (GPG_ERR_INV_SEXP);
+      goto out;
+    }
+
+  elems = spec->elems_signature;
+  elems_n = strlen (elems);
+
+  mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
+  if (!mpis)
+    {
+      err = gpg_error_from_syserror ();
+      goto out;
+    }
+
+  for (i = 0; i < elems_n; i++)
+    {
+      sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
+      if (!sublist)
+       {
+         err = gpg_error (GPG_ERR_INV_SEXP);
+         break;
+       }
+
+      sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
+      if (!sig_value)
+       {
+         err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
+         break;
+       }
+      gcry_sexp_release (sublist);
+      sublist = NULL;
+
+      mpis[i] = sig_value;
+    }
+  if (err)
+    goto out;
 
+  /* RSA specific */
   s = mpis[0];
 
   err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
@@ -1262,7 +1417,9 @@ ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
   xfree (data);
 
  out:
-
+  gcry_sexp_release (valuelist);
+  gcry_sexp_release (sublist);
+  mpint_list_free (mpis);
   return err;
 }
 
@@ -1270,17 +1427,63 @@ ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
 /* Signature encoder function for DSA.  */
 static gpg_error_t
 ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
-                           estream_t signature_blob, gcry_mpi_t *mpis)
+                           estream_t signature_blob,
+                           gcry_sexp_t s_signature)
 {
+  gpg_error_t err = 0;
+  gcry_sexp_t valuelist = NULL;
+  gcry_sexp_t sublist = NULL;
+  gcry_mpi_t sig_value = NULL;
+  gcry_mpi_t *mpis = NULL;
+  const char *elems;
+  size_t elems_n;
+  int i;
+
   unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
-  unsigned char *data;
+  unsigned char *data = NULL;
   size_t data_n;
-  gpg_error_t err;
-  int i;
 
-  (void)spec;
+  valuelist = gcry_sexp_nth (s_signature, 1);
+  if (!valuelist)
+    {
+      err = gpg_error (GPG_ERR_INV_SEXP);
+      goto out;
+    }
+
+  elems = spec->elems_signature;
+  elems_n = strlen (elems);
+
+  mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
+  if (!mpis)
+    {
+      err = gpg_error_from_syserror ();
+      goto out;
+    }
+
+  for (i = 0; i < elems_n; i++)
+    {
+      sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
+      if (!sublist)
+       {
+         err = gpg_error (GPG_ERR_INV_SEXP);
+         break;
+       }
+
+      sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
+      if (!sig_value)
+       {
+         err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
+         break;
+       }
+      gcry_sexp_release (sublist);
+      sublist = NULL;
+
+      mpis[i] = sig_value;
+    }
+  if (err)
+    goto out;
 
-  data = NULL;
+  /* DSA specific code.  */
 
   /* FIXME: Why this complicated code?  Why collecting boths mpis in a
      buffer instead of writing them out one after the other?  */
@@ -1310,9 +1513,10 @@ ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
   err = stream_write_string (signature_blob, buffer, sizeof (buffer));
 
  out:
-
   xfree (data);
-
+  gcry_sexp_release (valuelist);
+  gcry_sexp_release (sublist);
+  mpint_list_free (mpis);
   return err;
 }
 
@@ -1320,15 +1524,62 @@ ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
 /* Signature encoder function for ECDSA.  */
 static gpg_error_t
 ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
-                             estream_t stream, gcry_mpi_t *mpis)
+                             estream_t stream, gcry_sexp_t s_signature)
 {
+  gpg_error_t err = 0;
+  gcry_sexp_t valuelist = NULL;
+  gcry_sexp_t sublist = NULL;
+  gcry_mpi_t sig_value = NULL;
+  gcry_mpi_t *mpis = NULL;
+  const char *elems;
+  size_t elems_n;
+  int i;
+
   unsigned char *data[2] = {NULL, NULL};
   size_t data_n[2];
   size_t innerlen;
-  gpg_error_t err;
-  int i;
 
-  (void)spec;
+  valuelist = gcry_sexp_nth (s_signature, 1);
+  if (!valuelist)
+    {
+      err = gpg_error (GPG_ERR_INV_SEXP);
+      goto out;
+    }
+
+  elems = spec->elems_signature;
+  elems_n = strlen (elems);
+
+  mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
+  if (!mpis)
+    {
+      err = gpg_error_from_syserror ();
+      goto out;
+    }
+
+  for (i = 0; i < elems_n; i++)
+    {
+      sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
+      if (!sublist)
+       {
+         err = gpg_error (GPG_ERR_INV_SEXP);
+         break;
+       }
+
+      sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
+      if (!sig_value)
+       {
+         err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
+         break;
+       }
+      gcry_sexp_release (sublist);
+      sublist = NULL;
+
+      mpis[i] = sig_value;
+    }
+  if (err)
+    goto out;
+
+  /* ECDSA specific */
 
   innerlen = 0;
   for (i = 0; i < DIM(data); i++)
@@ -1353,103 +1604,212 @@ ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
  out:
   for (i = 0; i < DIM(data); i++)
     xfree (data[i]);
+  gcry_sexp_release (valuelist);
+  gcry_sexp_release (sublist);
+  mpint_list_free (mpis);
   return err;
 }
 
 
-/*
-   S-Expressions.
- */
-
-
-/* This function constructs a new S-Expression for the key identified
-   by the KEY_SPEC, SECRET, CURVE_NAME, MPIS, and COMMENT, which is to
-   be stored at R_SEXP.  Returns an error code.  */
+/* Signature encoder function for EdDSA.  */
 static gpg_error_t
-sexp_key_construct (gcry_sexp_t *r_sexp,
-                   ssh_key_type_spec_t key_spec, int secret,
-                   const char *curve_name, gcry_mpi_t *mpis,
-                    const char *comment)
+ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
+                             estream_t stream, gcry_sexp_t s_signature)
 {
-  const char *key_identifier[] = { "public-key", "private-key" };
-  gpg_error_t err;
-  gcry_sexp_t sexp_new = NULL;
-  void *formatbuf = NULL;
-  void **arg_list = NULL;
-  int arg_idx;
-  estream_t format;
+  gpg_error_t err = 0;
+  gcry_sexp_t valuelist = NULL;
+  gcry_sexp_t sublist = NULL;
   const char *elems;
   size_t elems_n;
-  unsigned int i, j;
+  int i;
 
-  if (secret)
-    elems = key_spec.elems_sexp_order;
-  else
-    elems = key_spec.elems_key_public;
-  elems_n = strlen (elems);
+  unsigned char *data[2] = {NULL, NULL};
+  size_t data_n[2];
+  size_t totallen = 0;
 
-  format = es_fopenmem (0, "a+b");
-  if (!format)
+  valuelist = gcry_sexp_nth (s_signature, 1);
+  if (!valuelist)
     {
-      err = gpg_error_from_syserror ();
+      err = gpg_error (GPG_ERR_INV_SEXP);
       goto out;
     }
 
-  /* Key identifier, algorithm identifier, mpis, comment, and a NULL
-     as a safeguard. */
-  arg_list = xtrymalloc (sizeof (*arg_list) * (2 + 1 + elems_n + 1 + 1));
-  if (!arg_list)
+  elems = spec->elems_signature;
+  elems_n = strlen (elems);
+
+  if (elems_n != DIM(data))
     {
-      err = gpg_error_from_syserror ();
+      err = gpg_error (GPG_ERR_INV_SEXP);
       goto out;
     }
-  arg_idx = 0;
 
-  es_fputs ("(%s(%s", format);
-  arg_list[arg_idx++] = &key_identifier[secret];
-  arg_list[arg_idx++] = &key_spec.identifier;
-  if (curve_name)
+  for (i = 0; i < DIM(data); i++)
     {
-      es_fputs ("(curve%s)", format);
-      arg_list[arg_idx++] = &curve_name;
-    }
+      sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
+      if (!sublist)
+       {
+         err = gpg_error (GPG_ERR_INV_SEXP);
+         break;
+       }
 
-  for (i = 0; i < elems_n; i++)
-    {
-      es_fprintf (format, "(%c%%m)", elems[i]);
-      if (secret)
+      data[i] = gcry_sexp_nth_buffer (sublist, 1, &data_n[i]);
+      if (!data[i])
        {
-         for (j = 0; j < elems_n; j++)
-           if (key_spec.elems_key_secret[j] == elems[i])
-             break;
+         err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
+         break;
        }
-      else
-       j = i;
-      arg_list[arg_idx++] = &mpis[j];
+      totallen += data_n[i];
+      gcry_sexp_release (sublist);
+      sublist = NULL;
     }
-  es_fputs (")(comment%s))", format);
-  arg_list[arg_idx++] = &comment;
-  arg_list[arg_idx] = NULL;
+  if (err)
+    goto out;
 
-  es_putc (0, format);
-  if (es_ferror (format))
+  err = stream_write_uint32 (stream, totallen);
+  if (err)
+    goto out;
+
+  for (i = 0; i < DIM(data); i++)
     {
-      err = gpg_error_from_syserror ();
-      goto out;
+      err = stream_write_data (stream, data[i], data_n[i]);
+      if (err)
+        goto out;
     }
-  if (es_fclose_snatch (format, &formatbuf, NULL))
+
+ out:
+  for (i = 0; i < DIM(data); i++)
+    xfree (data[i]);
+  gcry_sexp_release (valuelist);
+  gcry_sexp_release (sublist);
+  return err;
+}
+
+
+/*
+   S-Expressions.
+ */
+
+
+/* This function constructs a new S-Expression for the key identified
+   by the KEY_SPEC, SECRET, CURVE_NAME, MPIS, and COMMENT, which is to
+   be stored at R_SEXP.  Returns an error code.  */
+static gpg_error_t
+sexp_key_construct (gcry_sexp_t *r_sexp,
+                   ssh_key_type_spec_t key_spec, int secret,
+                   const char *curve_name, gcry_mpi_t *mpis,
+                    const char *comment)
+{
+  gpg_error_t err;
+  gcry_sexp_t sexp_new = NULL;
+  void *formatbuf = NULL;
+  void **arg_list = NULL;
+  estream_t format = NULL;
+
+
+  if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
     {
-      err = gpg_error_from_syserror ();
-      goto out;
+      /* It is much easier and more readable to use a separate code
+         path for EdDSA.  */
+      if (!curve_name)
+        err = gpg_error (GPG_ERR_INV_CURVE);
+      else if (!mpis[0] || !gcry_mpi_get_flag (mpis[0], GCRYMPI_FLAG_OPAQUE))
+        err = gpg_error (GPG_ERR_BAD_PUBKEY);
+      else if (secret
+               && (!mpis[1]
+                   || !gcry_mpi_get_flag (mpis[1], GCRYMPI_FLAG_OPAQUE)))
+        err = gpg_error (GPG_ERR_BAD_SECKEY);
+      else if (secret)
+        err = gcry_sexp_build (&sexp_new, NULL,
+                               "(private-key(ecc(curve %s)"
+                               "(flags eddsa)(q %m)(d %m))"
+                               "(comment%s))",
+                               curve_name,
+                               mpis[0], mpis[1],
+                               comment? comment:"");
+      else
+        err = gcry_sexp_build (&sexp_new, NULL,
+                               "(public-key(ecc(curve %s)"
+                               "(flags eddsa)(q %m))"
+                               "(comment%s))",
+                               curve_name,
+                               mpis[0],
+                               comment? comment:"");
     }
-  format = NULL;
+  else
+    {
+      const char *key_identifier[] = { "public-key", "private-key" };
+      int arg_idx;
+      const char *elems;
+      size_t elems_n;
+      unsigned int i, j;
 
-  err = gcry_sexp_build_array (&sexp_new, NULL, formatbuf, arg_list);
-  if (err)
-    goto out;
+      if (secret)
+        elems = key_spec.elems_sexp_order;
+      else
+        elems = key_spec.elems_key_public;
+      elems_n = strlen (elems);
 
-  *r_sexp = sexp_new;
-  err = 0;
+      format = es_fopenmem (0, "a+b");
+      if (!format)
+        {
+          err = gpg_error_from_syserror ();
+          goto out;
+        }
+
+      /* Key identifier, algorithm identifier, mpis, comment, and a NULL
+         as a safeguard. */
+      arg_list = xtrymalloc (sizeof (*arg_list) * (2 + 1 + elems_n + 1 + 1));
+      if (!arg_list)
+        {
+          err = gpg_error_from_syserror ();
+          goto out;
+        }
+      arg_idx = 0;
+
+      es_fputs ("(%s(%s", format);
+      arg_list[arg_idx++] = &key_identifier[secret];
+      arg_list[arg_idx++] = &key_spec.identifier;
+      if (curve_name)
+        {
+          es_fputs ("(curve%s)", format);
+          arg_list[arg_idx++] = &curve_name;
+        }
+
+      for (i = 0; i < elems_n; i++)
+        {
+          es_fprintf (format, "(%c%%m)", elems[i]);
+          if (secret)
+            {
+              for (j = 0; j < elems_n; j++)
+                if (key_spec.elems_key_secret[j] == elems[i])
+                  break;
+            }
+          else
+            j = i;
+          arg_list[arg_idx++] = &mpis[j];
+        }
+      es_fputs (")(comment%s))", format);
+      arg_list[arg_idx++] = &comment;
+      arg_list[arg_idx] = NULL;
+
+      es_putc (0, format);
+      if (es_ferror (format))
+        {
+          err = gpg_error_from_syserror ();
+          goto out;
+        }
+      if (es_fclose_snatch (format, &formatbuf, NULL))
+        {
+          err = gpg_error_from_syserror ();
+          goto out;
+        }
+      format = NULL;
+
+      err = gcry_sexp_build_array (&sexp_new, NULL, formatbuf, arg_list);
+    }
+
+  if (!err)
+    *r_sexp = sexp_new;
 
  out:
   es_fclose (format);
@@ -1460,96 +1820,66 @@ sexp_key_construct (gcry_sexp_t *r_sexp,
 }
 
 
-/* This functions breaks up the key contained in the S-Expression SEXP
-   according to KEY_SPEC.  The MPIs are bundled in a newly create
-   list, which is to be stored in MPIS; a newly allocated string
-   holding the curve name may be stored at RCURVE, and a comment will
-   be stored at COMMENT; SECRET will be filled with a boolean flag
-   specifying what kind of key it is.  Returns an error code.  */
+/* This function extracts the key from the s-expression SEXP according
+   to KEY_SPEC and stores it in ssh format at (R_BLOB, R_BLOBLEN).  If
+   WITH_SECRET is true, the secret key parts are also extracted if
+   possible.  Returns 0 on success or an error code.  Note that data
+   stored at R_BLOB must be freed using es_free!  */
 static gpg_error_t
-sexp_key_extract (gcry_sexp_t sexp,
-                 ssh_key_type_spec_t key_spec, int *secret,
-                 gcry_mpi_t **mpis, char **r_curve, char **comment)
+ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
+                 ssh_key_type_spec_t key_spec,
+                 void **r_blob, size_t *r_blob_size)
 {
   gpg_error_t err = 0;
   gcry_sexp_t value_list = NULL;
   gcry_sexp_t value_pair = NULL;
-  gcry_sexp_t comment_list = NULL;
-  unsigned int i;
-  char *comment_new = NULL;
-  const char *data;
-  size_t data_n;
-  int is_secret;
-  size_t elems_n;
-  const char *elems;
-  gcry_mpi_t *mpis_new = NULL;
-  gcry_mpi_t mpi;
   char *curve_name = NULL;
+  estream_t stream = NULL;
+  void *blob = NULL;
+  size_t blob_size;
+  const char *elems, *p_elems;
+  const char *data;
+  size_t datalen;
 
-  data = gcry_sexp_nth_data (sexp, 0, &data_n);
-  if (! data)
+  *r_blob = NULL;
+  *r_blob_size = 0;
+
+  stream = es_fopenmem (0, "r+b");
+  if (!stream)
     {
-      err = gpg_error (GPG_ERR_INV_SEXP);
+      err = gpg_error_from_syserror ();
       goto out;
     }
 
-  if ((data_n == 10 && !strncmp (data, "public-key", 10))
-      || (data_n == 21 && !strncmp (data, "protected-private-key", 21))
-      || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20)))
-    {
-      is_secret = 0;
-      elems = key_spec.elems_key_public;
-    }
-  else if (data_n == 11 && !strncmp (data, "private-key", 11))
-    {
-      is_secret = 1;
-      elems = key_spec.elems_key_secret;
-    }
-  else
+  /* Get the type of the key extpression.  */
+  data = gcry_sexp_nth_data (sexp, 0, &datalen);
+  if (!data)
     {
       err = gpg_error (GPG_ERR_INV_SEXP);
       goto out;
     }
 
-  elems_n = strlen (elems);
-  mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new );
-  if (!mpis_new)
+  if ((datalen == 10 && !strncmp (data, "public-key", 10))
+      || (datalen == 21 && !strncmp (data, "protected-private-key", 21))
+      || (datalen == 20 && !strncmp (data, "shadowed-private-key", 20)))
+    elems = key_spec.elems_key_public;
+  else if (datalen == 11 && !strncmp (data, "private-key", 11))
+    elems = with_secret? key_spec.elems_key_secret : key_spec.elems_key_public;
+  else
     {
-      err = gpg_error_from_syserror ();
+      err = gpg_error (GPG_ERR_INV_SEXP);
       goto out;
     }
 
+  /* Get the algorithm identifier.  */
   value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
-  if (! value_list)
+  if (!value_list)
     {
       err = gpg_error (GPG_ERR_INV_SEXP);
       goto out;
     }
 
-  for (i = 0; i < elems_n; i++)
-    {
-      value_pair = gcry_sexp_find_token (value_list, elems + i, 1);
-      if (! value_pair)
-       {
-         err = gpg_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      /* Note that we need to use STD format; i.e. prepend a 0x00 to
-         indicate a positive number if the high bit is set. */
-      mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
-      if (! mpi)
-       {
-         err = gpg_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-      mpis_new[i] = mpi;
-      gcry_sexp_release (value_pair);
-      value_pair = NULL;
-    }
-  if (err)
-    goto out;
-
+  /* Write the ssh algorithm identifier.  */
   if ((key_spec.flags & SPEC_FLAG_IS_ECDSA))
     {
       /* Parse the "curve" parameter.  We currently expect the curve
@@ -1557,7 +1887,9 @@ sexp_key_extract (gcry_sexp_t sexp,
          easily be changed but then we need to find the curve name
          from the parameters using gcry_pk_get_curve.  */
       const char *mapped;
+      const char *sshname;
 
+      gcry_sexp_release (value_pair);
       value_pair = gcry_sexp_find_token (value_list, "curve", 5);
       if (!value_pair)
        {
@@ -1591,48 +1923,87 @@ sexp_key_extract (gcry_sexp_t sexp,
               goto out;
             }
         }
-      gcry_sexp_release (value_pair);
-      value_pair = NULL;
-    }
 
-  /* We do not require a comment sublist to be present here.  */
-  data = NULL;
-  data_n = 0;
+      sshname = ssh_identifier_from_curve_name (curve_name);
+      if (!sshname)
+        {
+          err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
+          goto out;
+        }
+      err = stream_write_cstring (stream, sshname);
+      if (err)
+        goto out;
+      err = stream_write_cstring (stream, curve_name);
+      if (err)
+        goto out;
+    }
+  else
+    {
+      /* Note: This is also used for EdDSA.  */
+      err = stream_write_cstring (stream, key_spec.ssh_identifier);
+      if (err)
+        goto out;
+    }
 
-  comment_list = gcry_sexp_find_token (sexp, "comment", 0);
-  if (comment_list)
-    data = gcry_sexp_nth_data (comment_list, 1, &data_n);
-  if (! data)
+  /* Write the parameters.  */
+  for (p_elems = elems; *p_elems; p_elems++)
     {
-      data = "(none)";
-      data_n = 6;
+      gcry_sexp_release (value_pair);
+      value_pair = gcry_sexp_find_token (value_list, p_elems, 1);
+      if (!value_pair)
+       {
+         err = gpg_error (GPG_ERR_INV_SEXP);
+         goto out;
+       }
+      if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
+        {
+
+          data = gcry_sexp_nth_data (value_pair, 1, &datalen);
+          if (!data)
+            {
+              err = gpg_error (GPG_ERR_INV_SEXP);
+              goto out;
+            }
+          err = stream_write_string (stream, data, datalen);
+          if (err)
+            goto out;
+        }
+      else
+        {
+          gcry_mpi_t mpi;
+
+          /* Note that we need to use STD format; i.e. prepend a 0x00
+             to indicate a positive number if the high bit is set. */
+          mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
+          if (!mpi)
+            {
+              err = gpg_error (GPG_ERR_INV_SEXP);
+              goto out;
+            }
+          err = stream_write_mpi (stream, mpi);
+          gcry_mpi_release (mpi);
+          if (err)
+            goto out;
+        }
     }
 
-  comment_new = make_cstring (data, data_n);
-  if (! comment_new)
+  if (es_fclose_snatch (stream, &blob, &blob_size))
     {
       err = gpg_error_from_syserror ();
       goto out;
     }
+  stream = NULL;
 
-  if (secret)
-    *secret = is_secret;
-  *mpis = mpis_new;
-  *comment = comment_new;
-  *r_curve = curve_name;
+  *r_blob = blob;
+  blob = NULL;
+  *r_blob_size = blob_size;
 
  out:
-
   gcry_sexp_release (value_list);
   gcry_sexp_release (value_pair);
-  gcry_sexp_release (comment_list);
-
-  if (err)
-    {
-      xfree (curve_name);
-      xfree (comment_new);
-      mpint_list_free (mpis_new);
-    }
+  xfree (curve_name);
+  es_fclose (stream);
+  es_free (blob);
 
   return err;
 }
@@ -1700,6 +2071,11 @@ ssh_key_type_lookup (const char *ssh_name, const char *name,
   gpg_error_t err;
   unsigned int i;
 
+  /* FIXME: Although this sees to work, it not be correct if the
+     lookup is done via name which might be "ecc" but actually it need
+     to check the flags to see whether it is eddsa or ecdsa.  Maybe
+     the entire parameter controlled logic is too complicated and we
+     would do better by just switching on the ssh_name.  */
   for (i = 0; i < DIM (ssh_key_types); i++)
     if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
        || (name && (! strcmp (name, ssh_key_types[i].identifier))))
@@ -1717,23 +2093,6 @@ ssh_key_type_lookup (const char *ssh_name, const char *name,
 }
 
 
-/* Lookup the ssh-identifier for the ECC curve CURVE_NAME.  Returns
-   NULL if not found.  */
-static const char *
-ssh_identifier_from_curve_name (const char *curve_name)
-{
-  int i;
-
-  for (i = 0; i < DIM (ssh_key_types); i++)
-    if (ssh_key_types[i].curve_name
-        && !strcmp (ssh_key_types[i].curve_name, curve_name))
-      return ssh_key_types[i].ssh_identifier;
-
-  return NULL;
-}
-
-
-
 /* Receive a key from STREAM, according to the key specification given
    as KEY_SPEC.  Depending on SECRET, receive a secret or a public
    key.  If READ_COMMENT is true, receive a comment string as well.
@@ -1753,7 +2112,6 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
   char *curve_name = NULL;
 
 
-
   err = stream_read_cstring (stream, &key_type);
   if (err)
     goto out;
@@ -1762,7 +2120,65 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
   if (err)
     goto out;
 
-  if ((spec.flags & SPEC_FLAG_IS_ECDSA))
+  if ((spec.flags & SPEC_FLAG_IS_EdDSA))
+    {
+      /* The format of an EdDSA key is:
+       *   string      key_type ("ssh-ed25519")
+       *   string      public_key
+       *   string      private_key
+       *
+       * Note that the private key is the concatenation of the private
+       * key with the public key.  Thus theres are 64 bytes; however
+       * we only want the real 32 byte private key - Libgcrypt expects
+       * this.
+       */
+      mpi_list = xtrycalloc (3, sizeof *mpi_list);
+      if (!mpi_list)
+        {
+          err = gpg_error_from_syserror ();
+          goto out;
+        }
+
+      err = stream_read_blob (stream, 0, &mpi_list[0]);
+      if (err)
+        goto out;
+      if (secret)
+        {
+          u32 len = 0;
+          unsigned char *buffer;
+
+          /* Read string length.  */
+          err = stream_read_uint32 (stream, &len);
+          if (err)
+            goto out;
+          if (len != 32 && len != 64)
+            {
+              err = gpg_error (GPG_ERR_BAD_SECKEY);
+              goto out;
+            }
+          buffer = xtrymalloc_secure (32);
+          if (!buffer)
+            {
+              err = gpg_error_from_syserror ();
+              goto out;
+            }
+          err = stream_read_data (stream, buffer, 32);
+          if (err)
+            {
+              xfree (buffer);
+              goto out;
+            }
+          mpi_list[1] = gcry_mpi_set_opaque (NULL, buffer, 8*32);
+          buffer = NULL;
+          if (len == 64)
+            {
+              err = stream_read_skip (stream, 32);
+              if (err)
+                goto out;
+            }
+        }
+    }
+  else if ((spec.flags & SPEC_FLAG_IS_ECDSA))
     {
       /* The format of an ECDSA key is:
        *   string      key_type ("ecdsa-sha2-nistp256" |
@@ -1796,165 +2212,103 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
         mapped = NULL;
       if (mapped)
         {
-          xfree (curve_name);
-          curve_name = xtrystrdup (mapped);
-          if (!curve_name)
-            {
-              err = gpg_error_from_syserror ();
-              goto out;
-            }
-        }
-  }
-
-  err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
-  if (err)
-    goto out;
-
-  if (read_comment)
-    {
-      err = stream_read_cstring (stream, &comment);
-      if (err)
-       goto out;
-    }
-
-  if (secret)
-    elems = spec.elems_key_secret;
-  else
-    elems = spec.elems_key_public;
-
-  if (spec.key_modifier)
-    {
-      err = (*spec.key_modifier) (elems, mpi_list);
-      if (err)
-       goto out;
-    }
-
-  err = sexp_key_construct (&key, spec, secret, curve_name, mpi_list,
-                            comment? comment:"");
-  if (err)
-    goto out;
-
-  if (key_spec)
-    *key_spec = spec;
-  *key_new = key;
-
- out:
-  mpint_list_free (mpi_list);
-  xfree (curve_name);
-  xfree (key_type);
-  xfree (comment);
-
-  return err;
-}
-
-/* Converts a key of type TYPE, whose key material is given in MPIS,
-   into a newly created binary blob, which is to be stored in
-   BLOB/BLOB_SIZE.  Returns zero on success or an error code.  */
-static gpg_error_t
-ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size,
-                        ssh_key_type_spec_t *spec,
-                         const char *curve_name, gcry_mpi_t *mpis)
-{
-  unsigned char *blob_new;
-  long int blob_size_new;
-  estream_t stream;
-  gpg_error_t err;
-  unsigned int i;
-
-  *blob = NULL;
-  *blob_size = 0;
-
-  blob_new = NULL;
-  stream = NULL;
-  err = 0;
-
-  stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
-  if (! stream)
-    {
-      err = gpg_error_from_syserror ();
-      goto out;
-    }
-
-  if ((spec->flags & SPEC_FLAG_IS_ECDSA) && curve_name)
-    {
-      const char *sshname = ssh_identifier_from_curve_name (curve_name);
-      if (!curve_name)
-        {
-          err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
-          goto out;
+          xfree (curve_name);
+          curve_name = xtrystrdup (mapped);
+          if (!curve_name)
+            {
+              err = gpg_error_from_syserror ();
+              goto out;
+            }
         }
-      err = stream_write_cstring (stream, sshname);
-      if (err)
-        goto out;
-      err = stream_write_cstring (stream, curve_name);
+
+      err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
       if (err)
         goto out;
     }
   else
     {
-      err = stream_write_cstring (stream, spec->ssh_identifier);
+      err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
       if (err)
         goto out;
     }
 
-  for (i = 0; mpis[i]; i++)
-    if ((err = stream_write_mpi (stream, mpis[i])))
-      goto out;
-
-  blob_size_new = es_ftell (stream);
-  if (blob_size_new == -1)
+  if (read_comment)
     {
-      err = gpg_error_from_syserror ();
-      goto out;
+      err = stream_read_cstring (stream, &comment);
+      if (err)
+       goto out;
     }
 
-  err = es_fseek (stream, 0, SEEK_SET);
-  if (err)
-    goto out;
+  if (secret)
+    elems = spec.elems_key_secret;
+  else
+    elems = spec.elems_key_public;
 
-  blob_new = xtrymalloc (blob_size_new);
-  if (! blob_new)
+  if (spec.key_modifier)
     {
-      err = gpg_error_from_syserror ();
-      goto out;
+      err = (*spec.key_modifier) (elems, mpi_list);
+      if (err)
+       goto out;
     }
 
-  err = stream_read_data (stream, blob_new, blob_size_new);
-  if (err)
-    goto out;
+  if ((spec.flags & SPEC_FLAG_IS_EdDSA))
+    {
+      if (secret)
+        {
+          err = gcry_sexp_build (&key, NULL,
+                                 "(private-key(ecc(curve \"Ed25519\")"
+                                 "(flags eddsa)(q %m)(d %m))"
+                                 "(comment%s))",
+                                 mpi_list[0], mpi_list[1],
+                                 comment? comment:"");
+        }
+      else
+        {
+          err = gcry_sexp_build (&key, NULL,
+                                 "(public-key(ecc(curve \"Ed25519\")"
+                                 "(flags eddsa)(q %m))"
+                                 "(comment%s))",
+                                 mpi_list[0],
+                                 comment? comment:"");
+        }
+    }
+  else
+    {
+      err = sexp_key_construct (&key, spec, secret, curve_name, mpi_list,
+                                comment? comment:"");
+      if (err)
+        goto out;
+    }
 
-  *blob = blob_new;
-  *blob_size = blob_size_new;
+  if (key_spec)
+    *key_spec = spec;
+  *key_new = key;
 
  out:
-
-  if (stream)
-    es_fclose (stream);
-  if (err)
-    xfree (blob_new);
+  mpint_list_free (mpi_list);
+  xfree (curve_name);
+  xfree (key_type);
+  xfree (comment);
 
   return err;
 }
 
 
-/* Write the public key KEY_PUBLIC to STREAM in SSH key format.  If
+/* Write the public key from KEY to STREAM in SSH key format.  If
    OVERRIDE_COMMENT is not NULL, it will be used instead of the
    comment stored in the key.  */
 static gpg_error_t
-ssh_send_key_public (estream_t stream,
-                     gcry_sexp_t key_public,
+ssh_send_key_public (estream_t stream, gcry_sexp_t key,
                      const char *override_comment)
 {
   ssh_key_type_spec_t spec;
-  gcry_mpi_t *mpi_list = NULL;
   char *key_type = NULL;
-  char *curve;
   char *comment = NULL;
-  unsigned char *blob = NULL;
-  size_t blob_n;
+  void *blob = NULL;
+  size_t bloblen;
   gpg_error_t err;
 
-  err = sexp_extract_identifier (key_public, &key_type);
+  err = sexp_extract_identifier (key, &key_type);
   if (err)
     goto out;
 
@@ -1962,32 +2316,36 @@ ssh_send_key_public (estream_t stream,
   if (err)
     goto out;
 
-  err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &curve, &comment);
+  err = ssh_key_to_blob (key, 0, spec, &blob, &bloblen);
   if (err)
     goto out;
 
-  err = ssh_convert_key_to_blob (&blob, &blob_n, &spec, curve, mpi_list);
+  err = stream_write_string (stream, blob, bloblen);
   if (err)
     goto out;
 
-  err = stream_write_string (stream, blob, blob_n);
+  if (override_comment)
+    err = stream_write_cstring (stream, override_comment);
+  else
+    {
+      err = ssh_key_extract_comment (key, &comment);
+      if (err)
+        err = stream_write_cstring (stream, "(none)");
+      else
+        err = stream_write_cstring (stream, comment);
+    }
   if (err)
     goto out;
 
-  err = stream_write_cstring (stream,
-                              override_comment? override_comment : comment);
-
  out:
-
-  mpint_list_free (mpi_list);
-  xfree (curve);
-  xfree (comment);
   xfree (key_type);
-  xfree (blob);
+  xfree (comment);
+  es_free (blob);
 
   return err;
 }
 
+
 /* Read a public key out of BLOB/BLOB_SIZE according to the key
    specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
    Returns zero on success or an error code.  */
@@ -1996,13 +2354,11 @@ ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
                               gcry_sexp_t *key_public,
                               ssh_key_type_spec_t *key_spec)
 {
-  estream_t blob_stream;
   gpg_error_t err;
+  estream_t blob_stream;
 
-  err = 0;
-
-  blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
-  if (! blob_stream)
+  blob_stream = es_fopenmem (0, "r+b");
+  if (!blob_stream)
     {
       err = gpg_error_from_syserror ();
       goto out;
@@ -2019,10 +2375,7 @@ ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
   err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
 
  out:
-
-  if (blob_stream)
-    es_fclose (blob_stream);
-
+  es_fclose (blob_stream);
   return err;
 }
 
@@ -2044,39 +2397,6 @@ ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
 }
 
 
-/* Converts the secret key KEY_SECRET into a public key, storing it in
-   KEY_PUBLIC.  SPEC is the according key specification.  Returns zero
-   on success or an error code.  */
-static gpg_error_t
-key_secret_to_public (gcry_sexp_t *key_public,
-                     ssh_key_type_spec_t spec, gcry_sexp_t key_secret)
-{
-  char *curve;
-  char *comment;
-  gcry_mpi_t *mpis;
-  gpg_error_t err;
-  int is_secret;
-
-  comment = NULL;
-  mpis = NULL;
-
-  err = sexp_key_extract (key_secret, spec, &is_secret, &mpis,
-                          &curve, &comment);
-  if (err)
-    goto out;
-
-  err = sexp_key_construct (key_public, spec, 0, curve, mpis, comment);
-
- out:
-
-  mpint_list_free (mpis);
-  xfree (comment);
-  xfree (curve);
-
-  return err;
-}
-
-
 /* Check whether a smartcard is available and whether it has a usable
    key.  Store a copy of that key at R_PK and return 0.  If no key is
    available store NULL at R_PK and return an error code.  If CARDSN
@@ -2116,7 +2436,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
     }
   if (err)
     {
-      log_error (_("error getting default authentication keyID of card: %s\n"),
+      log_error (_("no authentication key for ssh on card: %s\n"),
                  gpg_strerror (err));
       xfree (serialno);
       return err;
@@ -2280,7 +2600,7 @@ ssh_handler_request_identities (ctrl_t ctrl,
   key_counter = 0;
   err = 0;
 
-  key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+b");
+  key_blobs = es_fopenmem (0, "r+b");
   if (! key_blobs)
     {
       err = gpg_error_from_syserror ();
@@ -2375,20 +2695,12 @@ ssh_handler_request_identities (ctrl_t ctrl,
           goto out;
       }
 
-      err = key_secret_to_public (&key_public, spec, key_secret);
+      err = ssh_send_key_public (key_blobs, key_secret, NULL);
       if (err)
         goto out;
-
       gcry_sexp_release (key_secret);
       key_secret = NULL;
 
-      err = ssh_send_key_public (key_blobs, key_public, NULL);
-      if (err)
-        goto out;
-
-      gcry_sexp_release (key_public);
-      key_public = NULL;
-
       key_counter++;
     }
   err = 0;
@@ -2440,30 +2752,27 @@ data_hash (unsigned char *data, size_t data_n,
   return 0;
 }
 
-/* This function signs the data contained in CTRL, stores the created
-   signature in newly allocated memory in SIG and it's size in SIG_N;
-   SIG_ENCODER is the signature encoder to use.  */
+
+/* This function signs the data described by CTRL. If HASH is is not
+   NULL, (HASH,HASHLEN) overrides the hash stored in CTRL.  This is to
+   allow the use of signature algorithms that implement the hashing
+   internally (e.g. Ed25519).  On success the created signature is
+   stored in ssh format at R_SIG and it's size at R_SIGLEN; the caller
+   must use es_free to releaase this memory.  */
 static gpg_error_t
 data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
-          unsigned char **sig, size_t *sig_n)
+           const void *hash, size_t hashlen,
+          unsigned char **r_sig, size_t *r_siglen)
 {
   gpg_error_t err;
   gcry_sexp_t signature_sexp = NULL;
   estream_t stream = NULL;
-  gcry_sexp_t valuelist = NULL;
-  gcry_sexp_t sublist = NULL;
-  gcry_mpi_t sig_value = NULL;
-  unsigned char *sig_blob = NULL;
-  size_t sig_blob_n = 0;
-  int ret;
-  unsigned int i;
-  const char *elems;
-  size_t elems_n;
-  gcry_mpi_t *mpis = NULL;
+  void *blob = NULL;
+  size_t bloblen;
   char hexgrip[40+1];
 
-  *sig = NULL;
-  *sig_n = 0;
+  *r_sig = NULL;
+  *r_siglen = 0;
 
   /* Quick check to see whether we have a valid keygrip and convert it
      to hex.  */
@@ -2510,24 +2819,18 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
 
   /* Create signature.  */
   ctrl->use_auth_call = 1;
-  err = agent_pksign_do (ctrl,
+  err = agent_pksign_do (ctrl, NULL,
                          _("Please enter the passphrase "
                            "for the ssh key%%0A  %F%%0A  (%c)"),
                          &signature_sexp,
-                         CACHE_MODE_SSH, ttl_from_sshcontrol);
+                         CACHE_MODE_SSH, ttl_from_sshcontrol,
+                         hash, hashlen);
   ctrl->use_auth_call = 0;
   if (err)
     goto out;
 
-  valuelist = gcry_sexp_nth (signature_sexp, 1);
-  if (! valuelist)
-    {
-      err = gpg_error (GPG_ERR_INV_SEXP);
-      goto out;
-    }
-
-  stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
-  if (! stream)
+  stream = es_fopenmem (0, "r+b");
+  if (!stream)
     {
       err = gpg_error_from_syserror ();
       goto out;
@@ -2537,99 +2840,40 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
   if (err)
     goto out;
 
-  elems = spec->elems_signature;
-  elems_n = strlen (elems);
-
-  mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
-  if (!mpis)
-    {
-      err = gpg_error_from_syserror ();
-      goto out;
-    }
-
-  for (i = 0; i < elems_n; i++)
-    {
-      sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
-      if (! sublist)
-       {
-         err = gpg_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
-      if (! sig_value)
-       {
-         err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
-         break;
-       }
-      gcry_sexp_release (sublist);
-      sublist = NULL;
-
-      mpis[i] = sig_value;
-    }
-  if (err)
-    goto out;
-
-  err = spec->signature_encoder (spec, stream, mpis);
+  err = spec->signature_encoder (spec, stream, signature_sexp);
   if (err)
     goto out;
 
-  sig_blob_n = es_ftell (stream);
-  if (sig_blob_n == -1)
-    {
-      err = gpg_error_from_syserror ();
-      goto out;
-    }
-
-  sig_blob = xtrymalloc (sig_blob_n);
-  if (! sig_blob)
-    {
-      err = gpg_error_from_syserror ();
-      goto out;
-    }
-
-  ret = es_fseek (stream, 0, SEEK_SET);
-  if (ret)
-    {
-      err = gpg_error_from_syserror ();
-      goto out;
-    }
-
-  err = stream_read_data (stream, sig_blob, sig_blob_n);
+  err = es_fclose_snatch (stream, &blob, &bloblen);
   if (err)
     goto out;
+  stream = NULL;
 
-  *sig = sig_blob;
-  *sig_n = sig_blob_n;
+  *r_sig = blob; blob = NULL;
+  *r_siglen = bloblen;
 
  out:
-
-  if (err)
-    xfree (sig_blob);
-
-  if (stream)
-    es_fclose (stream);
-  gcry_sexp_release (valuelist);
+  xfree (blob);
+  es_fclose (stream);
   gcry_sexp_release (signature_sexp);
-  gcry_sexp_release (sublist);
-  mpint_list_free (mpis);
 
   return err;
 }
 
+
 /* Handler for the "sign_request" command.  */
 static gpg_error_t
 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
 {
-  gcry_sexp_t key;
+  gcry_sexp_t key = NULL;
   ssh_key_type_spec_t spec;
   unsigned char hash[MAX_DIGEST_LEN];
   unsigned int hash_n;
   unsigned char key_grip[20];
-  unsigned char *key_blob;
+  unsigned char *key_blob = NULL;
   u32 key_blob_size;
-  unsigned char *data;
-  unsigned char *sig;
+  unsigned char *data = NULL;
+  unsigned char *sig = NULL;
   size_t sig_n;
   u32 data_size;
   u32 flags;
@@ -2637,11 +2881,6 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
   gpg_error_t ret_err;
   int hash_algo;
 
-  key_blob = NULL;
-  data = NULL;
-  sig = NULL;
-  key = NULL;
-
   /* Receive key.  */
 
   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
@@ -2665,42 +2904,48 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
   hash_algo = spec.hash_algo;
   if (!hash_algo)
     hash_algo = GCRY_MD_SHA1;  /* Use the default.  */
-
-  /* Hash data.  */
-  hash_n = gcry_md_get_algo_dlen (hash_algo);
-  if (! hash_n)
-    {
-      err = gpg_error (GPG_ERR_INTERNAL);
-      goto out;
-    }
-  err = data_hash (data, data_size, hash_algo, hash);
-  if (err)
-    goto out;
-
-  /* Calculate key grip.  */
-  err = ssh_key_grip (key, key_grip);
-  if (err)
-    goto out;
-
-  /* Sign data.  */
-
   ctrl->digest.algo = hash_algo;
-  memcpy (ctrl->digest.value, hash, hash_n);
-  ctrl->digest.valuelen = hash_n;
   if ((spec.flags & SPEC_FLAG_USE_PKCS1V2))
     ctrl->digest.raw_value = 0;
   else
     ctrl->digest.raw_value = 1;
+
+  /* Calculate key grip.  */
+  err = ssh_key_grip (key, key_grip);
+  if (err)
+    goto out;
   ctrl->have_keygrip = 1;
   memcpy (ctrl->keygrip, key_grip, 20);
 
-  err = data_sign (ctrl, &spec, &sig, &sig_n);
+  /* Hash data unless we use EdDSA.  */
+  if ((spec.flags & SPEC_FLAG_IS_EdDSA))
+    {
+      ctrl->digest.valuelen = 0;
+    }
+  else
+    {
+      hash_n = gcry_md_get_algo_dlen (hash_algo);
+      if (!hash_n)
+        {
+          err = gpg_error (GPG_ERR_INTERNAL);
+          goto out;
+        }
+      err = data_hash (data, data_size, hash_algo, hash);
+      if (err)
+        goto out;
+      memcpy (ctrl->digest.value, hash, hash_n);
+      ctrl->digest.valuelen = hash_n;
+    }
+
+  /* Sign data.  */
+  if ((spec.flags & SPEC_FLAG_IS_EdDSA))
+    err = data_sign (ctrl, &spec, data, data_size, &sig, &sig_n);
+  else
+    err = data_sign (ctrl, &spec, NULL, 0, &sig, &sig_n);
 
  out:
-
   /* Done.  */
-
-  if (! err)
+  if (!err)
     {
       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
       if (ret_err)
@@ -2711,6 +2956,8 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
     }
   else
     {
+      log_error ("ssh sign request failed: %s <%s>\n",
+                 gpg_strerror (err), gpg_strsource (err));
       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
       if (ret_err)
        goto leave;
@@ -2721,54 +2968,35 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
   gcry_sexp_release (key);
   xfree (key_blob);
   xfree (data);
-  xfree (sig);
+  es_free (sig);
 
   return ret_err;
 }
 
+
 /* This function extracts the comment contained in the key
-   S-Expression KEY and stores a copy in COMMENT.  Returns usual error
+   s-expression KEY and stores a copy in COMMENT.  Returns usual error
    code.  */
 static gpg_error_t
-ssh_key_extract_comment (gcry_sexp_t key, char **comment)
+ssh_key_extract_comment (gcry_sexp_t key, char **r_comment)
 {
   gcry_sexp_t comment_list;
-  char *comment_new;
-  const char *data;
-  size_t data_n;
-  gpg_error_t err;
-
-  comment_list = gcry_sexp_find_token (key, "comment", 0);
-  if (! comment_list)
-    {
-      err = gpg_error (GPG_ERR_INV_SEXP);
-      goto out;
-    }
-
-  data = gcry_sexp_nth_data (comment_list, 1, &data_n);
-  if (! data)
-    {
-      err = gpg_error (GPG_ERR_INV_SEXP);
-      goto out;
-    }
-
-  comment_new = make_cstring (data, data_n);
-  if (! comment_new)
-    {
-      err = gpg_error_from_syserror ();
-      goto out;
-    }
 
-  *comment = comment_new;
-  err = 0;
+  *r_comment = NULL;
 
- out:
+  comment_list = gcry_sexp_find_token (key, "comment", 0);
+  if (!comment_list)
+    return gpg_error (GPG_ERR_INV_SEXP);
 
+  *r_comment = gcry_sexp_nth_string (comment_list, 1);
   gcry_sexp_release (comment_list);
+  if (!*r_comment)
+    return gpg_error (GPG_ERR_INV_SEXP);
 
-  return err;
+  return 0;
 }
 
+
 /* This function converts the key contained in the S-Expression KEY
    into a buffer, which is protected by the passphrase PASSPHRASE.
    Returns usual error code.  */
@@ -2792,7 +3020,7 @@ ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
   /* FIXME: guarantee?  */
 
-  err = agent_protect (buffer_new, passphrase, buffer, buffer_n);
+  err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
 
  out:
 
@@ -2822,7 +3050,8 @@ reenter_compare_cb (struct pin_entry_info_s *pi)
    our key storage, don't do anything.  When entering a new key also
    add an entry to the sshcontrol file.  */
 static gpg_error_t
-ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
+ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+                       gcry_sexp_t key, int ttl, int confirm)
 {
   gpg_error_t err;
   unsigned char key_grip_raw[20];
@@ -2835,8 +3064,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
   char *key_fpr = NULL;
   const char *initial_errtext = NULL;
   unsigned int i;
-  struct pin_entry_info_s *pi = NULL;
-  struct pin_entry_info_s *pi2 = NULL;
+  struct pin_entry_info_s *pi = NULL, *pi2;
 
   err = ssh_key_grip (key, key_grip_raw);
   if (err)
@@ -2867,35 +3095,32 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
       goto out;
     }
 
-  pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
+  pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
   if (!pi)
     {
       err = gpg_error_from_syserror ();
       goto out;
     }
-  pi->max_length = 100 + 1;
+  pi2 = pi + (sizeof *pi + 100 + 1);
+  pi->max_length = 100;
   pi->max_tries = 1;
-  pi2 = gcry_calloc_secure (1, sizeof (*pi2) + 100 + 1);
-  if (!pi2)
-    {
-      err = gpg_error_from_syserror ();
-      goto out;
-    }
-  pi2->max_length = 100 + 1;
+  pi->with_repeat = 1;
+  pi2->max_length = 100;
   pi2->max_tries = 1;
   pi2->check_cb = reenter_compare_cb;
   pi2->check_cb_arg = pi->pin;
 
  next_try:
-  err = agent_askpin (ctrl, description, NULL, initial_errtext, pi, NULL, 0);
+  err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
   initial_errtext = NULL;
   if (err)
     goto out;
 
-  /* Unless the passphrase is empty, ask to confirm it.  */
-  if (pi->pin && *pi->pin)
+  /* Unless the passphrase is empty or the pinentry told us that
+     it already did the repetition check, ask to confirm it.  */
+  if (pi->pin && *pi->pin && !pi->repeat_okay)
     {
-      err = agent_askpin (ctrl, description2, NULL, NULL, pi2, NULL, 0);
+      err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
       if (err == -1)
        { /* The re-entered one did not match and the user did not
             hit cancel. */
@@ -2922,13 +3147,10 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
     goto out;
 
   /* And add an entry to the sshcontrol file.  */
-  err = add_control_entry (ctrl, key_grip, key_fpr, ttl, confirm);
+  err = add_control_entry (ctrl, spec, key_grip, key_fpr, ttl, confirm);
 
 
  out:
-  if (pi2 && pi2->max_length)
-    wipememory (pi2->pin, pi2->max_length);
-  xfree (pi2);
   if (pi && pi->max_length)
     wipememory (pi->pin, pi->max_length);
   xfree (pi);
@@ -2969,6 +3191,7 @@ static gpg_error_t
 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
 {
   gpg_error_t ret_err;
+  ssh_key_type_spec_t spec;
   gpg_error_t err;
   gcry_sexp_t key;
   unsigned char b;
@@ -2980,7 +3203,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
   ttl = 0;
 
   /* FIXME?  */
-  err = ssh_receive_key (request, &key, 1, 1, NULL);
+  err = ssh_receive_key (request, &key, 1, 1, &spec);
   if (err)
     goto out;
 
@@ -3019,7 +3242,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
   if (err)
     goto out;
 
-  err = ssh_identity_register (ctrl, key, ttl, confirm);
+  err = ssh_identity_register (ctrl, &spec, key, ttl, confirm);
 
  out:
 
@@ -3207,21 +3430,16 @@ static int
 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
 {
   ssh_request_spec_t *spec;
-  estream_t response;
-  estream_t request;
+  estream_t response = NULL;
+  estream_t request = NULL;
   unsigned char request_type;
   gpg_error_t err;
-  int send_err;
+  int send_err = 0;
   int ret;
-  unsigned char *request_data;
+  unsigned char *request_data = NULL;
   u32 request_data_size;
   u32 response_size;
 
-  request_data = NULL;
-  response = NULL;
-  request = NULL;
-  send_err = 0;
-
   /* Create memory streams for request/response data.  The entire
      request will be stored in secure memory, since it might contain
      secret key material.  The response does not have to be stored in
@@ -3260,9 +3478,9 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
     }
 
   if (spec->secret_input)
-    request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
+    request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+b");
   else
-    request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
+    request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+b");
   if (! request)
     {
       err = gpg_error_from_syserror ();
@@ -3279,7 +3497,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
     goto out;
   es_rewind (request);
 
-  response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
+  response = es_fopenmem (0, "r+b");
   if (! response)
     {
       err = gpg_error_from_syserror ();
@@ -3355,17 +3573,15 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
 
  leave:
 
-  if (request)
-    es_fclose (request);
-  if (response)
-    es_fclose (response);
-  xfree (request_data);                /* FIXME?  */
+  es_fclose (request);
+  es_fclose (response);
+  xfree (request_data);
 
   return !!err;
 }
 
 
-/* Because the ssh protocol does not send us information about the the
+/* Because the ssh protocol does not send us information about the
    current TTY setting, we use this function to use those from startup
    or those explictly set.  */
 static gpg_error_t
index 9393212..11bfbeb 100644 (file)
@@ -1,7 +1,6 @@
 /* command.c - gpg-agent command handler
- * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- *               2006, 2008, 2009  Free Software Foundation, Inc.
- * Copyright (C) 2013 Werner Koch
+ * Copyright (C) 2001-2011 Free Software Foundation, Inc.
+ * Copyright (C) 2001-2013 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include "agent.h"
 #include <assuan.h>
 #include "i18n.h"
+#include "cvt-openpgp.h"
 #include "../common/ssh-utils.h"
+#include "../common/asshelp.h"
 
-/* maximum allowed size of the inquired ciphertext */
+
+/* Maximum allowed size of the inquired ciphertext.  */
 #define MAXLEN_CIPHERTEXT 4096
-/* maximum allowed size of the key parameters */
+/* Maximum allowed size of the key parameters.  */
 #define MAXLEN_KEYPARAM 1024
+/* Maximum allowed size of key data as used in inquiries (bytes). */
+#define MAXLEN_KEYDATA 4096
+/* The size of the import/export KEK key (in bytes).  */
+#define KEYWRAP_KEYSIZE (128/8)
 
+/* A shortcut to call assuan_set_error using an gpg_err_code_t and a
+   text string.  */
 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
 
-
+/* Check that the maximum digest length we support has at least the
+   length of the keygrip.  */
 #if MAX_DIGEST_LEN < 20
 #error MAX_DIGEST_LEN shorter than keygrip
 #endif
 
-/* Data used to associate an Assuan context with local server data */
+/* Data used to associate an Assuan context with local server data.
+   This is this modules local part of the server_control_s struct.  */
 struct server_local_s
 {
+  /* Our Assuan context.  */
   assuan_context_t assuan_ctx;
-  int message_fd;
+
+  /* If this flag is true, the passphrase cache is used for signing
+     operations.  It defaults to true but may be set on a per
+     connection base.  The global option opt.ignore_cache_for_signing
+     takes precedence over this flag.  */
   int use_cache_for_signing;
-  char *keydesc;  /* Allocated description for the next key
-                     operation. */
-  int pause_io_logging; /* Used to suppress I/O logging during a command */
-  int stopme;    /* If set to true the agent will be terminated after
-                    the end of this session.  */
-  int allow_pinentry_notify; /* Set if pinentry notifications should
-                                be done. */
+
+  /* An allocated description for the next key operation.  This is
+     used if a pinnetry needs to be popped up.  */
+  char *keydesc;
+
+  /* Flags to suppress I/O logging during a command.  */
+  int pause_io_logging;
+
+  /* If this flags is set to true the agent will be terminated after
+     the end of the current session.  */
+  int stopme;
+
+  /* Flag indicating whether pinentry notifications shall be done. */
+  int allow_pinentry_notify;
+
+  /* Malloced KEK (Key-Encryption-Key) for the import_key command.  */
+  void *import_key;
+
+  /* Malloced KEK for the export_key command.  */
+  void *export_key;
+
+  /* Client is aware of the error code GPG_ERR_FULLY_CANCELED.  */
+  int allow_fully_canceled;
+
+  /* Last CACHE_NONCE sent as status (malloced).  */
+  char *last_cache_nonce;
+
+  /* Last PASSWD_NONCE sent as status (malloced). */
+  char *last_passwd_nonce;
 };
 
 
@@ -121,7 +158,7 @@ clear_outbuf (membuf_t *mb)
   p = get_membuf (mb, &n);
   if (p)
     {
-      memset (p, 0, n);
+      wipememory (p, n);
       xfree (p);
     }
 }
@@ -146,6 +183,31 @@ write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
 }
 
 
+/* Clear the nonces used to enable the passphrase cache for certain
+   multi-command command sequences.  */
+static void
+clear_nonce_cache (ctrl_t ctrl)
+{
+  if (ctrl->server_local->last_cache_nonce)
+    {
+      agent_put_cache (ctrl->server_local->last_cache_nonce,
+                       CACHE_MODE_NONCE, NULL, 0);
+      xfree (ctrl->server_local->last_cache_nonce);
+      ctrl->server_local->last_cache_nonce = NULL;
+    }
+  if (ctrl->server_local->last_passwd_nonce)
+    {
+      agent_put_cache (ctrl->server_local->last_passwd_nonce,
+                       CACHE_MODE_NONCE, NULL, 0);
+      xfree (ctrl->server_local->last_passwd_nonce);
+      ctrl->server_local->last_passwd_nonce = NULL;
+    }
+}
+
+
+/* This function is called by Libassuan whenever thee client sends a
+   reset.  It has been registered similar to the other Assuan
+   commands.  */
 static gpg_error_t
 reset_notify (assuan_context_t ctx, char *line)
 {
@@ -159,11 +221,40 @@ reset_notify (assuan_context_t ctx, char *line)
 
   xfree (ctrl->server_local->keydesc);
   ctrl->server_local->keydesc = NULL;
+
+  clear_nonce_cache (ctrl);
+
   return 0;
 }
 
 
-/* Check whether the option NAME appears in LINE */
+/* Skip over options in LINE.
+
+   Blanks after the options are also removed.  Options are indicated
+   by two leading dashes followed by a string consisting of non-space
+   characters.  The special option "--" indicates an explicit end of
+   options; all what follows will not be considered an option.  The
+   first no-option string also indicates the end of option parsing. */
+static char *
+skip_options (const char *line)
+{
+  while (spacep (line))
+    line++;
+  while ( *line == '-' && line[1] == '-' )
+    {
+      while (*line && !spacep (line))
+        line++;
+      while (spacep (line))
+        line++;
+    }
+  return (char*)line;
+}
+
+
+/* Check whether the option NAME appears in LINE.  An example for a
+   line with options is:
+     --algo=42 --data foo bar
+   This function would then only return true if NAME is "data".  */
 static int
 has_option (const char *line, const char *name)
 {
@@ -171,9 +262,12 @@ has_option (const char *line, const char *name)
   int n = strlen (name);
 
   s = strstr (line, name);
+  if (s && s >= skip_options (line))
+    return 0;
   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
 }
 
+
 /* Same as has_option but does only test for the name of the option
    and ignores an argument, i.e. with NAME being "--hash" it would
    return true for "--hash" as well as for "--hash=foo". */
@@ -184,12 +278,15 @@ has_option_name (const char *line, const char *name)
   int n = strlen (name);
 
   s = strstr (line, name);
+  if (s && s >= skip_options (line))
+    return 0;
   return (s && (s == line || spacep (s-1))
           && (!s[n] || spacep (s+n) || s[n] == '='));
 }
 
+
 /* Return a pointer to the argument of the option with NAME.  If such
-   an option is not given, it returns NULL. */
+   an option is not given, NULL is retruned. */
 static char *
 option_value (const char *line, const char *name)
 {
@@ -197,6 +294,8 @@ option_value (const char *line, const char *name)
   int n = strlen (name);
 
   s = strstr (line, name);
+  if (s && s >= skip_options (line))
+    return NULL;
   if (s && (s == line || spacep (s-1))
       && s[n] && (spacep (s+n) || s[n] == '='))
     {
@@ -209,24 +308,7 @@ option_value (const char *line, const char *name)
 }
 
 
-/* Skip over options.  It is assumed that leading spaces have been
-   removed (this is the case for lines passed to a handler from
-   assuan).  Blanks after the options are also removed. */
-static char *
-skip_options (char *line)
-{
-  while ( *line == '-' && line[1] == '-' )
-    {
-      while (*line && !spacep (line))
-        line++;
-      while (spacep (line))
-        line++;
-    }
-  return line;
-}
-
-
-/* Replace all '+' by a blank. */
+/* Replace all '+' by a blank in the string S. */
 static void
 plus_to_blank (char *s)
 {
@@ -257,8 +339,9 @@ parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
   return 0;
 }
 
+
 /* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
-   provide space for 20 bytes. BUF is not changed if the function
+   provide space for 20 bytes.  BUF is not changed if the function
    returns an error. */
 static int
 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
@@ -280,7 +363,11 @@ parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
 }
 
 
-/* Write an assuan status line. */
+/* Write an Assuan status line.  KEYWORD is the first item on the
+   status line.  The following arguments are all separated by a space
+   in the output.  The last argument must be a NULL.  Linefeeds and
+   carriage returns characters (which are not allowed in an Assuan
+   status line) are silently quoted in C-style.  */
 gpg_error_t
 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
 {
@@ -326,6 +413,22 @@ agent_write_status (ctrl_t ctrl, const char *keyword, ...)
 }
 
 
+/* This function is similar to print_assuan_status but takes a CTRL
+   arg instead of an assuan context as first argument.  */
+gpg_error_t
+agent_print_status (ctrl_t ctrl, const char *keyword, const char *format, ...)
+{
+  gpg_error_t err;
+  va_list arg_ptr;
+  assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+
+  va_start (arg_ptr, format);
+  err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
+  va_end (arg_ptr);
+  return err;
+}
+
+
 /* Helper to notify the client about a launched Pinentry.  Because
    that might disturb some older clients, this is only done if enabled
    via an option.  Returns an gpg error code. */
@@ -342,6 +445,42 @@ agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
 }
 
 
+/* Helper to print a message while leaving a command.  */
+static gpg_error_t
+leave_cmd (assuan_context_t ctx, gpg_error_t err)
+{
+  if (err)
+    {
+      const char *name = assuan_get_command_name (ctx);
+      if (!name)
+        name = "?";
+
+      /* Not all users of gpg-agent know about the fully canceled
+         error code; map it back if needed.  */
+      if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+        {
+          ctrl_t ctrl = assuan_get_pointer (ctx);
+
+          if (!ctrl->server_local->allow_fully_canceled)
+            err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);
+        }
+
+      /* Most code from common/ does not know the error source, thus
+         we fix this here.  */
+      if (gpg_err_source (err) == GPG_ERR_SOURCE_UNKNOWN)
+        err = gpg_err_make (GPG_ERR_SOURCE_DEFAULT, gpg_err_code (err));
+
+      if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
+        log_error ("command '%s' failed: %s\n", name,
+                   gpg_strerror (err));
+      else
+        log_error ("command '%s' failed: %s <%s>\n", name,
+                   gpg_strerror (err), gpg_strsource (err));
+    }
+  return err;
+}
+
+
 \f
 static const char hlp_geteventcounter[] =
   "GETEVENTCOUNTER\n"
@@ -360,21 +499,13 @@ static gpg_error_t
 cmd_geteventcounter (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
-  char any_counter[25];
-  char key_counter[25];
-  char card_counter[25];
 
   (void)line;
 
-  snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
-  snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
-  snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
-
-  return agent_write_status (ctrl, "EVENTCOUNTER",
-                             any_counter,
-                             key_counter,
-                             card_counter,
-                             NULL);
+  return agent_print_status (ctrl, "EVENTCOUNTER", "%u %u %u",
+                             eventcounter.any,
+                             eventcounter.key,
+                             eventcounter.card);
 }
 
 
@@ -388,6 +519,7 @@ bump_key_eventcounter (void)
   eventcounter.any++;
 }
 
+
 /* This function should be called for all card reader status
    changes.  This function is assured not to do any context
    switches. */
@@ -434,10 +566,7 @@ cmd_istrusted (assuan_context_t ctx, char *line)
   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
     return gpg_error (GPG_ERR_NOT_TRUSTED);
   else
-    {
-      log_error ("command is_trusted failed: %s\n", gpg_strerror (rc));
-      return rc;
-    }
+    return leave_cmd (ctx, rc);
 }
 
 
@@ -453,9 +582,7 @@ cmd_listtrusted (assuan_context_t ctx, char *line)
   (void)line;
 
   rc = agent_listtrusted (ctx);
-  if (rc)
-    log_error ("command listtrusted failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
@@ -496,32 +623,42 @@ cmd_marktrusted (assuan_context_t ctx, char *line)
     p++;
 
   rc = agent_marktrusted (ctrl, p, fpr, flag);
-  if (rc)
-    log_error ("command marktrusted failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
 
 \f
 static const char hlp_havekey[] =
-  "HAVEKEY <hexstring_with_keygrip>\n"
+  "HAVEKEY <hexstrings_with_keygrips>\n"
   "\n"
-  "Return success when the secret key is available.";
+  "Return success if at least one of the secret keys with the given\n"
+  "keygrips is available.";
 static gpg_error_t
 cmd_havekey (assuan_context_t ctx, char *line)
 {
-  int rc;
+  gpg_error_t err;
   unsigned char buf[20];
 
-  rc = parse_keygrip (ctx, line, buf);
-  if (rc)
-    return rc;
+  do
+    {
+      err = parse_keygrip (ctx, line, buf);
+      if (err)
+        return err;
 
-  if (agent_key_available (buf))
-    return gpg_error (GPG_ERR_NO_SECKEY);
+      if (!agent_key_available (buf))
+        return 0; /* Found.  */
 
-  return 0;
+      while (*line && *line != ' ' && *line != '\t')
+        line++;
+      while (*line == ' ' || *line == '\t')
+        line++;
+    }
+  while (*line);
+
+  /* No leave_cmd() here because errors are expected and would clutter
+     the log.  */
+  return gpg_error (GPG_ERR_NO_SECKEY);
 }
 
 
@@ -547,8 +684,8 @@ cmd_sigkey (assuan_context_t ctx, char *line)
 static const char hlp_setkeydesc[] =
   "SETKEYDESC plus_percent_escaped_string\n"
   "\n"
-  "Set a description to be used for the next PKSIGN or PKDECRYPT\n"
-  "operation if this operation requires the entry of a passphrase.  If\n"
+  "Set a description to be used for the next PKSIGN, PKDECRYPT, IMPORT_KEY\n"
+  "or EXPORT_KEY operation if this operation requires a passphrase.  If\n"
   "this command is not used a default text will be used.  Note, that\n"
   "this description implictly selects the label used for the entry\n"
   "box; if the string contains the string PIN (which in general will\n"
@@ -556,8 +693,8 @@ static const char hlp_setkeydesc[] =
   "\"passphrase\" is used.  The description string should not contain\n"
   "blanks unless they are percent or '+' escaped.\n"
   "\n"
-  "The description is only valid for the next PKSIGN or PKDECRYPT\n"
-  "operation.";
+  "The description is only valid for the next PKSIGN, PKDECRYPT,\n"
+  "IMPORT_KEY, EXPORT_KEY, or DELETE_KEY operation.";
 static gpg_error_t
 cmd_setkeydesc (assuan_context_t ctx, char *line)
 {
@@ -589,7 +726,7 @@ cmd_setkeydesc (assuan_context_t ctx, char *line)
 
 
 static const char hlp_sethash[] =
-  "SETHASH --hash=<name>|<algonumber> <hexstring>\n"
+  "SETHASH (--hash=<name>)|(<algonumber>) <hexstring>\n"
   "\n"
   "The client can use this command to tell the server about the data\n"
   "(which usually is a hash) to be signed.";
@@ -642,6 +779,7 @@ cmd_sethash (assuan_context_t ctx, char *line)
         return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
     }
   ctrl->digest.algo = algo;
+  ctrl->digest.raw_value = 0;
 
   /* Parse the hash value. */
   n = 0;
@@ -669,7 +807,7 @@ cmd_sethash (assuan_context_t ctx, char *line)
 
 
 static const char hlp_pksign[] =
-  "PKSIGN [options]\n"
+  "PKSIGN [<options>] [<cache_nonce>]\n"
   "\n"
   "Perform the actual sign operation.  Neither input nor output are\n"
   "sensitive to eavesdropping.";
@@ -680,8 +818,17 @@ cmd_pksign (assuan_context_t ctx, char *line)
   cache_mode_t cache_mode = CACHE_MODE_NORMAL;
   ctrl_t ctrl = assuan_get_pointer (ctx);
   membuf_t outbuf;
+  char *cache_nonce = NULL;
+  char *p;
 
-  (void)line;
+  line = skip_options (line);
+
+  p = line;
+  for (p=line; *p && *p != ' ' && *p != '\t'; p++)
+    ;
+  *p = '\0';
+  if (*line)
+    cache_nonce = xtrystrdup (line);
 
   if (opt.ignore_cache_for_signing)
     cache_mode = CACHE_MODE_IGNORE;
@@ -690,22 +837,22 @@ cmd_pksign (assuan_context_t ctx, char *line)
 
   init_membuf (&outbuf, 512);
 
-  rc = agent_pksign (ctrl, ctrl->server_local->keydesc,
+  rc = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
                      &outbuf, cache_mode);
   if (rc)
     clear_outbuf (&outbuf);
   else
     rc = write_and_clear_outbuf (ctx, &outbuf);
-  if (rc)
-    log_error ("command pksign failed: %s\n", gpg_strerror (rc));
+
+  xfree (cache_nonce);
   xfree (ctrl->server_local->keydesc);
   ctrl->server_local->keydesc = NULL;
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
 static const char hlp_pkdecrypt[] =
-  "PKDECRYPT <options>\n"
+  "PKDECRYPT [<options>]\n"
   "\n"
   "Perform the actual decrypt operation.  Input is not\n"
   "sensitive to eavesdropping.";
@@ -717,34 +864,42 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
   unsigned char *value;
   size_t valuelen;
   membuf_t outbuf;
+  int padding;
 
   (void)line;
 
   /* First inquire the data to decrypt */
-  rc = assuan_inquire (ctx, "CIPHERTEXT",
-                       &value, &valuelen, MAXLEN_CIPHERTEXT);
+  rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_CIPHERTEXT);
+  if (!rc)
+    rc = assuan_inquire (ctx, "CIPHERTEXT",
+                       &value, &valuelen, MAXLEN_CIPHERTEXT);
   if (rc)
     return rc;
 
   init_membuf (&outbuf, 512);
 
   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
-                        value, valuelen, &outbuf);
+                        value, valuelen, &outbuf, &padding);
   xfree (value);
   if (rc)
     clear_outbuf (&outbuf);
   else
-    rc = write_and_clear_outbuf (ctx, &outbuf);
-  if (rc)
-    log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
+    {
+      if (padding != -1)
+        rc = print_assuan_status (ctx, "PADDING", "%d", padding);
+      else
+        rc = 0;
+      if (!rc)
+        rc = write_and_clear_outbuf (ctx, &outbuf);
+    }
   xfree (ctrl->server_local->keydesc);
   ctrl->server_local->keydesc = NULL;
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
 static const char hlp_genkey[] =
-  "GENKEY\n"
+  "GENKEY [--no-protection] [--preset] [<cache_nonce>]\n"
   "\n"
   "Generate a new key, store the secret part and return the public\n"
   "part.  Here is an example transaction:\n"
@@ -756,34 +911,52 @@ static const char hlp_genkey[] =
   "  S: D (public-key\n"
   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
   "  S: OK key created\n"
+  "\n"
+  "When the --preset option is used the passphrase for the generated\n"
+  "key will be added to the cache.\n"
   "\n";
 static gpg_error_t
 cmd_genkey (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
+  int no_protection;
   unsigned char *value;
   size_t valuelen;
   membuf_t outbuf;
+  char *cache_nonce = NULL;
+  int opt_preset;
+  char *p;
 
-  (void)line;
+  opt_preset = has_option (line, "--preset");
+  no_protection = has_option (line, "--no-protection");
+  line = skip_options (line);
+
+  p = line;
+  for (p=line; *p && *p != ' ' && *p != '\t'; p++)
+    ;
+  *p = '\0';
+  if (*line)
+    cache_nonce = xtrystrdup (line);
 
   /* First inquire the parameters */
-  rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
+  rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_KEYPARAM);
+  if (!rc)
+    rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
   if (rc)
     return rc;
 
   init_membuf (&outbuf, 512);
 
-  rc = agent_genkey (ctrl, (char*)value, valuelen, &outbuf);
+  rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
+                     opt_preset, &outbuf);
   xfree (value);
   if (rc)
     clear_outbuf (&outbuf);
   else
     rc = write_and_clear_outbuf (ctx, &outbuf);
-  if (rc)
-    log_error ("command genkey failed: %s\n", gpg_strerror (rc));
-  return rc;
+  xfree (cache_nonce);
+  return leave_cmd (ctx, rc);
 }
 
 
@@ -826,9 +999,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
       gcry_sexp_release (s_pkey);
     }
 
-  if (rc)
-    log_error ("command readkey failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
@@ -844,11 +1015,11 @@ static const char hlp_keyinfo[] =
   "information from sshcontrol is always added to the info. Unless --data\n"
   "is given, the information is returned as a status line using the format:\n"
   "\n"
-  "  KEYINFO <keygrip> <type> <serialno> <idstr> - - <fpr> <ttl> <flags>\n"
+  "  KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection> <fpr>\n"
   "\n"
   "KEYGRIP is the keygrip.\n"
   "\n"
-  "TYPE describes the type of the key:\n"
+  "TYPE is describes the type of the key:\n"
   "    'D' - Regular key stored on disk,\n"
   "    'T' - Key is stored on a smartcard (token),\n"
   "    'X' - Unknown type,\n"
@@ -861,6 +1032,14 @@ static const char hlp_keyinfo[] =
   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
   "      is not known a dash is used instead.\n"
   "\n"
+  "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
+  "       If not, a '-' is used instead.\n"
+  "\n"
+  "PROTECTION describes the key protection type:\n"
+  "    'P' - The key is protected with a passphrase,\n"
+  "    'C' - The key is not protected,\n"
+  "    '-' - Unknown protection.\n"
+  "\n"
   "FPR returns the formatted ssh-style fingerprint of the key.  It is only\n"
   "    printed if the option --ssh-fpr has been used.  It defaults to '-'.\n"
   "\n"
@@ -886,6 +1065,9 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
   char *serialno = NULL;
   char *idstr = NULL;
   const char *keytypestr;
+  const char *cached;
+  const char *protectionstr;
+  char *pw;
   int missing_key = 0;
   char ttlbuf[20];
   char flagsbuf[5];
@@ -920,19 +1102,19 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
 
   if (missing_key)
     {
-      keytypestr = "-";
+      protectionstr = "-"; keytypestr = "-";
     }
   else
     {
       switch (keytype)
         {
-        case PRIVATE_KEY_CLEAR: keytypestr = "D";
+        case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
           break;
-        case PRIVATE_KEY_PROTECTED: keytypestr = "D";
+        case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
           break;
-        case PRIVATE_KEY_SHADOWED: keytypestr = "T";
+        case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
           break;
-        default: keytypestr = "X";
+        default: protectionstr = "-"; keytypestr = "X";
           break;
         }
     }
@@ -949,24 +1131,28 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
         }
     }
 
+  /* Here we have a little race by doing the cache check separately
+     from the retrieval function.  Given that the cache flag is only a
+     hint, it should not really matter.  */
+  pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
+  cached = pw ? "1" : "-";
+  xfree (pw);
+
   if (shadow_info)
     {
-      err = parse_shadow_info (shadow_info, &serialno, &idstr);
+      err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL);
       if (err)
         goto leave;
     }
 
-  /* Note that we don't support the CACHED and PROTECTION values as
-     gnupg 2.1 does.  We print '-' instead.  However we support the
-     ssh fingerprint.  */
   if (!data)
     err = agent_write_status (ctrl, "KEYINFO",
                               hexgrip,
                               keytypestr,
                               serialno? serialno : "-",
                               idstr? idstr : "-",
-                              "-",
-                             "-",
+                              cached,
+                             protectionstr,
                               fpr? fpr : "-",
                               ttlbuf,
                               flagsbuf,
@@ -975,14 +1161,13 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
     {
       char *string;
 
-      string = xtryasprintf ("%s %s %s %s - - %s %s %s\n",
+      string = xtryasprintf ("%s %s %s %s %s %s %s %s %s\n",
                              hexgrip, keytypestr,
                              serialno? serialno : "-",
-                             idstr? idstr : "-",
+                             idstr? idstr : "-", cached, protectionstr,
                              fpr? fpr : "-",
                              ttlbuf,
                              flagsbuf);
-
       if (!string)
         err = gpg_error_from_syserror ();
       else
@@ -999,6 +1184,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
 }
 
 
+/* Entry int for the command KEYINFO.  This function handles the
+   command option processing.  For details see hlp_keyinfo above.  */
 static gpg_error_t
 cmd_keyinfo (assuan_context_t ctx, char *line)
 {
@@ -1115,12 +1302,13 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
   if (dir)
     closedir (dir);
   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
-    log_error ("command keyinfo failed: %s\n", gpg_strerror (err));
+    leave_cmd (ctx, err);
   return err;
 }
 
 
 \f
+/* Helper for cmd_get_passphrase.  */
 static int
 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
 {
@@ -1179,12 +1367,11 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
-  const char *pw;
+  char *pw;
   char *response;
   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
   const char *desc2 = _("Please re-enter this passphrase");
   char *p;
-  void *cache_marker;
   int opt_data, opt_check, opt_no_ask, opt_qualbar;
   int opt_repeat = 0;
   char *repeat_errtext = NULL;
@@ -1245,12 +1432,11 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
   if (!strcmp (desc, "X"))
     desc = NULL;
 
-  pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_USER, &cache_marker)
-               : NULL;
+  pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
   if (pw)
     {
       rc = send_back_passphrase (ctx, opt_data, pw);
-      agent_unlock_cache_entry (&cache_marker);
+      xfree (pw);
     }
   else if (opt_no_ask)
     rc = gpg_error (GPG_ERR_NO_DATA);
@@ -1269,8 +1455,8 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
 
     next_try:
       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
-                                repeat_errtext? repeat_errtext:errtext,
-                                opt_qualbar, cacheid, CACHE_MODE_USER);
+                                 repeat_errtext? repeat_errtext:errtext,
+                                 opt_qualbar);
       xfree (repeat_errtext);
       repeat_errtext = NULL;
       if (!rc)
@@ -1287,8 +1473,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
               char *response2;
 
               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
-                                         errtext, 0,
-                                        cacheid, CACHE_MODE_USER);
+                                         errtext, 0);
               if (rc)
                 break;
               if (strcmp (response2, response))
@@ -1316,23 +1501,26 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
         }
     }
 
-  if (rc)
-    log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
 static const char hlp_clear_passphrase[] =
-  "CLEAR_PASSPHRASE <cache_id>\n"
+  "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
   "\n"
   "may be used to invalidate the cache entry for a passphrase.  The\n"
-  "function returns with OK even when there is no cached passphrase.";
+  "function returns with OK even when there is no cached passphrase.\n"
+  "The --mode=normal option is used to clear an entry for a cacheid\n"
+  "added by the agent.\n";
 static gpg_error_t
 cmd_clear_passphrase (assuan_context_t ctx, char *line)
 {
-  ctrl_t ctrl = assuan_get_pointer (ctx);
   char *cacheid = NULL;
   char *p;
+  int opt_normal;
+
+  opt_normal = has_option (line, "--mode=normal");
+  line = skip_options (line);
 
   /* parse the stuff */
   for (p=line; *p == ' '; p++)
@@ -1344,10 +1532,8 @@ cmd_clear_passphrase (assuan_context_t ctx, char *line)
   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
 
-  agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0);
-
-  agent_clear_passphrase (ctrl, cacheid, CACHE_MODE_USER);
-
+  agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
+                   NULL, 0);
   return 0;
 }
 
@@ -1393,9 +1579,7 @@ cmd_get_confirmation (assuan_context_t ctx, char *line)
     plus_to_blank (desc);
 
   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
-  if (rc)
-    log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
@@ -1412,77 +1596,178 @@ cmd_learn (assuan_context_t ctx, char *line)
   int rc;
 
   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
-  if (rc)
-    log_error ("command learn failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
 \f
 static const char hlp_passwd[] =
-  "PASSWD <hexstring_with_keygrip>\n"
+  "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset] <hexkeygrip>\n"
   "\n"
-  "Change the passphrase/PIN for the key identified by keygrip in LINE.";
+  "Change the passphrase/PIN for the key identified by keygrip in LINE. When\n"
+  "--preset is used then the new passphrase will be added to the cache.\n";
 static gpg_error_t
 cmd_passwd (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
-  int rc;
+  gpg_error_t err;
+  int c;
+  char *cache_nonce = NULL;
+  char *passwd_nonce = NULL;
   unsigned char grip[20];
   gcry_sexp_t s_skey = NULL;
   unsigned char *shadow_info = NULL;
+  char *passphrase = NULL;
+  char *pend;
+  int opt_preset;
 
-  rc = parse_keygrip (ctx, line, grip);
-  if (rc)
+  opt_preset = has_option (line, "--preset");
+  cache_nonce = option_value (line, "--cache-nonce");
+  if (cache_nonce)
+    {
+      for (pend = cache_nonce; *pend && !spacep (pend); pend++)
+        ;
+      c = *pend;
+      *pend = '\0';
+      cache_nonce = xtrystrdup (cache_nonce);
+      *pend = c;
+      if (!cache_nonce)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+    }
+
+  passwd_nonce = option_value (line, "--passwd-nonce");
+  if (passwd_nonce)
+    {
+      for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
+        ;
+      c = *pend;
+      *pend = '\0';
+      passwd_nonce = xtrystrdup (passwd_nonce);
+      *pend = c;
+      if (!passwd_nonce)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+    }
+
+  line = skip_options (line);
+
+  err = parse_keygrip (ctx, line, grip);
+  if (err)
     goto leave;
 
   ctrl->in_passwd++;
-  rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
-                            grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
-                            &s_skey);
-  if (rc)
+  err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
+                             grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
+                             &s_skey, &passphrase);
+  if (err)
     ;
-  else if (!s_skey)
+  else if (shadow_info)
     {
       log_error ("changing a smartcard PIN is not yet supported\n");
-      rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     }
   else
-    rc = agent_protect_and_store (ctrl, s_skey);
+    {
+      char *newpass = NULL;
+
+      if (passwd_nonce)
+        newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
+      err = agent_protect_and_store (ctrl, s_skey, &newpass);
+      if (!err && passphrase)
+        {
+          /* A passphrase existed on the old key and the change was
+             successful.  Return a nonce for that old passphrase to
+             let the caller try to unprotect the other subkeys with
+             the same key.  */
+          if (!cache_nonce)
+            {
+              char buf[12];
+              gcry_create_nonce (buf, 12);
+              cache_nonce = bin2hex (buf, 12, NULL);
+            }
+          if (cache_nonce
+              && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
+                                   passphrase, CACHE_TTL_NONCE))
+            {
+              assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
+              xfree (ctrl->server_local->last_cache_nonce);
+              ctrl->server_local->last_cache_nonce = cache_nonce;
+              cache_nonce = NULL;
+            }
+          if (newpass)
+            {
+              /* If we have a new passphrase (which might be empty) we
+                 store it under a passwd nonce so that the caller may
+                 send that nonce again to use it for another key. */
+              if (!passwd_nonce)
+                {
+                  char buf[12];
+                  gcry_create_nonce (buf, 12);
+                  passwd_nonce = bin2hex (buf, 12, NULL);
+                }
+              if (passwd_nonce
+                  && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
+                                       newpass, CACHE_TTL_NONCE))
+                {
+                  assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
+                  xfree (ctrl->server_local->last_passwd_nonce);
+                  ctrl->server_local->last_passwd_nonce = passwd_nonce;
+                  passwd_nonce = NULL;
+                }
+            }
+        }
+      if (!err && opt_preset)
+      {
+         char hexgrip[40+1];
+         bin2hex(grip, 20, hexgrip);
+         err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
+                                 ctrl->cache_ttl_opt_preset);
+      }
+      xfree (newpass);
+    }
   ctrl->in_passwd--;
 
   xfree (ctrl->server_local->keydesc);
   ctrl->server_local->keydesc = NULL;
 
  leave:
+  xfree (passphrase);
   gcry_sexp_release (s_skey);
   xfree (shadow_info);
-  if (rc)
-    log_error ("command passwd failed: %s\n", gpg_strerror (rc));
-  return rc;
+  xfree (cache_nonce);
+  return leave_cmd (ctx, err);
 }
 
 
 static const char hlp_preset_passphrase[] =
-  "PRESET_PASSPHRASE <string_or_keygrip> <timeout> <hexstring>\n"
+  "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
   "\n"
   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
   "to passwd for the given time, where -1 means infinite and 0 means\n"
   "the default (currently only a timeout of -1 is allowed, which means\n"
   "to never expire it).  If passwd is not provided, ask for it via the\n"
-  "pinentry module.";
+  "pinentry module unless --inquire is passed in which case the passphrase\n"
+  "is retrieved from the client via a server inquire.\n";
 static gpg_error_t
 cmd_preset_passphrase (assuan_context_t ctx, char *line)
 {
   int rc;
   char *grip_clear = NULL;
-  char *passphrase = NULL;
+  unsigned char *passphrase = NULL;
   int ttl;
   size_t len;
+  int opt_inquire;
 
   if (!opt.allow_preset_passphrase)
     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
 
+  opt_inquire = has_option (line, "--inquire");
+  line = skip_options (line);
   grip_clear = line;
   while (*line && (*line != ' ' && *line != '\t'))
     line++;
@@ -1513,21 +1798,40 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line)
      required.  */
   if (*line)
     {
+      if (opt_inquire)
+        {
+         rc = set_error (GPG_ERR_ASS_PARAMETER,
+                          "both --inquire and passphrase specified");
+         goto leave;
+       }
+
       /* Do in-place conversion.  */
       passphrase = line;
       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
     }
+  else if (opt_inquire)
+    {
+      /* Note that the passphrase will be truncated at any null byte and the
+       * limit is 480 characters. */
+      size_t maxlen = 480;
+
+      rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%zu", maxlen);
+      if (!rc)
+       rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, maxlen);
+    }
   else
     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
 
   if (!rc)
-    rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
-
-  if (rc)
-    log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc));
+    {
+      rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
+      if (opt_inquire)
+       xfree (passphrase);
+    }
 
-  return rc;
+leave:
+  return leave_cmd (ctx, rc);
 }
 
 
@@ -1550,6 +1854,587 @@ cmd_scd (assuan_context_t ctx, char *line)
 
 
 \f
+static const char hlp_keywrap_key[] =
+  "KEYWRAP_KEY [--clear] <mode>\n"
+  "\n"
+  "Return a key to wrap another key.  For now the key is returned\n"
+  "verbatim and and thus makes not much sense because an eavesdropper on\n"
+  "the gpg-agent connection will see the key as well as the wrapped key.\n"
+  "However, this function may either be equipped with a public key\n"
+  "mechanism or not used at all if the key is a pre-shared key.  In any\n"
+  "case wrapping the import and export of keys is a requirement for\n"
+  "certain cryptographic validations and thus useful.  The key persists\n"
+  "a RESET command but may be cleared using the option --clear.\n"
+  "\n"
+  "Supported modes are:\n"
+  "  --import  - Return a key to import a key into gpg-agent\n"
+  "  --export  - Return a key to export a key from gpg-agent";
+static gpg_error_t
+cmd_keywrap_key (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+  int clearopt = has_option (line, "--clear");
+
+
+  assuan_begin_confidential (ctx);
+  if (has_option (line, "--import"))
+    {
+      xfree (ctrl->server_local->import_key);
+      if (clearopt)
+        ctrl->server_local->import_key = NULL;
+      else if (!(ctrl->server_local->import_key =
+                 gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
+        err = gpg_error_from_syserror ();
+      else
+        err = assuan_send_data (ctx, ctrl->server_local->import_key,
+                                KEYWRAP_KEYSIZE);
+    }
+  else if (has_option (line, "--export"))
+    {
+      xfree (ctrl->server_local->export_key);
+      if (clearopt)
+        ctrl->server_local->export_key = NULL;
+      else if (!(ctrl->server_local->export_key =
+            gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
+        err = gpg_error_from_syserror ();
+      else
+        err = assuan_send_data (ctx, ctrl->server_local->export_key,
+                                KEYWRAP_KEYSIZE);
+    }
+  else
+    err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
+  assuan_end_confidential (ctx);
+
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_import_key[] =
+  "IMPORT_KEY [--unattended] [<cache_nonce>]\n"
+  "\n"
+  "Import a secret key into the key store.  The key is expected to be\n"
+  "encrypted using the current session's key wrapping key (cf. command\n"
+  "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
+  "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
+  "key data.  The unwrapped key must be a canonical S-expression.  The\n"
+  "option --unattended tries to import the key as-is without any\n"
+  "re-encryption";
+static gpg_error_t
+cmd_import_key (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  int opt_unattended;
+  unsigned char *wrappedkey = NULL;
+  size_t wrappedkeylen;
+  gcry_cipher_hd_t cipherhd = NULL;
+  unsigned char *key = NULL;
+  size_t keylen, realkeylen;
+  char *passphrase = NULL;
+  unsigned char *finalkey = NULL;
+  size_t finalkeylen;
+  unsigned char grip[20];
+  gcry_sexp_t openpgp_sexp = NULL;
+  char *cache_nonce = NULL;
+  char *p;
+
+  if (!ctrl->server_local->import_key)
+    {
+      err = gpg_error (GPG_ERR_MISSING_KEY);
+      goto leave;
+    }
+
+  opt_unattended = has_option (line, "--unattended");
+  line = skip_options (line);
+
+  p = line;
+  for (p=line; *p && *p != ' ' && *p != '\t'; p++)
+    ;
+  *p = '\0';
+  if (*line)
+    cache_nonce = xtrystrdup (line);
+
+  assuan_begin_confidential (ctx);
+  err = assuan_inquire (ctx, "KEYDATA",
+                        &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
+  assuan_end_confidential (ctx);
+  if (err)
+    goto leave;
+  if (wrappedkeylen < 24)
+    {
+      err = gpg_error (GPG_ERR_INV_LENGTH);
+      goto leave;
+    }
+  keylen = wrappedkeylen - 8;
+  key = xtrymalloc_secure (keylen);
+  if (!key)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
+                          GCRY_CIPHER_MODE_AESWRAP, 0);
+  if (err)
+    goto leave;
+  err = gcry_cipher_setkey (cipherhd,
+                            ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
+  if (err)
+    goto leave;
+  err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
+  if (err)
+    goto leave;
+  gcry_cipher_close (cipherhd);
+  cipherhd = NULL;
+  xfree (wrappedkey);
+  wrappedkey = NULL;
+
+  realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
+  if (!realkeylen)
+    goto leave; /* Invalid canonical encoded S-expression.  */
+
+  err = keygrip_from_canon_sexp (key, realkeylen, grip);
+  if (err)
+    {
+      /* This might be due to an unsupported S-expression format.
+         Check whether this is openpgp-private-key and trigger that
+         import code.  */
+      if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
+        {
+          const char *tag;
+          size_t taglen;
+
+          tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
+          if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
+            ;
+          else
+            {
+              gcry_sexp_release (openpgp_sexp);
+              openpgp_sexp = NULL;
+            }
+        }
+      if (!openpgp_sexp)
+        goto leave; /* Note that ERR is still set.  */
+    }
+
+
+  if (openpgp_sexp)
+    {
+      /* In most cases the key is encrypted and thus the conversion
+         function from the OpenPGP format to our internal format will
+         ask for a passphrase.  That passphrase will be returned and
+         used to protect the key using the same code as for regular
+         key import. */
+
+      xfree (key);
+      key = NULL;
+      err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
+                                  ctrl->server_local->keydesc, cache_nonce,
+                                  &key, opt_unattended? NULL : &passphrase);
+      if (err)
+        goto leave;
+      realkeylen = gcry_sexp_canon_len (key, 0, NULL, &err);
+      if (!realkeylen)
+        goto leave; /* Invalid canonical encoded S-expression.  */
+      if (passphrase)
+        {
+          assert (!opt_unattended);
+          if (!cache_nonce)
+            {
+              char buf[12];
+              gcry_create_nonce (buf, 12);
+              cache_nonce = bin2hex (buf, 12, NULL);
+            }
+          if (cache_nonce
+              && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
+                                   passphrase, CACHE_TTL_NONCE))
+            assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
+        }
+    }
+  else if (opt_unattended)
+    {
+      err = set_error (GPG_ERR_ASS_PARAMETER,
+                       "\"--unattended\" may only be used with OpenPGP keys");
+      goto leave;
+    }
+  else
+    {
+      if (!agent_key_available (grip))
+        err = gpg_error (GPG_ERR_EEXIST);
+      else
+        {
+          char *prompt = xtryasprintf
+            (_("Please enter the passphrase to protect the "
+               "imported object within the %s system."), GNUPG_NAME);
+          if (!prompt)
+            err = gpg_error_from_syserror ();
+          else
+            err = agent_ask_new_passphrase (ctrl, prompt, &passphrase);
+          xfree (prompt);
+        }
+      if (err)
+        goto leave;
+    }
+
+  if (passphrase)
+    {
+      err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
+                           ctrl->s2k_count);
+      if (!err)
+        err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
+    }
+  else
+    err = agent_write_private_key (grip, key, realkeylen, 0);
+
+ leave:
+  gcry_sexp_release (openpgp_sexp);
+  xfree (finalkey);
+  xfree (passphrase);
+  xfree (key);
+  gcry_cipher_close (cipherhd);
+  xfree (wrappedkey);
+  xfree (cache_nonce);
+  xfree (ctrl->server_local->keydesc);
+  ctrl->server_local->keydesc = NULL;
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_export_key[] =
+  "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
+  "\n"
+  "Export a secret key from the key store.  The key will be encrypted\n"
+  "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
+  "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
+  "prior to using this command.  The function takes the keygrip as argument.\n";
+static gpg_error_t
+cmd_export_key (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  unsigned char grip[20];
+  gcry_sexp_t s_skey = NULL;
+  unsigned char *key = NULL;
+  size_t keylen;
+  gcry_cipher_hd_t cipherhd = NULL;
+  unsigned char *wrappedkey = NULL;
+  size_t wrappedkeylen;
+  int openpgp;
+  char *cache_nonce;
+  char *passphrase = NULL;
+  unsigned char *shadow_info = NULL;
+  char *pend;
+  int c;
+
+  openpgp = has_option (line, "--openpgp");
+  cache_nonce = option_value (line, "--cache-nonce");
+  if (cache_nonce)
+    {
+      for (pend = cache_nonce; *pend && !spacep (pend); pend++)
+        ;
+      c = *pend;
+      *pend = '\0';
+      cache_nonce = xtrystrdup (cache_nonce);
+      *pend = c;
+      if (!cache_nonce)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+    }
+  line = skip_options (line);
+
+  if (!ctrl->server_local->export_key)
+    {
+      err = set_error (GPG_ERR_MISSING_KEY, "did you run KEYWRAP_KEY ?");
+      goto leave;
+    }
+
+  err = parse_keygrip (ctx, line, grip);
+  if (err)
+    goto leave;
+
+  if (agent_key_available (grip))
+    {
+      err = gpg_error (GPG_ERR_NO_SECKEY);
+      goto leave;
+    }
+
+  /* Get the key from the file.  With the openpgp flag we also ask for
+     the passphrase so that we can use it to re-encrypt it.  */
+  err = agent_key_from_file (ctrl, cache_nonce,
+                             ctrl->server_local->keydesc, grip,
+                             &shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey,
+                             openpgp ? &passphrase : NULL);
+  if (err)
+    goto leave;
+  if (shadow_info)
+    {
+      /* Key is on a smartcard.  */
+      err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
+      goto leave;
+    }
+
+  if (openpgp)
+    {
+      /* The openpgp option changes the key format into the OpenPGP
+         key transfer format.  The result is already a padded
+         canonical S-expression.  */
+      if (!passphrase)
+        {
+          err = agent_ask_new_passphrase
+            (ctrl, _("This key (or subkey) is not protected with a passphrase."
+                     "  Please enter a new passphrase to export it."),
+             &passphrase);
+          if (err)
+            goto leave;
+        }
+      err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
+      if (!err && passphrase)
+        {
+          if (!cache_nonce)
+            {
+              char buf[12];
+              gcry_create_nonce (buf, 12);
+              cache_nonce = bin2hex (buf, 12, NULL);
+            }
+          if (cache_nonce
+              && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
+                                   passphrase, CACHE_TTL_NONCE))
+            {
+              assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
+              xfree (ctrl->server_local->last_cache_nonce);
+              ctrl->server_local->last_cache_nonce = cache_nonce;
+              cache_nonce = NULL;
+            }
+        }
+    }
+  else
+    {
+      /* Convert into a canonical S-expression and wrap that.  */
+      err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
+    }
+  if (err)
+    goto leave;
+  gcry_sexp_release (s_skey);
+  s_skey = NULL;
+
+  err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
+                          GCRY_CIPHER_MODE_AESWRAP, 0);
+  if (err)
+    goto leave;
+  err = gcry_cipher_setkey (cipherhd,
+                            ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
+  if (err)
+    goto leave;
+
+  wrappedkeylen = keylen + 8;
+  wrappedkey = xtrymalloc (wrappedkeylen);
+  if (!wrappedkey)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
+  if (err)
+    goto leave;
+  xfree (key);
+  key = NULL;
+  gcry_cipher_close (cipherhd);
+  cipherhd = NULL;
+
+  assuan_begin_confidential (ctx);
+  err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
+  assuan_end_confidential (ctx);
+
+
+ leave:
+  xfree (cache_nonce);
+  xfree (passphrase);
+  xfree (wrappedkey);
+  gcry_cipher_close (cipherhd);
+  xfree (key);
+  gcry_sexp_release (s_skey);
+  xfree (ctrl->server_local->keydesc);
+  ctrl->server_local->keydesc = NULL;
+  xfree (shadow_info);
+
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_delete_key[] =
+  "DELETE_KEY <hexstring_with_keygrip>\n"
+  "\n"
+  "Delete a secret key from the key store.\n"
+  "As safeguard the agent asks the user for confirmation.\n";
+static gpg_error_t
+cmd_delete_key (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  unsigned char grip[20];
+
+  line = skip_options (line);
+
+  err = parse_keygrip (ctx, line, grip);
+  if (err)
+    goto leave;
+
+  err = agent_delete_key (ctrl, ctrl->server_local->keydesc, grip);
+  if (err)
+    goto leave;
+
+ leave:
+  xfree (ctrl->server_local->keydesc);
+  ctrl->server_local->keydesc = NULL;
+
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_keytocard[] =
+  "KEYTOCARD [--force] <hexstring_with_keygrip> <serialno> <id> <timestamp>\n"
+  "\n";
+static gpg_error_t
+cmd_keytocard (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  int force;
+  gpg_error_t err = 0;
+  unsigned char grip[20];
+  gcry_sexp_t s_skey = NULL;
+  gcry_sexp_t s_pkey = NULL;
+  unsigned char *keydata;
+  size_t keydatalen, timestamplen;
+  const char *serialno, *timestamp_str, *id;
+  unsigned char *shadow_info = NULL;
+  unsigned char *shdkey;
+  time_t timestamp;
+
+  force = has_option (line, "--force");
+  line = skip_options (line);
+
+  err = parse_keygrip (ctx, line, grip);
+  if (err)
+    return err;
+
+  if (agent_key_available (grip))
+    return gpg_error (GPG_ERR_NO_SECKEY);
+
+  line += 40;
+  while (*line && (*line == ' ' || *line == '\t'))
+    line++;
+  serialno = line;
+  while (*line && (*line != ' ' && *line != '\t'))
+    line++;
+  if (!*line)
+    return gpg_error (GPG_ERR_MISSING_VALUE);
+  *line = '\0';
+  line++;
+  while (*line && (*line == ' ' || *line == '\t'))
+    line++;
+  id = line;
+  while (*line && (*line != ' ' && *line != '\t'))
+    line++;
+  if (!*line)
+    return gpg_error (GPG_ERR_MISSING_VALUE);
+  *line = '\0';
+  line++;
+  while (*line && (*line == ' ' || *line == '\t'))
+    line++;
+  timestamp_str = line;
+  while (*line && (*line != ' ' && *line != '\t'))
+    line++;
+  if (*line)
+    *line = '\0';
+  timestamplen = line - timestamp_str;
+  if (timestamplen != 15)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
+                             &shadow_info, CACHE_MODE_IGNORE, NULL,
+                             &s_skey, NULL);
+  if (err)
+    {
+      xfree (shadow_info);
+      return err;
+    }
+  if (shadow_info)
+    {
+      /* Key is on a smartcard already.  */
+      xfree (shadow_info);
+      gcry_sexp_release (s_skey);
+      return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
+    }
+
+  keydatalen =  gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
+  keydata = xtrymalloc_secure (keydatalen + 30);
+  if (keydata == NULL)
+    {
+      gcry_sexp_release (s_skey);
+      return gpg_error_from_syserror ();
+    }
+
+  gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
+  gcry_sexp_release (s_skey);
+  keydatalen--;                        /* Decrement for last '\0'.  */
+  /* Add timestamp "created-at" in the private key */
+  timestamp = isotime2epoch (timestamp_str);
+  snprintf (keydata+keydatalen-1, 30, "(10:created-at10:%010lu))", timestamp);
+  keydatalen += 10 + 19 - 1;
+  err = divert_writekey (ctrl, force, serialno, id, keydata, keydatalen);
+  if (err)
+    {
+      xfree (keydata);
+      goto leave;
+    }
+  xfree (keydata);
+
+  err = agent_public_key_from_file (ctrl, grip, &s_pkey);
+  if (err)
+    goto leave;
+
+  shadow_info = make_shadow_info (serialno, id);
+  if (!shadow_info)
+    {
+      err = gpg_error (GPG_ERR_ENOMEM);
+      gcry_sexp_release (s_pkey);
+      goto leave;
+    }
+  keydatalen = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+  keydata = xtrymalloc (keydatalen);
+  if (keydata == NULL)
+    {
+      err = gpg_error_from_syserror ();
+      gcry_sexp_release (s_pkey);
+      goto leave;
+    }
+  gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
+  gcry_sexp_release (s_pkey);
+  err = agent_shadow_key (keydata, shadow_info, &shdkey);
+  xfree (keydata);
+  xfree (shadow_info);
+  if (err)
+    {
+      log_error ("shadowing the key failed: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  keydatalen = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
+  err = agent_write_private_key (grip, shdkey, keydatalen, 1);
+  xfree (shdkey);
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+\f
 static const char hlp_getval[] =
   "GETVAL <key>\n"
   "\n"
@@ -1588,9 +2473,7 @@ cmd_getval (assuan_context_t ctx, char *line)
   else
     return gpg_error (GPG_ERR_NO_DATA);
 
-  if (rc)
-    log_error ("command getval failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
@@ -1673,9 +2556,7 @@ cmd_putval (assuan_context_t ctx, char *line)
         }
     }
 
-  if (rc)
-    log_error ("command putval failed: %s\n", gpg_strerror (rc));
-  return rc;
+  return leave_cmd (ctx, rc);
 }
 
 
@@ -1745,8 +2626,7 @@ cmd_updatestartuptty (assuan_context_t ctx, char *line)
 static const char hlp_killagent[] =
   "KILLAGENT\n"
   "\n"
-  "If the agent has been started using a standard socket\n"
-  "we allow a client to stop the agent.";
+  "Stop the agent.";
 static gpg_error_t
 cmd_killagent (assuan_context_t ctx, char *line)
 {
@@ -1754,11 +2634,9 @@ cmd_killagent (assuan_context_t ctx, char *line)
 
   (void)line;
 
-  if (!opt.use_standard_socket)
-    return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
-
   ctrl->server_local->stopme = 1;
-  return gpg_error (GPG_ERR_EOF);
+  assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
+  return 0;
 }
 
 
@@ -1790,10 +2668,11 @@ static const char hlp_getinfo[] =
   "  socket_name - Return the name of the socket.\n"
   "  ssh_socket_name - Return the name of the ssh socket.\n"
   "  scd_running - Return OK if the SCdaemon is already running.\n"
+  "  s2k_count   - Return the calibrated S2K count.\n"
   "  std_session_env - List the standard session environment.\n"
   "  std_startup_env - List the standard startup environment.\n"
   "  cmd_has_option\n"
-  "              - Returns OK if the command CMD implements the option OPT.";
+  "              - Returns OK if the command CMD implements the option OPT\n.";
 static gpg_error_t
 cmd_getinfo (assuan_context_t ctx, char *line)
 {
@@ -1908,13 +2787,22 @@ cmd_getinfo (assuan_context_t ctx, char *line)
 
 
 \f
+/* This function is called by Libassuan to parse the OPTION command.
+   It has been registered similar to the other Assuan commands.  */
 static gpg_error_t
 option_handler (assuan_context_t ctx, const char *key, const char *value)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err = 0;
 
-  if (!strcmp (key, "putenv"))
+  if (!strcmp (key, "agent-awareness"))
+    {
+      /* The value is a version string telling us of which agent
+         version the caller is aware of.  */
+      ctrl->server_local->allow_fully_canceled =
+        gnupg_compare_version (value, "2.1.0");
+    }
+  else if (!strcmp (key, "putenv"))
     {
       /* Change the session's environment to be used for the
          Pinentry.  Valid values are:
@@ -1966,6 +2854,28 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
   else if (!strcmp (key, "allow-pinentry-notify"))
     ctrl->server_local->allow_pinentry_notify = 1;
+  else if (!strcmp (key, "pinentry-mode"))
+    {
+      int tmp = parse_pinentry_mode (value);
+      if (tmp == -1)
+        err = gpg_error (GPG_ERR_INV_VALUE);
+      else if (tmp == PINENTRY_MODE_LOOPBACK && !opt.allow_loopback_pinentry)
+        err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      else
+        ctrl->pinentry_mode = tmp;
+    }
+  else if (!strcmp (key, "cache-ttl-opt-preset"))
+    {
+      ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
+    }
+  else if (!strcmp (key, "s2k-count"))
+    {
+      ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
+      if (ctrl->s2k_count && ctrl->s2k_count < 65536)
+        {
+         ctrl->s2k_count = 0;
+        }
+    }
   else
     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
 
@@ -2030,7 +2940,8 @@ command_has_option (const char *cmd, const char *cmdopt)
 }
 
 
-/* Tell the assuan library about our commands */
+/* Tell Libassuan about our commands.  Also register the other Assuan
+   handlers. */
 static int
 register_commands (assuan_context_t ctx)
 {
@@ -2062,12 +2973,17 @@ register_commands (assuan_context_t ctx)
     { "INPUT",          NULL },
     { "OUTPUT",         NULL },
     { "SCD",            cmd_scd,       hlp_scd },
+    { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
+    { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
+    { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
+    { "DELETE_KEY",     cmd_delete_key, hlp_delete_key },
     { "GETVAL",         cmd_getval,    hlp_getval },
     { "PUTVAL",         cmd_putval,    hlp_putval },
     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
+    { "KEYTOCARD",      cmd_keytocard, hlp_keytocard },
     { NULL }
   };
   int i, rc;
@@ -2138,7 +3054,6 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
   assuan_set_pointer (ctx, ctrl);
   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
   ctrl->server_local->assuan_ctx = ctx;
-  ctrl->server_local->message_fd = -1;
   ctrl->server_local->use_cache_for_signing = 1;
   ctrl->digest.raw_value = 0;
 
@@ -2165,6 +3080,9 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
         }
     }
 
+  /* Reset the nonce caches.  */
+  clear_nonce_cache (ctrl);
+
   /* Reset the SCD if needed. */
   agent_reset_scd (ctrl);
 
@@ -2173,9 +3091,32 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
 
   /* Cleanup.  */
   assuan_release (ctx);
+  xfree (ctrl->server_local->keydesc);
+  xfree (ctrl->server_local->import_key);
+  xfree (ctrl->server_local->export_key);
   if (ctrl->server_local->stopme)
     agent_exit (0);
   xfree (ctrl->server_local);
   ctrl->server_local = NULL;
 }
 
+
+/* Helper for the pinentry loopback mode.  It merely passes the
+   parameters on to the client.  */
+gpg_error_t
+pinentry_loopback(ctrl_t ctrl, const char *keyword,
+                  unsigned char **buffer, size_t *size,
+                  size_t max_length)
+{
+  gpg_error_t rc;
+  assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+
+  rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%zu", max_length);
+  if (rc)
+    return rc;
+
+  assuan_begin_confidential (ctx);
+  rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
+  assuan_end_confidential (ctx);
+  return rc;
+}
diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
new file mode 100644 (file)
index 0000000..671dd4c
--- /dev/null
@@ -0,0 +1,1368 @@
+/* cvt-openpgp.c - Convert an OpenPGP key to our internal format.
+ * Copyright (C) 1998-2002, 2006, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "agent.h"
+#include "i18n.h"
+#include "cvt-openpgp.h"
+
+
+/* Helper to pass data via the callback to do_unprotect. */
+struct try_do_unprotect_arg_s
+{
+  int  is_v4;
+  int  is_protected;
+  int  pubkey_algo;
+  const char *curve;
+  int  protect_algo;
+  char *iv;
+  int  ivlen;
+  int  s2k_mode;
+  int  s2k_algo;
+  byte *s2k_salt;
+  u32  s2k_count;
+  u16 desired_csum;
+  gcry_mpi_t *skey;
+  size_t skeysize;
+  int skeyidx;
+  gcry_sexp_t *r_key;
+};
+
+
+
+/* Compute the keygrip from the public key and store it at GRIP.  */
+static gpg_error_t
+get_keygrip (int pubkey_algo, const char *curve, gcry_mpi_t *pkey,
+             unsigned char *grip)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_pkey = NULL;
+
+  switch (pubkey_algo)
+    {
+    case GCRY_PK_DSA:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                             pkey[0], pkey[1], pkey[2], pkey[3]);
+      break;
+
+    case GCRY_PK_ELG:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(elg(p%m)(g%m)(y%m)))",
+                             pkey[0], pkey[1], pkey[2]);
+      break;
+
+    case GCRY_PK_RSA:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
+      break;
+
+    case GCRY_PK_ECC:
+      if (!curve)
+        err = gpg_error (GPG_ERR_BAD_SECKEY);
+      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
+        err = gcry_sexp_build (&s_pkey, NULL,
+                               "(public-key(ecc(curve %s)(flags eddsa)(q%m)))",
+                               "Ed25519", pkey[0]);
+      else
+        err = gcry_sexp_build (&s_pkey, NULL,
+                               "(public-key(ecc(curve %s)(q%m)))",
+                               curve, pkey[0]);
+      break;
+
+    default:
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      break;
+    }
+
+  if (!err && !gcry_pk_get_keygrip (s_pkey, grip))
+    err = gpg_error (GPG_ERR_INTERNAL);
+
+  gcry_sexp_release (s_pkey);
+  return err;
+}
+
+
+/* Convert a secret key given as algorithm id and an array of key
+   parameters into our s-expression based format.  Note that
+   PUBKEY_ALGO has an gcrypt algorithm number. */
+static gpg_error_t
+convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
+                    const char *curve)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_skey = NULL;
+
+  *r_key = NULL;
+
+  switch (pubkey_algo)
+    {
+    case GCRY_PK_DSA:
+      err = gcry_sexp_build (&s_skey, NULL,
+                             "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
+                             skey[0], skey[1], skey[2], skey[3], skey[4]);
+      break;
+
+    case GCRY_PK_ELG:
+    case GCRY_PK_ELG_E:
+      err = gcry_sexp_build (&s_skey, NULL,
+                             "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
+                             skey[0], skey[1], skey[2], skey[3]);
+      break;
+
+
+    case GCRY_PK_RSA:
+    case GCRY_PK_RSA_E:
+    case GCRY_PK_RSA_S:
+      err = gcry_sexp_build (&s_skey, NULL,
+                             "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
+                             skey[0], skey[1], skey[2], skey[3], skey[4],
+                             skey[5]);
+      break;
+
+    case GCRY_PK_ECC:
+      if (!curve)
+        err = gpg_error (GPG_ERR_BAD_SECKEY);
+      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
+        {
+          /* Do not store the OID as name but the real name and the
+             EdDSA flag.  */
+          err = gcry_sexp_build (&s_skey, NULL,
+                                 "(private-key(ecc(curve%s)(flags eddsa)"
+                                 "(q%m)(d%m)))",
+                                 "Ed25519", skey[0], skey[1]);
+        }
+      else
+        err = gcry_sexp_build (&s_skey, NULL,
+                               "(private-key(ecc(curve%s)(q%m)(d%m)))",
+                               curve, skey[0], skey[1]);
+      break;
+
+    default:
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      break;
+    }
+
+  if (!err)
+    *r_key = s_skey;
+  return err;
+}
+
+
+/* Convert a secret key given as algorithm id, an array of key
+   parameters, and an S-expression of the original OpenPGP transfer
+   key into our s-expression based format.  This is a variant of
+   convert_secret_key which is used for the openpgp-native protection
+   mode.  Note that PUBKEY_ALGO has an gcrypt algorithm number. */
+static gpg_error_t
+convert_transfer_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
+                      const char *curve, gcry_sexp_t transfer_key)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_skey = NULL;
+
+  *r_key = NULL;
+
+  switch (pubkey_algo)
+    {
+    case GCRY_PK_DSA:
+      err = gcry_sexp_build
+        (&s_skey, NULL,
+         "(protected-private-key(dsa(p%m)(q%m)(g%m)(y%m)"
+         "(protected openpgp-native%S)))",
+         skey[0], skey[1], skey[2], skey[3], transfer_key);
+      break;
+
+    case GCRY_PK_ELG:
+      err = gcry_sexp_build
+        (&s_skey, NULL,
+         "(protected-private-key(elg(p%m)(g%m)(y%m)"
+         "(protected openpgp-native%S)))",
+         skey[0], skey[1], skey[2], transfer_key);
+      break;
+
+
+    case GCRY_PK_RSA:
+      err = gcry_sexp_build
+        (&s_skey, NULL,
+         "(protected-private-key(rsa(n%m)(e%m)"
+         "(protected openpgp-native%S)))",
+         skey[0], skey[1], transfer_key );
+      break;
+
+    case GCRY_PK_ECC:
+      if (!curve)
+        err = gpg_error (GPG_ERR_BAD_SECKEY);
+      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
+        {
+          /* Do not store the OID as name but the real name and the
+             EdDSA flag.  */
+          err = gcry_sexp_build
+            (&s_skey, NULL,
+             "(protected-private-key(ecc(curve%s)(flags eddsa)(q%m)"
+             "(protected openpgp-native%S)))",
+             "Ed25519", skey[0], transfer_key);
+        }
+      else
+        err = gcry_sexp_build
+          (&s_skey, NULL,
+           "(protected-private-key(ecc(curve%s)(q%m)"
+           "(protected openpgp-native%S)))",
+           curve, skey[0], transfer_key);
+      break;
+
+    default:
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      break;
+    }
+
+  if (!err)
+    *r_key = s_skey;
+  return err;
+}
+
+
+/* Hash the passphrase and set the key. */
+static gpg_error_t
+hash_passphrase_and_set_key (const char *passphrase,
+                             gcry_cipher_hd_t hd, int protect_algo,
+                             int s2k_mode, int s2k_algo,
+                             byte *s2k_salt, u32 s2k_count)
+{
+  gpg_error_t err;
+  unsigned char *key;
+  size_t keylen;
+
+  keylen = gcry_cipher_get_algo_keylen (protect_algo);
+  if (!keylen)
+    return gpg_error (GPG_ERR_INTERNAL);
+
+  key = xtrymalloc_secure (keylen);
+  if (!key)
+    return gpg_error_from_syserror ();
+
+  err = s2k_hash_passphrase (passphrase,
+                             s2k_algo, s2k_mode, s2k_salt, s2k_count,
+                             key, keylen);
+  if (!err)
+    err = gcry_cipher_setkey (hd, key, keylen);
+
+  xfree (key);
+  return err;
+}
+
+
+static u16
+checksum (const unsigned char *p, unsigned int n)
+{
+  u16 a;
+
+  for (a=0; n; n-- )
+    a += *p++;
+  return a;
+}
+
+
+/* Return the number of expected key parameters.  */
+static void
+get_npkey_nskey (int pubkey_algo, size_t *npkey, size_t *nskey)
+{
+  switch (pubkey_algo)
+    {
+    case GCRY_PK_RSA:   *npkey = 2; *nskey = 6; break;
+    case GCRY_PK_ELG:   *npkey = 3; *nskey = 4; break;
+    case GCRY_PK_ELG_E: *npkey = 3; *nskey = 4; break;
+    case GCRY_PK_DSA:   *npkey = 4; *nskey = 5; break;
+    case GCRY_PK_ECC:   *npkey = 1; *nskey = 2; break;
+    default:            *npkey = 0; *nskey = 0; break;
+    }
+}
+
+
+/* Helper for do_unprotect.  PUBKEY_ALOGO is the gcrypt algo number.
+   On success R_NPKEY and R_NSKEY receive the number or parameters for
+   the algorithm PUBKEY_ALGO and R_SKEYLEN the used length of
+   SKEY.  */
+static int
+prepare_unprotect (int pubkey_algo, gcry_mpi_t *skey, size_t skeysize,
+                   int s2k_mode,
+                   unsigned int *r_npkey, unsigned int *r_nskey,
+                   unsigned int *r_skeylen)
+{
+  size_t npkey, nskey, skeylen;
+  int i;
+
+  /* Count the actual number of MPIs is in the array and set the
+     remainder to NULL for easier processing later on.  */
+  for (skeylen = 0; skey[skeylen]; skeylen++)
+    ;
+  for (i=skeylen; i < skeysize; i++)
+    skey[i] = NULL;
+
+  /* Check some args.  */
+  if (s2k_mode == 1001)
+    {
+      /* Stub key.  */
+      log_info (_("secret key parts are not available\n"));
+      return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
+    }
+
+  if (gcry_pk_test_algo (pubkey_algo))
+    {
+      log_info (_("public key algorithm %d (%s) is not supported\n"),
+                pubkey_algo, gcry_pk_algo_name (pubkey_algo));
+      return gpg_error (GPG_ERR_PUBKEY_ALGO);
+    }
+
+  /* Get properties of the public key algorithm and do some
+     consistency checks.  Note that we need at least NPKEY+1 elements
+     in the SKEY array. */
+  get_npkey_nskey (pubkey_algo, &npkey, &nskey);
+  if (!npkey || !nskey || npkey >= nskey)
+    return gpg_error (GPG_ERR_INTERNAL);
+  if (skeylen <= npkey)
+    return gpg_error (GPG_ERR_MISSING_VALUE);
+  if (nskey+1 >= skeysize)
+    return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+
+  /* Check that the public key parameters are all available and not
+     encrypted.  */
+  for (i=0; i < npkey; i++)
+    {
+      if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_USER1))
+        return gpg_error (GPG_ERR_BAD_SECKEY);
+    }
+
+  if (r_npkey)
+    *r_npkey = npkey;
+  if (r_nskey)
+    *r_nskey = nskey;
+  if (r_skeylen)
+    *r_skeylen = skeylen;
+  return 0;
+}
+
+
+/* Note that this function modifies SKEY.  SKEYSIZE is the allocated
+   size of the array including the NULL item; this is used for a
+   bounds check.  On success a converted key is stored at R_KEY.  */
+static int
+do_unprotect (const char *passphrase,
+              int pkt_version, int pubkey_algo, int is_protected,
+              const char *curve, gcry_mpi_t *skey, size_t skeysize,
+              int protect_algo, void *protect_iv, size_t protect_ivlen,
+              int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count,
+              u16 desired_csum, gcry_sexp_t *r_key)
+{
+  gpg_error_t err;
+  unsigned int npkey, nskey, skeylen;
+  gcry_cipher_hd_t cipher_hd = NULL;
+  u16 actual_csum;
+  size_t nbytes;
+  int i;
+  gcry_mpi_t tmpmpi;
+
+  *r_key = NULL;
+
+  err = prepare_unprotect (pubkey_algo, skey, skeysize, s2k_mode,
+                           &npkey, &nskey, &skeylen);
+  if (err)
+    return err;
+
+  /* Check whether SKEY is at all protected.  If it is not protected
+     merely verify the checksum.  */
+  if (!is_protected)
+    {
+      actual_csum = 0;
+      for (i=npkey; i < nskey; i++)
+        {
+          if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_USER1))
+            return gpg_error (GPG_ERR_BAD_SECKEY);
+
+          if (gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
+            {
+              unsigned int nbits;
+              const unsigned char *buffer;
+              buffer = gcry_mpi_get_opaque (skey[i], &nbits);
+              nbytes = (nbits+7)/8;
+              actual_csum += checksum (buffer, nbytes);
+            }
+          else
+            {
+              unsigned char *buffer;
+
+              err = gcry_mpi_aprint (GCRYMPI_FMT_PGP, &buffer, &nbytes,
+                                     skey[i]);
+              if (!err)
+                actual_csum += checksum (buffer, nbytes);
+              xfree (buffer);
+            }
+          if (err)
+            return err;
+        }
+
+      if (actual_csum != desired_csum)
+        return gpg_error (GPG_ERR_CHECKSUM);
+
+      goto do_convert;
+    }
+
+
+  if (gcry_cipher_test_algo (protect_algo))
+    {
+      /* The algorithm numbers are Libgcrypt numbers but fortunately
+         the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
+         numbers.  */
+      log_info (_("protection algorithm %d (%s) is not supported\n"),
+                protect_algo, gnupg_cipher_algo_name (protect_algo));
+      return gpg_error (GPG_ERR_CIPHER_ALGO);
+    }
+
+  if (gcry_md_test_algo (s2k_algo))
+    {
+      log_info (_("protection hash algorithm %d (%s) is not supported\n"),
+                s2k_algo, gcry_md_algo_name (s2k_algo));
+      return gpg_error (GPG_ERR_DIGEST_ALGO);
+    }
+
+  err = gcry_cipher_open (&cipher_hd, protect_algo,
+                          GCRY_CIPHER_MODE_CFB,
+                          (GCRY_CIPHER_SECURE
+                           | (protect_algo >= 100 ?
+                              0 : GCRY_CIPHER_ENABLE_SYNC)));
+  if (err)
+    {
+      log_error ("failed to open cipher_algo %d: %s\n",
+                 protect_algo, gpg_strerror (err));
+      return err;
+    }
+
+  err = hash_passphrase_and_set_key (passphrase, cipher_hd, protect_algo,
+                                     s2k_mode, s2k_algo, s2k_salt, s2k_count);
+  if (err)
+    {
+      gcry_cipher_close (cipher_hd);
+      return err;
+    }
+
+  gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen);
+
+  actual_csum = 0;
+  if (pkt_version >= 4)
+    {
+      int ndata;
+      unsigned int ndatabits;
+      const unsigned char *p;
+      unsigned char *data;
+      u16 csum_pgp7 = 0;
+
+      if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE ))
+        {
+          gcry_cipher_close (cipher_hd);
+          return gpg_error (GPG_ERR_BAD_SECKEY);
+        }
+      p = gcry_mpi_get_opaque (skey[npkey], &ndatabits);
+      ndata = (ndatabits+7)/8;
+
+      if (ndata > 1)
+        csum_pgp7 = p[ndata-2] << 8 | p[ndata-1];
+      data = xtrymalloc_secure (ndata);
+      if (!data)
+        {
+          err = gpg_error_from_syserror ();
+          gcry_cipher_close (cipher_hd);
+          return err;
+        }
+      gcry_cipher_decrypt (cipher_hd, data, ndata, p, ndata);
+
+      p = data;
+      if (is_protected == 2)
+        {
+          /* This is the new SHA1 checksum method to detect tampering
+             with the key as used by the Klima/Rosa attack.  */
+          desired_csum = 0;
+          actual_csum = 1;  /* Default to bad checksum.  */
+
+          if (ndata < 20)
+            log_error ("not enough bytes for SHA-1 checksum\n");
+          else
+            {
+              gcry_md_hd_t h;
+
+              if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
+                BUG(); /* Algo not available. */
+              gcry_md_write (h, data, ndata - 20);
+              gcry_md_final (h);
+              if (!memcmp (gcry_md_read (h, GCRY_MD_SHA1), data+ndata-20, 20))
+                actual_csum = 0; /* Digest does match.  */
+              gcry_md_close (h);
+            }
+        }
+      else
+        {
+          /* Old 16 bit checksum method.  */
+          if (ndata < 2)
+            {
+              log_error ("not enough bytes for checksum\n");
+              desired_csum = 0;
+              actual_csum = 1;  /* Mark checksum bad.  */
+            }
+          else
+            {
+              desired_csum = (data[ndata-2] << 8 | data[ndata-1]);
+              actual_csum = checksum (data, ndata-2);
+              if (desired_csum != actual_csum)
+                {
+                  /* This is a PGP 7.0.0 workaround */
+                  desired_csum = csum_pgp7; /* Take the encrypted one.  */
+                }
+            }
+        }
+
+      /* Better check it here.  Otherwise the gcry_mpi_scan would fail
+         because the length may have an arbitrary value.  */
+      if (desired_csum == actual_csum)
+        {
+          for (i=npkey; i < nskey; i++ )
+            {
+              if (gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, p, ndata, &nbytes))
+                {
+                  /* Checksum was okay, but not correctly decrypted.  */
+                  desired_csum = 0;
+                  actual_csum = 1;   /* Mark checksum bad.  */
+                  break;
+                }
+              gcry_mpi_release (skey[i]);
+              skey[i] = tmpmpi;
+              ndata -= nbytes;
+              p += nbytes;
+            }
+          skey[i] = NULL;
+          skeylen = i;
+          assert (skeylen <= skeysize);
+
+          /* Note: at this point NDATA should be 2 for a simple
+             checksum or 20 for the sha1 digest.  */
+        }
+      xfree(data);
+    }
+  else /* Packet version <= 3.  */
+    {
+      unsigned char *buffer;
+
+      for (i = npkey; i < nskey; i++)
+        {
+          const unsigned char *p;
+          size_t ndata;
+          unsigned int ndatabits;
+
+          if (!skey[i] || !gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
+            {
+              gcry_cipher_close (cipher_hd);
+              return gpg_error (GPG_ERR_BAD_SECKEY);
+            }
+          p = gcry_mpi_get_opaque (skey[i], &ndatabits);
+          ndata = (ndatabits+7)/8;
+
+          if (!(ndata >= 2) || !(ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2))
+            {
+              gcry_cipher_close (cipher_hd);
+              return gpg_error (GPG_ERR_BAD_SECKEY);
+            }
+
+          buffer = xtrymalloc_secure (ndata);
+          if (!buffer)
+            {
+              err = gpg_error_from_syserror ();
+              gcry_cipher_close (cipher_hd);
+              return err;
+            }
+
+          gcry_cipher_sync (cipher_hd);
+          buffer[0] = p[0];
+          buffer[1] = p[1];
+          gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, p+2, ndata-2);
+          actual_csum += checksum (buffer, ndata);
+          err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, buffer, ndata, &ndata);
+          xfree (buffer);
+          if (err)
+            {
+              /* Checksum was okay, but not correctly decrypted.  */
+              desired_csum = 0;
+              actual_csum = 1;   /* Mark checksum bad.  */
+              break;
+            }
+          gcry_mpi_release (skey[i]);
+          skey[i] = tmpmpi;
+        }
+    }
+  gcry_cipher_close (cipher_hd);
+
+  /* Now let's see whether we have used the correct passphrase. */
+  if (actual_csum != desired_csum)
+    return gpg_error (GPG_ERR_BAD_PASSPHRASE);
+
+ do_convert:
+  if (nskey != skeylen)
+    err = gpg_error (GPG_ERR_BAD_SECKEY);
+  else
+    err = convert_secret_key (r_key, pubkey_algo, skey, curve);
+  if (err)
+    return err;
+
+  /* The checksum may fail, thus we also check the key itself.  */
+  err = gcry_pk_testkey (*r_key);
+  if (err)
+    {
+      gcry_sexp_release (*r_key);
+      *r_key = NULL;
+      return gpg_error (GPG_ERR_BAD_PASSPHRASE);
+    }
+
+  return 0;
+}
+
+
+/* Callback function to try the unprotection from the passphrase query
+   code.  */
+static int
+try_do_unprotect_cb (struct pin_entry_info_s *pi)
+{
+  gpg_error_t err;
+  struct try_do_unprotect_arg_s *arg = pi->check_cb_arg;
+
+  err = do_unprotect (pi->pin,
+                      arg->is_v4? 4:3,
+                      arg->pubkey_algo, arg->is_protected,
+                      arg->curve,
+                      arg->skey, arg->skeysize,
+                      arg->protect_algo, arg->iv, arg->ivlen,
+                      arg->s2k_mode, arg->s2k_algo,
+                      arg->s2k_salt, arg->s2k_count,
+                      arg->desired_csum, arg->r_key);
+  /* SKEY may be modified now, thus we need to re-compute SKEYIDX.  */
+  for (arg->skeyidx = 0; (arg->skeyidx < arg->skeysize
+                          && arg->skey[arg->skeyidx]); arg->skeyidx++)
+    ;
+  return err;
+}
+
+
+/* See convert_from_openpgp for the core of the description.  This
+   function adds an optional PASSPHRASE argument and uses this to
+   silently decrypt the key; CACHE_NONCE and R_PASSPHRASE must both be
+   NULL in this mode.  */
+static gpg_error_t
+convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp,
+                           unsigned char *grip, const char *prompt,
+                           const char *cache_nonce, const char *passphrase,
+                           unsigned char **r_key, char **r_passphrase)
+{
+  gpg_error_t err;
+  int unattended;
+  int from_native;
+  gcry_sexp_t top_list;
+  gcry_sexp_t list = NULL;
+  const char *value;
+  size_t valuelen;
+  char *string;
+  int  idx;
+  int  is_v4, is_protected;
+  int  pubkey_algo;
+  int  protect_algo = 0;
+  char iv[16];
+  int  ivlen = 0;
+  int  s2k_mode = 0;
+  int  s2k_algo = 0;
+  byte s2k_salt[8];
+  u32  s2k_count = 0;
+  size_t npkey, nskey;
+  gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
+  char *curve = NULL;
+  u16 desired_csum;
+  int skeyidx = 0;
+  gcry_sexp_t s_skey = NULL;
+
+  *r_key = NULL;
+  if (r_passphrase)
+    *r_passphrase = NULL;
+  unattended = !r_passphrase;
+  from_native = (!cache_nonce && passphrase && !r_passphrase);
+
+  top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
+  if (!top_list)
+    goto bad_seckey;
+
+  list = gcry_sexp_find_token (top_list, "version", 0);
+  if (!list)
+    goto bad_seckey;
+  value = gcry_sexp_nth_data (list, 1, &valuelen);
+  if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
+    goto bad_seckey;
+  is_v4 = (value[0] == '4');
+
+  gcry_sexp_release (list);
+  list = gcry_sexp_find_token (top_list, "protection", 0);
+  if (!list)
+    goto bad_seckey;
+  value = gcry_sexp_nth_data (list, 1, &valuelen);
+  if (!value)
+    goto bad_seckey;
+  if (valuelen == 4 && !memcmp (value, "sha1", 4))
+    is_protected = 2;
+  else if (valuelen == 3 && !memcmp (value, "sum", 3))
+    is_protected = 1;
+  else if (valuelen == 4 && !memcmp (value, "none", 4))
+    is_protected = 0;
+  else
+    goto bad_seckey;
+
+  if (is_protected)
+    {
+      string = gcry_sexp_nth_string (list, 2);
+      if (!string)
+        goto bad_seckey;
+      protect_algo = gcry_cipher_map_name (string);
+      xfree (string);
+
+      value = gcry_sexp_nth_data (list, 3, &valuelen);
+      if (!value || !valuelen || valuelen > sizeof iv)
+        goto bad_seckey;
+      memcpy (iv, value, valuelen);
+      ivlen = valuelen;
+
+      string = gcry_sexp_nth_string (list, 4);
+      if (!string)
+        goto bad_seckey;
+      s2k_mode = strtol (string, NULL, 10);
+      xfree (string);
+
+      string = gcry_sexp_nth_string (list, 5);
+      if (!string)
+        goto bad_seckey;
+      s2k_algo = gcry_md_map_name (string);
+      xfree (string);
+
+      value = gcry_sexp_nth_data (list, 6, &valuelen);
+      if (!value || !valuelen || valuelen > sizeof s2k_salt)
+        goto bad_seckey;
+      memcpy (s2k_salt, value, valuelen);
+
+      string = gcry_sexp_nth_string (list, 7);
+      if (!string)
+        goto bad_seckey;
+      s2k_count = strtoul (string, NULL, 10);
+      xfree (string);
+    }
+
+  gcry_sexp_release (list);
+  list = gcry_sexp_find_token (top_list, "algo", 0);
+  if (!list)
+    goto bad_seckey;
+  string = gcry_sexp_nth_string (list, 1);
+  if (!string)
+    goto bad_seckey;
+  pubkey_algo = gcry_pk_map_name (string);
+  xfree (string);
+
+  get_npkey_nskey (pubkey_algo, &npkey, &nskey);
+  if (!npkey || !nskey || npkey >= nskey)
+    goto bad_seckey;
+
+  if (npkey == 1) /* This is ECC */
+    {
+      gcry_sexp_release (list);
+      list = gcry_sexp_find_token (top_list, "curve", 0);
+      if (!list)
+        goto bad_seckey;
+      curve = gcry_sexp_nth_string (list, 1);
+      if (!curve)
+        goto bad_seckey;
+    }
+
+  gcry_sexp_release (list);
+  list = gcry_sexp_find_token (top_list, "skey", 0);
+  if (!list)
+    goto bad_seckey;
+  for (idx=0;;)
+    {
+      int is_enc;
+
+      value = gcry_sexp_nth_data (list, ++idx, &valuelen);
+      if (!value && skeyidx >= npkey)
+        break;  /* Ready.  */
+
+      /* Check for too many parameters.  Note that depending on the
+         protection mode and version number we may see less than NSKEY
+         (but at least NPKEY+1) parameters.  */
+      if (idx >= 2*nskey)
+        goto bad_seckey;
+      if (skeyidx >= DIM (skey)-1)
+        goto bad_seckey;
+
+      if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
+        goto bad_seckey;
+      is_enc = (value[0] == 'e');
+      value = gcry_sexp_nth_data (list, ++idx, &valuelen);
+      if (!value || !valuelen)
+        goto bad_seckey;
+      if (is_enc || curve)
+        {
+          /* Encrypted parameters and ECC parameters need or can be
+             stored as opaque.  */
+          skey[skeyidx] = gcry_mpi_set_opaque_copy (NULL, value, valuelen*8);
+          if (!skey[skeyidx])
+            goto outofmem;
+          if (is_enc)
+            gcry_mpi_set_flag (skey[skeyidx], GCRYMPI_FLAG_USER1);
+        }
+      else
+        {
+          if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
+                             value, valuelen, NULL))
+            goto bad_seckey;
+        }
+      skeyidx++;
+    }
+  skey[skeyidx++] = NULL;
+
+  gcry_sexp_release (list);
+  list = gcry_sexp_find_token (top_list, "csum", 0);
+  if (list)
+    {
+      string = gcry_sexp_nth_string (list, 1);
+      if (!string)
+        goto bad_seckey;
+      desired_csum = strtoul (string, NULL, 10);
+      xfree (string);
+    }
+  else
+    desired_csum = 0;
+
+
+  gcry_sexp_release (list); list = NULL;
+  gcry_sexp_release (top_list); top_list = NULL;
+
+#if 0
+  log_debug ("XXX is_v4=%d\n", is_v4);
+  log_debug ("XXX pubkey_algo=%d\n", pubkey_algo);
+  log_debug ("XXX is_protected=%d\n", is_protected);
+  log_debug ("XXX protect_algo=%d\n", protect_algo);
+  log_printhex ("XXX iv", iv, ivlen);
+  log_debug ("XXX ivlen=%d\n", ivlen);
+  log_debug ("XXX s2k_mode=%d\n", s2k_mode);
+  log_debug ("XXX s2k_algo=%d\n", s2k_algo);
+  log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt);
+  log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count);
+  log_debug ("XXX curve='%s'\n", curve);
+  for (idx=0; skey[idx]; idx++)
+    gcry_log_debugmpi (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_USER1)
+                       ? "skey(e)" : "skey(_)", skey[idx]);
+#endif /*0*/
+
+  err = get_keygrip (pubkey_algo, curve, skey, grip);
+  if (err)
+    goto leave;
+
+  if (!from_native && !agent_key_available (grip))
+    {
+      err = gpg_error (GPG_ERR_EEXIST);
+      goto leave;
+    }
+
+  if (unattended && !from_native)
+    {
+      err = prepare_unprotect (pubkey_algo, skey, DIM(skey), s2k_mode,
+                               NULL, NULL, NULL);
+      if (err)
+        goto leave;
+
+      err = convert_transfer_key (&s_skey, pubkey_algo, skey, curve, s_pgp);
+      if (err)
+        goto leave;
+    }
+  else
+    {
+      struct pin_entry_info_s *pi;
+      struct try_do_unprotect_arg_s pi_arg;
+
+      pi = xtrycalloc_secure (1, sizeof (*pi) + 100);
+      if (!pi)
+        return gpg_error_from_syserror ();
+      pi->max_length = 100;
+      pi->min_digits = 0;  /* We want a real passphrase.  */
+      pi->max_digits = 16;
+      pi->max_tries = 3;
+      pi->check_cb = try_do_unprotect_cb;
+      pi->check_cb_arg = &pi_arg;
+      pi_arg.is_v4 = is_v4;
+      pi_arg.is_protected = is_protected;
+      pi_arg.pubkey_algo = pubkey_algo;
+      pi_arg.curve = curve;
+      pi_arg.protect_algo = protect_algo;
+      pi_arg.iv = iv;
+      pi_arg.ivlen = ivlen;
+      pi_arg.s2k_mode = s2k_mode;
+      pi_arg.s2k_algo = s2k_algo;
+      pi_arg.s2k_salt = s2k_salt;
+      pi_arg.s2k_count = s2k_count;
+      pi_arg.desired_csum = desired_csum;
+      pi_arg.skey = skey;
+      pi_arg.skeysize = DIM (skey);
+      pi_arg.skeyidx = skeyidx;
+      pi_arg.r_key = &s_skey;
+
+      err = gpg_error (GPG_ERR_BAD_PASSPHRASE);
+      if (!is_protected)
+        {
+          err = try_do_unprotect_cb (pi);
+        }
+      else if (cache_nonce)
+        {
+          char *cache_value;
+
+          cache_value = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
+          if (cache_value)
+            {
+              if (strlen (cache_value) < pi->max_length)
+                strcpy (pi->pin, cache_value);
+              xfree (cache_value);
+            }
+          if (*pi->pin)
+            err = try_do_unprotect_cb (pi);
+        }
+      else if (from_native)
+        {
+          if (strlen (passphrase) < pi->max_length)
+            strcpy (pi->pin, passphrase);
+          err = try_do_unprotect_cb (pi);
+        }
+      if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE && !from_native)
+        err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
+      skeyidx = pi_arg.skeyidx;
+      if (!err && r_passphrase && is_protected)
+        {
+          *r_passphrase = xtrystrdup (pi->pin);
+          if (!*r_passphrase)
+            err = gpg_error_from_syserror ();
+        }
+      xfree (pi);
+      if (err)
+        goto leave;
+    }
+
+  /* Save some memory and get rid of the SKEY array now.  */
+  for (idx=0; idx < skeyidx; idx++)
+    gcry_mpi_release (skey[idx]);
+  skeyidx = 0;
+
+  /* Note that the padding is not required - we use it only because
+     that function allows us to create the result in secure memory.  */
+  err = make_canon_sexp_pad (s_skey, 1, r_key, NULL);
+
+ leave:
+  xfree (curve);
+  gcry_sexp_release (s_skey);
+  gcry_sexp_release (list);
+  gcry_sexp_release (top_list);
+  for (idx=0; idx < skeyidx; idx++)
+    gcry_mpi_release (skey[idx]);
+  if (err && r_passphrase)
+    {
+      xfree (*r_passphrase);
+      *r_passphrase = NULL;
+    }
+  return err;
+
+ bad_seckey:
+  err = gpg_error (GPG_ERR_BAD_SECKEY);
+  goto leave;
+
+ outofmem:
+  err = gpg_error (GPG_ERR_ENOMEM);
+  goto leave;
+
+}
+
+
+/* Convert an OpenPGP transfer key into our internal format.  Before
+   asking for a passphrase we check whether the key already exists in
+   our key storage.  S_PGP is the OpenPGP key in transfer format.  If
+   CACHE_NONCE is given the passphrase will be looked up in the cache.
+   On success R_KEY will receive a canonical encoded S-expression with
+   the unprotected key in our internal format; the caller needs to
+   release that memory.  The passphrase used to decrypt the OpenPGP
+   key will be returned at R_PASSPHRASE; the caller must release this
+   passphrase.  If R_PASSPHRASE is NULL the unattended conversion mode
+   will be used which uses the openpgp-native protection format for
+   the key.  The keygrip will be stored at the 20 byte buffer pointed
+   to by GRIP.  On error NULL is stored at all return arguments.  */
+gpg_error_t
+convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
+                      unsigned char *grip, const char *prompt,
+                      const char *cache_nonce,
+                      unsigned char **r_key, char **r_passphrase)
+{
+  return convert_from_openpgp_main (ctrl, s_pgp, grip, prompt,
+                                    cache_nonce, NULL,
+                                    r_key, r_passphrase);
+}
+
+/* This function is called by agent_unprotect to re-protect an
+   openpgp-native protected private-key into the standard private-key
+   protection format.  */
+gpg_error_t
+convert_from_openpgp_native (ctrl_t ctrl,
+                             gcry_sexp_t s_pgp, const char *passphrase,
+                             unsigned char **r_key)
+{
+  gpg_error_t err;
+  unsigned char grip[20];
+
+  if (!passphrase)
+    return gpg_error (GPG_ERR_INTERNAL);
+
+  err = convert_from_openpgp_main (ctrl, s_pgp, grip, NULL,
+                                   NULL, passphrase,
+                                   r_key, NULL);
+
+  /* On success try to re-write the key.  */
+  if (!err)
+    {
+      unsigned char *protectedkey = NULL;
+      size_t protectedkeylen;
+
+      if (!agent_protect (*r_key, passphrase, &protectedkey, &protectedkeylen,
+                          ctrl->s2k_count))
+        agent_write_private_key (grip, protectedkey, protectedkeylen, 1);
+      xfree (protectedkey);
+    }
+
+  return err;
+}
+
+
+/* Given an ARRAY of mpis with the key parameters, protect the secret
+   parameters in that array and replace them by one opaque encoded
+   mpi.  NPKEY is the number of public key parameters and NSKEY is
+   the number of secret key parameters (including the public ones).
+   On success the array will have NPKEY+1 elements.  */
+static gpg_error_t
+apply_protection (gcry_mpi_t *array, int npkey, int nskey,
+                  const char *passphrase,
+                  int protect_algo, void *protect_iv, size_t protect_ivlen,
+                  int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count)
+{
+  gpg_error_t err;
+  int i, j;
+  gcry_cipher_hd_t cipherhd;
+  unsigned char *bufarr[10];
+  size_t narr[10];
+  unsigned int nbits[10];
+  int ndata;
+  unsigned char *p, *data;
+
+  assert (npkey < nskey);
+  assert (nskey < DIM (bufarr));
+
+  /* Collect only the secret key parameters into BUFARR et al and
+     compute the required size of the data buffer.  */
+  ndata = 20; /* Space for the SHA-1 checksum.  */
+  for (i = npkey, j = 0; i < nskey; i++, j++ )
+    {
+      if (gcry_mpi_get_flag (array[i], GCRYMPI_FLAG_OPAQUE))
+        {
+          const void *s;
+          unsigned int n;
+
+          s = gcry_mpi_get_opaque (array[i], &n);
+          nbits[j] = n;
+          n = (n+7)/8;
+          narr[j] = n;
+          bufarr[j] = gcry_is_secure (s)? xtrymalloc_secure (n):xtrymalloc (n);
+          if (!bufarr[j])
+            {
+              err = gpg_error_from_syserror ();
+              for (i = 0; i < j; i++)
+                xfree (bufarr[i]);
+              return err;
+            }
+          memcpy (bufarr[j], s, n);
+        }
+      else
+        {
+          err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j, narr+j, array[i]);
+          if (err)
+            {
+              for (i = 0; i < j; i++)
+                xfree (bufarr[i]);
+              return err;
+            }
+          nbits[j] = gcry_mpi_get_nbits (array[i]);
+        }
+      ndata += 2 + narr[j];
+    }
+
+  /* Allocate data buffer and stuff it with the secret key parameters.  */
+  data = xtrymalloc_secure (ndata);
+  if (!data)
+    {
+      err = gpg_error_from_syserror ();
+      for (i = 0; i < (nskey-npkey); i++ )
+        xfree (bufarr[i]);
+      return err;
+    }
+  p = data;
+  for (i = 0; i < (nskey-npkey); i++ )
+    {
+      *p++ = nbits[i] >> 8 ;
+      *p++ = nbits[i];
+      memcpy (p, bufarr[i], narr[i]);
+      p += narr[i];
+      xfree (bufarr[i]);
+      bufarr[i] = NULL;
+    }
+  assert (p == data + ndata - 20);
+
+  /* Append a hash of the secret key parameters.  */
+  gcry_md_hash_buffer (GCRY_MD_SHA1, p, data, ndata - 20);
+
+  /* Encrypt it.  */
+  err = gcry_cipher_open (&cipherhd, protect_algo,
+                          GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
+  if (!err)
+    err = hash_passphrase_and_set_key (passphrase, cipherhd, protect_algo,
+                                       s2k_mode, s2k_algo, s2k_salt, s2k_count);
+  if (!err)
+    err = gcry_cipher_setiv (cipherhd, protect_iv, protect_ivlen);
+  if (!err)
+    err = gcry_cipher_encrypt (cipherhd, data, ndata, NULL, 0);
+  gcry_cipher_close (cipherhd);
+  if (err)
+    {
+      xfree (data);
+      return err;
+    }
+
+  /* Replace the secret key parameters in the array by one opaque value.  */
+  for (i = npkey; i < nskey; i++ )
+    {
+      gcry_mpi_release (array[i]);
+      array[i] = NULL;
+    }
+  array[npkey] = gcry_mpi_set_opaque (NULL, data, ndata*8);
+  return 0;
+}
+
+
+/* Convert our key S_KEY into an OpenPGP key transfer format.  On
+   success a canonical encoded S-expression is stored at R_TRANSFERKEY
+   and its length at R_TRANSFERKEYLEN; this S-expression is also
+   padded to a multiple of 64 bits.  */
+gpg_error_t
+convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
+                    unsigned char **r_transferkey, size_t *r_transferkeylen)
+{
+  gpg_error_t err;
+  gcry_sexp_t list, l2;
+  char *name;
+  const char *algoname;
+  int npkey, nskey;
+  gcry_mpi_t array[10];
+  gcry_sexp_t curve = NULL;
+  char protect_iv[16];
+  char salt[8];
+  unsigned long s2k_count;
+  int i, j;
+
+  (void)ctrl;
+
+  *r_transferkey = NULL;
+
+  for (i=0; i < DIM (array); i++)
+    array[i] = NULL;
+
+  list = gcry_sexp_find_token (s_key, "private-key", 0);
+  if (!list)
+    return gpg_error (GPG_ERR_NO_OBJ); /* Does not contain a key object.  */
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  name = gcry_sexp_nth_string (list, 0);
+  if (!name)
+    {
+      gcry_sexp_release (list);
+      return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
+    }
+
+  /* Map NAME to a name as used by Libgcrypt.  We do not use the
+     Libgcrypt function here because we need a lowercase name and
+     require special treatment for some algorithms.  */
+  strlwr (name);
+  if (!strcmp (name, "rsa"))
+    {
+      algoname = "rsa";
+      npkey = 2;
+      nskey = 6;
+      err = gcry_sexp_extract_param (list, NULL, "nedpqu",
+                                     array+0, array+1, array+2, array+3,
+                                     array+4, array+5, NULL);
+    }
+  else if (!strcmp (name, "elg"))
+    {
+      algoname = "elg";
+      npkey = 3;
+      nskey = 4;
+      err = gcry_sexp_extract_param (list, NULL, "pgyx",
+                                     array+0, array+1, array+2, array+3,
+                                     NULL);
+    }
+  else if (!strcmp (name, "dsa"))
+    {
+      algoname = "dsa";
+      npkey = 4;
+      nskey = 5;
+      err = gcry_sexp_extract_param (list, NULL, "pqgyx",
+                                     array+0, array+1, array+2, array+3,
+                                     array+4, NULL);
+    }
+  else if (!strcmp (name, "ecc"))
+    {
+      gcry_buffer_t iob;
+      char iobbuf[32];
+
+      algoname = "ecc"; /* Decide later by checking the usage.  */
+      npkey = 1;
+      nskey = 2;
+      iob.data = iobbuf;
+      iob.size = sizeof iobbuf - 1;
+      iob.off = 0;
+      iob.len = 0;
+      err = gcry_sexp_extract_param (list, NULL, "&'curve'/qd",
+                                     &iob, array+0, array+1, NULL);
+      if (!err)
+        {
+          assert (iob.len < sizeof iobbuf -1);
+          iobbuf[iob.len] = 0;
+          err = gcry_sexp_build (&curve, NULL, "(curve %s)", iobbuf);
+        }
+    }
+  else if (!strcmp (name, "ecdsa"))
+    {
+      algoname = "ecdsa";
+      npkey = 6;
+      nskey = 7;
+      err = gcry_sexp_extract_param (list, NULL, "pabgnqd",
+                                     array+0, array+1, array+2, array+3,
+                                     array+4, array+5, array+6, NULL);
+    }
+  else if (!strcmp (name, "ecdh"))
+    {
+      algoname = "ecdh";
+      npkey = 6;
+      nskey= 7;
+      err = gcry_sexp_extract_param (list, NULL, "pabgnqd",
+                                     array+0, array+1, array+2, array+3,
+                                     array+4, array+5, array+6, NULL);
+    }
+  else
+    {
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+    }
+  xfree (name);
+  gcry_sexp_release (list); list = NULL;
+  if (err)
+    {
+      gcry_sexp_release (curve);
+      return err;
+    }
+
+  gcry_create_nonce (protect_iv, sizeof protect_iv);
+  gcry_create_nonce (salt, sizeof salt);
+  /* We need to use the encoded S2k count.  It is not possible to
+     encode it after it has been used because the encoding procedure
+     may round the value up.  */
+  s2k_count = get_standard_s2k_count_rfc4880 ();
+  err = apply_protection (array, npkey, nskey, passphrase,
+                          GCRY_CIPHER_AES, protect_iv, sizeof protect_iv,
+                          3, GCRY_MD_SHA1, salt, s2k_count);
+  /* Turn it into the transfer key S-expression.  Note that we always
+     return a protected key.  */
+  if (!err)
+    {
+      char countbuf[35];
+      membuf_t mbuf;
+      void *format_args[10+2];
+      gcry_sexp_t tmpkey;
+      gcry_sexp_t tmpsexp = NULL;
+
+      snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
+
+      init_membuf (&mbuf, 50);
+      put_membuf_str (&mbuf, "(skey");
+      for (i=j=0; i < npkey; i++)
+        {
+          put_membuf_str (&mbuf, " _ %m");
+          format_args[j++] = array + i;
+        }
+      put_membuf_str (&mbuf, " e %m");
+      format_args[j++] = array + npkey;
+      put_membuf_str (&mbuf, ")\n");
+      put_membuf (&mbuf, "", 1);
+
+      tmpkey = NULL;
+      {
+        char *format = get_membuf (&mbuf, NULL);
+        if (!format)
+          err = gpg_error_from_syserror ();
+        else
+          err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args);
+        xfree (format);
+      }
+      if (!err)
+        err = gcry_sexp_build (&tmpsexp, NULL,
+                               "(openpgp-private-key\n"
+                               " (version 1:4)\n"
+                               " (algo %s)\n"
+                               " %S%S\n"
+                               " (protection sha1 aes %b 1:3 sha1 %b %s))\n",
+                               algoname,
+                               curve,
+                               tmpkey,
+                               (int)sizeof protect_iv, protect_iv,
+                               (int)sizeof salt, salt,
+                               countbuf);
+      gcry_sexp_release (tmpkey);
+      if (!err)
+        err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen);
+      gcry_sexp_release (tmpsexp);
+    }
+
+  for (i=0; i < DIM (array); i++)
+    gcry_mpi_release (array[i]);
+  gcry_sexp_release (curve);
+
+  return err;
+}
diff --git a/agent/cvt-openpgp.h b/agent/cvt-openpgp.h
new file mode 100644 (file)
index 0000000..d27a776
--- /dev/null
@@ -0,0 +1,36 @@
+/* cvt-openpgp.h - Convert an OpenPGP key to our internal format.
+ * Copyright (C) 2010 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GNUPG_AGENT_CVT_OPENPGP_H
+#define GNUPG_AGENT_CVT_OPENPGP_H
+
+gpg_error_t convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
+                                  unsigned char *grip, const char *prompt,
+                                  const char *cache_nonce,
+                                  unsigned char **r_key, char **r_passphrase);
+gpg_error_t convert_from_openpgp_native (ctrl_t ctrl,
+                                         gcry_sexp_t s_pgp,
+                                         const char *passphrase,
+                                         unsigned char **r_key);
+
+gpg_error_t convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key,
+                                const char *passphrase,
+                                unsigned char **r_transferkey,
+                                size_t *r_transferkeylen);
+
+#endif /*GNUPG_AGENT_CVT_OPENPGP_H*/
index 34ef498..ceef588 100644 (file)
@@ -1,4 +1,4 @@
-/* divert-scd.c - divert operations to the scdaemon 
+/* divert-scd.c - divert operations to the scdaemon
  *     Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
@@ -44,7 +44,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
 
   *r_kid = NULL;
 
-  rc = parse_shadow_info (shadow_info, &want_sn, &want_kid);
+  rc = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL);
   if (rc)
     return rc;
 
@@ -99,6 +99,10 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
           else
             {
               rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
+             if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK &&
+                 gpg_err_code (rc) == GPG_ERR_NO_PIN_ENTRY)
+               rc = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
+
               xfree (desc);
             }
         }
@@ -140,7 +144,7 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
   memcpy (frame+asnlen, digest, digestlen);
   if (DBG_CRYPTO)
     log_printhex ("encoded hash:", frame, asnlen+digestlen);
-      
+
   *r_val = frame;
   *r_len = asnlen+digestlen;
   return 0;
@@ -170,11 +174,11 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
    Example:
 
      "|AN|Please enter the new security officer's PIN"
-     
+
    The text "Please ..." will get displayed and the flags 'A' and 'N'
    are considered.
  */
-static int 
+static int
 getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
 {
   struct pin_entry_info_s *pi;
@@ -266,7 +270,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
 
   if (any_flags)
     {
-      rc = agent_askpin (ctrl, info, prompt, again_text, pi, NULL, 0);
+      rc = agent_askpin (ctrl, info, prompt, again_text, pi);
       again_text = NULL;
       if (!rc && newpin)
         {
@@ -288,10 +292,10 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
                               is_puk?
                               _("Repeat this PUK"):
                               _("Repeat this PIN")),
-                             prompt, NULL, pi2, NULL, 0);
+                             prompt, NULL, pi2);
           if (!rc && strcmp (pi->pin, pi2->pin))
             {
-              again_text = (resetcode? 
+              again_text = (resetcode?
                             N_("Reset Code not correctly repeated; try again"):
                             is_puk?
                             N_("PUK not correctly repeated; try again"):
@@ -307,12 +311,12 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
     {
       char *desc;
       if ( asprintf (&desc,
-                     _("Please enter the PIN%s%s%s to unlock the card"), 
-                     info? " (`":"",
+                     _("Please enter the PIN%s%s%s to unlock the card"),
+                     info? " (":"",
                      info? info:"",
-                     info? "')":"") < 0)
+                     info? ")":"") < 0)
         desc = NULL;
-      rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi, NULL, 0);
+      rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi);
       xfree (desc);
     }
 
@@ -329,9 +333,10 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
 
 
 int
-divert_pksign (ctrl_t ctrl, 
+divert_pksign (ctrl_t ctrl,
                const unsigned char *digest, size_t digestlen, int algo,
-               const unsigned char *shadow_info, unsigned char **r_sig)
+               const unsigned char *shadow_info, unsigned char **r_sig,
+               size_t *r_siglen)
 {
   int rc;
   char *kid;
@@ -347,7 +352,7 @@ divert_pksign (ctrl_t ctrl,
       int save = ctrl->use_auth_call;
       ctrl->use_auth_call = 1;
       rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
-                              digest, digestlen, &sigval, &siglen);
+                              algo, digest, digestlen, &sigval, &siglen);
       ctrl->use_auth_call = save;
     }
   else
@@ -359,13 +364,16 @@ divert_pksign (ctrl_t ctrl,
       if (!rc)
         {
           rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
-                                  data, ndata, &sigval, &siglen);
+                                  algo, data, ndata, &sigval, &siglen);
           xfree (data);
         }
     }
 
   if (!rc)
-    *r_sig = sigval;
+    {
+      *r_sig = sigval;
+      *r_siglen = siglen;
+    }
 
   xfree (kid);
 
@@ -375,12 +383,13 @@ divert_pksign (ctrl_t ctrl,
 
 /* Decrypt the the value given asn an S-expression in CIPHER using the
    key identified by SHADOW_INFO and return the plaintext in an
-   allocated buffer in R_BUF.  */
-int  
+   allocated buffer in R_BUF.  The padding information is stored at
+   R_PADDING with -1 for not known.  */
+int
 divert_pkdecrypt (ctrl_t ctrl,
                   const unsigned char *cipher,
                   const unsigned char *shadow_info,
-                  char **r_buf, size_t *r_len)
+                  char **r_buf, size_t *r_len, int *r_padding)
 {
   int rc;
   char *kid;
@@ -391,34 +400,36 @@ divert_pkdecrypt (ctrl_t ctrl,
   char *plaintext;
   size_t plaintextlen;
 
+  *r_padding = -1;
+
   s = cipher;
   if (*s != '(')
     return gpg_error (GPG_ERR_INV_SEXP);
   s++;
   n = snext (&s);
   if (!n)
-    return gpg_error (GPG_ERR_INV_SEXP); 
+    return gpg_error (GPG_ERR_INV_SEXP);
   if (!smatch (&s, n, "enc-val"))
-    return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
+    return gpg_error (GPG_ERR_UNKNOWN_SEXP);
   if (*s != '(')
     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
   s++;
   n = snext (&s);
   if (!n)
-    return gpg_error (GPG_ERR_INV_SEXP); 
+    return gpg_error (GPG_ERR_INV_SEXP);
   if (!smatch (&s, n, "rsa"))
-    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); 
+    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
   if (*s != '(')
     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
   s++;
   n = snext (&s);
   if (!n)
-    return gpg_error (GPG_ERR_INV_SEXP); 
+    return gpg_error (GPG_ERR_INV_SEXP);
   if (!smatch (&s, n, "a"))
     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
   n = snext (&s);
   if (!n)
-    return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
+    return gpg_error (GPG_ERR_UNKNOWN_SEXP);
   ciphertext = s;
   ciphertextlen = n;
 
@@ -428,7 +439,7 @@ divert_pkdecrypt (ctrl_t ctrl,
 
   rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl,
                              ciphertext, ciphertextlen,
-                             &plaintext, &plaintextlen);
+                             &plaintext, &plaintextlen, r_padding);
   if (!rc)
     {
       *r_buf = plaintext;
@@ -438,14 +449,16 @@ divert_pkdecrypt (ctrl_t ctrl,
   return rc;
 }
 
+int
+divert_writekey (ctrl_t ctrl, int force, const char *serialno,
+                 const char *id, const char *keydata, size_t keydatalen)
+{
+  return agent_card_writekey (ctrl, force, serialno, id, keydata, keydatalen,
+                              getpin_cb, ctrl);
+}
 
-int  
+int
 divert_generic_cmd (ctrl_t ctrl, const char *cmdline, void *assuan_context)
 {
   return agent_card_scd (ctrl, cmdline, getpin_cb, ctrl, assuan_context);
 }
-
-
-
-
-
index 6d85cfd..fbe3031 100644 (file)
@@ -1,6 +1,7 @@
 /* findkey.c - Locate the secret key
  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
  *               2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -29,7 +30,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <assert.h>
-#include <pth.h> /* (we use pth_sleep) */
+#include <npth.h> /* (we use pth_sleep) */
 
 #include "agent.h"
 #include "i18n.h"
@@ -58,69 +59,47 @@ agent_write_private_key (const unsigned char *grip,
                          const void *buffer, size_t length, int force)
 {
   char *fname;
-  FILE *fp;
+  estream_t fp;
   char hexgrip[40+4+1];
-  int fd;
 
   bin2hex (grip, 20, hexgrip);
   strcpy (hexgrip+40, ".key");
 
   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
 
+  /* FIXME: Write to a temp file first so that write failures during
+     key updates won't lead to a key loss.  */
+
   if (!force && !access (fname, F_OK))
     {
-      log_error ("secret key file `%s' already exists\n", fname);
+      log_error ("secret key file '%s' already exists\n", fname);
       xfree (fname);
-      return gpg_error (GPG_ERR_GENERAL);
-    }
-
-  /* In FORCE mode we would like to create FNAME but only if it does
-     not already exist.  We cannot make this guarantee just using
-     POSIX (GNU provides the "x" opentype for fopen, however, this is
-     not portable).  Thus, we use the more flexible open function and
-     then use fdopen to obtain a stream. */
-  fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY | O_BINARY)
-                         : (O_CREAT | O_EXCL | O_WRONLY | O_BINARY),
-             S_IRUSR | S_IWUSR
-#ifndef HAVE_W32_SYSTEM
-                 | S_IRGRP
-#endif
-                 );
-  if (fd < 0)
-    fp = NULL;
-  else
-    {
-      fp = fdopen (fd, "wb");
-      if (!fp)
-        {
-          int save_e = errno;
-          close (fd);
-          errno = save_e;
-        }
+      return gpg_error (GPG_ERR_EEXIST);
     }
 
+  fp = es_fopen (fname, force? "wb,mode=-rw" : "wbx,mode=-rw");
   if (!fp)
     {
-      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
-      log_error ("can't create `%s': %s\n", fname, strerror (errno));
+      gpg_error_t tmperr = gpg_error_from_syserror ();
+      log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
       xfree (fname);
       return tmperr;
     }
 
-  if (fwrite (buffer, length, 1, fp) != 1)
+  if (es_fwrite (buffer, length, 1, fp) != 1)
     {
-      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
-      log_error ("error writing `%s': %s\n", fname, strerror (errno));
-      fclose (fp);
-      remove (fname);
+      gpg_error_t tmperr = gpg_error_from_syserror ();
+      log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
+      es_fclose (fp);
+      gnupg_remove (fname);
       xfree (fname);
       return tmperr;
     }
-  if ( fclose (fp) )
+  if (es_fclose (fp))
     {
-      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
-      log_error ("error closing `%s': %s\n", fname, strerror (errno));
-      remove (fname);
+      gpg_error_t tmperr = gpg_error_from_syserror ();
+      log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
+      gnupg_remove (fname);
       xfree (fname);
       return tmperr;
     }
@@ -130,7 +109,7 @@ agent_write_private_key (const unsigned char *grip,
 }
 
 
-/* Callback function to try the unprotection from the passpharse query
+/* Callback function to try the unprotection from the passphrase query
    code. */
 static int
 try_unprotect_cb (struct pin_entry_info_s *pi)
@@ -144,7 +123,7 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
   assert (!arg->unprotected_key);
 
   arg->change_required = 0;
-  err = agent_unprotect (arg->protected_key, pi->pin, protected_at,
+  err = agent_unprotect (arg->ctrl, arg->protected_key, pi->pin, protected_at,
                          &arg->unprotected_key, &dummy);
   if (err)
     return err;
@@ -195,7 +174,8 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
                                         _("I'll change it later"), 0);
           if (!err)
             arg->change_required = 1;
-          else if (gpg_err_code (err) == GPG_ERR_CANCELED)
+          else if (gpg_err_code (err) == GPG_ERR_CANCELED
+                   || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
             err = 0;
         }
       xfree (desc);
@@ -210,6 +190,7 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
 
    %% - Replaced by a single %
    %c - Replaced by the content of COMMENT.
+   %C - Same as %c but put into parentheses.
    %F - Replaced by an ssh style fingerprint computed from KEY.
 
    The functions returns 0 on success or an error code.  On success a
@@ -261,6 +242,20 @@ modify_description (const char *in, const char *comment, const gcry_sexp_t key,
                     out_len += comment_length;
                   break;
 
+                case 'C': /* Comment.  */
+                  if (!comment_length)
+                    ;
+                  else if (out)
+                    {
+                      *out++ = '(';
+                      memcpy (out, comment, comment_length);
+                      out += comment_length;
+                      *out++ = ')';
+                    }
+                  else
+                    out_len += comment_length + 2;
+                  break;
+
                 case 'F': /* SSH style fingerprint.  */
                   if (!ssh_fpr && key)
                     ssh_get_fingerprint_string (key, &ssh_fpr);
@@ -318,11 +313,16 @@ modify_description (const char *in, const char *comment, const gcry_sexp_t key,
    should be the hex encoded keygrip of that key to be used with the
    caching mechanism. DESC_TEXT may be set to override the default
    description used for the pinentry.  If LOOKUP_TTL is given this
-   function is used to lookup the default ttl. */
+   function is used to lookup the default ttl.  If R_PASSPHRASE is not
+   NULL, the function succeeded and the key was protected the used
+   passphrase (entered or from the cache) is stored there; if not NULL
+   will be stored.  The caller needs to free the returned
+   passphrase. */
 static int
-unprotect (ctrl_t ctrl, const char *desc_text,
+unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
            unsigned char **keybuf, const unsigned char *grip,
-           cache_mode_t cache_mode, lookup_ttl_t lookup_ttl)
+           cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
+           char **r_passphrase)
 {
   struct pin_entry_info_s *pi;
   struct try_unprotect_arg_s arg;
@@ -331,29 +331,99 @@ unprotect (ctrl_t ctrl, const char *desc_text,
   size_t resultlen;
   char hexgrip[40+1];
 
+  if (r_passphrase)
+    *r_passphrase = NULL;
+
   bin2hex (grip, 20, hexgrip);
 
+  /* Initially try to get it using a cache nonce.  */
+  if (cache_nonce)
+    {
+      char *pw;
+
+      pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
+      if (pw)
+        {
+          rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
+          if (!rc)
+            {
+              if (r_passphrase)
+                *r_passphrase = pw;
+              else
+                xfree (pw);
+              xfree (*keybuf);
+              *keybuf = result;
+              return 0;
+            }
+          xfree (pw);
+        }
+    }
+
   /* First try to get it from the cache - if there is none or we can't
      unprotect it, we fall back to ask the user */
   if (cache_mode != CACHE_MODE_IGNORE)
     {
-      void *cache_marker;
-      const char *pw;
+      char *pw;
 
     retry:
-      pw = agent_get_cache (hexgrip, cache_mode, &cache_marker);
+      pw = agent_get_cache (hexgrip, cache_mode);
       if (pw)
         {
-          rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
-          agent_unlock_cache_entry (&cache_marker);
+          rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
           if (!rc)
             {
+              if (cache_mode == CACHE_MODE_NORMAL)
+                agent_store_cache_hit (hexgrip);
+              if (r_passphrase)
+                *r_passphrase = pw;
+              else
+                xfree (pw);
               xfree (*keybuf);
               *keybuf = result;
               return 0;
             }
+          xfree (pw);
           rc  = 0;
         }
+      else if (cache_mode == CACHE_MODE_NORMAL)
+        {
+          /* The standard use of GPG keys is to have a signing and an
+             encryption subkey.  Commonly both use the same
+             passphrase.  We try to help the user to enter the
+             passphrase only once by silently trying the last
+             correctly entered passphrase.  Checking one additional
+             passphrase should be acceptable; despite the S2K
+             introduced delays. The assumed workflow is:
+
+               1. Read encrypted message in a MUA and thus enter a
+                  passphrase for the encryption subkey.
+
+               2. Reply to that mail with an encrypted and signed
+                  mail, thus entering the passphrase for the signing
+                  subkey.
+
+             We can often avoid the passphrase entry in the second
+             step.  We do this only in normal mode, so not to
+             interfere with unrelated cache entries.  */
+          pw = agent_get_cache (NULL, cache_mode);
+          if (pw)
+            {
+              rc = agent_unprotect (ctrl, *keybuf, pw, NULL,
+                                    &result, &resultlen);
+              if (!rc)
+                {
+                  if (r_passphrase)
+                    *r_passphrase = pw;
+                  else
+                    xfree (pw);
+                  xfree (*keybuf);
+                  *keybuf = result;
+                  return 0;
+                }
+              xfree (pw);
+              rc  = 0;
+            }
+        }
 
       /* If the pinentry is currently in use, we wait up to 60 seconds
          for it to close and check the cache again.  This solves a common
@@ -372,7 +442,7 @@ unprotect (ctrl_t ctrl, const char *desc_text,
             {
               /* We need to give the other thread a chance to actually put
                  it into the cache. */
-              pth_sleep (1);
+              npth_sleep (1);
               goto retry;
             }
           /* Timeout - better call pinentry now the plain way. */
@@ -393,7 +463,7 @@ unprotect (ctrl_t ctrl, const char *desc_text,
   arg.change_required = 0;
   pi->check_cb_arg = &arg;
 
-  rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, hexgrip, cache_mode);
+  rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
   if (!rc)
     {
       assert (arg.unprotected_key);
@@ -415,7 +485,7 @@ unprotect (ctrl_t ctrl, const char *desc_text,
               xfree (pi);
               return rc;
             }
-          rc = agent_protect_and_store (ctrl, s_skey);
+          rc = agent_protect_and_store (ctrl, s_skey, NULL);
           gcry_sexp_release (s_skey);
           if (rc)
             {
@@ -428,8 +498,13 @@ unprotect (ctrl_t ctrl, const char *desc_text,
             }
         }
       else
-        agent_put_cache (hexgrip, cache_mode, pi->pin,
-                         lookup_ttl? lookup_ttl (hexgrip) : 0);
+        {
+          agent_put_cache (hexgrip, cache_mode, pi->pin,
+                           lookup_ttl? lookup_ttl (hexgrip) : 0);
+          agent_store_cache_hit (hexgrip);
+          if (r_passphrase && *pi->pin)
+            *r_passphrase = xtrystrdup (pi->pin);
+        }
       xfree (*keybuf);
       *keybuf = arg.unprotected_key;
     }
@@ -446,7 +521,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
 {
   int rc;
   char *fname;
-  FILE *fp;
+  estream_t fp;
   struct stat st;
   unsigned char *buf;
   size_t buflen, erroff;
@@ -459,33 +534,46 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
   strcpy (hexgrip+40, ".key");
 
   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
-  fp = fopen (fname, "rb");
+  fp = es_fopen (fname, "rb");
   if (!fp)
     {
       rc = gpg_error_from_syserror ();
       if (gpg_err_code (rc) != GPG_ERR_ENOENT)
-        log_error ("can't open `%s': %s\n", fname, strerror (errno));
+        log_error ("can't open '%s': %s\n", fname, strerror (errno));
       xfree (fname);
       return rc;
     }
 
-  if (fstat (fileno(fp), &st))
+  if (fstat (es_fileno (fp), &st))
     {
       rc = gpg_error_from_syserror ();
-      log_error ("can't stat `%s': %s\n", fname, strerror (errno));
+      log_error ("can't stat '%s': %s\n", fname, strerror (errno));
       xfree (fname);
-      fclose (fp);
+      es_fclose (fp);
       return rc;
     }
 
   buflen = st.st_size;
   buf = xtrymalloc (buflen+1);
-  if (!buf || fread (buf, buflen, 1, fp) != 1)
+  if (!buf)
     {
       rc = gpg_error_from_syserror ();
-      log_error ("error reading `%s': %s\n", fname, strerror (errno));
+      log_error ("error allocating %zu bytes for '%s': %s\n",
+                 buflen, fname, strerror (errno));
       xfree (fname);
-      fclose (fp);
+      es_fclose (fp);
+      xfree (buf);
+      return rc;
+
+    }
+
+  if (es_fread (buf, buflen, 1, fp) != 1)
+    {
+      rc = gpg_error_from_syserror ();
+      log_error ("error reading %zu bytes from '%s': %s\n",
+                 buflen, fname, strerror (errno));
+      xfree (fname);
+      es_fclose (fp);
       xfree (buf);
       return rc;
     }
@@ -493,7 +581,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
   /* Convert the file into a gcrypt S-expression object.  */
   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
   xfree (fname);
-  fclose (fp);
+  es_fclose (fp);
   xfree (buf);
   if (rc)
     {
@@ -506,35 +594,64 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
 }
 
 
+/* Remove the key identified by GRIP from the private key directory.  */
+static gpg_error_t
+remove_key_file (const unsigned char *grip)
+{
+  gpg_error_t err = 0;
+  char *fname;
+  char hexgrip[40+4+1];
+
+  bin2hex (grip, 20, hexgrip);
+  strcpy (hexgrip+40, ".key");
+  fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
+  if (gnupg_remove (fname))
+    err = gpg_error_from_syserror ();
+  xfree (fname);
+  return err;
+}
+
+
 /* Return the secret key as an S-Exp in RESULT after locating it using
-   the GRIP.  Stores NULL at RESULT if the operation shall be diverted
-   to a token; in this case an allocated S-expression with the
-   shadow_info part from the file is stored at SHADOW_INFO.
+   the GRIP.  If the operation shall be diverted to a token, an
+   allocated S-expression with the shadow_info part from the file is
+   stored at SHADOW_INFO; if not NULL will be stored at SHADOW_INFO.
    CACHE_MODE defines now the cache shall be used.  DESC_TEXT may be
    set to present a custom description for the pinentry.  LOOKUP_TTL
    is an optional function to convey a TTL to the cache manager; we do
-   not simply pass the TTL value because the value is only needed if an
-   unprotect action was needed and looking up the TTL may have some
-   overhead (e.g. scanning the sshcontrol file). */
+   not simply pass the TTL value because the value is only needed if
+   an unprotect action was needed and looking up the TTL may have some
+   overhead (e.g. scanning the sshcontrol file).  If a CACHE_NONCE is
+   given that cache item is first tried to get a passphrase.  If
+   R_PASSPHRASE is not NULL, the function succeeded and the key was
+   protected the used passphrase (entered or from the cache) is stored
+   there; if not NULL will be stored.  The caller needs to free the
+   returned passphrase.   */
 gpg_error_t
-agent_key_from_file (ctrl_t ctrl, const char *desc_text,
+agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
+                     const char *desc_text,
                      const unsigned char *grip, unsigned char **shadow_info,
                      cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
-                     gcry_sexp_t *result)
+                     gcry_sexp_t *result, char **r_passphrase)
 {
   int rc;
   unsigned char *buf;
   size_t len, buflen, erroff;
   gcry_sexp_t s_skey;
-  int got_shadow_info = 0;
 
   *result = NULL;
   if (shadow_info)
     *shadow_info = NULL;
+  if (r_passphrase)
+    *r_passphrase = NULL;
 
   rc = read_key_file (grip, &s_skey);
   if (rc)
-    return rc;
+    {
+      if (gpg_err_code (rc) == GPG_ERR_ENOENT)
+        rc = gpg_error (GPG_ERR_NO_SECKEY);
+      return rc;
+    }
 
   /* For use with the protection functions we also need the key as an
      canonical encoded S-expression in a buffer.  Create this buffer
@@ -572,8 +689,8 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
 
        if (!rc)
          {
-           rc = unprotect (ctrl, desc_text_final, &buf, grip,
-                            cache_mode, lookup_ttl);
+           rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
+                            cache_mode, lookup_ttl, r_passphrase);
            if (rc)
              log_error ("failed to unprotect the secret key: %s\n",
                         gpg_strerror (rc));
@@ -600,7 +717,6 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
                 {
                   memcpy (*shadow_info, s, n);
                   rc = 0;
-                  got_shadow_info = 1;
                 }
             }
           if (rc)
@@ -616,9 +732,14 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
     }
   gcry_sexp_release (s_skey);
   s_skey = NULL;
-  if (rc || got_shadow_info)
+  if (rc)
     {
       xfree (buf);
+      if (r_passphrase)
+        {
+          xfree (*r_passphrase);
+          *r_passphrase = NULL;
+        }
       return rc;
     }
 
@@ -630,6 +751,11 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
     {
       log_error ("failed to build S-Exp (off=%u): %s\n",
                  (unsigned int)erroff, gpg_strerror (rc));
+      if (r_passphrase)
+        {
+          xfree (*r_passphrase);
+          *r_passphrase = NULL;
+        }
       return rc;
     }
 
@@ -638,6 +764,186 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
 }
 
 
+/* Return the string name from the S-expression S_KEY as well as a
+   string describing the names of the parameters.  ALGONAMESIZE and
+   ELEMSSIZE give the allocated size of the provided buffers.  The
+   buffers may be NULL if not required.  If R_LIST is not NULL the top
+   level list will be stored there; the caller needs to release it in
+   this case.  */
+static gpg_error_t
+key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
+                     char *r_algoname, size_t algonamesize,
+                     char *r_elems, size_t elemssize)
+{
+  gcry_sexp_t list, l2;
+  const char *name, *algoname, *elems;
+  size_t n;
+
+  if (r_list)
+    *r_list = NULL;
+
+  list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
+  if (!list)
+    list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
+  if (!list)
+    list = gcry_sexp_find_token (s_key, "private-key", 0 );
+  if (!list)
+    {
+      log_error ("invalid private key format\n");
+      return gpg_error (GPG_ERR_BAD_SECKEY);
+    }
+
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  name = gcry_sexp_nth_data (list, 0, &n);
+  if (n==3 && !memcmp (name, "rsa", 3))
+    {
+      algoname = "rsa";
+      elems = "ne";
+    }
+  else if (n==3 && !memcmp (name, "dsa", 3))
+    {
+      algoname = "dsa";
+      elems = "pqgy";
+    }
+  else if (n==3 && !memcmp (name, "ecc", 3))
+    {
+      algoname = "ecc";
+      elems = "pabgnq";
+    }
+  else if (n==5 && !memcmp (name, "ecdsa", 5))
+    {
+      algoname = "ecdsa";
+      elems = "pabgnq";
+    }
+  else if (n==4 && !memcmp (name, "ecdh", 4))
+    {
+      algoname = "ecdh";
+      elems = "pabgnq";
+    }
+  else if (n==3 && !memcmp (name, "elg", 3))
+    {
+      algoname = "elg";
+      elems = "pgy";
+    }
+  else
+    {
+      log_error ("unknown private key algorithm\n");
+      gcry_sexp_release (list);
+      return gpg_error (GPG_ERR_BAD_SECKEY);
+    }
+
+  if (r_algoname)
+    {
+      if (strlen (algoname) >= algonamesize)
+        return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+      strcpy (r_algoname, algoname);
+    }
+  if (r_elems)
+    {
+      if (strlen (elems) >= elemssize)
+        return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+      strcpy (r_elems, elems);
+    }
+
+  if (r_list)
+    *r_list = list;
+  else
+    gcry_sexp_release (list);
+
+  return 0;
+}
+
+
+/* Return true if KEYPARMS holds an EdDSA key.  */
+static int
+is_eddsa (gcry_sexp_t keyparms)
+{
+  int result = 0;
+  gcry_sexp_t list;
+  const char *s;
+  size_t n;
+  int i;
+
+  list = gcry_sexp_find_token (keyparms, "flags", 0);
+  for (i = list ? gcry_sexp_length (list)-1 : 0; i > 0; i--)
+    {
+      s = gcry_sexp_nth_data (list, i, &n);
+      if (!s)
+        continue; /* Not a data element. */
+
+      if (n == 5 && !memcmp (s, "eddsa", 5))
+        {
+          result = 1;
+          break;
+        }
+    }
+  gcry_sexp_release (list);
+  return result;
+}
+
+
+/* Return the public key algorithm number if S_KEY is a DSA style key.
+   If it is not a DSA style key, return 0.  */
+int
+agent_is_dsa_key (gcry_sexp_t s_key)
+{
+  int result;
+  gcry_sexp_t list;
+  char algoname[6];
+
+  if (!s_key)
+    return 0;
+
+  if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
+    return 0; /* Error - assume it is not an DSA key.  */
+
+  if (!strcmp (algoname, "dsa"))
+    result = GCRY_PK_DSA;
+  else if (!strcmp (algoname, "ecc"))
+    {
+      if (is_eddsa (list))
+        result = 0;
+      else
+        result = GCRY_PK_ECDSA;
+    }
+  else if (!strcmp (algoname, "ecdsa"))
+    result = GCRY_PK_ECDSA;
+  else
+    result = 0;
+
+  gcry_sexp_release (list);
+  return result;
+}
+
+
+/* Return true if S_KEY is an EdDSA key as used with curve Ed25519.  */
+int
+agent_is_eddsa_key (gcry_sexp_t s_key)
+{
+  int result;
+  gcry_sexp_t list;
+  char algoname[6];
+
+  if (!s_key)
+    return 0;
+
+  if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
+    return 0; /* Error - assume it is not an EdDSA key.  */
+
+  if (!strcmp (algoname, "ecc") && is_eddsa (list))
+    result = 1;
+  else if (!strcmp (algoname, "eddsa")) /* backward compatibility.  */
+    result = 1;
+  else
+    result = 0;
+
+  gcry_sexp_release (list);
+  return result;
+}
+
+
 /* Return the key for the keygrip GRIP.  The result is stored at
    RESULT.  This function extracts the key from the private key
    database and returns it as an S-expression object as it is.  On
@@ -669,9 +975,11 @@ agent_public_key_from_file (ctrl_t ctrl,
                             const unsigned char *grip,
                             gcry_sexp_t *result)
 {
-  int i, idx, rc;
+  gpg_error_t err;
+  int i, idx;
   gcry_sexp_t s_skey;
-  const char *algoname;
+  char algoname[6];
+  char elems[7];
   gcry_sexp_t uri_sexp, comment_sexp;
   const char *uri, *comment;
   size_t uri_length, comment_length;
@@ -680,57 +988,24 @@ agent_public_key_from_file (ctrl_t ctrl,
                            for comment + end-of-list.  */
   int argidx;
   gcry_sexp_t list, l2;
-  const char *name;
   const char *s;
-  size_t n;
-  const char *elems;
   gcry_mpi_t *array;
 
   (void)ctrl;
 
   *result = NULL;
 
-  rc = read_key_file (grip, &s_skey);
-  if (rc)
-    return rc;
-
-  list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
-  if (!list)
-    list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
-  if (!list)
-    list = gcry_sexp_find_token (s_skey, "private-key", 0 );
-  if (!list)
-    {
-      log_error ("invalid private key format\n");
-      gcry_sexp_release (s_skey);
-      return gpg_error (GPG_ERR_BAD_SECKEY);
-    }
+  err = read_key_file (grip, &s_skey);
+  if (err)
+    return err;
 
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
-  list = l2;
-  name = gcry_sexp_nth_data (list, 0, &n);
-  if (n==3 && !memcmp (name, "rsa", 3))
-    {
-      algoname = "rsa";
-      elems = "ne";
-    }
-  else if (n==3 && !memcmp (name, "dsa", 3))
-    {
-      algoname = "dsa";
-      elems = "pqgy";
-    }
-  else if (n==3 && !memcmp (name, "elg", 3))
-    {
-      algoname = "elg";
-      elems = "pgy";
-    }
-  else
+  err = key_parms_from_sexp (s_skey, &list,
+                            algoname, sizeof algoname,
+                            elems, sizeof elems);
+  if (err)
     {
-      log_error ("unknown private key algorithm\n");
-      gcry_sexp_release (list);
       gcry_sexp_release (s_skey);
-      return gpg_error (GPG_ERR_BAD_SECKEY);
+      return err;
     }
 
   /* Allocate an array for the parameters and copy them out of the
@@ -738,10 +1013,10 @@ agent_public_key_from_file (ctrl_t ctrl,
   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
   if (!array)
     {
-      rc = gpg_error_from_syserror ();
+      err = gpg_error_from_syserror ();
       gcry_sexp_release (list);
       gcry_sexp_release (s_skey);
-      return rc;
+      return err;
     }
 
   for (idx=0, s=elems; *s; s++, idx++ )
@@ -790,8 +1065,8 @@ agent_public_key_from_file (ctrl_t ctrl,
 
 
   /* FIXME: The following thing is pretty ugly code; we should
-     investigate how to make it cleaner. Probably code to handle
-     canonical S-expressions in a memory buffer is better suioted for
+     investigate how to make it cleaner.  Probably code to handle
+     canonical S-expressions in a memory buffer is better suited for
      such a task.  After all that is what we do in protect.c.  Neeed
      to find common patterns and write a straightformward API to use
      them.  */
@@ -800,13 +1075,13 @@ agent_public_key_from_file (ctrl_t ctrl,
   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
   if (!format)
     {
-      rc = gpg_error_from_syserror ();
+      err = gpg_error_from_syserror ();
       for (i=0; array[i]; i++)
         gcry_mpi_release (array[i]);
       xfree (array);
       gcry_sexp_release (uri_sexp);
       gcry_sexp_release (comment_sexp);
-      return rc;
+      return err;
     }
 
   argidx = 0;
@@ -839,7 +1114,7 @@ agent_public_key_from_file (ctrl_t ctrl,
   assert (argidx < DIM (args));
   args[argidx] = NULL;
 
-  rc = gcry_sexp_build_array (&list, NULL, format, args);
+  err = gcry_sexp_build_array (&list, NULL, format, args);
   xfree (format);
   for (i=0; array[i]; i++)
     gcry_mpi_release (array[i]);
@@ -847,15 +1122,15 @@ agent_public_key_from_file (ctrl_t ctrl,
   gcry_sexp_release (uri_sexp);
   gcry_sexp_release (comment_sexp);
 
-  if (!rc)
+  if (!err)
     *result = list;
-  return rc;
+  return err;
 }
 
 
 
-/* Return the secret key as an S-Exp after locating it using the grip.
-   Returns NULL if key is not available. 0 = key is available */
+/* Check whether the the secret key identified by GRIP is available.
+   Returns 0 is the key is available.  */
 int
 agent_key_available (const unsigned char *grip)
 {
@@ -950,3 +1225,112 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
   xfree (buf);
   return err;
 }
+
+
+\f
+/* Delete the key with GRIP from the disk after having asked for
+   confirmation using DESC_TEXT.  Common error codes are:
+     GPG_ERR_NO_SECKEY
+     GPG_ERR_KEY_ON_CARD
+     GPG_ERR_NOT_CONFIRMED
+*/
+gpg_error_t
+agent_delete_key (ctrl_t ctrl, const char *desc_text,
+                  const unsigned char *grip)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_skey = NULL;
+  unsigned char *buf = NULL;
+  size_t len;
+  char *desc_text_final = NULL;
+  char *comment = NULL;
+  ssh_control_file_t cf = NULL;
+  char hexgrip[40+4+1];
+  char *default_desc = NULL;
+
+  err = read_key_file (grip, &s_skey);
+  if (gpg_err_code (err) == GPG_ERR_ENOENT)
+    err = gpg_error (GPG_ERR_NO_SECKEY);
+  if (err)
+    goto leave;
+
+  err = make_canon_sexp (s_skey, &buf, &len);
+  if (err)
+    goto leave;
+
+  switch (agent_private_key_type (buf))
+    {
+    case PRIVATE_KEY_CLEAR:
+    case PRIVATE_KEY_PROTECTED:
+      {
+        bin2hex (grip, 20, hexgrip);
+        if (!desc_text)
+          {
+            default_desc = xtryasprintf
+              ("Do you really want to delete the key identified by keygrip%%0A"
+               "  %s%%0A  %%C%%0A?", hexgrip);
+            desc_text = default_desc;
+          }
+
+        /* Note, that we will take the comment as a C string for
+           display purposes; i.e. all stuff beyond a Nul character is
+           ignored.  */
+        {
+          gcry_sexp_t comment_sexp;
+
+          comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
+          if (comment_sexp)
+            comment = gcry_sexp_nth_string (comment_sexp, 1);
+          gcry_sexp_release (comment_sexp);
+        }
+
+       if (desc_text)
+          err = modify_description (desc_text, comment? comment:"", s_skey,
+                                    &desc_text_final);
+       if (err)
+          goto leave;
+
+        err = agent_get_confirmation (ctrl, desc_text_final,
+                                      _("Delete key"), _("No"), 0);
+        if (err)
+          goto leave;
+
+        cf = ssh_open_control_file ();
+        if (cf)
+          {
+            if (!ssh_search_control_file (cf, hexgrip, NULL, NULL, NULL))
+              {
+                err = agent_get_confirmation
+                  (ctrl,
+                   _("Warning: This key is also listed for use with SSH!\n"
+                     "Deleting the key might remove your ability to "
+                     "access remote machines."),
+                   _("Delete key"), _("No"), 0);
+                if (err)
+                  goto leave;
+              }
+          }
+
+        err = remove_key_file (grip);
+      }
+      break;
+
+    case PRIVATE_KEY_SHADOWED:
+      err = gpg_error (GPG_ERR_KEY_ON_CARD);
+      break;
+
+    default:
+      log_error ("invalid private key format\n");
+      err = gpg_error (GPG_ERR_BAD_SECKEY);
+      break;
+    }
+
+ leave:
+  ssh_close_control_file (cf);
+  gcry_free (comment);
+  xfree (desc_text_final);
+  xfree (default_desc);
+  xfree (buf);
+  gcry_sexp_release (s_skey);
+  return err;
+}
index 562f7a2..91917f7 100644 (file)
@@ -1,5 +1,5 @@
 /* genkey.c - Generate a keypair
- *     Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2007, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -31,7 +31,8 @@
 #include "sysutils.h"
 
 static int
-store_key (gcry_sexp_t private, const char *passphrase, int force)
+store_key (gcry_sexp_t private, const char *passphrase, int force,
+       unsigned long s2k_count)
 {
   int rc;
   unsigned char *buf;
@@ -56,7 +57,7 @@ store_key (gcry_sexp_t private, const char *passphrase, int force)
     {
       unsigned char *p;
 
-      rc = agent_protect (buf, passphrase, &p, &len);
+      rc = agent_protect (buf, passphrase, &p, &len, s2k_count);
       if (rc)
         {
           xfree (buf);
@@ -117,7 +118,8 @@ check_passphrase_pattern (ctrl_t ctrl, const char *pw)
       fclose (infp);
       return 1; /* Error - assume password should not be used.  */
     }
-  rewind (infp);
+  fseek (infp, 0, SEEK_SET);
+  clearerr (infp);
 
   i = 0;
   argv[i++] = "--null";
@@ -128,13 +130,15 @@ check_passphrase_pattern (ctrl_t ctrl, const char *pw)
 
   if (gnupg_spawn_process_fd (pgmname, argv, fileno (infp), -1, -1, &pid))
     result = 1; /* Execute error - assume password should no be used.  */
-  else if (gnupg_wait_process (pgmname, pid, NULL))
+  else if (gnupg_wait_process (pgmname, pid, 1, NULL))
     result = 1; /* Helper returned an error - probably a match.  */
   else
     result = 0; /* Success; i.e. no match.  */
+  gnupg_release_process (pid);
 
   /* Overwrite our temporary file. */
-  rewind (infp);
+  fseek (infp, 0, SEEK_SET);
+  clearerr (infp);
   for (i=((strlen (pw)+99)/100)*100; i > 0; i--)
     putc ('\xff', infp);
   fflush (infp);
@@ -175,98 +179,132 @@ take_this_one_anyway (ctrl_t ctrl, const char *desc)
 int
 check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent)
 {
-  gpg_error_t err;
+  gpg_error_t err = 0;
   unsigned int minlen = opt.min_passphrase_len;
   unsigned int minnonalpha = opt.min_passphrase_nonalpha;
+  char *msg1 = NULL;
+  char *msg2 = NULL;
+  char *msg3 = NULL;
 
   if (!pw)
     pw = "";
 
-  if (utf8_charcount (pw) < minlen )
+  /* The first check is to warn about an empty passphrase. */
+  if (!*pw)
     {
-      char *desc;
+      const char *desc = (opt.enforce_passphrase_constraints?
+                          _("You have not entered a passphrase!%0A"
+                            "An empty passphrase is not allowed.") :
+                          _("You have not entered a passphrase - "
+                            "this is in general a bad idea!%0A"
+                            "Please confirm that you do not want to "
+                            "have any protection on your key."));
 
       if (silent)
         return gpg_error (GPG_ERR_INV_PASSPHRASE);
 
-      desc = xtryasprintf
-        ( ngettext ("Warning: You have entered an insecure passphrase.%%0A"
-                    "A passphrase should be at least %u character long.",
-                    "Warning: You have entered an insecure passphrase.%%0A"
+      err = take_this_one_anyway2 (ctrl, desc,
+                                   _("Yes, protection is not needed"));
+      goto leave;
+    }
+
+  /* Now check the constraints and collect the error messages unless
+     in in silent mode which returns immediately.  */
+  if (utf8_charcount (pw) < minlen )
+    {
+      if (silent)
+        {
+          err = gpg_error (GPG_ERR_INV_PASSPHRASE);
+          goto leave;
+        }
+
+      msg1 = xtryasprintf
+        ( ngettext ("A passphrase should be at least %u character long.",
                     "A passphrase should be at least %u characters long.",
                     minlen), minlen );
-      if (!desc)
-        return gpg_error_from_syserror ();
-      err = take_this_one_anyway (ctrl, desc);
-      xfree (desc);
-      if (err)
-        return err;
+      if (!msg1)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
 
   if (nonalpha_count (pw) < minnonalpha )
     {
-      char *desc;
-
       if (silent)
-        return gpg_error (GPG_ERR_INV_PASSPHRASE);
+        {
+          err = gpg_error (GPG_ERR_INV_PASSPHRASE);
+          goto leave;
+        }
 
-      desc = xtryasprintf
-        ( ngettext ("Warning: You have entered an insecure passphrase.%%0A"
-                    "A passphrase should contain at least %u digit or%%0A"
+      msg2 = xtryasprintf
+        ( ngettext ("A passphrase should contain at least %u digit or%%0A"
                     "special character.",
-                    "Warning: You have entered an insecure passphrase.%%0A"
                     "A passphrase should contain at least %u digits or%%0A"
                     "special characters.",
                     minnonalpha), minnonalpha );
-      if (!desc)
-        return gpg_error_from_syserror ();
-      err = take_this_one_anyway (ctrl, desc);
-      xfree (desc);
-      if (err)
-        return err;
+      if (!msg2)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
 
-  /* If configured check the passphrase against a list of know words
+  /* If configured check the passphrase against a list of known words
      and pattern.  The actual test is done by an external program.
      The warning message is generic to give the user no hint on how to
      circumvent this list.  */
   if (*pw && opt.check_passphrase_pattern &&
       check_passphrase_pattern (ctrl, pw))
     {
-      const char *desc =
-        /* */     _("Warning: You have entered an insecure passphrase.%%0A"
-                    "A passphrase may not be a known term or match%%0A"
-                    "certain pattern.");
-
       if (silent)
-        return gpg_error (GPG_ERR_INV_PASSPHRASE);
+        {
+          err = gpg_error (GPG_ERR_INV_PASSPHRASE);
+          goto leave;
+        }
 
-      err = take_this_one_anyway (ctrl, desc);
-      if (err)
-        return err;
+      msg3 = xtryasprintf
+        (_("A passphrase may not be a known term or match%%0A"
+           "certain pattern."));
+      if (!msg3)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
 
-  /* The final check is to warn about an empty passphrase. */
-  if (!*pw)
+  if (msg1 || msg2 || msg3)
     {
-      const char *desc = (opt.enforce_passphrase_constraints?
-                          _("You have not entered a passphrase!%0A"
-                            "An empty passphrase is not allowed.") :
-                          _("You have not entered a passphrase - "
-                            "this is in general a bad idea!%0A"
-                            "Please confirm that you do not want to "
-                            "have any protection on your key."));
-
-      if (silent)
-        return gpg_error (GPG_ERR_INV_PASSPHRASE);
-
-      err = take_this_one_anyway2 (ctrl, desc,
-                                   _("Yes, protection is not needed"));
-      if (err)
-        return err;
+      char *msg;
+      size_t n;
+
+      msg = strconcat
+        (_("Warning: You have entered an insecure passphrase."),
+         "%0A%0A",
+         msg1? msg1 : "", msg1? "%0A" : "",
+         msg2? msg2 : "", msg2? "%0A" : "",
+         msg3? msg3 : "", msg3? "%0A" : "",
+         NULL);
+      if (!msg)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      /* Strip a trailing "%0A".  */
+      n = strlen (msg);
+      if (n > 3 && !strcmp (msg + n - 3, "%0A"))
+        msg[n-3] = 0;
+
+      /* Show error messages.  */
+      err = take_this_one_anyway (ctrl, msg);
+      xfree (msg);
     }
 
-  return 0;
+ leave:
+  xfree (msg1);
+  xfree (msg2);
+  xfree (msg3);
+  return err;
 }
 
 
@@ -283,15 +321,103 @@ reenter_compare_cb (struct pin_entry_info_s *pi)
 }
 
 
+/* Ask the user for a new passphrase using PROMPT.  On success the
+   function returns 0 and store the passphrase at R_PASSPHRASE; if the
+   user opted not to use a passphrase NULL will be stored there.  The
+   user needs to free the returned string.  In case of an error and
+   error code is returned and NULL stored at R_PASSPHRASE.  */
+gpg_error_t
+agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
+                          char **r_passphrase)
+{
+  gpg_error_t err;
+  const char *text1 = prompt;
+  const char *text2 = _("Please re-enter this passphrase");
+  const char *initial_errtext = NULL;
+  struct pin_entry_info_s *pi, *pi2;
+
+  *r_passphrase = NULL;
+
+  if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
+    {
+       size_t size;
+       size_t len = 100;
+       unsigned char *buffer;
+
+       err = pinentry_loopback(ctrl, "NEW_PASSPHRASE", &buffer, &size, len);
+       if (!err)
+         {
+           if (size)
+             {
+               buffer[size] = 0;
+               *r_passphrase = buffer;
+             }
+           else
+               *r_passphrase = NULL;
+         }
+       return err;
+    }
+
+  pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
+  pi2 = pi + (sizeof *pi + 100);
+  pi->max_length = 100;
+  pi->max_tries = 3;
+  pi->with_qualitybar = 1;
+  pi->with_repeat = 1;
+  pi2->max_length = 100;
+  pi2->max_tries = 3;
+  pi2->check_cb = reenter_compare_cb;
+  pi2->check_cb_arg = pi->pin;
+
+ next_try:
+  err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
+  initial_errtext = NULL;
+  if (!err)
+    {
+      if (check_passphrase_constraints (ctrl, pi->pin, 0))
+        {
+          pi->failed_tries = 0;
+          pi2->failed_tries = 0;
+          goto next_try;
+        }
+      /* Unless the passphrase is empty or the pinentry told us that
+         it already did the repetition check, ask to confirm it.  */
+      if (pi->pin && *pi->pin && !pi->repeat_okay)
+        {
+          err = agent_askpin (ctrl, text2, NULL, NULL, pi2);
+          if (err == -1)
+            { /* The re-entered one did not match and the user did not
+                 hit cancel. */
+              initial_errtext = _("does not match - try again");
+              goto next_try;
+            }
+        }
+    }
+
+  if (!err && *pi->pin)
+    {
+      /* User wants a passphrase. */
+      *r_passphrase = xtrystrdup (pi->pin);
+      if (!*r_passphrase)
+        err = gpg_error_from_syserror ();
+    }
+  xfree (pi);
+  return err;
+}
+
+
 
 /* Generate a new keypair according to the parameters given in
-   KEYPARAM */
+   KEYPARAM.  If CACHE_NONCE is given first try to lookup a passphrase
+   using the cache nonce.  If NO_PROTECTION is true the key will not
+   be protected by a passphrase.  */
 int
-agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
-              membuf_t *outbuf)
+agent_genkey (ctrl_t ctrl, const char *cache_nonce,
+              const char *keyparam, size_t keyparamlen, int no_protection,
+              int preset, membuf_t *outbuf)
 {
   gcry_sexp_t s_keyparam, s_key, s_private, s_public;
-  struct pin_entry_info_s *pi, *pi2;
+  char *passphrase;
   int rc;
   size_t len;
   char *buf;
@@ -304,66 +430,27 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
     }
 
   /* Get the passphrase now, cause key generation may take a while. */
-  {
-    const char *text1 = _("Please enter the passphrase to%0A"
-                               "protect your new key");
-    const char *text2 = _("Please re-enter this passphrase");
-    const char *initial_errtext = NULL;
-
-    pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
-    pi->max_length = 100 + 1;
-    pi->max_tries = 3;
-    pi->with_qualitybar = 1;
-    pi2 = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
-    pi2->max_length = 100 + 1;
-    pi2->max_tries = 3;
-    pi2->check_cb = reenter_compare_cb;
-    pi2->check_cb_arg = pi->pin;
-
-  next_try:
-    rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi, NULL, 0);
-    initial_errtext = NULL;
-    if (!rc)
-      {
-        if (check_passphrase_constraints (ctrl, pi->pin, 0))
-          {
-            pi->failed_tries = 0;
-            pi2->failed_tries = 0;
-            goto next_try;
-          }
-        if (pi->pin && *pi->pin)
-          {
-            rc = agent_askpin (ctrl, text2, NULL, NULL, pi2, NULL, 0);
-            if (rc == -1)
-              { /* The re-entered one did not match and the user did not
-                   hit cancel. */
-                initial_errtext = _("does not match - try again");
-                goto next_try;
-              }
-          }
-      }
-    if (rc)
-      {
-        xfree (pi);
-        xfree (pi2);
-        return rc;
-      }
-
-    if (!*pi->pin)
-      {
-        xfree (pi);
-        xfree (pi2);
-        pi = pi2 = NULL; /* User does not want a passphrase. */
-      }
-  }
+  if (no_protection || !cache_nonce)
+    passphrase = NULL;
+  else
+    passphrase = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
+
+  if (passphrase || no_protection)
+    rc = 0;
+  else
+    rc = agent_ask_new_passphrase (ctrl,
+                                   _("Please enter the passphrase to%0A"
+                                     "protect your new key"),
+                                   &passphrase);
+  if (rc)
+    return rc;
 
   rc = gcry_pk_genkey (&s_key, s_keyparam );
   gcry_sexp_release (s_keyparam);
   if (rc)
     {
       log_error ("key generation failed: %s\n", gpg_strerror (rc));
-      xfree (pi);
-      xfree (pi2);
+      xfree (passphrase);
       return rc;
     }
 
@@ -373,8 +460,7 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
     {
       log_error ("key generation failed: invalid return value\n");
       gcry_sexp_release (s_key);
-      xfree (pi);
-      xfree (pi2);
+      xfree (passphrase);
       return gpg_error (GPG_ERR_INV_DATA);
     }
   s_public = gcry_sexp_find_token (s_key, "public-key", 0);
@@ -383,8 +469,7 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
       log_error ("key generation failed: invalid return value\n");
       gcry_sexp_release (s_private);
       gcry_sexp_release (s_key);
-      xfree (pi);
-      xfree (pi2);
+      xfree (passphrase);
       return gpg_error (GPG_ERR_INV_DATA);
     }
   gcry_sexp_release (s_key); s_key = NULL;
@@ -392,9 +477,34 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
   /* store the secret key */
   if (DBG_CRYPTO)
     log_debug ("storing private key\n");
-  rc = store_key (s_private, pi? pi->pin:NULL, 0);
-  xfree (pi);
-  xfree (pi2);
+  rc = store_key (s_private, passphrase, 0, ctrl->s2k_count);
+  if (!rc)
+    {
+      if (!cache_nonce)
+        {
+          char tmpbuf[12];
+          gcry_create_nonce (tmpbuf, 12);
+          cache_nonce = bin2hex (tmpbuf, 12, NULL);
+        }
+      if (cache_nonce
+          && !no_protection
+          && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
+                               passphrase, ctrl->cache_ttl_opt_preset))
+        agent_write_status (ctrl, "CACHE_NONCE", cache_nonce, NULL);
+      if (preset && !no_protection)
+       {
+         unsigned char grip[20];
+         char hexgrip[40+1];
+         if (gcry_pk_get_keygrip (s_private, grip))
+           {
+             bin2hex(grip, 20, hexgrip);
+             rc = agent_put_cache (hexgrip, CACHE_MODE_ANY, passphrase,
+                                    ctrl->cache_ttl_opt_preset);
+           }
+       }
+    }
+  xfree (passphrase);
+  passphrase = NULL;
   gcry_sexp_release (s_private);
   if (rc)
     {
@@ -426,68 +536,41 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
 
 
 \f
-/* Apply a new passpahrse to the key S_SKEY and store it. */
-int
-agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey)
+/* Apply a new passphrase to the key S_SKEY and store it.  If
+   PASSPHRASE_ADDR and *PASSPHRASE_ADDR are not NULL, use that
+   passphrase.  If PASSPHRASE_ADDR is not NULL store a newly entered
+   passphrase at that address. */
+gpg_error_t
+agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
+                         char **passphrase_addr)
 {
-  struct pin_entry_info_s *pi, *pi2;
-  int rc;
+  gpg_error_t err;
 
-  {
-    const char *text1 = _("Please enter the new passphrase");
-    const char *text2 = _("Please re-enter this passphrase");
-    const char *initial_errtext = NULL;
-
-    pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
-    pi->max_length = 100 + 1;
-    pi->max_tries = 3;
-    pi->with_qualitybar = 1;
-    pi2 = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
-    pi2->max_length = 100 + 1;
-    pi2->max_tries = 3;
-    pi2->check_cb = reenter_compare_cb;
-    pi2->check_cb_arg = pi->pin;
-
-  next_try:
-    rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi, NULL, 0);
-    initial_errtext = NULL;
-    if (!rc)
-      {
-        if (check_passphrase_constraints (ctrl, pi->pin, 0))
-          {
-            pi->failed_tries = 0;
-            pi2->failed_tries = 0;
-            goto next_try;
-          }
-        /* Unless the passphrase is empty, ask to confirm it.  */
-        if (pi->pin && *pi->pin)
-          {
-            rc = agent_askpin (ctrl, text2, NULL, NULL, pi2, NULL, 0);
-            if (rc == -1)
-              { /* The re-entered one did not match and the user did not
-                   hit cancel. */
-                initial_errtext = _("does not match - try again");
-                goto next_try;
-              }
-          }
-      }
-    if (rc)
-      {
-        xfree (pi);
-        xfree (pi2);
-        return rc;
-      }
-
-    if (!*pi->pin)
-      {
-        xfree (pi);
-        xfree (pi2);
-        pi = pi2 = NULL; /* User does not want a passphrase. */
-      }
-  }
-
-  rc = store_key (s_skey, pi? pi->pin:NULL, 1);
-  xfree (pi);
-  xfree (pi2);
-  return rc;
+  if (passphrase_addr && *passphrase_addr)
+    {
+      /* Take an empty string as request not to protect the key.  */
+      err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1,
+             ctrl->s2k_count);
+    }
+  else
+    {
+      char *pass = NULL;
+
+      if (passphrase_addr)
+        {
+          xfree (*passphrase_addr);
+          *passphrase_addr = NULL;
+        }
+      err = agent_ask_new_passphrase (ctrl,
+                                      _("Please enter the new passphrase"),
+                                      &pass);
+      if (!err)
+        err = store_key (s_skey, pass, 1, ctrl->s2k_count);
+      if (!err && passphrase_addr)
+        *passphrase_addr = pass;
+      else
+        xfree (pass);
+    }
+
+  return err;
 }
index 3b4a181..720f5f4 100644 (file)
@@ -1,7 +1,6 @@
 /* gpg-agent.c  -  The GnuPG Agent
- * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006, 2007, 2009, 2010 Free Software Foundation, Inc.
- * Copyright (C) 2013 Werner Koch
+ * Copyright (C) 2000-2007, 2009-2010 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
 # include <sys/un.h>
 #endif /*!HAVE_W32_SYSTEM*/
 #include <unistd.h>
-#include <signal.h>
-#include <pth.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+#include <npth.h>
 
 #define JNLIB_NEED_LOG_LOGV
 #define JNLIB_NEED_AFLOCAL
 #include "i18n.h"
 #include "mkdtemp.h" /* Gnulib replacement. */
 #include "sysutils.h"
-#include "setenv.h"
 #include "gc-opt-flags.h"
 #include "exechelp.h"
-#include "../common/estream.h"
+#include "asshelp.h"
+#include "openpgpdefs.h"  /* for PUBKEY_ALGO_ECDSA, PUBKEY_ALGO_ECDH */
+#include "../common/init.h"
+
 
 enum cmd_and_opt_values
 { aNull = 0,
@@ -77,6 +80,7 @@ enum cmd_and_opt_values
   oDebugAll,
   oDebugLevel,
   oDebugWait,
+  oDebugQuickRandom,
   oNoGreeting,
   oNoOptions,
   oHomedir,
@@ -114,12 +118,13 @@ enum cmd_and_opt_values
   oAllowMarkTrusted,
   oNoAllowMarkTrusted,
   oAllowPresetPassphrase,
-  oNoAllowExternalCache,
+  oAllowLoopbackPinentry,
   oKeepTTY,
   oKeepDISPLAY,
   oSSHSupport,
   oPuttySupport,
   oDisableScdaemon,
+  oDisableCheckOwnSocket,
   oWriteEnvFile
 };
 
@@ -144,18 +149,19 @@ static ARGPARSE_OPTS opts[] = {
   { oDebugAll, "debug-all"     ,0, "@"},
   { oDebugLevel, "debug-level" ,2, "@"},
   { oDebugWait,"debug-wait",1, "@"},
+  ARGPARSE_s_n (oDebugQuickRandom, "debug-quick-random", "@"),
   { oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
   { oNoGrab, "no-grab"     ,0, N_("do not grab keyboard and mouse")},
   { oLogFile, "log-file"   ,2, N_("use a log file for the server")},
-  { oUseStandardSocket, "use-standard-socket", 0,
-                      N_("use a standard location for the socket")},
-  { oNoUseStandardSocket, "no-use-standard-socket", 0, "@"},
+  { oUseStandardSocket, "use-standard-socket", 0, "@"},      /* dummy */
+  { oNoUseStandardSocket, "no-use-standard-socket", 0, "@"}, /* dummy */
   { oPinentryProgram, "pinentry-program", 2 ,
                                N_("|PGM|use PGM as the PIN-Entry program") },
   { oPinentryTouchFile, "pinentry-touch-file", 2 , "@" },
   { oScdaemonProgram, "scdaemon-program", 2 ,
                                N_("|PGM|use PGM as the SCdaemon program") },
   { oDisableScdaemon, "disable-scdaemon", 0, N_("do not use the SCdaemon") },
+  { oDisableCheckOwnSocket, "disable-check-own-socket", 0, "@" },
   { oFakedSystemTime, "faked-system-time", 2, "@" }, /* (epoch time) */
 
   { oBatch,      "batch",       0, "@" },
@@ -191,6 +197,8 @@ static ARGPARSE_OPTS opts[] = {
   { oAllowMarkTrusted, "allow-mark-trusted", 0, "@"},
   { oAllowPresetPassphrase, "allow-preset-passphrase", 0,
                              N_("allow presetting passphrase")},
+  { oAllowLoopbackPinentry, "allow-loopback-pinentry", 0,
+                             N_("allow presetting passphrase")},
   { oSSHSupport, "enable-ssh-support", 0, N_("enable ssh support") },
   { oPuttySupport, "enable-putty-support", 0,
 #ifdef HAVE_W32_SYSTEM
@@ -199,10 +207,7 @@ static ARGPARSE_OPTS opts[] = {
       "@"
 #endif
   },
-  { oNoAllowExternalCache, "no-allow-external-cache", 0,
-            N_("disallow the use of an external password cache") },
-  { oWriteEnvFile, "write-env-file", 2|8,
-            N_("|FILE|write environment settings also to FILE")},
+  { oWriteEnvFile, "write-env-file", 2|8, "@" }, /* dummy */
   {0}
 };
 
@@ -217,11 +222,18 @@ static ARGPARSE_OPTS opts[] = {
 
 /* The timer tick used for housekeeping stuff.  For Windows we use a
    longer period as the SetWaitableTimer seems to signal earlier than
-   the 2 seconds.  */
-#ifdef HAVE_W32_SYSTEM
-#define TIMERTICK_INTERVAL    (4)
+   the 2 seconds.  CHECK_OWN_SOCKET_INTERVAL defines how often we
+   check our own socket in standard socket mode.  If that value is 0
+   we don't check at all.   All values are in seconds. */
+#if defined(HAVE_W32CE_SYSTEM)
+# define TIMERTICK_INTERVAL         (60)
+# define CHECK_OWN_SOCKET_INTERVAL   (0)  /* Never */
+#elif defined(HAVE_W32_SYSTEM)
+# define TIMERTICK_INTERVAL          (4)
+# define CHECK_OWN_SOCKET_INTERVAL  (60)
 #else
-#define TIMERTICK_INTERVAL    (2)    /* Seconds.  */
+# define TIMERTICK_INTERVAL          (2)
+# define CHECK_OWN_SOCKET_INTERVAL  (60)
 #endif
 
 
@@ -252,6 +264,9 @@ static int shutdown_pending;
 /* Counter for the currently running own socket checks.  */
 static int check_own_socket_running;
 
+/* Flags to indicate that check_own_socket shall not be called.  */
+static int disable_check_own_socket;
+
 /* It is possible that we are currently running under setuid permissions */
 static int maybe_setuid = 1;
 
@@ -290,12 +305,15 @@ static char *current_logfile;
    watched. */
 static pid_t parent_pid = (pid_t)(-1);
 
+/* Number of active connections.  */
+static int active_connections;
+
 \f
 /*
    Local prototypes.
  */
 
-static char *create_socket_name (char *standard_name, char *template);
+static char *create_socket_name (char *standard_name);
 static gnupg_fd_t create_server_socket (char *name, int is_ssh,
                                         assuan_sock_nonce_t *nonce);
 static void create_directories (void);
@@ -306,34 +324,19 @@ static void agent_deinit_default_ctrl (ctrl_t ctrl);
 static void handle_connections (gnupg_fd_t listen_fd,
                                 gnupg_fd_t listen_fd_ssh);
 static void check_own_socket (void);
-static int check_for_running_agent (int silent, int mode);
+static int check_for_running_agent (int silent);
 
 /* Pth wrapper function definitions. */
-ASSUAN_SYSTEM_PTH_IMPL;
-
-#if GCRYPT_VERSION_NUMBER < 0x010600
-GCRY_THREAD_OPTION_PTH_IMPL;
-#if GCRY_THREAD_OPTION_VERSION < 1
-static int fixed_gcry_pth_init (void)
-{
-  return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0;
-}
-#endif
-#endif /*GCRYPT_VERSION_NUMBER < 0x10600*/
-
-#ifndef PTH_HAVE_PTH_THREAD_ID
-static unsigned long pth_thread_id (void)
-{
-  return (unsigned long)pth_self ();
-}
-#endif
-
+ASSUAN_SYSTEM_NPTH_IMPL;
 
 \f
 /*
    Functions.
  */
 
+/* Allocate a string describing a library version by calling a GETFNC.
+   This function is expected to be called only once.  GETFNC is
+   expected to have a semantic like gcry_check_version ().  */
 static char *
 make_libversion (const char *libname, const char *(*getfnc)(const char*))
 {
@@ -351,7 +354,9 @@ make_libversion (const char *libname, const char *(*getfnc)(const char*))
   return result;
 }
 
-
+/* Return strings describing this program.  The case values are
+   described in common/argparse.c:strusage.  The values here override
+   the default values given by strusage.  */
 static const char *
 my_strusage (int level)
 {
@@ -360,7 +365,7 @@ my_strusage (int level)
 
   switch (level)
     {
-    case 11: p = "gpg-agent (GnuPG)";
+    case 11: p = "@GPG_AGENT@ (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -376,10 +381,10 @@ my_strusage (int level)
       break;
 
     case 1:
-    case 40: p =  _("Usage: gpg-agent [options] (-h for help)");
+    case 40: p =  _("Usage: @GPG_AGENT@ [options] (-h for help)");
       break;
-    case 41: p =  _("Syntax: gpg-agent [options] [command [args]]\n"
-                    "Secret key management for GnuPG\n");
+    case 41: p =  _("Syntax: @GPG_AGENT@ [options] [command [args]]\n"
+                    "Secret key management for @GNUPG@\n");
     break;
 
     default: p = NULL;
@@ -424,7 +429,7 @@ set_debug (void)
     }
   else
     {
-      log_error (_("invalid debug-level `%s' given\n"), debug_level);
+      log_error (_("invalid debug-level '%s' given\n"), debug_level);
       opt.debug = 0; /* Reset debugging, so that prior debug
                         statements won't have an undesired effect. */
     }
@@ -461,7 +466,7 @@ remove_socket (char *name)
     {
       char *p;
 
-      remove (name);
+      gnupg_remove (name);
       p = strrchr (name, '/');
       if (p)
        {
@@ -473,9 +478,18 @@ remove_socket (char *name)
     }
 }
 
+
+/* Cleanup code for this program.  This is either called has an atexit
+   handler or directly.  */
 static void
 cleanup (void)
 {
+  static int done;
+
+  if (done)
+    return;
+  done = 1;
+  deinitialize_module_cache ();
   remove_socket (socket_name);
   remove_socket (socket_name_ssh);
 }
@@ -512,7 +526,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
       opt.ignore_cache_for_signing = 0;
       opt.allow_mark_trusted = 1;
       opt.disable_scdaemon = 0;
-      opt.allow_external_cache = 1;
+      disable_check_own_socket = 0;
       return 1;
     }
 
@@ -532,8 +546,6 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
           || strcmp (current_logfile, pargs->r.ret_str))
         {
           log_set_file (pargs->r.ret_str);
-         if (DBG_ASSUAN)
-           assuan_set_assuan_log_stream (log_get_stream ());
           xfree (current_logfile);
           current_logfile = xtrystrdup (pargs->r.ret_str);
         }
@@ -545,6 +557,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     case oPinentryTouchFile: opt.pinentry_touch_file = pargs->r.ret_str; break;
     case oScdaemonProgram: opt.scdaemon_program = pargs->r.ret_str; break;
     case oDisableScdaemon: opt.disable_scdaemon = 1; break;
+    case oDisableCheckOwnSocket: disable_check_own_socket = 1; break;
 
     case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break;
     case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break;
@@ -575,8 +588,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
 
     case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break;
 
-    case oNoAllowExternalCache: opt.allow_external_cache = 0;
-      break;
+    case oAllowLoopbackPinentry: opt.allow_loopback_pinentry = 1; break;
 
     default:
       return 0; /* not handled */
@@ -599,8 +611,6 @@ main (int argc, char **argv )
   unsigned configlineno;
   int parse_debug = 0;
   int default_config =1;
-  int greeting = 0;
-  int nogreeting = 0;
   int pipe_server = 0;
   int is_daemon = 0;
   int nodetach = 0;
@@ -609,7 +619,6 @@ main (int argc, char **argv )
   int debug_wait = 0;
   int gpgconf_list = 0;
   gpg_error_t err;
-  const char *env_file_name = NULL;
   struct assuan_malloc_hooks malloc_hooks;
 
   /* Before we do anything else we save the list of currently open
@@ -627,27 +636,13 @@ main (int argc, char **argv )
   /* Please note that we may running SUID(ROOT), so be very CAREFUL
      when adding any stuff between here and the call to INIT_SECMEM()
      somewhere after the option parsing */
-  log_set_prefix ("gpg-agent", JNLIB_LOG_WITH_PREFIX|JNLIB_LOG_WITH_PID);
+  log_set_prefix (GPG_AGENT_NAME, JNLIB_LOG_WITH_PREFIX|JNLIB_LOG_WITH_PID);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
-  init_common_subsystems ();
-
-
-#if GCRYPT_VERSION_NUMBER < 0x010600
-  /* Libgcrypt < 1.6 requires us to register the threading model first.
-     Note that this will also do the pth_init. */
-#if GCRY_THREAD_OPTION_VERSION < 1
-  gcry_threads_pth.init = fixed_gcry_pth_init;
-#endif
-  err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
-  if (err)
-    {
-      log_fatal ("can't register GNU Pth with Libgcrypt: %s\n",
-                 gpg_strerror (err));
-    }
-#endif /*GCRYPT_VERSION_NUMBER < 0x010600*/
+  init_common_subsystems (&argc, &argv);
 
+  npth_init ();
 
   /* Check that the libraries are suitable.  Do it here because
      the option parsing may need services of the library. */
@@ -661,10 +656,10 @@ main (int argc, char **argv )
   malloc_hooks.realloc = gcry_realloc;
   malloc_hooks.free = gcry_free;
   assuan_set_malloc_hooks (&malloc_hooks);
-  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
-  assuan_set_system_hooks (ASSUAN_SYSTEM_PTH);
+  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   assuan_sock_init ();
+  setup_libassuan_logging (&opt.debug);
 
   setup_libgcrypt_logging ();
   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
@@ -673,10 +668,6 @@ main (int argc, char **argv )
 
   /* Set default options.  */
   parse_rereadable_options (NULL, 0); /* Reset them to default values. */
-#ifdef USE_STANDARD_SOCKET
-  opt.use_standard_socket = 1;  /* Under Windows we always use a standard
-                                   socket.  */
-#endif
 
   shell = getenv ("SHELL");
   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
@@ -703,7 +694,7 @@ main (int argc, char **argv )
       }
     if (!err)
       {
-        s = ttyname (0);
+        s = gnupg_ttyname (0);
         if (s)
           err = session_env_setenv (opt.startup_env, "GPG_TTY", s);
       }
@@ -740,6 +731,11 @@ main (int argc, char **argv )
           default_config = 0; /* --no-options */
        else if (pargs.r_opt == oHomedir)
           opt.homedir = pargs.r.ret_str;
+       else if (pargs.r_opt == oDebugQuickRandom)
+          {
+            gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+          }
+
     }
 
   /* Initialize the secure memory. */
@@ -751,7 +747,8 @@ main (int argc, char **argv )
   */
 
   if (default_config)
-    configname = make_filename (opt.homedir, "gpg-agent.conf", NULL );
+    configname = make_filename (opt.homedir, GPG_AGENT_NAME EXTSEP_S "conf",
+                                NULL );
 
   argc = orig_argc;
   argv = orig_argv;
@@ -768,7 +765,7 @@ main (int argc, char **argv )
           if (default_config)
             {
               if( parse_debug )
-                log_info (_("NOTE: no default option file `%s'\n"),
+                log_info (_("Note: no default option file '%s'\n"),
                           configname );
               /* Save the default conf file name so that
                  reread_configuration is able to test whether the
@@ -779,7 +776,7 @@ main (int argc, char **argv )
            }
           else
             {
-              log_error (_("option file `%s': %s\n"),
+              log_error (_("option file '%s': %s\n"),
                          configname, strerror(errno) );
               exit(2);
            }
@@ -787,7 +784,7 @@ main (int argc, char **argv )
           configname = NULL;
        }
       if (parse_debug && configname )
-        log_info (_("reading options from `%s'\n"), configname );
+        log_info (_("reading options from '%s'\n"), configname );
       default_config = 0;
     }
 
@@ -813,7 +810,7 @@ main (int argc, char **argv )
                goto next_pass;
            }
           break;
-        case oNoGreeting: nogreeting = 1; break;
+        case oNoGreeting: /* Dummy option.  */ break;
         case oNoVerbose: opt.verbose = 0; break;
         case oNoOptions: break; /* no-options */
         case oHomedir: opt.homedir = pargs.r.ret_str; break;
@@ -829,11 +826,12 @@ main (int argc, char **argv )
         case oTTYtype: default_ttytype = xstrdup (pargs.r.ret_str); break;
         case oLCctype: default_lc_ctype = xstrdup (pargs.r.ret_str); break;
         case oLCmessages: default_lc_messages = xstrdup (pargs.r.ret_str);
+          break;
         case oXauthority: default_xauthority = xstrdup (pargs.r.ret_str);
           break;
 
-        case oUseStandardSocket:   opt.use_standard_socket = 1; break;
-        case oNoUseStandardSocket: opt.use_standard_socket = 0; break;
+        case oUseStandardSocket:   /* dummy */ break;
+        case oNoUseStandardSocket: /* dummy */ break;
 
         case oFakedSystemTime:
           {
@@ -855,13 +853,12 @@ main (int argc, char **argv )
 #        endif
           break;
 
-        case oWriteEnvFile:
-          if (pargs.r_type)
-            env_file_name = pargs.r.ret_str;
-          else
-            env_file_name = make_filename ("~/.gpg-agent-info", NULL);
+        case oDebugQuickRandom:
+          /* Only used by the first stage command line parser.  */
           break;
 
+        case oWriteEnvFile: /* dummy */ break;
+
         default : pargs.err = configfp? 1:2; break;
        }
     }
@@ -883,21 +880,43 @@ main (int argc, char **argv )
   configname = NULL;
   if (log_get_errorcount(0))
     exit(2);
-  if (nogreeting )
-    greeting = 0;
 
-  if (greeting)
+  /* Turn the homedir into an absolute one. */
+  opt.homedir = make_absfilename (opt.homedir, NULL);
+
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
     {
-      fprintf (stderr, "%s %s; %s\n",
-                 strusage(11), strusage(13), strusage(14) );
-      fprintf (stderr, "%s\n", strusage(15) );
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
     }
-#ifdef IS_DEVELOPMENT_VERSION
-  /* We don't want to print it here because gpg-agent is useful of its
-     own and quite matured.  */
-  /*log_info ("NOTE: this is a development version!\n");*/
+
+#ifdef ENABLE_NLS
+  /* gpg-agent usually does not output any messages because it runs in
+     the background.  For log files it is acceptable to have messages
+     always encoded in utf-8.  We switch here to utf-8, so that
+     commands like --help still give native messages.  It is far
+     easier to switch only once instead of for every message and it
+     actually helps when more then one thread is active (avoids an
+     extra copy step). */
+    bind_textdomain_codeset (PACKAGE_GT, "UTF-8");
 #endif
 
+  if (!pipe_server && !is_daemon && !gpgconf_list)
+    {
+     /* We have been called without any options and thus we merely
+        check whether an agent is already running.  We do this right
+        here so that we don't clobber a logfile with this check but
+        print the status directly to stderr. */
+      opt.debug = 0;
+      set_debug ();
+      check_for_running_agent (0);
+      agent_exit (0);
+    }
+
   set_debug ();
 
   if (atexit (cleanup))
@@ -907,6 +926,7 @@ main (int argc, char **argv )
       exit (1);
     }
 
+  initialize_module_cache ();
   initialize_module_call_pinentry ();
   initialize_module_call_scd ();
   initialize_module_trustlist ();
@@ -923,24 +943,30 @@ main (int argc, char **argv )
     }
 
   if (gpgconf_list == 3)
-    agent_exit (!opt.use_standard_socket);
-  if (gpgconf_list == 2)
+    {
+      /* We now use the standard socket always - return true for
+         backward compatibility.  */
+      agent_exit (0);
+    }
+  else if (gpgconf_list == 2)
     agent_exit (0);
-  if (gpgconf_list)
+  else if (gpgconf_list)
     {
       char *filename;
       char *filename_esc;
 
       /* List options and default values in the GPG Conf format.  */
-      filename = make_filename (opt.homedir, "gpg-agent.conf", NULL );
+      filename = make_filename (opt.homedir, GPG_AGENT_NAME EXTSEP_S "conf",
+                                NULL );
       filename_esc = percent_escape (filename, NULL);
 
-      printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n",
-              GC_OPT_FLAG_DEFAULT, filename_esc);
+      es_printf ("%s-%s.conf:%lu:\"%s\n",
+                 GPGCONF_NAME, GPG_AGENT_NAME,
+                 GC_OPT_FLAG_DEFAULT, filename_esc);
       xfree (filename);
       xfree (filename_esc);
 
-      printf ("verbose:%lu:\n"
+      es_printf ("verbose:%lu:\n"
               "quiet:%lu:\n"
               "debug-level:%lu:\"none:\n"
               "log-file:%lu:\n",
@@ -948,68 +974,45 @@ main (int argc, char **argv )
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME,
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME,
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME );
-      printf ("default-cache-ttl:%lu:%d:\n",
+      es_printf ("default-cache-ttl:%lu:%d:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL );
-      printf ("default-cache-ttl-ssh:%lu:%d:\n",
+      es_printf ("default-cache-ttl-ssh:%lu:%d:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL_SSH );
-      printf ("max-cache-ttl:%lu:%d:\n",
+      es_printf ("max-cache-ttl:%lu:%d:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL );
-      printf ("max-cache-ttl-ssh:%lu:%d:\n",
+      es_printf ("max-cache-ttl-ssh:%lu:%d:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL_SSH );
-      printf ("enforce-passphrase-constraints:%lu:\n",
+      es_printf ("enforce-passphrase-constraints:%lu:\n",
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
-      printf ("min-passphrase-len:%lu:%d:\n",
+      es_printf ("min-passphrase-len:%lu:%d:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MIN_PASSPHRASE_LEN );
-      printf ("min-passphrase-nonalpha:%lu:%d:\n",
+      es_printf ("min-passphrase-nonalpha:%lu:%d:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME,
               MIN_PASSPHRASE_NONALPHA);
-      printf ("check-passphrase-pattern:%lu:\n",
+      es_printf ("check-passphrase-pattern:%lu:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME);
-      printf ("max-passphrase-days:%lu:%d:\n",
+      es_printf ("max-passphrase-days:%lu:%d:\n",
               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME,
               MAX_PASSPHRASE_DAYS);
-      printf ("enable-passphrase-history:%lu:\n",
+      es_printf ("enable-passphrase-history:%lu:\n",
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
-      printf ("no-grab:%lu:\n",
+      es_printf ("no-grab:%lu:\n",
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
-      printf ("ignore-cache-for-signing:%lu:\n",
+      es_printf ("ignore-cache-for-signing:%lu:\n",
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
-      printf ("no-allow-mark-trusted:%lu:\n",
+      es_printf ("no-allow-mark-trusted:%lu:\n",
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
-      printf ("no-allow-external-cache:%lu:\n",
-              GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
-      printf ("disable-scdaemon:%lu:\n",
+      es_printf ("disable-scdaemon:%lu:\n",
               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
 #ifdef HAVE_W32_SYSTEM
-      printf ("enable-putty-support:%lu:\n", GC_OPT_FLAG_NONE);
+      es_printf ("enable-putty-support:%lu:\n", GC_OPT_FLAG_NONE);
 #else
-      printf ("enable-ssh-support:%lu:\n", GC_OPT_FLAG_NONE);
+      es_printf ("enable-ssh-support:%lu:\n", GC_OPT_FLAG_NONE);
 #endif
 
       agent_exit (0);
     }
 
-  /* If this has been called without any options, we merely check
-     whether an agent is already running.  We do this here so that we
-     don't clobber a logfile but print it directly to stderr. */
-  if (!pipe_server && !is_daemon)
-    {
-      log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
-      check_for_running_agent (0, 0);
-      agent_exit (0);
-    }
-
-#ifdef ENABLE_NLS
-  /* gpg-agent usually does not output any messages because it runs in
-     the background.  For log files it is acceptable to have messages
-     always encoded in utf-8.  We switch here to utf-8, so that
-     commands like --help still give native messages.  It is far
-     easier to switch only once instead of for every message and it
-     actually helps when more then one thread is active (avoids an
-     extra copy step). */
-    bind_textdomain_codeset (PACKAGE_GT, "UTF-8");
-#endif
-
   /* Now start with logging to a file if this is desired. */
   if (logfile)
     {
@@ -1019,12 +1022,10 @@ main (int argc, char **argv )
                              |JNLIB_LOG_WITH_PID));
       current_logfile = xstrdup (logfile);
     }
-  if (DBG_ASSUAN)
-    assuan_set_assuan_log_stream (log_get_stream ());
 
   /* Make sure that we have a default ttyname. */
-  if (!default_ttyname && ttyname (1))
-    default_ttyname = xstrdup (ttyname (1));
+  if (!default_ttyname && gnupg_ttyname (1))
+    default_ttyname = xstrdup (gnupg_ttyname (1));
   if (!default_ttytype && getenv ("TERM"))
     default_ttytype = xstrdup (getenv ("TERM"));
 
@@ -1070,20 +1071,18 @@ main (int argc, char **argv )
          exec the program given as arguments). */
 #ifndef HAVE_W32_SYSTEM
       if (!opt.keep_display && !argc)
-        unsetenv ("DISPLAY");
+        gnupg_unsetenv ("DISPLAY");
 #endif
 
 
       /* Create the sockets.  */
-      socket_name = create_socket_name
-        ("S.gpg-agent", "/tmp/gpg-XXXXXX/S.gpg-agent");
-      if (opt.ssh_support)
-       socket_name_ssh = create_socket_name
-          ("S.gpg-agent.ssh", "/tmp/gpg-XXXXXX/S.gpg-agent.ssh");
-
+      socket_name = create_socket_name (GPG_AGENT_SOCK_NAME);
       fd = create_server_socket (socket_name, 0, &socket_nonce);
       if (opt.ssh_support)
-       fd_ssh = create_server_socket (socket_name_ssh, 1, &socket_nonce_ssh);
+        {
+          socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME);
+          fd_ssh = create_server_socket (socket_name_ssh, 1, &socket_nonce_ssh);
+        }
       else
        fd_ssh = GNUPG_INVALID_FD;
 
@@ -1095,8 +1094,9 @@ main (int argc, char **argv )
 
       fflush (NULL);
 #ifdef HAVE_W32_SYSTEM
+      (void)csh_style;
+      (void)nodetach;
       pid = getpid ();
-      printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid);
 #else /*!HAVE_W32_SYSTEM*/
       pid = fork ();
       if (pid == (pid_t)-1)
@@ -1106,25 +1106,14 @@ main (int argc, char **argv )
         }
       else if (pid)
         { /* We are the parent */
-          char *infostr, *infostr_ssh_sock, *infostr_ssh_pid;
+          char *infostr_ssh_sock, *infostr_ssh_valid;
 
           /* Close the socket FD. */
           close (fd);
 
-          /* Note that we used a standard fork so that Pth runs in
-             both the parent and the child.  The pth_fork would
-             terminate Pth in the child but that is not the way we
-             want it.  Thus we use a plain fork and terminate Pth here
-             in the parent.  The pth_kill may or may not work reliable
-             but it should not harm to call it.  Because Pth fiddles
-             with the signal mask the signal mask might not be correct
-             right now and thus we restore it.  That is not strictly
-             necessary but some programs falsely assume a cleared
-             signal mask.  es_pth_kill is a wrapper around pth_kill to
-             take care not to use any Pth functions in the estream
-             code after Pth has been killed.  */
-          if ( !es_pth_kill () )
-            log_error ("pth_kill failed in forked process\n");
+          /* The signal mask might not be correct right now and thus
+             we restore it.  That is not strictly necessary but some
+             programs falsely assume a cleared signal mask.  */
 
 #ifdef HAVE_SIGPROCMASK
           if (startup_signal_mask_valid)
@@ -1137,14 +1126,7 @@ main (int argc, char **argv )
             log_info ("no saved signal mask\n");
 #endif /*HAVE_SIGPROCMASK*/
 
-          /* Create the info string: <name>:<pid>:<protocol_version> */
-          if (asprintf (&infostr, "GPG_AGENT_INFO=%s:%lu:1",
-                        socket_name, (ulong)pid ) < 0)
-            {
-              log_error ("out of core\n");
-              kill (pid, SIGTERM);
-              exit (1);
-            }
+          /* Create the SSH info string if enabled. */
          if (opt.ssh_support)
            {
              if (asprintf (&infostr_ssh_sock, "SSH_AUTH_SOCK=%s",
@@ -1154,8 +1136,8 @@ main (int argc, char **argv )
                  kill (pid, SIGTERM);
                  exit (1);
                }
-             if (asprintf (&infostr_ssh_pid, "SSH_AGENT_PID=%u",
-                           pid) < 0)
+             if (asprintf (&infostr_ssh_valid, "gnupg_SSH_AUTH_SOCK_by=%lu",
+                           (unsigned long)getpid()) < 0)
                {
                  log_error ("out of core\n");
                  kill (pid, SIGTERM);
@@ -1168,47 +1150,10 @@ main (int argc, char **argv )
          if (opt.ssh_support)
            *socket_name_ssh = 0;
 
-          if (env_file_name)
-            {
-              FILE *fp;
-
-              fp = fopen (env_file_name, "w");
-              if (!fp)
-                log_error (_("error creating `%s': %s\n"),
-                             env_file_name, strerror (errno));
-              else
-                {
-                  fputs (infostr, fp);
-                  putc ('\n', fp);
-                  if (opt.ssh_support)
-                    {
-                      fputs (infostr_ssh_sock, fp);
-                      putc ('\n', fp);
-                      fputs (infostr_ssh_pid, fp);
-                      putc ('\n', fp);
-                    }
-                  fclose (fp);
-                }
-            }
-
-
           if (argc)
             { /* Run the program given on the commandline.  */
-              if (putenv (infostr))
-                {
-                  log_error ("failed to set environment: %s\n",
-                             strerror (errno) );
-                  kill (pid, SIGTERM );
-                  exit (1);
-                }
-              if (opt.ssh_support && putenv (infostr_ssh_sock))
-                {
-                  log_error ("failed to set environment: %s\n",
-                             strerror (errno) );
-                  kill (pid, SIGTERM );
-                  exit (1);
-                }
-              if (opt.ssh_support && putenv (infostr_ssh_pid))
+              if (opt.ssh_support && (putenv (infostr_ssh_sock)
+                                      || putenv (infostr_ssh_valid)))
                 {
                   log_error ("failed to set environment: %s\n",
                              strerror (errno) );
@@ -1234,30 +1179,24 @@ main (int argc, char **argv )
                  shell's eval to set it */
               if (csh_style)
                 {
-                  *strchr (infostr, '=') = ' ';
-                  printf ("setenv %s;\n", infostr);
                  if (opt.ssh_support)
                    {
                      *strchr (infostr_ssh_sock, '=') = ' ';
-                     printf ("setenv %s;\n", infostr_ssh_sock);
-                     *strchr (infostr_ssh_pid, '=') = ' ';
-                     printf ("setenv %s;\n", infostr_ssh_pid);
+                     es_printf ("setenv %s;\n", infostr_ssh_sock);
                    }
                 }
               else
                 {
-                  printf ( "%s; export GPG_AGENT_INFO;\n", infostr);
                  if (opt.ssh_support)
                    {
-                     printf ("%s; export SSH_AUTH_SOCK;\n", infostr_ssh_sock);
-                     printf ("%s; export SSH_AGENT_PID;\n", infostr_ssh_pid);
+                     es_printf ("%s; export SSH_AUTH_SOCK;\n",
+                                 infostr_ssh_sock);
                    }
                 }
-              xfree (infostr);
              if (opt.ssh_support)
                {
                  xfree (infostr_ssh_sock);
-                 xfree (infostr_ssh_pid);
+                 xfree (infostr_ssh_valid);
                }
               exit (0);
             }
@@ -1282,7 +1221,7 @@ main (int argc, char **argv )
                   if ( ! close (i)
                        && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1)
                     {
-                      log_error ("failed to open `%s': %s\n",
+                      log_error ("failed to open '%s': %s\n",
                                  "/dev/null", strerror (errno));
                       cleanup ();
                       exit (1);
@@ -1326,10 +1265,18 @@ main (int argc, char **argv )
 }
 
 
+/* Exit entry point.  This function should be called instead of a
+   plain exit.  */
 void
 agent_exit (int rc)
 {
   /*FIXME: update_random_seed_file();*/
+
+  /* We run our cleanup handler because that may close cipher contexts
+     stored in secure memory and thus this needs to be done before we
+     explicitly terminate secure memory.  */
+  cleanup ();
+
 #if 1
   /* at this time a bit annoying */
   if (opt.debug & DBG_MEMSTAT_VALUE)
@@ -1346,6 +1293,11 @@ agent_exit (int rc)
 }
 
 
+/* Each thread has its own local variables conveyed by a control
+   structure usually identified by an argument named CTRL.  This
+   function is called immediately after allocating the control
+   structure.  Its purpose is to setup the default values for that
+   structure.  */
 static void
 agent_init_default_ctrl (ctrl_t ctrl)
 {
@@ -1368,9 +1320,12 @@ agent_init_default_ctrl (ctrl_t ctrl)
     xfree (ctrl->lc_messages);
   ctrl->lc_messages = default_lc_messages? xtrystrdup (default_lc_messages)
                                     /**/ : NULL;
+  ctrl->cache_ttl_opt_preset = CACHE_TTL_OPT_PRESET;
 }
 
 
+/* Release all resources allocated by default in the control
+   structure.  This is the counterpart to agent_init_default_ctrl.  */
 static void
 agent_deinit_default_ctrl (ctrl_t ctrl)
 {
@@ -1406,7 +1361,7 @@ reread_configuration (void)
   fp = fopen (config_filename, "r");
   if (!fp)
     {
-      log_info (_("option file `%s': %s\n"),
+      log_info (_("option file '%s': %s\n"),
                 config_filename, strerror(errno) );
       return;
     }
@@ -1453,18 +1408,18 @@ get_agent_ssh_socket_name (void)
 /* Under W32, this function returns the handle of the scdaemon
    notification event.  Calling it the first time creates that
    event.  */
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
 void *
 get_agent_scd_notify_event (void)
 {
-  static HANDLE the_event;
+  static HANDLE the_event = INVALID_HANDLE_VALUE;
 
-  if (!the_event)
+  if (the_event == INVALID_HANDLE_VALUE)
     {
       HANDLE h, h2;
       SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
 
-      /* We need to use manual reset evet object due to the way our
+      /* We need to use a manual reset event object due to the way our
          w32-pth wait function works: If we would use an automatic
          reset event we are not able to figure out which handle has
          been signaled because at the time we single out the signaled
@@ -1488,47 +1443,27 @@ get_agent_scd_notify_event (void)
         }
     }
 
-  log_debug  ("returning notify handle %p\n", the_event);
   return the_event;
 }
-#endif /*HAVE_W32_SYSTEM*/
+#endif /*HAVE_W32_SYSTEM && !HAVE_W32CE_SYSTEM*/
 
 
 
-/* Create a name for the socket.  With USE_STANDARD_SOCKET given as
-   true using STANDARD_NAME in the home directory or if given as
-   false from the mkdir type name TEMPLATE.  In the latter case a
-   unique name in a unique new directory will be created.  In both
-   cases check for valid characters as well as against a maximum
-   allowed length for a unix domain socket is done.  The function
-   terminates the process in case of an error.  Returns: Pointer to an
-   allocated string with the absolute name of the socket used.  */
+/* Create a name for the socket in the home directory as using
+   STANDARD_NAME.  We also check for valid characters as well as
+   against a maximum allowed length for a unix domain socket is done.
+   The function terminates the process in case of an error.  Returns:
+   Pointer to an allocated string with the absolute name of the socket
+   used.  */
 static char *
-create_socket_name (char *standard_name, char *template)
+create_socket_name (char *standard_name)
 {
-  char *name, *p;
-
-  if (opt.use_standard_socket)
-    name = make_filename (opt.homedir, standard_name, NULL);
-  else
-    {
-      name = xstrdup (template);
-      p = strrchr (name, '/');
-      if (!p)
-       BUG ();
-      *p = 0;
-      if (!mkdtemp (name))
-       {
-         log_error (_("can't create directory `%s': %s\n"),
-                    name, strerror (errno));
-         agent_exit (2);
-       }
-      *p = '/';
-    }
+  char *name;
 
+  name = make_filename (opt.homedir, standard_name, NULL);
   if (strchr (name, PATHSEP_C))
     {
-      log_error (("`%s' are not allowed in the socket name\n"), PATHSEP_S);
+      log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
       agent_exit (2);
     }
   if (strlen (name) + 1 >= DIMof (struct sockaddr_un, sun_path) )
@@ -1565,33 +1500,41 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
   serv_addr->sun_family = AF_UNIX;
   if (strlen (name) + 1 >= sizeof (serv_addr->sun_path))
     {
-      log_error (_("socket name `%s' is too long\n"), name);
+      log_error (_("socket name '%s' is too long\n"), name);
       agent_exit (2);
     }
   strcpy (serv_addr->sun_path, name);
   len = SUN_LEN (serv_addr);
   rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);
-  if (opt.use_standard_socket && rc == -1 && errno == EADDRINUSE)
+
+  /* Our error code mapping on W32CE returns EEXIST thus we also test
+     for this. */
+  if (rc == -1
+      && (errno == EADDRINUSE
+#ifdef HAVE_W32_SYSTEM
+          || errno == EEXIST
+#endif
+          ))
     {
-      /* Check whether a gpg-agent is already running on the standard
-         socket.  We do this test only if this is not the ssh socket.
+      /* Check whether a gpg-agent is already running.
+         We do this test only if this is not the ssh socket.
          For ssh we assume that a test for gpg-agent has already been
          done and reuse the requested ssh socket.  Testing the
          ssh-socket is not possible because at this point, though we
          know the new Assuan socket, the Assuan server and thus the
          ssh-agent server is not yet operational.  This would lead to
          a hang.  */
-      if (!is_ssh && !check_for_running_agent (1, 1))
+      if (!is_ssh && !check_for_running_agent (1))
         {
+          log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
+          log_set_file (NULL);
           log_error (_("a gpg-agent is already running - "
                        "not starting a new one\n"));
           *name = 0; /* Inhibit removal of the socket by cleanup(). */
-          if (opt.ssh_support)
-            *socket_name_ssh = 0; /* Likewise for the ssh socket.  */
           assuan_sock_close (fd);
           agent_exit (2);
         }
-      remove (name);
+      gnupg_remove (name);
       rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);
     }
   if (rc != -1
@@ -1601,13 +1544,12 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
     {
       /* We use gpg_strerror here because it allows us to get strings
          for some W32 socket error codes.  */
-      log_error (_("error binding socket to `%s': %s\n"),
+      log_error (_("error binding socket to '%s': %s\n"),
                 serv_addr->sun_path,
                  gpg_strerror (gpg_error_from_errno (errno)));
 
       assuan_sock_close (fd);
-      if (opt.use_standard_socket)
-        *name = 0; /* Inhibit removal of the socket by cleanup(). */
+      *name = 0; /* Inhibit removal of the socket by cleanup(). */
       agent_exit (2);
     }
 
@@ -1619,7 +1561,7 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
     }
 
   if (opt.verbose)
-    log_info (_("listening on socket `%s'\n"), serv_addr->sun_path);
+    log_info (_("listening on socket '%s'\n"), serv_addr->sun_path);
 
   return fd;
 }
@@ -1637,17 +1579,11 @@ create_private_keys_directory (const char *home)
   fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL);
   if (stat (fname, &statbuf) && errno == ENOENT)
     {
-#ifdef HAVE_W32_SYSTEM  /*FIXME: Setup proper permissions.  */
-      if (!CreateDirectory (fname, NULL))
-        log_error (_("can't create directory `%s': %s\n"),
-                   fname, w32_strerror (-1) );
-#else
-      if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR ))
-        log_error (_("can't create directory `%s': %s\n"),
+      if (gnupg_mkdir (fname, "-rwx"))
+        log_error (_("can't create directory '%s': %s\n"),
                    fname, strerror (errno) );
-#endif
       else if (!opt.quiet)
-        log_info (_("directory `%s' created\n"), fname);
+        log_info (_("directory '%s' created\n"), fname);
     }
   xfree (fname);
 }
@@ -1682,29 +1618,23 @@ create_directories (void)
 #endif
                )
             {
-#ifdef HAVE_W32_SYSTEM
-              if (!CreateDirectory (home, NULL))
-                log_error (_("can't create directory `%s': %s\n"),
-                           home, w32_strerror (-1) );
-#else
-              if (mkdir (home, S_IRUSR|S_IWUSR|S_IXUSR ))
-                log_error (_("can't create directory `%s': %s\n"),
+              if (gnupg_mkdir (home, "-rwx"))
+                log_error (_("can't create directory '%s': %s\n"),
                            home, strerror (errno) );
-#endif
               else
                 {
                   if (!opt.quiet)
-                    log_info (_("directory `%s' created\n"), home);
+                    log_info (_("directory '%s' created\n"), home);
                   create_private_keys_directory (home);
                 }
             }
         }
       else
-        log_error (_("stat() failed for `%s': %s\n"), home, strerror (errno));
+        log_error (_("stat() failed for '%s': %s\n"), home, strerror (errno));
     }
   else if ( !S_ISDIR(statbuf.st_mode))
     {
-      log_error (_("can't use `%s' as home directory\n"), home);
+      log_error (_("can't use '%s' as home directory\n"), home);
     }
   else /* exists and is a directory. */
     {
@@ -1736,23 +1666,22 @@ handle_tick (void)
       if (kill (parent_pid, 0))
         {
           shutdown_pending = 2;
-          if (!opt.quiet)
-            {
-              log_info ("parent process died - shutting down\n");
-              log_info ("%s %s stopped\n", strusage(11), strusage(13) );
-            }
+          log_info ("parent process died - shutting down\n");
+          log_info ("%s %s stopped\n", strusage(11), strusage(13) );
           cleanup ();
           agent_exit (0);
         }
     }
 #endif /*HAVE_W32_SYSTEM*/
 
-  /* Code to be run every minute.  */
-  if (last_minute + 60 <= time (NULL))
+  /* Code to be run from time to time.  */
+#if CHECK_OWN_SOCKET_INTERVAL > 0
+  if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL))
     {
       check_own_socket ();
       last_minute = time (NULL);
     }
+#endif
 
 }
 
@@ -1770,6 +1699,7 @@ agent_sighup_action (void)
 }
 
 
+/* A helper function to handle SIGUSR2.  */
 static void
 agent_sigusr2_action (void)
 {
@@ -1780,6 +1710,9 @@ agent_sigusr2_action (void)
 }
 
 
+#ifndef HAVE_W32_SYSTEM
+/* The signal handler for this program.  It is expected to be run in
+   its own trhead and not in the context of a signal handler.  */
 static void
 handle_signal (int signo)
 {
@@ -1792,7 +1725,9 @@ handle_signal (int signo)
 
     case SIGUSR1:
       log_info ("SIGUSR1 received - printing internal information:\n");
-      pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ());
+      /* Fixme: We need to see how to integrate pth dumping into our
+         logging system.  */
+      /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
       agent_query_dump_state ();
       agent_scd_dump_state ();
       break;
@@ -1805,8 +1740,8 @@ handle_signal (int signo)
       if (!shutdown_pending)
         log_info ("SIGTERM received - shutting down ...\n");
       else
-        log_info ("SIGTERM received - still %ld running threads\n",
-                  pth_ctrl( PTH_CTRL_GETTHREADS ));
+        log_info ("SIGTERM received - still %i open connections\n",
+                 active_connections);
       shutdown_pending++;
       if (shutdown_pending > 2)
         {
@@ -1828,7 +1763,7 @@ handle_signal (int signo)
       log_info ("signal %d received - no action defined\n", signo);
     }
 }
-
+#endif
 
 /* Check the nonce on a new connection.  This is a NOP unless we we
    are using our Unix domain socket emulation under Windows.  */
@@ -1868,9 +1803,6 @@ putty_message_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
 
   if (msg != WM_COPYDATA)
     {
-      /* pth_leave (); */
-      /* log_debug ("putty loop: received WM_%u\n", msg ); */
-      /* pth_enter (); */
       return DefWindowProc (hwnd, msg, wparam, lparam);
     }
 
@@ -1883,23 +1815,23 @@ putty_message_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
 
   if (DBG_ASSUAN)
     {
-      pth_leave ();
+      npth_protect ();
       log_debug ("ssh map file '%s'", mapfile);
-      pth_enter ();
+      npth_unprotect ();
     }
 
   maphd = OpenFileMapping (FILE_MAP_ALL_ACCESS, FALSE, mapfile);
   if (DBG_ASSUAN)
     {
-      pth_leave ();
+      npth_protect ();
       log_debug ("ssh map handle %p\n", maphd);
-      pth_enter ();
+      npth_unprotect ();
     }
 
   if (!maphd || maphd == INVALID_HANDLE_VALUE)
     return 0;
 
-  pth_leave ();
+  npth_protect ();
 
   mysid = w32_get_user_sid ();
   if (!mysid)
@@ -1977,7 +1909,7 @@ putty_message_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
   xfree (mysid);
   CloseHandle (maphd);
 
-  pth_enter ();
+  npth_unprotect ();
 
   return ret;
 }
@@ -1997,18 +1929,18 @@ putty_message_thread (void *arg)
   (void)arg;
 
   if (opt.verbose)
-    log_info ("putty message loop thread 0x%lx started\n", pth_thread_id ());
+    log_info ("putty message loop thread started\n");
 
-  /* The message loop runs as thread independet from out Pth system.
-     This also meand that we need to make sure that we switch back to
+  /* The message loop runs as thread independent from our nPth system.
+     This also means that we need to make sure that we switch back to
      our system before calling any no-windows function.  */
-  pth_enter ();
+  npth_unprotect ();
 
   /* First create a window to make sure that a message queue exists
      for this thread.  */
   if (!RegisterClass (&wndwclass))
     {
-      pth_leave ();
+      npth_protect ();
       log_error ("error registering Pageant window class");
       return NULL;
     }
@@ -2020,7 +1952,7 @@ putty_message_thread (void *arg)
                          NULL);         /* lpParm     */
   if (!hwnd)
     {
-      pth_leave ();
+      npth_protect ();
       log_error ("error creating Pageant window");
       return NULL;
     }
@@ -2031,11 +1963,11 @@ putty_message_thread (void *arg)
       DispatchMessage(&msg);
     }
 
-  /* Back to Pth.  */
-  pth_leave ();
+  /* Back to nPth.  */
+  npth_protect ();
 
   if (opt.verbose)
-    log_info ("putty message loop thread 0x%lx stopped\n", pth_thread_id ());
+    log_info ("putty message loop thread stopped\n");
   return NULL;
 }
 #endif /*HAVE_W32_SYSTEM*/
@@ -2048,17 +1980,21 @@ start_connection_thread (void *arg)
   ctrl_t ctrl = arg;
 
   if (check_nonce (ctrl, &socket_nonce))
-    return NULL;
+    {
+      log_error ("handler 0x%lx nonce check FAILED\n",
+                 (unsigned long) npth_self());
+      return NULL;
+    }
 
   agent_init_default_ctrl (ctrl);
   if (opt.verbose)
     log_info (_("handler 0x%lx for fd %d started\n"),
-              pth_thread_id (), FD2INT(ctrl->thread_startup.fd));
+              (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   start_command_handler (ctrl, GNUPG_INVALID_FD, ctrl->thread_startup.fd);
   if (opt.verbose)
     log_info (_("handler 0x%lx for fd %d terminated\n"),
-              pth_thread_id (), FD2INT(ctrl->thread_startup.fd));
+              (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   agent_deinit_default_ctrl (ctrl);
   xfree (ctrl);
@@ -2078,12 +2014,12 @@ start_connection_thread_ssh (void *arg)
   agent_init_default_ctrl (ctrl);
   if (opt.verbose)
     log_info (_("ssh handler 0x%lx for fd %d started\n"),
-              pth_thread_id (), FD2INT(ctrl->thread_startup.fd));
+              (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   start_command_handler_ssh (ctrl, ctrl->thread_startup.fd);
   if (opt.verbose)
     log_info (_("ssh handler 0x%lx for fd %d terminated\n"),
-              pth_thread_id (), FD2INT(ctrl->thread_startup.fd));
+              (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   agent_deinit_default_ctrl (ctrl);
   xfree (ctrl);
@@ -2096,59 +2032,46 @@ start_connection_thread_ssh (void *arg)
 static void
 handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
 {
-  pth_attr_t tattr;
-  pth_event_t ev, time_ev;
-  sigset_t sigs;
-  int signo;
+  npth_attr_t tattr;
   struct sockaddr_un paddr;
   socklen_t plen;
   fd_set fdset, read_fdset;
   int ret;
   gnupg_fd_t fd;
   int nfd;
+  int saved_errno;
+  struct timespec abstime;
+  struct timespec curtime;
+  struct timespec timeout;
+#ifdef HAVE_W32_SYSTEM
+  HANDLE events[2];
+  unsigned int events_set;
+#endif
 
-  tattr = pth_attr_new();
-  pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
-  pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
-
-#ifndef HAVE_W32_SYSTEM /* fixme */
-  /* Make sure that the signals we are going to handle are not blocked
-     and create an event object for them.  We also set the default
-     action to ignore because we use an Pth event to get notified
-     about signals.  This avoids that the default action is taken in
-     case soemthing goes wrong within Pth.  The problem might also be
-     a Pth bug.  */
-  sigemptyset (&sigs );
-  {
-    static const int mysigs[] = { SIGHUP, SIGUSR1, SIGUSR2, SIGINT, SIGTERM };
-    struct sigaction sa;
-    int i;
-
-    for (i=0; i < DIM (mysigs); i++)
-      {
-        sigemptyset (&sa.sa_mask);
-        sa.sa_handler = SIG_IGN;
-        sa.sa_flags = 0;
-        sigaction (mysigs[i], &sa, NULL);
-
-        sigaddset (&sigs, mysigs[i]);
-      }
-  }
+  ret = npth_attr_init(&tattr);
+  if (ret)
+    log_fatal ("error allocating thread attributes: %s\n",
+              strerror (ret));
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
 
-  pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
-  ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
+#ifndef HAVE_W32_SYSTEM
+  npth_sigev_init ();
+  npth_sigev_add (SIGHUP);
+  npth_sigev_add (SIGUSR1);
+  npth_sigev_add (SIGUSR2);
+  npth_sigev_add (SIGINT);
+  npth_sigev_add (SIGTERM);
+  npth_sigev_fini ();
 #else
-# ifdef PTH_EVENT_HANDLE
-  sigs = 0;
-  ev = pth_event (PTH_EVENT_HANDLE, get_agent_scd_notify_event ());
-  signo = 0;
-# else
+# ifdef HAVE_W32CE_SYSTEM
   /* Use a dummy event. */
   sigs = 0;
   ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
+# else
+  events[0] = get_agent_scd_notify_event ();
+  events[1] = INVALID_HANDLE_VALUE;
 # endif
 #endif
-  time_ev = NULL;
 
   /* On Windows we need to fire up a separate thread to listen for
      requests from Putty (an SSH client), so we can replace Putty's
@@ -2156,11 +2079,12 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
 #ifdef HAVE_W32_SYSTEM
   if (putty_support)
     {
-      pth_attr_set (tattr, PTH_ATTR_NAME, "putty message loop");
-      if (!pth_spawn (tattr, putty_message_thread, NULL))
+      npth_t thread;
+
+      ret = npth_create (&thread, &tattr, putty_message_thread, NULL);
+      if (ret)
         {
-          log_error ("error spawning putty message loop: %s\n",
-                     strerror (errno) );
+          log_error ("error spawning putty message loop: %s\n", strerror (ret));
         }
     }
 #endif /*HAVE_W32_SYSTEM*/
@@ -2179,15 +2103,15 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
         nfd = FD2INT (listen_fd_ssh);
     }
 
+  npth_clock_gettime (&abstime);
+  abstime.tv_sec += TIMERTICK_INTERVAL;
+
   for (;;)
     {
-      /* Make sure that our signals are not blocked.  */
-      pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
-
       /* Shutdown test.  */
       if (shutdown_pending)
         {
-          if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1)
+          if (active_connections == 0)
             break; /* ready */
 
           /* Do not accept new connections but keep on running the
@@ -2195,87 +2119,59 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
           FD_ZERO (&fdset);
        }
 
-      /* Create a timeout event if needed.  To help with power saving
-         we syncronize the ticks to the next full second.  */
-      if (!time_ev)
-        {
-          pth_time_t nexttick;
-
-          nexttick = pth_timeout (TIMERTICK_INTERVAL, 0);
-          if (nexttick.tv_usec > 10)  /* Use a 10 usec threshhold.  */
-            {
-              nexttick.tv_sec++;
-              nexttick.tv_usec = 0;
-            }
-          time_ev = pth_event (PTH_EVENT_TIME, nexttick);
-        }
-
       /* POSIX says that fd_set should be implemented as a structure,
          thus a simple assignment is fine to copy the entire set.  */
       read_fdset = fdset;
 
-      if (time_ev)
-        pth_event_concat (ev, time_ev, NULL);
-      ret = pth_select_ev (nfd+1, &read_fdset, NULL, NULL, NULL, ev);
-      if (time_ev)
-        pth_event_isolate (time_ev);
-
-      if (ret == -1)
+      npth_clock_gettime (&curtime);
+      if (!(npth_timercmp (&curtime, &abstime, <)))
        {
-          if (pth_event_occurred (ev)
-              || (time_ev && pth_event_occurred (time_ev)))
-            {
-              if (pth_event_occurred (ev))
-                {
-#if defined(HAVE_W32_SYSTEM) && defined(PTH_EVENT_HANDLE)
-                  agent_sigusr2_action ();
-#else
-                  handle_signal (signo);
-#endif
-                }
-              if (time_ev && pth_event_occurred (time_ev))
-                {
-                  pth_event_free (time_ev, PTH_FREE_ALL);
-                  time_ev = NULL;
-                  handle_tick ();
-                }
-              continue;
-            }
-          log_error (_("pth_select failed: %s - waiting 1s\n"),
-                     strerror (errno));
-          pth_sleep (1);
-          continue;
+         /* Timeout.  */
+         handle_tick ();
+         npth_clock_gettime (&abstime);
+         abstime.tv_sec += TIMERTICK_INTERVAL;
        }
+      npth_timersub (&abstime, &curtime, &timeout);
 
-      if (pth_event_occurred (ev))
-        {
-#if defined(HAVE_W32_SYSTEM) && defined(PTH_EVENT_HANDLE)
-          agent_sigusr2_action ();
-#else
-          handle_signal (signo);
-#endif
-        }
+#ifndef HAVE_W32_SYSTEM
+      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
+                          npth_sigev_sigmask ());
+      saved_errno = errno;
 
-      if (time_ev && pth_event_occurred (time_ev))
-        {
-          pth_event_free (time_ev, PTH_FREE_ALL);
-          time_ev = NULL;
-          handle_tick ();
-        }
+      {
+        int signo;
+        while (npth_sigev_get_pending (&signo))
+          handle_signal (signo);
+      }
+#else
+      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
+                          events, &events_set);
+      saved_errno = errno;
 
+      /* This is valid even if npth_eselect returns an error.  */
+      if (events_set & 1)
+       agent_sigusr2_action ();
+#endif
 
-      /* We now might create new threads and because we don't want any
-         signals (as we are handling them here) to be delivered to a
-         new thread.  Thus we need to block those signals. */
-      pth_sigmask (SIG_BLOCK, &sigs, NULL);
+      if (ret == -1 && saved_errno != EINTR)
+       {
+          log_error (_("npth_pselect failed: %s - waiting 1s\n"),
+                     strerror (saved_errno));
+          npth_sleep (1);
+          continue;
+       }
+      if (ret <= 0)
+       /* Interrupt or timeout.  Will be handled when calculating the
+          next timeout.  */
+       continue;
 
       if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset))
        {
           ctrl_t ctrl;
 
           plen = sizeof paddr;
-         fd = INT2FD (pth_accept (FD2INT(listen_fd),
-                                   (struct sockaddr *)&paddr, &plen));
+         fd = INT2FD (npth_accept (FD2INT(listen_fd),
+                                   (struct sockaddr *)&paddr, &plen));
          if (fd == GNUPG_INVALID_FD)
            {
              log_error ("accept failed: %s\n", strerror (errno));
@@ -2295,20 +2191,19 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
             }
           else
             {
-              char threadname[50];
+             npth_t thread;
 
-              snprintf (threadname, sizeof threadname-1,
-                        "conn fd=%d (gpg)", FD2INT(fd));
-              threadname[sizeof threadname -1] = 0;
-              pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
               ctrl->thread_startup.fd = fd;
-              if (!pth_spawn (tattr, start_connection_thread, ctrl))
+             ret = npth_create (&thread, &tattr,
+                                 start_connection_thread, ctrl);
+              if (ret)
                 {
                   log_error ("error spawning connection handler: %s\n",
-                             strerror (errno) );
+                            strerror (ret));
                   assuan_sock_close (fd);
                   xfree (ctrl);
                 }
+
             }
           fd = GNUPG_INVALID_FD;
        }
@@ -2319,8 +2214,8 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
           ctrl_t ctrl;
 
           plen = sizeof paddr;
-         fd = INT2FD(pth_accept (FD2INT(listen_fd_ssh),
-                                  (struct sockaddr *)&paddr, &plen));
+         fd = INT2FD(npth_accept (FD2INT(listen_fd_ssh),
+                                  (struct sockaddr *)&paddr, &plen));
          if (fd == GNUPG_INVALID_FD)
            {
              log_error ("accept failed for ssh: %s\n", strerror (errno));
@@ -2340,18 +2235,16 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
             }
           else
             {
-              char threadname[50];
+             npth_t thread;
 
               agent_init_default_ctrl (ctrl);
-              snprintf (threadname, sizeof threadname-1,
-                        "conn fd=%d (ssh)", FD2INT(fd));
-              threadname[sizeof threadname -1] = 0;
-              pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
               ctrl->thread_startup.fd = fd;
-              if (!pth_spawn (tattr, start_connection_thread_ssh, ctrl) )
+              ret = npth_create (&thread, &tattr,
+                                 start_connection_thread_ssh, ctrl);
+             if (ret)
                 {
                   log_error ("error spawning ssh connection handler: %s\n",
-                             strerror (errno) );
+                            strerror (ret));
                   assuan_sock_close (fd);
                   xfree (ctrl);
                 }
@@ -2360,11 +2253,9 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
        }
     }
 
-  pth_event_free (ev, PTH_FREE_ALL);
-  if (time_ev)
-    pth_event_free (time_ev, PTH_FREE_ALL);
   cleanup ();
   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
+  npth_attr_destroy (&tattr);
 }
 
 
@@ -2450,104 +2341,58 @@ check_own_socket_thread (void *arg)
 
 /* Check whether we are still listening on our own socket.  In case
    another gpg-agent process started after us has taken ownership of
-   our socket, we woul linger around without any real taks.  Thus we
+   our socket, we would linger around without any real task.  Thus we
    better check once in a while whether we are really needed.  */
 static void
 check_own_socket (void)
 {
   char *sockname;
-  pth_attr_t tattr;
+  npth_t thread;
+  npth_attr_t tattr;
+  int err;
 
-  if (!opt.use_standard_socket)
-    return; /* This check makes only sense in standard socket mode.  */
+  if (disable_check_own_socket)
+    return;
 
   if (check_own_socket_running || shutdown_pending)
     return;  /* Still running or already shutting down.  */
 
-  sockname = make_filename (opt.homedir, "S.gpg-agent", NULL);
+  sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
   if (!sockname)
     return; /* Out of memory.  */
 
-  tattr = pth_attr_new();
-  pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
-  pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
-  pth_attr_set (tattr, PTH_ATTR_NAME, "check-own-socket");
-
-  if (!pth_spawn (tattr, check_own_socket_thread, sockname))
-      log_error ("error spawning check_own_socket_thread: %s\n",
-                 strerror (errno) );
-  pth_attr_destroy (tattr);
+  err = npth_attr_init (&tattr);
+  if (err)
+    return;
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+  err = npth_create (&thread, &tattr, check_own_socket_thread, sockname);
+  if (err)
+    log_error ("error spawning check_own_socket_thread: %s\n", strerror (err));
+  npth_attr_destroy (&tattr);
 }
 
 
 
 /* Figure out whether an agent is available and running. Prints an
-   error if not.  If SILENT is true, no messages are printed.  Usually
-   started with MODE 0.  Returns 0 if the agent is running. */
+   error if not.  If SILENT is true, no messages are printed.
+   Returns 0 if the agent is running. */
 static int
-check_for_running_agent (int silent, int mode)
+check_for_running_agent (int silent)
 {
-  int rc;
-  char *infostr, *p;
+  gpg_error_t err;
+  char *sockname;
   assuan_context_t ctx = NULL;
-  int prot, pid;
-
-  if (!mode)
-    {
-      infostr = getenv ("GPG_AGENT_INFO");
-      if (!infostr || !*infostr)
-        {
-          if (!check_for_running_agent (silent, 1))
-            return 0; /* Okay, its running on the standard socket. */
-          if (!silent)
-            log_error (_("no gpg-agent running in this session\n"));
-          return -1;
-        }
 
-      infostr = xstrdup (infostr);
-      if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
-        {
-          xfree (infostr);
-          if (!check_for_running_agent (silent, 1))
-            return 0; /* Okay, its running on the standard socket. */
-          if (!silent)
-            log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
-          return -1;
-        }
+  sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
 
-      *p++ = 0;
-      pid = atoi (p);
-      while (*p && *p != PATHSEP_C)
-        p++;
-      prot = *p? atoi (p+1) : 0;
-      if (prot != 1)
-        {
-          xfree (infostr);
-          if (!silent)
-            log_error (_("gpg-agent protocol version %d is not supported\n"),
-                       prot);
-          if (!check_for_running_agent (silent, 1))
-            return 0; /* Okay, its running on the standard socket. */
-          return -1;
-        }
-    }
-  else /* MODE != 0 */
-    {
-      infostr = make_filename (opt.homedir, "S.gpg-agent", NULL);
-      pid = (pid_t)(-1);
-    }
-
-  rc = assuan_new (&ctx);
-  if (! rc)
-    rc = assuan_socket_connect (ctx, infostr, pid, 0);
-  xfree (infostr);
-  if (rc)
+  err = assuan_new (&ctx);
+  if (!err)
+    err = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0);
+  xfree (sockname);
+  if (err)
     {
-      if (!mode && !check_for_running_agent (silent, 1))
-        return 0; /* Okay, its running on the standard socket. */
-
-      if (!mode && !silent)
-        log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
+      if (!silent)
+        log_error (_("no gpg-agent running in this session\n"));
 
       if (ctx)
        assuan_release (ctx);
index e246e88..42c4b1f 100644 (file)
@@ -14,7 +14,8 @@ the ~/.gnupg home directory.  This directory is named
 and should have permissions 700.
 
 The secret keys are stored in files with a name matching the
-hexadecimal representation of the keygrip[2].
+hexadecimal representation of the keygrip[2] and suffixed with ".key".
+
 
 Unprotected Private Key Format
 ==============================
@@ -57,7 +58,7 @@ keys is in canonical representation[3]:
     (u #304559a..[some bytes not shown]..9b#)
    )
    (uri http://foo.bar x-foo:whatever_you_want)
-)  
+)
 
 
 Protected Private Key Format
@@ -73,7 +74,7 @@ A protected key is like this:
    )
    (uri http://foo.bar x-foo:whatever_you_want)
    (comment whatever)
-)  
+)
 
 
 In this scheme the encrypted_octet_string is encrypted according to
@@ -83,56 +84,94 @@ encrypted_octet_string.  The result of the decryption process is a
 list of the secret key parameters.  The protected-at expression is
 optional; the isotimestamp is 15 bytes long (e.g. "19610711T172000").
 
-The only available protection mode for now is
+The currently defined protection modes are:
 
-  openpgp-s2k3-sha1-aes-cbc
+1. openpgp-s2k3-sha1-aes-cbc
 
-which describes an algorithm using using AES in CBC mode for
-encryption, SHA-1 for integrity protection and the String to Key
-algorithm 3 from OpenPGP (rfc2440).
+  This describes an algorithm using using AES in CBC mode for
+  encryption, SHA-1 for integrity protection and the String to Key
+  algorithm 3 from OpenPGP (rfc2440).
 
-Example:
+  Example:
 
-(protected openpgp-s2k3-sha1-aes-cbc
-  ((sha1 16byte_salt no_of_iterations) 16byte_iv)
-  encrypted_octet_string
-)
+  (protected openpgp-s2k3-sha1-aes-cbc
+    ((sha1 16byte_salt no_of_iterations) 16byte_iv)
+    encrypted_octet_string
+  )
 
-The encrypted_octet string should yield this S-Exp (in canonical
-representation) after decryption:
+  The encrypted_octet string should yield this S-Exp (in canonical
+  representation) after decryption:
 
-(
- (
-  (d #046129F..[some bytes not shown]..81#)
-  (p #00e861b..[some bytes not shown]..f1#)
-  (q #00f7a7c..[some bytes not shown]..61#)
-  (u #304559a..[some bytes not shown]..9b#) 
- ) 
- (hash sha1 #...[hashvalue]...#)
-)
-
-For padding reasons, random bytes are appended to this list - they can
-easily be stripped by looking for the end of the list. 
-
-The hash is calculated on the concatenation of the public key and
-secret key parameter lists: i.e it is required to hash the
-concatenation of these 6 canonical encoded lists for RSA, including
-the parenthesis, the algorithm keyword and (if used) the protected-at
-list.
-
-(rsa
- (n #00e0ce9..[some bytes not shown]..51#)
- (e #010001#)
- (d #046129F..[some bytes not shown]..81#)
- (p #00e861b..[some bytes not shown]..f1#)
- (q #00f7a7c..[some bytes not shown]..61#)
- (u #304559a..[some bytes not shown]..9b#)
- (protected-at "18950523T000000")
-)
+  (
+   (
+    (d #046129F..[some bytes not shown]..81#)
+    (p #00e861b..[some bytes not shown]..f1#)
+    (q #00f7a7c..[some bytes not shown]..61#)
+    (u #304559a..[some bytes not shown]..9b#)
+   )
+   (hash sha1 #...[hashvalue]...#)
+  )
+
+  For padding reasons, random bytes are appended to this list - they can
+  easily be stripped by looking for the end of the list.
+
+  The hash is calculated on the concatenation of the public key and
+  secret key parameter lists: i.e it is required to hash the
+  concatenation of these 6 canonical encoded lists for RSA, including
+  the parenthesis, the algorithm keyword and (if used) the protected-at
+  list.
+
+  (rsa
+   (n #00e0ce9..[some bytes not shown]..51#)
+   (e #010001#)
+   (d #046129F..[some bytes not shown]..81#)
+   (p #00e861b..[some bytes not shown]..f1#)
+   (q #00f7a7c..[some bytes not shown]..61#)
+   (u #304559a..[some bytes not shown]..9b#)
+   (protected-at "18950523T000000")
+  )
+
+  After decryption the hash must be recalculated and compared against
+  the stored one - If they don't match the integrity of the key is not
+  given.
+
+2. openpgp-native
+
+  This is a wrapper around the OpenPGP Private Key Transport format
+  which resembles the standard OpenPGP format and allows the use of an
+  existing key without re-encrypting to the default protection format.
+
+  Example:
+
+  (protected openpgp-native
+    (openpgp-private-key
+     (version V)
+     (algo PUBKEYALGO)
+     (skey _ P1 _ P2 _ P3 ... e PN)
+     (csum n)
+     (protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT)))
+
+  Note that the public key paramaters in SKEY are duplicated and
+  should be identical to their copies in the standard parameter
+  elements.  Here is an example of an entire protected private key
+  using this format:
+
+  (protected-private-key
+   (rsa
+    (n #00e0ce9..[some bytes not shown]..51#)
+    (e #010001#)
+    (protected openpgp-native
+     (openpgp-private-key
+      (version 4)
+      (algo rsa)
+      (skey _ #00e0ce9..[some bytes not shown]..51#
+            _ #010001#
+            e #.........................#)
+      (protection sha1 aes #aabbccddeeff00112233445566778899#
+                  3 sha1 #2596f93e85f41e53# 3:190))))
+   (uri http://foo.bar x-foo:whatever_you_want)
+   (comment whatever))
 
-After decryption the hash must be recalculated and compared against
-the stored one - If they don't match the integrity of the key is not
-given.
 
 
 Shadowed Private Key Format
@@ -149,16 +188,151 @@ to keys stored on a token:
    )
    (uri http://foo.bar x-foo:whatever_you_want)
    (comment whatever)
-)  
+)
 
 The currently used protocol is "ti-v1" (token info version 1).  The
 second list with the information has this layout:
 
-(card_serial_number id_string_of_key)
+(card_serial_number id_string_of_key fixed_pin_length)
+
+FIXED_PIN_LENGTH is optional.  It can be used to store the length of
+the PIN; a value of 0 indicates that this information is not
+available.  The rationale for this field is that some pinpad equipped
+readers don't allow passing a variable length PIN.
 
 More items may be added to the list.
 
 
+OpenPGP Private Key Transfer Format
+===================================
+
+This format is used to transfer keys between gpg and gpg-agent.
+
+(openpgp-private-key
+  (version V)
+  (algo PUBKEYALGO)
+  (curve CURVENAME)
+  (skey _ P1 _ P2 _ P3 ... e PN)
+  (csum n)
+  (protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT))
+
+
+* V is the packet version number (3 or 4).
+* PUBKEYALGO is a Libgcrypt algo name
+* CURVENAME is the name of the curve - only used with ECC.
+* P1 .. PN are the parameters; the public parameters are never encrypted
+  the secrect key parameters are encrypted if the "protection" list is
+  given.  To make this more explicit each parameter is preceded by a
+  flag "_" for cleartext or "e" for encrypted text.
+* CSUM is the deprecated 16 bit checksum as defined by OpenPGP.  This
+  is an optional element.
+* If PROTTYPE is "sha1" the new style SHA1 checksum is used if it is "sum"
+  the old 16 bit checksum (above) is used and if it is "none" no
+  protection at all is used.
+* PROTALGO is a Libgcrypt style cipher algorithm name
+* IV is the initialization verctor.
+* S2KMODE is the value from RFC-4880.
+* S2KHASH is a a libgcrypt style hash algorithm identifier.
+* S2KSALT is the 8 byte salt
+* S2KCOUNT is the count value from RFC-4880.
+
+
+Persistent Passphrase Format
+============================
+
+To allow persistent storage of cached passphrases we use a scheme
+similar to the private-key storage format.  This is a master
+passphrase format where each file may protect several secrets under
+one master passphrase.  It is possible to have several of those files
+each protected by a dedicated master passphrase.  Clear text keywords
+allow to list the available protected passphrases.
+
+The name of the files with these protected secrets have this form:
+pw-<string>.dat.  STRING may be an arbitrary string, as a default name
+for the passphrase storage the name "pw-default.dat" is suggested.
+
+
+(protected-shared-secret
+   ((desc descriptive_text)
+    (key [key_1] (keyword_1 keyword_2 keyword_n))
+    (key [key_2] (keyword_21 keyword_22 keyword_2n))
+    (key [key_n] (keyword_n1 keyword_n2 keyword_nn))
+    (protected mode (parms) encrypted_octet_string)
+    (protected-at <isotimestamp>)
+   )
+)
+
+After decryption the encrypted_octet_string yields this S-expression:
+
+(
+ (
+  (value key_1 value_1)
+  (value key_2 value_2)
+  (value key_n value_n)
+ )
+ (hash sha1 #...[hashvalue]...#)
+)
+
+The "descriptive_text" is displayed with the prompt to enter the
+unprotection passphrase.
+
+KEY_1 to KEY_N are unique identifiers for the shared secret, for
+example an URI.  In case this information should be kept confidential
+as well, they may not appear in the unprotected part; however they are
+mandatory in the encrypted_octet_string.  The list of keywords is
+optional.  The oder of the "key" lists and the order of the "value"
+lists mut match, that is the first "key"-list is associated with the
+first "value" list in the encrypted_octet_string.
+
+The protection mode etc. is indentical to the protection mode as
+decribed for the private key format.
+
+list of the secret key parameters.  The protected-at expression is
+optional; the isotimestamp is 15 bytes long (e.g. "19610711T172000").
+
+The "hash" in the encrypted_octet_string is calculated on the
+concatenation of the key list and value lists: i.e it is required to
+hash the concatenation of all these lists, including the
+parenthesis and (if used) the protected-at list.
+
+Example:
+
+(protected-shared-secret
+   ((desc "List of system passphrases")
+    (key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
+    (key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
+    (key)
+    (protected mode (parms) encrypted_octet_string)
+    (protected-at "20100915T111722")
+   )
+)
+
+with "encrypted_octet_string" decoding to:
+
+(
+ (
+  (value 4:1002 "signal flags at the lock")
+  (value 4:1001 "taocp")
+  (value 1:0    "premature optimization is the root of all evil")
+ )
+ (hash sha1 #0102030405060708091011121314151617181920#)
+)
+
+To compute the hash this S-expression (in canoncical format) was
+hashed:
+
+   ((desc "List of system passphrases")
+    (key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
+    (key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
+    (key)
+    (value 4:1002 "signal flags at the lock")
+    (value 4:1001 "taocp")
+    (value 1:0    "premature optimization is the root of all evil")
+    (protected-at "20100915T111722")
+   )
+
+
+
 
 
 
index 77f2bb0..c60b3f4 100644 (file)
@@ -32,7 +32,7 @@
 
 /* Structures used by the callback mechanism to convey information
    pertaining to key pairs.  */
-struct keypair_info_s 
+struct keypair_info_s
 {
   struct keypair_info_s *next;
   int no_cert;
@@ -44,7 +44,7 @@ struct keypair_info_s
 };
 typedef struct keypair_info_s *KEYPAIR_INFO;
 
-struct kpinfo_cb_parm_s 
+struct kpinfo_cb_parm_s
 {
   ctrl_t ctrl;
   int error;
@@ -56,13 +56,13 @@ struct kpinfo_cb_parm_s
    pertaining to certificates.  */
 struct certinfo_s {
   struct certinfo_s *next;
-  int type;  
+  int type;
   int done;
   char id[1];
 };
 typedef struct certinfo_s *CERTINFO;
 
-struct certinfo_cb_parm_s 
+struct certinfo_cb_parm_s
 {
   ctrl_t ctrl;
   int error;
@@ -75,9 +75,9 @@ struct certinfo_cb_parm_s
 struct sinfo_s {
   struct sinfo_s *next;
   char *data;       /* Points into keyword. */
-  char keyword[1];  
+  char keyword[1];
 };
-typedef struct sinfo_s *SINFO;  
+typedef struct sinfo_s *SINFO;
 
 struct sinfo_cb_parm_s {
   int error;
@@ -172,7 +172,7 @@ kpinfo_cb (void *opaque, const char *line)
       return;
     }
   *p = 0; /* ignore trailing stuff */
-  
+
   /* store it */
   item->next = parm->info;
   parm->info = item;
@@ -202,7 +202,7 @@ certinfo_cb (void *opaque, const char *line)
   for (pend = p; *pend && !spacep (pend); pend++)
     ;
   if (p == pend || !*p)
-    { 
+    {
       parm->error = gpg_error (GPG_ERR_INV_RESPONSE);
       return;
     }
@@ -258,7 +258,7 @@ send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context)
   int rc;
   char *derbuf;
   size_t derbuflen;
-  
+
   rc = agent_card_readcert (ctrl, id, &derbuf, &derbuflen);
   if (rc)
     {
@@ -275,7 +275,7 @@ send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context)
           break;
         }
       if (opt.verbose || !*action)
-        log_info ("error reading certificate `%s': %s%s\n",
+        log_info ("error reading certificate '%s': %s%s\n",
                   id? id:"?", gpg_strerror (rc), action);
 
       return *action? 0 : rc;
@@ -312,7 +312,7 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
   unsigned char grip[20];
   char *p;
   int i;
-  static int certtype_list[] = { 
+  static int certtype_list[] = {
     111, /* Root CA */
     101, /* trusted */
     102, /* useful */
@@ -344,7 +344,7 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
       log_debug ("agent_card_learn failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
-  
+
   log_info ("card has S/N: %s\n", serialno);
 
   /* Pass on all the collected status information. */
@@ -368,7 +368,7 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
           if (opt.verbose)
             log_info ("          id: %s    (type=%d)\n",
                       citem->id, citem->type);
-          
+
           if (assuan_context)
             {
               rc = send_cert_back (ctrl, citem->id, assuan_context);
@@ -378,7 +378,7 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
             }
         }
     }
-  
+
   for (item = parm.info; item; item = item->next)
     {
       unsigned char *pubkey, *shdkey;
@@ -398,10 +398,10 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
 
       for (p=item->hexgrip, i=0; i < 20; p += 2, i++)
         grip[i] = xtoi_2 (p);
-      
+
       if (!agent_key_available (grip))
         continue; /* The key is already available. */
-      
+
       /* Unknown key - store it. */
       rc = agent_card_readkey (ctrl, item->id, &pubkey);
       if (rc)
@@ -440,11 +440,11 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
 
       if (opt.verbose)
         log_info ("stored\n");
-      
+
       if (assuan_context)
         {
           CERTINFO citem;
-          
+
           /* only send the certificate if we have not done so before */
           for (citem = cparm.info; citem; citem = citem->next)
             {
@@ -460,7 +460,7 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
         }
     }
 
-  
+
  leave:
   xfree (serialno);
   release_keypair_info (parm.info);
@@ -468,5 +468,3 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
   release_sinfo (sparm.info);
   return rc;
 }
-
-
index 9e1c47d..945de3c 100644 (file)
 
 /* DECRYPT the stuff in ciphertext which is expected to be a S-Exp.
    Try to get the key from CTRL and write the decoded stuff back to
-   OUTFP. */
+   OUTFP.   The padding information is stored at R_PADDING with -1
+   for not known.  */
 int
 agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
                  const unsigned char *ciphertext, size_t ciphertextlen,
-                 membuf_t *outbuf
+                 membuf_t *outbuf, int *r_padding)
 {
   gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL;
   unsigned char *shadow_info = NULL;
@@ -44,6 +45,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
   char *buf = NULL;
   size_t len;
 
+  *r_padding = -1;
+
   if (!ctrl->have_keygrip)
     {
       log_error ("speculative decryption not yet supported\n");
@@ -64,19 +67,17 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
       log_printhex ("keygrip:", ctrl->keygrip, 20);
       log_printhex ("cipher: ", ciphertext, ciphertextlen);
     }
-  rc = agent_key_from_file (ctrl, desc_text,
+  rc = agent_key_from_file (ctrl, NULL, desc_text,
                             ctrl->keygrip, &shadow_info,
-                            CACHE_MODE_NORMAL, NULL, &s_skey);
+                            CACHE_MODE_NORMAL, NULL, &s_skey, NULL);
   if (rc)
     {
-      if (gpg_err_code (rc) == GPG_ERR_ENOENT)
-        rc = gpg_error (GPG_ERR_NO_SECKEY);
-      else
+      if (gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
         log_error ("failed to read the secret key\n");
       goto leave;
     }
 
-  if (!s_skey)
+  if (shadow_info)
     { /* divert operation to the smartcard */
 
       if (!gcry_sexp_canon_len (ciphertext, ciphertextlen, NULL, NULL))
@@ -85,7 +86,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
           goto leave;
         }
 
-      rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, &buf, &len );
+      rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info,
+                             &buf, &len, r_padding);
       if (rc)
         {
           log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
@@ -136,7 +138,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
           put_membuf (outbuf, buf, len);
           put_membuf (outbuf, ")", 2);
         }
-    }      
+    }
 
 
  leave:
@@ -147,5 +149,3 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
   xfree (shadow_info);
   return rc;
 }
-
-
index 25cadb2..d737bad 100644 (file)
@@ -1,5 +1,6 @@
 /* pksign.c - public key signing (well, actually using a secret key)
- * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2001-2004, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2001-2004, 2010, 2013  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -28,6 +29,7 @@
 #include <sys/stat.h>
 
 #include "agent.h"
+#include "i18n.h"
 
 
 static int
@@ -42,13 +44,13 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
       const char *s;
       char tmp[16+1];
       int i;
-      
+
       s = gcry_md_algo_name (algo);
       if (s && strlen (s) < 16)
        {
          for (i=0; i < strlen (s); i++)
            tmp[i] = tolower (s[i]);
-         tmp[i] = '\0';   
+         tmp[i] = '\0';
        }
 
       rc = gcry_sexp_build (&hash, NULL,
@@ -58,20 +60,168 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
   else
     {
       gcry_mpi_t mpi;
-      
+
       rc = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, md, mdlen, NULL);
-      if (! rc)
+      if (!rc)
        {
          rc = gcry_sexp_build (&hash, NULL,
                                "(data (flags raw) (value %m))",
                                mpi);
          gcry_mpi_release (mpi);
        }
-         
+      else
+        hash = NULL;
+
     }
-  
+
   *r_hash = hash;
-  return rc;   
+  return rc;
+}
+
+
+/* Return the number of bits of the Q parameter from the DSA key
+   KEY.  */
+static unsigned int
+get_dsa_qbits (gcry_sexp_t key)
+{
+  gcry_sexp_t l1, l2;
+  gcry_mpi_t q;
+  unsigned int nbits;
+
+  l1 = gcry_sexp_find_token (key, "private-key", 0);
+  if (!l1)
+    l1 = gcry_sexp_find_token (key, "protected-private-key", 0);
+  if (!l1)
+    l1 = gcry_sexp_find_token (key, "shadowed-private-key", 0);
+  if (!l1)
+    l1 = gcry_sexp_find_token (key, "public-key", 0);
+  if (!l1)
+    return 0; /* Does not contain a key object.  */
+  l2 = gcry_sexp_cadr (l1);
+  gcry_sexp_release  (l1);
+  l1 = gcry_sexp_find_token (l2, "q", 1);
+  gcry_sexp_release (l2);
+  if (!l1)
+    return 0; /* Invalid object.  */
+  q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+  gcry_sexp_release (l1);
+  if (!q)
+    return 0; /* Missing value.  */
+  nbits = gcry_mpi_get_nbits (q);
+  gcry_mpi_release (q);
+
+  return nbits;
+}
+
+
+/* Return an appropriate hash algorithm to be used with RFC-6979 for a
+   message digest of length MDLEN.  Although a fallback of SHA-256 is
+   used the current implementation in Libgcrypt will reject a hash
+   algorithm which does not match the length of the message.  */
+static const char *
+rfc6979_hash_algo_string (size_t mdlen)
+{
+  switch (mdlen)
+    {
+    case 20: return "sha1";
+    case 28: return "sha224";
+    case 32: return "sha256";
+    case 48: return "sha384";
+    case 64: return "sha512";
+    default: return "sha256";
+    }
+}
+
+
+/* Encode a message digest for use with the EdDSA algorithm
+   (i.e. curve Ed25519). */
+static gpg_error_t
+do_encode_eddsa (const byte *md, size_t mdlen, gcry_sexp_t *r_hash)
+{
+  gpg_error_t err;
+  gcry_sexp_t hash;
+
+  *r_hash = NULL;
+  err = gcry_sexp_build (&hash, NULL,
+                         "(data(flags eddsa)(hash-algo sha512)(value %b))",
+                         (int)mdlen, md);
+  if (!err)
+    *r_hash = hash;
+  return err;
+}
+
+
+/* Encode a message digest for use with an DSA algorithm. */
+static gpg_error_t
+do_encode_dsa (const byte *md, size_t mdlen, int pkalgo, gcry_sexp_t pkey,
+               gcry_sexp_t *r_hash)
+{
+  gpg_error_t err;
+  gcry_sexp_t hash;
+  unsigned int qbits;
+
+  *r_hash = NULL;
+
+  if (pkalgo == GCRY_PK_ECDSA)
+    qbits = gcry_pk_get_nbits (pkey);
+  else if (pkalgo == GCRY_PK_DSA)
+    qbits = get_dsa_qbits (pkey);
+  else
+    return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
+
+  if (pkalgo == GCRY_PK_DSA && (qbits%8))
+    {
+      /* FIXME: We check the QBITS but print a message about the hash
+         length.  */
+      log_error (_("DSA requires the hash length to be a"
+                   " multiple of 8 bits\n"));
+      return gpg_error (GPG_ERR_INV_LENGTH);
+    }
+
+  /* Don't allow any Q smaller than 160 bits.  We don't want someone
+     to issue signatures from a key with a 16-bit Q or something like
+     that, which would look correct but allow trivial forgeries.  Yes,
+     I know this rules out using MD5 with DSA. ;) */
+  if (qbits < 160)
+    {
+      log_error (_("%s key uses an unsafe (%u bit) hash\n"),
+                 gcry_pk_algo_name (pkalgo), qbits);
+      return gpg_error (GPG_ERR_INV_LENGTH);
+    }
+
+  /* Check if we're too short.  Too long is safe as we'll
+   * automatically left-truncate.
+   *
+   * This check would require the use of SHA512 with ECDSA 512. I
+   * think this is overkill to fail in this case.  Therefore, relax
+   * the check, but only for ECDSA keys.  We may need to adjust it
+   * later for general case.  (Note that the check is really a bug for
+   * ECDSA 521 as the only hash that matches it is SHA 512, but 512 <
+   * 521 ).
+   */
+  if (mdlen < ((pkalgo==GCRY_PK_ECDSA && qbits > 521) ? 512 : qbits)/8)
+    {
+      log_error (_("a %zu bit hash is not valid for a %u bit %s key\n"),
+                 mdlen*8,
+                 gcry_pk_get_nbits (pkey),
+                 gcry_pk_algo_name (pkalgo));
+      /* FIXME: we need to check the requirements for ECDSA.  */
+      if (mdlen < 20 || pkalgo == GCRY_PK_DSA)
+        return gpg_error (GPG_ERR_INV_LENGTH);
+    }
+
+  /* Truncate.  */
+  if (mdlen > qbits/8)
+    mdlen = qbits/8;
+
+  /* Create the S-expression.  */
+  err = gcry_sexp_build (&hash, NULL,
+                         "(data (flags rfc6979) (hash %s %b))",
+                         rfc6979_hash_algo_string (mdlen),
+                         (int)mdlen, md);
+  if (!err)
+    *r_hash = hash;
+  return err;
 }
 
 
@@ -87,7 +237,7 @@ do_encode_raw_pkcs1 (const byte *md, size_t mdlen, unsigned int nbits,
   gcry_sexp_t hash;
   unsigned char *frame;
   size_t i, n, nframe;
-            
+
   nframe = (nbits+7) / 8;
   if ( !mdlen || mdlen + 8 + 4 > nframe )
     {
@@ -98,7 +248,7 @@ do_encode_raw_pkcs1 (const byte *md, size_t mdlen, unsigned int nbits,
   frame = xtrymalloc (nframe);
   if (!frame)
     return gpg_error_from_syserror ();
-  
+
   /* Assemble the pkcs#1 block type 1. */
   n = 0;
   frame[n++] = 0;
@@ -111,7 +261,7 @@ do_encode_raw_pkcs1 (const byte *md, size_t mdlen, unsigned int nbits,
   memcpy (frame+n, md, mdlen );
   n += mdlen;
   assert (n == nframe);
-  
+
   /* Create the S-expression.  */
   rc = gcry_sexp_build (&hash, NULL,
                         "(data (flags raw) (value %b))",
@@ -119,56 +269,156 @@ do_encode_raw_pkcs1 (const byte *md, size_t mdlen, unsigned int nbits,
   xfree (frame);
 
   *r_hash = hash;
-  return rc;   
+  return rc;
 }
 
 
 
 /* SIGN whatever information we have accumulated in CTRL and return
    the signature S-expression.  LOOKUP is an optional function to
-   provide a way for lower layers to ask for the caching TTL. */
+   provide a way for lower layers to ask for the caching TTL.  If a
+   CACHE_NONCE is given that cache item is first tried to get a
+   passphrase.  If OVERRIDEDATA is not NULL, OVERRIDEDATALEN bytes
+   from this buffer are used instead of the data in CTRL.  The
+   override feature is required to allow the use of Ed25519 with ssh
+   because Ed25519 dies the hashing itself.  */
 int
-agent_pksign_do (ctrl_t ctrl, const char *desc_text,
+agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
+                 const char *desc_text,
                 gcry_sexp_t *signature_sexp,
-                 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl)
+                 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
+                 const void *overridedata, size_t overridedatalen)
 {
   gcry_sexp_t s_skey = NULL, s_sig = NULL;
   unsigned char *shadow_info = NULL;
   unsigned int rc = 0;         /* FIXME: gpg-error? */
+  const unsigned char *data;
+  int datalen;
+
+  if (overridedata)
+    {
+      data = overridedata;
+      datalen = overridedatalen;
+    }
+  else
+    {
+      data = ctrl->digest.value;
+      datalen = ctrl->digest.valuelen;
+    }
 
-  if (! ctrl->have_keygrip)
+  if (!ctrl->have_keygrip)
     return gpg_error (GPG_ERR_NO_SECKEY);
 
-  rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip,
+  rc = agent_key_from_file (ctrl, cache_nonce, desc_text, ctrl->keygrip,
                             &shadow_info, cache_mode, lookup_ttl,
-                            &s_skey);
+                            &s_skey, NULL);
   if (rc)
     {
-      log_error ("failed to read the secret key\n");
+      if (gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
+        log_error ("failed to read the secret key\n");
       goto leave;
     }
 
-  if (!s_skey)
+  if (shadow_info)
     {
       /* Divert operation to the smartcard */
-
+      size_t len;
       unsigned char *buf = NULL;
-      size_t len = 0;
+      int key_type;
+      int is_RSA = 0;
+      int is_ECDSA = 0;
+      int is_EdDSA = 0;
 
-      rc = divert_pksign (ctrl, 
-                          ctrl->digest.value, 
-                          ctrl->digest.valuelen,
+      if (agent_is_eddsa_key (s_skey))
+        is_EdDSA = 1;
+      else
+        {
+          key_type = agent_is_dsa_key (s_skey);
+          if (key_type == 0)
+            is_RSA = 1;
+          else if (key_type == GCRY_PK_ECDSA)
+            is_ECDSA = 1;
+        }
+
+      rc = divert_pksign (ctrl,
+                          data, datalen,
                           ctrl->digest.algo,
-                          shadow_info, &buf);
+                          shadow_info, &buf, &len);
       if (rc)
         {
           log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
-      len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
-      assert (len);
 
-      rc = gcry_sexp_sscan (&s_sig, NULL, (char*)buf, len);
+      if (is_RSA)
+        {
+          if (*buf & 0x80)
+            {
+              len++;
+              buf = xtryrealloc (buf, len);
+              if (!buf)
+                goto leave;
+
+              memmove (buf + 1, buf, len - 1);
+              *buf = 0;
+            }
+
+          rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))", len, buf);
+        }
+      else if (is_EdDSA)
+        {
+          rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(eddsa(r%b)(s%b)))",
+                                len/2, buf, len/2, buf + len/2);
+        }
+      else if (is_ECDSA)
+        {
+          unsigned char *r_buf_allocated = NULL;
+          unsigned char *s_buf_allocated = NULL;
+          unsigned char *r_buf, *s_buf;
+          int r_buflen, s_buflen;
+
+          r_buflen = s_buflen = len/2;
+
+          if (*buf & 0x80)
+            {
+              r_buflen++;
+              r_buf_allocated = xtrymalloc (r_buflen);
+              if (!r_buf_allocated)
+                goto leave;
+
+              r_buf = r_buf_allocated;
+              memcpy (r_buf + 1, buf, len/2);
+              *r_buf = 0;
+            }
+          else
+            r_buf = buf;
+
+          if (*(buf + len/2) & 0x80)
+            {
+              s_buflen++;
+              s_buf_allocated = xtrymalloc (s_buflen);
+              if (!s_buf_allocated)
+                {
+                  xfree (r_buf_allocated);
+                  goto leave;
+                }
+
+              s_buf = s_buf_allocated;
+              memcpy (s_buf + 1, buf + len/2, len/2);
+              *s_buf = 0;
+            }
+          else
+            s_buf = buf + len/2;
+
+          rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(ecdsa(r%b)(s%b)))",
+                                r_buflen, r_buf,
+                                s_buflen, s_buf);
+          xfree (r_buf_allocated);
+          xfree (s_buf_allocated);
+        }
+      else
+        rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
       xfree (buf);
       if (rc)
        {
@@ -180,18 +430,23 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text,
   else
     {
       /* No smartcard, but a private key */
-
       gcry_sexp_t s_hash = NULL;
+      int dsaalgo;
 
       /* Put the hash into a sexp */
-      if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1)
-        rc = do_encode_raw_pkcs1 (ctrl->digest.value,
-                                  ctrl->digest.valuelen,
+      if (agent_is_eddsa_key (s_skey))
+        rc = do_encode_eddsa (data, datalen,
+                              &s_hash);
+      else if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1)
+        rc = do_encode_raw_pkcs1 (data, datalen,
                                   gcry_pk_get_nbits (s_skey),
                                   &s_hash);
+      else if ( (dsaalgo = agent_is_dsa_key (s_skey)) )
+        rc = do_encode_dsa (data, datalen,
+                            dsaalgo, s_skey,
+                            &s_hash);
       else
-        rc = do_encode_md (ctrl->digest.value,
-                           ctrl->digest.valuelen,
+        rc = do_encode_md (data, datalen,
                            ctrl->digest.algo,
                            &s_hash,
                            ctrl->digest.raw_value);
@@ -200,8 +455,8 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text,
 
       if (DBG_CRYPTO)
         {
-          log_debug ("skey: ");
-          gcry_sexp_dump (s_skey);
+          gcry_log_debugsxp ("skey", s_skey);
+          gcry_log_debugsxp ("hash", s_hash);
         }
 
       /* sign */
@@ -214,10 +469,7 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text,
         }
 
       if (DBG_CRYPTO)
-        {
-          log_debug ("result: ");
-          gcry_sexp_dump (s_sig);
-        }
+        gcry_log_debugsxp ("rslt", s_sig);
     }
 
  leave:
@@ -231,17 +483,19 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text,
 }
 
 /* SIGN whatever information we have accumulated in CTRL and write it
-   back to OUTFP. */
+   back to OUTFP.  If a CACHE_NONCE is given that cache item is first
+   tried to get a passphrase.  */
 int
-agent_pksign (ctrl_t ctrl, const char *desc_text,
-              membuf_t *outbuf, cache_mode_t cache_mode) 
+agent_pksign (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
+              membuf_t *outbuf, cache_mode_t cache_mode)
 {
   gcry_sexp_t s_sig = NULL;
   char *buf = NULL;
   size_t len = 0;
   int rc = 0;
 
-  rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode, NULL);
+  rc = agent_pksign_do (ctrl, cache_nonce, desc_text, &s_sig, cache_mode, NULL,
+                        NULL, 0);
   if (rc)
     goto leave;
 
index 8f6018b..ad8e500 100644 (file)
 
 #define JNLIB_NEED_LOG_LOGV
 #include "agent.h"
-#include "minip12.h"
 #include "simple-pwquery.h"
 #include "i18n.h"
 #include "sysutils.h"
+#include "../common/init.h"
 
 
 enum cmd_and_opt_values
@@ -90,7 +90,7 @@ my_strusage (int level)
   const char *p;
   switch (level)
     {
-    case 11: p = "gpg-preset-passphrase (GnuPG)";
+    case 11: p = "gpg-preset-passphrase (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -217,7 +217,7 @@ main (int argc, char **argv)
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   opt_homedir = default_homedir ();
 
@@ -248,7 +248,7 @@ main (int argc, char **argv)
 
   /* Tell simple-pwquery about the the standard socket name.  */
   {
-    char *tmp = make_filename (opt_homedir, "S.gpg-agent", NULL);
+    char *tmp = make_filename (opt_homedir, GPG_AGENT_SOCK_NAME, NULL);
     simple_pw_set_socket (tmp);
     xfree (tmp);
   }
index aff0abd..5e540cf 100644 (file)
 
 #define JNLIB_NEED_LOG_LOGV
 #include "agent.h"
-#include "minip12.h"
 #include "i18n.h"
 #include "get-passphrase.h"
 #include "sysutils.h"
-#include "estream.h"
+#include "../common/init.h"
 
 
 enum cmd_and_opt_values
@@ -64,9 +63,6 @@ enum cmd_and_opt_values
   oS2Kcalibration,
   oCanonical,
 
-  oP12Import,
-  oP12Export,
-  oP12Charset,
   oStore,
   oForce,
   oHaveCert,
@@ -100,14 +96,10 @@ static int opt_have_cert;
 static const char *opt_passphrase;
 static char *opt_prompt;
 static int opt_status_msg;
-static const char *opt_p12_charset;
 static const char *opt_agent_program;
-static session_env_t opt_session_env;
 
 static char *get_passphrase (int promptno);
 static void release_passphrase (char *pw);
-static int store_private_key (const unsigned char *grip,
-                              const void *buffer, size_t length, int force);
 
 
 static ARGPARSE_OPTS opts[] = {
@@ -118,11 +110,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (oShadow,    "shadow", "create a shadow entry for a public key"),
   ARGPARSE_c (oShowShadowInfo,  "show-shadow-info", "return the shadow info"),
   ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""),
-  ARGPARSE_c (oP12Import, "p12-import",
-              "import a pkcs#12 encoded private key"),
-  ARGPARSE_c (oP12Export, "p12-export",
-              "export a private key pkcs#12 encoded"),
-
   ARGPARSE_c (oS2Kcalibration, "s2k-calibration", "@"),
 
   ARGPARSE_group (301, N_("@\nOptions:\n ")),
@@ -132,8 +119,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oCanonical, "canonical", "write output in canonical format"),
 
   ARGPARSE_s_s (oPassphrase, "passphrase", "|STRING|use passphrase STRING"),
-  ARGPARSE_s_s (oP12Charset,"p12-charset",
-                "|NAME|set charset for a new PKCS#12 passphrase to NAME"),
   ARGPARSE_s_n (oHaveCert, "have-cert",
                 "certificate to export provided on STDIN"),
   ARGPARSE_s_n (oStore,    "store",
@@ -157,7 +142,7 @@ my_strusage (int level)
   const char *p;
   switch (level)
     {
-    case 11: p = "gpg-protect-tool (GnuPG)";
+    case 11: p = "gpg-protect-tool (" GNUPG_NAME ")";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -206,7 +191,7 @@ make_canonical (const char *fname, const char *buf, size_t buflen)
   rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
   if (rc)
     {
-      log_error ("invalid S-Expression in `%s' (off=%u): %s\n",
+      log_error ("invalid S-Expression in '%s' (off=%u): %s\n",
                  fname, (unsigned int)erroff, gpg_strerror (rc));
       return NULL;
     }
@@ -273,7 +258,7 @@ read_file (const char *fname, size_t *r_length)
           nread = fread (buf+buflen, 1, NCHUNK, fp);
           if (nread < NCHUNK && ferror (fp))
             {
-              log_error ("error reading `[stdin]': %s\n", strerror (errno));
+              log_error ("error reading '[stdin]': %s\n", strerror (errno));
               xfree (buf);
               return NULL;
             }
@@ -290,13 +275,13 @@ read_file (const char *fname, size_t *r_length)
       fp = fopen (fname, "rb");
       if (!fp)
         {
-          log_error ("can't open `%s': %s\n", fname, strerror (errno));
+          log_error ("can't open '%s': %s\n", fname, strerror (errno));
           return NULL;
         }
 
       if (fstat (fileno(fp), &st))
         {
-          log_error ("can't stat `%s': %s\n", fname, strerror (errno));
+          log_error ("can't stat '%s': %s\n", fname, strerror (errno));
           fclose (fp);
           return NULL;
         }
@@ -305,7 +290,7 @@ read_file (const char *fname, size_t *r_length)
       buf = xmalloc (buflen+1);
       if (fread (buf, buflen, 1, fp) != 1)
         {
-          log_error ("error reading `%s': %s\n", fname, strerror (errno));
+          log_error ("error reading '%s': %s\n", fname, strerror (errno));
           fclose (fp);
           xfree (buf);
           return NULL;
@@ -349,7 +334,7 @@ read_and_protect (const char *fname)
     return;
 
   pw = get_passphrase (1);
-  rc = agent_protect (key, pw, &result, &resultlen);
+  rc = agent_protect (key, pw, &result, &resultlen, 0);
   release_passphrase (pw);
   xfree (key);
   if (rc)
@@ -387,7 +372,7 @@ read_and_unprotect (const char *fname)
   if (!key)
     return;
 
-  rc = agent_unprotect (key, (pw=get_passphrase (1)),
+  rc = agent_unprotect (NULL, key, (pw=get_passphrase (1)),
                         protected_at, &result, &resultlen);
   release_passphrase (pw);
   xfree (key);
@@ -554,463 +539,6 @@ show_keygrip (const char *fname)
 }
 
 \f
-static int
-rsa_key_check (struct rsa_secret_key_s *skey)
-{
-  int err = 0;
-  gcry_mpi_t t = gcry_mpi_snew (0);
-  gcry_mpi_t t1 = gcry_mpi_snew (0);
-  gcry_mpi_t t2 = gcry_mpi_snew (0);
-  gcry_mpi_t phi = gcry_mpi_snew (0);
-
-  /* check that n == p * q */
-  gcry_mpi_mul (t, skey->p, skey->q);
-  if (gcry_mpi_cmp( t, skey->n) )
-    {
-      log_error ("RSA oops: n != p * q\n");
-      err++;
-    }
-
-  /* check that p is less than q */
-  if (gcry_mpi_cmp (skey->p, skey->q) > 0)
-    {
-      gcry_mpi_t tmp;
-
-      log_info ("swapping secret primes\n");
-      tmp = gcry_mpi_copy (skey->p);
-      gcry_mpi_set (skey->p, skey->q);
-      gcry_mpi_set (skey->q, tmp);
-      gcry_mpi_release (tmp);
-      /* and must recompute u of course */
-      gcry_mpi_invm (skey->u, skey->p, skey->q);
-    }
-
-  /* check that e divides neither p-1 nor q-1 */
-  gcry_mpi_sub_ui (t, skey->p, 1 );
-  gcry_mpi_div (NULL, t, t, skey->e, 0);
-  if (!gcry_mpi_cmp_ui( t, 0) )
-    {
-      log_error ("RSA oops: e divides p-1\n");
-      err++;
-    }
-  gcry_mpi_sub_ui (t, skey->q, 1);
-  gcry_mpi_div (NULL, t, t, skey->e, 0);
-  if (!gcry_mpi_cmp_ui( t, 0))
-    {
-      log_info ( "RSA oops: e divides q-1\n" );
-      err++;
-    }
-
-  /* check that d is correct. */
-  gcry_mpi_sub_ui (t1, skey->p, 1);
-  gcry_mpi_sub_ui (t2, skey->q, 1);
-  gcry_mpi_mul (phi, t1, t2);
-  gcry_mpi_invm (t, skey->e, phi);
-  if (gcry_mpi_cmp (t, skey->d))
-    { /* no: try universal exponent. */
-      gcry_mpi_gcd (t, t1, t2);
-      gcry_mpi_div (t, NULL, phi, t, 0);
-      gcry_mpi_invm (t, skey->e, t);
-      if (gcry_mpi_cmp (t, skey->d))
-        {
-          log_error ("RSA oops: bad secret exponent\n");
-          err++;
-        }
-    }
-
-  /* check for correctness of u */
-  gcry_mpi_invm (t, skey->p, skey->q);
-  if (gcry_mpi_cmp (t, skey->u))
-    {
-      log_info ( "RSA oops: bad u parameter\n");
-      err++;
-    }
-
-  if (err)
-    log_info ("RSA secret key check failed\n");
-
-  gcry_mpi_release (t);
-  gcry_mpi_release (t1);
-  gcry_mpi_release (t2);
-  gcry_mpi_release (phi);
-
-  return err? -1:0;
-}
-
-
-/* A callback used by p12_parse to return a certificate.  */
-static void
-import_p12_cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
-{
-  struct b64state state;
-  gpg_error_t err, err2;
-
-  (void)opaque;
-
-  err = b64enc_start (&state, stdout, "CERTIFICATE");
-  if (!err)
-    err = b64enc_write (&state, cert, certlen);
-  err2 = b64enc_finish (&state);
-  if (!err)
-    err = err2;
-  if (err)
-    log_error ("error writing armored certificate: %s\n", gpg_strerror (err));
-}
-
-static void
-import_p12_file (const char *fname)
-{
-  char *buf;
-  unsigned char *result;
-  size_t buflen, resultlen, buf_off;
-  int i;
-  int rc;
-  gcry_mpi_t *kparms;
-  struct rsa_secret_key_s sk;
-  gcry_sexp_t s_key;
-  unsigned char *key;
-  unsigned char grip[20];
-  char *pw;
-
-  /* fixme: we should release some stuff on error */
-
-  buf = read_file (fname, &buflen);
-  if (!buf)
-    return;
-
-  /* GnuPG 2.0.4 accidently created binary P12 files with the string
-     "The passphrase is %s encoded.\n\n" prepended to the ASN.1 data.
-     We fix that here.  */
-  if (buflen > 29 && !memcmp (buf, "The passphrase is ", 18))
-    {
-      for (buf_off=18; buf_off < buflen && buf[buf_off] != '\n'; buf_off++)
-        ;
-      buf_off++;
-      if (buf_off < buflen && buf[buf_off] == '\n')
-        buf_off++;
-    }
-  else
-    buf_off = 0;
-
-  kparms = p12_parse ((unsigned char*)buf+buf_off, buflen-buf_off,
-                      (pw=get_passphrase (2)),
-                      import_p12_cert_cb, NULL);
-  release_passphrase (pw);
-  xfree (buf);
-  if (!kparms)
-    {
-      log_error ("error parsing or decrypting the PKCS-12 file\n");
-      return;
-    }
-  for (i=0; kparms[i]; i++)
-    ;
-  if (i != 8)
-    {
-      log_error ("invalid structure of private key\n");
-      return;
-    }
-
-
-/*    print_mpi ("   n", kparms[0]); */
-/*    print_mpi ("   e", kparms[1]); */
-/*    print_mpi ("   d", kparms[2]); */
-/*    print_mpi ("   p", kparms[3]); */
-/*    print_mpi ("   q", kparms[4]); */
-/*    print_mpi ("dmp1", kparms[5]); */
-/*    print_mpi ("dmq1", kparms[6]); */
-/*    print_mpi ("   u", kparms[7]); */
-
-  sk.n = kparms[0];
-  sk.e = kparms[1];
-  sk.d = kparms[2];
-  sk.q = kparms[3];
-  sk.p = kparms[4];
-  sk.u = kparms[7];
-  if (rsa_key_check (&sk))
-    return;
-/*    print_mpi ("   n", sk.n); */
-/*    print_mpi ("   e", sk.e); */
-/*    print_mpi ("   d", sk.d); */
-/*    print_mpi ("   p", sk.p); */
-/*    print_mpi ("   q", sk.q); */
-/*    print_mpi ("   u", sk.u); */
-
-  /* Create an S-expresion from the parameters. */
-  rc = gcry_sexp_build (&s_key, NULL,
-                        "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
-                        sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL);
-  for (i=0; i < 8; i++)
-    gcry_mpi_release (kparms[i]);
-  gcry_free (kparms);
-  if (rc)
-    {
-      log_error ("failed to created S-expression from key: %s\n",
-                 gpg_strerror (rc));
-      return;
-    }
-
-  /* Compute the keygrip. */
-  if (!gcry_pk_get_keygrip (s_key, grip))
-    {
-      log_error ("can't calculate keygrip\n");
-      return;
-    }
-  log_info ("keygrip: ");
-  for (i=0; i < 20; i++)
-    log_printf ("%02X", grip[i]);
-  log_printf ("\n");
-
-  /* Convert to canonical encoding. */
-  buflen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_CANON, NULL, 0);
-  assert (buflen);
-  key = gcry_xmalloc_secure (buflen);
-  buflen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_CANON, key, buflen);
-  assert (buflen);
-  gcry_sexp_release (s_key);
-
-  pw = get_passphrase (4);
-  rc = agent_protect (key, pw, &result, &resultlen);
-  release_passphrase (pw);
-  xfree (key);
-  if (rc)
-    {
-      log_error ("protecting the key failed: %s\n", gpg_strerror (rc));
-      return;
-    }
-
-  if (opt_armor)
-    {
-      char *p = make_advanced (result, resultlen);
-      xfree (result);
-      if (!p)
-        return;
-      result = (unsigned char*)p;
-      resultlen = strlen (p);
-    }
-
-  if (opt_store)
-    store_private_key (grip, result, resultlen, opt_force);
-  else
-    fwrite (result, resultlen, 1, stdout);
-
-  xfree (result);
-}
-
-\f
-
-static gcry_mpi_t *
-sexp_to_kparms (gcry_sexp_t sexp)
-{
-  gcry_sexp_t list, l2;
-  const char *name;
-  const char *s;
-  size_t n;
-  int i, idx;
-  const char *elems;
-  gcry_mpi_t *array;
-
-  list = gcry_sexp_find_token (sexp, "private-key", 0 );
-  if(!list)
-    return NULL;
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
-  list = l2;
-  name = gcry_sexp_nth_data (list, 0, &n);
-  if(!name || n != 3 || memcmp (name, "rsa", 3))
-    {
-      gcry_sexp_release (list);
-      return NULL;
-    }
-
-  /* Parameter names used with RSA. */
-  elems = "nedpqu";
-  array = xcalloc (strlen(elems) + 1, sizeof *array);
-  for (idx=0, s=elems; *s; s++, idx++ )
-    {
-      l2 = gcry_sexp_find_token (list, s, 1);
-      if (!l2)
-        {
-          for (i=0; i<idx; i++)
-            gcry_mpi_release (array[i]);
-          xfree (array);
-          gcry_sexp_release (list);
-          return NULL; /* required parameter not found */
-       }
-      array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
-      gcry_sexp_release (l2);
-      if (!array[idx])
-        {
-          for (i=0; i<idx; i++)
-            gcry_mpi_release (array[i]);
-          xfree (array);
-          gcry_sexp_release (list);
-          return NULL; /* required parameter is invalid */
-       }
-    }
-
-  gcry_sexp_release (list);
-  return array;
-}
-
-
-/* Check whether STRING is a KEYGRIP, i.e has the correct length and
-   does only consist of uppercase hex characters. */
-static int
-is_keygrip (const char *string)
-{
-  int i;
-
-  for(i=0; string[i] && i < 41; i++)
-    if (!strchr("01234567890ABCDEF", string[i]))
-      return 0;
-  return i == 40;
-}
-
-
-static void
-export_p12_file (const char *fname)
-{
-  int rc;
-  gcry_mpi_t kparms[9], *kp;
-  unsigned char *key;
-  size_t keylen;
-  gcry_sexp_t private;
-  struct rsa_secret_key_s sk;
-  int i;
-  unsigned char *cert = NULL;
-  size_t certlen = 0;
-  int keytype;
-  size_t keylen_for_wipe = 0;
-  char *pw;
-
-  if ( is_keygrip (fname) )
-    {
-      char hexgrip[40+4+1];
-      char *p;
-
-      assert (strlen(fname) == 40);
-      strcpy (stpcpy (hexgrip, fname), ".key");
-
-      p = make_filename (opt_homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
-      key = read_key (p);
-      xfree (p);
-    }
-  else
-    key = read_key (fname);
-
-  if (!key)
-    return;
-
-  keytype = agent_private_key_type (key);
-  if (keytype == PRIVATE_KEY_PROTECTED)
-    {
-      unsigned char *tmpkey;
-      size_t tmplen;
-
-      rc = agent_unprotect (key, (pw=get_passphrase (1)),
-                            NULL, &tmpkey, &tmplen);
-      release_passphrase (pw);
-      if (rc)
-        {
-          if (opt_status_msg && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE )
-            log_info ("[PROTECT-TOOL:] bad-passphrase\n");
-          log_error ("unprotecting key `%s' failed: %s\n",
-                     fname, gpg_strerror (rc));
-          xfree (key);
-          return;
-        }
-      xfree (key);
-      key = tmpkey;
-      keylen_for_wipe = tmplen;
-
-      keytype = agent_private_key_type (key);
-    }
-
-  if (keytype == PRIVATE_KEY_SHADOWED)
-    {
-      log_error ("`%s' is a shadowed private key - can't export it\n", fname);
-      wipememory (key, keylen_for_wipe);
-      xfree (key);
-      return;
-    }
-  else if (keytype != PRIVATE_KEY_CLEAR)
-    {
-      log_error ("\%s' is not a private key\n", fname);
-      wipememory (key, keylen_for_wipe);
-      xfree (key);
-      return;
-    }
-
-
-  if (opt_have_cert)
-    {
-      cert = (unsigned char*)read_file ("-", &certlen);
-      if (!cert)
-        {
-          wipememory (key, keylen_for_wipe);
-          xfree (key);
-          return;
-        }
-    }
-
-
-  if (gcry_sexp_new (&private, key, 0, 0))
-    {
-      log_error ("gcry_sexp_new failed\n");
-      wipememory (key, keylen_for_wipe);
-      xfree (key);
-      xfree (cert);
-      return;
-    }
-  wipememory (key, keylen_for_wipe);
-  xfree (key);
-
-  kp = sexp_to_kparms (private);
-  gcry_sexp_release (private);
-  if (!kp)
-    {
-      log_error ("error converting key parameters\n");
-      xfree (cert);
-      return;
-    }
-  sk.n = kp[0];
-  sk.e = kp[1];
-  sk.d = kp[2];
-  sk.p = kp[3];
-  sk.q = kp[4];
-  sk.u = kp[5];
-  xfree (kp);
-
-
-  kparms[0] = sk.n;
-  kparms[1] = sk.e;
-  kparms[2] = sk.d;
-  kparms[3] = sk.q;
-  kparms[4] = sk.p;
-  kparms[5] = gcry_mpi_snew (0);  /* compute d mod (p-1) */
-  gcry_mpi_sub_ui (kparms[5], kparms[3], 1);
-  gcry_mpi_mod (kparms[5], sk.d, kparms[5]);
-  kparms[6] = gcry_mpi_snew (0);  /* compute d mod (q-1) */
-  gcry_mpi_sub_ui (kparms[6], kparms[4], 1);
-  gcry_mpi_mod (kparms[6], sk.d, kparms[6]);
-  kparms[7] = sk.u;
-  kparms[8] = NULL;
-
-  pw = get_passphrase (3);
-  key = p12_build (kparms, cert, certlen, pw, opt_p12_charset, &keylen);
-  release_passphrase (pw);
-  xfree (cert);
-  for (i=0; i < 8; i++)
-    gcry_mpi_release (kparms[i]);
-  if (!key)
-    return;
-
-#ifdef HAVE_DOSISH_SYSTEM
-  setmode ( fileno (stdout) , O_BINARY );
-#endif
-  fwrite (key, keylen, 1, stdout);
-  xfree (key);
-}
 
 
 \f
@@ -1027,7 +555,7 @@ main (int argc, char **argv )
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
     {
@@ -1041,7 +569,6 @@ main (int argc, char **argv )
 
   opt_homedir = default_homedir ();
 
-  opt_session_env = session_env_new ();
 
   pargs.argc = &argc;
   pargs.argv = &argv;
@@ -1062,10 +589,6 @@ main (int argc, char **argv )
         case oShadow: cmd = oShadow; break;
         case oShowShadowInfo: cmd = oShowShadowInfo; break;
         case oShowKeygrip: cmd = oShowKeygrip; break;
-        case oP12Import: cmd = oP12Import; break;
-        case oP12Export: cmd = oP12Export; break;
-        case oP12Charset: opt_p12_charset = pargs.r.ret_str; break;
-
         case oS2Kcalibration: cmd = oS2Kcalibration; break;
 
         case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
@@ -1093,7 +616,7 @@ main (int argc, char **argv )
                                 opt.verbose,
                                 opt_homedir,
                                 opt_agent_program,
-                                NULL, NULL, opt_session_env);
+                                NULL, NULL, NULL);
 
   if (opt_prompt)
     opt_prompt = percent_plus_unescape (opt_prompt, 0);
@@ -1108,10 +631,6 @@ main (int argc, char **argv )
     show_shadow_info (fname);
   else if (cmd == oShowKeygrip)
     show_keygrip (fname);
-  else if (cmd == oP12Import)
-    import_p12_file (fname);
-  else if (cmd == oP12Export)
-    export_p12_file (fname);
   else if (cmd == oS2Kcalibration)
     {
       if (!opt.verbose)
@@ -1129,8 +648,6 @@ void
 agent_exit (int rc)
 {
   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
-  session_env_release (opt_session_env);
-  opt_session_env = NULL;
   exit (rc);
 }
 
@@ -1188,7 +705,8 @@ get_passphrase (int promptno)
                               repeat, repeat, 1, &pw);
   if (err)
     {
-      if (gpg_err_code (err) == GPG_ERR_CANCELED)
+      if (gpg_err_code (err) == GPG_ERR_CANCELED
+          || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
         log_info (_("cancelled\n"));
       else
         log_error (_("error while asking for the passphrase: %s\n"),
@@ -1211,65 +729,14 @@ release_passphrase (char *pw)
     }
 }
 
-static int
-store_private_key (const unsigned char *grip,
-                   const void *buffer, size_t length, int force)
-{
-  char *fname;
-  estream_t fp;
-  char hexgrip[40+4+1];
-
-  bin2hex (grip, 20, hexgrip);
-  strcpy (hexgrip+40, ".key");
-
-  fname = make_filename (opt_homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
-  if (force)
-    fp = es_fopen (fname, "wb");
-  else
-    {
-      if (!access (fname, F_OK))
-      {
-        if (opt_status_msg)
-          log_info ("[PROTECT-TOOL:] secretkey-exists\n");
-        if (opt_no_fail_on_exist)
-          log_info ("secret key file `%s' already exists\n", fname);
-        else
-          log_error ("secret key file `%s' already exists\n", fname);
-        xfree (fname);
-        return opt_no_fail_on_exist? 0 : -1;
-      }
-      /* FWIW: Under Windows Vista the standard fopen in the msvcrt
-         fails if the "x" GNU extension is used.  */
-      fp = es_fopen (fname, "wbx");
-    }
-
-  if (!fp)
-    {
-      log_error ("can't create `%s': %s\n", fname, strerror (errno));
-      xfree (fname);
-      return -1;
-    }
-
-  if (es_fwrite (buffer, length, 1, fp) != 1)
-    {
-      log_error ("error writing `%s': %s\n", fname, strerror (errno));
-      es_fclose (fp);
-      remove (fname);
-      xfree (fname);
-      return -1;
-    }
-  if (es_fclose (fp))
-    {
-      log_error ("error closing `%s': %s\n", fname, strerror (errno));
-      remove (fname);
-      xfree (fname);
-      return -1;
-    }
-  log_info ("secret key stored as `%s'\n", fname);
-
-  if (opt_status_msg)
-    log_info ("[PROTECT-TOOL:] secretkey-stored\n");
 
-  xfree (fname);
-  return 0;
+/* Stub function.  */
+gpg_error_t
+convert_from_openpgp_native (gcry_sexp_t s_pgp, const char *passphrase,
+                             unsigned char **r_key)
+{
+  (void)s_pgp;
+  (void)passphrase;
+  (void)r_key;
+  return gpg_error (GPG_ERR_BUG);
 }
index 2eefd6d..01e72c2 100644 (file)
@@ -1,6 +1,6 @@
 /* protect.c - Un/Protect a secret key
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- *               2003, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 1998-2003, 2007, 2009, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 1998-2003, 2007, 2009, 2011, 2013 Werner Koch
  *
  * This file is part of GnuPG.
  *
 
 #include "agent.h"
 
+#include "cvt-openpgp.h"
 #include "sexp-parse.h"
 
-#define PROT_CIPHER        GCRY_CIPHER_AES
+/* The protection mode for encryption.  The supported modes for
+   decryption are listed in agent_unprotect().  */
+#define PROT_CIPHER        GCRY_CIPHER_AES128
 #define PROT_CIPHER_STRING "aes"
 #define PROT_CIPHER_KEYLEN (128/8)
 
+/* Decode an rfc4880 encoded S2K count.  */
+#define S2K_DECODE_COUNT(_val) ((16ul + ((_val) & 15)) << (((_val) >> 4) + 6))
+
 
 /* A table containing the information needed to create a protected
-   private key */
+   private key */
 static struct {
   const char *algo;
   const char *parmlist;
@@ -80,12 +86,18 @@ hash_passphrase (const char *passphrase, int hashalgo,
                  const unsigned char *s2ksalt, unsigned long s2kcount,
                  unsigned char *key, size_t keylen);
 
+
+\f
 /* Get the process time and store it in DATA.  */
 static void
 calibrate_get_time (struct calibrate_time_s *data)
 {
 #ifdef HAVE_W32_SYSTEM
+# ifdef HAVE_W32CE_SYSTEM
+  GetThreadTimes (GetCurrentThread (),
+# else
   GetProcessTimes (GetCurrentProcess (),
+# endif
                    &data->creation_time, &data->exit_time,
                    &data->kernel_time, &data->user_time);
 #else
@@ -168,7 +180,7 @@ calibrate_s2k_count (void)
   if (opt.verbose)
     {
       ms = calibrate_s2k_count_one (count);
-      log_info ("S2K calibration: %lu iterations for %lums\n", count, ms);
+      log_info ("S2K calibration: %lu -> %lums\n", count, ms);
     }
 
   return count;
@@ -190,16 +202,45 @@ get_standard_s2k_count (void)
 }
 
 
+/* Same as get_standard_s2k_count but return the count in the encoding
+   as described by rfc4880.  */
+unsigned char
+get_standard_s2k_count_rfc4880 (void)
+{
+  unsigned long iterations;
+  unsigned int count;
+  unsigned char result;
+  unsigned char c=0;
+
+  iterations = get_standard_s2k_count ();
+  if (iterations >= 65011712)
+    return 255;
+
+  /* Need count to be in the range 16-31 */
+  for (count=iterations>>6; count>=32; count>>=1)
+    c++;
+
+  result = (c<<4)|(count-16);
+
+  if (S2K_DECODE_COUNT(result) < iterations)
+    result++;
+
+  return result;
+
+}
+
 
 \f
-/* Calculate the MIC for a private key S-Exp. SHA1HASH should point to
-   a 20 byte buffer.  This function is suitable for any algorithms. */
+/* Calculate the MIC for a private key or shared secret S-expression.
+   SHA1HASH should point to a 20 byte buffer.  This function is
+   suitable for all algorithms. */
 static int
 calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
 {
   const unsigned char *hash_begin, *hash_end;
   const unsigned char *s;
   size_t n;
+  int is_shared_secret;
 
   s = plainkey;
   if (*s != '(')
@@ -208,16 +249,23 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
   n = snext (&s);
   if (!n)
     return gpg_error (GPG_ERR_INV_SEXP);
-  if (!smatch (&s, n, "private-key"))
+  if (smatch (&s, n, "private-key"))
+    is_shared_secret = 0;
+  else if (smatch (&s, n, "shared-secret"))
+    is_shared_secret = 1;
+  else
     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
   if (*s != '(')
     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
   hash_begin = s;
-  s++;
-  n = snext (&s);
-  if (!n)
-    return gpg_error (GPG_ERR_INV_SEXP);
-  s += n; /* skip over the algorithm name */
+  if (!is_shared_secret)
+    {
+      s++;
+      n = snext (&s);
+      if (!n)
+        return gpg_error (GPG_ERR_INV_SEXP);
+      s += n; /* Skip the algorithm name.  */
+    }
 
   while (*s == '(')
     {
@@ -268,7 +316,8 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
 static int
 do_encryption (const unsigned char *protbegin, size_t protlen,
                const char *passphrase,  const unsigned char *sha1hash,
-               unsigned char **result, size_t *resultlen)
+               unsigned char **result, size_t *resultlen,
+              unsigned long s2k_count)
 {
   gcry_cipher_hd_t hd;
   const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc";
@@ -327,7 +376,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
         {
           rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
                                 3, iv+2*blklen,
-                                get_standard_s2k_count (), key, keylen);
+                               s2k_count ? s2k_count : get_standard_s2k_count(),
+                               key, keylen);
           if (!rc)
             rc = gcry_cipher_setkey (hd, key, keylen);
           xfree (key);
@@ -370,7 +420,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
   {
     char countbuf[35];
 
-    snprintf (countbuf, sizeof countbuf, "%lu", get_standard_s2k_count ());
+    snprintf (countbuf, sizeof countbuf, "%lu",
+           s2k_count ? s2k_count : get_standard_s2k_count ());
     p = xtryasprintf
       ("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)",
        (int)strlen (modestr), modestr,
@@ -402,7 +453,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
    a valid S-Exp here. */
 int
 agent_protect (const unsigned char *plainkey, const char *passphrase,
-               unsigned char **result, size_t *resultlen)
+               unsigned char **result, size_t *resultlen,
+              unsigned long s2k_count)
 {
   int rc;
   const char *parmlist;
@@ -419,8 +471,9 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
   int depth = 0;
   unsigned char *p;
   gcry_md_hd_t md;
+  int have_curve = 0;
 
-  /* Create an S-expression with the procted-at timestamp.  */
+  /* Create an S-expression with the protected-at timestamp.  */
   memcpy (timestamp_exp, "(12:protected-at15:", 19);
   gnupg_get_isotime (timestamp_exp+19);
   timestamp_exp[19+15] = ')';
@@ -451,6 +504,11 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
   if (!protect_info[infidx].algo)
     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
 
+  /* The parser below is a complete mess: To make it robust for ECC
+     use we should reorder the s-expression to include only what we
+     really need and thus guarantee the right order for saving stuff.
+     This should be done before calling this function and maybe with
+     the help of the new gcry_sexp_extract_param.  */
   parmlist      = protect_info[infidx].parmlist;
   prot_from_idx = protect_info[infidx].prot_from;
   prot_to_idx   = protect_info[infidx].prot_to;
@@ -474,10 +532,19 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
               /* This is a private ECC key but the first parameter is
                  the name of the curve.  We change the parameter list
                  here to the one we expect in this case.  */
+              have_curve = 1;
               parmlist = "?qd";
               prot_from_idx = 2;
               prot_to_idx = 2;
             }
+          else if (n == 5 && !memcmp (s, "flags", 5)
+                   && i == 1 && have_curve)
+            {
+              /* "curve" followed by "flags": Change again.  */
+              parmlist = "??qd";
+              prot_from_idx = 3;
+              prot_to_idx = 3;
+            }
           else
             return gpg_error (GPG_ERR_INV_SEXP);
         }
@@ -498,7 +565,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
   depth--;
   hash_end = s;
   s++;
-  /* skip to the end of the S-exp */
+  /* Skip to the end of the S-expression.  */
   assert (depth == 1);
   rc = sskip (&s, &depth);
   if (rc)
@@ -520,7 +587,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
 
   rc = do_encryption (prot_begin, prot_end - prot_begin + 1,
                       passphrase,  hashvalue,
-                      &protected, &protectedlen);
+                      &protected, &protectedlen, s2k_count);
   if (rc)
     return rc;
 
@@ -558,6 +625,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
   return 0;
 }
 
+
 \f
 /* Do the actual decryption and check the return list for consistency.  */
 static int
@@ -565,6 +633,7 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
                const char *passphrase,
                const unsigned char *s2ksalt, unsigned long s2kcount,
                const unsigned char *iv, size_t ivlen,
+               int prot_cipher, int prot_cipher_keylen,
                unsigned char **result)
 {
   int rc = 0;
@@ -573,11 +642,11 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
   unsigned char *outbuf;
   size_t reallen;
 
-  blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER);
+  blklen = gcry_cipher_get_algo_blklen (prot_cipher);
   if (protectedlen < 4 || (protectedlen%blklen))
     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
 
-  rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
+  rc = gcry_cipher_open (&hd, prot_cipher, GCRY_CIPHER_MODE_CBC,
                          GCRY_CIPHER_SECURE);
   if (rc)
     return rc;
@@ -590,17 +659,16 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
   if (!rc)
     {
       unsigned char *key;
-      size_t keylen = PROT_CIPHER_KEYLEN;
 
-      key = gcry_malloc_secure (keylen);
+      key = gcry_malloc_secure (prot_cipher_keylen);
       if (!key)
         rc = out_of_core ();
       else
         {
           rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
-                                3, s2ksalt, s2kcount, key, keylen);
+                                3, s2ksalt, s2kcount, key, prot_cipher_keylen);
           if (!rc)
-            rc = gcry_cipher_setkey (hd, key, keylen);
+            rc = gcry_cipher_setkey (hd, key, prot_cipher_keylen);
           xfree (key);
         }
     }
@@ -786,12 +854,22 @@ merge_lists (const unsigned char *protectedkey,
 
 /* Unprotect the key encoded in canonical format.  We assume a valid
    S-Exp here.  If a protected-at item is available, its value will
-   be stored at protocted_at unless this is NULL.  */
+   be stored at protected_at unless this is NULL.  */
 int
-agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
+agent_unprotect (ctrl_t ctrl,
+                 const unsigned char *protectedkey, const char *passphrase,
                  gnupg_isotime_t protected_at,
                  unsigned char **result, size_t *resultlen)
 {
+  static struct {
+    const char *name; /* Name of the protection method. */
+    int algo;         /* (A zero indicates the "openpgp-native" hack.)  */
+    int keylen;       /* Used key length in bytes.  */
+  } algotable[] = {
+    { "openpgp-s2k3-sha1-aes-cbc",    GCRY_CIPHER_AES128, (128/8)},
+    { "openpgp-s2k3-sha1-aes256-cbc", GCRY_CIPHER_AES256, (256/8)},
+    { "openpgp-native", 0, 0 }
+  };
   int rc;
   const unsigned char *s;
   const unsigned char *protect_list;
@@ -801,8 +879,9 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
   const unsigned char *s2ksalt;
   unsigned long s2kcount;
   const unsigned char *iv;
+  int prot_cipher, prot_cipher_keylen;
   const unsigned char *prot_begin;
-  unsigned char *cleartext = NULL; /* Just to avoid gcc warning.  */
+  unsigned char *cleartext;
   unsigned char *final;
   size_t finallen;
   size_t cutoff, cutlen;
@@ -891,8 +970,40 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
   n = snext (&s);
   if (!n)
     return gpg_error (GPG_ERR_INV_SEXP);
-  if (!smatch (&s, n, "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"))
+
+  /* Lookup the protection algo.  */
+  prot_cipher = 0;        /* (avoid gcc warning) */
+  prot_cipher_keylen = 0; /* (avoid gcc warning) */
+  for (i= 0; i < DIM (algotable); i++)
+    if (smatch (&s, n, algotable[i].name))
+      {
+        prot_cipher = algotable[i].algo;
+        prot_cipher_keylen = algotable[i].keylen;
+        break;
+      }
+  if (i == DIM (algotable))
     return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION);
+
+  if (!prot_cipher)  /* This is "openpgp-native".  */
+    {
+      gcry_sexp_t s_prot_begin;
+
+      rc = gcry_sexp_sscan (&s_prot_begin, NULL,
+                            prot_begin,
+                            gcry_sexp_canon_len (prot_begin, 0,NULL,NULL));
+      if (rc)
+        return rc;
+
+      rc = convert_from_openpgp_native (ctrl, s_prot_begin, passphrase, &final);
+      gcry_sexp_release (s_prot_begin);
+      if (!rc)
+        {
+          *result = final;
+          *resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL);
+        }
+      return rc;
+    }
+
   if (*s != '(' || s[1] != '(')
     return gpg_error (GPG_ERR_INV_SEXP);
   s += 2;
@@ -935,7 +1046,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
   s++; /* skip list end */
 
   n = snext (&s);
-  if (n != 16) /* Wrong blocksize for IV (we support only aes-128). */
+  if (n != 16) /* Wrong blocksize for IV (we support only 128 bit). */
     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
   iv = s;
   s += n;
@@ -946,9 +1057,10 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
   if (!n)
     return gpg_error (GPG_ERR_INV_SEXP);
 
+  cleartext = NULL; /* Avoid cc warning. */
   rc = do_decryption (s, n,
                       passphrase, s2ksalt, s2kcount,
-                      iv, 16,
+                      iv, 16, prot_cipher, prot_cipher_keylen,
                       &cleartext);
   if (rc)
     return rc;
@@ -972,7 +1084,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
       xfree (final);
       return rc;
     }
-  /* Now remove tha part which is included in the MIC but should not
+  /* Now remove the part which is included in the MIC but should not
      go into the final thing.  */
   if (cutlen)
     {
@@ -1028,70 +1140,30 @@ hash_passphrase (const char *passphrase, int hashalgo,
                  unsigned long s2kcount,
                  unsigned char *key, size_t keylen)
 {
-  int rc;
-  gcry_md_hd_t md;
-  int pass, i;
-  int used = 0;
-  int pwlen = strlen (passphrase);
-
-  if ( (s2kmode != 0 && s2kmode != 1 && s2kmode != 3)
-      || !hashalgo || !keylen || !key || !passphrase)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt)
-    return gpg_error (GPG_ERR_INV_VALUE);
-
-  rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE);
-  if (rc)
-    return rc;
-
-  for (pass=0; used < keylen; pass++)
-    {
-      if (pass)
-        {
-          gcry_md_reset (md);
-          for (i=0; i < pass; i++) /* preset the hash context */
-            gcry_md_putc (md, 0);
-       }
-
-      if (s2kmode == 1 || s2kmode == 3)
-        {
-          int len2 = pwlen + 8;
-          unsigned long count = len2;
+  /* The key derive function does not support a zero length string for
+     the passphrase in the S2K modes.  Return a better suited error
+     code than GPG_ERR_INV_DATA.  */
+  if (!passphrase || !*passphrase)
+    return gpg_error (GPG_ERR_NO_PASSPHRASE);
+  return gcry_kdf_derive (passphrase, strlen (passphrase),
+                          s2kmode == 3? GCRY_KDF_ITERSALTED_S2K :
+                          s2kmode == 1? GCRY_KDF_SALTED_S2K :
+                          s2kmode == 0? GCRY_KDF_SIMPLE_S2K : GCRY_KDF_NONE,
+                          hashalgo, s2ksalt, 8, s2kcount,
+                          keylen, key);
+}
 
-          if (s2kmode == 3)
-            {
-              count = s2kcount;
-              if (count < len2)
-                count = len2;
-            }
 
-          while (count > len2)
-            {
-              gcry_md_write (md, s2ksalt, 8);
-              gcry_md_write (md, passphrase, pwlen);
-              count -= len2;
-            }
-          if (count < 8)
-            gcry_md_write (md, s2ksalt, count);
-          else
-            {
-              gcry_md_write (md, s2ksalt, 8);
-              count -= 8;
-              gcry_md_write (md, passphrase, count);
-            }
-        }
-      else
-        gcry_md_write (md, passphrase, pwlen);
-
-      gcry_md_final (md);
-      i = gcry_md_get_algo_dlen (hashalgo);
-      if (i > keylen - used)
-        i = keylen - used;
-      memcpy  (key+used, gcry_md_read (md, hashalgo), i);
-      used += i;
-    }
-  gcry_md_close(md);
-  return 0;
+gpg_error_t
+s2k_hash_passphrase (const char *passphrase, int hashalgo,
+                     int s2kmode,
+                     const unsigned char *s2ksalt,
+                     unsigned int s2kcount,
+                     unsigned char *key, size_t keylen)
+{
+  return hash_passphrase (passphrase, hashalgo, s2kmode, s2ksalt,
+                          S2K_DECODE_COUNT (s2kcount),
+                          key, keylen);
 }
 
 
@@ -1287,7 +1359,7 @@ agent_get_shadow_info (const unsigned char *shadowkey,
    required, NULL may be passed for them.  */
 gpg_error_t
 parse_shadow_info (const unsigned char *shadow_info,
-                   char **r_hexsn, char **r_idstr)
+                   char **r_hexsn, char **r_idstr, int *r_pinlen)
 {
   const unsigned char *s;
   size_t n;
@@ -1296,6 +1368,8 @@ parse_shadow_info (const unsigned char *shadow_info,
     *r_hexsn = NULL;
   if (r_idstr)
     *r_idstr = NULL;
+  if (r_pinlen)
+    *r_pinlen = 0;
 
   s = shadow_info;
   if (*s != '(')
@@ -1340,6 +1414,34 @@ parse_shadow_info (const unsigned char *shadow_info,
       (*r_idstr)[n] = 0;
     }
 
+  /* Parse the optional PINLEN.  */
+  n = snext (&s);
+  if (!n)
+    return 0;
+
+  if (r_pinlen)
+    {
+      char *tmpstr = xtrymalloc (n+1);
+      if (!tmpstr)
+        {
+          if (r_hexsn)
+            {
+              xfree (*r_hexsn);
+              *r_hexsn = NULL;
+            }
+          if (r_idstr)
+            {
+              xfree (*r_idstr);
+              *r_idstr = NULL;
+            }
+          return gpg_error_from_syserror ();
+        }
+      memcpy (tmpstr, s, n);
+      tmpstr[n] = 0;
+
+      *r_pinlen = (int)strtol (tmpstr, NULL, 10);
+      xfree (tmpstr);
+    }
+
   return 0;
 }
-
index 16ff7d7..9096cb2 100644 (file)
@@ -107,7 +107,7 @@ test_agent_protect (void)
       "\xA4\x44\x3B\xA5\x3A\x52\xFC\xA8\x17\x3D\xE6\xE8\x5B\x42\xF9\x78\x3D\x4A\x78\x17"
       "\xD0\x68\x0B\x29\x29\x00"
     };
-  /* This RSA key is the `e' value.  */
+  /* This RSA key is the 'e' value.  */
   struct key_spec key_rsa_bogus_1 =
     {
       "\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28\x33\x3A\x72\x73"
@@ -155,6 +155,7 @@ test_agent_protect (void)
       "\x64\x73\x61\x29\x29"
     };
 
+
   struct
   {
     const char *key;
@@ -194,7 +195,7 @@ test_agent_protect (void)
     {
       ret = agent_protect ((const unsigned char*)specs[i].key,
                            specs[i].passphrase,
-                          &specs[i].result, &specs[i].resultlen);
+                          &specs[i].result, &specs[i].resultlen, 0);
       if (gpg_err_code (ret) != specs[i].ret_expected)
        {
          printf ("agent_protect(%d) returned '%i/%s'; expected '%i/%s'\n",
@@ -309,6 +310,13 @@ test_agent_get_shadow_info (void)
 }
 
 
+static void
+test_agent_protect_shared_secret (void)
+{
+
+}
+
+
 
 
 int
@@ -325,6 +333,18 @@ main (int argc, char **argv)
   test_make_shadow_info ();
   test_agent_shadow_key ();
   test_agent_get_shadow_info ();
+  test_agent_protect_shared_secret ();
 
   return 0;
 }
+
+/* Stub function.  */
+gpg_error_t
+convert_from_openpgp_native (gcry_sexp_t s_pgp, const char *passphrase,
+                             unsigned char **r_key)
+{
+  (void)s_pgp;
+  (void)passphrase;
+  (void)r_key;
+  return gpg_error (GPG_ERR_BUG);
+}
index ef9c661..e8f8fff 100644 (file)
@@ -1,5 +1,6 @@
 /* trustlist.c - Maintain the list of trusted keys
- * Copyright (C) 2002, 2004, 2006, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2004, 2006, 2007, 2009,
+ *               2012 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <assert.h>
 #include <unistd.h>
 #include <sys/stat.h>
-#include <pth.h>
+#include <npth.h>
 
 #include "agent.h"
 #include <assuan.h> /* fixme: need a way to avoid assuan calls here */
 #include "i18n.h"
-#include "estream.h"
 
 
 /* A structure to store the information from the trust file. */
@@ -51,11 +51,10 @@ struct trustitem_s
 typedef struct trustitem_s trustitem_t;
 
 /* Malloced table and its allocated size with all trust items. */
-static trustitem_t *trusttable; 
-static size_t trusttablesize; 
+static trustitem_t *trusttable;
+static size_t trusttablesize;
 /* A mutex used to protect the table. */
-static pth_mutex_t trusttable_lock;
-
+static npth_mutex_t trusttable_lock;
 
 
 static const char headerblurb[] =
@@ -82,11 +81,13 @@ void
 initialize_module_trustlist (void)
 {
   static int initialized;
+  int err;
 
   if (!initialized)
     {
-      if (!pth_mutex_init (&trusttable_lock))
-        log_fatal ("error initializing mutex: %s\n", strerror (errno));
+      err = npth_mutex_init (&trusttable_lock, NULL);
+      if (err)
+        log_fatal ("failed to init mutex in %s: %s\n", __FILE__,strerror (err));
       initialized = 1;
     }
 }
@@ -97,69 +98,89 @@ initialize_module_trustlist (void)
 static void
 lock_trusttable (void)
 {
-  if (!pth_mutex_acquire (&trusttable_lock, 0, NULL))
-    log_fatal ("failed to acquire mutex in %s\n", __FILE__);
+  int err;
+
+  err = npth_mutex_lock (&trusttable_lock);
+  if (err)
+    log_fatal ("failed to acquire mutex in %s: %s\n", __FILE__, strerror (err));
 }
 
+
 static void
 unlock_trusttable (void)
 {
-  if (!pth_mutex_release (&trusttable_lock))
-    log_fatal ("failed to release mutex in %s\n", __FILE__);
+  int err;
+
+  err = npth_mutex_unlock (&trusttable_lock);
+  if (err)
+    log_fatal ("failed to release mutex in %s: %s\n", __FILE__, strerror (err));
 }
 
 
+/* Clear the trusttable.  The caller needs to make sure that the
+   trusttable is locked.  */
+static inline void
+clear_trusttable (void)
+{
+  xfree (trusttable);
+  trusttable = NULL;
+  trusttablesize = 0;
+}
+
 
 static gpg_error_t
 read_one_trustfile (const char *fname, int allow_include,
-                    trustitem_t **addr_of_table, 
+                    trustitem_t **addr_of_table,
                     size_t *addr_of_tablesize,
                     int *addr_of_tableidx)
 {
   gpg_error_t err = 0;
-  FILE *fp;
+  estream_t fp;
   int n, c;
   char *p, line[256];
   trustitem_t *table, *ti;
   int tableidx;
   size_t tablesize;
   int lnr = 0;
-  
+
   table = *addr_of_table;
   tablesize = *addr_of_tablesize;
   tableidx = *addr_of_tableidx;
 
-  fp = fopen (fname, "r");
+  fp = es_fopen (fname, "r");
   if (!fp)
     {
       err = gpg_error_from_syserror ();
-      log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
+      log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err));
       goto leave;
     }
 
-  while (fgets (line, DIM(line)-1, fp))
+  while (es_fgets (line, DIM(line)-1, fp))
     {
       lnr++;
-      
-      if (!*line || line[strlen(line)-1] != '\n')
+
+      n = strlen (line);
+      if (!n || line[n-1] != '\n')
         {
           /* Eat until end of line. */
-          while ( (c=getc (fp)) != EOF && c != '\n')
+          while ( (c=es_getc (fp)) != EOF && c != '\n')
             ;
           err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
                            : GPG_ERR_INCOMPLETE_LINE);
-          log_error (_("file `%s', line %d: %s\n"),
+          log_error (_("file '%s', line %d: %s\n"),
                      fname, lnr, gpg_strerror (err));
           continue;
         }
-      line[strlen(line)-1] = 0; /* Chop the LF. */
-      
+      line[--n] = 0; /* Chop the LF. */
+      if (n && line[n-1] == '\r')
+        line[--n] = 0; /* Chop an optional CR. */
+
       /* Allow for empty lines and spaces */
       for (p=line; spacep (p); p++)
         ;
       if (!*p || *p == '#')
         continue;
-  
+
       if (!strncmp (p, "include-default", 15)
           && (!p[15] || spacep (p+15)))
         {
@@ -168,7 +189,7 @@ read_one_trustfile (const char *fname, int allow_include,
 
           if (!allow_include)
             {
-              log_error (_("statement \"%s\" ignored in `%s', line %d\n"),
+              log_error (_("statement \"%s\" ignored in '%s', line %d\n"),
                          "include-default", fname, lnr);
               continue;
             }
@@ -176,13 +197,13 @@ read_one_trustfile (const char *fname, int allow_include,
 
           etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
           if ( !strcmp (etcname, fname) ) /* Same file. */
-            log_info (_("statement \"%s\" ignored in `%s', line %d\n"),
+            log_info (_("statement \"%s\" ignored in '%s', line %d\n"),
                       "include-default", fname, lnr);
           else if ( access (etcname, F_OK) && errno == ENOENT )
             {
               /* A non existent system trustlist is not an error.
                  Just print a note. */
-              log_info (_("system trustlist `%s' not available\n"), etcname);
+              log_info (_("system trustlist '%s' not available\n"), etcname);
             }
           else
             {
@@ -192,7 +213,7 @@ read_one_trustfile (const char *fname, int allow_include,
                 err = err2;
             }
           xfree (etcname);
-          
+
           continue;
         }
 
@@ -200,7 +221,7 @@ read_one_trustfile (const char *fname, int allow_include,
         {
           trustitem_t *tmp;
           size_t tmplen;
-          
+
           tmplen = tablesize + 20;
           tmp = xtryrealloc (table, tmplen * sizeof *table);
           if (!tmp)
@@ -226,14 +247,14 @@ read_one_trustfile (const char *fname, int allow_include,
       n = hexcolon2bin (p, ti->fpr, 20);
       if (n < 0)
         {
-          log_error (_("bad fingerprint in `%s', line %d\n"), fname, lnr);
-          err = gpg_error (GPG_ERR_BAD_DATA); 
+          log_error (_("bad fingerprint in '%s', line %d\n"), fname, lnr);
+          err = gpg_error (GPG_ERR_BAD_DATA);
           continue;
         }
       p += n;
       for (; spacep (p); p++)
         ;
-      
+
       /* Process the first flag which needs to be the first for
          backward compatibility. */
       if (!*p || *p == '*' )
@@ -251,14 +272,14 @@ read_one_trustfile (const char *fname, int allow_include,
         }
       else
         {
-          log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
+          log_error (_("invalid keyflag in '%s', line %d\n"), fname, lnr);
           err = gpg_error (GPG_ERR_BAD_DATA);
           continue;
         }
       p++;
       if ( *p && !spacep (p) )
         {
-          log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
+          log_error (_("invalid keyflag in '%s', line %d\n"), fname, lnr);
           err = gpg_error (GPG_ERR_BAD_DATA);
           continue;
         }
@@ -274,7 +295,7 @@ read_one_trustfile (const char *fname, int allow_include,
           if (p[n] == '=')
             {
               log_error ("assigning a value to a flag is not yet supported; "
-                         "in `%s', line %d\n", fname, lnr);
+                         "in '%s', line %d\n", fname, lnr);
               err = gpg_error (GPG_ERR_BAD_DATA);
               p++;
             }
@@ -283,22 +304,21 @@ read_one_trustfile (const char *fname, int allow_include,
           else if (n == 2 && !memcmp (p, "cm", 2))
             ti->flags.cm = 1;
           else
-            log_error ("flag `%.*s' in `%s', line %d ignored\n",
+            log_error ("flag '%.*s' in '%s', line %d ignored\n",
                        n, p, fname, lnr);
           p += n;
         }
       tableidx++;
     }
-  if ( !err && !feof (fp) )
+  if ( !err && !es_feof (fp) )
     {
       err = gpg_error_from_syserror ();
-      log_error (_("error reading `%s', line %d: %s\n"),
+      log_error (_("error reading '%s', line %d: %s\n"),
                  fname, lnr, gpg_strerror (err));
     }
 
  leave:
-  if (fp)
-    fclose (fp);
+  es_fclose (fp);
   *addr_of_table = table;
   *addr_of_tablesize = tablesize;
   *addr_of_tableidx = tableidx;
@@ -306,7 +326,8 @@ read_one_trustfile (const char *fname, int allow_include,
 }
 
 
-/* Read the trust files and update the global table on success.  */
+/* Read the trust files and update the global table on success.  The
+   trusttable is assumed to be locked. */
 static gpg_error_t
 read_trustfiles (void)
 {
@@ -331,7 +352,7 @@ read_trustfiles (void)
       else
         {
           err = gpg_error_from_syserror ();
-          log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
+          log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err));
         }
       xfree (fname);
       fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
@@ -347,11 +368,7 @@ read_trustfiles (void)
       if (gpg_err_code (err) == GPG_ERR_ENOENT)
         {
           /* Take a missing trustlist as an empty one.  */
-          lock_trusttable ();
-          xfree (trusttable);
-          trusttable = NULL;
-          trusttablesize = 0;
-          unlock_trusttable ();
+          clear_trusttable ();
           err = 0;
         }
       return err;
@@ -366,22 +383,23 @@ read_trustfiles (void)
       return err;
     }
 
-  lock_trusttable ();
+  /* Replace the trusttable.  */
   xfree (trusttable);
   trusttable = ti;
   trusttablesize = tableidx;
-  unlock_trusttable ();
   return 0;
 }
 
 
-
 /* Check whether the given fpr is in our trustdb.  We expect FPR to be
-   an all uppercase hexstring of 40 characters. */
-gpg_error_t 
-agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled)
+   an all uppercase hexstring of 40 characters.  If ALREADY_LOCKED is
+   true the function assumes that the trusttable is already locked. */
+static gpg_error_t
+istrusted_internal (ctrl_t ctrl, const char *fpr, int *r_disabled,
+                    int already_locked)
 {
   gpg_error_t err;
+  int locked = already_locked;
   trustitem_t *ti;
   size_t len;
   unsigned char fprbin[20];
@@ -390,7 +408,16 @@ agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled)
     *r_disabled = 0;
 
   if ( hexcolon2bin (fpr, fprbin, 20) < 0 )
-    return gpg_error (GPG_ERR_INV_VALUE);
+    {
+      err = gpg_error (GPG_ERR_INV_VALUE);
+      goto leave;
+    }
+
+  if (!already_locked)
+    {
+      lock_trusttable ();
+      locked = 1;
+    }
 
   if (!trusttable)
     {
@@ -398,7 +425,7 @@ agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled)
       if (err)
         {
           log_error (_("error reading list of trusted root certificates\n"));
-          return err;
+          goto leave;
         }
     }
 
@@ -410,31 +437,48 @@ agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled)
             if (ti->flags.disabled && r_disabled)
               *r_disabled = 1;
 
-            if (ti->flags.relax)
+            /* Print status messages only if we have not been called
+               in a locked state.  */
+            if (already_locked)
+              ;
+            else if (ti->flags.relax)
               {
-                err = agent_write_status (ctrl,
-                                          "TRUSTLISTFLAG", "relax", 
-                                          NULL);
-                if (err)
-                  return err;
+                unlock_trusttable ();
+                locked = 0;
+                err = agent_write_status (ctrl, "TRUSTLISTFLAG", "relax", NULL);
               }
             else if (ti->flags.cm)
               {
-                err = agent_write_status (ctrl,
-                                          "TRUSTLISTFLAG", "cm", 
-                                          NULL);
-                if (err)
-                  return err;
+                unlock_trusttable ();
+                locked = 0;
+                err = agent_write_status (ctrl, "TRUSTLISTFLAG", "cm", NULL);
               }
-            return ti->flags.disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
+
+            if (!err)
+              err = ti->flags.disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
+            goto leave;
           }
     }
-  return gpg_error (GPG_ERR_NOT_TRUSTED);
+  err = gpg_error (GPG_ERR_NOT_TRUSTED);
+
+ leave:
+  if (locked && !already_locked)
+    unlock_trusttable ();
+  return err;
+}
+
+
+/* Check whether the given fpr is in our trustdb.  We expect FPR to be
+   an all uppercase hexstring of 40 characters.  */
+gpg_error_t
+agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled)
+{
+  return istrusted_internal (ctrl, fpr, r_disabled, 0);
 }
 
 
 /* Write all trust entries to FP. */
-gpg_error_t 
+gpg_error_t
 agent_listtrusted (void *assuan_context)
 {
   trustitem_t *ti;
@@ -442,11 +486,13 @@ agent_listtrusted (void *assuan_context)
   gpg_error_t err;
   size_t len;
 
+  lock_trusttable ();
   if (!trusttable)
     {
       err = read_trustfiles ();
       if (err)
         {
+          unlock_trusttable ();
           log_error (_("error reading list of trusted root certificates\n"));
           return err;
         }
@@ -454,9 +500,6 @@ agent_listtrusted (void *assuan_context)
 
   if (trusttable)
     {
-      /* We need to lock the table because the scheduler may interrupt
-         assuan_send_data and an other thread may then re-read the table. */
-      lock_trusttable ();
       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
         {
           if (ti->flags.disabled)
@@ -469,9 +512,9 @@ agent_listtrusted (void *assuan_context)
           assuan_send_data (assuan_context, key, 43);
           assuan_send_data (assuan_context, NULL, 0); /* flush */
         }
-      unlock_trusttable ();
     }
 
+  unlock_trusttable ();
   return 0;
 }
 
@@ -531,7 +574,7 @@ reformat_name (const char *name, const char *replstring)
       count++;
   newname = xtrymalloc (strlen (name) + count*replstringlen + 1);
   if (!newname)
-    return NULL; 
+    return NULL;
   for (s=name+1, d=newname; *s; s++)
     if (*s == '/')
       d = stpcpy (d, replstring);
@@ -544,10 +587,10 @@ reformat_name (const char *name, const char *replstring)
 
 /* Insert the given fpr into our trustdb.  We expect FPR to be an all
    uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
-   This function does first check whether that key has already been put
-   into the trustdb and returns success in this case.  Before a FPR
-   actually gets inserted, the user is asked by means of the Pinentry
-   whether this is actual want he wants to do.  */
+   This function does first check whether that key has already been
+   put into the trustdb and returns success in this case.  Before a
+   FPR actually gets inserted, the user is asked by means of the
+   Pinentry whether this is actual what he wants to do.  */
 gpg_error_t
 agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
 {
@@ -570,7 +613,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
     {
       xfree (fname);
       return gpg_error (GPG_ERR_EPERM);
-    }    
+    }
   xfree (fname);
 
   if (!agent_istrusted (ctrl, fpr, &is_disabled))
@@ -578,7 +621,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
       return 0; /* We already got this fingerprint.  Silently return
                    success. */
     }
-  
+
   /* This feature must explicitly been enabled. */
   if (!opt.allow_mark_trusted)
     return gpg_error (GPG_ERR_NOT_SUPPORTED);
@@ -628,7 +671,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
       xfree (nameformatted);
       return err;
     }
-    
+
 
   fprformatted = insert_colons (fpr);
   if (!fprformatted)
@@ -641,7 +684,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
      fingerprint of course.  */
   if (yes_i_trust)
     {
-      desc = xtryasprintf 
+      desc = xtryasprintf
         (
          /* TRANSLATORS: This prompt is shown by the Pinentry and has
             one special property: A "%%0A" is used by Pinentry to
@@ -661,7 +704,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
           xfree (nameformatted);
           return out_of_core ();
         }
-      
+
       /* TRANSLATORS: "Correct" is the label of a button and intended
          to be hit if the fingerprint matches the one of the CA.  The
          other button is "the default "Cancel" of the Pinentry. */
@@ -681,23 +724,23 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
   /* Now check again to avoid duplicates.  We take the lock to make
      sure that nobody else plays with our file and force a reread.  */
   lock_trusttable ();
-  agent_reload_trustlist ();
-  if (!agent_istrusted (ctrl, fpr, &is_disabled) || is_disabled)
+  clear_trusttable ();
+  if (!istrusted_internal (ctrl, fpr, &is_disabled, 1) || is_disabled)
     {
       unlock_trusttable ();
       xfree (fprformatted);
       xfree (nameformatted);
-      return is_disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0; 
+      return is_disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
     }
 
   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
   if ( access (fname, F_OK) && errno == ENOENT)
     {
-      fp = es_fopen (fname, "wx");
+      fp = es_fopen (fname, "wx,mode=-rw-r");
       if (!fp)
         {
           err = gpg_error_from_syserror ();
-          log_error ("can't create `%s': %s\n", fname, gpg_strerror (err));
+          log_error ("can't create '%s': %s\n", fname, gpg_strerror (err));
           xfree (fname);
           unlock_trusttable ();
           xfree (fprformatted);
@@ -707,11 +750,11 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
       es_fputs (headerblurb, fp);
       es_fclose (fp);
     }
-  fp = es_fopen (fname, "a+");
+  fp = es_fopen (fname, "a+,mode=-rw-r");
   if (!fp)
     {
       err = gpg_error_from_syserror ();
-      log_error ("can't open `%s': %s\n", fname, gpg_strerror (err));
+      log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
       xfree (fname);
       unlock_trusttable ();
       xfree (fprformatted);
@@ -735,15 +778,17 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
               flag == 'S'? " relax":"");
   if (es_ferror (fp))
     err = gpg_error_from_syserror ();
-  
+
   if (es_fclose (fp))
     err = gpg_error_from_syserror ();
 
-  agent_reload_trustlist ();
+  clear_trusttable ();
   xfree (fname);
   unlock_trusttable ();
   xfree (fprformatted);
   xfree (nameformatted);
+  if (!err)
+    bump_key_eventcounter ();
   return err;
 }
 
@@ -756,9 +801,7 @@ agent_reload_trustlist (void)
   /* All we need to do is to delete the trusttable.  At the next
      access it will get re-read. */
   lock_trusttable ();
-  xfree (trusttable);
-  trusttable = NULL;
-  trusttablesize = 0;
+  clear_trusttable ();
   unlock_trusttable ();
   bump_key_eventcounter ();
 }
index 9fc3abb..5ccbb5e 100644 (file)
@@ -67,12 +67,12 @@ build_argv (char *cmdline_arg, int reserved)
         {
           argc++;
           /* Skip the remaining spaces.  */
-          while (*s==' ' || *s=='\t') 
+          while (*s==' ' || *s=='\t')
             s++;
           if (!*s)
             break;
           bs_count = 0;
-        } 
+        }
       else if (*s=='\\')
         {
           bs_count++;
@@ -84,7 +84,7 @@ build_argv (char *cmdline_arg, int reserved)
           in_quotes = !in_quotes;
           bs_count=0;
           s++;
-        } 
+        }
       else /* A regular character. */
         {
           bs_count = 0;
@@ -113,20 +113,20 @@ build_argv (char *cmdline_arg, int reserved)
           argv[argc++] = arg;
 
           /* Skip the remaining spaces. */
-          do 
+          do
             s++;
           while (*s==' ' || *s=='\t');
 
           /* Start with a new argument */
           arg = d = s;
           bs_count = 0;
-        } 
-      else if (*s=='\\') 
+        }
+      else if (*s=='\\')
         {
           *d++ = *s++;
           bs_count++;
-        } 
-      else if (*s=='\"') 
+        }
+      else if (*s=='\"')
         {
           if ( !(bs_count & 1) )
             {
@@ -137,7 +137,7 @@ build_argv (char *cmdline_arg, int reserved)
               s++;
               in_quotes = !in_quotes;
             }
-          else 
+          else
             {
               /* Preceded by an odd number of backslashes, this is
                  half that number of backslashes followed by a '\"'.  */
@@ -146,7 +146,7 @@ build_argv (char *cmdline_arg, int reserved)
               s++;
             }
           bs_count=0;
-        } 
+        }
       else /* A regular character. */
         {
           *d++ = *s++;
@@ -167,9 +167,9 @@ build_argv (char *cmdline_arg, int reserved)
 
 
 /* Our window message processing function.  */
-static LRESULT CALLBACK 
+static LRESULT CALLBACK
 wndw_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
-{              
+{
 
   switch (msg)
     {
@@ -233,14 +233,14 @@ handle_taskbar (void *ctx)
   nid.hWnd = glob_hwnd;
   nid.uID = 1;
   nid.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (1));
-  mem2str (nid.szTip, "GnuPG Agent version "PACKAGE_VERSION,
+  mem2str (nid.szTip, GPG_AGENT_NAME " version "PACKAGE_VERSION,
            sizeof nid.szTip);
   Shell_NotifyIcon (NIM_ADD, &nid);
   DestroyIcon (nid.hIcon);
 
   fprintf (stderr, "%s: enter\n", __func__);
-  while ( (rc=GetMessage (&msg, hwnd,  0, 0)) ) 
-    { 
+  while ( (rc=GetMessage (&msg, hwnd,  0, 0)) )
+    {
       if (rc == -1)
         {
           log_error ("getMessage failed: %s\n", w32_strerror (-1));
index b868e7c..4b48560 100644 (file)
@@ -25,7 +25,8 @@ AM_CPPFLAGS += -DGNUPG_BINDIR="\"$(bindir)\""            \
                -DGNUPG_LIBEXECDIR="\"$(libexecdir)\""    \
                -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\""  \
                -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \
-               -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\""
+               -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" \
+               -DGNUPG_LOCALSTATEDIR="\"$(localstatedir)\""
 endif
 
 
@@ -47,6 +48,22 @@ endif
 if GNUPG_PROTECT_TOOL_PGM
 AM_CPPFLAGS += -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\""
 endif
+if GNUPG_DIRMNGR_LDAP_PGM
+AM_CPPFLAGS += -DGNUPG_DEFAULT_DIRMNGR_LDAP="\"@GNUPG_DIRMNGR_LDAP_PGM@\""
+endif
+
+# Under Windows we use LockFileEx.  WindowsCE provides this only on
+# the WindowsMobile 6 platform and thus we need to use the coredll6
+# import library.  We also want to use a stacksize of 256k instead of
+# the 2MB which is the default with cegcc.  256k is the largest stack
+# we use with pth.
+if HAVE_W32CE_SYSTEM
+extra_sys_libs = -lcoredll6
+extra_bin_ldflags = -Wl,--stack=0x40000
+else
+extra_sys_libs =
+extra_bin_ldflags =
+endif
 
 if HAVE_W32_SYSTEM
 .rc.o:
@@ -58,4 +75,5 @@ resource_objs =
 # Convenience macros
 libcommon = ../common/libcommon.a
 libcommonpth = ../common/libcommonpth.a
-
+libcommontls = ../common/libcommontls.a
+libcommontlsnpth = ../common/libcommontlsnpth.a
diff --git a/announce.txt b/announce.txt
deleted file mode 100644 (file)
index 61c6ee2..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-To: gnupg-announce@gnupg.org, info-gnu@gnu.org
-Mail-Followup-To: gnupg-users@gnupg.org
-
-
-Hello!
-
-We are pleased to announce the availability of a new stable GnuPG-2
-release: Version 2.0.24.  This release includes a *security fix* to
-stop a possible DoS using garbled compressed data packets which can
-be used to put gpg into an infinite loop.
-
-The GNU Privacy Guard (GnuPG) is GNU's tool for secure communication
-and data storage.  It can be used to encrypt data, create digital
-signatures, help authenticating using Secure Shell and to provide a
-framework for public key cryptography.  It includes an advanced key
-management facility and is compliant with the OpenPGP and S/MIME
-standards.
-
-GnuPG-2 has a different architecture than GnuPG-1 (e.g. 1.4.17) in
-that it splits up functionality into several modules.  However, both
-versions may be installed alongside without any conflict.  In fact,
-the gpg version from GnuPG-1 is able to make use of the gpg-agent as
-included in GnuPG-2 and allows for seamless passphrase caching.  The
-advantage of GnuPG-1 is its smaller size and the lack of dependency on
-other modules at run and build time.  We will keep maintaining GnuPG-1
-versions because they are very useful for small systems and for server
-based applications requiring only OpenPGP support.
-
-GnuPG is distributed under the terms of the GNU General Public License
-(GPLv3+).  GnuPG-2 works best on GNU/Linux and *BSD systems but is
-also available for other Unices, Microsoft Windows and Mac OS X.
-
-
-What's New in 2.0.24
-====================
-
- * gpg: Avoid DoS due to garbled compressed data packets.
-
- * gpg: Screen keyserver responses to avoid importing unwanted keys
-   from rogue servers.
-
- * gpg: The validity of user ids is now shown by default.  To revert
-   this add "list-options no-show-uid-validity" to gpg.conf.
-
- * gpg: Print more specific reason codes with the INV_RECP status.
-
- * gpg: Allow loading of a cert only key to an OpenPGP card.
-
- * gpg-agent: Make ssh support for ECDSA keys work with Libgcrypt 1.6.
-
- * Minor bug fixes.
-
-
-Getting the Software
-====================
-
-Please follow the instructions found at https://www.gnupg.org/download/
-or read on:
-
-GnuPG 2.0.24 may be downloaded from one of the GnuPG mirror sites or
-direct from ftp://ftp.gnupg.org/gcrypt/gnupg/ .  The list of mirrors
-can be found at https://www.gnupg.org/mirrors.html .  Note that GnuPG
-is not available at ftp.gnu.org.
-
-On ftp.gnupg.org and on its mirrors you should find the following new
-files in the gnupg/ directory:
-
-  - The GnuPG-2 source code compressed using BZIP2 and its OpenPGP
-    signature:
-
-    gnupg-2.0.24.tar.bz2     (4201k)
-    gnupg-2.0.24.tar.bz2.sig
-
-  - A patch file to upgrade a 2.0.23 GnuPG source tree.  This patch does
-    not include updates of the language files.
-
-    gnupg-2.0.23-2.0.24.diff.bz2 (20k)
-
-Note, that we don't distribute gzip compressed tarballs for GnuPG-2.
-A Windows version will eventually be released at https://gpg4win.org .
-
-
-Checking the Integrity
-======================
-
-In order to check that the version of GnuPG which you are going to
-install is an original and unmodified one, you can do it in one of
-the following ways:
-
- * If you already have a trusted version of GnuPG installed, you
-   can simply check the supplied signature.  For example to check the
-   signature of the file gnupg-2.0.24.tar.bz2 you would use this command:
-
-     gpg --verify gnupg-2.0.24.tar.bz2.sig
-
-   This checks whether the signature file matches the source file.
-   You should see a message indicating that the signature is good and
-   made by that signing key.  Make sure that you have the right key,
-   either by checking the fingerprint of that key with other sources
-   or by checking that the key has been signed by a trustworthy other
-   key.  Note, that you can retrieve the signing key using the command
-
-     finger wk ,at' g10code.com
-
-   or using a keyserver like
-
-     gpg --keyserver keys.gnupg.net --recv-key 4F25E3B6
-
-   The distribution key 4F25E3B6 is signed by the well known key
-   1E42B367.
-
-   NEVER USE A GNUPG VERSION YOU JUST DOWNLOADED TO CHECK THE
-   INTEGRITY OF THE SOURCE - USE AN EXISTING GNUPG INSTALLATION!
-
- * If you are not able to use an old version of GnuPG, you have to verify
-   the SHA-1 checksum.  Assuming you downloaded the file
-   gnupg-2.0.24.tar.bz2, you would run the sha1sum command like this:
-
-     sha1sum gnupg-2.0.24.tar.bz2
-
-   and check that the output matches the first line from the
-   following list:
-
-010e027d5f622778cadc4c124013fe515ed705cf  gnupg-2.0.24.tar.bz2
-594d7f91ba4fc215345f18afee46c4aa9f2b3303  gnupg-2.0.23-2.0.24.diff.bz2
-
-
-Documentation
-=============
-
-The file gnupg.info has the complete user manual of the system.
-Separate man pages are included as well; however they have not all the
-details available in the manual.  It is also possible to read the
-complete manual online in HTML format at
-
-  https://www.gnupg.org/documentation/manuals/gnupg/
-
-or in Portable Document Format at
-
-  https://www.gnupg.org/documentation/manuals/gnupg.pdf .
-
-The chapters on gpg-agent, gpg and gpgsm include information on how
-to set up the whole thing.  You may also want search the GnuPG mailing
-list archives or ask on the gnupg-users mailing lists for advise on
-how to solve problems.  Many of the new features are around for
-several years and thus enough public knowledge is already available.
-
-Almost all mail clients support GnuPG-2.  Mutt users may want to use
-the configure option "--enable-gpgme" during build time and put a "set
-use_crypt_gpgme" in ~/.muttrc to enable S/MIME support along with the
-reworked OpenPGP support.
-
-
-Support
-=======
-
-Please consult the archive of the gnupg-users mailing list before
-reporting a bug <https://gnupg.org/documentation/mailing-lists.html>.
-We suggest to send bug reports for a new release to this list in favor
-of filing a bug at <https://bugs.gnupg.org>.  We also have a dedicated
-service directory at:
-
-  https://www.gnupg.org/service.html
-
-The driving force behind the development of GnuPG is the company of
-its principal author, Werner Koch.  Maintenance and improvement of
-GnuPG and related software takes up most of their resources.  To allow
-him to continue this work he kindly asks to either purchase a support
-contract, engage g10 Code for custom enhancements, or to donate money:
-
-  https://gnupg.org/donate/
-
-
-Thanks
-======
-
-We have to thank all the people who helped with this release, be it
-testing, coding, translating, suggesting, auditing, administering the
-servers, spreading the word, and answering questions on the mailing
-lists.
-
-
-Happy Hacking,
-
-  The GnuPG Team
diff --git a/artwork/gnupg-badge-128x128.png b/artwork/gnupg-badge-128x128.png
new file mode 100644 (file)
index 0000000..5116ec8
Binary files /dev/null and b/artwork/gnupg-badge-128x128.png differ
diff --git a/artwork/gnupg-lock-20x25tr.png b/artwork/gnupg-lock-20x25tr.png
new file mode 100644 (file)
index 0000000..a3a0658
Binary files /dev/null and b/artwork/gnupg-lock-20x25tr.png differ
diff --git a/artwork/gnupg-lock-80x100tr.png b/artwork/gnupg-lock-80x100tr.png
new file mode 100644 (file)
index 0000000..ee06ed9
Binary files /dev/null and b/artwork/gnupg-lock-80x100tr.png differ
diff --git a/artwork/gnupg-logo-180x59tr.png b/artwork/gnupg-logo-180x59tr.png
new file mode 100644 (file)
index 0000000..1bb1111
Binary files /dev/null and b/artwork/gnupg-logo-180x59tr.png differ
diff --git a/artwork/gnupg-logo-320x100tr.png b/artwork/gnupg-logo-320x100tr.png
new file mode 100644 (file)
index 0000000..e0b03f1
Binary files /dev/null and b/artwork/gnupg-logo-320x100tr.png differ
diff --git a/artwork/gnupg-logo-420x135tr.png b/artwork/gnupg-logo-420x135tr.png
new file mode 100644 (file)
index 0000000..a1556df
Binary files /dev/null and b/artwork/gnupg-logo-420x135tr.png differ
diff --git a/artwork/gnupg-logo-80x25tr.png b/artwork/gnupg-logo-80x25tr.png
new file mode 100644 (file)
index 0000000..c6df8a4
Binary files /dev/null and b/artwork/gnupg-logo-80x25tr.png differ
diff --git a/autogen.rc b/autogen.rc
new file mode 100644 (file)
index 0000000..f030b94
--- /dev/null
@@ -0,0 +1,45 @@
+# autogen.sh configuration for GnuPG                           -*- sh -*-
+
+#version_parts=3
+
+case "$myhost:$myhostsub" in
+  w32:ce)
+    extraoptions="--enable-dirmngr-auto-start --disable-scdaemon "
+    extraoptions="$extraoptions --disable-zip --enable-gpg2-is-gpg"
+    ;;
+  w32:)
+    extraoptions="--enable-gpgtar"
+    ;;
+esac
+
+case "$myhost" in
+  w32)
+    configure_opts="
+      --with-gpg-error-prefix=@SYSROOT@
+      --with-ksba-prefix=@SYSROOT@
+      --with-libgcrypt-prefix=@SYSROOT@
+      --with-libassuan-prefix=@SYSROOT@
+      --with-zlib=@SYSROOT@
+      --with-regex=@SYSROOT@
+      --with-npth-prefix=@SYSROOT@
+      --with-adns=@SYSROOT@
+      --disable-g13
+      "
+    ;;
+
+  amd64)
+    configure_opts="
+      --with-gpg-error-prefix=@SYSROOT@
+      --with-ksba-prefix=@SYSROOT@
+      --with-libgcrypt-prefix=@SYSROOT@
+      --with-libassuan-prefix=@SYSROOT@
+      --with-zlib=/usr/x86_64-linux-gnu/usr
+      --with-pth-prefix=/usr/x86_64-linux-gnu/usr
+     "
+    ;;
+esac
+
+
+extra_aclocal_flags="-I gl/m4"
+
+final_info="./configure --sysconfdir=/etc --enable-maintainer-mode  && make"
index 605babf..7effd56 100755 (executable)
@@ -1,7 +1,6 @@
 #! /bin/sh
-# Run this to generate all the initial makefiles, etc.
-#
-# Copyright (C) 2003 g10 Code GmbH
+# autogen.sh
+# Copyright (C) 2003, 2014 g10 Code GmbH
 #
 # This file is free software; as a special exception the author gives
 # unlimited permission to copy and/or distribute it, with or without
@@ -10,6 +9,13 @@
 # This program is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# This is a generic script to create the configure script and handle cross
+# build environments.  It requires the presence of a autogen.rc file to
+# configure it for the respective package.  It is maintained as part of
+# GnuPG and source copied by other packages.
+#
+# Version: 2014-06-06
 
 configure_ac="configure.ac"
 
@@ -18,7 +24,7 @@ cvtver () {
 }
 
 check_version () {
-    if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then
+    if [ $(( `("$1" --version || echo "0") | cvtver` >= $2 )) = 1 ]; then
        return 0
     fi
     echo "**Error**: "\`$1\'" not installed or too old." >&2
@@ -28,6 +34,29 @@ check_version () {
     return 1
 }
 
+fatal () {
+    echo "autogen.sh:" "$*" >&2
+    DIE=yes
+}
+
+info () {
+    if [ -z "${SILENT}" ]; then
+      echo "autogen.sh:" "$*" >&2
+    fi
+}
+
+die_p () {
+  if [ "$DIE" = "yes" ]; then
+    echo "autogen.sh: Stop." >&2
+    exit 1
+  fi
+}
+
+replace_sysroot () {
+    configure_opts=$(echo $configure_opts | sed "s#@SYSROOT@#${w32root}#g")
+    extraoptions=$(echo $extraoptions | sed "s#@SYSROOT@#${w32root}#g")
+}
+
 # Allow to override the default tool names
 AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
 AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
@@ -40,29 +69,219 @@ MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
 
 DIE=no
 FORCE=
+SILENT=
+PRINT_HOST=no
+PRINT_BUILD=no
+tmp=$(dirname "$0")
+tsdir=$(cd "${tmp}"; pwd)
+version_parts=3
+
+if [ -n "${AUTOGEN_SH_SILENT}" ]; then
+  SILENT=" --silent"
+fi
+if test x"$1" = x"--help"; then
+  echo "usage: ./autogen.sh [--silent] [--force] [--build-TYPE] [ARGS]"
+  exit 0
+fi
+if test x"$1" = x"--silent"; then
+  SILENT=" --silent"
+  shift
+fi
 if test x"$1" = x"--force"; then
   FORCE=" --force"
   shift
 fi
+if test x"$1" = x"--print-host"; then
+  PRINT_HOST=yes
+  shift
+fi
+if test x"$1" = x"--print-build"; then
+  PRINT_BUILD=yes
+  shift
+fi
 
-# ***** W32 build script *******
-# Used to cross-compile for Windows.
-if test "$1" = "--build-w32"; then
-    tmp=`dirname $0`
-    tsdir=`cd "$tmp"; pwd`
-    shift
-    if [ ! -f $tsdir/scripts/config.guess ]; then
-        echo "$tsdir/scripts/config.guess not found" >&2
-        exit 1
+
+# Reject unsafe characters in $HOME, $tsdir and cwd.  We consider spaces
+# as unsafe because it is too easy to get scripts wrong in this regard.
+am_lf='
+'
+case `pwd` in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    fatal "unsafe working directory name" ;;
+esac
+case $tsdir in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    fatal "unsafe source directory: \`$tsdir'" ;;
+esac
+case $HOME in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    fatal "unsafe home directory: \`$HOME'" ;;
+esac
+die_p
+
+
+# List of variables sourced from autogen.rc.  The strings '@SYSROOT@' in
+# these variables are replaced by the actual system root.
+configure_opts=
+extraoptions=
+# List of optional variables sourced from autogen.rc and ~/.gnupg-autogen.rc
+w32_toolprefixes=
+w32_extraoptions=
+w32ce_toolprefixes=
+w32ce_extraoptions=
+w64_toolprefixes=
+w64_extraoptions=
+amd64_toolprefixes=
+# End list of optional variables sourced from ~/.gnupg-autogen.rc
+# What follows are variables which are sourced but default to
+# environment variables or lacking them hardcoded values.
+#w32root=
+#w32ce_root=
+#w64root=
+#amd64root=
+
+# Convenience option to use certain configure options for some hosts.
+myhost=""
+myhostsub=""
+case "$1" in
+    --find-version)
+        myhost="find-version"
+        SILENT=" --silent"
+        shift
+        ;;
+    --build-w32)
+        myhost="w32"
+        shift
+        ;;
+    --build-w32ce)
+        myhost="w32"
+        myhostsub="ce"
+        shift
+        ;;
+    --build-w64)
+        myhost="w32"
+        myhostsub="64"
+        shift
+        ;;
+    --build-amd64)
+        myhost="amd64"
+        shift
+        ;;
+    --build*)
+        fatal "**Error**: invalid build option $1"
+        shift
+        ;;
+    *)
+        ;;
+esac
+die_p
+
+
+# Source our configuration
+if [ -f "${tsdir}/autogen.rc" ]; then
+    . "${tsdir}/autogen.rc"
+fi
+
+# Source optional site specific configuration
+if [ -f "$HOME/.gnupg-autogen.rc" ]; then
+    info "sourcing extra definitions from $HOME/.gnupg-autogen.rc"
+    . "$HOME/.gnupg-autogen.rc"
+fi
+
+
+# **** FIND VERSION ****
+# This is a helper for the configure.ac M4 magic
+# Called
+#   ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO]
+# returns a complete version string with automatic beta numbering.
+if [ "$myhost" = "find-version" ]; then
+    package="$1"
+    major="$2"
+    minor="$3"
+    micro="$4"
+
+    case "$version_parts" in
+      2)
+        matchstr1="$package-$major.[0-9]*"
+        matchstr2="$package-$major-base"
+        vers="$major.$minor"
+        ;;
+      *)
+        matchstr1="$package-$major.$minor.[0-9]*"
+        matchstr2="$package-$major.$minor-base"
+        vers="$major.$minor.$micro"
+        ;;
+    esac
+
+    beta=no
+    if [ -d .git ]; then
+      ingit=yes
+      tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null)
+      if [ -n "$tmp" ]; then
+          tmp=$(echo "$tmp"|awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}')
+      else
+          tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null \
+                | awk -F- '$4!=0{print"-beta"$4}')
+      fi
+      [ -n "$tmp" ] && beta=yes
+      rev=$(git rev-parse --short HEAD | tr -d '\n\r')
+      rvd=$((0x$(echo ${rev} | head -c 4)))
+    else
+      ingit=no
+      beta=yes
+      tmp="-unknown"
+      rev="0000000"
+      rvd="0"
     fi
-    build=`$tsdir/scripts/config.guess`
 
-    [ -z "$w32root" ] && w32root="$HOME/w32root"
-    echo "Using $w32root as standard install directory" >&2
+    echo "$package-$vers$tmp:$beta:$ingit:$vers$tmp:$vers:$tmp:$rev:$rvd:"
+    exit 0
+fi
+# **** end FIND VERSION ****
+
+
+if [ ! -f "$tsdir/build-aux/config.guess" ]; then
+    fatal "$tsdir/build-aux/config.guess not found"
+    exit 1
+fi
+build=`$tsdir/build-aux/config.guess`
+if [ $PRINT_BUILD = yes ]; then
+    echo "$build"
+    exit 0
+fi
+
+
+
+# ******************
+#  W32 build script
+# ******************
+if [ "$myhost" = "w32" ]; then
+    case $myhostsub in
+        ce)
+          w32root="$w32ce_root"
+          [ -z "$w32root" ] && w32root="$HOME/w32ce_root"
+          toolprefixes="$w32ce_toolprefixes arm-mingw32ce"
+          extraoptions="$extraoptions $w32ce_extraoptions"
+          ;;
+        64)
+          w32root="$w64root"
+          [ -z "$w32root" ] && w32root="$HOME/w64root"
+          toolprefixes="$w64_toolprefixes x86_64-w64-mingw32"
+          extraoptions="$extraoptions $w64_extraoptions"
+          ;;
+        *)
+          [ -z "$w32root" ] && w32root="$HOME/w32root"
+          toolprefixes="$w32_toolprefixes i686-w64-mingw32 i586-mingw32msvc"
+          toolprefixes="$toolprefixes i386-mingw32msvc mingw32"
+          extraoptions="$extraoptions $w32_extraoptions"
+          ;;
+    esac
+    info "Using $w32root as standard install directory"
+    replace_sysroot
 
     # Locate the cross compiler
     crossbindir=
-    for host in i686-w64-mingw32 i586-mingw32msvc i386-mingw32msvc mingw32; do
+    for host in $toolprefixes; do
         if ${host}-gcc --version >/dev/null 2>&1 ; then
             crossbindir=/usr/${host}/bin
             conf_CC="CC=${host}-gcc"
@@ -70,32 +289,29 @@ if test "$1" = "--build-w32"; then
         fi
     done
     if [ -z "$crossbindir" ]; then
-        echo "Cross compiler kit not installed" >&2
-        echo "Under Debian GNU/Linux, you may install it using" >&2
-        echo "  apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2
-        echo "Stop." >&2
-        exit 1
+        fatal "cross compiler kit not installed"
+        if [ -z "$myhostsub" ]; then
+          info "Under Debian GNU/Linux, you may install it using"
+          info "  apt-get install mingw32 mingw32-runtime mingw32-binutils"
+        fi
+        die_p
+    fi
+    if [ $PRINT_HOST = yes ]; then
+        echo "$host"
+        exit 0
     fi
 
     if [ -f "$tsdir/config.log" ]; then
         if ! head $tsdir/config.log | grep "$host" >/dev/null; then
-            echo "Please run a 'make distclean' first" >&2
-            exit 1
+            fatal "Please run a 'make distclean' first"
+            die_p
         fi
     fi
 
-    $tsdir/configure --enable-maintainer-mode --prefix=${w32root}  \
-             --host=${host} --build=${build} \
-             --enable-gpgtar \
-             --with-gpg-error-prefix=${w32root} \
-            --with-ksba-prefix=${w32root} \
-            --with-libgcrypt-prefix=${w32root} \
-            --with-libassuan-prefix=${w32root} \
-            --with-zlib=${w32root} \
-            --with-regex=${w32root} \
-             --with-pth-prefix=${w32root} \
-             --with-libiconv-prefix=${w32root} \
-             --with-adns=${w32root} "$@"
+    $tsdir/configure --enable-maintainer-mode ${SILENT} \
+             --prefix=${w32root}  \
+             --host=${host} --build=${build} SYSROOT=${w32root} \
+             ${configure_opts} ${extraoptions} "$@"
     rc=$?
     exit $rc
 fi
@@ -103,22 +319,16 @@ fi
 
 # ***** AMD64 cross build script *******
 # Used to cross-compile for AMD64 (for testing)
-if test "$1" = "--build-amd64"; then
-    tmp=`dirname $0`
-    tsdir=`cd "$tmp"; pwd`
-    shift
-    if [ ! -f $tsdir/scripts/config.guess ]; then
-        echo "$tsdir/scripts/config.guess not found" >&2
-        exit 1
-    fi
-    build=`$tsdir/scripts/config.guess`
-
+if [ "$myhost" = "amd64" ]; then
     [ -z "$amd64root" ] && amd64root="$HOME/amd64root"
-    echo "Using $amd64root as standard install directory" >&2
+    info "Using $amd64root as standard install directory"
+    replace_sysroot
+
+    toolprefixes="$amd64_toolprefixes x86_64-linux-gnu amd64-linux-gnu"
 
     # Locate the cross compiler
     crossbindir=
-    for host in x86_64-linux-gnu amd64-linux-gnu; do
+    for host in $toolprefixes ; do
         if ${host}-gcc --version >/dev/null 2>&1 ; then
             crossbindir=/usr/${host}/bin
             conf_CC="CC=${host}-gcc"
@@ -130,6 +340,10 @@ if test "$1" = "--build-amd64"; then
         echo "Stop." >&2
         exit 1
     fi
+    if [ $PRINT_HOST = yes ]; then
+        echo "$host"
+        exit 0
+    fi
 
     if [ -f "$tsdir/config.log" ]; then
         if ! head $tsdir/config.log | grep "$host" >/dev/null; then
@@ -138,14 +352,10 @@ if test "$1" = "--build-amd64"; then
         fi
     fi
 
-    $tsdir/configure --enable-maintainer-mode --prefix=${amd64root}  \
+    $tsdir/configure --enable-maintainer-mode ${SILENT} \
+             --prefix=${amd64root}  \
              --host=${host} --build=${build} \
-             --with-gpg-error-prefix=${amd64root} \
-            --with-ksba-prefix=${amd64root} \
-            --with-libgcrypt-prefix=${amd64root} \
-            --with-libassuan-prefix=${amd64root} \
-            --with-zlib=/usr/x86_64-linux-gnu/usr \
-             --with-pth-prefix=/usr/x86_64-linux-gnu/usr
+             ${configure_opts} ${extraoptions} "$@"
     rc=$?
     exit $rc
 fi
@@ -165,12 +375,15 @@ q
 }' ${configure_ac}`
 automake_vers_num=`echo "$automake_vers" | cvtver`
 
-gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
+if [ -d "${tsdir}/po" ]; then
+  gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
 s/^.*\[\(.*\)])/\1/p
 q
 }' ${configure_ac}`
-gettext_vers_num=`echo "$gettext_vers" | cvtver`
-
+  gettext_vers_num=`echo "$gettext_vers" | cvtver`
+else
+  gettext_vers="n/a"
+fi
 
 if [ -z "$autoconf_vers" -o -z "$automake_vers" -o -z "$gettext_vers" ]
 then
@@ -185,60 +398,71 @@ fi
 if check_version $AUTOMAKE $automake_vers_num $automake_vers; then
   check_version $ACLOCAL $automake_vers_num $autoconf_vers automake
 fi
-if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
-  check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
+if [ "$gettext_vers" != "n/a" ]; then
+  if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
+    check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
+  fi
 fi
 
-if test "$DIE" = "yes"; then
+if [ "$DIE" = "yes" ]; then
     cat <<EOF
 
 Note that you may use alternative versions of the tools by setting
-the corresponding environment variables; see README.CVS for details.
+the corresponding environment variables; see README.GIT for details.
 
 EOF
-    exit 1
+    die_p
 fi
 
-
-# Update the git setup.
+# Check the git setup.
 if [ -d .git ]; then
+  CP="cp -a"
+  [ -z "${SILENT}" ] && CP="$CP -v"
   if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then
-    cat <<EOF >&2
+    [ -z "${SILENT}" ] && cat <<EOF
 *** Activating trailing whitespace git pre-commit hook. ***
     For more information see this thread:
       http://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084html
     To deactivate this pre-commit hook again move .git/hooks/pre-commit
     and .git/hooks/pre-commit.sample out of the way.
 EOF
-      cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
-      chmod -c +x  .git/hooks/pre-commit
+      $CP .git/hooks/pre-commit.sample .git/hooks/pre-commit
+      chmod +x  .git/hooks/pre-commit
   fi
-  tmp=$(git config --get filter.cleanpo.clean)
-  if [ "$tmp" != "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ]
-  then
-    echo "*** Adding GIT filter.cleanpo.clean configuration." >&2
-    git config --add filter.cleanpo.clean \
+
+  if [ "$gettext_vers" != "n/a" ]; then
+    tmp=$(git config --get filter.cleanpo.clean)
+    if [ "$tmp" != \
+          "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ]
+    then
+      info "*** Adding GIT filter.cleanpo.clean configuration."
+      git config --add filter.cleanpo.clean \
         "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'"
+    fi
   fi
-  if [ -f scripts/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then
-    cat <<EOF >&2
+  if [ -f build-aux/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then
+      [ -z "${SILENT}" ] && cat <<EOF
 *** Activating commit log message check hook. ***
 EOF
-      cp scripts/git-hooks/commit-msg .git/hooks/commit-msg
-      chmod -c +x  .git/hooks/commit-msg
+      $CP build-aux/git-hooks/commit-msg .git/hooks/commit-msg
+      chmod +x  .git/hooks/commit-msg
   fi
 fi
 
-
-echo "Running aclocal -I m4 -I gl/m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..."
-$ACLOCAL -I m4 -I gl/m4 $ACLOCAL_FLAGS
-echo "Running autoheader..."
+aclocal_flags="-I m4"
+if [ -n "${extra_aclocal_flags}" ]; then
+  aclocal_flags="${aclocal_flags} ${extra_aclocal_flags}"
+fi
+if [ -n "${ACLOCAL_FLAGS}" ]; then
+  aclocal_flags="${aclocal_flags} ${ACLOCAL_FLAGS}"
+fi
+info "Running $ACLOCAL ${aclocal_flags} ..."
+$ACLOCAL ${aclocal_flags}
+info "Running autoheader..."
 $AUTOHEADER
-echo "Running automake --gnu ..."
+info "Running automake --gnu ..."
 $AUTOMAKE --gnu;
-echo "Running autoconf${FORCE} ..."
+info "Running autoconf${FORCE} ..."
 $AUTOCONF${FORCE}
 
-echo "You may now run:
-  ./configure --sysconfdir=/etc --enable-maintainer-mode --enable-symcryptrun --enable-mailto --enable-gpgtar && make
-"
+info "You may now run:${am_lf}  ${final_info}"
similarity index 66%
rename from scripts/ChangeLog-2011
rename to build-aux/ChangeLog-2011
index a4b30d7..9a3eed3 100644 (file)
@@ -1,21 +1,27 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-07-22  Werner Koch  <wk@g10code.com>
+2011-11-29  Werner Koch  <wk@g10code.com>
 
-       * config.sub, config.guess: Update to version 2011-06-03.
+       * build-all.sh: Make sure HOME has no unsafe characters.
 
-2011-01-11  Werner Koch  <wk@g10code.com>
+2011-11-28  Werner Koch  <wk@g10code.com>,
+           Jim Meyering  <jim@meyering.net>
 
-       * config.guess, config.sub: Update to version 2010-09-24.
+       * build-all.sh: New.
 
-2009-12-21  Werner Koch  <wk@g10code.com>
+2011-08-10  Werner Koch  <wk@g10code.com>
 
-       * config.guess, config.sub: Update to version 2009-06-11.
+       * config.guess, config.sub: Update to version 2011-06-03.
+
+2010-10-26  Werner Koch  <wk@g10code.com>
+
+       * config.guess: Update to version 2010-09-24.
+        * config.sub: Update to version 2010-09-11.
 
 2007-12-14  Werner Koch  <wk@g10code.com>
 
@@ -41,7 +47,7 @@
        * config.guess, config.sub: Updated.
 
 
- Copyright 2004, 2007 Free Software Foundation, Inc.
+ Copyright 2004, 2007, 2010 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
@@ -50,3 +56,7 @@
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/build-aux/build-all.sh b/build-aux/build-all.sh
new file mode 100755 (executable)
index 0000000..23af620
--- /dev/null
@@ -0,0 +1,65 @@
+#! /bin/bash
+# A simple script to build all parts of GnuPG from the git repos.
+#
+# Copyright 2011 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.
+
+# Run this in another window:
+#tail -n0 -F ~/tmp/gpg-tmp/b/{libgpg-error,libksba,libassuan,libgcrypt,gnupg}.log &
+
+p=$HOME/tmp/gpg-tmp
+parts="libgpg-error libassuan libksba libgcrypt gnupg"
+die=no
+here="`pwd`"
+
+# Reject unsafe characters in $PWD and $HOME.  We consider spaces as
+# unsafe because it is too easy to get scripts wrong in this regard.
+am_lf='
+'
+case $here in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    echo "unsafe working directory: \`$here'"; die=yes;;
+esac
+case $HOME in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    echo "unsafe home directory: \`$HOME'"; die=yes;;
+esac
+test $die = yes && exit 1
+
+# Check that all components are available
+for i in $parts; do
+  if test -d $i ; then
+    :
+  else
+    die=yes
+    echo "component $i missing"
+  fi
+done
+test $die = yes && exit 1
+
+mkdir $p || exit 1
+mkdir $p/b || exit 1
+for i in $parts; do
+  mkdir $p/b/$i || exit 1
+done
+
+export PATH=$p/bin:$PATH
+export LD_LIBRARY_PATH=$p/lib
+
+prev=
+cfg="configure --enable-maintainer-mode --prefix=$p"
+for i in $parts; do
+  echo $i...
+  test -n "$prev" && cfg="$cfg --with-$prev-prefix=$p"
+  (cd $p/b/$i && eval $here/$i/$cfg && make && make check && make install) \
+      > $p/b/$i.log 2>&1 \
+      || { echo FAIL; break; }
+  prev=$i
+done
diff --git a/build-aux/compile b/build-aux/compile
new file mode 100755 (executable)
index 0000000..c985324
--- /dev/null
@@ -0,0 +1,141 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2005-05-14.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program 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 3, or (at your option)
+# any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+       # configure might choose to run compile as `compile cc -o foo foo.c'.
+       # So we strip `-o arg' only if arg is an object.
+       eat=1
+       case $2 in
+         *.o | *.obj)
+           ofile=$2
+           ;;
+         *)
+           set x "$@" -o "$2"
+           shift
+           ;;
+       esac
+       ;;
+      *.c)
+       cfile=$1
+       set x "$@" "$1"
+       shift
+       ;;
+      *)
+       set x "$@" "$1"
+       shift
+       ;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no `-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # `.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
similarity index 85%
rename from scripts/config.guess
rename to build-aux/config.guess
index dbfb978..b02565c 100755 (executable)
@@ -1,12 +1,14 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2015-01-01'
+timestamp='2011-06-03'
 
 # This file 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 3 of the License, or
+# the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -15,22 +17,26 @@ timestamp='2015-01-01'
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program.  This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
 #
-# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
 #
 # You can get the latest version of this script from:
 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-#
-# Please send patches to <config-patches@gnu.org>.
-
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -50,7 +56,9 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -132,33 +140,12 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
 UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-case "${UNAME_SYSTEM}" in
-Linux|GNU|GNU/*)
-       # If the system lacks a compiler, then just pick glibc.
-       # We could probably try harder.
-       LIBC=gnu
-
-       eval $set_cc_for_build
-       cat <<-EOF > $dummy.c
-       #include <features.h>
-       #if defined(__UCLIBC__)
-       LIBC=uclibc
-       #elif defined(__dietlibc__)
-       LIBC=dietlibc
-       #else
-       LIBC=gnu
-       #endif
-       EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
-       ;;
-esac
-
 # Note: order is significant - the case branches are not exclusive.
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:NetBSD:*:*)
        # NetBSD (nbsd) targets should (where applicable) match one or
-       # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
        # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
        # switched to ELF, *-*-netbsd* would select the old
        # object file format.  This provides both forward
@@ -215,10 +202,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
        echo "${machine}-${os}${release}"
        exit ;;
-    *:Bitrig:*:*)
-       UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-       echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
-       exit ;;
     *:OpenBSD:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
        echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -321,7 +304,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
        echo arm-acorn-riscix${UNAME_RELEASE}
        exit ;;
-    arm*:riscos:*:*|arm*:RISCOS:*:*)
+    arm:riscos:*:*|arm:RISCOS:*:*)
        echo arm-unknown-riscos
        exit ;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -579,9 +562,8 @@ EOF
        else
                IBM_ARCH=powerpc
        fi
-       if [ -x /usr/bin/lslpp ] ; then
-               IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-                          awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
        else
                IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
        fi
@@ -810,26 +792,21 @@ EOF
        echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
        exit ;;
     *:FreeBSD:*:*)
-       UNAME_PROCESSOR=`/usr/bin/uname -p`
-       case ${UNAME_PROCESSOR} in
+       case ${UNAME_MACHINE} in
+           pc98)
+               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
            amd64)
                echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
            *)
-               echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
        esac
        exit ;;
     i*:CYGWIN*:*)
        echo ${UNAME_MACHINE}-pc-cygwin
        exit ;;
-    *:MINGW64*:*)
-       echo ${UNAME_MACHINE}-pc-mingw64
-       exit ;;
     *:MINGW*:*)
        echo ${UNAME_MACHINE}-pc-mingw32
        exit ;;
-    *:MSYS*:*)
-       echo ${UNAME_MACHINE}-pc-msys
-       exit ;;
     i*:windows32*:*)
        # uname -m includes "-pc" on this system.
        echo ${UNAME_MACHINE}-mingw32
@@ -875,22 +852,15 @@ EOF
        exit ;;
     *:GNU:*:*)
        # the GNU system
-       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
        exit ;;
     *:GNU/*:*:*)
        # other systems with GNU libc and userland
-       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
        exit ;;
     i*86:Minix:*:*)
        echo ${UNAME_MACHINE}-pc-minix
        exit ;;
-    aarch64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-       exit ;;
-    aarch64_be:Linux:*:*)
-       UNAME_MACHINE=aarch64_be
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-       exit ;;
     alpha:Linux:*:*)
        case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
          EV5)   UNAME_MACHINE=alphaev5 ;;
@@ -902,54 +872,56 @@ EOF
          EV68*) UNAME_MACHINE=alphaev68 ;;
        esac
        objdump --private-headers /bin/sh | grep -q ld.so.1
-       if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-       exit ;;
-    arc:Linux:*:* | arceb:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
        exit ;;
     arm*:Linux:*:*)
        eval $set_cc_for_build
        if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
            | grep -q __ARM_EABI__
        then
-           echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+           echo ${UNAME_MACHINE}-unknown-linux-gnu
        else
            if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
                | grep -q __ARM_PCS_VFP
            then
-               echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabi
            else
-               echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
            fi
        fi
        exit ;;
     avr32*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     cris:Linux:*:*)
-       echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+       echo cris-axis-linux-gnu
        exit ;;
     crisv32:Linux:*:*)
-       echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+       echo crisv32-axis-linux-gnu
        exit ;;
     frv:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-       exit ;;
-    hexagon:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo frv-unknown-linux-gnu
        exit ;;
     i*86:Linux:*:*)
-       echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+       LIBC=gnu
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+       echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
        exit ;;
     ia64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     m32r*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     m68*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
        eval $set_cc_for_build
@@ -968,63 +940,54 @@ EOF
        #endif
 EOF
        eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
-       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
        ;;
-    openrisc*:Linux:*:*)
-       echo or1k-unknown-linux-${LIBC}
-       exit ;;
-    or32:Linux:*:* | or1k*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+    or32:Linux:*:*)
+       echo or32-unknown-linux-gnu
        exit ;;
     padre:Linux:*:*)
-       echo sparc-unknown-linux-${LIBC}
+       echo sparc-unknown-linux-gnu
        exit ;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-       echo hppa64-unknown-linux-${LIBC}
+       echo hppa64-unknown-linux-gnu
        exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
        # Look for CPU level
        case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-         PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
-         PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
-         *)    echo hppa-unknown-linux-${LIBC} ;;
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
        esac
        exit ;;
     ppc64:Linux:*:*)
-       echo powerpc64-unknown-linux-${LIBC}
+       echo powerpc64-unknown-linux-gnu
        exit ;;
     ppc:Linux:*:*)
-       echo powerpc-unknown-linux-${LIBC}
-       exit ;;
-    ppc64le:Linux:*:*)
-       echo powerpc64le-unknown-linux-${LIBC}
-       exit ;;
-    ppcle:Linux:*:*)
-       echo powerpcle-unknown-linux-${LIBC}
+       echo powerpc-unknown-linux-gnu
        exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-       echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+       echo ${UNAME_MACHINE}-ibm-linux
        exit ;;
     sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     sh*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     tile*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     vax:Linux:*:*)
-       echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+       echo ${UNAME_MACHINE}-dec-linux-gnu
        exit ;;
     x86_64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo x86_64-unknown-linux-gnu
        exit ;;
     xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     i*86:DYNIX/ptx:4*:*)
        # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1228,9 +1191,6 @@ EOF
     BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
        echo i586-pc-haiku
        exit ;;
-    x86_64:Haiku:*:*)
-       echo x86_64-unknown-haiku
-       exit ;;
     SX-4:SUPER-UX:*:*)
        echo sx4-nec-superux${UNAME_RELEASE}
        exit ;;
@@ -1257,31 +1217,19 @@ EOF
        exit ;;
     *:Darwin:*:*)
        UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       eval $set_cc_for_build
-       if test "$UNAME_PROCESSOR" = unknown ; then
-           UNAME_PROCESSOR=powerpc
-       fi
-       if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-           if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-               if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-                   (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-                   grep IS_64BIT_ARCH >/dev/null
-               then
-                   case $UNAME_PROCESSOR in
-                       i386) UNAME_PROCESSOR=x86_64 ;;
-                       powerpc) UNAME_PROCESSOR=powerpc64 ;;
-                   esac
-               fi
-           fi
-       elif test "$UNAME_PROCESSOR" = i386 ; then
-           # Avoid executing cc on OS X 10.9, as it ships with a stub
-           # that puts up a graphical alert prompting to install
-           # developer tools.  Any system running Mac OS X 10.7 or
-           # later (Darwin 11 and later) is required to have a 64-bit
-           # processor. This is not true of the ARM version of Darwin
-           # that Apple uses in portable devices.
-           UNAME_PROCESSOR=x86_64
-       fi
+       case $UNAME_PROCESSOR in
+           i386)
+               eval $set_cc_for_build
+               if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+                 if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+                     (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+                     grep IS_64BIT_ARCH >/dev/null
+                 then
+                     UNAME_PROCESSOR="x86_64"
+                 fi
+               fi ;;
+           unknown) UNAME_PROCESSOR=powerpc ;;
+       esac
        echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
        exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1298,7 +1246,7 @@ EOF
     NEO-?:NONSTOP_KERNEL:*:*)
        echo neo-tandem-nsk${UNAME_RELEASE}
        exit ;;
-    NSE-*:NONSTOP_KERNEL:*:*)
+    NSE-?:NONSTOP_KERNEL:*:*)
        echo nse-tandem-nsk${UNAME_RELEASE}
        exit ;;
     NSR-?:NONSTOP_KERNEL:*:*)
@@ -1367,11 +1315,159 @@ EOF
     i*86:AROS:*:*)
        echo ${UNAME_MACHINE}-pc-aros
        exit ;;
-    x86_64:VMkernel:*:*)
-       echo ${UNAME_MACHINE}-unknown-esx
-       exit ;;
 esac
 
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+       "4"
+#else
+       ""
+#endif
+       ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+       { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit ;;
+    c34*)
+       echo c34-convex-bsd
+       exit ;;
+    c38*)
+       echo c38-convex-bsd
+       exit ;;
+    c4*)
+       echo c4-convex-bsd
+       exit ;;
+    esac
+fi
+
 cat >&2 <<EOF
 $0: unable to guess system type
 
similarity index 88%
rename from scripts/config.rpath
rename to build-aux/config.rpath
index b625621..c547c68 100755 (executable)
@@ -2,7 +2,7 @@
 # Output a system dependent set of variables, describing how to set the
 # run time search path of shared libraries in an executable.
 #
-#   Copyright 1996-2014 Free Software Foundation, Inc.
+#   Copyright 1996-2007 Free Software Foundation, Inc.
 #   Taken from GNU libtool, 2001
 #   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 #
@@ -25,7 +25,7 @@
 #   known workaround is to choose shorter directory names for the build
 #   directory and/or the installation directory.
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 shrext=.so
@@ -47,7 +47,7 @@ for cc_temp in $CC""; do
 done
 cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
 
-# Code taken from libtool.m4's _LT_COMPILER_PIC.
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
 
 wl=
 if test "$GCC" = yes; then
@@ -57,7 +57,14 @@ else
     aix*)
       wl='-Wl,'
       ;;
-    mingw* | cygwin* | pw32* | os2* | cegcc*)
+    darwin*)
+      case $cc_basename in
+        xlc*)
+          wl='-Wl,'
+          ;;
+      esac
+      ;;
+    mingw* | cygwin* | pw32* | os2*)
       ;;
     hpux9* | hpux10* | hpux11*)
       wl='-Wl,'
@@ -65,37 +72,24 @@ else
     irix5* | irix6* | nonstopux*)
       wl='-Wl,'
       ;;
-    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+    newsos6)
+      ;;
+    linux* | k*bsd*-gnu)
       case $cc_basename in
-        ecc*)
-          wl='-Wl,'
-          ;;
-        icc* | ifort*)
-          wl='-Wl,'
-          ;;
-        lf95*)
+        icc* | ecc*)
           wl='-Wl,'
           ;;
-        nagfor*)
-          wl='-Wl,-Wl,,'
-          ;;
-        pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        pgcc | pgf77 | pgf90)
           wl='-Wl,'
           ;;
         ccc*)
           wl='-Wl,'
           ;;
-        xl* | bgxl* | bgf* | mpixl*)
-          wl='-Wl,'
-          ;;
         como)
           wl='-lopt='
           ;;
         *)
           case `$CC -V 2>&1 | sed 5q` in
-            *Sun\ F* | *Sun*Fortran*)
-              wl=
-              ;;
             *Sun\ C*)
               wl='-Wl,'
               ;;
@@ -103,24 +97,13 @@ else
           ;;
       esac
       ;;
-    newsos6)
-      ;;
-    *nto* | *qnx*)
-      ;;
     osf3* | osf4* | osf5*)
       wl='-Wl,'
       ;;
     rdos*)
       ;;
     solaris*)
-      case $cc_basename in
-        f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
-          wl='-Qoption ld '
-          ;;
-        *)
-          wl='-Wl,'
-          ;;
-      esac
+      wl='-Wl,'
       ;;
     sunos4*)
       wl='-Qoption ld '
@@ -141,7 +124,7 @@ else
   esac
 fi
 
-# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
 
 hardcode_libdir_flag_spec=
 hardcode_libdir_separator=
@@ -149,7 +132,7 @@ hardcode_direct=no
 hardcode_minus_L=no
 
 case "$host_os" in
-  cygwin* | mingw* | pw32* | cegcc*)
+  cygwin* | mingw* | pw32*)
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
@@ -175,21 +158,22 @@ if test "$with_gnu_ld" = yes; then
   # option of GNU ld is called -rpath, not --rpath.
   hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
   case "$host_os" in
-    aix[3-9]*)
+    aix3* | aix4* | aix5*)
       # On AIX/PPC, the GNU linker is very broken
       if test "$host_cpu" != ia64; then
         ld_shlibs=no
       fi
       ;;
     amigaos*)
-      case "$host_cpu" in
-        powerpc)
-          ;;
-        m68k)
-          hardcode_libdir_flag_spec='-L$libdir'
-          hardcode_minus_L=yes
-          ;;
-      esac
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we cannot use
+      # them.
+      ld_shlibs=no
       ;;
     beos*)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
@@ -198,7 +182,7 @@ if test "$with_gnu_ld" = yes; then
         ld_shlibs=no
       fi
       ;;
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | pw32*)
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       hardcode_libdir_flag_spec='-L$libdir'
@@ -208,13 +192,11 @@ if test "$with_gnu_ld" = yes; then
         ld_shlibs=no
       fi
       ;;
-    haiku*)
-      ;;
     interix[3-9]*)
       hardcode_direct=no
       hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
       ;;
-    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+    gnu* | linux* | k*bsd*-gnu)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
         :
       else
@@ -272,7 +254,7 @@ else
         hardcode_direct=unsupported
       fi
       ;;
-    aix[4-9]*)
+    aix4* | aix5*)
       if test "$host_cpu" = ia64; then
         # On IA64, the linker does run time linking by default, so we don't
         # have to do anything special.
@@ -282,7 +264,7 @@ else
         # Test if we are trying to use run time linking or normal
         # AIX style linking. If -brtl is somewhere in LDFLAGS, we
         # need to do runtime linking.
-        case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+        case $host_os in aix4.[23]|aix4.[23].*|aix5*)
           for ld_flag in $LDFLAGS; do
             if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
               aix_use_runtimelinking=yes
@@ -337,18 +319,14 @@ else
       fi
       ;;
     amigaos*)
-      case "$host_cpu" in
-        powerpc)
-          ;;
-        m68k)
-          hardcode_libdir_flag_spec='-L$libdir'
-          hardcode_minus_L=yes
-          ;;
-      esac
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs=no
       ;;
     bsdi[45]*)
       ;;
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | pw32*)
       # When not using gcc, we currently assume that we are using
       # Microsoft Visual C++.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
@@ -358,16 +336,29 @@ else
       ;;
     darwin* | rhapsody*)
       hardcode_direct=no
-      if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
+      if test "$GCC" = yes ; then
         :
       else
-        ld_shlibs=no
+        case $cc_basename in
+          xlc*)
+            ;;
+          *)
+            ld_shlibs=no
+            ;;
+        esac
       fi
       ;;
     dgux*)
       hardcode_libdir_flag_spec='-L$libdir'
       ;;
-    freebsd2.[01]*)
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+    freebsd2.2*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    freebsd2*)
       hardcode_direct=yes
       hardcode_minus_L=yes
       ;;
@@ -423,8 +414,6 @@ else
       hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       ;;
-    *nto* | *qnx*)
-      ;;
     openbsd*)
       if test -f /usr/libexec/ld.so; then
         hardcode_direct=yes
@@ -505,7 +494,7 @@ else
 fi
 
 # Check dynamic linker characteristics
-# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
 # Unlike libtool.m4, here we don't care about _all_ names of the library, but
 # only about the one the linker finds when passed -lNAME. This is the last
 # element of library_names_spec in libtool.m4, or possibly two of them if the
@@ -516,16 +505,11 @@ case "$host_os" in
   aix3*)
     library_names_spec='$libname.a'
     ;;
-  aix[4-9]*)
+  aix4* | aix5*)
     library_names_spec='$libname$shrext'
     ;;
   amigaos*)
-    case "$host_cpu" in
-      powerpc*)
-        library_names_spec='$libname$shrext' ;;
-      m68k)
-        library_names_spec='$libname.a' ;;
-    esac
+    library_names_spec='$libname.a'
     ;;
   beos*)
     library_names_spec='$libname$shrext'
@@ -533,7 +517,7 @@ case "$host_os" in
   bsdi[45]*)
     library_names_spec='$libname$shrext'
     ;;
-  cygwin* | mingw* | pw32* | cegcc*)
+  cygwin* | mingw* | pw32*)
     shrext=.dll
     library_names_spec='$libname.dll.a $libname.lib'
     ;;
@@ -544,18 +528,19 @@ case "$host_os" in
   dgux*)
     library_names_spec='$libname$shrext'
     ;;
-  freebsd[23].*)
-    library_names_spec='$libname$shrext$versuffix'
+  freebsd1*)
     ;;
   freebsd* | dragonfly*)
-    library_names_spec='$libname$shrext'
+    case "$host_os" in
+      freebsd[123]*)
+        library_names_spec='$libname$shrext$versuffix' ;;
+      *)
+        library_names_spec='$libname$shrext' ;;
+    esac
     ;;
   gnu*)
     library_names_spec='$libname$shrext'
     ;;
-  haiku*)
-    library_names_spec='$libname$shrext'
-    ;;
   hpux9* | hpux10* | hpux11*)
     case $host_cpu in
       ia64*)
@@ -591,7 +576,7 @@ case "$host_os" in
     ;;
   linux*oldld* | linux*aout* | linux*coff*)
     ;;
-  linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  linux* | k*bsd*-gnu)
     library_names_spec='$libname$shrext'
     ;;
   knetbsd*-gnu)
@@ -603,7 +588,7 @@ case "$host_os" in
   newsos6)
     library_names_spec='$libname$shrext'
     ;;
-  *nto* | *qnx*)
+  nto-qnx*)
     library_names_spec='$libname$shrext'
     ;;
   openbsd*)
@@ -634,9 +619,6 @@ case "$host_os" in
   sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
     library_names_spec='$libname$shrext'
     ;;
-  tpf*)
-    library_names_spec='$libname$shrext'
-    ;;
   uts4*)
     library_names_spec='$libname$shrext'
     ;;
similarity index 91%
rename from scripts/config.sub
rename to build-aux/config.sub
index a68f862..f9fcdc8 100755 (executable)
@@ -1,31 +1,38 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2015-01-01'
+timestamp='2011-06-03'
 
-# This file 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 3 of the License, or
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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.
 #
-# This program 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.
+# This program 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, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program.  This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
+# the same distribution terms that you use for the rest of that program.
 
 
-# Please send patches to <config-patches@gnu.org>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -68,7 +75,9 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -116,17 +125,13 @@ esac
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
   knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
   *)
     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
     if [ $basic_machine != $1 ]
@@ -149,7 +154,7 @@ case $os in
        -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
        -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
        -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray | -microblaze*)
+       -apple | -axis | -knuth | -cray | -microblaze)
                os=
                basic_machine=$1
                ;;
@@ -218,12 +223,6 @@ case $os in
        -isc*)
                basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
                ;;
-       -lynx*178)
-               os=-lynxos178
-               ;;
-       -lynx*5)
-               os=-lynxos5
-               ;;
        -lynx*)
                os=-lynxos
                ;;
@@ -248,28 +247,20 @@ case $basic_machine in
        # Some are omitted here because they have special meanings below.
        1750a | 580 \
        | a29k \
-       | aarch64 | aarch64_be \
        | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
        | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
        | am33_2.0 \
-       | arc | arceb \
-       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-       | avr | avr32 \
-       | be32 | be64 \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
        | bfin \
-       | c4x | c8051 | clipper \
+       | c4x | clipper \
        | d10v | d30v | dlx | dsp16xx \
-       | epiphany \
-       | fido | fr30 | frv | ft32 \
+       | fido | fr30 | frv \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-       | hexagon \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
-       | k1om \
-       | le32 | le64 \
        | lm32 \
        | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+       | maxq | mb | microblaze | mcore | mep | metag \
        | mips | mipsbe | mipseb | mipsel | mipsle \
        | mips16 \
        | mips64 | mips64el \
@@ -283,27 +274,24 @@ case $basic_machine in
        | mips64vr5900 | mips64vr5900el \
        | mipsisa32 | mipsisa32el \
        | mipsisa32r2 | mipsisa32r2el \
-       | mipsisa32r6 | mipsisa32r6el \
        | mipsisa64 | mipsisa64el \
        | mipsisa64r2 | mipsisa64r2el \
-       | mipsisa64r6 | mipsisa64r6el \
        | mipsisa64sb1 | mipsisa64sb1el \
        | mipsisa64sr71k | mipsisa64sr71kel \
-       | mipsr5900 | mipsr5900el \
        | mipstx39 | mipstx39el \
        | mn10200 | mn10300 \
        | moxie \
        | mt \
        | msp430 \
        | nds32 | nds32le | nds32be \
-       | nios | nios2 | nios2eb | nios2el \
+       | nios | nios2 \
        | ns16k | ns32k \
-       | open8 | or1k | or1knd | or32 \
+       | open8 \
+       | or32 \
        | pdp10 | pdp11 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle \
        | pyramid \
-       | riscv32 | riscv64 \
-       | rl78 | rx \
+       | rx \
        | score \
        | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
        | sh64 | sh64le \
@@ -313,7 +301,6 @@ case $basic_machine in
        | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
        | ubicom32 \
        | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-       | visium \
        | we32k \
        | x86 | xc16x | xstormy16 | xtensa \
        | z8k | z80)
@@ -328,10 +315,8 @@ case $basic_machine in
        c6x)
                basic_machine=tic6x-unknown
                ;;
-       leon|leon[3-9])
-               basic_machine=sparc-$basic_machine
-               ;;
-       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+       m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+               # Motorola 68HC11/12.
                basic_machine=$basic_machine-unknown
                os=-none
                ;;
@@ -344,10 +329,7 @@ case $basic_machine in
        strongarm | thumb | xscale)
                basic_machine=arm-unknown
                ;;
-       xgate)
-               basic_machine=$basic_machine-unknown
-               os=-none
-               ;;
+
        xscaleeb)
                basic_machine=armeb-unknown
                ;;
@@ -370,31 +352,25 @@ case $basic_machine in
        # Recognize the basic CPU types with company name.
        580-* \
        | a29k-* \
-       | aarch64-* | aarch64_be-* \
        | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
        | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
        | avr-* | avr32-* \
-       | be32-* | be64-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | c8051-* | clipper-* | craynv-* | cydra-* \
+       | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-       | hexagon-* \
        | i*86-* | i860-* | i960-* | ia64-* \
        | ip2k-* | iq2000-* \
-       | k1om-* \
-       | le32-* | le64-* \
        | lm32-* \
        | m32c-* | m32r-* | m32rle-* \
        | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-       | microblaze-* | microblazeel-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
        | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
        | mips16-* \
        | mips64-* | mips64el-* \
@@ -408,27 +384,23 @@ case $basic_machine in
        | mips64vr5900-* | mips64vr5900el-* \
        | mipsisa32-* | mipsisa32el-* \
        | mipsisa32r2-* | mipsisa32r2el-* \
-       | mipsisa32r6-* | mipsisa32r6el-* \
        | mipsisa64-* | mipsisa64el-* \
        | mipsisa64r2-* | mipsisa64r2el-* \
-       | mipsisa64r6-* | mipsisa64r6el-* \
        | mipsisa64sb1-* | mipsisa64sb1el-* \
        | mipsisa64sr71k-* | mipsisa64sr71kel-* \
-       | mipsr5900-* | mipsr5900el-* \
        | mipstx39-* | mipstx39el-* \
        | mmix-* \
        | mt-* \
        | msp430-* \
        | nds32-* | nds32le-* | nds32be-* \
-       | nios-* | nios2-* | nios2eb-* | nios2el-* \
+       | nios-* | nios2-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
        | open8-* \
-       | or1k*-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
        | pyramid-* \
-       | rl78-* | romp-* | rs6000-* | rx-* \
+       | romp-* | rs6000-* | rx-* \
        | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
        | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
@@ -441,7 +413,6 @@ case $basic_machine in
        | ubicom32-* \
        | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
        | vax-* \
-       | visium-* \
        | we32k-* \
        | x86-* | x86_64-* | xc16x-* | xps100-* \
        | xstormy16-* | xtensa*-* \
@@ -741,6 +712,7 @@ case $basic_machine in
        i370-ibm* | ibm*)
                basic_machine=i370-ibm
                ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
        i*86v32)
                basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
                os=-sysv32
@@ -779,9 +751,6 @@ case $basic_machine in
                basic_machine=m68k-isi
                os=-sysv
                ;;
-       leon-*|leon[3-9]-*)
-               basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
-               ;;
        m68knommu)
                basic_machine=m68k-unknown
                os=-linux
@@ -801,15 +770,11 @@ case $basic_machine in
                basic_machine=ns32k-utek
                os=-sysv
                ;;
-       microblaze*)
+       microblaze)
                basic_machine=microblaze-xilinx
                ;;
-       mingw64)
-               basic_machine=x86_64-pc
-               os=-mingw64
-               ;;
        mingw32)
-               basic_machine=i686-pc
+               basic_machine=i386-pc
                os=-mingw32
                ;;
        mingw32ce)
@@ -837,10 +802,6 @@ case $basic_machine in
                basic_machine=powerpc-unknown
                os=-morphos
                ;;
-       moxiebox)
-               basic_machine=moxie-unknown
-               os=-moxiebox
-               ;;
        msdos)
                basic_machine=i386-pc
                os=-msdos
@@ -848,18 +809,10 @@ case $basic_machine in
        ms1-*)
                basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
                ;;
-       msys)
-               basic_machine=i686-pc
-               os=-msys
-               ;;
        mvs)
                basic_machine=i370-ibm
                os=-mvs
                ;;
-       nacl)
-               basic_machine=le32-unknown
-               os=-nacl
-               ;;
        ncr3000)
                basic_machine=i486-ncr
                os=-sysv4
@@ -1040,11 +993,7 @@ case $basic_machine in
                basic_machine=i586-unknown
                os=-pw32
                ;;
-       rdos | rdos64)
-               basic_machine=x86_64-pc
-               os=-rdos
-               ;;
-       rdos32)
+       rdos)
                basic_machine=i386-pc
                os=-rdos
                ;;
@@ -1371,29 +1320,29 @@ case $os in
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
              | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
              | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-             | -sym* | -kopensolaris* | -plan9* \
+             | -sym* | -kopensolaris* \
              | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
              | -aos* | -aros* \
              | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
              | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
              | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -bitrig* | -openbsd* | -solidbsd* \
+             | -openbsd* | -solidbsd* \
              | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
              | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
              | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
              | -chorusos* | -chorusrdb* | -cegcc* \
-             | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-             | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -linux-android* \
+             | -linux-newlib* | -linux-uclibc* \
+             | -uxpv* | -beos* | -mpeix* | -udk* \
              | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
              | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
              | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
              | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
              | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
        -qnx*)
@@ -1517,6 +1466,9 @@ case $os in
        -aros*)
                os=-aros
                ;;
+       -kaos*)
+               os=-kaos
+               ;;
        -zvmoe)
                os=-zvmoe
                ;;
@@ -1565,12 +1517,6 @@ case $basic_machine in
        c4x-* | tic4x-*)
                os=-coff
                ;;
-       c8051-*)
-               os=-elf
-               ;;
-       hexagon-*)
-               os=-elf
-               ;;
        tic54x-*)
                os=-coff
                ;;
@@ -1598,6 +1544,9 @@ case $basic_machine in
                ;;
        m68000-sun)
                os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
                ;;
        m68*-cisco)
                os=-aout
@@ -1611,9 +1560,6 @@ case $basic_machine in
        mips*-*)
                os=-elf
                ;;
-       or1k-*)
-               os=-elf
-               ;;
        or32-*)
                os=-coff
                ;;
diff --git a/build-aux/depcomp b/build-aux/depcomp
new file mode 100755 (executable)
index 0000000..e1c6e34
--- /dev/null
@@ -0,0 +1,582 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2006-10-15.18
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
+# Foundation, Inc.
+
+# This program 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 3, or (at your option)
+# any later version.
+
+# This program 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
+  echo "       " >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/build-aux/getswdb.sh b/build-aux/getswdb.sh
new file mode 100755 (executable)
index 0000000..8b1d5e5
--- /dev/null
@@ -0,0 +1,152 @@
+#!/bin/sh
+# Get the online version of the GnuPG software version database
+# Copyright (C) 2014  Werner Koch
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# The URL of the file to retrieve.
+# (some wget versions seem to have problems with SubjectAltName, thus
+#  we do not use www.gnupg.org)
+urlbase="https://gnupg.org/"
+
+WGET=wget
+GPGV=gpgv
+
+srcdir=$(dirname "$0")
+distsigkey="$srcdir/../g10/distsigkey.gpg"
+
+# Convert a 3 part version number it a numeric value.
+cvtver () {
+  awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}'
+}
+
+# Prints usage information.
+usage()
+{
+    cat <<EOF
+Usage: $(basename $0) [OPTIONS]
+Get the online version of the GnuPG software version database
+Options:
+    --skip-download  Assume download has already been done.
+    --find-sha1sum   Print the name of the sha1sum utility
+    --help           Print this help.
+EOF
+    exit $1
+}
+
+#
+# Parse options
+#
+skip_download=no
+find_sha1sum=no
+while test $# -gt 0; do
+    case "$1" in
+       # Set up `optarg'.
+       --*=*)
+           optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
+           ;;
+       *)
+           optarg=""
+           ;;
+    esac
+
+    case $1 in
+        --help|-h)
+           usage 0
+           ;;
+        --skip-download)
+            skip_download=yes
+            ;;
+        --find-sha1sum)
+            find_sha1sum=yes
+            ;;
+       *)
+           usage 1 1>&2
+           ;;
+    esac
+    shift
+done
+
+# Mac OSX has only a shasum and not sha1sum
+if [ ${find_sha1sum} = yes ]; then
+    for i in sha1sum shasum ; do
+       tmp=$($i </dev/null 2>/dev/null | cut -d ' ' -f1)
+       if [ x"$tmp" = x"da39a3ee5e6b4b0d3255bfef95601890afd80709" ]; then
+           echo "$i"
+           exit 0
+       fi
+    done
+    echo "false"
+    exit 1
+fi
+
+# Get GnuPG version from VERSION file.  For a GIT checkout this means
+# that ./autogen.sh must have been run first.  For a regular tarball
+# VERSION is always available.
+if [ ! -f "$srcdir/../VERSION" ]; then
+    echo "VERSION file missing - run autogen.sh first." >&2
+    exit 1
+fi
+version=$(cat "$srcdir/../VERSION")
+version_num=$(echo "$version" | cvtver)
+
+if ! $GPGV --version >/dev/null 2>/dev/null ; then
+  echo "command \"gpgv\" is not installed" >&2
+  echo "(please install an older version of GnuPG)" >&2
+  exit 1
+fi
+
+#
+# Download the list and verify.
+#
+if [ $skip_download = yes ]; then
+  if [ ! -f swdb.lst ]; then
+      echo "swdb.lst is missing." >&2
+      exit 1
+  fi
+  if [ ! -f swdb.lst.sig ]; then
+      echo "swdb.lst.sig is missing." >&2
+      exit 1
+  fi
+else
+  if ! $WGET --version >/dev/null 2>/dev/null ; then
+      echo "command \"wget\" is not installed" >&2
+      exit 1
+  fi
+
+  if ! $WGET -q -O swdb.lst "$urlbase/swdb.lst" ; then
+      echo "download of swdb.lst failed." >&2
+      exit 1
+  fi
+  if ! $WGET -q -O swdb.lst.sig "$urlbase/swdb.lst.sig" ; then
+      echo "download of swdb.lst.sig failed." >&2
+      exit 1
+  fi
+fi
+if ! $GPGV --keyring "$distsigkey" swdb.lst.sig swdb.lst; then
+    echo "list of software versions is not valid!" >&2
+    exit 1
+fi
+
+#
+# Check that the online version of GnuPG is not less than this version
+# to help detect rollback attacks.
+#
+gnupg_ver=$(awk '$1=="gnupg21_ver" {print $2;exit}' swdb.lst)
+if [ -z "$gnupg_ver" ]; then
+    echo "GnuPG 2.1 version missing in swdb.lst!" >&2
+    exit 1
+fi
+gnupg_ver_num=$(echo "$gnupg_ver" | cvtver)
+if [ $(( $gnupg_ver_num >= $version_num )) = 0 ]; then
+    echo "GnuPG version in swdb.lst is less than this version!" >&2
+    echo "  This version: $version" >&2
+    echo "  SWDB version: $gnupg_ver" >&2
+    exit 1
+fi
diff --git a/build-aux/git-log-fix b/build-aux/git-log-fix
new file mode 100644 (file)
index 0000000..af702fe
--- /dev/null
@@ -0,0 +1,3 @@
+# This file is expected to be used via gitlog-to-changelog's --amend=FILE
+# option.  It specifies what changes to make to each given SHA1's commit
+# log and metadata, using Perl-eval'able expressions.
similarity index 67%
rename from scripts/git-log-footer
rename to build-aux/git-log-footer
index f707935..c31fe93 100644 (file)
@@ -6,9 +6,7 @@
        details.
 
         -----
-       Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                      2005, 2006, 2007, 2008, 2009, 2010, 2011,
-                      2012 Free Software Foundation, Inc.
+       Copyright (C) 2011 Free Software Foundation, Inc.
 
        Copying and distribution of this file and/or the original GIT
        commit log messages, with or without modification, are
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog
new file mode 100755 (executable)
index 0000000..5cf071f
--- /dev/null
@@ -0,0 +1,375 @@
+eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
+  & eval 'exec perl -wS "$0" $argv:q'
+    if 0;
+# Convert git log output to ChangeLog format.
+
+my $VERSION = '2012-01-24 15:58 (wk)'; # UTC
+# The definition above must lie within the first 8 lines in order
+# for the Emacs time-stamp write hook (at end) to update it.
+# If you change this file with Emacs, please let the write hook
+# do its job.  Otherwise, update this string manually.
+
+# Copyright (C) 2008-2012 Free Software Foundation, Inc.
+
+# This program 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 3 of the License, or
+# (at your option) any later version.
+
+# This program 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, see <http://www.gnu.org/licenses/>.
+
+# Written by Jim Meyering
+# Custom bugs bred by Werner Koch
+
+use strict;
+use warnings;
+use Getopt::Long;
+use POSIX qw(strftime);
+
+(my $ME = $0) =~ s|.*/||;
+
+# use File::Coda; # http://meyering.net/code/Coda/
+END {
+  defined fileno STDOUT or return;
+  close STDOUT and return;
+  warn "$ME: failed to close standard output: $!\n";
+  $? ||= 1;
+}
+
+sub usage ($)
+{
+  my ($exit_code) = @_;
+  my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
+  if ($exit_code != 0)
+    {
+      print $STREAM "Try `$ME --help' for more information.\n";
+    }
+  else
+    {
+      print $STREAM <<EOF;
+Usage: $ME [OPTIONS] [ARGS]
+
+Convert git log output to ChangeLog format.  If present, any ARGS
+are passed to "git log".  To avoid ARGS being parsed as options to
+$ME, they may be preceded by '--'.
+
+OPTIONS:
+
+   --amend=FILE FILE maps from an SHA1 to perl code (i.e., s/old/new/) that
+                  makes a change to SHA1's commit log text or metadata.
+   --append-dot append a dot to the first line of each commit message if
+                  there is no other punctuation or blank at the end.
+   --tear-off   tear off all commit log lines after a '--' line and
+                skip log entry with the first body line being '--'.
+   --since=DATE convert only the logs since DATE;
+                  the default is to convert all log entries.
+   --format=FMT set format string for commit subject and body;
+                  see 'man git-log' for the list of format metacharacters;
+                  the default is '%s%n%b%n'
+
+   --help       display this help and exit
+   --version    output version information and exit
+
+EXAMPLE:
+
+  $ME --since=2008-01-01 > ChangeLog
+  $ME -- -n 5 foo > last-5-commits-to-branch-foo
+
+In a FILE specified via --amend, comment lines (starting with "#") are ignored.
+FILE must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1 (alone on
+a line) referring to a commit in the current project, and CODE refers to one
+or more consecutive lines of Perl code.  Pairs must be separated by one or
+more blank line.
+
+Here is sample input for use with --amend=FILE, from coreutils:
+
+3a169f4c5d9159283548178668d2fae6fced3030
+# fix typo in title:
+s/all tile types/all file types/
+
+1379ed974f1fa39b12e2ffab18b3f7a607082202
+# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself.
+# Change the author to be Paul.  Note the escaped "@":
+s,Jim .*>,Paul Eggert <eggert\@cs.ucla.edu>,
+
+EOF
+    }
+  exit $exit_code;
+}
+
+# If the string $S is a well-behaved file name, simply return it.
+# If it contains white space, quotes, etc., quote it, and return the new string.
+sub shell_quote($)
+{
+  my ($s) = @_;
+  if ($s =~ m![^\w+/.,-]!)
+    {
+      # Convert each single quote to '\''
+      $s =~ s/\'/\'\\\'\'/g;
+      # Then single quote the string.
+      $s = "'$s'";
+    }
+  return $s;
+}
+
+sub quoted_cmd(@)
+{
+  return join (' ', map {shell_quote $_} @_);
+}
+
+# Parse file F.
+# Comment lines (starting with "#") are ignored.
+# F must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1
+# (alone on a line) referring to a commit in the current project, and
+# CODE refers to one or more consecutive lines of Perl code.
+# Pairs must be separated by one or more blank line.
+sub parse_amend_file($)
+{
+  my ($f) = @_;
+
+  open F, '<', $f
+    or die "$ME: $f: failed to open for reading: $!\n";
+
+  my $fail;
+  my $h = {};
+  my $in_code = 0;
+  my $sha;
+  while (defined (my $line = <F>))
+    {
+      $line =~ /^\#/
+        and next;
+      chomp $line;
+      $line eq ''
+        and $in_code = 0, next;
+
+      if (!$in_code)
+        {
+          $line =~ /^([0-9a-fA-F]{40})$/
+            or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"),
+              $fail = 1, next;
+          $sha = lc $1;
+          $in_code = 1;
+          exists $h->{$sha}
+            and (warn "$ME: $f:$.: duplicate SHA1\n"),
+              $fail = 1, next;
+        }
+      else
+        {
+          $h->{$sha} ||= '';
+          $h->{$sha} .= "$line\n";
+        }
+    }
+  close F;
+
+  $fail
+    and exit 1;
+
+  return $h;
+}
+
+{
+  my $since_date;
+  my $format_string = '%s%n%b%n';
+  my $amend_file;
+  my $append_dot = 0;
+  my $tear_off = 0;
+  GetOptions
+    (
+     help => sub { usage 0 },
+     version => sub { print "$ME version $VERSION\n"; exit },
+     'since=s' => \$since_date,
+     'format=s' => \$format_string,
+     'amend=s' => \$amend_file,
+     'append-dot' => \$append_dot,
+     'tear-off' => \$tear_off,
+    ) or usage 1;
+
+
+  defined $since_date
+    and unshift @ARGV, "--since=$since_date";
+
+  # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/)
+  # that makes a correction in the log or attribution of that commit.
+  my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {};
+
+  my @cmd = (qw (git log --log-size),
+             '--pretty=format:%H:%ct  %an  <%ae>%n%n'.$format_string, @ARGV);
+  open PIPE, '-|', @cmd
+    or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n"
+            . "(Is your Git too old?  Version 1.5.1 or later is required.)\n");
+
+  my $prev_date_line = '';
+  my @prev_coauthors = ();
+
+  while (1)
+    {
+      defined (my $in = <PIPE>)
+        or last;
+      $in =~ /^log size (\d+)$/
+        or die "$ME:$.: Invalid line (expected log size):\n$in";
+      my $log_nbytes = $1;
+
+      my $log;
+      my $n_read = read PIPE, $log, $log_nbytes;
+      $n_read == $log_nbytes
+        or die "$ME:$.: unexpected EOF\n";
+
+      # Skip log entries with the default merge commit message.
+      $log =~ /^.*\n\nMerge branch '.*\n\s*/
+        and goto SKIPCOMMIT;
+
+      # Skip log entries if the body starts with a tear off marker.
+      if ($tear_off)
+        {
+          $log =~ /^.*\n\n.*\n--\s*/
+            and goto SKIPCOMMIT;
+        }
+
+      # Extract leading hash.
+      my ($sha, $rest) = split ':', $log, 2;
+      defined $sha
+        or die "$ME:$.: malformed log entry\n";
+      $sha =~ /^[0-9a-fA-F]{40}$/
+        or die "$ME:$.: invalid SHA1: $sha\n";
+
+      # If this commit's log requires any transformation, do it now.
+      my $code = $amend_code->{$sha};
+      if (defined $code)
+        {
+          eval 'use Safe';
+          my $s = new Safe;
+          # Put the unpreprocessed entry into "$_".
+          $_ = $rest;
+
+          # Let $code operate on it, safely.
+          my $r = $s->reval("$code")
+            or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n";
+
+          # Note that we've used this entry.
+          delete $amend_code->{$sha};
+
+          # Update $rest upon success.
+          $rest = $_;
+        }
+
+      my @line = split "\n", $rest;
+      my $author_line = shift @line;
+      defined $author_line
+        or die "$ME:$.: unexpected EOF\n";
+      $author_line =~ /^(\d+)  (.*>)$/
+        or die "$ME:$.: Invalid line "
+          . "(expected date/author/email):\n$author_line\n";
+
+      my $date_line = sprintf "%s  $2\n", strftime ("%F", localtime ($1));
+
+      # Format 'Co-authored-by: A U Thor <email@example.com>' lines in
+      # standard multi-author ChangeLog format.
+      my @coauthors = grep /^Co-authored-by:.*$/, @line;
+      for (@coauthors)
+        {
+          s/^Co-authored-by:\s*/\t    /;
+          s/\s*</  </;
+
+          /<.*?@.*\..*>/
+            or warn "$ME: warning: missing email address for "
+              . substr ($_, 5) . "\n";
+        }
+
+      # If this header would be the same as the previous date/name/email/
+      # coauthors header, then arrange not to print it.
+      if ($date_line ne $prev_date_line or "@coauthors" ne "@prev_coauthors")
+        {
+          $prev_date_line eq ''
+            or print "\n";
+          print $date_line;
+          @coauthors
+            and print join ("\n", @coauthors), "\n";
+        }
+      $prev_date_line = $date_line;
+      @prev_coauthors = @coauthors;
+
+      # Omit "Co-authored-by..." and "Signed-off-by..." lines.
+      @line = grep !/^Signed-off-by: .*>$/, @line;
+      @line = grep !/^Co-authored-by: /, @line;
+
+      # Remove everything after a line with 2 dashes at the beginning.
+      if ($tear_off)
+        {
+           my @tmpline;
+           foreach (@line)
+             {
+              last if /^--\s*$/;
+               push @tmpline,$_;
+             }
+           @line = @tmpline;
+        }
+
+      # Remove leading and trailing blank lines.
+      if (@line)
+        {
+          while ($line[0] =~ /^\s*$/) { shift @line; }
+          while ($line[$#line] =~ /^\s*$/) { pop @line; }
+        }
+
+      # If there were any lines
+      if (@line == 0)
+        {
+          warn "$ME: warning: empty commit message:\n  $date_line\n";
+        }
+      else
+        {
+          if ($append_dot)
+            {
+              # If the first line of the message has enough room, then
+              if (length $line[0] < 72)
+                {
+                  # append a dot if there is no other punctuation or blank
+                  # at the end.
+                  $line[0] =~ /[[:punct:]\s]$/
+                    or $line[0] .= '.';
+                }
+            }
+
+          # Prefix each non-empty line with a TAB.
+          @line = map { length $_ ? "\t$_" : '' } @line;
+
+          print "\n", join ("\n", @line), "\n";
+        }
+
+    SKIPCOMMIT:
+      defined ($in = <PIPE>)
+        or last;
+      $in ne "\n"
+        and die "$ME:$.: unexpected line:\n$in";
+    }
+
+  close PIPE
+    or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n";
+  # FIXME-someday: include $PROCESS_STATUS in the diagnostic
+
+  # Complain about any unused entry in the --amend=F specified file.
+  my $fail = 0;
+  foreach my $sha (keys %$amend_code)
+    {
+      warn "$ME:$amend_file: unused entry: $sha\n";
+      $fail = 1;
+    }
+
+  exit $fail;
+}
+
+# Local Variables:
+# mode: perl
+# indent-tabs-mode: nil
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "my $VERSION = '"
+# time-stamp-format: "%:y-%02m-%02d %02H:%02M (wk)"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "'; # UTC"
+# End:
similarity index 69%
rename from scripts/install-sh
rename to build-aux/install-sh
index 377bb86..4fbbae7 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2011-11-20.07; # UTC
+scriptversion=2006-10-14.15
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,7 +35,7 @@ scriptversion=2011-11-20.07; # UTC
 # FSF changes to this file are in the public domain.
 #
 # Calling this script install-sh is preferred over install.sh, to prevent
-# 'make' implicit rules from creating a file called install from it
+# `make' implicit rules from creating a file called install from it
 # when there is no Makefile.
 #
 # This script is compatible with the BSD install script, but was written
@@ -48,7 +48,7 @@ IFS=" ""      $nl"
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
+doit="${DOITPROG-}"
 if test -z "$doit"; then
   doit_exec=exec
 else
@@ -58,49 +58,34 @@ fi
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
 
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
-  test "$posix_glob" != "?" || {
-    if (set -f) 2>/dev/null; then
-      posix_glob=
-    else
-      posix_glob=:
-    fi
-  }
-'
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
 
+posix_glob=
 posix_mkdir=
 
 # Desired mode of installed file.
 mode=0755
 
-chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
+chgrpcmd=
 stripcmd=
-
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
 src=
 dst=
 dir_arg=
-dst_arg=
-
-copy_on_change=false
+dstarg=
 no_target_directory=
 
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
    or: $0 [OPTION]... SRCFILES... DIRECTORY
    or: $0 [OPTION]... -t DIRECTORY SRCFILES...
    or: $0 [OPTION]... -d DIRECTORIES...
@@ -110,59 +95,65 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
 In the 4th, create DIRECTORIES.
 
 Options:
-     --help     display this help and exit.
-     --version  display version info and exit.
-
-  -c            (ignored)
-  -C            install only if different (preserve the last data modification time)
-  -d            create directories instead of installing files.
-  -g GROUP      $chgrpprog installed files to GROUP.
-  -m MODE       $chmodprog installed files to MODE.
-  -o USER       $chownprog installed files to USER.
-  -s            $stripprog installed files.
-  -t DIRECTORY  install into DIRECTORY.
-  -T            report an error if DSTFILE is a directory.
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
 
 Environment variables override the default commands:
-  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
-  RMPROG STRIPPROG
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
 "
 
 while test $# -ne 0; do
   case $1 in
-    -c) ;;
+    -c) shift
+        continue;;
 
-    -C) copy_on_change=true;;
-
-    -d) dir_arg=true;;
+    -d) dir_arg=true
+        shift
+        continue;;
 
     -g) chgrpcmd="$chgrpprog $2"
-       shift;;
+        shift
+        shift
+        continue;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
+        shift
+        shift
        case $mode in
          *' '* | *'    '* | *'
 '*       | *'*'* | *'?'* | *'['*)
            echo "$0: invalid mode: $mode" >&2
            exit 1;;
        esac
-       shift;;
+        continue;;
 
     -o) chowncmd="$chownprog $2"
-       shift;;
+        shift
+        shift
+        continue;;
 
-    -s) stripcmd=$stripprog;;
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
 
-    -t) dst_arg=$2
-       # Protect names problematic for 'test' and other utilities.
-       case $dst_arg in
-         -* | [=\(\)!]) dst_arg=./$dst_arg;;
-       esac
-       shift;;
+    -t) dstarg=$2
+       shift
+       shift
+       continue;;
 
-    -T) no_target_directory=true;;
+    -T) no_target_directory=true
+       shift
+       continue;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
@@ -174,26 +165,21 @@ while test $# -ne 0; do
 
     *)  break;;
   esac
-  shift
 done
 
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
   # Otherwise, the last argument is the destination.  Remove it from $@.
   for arg
   do
-    if test -n "$dst_arg"; then
+    if test -n "$dstarg"; then
       # $@ is not empty: it contains at least $arg.
-      set fnord "$@" "$dst_arg"
+      set fnord "$@" "$dstarg"
       shift # fnord
     fi
     shift # arg
-    dst_arg=$arg
-    # Protect names problematic for 'test' and other utilities.
-    case $dst_arg in
-      -* | [=\(\)!]) dst_arg=./$dst_arg;;
-    esac
+    dstarg=$arg
   done
 fi
 
@@ -202,17 +188,13 @@ if test $# -eq 0; then
     echo "$0: no input file specified." >&2
     exit 1
   fi
-  # It's OK to call 'install-sh -d' without argument.
+  # It's OK to call `install-sh -d' without argument.
   # This can happen when creating conditional directories.
   exit 0
 fi
 
 if test -z "$dir_arg"; then
-  do_exit='(exit $ret); exit $ret'
-  trap "ret=129; $do_exit" 1
-  trap "ret=130; $do_exit" 2
-  trap "ret=141; $do_exit" 13
-  trap "ret=143; $do_exit" 15
+  trap '(exit $?); exit' 1 2 13 15
 
   # Set umask so as not to create temps with too-generous modes.
   # However, 'strip' requires both read and write access to temps.
@@ -240,9 +222,9 @@ fi
 
 for src
 do
-  # Protect names problematic for 'test' and other utilities.
+  # Protect names starting with `-'.
   case $src in
-    -* | [=\(\)!]) src=./$src;;
+    -*) src=./$src ;;
   esac
 
   if test -n "$dir_arg"; then
@@ -260,17 +242,22 @@ do
       exit 1
     fi
 
-    if test -z "$dst_arg"; then
+    if test -z "$dstarg"; then
       echo "$0: no destination specified." >&2
       exit 1
     fi
-    dst=$dst_arg
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
       if test -n "$no_target_directory"; then
-       echo "$0: $dst_arg: Is a directory" >&2
+       echo "$0: $dstarg: Is a directory" >&2
        exit 1
       fi
       dstdir=$dst
@@ -354,7 +341,7 @@ do
              if test -z "$dir_arg" || {
                   # Check for POSIX incompatibilities with -m.
                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                  # other-writable bit of parent directory when it shouldn't.
+                  # other-writeable bit of parent directory when it shouldn't.
                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
                   case $ls_ld_tmpdir in
@@ -391,26 +378,33 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-       /*) prefix='/';;
-       [-=\(\)!]*) prefix='./';;
-       *)  prefix='';;
+       /*) prefix=;;
+       -*) prefix=./ ;;
+       *)  prefix= ;;
       esac
 
-      eval "$initialize_posix_glob"
+      case $posix_glob in
+        '')
+         if (set -f) 2>/dev/null; then
+           posix_glob=true
+         else
+           posix_glob=false
+         fi ;;
+      esac
 
       oIFS=$IFS
       IFS=/
-      $posix_glob set -f
+      $posix_glob && set -f
       set fnord $dstdir
       shift
-      $posix_glob set +f
+      $posix_glob && set +f
       IFS=$oIFS
 
       prefixes=
 
       for d
       do
-       test X"$d" = X && continue
+       test -z "$d" && continue
 
        prefix=$prefix$d
        if test -d "$prefix"; then
@@ -465,54 +459,41 @@ do
     # ignore errors from any of these, just make sure not to ignore
     # errors from the above "$doit $cpprog $src $dsttmp" command.
     #
-    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
-    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
-    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
-    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
-    # If -C, don't bother to copy if it wouldn't change the file.
-    if $copy_on_change &&
-       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
-       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
-       eval "$initialize_posix_glob" &&
-       $posix_glob set -f &&
-       set X $old && old=:$2:$4:$5:$6 &&
-       set X $new && new=:$2:$4:$5:$6 &&
-       $posix_glob set +f &&
-
-       test "$old" = "$new" &&
-       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
-    then
-      rm -f "$dsttmp"
-    else
-      # Rename the file to the real destination.
-      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
-      # The rename failed, perhaps because mv can't rename something else
-      # to itself, or perhaps because mv is so ancient that it does not
-      # support -f.
-      {
-       # Now remove or move aside any old file at destination location.
-       # We try this two ways since rm can't unlink itself on some
-       # systems and the destination file might be busy for other
-       # reasons.  In this case, the final cleanup might fail but the new
-       # file should still install successfully.
-       {
-         test ! -f "$dst" ||
-         $doit $rmcmd -f "$dst" 2>/dev/null ||
-         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
-         } ||
-         { echo "$0: cannot unlink or rename $dst" >&2
-           (exit 1); exit 1
-         }
-       } &&
-
-       # Now rename the file to the real destination.
-       $doit $mvcmd "$dsttmp" "$dst"
-      }
-    fi || exit 1
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
+      || {
+          # The rename failed, perhaps because mv can't rename something else
+          # to itself, or perhaps because mv is so ancient that it does not
+          # support -f.
+
+          # Now remove or move aside any old file at destination location.
+          # We try this two ways since rm can't unlink itself on some
+          # systems and the destination file might be busy for other
+          # reasons.  In this case, the final cleanup might fail but the new
+          # file should still install successfully.
+          {
+            if test -f "$dst"; then
+              $doit $rmcmd -f "$dst" 2>/dev/null \
+              || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
+                    && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
+              || {
+                echo "$0: cannot unlink or rename $dst" >&2
+                (exit 1); exit 1
+              }
+            else
+              :
+            fi
+          } &&
+
+          # Now rename the file to the real destination.
+          $doit $mvcmd "$dsttmp" "$dst"
+        }
+    } || exit 1
 
     trap '' 0
   fi
@@ -522,6 +503,5 @@ done
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
+# time-stamp-end: "$"
 # End:
similarity index 75%
rename from scripts/mail-to-translators
rename to build-aux/mail-to-translators
index be7291f..6937b59 100755 (executable)
@@ -2,7 +2,7 @@
 # mail a compressed version of the current translation to the Last-Translator
 #
 
-# Remove the colon to armor this script.
+# remove the colon to armor this script.
 SENDMAIL=": /usr/sbin/sendmail"
 
 LC_ALL=C
@@ -13,19 +13,19 @@ for file in *.po; do
     if [ -z "$addr" ]; then
     addr=$(awk '/Last-Translator:/ { printf "%s", $0; exit 0}' $file | sed 's/.*\(<.*>\).*/\1/')
     fi
-    ll=$(basename $file .po)    
+    ll=$(basename $file .po)
 
     if ! msgfmt -vc $file 2>&1| egrep -q 'fuzzy|untranslated|error'; then
         echo "$file: okay" >&2
         continue;
-    fi    
+    fi
 
     if ! echo "$addr" | grep -q @ ; then
         echo "$file: no translator known" >&2
         continue;
     fi
 
-    echo "$file: sending to $addr" >&2
+    echo "$file: sending to $addr"
     ( cat <<EOF
 From: translations@gnupg.org
 To: $addr
@@ -40,20 +40,21 @@ Content-Type: multipart/mixed; boundary="=-=-="
 Hi!
 
 We are preparing for a new 2.0 release of GnuPG and like you to ask to
-update your translation.  Unfortunately there is not much time left;
-we can only include updates we receive by XXXXXXXXXXXXXX UTC.
+update your translation.
 
 Please find attached the very latest version of the PO file for your
 GnuPG translation ($file).
 
 It is important to have a basic understanding of GnuPG's functionality
 to do a correct translation.  A false translation might lead to
-security problems.  Please do *not to use the TP Robot* for GnuPG.
+security problems.  Furthermore the TP Robot is not able to handle
+more than one version of a project (we maintain 1.4 and 2.0) and thus
+I'd ask you *not to use the TP Robot* for GnuPG.
 
-A release candidate for 2.0.xx is available at:
+The release candidate for 2.0.10 is available at:
 
-  ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/
-  ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/
+  ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/gnupg-2.0.10rc1.tar.bz2
+  ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/gnupg-2.0.10rc1.tar.bz2.sig
 
 Output of msgfmt is:
 $(msgfmt --check --statistics $file 2>&1 | head)
@@ -75,7 +76,7 @@ Content-Transfer-Encoding: base64
 
 EOF
 
-bzip2 <$file | mimencode 
+bzip2 <$file | mimencode
 
 echo ""
 echo "--=-=-=--"
@@ -83,4 +84,3 @@ echo ""
     ) | $SENDMAIL -oi "$addr"
 
 done
-
similarity index 80%
rename from scripts/mdate-sh
rename to build-aux/mdate-sh
index b3719cf..9a6d216 100755 (executable)
@@ -1,9 +1,10 @@
 #!/bin/sh
 # Get modification time of a file or directory and pretty-print it.
 
-scriptversion=2010-08-21.06; # UTC
+scriptversion=2005-06-29.22
 
-# Copyright (C) 1995-2013 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software
+# Foundation, Inc.
 # written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
 #
 # This program is free software; you can redistribute it and/or modify
@@ -17,8 +18,7 @@ scriptversion=2010-08-21.06; # UTC
 # 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, see <http://www.gnu.org/licenses/>.
-
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
@@ -28,26 +28,16 @@ scriptversion=2010-08-21.06; # UTC
 # bugs to <bug-automake@gnu.org> or send patches to
 # <automake-patches@gnu.org>.
 
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-fi
-
 case $1 in
   '')
-     echo "$0: No file.  Try '$0 --help' for more information." 1>&2
+     echo "$0: No file.  Try \`$0 --help' for more information." 1>&2
      exit 1;
      ;;
   -h | --h*)
     cat <<\EOF
 Usage: mdate-sh [--help] [--version] FILE
 
-Pretty-print the modification day of FILE, in the format:
-1 January 1970
+Pretty-print the modification time of FILE.
 
 Report bugs to <bug-automake@gnu.org>.
 EOF
@@ -59,13 +49,6 @@ EOF
     ;;
 esac
 
-error ()
-{
-  echo "$0: $1" >&2
-  exit 1
-}
-
-
 # Prevent date giving response in another language.
 LANG=C
 export LANG
@@ -75,7 +58,7 @@ LC_TIME=C
 export LC_TIME
 
 # GNU ls changes its time format in response to the TIME_STYLE
-# variable.  Since we cannot assume 'unset' works, revert this
+# variable.  Since we cannot assume `unset' works, revert this
 # variable to its documented default.
 if test "${TIME_STYLE+set}" = set; then
   TIME_STYLE=posix-long-iso
@@ -90,32 +73,27 @@ if ls -L /dev/null 1>/dev/null 2>&1; then
 else
   ls_command='ls -l -d'
 fi
-# Avoid user/group names that might have spaces, when possible.
-if ls -n /dev/null 1>/dev/null 2>&1; then
-  ls_command="$ls_command -n"
-fi
 
-# A 'ls -l' line looks as follows on OS/2.
+# A `ls -l' line looks as follows on OS/2.
 #  drwxrwx---        0 Aug 11  2001 foo
 # This differs from Unix, which adds ownership information.
 #  drwxrwx---   2 root  root      4096 Aug 11  2001 foo
 #
 # To find the date, we split the line on spaces and iterate on words
 # until we find a month.  This cannot work with files whose owner is a
-# user named "Jan", or "Feb", etc.  However, it's unlikely that '/'
+# user named `Jan', or `Feb', etc.  However, it's unlikely that `/'
 # will be owned by a user whose name is a month.  So we first look at
 # the extended ls output of the root directory to decide how many
 # words should be skipped to get the date.
 
 # On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
-set x`$ls_command /`
+set x`ls -l -d /`
 
 # Find which argument is the month.
 month=
 command=
 until test $month
 do
-  test $# -gt 0 || error "failed parsing '$ls_command /' output"
   shift
   # Add another shift to the command.
   command="$command shift;"
@@ -135,10 +113,8 @@ do
   esac
 done
 
-test -n "$month" || error "failed parsing '$ls_command /' output"
-
 # Get the extended ls output of the file or directory.
-set dummy x`eval "$ls_command \"\\\$save_arg1\""`
+set dummy x`eval "$ls_command \"\$save_arg1\""`
 
 # Remove all preceding arguments
 eval $command
@@ -219,6 +195,5 @@ echo $day $month $year
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
+# time-stamp-end: "$"
 # End:
diff --git a/build-aux/missing b/build-aux/missing
new file mode 100755 (executable)
index 0000000..cff574b
--- /dev/null
@@ -0,0 +1,365 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2006-05-10.23
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program 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 3, or (at your option)
+# any later version.
+
+# This program 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case $1 in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $1 in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+       case $LASTARG in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if test ! -f y.tab.h; then
+       echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+       case $LASTARG in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if test ! -f lex.yy.c; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit 1
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+       /^@setfilename/{
+         s/.* \([^ ]*\) *$/\1/
+         p
+         q
+       }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+       case $firstarg in
+       *o*)
+           firstarg=`echo "$firstarg" | sed s/o//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+       case $firstarg in
+       *h*)
+           firstarg=`echo "$firstarg" | sed s/h//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
similarity index 93%
rename from scripts/mkinstalldirs
rename to build-aux/mkinstalldirs
index 55d537f..ef7e16f 100755 (executable)
@@ -1,7 +1,7 @@
 #! /bin/sh
 # mkinstalldirs --- make directory hierarchy
 
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2006-05-11.19
 
 # Original author: Noah Friedman <friedman@prep.ai.mit.edu>
 # Created: 1993-05-16
@@ -81,9 +81,9 @@ case $dirmode in
       echo "mkdir -p -- $*"
       exec mkdir -p -- "$@"
     else
-      # On NextStep and OpenStep, the 'mkdir' command does not
+      # On NextStep and OpenStep, the `mkdir' command does not
       # recognize any option.  It will interpret all options as
-      # directories to create, and then abort because '.' already
+      # directories to create, and then abort because `.' already
       # exists.
       test -d ./-p && rmdir ./-p
       test -d ./--version && rmdir ./--version
@@ -157,6 +157,5 @@ exit $errstatus
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
+# time-stamp-end: "$"
 # End:
diff --git a/build-aux/potomo b/build-aux/potomo
new file mode 100755 (executable)
index 0000000..b4c0a6b
--- /dev/null
@@ -0,0 +1,64 @@
+#!/bin/sh
+# potomo - Convert a .po file to an utf-8 encoded .mo file.
+# Copyright 2008 g10 Code GmbH
+# Copyright 2010 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.
+
+# This script is used to create the mo files for applications using
+# the simple gettext implementation provided by libgpg-error.  That
+# gettext can only cope with utf-8 encoded mo files; thus we make this
+# sure while creating the mo.  A conversion is not done if the source
+# file does not exist or if it is not newer than the mo file.
+
+if [ "$1" = "--get-linguas" -a $# -eq 2 ]; then
+   if [ ! -f "$2/LINGUAS" ]; then
+       echo "potomo: directory '$2' has no LINGUAS file" >&2
+       exit 1
+   fi
+   echo $(sed -e "/^#/d" -e "s/#.*//" "$2"/LINGUAS)
+   exit 0
+fi
+
+if [ $# -ne 2 ]; then
+  echo "usage: potomo INFILE.PO OUTFILE.MO" >&2
+  echo "       potomo --get-linguas DIR"    >&2
+  exit 1
+fi
+infile="$1"
+outfile="$2"
+
+if [ ! -f "$infile" ]; then
+  echo "potomo: '$infile' not found - ignored" 2>&1
+  exit 0
+fi
+
+if [ "$outfile" -nt "$infile" ]; then
+  echo "potomo: '$outfile' is newer than source - keeping" 2>&1
+  exit 0
+fi
+
+# Note that we could use the newer msgconv.  However this tool was not
+# widely available back in 2008.
+
+fromset=`sed -n '/^"Content-Type:/ s/.*charset=\([a-zA-Z0-9_-]*\).*/\1/p' \
+         "$infile"`
+
+case "$fromset" in
+    utf8|utf-8|UTF8|UTF-8)
+        echo "potomo: '$infile' keeping $fromset" >&2
+        msgfmt --output-file="$outfile" "$infile"
+        ;;
+    *)
+        echo "potomo: '$infile' converting from $fromset to utf-8" >&2
+        iconv --silent --from-code=$fromset --to-code=utf-8 < "$infile" |\
+            sed "/^\"Content-Type:/ s/charset=[a-zA-Z0-9_-]*/charset=utf-8/"|\
+            msgfmt --output-file="$outfile" -
+        ;;
+esac
diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk
new file mode 100644 (file)
index 0000000..b7bcf06
--- /dev/null
@@ -0,0 +1,1066 @@
+# speedo.mk - Speedo rebuilds speedily.
+# Copyright (C) 2008, 2014 g10 Code GmbH
+#
+# speedo 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 3 of the License, or
+# (at your option) any later version.
+#
+# speedo 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, see <http://www.gnu.org/licenses/>.
+
+# speedo builds gnupg-related packages from GIT and installs them in a
+# user directory, thereby providing a non-obstrusive test environment.
+# speedo does only work with GNU make.  The build system is similar to
+# that of gpg4win.  The following commands are supported:
+#
+#   make -f speedo.mk all  pkg2rep=/dir/with/tarballs
+# or
+#   make -f speedo.mk
+#
+# Builds all packages and installs them under PLAY/inst.  At the end,
+# speedo prints commands that can be executed in the local shell to
+# make use of the installed packages.
+#
+#   make -f speedo.mk clean
+# or
+#   make -f speedo.mk clean-PACKAGE
+#
+# Removes all packages or the package PACKAGE from the installation
+# and build tree.  A subsequent make will rebuild these (and only
+# these) packages.
+#
+#   make -f speedo.mk report
+# or
+#   make -f speedo.mk report-PACKAGE
+#
+# Lists packages and versions.
+#
+
+# We need to know our own name.
+SPEEDO_MK := $(realpath $(lastword $(MAKEFILE_LIST)))
+
+.PHONY : help native native-gui w32-installer w32-source
+.PHONY :      git-native git-native-gui git-w32-installer git-w32-source
+.PHONY :      this-native this-native-gui this-w32-installer this-w32-source
+
+help:
+       @echo 'usage: make -f speedo.mk TARGET'
+       @echo '       with TARGET being one of:'
+       @echo '  help           This help'
+       @echo '  native         Native build of the GnuPG core'
+       @echo '  native-gui     Ditto but with pinentry and GPA'
+       @echo '  w32-installer  Build a Windows installer'
+       @echo '  w32-source     Pack a source archive'
+       @echo
+       @echo 'You may append INSTALL_REFIX=<dir> for native builds.'
+       @echo 'Prepend TARGET with "git-" to build from GIT repos.'
+       @echo 'Prepend TARGET with "this-" to build from the source tarball.'
+
+
+SPEEDOMAKE := $(MAKE) -f $(SPEEDO_MK) UPD_SWDB=1
+
+native: check-tools
+       $(SPEEDOMAKE) TARGETOS=native WHAT=release WITH_GUI=0 all
+
+git-native: check-tools
+       $(SPEEDOMAKE) TARGETOS=native WHAT=git     WITH_GUI=0 all
+
+this-native: check-tools
+       $(SPEEDOMAKE) TARGETOS=native WHAT=this    WITH_GUI=0 all
+
+native-gui: check-tools
+       $(SPEEDOMAKE) TARGETOS=native WHAT=release WITH_GUI=1 all
+
+git-native-gui: check-tools
+       $(SPEEDOMAKE) TARGETOS=native WHAT=git     WITH_GUI=1 all
+
+this-native-gui: check-tools
+       $(SPEEDOMAKE) TARGETOS=native WHAT=this    WITH_GUI=1 all
+
+w32-installer: check-tools
+       $(SPEEDOMAKE) TARGETOS=w32    WHAT=release WITH_GUI=1 installer
+
+git-w32-installer: check-tools
+       $(SPEEDOMAKE) TARGETOS=w32    WHAT=git     WITH_GUI=1 installer
+
+this-w32-installer: check-tools
+       $(SPEEDOMAKE) TARGETOS=w32    WHAT=this    WITH_GUI=1 installer
+
+w32-source: check-tools
+       $(SPEEDOMAKE) TARGETOS=w32    WHAT=release WITH_GUI=1 dist-source
+
+git-w32-source: check-tools
+       $(SPEEDOMAKE) TARGETOS=w32    WHAT=git     WITH_GUI=1 dist-source
+
+this-w32-source: check-tools
+       $(SPEEDOMAKE) TARGETOS=w32    WHAT=git     WITH_GUI=1 dist-source
+
+
+# Set this to "git" to build from git,
+#          to "release" from tarballs,
+#          to "this" from the unpacked sources.
+WHAT=git
+
+# Set target to "native" or "w32"
+TARGETOS=
+
+# Set to 1 to build the GUI tools
+WITH_GUI=0
+
+# Set to 1 to really download the swdb.
+UPD_SWDB=0
+
+# Set to the location of the directory with tarballs of
+# external packages.
+TARBALLS=$(shell pwd)/../tarballs
+
+#  Number of parallel make jobs
+MAKE_J=3
+
+# Name to use for the w32 installer and sources
+INST_NAME=gnupg-w32
+
+# Use this to override the installaion directory for native builds.
+INSTALL_PREFIX=none
+
+
+# Directory names.
+# They must be absolute, as we switch directories pretty often.
+root := $(shell pwd)/PLAY
+sdir := $(root)/src
+bdir := $(root)/build
+bdir6:= $(root)/build-w64
+ifeq ($(INSTALL_PREFIX),none)
+idir := $(root)/inst
+else
+idir := $(abspath $(INSTALL_PREFIX))
+endif
+idir6:= $(root)/inst-w64
+stampdir := $(root)/stamps
+topsrc := $(shell cd $(dir $(SPEEDO_MK)).. && pwd)
+auxsrc := $(topsrc)/build-aux/speedo
+patdir := $(topsrc)/build-aux/speedo/patches
+w32src := $(topsrc)/build-aux/speedo/w32
+
+# =====BEGIN LIST OF PACKAGES=====
+# The packages that should be built.  The order is also the build order.
+# Fixme: Do we need to build pkg-config for cross-building?
+
+speedo_spkgs  = \
+       libgpg-error npth libgcrypt
+
+ifeq ($(TARGETOS),w32)
+speedo_spkgs += \
+       zlib bzip2 libiconv gettext
+endif
+
+speedo_spkgs += \
+       libassuan libksba gnupg
+
+ifeq ($(TARGETOS),w32)
+speedo_spkgs += \
+       libffi glib pkg-config
+endif
+
+speedo_spkgs += \
+       gpgme
+
+ifeq ($(TARGETOS),w32)
+speedo_spkgs += \
+       libpng \
+       gdk-pixbuf atk pixman cairo pango gtk+
+endif
+
+
+ifeq ($(WITH_GUI),1)
+speedo_spkgs += \
+       pinentry gpa
+endif
+
+ifeq ($(TARGETOS),w32)
+speedo_spkgs += \
+       gpgex
+endif
+
+# =====END LIST OF PACKAGES=====
+
+
+# Packages which are additionally build for 64 bit Windows
+speedo_w64_spkgs  = \
+       libgpg-error libiconv gettext libassuan gpgex
+
+# Packages which use the gnupg autogen.sh build style
+speedo_gnupg_style = \
+       libgpg-error npth libgcrypt  \
+       libassuan libksba gnupg gpgme \
+       pinentry gpa gpgex
+
+# Packages which use only make and no build directory
+speedo_make_only_style = \
+       zlib bzip2
+
+# Get the content of the software DB.
+ifeq ($(UPD_SWDB),1)
+SWDB := $(shell $(topsrc)/build-aux/getswdb.sh && echo okay)
+ifeq ($(strip $(SWDB)),)
+$(error Error getting GnuPG software version database)
+endif
+
+# Version numbers of the released packages
+gnupg_ver = $(shell cat $(topsrc)/VERSION)
+
+libgpg_error_ver := $(shell awk '$$1=="libgpg_error_ver" {print $$2}' swdb.lst)
+libgpg_error_sha1:= $(shell awk '$$1=="libgpg_error_sha1" {print $$2}' swdb.lst)
+
+npth_ver  := $(shell awk '$$1=="npth_ver" {print $$2}' swdb.lst)
+npth_sha1 := $(shell awk '$$1=="npth_sha1" {print $$2}' swdb.lst)
+
+libgcrypt_ver  := $(shell awk '$$1=="libgcrypt_ver" {print $$2}' swdb.lst)
+libgcrypt_sha1 := $(shell awk '$$1=="libgcrypt_sha1" {print $$2}' swdb.lst)
+
+libassuan_ver  := $(shell awk '$$1=="libassuan_ver" {print $$2}' swdb.lst)
+libassuan_sha1 := $(shell awk '$$1=="libassuan_sha1" {print $$2}' swdb.lst)
+
+libksba_ver  := $(shell awk '$$1=="libksba_ver" {print $$2}' swdb.lst)
+libksba_sha1 := $(shell awk '$$1=="libksba_sha1" {print $$2}' swdb.lst)
+
+gpgme_ver  := $(shell awk '$$1=="gpgme_ver" {print $$2}' swdb.lst)
+gpgme_sha1 := $(shell awk '$$1=="gpgme_sha1" {print $$2}' swdb.lst)
+
+pinentry_ver  := $(shell awk '$$1=="pinentry_ver" {print $$2}' swdb.lst)
+pinentry_sha1 := $(shell awk '$$1=="pinentry_sha1" {print $$2}' swdb.lst)
+
+gpa_ver  := $(shell awk '$$1=="gpa_ver" {print $$2}' swdb.lst)
+gpa_sha1 := $(shell awk '$$1=="gpa_sha1" {print $$2}' swdb.lst)
+
+gpgex_ver  := $(shell awk '$$1=="gpgex_ver" {print $$2}' swdb.lst)
+gpgex_sha1 := $(shell awk '$$1=="gpgex_sha1" {print $$2}' swdb.lst)
+
+zlib_ver  := $(shell awk '$$1=="zlib_ver" {print $$2}' swdb.lst)
+zlib_sha1 := $(shell awk '$$1=="zlib_sha1_gz" {print $$2}' swdb.lst)
+
+bzip2_ver  := $(shell awk '$$1=="bzip2_ver" {print $$2}' swdb.lst)
+bzip2_sha1 := $(shell awk '$$1=="bzip2_sha1_gz" {print $$2}' swdb.lst)
+
+$(info Information from the version database)
+$(info GnuPG ..........: $(gnupg_ver))
+$(info Libgpg-error ...: $(libgpg_error_ver))
+$(info Npth ...........: $(npth_ver))
+$(info Libgcrypt ......: $(libgcrypt_ver))
+$(info Libassuan ......: $(libassuan_ver))
+$(info Zlib ...........: $(zlib_ver))
+$(info Bzip2 ..........: $(bzip2_ver))
+$(info GPGME ..........: $(gpgme_ver))
+$(info Pinentry .......: $(pinentry_ver))
+$(info GPA ............: $(gpa_ver))
+$(info GpgEX.... ......: $(gpgex_ver))
+endif
+
+# Version number for external packages
+pkg_config_ver = 0.23
+zlib_ver = 1.2.8
+libiconv_ver = 1.14
+gettext_ver = 0.18.2.1
+libffi_ver = 3.0.13
+glib_ver = 2.34.3
+libpng_ver = 1.4.12
+gdk_pixbuf_ver = 2.26.5
+atk_ver = 1.32.0
+pango_ver = 1.29.4
+pixman_ver = 0.32.4
+cairo_ver = 1.12.16
+gtk__ver = 2.24.17
+
+
+# The GIT repository.  Using a local repo is much faster.
+#gitrep = git://git.gnupg.org
+gitrep = ${HOME}/s
+
+# The tarball directories
+pkgrep = ftp://ftp.gnupg.org/gcrypt
+pkg10rep = ftp://ftp.g10code.com/g10code
+pkg2rep = $(TARBALLS)
+
+# For each package, the following variables can be defined:
+#
+# speedo_pkg_PACKAGE_git: The GIT repository that should be built.
+# speedo_pkg_PACKAGE_gitref: The GIT revision to checkout
+#
+# speedo_pkg_PACKAGE_tar: URL to the tar file that should be built.
+#
+# Exactly one of the above variables is required.  Note that this
+# version of speedo does not cache repositories or tar files, and does
+# not test the integrity of the downloaded software.  If you care
+# about this, you can also specify filenames to locally verified files.
+# Filenames are differentiated from URLs by starting with a slash '/'.
+#
+# speedo_pkg_PACKAGE_configure: Extra arguments to configure.
+#
+# speedo_pkg_PACKAGE_make_args: Extra arguments to make.
+#
+# speedo_pkg_PACKAGE_make_args_inst: Extra arguments to make install.
+#
+# Note that you can override the defaults in this file in a local file
+# "config.mk"
+
+ifeq ($(WHAT),this)
+else ifeq ($(WHAT),git)
+  speedo_pkg_libgpg_error_git = $(gitrep)/libgpg-error
+  speedo_pkg_libgpg_error_gitref = master
+  speedo_pkg_npth_git = $(gitrep)/npth
+  speedo_pkg_npth_gitref = master
+  speedo_pkg_libassuan_git = $(gitrep)/libassuan
+  speedo_pkg_libassuan_gitref = master
+  speedo_pkg_libgcrypt_git = $(gitrep)/libgcrypt
+  speedo_pkg_libgcrypt_gitref = LIBGCRYPT-1-6-BRANCH
+  speedo_pkg_libksba_git = $(gitrep)/libksba
+  speedo_pkg_libksba_gitref = master
+  speedo_pkg_gpgme_git = $(gitrep)/gpgme
+  speedo_pkg_gpgme_gitref = master
+  speedo_pkg_pinentry_git = $(gitrep)/pinentry
+  speedo_pkg_pinentry_gitref = master
+  speedo_pkg_gpa_git = $(gitrep)/gpa
+  speedo_pkg_gpa_gitref = master
+  speedo_pkg_gpgex_git = $(gitrep)/gpgex
+  speedo_pkg_gpgex_gitref = master
+else ifeq ($(WHAT),release)
+  speedo_pkg_libgpg_error_tar = \
+       $(pkgrep)/libgpg-error/libgpg-error-$(libgpg_error_ver).tar.bz2
+  speedo_pkg_npth_tar = \
+       $(pkgrep)/npth/npth-$(npth_ver).tar.bz2
+  speedo_pkg_libassuan_tar = \
+       $(pkgrep)/libassuan/libassuan-$(libassuan_ver).tar.bz2
+  speedo_pkg_libgcrypt_tar = \
+       $(pkgrep)/libgcrypt/libgcrypt-$(libgcrypt_ver).tar.bz2
+  speedo_pkg_libksba_tar = \
+       $(pkgrep)/libksba/libksba-$(libksba_ver).tar.bz2
+  speedo_pkg_gpgme_tar = \
+       $(pkgrep)/gpgme/gpgme-$(gpgme_ver).tar.bz2
+  speedo_pkg_pinentry_tar = \
+       $(pkgrep)/pinentry/pinentry-$(pinentry_ver).tar.bz2
+  speedo_pkg_gpa_tar = \
+       $(pkgrep)/gpa/gpa-$(gpa_ver).tar.bz2
+  speedo_pkg_gpgex_tar = \
+       $(pkg10rep)/gpgex/gpgex-$(gpgex_ver).tar.bz2
+else
+  $(error invalid value for WHAT (use on of: git release this))
+endif
+
+speedo_pkg_pkg_config_tar = $(pkg2rep)/pkg-config-$(pkg_config_ver).tar.gz
+speedo_pkg_zlib_tar       = $(pkgrep)/zlib/zlib-$(zlib_ver).tar.gz
+speedo_pkg_bzip2_tar      = $(pkgrep)/bzip2/bzip2-$(bzip2_ver).tar.gz
+speedo_pkg_libiconv_tar   = $(pkg2rep)/libiconv-$(libiconv_ver).tar.gz
+speedo_pkg_gettext_tar    = $(pkg2rep)/gettext-$(gettext_ver).tar.gz
+speedo_pkg_libffi_tar     = $(pkg2rep)/libffi-$(libffi_ver).tar.gz
+speedo_pkg_glib_tar       = $(pkg2rep)/glib-$(glib_ver).tar.xz
+speedo_pkg_libpng_tar     = $(pkg2rep)/libpng-$(libpng_ver).tar.bz2
+speedo_pkg_gdk_pixbuf_tar = $(pkg2rep)/gdk-pixbuf-$(gdk_pixbuf_ver).tar.xz
+speedo_pkg_atk_tar        = $(pkg2rep)/atk-$(atk_ver).tar.bz2
+speedo_pkg_pango_tar      = $(pkg2rep)/pango-$(pango_ver).tar.bz2
+speedo_pkg_pixman_tar     = $(pkg2rep)/pixman-$(pixman_ver).tar.gz
+speedo_pkg_cairo_tar      = $(pkg2rep)/cairo-$(cairo_ver).tar.xz
+speedo_pkg_gtk__tar       = $(pkg2rep)/gtk+-$(gtk__ver).tar.xz
+
+
+#
+# Package build options
+#
+
+speedo_pkg_libgpg_error_configure = --enable-static
+speedo_pkg_w64_libgpg_error_configure = --enable-static
+
+speedo_pkg_libassuan_configure = --enable-static
+speedo_pkg_w64_libassuan_configure = --enable-static
+
+speedo_pkg_libgcrypt_configure = --disable-static
+
+speedo_pkg_libksba_configure = --disable-static
+
+ifeq ($(TARGETOS),w32)
+speedo_pkg_gnupg_configure = --enable-gpg2-is-gpg --disable-g13 --disable-ntbtls
+else
+speedo_pkg_gnupg_configure = --disable-g13
+endif
+speedo_pkg_gnupg_extracflags = -g
+
+# Create the version info files only for W32 so that they won't get
+# installed if for example INSTALL_PREFIX=/usr/local is used.
+ifeq ($(TARGETOS),w32)
+define speedo_pkg_gnupg_post_install
+(set -e; \
+ sed -n  's/.*PACKAGE_VERSION "\(.*\)"/\1/p' config.h >$(idir)/INST_VERSION; \
+ sed -n  's/.*W32INFO_VI_PRODUCTVERSION \(.*\)/\1/p' common/w32info-rc.h \
+    |sed 's/,/./g' >$(idir)/INST_PROD_VERSION )
+endef
+endif
+
+# The LDFLAGS is needed for -lintl for glib.
+speedo_pkg_gpgme_configure = \
+       --enable-static --enable-w32-glib --disable-w32-qt \
+       --with-gpg-error-prefix=$(idir) \
+       LDFLAGS=-L$(idir)/lib
+
+speedo_pkg_pinentry_configure = \
+       --disable-pinentry-qt --disable-pinentry-qt4 --disable-pinentry-gtk \
+       --enable-pinentry-gtk2 \
+       --with-glib-prefix=$(idir) --with-gtk-prefix=$(idir) \
+       CPPFLAGS=-I$(idir)/include   \
+       LDFLAGS=-L$(idir)/lib        \
+       CXXFLAGS=-static-libstdc++
+
+speedo_pkg_gpa_configure = \
+        --with-libiconv-prefix=$(idir) --with-libintl-prefix=$(idir) \
+        --with-gpgme-prefix=$(idir) --with-zlib=$(idir) \
+        --with-libassuan-prefix=$(idir) --with-gpg-error-prefix=$(idir)
+
+speedo_pkg_gpgex_configure = \
+       --with-gpg-error-prefix=$(idir) \
+       --with-libassuan-prefix=$(idir) \
+       --enable-gpa-only
+
+speedo_pkg_w64_gpgex_configure = \
+       --with-gpg-error-prefix=$(idir6) \
+       --with-libassuan-prefix=$(idir6) \
+       --enable-gpa-only
+
+
+#
+# External packages
+#
+
+ifeq ($(TARGETOS),w32)
+speedo_pkg_zlib_make_args = \
+        -fwin32/Makefile.gcc PREFIX=$(host)- IMPLIB=libz.dll.a
+
+speedo_pkg_zlib_make_args_inst = \
+        -fwin32/Makefile.gcc \
+        BINARY_PATH=$(idir)/bin INCLUDE_PATH=$(idir)/include \
+       LIBRARY_PATH=$(idir)/lib SHARED_MODE=1 IMPLIB=libz.dll.a
+
+# Zlib needs some special magic to generate a libtool file.
+# We also install the pc file here.
+define speedo_pkg_zlib_post_install
+(set -e; mkdir $(idir)/lib/pkgconfig || true;          \
+cp $(auxsrc)/zlib.pc $(idir)/lib/pkgconfig/;           \
+cd $(idir);                                            \
+echo "# Generated by libtool" > lib/libz.la            \
+echo "dlname='../bin/zlib1.dll'" >> lib/libz.la;       \
+echo "library_names='libz.dll.a'" >> lib/libz.la;      \
+echo "old_library='libz.a'" >> lib/libz.la;            \
+echo "dependency_libs=''" >> lib/libz.la;              \
+echo "current=1" >> lib/libz.la;                       \
+echo "age=2" >> lib/libz.la;                           \
+echo "revision=5" >> lib/libz.la;                      \
+echo "installed=yes" >> lib/libz.la;                   \
+echo "shouldnotlink=no" >> lib/libz.la;                        \
+echo "dlopen=''" >> lib/libz.la;                       \
+echo "dlpreopen=''" >> lib/libz.la;                    \
+echo "libdir=\"$(idir)/lib\"" >> lib/libz.la)
+endef
+
+endif
+
+ifeq ($(TARGETOS),w32)
+speedo_pkg_bzip2_make_args = \
+       CC="$(host)-gcc" AR="$(host)-ar" RANLIB="$(host)-ranlib"
+
+speedo_pkg_bzip2_make_args_inst = \
+       PREFIX=$(idir) CC="$(host)-gcc" AR="$(host)-ar" RANLIB="$(host)-ranlib"
+endif
+
+speedo_pkg_w64_libiconv_configure = \
+       --enable-shared=no --enable-static=yes
+
+speedo_pkg_gettext_configure = \
+       --with-lib-prefix=$(idir) --with-libiconv-prefix=$(idir) \
+        CPPFLAGS=-I$(idir)/include LDFLAGS=-L$(idir)/lib
+speedo_pkg_w64_gettext_configure = \
+       --with-lib-prefix=$(idir) --with-libiconv-prefix=$(idir) \
+        CPPFLAGS=-I$(idir6)/include LDFLAGS=-L$(idir6)/lib
+speedo_pkg_gettext_extracflags = -O2
+# We only need gettext-runtime and there is sadly no top level
+# configure option for this
+speedo_pkg_gettext_make_dir = gettext-runtime
+
+
+speedo_pkg_glib_configure = \
+       --disable-modular-tests \
+       --with-libiconv=gnu \
+       CPPFLAGS=-I$(idir)/include \
+       LDFLAGS=-L$(idir)/lib \
+       CCC=$(host)-g++ \
+        LIBFFI_CFLAGS=-I$(idir)/lib/libffi-$(libffi_ver)/include \
+       LIBFFI_LIBS=\"-L$(idir)/lib -lffi\"
+ifeq ($(TARGETOS),w32)
+speedo_pkg_glib_extracflags = -march=i486
+endif
+
+ifeq ($(TARGETOS),w32)
+speedo_pkg_libpng_configure = \
+       CPPFLAGS=\"-I$(idir)/include -DPNG_BUILD_DLL\" \
+       LDFLAGS=\"-L$(idir)/lib\" LIBPNG_DEFINES=\"-DPNG_BUILD_DLL\"
+else
+speedo_pkg_libpng_configure = \
+        CPPFLAGS=\"-I$(idir)/include\" \
+        LDFLAGS=\"-L$(idir)/lib\"
+endif
+
+ifneq ($(TARGETOS),w32)
+speedo_pkg_gdk_pixbuf_configure = --without-libtiff --without-libjpeg
+endif
+
+speedo_pkg_pixman_configure = \
+       CPPFLAGS=-I$(idir)/include \
+       LDFLAGS=-L$(idir)/lib
+
+ifeq ($(TARGETOS),w32)
+speedo_pkg_cairo_configure = \
+       --disable-qt --disable-ft --disable-fc \
+       --enable-win32 --enable-win32-font \
+       CPPFLAGS=-I$(idir)/include \
+       LDFLAGS=-L$(idir)/lib
+else
+speedo_pkg_cairo_configure = \
+       --disable-qt \
+        CPPFLAGS=-I$(idir)/include \
+        LDFLAGS=-L$(idir)/lib
+endif
+
+speedo_pkg_pango_configure = \
+       --disable-gtk-doc  \
+       CPPFLAGS=-I$(idir)/include \
+       LDFLAGS=-L$(idir)/lib
+
+speedo_pkg_gtk__configure = \
+       --disable-cups \
+       CPPFLAGS=-I$(idir)/include \
+       LDFLAGS=-L$(idir)/lib
+
+
+# ---------
+
+all: all-speedo
+
+report: report-speedo
+
+clean: clean-speedo
+
+ifeq ($(TARGETOS),w32)
+STRIP = i686-w64-mingw32-strip
+else
+STRIP = strip
+endif
+W32CC = i686-w64-mingw32-gcc
+
+-include config.mk
+
+#
+#  The generic speedo code
+#
+
+MKDIR=mkdir
+MAKENSIS=makensis
+SHA1SUM := $(shell $(topsrc)/build-aux/getswdb.sh --find-sha1sum)
+ifeq ($(SHA1SUM),false)
+$(error The sha1sum tool is missing)
+endif
+
+
+BUILD_ISODATE=$(shell date -u +%Y-%m-%d)
+
+# The next two macros will work only after gnupg has been build.
+ifeq ($(TARGETOS),w32)
+INST_VERSION=$(shell head -1 $(idir)/INST_VERSION)
+INST_PROD_VERSION=$(shell head -1 $(idir)/INST_PROD_VERSION)
+endif
+
+# List with packages
+speedo_build_list = $(speedo_spkgs)
+speedo_w64_build_list = $(speedo_w64_spkgs)
+
+# To avoid running external commands during the read phase (":=" style
+# assignments), we check that the targetos has been given
+ifneq ($(TARGETOS),)
+
+# Determine build and host system
+build := $(shell $(topsrc)/autogen.sh --silent --print-build)
+ifeq ($(TARGETOS),w32)
+  speedo_autogen_buildopt := --build-w32
+  speedo_autogen_buildopt6 := --build-w64
+  host := $(shell $(topsrc)/autogen.sh --silent --print-host --build-w32)
+  host6:= $(shell $(topsrc)/autogen.sh --silent --print-host --build-w64)
+  speedo_host_build_option := --host=$(host) --build=$(build)
+  speedo_host_build_option6 := --host=$(host6) --build=$(build)
+  speedo_w32_cflags := -mms-bitfields
+else
+  speedo_autogen_buildopt :=
+  host :=
+  speedo_host_build_option :=
+  speedo_w32_cflags :=
+endif
+
+ifeq ($(MAKE_J),)
+  speedo_makeopt=
+else
+  speedo_makeopt=-j$(MAKE_J)
+endif
+
+# End non-empty TARGETOS
+endif
+
+
+
+# The playground area is our scratch area, where we unpack, build and
+# install the packages.
+$(stampdir)/stamp-directories:
+       $(MKDIR) $(root) || true
+       $(MKDIR) $(stampdir) || true
+       $(MKDIR) $(sdir)  || true
+       $(MKDIR) $(bdir)  || true
+       $(MKDIR) $(idir)   || true
+ifeq ($(TARGETOS),w32)
+       $(MKDIR) $(bdir6)  || true
+       $(MKDIR) $(idir6)   || true
+endif
+       touch $(stampdir)/stamp-directories
+
+# Frob the name $1 by converting all '-' and '+' characters to '_'.
+define FROB_macro
+$(subst +,_,$(subst -,_,$(1)))
+endef
+
+# Get the variable $(1) (which may contain '-' and '+' characters).
+define GETVAR
+$($(call FROB_macro,$(1)))
+endef
+
+# Set a couple of common variables.
+define SETVARS
+        pkg="$(1)";                                                     \
+        git="$(call GETVAR,speedo_pkg_$(1)_git)";                       \
+        gitref="$(call GETVAR,speedo_pkg_$(1)_gitref)";                 \
+        tar="$(call GETVAR,speedo_pkg_$(1)_tar)";                       \
+        sha1="$(call GETVAR,$(1)_sha1)";                                \
+        pkgsdir="$(sdir)/$(1)";                                         \
+        if [ "$(1)" = "gnupg" ]; then                                   \
+          git='';                                                       \
+          gitref='';                                                    \
+          tar='';                                                       \
+          pkgsdir="$(topsrc)";                                          \
+        fi;                                                             \
+        pkgbdir="$(bdir)/$(1)";                                         \
+        pkgcfg="$(call GETVAR,speedo_pkg_$(1)_configure)";              \
+        tmp="$(speedo_w32_cflags)                                       \
+             $(call GETVAR,speedo_pkg_$(1)_extracflags)";               \
+        if [ x$$$$(echo "$$$$tmp" | tr -d '[:space:]')x != xx ]; then   \
+          pkgextracflags="CFLAGS=\"$$$$tmp\"";                          \
+        else                                                            \
+          pkgextracflags=;                                              \
+        fi;                                                             \
+        pkgmkdir="$(call GETVAR,speedo_pkg_$(1)_make_dir)";             \
+        pkgmkargs="$(call GETVAR,speedo_pkg_$(1)_make_args)";           \
+        pkgmkargs_inst="$(call GETVAR,speedo_pkg_$(1)_make_args_inst)"; \
+        pkgmkargs_uninst="$(call GETVAR,speedo_pkg_$(1)_make_args_uninst)"; \
+        export PKG_CONFIG="/usr/bin/pkg-config";                        \
+        export PKG_CONFIG_PATH="$(idir)/lib/pkgconfig";                 \
+        [ "$(TARGETOS)" != native ] && export PKG_CONFIG_LIBDIR="";     \
+        export SYSROOT="$(idir)";                                       \
+        export PATH="$(idir)/bin:$${PATH}";                             \
+        export LD_LIBRARY_PATH="$(idir)/lib:$${LD_LIBRARY_PATH}"
+endef
+
+define SETVARS_W64
+        pkg="$(1)";                                                     \
+        git="$(call GETVAR,speedo_pkg_$(1)_git)";                       \
+        gitref="$(call GETVAR,speedo_pkg_$(1)_gitref)";                 \
+        tar="$(call GETVAR,speedo_pkg_$(1)_tar)";                       \
+        sha1="$(call GETVAR,$(1)_sha1)";                                \
+        pkgsdir="$(sdir)/$(1)";                                         \
+        if [ "$(1)" = "gnupg" ]; then                                   \
+          git='';                                                       \
+          gitref='';                                                    \
+          tar='';                                                       \
+          pkgsdir="$(topsrc)";                                          \
+        fi;                                                             \
+        pkgbdir="$(bdir6)/$(1)";                                        \
+        pkgcfg="$(call GETVAR,speedo_pkg_w64_$(1)_configure)";          \
+        tmp="$(speedo_w32_cflags)                                       \
+             $(call GETVAR,speedo_pkg_$(1)_extracflags)";               \
+        if [ x$$$$(echo "$$$$tmp" | tr -d '[:space:]')x != xx ]; then   \
+          pkgextracflags="CFLAGS=\"$$$$tmp\"";                          \
+        else                                                            \
+          pkgextracflags=;                                              \
+        fi;                                                             \
+        pkgmkdir="$(call GETVAR,speedo_pkg_$(1)_make_dir)";             \
+        pkgmkargs="$(call GETVAR,speedo_pkg_$(1)_make_args)";           \
+        pkgmkargs_inst="$(call GETVAR,speedo_pkg_$(1)_make_args_inst)"; \
+        pkgmkargs_uninst="$(call GETVAR,speedo_pkg_$(1)_make_args_uninst)"; \
+        export PKG_CONFIG="/usr/bin/pkg-config";                        \
+        export PKG_CONFIG_PATH="$(idir6)/lib/pkgconfig";                \
+        [ "$(TARGETOS)" != native ] && export PKG_CONFIG_LIBDIR="";     \
+        export SYSROOT="$(idir6)";                                      \
+        export PATH="$(idir6)/bin:$${PATH}";                            \
+        export LD_LIBRARY_PATH="$(idir6)/lib:$${LD_LIBRARY_PATH}"
+endef
+
+
+# Template for source packages.
+
+# Note that the gnupg package is special: The package source dir is
+# the same as the topsrc dir and thus we need to detect the gnupg
+# package and cd to that directory.  We also test that no in-source build
+# has been done.  autogen.sh is not run for gnupg.
+#
+define SPKG_template
+
+$(stampdir)/stamp-$(1)-00-unpack: $(stampdir)/stamp-directories
+       @echo "speedo: /*"
+       @echo "speedo:  *   $(1)"
+       @echo "speedo:  */"
+       @(set -e; cd $(sdir);                           \
+        $(call SETVARS,$(1));                          \
+        if [ "$(WHAT)" = "this" ]; then                \
+           echo "speedo: using included source";        \
+        elif [ "$(1)" = "gnupg" ]; then                \
+          cd $$$${pkgsdir};                            \
+           if [ -f config.log ]; then                   \
+             echo "GnuPG has already been build in-source" >&2  ;\
+            echo "Please run \"make distclean\" and retry" >&2 ;\
+            exit 1 ;                                   \
+           fi;                                          \
+          echo "speedo: unpacking gnupg not needed";   \
+        elif [ -n "$$$${git}" ]; then                  \
+          echo "speedo: unpacking $(1) from $$$${git}:$$$${gitref}"; \
+           git clone -b "$$$${gitref}" "$$$${git}" "$$$${pkg}"; \
+          cd "$$$${pkg}";                              \
+          AUTOGEN_SH_SILENT=1 ./autogen.sh;            \
+         elif [ -n "$$$${tar}" ]; then                 \
+          echo "speedo: unpacking $(1) from $$$${tar}"; \
+           case "$$$${tar}" in                         \
+             *.gz) pretar=zcat ;;                      \
+             *.bz2) pretar=bzcat ;;                    \
+            *.xz) pretar=xzcat ;;                      \
+             *) pretar=cat ;;                          \
+           esac;                                       \
+           [ -f tmp.tgz ] && rm tmp.tgz;                \
+           case "$$$${tar}" in                         \
+            /*) $$$${pretar} < $$$${tar} | tar xf - ;; \
+            *)  wget -q -O - $$$${tar} | tee tmp.tgz   \
+                  | $$$${pretar} | tar x$$$${opt}f - ;; \
+          esac;                                        \
+          if [ -f tmp.tgz ]; then                      \
+            if [ -n "$$$${sha1}" ]; then               \
+               tmp=$$$$($(SHA1SUM) <tmp.tgz|cut -d' ' -f1);\
+               if [ "$$$${tmp}" != "$$$${sha1}" ]; then \
+                echo "speedo:";                        \
+                 echo "speedo: ERROR: checksum mismatch for $(1)";\
+                echo "speedo:";                        \
+                 exit 1;                                \
+               fi;                                      \
+            else                                       \
+               echo "speedo:";                          \
+               echo "speedo: Warning: No checksum known for $(1)";\
+               echo "speedo:";                          \
+             fi;                                        \
+            rm tmp.tgz;                                \
+           fi;                                          \
+          base=`echo "$$$${tar}" | sed -e 's,^.*/,,'   \
+                 | sed -e 's,\.tar.*$$$$,,'`;          \
+          mv $$$${base} $(1);                          \
+          patch="$(patdir)/$(1)-$$$${base#$(1)-}.patch";\
+          if [ -x "$$$${patch}" ]; then                \
+             echo "speedo: applying patch $$$${patch}"; \
+             cd $(1); "$$$${patch}";                   \
+          elif [ -f "$$$${patch}" ]; then              \
+             echo "speedo: warning: $$$${patch} is not executable"; \
+          fi;                                          \
+        else                                           \
+          echo "speedo: unpacking $(1) from UNKNOWN";  \
+        fi)
+       @touch $(stampdir)/stamp-$(1)-00-unpack
+
+$(stampdir)/stamp-$(1)-01-configure: $(stampdir)/stamp-$(1)-00-unpack
+       @echo "speedo: configuring $(1)"
+ifneq ($(findstring $(1),$(speedo_make_only_style)),)
+       @echo "speedo: configure run not required"
+else ifneq ($(findstring $(1),$(speedo_gnupg_style)),)
+       @($(call SETVARS,$(1));                         \
+        mkdir "$$$${pkgbdir}";                         \
+        cd "$$$${pkgbdir}";                            \
+         if [ -n "$(speedo_autogen_buildopt)" ]; then   \
+            eval AUTOGEN_SH_SILENT=1 w32root="$(idir)"  \
+               "$$$${pkgsdir}/autogen.sh"               \
+               $(speedo_autogen_buildopt)              \
+               $$$${pkgcfg} $$$${pkgextracflags};      \
+         else                                          \
+            eval "$$$${pkgsdir}/configure"             \
+              --silent                                 \
+              --enable-maintainer-mode                 \
+               --prefix="$(idir)"                      \
+               $$$${pkgcfg} $$$${pkgextracflags};      \
+        fi)
+else
+       @($(call SETVARS,$(1));                         \
+        mkdir "$$$${pkgbdir}";                         \
+        cd "$$$${pkgbdir}";                            \
+        eval "$$$${pkgsdir}/configure"                 \
+            --silent $(speedo_host_build_option)       \
+             --prefix="$(idir)"                                \
+            $$$${pkgcfg}  $$$${pkgextracflags};        \
+        )
+endif
+       @touch $(stampdir)/stamp-$(1)-01-configure
+
+# Note that unpack has no 64 bit version becuase it is just the source.
+# Fixme: We should use templates to create the standard and w64
+# version of these rules.
+$(stampdir)/stamp-w64-$(1)-01-configure: $(stampdir)/stamp-$(1)-00-unpack
+       @echo "speedo: configuring $(1) (64 bit)"
+ifneq ($(findstring $(1),$(speedo_make_only_style)),)
+       @echo "speedo: configure run not required"
+else ifneq ($(findstring $(1),$(speedo_gnupg_style)),)
+       @($(call SETVARS_W64,$(1));                     \
+        mkdir "$$$${pkgbdir}";                         \
+        cd "$$$${pkgbdir}";                            \
+         if [ -n "$(speedo_autogen_buildopt)" ]; then   \
+            eval AUTOGEN_SH_SILENT=1 w64root="$(idir6)" \
+               "$$$${pkgsdir}/autogen.sh"               \
+               $(speedo_autogen_buildopt6)             \
+               $$$${pkgcfg} $$$${pkgextracflags};       \
+         else                                          \
+            eval "$$$${pkgsdir}/configure"             \
+              --silent                                 \
+              --enable-maintainer-mode                 \
+               --prefix="$(idir6)"                     \
+               $$$${pkgcfg} $$$${pkgextracflags};       \
+        fi)
+else
+       @($(call SETVARS_W64,$(1));                     \
+        mkdir "$$$${pkgbdir}";                         \
+        cd "$$$${pkgbdir}";                            \
+        eval "$$$${pkgsdir}/configure"                 \
+            --silent $(speedo_host_build_option6)      \
+             --prefix="$(idir6)"                       \
+            $$$${pkgcfg} $$$${pkgextracflags};         \
+        )
+endif
+       @touch $(stampdir)/stamp-w64-$(1)-01-configure
+
+
+$(stampdir)/stamp-$(1)-02-make: $(stampdir)/stamp-$(1)-01-configure
+       @echo "speedo: making $(1)"
+ifneq ($(findstring $(1),$(speedo_make_only_style)),)
+       @($(call SETVARS,$(1));                         \
+          cd "$$$${pkgsdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+          if test "$$$${pkg}" = zlib -a "$(TARGETOS)" != w32 ; then \
+            ./configure --prefix="$(idir)" ; \
+          fi ;\
+         $(MAKE) --no-print-directory $(speedo_makeopt) $$$${pkgmkargs} V=0)
+else
+       @($(call SETVARS,$(1));                         \
+          cd "$$$${pkgbdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+         $(MAKE) --no-print-directory $(speedo_makeopt) $$$${pkgmkargs} V=0)
+endif
+       @touch $(stampdir)/stamp-$(1)-02-make
+
+$(stampdir)/stamp-w64-$(1)-02-make: $(stampdir)/stamp-w64-$(1)-01-configure
+       @echo "speedo: making $(1) (64 bit)"
+ifneq ($(findstring $(1),$(speedo_make_only_style)),)
+       @($(call SETVARS_W64,$(1));                             \
+          cd "$$$${pkgsdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+         $(MAKE) --no-print-directory $(speedo_makeopt) $$$${pkgmkargs} V=0)
+else
+       @($(call SETVARS_W64,$(1));                             \
+          cd "$$$${pkgbdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+         $(MAKE) --no-print-directory $(speedo_makeopt) $$$${pkgmkargs} V=0)
+endif
+       @touch $(stampdir)/stamp-w64-$(1)-02-make
+
+# Note that post_install must come last because it may be empty and
+# "; ;" is a syntax error.
+$(stampdir)/stamp-$(1)-03-install: $(stampdir)/stamp-$(1)-02-make
+       @echo "speedo: installing $(1)"
+ifneq ($(findstring $(1),$(speedo_make_only_style)),)
+       @($(call SETVARS,$(1));                         \
+          cd "$$$${pkgsdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+         $(MAKE) --no-print-directory $$$${pkgmkargs_inst} install V=0;\
+         $(call speedo_pkg_$(call FROB_macro,$(1))_post_install))
+else
+       @($(call SETVARS,$(1));                         \
+          cd "$$$${pkgbdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+         $(MAKE) --no-print-directory $$$${pkgmkargs_inst} install-strip V=0;\
+         $(call speedo_pkg_$(call FROB_macro,$(1))_post_install))
+endif
+       touch $(stampdir)/stamp-$(1)-03-install
+
+$(stampdir)/stamp-w64-$(1)-03-install: $(stampdir)/stamp-w64-$(1)-02-make
+       @echo "speedo: installing $(1) (64 bit)"
+ifneq ($(findstring $(1),$(speedo_make_only_style)),)
+       @($(call SETVARS_W64,$(1));                             \
+          cd "$$$${pkgsdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+         $(MAKE) --no-print-directory $$$${pkgmkargs_inst} install V=0;\
+         $(call speedo_pkg_$(call FROB_macro,$(1))_post_install))
+else
+       @($(call SETVARS_W64,$(1));                             \
+          cd "$$$${pkgbdir}";                          \
+         test -n "$$$${pkgmkdir}" && cd "$$$${pkgmkdir}"; \
+         $(MAKE) --no-print-directory $$$${pkgmkargs_inst} install-strip V=0;\
+         $(call speedo_pkg_$(call FROB_macro,$(1))_post_install))
+endif
+       touch $(stampdir)/stamp-w64-$(1)-03-install
+
+$(stampdir)/stamp-final-$(1): $(stampdir)/stamp-$(1)-03-install
+       @echo "speedo: $(1) done"
+       @touch $(stampdir)/stamp-final-$(1)
+
+$(stampdir)/stamp-w64-final-$(1): $(stampdir)/stamp-w64-$(1)-03-install
+       @echo "speedo: $(1) (64 bit) done"
+       @touch $(stampdir)/stamp-w64-final-$(1)
+
+.PHONY : clean-$(1)
+clean-$(1):
+       @echo "speedo: uninstalling $(1)"
+       @($(call SETVARS,$(1));                           \
+        (cd "$$$${pkgbdir}" 2>/dev/null &&               \
+         $(MAKE) --no-print-directory                    \
+           $$$${pkgmkargs_uninst} uninstall V=0 ) || true;\
+         if [ "$(1)" = "gnupg" ]; then                    \
+          rm -fR "$$$${pkgbdir}" || true                ;\
+        else                                             \
+          rm -fR "$$$${pkgsdir}" "$$$${pkgbdir}" || true;\
+        fi)
+       -rm -f $(stampdir)/stamp-final-$(1) $(stampdir)/stamp-$(1)-*
+
+
+.PHONY : build-$(1)
+build-$(1): $(stampdir)/stamp-final-$(1)
+
+
+.PHONY : report-$(1)
+report-$(1):
+       @($(call SETVARS,$(1));                         \
+        echo -n $(1):\  ;                              \
+        if [ -n "$$$${git}" ]; then                    \
+           if [ -e "$$$${pkgsdir}/.git" ]; then                \
+            cd "$$$${pkgsdir}" &&                      \
+             git describe ;                            \
+          else                                         \
+             echo missing;                             \
+          fi                                           \
+         elif [ -n "$$$${tar}" ]; then                 \
+          base=`echo "$$$${tar}" | sed -e 's,^.*/,,'   \
+                 | sed -e 's,\.tar.*$$$$,,'`;          \
+          echo $$$${base} ;                            \
+         fi)
+
+endef
+
+
+# Insert the template for each source package.
+$(foreach spkg, $(speedo_spkgs), $(eval $(call SPKG_template,$(spkg))))
+
+$(stampdir)/stamp-final: $(stampdir)/stamp-directories
+ifeq ($(TARGETOS),w32)
+$(stampdir)/stamp-final: $(addprefix $(stampdir)/stamp-w64-final-,$(speedo_w64_build_list))
+endif
+$(stampdir)/stamp-final: $(addprefix $(stampdir)/stamp-final-,$(speedo_build_list))
+       touch $(stampdir)/stamp-final
+
+all-speedo: $(stampdir)/stamp-final
+
+report-speedo: $(addprefix report-,$(speedo_build_list))
+
+# Just to check if we catched all stamps.
+clean-stamps:
+       $(RM) -fR $(stampdir)
+
+clean-speedo:
+       $(RM) -fR PLAY
+
+
+#
+# Windows installer
+#
+# {{{
+ifeq ($(TARGETOS),w32)
+
+dist-source: all
+       for i in 00 01 02 03; do sleep 1;touch PLAY/stamps/stamp-*-${i}-*;done
+       (set -e;\
+        tarname="$(INST_NAME)-$(INST_VERSION)_$(BUILD_ISODATE).tar" ;\
+        [ -f "$$tarname" ] && rm "$$tarname" ;\
+         tar -C $(topsrc) -cf "$$tarname" --exclude-backups --exclude-vc \
+             --transform='s,^\./,$(INST_NAME)-$(INST_VERSION)/,' \
+             --anchored --exclude './PLAY' . ;\
+        tar --totals -rf "$$tarname" --exclude-backups --exclude-vc \
+              --transform='s,^,$(INST_NAME)-$(INST_VERSION)/,' \
+            PLAY/stamps/stamp-*-00-unpack PLAY/src ;\
+         xz "$$tarname" ;\
+       )
+
+
+$(bdir)/NEWS.tmp: $(topsrc)/NEWS
+       sed -e '/^#/d' <$(topsrc)/NEWS >$(bdir)/NEWS.tmp
+
+$(bdir)/README.txt: $(bdir)/NEWS.tmp $(w32src)/README.txt \
+                    $(w32src)/pkg-copyright.txt
+       sed -e '/^;.*/d;' \
+       -e '/!NEWSFILE!/{r NEWS.tmp' -e 'd;}' \
+        -e '/!PKG-COPYRIGHT!/{r $(w32src)/pkg-copyright.txt' -e 'd;}' \
+        -e 's,!VERSION!,$(INST_VERSION),g' \
+          < $(w32src)/README.txt \
+           | awk '{printf "%s\r\n", $$0}' >$(bdir)/README.txt
+
+$(bdir)/g4wihelp.dll: $(w32src)/g4wihelp.c $(w32src)/exdll.h
+       (set -e; cd $(bdir); \
+        $(W32CC) -I. -shared -O2 -o g4wihelp.dll $(w32src)/g4wihelp.c \
+                 -lwinmm -lgdi32; \
+        $(STRIP) g4wihelp.dll)
+
+w32_insthelpers: $(bdir)/g4wihelp.dll
+
+$(bdir)/inst-options.ini: $(w32src)/inst-options.ini
+       cat $(w32src)/inst-options.ini >$(bdir)/inst-options.ini
+
+installer: all w32_insthelpers $(w32src)/inst-options.ini $(bdir)/README.txt
+       $(MAKENSIS) -V2 \
+                    -DINST_DIR=$(idir) \
+                    -DINST6_DIR=$(idir6) \
+                    -DBUILD_DIR=$(bdir) \
+                    -DTOP_SRCDIR=$(topsrc) \
+                    -DW32_SRCDIR=$(w32src) \
+                    -DBUILD_ISODATE=$(BUILD_ISODATE) \
+                   -DNAME=$(INST_NAME) \
+                   -DVERSION=$(INST_VERSION) \
+                   -DPROD_VERSION=$(INST_PROD_VERSION) \
+                   $(w32src)/inst.nsi
+       @echo "Ready: $(idir)/$(INST_NAME)-$(INST_VERSION)"
+
+endif
+# }}} W32
+
+
+#
+# Check availibility of standard tools
+#
+check-tools:
+
+
+#
+# Mark phony targets
+#
+.PHONY: all all-speedo report-speedo clean-stamps clean-speedo installer \
+       w32_insthelpers check-tools
diff --git a/build-aux/speedo/patches/atk-1.32.0.patch b/build-aux/speedo/patches/atk-1.32.0.patch
new file mode 100755 (executable)
index 0000000..51d7975
--- /dev/null
@@ -0,0 +1,671 @@
+#! /bin/sh
+patch -p1 -l -f $* < $0
+exit $?
+
+
+diff -urpb orig/atk-1.32.0/atk/atkaction.c atk/atk/atkaction.c
+--- orig/atk-1.32.0/atk/atkaction.c    2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkaction.c        2014-02-17 12:30:53.263192763 +0100
+@@ -101,7 +101,7 @@ atk_action_get_n_actions  (AtkAction *ob
+  * Returns a description string, or %NULL
+  * if @action does not implement this interface.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_action_get_description (AtkAction *obj,
+                             gint      i)
+ {
+@@ -140,7 +140,7 @@ atk_action_get_description (AtkAction *o
+  * Returns a name string, or %NULL
+  * if @action does not implement this interface.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_action_get_name (AtkAction *obj,
+                      gint      i)
+ {
+@@ -166,7 +166,7 @@ atk_action_get_name (AtkAction *obj,
+  * Returns a name string, or %NULL
+  * if @action does not implement this interface.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_action_get_localized_name (AtkAction *obj,
+                                gint      i)
+ {
+@@ -203,7 +203,7 @@ atk_action_get_localized_name (AtkAction
+  * if there is no keybinding for this action.
+  *
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_action_get_keybinding (AtkAction *obj,
+                            gint      i)
+ {
+Only in atk/atk: atkaction.c~
+diff -urpb orig/atk-1.32.0/atk/atkaction.h atk/atk/atkaction.h
+--- orig/atk-1.32.0/atk/atkaction.h    2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkaction.h        2014-02-17 12:30:58.907192071 +0100
+@@ -55,16 +55,16 @@ struct _AtkActionIface
+   gboolean                (*do_action)         (AtkAction         *action,
+                                                 gint              i);
+   gint                    (*get_n_actions)     (AtkAction         *action);
+-  G_CONST_RETURN gchar*   (*get_description)   (AtkAction         *action,
++  const gchar*   (*get_description)   (AtkAction         *action,
+                                                 gint              i);
+-  G_CONST_RETURN gchar*   (*get_name)          (AtkAction         *action,
++  const gchar*   (*get_name)          (AtkAction         *action,
+                                                 gint              i);
+-  G_CONST_RETURN gchar*   (*get_keybinding)    (AtkAction         *action,
++  const gchar*   (*get_keybinding)    (AtkAction         *action,
+                                                 gint              i);
+   gboolean                (*set_description)   (AtkAction         *action,
+                                                 gint              i,
+                                                 const gchar       *desc);
+-  G_CONST_RETURN gchar*   (*get_localized_name)(AtkAction         *action,
++  const gchar*   (*get_localized_name)(AtkAction         *action,
+                                                gint              i);
+   AtkFunction             pad2;
+ };
+@@ -85,11 +85,11 @@ GType atk_action_get_type (void);
+ gboolean   atk_action_do_action                (AtkAction         *action,
+                                             gint              i);
+ gint   atk_action_get_n_actions            (AtkAction *action);
+-G_CONST_RETURN gchar* atk_action_get_description  (AtkAction         *action,
++const gchar* atk_action_get_description  (AtkAction         *action,
+                                                    gint              i);
+-G_CONST_RETURN gchar* atk_action_get_name         (AtkAction         *action,
++const gchar* atk_action_get_name         (AtkAction         *action,
+                                                    gint              i);
+-G_CONST_RETURN gchar* atk_action_get_keybinding   (AtkAction         *action,
++const gchar* atk_action_get_keybinding   (AtkAction         *action,
+                                                    gint              i);
+ gboolean              atk_action_set_description  (AtkAction         *action,
+                                                    gint              i,
+@@ -97,7 +97,7 @@ gboolean              atk_action_set_des
+
+ /* NEW in ATK 1.1: */
+
+-G_CONST_RETURN gchar* atk_action_get_localized_name (AtkAction       *action,
++const gchar* atk_action_get_localized_name (AtkAction       *action,
+                                                    gint            i);
+
+ /*
+Only in atk/atk: atkaction.h~
+diff -urpb orig/atk-1.32.0/atk/atkdocument.c atk/atk/atkdocument.c
+--- orig/atk-1.32.0/atk/atkdocument.c  2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkdocument.c      2014-02-17 12:30:58.535192391 +0100
+@@ -93,7 +93,7 @@ atk_document_base_init (AtkDocumentIface
+  *
+  * Returns: a string indicating the document type
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_document_get_document_type (AtkDocument *document)
+ {
+   AtkDocumentIface *iface;
+@@ -155,7 +155,7 @@ atk_document_get_document (AtkDocument *
+  *          locale of the document content as a whole, or NULL if
+  *          the document content does not specify a locale.
+  **/
+-G_CONST_RETURN gchar *
++const gchar *
+ atk_document_get_locale (AtkDocument *document)
+ {
+   AtkDocumentIface *iface;
+@@ -219,7 +219,7 @@ atk_document_get_attributes (AtkDocument
+  *    document, or NULL if a value for #attribute_name has not been specified
+  *    for this document.
+  */
+-G_CONST_RETURN gchar *
++const gchar *
+ atk_document_get_attribute_value (AtkDocument *document,
+                                 const gchar *attribute_name)
+ {
+Only in atk/atk: atkdocument.c~
+diff -urpb orig/atk-1.32.0/atk/atkdocument.h atk/atk/atkdocument.h
+--- orig/atk-1.32.0/atk/atkdocument.h  2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkdocument.h      2014-02-17 12:31:31.691190631 +0100
+@@ -49,12 +49,12 @@ typedef struct _AtkDocumentIface AtkDocu
+ struct _AtkDocumentIface
+ {
+   GTypeInterface parent;
+-  G_CONST_RETURN gchar* ( *get_document_type) (AtkDocument              *document);
++  const gchar* ( *get_document_type) (AtkDocument              *document);
+   gpointer              ( *get_document)      (AtkDocument              *document);
+
+-  G_CONST_RETURN gchar* ( *get_document_locale) (AtkDocument              *document);
++  const gchar* ( *get_document_locale) (AtkDocument              *document);
+   AtkAttributeSet *     ( *get_document_attributes) (AtkDocument        *document);
+-  G_CONST_RETURN gchar* ( *get_document_attribute_value) (AtkDocument   *document,
++  const gchar* ( *get_document_attribute_value) (AtkDocument   *document,
+                                                           const gchar   *attribute_name);
+   gboolean              ( *set_document_attribute) (AtkDocument         *document,
+                                                     const gchar         *attribute_name,
+@@ -68,11 +68,11 @@ struct _AtkDocumentIface
+
+ GType  atk_document_get_type             (void);
+
+-G_CONST_RETURN gchar* atk_document_get_document_type (AtkDocument   *document);
++const gchar* atk_document_get_document_type (AtkDocument   *document);
+ gpointer atk_document_get_document (AtkDocument   *document);
+-G_CONST_RETURN gchar* atk_document_get_locale (AtkDocument *document);
++const gchar* atk_document_get_locale (AtkDocument *document);
+ AtkAttributeSet*      atk_document_get_attributes (AtkDocument *document);
+-G_CONST_RETURN gchar* atk_document_get_attribute_value (AtkDocument *document,
++const gchar* atk_document_get_attribute_value (AtkDocument *document,
+                                                         const gchar *attribute_name);
+ gboolean              atk_document_set_attribute_value (AtkDocument *document,
+                                                         const gchar *attribute_name,
+Only in atk/atk: atkdocument.h~
+diff -urpb orig/atk-1.32.0/atk/atkimage.c atk/atk/atkimage.c
+--- orig/atk-1.32.0/atk/atkimage.c     2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkimage.c 2014-02-17 12:30:58.119192299 +0100
+@@ -46,7 +46,7 @@ atk_image_get_type (void)
+  *
+  * Returns: a string representing the image description
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_image_get_image_description (AtkImage *image)
+ {
+   AtkImageIface *iface;
+@@ -192,7 +192,7 @@ atk_image_get_image_position (AtkImage *
+  * Returns a string corresponding to the POSIX LC_MESSAGES locale used by the image description, or NULL if the image does not specify a locale.
+  *
+  */
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_image_get_image_locale (AtkImage   *image)
+ {
+
+Only in atk/atk: atkimage.c~
+diff -urpb orig/atk-1.32.0/atk/atkimage.h atk/atk/atkimage.h
+--- orig/atk-1.32.0/atk/atkimage.h     2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkimage.h 2014-02-17 12:28:31.599200223 +0100
+@@ -53,13 +53,13 @@ struct _AtkImageIface
+                                                    gint                  *x,
+                                                  gint                  *y,
+                                                  AtkCoordType          coord_type);
+-  G_CONST_RETURN gchar* ( *get_image_description) (AtkImage              *image);
++  const gchar* ( *get_image_description) (AtkImage              *image);
+   void                  ( *get_image_size)        (AtkImage              *image,
+                                                    gint                  *width,
+                                                    gint                  *height);
+   gboolean              ( *set_image_description) (AtkImage              *image,
+                                                    const gchar           *description);
+-  G_CONST_RETURN gchar* ( *get_image_locale)      (AtkImage              *image);
++  const gchar* ( *get_image_locale)      (AtkImage              *image);
+
+   AtkFunction           pad1;
+
+@@ -67,7 +67,7 @@ struct _AtkImageIface
+
+ GType  atk_image_get_type             (void);
+
+-G_CONST_RETURN gchar* atk_image_get_image_description (AtkImage   *image);
++const gchar* atk_image_get_image_description (AtkImage   *image);
+
+ void     atk_image_get_image_size        (AtkImage           *image,
+                                           gint               *width,
+@@ -80,7 +80,7 @@ void     atk_image_get_image_position
+                                         gint               *y,
+                                         AtkCoordType       coord_type);
+
+-G_CONST_RETURN gchar* atk_image_get_image_locale (AtkImage   *image);
++const gchar* atk_image_get_image_locale (AtkImage   *image);
+
+ G_END_DECLS
+
+Only in atk/atk: atkimage.h~
+diff -urpb orig/atk-1.32.0/atk/atkobject.c atk/atk/atkobject.c
+--- orig/atk-1.32.0/atk/atkobject.c    2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkobject.c        2014-02-17 12:28:39.467199803 +0100
+@@ -285,9 +285,9 @@ static void            atk_object_real_g
+                                                      GValue          *value,
+                                                      GParamSpec      *pspec);
+ static void            atk_object_finalize          (GObject         *object);
+-static G_CONST_RETURN gchar*
++static const gchar*
+                        atk_object_real_get_name     (AtkObject       *object);
+-static G_CONST_RETURN gchar*
++static const gchar*
+                        atk_object_real_get_description
+                                                    (AtkObject       *object);
+ static AtkObject*      atk_object_real_get_parent  (AtkObject       *object);
+@@ -692,7 +692,7 @@ atk_implementor_get_type (void)
+  *
+  * Returns: a character string representing the accessible name of the object.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_object_get_name (AtkObject *accessible)
+ {
+   AtkObjectClass *klass;
+@@ -716,7 +716,7 @@ atk_object_get_name (AtkObject *accessib
+  * of the accessible.
+  *
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_object_get_description (AtkObject *accessible)
+ {
+   AtkObjectClass *klass;
+@@ -1123,7 +1123,7 @@ atk_object_notify_state_change (AtkObjec
+                                 AtkState  state,
+                                 gboolean  value)
+ {
+-  G_CONST_RETURN gchar* name;
++  const gchar* name;
+
+   g_return_if_fail (ATK_IS_OBJECT (accessible));
+
+@@ -1319,13 +1319,13 @@ atk_object_finalize (GObject *object)
+   G_OBJECT_CLASS (parent_class)->finalize (object);
+ }
+
+-static G_CONST_RETURN gchar*
++static const gchar*
+ atk_object_real_get_name (AtkObject *object)
+ {
+   return object->name;
+ }
+
+-static G_CONST_RETURN gchar*
++static const gchar*
+ atk_object_real_get_description (AtkObject *object)
+ {
+   return object->description;
+@@ -1487,7 +1487,7 @@ atk_object_notify (GObject     *obj,
+  *
+  * Returns: the string describing the AtkRole
+  */
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_role_get_name (AtkRole role)
+ {
+   if (role >= 0 && role < ATK_ROLE_LAST_DEFINED)
+@@ -1514,7 +1514,7 @@ atk_role_get_name (AtkRole role)
+  *
+  * Returns: the localized string describing the AtkRole
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_role_get_localized_name (AtkRole role)
+ {
+   gettext_initialization ();
+Only in atk/atk: atkobject.c~
+diff -urpb orig/atk-1.32.0/atk/atkobject.h atk/atk/atkobject.h
+--- orig/atk-1.32.0/atk/atkobject.h    2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkobject.h        2014-02-17 12:28:48.851199302 +0100
+@@ -381,11 +381,11 @@ struct _AtkObjectClass
+   /*
+    * Gets the accessible name of the object
+    */
+-  G_CONST_RETURN gchar*    (* get_name)            (AtkObject                *accessible);
++  const gchar*    (* get_name)            (AtkObject                *accessible);
+   /*
+    * Gets the accessible description of the object
+    */
+-  G_CONST_RETURN gchar*    (* get_description)     (AtkObject                *accessible);
++  const gchar*    (* get_description)     (AtkObject                *accessible);
+   /*
+    * Gets the accessible parent of the object
+    */
+@@ -535,8 +535,8 @@ AtkObject*              atk_implementor_
+  * Properties directly supported by AtkObject
+  */
+
+-G_CONST_RETURN gchar*   atk_object_get_name                       (AtkObject *accessible);
+-G_CONST_RETURN gchar*   atk_object_get_description                (AtkObject *accessible);
++const gchar*   atk_object_get_name                       (AtkObject *accessible);
++const gchar*   atk_object_get_description                (AtkObject *accessible);
+ AtkObject*              atk_object_get_parent                     (AtkObject *accessible);
+ gint                    atk_object_get_n_accessible_children      (AtkObject *accessible);
+ AtkObject*              atk_object_ref_accessible_child           (AtkObject *accessible,
+@@ -571,7 +571,7 @@ void                 atk_object_notify_s
+ void                 atk_object_initialize                       (AtkObject                     *accessible,
+                                                                   gpointer                      data);
+
+-G_CONST_RETURN gchar* atk_role_get_name      (AtkRole         role);
++const gchar* atk_role_get_name      (AtkRole         role);
+ AtkRole               atk_role_for_name      (const gchar     *name);
+
+
+@@ -582,7 +582,7 @@ gboolean              atk_object_add_rel
+ gboolean              atk_object_remove_relationship           (AtkObject      *object,
+                                                               AtkRelationType relationship,
+                                                               AtkObject      *target);
+-G_CONST_RETURN gchar* atk_role_get_localized_name              (AtkRole     role);
++const gchar* atk_role_get_localized_name              (AtkRole     role);
+
+ /* */
+
+Only in atk/atk: atkobject.h~
+diff -urpb orig/atk-1.32.0/atk/atkrelation.c atk/atk/atkrelation.c
+--- orig/atk-1.32.0/atk/atkrelation.c  2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkrelation.c      2014-02-17 12:29:04.307198532 +0100
+@@ -130,7 +130,7 @@ atk_relation_type_register (const gchar
+  *
+  * Returns: the string describing the AtkRelationType
+  */
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_relation_type_get_name (AtkRelationType type)
+ {
+   GTypeClass *type_class;
+Only in atk/atk: atkrelation.c~
+diff -urpb orig/atk-1.32.0/atk/atkrelation.h atk/atk/atkrelation.h
+--- orig/atk-1.32.0/atk/atkrelation.h  2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkrelation.h      2014-02-17 12:29:12.167198142 +0100
+@@ -61,7 +61,7 @@ struct _AtkRelationClass
+ GType atk_relation_get_type (void);
+
+ AtkRelationType       atk_relation_type_register      (const gchar     *name);
+-G_CONST_RETURN gchar* atk_relation_type_get_name      (AtkRelationType type);
++const gchar* atk_relation_type_get_name      (AtkRelationType type);
+ AtkRelationType       atk_relation_type_for_name      (const gchar     *name);
+
+ /*
+Only in atk/atk: atkrelation.h~
+diff -urpb orig/atk-1.32.0/atk/atkstate.c atk/atk/atkstate.c
+--- orig/atk-1.32.0/atk/atkstate.c     2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkstate.c 2014-02-17 12:29:19.023197754 +0100
+@@ -57,7 +57,7 @@ atk_state_type_register (const gchar *na
+  *
+  * Returns: the string describing the AtkStateType
+  */
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_state_type_get_name (AtkStateType type)
+ {
+   GTypeClass *type_class;
+Only in atk/atk: atkstate.c~
+diff -urpb orig/atk-1.32.0/atk/atkstate.h atk/atk/atkstate.h
+--- orig/atk-1.32.0/atk/atkstate.h     2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkstate.h 2014-02-17 12:26:44.459205944 +0100
+@@ -170,7 +170,7 @@ typedef guint64      AtkState;
+
+ AtkStateType atk_state_type_register            (const gchar *name);
+
+-G_CONST_RETURN gchar* atk_state_type_get_name   (AtkStateType type);
++const gchar* atk_state_type_get_name   (AtkStateType type);
+ AtkStateType          atk_state_type_for_name   (const gchar  *name);
+
+ G_END_DECLS
+Only in atk/atk: atkstate.h~
+diff -urpb orig/atk-1.32.0/atk/atkstreamablecontent.c atk/atk/atkstreamablecontent.c
+--- orig/atk-1.32.0/atk/atkstreamablecontent.c 2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkstreamablecontent.c     2014-02-17 12:30:57.659192412 +0100
+@@ -73,7 +73,7 @@ atk_streamable_content_get_n_mime_types
+  * Returns : a gchar* representing the specified mime type; the caller
+  * should not free the character string.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_streamable_content_get_mime_type (AtkStreamableContent *streamable,
+                                       gint                 i)
+ {
+Only in atk/atk: atkstreamablecontent.c~
+diff -urpb orig/atk-1.32.0/atk/atkstreamablecontent.h atk/atk/atkstreamablecontent.h
+--- orig/atk-1.32.0/atk/atkstreamablecontent.h 2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkstreamablecontent.h     2014-02-17 12:29:49.487196042 +0100
+@@ -54,11 +54,11 @@ struct _AtkStreamableContentIface
+    * at index 0 should be considered the "default" data type for the stream.
+    *
+    * This assumes that the strings for the mime types are stored in the
+-   * AtkStreamableContent. Alternatively the G_CONST_RETURN could be removed
++   * AtkStreamableContent. Alternatively the const could be removed
+    * and the caller would be responsible for calling g_free() on the
+    * returned value.
+    */
+-  G_CONST_RETURN gchar*     (* get_mime_type)     (AtkStreamableContent     *streamable,
++  const gchar*     (* get_mime_type)     (AtkStreamableContent     *streamable,
+                                                    gint                     i);
+   /*
+    * One possible implementation for this method is that it constructs the
+@@ -80,7 +80,7 @@ struct _AtkStreamableContentIface
+  * constructed.  Note that it is possible for get_uri to return NULL but for
+  * get_stream to work nonetheless, since not all GIOChannels connect to URIs.
+  */
+-    G_CONST_RETURN  gchar*  (* get_uri)           (AtkStreamableContent     *streamable,
++    const  gchar*  (* get_uri)           (AtkStreamableContent     *streamable,
+                                                    const gchar              *mime_type);
+
+
+@@ -92,7 +92,7 @@ GType                  atk_streamable_co
+
+ gint                   atk_streamable_content_get_n_mime_types (AtkStreamableContent     *streamable);
+
+-G_CONST_RETURN gchar*  atk_streamable_content_get_mime_type    (AtkStreamableContent     *streamable,
++const gchar*  atk_streamable_content_get_mime_type    (AtkStreamableContent     *streamable,
+                                                                 gint                     i);
+ GIOChannel*             atk_streamable_content_get_stream       (AtkStreamableContent     *streamable,
+                                                                  const gchar              *mime_type);
+Only in atk/atk: atkstreamablecontent.h~
+diff -urpb orig/atk-1.32.0/atk/atktable.c atk/atk/atktable.c
+--- orig/atk-1.32.0/atk/atktable.c     2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atktable.c 2014-02-17 12:30:57.319192444 +0100
+@@ -300,7 +300,7 @@ atk_table_get_n_columns (AtkTable *table
+  * Returns: a gchar* representing the column description, or %NULL
+  * if value does not implement this interface.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_table_get_column_description (AtkTable *table,
+                                   gint     column)
+ {
+@@ -404,7 +404,7 @@ atk_table_get_n_rows (AtkTable *table)
+  * Returns: a gchar* representing the row description, or %NULL
+  * if value does not implement this interface.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_table_get_row_description (AtkTable *table,
+                                gint      row)
+ {
+Only in atk/atk: atktable.c~
+diff -urpb orig/atk-1.32.0/atk/atktable.h atk/atk/atktable.h
+--- orig/atk-1.32.0/atk/atktable.h     2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atktable.h 2014-02-17 12:30:08.035195073 +0100
+@@ -69,12 +69,12 @@ struct _AtkTableIface
+                                                   gint          column);
+   AtkObject*
+                     (* get_caption)              (AtkTable      *table);
+-  G_CONST_RETURN gchar*
++  const gchar*
+                     (* get_column_description)   (AtkTable      *table,
+                                                   gint          column);
+   AtkObject*        (* get_column_header)        (AtkTable      *table,
+                                                 gint          column);
+-  G_CONST_RETURN gchar*
++  const gchar*
+                     (* get_row_description)      (AtkTable      *table,
+                                                   gint          row);
+   AtkObject*        (* get_row_header)           (AtkTable      *table,
+@@ -163,12 +163,12 @@ gint              atk_table_get_row_exte
+                                                   gint             column);
+ AtkObject*
+                   atk_table_get_caption          (AtkTable         *table);
+-G_CONST_RETURN gchar*
++const gchar*
+                   atk_table_get_column_description (AtkTable         *table,
+                                                   gint             column);
+ AtkObject*        atk_table_get_column_header    (AtkTable         *table,
+                                                 gint             column);
+-G_CONST_RETURN gchar*
++const gchar*
+                   atk_table_get_row_description  (AtkTable         *table,
+                                                   gint             row);
+ AtkObject*        atk_table_get_row_header       (AtkTable         *table,
+Only in atk/atk: atktable.h~
+diff -urpb orig/atk-1.32.0/atk/atktext.c atk/atk/atktext.c
+--- orig/atk-1.32.0/atk/atktext.c      2010-09-27 09:07:09.000000000 +0200
++++ atk/atk/atktext.c  2014-02-17 12:30:56.871192495 +0100
+@@ -1054,7 +1054,7 @@ atk_text_attribute_register (const gchar
+  *
+  * Returns: a string containing the name; this string should not be freed
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_text_attribute_get_name (AtkTextAttribute attr)
+ {
+   GTypeClass *type_class;
+@@ -1150,7 +1150,7 @@ atk_text_attribute_for_name (const gchar
+  * Returns: a string containing the value; this string should not be freed;
+  * NULL is returned if there are no values maintained for the attr value.
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_text_attribute_get_value (AtkTextAttribute attr,
+                               gint             index)
+ {
+Only in atk/atk: atktext.c~
+diff -urpb orig/atk-1.32.0/atk/atktext.h atk/atk/atktext.h
+--- orig/atk-1.32.0/atk/atktext.h      2010-09-27 09:07:09.000000000 +0200
++++ atk/atk/atktext.h  2014-02-17 12:30:56.475192626 +0100
+@@ -355,9 +355,9 @@ AtkTextRange**  atk_text_get_bounded_ran
+                                                            AtkTextClipType  y_clip_type);
+ void          atk_text_free_ranges                        (AtkTextRange     **ranges);
+ void        atk_attribute_set_free                      (AtkAttributeSet  *attrib_set);
+-G_CONST_RETURN gchar*  atk_text_attribute_get_name        (AtkTextAttribute attr);
++const gchar*  atk_text_attribute_get_name        (AtkTextAttribute attr);
+ AtkTextAttribute       atk_text_attribute_for_name        (const gchar      *name);
+-G_CONST_RETURN gchar*  atk_text_attribute_get_value       (AtkTextAttribute attr,
++const gchar*  atk_text_attribute_get_value       (AtkTextAttribute attr,
+                                                            gint             index_);
+
+ G_END_DECLS
+Only in atk/atk: atktext.h~
+diff -urpb orig/atk-1.32.0/atk/atkutil.c atk/atk/atkutil.c
+--- orig/atk-1.32.0/atk/atkutil.c      2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkutil.c  2014-02-17 12:30:33.651193705 +0100
+@@ -340,7 +340,7 @@ atk_get_focus_object (void)
+  *
+  * Returns: name string for the GUI toolkit implementing ATK for this application
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_get_toolkit_name (void)
+ {
+   const gchar *retval;
+@@ -365,7 +365,7 @@ atk_get_toolkit_name (void)
+  *
+  * Returns: version string for the GUI toolkit implementing ATK for this application
+  **/
+-G_CONST_RETURN gchar*
++const gchar*
+ atk_get_toolkit_version (void)
+ {
+   const gchar *retval;
+@@ -391,7 +391,7 @@ atk_get_toolkit_version (void)
+  * Returns: version string for ATK
+  **/
+
+-G_CONST_RETURN gchar *
++const gchar *
+ atk_get_version (void)
+ {
+   return VERSION;
+Only in atk/atk: atkutil.c~
+diff -urpb orig/atk-1.32.0/atk/atkutil.h atk/atk/atkutil.h
+--- orig/atk-1.32.0/atk/atkutil.h      2010-09-06 08:45:45.000000000 +0200
++++ atk/atk/atkutil.h  2014-02-17 12:30:40.635193333 +0100
+@@ -147,8 +147,8 @@ struct _AtkUtilClass
+                                                 gpointer data);
+    void         (* remove_key_event_listener)    (guint               listener_id);
+    AtkObject*   (* get_root)                     (void);
+-   G_CONST_RETURN gchar* (* get_toolkit_name)    (void);
+-   G_CONST_RETURN gchar* (* get_toolkit_version) (void);
++   const gchar* (* get_toolkit_name)    (void);
++   const gchar* (* get_toolkit_version) (void);
+ };
+ GType atk_util_get_type (void);
+
+@@ -229,17 +229,17 @@ AtkObject* atk_get_focus_object (void);
+ /*
+  * Returns name string for the GUI toolkit.
+  */
+-G_CONST_RETURN gchar *atk_get_toolkit_name (void);
++const gchar *atk_get_toolkit_name (void);
+
+ /*
+  * Returns version string for the GUI toolkit.
+  */
+-G_CONST_RETURN gchar *atk_get_toolkit_version (void);
++const gchar *atk_get_toolkit_version (void);
+
+ /*
+  * Gets the current version of ATK
+  */
+-G_CONST_RETURN gchar *atk_get_version (void);
++const gchar *atk_get_version (void);
+
+ /* --- GType boilerplate --- */
+ /* convenience macros for atk type implementations, which for a type GtkGadgetAccessible will:
+Only in atk/atk: atkutil.h~
+diff -urpb orig/atk-1.32.0/tests/testrelation.c atk/tests/testrelation.c
+--- orig/atk-1.32.0/tests/testrelation.c       2010-09-06 08:45:45.000000000 +0200
++++ atk/tests/testrelation.c   2014-02-17 12:53:42.095119569 +0100
+@@ -28,7 +28,7 @@ static gboolean
+ test_relation (void)
+ {
+   AtkRelationType type1, type2;
+-  G_CONST_RETURN gchar *name;
++  const gchar *name;
+   AtkObject *obj;
+   gboolean ret_value;
+   AtkRelationSet *set;
+@@ -169,7 +169,7 @@ static gboolean
+ test_role (void)
+ {
+   AtkRole role1, role2;
+-  G_CONST_RETURN gchar *name;
++  const gchar *name;
+
+   name = atk_role_get_name (ATK_ROLE_PAGE_TAB);
+   g_return_val_if_fail (name, FALSE);
+@@ -230,7 +230,7 @@ static gboolean
+ test_text_attr (void)
+ {
+   AtkTextAttribute attr1, attr2;
+-  G_CONST_RETURN gchar *name;
++  const gchar *name;
+
+   name = atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP);
+   g_return_val_if_fail (name, FALSE);
+Only in atk/tests/: testrelation.c~
+diff -urpb orig/atk-1.32.0/tests/teststateset.c atk/tests/teststateset.c
+--- orig/atk-1.32.0/tests/teststateset.c       2010-09-06 08:45:45.000000000 +0200
++++ atk/tests/teststateset.c   2014-02-17 12:53:55.675118832 +0100
+@@ -208,7 +208,7 @@ static gboolean
+ test_state (void)
+ {
+   AtkStateType type1, type2;
+-  G_CONST_RETURN gchar *name;
++  const gchar *name;
+
+   name = atk_state_type_get_name (ATK_STATE_VISIBLE);
+   g_return_val_if_fail (name, FALSE);
+
+
+--- orig/atk-1.32.0/atk/Makefile.in    2010-09-27 09:53:57.000000000 +0200
++++ atk/atk/Makefile.in        2014-02-17 12:52:40.443122866 +0100
+@@ -40,7 +40,7 @@ host_triplet = @host@
+ @HAVE_INTROSPECTION_TRUE@am__append_2 = $(gir_DATA) $(typelibs_DATA)
+
+ # ---------- Win32 stuff ----------
+-@OS_WIN32_TRUE@am__append_3 = -export-symbols $(srcdir)/atk.def -no-undefined -Wl,atk-win32-res.o
++@OS_WIN32_TRUE@am__append_3 = -export-symbols atk.def -no-undefined -Wl,atk-win32-res.o
+ @OS_WIN32_FALSE@libatk_1_0_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ @OS_WIN32_FALSE@      $(am__DEPENDENCIES_1)
+ subdir = atk
+@@ -861,7 +861,7 @@ s-enum-types-c: @REBUILD@ $(atk_headers)
+ @HAVE_INTROSPECTION_TRUE@Atk-1.0.gir: libatk-1.0.la Makefile
+
+ @OS_WIN32_TRUE@install-def-file:
+-@OS_WIN32_TRUE@       $(INSTALL) $(srcdir)/atk.def $(DESTDIR)$(libdir)/atk-1.0.def
++@OS_WIN32_TRUE@       $(INSTALL) atk.def $(DESTDIR)$(libdir)/atk-1.0.def
+ @OS_WIN32_TRUE@uninstall-def-file:
+ @OS_WIN32_TRUE@       -rm $(DESTDIR)$(libdir)/atk-1.0.def
+ @OS_WIN32_FALSE@install-def-file:
diff --git a/build-aux/speedo/patches/libiconv-1.14.patch b/build-aux/speedo/patches/libiconv-1.14.patch
new file mode 100755 (executable)
index 0000000..5e60689
--- /dev/null
@@ -0,0 +1,19 @@
+#! /bin/sh
+patch -p0 -l -f $* < $0
+exit $?
+
+On some systems the gets macro has been removed and thus the test
+leads to an unresolved symbol error.
+
+--- srclib/stdio.in.h~ 2011-08-07 15:42:06.000000000 +0200
++++ srclib/stdio.in.h  2014-09-04 13:07:07.079024312 +0200
+@@ -691,11 +691,6 @@
+ _GL_CXXALIAS_SYS (gets, char *, (char *s));
+ #  undef gets
+ # endif
+-_GL_CXXALIASWARN (gets);
+-/* It is very rare that the developer ever has full control of stdin,
+-   so any use of gets warrants an unconditional warning.  Assume it is
+-   always declared, since it is required by C89.  */
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
+ #endif
diff --git a/build-aux/speedo/patches/pango-1.29.4.patch b/build-aux/speedo/patches/pango-1.29.4.patch
new file mode 100755 (executable)
index 0000000..edeee85
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/sh
+patch -p0 -l -f $* < $0
+exit $?
+
+Without that patch the module is build with wrong symbols and thus
+can't be loaded by pango.  I don't know why they have this defines
+just in this module.  It entirely defeats the feature of loading
+modules dynamically - maybe this was just a quick hack for including
+the code directly - however, I was not able to make that work either.
+
+
+--- modules/basic/basic-win32.c~       2011-09-28 16:34:33.000000000 +0200
++++ modules/basic/basic-win32.c        2014-02-20 20:01:10.107723565 +0100
+@@ -33,9 +33,10 @@
+
+ extern HFONT _pango_win32_font_get_hfont (PangoFont *font);
+
+-#ifndef PANGO_MODULE_PREFIX
+-#define PANGO_MODULE_PREFIX _pango_basic_win32
+-#endif
++/* #ifndef PANGO_MODULE_PREFIX */
++/* #define PANGO_MODULE_PREFIX _pango_basic_win32 */
++/* #endif */
++#undef PANGO_MODULE_PREFIX
+
+ #include "pango-engine.h"
+ #include "pango-utils.h"
diff --git a/build-aux/speedo/w32/README.txt b/build-aux/speedo/w32/README.txt
new file mode 100644 (file)
index 0000000..847ecd7
--- /dev/null
@@ -0,0 +1,54 @@
+;; README.txt                               -*- coding: latin-1; -*-
+;; This is the README installed with megacryption.  Lines with a
+;; semicolon in the first column are considered a comment and not
+;; included in the actually installed version.  Certain keywords are
+;; replaced by the Makefile; those words are enclosed by exclamation
+;; marks.
+
+                          GNUPG for Windows
+                         ===================
+
+This is GnuPG for Windows, version !VERSION!.
+
+Content:
+
+     1. Important notes
+     2. Changes
+     3. Legal notices
+
+
+
+
+1. Important Notes
+==================
+
+HTML versions of the manuals have been installed on the desktop.
+Check out https://gnupg.org for latest news.
+
+
+2. Record of Changes (NEWS file)
+================================
+
+Below you find the raw NEWS file:
+
+!NEWSFILE!
+
+
+3. Legal notices pertaining to the individual packets
+=====================================================
+
+GnuPG for Windows consist of several independent developed packages,
+available under different license conditions.  Most of these packages
+are however available under the GNU General Public License (GNU GPL).
+Common to all is that they are free to use without restrictions, may
+be modified and that modifications may be distributed.  If the source
+file (i.e. gnupg-src-k.m.n.zip) is distributed along with the binaries
+and the use of the GNU GPL has been pointed out, distribution is in
+all cases possible.
+
+What follows is a list of copyright statements.
+
+!PKG-COPYRIGHT!
+
+
+***end of file ***
diff --git a/build-aux/speedo/w32/exdll.h b/build-aux/speedo/w32/exdll.h
new file mode 100644 (file)
index 0000000..e5ba3bb
--- /dev/null
@@ -0,0 +1,151 @@
+/* exdll.h for use with gpg4win
+ * Copyright (C) 1999-2005 Nullsoft, Inc.
+ *
+ * This license applies to everything in the NSIS package, except
+ * where otherwise noted.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any
+ * damages arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose, including commercial applications, and to alter it and
+ * redistribute it freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must
+ *    not claim that you wrote the original software. If you use this
+ *    software in a product, an acknowledgment in the product
+ *    documentation would be appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must
+ *    not be misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ *    distribution.
+ ************************************************************
+ * 2005-11-14 wk  Applied license text to orginal exdll.h file from
+ *                NSIS 2.0.4 and did some formatting changes.
+ */
+
+#ifndef _EXDLL_H_
+#define _EXDLL_H_
+
+/* only include this file from one place in your DLL.  (it is all
+   static, if you use it in two places it will fail) */
+
+#define EXDLL_INIT()           {  \
+        g_stringsize=string_size; \
+        g_stacktop=stacktop;      \
+        g_variables=variables; }
+
+/* For page showing plug-ins */
+#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
+#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
+#define NOTIFY_BYE_BYE 'x'
+
+typedef struct _stack_t {
+  struct _stack_t *next;
+  char text[1];          /* This should be the length of string_size. */
+} stack_t;
+
+
+static unsigned int g_stringsize;
+static stack_t **g_stacktop;
+static char *g_variables;
+
+static int __stdcall popstring(char *str, size_t maxlen); /* 0 on success, 1 on empty stack */
+static void __stdcall pushstring(const char *str);
+
+enum
+  {
+    INST_0,         // $0
+    INST_1,         // $1
+    INST_2,         // $2
+    INST_3,         // $3
+    INST_4,         // $4
+    INST_5,         // $5
+    INST_6,         // $6
+    INST_7,         // $7
+    INST_8,         // $8
+    INST_9,         // $9
+    INST_R0,        // $R0
+    INST_R1,        // $R1
+    INST_R2,        // $R2
+    INST_R3,        // $R3
+    INST_R4,        // $R4
+    INST_R5,        // $R5
+    INST_R6,        // $R6
+    INST_R7,        // $R7
+    INST_R8,        // $R8
+    INST_R9,        // $R9
+    INST_CMDLINE,   // $CMDLINE
+    INST_INSTDIR,   // $INSTDIR
+    INST_OUTDIR,    // $OUTDIR
+    INST_EXEDIR,    // $EXEDIR
+    INST_LANG,      // $LANGUAGE
+    __INST_LAST
+};
+
+typedef struct {
+  int autoclose;
+  int all_user_var;
+  int exec_error;
+  int abort;
+  int exec_reboot;
+  int reboot_called;
+  int XXX_cur_insttype; /* deprecated */
+  int XXX_insttype_changed; /* deprecated */
+  int silent;
+  int instdir_error;
+  int rtl;
+  int errlvl;
+} exec_flags_t;
+
+typedef struct {
+  exec_flags_t *exec_flags;
+  int (__stdcall *ExecuteCodeSegment)(int, HWND);
+} extra_parameters_t;
+
+
+/* Utility functions (not required but often useful). */
+static int __stdcall
+popstring(char *str, size_t maxlen)
+{
+  stack_t *th;
+  if (!g_stacktop || !*g_stacktop)
+    return 1;
+  th=(*g_stacktop);
+  lstrcpyn (str, th->text, maxlen);
+  *g_stacktop = th->next;
+  GlobalFree((HGLOBAL)th);
+  return 0;
+}
+
+static void __stdcall
+pushstring(const char *str)
+{
+  stack_t *th;
+  if (!g_stacktop) return;
+  th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
+  lstrcpyn(th->text,str,g_stringsize);
+  th->next=*g_stacktop;
+  *g_stacktop=th;
+}
+
+static char * __stdcall
+getuservariable(const int varnum)
+{
+  if (varnum < 0 || varnum >= __INST_LAST) return NULL;
+  return g_variables+varnum*g_stringsize;
+}
+
+static void __stdcall
+setuservariable(const int varnum, const char *var)
+{
+  if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
+    lstrcpy(g_variables + varnum*g_stringsize, var);
+}
+
+
+
+#endif/*_EXDLL_H_*/
diff --git a/build-aux/speedo/w32/g4wihelp.c b/build-aux/speedo/w32/g4wihelp.c
new file mode 100644 (file)
index 0000000..d2c93e7
--- /dev/null
@@ -0,0 +1,1136 @@
+/* g4wihelp.c - NSIS Helper DLL used with gpg4win. -*- coding: latin-1; -*-
+ * Copyright (C) 2005 g10 Code GmbH
+ * Copyright (C) 2001 Justin Frankel
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any
+ * damages arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose, including commercial applications, and to alter it and
+ * redistribute it freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must
+ *    not claim that you wrote the original software. If you use this
+ *    software in a product, an acknowledgment in the product
+ *    documentation would be appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must
+ *    not be misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ *    distribution.
+ ************************************************************
+ * The code for the splash screen has been taken from the Splash
+ * plugin of the NSIS 2.04 distribution.  That code comes without
+ * explicit copyright notices in tyhe source files or author names, it
+ * seems that it has been written by Justin Frankel; not sure about
+ * the year, though. [wk 2005-11-28]
+ *
+ * Fixed some compiler warnings. [wk 2014-02-24].
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include "exdll.h"
+
+static HINSTANCE g_hInstance; /* Our Instance. */
+static HWND g_hwndParent;     /* Handle of parent window or NULL. */
+static HBITMAP g_hbm;         /* Handle of the splash image. */
+static int sleepint;          /* Milliseconds to show the spals image. */
+
+
+/* Standard entry point for DLLs. */
+int WINAPI
+DllMain (HANDLE hinst, DWORD reason, LPVOID reserved)
+{
+   if (reason == DLL_PROCESS_ATTACH)
+     g_hInstance = hinst;
+   return TRUE;
+}
+
+
+
+/* Dummy function for testing. */
+void __declspec(dllexport)
+dummy (HWND hwndParent, int string_size, char *variables,
+       stack_t **stacktop, extra_parameters_t *extra)
+{
+  g_hwndParent = hwndParent;
+
+  EXDLL_INIT();
+
+  // note if you want parameters from the stack, pop them off in order.
+  // i.e. if you are called via exdll::myFunction file.dat poop.dat
+  // calling popstring() the first time would give you file.dat,
+  // and the second time would give you poop.dat.
+  // you should empty the stack of your parameters, and ONLY your
+  // parameters.
+
+  // do your stuff here
+  {
+    char buf[1024];
+    snprintf (buf, sizeof buf - 1, "$R0=%s\r\n$R1=%s\r\n",
+              getuservariable(INST_R0),
+              getuservariable(INST_R1));
+    MessageBox (g_hwndParent,buf,0,MB_OK);
+
+    snprintf (buf, sizeof buf - 1,
+             "autoclose    =%d\r\n"
+             "all_user_var =%d\r\n"
+             "exec_error   =%d\r\n"
+             "abort        =%d\r\n"
+             "exec_reboot  =%d\r\n"
+             "reboot_called=%d\r\n"
+             "silent       =%d\r\n"
+             "instdir_error=%d\r\n"
+             "rtl          =%d\r\n"
+             "errlvl       =%d\r\n",
+             extra->exec_flags->autoclose,
+             extra->exec_flags->all_user_var,
+             extra->exec_flags->exec_error,
+             extra->exec_flags->abort,
+             extra->exec_flags->exec_reboot,
+             extra->exec_flags->reboot_called,
+             extra->exec_flags->silent,
+             extra->exec_flags->instdir_error,
+             extra->exec_flags->rtl,
+             extra->exec_flags->errlvl);
+    MessageBox(g_hwndParent,buf,0,MB_OK);
+  }
+}
+
+
+void __declspec(dllexport)
+runonce (HWND hwndParent, int string_size, char *variables,
+         stack_t **stacktop, extra_parameters_t *extra)
+{
+  const char *result;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  CreateMutexA (NULL, 0, getuservariable(INST_R0));
+  result = GetLastError ()? "1":"0";
+  setuservariable (INST_R0, result);
+}
+
+
+void __declspec(dllexport)
+playsound (HWND hwndParent, int string_size, char *variables,
+           stack_t **stacktop, extra_parameters_t *extra)
+{
+  char fname[MAX_PATH];
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  if (popstring(fname, sizeof fname))
+    return;
+  PlaySound (fname, NULL, SND_ASYNC|SND_FILENAME|SND_NODEFAULT);
+}
+
+
+void __declspec(dllexport)
+stopsound (HWND hwndParent, int string_size, char *variables,
+           stack_t **stacktop, extra_parameters_t *extra)
+{
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+  PlaySound (NULL, NULL, 0);
+}
+
+
+/* Windows procedure to control the splashimage.  This one pauses the
+   execution until the sleep time is over or the user closes this
+   windows. */
+static LRESULT CALLBACK
+splash_wndproc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+  LRESULT result = 0;
+
+  switch (uMsg)
+    {
+    case WM_CREATE:
+      {
+        BITMAP bm;
+        RECT vp;
+
+        GetObject(g_hbm, sizeof(bm), (LPSTR)&bm);
+        SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);
+        SetWindowLong(hwnd,GWL_STYLE,0);
+        SetWindowPos(hwnd,NULL,
+                     vp.left+(vp.right-vp.left-bm.bmWidth)/2,
+                     vp.top+(vp.bottom-vp.top-bm.bmHeight)/2,
+                     bm.bmWidth,bm.bmHeight,
+                     SWP_NOZORDER);
+        ShowWindow(hwnd,SW_SHOW);
+        SetTimer(hwnd,1,sleepint,NULL);
+      }
+      break;
+
+    case WM_PAINT:
+      {
+        PAINTSTRUCT ps;
+        RECT r;
+        HDC curdc=BeginPaint(hwnd,&ps);
+        HDC hdc=CreateCompatibleDC(curdc);
+        HBITMAP oldbm;
+        GetClientRect(hwnd,&r);
+        oldbm=(HBITMAP)SelectObject(hdc,g_hbm);
+        BitBlt(curdc,r.left,r.top,r.right-r.left,r.bottom-r.top,
+               hdc,0,0,SRCCOPY);
+        SelectObject(hdc,oldbm);
+        DeleteDC(hdc);
+        EndPaint(hwnd,&ps);
+      }
+      break;
+
+    case WM_CLOSE:
+      break;
+
+    case WM_TIMER:
+    case WM_LBUTTONDOWN:
+      DestroyWindow(hwnd);
+      /*(fall through)*/
+    default:
+      result =  DefWindowProc (hwnd, uMsg, wParam, lParam);
+    }
+
+  return result;
+}
+
+
+/* Display a splash screen.  Call as
+
+     g4wihelp::showsplash SLEEP FNAME
+
+   With SLEEP being the time in milliseconds to show the splashscreen
+   and FNAME the complete filename of the image.  As of now only BMP
+   is supported.
+*/
+void __declspec(dllexport)
+showsplash (HWND hwndParent, int string_size, char *variables,
+           stack_t **stacktop, extra_parameters_t *extra)
+{
+  static WNDCLASS wc;
+  char sleepstr[30];
+  char fname[MAX_PATH];
+  int err = 0;
+  char *p;
+  char classname[] = "_sp";
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+  if (popstring(sleepstr, sizeof sleepstr))
+    err = 1;
+  if (popstring(fname, sizeof fname))
+    err = 1;
+  if (err)
+    return;
+
+  if (!*fname)
+    return; /* Nothing to do. */
+
+  for (sleepint=0, p=sleepstr; *p >= '0' && *p <= '9'; p++)
+    {
+      sleepint *= 10;
+      sleepint += *p - '0';
+    }
+  if (sleepint <= 0)
+    return; /* Nothing to do. */
+
+  wc.lpfnWndProc = splash_wndproc;
+  wc.hInstance = g_hInstance;
+  wc.hCursor = LoadCursor(NULL,IDC_ARROW);
+  wc.lpszClassName = classname;
+  if (!RegisterClass(&wc))
+    return; /* Error. */
+
+  g_hbm = LoadImage (NULL, fname, IMAGE_BITMAP,
+                     0, 0 , LR_CREATEDIBSECTION|LR_LOADFROMFILE);
+  if (g_hbm)
+    {
+      MSG msg;
+      HWND hwnd;
+
+      hwnd = CreateWindowEx (WS_EX_TOOLWINDOW, classname, classname,
+                             0, 0, 0, 0, 0, (HWND)hwndParent, NULL,
+                             g_hInstance, NULL);
+
+      while (IsWindow(hwnd) && GetMessage ( &msg, hwnd, 0, 0))
+        {
+          DispatchMessage (&msg);
+        }
+
+      DeleteObject (g_hbm);
+      g_hbm = NULL;
+    }
+  UnregisterClass (classname, g_hInstance);
+}
+
+\f
+/* Service Management.  */
+
+/* Use this to report unexpected errors.  FIXME: This is really not
+   very descriptive.  */
+void
+service_error (const char *str)
+{
+  char buf[1024];
+  snprintf (buf, sizeof (buf) - 1, "error: %s: ec=%d\r\n", str,
+           GetLastError ());
+  MessageBox(g_hwndParent, buf, 0, MB_OK);
+
+  setuservariable (INST_R0, "1");
+}
+
+
+void __declspec(dllexport)
+service_create (HWND hwndParent, int string_size, char *variables,
+                stack_t **stacktop, extra_parameters_t *extra)
+{
+  SC_HANDLE sc;
+  SC_HANDLE service;
+  const char *result = NULL;
+  char service_name[256];
+  char display_name[256];
+  char program[256];
+  int err = 0;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  /* The expected stack layout: service_name, display_name, program.  */
+  if (popstring (service_name, sizeof (service_name)))
+    err = 1;
+  if (!err && popstring (display_name, sizeof (display_name)))
+    err = 1;
+  if (!err && popstring (program, sizeof (program)))
+    err = 1;
+  if (err)
+    {
+      setuservariable (INST_R0, "1");
+      return;
+    }
+
+  sc = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+  if (sc == NULL)
+    {
+      service_error ("OpenSCManager");
+      return;
+    }
+
+  service = CreateService (sc, service_name, display_name,
+                          SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
+                          /* Use SERVICE_DEMAND_START for testing.
+                             FIXME: Currently not configurable by caller.  */
+                          SERVICE_AUTO_START,
+                          SERVICE_ERROR_NORMAL, program,
+                          NULL, NULL, NULL,
+                          /* FIXME: Currently not configurable by caller.  */
+                          /* FIXME: LocalService or NetworkService
+                             don't work for dirmngr right now.  NOTE!
+                             If you change it here, you also should
+                             adjust make-msi.pl for the msi
+                             installer.  In the future, this should
+                             be an argument to the function and then
+                             the make-msi.pl script can extract it
+                             from the invocation.  */
+                          NULL /* "NT AUTHORITY\\LocalService" */,
+                          NULL);
+  if (service == NULL)
+    {
+      service_error ("CreateService");
+      CloseServiceHandle (sc);
+      return;
+    }
+  CloseServiceHandle (service);
+
+  result = GetLastError () ? "1":"0";
+  setuservariable (INST_R0, result);
+  return;
+}
+
+
+/* Requires g_hwndParent to be set!  */
+SC_HANDLE
+service_lookup (char *service_name)
+{
+  SC_HANDLE sc;
+  SC_HANDLE service;
+
+  sc = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+  if (sc == NULL)
+    {
+      service_error ("OpenSCManager");
+      return NULL;
+    }
+  service = OpenService (sc, service_name, SC_MANAGER_ALL_ACCESS);
+  if (service == NULL)
+    {
+      /* Fail silently here.  */
+      CloseServiceHandle (sc);
+      return NULL;
+    }
+  CloseServiceHandle (sc);
+  return service;
+}
+
+
+/* Returns status.  */
+void __declspec(dllexport)
+service_query (HWND hwndParent, int string_size, char *variables,
+              stack_t **stacktop, extra_parameters_t *extra)
+{
+  SC_HANDLE service;
+  const char *result = NULL;
+  char service_name[256];
+  int err = 0;
+  SERVICE_STATUS status;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  /* The expected stack layout: service_name argc [argv].  */
+  if (popstring (service_name, sizeof (service_name)))
+    err = 1;
+  if (err)
+    {
+      setuservariable (INST_R0, "ERROR");
+      return;
+    }
+
+  service = service_lookup (service_name);
+  if (service == NULL)
+  if (err == 0)
+    {
+      setuservariable (INST_R0, "MISSING");
+      return;
+    }
+
+  err = QueryServiceStatus (service, &status);
+  if (err == 0)
+    {
+      setuservariable (INST_R0, "ERROR");
+      CloseServiceHandle (service);
+      return;
+    }
+  CloseServiceHandle (service);
+
+  switch (status.dwCurrentState)
+    {
+    case SERVICE_START_PENDING:
+      result = "START_PENDING";
+      break;
+    case SERVICE_RUNNING:
+      result = "RUNNING";
+      break;
+    case SERVICE_PAUSE_PENDING:
+      result = "PAUSE_PENDING";
+      break;
+    case SERVICE_PAUSED:
+      result = "PAUSED";
+      break;
+    case SERVICE_CONTINUE_PENDING:
+      result = "CONTINUE_PENDING";
+      break;
+    case SERVICE_STOP_PENDING:
+      result = "STOP_PENDING";
+      break;
+    case SERVICE_STOPPED:
+      result = "STOPPED";
+      break;
+    default:
+      result = "UNKNOWN";
+    }
+  setuservariable (INST_R0, result);
+  return;
+}
+
+
+void __declspec(dllexport)
+service_start (HWND hwndParent, int string_size, char *variables,
+              stack_t **stacktop, extra_parameters_t *extra)
+{
+  SC_HANDLE service;
+  const char *result = NULL;
+  char service_name[256];
+  char argc_str[256];
+#define NR_ARGS 10
+#define ARG_MAX 256
+  char argv_str[NR_ARGS][ARG_MAX];
+  const char *argv[NR_ARGS + 1];
+  int argc;
+  int i;
+  int err = 0;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  /* The expected stack layout: service_name argc [argv].  */
+  if (popstring (service_name, sizeof (service_name)))
+    err = 1;
+  if (!err && popstring (argc_str, sizeof (argc_str)))
+    err = 1;
+  if (!err)
+    {
+      argc = atoi (argc_str);
+      for (i = 0; i < argc; i++)
+       {
+         if (popstring (argv_str[i], ARG_MAX))
+           {
+             err = 1;
+             break;
+           }
+         argv[i] = argv_str[i];
+       }
+      argv[i] = NULL;
+    }
+  if (err)
+    {
+      setuservariable (INST_R0, "1");
+      return;
+    }
+
+  service = service_lookup (service_name);
+  if (service == NULL)
+    return;
+
+  err = StartService (service, argc, argc == 0 ? NULL : argv);
+  if (err == 0)
+    {
+      service_error ("StartService");
+      CloseServiceHandle (service);
+      return;
+    }
+  CloseServiceHandle (service);
+
+  setuservariable (INST_R0, "0");
+  return;
+}
+
+
+void __declspec(dllexport)
+service_stop (HWND hwndParent, int string_size, char *variables,
+             stack_t **stacktop, extra_parameters_t *extra)
+{
+  SC_HANDLE service;
+  const char *result = NULL;
+  char service_name[256];
+  int err = 0;
+  SERVICE_STATUS status;
+  DWORD timeout = 10000;       /* 10 seconds.  */
+  DWORD start_time;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  /* The expected stack layout: service_name argc [argv].  */
+  if (popstring (service_name, sizeof (service_name)))
+    err = 1;
+  if (err)
+    {
+      setuservariable (INST_R0, "1");
+      return;
+    }
+
+  service = service_lookup (service_name);
+  if (service == NULL)
+    return;
+
+  err = QueryServiceStatus (service, &status);
+  if (err == 0)
+    {
+      service_error ("QueryService");
+      CloseServiceHandle (service);
+      return;
+    }
+
+  if (status.dwCurrentState != SERVICE_STOPPED
+      && status.dwCurrentState != SERVICE_STOP_PENDING)
+    {
+      err = ControlService (service, SERVICE_CONTROL_STOP, &status);
+      if (err == 0)
+       {
+         service_error ("ControlService");
+         CloseServiceHandle (service);
+         return;
+       }
+    }
+
+  start_time = GetTickCount ();
+  while (status.dwCurrentState != SERVICE_STOPPED)
+    {
+      Sleep (1000);    /* One second.  */
+      if (!QueryServiceStatus (service, &status))
+       {
+         service_error ("QueryService");
+         CloseServiceHandle (service);
+         return;
+       }
+      if (status.dwCurrentState == SERVICE_STOPPED)
+       break;
+
+      if (GetTickCount () - start_time > timeout)
+       {
+         char buf[1024];
+         snprintf (buf, sizeof (buf) - 1,
+                   "time out waiting for service %s to stop\r\n",
+                   service_name);
+         MessageBox (g_hwndParent, buf, 0, MB_OK);
+         setuservariable (INST_R0, "1");
+         return;
+       }
+    }
+  CloseServiceHandle (service);
+  setuservariable (INST_R0, "0");
+  return;
+}
+
+
+void __declspec(dllexport)
+service_delete (HWND hwndParent, int string_size, char *variables,
+               stack_t **stacktop, extra_parameters_t *extra)
+{
+  SC_HANDLE service;
+  const char *result = NULL;
+  char service_name[256];
+  int err = 0;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  /* The expected stack layout: service_name argc [argv].  */
+  if (popstring (service_name, sizeof (service_name)))
+    err = 1;
+  if (err)
+    {
+      setuservariable (INST_R0, "1");
+      return;
+    }
+
+  service = service_lookup (service_name);
+  if (service == NULL)
+    return;
+
+  err = DeleteService (service);
+  if (err == 0)
+    {
+      service_error ("DeleteService");
+      CloseServiceHandle (service);
+      return;
+    }
+  CloseServiceHandle (service);
+
+  setuservariable (INST_R0, "0");
+  return;
+}
+
+\f
+#include <stdio.h>
+
+/* Extract config file parameters.  FIXME: Not particularly robust.
+   We expect some reasonable formatting.  The parser below is very
+   limited.  It expects a command line option /c=FILE or /C=FILE,
+   where FILE must be enclosed in double-quotes if it contains spaces.
+   That file should contain a single section [gpg4win] and KEY=VALUE
+   pairs for each additional configuration file to install.  Comments
+   are supported only on lines by themselves.  VALUE can be quoted in
+   double-quotes, but does not need to be, unless it has whitespace at
+   the beginning or end.  KEY can, for example, be "gpg.conf" (without
+   the quotes).  */
+void
+config_init (char **keys, char **values, int max)
+{
+  /* First, parse the command line.  */
+  char *cmdline;
+  char *begin = NULL;
+  char *end = NULL;
+  char mark;
+  char *fname;
+  char *ptr;
+  FILE *conf;
+
+  *keys = NULL;
+  *values = NULL;
+
+  cmdline = getuservariable (INST_CMDLINE);
+
+  mark = (*cmdline == '"') ? (cmdline++, '"') : ' ';
+  while (*cmdline && *cmdline != mark)
+    cmdline++;
+  if (mark == '"' && *cmdline)
+    cmdline++;
+  while (*cmdline && *cmdline == ' ')
+    cmdline++;
+
+  while (*cmdline)
+    {
+      /* We are at the beginning of a new argument.  */
+      if (cmdline[0] == '/' && (cmdline[1] == 'C' || cmdline[1] == 'c')
+         && cmdline[2] == '=')
+       {
+         cmdline += 3;
+         begin = cmdline;
+       }
+
+      while (*cmdline && *cmdline != ' ')
+       {
+         /* Skip over quoted parts.  */
+         if (*cmdline == '"')
+           {
+             cmdline++;
+             while (*cmdline && *cmdline != '"')
+               cmdline++;
+             if (*cmdline)
+               cmdline++;
+           }
+         else
+           cmdline++;
+       }
+      if (begin && !end)
+       {
+         end = cmdline - 1;
+         break;
+       }
+      while (*cmdline && *cmdline == ' ')
+       cmdline++;
+    }
+
+  if (!begin || begin > end)
+    return;
+
+  /* Strip quotes.  */
+  if (*begin == '"' && *end == '"')
+    {
+      begin++;
+      end--;
+    }
+  if (begin > end)
+    return;
+
+  fname = malloc (end - begin + 2);
+  if (!fname)
+    return;
+
+  ptr = fname;
+  while (begin <= end)
+    *(ptr++) = *(begin++);
+  *ptr = '\0';
+
+  conf = fopen (fname, "r");
+  free (fname);
+  if (!conf)
+    return;
+
+  while (max - 1 > 0)
+    {
+      char line[256];
+      char *ptr2;
+
+      if (fgets (line, sizeof (line), conf) == NULL)
+       break;
+      ptr = &line[strlen (line)];
+      while (ptr > line && (ptr[-1] == '\n' || ptr[-1] == '\r'
+                           || ptr[-1] == ' ' || ptr[-1] == '\t'))
+       ptr--;
+      *ptr = '\0';
+
+      ptr = line;
+      while (*ptr && (*ptr == ' ' || *ptr == '\t'))
+       ptr++;
+      /* Ignore comment lines.  */
+      /* FIXME: Ignore section markers.  */
+      if (*ptr == '\0' || *ptr == ';' || *ptr == '[')
+       continue;
+      begin = ptr;
+      while (*ptr && *ptr != '=' && *ptr != ' ' && *ptr != '\t')
+       ptr++;
+      end = ptr - 1;
+      while (*ptr && (*ptr == ' ' || *ptr == '\t'))
+       ptr++;
+      if (*ptr != '=')
+       continue;
+      ptr++;
+
+      if (begin > end)
+       continue;
+
+      /* We found a key.  */
+      *keys = malloc (end - begin + 2);
+      if (!keys)
+       return;
+      ptr2 = *keys;
+      while (begin <= end)
+       *(ptr2++) = *(begin++);
+      *ptr2 = '\0';
+
+      *values = NULL;
+
+      while (*ptr && (*ptr == ' ' || *ptr == '\t'))
+       ptr++;
+      begin = ptr;
+      /* In this case, end points to the byte after the value, which
+        is OK because that is '\0'.  */
+      end = &line[strlen (line)];
+      if (begin > end)
+       begin = end;
+
+      /* Strip quotes.  */
+      if (*begin == '"' && end[-1] == '"')
+       {
+         begin++;
+         end--;
+         *end = '\0';
+       }
+      if (begin > end)
+       return;
+
+      *values = malloc (end - begin + 1);
+      ptr2 = *values;
+      while (begin <= end)
+       *(ptr2++) = *(begin++);
+
+      keys++;
+      values++;
+      max--;
+    }
+
+  fclose (conf);
+  *keys = NULL;
+  *values = NULL;
+}
+
+
+char *
+config_lookup (char *key)
+{
+#define MAX_KEYS 128
+  static int initialised = 0;
+  static char *keys[MAX_KEYS];
+  static char *values[MAX_KEYS];
+  int i;
+
+  if (initialised == 0)
+    {
+      initialised = 1;
+      config_init (keys, values, MAX_KEYS);
+
+#if 0
+      MessageBox(g_hwndParent, "Configuration File:", 0, MB_OK);
+      i = 0;
+      while (keys[i])
+       {
+         char buf[256];
+         sprintf (buf, "%s=%s\r\n", keys[i], values[i]);
+         MessageBox (g_hwndParent, buf, 0, MB_OK);
+         i++;
+       }
+#endif
+    }
+
+  i = 0;
+  while (keys[i])
+    {
+      if (!strcmp (keys[i], key))
+       return values[i];
+      i++;
+    }
+
+  return NULL;
+}
+
+
+void __declspec(dllexport)
+config_fetch (HWND hwndParent, int string_size, char *variables,
+             stack_t **stacktop, extra_parameters_t *extra)
+{
+  char key[256];
+  int err = 0;
+  char *value;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  /* The expected stack layout: key.  */
+  if (popstring (key, sizeof (key)))
+    err = 1;
+  if (err)
+    {
+      setuservariable (INST_R0, "");
+      return;
+    }
+
+  value = config_lookup (key);
+
+  setuservariable (INST_R0, value == NULL ? "" : value);
+  return;
+}
+
+
+void __declspec(dllexport)
+config_fetch_bool (HWND hwndParent, int string_size, char *variables,
+                  stack_t **stacktop, extra_parameters_t *extra)
+{
+  char key[256];
+  int err = 0;
+  char *value;
+  int result;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  /* The expected stack layout: key.  */
+  if (popstring (key, sizeof (key)))
+    err = 1;
+  if (err)
+    {
+      setuservariable (INST_R0, "");
+      return;
+    }
+
+  value = config_lookup (key);
+  if (value == NULL || *value == '\0')
+    {
+      setuservariable (INST_R0, "");
+      return;
+    }
+
+  result = 0;
+  if (!strcasecmp (value, "true")
+      || !strcasecmp (value, "yes")
+      || atoi (value) != 0)
+    result = 1;
+
+  setuservariable (INST_R0, result == 0 ? "0" : "1");
+  return;
+}
+
+\f
+/* Return a string from the Win32 Registry or NULL in case of error.
+   Caller must release the return value.  A NULL for root is an alias
+   for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn.  */
+char *
+read_w32_registry_string (HKEY root, const char *dir, const char *name)
+{
+  HKEY root_key;
+  HKEY key_handle;
+  DWORD n1, nbytes, type;
+  char *result = NULL;
+
+  root_key = root;
+  if (! root_key)
+    root_key = HKEY_CURRENT_USER;
+
+  if( RegOpenKeyEx( root_key, dir, 0, KEY_READ, &key_handle ) )
+    {
+      if (root)
+       return NULL; /* no need for a RegClose, so return direct */
+      /* It seems to be common practise to fall back to HKLM. */
+      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) )
+       return NULL; /* still no need for a RegClose, so return direct */
+    }
+
+  nbytes = 1;
+  if( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) {
+    if (root)
+      goto leave;
+    /* Try to fallback to HKLM also vor a missing value.  */
+    RegCloseKey (key_handle);
+    if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) )
+      return NULL; /* Nope.  */
+    if (RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes))
+      goto leave;
+  }
+
+  result = malloc( (n1=nbytes+1) );
+
+  if( !result )
+    goto leave;
+  if( RegQueryValueEx( key_handle, name, 0, &type, result, &n1 ) ) {
+    free(result); result = NULL;
+    goto leave;
+  }
+  result[nbytes] = 0; /* make sure it is really a string  */
+
+ leave:
+  RegCloseKey( key_handle );
+  return result;
+}
+
+
+#define ENV_HK HKEY_LOCAL_MACHINE
+#define ENV_REG "SYSTEM\\CurrentControlSet\\Control\\" \
+    "Session Manager\\Environment"
+  /* The following setting can be used for a per-user setting.  */
+#if 0
+#define ENV_HK HKEY_CURRENT_USER
+#define ENV_REG "Environment"
+#endif
+/* Due to a bug in Windows7 (kb 2685893) we better put a lower limit
+   than 8191 on the maximum length of the PATH variable.  Note, that
+   depending on the used toolchain we used to had a 259 byte limit in
+   the past.  */
+#define PATH_LENGTH_LIMIT 2047
+
+void __declspec(dllexport)
+path_add (HWND hwndParent, int string_size, char *variables,
+         stack_t **stacktop, extra_parameters_t *extra)
+{
+  char dir[PATH_LENGTH_LIMIT];
+  char *path;
+  char *path_new;
+  int path_new_size;
+  char *comp;
+  const char delims[] = ";";
+  HKEY key_handle = 0;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  setuservariable (INST_R0, "0");
+
+/*   MessageBox (g_hwndParent, "XXX 1", 0, MB_OK); */
+
+  /* The expected stack layout: path component.  */
+  if (popstring (dir, sizeof (dir)))
+    return;
+
+/*   MessageBox (g_hwndParent, "XXX 2", 0, MB_OK); */
+
+  path = read_w32_registry_string (ENV_HK, ENV_REG, "Path");
+  if (! path)
+    {
+      MessageBox (g_hwndParent, "No PATH variable found", 0, MB_OK);
+      return;
+    }
+
+/*   MessageBox (g_hwndParent, "XXX 3", 0, MB_OK); */
+
+  /* Old path plus semicolon plus dir plus terminating nul.  */
+  path_new_size = strlen (path) + 1 + strlen (dir) + 1;
+  if (path_new_size > PATH_LENGTH_LIMIT)
+    {
+      MessageBox (g_hwndParent, "PATH env variable too big", 0, MB_OK);
+      free (path);
+      return;
+    }
+
+/*   MessageBox (g_hwndParent, "XXX 4", 0, MB_OK); */
+
+  path_new = malloc (path_new_size);
+  if (!path_new)
+    {
+      free (path);
+      return;
+    }
+
+/*   MessageBox (g_hwndParent, "XXX 5", 0, MB_OK); */
+
+  strcpy (path_new, path);
+  strcat (path_new, ";");
+  strcat (path_new, dir);
+
+/*   MessageBox (g_hwndParent, "XXX 6", 0, MB_OK); */
+/*   MessageBox (g_hwndParent, dir, 0, MB_OK); */
+/*   MessageBox (g_hwndParent, "XXX 7", 0, MB_OK); */
+
+  /* Check if the directory already exists in the path.  */
+  comp = strtok (path, delims);
+  do
+    {
+/*       MessageBox (g_hwndParent, comp, 0, MB_OK); */
+
+      if (!strcmp (comp, dir))
+       {
+         free (path);
+         free (path_new);
+         return;
+       }
+      comp = strtok (NULL, delims);
+    }
+  while (comp);
+  free (path);
+
+/*   MessageBox (g_hwndParent, "XXX 8", 0, MB_OK); */
+
+  /* Set a key for our CLSID.  */
+  RegCreateKey (ENV_HK, ENV_REG, &key_handle);
+  RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
+                path_new, path_new_size);
+  RegCloseKey (key_handle);
+  SetEnvironmentVariable("PATH", path_new);
+  free (path_new);
+
+/*   MessageBox (g_hwndParent, "XXX 9", 0, MB_OK); */
+
+  setuservariable (INST_R0, "1");
+}
+
+
+void __declspec(dllexport)
+path_remove (HWND hwndParent, int string_size, char *variables,
+            stack_t **stacktop, extra_parameters_t *extra)
+{
+  char dir[PATH_LENGTH_LIMIT];
+  char *path;
+  char *path_new;
+  int path_new_size;
+  char *comp;
+  const char delims[] = ";";
+  HKEY key_handle = 0;
+  int changed = 0;
+  int count = 0;
+
+  g_hwndParent = hwndParent;
+  EXDLL_INIT();
+
+  setuservariable (INST_R0, "0");
+
+  /* The expected stack layout: path component.  */
+  if (popstring (dir, sizeof (dir)))
+    return;
+
+  path = read_w32_registry_string (ENV_HK, ENV_REG, "Path");
+  /* Old path plus semicolon plus dir plus terminating nul.  */
+  path_new_size = strlen (path) + 1;
+  path_new = malloc (path_new_size);
+  if (!path_new)
+    {
+      free (path);
+      return;
+    }
+  path_new[0] = '\0';
+
+  /* Compose the new path.  */
+  comp = strtok (path, delims);
+  do
+    {
+      if (strcmp (comp, dir))
+       {
+         if (count != 0)
+           strcat (path_new, ";");
+         strcat (path_new, comp);
+         count++;
+       }
+      else
+       changed = 1;
+
+      comp = strtok (NULL, delims);
+    }
+  while (comp);
+  free (path);
+
+  if (! changed)
+    return;
+
+  /* Set a key for our CLSID.  */
+  RegCreateKey (ENV_HK, ENV_REG, &key_handle);
+  RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
+                path_new, path_new_size);
+  RegCloseKey (key_handle);
+  free (path_new);
+
+  setuservariable (INST_R0, "1");
+}
diff --git a/build-aux/speedo/w32/gdk-pixbuf-loaders.cache b/build-aux/speedo/w32/gdk-pixbuf-loaders.cache
new file mode 100755 (executable)
index 0000000..78bc18a
--- /dev/null
@@ -0,0 +1,138 @@
+# GdkPixbuf Image Loader Modules file
+# Automatically generated file, do not edit
+# Created by gdk-pixbuf-query-loaders.exe from gdk-pixbuf-2.26.5
+#
+# LoaderDir = ../lib/gdk-pixbuf-2.0/2.10.0/loaders
+#
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ani.dll"
+"ani" 4 "gdk-pixbuf" "The ANI image format" "LGPL"
+"application/x-navi-animation" ""
+"ani" ""
+"RIFF    ACON" "    xxxx    " 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-bmp.dll"
+"bmp" 5 "gdk-pixbuf" "The BMP image format" "LGPL"
+"image/bmp" "image/x-bmp" "image/x-MS-bmp" ""
+"bmp" ""
+"BM" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-emf.dll"
+"emf" 4 "gdk-pixbuf" "The EMF image format" "LGPL"
+"application/emf" "application/x-emf" "image/x-emf" "image/x-mgx-emf" ""
+"emf" ""
+"\001" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-gif.dll"
+"gif" 5 "gdk-pixbuf" "The GIF image format" "LGPL"
+"image/gif" ""
+"gif" ""
+"GIF8" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-ico.dll"
+"ico" 4 "gdk-pixbuf" "The ICO image format" "LGPL"
+"image/x-icon" "image/x-ico" ""
+"ico" "cur" ""
+"  \001   " "zz znz" 100
+"  \002   " "zz znz" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-jpeg.dll"
+"jpeg" 5 "gdk-pixbuf" "The JPEG image format" "LGPL"
+"image/jpeg" ""
+"jpeg" "jpe" "jpg" ""
+"\377\330" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-tiff.dll"
+"tiff" 5 "gdk-pixbuf" "The TIFF image format" "LGPL"
+"image/tiff" ""
+"tiff" "tif" ""
+"MM *" "  z " 100
+"II* " "   z" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-wmf.dll"
+"wmf" 4 "gdk-pixbuf" "The WMF image format" "LGPL"
+"image/x-wmf" ""
+"wmf" "apm" ""
+"\327\315\306\232" "" 100
+"\001" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-icns.dll"
+"icns" 4 "gdk-pixbuf" "The ICNS image format" "GPL"
+"image/x-icns" ""
+"icns" ""
+"icns" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-pcx.dll"
+"pcx" 4 "gdk-pixbuf" "The PCX image format" "LGPL"
+"image/x-pcx" ""
+"pcx" ""
+"\n \001" "" 100
+"\n\002\001" "" 100
+"\n\003\001" "" 100
+"\n\004\001" "" 100
+"\n\005\001" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.dll"
+"png" 5 "gdk-pixbuf" "The PNG image format" "LGPL"
+"image/png" ""
+"png" ""
+"\211PNG\r\n\032\n" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-pnm.dll"
+"pnm" 4 "gdk-pixbuf" "The PNM/PBM/PGM/PPM image format family" "LGPL"
+"image/x-portable-anymap" "image/x-portable-bitmap" "image/x-portable-graymap" "image/x-portable-pixmap" ""
+"pnm" "pbm" "pgm" "ppm" ""
+"P1" "" 100
+"P2" "" 100
+"P3" "" 100
+"P4" "" 100
+"P5" "" 100
+"P6" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-qtif.dll"
+"qtif" 4 "gdk-pixbuf" "The QTIF image format" "LGPL"
+"image/x-quicktime" "image/qtif" ""
+"qtif" "qif" ""
+"abcdidsc" "xxxx    " 100
+"abcdidat" "xxxx    " 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ras.dll"
+"ras" 4 "gdk-pixbuf" "The Sun raster image format" "LGPL"
+"image/x-cmu-raster" "image/x-sun-raster" ""
+"ras" ""
+"Y\246j\225" "" 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-tga.dll"
+"tga" 4 "gdk-pixbuf" "The Targa image format" "LGPL"
+"image/x-tga" ""
+"tga" "targa" ""
+" \001\001" "x  " 100
+" \001\t" "x  " 100
+"  \002" "xz " 99
+"  \003" "xz " 100
+"  \n" "xz " 100
+"  \v" "xz " 100
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-wbmp.dll"
+"wbmp" 4 "gdk-pixbuf" "The WBMP image format" "LGPL"
+"image/vnd.wap.wbmp" ""
+"wbmp" ""
+"  " "zz" 1
+" `" "z " 1
+" @" "z " 1
+"  " "z " 1
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-xbm.dll"
+"xbm" 4 "gdk-pixbuf" "The XBM image format" "LGPL"
+"image/x-xbitmap" ""
+"xbm" ""
+"#define " "" 100
+"/*" "" 50
+
+"../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-xpm.dll"
+"xpm" 4 "gdk-pixbuf" "The XPM image format" "LGPL"
+"image/x-xpixmap" ""
+"xpm" ""
+"/* XPM */" "" 100
+
+
+# eof #
diff --git a/build-aux/speedo/w32/inst-options.ini b/build-aux/speedo/w32/inst-options.ini
new file mode 100644 (file)
index 0000000..8697e89
--- /dev/null
@@ -0,0 +1,46 @@
+[Settings]
+NumFields=5
+
+; The number of the fields here is known in w32inst.nsi.
+; The tags must be "[Field N]" with N=1..NumFields
+
+[Field 1]
+Type=Label
+Left=0
+Right=-1
+Top=0
+Bottom=20
+
+[Field 2]
+Type=Checkbox
+Left=0
+Right=-1
+Top=30
+Bottom=40
+;Text=Start Menu
+State=1
+
+[Field 3]
+Type=Checkbox
+Left=0
+Right=-1
+Top=50
+Bottom=60
+;Text=Desktop
+State=0
+
+[Field 4]
+Type=Checkbox
+Left=0
+Right=-1
+Top=70
+Bottom=80
+;Text=Quick Launch Bar
+State=0
+
+[Field 5]
+Type=Label
+Left=0
+Right=-1
+Top=90
+Bottom=130
diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi
new file mode 100644 (file)
index 0000000..707b058
--- /dev/null
@@ -0,0 +1,1257 @@
+# inst.nsi - Installer for GnuPG on Windows.      -*- coding: latin-1; -*-
+# Copyright (C) 2005, 2014 g10 Code GmbH
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# Macros to provide for invocation:
+#  INST_DIR
+#  INST6_DIR
+#  BUILD_DIR
+#  TOP_SRCDIR
+#  W32_SRCDIR
+#  BUILD_ISODATE
+#  NAME
+#  VERSION
+#  PROD_VERSION
+
+!cd "${INST_DIR}"
+!addincludedir "${W32_SRCDIR}"
+!addplugindir "${BUILD_DIR}"
+
+# The package name and version.  PRETTY_PACKAGE is a user visible name
+# only while PACKAGE is useful for filenames etc.  PROD_VERSION is the
+# product version and needs to be in the format "MAJ.MIN.MIC.BUILDNR".
+!define PACKAGE "gnupg"
+!define PACKAGE_SHORT "gnupg"
+!define PRETTY_PACKAGE "GNU Privacy Guard"
+!define PRETTY_PACKAGE_SHORT "GnuPG"
+!define COMPANY "The GnuPG Project"
+!define COPYRIGHT "Copyright (C) 2014 The GnuPG Project"
+!define DESCRIPTION "GnuPG: The GNU Privacy Guard for Windows"
+
+!define INSTALL_DIR "GnuPG"
+
+!define WELCOME_TITLE_ENGLISH \
+ "Welcome to the installation of GnuPG"
+
+!define WELCOME_TITLE_GERMAN \
+ "Willkommen bei der Installation von GnuPG"
+
+!define ABOUT_ENGLISH \
+ "GnuPG is the mostly used software for mail and data encryption. \
+  GnuPG can be used to encrypt data and to create digital signatures. \
+  GnuPG includes an advanced key management facility and is compliant \
+  with the OpenPGP Internet standard as described in RFC-4880. \
+  \r\n\r\n$_CLICK \
+  \r\n\r\n\r\n\r\n\r\nThis is GnuPG version ${VERSION}.\r\n\
+  File version: ${PROD_VERSION}\r\n\
+  Release date: ${BUILD_ISODATE}"
+!define ABOUT_GERMAN \
+ "GnuPG is die häufigst verwendete Software zur Mail- und Datenverschlüsselung.\
+   \r\n\r\n$_CLICK \
+   \r\n\r\n\r\n\r\n\r\nDies ist GnuPG Version ${VERSION}.\r\n\
+   Dateiversion: ${PROD_VERSION}\r\n\
+   Releasedatum: ${BUILD_ISODATE}"
+
+
+# The copyright license of the package.  Define only one of these.
+!define LICENSE_GPL
+
+# Select the best compression algorithm available.  The dictionary
+# size is the default (8 MB).
+!ifndef SOURCES
+SetCompressor lzma
+# SetCompressorDictSize 8
+!endif
+
+# Include the generic parts.
+!define HAVE_STARTMENU
+
+# We use the modern UI.
+!include "MUI.nsh"
+
+# Some helper some
+!include "LogicLib.nsh"
+!include "x64.nsh"
+
+# Set the package name.  Note that this name should not be suffixed
+# with the version because this would get displayed in the start menu.
+# Given that a slash in the name troubles Windows startmenu creation
+# we set the Startmenu explicit below.
+Name "${PRETTY_PACKAGE}"
+
+# Set the output filename.
+OutFile "${NAME}-${VERSION}.exe"
+
+#Fixme: Do we need a logo
+#Icon "${TOP_SRCDIR}/doc/logo/gnupg-logo-icon.ico"
+#UninstallIcon "${TOP_SRCDIR}/doc/logo/gnupg-logo-icon.ico"
+
+# Set the installation directory.
+!ifndef INSTALL_DIR
+!define INSTALL_DIR "GnuPG"
+!endif
+InstallDir "$PROGRAMFILES\GNU\${INSTALL_DIR}"
+
+InstallDirRegKey HKLM "Software\GNU\${PACKAGE_SHORT}" "Install Directory"
+
+
+# Add version information to the file properties.
+VIProductVersion "${PROD_VERSION}"
+VIAddVersionKey "ProductName" "${PRETTY_PACKAGE_SHORT} (${VERSION})"
+VIAddVersionKey "Comments" \
+   "GnuPG is Free Software; you can redistribute it  \
+    and/or modify it under the terms of the GNU General Public License.  \
+    You should have received a copy of the GNU General Public License  \
+    along with this software; if not, write to the Free Software  \
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,  \
+    MA 02110-1301, USA"
+VIAddVersionKey "CompanyName" "${COMPANY}"
+VIAddVersionKey "LegalTrademarks" ""
+VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
+VIAddVersionKey "FileDescription" "${DESCRIPTION}"
+VIAddVersionKey "FileVersion" "${PROD_VERSION}"
+
+# Interface Settings
+
+# !define MUI_ABORTWARNING
+!define MUI_FINISHPAGE_NOAUTOCLOSE
+!define MUI_UNFINISHPAGE_NOAUTOCLOSE
+
+#!define MUI_HEADERIMAGE
+#!define MUI_HEADERIMAGE_BITMAP \
+#               "${TOP_SRCDIR}/doc/logo/gnupg-logo-150x57.bmp"
+#!define MUI_WELCOMEFINISHPAGE_BITMAP \
+#               "${TOP_SRCDIR}/doc/logo/gnupg-logo-164x314.bmp"
+
+# Remember the installer language
+!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
+!define MUI_LANGDLL_REGISTRY_KEY "Software\GNU\GnuPG"
+!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
+
+#
+# The list of wizard pages.
+#
+!define MUI_WELCOMEPAGE_TITLE "$(T_WelcomeTitle)"
+!define MUI_WELCOMEPAGE_TEXT  "$(T_About)"
+!insertmacro MUI_PAGE_WELCOME
+
+!define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)"
+!define MUI_PAGE_HEADER_SUBTEXT "$(T_GPLHeader)"
+!define MUI_LICENSEPAGE_TEXT_BOTTOM "$(T_GPLShort)"
+!insertmacro MUI_PAGE_LICENSE "${TOP_SRCDIR}/COPYING"
+
+!define MUI_PAGE_CUSTOMFUNCTION_SHOW PrintNonAdminWarning
+!insertmacro MUI_PAGE_COMPONENTS
+
+!define MUI_PAGE_CUSTOMFUNCTION_LEAVE CheckExistingVersion
+!insertmacro MUI_PAGE_DIRECTORY
+
+!ifdef HAVE_STARTMENU
+
+Page custom CustomPageOptions
+
+Var STARTMENU_FOLDER
+
+!define MUI_PAGE_CUSTOMFUNCTION_PRE CheckIfStartMenuWanted
+!define MUI_STARTMENUPAGE_NODISABLE
+!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
+!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\GNU\GnuPG"
+!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
+# We need to set the Startmenu name explicitly because a slash in the
+# name is not possible.
+!define MUI_STARTMENUPAGE_DEFAULTFOLDER "GnuPG"
+
+!insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
+
+!endif
+
+!define MUI_PAGE_CUSTOMFUNCTION_PRE PrintCloseOtherApps
+!insertmacro MUI_PAGE_INSTFILES
+
+#!define MUI_PAGE_CUSTOMFUNCTION_PRE ShowFinalWarnings
+!define MUI_FINISHPAGE_SHOWREADME "README.txt"
+!define MUI_FINISHPAGE_SHOWREADME_TEXT "$(T_ShowReadme)"
+#!define MUI_FINISHPAGE_RUN
+#!define MUI_FINISHPAGE_RUN_FUNCTION RunOnFinish
+#!define MUI_FINISHPAGE_RUN_TEXT "$(T_RunKeyManager)"
+#!define MUI_FINISHPAGE_RUN_NOTCHECKED
+!define MUI_FINISHPAGE_LINK "$(T_MoreInfo)"
+!define MUI_FINISHPAGE_LINK_LOCATION "$(T_MoreInfoURL)"
+!insertmacro MUI_PAGE_FINISH
+
+
+# Uninstaller pages.
+
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+
+
+#Page license
+#Page components
+#Page directory
+#Page instfiles
+#UninstPage uninstConfirm
+#UninstPage instfiles
+
+
+# Language support.  This has to be done after defining the pages, but
+# before defining the translation strings.  Confusing.
+
+!insertmacro MUI_LANGUAGE "English"
+!insertmacro MUI_LANGUAGE "German"
+
+!insertmacro MUI_RESERVEFILE_LANGDLL
+!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+ReserveFile "${BUILD_DIR}\g4wihelp.dll"
+#ReserveFile "${TOP_SRCDIR}\doc\logo\gnupg-logo-400px.bmp"
+#ReserveFile "${W32_SRCDIR}\gnupg-splash.wav"
+ReserveFile "${TOP_SRCDIR}\COPYING"
+ReserveFile "${W32_SRCDIR}\inst-options.ini"
+#ReserveFile "${TOP_SRCDIR}\doc\logo\gnupg-logo-164x314.bmp"
+
+# Language support
+
+LangString T_LangCode ${LANG_ENGLISH} "en"
+LangString T_LangCode ${LANG_GERMAN}  "de"
+
+
+# The WelcomeTitle is displayed on the first page.
+LangString T_WelcomeTitle ${LANG_ENGLISH} "${WELCOME_TITLE_ENGLISH}"
+LangString T_WelcomeTitle ${LANG_GERMAN} "${WELCOME_TITLE_GERMAN}"
+
+# The About string as displayed on the first page.
+LangString T_About ${LANG_ENGLISH} "${ABOUT_ENGLISH}"
+LangString T_About ${LANG_GERMAN} "${ABOUT_GERMAN}"
+
+# Startup page
+LangString T_GPLHeader ${LANG_ENGLISH} \
+  "This software is licensed under the terms of the GNU General Public \
+   License (GNU GPL)."
+LangString T_GPLHeader ${LANG_GERMAN}} \
+  "Diese Software ist unter der GNU General Public License \
+   (GNU GPL) lizensiert."
+
+LangString T_GPLShort ${LANG_ENGLISH} \
+  "In short: You are allowed to run this software for any purpose. \
+   You may distribute it as long as you give the recipients the same \
+   rights you have received."
+LangString T_GPLShort ${LANG_GERMAN} \
+  "In aller Kürze: Sie haben das Recht, die Software zu jedem Zweck \
+   einzusetzen.  Sie können die Software weitergeben, sofern Sie dem \
+   Empfänger dieselben Rechte einräumen, die auch Sie erhalten haben."
+
+LangString T_RunKeyManager ${LANG_ENGLISH} \
+   "Run the key manager"
+LangString T_RunKeyManager ${LANG_GERMAN} \
+   "Die Schlüsselverwaltung aufrufen"
+
+LangString T_MoreInfo ${LANG_ENGLISH} \
+   "Click here for GnuPG's website"
+LangString T_MoreInfo ${LANG_GERMAN} \
+   "Hier klicken um zur GnuPG Homepage zu gelangen"
+LangString T_MoreInfoURL ${LANG_ENGLISH} "https://gnupg.org"
+LangString T_MoreInfoURL ${LANG_GERMAN}  "https://gnupg.org"
+
+LangString T_ShowReadme ${LANG_ENGLISH} \
+   "Show the README file"
+LangString T_ShowReadme ${LANG_GERMAN} \
+   "Die README Datei anzeigen"
+
+LangString T_NoKeyManager ${LANG_ENGLISH} \
+   "No key manager has been installed, thus we can't run one now."
+LangString T_NoKeyManager ${LANG_GERMAN} \
+   "Es wurde keine Schlüsselverwaltung installiert. \
+    Deswegen kann sie jetzt auch nicht ausgeführt werden."
+
+# Functions
+
+# Custom functions and macros for this installer.
+LangString T_AlreadyRunning ${LANG_ENGLISH} \
+   "An instance of this installer is already running."
+LangString T_AlreadyRunning ${LANG_GERMAN} \
+   "Ein Exemplar dieses Installers läuft bereits."
+
+Function G4wRunOnce
+  Push $R0
+  StrCpy $R0 "gnupg"
+  g4wihelp::runonce
+  StrCmp $R0 0 +3
+     MessageBox MB_OK $(T_AlreadyRunning)
+     Abort
+  Pop $R0
+FunctionEnd
+
+#
+# Control function for the Custom page to select special
+# install options.
+#
+Function CustomPageOptions
+  !insertmacro MUI_HEADER_TEXT "$(T_InstallOptions)" "$(T_InstallOptLinks)"
+
+  # Note, that the default selection is done in the ini file
+  !insertmacro MUI_INSTALLOPTIONS_WRITE "${W32_SRCDIR}/inst-options.ini" \
+       "Field 1" "Text"  "$(T_InstOptLabelA)"
+  !insertmacro MUI_INSTALLOPTIONS_WRITE "${W32_SRCDIR}/inst-options.ini" \
+       "Field 2" "Text"  "$(T_InstOptFieldA)"
+  !insertmacro MUI_INSTALLOPTIONS_WRITE "${W32_SRCDIR}/inst-options.ini" \
+       "Field 3" "Text"  "$(T_InstOptFieldB)"
+  !insertmacro MUI_INSTALLOPTIONS_WRITE "${W32_SRCDIR}/inst-options.ini" \
+       "Field 4" "Text"  "$(T_InstOptFieldC)"
+  !insertmacro MUI_INSTALLOPTIONS_WRITE "${W32_SRCDIR}/inst-options.ini" \
+       "Field 5" "Text"  "$(T_InstOptLabelB)"
+
+  !insertmacro MUI_INSTALLOPTIONS_DISPLAY "${W32_SRCDIR}/inst-options.ini"
+FunctionEnd
+
+
+# Check whether GnuPG has already been installed.  This is called as
+# a leave function from the directory page.  A call to abort will get
+# back to the directory selection.
+Function CheckExistingVersion
+  ClearErrors
+  FileOpen $0 "$INSTDIR\VERSION" r
+  IfErrors nexttest
+  FileRead $0 $R0
+  FileRead $0 $R1
+  FileClose $0
+
+  Push $R1
+  Call TrimNewLines
+  Pop $R1
+
+  MessageBox MB_YESNO "$(T_FoundExistingVersion)" IDYES leave
+  Abort
+
+ nexttest:
+  ClearErrors
+  ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG" "DisplayVersion"
+  IfErrors leave 0
+     MessageBox MB_YESNO "$(T_FoundExistingVersionB)" IDYES leave
+     Abort
+
+ leave:
+FunctionEnd
+
+
+
+# PrintNonAdminWarning
+
+# Check whether the current user is in the Administrator group or an
+# OS version without the need for an Administrator is in use.  Print a
+# diagnostic if this is not the case and abort installation.
+Function PrintNonAdminWarning
+  ClearErrors
+  UserInfo::GetName
+  IfErrors leave
+  Pop $0
+  UserInfo::GetAccountType
+  Pop $1
+  StrCmp $1 "Admin" leave +1
+  MessageBox MB_OK "$(T_AdminNeeded)"
+  Quit
+
+ leave:
+FunctionEnd
+
+
+# Check whether the start menu is actually wanted.
+
+Function CheckIfStartMenuWanted
+  !insertmacro MUI_INSTALLOPTIONS_READ $R0 "${W32_SRCDIR}/inst-options.ini" \
+       "Field 2" "State"
+  IntCmp $R0 1 +2
+    Abort
+FunctionEnd
+
+
+# Check whether this is a reinstall and popup a message box to explain
+# that it is better to close other apps before continuing
+Function PrintCloseOtherApps
+    IfFileExists $INSTDIR\bin\gpg.exe print_warning
+    IfFileExists $INSTDIR\bin\gpa.exe print_warning
+    Return
+   print_warning:
+    MessageBox MB_OK|MB_ICONEXCLAMATION "$(T_CloseOtherApps)"
+
+FunctionEnd
+
+# Called right before the final page to show more warnings.
+#Function ShowFinalWarnings
+#   leave:
+#FunctionEnd
+
+#-----------------------------------------------
+# Strings pertaining to the install options page
+#-----------------------------------------------
+
+# Installation options title
+LangString T_InstallOptions ${LANG_ENGLISH} "Install Options"
+LangString T_InstallOptions ${LANG_GERMAN}  "Installationsoptionen"
+
+# Installation options subtitle 1
+LangString T_InstallOptLinks ${LANG_ENGLISH} "Start links"
+LangString T_InstallOptLinks ${LANG_GERMAN}  "Startlinks"
+
+LangString T_InstOptLabelA  ${LANG_ENGLISH} \
+     "Please select where GnuPG shall install links:"
+LangString T_InstOptLabelA  ${LANG_GERMAN} \
+     "Bitte wählen Sie, welche Verknüpfungen angelegt werden sollen:"
+
+LangString T_InstOptLabelB  ${LANG_ENGLISH} \
+     "(Only programs will be linked into the quick launch bar.)"
+LangString T_InstOptLabelB  ${LANG_GERMAN} \
+     "(In die Schnellstartleiste werden nur Verknüpfungen für \
+      Programme angelegt.) "
+
+LangString T_InstOptFieldA  ${LANG_ENGLISH} \
+     "Start Menu"
+LangString T_InstOptFieldA  ${LANG_GERMAN} \
+     "Startmenü"
+
+LangString T_InstOptFieldB  ${LANG_ENGLISH} \
+     "Desktop"
+LangString T_InstOptFieldB  ${LANG_GERMAN} \
+     "Arbeitsfläche"
+
+LangString T_InstOptFieldC  ${LANG_ENGLISH} \
+     "Quick Launch Bar"
+LangString T_InstOptFieldC  ${LANG_GERMAN} \
+     "Schnellstartleiste"
+
+#------------------------------------------------
+# String pertaining to the existing version check
+#------------------------------------------------
+LangString T_FoundExistingVersion ${LANG_ENGLISH} \
+     "Version $R1 has already been installed.  $\r$\n\
+      Do you want to overwrite it with version ${VERSION}?"
+LangString T_FoundExistingVersion ${LANG_GERMAN} \
+     "Version $R1 ist hier bereits installiert. $\r$\n\
+      Möchten Sie diese mit Version ${VERSION} überschreiben? $\r$\n\
+       $\r$\n\
+      (Sie können in jedem Fall mit JA antworten, falls es sich um \
+       eine neuere oder dieselbe Version handelt.)"
+LangString T_FoundExistingVersionB ${LANG_ENGLISH} \
+     "A version of GnuPG has already been installed on the system. \
+      There will be no problem installing and thus overwriting this \
+      Version. $\r$\n\
+       $\r$\n\
+      Do you want to continue installing GnuPG?"
+LangString T_FoundExistingVersionB ${LANG_GERMAN} \
+     "Eine Version von GnuPG ist hier bereits installiert. \
+      Es ist problemlos möglich, die Installation fortzuführen.  $\r$\n\
+        $\r$\n\
+      Möchten die die Installation von GnuPG fortführen?"
+
+
+
+# From Function PrintNonAdminWarning
+LangString T_AdminNeeded ${LANG_ENGLISH} \
+   "Warning: Administrator permissions required for a successful installation"
+LangString T_AdminNeeded ${LANG_GERMAN} \
+   "Achtung: Für eine erfolgreiche Installation werden \
+    Administratorrechte benötigt."
+
+# From Function PrintCloseOtherApps
+LangString T_CloseOtherApps ${LANG_ENGLISH} \
+   "Please make sure that other applications are not running. \
+    GnuPG will try to install anyway but a reboot may be required."
+LangString T_CloseOtherApps ${LANG_GERMAN} \
+   "Bitte stellen Sie sicher, daß alle anderen Anwendugen geschlossen \
+    sind.  GnuPG wird auf jeden Fall versuchen, eine Installation \
+    durchzuführen; es ist dann aber u.U. notwendig, das System neu zu starten."
+
+
+# TrimNewlines  - taken from the NSIS reference
+# input, top of stack  (e.g. whatever$\r$\n)
+# output, top of stack (replaces, with e.g. whatever)
+# modifies no other variables.
+Function TrimNewlines
+   Exch $R0
+   Push $R1
+   Push $R2
+   StrCpy $R1 0
+
+ loop:
+   IntOp $R1 $R1 - 1
+   StrCpy $R2 $R0 1 $R1
+   StrCmp $R2 "$\r" loop
+   StrCmp $R2 "$\n" loop
+   IntOp $R1 $R1 + 1
+   IntCmp $R1 0 no_trim_needed
+   StrCpy $R0 $R0 $R1
+
+ no_trim_needed:
+   Pop $R2
+   Pop $R1
+   Exch $R0
+FunctionEnd
+
+#
+# Define the installer sections.
+#
+
+Section "-gnupginst"
+  SetOutPath "$INSTDIR"
+
+  File "${BUILD_DIR}/README.txt"
+
+  # Write a version file.
+  FileOpen $0 "$INSTDIR\VERSION" w
+  FileWrite $0 "${PACKAGE}$\r$\n"
+  FileWrite $0 "${VERSION}$\r$\n"
+  FileClose $0
+
+  WriteRegStr HKLM "Software\GNU\GnuPG" "Install Directory" $INSTDIR
+
+  # If we are reinstalling, try to kill a possible running gpa using
+  # an already installed gpa.
+  ifFileExists "$INSTDIR\bin\launch-gpa.exe"  0 no_uiserver
+    ExecWait '"$INSTDIR\bin\launch-gpa" --stop-server'
+
+  no_uiserver:
+
+  # If we are reinstalling, try to kill a possible running agent using
+  # an already installed gpgconf.
+  ifFileExists "$INSTDIR\bin\gpgconf.exe"  0 no_gpgconf
+    ExecWait '"$INSTDIR\bin\gpgconf" --kill dirmngr'
+    ExecWait '"$INSTDIR\bin\gpgconf" --kill gpg-agent'
+
+  no_gpgconf:
+SectionEnd
+
+LangString DESC_Menu_gnupg_readme ${LANG_ENGLISH} \
+   "General information on GnuPG"
+LangString DESC_Menu_gnupg_readme ${LANG_GERMAN} \
+   "Allgemeine Informationen zu GnuPG"
+
+
+Section "GnuPG" SEC_gnupg
+  SectionIn RO
+
+  SetOutPath "$INSTDIR\bin"
+  File /oname=gpg.exe "bin/gpg2.exe"
+  File /oname=gpgv.exe "bin/gpgv2.exe"
+  File "bin/gpgsm.exe"
+  File "bin/gpgconf.exe"
+  File "bin/gpg-connect-agent.exe"
+  File "bin/gpgtar.exe"
+
+  ClearErrors
+  SetOverwrite try
+  File "bin/gpg-agent.exe"
+  SetOverwrite lastused
+  ifErrors 0 +3
+      File /oname=gpg-agent.exe.tmp "bin/gpg-agent.exe"
+      Rename /REBOOTOK gpg-agent.exe.tmp gpg-agent.exe
+
+  ClearErrors
+  SetOverwrite try
+  File "libexec/scdaemon.exe"
+  SetOverwrite lastused
+  ifErrors 0 +3
+      File /oname=scdaemon.exe.tmp "libexec/scdaemon.exe"
+      Rename /REBOOTOK scdaemon.exe.tmp scdaemon.exe
+
+  ClearErrors
+  SetOverwrite try
+  File "bin/dirmngr.exe"
+  SetOverwrite lastused
+  ifErrors 0 +3
+      File /oname=dirmngr.exe.tmp "bin/dirmngr.exe"
+      Rename /REBOOTOK dirmngr.exe.tmp dirmngr.exe
+
+  SetOutPath "$INSTDIR\share\gnupg"
+  File "share/gnupg/gpg-conf.skel"
+SectionEnd
+
+
+LangString DESC_SEC_gnupg ${LANG_ENGLISH} \
+   "The GnuPG Core is the actual encrypt core and a set of command \
+    line utilities."
+LangString DESC_SEC_gnupg ${LANG_GERMAN} \
+   "Der GnuPG Core ist, wie der Name schon sagt, der Kernbestandteil \
+    dieser Software.  Der GnuPG Core stellt die eigentliche \
+    Verschlüsselung sowie die Verwaltung der Schlüssel bereit."
+
+LangString DESC_Menu_gnupg_manual ${LANG_ENGLISH} \
+   "Show the manual for the GnuPG Core"
+LangString DESC_Menu_gnupg_manual ${LANG_GERMAN} \
+   "Das Handbuch zum GnuPG Kern anzeigen"
+
+Section "-libgpg-error" SEC_libgpg_error
+  SetOutPath "$INSTDIR\bin"
+  File bin/libgpg-error-0.dll
+SectionEnd
+
+Section "-libiconv" SEC_libiconv
+  SetOutPath "$INSTDIR\bin"
+  File bin/libiconv-2.dll
+SectionEnd
+
+Section "-zlib" SEC_zlib
+  SetOutPath "$INSTDIR\bin"
+  File bin/zlib1.dll
+SectionEnd
+
+Section "-npth" SEC_npth
+  SetOutPath "$INSTDIR\bin"
+  File bin/libnpth-0.dll
+SectionEnd
+
+Section "-gcrypt" SEC_gcrypt
+  SetOutPath "$INSTDIR\bin"
+  File bin/libgcrypt-20.dll
+SectionEnd
+
+Section "-assuan" SEC_assuan
+  SetOutPath "$INSTDIR\bin"
+  File bin/libassuan-0.dll
+SectionEnd
+
+Section "-ksba" SEC_ksba
+  SetOutPath "$INSTDIR\bin"
+  File bin/libksba-8.dll
+SectionEnd
+
+Section "-gpgme" SEC_gpgme
+  SetOutPath "$INSTDIR\bin"
+  File bin/libgpgme-11.dll
+  File bin/libgpgme-glib-11.dll
+  File libexec/gpgme-w32spawn.exe
+SectionEnd
+
+Section "-gettext" SEC_gettext
+  SetOutPath "$INSTDIR\bin"
+  File bin/libintl-8.dll
+SectionEnd
+
+Section "-glib" SEC_glib
+  SetOutPath "$INSTDIR\bin"
+  File bin/libgio-2.0-0.dll
+  File bin/libglib-2.0-0.dll
+  File bin/libgmodule-2.0-0.dll
+  File bin/libgobject-2.0-0.dll
+  File bin/libgthread-2.0-0.dll
+  File bin/gspawn-win32-helper.exe
+  File bin/gspawn-win32-helper-console.exe
+
+  File bin/libffi-6.dll
+SectionEnd
+
+Section "-libpng" SEC_libpng
+  SetOutPath "$INSTDIR\bin"
+  File bin/libpng14-14.dll
+SectionEnd
+
+#Section "-jpeg" SEC_jpeg
+#  SetOutPath "$INSTDIR"
+#  File bin/jpeg62.dll
+#SectionEnd
+
+Section "-cairo" SEC_cairo
+  SetOutPath "$INSTDIR\bin"
+  File bin/libcairo-gobject-2.dll
+  File bin/libpangocairo-1.0-0.dll
+  File bin/libcairo-2.dll
+  File bin/libcairo-script-interpreter-2.dll
+SectionEnd
+
+Section "-pixman" SEC_pixman
+  SetOutPath "$INSTDIR\bin"
+  File bin/libpixman-1-0.dll
+SectionEnd
+
+Section "-pango" SEC_pango
+  SetOutPath "$INSTDIR\bin"
+  File bin/pango-querymodules.exe
+  File bin/libpango-1.0-0.dll
+  File bin/libpangowin32-1.0-0.dll
+
+  SetOutPath "$INSTDIR\lib\pango\1.6.0\modules"
+  File lib/pango/1.6.0/modules/pango-basic-win32.dll
+  File lib/pango/1.6.0/modules/pango-arabic-lang.dll
+  File lib/pango/1.6.0/modules/pango-indic-lang.dll
+
+  SetOutPath "$INSTDIR\etc\pango"
+  File ${W32_SRCDIR}/pango.modules
+SectionEnd
+
+Section "-atk" SEC_atk
+  SetOutPath "$INSTDIR\bin"
+  File bin/libatk-1.0-0.dll
+SectionEnd
+
+Section "-gtk+" SEC_gtk_
+  SetOutPath "$INSTDIR\bin"
+  File bin/libgdk_pixbuf-2.0-0.dll
+  File bin/libgdk-win32-2.0-0.dll
+  File bin/libgtk-win32-2.0-0.dll
+
+  SetOutPath "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0"
+  File /oname=loaders.cache ${W32_SRCDIR}/gdk-pixbuf-loaders.cache
+  SetOutPath "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders"
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ani.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-bmp.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-emf.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-gif.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-ico.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-jpeg.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-tiff.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-wmf.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-icns.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-pcx.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-pnm.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-qtif.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ras.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-tga.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-wbmp.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-xbm.dll
+  File lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-xpm.dll
+
+  SetOutPath "$INSTDIR\lib\gtk-2.0\2.10.0\engines"
+  File lib/gtk-2.0/2.10.0/engines/libwimp.dll
+  File lib/gtk-2.0/2.10.0/engines/libpixmap.dll
+
+  SetOutPath "$INSTDIR\lib\gtk-2.0\2.10.0\immodules"
+  File lib/gtk-2.0/2.10.0/immodules/im-thai.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-cyrillic-translit.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-multipress.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-ti-er.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-am-et.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-cedilla.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-inuktitut.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-viqr.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-ti-et.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-ipa.dll
+  File lib/gtk-2.0/2.10.0/immodules/im-ime.dll
+
+  SetOutPath "$INSTDIR\share\themes\Default\gtk-2.0-key"
+  File share/themes/Default/gtk-2.0-key/gtkrc
+
+  SetOutPath "$INSTDIR\share\themes\MS-Windows\gtk-2.0"
+  File share/themes/MS-Windows/gtk-2.0/gtkrc
+
+  SetOutPath "$INSTDIR\etc\gtk-2.0"
+  File etc/gtk-2.0/im-multipress.conf
+SectionEnd
+
+Section "-pinentry" SEC_pinentry
+  SetOutPath "$INSTDIR\bin"
+  File /oname=pinentry.exe "bin/pinentry-gtk-2.exe"
+SectionEnd
+
+Section "gpa" SEC_gpa
+  SectionIn RO
+  SetOutPath "$INSTDIR\bin"
+  File bin/gpa.exe
+  File bin/launch-gpa.exe
+SectionEnd
+
+LangString DESC_SEC_gpa ${LANG_ENGLISH} \
+   "The GnuPG Assistant is the graphical interface of GnuPG"
+LangString DESC_SEC_gpa ${LANG_GERMAN} \
+   "Der GnuPG Assistent ist die graphische Oberfläche von GnuPG."
+
+LangString DESC_Menu_gpa ${LANG_ENGLISH} \
+   "Run the GnuGP Assistant."
+LangString DESC_Menu_gpa ${LANG_GERMAN} \
+   "Den GnuPG Assistenten starten."
+
+Section "gpgex" SEC_gpgex
+  SetOutPath "$INSTDIR\bin"
+
+  ClearErrors
+  SetOverwrite try
+  File bin/gpgex.dll
+  SetOverwrite lastused
+  ifErrors 0 do_reg
+      File /oname=gpgex.dll.tmp bin/gpgex.dll
+      Rename /REBOOTOK gpgex.dll.tmp gpgex.dll
+
+ do_reg:
+  ClearErrors
+  RegDLL "$INSTDIR\bin\gpgex.dll"
+  ifErrors 0 +2
+     MessageBox MB_OK "$(T_GPGEX_RegFailed)"
+
+${If} ${RunningX64}
+  # Install the 64 bit version of the plugin.
+  # Note that we install this in addition to the 32 bit version so that
+  # the 32 bit version can be used by file dialogs of 32 bit programs.
+  ClearErrors
+  SetOverwrite try
+  File /oname=gpgex6.dll "${INST6_DIR}/bin/gpgex.dll"
+  SetOverwrite lastused
+  ifErrors 0 do_reg64
+      File /oname=gpgex6.dll.tmp "${INST6_DIR}/bin/gpgex.dll"
+      Rename /REBOOTOK gpgex6.dll.tmp gpgex6.dll
+
+ do_reg64:
+  # Register the DLL. We need to register both versions.  However
+  # RegDLL can't be used for 64 bit and InstallLib seems to be a
+  # registry hack.
+  ClearErrors
+  ExecWait '"$SYSDIR\regsvr32" /s "$INSTDIR\bin\gpgex6.dll"'
+  ifErrors 0 +2
+     MessageBox MB_OK "$(T_GPGEX_RegFailed) (64 bit)"
+
+  # Note: There is no need to install the help an mo files because
+  # they are identical to those installed by the 32 bit version.
+${EndIf}
+SectionEnd
+
+LangString T_GPGEX_RegFailed ${LANG_ENGLISH} \
+   "Warning: Registration of the Explorer plugin failed."
+
+LangString DESC_SEC_gpgex ${LANG_ENGLISH} \
+   "GnuPG Explorer Extension"
+
+
+Section "-gnupglast" SEC_gnupglast
+  SetOutPath "$INSTDIR"
+SectionEnd
+
+
+#
+# Define the uninstaller sections.
+#
+# (reverse order of the installer sections!)
+#
+
+Section "-un.gnupglast"
+  ifFileExists "$INSTDIR\bin\launch-gpa.exe"  0 no_uiserver
+    ExecWait '"$INSTDIR\bin\launch-gpa" --stop-server'
+  no_uiserver:
+  ifFileExists "$INSTDIR\bin\gpgconf.exe"  0 no_gpgconf
+    ExecWait '"$INSTDIR\bin\gpgconf" --kill gpg-agent'
+  no_gpgconf:
+SectionEnd
+
+Section "-un.gpgex"
+  UnRegDLL "$INSTDIR\bin\gpgex.dll"
+
+  Delete /REBOOTOK "$INSTDIR\bin\gpgex.dll"
+
+${If} ${RunningX64}
+  ExecWait '"$SYSDIR\regsvr32" /u /s "$INSTDIR\bin\gpgex6.dll"'
+  Delete /REBOOTOK "$INSTDIR\bin\gpgex6.dll"
+${EndIf}
+SectionEnd
+
+
+Section "-un.gpa"
+  Delete "$INSTDIR\bin\gpa.exe"
+  Delete "$INSTDIR\bin\launch-gpa.exe"
+
+  RMDir "$INSTDIR\share\gpa"
+SectionEnd
+
+Section "-un.pinentry"
+  Delete "$INSTDIR\bin\pinentry.exe"
+SectionEnd
+
+
+Section "-un.gtk+"
+  Delete "$INSTDIR\bin\libgdk_pixbuf-2.0-0.dll"
+  Delete "$INSTDIR\bin\libgdk-win32-2.0-0.dll"
+  Delete "$INSTDIR\bin\libgtk-win32-2.0-0.dll"
+
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache"
+
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-ani.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-gdip-bmp.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-gdip-emf.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-gdip-gif.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-gdip-ico.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-gdip-jpeg.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-gdip-tiff.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-gdip-wmf.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-icns.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-pcx.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-png.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-pnm.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-qtif.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-ras.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-tga.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-wbmp.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-xbm.dll"
+  Delete "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders\libpixbufloader-xpm.dll"
+  RMDir  "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0\loaders"
+  RMDir  "$INSTDIR\lib\gdk-pixbuf-2.0\2.10.0"
+  RMDir  "$INSTDIR\lib\gdk-pixbuf-2.0"
+
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\engines\libwimp.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\engines\libpixmap.dll"
+  RMDir  "$INSTDIR\lib\gtk-2.0\2.10.0\engines"
+
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-thai.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-cyrillic-translit.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-multipress.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-ti-er.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-am-et.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-cedilla.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-inuktitut.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-viqr.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-ti-et.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-ipa.dll"
+  Delete "$INSTDIR\lib\gtk-2.0\2.10.0\immodules\im-ime.dll"
+  RMDir  "$INSTDIR\lib\gtk-2.0\2.10.0\immodules"
+
+  RMDir  "$INSTDIR\lib\gtk-2.0\2.10.0"
+  RMDir  "$INSTDIR\lib\gtk-2.0"
+
+  Delete "$INSTDIR\share\themes\Default\gtk-2.0-key\gtkrc"
+  RMDir  "$INSTDIR\share\themes\Default\gtk-2.0-key"
+  RMDir  "$INSTDIR\share\themes\Default"
+
+  Delete "$INSTDIR\share\themes\MS-Windows\gtk-2.0\gtkrc"
+  RMDir  "$INSTDIR\share\themes\MS-Windows\gtk-2.0"
+  RMDir  "$INSTDIR\share\themes\MS-Windows"
+
+  RMDir  "$INSTDIR\share\themes"
+
+  Delete "$INSTDIR\etc\gtk-2.0\im-multipress.conf"
+  RMDir  "$INSTDIR\etc\gtk-2.0"
+SectionEnd
+
+Section "-un.atk"
+  Delete "$INSTDIR\bin\libatk-1.0-0.dll"
+SectionEnd
+
+Section "-un.pango"
+  Delete "$INSTDIR\bin\pango-querymodules.exe"
+  Delete "$INSTDIR\bin\libpango-1.0-0.dll"
+  Delete "$INSTDIR\bin\libpangowin32-1.0-0.dll"
+
+  Delete "$INSTDIR\lib\pango\1.6.0\modules\pango-basic-win32.dll"
+  Delete "$INSTDIR\lib\pango\1.6.0\modules\pango-arabic-lang.dll"
+  Delete "$INSTDIR\lib\pango\1.6.0\modules\pango-indic-lang.dll"
+  RMDir  "$INSTDIR\lib\pango\1.6.0\modules"
+  RMDir  "$INSTDIR\lib\pango\1.6.0"
+  RMDir  "$INSTDIR\lib\pango"
+
+  Delete "$INSTDIR\etc\pango\pango.modules"
+  RMDir  "$INSTDIR\etc\pango"
+SectionEnd
+
+Section "-un.pixman"
+  Delete "$INSTDIR\bin\libpixman-1-0.dll"
+SectionEnd
+
+Section "-un.cairo"
+  Delete "$INSTDIR\bin\libcairo-gobject-2.dll"
+  Delete "$INSTDIR\bin\libpangocairo-1.0-0.dll"
+  Delete "$INSTDIR\bin\libcairo-2.dll"
+  Delete "$INSTDIR\bin\libcairo-script-interpreter-2.dll"
+SectionEnd
+
+Section "-un.libpng"
+  Delete "$INSTDIR\bin\libpng14-14.dll"
+SectionEnd
+
+Section "-un.glib"
+  Delete "$INSTDIR\bin\libgio-2.0-0.dll"
+  Delete "$INSTDIR\bin\libglib-2.0-0.dll"
+  Delete "$INSTDIR\bin\libgmodule-2.0-0.dll"
+  Delete "$INSTDIR\bin\libgobject-2.0-0.dll"
+  Delete "$INSTDIR\bin\libgthread-2.0-0.dll"
+  Delete "$INSTDIR\bin\gspawn-win32-helper.exe"
+  Delete "$INSTDIR\bin\gspawn-win32-helper-console.exe"
+  Delete "$INSTDIR\bin\libffi-6.dll"
+SectionEnd
+
+Section "-un.gettext"
+  Delete "$INSTDIR\bin\libintl-8.dll"
+SectionEnd
+
+Section "-un.gpgme"
+  Delete "$INSTDIR\bin\libgpgme-11.dll"
+  Delete "$INSTDIR\bin\libgpgme-glib-11.dll"
+  Delete "$INSTDIR\bin\gpgme-w32spawn.exe"
+SectionEnd
+
+Section "-un.ksba"
+  Delete "$INSTDIR\bin\libksba-8.dll"
+SectionEnd
+
+Section "-un.assuan"
+  Delete "$INSTDIR\bin\libassuan-0.dll"
+SectionEnd
+
+Section "-un.gcrypt"
+  Delete "$INSTDIR\bin\libgcrypt-20.dll"
+SectionEnd
+
+Section "-un.npth"
+  Delete "$INSTDIR\bin\libnpth-0.dll"
+SectionEnd
+
+Section "-un.zlib"
+  Delete "$INSTDIR\bin\zlib1.dll"
+SectionEnd
+
+Section "-un.libiconv"
+  Delete "$INSTDIR\bin\libiconv-2.dll"
+SectionEnd
+
+Section "-un.libgpg-error"
+  Delete "$INSTDIR\bin\libgpg-error-0.dll"
+SectionEnd
+
+Section "-un.gnupg"
+  Delete "$INSTDIR\bin\gpg.exe"
+  Delete "$INSTDIR\bin\gpgv.exe"
+  Delete "$INSTDIR\bin\gpgsm.exe"
+  Delete "$INSTDIR\bin\gpg-agent.exe"
+  Delete "$INSTDIR\bin\scdaemon.exe"
+  Delete "$INSTDIR\bin\dirmngr.exe"
+  Delete "$INSTDIR\bin\gpgconf.exe"
+  Delete "$INSTDIR\bin\gpg-connect-agent.exe"
+  Delete "$INSTDIR\bin\gpgtar.exe"
+
+  Delete "$INSTDIR\share\gnupg\gpg-conf.skel"
+  RMDir  "$INSTDIR\share\gnupg"
+SectionEnd
+
+Section "-un.gnupginst"
+  # Delete standard stuff.
+  Delete "$INSTDIR\README.txt"
+
+  Delete "$INSTDIR\VERSION"
+
+  # Try to remove the top level directories.
+  RMDir "$INSTDIR\bin"
+  RMDir "$INSTDIR\lib"
+  RMDir "$INSTDIR\share"
+  RMDir "$INSTDIR\etc"
+  RMDir "$INSTDIR"
+
+  # Clean the registry.
+  DeleteRegValue HKLM "Software\GNU\GnuPG" "Install Directory"
+SectionEnd
+
+
+Function .onInit
+  ;;!define MUI_LANGDLL_ALWAYSSHOW
+  !insertmacro MUI_LANGDLL_DISPLAY
+
+  Call G4wRunOnce
+
+  SetOutPath $TEMP
+#!ifdef SOURCES
+#  File /oname=gpgspltmp.bmp "${TOP_SRCDIR}/doc/logo/gnupg-logo-400px.bmp"
+#  # We play the tune only for the soruce installer
+#  File /oname=gpgspltmp.wav "${TOP_SRCDIR}/src/gnupg-splash.wav"
+#  g4wihelp::playsound $TEMP\gpgspltmp.wav
+#  g4wihelp::showsplash 2500 $TEMP\gpgspltmp.bmp
+
+#  Delete $TEMP\gpgspltmp.bmp
+#  # Note that we delete gpgspltmp.wav in .onInst{Failed,Success}
+#!endif
+
+  # We can't use TOP_SRCDIR dir as the name of the file needs to be
+  # the same while building and running the installer.  Thus we
+  # generate the file from a template.
+  !insertmacro MUI_INSTALLOPTIONS_EXTRACT "${W32_SRCDIR}/inst-options.ini"
+
+  #Call CalcDepends
+FunctionEnd
+
+
+#Function .onInstFailed
+#  Delete $TEMP\gpgspltmp.wav
+#FunctionEnd
+
+#Function .onInstSuccess
+#  Delete $TEMP\gpgspltmp.wav
+#FunctionEnd
+
+#Function .onSelChange
+#  Call CalcDepends
+#FunctionEnd
+
+
+# This must be in a central place.  Urgs.
+
+!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+!insertmacro MUI_DESCRIPTION_TEXT ${SEC_gnupg} $(DESC_SEC_gnupg)
+!insertmacro MUI_DESCRIPTION_TEXT ${SEC_gpa}   $(DESC_SEC_gpa)
+!insertmacro MUI_DESCRIPTION_TEXT ${SEC_gpgex} $(DESC_SEC_gpgex)
+!insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+
+# This also must be in a central place.  Also Urgs.
+
+Section "-startmenu"
+
+!ifdef HAVE_STARTMENU
+  # Make sure that the context of the automatic variables has been set to
+  # the "all users" shell folder.  This guarantees that the menu gets written
+  # for all users.  We have already checked that we are running as Admin; or
+  # we printed a warning that installation will not succeed.
+  SetShellVarContext all
+
+  # Check if the start menu entries where requested.
+  !insertmacro MUI_INSTALLOPTIONS_READ $R0 "${W32_SRCDIR}/inst-options.ini" \
+       "Field 2" "State"
+  IntCmp $R0 0 no_start_menu
+
+!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+    CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
+
+    SectionGetFlags ${SEC_gpa} $R0
+    IntOp $R0 $R0 & ${SF_SELECTED}
+    IntCmp $R0 ${SF_SELECTED} 0 no_gpa_menu
+    CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\GPA.lnk" \
+       "$INSTDIR\bin\launch-gpa.exe" \
+        "" "" "" SW_SHOWNORMAL "" $(DESC_Menu_gpa)
+  no_gpa_menu:
+
+
+    CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\GnuPG Manual.lnk" \
+                   "$INSTDIR\share\gnupg\gnupg.html" \
+                   "" "" "" SW_SHOWNORMAL "" $(DESC_Menu_gnupg_manual)
+
+    CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\GnuPG README.lnk" \
+                   "$INSTDIR\README.txt" \
+                   "" "" "" SW_SHOWNORMAL "" $(DESC_Menu_gnupg_readme)
+
+!insertmacro MUI_STARTMENU_WRITE_END
+
+
+
+no_start_menu:
+
+
+  # Check if the desktop entries where requested.
+  !insertmacro MUI_INSTALLOPTIONS_READ $R0 "${W32_SRCDIR}/inst-options.ini" \
+       "Field 3" "State"
+  IntCmp $R0 0 no_desktop
+
+    SectionGetFlags ${SEC_gpa} $R0
+    IntOp $R0 $R0 & ${SF_SELECTED}
+    IntCmp $R0 ${SF_SELECTED} 0 no_gpa_desktop
+    CreateShortCut "$DESKTOP\GPA.lnk" \
+       "$INSTDIR\bin\launch-gpa.exe" \
+        "" "" "" SW_SHOWNORMAL "" $(DESC_Menu_gpa)
+  no_gpa_desktop:
+
+
+    CreateShortCut "$DESKTOP\GPA Manual.lnk" \
+                   "$INSTDIR\share\gpa\gpa.html" \
+                   "" "" "" SW_SHOWNORMAL "" $(DESC_Menu_gpa_manual)
+
+no_desktop:
+
+
+  # Check if the quick launch bar entries where requested.
+  !insertmacro MUI_INSTALLOPTIONS_READ $R0 "${W32_SRCDIR}/inst-options.ini" \
+       "Field 4" "State"
+  IntCmp $R0 0 no_quick_launch
+  StrCmp $QUICKLAUNCH $TEMP no_quick_launch
+
+    SectionGetFlags ${SEC_gpa} $R0
+    IntOp $R0 $R0 & ${SF_SELECTED}
+    IntCmp $R0 ${SF_SELECTED} 0 no_gpa_quicklaunch
+    CreateShortCut "$QUICKLAUNCH\GPA.lnk" \
+       "$INSTDIR\bin\launch-gpa.exe" \
+        "" "" "" SW_SHOWNORMAL "" $(DESC_Menu_gpa)
+no_gpa_quicklaunch:
+
+
+no_quick_launch:
+
+
+!endif
+SectionEnd
+
+
+
+#
+# Now for the generic parts to end the installation.
+#
+Var MYTMP
+
+# Last section is a hidden one.
+Section
+  WriteUninstaller "$INSTDIR\gnupg-uninstall.exe"
+
+  # Windows Add/Remove Programs support
+  StrCpy $MYTMP "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
+  WriteRegExpandStr HKLM $MYTMP "UninstallString" '"$INSTDIR\gnupg-uninstall.exe"'
+  WriteRegExpandStr HKLM $MYTMP "InstallLocation" "$INSTDIR"
+  WriteRegStr       HKLM $MYTMP "DisplayName"     "${PRETTY_PACKAGE}"
+  WriteRegStr       HKLM $MYTMP "DisplayIcon"     "$INSTDIR\bin\gpa.exe,0"
+  WriteRegStr       HKLM $MYTMP "DisplayVersion"  "${VERSION}"
+  WriteRegStr       HKLM $MYTMP "Publisher"       "The GnuPG Project"
+  WriteRegStr       HKLM $MYTMP "URLInfoAbout"    "https://gnupg.org"
+  WriteRegDWORD     HKLM $MYTMP "NoModify"        "1"
+  WriteRegDWORD     HKLM $MYTMP "NoRepair"        "1"
+SectionEnd
+
+
+Section Uninstall
+
+!ifdef HAVE_STARTMENU
+  # Make sure that the context of the automatic variables has been set to
+  # the "all users" shell folder.  This guarantees that the menu gets written
+  # for all users.  We have already checked that we are running as Admin; or
+  # we printed a warning that installation will not succeed.
+  SetShellVarContext all
+
+  #---------------------------------------------------
+  # Delete the menu entries and any empty parent menus
+  #---------------------------------------------------
+  !insertmacro MUI_STARTMENU_GETFOLDER Application $MYTMP
+  Delete "$SMPROGRAMS\$MYTMP\GPA.lnk"
+  Delete "$SMPROGRAMS\$MYTMP\GnuPG Manual.lnk"
+  Delete "$SMPROGRAMS\$MYTMP\GnuPG README.lnk"
+  Delete "$SMPROGRAMS\$MYTMP\*.lnk"
+  StrCpy $MYTMP "$SMPROGRAMS\$MYTMP"
+  startMenuDeleteLoop:
+    ClearErrors
+    RMDir $MYTMP
+    GetFullPathName $MYTMP "$MYTMP\.."
+    IfErrors startMenuDeleteLoopDone
+    StrCmp $MYTMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop
+  startMenuDeleteLoopDone:
+
+  DeleteRegValue HKLM "Software\GNU\GnuPG" "Start Menu Folder"
+
+  # Delete Desktop links.
+  Delete "$DESKTOP\GPA.lnk"
+  Delete "$DESKTOP\GnuPG Manual.lnk"
+  Delete "$DESKTOP\GnuPG README.lnk"
+
+  # Delete Quick Launch Bar links.
+  StrCmp $QUICKLAUNCH $TEMP no_quick_launch_uninstall
+  Delete "$QUICKLAUNCH\GPA.lnk"
+no_quick_launch_uninstall:
+
+!endif
+
+
+  Delete "$INSTDIR\gnupg-uninstall.exe"
+  RMDir "$INSTDIR"
+
+  # Clean the registry.
+  DeleteRegValue HKLM "Software\GNU\GnuPG" "Install Directory"
+  DeleteRegKey /ifempty HKLM "Software\GNU\GnuPG"
+  # Remove Windows Add/Remove Programs support.
+  DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
+SectionEnd
diff --git a/build-aux/speedo/w32/pango.modules b/build-aux/speedo/w32/pango.modules
new file mode 100755 (executable)
index 0000000..75b2527
--- /dev/null
@@ -0,0 +1,3 @@
+# Pango Modules file
+#
+"../lib/pango/1.6.0/modules/pango-basic-win32.dll" BasicScriptEngineWin32 PangoEngineShape PangoRenderWin32 common:
diff --git a/build-aux/speedo/w32/pkg-copyright.txt b/build-aux/speedo/w32/pkg-copyright.txt
new file mode 100644 (file)
index 0000000..69bb08b
--- /dev/null
@@ -0,0 +1,165 @@
+Here is a list with collected copyright notices. For details see the
+description of each individual package.  [Compiled by wk FIXME]
+
+GnuPG is
+
+  Copyright (C) 1997-1998, 2013-2014 Werner Koch
+  Copyright (C) 1998-2013 Free Software Foundation, Inc.
+  Copyright (C) 2003-2013 g10 Code GmbH
+  Copyright (C) 2002 Klarälvdalens Datakonsult AB
+  Copyright (C) 1995-1997, 2000-2007 Ulrich Drepper <drepper@gnu.ai.mit.edu>
+  Copyright (C) 1994 X Consortium
+  Copyright (C) 1998 by The Internet Society.
+  Copyright (C) 1998-2004 The OpenLDAP Foundation
+  Copyright (C) 1998-2004 Kurt D. Zeilenga.
+  Copyright (C) 1998-2004 Net Boolean Incorporated.
+  Copyright (C) 2001-2004 IBM Corporation.
+  Copyright (C) 1999-2003 Howard Y.H. Chu.
+  Copyright (C) 1999-2003 Symas Corporation.
+  Copyright (C) 1998-2003 Hallvard B. Furuseth.
+  Copyright (C) 1992-1996 Regents of the University of Michigan.
+
+  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 3 of the License, or
+  (at your option) any later version.
+
+  GnuPG is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+  02110-1301, USA
+
+
+GPA is
+
+  Copyright (C) 2000-2002 G-N-U GmbH (http://www.g-n-u.de)
+  Copyright (C) 2002-2003 Miguel Coca.
+  Copyright (C) 2005, 2006, 2008, 2012, 2014 g10 Code GmbH.
+  Copyright (C) 1998-2000 Free Software Foundation, Inc.
+  Copyright (C) 2000-2001 Werner Koch
+  Copyright (C) 2000-2002 Timo Schulz
+
+  GPA 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 3 of the License, or
+  (at your option) any later version.
+
+  GPA 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, see <http://www.gnu.org/licenses/>.
+
+
+GPGME is
+
+  Copyright (C) 2000 Werner Koch (dd9jn)
+  Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 g10 Code GmbH
+
+  GPGME is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of
+  the License, or (at your option) any later version.
+
+  GPGME 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+LIBGPG-ERROR is
+
+  Copyright (C) 2003, 2004 g10 Code GmbH
+
+  libgpg-error is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public License
+  as published by the Free Software Foundation; either version 2.1 of
+  the License, or (at your option) any later version.
+
+  libgpg-error 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+GLIB is
+
+  Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the
+  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+
+  Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+  file for a list of people on the GLib Team.  See the ChangeLog
+  files for a list of changes.  These files are distributed with
+  GLib at ftp://ftp.gtk.org/pub/gtk/.
+
+
+Pthreads-win32 is
+
+  Copyright(C) 1998 John E. Bossom
+  Copyright(C) 1999,2002 Pthreads-win32 contributors
+
+  Most of this is work available under the GNU Lesser General Public
+  License as published by the Free Software Foundation version 2.1 of
+  the License.  The detailed terms are given in the file COPYING in
+  the source distribution; that very file may not be modified and thus
+  it is not possible to include it here.
+
+
+NSIS is
+
+  Copyright (C) 1999-2005 Nullsoft, Inc.
+
+  This license applies to everything in the NSIS package, except where
+  otherwise noted.
+
+  This software is provided 'as-is', without any express or implied
+  warranty. In no event will the authors be held liable for any
+  damages arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any
+  purpose, including commercial applications, and to alter it and
+  redistribute it freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must
+     not claim that you wrote the original software. If you use this
+     software in a product, an acknowledgment in the product
+     documentation would be appreciated but is not required.
+
+  2. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  3. This notice may not be removed or altered from any source
+     distribution.
+
+  The user interface used with the installer is
+
+  Copyright (C) 2002-2005 Joost Verburg
+
+  [It is distributed along with NSIS and the same conditions as stated
+   above apply]
diff --git a/build-aux/speedo/zlib.pc b/build-aux/speedo/zlib.pc
new file mode 100644 (file)
index 0000000..b758050
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: zlib
+Description:  zlib compression library
+Version: 1.2.5
+Libs: -L${libdir} -lz
+Cflags: -I${includedir}
similarity index 99%
rename from scripts/texinfo.tex
rename to build-aux/texinfo.tex
index 5063065..a181898 100644 (file)
@@ -20,7 +20,7 @@
 % General Public License for more details.
 %
 % You should have received a copy of the GNU General Public License
-% along with this texinfo.tex file; see the file COPYING.  If not, 
+% along with this texinfo.tex file; see the file COPYING.  If not,
 % see <http://www.gnu.org/licenses/>.
 %
 % As a special exception, when this file is read by TeX when processing
                % We don't want .vr (or whatever) entries like this:
                % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
                % "\acronym" won't work when it's read back in;
-               % it needs to be 
+               % it needs to be
                % {\code {{\tt \backslashcurfont }acronym}
     \shipout\vbox{%
       % Do this early so pdf references go to the beginning of the page.
 \def\?{?\spacefactor=\endofsentencespacefactor\space}
 
 % @frenchspacing on|off  says whether to put extra space after punctuation.
-% 
+%
 \def\onword{on}
 \def\offword{off}
 %
@@ -1215,7 +1215,7 @@ where each line of input produces a line of output.}
 % that's what we do).
 
 % double active backslashes.
-% 
+%
 {\catcode`\@=0 \catcode`\\=\active
  @gdef@activebackslashdouble{%
    @catcode`@\=@active
@@ -1227,11 +1227,11 @@ where each line of input produces a line of output.}
 % us) handles it with this amazing macro to replace tokens, with minor
 % changes for Texinfo.  It is included here under the GPL by permission
 % from the author, Heiko Oberdiek.
-% 
+%
 % #1 is the tokens to replace.
 % #2 is the replacement.
 % #3 is the control sequence with the string.
-% 
+%
 \def\HyPsdSubst#1#2#3{%
   \def\HyPsdReplace##1#1##2\END{%
     ##1%
@@ -1459,7 +1459,7 @@ output) for that.)}
       % tried to figure out what each command should do in the context
       % of @url.  for now, just make @/ a no-op, that's the only one
       % people have actually reported a problem with.
-      % 
+      %
       \normalturnoffactive
       \def\@{@}%
       \let\/=\empty
@@ -1851,7 +1851,7 @@ end
 
 % Definitions for a main text size of 11pt.  This is the default in
 % Texinfo.
-% 
+%
 \def\definetextfontsizexi{%
 % Text fonts (11.2pt, magstep1).
 \def\textnominalsize{11pt}
@@ -1976,7 +1976,7 @@ end
 % section, chapter, etc., sizes following suit.  This is for the GNU
 % Press printing of the Emacs 22 manual.  Maybe other manuals in the
 % future.  Used with @smallbook, which sets the leading to 12pt.
-% 
+%
 \def\definetextfontsizex{%
 % Text fonts (10pt).
 \def\textnominalsize{10pt}
@@ -2062,7 +2062,7 @@ end
 \setfont\secsf\sfbshape{12}{1000}{OT1}
 \let\secbf\secrm
 \setfont\secsc\scbshape{10}{\magstep1}{OT1}
-\font\seci=cmmi12 
+\font\seci=cmmi12
 \font\secsy=cmsy10 scaled \magstep1
 
 % Subsection fonts (10pt).
@@ -2103,7 +2103,7 @@ end
 % We provide the user-level command
 %   @fonttextsize 10
 % (or 11) to redefine the text font size.  pt is assumed.
-% 
+%
 \def\xword{10}
 \def\xiword{11}
 %
@@ -2113,7 +2113,7 @@ end
   %
   % Set \globaldefs so that documents can use this inside @tex, since
   % makeinfo 4.8 does not support it, but we need it nonetheless.
-  % 
+  %
  \begingroup \globaldefs=1
   \ifx\textsizearg\xword \definetextfontsizex
   \else \ifx\textsizearg\xiword \definetextfontsizexi
@@ -2399,7 +2399,7 @@ end
 % each of the four underscores in __typeof__.  This is undesirable in
 % some manuals, especially if they don't have long identifiers in
 % general.  @allowcodebreaks provides a way to control this.
-% 
+%
 \newif\ifallowcodebreaks  \allowcodebreakstrue
 
 \def\keywordtrue{true}
@@ -2530,7 +2530,7 @@ end
 % @acronym for "FBI", "NATO", and the like.
 % We print this one point size smaller, since it's intended for
 % all-uppercase.
-% 
+%
 \def\acronym#1{\doacronym #1,,\finish}
 \def\doacronym#1,#2,#3\finish{%
   {\selectfonts\lsize #1}%
@@ -2542,7 +2542,7 @@ end
 
 % @abbr for "Comput. J." and the like.
 % No font change, but don't do end-of-sentence spacing.
-% 
+%
 \def\abbr#1{\doabbr #1,,\finish}
 \def\doabbr#1,#2,#3\finish{%
   {\plainfrenchspacing #1}%
@@ -2561,43 +2561,43 @@ end
 % Theiling, which support regular, slanted, bold and bold slanted (and
 % "outlined" (blackboard board, sort of) versions, which we don't need).
 % It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
-% 
+%
 % Although only regular is the truly official Euro symbol, we ignore
 % that.  The Euro is designed to be slightly taller than the regular
 % font height.
-% 
+%
 % feymr - regular
 % feymo - slanted
 % feybr - bold
 % feybo - bold slanted
-% 
+%
 % There is no good (free) typewriter version, to my knowledge.
 % A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
 % Hmm.
-% 
+%
 % Also doesn't work in math.  Do we need to do math with euro symbols?
 % Hope not.
-% 
-% 
+%
+%
 \def\euro{{\eurofont e}}
 \def\eurofont{%
   % We set the font at each command, rather than predefining it in
   % \textfonts and the other font-switching commands, so that
   % installations which never need the symbol don't have to have the
   % font installed.
-  % 
+  %
   % There is only one designed size (nominal 10pt), so we always scale
   % that to the current nominal size.
-  % 
+  %
   % By the way, simply using "at 1em" works for cmr10 and the like, but
   % does not work for cmbx10 and other extended/shrunken fonts.
-  % 
+  %
   \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
   %
-  \ifx\curfontstyle\bfstylename 
+  \ifx\curfontstyle\bfstylename
     % bold:
     \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
-  \else 
+  \else
     % regular:
     \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
   \fi
@@ -2621,7 +2621,7 @@ end
 % Laurent Siebenmann reports \Orb undefined with:
 %  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
 % so we'll define it if necessary.
-% 
+%
 \ifx\Orb\undefined
 \def\Orb{\mathhexbox20D}
 \fi
@@ -2937,7 +2937,7 @@ end
     % cause the example and the item to crash together.  So we use this
     % bizarre value of 10001 as a signal to \aboveenvbreak to insert
     % \parskip glue after all.  Section titles are handled this way also.
-    % 
+    %
     \penalty 10001
     \endgroup
     \itemxneedsnegativevskipfalse
@@ -3733,7 +3733,7 @@ end
   % processing continues to some further point.  On the other hand, it
   % seems \endinput does not hurt in the printed index arg, since that
   % is still getting written without apparent harm.
-  % 
+  %
   % Sample source (mac-idx3.tex, reported by Graham Percival to
   % help-texinfo, 22may06):
   % @macro funindex {WORD}
@@ -3741,12 +3741,12 @@ end
   % @end macro
   % ...
   % @funindex commtest
-  % 
+  %
   % The above is not enough to reproduce the bug, but it gives the flavor.
-  % 
+  %
   % Sample whatsit resulting:
   % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
-  % 
+  %
   % So:
   \let\endinput = \empty
   %
@@ -3982,11 +3982,11 @@ end
   % makeinfo does not expand macros in the argument to @deffn, which ends up
   % writing an index entry, and texindex isn't prepared for an index sort entry
   % that starts with \.
-  % 
+  %
   % Since macro invocations are followed by braces, we can just redefine them
   % to take a single TeX argument.  The case of a macro invocation that
   % goes to end-of-line is not handled.
-  % 
+  %
   \macrolist
 }
 
@@ -4114,7 +4114,7 @@ end
     % to re-insert the same penalty (values >10000 are used for various
     % signals); since we just inserted a non-discardable item, any
     % following glue (such as a \parskip) would be a breakpoint.  For example:
-    % 
+    %
     %   @deffn deffn-whatever
     %   @vindex index-whatever
     %   Description.
@@ -5096,11 +5096,11 @@ end
   % glue accumulate.  (Not a breakpoint because it's preceded by a
   % discardable item.)
   \vskip-\parskip
-  % 
+  %
   % This is purely so the last item on the list is a known \penalty >
   % 10000.  This is so \startdefun can avoid allowing breakpoints after
   % section headings.  Otherwise, it would insert a valid breakpoint between:
-  % 
+  %
   %   @section sec-whatever
   %   @deffn def-whatever
   \penalty 10001
@@ -5158,7 +5158,7 @@ end
 % These characters do not print properly in the Computer Modern roman
 % fonts, so we must take special care.  This is more or less redundant
 % with the Texinfo input format setup at the end of this file.
-% 
+%
 \def\activecatcodes{%
   \catcode`\"=\active
   \catcode`\$=\active
@@ -5759,8 +5759,8 @@ end
 % from cmtt (char 0x0d).  The undirected quote is ugly, so don't make it
 % the default, but it works for pasting with more pdf viewers (at least
 % evince), the lilypond developers report.  xpdf does work with the
-% regular 0x27.  
-% 
+% regular 0x27.
+%
 \def\codequoteright{%
   \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
     '%
@@ -5772,7 +5772,7 @@ end
 % and a similar option for the left quote char vs. a grave accent.
 % Modern fonts display ASCII 0x60 as a grave accent, so some people like
 % the code environments to do likewise.
-% 
+%
 \def\codequoteleft{%
   \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
     `%
@@ -6301,7 +6301,7 @@ end
 % This does \let #1 = #2, with \csnames; that is,
 %   \let \csname#1\endcsname = \csname#2\endcsname
 % (except of course we have to play expansion games).
-% 
+%
 \def\cslet#1#2{%
   \expandafter\let
   \csname#1\expandafter\endcsname
@@ -7483,7 +7483,7 @@ should work if nowhere else does.}
      \setnonasciicharscatcode\active
      \lattwochardefs
   %
-  \else \ifx \declaredencoding \latone 
+  \else \ifx \declaredencoding \latone
      \setnonasciicharscatcode\active
      \latonechardefs
   %
@@ -7495,7 +7495,7 @@ should work if nowhere else does.}
      \setnonasciicharscatcode\active
      \utfeightchardefs
   %
-  \else 
+  \else
     \message{Unknown document encoding #1, ignoring.}%
   %
   \fi % utfeight
@@ -7507,7 +7507,7 @@ should work if nowhere else does.}
 
 % A message to be logged when using a character that isn't available
 % the default font encoding (OT1).
-% 
+%
 \def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
 
 % Take account of \c (plain) vs. \, (Texinfo) difference.
@@ -7520,21 +7520,21 @@ should work if nowhere else does.}
 %
 % Latin1 (ISO-8859-1) character definitions.
 \def\latonechardefs{%
-  \gdef^^a0{~} 
+  \gdef^^a0{~}
   \gdef^^a1{\exclamdown}
-  \gdef^^a2{\missingcharmsg{CENT SIGN}} 
+  \gdef^^a2{\missingcharmsg{CENT SIGN}}
   \gdef^^a3{{\pounds}}
   \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
   \gdef^^a5{\missingcharmsg{YEN SIGN}}
-  \gdef^^a6{\missingcharmsg{BROKEN BAR}} 
+  \gdef^^a6{\missingcharmsg{BROKEN BAR}}
   \gdef^^a7{\S}
-  \gdef^^a8{\"{}} 
-  \gdef^^a9{\copyright} 
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\copyright}
   \gdef^^aa{\ordf}
-  \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}} 
+  \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
   \gdef^^ac{$\lnot$}
-  \gdef^^ad{\-} 
-  \gdef^^ae{\registeredsymbol} 
+  \gdef^^ad{\-}
+  \gdef^^ae{\registeredsymbol}
   \gdef^^af{\={}}
   %
   \gdef^^b0{\textdegree}
@@ -7561,7 +7561,7 @@ should work if nowhere else does.}
   \gdef^^c2{\^A}
   \gdef^^c3{\~A}
   \gdef^^c4{\"A}
-  \gdef^^c5{\ringaccent A} 
+  \gdef^^c5{\ringaccent A}
   \gdef^^c6{\AE}
   \gdef^^c7{\cedilla C}
   \gdef^^c8{\`E}
@@ -7702,7 +7702,7 @@ should work if nowhere else does.}
   \gdef^^d6{\"O}
   \gdef^^d7{$\times$}
   \gdef^^d8{\v R}
-  \gdef^^d9{\ringaccent U} 
+  \gdef^^d9{\ringaccent U}
   \gdef^^da{\'U}
   \gdef^^db{\H U}
   \gdef^^dc{\"U}
@@ -7746,11 +7746,11 @@ should work if nowhere else does.}
 }
 
 % UTF-8 character definitions.
-% 
+%
 % This code to support UTF-8 is based on LaTeX's utf8.def, with some
 % changes for Texinfo conventions.  It is included here under the GPL by
 % permission from Frank Mittelbach and the LaTeX team.
-% 
+%
 \newcount\countUTFx
 \newcount\countUTFy
 \newcount\countUTFz
@@ -8576,7 +8576,7 @@ should work if nowhere else does.}
 
 % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
 % the literal character `\'.
-% 
+%
 @def@normalturnoffactive{%
   @let\=@normalbackslash
   @let"=@normaldoublequote
index 0d0d1cc..7fed0a7 100644 (file)
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-11-30  Werner Koch  <wk@gnupg.org>
+
+        Rewrite dns-cert.c to not use the gpg-only iobuf stuff.
+        * dns-cert.c: Remove iobuf.h.
+        (get_dns_cert): Rename to _get_dns_cert.  Remove MAX_SIZE arg.
+       Change iobuf arg to a estream-t.  Rewrite function to make use of
+       estream instead of iobuf.  Require all parameters.  Return an
+       gpg_error_t error instead of the type.  Add arg ERRSOURCE.
+        * dns-cert.h (get_dns_cert): New macro to pass the error source to
+       _gpg_dns_cert.
+        * t-dns-cert.c (main): Adjust for changes in get_dns_cert.
+
+        * estream.c (es_fopenmem_init): New.
+       * estream.h (es_fopenmem_init): New.
+
+2011-11-29  Werner Koch  <wk@g10code.com>
+
+       * estream.c (func_mem_create): Don't set FUNC_REALLOC if GROW is
+       not set.  Require FUNC_REALLOC if DATA is NULL and FUNC_FREE is
+       given.
+
+       * dns-cert.c: Use new CERTTYPE_ constants for better readability.
+
+2011-11-28  Werner Koch  <wk@g10code.com>
+
+       * t-dns-cert.c (main): Increase MAX_SIZE to 64k.
+
+       * dns-cert.c (get_dns_cert): Factor test code out to ...
+       * t-dns-cert.c: new file.
+
+2011-10-24  Werner Koch  <wk@g10code.com>
+
+       * dotlock.h, dotlock.c: Add alternative to allow distribution of
+       these files under a modified BSD license
+
+2011-09-30  Werner Koch  <wk@g10code.com>
+
+       Change the license of all JNLIB parts from LPGLv3+ to to LGPLv3+
+       or GPLv2+.
+
+       * dotlock.h (DOTLOCK_EXT_SYM_PREFIX): New macro.
+
+2011-09-29  Werner Koch  <wk@g10code.com>
+
+       * dotlock.c (DOTLOCK_USE_PTHREAD): New macro.
+       [DOTLOCK_USE_PTHREAD] (all_lockfiles_mutex): New.
+       (LOCK_all_lockfiles, UNLOCK_all_lockfiles): New.  Use them to
+       protect access to all_lockfiles.
+       (dotlock_set_fd, dotlock_get_fd): New.
+
+2011-09-28  Werner Koch  <wk@g10code.com>
+
+       * dotlock.c (dotlock_take, dotlock_take_unix, dotlock_take_w32):
+       Implement arbitrary timeout values.
+       (dotlock_create): Add arg FLAGS for future extensions.
+
+2011-09-27  Werner Koch  <wk@g10code.com>
+
+       * dotlock.c (dotlock_take_unix): Check only the link count and not
+       the error return from link.
+       (use_hardlinks_p): New.
+       (dotlock_create_unix): Test for hardlinks.
+       (dotlock_take_unix): Implement O_EXCL locking.
+
+2011-09-23  Werner Koch  <wk@g10code.com>
+
+       * dotlock.c: Factor Unix and W32 specific code out into specific
+       functions.  Define HAVE_POSIX_SYSTEM.  Rearrange some functions.
+       (disable_dotlock): Rename to dotlock_disable.
+       (create_dotlock): Rename to dotlock_create.
+       (destroy_dotlock): Rename to dotlock_destroy.
+       (make_dotlock): Rename to dotlock_take.
+       (release_dotlock): Rename to dotlock_release.
+
+2011-09-22  Werner Koch  <wk@g10code.com>
+
+       * dotlock.c: Remove support for RISCOS.
+
+2011-08-10  Werner Koch  <wk@g10code.com>
+
+       * t-exechelp.c (test_close_all_fds): Don't use the DUMMY_FD var.
+
+       * pka.c (get_pka_info): Remove unused var.
+
+       * signal.c (got_fatal_signal): Remove unused var.
+
+       * estream.c (es_fread, es_fwrite): Remove unused var.
+
+2011-07-20  Werner Koch  <wk@g10code.com>
 
        * ssh-utils.c, ssh-utils.h: New.
        * t-ssh-utils.c: New.
        * Makefile.am (t_ssh_utils_LDADD): New.
        (module_tests): Add t-ssh-utils.c
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-06-01  Marcus Brinkmann  <mb@g10code.com>
+
+       * util.h: Undef snprintf before redefining it.
+
+2011-05-20  Werner Koch  <wk@g10code.com>
+
+       * util.h: Remove some error code substitutes.
+
+2011-04-25  Werner Koch  <wk@g10code.com>
+
+       * userids.c (classify_user_id): Add arg OPENPGP_HACK to fix
+       regression from 2009-12-08.
+
+2011-04-01  Werner Koch  <wk@g10code.com>
+
+       * sysutils.c (get_uint_nonce): New.
+
+2011-03-03  Werner Koch  <wk@g10code.com>
+
+       * estream.c (struct estream_list): Rename to estream_list_s and
+       simplify.  A double linked list is overkill for our purpose.
+       (do_list_add, do_list_remove): Adjust accordingly.
+       (_es_get_std_stream): Ditto.
+       (do_list_iterate, estream_iterator_t): Remove; it is used only at
+       one place.
+       (es_fflush): Replace iteration function.  Also lock each stream
+       while flushing all streams.
+
+2011-02-27  Werner Koch  <wk@g10code.com>
 
-       * pka.c (get_pka_info): Remove set but unused variables ARCOUNT
-       and NSCOUNT.
-       * estream.c (es_fwrite, es_fread): Remove set but unused variable
-       ERR.
+       * gettime.c (isotime2epoch): Factor check code out to ..
+       (isotime_p): .. new.
+       (isotime_human_p): New.
+       (string2isotime): New.
+       * t-gettime.c (test_string2isotime): New.
 
-2011-04-29  Werner Koch  <wk@g10code.com>
+2011-02-11  Andrey Jivsov <openpgp@brainhub.org>
 
-       * estream.c (es_pth_kill): New.
-       (estream_pth_killed): New.
-       (ESTREAM_MUTEX_LOCK, ESTREAM_MUTEX_UNLOCK)
-       (ESTREAM_MUTEX_TRYLOCK, ESTREAM_MUTEX_INITIALIZE): Take care of
-       the killed status.
-       (ESTREAM_SYS_YIELD): Ditto.
-       (es_pth_read, es_pth_write): Ditto.
-       (es_init_do): Ditto.
+       * openpgp-oid.c (openpgp_oid_to_str): Use unsigned int for
+       get_opaque.  Fixes a bug on 64 bit platforms.
+
+2011-02-08  Werner Koch  <wk@g10code.com>
+
+       * http.c (connect_server): Add arg R_HOST_NOT_FOUND.
+
+2011-02-07  Werner Koch  <wk@g10code.com>
+
+       * http.c (my_socket_new, my_socket_ref, my_socket_unref): New.
+       (cookie_close, cookie_read, cookie_write, http_close, _http_open)
+       (send_request): Replace use of an socket integer by the new socket
+       object.
+       (_http_raw_connect): New.
+       (fp_onclose_notification): New.
+       (_http_raw_connect, _http_wait_response, http_close): Register and
+       unregister this notification.
+       * http.h (http_raw_connect): New.
+
+       * http.h (parsed_uri_s): Add field IS_OPAQUE.
+       (http_req_t): Add HTTP_REQ_OPAQUE.
+       * http.c (do_parse_uri): Parse unknown schemes into PATH.
+       (my_socket_new, my_socket_ref, my_socket_unref): New.
+       (send_request): Simplify save_errno stuff.
+
+2011-02-03  Werner Koch  <wk@g10code.com>
+
+       * status.h (STATUS_DECRYPTION_INFO): New.
+
+       * argparse.c (strusage): Update copyright year.
+
+2011-01-31  Werner Koch  <wk@g10code.com>
+
+       * openpgp-oid.c: New.
+       * t-openpgp-oid.c: New.
 
 2011-01-20  Werner Koch  <wk@g10code.com>
 
+       Fix bug#1313.
+
+       * http.c (my_select): New.  Define to pth_select if building with Pth.
+       (start_server, write_server, cookie_read, cookie_write): Use it.
+       (my_connect): New.  Define to pth_connect if building with Pth.
+       (connect_server): Use it.
+       (my_accept): New.  Define to pth_accept if building with Pth.
+       (start_server): Use it.
+
+2011-01-20  Werner Koch  <wk@g10code.com>
+
+       * util.h (struct b64state): Add field LASTERR.
+       * b64enc.c (enc_start, b64enc_write, b64enc_finish): Handle
+       LASTERR.  This is to make sure that we don't leak strduped data.
+       * b64dec.c (b64dec_start, b64dec_proc, b64dec_finish): Ditto.
+
+       * http.c (escape_data): New.
+       (insert_escapes): Implement using escape_data.
+       (http_escape_data): New.
+
+2011-01-19  Werner Koch  <wk@g10code.com>
+
+       * homedir.c (gnupg_module_name): Use NAME_OF_INSTALLED_GPG instead
+       of "gpg2".
+
+2011-01-18  Werner Koch  <wk@g10code.com>
+
+       * iobuf.c (file_es_filter_ctx_t): New.
+       (file_es_filter): New.
+       (iobuf_esopen): New.
+
+       * membuf.c (clear_membuf, peek_membuf): New.
+
+       * util.h (GPG_ERR_NO_KEYSERVER): New.
+
+       * keyserver.h (keyserver_spec): Move from ../g10/options.h to here.
+
+       * http.c (do_parse_uri): Add arg NO_SCHEME_CHECK.  Change all
+       callers.  Support HKP and HKPS.
+       (_http_parse_uri): Do proper error management.
+       * http.h (parsed_uri_s): Add field IS_HTTP.
+       (http_parse_uri): Support NO_SCHEME_CHECK arg.
+
        * estream.c (es_func_mem_write): Fix computation of NEWSIZE.
 
-2011-01-11  Werner Koch  <wk@g10code.com>
+2011-01-10  Werner Koch  <wk@g10code.com>
+
+       * session-env.c (update_var): Fix same value detection.  Fixes
+       bug#1311.
+
+2010-12-17  Werner Koch  <wk@g10code.com>
+
+       * asshelp.c (lock_spawning): Add arg VERBOSE.  Improve timeout
+       management.  Make callers pass a value for VERBOSE.
+       (lock_agent_spawning, unlock_agent_spawning): Remove.  Change
+       callers to use lock_spawning and unlock_spawning.
+
+2010-12-17  Marcus Brinkmann  <mb@g10code.com>
+
+       * homedir.c (gnupg_cachedir): Create /temp subdirectories.
+
+2010-12-02  Werner Koch  <wk@g10code.com>
+
+       * miscellaneous.c (gnupg_cipher_algo_name): New.  Replace all
+       users of gcry_cipher_algo_name by this one.
+
+       * logging.c (fun_cookie_s) [W32CE]: Add field USE_WRITEFILE.
+       (fun_writer) [W32CE]: Make use of it.
+       (set_file_fd) [W32CE]: Implement special filename "GPG2:".
+
+2010-11-25  Werner Koch  <wk@g10code.com>
+
+       * asshelp.c (start_new_gpg_agent): Change style of startup info.
+       (start_new_dirmngr): Ditto.
+
+2010-11-23  Werner Koch  <wk@g10code.com>
+
+       * asshelp.c (SECS_TO_WAIT_FOR_AGENT, SECS_TO_WAIT_FOR_DIRMNGR):
+       Use these constants.  For W32CE increase them to 30 seconds.
+       (start_new_gpg_agent): Print time to startup agent.
+       (start_new_dirmngr): Ditto.
+
+2010-11-04  Werner Koch  <wk@g10code.com>
+
+       * logging.c (do_logv) [W32]: Don't set a default log stream if the
+       registry entry is empty.
+
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * gettime.c (gnupg_get_isotime): Compare to (time_t)-1.
+       (epoch2isotime): Ditto.
+       (IS_INVALID_TIME_T): New.
+       (asctimestamp): Use new macro.
+       (strtimestamp, isotimestamp): Ditto.  Use snprintf.
+
+2010-10-25  Werner Koch  <wk@g10code.com>
+
+       * logging.c (do_log): Rename to log_log and make global.
+
+2010-10-20  Werner Koch  <wk@g10code.com>
+
+       * i18n.c (i18n_init) [USE_SIMPLE_GETTEXT]: Call textdomain.
+
+2010-10-14  Werner Koch  <wk@g10code.com>
+
+       * asshelp.c (start_new_gpg_agent): Print a notice once the agent
+       has been started.
+       (start_new_dirmngr): Likewise.
+
+2010-10-13  Werner Koch  <wk@g10code.com>
+
+       * miscellaneous.c (parse_version_number, parse_version_string)
+       (gnupg_compare_version): New.
+
+2010-10-04  Werner Koch  <wk@g10code.com>
+
+       * gettime.c (asctimestamp) [W32CE]: Do not print the timezone.
+
+2010-09-30  Werner Koch  <wk@g10code.com>
+
+       * util.h (GPG_ERR_FULLY_CANCELED): Add replacement.
+
+2010-09-17  Werner Koch  <wk@g10code.com>
+
+       * http.c (INADDR_NONE): Provide fallback.
+       * logging.c (INADDR_NONE): Ditto.
+
+2010-09-16  Werner Koch  <wk@g10code.com>
+
+       * util.h: Add GPG_ERR_MISSING_ISSUER_CERT.
+       * status.c (get_inv_recpsgnr_code): Ditto.
+
+2010-09-13  Werner Koch  <wk@g10code.com>
+
+       * homedir.c (gnupg_bindir) [W32CE]: Change to bin/.
+       (gnupg_libexecdir) [W32]: Call gnupg_bindir.
+       (gnupg_libdir, gnupg_datadir, gnupg_localedir) [W32]: Simplify by
+       using xstrconcat.
+       (gnupg_module_name): Ditto.
+       (w32_rootdir): Strip a trailing "bin".
+
+2010-09-02  Werner Koch  <wk@g10code.com>
+
+       * util.h (GPG_ERR_NOT_INITIALIZED): Define if not defined.
+
+2010-09-01  Marcus Brinkmann  <marcus@g10code.de>
+
+       * estream.c (_es_set_std_fd): Disable debug output.
+
+2010-08-26  Werner Koch  <wk@g10code.com>
+
+       * estream.c (es_convert_mode): Rename to parse_mode.
+       (parse_mode): Add arg R_CMODE and parse key value pairs.  Use Use
+       664 as the default mode.  Change callers.
+       (ES_DEFAULT_OPEN_MODE): Remove.
+       (es_fopen, do_fpopen, do_w32open, es_freopen): Support a creation
+       mode.
+       (es_func_file_create): Rename to func_file_create and add arg CMODE.
+       (es_func_fd_create): Rename to func_fd_create.
+       (es_func_fp_create): Rename to func_fp_create.
+       (es_list_add): Rename to do_list_add.
+       (es_list_remove): Rename to do_list_remove.
+       (es_list_iterate): Rename to do_list_iterate.
+       (es_pth_read): Rename to do_pth_read.
+       (es_deinit): Rename to do_deinit.
+       (es_init_do): Rename to do_init.
+       (es_func_mem_create): Rename to func_mem_create.
+
+2010-08-23  Werner Koch  <wk@g10code.com>
+
+       * exechelp-w32ce.c: Rewrite all spawn stuff.
+
+       * exechelp-w32.c (close_all_fds) [W32]: Make it a dummy function.
+
+       * estream.c (es_onclose): New.
+       (notify_list_t, onclose): New.
+       (struct estream_internal): Add field ONCLOSE.
+       (es_initialize, es_deinitialize): Manage new field.
+       (do_close): Call onclose notify functions.
+
+2010-08-20  Werner Koch  <wk@g10code.com>
+
+       * exechelp-w32.c (create_inheritable_pipe): Change arg to HANDLE.
+
+       * estream.h (es_sysopen_t): New.
+       * estream.c (es_func_w32_create, es_func_w32_read)
+       (es_func_w32_write, es_func_w32_seek, es_func_w32_destroy)
+       (estream_functions_w32, estream_cookie_fd): New.  Only for W32.
+       (es_sysopen, es_sysopen_nc): New.
+       (do_w32open, do_sysopen): New.
+       (es_syshd, es_syshd_unlocked): New.
+       (struct estream_internal): Replace filed FD by SYSHD.
+       (es_initialize): Clear SYSHD_VALID.
+       (map_w32_to_errno): New.
+       (es_get_fd): Remove.
+       (es_fileno_unlocked): Re-implement using es_syshd.
+       (es_initialize, es_create): Replace arg FD by SYSHD.
+       (es_fopen, es_mopen, es_fopenmem, do_fdopen, do_fpopen)
+       (es_tmpfile): Use SYSHD instead of FD.
+       (es_destroy): Rename to do_close.
+
+2010-08-19  Werner Koch  <wk@g10code.com>
+
+       * exechelp-posix.c (create_pipe_and_estream): New.
+       (gnupg_spawn_process): Rework this function and its calling
+       convention; it is not used anyway.
+       * exechelp-w32.c (gnupg_spawn_process): Ditto.
+
+2010-08-18  Werner Koch  <wk@g10code.com>
+
+       * logging.c (writen): Add arg IS_SOCKET.
+       (fun_writer): Pass the is_socket flag.
+       (do_logv) [W32]: Allow for a default log stream
+
+       * estream.c (struct estream_internal): Remove obsolete fields
+       PRINT_FP, PRINT_ERRNO, PRINT_ERR and all remaining code cruft.
+
+2010-08-16  Werner Koch  <wk@g10code.com>
+
+       * estream.c (es_printf_unlocked, es_printf): New.
+
+       * asshelp.c (lock_agent_t): Rename to lock_spawn_t.
+       (lock_agent_spawning, unlock_agent_spawning): Factor code out to ...
+       (lock_spawning, unlock_spawning): .. new.
+       (start_new_gpg_agent): Make more use of ERRSOURCE.
+       (start_new_dirmngr): New.
+
+2010-08-13  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (audit-events.h, status-codes.h): Fix srcdir problem
+       amd depend on Makefile.am instead of Makefile.
+
+2010-08-12  Werner Koch  <wk@g10code.com>
+
+       * sysutils.c (gnupg_remove) [W32CE]: Fix returned error.
+
+2010-08-09  Werner Koch  <wk@g10code.com>
+
+       * logging.c (WITH_IPV6): New macro.
+       (parse_portno): New.  From libassuan.
+       (fun_writer): Support TCP logging on all platforms.
+       (sock_close): New.
+
+2010-08-06  Werner Koch  <wk@g10code.com>
+
+       * homedir.c (dirmngr_socket_name) [W32CE]: Base on default homedir.
+       (gnupg_cachedir) [W32CE]: Drop drive letter.
+
+       * http.c (http_open_document): Rename to _http_open_document and
+       add arg ERRSOURCE.  Pass ERRSOURCE to all called funcs.
+       (http_wait_response, http_open, http_parse_uri): Likewise.
+       (do_parse_uri, parse_response, store_header): Change to return an
+       gpg_err_code_t.  Change callers.
+       (send_request): Add arg ERRSOURCE.  Change callers.
+       * http.h (http_open_document, http_wait_response, http_open)
+       (http_parse_uri): Define as macro.
+
+2010-08-05  Werner Koch  <wk@g10code.com>
+
+       * estream.h (es_asprintf, es_vasprintf): Add lost prototyps.
+
+       * http.c: Require estream and make HTTP_USE_ESTREAM obsolete.  It
+       make the code unreadable and we require estream anyway for GnuPG.
+       (http_wait_response): Get use of cookies right.
+       (send_request): s/xtryasprintf/es_asprintf/ to allow standalone
+       use of the code.
+       (insert_escapes, connect_server): s/sprintf/snprintf/.
+       (parse_response): s/my_read_line/es_read_line/.
+       (my_read_line): Remove.
+       (write_server): Use pth_write.
+
+2010-07-26  Werner Koch  <wk@g10code.com>
+
+       * estream.c (es_func_fp_write) [W32]: Write smaller chunks.
+
+2010-07-25  Werner Koch  <wk@g10code.com>
+
+       * argparse.c (initialize): Use ARGPARSE_PRINT_WARNING constant.
+
+2010-07-24  Werner Koch  <wk@g10code.com>
+
+       * estream.c (es_set_binary): New.
+
+2010-07-19  Werner Koch  <wk@g10code.com>
+
+       * utf8conv.c (utf8_to_wchar): s/malloc/jnlib_malloc/.
+
+2010-07-16  Werner Koch  <wk@g10code.com>
+
+       * http.h (HTTP_FLAG_IGNORE_CL): Add flag .
+       * http.c (WITHOUT_GNU_PTH): Test macro for Pth support.
+       (http_parse_uri): s/xcalloc/xtrycalloc/.
+       (send_request): Replace of discrete allocation and sprintf by
+       xtryasprintf.
+       (http_wait_response): Replace HTTP_FLAG_NO_SHUTDOWN by
+       HTTP_FLAG_SHUTDOWN to change the default to no shutdown.
+       (cookie_read) [HAVE_PTH]: Use pth_read.
+       (longcounter_t): New.
+       (struct cookie_s): Add support for content length.  Turn flag
+       fields into bit types.
+       (parse_response): Parse content length header.
+       (cookie_read): Take care of the content length.
+
+2010-07-08  Werner Koch  <wk@g10code.com>
+
+       * estream.c (estream_functions_file): Remove and replace by
+       identical estream_functions_fd.
+
+2010-07-06  Werner Koch  <wk@g10code.com>
+
+       * util.h (b64state): Add field STREAM.
+       * b64enc.c (b64enc_start): Factor code out to ..
+       (enc_start): new.
+       (b64enc_start_es, my_fputs): New.
+       (b64enc_write, b64enc_finish): Support estream.
+
+2010-06-24  Werner Koch  <wk@g10code.com>
+
+       * asshelp.c (lock_agent_spawning) [W32]: Use CreateMutexW.
+       (start_new_gpg_agent): Use HANG option for gnupg_wait_progress.
+       Fixes regression from 2010-06-09.
+
+2010-06-21  Werner Koch  <wk@g10code.com>
+
+       * util.h (xfree_fnc): New.
 
-        Estream changes as used by gnupg master from 2010-07-19.
+2010-06-18  Werner Koch  <wk@g10code.com>
+
+       * util.h (GPG_ERR_MISSING_KEY) [!GPG_ERR_MISSING_KEY]: New.
+
+       * sexputil.c (make_canon_sexp_pad): Add arg SECURE.
+
+2010-06-17  Werner Koch  <wk@g10code.com>
+
+       * sexputil.c (make_canon_sexp_pad): New.
+
+2010-06-14  Werner Koch  <wk@g10code.com>
+
+       * membuf.c (put_membuf): Add shortcut for !LEN.
+
+2010-06-11  Marcus Brinkmann  <marcus@g10code.de>
+
+       * sysutils.c (translate_sys2libc_fd): Revert last change.
+       (translate_sys2libc_fd_int): Revert last change.
+
+2010-06-10  Marcus Brinkmann  <marcus@g10code.de>
+
+       * sysutils.c (translate_sys2libc_fd) [HAVE_W32CE_SYSTEM]:
+       Implement.
+       (translate_sys2libc_fd_int) [HAVE_W32CE_SYSTEM]: Don't call
+       translate_sys2libc_fd.
+
+       * estream.c (_es_get_std_stream): Fix cut&paste bug.
+
+2010-06-09  Werner Koch  <wk@g10code.com>
+
+       * exechelp-posix.c, exechelp-w32.c
+       * exechelp-w32ce.c (gnupg_wait_process): Add new arg HANG.  Change
+       all callers.
+       (gnupg_release_process): New.  Use it after all calls to
+       gnupg_wait_process.
+
+       * util.h (GNUPG_MODULE_NAME_DIRMNGR_LDAP): New.
+       * homedir.c (gnupg_cachedir): New.
+       (w32_try_mkdir): New.
+       (dirmngr_socket_name): Change standard socket name.
+       (gnupg_module_name): Support GNUPG_MODULE_NAME_DIRMNGR_LDAP.
+
+       * logging.c (log_set_get_tid_callback): Replace by ...
+       (log_set_pid_suffix_cb): .. new.
+       (do_logv): Change accordingly.
+
+2010-06-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       * Makefile.am (AM_CFLAGS): Add $(LIBASSUAN_CFLAGS).
+       (t_common_ldadd): Add $(LIBASSUAN_LIBS).
+       * sysutils.c: Include <assuan.h>.
+       (translate_sys2libc_fd_int): Cast to silence gcc warning.
+       * iobuf.c: Include <assuan.h>
+       (translate_file_handle): Fix syntax error.
+
+2010-06-08  Werner Koch  <wk@g10code.com>
+
+       * iobuf.c (translate_file_handle) [W32CE]: Handle rendezvous ids.
+
+2010-06-07  Werner Koch  <wk@g10code.com>
+
+       * sysutils.c [W32CE]: Finish pipe creation.
 
        * estream.c (es_fname_get, es_fname_set): New.
        (fname_set_internal): New.
        (_es_get_std_stream): Set stream name.
        (es_fopen, es_freopen, es_deinitialize): Set fname.
 
-2011-01-10  Thomas Mraz  <t8m@centrum.cz>  (wk)
+       * exechelp-posix.c (gnupg_spawn_process): Allow passing INFILE or
+       OUTFILE as NULL.
+       * exechelp-w32.c (gnupg_spawn_process): Ditto.
+       * exechelp-w32ce.c (gnupg_spawn_process): Return an error for
+       INFILE or OUTFILE passed as NULL.
 
-       * pka.c (get_pka_info) [!USE_ADNS]: Turn ANSWER into a union to
-       avoid aliasing problems with modern compilers.  See bug#1307.
-       Reported by Steve Grubb.
+2010-06-01  Werner Koch  <wk@g10code.com>
 
-2011-01-10  Werner Koch  <wk@g10code.com>
+       * logging.c (log_get_stream): Make sture a log stream is available.
 
-       * session-env.c (update_var): Fix same value test.  Fixes
-       bug#1311.
+2010-05-30  Werner Koch  <wk@g10code.com>
 
-2010-09-16  Werner Koch  <wk@g10code.com>
+       * init.c (writestring_via_estream): New.
+       (init_common_subsystems): Register with argparse.
 
-       * util.h: Add GPG_ERR_MISSING_ISSUER_CERT.
-       * status.c (get_inv_recpsgnr_code): Ditto.
+       * argparse.c (argparse_register_outfnc): New.
+       (writestrings, flushstrings): New.  Use them instead of stdout or
+       stderr based functions.
+
+2010-05-04  Werner Koch  <wk@g10code.com>
+
+       * estream.c (_es_get_std_stream): Re-use registered standard fds.
+       (IS_INVALID_FD, ESTREAM_SYS_YIELD): New.
+       (es_func_fd_read, es_func_fd_write, es_func_fd_seek)
+       (es_func_fd_destroy): Implement a dummy stream.
+
+       * exechelp-w32ce.c (build_w32_commandline): Add args FD0_ISNULL
+       and FD1_ISNULL.  Remove arg PGMNAME.  Change callers.
+       (gnupg_spawn_process_detached): Implement.
+       (gnupg_spawn_process_fd): Implement one special case for now.
 
 2010-05-03  Werner Koch  <wk@g10code.com>
 
        (start_new_gpg_agent): Test for configured standard socket and
        try to fire up the agent in this case.
 
-       * exechelp.c (gnupg_spawn_process_detached): Do not reuse PID for
-       the second fork.
-       (gnupg_wait_process): Do not log a message if EXITCODE is given.
+       * exechelp-posix.c (gnupg_wait_process): Do not log a message if
+       EXITCODE is given.
+       (gnupg_spawn_process_detached): Do not reuse PID for the second fork.
+
+2010-04-26  Werner Koch  <wk@g10code.com>
+
+       * utf8conv.c (load_libiconv) [W32CE]: No libiconv warning
+
+       * init.c (init_common_subsystems) [W32CE]: Register the sleep
+       function before es_init.
+
+2010-04-20  Werner Koch  <wk@g10code.com>
+
+       * estream.c (es_deinit): New.
+       (es_init_do): Install atexit handler to flush all streams.
+
+       * Makefile.am (common_sources): Add gettime.h.
+
+2010-04-20  Marcus Brinkmann  <marcus@g10code.de>
+
+       * logging.c (do_log_ignore_arg): New helper function.
+       (log_string): Use it to remove ugly volatile hack that causes gcc
+       warning.
+       (log_flush): Likewise.
+       * sysutils.c (gnupg_unsetenv) [!HAVE_W32CE_SYSTEM]: Return something.
+       (gnupg_setenv) [!HAVE_W32CE_SYSTEM]: Likewise.
+       * pka.c (get_pka_info): Solve strict aliasing rule violation.
+       * t-exechelp.c (test_close_all_fds): Use dummy variables to
+       silence gcc warning.
+
+2010-04-15  Werner Koch  <wk@g10code.com>
+
+       * util.h: Factor time related functions out to ...
+       * gettime.h: New.
+       (gnupg_copy_time): Move to ...
+       * gettime.c (gnupg_copy_time): New.
+
+       * sysutils.c (gnupg_setenv) [!W32CE]: Add missing return.
+       (gnupg_unsetenv) [!W32CE]: Add missing return.
+
+2010-04-14  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (noinst_LIBRARIES) [W32CE]: Exclude libsimple-pwquery.
+
+       * w32help.h (umask) [W32CE]: New.
+
+       * sysutils.c (_gnupg_isatty): New.
+       * util.h (gnupg_isatty): New.
+
+       * asshelp.c (setup_libassuan_logging): Read ASSUAN_DEBUG envvar.
+       (my_libassuan_log_handler): Use it.
+       * sysutils.c (_gnupg_getenv): Implement ASSUAN_DEBUG.
+
+2010-04-08  Werner Koch  <wk@g10code.com>
+
+       * w32help.h (_setmode, setmode) [W32CE]: Provide prototype and
+       macro.
+
+2010-04-07  Werner Koch  <wk@g10code.com>
+
+       * mischelp.c (timegm): Replace unsetenv/putenv by gnupg_unsetenv.
+
+       * sysutils.c: Include setenv.h.
+       (gnupg_setenv, gnupg_unsetenv): New.
+
+
+2010-04-06  Werner Koch  <wk@g10code.com>
+
+       * sysutils.c (gnupg_mkdir): New.
+
+2010-03-29  Werner Koch  <wk@g10code.com>
+
+       * init.c (sleep_on_exit): Change to 400ms.
+
+2010-03-25  Werner Koch  <wk@g10code.com>
+
+       * init.c (sleep_on_exit) [W32CE]: New.
+       (init_common_subsystems): Call it.
+
+2010-03-24  Werner Koch  <wk@g10code.com>
+
+       * stringhelp.c (change_slashes, compare_filenames): Replace
+       HAVE_DRIVE_LETTERS by HAVE_DOSISH_SYSTEM.
+       (make_basename, make_dirname): Detect backslashes and drive
+       letters separately.
+
+       * dotlock.c (make_dotlock, create_dotlock, release_dotlock): Use
+       LockFileEx and UnlockFileEx to support W32CE.
+
+       * ttyio.c (USE_W32_CONSOLE): Replace all _WIN32 by this.
+       (init_ttyfp) [W32CE]: Use stderr.
+
+       * iobuf.c (FD_FOR_STDIN, FD_FOR_STDOUT) [W32CE]: Use estream.
+       (translate_file_handle) [W32CE]: Remove handle translation.
+
+2010-03-23  Werner Koch  <wk@g10code.com>
+
+       * sysutils.c (gnupg_remove): New.
+
+2010-03-22  Werner Koch  <wk@g10code.com>
+
+       * exechelp-w32ce.c (build_w32_commandline): Replace by code from
+       libassuan.
+       (create_inheritable_pipe): Use _assuan_w32ce_prepare_pipe.
+       (build_w32_commandline_copy, do_create_pipe): Remove.
+
+       * exechelp-posix.c (gnupg_spawn_process): Change to use estream
+       also for INFILE and STATUSFILE.
+       * exechelp-w32.c (gnupg_spawn_process): Ditto.
+
+2010-03-22  Werner Koch  <wk@g10code.com>
+
+       * exechelp.c: Remove after factoring all code out to ...
+       * exechelp-posix.c, exechelp-w32.c, exechelp-w32ce.c:  .. new.
+
+       * exechelp.c (create_inheritable_pipe_r)
+       (create_inheritable_pipe_w): Fold both into ...
+       (create_inheritable_pipe): .. New.  Change callers to use this.
+       (gnupg_create_inbound_pipe, gnupg_create_outbound_pipe): Factor
+       code out to ...
+       (do_create_pipe): .. New.
+
+       * init.c (parse_std_file_handles): Change to use rendezvous ids.
+
+2010-03-15  Werner Koch  <wk@g10code.com>
+
+       * init.c (init_common_subsystems): Add args ARGCP and
+       ARGVP.  Change all callers to provide them.
+       (parse_std_file_handles): New.
+
+       * t-sysutils.c (rewind) [W32CE]: Provide a replacement.
+
+       * Makefile.am (module_tests) [W32CE]: Don't build t-exechelp for now.
+
+       * sysutils.c (gnupg_allow_set_foregound_window) [W32CE]: Don't
+       call AllowSetForegroundWindow.
 
-2010-03-17  Werner Koch  <wk@g10code.com>
+       * logging.c (isatty) [W32CE]: New.
+       (fun_writer, set_file_fd): Use estream even for the internal error
+       messages.
+       (log_string, log_flush): Make DUMMY_ARG_PTR static.
 
-       * asshelp.c (start_new_gpg_agent) [W32]: Use a named mutex to
-       avoid starting two agents.
+2010-03-15  Werner Koch  <wk@g10code.com>
+
+       * asshelp.c (send_pinentry_environment) [!HAVE_SETLOCALE]: Do not
+       define OLD_LC.
+       * http.c (connect_server) [!USE_DNS_SRV]: Mark SRVTAG unused.
+       * dns-cert.c (get_dns_cert) [!USE_DNS_CERT]: Mark args unused.
+       * pka.c (get_pka_info): Ditto.
+
+       * signal.c (pause_on_sigusr): Remove.  It was used in ancient gpg
+       version with shared memory IPC.  Last caller removed on 2006-04-18.
+       (do_block) [W32]: Mark arg unused.
+
+       * exechelp.c (w32_open_null): Use CreateFileW.
+
+       * init.c (init_common_subsystems): Add args ARGCP and ARGVP.
+       Change all callers to pass them.
+
+       * logging.c (S_IRGRP, S_IROTH, S_IWGRP, S_IWOTH) [W32]: New.
+       (fun_writer, set_file_fd) [W32]: Disable socket code.
+
+       * localename.c: Include gpg-error.h.
+
+       * util.h (GPG_ERR_NOT_ENABLED): Remove this temporary definition.
 
 2010-03-12  Werner Koch  <wk@g10code.com>
 
        * status.h (STATUS_ENTER): New.
 
-2010-02-11  Marcus Brinkmann  <marcus@g10code.de>
+       * ttyio.c (tty_fprintf): Change to use estream.
 
-       From trunk 2009-10-16, 2009-11-02, 2009-11-05:
+       * miscellaneous.c (print_utf8_string): Rename to print_utf8_buffer
+       and change FP arg to an estream.  Change all callers.
+       (print_utf8_string2): Ditto; new name is to print_utf8_buffer2.
 
-       * Makefile.am (libcommon_a_CFLAGS): Use LIBASSUAN_CFLAGS instead
-       of LIBASSUAN_PTH_CFLAGS.
-       * get-passphrase.c (default_inq_cb, membuf_data_cb): Change return
-       type to gpg_error_t.
-       * asshelp.c (start_new_gpg_agent): Update use of
-       assuan_socket_connect and assuan_pipe_connect.  Convert posix FD
-       to assuan FD.
-       [HAVE_W32_SYSTEM]: Add missing argument in assuan_socket_connect
-       invocation.
-       * iobuf.c (iobuf_open_fd_or_name): Fix type of FD in function
-       declaration.
+2010-03-11  Werner Koch  <wk@g10code.com>
 
-2009-10-13  Werner Koch  <wk@g10code.com>
+       * miscellaneous.c (print_string): Remove.
 
-       From trunk 2009-09-23:
+       * estream.c (es_setvbuf): Fix parameter check.
+       (es_set_buffering): Allow a SIZE of 0.
+       * asshelp.c (setup_libassuan_logging, my_libassuan_log_handler): New.
+       * logging.c (do_logv): Add arg IGNORE_ARG_PTR.  Change all callers.
+       (log_string): New.
+       (log_flush): New.
+       (set_file_fd): Simplify by using estreams es_stderr.
 
-       * asshelp.c (start_new_gpg_agent): Allocate assuan context before
-       starting server.
+       * estream.h (es_stdout, es_stderr, es_stdin): New.
+
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * estream.c (es_func_fp_read, es_func_fp_write, es_func_fp_seek)
+       (es_func_fp_destroy): Allow a NULL FP to implement a dummy stream.
+       (do_fpopen): Ditto.
+       (es_vfprintf_unlocked): New.
+       (es_fprintf_unlocked): Make public.
+       (es_fputs_unlocked): New.
+
+       * logging.h: Replace FILE* by estream_t.
+       * logging.c: Remove USE_FUNWRITER cpp conditional because we now
+       use estream.
+       (my_funopen_hook_ret_t, my_funopen_hook_size_t): Replace by
+       ssize_t.
+       (log_get_stream): Change to return an estream_t.
+       (set_file_fd): Always close the log stream because it can't be
+       assigned to stderr or stdout directly.  Use a dummy estream as
+       last resort log stream.
+       (log_test_fd, log_get_fd): Use es_fileno.
+       (log_get_stream): Assert that we have a log stream.
+       (do_logv): Use estream functions and lock the output.
+
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * util.h: Replace jnlib path part by common.
+       (snprintf): Use the replacement macro on all platforms.
+
+       * Makefile.am (jnlib_sources): New.
+       (libcommon_a_SOURCES, libcommonpth_a_SOURCES): Add jnlib_sources.
+       (jnlib_tests): New.
+       (noinst_PROGRAMS, TESTS): Add jnlib_tests.
+       (t_common_ldadd): Remove libjnlib.a.
+
+       * README.jnlib, ChangeLog.jnlib, libjnlib-config.h, argparse.c
+       * argparse.h, dotlock.c, dotlock.h, dynload.h, logging.c
+       * logging.h, mischelp.c, mischelp.h, stringhelp.c, stringhelp.h
+       * strlist.c, strlist.h, types.h, utf8conv.c, utf8conv.h
+       * w32-afunix.c, w32-afunix.h, w32-reg.c, w32help.h, xmalloc.c
+       * xmalloc.h, t-stringhelp.c, t-support.c, t-support.h
+       * t-timestuff.c, t-w32-reg.c: Move from jnlib to here.
+
+       * init.c: Remove "estream.h".
+       * util.h: Include "estream.h".
+
+       * xasprintf.c, ttyio.c: Remove "estream-printf.h".
+
+2010-03-08  Werner Koch  <wk@g10code.com>
+
+       * exechelp.c [!HAVE_SIGNAL_H]: Do not include signal.h.
+       (DETACHED_PROCESS, CREATE_NEW_PROCESS_GROUP) [W32CE]: Provide stubs.
+
+       * iobuf.h (iobuf_ioctl_t): New.  Use the new macros instead of the
+       hard wired values.
+       * iobuf.c (iobuf_append): Remove.
+       (iobuf_fdopen): Factor code out to ...
+       (do_iobuf_fdopen): ... new.
+       (iobuf_fdopen_nc): New.
+       (iobuf_open_fd_or_name): Implement using iobuf_fdopen_nc.
+
+       * iobuf.c (INVALID_FD): Replace by GNUPG_INVALID_FD.
+       (fp_or_fd_t): Replace by gnupg_fd_t.
+       (my_fileno): Replace by the FD2INT macro.
+       (FILEP_OR_FD_FOR_STDIN, FILEP_OR_FD_FOR_STDOUT): Rename to
+       FD_FOR_STDIN, FD_FOR_STDOUT.
+       (file_filter): Make full use of FD_FOR_STDIN.
+       (USE_SETMODE): Remove.  Not needed without stdio.
+       (my_fopen_ro, my_fopen): Replace unneeded macros.
+
+       * iobuf.c [FILE_FILTER_USES_STDIO]: Remove all code.  It has not
+       been used for a long time.
+
+       * exechelp.h: Include "estream.h".
+
+       * exechelp.c (gnupg_spawn_process): Change OUTFILE to an estream_t.
+
+2010-03-02  Werner Koch  <wk@g10code.com>
+
+       * estream.c, estream.h, estream-printf.c, estream-printf.h: Update
+       from libestream.
+
+2010-03-01  Werner Koch  <wk@g10code.com>
+
+       * signal.c [!HAVE_SIGNAL_H]: Don't include signal.h.
+
+       * iobuf.c (direct_open) [W32CE]: Make filename to wchar_t.
+       (iobuf_cancel) [W32CE]: Use DeleteFile.
 
-2009-12-21  Marcus Brinkmann  <marcus@g10code.de>  (wk)
+       * gettime.c (dump_isotime): Use "%s" to print "none".
+
+       * homedir.c (standard_homedir) [W32CE]: Use wchar_t to create the
+       directory.
+       (w32_rootdir) [W32CE]: Likewise.
+
+       * sysutils.c (translate_sys2libc_fd) [W32CE]: Add support.
+       (gnupg_tmpfile) [W32CE]: Ditto.
+       (_gnupg_getenv) [W32CE]: New.
+
+       * util.h (getpid, getenv) [W32CE]: New.
+
+       * i18n.c (i18n_switchto_utf8)
+       (i18n_switchback) [USE_SIMPLE_GETTEXT]: Use new function from
+       libgpg-error which supports proper restoring.
+
+       * sysutils.c (get_session_marker): Simplified by using gcrypt.
+
+2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
 
        * Makefile.am (audit-events.h, status.h) [!MAINTAINER_MODE]: No
        longer include these rules if not in maintainer mode.
 
 2009-12-08  Werner Koch  <wk@g10code.com>
 
-       * dns-cert.c: Add support for ADNS.
+       * userids.h, userids.c: New.
+       (classify_user_id): Merged from similar fucntions in sm/ and g10/.
+
+       * dns-cert.c (get_dns_cert): Add support for ADNS.
+
+2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       * asshelp.c (start_new_gpg_agent): Convert posix FD to assuan FD.
+
+       * asshelp.c (start_new_gpg_agent) [HAVE_W32_SYSTEM]: Add missing
+       argument in assuan_socket_connect invocation.
+       * iobuf.c (iobuf_open_fd_or_name): Fix type of FD in function
+       declaration.
 
 2009-12-07  Werner Koch  <wk@g10code.com>
 
        * Makefile.am (audit-events.h, status-codes.h): Create files in
        the source dir.  Fixes bug#1164.
 
-2009-12-03  Werner Koch  <wk@g10code.com>
+2009-12-02  Werner Koch  <wk@g10code.com>
 
-       From trunk:
        * audit.c (proc_type_decrypt, proc_type_sign): Implemented.
        (proc_type_verify): Print hash algo infos.
        * audit.h (AUDIT_DATA_CIPHER_ALGO, AUDIT_BAD_DATA_CIPHER_ALSO)
        (AUDIT_NEW_RECP, AUDIT_DECRYPTION_RESULT, AUDIT_RECP_RESULT)
        (AUDIT_ATTR_HASH_ALGO, AUDIT_SIGNED_BY, AUDIT_SIGNING_DONE):
 
+2009-11-05  Marcus Brinkmann  <marcus@g10code.de>
+
+       * asshelp.c (start_new_gpg_agent): Update use of
+       assuan_socket_connect and assuan_pipe_connect.
+
+2009-11-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * get-passphrase.c (default_inq_cb, membuf_data_cb): Change return
+       type to gpg_error_t.
+
+2009-10-28  Werner Koch  <wk@g10code.com>
+
+       * status.h (STATUS_MOUNTPOINT): New.
+
+2009-10-16  Marcus Brinkmann  <marcus@g10code.com>
+
+       * Makefile.am (libcommon_a_CFLAGS): Use LIBASSUAN_CFLAGS instead
+       of LIBASSUAN_PTH_CFLAGS.
+
+2009-10-13  Werner Koch  <wk@g10code.com>
+
+       * exechelp.c (gnupg_kill_process): New.
+
+2009-09-29  Werner Koch  <wk@g10code.com>
+
+       * exechelp.c (create_inheritable_pipe): Rename to
+       create_inheritable_pipe_w.
+       (create_inheritable_pipe_r): New.
+       (gnupg_create_outbound_pipe): New.
+
+       * iobuf.h: Include "sysutils.h"
+
+       * iobuf.c (iobuf_open_fd_or_name): New.
+       (iobuf_get_fname_nonnull): New.
+
+2009-09-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * asshelp.c (start_new_gpg_agent): Allocate assuan context before
+       starting server.
+
 2009-09-03  Werner Koch  <wk@g10code.com>
 
        Update from libestream:
 
        * iobuf.c: Port David's changes from 1.4:
        (fd_cache_invalidate): Pass return code from close back.
-       (direct_open, iobuf_ioctl): Check that eturn value.
+       (direct_open, iobuf_ioctl): Check that return value.
        (fd_cache_synchronize): New.
        (iobuf_ioctl): Add new sub command 4 (fsync).
 
        (atoi_1,atoi_2,atoi_4,xtoi_1,xtoi_2): New.
 
 
- Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-          2008, 2009 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+          2009, 2010, 2011 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
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
similarity index 95%
rename from include/ChangeLog-2011
rename to common/ChangeLog-2011.include
index 7098427..b5a9a5e 100644 (file)
@@ -1,13 +1,23 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+# This is the ChangeLog-2011 from the former ../include directory.  It
+# was moved to here after the removal of the directory on 2014-01-29.
+
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-07-01  Werner Koch  <wk@g10code.com>
+2011-02-01  Werner Koch  <wk@g10code.com>
+
+       * cipher.h (PUBKEY_MAX_NPKEY, PUBKEY_MAX_NSKEY): Bump up to
+       accommodate gcrypt ECC keys.
 
-       * cipher.h (PUBKEY_ALGO_ECDH, PUBKEY_ALGO_ECDSA): New.
+2011-01-21  Werner Koch  <wk@g10code.com>
+
+       * cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros
+       because we now require libgcrypt 1.4.6.
+       (GCRY_PK_ECDH): Add replacement.
 
 2009-08-20  Daiki Ueno  <ueno@unixuser.org>  (wk)
 
@@ -442,3 +452,7 @@ Tue Mar  3 15:11:21 1998  Werner Koch  (wk@isil.d.shuttle.de)
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
similarity index 90%
rename from jnlib/ChangeLog-2011
rename to common/ChangeLog.jnlib
index c8306fc..4ac02f3 100644 (file)
@@ -1,10 +1,77 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       See gnupg/common/ChangeLog for newer changes.
+
+       JNLIB has been merged into GnuPG's common directory.  README.jnlib
+       list the files making up JNLIB.
+
+       * README: Rename to README.jnlib
+       * ChangeLog: Rename to ChangeLog.jnlib.
+       * Makefile.am: Remove.
+
+2010-03-01  Werner Koch  <wk@g10code.com>
+
+       * t-w32-reg.c: New.
+
+       * w32-reg.c (read_w32_registry_string)
+       (write_w32_registry_string): Support W32CE.
+
+2010-02-26  Werner Koch  <wk@g10code.com>
+
+       * t-timestuff.c: New.
+
+       * dynload.h (dlopen, dlsym) [W32CE]: Map to wchar_t.
+
+       * mischelp.c (_jnlib_free): New.
+       (same_file_p) [W32CE]: Map to wchar_t.
+
+       * utf8conv.c (set_native_charset) [W32CE]: Do not use
+       GetConsoleOutputCP.
+       (wchar_to_utf8, utf8_to_wchar) [W32]: New.
+
+       * Makefile.am (t_jnlib_ldadd) [W32CE]: Add gpg-error.
+
+       * t-support.h (getenv) [HAVE_GETENV]: Add getenv stub.
+       [W32CE]: Include gpg-error.h
+       * t-support.c (gpg_err_code_from_errno)
+       (gpg_err_code_from_syserror) [GPG_ERROR_H]: Do not build.
+
+       * t-stringhelp.c (gethome) [!HAVE_GETPWUID]: Keep result of getenv.
+
+       * dotlock.c [!HAVE_SIGNAL_H]: Don't include signal.h.
+       (create_dotlock) [W32CE]: Map filename top wchar_t.
+
+       * libjnlib-config.h [USE_SIMPLE_GETTEXT]: Include gpg-error.h and
+       remove w32help.h.
+       (jnlib_set_errno): New.  Use it everywhere to set ERRNO.
+       (getenv) [!HAVE_GETENV]: New.
+       (getpid) [W32E]: New.
+
+       * stringhelp.c (get_pwdir) [!HAVE_PWD_H]: Mark unused args.
+       (w32_strerror) [W32CE]: Use a simple implementation.
+
+       * w32help.h [USE_SIMPLE_GETTEXT]: Remove all definitions; we are
+       now using the gpg-error included implementation.
+       * w32-gettext.c: Remove.
+
+       * mischelp.c (same_file_p): Fix bug in case the second file can't
+       be opened.
+
+2009-10-19  Werner Koch  <wk@g10code.com>
+
+       * strlist.c (add_to_strlist_try): New.
+
+2009-09-22  Werner Koch  <wk@g10code.com>
+
+       * dotlock.h (DOTLOCK): Rename to dotlock_t.  Change all users.
+
 2009-08-26  Werner Koch  <wk@g10code.com>
 
        * stringhelp.c (do_make_filename): Factor some code out to ..
@@ -697,8 +764,8 @@ Mon Jan 24 13:04:28 CET 2000  Werner Koch  <wk@gnupg.de>
      * You may find it source-copied in other packages.        *
      ***********************************************************
 
- Copyright 2000, 2001, 2002, 2003, 2004,
-          2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+          2010 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
@@ -707,3 +774,7 @@ Mon Jan 24 13:04:28 CET 2000  Werner Koch  <wk@gnupg.de>
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 337e246..87d6820 100644 (file)
@@ -1,5 +1,5 @@
 # Makefile for common gnupg modules
-# Copyright (C) 2001, 2003, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2007, 2010 Free Software Foundation, Inc.
 #
 # This file is part of GnuPG.
 #
 
 ## Process this file with automake to produce Makefile.in
 
-EXTRA_DIST = mkstrtable.awk exaudit.awk exstatus.awk \
-             audit-events.h status-codes.h ChangeLog-2011 \
-            w32info-rc.h.in gnupg.ico
+EXTRA_DIST = mkstrtable.awk exaudit.awk exstatus.awk ChangeLog-2011 \
+             audit-events.h status-codes.h README.jnlib ChangeLog.jnlib \
+            ChangeLog-2011.include w32info-rc.h.in gnupg.ico tls-ca.pem
 
-noinst_LIBRARIES = libcommon.a libcommonpth.a libsimple-pwquery.a libgpgrl.a
-noinst_PROGRAMS = $(module_tests) $(module_maint_tests)
-TESTS = $(module_tests)
+noinst_LIBRARIES = libcommon.a libcommonpth.a libgpgrl.a \
+                   libcommontls.a libcommontlsnpth.a
+if !HAVE_W32CE_SYSTEM
+noinst_LIBRARIES += libsimple-pwquery.a
+endif
+noinst_PROGRAMS = $(jnlib_tests) $(module_tests) $(module_maint_tests)
+TESTS = $(jnlib_tests) $(module_tests)
 
 BUILT_SOURCES = audit-events.h status-codes.h
 
@@ -32,14 +36,31 @@ MAINTAINERCLEANFILES = audit-events.h status-codes.h
 
 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl
 
-AM_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS)
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(KSBA_CFLAGS)
 
 include $(top_srcdir)/am/cmacros.am
 
+jnlib_sources = \
+       libjnlib-config.h \
+       types.h host2net.h dynload.h w32help.h \
+       mapstrings.c stringhelp.c stringhelp.h \
+       strlist.c strlist.h \
+       utf8conv.c utf8conv.h \
+       argparse.c argparse.h \
+       logging.c logging.h  \
+       dotlock.c dotlock.h  \
+        mischelp.c mischelp.h
+
+if HAVE_W32_SYSTEM
+jnlib_sources += w32-reg.c w32-afunix.c w32-afunix.h
+endif
+
+
 common_sources = \
        common-defs.h \
        util.h i18n.c i18n.h \
        status.c status.h\
+       shareddefs.h \
        openpgpdefs.h \
        gc-opt-flags.h \
        keyserver.h \
@@ -49,10 +70,9 @@ common_sources = \
        sexputil.c \
        sysutils.c sysutils.h \
        homedir.c \
-       gettime.c \
+       gettime.c gettime.h \
        yesno.c \
-       b64enc.c b64dec.c \
-       zb32.c \
+       b64enc.c b64dec.c zb32.c \
        convert.c \
        percent.c \
        miscellaneous.c \
@@ -61,40 +81,67 @@ common_sources = \
        membuf.c membuf.h \
        iobuf.c iobuf.h \
        ttyio.c ttyio.h \
-       asshelp.c asshelp.h \
-       exechelp.c exechelp.h \
+       asshelp.c asshelp2.c asshelp.h \
+       exechelp.h \
        signal.c \
-       estream.c estream.h estream-printf.c estream-printf.h \
        audit.c audit.h \
        srv.h \
        dns-cert.c dns-cert.h \
        pka.c pka.h \
-       http.c http.h \
        localename.c \
        session-env.c session-env.h \
+       userids.c userids.h \
+       openpgp-oid.c \
        ssh-utils.c ssh-utils.h \
+       agent-opt.c \
        helpfile.c
 
-# Sources only useful without PTH.
-without_pth_sources = \
+# Sources possible requiring a TLS library are put into a separate
+# conveince library.
+tls_sources = \
+       http.c http.h
+
+
+# To make the code easier to read we have split home some code into
+# separate source files.
+if HAVE_W32_SYSTEM
+if HAVE_W32CE_SYSTEM
+common_sources += exechelp-w32ce.c
+else
+common_sources += exechelp-w32.c
+endif
+else
+common_sources += exechelp-posix.c
+endif
+
+# Sources only useful without NPTH.
+without_npth_sources = \
         get-passphrase.c get-passphrase.h
 
 
-libcommon_a_SOURCES = $(common_sources) $(without_pth_sources)
+libcommon_a_SOURCES = $(jnlib_sources) $(common_sources) $(without_npth_sources)
 if USE_DNS_SRV
 libcommon_a_SOURCES += srv.c
 endif
-libcommon_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) -DWITHOUT_GNU_PTH=1
+libcommon_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) -DWITHOUT_NPTH=1
 
-libcommonpth_a_SOURCES = $(common_sources)
+libcommonpth_a_SOURCES = $(jnlib_sources) $(common_sources)
 if USE_DNS_SRV
 libcommonpth_a_SOURCES += srv.c
 endif
-libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS)
+libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
+
+libcommontls_a_SOURCES = $(tls_sources)
+libcommontls_a_CFLAGS = $(AM_CFLAGS) $(LIBGNUTLS_CFLAGS) -DWITHOUT_NPTH=1
 
+libcommontlsnpth_a_SOURCES = $(tls_sources)
+libcommontlsnpth_a_CFLAGS = $(AM_CFLAGS) $(LIBGNUTLS_CFLAGS) $(NPTH_CFLAGS)
+
+if !HAVE_W32CE_SYSTEM
 libsimple_pwquery_a_SOURCES = \
        simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h
 libsimple_pwquery_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS)
+endif
 
 libgpgrl_a_SOURCES = \
         gpgrlhelp.c
@@ -108,30 +155,60 @@ if MAINTAINER_MODE
 # is a distributed built source.  If we would not do that we may end
 # up with two files and then it is not clear which version of the
 # files will be picked up.
-audit-events.h: Makefile mkstrtable.awk exaudit.awk audit.h
+audit-events.h: Makefile.am mkstrtable.awk exaudit.awk audit.h
        $(AWK) -f $(srcdir)/exaudit.awk $(srcdir)/audit.h \
          | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \
                   -v namespace=eventstr_  > $(srcdir)/audit-events.h
 
 # Create the status-codes.h include file from status.h
-status-codes.h: Makefile mkstrtable.awk exstatus.awk status.h
+status-codes.h: Makefile.am mkstrtable.awk exstatus.awk status.h
        $(AWK) -f $(srcdir)/exstatus.awk $(srcdir)/status.h \
          | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \
                   -v namespace=statusstr_  > $(srcdir)/status-codes.h
-
 endif
 
-
 #
 # Module tests
 #
-module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil t-exechelp \
-              t-session-env t-ssh-utils
-module_maint_tests = t-helpfile t-b64
+t_jnlib_src = t-support.c t-support.h
+jnlib_tests = t-stringhelp t-timestuff
+if HAVE_W32_SYSTEM
+jnlib_tests += t-w32-reg
+endif
+module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil \
+              t-session-env t-openpgp-oid t-ssh-utils t-dns-cert \
+              t-mapstrings t-zb32
+if !HAVE_W32CE_SYSTEM
+module_tests += t-exechelp
+endif
+
+if MAINTAINER_MODE
+module_maint_tests = t-helpfile t-b64 t-http
+else
+module_maint_tests =
+endif
 
-t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \
-                 $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
 
+t_common_cflags = $(KSBA_CFLAGS) $(LIBGCRYPT_CFLAGS) \
+                  $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
+t_common_ldadd = libcommon.a ../gl/libgnu.a \
+                 $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+                $(LIBINTL) $(LIBICONV)
+
+
+# jnlib tests
+t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src)
+t_stringhelp_LDADD = $(t_common_ldadd)
+
+t_timestuff_SOURCES = t-timestuff.c $(t_jnlib_src)
+t_timestuff_LDADD = $(t_common_ldadd)
+
+if HAVE_W32_SYSTEM
+t_w32_reg_SOURCES = t-w32-reg.c $(t_jnlib_src)
+t_w32_reg_LDADD   = $(t_common_ldadd)
+endif
+
+# common tests
 t_convert_LDADD = $(t_common_ldadd)
 t_percent_LDADD = $(t_common_ldadd)
 t_gettime_LDADD = $(t_common_ldadd)
@@ -141,4 +218,17 @@ t_sexputil_LDADD = $(t_common_ldadd)
 t_b64_LDADD = $(t_common_ldadd)
 t_exechelp_LDADD = $(t_common_ldadd)
 t_session_env_LDADD = $(t_common_ldadd)
+t_openpgp_oid_LDADD = $(t_common_ldadd)
 t_ssh_utils_LDADD = $(t_common_ldadd)
+t_dns_cert_LDADD = $(t_common_ldadd) $(DNSLIBS)
+t_mapstrings_LDADD = $(t_common_ldadd)
+t_zb32_LDADD = $(t_common_ldadd)
+
+# http tests
+t_http_SOURCES = t-http.c
+t_http_CFLAGS  = $(t_common_cflags) $(NTBTLS_CFLAGS) $(LIBGNUTLS_CFLAGS)
+t_http_LDADD   = libcommontls.a $(t_common_ldadd) \
+                $(NTBTLS_LIBS) $(LIBGNUTLS_LIBS) $(DNSLIBS)
+
+# All programs should depend on the created libs.
+$(PROGRAMS) : libcommon.a libcommonpth.a libcommontls.a libcommontlsnpth.a
diff --git a/common/README.jnlib b/common/README.jnlib
new file mode 100644 (file)
index 0000000..50a2925
--- /dev/null
@@ -0,0 +1,99 @@
+JNLIB - This is a collection of utility function which are too small
+to put into a library.  The code here is licensed under the LGPL.
+
+libjnlib-config.h should be be modified for each project to make these
+functions fit into the software. Mainly these are memory functions in
+case you need another allocator.
+
+Files which make up jnlib:
+    README.jnlib
+    ChangeLog.jnlib
+    libjnlib-config.h
+    argparse.c
+    argparse.h
+    dotlock.c
+    dotlock.h
+    dynload.h
+    logging.c
+    logging.h
+    mischelp.c
+    mischelp.h
+    stringhelp.c
+    stringhelp.h
+    strlist.c
+    strlist.h
+    types.h
+    utf8conv.c
+    utf8conv.h
+    w32-afunix.c
+    w32-afunix.h
+    w32-reg.c
+    w32help.h
+    xmalloc.c
+    xmalloc.h
+    t-stringhelp.c
+    t-support.c
+    t-support.h
+    t-timestuff.c
+    t-w32-reg.c
+
+
+Here is a template Makefile.am for these jnlib modules:
+===8<==================================================
+EXTRA_DIST = README
+noinst_PROGRAMS = $(module_tests)
+TESTS = $(module_tests)
+
+AM_CPPFLAGS = -I$(top_srcdir)/intl
+
+# We need libgcrypt because libjnlib-config includes gcrypt.h
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS)
+
+noinst_LIBRARIES = libjnlib.a
+
+libjnlib_a_SOURCES = \
+       libjnlib-config.h \
+       stringhelp.c stringhelp.h \
+       strlist.c strlist.h \
+       utf8conv.c utf8conv.h \
+       argparse.c argparse.h \
+       logging.c logging.h  \
+       dotlock.c dotlock.h  \
+       types.h mischelp.c mischelp.h dynload.h w32help.h \
+        xmalloc.c xmalloc.h
+
+if HAVE_W32_SYSTEM
+libjnlib_a_SOURCES += w32-reg.c w32-afunix.c w32-afunix.h
+endif
+
+#
+# Module tests.
+#
+# These tests should only be used at the canonical location of jnlib
+# which is the GnuPG package.  The reason for this is that t-support.c
+# defines replacements for the actual used memory allocation functions
+# so that there is no dependency on libgcrypt.
+#
+module_tests = t-stringhelp t-timestuff
+if HAVE_W32_SYSTEM
+module_tests += t-w32-reg
+endif
+
+t_jnlib_src = t-support.c t-support.h
+t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV)
+# For W32 we need libgpg-error because it provides gettext.
+if HAVE_W32_SYSTEM
+t_jnlib_ldadd += $(GPG_ERROR_LIBS)
+endif
+
+t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src)
+t_stringhelp_LDADD = $(t_jnlib_ldadd)
+
+t_timestuff_SOURCES = t-timestuff.c $(t_jnlib_src)
+t_timestuff_LDADD = $(t_jnlib_ldadd)
+
+if HAVE_W32_SYSTEM
+t_w32_reg_SOURCES = t-w32-reg.c $(t_jnlib_src)
+t_w32_reg_LDADD   = $(t_jnlib_ldadd)
+endif
+==>8===================================================
diff --git a/common/agent-opt.c b/common/agent-opt.c
new file mode 100644 (file)
index 0000000..4317ba3
--- /dev/null
@@ -0,0 +1,71 @@
+/* agent-opt.c - Helper for certain agent options
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "shareddefs.h"
+
+
+/* Parse VALUE and return an integer representing a pinentry_mode_t.
+   (-1) is returned for an invalid VALUE.  */
+int
+parse_pinentry_mode (const char *value)
+{
+  int result;
+
+  if (!strcmp (value, "ask") || !strcmp (value, "default"))
+    result = PINENTRY_MODE_ASK;
+  else if (!strcmp (value, "cancel"))
+    result = PINENTRY_MODE_CANCEL;
+  else if (!strcmp (value, "error"))
+    result = PINENTRY_MODE_ERROR;
+  else if (!strcmp (value, "loopback"))
+    result = PINENTRY_MODE_LOOPBACK;
+  else
+    result = -1;
+
+  return result;
+}
+
+/* Return the string representation for the pinentry MODE.  Returns
+   "?" for an invalid mode.  */
+const char *
+str_pinentry_mode (pinentry_mode_t mode)
+{
+  switch (mode)
+    {
+    case PINENTRY_MODE_ASK:      return "ask";
+    case PINENTRY_MODE_CANCEL:   return "cancel";
+    case PINENTRY_MODE_ERROR:    return "error";
+    case PINENTRY_MODE_LOOPBACK: return "loopback";
+    }
+ return "?";
+}
similarity index 87%
rename from jnlib/argparse.c
rename to common/argparse.c
index 49f50ec..0a36a9e 100644 (file)
@@ -1,22 +1,32 @@
 /* [argparse.c wk 17.06.97] Argument Parser for option handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2006
- *               2007, 2008, 2012  Free Software Foundation, Inc.
- * Copyright (C) 1997, 2013 Werner Koch
+ * Copyright (C) 1998-2001, 2006-2008, 2012  Free Software Foundation, Inc.
+ * Copyright (C) 1997-2001, 2006-2008, 2013 Werner Koch
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -160,10 +170,62 @@ struct iio_item_def_s
 };
 
 static const char *(*strusage_handler)( int ) = NULL;
+static int (*custom_outfnc) (int, const char *);
 
 static int  set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s);
 static void show_help(ARGPARSE_OPTS *opts, unsigned flags);
 static void show_version(void);
+static int writestrings (int is_error, const char *string, ...)
+#if __GNUC__ >= 4
+  __attribute__ ((sentinel(0)))
+#endif
+  ;
+
+
+void
+argparse_register_outfnc (int (*fnc)(int, const char *))
+{
+  custom_outfnc = fnc;
+}
+
+
+/* Write STRING and all following const char * arguments either to
+   stdout or, if IS_ERROR is set, to stderr.  The list of strings must
+   be terminated by a NULL.  */
+static int
+writestrings (int is_error, const char *string, ...)
+{
+  va_list arg_ptr;
+  const char *s;
+  int count = 0;
+
+  if (string)
+    {
+      s = string;
+      va_start (arg_ptr, string);
+      do
+        {
+          if (custom_outfnc)
+            custom_outfnc (is_error? 2:1, s);
+          else
+            fputs (s, is_error? stderr : stdout);
+          count += strlen (s);
+        }
+      while ((s = va_arg (arg_ptr, const char *)));
+      va_end (arg_ptr);
+    }
+  return count;
+}
+
+
+static void
+flushstrings (int is_error)
+{
+  if (custom_outfnc)
+    custom_outfnc (is_error? 2:1, NULL);
+  else
+    fflush (is_error? stderr : stdout);
+}
 
 
 static void
@@ -182,7 +244,7 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
       arg->err = 0;
       arg->flags |= 1<<15; /* Mark as initialized.  */
       if ( *arg->argc < 0 )
-        jnlib_log_bug ("invalid argument for arg_parsee\n");
+        jnlib_log_bug ("invalid argument for arg_parse\n");
     }
 
 
@@ -235,7 +297,7 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
           else
             jnlib_log_error (_("invalid option \"%.50s\"\n"), s);
        }
-      if ( arg->err != 1 )
+      if (arg->err != ARGPARSE_PRINT_WARNING)
         exit (2);
       arg->err = 0;
     }
@@ -773,6 +835,7 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
         {
           /* Stop option processing.  */
           arg->internal.stopped = 1;
+          arg->flags |= ARGPARSE_FLAG_STOP_SEEN;
           argc--; argv++; idx++;
           goto next_one;
        }
@@ -796,7 +859,7 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
        }
       else if ( i < 0 && !strcmp( "warranty", s+2))
         {
-          puts ( strusage (16) );
+          writestrings (0, strusage (16), "\n", NULL);
           exit (0);
        }
       else if ( i < 0 && !strcmp( "dump-options", s+2) )
@@ -804,9 +867,10 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
           for (i=0; opts[i].short_opt; i++ )
             {
               if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
-                printf ("--%s\n", opts[i].long_opt);
+                writestrings (0, "--", opts[i].long_opt, "\n", NULL);
            }
-          fputs ("--dump-options\n--help\n--version\n--warranty\n", stdout);
+          writestrings (0, "--dump-options\n--help\n--version\n--warranty\n",
+                        NULL);
           exit (0);
        }
 
@@ -1072,11 +1136,12 @@ static void
 show_help (ARGPARSE_OPTS *opts, unsigned int flags)
 {
   const char *s;
+  char tmp[2];
 
   show_version ();
-  putchar ('\n');
+  writestrings (0, "\n", NULL);
   s = strusage(41);
-  puts (s);
+  writestrings (0, s, "\n", NULL);
   if ( opts[0].description )
     {
       /* Auto format the option description.  */
@@ -1094,10 +1159,10 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags)
       /* Example: " -v, --verbose   Viele Sachen ausgeben" */
       indent += 10;
       if ( *opts[0].description != '@' )
-        puts ("Options:");
+        writestrings (0, "Options:", "\n", NULL);
       for (i=0; opts[i].short_opt; i++ )
         {
-          s = _( opts[i].description );
+          s = map_static_macro_string (_( opts[i].description ));
           if ( s && *s== '@' && !s[1] ) /* Hide this line.  */
             continue;
           if ( s && *s == '@' )  /* Unindented comment only line.  */
@@ -1107,61 +1172,76 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags)
                   if ( *s == '\n' )
                     {
                       if( s[1] )
-                        putchar('\n');
+                        writestrings (0, "\n", NULL);
                    }
                   else
-                    putchar(*s);
-               }
-              putchar('\n');
+                    {
+                      tmp[0] = *s;
+                      tmp[1] = 0;
+                      writestrings (0, tmp, NULL);
+                    }
+                }
+              writestrings (0, "\n", NULL);
               continue;
            }
 
           j = 3;
           if ( opts[i].short_opt < 256 )
             {
-              printf (" -%c", opts[i].short_opt);
+              tmp[0] = opts[i].short_opt;
+              tmp[1] = 0;
+              writestrings (0, " -", tmp, NULL );
               if ( !opts[i].long_opt )
                 {
                   if (s && *s == '|' )
                     {
-                      putchar (' '); j++;
+                      writestrings (0, " ", NULL); j++;
                       for (s++ ; *s && *s != '|'; s++, j++ )
-                        putchar (*s);
+                        {
+                          tmp[0] = *s;
+                          tmp[1] = 0;
+                          writestrings (0, tmp, NULL);
+                        }
                       if ( *s )
                         s++;
                    }
                }
            }
           else
-            fputs("   ", stdout);
+            writestrings (0, "   ", NULL);
           if ( opts[i].long_opt )
             {
-              j += printf ("%c --%s", opts[i].short_opt < 256?',':' ',
-                           opts[i].long_opt );
+              tmp[0] = opts[i].short_opt < 256?',':' ';
+              tmp[1] = 0;
+              j += writestrings (0, tmp, " --", opts[i].long_opt, NULL);
               if (s && *s == '|' )
                 {
                   if ( *++s != '=' )
                     {
-                      putchar(' ');
+                      writestrings (0, " ", NULL);
                       j++;
                    }
                   for ( ; *s && *s != '|'; s++, j++ )
-                    putchar(*s);
+                    {
+                      tmp[0] = *s;
+                      tmp[1] = 0;
+                      writestrings (0, tmp, NULL);
+                    }
                   if ( *s )
                     s++;
                }
-              fputs ("   ", stdout);
+              writestrings (0, "   ", NULL);
               j += 3;
            }
           for (;j < indent; j++ )
-            putchar(' ');
+            writestrings (0, " ", NULL);
           if ( s )
             {
               if ( *s && j > indent )
                 {
-                  putchar('\n');
+                  writestrings (0, "\n", NULL);
                   for (j=0;j < indent; j++ )
-                    putchar (' ');
+                    writestrings (0, " ", NULL);
                }
               for (; *s; s++ )
                 {
@@ -1169,44 +1249,31 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags)
                     {
                       if ( s[1] )
                         {
-                          putchar ('\n');
+                          writestrings (0, "\n", NULL);
                           for (j=0; j < indent; j++ )
-                            putchar (' ');
+                            writestrings (0, " ", NULL);
                        }
                    }
                   else
-                    putchar (*s);
+                    {
+                      tmp[0] = *s;
+                      tmp[1] = 0;
+                      writestrings (0, tmp, NULL);
+                    }
                }
            }
-          putchar ('\n');
+          writestrings (0, "\n", NULL);
        }
        if ( (flags & ARGPARSE_FLAG_ONEDASH) )
-           puts ("\n(A single dash may be used instead of the double ones)");
+          writestrings (0, "\n(A single dash may be used "
+                        "instead of the double ones)\n", NULL);
     }
   if ( (s=strusage(19)) )
     {
-      /* bug reports to ... */
-      char *s2;
-
-      putchar('\n');
-      s2 = strstr (s, "@EMAIL@");
-      if (s2)
-        {
-          if (s2-s)
-            fwrite (s, s2-s, 1, stdout);
-#ifdef PACKAGE_BUGREPORT
-          fputs (PACKAGE_BUGREPORT, stdout);
-#else
-          fputs ("bug@example.org", stdout);
-#endif
-          s2 += 7;
-          if (*s2)
-            fputs (s2, stdout);
-        }
-      else
-        fputs(s, stdout);
+      writestrings (0, "\n", NULL);
+      writestrings (0, s, NULL);
     }
-  fflush(stdout);
+  flushstrings (0);
   exit(0);
 }
 
@@ -1217,31 +1284,31 @@ show_version ()
   int i;
 
   /* Version line.  */
-  fputs (strusage (11), stdout);
+  writestrings (0, strusage (11), NULL);
   if ((s=strusage (12)))
-    printf (" (%s)", s );
-  printf (" %s\n", strusage (13) );
+    writestrings (0, " (", s, ")", NULL);
+  writestrings (0, " ", strusage (13), "\n", NULL);
   /* Additional version lines. */
   for (i=20; i < 30; i++)
     if ((s=strusage (i)))
-      printf ("%s\n", s );
+      writestrings (0, s, "\n", NULL);
   /* Copyright string.  */
-  if( (s=strusage (14)) )
-    printf("%s\n", s );
+  if ((s=strusage (14)))
+    writestrings (0, s, "\n", NULL);
   /* Licence string.  */
   if( (s=strusage (10)) )
-    printf("%s\n", s );
+    writestrings (0, s, "\n", NULL);
   /* Copying conditions. */
   if ( (s=strusage(15)) )
-    fputs (s, stdout);
+    writestrings (0, s, NULL);
   /* Thanks. */
   if ((s=strusage(18)))
-    fputs (s, stdout);
+    writestrings (0, s, NULL);
   /* Additional program info. */
   for (i=30; i < 40; i++ )
     if ( (s=strusage (i)) )
-      fputs (s, stdout);
-  fflush (stdout);
+      writestrings (0, s, NULL);
+  flushstrings (0);
 }
 
 
@@ -1252,20 +1319,21 @@ usage (int level)
 
   if (!level)
     {
-      fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), strusage (14));
-      fflush (stderr);
+      writestrings (1, strusage(11), " ", strusage(13), "; ",
+                    strusage (14), "\n", NULL);
+      flushstrings (1);
     }
   else if (level == 1)
     {
       p = strusage (40);
-      fputs (p, stderr);
+      writestrings (1, p, NULL);
       if (*p && p[strlen(p)] != '\n')
-        putc ('\n', stderr);
+        writestrings (1, "\n", NULL);
       exit (2);
     }
   else if (level == 2)
     {
-      puts (strusage(41));
+      writestrings (0, strusage(41), "\n", NULL);
       exit (0);
     }
 }
@@ -1295,7 +1363,7 @@ strusage( int level )
   const char *p = strusage_handler? strusage_handler(level) : NULL;
 
   if ( p )
-    return p;
+    return map_static_macro_string (p);
 
   switch ( level )
     {
@@ -1304,7 +1372,7 @@ strusage( int level )
       break;
     case 11: p = "foo"; break;
     case 13: p = "0.0"; break;
-    case 14: p = "Copyright (C) 2015 Free Software Foundation, Inc."; break;
+    case 14: p = "Copyright (C) 2014 Free Software Foundation, Inc."; break;
     case 15: p =
 "This is free software: you are free to change and redistribute it.\n"
 "There is NO WARRANTY, to the extent permitted by law.\n";
@@ -1328,6 +1396,8 @@ strusage( int level )
   return p;
 }
 
+
+/* Set the usage handler.  This function is basically a constructor.  */
 void
 set_strusage ( const char *(*f)( int ) )
 {
@@ -1367,7 +1437,7 @@ main(int argc, char **argv)
 
     while( arg_parse ( &pargs, opts) ) {
        switch( pargs.r_opt ) {
-         case -1 : printf( "arg=`%s'\n", pargs.r.ret_str); break;
+         case -1 : printf( "arg='%s'\n", pargs.r.ret_str); break;
          case 'v': opt.verbose++; break;
          case 'e': opt.echo++; break;
          case 'd': opt.debug++; break;
@@ -1386,9 +1456,9 @@ main(int argc, char **argv)
     if( opt.debug )
        printf("  debug=%d\n", opt.debug );
     if( opt.outfile )
-       printf("  outfile=`%s'\n", opt.outfile );
+       printf("  outfile='%s'\n", opt.outfile );
     if( opt.crf )
-       printf("  crffile=`%s'\n", opt.crf );
+       printf("  crffile='%s'\n", opt.crf );
     if( opt.myopt )
        printf("  myopt=%d\n", opt.myopt );
     if( opt.a_long_one )
similarity index 88%
rename from jnlib/argparse.h
rename to common/argparse.h
index 74f2040..471cf74 100644 (file)
@@ -1,20 +1,31 @@
 /* argparse.h - Argument parser for option handling.
  *     Copyright (C) 1998,1999,2000,2001,2006 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_ARGPARSE_H
@@ -72,6 +83,8 @@ typedef struct
 #define ARGPARSE_FLAG_ONEDASH   32   /* Allow long options with one dash.    */
 #define ARGPARSE_FLAG_NOVERSION 64   /* No output for "--version".           */
 
+#define ARGPARSE_FLAG_STOP_SEEN 256  /* Set to true if a "--" has been seen. */
+
 /* Flags for each option (ARGPARSE_OPTS).  The type code may be
    ORed with the OPT flags.  */
 #define ARGPARSE_TYPE_NONE        0  /* Does not take an argument.        */
@@ -186,5 +199,6 @@ int optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
 void usage( int level );
 const char *strusage( int level );
 void set_strusage( const char *(*f)( int ) );
+void argparse_register_outfnc (int (*fnc)(int, const char *));
 
 #endif /*LIBJNLIB_ARGPARSE_H*/
index 3dc4b22..3fc28a1 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #include "util.h"
 #include "exechelp.h"
 #include "sysutils.h"
-#include "status.h" 
+#include "status.h"
 #include "asshelp.h"
 
 /* The type we use for lock_agent_spawning.  */
 #ifdef HAVE_W32_SYSTEM
-# define lock_agent_t HANDLE
+# define lock_spawn_t HANDLE
 #else
-# define lock_agent_t DOTLOCK
+# define lock_spawn_t dotlock_t
 #endif
 
+/* The time we wait until the agent or the dirmngr are ready for
+   operation after we started them before giving up.  */
+#ifdef HAVE_W32CE_SYSTEM
+# define SECS_TO_WAIT_FOR_AGENT 30
+# define SECS_TO_WAIT_FOR_DIRMNGR 30
+#else
+# define SECS_TO_WAIT_FOR_AGENT 5
+# define SECS_TO_WAIT_FOR_DIRMNGR 5
+#endif
+
+/* A bitfield that specifies the assuan categories to log.  This is
+   identical to the default log handler of libassuan.  We need to do
+   it ourselves because we use a custom log handler and want to use
+   the same assuan variables to select the categories to log. */
+static int log_cats;
+#define TEST_LOG_CAT(x) (!! (log_cats & (1 << (x - 1))))
+
+
+static int
+my_libassuan_log_handler (assuan_context_t ctx, void *hook,
+                          unsigned int cat, const char *msg)
+{
+  unsigned int dbgval;
+
+  (void)ctx;
+
+  if (! TEST_LOG_CAT (cat))
+    return 0;
+
+  dbgval = hook? *(unsigned int*)hook : 0;
+  if (!(dbgval & 1024))
+    return 0; /* Assuan debugging is not enabled.  */
+
+  if (msg)
+    log_string (JNLIB_LOG_DEBUG, msg);
+
+  return 1;
+}
+
+
+/* Setup libassuan to use our own logging functions.  Should be used
+   early at startup.  */
+void
+setup_libassuan_logging (unsigned int *debug_var_address)
+{
+  char *flagstr;
+
+  flagstr = getenv ("ASSUAN_DEBUG");
+  if (flagstr)
+    log_cats = atoi (flagstr);
+  else /* Default to log the control channel.  */
+    log_cats = (1 << (ASSUAN_LOG_CONTROL - 1));
+  assuan_set_log_cb (my_libassuan_log_handler, debug_var_address);
+}
+
+/* Change the Libassuan log categories to those given by NEWCATS.
+   NEWCATS is 0 the default category of ASSUAN_LOG_CONTROL is
+   selected.  Note, that setup_libassuan_logging overrides the values
+   given here.  */
+void
+set_libassuan_log_cats (unsigned int newcats)
+{
+  if (newcats)
+    log_cats = newcats;
+  else /* Default to log the control channel.  */
+    log_cats = (1 << (ASSUAN_LOG_CONTROL - 1));
+}
+
+
 
 static gpg_error_t
 send_one_option (assuan_context_t ctx, gpg_err_source_t errsource,
@@ -54,7 +133,7 @@ send_one_option (assuan_context_t ctx, gpg_err_source_t errsource,
 
   if (!value || !*value)
     err = 0;  /* Avoid sending empty strings.  */
-  else if (asprintf (&optstr, "OPTION %s%s=%s", 
+  else if (asprintf (&optstr, "OPTION %s%s=%s",
                      use_putenv? "putenv=":"", name, value) < 0)
     err = gpg_error_from_syserror ();
   else
@@ -80,7 +159,7 @@ send_pinentry_environment (assuan_context_t ctx,
 {
   gpg_error_t err = 0;
 #if defined(HAVE_SETLOCALE)
-  char *old_lc = NULL; 
+  char *old_lc = NULL;
 #endif
   char *dft_lc = NULL;
   const char *dft_ttyname;
@@ -88,7 +167,7 @@ send_pinentry_environment (assuan_context_t ctx,
   const char *name, *assname, *value;
   int is_default;
 
-  iterator = 0; 
+  iterator = 0;
   while ((name = session_env_list_stdenvnames (&iterator, &assname)))
     {
       value = session_env_getenv_or_default (session_env, name, NULL);
@@ -108,7 +187,7 @@ send_pinentry_environment (assuan_context_t ctx,
     }
 
 
-  dft_ttyname = session_env_getenv_or_default (session_env, "GPG_TTY", 
+  dft_ttyname = session_env_getenv_or_default (session_env, "GPG_TTY",
                                                &is_default);
   if (dft_ttyname && !is_default)
     dft_ttyname = NULL;  /* We need the default value.  */
@@ -126,7 +205,7 @@ send_pinentry_environment (assuan_context_t ctx,
 #endif
   if (opt_lc_ctype || (dft_ttyname && dft_lc))
     {
-      err = send_one_option (ctx, errsource, "lc-ctype", 
+      err = send_one_option (ctx, errsource, "lc-ctype",
                              opt_lc_ctype ? opt_lc_ctype : dft_lc, 0);
     }
 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
@@ -152,7 +231,7 @@ send_pinentry_environment (assuan_context_t ctx,
 #endif
   if (opt_lc_messages || (dft_ttyname && dft_lc))
     {
-      err = send_one_option (ctx, errsource, "lc-messages", 
+      err = send_one_option (ctx, errsource, "lc-messages",
                              opt_lc_messages ? opt_lc_messages : dft_lc, 0);
     }
 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
@@ -169,51 +248,76 @@ send_pinentry_environment (assuan_context_t ctx,
 }
 
 
-/* Lock the agent spawning process.  The caller needs to provide the
-   address of a variable to store the lock information.  */
+/* Lock a spawning process.  The caller needs to provide the address
+   of a variable to store the lock information and the name or the
+   process.  */
 static gpg_error_t
-lock_agent_spawning (lock_agent_t *lock, const char *homedir)
+lock_spawning (lock_spawn_t *lock, const char *homedir, const char *name,
+               int verbose)
 {
 #ifdef HAVE_W32_SYSTEM
   int waitrc;
+  int timeout = (!strcmp (name, "agent")
+                 ? SECS_TO_WAIT_FOR_AGENT
+                 : SECS_TO_WAIT_FOR_DIRMNGR);
 
   (void)homedir; /* Not required. */
 
-  *lock = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel");
+  *lock = CreateMutexW
+    (NULL, FALSE,
+     !strcmp (name, "agent")?   L"spawn_"GNUPG_NAME"_agent_sentinel":
+     !strcmp (name, "dirmngr")? L"spawn_"GNUPG_NAME"_dirmngr_sentinel":
+     /*                    */   L"spawn_"GNUPG_NAME"_unknown_sentinel");
   if (!*lock)
     {
-      log_error ("failed to create the spawn_agent mutex: %s\n",
-                 w32_strerror (-1));
+      log_error ("failed to create the spawn_%s mutex: %s\n",
+                 name, w32_strerror (-1));
       return gpg_error (GPG_ERR_GENERAL);
     }
 
-  waitrc = WaitForSingleObject (*lock, 5000);
+ retry:
+  waitrc = WaitForSingleObject (*lock, 1000);
   if (waitrc == WAIT_OBJECT_0)
     return 0;
 
+  if (waitrc == WAIT_TIMEOUT && timeout)
+    {
+      timeout--;
+      if (verbose)
+        log_info ("another process is trying to start the %s ... (%ds)\n",
+                  name, timeout);
+      goto retry;
+    }
   if (waitrc == WAIT_TIMEOUT)
-    log_info ("error waiting for the spawn_agent mutex: timeout\n");
+    log_info ("error waiting for the spawn_%s mutex: timeout\n", name);
   else
-    log_info ("error waiting for the spawn_agent mutex: "
-              "(code=%d) %s\n", waitrc, w32_strerror (-1));
+    log_info ("error waiting for the spawn_%s mutex: (code=%d) %s\n",
+              name, waitrc, w32_strerror (-1));
   return gpg_error (GPG_ERR_GENERAL);
 #else /*!HAVE_W32_SYSTEM*/
   char *fname;
 
+  (void)verbose;
+
   *lock = NULL;
 
-  fname = make_filename (homedir, "gnupg_spawn_agent_sentinel", NULL);
+  fname = make_absfilename_try
+    (homedir,
+     !strcmp (name, "agent")?   "gnupg_spawn_agent_sentinel":
+     !strcmp (name, "dirmngr")? "gnupg_spawn_dirmngr_sentinel":
+     /*                    */   "gnupg_spawn_unknown_sentinel",
+     NULL);
   if (!fname)
     return gpg_error_from_syserror ();
 
-  *lock = create_dotlock (fname);
+  *lock = dotlock_create (fname, 0);
   xfree (fname);
   if (!*lock)
     return gpg_error_from_syserror ();
 
   /* FIXME: We should use a timeout of 5000 here - however
      make_dotlock does not yet support values other than -1 and 0.  */
-  if (make_dotlock (*lock, -1))
+  if (dotlock_take (*lock, -1))
     return gpg_error_from_syserror ();
 
   return 0;
@@ -223,23 +327,23 @@ lock_agent_spawning (lock_agent_t *lock, const char *homedir)
 
 /* Unlock the spawning process.  */
 static void
-unlock_agent_spawning (lock_agent_t *lock)
+unlock_spawning (lock_spawn_t *lock, const char *name)
 {
   if (*lock)
     {
 #ifdef HAVE_W32_SYSTEM
       if (!ReleaseMutex (*lock))
-        log_error ("failed to release the spawn_agent mutex: %s\n",
-                   w32_strerror (-1));
+        log_error ("failed to release the spawn_%s mutex: %s\n",
+                   name, w32_strerror (-1));
       CloseHandle (*lock);
 #else /*!HAVE_W32_SYSTEM*/
-      destroy_dotlock (*lock);
+      (void)name;
+      dotlock_destroy (*lock);
 #endif /*!HAVE_W32_SYSTEM*/
       *lock = NULL;
     }
 }
 
-
 /* Try to connect to the agent via socket or fork it off and work by
    pipes.  Handle the server's initial greeting.  Returns a new assuan
    context at R_CTX or an error code. */
@@ -255,13 +359,11 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
                      gpg_error_t (*status_cb)(ctrl_t, int, ...),
                      ctrl_t status_cb_arg)
 {
-  /* If we ever failed to connect via a socket we will force the use
-     of the pipe based server for the lifetime of the process.  */
-  static int force_pipe_server = 0;
-
-  gpg_error_t err = 0;
-  char *infostr, *p;
+  gpg_error_t err;
   assuan_context_t ctx;
+  int did_success_msg = 0;
+  char *sockname;
+  const char *argv[6];
 
   *r_ctx = NULL;
 
@@ -272,179 +374,137 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
       return err;
     }
 
- restart:
-  infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO");
-  if (!infostr || !*infostr)
+  sockname = make_absfilename (homedir, GPG_AGENT_SOCK_NAME, NULL);
+  err = assuan_socket_connect (ctx, sockname, 0, 0);
+  if (err)
     {
-      char *sockname;
-      const char *argv[3];
-      pid_t pid;
-      int excode;
-
-      /* First check whether we can connect at the standard
-         socket.  */
-      sockname = make_filename (homedir, "S.gpg-agent", NULL);
-      err = assuan_socket_connect (ctx, sockname, 0, 0);
-
-      if (err)
+      char *abs_homedir;
+      lock_spawn_t lock;
+      char *program = NULL;
+      const char *program_arg = NULL;
+      char *p;
+      const char *s;
+      int i;
+
+      /* With no success start a new server.  */
+      if (!agent_program || !*agent_program)
+        agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
+      else if ((s=strchr (agent_program, '|')) && s[1] == '-' && s[2]=='-')
         {
-          /* With no success start a new server.  */
-          if (verbose)
-            log_info (_("no running gpg-agent - starting one\n"));
-          
-          if (status_cb)
-            status_cb (status_cb_arg, STATUS_PROGRESS, 
-                       "starting_agent ? 0 0", NULL);
-          
-          if (fflush (NULL))
+          /* Hack to insert an additional option on the command line.  */
+          program = xtrystrdup (agent_program);
+          if (!program)
             {
-              gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
-              log_error ("error flushing pending output: %s\n",
-                         strerror (errno));
+              gpg_error_t tmperr = gpg_err_make (errsource,
+                                                 gpg_err_code_from_syserror ());
               xfree (sockname);
-             assuan_release (ctx);
+              assuan_release (ctx);
               return tmperr;
             }
-          
-          if (!agent_program || !*agent_program)
-            agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
+          p = strchr (program, '|');
+          *p++ = 0;
+          program_arg = p;
+        }
+
+      if (verbose)
+        log_info (_("no running gpg-agent - starting '%s'\n"),
+                  agent_program);
+
+      if (status_cb)
+        status_cb (status_cb_arg, STATUS_PROGRESS,
+                   "starting_agent ? 0 0", NULL);
+
+      /* We better pass an absolute home directory to the agent just
+         in case gpg-agent does not convert the passed name to an
+         absolute one (which it should do).  */
+      abs_homedir = make_absfilename_try (homedir, NULL);
+      if (!abs_homedir)
+        {
+          gpg_error_t tmperr = gpg_err_make (errsource,
+                                             gpg_err_code_from_syserror ());
+          log_error ("error building filename: %s\n",gpg_strerror (tmperr));
+          xfree (sockname);
+          assuan_release (ctx);
+          xfree (program);
+          return tmperr;
+        }
 
-          argv[0] = "--use-standard-socket-p"; 
-          argv[1] = NULL;  
-          err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid);
+      if (fflush (NULL))
+        {
+          gpg_error_t tmperr = gpg_err_make (errsource,
+                                             gpg_err_code_from_syserror ());
+          log_error ("error flushing pending output: %s\n",
+                     strerror (errno));
+          xfree (sockname);
+          assuan_release (ctx);
+          xfree (abs_homedir);
+          xfree (program);
+          return tmperr;
+        }
+
+      /* If the agent has been configured for use with a standard
+         socket, an environment variable is not required and thus
+         we we can savely start the agent here.  */
+      i = 0;
+      argv[i++] = "--homedir";
+      argv[i++] = abs_homedir;
+      argv[i++] = "--use-standard-socket";
+      if (program_arg)
+        argv[i++] = program_arg;
+      argv[i++] = "--daemon";
+      argv[i++] = NULL;
+
+      if (!(err = lock_spawning (&lock, homedir, "agent", verbose))
+          && assuan_socket_connect (ctx, sockname, 0, 0))
+        {
+          err = gnupg_spawn_process_detached (program? program : agent_program,
+                                              argv, NULL);
           if (err)
-            log_debug ("starting `%s' for testing failed: %s\n",
+            log_error ("failed to start agent '%s': %s\n",
                        agent_program, gpg_strerror (err));
-          else if ((err = gnupg_wait_process (agent_program, pid, &excode)))
-            {
-              if (excode == -1)
-                log_debug ("running `%s' for testing failed: %s\n",
-                           agent_program, gpg_strerror (err));
-            }          
-
-          if (!err && !excode)
+          else
             {
-              /* If the agent has been configured for use with a
-                 standard socket, an environment variable is not
-                 required and thus we we can savely start the agent
-                 here.  */
-              lock_agent_t lock;
-
-              argv[0] = "--daemon";
-              argv[1] = "--use-standard-socket"; 
-              argv[2] = NULL;  
-
-              if (!(err = lock_agent_spawning (&lock, homedir))
-                  && assuan_socket_connect (ctx, sockname, 0, 0))
+              for (i=0; i < SECS_TO_WAIT_FOR_AGENT; i++)
                 {
-                  err = gnupg_spawn_process_detached (agent_program, argv,NULL);
-                  if (err)
-                    log_error ("failed to start agent `%s': %s\n",
-                               agent_program, gpg_strerror (err));
-                  else
+                  if (verbose)
+                    log_info (_("waiting for the agent to come up ... (%ds)\n"),
+                              SECS_TO_WAIT_FOR_AGENT - i);
+                  gnupg_sleep (1);
+                  err = assuan_socket_connect (ctx, sockname, 0, 0);
+                  if (!err)
                     {
-                      int i;
-
                       if (verbose)
-                        log_info (_("waiting %d seconds for the agent "
-                                    "to come up\n"), 5);
-                      for (i=0; i < 5; i++)
                         {
-                          gnupg_sleep (1);
-                          err = assuan_socket_connect (ctx, sockname, 0, 0);
-                          if (!err)
-                            break;
+                          log_info (_("connection to agent established\n"));
+                          did_success_msg = 1;
                         }
+                      break;
                     }
                 }
-
-              unlock_agent_spawning (&lock);
-            }
-          else
-            {
-              /* If using the standard socket is not the default we
-                 start the agent as a pipe server which gives us most
-                 of the required features except for passphrase
-                 caching etc.  */
-              const char *pgmname;
-              int no_close_list[3];
-              int i;
-              
-              if ( !(pgmname = strrchr (agent_program, '/')))
-                pgmname = agent_program;
-              else
-                pgmname++;
-              
-              argv[0] = pgmname;
-              argv[1] = "--server";
-              argv[2] = NULL;
-              
-              i=0;
-              if (log_get_fd () != -1)
-                no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
-              no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
-              no_close_list[i] = -1;
-              
-              /* Connect to the agent and perform initial handshaking. */
-              err = assuan_pipe_connect (ctx, agent_program, argv,
-                                         no_close_list, NULL, NULL, 0);
             }
         }
-      xfree (sockname);
-    }
-  else
-    {
-      int prot;
-      int pid;
 
-      infostr = xstrdup (infostr);
-      if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
-        {
-          log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
-          xfree (infostr);
-          force_pipe_server = 1;
-          goto restart;
-        }
-      *p++ = 0;
-      pid = atoi (p);
-      while (*p && *p != PATHSEP_C)
-        p++;
-      prot = *p? atoi (p+1) : 0;
-      if (prot != 1)
-        {
-          log_error (_("gpg-agent protocol version %d is not supported\n"),
-                     prot);
-          xfree (infostr);
-          force_pipe_server = 1;
-          goto restart;
-        }
-
-      err = assuan_socket_connect (ctx, infostr, pid, 0);
-      xfree (infostr);
-      if (gpg_err_code (err) == GPG_ERR_ASS_CONNECT_FAILED)
-        {
-          log_info (_("can't connect to the agent - trying fall back\n"));
-          force_pipe_server = 1;
-          goto restart;
-        }
+      unlock_spawning (&lock, "agent");
+      xfree (abs_homedir);
+      xfree (program);
     }
-
+  xfree (sockname);
   if (err)
     {
       log_error ("can't connect to the agent: %s\n", gpg_strerror (err));
       assuan_release (ctx);
-      return gpg_error (GPG_ERR_NO_AGENT);
+      return gpg_err_make (errsource, GPG_ERR_NO_AGENT);
     }
 
-  if (debug)
-    log_debug ("connection to agent established\n");
+  if (debug && !did_success_msg)
+    log_debug (_("connection to agent established\n"));
 
   err = assuan_transact (ctx, "RESET",
-                        NULL, NULL, NULL, NULL, NULL, NULL);
+                         NULL, NULL, NULL, NULL, NULL, NULL);
   if (!err)
     err = send_pinentry_environment (ctx, errsource,
-                                    opt_lc_ctype, opt_lc_messages,
-                                    session_env);
+                                     opt_lc_ctype, opt_lc_messages,
+                                     session_env);
   if (err)
     {
       assuan_release (ctx);
@@ -455,3 +515,170 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
   return 0;
 }
 
+
+/* Try to connect to the dirmngr via a socket.  On platforms
+   supporting it, start it up if needed.  Returns a new assuan context
+   at R_CTX or an error code. */
+gpg_error_t
+start_new_dirmngr (assuan_context_t *r_ctx,
+                   gpg_err_source_t errsource,
+                   const char *homedir,
+                   const char *dirmngr_program,
+                   int verbose, int debug,
+                   gpg_error_t (*status_cb)(ctrl_t, int, ...),
+                   ctrl_t status_cb_arg)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  const char *sockname;
+  int did_success_msg = 0;
+
+  *r_ctx = NULL;
+
+  err = assuan_new (&ctx);
+  if (err)
+    {
+      log_error ("error allocating assuan context: %s\n", gpg_strerror (err));
+      return err;
+    }
+
+  sockname = dirmngr_user_socket_name ();
+  if (sockname)
+    {
+      /* First try the local socket name and only if that fails try
+         the system socket.  */
+      err = assuan_socket_connect (ctx, sockname, 0, 0);
+      if (err)
+        sockname = dirmngr_sys_socket_name ();
+    }
+  else
+    sockname = dirmngr_sys_socket_name ();
+
+  err = assuan_socket_connect (ctx, sockname, 0, 0);
+
+#ifdef USE_DIRMNGR_AUTO_START
+  if (err)
+    {
+      lock_spawn_t lock;
+      const char *argv[4];
+      int try_system_daemon = 0;
+      char *abs_homedir;
+
+      /* No connection: Try start a new Dirmngr.  On Windows this will
+         fail because the Dirmngr is expected to be a system service.
+         However on WinCE we don't distinguish users and thus we can
+         start it.  */
+
+      /* We prefer to start it as a user daemon.  */
+      sockname = dirmngr_user_socket_name ();
+      if (!sockname)
+        {
+          sockname = dirmngr_sys_socket_name ();
+          try_system_daemon = 1;
+        }
+
+      if (!dirmngr_program || !*dirmngr_program)
+        dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
+
+      if (verbose)
+        log_info (_("no running Dirmngr - starting '%s'\n"),
+                  dirmngr_program);
+
+      if (status_cb)
+        status_cb (status_cb_arg, STATUS_PROGRESS,
+                   "starting_dirmngr ? 0 0", NULL);
+
+      abs_homedir = make_absfilename (homedir, NULL);
+      if (!abs_homedir)
+        {
+          gpg_error_t tmperr = gpg_err_make (errsource,
+                                             gpg_err_code_from_syserror ());
+          log_error ("error building filename: %s\n",gpg_strerror (tmperr));
+          assuan_release (ctx);
+          return tmperr;
+        }
+
+      if (fflush (NULL))
+        {
+          gpg_error_t tmperr = gpg_err_make (errsource,
+                                             gpg_err_code_from_syserror ());
+          log_error ("error flushing pending output: %s\n",
+                     strerror (errno));
+          assuan_release (ctx);
+          return tmperr;
+        }
+
+      argv[0] = "--daemon";
+      if (try_system_daemon)
+        argv[1] = NULL;
+      else
+        { /* Try starting as user daemon - dirmngr does this if the
+             home directory is given on the command line.  */
+          argv[1] = "--homedir";
+          argv[2] = abs_homedir;
+          argv[3] = NULL;
+        }
+
+      /* On the use of HOMEDIR for locking: Under Windows HOMEDIR is
+         not used thus it does not matter.  Under Unix we should
+         TRY_SYSTEM_DAEMON should never be true because
+         dirmngr_user_socket_name() won't return NULL.  */
+
+      if (!(err = lock_spawning (&lock, homedir, "dirmngr", verbose))
+          && assuan_socket_connect (ctx, sockname, 0, 0))
+        {
+          err = gnupg_spawn_process_detached (dirmngr_program, argv, NULL);
+          if (err)
+            log_error ("failed to start the dirmngr '%s': %s\n",
+                       dirmngr_program, gpg_strerror (err));
+          else
+            {
+              int i;
+
+              for (i=0; i < SECS_TO_WAIT_FOR_DIRMNGR; i++)
+                {
+                  if (verbose)
+                    log_info (_("waiting for the dirmngr "
+                                "to come up ... (%ds)\n"),
+                              SECS_TO_WAIT_FOR_DIRMNGR - i);
+                  gnupg_sleep (1);
+                  err = assuan_socket_connect (ctx, sockname, 0, 0);
+                  if (!err)
+                    {
+                      if (verbose)
+                        {
+                          log_info (_("connection to the dirmngr"
+                                      " established\n"));
+                          did_success_msg = 1;
+                        }
+                      break;
+                    }
+                }
+            }
+        }
+
+      unlock_spawning (&lock, "dirmngr");
+      xfree (abs_homedir);
+    }
+#else
+  (void)homedir;
+  (void)dirmngr_program;
+  (void)verbose;
+  (void)status_cb;
+  (void)status_cb_arg;
+#endif /*USE_DIRMNGR_AUTO_START*/
+
+  if (err)
+    {
+      log_error ("connecting dirmngr at '%s' failed: %s\n",
+                 sockname, gpg_strerror (err));
+      assuan_release (ctx);
+      return gpg_err_make (errsource, GPG_ERR_NO_DIRMNGR);
+    }
+
+  if (debug && !did_success_msg)
+    log_debug (_("connection to the dirmngr established\n"));
+
+  *r_ctx = ctx;
+  return 0;
+}
index f7bc88b..08c3c8c 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 
 #include "session-env.h"
 
+/*-- asshelp.c --*/
+
+void setup_libassuan_logging (unsigned int *debug_var_address);
+void set_libassuan_log_cats (unsigned int newcats);
+
+
 gpg_error_t
 send_pinentry_environment (assuan_context_t ctx,
                            gpg_err_source_t errsource,
@@ -32,7 +48,7 @@ send_pinentry_environment (assuan_context_t ctx,
                            const char *opt_lc_messages,
                            session_env_t session_env);
 
-/* This fucntion is used by the call-agent.c modules to fire up a new
+/* This function is used by the call-agent.c modules to fire up a new
    agent.  */
 gpg_error_t
 start_new_gpg_agent (assuan_context_t *r_ctx,
@@ -46,5 +62,30 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
                      gpg_error_t (*status_cb)(ctrl_t, int, ...),
                      ctrl_t status_cb_arg);
 
+/* This function is used to connect to the dirmngr.  On some platforms
+   the function is able starts a dirmngr process if needed.  */
+gpg_error_t
+start_new_dirmngr (assuan_context_t *r_ctx,
+                   gpg_err_source_t errsource,
+                   const char *homedir,
+                   const char *dirmngr_program,
+                   int verbose, int debug,
+                   gpg_error_t (*status_cb)(ctrl_t, int, ...),
+                   ctrl_t status_cb_arg);
+
+
+/*-- asshelp2.c --*/
+
+/* Helper function to print an assuan status line using a printf
+   format string.  */
+gpg_error_t print_assuan_status (assuan_context_t ctx,
+                                 const char *keyword,
+                                 const char *format,
+                                 ...) JNLIB_GCC_A_PRINTF(3,4);
+gpg_error_t vprint_assuan_status (assuan_context_t ctx,
+                                  const char *keyword,
+                                  const char *format,
+                                  va_list arg_ptr) JNLIB_GCC_A_PRINTF(3,0);
+
 
 #endif /*GNUPG_COMMON_ASSHELP_H*/
diff --git a/common/asshelp2.c b/common/asshelp2.c
new file mode 100644 (file)
index 0000000..0a70d2b
--- /dev/null
@@ -0,0 +1,73 @@
+/* asshelp2.c - More helper functions for Assuan
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assuan.h>
+
+#include "util.h"
+#include "asshelp.h"
+
+/* Helper function to print an assuan status line using a printf
+   format string.  */
+gpg_error_t
+vprint_assuan_status (assuan_context_t ctx,
+                      const char *keyword,
+                      const char *format, va_list arg_ptr)
+{
+  int rc;
+  char *buf;
+
+  rc = gpgrt_vasprintf (&buf, format, arg_ptr);
+  if (rc < 0)
+    return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+  rc = assuan_write_status (ctx, keyword, buf);
+  xfree (buf);
+  return rc;
+}
+
+
+/* Helper function to print an assuan status line using a printf
+   format string.  */
+gpg_error_t
+print_assuan_status (assuan_context_t ctx,
+                     const char *keyword,
+                     const char *format, ...)
+{
+  va_list arg_ptr;
+  gpg_error_t err;
+
+  va_start (arg_ptr, format);
+  err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
+  va_end (arg_ptr);
+  return err;
+}
index 02a0a2b..875e595 100644 (file)
@@ -57,7 +57,7 @@ struct audit_ctx_s
 {
   const char *failure;  /* If set a description of the internal failure.  */
   audit_type_t type;
-  
+
   log_item_t log;       /* The table with the log entries.  */
   size_t logsize;       /* The allocated size for LOG.  */
   size_t logused;       /* The used size of LOG.  */
@@ -71,17 +71,17 @@ struct audit_ctx_s
 
 
 \f
-static void writeout_para (audit_ctx_t ctx, 
+static void writeout_para (audit_ctx_t ctx,
                            const char *format, ...) JNLIB_GCC_A_PRINTF(2,3);
 static void writeout_li (audit_ctx_t ctx, const char *oktext,
                          const char *format, ...) JNLIB_GCC_A_PRINTF(3,4);
-static void writeout_rem (audit_ctx_t ctx, 
+static void writeout_rem (audit_ctx_t ctx,
                           const char *format, ...) JNLIB_GCC_A_PRINTF(2,3);
 
 
 /* Add NAME to the list of help tags.  NAME needs to be a const string
    an this function merly stores this pointer.  */
-static void 
+static void
 add_helptag (audit_ctx_t ctx, const char *name)
 {
   helptag_t item;
@@ -127,7 +127,7 @@ event2str (audit_event_t event)
 
 
 /* Create a new audit context.  In case of an error NULL is returned
-   and errno set appropriately. */ 
+   and errno set appropriately. */
 audit_ctx_t
 audit_new (void)
 {
@@ -228,7 +228,7 @@ create_log_item (audit_ctx_t ctx)
   item->cert = NULL;
 
   return item;
+
 }
 
 /* Add a new event to the audit log.  If CTX is NULL, this function
@@ -329,7 +329,7 @@ audit_log_s (audit_ctx_t ctx, audit_event_t event, const char *value)
    does nothing.  This version also adds the certificate CERT and the
    result of an operation to the log.  */
 void
-audit_log_cert (audit_ctx_t ctx, audit_event_t event, 
+audit_log_cert (audit_ctx_t ctx, audit_event_t event,
                 ksba_cert_t cert, gpg_error_t err)
 {
   log_item_t item;
@@ -348,14 +348,14 @@ audit_log_cert (audit_ctx_t ctx, audit_event_t event,
   item->have_err = 1;
   if (cert)
     {
-      ksba_cert_ref (cert); 
+      ksba_cert_ref (cert);
       item->cert = cert;
     }
 }
 
 
 /* Write TEXT to the outstream.  */
-static void 
+static void
 writeout (audit_ctx_t ctx, const char *text)
 {
   if (ctx->use_html)
@@ -376,12 +376,12 @@ writeout (audit_ctx_t ctx, const char *text)
 
 
 /* Write TEXT to the outstream using a variable argument list.  */
-static void 
+static void
 writeout_v (audit_ctx_t ctx, const char *format, va_list arg_ptr)
 {
   char *buf;
 
-  estream_vasprintf (&buf, format, arg_ptr);
+  gpgrt_vasprintf (&buf, format, arg_ptr);
   if (buf)
     {
       writeout (ctx, buf);
@@ -440,7 +440,7 @@ leave_li (audit_ctx_t ctx)
     }
 }
 
-  
+
 /* Write TEXT as a list element.  If OKTEXT is not NULL, append it to
    the last line. */
 static void
@@ -451,7 +451,7 @@ writeout_li (audit_ctx_t ctx, const char *oktext, const char *format, ...)
 
   if (ctx->use_html && format && oktext)
     {
-      if (!strcmp (oktext, "Yes") 
+      if (!strcmp (oktext, "Yes")
           || !strcmp (oktext, "good") )
         color = "green";
       else if (!strcmp (oktext, "No")
@@ -530,13 +530,13 @@ writeout_li (audit_ctx_t ctx, const char *oktext, const char *format, ...)
           if (color)
             es_fprintf (ctx->outstream, "<font color=\"%s\">", color);
         }
-      else  
+      else
         writeout (ctx, ":         ");
       writeout (ctx, oktext);
       if (color)
         es_fputs ("</font>", ctx->outstream);
     }
-  
+
   if (ctx->use_html)
     es_fputs ("</td></tr>\n", ctx->outstream);
   else
@@ -579,7 +579,7 @@ writeout_rem (audit_ctx_t ctx, const char *format, ...)
    look behind that event in the log. If STARTITEM is not NULL start
    search _after_that item.  */
 static log_item_t
-find_next_log_item (audit_ctx_t ctx, log_item_t startitem, 
+find_next_log_item (audit_ctx_t ctx, log_item_t startitem,
                     audit_event_t event, audit_event_t stopevent)
 {
   int idx;
@@ -725,9 +725,9 @@ list_certchain (audit_ctx_t ctx, log_item_t startitem, audit_event_t stopevent)
   startitem = find_next_log_item (ctx, startitem, AUDIT_CHAIN_BEGIN,stopevent);
   writeout_li (ctx, startitem? "Yes":"No", _("Certificate chain available"));
   if (!startitem)
-    return; 
+    return;
 
-  item = find_next_log_item (ctx, startitem, 
+  item = find_next_log_item (ctx, startitem,
                              AUDIT_CHAIN_ROOTCERT, AUDIT_CHAIN_END);
   if (!item)
     writeout_rem (ctx, "%s", _("root certificate missing"));
@@ -736,7 +736,7 @@ list_certchain (audit_ctx_t ctx, log_item_t startitem, audit_event_t stopevent)
       list_cert (ctx, item->cert, 0);
     }
   item = startitem;
-  while ( ((item = find_next_log_item (ctx, item, 
+  while ( ((item = find_next_log_item (ctx, item,
                                        AUDIT_CHAIN_CERT, AUDIT_CHAIN_END))))
     {
       list_cert (ctx, item->cert, 1);
@@ -769,7 +769,7 @@ proc_type_encrypt (audit_ctx_t ctx)
     {
       algo = gcry_cipher_map_name (item->string);
       if (algo)
-        writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo));
+        writeout_rem (ctx, _("algorithm: %s"), gnupg_cipher_algo_name (algo));
       else if (item->string && !strcmp (item->string, "1.2.840.113549.3.2"))
         writeout_rem (ctx, _("unsupported algorithm: %s"), "RC2");
       else if (item->string)
@@ -779,7 +779,7 @@ proc_type_encrypt (audit_ctx_t ctx)
     }
 
   item = find_log_item (ctx, AUDIT_GOT_RECIPIENTS, 0);
-  snprintf (numbuf, sizeof numbuf, "%d", 
+  snprintf (numbuf, sizeof numbuf, "%d",
             item && item->have_intvalue? item->intvalue : 0);
   writeout_li (ctx, numbuf, "%s", _("Number of recipients"));
 
@@ -830,7 +830,7 @@ proc_type_sign (audit_ctx_t ctx)
   writeout_li (ctx, item? "Yes":"No", "%s", _("Data available"));
   /* Write remarks with the data hash algorithms.  We use a very
      simple scheme to avoid some duplicates.  */
-  loopitem = NULL; 
+  loopitem = NULL;
   lastalgo = 0;
   while ((loopitem = find_next_log_item
           (ctx, loopitem, AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG)))
@@ -909,14 +909,14 @@ proc_type_decrypt (audit_ctx_t ctx)
   algo = item? item->intvalue : 0;
   writeout_li (ctx, algo?"Yes":"No", "%s", _("Encryption algorithm supported"));
   if (algo)
-    writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo));
+    writeout_rem (ctx, _("algorithm: %s"), gnupg_cipher_algo_name (algo));
 
   item = find_log_item (ctx, AUDIT_BAD_DATA_CIPHER_ALGO, 0);
   if (item && item->string)
     {
       algo = gcry_cipher_map_name (item->string);
       if (algo)
-        writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo));
+        writeout_rem (ctx, _("algorithm: %s"), gnupg_cipher_algo_name (algo));
       else if (item->string && !strcmp (item->string, "1.2.840.113549.3.2"))
         writeout_rem (ctx, _("unsupported algorithm: %s"), "RC2");
       else if (item->string)
@@ -1033,7 +1033,7 @@ proc_type_verify (audit_ctx_t ctx)
             writeout_rem (ctx, _("data hash algorithm: %s"),
                           gcry_md_algo_name (item->intvalue));
           else if (item->event == AUDIT_BAD_DATA_HASH_ALGO)
-            writeout_rem (ctx, _("bad data hash algorithm: %s"), 
+            writeout_rem (ctx, _("bad data hash algorithm: %s"),
                           item->string? item->string:"?");
         }
     }
@@ -1066,7 +1066,7 @@ proc_type_verify (audit_ctx_t ctx)
                       gcry_md_algo_name (item->intvalue));
 
       enter_li (ctx);
-      
+
       /* List the certificate chain.  */
       list_certchain (ctx, loopitem, AUDIT_NEW_SIG);
 
@@ -1075,12 +1075,12 @@ proc_type_verify (audit_ctx_t ctx)
                                  AUDIT_CHAIN_STATUS, AUDIT_NEW_SIG);
       if (item && item->have_err)
         {
-          writeout_li (ctx, item->err? "No":"Yes", 
+          writeout_li (ctx, item->err? "No":"Yes",
                        _("Certificate chain valid"));
           if (item->err)
             writeout_rem (ctx, "%s", gpg_strerror (item->err));
         }
-      
+
       /* Show whether the root certificate is fine.  */
       item = find_next_log_item (ctx, loopitem,
                                  AUDIT_ROOT_TRUSTED, AUDIT_CHAIN_STATUS);
@@ -1115,9 +1115,9 @@ proc_type_verify (audit_ctx_t ctx)
               break;
             default: ok = gpg_strerror (item->err); break;
             }
-            
+
           writeout_li (ctx, ok, "%s", _("CRL/OCSP check of certificates"));
-          if (item->err 
+          if (item->err
               && gpg_err_code (item->err) != GPG_ERR_CERT_REVOKED
               && gpg_err_code (item->err) != GPG_ERR_NOT_ENABLED)
             add_helptag (ctx, "gpgsm.crl-problem");
@@ -1132,13 +1132,13 @@ proc_type_verify (audit_ctx_t ctx)
   /* Always list the certificates stored in the signature.  */
   item = NULL;
   count = 0;
-  while ( ((item = find_next_log_item (ctx, item, 
+  while ( ((item = find_next_log_item (ctx, item,
                                        AUDIT_SAVE_CERT, AUDIT_NEW_SIG))))
     count++;
   snprintf (numbuf, sizeof numbuf, "%d", count);
   writeout_li (ctx, numbuf, _("Included certificates"));
   item = NULL;
-  while ( ((item = find_next_log_item (ctx, item, 
+  while ( ((item = find_next_log_item (ctx, item,
                                        AUDIT_SAVE_CERT, AUDIT_NEW_SIG))))
     {
       char *name = get_cert_name (item->cert);
@@ -1169,7 +1169,7 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
   const char *s;
   int show_raw = 0;
   char *orig_codeset;
-  
+
   if (!ctx)
     return;
 
@@ -1187,7 +1187,7 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
   clear_helptags (ctx);
 
   if (use_html)
-    es_fputs ("<div class=\"GnuPGAuditLog\">\n", ctx->outstream);
+    es_fputs ("<div class=\"" GNUPG_NAME "AuditLog\">\n", ctx->outstream);
 
   if (!ctx->log || !ctx->logused)
     {
@@ -1201,31 +1201,31 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
 
       for (idx=0,maxlen=0; idx < DIM (eventstr_msgidx); idx++)
         {
-          n = strlen (eventstr_msgstr + eventstr_msgidx[idx]);    
+          n = strlen (eventstr_msgstr + eventstr_msgidx[idx]);
           if (n > maxlen)
             maxlen = n;
         }
-      
+
       if (use_html)
         es_fputs ("<pre>\n", out);
       for (idx=0; idx < ctx->logused; idx++)
         {
-          es_fprintf (out, "log: %-*s", 
+          es_fprintf (out, "log: %-*s",
                       maxlen, event2str (ctx->log[idx].event));
           if (ctx->log[idx].have_intvalue)
-            es_fprintf (out, " i=%d", ctx->log[idx].intvalue); 
+            es_fprintf (out, " i=%d", ctx->log[idx].intvalue);
           if (ctx->log[idx].string)
             {
-              es_fputs (" s=`", out); 
-              writeout (ctx, ctx->log[idx].string); 
-              es_fputs ("'", out); 
+              es_fputs (" s='", out);
+              writeout (ctx, ctx->log[idx].string);
+              es_fputs ("'", out);
             }
           if (ctx->log[idx].cert)
-            es_fprintf (out, " has_cert"); 
+            es_fprintf (out, " has_cert");
           if (ctx->log[idx].have_err)
             {
-              es_fputs (" err=`", out);
-              writeout (ctx, gpg_strerror (ctx->log[idx].err)); 
+              es_fputs (" err='", out);
+              writeout (ctx, gpg_strerror (ctx->log[idx].err));
               es_fputs ("'", out);
             }
           es_fputs ("\n", out);
@@ -1304,7 +1304,7 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
           xfree (text);
         }
       else
-        writeout_para (ctx, _("No help available for `%s'."), helptag->name);
+        writeout_para (ctx, _("No help available for '%s'."), helptag->name);
       if (use_html && ctx->helptags->next)
         es_fputs ("</li>\n", ctx->outstream);
       if (helptag->next)
@@ -1321,4 +1321,3 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
   clear_helptags (ctx);
   i18n_switchback (orig_codeset);
 }
-
index bc67a2e..345477d 100644 (file)
@@ -22,8 +22,6 @@
 
 #include <ksba.h>
 
-#include "estream.h"
-
 struct audit_ctx_s;
 typedef struct audit_ctx_s *audit_ctx_t;
 
@@ -56,7 +54,7 @@ typedef enum
     /* Indicates whether the gpg-agent is available.  For some
        operations the agent is not required and thus no such event
        will be logged.  */
-    
+
     AUDIT_DIRMNGR_READY,   /* err */
     /* Indicates whether the Dirmngr is available.  For some
        operations the Dirmngr is not required and thus no such event
@@ -68,6 +66,9 @@ typedef enum
     AUDIT_GPGSM_READY, /* err */
     /* Indicates whether the Gpgsm engine is available. */
 
+    AUDIT_G13_READY, /* err */
+    /* Indicates whether the G13 engine is available. */
+
     AUDIT_GOT_DATA,
     /* Data to be processed has been seen.  */
 
@@ -112,7 +113,7 @@ typedef enum
     /* The program was used in an inappropriate way; For example by
        passing a data object while the signature does not expect one
        or vice versa.  */
-    
+
     AUDIT_SAVE_CERT,       /* cert, ok_err */
     /* Save the certificate received in a message. */
 
@@ -120,7 +121,7 @@ typedef enum
     /* Start the verification of a new signature for the last data
        object.  The argument is the signature number as used
        internally by the program.  */
-    
+
     AUDIT_SIG_NAME,        /* string */
     /* The name of a signer.  This is the name or other identification
        data as known from the signature and not the name from the
@@ -132,7 +133,7 @@ typedef enum
        audit information for one signature.  STRING gives the status:
 
          "error"       - there was a problem checking this or any signature.
-         "unsupported" - the signature type is not supported. 
+         "unsupported" - the signature type is not supported.
          "no-cert"     - The certificate of the signer was not found (the
                          S/N+issuer of the signer is already in the log).
          "bad"         - bad signature
@@ -142,7 +143,7 @@ typedef enum
     AUDIT_NEW_RECP,        /* int */
     /* A new recipient has been seen during decryption.  The argument
        is the recipient number as used internally by the program.  */
-    
+
     AUDIT_RECP_NAME,       /* string */
     /* The name of a recipient.  This is the name or other identification
        data as known from the decryption and not the name from the
@@ -166,7 +167,7 @@ typedef enum
     AUDIT_CHAIN_END,
     /* These 4 events are used to log the certificates making up a
        certificate chain.  ROOTCERT is used for the trustanchor and
-       CERT for all other certificates.  */ 
+       CERT for all other certificates.  */
 
     AUDIT_CHAIN_STATUS,  /* err */
     /* Tells the final status of the chain validation.  */
@@ -214,7 +215,7 @@ void audit_log (audit_ctx_t ctx, audit_event_t event);
 void audit_log_ok (audit_ctx_t ctx, audit_event_t event, gpg_error_t err);
 void audit_log_i (audit_ctx_t ctx, audit_event_t event, int value);
 void audit_log_s (audit_ctx_t ctx, audit_event_t event, const char *value);
-void audit_log_cert (audit_ctx_t ctx, audit_event_t event, 
+void audit_log_cert (audit_ctx_t ctx, audit_event_t event,
                      ksba_cert_t cert, gpg_error_t err);
 
 void audit_print_result (audit_ctx_t ctx, estream_t stream, int use_html);
index af223ae..3e02e4a 100644 (file)
@@ -1,14 +1,24 @@
 /* b64dec.c - Simple Base64 decoder.
- * Copyright (C) 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2008, 2011 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -29,7 +39,7 @@
 
 
 /* The reverse base-64 list used for base-64 decoding. */
-static unsigned char const asctobin[128] = 
+static unsigned char const asctobin[128] =
   {
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -49,7 +59,7 @@ static unsigned char const asctobin[128] =
     0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
   };
 
-enum decoder_states 
+enum decoder_states
   {
     s_init, s_idle, s_lfseen, s_begin,
     s_b64_0, s_b64_1, s_b64_2, s_b64_3,
@@ -62,7 +72,7 @@ enum decoder_states
    plain base64 decoding is done.  If it is the empty string the
    decoder will skip everything until a "-----BEGIN " line has been
    seen, decoding ends at a "----END " line.
-   
+
    Not yet implemented: If TITLE is either "PGP" or begins with "PGP "
    the PGP armor lines are skipped as well.  */
 gpg_error_t
@@ -72,16 +82,19 @@ b64dec_start (struct b64state *state, const char *title)
   if (title)
     {
       if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' '))
-        return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-
-      state->title = xtrystrdup (title);
-      if (!state->title)
-        return gpg_error_from_syserror ();
-      state->idx = s_init;
+        state->lasterr = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      else
+        {
+          state->title = xtrystrdup (title);
+          if (!state->title)
+            state->lasterr = gpg_error_from_syserror ();
+          else
+            state->idx = s_init;
+        }
     }
   else
     state->idx = s_b64_0;
-  return 0;
+  return state->lasterr;
 }
 
 
@@ -93,13 +106,19 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
 {
   enum decoder_states ds = state->idx;
   unsigned char val = state->radbuf[0];
-  int pos = state->quad_count; 
+  int pos = state->quad_count;
   char *d, *s;
 
+  if (state->lasterr)
+    return state->lasterr;
+
   if (state->stop_seen)
     {
       *r_nbytes = 0;
-      return gpg_error (GPG_ERR_EOF);
+      state->lasterr = gpg_error (GPG_ERR_EOF);
+      xfree (state->title);
+      state->title = NULL;
+      return state->lasterr;
     }
 
   for (s=d=buffer; length && !state->stop_seen; length--, s++)
@@ -134,7 +153,7 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
           {
             int c;
 
-            if (*s == '-' && state->title) 
+            if (*s == '-' && state->title)
               {
                 /* Not a valid Base64 character: assume end
                    header.  */
@@ -149,7 +168,7 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
               }
             else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == '\t')
               ; /* Skip white spaces. */
-            else if ( (*s & 0x80) 
+            else if ( (*s & 0x80)
                       || (c = asctobin[*(unsigned char *)s]) == 255)
               {
                 /* Skip invalid encodings.  */
@@ -189,8 +208,8 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
         case s_waitend:
           if ( *s == '\n')
             state->stop_seen = 1;
-          break; 
-        default: 
+          break;
+        default:
           BUG();
         }
     }
@@ -198,7 +217,7 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
 
   state->idx = ds;
   state->radbuf[0] = val;
-  state->quad_count = pos; 
+  state->quad_count = pos;
   *r_nbytes = (d -(char*) buffer);
   return 0;
 }
@@ -210,8 +229,10 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
 gpg_error_t
 b64dec_finish (struct b64state *state)
 {
+  if (state->lasterr)
+    return state->lasterr;
+
   xfree (state->title);
   state->title = NULL;
   return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0;
 }
-
index 4722bd1..91ba69d 100644 (file)
@@ -1,14 +1,25 @@
 /* b64enc.c - Simple Base64 encoder.
- * Copyright (C) 2001, 2003, 2004, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2008, 2010,
+ *               2011 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #define B64ENC_USE_PGPCRC   32
 
 /* The base-64 character list */
-static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
-                                    "abcdefghijklmnopqrstuvwxyz" 
-                                    "0123456789+/"; 
+static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                    "abcdefghijklmnopqrstuvwxyz"
+                                    "0123456789+/";
 
 /* Stuff required to create the OpenPGP CRC.  This crc_table has been
    created using this code:
 
    #include <stdio.h>
    #include <stdint.h>
-   
+
    #define CRCPOLY 0x864CFB
-   
+
    int
    main (void)
    {
      int i, j;
      uint32_t t;
      uint32_t crc_table[256];
-   
+
      crc_table[0] = 0;
      for (i=j=0; j < 128; j++ )
        {
@@ -69,7 +80,7 @@ static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
              crc_table[i++] = t ^ CRCPOLY;
        }
        }
-   
+
      puts ("static const u32 crc_table[256] = {");
      for (i=j=0; i < 256; i++)
        {
@@ -136,20 +147,14 @@ static const u32 crc_table[256] = {
 };
 
 
-/* Prepare for base-64 writing to the stream FP.  If TITLE is not NULL
-   and not an empty string, this string will be used as the title for
-   the armor lines, with TITLE being an empty string, we don't write
-   the header lines and furthermore even don't write any linefeeds.
-   If TITLE starts with "PGP " the OpenPGP CRC checksum will be
-   written as well.  With TITLE beeing NULL, we merely don't write
-   header but make sure that lines are not too long. Note, that we
-   don't write any output unless at least one byte get written using
-   b64enc_write. */
-gpg_error_t
-b64enc_start (struct b64state *state, FILE *fp, const char *title)
+static gpg_error_t
+enc_start (struct b64state *state, FILE *fp, estream_t stream,
+           const char *title)
 {
   memset (state, 0, sizeof *state);
   state->fp = fp;
+  state->stream = stream;
+  state->lasterr = 0;
   if (title && !*title)
     state->flags |= B64ENC_NO_LINEFEEDS;
   else if (title)
@@ -161,9 +166,42 @@ b64enc_start (struct b64state *state, FILE *fp, const char *title)
         }
       state->title = xtrystrdup (title);
       if (!state->title)
-        return gpg_error_from_syserror ();
+        state->lasterr = gpg_error_from_syserror ();
     }
-  return 0;
+  return state->lasterr;
+}
+
+
+/* Prepare for base-64 writing to the stream FP.  If TITLE is not NULL
+   and not an empty string, this string will be used as the title for
+   the armor lines, with TITLE being an empty string, we don't write
+   the header lines and furthermore even don't write any linefeeds.
+   If TITLE starts with "PGP " the OpenPGP CRC checksum will be
+   written as well.  With TITLE beeing NULL, we merely don't write
+   header but make sure that lines are not too long. Note, that we
+   don't write any output unless at least one byte get written using
+   b64enc_write. */
+gpg_error_t
+b64enc_start (struct b64state *state, FILE *fp, const char *title)
+{
+  return enc_start (state, fp, NULL, title);
+}
+
+/* Same as b64enc_start but takes an estream.  */
+gpg_error_t
+b64enc_start_es (struct b64state *state, estream_t fp, const char *title)
+{
+  return enc_start (state, NULL, fp, title);
+}
+
+
+static int
+my_fputs (const char *string, struct b64state *state)
+{
+  if (state->stream)
+    return es_fputs (string, state->stream);
+  else
+    return fputs (string, state->fp);
 }
 
 
@@ -176,13 +214,15 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
   unsigned char radbuf[4];
   int idx, quad_count;
   const unsigned char *p;
-  FILE *fp = state->fp;
 
+  if (state->lasterr)
+    return state->lasterr;
 
   if (!nbytes)
     {
-      if (buffer && fflush (fp))
-        goto write_error;
+      if (buffer)
+        if (state->stream? es_fflush (state->stream) : fflush (state->fp))
+          goto write_error;
       return 0;
     }
 
@@ -190,15 +230,15 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
     {
       if (state->title)
         {
-          if ( fputs ("-----BEGIN ", fp) == EOF
-               || fputs (state->title, fp) == EOF
-               || fputs ("-----\n", fp) == EOF)
+          if ( my_fputs ("-----BEGIN ", state) == EOF
+               || my_fputs (state->title, state) == EOF
+               || my_fputs ("-----\n", state) == EOF)
             goto write_error;
-          if ( (state->flags & B64ENC_USE_PGPCRC) 
-               && fputs ("\n", fp) == EOF)
+          if ( (state->flags & B64ENC_USE_PGPCRC)
+               && my_fputs ("\n", state) == EOF)
             goto write_error;
         }
-        
+
       state->flags |= B64ENC_DID_HEADER;
     }
 
@@ -228,16 +268,27 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
           tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
           tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
           tmp[3] = bintoasc[radbuf[2]&077];
-          for (idx=0; idx < 4; idx++)
-            putc (tmp[idx], fp);
-          idx = 0;
-          if (ferror (fp))
-            goto write_error;
-          if (++quad_count >= (64/4)) 
+          if (state->stream)
+            {
+              for (idx=0; idx < 4; idx++)
+                es_putc (tmp[idx], state->stream);
+              idx = 0;
+              if (es_ferror (state->stream))
+                goto write_error;
+            }
+          else
+            {
+              for (idx=0; idx < 4; idx++)
+                putc (tmp[idx], state->fp);
+              idx = 0;
+              if (ferror (state->fp))
+                goto write_error;
+            }
+          if (++quad_count >= (64/4))
             {
               quad_count = 0;
               if (!(state->flags & B64ENC_NO_LINEFEEDS)
-                  && fputs ("\n", fp) == EOF)
+                  && my_fputs ("\n", state) == EOF)
                 goto write_error;
             }
         }
@@ -248,23 +299,31 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
   return 0;
 
  write_error:
-  return gpg_error_from_syserror ();
+  state->lasterr = gpg_error_from_syserror ();
+  if (state->title)
+    {
+      xfree (state->title);
+      state->title = NULL;
+    }
+  return state->lasterr;
 }
 
+
 gpg_error_t
 b64enc_finish (struct b64state *state)
 {
   gpg_error_t err = 0;
   unsigned char radbuf[4];
   int idx, quad_count;
-  FILE *fp;
   char tmp[4];
 
+  if (state->lasterr)
+    return state->lasterr;
+
   if (!(state->flags & B64ENC_DID_HEADER))
     goto cleanup;
 
   /* Flush the base64 encoding */
-  fp = state->fp;
   idx = state->idx;
   quad_count = state->quad_count;
   assert (idx < 4);
@@ -279,23 +338,34 @@ b64enc_finish (struct b64state *state)
           tmp[2] = '=';
           tmp[3] = '=';
         }
-      else 
-        { 
+      else
+        {
           tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
           tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077];
           tmp[3] = '=';
         }
-      for (idx=0; idx < 4; idx++)
-        putc (tmp[idx], fp);
-      idx = 0;
-      if (ferror (fp))
-        goto write_error;
-      
-      if (++quad_count >= (64/4)) 
+      if (state->stream)
+        {
+          for (idx=0; idx < 4; idx++)
+            es_putc (tmp[idx], state->stream);
+          idx = 0;
+          if (es_ferror (state->stream))
+            goto write_error;
+        }
+      else
+        {
+          for (idx=0; idx < 4; idx++)
+            putc (tmp[idx], state->fp);
+          idx = 0;
+          if (ferror (state->fp))
+            goto write_error;
+        }
+
+      if (++quad_count >= (64/4))
         {
           quad_count = 0;
           if (!(state->flags & B64ENC_NO_LINEFEEDS)
-              && fputs ("\n", fp) == EOF)
+              && my_fputs ("\n", state) == EOF)
             goto write_error;
         }
     }
@@ -303,13 +373,13 @@ b64enc_finish (struct b64state *state)
   /* Finish the last line and write the trailer. */
   if (quad_count
       && !(state->flags & B64ENC_NO_LINEFEEDS)
-      && fputs ("\n", fp) == EOF)
+      && my_fputs ("\n", state) == EOF)
     goto write_error;
-  
+
   if ( (state->flags & B64ENC_USE_PGPCRC) )
     {
       /* Write the CRC.  */
-      putc ('=', fp);
+      my_fputs ("=", state);
       radbuf[0] = state->crc >>16;
       radbuf[1] = state->crc >> 8;
       radbuf[2] = state->crc;
@@ -317,20 +387,30 @@ b64enc_finish (struct b64state *state)
       tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
       tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
       tmp[3] = bintoasc[radbuf[2]&077];
-      for (idx=0; idx < 4; idx++)
-        putc (tmp[idx], fp);
-      if (ferror (fp))
-        goto write_error;
+      if (state->stream)
+        {
+          for (idx=0; idx < 4; idx++)
+            es_putc (tmp[idx], state->stream);
+          if (es_ferror (state->stream))
+            goto write_error;
+        }
+      else
+        {
+          for (idx=0; idx < 4; idx++)
+            putc (tmp[idx], state->fp);
+          if (ferror (state->fp))
+            goto write_error;
+        }
       if (!(state->flags & B64ENC_NO_LINEFEEDS)
-          && fputs ("\n", fp) == EOF)
+          && my_fputs ("\n", state) == EOF)
         goto write_error;
     }
 
   if (state->title)
     {
-      if ( fputs ("-----END ", fp) == EOF
-           || fputs (state->title, fp) == EOF
-           || fputs ("-----\n", fp) == EOF)
+      if ( my_fputs ("-----END ", state) == EOF
+           || my_fputs (state->title, state) == EOF
+           || my_fputs ("-----\n", state) == EOF)
         goto write_error;
     }
 
@@ -346,6 +426,7 @@ b64enc_finish (struct b64state *state)
       state->title = NULL;
     }
   state->fp = NULL;
+  state->stream = NULL;
+  state->lasterr = err;
   return err;
 }
-
index d3e8b64..e86ccec 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -106,23 +116,23 @@ do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
 {
   const unsigned char *s;
   char *p;
-  
+
   if (!stringbuf)
     {
       /* Not really correct for with_colon but we don't care about the
          one wasted byte. */
-      size_t n = with_colon? 3:2; 
-      size_t nbytes = n * length + 1; 
-      if (length &&  (nbytes-1) / n != length) 
+      size_t n = with_colon? 3:2;
+      size_t nbytes = n * length + 1;
+      if (length &&  (nbytes-1) / n != length)
         {
-          errno = ENOMEM;
+          gpg_err_set_errno (ENOMEM);
           return NULL;
         }
       stringbuf = xtrymalloc (nbytes);
       if (!stringbuf)
         return NULL;
     }
-  
+
   for (s = buffer, p = stringbuf; length; length--, s++)
     {
       if (with_colon && s != buffer)
@@ -171,7 +181,7 @@ bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
    buffer, the function returns NULL and won't change the existing
    conent of buffer.  In-place conversion is possible as long as
    BUFFER points to HEXSTRING.
-   
+
    If BUFFER is NULL and bufsize is 0 the function scans HEXSTRING but
    does not store anything.  This may be used to find the end of
    hexstring.
@@ -204,7 +214,7 @@ hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen)
     {
       if (count > bufsize)
         return NULL; /* Too long.  */
-      
+
       for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2)
         ((unsigned char*)buffer)[idx++] = xtoi_2 (s);
       if (need_nul)
@@ -232,7 +242,7 @@ hex2str_alloc (const char *hexstring, size_t *r_count)
     {
       if (r_count)
         *r_count = 0;
-      errno = EINVAL;
+      gpg_err_set_errno (EINVAL);
       return NULL;
     }
   if (r_count)
@@ -244,6 +254,3 @@ hex2str_alloc (const char *hexstring, size_t *r_count)
     BUG ();
   return result;
 }
-
-
-
index efdefaf..179bb15 100644 (file)
@@ -1,14 +1,24 @@
-/* dns-cert.c - DNS CERT code
+/* dns-cert.c - DNS CERT code (rfc-4398)
  * Copyright (C) 2005, 2006, 2009 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GNUPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -21,6 +31,9 @@
 #include <sys/types.h>
 #ifdef USE_DNS_CERT
 # ifdef HAVE_W32_SYSTEM
+#  ifdef HAVE_WINSOCK2_H
+#   include <winsock2.h>
+#  endif
 #  include <windows.h>
 # else
 #  include <netinet/in.h>
@@ -37,7 +50,6 @@
 #endif
 
 #include "util.h"
-#include "iobuf.h"
 #include "dns-cert.h"
 
 /* Not every installation has gotten around to supporting CERTs
 #define T_CERT 37
 #endif
 
-/* ADNS has no support for CERT yes. */
+/* ADNS has no support for CERT yet. */
 #define my_adns_r_cert 37
 
 
-
-/* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for
-   IPGP provided.  Note that this fucntion retruns the first CERT
-   found with a supported type; it is expected that only one CERT
-   record is used. */
-int
-get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf,
-              unsigned char **fpr, size_t *fpr_len, char **url)
+/* Certificate types according to RFC-4398.  */
+#define CERTTYPE_PKIX      1 /* X.509 as per PKIX. */
+#define CERTTYPE_SPKI      2 /* SPKI certificate.  */
+#define CERTTYPE_PGP       3 /* OpenPGP packet.  */
+#define CERTTYPE_IPKIX     4 /* The URL of an X.509 data object. */
+#define CERTTYPE_ISPKI     5 /* The URL of an SPKI certificate.  */
+#define CERTTYPE_IPGP      6 /* The fingerprint and URL of an OpenPGP packet.*/
+#define CERTTYPE_ACPKIX    7 /* Attribute Certificate.  */
+#define CERTTYPE_IACPKIX   8 /* The URL of an Attribute Certificate.  */
+#define CERTTYPE_URI     253 /* URI private.  */
+#define CERTTYPE_OID     254 /* OID private.  */
+
+
+/* Returns 0 on success or an error code.  If a PGP CERT record was
+   found, a new estream with that key will be returned at R_KEY and
+   the other return parameters are set to NULL/0.  If an IPGP CERT
+   record was found the fingerprint is stored as an allocated block at
+   R_FPR and its length at R_FPRLEN; an URL is is allocated as a
+   string and returned at R_URL.  Note that this function returns the
+   first CERT found with a supported type; it is expected that only
+   one CERT record is used. */
+gpg_error_t
+get_dns_cert (const char *name, estream_t *r_key,
+              unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
 {
 #ifdef USE_DNS_CERT
 #ifdef USE_ADNS
+  gpg_error_t err;
   adns_state state;
   adns_answer *answer = NULL;
-  int rc;
   unsigned int ctype;
   int count;
 
-  rc = adns_init (&state, adns_if_noerrprint, NULL);
-  if (rc)
+  *r_key = NULL;
+  *r_fpr = NULL;
+  *r_fprlen = 0;
+  *r_url = NULL;
+
+  if (adns_init (&state, adns_if_noerrprint, NULL))
     {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
       log_error ("error initializing adns: %s\n", strerror (errno));
-      return -1;
+      return err;
     }
 
-  rc = adns_synchronous (state, name, (adns_r_unknown | my_adns_r_cert),
-                         adns_qf_quoteok_query, &answer);
-  if (rc)
+  if (adns_synchronous (state, name, (adns_r_unknown | my_adns_r_cert),
+                        adns_qf_quoteok_query, &answer))
     {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
       /* log_error ("DNS query failed: %s\n", strerror (errno)); */
       adns_finish (state);
-      return -1;
+      return err;
     }
-  if (answer->status != adns_s_ok) 
+  if (answer->status != adns_s_ok)
     {
       /* log_error ("DNS query returned an error: %s (%s)\n", */
       /*            adns_strerror (answer->status), */
       /*            adns_errabbrev (answer->status)); */
-      adns_free (answer);
-      adns_finish (state);
-      return 0;
+      err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
+      goto leave;
     }
 
-  for (rc = 0, count=0; !rc && count < answer->nrrs; count++)
+  err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
+  for (count = 0; count < answer->nrrs; count++)
     {
       int datalen = answer->rrs.byteblock[count].len;
       const unsigned char *data = answer->rrs.byteblock[count].data;
@@ -100,243 +133,241 @@ get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf,
       if (datalen < 5)
         continue;  /* Truncated CERT record - skip.  */
 
-      ctype = ((data[0]<<8)|data[1]);
+      ctype = ((data[0] << 8) | data[1]);
       /* (key tag and algorithm fields are not required.) */
       data += 5;
       datalen -= 5;
 
-      if (ctype == 3 && datalen >= 11)
+      if (ctype == CERTTYPE_PGP && datalen >= 11)
         {
           /* CERT type is PGP.  Gpg checks for a minimum length of 11,
              thus we do the same.  */
-          *iobuf = iobuf_temp_with_content ((char*)data, datalen);
-          rc = 1;
+          *r_key = es_fopenmem_init (0, "rwb", data, datalen);
+          if (!*r_key)
+            err = gpg_err_make (default_errsource,
+                                gpg_err_code_from_syserror ());
+          else
+            err = 0;
+          goto leave;
         }
-      else if (ctype == 6 && datalen && datalen < 1023 
-               && datalen >= data[0]+1 && fpr && fpr_len && url)
+      else if (ctype == CERTTYPE_IPGP && datalen && datalen < 1023
+               && datalen >= data[0] + 1 && r_fpr && r_fprlen && r_url)
         {
-          /* CERT type is IPGP.  We made sure tha the data is
-             plausible and that the caller requested the
+          /* CERT type is IPGP.  We made sure that the data is
+             plausible and that the caller requested this
              information.  */
-          *fpr_len = data[0];
-          if (*fpr_len)
+          *r_fprlen = data[0];
+          if (*r_fprlen)
             {
-              *fpr = xmalloc (*fpr_len);
-              memcpy (*fpr, data+1, *fpr_len);
+              *r_fpr = xtrymalloc (*r_fprlen);
+              if (!*r_fpr)
+                {
+                  err = gpg_err_make (default_errsource,
+                                      gpg_err_code_from_syserror ());
+                  goto leave;
+                }
+              memcpy (*r_fpr, data + 1, *r_fprlen);
             }
           else
-            *fpr = NULL;
-              
-          if (datalen > *fpr_len + 1)
+            *r_fpr = NULL;
+
+          if (datalen > *r_fprlen + 1)
             {
-              *url = xmalloc (datalen - (*fpr_len+1) + 1);
-              memcpy (*url, data + (*fpr_len+1), datalen - (*fpr_len+1));
-              (*url)[datalen - (*fpr_len+1)] = '\0';
+              *r_url = xtrymalloc (datalen - (*r_fprlen + 1) + 1);
+              if (!*r_url)
+                {
+                  err = gpg_err_make (default_errsource,
+                                      gpg_err_code_from_syserror ());
+                  xfree (*r_fpr);
+                  *r_fpr = NULL;
+                  goto leave;
+                }
+              memcpy (*r_url,
+                      data + (*r_fprlen + 1), datalen - (*r_fprlen + 1));
+              (*r_url)[datalen - (*r_fprlen + 1)] = '\0';
             }
           else
-            *url = NULL;
-          
-          rc = 2;
+            *r_url = NULL;
+
+          err = 0;
+          goto leave;
         }
     }
-  
+
+ leave:
   adns_free (answer);
   adns_finish (state);
-  return rc;
+  return err;
 
 #else /*!USE_ADNS*/
 
+  gpg_error_t err;
   unsigned char *answer;
-  int r,ret=-1;
+  int r;
   u16 count;
 
-  if(fpr)
-    *fpr=NULL;
+  *r_key = NULL;
+  *r_fpr = NULL;
+  *r_fprlen = 0;
+  *r_url = NULL;
 
-  if(url)
-    *url=NULL;
+  /* Allocate a 64k buffer which is the limit for an DNS response.  */
+  answer = xtrymalloc (65536);
+  if (!answer)
+    return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
 
-  answer=xmalloc(max_size);
+  err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
 
-  r=res_query(name,C_IN,T_CERT,answer,max_size);
+  r = res_query (name, C_IN, T_CERT, answer, 65536);
   /* Not too big, not too small, no errors and at least 1 answer. */
-  if(r>=sizeof(HEADER) && r<=max_size
-     && (((HEADER *)answer)->rcode)==NOERROR
-     && (count=ntohs(((HEADER *)answer)->ancount)))
+  if (r >= sizeof (HEADER) && r <= 65536
+      && (((HEADER *) answer)->rcode) == NOERROR
+      && (count = ntohs (((HEADER *) answer)->ancount)))
     {
       int rc;
-      unsigned char *pt,*emsg;
+      unsigned char *pt, *emsg;
 
-      emsg=&answer[r];
+      emsg = &answer[r];
 
-      pt=&answer[sizeof(HEADER)];
+      pt = &answer[sizeof (HEADER)];
 
       /* Skip over the query */
 
-      rc=dn_skipname(pt,emsg);
-      if(rc==-1)
-       goto fail;
-
-      pt+=rc+QFIXEDSZ;
+      rc = dn_skipname (pt, emsg);
+      if (rc == -1)
+        {
+          err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
+          goto leave;
+        }
+      pt += rc + QFIXEDSZ;
 
       /* There are several possible response types for a CERT request.
-        We're interested in the PGP (a key) and IPGP (a URI) types.
-        Skip all others.  TODO: A key is better than a URI since
-        we've gone through all this bother to fetch it, so favor that
-        if we have both PGP and IPGP? */
-
-      while(count-->0 && pt<emsg)
-       {
-         u16 type,class,dlen,ctype;
-
-         rc=dn_skipname(pt,emsg); /* the name we just queried for */
-         if(rc==-1)
-           break;
-
-         pt+=rc;
-
-         /* Truncated message? 15 bytes takes us to the point where
-            we start looking at the ctype. */
-         if((emsg-pt)<15)
-           break;
-
-         type=*pt++ << 8;
-         type|=*pt++;
-
-         class=*pt++ << 8;
-         class|=*pt++;
-         /* We asked for IN and got something else !? */
-         if(class!=C_IN)
-           break;
-
-         /* ttl */
-         pt+=4;
-
-         /* data length */
-         dlen=*pt++ << 8;
-         dlen|=*pt++;
-
-         /* We asked for CERT and got something else - might be a
-            CNAME, so loop around again. */
-         if(type!=T_CERT)
-           {
-             pt+=dlen;
-             continue;
-           }
-
-         /* The CERT type */
-         ctype=*pt++ << 8;
-         ctype|=*pt++;
-
-         /* Skip the CERT key tag and algo which we don't need. */
-         pt+=3;
-
-         dlen-=5;
-
-         /* 15 bytes takes us to here */
-
-         if(ctype==3 && iobuf && dlen)
-           {
-             /* PGP type */
-             *iobuf=iobuf_temp_with_content((char *)pt,dlen);
-             ret=1;
-             break;
-           }
-         else if(ctype==6 && dlen && dlen<1023 && dlen>=pt[0]+1
-                 && fpr && fpr_len && url)
-           {
-             /* IPGP type */
-             *fpr_len=pt[0];
-
-             if(*fpr_len)
-               {
-                 *fpr=xmalloc(*fpr_len);
-                 memcpy(*fpr,&pt[1],*fpr_len);
-               }
-             else
-               *fpr=NULL;
-
-             if(dlen>*fpr_len+1)
-               {
-                 *url=xmalloc(dlen-(*fpr_len+1)+1);
-                 memcpy(*url,&pt[*fpr_len+1],dlen-(*fpr_len+1));
-                 (*url)[dlen-(*fpr_len+1)]='\0';
-               }
-             else
-               *url=NULL;
-
-             ret=2;
-             break;
-           }
-
-         /* Neither type matches, so go around to the next answer. */
-         pt+=dlen;
-       }
-    }
+         We're interested in the PGP (a key) and IPGP (a URI) types.
+         Skip all others.  TODO: A key is better than a URI since
+         we've gone through all this bother to fetch it, so favor that
+         if we have both PGP and IPGP? */
 
- fail:
-  xfree(answer);
-  return ret;
-#endif /*!USE_ADNS*/
-#else /* !USE_DNS_CERT */
-  return -1;
-#endif
-}
+      while (count-- > 0 && pt < emsg)
+        {
+          u16 type, class, dlen, ctype;
 
+          rc = dn_skipname (pt, emsg);  /* the name we just queried for */
+          if (rc == -1)
+            {
+              err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
+              goto leave;
+            }
 
+          pt += rc;
 
-/* Test with simon.josefsson.org */
+          /* Truncated message? 15 bytes takes us to the point where
+             we start looking at the ctype. */
+          if ((emsg - pt) < 15)
+            break;
 
-#ifdef TEST
-int
-main(int argc,char *argv[])
-{
-  unsigned char *fpr;
-  size_t fpr_len;
-  char *url;
-  int rc;
-  IOBUF iobuf;
+          type = *pt++ << 8;
+          type |= *pt++;
 
-  if(argc!=2)
-    {
-      printf("cert-test [name]\n");
-      return 1;
-    }
+          class = *pt++ << 8;
+          class |= *pt++;
+          /* We asked for IN and got something else !? */
+          if (class != C_IN)
+            break;
 
-  printf("CERT lookup on %s\n",argv[1]);
+          /* ttl */
+          pt += 4;
 
-  rc=get_dns_cert (argv[1],16384,&iobuf,&fpr,&fpr_len,&url);
-  if(rc==-1)
-    printf("error\n");
-  else if(rc==0)
-    printf("no answer\n");
-  else if(rc==1)
-    {
-      printf("key found: %d bytes\n",(int)iobuf_get_temp_length(iobuf));
-      iobuf_close(iobuf);
-    }
-  else if(rc==2)
-    {
-      if(fpr)
-       {
-         size_t i;
-         printf("Fingerprint found (%d bytes): ",(int)fpr_len);
-         for(i=0;i<fpr_len;i++)
-           printf("%02X",fpr[i]);
-         printf("\n");
-       }
-      else
-       printf("No fingerprint found\n");
-
-      if(url)
-       printf("URL found: %s\n",url);
-      else
-       printf("No URL found\n");
-
-      xfree(fpr);
-      xfree(url);
+          /* data length */
+          dlen = *pt++ << 8;
+          dlen |= *pt++;
+
+          /* We asked for CERT and got something else - might be a
+             CNAME, so loop around again. */
+          if (type != T_CERT)
+            {
+              pt += dlen;
+              continue;
+            }
+
+          /* The CERT type */
+          ctype = *pt++ << 8;
+          ctype |= *pt++;
+
+          /* Skip the CERT key tag and algo which we don't need. */
+          pt += 3;
+
+          dlen -= 5;
+
+          /* 15 bytes takes us to here */
+
+          if (ctype == CERTTYPE_PGP && dlen)
+            {
+              /* PGP type */
+              *r_key = es_fopenmem_init (0, "rwb", pt, dlen);
+              if (!*r_key)
+                err = gpg_err_make (default_errsource,
+                                    gpg_err_code_from_syserror ());
+              else
+                err = 0;
+              goto leave;
+            }
+          else if (ctype == CERTTYPE_IPGP
+                   && dlen && dlen < 1023 && dlen >= pt[0] + 1)
+            {
+              /* IPGP type */
+              *r_fprlen = pt[0];
+              if (*r_fprlen)
+                {
+                  *r_fpr = xtrymalloc (*r_fprlen);
+                  if (!*r_fpr)
+                    {
+                      err = gpg_err_make (default_errsource,
+                                          gpg_err_code_from_syserror ());
+                      goto leave;
+                    }
+                  memcpy (*r_fpr, &pt[1], *r_fprlen);
+                }
+              else
+                *r_fpr = NULL;
+
+              if (dlen > *r_fprlen + 1)
+                {
+                  *r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1);
+                  if (!*r_fpr)
+                    {
+                      err = gpg_err_make (default_errsource,
+                                          gpg_err_code_from_syserror ());
+                      xfree (*r_fpr);
+                      *r_fpr = NULL;
+                      goto leave;
+                    }
+                  memcpy (*r_url, &pt[*r_fprlen + 1], dlen - (*r_fprlen + 1));
+                  (*r_url)[dlen - (*r_fprlen + 1)] = '\0';
+                }
+              else
+                *r_url = NULL;
+
+              err = 0;
+              goto leave;
+            }
+
+          /* Neither type matches, so go around to the next answer. */
+          pt += dlen;
+        }
     }
 
-  return 0;
+ leave:
+  xfree (answer);
+  return err;
+
+#endif /*!USE_ADNS */
+#else /* !USE_DNS_CERT */
+  (void)name;
+  *r_key = NULL;
+  *r_fpr = NULL;
+  *r_fprlen = 0;
+  *r_url = NULL;
+
+  return gpg_err_make (default_errsource, GPG_ERR_NOT_SUPPORTED);
+#endif
 }
-#endif /* TEST */
index 8275339..ae38caa 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #ifndef GNUPG_COMMON_DNS_CERT_H
 #define GNUPG_COMMON_DNS_CERT_H
 
-int get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf,
-                  unsigned char **fpr, size_t *fpr_len, char **url);
+gpg_error_t get_dns_cert (const char *name, estream_t *r_key,
+                          unsigned char **r_fpr, size_t *r_fprlen,
+                          char **r_url);
+
 
 
 #endif /*GNUPG_COMMON_DNS_CERT_H*/
diff --git a/common/dotlock.c b/common/dotlock.c
new file mode 100644 (file)
index 0000000..c5520db
--- /dev/null
@@ -0,0 +1,1304 @@
+/* dotlock.c - dotfile locking
+ * Copyright (C) 1998, 2000, 2001, 2003, 2004,
+ *               2005, 2006, 2008, 2010, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ *
+ * ALTERNATIVELY, this file may be distributed under the terms of the
+ * following license, in which case the provisions of this license are
+ * required INSTEAD OF the GNU Lesser General License or the GNU
+ * General Public License. If you wish to allow use of your version of
+ * this file only under the terms of the GNU Lesser General License or
+ * the GNU General Public License, and not to allow others to use your
+ * version of this file under the terms of the following license,
+ * indicate your decision by deleting this paragraph and the license
+ * below.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+   Overview:
+   =========
+
+   This module implements advisory file locking in a portable way.
+   Due to the problems with POSIX fcntl locking a separate lock file
+   is used.  It would be possible to use fcntl locking on this lock
+   file and thus avoid the weird auto unlock bug of POSIX while still
+   having an unproved better performance of fcntl locking.  However
+   there are still problems left, thus we resort to use a hardlink
+   which has the well defined property that a link call will fail if
+   the target file already exists.
+
+   Given that hardlinks are also available on NTFS file systems since
+   Windows XP; it will be possible to enhance this module to use
+   hardlinks even on Windows and thus allow Windows and Posix clients
+   to use locking on the same directory.  This is not yet implemented;
+   instead we use a lockfile on Windows along with W32 style file
+   locking.
+
+   On FAT file systems hardlinks are not supported.  Thus this method
+   does not work.  Our solution is to use a O_EXCL locking instead.
+   Querying the type of the file system is not easy to do in a
+   portable way (e.g. Linux has a statfs, BSDs have a the same call
+   but using different structures and constants).  What we do instead
+   is to check at runtime whether link(2) works for a specific lock
+   file.
+
+
+   How to use:
+   ===========
+
+   At program initialization time, the module should be explicitly
+   initialized:
+
+      dotlock_create (NULL, 0);
+
+   This installs an atexit handler and may also initialize mutex etc.
+   It is optional for non-threaded applications.  Only the first call
+   has an effect.  This needs to be done before any extra threads are
+   started.
+
+   To create a lock file (which  prepares it but does not take the
+   lock) you do:
+
+     dotlock_t h
+
+     h = dotlock_create (fname, 0);
+     if (!h)
+       error ("error creating lock file: %s\n", strerror (errno));
+
+   It is important to handle the error.  For example on a read-only
+   file system a lock can't be created (but is usually not needed).
+   FNAME is the file you want to lock; the actual lockfile is that
+   name with the suffix ".lock" appended.  On success a handle to be
+   used with the other functions is returned or NULL on error.  Note
+   that the handle shall only be used by one thread at a time.  This
+   function creates a unique file temporary file (".#lk*") in the same
+   directory as FNAME and returns a handle for further operations.
+   The module keeps track of theses unique files so that they will be
+   unlinked using the atexit handler.  If you don't need the lock file
+   anymore, you may also explicitly remove it with a call to:
+
+     dotlock_destroy (h);
+
+   To actually lock the file, you use:
+
+     if (dotlock_take (h, -1))
+       error ("error taking lock: %s\n", strerror (errno));
+
+   This function will wait until the lock is acquired.  If an
+   unexpected error occurs if will return non-zero and set ERRNO.  If
+   you pass (0) instead of (-1) the function does not wait in case the
+   file is already locked but returns -1 and sets ERRNO to EACCES.
+   Any other positive value for the second parameter is considered a
+   timeout valuie in milliseconds.
+
+   To release the lock you call:
+
+     if (dotlock_release (h))
+       error ("error releasing lock: %s\n", strerror (errno));
+
+   or, if the lock file is not anymore needed, you may just call
+   dotlock_destroy.  However dotlock_release does some extra checks
+   before releasing the lock and prints diagnostics to help detecting
+   bugs.
+
+   If you want to explicitly destroy all lock files you may call
+
+     dotlock_remove_lockfiles ();
+
+   which is the core of the installed atexit handler.  In case your
+   application wants to disable locking completely it may call
+
+     disable_locking ()
+
+   before any locks are created.
+
+   There are two convenience functions to store an integer (e.g. a
+   file descriptor) value with the handle:
+
+     void dotlock_set_fd (dotlock_t h, int fd);
+     int  dotlock_get_fd (dotlock_t h);
+
+   If nothing has been stored dotlock_get_fd returns -1.
+
+
+
+   How to build:
+   =============
+
+   This module was originally developed for GnuPG but later changed to
+   allow its use without any GnuPG dependency.  If you want to use it
+   with you application you may simply use it and it should figure out
+   most things automagically.
+
+   You may use the common config.h file to pass macros, but take care
+   to pass -DHAVE_CONFIG_H to the compiler.  Macros used by this
+   module are:
+
+     DOTLOCK_USE_PTHREAD  - Define if POSIX threads are in use.
+
+     DOTLOCK_GLIB_LOGGING - Define this to use Glib logging functions.
+
+     DOTLOCK_EXT_SYM_PREFIX - Prefix all external symbols with the
+                              string to which this macro evaluates.
+
+     GNUPG_MAJOR_VERSION - Defined when used by GnuPG.
+
+     HAVE_DOSISH_SYSTEM  - Defined for Windows etc.  Will be
+                           automatically defined if a the target is
+                           Windows.
+
+     HAVE_POSIX_SYSTEM   - Internally defined to !HAVE_DOSISH_SYSTEM.
+
+     HAVE_SIGNAL_H       - Should be defined on Posix systems.  If config.h
+                           is not used defaults to defined.
+
+     DIRSEP_C            - Separation character for file name parts.
+                           Usually not redefined.
+
+     EXTSEP_S            - Separation string for file name suffixes.
+                           Usually not redefined.
+
+     HAVE_W32CE_SYSTEM   - Currently only used by GnuPG.
+
+   Note that there is a test program t-dotlock which has compile
+   instructions at its end.  At least for SMBFS and CIFS it is
+   important that 64 bit versions of stat are used; most programming
+   environments do this these days, just in case you want to compile
+   it on the command line, remember to pass -D_FILE_OFFSET_BITS=64
+
+
+   Bugs:
+   =====
+
+   On Windows this module is not yet thread-safe.
+
+
+   Miscellaneous notes:
+   ====================
+
+   On hardlinks:
+   - Hardlinks are supported under Windows with NTFS since XP/Server2003.
+   - In Linux 2.6.33 both SMBFS and CIFS seem to support hardlinks.
+   - NFS supports hard links.  But there are solvable problems.
+   - FAT does not support links
+
+   On the file locking API:
+   - CIFS on Linux 2.6.33 supports several locking methods.
+     SMBFS seems not to support locking.  No closer checks done.
+   - NFS supports Posix locks.  flock is emulated in the server.
+     However there are a couple of problems; see below.
+   - FAT does not support locks.
+   - An advantage of fcntl locking is that R/W locks can be
+     implemented which is not easy with a straight lock file.
+
+   On O_EXCL:
+   - Does not work reliable on NFS
+   - Should work on CIFS and SMBFS but how can we delete lockfiles?
+
+   On NFS problems:
+   - Locks vanish if the server crashes and reboots.
+   - Client crashes keep the lock in the server until the client
+     re-connects.
+   - Communication problems may return unreliable error codes.  The
+     MUA Postfix's workaround is to compare the link count after
+     seeing an error for link.  However that gives a race.  If using a
+     unique file to link to a lockfile and using stat to check the
+     link count instead of looking at the error return of link(2) is
+     the best solution.
+   - O_EXCL seems to have a race and may re-create a file anyway.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Some quick replacements for stuff we usually expect to be defined
+   in config.h.  Define HAVE_POSIX_SYSTEM for better readability. */
+#if !defined (HAVE_DOSISH_SYSTEM) && defined(_WIN32)
+# define HAVE_DOSISH_SYSTEM 1
+#endif
+#if !defined (HAVE_DOSISH_SYSTEM) && !defined (HAVE_POSIX_SYSTEM)
+# define HAVE_POSIX_SYSTEM 1
+#endif
+
+/* With no config.h assume that we have sitgnal.h.  */
+#if !defined (HAVE_CONFIG_H) && defined (HAVE_POSIX_SYSTEM)
+# define HAVE_SIGNAL_H 1
+#endif
+
+/* Standard headers.  */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef  HAVE_DOSISH_SYSTEM
+# define WIN32_LEAN_AND_MEAN  /* We only need the OS core stuff.  */
+# include <windows.h>
+#else
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/utsname.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+#ifdef DOTLOCK_USE_PTHREAD
+# include <pthread.h>
+#endif
+
+#ifdef DOTLOCK_GLIB_LOGGING
+# include <glib.h>
+#endif
+
+#ifdef GNUPG_MAJOR_VERSION
+# include "libjnlib-config.h"
+# include "stringhelp.h"  /* For stpcpy and w32_strerror. */
+#endif
+#ifdef HAVE_W32CE_SYSTEM
+# include "utf8conv.h"  /* WindowsCE requires filename conversion.  */
+#endif
+
+#include "dotlock.h"
+
+
+/* Define constants for file name construction.  */
+#if !defined(DIRSEP_C) && !defined(EXTSEP_S)
+# ifdef HAVE_DOSISH_SYSTEM
+#  define DIRSEP_C '\\'
+#  define EXTSEP_S "."
+#else
+#  define DIRSEP_C '/'
+#  define EXTSEP_S "."
+# endif
+#endif
+
+/* In GnuPG we use wrappers around the malloc fucntions.  If they are
+   not defined we assume that this code is used outside of GnuPG and
+   fall back to the regular malloc functions.  */
+#ifndef jnlib_malloc
+# define jnlib_malloc(a)     malloc ((a))
+# define jnlib_calloc(a,b)   calloc ((a), (b))
+# define jnlib_free(a)      free ((a))
+#endif
+
+/* Wrapper to set ERRNO.  */
+#ifndef jnlib_set_errno
+# ifdef HAVE_W32CE_SYSTEM
+#  define jnlib_set_errno(e)  gpg_err_set_errno ((e))
+# else
+#  define jnlib_set_errno(e)  do { errno = (e); } while (0)
+# endif
+#endif
+
+/* Gettext macro replacement.  */
+#ifndef _
+# define _(a) (a)
+#endif
+
+#ifdef GNUPG_MAJOR_VERSION
+# define my_info_0(a)       log_info ((a))
+# define my_info_1(a,b)     log_info ((a), (b))
+# define my_info_2(a,b,c)   log_info ((a), (b), (c))
+# define my_info_3(a,b,c,d) log_info ((a), (b), (c), (d))
+# define my_error_0(a)      log_error ((a))
+# define my_error_1(a,b)    log_error ((a), (b))
+# define my_error_2(a,b,c)  log_error ((a), (b), (c))
+# define my_debug_1(a,b)    log_debug ((a), (b))
+# define my_fatal_0(a)      log_fatal ((a))
+#elif defined (DOTLOCK_GLIB_LOGGING)
+# define my_info_0(a)       g_message ((a))
+# define my_info_1(a,b)     g_message ((a), (b))
+# define my_info_2(a,b,c)   g_message ((a), (b), (c))
+# define my_info_3(a,b,c,d) g_message ((a), (b), (c), (d))
+# define my_error_0(a)      g_warning ((a))
+# define my_error_1(a,b)    g_warning ((a), (b))
+# define my_error_2(a,b,c)  g_warning ((a), (b), (c))
+# define my_debug_1(a,b)    g_debug ((a), (b))
+# define my_fatal_0(a)      g_error ((a))
+#else
+# define my_info_0(a)       fprintf (stderr, (a))
+# define my_info_1(a,b)     fprintf (stderr, (a), (b))
+# define my_info_2(a,b,c)   fprintf (stderr, (a), (b), (c))
+# define my_info_3(a,b,c,d) fprintf (stderr, (a), (b), (c), (d))
+# define my_error_0(a)      fprintf (stderr, (a))
+# define my_error_1(a,b)    fprintf (stderr, (a), (b))
+# define my_error_2(a,b,c)  fprintf (stderr, (a), (b), (c))
+# define my_debug_1(a,b)    fprintf (stderr, (a), (b))
+# define my_fatal_0(a)      do { fprintf (stderr,(a)); fflush (stderr); \
+                                 abort (); } while (0)
+#endif
+
+
+
+
+\f
+/* The object describing a lock.  */
+struct dotlock_handle
+{
+  struct dotlock_handle *next;
+  char *lockname;            /* Name of the actual lockfile.          */
+  unsigned int locked:1;     /* Lock status.                          */
+  unsigned int disable:1;    /* If true, locking is disabled.         */
+  unsigned int use_o_excl:1; /* Use open (O_EXCL) for locking.        */
+
+  int extra_fd;              /* A place for the caller to store an FD.  */
+
+#ifdef HAVE_DOSISH_SYSTEM
+  HANDLE lockhd;       /* The W32 handle of the lock file.      */
+#else /*!HAVE_DOSISH_SYSTEM */
+  char *tname;         /* Name of the lockfile template.        */
+  size_t nodename_off; /* Offset in TNAME of the nodename part. */
+  size_t nodename_len; /* Length of the nodename part.          */
+#endif /*!HAVE_DOSISH_SYSTEM */
+};
+
+
+/* A list of of all lock handles.  The volatile attribute might help
+   if used in an atexit handler.  */
+static volatile dotlock_t all_lockfiles;
+#ifdef DOTLOCK_USE_PTHREAD
+static pthread_mutex_t all_lockfiles_mutex = PTHREAD_MUTEX_INITIALIZER;
+# define LOCK_all_lockfiles() do {                               \
+        if (pthread_mutex_lock (&all_lockfiles_mutex))           \
+          my_fatal_0 ("locking all_lockfiles_mutex failed\n");   \
+      } while (0)
+# define UNLOCK_all_lockfiles() do {                             \
+        if (pthread_mutex_unlock (&all_lockfiles_mutex))         \
+          my_fatal_0 ("unlocking all_lockfiles_mutex failed\n"); \
+      } while (0)
+#else  /*!DOTLOCK_USE_PTHREAD*/
+# define LOCK_all_lockfiles()   do { } while (0)
+# define UNLOCK_all_lockfiles() do { } while (0)
+#endif /*!DOTLOCK_USE_PTHREAD*/
+
+/* If this has the value true all locking is disabled.  */
+static int never_lock;
+
+
+
+
+\f
+/* Entirely disable all locking.  This function should be called
+   before any locking is done.  It may be called right at startup of
+   the process as it only sets a global value.  */
+void
+dotlock_disable (void)
+{
+  never_lock = 1;
+}
+
+
+#ifdef HAVE_POSIX_SYSTEM
+static int
+maybe_deadlock (dotlock_t h)
+{
+  dotlock_t r;
+  int res = 0;
+
+  LOCK_all_lockfiles ();
+  for (r=all_lockfiles; r; r = r->next)
+    {
+      if ( r != h && r->locked )
+        {
+          res = 1;
+          break;
+        }
+    }
+  UNLOCK_all_lockfiles ();
+  return res;
+}
+#endif /*HAVE_POSIX_SYSTEM*/
+
+
+/* Read the lock file and return the pid, returns -1 on error.  True
+   will be stored in the integer at address SAME_NODE if the lock file
+   has been created on the same node. */
+#ifdef HAVE_POSIX_SYSTEM
+static int
+read_lockfile (dotlock_t h, int *same_node )
+{
+  char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node
+                                   names are usually shorter. */
+  int fd;
+  int pid = -1;
+  char *buffer, *p;
+  size_t expected_len;
+  int res, nread;
+
+  *same_node = 0;
+  expected_len = 10 + 1 + h->nodename_len + 1;
+  if ( expected_len >= sizeof buffer_space)
+    {
+      buffer = jnlib_malloc (expected_len);
+      if (!buffer)
+        return -1;
+    }
+  else
+    buffer = buffer_space;
+
+  if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
+    {
+      int e = errno;
+      my_info_2 ("error opening lockfile '%s': %s\n",
+                 h->lockname, strerror(errno) );
+      if (buffer != buffer_space)
+        jnlib_free (buffer);
+      jnlib_set_errno (e); /* Need to return ERRNO here. */
+      return -1;
+    }
+
+  p = buffer;
+  nread = 0;
+  do
+    {
+      res = read (fd, p, expected_len - nread);
+      if (res == -1 && errno == EINTR)
+        continue;
+      if (res < 0)
+        {
+          my_info_1 ("error reading lockfile '%s'\n", h->lockname );
+          close (fd);
+          if (buffer != buffer_space)
+            jnlib_free (buffer);
+          jnlib_set_errno (0); /* Do not return an inappropriate ERRNO. */
+          return -1;
+        }
+      p += res;
+      nread += res;
+    }
+  while (res && nread != expected_len);
+  close(fd);
+
+  if (nread < 11)
+    {
+      my_info_1 ("invalid size of lockfile '%s'\n", h->lockname);
+      if (buffer != buffer_space)
+        jnlib_free (buffer);
+      jnlib_set_errno (0); /* Better don't return an inappropriate ERRNO. */
+      return -1;
+    }
+
+  if (buffer[10] != '\n'
+      || (buffer[10] = 0, pid = atoi (buffer)) == -1
+      || !pid )
+    {
+      my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname);
+      if (buffer != buffer_space)
+        jnlib_free (buffer);
+      jnlib_set_errno (0);
+      return -1;
+    }
+
+  if (nread == expected_len
+      && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
+      && buffer[11+h->nodename_len] == '\n')
+    *same_node = 1;
+
+  if (buffer != buffer_space)
+    jnlib_free (buffer);
+  return pid;
+}
+#endif /*HAVE_POSIX_SYSTEM */
+
+
+/* Check whether the file system which stores TNAME supports
+   hardlinks.  Instead of using the non-portable statsfs call which
+   differs between various Unix versions, we do a runtime test.
+   Returns: 0 supports hardlinks; 1 no hardlink support, -1 unknown
+   (test error).  */
+#ifdef HAVE_POSIX_SYSTEM
+static int
+use_hardlinks_p (const char *tname)
+{
+  char *lname;
+  struct stat sb;
+  unsigned int nlink;
+  int res;
+
+  if (stat (tname, &sb))
+    return -1;
+  nlink = (unsigned int)sb.st_nlink;
+
+  lname = jnlib_malloc (strlen (tname) + 1 + 1);
+  if (!lname)
+    return -1;
+  strcpy (lname, tname);
+  strcat (lname, "x");
+
+  /* We ignore the return value of link() because it is unreliable.  */
+  (void) link (tname, lname);
+
+  if (stat (tname, &sb))
+    res = -1;  /* Ooops.  */
+  else if (sb.st_nlink == nlink + 1)
+    res = 0;   /* Yeah, hardlinks are supported.  */
+  else
+    res = 1;   /* No hardlink support.  */
+
+  unlink (lname);
+  jnlib_free (lname);
+  return res;
+}
+#endif /*HAVE_POSIX_SYSTEM */
+
+
+\f
+#ifdef  HAVE_POSIX_SYSTEM
+/* Locking core for Unix.  It used a temporary file and the link
+   system call to make locking an atomic operation. */
+static dotlock_t
+dotlock_create_unix (dotlock_t h, const char *file_to_lock)
+{
+  int  fd = -1;
+  char pidstr[16];
+  const char *nodename;
+  const char *dirpart;
+  int dirpartlen;
+  struct utsname utsbuf;
+  size_t tnamelen;
+
+  snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );
+
+  /* Create a temporary file. */
+  if ( uname ( &utsbuf ) )
+    nodename = "unknown";
+  else
+    nodename = utsbuf.nodename;
+
+  if ( !(dirpart = strrchr (file_to_lock, DIRSEP_C)) )
+    {
+      dirpart = EXTSEP_S;
+      dirpartlen = 1;
+    }
+  else
+    {
+      dirpartlen = dirpart - file_to_lock;
+      dirpart = file_to_lock;
+    }
+
+  LOCK_all_lockfiles ();
+  h->next = all_lockfiles;
+  all_lockfiles = h;
+
+  tnamelen = dirpartlen + 6 + 30 + strlen(nodename) + 10 + 1;
+  h->tname = jnlib_malloc (tnamelen + 1);
+  if (!h->tname)
+    {
+      all_lockfiles = h->next;
+      UNLOCK_all_lockfiles ();
+      jnlib_free (h);
+      return NULL;
+    }
+  h->nodename_len = strlen (nodename);
+
+  snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h );
+  h->nodename_off = strlen (h->tname);
+  snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off,
+           "%s.%d", nodename, (int)getpid ());
+
+  do
+    {
+      jnlib_set_errno (0);
+      fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
+                 S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
+    }
+  while (fd == -1 && errno == EINTR);
+
+  if ( fd == -1 )
+    {
+      all_lockfiles = h->next;
+      UNLOCK_all_lockfiles ();
+      my_error_2 (_("failed to create temporary file '%s': %s\n"),
+                  h->tname, strerror(errno));
+      jnlib_free (h->tname);
+      jnlib_free (h);
+      return NULL;
+    }
+  if ( write (fd, pidstr, 11 ) != 11 )
+    goto write_failed;
+  if ( write (fd, nodename, strlen (nodename) ) != strlen (nodename) )
+    goto write_failed;
+  if ( write (fd, "\n", 1 ) != 1 )
+    goto write_failed;
+  if ( close (fd) )
+    goto write_failed;
+
+  /* Check whether we support hard links.  */
+  switch (use_hardlinks_p (h->tname))
+    {
+    case 0: /* Yes.  */
+      break;
+    case 1: /* No.  */
+      unlink (h->tname);
+      h->use_o_excl = 1;
+      break;
+    default:
+      my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n",
+                  h->tname, strerror(errno));
+      goto write_failed;
+    }
+
+  h->lockname = jnlib_malloc (strlen (file_to_lock) + 6 );
+  if (!h->lockname)
+    {
+      all_lockfiles = h->next;
+      UNLOCK_all_lockfiles ();
+      unlink (h->tname);
+      jnlib_free (h->tname);
+      jnlib_free (h);
+      return NULL;
+    }
+  strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
+  UNLOCK_all_lockfiles ();
+  if (h->use_o_excl)
+    my_debug_1 ("locking for '%s' done via O_EXCL\n", h->lockname);
+
+  return h;
+
+ write_failed:
+  all_lockfiles = h->next;
+  UNLOCK_all_lockfiles ();
+  my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno));
+  close (fd);
+  unlink (h->tname);
+  jnlib_free (h->tname);
+  jnlib_free (h);
+  return NULL;
+}
+#endif /*HAVE_POSIX_SYSTEM*/
+
+
+#ifdef HAVE_DOSISH_SYSTEM
+/* Locking core for Windows.  This version does not need a temporary
+   file but uses the plain lock file along with record locking.  We
+   create this file here so that we later only need to do the file
+   locking.  For error reporting it is useful to keep the name of the
+   file in the handle.  */
+static dotlock_t
+dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
+{
+  LOCK_all_lockfiles ();
+  h->next = all_lockfiles;
+  all_lockfiles = h;
+
+  h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 );
+  if (!h->lockname)
+    {
+      all_lockfiles = h->next;
+      UNLOCK_all_lockfiles ();
+      jnlib_free (h);
+      return NULL;
+    }
+  strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
+
+  /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
+     along with FILE_SHARE_DELETE but that does not work due to a race
+     condition: Despite the OPEN_ALWAYS flag CreateFile may return an
+     error and we can't reliable create/open the lock file unless we
+     would wait here until it works - however there are other valid
+     reasons why a lock file can't be created and thus the process
+     would not stop as expected but spin until Windows crashes.  Our
+     solution is to keep the lock file open; that does not harm. */
+  {
+#ifdef HAVE_W32CE_SYSTEM
+    wchar_t *wname = utf8_to_wchar (h->lockname);
+
+    if (wname)
+      h->lockhd = CreateFile (wname,
+                              GENERIC_READ|GENERIC_WRITE,
+                              FILE_SHARE_READ|FILE_SHARE_WRITE,
+                              NULL, OPEN_ALWAYS, 0, NULL);
+    else
+      h->lockhd = INVALID_HANDLE_VALUE;
+    jnlib_free (wname);
+#else
+    h->lockhd = CreateFile (h->lockname,
+                            GENERIC_READ|GENERIC_WRITE,
+                            FILE_SHARE_READ|FILE_SHARE_WRITE,
+                            NULL, OPEN_ALWAYS, 0, NULL);
+#endif
+  }
+  if (h->lockhd == INVALID_HANDLE_VALUE)
+    {
+      all_lockfiles = h->next;
+      UNLOCK_all_lockfiles ();
+      my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1));
+      jnlib_free (h->lockname);
+      jnlib_free (h);
+      return NULL;
+    }
+  return h;
+}
+#endif /*HAVE_DOSISH_SYSTEM*/
+
+
+/* Create a lockfile for a file name FILE_TO_LOCK and returns an
+   object of type dotlock_t which may be used later to actually acquire
+   the lock.  A cleanup routine gets installed to cleanup left over
+   locks or other files used internally by the lock mechanism.
+
+   Calling this function with NULL does only install the atexit
+   handler and may thus be used to assure that the cleanup is called
+   after all other atexit handlers.
+
+   This function creates a lock file in the same directory as
+   FILE_TO_LOCK using that name and a suffix of ".lock".  Note that on
+   POSIX systems a temporary file ".#lk.<hostname>.pid[.threadid] is
+   used.
+
+   FLAGS must be 0.
+
+   The function returns an new handle which needs to be released using
+   destroy_dotlock but gets also released at the termination of the
+   process.  On error NULL is returned.
+ */
+
+dotlock_t
+dotlock_create (const char *file_to_lock, unsigned int flags)
+{
+  static int initialized;
+  dotlock_t h;
+
+  if ( !initialized )
+    {
+      atexit (dotlock_remove_lockfiles);
+      initialized = 1;
+    }
+
+  if ( !file_to_lock )
+    return NULL;  /* Only initialization was requested.  */
+
+  if (flags)
+    {
+      jnlib_set_errno (EINVAL);
+      return NULL;
+    }
+
+  h = jnlib_calloc (1, sizeof *h);
+  if (!h)
+    return NULL;
+  h->extra_fd = -1;
+
+  if (never_lock)
+    {
+      h->disable = 1;
+      LOCK_all_lockfiles ();
+      h->next = all_lockfiles;
+      all_lockfiles = h;
+      UNLOCK_all_lockfiles ();
+      return h;
+    }
+
+#ifdef HAVE_DOSISH_SYSTEM
+  return dotlock_create_w32 (h, file_to_lock);
+#else /*!HAVE_DOSISH_SYSTEM */
+  return dotlock_create_unix (h, file_to_lock);
+#endif /*!HAVE_DOSISH_SYSTEM*/
+}
+
+
+\f
+/* Convenience function to store a file descriptor (or any any other
+   integer value) in the context of handle H.  */
+void
+dotlock_set_fd (dotlock_t h, int fd)
+{
+  h->extra_fd = fd;
+}
+
+/* Convenience function to retrieve a file descriptor (or any any other
+   integer value) stored in the context of handle H.  */
+int
+dotlock_get_fd (dotlock_t h)
+{
+  return h->extra_fd;
+}
+
+
+\f
+#ifdef HAVE_POSIX_SYSTEM
+/* Unix specific code of destroy_dotlock.  */
+static void
+dotlock_destroy_unix (dotlock_t h)
+{
+  if (h->locked && h->lockname)
+    unlink (h->lockname);
+  if (h->tname && !h->use_o_excl)
+    unlink (h->tname);
+  jnlib_free (h->tname);
+}
+#endif /*HAVE_POSIX_SYSTEM*/
+
+
+#ifdef HAVE_DOSISH_SYSTEM
+/* Windows specific code of destroy_dotlock.  */
+static void
+dotlock_destroy_w32 (dotlock_t h)
+{
+  if (h->locked)
+    {
+      OVERLAPPED ovl;
+
+      memset (&ovl, 0, sizeof ovl);
+      UnlockFileEx (h->lockhd, 0, 1, 0, &ovl);
+    }
+  CloseHandle (h->lockhd);
+}
+#endif /*HAVE_DOSISH_SYSTEM*/
+
+
+/* Destroy the locck handle H and release the lock.  */
+void
+dotlock_destroy (dotlock_t h)
+{
+  dotlock_t hprev, htmp;
+
+  if ( !h )
+    return;
+
+  /* First remove the handle from our global list of all locks. */
+  LOCK_all_lockfiles ();
+  for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next)
+    if (htmp == h)
+      {
+        if (hprev)
+          hprev->next = htmp->next;
+        else
+          all_lockfiles = htmp->next;
+        h->next = NULL;
+        break;
+      }
+  UNLOCK_all_lockfiles ();
+
+  /* Then destroy the lock. */
+  if (!h->disable)
+    {
+#ifdef HAVE_DOSISH_SYSTEM
+      dotlock_destroy_w32 (h);
+#else /* !HAVE_DOSISH_SYSTEM */
+      dotlock_destroy_unix (h);
+#endif /* HAVE_DOSISH_SYSTEM */
+      jnlib_free (h->lockname);
+    }
+  jnlib_free(h);
+}
+
+
+\f
+#ifdef HAVE_POSIX_SYSTEM
+/* Unix specific code of make_dotlock.  Returns 0 on success and -1 on
+   error.  */
+static int
+dotlock_take_unix (dotlock_t h, long timeout)
+{
+  int wtime = 0;
+  int sumtime = 0;
+  int pid;
+  int lastpid = -1;
+  int ownerchanged;
+  const char *maybe_dead="";
+  int same_node;
+
+ again:
+  if (h->use_o_excl)
+    {
+      /* No hardlink support - use open(O_EXCL).  */
+      int fd;
+
+      do
+        {
+          jnlib_set_errno (0);
+          fd = open (h->lockname, O_WRONLY|O_CREAT|O_EXCL,
+                     S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
+        }
+      while (fd == -1 && errno == EINTR);
+
+      if (fd == -1 && errno == EEXIST)
+        ; /* Lock held by another process.  */
+      else if (fd == -1)
+        {
+          my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n",
+                      h->lockname, strerror (errno));
+          return -1;
+        }
+      else
+        {
+          char pidstr[16];
+
+          snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid());
+          if (write (fd, pidstr, 11 ) == 11
+              && write (fd, h->tname + h->nodename_off,h->nodename_len)
+              == h->nodename_len
+              && write (fd, "\n", 1) == 1
+              && !close (fd))
+            {
+              h->locked = 1;
+              return 0;
+            }
+          /* Write error.  */
+          my_error_2 ("lock not made: writing to '%s' failed: %s\n",
+                      h->lockname, strerror (errno));
+          close (fd);
+          unlink (h->lockname);
+          return -1;
+        }
+    }
+  else /* Standard method:  Use hardlinks.  */
+    {
+      struct stat sb;
+
+      /* We ignore the return value of link() because it is unreliable.  */
+      (void) link (h->tname, h->lockname);
+
+      if (stat (h->tname, &sb))
+        {
+          my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
+                      strerror (errno));
+          /* In theory this might be a severe error: It is possible
+             that link succeeded but stat failed due to changed
+             permissions.  We can't do anything about it, though.  */
+          return -1;
+        }
+
+      if (sb.st_nlink == 2)
+        {
+          h->locked = 1;
+          return 0; /* Okay.  */
+        }
+    }
+
+  /* Check for stale lock files.  */
+  if ( (pid = read_lockfile (h, &same_node)) == -1 )
+    {
+      if ( errno != ENOENT )
+        {
+          my_info_0 ("cannot read lockfile\n");
+          return -1;
+        }
+      my_info_0 ("lockfile disappeared\n");
+      goto again;
+    }
+  else if ( pid == getpid() && same_node )
+    {
+      my_info_0 ("Oops: lock already held by us\n");
+      h->locked = 1;
+      return 0; /* okay */
+    }
+  else if ( same_node && kill (pid, 0) && errno == ESRCH )
+    {
+      /* Note: It is unlikley that we get a race here unless a pid is
+         reused too fast or a new process with the same pid as the one
+         of the stale file tries to lock right at the same time as we.  */
+      my_info_1 (_("removing stale lockfile (created by %d)\n"), pid);
+      unlink (h->lockname);
+      goto again;
+    }
+
+  if (lastpid == -1)
+    lastpid = pid;
+  ownerchanged = (pid != lastpid);
+
+  if (timeout)
+    {
+      struct timeval tv;
+
+      /* Wait until lock has been released.  We use increasing retry
+         intervals of 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s
+         but reset it if the lock owner meanwhile changed.  */
+      if (!wtime || ownerchanged)
+        wtime = 50;
+      else if (wtime < 800)
+        wtime *= 2;
+      else if (wtime == 800)
+        wtime = 2000;
+      else if (wtime < 8000)
+        wtime *= 2;
+
+      if (timeout > 0)
+        {
+          if (wtime > timeout)
+            wtime = timeout;
+          timeout -= wtime;
+        }
+
+      sumtime += wtime;
+      if (sumtime >= 1500)
+        {
+          sumtime = 0;
+          my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
+                     pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
+        }
+
+
+      tv.tv_sec = wtime / 1000;
+      tv.tv_usec = (wtime % 1000) * 1000;
+      select (0, NULL, NULL, NULL, &tv);
+      goto again;
+    }
+
+  jnlib_set_errno (EACCES);
+  return -1;
+}
+#endif /*HAVE_POSIX_SYSTEM*/
+
+
+#ifdef HAVE_DOSISH_SYSTEM
+/* Windows specific code of make_dotlock.  Returns 0 on success and -1 on
+   error.  */
+static int
+dotlock_take_w32 (dotlock_t h, long timeout)
+{
+  int wtime = 0;
+  int w32err;
+  OVERLAPPED ovl;
+
+ again:
+  /* Lock one byte at offset 0.  The offset is given by OVL.  */
+  memset (&ovl, 0, sizeof ovl);
+  if (LockFileEx (h->lockhd, (LOCKFILE_EXCLUSIVE_LOCK
+                              | LOCKFILE_FAIL_IMMEDIATELY), 0, 1, 0, &ovl))
+    {
+      h->locked = 1;
+      return 0; /* okay */
+    }
+
+  w32err = GetLastError ();
+  if (w32err != ERROR_LOCK_VIOLATION)
+    {
+      my_error_2 (_("lock '%s' not made: %s\n"),
+                  h->lockname, w32_strerror (w32err));
+      return -1;
+    }
+
+  if (timeout)
+    {
+      /* Wait until lock has been released.  We use retry intervals of
+         50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s.  */
+      if (!wtime)
+        wtime = 50;
+      else if (wtime < 800)
+        wtime *= 2;
+      else if (wtime == 800)
+        wtime = 2000;
+      else if (wtime < 8000)
+        wtime *= 2;
+
+      if (timeout > 0)
+        {
+          if (wtime > timeout)
+            wtime = timeout;
+          timeout -= wtime;
+        }
+
+      if (wtime >= 800)
+        my_info_1 (_("waiting for lock %s...\n"), h->lockname);
+
+      Sleep (wtime);
+      goto again;
+    }
+
+  return -1;
+}
+#endif /*HAVE_DOSISH_SYSTEM*/
+
+
+/* Take a lock on H.  A value of 0 for TIMEOUT returns immediately if
+   the lock can't be taked, -1 waits forever (hopefully not), other
+   values wait for TIMEOUT milliseconds.  Returns: 0 on success  */
+int
+dotlock_take (dotlock_t h, long timeout)
+{
+  int ret;
+
+  if ( h->disable )
+    return 0; /* Locks are completely disabled.  Return success. */
+
+  if ( h->locked )
+    {
+      my_debug_1 ("Oops, '%s' is already locked\n", h->lockname);
+      return 0;
+    }
+
+#ifdef HAVE_DOSISH_SYSTEM
+  ret = dotlock_take_w32 (h, timeout);
+#else /*!HAVE_DOSISH_SYSTEM*/
+  ret = dotlock_take_unix (h, timeout);
+#endif /*!HAVE_DOSISH_SYSTEM*/
+
+  return ret;
+}
+
+
+\f
+#ifdef HAVE_POSIX_SYSTEM
+/* Unix specific code of release_dotlock.  */
+static int
+dotlock_release_unix (dotlock_t h)
+{
+  int pid, same_node;
+
+  pid = read_lockfile (h, &same_node);
+  if ( pid == -1 )
+    {
+      my_error_0 ("release_dotlock: lockfile error\n");
+      return -1;
+    }
+  if ( pid != getpid() || !same_node )
+    {
+      my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid);
+      return -1;
+    }
+
+  if ( unlink( h->lockname ) )
+    {
+      my_error_1 ("release_dotlock: error removing lockfile '%s'\n",
+                  h->lockname);
+      return -1;
+    }
+  /* Fixme: As an extra check we could check whether the link count is
+     now really at 1. */
+  return 0;
+}
+#endif /*HAVE_POSIX_SYSTEM */
+
+
+#ifdef HAVE_DOSISH_SYSTEM
+/* Windows specific code of release_dotlock.  */
+static int
+dotlock_release_w32 (dotlock_t h)
+{
+  OVERLAPPED ovl;
+
+  memset (&ovl, 0, sizeof ovl);
+  if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
+    {
+      my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n",
+                  h->lockname, w32_strerror (-1));
+      return -1;
+    }
+
+  return 0;
+}
+#endif /*HAVE_DOSISH_SYSTEM */
+
+
+/* Release a lock.  Returns 0 on success.  */
+int
+dotlock_release (dotlock_t h)
+{
+  int ret;
+
+  /* To avoid atexit race conditions we first check whether there are
+     any locks left.  It might happen that another atexit handler
+     tries to release the lock while the atexit handler of this module
+     already ran and thus H is undefined.  */
+  LOCK_all_lockfiles ();
+  ret = !all_lockfiles;
+  UNLOCK_all_lockfiles ();
+  if (ret)
+    return 0;
+
+  if ( h->disable )
+    return 0;
+
+  if ( !h->locked )
+    {
+      my_debug_1 ("Oops, '%s' is not locked\n", h->lockname);
+      return 0;
+    }
+
+#ifdef HAVE_DOSISH_SYSTEM
+  ret = dotlock_release_w32 (h);
+#else
+  ret = dotlock_release_unix (h);
+#endif
+
+  if (!ret)
+    h->locked = 0;
+  return ret;
+}
+
+
+\f
+/* Remove all lockfiles.  This is called by the atexit handler
+   installed by this module but may also be called by other
+   termination handlers.  */
+void
+dotlock_remove_lockfiles (void)
+{
+  dotlock_t h, h2;
+
+  /* First set the lockfiles list to NULL so that for example
+     dotlock_release is ware that this fucntion is currently
+     running.  */
+  LOCK_all_lockfiles ();
+  h = all_lockfiles;
+  all_lockfiles = NULL;
+  UNLOCK_all_lockfiles ();
+
+  while ( h )
+    {
+      h2 = h->next;
+      dotlock_destroy (h);
+      h = h2;
+    }
+}
diff --git a/common/dotlock.h b/common/dotlock.h
new file mode 100644 (file)
index 0000000..3fb9bcb
--- /dev/null
@@ -0,0 +1,112 @@
+/* dotlock.h - dotfile locking declarations
+ * Copyright (C) 2000, 2001, 2006, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ *
+ * ALTERNATIVELY, this file may be distributed under the terms of the
+ * following license, in which case the provisions of this license are
+ * required INSTEAD OF the GNU Lesser General License or the GNU
+ * General Public License. If you wish to allow use of your version of
+ * this file only under the terms of the GNU Lesser General License or
+ * the GNU General Public License, and not to allow others to use your
+ * version of this file under the terms of the following license,
+ * indicate your decision by deleting this paragraph and the license
+ * below.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBJNLIB_DOTLOCK_H
+#define LIBJNLIB_DOTLOCK_H
+
+/* See dotlock.c for a description.  */
+
+#ifdef DOTLOCK_EXT_SYM_PREFIX
+# ifndef _DOTLOCK_PREFIX
+#  define _DOTLOCK_PREFIX1(x,y)  x ## y
+#  define _DOTLOCK_PREFIX2(x,y) _DOTLOCK_PREFIX1(x,y)
+#  define _DOTLOCK_PREFIX(x)    _DOTLOCK_PREFIX2(DOTLOCK_EXT_SYM_PREFIX,x)
+# endif /*_DOTLOCK_PREFIX*/
+# define dotlock_disable          _DOTLOCK_PREFIX(dotlock_disable)
+# define dotlock_create           _DOTLOCK_PREFIX(dotlock_create)
+# define dotlock_set_fd           _DOTLOCK_PREFIX(dotlock_set_fd)
+# define dotlock_get_fd           _DOTLOCK_PREFIX(dotlock_get_fd)
+# define dotlock_destroy          _DOTLOCK_PREFIX(dotlock_destroy)
+# define dotlock_take             _DOTLOCK_PREFIX(dotlock_take)
+# define dotlock_release          _DOTLOCK_PREFIX(dotlock_release)
+# define dotlock_remove_lockfiles _DOTLOCK_PREFIX(dotlock_remove_lockfiles)
+#endif /*DOTLOCK_EXT_SYM_PREFIX*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0
+}
+#endif
+#endif
+
+
+struct dotlock_handle;
+typedef struct dotlock_handle *dotlock_t;
+
+void dotlock_disable (void);
+dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags);
+void dotlock_set_fd (dotlock_t h, int fd);
+int  dotlock_get_fd (dotlock_t h);
+void dotlock_destroy (dotlock_t h);
+int dotlock_take (dotlock_t h, long timeout);
+int dotlock_release (dotlock_t h);
+void dotlock_remove_lockfiles (void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*LIBJNLIB_DOTLOCK_H*/
diff --git a/common/dynload.h b/common/dynload.h
new file mode 100644 (file)
index 0000000..e029b2b
--- /dev/null
@@ -0,0 +1,97 @@
+/* dynload.h - Wrapper functions for run-time dynamic loading
+ *      Copyright (C) 2003, 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBJNLIB_DYNLOAD_H
+#define LIBJNLIB_DYNLOAD_H
+
+#ifndef __MINGW32__
+# include <dlfcn.h>
+#else
+# include <windows.h>
+# include "utf8conv.h"
+# include "mischelp.h"
+# define RTLD_LAZY 0
+
+static inline void *
+dlopen (const char *name, int flag)
+{
+  void *hd;
+#ifdef HAVE_W32CE_SYSTEM
+  wchar_t *wname = utf8_to_wchar (name);
+  hd = wname? LoadLibrary (wname) : NULL;
+  _jnlib_free (wname);
+#else
+  hd = LoadLibrary (name);
+#endif
+  (void)flag;
+  return hd;
+}
+
+static inline void *
+dlsym (void *hd, const char *sym)
+{
+  if (hd && sym)
+    {
+#ifdef HAVE_W32CE_SYSTEM
+      wchar_t *wsym = utf8_to_wchar (sym);
+      void *fnc = wsym? GetProcAddress (hd, wsym) : NULL;
+      _jnlib_free (wsym);
+#else
+      void *fnc = GetProcAddress (hd, sym);
+#endif
+      if (!fnc)
+        return NULL;
+      return fnc;
+    }
+  return NULL;
+}
+
+
+static inline const char *
+dlerror (void)
+{
+  static char buf[32];
+  snprintf (buf, sizeof buf, "ec=%lu", GetLastError ());
+  return buf;
+}
+
+
+static inline int
+dlclose (void * hd)
+{
+  if (hd)
+    {
+      CloseHandle (hd);
+      return 0;
+    }
+  return -1;
+}
+# endif /*__MINGW32__*/
+#endif /*LIBJNLIB_DYNLOAD_H*/
diff --git a/common/estream-printf.c b/common/estream-printf.c
deleted file mode 100644 (file)
index 91917cf..0000000
+++ /dev/null
@@ -1,1790 +0,0 @@
-/* estream-printf.c - Versatile C-99 compliant printf formatting
- * Copyright (C) 2007, 2008, 2009 g10 Code GmbH
- *
- * This file is part of Libestream.
- *
- * Libestream 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.
- *
- * Libestream 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 Libestream; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*  Required autoconf tests:
-
-    AC_TYPE_LONG_LONG_INT            defines HAVE_LONG_LONG_INT
-    AC_TYPE_LONG_DOUBLE              defines HAVE_LONG_DOUBLE
-    AC_TYPE_INTMAX_T                 defines HAVE_INTMAX_T
-    AC_TYPE_UINTMAX_T                defines HAVE_UINTMAX_T
-    AC_CHECK_TYPES([ptrdiff_t])      defines HAVE_PTRDIFF_T
-    AC_CHECK_SIZEOF([unsigned long]) defines SIZEOF_UNSIGNED_LONG
-    AC_CHECK_SIZEOF([void *])        defines SIZEOF_VOID_P
-                                             HAVE_LANGINFO_THOUSANDS_SEP
-
-    Note that the file estream.m4 provides the autoconf macro
-    ESTREAM_PRINTF_INIT which runs all required checks.
-    See estream-printf.h for ways to tune this code.
-
-  Missing stuff:  wchar and wint_t
-                  thousands_sep in pr_float.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <stddef.h>
-#include <assert.h>
-#if defined(HAVE_INTMAX_T) || defined(HAVE_UINTMAX_T)
-# ifdef HAVE_STDINT_H
-#  include <stdint.h>
-# endif
-#endif
-#ifdef HAVE_LANGINFO_THOUSANDS_SEP
-#include <langinfo.h>
-#endif
-#ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE
-# include _ESTREAM_PRINTF_EXTRA_INCLUDE
-#endif
-#include "estream-printf.h"
-
-/* #define DEBUG 1 */
-
-
-/* Allow redefinition of asprintf used malloc functions.  */
-#if defined(_ESTREAM_PRINTF_MALLOC)
-#define my_printf_malloc(a) _ESTREAM_PRINTF_MALLOC((a))
-#else
-#define my_printf_malloc(a) malloc((a))
-#endif
-#if defined(_ESTREAM_PRINTF_FREE)
-#define my_printf_free(a)   _ESTREAM_PRINTF_FREE((a))
-#else
-#define my_printf_free(a)   free((a))
-#endif
-
-
-/* Calculate array dimension.  */
-#ifndef DIM
-#define DIM(array) (sizeof (array) / sizeof (*array))
-#endif
-
-
-/* We allow for that many args without requiring malloced memory. */
-#define DEFAULT_MAX_ARGSPECS  5
-
-/* We allow for that many values without requiring malloced memory. */
-#define DEFAULT_MAX_VALUES  8
-
-/* We allocate this many new array argspec elements each time.  */
-#define ARGSPECS_BUMP_VALUE   10
-
-/* Special values for the field width and the precision.  */
-#define NO_FIELD_VALUE   (-1)
-#define STAR_FIELD_VALUE (-2)
-
-/* Bit valuues used for the conversion flags. */
-#define FLAG_GROUPING   1
-#define FLAG_LEFT_JUST  2
-#define FLAG_PLUS_SIGN  4
-#define FLAG_SPACE_PLUS 8
-#define FLAG_ALT_CONV   16
-#define FLAG_ZERO_PAD   32
-
-/* Constants used the length modifiers.  */
-typedef enum
-  {
-    LENMOD_NONE = 0,
-    LENMOD_CHAR,     /* "hh" */
-    LENMOD_SHORT,    /* "h"  */
-    LENMOD_LONG,     /* "l"  */
-    LENMOD_LONGLONG, /* "ll" */
-    LENMOD_INTMAX,   /* "j"  */
-    LENMOD_SIZET,    /* "z"  */
-    LENMOD_PTRDIFF,  /* "t"  */
-    LENMOD_LONGDBL   /* "L"  */
-  } lenmod_t;
-
-/* All the conversion specifiers.  */
-typedef enum
-  {
-    CONSPEC_UNKNOWN = 0,
-    CONSPEC_DECIMAL,
-    CONSPEC_OCTAL,
-    CONSPEC_UNSIGNED,
-    CONSPEC_HEX,
-    CONSPEC_HEX_UP,
-    CONSPEC_FLOAT,
-    CONSPEC_FLOAT_UP,
-    CONSPEC_EXP,
-    CONSPEC_EXP_UP,
-    CONSPEC_F_OR_G,
-    CONSPEC_F_OR_G_UP,
-    CONSPEC_HEX_EXP,
-    CONSPEC_HEX_EXP_UP,
-    CONSPEC_CHAR,
-    CONSPEC_STRING,
-    CONSPEC_POINTER,
-    CONSPEC_STRERROR,
-    CONSPEC_BYTES_SO_FAR
-  } conspec_t;
-
-
-/* Constants describing all the suppoorted types.  Note that we list
-   all the types we know about even if certain types are not available
-   on this system. */
-typedef enum
-  {
-    VALTYPE_UNSUPPORTED = 0,  /* Artificial type for error detection.  */
-    VALTYPE_CHAR,
-    VALTYPE_SCHAR,
-    VALTYPE_UCHAR,
-    VALTYPE_SHORT,
-    VALTYPE_USHORT,
-    VALTYPE_INT,
-    VALTYPE_UINT,
-    VALTYPE_LONG,
-    VALTYPE_ULONG,
-    VALTYPE_LONGLONG,
-    VALTYPE_ULONGLONG,
-    VALTYPE_DOUBLE,
-    VALTYPE_LONGDOUBLE,
-    VALTYPE_STRING,
-    VALTYPE_INTMAX,
-    VALTYPE_UINTMAX,
-    VALTYPE_SIZE,
-    VALTYPE_PTRDIFF,
-    VALTYPE_POINTER,
-    VALTYPE_CHAR_PTR,
-    VALTYPE_SCHAR_PTR,
-    VALTYPE_SHORT_PTR,
-    VALTYPE_INT_PTR,
-    VALTYPE_LONG_PTR,
-    VALTYPE_LONGLONG_PTR,
-    VALTYPE_INTMAX_PTR,
-    VALTYPE_SIZE_PTR,
-    VALTYPE_PTRDIFF_PTR
-  } valtype_t;
-
-
-/* A union used to store the actual values. */
-typedef union
-{
-  char a_char;
-  signed char a_schar;
-  unsigned char a_uchar;
-  short a_short;
-  unsigned short a_ushort;
-  int a_int;
-  unsigned int a_uint;
-  long int a_long;
-  unsigned long int a_ulong;
-#ifdef HAVE_LONG_LONG_INT
-  long long int a_longlong;
-  unsigned long long int a_ulonglong;
-#endif
-  double a_double;
-#ifdef HAVE_LONG_DOUBLE
-  long double a_longdouble;
-#endif
-  const char *a_string;
-#ifdef HAVE_INTMAX_T
-  intmax_t a_intmax;
-#endif
-#ifdef HAVE_UINTMAX_T
-  intmax_t a_uintmax;
-#endif
-  size_t a_size;
-#ifdef HAVE_PTRDIFF_T
-  ptrdiff_t a_ptrdiff;
-#endif
-  void *a_void_ptr;
-  char *a_char_ptr;
-  signed char *a_schar_ptr;
-  short *a_short_ptr;
-  int  *a_int_ptr;
-  long *a_long_ptr;
-#ifdef HAVE_LONG_LONG_INT
-  long long int *a_longlong_ptr;
-#endif
-#ifdef HAVE_INTMAX_T
-  intmax_t *a_intmax_ptr;
-#endif
-  size_t *a_size_ptr;
-#ifdef HAVE_PTRDIFF_T
-  ptrdiff_t *a_ptrdiff_ptr;
-#endif
-} value_t;
-
-/* An object used to keep track of a format option and arguments. */
-struct argspec_s
-{
-  size_t length;       /* The length of these args including the percent.  */
-  unsigned int flags;  /* The conversion flags (bits defined by FLAG_foo).  */
-  int width;           /* The field width.  */
-  int precision;       /* The precision.  */
-  lenmod_t lenmod;     /* The length modifier.  */
-  conspec_t conspec;   /* The conversion specifier.  */
-  int arg_pos;         /* The position of the argument.  This one may
-                          be -1 to indicate that no value is expected
-                          (e.g. for "%m").  */
-  int width_pos;       /* The position of the argument for a field
-                          width star's value. 0 for not used.  */
-  int precision_pos;   /* The position of the argument for the a
-                          precision star's value.  0 for not used. */
-  valtype_t vt;        /* The type of the corresponding argument.  */
-};
-typedef struct argspec_s *argspec_t;
-
-/* An object to build up a table of values and their types.  */
-struct valueitem_s
-{
-  valtype_t vt;  /* The type of the value.  */
-  value_t value; /* The value.  */
-};
-typedef struct valueitem_s *valueitem_t;
-
-
-#ifdef DEBUG
-static void
-dump_argspecs (argspec_t arg, size_t argcount)
-{
-  int idx;
-
-  for (idx=0; argcount; argcount--, arg++, idx++)
-    fprintf (stderr,
-             "%2d: len=%u flags=%u width=%d prec=%d mod=%d "
-             "con=%d vt=%d pos=%d-%d-%d\n",
-             idx,
-             (unsigned int)arg->length,
-             arg->flags,
-             arg->width,
-             arg->precision,
-             arg->lenmod,
-             arg->conspec,
-             arg->vt,
-             arg->arg_pos,
-             arg->width_pos,
-             arg->precision_pos);
-}
-#endif /*DEBUG*/
-
-
-/* Set the vt field for ARG.  */
-static void
-compute_type (argspec_t arg)
-{
-  switch (arg->conspec)
-    {
-    case CONSPEC_UNKNOWN:
-      arg->vt = VALTYPE_UNSUPPORTED;
-      break;
-
-    case CONSPEC_DECIMAL:
-      switch (arg->lenmod)
-        {
-        case LENMOD_CHAR: arg->vt = VALTYPE_SCHAR; break;
-        case LENMOD_SHORT: arg->vt = VALTYPE_SHORT; break;
-        case LENMOD_LONG: arg->vt = VALTYPE_LONG; break;
-        case LENMOD_LONGLONG: arg->vt = VALTYPE_LONGLONG; break;
-        case LENMOD_INTMAX: arg->vt = VALTYPE_INTMAX; break;
-        case LENMOD_SIZET: arg->vt = VALTYPE_SIZE; break;
-        case LENMOD_PTRDIFF: arg->vt = VALTYPE_PTRDIFF; break;
-        default: arg->vt = VALTYPE_INT; break;
-        }
-      break;
-
-    case CONSPEC_OCTAL:
-    case CONSPEC_UNSIGNED:
-    case CONSPEC_HEX:
-    case CONSPEC_HEX_UP:
-      switch (arg->lenmod)
-        {
-        case LENMOD_CHAR: arg->vt = VALTYPE_UCHAR; break;
-        case LENMOD_SHORT: arg->vt = VALTYPE_USHORT; break;
-        case LENMOD_LONG: arg->vt = VALTYPE_ULONG; break;
-        case LENMOD_LONGLONG: arg->vt = VALTYPE_ULONGLONG; break;
-        case LENMOD_INTMAX: arg->vt = VALTYPE_UINTMAX; break;
-        case LENMOD_SIZET: arg->vt = VALTYPE_SIZE; break;
-        case LENMOD_PTRDIFF: arg->vt = VALTYPE_PTRDIFF; break;
-        default: arg->vt = VALTYPE_UINT; break;
-        }
-      break;
-
-    case CONSPEC_FLOAT:
-    case CONSPEC_FLOAT_UP:
-    case CONSPEC_EXP:
-    case CONSPEC_EXP_UP:
-    case CONSPEC_F_OR_G:
-    case CONSPEC_F_OR_G_UP:
-    case CONSPEC_HEX_EXP:
-    case CONSPEC_HEX_EXP_UP:
-      switch (arg->lenmod)
-        {
-        case LENMOD_LONGDBL: arg->vt = VALTYPE_LONGDOUBLE; break;
-        case LENMOD_LONG: arg->vt = VALTYPE_DOUBLE; break;
-        default: arg->vt = VALTYPE_DOUBLE; break;
-        }
-      break;
-
-    case CONSPEC_CHAR:
-      arg->vt = VALTYPE_INT;
-      break;
-
-    case CONSPEC_STRING:
-      arg->vt = VALTYPE_STRING;
-      break;
-
-    case CONSPEC_POINTER:
-      arg->vt = VALTYPE_POINTER;
-      break;
-
-    case CONSPEC_STRERROR:
-      arg->vt = VALTYPE_STRING;
-      break;
-
-    case CONSPEC_BYTES_SO_FAR:
-      switch (arg->lenmod)
-        {
-        case LENMOD_CHAR: arg->vt = VALTYPE_SCHAR_PTR; break;
-        case LENMOD_SHORT: arg->vt = VALTYPE_SHORT_PTR; break;
-        case LENMOD_LONG: arg->vt = VALTYPE_LONG_PTR; break;
-        case LENMOD_LONGLONG: arg->vt = VALTYPE_LONGLONG_PTR; break;
-        case LENMOD_INTMAX: arg->vt = VALTYPE_INTMAX_PTR; break;
-        case LENMOD_SIZET: arg->vt = VALTYPE_SIZE_PTR; break;
-        case LENMOD_PTRDIFF: arg->vt = VALTYPE_PTRDIFF_PTR; break;
-        default: arg->vt = VALTYPE_INT_PTR; break;
-        }
-      break;
-
-    }
-}
-
-
-
-/* Parse the FORMAT string and populate the specification array stored
-   at the address ARGSPECS_ADDR.  The caller has provided enough space
-   to store up to MAX_ARGSPECS in that buffer.  The function may
-   however ignore the provided buffer and malloc a larger one.  On
-   success the addrrss of that larger buffer will be stored at
-   ARGSPECS_ADDR.  The actual number of specifications will be
-   returned at R_ARGSPECS_COUNT. */
-static int
-parse_format (const char *format,
-              argspec_t *argspecs_addr, size_t max_argspecs,
-              size_t *r_argspecs_count)
-{
-  const char *s;
-  argspec_t argspecs = *argspecs_addr;
-  argspec_t arg;
-  size_t argcount = 0;
-
-  if (!format)
-    goto leave_einval;
-
-  for (; *format; format++)
-    {
-      unsigned int flags;
-      int width, precision;
-      lenmod_t lenmod;
-      conspec_t conspec;
-      int arg_pos, width_pos, precision_pos;
-
-      if (*format != '%')
-        continue;
-      s = ++format;
-      if (!*s)
-        goto leave_einval;
-      if (*s == '%')
-        continue; /* Just a quoted percent.  */
-
-      /* First check whether there is a positional argument.  */
-      arg_pos = 0; /* No positional argument given.  */
-      if (*s >= '1' && *s <= '9')
-        {
-          const char *save_s = s;
-
-          arg_pos = (*s++ - '0');
-          for (; *s >= '0' && *s <= '9'; s++)
-            arg_pos = 10*arg_pos + (*s - '0');
-          if (arg_pos < 0)
-            goto leave_einval; /* Overflow during conversion.  */
-          if (*s == '$')
-            s++;
-          else
-            {
-              arg_pos = 0;
-              s = save_s;
-            }
-        }
-
-      /* Parse the flags.  */
-      flags = 0;
-      for ( ; *s; s++)
-        {
-          switch (*s)
-            {
-            case '\'': flags |= FLAG_GROUPING; break;
-            case '-': flags |= FLAG_LEFT_JUST; break;
-            case '+': flags |= FLAG_PLUS_SIGN; break;
-            case ' ': flags |= FLAG_SPACE_PLUS; break;
-            case '#': flags |= FLAG_ALT_CONV; break;
-            case '0': flags |= FLAG_ZERO_PAD; break;
-            default:
-              goto flags_parsed;
-            }
-        }
-    flags_parsed:
-
-      /* Parse the field width.  */
-      width_pos = 0;
-      if (*s == '*')
-        {
-          width = STAR_FIELD_VALUE;
-          s++;
-          /* If we have a positional argument, another one might also
-             be used to give the position of the star's value. */
-          if (arg_pos && *s >= '1' && *s <= '9')
-            {
-              width_pos = (*s++ - '0');
-              for (; *s >= '0' && *s <= '9'; s++)
-                width_pos = 10*width_pos + (*s - '0');
-              if (width_pos < 1)
-                goto leave_einval; /* Overflow during conversion.  */
-              if (*s != '$')
-                goto leave_einval; /* Not followed by $.  */
-              s++;
-            }
-        }
-      else if ( *s >= '0' && *s <= '9')
-        {
-          width = (*s++ - '0');
-          for (; *s >= '0' && *s <= '9'; s++)
-            {
-              if (!width && *s == '0')
-                goto leave_einval; /* Leading zeroes are not allowed.
-                                      Fixme: check what other
-                                      implementations do. */
-              width = 10*width + (*s - '0');
-            }
-          if (width < 0)
-            goto leave_einval; /* Overflow during conversion.  */
-        }
-      else
-        width = NO_FIELD_VALUE;
-
-      /* Parse the precision.  */
-      precision_pos = 0;
-      precision = NO_FIELD_VALUE;
-      if (*s == '.')
-        {
-          int ignore_value = (s[1] == '-');
-
-          s++;
-          if (*s == '*')
-            {
-              precision = STAR_FIELD_VALUE;
-              s++;
-              /* If we have a positional argument, another one might also
-                 be used to give the position of the star's value. */
-              if (arg_pos && *s >= '1' && *s <= '9')
-                {
-                  precision_pos = (*s++ - '0');
-                  for (; *s >= '0' && *s <= '9'; s++)
-                    precision_pos = 10*precision_pos + (*s - '0');
-                  if (precision_pos < 1)
-                    goto leave_einval; /* Overflow during conversion.  */
-                  if (*s != '$')
-                    goto leave_einval; /* Not followed by $.  */
-                  s++;
-                }
-            }
-          else if ( *s >= '0' && *s <= '9')
-            {
-              precision = (*s++ - '0');
-              for (; *s >= '0' && *s <= '9'; s++)
-                {
-                  if (!precision && *s == '0')
-                    goto leave_einval; /* Leading zeroes are not allowed.
-                                          Fixme: check what other
-                                          implementations do. */
-                  precision = 10*precision + (*s - '0');
-                }
-              if (precision < 0)
-                goto leave_einval; /* Overflow during conversion.  */
-            }
-          else
-            precision = 0;
-          if (ignore_value)
-            precision = NO_FIELD_VALUE;
-        }
-
-      /* Parse the length modifiers.  */
-      switch (*s)
-        {
-        case 'h':
-          if (s[1] == 'h')
-            {
-              lenmod = LENMOD_CHAR;
-              s++;
-            }
-          else
-            lenmod = LENMOD_SHORT;
-          s++;
-          break;
-        case 'l':
-          if (s[1] == 'l')
-            {
-              lenmod = LENMOD_LONGLONG;
-              s++;
-            }
-          else
-            lenmod = LENMOD_LONG;
-          s++;
-          break;
-        case 'j': lenmod = LENMOD_INTMAX; s++; break;
-        case 'z': lenmod = LENMOD_SIZET; s++; break;
-        case 't': lenmod = LENMOD_PTRDIFF; s++; break;
-        case 'L': lenmod = LENMOD_LONGDBL; s++; break;
-        default:  lenmod = LENMOD_NONE; break;
-        }
-
-      /* Parse the conversion specifier.  */
-      switch (*s)
-        {
-        case 'd':
-        case 'i': conspec = CONSPEC_DECIMAL; break;
-        case 'o': conspec = CONSPEC_OCTAL; break;
-        case 'u': conspec = CONSPEC_UNSIGNED; break;
-        case 'x': conspec = CONSPEC_HEX; break;
-        case 'X': conspec = CONSPEC_HEX_UP; break;
-        case 'f': conspec = CONSPEC_FLOAT; break;
-        case 'F': conspec = CONSPEC_FLOAT_UP; break;
-        case 'e': conspec = CONSPEC_EXP; break;
-        case 'E': conspec = CONSPEC_EXP_UP; break;
-        case 'g': conspec = CONSPEC_F_OR_G; break;
-        case 'G': conspec = CONSPEC_F_OR_G_UP; break;
-        case 'a': conspec = CONSPEC_HEX_EXP; break;
-        case 'A': conspec = CONSPEC_HEX_EXP_UP; break;
-        case 'c': conspec = CONSPEC_CHAR; break;
-        case 's': conspec = CONSPEC_STRING; break;
-        case 'p': conspec = CONSPEC_POINTER; break;
-        case 'n': conspec = CONSPEC_BYTES_SO_FAR; break;
-        case 'C': conspec = CONSPEC_CHAR; lenmod = LENMOD_LONG; break;
-        case 'S': conspec = CONSPEC_STRING; lenmod = LENMOD_LONG; break;
-        case 'm': conspec = CONSPEC_STRERROR; arg_pos = -1; break;
-        default: conspec = CONSPEC_UNKNOWN;
-        }
-
-      /* Save the args. */
-      if (argcount >= max_argspecs)
-        {
-          /* We either need to allocate a new array instead of the
-             caller provided one or realloc the array.  Instead of
-             using realloc we allocate a new one and release the
-             original one then. */
-          size_t n, newmax;
-          argspec_t newarg;
-
-          newmax = max_argspecs + ARGSPECS_BUMP_VALUE;
-          if (newmax <= max_argspecs)
-            goto leave_einval;  /* Too many arguments. */
-          newarg = calloc (newmax, sizeof *newarg);
-          if (!newarg)
-            goto leave;
-          for (n=0; n < argcount; n++)
-            newarg[n] = argspecs[n];
-          if (argspecs != *argspecs_addr)
-            free (argspecs);
-          argspecs = newarg;
-          max_argspecs = newmax;
-        }
-
-      arg = argspecs + argcount;
-      arg->length = s - format + 2;
-      arg->flags = flags;
-      arg->width = width;
-      arg->precision = precision;
-      arg->lenmod = lenmod;
-      arg->conspec = conspec;
-      arg->arg_pos = arg_pos;
-      arg->width_pos = width_pos;
-      arg->precision_pos = precision_pos;
-      compute_type (arg);
-      argcount++;
-      format = s;
-    }
-
-  *argspecs_addr = argspecs;
-  *r_argspecs_count = argcount;
-  return 0; /* Success.  */
-
- leave_einval:
-  errno = EINVAL;
- leave:
-  if (argspecs != *argspecs_addr)
-    free (argspecs);
-  *argspecs_addr = NULL;
-  return -1;
-}
-
-
-/* This function reads all the values as specified by VALUETABLE into
-   VALUETABLE.  The values are expected in VAARGS.  The function
-   returns -1 if a specified type is not supported. */
-static int
-read_values (valueitem_t valuetable, size_t valuetable_len, va_list vaargs)
-{
-  int validx;
-
-  for (validx=0; validx < valuetable_len; validx++)
-    {
-      value_t *value = &valuetable[validx].value;
-      valtype_t vt = valuetable[validx].vt;
-
-      switch (vt)
-        {
-        case VALTYPE_CHAR: value->a_char = va_arg (vaargs, int); break;
-        case VALTYPE_CHAR_PTR:
-          value->a_char_ptr = va_arg (vaargs, char *);
-          break;
-        case VALTYPE_SCHAR: value->a_schar = va_arg (vaargs, int); break;
-        case VALTYPE_SCHAR_PTR:
-          value->a_schar_ptr = va_arg (vaargs, signed char *);
-          break;
-        case VALTYPE_UCHAR: value->a_uchar = va_arg (vaargs, int); break;
-        case VALTYPE_SHORT: value->a_short = va_arg (vaargs, int); break;
-        case VALTYPE_USHORT: value->a_ushort = va_arg (vaargs, int); break;
-        case VALTYPE_SHORT_PTR:
-          value->a_short_ptr = va_arg (vaargs, short *);
-          break;
-        case VALTYPE_INT:
-          value->a_int = va_arg (vaargs, int);
-          break;
-        case VALTYPE_INT_PTR:
-          value->a_int_ptr = va_arg (vaargs, int *);
-          break;
-        case VALTYPE_UINT:
-          value->a_uint = va_arg (vaargs, unsigned int);
-          break;
-        case VALTYPE_LONG:
-          value->a_long = va_arg (vaargs, long);
-          break;
-        case VALTYPE_ULONG:
-          value->a_ulong = va_arg (vaargs, unsigned long);
-          break;
-        case VALTYPE_LONG_PTR:
-          value->a_long_ptr = va_arg (vaargs, long *);
-          break;
-#ifdef HAVE_LONG_LONG_INT
-        case VALTYPE_LONGLONG:
-          value->a_longlong = va_arg (vaargs, long long int);
-          break;
-        case VALTYPE_ULONGLONG:
-          value->a_ulonglong = va_arg (vaargs, unsigned long long int);
-          break;
-        case VALTYPE_LONGLONG_PTR:
-          value->a_longlong_ptr = va_arg (vaargs, long long *);
-          break;
-#endif
-        case VALTYPE_DOUBLE:
-          value->a_double = va_arg (vaargs, double);
-          break;
-#ifdef HAVE_LONG_DOUBLE
-        case VALTYPE_LONGDOUBLE:
-          value->a_longdouble = va_arg (vaargs, long double);
-          break;
-#endif
-        case VALTYPE_STRING:
-          value->a_string = va_arg (vaargs, const char *);
-          break;
-        case VALTYPE_POINTER:
-          value->a_void_ptr = va_arg (vaargs, void *);
-          break;
-#ifdef HAVE_INTMAX_T
-        case VALTYPE_INTMAX:
-          value->a_intmax = va_arg (vaargs, intmax_t);
-          break;
-        case VALTYPE_INTMAX_PTR:
-          value->a_intmax_ptr = va_arg (vaargs, intmax_t *);
-          break;
-#endif
-#ifdef HAVE_UINTMAX_T
-        case VALTYPE_UINTMAX:
-          value->a_uintmax = va_arg (vaargs, uintmax_t);
-          break;
-#endif
-        case VALTYPE_SIZE:
-          value->a_size = va_arg (vaargs, size_t);
-          break;
-        case VALTYPE_SIZE_PTR:
-          value->a_size_ptr = va_arg (vaargs, size_t *);
-          break;
-#ifdef HAVE_PTRDIFF_T
-        case VALTYPE_PTRDIFF:
-          value->a_ptrdiff = va_arg (vaargs, ptrdiff_t);
-          break;
-        case VALTYPE_PTRDIFF_PTR:
-          value->a_ptrdiff_ptr = va_arg (vaargs, ptrdiff_t *);
-          break;
-#endif
-        default: /* Unsupported type.  */
-          return -1;
-        }
-    }
-  return 0;
-}
-
-
-\f
-/* Output COUNT padding characters PADCHAR and update NBYTES by the
-   number of bytes actually written.  */
-static int
-pad_out (estream_printf_out_t outfnc, void *outfncarg,
-         int padchar, int count, size_t *nbytes)
-{
-  char buf[32];
-  size_t n;
-  int rc;
-
-  while (count > 0)
-    {
-      n = (count <= sizeof buf)? count : sizeof buf;
-      memset (buf, padchar, n);
-      rc = outfnc (outfncarg, buf, n);
-      if (rc)
-        return rc;
-      *nbytes += n;
-      count -= n;
-    }
-
-  return 0;
-}
-
-
-/* "d,i,o,u,x,X" formatting.  OUTFNC and OUTFNCARG describes the
-   output routine, ARG gives the argument description and VALUE the
-   actual value (its type is available through arg->vt).  */
-static int
-pr_integer (estream_printf_out_t outfnc, void *outfncarg,
-            argspec_t arg, value_t value, size_t *nbytes)
-{
-  int rc;
-#ifdef HAVE_LONG_LONG_INT
-  unsigned long long aulong;
-#else
-  unsigned long aulong;
-#endif
-  char numbuf[100];
-  char *p, *pend;
-  size_t n;
-  char signchar = 0;
-  int n_prec;  /* Number of extra precision digits required.  */
-  int n_extra; /* Extra number of prefix or sign characters.  */
-
-  if (arg->conspec == CONSPEC_DECIMAL)
-    {
-#ifdef HAVE_LONG_LONG_INT
-      long long along;
-#else
-      long along;
-#endif
-
-      switch (arg->vt)
-        {
-        case VALTYPE_SHORT: along = value.a_short; break;
-        case VALTYPE_INT: along = value.a_int; break;
-        case VALTYPE_LONG: along = value.a_long; break;
-#ifdef HAVE_LONG_LONG_INT
-        case VALTYPE_LONGLONG: along = value.a_longlong; break;
-        case VALTYPE_SIZE: along = value.a_size; break;
-# ifdef HAVE_INTMAX_T
-        case VALTYPE_INTMAX: along = value.a_intmax; break;
-# endif
-# ifdef HAVE_PTRDIFF_T
-        case VALTYPE_PTRDIFF: along = value.a_ptrdiff; break;
-# endif
-#endif /*HAVE_LONG_LONG_INT*/
-        default:
-          return -1;
-        }
-      if (along < 0)
-        {
-          aulong = -along;
-          signchar = '-';
-        }
-      else
-        aulong = along;
-    }
-  else
-    {
-      switch (arg->vt)
-        {
-        case VALTYPE_USHORT: aulong = value.a_ushort; break;
-        case VALTYPE_UINT: aulong = value.a_uint; break;
-        case VALTYPE_ULONG: aulong = value.a_ulong; break;
-#ifdef HAVE_LONG_LONG_INT
-        case VALTYPE_ULONGLONG: aulong = value.a_ulonglong; break;
-        case VALTYPE_SIZE: aulong = value.a_size; break;
-# ifdef HAVE_UINTMAX_T
-        case VALTYPE_UINTMAX: aulong = value.a_uintmax; break;
-# endif
-# ifdef HAVE_PTRDIFF_T
-        case VALTYPE_PTRDIFF: aulong = value.a_ptrdiff; break;
-# endif
-#endif /*HAVE_LONG_LONG_INT*/
-        default:
-          return -1;
-        }
-    }
-
-  if (signchar == '-')
-    ;
-  else if ((arg->flags & FLAG_PLUS_SIGN))
-    signchar = '+';
-  else if ((arg->flags & FLAG_SPACE_PLUS))
-    signchar = ' ';
-
-  n_extra = !!signchar;
-
-  /* We build the string up backwards.  */
-  p = pend = numbuf + DIM(numbuf);
-  if ((!aulong && !arg->precision))
-    ;
-  else if (arg->conspec == CONSPEC_DECIMAL
-           || arg->conspec == CONSPEC_UNSIGNED)
-    {
-      int grouping = -1;
-      const char * grouping_string =
-#ifdef HAVE_LANGINFO_THOUSANDS_SEP
-        nl_langinfo(THOUSANDS_SEP);
-#else
-        "'";
-#endif
-
-      do
-        {
-          if ((arg->flags & FLAG_GROUPING)
-              && (++grouping == 3) && *grouping_string)
-            {
-              *--p = *grouping_string;
-              grouping = 0;
-            }
-          *--p = '0' + (aulong % 10);
-          aulong /= 10;
-        }
-      while (aulong);
-    }
-  else if (arg->conspec == CONSPEC_OCTAL)
-    {
-      do
-        {
-          *--p = '0' + (aulong % 8);
-          aulong /= 8;
-        }
-      while (aulong);
-      if ((arg->flags & FLAG_ALT_CONV) && *p != '0')
-        *--p = '0';
-    }
-  else /* HEX or HEXUP */
-    {
-      const char *digits = ((arg->conspec == CONSPEC_HEX)
-                            ? "0123456789abcdef" : "0123456789ABCDEF");
-      do
-        {
-          *--p = digits[(aulong % 16)];
-          aulong /= 16;
-        }
-      while (aulong);
-      if ((arg->flags & FLAG_ALT_CONV))
-        n_extra += 2;
-    }
-
-  n = pend - p;
-
-  if ((arg->flags & FLAG_ZERO_PAD)
-      && arg->precision == NO_FIELD_VALUE && !(arg->flags & FLAG_LEFT_JUST)
-      && n && arg->width - n_extra > n )
-    n_prec = arg->width - n_extra - n;
-  else if (arg->precision > 0 && arg->precision > n)
-    n_prec = arg->precision - n;
-  else
-    n_prec = 0;
-
-  if (!(arg->flags & FLAG_LEFT_JUST)
-      && arg->width >= 0 && arg->width - n_extra > n
-      && arg->width - n_extra - n >= n_prec )
-    {
-      rc = pad_out (outfnc, outfncarg, ' ',
-                    arg->width - n_extra - n - n_prec, nbytes);
-      if (rc)
-        return rc;
-    }
-
-  if (signchar)
-    {
-      rc = outfnc (outfncarg, &signchar, 1);
-      if (rc)
-        return rc;
-      *nbytes += 1;
-    }
-
-  if ((arg->flags & FLAG_ALT_CONV)
-      && (arg->conspec == CONSPEC_HEX || arg->conspec == CONSPEC_HEX_UP))
-    {
-      rc = outfnc (outfncarg, arg->conspec == CONSPEC_HEX? "0x": "0X", 2);
-      if (rc)
-        return rc;
-      *nbytes += 2;
-    }
-
-  if (n_prec)
-    {
-      rc = pad_out (outfnc, outfncarg, '0', n_prec, nbytes);
-      if (rc)
-        return rc;
-    }
-
-  rc = outfnc (outfncarg, p, pend - p);
-  if (rc)
-    return rc;
-  *nbytes += pend - p;
-
-  if ((arg->flags & FLAG_LEFT_JUST)
-      && arg->width >= 0 && arg->width - n_extra - n_prec > n)
-    {
-      rc = pad_out (outfnc, outfncarg, ' ',
-                    arg->width - n_extra - n_prec - n, nbytes);
-      if (rc)
-        return rc;
-    }
-
-  return 0;
-}
-
-
-/* "e,E,f,F,g,G,a,A" formatting.  OUTFNC and OUTFNCARG describes the
-   output routine, ARG gives the argument description and VALUE the
-   actual value (its type is available through arg->vt).  For
-   portability reasons sprintf is used for the actual formatting.
-   This is useful because sprint is the only standard function to
-   convert a floating number into its ascii representation.  To avoid
-   using malloc we just pass the precision to sprintf and do the final
-   formatting with our own code.  */
-static int
-pr_float (estream_printf_out_t outfnc, void *outfncarg,
-          argspec_t arg, value_t value, size_t *nbytes)
-{
-  int rc;
-#ifdef HAVE_LONG_DOUBLE
-  long double adblfloat = 0; /* Just to please gcc.  */
-  int use_dbl = 0;
-#endif
-  double afloat;
-  char numbuf[350];
-  char formatstr[20];
-  char *p, *pend;
-  size_t n;
-  char signchar = 0;
-  int n_extra;  /* Extra number of prefix or sign characters.  */
-
-  switch (arg->vt)
-    {
-    case VALTYPE_DOUBLE: afloat = value.a_double; break;
-#ifdef HAVE_LONG_DOUBLE
-    case VALTYPE_LONGDOUBLE:
-      afloat = 0;  /* Just to please gcc.  */
-      adblfloat = value.a_longdouble;
-      use_dbl=1; break;
-#endif
-    default:
-      return -1;
-    }
-
-  /* We build the string using sprint.  */
-  p = formatstr + sizeof formatstr;
-  *--p = 0;
-  switch (arg->conspec)
-    {
-    case CONSPEC_FLOAT:      *--p = 'f'; break;
-    case CONSPEC_FLOAT_UP:   *--p = 'F'; break;
-    case CONSPEC_EXP:        *--p = 'e'; break;
-    case CONSPEC_EXP_UP:     *--p = 'E'; break;
-    case CONSPEC_F_OR_G:     *--p = 'g'; break;
-    case CONSPEC_F_OR_G_UP:  *--p = 'G'; break;
-    case CONSPEC_HEX_EXP:    *--p = 'a'; break;
-    case CONSPEC_HEX_EXP_UP: *--p = 'A'; break;
-    default:
-      return -1; /* Actually a bug.  */
-    }
-#ifdef HAVE_LONG_DOUBLE
-  if (use_dbl)
-    *--p = 'L';
-#endif
-  if (arg->precision != NO_FIELD_VALUE)
-    {
-      /* Limit it to a meaningful value so that even a stupid sprintf
-         won't overflow our buffer.  */
-      n = arg->precision <= 100? arg->precision : 100;
-      do
-        {
-          *--p = '0' + (n % 10);
-          n /= 10;
-        }
-      while (n);
-      *--p = '.';
-    }
-  if ((arg->flags & FLAG_ALT_CONV))
-    *--p = '#';
-  *--p = '%';
-#ifdef HAVE_LONG_DOUBLE
-  if (use_dbl)
-    sprintf (numbuf, p, adblfloat);
-  else
-#endif /*HAVE_LONG_DOUBLE*/
-    sprintf (numbuf, p, afloat);
-  p = numbuf;
-  n = strlen (numbuf);
-  pend = p + n;
-
-  if (*p =='-')
-    {
-      signchar = '-';
-      p++;
-      n--;
-    }
-  else if ((arg->flags & FLAG_PLUS_SIGN))
-    signchar = '+';
-  else if ((arg->flags & FLAG_SPACE_PLUS))
-    signchar = ' ';
-
-  n_extra = !!signchar;
-
-  if (!(arg->flags & FLAG_LEFT_JUST)
-      && arg->width >= 0 && arg->width - n_extra > n)
-    {
-      rc = pad_out (outfnc, outfncarg, ' ', arg->width - n_extra - n, nbytes);
-      if (rc)
-        return rc;
-    }
-
-  if (signchar)
-    {
-      rc = outfnc (outfncarg, &signchar, 1);
-      if (rc)
-        return rc;
-      *nbytes += 1;
-    }
-
-  rc = outfnc (outfncarg, p, pend - p);
-  if (rc)
-    return rc;
-  *nbytes += pend - p;
-
-  if ((arg->flags & FLAG_LEFT_JUST)
-      && arg->width >= 0 && arg->width - n_extra > n)
-    {
-      rc = pad_out (outfnc, outfncarg, ' ', arg->width - n_extra - n, nbytes);
-      if (rc)
-        return rc;
-    }
-
-  return 0;
-}
-
-
-/* "c" formatting.  */
-static int
-pr_char (estream_printf_out_t outfnc, void *outfncarg,
-            argspec_t arg, value_t value, size_t *nbytes)
-{
-  int rc;
-  char buf[1];
-
-  if (arg->vt != VALTYPE_INT)
-    return -1;
-  buf[0] = (unsigned int)value.a_int;
-  rc = outfnc (outfncarg, buf, 1);
-  if(rc)
-    return rc;
-  *nbytes += 1;
-
-  return 0;
-}
-
-
-/* "s" formatting.  */
-static int
-pr_string (estream_printf_out_t outfnc, void *outfncarg,
-            argspec_t arg, value_t value, size_t *nbytes)
-{
-  int rc;
-  size_t n;
-  const char *string, *s;
-
-  if (arg->vt != VALTYPE_STRING)
-    return -1;
-  string = value.a_string;
-  if (!string)
-    string = "(null)";
-  if (arg->precision >= 0)
-    {
-      /* Test for nul after N so that we can pass a non-nul terminated
-         string.  */
-      for (n=0,s=string; n < arg->precision && *s; s++)
-        n++;
-    }
-  else
-    n = strlen (string);
-
-  if (!(arg->flags & FLAG_LEFT_JUST)
-      && arg->width >= 0 && arg->width > n )
-    {
-      rc = pad_out (outfnc, outfncarg, ' ', arg->width - n, nbytes);
-      if (rc)
-        return rc;
-    }
-
-  rc = outfnc (outfncarg, string, n);
-  if (rc)
-    return rc;
-  *nbytes += n;
-
-  if ((arg->flags & FLAG_LEFT_JUST)
-      && arg->width >= 0 && arg->width > n)
-    {
-      rc = pad_out (outfnc, outfncarg, ' ', arg->width - n, nbytes);
-      if (rc)
-        return rc;
-    }
-
-  return 0;
-}
-
-
-/* "p" formatting.  */
-static int
-pr_pointer (estream_printf_out_t outfnc, void *outfncarg,
-            argspec_t arg, value_t value, size_t *nbytes)
-{
-  int rc;
-#if defined(HAVE_LONG_LONG_INT) && (SIZEOF_UNSIGNED_LONG < SIZEOF_VOID_P)
-  unsigned long long aulong;
-#else
-  unsigned long aulong;
-#endif
-  char numbuf[100];
-  char *p, *pend;
-
-  if (arg->vt != VALTYPE_POINTER)
-    return -1;
-  /* We assume that a pointer can be converted to an unsigned long.
-     That is not correct for a 64 bit Windows, but then we assume that
-     long long is supported and usable for storing a pointer.  */
-#if defined(HAVE_LONG_LONG_INT) && (SIZEOF_UNSIGNED_LONG < SIZEOF_VOID_P)
-  aulong = (unsigned long long)value.a_void_ptr;
-#else
-  aulong = (unsigned long)value.a_void_ptr;
-#endif
-
-  p = pend = numbuf + DIM(numbuf);
-  do
-    {
-      *--p = "0123456789abcdefx"[(aulong % 16)];
-      aulong /= 16;
-    }
-  while (aulong);
-  while ((pend-p) < 2*sizeof (aulong))
-    *--p = '0';
-  *--p = 'x';
-  *--p = '0';
-
-  rc = outfnc (outfncarg, p, pend - p);
-  if (rc)
-    return rc;
-  *nbytes += pend - p;
-
-  return 0;
-}
-
-/* "n" pesudo format operation.  */
-static int
-pr_bytes_so_far (estream_printf_out_t outfnc, void *outfncarg,
-                 argspec_t arg, value_t value, size_t *nbytes)
-{
-  (void)outfnc;
-  (void)outfncarg;
-
-  switch (arg->vt)
-    {
-    case VALTYPE_SCHAR_PTR:
-      *value.a_schar_ptr = (signed char)(unsigned int)(*nbytes);
-      break;
-    case VALTYPE_SHORT_PTR:
-      *value.a_short_ptr = (short)(unsigned int)(*nbytes);
-      break;
-    case VALTYPE_LONG_PTR:
-      *value.a_long_ptr = (long)(*nbytes);
-      break;
-#ifdef HAVE_LONG_LONG_INT
-    case VALTYPE_LONGLONG_PTR:
-      *value.a_longlong_ptr = (long long)(*nbytes);
-      break;
-#endif
-#ifdef HAVE_INTMAX_T
-    case VALTYPE_INTMAX_PTR:
-      *value.a_intmax_ptr = (intmax_t)(*nbytes);
-      break;
-#endif
-    case VALTYPE_SIZE_PTR:
-      *value.a_size_ptr = (*nbytes);
-      break;
-#ifdef HAVE_PTRDIFF_T
-    case VALTYPE_PTRDIFF_PTR:
-      *value.a_ptrdiff_ptr = (ptrdiff_t)(*nbytes);
-      break;
-#endif
-    case VALTYPE_INT_PTR:
-      *value.a_int_ptr = (int)(*nbytes);
-      break;
-    default:
-      return -1; /* An unsupported type has been used.  */
-    }
-
-  return 0;
-}
-
-
-
-/* Run the actual formatting.  OUTFNC and OUTFNCARG are the output
-   functions.  FORMAT is format string ARGSPECS is the parsed format
-   string, ARGSPECS_LEN the number of items in ARGSPECS.  VALUETABLE
-   holds the values and may be directly addressed using the position
-   arguments given by ARGSPECS.  MYERRNO is used for the "%m"
-   conversion. NBYTES well be updated to reflect the number of bytes
-   send to the output function. */
-static int
-do_format (estream_printf_out_t outfnc, void *outfncarg,
-           const char *format, argspec_t argspecs, size_t argspecs_len,
-           valueitem_t valuetable, int myerrno, size_t *nbytes)
-{
-  int rc = 0;
-  const char *s;
-  argspec_t arg = argspecs;
-  int argidx = 0; /* Only used for assertion.  */
-  size_t n;
-  value_t value;
-
-  s = format;
-  while ( *s )
-    {
-      if (*s != '%')
-        {
-          s++;
-          continue;
-        }
-      if (s != format)
-        {
-          rc = outfnc (outfncarg, format, (n=s-format));
-          if (rc)
-            return rc;
-          *nbytes += n;
-        }
-      if (s[1] == '%')
-        {
-          /* Note that this code ignores one trailing percent escape -
-             this is however okay as the args parser must have
-             detected this already.  */
-          rc = outfnc (outfncarg, s, 1);
-          if (rc)
-            return rc;
-          *nbytes += 1;
-          s += 2;
-          format = s;
-          continue;
-        }
-
-      /* Save the next start.  */
-      s += arg->length;
-      format = s;
-
-      assert (argidx < argspecs_len);
-      argidx++;
-
-      /* Apply indirect field width and precision values.  */
-      if (arg->width == STAR_FIELD_VALUE)
-        {
-          assert (valuetable[arg->width_pos-1].vt == VALTYPE_INT);
-          arg->width = valuetable[arg->width_pos-1].value.a_int;
-          if (arg->width < 0)
-            {
-              arg->width = -arg->width;
-              arg->flags |= FLAG_LEFT_JUST;
-            }
-        }
-      if (arg->precision == STAR_FIELD_VALUE)
-        {
-          assert (valuetable[arg->precision_pos-1].vt == VALTYPE_INT);
-          arg->precision = valuetable[arg->precision_pos-1].value.a_int;
-          if (arg->precision < 0)
-            arg->precision = NO_FIELD_VALUE;
-        }
-
-      if (arg->arg_pos == -1 && arg->conspec == CONSPEC_STRERROR)
-        value.a_string = strerror (myerrno);
-      else
-        {
-          assert (arg->vt == valuetable[arg->arg_pos-1].vt);
-          value = valuetable[arg->arg_pos-1].value;
-        }
-
-      switch (arg->conspec)
-        {
-        case CONSPEC_UNKNOWN: assert (!"bug"); break;
-
-        case CONSPEC_DECIMAL:
-        case CONSPEC_UNSIGNED:
-        case CONSPEC_OCTAL:
-        case CONSPEC_HEX:
-        case CONSPEC_HEX_UP:
-          rc = pr_integer (outfnc, outfncarg, arg, value, nbytes);
-          break;
-        case CONSPEC_FLOAT:
-        case CONSPEC_FLOAT_UP:
-        case CONSPEC_EXP:
-        case CONSPEC_EXP_UP:
-        case CONSPEC_F_OR_G:
-        case CONSPEC_F_OR_G_UP:
-        case CONSPEC_HEX_EXP:
-        case CONSPEC_HEX_EXP_UP:
-          rc = pr_float (outfnc, outfncarg, arg, value, nbytes);
-          break;
-        case CONSPEC_CHAR:
-          rc = pr_char (outfnc, outfncarg, arg, value, nbytes);
-          break;
-        case CONSPEC_STRING:
-        case CONSPEC_STRERROR:
-          rc = pr_string (outfnc, outfncarg, arg, value, nbytes);
-          break;
-        case CONSPEC_POINTER:
-          rc = pr_pointer (outfnc, outfncarg, arg, value, nbytes);
-          break;
-        case CONSPEC_BYTES_SO_FAR:
-          rc = pr_bytes_so_far (outfnc, outfncarg, arg, value, nbytes);
-          break;
-        }
-      if (rc)
-        return rc;
-      arg++;
-    }
-
-  /* Print out any trailing stuff. */
-  n = s - format;
-  rc = n? outfnc (outfncarg, format, n) : 0;
-  if (!rc)
-    *nbytes += n;
-
-  return rc;
-}
-
-
-
-\f
-/* The versatile printf formatting routine.  It expects a callback
-   function OUTFNC and an opaque argument OUTFNCARG used for actual
-   output of the formatted stuff.  FORMAT is the format specification
-   and VAARGS a variable argumemt list matching the arguments of
-   FORMAT.  */
-int
-estream_format (estream_printf_out_t outfnc,
-                void *outfncarg,
-                const char *format, va_list vaargs)
-{
-  /* Buffer to hold the argspecs and a pointer to it.*/
-  struct argspec_s argspecs_buffer[DEFAULT_MAX_ARGSPECS];
-  argspec_t argspecs = argspecs_buffer;
-  size_t argspecs_len;  /* Number of specifications in ARGSPECS.  */
-
-  /* Buffer to hold the description for the values.  */
-  struct valueitem_s valuetable_buffer[DEFAULT_MAX_VALUES];
-  valueitem_t valuetable = valuetable_buffer;
-
-  int rc;     /* Return code. */
-  size_t argidx; /* Used to index the argspecs array.  */
-  size_t validx; /* Used to index the valuetable.  */
-  int max_pos;/* Highest argument position.  */
-
-  size_t nbytes = 0; /* Keep track of the number of bytes passed to
-                        the output function.  */
-
-  int myerrno = errno; /* Save the errno for use with "%m". */
-
-
-  /* Parse the arguments to come up with descriptive list.  We can't
-     do this on the fly because we need to support positional
-     arguments. */
-  rc = parse_format (format, &argspecs, DIM(argspecs_buffer), &argspecs_len);
-  if (rc)
-    goto leave;
-
-  /* Check that all ARG_POS fields are set.  */
-  for (argidx=0,max_pos=0; argidx < argspecs_len; argidx++)
-    {
-      if (argspecs[argidx].arg_pos != -1
-          && argspecs[argidx].arg_pos > max_pos)
-        max_pos = argspecs[argidx].arg_pos;
-      if (argspecs[argidx].width_pos > max_pos)
-        max_pos = argspecs[argidx].width_pos;
-      if (argspecs[argidx].precision_pos > max_pos)
-        max_pos = argspecs[argidx].precision_pos;
-    }
-  if (!max_pos)
-    {
-      /* Fill in all the positions.  */
-      for (argidx=0; argidx < argspecs_len; argidx++)
-        {
-          if (argspecs[argidx].width == STAR_FIELD_VALUE)
-            argspecs[argidx].width_pos = ++max_pos;
-          if (argspecs[argidx].precision == STAR_FIELD_VALUE)
-            argspecs[argidx].precision_pos = ++max_pos;
-          if (argspecs[argidx].arg_pos != -1 )
-            argspecs[argidx].arg_pos = ++max_pos;
-        }
-    }
-  else
-    {
-      /* Check that they are all filled.   More test are done later.  */
-      for (argidx=0; argidx < argspecs_len; argidx++)
-        {
-          if (!argspecs[argidx].arg_pos
-              || (argspecs[argidx].width == STAR_FIELD_VALUE
-                  && !argspecs[argidx].width_pos)
-              || (argspecs[argidx].precision == STAR_FIELD_VALUE
-                  && !argspecs[argidx].precision_pos))
-            goto leave_einval;
-        }
-    }
-  /* Check that there is no overflow in max_pos and that it has a
-     reasonable length.  There may never be more elements than the
-     number of characters in FORMAT.  */
-  if (max_pos < 0 || max_pos >= strlen (format))
-    goto leave_einval;
-
-#ifdef DEBUG
-    dump_argspecs (argspecs, argspecs_len);
-#endif
-
-  /* Allocate a table to hold the values.  If it is small enough we
-     use a stack allocated buffer.  */
-  if (max_pos > DIM(valuetable_buffer))
-    {
-      valuetable = calloc (max_pos, sizeof *valuetable);
-      if (!valuetable)
-        goto leave_error;
-    }
-  else
-    {
-      for (validx=0; validx < DIM(valuetable_buffer); validx++)
-        valuetable[validx].vt = VALTYPE_UNSUPPORTED;
-    }
-  for (argidx=0; argidx < argspecs_len; argidx++)
-    {
-      if (argspecs[argidx].arg_pos != - 1)
-        {
-          validx = argspecs[argidx].arg_pos - 1;
-          if (valuetable[validx].vt)
-            goto leave_einval; /* Already defined. */
-          valuetable[validx].vt = argspecs[argidx].vt;
-        }
-      if (argspecs[argidx].width == STAR_FIELD_VALUE)
-        {
-          validx = argspecs[argidx].width_pos - 1;
-          if (valuetable[validx].vt)
-            goto leave_einval; /* Already defined.  */
-          valuetable[validx].vt = VALTYPE_INT;
-        }
-      if (argspecs[argidx].precision == STAR_FIELD_VALUE)
-        {
-          validx = argspecs[argidx].precision_pos - 1;
-          if (valuetable[validx].vt)
-            goto leave_einval; /* Already defined.  */
-          valuetable[validx].vt = VALTYPE_INT;
-        }
-    }
-
-  /* Read all the arguments.  This will error out for unsupported
-     types and for not given positional arguments. */
-  rc = read_values (valuetable, max_pos, vaargs);
-  if (rc)
-    goto leave_einval;
-
-/*   for (validx=0; validx < max_pos; validx++) */
-/*     fprintf (stderr, "%2d: vt=%d\n", validx, valuetable[validx].vt); */
-
-  /* Everything has been collected, go ahead with the formatting.  */
-  rc = do_format (outfnc, outfncarg, format,
-                  argspecs, argspecs_len, valuetable, myerrno, &nbytes);
-
-  goto leave;
-
- leave_einval:
-  errno = EINVAL;
- leave_error:
-  rc = -1;
- leave:
-  if (valuetable != valuetable_buffer)
-    free (valuetable);
-  if (argspecs != argspecs_buffer)
-    free (argspecs);
-  return rc;
-}
-
-
-\f
-
-/* A simple output handler utilizing stdio.  */
-static int
-plain_stdio_out (void *outfncarg, const char *buf, size_t buflen)
-{
-  FILE *fp = (FILE*)outfncarg;
-
-  if ( fwrite (buf, buflen, 1, fp) != 1 )
-    return -1;
-  return 0;
-}
-
-
-/* A replacement for printf.  */
-int
-estream_printf (const char *format, ...)
-{
-  int rc;
-  va_list arg_ptr;
-
-  va_start (arg_ptr, format);
-  rc = estream_format (plain_stdio_out, stderr, format, arg_ptr);
-  va_end (arg_ptr);
-
-  return rc;
-}
-
-/* A replacement for fprintf.  */
-int
-estream_fprintf (FILE *fp, const char *format, ...)
-{
-  int rc;
-  va_list arg_ptr;
-
-  va_start (arg_ptr, format);
-  rc = estream_format (plain_stdio_out, fp, format, arg_ptr);
-  va_end (arg_ptr);
-
-  return rc;
-}
-
-/* A replacement for vfprintf.  */
-int
-estream_vfprintf (FILE *fp, const char *format, va_list arg_ptr)
-{
-  return estream_format (plain_stdio_out, fp, format, arg_ptr);
-}
-
-
-\f
-/* Communication object used between estream_snprintf and
-   fixed_buffer_out.  */
-struct fixed_buffer_parm_s
-{
-  size_t size;    /* Size of the buffer.  */
-  size_t count;   /* Number of bytes requested for output.  */
-  size_t used;    /* Used size of the buffer.  */
-  char *buffer;   /* Provided buffer.  */
-};
-
-/* A simple malloced buffer output handler.  */
-static int
-fixed_buffer_out (void *outfncarg, const char *buf, size_t buflen)
-{
-  struct fixed_buffer_parm_s *parm = outfncarg;
-
-  parm->count += buflen;
-
-  if (!parm->buffer)
-    ;
-  else if (parm->used + buflen < parm->size)
-    {
-      /* Handle the common case that everything fits into the buffer
-         separately.  */
-      memcpy (parm->buffer + parm->used, buf, buflen);
-      parm->used += buflen;
-    }
-  else
-    {
-      /* The slow version of above.  */
-      for ( ;buflen && parm->used < parm->size; buflen--)
-        parm->buffer[parm->used++] = *buf++;
-    }
-
-  return 0;
-}
-
-
-/* A replacement for vsnprintf. */
-int
-estream_vsnprintf (char *buf, size_t bufsize,
-                   const char *format, va_list arg_ptr)
-{
-  struct fixed_buffer_parm_s parm;
-  int rc;
-
-  parm.size = bufsize;
-  parm.count = 0;
-  parm.used = 0;
-  parm.buffer = bufsize?buf:NULL;
-  rc = estream_format (fixed_buffer_out, &parm, format, arg_ptr);
-  if (!rc)
-    rc = fixed_buffer_out (&parm, "", 1); /* Print terminating Nul.  */
-  if (rc == -1)
-    return -1;
-  if (bufsize && buf && parm.size && parm.count >= parm.size)
-    buf[parm.size-1] = 0;
-
-  parm.count--; /* Do not count the trailing nul.  */
-  return (int)parm.count; /* Return number of bytes which would have
-                             been written.  */
-}
-
-/* A replacement for snprintf.  */
-int
-estream_snprintf (char *buf, size_t bufsize, const char *format, ...)
-{
-  int rc;
-  va_list arg_ptr;
-
-  va_start (arg_ptr, format);
-  rc = estream_vsnprintf (buf, bufsize, format, arg_ptr);
-  va_end (arg_ptr);
-
-  return rc;
-}
-
-
-\f
-/* Communication object used between estream_asprintf and
-   dynamic_buffer_out.  */
-struct dynamic_buffer_parm_s
-{
-  int error_flag; /* Internal helper.  */
-  size_t alloced; /* Allocated size of the buffer.  */
-  size_t used;    /* Used size of the buffer.  */
-  char *buffer;   /* Malloced buffer.  */
-};
-
-/* A simple malloced buffer output handler.  */
-static int
-dynamic_buffer_out (void *outfncarg, const char *buf, size_t buflen)
-{
-  struct dynamic_buffer_parm_s *parm = outfncarg;
-
-  if (parm->error_flag)
-    {
-      /* Just in case some formatting routine did not checked for an
-         error. */
-      errno = parm->error_flag;
-      return -1;
-    }
-
-  if (parm->used + buflen >= parm->alloced)
-    {
-      char *p;
-
-      parm->alloced += buflen + 512;
-      p = realloc (parm->buffer, parm->alloced);
-      if (!p)
-        {
-          parm->error_flag = errno ? errno : ENOMEM;
-          /* Wipe out what we already accumulated.  This is useful in
-             case sensitive data is formated.  */
-          memset (parm->buffer, 0, parm->used);
-          return -1;
-        }
-      parm->buffer = p;
-    }
-  memcpy (parm->buffer + parm->used, buf, buflen);
-  parm->used += buflen;
-
-  return 0;
-}
-
-
-/* A replacement for vasprintf.  As with the BSD of vasprintf version -1
-   will be returned on error and NULL stored at BUFP.  On success the
-   number of bytes printed will be returned. */
-int
-estream_vasprintf (char **bufp, const char *format, va_list arg_ptr)
-{
-  struct dynamic_buffer_parm_s parm;
-  int rc;
-
-  parm.error_flag = 0;
-  parm.alloced = 512;
-  parm.used = 0;
-  parm.buffer = my_printf_malloc (parm.alloced);
-  if (!parm.buffer)
-    {
-      *bufp = NULL;
-      return -1;
-    }
-
-  rc = estream_format (dynamic_buffer_out, &parm, format, arg_ptr);
-  if (!rc)
-    rc = dynamic_buffer_out (&parm, "", 1); /* Print terminating Nul.  */
-  /* Fixme: Should we shrink the resulting buffer?  */
-  if (rc != -1 && parm.error_flag)
-    {
-      rc = -1;
-      errno = parm.error_flag;
-    }
-  if (rc == -1)
-    {
-      memset (parm.buffer, 0, parm.used);
-      my_printf_free (parm.buffer);
-      *bufp = NULL;
-      return -1;
-    }
-  assert (parm.used);   /* We have at least the terminating Nul.  */
-  *bufp = parm.buffer;
-  return parm.used - 1; /* Do not include that Nul. */
-}
-
-/* A replacement for asprintf.  As with the BSD of asprintf version -1
-   will be returned on error and NULL stored at BUFP.  On success the
-   number of bytes printed will be returned. */
-int
-estream_asprintf (char **bufp, const char *format, ...)
-{
-  int rc;
-  va_list arg_ptr;
-
-  va_start (arg_ptr, format);
-  rc = estream_vasprintf (bufp, format, arg_ptr);
-  va_end (arg_ptr);
-
-  return rc;
-}
-
-
diff --git a/common/estream-printf.h b/common/estream-printf.h
deleted file mode 100644 (file)
index 3987b33..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* estream-printf.h - Versatile C-99 compliant printf formatting.
- * Copyright (C) 2007 g10 Code GmbH
- *
- * This file is part of Libestream.
- *
- * Libestream 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.
- *
- * Libestream 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 Libestream; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ESTREAM_PRINTF_H
-#define ESTREAM_PRINTF_H
-
-#include <stdarg.h>
-#include <stdio.h>
-
-/* To use this file with libraries the following macro is useful:
-
-     #define _ESTREAM_EXT_SYM_PREFIX _foo_
-   
-       This prefixes all external symbols with "_foo_".
-
-   For the implementation of the code (estream-printf.c) the following
-   macros may be used to tune the implementation for certain systems:
-
-     #define _ESTREAM_PRINTF_MALLOC foo_malloc
-     #define _ESTREAM_PRINTF_FREE   foo_free
-
-       Make estream_asprintf and estream_vasprintf use foo_malloc and
-       foo_free instead of the standard malloc and free functions to
-       allocate the memory returned to the caller.
-
-     #define  _ESTREAM_PRINTF_EXTRA_INCLUDE "foo.h"
-
-       This includes the file "foo.h" which may provide prototypes for
-       the custom memory allocation functions.
- */
-
-
-#ifdef _ESTREAM_EXT_SYM_PREFIX
-#ifndef _ESTREAM_PREFIX
-#define _ESTREAM_PREFIX1(x,y)  x ## y
-#define _ESTREAM_PREFIX2(x,y) _ESTREAM_PREFIX1(x,y)
-#define _ESTREAM_PREFIX(x)    _ESTREAM_PREFIX2(_ESTREAM_EXT_SYM_PREFIX,x)
-#endif /*_ESTREAM_PREFIX*/
-#define estream_printf_out_t  _ESTREAM_PREFIX(estream_printf_out_t)
-#define estream_format        _ESTREAM_PREFIX(estream_format)
-#define estream_printf        _ESTREAM_PREFIX(estream_printf)
-#define estream_fprintf       _ESTREAM_PREFIX(estream_fprintf)
-#define estream_vfprintf      _ESTREAM_PREFIX(estream_vfprintf)
-#define estream_snprintf      _ESTREAM_PREFIX(estream_snprintf)
-#define estream_vsnprintf     _ESTREAM_PREFIX(estream_vsnprintf)
-#define estream_asprintf      _ESTREAM_PREFIX(estream_asprintf)
-#define estream_vasprintf     _ESTREAM_PREFIX(estream_vasprintf)
-#endif /*_ESTREAM_EXT_SYM_PREFIX*/
-
-#ifndef _ESTREAM_GCC_A_PRINTF
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
-# define _ESTREAM_GCC_A_PRINTF( f, a )  __attribute__ ((format (printf,f,a)))
-#else
-# define _ESTREAM_GCC_A_PRINTF( f, a )
-#endif
-#endif /*_ESTREAM_GCC_A_PRINTF*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0
-}
-#endif
-#endif
-
-
-typedef int (*estream_printf_out_t)
-     (void *outfncarg,  const char *buf, size_t buflen);
-
-int estream_format (estream_printf_out_t outfnc, void *outfncarg,
-                    const char *format, va_list vaargs) 
-     _ESTREAM_GCC_A_PRINTF(3,0);
-int estream_printf (const char *format, ...) 
-     _ESTREAM_GCC_A_PRINTF(1,2);
-int estream_fprintf (FILE *fp, const char *format, ... )
-     _ESTREAM_GCC_A_PRINTF(2,3);
-int estream_vfprintf (FILE *fp, const char *format, va_list arg_ptr)
-     _ESTREAM_GCC_A_PRINTF(2,0);
-int estream_snprintf (char *buf, size_t bufsize, const char *format, ...)
-     _ESTREAM_GCC_A_PRINTF(3,4);
-int estream_vsnprintf (char *buf,size_t bufsize, 
-                       const char *format, va_list arg_ptr) 
-     _ESTREAM_GCC_A_PRINTF(3,0);
-int estream_asprintf (char **bufp, const char *format, ...)
-     _ESTREAM_GCC_A_PRINTF(2,3);
-int estream_vasprintf (char **bufp, const char *format, va_list arg_ptr)
-     _ESTREAM_GCC_A_PRINTF(2,0);
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif /*ESTREAM_PRINTF_H*/
diff --git a/common/estream.c b/common/estream.c
deleted file mode 100644 (file)
index 86d8e21..0000000
+++ /dev/null
@@ -1,3823 +0,0 @@
-/* estream.c - Extended Stream I/O Library
- * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 g10 Code GmbH
- *
- * This file is part of Libestream.
- *
- * Libestream 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.
- *
- * Libestream 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 Libestream; if not, see <http://www.gnu.org/licenses/>.
- *
- * ALTERNATIVELY, Libestream may be distributed under the terms of the
- * following license, in which case the provisions of this license are
- * required INSTEAD OF the GNU General Public License. If you wish to
- * allow use of your version of this file only under the terms of the
- * GNU General Public License, and not to allow others to use your
- * version of this file under the terms of the following license,
- * indicate your decision by deleting this paragraph and the license
- * below.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, and the entire permission notice in its entirety,
- *    including the disclaimer of warranties.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef USE_ESTREAM_SUPPORT_H
-# include <estream-support.h>
-#endif
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined(_WIN32) && !defined(HAVE_W32_SYSTEM)
-# define HAVE_W32_SYSTEM 1
-# if defined(__MINGW32CE__) && !defined (HAVE_W32CE_SYSTEM)
-#  define HAVE_W32CE_SYSTEM
-# endif
-#endif
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stddef.h>
-#include <assert.h>
-#ifdef HAVE_W32_SYSTEM
-# ifdef HAVE_WINSOCK2_H
-#  include <winsock2.h>
-# endif
-# include <windows.h>
-#endif
-#ifdef HAVE_W32CE_SYSTEM
-# include <gpg-error.h> /* ERRNO replacement.  */
-#endif
-
-#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
-# undef HAVE_PTH
-# undef USE_GNU_PTH
-#endif
-
-#ifdef HAVE_PTH
-# include <pth.h>
-#endif
-
-/* This is for the special hack to use estream.c in GnuPG.  */
-#ifdef GNUPG_MAJOR_VERSION
-# include "../common/util.h"
-#endif
-
-#ifndef HAVE_MKSTEMP
-int mkstemp (char *template);
-#endif
-
-#ifndef HAVE_MEMRCHR
-void *memrchr (const void *block, int c, size_t size);
-#endif
-
-#include <estream.h>
-#include <estream-printf.h>
-
-\f
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#ifdef HAVE_W32CE_SYSTEM
-# define _set_errno(a)  gpg_err_set_errno ((a))
-/* Setmode is missing in cegcc but available since CE 5.0.  */
-int _setmode (int handle, int mode);
-# define setmode(a,b)   _setmode ((a),(b))
-#else
-# define _set_errno(a)  do { errno = (a); } while (0)
-#endif
-
-#ifdef HAVE_W32_SYSTEM
-# define IS_INVALID_FD(a) ((void*)(a) == (void*)(-1))
-#else
-# define IS_INVALID_FD(a) ((a) == -1)
-#endif
-
-
-/* Generally used types.  */
-
-typedef void *(*func_realloc_t) (void *mem, size_t size);
-typedef void (*func_free_t) (void *mem);
-
-
-\f
-
-/* Buffer management layer.  */
-
-#define BUFFER_BLOCK_SIZE  BUFSIZ
-#define BUFFER_UNREAD_SIZE 16
-
-\f
-
-/* Locking.  */
-
-#ifdef HAVE_PTH
-typedef pth_mutex_t estream_mutex_t;
-#else /*!HAVE_PTH*/
-typedef void *estream_mutex_t;
-#endif /*!HAVE_PTH*/
-
-static inline void
-dummy_mutex_call_void (estream_mutex_t mutex)
-{
-  (void)mutex;
-}
-
-static inline int
-dummy_mutex_call_int (estream_mutex_t mutex)
-{
-  (void)mutex;
-  return 0;
-}
-
-
-#ifdef HAVE_PTH
-
-static int estream_pth_killed;
-
-# define ESTREAM_MUTEX_INITIALIZER PTH_MUTEX_INIT
-# define ESTREAM_MUTEX_LOCK(mutex)                              \
-  (estream_pth_killed ? dummy_mutex_call_void ((mutex))         \
-   : (void)pth_mutex_acquire (&(mutex), 0, NULL))
-# define ESTREAM_MUTEX_UNLOCK(mutex)                            \
-  (estream_pth_killed ? dummy_mutex_call_int ((mutex))          \
-   : pth_mutex_release (&(mutex)))
-# define ESTREAM_MUTEX_TRYLOCK(mutex)                                   \
-  (estream_pth_killed ? dummy_mutex_call_int ((mutex))                  \
-   : ((pth_mutex_acquire (&(mutex), 1, NULL) == TRUE)? 0:-1))
-# define ESTREAM_MUTEX_INITIALIZE(mutex)                        \
-  (estream_pth_killed ? dummy_mutex_call_int ((mutex))          \
-   : pth_mutex_init (&(mutex)))
-
-#else /*!HAVE_PTH*/
-
-# define ESTREAM_MUTEX_INITIALIZER NULL
-# define ESTREAM_MUTEX_LOCK(mutex) dummy_mutex_call_void ((mutex))
-# define ESTREAM_MUTEX_UNLOCK(mutex) dummy_mutex_call_void ((mutex))
-# define ESTREAM_MUTEX_TRYLOCK(mutex) dummy_mutex_call_int ((mutex))
-# define ESTREAM_MUTEX_INITIALIZE(mutex) dummy_mutex_call_void ((mutex))
-
-#endif /*!HAVE_PTH*/
-
-/* Primitive system I/O.  */
-
-#ifdef HAVE_PTH
-# define ESTREAM_SYS_READ  es_pth_read
-# define ESTREAM_SYS_WRITE es_pth_write
-# define ESTREAM_SYS_YIELD() \
-  do { if (!estream_pth_killed) pth_yield (NULL); } while (0)
-#else
-# define ESTREAM_SYS_READ  read
-# define ESTREAM_SYS_WRITE write
-# define ESTREAM_SYS_YIELD() do { } while (0)
-#endif
-
-/* Misc definitions.  */
-
-#define ES_DEFAULT_OPEN_MODE (S_IRUSR | S_IWUSR)
-
-/* A private cookie function to implement an internal IOCTL
-   service.  */
-typedef int (*cookie_ioctl_function_t) (void *cookie, int cmd,
-                                       void *ptr, size_t *len);
-/* IOCTL commands for the private cookie function.  */
-#define COOKIE_IOCTL_SNATCH_BUFFER 1
-
-
-
-/* An internal stream object.  */
-struct estream_internal
-{
-  unsigned char buffer[BUFFER_BLOCK_SIZE];
-  unsigned char unread_buffer[BUFFER_UNREAD_SIZE];
-  estream_mutex_t lock;                 /* Lock. */
-  void *cookie;                         /* Cookie.                */
-  void *opaque;                         /* Opaque data.           */
-  unsigned int modeflags;       /* Flags for the backend. */
-  char *printable_fname;         /* Malloced filename for es_fname_get.  */
-  off_t offset;
-  es_cookie_read_function_t func_read;
-  es_cookie_write_function_t func_write;
-  es_cookie_seek_function_t func_seek;
-  cookie_ioctl_function_t func_ioctl;
-  es_cookie_close_function_t func_close;
-  int strategy;
-  int fd;
-  struct
-  {
-    unsigned int err: 1;
-    unsigned int eof: 1;
-  } indicators;
-  unsigned int deallocate_buffer: 1;
-  unsigned int is_stdstream:1;   /* This is a standard stream.  */
-  unsigned int stdstream_fd:2;   /* 0, 1 or 2 for a standard stream.  */
-  unsigned int print_err: 1;     /* Error in print_fun_writer.  */
-  unsigned int printable_fname_inuse: 1;  /* es_fname_get has been used.  */
-  int print_errno;               /* Errno from print_fun_writer.  */
-  size_t print_ntotal;           /* Bytes written from in print_fun_writer. */
-  FILE *print_fp;                /* Stdio stream used by print_fun_writer.  */
-};
-
-
-typedef struct estream_internal *estream_internal_t;
-
-#define ESTREAM_LOCK(stream) ESTREAM_MUTEX_LOCK (stream->intern->lock)
-#define ESTREAM_UNLOCK(stream) ESTREAM_MUTEX_UNLOCK (stream->intern->lock)
-#define ESTREAM_TRYLOCK(stream) ESTREAM_MUTEX_TRYLOCK (stream->intern->lock)
-
-/* Stream list.  */
-
-typedef struct estream_list *estream_list_t;
-
-struct estream_list
-{
-  estream_t car;
-  estream_list_t cdr;
-  estream_list_t *prev_cdr;
-};
-
-static estream_list_t estream_list;
-static estream_mutex_t estream_list_lock;
-
-#define ESTREAM_LIST_LOCK   ESTREAM_MUTEX_LOCK   (estream_list_lock)
-#define ESTREAM_LIST_UNLOCK ESTREAM_MUTEX_UNLOCK (estream_list_lock)
-
-/* File descriptors registered to be used as the standard file handles. */
-static int custom_std_fds[3];
-static unsigned char custom_std_fds_valid[3];
-
-
-#ifndef EOPNOTSUPP
-# define EOPNOTSUPP ENOSYS
-#endif
-
-
-/* Local prototypes.  */
-static void fname_set_internal (estream_t stream, const char *fname, int quote);
-
-
-
-\f
-/* Macros.  */
-
-/* Calculate array dimension.  */
-#ifndef DIM
-#define DIM(array) (sizeof (array) / sizeof (*array))
-#endif
-
-#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
-
-
-/* Evaluate EXPRESSION, setting VARIABLE to the return code, if
-   VARIABLE is zero.  */
-#define SET_UNLESS_NONZERO(variable, tmp_variable, expression) \
-  do                                                           \
-    {                                                          \
-      tmp_variable = expression;                               \
-      if ((! variable) && tmp_variable)                        \
-        variable = tmp_variable;                               \
-    }                                                          \
-  while (0)
-
-
-/* Malloc wrappers to overcome problems on some older OSes.  */
-static void *
-mem_alloc (size_t n)
-{
-  if (!n)
-    n++;
-  return malloc (n);
-}
-
-static void *
-mem_realloc (void *p, size_t n)
-{
-  if (!p)
-    return mem_alloc (n);
-  return realloc (p, n);
-}
-
-static void
-mem_free (void *p)
-{
-  if (p)
-    free (p);
-}
-
-
-
-/*
- * List manipulation.
- */
-
-/* Add STREAM to the list of registered stream objects.  If
-   WITH_LOCKED_LIST is true we assumed that the list of streams is
-   already locked.  */
-static int
-es_list_add (estream_t stream, int with_locked_list)
-{
-  estream_list_t list_obj;
-  int ret;
-
-  list_obj = mem_alloc (sizeof (*list_obj));
-  if (! list_obj)
-    ret = -1;
-  else
-    {
-      if (!with_locked_list)
-        ESTREAM_LIST_LOCK;
-      list_obj->car = stream;
-      list_obj->cdr = estream_list;
-      list_obj->prev_cdr = &estream_list;
-      if (estream_list)
-       estream_list->prev_cdr = &list_obj->cdr;
-      estream_list = list_obj;
-      if (!with_locked_list)
-        ESTREAM_LIST_UNLOCK;
-      ret = 0;
-    }
-
-  return ret;
-}
-
-/* Remove STREAM from the list of registered stream objects.  */
-static void
-es_list_remove (estream_t stream, int with_locked_list)
-{
-  estream_list_t list_obj;
-
-  if (!with_locked_list)
-    ESTREAM_LIST_LOCK;
-  for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr)
-    if (list_obj->car == stream)
-      {
-       *list_obj->prev_cdr = list_obj->cdr;
-       if (list_obj->cdr)
-         list_obj->cdr->prev_cdr = list_obj->prev_cdr;
-       mem_free (list_obj);
-       break;
-      }
-  if (!with_locked_list)
-    ESTREAM_LIST_UNLOCK;
-}
-
-/* Type of an stream-iterator-function.  */
-typedef int (*estream_iterator_t) (estream_t stream);
-
-/* Iterate over list of registered streams, calling ITERATOR for each
-   of them.  */
-static int
-es_list_iterate (estream_iterator_t iterator)
-{
-  estream_list_t list_obj;
-  int ret = 0;
-
-  ESTREAM_LIST_LOCK;
-  for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr)
-    ret |= (*iterator) (list_obj->car);
-  ESTREAM_LIST_UNLOCK;
-
-  return ret;
-}
-
-
-\f
-/*
- * I/O Helper
- *
- * Unfortunately our Pth emulation for Windows expects system handles
- * for pth_read and pth_write.  We use a simple approach to fix this:
- * If the function returns an error we fall back to a vanilla read or
- * write, assuming that we do I/O on a plain file where the operation
- * can't block.
- */
-#ifdef HAVE_PTH
-static int
-es_pth_read (int fd, void *buffer, size_t size)
-{
-  if (estream_pth_killed)
-    return read (fd, buffer, size);
-  else
-    {
-# ifdef HAVE_W32_SYSTEM
-      int rc = pth_read (fd, buffer, size);
-      if (rc == -1 && errno == EINVAL)
-        rc = read (fd, buffer, size);
-      return rc;
-# else /*!HAVE_W32_SYSTEM*/
-      return pth_read (fd, buffer, size);
-# endif /* !HAVE_W32_SYSTEM*/
-    }
-}
-
-static int
-es_pth_write (int fd, const void *buffer, size_t size)
-{
-  if (estream_pth_killed)
-    return write (fd, buffer, size);
-  else
-    {
-# ifdef HAVE_W32_SYSTEM
-      int rc = pth_write (fd, buffer, size);
-      if (rc == -1 && errno == EINVAL)
-        rc = write (fd, buffer, size);
-      return rc;
-# else /*!HAVE_W32_SYSTEM*/
-      return pth_write (fd, buffer, size);
-# endif /* !HAVE_W32_SYSTEM*/
-    }
-}
-#endif /*HAVE_PTH*/
-
-\f
-
-static void
-es_deinit (void)
-{
-  /* Flush all streams. */
-  es_fflush (NULL);
-}
-
-
-/* A replacement for pth_kill.  The reason we need this is that after
-   a pth_kill all our pth functions may not be used anymore.  Thus
-   applications using estream and pth need to use this function
-   instead of a plain pth_kill.  */
-int
-es_pth_kill (void)
-{
-#ifdef HAVE_PTH
-  int rc;
-
-  rc = pth_kill ();
-  if (rc)
-    estream_pth_killed = 1;
-  return rc;
-#else /*!HAVE_PTH*/
-  return 0;
-#endif /*!HAVE_PTH*/
-}
-
-
-/*
- * Initialization.
- */
-
-static int
-es_init_do (void)
-{
-  static int initialized;
-
-  if (!initialized)
-    {
-#ifdef HAVE_PTH
-      if (estream_pth_killed)
-        initialized = 1;
-      else
-        {
-          if (!pth_init () && errno != EPERM )
-            return -1;
-          if (pth_mutex_init (&estream_list_lock))
-            initialized = 1;
-        }
-#else
-      initialized = 1;
-#endif
-      atexit (es_deinit);
-    }
-  return 0;
-}
-
-\f
-
-/*
- * I/O methods.
- */
-
-/* Implementation of Memory I/O.  */
-
-/* Cookie for memory objects.  */
-typedef struct estream_cookie_mem
-{
-  unsigned int modeflags;      /* Open flags.  */
-  unsigned char *memory;       /* Allocated data buffer.  */
-  size_t memory_size;          /* Allocated size of MEMORY.  */
-  size_t memory_limit;          /* Caller supplied maximum allowed
-                                   allocation size or 0 for no limit.  */
-  size_t offset;               /* Current offset in MEMORY.  */
-  size_t data_len;             /* Used length of data in MEMORY.  */
-  size_t block_size;           /* Block size.  */
-  struct {
-    unsigned int grow: 1;      /* MEMORY is allowed to grow.  */
-  } flags;
-  func_realloc_t func_realloc;
-  func_free_t func_free;
-} *estream_cookie_mem_t;
-
-
-/* Create function for memory objects.  DATA is either NULL or a user
-   supplied buffer with the initial content of the memory buffer.  If
-   DATA is NULL, DATA_N and DATA_LEN need to be 0 as well.  If DATA is
-   not NULL, DATA_N gives the allocated size of DATA and DATA_LEN the
-   used length in DATA.  */
-static int
-es_func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie,
-                   unsigned char *ES__RESTRICT data, size_t data_n,
-                   size_t data_len,
-                   size_t block_size, unsigned int grow,
-                   func_realloc_t func_realloc, func_free_t func_free,
-                   unsigned int modeflags,
-                    size_t memory_limit)
-{
-  estream_cookie_mem_t mem_cookie;
-  int err;
-
-  if (!data && (data_n || data_len))
-    {
-      _set_errno (EINVAL);
-      return -1;
-    }
-
-  mem_cookie = mem_alloc (sizeof (*mem_cookie));
-  if (!mem_cookie)
-    err = -1;
-  else
-    {
-      mem_cookie->modeflags = modeflags;
-      mem_cookie->memory = data;
-      mem_cookie->memory_size = data_n;
-      mem_cookie->memory_limit = memory_limit;
-      mem_cookie->offset = 0;
-      mem_cookie->data_len = data_len;
-      mem_cookie->block_size = block_size;
-      mem_cookie->flags.grow = !!grow;
-      mem_cookie->func_realloc = func_realloc ? func_realloc : mem_realloc;
-      mem_cookie->func_free = func_free ? func_free : mem_free;
-      *cookie = mem_cookie;
-      err = 0;
-    }
-
-  return err;
-}
-
-
-/* Read function for memory objects.  */
-static ssize_t
-es_func_mem_read (void *cookie, void *buffer, size_t size)
-{
-  estream_cookie_mem_t mem_cookie = cookie;
-  ssize_t ret;
-
-  if (size > mem_cookie->data_len - mem_cookie->offset)
-    size = mem_cookie->data_len - mem_cookie->offset;
-
-  if (size)
-    {
-      memcpy (buffer, mem_cookie->memory + mem_cookie->offset, size);
-      mem_cookie->offset += size;
-    }
-
-  ret = size;
-  return ret;
-}
-
-
-/* Write function for memory objects.  */
-static ssize_t
-es_func_mem_write (void *cookie, const void *buffer, size_t size)
-{
-  estream_cookie_mem_t mem_cookie = cookie;
-  ssize_t ret;
-  size_t nleft;
-
-  if (!size)
-    return 0;  /* A flush is a NOP for memory objects.  */
-
-  if (mem_cookie->modeflags & O_APPEND)
-    {
-      /* Append to data.  */
-      mem_cookie->offset = mem_cookie->data_len;
-    }
-
-  assert (mem_cookie->memory_size >= mem_cookie->offset);
-  nleft = mem_cookie->memory_size - mem_cookie->offset;
-
-  /* If we are not allowed to grow limit the size to the left space.  */
-  if (!mem_cookie->flags.grow && size > nleft)
-    size = nleft;
-
-  /* Enlarge the memory buffer if needed.  */
-  if (size > nleft)
-    {
-      unsigned char *newbuf;
-      size_t newsize;
-
-      if (!mem_cookie->memory_size)
-        newsize = size;  /* Not yet allocated.  */
-      else
-        newsize = mem_cookie->memory_size + (size - nleft);
-      if (newsize < mem_cookie->offset)
-        {
-          _set_errno (EINVAL);
-          return -1;
-        }
-
-      /* Round up to the next block length.  BLOCK_SIZE should always
-         be set; we check anyway.  */
-      if (mem_cookie->block_size)
-        {
-          newsize += mem_cookie->block_size - 1;
-          if (newsize < mem_cookie->offset)
-            {
-              _set_errno (EINVAL);
-              return -1;
-            }
-          newsize /= mem_cookie->block_size;
-          newsize *= mem_cookie->block_size;
-        }
-
-      /* Check for a total limit.  */
-      if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit)
-        {
-          _set_errno (ENOSPC);
-          return -1;
-        }
-
-      newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize);
-      if (!newbuf)
-        return -1;
-
-      mem_cookie->memory = newbuf;
-      mem_cookie->memory_size = newsize;
-
-      assert (mem_cookie->memory_size >= mem_cookie->offset);
-      nleft = mem_cookie->memory_size - mem_cookie->offset;
-
-      assert (size <= nleft);
-    }
-
-  memcpy (mem_cookie->memory + mem_cookie->offset, buffer, size);
-  if (mem_cookie->offset + size > mem_cookie->data_len)
-    mem_cookie->data_len = mem_cookie->offset + size;
-  mem_cookie->offset += size;
-
-  ret = size;
-  return ret;
-}
-
-
-/* Seek function for memory objects.  */
-static int
-es_func_mem_seek (void *cookie, off_t *offset, int whence)
-{
-  estream_cookie_mem_t mem_cookie = cookie;
-  off_t pos_new;
-
-  switch (whence)
-    {
-    case SEEK_SET:
-      pos_new = *offset;
-      break;
-
-    case SEEK_CUR:
-      pos_new = mem_cookie->offset += *offset;
-      break;
-
-    case SEEK_END:
-      pos_new = mem_cookie->data_len += *offset;
-      break;
-
-    default:
-      _set_errno (EINVAL);
-      return -1;
-    }
-
-  if (pos_new > mem_cookie->memory_size)
-    {
-      size_t newsize;
-      void *newbuf;
-
-      if (!mem_cookie->flags.grow)
-       {
-         _set_errno (ENOSPC);
-         return -1;
-        }
-
-      newsize = pos_new + mem_cookie->block_size - 1;
-      if (newsize < pos_new)
-        {
-          _set_errno (EINVAL);
-          return -1;
-        }
-      newsize /= mem_cookie->block_size;
-      newsize *= mem_cookie->block_size;
-
-      if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit)
-        {
-          _set_errno (ENOSPC);
-          return -1;
-        }
-
-      newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize);
-      if (!newbuf)
-        return -1;
-
-      mem_cookie->memory = newbuf;
-      mem_cookie->memory_size = newsize;
-    }
-
-  if (pos_new > mem_cookie->data_len)
-    {
-      /* Fill spare space with zeroes.  */
-      memset (mem_cookie->memory + mem_cookie->data_len,
-              0, pos_new - mem_cookie->data_len);
-      mem_cookie->data_len = pos_new;
-    }
-
-  mem_cookie->offset = pos_new;
-  *offset = pos_new;
-
-  return 0;
-}
-
-
-/* An IOCTL function for memory objects.  */
-static int
-es_func_mem_ioctl (void *cookie, int cmd, void *ptr, size_t *len)
-{
-  estream_cookie_mem_t mem_cookie = cookie;
-  int ret;
-
-  if (cmd == COOKIE_IOCTL_SNATCH_BUFFER)
-    {
-      /* Return the internal buffer of the stream to the caller and
-         invalidate it for the stream.  */
-      *(void**)ptr = mem_cookie->memory;
-      *len = mem_cookie->offset;
-      mem_cookie->memory = NULL;
-      mem_cookie->memory_size = 0;
-      mem_cookie->offset = 0;
-      ret = 0;
-    }
-  else
-    {
-      _set_errno (EINVAL);
-      ret = -1;
-    }
-
-  return ret;
-}
-
-
-/* Destroy function for memory objects.  */
-static int
-es_func_mem_destroy (void *cookie)
-{
-  estream_cookie_mem_t mem_cookie = cookie;
-
-  if (cookie)
-    {
-      mem_cookie->func_free (mem_cookie->memory);
-      mem_free (mem_cookie);
-    }
-  return 0;
-}
-
-
-static es_cookie_io_functions_t estream_functions_mem =
-  {
-    es_func_mem_read,
-    es_func_mem_write,
-    es_func_mem_seek,
-    es_func_mem_destroy
-  };
-
-
-\f
-/* Implementation of fd I/O.  */
-
-/* Cookie for fd objects.  */
-typedef struct estream_cookie_fd
-{
-  int fd;        /* The file descriptor we are using for actual output.  */
-  int no_close;  /* If set we won't close the file descriptor.  */
-} *estream_cookie_fd_t;
-
-/* Create function for fd objects.  */
-static int
-es_func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close)
-{
-  estream_cookie_fd_t fd_cookie;
-  int err;
-
-  fd_cookie = mem_alloc (sizeof (*fd_cookie));
-  if (! fd_cookie)
-    err = -1;
-  else
-    {
-#ifdef HAVE_DOSISH_SYSTEM
-      /* Make sure it is in binary mode if requested.  */
-      if ( (modeflags & O_BINARY) )
-        setmode (fd, O_BINARY);
-#else
-      (void)modeflags;
-#endif
-      fd_cookie->fd = fd;
-      fd_cookie->no_close = no_close;
-      *cookie = fd_cookie;
-      err = 0;
-    }
-
-  return err;
-}
-
-/* Read function for fd objects.  */
-static ssize_t
-es_func_fd_read (void *cookie, void *buffer, size_t size)
-
-{
-  estream_cookie_fd_t file_cookie = cookie;
-  ssize_t bytes_read;
-
-  if (IS_INVALID_FD (file_cookie->fd))
-    {
-      ESTREAM_SYS_YIELD ();
-      bytes_read = 0;
-    }
-  else
-    {
-      do
-        bytes_read = ESTREAM_SYS_READ (file_cookie->fd, buffer, size);
-      while (bytes_read == -1 && errno == EINTR);
-    }
-
-  return bytes_read;
-}
-
-/* Write function for fd objects.  */
-static ssize_t
-es_func_fd_write (void *cookie, const void *buffer, size_t size)
-{
-  estream_cookie_fd_t file_cookie = cookie;
-  ssize_t bytes_written;
-
-  if (IS_INVALID_FD (file_cookie->fd))
-    {
-      ESTREAM_SYS_YIELD ();
-      bytes_written = size; /* Yeah:  Success writing to the bit bucket.  */
-    }
-  else
-    {
-      do
-        bytes_written = ESTREAM_SYS_WRITE (file_cookie->fd, buffer, size);
-      while (bytes_written == -1 && errno == EINTR);
-    }
-
-  return bytes_written;
-}
-
-/* Seek function for fd objects.  */
-static int
-es_func_fd_seek (void *cookie, off_t *offset, int whence)
-{
-  estream_cookie_fd_t file_cookie = cookie;
-  off_t offset_new;
-  int err;
-
-  if (IS_INVALID_FD (file_cookie->fd))
-    {
-      _set_errno (ESPIPE);
-      err = -1;
-    }
-  else
-    {
-      offset_new = lseek (file_cookie->fd, *offset, whence);
-      if (offset_new == -1)
-        err = -1;
-      else
-        {
-          *offset = offset_new;
-          err = 0;
-        }
-    }
-
-  return err;
-}
-
-/* Destroy function for fd objects.  */
-static int
-es_func_fd_destroy (void *cookie)
-{
-  estream_cookie_fd_t fd_cookie = cookie;
-  int err;
-
-  if (fd_cookie)
-    {
-      if (IS_INVALID_FD (fd_cookie->fd))
-        err = 0;
-      else
-        err = fd_cookie->no_close? 0 : close (fd_cookie->fd);
-      mem_free (fd_cookie);
-    }
-  else
-    err = 0;
-
-  return err;
-}
-
-
-static es_cookie_io_functions_t estream_functions_fd =
-  {
-    es_func_fd_read,
-    es_func_fd_write,
-    es_func_fd_seek,
-    es_func_fd_destroy
-  };
-
-
-
-\f
-/* Implementation of FILE* I/O.  */
-
-/* Cookie for fp objects.  */
-typedef struct estream_cookie_fp
-{
-  FILE *fp;      /* The file pointer we are using for actual output.  */
-  int no_close;  /* If set we won't close the file pointer.  */
-} *estream_cookie_fp_t;
-
-/* Create function for fd objects.  */
-static int
-es_func_fp_create (void **cookie, FILE *fp,
-                   unsigned int modeflags, int no_close)
-{
-  estream_cookie_fp_t fp_cookie;
-  int err;
-
-  fp_cookie = mem_alloc (sizeof *fp_cookie);
-  if (!fp_cookie)
-    err = -1;
-  else
-    {
-#ifdef HAVE_DOSISH_SYSTEM
-      /* Make sure it is in binary mode if requested.  */
-      if ( (modeflags & O_BINARY) )
-        setmode (fileno (fp), O_BINARY);
-#else
-      (void)modeflags;
-#endif
-      fp_cookie->fp = fp;
-      fp_cookie->no_close = no_close;
-      *cookie = fp_cookie;
-      err = 0;
-    }
-
-  return err;
-}
-
-/* Read function for FILE* objects.  */
-static ssize_t
-es_func_fp_read (void *cookie, void *buffer, size_t size)
-
-{
-  estream_cookie_fp_t file_cookie = cookie;
-  ssize_t bytes_read;
-
-  if (file_cookie->fp)
-    bytes_read = fread (buffer, 1, size, file_cookie->fp);
-  else
-    bytes_read = 0;
-  if (!bytes_read && ferror (file_cookie->fp))
-    return -1;
-  return bytes_read;
-}
-
-/* Write function for FILE* objects.  */
-static ssize_t
-es_func_fp_write (void *cookie, const void *buffer, size_t size)
-
-{
-  estream_cookie_fp_t file_cookie = cookie;
-  size_t bytes_written;
-
-
-  if (file_cookie->fp)
-    bytes_written = fwrite (buffer, 1, size, file_cookie->fp);
-  else
-    bytes_written = size; /* Successfully written to the bit bucket.  */
-  if (bytes_written != size)
-    return -1;
-  return bytes_written;
-}
-
-/* Seek function for FILE* objects.  */
-static int
-es_func_fp_seek (void *cookie, off_t *offset, int whence)
-{
-  estream_cookie_fp_t file_cookie = cookie;
-  long int offset_new;
-
-  if (!file_cookie->fp)
-    {
-      _set_errno (ESPIPE);
-      return -1;
-    }
-
-  if ( fseek (file_cookie->fp, (long int)*offset, whence) )
-    {
-      /* fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", */
-      /*          errno,strerror (errno)); */
-      return -1;
-    }
-
-  offset_new = ftell (file_cookie->fp);
-  if (offset_new == -1)
-    {
-      /* fprintf (stderr, "\nftell failed: errno=%d (%s)\n",  */
-      /*          errno,strerror (errno)); */
-      return -1;
-    }
-  *offset = offset_new;
-  return 0;
-}
-
-/* Destroy function for FILE* objects.  */
-static int
-es_func_fp_destroy (void *cookie)
-{
-  estream_cookie_fp_t fp_cookie = cookie;
-  int err;
-
-  if (fp_cookie)
-    {
-      if (fp_cookie->fp)
-        {
-          fflush (fp_cookie->fp);
-          err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp);
-        }
-      else
-        err = 0;
-      mem_free (fp_cookie);
-    }
-  else
-    err = 0;
-
-  return err;
-}
-
-
-static es_cookie_io_functions_t estream_functions_fp =
-  {
-    es_func_fp_read,
-    es_func_fp_write,
-    es_func_fp_seek,
-    es_func_fp_destroy
-  };
-
-
-
-\f
-/* Implementation of file I/O.  */
-
-/* Create function for file objects.  */
-static int
-es_func_file_create (void **cookie, int *filedes,
-                    const char *path, unsigned int modeflags)
-{
-  estream_cookie_fd_t file_cookie;
-  int err;
-  int fd;
-
-  err = 0;
-  fd = -1;
-
-  file_cookie = mem_alloc (sizeof (*file_cookie));
-  if (! file_cookie)
-    {
-      err = -1;
-      goto out;
-    }
-
-  fd = open (path, modeflags, ES_DEFAULT_OPEN_MODE);
-  if (fd == -1)
-    {
-      err = -1;
-      goto out;
-    }
-#ifdef HAVE_DOSISH_SYSTEM
-  /* Make sure it is in binary mode if requested.  */
-  if ( (modeflags & O_BINARY) )
-    setmode (fd, O_BINARY);
-#endif
-
-  file_cookie->fd = fd;
-  file_cookie->no_close = 0;
-  *cookie = file_cookie;
-  *filedes = fd;
-
- out:
-
-  if (err)
-    mem_free (file_cookie);
-
-  return err;
-}
-
-\f
-static int
-es_convert_mode (const char *mode, unsigned int *modeflags)
-{
-  unsigned int omode, oflags;
-
-  switch (*mode)
-    {
-    case 'r':
-      omode = O_RDONLY;
-      oflags = 0;
-      break;
-    case 'w':
-      omode = O_WRONLY;
-      oflags = O_TRUNC | O_CREAT;
-      break;
-    case 'a':
-      omode = O_WRONLY;
-      oflags = O_APPEND | O_CREAT;
-      break;
-    default:
-      _set_errno (EINVAL);
-      return -1;
-    }
-  for (mode++; *mode; mode++)
-    {
-      switch (*mode)
-        {
-        case '+':
-          omode = O_RDWR;
-          break;
-        case 'b':
-          oflags |= O_BINARY;
-          break;
-        case 'x':
-          oflags |= O_EXCL;
-          break;
-        default: /* Ignore unknown flags.  */
-          break;
-        }
-    }
-
-  *modeflags = (omode | oflags);
-  return 0;
-}
-
-\f
-
-/*
- * Low level stream functionality.
- */
-
-static int
-es_fill (estream_t stream)
-{
-  size_t bytes_read = 0;
-  int err;
-
-  if (!stream->intern->func_read)
-    {
-      _set_errno (EOPNOTSUPP);
-      err = -1;
-    }
-  else
-    {
-      es_cookie_read_function_t func_read = stream->intern->func_read;
-      ssize_t ret;
-
-      ret = (*func_read) (stream->intern->cookie,
-                         stream->buffer, stream->buffer_size);
-      if (ret == -1)
-       {
-         bytes_read = 0;
-         err = -1;
-       }
-      else
-       {
-         bytes_read = ret;
-         err = 0;
-       }
-    }
-
-  if (err)
-    stream->intern->indicators.err = 1;
-  else if (!bytes_read)
-    stream->intern->indicators.eof = 1;
-
-  stream->intern->offset += stream->data_len;
-  stream->data_len = bytes_read;
-  stream->data_offset = 0;
-
-  return err;
-}
-
-static int
-es_flush (estream_t stream)
-{
-  es_cookie_write_function_t func_write = stream->intern->func_write;
-  int err;
-
-  assert (stream->flags.writing);
-
-  if (stream->data_offset)
-    {
-      size_t bytes_written;
-      size_t data_flushed;
-      ssize_t ret;
-
-      if (! func_write)
-       {
-         err = EOPNOTSUPP;
-         goto out;
-       }
-
-      /* Note: to prevent an endless loop caused by user-provided
-        write-functions that pretend to have written more bytes than
-        they were asked to write, we have to check for
-        "(stream->data_offset - data_flushed) > 0" instead of
-        "stream->data_offset - data_flushed".  */
-
-      data_flushed = 0;
-      err = 0;
-
-      while ((((ssize_t) (stream->data_offset - data_flushed)) > 0) && (! err))
-       {
-         ret = (*func_write) (stream->intern->cookie,
-                              stream->buffer + data_flushed,
-                              stream->data_offset - data_flushed);
-         if (ret == -1)
-           {
-             bytes_written = 0;
-             err = -1;
-           }
-         else
-           bytes_written = ret;
-
-         data_flushed += bytes_written;
-         if (err)
-           break;
-       }
-
-      stream->data_flushed += data_flushed;
-      if (stream->data_offset == data_flushed)
-       {
-         stream->intern->offset += stream->data_offset;
-         stream->data_offset = 0;
-         stream->data_flushed = 0;
-
-         /* Propagate flush event.  */
-         (*func_write) (stream->intern->cookie, NULL, 0);
-       }
-    }
-  else
-    err = 0;
-
- out:
-
-  if (err)
-    stream->intern->indicators.err = 1;
-
-  return err;
-}
-
-/* Discard buffered data for STREAM.  */
-static void
-es_empty (estream_t stream)
-{
-  assert (!stream->flags.writing);
-  stream->data_len = 0;
-  stream->data_offset = 0;
-  stream->unread_data_len = 0;
-}
-
-/* Initialize STREAM.  */
-static void
-es_initialize (estream_t stream,
-              void *cookie, int fd, es_cookie_io_functions_t functions,
-               unsigned int modeflags)
-{
-  stream->intern->cookie = cookie;
-  stream->intern->opaque = NULL;
-  stream->intern->offset = 0;
-  stream->intern->func_read = functions.func_read;
-  stream->intern->func_write = functions.func_write;
-  stream->intern->func_seek = functions.func_seek;
-  stream->intern->func_ioctl = NULL;
-  stream->intern->func_close = functions.func_close;
-  stream->intern->strategy = _IOFBF;
-  stream->intern->fd = fd;
-  stream->intern->print_err = 0;
-  stream->intern->print_errno = 0;
-  stream->intern->print_ntotal = 0;
-  stream->intern->print_fp = NULL;
-  stream->intern->indicators.err = 0;
-  stream->intern->indicators.eof = 0;
-  stream->intern->is_stdstream = 0;
-  stream->intern->stdstream_fd = 0;
-  stream->intern->deallocate_buffer = 0;
-  stream->intern->printable_fname = NULL;
-  stream->intern->printable_fname_inuse = 0;
-
-  stream->data_len = 0;
-  stream->data_offset = 0;
-  stream->data_flushed = 0;
-  stream->unread_data_len = 0;
-  /* Depending on the modeflags we set whether we start in writing or
-     reading mode.  This is required in case we are working on a
-     stream which is not seeekable (like stdout).  Without this
-     pre-initialization we would do a seek at the first write call and
-     as this will fail no utput will be delivered. */
-  if ((modeflags & O_WRONLY) || (modeflags & O_RDWR) )
-    stream->flags.writing = 1;
-  else
-    stream->flags.writing = 0;
-}
-
-/* Deinitialize STREAM.  */
-static int
-es_deinitialize (estream_t stream)
-{
-  es_cookie_close_function_t func_close;
-  int err, tmp_err;
-
-  if (stream->intern->print_fp)
-    {
-      int save_errno = errno;
-      fclose (stream->intern->print_fp);
-      stream->intern->print_fp = NULL;
-      _set_errno (save_errno);
-    }
-
-  func_close = stream->intern->func_close;
-
-  err = 0;
-  if (stream->flags.writing)
-    SET_UNLESS_NONZERO (err, tmp_err, es_flush (stream));
-  if (func_close)
-    SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie));
-
-  mem_free (stream->intern->printable_fname);
-  stream->intern->printable_fname = NULL;
-  stream->intern->printable_fname_inuse = 0;
-
-  return err;
-}
-
-/* Create a new stream object, initialize it.  */
-static int
-es_create (estream_t *stream, void *cookie, int fd,
-          es_cookie_io_functions_t functions, unsigned int modeflags,
-           int with_locked_list)
-{
-  estream_internal_t stream_internal_new;
-  estream_t stream_new;
-  int err;
-
-  stream_new = NULL;
-  stream_internal_new = NULL;
-
-  stream_new = mem_alloc (sizeof (*stream_new));
-  if (! stream_new)
-    {
-      err = -1;
-      goto out;
-    }
-
-  stream_internal_new = mem_alloc (sizeof (*stream_internal_new));
-  if (! stream_internal_new)
-    {
-      err = -1;
-      goto out;
-    }
-
-  stream_new->buffer = stream_internal_new->buffer;
-  stream_new->buffer_size = sizeof (stream_internal_new->buffer);
-  stream_new->unread_buffer = stream_internal_new->unread_buffer;
-  stream_new->unread_buffer_size = sizeof (stream_internal_new->unread_buffer);
-  stream_new->intern = stream_internal_new;
-
-  ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock);
-  es_initialize (stream_new, cookie, fd, functions, modeflags);
-
-  err = es_list_add (stream_new, with_locked_list);
-  if (err)
-    goto out;
-
-  *stream = stream_new;
-
- out:
-
-  if (err)
-    {
-      if (stream_new)
-       {
-         es_deinitialize (stream_new);
-         mem_free (stream_new);
-       }
-    }
-
-  return err;
-}
-
-/* Deinitialize a stream object and destroy it.  */
-static int
-es_destroy (estream_t stream, int with_locked_list)
-{
-  int err = 0;
-
-  if (stream)
-    {
-      es_list_remove (stream, with_locked_list);
-      err = es_deinitialize (stream);
-      mem_free (stream->intern);
-      mem_free (stream);
-    }
-
-  return err;
-}
-
-/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER in
-   unbuffered-mode, storing the amount of bytes read in
-   *BYTES_READ.  */
-static int
-es_read_nbf (estream_t ES__RESTRICT stream,
-            unsigned char *ES__RESTRICT buffer,
-            size_t bytes_to_read, size_t *ES__RESTRICT bytes_read)
-{
-  es_cookie_read_function_t func_read = stream->intern->func_read;
-  size_t data_read;
-  ssize_t ret;
-  int err;
-
-  data_read = 0;
-  err = 0;
-
-  while (bytes_to_read - data_read)
-    {
-      ret = (*func_read) (stream->intern->cookie,
-                         buffer + data_read, bytes_to_read - data_read);
-      if (ret == -1)
-       {
-         err = -1;
-         break;
-       }
-      else if (ret)
-       data_read += ret;
-      else
-       break;
-    }
-
-  stream->intern->offset += data_read;
-  *bytes_read = data_read;
-
-  return err;
-}
-
-/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER in
-   fully-buffered-mode, storing the amount of bytes read in
-   *BYTES_READ.  */
-static int
-es_read_fbf (estream_t ES__RESTRICT stream,
-            unsigned char *ES__RESTRICT buffer,
-            size_t bytes_to_read, size_t *ES__RESTRICT bytes_read)
-{
-  size_t data_available;
-  size_t data_to_read;
-  size_t data_read;
-  int err;
-
-  data_read = 0;
-  err = 0;
-
-  while ((bytes_to_read - data_read) && (! err))
-    {
-      if (stream->data_offset == stream->data_len)
-       {
-         /* Nothing more to read in current container, try to
-            fill container with new data.  */
-         err = es_fill (stream);
-         if (! err)
-           if (! stream->data_len)
-             /* Filling did not result in any data read.  */
-             break;
-       }
-
-      if (! err)
-       {
-         /* Filling resulted in some new data.  */
-
-         data_to_read = bytes_to_read - data_read;
-         data_available = stream->data_len - stream->data_offset;
-         if (data_to_read > data_available)
-           data_to_read = data_available;
-
-         memcpy (buffer + data_read,
-                 stream->buffer + stream->data_offset, data_to_read);
-         stream->data_offset += data_to_read;
-         data_read += data_to_read;
-       }
-    }
-
-  *bytes_read = data_read;
-
-  return err;
-}
-
-/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER in
-   line-buffered-mode, storing the amount of bytes read in
-   *BYTES_READ.  */
-static int
-es_read_lbf (estream_t ES__RESTRICT stream,
-            unsigned char *ES__RESTRICT buffer,
-            size_t bytes_to_read, size_t *ES__RESTRICT bytes_read)
-{
-  int err;
-
-  err = es_read_fbf (stream, buffer, bytes_to_read, bytes_read);
-
-  return err;
-}
-
-/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER, storing
-   *the amount of bytes read in BYTES_READ.  */
-static int
-es_readn (estream_t ES__RESTRICT stream,
-         void *ES__RESTRICT buffer_arg,
-         size_t bytes_to_read, size_t *ES__RESTRICT bytes_read)
-{
-  unsigned char *buffer = (unsigned char *)buffer_arg;
-  size_t data_read_unread, data_read;
-  int err;
-
-  data_read_unread = 0;
-  data_read = 0;
-  err = 0;
-
-  if (stream->flags.writing)
-    {
-      /* Switching to reading mode -> flush output.  */
-      err = es_flush (stream);
-      if (err)
-       goto out;
-      stream->flags.writing = 0;
-    }
-
-  /* Read unread data first.  */
-  while ((bytes_to_read - data_read_unread) && stream->unread_data_len)
-    {
-      buffer[data_read_unread]
-       = stream->unread_buffer[stream->unread_data_len - 1];
-      stream->unread_data_len--;
-      data_read_unread++;
-    }
-
-  switch (stream->intern->strategy)
-    {
-    case _IONBF:
-      err = es_read_nbf (stream,
-                        buffer + data_read_unread,
-                        bytes_to_read - data_read_unread, &data_read);
-      break;
-    case _IOLBF:
-      err = es_read_lbf (stream,
-                        buffer + data_read_unread,
-                        bytes_to_read - data_read_unread, &data_read);
-      break;
-    case _IOFBF:
-      err = es_read_fbf (stream,
-                        buffer + data_read_unread,
-                        bytes_to_read - data_read_unread, &data_read);
-      break;
-    }
-
- out:
-
-  if (bytes_read)
-    *bytes_read = data_read_unread + data_read;
-
-  return err;
-}
-
-/* Try to unread DATA_N bytes from DATA into STREAM, storing the
-   amount of bytes successfully unread in *BYTES_UNREAD.  */
-static void
-es_unreadn (estream_t ES__RESTRICT stream,
-           const unsigned char *ES__RESTRICT data, size_t data_n,
-           size_t *ES__RESTRICT bytes_unread)
-{
-  size_t space_left;
-
-  space_left = stream->unread_buffer_size - stream->unread_data_len;
-
-  if (data_n > space_left)
-    data_n = space_left;
-
-  if (! data_n)
-    goto out;
-
-  memcpy (stream->unread_buffer + stream->unread_data_len, data, data_n);
-  stream->unread_data_len += data_n;
-  stream->intern->indicators.eof = 0;
-
- out:
-
-  if (bytes_unread)
-    *bytes_unread = data_n;
-}
-
-/* Seek in STREAM.  */
-static int
-es_seek (estream_t ES__RESTRICT stream, off_t offset, int whence,
-        off_t *ES__RESTRICT offset_new)
-{
-  es_cookie_seek_function_t func_seek = stream->intern->func_seek;
-  int err, ret;
-  off_t off;
-
-  if (! func_seek)
-    {
-      _set_errno (EOPNOTSUPP);
-      err = -1;
-      goto out;
-    }
-
-  if (stream->flags.writing)
-    {
-      /* Flush data first in order to prevent flushing it to the wrong
-        offset.  */
-      err = es_flush (stream);
-      if (err)
-       goto out;
-      stream->flags.writing = 0;
-    }
-
-  off = offset;
-  if (whence == SEEK_CUR)
-    {
-      off = off - stream->data_len + stream->data_offset;
-      off -= stream->unread_data_len;
-    }
-
-  ret = (*func_seek) (stream->intern->cookie, &off, whence);
-  if (ret == -1)
-    {
-      err = -1;
-      goto out;
-    }
-
-  err = 0;
-  es_empty (stream);
-
-  if (offset_new)
-    *offset_new = off;
-
-  stream->intern->indicators.eof = 0;
-  stream->intern->offset = off;
-
- out:
-
-  if (err)
-    stream->intern->indicators.err = 1;
-
-  return err;
-}
-
-/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in
-   unbuffered-mode, storing the amount of bytes written in
-   *BYTES_WRITTEN.  */
-static int
-es_write_nbf (estream_t ES__RESTRICT stream,
-             const unsigned char *ES__RESTRICT buffer,
-             size_t bytes_to_write, size_t *ES__RESTRICT bytes_written)
-{
-  es_cookie_write_function_t func_write = stream->intern->func_write;
-  size_t data_written;
-  ssize_t ret;
-  int err;
-
-  if (bytes_to_write && (! func_write))
-    {
-      err = EOPNOTSUPP;
-      goto out;
-    }
-
-  data_written = 0;
-  err = 0;
-
-  while (bytes_to_write - data_written)
-    {
-      ret = (*func_write) (stream->intern->cookie,
-                          buffer + data_written,
-                          bytes_to_write - data_written);
-      if (ret == -1)
-       {
-         err = -1;
-         break;
-       }
-      else
-       data_written += ret;
-    }
-
-  stream->intern->offset += data_written;
-  *bytes_written = data_written;
-
- out:
-
-  return err;
-}
-
-/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in
-   fully-buffered-mode, storing the amount of bytes written in
-   *BYTES_WRITTEN.  */
-static int
-es_write_fbf (estream_t ES__RESTRICT stream,
-             const unsigned char *ES__RESTRICT buffer,
-             size_t bytes_to_write, size_t *ES__RESTRICT bytes_written)
-{
-  size_t space_available;
-  size_t data_to_write;
-  size_t data_written;
-  int err;
-
-  data_written = 0;
-  err = 0;
-
-  while ((bytes_to_write - data_written) && (! err))
-    {
-      if (stream->data_offset == stream->buffer_size)
-       /* Container full, flush buffer.  */
-       err = es_flush (stream);
-
-      if (! err)
-       {
-         /* Flushing resulted in empty container.  */
-
-         data_to_write = bytes_to_write - data_written;
-         space_available = stream->buffer_size - stream->data_offset;
-         if (data_to_write > space_available)
-           data_to_write = space_available;
-
-         memcpy (stream->buffer + stream->data_offset,
-                 buffer + data_written, data_to_write);
-         stream->data_offset += data_to_write;
-         data_written += data_to_write;
-       }
-    }
-
-  *bytes_written = data_written;
-
-  return err;
-}
-
-
-/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in
-   line-buffered-mode, storing the amount of bytes written in
-   *BYTES_WRITTEN.  */
-static int
-es_write_lbf (estream_t ES__RESTRICT stream,
-             const unsigned char *ES__RESTRICT buffer,
-             size_t bytes_to_write, size_t *ES__RESTRICT bytes_written)
-{
-  size_t data_flushed = 0;
-  size_t data_buffered = 0;
-  unsigned char *nlp;
-  int err = 0;
-
-  nlp = memrchr (buffer, '\n', bytes_to_write);
-  if (nlp)
-    {
-      /* Found a newline, directly write up to (including) this
-        character.  */
-      err = es_flush (stream);
-      if (!err)
-       err = es_write_nbf (stream, buffer, nlp - buffer + 1, &data_flushed);
-    }
-
-  if (!err)
-    {
-      /* Write remaining data fully buffered.  */
-      err = es_write_fbf (stream, buffer + data_flushed,
-                         bytes_to_write - data_flushed, &data_buffered);
-    }
-
-  *bytes_written = data_flushed + data_buffered;
-  return err;
-}
-
-
-/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in, storing the
-   amount of bytes written in BYTES_WRITTEN.  */
-static int
-es_writen (estream_t ES__RESTRICT stream,
-          const void *ES__RESTRICT buffer,
-          size_t bytes_to_write, size_t *ES__RESTRICT bytes_written)
-{
-  size_t data_written;
-  int err;
-
-  data_written = 0;
-  err = 0;
-
-  if (!stream->flags.writing)
-    {
-      /* Switching to writing mode -> discard input data and seek to
-        position at which reading has stopped.  We can do this only
-        if a seek function has been registered. */
-      if (stream->intern->func_seek)
-        {
-          err = es_seek (stream, 0, SEEK_CUR, NULL);
-          if (err)
-            {
-              if (errno == ESPIPE)
-                err = 0;
-              else
-                goto out;
-            }
-        }
-    }
-
-  switch (stream->intern->strategy)
-    {
-    case _IONBF:
-      err = es_write_nbf (stream, buffer, bytes_to_write, &data_written);
-      break;
-
-    case _IOLBF:
-      err = es_write_lbf (stream, buffer, bytes_to_write, &data_written);
-      break;
-
-    case _IOFBF:
-      err = es_write_fbf (stream, buffer, bytes_to_write, &data_written);
-      break;
-    }
-
- out:
-
-  if (bytes_written)
-    *bytes_written = data_written;
-  if (data_written)
-    if (!stream->flags.writing)
-      stream->flags.writing = 1;
-
-  return err;
-}
-
-
-static int
-es_peek (estream_t ES__RESTRICT stream, unsigned char **ES__RESTRICT data,
-        size_t *ES__RESTRICT data_len)
-{
-  int err;
-
-  if (stream->flags.writing)
-    {
-      /* Switching to reading mode -> flush output.  */
-      err = es_flush (stream);
-      if (err)
-       goto out;
-      stream->flags.writing = 0;
-    }
-
-  if (stream->data_offset == stream->data_len)
-    {
-      /* Refill container.  */
-      err = es_fill (stream);
-      if (err)
-       goto out;
-    }
-
-  if (data)
-    *data = stream->buffer + stream->data_offset;
-  if (data_len)
-    *data_len = stream->data_len - stream->data_offset;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-
-/* Skip SIZE bytes of input data contained in buffer.  */
-static int
-es_skip (estream_t stream, size_t size)
-{
-  int err;
-
-  if (stream->data_offset + size > stream->data_len)
-    {
-      _set_errno (EINVAL);
-      err = -1;
-    }
-  else
-    {
-      stream->data_offset += size;
-      err = 0;
-    }
-
-  return err;
-}
-
-
-static int
-doreadline (estream_t ES__RESTRICT stream, size_t max_length,
-            char *ES__RESTRICT *ES__RESTRICT line,
-            size_t *ES__RESTRICT line_length)
-{
-  size_t space_left;
-  size_t line_size;
-  estream_t line_stream;
-  char *line_new;
-  void *line_stream_cookie;
-  char *newline;
-  unsigned char *data;
-  size_t data_len;
-  int err;
-
-  line_new = NULL;
-  line_stream = NULL;
-  line_stream_cookie = NULL;
-
-  err = es_func_mem_create (&line_stream_cookie, NULL, 0, 0,
-                            BUFFER_BLOCK_SIZE, 1,
-                            mem_realloc, mem_free,
-                            O_RDWR,
-                            0);
-  if (err)
-    goto out;
-
-  err = es_create (&line_stream, line_stream_cookie, -1,
-                  estream_functions_mem, O_RDWR, 0);
-  if (err)
-    goto out;
-
-  space_left = max_length;
-  line_size = 0;
-  while (1)
-    {
-      if (max_length && (space_left == 1))
-       break;
-
-      err = es_peek (stream, &data, &data_len);
-      if (err || (! data_len))
-       break;
-
-      if (data_len > (space_left - 1))
-       data_len = space_left - 1;
-
-      newline = memchr (data, '\n', data_len);
-      if (newline)
-       {
-         data_len = (newline - (char *) data) + 1;
-         err = es_write (line_stream, data, data_len, NULL);
-         if (! err)
-           {
-             space_left -= data_len;
-             line_size += data_len;
-             es_skip (stream, data_len);
-             break;
-           }
-       }
-      else
-       {
-         err = es_write (line_stream, data, data_len, NULL);
-         if (! err)
-           {
-             space_left -= data_len;
-             line_size += data_len;
-             es_skip (stream, data_len);
-           }
-       }
-      if (err)
-       break;
-    }
-  if (err)
-    goto out;
-
-  /* Complete line has been written to line_stream.  */
-
-  if ((max_length > 1) && (! line_size))
-    {
-      stream->intern->indicators.eof = 1;
-      goto out;
-    }
-
-  err = es_seek (line_stream, 0, SEEK_SET, NULL);
-  if (err)
-    goto out;
-
-  if (! *line)
-    {
-      line_new = mem_alloc (line_size + 1);
-      if (! line_new)
-       {
-         err = -1;
-         goto out;
-       }
-    }
-  else
-    line_new = *line;
-
-  err = es_read (line_stream, line_new, line_size, NULL);
-  if (err)
-    goto out;
-
-  line_new[line_size] = '\0';
-
-  if (! *line)
-    *line = line_new;
-  if (line_length)
-    *line_length = line_size;
-
- out:
-
-  if (line_stream)
-    es_destroy (line_stream, 0);
-  else if (line_stream_cookie)
-    es_func_mem_destroy (line_stream_cookie);
-
-  if (err)
-    {
-      if (! *line)
-       mem_free (line_new);
-      stream->intern->indicators.err = 1;
-    }
-
-  return err;
-}
-
-
-/* Output fucntion used for estream_format.  */
-static int
-print_writer (void *outfncarg, const char *buf, size_t buflen)
-{
-  estream_t stream = outfncarg;
-  size_t nwritten;
-  int rc;
-
-  nwritten = 0;
-  rc = es_writen (stream, buf, buflen, &nwritten);
-  stream->intern->print_ntotal += nwritten;
-  return rc;
-}
-
-
-/* The core of our printf function.  This is called in locked state. */
-static int
-es_print (estream_t ES__RESTRICT stream,
-         const char *ES__RESTRICT format, va_list ap)
-{
-  int rc;
-
-  stream->intern->print_ntotal = 0;
-  rc = estream_format (print_writer, stream, format, ap);
-  if (rc)
-    return -1;
-  return (int)stream->intern->print_ntotal;
-}
-
-
-static void
-es_set_indicators (estream_t stream, int ind_err, int ind_eof)
-{
-  if (ind_err != -1)
-    stream->intern->indicators.err = ind_err ? 1 : 0;
-  if (ind_eof != -1)
-    stream->intern->indicators.eof = ind_eof ? 1 : 0;
-}
-
-
-static int
-es_get_indicator (estream_t stream, int ind_err, int ind_eof)
-{
-  int ret = 0;
-
-  if (ind_err)
-    ret = stream->intern->indicators.err;
-  else if (ind_eof)
-    ret = stream->intern->indicators.eof;
-
-  return ret;
-}
-
-
-static int
-es_set_buffering (estream_t ES__RESTRICT stream,
-                 char *ES__RESTRICT buffer, int mode, size_t size)
-{
-  int err;
-
-  /* Flush or empty buffer depending on mode.  */
-  if (stream->flags.writing)
-    {
-      err = es_flush (stream);
-      if (err)
-       goto out;
-    }
-  else
-    es_empty (stream);
-
-  es_set_indicators (stream, -1, 0);
-
-  /* Free old buffer in case that was allocated by this function.  */
-  if (stream->intern->deallocate_buffer)
-    {
-      stream->intern->deallocate_buffer = 0;
-      mem_free (stream->buffer);
-      stream->buffer = NULL;
-    }
-
-  if (mode == _IONBF)
-    stream->buffer_size = 0;
-  else
-    {
-      void *buffer_new;
-
-      if (buffer)
-       buffer_new = buffer;
-      else
-       {
-          if (!size)
-            size = BUFSIZ;
-         buffer_new = mem_alloc (size);
-         if (! buffer_new)
-           {
-             err = -1;
-             goto out;
-           }
-       }
-
-      stream->buffer = buffer_new;
-      stream->buffer_size = size;
-      if (! buffer)
-       stream->intern->deallocate_buffer = 1;
-    }
-  stream->intern->strategy = mode;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-
-static off_t
-es_offset_calculate (estream_t stream)
-{
-  off_t offset;
-
-  offset = stream->intern->offset + stream->data_offset;
-  if (offset < stream->unread_data_len)
-    /* Offset undefined.  */
-    offset = 0;
-  else
-    offset -= stream->unread_data_len;
-
-  return offset;
-}
-
-
-static void
-es_opaque_ctrl (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque_new,
-               void **ES__RESTRICT opaque_old)
-{
-  if (opaque_old)
-    *opaque_old = stream->intern->opaque;
-  if (opaque_new)
-    stream->intern->opaque = opaque_new;
-}
-
-
-static int
-es_get_fd (estream_t stream)
-{
-  return stream->intern->fd;
-}
-
-\f
-
-/* API.  */
-
-int
-es_init (void)
-{
-  int err;
-
-  err = es_init_do ();
-
-  return err;
-}
-
-estream_t
-es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode)
-{
-  unsigned int modeflags;
-  int create_called;
-  estream_t stream;
-  void *cookie;
-  int err;
-  int fd;
-
-  stream = NULL;
-  cookie = NULL;
-  create_called = 0;
-
-  err = es_convert_mode (mode, &modeflags);
-  if (err)
-    goto out;
-
-  err = es_func_file_create (&cookie, &fd, path, modeflags);
-  if (err)
-    goto out;
-
-  create_called = 1;
-  err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0);
-  if (err)
-    goto out;
-
-  if (stream && path)
-    fname_set_internal (stream, path, 1);
-
- out:
-
-  if (err && create_called)
-    (*estream_functions_fd.func_close) (cookie);
-
-  return stream;
-}
-
-
-estream_t
-es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len,
-         unsigned int grow,
-         func_realloc_t func_realloc, func_free_t func_free,
-         const char *ES__RESTRICT mode)
-{
-  unsigned int modeflags;
-  int create_called;
-  estream_t stream;
-  void *cookie;
-  int err;
-
-  cookie = 0;
-  stream = NULL;
-  create_called = 0;
-
-  err = es_convert_mode (mode, &modeflags);
-  if (err)
-    goto out;
-
-  err = es_func_mem_create (&cookie, data, data_n, data_len,
-                           BUFFER_BLOCK_SIZE, grow,
-                           func_realloc, func_free, modeflags, 0);
-  if (err)
-    goto out;
-
-  create_called = 1;
-  err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0);
-
- out:
-
-  if (err && create_called)
-    (*estream_functions_mem.func_close) (cookie);
-
-  return stream;
-}
-
-
-estream_t
-es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode)
-{
-  unsigned int modeflags;
-  estream_t stream = NULL;
-  void *cookie = NULL;
-
-  /* Memory streams are always read/write.  We use MODE only to get
-     the append flag.  */
-  if (es_convert_mode (mode, &modeflags))
-    return NULL;
-  modeflags |= O_RDWR;
-
-
-  if (es_func_mem_create (&cookie, NULL, 0, 0,
-                          BUFFER_BLOCK_SIZE, 1,
-                          mem_realloc, mem_free, modeflags,
-                          memlimit))
-    return NULL;
-
-  if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0))
-    (*estream_functions_mem.func_close) (cookie);
-
-  if (stream)
-    stream->intern->func_ioctl = es_func_mem_ioctl;
-
-  return stream;
-}
-
-
-/* This is the same as es_fopenmem but intializes the memory with a
-   copy of (DATA,DATALEN).  The stream is initally set to the
-   beginning.  If MEMLIMIT is not 0 but shorter than DATALEN it
-   DATALEN will be used as the value for MEMLIMIT.  */
-estream_t
-es_fopenmem_init (size_t memlimit, const char *ES__RESTRICT mode,
-                  const void *data, size_t datalen)
-{
-  estream_t stream;
-
-  if (memlimit && memlimit < datalen)
-    memlimit = datalen;
-
-  stream = es_fopenmem (memlimit, mode);
-  if (stream && data && datalen)
-    {
-      if (es_writen (stream, data, datalen, NULL))
-        {
-          int saveerrno = errno;
-          es_fclose (stream);
-          stream = NULL;
-          _set_errno (saveerrno);
-        }
-      else
-        {
-          es_seek (stream, 0L, SEEK_SET, NULL);
-          es_set_indicators (stream, 0, 0);
-        }
-    }
-  return stream;
-}
-
-
-estream_t
-es_fopencookie (void *ES__RESTRICT cookie,
-               const char *ES__RESTRICT mode,
-               es_cookie_io_functions_t functions)
-{
-  unsigned int modeflags;
-  estream_t stream;
-  int err;
-
-  stream = NULL;
-  modeflags = 0;
-
-  err = es_convert_mode (mode, &modeflags);
-  if (err)
-    goto out;
-
-  err = es_create (&stream, cookie, -1, functions, modeflags, 0);
-  if (err)
-    goto out;
-
- out:
-
-  return stream;
-}
-
-
-estream_t
-do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list)
-{
-  unsigned int modeflags;
-  int create_called;
-  estream_t stream;
-  void *cookie;
-  int err;
-
-  stream = NULL;
-  cookie = NULL;
-  create_called = 0;
-
-  err = es_convert_mode (mode, &modeflags);
-  if (err)
-    goto out;
-
-  err = es_func_fd_create (&cookie, filedes, modeflags, no_close);
-  if (err)
-    goto out;
-
-  create_called = 1;
-  err = es_create (&stream, cookie, filedes, estream_functions_fd,
-                   modeflags, with_locked_list);
-
- out:
-
-  if (err && create_called)
-    (*estream_functions_fd.func_close) (cookie);
-
-  return stream;
-}
-
-estream_t
-es_fdopen (int filedes, const char *mode)
-{
-  return do_fdopen (filedes, mode, 0, 0);
-}
-
-/* A variant of es_fdopen which does not close FILEDES at the end.  */
-estream_t
-es_fdopen_nc (int filedes, const char *mode)
-{
-  return do_fdopen (filedes, mode, 1, 0);
-}
-
-
-estream_t
-do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list)
-{
-  unsigned int modeflags;
-  int create_called;
-  estream_t stream;
-  void *cookie;
-  int err;
-
-  stream = NULL;
-  cookie = NULL;
-  create_called = 0;
-
-  err = es_convert_mode (mode, &modeflags);
-  if (err)
-    goto out;
-
-  if (fp)
-    fflush (fp);
-  err = es_func_fp_create (&cookie, fp, modeflags, no_close);
-  if (err)
-    goto out;
-
-  create_called = 1;
-  err = es_create (&stream, cookie, fp? fileno (fp):-1, estream_functions_fp,
-                   modeflags, with_locked_list);
-
- out:
-
-  if (err && create_called)
-    (*estream_functions_fp.func_close) (cookie);
-
-  return stream;
-}
-
-
-/* Create an estream from the stdio stream FP.  This mechanism is
-   useful in case the stdio streams have special properties and may
-   not be mixed with fd based functions.  This is for example the case
-   under Windows where the 3 standard streams are associated with the
-   console whereas a duped and fd-opened stream of one of this stream
-   won't be associated with the console.  As this messes things up it
-   is easier to keep on using the standard I/O stream as a backend for
-   estream. */
-estream_t
-es_fpopen (FILE *fp, const char *mode)
-{
-  return do_fpopen (fp, mode, 0, 0);
-}
-
-
-/* Same as es_fpopen but does not close  FP at the end.  */
-estream_t
-es_fpopen_nc (FILE *fp, const char *mode)
-{
-  return do_fpopen (fp, mode, 1, 0);
-}
-
-
-/* Set custom standard descriptors to be used for stdin, stdout and
-   stderr.  This function needs to be called before any of the
-   standard streams are accessed.  */
-void
-_es_set_std_fd (int no, int fd)
-{
-  ESTREAM_LIST_LOCK;
-  if (no >= 0 && no < 3 && !custom_std_fds_valid[no])
-    {
-      custom_std_fds[no] = fd;
-      custom_std_fds_valid[no] = 1;
-    }
-  ESTREAM_LIST_UNLOCK;
-}
-
-
-/* Return the stream used for stdin, stdout or stderr.  */
-estream_t
-_es_get_std_stream (int fd)
-{
-  estream_list_t list_obj;
-  estream_t stream = NULL;
-
-  fd %= 3; /* We only allow 0, 1 or 2 but we don't want to return an error. */
-  ESTREAM_LIST_LOCK;
-  for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr)
-    if (list_obj->car->intern->is_stdstream
-        && list_obj->car->intern->stdstream_fd == fd)
-      {
-       stream = list_obj->car;
-       break;
-      }
-  if (!stream)
-    {
-      /* Standard stream not yet created.  We first try to create them
-         from registered file descriptors.  */
-      if (!fd && custom_std_fds_valid[0])
-        stream = do_fdopen (custom_std_fds[0], "r", 1, 1);
-      else if (fd == 1 && custom_std_fds_valid[1])
-        stream = do_fdopen (custom_std_fds[1], "a", 1, 1);
-      else if (custom_std_fds_valid[2])
-        stream = do_fdopen (custom_std_fds[2], "a", 1, 1);
-
-      if (!stream)
-        {
-          /* Second try is to use the standard C streams.  */
-          if (!fd)
-            stream = do_fpopen (stdin, "r", 1, 1);
-          else if (fd == 1)
-            stream = do_fpopen (stdout, "a", 1, 1);
-          else
-            stream = do_fpopen (stderr, "a", 1, 1);
-        }
-
-      if (!stream)
-        {
-          /* Last try: Create a bit bucket.  */
-          stream = do_fpopen (NULL, fd? "a":"r", 0, 1);
-          if (!stream)
-            {
-              fprintf (stderr, "fatal: error creating a dummy estream"
-                       " for %d: %s\n", fd, strerror (errno));
-              abort();
-            }
-        }
-
-      stream->intern->is_stdstream = 1;
-      stream->intern->stdstream_fd = fd;
-      if (fd == 2)
-        es_set_buffering (stream, NULL, _IOLBF, 0);
-      fname_set_internal (stream,
-                          fd == 0? "[stdin]" :
-                          fd == 1? "[stdout]" : "[stderr]", 0);
-    }
-  ESTREAM_LIST_UNLOCK;
-  return stream;
-}
-
-
-estream_t
-es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode,
-           estream_t ES__RESTRICT stream)
-{
-  int err;
-
-  if (path)
-    {
-      unsigned int modeflags;
-      int create_called;
-      void *cookie;
-      int fd;
-
-      cookie = NULL;
-      create_called = 0;
-
-      ESTREAM_LOCK (stream);
-
-      es_deinitialize (stream);
-
-      err = es_convert_mode (mode, &modeflags);
-      if (err)
-       goto leave;
-
-      err = es_func_file_create (&cookie, &fd, path, modeflags);
-      if (err)
-       goto leave;
-
-      create_called = 1;
-      es_initialize (stream, cookie, fd, estream_functions_fd, modeflags);
-
-    leave:
-
-      if (err)
-       {
-         if (create_called)
-           es_func_fd_destroy (cookie);
-
-         es_destroy (stream, 0);
-         stream = NULL;
-       }
-      else
-        {
-          if (stream && path)
-            fname_set_internal (stream, path, 1);
-          ESTREAM_UNLOCK (stream);
-        }
-    }
-  else
-    {
-      /* FIXME?  We don't support re-opening at the moment.  */
-      _set_errno (EINVAL);
-      es_deinitialize (stream);
-      es_destroy (stream, 0);
-      stream = NULL;
-    }
-
-  return stream;
-}
-
-
-int
-es_fclose (estream_t stream)
-{
-  int err;
-
-  err = es_destroy (stream, 0);
-
-  return err;
-}
-
-
-/* This is a special version of es_fclose which can be used with
-   es_fopenmem to return the memory buffer.  This is feature is useful
-   to write to a memory buffer using estream.  Note that the function
-   does not close the stream if the stream does not support snatching
-   the buffer.  On error NULL is stored at R_BUFFER.  Note that if no
-   write operation has happened, NULL may also be stored at BUFFER on
-   success.  The caller needs to release the returned memory using
-   es_free.  */
-int
-es_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen)
-{
-  int err;
-
-  /* Note: There is no need to lock the stream in a close call.  The
-     object will be destroyed after the close and thus any other
-     contender for the lock would work on a closed stream.  */
-
-  if (r_buffer)
-    {
-      cookie_ioctl_function_t func_ioctl = stream->intern->func_ioctl;
-      size_t buflen;
-
-      *r_buffer = NULL;
-
-      if (!func_ioctl)
-        {
-          _set_errno (EOPNOTSUPP);
-          err = -1;
-          goto leave;
-        }
-
-      if (stream->flags.writing)
-        {
-          err = es_flush (stream);
-          if (err)
-            goto leave;
-          stream->flags.writing = 0;
-        }
-
-      err = func_ioctl (stream->intern->cookie, COOKIE_IOCTL_SNATCH_BUFFER,
-                        r_buffer, &buflen);
-      if (err)
-        goto leave;
-      if (r_buflen)
-        *r_buflen = buflen;
-    }
-
-  err = es_destroy (stream, 0);
-
- leave:
-  if (err && r_buffer)
-    {
-      mem_free (*r_buffer);
-      *r_buffer = NULL;
-    }
-  return err;
-}
-
-
-int
-es_fileno_unlocked (estream_t stream)
-{
-  return es_get_fd (stream);
-}
-
-
-void
-es_flockfile (estream_t stream)
-{
-  ESTREAM_LOCK (stream);
-}
-
-
-int
-es_ftrylockfile (estream_t stream)
-{
-  return ESTREAM_TRYLOCK (stream);
-}
-
-
-void
-es_funlockfile (estream_t stream)
-{
-  ESTREAM_UNLOCK (stream);
-}
-
-
-int
-es_fileno (estream_t stream)
-{
-  int ret;
-
-  ESTREAM_LOCK (stream);
-  ret = es_fileno_unlocked (stream);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-int
-es_feof_unlocked (estream_t stream)
-{
-  return es_get_indicator (stream, 0, 1);
-}
-
-
-int
-es_feof (estream_t stream)
-{
-  int ret;
-
-  ESTREAM_LOCK (stream);
-  ret = es_feof_unlocked (stream);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-int
-es_ferror_unlocked (estream_t stream)
-{
-  return es_get_indicator (stream, 1, 0);
-}
-
-
-int
-es_ferror (estream_t stream)
-{
-  int ret;
-
-  ESTREAM_LOCK (stream);
-  ret = es_ferror_unlocked (stream);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-void
-es_clearerr_unlocked (estream_t stream)
-{
-  es_set_indicators (stream, 0, 0);
-}
-
-
-void
-es_clearerr (estream_t stream)
-{
-  ESTREAM_LOCK (stream);
-  es_clearerr_unlocked (stream);
-  ESTREAM_UNLOCK (stream);
-}
-
-
-static int
-do_fflush (estream_t stream)
-{
-  int err;
-
-  if (stream->flags.writing)
-    err = es_flush (stream);
-  else
-    {
-      es_empty (stream);
-      err = 0;
-    }
-
-  return err;
-}
-
-
-int
-es_fflush (estream_t stream)
-{
-  int err;
-
-  if (stream)
-    {
-      ESTREAM_LOCK (stream);
-      err = do_fflush (stream);
-      ESTREAM_UNLOCK (stream);
-    }
-  else
-    err = es_list_iterate (do_fflush);
-
-  return err ? EOF : 0;
-}
-
-
-int
-es_fseek (estream_t stream, long int offset, int whence)
-{
-  int err;
-
-  ESTREAM_LOCK (stream);
-  err = es_seek (stream, offset, whence, NULL);
-  ESTREAM_UNLOCK (stream);
-
-  return err;
-}
-
-
-int
-es_fseeko (estream_t stream, off_t offset, int whence)
-{
-  int err;
-
-  ESTREAM_LOCK (stream);
-  err = es_seek (stream, offset, whence, NULL);
-  ESTREAM_UNLOCK (stream);
-
-  return err;
-}
-
-
-long int
-es_ftell (estream_t stream)
-{
-  long int ret;
-
-  ESTREAM_LOCK (stream);
-  ret = es_offset_calculate (stream);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-off_t
-es_ftello (estream_t stream)
-{
-  off_t ret = -1;
-
-  ESTREAM_LOCK (stream);
-  ret = es_offset_calculate (stream);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-void
-es_rewind (estream_t stream)
-{
-  ESTREAM_LOCK (stream);
-  es_seek (stream, 0L, SEEK_SET, NULL);
-  es_set_indicators (stream, 0, -1);
-  ESTREAM_UNLOCK (stream);
-}
-
-
-int
-_es_getc_underflow (estream_t stream)
-{
-  int err;
-  unsigned char c;
-  size_t bytes_read;
-
-  err = es_readn (stream, &c, 1, &bytes_read);
-
-  return (err || (! bytes_read)) ? EOF : c;
-}
-
-
-int
-_es_putc_overflow (int c, estream_t stream)
-{
-  unsigned char d = c;
-  int err;
-
-  err = es_writen (stream, &d, 1, NULL);
-
-  return err ? EOF : c;
-}
-
-
-int
-es_fgetc (estream_t stream)
-{
-  int ret;
-
-  ESTREAM_LOCK (stream);
-  ret = es_getc_unlocked (stream);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-int
-es_fputc (int c, estream_t stream)
-{
-  int ret;
-
-  ESTREAM_LOCK (stream);
-  ret = es_putc_unlocked (c, stream);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-int
-es_ungetc (int c, estream_t stream)
-{
-  unsigned char data = (unsigned char) c;
-  size_t data_unread;
-
-  ESTREAM_LOCK (stream);
-  es_unreadn (stream, &data, 1, &data_unread);
-  ESTREAM_UNLOCK (stream);
-
-  return data_unread ? c : EOF;
-}
-
-
-int
-es_read (estream_t ES__RESTRICT stream,
-        void *ES__RESTRICT buffer, size_t bytes_to_read,
-        size_t *ES__RESTRICT bytes_read)
-{
-  int err;
-
-  if (bytes_to_read)
-    {
-      ESTREAM_LOCK (stream);
-      err = es_readn (stream, buffer, bytes_to_read, bytes_read);
-      ESTREAM_UNLOCK (stream);
-    }
-  else
-    err = 0;
-
-  return err;
-}
-
-
-int
-es_write (estream_t ES__RESTRICT stream,
-         const void *ES__RESTRICT buffer, size_t bytes_to_write,
-         size_t *ES__RESTRICT bytes_written)
-{
-  int err;
-
-  if (bytes_to_write)
-    {
-      ESTREAM_LOCK (stream);
-      err = es_writen (stream, buffer, bytes_to_write, bytes_written);
-      ESTREAM_UNLOCK (stream);
-    }
-  else
-    err = 0;
-
-  return err;
-}
-
-
-size_t
-es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems,
-         estream_t ES__RESTRICT stream)
-{
-  size_t ret, bytes;
-
-  if (size * nitems)
-    {
-      ESTREAM_LOCK (stream);
-      es_readn (stream, ptr, size * nitems, &bytes);
-      ESTREAM_UNLOCK (stream);
-
-      ret = bytes / size;
-    }
-  else
-    ret = 0;
-
-  return ret;
-}
-
-
-size_t
-es_fwrite (const void *ES__RESTRICT ptr, size_t size, size_t nitems,
-          estream_t ES__RESTRICT stream)
-{
-  size_t ret, bytes;
-
-  if (size * nitems)
-    {
-      ESTREAM_LOCK (stream);
-      es_writen (stream, ptr, size * nitems, &bytes);
-      ESTREAM_UNLOCK (stream);
-
-      ret = bytes / size;
-    }
-  else
-    ret = 0;
-
-  return ret;
-}
-
-
-char *
-es_fgets (char *ES__RESTRICT buffer, int length, estream_t ES__RESTRICT stream)
-{
-  unsigned char *s = (unsigned char*)buffer;
-  int c;
-
-  if (!length)
-    return NULL;
-
-  c = EOF;
-  ESTREAM_LOCK (stream);
-  while (length > 1 && (c = es_getc_unlocked (stream)) != EOF && c != '\n')
-    {
-      *s++ = c;
-      length--;
-    }
-  ESTREAM_UNLOCK (stream);
-
-  if (c == EOF && s == (unsigned char*)buffer)
-    return NULL; /* Nothing read.  */
-
-  if (c != EOF && length > 1)
-    *s++ = c;
-
-  *s = 0;
-  return buffer;
-}
-
-
-int
-es_fputs_unlocked (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream)
-{
-  size_t length;
-  int err;
-
-  length = strlen (s);
-  err = es_writen (stream, s, length, NULL);
-  return err ? EOF : 0;
-}
-
-int
-es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream)
-{
-  size_t length;
-  int err;
-
-  length = strlen (s);
-  ESTREAM_LOCK (stream);
-  err = es_writen (stream, s, length, NULL);
-  ESTREAM_UNLOCK (stream);
-
-  return err ? EOF : 0;
-}
-
-
-ssize_t
-es_getline (char *ES__RESTRICT *ES__RESTRICT lineptr, size_t *ES__RESTRICT n,
-           estream_t ES__RESTRICT stream)
-{
-  char *line = NULL;
-  size_t line_n = 0;
-  int err;
-
-  ESTREAM_LOCK (stream);
-  err = doreadline (stream, 0, &line, &line_n);
-  ESTREAM_UNLOCK (stream);
-  if (err)
-    goto out;
-
-  if (*n)
-    {
-      /* Caller wants us to use his buffer.  */
-
-      if (*n < (line_n + 1))
-       {
-         /* Provided buffer is too small -> resize.  */
-
-         void *p;
-
-         p = mem_realloc (*lineptr, line_n + 1);
-         if (! p)
-           err = -1;
-         else
-           {
-             if (*lineptr != p)
-               *lineptr = p;
-           }
-       }
-
-      if (! err)
-       {
-         memcpy (*lineptr, line, line_n + 1);
-         if (*n != line_n)
-           *n = line_n;
-       }
-      mem_free (line);
-    }
-  else
-    {
-      /* Caller wants new buffers.  */
-      *lineptr = line;
-      *n = line_n;
-    }
-
- out:
-
-  return err ? err : (ssize_t)line_n;
-}
-
-
-
-/* Same as fgets() but if the provided buffer is too short a larger
-   one will be allocated.  This is similar to getline. A line is
-   considered a byte stream ending in a LF.
-
-   If MAX_LENGTH is not NULL, it shall point to a value with the
-   maximum allowed allocation.
-
-   Returns the length of the line. EOF is indicated by a line of
-   length zero. A truncated line is indicated my setting the value at
-   MAX_LENGTH to 0.  If the returned value is less then 0 not enough
-   memory was enable or another error occurred; ERRNO is then set
-   accordingly.
-
-   If a line has been truncated, the file pointer is moved forward to
-   the end of the line so that the next read starts with the next
-   line.  Note that MAX_LENGTH must be re-initialzied in this case.
-
-   The caller initially needs to provide the address of a variable,
-   initialized to NULL, at ADDR_OF_BUFFER and don't change this value
-   anymore with the following invocations.  LENGTH_OF_BUFFER should be
-   the address of a variable, initialized to 0, which is also
-   maintained by this function.  Thus, both paramaters should be
-   considered the state of this function.
-
-   Note: The returned buffer is allocated with enough extra space to
-   allow the caller to append a CR,LF,Nul.  The buffer should be
-   released using es_free.
- */
-ssize_t
-es_read_line (estream_t stream,
-              char **addr_of_buffer, size_t *length_of_buffer,
-              size_t *max_length)
-{
-  int c;
-  char  *buffer = *addr_of_buffer;
-  size_t length = *length_of_buffer;
-  size_t nbytes = 0;
-  size_t maxlen = max_length? *max_length : 0;
-  char *p;
-
-  if (!buffer)
-    {
-      /* No buffer given - allocate a new one. */
-      length = 256;
-      buffer = mem_alloc (length);
-      *addr_of_buffer = buffer;
-      if (!buffer)
-        {
-          *length_of_buffer = 0;
-          if (max_length)
-            *max_length = 0;
-          return -1;
-        }
-      *length_of_buffer = length;
-    }
-
-  if (length < 4)
-    {
-      /* This should never happen. If it does, the function has been
-         called with wrong arguments. */
-      _set_errno (EINVAL);
-      return -1;
-    }
-  length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */
-
-  ESTREAM_LOCK (stream);
-  p = buffer;
-  while  ((c = es_getc_unlocked (stream)) != EOF)
-    {
-      if (nbytes == length)
-        {
-          /* Enlarge the buffer. */
-          if (maxlen && length > maxlen)
-            {
-              /* We are beyond our limit: Skip the rest of the line. */
-              while (c != '\n' && (c=es_getc_unlocked (stream)) != EOF)
-                ;
-              *p++ = '\n'; /* Always append a LF (we reserved some space). */
-              nbytes++;
-              if (max_length)
-                *max_length = 0; /* Indicate truncation. */
-              break; /* the while loop. */
-            }
-          length += 3; /* Adjust for the reserved bytes. */
-          length += length < 1024? 256 : 1024;
-          *addr_of_buffer = mem_realloc (buffer, length);
-          if (!*addr_of_buffer)
-            {
-              int save_errno = errno;
-              mem_free (buffer);
-              *length_of_buffer = 0;
-              if (max_length)
-                *max_length = 0;
-              ESTREAM_UNLOCK (stream);
-              _set_errno (save_errno);
-              return -1;
-            }
-          buffer = *addr_of_buffer;
-          *length_of_buffer = length;
-          length -= 3;
-          p = buffer + nbytes;
-       }
-      *p++ = c;
-      nbytes++;
-      if (c == '\n')
-        break;
-    }
-  *p = 0; /* Make sure the line is a string. */
-  ESTREAM_UNLOCK (stream);
-
-  return nbytes;
-}
-
-/* Wrapper around free() to match the memory allocation system used
-   by estream.  Should be used for all buffers returned to the caller
-   by libestream. */
-void
-es_free (void *a)
-{
-  mem_free (a);
-}
-
-
-int
-es_vfprintf_unlocked (estream_t ES__RESTRICT stream,
-                      const char *ES__RESTRICT format,
-                      va_list ap)
-{
-  return es_print (stream, format, ap);
-}
-
-
-int
-es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format,
-            va_list ap)
-{
-  int ret;
-
-  ESTREAM_LOCK (stream);
-  ret = es_print (stream, format, ap);
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-int
-es_fprintf_unlocked (estream_t ES__RESTRICT stream,
-                     const char *ES__RESTRICT format, ...)
-{
-  int ret;
-
-  va_list ap;
-  va_start (ap, format);
-  ret = es_print (stream, format, ap);
-  va_end (ap);
-
-  return ret;
-}
-
-
-int
-es_fprintf (estream_t ES__RESTRICT stream,
-           const char *ES__RESTRICT format, ...)
-{
-  int ret;
-
-  va_list ap;
-  va_start (ap, format);
-  ESTREAM_LOCK (stream);
-  ret = es_print (stream, format, ap);
-  ESTREAM_UNLOCK (stream);
-  va_end (ap);
-
-  return ret;
-}
-
-/* A variant of asprintf.  The function returns the allocated buffer
-   or NULL on error; ERRNO is set in the error case.  The caller
-   should use es_free to release the buffer.  This function actually
-   belongs into estream-printf but we put it here as a convenience
-   and because es_free is required anyway.  */
-char *
-es_asprintf (const char *ES__RESTRICT format, ...)
-{
-  int rc;
-  va_list ap;
-  char *buf;
-
-  va_start (ap, format);
-  rc = estream_vasprintf (&buf, format, ap);
-  va_end (ap);
-  if (rc < 0)
-    return NULL;
-  return buf;
-}
-
-
-/* A variant of vasprintf.  The function returns the allocated buffer
-   or NULL on error; ERRNO is set in the error case.  The caller
-   should use es_free to release the buffer.  This function actually
-   belongs into estream-printf but we put it here as a convenience
-   and because es_free is required anyway.  */
-char *
-es_vasprintf (const char *ES__RESTRICT format, va_list ap)
-{
-  int rc;
-  char *buf;
-
-  rc = estream_vasprintf (&buf, format, ap);
-  if (rc < 0)
-    return NULL;
-  return buf;
-}
-
-
-static int
-tmpfd (void)
-{
-#ifdef HAVE_W32_SYSTEM
-  int attempts, n;
-#ifdef HAVE_W32CE_SYSTEM
-  wchar_t buffer[MAX_PATH+9+12+1];
-# define mystrlen(a) wcslen (a)
-  wchar_t *name, *p;
-#else
-  char buffer[MAX_PATH+9+12+1];
-# define mystrlen(a) strlen (a)
-  char *name, *p;
-#endif
-  HANDLE file;
-  int pid = GetCurrentProcessId ();
-  unsigned int value;
-  int i;
-
-  n = GetTempPath (MAX_PATH+1, buffer);
-  if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
-    {
-      _set_errno (ENOENT);
-      return -1;
-    }
-  p = buffer + mystrlen (buffer);
-#ifdef HAVE_W32CE_SYSTEM
-  wcscpy (p, L"_estream");
-#else
-  strcpy (p, "_estream");
-#endif
-  p += 8;
-  /* We try to create the directory but don't care about an error as
-     it may already exist and the CreateFile would throw an error
-     anyway.  */
-  CreateDirectory (buffer, NULL);
-  *p++ = '\\';
-  name = p;
-  for (attempts=0; attempts < 10; attempts++)
-    {
-      p = name;
-      value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
-      for (i=0; i < 8; i++)
-        {
-          *p++ = tohex (((value >> 28) & 0x0f));
-          value <<= 4;
-        }
-#ifdef HAVE_W32CE_SYSTEM
-      wcscpy (p, L".tmp");
-#else
-      strcpy (p, ".tmp");
-#endif
-      file = CreateFile (buffer,
-                         GENERIC_READ | GENERIC_WRITE,
-                         0,
-                         NULL,
-                         CREATE_NEW,
-                         FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
-                         NULL);
-      if (file != INVALID_HANDLE_VALUE)
-        {
-#ifdef HAVE_W32CE_SYSTEM
-          int fd = (int)file;
-#else
-          int fd = _open_osfhandle ((long)file, 0);
-          if (fd == -1)
-            {
-              CloseHandle (file);
-              return -1;
-            }
-#endif
-          return fd;
-        }
-      Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
-    }
-  _set_errno (ENOENT);
-  return -1;
-#else /*!HAVE_W32_SYSTEM*/
-  FILE *fp;
-  int fp_fd;
-  int fd;
-
-  fp = NULL;
-  fd = -1;
-
-  fp = tmpfile ();
-  if (! fp)
-    goto out;
-
-  fp_fd = fileno (fp);
-  fd = dup (fp_fd);
-
- out:
-
-  if (fp)
-    fclose (fp);
-
-  return fd;
-#endif /*!HAVE_W32_SYSTEM*/
-}
-
-estream_t
-es_tmpfile (void)
-{
-  unsigned int modeflags;
-  int create_called;
-  estream_t stream;
-  void *cookie;
-  int err;
-  int fd;
-
-  create_called = 0;
-  stream = NULL;
-  modeflags = O_RDWR | O_TRUNC | O_CREAT;
-  cookie = NULL;
-
-  fd = tmpfd ();
-  if (fd == -1)
-    {
-      err = -1;
-      goto out;
-    }
-
-  err = es_func_fd_create (&cookie, fd, modeflags, 0);
-  if (err)
-    goto out;
-
-  create_called = 1;
-  err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0);
-
- out:
-
-  if (err)
-    {
-      if (create_called)
-       es_func_fd_destroy (cookie);
-      else if (fd != -1)
-       close (fd);
-      stream = NULL;
-    }
-
-  return stream;
-}
-
-
-int
-es_setvbuf (estream_t ES__RESTRICT stream,
-           char *ES__RESTRICT buf, int type, size_t size)
-{
-  int err;
-
-  if ((type == _IOFBF || type == _IOLBF || type == _IONBF)
-      && (!buf || size || type == _IONBF))
-    {
-      ESTREAM_LOCK (stream);
-      err = es_set_buffering (stream, buf, type, size);
-      ESTREAM_UNLOCK (stream);
-    }
-  else
-    {
-      _set_errno (EINVAL);
-      err = -1;
-    }
-
-  return err;
-}
-
-
-void
-es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf)
-{
-  ESTREAM_LOCK (stream);
-  es_set_buffering (stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
-  ESTREAM_UNLOCK (stream);
-}
-
-void
-es_opaque_set (estream_t stream, void *opaque)
-{
-  ESTREAM_LOCK (stream);
-  es_opaque_ctrl (stream, opaque, NULL);
-  ESTREAM_UNLOCK (stream);
-}
-
-
-void *
-es_opaque_get (estream_t stream)
-{
-  void *opaque;
-
-  ESTREAM_LOCK (stream);
-  es_opaque_ctrl (stream, NULL, &opaque);
-  ESTREAM_UNLOCK (stream);
-
-  return opaque;
-}
-
-
-static void
-fname_set_internal (estream_t stream, const char *fname, int quote)
-{
-  if (stream->intern->printable_fname
-      && !stream->intern->printable_fname_inuse)
-    {
-      mem_free (stream->intern->printable_fname);
-      stream->intern->printable_fname = NULL;
-    }
-  if (stream->intern->printable_fname)
-    return; /* Can't change because it is in use.  */
-
-  if (*fname != '[')
-    quote = 0;
-  else
-    quote = !!quote;
-
-  stream->intern->printable_fname = mem_alloc (strlen (fname) + quote + 1);
-  if (fname)
-    {
-      if (quote)
-        stream->intern->printable_fname[0] = '\\';
-      strcpy (stream->intern->printable_fname+quote, fname);
-    }
-}
-
-
-/* Set the filename attribute of STREAM.  There is no error return.
-   as long as STREAM is valid.  This function is called internally by
-   functions which open a filename.  */
-void
-es_fname_set (estream_t stream, const char *fname)
-{
-  if (fname)
-    {
-      ESTREAM_LOCK (stream);
-      fname_set_internal (stream, fname, 1);
-      ESTREAM_UNLOCK (stream);
-    }
-}
-
-
-/* Return the filename attribute of STREAM.  In case no filename has
-   been set, "[?]" will be returned.  The returned file name is valid
-   as long as STREAM is valid.  */
-const char *
-es_fname_get (estream_t stream)
-{
-  const char *fname;
-
-  ESTREAM_LOCK (stream);
-  fname = stream->intern->printable_fname;
-  if (fname)
-    stream->intern->printable_fname_inuse = 1;
-  ESTREAM_UNLOCK (stream);
-  if (!fname)
-    fname = "[?]";
-  return fname;
-}
-
-
-/* Print a BUFFER to STREAM while replacing all control characters and
-   the characters in DELIMITERS by standard C escape sequences.
-   Returns 0 on success or -1 on error.  If BYTES_WRITTEN is not NULL
-   the number of bytes actually written are stored at this
-   address.  */
-int
-es_write_sanitized (estream_t ES__RESTRICT stream,
-                    const void * ES__RESTRICT buffer, size_t length,
-                    const char * delimiters,
-                    size_t * ES__RESTRICT bytes_written)
-{
-  const unsigned char *p = buffer;
-  size_t count = 0;
-  int ret;
-
-  ESTREAM_LOCK (stream);
-  for (; length; length--, p++, count++)
-    {
-      if (*p < 0x20
-          || *p == 0x7f
-          || (delimiters
-              && (strchr (delimiters, *p) || *p == '\\')))
-        {
-          es_putc_unlocked ('\\', stream);
-          count++;
-          if (*p == '\n')
-            {
-              es_putc_unlocked ('n', stream);
-              count++;
-            }
-          else if (*p == '\r')
-            {
-              es_putc_unlocked ('r', stream);
-              count++;
-            }
-          else if (*p == '\f')
-            {
-              es_putc_unlocked ('f', stream);
-              count++;
-            }
-          else if (*p == '\v')
-            {
-              es_putc_unlocked ('v', stream);
-              count++;
-            }
-          else if (*p == '\b')
-            {
-              es_putc_unlocked ('b', stream);
-              count++;
-            }
-          else if (!*p)
-            {
-              es_putc_unlocked('0', stream);
-              count++;
-            }
-          else
-            {
-              es_fprintf_unlocked (stream, "x%02x", *p);
-              count += 3;
-            }
-       }
-      else
-        {
-          es_putc_unlocked (*p, stream);
-          count++;
-        }
-    }
-
-  if (bytes_written)
-    *bytes_written = count;
-  ret =  es_ferror_unlocked (stream)? -1 : 0;
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-}
-
-
-/* Write LENGTH bytes of BUFFER to STREAM as a hex encoded string.
-   RESERVED must be 0.  Returns 0 on success or -1 on error.  If
-   BYTES_WRITTEN is not NULL the number of bytes actually written are
-   stored at this address.  */
-int
-es_write_hexstring (estream_t ES__RESTRICT stream,
-                    const void *ES__RESTRICT buffer, size_t length,
-                    int reserved, size_t *ES__RESTRICT bytes_written )
-{
-  int ret;
-  const unsigned char *s;
-  size_t count = 0;
-
-  (void)reserved;
-
-#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
-
-  if (!length)
-    return 0;
-
-  ESTREAM_LOCK (stream);
-
-  for (s = buffer; length; s++, length--)
-    {
-      es_putc_unlocked ( tohex ((*s>>4)&15), stream);
-      es_putc_unlocked ( tohex (*s&15), stream);
-      count += 2;
-    }
-
-  if (bytes_written)
-    *bytes_written = count;
-  ret = es_ferror_unlocked (stream)? -1 : 0;
-
-  ESTREAM_UNLOCK (stream);
-
-  return ret;
-
-#undef tohex
-}
-
-
-
-#ifdef GNUPG_MAJOR_VERSION
-/* Special estream function to print an UTF8 string in the native
-   encoding.  The interface is the same as es_write_sanitized, however
-   only one delimiter may be supported.
-
-   THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG!. */
-int
-es_write_sanitized_utf8_buffer (estream_t stream,
-                                const void *buffer, size_t length,
-                                const char *delimiters, size_t *bytes_written)
-{
-  const char *p = buffer;
-  size_t i;
-
-  /* We can handle plain ascii simpler, so check for it first. */
-  for (i=0; i < length; i++ )
-    {
-      if ( (p[i] & 0x80) )
-        break;
-    }
-  if (i < length)
-    {
-      int delim = delimiters? *delimiters : 0;
-      char *buf;
-      int ret;
-
-      /*(utf8 conversion already does the control character quoting). */
-      buf = utf8_to_native (p, length, delim);
-      if (bytes_written)
-        *bytes_written = strlen (buf);
-      ret = es_fputs (buf, stream);
-      xfree (buf);
-      return ret == EOF? ret : (int)i;
-    }
-  else
-    return es_write_sanitized (stream, p, length, delimiters, bytes_written);
-}
-#endif /*GNUPG_MAJOR_VERSION*/
diff --git a/common/estream.h b/common/estream.h
deleted file mode 100644 (file)
index 35df20b..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-/* estream.h - Extended stream I/O Library
- * Copyright (C) 2004, 2005, 2006, 2007, 2010 g10 Code GmbH
- *
- * This file is part of Libestream.
- *
- * Libestream 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.
- *
- * Libestream 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 Libestream; if not, see <http://www.gnu.org/licenses/>.
- *
- * ALTERNATIVELY, Libestream may be distributed under the terms of the
- * following license, in which case the provisions of this license are
- * required INSTEAD OF the GNU General Public License. If you wish to
- * allow use of your version of this file only under the terms of the
- * GNU General Public License, and not to allow others to use your
- * version of this file under the terms of the following license,
- * indicate your decision by deleting this paragraph and the license
- * below.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, and the entire permission notice in its entirety,
- *    including the disclaimer of warranties.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ESTREAM_H
-#define ESTREAM_H
-
-#include <sys/types.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-/* To use this file with libraries the following macro is useful:
-
-     #define _ESTREAM_EXT_SYM_PREFIX _foo_
-
-       This prefixes all external symbols with "_foo_".
-
- */
-
-
-#ifdef _ESTREAM_EXT_SYM_PREFIX
-#ifndef _ESTREAM_PREFIX
-#define _ESTREAM_PREFIX1(x,y)  x ## y
-#define _ESTREAM_PREFIX2(x,y) _ESTREAM_PREFIX1(x,y)
-#define _ESTREAM_PREFIX(x)    _ESTREAM_PREFIX2(_ESTREAM_EXT_SYM_PREFIX,x)
-#endif /*_ESTREAM_PREFIX*/
-#define es_fopen              _ESTREAM_PREFIX(es_fopen)
-#define es_mopen              _ESTREAM_PREFIX(es_mopen)
-#define es_fopenmem           _ESTREAM_PREFIX(es_fopenmem)
-#define es_fopenmem_init      _ESTREAM_PREFIX(es_fopenmem_init)
-#define es_fdopen             _ESTREAM_PREFIX(es_fdopen)
-#define es_fdopen_nc          _ESTREAM_PREFIX(es_fdopen_nc)
-#define es_fpopen             _ESTREAM_PREFIX(es_fpopen)
-#define es_fpopen_nc          _ESTREAM_PREFIX(es_fpopen_nc)
-#define _es_set_std_fd        _ESTREAM_PREFIX(_es_set_std_fd)
-#define _es_get_std_stream    _ESTREAM_PREFIX(_es_get_std_stream)
-#define es_freopen            _ESTREAM_PREFIX(es_freopen)
-#define es_fopencookie        _ESTREAM_PREFIX(es_fopencookie)
-#define es_fclose             _ESTREAM_PREFIX(es_fclose)
-#define es_fclose_snatch      _ESTREAM_PREFIX(es_fclose_snatch)
-#define es_fileno             _ESTREAM_PREFIX(es_fileno)
-#define es_fileno_unlocked    _ESTREAM_PREFIX(es_fileno_unlocked)
-#define es_flockfile          _ESTREAM_PREFIX(es_flockfile)
-#define es_ftrylockfile       _ESTREAM_PREFIX(es_ftrylockfile)
-#define es_funlockfile        _ESTREAM_PREFIX(es_funlockfile)
-#define es_feof               _ESTREAM_PREFIX(es_feof)
-#define es_feof_unlocked      _ESTREAM_PREFIX(es_feof_unlocked)
-#define es_ferror             _ESTREAM_PREFIX(es_ferror)
-#define es_ferror_unlocked    _ESTREAM_PREFIX(es_ferror_unlocked)
-#define es_clearerr           _ESTREAM_PREFIX(es_clearerr)
-#define es_clearerr_unlocked  _ESTREAM_PREFIX(es_clearerr_unlocked)
-#define es_fflush             _ESTREAM_PREFIX(es_fflush)
-#define es_fseek              _ESTREAM_PREFIX(es_fseek)
-#define es_fseeko             _ESTREAM_PREFIX(es_fseeko)
-#define es_ftell              _ESTREAM_PREFIX(es_ftell)
-#define es_ftello             _ESTREAM_PREFIX(es_ftello)
-#define es_rewind             _ESTREAM_PREFIX(es_rewind)
-#define es_fgetc              _ESTREAM_PREFIX(es_fgetc)
-#define es_fputc              _ESTREAM_PREFIX(es_fputc)
-#define _es_getc_underflow    _ESTREAM_PREFIX(_es_getc_underflow)
-#define _es_putc_overflow     _ESTREAM_PREFIX(_es_putc_overflow)
-#define es_ungetc             _ESTREAM_PREFIX(es_ungetc)
-#define es_read               _ESTREAM_PREFIX(es_read)
-#define es_write              _ESTREAM_PREFIX(es_write)
-#define es_write_sanitized    _ESTREAM_PREFIX(es_write_sanitized)
-#define es_write_hexstring    _ESTREAM_PREFIX(es_write_hexstring)
-#define es_fread              _ESTREAM_PREFIX(es_fread)
-#define es_fwrite             _ESTREAM_PREFIX(es_fwrite)
-#define es_fgets              _ESTREAM_PREFIX(es_fgets)
-#define es_fputs              _ESTREAM_PREFIX(es_fputs)
-#define es_fputs_unlocked     _ESTREAM_PREFIX(es_fputs_unlocked)
-#define es_getline            _ESTREAM_PREFIX(es_getline)
-#define es_read_line          _ESTREAM_PREFIX(es_read_line)
-#define es_free               _ESTREAM_PREFIX(es_free)
-#define es_fprintf            _ESTREAM_PREFIX(es_fprintf)
-#define es_fprintf_unlocked   _ESTREAM_PREFIX(es_fprintf_unlocked)
-#define es_vfprintf           _ESTREAM_PREFIX(es_vfprint)
-#define es_vfprintf_unlocked  _ESTREAM_PREFIX(es_vfprint_unlocked)
-#define es_setvbuf            _ESTREAM_PREFIX(es_setvbuf)
-#define es_setbuf             _ESTREAM_PREFIX(es_setbuf)
-#define es_tmpfile            _ESTREAM_PREFIX(es_tmpfile)
-#define es_opaque_set         _ESTREAM_PREFIX(es_opaque_set)
-#define es_opaque_get         _ESTREAM_PREFIX(es_opaque_get)
-#define es_fname_set          _ESTREAM_PREFIX(es_fname_set)
-#define es_fname_get          _ESTREAM_PREFIX(es_fname_get)
-#define es_write_sanitized_utf8_buffer  \
-              _ESTREAM_PREFIX(es_write_sanitized_utf8_buffer)
-#endif /*_ESTREAM_EXT_SYM_PREFIX*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0
-}
-#endif
-#endif
-
-
-/* Forward declaration for the (opaque) internal type.  */
-struct estream_internal;
-
-/* The definition of this struct is entirely private.  You must not
-   use it for anything.  It is only here so some functions can be
-   implemented as macros.  */
-struct es__stream
-{
-  /* The layout of this struct must never change.  It may be grown,
-     but only if all functions which access the new members are
-     versioned.  */
-
-  /* A pointer to the stream buffer.  */
-  unsigned char *buffer;
-
-  /* The size of the buffer in bytes.  */
-  size_t buffer_size;
-
-  /* The length of the usable data in the buffer, only valid when in
-     read mode (see flags).  */
-  size_t data_len;
-
-  /* The current position of the offset pointer, valid in read and
-     write mode.  */
-  size_t data_offset;
-
-  size_t data_flushed;
-  unsigned char *unread_buffer;
-  size_t unread_buffer_size;
-
-  /* The number of unread bytes.  */
-  size_t unread_data_len;
-
-  /* Various flags.  */
-  struct {
-    unsigned int writing: 1;
-    unsigned int reserved: 7;
-  } flags;
-
-  /* A pointer to our internal data for this stream.  */
-  struct estream_internal *intern;
-};
-
-/* The opaque type for an estream.  */
-typedef struct es__stream *estream_t;
-
-\f
-typedef ssize_t (*es_cookie_read_function_t) (void *cookie,
-                                             void *buffer, size_t size);
-typedef ssize_t (*es_cookie_write_function_t) (void *cookie,
-                                              const void *buffer,
-                                              size_t size);
-typedef int (*es_cookie_seek_function_t) (void *cookie,
-                                         off_t *pos, int whence);
-typedef int (*es_cookie_close_function_t) (void *cookie);
-
-typedef struct es_cookie_io_functions
-{
-  es_cookie_read_function_t func_read;
-  es_cookie_write_function_t func_write;
-  es_cookie_seek_function_t func_seek;
-  es_cookie_close_function_t func_close;
-} es_cookie_io_functions_t;
-
-\f
-#ifndef _ESTREAM_GCC_A_PRINTF
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
-# define _ESTREAM_GCC_A_PRINTF( f, a )  __attribute__ ((format (printf,f,a)))
-#else
-# define _ESTREAM_GCC_A_PRINTF( f, a )
-#endif
-#endif /*_ESTREAM_GCC_A_PRINTF*/
-
-
-#ifndef ES__RESTRICT
-#  if defined __GNUC__ && defined __GNUC_MINOR__
-#    if  (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 92))
-#      define ES__RESTRICT __restrict__
-#    endif
-#  endif
-#endif
-#ifndef ES__RESTRICT
-#  define ES__RESTRICT
-#endif
-
-int es_init (void);
-
-int es_pth_kill (void);
-
-estream_t es_fopen (const char *ES__RESTRICT path,
-                   const char *ES__RESTRICT mode);
-estream_t es_mopen (unsigned char *ES__RESTRICT data,
-                   size_t data_n, size_t data_len,
-                   unsigned int grow,
-                   void *(*func_realloc) (void *mem, size_t size),
-                   void (*func_free) (void *mem),
-                   const char *ES__RESTRICT mode);
-estream_t es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode);
-estream_t es_fopenmem_init (size_t memlimit, const char *ES__RESTRICT mode,
-                            const void *data, size_t datalen);
-estream_t es_fdopen (int filedes, const char *mode);
-estream_t es_fdopen_nc (int filedes, const char *mode);
-estream_t es_fpopen (FILE *fp, const char *mode);
-estream_t es_fpopen_nc (FILE *fp, const char *mode);
-estream_t es_freopen (const char *ES__RESTRICT path,
-                     const char *ES__RESTRICT mode,
-                     estream_t ES__RESTRICT stream);
-estream_t es_fopencookie (void *ES__RESTRICT cookie,
-                         const char *ES__RESTRICT mode,
-                         es_cookie_io_functions_t functions);
-int es_fclose (estream_t stream);
-int es_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen);
-int es_fileno (estream_t stream);
-int es_fileno_unlocked (estream_t stream);
-
-void _es_set_std_fd (int no, int fd);
-estream_t _es_get_std_stream (int fd);
-
-#define es_stdin  _es_get_std_stream (0)
-#define es_stdout _es_get_std_stream (1)
-#define es_stderr _es_get_std_stream (2)
-
-
-void es_flockfile (estream_t stream);
-int es_ftrylockfile (estream_t stream);
-void es_funlockfile (estream_t stream);
-
-int es_feof (estream_t stream);
-int es_feof_unlocked (estream_t stream);
-int es_ferror (estream_t stream);
-int es_ferror_unlocked (estream_t stream);
-void es_clearerr (estream_t stream);
-void es_clearerr_unlocked (estream_t stream);
-
-int es_fflush (estream_t stream);
-int es_fseek (estream_t stream, long int offset, int whence);
-int es_fseeko (estream_t stream, off_t offset, int whence);
-long int es_ftell (estream_t stream);
-off_t es_ftello (estream_t stream);
-void es_rewind (estream_t stream);
-
-int es_fgetc (estream_t stream);
-int es_fputc (int c, estream_t stream);
-
-int _es_getc_underflow (estream_t stream);
-int _es_putc_overflow (int c, estream_t stream);
-
-#define es_getc_unlocked(stream)                               \
-  (((!(stream)->flags.writing)                                 \
-    && ((stream)->data_offset < (stream)->data_len)            \
-    && (! (stream)->unread_data_len))                          \
-  ? ((int) (stream)->buffer[((stream)->data_offset)++])                \
-  : _es_getc_underflow ((stream)))
-
-#define es_putc_unlocked(c, stream)                            \
-  (((stream)->flags.writing                                    \
-    && ((stream)->data_offset < (stream)->buffer_size)         \
-    && (c != '\n'))                                            \
-  ? ((int) ((stream)->buffer[((stream)->data_offset)++] = (c)))        \
-  : _es_putc_overflow ((c), (stream)))
-
-#define es_getc(stream)    es_fgetc (stream)
-#define es_putc(c, stream) es_fputc (c, stream)
-
-int es_ungetc (int c, estream_t stream);
-
-int es_read (estream_t ES__RESTRICT stream,
-            void *ES__RESTRICT buffer, size_t bytes_to_read,
-            size_t *ES__RESTRICT bytes_read);
-int es_write (estream_t ES__RESTRICT stream,
-             const void *ES__RESTRICT buffer, size_t bytes_to_write,
-             size_t *ES__RESTRICT bytes_written);
-int es_write_sanitized (estream_t ES__RESTRICT stream,
-                        const void *ES__RESTRICT buffer, size_t length,
-                        const char *delimiters,
-                        size_t *ES__RESTRICT bytes_written);
-int es_write_hexstring (estream_t ES__RESTRICT stream,
-                        const void *ES__RESTRICT buffer, size_t length,
-                        int reserved, size_t *ES__RESTRICT bytes_written);
-
-size_t es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems,
-                estream_t ES__RESTRICT stream);
-size_t es_fwrite (const void *ES__RESTRICT ptr, size_t size, size_t memb,
-                 estream_t ES__RESTRICT stream);
-
-char *es_fgets (char *ES__RESTRICT s, int n, estream_t ES__RESTRICT stream);
-int es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream);
-int es_fputs_unlocked (const char *ES__RESTRICT s,
-                       estream_t ES__RESTRICT stream);
-
-ssize_t es_getline (char *ES__RESTRICT *ES__RESTRICT lineptr,
-                   size_t *ES__RESTRICT n,
-                   estream_t stream);
-ssize_t es_read_line (estream_t stream,
-                      char **addr_of_buffer, size_t *length_of_buffer,
-                      size_t *max_length);
-void es_free (void *a);
-
-int es_fprintf (estream_t ES__RESTRICT stream,
-               const char *ES__RESTRICT format, ...)
-     _ESTREAM_GCC_A_PRINTF(2,3);
-int es_fprintf_unlocked (estream_t ES__RESTRICT stream,
-                         const char *ES__RESTRICT format, ...)
-     _ESTREAM_GCC_A_PRINTF(2,3);
-
-int es_vfprintf (estream_t ES__RESTRICT stream,
-                const char *ES__RESTRICT format, va_list ap)
-     _ESTREAM_GCC_A_PRINTF(2,0);
-int es_vfprintf_unlocked (estream_t ES__RESTRICT stream,
-                          const char *ES__RESTRICT format, va_list ap)
-     _ESTREAM_GCC_A_PRINTF(2,0);
-
-int es_setvbuf (estream_t ES__RESTRICT stream,
-               char *ES__RESTRICT buf, int mode, size_t size);
-void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf);
-
-estream_t es_tmpfile (void);
-
-void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque);
-void *es_opaque_get (estream_t stream);
-
-void es_fname_set (estream_t stream, const char *fname);
-const char *es_fname_get (estream_t stream);
-
-
-#ifdef GNUPG_MAJOR_VERSION
-int es_write_sanitized_utf8_buffer (estream_t stream,
-                                    const void *buffer, size_t length,
-                                    const char *delimiters,
-                                    size_t *bytes_written);
-#endif /*GNUPG_MAJOR_VERSION*/
-
-#ifdef __cplusplus
-}
-#endif
-#endif /*ESTREAM_H*/
index 270e148..0d2f95e 100644 (file)
@@ -30,7 +30,7 @@ topheader == 1 && /\*\//   { topheader = 2; print "" }
 /AUDIT_NULL_EVENT/   { okay = 1 }
 !okay                { next }
 /AUDIT_LAST_EVENT/   { exit }
-/AUDIT_[A-Za-z_]+/  { 
+/AUDIT_[A-Za-z_]+/  {
   sub (/[,\/\*]+/, "", $1);
   desc = tolower (substr($1,7));
   gsub (/_/," ",desc);
diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c
new file mode 100644 (file)
index 0000000..1a1ff1b
--- /dev/null
@@ -0,0 +1,608 @@
+/* exechelp.c - Fork and exec helpers for POSIX
+ * Copyright (C) 2004, 2007, 2008, 2009,
+ *               2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_W32_SYSTEM) || defined (HAVE_W32CE_SYSTEM)
+#error This code is only used on POSIX
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+#undef HAVE_NPTH
+#undef USE_NPTH
+#endif
+
+#ifdef HAVE_NPTH
+#include <npth.h>
+#endif
+#include <sys/wait.h>
+
+#ifdef HAVE_GETRLIMIT
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif /*HAVE_GETRLIMIT*/
+
+#ifdef HAVE_STAT
+# include <sys/stat.h>
+#endif
+
+#include "util.h"
+#include "i18n.h"
+#include "sysutils.h"
+#include "exechelp.h"
+
+
+/* Return the maximum number of currently allowed open file
+   descriptors.  Only useful on POSIX systems but returns a value on
+   other systems too.  */
+int
+get_max_fds (void)
+{
+  int max_fds = -1;
+#ifdef HAVE_GETRLIMIT
+  struct rlimit rl;
+
+# ifdef RLIMIT_NOFILE
+  if (!getrlimit (RLIMIT_NOFILE, &rl))
+    max_fds = rl.rlim_max;
+# endif
+
+# ifdef RLIMIT_OFILE
+  if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
+    max_fds = rl.rlim_max;
+
+# endif
+#endif /*HAVE_GETRLIMIT*/
+
+#ifdef _SC_OPEN_MAX
+  if (max_fds == -1)
+    {
+      long int scres = sysconf (_SC_OPEN_MAX);
+      if (scres >= 0)
+        max_fds = scres;
+    }
+#endif
+
+#ifdef _POSIX_OPEN_MAX
+  if (max_fds == -1)
+    max_fds = _POSIX_OPEN_MAX;
+#endif
+
+#ifdef OPEN_MAX
+  if (max_fds == -1)
+    max_fds = OPEN_MAX;
+#endif
+
+  if (max_fds == -1)
+    max_fds = 256;  /* Arbitrary limit.  */
+
+  return max_fds;
+}
+
+
+/* Close all file descriptors starting with descriptor FIRST.  If
+   EXCEPT is not NULL, it is expected to be a list of file descriptors
+   which shall not be closed.  This list shall be sorted in ascending
+   order with the end marked by -1.  */
+void
+close_all_fds (int first, int *except)
+{
+  int max_fd = get_max_fds ();
+  int fd, i, except_start;
+
+  if (except)
+    {
+      except_start = 0;
+      for (fd=first; fd < max_fd; fd++)
+        {
+          for (i=except_start; except[i] != -1; i++)
+            {
+              if (except[i] == fd)
+                {
+                  /* If we found the descriptor in the exception list
+                     we can start the next compare run at the next
+                     index because the exception list is ordered.  */
+                except_start = i + 1;
+                break;
+                }
+            }
+          if (except[i] == -1)
+            close (fd);
+        }
+    }
+  else
+    {
+      for (fd=first; fd < max_fd; fd++)
+        close (fd);
+    }
+
+  gpg_err_set_errno (0);
+}
+
+
+/* Returns an array with all currently open file descriptors.  The end
+   of the array is marked by -1.  The caller needs to release this
+   array using the *standard free* and not with xfree.  This allow the
+   use of this fucntion right at startup even before libgcrypt has
+   been initialized.  Returns NULL on error and sets ERRNO
+   accordingly.  */
+int *
+get_all_open_fds (void)
+{
+  int *array;
+  size_t narray;
+  int fd, max_fd, idx;
+#ifndef HAVE_STAT
+  array = calloc (1, sizeof *array);
+  if (array)
+    array[0] = -1;
+#else /*HAVE_STAT*/
+  struct stat statbuf;
+
+  max_fd = get_max_fds ();
+  narray = 32;  /* If you change this change also t-exechelp.c.  */
+  array = calloc (narray, sizeof *array);
+  if (!array)
+    return NULL;
+
+  /* Note:  The list we return is ordered.  */
+  for (idx=0, fd=0; fd < max_fd; fd++)
+    if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
+      {
+        if (idx+1 >= narray)
+          {
+            int *tmp;
+
+            narray += (narray < 256)? 32:256;
+            tmp = realloc (array, narray * sizeof *array);
+            if (!tmp)
+              {
+                free (array);
+                return NULL;
+              }
+            array = tmp;
+          }
+        array[idx++] = fd;
+      }
+  array[idx] = -1;
+#endif /*HAVE_STAT*/
+  return array;
+}
+
+
+/* The exec core used right after the fork. This will never return. */
+static void
+do_exec (const char *pgmname, const char *argv[],
+         int fd_in, int fd_out, int fd_err,
+         void (*preexec)(void) )
+{
+  char **arg_list;
+  int i, j;
+  int fds[3];
+
+  fds[0] = fd_in;
+  fds[1] = fd_out;
+  fds[2] = fd_err;
+
+  /* Create the command line argument array.  */
+  i = 0;
+  if (argv)
+    while (argv[i])
+      i++;
+  arg_list = xcalloc (i+2, sizeof *arg_list);
+  arg_list[0] = strrchr (pgmname, '/');
+  if (arg_list[0])
+    arg_list[0]++;
+  else
+    arg_list[0] = xstrdup (pgmname);
+  if (argv)
+    for (i=0,j=1; argv[i]; i++, j++)
+      arg_list[j] = (char*)argv[i];
+
+  /* Assign /dev/null to unused FDs. */
+  for (i=0; i <= 2; i++)
+    {
+      if (fds[i] == -1 )
+        {
+          fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
+          if (fds[i] == -1)
+            log_fatal ("failed to open '%s': %s\n",
+                       "/dev/null", strerror (errno));
+        }
+    }
+
+  /* Connect the standard files.  */
+  for (i=0; i <= 2; i++)
+    {
+      if (fds[i] != i && dup2 (fds[i], i) == -1)
+        log_fatal ("dup2 std%s failed: %s\n",
+                   i==0?"in":i==1?"out":"err", strerror (errno));
+    }
+
+  /* Close all other files. */
+  close_all_fds (3, NULL);
+
+  if (preexec)
+    preexec ();
+  execv (pgmname, arg_list);
+  /* No way to print anything, as we have closed all streams. */
+  _exit (127);
+}
+
+
+static gpg_error_t
+do_create_pipe (int filedes[2])
+{
+  gpg_error_t err = 0;
+
+  if (pipe (filedes) == -1)
+    {
+      err = gpg_error_from_syserror ();
+      filedes[0] = filedes[1] = -1;
+    }
+
+  return err;
+}
+
+/* Portable function to create a pipe.  Under Windows the write end is
+   inheritable.  */
+gpg_error_t
+gnupg_create_inbound_pipe (int filedes[2])
+{
+  return do_create_pipe (filedes);
+}
+
+
+/* Portable function to create a pipe.  Under Windows the read end is
+   inheritable.  */
+gpg_error_t
+gnupg_create_outbound_pipe (int filedes[2])
+{
+  return do_create_pipe (filedes);
+}
+
+
+
+static gpg_error_t
+create_pipe_and_estream (int filedes[2], estream_t *r_fp,
+                         gpg_err_source_t errsource)
+{
+  gpg_error_t err;
+
+  if (pipe (filedes) == -1)
+    {
+      err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+      filedes[0] = filedes[1] = -1;
+      *r_fp = NULL;
+      return err;
+    }
+
+  *r_fp = es_fdopen (filedes[0], "r");
+  if (!*r_fp)
+    {
+      err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+      log_error (_("error creating a stream for a pipe: %s\n"),
+                 gpg_strerror (err));
+      close (filedes[0]);
+      close (filedes[1]);
+      filedes[0] = filedes[1] = -1;
+      return err;
+    }
+  return 0;
+}
+
+
+
+/* Fork and exec the PGMNAME, see exechelp.h for details.  */
+gpg_error_t
+gnupg_spawn_process (const char *pgmname, const char *argv[],
+                     gpg_err_source_t errsource,
+                     void (*preexec)(void), unsigned int flags,
+                     estream_t infp,
+                     estream_t *r_outfp,
+                     estream_t *r_errfp,
+                     pid_t *pid)
+{
+  gpg_error_t err;
+  int infd = -1;
+  int outpipe[2] = {-1, -1};
+  int errpipe[2] = {-1, -1};
+  estream_t outfp = NULL;
+  estream_t errfp = NULL;
+
+  (void)flags; /* Currently not used.  */
+
+  if (r_outfp)
+    *r_outfp = NULL;
+  if (r_errfp)
+    *r_errfp = NULL;
+  *pid = (pid_t)(-1); /* Always required.  */
+
+  if (infp)
+    {
+      es_fflush (infp);
+      es_rewind (infp);
+      infd = es_fileno (infp);
+      if (infd == -1)
+        return gpg_err_make (errsource, GPG_ERR_INV_VALUE);
+    }
+
+  if (r_outfp)
+    {
+      err = create_pipe_and_estream (outpipe, &outfp, errsource);
+      if (err)
+        return err;
+    }
+
+  if (r_errfp)
+    {
+      err = create_pipe_and_estream (errpipe, &errfp, errsource);
+      if (err)
+        {
+          if (outfp)
+            es_fclose (outfp);
+          else if (outpipe[0] != -1)
+            close (outpipe[0]);
+          if (outpipe[1] != -1)
+            close (outpipe[1]);
+          return err;
+        }
+    }
+
+
+  *pid = fork ();
+  if (*pid == (pid_t)(-1))
+    {
+      err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+      log_error (_("error forking process: %s\n"), gpg_strerror (err));
+
+      if (outfp)
+        es_fclose (outfp);
+      else if (outpipe[0] != -1)
+        close (outpipe[0]);
+      if (outpipe[1] != -1)
+        close (outpipe[1]);
+
+      if (errfp)
+        es_fclose (errfp);
+      else if (errpipe[0] != -1)
+        close (errpipe[0]);
+      if (errpipe[1] != -1)
+        close (errpipe[1]);
+      return err;
+    }
+
+  if (!*pid)
+    {
+      /* This is the child. */
+      gcry_control (GCRYCTL_TERM_SECMEM);
+      es_fclose (outfp);
+      es_fclose (errfp);
+      do_exec (pgmname, argv, infd, outpipe[1], errpipe[1], preexec);
+      /*NOTREACHED*/
+    }
+
+  /* This is the parent. */
+  if (outpipe[1] != -1)
+    close (outpipe[1]);
+  if (errpipe[1] != -1)
+    close (errpipe[1]);
+
+  if (r_outfp)
+    *r_outfp = outfp;
+  if (r_errfp)
+    *r_errfp = errfp;
+
+  return 0;
+}
+
+
+
+/* Simplified version of gnupg_spawn_process.  This function forks and
+   then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
+   and ERRFD to stderr (any of them may be -1 to connect them to
+   /dev/null).  The arguments for the process are expected in the NULL
+   terminated array ARGV.  The program name itself should not be
+   included there.  Calling gnupg_wait_process is required.
+
+   Returns 0 on success or an error code. */
+gpg_error_t
+gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
+                        int infd, int outfd, int errfd, pid_t *pid)
+{
+  gpg_error_t err;
+
+  *pid = fork ();
+  if (*pid == (pid_t)(-1))
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("error forking process: %s\n"), strerror (errno));
+      return err;
+    }
+
+  if (!*pid)
+    {
+      gcry_control (GCRYCTL_TERM_SECMEM);
+      /* Run child. */
+      do_exec (pgmname, argv, infd, outfd, errfd, NULL);
+      /*NOTREACHED*/
+    }
+
+  return 0;
+}
+
+
+/* See exechelp.h for the description.  */
+gpg_error_t
+gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
+{
+  gpg_err_code_t ec;
+  int i, status;
+
+  if (r_exitcode)
+    *r_exitcode = -1;
+
+  if (pid == (pid_t)(-1))
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+#ifdef USE_NPTH
+  i = npth_waitpid (pid, &status, hang? 0:WNOHANG);
+#else
+  while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
+        && errno == EINTR);
+#endif
+
+  if (i == (pid_t)(-1))
+    {
+      ec = gpg_err_code_from_errno (errno);
+      log_error (_("waiting for process %d to terminate failed: %s\n"),
+                 (int)pid, strerror (errno));
+    }
+  else if (!i)
+    {
+      ec = GPG_ERR_TIMEOUT; /* Still running.  */
+    }
+  else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
+    {
+      log_error (_("error running '%s': probably not installed\n"), pgmname);
+      ec = GPG_ERR_CONFIGURATION;
+    }
+  else if (WIFEXITED (status) && WEXITSTATUS (status))
+    {
+      if (!r_exitcode)
+        log_error (_("error running '%s': exit status %d\n"), pgmname,
+                   WEXITSTATUS (status));
+      else
+        *r_exitcode = WEXITSTATUS (status);
+      ec = GPG_ERR_GENERAL;
+    }
+  else if (!WIFEXITED (status))
+    {
+      log_error (_("error running '%s': terminated\n"), pgmname);
+      ec = GPG_ERR_GENERAL;
+    }
+  else
+    {
+      if (r_exitcode)
+        *r_exitcode = 0;
+      ec = 0;
+    }
+
+  return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
+}
+
+
+void
+gnupg_release_process (pid_t pid)
+{
+  (void)pid;
+}
+
+
+/* Spawn a new process and immediately detach from it.  The name of
+   the program to exec is PGMNAME and its arguments are in ARGV (the
+   programname is automatically passed as first argument).
+   Environment strings in ENVP are set.  An error is returned if
+   pgmname is not executable; to make this work it is necessary to
+   provide an absolute file name.  All standard file descriptors are
+   connected to /dev/null. */
+gpg_error_t
+gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
+                              const char *envp[] )
+{
+  pid_t pid;
+  int i;
+
+  if (getuid() != geteuid())
+    return gpg_error (GPG_ERR_BUG);
+
+  if (access (pgmname, X_OK))
+    return gpg_error_from_syserror ();
+
+  pid = fork ();
+  if (pid == (pid_t)(-1))
+    {
+      log_error (_("error forking process: %s\n"), strerror (errno));
+      return gpg_error_from_syserror ();
+    }
+  if (!pid)
+    {
+      pid_t pid2;
+
+      gcry_control (GCRYCTL_TERM_SECMEM);
+      if (setsid() == -1 || chdir ("/"))
+        _exit (1);
+
+      pid2 = fork (); /* Double fork to let init take over the new child. */
+      if (pid2 == (pid_t)(-1))
+        _exit (1);
+      if (pid2)
+        _exit (0);  /* Let the parent exit immediately. */
+
+      if (envp)
+        for (i=0; envp[i]; i++)
+          putenv (xstrdup (envp[i]));
+
+      do_exec (pgmname, argv, -1, -1, -1, NULL);
+
+      /*NOTREACHED*/
+    }
+
+  if (waitpid (pid, NULL, 0) == -1)
+    log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
+               strerror (errno));
+
+  return 0;
+}
+
+
+/* Kill a process; that is send an appropriate signal to the process.
+   gnupg_wait_process must be called to actually remove the process
+   from the system.  An invalid PID is ignored.  */
+void
+gnupg_kill_process (pid_t pid)
+{
+  if (pid != (pid_t)(-1))
+    {
+      kill (pid, SIGTERM);
+    }
+}
similarity index 50%
rename from common/exechelp.c
rename to common/exechelp-w32.c
index 6d60b07..05e9e10 100644 (file)
@@ -1,14 +1,25 @@
-/* exechelp.c - fork and exec helpers
- * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* exechelp-w32.c - Fork and exec helpers for W32.
+ * Copyright (C) 2004, 2007, 2008, 2009,
+ *               2010 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 
 #include <config.h>
 
+#if !defined(HAVE_W32_SYSTEM) || defined (HAVE_W32CE_SYSTEM)
+#error This code is only used on W32.
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
-#include <signal.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 #include <unistd.h>
 #include <fcntl.h>
 
-#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
-#undef HAVE_PTH
-#undef USE_GNU_PTH
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+#undef HAVE_NPTH
+#undef USE_NPTH
 #endif
 
-#ifdef USE_GNU_PTH
-#include <pth.h>
-#endif
-#ifndef HAVE_W32_SYSTEM
-#include <sys/wait.h>
+#ifdef HAVE_NPTH
+#include <npth.h>
 #endif
 
-#ifdef HAVE_GETRLIMIT
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif /*HAVE_GETRLIMIT*/
-
 #ifdef HAVE_STAT
 # include <sys/stat.h>
 #endif
 #define DEBUG_W32_SPAWN 1
 
 
-/* We have the usual problem here: Some modules are linked against pth
-   and some are not.  However we want to use pth_fork and pth_waitpid
-   here. Using a weak symbol works but is not portable - we should
-   provide a an explicit dummy pth module instead of using the
-   pragma.  */
-#ifndef _WIN32
-#pragma weak pth_fork
-#pragma weak pth_waitpid
-#endif
-
-#ifdef HAVE_W32_SYSTEM
 /* It seems Vista doesn't grok X_OK and so fails access() tests.
    Previous versions interpreted X_OK as F_OK anyway, so we'll just
    use F_OK directly. */
 #undef X_OK
 #define X_OK F_OK
-#endif /* HAVE_W32_SYSTEM */
-
 
-#ifdef HAVE_W32_SYSTEM
 /* We assume that a HANDLE can be represented by an int which should
    be true for all i386 systems (HANDLE is defined as void *) and
    these are the only systems for which Windows is available.  Further
@@ -90,7 +82,6 @@
 # define handle_to_fd(a)  ((int)(a))
 # define pid_to_handle(a) ((HANDLE)(a))
 # define handle_to_pid(a) ((int)(a))
-#endif
 
 
 /* Return the maximum number of currently allowed open file
@@ -100,34 +91,6 @@ int
 get_max_fds (void)
 {
   int max_fds = -1;
-#ifdef HAVE_GETRLIMIT
-  struct rlimit rl;
-
-# ifdef RLIMIT_NOFILE
-  if (!getrlimit (RLIMIT_NOFILE, &rl))
-    max_fds = rl.rlim_max;
-# endif
-
-# ifdef RLIMIT_OFILE
-  if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
-    max_fds = rl.rlim_max;
-
-# endif
-#endif /*HAVE_GETRLIMIT*/
-
-#ifdef _SC_OPEN_MAX
-  if (max_fds == -1)
-    {
-      long int scres = sysconf (_SC_OPEN_MAX);
-      if (scres >= 0)
-        max_fds = scres;
-    }
-#endif
-
-#ifdef _POSIX_OPEN_MAX
-  if (max_fds == -1)
-    max_fds = _POSIX_OPEN_MAX;
-#endif
 
 #ifdef OPEN_MAX
   if (max_fds == -1)
@@ -137,54 +100,16 @@ get_max_fds (void)
   if (max_fds == -1)
     max_fds = 256;  /* Arbitrary limit.  */
 
-  /* AIX returns INT32_MAX instead of a proper value.  We assume that
-     this is always an error and use an arbitrary limit.  */
-#ifdef INT32_MAX
-  if (max_fds == INT32_MAX)
-    max_fds = 256;
-#endif
-
   return max_fds;
 }
 
 
-/* Close all file descriptors starting with descriptor FIRST.  If
-   EXCEPT is not NULL, it is expected to be a list of file descriptors
-   which shall not be closed.  This list shall be sorted in ascending
-   order with the end marked by -1.  */
+/* Under Windows this is a dummy function.  */
 void
 close_all_fds (int first, int *except)
 {
-  int max_fd = get_max_fds ();
-  int fd, i, except_start;
-
-  if (except)
-    {
-      except_start = 0;
-      for (fd=first; fd < max_fd; fd++)
-        {
-          for (i=except_start; except[i] != -1; i++)
-            {
-              if (except[i] == fd)
-                {
-                  /* If we found the descriptor in the exception list
-                     we can start the next compare run at the next
-                     index because the exception list is ordered.  */
-                except_start = i + 1;
-                break;
-                }
-            }
-          if (except[i] == -1)
-            close (fd);
-        }
-    }
-  else
-    {
-      for (fd=first; fd < max_fd; fd++)
-        close (fd);
-    }
-
-  errno = 0;
+  (void)first;
+  (void)except;
 }
 
 
@@ -238,8 +163,6 @@ get_all_open_fds (void)
 }
 
 
-
-#ifdef HAVE_W32_SYSTEM
 /* Helper function to build_w32_commandline. */
 static char *
 build_w32_commandline_copy (char *buffer, const char *string)
@@ -251,7 +174,7 @@ build_w32_commandline_copy (char *buffer, const char *string)
     p = stpcpy (p, "\"\"");
   else if (strpbrk (string, " \t\n\v\f\""))
     {
-      /* Need top do some kind of quoting.  */
+      /* Need to do some kind of quoting.  */
       p = stpcpy (p, "\"");
       for (s=string; *s; s++)
         {
@@ -308,13 +231,12 @@ build_w32_commandline (const char *pgmname, const char * const *argv,
   *cmdline= buf;
   return 0;
 }
-#endif /*HAVE_W32_SYSTEM*/
 
 
-#ifdef HAVE_W32_SYSTEM
-/* Create  pipe where the write end is inheritable.  */
+/* Create pipe where one end is inheritable: With an INHERIT_IDX of 0
+   the read end is inheritable, with 1 the write end is inheritable.  */
 static int
-create_inheritable_pipe (int filedes[2])
+create_inheritable_pipe (HANDLE filedes[2], int inherit_idx)
 {
   HANDLE r, w, h;
   SECURITY_ATTRIBUTES sec_attr;
@@ -326,7 +248,7 @@ create_inheritable_pipe (int filedes[2])
   if (!CreatePipe (&r, &w, &sec_attr, 0))
     return -1;
 
-  if (!DuplicateHandle (GetCurrentProcess(), w,
+  if (!DuplicateHandle (GetCurrentProcess(), inherit_idx? w : r,
                         GetCurrentProcess(), &h, 0,
                         TRUE, DUPLICATE_SAME_ACCESS ))
     {
@@ -335,166 +257,100 @@ create_inheritable_pipe (int filedes[2])
       CloseHandle (w);
       return -1;
     }
-  CloseHandle (w);
-  w = h;
 
-  filedes[0] = handle_to_fd (r);
-  filedes[1] = handle_to_fd (w);
+  if (inherit_idx)
+    {
+      CloseHandle (w);
+      w = h;
+    }
+  else
+    {
+      CloseHandle (r);
+      r = h;
+    }
+
+  filedes[0] = r;
+  filedes[1] = w;
   return 0;
 }
-#endif /*HAVE_W32_SYSTEM*/
 
 
-#ifdef HAVE_W32_SYSTEM
 static HANDLE
 w32_open_null (int for_write)
 {
   HANDLE hfile;
 
-  hfile = CreateFile ("nul",
-                      for_write? GENERIC_WRITE : GENERIC_READ,
-                      FILE_SHARE_READ | FILE_SHARE_WRITE,
-                      NULL, OPEN_EXISTING, 0, NULL);
+  hfile = CreateFileW (L"nul",
+                       for_write? GENERIC_WRITE : GENERIC_READ,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE,
+                       NULL, OPEN_EXISTING, 0, NULL);
   if (hfile == INVALID_HANDLE_VALUE)
-    log_debug ("can't open `nul': %s\n", w32_strerror (-1));
+    log_debug ("can't open 'nul': %s\n", w32_strerror (-1));
   return hfile;
 }
-#endif /*HAVE_W32_SYSTEM*/
 
 
-#ifndef HAVE_W32_SYSTEM
-/* The exec core used right after the fork. This will never return. */
-static void
-do_exec (const char *pgmname, const char *argv[],
-         int fd_in, int fd_out, int fd_err,
-         void (*preexec)(void) )
-{
-  char **arg_list;
-  int i, j;
-  int fds[3];
-
-  fds[0] = fd_in;
-  fds[1] = fd_out;
-  fds[2] = fd_err;
-
-  /* Create the command line argument array.  */
-  i = 0;
-  if (argv)
-    while (argv[i])
-      i++;
-  arg_list = xcalloc (i+2, sizeof *arg_list);
-  arg_list[0] = strrchr (pgmname, '/');
-  if (arg_list[0])
-    arg_list[0]++;
-  else
-    arg_list[0] = xstrdup (pgmname);
-  if (argv)
-    for (i=0,j=1; argv[i]; i++, j++)
-      arg_list[j] = (char*)argv[i];
-
-  /* Assign /dev/null to unused FDs. */
-  for (i=0; i <= 2; i++)
-    {
-      if (fds[i] == -1 )
-        {
-          fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
-          if (fds[i] == -1)
-            log_fatal ("failed to open `%s': %s\n",
-                       "/dev/null", strerror (errno));
-        }
-    }
-
-  /* Connect the standard files.  */
-  for (i=0; i <= 2; i++)
-    {
-      if (fds[i] != i && dup2 (fds[i], i) == -1)
-        log_fatal ("dup2 std%s failed: %s\n",
-                   i==0?"in":i==1?"out":"err", strerror (errno));
-    }
-
-  /* Close all other files. */
-  close_all_fds (3, NULL);
-
-  if (preexec)
-    preexec ();
-  execv (pgmname, arg_list);
-  /* No way to print anything, as we have closed all streams. */
-  _exit (127);
-}
-#endif /*!HAVE_W32_SYSTEM*/
-
-
-/* Portable function to create a pipe.  Under Windows the write end is
-   inheritable.  */
-gpg_error_t
-gnupg_create_inbound_pipe (int filedes[2])
+static gpg_error_t
+do_create_pipe (int filedes[2], int inherit_idx)
 {
   gpg_error_t err = 0;
-#if HAVE_W32_SYSTEM
-  int fds[2];
+  HANDLE fds[2];
 
   filedes[0] = filedes[1] = -1;
   err = gpg_error (GPG_ERR_GENERAL);
-  if (!create_inheritable_pipe (fds))
+  if (!create_inheritable_pipe (fds, inherit_idx))
     {
-      filedes[0] = _open_osfhandle (fds[0], 0);
+      filedes[0] = _open_osfhandle (handle_to_fd (fds[0]), 0);
       if (filedes[0] == -1)
         {
-          log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
-          CloseHandle (fd_to_handle (fds[1]));
+          log_error ("failed to translate osfhandle %p\n", fds[0]);
+          CloseHandle (fds[1]);
         }
       else
         {
-          filedes[1] = _open_osfhandle (fds[1], 1);
+          filedes[1] = _open_osfhandle (handle_to_fd (fds[1]), 1);
           if (filedes[1] == -1)
             {
-              log_error ("failed to translate osfhandle %p\n", (void*)fds[1]);
+              log_error ("failed to translate osfhandle %p\n", fds[1]);
               close (filedes[0]);
               filedes[0] = -1;
-              CloseHandle (fd_to_handle (fds[1]));
+              CloseHandle (fds[1]);
             }
           else
             err = 0;
         }
     }
-#else
-  if (pipe (filedes) == -1)
-    {
-      err = gpg_error_from_syserror ();
-      filedes[0] = filedes[1] = -1;
-    }
-#endif
   return err;
 }
 
+/* Portable function to create a pipe.  Under Windows the write end is
+   inheritable.  */
+gpg_error_t
+gnupg_create_inbound_pipe (int filedes[2])
+{
+  return do_create_pipe (filedes, 1);
+}
 
-/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
-   stdin, write the output to OUTFILE, return a new stream in
-   STATUSFILE for stderr and the pid of the process in PID. The
-   arguments for the process are expected in the NULL terminated array
-   ARGV.  The program name itself should not be included there.  If
-   PREEXEC is not NULL, that function will be called right before the
-   exec.  Calling gnupg_wait_process is required.
-
-   FLAGS is a bit vector with just one bit defined for now:
 
-   Bit 7: If set the process will be started as a background process.
-          This flag is only useful under W32 systems, so that no new
-          console is created and pops up a console window when
-          starting the server
+/* Portable function to create a pipe.  Under Windows the read end is
+   inheritable.  */
+gpg_error_t
+gnupg_create_outbound_pipe (int filedes[2])
+{
+  return do_create_pipe (filedes, 0);
+}
 
-   Bit 6: On W32 run AllowSetForegroundWindow for the child.  Due to
-          error problems this actually allows SetForegroundWindow for
-          childs of this process.
 
-   Returns 0 on success or an error code. */
+/* Fork and exec the PGMNAME, see exechelp.h for details.  */
 gpg_error_t
 gnupg_spawn_process (const char *pgmname, const char *argv[],
-                     FILE *infile, FILE *outfile,
+                     gpg_err_source_t errsource,
                      void (*preexec)(void), unsigned int flags,
-                     FILE **statusfile, pid_t *pid)
+                     estream_t infp,
+                     estream_t *r_outfp,
+                     estream_t *r_errfp,
+                     pid_t *pid)
 {
-#ifdef HAVE_W32_SYSTEM
   gpg_error_t err;
   SECURITY_ATTRIBUTES sec_attr;
   PROCESS_INFORMATION pi =
@@ -507,19 +363,103 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
   STARTUPINFO si;
   int cr_flags;
   char *cmdline;
-  int fd, fdout, rp[2];
+  HANDLE inhandle = INVALID_HANDLE_VALUE;
+  HANDLE outpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
+  HANDLE errpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
+  estream_t outfp = NULL;
+  estream_t errfp = NULL;
+  HANDLE nullhd[3] = {INVALID_HANDLE_VALUE,
+                      INVALID_HANDLE_VALUE,
+                      INVALID_HANDLE_VALUE};
+  int i;
+  es_syshd_t syshd;
 
-  (void)preexec;
+  if (r_outfp)
+    *r_outfp = NULL;
+  if (r_errfp)
+    *r_errfp = NULL;
+  *pid = (pid_t)(-1); /* Always required.  */
 
-  /* Setup return values.  */
-  *statusfile = NULL;
-  *pid = (pid_t)(-1);
-  fflush (infile);
-  rewind (infile);
-  fd = _get_osfhandle (fileno (infile));
-  fdout = _get_osfhandle (fileno (outfile));
-  if (fd == -1 || fdout == -1)
-    log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
+  if (infp)
+    {
+      es_fflush (infp);
+      es_rewind (infp);
+      es_syshd (infp, &syshd);
+      switch (syshd.type)
+        {
+        case ES_SYSHD_FD:
+          inhandle = (HANDLE)_get_osfhandle (syshd.u.fd);
+          break;
+        case ES_SYSHD_SOCK:
+          inhandle = (HANDLE)_get_osfhandle (syshd.u.sock);
+          break;
+        case ES_SYSHD_HANDLE:
+          inhandle = syshd.u.handle;
+          break;
+        default:
+          inhandle = INVALID_HANDLE_VALUE;
+          break;
+        }
+      if (inhandle == INVALID_HANDLE_VALUE)
+        return gpg_err_make (errsource, GPG_ERR_INV_VALUE);
+      /* FIXME: In case we can't get a system handle (e.g. due to
+         es_fopencookie we should create a piper and a feeder
+         thread.  */
+    }
+
+  if (r_outfp)
+    {
+      if (create_inheritable_pipe (outpipe, 1))
+        {
+          err = gpg_err_make (errsource, GPG_ERR_GENERAL);
+          log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+          return err;
+        }
+
+      syshd.type = ES_SYSHD_HANDLE;
+      syshd.u.handle = outpipe[0];
+      outfp = es_sysopen (&syshd, "r");
+      if (!outfp)
+        {
+          err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+          log_error (_("error creating a stream for a pipe: %s\n"),
+                     gpg_strerror (err));
+          CloseHandle (outpipe[0]);
+          CloseHandle (outpipe[1]);
+          outpipe[0] = outpipe[1] = INVALID_HANDLE_VALUE;
+          return err;
+        }
+    }
+
+  if (r_errfp)
+    {
+      if (create_inheritable_pipe (errpipe, 1))
+        {
+          err = gpg_err_make (errsource, GPG_ERR_GENERAL);
+          log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+          return err;
+        }
+
+      syshd.type = ES_SYSHD_HANDLE;
+      syshd.u.handle = errpipe[0];
+      errfp = es_sysopen (&syshd, "r");
+      if (!errfp)
+        {
+          err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+          log_error (_("error creating a stream for a pipe: %s\n"),
+                     gpg_strerror (err));
+          CloseHandle (errpipe[0]);
+          CloseHandle (errpipe[1]);
+          errpipe[0] = errpipe[1] = INVALID_HANDLE_VALUE;
+          if (outfp)
+            es_fclose (outfp);
+          else if (outpipe[0] != INVALID_HANDLE_VALUE)
+            CloseHandle (outpipe[0]);
+          if (outpipe[1] != INVALID_HANDLE_VALUE)
+            CloseHandle (outpipe[1]);
+          return err;
+        }
+    }
 
   /* Prepare security attributes.  */
   memset (&sec_attr, 0, sizeof sec_attr );
@@ -531,30 +471,30 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
   if (err)
     return err;
 
-  /* Create a pipe.  */
-  if (create_inheritable_pipe (rp))
-    {
-      err = gpg_error (GPG_ERR_GENERAL);
-      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
-      xfree (cmdline);
-      return err;
-    }
+  if (inhandle != INVALID_HANDLE_VALUE)
+    nullhd[0] = w32_open_null (0);
+  if (outpipe[1] != INVALID_HANDLE_VALUE)
+    nullhd[1] = w32_open_null (0);
+  if (errpipe[1] != INVALID_HANDLE_VALUE)
+    nullhd[2] = w32_open_null (0);
 
   /* Start the process.  Note that we can't run the PREEXEC function
-     because this would change our own environment. */
+     because this might change our own environment. */
+  (void)preexec;
+
   memset (&si, 0, sizeof si);
   si.cb = sizeof (si);
   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
   si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
-  si.hStdInput  = fd_to_handle (fd);
-  si.hStdOutput = fd_to_handle (fdout);
-  si.hStdError  = fd_to_handle (rp[1]);
+  si.hStdInput  =   inhandle == INVALID_HANDLE_VALUE? nullhd[0] : inhandle;
+  si.hStdOutput = outpipe[1] == INVALID_HANDLE_VALUE? nullhd[1] : outpipe[1];
+  si.hStdError  = errpipe[1] == INVALID_HANDLE_VALUE? nullhd[2] : errpipe[1];
 
   cr_flags = (CREATE_DEFAULT_ERROR_MODE
               | ((flags & 128)? DETACHED_PROCESS : 0)
               | GetPriorityClass (GetCurrentProcess ())
               | CREATE_SUSPENDED);
-/*   log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */
+/*   log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */
   if (!CreateProcess (pgmname,       /* Program to start.  */
                       cmdline,       /* Command line arguments.  */
                       &sec_attr,     /* Process security attributes.  */
@@ -569,24 +509,43 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
     {
       log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
       xfree (cmdline);
-      CloseHandle (fd_to_handle (rp[0]));
-      CloseHandle (fd_to_handle (rp[1]));
-      return gpg_error (GPG_ERR_GENERAL);
+      if (outfp)
+        es_fclose (outfp);
+      else if (outpipe[0] != INVALID_HANDLE_VALUE)
+        CloseHandle (outpipe[0]);
+      if (outpipe[1] != INVALID_HANDLE_VALUE)
+        CloseHandle (outpipe[1]);
+      if (errfp)
+        es_fclose (errfp);
+      else if (errpipe[0] != INVALID_HANDLE_VALUE)
+        CloseHandle (errpipe[0]);
+      if (errpipe[1] != INVALID_HANDLE_VALUE)
+        CloseHandle (errpipe[1]);
+      return gpg_err_make (errsource, GPG_ERR_GENERAL);
     }
   xfree (cmdline);
   cmdline = NULL;
 
-  /* Close the other end of the pipe.  */
-  CloseHandle (fd_to_handle (rp[1]));
+  /* Close the inherited handles to /dev/null.  */
+  for (i=0; i < DIM (nullhd); i++)
+    if (nullhd[i] != INVALID_HANDLE_VALUE)
+      CloseHandle (nullhd[i]);
 
-/*   log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */
-/*              " dwProcessID=%d dwThreadId=%d\n", */
-/*              pi.hProcess, pi.hThread, */
-/*              (int) pi.dwProcessId, (int) pi.dwThreadId); */
+  /* Close the inherited ends of the pipes.  */
+  if (outpipe[1] != INVALID_HANDLE_VALUE)
+    CloseHandle (outpipe[1]);
+  if (errpipe[1] != INVALID_HANDLE_VALUE)
+    CloseHandle (errpipe[1]);
+
+  /* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */
+  /*            " dwProcessID=%d dwThreadId=%d\n", */
+  /*            pi.hProcess, pi.hThread, */
+  /*            (int) pi.dwProcessId, (int) pi.dwThreadId); */
+  /* log_debug ("                     outfp=%p errfp=%p\n", outfp, errfp); */
 
   /* Fixme: For unknown reasons AllowSetForegroundWindow returns an
-     invalid argument error if we pass the correct processID to
-     it.  As a workaround we use -1 (ASFW_ANY).  */
+     invalid argument error if we pass it the correct processID.  As a
+     workaround we use -1 (ASFW_ANY).  */
   if ( (flags & 64) )
     gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/);
 
@@ -594,85 +553,14 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
   ResumeThread (pi.hThread);
   CloseHandle (pi.hThread);
 
-  {
-    int x;
-
-    x = _open_osfhandle (rp[0], 0);
-    if (x == -1)
-      log_error ("failed to translate osfhandle %p\n", (void*)rp[0] );
-    else
-      *statusfile = fdopen (x, "r");
-  }
-  if (!*statusfile)
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err));
-      CloseHandle (pi.hProcess);
-      return err;
-    }
+  if (r_outfp)
+    *r_outfp = outfp;
+  if (r_errfp)
+    *r_errfp = errfp;
 
   *pid = handle_to_pid (pi.hProcess);
   return 0;
 
-#else /* !HAVE_W32_SYSTEM */
-  gpg_error_t err;
-  int fd, fdout, rp[2];
-
-  (void)flags; /* Currently not used.  */
-
-  *statusfile = NULL;
-  *pid = (pid_t)(-1);
-  fflush (infile);
-  rewind (infile);
-  fd = fileno (infile);
-  fdout = fileno (outfile);
-  if (fd == -1 || fdout == -1)
-    log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
-
-  if (pipe (rp) == -1)
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("error creating a pipe: %s\n"), strerror (errno));
-      return err;
-    }
-
-#ifdef USE_GNU_PTH
-  *pid = pth_fork? pth_fork () : fork ();
-#else
-  *pid = fork ();
-#endif
-  if (*pid == (pid_t)(-1))
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("error forking process: %s\n"), strerror (errno));
-      close (rp[0]);
-      close (rp[1]);
-      return err;
-    }
-
-  if (!*pid)
-    {
-      gcry_control (GCRYCTL_TERM_SECMEM);
-      /* Run child. */
-      do_exec (pgmname, argv, fd, fdout, rp[1], preexec);
-      /*NOTREACHED*/
-    }
-
-  /* Parent. */
-  close (rp[1]);
-
-  *statusfile = fdopen (rp[0], "r");
-  if (!*statusfile)
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno));
-      kill (*pid, SIGTERM);
-      *pid = (pid_t)(-1);
-      return err;
-    }
-
-  return 0;
-#endif /* !HAVE_W32_SYSTEM */
 }
 
 
@@ -689,7 +577,6 @@ gpg_error_t
 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
                         int infd, int outfd, int errfd, pid_t *pid)
 {
-#ifdef HAVE_W32_SYSTEM
   gpg_error_t err;
   SECURITY_ATTRIBUTES sec_attr;
   PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
@@ -722,7 +609,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
   si.hStdOutput = outfd == -1? stdhd[1] : (void*)_get_osfhandle (outfd);
   si.hStdError  = errfd == -1? stdhd[2] : (void*)_get_osfhandle (errfd);
 
-/*   log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */
+/*   log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */
   if (!CreateProcess (pgmname,       /* Program to start.  */
                       cmdline,       /* Command line arguments.  */
                       &sec_attr,     /* Process security attributes.  */
@@ -761,52 +648,20 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
   *pid = handle_to_pid (pi.hProcess);
   return 0;
 
-#else /* !HAVE_W32_SYSTEM */
-  gpg_error_t err;
-
-#ifdef USE_GNU_PTH
-  *pid = pth_fork? pth_fork () : fork ();
-#else
-  *pid = fork ();
-#endif
-  if (*pid == (pid_t)(-1))
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("error forking process: %s\n"), strerror (errno));
-      return err;
-    }
-
-  if (!*pid)
-    {
-      gcry_control (GCRYCTL_TERM_SECMEM);
-      /* Run child. */
-      do_exec (pgmname, argv, infd, outfd, errfd, NULL);
-      /*NOTREACHED*/
-    }
-
-  return 0;
-#endif /* !HAVE_W32_SYSTEM */
 }
 
 
-/* Wait for the process identified by PID to terminate. PGMNAME should
-   be the same as supplied to the spawn function and is only used for
-   diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL
-   for any failures of the spawned program or other error codes.  If
-   EXITCODE is not NULL the exit code of the process is stored at this
-   address or -1 if it could not be retrieved. */
+/* See exechelp.h for a description.  */
 gpg_error_t
-gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode)
+gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
 {
   gpg_err_code_t ec;
-
-#ifdef HAVE_W32_SYSTEM
   HANDLE proc = fd_to_handle (pid);
   int code;
   DWORD exc;
 
-  if (exitcode)
-    *exitcode = -1;
+  if (r_exitcode)
+    *r_exitcode = -1;
 
   if (pid == (pid_t)(-1))
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -814,99 +669,66 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode)
   /* FIXME: We should do a pth_waitpid here.  However this has not yet
      been implemented.  A special W32 pth system call would even be
      better.  */
-  code = WaitForSingleObject (proc, INFINITE);
+  code = WaitForSingleObject (proc, hang? INFINITE : 0);
   switch (code)
     {
-      case WAIT_FAILED:
-        log_error (_("waiting for process %d to terminate failed: %s\n"),
-                   (int)pid, w32_strerror (-1));
-        ec = GPG_ERR_GENERAL;
-        break;
-
-      case WAIT_OBJECT_0:
-        if (!GetExitCodeProcess (proc, &exc))
-          {
-            log_error (_("error getting exit code of process %d: %s\n"),
-                         (int)pid, w32_strerror (-1) );
-            ec = GPG_ERR_GENERAL;
-          }
-        else if (exc)
-          {
-            log_error (_("error running `%s': exit status %d\n"),
-                       pgmname, (int)exc );
-            if (exitcode)
-              *exitcode = (int)exc;
-            ec = GPG_ERR_GENERAL;
-          }
-        else
-          {
-            if (exitcode)
-              *exitcode = 0;
-            ec = 0;
-          }
-        CloseHandle (proc);
-        break;
-
-      default:
-        log_error ("WaitForSingleObject returned unexpected "
-                   "code %d for pid %d\n", code, (int)pid );
-        ec = GPG_ERR_GENERAL;
-        break;
-    }
+    case WAIT_TIMEOUT:
+      ec = GPG_ERR_TIMEOUT;
+      break;
 
-#else /* !HAVE_W32_SYSTEM */
-  int i, status;
-
-  if (exitcode)
-    *exitcode = -1;
-
-  if (pid == (pid_t)(-1))
-    return gpg_error (GPG_ERR_INV_VALUE);
-
-#ifdef USE_GNU_PTH
-  i = pth_waitpid ? pth_waitpid (pid, &status, 0) : waitpid (pid, &status, 0);
-#else
-  while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
-    ;
-#endif
-  if (i == (pid_t)(-1))
-    {
+    case WAIT_FAILED:
       log_error (_("waiting for process %d to terminate failed: %s\n"),
-                 (int)pid, strerror (errno));
-      ec = gpg_err_code_from_errno (errno);
-    }
-  else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
-    {
-      log_error (_("error running `%s': probably not installed\n"), pgmname);
-      ec = GPG_ERR_CONFIGURATION;
-    }
-  else if (WIFEXITED (status) && WEXITSTATUS (status))
-    {
+                 (int)pid, w32_strerror (-1));
+      ec = GPG_ERR_GENERAL;
+      break;
 
-      if (!exitcode)
-        log_error (_("error running `%s': exit status %d\n"), pgmname,
-                   WEXITSTATUS (status));
+    case WAIT_OBJECT_0:
+      if (!GetExitCodeProcess (proc, &exc))
+        {
+          log_error (_("error getting exit code of process %d: %s\n"),
+                     (int)pid, w32_strerror (-1) );
+          ec = GPG_ERR_GENERAL;
+        }
+      else if (exc)
+        {
+          log_error (_("error running '%s': exit status %d\n"),
+                     pgmname, (int)exc );
+          if (r_exitcode)
+            *r_exitcode = (int)exc;
+          ec = GPG_ERR_GENERAL;
+        }
       else
-        *exitcode = WEXITSTATUS (status);
-      ec = GPG_ERR_GENERAL;
-    }
-  else if (!WIFEXITED (status))
-    {
-      log_error (_("error running `%s': terminated\n"), pgmname);
+        {
+          if (r_exitcode)
+            *r_exitcode = 0;
+          ec = 0;
+        }
+      break;
+
+    default:
+      log_error ("WaitForSingleObject returned unexpected "
+                 "code %d for pid %d\n", code, (int)pid );
       ec = GPG_ERR_GENERAL;
+      break;
     }
-  else
-    {
-      if (exitcode)
-        *exitcode = 0;
-      ec = 0;
-    }
-#endif /* !HAVE_W32_SYSTEM */
 
   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
 }
 
 
+
+void
+gnupg_release_process (pid_t pid)
+{
+  if (pid != (pid_t)INVALID_HANDLE_VALUE)
+    {
+      HANDLE process = (HANDLE)pid;
+
+      CloseHandle (process);
+    }
+}
+
+
 /* Spawn a new process and immediatley detach from it.  The name of
    the program to exec is PGMNAME and its arguments are in ARGV (the
    programname is automatically passed as first argument).
@@ -918,7 +740,6 @@ gpg_error_t
 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
                               const char *envp[] )
 {
-#ifdef HAVE_W32_SYSTEM
   gpg_error_t err;
   SECURITY_ATTRIBUTES sec_attr;
   PROCESS_INFORMATION pi =
@@ -933,10 +754,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
   char *cmdline;
 
 
-  /* FIXME: We don't make use of ENVP yet.  It is currently only used
-     to pass the GPG_AGENT_INFO variable to gpg-agent.  As the default
-     on windows is to use a standard socket, this does not really
-     matter.  */
+  /* We don't use ENVP.  */
   (void)envp;
 
   if (access (pgmname, X_OK))
@@ -962,7 +780,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
               | GetPriorityClass (GetCurrentProcess ())
               | CREATE_NEW_PROCESS_GROUP
               | DETACHED_PROCESS);
-/*   log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", */
+/*   log_debug ("CreateProcess(detached), path='%s' cmdline='%s'\n", */
 /*              pgmname, cmdline); */
   if (!CreateProcess (pgmname,       /* Program to start.  */
                       cmdline,       /* Command line arguments.  */
@@ -991,53 +809,20 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
   CloseHandle (pi.hThread);
 
   return 0;
+}
 
-#else
-  pid_t pid;
-  int i;
-
-  if (getuid() != geteuid())
-    return gpg_error (GPG_ERR_BUG);
-
-  if (access (pgmname, X_OK))
-    return gpg_error_from_syserror ();
 
-#ifdef USE_GNU_PTH
-  pid = pth_fork? pth_fork () : fork ();
-#else
-  pid = fork ();
-#endif
-  if (pid == (pid_t)(-1))
-    {
-      log_error (_("error forking process: %s\n"), strerror (errno));
-      return gpg_error_from_syserror ();
-    }
-  if (!pid)
+/* Kill a process; that is send an appropriate signal to the process.
+   gnupg_wait_process must be called to actually remove the process
+   from the system.  An invalid PID is ignored.  */
+void
+gnupg_kill_process (pid_t pid)
+{
+  if (pid != (pid_t) INVALID_HANDLE_VALUE)
     {
-      pid_t pid2;
+      HANDLE process = (HANDLE) pid;
 
-      gcry_control (GCRYCTL_TERM_SECMEM);
-      if (setsid() == -1 || chdir ("/"))
-        _exit (1);
-      pid2 = fork (); /* Double fork to let init takes over the new child. */
-      if (pid2 == (pid_t)(-1))
-        _exit (1);
-      if (pid2)
-        _exit (0);  /* Let the parent exit immediately. */
-
-      if (envp)
-        for (i=0; envp[i]; i++)
-          putenv (xstrdup (envp[i]));
-
-      do_exec (pgmname, argv, -1, -1, -1, NULL);
-
-      /*NOTREACHED*/
+      /* Arbitrary error code.  */
+      TerminateProcess (process, 1);
     }
-
-  if (waitpid (pid, NULL, 0) == -1)
-    log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
-               strerror (errno));
-
-  return 0;
-#endif /* !HAVE_W32_SYSTEM*/
 }
diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c
new file mode 100644 (file)
index 0000000..cca55c8
--- /dev/null
@@ -0,0 +1,861 @@
+/* exechelp-w32.c - Fork and exec helpers for W32CE.
+ * Copyright (C) 2004, 2007, 2008, 2009,
+ *               2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if !defined(HAVE_W32_SYSTEM) && !defined (HAVE_W32CE_SYSTEM)
+#error This code is only used on W32CE.
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+#undef HAVE_NPTH
+#undef USE_NPTH
+#endif
+
+#ifdef HAVE_NPTH
+#include <npth.h>
+#endif
+
+#ifdef HAVE_STAT
+# include <sys/stat.h>
+#endif
+
+#include <assuan.h>
+
+#include "util.h"
+#include "i18n.h"
+#include "sysutils.h"
+#include "exechelp.h"
+
+
+/* It seems Vista doesn't grok X_OK and so fails access() tests.
+   Previous versions interpreted X_OK as F_OK anyway, so we'll just
+   use F_OK directly. */
+#undef X_OK
+#define X_OK F_OK
+
+
+/* We assume that a HANDLE can be represented by an int which should
+   be true for all i386 systems (HANDLE is defined as void *) and
+   these are the only systems for which Windows is available.  Further
+   we assume that -1 denotes an invalid handle.  */
+#define fd_to_handle(a)  ((HANDLE)(a))
+#define handle_to_fd(a)  ((int)(a))
+#define pid_to_handle(a) ((HANDLE)(a))
+#define handle_to_pid(a) ((int)(a))
+
+\f
+#ifdef USE_NPTH
+/* The data passed to the feeder_thread.  */
+struct feeder_thread_parms
+{
+  estream_t stream;
+  volatile int stream_valid;
+  HANDLE hd;
+  int direction;
+};
+
+
+/* The thread started by start_feede3.  */
+static void *
+feeder_thread (void *arg)
+{
+  struct feeder_thread_parms *parm = arg;
+  char buffer[4096];
+  int rc;
+
+  if (parm->direction)
+    {
+      size_t nread = 0;
+      DWORD nwritten;
+
+      log_debug ("feeder_thread estream->pipe: stream=%p pipe=%p\n",
+                 parm->stream, parm->hd);
+      while (parm->stream_valid
+             && !es_read (parm->stream, buffer, sizeof buffer, &nread))
+        {
+          do
+            {
+              pth_enter ();
+              rc = WriteFile (parm->hd, buffer, nread, &nwritten, NULL);
+              pth_leave ();
+              if (!rc)
+                {
+                  log_debug ("feeder(%p): WriteFile error: rc=%d\n",
+                             parm->hd, (int)GetLastError ());
+                  goto leave;
+                }
+              nread -= nwritten;
+            }
+          while (nread);
+        }
+      if (!parm->stream_valid)
+        log_debug ("feeder(%p): closed by other thread\n", parm->hd);
+      else if (nread)
+        log_debug ("feeder(%p): es_read error: %s\n",
+                   parm->hd, strerror (errno));
+    }
+  else
+    {
+      DWORD nread = 0;
+      size_t nwritten;
+
+      log_debug ("feeder_thread pipe->estream: stream=%p pipe=%p\n",
+                 parm->stream, parm->hd);
+      while ( (pth_enter (),
+               (rc = ReadFile (parm->hd, buffer, sizeof buffer, &nread, NULL)),
+               pth_leave (),
+               rc) && nread)
+        {
+          log_debug ("feeder_thread pipe->estream: read %d bytes\n",
+                     (int)nread);
+          do
+            {
+              if (parm->stream_valid
+                  && es_write (parm->stream, buffer, nread, &nwritten))
+                {
+                  log_debug ("feeder(%p): es_write error: %s\n",
+                             parm->hd, strerror (errno));
+                  goto leave;
+                }
+              log_debug ("feeder_thread pipe->estream: es_wrote %d bytes\n",
+                         (int)nwritten);
+              nread -= nwritten;
+            }
+          while (nread && parm->stream_valid);
+        }
+      if (!parm->stream_valid)
+        log_debug ("feeder(%p): closed by other thread\n", parm->hd);
+      else if (nread)
+        log_debug ("feeder(%p): ReadFile error: rc=%d\n",
+                   parm->hd, (int)GetLastError ());
+      else
+        log_debug ("feeder(%p): eof\n", parm->hd);
+    }
+
+leave:
+  log_debug ("feeder(%p): waiting for es_fclose\n", parm->hd);
+  while (parm->stream_valid)
+    pth_yield (NULL);
+  log_debug ("feeder(%p): about to close the pipe handle\n", parm->hd);
+  CloseHandle (parm->hd);
+  log_debug ("feeder(%p): pipe handle closed\n", parm->hd);
+  xfree (parm);
+  return NULL;
+}
+#endif /*USE_NPTH*/
+
+#ifdef USE_NPTH
+static void
+feeder_onclose_notification (estream_t stream, void *opaque)
+{
+  struct feeder_thread_parms *parm = opaque;
+  (void)stream;
+  log_debug ("feeder(%p): received onclose note\n", parm->hd);
+  parm->stream_valid = 0;
+}
+#endif /*USE_NPTH*/
+
+/* Fire up a thread to copy data between STREAM and a pipe's
+   descriptor FD.  With DIRECTION set to true the copy takes place
+   from the stream to the pipe, otherwise from the pipe to the
+   stream.  */
+static gpg_error_t
+start_feeder (estream_t stream, HANDLE hd, int direction)
+{
+#ifdef USE_NPTH
+  gpg_error_t err;
+  struct feeder_thread_parms *parm;
+  pth_attr_t tattr;
+
+  parm = xtrymalloc (sizeof *parm);
+  if (!parm)
+    return gpg_error_from_syserror ();
+  parm->stream = stream;
+  parm->stream_valid = 1;
+  parm->hd = hd;
+  parm->direction = direction;
+
+  if (es_onclose (stream, 1, feeder_onclose_notification, parm))
+    {
+      err = gpg_error_from_syserror ();
+      xfree (parm);
+      return err;
+    }
+
+  tattr = pth_attr_new ();
+  pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
+  pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024);
+  pth_attr_set (tattr, PTH_ATTR_NAME, "exec-feeder");
+
+  log_debug ("spawning new feeder(%p, %p, %d)\n", stream, hd, direction);
+  if(!pth_spawn (tattr, feeder_thread, parm))
+    {
+      err = gpg_error_from_syserror ();
+      es_onclose (stream, 0, feeder_onclose_notification, parm);
+      xfree (parm);
+    }
+  else
+    err = 0;
+  pth_attr_destroy (tattr);
+
+  return err;
+#else
+  (void)stream;
+  (void)hd;
+  (void)direction;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);  /* No Pth.  */
+#endif
+}
+
+
+\f
+/* Return the maximum number of currently allowed open file
+   descriptors.  Only useful on POSIX systems but returns a value on
+   other systems too.  */
+int
+get_max_fds (void)
+{
+  int max_fds = -1;
+
+#ifdef OPEN_MAX
+  if (max_fds == -1)
+    max_fds = OPEN_MAX;
+#endif
+
+  if (max_fds == -1)
+    max_fds = 256;  /* Arbitrary limit.  */
+
+  return max_fds;
+}
+
+
+/* Under Windows this is a dummy function.  */
+void
+close_all_fds (int first, int *except)
+{
+  (void)first;
+  (void)except;
+}
+
+
+/* Returns an array with all currently open file descriptors.  The end
+   of the array is marked by -1.  The caller needs to release this
+   array using the *standard free* and not with xfree.  This allow the
+   use of this function right at startup even before libgcrypt has
+   been initialized.  Returns NULL on error and sets ERRNO
+   accordingly.  */
+int *
+get_all_open_fds (void)
+{
+  int *array;
+  size_t narray;
+  int fd, max_fd, idx;
+#ifndef HAVE_STAT
+  array = calloc (1, sizeof *array);
+  if (array)
+    array[0] = -1;
+#else /*HAVE_STAT*/
+  struct stat statbuf;
+
+  max_fd = get_max_fds ();
+  narray = 32;  /* If you change this change also t-exechelp.c.  */
+  array = calloc (narray, sizeof *array);
+  if (!array)
+    return NULL;
+
+  /* Note:  The list we return is ordered.  */
+  for (idx=0, fd=0; fd < max_fd; fd++)
+    if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
+      {
+        if (idx+1 >= narray)
+          {
+            int *tmp;
+
+            narray += (narray < 256)? 32:256;
+            tmp = realloc (array, narray * sizeof *array);
+            if (!tmp)
+              {
+                free (array);
+                return NULL;
+              }
+            array = tmp;
+          }
+        array[idx++] = fd;
+      }
+  array[idx] = -1;
+#endif /*HAVE_STAT*/
+  return array;
+}
+
+
+
+static char *
+copy_quoted (char *p, const char *string)
+{
+  const char *s;
+
+  if (!*string) /* Empty string. */
+    p = stpcpy (p, "\"\"");
+  else if (strpbrk (string, " \t\n\v\f\"")) /* Need quotes.  */
+    {
+      p = stpcpy (p, "\"");
+      for (s = string; *s; s++)
+        {
+          *p++ = *s;
+          if (*s == '\"')
+            *p++ = *s;
+        }
+      *p++ = '\"';
+      *p = 0;
+    }
+  else /* Copy verbatim.  */
+    p = stpcpy (p, string);
+
+  return p;
+}
+
+
+/* Build a command line for use with W32's CreateProcess.  On success
+   CMDLINE gets the address of a newly allocated string.  */
+static int
+build_w32_commandline (const char * const *argv,
+                      int rvid0, int rvid1, int rvid2,
+                       char **cmdline)
+{
+  int i, n;
+  const char *s;
+  char *buf, *p;
+  char fdbuf[3*30];
+
+  p = fdbuf;
+  *p = 0;
+
+  if (rvid0)
+    snprintf (p, 25, "-&S0=%d ", rvid0);
+  else
+    strcpy (p, "-&S0=null ");
+  p += strlen (p);
+
+  if (rvid1)
+    snprintf (p, 25, "-&S1=%d ", rvid1);
+  else
+    strcpy (p, "-&S1=null ");
+  p += strlen (p);
+
+  if (rvid2)
+    snprintf (p, 25, "-&S2=%d ", rvid2);
+  else
+    strcpy (p, "-&S2=null ");
+  p += strlen (p);
+
+  *cmdline = NULL;
+  n = strlen (fdbuf);
+  for (i=0; (s = argv[i]); i++)
+    {
+      n += strlen (s) + 1 + 2;  /* (1 space, 2 quoting) */
+      for (; *s; s++)
+        if (*s == '\"')
+          n++;  /* Need to double inner quotes.  */
+    }
+  n++;
+
+  buf = p = xtrymalloc (n);
+  if (! buf)
+    return -1;
+
+  p = stpcpy (p, fdbuf);
+  for (i = 0; argv[i]; i++)
+    {
+      *p++ = ' ';
+      p = copy_quoted (p, argv[i]);
+    }
+
+  *cmdline = buf;
+  return 0;
+}
+
+
+/* Create pipe where one end is inheritable: With an INHERIT_IDX of 0
+   the read end is inheritable, with 1 the write end is inheritable.
+   Note that the inheritable ends are rendezvous ids and no file
+   descriptors or handles. */
+static gpg_error_t
+create_inheritable_pipe (int filedes[2], int inherit_idx)
+{
+  HANDLE hd;
+  int rvid;
+
+  filedes[0] = filedes[1] = -1;
+  hd = _assuan_w32ce_prepare_pipe (&rvid, !inherit_idx);
+  if (hd == INVALID_HANDLE_VALUE)
+    {
+      log_error ("_assuan_w32ce_prepare_pipe failed: %s\n", w32_strerror (-1));
+      gpg_err_set_errno (EIO);
+      return gpg_error_from_syserror ();
+    }
+
+  if (inherit_idx)
+    {
+      filedes[0] = handle_to_fd (hd);
+      filedes[1] = rvid;
+    }
+  else
+    {
+      filedes[0] = rvid;
+      filedes[1] = handle_to_fd (hd);
+    }
+  return 0;
+}
+
+
+/* Portable function to create a pipe.  Under Windows the write end is
+   inheritable (i.e. an rendezvous id).  */
+gpg_error_t
+gnupg_create_inbound_pipe (int filedes[2])
+{
+  return create_inheritable_pipe (filedes, 1);
+}
+
+
+/* Portable function to create a pipe.  Under Windows the read end is
+   inheritable (i.e. an rendezvous id).  */
+gpg_error_t
+gnupg_create_outbound_pipe (int filedes[2])
+{
+  return create_inheritable_pipe (filedes, 0);
+}
+
+
+static int
+create_process (const char *pgmname, const char *cmdline,
+                PROCESS_INFORMATION *pi)
+{
+  int res;
+  wchar_t *wpgmname, *wcmdline;
+
+  wpgmname = utf8_to_wchar (pgmname);
+  if (!wpgmname)
+    return 0;
+  wcmdline = utf8_to_wchar (cmdline);
+  if (!wcmdline)
+    {
+      xfree (wpgmname);
+      return 0;
+    }
+  res = CreateProcess (wpgmname,      /* Program to start.  */
+                       wcmdline,      /* Command line arguments.  */
+                       NULL,          /* Process security attributes.  */
+                       NULL,          /* Thread security attributes.  */
+                       FALSE,          /* Inherit handles.  */
+                       CREATE_SUSPENDED, /* Creation flags.  */
+                       NULL,          /* Environment.  */
+                       NULL,          /* Use current drive/directory.  */
+                       NULL,          /* Startup information. */
+                       pi);           /* Returns process information.  */
+  xfree (wcmdline);
+  xfree (wpgmname);
+  return res;
+}
+
+
+/* Fork and exec the PGMNAME, see exechelp.h for details.  */
+gpg_error_t
+gnupg_spawn_process (const char *pgmname, const char *argv[],
+                     gpg_err_source_t errsource,
+                     void (*preexec)(void), unsigned int flags,
+                     estream_t infp,
+                     estream_t *r_outfp,
+                     estream_t *r_errfp,
+                     pid_t *pid)
+{
+  gpg_error_t err;
+  PROCESS_INFORMATION pi = {NULL };
+  char *cmdline;
+  es_syshd_t syshd;
+  struct {
+    HANDLE hd;
+    int rvid;
+  } inpipe = {INVALID_HANDLE_VALUE, 0};
+  struct {
+    HANDLE hd;
+    int rvid;
+  } outpipe = {INVALID_HANDLE_VALUE, 0};
+  struct {
+    HANDLE hd;
+    int rvid;
+  } errpipe = {INVALID_HANDLE_VALUE, 0};
+  estream_t outfp = NULL;
+  estream_t errfp = NULL;
+
+  (void)preexec;
+  (void)flags;
+
+  /* Setup return values.  */
+  if (r_outfp)
+    *r_outfp = NULL;
+  if (r_errfp)
+    *r_errfp = NULL;
+  *pid = (pid_t)(-1); /* Always required.  */
+
+  log_debug ("%s: enter\n", __func__);
+  if (infp)
+    {
+      es_fflush (infp);
+      es_rewind (infp);
+
+      /* Create a pipe to copy our infile to the stdin of the child
+         process.  On success inpipe.hd is owned by the feeder.  */
+      inpipe.hd = _assuan_w32ce_prepare_pipe (&inpipe.rvid, 1);
+      if (inpipe.hd == INVALID_HANDLE_VALUE)
+        {
+          log_error ("_assuan_w32ce_prepare_pipe failed: %s\n",
+                     w32_strerror (-1));
+          gpg_err_set_errno (EIO);
+          return gpg_error_from_syserror ();
+        }
+      log_debug ("%s: inpipe %p created; hd=%p rvid=%d\n", __func__,
+                 infp, inpipe.hd, inpipe.rvid);
+      err = start_feeder (infp, inpipe.hd, 1);
+      if (err)
+        {
+          log_error ("error spawning feeder: %s\n", gpg_strerror (err));
+          CloseHandle (inpipe.hd);
+          return err;
+        }
+      inpipe.hd = INVALID_HANDLE_VALUE; /* Now owned by the feeder.  */
+      log_debug ("%s: inpipe %p created; feeder started\n", __func__,
+                 infp);
+    }
+
+  if (r_outfp)
+    {
+      /* Create a pipe to make the stdout of the child process
+         available as a stream.  */
+      outpipe.hd = _assuan_w32ce_prepare_pipe (&outpipe.rvid, 0);
+      if (outpipe.hd == INVALID_HANDLE_VALUE)
+        {
+          log_error ("_assuan_w32ce_prepare_pipe failed: %s\n",
+                     w32_strerror (-1));
+          gpg_err_set_errno (EIO);
+          /* Fixme release other stuff/kill feeder.  */
+          return gpg_error_from_syserror ();
+        }
+      syshd.type = ES_SYSHD_HANDLE;
+      syshd.u.handle = outpipe.hd;
+      err = 0;
+      outfp = es_sysopen (&syshd, "r");
+      if (!outfp)
+        {
+          err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+          log_error ("error opening pipe stream: %s\n", gpg_strerror (err));
+          CloseHandle (outpipe.hd);
+          return err;
+        }
+      log_debug ("%s: outpipe %p created; hd=%p rvid=%d\n", __func__,
+                 outfp, outpipe.hd, outpipe.rvid);
+      outpipe.hd = INVALID_HANDLE_VALUE; /* Now owned by the OUTFP.  */
+    }
+
+  if (r_errfp)
+    {
+      /* Create a pipe to make the stderr of the child process
+         available as a stream.  */
+      errpipe.hd = _assuan_w32ce_prepare_pipe (&errpipe.rvid, 0);
+      if (errpipe.hd == INVALID_HANDLE_VALUE)
+        {
+          log_error ("_assuan_w32ce_prepare_pipe failed: %s\n",
+                     w32_strerror (-1));
+          gpg_err_set_errno (EIO);
+          /* Fixme release other stuff/kill feeder.  */
+          return gpg_error_from_syserror ();
+        }
+      syshd.type = ES_SYSHD_HANDLE;
+      syshd.u.handle = errpipe.hd;
+      err = 0;
+      errfp = es_sysopen (&syshd, "r");
+      if (!errfp)
+        {
+          err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+          log_error ("error opening pipe stream: %s\n", gpg_strerror (err));
+          CloseHandle (errpipe.hd);
+          return err;
+        }
+      log_debug ("%s: errpipe %p created; hd=%p rvid=%d\n", __func__,
+                 errfp, errpipe.hd, errpipe.rvid);
+      errpipe.hd = INVALID_HANDLE_VALUE; /* Now owned by the ERRFP.  */
+    }
+
+
+
+  /* Build the command line.  */
+  err = build_w32_commandline (argv, inpipe.rvid, outpipe.rvid, errpipe.rvid,
+                               &cmdline);
+  if (err)
+    {
+      /* Fixme release other stuff/kill feeder.  */
+      CloseHandle (errpipe.hd);
+      return err;
+    }
+
+  log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline);
+  if (!create_process (pgmname, cmdline, &pi))
+    {
+      log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
+      xfree (cmdline);
+      /* Fixme release other stuff/kill feeder.  */
+      CloseHandle (errpipe.hd);
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+  xfree (cmdline);
+  cmdline = NULL;
+
+  /* Note: The other end of the pipe is a rendezvous id and thus there
+     is no need for a close.  */
+
+  log_debug ("CreateProcess ready: hProcess=%p hThread=%p"
+             " dwProcessID=%d dwThreadId=%d\n",
+             pi.hProcess, pi.hThread,
+             (int) pi.dwProcessId, (int) pi.dwThreadId);
+
+
+  /* Process has been created suspended; resume it now. */
+  ResumeThread (pi.hThread);
+  CloseHandle (pi.hThread);
+
+  if (r_outfp)
+    *r_outfp = outfp;
+  if (r_errfp)
+    *r_errfp = errfp;
+  *pid = handle_to_pid (pi.hProcess);
+  return 0;
+}
+
+
+
+/* Simplified version of gnupg_spawn_process.  This function forks and
+   then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
+   and ERRFD to stderr (any of them may be -1 to connect them to
+   /dev/null).  The arguments for the process are expected in the NULL
+   terminated array ARGV.  The program name itself should not be
+   included there.  Calling gnupg_wait_process is required.
+
+   Returns 0 on success or an error code. */
+gpg_error_t
+gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
+                        int infd, int outfd, int errfd, pid_t *pid)
+{
+  gpg_error_t err;
+  PROCESS_INFORMATION pi = {NULL};
+  char *cmdline;
+
+  /* Setup return values.  */
+  *pid = (pid_t)(-1);
+
+  if (infd != -1 || outfd != -1 || errfd != -1)
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  /* Build the command line.  */
+  err = build_w32_commandline (argv, 0, 0, 0, &cmdline);
+  if (err)
+    return err;
+
+  log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline);
+  if (!create_process (pgmname, cmdline, &pi))
+    {
+      log_error ("CreateProcess(fd) failed: %s\n", w32_strerror (-1));
+      xfree (cmdline);
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+  xfree (cmdline);
+  cmdline = NULL;
+
+  log_debug ("CreateProcess(fd) ready: hProcess=%p hThread=%p"
+             " dwProcessID=%d dwThreadId=%d\n",
+             pi.hProcess, pi.hThread,
+             (int) pi.dwProcessId, (int) pi.dwThreadId);
+
+  /* Process has been created suspended; resume it now. */
+  ResumeThread (pi.hThread);
+  CloseHandle (pi.hThread);
+
+  *pid = handle_to_pid (pi.hProcess);
+  return 0;
+}
+
+
+/* See exechelp.h for a description.  */
+gpg_error_t
+gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *exitcode)
+{
+  gpg_err_code_t ec;
+  HANDLE proc = fd_to_handle (pid);
+  int code;
+  DWORD exc;
+
+  if (exitcode)
+    *exitcode = -1;
+
+  if (pid == (pid_t)(-1))
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  /* FIXME: We should do a pth_waitpid here.  However this has not yet
+     been implemented.  A special W32 pth system call would even be
+     better.  */
+  code = WaitForSingleObject (proc, hang? INFINITE : 0);
+  switch (code)
+    {
+    case WAIT_TIMEOUT:
+      ec = GPG_ERR_TIMEOUT;
+      break;
+
+    case WAIT_FAILED:
+      log_error (_("waiting for process %d to terminate failed: %s\n"),
+                 (int)pid, w32_strerror (-1));
+      ec = GPG_ERR_GENERAL;
+      break;
+
+    case WAIT_OBJECT_0:
+      if (!GetExitCodeProcess (proc, &exc))
+        {
+          log_error (_("error getting exit code of process %d: %s\n"),
+                     (int)pid, w32_strerror (-1) );
+          ec = GPG_ERR_GENERAL;
+          }
+      else if (exc)
+        {
+          log_error (_("error running '%s': exit status %d\n"),
+                       pgmname, (int)exc );
+          if (exitcode)
+            *exitcode = (int)exc;
+          ec = GPG_ERR_GENERAL;
+        }
+      else
+        {
+          if (exitcode)
+            *exitcode = 0;
+          ec = 0;
+        }
+      break;
+
+    default:
+      log_error ("WaitForSingleObject returned unexpected "
+                 "code %d for pid %d\n", code, (int)pid );
+      ec = GPG_ERR_GENERAL;
+      break;
+    }
+
+  return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
+}
+
+
+void
+gnupg_release_process (pid_t pid)
+{
+  if (pid != (pid_t)INVALID_HANDLE_VALUE)
+    {
+      HANDLE process = (HANDLE)pid;
+
+      CloseHandle (process);
+    }
+}
+
+
+/* Spawn a new process and immediatley detach from it.  The name of
+   the program to exec is PGMNAME and its arguments are in ARGV (the
+   programname is automatically passed as first argument).
+   Environment strings in ENVP are set.  An error is returned if
+   pgmname is not executable; to make this work it is necessary to
+   provide an absolute file name.  All standard file descriptors are
+   connected to /dev/null. */
+gpg_error_t
+gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
+                              const char *envp[] )
+{
+  gpg_error_t err;
+  char *cmdline;
+  PROCESS_INFORMATION pi = {NULL };
+
+  (void)envp;
+
+  /* Build the command line.  */
+  err = build_w32_commandline (argv, 0, 0, 0, &cmdline);
+  if (err)
+    return err;
+
+  /* Note: There is no detached flag under CE.  */
+  log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline);
+  if (!create_process (pgmname, cmdline, &pi))
+    {
+      log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1));
+      xfree (cmdline);
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+  xfree (cmdline);
+  cmdline = NULL;
+
+  log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p"
+             " dwProcessID=%d dwThreadId=%d\n",
+             pi.hProcess, pi.hThread,
+             (int) pi.dwProcessId, (int) pi.dwThreadId);
+
+  /* Process has been created suspended; resume it now. */
+  ResumeThread (pi.hThread);
+  CloseHandle (pi.hThread);
+
+  return 0;
+}
+
+
+/* Kill a process; that is send an appropriate signal to the process.
+   gnupg_wait_process must be called to actually remove the process
+   from the system.  An invalid PID is ignored.  */
+void
+gnupg_kill_process (pid_t pid)
+{
+  if (pid != (pid_t) INVALID_HANDLE_VALUE)
+    {
+      HANDLE process = (HANDLE) pid;
+
+      /* Arbitrary error code.  */
+      TerminateProcess (process, 1);
+    }
+}
index 0efee29..a9a9ca3 100644 (file)
@@ -1,14 +1,24 @@
 /* exechelp.h - Definitions for the fork and exec helpers
- *     Copyright (C) 2004, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2009, 2010 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -20,6 +30,7 @@
 #ifndef GNUPG_COMMON_EXECHELP_H
 #define GNUPG_COMMON_EXECHELP_H
 
+
 /* Return the maximum number of currently allowed file descriptors.
    Only useful on POSIX systems.  */
 int get_max_fds (void);
@@ -44,20 +55,50 @@ int *get_all_open_fds (void);
    inheritable.  */
 gpg_error_t gnupg_create_inbound_pipe (int filedes[2]);
 
+/* Portable function to create a pipe.  Under Windows the read end is
+   inheritable.  */
+gpg_error_t gnupg_create_outbound_pipe (int filedes[2]);
+
+
+/* Fork and exec the PGMNAME.  If INFP is NULL connect /dev/null to
+   stdin of the new process; if it is not NULL connect the file
+   descriptor retrieved from INFP to stdin.  If R_OUTFP is NULL
+   connect stdout of the new process to /dev/null; if it is not NULL
+   store the address of a pointer to a new estream there.  If R_ERRFP
+   is NULL connect stderr of the new process to /dev/null; if it is
+   not NULL store the address of a pointer to a new estream there.  On
+   success the pid of the new process is stored at PID.  On error -1
+   is stored at PID and if R_OUTFP or R_ERRFP are not NULL, NULL is
+   stored there.
+
+   The arguments for the process are expected in the NULL terminated
+   array ARGV.  The program name itself should not be included there.
+   If PREEXEC is not NULL, the given function will be called right
+   before the exec.
+
+   Returns 0 on success or an error code.  Calling gnupg_wait_process
+   and gnupg_release_process is required if the function succeeded.
+
+   FLAGS is a bit vector:
 
-/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
-   stdin, write the output to OUTFILE, return a new stream in
-   STATUSFILE for stderr and the pid of the process in PID. The
-   arguments for the process are expected in the NULL terminated array
-   ARGV.  The program name itself should not be included there.  If
-   PREEXEC is not NULL, that function will be called right before the
-   exec.  FLAGS is currently only useful for W32, see the source for
-   details.  Calling gnupg_wait_process is required.  Returns 0 on
-   success or an error code. */
-gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[],
-                                 FILE *infile, FILE *outfile,
-                                 void (*preexec)(void), unsigned int flags,
-                                 FILE **statusfile, pid_t *pid);
+   Bit 7: If set the process will be started as a background process.
+          This flag is only useful under W32 (but not W32CE) systems,
+          so that no new console is created and pops up a console
+          window when starting the server.  Does not work on W32CE.
+
+   Bit 6: On W32 (but not on W32CE) run AllowSetForegroundWindow for
+          the child.  Note that due to unknown problems this actually
+          allows SetForegroundWindow for all childs of this process.
+
+ */
+gpg_error_t
+gnupg_spawn_process (const char *pgmname, const char *argv[],
+                     gpg_err_source_t errsource,
+                     void (*preexec)(void), unsigned int flags,
+                     estream_t infp,
+                     estream_t *r_outfp,
+                     estream_t *r_errfp,
+                     pid_t *pid);
 
 
 /* Simplified version of gnupg_spawn_process.  This function forks and
@@ -65,21 +106,52 @@ gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[],
    and ERRFD to stderr (any of them may be -1 to connect them to
    /dev/null).  The arguments for the process are expected in the NULL
    terminated array ARGV.  The program name itself should not be
-   included there.  Calling gnupg_wait_process is required.  Returns 0
-   on success or an error code. */
-gpg_error_t gnupg_spawn_process_fd (const char *pgmname, 
+   included there.  Calling gnupg_wait_process and
+   gnupg_release_process is required.  Returns 0 on success or an
+   error code. */
+gpg_error_t gnupg_spawn_process_fd (const char *pgmname,
                                     const char *argv[],
                                     int infd, int outfd, int errfd,
                                     pid_t *pid);
 
 
-/* Wait for the process identified by PID to terminate. PGMNAME should
-   be the same as supplied to the spawn fucntion and is only used for
-   diagnostics.  Returns 0 if the process succeded, GPG_ERR_GENERAL
-   for any failures of the spawned program or other error codes.  If
-   EXITCODE is not NULL the exit code of the process is stored at this
-   address or -1 if it could not be retrieved.  */
-gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode);
+/* If HANG is true, waits for the process identified by PID to exit;
+   if HANG is false, checks whether the process has terminated.
+   PGMNAME should be the same as supplied to the spawn function and is
+   only used for diagnostics.  Return values:
+
+   0
+       The process exited successful.  0 is stored at R_EXITCODE.
+
+   GPG_ERR_GENERAL
+       The process exited without success.  The exit code of process
+       is then stored at R_EXITCODE.  An exit code of -1 indicates
+       that the process terminated abnormally (e.g. due to a signal).
+
+   GPG_ERR_TIMEOUT
+       The process is still running (returned only if HANG is false).
+
+   GPG_ERR_INV_VALUE
+       An invalid PID has been specified.
+
+   Other error codes may be returned as well.  Unless otherwise noted,
+   -1 will be stored at R_EXITCODE.  R_EXITCODE may be passed as NULL
+   if the exit code is not required (in that case an error messge will
+   be printed).  Note that under Windows PID is not the process id but
+   the handle of the process.  */
+gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int hang,
+                                int *r_exitcode);
+
+
+/* Kill a process; that is send an appropriate signal to the process.
+   gnupg_wait_process must be called to actually remove the process
+   from the system.  An invalid PID is ignored.  */
+void gnupg_kill_process (pid_t pid);
+
+/* Release the process identified by PID.  This function is actually
+   only required for Windows but it does not harm to always call it.
+   It is a nop if PID is invalid.  */
+void gnupg_release_process (pid_t pid);
 
 
 /* Spawn a new process and immediatley detach from it.  The name of
index ea48e81..fb13819 100644 (file)
@@ -26,7 +26,7 @@ topheader == 0 && /^\/\*/  { topheader = 1 }
 topheader == 1             { print $0 }
 topheader == 1 && /\*\//   { topheader = 2; print "" }
 
-/^[ \t]+STATUS_[A-Za-z_]+/  { 
+/^[ \t]+STATUS_[A-Za-z_]+/  {
   sub (/[,\/\*]+/, "", $1);
   desc = substr($1,8);
   printf "%d\t%s\t%s\n", code, $1, desc;
@@ -37,4 +37,3 @@ topheader == 1 && /\*\//   { topheader = 2; print "" }
 END {
   print "# end of status codes."
 }
-
index 261fe87..11ecec0 100644 (file)
@@ -4,7 +4,7 @@
  * 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
    a default, which is described by the value of the ARGDEF field.  */
 #define GC_OPT_FLAG_NO_ARG_DESC        (1UL << 6)
 
+/* The NO_CHANGE flag for an option indicates that the user should not
+   be allowed to change this option using the standard gpgconf method.
+   Frontends using gpgconf should grey out such options, so that only
+   the current value is displayed.  */
+#define GC_OPT_FLAG_NO_CHANGE   (1UL <<7)
+
 
 #endif /*GNUPG_GC_OPT_FLAGS_H*/
index 0900794..5b11eb1 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -79,7 +89,7 @@ start_agent (void)
      pth.  We will need a context for each thread or serialize the
      access to the agent.  */
   if (agent_ctx)
-    return 0; 
+    return 0;
 
   err = start_new_gpg_agent (&agent_ctx,
                              agentargs.errsource,
@@ -114,7 +124,7 @@ default_inq_cb (void *opaque, const char *line)
       /* We do not return errors to avoid breaking other code.  */
     }
   else
-    log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
+    log_debug ("ignoring gpg-agent inquiry '%s'\n", line);
 
   return 0;
 }
@@ -129,7 +139,7 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
     put_membuf (data, buffer, length);
   return 0;
 }
-  
+
 
 /* Ask for a passphrase via gpg-agent.  On success the caller needs to
    free the string stored at R_PASSPHRASE.  On error NULL will be
@@ -158,8 +168,8 @@ gnupg_get_passphrase (const char *cache_id,
   gpg_error_t err;
   char line[ASSUAN_LINELENGTH];
   const char *arg1 = NULL;
-  char *arg2 = NULL;  
-  char *arg3 = NULL; 
+  char *arg2 = NULL;
+  char *arg3 = NULL;
   char *arg4 = NULL;
   membuf_t data;
 
@@ -170,7 +180,7 @@ gnupg_get_passphrase (const char *cache_id,
     return err;
 
   /* Check that the gpg-agent understands the repeat option.  */
-  if (assuan_transact (agent_ctx, 
+  if (assuan_transact (agent_ctx,
                        "GETINFO cmd_has_option GET_PASSPHRASE repeat",
                        NULL, NULL, NULL, NULL, NULL, NULL))
     return gpg_error (GPG_ERR_NOT_SUPPORTED);
@@ -186,10 +196,10 @@ gnupg_get_passphrase (const char *cache_id,
     if (!(arg4 = percent_plus_escape (desc_msg)))
       goto no_mem;
 
-  snprintf (line, DIM(line)-1, 
-            "GET_PASSPHRASE --data %s--repeat=%d -- %s %s %s %s", 
+  snprintf (line, DIM(line)-1,
+            "GET_PASSPHRASE --data %s--repeat=%d -- %s %s %s %s",
             check_quality? "--check ":"",
-            repeat, 
+            repeat,
             arg1? arg1:"X",
             arg2? arg2:"X",
             arg3? arg3:"X",
@@ -203,10 +213,10 @@ gnupg_get_passphrase (const char *cache_id,
     init_membuf_secure (&data, 64);
   else
     init_membuf (&data, 64);
-  err = assuan_transact (agent_ctx, line, 
+  err = assuan_transact (agent_ctx, line,
                          membuf_data_cb, &data,
                          default_inq_cb, NULL, NULL, NULL);
-  
+
   /* Older Pinentries return the old assuan error code for canceled
      which gets translated bt libassuan to GPG_ERR_ASS_CANCELED and
      not to the code for a user cancel.  Fix this here. */
@@ -224,7 +234,7 @@ gnupg_get_passphrase (const char *cache_id,
         wipememory (p, n);
       xfree (p);
     }
-  else 
+  else
     {
       put_membuf (&data, "", 1);
       *r_passphrase = get_membuf (&data, NULL);
index 603ac81..a69262f 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
index 1b4e435..788743f 100644 (file)
@@ -1,14 +1,24 @@
 /* gettime.c - Wrapper for time functions
- *     Copyright (C) 1998, 2002, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2002, 2007, 2011 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 
 #include "util.h"
 #include "i18n.h"
+#include "gettime.h"
+
+#ifdef HAVE_UNSIGNED_TIME_T
+# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
+#else
+  /* Error or 32 bit time_t and value after 2038-01-19.  */
+# define IS_INVALID_TIME_T(a) ((a) < 0)
+#endif
+
 
 static unsigned long timewarp;
 static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode;
@@ -37,8 +56,8 @@ static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode;
 
 /* Wrapper for the time(3).  We use this here so we can fake the time
    for tests */
-time_t 
-gnupg_get_time () 
+time_t
+gnupg_get_time ()
 {
   time_t current = time (NULL);
   if (timemode == NORMAL)
@@ -57,15 +76,15 @@ void
 gnupg_get_isotime (gnupg_isotime_t timebuf)
 {
   time_t atime = gnupg_get_time ();
-    
-  if (atime < 0)
+
+  if (atime == (time_t)(-1))
     *timebuf = 0;
-  else 
+  else
     {
       struct tm *tp;
 #ifdef HAVE_GMTIME_R
       struct tm tmbuf;
-      
+
       tp = gmtime_r (&atime, &tmbuf);
 #else
       tp = gmtime (&atime);
@@ -119,7 +138,7 @@ gnupg_faked_time_p (void)
 
 /* This function is used by gpg because OpenPGP defines the timestamp
    as an unsigned 32 bit value. */
-u32 
+u32
 make_timestamp (void)
 {
   time_t t = gnupg_get_time ();
@@ -170,29 +189,162 @@ scan_isodatestr( const char *string )
     return stamp;
 }
 
-/* Scan am ISO timestamp and return an Epoch based timestamp.  The only
-   supported format is "yyyymmddThhmmss" delimited by white space, nul, a
-   colon or a comma.  Returns (time_t)(-1) for an invalid string.  */
-time_t
-isotime2epoch (const char *string)
+
+int
+isotime_p (const char *string)
 {
   const char *s;
-  int year, month, day, hour, minu, sec;
-  struct tm tmbuf;
   int i;
 
   if (!*string)
-    return (time_t)(-1);
+    return 0;
   for (s=string, i=0; i < 8; i++, s++)
     if (!digitp (s))
-      return (time_t)(-1);
+      return 0;
   if (*s != 'T')
-      return (time_t)(-1);
+      return 0;
   for (s++, i=9; i < 15; i++, s++)
     if (!digitp (s))
-      return (time_t)(-1);
+      return 0;
   if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ','))
-    return (time_t)(-1);  /* Wrong delimiter.  */
+    return 0;  /* Wrong delimiter.  */
+
+  return 1;
+}
+
+
+/* Scan a string and return true if the string represents the human
+   readable format of an ISO time.  This format is:
+      yyyy-mm-dd[ hh[:mm[:ss]]]
+   Scanning stops at the second space or at a comma.  */
+int
+isotime_human_p (const char *string)
+{
+  const char *s;
+  int i;
+
+  if (!*string)
+    return 0;
+  for (s=string, i=0; i < 4; i++, s++)
+    if (!digitp (s))
+      return 0;
+  if (*s != '-')
+    return 0;
+  s++;
+  if (!digitp (s) || !digitp (s+1) || s[2] != '-')
+    return 0;
+  i = atoi_2 (s);
+  if (i < 1 || i > 12)
+    return 0;
+  s += 3;
+  if (!digitp (s) || !digitp (s+1))
+    return 0;
+  i = atoi_2 (s);
+  if (i < 1 || i > 31)
+    return 0;
+  s += 2;
+  if (!*s || *s == ',')
+    return 1; /* Okay; only date given.  */
+  if (!spacep (s))
+    return 0;
+  s++;
+  if (spacep (s))
+    return 1; /* Okay, second space stops scanning.  */
+  if (!digitp (s) || !digitp (s+1))
+    return 0;
+  i = atoi_2 (s);
+  if (i < 0 || i > 23)
+    return 0;
+  s += 2;
+  if (!*s || *s == ',')
+    return 1; /* Okay; only date and hour given.  */
+  if (*s != ':')
+    return 0;
+  s++;
+  if (!digitp (s) || !digitp (s+1))
+    return 0;
+  i = atoi_2 (s);
+  if (i < 0 || i > 59)
+    return 0;
+  s += 2;
+  if (!*s || *s == ',')
+    return 1; /* Okay; only date, hour and minute given.  */
+  if (*s != ':')
+    return 0;
+  s++;
+  if (!digitp (s) || !digitp (s+1))
+    return 0;
+  i = atoi_2 (s);
+  if (i < 0 || i > 60)
+    return 0;
+  s += 2;
+  if (!*s || *s == ',' || spacep (s))
+    return 1; /* Okay; date, hour and minute and second given.  */
+
+  return 0; /* Unexpected delimiter.  */
+}
+
+/* Convert a standard isotime or a human readable variant into an
+   isotime structure.  The allowed formats are those described by
+   isotime_p and isotime_human_p.  The function returns 0 on failure
+   or the length of the scanned string on success.  */
+size_t
+string2isotime (gnupg_isotime_t atime, const char *string)
+{
+  gnupg_isotime_t dummyatime;
+
+  if (!atime)
+    atime = dummyatime;
+
+  atime[0] = 0;
+  if (isotime_p (string))
+    {
+      memcpy (atime, string, 15);
+      atime[15] = 0;
+      return 15;
+    }
+  if (!isotime_human_p (string))
+    return 0;
+  atime[0] = string[0];
+  atime[1] = string[1];
+  atime[2] = string[2];
+  atime[3] = string[3];
+  atime[4] = string[5];
+  atime[5] = string[6];
+  atime[6] = string[8];
+  atime[7] = string[9];
+  atime[8] = 'T';
+  memset (atime+9, '0', 6);
+  atime[15] = 0;
+  if (!spacep (string+10))
+    return 10;
+  if (spacep (string+11))
+    return 11; /* As per def, second space stops scanning.  */
+  atime[9] = string[11];
+  atime[10] = string[12];
+  if (string[13] != ':')
+    return 13;
+  atime[11] = string[14];
+  atime[12] = string[15];
+  if (string[16] != ':')
+    return 16;
+  atime[13] = string[17];
+  atime[14] = string[18];
+  return 19;
+}
+
+
+/* Scan an ISO timestamp and return an Epoch based timestamp.  The only
+   supported format is "yyyymmddThhmmss" delimited by white space, nul, a
+   colon or a comma.  Returns (time_t)(-1) for an invalid string.  */
+time_t
+isotime2epoch (const char *string)
+{
+  int year, month, day, hour, minu, sec;
+  struct tm tmbuf;
+
+  if (!isotime_p (string))
+    return (time_t)(-1);
 
   year  = atoi_4 (string);
   month = atoi_2 (string + 4);
@@ -222,14 +374,14 @@ isotime2epoch (const char *string)
 void
 epoch2isotime (gnupg_isotime_t timebuf, time_t atime)
 {
-  if (atime < 0)
+  if (atime == (time_t)(-1))
     *timebuf = 0;
-  else 
+  else
     {
       struct tm *tp;
 #ifdef HAVE_GMTIME_R
       struct tm tmbuf;
-      
+
       tp = gmtime_r (&atime, &tmbuf);
 #else
       tp = gmtime (&atime);
@@ -278,25 +430,66 @@ strtimevalue( u32 value )
 }
 
 
+
+/* Return a malloced string with the time elapsed between NOW and
+   SINCE.  May return NULL on error. */
+char *
+elapsed_time_string (time_t since, time_t now)
+{
+  char *result;
+  double diff;
+  unsigned long value;
+  unsigned int days, hours, minutes, seconds;
+
+  if (!now)
+    now = gnupg_get_time ();
+
+  diff = difftime (now, since);
+  if (diff < 0)
+    return xtrystrdup ("time-warp");
+
+  seconds = (unsigned long)diff % 60;
+  value = (unsigned long)(diff / 60);
+  minutes = value % 60;
+  value /= 60;
+  hours = value % 24;
+  value /= 24;
+  days = value % 365;
+
+  if (days)
+    result = xtryasprintf ("%ud%uh%um%us", days, hours, minutes, seconds);
+  else if (hours)
+    result = xtryasprintf ("%uh%um%us", hours, minutes, seconds);
+  else if (minutes)
+    result = xtryasprintf ("%um%us", minutes, seconds);
+  else
+    result = xtryasprintf ("%us", seconds);
+
+  return result;
+}
+
+
 /*
  * Note: this function returns GMT
  */
 const char *
-strtimestamp( u32 stamp )
+strtimestamp (u32 stamp)
 {
-    static char buffer[11+5];
-    struct tm *tp;
-    time_t atime = stamp;
-    
-    if (atime < 0) {
-        strcpy (buffer, "????" "-??" "-??");
+  static char buffer[11+5];
+  struct tm *tp;
+  time_t atime = stamp;
+
+  if (IS_INVALID_TIME_T (atime))
+    {
+      strcpy (buffer, "????" "-??" "-??");
     }
-    else {
-        tp = gmtime( &atime );
-        sprintf(buffer,"%04d-%02d-%02d",
+  else
+    {
+      tp = gmtime( &atime );
+      snprintf (buffer, sizeof buffer, "%04d-%02d-%02d",
                 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     }
-    return buffer;
+  return buffer;
 }
 
 
@@ -309,17 +502,17 @@ isotimestamp (u32 stamp)
   static char buffer[25+5];
   struct tm *tp;
   time_t atime = stamp;
-  
-  if (atime < 0)
+
+  if (IS_INVALID_TIME_T (atime))
     {
       strcpy (buffer, "????" "-??" "-??" " " "??" ":" "??" ":" "??");
     }
   else
     {
       tp = gmtime ( &atime );
-      sprintf (buffer,"%04d-%02d-%02d %02d:%02d:%02d",
-               1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
-               tp->tm_hour, tp->tm_min, tp->tm_sec);
+      snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d",
+                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+                tp->tm_hour, tp->tm_min, tp->tm_sec);
     }
   return buffer;
 }
@@ -329,41 +522,46 @@ isotimestamp (u32 stamp)
  * Note: this function returns local time
  */
 const char *
-asctimestamp( u32 stamp )
+asctimestamp (u32 stamp)
 {
-    static char buffer[50];
+  static char buffer[50];
 #if defined (HAVE_STRFTIME) && defined (HAVE_NL_LANGINFO)
-      static char fmt[50];
+  static char fmt[50];
 #endif
-    struct tm *tp;
-    time_t atime = stamp;
+  struct tm *tp;
+  time_t atime = stamp;
 
-    if (atime < 0) {
-        strcpy (buffer, "????" "-??" "-??");
-        return buffer;
+  if (IS_INVALID_TIME_T (atime))
+    {
+      strcpy (buffer, "????" "-??" "-??");
+      return buffer;
     }
 
-    tp = localtime( &atime );
+  tp = localtime( &atime );
 #ifdef HAVE_STRFTIME
-#if defined(HAVE_NL_LANGINFO)
-      mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt)-3 );
-      if( strstr( fmt, "%Z" ) == NULL )
-       strcat( fmt, " %Z");
-      /* NOTE: gcc -Wformat-noliteral will complain here.  I have
-         found no way to suppress this warning .*/
-      strftime (buffer, DIM(buffer)-1, fmt, tp);
-#else
-      /* FIXME: we should check whether the locale appends a " %Z"
-       * These locales from glibc don't put the " %Z":
-       * fi_FI hr_HR ja_JP lt_LT lv_LV POSIX ru_RU ru_SU sv_FI sv_SE zh_CN
-       */
-      strftime( buffer, DIM(buffer)-1, "%c %Z", tp );
-#endif
-    buffer[DIM(buffer)-1] = 0;
+# if defined(HAVE_NL_LANGINFO)
+  mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt)-3 );
+  if (!strstr( fmt, "%Z" ))
+    strcat( fmt, " %Z");
+  /* NOTE: gcc -Wformat-noliteral will complain here.  I have found no
+     way to suppress this warning.  */
+  strftime (buffer, DIM(buffer)-1, fmt, tp);
+# elif defined(HAVE_W32CE_SYSTEM)
+  /* tzset is not available but %Z nevertheless prints a default
+     nonsense timezone ("WILDABBR").  Thus we don't print the time
+     zone at all.  */
+  strftime (buffer, DIM(buffer)-1, "%c", tp);
+# else
+   /* FIXME: we should check whether the locale appends a " %Z" These
+    * locales from glibc don't put the " %Z": fi_FI hr_HR ja_JP lt_LT
+    * lv_LV POSIX ru_RU ru_SU sv_FI sv_SE zh_CN.  */
+  strftime (buffer, DIM(buffer)-1, "%c %Z", tp);
+# endif
+  buffer[DIM(buffer)-1] = 0;
 #else
-    mem2str( buffer, asctime(tp), DIM(buffer) );
+  mem2str( buffer, asctime(tp), DIM(buffer) );
 #endif
-    return buffer;
+  return buffer;
 }
 
 
@@ -384,7 +582,7 @@ static int
 days_per_month (int y, int m)
 {
   int s;
-    
+
   switch(m)
     {
     case 1: case 3: case 5: case 7: case 8: case 10: case 12:
@@ -444,19 +642,19 @@ jd2date (unsigned long jd, int *year, int *month, int *day)
   m = (delta / 31) + 1;
   while( (delta = jd - date2jd (y, m, d)) > days_per_month (y,m))
     if (++m > 12)
-      { 
+      {
         m = 1;
         y++;
       }
 
   d = delta + 1 ;
   if (d > days_per_month (y, m))
-    { 
+    {
       d = 1;
       m++;
     }
   if (m > 12)
-    { 
+    {
       m = 1;
       y++;
     }
@@ -483,7 +681,7 @@ check_isotime (const gnupg_isotime_t atime)
 
   if (!*atime)
     return gpg_error (GPG_ERR_NO_VALUE);
-  
+
   for (s=atime, i=0; i < 8; i++, s++)
     if (!digitp (s))
       return gpg_error (GPG_ERR_INV_TIME);
@@ -496,17 +694,35 @@ check_isotime (const gnupg_isotime_t atime)
 }
 
 
+/* Dump the ISO time T to the log stream without a LF.  */
 void
 dump_isotime (const gnupg_isotime_t t)
 {
   if (!t || !*t)
-    log_printf (_("[none]"));
+    log_printf ("%s", _("[none]"));
   else
     log_printf ("%.4s-%.2s-%.2s %.2s:%.2s:%s",
                 t, t+4, t+6, t+9, t+11, t+13);
 }
 
 
+/* Copy one ISO date to another, this is inline so that we can do a
+   minimal sanity check.  A null date (empty string) is allowed.  */
+void
+gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s)
+{
+  if (*s)
+    {
+      if ((strlen (s) != 15 || s[8] != 'T'))
+        BUG();
+      memcpy (d, s, 15);
+      d[15] = 0;
+    }
+  else
+    *d = 0;
+}
+
+
 /* Add SECONDS to ATIME.  SECONDS may not be negative and is limited
    to about the equivalent of 62 years which should be more then
    enough for our purposes. */
@@ -532,7 +748,7 @@ add_seconds_to_isotime (gnupg_isotime_t atime, int nseconds)
   sec   = atoi_2 (atime+13);
 
   if (year <= 1582) /* The julian date functions don't support this. */
-    return gpg_error (GPG_ERR_INV_VALUE); 
+    return gpg_error (GPG_ERR_INV_VALUE);
 
   sec    += nseconds;
   minute += sec/60;
@@ -541,14 +757,14 @@ add_seconds_to_isotime (gnupg_isotime_t atime, int nseconds)
   minute %= 60;
   ndays  = hour/24;
   hour   %= 24;
-  
+
   jd = date2jd (year, month, day) + ndays;
   jd2date (jd, &year, &month, &day);
 
   if (year > 9999 || month > 12 || day > 31
       || year < 0 || month < 1 || day < 1)
-    return gpg_error (GPG_ERR_INV_VALUE); 
-    
+    return gpg_error (GPG_ERR_INV_VALUE);
+
   snprintf (atime, 16, "%04d%02d%02dT%02d%02d%02d",
             year, month, day, hour, minute, sec);
   return 0;
@@ -577,15 +793,15 @@ add_days_to_isotime (gnupg_isotime_t atime, int ndays)
   sec   = atoi_2 (atime+13);
 
   if (year <= 1582) /* The julian date functions don't support this. */
-    return gpg_error (GPG_ERR_INV_VALUE); 
+    return gpg_error (GPG_ERR_INV_VALUE);
 
   jd = date2jd (year, month, day) + ndays;
   jd2date (jd, &year, &month, &day);
 
   if (year > 9999 || month > 12 || day > 31
       || year < 0 || month < 1 || day < 1)
-    return gpg_error (GPG_ERR_INV_VALUE); 
-    
+    return gpg_error (GPG_ERR_INV_VALUE);
+
   snprintf (atime, 16, "%04d%02d%02dT%02d%02d%02d",
             year, month, day, hour, minute, sec);
   return 0;
diff --git a/common/gettime.h b/common/gettime.h
new file mode 100644 (file)
index 0000000..736eb41
--- /dev/null
@@ -0,0 +1,56 @@
+/* gettime.h - Wrapper for time functions
+ * Copyright (C) 2010, 2012 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_GETTIME_H
+#define GNUPG_COMMON_GETTIME_H
+
+#include <time.h>      /* We need time_t. */
+#include <gpg-error.h> /* We need gpg_error_t. */
+
+
+/* A type to hold the ISO time.  Note that this is the same as
+   the KSBA type ksba_isotime_t. */
+typedef char gnupg_isotime_t[16];
+
+time_t gnupg_get_time (void);
+void   gnupg_get_isotime (gnupg_isotime_t timebuf);
+void   gnupg_set_time (time_t newtime, int freeze);
+int    gnupg_faked_time_p (void);
+u32    make_timestamp (void);
+char *elapsed_time_string (time_t since, time_t now);
+
+u32    scan_isodatestr (const char *string);
+int    isotime_p (const char *string);
+int    isotime_human_p (const char *string);
+size_t string2isotime (gnupg_isotime_t atime, const char *string);
+time_t isotime2epoch (const char *string);
+void   epoch2isotime (gnupg_isotime_t timebuf, time_t atime);
+u32    add_days_to_timestamp (u32 stamp, u16 days);
+const char *strtimevalue (u32 stamp);
+const char *strtimestamp (u32 stamp); /* GMT */
+const char *isotimestamp (u32 stamp); /* GMT */
+const char *asctimestamp (u32 stamp); /* localized */
+gpg_error_t add_seconds_to_isotime (gnupg_isotime_t atime, int nseconds);
+gpg_error_t add_days_to_isotime (gnupg_isotime_t atime, int ndays);
+gpg_error_t check_isotime (const gnupg_isotime_t atime);
+void dump_isotime (const gnupg_isotime_t atime);
+void gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s);
+
+
+#endif /*GNUPG_COMMON_GETTIME_H*/
index 28459aa..e2fdb9a 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -82,10 +92,6 @@ gnupg_rl_initialize (void)
                             cleanup_after_signal,
                             readline,
                             add_history);
-  rl_readline_name = "GnuPG";
+  rl_readline_name = GNUPG_NAME;
 #endif
 }
-
-
-
-
index 34b6bdc..faed819 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -44,7 +54,7 @@ findkey_fname (const char *key, const char *fname)
       if (errno != ENOENT)
         {
           err = gpg_error_from_syserror ();
-          log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err));
+          log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err));
         }
       return NULL;
     }
@@ -52,7 +62,7 @@ findkey_fname (const char *key, const char *fname)
   while (fgets (line, DIM(line)-1, fp))
     {
       lnr++;
-      
+
       if (!*line || line[strlen(line)-1] != '\n')
         {
           /* Eat until end of line. */
@@ -60,12 +70,12 @@ findkey_fname (const char *key, const char *fname)
             ;
           err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
                            : GPG_ERR_INCOMPLETE_LINE);
-          log_error (_("file `%s', line %d: %s\n"),
+          log_error (_("file '%s', line %d: %s\n"),
                      fname, lnr, gpg_strerror (err));
         }
       else
         line[strlen(line)-1] = 0; /* Chop the LF. */
-      
+
     again:
       if (!in_item)
         {
@@ -76,7 +86,7 @@ findkey_fname (const char *key, const char *fname)
             continue;
           if (*line != '.' || spacep(line+1))
             {
-              log_info (_("file `%s', line %d: %s\n"),
+              log_info (_("file '%s', line %d: %s\n"),
                         fname, lnr, _("ignoring garbage line"));
               continue;
             }
@@ -96,7 +106,7 @@ findkey_fname (const char *key, const char *fname)
       if (*line == '#')
         continue;
       if (*line == '.')
-        { 
+        {
           if (spacep(line+1))
             p = line + 2;
           else
@@ -123,10 +133,10 @@ findkey_fname (const char *key, const char *fname)
   if ( !err && ferror (fp) )
     {
       err = gpg_error_from_syserror ();
-      log_error (_("error reading `%s', line %d: %s\n"),
+      log_error (_("error reading '%s', line %d: %s\n"),
                  fname, lnr, gpg_strerror (err));
     }
-  
+
   fclose (fp);
   if (is_membuf_ready (&mb))
     {
@@ -182,7 +192,7 @@ findkey_locale (const char *key, const char *locname,
       else
         result = NULL;
     }
-  
+
   if (!result && (!only_current_locale || !*locname) )
     {
       /* Last try: Search in file without any locale info.  ("help.txt") */
@@ -204,18 +214,18 @@ findkey_locale (const char *key, const char *locname,
      /etc/gnupg/help.txt
      /usr/share/gnupg/help.LL.txt
      /usr/share/gnupg/help.txt
-     
+
    Here LL denotes the two digit language code of the current locale.
    If ONLY_CURRENT_LOCALE is set, the fucntion won;t fallback to the
    english valiant ("help.txt") unless that locale has been requested.
-   
+
    The help file needs to be encoded in UTF-8, lines with a '#' in the
    first column are comment lines and entirely ignored.  Help keys are
    identified by a key consisting of a single word with a single dot
    as the first character.  All key lines listed without any
    intervening lines (except for comment lines) lead to the same help
    text.  Lines following the key lines make up the actual hep texts.
-   
+
 */
 
 char *
@@ -249,7 +259,7 @@ gnupg_get_help_string (const char *key, int only_current_locale)
   if (!key || !*key)
     return NULL;
 
-  result = findkey_locale (key, locname, only_current_locale, 
+  result = findkey_locale (key, locname, only_current_locale,
                            gnupg_sysconfdir ());
   if (!result)
     result = findkey_locale (key, locname, only_current_locale,
index 4b03cfe..7939841 100644 (file)
@@ -1,15 +1,25 @@
 /* homedir.c - Setup the home directory.
- * Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2006, 2007, 2010 Free Software Foundation, Inc.
  * Copyright (C) 2013 Werner Koch
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -24,9 +34,9 @@
 #include <fcntl.h>
 
 #ifdef HAVE_W32_SYSTEM
-# ifdef HAVE_WINSOCK2_H
-#  include <winsock2.h>
-# endif
+#include <winsock2.h>   /* Due to the stupid mingw64 requirement to
+                           include this header before windows.h which
+                           is often implicitly included.  */
 #include <shlobj.h>
 #ifndef CSIDL_APPDATA
 #define CSIDL_APPDATA 0x001a
 #include "util.h"
 #include "sysutils.h"
 
-
 #ifdef HAVE_W32_SYSTEM
 /* A flag used to indicate that a control file for gpgconf has been
    detected.  Under Windows the presence of this file indicates a
    portable installations and triggers several changes:
 
    - The GNUGHOME directory is fixed relative to installation
-     directory.  All other means to set the home directory are
-     ignored.
+     directory.  All other means to set the home directory are ignore.
 
-   - All registry variables are ignored.
+   - All registry variables will be ignored.
 
    This flag is not used on Unix systems.
  */
 static int w32_portable_app;
+#endif /*HAVE_W32_SYSTEM*/
 
+#ifdef HAVE_W32_SYSTEM
 /* This flag is true if this process' binary has been installed under
    bin and not in the root directory. */
 static int w32_bin_is_bin;
+#endif /*HAVE_W32_SYSTEM*/
 
-/* Just a little prototype.  */
+
+#ifdef HAVE_W32_SYSTEM
 static const char *w32_rootdir (void);
+#endif
 
-#endif /*HAVE_W32_SYSTEM*/
 
 
+#ifdef HAVE_W32_SYSTEM
+static void
+w32_try_mkdir (const char *dir)
+{
+#ifdef HAVE_W32CE_SYSTEM
+  wchar_t *wdir = utf8_to_wchar (dir);
+  if (wdir)
+    {
+      CreateDirectory (wdir, NULL);
+      xfree (wdir);
+    }
+#else
+  CreateDirectory (dir, NULL);
+#endif
+}
+#endif
 
 
 /* This is a helper function to load a Windows function from either of
@@ -155,7 +183,7 @@ standard_homedir (void)
 
               /* Try to create the directory if it does not yet exists.  */
               if (access (dir, F_OK))
-                CreateDirectory (dir, NULL);
+                w32_try_mkdir (dir);
             }
           else
             dir = GNUPG_DEFAULT_HOMEDIR;
@@ -193,7 +221,8 @@ default_homedir (void)
             {
               char *tmp;
 
-              tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG",
+              tmp = read_w32_registry_string (NULL,
+                                              GNUPG_REGISTRY_DIR,
                                               "HomeDir");
               if (tmp && !*tmp)
                 {
@@ -235,14 +264,20 @@ check_portable_app (const char *dir)
         {
           /* gpgconf.ctl file found.  Record this fact.  */
           w32_portable_app = 1;
-
+          {
+            unsigned int flags;
+            log_get_prefix (&flags);
+            log_set_prefix (NULL, (flags | JNLIB_LOG_NO_REGISTRY));
+          }
           /* FIXME: We should read the file to detect special flags
-             and print a warning if we don't understand them.  */
+             and print a warning if we don't understand them  */
         }
     }
   xfree (fname);
 }
 
+
+/* Determine the root directory of the gnupg installation on Windows.  */
 static const char *
 w32_rootdir (void)
 {
@@ -252,8 +287,20 @@ w32_rootdir (void)
   if (!got_dir)
     {
       char *p;
-
-      if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
+      int rc;
+
+#ifdef HAVE_W32CE_SYSTEM
+      {
+        wchar_t wdir [MAX_PATH+5];
+        rc = GetModuleFileName (NULL, wdir, MAX_PATH);
+        if (rc && WideCharToMultiByte (CP_UTF8, 0, wdir, -1, dir, MAX_PATH-4,
+                                       NULL, NULL) < 0)
+          rc = 0;
+      }
+#else
+      rc = GetModuleFileName (NULL, dir, MAX_PATH);
+#endif
+      if (!rc)
         {
           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
           *dir = 0;
@@ -269,7 +316,6 @@ w32_rootdir (void)
           /* If we are installed below "bin" we strip that and use
              the top directory instead.  */
           p = strrchr (dir, DIRSEP_C);
-
           if (p && !strcmp (p+1, "bin"))
             {
               *p = 0;
@@ -278,7 +324,7 @@ w32_rootdir (void)
         }
       if (!p)
         {
-          log_debug ("bad filename `%s' returned for this process\n", dir);
+          log_debug ("bad filename '%s' returned for this process\n", dir);
           *dir = 0;
         }
     }
@@ -301,8 +347,8 @@ w32_commondir (void)
 
       /* Make sure that w32_rootdir has been called so that we are
          able to check the portable application flag.  The common dir
-         is identical to the rootdir.  In that case there is also no
-         need to strdup its value.  */
+         is the identical to the rootdir.  In that case there is also
+         no need to strdup its value.  */
       rdir = w32_rootdir ();
       if (w32_portable_app)
         return rdir;
@@ -329,6 +375,8 @@ w32_commondir (void)
 #endif /*HAVE_W32_SYSTEM*/
 
 
+
+
 /* Return the name of the sysconfdir.  This is a static string.  This
    function is required because under Windows we can't simply compile
    it in.  */
@@ -356,7 +404,13 @@ gnupg_sysconfdir (void)
 const char *
 gnupg_bindir (void)
 {
-#ifdef HAVE_W32_SYSTEM
+#if defined (HAVE_W32CE_SYSTEM)
+  static char *name;
+
+  if (!name)
+    name = xstrconcat (w32_rootdir (), DIRSEP_S "bin", NULL);
+  return name;
+#elif defined(HAVE_W32_SYSTEM)
   const char *rdir;
 
   rdir = w32_rootdir ();
@@ -395,13 +449,7 @@ gnupg_libdir (void)
   static char *name;
 
   if (!name)
-    {
-      const char *s1, *s2;
-      s1 = w32_rootdir ();
-      s2 = DIRSEP_S "lib" DIRSEP_S "gnupg";
-      name = xmalloc (strlen (s1) + strlen (s2) + 1);
-      strcpy (stpcpy (name, s1), s2);
-    }
+    name = xstrconcat (w32_rootdir (), DIRSEP_S "lib" DIRSEP_S "gnupg", NULL);
   return name;
 #else /*!HAVE_W32_SYSTEM*/
   return GNUPG_LIBDIR;
@@ -415,13 +463,7 @@ gnupg_datadir (void)
   static char *name;
 
   if (!name)
-    {
-      const char *s1, *s2;
-      s1 = w32_rootdir ();
-      s2 = DIRSEP_S "share" DIRSEP_S "gnupg";
-      name = xmalloc (strlen (s1) + strlen (s2) + 1);
-      strcpy (stpcpy (name, s1), s2);
-    }
+    name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "gnupg", NULL);
   return name;
 #else /*!HAVE_W32_SYSTEM*/
   return GNUPG_DATADIR;
@@ -436,13 +478,8 @@ gnupg_localedir (void)
   static char *name;
 
   if (!name)
-    {
-      const char *s1, *s2;
-      s1 = w32_rootdir ();
-      s2 = DIRSEP_S "share" DIRSEP_S "locale";
-      name = xmalloc (strlen (s1) + strlen (s2) + 1);
-      strcpy (stpcpy (name, s1), s2);
-    }
+    name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "locale",
+                       NULL);
   return name;
 #else /*!HAVE_W32_SYSTEM*/
   return LOCALEDIR;
@@ -450,52 +487,143 @@ gnupg_localedir (void)
 }
 
 
-/* Return the default socket name used by DirMngr. */
+/* Return the name of the cache directory.  The name is allocated in a
+   static area on the first use.  Windows only: If the directory does
+   not exist it is created.  */
+const char *
+gnupg_cachedir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+  static const char *dir;
+
+  if (!dir)
+    {
+      const char *rdir;
+
+      rdir = w32_rootdir ();
+      if (w32_portable_app)
+        {
+          dir = xstrconcat (rdir,
+                            DIRSEP_S, "var",
+                            DIRSEP_S, "cache",
+                            DIRSEP_S, "gnupg", NULL);
+        }
+      else
+        {
+          char path[MAX_PATH];
+          const char *s1[] = { "GNU", "cache", "gnupg", NULL };
+          int s1_len;
+          const char **comp;
+
+          s1_len = 0;
+          for (comp = s1; *comp; comp++)
+            s1_len += 1 + strlen (*comp);
+
+          if (w32_shgetfolderpath (NULL, CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE,
+                                   NULL, 0, path) >= 0)
+            {
+              char *tmp = xmalloc (strlen (path) + s1_len + 1);
+              char *p;
+
+              p = stpcpy (tmp, path);
+              for (comp = s1; *comp; comp++)
+                {
+                  p = stpcpy (p, "\\");
+                  p = stpcpy (p, *comp);
+
+                  if (access (tmp, F_OK))
+                    w32_try_mkdir (tmp);
+                }
+
+              dir = tmp;
+            }
+          else
+            {
+              dir = "c:\\temp\\cache\\gnupg";
+#ifdef HAVE_W32CE_SYSTEM
+              dir += 2;
+              w32_try_mkdir ("\\temp\\cache");
+              w32_try_mkdir ("\\temp\\cache\\gnupg");
+#endif
+            }
+        }
+    }
+  return dir;
+#else /*!HAVE_W32_SYSTEM*/
+  return GNUPG_LOCALSTATEDIR "/cache/" PACKAGE_NAME;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Return the system socket name used by DirMngr.  */
 const char *
-dirmngr_socket_name (void)
+dirmngr_sys_socket_name (void)
 {
 #ifdef HAVE_W32_SYSTEM
   static char *name;
 
   if (!name)
     {
-      char s1[MAX_PATH];
-      const char *s2;
-
-      /* We need something akin CSIDL_COMMON_PROGRAMS, but local
-        (non-roaming).  */
-      if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0)
-       strcpy (s1, "C:\\WINDOWS");
-      s2 = DIRSEP_S "S.dirmngr";
+      char *p;
+# ifdef HAVE_W32CE_SYSTEM
+      const char *s1, *s2;
+
+      s1 = default_homedir ();
+# else
+      char s1buf[MAX_PATH];
+      const char *s1, *s2;
+
+      s1 = default_homedir ();
+      if (!w32_portable_app)
+        {
+          /* We need something akin CSIDL_COMMON_PROGRAMS, but local
+             (non-roaming).  This is because the file needs to be on
+             the local machine and makes only sense on that machine.
+             CSIDL_WINDOWS seems to be the only location which
+             guarantees that. */
+          if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1buf) < 0)
+            strcpy (s1buf, "C:\\WINDOWS");
+          s1 = s1buf;
+        }
+# endif
+      s2 = DIRSEP_S DIRMNGR_SOCK_NAME;
       name = xmalloc (strlen (s1) + strlen (s2) + 1);
       strcpy (stpcpy (name, s1), s2);
+      for (p=name; *p; p++)
+        if (*p == '/')
+          *p = '\\';
     }
   return name;
 #else /*!HAVE_W32_SYSTEM*/
-  return "/var/run/dirmngr/socket";
+  return GNUPG_LOCALSTATEDIR "/run/" PACKAGE_NAME "/"DIRMNGR_SOCK_NAME;
 #endif /*!HAVE_W32_SYSTEM*/
 }
 
 
+/* Return the user socket name used by DirMngr.  If a user specific
+   dirmngr installation is not supported, NULL is returned.  */
+const char *
+dirmngr_user_socket_name (void)
+{
+  static char *name;
+
+  if (!name)
+    name = make_absfilename (default_homedir (), DIRMNGR_SOCK_NAME, NULL);
+  return name;
+}
+
 
 /* Return the file name of a helper tool.  WHICH is one of the
    GNUPG_MODULE_NAME_foo constants.  */
 const char *
 gnupg_module_name (int which)
 {
-  const char *s, *s2;
-
-#define X(a,b) do {                                          \
-        static char *name;                                   \
-        if (!name)                                           \
-          {                                                  \
-            s = gnupg_ ## a ();                              \
-            s2 = DIRSEP_S b EXEEXT_S;                        \
-            name = xmalloc (strlen (s) + strlen (s2) + 1);   \
-            strcpy (stpcpy (name, s), s2);                   \
-          }                                                  \
-        return name;                                         \
-      } while (0)
+#define X(a,b) do {                                                     \
+    static char *name;                                                  \
+    if (!name)                                                          \
+      name = xstrconcat (gnupg_ ## a (), DIRSEP_S b EXEEXT_S, NULL);    \
+    return name;                                                        \
+  } while (0)
 
   switch (which)
     {
@@ -524,7 +652,7 @@ gnupg_module_name (int which)
 #ifdef GNUPG_DEFAULT_DIRMNGR
       return GNUPG_DEFAULT_DIRMNGR;
 #else
-      X(bindir, "dirmngr");
+      X(bindir, DIRMNGR_NAME);
 #endif
 
     case GNUPG_MODULE_NAME_PROTECT_TOOL:
@@ -534,6 +662,13 @@ gnupg_module_name (int which)
       X(libexecdir, "gpg-protect-tool");
 #endif
 
+    case GNUPG_MODULE_NAME_DIRMNGR_LDAP:
+#ifdef GNUPG_DEFAULT_DIRMNGR_LDAP
+      return GNUPG_DEFAULT_DIRMNGR_LDAP;
+#else
+      X(libexecdir, "dirmngr_ldap");
+#endif
+
     case GNUPG_MODULE_NAME_CHECK_PATTERN:
       X(libexecdir, "gpg-check-pattern");
 
@@ -541,7 +676,7 @@ gnupg_module_name (int which)
       X(bindir, "gpgsm");
 
     case GNUPG_MODULE_NAME_GPG:
-      X(bindir, "gpg2");
+      X(bindir, NAME_OF_INSTALLED_GPG);
 
     case GNUPG_MODULE_NAME_CONNECT_AGENT:
       X(bindir, "gpg-connect-agent");
similarity index 51%
rename from include/host2net.h
rename to common/host2net.h
index be5e520..dd20e36 100644 (file)
@@ -1,5 +1,5 @@
 /* host2net.h - Endian conversion macros
- * Copyright (C) 1998, 2014, 2015  Werner Koch
+ * Copyright (C) 1998, 2014  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -32,6 +32,9 @@
 
 #include "types.h"
 
+#define buftoulong( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
+                      (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
+#define buftoushort( p )  ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
 #define ulongtobuf( p, a ) do {                          \
                            ((byte*)p)[0] = a >> 24;    \
                            ((byte*)p)[1] = a >> 16;    \
                            ((byte*)p)[0] = a >>  8;    \
                            ((byte*)p)[1] = a      ;    \
                        } while(0)
-
-
-static inline unsigned long
-buf16_to_ulong (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((unsigned long)p[0] << 8) | p[1]);
-}
-
-static inline unsigned int
-buf16_to_uint (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((unsigned int)p[0] << 8) | p[1]);
-}
-
-static inline unsigned short
-buf16_to_ushort (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((unsigned short)p[0] << 8) | p[1]);
-}
-
-static inline u16
-buf16_to_u16 (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((u16)p[0] << 8) | p[1]);
-}
-
-static inline size_t
-buf32_to_size_t (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((size_t)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
-}
-
-static inline unsigned long
-buf32_to_ulong (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((unsigned long)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
-}
-
-static inline unsigned int
-buf32_to_uint (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((unsigned int)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
-}
-
-static inline u32
-buf32_to_u32 (const void *buffer)
-{
-  const unsigned char *p = buffer;
-
-  return (((u32)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
-}
+#define buftou32( p)   buftoulong( (p) )
+#define u32tobuf( p, a) ulongtobuf( (p), (a) )
 
 
 #endif /*GNUPG_COMMON_HOST2NET_H*/
index 15d64c4..413efd8 100644 (file)
@@ -1,15 +1,26 @@
 /* http.c  -  HTTP protocol handler
- * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006,
- *               2009, 2012, 2013 Free Software Foundation, Inc.
+ * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
+ *               2011 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 /* Simple HTTP client implementation.  We try to keep the code as
    self-contained as possible.  There are some contraints however:
 
+  - estream is required.  We now require estream because it provides a
+    very useful and portable asprintf implementation and the fopencookie
+    function.
   - stpcpy is required
   - fixme: list other requirements.
 
 
-  - With HTTP_USE_ESTREAM defined, all I/O is done through estream.
-  - With HTTP_USE_GNUTLS support for https is provided (this also
-    requires estream).
+  - With HTTP_USE_NTBTLS or HTTP_USE_GNUTLS support for https is
+    provided (this also requires estream).
+
   - With HTTP_NO_WSASTARTUP the socket initialization is not done
     under Windows.  This is useful if the socket layer has already
     been initialized elsewhere.  This also avoids the installation of
 # include <netdb.h>
 #endif /*!HAVE_W32_SYSTEM*/
 
-#ifdef HTTP_USE_GNUTLS
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+# undef USE_NPTH
+#endif
+
+#ifdef USE_NPTH
+# include <npth.h>
+#endif
+
+#if defined (HTTP_USE_GNUTLS) && defined (HTTP_USE_NTBTLS)
+# error Both, HTTP_USE_GNUTLS and HTTP_USE_NTBTLS, are defined.
+#endif
+
+#ifdef HTTP_USE_NTBTLS
+# include <ntbtls.h>
+#elif HTTP_USE_GNUTLS
 # include <gnutls/gnutls.h>
-/* For non-understandable reasons GNUTLS dropped the _t suffix from
-   all types. yes, ISO-C might be read as this but there are still
-   other name space conflicts and using _t is actually a Good
-   Thing. */
-typedef gnutls_session gnutls_session_t;
-typedef gnutls_transport_ptr gnutls_transport_ptr_t;
+# include <gnutls/x509.h>
 #endif /*HTTP_USE_GNUTLS*/
 
-#ifdef TEST
-#undef USE_DNS_SRV
-#endif
 
 #include "util.h"
 #include "i18n.h"
 #include "http.h"
 #ifdef USE_DNS_SRV
-#include "srv.h"
+# include "srv.h"
 #else /*!USE_DNS_SRV*/
-/* If we are not compiling with SRV record support we provide stub
-   data structures. */
-#ifndef MAXDNAME
-#define MAXDNAME 1025
-#endif
+  /* If we are not compiling with SRV record support we provide stub
+     data structures. */
+# ifndef MAXDNAME
+#  define MAXDNAME 1025
+# endif
 struct srventry
 {
   unsigned short priority;
@@ -96,6 +116,16 @@ struct srventry
 #endif/*!USE_DNS_SRV*/
 
 
+#ifdef USE_NPTH
+# define my_select(a,b,c,d,e)  npth_select ((a), (b), (c), (d), (e))
+# define my_connect(a,b,c)     npth_connect ((a), (b), (c))
+# define my_accept(a,b,c)      npth_accept ((a), (b), (c))
+#else
+# define my_select(a,b,c,d,e)  select ((a), (b), (c), (d), (e))
+# define my_connect(a,b,c)     connect ((a), (b), (c))
+# define my_accept(a,b,c)      accept ((a), (b), (c))
+#endif
+
 #ifdef HAVE_W32_SYSTEM
 #define sock_close(a)  closesocket(a)
 #else
@@ -105,6 +135,9 @@ struct srventry
 #ifndef EAGAIN
 #define EAGAIN  EWOULDBLOCK
 #endif
+#ifndef INADDR_NONE  /* Slowaris is missing that.  */
+#define INADDR_NONE  ((unsigned long)(-1))
+#endif /*INADDR_NONE*/
 
 #define HTTP_PROXY_ENV           "http_proxy"
 #define MAX_LINELEN 20000  /* Max. length of a HTTP header line. */
@@ -113,38 +146,60 @@ struct srventry
                         "01234567890@"                 \
                         "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
 
-/* Define a prefix to map stream functions to the estream library. */
-#ifdef HTTP_USE_ESTREAM
-#define P_ES(a)  es_ ## a
+/* A long counter type.  */
+#ifdef HAVE_STRTOULL
+typedef unsigned long long longcounter_t;
+# define counter_strtoul(a) strtoull ((a), NULL, 10)
 #else
-#define P_ES(a)  a
-#endif
-#ifndef HTTP_USE_GNUTLS
-typedef void * gnutls_session_t;
+typedef unsigned long longcounter_t;
+# define counter_strtoul(a) strtoul ((a), NULL, 10)
 #endif
-#if defined(HTTP_USE_GNUTLS) && !defined(HTTP_USE_ESTREAM)
-#error Use of GNUTLS also requires support for Estream
+
+#if HTTP_USE_NTBTLS
+typedef ntbtls_t         tls_session_t;
+# define USE_TLS 1
+#elif HTTP_USE_GNUTLS
+typedef gnutls_session_t tls_session_t;
+# define USE_TLS 1
+#else
+typedef void *tls_session_t;
+# undef USE_TLS
 #endif
 
-static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part);
+static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part,
+                                    int no_scheme_check, int force_tls);
+static gpg_error_t parse_uri (parsed_uri_t *ret_uri, const char *uri,
+                              int no_scheme_check, int force_tls);
 static int remove_escapes (char *string);
 static int insert_escapes (char *buffer, const char *string,
                            const char *special);
 static uri_tuple_t parse_tuple (char *string);
-static gpg_error_t send_request (http_t hd, const char *auth,const char *proxy,
-                                struct http_srv *srv,strlist_t headers);
+static gpg_error_t send_request (http_t hd, const char *httphost,
+                                 const char *auth,const char *proxy,
+                                const char *srvtag,strlist_t headers);
 static char *build_rel_path (parsed_uri_t uri);
 static gpg_error_t parse_response (http_t hd);
 
 static int connect_server (const char *server, unsigned short port,
-                           unsigned int flags, struct http_srv *srv);
+                           unsigned int flags, const char *srvtag,
+                           int *r_host_not_found);
 static gpg_error_t write_server (int sock, const char *data, size_t length);
 
-#ifdef HTTP_USE_ESTREAM
 static ssize_t cookie_read (void *cookie, void *buffer, size_t size);
 static ssize_t cookie_write (void *cookie, const void *buffer, size_t size);
 static int cookie_close (void *cookie);
 
+
+/* A socket object used to a allow ref counting of sockets.  */
+struct my_socket_s
+{
+  int fd;       /* The actual socket - shall never be -1.  */
+  int refcount; /* Number of references to this socket.  */
+};
+typedef struct my_socket_s *my_socket_t;
+
+
+/* Cookie function structure and cookie object.  */
 static es_cookie_io_functions_t cookie_functions =
   {
     cookie_read,
@@ -155,17 +210,42 @@ static es_cookie_io_functions_t cookie_functions =
 
 struct cookie_s
 {
-  int fd;  /* File descriptor or -1 if already closed. */
-  gnutls_session_t tls_session;  /* TLS session context or NULL if not used. */
-  int keep_socket; /* Flag to communicate with teh close handler. */
+  /* Socket object or NULL if already closed. */
+  my_socket_t sock;
+
+  /* The session object or NULL if not used. */
+  http_session_t session;
+
+  /* True if TLS is to be used.  */
+  int use_tls;
+
+  /* The remaining content length and a flag telling whether to use
+     the content length.  */
+  longcounter_t content_length;
+  unsigned int content_length_valid:1;
 };
 typedef struct cookie_s *cookie_t;
 
-#endif /*HTTP_USE_ESTREAM*/
-
+/* The session object. */
+struct http_session_s
+{
+  int refcount;    /* Number of references to this object.  */
 #ifdef HTTP_USE_GNUTLS
-static gpg_error_t (*tls_callback) (http_t, gnutls_session_t, int);
+  gnutls_certificate_credentials_t certcred;
 #endif /*HTTP_USE_GNUTLS*/
+#ifdef USE_TLS
+  tls_session_t tls_session;
+  struct {
+    int done;      /* Verifciation has been done.  */
+    int rc;        /* TLS verification return code.  */
+    unsigned int status; /* Verification status.  */
+  } verify;
+  char *servername; /* Malloced server name.  */
+#endif /*USE_TLS*/
+  /* A callback function to log details of TLS certifciates.  */
+  void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
+                       const void **, size_t *);
+};
 
 
 /* An object to save header lines. */
@@ -182,18 +262,14 @@ typedef struct header_s *header_t;
 struct http_context_s
 {
   unsigned int status_code;
-  int sock;
-  int in_data;
-#ifdef HTTP_USE_ESTREAM
+  my_socket_t sock;
+  unsigned int in_data:1;
+  unsigned int is_http_0_9:1;
   estream_t fp_read;
   estream_t fp_write;
   void *write_cookie;
-#else /*!HTTP_USE_ESTREAM*/
-  FILE *fp_read;
-  FILE *fp_write;
-#endif /*!HTTP_USE_ESTREAM*/
-  void *tls_context;
-  int is_http_0_9;
+  void *read_cookie;
+  http_session_t session;
   parsed_uri_t uri;
   http_req_t req_type;
   char *buffer;          /* Line buffer. */
@@ -203,6 +279,12 @@ struct http_context_s
 };
 
 
+/* The global callback for the verification fucntion.  */
+static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
+
+/* The list of files with trusted CA certificates.  */
+static strlist_t tls_ca_certlist;
+
 
 \f
 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
@@ -252,6 +334,102 @@ init_sockets (void)
 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
 
 
+/* Create a new socket object.  Returns NULL and closes FD if not
+   enough memory is available.  */
+static my_socket_t
+_my_socket_new (int lnr, int fd)
+{
+  my_socket_t so;
+
+  so = xtrymalloc (sizeof *so);
+  if (!so)
+    {
+      int save_errno = errno;
+      sock_close (fd);
+      gpg_err_set_errno (save_errno);
+      return NULL;
+    }
+  so->fd = fd;
+  so->refcount = 1;
+  /* log_debug ("http.c:socket_new(%d): object %p for fd %d created\n", */
+  /*            lnr, so, so->fd); */
+  (void)lnr;
+  return so;
+}
+#define my_socket_new(a) _my_socket_new (__LINE__, (a))
+
+/* Bump up the reference counter for the socket object SO.  */
+static my_socket_t
+_my_socket_ref (int lnr, my_socket_t so)
+{
+  so->refcount++;
+  /* log_debug ("http.c:socket_ref(%d) object %p for fd %d refcount now %d\n", */
+  /*            lnr, so, so->fd, so->refcount); */
+  (void)lnr;
+  return so;
+}
+#define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
+
+
+/* Bump down the reference counter for the socket object SO.  If SO
+   has no more references, close the socket and release the
+   object.  */
+static void
+_my_socket_unref (int lnr, my_socket_t so,
+                  void (*preclose)(void*), void *preclosearg)
+{
+  if (so)
+    {
+      so->refcount--;
+      /* log_debug ("http.c:socket_unref(%d): object %p for fd %d ref now %d\n", */
+      /*            lnr, so, so->fd, so->refcount); */
+      (void)lnr;
+      if (!so->refcount)
+        {
+          if (preclose)
+            preclose (preclosearg);
+          sock_close (so->fd);
+          xfree (so);
+        }
+    }
+}
+#define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
+
+
+#if defined (USE_NPTH) && defined(HTTP_USE_GNUTLS)
+static ssize_t
+my_npth_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
+{
+  my_socket_t sock = ptr;
+  return npth_read (sock->fd, buffer, size);
+}
+static ssize_t
+my_npth_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
+{
+  my_socket_t sock = ptr;
+  return npth_write (sock->fd, buffer, size);
+}
+#endif /*USE_NPTH && HTTP_USE_GNUTLS*/
+
+
+
+\f
+/* This notification function is called by estream whenever stream is
+   closed.  Its purpose is to mark the closing in the handle so
+   that a http_close won't accidentally close the estream.  The function
+   http_close removes this notification so that it won't be called if
+   http_close was used before an es_fclose.  */
+static void
+fp_onclose_notification (estream_t stream, void *opaque)
+{
+  http_t hd = opaque;
+
+  if (hd->fp_read && hd->fp_read == stream)
+    hd->fp_read = NULL;
+  else if (hd->fp_write && hd->fp_write == stream)
+    hd->fp_write = NULL;
+}
+
 
 /*
  * Helper function to create an HTTP header with hex encoded data.  A
@@ -261,13 +439,13 @@ init_sockets (void)
  */
 static char *
 make_header_line (const char *prefix, const char *suffix,
-                   const void *data, size_t len )
+                  const void *data, size_t len )
 {
   static unsigned char bintoasc[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "abcdefghijklmnopqrstuvwxyz"
     "0123456789+/";
-  const unsigned int *s = data;
+  const unsigned char *s = data;
   char *buffer, *p;
 
   buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
@@ -280,6 +458,7 @@ make_header_line (const char *prefix, const char *suffix,
       *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
       *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
       *p++ = bintoasc[s[2]&077];
+      *p = 0;
     }
   if ( len == 2 )
     {
@@ -295,6 +474,7 @@ make_header_line (const char *prefix, const char *suffix,
       *p++ = '=';
       *p++ = '=';
     }
+  *p = 0;
   strcpy (p, suffix);
   return buffer;
 }
@@ -302,25 +482,218 @@ make_header_line (const char *prefix, const char *suffix,
 
 
 \f
+/* Register a non-standard global TLS callback function.  If no
+   verification is desired a callback needs to be registered which
+   always returns NULL.  */
 void
-http_register_tls_callback ( gpg_error_t (*cb) (http_t, void *, int) )
+http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
 {
-#ifdef HTTP_USE_GNUTLS
-  tls_callback = (gpg_error_t (*) (http_t, gnutls_session_t, int))cb;
-#else
-  (void)cb;
-#endif
+  tls_callback = cb;
+}
+
+
+/* Register a CA certificate for future use.  The certificate is
+   expected to be in FNAME.  PEM format is assume if FNAME has a
+   suffix of ".pem".  If FNAME is NULL the list of CA files is
+   removed.  */
+void
+http_register_tls_ca (const char *fname)
+{
+  strlist_t sl;
+
+  if (!fname)
+    {
+      free_strlist (tls_ca_certlist);
+      tls_ca_certlist = NULL;
+    }
+  else
+    {
+      sl = add_to_strlist (&tls_ca_certlist, fname);
+      if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
+        sl->flags = 1;
+    }
+}
+
+
+/* Release a session.  Take care not to release it while it is being
+   used by a http context object.  */
+static void
+session_unref (int lnr, http_session_t sess)
+{
+  if (!sess)
+    return;
+
+  sess->refcount--;
+  /* log_debug ("http.c:session_unref(%d): sess %p ref now %d\n", */
+  /*            lnr, sess, sess->refcount); */
+  (void)lnr;
+  if (sess->refcount)
+    return;
+
+#ifdef USE_TLS
+# ifdef HTTP_USE_GNUTLS
+  if (sess->tls_session)
+    {
+      my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
+      my_socket_unref (sock, NULL, NULL);
+      gnutls_deinit (sess->tls_session);
+    }
+  if (sess->certcred)
+    gnutls_certificate_free_credentials (sess->certcred);
+# endif /*HTTP_USE_GNUTLS*/
+  xfree (sess->servername);
+#endif /*USE_TLS*/
+
+  xfree (sess);
+}
+#define http_session_unref(a) session_unref (__LINE__, (a))
+
+void
+http_session_release (http_session_t sess)
+{
+  http_session_unref (sess);
+}
+
+
+/* Create a new session object which is currently used to enable TLS
+   support.  It may eventually allow reusing existing connections.  */
+gpg_error_t
+http_session_new (http_session_t *r_session, const char *tls_priority)
+{
+  gpg_error_t err;
+  http_session_t sess;
+
+  *r_session = NULL;
+
+  sess = xtrycalloc (1, sizeof *sess);
+  if (!sess)
+    return gpg_error_from_syserror ();
+  sess->refcount = 1;
+
+#if HTTP_USE_NTBTLS
+  {
+    (void)tls_priority;
+
+    err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT);
+    if (err)
+      {
+        log_error ("ntbtls_new failed: %s\n", gpg_strerror (err));
+        goto leave;
+      }
+  }
+#elif HTTP_USE_GNUTLS
+  {
+    const char *errpos;
+    int rc;
+    strlist_t sl;
+
+    rc = gnutls_certificate_allocate_credentials (&sess->certcred);
+    if (rc < 0)
+      {
+        log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
+                   gnutls_strerror (rc));
+        err = gpg_error (GPG_ERR_GENERAL);
+        goto leave;
+      }
+
+    for (sl = tls_ca_certlist; sl; sl = sl->next)
+      {
+        rc = gnutls_certificate_set_x509_trust_file
+          (sess->certcred, sl->d,
+           (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
+        if (rc < 0)
+          log_info ("setting CA from file '%s' failed: %s\n",
+                    sl->d, gnutls_strerror (rc));
+      }
+
+    rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
+    if (rc < 0)
+      {
+        log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
+        err = gpg_error (GPG_ERR_GENERAL);
+        goto leave;
+      }
+    /* A new session has the transport ptr set to (void*(-1), we need
+       it to be NULL.  */
+    gnutls_transport_set_ptr (sess->tls_session, NULL);
+
+    rc = gnutls_priority_set_direct (sess->tls_session,
+                                     tls_priority? tls_priority : "NORMAL",
+                                     &errpos);
+    if (rc < 0)
+      {
+        log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
+                   errpos, gnutls_strerror (rc));
+        err = gpg_error (GPG_ERR_GENERAL);
+        goto leave;
+      }
+
+    rc = gnutls_credentials_set (sess->tls_session,
+                                 GNUTLS_CRD_CERTIFICATE, sess->certcred);
+    if (rc < 0)
+      {
+        log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
+        err = gpg_error (GPG_ERR_GENERAL);
+        goto leave;
+      }
+  }
+#else /*!HTTP_USE_GNUTLS*/
+  {
+    (void)tls_priority;
+  }
+#endif /*!HTTP_USE_GNUTLS*/
+
+  /* log_debug ("http.c:session_new: sess %p created\n", sess); */
+  err = 0;
+
+#if USE_TLS
+ leave:
+#endif /*USE_TLS*/
+  if (err)
+    http_session_unref (sess);
+  else
+    *r_session = sess;
+
+  return err;
+}
+
+
+/* Increment the reference count for session SESS.  Passing NULL for
+   SESS is allowed. */
+http_session_t
+http_session_ref (http_session_t sess)
+{
+  if (sess)
+    {
+      sess->refcount++;
+      /* log_debug ("http.c:session_ref: sess %p ref now %d\n", sess, */
+      /*            sess->refcount); */
+    }
+  return sess;
+}
+
+
+void
+http_session_set_log_cb (http_session_t sess,
+                         void (*cb)(http_session_t, gpg_error_t,
+                                    const char *hostname,
+                                    const void **certs, size_t *certlens))
+{
+  sess->cert_log_cb = cb;
 }
 
 
 
-/* Start a HTTP retrieval and return on success in R_HD a context
-   pointer for completing the the request and to wait for the
-   response. */
+\f
+/* Start a HTTP retrieval and on success store at R_HD a context
+   pointer for completing the request and to wait for the response.
+   If HTTPHOST is not NULL it is used hor the Host header instead of a
+   Host header derived from the URL. */
 gpg_error_t
 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
+           const char *httphost,
            const char *auth, unsigned int flags, const char *proxy,
-           void *tls_context, struct http_srv *srv, strlist_t headers)
+           http_session_t session, const char *srvtag, strlist_t headers)
 {
   gpg_error_t err;
   http_t hd;
@@ -328,30 +701,125 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
   *r_hd = NULL;
 
   if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
-    return gpg_error (GPG_ERR_INV_ARG);
+    return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
 
   /* Create the handle. */
   hd = xtrycalloc (1, sizeof *hd);
   if (!hd)
     return gpg_error_from_syserror ();
-  hd->sock = -1;
   hd->req_type = reqtype;
   hd->flags = flags;
-  hd->tls_context = tls_context;
+  hd->session = http_session_ref (session);
+
+  err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
+  if (!err)
+    err = send_request (hd, httphost, auth, proxy, srvtag, headers);
+
+  if (err)
+    {
+      my_socket_unref (hd->sock, NULL, NULL);
+      if (hd->fp_read)
+        es_fclose (hd->fp_read);
+      if (hd->fp_write)
+        es_fclose (hd->fp_write);
+      http_session_unref (hd->session);
+      xfree (hd);
+    }
+  else
+    *r_hd = hd;
+  return err;
+}
+
+
+/* This function is useful to connect to a generic TCP service using
+   this http abstraction layer.  This has the advantage of providing
+   service tags and an estream interface.  */
+gpg_error_t
+http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
+                  unsigned int flags, const char *srvtag)
+{
+  gpg_error_t err = 0;
+  int sock;
+  http_t hd;
+  cookie_t cookie;
+  int hnf;
+
+  *r_hd = NULL;
+
+  /* Create the handle. */
+  hd = xtrycalloc (1, sizeof *hd);
+  if (!hd)
+    return gpg_error_from_syserror ();
+  hd->req_type = HTTP_REQ_OPAQUE;
+  hd->flags = flags;
+
+  /* Connect.  */
+  sock = connect_server (server, port, hd->flags, srvtag, &hnf);
+  if (sock == -1)
+    {
+      err = gpg_err_make (default_errsource,
+                          (hnf? GPG_ERR_UNKNOWN_HOST
+                              : gpg_err_code_from_syserror ()));
+      xfree (hd);
+      return err;
+    }
+  hd->sock = my_socket_new (sock);
+  if (!hd->sock)
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      xfree (hd);
+      return err;
+    }
+
+  /* Setup estreams for reading and writing.  */
+  cookie = xtrycalloc (1, sizeof *cookie);
+  if (!cookie)
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      goto leave;
+    }
+  cookie->sock = my_socket_ref (hd->sock);
+  hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
+  if (!hd->fp_write)
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      my_socket_unref (cookie->sock, NULL, NULL);
+      xfree (cookie);
+      goto leave;
+    }
+  hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE.  */
+
+  cookie = xtrycalloc (1, sizeof *cookie);
+  if (!cookie)
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      goto leave;
+    }
+  cookie->sock = my_socket_ref (hd->sock);
+  hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
+  if (!hd->fp_read)
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      my_socket_unref (cookie->sock, NULL, NULL);
+      xfree (cookie);
+      goto leave;
+    }
+  hd->read_cookie = cookie; /* Cookie now owned by FP_READ.  */
 
-  err = http_parse_uri (&hd->uri, url);
+  /* Register close notification to interlock the use of es_fclose in
+     http_close and in user code.  */
+  err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
   if (!err)
-    err = send_request (hd, auth, proxy, srv, headers);
+    err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
 
+ leave:
   if (err)
     {
-      if (!hd->fp_read && !hd->fp_write && hd->sock != -1)
-        sock_close (hd->sock);
       if (hd->fp_read)
-        P_ES(fclose) (hd->fp_read);
+        es_fclose (hd->fp_read);
       if (hd->fp_write)
-        P_ES(fclose) (hd->fp_write);
-      http_release_parsed_uri (hd->uri);
+        es_fclose (hd->fp_write);
+      my_socket_unref (hd->sock, NULL, NULL);
       xfree (hd);
     }
   else
@@ -360,22 +828,19 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
 }
 
 
+
+
 void
 http_start_data (http_t hd)
 {
   if (!hd->in_data)
     {
-#ifdef HTTP_USE_ESTREAM
       es_fputs ("\r\n", hd->fp_write);
       es_fflush (hd->fp_write);
-#else
-      fflush (hd->fp_write);
-      write_server (hd->sock, "\r\n", 2);
-#endif
       hd->in_data = 1;
     }
   else
-    P_ES(fflush) (hd->fp_write);
+    es_fflush (hd->fp_write);
 }
 
 
@@ -383,70 +848,54 @@ gpg_error_t
 http_wait_response (http_t hd)
 {
   gpg_error_t err;
+  cookie_t cookie;
 
   /* Make sure that we are in the data. */
   http_start_data (hd);
 
-  /* We dup the socket, to cope with the fact that fclose closes the
-     underlying socket. In TLS mode we don't do that because we can't
-     close the socket gnutls is working on; instead we make sure that
-     the fclose won't close the socket in this case. */
-#ifdef HTTP_USE_ESTREAM
-  if (hd->write_cookie)
-    {
-      /* The write cookie is only set in the TLS case. */
-      cookie_t cookie = hd->write_cookie;
-      cookie->keep_socket = 1;
-    }
-  else
-#endif /*HTTP_USE_ESTREAM*/
-    {
-#ifdef HAVE_W32_SYSTEM
-      HANDLE handle = (HANDLE)hd->sock;
-      if (!DuplicateHandle (GetCurrentProcess(), handle,
-                           GetCurrentProcess(), &handle, 0,
-                           TRUE, DUPLICATE_SAME_ACCESS ))
-       return gpg_error_from_syserror ();
-      hd->sock = (int)handle;
-#else
-      hd->sock = dup (hd->sock);
-#endif
-      if (hd->sock == -1)
-        return gpg_error_from_syserror ();
-    }
-  P_ES(fclose) (hd->fp_write);
+  /* Close the write stream.  Note that the reference counted socket
+     object keeps the actual system socket open.  */
+  cookie = hd->write_cookie;
+  if (!cookie)
+    return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
+
+  es_fclose (hd->fp_write);
   hd->fp_write = NULL;
-#ifdef HTTP_USE_ESTREAM
+  /* The close has released the cookie and thus we better set it to NULL.  */
   hd->write_cookie = NULL;
-#endif
 
+  /* Shutdown one end of the socket is desired.  As per HTTP/1.0 this
+     is not required but some very old servers (e.g. the original pksd
+     key server didn't worked without it.  */
+  if ((hd->flags & HTTP_FLAG_SHUTDOWN))
+    shutdown (hd->sock->fd, 1);
   hd->in_data = 0;
 
-#ifdef HTTP_USE_ESTREAM
-  {
-    cookie_t cookie;
-
-    cookie = xtrycalloc (1, sizeof *cookie);
-    if (!cookie)
-      return gpg_error_from_syserror ();
-    cookie->fd = hd->sock;
-    if (hd->uri->use_tls)
-      cookie->tls_session = hd->tls_context;
+  /* Create a new cookie and a stream for reading.  */
+  cookie = xtrycalloc (1, sizeof *cookie);
+  if (!cookie)
+    return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+  cookie->sock = my_socket_ref (hd->sock);
+  cookie->session = http_session_ref (hd->session);
+  cookie->use_tls = hd->uri->use_tls;
 
-    hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
-    if (!hd->fp_read)
-      {
-        xfree (cookie);
-        return gpg_error_from_syserror ();
-      }
-  }
-#else /*!HTTP_USE_ESTREAM*/
-  hd->fp_read = fdopen (hd->sock, "r");
+  hd->read_cookie = cookie;
+  hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
   if (!hd->fp_read)
-    return gpg_error_from_syserror ();
-#endif /*!HTTP_USE_ESTREAM*/
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      my_socket_unref (cookie->sock, NULL, NULL);
+      http_session_unref (cookie->session);
+      xfree (cookie);
+      hd->read_cookie = NULL;
+      return err;
+    }
 
   err = parse_response (hd);
+
+  if (!err)
+    err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
+
   return err;
 }
 
@@ -458,13 +907,13 @@ http_wait_response (http_t hd)
 gpg_error_t
 http_open_document (http_t *r_hd, const char *document,
                     const char *auth, unsigned int flags, const char *proxy,
-                    void *tls_context, struct http_srv *srv,
-                   strlist_t headers)
+                    http_session_t session,
+                    const char *srvtag, strlist_t headers)
 {
   gpg_error_t err;
 
-  err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags,
-                   proxy, tls_context, srv, headers);
+  err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
+                   proxy, session, srvtag, headers);
   if (err)
     return err;
 
@@ -481,12 +930,20 @@ http_close (http_t hd, int keep_read_stream)
 {
   if (!hd)
     return;
-  if (!hd->fp_read && !hd->fp_write && hd->sock != -1)
-    sock_close (hd->sock);
+
+  /* First remove the close notifications for the streams.  */
+  if (hd->fp_read)
+    es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
+  if (hd->fp_write)
+    es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
+
+  /* Now we can close the streams.  */
+  my_socket_unref (hd->sock, NULL, NULL);
   if (hd->fp_read && !keep_read_stream)
-    P_ES(fclose) (hd->fp_read);
+    es_fclose (hd->fp_read);
   if (hd->fp_write)
-    P_ES(fclose) (hd->fp_write);
+    es_fclose (hd->fp_write);
+  http_session_unref (hd->session);
   http_release_parsed_uri (hd->uri);
   while (hd->headers)
     {
@@ -500,50 +957,78 @@ http_close (http_t hd, int keep_read_stream)
 }
 
 
-#ifdef HTTP_USE_ESTREAM
 estream_t
 http_get_read_ptr (http_t hd)
 {
   return hd?hd->fp_read:NULL;
 }
+
 estream_t
 http_get_write_ptr (http_t hd)
 {
   return hd?hd->fp_write:NULL;
 }
-#else /*!HTTP_USE_ESTREAM*/
-FILE *
-http_get_read_ptr (http_t hd)
-{
-  return hd?hd->fp_read:NULL;
-}
-FILE *
-http_get_write_ptr (http_t hd)
-{
-  return hd?hd->fp_write:NULL;
-}
-#endif /*!HTTP_USE_ESTREAM*/
+
 unsigned int
 http_get_status_code (http_t hd)
 {
   return hd?hd->status_code:0;
 }
 
+/* Return information pertaining to TLS.  If TLS is not in use for HD,
+   NULL is returned.  WHAT is used ask for specific information:
+
+     (NULL) := Only check whether TLS is is use.  Returns an
+               unspecified string if TLS is in use.  That string may
+               even be the empty string.
+ */
+const char *
+http_get_tls_info (http_t hd, const char *what)
+{
+  (void)what;
+
+  if (!hd)
+    return NULL;
+
+  return hd->uri->use_tls? "":NULL;
+}
+
 
 \f
+static gpg_error_t
+parse_uri (parsed_uri_t *ret_uri, const char *uri,
+           int no_scheme_check, int force_tls)
+{
+  gpg_err_code_t ec;
+
+  *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
+  if (!*ret_uri)
+    return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+  strcpy ((*ret_uri)->buffer, uri);
+  ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
+  if (ec)
+    {
+      xfree (*ret_uri);
+      *ret_uri = NULL;
+    }
+  return gpg_err_make (default_errsource, ec);
+}
+
+
 /*
  * Parse an URI and put the result into the newly allocated RET_URI.
- * The caller must always use release_parsed_uri() to releases the
- * resources (even on error).
+ * On success the caller must use release_parsed_uri() to releases the
+ * resources.  If NO_SCHEME_CHECK is set, the function tries to parse
+ * the URL in the same way it would do for an HTTP style URI.
  */
 gpg_error_t
-http_parse_uri (parsed_uri_t * ret_uri, const char *uri)
+http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
+                int no_scheme_check)
 {
-  *ret_uri = xcalloc (1, sizeof **ret_uri + strlen (uri));
-  strcpy ((*ret_uri)->buffer, uri);
-  return do_parse_uri (*ret_uri, 0);
+  return parse_uri (ret_uri, uri, no_scheme_check, 0);
 }
 
+
 void
 http_release_parsed_uri (parsed_uri_t uri)
 {
@@ -561,8 +1046,9 @@ http_release_parsed_uri (parsed_uri_t uri)
 }
 
 
-static gpg_error_t
-do_parse_uri (parsed_uri_t uri, int only_local_part)
+static gpg_err_code_t
+do_parse_uri (parsed_uri_t uri, int only_local_part,
+              int no_scheme_check, int force_tls)
 {
   uri_tuple_t *tail;
   char *p, *p2, *p3, *pp;
@@ -576,42 +1062,51 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
   uri->port = 0;
   uri->params = uri->query = NULL;
   uri->use_tls = 0;
+  uri->is_http = 0;
+  uri->opaque = 0;
+  uri->v6lit = 0;
 
   /* A quick validity check. */
   if (strspn (p, VALID_URI_CHARS) != n)
-    return gpg_error (GPG_ERR_BAD_URI);        /* Invalid characters found. */
+    return GPG_ERR_BAD_URI;    /* Invalid characters found. */
 
   if (!only_local_part)
     {
       /* Find the scheme. */
       if (!(p2 = strchr (p, ':')) || p2 == p)
-       return gpg_error (GPG_ERR_BAD_URI); /* No scheme. */
+       return GPG_ERR_BAD_URI; /* No scheme. */
       *p2++ = 0;
       for (pp=p; *pp; pp++)
        *pp = tolower (*(unsigned char*)pp);
       uri->scheme = p;
-      if (!strcmp (uri->scheme, "http"))
-        uri->port = 80;
-#ifdef HTTP_USE_GNUTLS
-      else if (!strcmp (uri->scheme, "https"))
+      if (!strcmp (uri->scheme, "http") && !force_tls)
+        {
+          uri->port = 80;
+          uri->is_http = 1;
+        }
+      else if (!strcmp (uri->scheme, "hkp") && !force_tls)
+        {
+          uri->port = 11371;
+          uri->is_http = 1;
+        }
+#ifdef USE_TLS
+      else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
+               || (force_tls && (!strcmp (uri->scheme, "http")
+                                 || !strcmp (uri->scheme,"hkp"))))
         {
           uri->port = 443;
+          uri->is_http = 1;
           uri->use_tls = 1;
         }
-#endif
-      else
-       return gpg_error (GPG_ERR_INV_URI); /* Unsupported scheme */
+#endif /*USE_TLS*/
+      else if (!no_scheme_check)
+       return GPG_ERR_INV_URI; /* Unsupported scheme */
 
       p = p2;
 
-      /* Find the hostname */
-      if (*p != '/')
-       return gpg_error (GPG_ERR_INV_URI); /* Does not start with a slash. */
-
-      p++;
-      if (*p == '/') /* There seems to be a hostname. */
+      if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
        {
-         p++;
+          p += 2;
          if ((p2 = strchr (p, '/')))
            *p2++ = 0;
 
@@ -632,6 +1127,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
              *p3++ = '\0';
              /* worst case, uri->host should have length 0, points to \0 */
              uri->host = p + 1;
+              uri->v6lit = 1;
              p = p3;
            }
          else
@@ -644,11 +1140,20 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
            }
 
          if ((n = remove_escapes (uri->host)) < 0)
-           return gpg_error (GPG_ERR_BAD_URI);
+           return GPG_ERR_BAD_URI;
          if (n != strlen (uri->host))
-           return gpg_error (GPG_ERR_BAD_URI); /* Hostname incudes a Nul. */
+           return GPG_ERR_BAD_URI;     /* Hostname incudes a Nul. */
          p = p2 ? p2 : NULL;
        }
+      else if (uri->is_http)
+       return GPG_ERR_INV_URI; /* No Leading double slash for HTTP.  */
+      else
+        {
+          uri->opaque = 1;
+          uri->path = p;
+          return 0;
+        }
+
     } /* End global URI part. */
 
   /* Parse the pathname part */
@@ -663,9 +1168,9 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
 
   uri->path = p;
   if ((n = remove_escapes (p)) < 0)
-    return gpg_error (GPG_ERR_BAD_URI);
+    return GPG_ERR_BAD_URI;
   if (n != strlen (p))
-    return gpg_error (GPG_ERR_BAD_URI);        /* Path includes a Nul. */
+    return GPG_ERR_BAD_URI;    /* Path includes a Nul. */
   p = p2 ? p2 : NULL;
 
   if (!p || !*p)
@@ -680,7 +1185,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part)
       if ((p2 = strchr (p, '&')))
        *p2++ = 0;
       if (!(elem = parse_tuple (p)))
-       return gpg_error (GPG_ERR_BAD_URI);
+       return GPG_ERR_BAD_URI;
       *tail = elem;
       tail = &elem->next;
 
@@ -742,16 +1247,41 @@ remove_escapes (char *string)
 }
 
 
-static int
-insert_escapes (char *buffer, const char *string,
-               const char *special)
+/* If SPECIAL is NULL this function escapes in forms mode.  */
+static size_t
+escape_data (char *buffer, const void *data, size_t datalen,
+             const char *special)
 {
-  const unsigned char *s = (const unsigned char*)string;
-  int n = 0;
+  int forms = !special;
+  const unsigned char *s;
+  size_t n = 0;
 
-  for (; *s; s++)
+  if (forms)
+    special = "%;?&=";
+
+  for (s = data; datalen; s++, datalen--)
     {
-      if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
+      if (forms && *s == ' ')
+        {
+         if (buffer)
+           *buffer++ = '+';
+         n++;
+        }
+      else if (forms && *s == '\n')
+        {
+         if (buffer)
+           memcpy (buffer, "%0D%0A", 6);
+         n += 6;
+        }
+      else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
+        {
+         if (buffer)
+           memcpy (buffer, "%0D%0A", 6);
+         n += 6;
+          s++;
+          datalen--;
+        }
+      else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
        {
          if (buffer)
            *(unsigned char*)buffer++ = *s;
@@ -761,7 +1291,7 @@ insert_escapes (char *buffer, const char *string,
        {
          if (buffer)
            {
-             sprintf (buffer, "%%%02X", *s);
+             snprintf (buffer, 4, "%%%02X", *s);
              buffer += 3;
            }
          n += 3;
@@ -771,11 +1301,20 @@ insert_escapes (char *buffer, const char *string,
 }
 
 
+static int
+insert_escapes (char *buffer, const char *string,
+               const char *special)
+{
+  return escape_data (buffer, string, strlen (string), special);
+}
+
+
 /* Allocate a new string from STRING using standard HTTP escaping as
    well as escaping of characters given in SPECIALS.  A common pattern
    for SPECIALS is "%;?&=". However it depends on the needs, for
    example "+" and "/: often needs to be escaped too.  Returns NULL on
-   failure and sets ERRNO. */
+   failure and sets ERRNO.  If SPECIAL is NULL a dedicated forms
+   encoding mode is used. */
 char *
 http_escape_string (const char *string, const char *specials)
 {
@@ -792,6 +1331,27 @@ http_escape_string (const char *string, const char *specials)
   return buf;
 }
 
+/* Allocate a new string from {DATA,DATALEN} using standard HTTP
+   escaping as well as escaping of characters given in SPECIALS.  A
+   common pattern for SPECIALS is "%;?&=".  However it depends on the
+   needs, for example "+" and "/: often needs to be escaped too.
+   Returns NULL on failure and sets ERRNO.  If SPECIAL is NULL a
+   dedicated forms encoding mode is used. */
+char *
+http_escape_data (const void *data, size_t datalen, const char *specials)
+{
+  int n;
+  char *buf;
+
+  n = escape_data (NULL, data, datalen, specials);
+  buf = xtrymalloc (n+1);
+  if (buf)
+    {
+      escape_data (buf, data, datalen, specials);
+      buf[n] = 0;
+    }
+  return buf;
+}
 
 
 static uri_tuple_t
@@ -837,10 +1397,9 @@ parse_tuple (char *string)
  * Returns 0 if the request was successful
  */
 static gpg_error_t
-send_request (http_t hd, const char *auth,
-             const char *proxy, struct http_srv *srv, strlist_t headers)
+send_request (http_t hd, const char *httphost, const char *auth,
+             const char *proxy, const char *srvtag, strlist_t headers)
 {
-  gnutls_session_t tls_session;
   gpg_error_t err;
   const char *server;
   char *request, *p;
@@ -848,36 +1407,76 @@ send_request (http_t hd, const char *auth,
   const char *http_proxy = NULL;
   char *proxy_authstr = NULL;
   char *authstr = NULL;
-  int save_errno;
+  int sock;
+  int hnf;
 
-  tls_session = hd->tls_context;
-  if (hd->uri->use_tls && !tls_session)
+  if (hd->uri->use_tls && !hd->session)
+    {
+      log_error ("TLS requested but no session object provided\n");
+      return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
+    }
+#ifdef USE_TLS
+  if (hd->uri->use_tls && !hd->session->tls_session)
     {
-      log_error ("TLS requested but no GNUTLS context provided\n");
-      return gpg_error (GPG_ERR_INTERNAL);
+      log_error ("TLS requested but no GNUTLS context available\n");
+      return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
     }
+#endif /*USE_TLS*/
 
   server = *hd->uri->host ? hd->uri->host : "localhost";
   port = hd->uri->port ? hd->uri->port : 80;
 
+  /* Try to use SNI.  */
+#ifdef USE_TLS
+  if (hd->uri->use_tls)
+    {
+# if HTTP_USE_GNUTLS
+      int rc;
+# endif
+
+      xfree (hd->session->servername);
+      hd->session->servername = xtrystrdup (httphost? httphost : server);
+      if (!hd->session->servername)
+        {
+          err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+          return err;
+        }
+
+# if HTTP_USE_NTBTLS
+      err = ntbtls_set_hostname (hd->session->tls_session, server);
+      if (err)
+        {
+          log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
+          return err;
+        }
+# elif HTTP_USE_GNUTLS
+      rc = gnutls_server_name_set (hd->session->tls_session,
+                                   GNUTLS_NAME_DNS,
+                                   server, strlen (server));
+      if (rc < 0)
+        log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
+# endif /*HTTP_USE_GNUTLS*/
+    }
+#endif /*USE_TLS*/
+
   if ( (proxy && *proxy)
        || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
             && (http_proxy = getenv (HTTP_PROXY_ENV))
             && *http_proxy ))
     {
       parsed_uri_t uri;
+      int save_errno;
 
       if (proxy)
        http_proxy = proxy;
 
-      err = http_parse_uri (&uri, http_proxy);
+      err = parse_uri (&uri, http_proxy, 0,
+                       !!(hd->flags & HTTP_FLAG_FORCE_TLS));
       if (err)
        {
          log_error ("invalid HTTP proxy (%s): %s\n",
                     http_proxy, gpg_strerror (err));
-         http_release_parsed_uri (uri);
-         return gpg_error (GPG_ERR_CONFIGURATION);
-
+         return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
        }
 
       if (uri->auth)
@@ -888,60 +1487,109 @@ send_request (http_t hd, const char *auth,
                                             uri->auth, strlen(uri->auth));
           if (!proxy_authstr)
             {
-              err = gpg_error_from_syserror ();
+              err = gpg_err_make (default_errsource,
+                                  gpg_err_code_from_syserror ());
               http_release_parsed_uri (uri);
               return err;
             }
         }
 
-      hd->sock = connect_server (*uri->host ? uri->host : "localhost",
-                                uri->port ? uri->port : 80,
-                                 hd->flags, srv);
+      sock = connect_server (*uri->host ? uri->host : "localhost",
+                             uri->port ? uri->port : 80,
+                             hd->flags, srvtag, &hnf);
       save_errno = errno;
       http_release_parsed_uri (uri);
+      if (sock == -1)
+        gpg_err_set_errno (save_errno);
     }
   else
     {
-      hd->sock = connect_server (server, port, hd->flags, srv);
-      save_errno = errno;
+      sock = connect_server (server, port, hd->flags, srvtag, &hnf);
     }
 
-  if (hd->sock == -1)
+  if (sock == -1)
+    {
+      xfree (proxy_authstr);
+      return gpg_err_make (default_errsource,
+                           (hnf? GPG_ERR_UNKNOWN_HOST
+                               : gpg_err_code_from_syserror ()));
+    }
+  hd->sock = my_socket_new (sock);
+  if (!hd->sock)
     {
       xfree (proxy_authstr);
-      return (save_errno
-              ? gpg_error_from_errno (save_errno)
-              : gpg_error (GPG_ERR_NOT_FOUND));
+      return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
     }
 
-#ifdef HTTP_USE_GNUTLS
+
+
+#if HTTP_USE_NTBTLS
+  if (hd->uri->use_tls)
+    {
+      my_socket_ref (hd->sock);
+
+      while ((err = ntbtls_handshake (hd->session->tls_session)))
+        {
+          switch (err)
+            {
+            default:
+              log_info ("TLS handshake failed: %s <%s>\n",
+                        gpg_strerror (err), gpg_strsource (err));
+              xfree (proxy_authstr);
+              return err;
+            }
+        }
+
+      hd->session->verify.done = 0;
+      if (tls_callback)
+        err = tls_callback (hd, hd->session, 0);
+      else
+        err = http_verify_server_credentials (hd->session);
+      if (err)
+        {
+          log_info ("TLS connection authentication failed: %s <%s>\n",
+                    gpg_strerror (err), gpg_strsource (err));
+          xfree (proxy_authstr);
+          return err;
+        }
+    }
+#elif HTTP_USE_GNUTLS
   if (hd->uri->use_tls)
     {
       int rc;
 
-      gnutls_transport_set_ptr (tls_session, (gnutls_transport_ptr_t)hd->sock);
+      my_socket_ref (hd->sock);
+      gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
+#ifdef USE_NPTH
+      gnutls_transport_set_pull_function (hd->session->tls_session,
+                                          my_npth_read);
+      gnutls_transport_set_push_function (hd->session->tls_session,
+                                          my_npth_write);
+#endif
+
       do
         {
-          rc = gnutls_handshake (tls_session);
+          rc = gnutls_handshake (hd->session->tls_session);
         }
       while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
       if (rc < 0)
         {
           log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
           xfree (proxy_authstr);
-          return gpg_error (GPG_ERR_NETWORK);
+          return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
         }
 
+      hd->session->verify.done = 0;
       if (tls_callback)
+        err = tls_callback (hd, hd->session, 0);
+      else
+        err = http_verify_server_credentials (hd->session);
+      if (err)
         {
-          err = tls_callback (hd, tls_session, 0);
-          if (err)
-            {
-              log_info ("TLS connection authentication failed: %s\n",
-                        gpg_strerror (err));
-              xfree (proxy_authstr);
-              return err;
-            }
+          log_info ("TLS connection authentication failed: %s\n",
+                    gpg_strerror (err));
+          xfree (proxy_authstr);
+          return err;
         }
     }
 #endif /*HTTP_USE_GNUTLS*/
@@ -956,7 +1604,7 @@ send_request (http_t hd, const char *auth,
           if (!myauth)
             {
               xfree (proxy_authstr);
-              return gpg_error_from_syserror ();
+              return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
             }
           remove_escapes (myauth);
         }
@@ -966,7 +1614,7 @@ send_request (http_t hd, const char *auth,
           myauth = hd->uri->auth;
         }
 
-      authstr = make_header_line ("Authorization: Basic %s", "\r\n",
+      authstr = make_header_line ("Authorization: Basic ", "\r\n",
                                   myauth, strlen (myauth));
       if (auth)
         xfree (myauth);
@@ -974,58 +1622,58 @@ send_request (http_t hd, const char *auth,
       if (!authstr)
         {
           xfree (proxy_authstr);
-          return gpg_error_from_syserror ();
+          return gpg_err_make (default_errsource,
+                               gpg_err_code_from_syserror ());
         }
     }
 
   p = build_rel_path (hd->uri);
   if (!p)
-    return gpg_error_from_syserror ();
-
-  request = xtrymalloc (2 * strlen (server)
-                        + strlen (p)
-                        + (authstr?strlen(authstr):0)
-                        + (proxy_authstr?strlen(proxy_authstr):0)
-                        + 100);
-  if (!request)
-    {
-      err = gpg_error_from_syserror ();
-      xfree (p);
-      xfree (authstr);
-      xfree (proxy_authstr);
-      return err;
-    }
+    return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
 
   if (http_proxy && *http_proxy)
     {
-      sprintf (request, "%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s",
-              hd->req_type == HTTP_REQ_GET ? "GET" :
-              hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
-              hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
-              server, port, *p == '/' ? "" : "/", p,
-              authstr ? authstr : "",
-               proxy_authstr ? proxy_authstr : "");
+      request = es_bsprintf
+        ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
+         hd->req_type == HTTP_REQ_GET ? "GET" :
+         hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
+         hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
+         hd->uri->use_tls? "https" : "http",
+         httphost? httphost : server,
+         port, *p == '/' ? "" : "/", p,
+         authstr ? authstr : "",
+         proxy_authstr ? proxy_authstr : "");
     }
   else
     {
       char portstr[35];
 
-      if (port == 80 || (srv && srv->used_server))
+      if (port == 80)
         *portstr = 0;
       else
-        sprintf (portstr, ":%u", port);
-
-      sprintf (request, "%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
-              hd->req_type == HTTP_REQ_GET ? "GET" :
-              hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
-              hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
-              *p == '/' ? "" : "/", p, server, portstr,
-               authstr? authstr:"");
+        snprintf (portstr, sizeof portstr, ":%u", port);
+
+      request = es_bsprintf
+        ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
+         hd->req_type == HTTP_REQ_GET ? "GET" :
+         hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
+         hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
+         *p == '/' ? "" : "/", p,
+         httphost? httphost : server,
+         portstr,
+         authstr? authstr:"");
     }
   xfree (p);
+  if (!request)
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      xfree (authstr);
+      xfree (proxy_authstr);
+      return err;
+    }
 
+  /* log_debug ("request:\n%s\nEND request\n", request); */
 
-#ifdef HTTP_USE_ESTREAM
   /* First setup estream so that we can write even the first line
      using estream.  This is also required for the sake of gnutls. */
   {
@@ -1034,68 +1682,44 @@ send_request (http_t hd, const char *auth,
     cookie = xtrycalloc (1, sizeof *cookie);
     if (!cookie)
       {
-        err = gpg_error_from_syserror ();
+        err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
         goto leave;
       }
-    cookie->fd = hd->sock;
-    if (hd->uri->use_tls)
-      {
-        cookie->tls_session = tls_session;
-        hd->write_cookie = cookie;
-      }
+    cookie->sock = my_socket_ref (hd->sock);
+    hd->write_cookie = cookie;
+    cookie->use_tls = hd->uri->use_tls;
+    cookie->session = http_session_ref (hd->session);
 
     hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
     if (!hd->fp_write)
       {
+        err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+        my_socket_unref (cookie->sock, NULL, NULL);
         xfree (cookie);
-        err = gpg_error_from_syserror ();
+        hd->write_cookie = NULL;
       }
     else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
-      err = gpg_error_from_syserror ();
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
     else
       err = 0;
 
-  if(err==0)
-    for(;headers;headers=headers->next)
-      {
-       if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
-           || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
-         {
-           err = gpg_error_from_syserror ();
-           break;
-         }
-      }
-  }
-
- leave:
-
-#else /*!HTTP_USE_ESTREAM*/
-  /* We send out the start of the request through our own send
-     function and only then assign a stdio stream.  This allows for
-     better error reporting that through standard stdio means. */
-  err = write_server (hd->sock, request, strlen (request));
-
-  if(err==0)
-    for(;headers;headers=headers->next)
-      {
-       err = write_server( hd->sock, headers->d, strlen(headers->d) );
-       if(err)
-         break;
-       err = write_server( hd->sock, "\r\n", 2 );
-       if(err)
-         break;
-      }
-
   if (!err)
     {
-      hd->fp_write = fdopen (hd->sock, "w");
-      if (!hd->fp_write)
-        err = gpg_error_from_syserror ();
+      for (;headers; headers=headers->next)
+        {
+          if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
+              || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
+            {
+              err = gpg_err_make (default_errsource,
+                                  gpg_err_code_from_syserror ());
+              break;
+            }
+        }
     }
+  }
 
-#endif /*!HTTP_USE_ESTREAM*/
-
-  xfree (request);
+ leave:
+  es_free (request);
   xfree (authstr);
   xfree (proxy_authstr);
 
@@ -1155,97 +1779,6 @@ build_rel_path (parsed_uri_t uri)
 }
 
 
-
-/*
-   Same as fgets() but if the buffer is too short a larger one will be
-   allocated up to some limit *MAX_LENGTH.  A line is considered a
-   byte stream ending in a LF.  Returns the length of the line. EOF is
-   indicated by a line of length zero. The last LF may be missing due
-   to an EOF.  If MAX_LENGTH is zero on return, the line has been
-   truncated.  If the returned buffer is NULL, not enough memory was
-   enable to increase it, the return value will also be 0 and some
-   bytes might have been lost which should be no problem becuase
-   out-of-memory is pretty fatal for most applications.
-
-   If a line has been truncated, the file pointer is internally moved
-   forward to the end of the line.
-
-   Note: The returned buffer is allocated with enough extra space to
-   append a CR,LF,Nul
- */
-static size_t
-my_read_line (
-#ifdef HTTP_USE_ESTREAM
-              estream_t fp,
-#else
-              FILE *fp,
-#endif
-              char **addr_of_buffer,
-              size_t *length_of_buffer, size_t *max_length)
-{
-  int c;
-  char *buffer = *addr_of_buffer;
-  size_t length = *length_of_buffer;
-  size_t nbytes = 0;
-  size_t maxlen = *max_length;
-  char *p;
-
-  if (!buffer) /* Must allocate a new buffer. */
-    {
-      length = 256;
-      buffer = xtrymalloc (length);
-      *addr_of_buffer = buffer;
-      if (!buffer)
-       {
-         *length_of_buffer = *max_length = 0;
-         return 0;
-       }
-      *length_of_buffer = length;
-    }
-
-  length -= 3; /* Reserve 3 bytes (cr,lf,eol). */
-  p = buffer;
-  while ((c = P_ES(getc) (fp)) != EOF)
-    {
-      if (nbytes == length) /* Increase the buffer. */
-       {
-         if (length > maxlen) /* Limit reached. */
-           {
-             /* Skip the rest of the line. */
-             while (c != '\n' && (c = P_ES(getc) (fp)) != EOF)
-               ;
-             *p++ = '\n'; /* Always append a LF (we reserved some space). */
-             nbytes++;
-             *max_length = 0; /* Indicate truncation */
-             break; /*(the while loop)*/
-           }
-         length += 3; /* Adjust for the reserved bytes. */
-         length += length < 1024 ? 256 : 1024;
-         *addr_of_buffer = xtryrealloc (buffer, length);
-         if (!*addr_of_buffer)
-           {
-             int save_errno = errno;
-             xfree (buffer);
-             *length_of_buffer = *max_length = 0;
-             errno = save_errno;
-             return 0;
-           }
-         buffer = *addr_of_buffer;
-         *length_of_buffer = length;
-         length -= 3; /* And re-adjust for the reservation. */
-         p = buffer + nbytes;
-       }
-      *p++ = c;
-      nbytes++;
-      if (c == '\n')
-       break;
-    }
-  *p = 0; /* Make sure the line is a string. */
-
-  return nbytes;
-}
-
-
 /* Transform a header name into a standard capitalized format; e.g.
    "Content-Type".  Conversion stops at the colon.  As usual we don't
    use the localized versions of ctype.h. */
@@ -1273,7 +1806,7 @@ capitalize_header_name (char *name)
 /* Store an HTTP header line in LINE away.  Line continuation is
    supported as well as merging of headers with the same name. This
    function may modify LINE. */
-static gpg_error_t
+static gpg_err_code_t
 store_header (http_t hd, char *line)
 {
   size_t n;
@@ -1288,17 +1821,17 @@ store_header (http_t hd, char *line)
         line[--n] = 0;
     }
   if (!n)  /* we are never called to hit this. */
-    return gpg_error (GPG_ERR_BUG);
+    return GPG_ERR_BUG;
   if (*line == ' ' || *line == '\t')
     {
       /* Continuation. This won't happen too often as it is not
          recommended.  We use a straightforward implementaion. */
       if (!hd->headers)
-        return gpg_error (GPG_ERR_PROTOCOL_VIOLATION);
+        return GPG_ERR_PROTOCOL_VIOLATION;
       n += strlen (hd->headers->value);
       p = xtrymalloc (n+1);
       if (!p)
-        return gpg_error_from_syserror ();
+        return gpg_err_code_from_syserror ();
       strcpy (stpcpy (p, hd->headers->value), line);
       xfree (hd->headers->value);
       hd->headers->value = p;
@@ -1308,7 +1841,7 @@ store_header (http_t hd, char *line)
   capitalize_header_name (line);
   p = strchr (line, ':');
   if (!p)
-    return gpg_error (GPG_ERR_PROTOCOL_VIOLATION);
+    return GPG_ERR_PROTOCOL_VIOLATION;
   *p++ = 0;
   while (*p == ' ' || *p == '\t')
     p++;
@@ -1323,7 +1856,7 @@ store_header (http_t hd, char *line)
          it is a comma separated list and merge them.  */
       p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
       if (!p)
-        return gpg_error_from_syserror ();
+        return gpg_err_code_from_syserror ();
       strcpy (stpcpy (stpcpy (p, h->value), ","), value);
       xfree (h->value);
       h->value = p;
@@ -1333,13 +1866,13 @@ store_header (http_t hd, char *line)
   /* Append a new header. */
   h = xtrymalloc (sizeof *h + strlen (line));
   if (!h)
-    return gpg_error_from_syserror ();
+    return gpg_err_code_from_syserror ();
   strcpy (h->name, line);
   h->value = xtrymalloc (strlen (value)+1);
   if (!h->value)
     {
       xfree (h);
-      return gpg_error_from_syserror ();
+      return gpg_err_code_from_syserror ();
     }
   strcpy (h->value, value);
   h->next = hd->headers;
@@ -1350,12 +1883,10 @@ store_header (http_t hd, char *line)
 
 
 /* Return the header NAME from the last response.  The returned value
-   is valid as along as HD has not been closed and no othe request has
-   been send. If the header was not found, NULL is returned.  Name
+   is valid as along as HD has not been closed and no other request
+   has been send. If the header was not found, NULL is returned.  NAME
    must be canonicalized, that is the first letter of each dash
-   delimited part must be uppercase and all other letters lowercase.
-   Note that the context must have been opened with the
-   HTTP_FLAG_NEED_HEADER. */
+   delimited part must be uppercase and all other letters lowercase.  */
 const char *
 http_get_header (http_t hd, const char *name)
 {
@@ -1368,16 +1899,41 @@ http_get_header (http_t hd, const char *name)
 }
 
 
+/* Return a newly allocated and NULL terminated array with pointers to
+   header names.  The array must be released with xfree() and its
+   content is only values as long as no other request has been
+   send.  */
+const char **
+http_get_header_names (http_t hd)
+{
+  const char **array;
+  size_t n;
+  header_t h;
+
+  for (n=0, h = hd->headers; h; h = h->next)
+    n++;
+  array = xtrycalloc (n+1, sizeof *array);
+  if (array)
+    {
+      for (n=0, h = hd->headers; h; h = h->next)
+        array[n++] = h->name;
+    }
+
+  return array;
+}
+
 
 /*
  * Parse the response from a server.
  * Returns: Errorcode and sets some files in the handle
  */
-static gpg_error_t
+static gpg_err_code_t
 parse_response (http_t hd)
 {
   char *line, *p, *p2;
   size_t maxlen, len;
+  cookie_t cookie = hd->read_cookie;
+  const char *s;
 
   /* Delete old header lines.  */
   while (hd->headers)
@@ -1392,16 +1948,17 @@ parse_response (http_t hd)
   do
     {
       maxlen = MAX_LINELEN;
-      len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
+      len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
       line = hd->buffer;
       if (!line)
-       return gpg_error_from_syserror (); /* Out of core. */
+       return gpg_err_code_from_syserror (); /* Out of core. */
       if (!maxlen)
-       return gpg_error (GPG_ERR_TRUNCATED); /* Line has been truncated. */
+       return GPG_ERR_TRUNCATED; /* Line has been truncated. */
       if (!len)
-       return gpg_error (GPG_ERR_EOF);
-      if ( (hd->flags & HTTP_FLAG_LOG_RESP) )
-        log_info ("RESP: `%.*s'\n",
+       return GPG_ERR_EOF;
+
+      if ((hd->flags & HTTP_FLAG_LOG_RESP))
+        log_info ("RESP: '%.*s'\n",
                   (int)strlen(line)-(*line&&line[1]?2:0),line);
     }
   while (!*line);
@@ -1436,28 +1993,39 @@ parse_response (http_t hd)
   do
     {
       maxlen = MAX_LINELEN;
-      len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
+      len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
       line = hd->buffer;
       if (!line)
-       return gpg_error_from_syserror (); /* Out of core. */
+       return gpg_err_code_from_syserror (); /* Out of core. */
       /* Note, that we can silently ignore truncated lines. */
       if (!len)
-       return gpg_error (GPG_ERR_EOF);
+       return GPG_ERR_EOF;
       /* Trim line endings of empty lines. */
       if ((*line == '\r' && line[1] == '\n') || *line == '\n')
        *line = 0;
-      if ( (hd->flags & HTTP_FLAG_LOG_RESP) )
-        log_info ("RESP: `%.*s'\n",
+      if ((hd->flags & HTTP_FLAG_LOG_RESP))
+        log_info ("RESP: '%.*s'\n",
                   (int)strlen(line)-(*line&&line[1]?2:0),line);
-      if ( (hd->flags & HTTP_FLAG_NEED_HEADER) && *line )
+      if (*line)
         {
-          gpg_error_t err = store_header (hd, line);
-          if (err)
-            return err;
+          gpg_err_code_t ec = store_header (hd, line);
+          if (ec)
+            return ec;
         }
     }
   while (len && *line);
 
+  cookie->content_length_valid = 0;
+  if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
+    {
+      s = http_get_header (hd, "Content-Length");
+      if (s)
+        {
+          cookie->content_length_valid = 1;
+          cookie->content_length = counter_strtoul (s);
+        }
+    }
+
   return 0;
 }
 
@@ -1504,14 +2072,14 @@ start_server ()
       FD_ZERO (&rfds);
       FD_SET (fd, &rfds);
 
-      if (select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
+      if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
        continue;               /* ignore any errors */
 
       if (!FD_ISSET (fd, &rfds))
        continue;
 
       addrlen = sizeof peer;
-      client = accept (fd, (struct sockaddr *) &peer, &addrlen);
+      client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
       if (client == -1)
        continue;               /* oops */
 
@@ -1542,22 +2110,20 @@ start_server ()
    error.  ERRNO is set on error. */
 static int
 connect_server (const char *server, unsigned short port,
-                unsigned int flags, struct http_srv *srv)
+                unsigned int flags, const char *srvtag, int *r_host_not_found)
 {
   int sock = -1;
   int srvcount = 0;
-  int fakesrv = 0;
   int hostfound = 0;
-  int srvindex, connected;
-  int chosen = -1;
+  int srv, connected;
   int last_errno = 0;
   struct srventry *serverlist = NULL;
-
-  /* Not currently using the flags */
-  (void)flags;
-
 #ifdef HAVE_W32_SYSTEM
   unsigned long inaddr;
+#endif
+
+  *r_host_not_found = 0;
+#ifdef HAVE_W32_SYSTEM
 
 #ifndef HTTP_NO_WSASTARTUP
   init_sockets ();
@@ -1582,7 +2148,7 @@ connect_server (const char *server, unsigned short port,
       addr.sin_port = htons(port);
       memcpy (&addr.sin_addr,&inaddr,sizeof(inaddr));
 
-      if (!connect (sock,(struct sockaddr *)&addr,sizeof(addr)) )
+      if (!my_connect (sock,(struct sockaddr *)&addr,sizeof(addr)) )
        return sock;
       sock_close(sock);
       return -1;
@@ -1591,18 +2157,21 @@ connect_server (const char *server, unsigned short port,
 
 #ifdef USE_DNS_SRV
   /* Do the SRV thing */
-  if (srv && srv->srvtag)
+  if (srvtag)
     {
       /* We're using SRV, so append the tags. */
-      if (1+strlen (srv->srvtag) + 6 + strlen (server) + 1 <= MAXDNAME)
+      if (1+strlen (srvtag) + 6 + strlen (server) + 1 <= MAXDNAME)
        {
          char srvname[MAXDNAME];
 
-         stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srv->srvtag),
+         stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
                            "._tcp."), server);
          srvcount = getsrv (srvname, &serverlist);
        }
     }
+#else
+  (void)flags;
+  (void)srvtag;
 #endif /*USE_DNS_SRV*/
 
   if (!serverlist)
@@ -1616,25 +2185,29 @@ connect_server (const char *server, unsigned short port,
       strncpy (serverlist->target, server, MAXDNAME);
       serverlist->target[MAXDNAME-1] = '\0';
       srvcount = 1;
-      fakesrv = 1;
     }
 
 #ifdef HAVE_GETADDRINFO
   connected = 0;
-  for (srvindex=0; srvindex < srvcount && !connected; srvindex++)
+  for (srv=0; srv < srvcount && !connected; srv++)
     {
       struct addrinfo hints, *res, *ai;
       char portstr[35];
 
-      sprintf (portstr, "%hu", serverlist[srvindex].port);
+      snprintf (portstr, sizeof portstr, "%hu", port);
       memset (&hints, 0, sizeof (hints));
       hints.ai_socktype = SOCK_STREAM;
-      if (getaddrinfo (serverlist[srvindex].target, portstr, &hints, &res))
+      if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res))
         continue; /* Not found - try next one. */
       hostfound = 1;
 
       for (ai = res; ai && !connected; ai = ai->ai_next)
         {
+          if (ai->ai_family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
+            continue;
+          if (ai->ai_family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
+            continue;
+
           if (sock != -1)
             sock_close (sock);
           sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
@@ -1648,19 +2221,16 @@ connect_server (const char *server, unsigned short port,
               return -1;
             }
 
-          if (connect (sock, ai->ai_addr, ai->ai_addrlen))
+          if (my_connect (sock, ai->ai_addr, ai->ai_addrlen))
             last_errno = errno;
           else
-            {
-             connected = 1;
-             chosen = srvindex;
-           }
+            connected = 1;
         }
       freeaddrinfo (res);
     }
 #else /* !HAVE_GETADDRINFO */
   connected = 0;
-  for (srvindex=0; srvindex < srvcount && !connected; srvindex++)
+  for (srv=0; srv < srvcount && !connected; srv++)
     {
       int i;
       struct hostent *host = NULL;
@@ -1669,7 +2239,7 @@ connect_server (const char *server, unsigned short port,
       /* Note: This code is not thread-safe.  */
 
       memset (&addr, 0, sizeof (addr));
-      host = gethostbyname (serverlist[srvindex].target);
+      host = gethostbyname (serverlist[srv].target);
       if (!host)
         continue;
       hostfound = 1;
@@ -1679,7 +2249,7 @@ connect_server (const char *server, unsigned short port,
       sock = socket (host->h_addrtype, SOCK_STREAM, 0);
       if (sock == -1)
         {
-          log_error (_("error creating socket: %s\n"), strerror (errno));
+          log_error ("error creating socket: %s\n", strerror (errno));
           xfree (serverlist);
           return -1;
         }
@@ -1687,16 +2257,16 @@ connect_server (const char *server, unsigned short port,
       addr.sin_family = host->h_addrtype;
       if (addr.sin_family != AF_INET)
        {
-         log_error ("unknown address family for `%s'\n",
-                     serverlist[srvindex].target);
+         log_error ("unknown address family for '%s'\n",
+                     serverlist[srv].target);
           xfree (serverlist);
          return -1;
        }
-      addr.sin_port = htons (serverlist[srvindex].port);
+      addr.sin_port = htons (serverlist[srv].port);
       if (host->h_length != 4)
         {
-          log_error ("illegal address length for `%s'\n",
-                     serverlist[srvindex].target);
+          log_error ("illegal address length for '%s'\n",
+                     serverlist[srv].target);
           xfree (serverlist);
           return -1;
         }
@@ -1705,41 +2275,36 @@ connect_server (const char *server, unsigned short port,
       for (i = 0; host->h_addr_list[i] && !connected; i++)
         {
           memcpy (&addr.sin_addr, host->h_addr_list[i], host->h_length);
-          if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
+          if (my_connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
             last_errno = errno;
           else
             {
               connected = 1;
-             chosen = srvindex;
               break;
             }
         }
     }
 #endif /* !HAVE_GETADDRINFO */
 
-  if(!fakesrv && chosen >- 1 && srv)
-    {
-      srv->used_server = xstrdup (serverlist[chosen].target);
-      srv->used_port = serverlist[chosen].port;
-    }
-
   xfree (serverlist);
 
   if (!connected)
     {
 #ifdef HAVE_W32_SYSTEM
-      log_error ("can't connect to `%s': %s%sec=%d\n",
+      log_error ("can't connect to '%s': %s%sec=%d\n",
                    server,
-                   hostfound? "":_("host not found"),
+                   hostfound? "":"host not found",
                    hostfound? "":" - ", (int)WSAGetLastError());
 #else
-      log_error ("can't connect to `%s': %s\n",
+      log_error ("can't connect to '%s': %s\n",
                  server,
                  hostfound? strerror (last_errno):"host not found");
 #endif
+      if (!hostfound)
+        *r_host_not_found = 1;
       if (sock != -1)
        sock_close (sock);
-      errno = last_errno;
+      gpg_err_set_errno (last_errno);
       return -1;
     }
   return sock;
@@ -1750,21 +2315,24 @@ static gpg_error_t
 write_server (int sock, const char *data, size_t length)
 {
   int nleft;
+  int nwritten;
 
   nleft = length;
   while (nleft > 0)
     {
-#ifdef HAVE_W32_SYSTEM
-      int nwritten;
-
+#if defined(HAVE_W32_SYSTEM) && !defined(USE_NPTH)
       nwritten = send (sock, data, nleft, 0);
       if ( nwritten == SOCKET_ERROR )
         {
           log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
           return gpg_error (GPG_ERR_NETWORK);
         }
-#else /*!HAVE_W32_SYSTEM*/
-      int nwritten = write (sock, data, nleft);
+#else /*!HAVE_W32_SYSTEM || USE_NPTH*/
+# ifdef USE_NPTH
+      nwritten = npth_write (sock, data, nleft);
+# else
+      nwritten = write (sock, data, nleft);
+# endif
       if (nwritten == -1)
        {
          if (errno == EINTR)
@@ -1775,13 +2343,13 @@ write_server (int sock, const char *data, size_t length)
 
              tv.tv_sec = 0;
              tv.tv_usec = 50000;
-             select (0, NULL, NULL, NULL, &tv);
+             my_select (0, NULL, NULL, NULL, &tv);
              continue;
            }
          log_info ("network write failed: %s\n", strerror (errno));
          return gpg_error_from_syserror ();
        }
-#endif /*!HAVE_W32_SYSTEM*/
+#endif /*!HAVE_W32_SYSTEM || USE_NPTH*/
       nleft -= nwritten;
       data += nwritten;
     }
@@ -1791,7 +2359,6 @@ write_server (int sock, const char *data, size_t length)
 
 
 \f
-#ifdef HTTP_USE_ESTREAM
 /* Read handler for estream.  */
 static ssize_t
 cookie_read (void *cookie, void *buffer, size_t size)
@@ -1799,11 +2366,19 @@ cookie_read (void *cookie, void *buffer, size_t size)
   cookie_t c = cookie;
   int nread;
 
+  if (c->content_length_valid)
+    {
+      if (!c->content_length)
+        return 0; /* EOF */
+      if (c->content_length < size)
+        size = c->content_length;
+    }
+
 #ifdef HTTP_USE_GNUTLS
-  if (c->tls_session)
+  if (c->use_tls && c->session && c->session->tls_session)
     {
     again:
-      nread = gnutls_record_recv (c->tls_session, buffer, size);
+      nread = gnutls_record_recv (c->session->tls_session, buffer, size);
       if (nread < 0)
         {
           if (nread == GNUTLS_E_INTERRUPTED)
@@ -1814,13 +2389,13 @@ cookie_read (void *cookie, void *buffer, size_t size)
 
               tv.tv_sec = 0;
               tv.tv_usec = 50000;
-              select (0, NULL, NULL, NULL, &tv);
+              my_select (0, NULL, NULL, NULL, &tv);
               goto again;
             }
           if (nread == GNUTLS_E_REHANDSHAKE)
             goto again; /* A client is allowed to just ignore this request. */
           log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
-          errno = EIO;
+          gpg_err_set_errno (EIO);
           return -1;
         }
     }
@@ -1829,33 +2404,45 @@ cookie_read (void *cookie, void *buffer, size_t size)
     {
       do
         {
-#ifdef HAVE_W32_SYSTEM
+#ifdef USE_NPTH
+          nread = npth_read (c->sock->fd, buffer, size);
+#elif defined(HAVE_W32_SYSTEM)
           /* Under Windows we need to use recv for a socket.  */
-          nread = recv (c->fd, buffer, size, 0);
+          nread = recv (c->sock->fd, buffer, size, 0);
 #else
-          nread = read (c->fd, buffer, size);
+          nread = read (c->sock->fd, buffer, size);
 #endif
         }
       while (nread == -1 && errno == EINTR);
     }
 
+  if (c->content_length_valid && nread > 0)
+    {
+      if (nread < c->content_length)
+        c->content_length -= nread;
+      else
+        c->content_length = 0;
+    }
+
   return nread;
 }
 
 /* Write handler for estream.  */
 static ssize_t
-cookie_write (void *cookie, const void *buffer, size_t size)
+cookie_write (void *cookie, const void *buffer_arg, size_t size)
 {
+  const char *buffer = buffer_arg;
   cookie_t c = cookie;
   int nwritten = 0;
 
 #ifdef HTTP_USE_GNUTLS
-  if (c->tls_session)
+  if (c->use_tls && c->session && c->session->tls_session)
     {
       int nleft = size;
       while (nleft > 0)
         {
-          nwritten = gnutls_record_send (c->tls_session, buffer, nleft);
+          nwritten = gnutls_record_send (c->session->tls_session,
+                                         buffer, nleft);
           if (nwritten <= 0)
             {
               if (nwritten == GNUTLS_E_INTERRUPTED)
@@ -1866,12 +2453,12 @@ cookie_write (void *cookie, const void *buffer, size_t size)
 
                   tv.tv_sec = 0;
                   tv.tv_usec = 50000;
-                  select (0, NULL, NULL, NULL, &tv);
+                  my_select (0, NULL, NULL, NULL, &tv);
                   continue;
                 }
               log_info ("TLS network write failed: %s\n",
                         gnutls_strerror (nwritten));
-              errno = EIO;
+              gpg_err_set_errno (EIO);
               return -1;
             }
           nleft -= nwritten;
@@ -1881,9 +2468,9 @@ cookie_write (void *cookie, const void *buffer, size_t size)
   else
 #endif /*HTTP_USE_GNUTLS*/
     {
-      if ( write_server (c->fd, buffer, size) )
+      if ( write_server (c->sock->fd, buffer, size) )
         {
-          errno = EIO;
+          gpg_err_set_errno (EIO);
           nwritten = -1;
         }
       else
@@ -1893,6 +2480,31 @@ cookie_write (void *cookie, const void *buffer, size_t size)
   return nwritten;
 }
 
+
+#ifdef HTTP_USE_GNUTLS
+/* Wrapper for gnutls_bye used by my_socket_unref.  */
+static void
+send_gnutls_bye (void *opaque)
+{
+  tls_session_t tls_session = opaque;
+  int ret;
+
+ again:
+  do
+    ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
+  while (ret == GNUTLS_E_INTERRUPTED);
+  if (ret == GNUTLS_E_AGAIN)
+    {
+      struct timeval tv;
+
+      tv.tv_sec = 0;
+      tv.tv_usec = 50000;
+      my_select (0, NULL, NULL, NULL, &tv);
+      goto again;
+    }
+}
+#endif /*HTTP_USE_GNUTLS*/
+
 /* Close handler for estream.  */
 static int
 cookie_close (void *cookie)
@@ -1903,180 +2515,148 @@ cookie_close (void *cookie)
     return 0;
 
 #ifdef HTTP_USE_GNUTLS
-  if (c->tls_session && !c->keep_socket)
-    {
-      gnutls_bye (c->tls_session, GNUTLS_SHUT_RDWR);
-    }
+  if (c->use_tls && c->session && c->session->tls_session)
+    my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
+  else
 #endif /*HTTP_USE_GNUTLS*/
-  if (c->fd != -1 && !c->keep_socket)
-    sock_close (c->fd);
+    if (c->sock)
+      my_socket_unref (c->sock, NULL, NULL);
 
+  if (c->session)
+    http_session_unref (c->session);
   xfree (c);
   return 0;
 }
-#endif /*HTTP_USE_ESTREAM*/
 
 
 
 \f
-/**** Test code ****/
-#ifdef TEST
-
-static gpg_error_t
-verify_callback (http_t hd, void *tls_context, int reserved)
-{
-  log_info ("verification of certificates skipped\n");
-  return 0;
-}
-
-
-
-/* static void */
-/* my_gnutls_log (int level, const char *text) */
-/* { */
-/*   fprintf (stderr, "gnutls:L%d: %s", level, text); */
-/* } */
-
-int
-main (int argc, char **argv)
+/* Verify the credentials of the server.  Returns 0 on success and
+   store the result in the session object.  */
+gpg_error_t
+http_verify_server_credentials (http_session_t sess)
 {
+#if HTTP_USE_NTBTLS
+  (void)sess;
+  return 0;  /* FIXME!! */
+#elif HTTP_USE_GNUTLS
+  static const char const errprefix[] = "TLS verification of peer failed";
   int rc;
-  parsed_uri_t uri;
-  uri_tuple_t r;
-  http_t hd;
-  int c;
-  gnutls_session_t tls_session = NULL;
-#ifdef HTTP_USE_GNUTLS
-  gnutls_certificate_credentials certcred;
-  const int certprio[] = { GNUTLS_CRT_X509, 0 };
-#endif /*HTTP_USE_GNUTLS*/
-  header_t hdr;
+  unsigned int status;
+  const char *hostname;
+  const gnutls_datum_t *certlist;
+  unsigned int certlistlen;
+  gnutls_x509_crt_t cert;
+  gpg_error_t err = 0;
 
-#ifdef HTTP_USE_ESTREAM
-  es_init ();
-#endif
-  log_set_prefix ("http-test", 1 | 4);
-  if (argc == 1)
-    {
-      /*start_server (); */
-      return 0;
-    }
+  sess->verify.done = 1;
+  sess->verify.status = 0;
+  sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
 
-  if (argc != 2)
+  if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
     {
-      fprintf (stderr, "usage: http-test uri\n");
-      return 1;
+      log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
+      sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
+      return gpg_error (GPG_ERR_GENERAL);
     }
-  argc--;
-  argv++;
 
-#ifdef HTTP_USE_GNUTLS
-  rc = gnutls_global_init ();
-  if (rc)
-    log_error ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));
-  rc = gnutls_certificate_allocate_credentials (&certcred);
-  if (rc)
-    log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
-               gnutls_strerror (rc));
-/*   rc = gnutls_certificate_set_x509_trust_file */
-/*     (certcred, "ca.pem", GNUTLS_X509_FMT_PEM); */
-/*   if (rc) */
-/*     log_error ("gnutls_certificate_set_x509_trust_file failed: %s\n", */
-/*                gnutls_strerror (rc)); */
-  rc = gnutls_init (&tls_session, GNUTLS_CLIENT);
-  if (rc)
-    log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
-  rc = gnutls_set_default_priority (tls_session);
-  if (rc)
-    log_error ("gnutls_set_default_priority failed: %s\n",
-               gnutls_strerror (rc));
-  rc = gnutls_certificate_type_set_priority (tls_session, certprio);
+  rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
   if (rc)
-    log_error ("gnutls_certificate_type_set_priority failed: %s\n",
-               gnutls_strerror (rc));
-  rc = gnutls_credentials_set (tls_session, GNUTLS_CRD_CERTIFICATE, certcred);
-  if (rc)
-    log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
-/*   gnutls_global_set_log_function (my_gnutls_log); */
-/*   gnutls_global_set_log_level (4); */
+    {
+      log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
+      if (!err)
+        err = gpg_error (GPG_ERR_GENERAL);
+    }
+  else if (status)
+    {
+      log_error ("%s: status=0x%04x\n", errprefix, status);
+#if GNUTLS_VERSION_NUMBER >= 0x030104
+      {
+        gnutls_datum_t statusdat;
+
+        if (!gnutls_certificate_verification_status_print
+            (status, GNUTLS_CRT_X509, &statusdat, 0))
+          {
+            log_info ("%s: %s\n", errprefix, statusdat.data);
+            gnutls_free (statusdat.data);
+          }
+      }
+#endif /*gnutls >= 3.1.4*/
 
-  http_register_tls_callback (verify_callback);
-#endif /*HTTP_USE_GNUTLS*/
+      sess->verify.status = status;
+      if (!err)
+        err = gpg_error (GPG_ERR_GENERAL);
+    }
 
-  rc = http_parse_uri (&uri, *argv);
-  if (rc)
+  hostname = sess->servername;
+  if (!hostname || !strchr (hostname, '.'))
     {
-      log_error ("`%s': %s\n", *argv, gpg_strerror (rc));
-      http_release_parsed_uri (uri);
-      return 1;
+      log_error ("%s: %s\n", errprefix, "hostname missing");
+      if (!err)
+        err = gpg_error (GPG_ERR_GENERAL);
     }
 
-  printf ("Scheme: %s\n", uri->scheme);
-  printf ("Host  : %s\n", uri->host);
-  printf ("Port  : %u\n", uri->port);
-  printf ("Path  : %s\n", uri->path);
-  for (r = uri->params; r; r = r->next)
+  certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
+  if (!certlistlen)
     {
-      printf ("Params: %s", r->name);
-      if (!r->no_value)
-       {
-         printf ("=%s", r->value);
-         if (strlen (r->value) != r->valuelen)
-           printf (" [real length=%d]", (int) r->valuelen);
-       }
-      putchar ('\n');
+      log_error ("%s: %s\n", errprefix, "server did not send a certificate");
+      if (!err)
+        err = gpg_error (GPG_ERR_GENERAL);
+
+      /* Need to stop here.  */
+      if (err)
+        return err;
     }
-  for (r = uri->query; r; r = r->next)
+
+  rc = gnutls_x509_crt_init (&cert);
+  if (rc < 0)
     {
-      printf ("Query : %s", r->name);
-      if (!r->no_value)
-       {
-         printf ("=%s", r->value);
-         if (strlen (r->value) != r->valuelen)
-           printf (" [real length=%d]", (int) r->valuelen);
-       }
-      putchar ('\n');
+      if (!err)
+        err = gpg_error (GPG_ERR_GENERAL);
+      if (err)
+        return err;
     }
-  http_release_parsed_uri (uri);
-  uri = NULL;
 
-  rc = http_open_document (&hd, *argv, NULL, HTTP_FLAG_NEED_HEADER,
-                           NULL, tls_session);
-  if (rc)
+  rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
+  if (rc < 0)
     {
-      log_error ("can't get `%s': %s\n", *argv, gpg_strerror (rc));
-      return 1;
+      log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
+                 gnutls_strerror (rc));
+      if (!err)
+        err = gpg_error (GPG_ERR_GENERAL);
     }
-  log_info ("open_http_document succeeded; status=%u\n",
-            http_get_status_code (hd));
-  for (hdr = hd->headers; hdr; hdr = hdr->next)
-    printf ("HDR: %s: %s\n", hdr->name, hdr->value);
-  switch (http_get_status_code (hd))
+
+  if (!gnutls_x509_crt_check_hostname (cert, hostname))
     {
-    case 200:
-      while ((c = P_ES(getc) (http_get_read_ptr (hd))) != EOF)
-        putchar (c);
-      break;
-    case 301:
-    case 302:
-      printf ("Redirected to `%s'\n", http_get_header (hd, "Location"));
-      break;
+      log_error ("%s: %s\n", errprefix, "hostname does not match");
+      if (!err)
+        err = gpg_error (GPG_ERR_GENERAL);
     }
-  http_close (hd, 0);
 
-#ifdef HTTP_USE_GNUTLS
-  gnutls_deinit (tls_session);
-  gnutls_certificate_free_credentials (certcred);
-  gnutls_global_deinit ();
-#endif /*HTTP_USE_GNUTLS*/
+  gnutls_x509_crt_deinit (cert);
 
-  return 0;
-}
-#endif /*TEST*/
+  if (!err)
+    sess->verify.rc = 0;
 
+  if (sess->cert_log_cb)
+    {
+      const void *bufarr[10];
+      size_t buflenarr[10];
+      size_t n;
 
-/*
-Local Variables:
-compile-command: "gcc -I.. -I../gl -DTEST -DHAVE_CONFIG_H -Wall -O2 -g -o http-test http.c -L. -lcommon -L../jnlib -ljnlib -lgcrypt -lpth -lgnutls"
-End:
-*/
+      for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
+        {
+          bufarr[n] = certlist[n].data;
+          buflenarr[n] = certlist[n].size;
+        }
+      bufarr[n] = NULL;
+      buflenarr[n] = 0;
+      sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
+    }
+
+  return err;
+#else /*!HTTP_USE_GNUTLS*/
+  (void)sess;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif
+}
index 0b1dc4d..3a44430 100644 (file)
@@ -1,15 +1,25 @@
 /* http.h  -  HTTP protocol handler
- * Copyright (C) 1999, 2000, 2001, 2003,
- *               2006, 2012, 2013 Free Software Foundation, Inc.
- *     
+ * Copyright (C) 1999, 2000, 2001, 2003, 2006,
+ *               2010 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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,
+ * or both in parallel, as here.
+ *
+ * This file 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.
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef GNUPG_COMMON_HTTP_H
-#define GNUPG_COMMON_HTTP_H 
+#define GNUPG_COMMON_HTTP_H
 
 #include <gpg-error.h>
-#ifdef HTTP_USE_ESTREAM
-#include "estream.h"
-#endif
 
-struct uri_tuple_s {
+struct uri_tuple_s
+{
   struct uri_tuple_s *next;
   const char *name;    /* A pointer into name. */
   char  *value;         /* A pointer to value (a Nul is always appended). */
@@ -35,12 +43,15 @@ struct uri_tuple_s {
 };
 typedef struct uri_tuple_s *uri_tuple_t;
 
-struct parsed_uri_s 
+struct parsed_uri_s
 {
   /* All these pointers point into BUFFER; most stuff is not escaped. */
-  char *scheme;                /* Pointer to the scheme string (lowercase). */
-  int use_tls;          /* Whether TLS should be used. */
-  char *auth;           /* username/password for basic auth */
+  char *scheme;                /* Pointer to the scheme string (always lowercase). */
+  unsigned int is_http:1; /* This is a HTTP style URI.   */
+  unsigned int use_tls:1; /* Whether TLS should be used. */
+  unsigned int opaque:1;/* Unknown scheme; PATH has the rest.  */
+  unsigned int v6lit:1; /* Host was given as a literal v6 address.  */
+  char *auth;           /* username/password for basic auth.  */
   char *host;          /* Host (converted to lowercase). */
   unsigned short port;  /* Port (always set if the host is set). */
   char *path;          /* Path. */
@@ -50,46 +61,66 @@ struct parsed_uri_s
 };
 typedef struct parsed_uri_s *parsed_uri_t;
 
-typedef enum 
+typedef enum
   {
     HTTP_REQ_GET  = 1,
     HTTP_REQ_HEAD = 2,
-    HTTP_REQ_POST = 3
-  } 
+    HTTP_REQ_POST = 3,
+    HTTP_REQ_OPAQUE = 4  /* Internal use.  */
+  }
 http_req_t;
 
 /* We put the flag values into an enum, so that gdb can display them. */
 enum
-  { 
-    HTTP_FLAG_TRY_PROXY = 1,
-    HTTP_FLAG_LOG_RESP = 2,
-    HTTP_FLAG_NEED_HEADER = 4
+  {
+    HTTP_FLAG_TRY_PROXY = 1,     /* Try to use a proxy.  */
+    HTTP_FLAG_SHUTDOWN = 2,      /* Close sending end after the request.  */
+    HTTP_FLAG_LOG_RESP = 8,      /* Log the server respone.  */
+    HTTP_FLAG_FORCE_TLS = 16,    /* Force the use opf TLS.  */
+    HTTP_FLAG_IGNORE_CL = 32,    /* Ignore content-length.  */
+    HTTP_FLAG_IGNORE_IPv4 = 64,  /* Do not use IPv4.  */
+    HTTP_FLAG_IGNORE_IPv6 = 128  /* Do not use IPv6.  */
   };
 
+
+struct http_session_s;
+typedef struct http_session_s *http_session_t;
+
 struct http_context_s;
 typedef struct http_context_s *http_t;
 
-void http_register_tls_callback (gpg_error_t (*cb) (http_t, void *, int));
+void http_register_tls_callback (gpg_error_t (*cb)(http_t,http_session_t,int));
+void http_register_tls_ca (const char *fname);
+
+gpg_error_t http_session_new (http_session_t *r_session,
+                              const char *tls_priority);
+http_session_t http_session_ref (http_session_t sess);
+void http_session_release (http_session_t sess);
+
+void http_session_set_log_cb (http_session_t sess,
+                              void (*cb)(http_session_t, gpg_error_t,
+                                         const char *,
+                                         const void **, size_t *));
 
-gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri);
+
+gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
+                            int no_scheme_check);
 
 void http_release_parsed_uri (parsed_uri_t uri);
 
-struct http_srv
-{
-  const char *srvtag;
-  char *used_server;
-  unsigned short used_port;
-};
+gpg_error_t http_raw_connect (http_t *r_hd,
+                              const char *server, unsigned short port,
+                              unsigned int flags, const char *srvtag);
 
 gpg_error_t http_open (http_t *r_hd, http_req_t reqtype,
                        const char *url,
+                       const char *httphost,
                        const char *auth,
                        unsigned int flags,
                        const char *proxy,
-                       void *tls_context,
-                      struct http_srv *srv,
-                      strlist_t headers);
+                       http_session_t session,
+                       const char *srvtag,
+                       strlist_t headers);
 
 void http_start_data (http_t hd);
 
@@ -102,21 +133,20 @@ gpg_error_t http_open_document (http_t *r_hd,
                                 const char *auth,
                                 unsigned int flags,
                                 const char *proxy,
-                                void *tls_context,
-                               struct http_srv *srv,
-                               strlist_t headers);
+                                http_session_t session,
+                                const char *srvtag,
+                                strlist_t headers);
 
-#ifdef HTTP_USE_ESTREAM
 estream_t http_get_read_ptr (http_t hd);
 estream_t http_get_write_ptr (http_t hd);
-#else /*!HTTP_USE_ESTREAM*/
-FILE *http_get_read_ptr (http_t hd);
-FILE *http_get_write_ptr (http_t hd);
-#endif /*!HTTP_USE_ESTREAM*/
 unsigned int http_get_status_code (http_t hd);
+const char *http_get_tls_info (http_t hd, const char *what);
 const char *http_get_header (http_t hd, const char *name);
+const char **http_get_header_names (http_t hd);
+gpg_error_t http_verify_server_credentials (http_session_t sess);
 
 char *http_escape_string (const char *string, const char *specials);
+char *http_escape_data (const void *data, size_t datalen, const char *specials);
 
 
 #endif /*GNUPG_COMMON_HTTP_H*/
index db5ddf5..202d840 100644 (file)
@@ -1,14 +1,22 @@
 /* i18n.c - gettext initialization
- *     Copyright (C) 2007 Free Software Foundation, Inc.
+ *     Copyright (C) 2007, 2010 Free Software Foundation, Inc.
  *
- * This file is part of GnuPG.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * 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 3 of the License, or
- * (at your option) any later version.
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
  *
- * GnuPG is distributed in the hope that it will be useful,
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -34,6 +42,7 @@ i18n_init (void)
 {
 #ifdef USE_SIMPLE_GETTEXT
   bindtextdomain (PACKAGE_GT, gnupg_localedir ());
+  textdomain (PACKAGE_GT);
 #else
 # ifdef ENABLE_NLS
   setlocale (LC_ALL, "" );
@@ -51,8 +60,8 @@ char *
 i18n_switchto_utf8 (void)
 {
 #ifdef USE_SIMPLE_GETTEXT
-  gettext_select_utf8 (1);
-  return NULL;
+  /* Return an arbitrary pointer as true value.  */
+  return gettext_use_utf8 (1) ? (char*)(-1) : NULL;
 #elif defined(ENABLE_NLS)
   char *orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL);
 # ifdef HAVE_LANGINFO_CODESET
@@ -68,7 +77,7 @@ i18n_switchto_utf8 (void)
       if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8"))
         {
          xfree (orig_codeset);
-         orig_codeset = NULL; 
+         orig_codeset = NULL;
        }
     }
   return orig_codeset;
@@ -82,8 +91,7 @@ void
 i18n_switchback (char *saved_codeset)
 {
 #ifdef USE_SIMPLE_GETTEXT
-  (void)saved_codeset;
-  gettext_select_utf8 (0);
+  gettext_use_utf8 (!!saved_codeset);
 #elif defined(ENABLE_NLS)
   if (saved_codeset)
     {
index 7405f9a..3b02a6b 100644 (file)
@@ -4,7 +4,7 @@
  * 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
 
 
 #ifdef USE_SIMPLE_GETTEXT
-# include "../jnlib/w32help.h"
+# include "../common/w32help.h"
 # define _(a) gettext (a)
 # define N_(a) (a)
 #else
 # ifdef HAVE_LOCALE_H
-#  include <locale.h>  
+#  include <locale.h>
 # endif
 # ifdef ENABLE_NLS
 #  include <libintl.h>
index 7be8af0..1cbd709 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 
 #include <config.h>
 
-#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
-#undef HAVE_PTH
-#undef USE_GNU_PTH
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+#undef HAVE_NPTH
+#undef USE_NPTH
 #endif
 
 #ifdef HAVE_W32_SYSTEM
 # ifdef HAVE_WINSOCK2_H
 #  include <winsock2.h>
 # endif
-#include <windows.h>
+# include <windows.h>
 #endif
-#ifdef HAVE_PTH
-#include <pth.h>
+#ifdef HAVE_NPTH
+# include <npth.h>
+#endif
+#ifdef HAVE_W32CE_SYSTEM
+# include <assuan.h> /* For _assuan_w32ce_finish_pipe. */
 #endif
 
-#include "estream.h"
 #include "util.h"
 
+/* This object is used to register memory cleanup functions.
+   Technically they are not needed but they can avoid frequent
+   questions about un-released memory.  Note that we use the system
+   malloc and not any wrappers.  */
+struct mem_cleanup_item_s;
+typedef struct mem_cleanup_item_s *mem_cleanup_item_t;
+
+struct mem_cleanup_item_s
+{
+  mem_cleanup_item_t next;
+  void (*func) (void);
+};
+
+static mem_cleanup_item_t mem_cleanup_list;
+
+
+/* The default error source of the application.  This is different
+   from GPG_ERR_SOURCE_DEFAULT in that it does not depend on the
+   source file and thus is usable in code shared by applications.  */
+gpg_err_source_t default_errsource;
+
+
+#ifdef HAVE_W32CE_SYSTEM
+static void parse_std_file_handles (int *argcp, char ***argvp);
+static void
+sleep_on_exit (void)
+{
+  /* The sshd on CE swallows some of the command output.  Sleeping a
+     while usually helps.  */
+  Sleep (400);
+}
+#endif /*HAVE_W32CE_SYSTEM*/
+
+
+static void
+run_mem_cleanup (void)
+{
+  mem_cleanup_item_t next;
+
+  while (mem_cleanup_list)
+    {
+      next = mem_cleanup_list->next;
+      mem_cleanup_list->func ();
+      free (mem_cleanup_list);
+      mem_cleanup_list = next;
+    }
+}
+
+
+void
+register_mem_cleanup_func (void (*func)(void))
+{
+  mem_cleanup_item_t item;
+
+  item = malloc (sizeof *item);
+  if (item)
+    {
+      item->func = func;
+      item->next = mem_cleanup_list;
+      mem_cleanup_list = item;
+    }
+}
+
+
+/* If STRING is not NULL write string to es_stdout or es_stderr.  MODE
+   must be 1 or 2.  If STRING is NULL flush the respective stream.  */
+static int
+writestring_via_estream (int mode, const char *string)
+{
+  if (mode == 1 || mode == 2)
+    {
+      if (string)
+        return es_fputs (string, mode == 1? es_stdout : es_stderr);
+      else
+        return es_fflush (mode == 1? es_stdout : es_stderr);
+    }
+  else
+    return -1;
+}
+
 
 /* This function is to be used early at program startup to make sure
    that some subsystems are initialized.  This is in particular
    important for W32 to initialize the sockets so that our socket
    emulation code used directly as well as in libassuan may be used.
    It should best be called before any I/O is done so that setup
-   required for logging is ready.  CAUTION: This might be called while
-   running suid(root). */
+   required for logging is ready.  ARGCP and ARGVP are the addresses
+   of the parameters given to main.  This function may modify them.
+
+   This function should be called only via the macro
+   init_common_subsystems.
+
+   CAUTION: This might be called while running suid(root).  */
 void
-init_common_subsystems (void)
+_init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
 {
+  /* Store the error source in a gloabl variable. */
+  default_errsource = errsource;
+
+  atexit (run_mem_cleanup);
+
   /* Try to auto set the character set.  */
   set_native_charset (NULL);
 
 #ifdef HAVE_W32_SYSTEM
   /* For W32 we need to initialize the socket layer.  This is because
      we use recv and send in libassuan as well as at some other
-     places.  If we are building with PTH we let pth_init do it.  We
-     can't do much on error so we ignore them.  An error would anyway
-     later pop up if one of the socket functions is used. */
-# ifdef HAVE_PTH
-  pth_init ();
-# else
- {
-   WSADATA wsadat;
-
-   WSAStartup (0x202, &wsadat);
- }
-# endif /*!HAVE_PTH*/
+     places.  */
+  {
+    WSADATA wsadat;
+
+    WSAStartup (0x202, &wsadat);
+  }
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+  /* Register the sleep exit function before the estream init so that
+     the sleep will be called after the estream registered atexit
+     function which flushes the left open estream streams and in
+     particular es_stdout.  */
+  atexit (sleep_on_exit);
 #endif
 
   /* Initialize the Estream library. */
-  es_init ();
+  gpgrt_init ();
+  gpgrt_set_alloc_func (gcry_realloc);
+#ifdef USE_NPTH
+  gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
+#endif
+
+  /* Special hack for Windows CE: We extract some options from arg
+     to setup the standard handles.  */
+#ifdef HAVE_W32CE_SYSTEM
+  parse_std_file_handles (argcp, argvp);
+#else
+  (void)argcp;
+  (void)argvp;
+#endif
+
+  /* Access the standard estreams as early as possible.  If we don't
+     do this the original stdio streams may have been closed when
+     _es_get_std_stream is first use and in turn it would connect to
+     the bit bucket.  */
+  {
+    int i;
+    for (i=0; i < 3; i++)
+      (void)_gpgrt_get_std_stream (i);
+  }
+
+  /* --version et al shall use estream as well.  */
+  argparse_register_outfnc (writestring_via_estream);
 }
 
+
+
+/* WindowsCE uses a very strange way of handling the standard streams.
+   There is a function SetStdioPath to associate a standard stream
+   with a file or a device but what we really want is to use pipes as
+   standard streams.  Despite that we implement pipes using a device,
+   we would have some limitations on the number of open pipes due to
+   the 3 character limit of device file name.  Thus we don't take this
+   path.  Another option would be to install a file system driver with
+   support for pipes; this would allow us to get rid of the device
+   name length limitation.  However, with GnuPG we can get away be
+   redefining the standard streams and passing the handles to be used
+   on the command line.  This has also the advantage that it makes
+   creating a process much easier and does not require the
+   SetStdioPath set and restore game.  The caller needs to pass the
+   rendezvous ids using up to three options:
+
+     -&S0=<rvid> -&S1=<rvid> -&S2=<rvid>
+
+   They are all optional but they must be the first arguments on the
+   command line.  Parsing stops as soon as an invalid option is found.
+   These rendezvous ids are then used to finish the pipe creation.*/
+#ifdef HAVE_W32CE_SYSTEM
+static void
+parse_std_file_handles (int *argcp, char ***argvp)
+{
+  int argc = *argcp;
+  char **argv = *argvp;
+  const char *s;
+  assuan_fd_t fd;
+  int i;
+  int fixup = 0;
+
+  if (!argc)
+    return;
+
+  for (argc--, argv++; argc; argc--, argv++)
+    {
+      s = *argv;
+      if (*s == '-' && s[1] == '&' && s[2] == 'S'
+          && (s[3] == '0' || s[3] == '1' || s[3] == '2')
+          && s[4] == '='
+          && (strchr ("-01234567890", s[5]) || !strcmp (s+5, "null")))
+        {
+          if (s[5] == 'n')
+            fd = ASSUAN_INVALID_FD;
+          else
+            fd = _assuan_w32ce_finish_pipe (atoi (s+5), s[3] != '0');
+          _es_set_std_fd (s[3] - '0', (int)fd);
+          fixup++;
+        }
+      else
+        break;
+    }
+
+  if (fixup)
+    {
+      argc = *argcp;
+      argc -= fixup;
+      *argcp = argc;
+
+      argv = *argvp;
+      for (i=1; i < argc; i++)
+        argv[i] = argv[i + fixup];
+      for (; i < argc + fixup; i++)
+        argv[i] = NULL;
+    }
+
+
+}
+#endif /*HAVE_W32CE_SYSTEM*/
index 14dfa7b..eea2eb1 100644 (file)
@@ -1,14 +1,24 @@
 /* init.h - Definitions for init fucntions.
- *     Copyright (C) 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2007, 2012 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #ifndef GNUPG_COMMON_INIT_H
 #define GNUPG_COMMON_INIT_H
 
-void init_common_subsystems (void);
+#ifndef GPG_ERR_SOURCE_DEFAULT
+# error GPG_ERR_SOURCE_DEFAULT is not defined
+#elseif GPG_ERR_SOURCE_DEFAULT == GPG_ERR_SOURCE_UNKNOWN
+# error GPG_ERR_SOURCE_DEFAULT has default value
+#endif
+
+void register_mem_cleanup_func (void (*func)(void));
 
+void _init_common_subsystems (gpg_err_source_t errsource,
+                              int *argcp, char ***argvp);
+#define init_common_subsystems(a,b)                             \
+  _init_common_subsystems (GPG_ERR_SOURCE_DEFAULT, (a), (b))
 
 #endif /*GNUPG_COMMON_INIT_H*/
index ee0775c..3c68ce5 100644 (file)
@@ -1,15 +1,25 @@
 /* iobuf.c  -  File Handling for OpenPGP.
- * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006,
- *               2007, 2008, 2009  Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
+ *               2009, 2010, 2011  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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 # include <swis.h>
 #endif /* __riscos__ */
 
+#include <assuan.h>
+
 #include "util.h"
 #include "sysutils.h"
-#include "../include/host2net.h"
 #include "iobuf.h"
 
 /*-- Begin configurable part.  --*/
    test "armored_key_8192" in armor.test! */
 #define IOBUF_BUFFER_SIZE  8192
 
-/* We don't want to use the STDIO based backend.  If you change this
-   be aware that there is no fsync support for the stdio backend.  */
-#undef FILE_FILTER_USES_STDIO
-
 /* To avoid a potential DoS with compression packets we better limit
    the number of filters in a chain.  */
 #define MAX_NESTING_FILTER 64
 /*-- End configurable part.  --*/
 
 
-/* Under W32 the default is to use the setmode call.  Define a macro
-   which allows us to enable this call.  */
 #ifdef HAVE_W32_SYSTEM
-# define USE_SETMODE 1
-#endif /*HAVE_W32_SYSTEM*/
-
+# ifdef HAVE_W32CE_SYSTEM
+#  define FD_FOR_STDIN  (es_fileno (es_stdin))
+#  define FD_FOR_STDOUT (es_fileno (es_stdout))
+# else
+#  define FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
+#  define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
+# endif
+#else /*!HAVE_W32_SYSTEM*/
+# define FD_FOR_STDIN  (0)
+# define FD_FOR_STDOUT (1)
+#endif /*!HAVE_W32_SYSTEM*/
 
-/* Definition of constants and macros used by our file filter
-   implementation.  What we define here are 3 macros to make the
-   appropriate calls:
-
-   my_fileno
-     Is expanded to fileno(a) if using a stdion backend and to a if we
-     are using the low-level backend.
-
-   my_fopen
-     Is defined to fopen for the stdio backend and to direct_open if
-     we are using the low-evel backend.
-
-   my_fopen_ro
-     Is defined to fopen for the stdio backend and to fd_cache_open if
-     we are using the low-evel backend.
-
-   fp_or_fd_t
-     Is the type we use for the backend stream or file descriptor.
-
-   INVALID_FP, FILEP_OR_FD_FOR_STDIN, FILEP_OR_FD_FOR_STDOUT
-     Are macros defined depending on the used backend.
-
-*/
-#ifdef FILE_FILTER_USES_STDIO
-# define my_fileno(a)     fileno ((a))
-# define my_fopen_ro(a,b) fopen ((a),(b))
-# define my_fopen(a,b)    fopen ((a),(b))
-  typedef FILE *fp_or_fd_t;
-# define INVALID_FP              NULL
-# define FILEP_OR_FD_FOR_STDIN   (stdin)
-# define FILEP_OR_FD_FOR_STDOUT  (stdout)
-#else /*!FILE_FILTER_USES_STDIO*/
-# define my_fopen_ro(a,b) fd_cache_open ((a),(b))
-# define my_fopen(a,b)    direct_open ((a),(b))
-# ifdef HAVE_W32_SYSTEM
-   /* (We assume that a HANDLE first into an int.)  */
-#  define my_fileno(a)  ((int)(a))
-   typedef HANDLE fp_or_fd_t;
-#  define INVALID_FP             ((HANDLE)-1)
-#  define FILEP_OR_FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
-#  define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
-#  undef USE_SETMODE
-# else /*!HAVE_W32_SYSTEM*/
-#  define my_fileno(a)  (a)
-   typedef int fp_or_fd_t;
-#  define INVALID_FP             (-1)
-#  define FILEP_OR_FD_FOR_STDIN  (0)
-#  define FILEP_OR_FD_FOR_STDOUT (1)
-# endif /*!HAVE_W32_SYSTEM*/
-#endif /*!FILE_FILTER_USES_STDIO*/
 
 /* The context used by the file filter.  */
 typedef struct
 {
-  fp_or_fd_t fp;       /* Open file pointer or handle.  */
+  gnupg_fd_t fp;       /* Open file pointer or handle.  */
   int keep_open;
   int no_cache;
   int eof_seen;
   int print_only_name; /* Flags indicating that fname is not a real file.  */
   char fname[1];       /* Name of the file.  */
-}
-file_filter_ctx_t;
+} file_filter_ctx_t;
+
+/* The context used by the estream filter.  */
+typedef struct
+{
+  estream_t fp;        /* Open estream handle.  */
+  int keep_open;
+  int no_cache;
+  int eof_seen;
+  int print_only_name; /* Flags indicating that fname is not a real file.  */
+  char fname[1];       /* Name of the file.  */
+} file_es_filter_ctx_t;
 
 
-/* If we are not using stdio as the backend we make use of a "close
-   cache".  */
-#ifndef FILE_FILTER_USES_STDIO
+/* Object to control the "close cache".  */
 struct close_cache_s
 {
   struct close_cache_s *next;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   char fname[1];
 };
 typedef struct close_cache_s *close_cache_t;
 static close_cache_t close_cache;
-#endif /*!FILE_FILTER_USES_STDIO*/
 
 
 
@@ -158,8 +128,8 @@ typedef struct
   int eof_seen;
   int print_only_name; /* Flag indicating that fname is not a real file.  */
   char fname[1];       /* Name of the file */
-}
-sock_filter_ctx_t;
+
+sock_filter_ctx_t;
 #endif /*HAVE_W32_SYSTEM*/
 
 /* The first partial length header block must be of size 512
@@ -195,7 +165,6 @@ static int translate_file_handle (int fd, int for_write);
 
 
 \f
-#ifndef FILE_FILTER_USES_STDIO
 /* This is a replacement for strcmp.  Under W32 it does not
    distinguish between backslash and slash.  */
 static int
@@ -229,7 +198,7 @@ fd_cache_invalidate (const char *fname)
 
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
          if (DBG_IOBUF)
            log_debug ("                did (%s)\n", cc->fname);
@@ -239,7 +208,7 @@ fd_cache_invalidate (const char *fname)
 #else
          rc = close (cc->fp);
 #endif
-         cc->fp = INVALID_FP;
+         cc->fp = GNUPG_INVALID_FD;
        }
     }
   return rc;
@@ -262,7 +231,7 @@ fd_cache_synchronize (const char *fname)
 
   for (cc=close_cache; cc; cc = cc->next )
     {
-      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
          if (DBG_IOBUF)
            log_debug ("                 did (%s)\n", cc->fname);
@@ -278,8 +247,8 @@ fd_cache_synchronize (const char *fname)
 }
 
 
-static fp_or_fd_t
-direct_open (const char *fname, const char *mode)
+static gnupg_fd_t
+direct_open (const char *fname, const char *mode, int mode700)
 {
 #ifdef HAVE_W32_SYSTEM
   unsigned long da, cd, sm;
@@ -294,7 +263,7 @@ direct_open (const char *fname, const char *mode)
   if (strchr (mode, '+'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       da = GENERIC_READ | GENERIC_WRITE;
       cd = OPEN_EXISTING;
       sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
@@ -302,7 +271,7 @@ direct_open (const char *fname, const char *mode)
   else if (strchr (mode, 'w'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       da = GENERIC_WRITE;
       cd = CREATE_ALWAYS;
       sm = FILE_SHARE_WRITE;
@@ -314,23 +283,42 @@ direct_open (const char *fname, const char *mode)
       sm = FILE_SHARE_READ;
     }
 
+#ifdef HAVE_W32CE_SYSTEM
+  {
+    wchar_t *wfname = utf8_to_wchar (fname);
+    if (wfname)
+      {
+        hfile = CreateFile (wfname, da, sm, NULL, cd,
+                            FILE_ATTRIBUTE_NORMAL, NULL);
+        xfree (wfname);
+      }
+    else
+      hfile = INVALID_HANDLE_VALUE;
+  }
+#else
   hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
   return hfile;
+
 #else /*!HAVE_W32_SYSTEM*/
+
   int oflag;
-  int cflag = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  int cflag = S_IRUSR | S_IWUSR;
+
+  if (!mode700)
+    cflag |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
 
   /* Note, that we do not handle all mode combinations */
   if (strchr (mode, '+'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       oflag = O_RDWR;
     }
   else if (strchr (mode, 'w'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       oflag = O_WRONLY | O_CREAT | O_TRUNC;
     }
   else
@@ -341,21 +329,18 @@ direct_open (const char *fname, const char *mode)
   if (strchr (mode, 'b'))
     oflag |= O_BINARY;
 #endif
-  /* No we need to distinguish between POSIX and RISC OS.  */
-#ifndef __riscos__
-  return open (fname, oflag, cflag);
-#else
+
+#ifdef __riscos__
   {
     struct stat buf;
-    int rc = stat (fname, &buf);
 
     /* Don't allow iobufs on directories */
-    if (!rc && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode))
+    if (!stat (fname, &buf) && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode))
       return __set_errno (EISDIR);
-    else
-      return open (fname, oflag, cflag);
   }
 #endif
+  return open (fname, oflag, cflag);
+
 #endif /*!HAVE_W32_SYSTEM*/
 }
 
@@ -365,7 +350,7 @@ direct_open (const char *fname, const char *mode)
  * Note that this caching strategy only works if the process does not chdir.
  */
 static void
-fd_cache_close (const char *fname, fp_or_fd_t fp)
+fd_cache_close (const char *fname, gnupg_fd_t fp)
 {
   close_cache_t cc;
 
@@ -384,7 +369,7 @@ fd_cache_close (const char *fname, fp_or_fd_t fp)
   /* try to reuse a slot */
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp == INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp == GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
          cc->fp = fp;
          if (DBG_IOBUF)
@@ -405,7 +390,7 @@ fd_cache_close (const char *fname, fp_or_fd_t fp)
 /*
  * Do an direct_open on FNAME but first try to reuse one from the fd_cache
  */
-static fp_or_fd_t
+static gnupg_fd_t
 fd_cache_open (const char *fname, const char *mode)
 {
   close_cache_t cc;
@@ -413,10 +398,10 @@ fd_cache_open (const char *fname, const char *mode)
   assert (fname);
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
-         fp_or_fd_t fp = cc->fp;
-         cc->fp = INVALID_FP;
+         gnupg_fd_t fp = cc->fp;
+         cc->fp = GNUPG_INVALID_FD;
          if (DBG_IOBUF)
            log_debug ("fd_cache_open (%s) using cached fp\n", fname);
 #ifdef HAVE_W32_SYSTEM
@@ -424,13 +409,13 @@ fd_cache_open (const char *fname, const char *mode)
            {
              log_error ("rewind file failed on handle %p: ec=%d\n",
                         fp, (int) GetLastError ());
-             fp = INVALID_FP;
+             fp = GNUPG_INVALID_FD;
            }
 #else
          if (lseek (fp, 0, SEEK_SET) == (off_t) - 1)
            {
              log_error ("can't rewind fd %d: %s\n", fp, strerror (errno));
-             fp = INVALID_FP;
+             fp = GNUPG_INVALID_FD;
            }
 #endif
          return fp;
@@ -438,11 +423,9 @@ fd_cache_open (const char *fname, const char *mode)
     }
   if (DBG_IOBUF)
     log_debug ("fd_cache_open (%s) not cached\n", fname);
-  return direct_open (fname, mode);
+  return direct_open (fname, mode, 0);
 }
 
-#endif /*FILE_FILTER_USES_STDIO */
-
 
 /****************
  * Read data from a file into buf which has an allocated length of *LEN.
@@ -473,78 +456,13 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
             size_t * ret_len)
 {
   file_filter_ctx_t *a = opaque;
-  fp_or_fd_t f = a->fp;
+  gnupg_fd_t f = a->fp;
   size_t size = *ret_len;
   size_t nbytes = 0;
   int rc = 0;
 
   (void)chain; /* Not used.  */
 
-#ifdef FILE_FILTER_USES_STDIO
-  if (control == IOBUFCTRL_UNDERFLOW)
-    {
-      assert (size);  /* We need a buffer. */
-      if (feof (f))
-       {
-          /* On terminals you could easily read as many EOFs as you
-             call fread() or fgetc() repeatly.  Every call will block
-             until you press CTRL-D. So we catch this case before we
-             call fread() again.  */
-         rc = -1;
-         *ret_len = 0;
-       }
-      else
-       {
-         clearerr (f);
-         nbytes = fread (buf, 1, size, f);
-         if (feof (f) && !nbytes)
-           {
-             rc = -1;  /* Okay: we can return EOF now. */
-           }
-         else if (ferror (f) && errno != EPIPE)
-           {
-             rc = gpg_error_from_syserror ();
-             log_error ("%s: read error: %s\n", a->fname, strerror (errno));
-           }
-         *ret_len = nbytes;
-       }
-    }
-  else if (control == IOBUFCTRL_FLUSH)
-    {
-      if (size)
-       {
-         clearerr (f);
-         nbytes = fwrite (buf, 1, size, f);
-         if (ferror (f))
-           {
-             rc = gpg_error_from_syserror ();
-             log_error ("%s: write error: %s\n", a->fname, strerror (errno));
-           }
-       }
-      *ret_len = nbytes;
-    }
-  else if (control == IOBUFCTRL_INIT)
-    {
-      a->keep_open = a->no_cache = 0;
-    }
-  else if (control == IOBUFCTRL_DESC)
-    {
-      *(char **) buf = "file_filter";
-    }
-  else if (control == IOBUFCTRL_FREE)
-    {
-      if (f != stdin && f != stdout)
-       {
-         if (DBG_IOBUF)
-           log_debug ("%s: close fd %d\n", a->fname, fileno (f));
-         if (!a->keep_open)
-           fclose (f);
-       }
-      f = NULL;
-      xfree (a); /* We can free our context now. */
-    }
-#else /* !stdio implementation */
-
   if (control == IOBUFCTRL_UNDERFLOW)
     {
       assert (size); /* We need a buffer.  */
@@ -674,27 +592,107 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
     }
   else if (control == IOBUFCTRL_FREE)
     {
-#ifdef HAVE_W32_SYSTEM
-      if (f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT)
+      if (f != FD_FOR_STDIN && f != FD_FOR_STDOUT)
        {
          if (DBG_IOBUF)
-           log_debug ("%s: close handle %p\n", a->fname, f);
+           log_debug ("%s: close fd/handle %d\n", a->fname, FD2INT (f));
          if (!a->keep_open)
            fd_cache_close (a->no_cache ? NULL : a->fname, f);
        }
-#else
-      if ((int) f != 0 && (int) f != 1)
+      f = GNUPG_INVALID_FD;
+      xfree (a); /* We can free our context now. */
+    }
+
+  return rc;
+}
+
+
+/* Similar to file_filter but using the estream system.  */
+static int
+file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
+                size_t * ret_len)
+{
+  file_es_filter_ctx_t *a = opaque;
+  estream_t f = a->fp;
+  size_t size = *ret_len;
+  size_t nbytes = 0;
+  int rc = 0;
+
+  (void)chain; /* Not used.  */
+
+  if (control == IOBUFCTRL_UNDERFLOW)
+    {
+      assert (size); /* We need a buffer.  */
+      if (a->eof_seen)
+       {
+         rc = -1;
+         *ret_len = 0;
+       }
+      else
+       {
+          nbytes = 0;
+          rc = es_read (f, buf, size, &nbytes);
+         if (rc == -1)
+           {                   /* error */
+              rc = gpg_error_from_syserror ();
+              log_error ("%s: read error: %s\n", a->fname, strerror (errno));
+           }
+         else if (!nbytes)
+           {                   /* eof */
+             a->eof_seen = 1;
+             rc = -1;
+           }
+         *ret_len = nbytes;
+       }
+    }
+  else if (control == IOBUFCTRL_FLUSH)
+    {
+      if (size)
+       {
+         byte *p = buf;
+         size_t nwritten;
+
+         nbytes = size;
+         do
+           {
+              nwritten = 0;
+              if (es_write (f, p, nbytes, &nwritten))
+                {
+                  rc = gpg_error_from_syserror ();
+                  log_error ("%s: write error: %s\n",
+                             a->fname, strerror (errno));
+                  break;
+                }
+              p += nwritten;
+              nbytes -= nwritten;
+           }
+         while (nbytes);
+         nbytes = p - buf;
+       }
+      *ret_len = nbytes;
+    }
+  else if (control == IOBUFCTRL_INIT)
+    {
+      a->eof_seen = 0;
+      a->no_cache = 0;
+    }
+  else if (control == IOBUFCTRL_DESC)
+    {
+      *(char **) buf = "estream_filter";
+    }
+  else if (control == IOBUFCTRL_FREE)
+    {
+      if (f != es_stdin && f != es_stdout)
        {
          if (DBG_IOBUF)
-           log_debug ("%s: close fd %d\n", a->fname, f);
+           log_debug ("%s: es_fclose %p\n", a->fname, f);
          if (!a->keep_open)
-           fd_cache_close (a->no_cache ? NULL : a->fname, f);
+           es_fclose (f);
        }
-      f = INVALID_FP;
-#endif
+      f = NULL;
       xfree (a); /* We can free our context now. */
     }
-#endif /* !stdio implementation. */
+
   return rc;
 }
 
@@ -873,7 +871,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
                    }
                  else if (c == 255)
                    {
-                     a->size = (size_t)iobuf_get (chain) << 24;
+                     a->size = iobuf_get (chain) << 24;
                      a->size |= iobuf_get (chain) << 16;
                      a->size |= iobuf_get (chain) << 8;
                      if ((c = iobuf_get (chain)) == -1)
@@ -1085,7 +1083,7 @@ print_chain (iobuf_t a)
        a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL,
                   (byte *) & desc, &dummy_len);
 
-      log_debug ("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n",
+      log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n",
                 a->no, a->subno, desc?desc:"?", a->filter_eof,
                 (int) a->d.start, (int) a->d.len);
     }
@@ -1143,7 +1141,7 @@ iobuf_close (iobuf_t a)
        log_error ("iobuf_flush failed on close: %s\n", gpg_strerror (rc));
 
       if (DBG_IOBUF)
-       log_debug ("iobuf-%d.%d: close `%s'\n", a->no, a->subno,
+       log_debug ("iobuf-%d.%d: close '%s'\n", a->no, a->subno,
                    a->desc?a->desc:"?");
       if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_FREE,
                                        a->chain, NULL, &dummy_len)))
@@ -1196,7 +1194,14 @@ iobuf_cancel (iobuf_t a)
     {
       /* Argg, MSDOS does not allow to remove open files.  So
        * we have to do it here */
+#ifdef HAVE_W32CE_SYSTEM
+      wchar_t *wtmp = utf8_to_wchar (remove_name);
+      if (wtmp)
+        DeleteFile (wtmp);
+      xfree (wtmp);
+#else
       remove (remove_name);
+#endif
       xfree (remove_name);
     }
 #endif
@@ -1278,18 +1283,10 @@ iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, const char *mode)
 {
   iobuf_t a;
 
-  if (fd == -1)
+  if (fd == GNUPG_INVALID_FD)
     a = iobuf_open (fname);
   else
-    {
-      int fd2;
-
-      fd2 = dup (fd);
-      if (fd2 == -1)
-        a = NULL;
-      else
-        a = iobuf_fdopen (fd2, mode);
-    }
+    a = iobuf_fdopen_nc (FD2INT(fd), mode);
   return a;
 }
 
@@ -1302,24 +1299,21 @@ iobuf_t
 iobuf_open (const char *fname)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
-  size_t len = 0;
+  size_t len;
   int print_only = 0;
   int fd;
 
   if (!fname || (*fname == '-' && !fname[1]))
     {
-      fp = FILEP_OR_FD_FOR_STDIN;
-#ifdef USE_SETMODE
-      setmode (my_fileno (fp), O_BINARY);
-#endif
+      fp = FD_FOR_STDIN;
       fname = "[stdin]";
       print_only = 1;
     }
   else if ((fd = check_special_filename (fname)) != -1)
     return iobuf_fdopen (translate_file_handle (fd, 0), "rb");
-  else if ((fp = my_fopen_ro (fname, "rb")) == INVALID_FP)
+  else if ((fp = fd_cache_open (fname, "rb")) == GNUPG_INVALID_FD)
     return NULL;
   a = iobuf_alloc (1, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + strlen (fname));
@@ -1333,42 +1327,76 @@ iobuf_open (const char *fname)
   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: open `%s' fd=%d\n",
-              a->no, a->subno, fname, (int) my_fileno (fcx->fp));
+    log_debug ("iobuf-%d.%d: open '%s' fd=%d\n",
+              a->no, a->subno, fname, FD2INT (fcx->fp));
 
   return a;
 }
 
-/****************
- * Create a head iobuf for reading from a file
- * returns: NULL if an error occures and sets errno
- */
-iobuf_t
-iobuf_fdopen (int fd, const char *mode)
+
+static iobuf_t
+do_iobuf_fdopen (int fd, const char *mode, int keep_open)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
 
-#ifdef FILE_FILTER_USES_STDIO
-  if (!(fp = fdopen (fd, mode)))
-    return NULL;
-#else
-  fp = (fp_or_fd_t) fd;
-#endif
+  fp = INT2FD (fd);
+
   a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + 20);
   fcx->fp = fp;
   fcx->print_only_name = 1;
+  fcx->keep_open = keep_open;
   sprintf (fcx->fname, "[fd %d]", fd);
   a->filter = file_filter;
   a->filter_ov = fcx;
   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname);
-  iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
+    log_debug ("iobuf-%d.%d: fdopen%s '%s'\n",
+               a->no, a->subno, keep_open? "_nc":"", fcx->fname);
+  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
+  return a;
+}
+
+
+/* Create a head iobuf for reading or writing from/to a file Returns:
+ * NULL and sets ERRNO if an error occured.  */
+iobuf_t
+iobuf_fdopen (int fd, const char *mode)
+{
+  return do_iobuf_fdopen (fd, mode, 0);
+}
+
+iobuf_t
+iobuf_fdopen_nc (int fd, const char *mode)
+{
+  return do_iobuf_fdopen (fd, mode, 1);
+}
+
+
+iobuf_t
+iobuf_esopen (estream_t estream, const char *mode, int keep_open)
+{
+  iobuf_t a;
+  file_es_filter_ctx_t *fcx;
+  size_t len;
+
+  a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE);
+  fcx = xtrymalloc (sizeof *fcx + 30);
+  fcx->fp = estream;
+  fcx->print_only_name = 1;
+  fcx->keep_open = keep_open;
+  sprintf (fcx->fname, "[fd %p]", estream);
+  a->filter = file_es_filter;
+  a->filter_ov = fcx;
+  file_es_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
+  file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
+  if (DBG_IOBUF)
+    log_debug ("iobuf-%d.%d: esopen%s '%s'\n",
+               a->no, a->subno, keep_open? "_nc":"", fcx->fname);
   return a;
 }
 
@@ -1391,8 +1419,8 @@ iobuf_sockopen (int fd, const char *mode)
   sock_filter (scx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
-  iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
+    log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname);
+  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
 #else
   a = iobuf_fdopen (fd, mode);
 #endif
@@ -1400,13 +1428,14 @@ iobuf_sockopen (int fd, const char *mode)
 }
 
 /****************
- * create an iobuf for writing to a file; the file will be created.
+ * Create an iobuf for writing to a file; the file will be created.
+ * With MODE700 set the file is created with that mode (Unix only).
  */
 iobuf_t
-iobuf_create (const char *fname)
+iobuf_create (const char *fname, int mode700)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
   int print_only = 0;
@@ -1414,16 +1443,13 @@ iobuf_create (const char *fname)
 
   if (!fname || (*fname == '-' && !fname[1]))
     {
-      fp = FILEP_OR_FD_FOR_STDOUT;
-#ifdef USE_SETMODE
-      setmode (my_fileno (fp), O_BINARY);
-#endif
+      fp = FD_FOR_STDOUT;
       fname = "[stdout]";
       print_only = 1;
     }
   else if ((fd = check_special_filename (fname)) != -1)
     return iobuf_fdopen (translate_file_handle (fd, 1), "wb");
-  else if ((fp = my_fopen (fname, "wb")) == INVALID_FP)
+  else if ((fp = direct_open (fname, "wb", mode700)) == GNUPG_INVALID_FD)
     return NULL;
   a = iobuf_alloc (2, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + strlen (fname));
@@ -1437,58 +1463,24 @@ iobuf_create (const char *fname)
   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: create `%s'\n", a->no, a->subno,
+    log_debug ("iobuf-%d.%d: create '%s'\n", a->no, a->subno,
                a->desc?a->desc:"?");
 
   return a;
 }
 
-/****************
- * append to an iobuf; if the file does not exist, create it.
- * cannot be used for stdout.
- * Note: This is not used.
- */
-#if 0                          /* not used */
-iobuf_t
-iobuf_append (const char *fname)
-{
-  iobuf_t a;
-  FILE *fp;
-  file_filter_ctx_t *fcx;
-  size_t len;
-
-  if (!fname)
-    return NULL;
-  else if (!(fp = my_fopen (fname, "ab")))
-    return NULL;
-  a = iobuf_alloc (2, IOBUF_BUFFER_SIZE);
-  fcx = m_alloc (sizeof *fcx + strlen (fname));
-  fcx->fp = fp;
-  strcpy (fcx->fname, fname);
-  a->real_fname = m_strdup (fname);
-  a->filter = file_filter;
-  a->filter_ov = fcx;
-  file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
-  file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
-  if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: append `%s'\n", a->no, a->subno,
-               a->desc?a->desc:"?");
-
-  return a;
-}
-#endif
 
 iobuf_t
 iobuf_openrw (const char *fname)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
 
   if (!fname)
     return NULL;
-  else if ((fp = my_fopen (fname, "r+b")) == INVALID_FP)
+  else if ((fp = direct_open (fname, "r+b", 0)) == GNUPG_INVALID_FD)
     return NULL;
   a = iobuf_alloc (2, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + strlen (fname));
@@ -1500,7 +1492,7 @@ iobuf_openrw (const char *fname)
   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno,
+    log_debug ("iobuf-%d.%d: openrw '%s'\n", a->no, a->subno,
                a->desc?a->desc:"?");
 
   return a;
@@ -1508,12 +1500,15 @@ iobuf_openrw (const char *fname)
 
 
 int
-iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
+iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
 {
-  if (cmd == 1)
-    {                          /* keep system filepointer/descriptor open */
+  if (cmd == IOBUF_IOCTL_KEEP_OPEN)
+    {
+      /* Keep system filepointer/descriptor open.  This was used in
+         the past by http.c; this ioctl is not directly used
+         anymore.  */
       if (DBG_IOBUF)
-       log_debug ("iobuf-%d.%d: ioctl `%s' keep=%d\n",
+       log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n",
                   a ? a->no : -1, a ? a->subno : -1,
                    a && a->desc ? a->desc : "?",
                   intval);
@@ -1533,24 +1528,22 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
          }
 #endif
     }
-  else if (cmd == 2)
-    {                          /* invalidate cache */
+  else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
+    {
       if (DBG_IOBUF)
-       log_debug ("iobuf-*.*: ioctl `%s' invalidate\n",
+       log_debug ("iobuf-*.*: ioctl '%s' invalidate\n",
                   ptrval ? (char *) ptrval : "?");
       if (!a && !intval && ptrval)
        {
-#ifndef FILE_FILTER_USES_STDIO
          if (fd_cache_invalidate (ptrval))
             return -1;
-#endif
          return 0;
        }
     }
-  else if (cmd == 3)
-    {                          /* disallow/allow caching */
+  else if (cmd == IOBUF_IOCTL_NO_CACHE)
+    {
       if (DBG_IOBUF)
-       log_debug ("iobuf-%d.%d: ioctl `%s' no_cache=%d\n",
+       log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n",
                   a ? a->no : -1, a ? a->subno : -1,
                    a && a->desc? a->desc : "?",
                   intval);
@@ -1570,21 +1563,17 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
          }
 #endif
     }
-  else if (cmd == 4)
+  else if (cmd == IOBUF_IOCTL_FSYNC)
     {
       /* Do a fsync on the open fd and return any errors to the caller
          of iobuf_ioctl.  Note that we work on a file name here. */
       if (DBG_IOBUF)
-        log_debug ("iobuf-*.*: ioctl `%s' fsync\n",
+        log_debug ("iobuf-*.*: ioctl '%s' fsync\n",
                    ptrval? (const char*)ptrval:"<null>");
 
        if (!a && !intval && ptrval)
          {
-#ifndef FILE_FILTER_USES_STDIO
            return fd_cache_synchronize (ptrval);
-#else
-           return 0;
-#endif
          }
       }
 
@@ -1678,7 +1667,7 @@ iobuf_push_filter2 (iobuf_t a,
 
   if (DBG_IOBUF)
     {
-      log_debug ("iobuf-%d.%d: push `%s'\n", a->no, a->subno,
+      log_debug ("iobuf-%d.%d: push '%s'\n", a->no, a->subno,
                  a->desc?a->desc:"?");
       print_chain (a);
     }
@@ -1706,7 +1695,7 @@ pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
     BUG ();
 
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: pop `%s'\n", a->no, a->subno,
+    log_debug ("iobuf-%d.%d: pop '%s'\n", a->no, a->subno,
                a->desc?a->desc:"?");
   if (!a->filter)
     {                          /* this is simple */
@@ -1793,7 +1782,7 @@ underflow (iobuf_t a)
        {
          iobuf_t b = a->chain;
          if (DBG_IOBUF)
-           log_debug ("iobuf-%d.%d: pop `%s' in underflow\n",
+           log_debug ("iobuf-%d.%d: pop '%s' in underflow\n",
                       a->no, a->subno, a->desc?a->desc:"?");
          xfree (a->d.buf);
          xfree (a->real_fname);
@@ -2201,9 +2190,9 @@ iobuf_get_filelength (iobuf_t a, int *overflow)
     if ( !a->chain && a->filter == file_filter )
       {
         file_filter_ctx_t *b = a->filter_ov;
-        fp_or_fd_t fp = b->fp;
+        gnupg_fd_t fp = b->fp;
 
-#if defined(HAVE_W32_SYSTEM) && !defined(FILE_FILTER_USES_STDIO)
+#if defined(HAVE_W32_SYSTEM)
         ulong size;
         static int (* __stdcall get_file_size_ex) (void *handle,
                                                    LARGE_INTEGER *r_size);
@@ -2247,7 +2236,7 @@ iobuf_get_filelength (iobuf_t a, int *overflow)
         log_error ("GetFileSize for handle %p failed: %s\n",
                    fp, w32_strerror (0));
 #else
-        if ( !fstat(my_fileno(fp), &st) )
+        if ( !fstat (FD2INT (fp), &st) )
           return st.st_size;
         log_error("fstat() failed: %s\n", strerror(errno) );
 #endif
@@ -2270,9 +2259,9 @@ iobuf_get_fd (iobuf_t a)
     if (!a->chain && a->filter == file_filter)
       {
         file_filter_ctx_t *b = a->filter_ov;
-        fp_or_fd_t fp = b->fp;
+        gnupg_fd_t fp = b->fp;
 
-        return my_fileno (fp);
+        return FD2INT (fp);
       }
 
   return -1;
@@ -2339,7 +2328,7 @@ iobuf_seek (iobuf_t a, off_t newpos)
        }
       clearerr (fp);
     }
-  else
+  else if (a->use != 3)  /* Not a temp stream.  */
     {
       for (; a; a = a->chain)
        {
@@ -2351,13 +2340,6 @@ iobuf_seek (iobuf_t a, off_t newpos)
        }
       if (!a)
        return -1;
-#ifdef FILE_FILTER_USES_STDIO
-      if (fseeko (b->fp, newpos, SEEK_SET))
-       {
-         log_error ("can't fseek: %s\n", strerror (errno));
-         return -1;
-       }
-#else
 #ifdef HAVE_W32_SYSTEM
       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
        {
@@ -2372,9 +2354,9 @@ iobuf_seek (iobuf_t a, off_t newpos)
          return -1;
        }
 #endif
-#endif
     }
-  a->d.len = 0;                        /* discard buffer */
+  if (a->use != 3)
+    a->d.len = 0;      /* Discard the buffer  unless it is a temp stream.  */
   a->d.start = 0;
   a->nbytes = 0;
   a->nlimit = 0;
@@ -2396,7 +2378,9 @@ iobuf_seek (iobuf_t a, off_t newpos)
 
 
 /****************
- * Retrieve the real filename
+ * Retrieve the real filename.  This is the filename actually used on
+ * disk and not a made up one.  Returns NULL if no real filename is
+ * available.
  */
 const char *
 iobuf_get_real_fname (iobuf_t a)
@@ -2417,7 +2401,7 @@ iobuf_get_real_fname (iobuf_t a)
 
 
 /****************
- * Retrieve the filename
+ * Retrieve the filename.  This name should only be used in diagnostics.
  */
 const char *
 iobuf_get_fname (iobuf_t a)
@@ -2431,6 +2415,16 @@ iobuf_get_fname (iobuf_t a)
   return NULL;
 }
 
+/* Same as iobuf_get_fname but never returns NULL.  */
+const char *
+iobuf_get_fname_nonnull (iobuf_t a)
+{
+  const char *fname;
+
+  fname = iobuf_get_fname (a);
+  return fname? fname : "[?]";
+}
+
 
 /****************
  * enable partial block mode as described in the OpenPGP draft.
@@ -2527,10 +2521,12 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
 static int
 translate_file_handle (int fd, int for_write)
 {
-#ifdef HAVE_W32_SYSTEM
-# ifdef FILE_FILTER_USES_STDIO
-  fd = translate_sys2libc_fd (fd, for_write);
-# else
+#if defined(HAVE_W32CE_SYSTEM)
+  /* This is called only with one of the special filenames.  Under
+     W32CE the FD here is not a file descriptor but a rendezvous id,
+     thus we need to finish the pipe first.  */
+  fd = _assuan_w32ce_finish_pipe (fd, for_write);
+#elif defined(HAVE_W32_SYSTEM)
   {
     int x;
 
@@ -2551,7 +2547,6 @@ translate_file_handle (int fd, int for_write)
 
     fd = x;
   }
-# endif
 #else
   (void)for_write;
 #endif
index 8a3671e..3889459 100644 (file)
@@ -1,14 +1,25 @@
 /* iobuf.h - I/O buffer
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003,
+ *               2010 Free Software Foundation, Inc.
  *
- * This file is part of GNUPG.
+ * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GNUPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #ifndef GNUPG_COMMON_IOBUF_H
 #define GNUPG_COMMON_IOBUF_H
 
-#include "../include/types.h" /* fixme: should be moved elsewhere. */
-
+#include "../common/types.h"
+#include "../common/sysutils.h"
 
 #define DBG_IOBUF   iobuf_debug_mode
 
-
+/* Filter control modes.  */
 #define IOBUFCTRL_INIT     1
 #define IOBUFCTRL_FREE     2
 #define IOBUFCTRL_UNDERFLOW 3
 #define IOBUFCTRL_CANCEL    6
 #define IOBUFCTRL_USER     16
 
+
+/* Command codes for iobuf_ioctl.  */
+typedef enum
+  {
+    IOBUF_IOCTL_KEEP_OPEN        = 1, /* Uses intval.  */
+    IOBUF_IOCTL_INVALIDATE_CACHE = 2, /* Uses ptrval.  */
+    IOBUF_IOCTL_NO_CACHE         = 3, /* Uses intval.  */
+    IOBUF_IOCTL_FSYNC            = 4  /* Uses ptrval.  */
+  } iobuf_ioctl_t;
+
+
 typedef struct iobuf_struct *iobuf_t;
 typedef struct iobuf_struct *IOBUF;  /* Compatibility with gpg 1.4. */
 
@@ -85,13 +107,17 @@ int  iobuf_is_pipe_filename (const char *fname);
 iobuf_t iobuf_alloc (int use, size_t bufsize);
 iobuf_t iobuf_temp (void);
 iobuf_t iobuf_temp_with_content (const char *buffer, size_t length);
+iobuf_t iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname,
+                               const char *mode);
 iobuf_t iobuf_open (const char *fname);
 iobuf_t iobuf_fdopen (int fd, const char *mode);
+iobuf_t iobuf_fdopen_nc (int fd, const char *mode);
+iobuf_t iobuf_esopen (estream_t estream, const char *mode, int keep_open);
 iobuf_t iobuf_sockopen (int fd, const char *mode);
-iobuf_t iobuf_create (const char *fname);
+iobuf_t iobuf_create (const char *fname, int mode700);
 iobuf_t iobuf_append (const char *fname);
 iobuf_t iobuf_openrw (const char *fname);
-int iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval);
+int iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval);
 int iobuf_close (iobuf_t iobuf);
 int iobuf_cancel (iobuf_t iobuf);
 
@@ -131,16 +157,17 @@ off_t iobuf_get_filelength (iobuf_t a, int *overflow);
 int  iobuf_get_fd (iobuf_t a);
 const char *iobuf_get_real_fname (iobuf_t a);
 const char *iobuf_get_fname (iobuf_t a);
+const char *iobuf_get_fname_nonnull (iobuf_t a);
 
 void iobuf_set_partial_block_mode (iobuf_t a, size_t len);
 
 void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial);
 
 
-/* get a byte form the iobuf; must check for eof prior to this function
- * this function returns values in the range 0 .. 255 or -1 to indicate EOF
- * iobuf_get_noeof() does not return -1 to indicate EOF, but masks the
- * returned value to be in the range 0 ..255.
+/* Get a byte from the iobuf; must check for eof prior to this
+ * function.  This function returns values in the range 0 .. 255 or -1
+ * to indicate EOF.  iobuf_get_noeof() does not return -1 to indicate
+ * EOF, but masks the returned value to be in the range 0 .. 255.
  */
 #define iobuf_get(a)  \
      ( ((a)->nofast || (a)->d.start >= (a)->d.len )?  \
index 6455e8c..d286f7d 100644 (file)
@@ -1,5 +1,5 @@
 /* keyserver.h - Public definitions for gpg keyserver helpers.
- * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 /* Must be 127 due to shell internal magic. */
 #define KEYSERVER_SCHEME_NOT_FOUND 127
 
+/* Object to hold information pertaining to a keyserver; it further
+   allows to build a list of keyservers.  Note that g10/options.h has
+   a typedef for this.  FIXME: We should make use of the
+   parse_uri_t. */
+struct keyserver_spec
+{
+  struct keyserver_spec *next;
+  char *uri;
+  char *scheme;
+  char *auth;
+  char *host;
+  char *port;
+  char *path;
+  char *opaque;
+  strlist_t options;
+  struct
+  {
+    unsigned int direct_uri:1;
+  } flags;
+};
+
+
 #endif /*GNUPG_COMMON_KEYSERVER_H*/
similarity index 64%
rename from jnlib/libjnlib-config.h
rename to common/libjnlib-config.h
index 5c61442..85be87f 100644 (file)
@@ -1,20 +1,31 @@
 /* libjnlib-config.h - local configuration of the jnlib functions
  *     Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 /****************
@@ -39,7 +50,7 @@
 
 /* Gettext stuff */
 #ifdef USE_SIMPLE_GETTEXT
-# include "w32help.h"
+# include <gpg-error.h>
 # define _(a) gettext (a)
 # define N_(a) (a)
 
 #define jnlib_log_fatal    log_fatal
 #define jnlib_log_bug     log_bug
 
+/* Wrapper to set ERRNO.  */
+#ifdef HAVE_W32CE_SYSTEM
+# define jnlib_set_errno(e)  gpg_err_set_errno ((e))
+#else
+# define jnlib_set_errno(e)  do { errno = (e); } while (0)
+#endif
+
+/* Dummy replacement for getenv.  */
+#ifndef HAVE_GETENV
+#define getenv(a)  (NULL)
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+#define getpid() GetCurrentProcessId ()
+#endif
 
 #endif /*LIBJNUTIL_CONFIG_H*/
index cb7fcc2..54d22d0 100644 (file)
@@ -1,23 +1,33 @@
 /* localename.c - Determine the current selected locale.
-   Copyright (C) 1995-1999, 2000-2003, 2007, 
-                 2008 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License
-   as published by the Free Software Foundation; either version 2.1,
-   or (at your option) any later version.
-
-   This program 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
+ * Copyright (C) 1995-1999, 2000-2003, 2007,
+ *               2008 Free Software Foundation, Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
 /* Written by Ulrich Drepper <drepper@gnu.org>, 1995.  */
 /* Win32 code written by Tor Lillqvist <tml@iki.fi>.  */
-/* Modified for GpgOL use by Werner Koch <wk@gnupg.org>, 2005.  */ 
+/* Modified for GpgOL use by Werner Koch <wk@gnupg.org>, 2005.  */
 /* Modified for GnuPG use by Werner Koch <wk@gnupg.org>, 2007 */
 
 #ifdef HAVE_CONFIG_H
@@ -29,8 +39,9 @@
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
+#include <gpg-error.h> /* We need gettext_localename for W32. */
 
-#include "../jnlib/w32help.h"
+#include "../common/w32help.h"
 
 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
    "Directs 'setlocale()' to query 'category' and return the current
@@ -43,7 +54,7 @@
 #endif
 
 /* Use a dummy value for LC_MESSAGES in case it is not defined.  This
-   works becuase we always test for HAVE_LC_MESSAGES and the core
+   works because we always test for HAVE_LC_MESSAGES and the core
    fucntion takes the category as a string as well.  */
 #ifndef HAVE_LC_MESSAGES
 #define LC_MESSAGES 0
@@ -67,7 +78,7 @@ do_nl_locale_name (int category, const char *categoryname)
 # if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
   (void)categoryname;
   retval = setlocale (category, NULL);
-# else 
+# else
   /* Setting of LC_ALL overwrites all other.  */
   retval = getenv ("LC_ALL");
   if (retval == NULL || retval[0] == '\0')
@@ -101,7 +112,7 @@ gnupg_messages_locale_name (void)
   const char *s;
 
 #ifdef HAVE_W32_SYSTEM
-  /* We use the localname function from ../jnlib/w32-gettext.c. */
+  /* We use the localename function libgpg-error.  */
   s = gettext_localename ();
 #else
   s = do_nl_locale_name (LC_MESSAGES, "LC_MESSAGES");
@@ -113,4 +124,3 @@ gnupg_messages_locale_name (void)
 
   return s;
 }
-
diff --git a/common/logging.c b/common/logging.c
new file mode 100644 (file)
index 0000000..40d098c
--- /dev/null
@@ -0,0 +1,935 @@
+/* logging.c - Useful logging functions
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+ *               2009, 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_W32_SYSTEM
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
+# include <windows.h>
+#else /*!HAVE_W32_SYSTEM*/
+# include <sys/socket.h>
+# include <sys/un.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif /*!HAVE_W32_SYSTEM*/
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+
+
+#define JNLIB_NEED_LOG_LOGV 1
+#define JNLIB_NEED_AFLOCAL 1
+#include "libjnlib-config.h"
+#include "logging.h"
+
+#ifdef HAVE_W32_SYSTEM
+# define S_IRGRP S_IRUSR
+# define S_IROTH S_IRUSR
+# define S_IWGRP S_IWUSR
+# define S_IWOTH S_IWUSR
+#endif
+
+
+#ifdef HAVE_W32CE_SYSTEM
+# define isatty(a)  (0)
+#endif
+
+#undef WITH_IPV6
+#if defined (AF_INET6) && defined(PF_INET) \
+    && defined (INET6_ADDRSTRLEN) && defined(HAVE_INET_PTON)
+# define WITH_IPV6 1
+#endif
+
+#ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT EINVAL
+#endif
+#ifndef INADDR_NONE  /* Slowaris is missing that.  */
+#define INADDR_NONE  ((unsigned long)(-1))
+#endif /*INADDR_NONE*/
+
+#ifdef HAVE_W32_SYSTEM
+#define sock_close(a)  closesocket(a)
+#else
+#define sock_close(a)  close(a)
+#endif
+
+
+static estream_t logstream;
+static int log_socket = -1;
+static char prefix_buffer[80];
+static int with_time;
+static int with_prefix;
+static int with_pid;
+#ifdef HAVE_W32_SYSTEM
+static int no_registry;
+#endif
+static int (*get_pid_suffix_cb)(unsigned long *r_value);
+static int running_detached;
+static int force_prefixes;
+
+static int missing_lf;
+static int errorcount;
+
+
+int
+log_get_errorcount (int clear)
+{
+    int n = errorcount;
+    if( clear )
+       errorcount = 0;
+    return n;
+}
+
+void
+log_inc_errorcount (void)
+{
+   errorcount++;
+}
+
+
+/* The following 3 functions are used by es_fopencookie to write logs
+   to a socket.  */
+struct fun_cookie_s
+{
+  int fd;
+  int quiet;
+  int want_socket;
+  int is_socket;
+#ifdef HAVE_W32CE_SYSTEM
+  int use_writefile;
+#endif
+  char name[1];
+};
+
+
+/* Write NBYTES of BUFFER to file descriptor FD. */
+static int
+writen (int fd, const void *buffer, size_t nbytes, int is_socket)
+{
+  const char *buf = buffer;
+  size_t nleft = nbytes;
+  int nwritten;
+#ifndef HAVE_W32_SYSTEM
+  (void)is_socket; /* Not required.  */
+#endif
+
+  while (nleft > 0)
+    {
+#ifdef HAVE_W32_SYSTEM
+      if (is_socket)
+        nwritten = send (fd, buf, nleft, 0);
+      else
+#endif
+        nwritten = write (fd, buf, nleft);
+
+      if (nwritten < 0 && errno == EINTR)
+        continue;
+      if (nwritten < 0)
+        return -1;
+      nleft -= nwritten;
+      buf = buf + nwritten;
+    }
+
+  return 0;
+}
+
+
+/* Returns true if STR represents a valid port number in decimal
+   notation and no garbage is following.  */
+static int
+parse_portno (const char *str, unsigned short *r_port)
+{
+  unsigned int value;
+
+  for (value=0; *str && (*str >= '0' && *str <= '9'); str++)
+    {
+      value = value * 10 + (*str - '0');
+      if (value > 65535)
+        return 0;
+    }
+  if (*str || !value)
+    return 0;
+
+  *r_port = value;
+  return 1;
+}
+
+
+static ssize_t
+fun_writer (void *cookie_arg, const void *buffer, size_t size)
+{
+  struct fun_cookie_s *cookie = cookie_arg;
+
+  /* FIXME: Use only estream with a callback for socket writing.  This
+     avoids the ugly mix of fd and estream code.  */
+
+  /* Note that we always try to reconnect to the socket but print
+     error messages only the first time an error occured.  If
+     RUNNING_DETACHED is set we don't fall back to stderr and even do
+     not print any error messages.  This is needed because detached
+     processes often close stderr and by writing to file descriptor 2
+     we might send the log message to a file not intended for logging
+     (e.g. a pipe or network connection). */
+  if (cookie->want_socket && cookie->fd == -1)
+    {
+#ifdef WITH_IPV6
+      struct sockaddr_in6 srvr_addr_in6;
+#endif
+      struct sockaddr_in srvr_addr_in;
+#ifndef HAVE_W32_SYSTEM
+      struct sockaddr_un srvr_addr_un;
+#endif
+      size_t addrlen;
+      struct sockaddr *srvr_addr = NULL;
+      unsigned short port = 0;
+      int af = AF_LOCAL;
+      int pf = PF_LOCAL;
+      const char *name = cookie->name;
+
+      /* Not yet open or meanwhile closed due to an error. */
+      cookie->is_socket = 0;
+
+      /* Check whether this is a TCP socket or a local socket.  */
+      if (!strncmp (name, "tcp://", 6) && name[6])
+        {
+          name += 6;
+          af = AF_INET;
+          pf = PF_INET;
+        }
+#ifndef HAVE_W32_SYSTEM
+      else if (!strncmp (name, "socket://", 9) && name[9])
+        name += 9;
+#endif
+
+      if (af == AF_LOCAL)
+        {
+#ifdef HAVE_W32_SYSTEM
+          addrlen = 0;
+#else
+          memset (&srvr_addr, 0, sizeof srvr_addr);
+          srvr_addr_un.sun_family = af;
+          strncpy (srvr_addr_un.sun_path,
+                   name, sizeof (srvr_addr_un.sun_path)-1);
+          srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0;
+          srvr_addr = (struct sockaddr *)&srvr_addr_un;
+          addrlen = SUN_LEN (&srvr_addr_un);
+#endif
+        }
+      else
+        {
+          char *addrstr, *p;
+#ifdef HAVE_INET_PTON
+          void *addrbuf = NULL;
+#endif /*HAVE_INET_PTON*/
+
+          addrstr = jnlib_malloc (strlen (name) + 1);
+          if (!addrstr)
+            addrlen = 0; /* This indicates an error.  */
+          else if (*name == '[')
+            {
+              /* Check for IPv6 literal address.  */
+              strcpy (addrstr, name+1);
+              p = strchr (addrstr, ']');
+              if (!p || p[1] != ':' || !parse_portno (p+2, &port))
+                {
+                  jnlib_set_errno (EINVAL);
+                  addrlen = 0;
+                }
+              else
+                {
+                  *p = 0;
+#ifdef WITH_IPV6
+                  af = AF_INET6;
+                  pf = PF_INET6;
+                  memset (&srvr_addr_in6, 0, sizeof srvr_addr_in6);
+                  srvr_addr_in6.sin6_family = af;
+                  srvr_addr_in6.sin6_port = htons (port);
+#ifdef HAVE_INET_PTON
+                  addrbuf = &srvr_addr_in6.sin6_addr;
+#endif /*HAVE_INET_PTON*/
+                  srvr_addr = (struct sockaddr *)&srvr_addr_in6;
+                  addrlen = sizeof srvr_addr_in6;
+#else
+                  jnlib_set_errno (EAFNOSUPPORT);
+                  addrlen = 0;
+#endif
+                }
+            }
+          else
+            {
+              /* Check for IPv4 literal address.  */
+              strcpy (addrstr, name);
+              p = strchr (addrstr, ':');
+              if (!p || !parse_portno (p+1, &port))
+                {
+                  jnlib_set_errno (EINVAL);
+                  addrlen = 0;
+                }
+              else
+                {
+                  *p = 0;
+                  memset (&srvr_addr_in, 0, sizeof srvr_addr_in);
+                  srvr_addr_in.sin_family = af;
+                  srvr_addr_in.sin_port = htons (port);
+#ifdef HAVE_INET_PTON
+                  addrbuf = &srvr_addr_in.sin_addr;
+#endif /*HAVE_INET_PTON*/
+                  srvr_addr = (struct sockaddr *)&srvr_addr_in;
+                  addrlen = sizeof srvr_addr_in;
+                }
+            }
+
+          if (addrlen)
+            {
+#ifdef HAVE_INET_PTON
+              if (inet_pton (af, addrstr, addrbuf) != 1)
+                addrlen = 0;
+#else /*!HAVE_INET_PTON*/
+              /* We need to use the old function.  If we are here v6
+                 support isn't enabled anyway and thus we can do fine
+                 without.  Note that Windows has a compatible inet_pton
+                 function named inetPton, but only since Vista.  */
+              srvr_addr_in.sin_addr.s_addr = inet_addr (addrstr);
+              if (srvr_addr_in.sin_addr.s_addr == INADDR_NONE)
+                addrlen = 0;
+#endif /*!HAVE_INET_PTON*/
+            }
+
+          jnlib_free (addrstr);
+        }
+
+      cookie->fd = addrlen? socket (pf, SOCK_STREAM, 0) : -1;
+      if (cookie->fd == -1)
+        {
+          if (!cookie->quiet && !running_detached
+              && isatty (es_fileno (es_stderr)))
+            es_fprintf (es_stderr, "failed to create socket for logging: %s\n",
+                        strerror(errno));
+        }
+      else
+        {
+          if (connect (cookie->fd, srvr_addr, addrlen) == -1)
+            {
+              if (!cookie->quiet && !running_detached
+                  && isatty (es_fileno (es_stderr)))
+                es_fprintf (es_stderr, "can't connect to '%s': %s\n",
+                            cookie->name, strerror(errno));
+              sock_close (cookie->fd);
+              cookie->fd = -1;
+            }
+        }
+
+      if (cookie->fd == -1)
+        {
+          if (!running_detached)
+            {
+              /* Due to all the problems with apps not running
+                 detached but being called with stderr closed or used
+                 for a different purposes, it does not make sense to
+                 switch to stderr.  We therefore disable it. */
+              if (!cookie->quiet)
+                {
+                  /* fputs ("switching logging to stderr\n", stderr);*/
+                  cookie->quiet = 1;
+                }
+              cookie->fd = -1; /*fileno (stderr);*/
+            }
+        }
+      else /* Connection has been established. */
+        {
+          cookie->quiet = 0;
+          cookie->is_socket = 1;
+        }
+    }
+
+  log_socket = cookie->fd;
+  if (cookie->fd != -1)
+    {
+#ifdef HAVE_W32CE_SYSTEM
+      if (cookie->use_writefile)
+        {
+          DWORD nwritten;
+
+          WriteFile ((HANDLE)cookie->fd, buffer, size, &nwritten, NULL);
+          return (ssize_t)size; /* Okay.  */
+        }
+#endif
+      if (!writen (cookie->fd, buffer, size, cookie->is_socket))
+        return (ssize_t)size; /* Okay. */
+    }
+
+  if (!running_detached && cookie->fd != -1
+      && isatty (es_fileno (es_stderr)))
+    {
+      if (*cookie->name)
+        es_fprintf (es_stderr, "error writing to '%s': %s\n",
+                    cookie->name, strerror(errno));
+      else
+        es_fprintf (es_stderr, "error writing to file descriptor %d: %s\n",
+                    cookie->fd, strerror(errno));
+    }
+  if (cookie->is_socket && cookie->fd != -1)
+    {
+      sock_close (cookie->fd);
+      cookie->fd = -1;
+      log_socket = -1;
+    }
+
+  return (ssize_t)size;
+}
+
+
+static int
+fun_closer (void *cookie_arg)
+{
+  struct fun_cookie_s *cookie = cookie_arg;
+
+  if (cookie->fd != -1 && cookie->fd != 2)
+    sock_close (cookie->fd);
+  jnlib_free (cookie);
+  log_socket = -1;
+  return 0;
+}
+
+
+/* Common function to either set the logging to a file or a file
+   descriptor. */
+static void
+set_file_fd (const char *name, int fd)
+{
+  estream_t fp;
+  int want_socket;
+#ifdef HAVE_W32CE_SYSTEM
+  int use_writefile = 0;
+#endif
+  struct fun_cookie_s *cookie;
+
+  /* Close an open log stream.  */
+  if (logstream)
+    {
+      es_fclose (logstream);
+      logstream = NULL;
+    }
+
+  /* Figure out what kind of logging we want.  */
+  if (name && !strcmp (name, "-"))
+    {
+      name = NULL;
+      fd = es_fileno (es_stderr);
+    }
+
+  want_socket = 0;
+  if (name && !strncmp (name, "tcp://", 6) && name[6])
+    want_socket = 1;
+#ifndef HAVE_W32_SYSTEM
+  else if (name && !strncmp (name, "socket://", 9) && name[9])
+    want_socket = 2;
+#endif /*HAVE_W32_SYSTEM*/
+#ifdef HAVE_W32CE_SYSTEM
+  else if (name && !strcmp (name, "GPG2:"))
+    {
+      HANDLE hd;
+
+      ActivateDevice (L"Drivers\\"GNUPG_NAME"_Log", 0);
+      /* Ignore a filename and write the debug output to the GPG2:
+         device.  */
+      hd = CreateFile (L"GPG2:", GENERIC_WRITE,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE,
+                       NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+      fd = (hd == INVALID_HANDLE_VALUE)? -1 : (int)hd;
+      name = NULL;
+      force_prefixes = 1;
+      use_writefile = 1;
+    }
+#endif /*HAVE_W32CE_SYSTEM*/
+
+  /* Setup a new stream.  */
+
+  /* The xmalloc below is justified because we can expect that this
+     function is called only during initialization and there is no
+     easy way out of this error condition.  */
+  cookie = jnlib_xmalloc (sizeof *cookie + (name? strlen (name):0));
+  strcpy (cookie->name, name? name:"");
+  cookie->quiet = 0;
+  cookie->is_socket = 0;
+  cookie->want_socket = want_socket;
+#ifdef HAVE_W32CE_SYSTEM
+  cookie->use_writefile = use_writefile;
+#endif
+  if (!name)
+    cookie->fd = fd;
+  else if (want_socket)
+    cookie->fd = -1;
+  else
+    {
+      do
+        cookie->fd = open (name, O_WRONLY|O_APPEND|O_CREAT,
+                           (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH));
+      while (cookie->fd == -1 && errno == EINTR);
+    }
+  log_socket = cookie->fd;
+
+  {
+    es_cookie_io_functions_t io = { NULL };
+    io.func_write = fun_writer;
+    io.func_close = fun_closer;
+
+    fp = es_fopencookie (cookie, "w", io);
+  }
+
+  /* On error default to a stderr based estream.  */
+  if (!fp)
+    fp = es_stderr;
+
+  es_setvbuf (fp, NULL, _IOLBF, 0);
+
+  logstream = fp;
+
+  /* We always need to print the prefix and the pid for socket mode,
+     so that the server reading the socket can do something
+     meaningful. */
+  force_prefixes = want_socket;
+
+  missing_lf = 0;
+}
+
+
+/* Set the file to write log to.  The special names NULL and "-" may
+   be used to select stderr and names formatted like
+   "socket:///home/foo/mylogs" may be used to write the logging to the
+   socket "/home/foo/mylogs".  If the connection to the socket fails
+   or a write error is detected, the function writes to stderr and
+   tries the next time again to connect the socket.
+  */
+void
+log_set_file (const char *name)
+{
+  set_file_fd (name? name: "-", -1);
+}
+
+void
+log_set_fd (int fd)
+{
+  set_file_fd (NULL, fd);
+}
+
+
+void
+log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value))
+{
+  get_pid_suffix_cb = cb;
+}
+
+
+void
+log_set_prefix (const char *text, unsigned int flags)
+{
+  if (text)
+    {
+      strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1);
+      prefix_buffer[sizeof (prefix_buffer)-1] = 0;
+    }
+
+  with_prefix = (flags & JNLIB_LOG_WITH_PREFIX);
+  with_time = (flags & JNLIB_LOG_WITH_TIME);
+  with_pid  = (flags & JNLIB_LOG_WITH_PID);
+  running_detached = (flags & JNLIB_LOG_RUN_DETACHED);
+#ifdef HAVE_W32_SYSTEM
+  no_registry = (flags & JNLIB_LOG_NO_REGISTRY);
+#endif
+}
+
+
+const char *
+log_get_prefix (unsigned int *flags)
+{
+  if (flags)
+    {
+      *flags = 0;
+      if (with_prefix)
+        *flags |= JNLIB_LOG_WITH_PREFIX;
+      if (with_time)
+        *flags |= JNLIB_LOG_WITH_TIME;
+      if (with_pid)
+        *flags |= JNLIB_LOG_WITH_PID;
+      if (running_detached)
+        *flags |= JNLIB_LOG_RUN_DETACHED;
+#ifdef HAVE_W32_SYSTEM
+      if (no_registry)
+        *flags |= JNLIB_LOG_NO_REGISTRY;
+#endif
+    }
+  return prefix_buffer;
+}
+
+/* This function returns true if the file descriptor FD is in use for
+   logging.  This is preferable over a test using log_get_fd in that
+   it allows the logging code to use more then one file descriptor.  */
+int
+log_test_fd (int fd)
+{
+  if (logstream)
+    {
+      int tmp = es_fileno (logstream);
+      if ( tmp != -1 && tmp == fd)
+        return 1;
+    }
+  if (log_socket != -1 && log_socket == fd)
+    return 1;
+  return 0;
+}
+
+int
+log_get_fd ()
+{
+  return logstream? es_fileno(logstream) : -1;
+}
+
+estream_t
+log_get_stream ()
+{
+  if (!logstream)
+    {
+      log_set_file (NULL); /* Make sure a log stream has been set.  */
+      assert (logstream);
+    }
+  return logstream;
+}
+
+static void
+do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr)
+{
+  if (!logstream)
+    {
+#ifdef HAVE_W32_SYSTEM
+      char *tmp;
+
+      tmp = (no_registry
+             ? NULL
+             : read_w32_registry_string (NULL, GNUPG_REGISTRY_DIR,
+                                         "DefaultLogFile"));
+      log_set_file (tmp && *tmp? tmp : NULL);
+      jnlib_free (tmp);
+#else
+      log_set_file (NULL); /* Make sure a log stream has been set.  */
+#endif
+      assert (logstream);
+    }
+
+  es_flockfile (logstream);
+  if (missing_lf && level != JNLIB_LOG_CONT)
+    es_putc_unlocked ('\n', logstream );
+  missing_lf = 0;
+
+  if (level != JNLIB_LOG_CONT)
+    { /* Note this does not work for multiple line logging as we would
+       * need to print to a buffer first */
+      if (with_time && !force_prefixes)
+        {
+          struct tm *tp;
+          time_t atime = time (NULL);
+
+          tp = localtime (&atime);
+          es_fprintf_unlocked (logstream, "%04d-%02d-%02d %02d:%02d:%02d ",
+                               1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+                               tp->tm_hour, tp->tm_min, tp->tm_sec );
+        }
+      if (with_prefix || force_prefixes)
+        es_fputs_unlocked (prefix_buffer, logstream);
+      if (with_pid || force_prefixes)
+        {
+          unsigned long pidsuf;
+          int pidfmt;
+
+          if (get_pid_suffix_cb && (pidfmt=get_pid_suffix_cb (&pidsuf)))
+            es_fprintf_unlocked (logstream, pidfmt == 1? "[%u.%lu]":"[%u.%lx]",
+                                 (unsigned int)getpid (), pidsuf);
+          else
+            es_fprintf_unlocked (logstream, "[%u]", (unsigned int)getpid ());
+        }
+      if (!with_time || force_prefixes)
+        es_putc_unlocked (':', logstream);
+      /* A leading backspace suppresses the extra space so that we can
+         correctly output, programname, filename and linenumber. */
+      if (fmt && *fmt == '\b')
+        fmt++;
+      else
+        es_putc_unlocked (' ', logstream);
+    }
+
+  switch (level)
+    {
+    case JNLIB_LOG_BEGIN: break;
+    case JNLIB_LOG_CONT: break;
+    case JNLIB_LOG_INFO: break;
+    case JNLIB_LOG_WARN: break;
+    case JNLIB_LOG_ERROR: break;
+    case JNLIB_LOG_FATAL: es_fputs_unlocked ("Fatal: ",logstream ); break;
+    case JNLIB_LOG_BUG:   es_fputs_unlocked ("Ohhhh jeeee: ", logstream); break;
+    case JNLIB_LOG_DEBUG: es_fputs_unlocked ("DBG: ", logstream ); break;
+    default:
+      es_fprintf_unlocked (logstream,"[Unknown log level %d]: ", level);
+      break;
+    }
+
+  if (fmt)
+    {
+      if (ignore_arg_ptr)
+        es_fputs_unlocked (fmt, logstream);
+      else
+        es_vfprintf_unlocked (logstream, fmt, arg_ptr);
+      if (*fmt && fmt[strlen(fmt)-1] != '\n')
+        missing_lf = 1;
+    }
+
+  if (level == JNLIB_LOG_FATAL)
+    {
+      if (missing_lf)
+        es_putc_unlocked ('\n', logstream);
+      es_funlockfile (logstream);
+      exit (2);
+    }
+  else if (level == JNLIB_LOG_BUG)
+    {
+      if (missing_lf)
+        es_putc_unlocked ('\n', logstream );
+      es_funlockfile (logstream);
+      abort ();
+    }
+  else
+    es_funlockfile (logstream);
+}
+
+
+void
+log_log (int level, const char *fmt, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, fmt) ;
+  do_logv (level, 0, fmt, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+void
+log_logv (int level, const char *fmt, va_list arg_ptr)
+{
+  do_logv (level, 0, fmt, arg_ptr);
+}
+
+
+static void
+do_log_ignore_arg (int level, const char *str, ...)
+{
+  va_list arg_ptr;
+  va_start (arg_ptr, str);
+  do_logv (level, 1, str, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+void
+log_string (int level, const char *string)
+{
+  /* We need a dummy arg_ptr, but there is no portable way to create
+     one.  So we call the do_logv function through a variadic wrapper.
+     MB: Why not just use "%s"?  */
+  do_log_ignore_arg (level, string);
+}
+
+
+void
+log_info (const char *fmt, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, fmt);
+  do_logv (JNLIB_LOG_INFO, 0, fmt, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+void
+log_error (const char *fmt, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, fmt);
+  do_logv (JNLIB_LOG_ERROR, 0, fmt, arg_ptr);
+  va_end (arg_ptr);
+  /* Protect against counter overflow.  */
+  if (errorcount < 30000)
+    errorcount++;
+}
+
+
+void
+log_fatal (const char *fmt, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, fmt);
+  do_logv (JNLIB_LOG_FATAL, 0, fmt, arg_ptr);
+  va_end (arg_ptr);
+  abort (); /* Never called; just to make the compiler happy.  */
+}
+
+
+void
+log_bug (const char *fmt, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, fmt);
+  do_logv (JNLIB_LOG_BUG, 0, fmt, arg_ptr);
+  va_end (arg_ptr);
+  abort (); /* Never called; just to make the compiler happy.  */
+}
+
+
+void
+log_debug (const char *fmt, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, fmt);
+  do_logv (JNLIB_LOG_DEBUG, 0, fmt, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+void
+log_printf (const char *fmt, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, fmt);
+  do_logv (fmt ? JNLIB_LOG_CONT : JNLIB_LOG_BEGIN, 0, fmt, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+/* Flush the log - this is useful to make sure that the trailing
+   linefeed has been printed.  */
+void
+log_flush (void)
+{
+  do_log_ignore_arg (JNLIB_LOG_CONT, NULL);
+}
+
+
+/* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
+   dump, with TEXT just an empty string, print a trailing linefeed,
+   otherwise print an entire debug line. */
+void
+log_printhex (const char *text, const void *buffer, size_t length)
+{
+  if (text && *text)
+    log_debug ("%s ", text);
+  if (length)
+    {
+      const unsigned char *p = buffer;
+      log_printf ("%02X", *p);
+      for (length--, p++; length--; p++)
+        log_printf (" %02X", *p);
+    }
+  if (text)
+    log_printf ("\n");
+}
+
+
+/*
+void
+log_printcanon () {}
+is found in sexputils.c
+*/
+
+/*
+void
+log_printsexp () {}
+is found in sexputils.c
+*/
+
+
+void
+log_clock (const char *string)
+{
+#if 0
+  static unsigned long long initial;
+  struct timespec tv;
+  unsigned long long now;
+
+  if (clock_gettime (CLOCK_REALTIME, &tv))
+    {
+      log_debug ("error getting the realtime clock value\n");
+      return;
+    }
+  now = tv.tv_sec * 1000000000ull;
+  now += tv.tv_nsec;
+
+  if (!initial)
+    initial = now;
+
+  log_debug ("[%6llu] %s", (now - initial)/1000, string);
+#else
+  /* You need to link with -ltr to enable the above code.  */
+  log_debug ("[not enabled in the source] %s", string);
+#endif
+}
+
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
+void
+bug_at( const char *file, int line, const char *func )
+{
+  log_log (JNLIB_LOG_BUG, ("... this is a bug (%s:%d:%s)\n"), file, line, func);
+  abort (); /* Never called; just to make the compiler happy.  */
+}
+#else
+void
+bug_at( const char *file, int line )
+{
+  log_log (JNLIB_LOG_BUG, _("you found a bug ... (%s:%d)\n"), file, line);
+  abort (); /* Never called; just to make the compiler happy.  */
+}
+#endif
similarity index 66%
rename from jnlib/logging.h
rename to common/logging.h
index 0b96108..7487b35 100644 (file)
@@ -1,20 +1,32 @@
 /* logging.h
- * Copyright (C) 1999, 2000, 2001, 2004, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 1999, 2000, 2001, 2004, 2006,
+ *               2010 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_LOGGING_H
 
 #include <stdio.h>
 #include "mischelp.h"
+#include "w32help.h"
 
 /* Flag values for log_set_prefix. */
 #define JNLIB_LOG_WITH_PREFIX  1
 #define JNLIB_LOG_WITH_TIME    2
 #define JNLIB_LOG_WITH_PID     4
 #define JNLIB_LOG_RUN_DETACHED 256
+#define JNLIB_LOG_NO_REGISTRY  512
 
 int  log_get_errorcount (int clear);
 void log_inc_errorcount (void);
 void log_set_file( const char *name );
 void log_set_fd (int fd);
-void log_set_get_tid_callback (unsigned long (*cb)(void));
+void log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value));
 void log_set_prefix (const char *text, unsigned int flags);
 const char *log_get_prefix (unsigned int *flags);
 int log_test_fd (int fd);
 int  log_get_fd(void);
-FILE *log_get_stream (void);
+estream_t log_get_stream (void);
 
 #ifdef JNLIB_GCC_M_FUNCTION
   void bug_at( const char *file, int line, const char *func ) JNLIB_GCC_A_NR;
@@ -62,7 +76,9 @@ enum jnlib_log_levels {
     JNLIB_LOG_BUG,
     JNLIB_LOG_DEBUG
 };
+void log_log (int level, const char *fmt, ...) JNLIB_GCC_A_PRINTF(2,3);
 void log_logv (int level, const char *fmt, va_list arg_ptr);
+void log_string (int level, const char *string);
 #endif /*JNLIB_NEED_LOG_LOGV*/
 
 
@@ -72,6 +88,7 @@ void log_error( const char *fmt, ... )        JNLIB_GCC_A_PRINTF(1,2);
 void log_info( const char *fmt, ... )  JNLIB_GCC_A_PRINTF(1,2);
 void log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
 void log_printf( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void log_flush (void);
 
 /* Print a hexdump of BUFFER.  With TEXT passes as NULL print just the
    raw dump, with TEXT being an empty string, print a trailing
@@ -79,10 +96,7 @@ void log_printf( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
    by the hexdump and a final LF.  */
 void log_printhex (const char *text, const void *buffer, size_t length);
 
-
-#endif /*LIBJNLIB_LOGGING_H*/
-
-
-
+void log_clock (const char *string);
 
 
+#endif /*LIBJNLIB_LOGGING_H*/
diff --git a/common/mapstrings.c b/common/mapstrings.c
new file mode 100644 (file)
index 0000000..91795d5
--- /dev/null
@@ -0,0 +1,167 @@
+/* mapstrings.c - Static string mapping
+ * Copyright (C) 2014 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "util.h"
+#include "stringhelp.h"
+#include "membuf.h"
+
+
+static struct {
+  const char *name;
+  const char *value;
+} macros[] = {
+#ifdef PACKAGE_BUGREPORT
+  { "EMAIL", PACKAGE_BUGREPORT },
+#else
+  { "EMAIL", "bug@example.org" },
+#endif
+  { "GNUPG",     GNUPG_NAME },
+  { "GPG",       GPG_NAME },
+  { "GPGSM",     GPGSM_NAME },
+  { "GPG_AGENT", GPG_AGENT_NAME },
+  { "SCDAEMON",  SCDAEMON_NAME },
+  { "DIRMNGR",   DIRMNGR_NAME },
+  { "G13",       G13_NAME },
+  { "GPGCONF",   GPGCONF_NAME },
+  { "GPGTAR",    GPGTAR_NAME }
+};
+
+
+
+/* A list to remember already done mappings.  */
+struct mapping_s
+{
+  struct mapping_s *next;
+  const char *key;
+  const char *value;
+};
+static struct mapping_s *mappings;
+
+
+/* If STRING has already been mapped, return the mapped string.  If
+   not return NULL.  */
+static const char *
+already_mapped (const char *string)
+{
+  struct mapping_s *m;
+
+  for (m=mappings; m; m = m->next)
+    if (m->key == string && !strcmp (m->key, string))
+      return m->value;
+  return NULL;
+}
+
+
+/* Store NEWSTRING under key STRING and return NEWSTRING.  */
+static const char *
+store_mapping (const char *string, char *newstring)
+{
+  struct mapping_s *m;
+
+  m = xmalloc (sizeof *m);
+  m->key = string;
+  m->value = newstring;
+  m->next = mappings;
+  mappings = m;
+  return newstring;
+}
+
+
+/* Find the first macro in STRING.  Return a pointer to the
+   replacement value, set BEGPTR to the leading '@', and set ENDPTR to
+   the terminating '@'.  If no macro is found return NULL.  */
+const char *
+find_macro (const char *string,  const char **begptr,
+            const char **endptr)
+{
+  const char *s, *s2, *s3;
+  int idx;
+
+  s = string;
+  if (!s)
+    return NULL;
+
+  for (; (s2 = strchr (s, '@')); s = s2)
+    {
+      s2++;
+      if (*s2 >= 'A' && *s2 <= 'Z' && (s3 = (strchr (s2, '@'))))
+        {
+          for (idx=0; idx < DIM (macros); idx++)
+            if (strlen (macros[idx].name) == (s3 - s2)
+                && !memcmp (macros[idx].name, s2, (s3 - s2)))
+              {
+                *begptr = s2 - 1;
+                *endptr = s3;
+                return macros[idx].value;
+              }
+        }
+    }
+  return NULL;
+}
+
+
+/* If STRING includes known @FOO@ macros, replace these macros and
+   return a new static string.  Warning: STRING must have been
+   allocated statically.  Note that this function allocated memory
+   which will not be released (similar to gettext).  */
+const char *
+map_static_macro_string (const char *string)
+{
+  const char *s, *s2, *s3, *value;
+  membuf_t mb;
+  char *p;
+
+  if ((s = already_mapped (string)))
+    return s;
+  s = string;
+  value = find_macro (s, &s2, &s3);
+  if (!value)
+    return string; /* No macros at all.  */
+
+  init_membuf (&mb, strlen (string) + 100);
+  do
+    {
+      put_membuf (&mb, s, s2 - s);
+      put_membuf_str (&mb, value);
+      s = s3 + 1;
+    }
+  while ((value = find_macro (s, &s2, &s3)));
+  put_membuf_str (&mb, s);
+  put_membuf (&mb, "", 1);
+
+  p = get_membuf_shrink (&mb, NULL);
+  if (!p)
+    log_fatal ("map_static_macro_string failed: %s\n", strerror (errno));
+
+  return store_mapping (string, p);
+}
index 737930b..cc7772f 100644 (file)
@@ -1,14 +1,25 @@
 /* membuf.c - A simple implementation of a dynamic buffer.
- * Copyright (C) 2001, 2003, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2009, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -20,6 +31,7 @@
 #include <config.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <stdarg.h>
 
 #include "membuf.h"
 
@@ -56,16 +68,36 @@ init_membuf_secure (membuf_t *mb, int initiallen)
 }
 
 
+/* Shift the the content of the membuf MB by AMOUNT bytes.  The next
+   operation will then behave as if AMOUNT bytes had not been put into
+   the buffer.  If AMOUNT is greater than the actual accumulated
+   bytes, the membuf is basically reset to its initial state.  */
 void
-put_membuf (membuf_t *mb, const void *buf, size_t len)
+clear_membuf (membuf_t *mb, size_t amount)
 {
+  /* No need to clear if we are already out of core.  */
   if (mb->out_of_core)
     return;
+  if (amount >= mb->len)
+    mb->len = 0;
+  else
+    {
+      mb->len -= amount;
+      memmove (mb->buf, mb->buf+amount, mb->len);
+    }
+}
+
+
+void
+put_membuf (membuf_t *mb, const void *buf, size_t len)
+{
+  if (mb->out_of_core || !len)
+    return;
 
   if (mb->len + len >= mb->size)
     {
       char *p;
-      
+
       mb->size += len + 1024;
       p = xtryrealloc (mb->buf, mb->size);
       if (!p)
@@ -74,7 +106,7 @@ put_membuf (membuf_t *mb, const void *buf, size_t len)
           /* Wipe out what we already accumulated.  This is required
              in case we are storing sensitive data here.  The membuf
              API does not provide another way to cleanup after an
-             error. */ 
+             error. */
           wipememory (mb->buf, mb->len);
           return;
         }
@@ -92,6 +124,26 @@ put_membuf_str (membuf_t *mb, const char *string)
 }
 
 
+void
+put_membuf_printf (membuf_t *mb, const char *format, ...)
+{
+  int rc;
+  va_list arg_ptr;
+  char *buf;
+
+  va_start (arg_ptr, format);
+  rc = gpgrt_vasprintf (&buf, format, arg_ptr);
+  if (rc < 0)
+    mb->out_of_core = errno ? errno : ENOMEM;
+  va_end (arg_ptr);
+  if (rc >= 0)
+    {
+      put_membuf (mb, buf, strlen (buf));
+      xfree (buf);
+    }
+}
+
+
 void *
 get_membuf (membuf_t *mb, size_t *len)
 {
@@ -105,7 +157,7 @@ get_membuf (membuf_t *mb, size_t *len)
           xfree (mb->buf);
           mb->buf = NULL;
         }
-      errno = mb->out_of_core;
+      gpg_err_set_errno (mb->out_of_core);
       return NULL;
     }
 
@@ -116,3 +168,50 @@ get_membuf (membuf_t *mb, size_t *len)
   mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
   return p;
 }
+
+
+/* Same as get_membuf but shrinks the reallocated space to the
+   required size.  */
+void *
+get_membuf_shrink (membuf_t *mb, size_t *len)
+{
+  void *p, *pp;
+  size_t dummylen;
+
+  if (!len)
+    len = &dummylen;
+
+  p = get_membuf (mb, len);
+  if (!p)
+    return NULL;
+  if (*len)
+    {
+      pp = xtryrealloc (p, *len);
+      if (pp)
+        p = pp;
+    }
+
+  return p;
+}
+
+
+/* Peek at the membuf MB.  On success a pointer to the buffer is
+   returned which is valid until the next operation on MB.  If LEN is
+   not NULL the current LEN of the buffer is stored there.  On error
+   NULL is returned and ERRNO is set.  */
+const void *
+peek_membuf (membuf_t *mb, size_t *len)
+{
+  const char *p;
+
+  if (mb->out_of_core)
+    {
+      gpg_err_set_errno (mb->out_of_core);
+      return NULL;
+    }
+
+  p = mb->buf;
+  if (len)
+    *len = mb->len;
+  return p;
+}
index 75b506d..dfa236d 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #ifndef GNUPG_COMMON_MEMBUF_H
 #define GNUPG_COMMON_MEMBUF_H
 
+#include "mischelp.h"
+
 /* The definition of the structure is private, we only need it here,
    so it can be allocated on the stack. */
-struct private_membuf_s 
+struct private_membuf_s
 {
-  size_t len;      
-  size_t size;     
-  char *buf;       
-  int out_of_core; 
+  size_t len;
+  size_t size;
+  char *buf;
+  int out_of_core;
 };
 
 typedef struct private_membuf_s membuf_t;
@@ -39,9 +51,13 @@ typedef struct private_membuf_s membuf_t;
 
 void init_membuf (membuf_t *mb, int initiallen);
 void init_membuf_secure (membuf_t *mb, int initiallen);
+void clear_membuf (membuf_t *mb, size_t amount);
 void put_membuf  (membuf_t *mb, const void *buf, size_t len);
 void put_membuf_str (membuf_t *mb, const char *string);
+void put_membuf_printf (membuf_t *mb, const char *format,
+                        ...) JNLIB_GCC_A_PRINTF(2,3);
 void *get_membuf (membuf_t *mb, size_t *len);
-
+void *get_membuf_shrink (membuf_t *mb, size_t *len);
+const void *peek_membuf (membuf_t *mb, size_t *len);
 
 #endif /*GNUPG_COMMON_MEMBUF_H*/
index 1c88068..862e952 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #include "iobuf.h"
 #include "i18n.h"
 
-
 /* Used by libgcrypt for logging.  */
 static void
 my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
 {
   (void)dummy;
-  
+
   /* Map the log levels.  */
   switch (level)
     {
@@ -43,7 +52,7 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
     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;  
+    default:            level = JNLIB_LOG_ERROR; break;
     }
   log_logv (level, fmt, arg_ptr);
 }
@@ -96,6 +105,22 @@ setup_libgcrypt_logging (void)
   gcry_set_outofcore_handler (my_gcry_outofcore_handler, NULL);
 }
 
+/* A wrapper around gcry_cipher_algo_name to return the string
+   "AES-128" instead of "AES".  Given that we have an alias in
+   libgcrypt for it, it does not harm to too much to return this other
+   string.  Some users complained that we print "AES" but "AES192"
+   and "AES256".  We can't fix that in libgcrypt but it is pretty
+   safe to do it in an application. */
+const char *
+gnupg_cipher_algo_name (int algo)
+{
+  const char *s;
+
+  s = gcry_cipher_algo_name (algo);
+  if (!strcmp (s, "AES"))
+    s = "AES128";
+  return s;
+}
 
 
 /* Decide whether the filename is stdout or a real filename and return
@@ -119,23 +144,63 @@ print_fname_stdin (const char *s)
     return s;
 }
 
-/* fixme: Globally replace it by print_sanitized_buffer. */
+
+static int
+do_print_utf8_buffer (estream_t stream,
+                      const void *buffer, size_t length,
+                      const char *delimiters, size_t *bytes_written)
+{
+  const char *p = buffer;
+  size_t i;
+
+  /* We can handle plain ascii simpler, so check for it first. */
+  for (i=0; i < length; i++ )
+    {
+      if ( (p[i] & 0x80) )
+        break;
+    }
+  if (i < length)
+    {
+      int delim = delimiters? *delimiters : 0;
+      char *buf;
+      int ret;
+
+      /*(utf8 conversion already does the control character quoting). */
+      buf = utf8_to_native (p, length, delim);
+      if (bytes_written)
+        *bytes_written = strlen (buf);
+      ret = es_fputs (buf, stream);
+      xfree (buf);
+      return ret == EOF? ret : (int)i;
+    }
+  else
+    return es_write_sanitized (stream, p, length, delimiters, bytes_written);
+}
+
+
 void
-print_string( FILE *fp, const byte *p, size_t n, int delim )
+print_utf8_buffer3 (estream_t stream, const void *p, size_t n,
+                    const char *delim)
 {
-  print_sanitized_buffer (fp, p, n, delim);
+  do_print_utf8_buffer (stream, p, n, delim, NULL);
 }
 
+
 void
-print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim )
+print_utf8_buffer2 (estream_t stream, const void *p, size_t n, int delim)
 {
-  print_sanitized_utf8_buffer (fp, p, n, delim);
+  char tmp[2];
+
+  tmp[0] = delim;
+  tmp[1] = 0;
+  do_print_utf8_buffer (stream, p, n, tmp, NULL);
 }
 
+
 void
-print_utf8_string( FILE *fp, const byte *p, size_t n )
+print_utf8_buffer (estream_t stream, const void *p, size_t n)
 {
-    print_utf8_string2 (fp, p, n, 0);
+  do_print_utf8_buffer (stream, p, n, NULL, NULL);
 }
 
 /* Write LENGTH bytes of BUFFER to FP as a hex encoded string.
@@ -183,7 +248,7 @@ is_file_compressed (const char *s, int *ret_rc)
         { 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
         { 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
     };
-    
+
     if ( iobuf_is_pipe_filename (s) || !ret_rc )
         return 0; /* We can't check stdin or no file was given */
 
@@ -211,7 +276,7 @@ is_file_compressed (const char *s, int *ret_rc)
         }
     }
 
-leave:    
+leave:
     iobuf_close( a );
     return rc;
 }
@@ -239,3 +304,80 @@ match_multistr (const char *multistr,const char *match)
 }
 
 
+\f
+/* Parse the first portion of the version number S and store it at
+   NUMBER.  On success, the function returns a pointer into S starting
+   with the first character, which is not part of the initial number
+   portion; on failure, NULL is returned.  */
+static const char*
+parse_version_number (const char *s, int *number)
+{
+  int val = 0;
+
+  if (*s == '0' && digitp (s+1))
+    return NULL; /* Leading zeros are not allowed.  */
+  for (; digitp (s); s++ )
+    {
+      val *= 10;
+      val += *s - '0';
+    }
+  *number = val;
+  return val < 0? NULL : s;
+}
+
+/* Break up the complete string representation of the version number S,
+   which is expected to have this format:
+
+      <major number>.<minor number>.<micro number><patch level>.
+
+   The major, minor and micro number components will be stored at
+   MAJOR, MINOR and MICRO. On success, a pointer to the last
+   component, the patch level, will be returned; on failure, NULL will
+   be returned.  */
+static const char *
+parse_version_string (const char *s, int *major, int *minor, int *micro)
+{
+  s = parse_version_number (s, major);
+  if (!s || *s != '.')
+    return NULL;
+  s++;
+  s = parse_version_number (s, minor);
+  if (!s || *s != '.')
+    return NULL;
+  s++;
+  s = parse_version_number (s, micro);
+  if (!s)
+    return NULL;
+  return s; /* Patchlevel.  */
+}
+
+/* Return true if version string is at least version B. */
+int
+gnupg_compare_version (const char *a, const char *b)
+{
+  int a_major, a_minor, a_micro;
+  int b_major, b_minor, b_micro;
+  const char *a_plvl, *b_plvl;
+
+  if (!a || !b)
+    return 0;
+
+  /* Parse version A.  */
+  a_plvl = parse_version_string (a, &a_major, &a_minor, &a_micro);
+  if (!a_plvl )
+    return 0; /* Invalid version number.  */
+
+  /* Parse version B.  */
+  b_plvl = parse_version_string (b, &b_major, &b_minor, &b_micro);
+  if (!b_plvl )
+    return 0; /* Invalid version number.  */
+
+  /* Compare version numbers.  */
+  return (a_major > b_major
+          || (a_major == b_major && a_minor > b_minor)
+          || (a_major == b_major && a_minor == b_minor
+              && a_micro > b_micro)
+          || (a_major == b_major && a_minor == b_minor
+              && a_micro == b_micro
+              && strcmp (a_plvl, b_plvl) >= 0));
+}
similarity index 55%
rename from jnlib/mischelp.c
rename to common/mischelp.c
index f7df5c1..d106cde 100644 (file)
@@ -1,20 +1,31 @@
 /* mischelp.c - Miscellaneous helper functions
  * Copyright (C) 1998, 2000, 2001, 2006, 2007 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 # include <sys/stat.h>
 # include <unistd.h>
 #endif /*!HAVE_W32_SYSTEM*/
+#include <errno.h>
 
 #include "libjnlib-config.h"
 #include "stringhelp.h"
+#include "utf8conv.h"
 #include "mischelp.h"
 
 
+/* Because we can't use our jnlib_free macro in inline functions we
+   provide this wrapper.  */
+void
+_jnlib_free (void *p)
+{
+  if (p)
+    jnlib_free (p);
+}
+
+
 /* Check whether the files NAME1 and NAME2 are identical.  This is for
    example achieved by comparing the inode numbers of the files.  */
 int
 same_file_p (const char *name1, const char *name2)
 {
   int yes;
-      
+
   /* First try a shortcut.  */
   if (!compare_filenames (name1, name2))
     yes = 1;
   else
     {
-#ifdef HAVE_W32_SYSTEM  
+#ifdef HAVE_W32_SYSTEM
       HANDLE file1, file2;
       BY_HANDLE_FILE_INFORMATION info1, info2;
-      
+
+#ifdef HAVE_W32CE_SYSTEM
+      {
+        wchar_t *wname = utf8_to_wchar (name1);
+        if (wname)
+          file1 = CreateFile (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+        else
+          file1 = INVALID_HANDLE_VALUE;
+        jnlib_free (wname);
+      }
+#else
       file1 = CreateFile (name1, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+#endif
       if (file1 == INVALID_HANDLE_VALUE)
         yes = 0; /* If we can't open the file, it is not the same.  */
       else
         {
+#ifdef HAVE_W32CE_SYSTEM
+          {
+            wchar_t *wname = utf8_to_wchar (name2);
+            if (wname)
+              file2 = CreateFile (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+            else
+              file2 = INVALID_HANDLE_VALUE;
+            jnlib_free (wname);
+          }
+#else
           file2 = CreateFile (name2, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
-          if (file1 == INVALID_HANDLE_VALUE)
+#endif
+          if (file2 == INVALID_HANDLE_VALUE)
             yes = 0; /* If we can't open the file, it is not the same.  */
           else
             {
@@ -72,7 +117,7 @@ same_file_p (const char *name1, const char *name2)
         }
 #else /*!HAVE_W32_SYSTEM*/
       struct stat info1, info2;
-      
+
       yes = (!stat (name1, &info1) && !stat (name2, &info2)
              && info1.st_dev == info2.st_dev && info1.st_ino == info2.st_ino);
 #endif /*!HAVE_W32_SYSTEM*/
@@ -87,7 +132,7 @@ same_file_p (const char *name1, const char *name2)
   and get back a time_t.  It differs from mktime() in that it handles
   the case where the struct tm is UTC and the local environment isn't.
 
-  Note, that this replacement implementaion is not thread-safe!
+  Note, that this replacement implementation might not be thread-safe!
 
   Some BSDs don't handle the putenv("foo") case properly, so we use
   unsetenv if the platform has it to remove environment variables.
@@ -96,6 +141,35 @@ same_file_p (const char *name1, const char *name2)
 time_t
 timegm (struct tm *tm)
 {
+#ifdef HAVE_W32_SYSTEM
+  /* This one is thread safe.  */
+  SYSTEMTIME st;
+  FILETIME ft;
+  unsigned long long cnsecs;
+
+  st.wYear   = tm->tm_year + 1900;
+  st.wMonth  = tm->tm_mon  + 1;
+  st.wDay    = tm->tm_mday;
+  st.wHour   = tm->tm_hour;
+  st.wMinute = tm->tm_min;
+  st.wSecond = tm->tm_sec;
+  st.wMilliseconds = 0; /* Not available.  */
+  st.wDayOfWeek = 0;    /* Ignored.  */
+
+  /* System time is UTC thus the conversion is pretty easy.  */
+  if (!SystemTimeToFileTime (&st, &ft))
+    {
+      jnlib_set_errno (EINVAL);
+      return (time_t)(-1);
+    }
+
+  cnsecs = (((unsigned long long)ft.dwHighDateTime << 32)
+            | ft.dwLowDateTime);
+  cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01.  */
+  return (time_t)(cnsecs / 10000000ULL);
+
+#else /* (Non thread safe implementation!) */
+
   time_t answer;
   char *zone;
 
@@ -117,17 +191,13 @@ timegm (struct tm *tm)
             }
        }
       if (old_zone)
-        putenv (old_zone);     
+        putenv (old_zone);
     }
   else
-#ifdef HAVE_UNSETENV
-    unsetenv("TZ");
-#else
-    putenv("TZ");
-#endif
+    gnupg_unsetenv("TZ");
 
   tzset();
   return answer;
+#endif
 }
 #endif /*!HAVE_TIMEGM*/
-
similarity index 66%
rename from jnlib/mischelp.h
rename to common/mischelp.h
index dc17384..33739e8 100644 (file)
@@ -2,26 +2,41 @@
  * Copyright (C) 1999, 2000, 2001, 2002, 2003,
  *               2006, 2007, 2009  Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_MISCHELP_H
 #define LIBJNLIB_MISCHELP_H
 
 
+/* Because we can't use the internal jnlib_free macro in inline
+   functions we provide a wrapper function as well.   */
+void _jnlib_free (void *p);
+
 /* Check whether the files NAME1 and NAME2 are identical.  This is for
    example achieved by comparing the inode numbers of the files.  */
 int same_file_p (const char *name1, const char *name2);
@@ -37,12 +52,21 @@ time_t timegm (struct tm *tm);
 #define DIMof(type,member)   DIM(((type *)0)->member)
 
 
+#undef JNLIB_GCC_HAVE_PUSH_PRAGMA
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
 # define JNLIB_GCC_M_FUNCTION 1
 # define JNLIB_GCC_A_NR             __attribute__ ((noreturn))
-# define JNLIB_GCC_A_PRINTF( f, a )  __attribute__ ((format (printf,f,a)))
-# define JNLIB_GCC_A_NR_PRINTF( f, a ) \
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4 )
+#   define JNLIB_GCC_HAVE_PUSH_PRAGMA 1
+#   define JNLIB_GCC_A_PRINTF( f, a ) \
+                    __attribute__ ((format (__gnu_printf__,f,a)))
+#   define JNLIB_GCC_A_NR_PRINTF( f, a ) \
+                   __attribute__ ((noreturn, format (__gnu_printf__,f,a)))
+# else
+#   define JNLIB_GCC_A_PRINTF( f, a )  __attribute__ ((format (printf,f,a)))
+#   define JNLIB_GCC_A_NR_PRINTF( f, a ) \
                            __attribute__ ((noreturn, format (printf,f,a)))
+# endif
 #else
 # define JNLIB_GCC_A_NR
 # define JNLIB_GCC_A_PRINTF( f, a )
@@ -66,6 +90,9 @@ time_t timegm (struct tm *tm);
 # include <sys/socket.h>
 # include <sys/un.h>
 #else
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
 # include <windows.h>
 #endif
 
index 48c6b89..138d3c1 100755 (executable)
@@ -28,12 +28,12 @@ cat <<EOF
 
 /**
  * gnupg_strerror:
- * @err:  Error code 
- * 
+ * @err:  Error code
+ *
  * This function returns a textual representaion of the given
  * errorcode. If this is an unknown value, a string with the value
  * is returned (Beware: it is hold in a static buffer).
- * 
+ *
  * Return value: String with the error description.
  **/
 const char *
index b804ffc..e631072 100755 (executable)
@@ -24,13 +24,13 @@ cat <<EOF
 
 /**
  * gnupg_error_token:
- * @err:  Error code 
- * 
+ * @err:  Error code
+ *
  * This function returns a textual representaion of the given
  * errorcode. If this is an unknown value, a static string is returned.
- * This function differs from gnupg_strerror that it yields the string 
+ * This function differs from gnupg_strerror that it yields the string
  * representation of the macro which is never subject to i18n.
- * 
+ *
  * Return value: String with the error token.
  **/
 const char *
index 56e9bb8..b5d4ef0 100644 (file)
@@ -1,6 +1,6 @@
 # mkstrtable.awk
 # Copyright (C) 2003, 2004 g10 Code GmbH
-# 
+#
 # This program 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
@@ -181,5 +181,5 @@ END {
     print "  : " stop + 1 " - " skip ")";
   else
     print "  : -1)";
-    
+
  }
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c
new file mode 100644 (file)
index 0000000..010c23f
--- /dev/null
@@ -0,0 +1,347 @@
+/* openpgp-oids.c - OID helper for OpenPGP
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "util.h"
+
+
+/* A table with all our supported OpenPGP curves.  */
+static struct {
+  const char *name;   /* Standard name.  */
+  const char *oidstr; /* IETF formatted OID.  */
+  unsigned int nbits; /* Nominla bit length of the curve.  */
+  const char *alias;  /* NULL or alternative name of the curve.  */
+} oidtable[] = {
+
+  { "Ed25519",         "1.3.6.1.4.1.11591.15.1", 255, "ed25519" },
+
+  { "NIST P-256",      "1.2.840.10045.3.1.7",    256, "nistp256" },
+  { "NIST P-384",      "1.3.132.0.34",           384, "nistp384" },
+  { "NIST P-521",      "1.3.132.0.35",           521, "nistp521" },
+
+  { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7",   256 },
+  { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11",  384 },
+  { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13",  512 },
+
+  { "secp256k1",       "1.3.132.0.10",           256 },
+
+  { NULL, NULL, 0}
+};
+
+
+/* The OID for Curve Ed25519 in OpenPGP format.  */
+static const char oid_ed25519[] =
+  { 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01 };
+
+
+/* Helper for openpgp_oid_from_str.  */
+static size_t
+make_flagged_int (unsigned long value, char *buf, size_t buflen)
+{
+  int more = 0;
+  int shift;
+
+  /* fixme: figure out the number of bits in an ulong and start with
+     that value as shift (after making it a multiple of 7) a more
+     straigtforward implementation is to do it in reverse order using
+     a temporary buffer - saves a lot of compares */
+  for (more=0, shift=28; shift > 0; shift -= 7)
+    {
+      if (more || value >= (1<<shift))
+        {
+          buf[buflen++] = 0x80 | (value >> shift);
+          value -= (value >> shift) << shift;
+          more = 1;
+        }
+    }
+  buf[buflen++] = value;
+  return buflen;
+}
+
+
+/* Convert the OID given in dotted decimal form in STRING to an DER
+ * encoding and store it as an opaque value at R_MPI.  The format of
+ * the DER encoded is not a regular ASN.1 object but the modified
+ * format as used by OpenPGP for the ECC curve description.  On error
+ * the function returns and error code an NULL is stored at R_BUG.
+ * Note that scanning STRING stops at the first white space
+ * character.  */
+gpg_error_t
+openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi)
+{
+  unsigned char *buf;
+  size_t buflen;
+  unsigned long val1, val;
+  const char *endp;
+  int arcno;
+
+  *r_mpi = NULL;
+
+  if (!string || !*string)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  /* We can safely assume that the encoded OID is shorter than the string. */
+  buf = xtrymalloc (1 + strlen (string) + 2);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  /* Save the first byte for the length.  */
+  buflen = 1;
+
+  val1 = 0; /* Avoid compiler warning.  */
+  arcno = 0;
+  do {
+    arcno++;
+    val = strtoul (string, (char**)&endp, 10);
+    if (!digitp (string) || !(*endp == '.' || !*endp))
+      {
+        xfree (buf);
+        return gpg_error (GPG_ERR_INV_OID_STRING);
+      }
+    if (*endp == '.')
+      string = endp+1;
+
+    if (arcno == 1)
+      {
+        if (val > 2)
+          break; /* Not allowed, error catched below.  */
+        val1 = val;
+      }
+    else if (arcno == 2)
+      { /* Need to combine the first two arcs in one octet.  */
+        if (val1 < 2)
+          {
+            if (val > 39)
+              {
+                xfree (buf);
+                return gpg_error (GPG_ERR_INV_OID_STRING);
+              }
+            buf[buflen++] = val1*40 + val;
+          }
+        else
+          {
+            val += 80;
+            buflen = make_flagged_int (val, buf, buflen);
+          }
+      }
+    else
+      {
+        buflen = make_flagged_int (val, buf, buflen);
+      }
+  } while (*endp == '.');
+
+  if (arcno == 1 || buflen < 2 || buflen > 254 )
+    { /* It is not possible to encode only the first arc.  */
+      xfree (buf);
+      return gpg_error (GPG_ERR_INV_OID_STRING);
+    }
+
+  *buf = buflen - 1;
+  *r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8);
+  if (!*r_mpi)
+    {
+      xfree (buf);
+      return gpg_error_from_syserror ();
+    }
+  return 0;
+}
+
+
+/* Return a malloced string represenation of the OID in the opaque MPI
+   A.  In case of an error NULL is returned and ERRNO is set.  */
+char *
+openpgp_oid_to_str (gcry_mpi_t a)
+{
+  const unsigned char *buf;
+  size_t length;
+  unsigned int lengthi;
+  char *string, *p;
+  int n = 0;
+  unsigned long val, valmask;
+
+  valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
+
+  if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    {
+      gpg_err_set_errno (EINVAL);
+      return NULL;
+    }
+
+  buf = gcry_mpi_get_opaque (a, &lengthi);
+  length = (lengthi+7)/8;
+
+  /* The first bytes gives the length; check consistency.  */
+  if (!length || buf[0] != length -1)
+    {
+      gpg_err_set_errno (EINVAL);
+      return NULL;
+    }
+  /* Skip length byte.  */
+  length--;
+  buf++;
+
+  /* To calculate the length of the string we can safely assume an
+     upper limit of 3 decimal characters per byte.  Two extra bytes
+     account for the special first octect */
+  string = p = xtrymalloc (length*(1+3)+2+1);
+  if (!string)
+    return NULL;
+  if (!buf || !length)
+    {
+      *p = 0;
+      return string;
+    }
+
+  if (buf[0] < 40)
+    p += sprintf (p, "0.%d", buf[n]);
+  else if (buf[0] < 80)
+    p += sprintf (p, "1.%d", buf[n]-40);
+  else {
+    val = buf[n] & 0x7f;
+    while ( (buf[n]&0x80) && ++n < length )
+      {
+        if ( (val & valmask) )
+          goto badoid;  /* Overflow.  */
+        val <<= 7;
+        val |= buf[n] & 0x7f;
+      }
+    val -= 80;
+    sprintf (p, "2.%lu", val);
+    p += strlen (p);
+  }
+  for (n++; n < length; n++)
+    {
+      val = buf[n] & 0x7f;
+      while ( (buf[n]&0x80) && ++n < length )
+        {
+          if ( (val & valmask) )
+            goto badoid;  /* Overflow.  */
+          val <<= 7;
+          val |= buf[n] & 0x7f;
+        }
+      sprintf (p, ".%lu", val);
+      p += strlen (p);
+    }
+
+  *p = 0;
+  return string;
+
+ badoid:
+  /* Return a special OID (gnu.gnupg.badoid) to indicate the error
+     case.  The OID is broken and thus we return one which can't do
+     any harm.  Formally this does not need to be a bad OID but an OID
+     with an arc that can't be represented in a 32 bit word is more
+     than likely corrupt.  */
+  xfree (string);
+  return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973");
+}
+
+
+
+/* Return true if A represents the OID for Ed25519.  */
+int
+openpgp_oid_is_ed25519 (gcry_mpi_t a)
+{
+  const unsigned char *buf;
+  unsigned int nbits;
+  size_t n;
+
+  if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    return 0;
+
+  buf = gcry_mpi_get_opaque (a, &nbits);
+  n = (nbits+7)/8;
+  return (n == DIM (oid_ed25519)
+          && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
+}
+
+
+
+/* Map the Libgcrypt ECC curve NAME to an OID.  If R_NBITS is not NULL
+   store the bit size of the curve there.  Returns NULL for unknown
+   curve names.  */
+const char *
+openpgp_curve_to_oid (const char *name, unsigned int *r_nbits)
+{
+  int i;
+  unsigned int nbits = 0;
+  const char *oidstr = NULL;
+
+  if (name)
+    {
+      for (i=0; oidtable[i].name; i++)
+        if (!strcmp (oidtable[i].name, name)
+            || (oidtable[i].alias && !strcmp (oidtable[i].alias, name)))
+          {
+            oidstr = oidtable[i].oidstr;
+            nbits  = oidtable[i].nbits;
+            break;
+          }
+      if (!oidtable[i].name)
+        {
+          /* If not found assume the input is already an OID and check
+             whether we support it.  */
+          for (i=0; oidtable[i].name; i++)
+            if (!strcmp (name, oidtable[i].oidstr))
+              {
+                oidstr = oidtable[i].oidstr;
+                nbits  = oidtable[i].nbits;
+                break;
+              }
+        }
+    }
+
+  if (r_nbits)
+    *r_nbits = nbits;
+  return oidstr;
+}
+
+
+/* Map an OpenPGP OID to the Libgcrypt curve NAME.  Returns "?" for
+   unknown curve names.  We prefer an alias name here which is more
+   suitable for printing.  */
+const char *
+openpgp_oid_to_curve (const char *oidstr)
+{
+  int i;
+
+  if (!oidstr)
+    return "";
+
+  for (i=0; oidtable[i].name; i++)
+    if (!strcmp (oidtable[i].oidstr, oidstr))
+      return oidtable[i].alias? oidtable[i].alias : oidtable[i].name;
+
+  return "?";
+}
index e8121b1..c81109a 100644 (file)
@@ -1,15 +1,24 @@
 /* openpgpdefs.h - Constants from the OpenPGP standard (rfc2440)
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  *               2006 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
- * This file is part of GnuPG.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * 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 3 of the License, or
- * (at your option) any later version.
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
  *
- * GnuPG is distributed in the hope that it will be useful,
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -21,7 +30,7 @@
 #ifndef GNUPG_COMMON_OPENPGPDEFS_H
 #define GNUPG_COMMON_OPENPGPDEFS_H
 
-typedef enum 
+typedef enum
   {
     PKT_NONE         = 0,
     PKT_PUBKEY_ENC    = 1,  /* Public key encrypted packet. */
@@ -44,11 +53,11 @@ typedef enum
     PKT_MDC          = 19, /* Manipulation detection code packet. */
     PKT_COMMENT              = 61, /* new comment packet (GnuPG specific). */
     PKT_GPG_CONTROL   = 63  /* internal control packet (GnuPG specific). */
-  } 
+  }
 pkttype_t;
 
 
-typedef enum 
+typedef enum
   {
     SIGSUBPKT_TEST_CRITICAL = -3,
     SIGSUBPKT_LIST_UNHASHED = -2,
@@ -76,12 +85,71 @@ typedef enum
     SIGSUBPKT_SIGNERS_UID   = 28, /* Signer's user id. */
     SIGSUBPKT_REVOC_REASON  = 29, /* Reason for revocation. */
     SIGSUBPKT_FEATURES      = 30, /* Feature flags. */
-                              
+
     SIGSUBPKT_SIGNATURE     = 32, /* Embedded signature. */
-                              
+
     SIGSUBPKT_FLAG_CRITICAL = 128
-  } 
+  }
 sigsubpkttype_t;
 
 
+typedef enum
+  {
+    CIPHER_ALGO_NONE       =  0,
+    CIPHER_ALGO_IDEA       =  1,
+    CIPHER_ALGO_3DES       =  2,
+    CIPHER_ALGO_CAST5      =  3,
+    CIPHER_ALGO_BLOWFISH    =  4, /* 128 bit */
+    /* 5 & 6 are reserved */
+    CIPHER_ALGO_AES         =  7,
+    CIPHER_ALGO_AES192      =  8,
+    CIPHER_ALGO_AES256      =  9,
+    CIPHER_ALGO_TWOFISH            = 10, /* 256 bit */
+    CIPHER_ALGO_CAMELLIA128 = 11,
+    CIPHER_ALGO_CAMELLIA192 = 12,
+    CIPHER_ALGO_CAMELLIA256 = 13
+  }
+cipher_algo_t;
+
+
+typedef enum
+  {
+    PUBKEY_ALGO_RSA         =  1,
+    PUBKEY_ALGO_RSA_E       =  2, /* RSA encrypt only (legacy). */
+    PUBKEY_ALGO_RSA_S       =  3, /* RSA sign only (legacy).    */
+    PUBKEY_ALGO_ELGAMAL_E   = 16, /* Elgamal encrypt only.      */
+    PUBKEY_ALGO_DSA         = 17,
+    PUBKEY_ALGO_ECDH        = 18, /* RFC-6637  */
+    PUBKEY_ALGO_ECDSA       = 19, /* RFC-6637  */
+    PUBKEY_ALGO_ELGAMAL     = 20, /* Elgamal encrypt+sign (legacy).  */
+    /*                        21     reserved by OpenPGP.            */
+    PUBKEY_ALGO_EDDSA       = 22  /* EdDSA (not yet assigned).       */
+  }
+pubkey_algo_t;
+
+
+typedef enum
+  {
+    DIGEST_ALGO_MD5         =  1,
+    DIGEST_ALGO_SHA1        =  2,
+    DIGEST_ALGO_RMD160      =  3,
+    /* 4, 5, 6, and 7 are reserved. */
+    DIGEST_ALGO_SHA256      =  8,
+    DIGEST_ALGO_SHA384      =  9,
+    DIGEST_ALGO_SHA512      = 10,
+    DIGEST_ALGO_SHA224      = 11
+  }
+digest_algo_t;
+
+
+typedef enum
+  {
+    COMPRESS_ALGO_NONE      =  0,
+    COMPRESS_ALGO_ZIP       =  1,
+    COMPRESS_ALGO_ZLIB      =  2,
+    COMPRESS_ALGO_BZIP2     =  3
+  }
+compress_algo_t;
+
+
 #endif /*GNUPG_COMMON_OPENPGPDEFS_H*/
index e0c3592..0cab99a 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -46,13 +56,13 @@ percent_plus_escape (const char *string)
 
   for (length=1, s=string; *s; s++)
     {
-      if (*s == '+' || *s == '\"' || *s == '%' 
+      if (*s == '+' || *s == '\"' || *s == '%'
           || *(const unsigned char *)s < 0x20)
         length += 3;
       else
         length++;
     }
-  
+
   buffer = p = xtrymalloc (length);
   if (!buffer)
     return NULL;
@@ -82,7 +92,7 @@ percent_plus_escape (const char *string)
    done if WITHPLUS is true.  An escaped Nul character will be
    replaced by NULREPL.  */
 static size_t
-do_unescape (unsigned char *buffer, const unsigned char *string, 
+do_unescape (unsigned char *buffer, const unsigned char *string,
              int withplus, int nulrepl)
 {
   unsigned char *p = buffer;
@@ -90,7 +100,7 @@ do_unescape (unsigned char *buffer, const unsigned char *string,
   while (*string)
     {
       if (*string == '%' && string[1] && string[2])
-        { 
+        {
           string++;
           *p = xtoi_2 (string);
           if (!*p)
@@ -119,7 +129,7 @@ count_unescape (const unsigned char *string)
   while (*string)
     {
       if (*string == '%' && string[1] && string[2])
-        { 
+        {
           string++;
           string++;
         }
@@ -181,7 +191,7 @@ do_unescape_inplace (char *string, int withplus, int nulrepl)
   while (*string)
     {
       if (*string == '%' && string[1] && string[2])
-        { 
+        {
           string++;
           *p = xtoi_2 (string);
           if (!*p)
@@ -226,4 +236,3 @@ percent_unescape_inplace (char *string, int nulrepl)
 {
   return do_unescape_inplace (string, 0, nulrepl);
 }
-
index 918f19e..3c45e8b 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #ifdef USE_DNS_PKA
 #include <sys/types.h>
 #ifdef _WIN32
-#include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
+# include <windows.h>
 #else
 #include <netinet/in.h>
 #include <arpa/nameser.h>
@@ -149,9 +162,9 @@ get_pka_info (const char *address, unsigned char *fpr)
   if (answer->status != adns_s_ok
       || answer->type != adns_r_txt || !answer->nrrs)
     {
-      /* log_error ("DNS query returned an error: %s (%s)\n", */
-      /*            adns_strerror (answer->status), */
-      /*            adns_errabbrev (answer->status)); */
+      log_error ("DNS query returned an error: %s (%s)\n",
+                 adns_strerror (answer->status),
+                 adns_errabbrev (answer->status));
       adns_free (answer);
       adns_finish (state);
       return NULL;
@@ -173,18 +186,14 @@ get_pka_info (const char *address, unsigned char *fpr)
   return buffer;
 
 #else /*!USE_ADNS*/
-  union
-    {
-      signed char p[PACKETSZ];
-      HEADER h;
-    } answer;
+  unsigned char answer[PACKETSZ];
   int anslen;
   int qdcount, ancount;
   int rc;
   unsigned char *p, *pend;
   const char *domain;
   char *name;
-
+  HEADER header;
 
   domain = strrchr (address, '@');
   if (!domain || domain == address || !domain[1])
@@ -196,11 +205,17 @@ get_pka_info (const char *address, unsigned char *fpr)
   memcpy (name, address, domain - address);
   strcpy (stpcpy (name + (domain-address), "._pka."), domain+1);
 
-  anslen = res_query (name, C_IN, T_TXT, answer.p, PACKETSZ);
+  anslen = res_query (name, C_IN, T_TXT, answer, PACKETSZ);
   xfree (name);
   if (anslen < sizeof(HEADER))
     return NULL; /* DNS resolver returned a too short answer. */
-  if ( (rc=answer.h.rcode) != NOERROR )
+
+  /* Don't despair: A good compiler should optimize this away, as
+     header is just 32 byte and constant at compile time.  It's
+     one way to comply with strict aliasing rules.  */
+  memcpy (&header, answer, sizeof (header));
+
+  if ( (rc=header.rcode) != NOERROR )
     return NULL; /* DNS resolver returned an error. */
 
   /* We assume that PACKETSZ is large enough and don't do dynmically
@@ -208,14 +223,14 @@ get_pka_info (const char *address, unsigned char *fpr)
   if (anslen > PACKETSZ)
     return NULL; /* DNS resolver returned a too long answer */
 
-  qdcount = ntohs (answer.h.qdcount);
-  ancount = ntohs (answer.h.ancount);
+  qdcount = ntohs (header.qdcount);
+  ancount = ntohs (header.ancount);
 
   if (!ancount)
     return NULL; /* Got no answer. */
 
-  p = answer.p + sizeof (HEADER);
-  pend = answer.p + anslen; /* Actually points directly behind the buffer. */
+  p = answer + sizeof (HEADER);
+  pend = answer + anslen; /* Actually points directly behind the buffer. */
 
   while (qdcount-- && p < pend)
     {
@@ -276,6 +291,8 @@ get_pka_info (const char *address, unsigned char *fpr)
 char *
 get_pka_info (const char *address, unsigned char *fpr)
 {
+  (void)address;
+  (void)fpr;
   return NULL;
 }
 #endif /* !USE_DNS_PKA */
index 98c29ec..68b4c2e 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
index 10f5dfe..478d5e3 100644 (file)
@@ -1,14 +1,24 @@
-/* se4ssiobn-env.c - session environment helper functions.
+/* session-env.c - Session environment helper functions.
  * Copyright (C) 2009 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -49,8 +59,8 @@ struct session_environment_s
 /* A list of environment vribales we pass from the acual user
   (e.g. gpgme) down to the pinentry.  We do not handle the locale
   settings because they do not only depend on envvars.  */
-static struct 
-{ 
+static struct
+{
   const char *name;
   const char *assname;  /* Name used by Assuan or NULL.  */
 } stdenvnames[] = {
@@ -64,7 +74,7 @@ static struct
                                     modules (eg "scim-bridge").  */
   { "QT_IM_MODULE" },            /* Used by Qt to select qt input
                                       modules (eg "xim").  */
-  { "PINENTRY_USER_DATA", "pinentry-user-data"} 
+  { "PINENTRY_USER_DATA", "pinentry-user-data"}
                                  /* Used for communication with
                                     non-standard Pinentries.  */
 };
@@ -109,7 +119,7 @@ session_env_new (void)
   se = xtrycalloc (1, sizeof *se);
   if (se)
     {
-      se->arraysize = (lastallocatedarraysize? 
+      se->arraysize = (lastallocatedarraysize?
                        lastallocatedarraysize : INITIAL_ARRAYSIZE);
       se->array = xtrycalloc (se->arraysize, sizeof *se->array);
       if (!se->array)
@@ -132,7 +142,7 @@ session_env_release (session_env_t se)
   if (!se)
     return;
 
-  if (se->arraysize > INITIAL_ARRAYSIZE 
+  if (se->arraysize > INITIAL_ARRAYSIZE
       && se->arraysize <= MAXDEFAULT_ARRAYSIZE
       && se->arraysize > lastallocatedarraysize)
     lastallocatedarraysize = se->arraysize;
@@ -249,7 +259,7 @@ gpg_error_t
 session_env_putenv (session_env_t se, const char *string)
 {
   const char *s;
-  
+
   if (!string || !*string)
     return gpg_error (GPG_ERR_INV_VALUE);
   s = strchr (string, '=');
@@ -301,7 +311,7 @@ session_env_getenv (session_env_t se, const char *name)
 /* Return the value of the environment variable NAME from the SE
    object.  The returned value is valid as long as SE is valid and as
    long it has not been removed or updated by a call to
-   session_env_putenv.  If the variable does not exist, the fucntion
+   session_env_putenv.  If the variable does not exist, the function
    tries to return the value trough a call to getenv; if that returns
    a value, this value is recorded and and used.  If no value could be
    found, returns NULL.  The caller must not change the returned
@@ -325,11 +335,14 @@ session_env_getenv_or_default (session_env_t se, const char *name,
           *r_default = 1;
         return se->array[idx]->value;
       }
-  
-  /* Get the default value with and additional fallback for GPG_TTY.  */
+
+  /* Get the default value with an additional fallback for GPG_TTY.  */
   defvalue = getenv (name);
-  if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY") && ttyname (0))
-    defvalue = ttyname (0);
+  if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY")
+      && gnupg_ttyname (0))
+    {
+      defvalue = gnupg_ttyname (0);
+    }
   if (defvalue)
     {
       /* Record the default value for later use so that we are safe
@@ -339,7 +352,7 @@ session_env_getenv_or_default (session_env_t se, const char *name,
          explicit error anyway and the following scan would then fail
          anyway. */
       update_var (se, name, strlen (name), defvalue, 1);
-      
+
       for (idx=0; idx < se->arrayused; idx++)
         if (se->array[idx] && !strcmp (se->array[idx]->name, name))
           {
@@ -359,7 +372,7 @@ session_env_getenv_or_default (session_env_t se, const char *name,
    R_DEFAULT is not NULL, the default flag is stored on return.  The
    default flag indicates that the value has been taken from the
    process' environment.  The caller must not change the returned
-   name or value.  */ 
+   name or value.  */
 char *
 session_env_listenv (session_env_t se, int *iterator,
                      const char **r_value, int *r_default)
@@ -381,5 +394,3 @@ session_env_listenv (session_env_t se, int *iterator,
       }
   return NULL;
 }
-
-
index 031fe1d..1173ed5 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 struct session_environment_s;
 typedef struct session_environment_s *session_env_t;
 
-const char *session_env_list_stdenvnames (int *iterator, 
+const char *session_env_list_stdenvnames (int *iterator,
                                           const char **r_assname);
 
 session_env_t session_env_new (void);
 void session_env_release (session_env_t se);
 
 gpg_error_t session_env_putenv (session_env_t se, const char *string);
-gpg_error_t session_env_setenv (session_env_t se, 
+gpg_error_t session_env_setenv (session_env_t se,
                                 const char *name, const char *value);
 
 char *session_env_getenv (session_env_t se, const char *name);
 char *session_env_getenv_or_default (session_env_t se, const char *name,
                                      int *r_default);
-char *session_env_listenv (session_env_t se, int *iterator, 
+char *session_env_listenv (session_env_t se, int *iterator,
                            const char **r_value, int *r_default);
 
 
index b3213a6..f68c552 100644 (file)
@@ -1,14 +1,22 @@
-/* sexp-parse.h - S-Exp helper functions
+/* sexp-parse.h - S-expression helper functions
  * Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
  *
- * This file is part of GnuPG.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * 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 3 of the License, or
- * (at your option) any later version.
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
  *
- * GnuPG is distributed in the hope that it will be useful,
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -22,6 +30,7 @@
 
 #include <gpg-error.h>
 
+
 /* Return the length of the next S-Exp part and update the pointer to
    the first data byte.  0 is returned on error */
 static inline size_t
@@ -51,7 +60,7 @@ sskip (unsigned char const **buf, int *depth)
   const unsigned char *s = *buf;
   size_t n;
   int d = *depth;
-  
+
   while (d > 0)
     {
       if (*s == '(')
@@ -70,7 +79,7 @@ sskip (unsigned char const **buf, int *depth)
             return gpg_error (GPG_ERR_INV_SEXP);
           n = snext (&s);
           if (!n)
-            return gpg_error (GPG_ERR_INV_SEXP); 
+            return gpg_error (GPG_ERR_INV_SEXP);
           s += n;
         }
     }
@@ -82,7 +91,7 @@ sskip (unsigned char const **buf, int *depth)
 
 /* Check whether the the string at the address BUF points to matches
    the token.  Return true on match and update BUF to point behind the
-   token.  Return false and dont update tha buffer if it does not
+   token.  Return false and do not update the buffer if it does not
    match. */
 static inline int
 smatch (unsigned char const **buf, size_t buflen, const char *token)
@@ -123,6 +132,6 @@ smklen (char *help_buffer, size_t help_buflen, size_t value, size_t *length)
     *length = (help_buffer + help_buflen) - p;
   return p;
 }
-    
+
 
 #endif /*SEXP_PARSE_H*/
index 1e59187..c24facb 100644 (file)
@@ -1,14 +1,25 @@
 /* sexputil.c - Utility functions for S-expressions.
  * Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #include "sexp-parse.h"
 
 
-/* Helper function to create a a canonical encoded S-expression from a
+/* Return a malloced string with the S-expression CANON in advanced
+   format.  Returns NULL on error.  */
+static char *
+sexp_to_string (gcry_sexp_t sexp)
+{
+  size_t n;
+  char *result;
+
+  if (!sexp)
+    return NULL;
+  n = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  if (!n)
+    return NULL;
+  result = xtrymalloc (n);
+  if (!result)
+    return NULL;
+  n = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, n);
+  if (!n)
+    BUG ();
+
+  return result;
+}
+
+
+/* Return a malloced string with the S-expression CANON in advanced
+   format.  Returns NULL on error.  */
+char *
+canon_sexp_to_string (const unsigned char *canon, size_t canonlen)
+{
+  size_t n;
+  gcry_sexp_t sexp;
+  char *result;
+
+  n = gcry_sexp_canon_len (canon, canonlen, NULL, NULL);
+  if (!n)
+    return NULL;
+  if (gcry_sexp_sscan (&sexp, NULL, canon, n))
+    return NULL;
+  result = sexp_to_string (sexp);
+  gcry_sexp_release (sexp);
+  return result;
+}
+
+
+/* Print the canonical encoded S-expression in SEXP in advanced
+   format.  SEXPLEN may be passed as 0 is SEXP is known to be valid.
+   With TEXT of NULL print just the raw S-expression, with TEXT just
+   an empty string, print a trailing linefeed, otherwise print an
+   entire debug line. */
+void
+log_printcanon (const char *text, const unsigned char *sexp, size_t sexplen)
+{
+  if (text && *text)
+    log_debug ("%s ", text);
+  if (sexp)
+    {
+      char *buf = canon_sexp_to_string (sexp, sexplen);
+      log_printf ("%s", buf? buf : "[invalid S-expression]");
+      xfree (buf);
+    }
+  if (text)
+    log_printf ("\n");
+}
+
+
+/* Print the gcryp S-expression in SEXP in advanced format.  With TEXT
+   of NULL print just the raw S-expression, with TEXT just an empty
+   string, print a trailing linefeed, otherwise print an entire debug
+   line. */
+void
+log_printsexp (const char *text, gcry_sexp_t sexp)
+{
+  if (text && *text)
+    log_debug ("%s ", text);
+  if (sexp)
+    {
+      char *buf = sexp_to_string (sexp);
+      log_printf ("%s", buf? buf : "[invalid S-expression]");
+      xfree (buf);
+    }
+  if (text)
+    log_printf ("\n");
+}
+
+
+/* Helper function to create a canonical encoded S-expression from a
    Libgcrypt S-expression object.  The function returns 0 on success
    and the malloced canonical S-expression is stored at R_BUFFER and
    the allocated length at R_BUFLEN.  On error an error code is
@@ -52,7 +148,7 @@ make_canon_sexp (gcry_sexp_t sexp, unsigned char **r_buffer, size_t *r_buflen)
   *r_buffer = NULL;
   if (r_buflen)
     *r_buflen = 0;;
-  
+
   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
   if (!len)
     return gpg_error (GPG_ERR_BUG);
@@ -71,6 +167,36 @@ make_canon_sexp (gcry_sexp_t sexp, unsigned char **r_buffer, size_t *r_buflen)
 }
 
 
+/* Same as make_canon_sexp but pad the buffer to multiple of 64
+   bits.  If SECURE is set, secure memory will be allocated.  */
+gpg_error_t
+make_canon_sexp_pad (gcry_sexp_t sexp, int secure,
+                     unsigned char **r_buffer, size_t *r_buflen)
+{
+  size_t len;
+  unsigned char *buf;
+
+  *r_buffer = NULL;
+  if (r_buflen)
+    *r_buflen = 0;;
+
+  len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
+  if (!len)
+    return gpg_error (GPG_ERR_BUG);
+  len += (8 - len % 8) % 8;
+  buf = secure? xtrycalloc_secure (1, len) : xtrycalloc (1, len);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  if (!gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len))
+    return gpg_error (GPG_ERR_BUG);
+
+  *r_buffer = buf;
+  if (r_buflen)
+    *r_buflen = len;
+
+  return 0;
+}
+
 /* Return the so called "keygrip" which is the SHA-1 hash of the
    public key parameters expressed in a way depended on the algorithm.
 
@@ -99,7 +225,7 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
 
 
 /* Compare two simple S-expressions like "(3:foo)".  Returns 0 if they
-   are identical or !0 if they are not.  Not that this function can't
+   are identical or !0 if they are not.  Note that this function can't
    be used for sorting. */
 int
 cmp_simple_canon_sexp (const unsigned char *a_orig,
@@ -136,7 +262,7 @@ cmp_simple_canon_sexp (const unsigned char *a_orig,
 }
 
 
-/* Create a simple S-expression from the hex string at LIBNE.  Returns
+/* Create a simple S-expression from the hex string at LINE.  Returns
    a newly allocated buffer with that canonical encoded S-expression
    or NULL in case of an error.  On return the number of characters
    scanned in LINE will be stored at NSCANNED.  This fucntions stops
@@ -159,7 +285,7 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
     *nscanned = n;
   if (!n)
     return NULL;
-  len = ((n+1) & ~0x01)/2; 
+  len = ((n+1) & ~0x01)/2;
   numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
   buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
   if (!buf)
@@ -222,7 +348,7 @@ hash_algo_from_sigval (const unsigned char *sigval)
     return 0; /* Algorithm string is missing or too long.  */
   memcpy (buffer, s, n);
   buffer[n] = 0;
-  
+
   return gcry_md_map_name (buffer);
 }
 
@@ -244,16 +370,16 @@ make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen,
   char mlen_str[35];
   char elen_str[35];
   unsigned char *keybuf, *p;
-  const char const part1[] = "(10:public-key(3:rsa(1:n";
-  const char const part2[] = ")(1:e";
-  const char const part3[] = ")))";
+  const char part1[] = "(10:public-key(3:rsa(1:n";
+  const char part2[] = ")(1:e";
+  const char part3[] = ")))";
 
   /* Remove leading zeroes.  */
   for (; mlen && !*m; mlen--, m++)
     ;
   for (; elen && !*e; elen--, e++)
     ;
-      
+
   /* Insert a leading zero if the number would be zero or interpreted
      as negative.  */
   if (!mlen || (m[0] & 0x80))
@@ -270,7 +396,7 @@ make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen,
                        + strlen (part3) + 1);
   if (!keybuf)
     return NULL;
-  
+
   p = stpcpy (keybuf, part1);
   p = stpcpy (p, mlen_str);
   if (m_extra)
@@ -284,7 +410,7 @@ make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen,
   memcpy (p, e, elen);
   p += elen;
   p = stpcpy (p, part3);
+
   if (r_len)
     *r_len = p - keybuf;
 
@@ -292,7 +418,7 @@ make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen,
 }
 
 
-/* Return the so parameters of a public RSA key expressed as an
+/* Return the parameters of a public RSA key expressed as an
    canonical encoded S-expression.  */
 gpg_error_t
 get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
@@ -343,8 +469,8 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
 
           switch (*tok)
             {
-            case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break; 
-            case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break; 
+            case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break;
+            case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break;
             default:  mpi = NULL;   mpi_len = NULL; break;
             }
           if (mpi && *mpi)
@@ -386,17 +512,18 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
 
 
 /* Return the algo of a public RSA expressed as an canonical encoded
-   S-expression.  On error the algo is set to 0. */
+   S-expression.  The return value is a statically allocated
+   string.  On error that string is set to NULL. */
 gpg_error_t
 get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
-                             int *r_algo)
+                             const char **r_algo)
 {
   gpg_error_t err;
   const unsigned char *buf, *tok;
   size_t buflen, toklen;
   int depth;
-    
-  *r_algo = 0;
+
+  *r_algo = NULL;
 
   buf = keydata;
   buflen = keydatalen;
@@ -415,15 +542,17 @@ get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
     return gpg_error (GPG_ERR_BAD_PUBKEY);
 
   if (toklen == 3 && !memcmp ("rsa", tok, toklen))
-    *r_algo = GCRY_PK_RSA;
+    *r_algo = "rsa";
   else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
-    *r_algo = GCRY_PK_DSA;
+    *r_algo = "dsa";
   else if (toklen == 3 && !memcmp ("elg", tok, toklen))
-    *r_algo = GCRY_PK_ELG;
+    *r_algo = "elg";
   else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
-    *r_algo = GCRY_PK_ECDSA;
+    *r_algo = "ecdsa";
+  else if (toklen == 5 && !memcmp ("eddsa", tok, toklen))
+    *r_algo = "eddsa";
   else
-    return  gpg_error (GPG_ERR_PUBKEY_ALGO);
+    return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
   return 0;
 }
diff --git a/common/shareddefs.h b/common/shareddefs.h
new file mode 100644 (file)
index 0000000..604b7e9
--- /dev/null
@@ -0,0 +1,48 @@
+/* shareddefs.h - Constants and helpers useful for all modules
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_SHAREDDEFS_H
+#define GNUPG_COMMON_SHAREDDEFS_H
+
+/* Values for the pinentry mode.  */
+typedef enum
+  {
+    PINENTRY_MODE_ASK = 0, /* Ask via pinentry (default).  */
+    PINENTRY_MODE_CANCEL,  /* Always return a cancel error.  */
+    PINENTRY_MODE_ERROR,   /* Return error code for no pinentry.  */
+    PINENTRY_MODE_LOOPBACK /* Use an inquiry to get the value.    */
+  }
+pinentry_mode_t;
+
+
+/*-- agent-opt.c --*/
+int parse_pinentry_mode (const char *value);
+const char *str_pinentry_mode (pinentry_mode_t mode);
+
+
+
+#endif /*GNUPG_COMMON_SHAREDDEFS_H*/
index 98859a4..b202f0f 100644 (file)
@@ -4,12 +4,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -21,7 +31,9 @@
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <signal.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
@@ -43,7 +55,7 @@ init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
 {
 # ifdef HAVE_SIGACTION
   struct sigaction oact, nact;
-  
+
   if (check_ign)
     {
       /* we don't want to change an IGN handler */
@@ -56,11 +68,11 @@ init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
   sigemptyset (&nact.sa_mask);
   nact.sa_flags = 0;
   sigaction ( sig, &nact, NULL);
-# else 
+# else
   RETSIGTYPE (*ohandler)(int);
-  
+
   ohandler = signal (sig, handler);
-  if (check_ign && ohandler == SIG_IGN) 
+  if (check_ign && ohandler == SIG_IGN)
     {
       /* Change it back if it was already set to IGN */
       signal (sig, SIG_IGN);
@@ -92,18 +104,18 @@ got_fatal_signal (int sig)
   if (caught_fatal_sig)
     raise (sig);
   caught_fatal_sig = 1;
-  
+
   if (cleanup_fnc)
     cleanup_fnc ();
   /* Better don't translate these messages. */
-  write (2, "\n", 1 );
+  (void)write (2, "\n", 1 );
   s = log_get_prefix (NULL);
   if (s)
-    write(2, s, strlen (s));
-  write (2, ": signal ", 9 );
+    (void)write(2, s, strlen (s));
+  (void)write (2, ": signal ", 9 );
   s = get_signal_name(sig);
   if (s)
-    write (2, s, strlen(s) );
+    (void) write (2, s, strlen(s) );
   else
     {
       /* We are in a signal handler so we can't use any kind of printf
@@ -113,8 +125,8 @@ got_fatal_signal (int sig)
          things are messed up because we modify its value.  Although
          this is a bug in that system, we will protect against it.  */
       if (sig < 0 || sig >= 100000)
-        write (2, "?", 1);
-      else 
+        (void)write (2, "?", 1);
+      else
         {
           int i, value, any=0;
 
@@ -122,7 +134,7 @@ got_fatal_signal (int sig)
             {
               if (value >= i || ((any || i==1) && !(value/i)))
                 {
-                  write (2, "0123456789"+(value/i), 1);
+                  (void)write (2, "0123456789"+(value/i), 1);
                   if ((value/i))
                     any = 1;
                   value %= i;
@@ -130,8 +142,8 @@ got_fatal_signal (int sig)
             }
         }
     }
-  write (2, " caught ... exiting\n", 20);
-  
+  (void)write (2, " caught ... exiting\n", 20);
+
   /* Reset action to default action and raise signal again */
   init_one_signal (sig, SIG_DFL, 0);
   /* Fixme: remove_lockfiles ();*/
@@ -168,38 +180,13 @@ gnupg_init_signals (int mode, void (*fast_cleanup)(void))
 #endif
 }
 
-void
-gnupg_pause_on_sigusr (int which)
-{
-#ifndef HAVE_DOSISH_SYSTEM
-# ifdef HAVE_SIGPROCMASK
-  sigset_t mask, oldmask;
-
-  assert (which == 1);
-  sigemptyset( &mask );
-  sigaddset( &mask, SIGUSR1 );
-  
-  sigprocmask( SIG_BLOCK, &mask, &oldmask );
-  while (!caught_sigusr1)
-    sigsuspend (&oldmask);
-  caught_sigusr1 = 0;
-  sigprocmask (SIG_UNBLOCK, &mask, NULL);
-# else 
-  assert (which == 1);
-  sighold (SIGUSR1);
-  while (!caught_sigusr1)
-    sigpause(SIGUSR1);
-  caught_sigusr1 = 0;
-  sigrelease(SIGUSR1);
-# endif /*!HAVE_SIGPROCMASK*/
-#endif
-}
-
 
 static void
-do_block( int block )
+do_block (int block)
 {
-#ifndef HAVE_DOSISH_SYSTEM
+#ifdef HAVE_DOSISH_SYSTEM
+  (void)block;
+#else /*!HAVE_DOSISH_SYSTEM*/
   static int is_blocked;
 #ifdef HAVE_SIGPROCMASK
   static sigset_t oldmask;
@@ -245,7 +232,7 @@ do_block( int block )
       is_blocked = 0;
     }
 #endif /*!HAVE_SIGPROCMASK*/
-#endif /*HAVE_DOSISH_SYSTEM*/
+#endif /*!HAVE_DOSISH_SYSTEM*/
 }
 
 
index 3598b35..0eff5c5 100644 (file)
@@ -41,9 +41,9 @@
 #endif
 
 #define JNLIB_NEED_AFLOCAL
-#include "../jnlib/mischelp.h"
+#include "../common/mischelp.h"
 #ifdef HAVE_W32_SYSTEM
-#include "../jnlib/w32-afunix.h"
+#include "../common/w32-afunix.h"
 #endif
 
 
 #endif
 
 
-/* Name of the socket to be used if GPG_AGENT_INFO has not been
-   set. No default socket is used if this is NULL.  */
+/* Name of the socket to be used.  This is a kludge to keep on using
+   the existsing code despite that we only support a standard socket.  */
 static char *default_gpg_agent_info;
 
 
 
-
 \f
 
 #ifndef HAVE_STPCPY
@@ -99,7 +98,7 @@ writen (int fd, const void *buf, size_t nbytes)
 {
   size_t nleft = nbytes;
   int nwritten;
-  
+
   while (nleft > 0)
     {
 #ifdef HAVE_W32_SYSTEM
@@ -121,7 +120,7 @@ writen (int fd, const void *buf, size_t nbytes)
       nleft -= nwritten;
       buf = (const char*)buf + nwritten;
     }
-    
+
   return 0;
 }
 
@@ -155,7 +154,7 @@ readline (int fd, char *buf, size_t buflen)
       nleft -= n;
       buf += n;
       nread += n;
-      
+
       for (; n && *p != '\n'; n--, p++)
         ;
       if (n)
@@ -166,7 +165,7 @@ readline (int fd, char *buf, size_t buflen)
         }
     }
 
-  return nread; 
+  return nread;
 }
 
 
@@ -177,8 +176,8 @@ agent_send_option (int fd, const char *name, const char *value)
   char buf[200];
   int nread;
   char *line;
-  int i; 
-  
+  int i;
+
   line = spwq_malloc (7 + strlen (name) + 1 + strlen (value) + 2);
   if (!line)
     return SPWQ_OUT_OF_CORE;
@@ -188,15 +187,15 @@ agent_send_option (int fd, const char *name, const char *value)
   spwq_free (line);
   if (i)
     return i;
-  
+
   /* get response */
   nread = readline (fd, buf, DIM(buf)-1);
   if (nread < 0)
     return -nread;
   if (nread < 3)
     return SPWQ_PROTOCOL_ERROR;
-  
-  if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) 
+
+  if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n'))
     return 0; /* okay */
 
   return SPWQ_ERR_RESPONSE;
@@ -204,7 +203,7 @@ agent_send_option (int fd, const char *name, const char *value)
 
 
 /* Send all available options to the agent. */
-static int 
+static int
 agent_send_all_options (int fd)
 {
   char *dft_display = NULL;
@@ -222,7 +221,7 @@ agent_send_all_options (int fd)
     }
 
   dft_ttyname = getenv ("GPG_TTY");
-#ifndef HAVE_W32_SYSTEM
+#if !defined(HAVE_W32_SYSTEM) && !defined(HAVE_BROKEN_TTYNAME)
   if ((!dft_ttyname || !*dft_ttyname) && ttyname (0))
     dft_ttyname = ttyname (0);
 #endif
@@ -239,7 +238,7 @@ agent_send_all_options (int fd)
         return rc;
     }
 
-#if defined(HAVE_SETLOCALE) 
+#if defined(HAVE_SETLOCALE)
   {
     char *old_lc = NULL;
     char *dft_lc = NULL;
@@ -324,15 +323,12 @@ agent_open (int *rfd)
   char *infostr, *p;
   struct sockaddr_un client_addr;
   size_t len;
-  int prot;
   char line[200];
   int nread;
 
   *rfd = -1;
-  infostr = getenv ( "GPG_AGENT_INFO" );
-  if ( !infostr || !*infostr ) 
-    infostr = default_gpg_agent_info;
-  if ( !infostr || !*infostr ) 
+  infostr = default_gpg_agent_info;
+  if ( !infostr || !*infostr )
     {
 #ifdef SPWQ_USE_LOGGING
       log_error (_("gpg-agent is not available in this session\n"));
@@ -346,45 +342,34 @@ agent_open (int *rfd)
   infostr = p;
 
   if ( !(p = strchr ( infostr, PATHSEP_C)) || p == infostr
-       || (p-infostr)+1 >= sizeof client_addr.sun_path ) 
+       || (p-infostr)+1 >= sizeof client_addr.sun_path )
     {
-#ifdef SPWQ_USE_LOGGING
-      log_error ( _("malformed GPG_AGENT_INFO environment variable\n"));
-#endif
       return SPWQ_NO_AGENT;
     }
   *p++ = 0;
 
   while (*p && *p != PATHSEP_C)
     p++;
-  prot = *p? atoi (p+1) : 0;
-  if ( prot != 1)
-    {
-#ifdef SPWQ_USE_LOGGING
-      log_error (_("gpg-agent protocol version %d is not supported\n"),prot);
-#endif
-      return SPWQ_PROTOCOL_ERROR;
-    }
 
-#ifdef HAVE_W32_SYSTEM       
+#ifdef HAVE_W32_SYSTEM
   fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0);
 #else
   fd = socket (AF_UNIX, SOCK_STREAM, 0);
 #endif
-  if (fd == -1) 
+  if (fd == -1)
     {
 #ifdef SPWQ_USE_LOGGING
       log_error ("can't create socket: %s\n", strerror(errno) );
 #endif
       return SPWQ_SYS_ERROR;
     }
-    
+
   memset (&client_addr, 0, sizeof client_addr);
   client_addr.sun_family = AF_UNIX;
   strcpy (client_addr.sun_path, infostr);
   len = SUN_LEN (&client_addr);
-    
-#ifdef HAVE_W32_SYSTEM       
+
+#ifdef HAVE_W32_SYSTEM
   rc = _w32_sock_connect (fd, (struct sockaddr*)&client_addr, len );
 #else
   rc = connect (fd, (struct sockaddr*)&client_addr, len );
@@ -392,7 +377,7 @@ agent_open (int *rfd)
   if (rc == -1)
     {
 #ifdef SPWQ_USE_LOGGING
-      log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno));
+      log_error ( _("can't connect to '%s': %s\n"), infostr, strerror (errno));
 #endif
       close (fd );
       return SPWQ_IO_ERROR;
@@ -400,7 +385,7 @@ agent_open (int *rfd)
 
   nread = readline (fd, line, DIM(line));
   if (nread < 3 || !(line[0] == 'O' && line[1] == 'K'
-                     && (line[2] == '\n' || line[2] == ' ')) ) 
+                     && (line[2] == '\n' || line[2] == ' ')) )
     {
 #ifdef SPWQ_USE_LOGGING
       log_error ( _("communication problem with gpg-agent\n"));
@@ -434,7 +419,7 @@ copy_and_escape (char *buffer, const char *text)
   int i;
   const unsigned char *s = (unsigned char *)text;
   char *p = buffer;
-  
+
 
   for (i=0; s[i]; i++)
     {
@@ -453,7 +438,7 @@ copy_and_escape (char *buffer, const char *text)
 
 
 /* Set the name of the default socket to NAME.  */
-int 
+int
 simple_pw_set_socket (const char *name)
 {
   spwq_free (default_gpg_agent_info);
@@ -482,7 +467,7 @@ simple_pw_set_socket (const char *name)
    errorcode; this error code might be 0 if the user canceled the
    operation.  The function returns NULL to indicate an error.  */
 char *
-simple_pwquery (const char *cacheid, 
+simple_pwquery (const char *cacheid,
                 const char *tryagain,
                 const char *prompt,
                 const char *description,
@@ -494,7 +479,7 @@ simple_pwquery (const char *cacheid,
   char *result = NULL;
   char *pw = NULL;
   char *p;
-  int rc, i; 
+  int rc, i;
 
   rc = agent_open (&fd);
   if (rc)
@@ -555,11 +540,11 @@ simple_pwquery (const char *cacheid,
       rc = SPWQ_PROTOCOL_ERROR;
       goto leave;
     }
-      
-  if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') 
+
+  if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ')
     { /* we got a passphrase - convert it back from hex */
       size_t pwlen = 0;
-      
+
       for (i=3; i < nread && hexdigitp (pw+i); i+=2)
         pw[pwlen++] = xtoi_2 (pw+i);
       pw[pwlen] = 0; /* make a C String */
@@ -569,7 +554,7 @@ simple_pwquery (const char *cacheid,
   else if ((nread > 7 && !memcmp (pw, "ERR 111", 7)
             && (pw[7] == ' ' || pw[7] == '\n') )
            || ((nread > 4 && !memcmp (pw, "ERR ", 4)
-                && (strtoul (pw+4, NULL, 0) & 0xffff) == 99)) ) 
+                && (strtoul (pw+4, NULL, 0) & 0xffff) == 99)) )
     {
       /* 111 is the old Assuan code for canceled which might still
          be in use by old installations. 99 is GPG_ERR_CANCELED as
@@ -588,14 +573,14 @@ simple_pwquery (const char *cacheid,
         default: rc = SPWQ_GENERAL_ERROR; break;
         }
     }
-  else 
+  else
     {
 #ifdef SPWQ_USE_LOGGING
       log_error (_("problem with the agent\n"));
 #endif
       rc = SPWQ_ERR_RESPONSE;
     }
-        
+
  leave:
   if (errorcode)
     *errorcode = rc;
@@ -659,13 +644,13 @@ simple_query (const char *query)
       rc = SPWQ_PROTOCOL_ERROR;
       goto leave;
     }
-  
-  if (response[0] == 'O' && response[1] == 'K') 
+
+  if (response[0] == 'O' && response[1] == 'K')
     /* OK, do nothing.  */;
   else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
             && (response[7] == ' ' || response[7] == '\n') )
            || ((nread > 4 && !memcmp (response, "ERR ", 4)
-                && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) ) 
+                && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
     {
       /* 111 is the old Assuan code for canceled which might still
          be in use by old installations. 99 is GPG_ERR_CANCELED as
@@ -675,14 +660,14 @@ simple_query (const char *query)
       log_info (_("canceled by user\n") );
 #endif
     }
-  else 
+  else
     {
 #ifdef SPWQ_USE_LOGGING
       log_error (_("problem with the agent\n"));
 #endif
       rc = SPWQ_ERR_RESPONSE;
     }
-        
+
  leave:
   if (fd != -1)
     close (fd);
index 8de9b1b..04ae1f0 100644 (file)
@@ -24,7 +24,7 @@
 
 /* Include whatever files you need.  */
 #include <gcrypt.h>
-#include "../jnlib/logging.h"
+#include "../common/logging.h"
 
 /* Try to write error message using the standard log mechanism.  The
    current implementation requires that the HAVE_JNLIB_LOGGING is also
@@ -50,7 +50,7 @@
    If ERRORCODE is not NULL it should point a variable receiving an
    errorcode; this errocode might be 0 if the user canceled the
    operation.  The function returns NULL to indicate an error. */
-char *simple_pwquery (const char *cacheid, 
+char *simple_pwquery (const char *cacheid,
                       const char *tryagain,
                       const char *prompt,
                       const char *description,
@@ -71,7 +71,7 @@ int simple_pw_set_socket (const char *name);
 
 #define SPWQ_OUT_OF_CORE 1
 #define SPWQ_IO_ERROR 2
-#define SPWQ_PROTOCOL_ERROR 3 
+#define SPWQ_PROTOCOL_ERROR 3
 #define SPWQ_ERR_RESPONSE 4
 #define SPWQ_NO_AGENT 5
 #define SPWQ_SYS_ERROR 6
@@ -108,8 +108,8 @@ int simple_pw_set_socket (const char *name);
            default:                                         \
              return gpg_error (GPG_ERR_GENERAL);            \
            }                                                \
-       }                                                      
-/* End of MAP_SPWQ_ERROR_IMPL.  */       
+       }
+/* End of MAP_SPWQ_ERROR_IMPL.  */
 
 
 #endif /*SIMPLE_PWQUERY_H*/
index f3831b4..380e356 100644 (file)
@@ -1,14 +1,24 @@
 /* srv.c - DNS SRV code
  * Copyright (C) 2003, 2009 Free Software Foundation, Inc.
  *
- * This file is part of GNUPG.
+ * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GNUPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #include <config.h>
 #include <sys/types.h>
 #ifdef _WIN32
-#include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
+# include <windows.h>
 #else
 #include <netinet/in.h>
 #include <arpa/nameser.h>
@@ -72,7 +85,7 @@ getsrv (const char *name,struct srventry **list)
   {
     adns_state state;
     adns_answer *answer = NULL;
-    
+
     rc = adns_init (&state, adns_if_noerrprint, NULL);
     if (rc)
       {
@@ -88,12 +101,12 @@ getsrv (const char *name,struct srventry **list)
         adns_finish (state);
         return -1;
       }
-    if (answer->status != adns_s_ok 
+    if (answer->status != adns_s_ok
         || answer->type != adns_r_srv || !answer->nrrs)
       {
-        /* log_error ("DNS query returned an error or no records: %s (%s)\n", */
-        /*            adns_strerror (answer->status), */
-        /*            adns_errabbrev (answer->status)); */
+        log_error ("DNS query returned an error or no records: %s (%s)\n",
+                   adns_strerror (answer->status),
+                   adns_errabbrev (answer->status));
         adns_free (answer);
         adns_finish (state);
         return 0;
@@ -109,7 +122,7 @@ getsrv (const char *name,struct srventry **list)
             log_info ("hostname in SRV record too long - skipped\n");
             continue;
           }
-      
+
         newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
         if (!newlist)
           goto fail;
@@ -117,7 +130,7 @@ getsrv (const char *name,struct srventry **list)
         memset (&(*list)[srvcount], 0, sizeof(struct srventry));
         srv = &(*list)[srvcount];
         srvcount++;
-      
+
         srv->priority = answer->rrs.srvha[count].priority;
         srv->weight   = answer->rrs.srvha[count].weight;
         srv->port     = answer->rrs.srvha[count].port;
@@ -134,29 +147,29 @@ getsrv (const char *name,struct srventry **list)
     unsigned char *pt, *emsg;
     int r;
     u16 dlen;
-    
+
     r = res_query (name, C_IN, T_SRV, answer, sizeof answer);
     if (r < sizeof (HEADER) || r > sizeof answer)
       return -1;
     if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
       return 0; /* Error or no record found.  */
-    
+
     emsg = &answer[r];
     pt = &answer[sizeof(HEADER)];
-  
+
     /* Skip over the query */
     rc = dn_skipname (pt, emsg);
     if (rc == -1)
       goto fail;
-  
+
     pt += rc + QFIXEDSZ;
-  
+
     while (count-- > 0 && pt < emsg)
       {
         struct srventry *srv=NULL;
         u16 type,class;
         struct srventry *newlist;
-      
+
         newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
         if (!newlist)
           goto fail;
@@ -164,28 +177,28 @@ getsrv (const char *name,struct srventry **list)
         memset(&(*list)[srvcount],0,sizeof(struct srventry));
         srv=&(*list)[srvcount];
         srvcount++;
-      
+
         rc = dn_skipname(pt,emsg); /* the name we just queried for */
         if (rc == -1)
           goto fail;
         pt+=rc;
-      
+
         /* Truncated message? */
         if((emsg-pt)<16)
           goto fail;
-      
+
         type=*pt++ << 8;
         type|=*pt++;
         /* We asked for SRV and got something else !? */
         if(type!=T_SRV)
           goto fail;
-      
+
         class=*pt++ << 8;
         class|=*pt++;
         /* We asked for IN and got something else !? */
         if(class!=C_IN)
           goto fail;
-      
+
         pt+=4; /* ttl */
         dlen=*pt++ << 8;
         dlen|=*pt++;
@@ -195,7 +208,7 @@ getsrv (const char *name,struct srventry **list)
         srv->weight|=*pt++;
         srv->port=*pt++ << 8;
         srv->port|=*pt++;
-      
+
         /* Get the name.  2782 doesn't allow name compression, but
            dn_expand still works to pull the name out of the
            packet. */
@@ -215,17 +228,17 @@ getsrv (const char *name,struct srventry **list)
       }
   }
 #endif /*!USE_ADNS*/
-  
+
   /* Now we have an array of all the srv records. */
-  
+
   /* Order by priority */
   qsort(*list,srvcount,sizeof(struct srventry),priosort);
-  
+
   /* For each priority, move the zero-weighted items first. */
   for (i=0; i < srvcount; i++)
     {
       int j;
-      
+
       for (j=i;j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
         {
           if((*list)[j].weight==0)
@@ -234,12 +247,12 @@ getsrv (const char *name,struct srventry **list)
               if(j!=i)
                 {
                   struct srventry temp;
-                  
+
                   memcpy (&temp,&(*list)[j],sizeof(struct srventry));
                   memcpy (&(*list)[j],&(*list)[i],sizeof(struct srventry));
                   memcpy (&(*list)[i],&temp,sizeof(struct srventry));
                 }
-              
+
               break;
             }
         }
@@ -255,15 +268,15 @@ getsrv (const char *name,struct srventry **list)
     {
       int j;
       float prio_count=0,chose;
-      
+
       for (j=i; j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
         {
           prio_count+=(*list)[j].weight;
           (*list)[j].run_count=prio_count;
         }
-      
+
       chose=prio_count*rand()/RAND_MAX;
-      
+
       for (j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
         {
           if (chose<=(*list)[j].run_count)
@@ -272,7 +285,7 @@ getsrv (const char *name,struct srventry **list)
               if(j!=i)
                 {
                   struct srventry temp;
-                  
+
                   memcpy(&temp,&(*list)[j],sizeof(struct srventry));
                   memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
                   memcpy(&(*list)[i],&temp,sizeof(struct srventry));
@@ -281,7 +294,7 @@ getsrv (const char *name,struct srventry **list)
             }
         }
     }
-  
+
   return srvcount;
 
  fail:
@@ -316,6 +329,6 @@ main(int argc,char *argv[])
 
 /*
 Local Variables:
-compile-command: "cc -DTEST -I.. -I../include -Wall -g -o srv srv.c -lresolv  ../tools/no-libgcrypt.o  ../jnlib/libjnlib.a"
+compile-command: "cc -DTEST -I.. -I../include -Wall -g -o srv srv.c -lresolv  ../tools/no-libgcrypt.o  ../common/libcommon.a"
 End:
 */
index fa35863..016d2b1 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GNUPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -22,6 +32,9 @@
 
 #ifdef USE_DNS_SRV
 # ifdef _WIN32
+#  ifdef HAVE_WINSOCK2_H
+#   include <winsock2.h>
+#  endif
 #  include <windows.h>
 # else
 #  include <netinet/in.h>
index cda1694..a75b3c0 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #include "ssh-utils.h"
 
 
+/* Return true if KEYPARMS holds an EdDSA key.  */
+static int
+is_eddsa (gcry_sexp_t keyparms)
+{
+  int result = 0;
+  gcry_sexp_t list;
+  const char *s;
+  size_t n;
+  int i;
+
+  list = gcry_sexp_find_token (keyparms, "flags", 0);
+  for (i = list ? gcry_sexp_length (list)-1 : 0; i > 0; i--)
+    {
+      s = gcry_sexp_nth_data (list, i, &n);
+      if (!s)
+        continue; /* Not a data element. */
+
+      if (n == 5 && !memcmp (s, "eddsa", 5))
+        {
+          result = 1;
+          break;
+        }
+    }
+  gcry_sexp_release (list);
+  return result;
+}
+
 
 /* Return the Secure Shell type fingerprint for KEY.  The length of
    the fingerprint is returned at R_LEN and the fingerprint itself at
    R_FPR.  In case of a error code is returned and NULL stored at
-   R_FPR.  This function is usually called via the ssh_get_fingerprint
-   macro which makes sure to use the correct value for ERRSOURCE. */
+   R_FPR.  */
 static gpg_error_t
-get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
-                 gpg_err_source_t errsource, int as_string)
+get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
 {
   gpg_error_t err;
   gcry_sexp_t list = NULL;
@@ -45,6 +80,7 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
   int idx;
   const char *elems;
   gcry_md_hd_t md = NULL;
+  int blobmode = 0;
 
   *r_fpr = NULL;
   *r_len = 0;
@@ -59,7 +95,7 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
   if (!list)
     {
-      err = gpg_err_make (errsource, GPG_ERR_UNKNOWN_SEXP);
+      err = gpg_err_make (default_errsource, GPG_ERR_UNKNOWN_SEXP);
       goto leave;
     }
 
@@ -71,7 +107,7 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
   name = gcry_sexp_nth_string (list, 0);
   if (!name)
     {
-      err = gpg_err_make (errsource, GPG_ERR_INV_SEXP);
+      err = gpg_err_make (default_errsource, GPG_ERR_INV_SEXP);
       goto leave;
     }
 
@@ -85,82 +121,116 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
       elems = "en";
       gcry_md_write (md, "\0\0\0\x07ssh-rsa", 11);
       break;
+
     case GCRY_PK_DSA:
       elems = "pqgy";
       gcry_md_write (md, "\0\0\0\x07ssh-dss", 11);
       break;
-#if GCRYPT_VERSION_NUMBER >= 0x010600
+
     case GCRY_PK_ECC:
-#endif
-    case GCRY_PK_ECDSA:
-      /* We only support the 3 standard curves for now.  It is just a
-         quick hack.  */
-      elems = "q";
-      gcry_md_write (md, "\0\0\0\x13" "ecdsa-sha2-nistp", 20);
-      l2 = gcry_sexp_find_token (list, "curve", 0);
-      if (!l2)
-        elems = "";
+      if (is_eddsa (list))
+        {
+          elems = "q";
+          blobmode = 1;
+          /* For now there is just one curve, thus no need to switch
+             on it.  */
+          gcry_md_write (md, "\0\0\0\x0b" "ssh-ed25519", 15);
+        }
       else
         {
-          gcry_free (name);
-          name = gcry_sexp_nth_string (l2, 1);
-          gcry_sexp_release (l2);
-          l2 = NULL;
-          if (!name)
+          /* We only support the 3 standard curves for now.  It is
+             just a quick hack.  */
+          elems = "q";
+          gcry_md_write (md, "\0\0\0\x13" "ecdsa-sha2-nistp", 20);
+          l2 = gcry_sexp_find_token (list, "curve", 0);
+          if (!l2)
             elems = "";
-          else if (!strcmp (name, "NIST P-256") || !strcmp (name, "nistp256"))
-            gcry_md_write (md, "256\0\0\0\x08nistp256", 15);
-          else if (!strcmp (name, "NIST P-384") || !strcmp (name, "nistp384"))
-            gcry_md_write (md, "384\0\0\0\x08nistp384", 15);
-          else if (!strcmp (name, "NIST P-521") || !strcmp (name, "nistp521"))
-            gcry_md_write (md, "521\0\0\0\x08nistp521", 15);
           else
-            elems = "";
+            {
+              gcry_free (name);
+              name = gcry_sexp_nth_string (l2, 1);
+              gcry_sexp_release (l2);
+              l2 = NULL;
+              if (!name)
+                elems = "";
+              else if (!strcmp (name, "NIST P-256")||!strcmp (name, "nistp256"))
+                gcry_md_write (md, "256\0\0\0\x08nistp256", 15);
+              else if (!strcmp (name, "NIST P-384")||!strcmp (name, "nistp384"))
+                gcry_md_write (md, "384\0\0\0\x08nistp521", 15);
+              else if (!strcmp (name, "NIST P-521")||!strcmp (name, "nistp521"))
+                gcry_md_write (md, "521\0\0\0\x08nistp521", 15);
+              else
+                elems = "";
+            }
+          if (!*elems)
+            err = gpg_err_make (default_errsource, GPG_ERR_UNKNOWN_CURVE);
         }
-      if (!*elems)
-        err = gpg_err_make (errsource, GPG_ERR_UNKNOWN_CURVE);
       break;
+
     default:
       elems = "";
-      err = gpg_err_make (errsource, GPG_ERR_PUBKEY_ALGO);
+      err = gpg_err_make (default_errsource, GPG_ERR_PUBKEY_ALGO);
       break;
     }
   if (err)
     goto leave;
 
+
   for (idx = 0, s = elems; *s; s++, idx++)
     {
-      gcry_mpi_t a;
-      unsigned char *buf;
-      size_t buflen;
-
       l2 = gcry_sexp_find_token (list, s, 1);
       if (!l2)
         {
-          err = gpg_err_make (errsource, GPG_ERR_INV_SEXP);
+          err = gpg_err_make (default_errsource, GPG_ERR_INV_SEXP);
           goto leave;
         }
-      a = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
-      gcry_sexp_release (l2);
-      l2 = NULL;
-      if (!a)
+      if (blobmode)
         {
-          err = gpg_err_make (errsource, GPG_ERR_INV_SEXP);
-          goto leave;
+          const char *blob;
+          size_t bloblen;
+          unsigned char lenbuf[4];
+
+          blob = gcry_sexp_nth_data (l2, 1, &bloblen);
+          if (!blob)
+            {
+              err = gpg_err_make (default_errsource, GPG_ERR_INV_SEXP);
+              goto leave;
+            }
+          lenbuf[0] = bloblen >> 24;
+          lenbuf[1] = bloblen >> 16;
+          lenbuf[2] = bloblen >>  8;
+          lenbuf[3] = bloblen;
+          gcry_md_write (md, lenbuf, 4);
+          gcry_md_write (md, blob, bloblen);
         }
+      else
+        {
+          gcry_mpi_t a;
+          unsigned char *buf;
+          size_t buflen;
 
-      err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, &buf, &buflen, a);
-      gcry_mpi_release (a);
-      if (err)
-        goto leave;
-      gcry_md_write (md, buf, buflen);
-      gcry_free (buf);
+          a = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+          gcry_sexp_release (l2);
+          l2 = NULL;
+          if (!a)
+            {
+              err = gpg_err_make (default_errsource, GPG_ERR_INV_SEXP);
+              goto leave;
+            }
+
+          err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, &buf, &buflen, a);
+          gcry_mpi_release (a);
+          if (err)
+            goto leave;
+          gcry_md_write (md, buf, buflen);
+          gcry_free (buf);
+        }
     }
 
   *r_fpr = gcry_malloc (as_string? 61:20);
   if (!*r_fpr)
     {
-      err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
       goto leave;
     }
 
@@ -188,31 +258,25 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
 /* Return the Secure Shell type fingerprint for KEY.  The length of
    the fingerprint is returned at R_LEN and the fingerprint itself at
    R_FPR.  In case of an error an error code is returned and NULL
-   stored at R_FPR.  This function is usually called via the
-   ssh_get_fingerprint macro which makes sure to use the correct value
-   for ERRSOURCE. */
+   stored at R_FPR.  */
 gpg_error_t
-_ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
-                      gpg_err_source_t errsource)
+ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len)
 {
-  return get_fingerprint (key, r_fpr, r_len, errsource, 0);
+  return get_fingerprint (key, r_fpr, r_len, 0);
 }
 
 
 /* Return the Secure Shell type fingerprint for KEY as a string.  The
    fingerprint is mallcoed and stored at R_FPRSTR.  In case of an
-   error an error code is returned and NULL stored at R_FPRSTR.  This
-   function is usually called via the ssh_get_fingerprint_string macro
-   which makes sure to use the correct value for ERRSOURCE. */
+   error an error code is returned and NULL stored at R_FPRSTR.  */
 gpg_error_t
-_ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr,
-                             gpg_err_source_t errsource)
+ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr)
 {
   gpg_error_t err;
   size_t dummy;
   void *string;
 
-  err = get_fingerprint (key, &string, &dummy, errsource, 1);
+  err = get_fingerprint (key, &string, &dummy, 1);
   *r_fprstr = string;
   return err;
 }
index 1813c8b..dcf0787 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #define GNUPG_COMMON_SSH_UTILS_H
 
 
-gpg_error_t _ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len,
-                                  gpg_err_source_t errsource);
-#define ssh_get_fingerprint(a,b,c)                              \
-  _ssh_get_fingerprint ((a), (b), (c), GPG_ERR_SOURCE_DEFAULT)
-
-gpg_error_t _ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr,
-                                         gpg_err_source_t errsource);
-#define ssh_get_fingerprint_string(a,b)                         \
-  _ssh_get_fingerprint_string ((a), (b), GPG_ERR_SOURCE_DEFAULT)
+gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len);
 
+gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr);
 
 
 #endif /*GNUPG_COMMON_SSH_UTILS_H*/
index 7b9f4a3..435279c 100644 (file)
@@ -27,7 +27,7 @@
 
 /* Return the status string for code NO. */
 const char *
-get_status_string ( int no ) 
+get_status_string ( int no )
 {
   int idx = statusstr_msgidxof (no);
   if (idx == -1)
@@ -41,7 +41,7 @@ const char *
 get_inv_recpsgnr_code (gpg_error_t err)
 {
   const char *errstr;
-  
+
   switch (gpg_err_code (err))
     {
     case GPG_ERR_NO_PUBKEY:       errstr = "1"; break;
index f101bf0..9219bf4 100644 (file)
@@ -32,8 +32,6 @@ enum
 
     STATUS_BADARMOR,
 
-    STATUS_RSA_OR_IDEA,
-
     STATUS_TRUST_UNDEFINED,
     STATUS_TRUST_NEVER,
     STATUS_TRUST_MARGINAL,
@@ -86,8 +84,6 @@ enum
     STATUS_NOTATION_NAME,
     STATUS_NOTATION_DATA,
     STATUS_POLICY_URL,
-    STATUS_BEGIN_STREAM,
-    STATUS_END_STREAM,
     STATUS_KEY_CREATED,
     STATUS_USERID_HINT,
     STATUS_UNEXPECTED,
@@ -99,7 +95,6 @@ enum
     STATUS_ALREADY_SIGNED,
     STATUS_KEYEXPIRED,
     STATUS_KEYREVOKED,
-    STATUS_SIGEXPIRED,
     STATUS_EXPSIG,
     STATUS_EXPKEYSIG,
 
@@ -125,8 +120,11 @@ enum
     STATUS_PKA_TRUST_GOOD,
 
     STATUS_TRUNCATED,
+    STATUS_MOUNTPOINT,
+
+    STATUS_PINENTRY_LAUNCHED,
+
     STATUS_ERROR,
-    STATUS_FAILURE,
     STATUS_SUCCESS
 };
 
similarity index 83%
rename from jnlib/stringhelp.c
rename to common/stringhelp.c
index c43b120..e1ddf2c 100644 (file)
@@ -1,21 +1,33 @@
 /* stringhelp.c -  standard string helper functions
- * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005,
- *               2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
+ *               2008, 2009, 2010  Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -38,9 +50,9 @@
 
 #include "libjnlib-config.h"
 #include "utf8conv.h"
+#include "sysutils.h"
 #include "stringhelp.h"
 
-
 #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
 
 /* Sometimes we want to avoid mixing slashes and backslashes on W32
@@ -51,7 +63,7 @@
 static inline char *
 change_slashes (char *name)
 {
-#ifdef HAVE_DRIVE_LETTERS
+#ifdef HAVE_DOSISH_SYSTEM
   char *p;
 
   if (strchr (name, '\\'))
@@ -60,12 +72,35 @@ change_slashes (char *name)
         if (*p == '/')
           *p = '\\';
     }
-#endif /*HAVE_DRIVE_LETTERS*/
+#endif /*HAVE_DOSISH_SYSTEM*/
   return name;
 }
 
 
 /*
+ * Check whether STRING starts with KEYWORD.  The keyword is
+ * delimited by end of string, a space or a tab.  Returns NULL if not
+ * found or a pointer into STRING to the next non-space character
+ * after the KEYWORD (which may be end of string).
+ */
+char *
+has_leading_keyword (const char *string, const char *keyword)
+{
+  size_t n = strlen (keyword);
+
+  if (!strncmp (string, keyword, n)
+      && (!string[n] || string[n] == ' ' || string[n] == '\t'))
+    {
+      string += n;
+      while (*string == ' ' || *string == '\t')
+        string++;
+      return (char*)string;
+    }
+  return NULL;
+}
+
+
+/*
  * Look for the substring SUB in buffer and return a pointer to that
  * substring in BUFFER or NULL if not found.
  * Comparison is case-insensitive.
@@ -276,8 +311,10 @@ make_basename(const char *filepath, const char *inputpath)
     (void)inputpath; /* Only required for riscos.  */
 
     if ( !(p=strrchr(filepath, '/')) )
-#ifdef HAVE_DRIVE_LETTERS
+#ifdef HAVE_DOSISH_SYSTEM
        if ( !(p=strrchr(filepath, '\\')) )
+#endif
+#ifdef HAVE_DRIVE_LETTERS
            if ( !(p=strrchr(filepath, ':')) )
 #endif
              {
@@ -303,8 +340,10 @@ make_dirname(const char *filepath)
     char *p;
 
     if ( !(p=strrchr(filepath, '/')) )
-#ifdef HAVE_DRIVE_LETTERS
+#ifdef HAVE_DOSISH_SYSTEM
        if ( !(p=strrchr(filepath, '\\')) )
+#endif
+#ifdef HAVE_DRIVE_LETTERS
            if ( !(p=strrchr(filepath, ':')) )
 #endif
              {
@@ -349,10 +388,20 @@ get_pwdir (int xmode, const char *name)
       else
         result = jnlib_strdup (pwd->pw_dir);
     }
+#else /*!HAVE_PWD_H*/
+  /* No support at all.  */
+  (void)xmode;
+  (void)name;
 #endif /*HAVE_PWD_H*/
   return result;
 }
 
+
+/* xmode 0 := Return NULL on error
+         1 := Terminate on error
+         2 := Make sure that name is absolute; return NULL on error
+         3 := Make sure that name is absolute; terminate on error
+ */
 static char *
 do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
 {
@@ -362,6 +411,10 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
   int skip = 1;
   char *home_buffer = NULL;
   char *name, *home, *p;
+  int want_abs;
+
+  want_abs = !!(xmode & 2);
+  xmode &= 1;
 
   n = strlen (first_part) + 1;
   argc = 0;
@@ -372,7 +425,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
         {
           if (xmode)
             BUG ();
-          errno = EINVAL;
+          jnlib_set_errno (EINVAL);
           return NULL;
         }
       argc++;
@@ -436,10 +489,67 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
     p = stpcpy (name, first_part);
 
   jnlib_free (home_buffer);
-
   for (argc=0; argv[argc]; argc++)
     p = stpcpy (stpcpy (p, "/"), argv[argc]);
 
+  if (want_abs)
+    {
+#ifdef HAVE_DRIVE_LETTERS
+      p = strchr (name, ':');
+      if (p)
+        p++;
+      else
+        p = name;
+#else
+      p = name;
+#endif
+      if (*p != '/'
+#ifdef HAVE_DRIVE_LETTERS
+          && *p != '\\'
+#endif
+          )
+        {
+          home = gnupg_getcwd ();
+          if (!home)
+            {
+              if (xmode)
+                {
+                  fprintf (stderr, "\nfatal: getcwd failed: %s\n",
+                           strerror (errno));
+                  exit(2);
+                }
+              jnlib_free (name);
+              return NULL;
+            }
+          n = strlen (home) + 1 + strlen (name) + 1;
+          if (xmode)
+            home_buffer = jnlib_xmalloc (n);
+          else
+            {
+              home_buffer = jnlib_malloc (n);
+              if (!home_buffer)
+                {
+                  jnlib_free (name);
+                  return NULL;
+                }
+            }
+          if (p == name)
+            p = home_buffer;
+          else /* Windows case.  */
+            {
+              memcpy (home_buffer, p, p - name + 1);
+              p = home_buffer + (p - name + 1);
+            }
+          strcpy (stpcpy (stpcpy (p, home), "/"), name);
+          jnlib_free (name);
+          name = home_buffer;
+          /* Let's do a simple compression to catch the most common
+             case of using "." for gpg's --homedir option.  */
+          n = strlen (name);
+          if (n > 2 && name[n-2] == '/' && name[n-1] == '.')
+            name[n-2] = 0;
+        }
+    }
   return change_slashes (name);
 }
 
@@ -473,17 +583,47 @@ make_filename_try (const char *first_part, ... )
   return result;
 }
 
+/* Construct an absolute filename from the NULL terminated list of
+   parts.  Tilde expansion is done for the first argument.  This
+   function terminates the process on memory shortage. */
+char *
+make_absfilename (const char *first_part, ... )
+{
+  va_list arg_ptr;
+  char *result;
+
+  va_start (arg_ptr, first_part);
+  result = do_make_filename (3, first_part, arg_ptr);
+  va_end (arg_ptr);
+  return result;
+}
+
+/* Construct an absolute filename from the NULL terminated list of
+   parts.  Tilde expansion is done for the first argument.  This
+   function may return NULL on error. */
+char *
+make_absfilename_try (const char *first_part, ... )
+{
+  va_list arg_ptr;
+  char *result;
+
+  va_start (arg_ptr, first_part);
+  result = do_make_filename (2, first_part, arg_ptr);
+  va_end (arg_ptr);
+  return result;
+}
+
 
 \f
 /* Compare whether the filenames are identical.  This is a
    special version of strcmp() taking the semantics of filenames in
    account.  Note that this function works only on the supplied names
-   without considereing any context like the current directory.  See
+   without considering any context like the current directory.  See
    also same_file_p(). */
 int
 compare_filenames (const char *a, const char *b)
 {
-#ifdef HAVE_DRIVE_LETTERS
+#ifdef HAVE_DOSISH_SYSTEM
   for ( ; *a && *b; a++, b++ )
     {
       if (*a != *b
@@ -741,9 +881,15 @@ w32_strerror (int ec)
 
   if (ec == -1)
     ec = (int)GetLastError ();
+#ifdef HAVE_W32CE_SYSTEM
+  /* There is only a wchar_t FormatMessage.  It does not make much
+     sense to play the conversion game; we print only the code.  */
+  snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ());
+#else
   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
                  strerr, DIM (strerr)-1, NULL);
+#endif
   return strerr;
 }
 #endif /*HAVE_W32_SYSTEM*/
@@ -901,8 +1047,8 @@ strsep (char **stringp, const char *delim)
     return NULL;
 
   /* A frequent case is when the delimiter string contains only one
-     character.  Here we don't need to call the expensive `strpbrk'
-     function and instead work using `strchr'.  */
+     character.  Here we don't need to call the expensive 'strpbrk'
+     function and instead work using 'strchr'.  */
   if (delim[0] == '\0' || delim[1] == '\0')
     {
       char ch = delim[0];
@@ -1079,7 +1225,7 @@ do_strconcat (const char *s1, va_list arg_ptr)
       needed += strlen (argv[argc]);
       if (argc >= DIM (argv)-1)
         {
-          errno = EINVAL;
+          jnlib_set_errno (EINVAL);
           return NULL;
         }
       argc++;
@@ -1141,4 +1287,3 @@ xstrconcat (const char *s1, ...)
     }
   return result;
 }
-
similarity index 79%
rename from jnlib/stringhelp.h
rename to common/stringhelp.h
index a560b16..1ad380e 100644 (file)
@@ -2,20 +2,31 @@
  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
  *               2006, 2007, 2009  Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_STRINGHELP_H
@@ -23,6 +34,9 @@
 
 #include "types.h"
 
+/*-- stringhelp.c --*/
+char *has_leading_keyword (const char *string, const char *keyword);
+
 const char *memistr (const void *buf, size_t buflen, const char *sub);
 char *mem2str( char *, const void *, size_t);
 char *trim_spaces( char *string );
@@ -39,6 +53,9 @@ char *make_basename(const char *filepath, const char *inputpath);
 char *make_dirname(const char *filepath);
 char *make_filename( const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
 char *make_filename_try (const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
+char *make_absfilename (const char *first_part, ...) GNUPG_GCC_A_SENTINEL(0);
+char *make_absfilename_try (const char *first_part,
+                            ...) GNUPG_GCC_A_SENTINEL(0);
 int compare_filenames( const char *a, const char *b );
 
 int hextobyte (const char *s);
@@ -103,7 +120,7 @@ void *memrchr (const void *buffer, int c, size_t n);
 
 
 #ifndef HAVE_ISASCII
-static inline int 
+static inline int
 isascii (int c)
 {
   return (((c) & ~0x7f) == 0);
@@ -132,5 +149,8 @@ char *strconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0);
 char *xstrconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0);
 
 
+/*-- mapstrings.c --*/
+const char *map_static_macro_string (const char *string);
+
 
 #endif /*LIBJNLIB_STRINGHELP_H*/
similarity index 75%
rename from jnlib/strlist.c
rename to common/strlist.c
index d45a164..d9aed16 100644 (file)
@@ -1,20 +1,31 @@
 /* strlist.c -  string helpers
  * Copyright (C) 1998, 2000, 2001, 2006 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -57,6 +68,25 @@ add_to_strlist( strlist_t *list, const char *string )
 }
 
 
+/* Add STRING to the LIST at the front.  This function returns NULL
+   and sets ERRNO on memory shortage.  */
+strlist_t
+add_to_strlist_try (strlist_t *list, const char *string)
+{
+  strlist_t sl;
+
+  sl = jnlib_malloc (sizeof *sl + strlen (string));
+  if (sl)
+    {
+      sl->flags = 0;
+      strcpy (sl->d, string);
+      sl->next = *list;
+      *list = sl;
+    }
+  return sl;
+}
+
+
 /* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion
    to UTF-8 is done.  This function terminates the process on memory
    shortage.  */
@@ -65,10 +95,10 @@ strlist_t
 add_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
 {
   strlist_t sl;
-  
+
   if (is_utf8)
     sl = add_to_strlist( list, string );
-  else 
+  else
     {
       char *p = native_to_utf8( string );
       sl = add_to_strlist( list, p );
@@ -106,7 +136,7 @@ strlist_t
 append_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
 {
   strlist_t sl;
-    
+
   if( is_utf8 )
     sl = append_to_strlist( list, string );
   else
@@ -182,4 +212,3 @@ strlist_pop (strlist_t *list)
 
   return str;
 }
-
similarity index 59%
rename from jnlib/strlist.h
rename to common/strlist.h
index 4191624..c72549f 100644 (file)
@@ -1,26 +1,37 @@
 /* strlist.h
  *     Copyright (C) 1998, 2000, 2001, 2006 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_STRLIST_H
 #define LIBJNLIB_STRLIST_H
 
-struct string_list 
+struct string_list
 {
   struct string_list *next;
   unsigned int flags;
@@ -30,6 +41,7 @@ typedef struct string_list *strlist_t;
 
 void    free_strlist (strlist_t sl);
 strlist_t add_to_strlist (strlist_t *list, const char *string);
+strlist_t add_to_strlist_try (strlist_t *list, const char *string);
 
 strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8);
 
index 8f93ff5..afb12ed 100644 (file)
@@ -5,12 +5,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -21,9 +31,9 @@
 
 #include <config.h>
 
-#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
-# undef HAVE_PTH
-# undef USE_GNU_PTH
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+# undef HAVE_NPTH
+# undef USE_NPTH
 #endif
 
 #include <stdio.h>
 # include <sys/resource.h>
 #endif
 #ifdef HAVE_W32_SYSTEM
-# ifndef WINVER
-#  define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
+# if WINVER < 0x0500
+#   define WINVER 0x0500  /* Required for AllowSetForegroundWindow.  */
 # endif
 # ifdef HAVE_WINSOCK2_H
 #  include <winsock2.h>
 # endif
 # include <windows.h>
 #endif
-#ifdef HAVE_PTH
-# include <pth.h>
+#ifdef HAVE_NPTH
+# include <npth.h>
 #endif
 #include <fcntl.h>
 
+#include <assuan.h>
+
+#include "setenv.h"   /* Gnulib replacement.  */
+
 #include "util.h"
 #include "i18n.h"
 
@@ -136,34 +150,34 @@ enable_core_dumps (void)
 
 
 
-/* Return a string which is used as a kind of process ID */
+/* Return a string which is used as a kind of process ID */
 const byte *
-get_session_marker( size_t *rlen )
+get_session_marker (size_t *rlen)
 {
-    static byte marker[SIZEOF_UNSIGNED_LONG*2];
-    static int initialized;
-
-    if ( !initialized ) {
-        volatile ulong aa, bb; /* we really want the uninitialized value */
-        ulong a, b;
-
-        initialized = 1;
-        /* Although this marker is guessable it is not easy to use
-         * for a faked control packet because an attacker does not
-         * have enough control about the time the verification does
-         * take place.  Of course, we can add just more random but
-         * than we need the random generator even for verification
-         * tasks - which does not make sense. */
-        a = aa ^ (ulong)getpid();
-        b = bb ^ (ulong)time(NULL);
-        memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
-        memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
+  static byte marker[SIZEOF_UNSIGNED_LONG*2];
+  static int initialized;
+
+  if (!initialized)
+    {
+      gcry_create_nonce (marker, sizeof marker);
+      initialized = 1;
     }
-    *rlen = sizeof(marker);
-    return marker;
+  *rlen = sizeof (marker);
+  return marker;
+}
+
+/* Return a random number in an unsigned int. */
+unsigned int
+get_uint_nonce (void)
+{
+  unsigned int value;
+
+  gcry_create_nonce (&value, sizeof value);
+  return value;
 }
 
 
+
 #if 0 /* not yet needed - Note that this will require inclusion of
          cmacros.am in Makefile.am */
 int
@@ -261,18 +275,8 @@ check_permissions(const char *path,int extension,int checkonly)
 void
 gnupg_sleep (unsigned int seconds)
 {
-#ifdef HAVE_PTH
-  /* With Pth we force a regular sleep for seconds == 0 so that also
-     the process will give up its timeslot.  */
-  if (!seconds)
-    {
-# ifdef HAVE_W32_SYSTEM
-      Sleep (0);
-# else
-      sleep (0);
-# endif
-    }
-  pth_sleep (seconds);
+#ifdef USE_NPTH
+  npth_sleep (seconds);
 #else
   /* Fixme:  make sure that a sleep won't wake up to early.  */
 # ifdef HAVE_W32_SYSTEM
@@ -292,7 +296,10 @@ gnupg_sleep (unsigned int seconds)
 int
 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
 {
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32CE_SYSTEM)
+  (void)for_write;
+  return (int) fd;
+#elif defined(HAVE_W32_SYSTEM)
   int x;
 
   if (fd == GNUPG_INVALID_FD)
@@ -311,11 +318,16 @@ translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
 }
 
 /* This is the same as translate_sys2libc_fd but takes an integer
-   which is assumed to be such an system handle.  */
+   which is assumed to be such an system handle.  On WindowsCE the
+   passed FD is a rendezvous ID and the function finishes the pipe
+   creation. */
 int
 translate_sys2libc_fd_int (int fd, int for_write)
 {
-#ifdef HAVE_W32_SYSTEM
+#if HAVE_W32CE_SYSTEM
+  fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
+  return translate_sys2libc_fd ((void*)fd, for_write);
+#elif HAVE_W32_SYSTEM
   if (fd <= 2)
     return fd; /* Do not do this for error, stdin, stdout, stderr. */
 
@@ -337,8 +349,15 @@ gnupg_tmpfile (void)
 {
 #ifdef HAVE_W32_SYSTEM
   int attempts, n;
+#ifdef HAVE_W32CE_SYSTEM
+  wchar_t buffer[MAX_PATH+7+12+1];
+# define mystrlen(a) wcslen (a)
+  wchar_t *name, *p;
+#else
   char buffer[MAX_PATH+7+12+1];
+# define mystrlen(a) strlen (a)
   char *name, *p;
+#endif
   HANDLE file;
   int pid = GetCurrentProcessId ();
   unsigned int value;
@@ -350,13 +369,18 @@ gnupg_tmpfile (void)
   sec_attr.bInheritHandle = TRUE;
 
   n = GetTempPath (MAX_PATH+1, buffer);
-  if (!n || n > MAX_PATH || strlen (buffer) > MAX_PATH)
+  if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
     {
-      errno = ENOENT;
+      gpg_err_set_errno (ENOENT);
       return NULL;
     }
-  p = buffer + strlen (buffer);
+  p = buffer + mystrlen (buffer);
+#ifdef HAVE_W32CE_SYSTEM
+  wcscpy (p, L"_gnupg");
+  p += 7;
+#else
   p = stpcpy (p, "_gnupg");
+#endif
   /* We try to create the directory but don't care about an error as
      it may already exist and the CreateFile would throw an error
      anyway.  */
@@ -372,7 +396,11 @@ gnupg_tmpfile (void)
           *p++ = tohex (((value >> 28) & 0x0f));
           value <<= 4;
         }
+#ifdef HAVE_W32CE_SYSTEM
+      wcscpy (p, L".tmp");
+#else
       strcpy (p, ".tmp");
+#endif
       file = CreateFile (buffer,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
@@ -383,6 +411,10 @@ gnupg_tmpfile (void)
       if (file != INVALID_HANDLE_VALUE)
         {
           FILE *fp;
+#ifdef HAVE_W32CE_SYSTEM
+          int fd = (int)file;
+          fp = _wfdopen (fd, L"w+b");
+#else
           int fd = _open_osfhandle ((long)file, 0);
           if (fd == -1)
             {
@@ -390,19 +422,21 @@ gnupg_tmpfile (void)
               return NULL;
             }
           fp = fdopen (fd, "w+b");
+#endif
           if (!fp)
             {
               int save = errno;
               close (fd);
-              errno = save;
+              gpg_err_set_errno (save);
               return NULL;
             }
           return fp;
         }
       Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
     }
-  errno = ENOENT;
+  gpg_err_set_errno (ENOENT);
   return NULL;
+#undef mystrlen
 #else /*!HAVE_W32_SYSTEM*/
   return tmpfile ();
 #endif /*!HAVE_W32_SYSTEM*/
@@ -490,13 +524,197 @@ gnupg_allow_set_foregound_window (pid_t pid)
   if (!pid)
     log_info ("%s called with invalid pid %lu\n",
               "gnupg_allow_set_foregound_window", (unsigned long)pid);
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
   else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
     log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
                (unsigned long)pid, w32_strerror (-1));
 #endif
 }
 
+int
+gnupg_remove (const char *fname)
+{
+#ifdef HAVE_W32CE_SYSTEM
+  int rc;
+  wchar_t *wfname;
+
+  wfname = utf8_to_wchar (fname);
+  if (!wfname)
+    rc = 0;
+  else
+    {
+      rc = DeleteFile (wfname);
+      xfree (wfname);
+    }
+  if (!rc)
+    return -1; /* ERRNO is automagically provided by gpg-error.h.  */
+  return 0;
+#else
+  return remove (fname);
+#endif
+}
+
+
+/* A wrapper around mkdir which takes a string for the mode argument.
+   This makes it easier to handle the mode argument which is not
+   defined on all systems.  The format of the modestring is
+
+      "-rwxrwxrwx"
+
+   '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
+   write allowed, execution allowed with the first group for the user,
+   the second for the group and the third for all others.  If the
+   string is shorter than above the missing mode characters are meant
+   to be not set.  */
+int
+gnupg_mkdir (const char *name, const char *modestr)
+{
+#ifdef HAVE_W32CE_SYSTEM
+  wchar_t *wname;
+  (void)modestr;
+
+  wname = utf8_to_wchar (name);
+  if (!wname)
+    return -1;
+  if (!CreateDirectoryW (wname, NULL))
+    {
+      xfree (wname);
+      return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
+    }
+  xfree (wname);
+  return 0;
+#elif MKDIR_TAKES_ONE_ARG
+  (void)modestr;
+  /* Note: In the case of W32 we better use CreateDirectory and try to
+     set appropriate permissions.  However using mkdir is easier
+     because this sets ERRNO.  */
+  return mkdir (name);
+#else
+  mode_t mode = 0;
+
+  if (modestr && *modestr)
+    {
+      modestr++;
+      if (*modestr && *modestr++ == 'r')
+        mode |= S_IRUSR;
+      if (*modestr && *modestr++ == 'w')
+        mode |= S_IWUSR;
+      if (*modestr && *modestr++ == 'x')
+        mode |= S_IXUSR;
+      if (*modestr && *modestr++ == 'r')
+        mode |= S_IRGRP;
+      if (*modestr && *modestr++ == 'w')
+        mode |= S_IWGRP;
+      if (*modestr && *modestr++ == 'x')
+        mode |= S_IXGRP;
+      if (*modestr && *modestr++ == 'r')
+        mode |= S_IROTH;
+      if (*modestr && *modestr++ == 'w')
+        mode |= S_IWOTH;
+      if (*modestr && *modestr++ == 'x')
+        mode |= S_IXOTH;
+    }
+  return mkdir (name, mode);
+#endif
+}
+
+
+int
+gnupg_setenv (const char *name, const char *value, int overwrite)
+{
+#ifdef HAVE_W32CE_SYSTEM
+  (void)name;
+  (void)value;
+  (void)overwrite;
+  return 0;
+#else
+  return setenv (name, value, overwrite);
+#endif
+}
+
+int
+gnupg_unsetenv (const char *name)
+{
+#ifdef HAVE_W32CE_SYSTEM
+  (void)name;
+  return 0;
+#else
+# ifdef HAVE_UNSETENV
+  return unsetenv (name);
+# else
+  return putenv (name);
+# endif
+#endif
+}
+
+
+/* Return the current working directory as a malloced string.  Return
+   NULL and sets ERRNo on error.  */
+char *
+gnupg_getcwd (void)
+{
+  char *buffer;
+  size_t size = 100;
+
+  for (;;)
+    {
+      buffer = xtrymalloc (size+1);
+      if (!buffer)
+        return NULL;
+#ifdef HAVE_W32CE_SYSTEM
+      strcpy (buffer, "/");  /* Always "/".  */
+      return buffer;
+#else
+      if (getcwd (buffer, size) == buffer)
+        return buffer;
+      xfree (buffer);
+      if (errno != ERANGE)
+        return NULL;
+      size *= 2;
+#endif
+    }
+}
+
+
+\f
+#ifdef HAVE_W32CE_SYSTEM
+/* There is a isatty function declaration in cegcc but it does not
+   make sense, thus we redefine it.  */
+int
+_gnupg_isatty (int fd)
+{
+  (void)fd;
+  return 0;
+}
+#endif
+
+
+#ifdef HAVE_W32CE_SYSTEM
+/* Replacement for getenv which takes care of the our use of getenv.
+   The code is not thread safe but we expect it to work in all cases
+   because it is called for the first time early enough.  */
+char *
+_gnupg_getenv (const char *name)
+{
+  static int initialized;
+  static char *assuan_debug;
+
+  if (!initialized)
+    {
+      assuan_debug = read_w32_registry_string (NULL,
+                                               "\\Software\\GNU\\libassuan",
+                                               "debug");
+      initialized = 1;
+    }
+
+  if (!strcmp (name, "ASSUAN_DEBUG"))
+    return assuan_debug;
+  else
+    return NULL;
+}
+
+#endif /*HAVE_W32CE_SYSTEM*/
+
 
 #ifdef HAVE_W32_SYSTEM
 /* Return the user's security identifier from the current process.  */
index 0a05e2b..d139665 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -41,6 +51,7 @@ void trap_unaligned (void);
 int  disable_core_dumps (void);
 int  enable_core_dumps (void);
 const unsigned char *get_session_marker (size_t *rlen);
+unsigned int get_uint_nonce (void);
 /*int check_permissions (const char *path,int extension,int checkonly);*/
 void gnupg_sleep (unsigned int seconds);
 int translate_sys2libc_fd (gnupg_fd_t fd, int for_write);
@@ -48,12 +59,16 @@ int translate_sys2libc_fd_int (int fd, int for_write);
 FILE *gnupg_tmpfile (void);
 void gnupg_reopen_std (const char *pgmname);
 void gnupg_allow_set_foregound_window (pid_t pid);
-
+int  gnupg_remove (const char *fname);
+int  gnupg_mkdir (const char *name, const char *modestr);
+int  gnupg_setenv (const char *name, const char *value, int overwrite);
+int  gnupg_unsetenv (const char *name);
+char *gnupg_getcwd (void);
 
 #ifdef HAVE_W32_SYSTEM
 void *w32_get_user_sid (void);
 
-# include "../jnlib/w32help.h"
+#include "../common/w32help.h"
 
 #endif /*HAVE_W32_SYSTEM*/
 
index a230dc0..c86c920 100644 (file)
@@ -17,7 +17,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-/* 
+/*
 
    As of now this is only a test program for manual tests.
 
@@ -77,7 +77,7 @@ test_b64enc_file (const char *fname)
   fp = fname ? fopen (fname, "r") : stdin;
   if (!fp)
     {
-      fprintf (stderr, "%s:%d: can't open `%s': %s\n",
+      fprintf (stderr, "%s:%d: can't open '%s': %s\n",
                __FILE__, __LINE__, fname? fname:"[stdin]", strerror (errno));
       fail (0);
     }
@@ -113,7 +113,7 @@ test_b64dec_file (const char *fname)
   fp = fname ? fopen (fname, "r") : stdin;
   if (!fp)
     {
-      fprintf (stderr, "%s:%d: can't open `%s': %s\n",
+      fprintf (stderr, "%s:%d: can't open '%s': %s\n",
                __FILE__, __LINE__, fname? fname:"[stdin]", strerror (errno));
       fail (0);
     }
@@ -179,4 +179,3 @@ main (int argc, char **argv)
 
   return !!errcount;
 }
-
index 4b04f3a..d6056b9 100644 (file)
@@ -72,8 +72,8 @@ test_hex2bin (void)
   unsigned char buffer[20];
   int len;
   int i;
-  
-  
+
+
   for (i=0; valid[i]; i++)
     {
       len = hex2bin (valid[i], buffer, sizeof buffer);
@@ -87,7 +87,7 @@ test_hex2bin (void)
     fail (0);
   if (hex2bin (valid[2], buffer, sizeof buffer) != 41)
     fail (0);
-  
+
   for (i=0; invalid[i]; i++)
     {
       len = hex2bin (invalid[i], buffer, sizeof buffer);
@@ -107,7 +107,7 @@ test_hex2bin (void)
     fail (0);
   if (hex2bin (valid2[1], buffer, 1) != 3)
     fail (0);
-  
+
   for (i=0; invalid2[i]; i++)
     {
       len = hex2bin (invalid2[i], buffer, 1);
@@ -164,8 +164,8 @@ test_hexcolon2bin (void)
   unsigned char buffer[20];
   int len;
   int i;
-  
-  
+
+
   for (i=0; valid[i]; i++)
     {
       len = hexcolon2bin (valid[i], buffer, sizeof buffer);
@@ -179,7 +179,7 @@ test_hexcolon2bin (void)
     fail (0);
   if (hexcolon2bin (valid[3], buffer, sizeof buffer) != 41)
     fail (0);
-  
+
   for (i=0; invalid[i]; i++)
     {
       len = hexcolon2bin (invalid[i], buffer, sizeof buffer);
@@ -199,7 +199,7 @@ test_hexcolon2bin (void)
     fail (0);
   if (hexcolon2bin (valid2[1], buffer, 1) != 3)
     fail (0);
-  
+
   for (i=0; invalid2[i]; i++)
     {
       len = hexcolon2bin (invalid2[i], buffer, 1);
@@ -234,10 +234,10 @@ test_bin2hex (void)
     fail (0);
   if (strcmp (p, hexstuff))
     fail (0);
-  
+
   p = bin2hex (stuff, (size_t)(-1), NULL);
   if (p)
-    fail (0); 
+    fail (0);
   if (errno != ENOMEM)
     fail (1);
 }
@@ -263,13 +263,13 @@ test_bin2hexcolon (void)
 
   p = bin2hexcolon (stuff, 20, NULL);
   if (!p)
-    fail (0); 
+    fail (0);
   if (strcmp (p, hexstuff))
     fail (0);
-  
+
   p = bin2hexcolon (stuff, (size_t)(-1), NULL);
   if (p)
-    fail (0); 
+    fail (0);
   if (errno != ENOMEM)
     fail (1);
 }
@@ -384,10 +384,10 @@ test_hex2str (void)
   for (idx=0; tests[idx].hex; idx++)
     {
       char tmpbuf[100];
-      
+
       assert (strlen (tests[idx].hex)+1 < sizeof tmpbuf);
       strcpy (tmpbuf, tests[idx].hex);
-      
+
       /* Note: we still need to use 20 as buffer length because our
          tests assume that. */
       tail = hex2str (tmpbuf, tmpbuf, 20, &count);
@@ -449,7 +449,7 @@ main (int argc, char **argv)
 {
   (void)argc;
   (void)argv;
-  
+
   test_hex2bin ();
   test_hexcolon2bin ();
   test_bin2hex ();
@@ -458,4 +458,3 @@ main (int argc, char **argv)
 
   return 0;
 }
-
diff --git a/common/t-dns-cert.c b/common/t-dns-cert.c
new file mode 100644 (file)
index 0000000..71c7a9c
--- /dev/null
@@ -0,0 +1,95 @@
+/* t-dns-cert.c - Module test for dns-cert.c
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "util.h"
+#include "dns-cert.h"
+
+
+int
+main (int argc, char **argv)
+{
+  gpg_error_t err;
+  unsigned char *fpr;
+  size_t fpr_len;
+  char *url;
+  estream_t key;
+  char const *name;
+
+  if (argc)
+    {
+      argc--;
+      argv++;
+    }
+
+  if (!argc)
+    name = "simon.josefsson.org";
+  else if (argc == 1)
+    name = *argv;
+  else
+    {
+      fputs ("usage: t-dns-cert [name]\n", stderr);
+      return 1;
+    }
+
+  printf ("CERT lookup on '%s'\n", name);
+
+  err = get_dns_cert (name, &key, &fpr, &fpr_len, &url);
+  if (err)
+    printf ("get_dns_cert failed: %s <%s>\n",
+            gpg_strerror (err), gpg_strsource (err));
+  else if (key)
+    {
+      int count = 0;
+
+      while (es_getc (key) != EOF)
+        count++;
+      printf ("Key found (%d bytes)\n", count);
+    }
+  else
+    {
+      if (fpr)
+       {
+         int i;
+
+         printf ("Fingerprint found (%d bytes): ", (int)fpr_len);
+         for (i = 0; i < fpr_len; i++)
+           printf ("%02X", fpr[i]);
+         putchar ('\n');
+       }
+      else
+       printf ("No fingerprint found\n");
+
+      if (url)
+       printf ("URL found: %s\n", url);
+      else
+       printf ("No URL found\n");
+
+    }
+
+  es_fclose (key);
+  xfree (fpr);
+  xfree (url);
+
+  return 0;
+}
diff --git a/common/t-dotlock.c b/common/t-dotlock.c
new file mode 100644 (file)
index 0000000..d509426
--- /dev/null
@@ -0,0 +1,145 @@
+/* t-dotlock.c - Module test for dotlock.c
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Note: This is a standalone test program which does not rely on any
+   GnuPG helper files.  However, it may also be build as part of the
+   GnuPG build system.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Some quick replacements for stuff we usually expect to be defined
+   in config.h.  Define HAVE_POSIX_SYSTEM for better readability. */
+#if !defined (HAVE_DOSISH_SYSTEM) && defined(_WIN32)
+# define HAVE_DOSISH_SYSTEM 1
+#endif
+#if !defined (HAVE_DOSISH_SYSTEM) && !defined (HAVE_POSIX_SYSTEM)
+# define HAVE_POSIX_SYSTEM 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "dotlock.h"
+
+#define PGM "t-dotlock"
+
+
+static volatile int ctrl_c_pending;
+
+static void
+control_c_handler (int signo)
+{
+  (void)signo;
+  ctrl_c_pending = 1;
+}
+
+
+
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format);
+  fprintf (stderr, PGM "[%lu]: ", (unsigned long)getpid ());
+  vfprintf (stderr, format, arg_ptr);
+  putc ('\n', stderr);
+  va_end (arg_ptr);
+  exit (1);
+}
+
+
+static void
+inf (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format);
+  fprintf (stderr, PGM "[%lu]: ", (unsigned long)getpid ());
+  vfprintf (stderr, format, arg_ptr);
+  putc ('\n', stderr);
+  va_end (arg_ptr);
+}
+
+
+static void
+lock_and_unlock (const char *fname)
+{
+  dotlock_t h;
+
+  h = dotlock_create (fname, 0);
+  if (!h)
+    die ("error creating lock file for '%s': %s", fname, strerror (errno));
+  inf ("lock created");
+
+  while (!ctrl_c_pending)
+    {
+      if (dotlock_take (h, -1))
+        die ("error taking lock");
+      inf ("lock taken");
+      sleep (1);
+      if (dotlock_release (h))
+        die ("error releasing lock");
+      inf ("lock released");
+      sleep (1);
+    }
+  dotlock_destroy (h);
+  inf ("lock destroyed");
+}
+
+
+int
+main (int argc, char **argv)
+{
+  const char *fname;
+
+  if (argc > 1)
+    fname = argv[1];
+  else
+    fname = "t-dotlock.tmp";
+
+  {
+    struct sigaction nact;
+
+    nact.sa_handler = control_c_handler;
+    nact.sa_flags = 0;
+    sigaction (SIGINT, &nact, NULL);
+  }
+
+  dotlock_create (NULL, 0);  /* Initialize (optional).  */
+
+  lock_and_unlock (fname);
+
+
+  return 0;
+}
+
+
+/*
+Local Variables:
+compile-command: "cc -Wall -O2 -D_FILE_OFFSET_BITS=64 -o t-dotlock t-dotlock.c dotlock.c"
+End:
+*/
index 600379b..19079d3 100644 (file)
@@ -149,7 +149,7 @@ test_close_all_fds (void)
             print_open_fds (array);
           free (array);
         }
-      
+
       /* Check whether the except list works.  */
       close_all_fds (3, except);
       array = xget_all_open_fds ();
@@ -180,9 +180,8 @@ main (int argc, char **argv)
       verbose = 1;
       argc--; argv++;
     }
-  
+
   test_close_all_fds ();
 
   return 0;
 }
-
index a4401d8..5d554ee 100644 (file)
@@ -1,5 +1,5 @@
 /* t-gettime.c - Module test for gettime.c
- *     Copyright (C) 2007 Free Software Foundation, Inc.
+ *     Copyright (C) 2007, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -67,8 +67,8 @@ test_isotime2epoch (void)
         {
           fail (idx);
           if (verbose)
-            fprintf (stderr, "string `%s' exp: %ld got: %ld\n",
-                     array[idx].string, (long)array[idx].expected, 
+            fprintf (stderr, "string '%s' exp: %ld got: %ld\n",
+                     array[idx].string, (long)array[idx].expected,
                      (long)val);
         }
       if (array[idx].expected != INVALID)
@@ -77,7 +77,7 @@ test_isotime2epoch (void)
           if (strlen (tbuf) != 15)
             {
               if (verbose)
-                fprintf (stderr, "string `%s', time-t %ld, revert: `%s'\n",
+                fprintf (stderr, "string '%s', time-t %ld, revert: '%s'\n",
                          array[idx].string, (long)val, tbuf);
               fail (idx);
             }
@@ -89,6 +89,90 @@ test_isotime2epoch (void)
 
 
 
+static void
+test_string2isotime (void)
+{
+  struct {
+    const char *string;
+    size_t result;
+    const char *expected;
+  } array [] = {
+    { "19700101T000001",      15, "19700101T000001" },
+    { "19700101T235959",      15, "19700101T235959" },
+    { "19980815T143712",      15, "19980815T143712" },
+    { "19700101T000000",      15, "19700101T000000" },
+    { "19691231T235959",      15, "19691231T235959" },
+    { "19000101T000000",      15, "19000101T000000" },
+    { "",                      0, ""                },
+    { "19000101T00000",        0, ""                },
+    { "20010101t123456",       0, ""                },
+    { "20010101T123456",      15, "20010101T123456" },
+    { "20070629T160000",      15, "20070629T160000" },
+    { "20070629T160000:",     15, "20070629T160000" },
+    { "20070629T160000,",     15, "20070629T160000" },
+    { "20070629T160000 ",     15, "20070629T160000" },
+    { "20070629T160000\n",    15,"20070629T160000"  },
+    { "20070629T160000.",      0, ""                },
+    { "1066-03-20",           10, "10660320T000000" },
+    { "1066-03-20,",          10, "10660320T000000" },
+    { "1066-03-20:",           0, ""                },
+    { "1066-03-20 00",        13, "10660320T000000" },
+    { "1066-03-20 01",        13, "10660320T010000" },
+    { "1066-03-20 23",        13, "10660320T230000" },
+    { "1066-03-20 24",         0, ""                },
+    { "1066-03-20 00:",        0, ""                },
+    { "1066-03-20 00:3",       0, ""                },
+    { "1066-03-20 00:31",     16, "10660320T003100" },
+    { "1066-03-20 00:31:47",  19, "10660320T003147" },
+    { "1066-03-20 00:31:47 ", 19, "10660320T003147" },
+    { "1066-03-20 00:31:47,", 19, "10660320T003147" },
+    { "1066-03-20 00:31:47:",  0, ""                },
+    { "1-03-20 00:31:47:",     0, ""                },
+    { "10-03-20 00:31:47:",    0, ""                },
+    { "106-03-20 00:31:47:",   0, ""                },
+    { "1066-23-20 00:31:47:",  0, ""                },
+    { "1066-00-20 00:31:47:",  0, ""                },
+    { "1066-0-20 00:31:47:",   0, ""                },
+    { "1066-01-2 00:31:47:",   0, ""                },
+    { "1066-01-2  00:31:47:",  0, ""                },
+    { "1066-01-32 00:31:47:",  0, ""                },
+    { "1066-01-00 00:31:47:",  0, ""                },
+    { "1066-03-20  00:31:47:",11, "10660320T000000" },
+    { "1066-03-2000:31:47:",   0, ""                },
+    { "10666-03-20 00:31:47:", 0, ""                },
+    { NULL, 0 }
+  };
+  int idx;
+  size_t result;
+  gnupg_isotime_t tbuf;
+
+  for (idx=0; array[idx].string; idx++)
+    {
+      result = string2isotime (tbuf, array[idx].string);
+      if (result != array[idx].result)
+        {
+          fail (idx);
+          if (verbose)
+            fprintf (stderr, "string '%s' expected: %d, got: %d\n",
+                     array[idx].string, (int)array[idx].result, (int)result);
+        }
+      else if (result && strlen (tbuf) != 15)
+        {
+          fail (idx);
+          if (verbose)
+            fprintf (stderr, "string '%s' invalid isotime returned\n",
+                     array[idx].string);
+        }
+      else if (result && strcmp (array[idx].expected, tbuf))
+        {
+          fail (idx);
+          if (verbose)
+            fprintf (stderr, "string '%s' bad isotime '%s' returned\n",
+                     array[idx].string, tbuf);
+        }
+    }
+}
+
 
 int
 main (int argc, char **argv)
@@ -97,7 +181,7 @@ main (int argc, char **argv)
     verbose = 1;
 
   test_isotime2epoch ();
+  test_string2isotime ();
 
   return !!errcount;
 }
-
index fa5d27a..4c77c9a 100644 (file)
@@ -52,16 +52,15 @@ main (int argc, char **argv)
   result = gnupg_get_help_string (argc? argv[0]:NULL, 0);
   if (!result)
     {
-      fprintf (stderr, 
-               "Error: nothing found for `%s'\n", argc?argv[0]:"(null)");
+      fprintf (stderr,
+               "Error: nothing found for '%s'\n", argc?argv[0]:"(null)");
       errcount++;
     }
   else
     {
-      printf ("key `%s' result=`%s'\n", argc?argv[0]:"(null)", result);
+      printf ("key '%s' result='%s'\n", argc?argv[0]:"(null)", result);
       xfree (result);
     }
 
   return !!errcount;
 }
-
diff --git a/common/t-http.c b/common/t-http.c
new file mode 100644 (file)
index 0000000..e031ef9
--- /dev/null
@@ -0,0 +1,381 @@
+/* t-http.c
+ * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
+ *               2011 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "logging.h"
+#include "http.h"
+
+
+#if HTTP_USE_NTBTLS
+# include <ntbtls.h>
+#elif HTTP_USE_GNUTLS
+# include <gnutls/gnutls.h>  /* For init, logging, and deinit.  */
+#endif /*HTTP_USE_GNUTLS*/
+
+#define PGM "t-http"
+
+static int verbose;
+static int debug;
+static int no_verify;
+
+/* static void */
+/* read_dh_params (const char *fname) */
+/* { */
+/*   gpg_error_t err; */
+/*   int rc; */
+/*   FILE *fp; */
+/*   struct stat st; */
+/*   char *buf; */
+/*   size_t buflen; */
+/*   gnutls_datum_t datum; */
+
+/*   fp = fopen (fname, "rb"); */
+/*   if (!fp) */
+/*     { */
+/*       err = gpg_error_from_syserror (); */
+/*       log_fatal ("can't open '%s': %s\n", fname, gpg_strerror (err)); */
+/*     } */
+
+/*   if (fstat (fileno(fp), &st)) */
+/*     { */
+/*       err = gpg_error_from_syserror (); */
+/*       log_fatal ("can't stat '%s': %s\n", fname, gpg_strerror (err)); */
+/*     } */
+
+/*   buflen = st.st_size; */
+/*   buf = xmalloc (buflen+1); */
+/*   if (fread (buf, buflen, 1, fp) != 1) */
+/*     { */
+/*       err = gpg_error_from_syserror (); */
+/*       log_fatal ("error reading '%s': %s\n", fname, gpg_strerror (err)); */
+/*     } */
+/*   fclose (fp); */
+
+/*   datum.size = buflen; */
+/*   datum.data = buf; */
+
+/*   rc = gnutls_dh_params_import_pkcs3 (dh_params, &datum, GNUTLS_X509_FMT_PEM); */
+/*   if (rc < 0) */
+/*     log_fatal ("gnutls_dh_param_import failed: %s\n", gnutls_strerror (rc)); */
+
+/*   xfree (buf); */
+/* } */
+
+
+
+#if HTTP_USE_GNUTLS
+static gpg_error_t
+verify_callback (http_t hd, http_session_t session, int reserved)
+{
+  (void)hd;
+  (void)reserved;
+  return no_verify? 0 : http_verify_server_credentials (session);
+}
+#endif
+
+#if HTTP_USE_GNUTLS
+static void
+my_gnutls_log (int level, const char *text)
+{
+  fprintf (stderr, "gnutls:L%d: %s", level, text);
+}
+#endif
+
+/* Prepend FNAME with the srcdir environment variable's value and
+   return an allocated filename. */
+static char *
+prepend_srcdir (const char *fname)
+{
+  static const char *srcdir;
+  char *result;
+
+  if (!srcdir && !(srcdir = getenv ("srcdir")))
+    srcdir = ".";
+
+  result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1);
+  strcpy (result, srcdir);
+  strcat (result, "/");
+  strcat (result, fname);
+  return result;
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  gpg_error_t err;
+  int rc;
+  parsed_uri_t uri;
+  uri_tuple_t r;
+  http_t hd;
+  int c;
+  unsigned int my_http_flags = 0;
+  int no_out = 0;
+  int tls_dbg = 0;
+  const char *cafile = NULL;
+  http_session_t session = NULL;
+
+  gpgrt_init ();
+  log_set_prefix (PGM, 1 | 4);
+  if (argc)
+    { argc--; argv++; }
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          fputs ("usage: " PGM " URL\n"
+                 "Options:\n"
+                 "  --verbose         print timings etc.\n"
+                 "  --debug           flyswatter\n"
+                 "  --gnutls-debug N  use GNUTLS debug level N\n"
+                 "  --cacert FNAME    expect CA certificate in file FNAME\n"
+                 "  --no-verify       do not verify the certificate\n"
+                 "  --force-tls       use HTTP_FLAG_FORCE_TLS\n"
+                 "  --no-out          do not print the content\n",
+                 stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose += 2;
+          debug++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--gnutls-debug"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              tls_dbg = atoi (*argv);
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "--cacert"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              cafile = *argv;
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "--no-verify"))
+        {
+          no_verify = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--force-tls"))
+        {
+          my_http_flags |= HTTP_FLAG_FORCE_TLS;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--no-out"))
+        {
+          no_out = 1;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        {
+          fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
+          exit (1);
+        }
+    }
+  if (argc != 1)
+    {
+      fprintf (stderr, PGM ": no or too many URLS given\n");
+      exit (1);
+    }
+
+  if (!cafile)
+    cafile = prepend_srcdir ("tls-ca.pem");
+
+#if HTTP_USE_NTBTLS
+
+  (void)err;
+
+  ntbtls_set_debug (tls_dbg, NULL, NULL);
+
+#elif HTTP_USE_GNUTLS
+
+  rc = gnutls_global_init ();
+  if (rc)
+    log_error ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));
+
+  http_register_tls_callback (verify_callback);
+  http_register_tls_ca (cafile);
+
+  err = http_session_new (&session, NULL);
+  if (err)
+    log_error ("http_session_new failed: %s\n", gpg_strerror (err));
+
+  /* rc = gnutls_dh_params_init(&dh_params); */
+  /* if (rc) */
+  /*   log_error ("gnutls_dh_params_init failed: %s\n", gnutls_strerror (rc)); */
+  /* read_dh_params ("dh_param.pem"); */
+
+  /* rc = gnutls_certificate_set_x509_trust_file */
+  /*   (certcred, "ca.pem", GNUTLS_X509_FMT_PEM); */
+  /* if (rc) */
+  /*   log_error ("gnutls_certificate_set_x509_trust_file failed: %s\n", */
+  /*              gnutls_strerror (rc)); */
+
+  /* gnutls_certificate_set_dh_params (certcred, dh_params); */
+
+  gnutls_global_set_log_function (my_gnutls_log);
+  if (tls_dbg)
+    gnutls_global_set_log_level (tls_dbg);
+
+#endif /*HTTP_USE_GNUTLS*/
+
+  rc = http_parse_uri (&uri, *argv, 1);
+  if (rc)
+    {
+      log_error ("'%s': %s\n", *argv, gpg_strerror (rc));
+      return 1;
+    }
+
+  printf ("Scheme: %s\n", uri->scheme);
+  if (uri->opaque)
+    printf ("Value : %s\n", uri->path);
+  else
+    {
+      printf ("Auth  : %s\n", uri->auth? uri->auth:"[none]");
+      printf ("Host  : %s\n", uri->host);
+      printf ("Port  : %u\n", uri->port);
+      printf ("Path  : %s\n", uri->path);
+      for (r = uri->params; r; r = r->next)
+        {
+          printf ("Params: %s", r->name);
+          if (!r->no_value)
+            {
+              printf ("=%s", r->value);
+              if (strlen (r->value) != r->valuelen)
+                printf (" [real length=%d]", (int) r->valuelen);
+            }
+          putchar ('\n');
+        }
+      for (r = uri->query; r; r = r->next)
+        {
+          printf ("Query : %s", r->name);
+          if (!r->no_value)
+            {
+              printf ("=%s", r->value);
+              if (strlen (r->value) != r->valuelen)
+                printf (" [real length=%d]", (int) r->valuelen);
+            }
+          putchar ('\n');
+        }
+      printf ("TLS   : %s\n",
+              uri->use_tls? "yes":
+              (my_http_flags&HTTP_FLAG_FORCE_TLS)? "forced" : "no");
+
+    }
+  fflush (stdout);
+  http_release_parsed_uri (uri);
+  uri = NULL;
+
+  rc = http_open_document (&hd, *argv, NULL, my_http_flags,
+                           NULL, session, NULL, NULL);
+  if (rc)
+    {
+      log_error ("can't get '%s': %s\n", *argv, gpg_strerror (rc));
+      return 1;
+    }
+  log_info ("open_http_document succeeded; status=%u\n",
+            http_get_status_code (hd));
+
+  {
+    const char **names;
+    int i;
+
+    names = http_get_header_names (hd);
+    if (!names)
+      log_fatal ("http_get_header_names failed: %s\n",
+                 gpg_strerror (gpg_error_from_syserror ()));
+    for (i = 0; names[i]; i++)
+      printf ("HDR: %s: %s\n", names[i], http_get_header (hd, names[i]));
+    xfree (names);
+  }
+  fflush (stdout);
+
+  switch (http_get_status_code (hd))
+    {
+    case 200:
+    case 400:
+    case 401:
+    case 403:
+    case 404:
+      {
+        unsigned long count = 0;
+        while ((c = es_getc (http_get_read_ptr (hd))) != EOF)
+          {
+            count++;
+            if (!no_out)
+              putchar (c);
+          }
+        log_info ("Received bytes: %lu\n", count);
+      }
+      break;
+    case 301:
+    case 302:
+    case 307:
+      log_info ("Redirected to: %s\n", http_get_header (hd, "Location"));
+      break;
+    }
+  http_close (hd, 0);
+
+  http_session_release (session);
+#ifdef HTTP_USE_GNUTLS
+  gnutls_global_deinit ();
+#endif /*HTTP_USE_GNUTLS*/
+
+  return 0;
+}
diff --git a/common/t-mapstrings.c b/common/t-mapstrings.c
new file mode 100644 (file)
index 0000000..14e4bb9
--- /dev/null
@@ -0,0 +1,101 @@
+/* t-mapstrings.c - Regression tests for mapstrings.c
+ * Copyright (C) 2014 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stringhelp.h"
+
+#include "t-support.h"
+
+static void
+test_map_static_macro_string (void)
+{
+  static struct {
+    const char *string;
+    const char *expected;
+    const char *lastresult;
+  } tests[] = {
+    { "@GPG@ (@GNUPG@)",
+      GPG_NAME " (" GNUPG_NAME ")" },
+    { "@GPG@(@GNUPG@)",
+      GPG_NAME "(" GNUPG_NAME ")" },
+    { "@GPG@@GNUPG@",
+      GPG_NAME  GNUPG_NAME },
+    { " @GPG@@GNUPG@",
+      " " GPG_NAME  GNUPG_NAME },
+    { " @GPG@@GNUPG@ ",
+      " " GPG_NAME  GNUPG_NAME " " },
+    { " @GPG@GNUPG@ ",
+      " " GPG_NAME "GNUPG@ " },
+    { " @ GPG@GNUPG@ ",
+      " @ GPG" GNUPG_NAME " " },
+    { "--@GPGTAR@",
+      "--" GPGTAR_NAME }
+  };
+  int testno;
+  const char *result;
+
+  for (testno=0; testno < DIM(tests); testno++)
+    {
+      result = map_static_macro_string (tests[testno].string);
+      if (!result)
+        fail (testno);
+      if (strcmp (result, tests[testno].expected))
+        fail (testno);
+      if (!tests[testno].lastresult)
+        tests[testno].lastresult = result;
+    }
+
+  /* A second time to check that the same string is been returned.  */
+  for (testno=0; testno < DIM(tests); testno++)
+    {
+      result = map_static_macro_string (tests[testno].string);
+      if (!result)
+        fail (testno);
+      if (strcmp (result, tests[testno].expected))
+        fail (testno);
+      if (result != tests[testno].lastresult)
+        fail (testno);
+    }
+}
+
+
+int
+main (int argc, char **argv)
+{
+  (void)argc;
+  (void)argv;
+
+  test_map_static_macro_string ();
+
+  return 0;
+}
diff --git a/common/t-openpgp-oid.c b/common/t-openpgp-oid.c
new file mode 100644 (file)
index 0000000..79e5a70
--- /dev/null
@@ -0,0 +1,189 @@
+/* t-openpgp-oid.c - Module test for openpgp-oid.c
+ *     Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "util.h"
+
+#define pass()  do { ; } while(0)
+#define fail(a,e)                                                       \
+  do { fprintf (stderr, "%s:%d: test %d failed (%s)\n",                 \
+                __FILE__,__LINE__, (a), gpg_strerror (e));              \
+    exit (1);                                                           \
+  } while(0)
+
+
+static void
+test_openpgp_oid_from_str (void)
+{
+   static char *sample_oids[] =
+    {
+      "0.0",
+      "1.0",
+      "1.2.3",
+      "1.2.840.10045.3.1.7",
+      "1.3.132.0.34",
+      "1.3.132.0.35",
+      NULL
+    };
+  gpg_error_t err;
+  gcry_mpi_t a;
+  int idx;
+  char *string;
+  unsigned char *p;
+  unsigned int nbits;
+  size_t length;
+
+  err = openpgp_oid_from_str ("", &a);
+  if (gpg_err_code (err) != GPG_ERR_INV_VALUE)
+    fail (0, err);
+  gcry_mpi_release (a);
+
+  err = openpgp_oid_from_str (".", &a);
+  if (gpg_err_code (err) != GPG_ERR_INV_OID_STRING)
+    fail (0, err);
+  gcry_mpi_release (a);
+
+  err = openpgp_oid_from_str ("0", &a);
+  if (gpg_err_code (err) != GPG_ERR_INV_OID_STRING)
+    fail (0, err);
+  gcry_mpi_release (a);
+
+  for (idx=0; sample_oids[idx]; idx++)
+    {
+      err = openpgp_oid_from_str (sample_oids[idx], &a);
+      if (err)
+        fail (idx, err);
+
+      string = openpgp_oid_to_str (a);
+      if (!string)
+        fail (idx, gpg_error_from_syserror ());
+      if (strcmp (string, sample_oids[idx]))
+        fail (idx, 0);
+      xfree (string);
+
+      p = gcry_mpi_get_opaque (a, &nbits);
+      length = (nbits+7)/8;
+      if (!p || !length || p[0] != length - 1)
+        fail (idx, 0);
+
+      gcry_mpi_release (a);
+    }
+
+}
+
+
+static void
+test_openpgp_oid_to_str (void)
+{
+  static struct {
+    const char *string;
+    unsigned char der[10];
+  } samples[] = {
+    { "1.2.840.10045.3.1.7",
+      {8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }},
+
+    { "1.3.132.0.34",
+      {5, 0x2B, 0x81, 0x04, 0x00, 0x22 }},
+
+    { "1.3.132.0.35",
+      { 5, 0x2B, 0x81, 0x04, 0x00, 0x23 }},
+
+    { NULL }};
+  gcry_mpi_t a;
+  int idx;
+  char *string;
+  unsigned char *p;
+
+  for (idx=0; samples[idx].string; idx++)
+    {
+      p = xmalloc (samples[idx].der[0]+1);
+      memcpy (p, samples[idx].der, samples[idx].der[0]+1);
+      a = gcry_mpi_set_opaque (NULL, p, (samples[idx].der[0]+1)*8);
+      if (!a)
+        fail (idx, gpg_error_from_syserror ());
+
+      string = openpgp_oid_to_str (a);
+      if (!string)
+        fail (idx, gpg_error_from_syserror ());
+      if (strcmp (string, samples[idx].string))
+        fail (idx, 0);
+      xfree (string);
+      gcry_mpi_release (a);
+    }
+
+}
+
+
+static void
+test_openpgp_oid_is_ed25519 (void)
+{
+  static struct
+  {
+    int yes;
+    const char *oidstr;
+  } samples[] = {
+    { 0, "0.0" },
+    { 0, "1.3.132.0.35" },
+    { 0, "1.3.6.1.4.1.3029.1.5.0" },
+    { 0, "1.3.6.1.4.1.3029.1.5.1" }, /* Used during Libgcrypt development. */
+    { 0, "1.3.6.1.4.1.3029.1.5.2" },
+    { 0, "1.3.6.1.4.1.3029.1.5.1.0" },
+    { 0, "1.3.6.1.4.1.3029.1.5" },
+    { 0, "1.3.6.1.4.1.11591.15.0" },
+    { 1, "1.3.6.1.4.1.11591.15.1" }, /* Your the one we want.  */
+    { 0, "1.3.6.1.4.1.11591.15.2" },
+    { 0, "1.3.6.1.4.1.11591.15.1.0" },
+    { 0, "1.3.6.1.4.1.11591.15" },
+    { 0, NULL },
+  };
+  gpg_error_t err;
+  gcry_mpi_t a;
+  int idx;
+
+  for (idx=0; samples[idx].oidstr; idx++)
+    {
+      err = openpgp_oid_from_str (samples[idx].oidstr, &a);
+      if (err)
+        fail (idx, err);
+
+      if (openpgp_oid_is_ed25519 (a) != samples[idx].yes)
+        fail (idx, 0);
+
+      gcry_mpi_release (a);
+    }
+
+}
+
+
+int
+main (int argc, char **argv)
+{
+  (void)argc;
+  (void)argv;
+
+  test_openpgp_oid_from_str ();
+  test_openpgp_oid_to_str ();
+  test_openpgp_oid_is_ed25519 ();
+
+  return 0;
+}
index b8641b9..c148c22 100644 (file)
@@ -37,31 +37,31 @@ test_percent_plus_escape (void)
     const char *string;
     const char *expect;
   } tbl[] = {
-    { 
+    {
       "",
-      "" 
-    }, { 
+      ""
+    }, {
       "a",
       "a",
-    }, { 
+    }, {
       " ",
       "+",
-    }, { 
+    }, {
       "  ",
       "++"
-    }, { 
+    }, {
       "+ +",
       "%2B+%2B"
-    }, { 
+    }, {
       "\" \"",
       "%22+%22"
-    }, { 
+    }, {
       "%22",
       "%2522"
-    }, { 
+    }, {
       "%% ",
       "%25%25+"
-    }, { 
+    }, {
       "\n ABC\t",
       "%0A+ABC%09"
     }, { NULL, NULL }
@@ -69,7 +69,7 @@ test_percent_plus_escape (void)
   char *buf, *buf2;
   int i;
   size_t len;
-  
+
   for (i=0; tbl[i].string; i++)
     {
       buf = percent_plus_escape (tbl[i].string);
@@ -105,11 +105,10 @@ main (int argc, char **argv)
 {
   (void)argc;
   (void)argv;
-  
+
   /* FIXME: We escape_unescape is not tested - only
      percent_plus_unescape.  */
   test_percent_plus_escape ();
 
   return 0;
 }
-
index 94b6683..46c6552 100644 (file)
@@ -46,7 +46,7 @@ listall (session_env_t se)
   while ( (name = session_env_listenv (se, &iterator, &value, &def)) )
     if (verbose)
       printf ("  %s%s=%s\n",  def? "[def] ":"      ", name, value);
-          
+
 }
 
 
@@ -150,7 +150,7 @@ test_all (void)
       fprintf (stderr, "failed to get default of HOME\n");
       exit (1);
     }
-      
+
   s = session_env_getenv (se, "HOME");
   if (s)
     fail(0);  /* This is a default value, thus we should not see it.  */
@@ -194,7 +194,7 @@ test_all (void)
   /* Check that the other object is clean.  */
   {
     int iterator = 0;
-    
+
     if (session_env_listenv (se_0, &iterator, NULL, NULL))
       fail (0);
   }
@@ -211,7 +211,7 @@ test_all (void)
   for (idx=0; idx < 500; idx++)
     {
       char buf[100];
-      
+
       snprintf (buf, sizeof buf, "FOO_%d=Value for %x", idx, idx);
       err = session_env_putenv (se, buf);
       if (err)
@@ -230,7 +230,7 @@ test_all (void)
   for (idx=0; idx < 500; idx++)
     {
       char buf[100];
-      
+
       snprintf (buf, sizeof buf, "FOO_%d", idx);
       err = session_env_putenv (se, buf);
       if (err)
@@ -243,7 +243,7 @@ test_all (void)
   /* Check that all are deleted.  */
   {
     int iterator = 0;
-    
+
     if (session_env_listenv (se, &iterator, NULL, NULL))
       fail (0);
   }
@@ -252,7 +252,7 @@ test_all (void)
   for (idx=0; idx < 500; idx++)
     {
       char buf[100];
-      
+
       if (!(idx % 10))
         {
           if ( !(idx % 3))
@@ -266,7 +266,7 @@ test_all (void)
     }
 
   listall (se);
-  
+
   session_env_release (se);
 
   session_env_release (se_0);
@@ -291,4 +291,3 @@ main (int argc, char **argv)
 
   return 0;
 }
-
index 05da162..987b062 100644 (file)
@@ -35,7 +35,7 @@ test_hash_algo_from_sigval (void)
 {
   int algo;
   /* A real world example.  */
-  unsigned char example1_rsa_sha1[] = 
+  unsigned char example1_rsa_sha1[] =
     ("\x28\x37\x3A\x73\x69\x67\x2D\x76\x61\x6C\x28\x33\x3A\x72\x73\x61"
      "\x28\x31\x3A\x73\x31\x32\x38\x3A\x17\xD2\xE9\x5F\xB4\x24\xD4\x1E"
      "\x8C\xEE\x94\xDA\x41\x42\x1F\x26\x5E\xF4\x6D\xEC\x5B\xBD\x5B\x89"
@@ -48,7 +48,7 @@ test_hash_algo_from_sigval (void)
      "\x27\xAC\x43\x45\xFA\x04\xD1\x22\x29\x29\x28\x34\x3A\x68\x61\x73"
      "\x68\x34\x3A\x73\x68\x61\x31\x29\x29");
   /* The same but without the hash algo. */
-  unsigned char example1_rsa[] = 
+  unsigned char example1_rsa[] =
     ("\x28\x37\x3A\x73\x69\x67\x2D\x76\x61\x6C\x28\x33\x3A\x72\x73\x61"
      "\x28\x31\x3A\x73\x31\x32\x38\x3A\x17\xD2\xE9\x5F\xB4\x24\xD4\x1E"
      "\x8C\xEE\x94\xDA\x41\x42\x1F\x26\x5E\xF4\x6D\xEC\x5B\xBD\x5B\x89"
@@ -105,7 +105,7 @@ test_make_canon_sexp_from_rsa_pk (void)
       "\x3d\x14\xbb\xea\x63\x65\xa7\xf1\xf2\xf8\x97\x74\xa7\x29\x28\x31"
       "\x3a\x65\x34\x3a\x40\x00\x00\x81\x29\x29\x29",
       171
-    }, 
+    },
     {
       "\x63\xB4\x12\x48\x08\x48\xC0\x76\xAA\x8E\xF1\xF8\x7F\x5E\x9B\x89",
       16,
@@ -116,7 +116,7 @@ test_make_canon_sexp_from_rsa_pk (void)
       "\x48\xc0\x76\xaa\x8e\xf1\xf8\x7f\x5e\x9b\x89\x29\x28\x31\x3a\x65"
       "\x31\x3a\x03\x29\x29\x29",
       54,
-    }, 
+    },
     {
       "",
       0,
@@ -149,7 +149,7 @@ test_make_canon_sexp_from_rsa_pk (void)
           fprintf (stderr, "%s:%d: out of core\n", __FILE__, __LINE__);
           exit (1);
         }
-      
+
       if (length != tests[idx].resultlen)
         fail (idx);
       if (memcmp (sexp, tests[idx].result, tests[idx].resultlen))
@@ -189,4 +189,3 @@ main (int argc, char **argv)
 
   return 0;
 }
-
index a8a63cf..5a76233 100644 (file)
@@ -120,14 +120,14 @@ read_file (const char *fname, size_t *r_length)
   fp = fopen (fname, "rb");
   if (!fp)
     {
-      fprintf (stderr, "%s:%d: can't open `%s': %s\n",
+      fprintf (stderr, "%s:%d: can't open '%s': %s\n",
                __FILE__, __LINE__, fname, strerror (errno));
       exit (1);
     }
 
   if (fstat (fileno(fp), &st))
     {
-      fprintf (stderr, "%s:%d: can't stat `%s': %s\n",
+      fprintf (stderr, "%s:%d: can't stat '%s': %s\n",
                __FILE__, __LINE__, fname, strerror (errno));
       exit (1);
     }
@@ -136,7 +136,7 @@ read_file (const char *fname, size_t *r_length)
   buf = xmalloc (buflen+1);
   if (fread (buf, buflen, 1, fp) != 1)
     {
-      fprintf (stderr, "%s:%d: error reading `%s': %s\n",
+      fprintf (stderr, "%s:%d: error reading '%s': %s\n",
                __FILE__, __LINE__, fname, strerror (errno));
       exit (1);
     }
similarity index 80%
rename from jnlib/t-stringhelp.c
rename to common/t-stringhelp.c
index 02041d3..dcd5a45 100644 (file)
@@ -1,20 +1,31 @@
 /* t-stringhelp.c - Regression tests for stringhelp.c
  * Copyright (C) 2007 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -42,14 +53,14 @@ gethome (void)
   if (!home_buffer)
     {
       char *home = getenv("HOME");
-      
-#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H)
+
       if(home)
         home_buffer = xstrdup (home);
+#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H)
       else
         {
           struct passwd *pwd;
-          
+
           pwd = getpwuid (getuid());
           if (pwd)
             home_buffer = xstrdup (pwd->pw_dir);
@@ -60,15 +71,43 @@ gethome (void)
 }
 
 
+static char *
+mygetcwd (void)
+{
+  char *buffer;
+  size_t size = 100;
+
+  for (;;)
+    {
+      buffer = xmalloc (size+1);
+#ifdef HAVE_W32CE_SYSTEM
+      strcpy (buffer, "/");  /* Always "/".  */
+      return buffer;
+#else
+      if (getcwd (buffer, size) == buffer)
+        return buffer;
+      xfree (buffer);
+      if (errno != ERANGE)
+        {
+          fprintf (stderr,"error getting current cwd: %s\n",
+                   strerror (errno));
+          exit (2);
+        }
+      size *= 2;
+#endif
+    }
+}
+
+
 static void
 test_percent_escape (void)
 {
   char *result;
   static struct {
-    const char *extra; 
-    const char *value; 
+    const char *extra;
+    const char *value;
     const char *expected;
-  } tests[] = 
+  } tests[] =
     {
       { NULL, "", "" },
       { NULL, "%", "%25" },
@@ -183,7 +222,7 @@ test_strconcat (void)
     fail (0);
   else if (errno != EINVAL)
     fail (0);
-  
+
 #if __GNUC__ < 4 /* gcc 4.0 has a sentinel attribute.  */
   out = strconcat (NULL);
   if (!out || *out)
@@ -322,10 +361,10 @@ test_make_filename_try (void)
                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                            "1", "2", NULL);
-  if (!out || strcmp (out, 
-                      "1/2/3/4/5/6/7/8/9/10/" 
-                      "1/2/3/4/5/6/7/8/9/10/" 
-                      "1/2/3/4/5/6/7/8/9/10/" 
+  if (!out || strcmp (out,
+                      "1/2/3/4/5/6/7/8/9/10/"
+                      "1/2/3/4/5/6/7/8/9/10/"
+                      "1/2/3/4/5/6/7/8/9/10/"
                       "1/2"))
     fail (0);
   xfree (out);
@@ -396,6 +435,50 @@ test_make_filename_try (void)
 }
 
 
+static void
+test_make_absfilename_try (void)
+{
+  char *out;
+  char *cwd = mygetcwd ();
+  size_t cwdlen = strlen (cwd);
+
+  out = make_absfilename_try ("foo", "bar", NULL);
+  if (!out)
+    fail (0);
+  if (strlen (out) < cwdlen + 7)
+    fail (0);
+  if (strncmp (out, cwd, cwdlen))
+    fail (0);
+  if (strcmp (out+cwdlen, "/foo/bar"))
+    fail (0);
+  xfree (out);
+
+  out = make_absfilename_try ("./foo", NULL);
+  if (!out)
+    fail (1);
+  if (strlen (out) < cwdlen + 5)
+    fail (1);
+  if (strncmp (out, cwd, cwdlen))
+    fail (1);
+  if (strcmp (out+cwdlen, "/./foo"))
+    fail (1);
+  xfree (out);
+
+  out = make_absfilename_try (".", NULL);
+  if (!out)
+    fail (2);
+  if (strlen (out) < cwdlen)
+    fail (2);
+  if (strncmp (out, cwd, cwdlen))
+    fail (2);
+  if (strcmp (out+cwdlen, ""))
+    fail (2);
+  xfree (out);
+
+  xfree (cwd);
+}
+
+
 int
 main (int argc, char **argv)
 {
@@ -407,8 +490,8 @@ main (int argc, char **argv)
   test_strconcat ();
   test_xstrconcat ();
   test_make_filename_try ();
+  test_make_absfilename_try ();
 
   xfree (home_buffer);
   return 0;
 }
-
similarity index 71%
rename from jnlib/t-support.c
rename to common/t-support.c
index d8eba3b..f8b087d 100644 (file)
@@ -1,20 +1,31 @@
 /* t-support.c - helper functions for the regression tests.
  * Copyright (C) 2007 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -120,6 +131,7 @@ gcry_free (void *a)
    require functions called from these inline fucntions.  Although we
    do not use gpg-error, gpg-error.h may get included via gcrypt.h if
    it happens to be used used in libjnlib-config.h.  */
+#ifndef GPG_ERROR_H /* Don't do this if gpg-error.h has been included.  */
 int
 gpg_err_code_from_errno (int err)
 {
@@ -127,17 +139,17 @@ gpg_err_code_from_errno (int err)
   assert (!"stub function");
   return -1;
 }
+#endif /*GPG_ERROR_H*/
 
 
 /* Retrieve the error code directly from the ERRNO variable.  This
    returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped
    (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */
+#ifndef GPG_ERROR_H /* Don't do this if gpg-error.h has been included.  */
 int
 gpg_err_code_from_syserror (void)
 {
   assert (!"stub function");
   return -1;
 }
-
-
-
+#endif /*GPG_ERROR_H*/
similarity index 57%
rename from jnlib/t-support.h
rename to common/t-support.h
index 5270174..0dfcc7a 100644 (file)
@@ -1,20 +1,31 @@
 /* t-support.h - Helper for the regression tests
  * Copyright (C) 2007  Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_T_SUPPORT_H
 #error The regression tests should not include with gcrypt.h
 #endif
 
-/* Repalcement prototypes. */
+#ifdef HAVE_W32CE_SYSTEM
+#include <gpg-error.h>  /* Defines strerror.  */
+#endif
+
+
+#ifndef HAVE_GETENV
+# define getenv(a)  (NULL)
+#endif
+
+#ifndef DIM
+# define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
+# define DIMof(type,member)   DIM(((type *)0)->member)
+#endif
+
+
+/* Replacement prototypes. */
 void *gcry_xmalloc (size_t n);
 void *gcry_xcalloc (size_t n, size_t m);
 void *gcry_xrealloc (void *a, size_t n);
index 45d359e..d13bdfe 100644 (file)
 #include "util.h"
 #include "sysutils.h"
 
+#ifdef HAVE_W32CE_SYSTEM
+# define rewind(f) do { fseek (f, 0, SEEK_SET); clearerr (f); } while (0)
+#endif
+
 #define pass()  do { ; } while(0)
 #define fail(a)  do { fprintf (stderr, "%s:%d: test %d failed\n",\
                                __FILE__,__LINE__, (a));          \
@@ -82,4 +86,3 @@ main (int argc, char **argv)
 
   return !!errcount;
 }
-
diff --git a/common/t-timestuff.c b/common/t-timestuff.c
new file mode 100644 (file)
index 0000000..f39e308
--- /dev/null
@@ -0,0 +1,168 @@
+/* t-timestuff.c - Regression tests for time functions
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include "mischelp.h"
+
+#include "t-support.h"
+
+
+static int
+cmp_time_s (struct tm *a, struct tm *b)
+{
+  if (a->tm_year != b->tm_year
+      || a->tm_mon  != b->tm_mon
+      || a->tm_mday != b->tm_mday
+      || a->tm_hour != b->tm_hour
+      || a->tm_min  != b->tm_min
+      || a->tm_sec  != b->tm_sec
+      || a->tm_wday != b->tm_wday
+      || a->tm_yday != b->tm_yday
+      || !a->tm_isdst != !b->tm_isdst)
+    return -1;
+  return 0;
+}
+
+
+
+static void
+test_timegm (void)
+{
+  static struct {
+    int year, mon, mday, hour, min, sec;
+  } tvalues[] = {
+    { -1 },
+    { -2,  1 },
+    { -2,  2 },
+    { -2,  86399 },
+    { -2,  86400 },
+    { -2,  0x7ffffffe },
+    { -2,  0x7fffffff },
+    /* Note: Because we use mktime below we can only start with the
+       day after Epoch.  */
+    { 1970, 0, 2, 0, 0 , 1},
+    { 1970, 0, 2, 0, 0 , 2},
+    { 1970, 0, 2, 12, 0 , 0},
+    { 1970, 0, 2, 23, 59 , 59},
+    { 1999, 11, 31, 23, 59 , 59},
+    { 2000, 0, 1, 0, 0, 0},
+    { 2000, 0, 1, 0, 0, 1},
+    { 2010, 11, 31, 23, 59 , 59},
+    { 2010, 0, 1, 0, 0, 0},
+    { 2010, 0, 1, 0, 0, 1},
+    /* On GNU based 32 bit systems the end of all ticks will be on
+       20380119T031408 (unless Uli takes compassion on us and changes
+       time_t to a u64).  We check that the previous day is okay.  */
+    { 2038, 0, 18, 23, 59, 59}
+
+  };
+  int tidx;
+  time_t now, atime;
+  struct tm tbuf, tbuf2, *tp;
+
+  for (tidx=0; tidx < DIM (tvalues); tidx++)
+    {
+      if (tvalues[tidx].year == -1)
+        {
+          now = time (NULL);
+        }
+      else if (tvalues[tidx].year == -2)
+        {
+          now = tvalues[tidx].mon;
+        }
+      else
+        {
+          memset (&tbuf, 0, sizeof tbuf);
+          tbuf.tm_year = tvalues[tidx].year - 1900;
+          tbuf.tm_mon  = tvalues[tidx].mon;
+          tbuf.tm_mday = tvalues[tidx].mday;
+          tbuf.tm_hour = tvalues[tidx].hour;
+          tbuf.tm_min  = tvalues[tidx].min;
+          tbuf.tm_sec  = tvalues[tidx].sec;
+#ifdef HAVE_TIMEGM
+          now = timegm (&tbuf);
+#else
+          now = mktime (&tbuf);
+#endif
+        }
+      if (now == (time_t)(-1))
+        fail (tidx);
+
+      tp = gmtime (&now);
+      if (!tp)
+        fail (tidx);
+      tbuf = *tp;
+      tbuf2 = tbuf;
+#ifdef HAVE_TIMEGM
+      atime = timegm (&tbuf);
+#else
+      atime = mktime (&tbuf);
+#endif
+      if (atime == (time_t)(-1))
+        fail (tidx);
+      if (atime != now)
+        fail (tidx);
+
+      tp = gmtime (&atime);
+      if (!tp)
+        fail (tidx);
+      if (cmp_time_s (tp, &tbuf))
+        fail (tidx);
+      if (cmp_time_s (tp, &tbuf2))
+        fail (tidx);
+    }
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+  (void)argc;
+  (void)argv;
+
+  /* If we do not have timegm, we use mktime.  However, we need to use
+     UTC in this case so that the 20380118T235959 test does not fail
+     for other timezones.  */
+#ifndef HAVE_TIMEGM
+  setenv ("TZ", "UTC", 1);
+  tzset ();
+#endif
+
+  test_timegm ();
+
+  return 0;
+}
diff --git a/common/t-w32-reg.c b/common/t-w32-reg.c
new file mode 100644 (file)
index 0000000..cac6db0
--- /dev/null
@@ -0,0 +1,80 @@
+/* t-w32-reg.c - Regression tests for W32 registry functions
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include "mischelp.h"
+
+#include "t-support.h"
+#include "w32help.h"
+
+
+static void
+test_read_registry (void)
+{
+  char *string;
+
+#ifdef HAVE_W32CE_SYSTEM
+  string = read_w32_registry_string ("HKEY_CLASSES_ROOT",
+                                     "BOOTSTRAP\\CLSID", NULL);
+  if (!string)
+    fail (0);
+  fprintf (stderr, "Bootstrap clsid: %s\n", string);
+  xfree (string);
+#endif
+
+  string = read_w32_registry_string
+    ("HKEY_CURRENT_USER",
+     "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
+     "User Agent");
+  if (!string)
+    fail (0);
+  fprintf (stderr, "User agent: %s\n", string);
+  xfree (string);
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+  (void)argc;
+  (void)argv;
+
+  test_read_registry ();
+
+  return 0;
+}
diff --git a/common/t-zb32.c b/common/t-zb32.c
new file mode 100644 (file)
index 0000000..7d509da
--- /dev/null
@@ -0,0 +1,110 @@
+/* t-zb32.c - Module tests for zb32.c
+ * Copyright (C) 2014  Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "util.h"
+
+#define pass()  do { ; } while(0)
+#define fail(a)  do { fprintf (stderr, "%s:%d: test %d failed\n",\
+                               __FILE__,__LINE__, (a));          \
+                     errcount++;                                 \
+                   } while(0)
+
+static int errcount;
+
+
+static void
+test_zb32enc (void)
+{
+  static struct {
+    size_t datalen;
+    char *data;
+    const char *expected;
+  } tests[] = {
+    /* From the DESIGN document.  */
+    {  1, "\x00", "y" },
+    {  1, "\x80", "o" },
+    {  2, "\x40", "e" },
+    {  2, "\xc0", "a" },
+    { 10, "\x00\x00", "yy" },
+    { 10, "\x80\x80", "on" },
+    { 20, "\x8b\x88\x80", "tqre" },
+    { 24, "\xf0\xbf\xc7", "6n9hq" },
+    { 24, "\xd4\x7a\x04", "4t7ye" },
+    /* The next vector is strange: The DESIGN document from 2007 gives
+       "8ik66o" as result, the revision from 2009 gives "6im5sd".  I
+       look at it for quite some time and came to the conclusion that
+       "6im54d" is the right encoding.  */
+    { 30, "\xf5\x57\xbd\x0c", "6im54d" },
+    /* From ccrtp's Java code.  */
+    { 40, "\x01\x01\x01\x01\x01", "yryonyeb" },
+    { 15, "\x01\x01", "yry" },
+    { 80, "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01", "yryonyebyryonyeb" },
+    { 15, "\x81\x81", "ogy" },
+    { 16, "\x81\x81", "ogyo" },
+    { 20, "\x81\x81\x81", "ogya" },
+    { 64, "\x81\x81\x81\x81\x81\x81\x81\x81", "ogyadycbogyan" },
+    /* More tests.  */
+    { 0,  "", "" }
+  };
+  int tidx;
+  char *output;
+
+  for (tidx = 0; tidx < DIM(tests); tidx++)
+    {
+      output = zb32_encode (tests[tidx].data, tests[tidx].datalen);
+      if (!output)
+        {
+          fprintf (stderr, "%s:%d: error encoding test %d: %s\n",
+                   __FILE__, __LINE__, tidx, strerror (errno));
+          exit (1);
+        }
+      /* puts (output); */
+      if (strcmp (output, tests[tidx].expected))
+        fail (tidx);
+      xfree (output);
+    }
+}
+
+
+int
+main (int argc, char **argv)
+{
+  (void)argc;
+  (void)argv;
+
+  test_zb32enc ();
+
+  return !!errcount;
+}
diff --git a/common/tls-ca.pem b/common/tls-ca.pem
new file mode 100644 (file)
index 0000000..c296466
--- /dev/null
@@ -0,0 +1,30 @@
+Issuer ...: /CN=UTN-USERFirst-Hardware/OU=http:\x2f\x2fwww.usertrust.com/O=The USERTRUST Network/L=Salt Lake City/ST=UT/C=US
+Serial ...: 44BE0C8B500024B411D3362AFE650AFD
+Subject ..: /CN=UTN-USERFirst-Hardware/OU=http:\x2f\x2fwww.usertrust.com/O=The USERTRUST Network/L=Salt Lake City/ST=UT/C=US
+
+-----BEGIN CERTIFICATE-----
+MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
+lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
+SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
+A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
+MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
+d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
+cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
+0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
+M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
+MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
+oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
+DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
+oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
+dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
+bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
+BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
+//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
+CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
+CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
+3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
+KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
+-----END CERTIFICATE-----
index c687564..51a0907 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -34,6 +44,7 @@ typedef int gpg_error_t;
 #include <gpg-error.h>
 #endif
 
+#include "util.h"
 #include "tlv.h"
 
 static const unsigned char *
@@ -45,7 +56,7 @@ do_find_tlv (const unsigned char *buffer, size_t length,
   size_t len;
   int this_tag;
   int composite;
-    
+
   for (;;)
     {
       buffer = s;
@@ -97,7 +108,7 @@ do_find_tlv (const unsigned char *buffer, size_t length,
              nesting. */
           const unsigned char *tmp_s;
           size_t tmp_len;
-          
+
           tmp_s = do_find_tlv (s, len, tag, &tmp_len, nestlevel+1);
           if (tmp_s)
             {
@@ -151,11 +162,10 @@ find_tlv_unchecked (const unsigned char *buffer, size_t length,
    and the length part from the TLV triplet.  Update BUFFER and SIZE
    on success. */
 gpg_error_t
-_parse_ber_header (unsigned char const **buffer, size_t *size,
-                   int *r_class, int *r_tag, 
-                   int *r_constructed, int *r_ndef,
-                   size_t *r_length, size_t *r_nhdr,
-                   gpg_err_source_t errsource)
+parse_ber_header (unsigned char const **buffer, size_t *size,
+                  int *r_class, int *r_tag,
+                  int *r_constructed, int *r_ndef,
+                  size_t *r_length, size_t *r_nhdr)
 {
   int c;
   unsigned long tag;
@@ -168,7 +178,7 @@ _parse_ber_header (unsigned char const **buffer, size_t *size,
 
   /* Get the tag. */
   if (!length)
-    return gpg_err_make (errsource, GPG_ERR_EOF);
+    return gpg_err_make (default_errsource, GPG_ERR_EOF);
   c = *buf++; length--; ++*r_nhdr;
 
   *r_class = (c & 0xc0) >> 6;
@@ -182,7 +192,7 @@ _parse_ber_header (unsigned char const **buffer, size_t *size,
         {
           tag <<= 7;
           if (!length)
-            return gpg_err_make (errsource, GPG_ERR_EOF);
+            return gpg_err_make (default_errsource, GPG_ERR_EOF);
           c = *buf++; length--; ++*r_nhdr;
           tag |= c & 0x7f;
 
@@ -193,7 +203,7 @@ _parse_ber_header (unsigned char const **buffer, size_t *size,
 
   /* Get the length. */
   if (!length)
-    return gpg_err_make (errsource, GPG_ERR_EOF);
+    return gpg_err_make (default_errsource, GPG_ERR_EOF);
   c = *buf++; length--; ++*r_nhdr;
 
   if ( !(c & 0x80) )
@@ -201,30 +211,30 @@ _parse_ber_header (unsigned char const **buffer, size_t *size,
   else if (c == 0x80)
     *r_ndef = 1;
   else if (c == 0xff)
-    return gpg_err_make (errsource, GPG_ERR_BAD_BER);
+    return gpg_err_make (default_errsource, GPG_ERR_BAD_BER);
   else
     {
       unsigned long len = 0;
       int count = c & 0x7f;
 
       if (count > sizeof (len) || count > sizeof (size_t))
-        return gpg_err_make (errsource, GPG_ERR_BAD_BER);
+        return gpg_err_make (default_errsource, GPG_ERR_BAD_BER);
 
       for (; count; count--)
         {
           len <<= 8;
           if (!length)
-            return gpg_err_make (errsource, GPG_ERR_EOF);
+            return gpg_err_make (default_errsource, GPG_ERR_EOF);
           c = *buf++; length--; ++*r_nhdr;
           len |= c & 0xff;
         }
       *r_length = len;
     }
-  
+
   /* Without this kludge some example certs can't be parsed. */
   if (*r_class == CLASS_UNIVERSAL && !*r_tag)
     *r_length = 0;
-  
+
   *buffer = buf;
   *size = length;
   return 0;
@@ -234,30 +244,29 @@ _parse_ber_header (unsigned char const **buffer, size_t *size,
 /* FIXME: The following function should not go into this file but for
    now it is easier to keep it here. */
 
-/* Return the next token of an canconical encoded S-expression.  BUF
+/* Return the next token of an canonical encoded S-expression.  BUF
    is the pointer to the S-expression and BUFLEN is a pointer to the
    length of this S-expression (used to validate the syntax).  Both
    are updated to reflect the new position.  The token itself is
-   returned as a pointer into the orginal buffer at TOK and TOKLEN.
+   returned as a pointer into the original buffer at TOK and TOKLEN.
    If a parentheses is the next token, TOK will be set to NULL.
-   TOKLEN is checked to be within the bounds.  On error a error code
-   is returned and all pointers should are not guaranteed to point to
-   a meanigful value. DEPTH should be initialized to 0 and will
+   TOKLEN is checked to be within the bounds.  On error an error code
+   is returned and no pointer is not guaranteed to point to
+   a meaningful value.  DEPTH should be initialized to 0 and will
    reflect on return the actual depth of the tree. To detect the end
    of the S-expression it is advisable to check DEPTH after a
-   successful return:
+   successful return.
 
    depth = 0;
    while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
           && depth)
      process_token (tok, toklen);
-   if (err)  
+   if (err)
      handle_error ();
  */
 gpg_error_t
-_parse_sexp (unsigned char const **buf, size_t *buflen,
-             int *depth, unsigned char const **tok, size_t *toklen,
-             gpg_err_source_t errsource)
+parse_sexp (unsigned char const **buf, size_t *buflen,
+            int *depth, unsigned char const **tok, size_t *toklen)
 {
   const unsigned char *s;
   size_t n, vlen;
@@ -267,7 +276,7 @@ _parse_sexp (unsigned char const **buf, size_t *buflen,
   *tok = NULL;
   *toklen = 0;
   if (!n)
-    return *depth ? gpg_err_make (errsource, GPG_ERR_INV_SEXP) : 0;
+    return *depth ? gpg_err_make (default_errsource, GPG_ERR_INV_SEXP) : 0;
   if (*s == '(')
     {
       s++; n--;
@@ -279,7 +288,7 @@ _parse_sexp (unsigned char const **buf, size_t *buflen,
   if (*s == ')')
     {
       if (!*depth)
-        return gpg_err_make (errsource, GPG_ERR_INV_SEXP);
+        return gpg_err_make (default_errsource, GPG_ERR_INV_SEXP);
       *toklen = 1;
       s++; n--;
       (*depth)--;
@@ -290,10 +299,10 @@ _parse_sexp (unsigned char const **buf, size_t *buflen,
   for (vlen=0; n && *s && *s != ':' && (*s >= '0' && *s <= '9'); s++, n--)
     vlen = vlen*10 + (*s - '0');
   if (!n || *s != ':')
-    return gpg_err_make (errsource, GPG_ERR_INV_SEXP);
+    return gpg_err_make (default_errsource, GPG_ERR_INV_SEXP);
   s++; n--;
   if (vlen > n)
-    return gpg_err_make (errsource, GPG_ERR_INV_SEXP);
+    return gpg_err_make (default_errsource, GPG_ERR_INV_SEXP);
   *tok = s;
   *toklen = vlen;
   s += vlen;
@@ -302,4 +311,3 @@ _parse_sexp (unsigned char const **buf, size_t *buflen,
   *buflen = n;
   return 0;
 }
-
index a04af93..05ddaa4 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -80,33 +90,26 @@ const unsigned char *find_tlv_unchecked (const unsigned char *buffer,
 /* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag
    and the length part from the TLV triplet.  Update BUFFER and SIZE
    on success. */
-gpg_error_t _parse_ber_header (unsigned char const **buffer, size_t *size,
-                               int *r_class, int *r_tag, 
+gpg_error_t parse_ber_header (unsigned char const **buffer, size_t *size,
+                               int *r_class, int *r_tag,
                                int *r_constructed,
-                               int *r_ndef, size_t *r_length, size_t *r_nhdr,
-                               gpg_err_source_t errsource);
-#define parse_ber_header(a,b,c,d,e,f,g,h) \
-        _parse_ber_header ((a),(b),(c),(d),(e),(f),(g),(h),\
-                           GPG_ERR_SOURCE_DEFAULT)
+                              int *r_ndef, size_t *r_length, size_t *r_nhdr);
 
 
-/* Return the next token of an canconical encoded S-expression.  BUF
+/* Return the next token of an canonical encoded S-expression.  BUF
    is the pointer to the S-expression and BUFLEN is a pointer to the
    length of this S-expression (used to validate the syntax).  Both
    are updated to reflect the new position.  The token itself is
-   returned as a pointer into the orginal buffer at TOK and TOKLEN.
+   returned as a pointer into the original buffer at TOK and TOKLEN.
    If a parentheses is the next token, TOK will be set to NULL.
-   TOKLEN is checked to be within the bounds.  On error a error code
-   is returned and all pointers should are not guaranteed to point to
-   a meanigful value. DEPTH should be initialized to 0 and will
+   TOKLEN is checked to be within the bounds.  On error an error code
+   is returned and no pointer is not guaranteed to point to
+   a meaningful value.  DEPTH should be initialized to 0 and will
    reflect on return the actual depth of the tree. To detect the end
    of the S-expression it is advisable to check DEPTH after a
    successful return. */
-gpg_error_t _parse_sexp (unsigned char const **buf, size_t *buflen,
-                         int *depth, unsigned char const **tok, size_t *toklen,
-                         gpg_err_source_t errsource);
-#define parse_sexp(a,b,c,d,e) \
-        _parse_sexp ((a),(b),(c),(d),(e), GPG_ERR_SOURCE_DEFAULT)
+gpg_error_t parse_sexp (unsigned char const **buf, size_t *buflen,
+                        int *depth, unsigned char const **tok, size_t *toklen);
 
 
 
index e70a205..0f8c780 100644 (file)
@@ -1,15 +1,25 @@
 /* ttyio.c -  tty i/O functions
  * Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2006,2007,
- *               2009 Free Software Foundation, Inc.
+ *               2009, 2010 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #include <string.h>
 #include <stdarg.h>
 #include <unistd.h>
+
+#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
+# define USE_W32_CONSOLE 1
+#endif
+
 #ifdef HAVE_TCGETATTR
-# include <termios.h>
+#include <termios.h>
 #else
-# ifdef HAVE_TERMIO_H
-   /* Simulate termios with termio.  */
-#  include <termio.h>
-#  define termios termio
-#  define tcsetattr ioctl
-#  define TCSAFLUSH TCSETAF
-#  define tcgetattr(A,B) ioctl(A,TCGETA,B)
-#  define HAVE_TCGETATTR
-# endif
+#ifdef HAVE_TERMIO_H
+/* simulate termios with termio */
+#include <termio.h>
+#define termios termio
+#define tcsetattr ioctl
+#define TCSAFLUSH TCSETAF
+#define tcgetattr(A,B) ioctl(A,TCGETA,B)
+#define HAVE_TCGETATTR
+#endif
 #endif
-#ifdef _WIN32 /* use the odd Win32 functions */
+#ifdef USE_W32_CONSOLE
 # ifdef HAVE_WINSOCK2_H
 #  include <winsock2.h>
 # endif
 
 #include "util.h"
 #include "ttyio.h"
-#include "estream-printf.h"
 #include "common-defs.h"
 
 #define CONTROL_D ('D' - 'A' + 1)
 
-#ifdef _WIN32 /* use the odd Win32 functions */
+
+#ifdef USE_W32_CONSOLE
 static struct {
     HANDLE in, out;
 } con;
@@ -120,7 +135,7 @@ tty_get_ttyname (void)
     }
 #endif /*HAVE_CTERMID*/
   /* Assume the standard tty on memory error or when tehre is no
-     certmid. */
+     ctermid. */
   return name? name : "/dev/tty";
 }
 
@@ -144,7 +159,7 @@ init_ttyfp(void)
     if( initialized )
        return;
 
-#if defined(_WIN32)
+#if defined(USE_W32_CONSOLE)
     {
        SECURITY_ATTRIBUTES sa;
 
@@ -172,10 +187,12 @@ init_ttyfp(void)
     ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */
     if (my_rl_init_stream)
       my_rl_init_stream (ttyfp);
+#elif defined (HAVE_W32CE_SYSTEM)
+    ttyfp = stderr;
 #else
     ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+");
     if( !ttyfp ) {
-       log_error("cannot open `%s': %s\n", tty_get_ttyname (),
+       log_error("cannot open '%s': %s\n", tty_get_ttyname (),
                   strerror(errno) );
        exit(2);
     }
@@ -220,7 +237,7 @@ tty_printf( const char *fmt, ... )
        init_ttyfp();
 
     va_start( arg_ptr, fmt ) ;
-#ifdef _WIN32
+#ifdef USE_W32_CONSOLE
     {
         char *buf = NULL;
         int n;
@@ -248,14 +265,14 @@ tty_printf( const char *fmt, ... )
 /* Same as tty_printf but if FP is not NULL, behave like a regular
    fprintf. */
 void
-tty_fprintf (FILE *fp, const char *fmt, ... )
+tty_fprintf (estream_t fp, const char *fmt, ... )
 {
   va_list arg_ptr;
 
   if (fp)
     {
       va_start (arg_ptr, fmt) ;
-      vfprintf (fp, fmt, arg_ptr );
+      es_vfprintf (fp, fmt, arg_ptr );
       va_end (arg_ptr);
       return;
     }
@@ -263,83 +280,131 @@ tty_fprintf (FILE *fp, const char *fmt, ... )
   if (no_terminal)
     return;
 
-  if( !initialized )
-    init_ttyfp();
-
-    va_start( arg_ptr, fmt ) ;
-#ifdef _WIN32
-    {
-        char *buf = NULL;
-        int n;
-       DWORD nwritten;
-
-       n = vasprintf(&buf, fmt, arg_ptr);
-       if( !buf )
-           log_bug("vasprintf() failed\n");
-
-       if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) )
-           log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
-       if( n != nwritten )
-           log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten );
-       last_prompt_len += n;
-        xfree (buf);
-    }
+  if (!initialized)
+    init_ttyfp ();
+
+  va_start (arg_ptr, fmt);
+#ifdef USE_W32_CONSOLE
+  {
+    char *buf = NULL;
+    int n;
+    DWORD nwritten;
+
+    n = vasprintf(&buf, fmt, arg_ptr);
+    if (!buf)
+      log_bug("vasprintf() failed\n");
+
+    if (!WriteConsoleA( con.out, buf, n, &nwritten, NULL ))
+      log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
+    if (n != nwritten)
+      log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten );
+    last_prompt_len += n;
+    xfree (buf);
+  }
 #else
-    last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ;
-    fflush(ttyfp);
+  last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ;
+  fflush(ttyfp);
 #endif
-    va_end(arg_ptr);
+  va_end(arg_ptr);
 }
 
 
 /****************
- * Print a string, but filter all control characters out.
+ * Print a string, but filter all control characters out.  If FP is
+ * not NULL print to that stream instead to the tty.
  */
 void
-tty_print_string ( const byte *p, size_t n )
+tty_print_string (estream_t fp, const byte *p, size_t n )
 {
-    if (no_terminal)
+    if (no_terminal && !fp)
        return;
 
-    if( !initialized )
+    if( !initialized & !fp)
        init_ttyfp();
 
-#ifdef _WIN32
+#ifdef USE_W32_CONSOLE
     /* not so effective, change it if you want */
-    for( ; n; n--, p++ )
-       if( iscntrl( *p ) ) {
-           if( *p == '\n' )
-               tty_printf("\\n");
-           else if( !*p )
-               tty_printf("\\0");
-           else
-               tty_printf("\\x%02x", *p);
-       }
-       else
-           tty_printf("%c", *p);
+    if (fp)
+      {
+        for( ; n; n--, p++ )
+          {
+            if( iscntrl( *p ) )
+              {
+                if( *p == '\n' )
+                  tty_fprintf (fp, "\\n");
+                else if( !*p )
+                  tty_fprintf (fp, "\\0");
+                else
+                  tty_fprintf (fp, "\\x%02x", *p);
+              }
+            else
+              tty_fprintf (fp, "%c", *p);
+          }
+      }
+    else
+      {
+        for( ; n; n--, p++ )
+          {
+            if( iscntrl( *p ) )
+              {
+                if( *p == '\n' )
+                  tty_printf ("\\n");
+                else if( !*p )
+                  tty_printf ("\\0");
+                else
+                  tty_printf ("\\x%02x", *p);
+              }
+            else
+              tty_printf ("%c", *p);
+          }
+      }
 #else
-    for( ; n; n--, p++ )
-       if( iscntrl( *p ) ) {
-           putc('\\', ttyfp);
-           if( *p == '\n' )
-               putc('n', ttyfp);
-           else if( !*p )
-               putc('0', ttyfp);
-           else
-               fprintf(ttyfp, "x%02x", *p );
-       }
-       else
-           putc(*p, ttyfp);
+    if (fp)
+      {
+        for( ; n; n--, p++ )
+          {
+            if (iscntrl (*p))
+              {
+                es_putc ('\\', fp);
+                if ( *p == '\n' )
+                  es_putc ('n', fp);
+                else if ( !*p )
+                  es_putc ('0', fp);
+                else
+                  es_fprintf (fp, "x%02x", *p);
+              }
+            else
+              es_putc (*p, fp);
+          }
+      }
+    else
+      {
+        for (; n; n--, p++)
+          {
+            if (iscntrl (*p))
+              {
+                putc ('\\', ttyfp);
+                if ( *p == '\n' )
+                  putc ('n', ttyfp);
+                else if ( !*p )
+                  putc ('0', ttyfp);
+                else
+                  fprintf (ttyfp, "x%02x", *p );
+              }
+            else
+              putc (*p, ttyfp);
+          }
+      }
 #endif
 }
 
 void
-tty_print_utf8_string2( const byte *p, size_t n, size_t max_n )
+tty_print_utf8_string2 (estream_t fp, const byte *p, size_t n, size_t max_n)
 {
     size_t i;
     char *buf;
 
-    if (no_terminal)
+    if (no_terminal && !fp)
        return;
 
     /* we can handle plain ascii simpler, so check for it first */
@@ -353,21 +418,22 @@ tty_print_utf8_string2( const byte *p, size_t n, size_t max_n )
            buf[max_n] = 0;
        }
        /*(utf8 conversion already does the control character quoting)*/
-       tty_printf("%s", buf );
-       xfree( buf );
+       tty_fprintf (fp, "%s", buf);
+       xfree (buf);
     }
     else {
        if( max_n && (n > max_n) ) {
            n = max_n;
        }
-       tty_print_string( p, n );
+       tty_print_string (fp, p, n );
     }
 }
 
+
 void
 tty_print_utf8_string( const byte *p, size_t n )
 {
-    tty_print_utf8_string2( p, n, 0 );
+  tty_print_utf8_string2 (NULL, p, n, 0);
 }
 
 
@@ -398,7 +464,7 @@ do_get( const char *prompt, int hidden )
     buf = xmalloc((n=50));
     i = 0;
 
-#ifdef _WIN32 /* windoze version */
+#ifdef USE_W32_CONSOLE
     if( hidden )
        SetConsoleMode(con.in, HID_INPMODE );
 
@@ -432,9 +498,17 @@ do_get( const char *prompt, int hidden )
     if( hidden )
        SetConsoleMode(con.in, DEF_INPMODE );
 
-#elif defined(__riscos__)
+#elif defined(__riscos__) || defined(HAVE_W32CE_SYSTEM)
     do {
+#ifdef HAVE_W32CE_SYSTEM
+      /* Using getchar is not a correct solution but for now it
+         doesn't matter becuase we have no real console at all.  We
+         should rework this as soon as we have switched this entire
+         module to estream.  */
+        c = getchar();
+#else
         c = riscos_getchar();
+#endif
         if (c == 0xa || c == 0xd) { /* Return || Enter */
             c = (int) '\n';
         } else if (c == 0x8 || c == 0x7f) { /* Backspace || Delete */
@@ -472,7 +546,7 @@ do_get( const char *prompt, int hidden )
         }
     } while (c != '\n');
     i = (i>0) ? i-1 : 0;
-#else /* unix version */
+#else /* Other systems. */
     if( hidden ) {
 #ifdef HAVE_TCGETATTR
        struct termios term;
@@ -513,7 +587,6 @@ do_get( const char *prompt, int hidden )
        i = 1;
     }
 
-
     if( hidden ) {
 #ifdef HAVE_TCGETATTR
        if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) )
@@ -575,7 +648,7 @@ tty_getf (const char *promptfmt, ... )
   char *answer;
 
   va_start (arg_ptr, promptfmt);
-  if (estream_vasprintf (&prompt, promptfmt, arg_ptr) < 0)
+  if (gpgrt_vasprintf (&prompt, promptfmt, arg_ptr) < 0)
     log_fatal ("estream_vasprintf failed: %s\n", strerror (errno));
   va_end (arg_ptr);
   answer = tty_get (prompt);
@@ -605,7 +678,7 @@ tty_kill_prompt()
        last_prompt_len = 0;
     if( !last_prompt_len )
        return;
-#ifdef _WIN32
+#ifdef USE_W32_CONSOLE
     tty_printf("\r%*s\r", last_prompt_len, "");
 #else
     {
index eb2116a..0a66d86 100644 (file)
@@ -4,12 +4,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GNUPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -28,18 +38,19 @@ int tty_batchmode (int onoff);
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
 void tty_printf (const char *fmt, ... )
                  __attribute__ ((format (printf,1,2)));
-void tty_fprintf (FILE *fp, const char *fmt, ... )
+void tty_fprintf (estream_t fp, const char *fmt, ... )
                  __attribute__ ((format (printf,2,3)));
 char *tty_getf (const char *promptfmt, ... )
                  __attribute__ ((format (printf,1,2)));
 #else
 void tty_printf (const char *fmt, ... );
-void tty_fprintf (FILE *fp, const char *fmt, ... );
+void tty_fprintf (estream_t fp, const char *fmt, ... );
 char *tty_getf (const char *promptfmt, ... );
 #endif
-void tty_print_string (const unsigned char *p, size_t n);
+void tty_print_string (estream_t fp, const unsigned char *p, size_t n);
 void tty_print_utf8_string (const unsigned char *p, size_t n);
-void tty_print_utf8_string2 (const unsigned char *p, size_t n, size_t max_n);
+void tty_print_utf8_string2 (estream_t fp,
+                             const unsigned char *p, size_t n, size_t max_n);
 char *tty_get (const char *prompt);
 char *tty_get_hidden (const char *prompt);
 void tty_kill_prompt (void);
similarity index 60%
rename from jnlib/types.h
rename to common/types.h
index 62fa047..97cedc2 100644 (file)
@@ -1,25 +1,40 @@
 /* types.h - define some extra types
  *     Copyright (C) 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_TYPES_H
 #define LIBJNLIB_TYPES_H
 
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
 /* The AC_CHECK_SIZEOF() in configure fails for some machines.
  * we provide some fallback values here */
 #if !SIZEOF_UNSIGNED_SHORT
 #include <sys/types.h>
 
 
+/* We use byte as an abbreviation for unsigned char.  On some
+   platforms this needs special treatment:
+
+   - RISC OS:
+     Norcroft C treats char  = unsigned char  as legal assignment
+                   but char* = unsigned char* as illegal assignment
+     and the same applies to the signed variants as well.  Thus we use
+     char which is anyway unsigned.
+
+   - Windows:
+     Windows typedefs byte in the RPC headers but we need to avoid a
+     warning about a double definition.
+ */
 #ifndef HAVE_BYTE_TYPEDEF
 #  undef byte      /* There might be a macro with this name.  */
-/* Windows typedefs byte in the rpc headers.  Avoid warning about
-   double definition.  */
-#if !(defined(_WIN32) && defined(cbNDRContext))
-  typedef unsigned char byte;
-#endif
+#  ifdef __riscos__
+     typedef char byte;
+#  elif !(defined(_WIN32) && defined(cbNDRContext))
+     typedef unsigned char byte;
+#  endif
 #  define HAVE_BYTE_TYPEDEF
-#endif
+#endif /*!HAVE_BYTE_TYPEDEF*/
 
 #ifndef HAVE_USHORT_TYPEDEF
 #  undef ushort     /* There might be a macro with this name.  */
 #  define HAVE_U32_TYPEDEF
 #endif
 
-#ifndef HAVE_U64_TYPEDEF
-#  undef u64        /* There might be a macro with this name.  */
-#  if SIZEOF_UNSIGNED_INT == 8
-     typedef unsigned int u64;
-#    define HAVE_U64_TYPEDEF
-#  elif SIZEOF_UNSIGNED_LONG == 8
-     typedef unsigned long u64;
-#    define HAVE_U64_TYPEDEF
-#  elif __GNUC__ >= 2 || defined(__SUNPRO_C)
-     typedef unsigned long long u64;
-#    define HAVE_U64_TYPEDEF
-#  endif
-#endif
-
 
 /* Some GCC attributes.  Note that we use also define some in
    mischelp.h, but this header and types.h are not always included.
    Should eventually be put into one file (e.g. nlib-common.h).  */
-#if __GNUC__ >= 4 
+#if __GNUC__ >= 4
 # define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
 #else
-# define GNUPG_GCC_A_SENTINEL(a) 
+# define GNUPG_GCC_A_SENTINEL(a)
 #endif
 
-
-
 #endif /*LIBJNLIB_TYPES_H*/
diff --git a/common/userids.c b/common/userids.c
new file mode 100644 (file)
index 0000000..61e88cc
--- /dev/null
@@ -0,0 +1,376 @@
+/* userids.c - Utility functions for user ids.
+ * Copyright (C) 2001, 2003, 2004, 2006,
+ *               2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+#include "userids.h"
+
+
+/* Parse the user-id NAME and build a search description for it.
+ * Returns 0 on succdess or an error code.  DESC may be NULL to merely
+ * check the validity of a user-id.
+ *
+ * Some used rules:
+ * - If the username starts with 8,9,16 or 17 hex-digits (the first one
+ *   must be in the range 0..9), this is considered a keyid; depending
+ *   on the length a short or complete one.
+ * - If the username starts with 32,33,40 or 41 hex-digits (the first one
+ *   must be in the range 0..9), this is considered a fingerprint.
+ * - If the username starts with a left angle, we assume it is a complete
+ *   email address and look only at this part.
+ * - If the username starts with a colon we assume it is a unified
+ *   key specfification.
+ * - If the username starts with a '.', we assume it is the ending
+ *   part of an email address
+ * - If the username starts with an '@', we assume it is a part of an
+ *   email address
+ * - If the userid start with an '=' an exact compare is done.
+ * - If the userid starts with a '*' a case insensitive substring search is
+ *   done (This is the default).
+ * - If the userid starts with a '+' we will compare individual words
+ *   and a match requires that all the words are in the userid.
+ *   Words are delimited by white space or "()<>[]{}.@-+_,;/&!"
+ *   (note that you can't search for these characters). Compare
+ *   is not case sensitive.
+ * - If the userid starts with a '&' a 40 hex digits keygrip is expected.
+ */
+
+gpg_error_t
+classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
+{
+  const char *s;
+  int hexprefix = 0;
+  int hexlength;
+  int mode = 0;
+  KEYDB_SEARCH_DESC dummy_desc;
+
+  if (!desc)
+    desc = &dummy_desc;
+
+  /* Clear the structure so that the mode field is set to zero unless
+     we set it to the correct value right at the end of this
+     function. */
+  memset (desc, 0, sizeof *desc);
+
+  /* Skip leading spaces.  */
+  for(s = name; *s && spacep (s); s++ )
+    ;
+
+  switch (*s)
+    {
+    case 0:  /* Empty string is an error.  */
+      return gpg_error (GPG_ERR_INV_USER_ID);
+
+    case '.': /* An email address, compare from end.  Note that this
+                 has not yet been implemented in the search code.  */
+      mode = KEYDB_SEARCH_MODE_MAILEND;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '<': /* An email address.  */
+      mode = KEYDB_SEARCH_MODE_MAIL;
+      /* FIXME: The keyring code in g10 assumes that the mail name is
+         prefixed with an '<'.  However the keybox code used for sm/
+         assumes it has been removed.  For now we use this simple hack
+         to overcome the problem.  */
+      if (!openpgp_hack)
+        s++;
+      desc->u.name = s;
+      break;
+
+    case '@':  /* Part of an email address.  */
+      mode = KEYDB_SEARCH_MODE_MAILSUB;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '=':  /* Exact compare.  */
+      mode = KEYDB_SEARCH_MODE_EXACT;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '*':  /* Case insensitive substring search.  */
+      mode = KEYDB_SEARCH_MODE_SUBSTR;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '+':  /* Compare individual words.  Note that this has not
+                  yet been implemented in the search code.  */
+      mode = KEYDB_SEARCH_MODE_WORDS;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '/': /* Subject's DN.  */
+      s++;
+      if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
+        return gpg_error (GPG_ERR_INV_USER_ID);
+      desc->u.name = s;
+      mode = KEYDB_SEARCH_MODE_SUBJECT;
+      break;
+
+    case '#': /* S/N with optional issuer id or just issuer id.  */
+      {
+        const char *si;
+
+        s++;
+        if ( *s == '/')
+          { /* "#/" indicates an issuer's DN.  */
+            s++;
+            if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
+              return gpg_error (GPG_ERR_INV_USER_ID);
+            desc->u.name = s;
+            mode = KEYDB_SEARCH_MODE_ISSUER;
+          }
+        else
+          { /* Serialnumber + optional issuer ID.  */
+            for (si=s; *si && *si != '/'; si++)
+              {
+                 /* Check for an invalid digit in the serial number. */
+                if (!strchr("01234567890abcdefABCDEF", *si))
+                  return gpg_error (GPG_ERR_INV_USER_ID);
+              }
+            desc->sn = (const unsigned char*)s;
+            desc->snlen = -1;
+            if (!*si)
+              mode = KEYDB_SEARCH_MODE_SN;
+            else
+              {
+                s = si+1;
+                if (!*s || spacep (s))  /* No DN or prefixed with a space.  */
+                  return gpg_error (GPG_ERR_INV_USER_ID);
+                desc->u.name = s;
+                mode = KEYDB_SEARCH_MODE_ISSUER_SN;
+              }
+          }
+      }
+      break;
+
+    case ':': /* Unified fingerprint. */
+      {
+        const char *se, *si;
+        int i;
+
+        se = strchr (++s,':');
+        if (!se)
+          return gpg_error (GPG_ERR_INV_USER_ID);
+        for (i=0,si=s; si < se; si++, i++ )
+          {
+            if (!strchr("01234567890abcdefABCDEF", *si))
+              return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid digit.  */
+          }
+        if (i != 32 && i != 40)
+          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr.  */
+        for (i=0,si=s; si < se; i++, si +=2)
+          desc->u.fpr[i] = hextobyte(si);
+        for (; i < 20; i++)
+          desc->u.fpr[i]= 0;
+        s = se + 1;
+        mode = KEYDB_SEARCH_MODE_FPR;
+      }
+      break;
+
+    case '&': /* Keygrip*/
+      {
+        if (hex2bin (s+1, desc->u.grip, 20) < 0)
+          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
+        mode = KEYDB_SEARCH_MODE_KEYGRIP;
+      }
+      break;
+
+    default:
+      if (s[0] == '0' && s[1] == 'x')
+        {
+          hexprefix = 1;
+          s += 2;
+        }
+
+      hexlength = strspn(s, "0123456789abcdefABCDEF");
+      if (hexlength >= 8 && s[hexlength] =='!')
+        {
+          desc->exact = 1;
+          hexlength++; /* Just for the following check.  */
+        }
+
+      /* Check if a hexadecimal number is terminated by EOS or blank.  */
+      if (hexlength && s[hexlength] && !spacep (s+hexlength))
+        {
+          if (hexprefix) /* A "0x" prefix without a correct
+                            termination is an error.  */
+            return gpg_error (GPG_ERR_INV_USER_ID);
+          /* The first characters looked like a hex number, but the
+             entire string is not.  */
+          hexlength = 0;
+        }
+
+      if (desc->exact)
+        hexlength--; /* Remove the bang.  */
+
+      if (hexlength == 8
+          || (!hexprefix && hexlength == 9 && *s == '0'))
+        {
+          /* Short keyid.  */
+          if (hexlength == 9)
+            s++;
+          desc->u.kid[1] = strtoul( s, NULL, 16 );
+          mode = KEYDB_SEARCH_MODE_SHORT_KID;
+        }
+      else if (hexlength == 16
+               || (!hexprefix && hexlength == 17 && *s == '0'))
+        {
+          /* Long keyid.  */
+          char buf[9];
+          if (hexlength == 17)
+            s++;
+          mem2str (buf, s, 9);
+          desc->u.kid[0] = strtoul (buf, NULL, 16);
+          desc->u.kid[1] = strtoul (s+8, NULL, 16);
+          mode = KEYDB_SEARCH_MODE_LONG_KID;
+        }
+      else if (hexlength == 32
+               || (!hexprefix && hexlength == 33 && *s == '0'))
+        {
+          /* MD5 fingerprint.  */
+          int i;
+          if (hexlength == 33)
+            s++;
+          memset (desc->u.fpr+16, 0, 4);
+          for (i=0; i < 16; i++, s+=2)
+            {
+              int c = hextobyte(s);
+              if (c == -1)
+                return gpg_error (GPG_ERR_INV_USER_ID);
+              desc->u.fpr[i] = c;
+            }
+          mode = KEYDB_SEARCH_MODE_FPR16;
+        }
+      else if (hexlength == 40
+               || (!hexprefix && hexlength == 41 && *s == '0'))
+        {
+          /* SHA1/RMD160 fingerprint.  */
+          int i;
+          if (hexlength == 41)
+            s++;
+          for (i=0; i < 20; i++, s+=2)
+            {
+              int c = hextobyte(s);
+              if (c == -1)
+                return gpg_error (GPG_ERR_INV_USER_ID);
+              desc->u.fpr[i] = c;
+            }
+          mode = KEYDB_SEARCH_MODE_FPR20;
+        }
+      else if (!hexprefix)
+        {
+          /* The fingerprint in an X.509 listing is often delimited by
+             colons, so we try to single this case out. */
+          mode = 0;
+          hexlength = strspn (s, ":0123456789abcdefABCDEF");
+          if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength)))
+            {
+              int i;
+
+              for (i=0; i < 20; i++, s += 3)
+                {
+                  int c = hextobyte(s);
+                  if (c == -1 || (i < 19 && s[2] != ':'))
+                    break;
+                  desc->u.fpr[i] = c;
+                }
+              if (i == 20)
+                mode = KEYDB_SEARCH_MODE_FPR20;
+            }
+          if (!mode)
+            {
+              /* Still not found.  Now check for a space separated
+                 OpenPGP v4 fingerprint like:
+                   8061 5870 F5BA D690 3336  86D0 F2AD 85AC 1E42 B367
+                 or
+                   8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367
+               */
+              hexlength = strspn (s, " 0123456789abcdefABCDEF");
+              if (s[hexlength] && s[hexlength] != ' ')
+                hexlength = 0; /* Followed by non-space.  */
+              while (hexlength && s[hexlength-1] == ' ')
+                hexlength--;   /* Trim trailing spaces.  */
+              if ((hexlength == 49 || hexlength == 50)
+                  && (!s[hexlength] || s[hexlength] == ' '))
+                {
+                  int i, c;
+
+                  for (i=0; i < 20; i++)
+                    {
+                      if (i && !(i % 2))
+                        {
+                          if (*s != ' ')
+                            break;
+                          s++;
+                          /* Skip the double space in the middle but
+                             don't require it to help copying
+                             fingerprints from sources which fold
+                             multiple space to one.  */
+                          if (i == 10 && *s == ' ')
+                            s++;
+                        }
+
+                      c = hextobyte(s);
+                      if (c == -1)
+                        break;
+                      desc->u.fpr[i] = c;
+                      s += 2;
+                    }
+                  if (i == 20)
+                    mode = KEYDB_SEARCH_MODE_FPR20;
+                }
+            }
+          if (!mode) /* Default to substring search.  */
+            {
+              desc->exact = 0;
+              desc->u.name = s;
+              mode = KEYDB_SEARCH_MODE_SUBSTR;
+            }
+        }
+      else
+       {
+          /* Hex number with a prefix but with a wrong length.  */
+          return gpg_error (GPG_ERR_INV_USER_ID);
+        }
+    }
+
+  desc->mode = mode;
+  return 0;
+}
diff --git a/common/userids.h b/common/userids.h
new file mode 100644 (file)
index 0000000..dcb6f4a
--- /dev/null
@@ -0,0 +1,39 @@
+/* userids.h - Utility functions for user ids.
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_USERIDS_H
+#define GNUPG_COMMON_USERIDS_H
+
+#include "../kbx/keybox-search-desc.h"
+
+gpg_error_t classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc,
+                              int openpgp_hack);
+
+
+#endif /*GNUPG_COMMON_USERIDS_H*/
similarity index 81%
rename from jnlib/utf8conv.c
rename to common/utf8conv.c
index b5cf6a8..fa08b04 100644 (file)
@@ -1,21 +1,32 @@
 /* utf8conf.c -  UTF8 character set conversion
- * Copyright (C) 1994, 1998, 1999, 2000, 2001,
- *               2003, 2006, 2008  Free Software Foundation, Inc.
+ * Copyright (C) 1994, 1998, 1999, 2000, 2001, 2003, 2006,
+ *               2008, 2010  Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <langinfo.h>
 #endif
 #include <errno.h>
-#include <iconv.h>
+#ifndef HAVE_ANDROID_SYSTEM
+# include <iconv.h>
+#endif
 
 #include "libjnlib-config.h"
 #include "stringhelp.h"
-#include "dynload.h"
 #include "utf8conv.h"
 
 #ifndef MB_LEN_MAX
 
 static const char *active_charset_name = "iso-8859-1";
 static int no_translation;     /* Set to true if we let simply pass through. */
-static int use_iconv;          /* iconv comversion fucntions required. */
+static int use_iconv;          /* iconv conversion functions required. */
+
+
+#ifdef HAVE_ANDROID_SYSTEM
+/* Fake stuff to get things building.  */
+typedef void *iconv_t;
+#define ICONV_CONST
+
+static iconv_t
+iconv_open (const char *tocode, const char *fromcode)
+{
+  (void)tocode;
+  (void)fromcode;
+  return (iconv_t)(-1);
+}
+
+static size_t
+iconv (iconv_t cd, char **inbuf, size_t *inbytesleft,
+       char **outbuf, size_t *outbytesleft)
+{
+  (void)cd;
+  (void)inbuf;
+  (void)inbytesleft;
+  (void)outbuf;
+  (void)outbytesleft;
+  return (size_t)(0);
+}
+
+static int
+iconv_close (iconv_t cd)
+{
+  (void)cd;
+  return 0;
+}
+#endif /*HAVE_ANDROID_SYSTEM*/
 
 
 /* Error handler for iconv failures. This is needed to not clutter the
@@ -65,7 +111,7 @@ handle_iconv_error (const char *to, const char *from, int use_fallback)
         }
 
       if (!x)
-        log_info (_("conversion from `%s' to `%s' not available\n"),
+        log_info (_("conversion from '%s' to '%s' not available\n"),
                   from, to);
     }
   else
@@ -99,7 +145,9 @@ set_native_charset (const char *newset)
 
   if (!newset)
     {
-#ifdef HAVE_W32_SYSTEM
+#ifdef HAVE_ANDROID_SYSTEM
+      newset = "utf-8";
+#elif defined HAVE_W32_SYSTEM
       static char codepage[30];
       unsigned int cpno;
       const char *aliases;
@@ -111,8 +159,10 @@ set_native_charset (const char *newset)
          different one for console input.  Not sure how to cope with
          that.  If the console Code page is not known we fall back to
          the system code page.  */
+#ifndef HAVE_W32CE_SYSTEM
       cpno = GetConsoleOutputCP ();
       if (!cpno)
+#endif
         cpno = GetACP ();
       sprintf (codepage, "CP%u", cpno );
       /* Resolve alias.  We use a long string string and not the usual
@@ -145,7 +195,7 @@ set_native_charset (const char *newset)
             }
         }
 
-#else /*!HAVE_W32_SYSTEM*/
+#else /*!HAVE_W32_SYSTEM && !HAVE_ANDROID_SYSTEM*/
 
 #ifdef HAVE_LANGINFO_CODESET
       newset = nl_langinfo (CODESET);
@@ -179,7 +229,7 @@ set_native_charset (const char *newset)
         }
       newset = codepage;
 #endif /*!HAVE_LANGINFO_CODESET*/
-#endif /*!HAVE_W32_SYSTEM*/
+#endif /*!HAVE_W32_SYSTEM && !HAVE_ANDROID_SYSTEM*/
     }
 
   full_newset = newset;
@@ -325,7 +375,7 @@ native_to_utf8 (const char *orig_string)
           static int shown;
 
           if (!shown)
-            log_info (_("conversion from `%s' to `%s' failed: %s\n"),
+            log_info (_("conversion from '%s' to '%s' failed: %s\n"),
                       active_charset_name, "utf-8", strerror (errno));
           shown = 1;
           /* We don't do any conversion at all but use the strings as is. */
@@ -591,7 +641,7 @@ do_utf8_to_native (const char *string, size_t length, int delim,
               static int shown;
 
               if (!shown)
-                log_info (_("conversion from `%s' to `%s' failed: %s\n"),
+                log_info (_("conversion from '%s' to '%s' failed: %s\n"),
                           "utf-8", active_charset_name, strerror (errno));
               shown = 1;
               /* Didn't worked out.  Try again but without iconv.  */
@@ -634,8 +684,8 @@ utf8_to_native (const char *string, size_t length, int delim)
 
 
 
-/* Wrapper function for iconv_open, formerly required for W32 as we
-   used to dlopen that library on that system.  */
+/* Wrapper function for iconv_open, required for W32 as we dlopen that
+   library on that system.  */
 jnlib_iconv_t
 jnlib_iconv_open (const char *tocode, const char *fromcode)
 {
@@ -643,8 +693,8 @@ jnlib_iconv_open (const char *tocode, const char *fromcode)
 }
 
 
-/* Wrapper function for iconv, formerly required for W32 as we used to
-   dlopen that library on that system.  */
+/* Wrapper function for iconv, required for W32 as we dlopen that
+   library on that system.  */
 size_t
 jnlib_iconv (jnlib_iconv_t cd,
              const char **inbuf, size_t *inbytesleft,
@@ -653,10 +703,83 @@ jnlib_iconv (jnlib_iconv_t cd,
   return iconv ((iconv_t)cd, (char**)inbuf, inbytesleft, outbuf, outbytesleft);
 }
 
-/* Wrapper function for iconv_close, formerly required for W32 as we
-   used to dlopen that library on that system.  */
+/* Wrapper function for iconv_close, required for W32 as we dlopen that
+   library on that system.  */
 int
 jnlib_iconv_close (jnlib_iconv_t cd)
 {
   return iconv_close ((iconv_t)cd);
 }
+
+
+#ifdef HAVE_W32_SYSTEM
+/* Return a malloced string encoded in UTF-8 from the wide char input
+   string STRING.  Caller must free this value.  Returns NULL and sets
+   ERRNO on failure.  Calling this function with STRING set to NULL is
+   not defined.  */
+char *
+wchar_to_utf8 (const wchar_t *string)
+{
+  int n;
+  char *result;
+
+  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
+  if (n < 0)
+    {
+      jnlib_set_errno (EINVAL);
+      return NULL;
+    }
+
+  result = jnlib_malloc (n+1);
+  if (!result)
+    return NULL;
+
+  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
+  if (n < 0)
+    {
+      jnlib_free (result);
+      jnlib_set_errno (EINVAL);
+      result = NULL;
+    }
+  return result;
+}
+
+
+/* Return a malloced wide char string from an UTF-8 encoded input
+   string STRING.  Caller must free this value.  Returns NULL and sets
+   ERRNO on failure.  Calling this function with STRING set to NULL is
+   not defined.  */
+wchar_t *
+utf8_to_wchar (const char *string)
+{
+  int n;
+  size_t nbytes;
+  wchar_t *result;
+
+  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+  if (n < 0)
+    {
+      jnlib_set_errno (EINVAL);
+      return NULL;
+    }
+
+  nbytes = (size_t)(n+1) * sizeof(*result);
+  if (nbytes / sizeof(*result) != (n+1))
+    {
+      jnlib_set_errno (ENOMEM);
+      return NULL;
+    }
+  result = jnlib_malloc (nbytes);
+  if (!result)
+    return NULL;
+
+  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+  if (n < 0)
+    {
+      free (result);
+      jnlib_set_errno (EINVAL);
+      result = NULL;
+    }
+  return result;
+}
+#endif /*HAVE_W32_SYSTEM*/
similarity index 53%
rename from jnlib/utf8conv.h
rename to common/utf8conv.h
index e800f81..a08d3f3 100644 (file)
@@ -1,20 +1,31 @@
 /* utf8conf.h
  *     Copyright (C) 2003, 2006 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef LIBJNLIB_UTF8CONF_H
@@ -36,6 +47,10 @@ size_t jnlib_iconv (jnlib_iconv_t cd, const char **inbuf, size_t *inbytesleft,
                     char **outbuf, size_t *outbytesleft);
 int jnlib_iconv_close (jnlib_iconv_t cd);
 
+#ifdef HAVE_W32_SYSTEM
+char *wchar_to_utf8 (const wchar_t *string);
+wchar_t *utf8_to_wchar (const char *string);
+#endif /*HAVE_W32_SYSTEM*/
 
 
 #endif /*LIBJNLIB_UTF8CONF_H*/
index 48d02e0..dd5fdb1 100644 (file)
@@ -1,57 +1,65 @@
 /* util.h - Utility functions for GnuPG
  * Copyright (C) 2001, 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
  *
- * This file is part of GnuPG.
+ * This file is part of JNLIB, which is a subsystem 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 3 of the License, or
- * (at your option) any later version.
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
  *
- * 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.
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef GNUPG_COMMON_UTIL_H
 #define GNUPG_COMMON_UTIL_H
 
 #include <gcrypt.h> /* We need this for the memory function protos. */
-#include <time.h>   /* We need time_t. */
 #include <errno.h>  /* We need errno.  */
-#include <gpg-error.h> /* We need gpg_error_t. */
+#include <gpg-error.h> /* We need gpg_error_t and estream. */
 
 
 /* Hash function used with libksba. */
 #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
 
 /* Get all the stuff from jnlib. */
-#include "../jnlib/logging.h"
-#include "../jnlib/argparse.h"
-#include "../jnlib/stringhelp.h"
-#include "../jnlib/mischelp.h"
-#include "../jnlib/strlist.h"
-#include "../jnlib/dotlock.h"
-#include "../jnlib/utf8conv.h"
-#include "../jnlib/dynload.h"
+#include "../common/logging.h"
+#include "../common/argparse.h"
+#include "../common/stringhelp.h"
+#include "../common/mischelp.h"
+#include "../common/strlist.h"
+#include "../common/dotlock.h"
+#include "../common/utf8conv.h"
+#include "../common/dynload.h"
 
-#include "init.h"
+#include "gettime.h"
 
 /* Redefine asprintf by our estream version which uses our own memory
    allocator..  */
-#include "estream-printf.h"
-#define asprintf estream_asprintf
-#define vasprintf estream_vasprintf
-
-/* Due to a bug in mingw32's snprintf related to the 'l' modifier we
-   better use our snprintf.  */
-#ifdef HAVE_W32_SYSTEM
-#define snprintf estream_snprintf
-#endif
+#define asprintf gpgrt_asprintf
+#define vasprintf gpgrt_vasprintf
+
+/* Due to a bug in mingw32's snprintf related to the 'l' modifier and
+   for increased portability we use our snprintf on all systems. */
+#undef snprintf
+#define snprintf gpgrt_snprintf
 
 
 /* GCC attributes.  */
@@ -77,6 +85,7 @@ typedef char **rl_completion_func_t (const char *, int, int);
 #define xtryrealloc(a,b) gcry_realloc ((a),(b))
 #define xtrystrdup(a)    gcry_strdup ((a))
 #define xfree(a)         gcry_free ((a))
+#define xfree_fnc        gcry_free
 
 #define xmalloc(a)       gcry_xmalloc ((a))
 #define xmalloc_secure(a)  gcry_xmalloc_secure ((a))
@@ -89,6 +98,12 @@ typedef char **rl_completion_func_t (const char *, int, int);
 #define xmalloc_clear(a) gcry_xcalloc (1, (a))
 #define xmalloc_secure_clear(a) gcry_xcalloc_secure (1, (a))
 
+/* The default error source of the application.  This is different
+   from GPG_ERR_SOURCE_DEFAULT in that it does not depend on the
+   source file and thus is usable in code shared by applications.
+   Defined by init.c.  */
+extern gpg_err_source_t default_errsource;
+
 /* Convenience function to return a gpg-error code for memory
    allocation failures.  This function makes sure that an error will
    be returned even if accidently ERRNO is not set.  */
@@ -98,50 +113,9 @@ out_of_core (void)
   return gpg_error_from_syserror ();
 }
 
-/* A type to hold the ISO time.  Note that this this is the same as
-   the the KSBA type ksba_isotime_t. */
-typedef char gnupg_isotime_t[16];
-
-
-/*-- gettime.c --*/
-time_t gnupg_get_time (void);
-void   gnupg_get_isotime (gnupg_isotime_t timebuf);
-void   gnupg_set_time (time_t newtime, int freeze);
-int    gnupg_faked_time_p (void);
-u32    make_timestamp (void);
-u32    scan_isodatestr (const char *string);
-time_t isotime2epoch (const char *string);
-void   epoch2isotime (gnupg_isotime_t timebuf, time_t atime);
-u32    add_days_to_timestamp (u32 stamp, u16 days);
-const char *strtimevalue (u32 stamp);
-const char *strtimestamp (u32 stamp); /* GMT */
-const char *isotimestamp (u32 stamp); /* GMT */
-const char *asctimestamp (u32 stamp); /* localized */
-gpg_error_t add_seconds_to_isotime (gnupg_isotime_t atime, int nseconds);
-gpg_error_t add_days_to_isotime (gnupg_isotime_t atime, int ndays);
-gpg_error_t check_isotime (const gnupg_isotime_t atime);
-void dump_isotime (const gnupg_isotime_t atime);
-
-/* Copy one ISO date to another, this is inline so that we can do a
-   minimal sanity check.  A null date (empty string) is allowed.  */
-static inline void
-gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s)
-{
-  if (*s)
-    {
-      if ((strlen (s) != 15 || s[8] != 'T'))
-        BUG();
-      memcpy (d, s, 15);
-      d[15] = 0;
-    }
-  else
-    *d = 0;
-}
-
 
 /*-- signal.c --*/
 void gnupg_init_signals (int mode, void (*fast_cleanup)(void));
-void gnupg_pause_on_sigusr (int which);
 void gnupg_block_all_signals (void);
 void gnupg_unblock_all_signals (void);
 
@@ -164,14 +138,18 @@ struct b64state
   int idx;
   int quad_count;
   FILE *fp;
+  estream_t stream;
   char *title;
   unsigned char radbuf[4];
   u32 crc;
   int stop_seen:1;
   int invalid_encoding:1;
+  gpg_error_t lasterr;
 };
 
 gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title);
+gpg_error_t b64enc_start_es (struct b64state *state, estream_t fp,
+                             const char *title);
 gpg_error_t b64enc_write (struct b64state *state,
                           const void *buffer, size_t nbytes);
 gpg_error_t b64enc_finish (struct b64state *state);
@@ -187,8 +165,15 @@ char *zb32_encode (const void *data, unsigned int databits);
 
 
 /*-- sexputil.c */
+char *canon_sexp_to_string (const unsigned char *canon, size_t canonlen);
+void log_printcanon (const char *text,
+                     const unsigned char *sexp, size_t sexplen);
+void log_printsexp (const char *text, gcry_sexp_t sexp);
+
 gpg_error_t make_canon_sexp (gcry_sexp_t sexp,
                              unsigned char **r_buffer, size_t *r_buflen);
+gpg_error_t make_canon_sexp_pad (gcry_sexp_t sexp, int secure,
+                                 unsigned char **r_buffer, size_t *r_buflen);
 gpg_error_t keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
                                      unsigned char *grip);
 int cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b);
@@ -206,7 +191,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
                                         size_t *r_elen);
 gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
                                          size_t keydatalen,
-                                         int *r_algo);
+                                         const char **r_algo);
 
 /*-- convert.c --*/
 int hex2bin (const char *string, void *buffer, size_t length);
@@ -225,6 +210,14 @@ char *percent_unescape (const char *string, int nulrepl);
 size_t percent_plus_unescape_inplace (char *string, int nulrepl);
 size_t percent_unescape_inplace (char *string, int nulrepl);
 
+/*-- openpgp-oid.c --*/
+gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi);
+char *openpgp_oid_to_str (gcry_mpi_t a);
+int openpgp_oid_is_ed25519 (gcry_mpi_t a);
+const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits);
+const char *openpgp_oid_to_curve (const char *oid);
+
+
 
 /*-- homedir.c --*/
 const char *standard_homedir (void);
@@ -235,7 +228,9 @@ const char *gnupg_libexecdir (void);
 const char *gnupg_libdir (void);
 const char *gnupg_datadir (void);
 const char *gnupg_localedir (void);
-const char *dirmngr_socket_name (void);
+const char *gnupg_cachedir (void);
+const char *dirmngr_sys_socket_name (void);
+const char *dirmngr_user_socket_name (void);
 
 /* All module names.  We also include gpg and gpgsm for the sake for
    gpgconf. */
@@ -249,6 +244,7 @@ const char *dirmngr_socket_name (void);
 #define GNUPG_MODULE_NAME_GPG           8
 #define GNUPG_MODULE_NAME_CONNECT_AGENT 9
 #define GNUPG_MODULE_NAME_GPGCONF       10
+#define GNUPG_MODULE_NAME_DIRMNGR_LDAP  11
 const char *gnupg_module_name (int which);
 
 
@@ -273,11 +269,15 @@ char *xasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2);
 /* This is now an alias to estream_asprintf.  */
 char *xtryasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2);
 
+/* Replacement for gcry_cipher_algo_name.  */
+const char *gnupg_cipher_algo_name (int algo);
+
 const char *print_fname_stdout (const char *s);
 const char *print_fname_stdin (const char *s);
-void print_string (FILE *fp, const byte *p, size_t n, int delim);
-void print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim);
-void print_utf8_string (FILE *fp, const byte *p, size_t n);
+void print_utf8_buffer3 (estream_t fp, const void *p, size_t n,
+                         const char *delim);
+void print_utf8_buffer2 (estream_t fp, const void *p, size_t n, int delim);
+void print_utf8_buffer (estream_t fp, const void *p, size_t n);
 void print_hexstring (FILE *fp, const void *buffer, size_t length,
                       int reserved);
 char *make_printable_string (const void *p, size_t n, int delim);
@@ -286,17 +286,38 @@ int is_file_compressed (const char *s, int *ret_rc);
 
 int match_multistr (const char *multistr,const char *match);
 
+int gnupg_compare_version (const char *a, const char *b);
+
 
 /*-- Simple replacement functions. */
-#ifndef HAVE_TTYNAME
+
+/* We use the gnupg_ttyname macro to be safe not to run into conflicts
+   which an extisting but broken ttyname.  */
+#if !defined(HAVE_TTYNAME) || defined(HAVE_BROKEN_TTYNAME)
+# define gnupg_ttyname(n) _gnupg_ttyname ((n))
 /* Systems without ttyname (W32) will merely return NULL. */
 static inline char *
-ttyname (int fd)
+_gnupg_ttyname (int fd)
 {
   (void)fd;
   return NULL;
 }
-#endif /* !HAVE_TTYNAME */
+#else /*HAVE_TTYNAME*/
+# define gnupg_ttyname(n) ttyname ((n))
+#endif /*HAVE_TTYNAME */
+
+#ifdef HAVE_W32CE_SYSTEM
+#define getpid() GetCurrentProcessId ()
+char *_gnupg_getenv (const char *name); /* See sysutils.c */
+#define getenv(a)  _gnupg_getenv ((a))
+char *_gnupg_setenv (const char *name); /* See sysutils.c */
+#define setenv(a,b,c)  _gnupg_setenv ((a),(b),(c))
+int _gnupg_isatty (int fd);
+#define gnupg_isatty(a)  _gnupg_isatty ((a))
+#else
+#define gnupg_isatty(a)  isatty ((a))
+#endif
+
 
 
 /*-- Macros to replace ctype ones to avoid locale problems. --*/
similarity index 72%
rename from jnlib/w32-afunix.c
rename to common/w32-afunix.c
index 6365394..5f56c29 100644 (file)
@@ -1,23 +1,34 @@
 /* w32-afunix.c - AF_UNIX emulation for Windows (Client only).
  * Copyright (C) 2004, 2006 g10 Code GmbH
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
-/* Use of this code is preprecated - you better use the sockt wrappers
+/* Use of this code is deprecated - you better use the socket wrappers
    from libassuan. */
 
 #ifdef _WIN32
@@ -51,14 +62,14 @@ read_port_and_nonce (const char *fname, unsigned short *port, char *nonce)
   fclose (fp);
   if (!nread)
     {
-      errno = ENOFILE;
+      gpg_err_set_errno (EIO);
       return -1;
     }
   buffer[nread] = 0;
   aval = atoi (buffer);
   if (aval < 1 || aval > 65535)
     {
-      errno = EINVAL;
+      gpg_err_set_errno (EINVAL);
       return -1;
     }
   *port = (unsigned int)aval;
@@ -66,7 +77,7 @@ read_port_and_nonce (const char *fname, unsigned short *port, char *nonce)
     ;
   if (*p != '\n' || nread != 17)
     {
-      errno = EINVAL;
+      gpg_err_set_errno (EINVAL);
       return -1;
     }
   p++; nread--;
@@ -105,20 +116,20 @@ _w32_sock_connect (int sockfd, struct sockaddr *addr, int addrlen)
   int ret;
 
   (void)addrlen;
-      
+
   unaddr = (struct sockaddr_un *)addr;
   if (read_port_and_nonce (unaddr->sun_path, &port, nonce))
     return -1;
-      
+
   myaddr.sin_family = AF_INET;
-  myaddr.sin_port = htons (port); 
+  myaddr.sin_port = htons (port);
   myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-  
+
   /* Set return values.  */
   unaddr->sun_family = myaddr.sin_family;
   unaddr->sun_port = myaddr.sin_port;
   unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
-  
+
   ret = connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr);
   if (!ret)
     {
@@ -126,7 +137,7 @@ _w32_sock_connect (int sockfd, struct sockaddr *addr, int addrlen)
       ret = send (sockfd, nonce, 16, 0);
       if (ret >= 0 && ret != 16)
         {
-          errno = EIO;
+          gpg_err_set_errno (EIO);
           ret = -1;
         }
     }
similarity index 55%
rename from jnlib/w32-afunix.h
rename to common/w32-afunix.h
index 6b8f3f9..c9abd7b 100644 (file)
@@ -1,20 +1,31 @@
 /* w32-afunix.h - AF_UNIX emulation for Windows
  *     Copyright (C) 2004, 2006 g10 Code GmbH
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef _WIN32
@@ -26,6 +37,9 @@
 #include <ws2tcpip.h>
 #include <unistd.h>
 
+/* We can easiliy replace this code by the socket wrappers from libassuan.  */
+#warning Please do not use this module anymore
+
 #define DIRSEP_C '\\'
 
 #define AF_LOCAL AF_UNIX
similarity index 61%
rename from jnlib/w32-reg.c
rename to common/w32-reg.c
index e55f806..2507177 100644 (file)
@@ -1,20 +1,31 @@
 /* w32-reg.c -  MS-Windows Registry access
  * Copyright (C) 1999, 2002, 2007 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <windows.h>
 
 #include "libjnlib-config.h"
+#include "utf8conv.h"
 #include "w32help.h"
 
+
 static HKEY
 get_root_key(const char *root)
 {
@@ -65,6 +78,70 @@ get_root_key(const char *root)
 char *
 read_w32_registry_string (const char *root, const char *dir, const char *name)
 {
+#ifdef HAVE_W32CE_SYSTEM
+  HKEY root_key, key_handle;
+  DWORD n1, nbytes, type;
+  char *result = NULL;
+  wchar_t *wdir, *wname;
+
+  if ( !(root_key = get_root_key(root) ) )
+    return NULL;
+
+  wdir = utf8_to_wchar (dir);
+  if (!wdir)
+    return NULL;
+
+  if (RegOpenKeyEx (root_key, wdir, 0, KEY_READ, &key_handle) )
+    {
+      if (root)
+        {
+          jnlib_free (wdir);
+          return NULL; /* No need for a RegClose, so return immediately. */
+        }
+      /* It seems to be common practise to fall back to HKLM. */
+      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, wdir, 0, KEY_READ, &key_handle) )
+        {
+          jnlib_free (wdir);
+          return NULL; /* Still no need for a RegClose. */
+        }
+    }
+  jnlib_free (wdir);
+
+  if (name)
+    {
+      wname = utf8_to_wchar (name);
+      if (!wname)
+        goto leave;
+    }
+  else
+    wname = NULL;
+
+  nbytes = 2;
+  if (RegQueryValueEx (key_handle, wname, 0, NULL, NULL, &nbytes))
+    goto leave;
+  result = jnlib_malloc ((n1=nbytes+2));
+  if (!result)
+    goto leave;
+  if (RegQueryValueEx (key_handle, wname, 0, &type, result, &n1))
+    {
+      jnlib_free (result);
+      result = NULL;
+      goto leave;
+    }
+  result[nbytes] = 0;   /* Make sure it is a string.  */
+  result[nbytes+1] = 0;
+  if (type == REG_SZ || type == REG_EXPAND_SZ)
+    {
+      wchar_t *tmp = (void*)result;
+      result = wchar_to_utf8 (tmp);
+      jnlib_free (tmp);
+    }
+
+ leave:
+  jnlib_free (wname);
+  RegCloseKey (key_handle);
+  return result;
+#else /*!HAVE_W32CE_SYSTEM*/
   HKEY root_key, key_handle;
   DWORD n1, nbytes, type;
   char *result = NULL;
@@ -72,7 +149,7 @@ read_w32_registry_string (const char *root, const char *dir, const char *name)
   if ( !(root_key = get_root_key(root) ) )
     return NULL;
 
-  if ( RegOpenKeyEx( root_key, dir, 0, KEY_READ, &key_handle ) )
+  if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle) )
     {
       if (root)
         return NULL; /* No need for a RegClose, so return immediately. */
@@ -145,6 +222,7 @@ read_w32_registry_string (const char *root, const char *dir, const char *name)
  leave:
   RegCloseKey (key_handle);
   return result;
+#endif /*!HAVE_W32CE_SYSTEM*/
 }
 
 
diff --git a/common/w32help.h b/common/w32help.h
new file mode 100644 (file)
index 0000000..b9b7c44
--- /dev/null
@@ -0,0 +1,56 @@
+/* w32help.h - W32 speicif functions
+ * Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBJNLIB_W32HELP_H
+#define LIBJNLIB_W32HELP_H
+#ifdef HAVE_W32_SYSTEM
+
+/*-- w32-reg.c --*/
+char *read_w32_registry_string (const char *root,
+                               const char *dir, const char *name );
+
+/* Other stuff.  */
+#ifdef HAVE_W32CE_SYSTEM
+/* Setmode is missing in cegcc but available since CE 5.0.  */
+int _setmode (int handle, int mode);
+# define setmode(a,b)   _setmode ((a),(b))
+
+static inline int
+umask (int a)
+{
+  (void)a;
+  return 0;
+}
+
+
+#endif /*HAVE_W32CE_SYSTEM*/
+
+#endif /*HAVE_W32_SYSTEM*/
+#endif /*LIBJNLIB_MISCHELP_H*/
index 9774d06..8adf2e4 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
 #include <errno.h>
 
 #include "util.h"
-#include "iobuf.h"
-#include "estream-printf.h"
-
-#if !defined(_ESTREAM_PRINTF_MALLOC) || !defined(_ESTREAM_PRINTF_FREE)
-#error Need to define ESTREAM_PRINTF_MALLOC and _FREE
-#endif
 
 /* Same as asprintf but return an allocated buffer suitable to be
    freed using xfree.  This function simply dies on memory failure,
-   thus no extra check is required. */
+   thus no extra check is required.
+
+   FIXME: We should remove these functions in favor of gpgrt_bsprintf
+   and a xgpgrt_bsprintf or rename them to xbsprintf and
+   xtrybsprintf.  */
 char *
 xasprintf (const char *fmt, ...)
 {
@@ -39,7 +47,7 @@ xasprintf (const char *fmt, ...)
   char *buf;
 
   va_start (ap, fmt);
-  if (estream_vasprintf (&buf, fmt, ap) < 0)
+  if (gpgrt_vasprintf (&buf, fmt, ap) < 0)
     log_fatal ("estream_asprintf failed: %s\n", strerror (errno));
   va_end (ap);
   return buf;
@@ -54,7 +62,7 @@ xtryasprintf (const char *fmt, ...)
   char *buf;
 
   va_start (ap, fmt);
-  rc = estream_vasprintf (&buf, fmt, ap);
+  rc = gpgrt_vasprintf (&buf, fmt, ap);
   va_end (ap);
   if (rc < 0)
     return NULL;
similarity index 69%
rename from jnlib/xmalloc.c
rename to common/xmalloc.c
index 244f764..3378e48 100644 (file)
@@ -1,20 +1,31 @@
 /* xmalloc.c - standard malloc wrappers
  *     Copyright (C) 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
  *
- * This file is part of JNLIB.
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
  * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
  *
  * JNLIB 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
- * Lesser General Public License for more details.
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -99,4 +110,3 @@ xstrcat2( const char *a, const char *b )
     strcpy(p+n1, b );
     return p;
 }
-
diff --git a/common/xmalloc.h b/common/xmalloc.h
new file mode 100644 (file)
index 0000000..73d6f45
--- /dev/null
@@ -0,0 +1,41 @@
+/* xmalloc.h
+ *     Copyright (C) 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB, which is a subsystem of GnuPG.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * JNLIB 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 copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBJNLIB_XMALLOC_H
+#define LIBJNLIB_XMALLOC_H
+
+void *xmalloc( size_t n );
+void *xrealloc( void *a, size_t n );
+void *xcalloc( size_t n, size_t m );
+char *xstrdup( const char *string );
+char *xstrcat2( const char *a, const char *b );
+
+
+#endif /*LIBJNLIB_XMALLOC_H*/
index 8ca72b7..f3c43df 100644 (file)
@@ -3,12 +3,22 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -30,7 +40,7 @@
    considered a byte stream ending in a LF.
 
    If MAX_LENGTH is not NULL, it shall point to a value with the
-   maximum allowed allocation.  
+   maximum allowed allocation.
 
    Returns the length of the line. EOF is indicated by a line of
    length zero. A truncated line is indicated by setting the value at
@@ -45,7 +55,7 @@
    append a CR,LF,Nul
  */
 ssize_t
-read_line (FILE *fp, 
+read_line (FILE *fp,
            char **addr_of_buffer, size_t *length_of_buffer,
            size_t *max_length)
 {
@@ -94,16 +104,16 @@ read_line (FILE *fp,
           if (!*addr_of_buffer)
             {
               int save_errno = errno;
-              xfree (buffer); 
+              xfree (buffer);
               *length_of_buffer = 0;
               if (max_length)
                 *max_length = 0;
-              errno = save_errno;
+              gpg_err_set_errno (save_errno);
               return -1;
             }
           buffer = *addr_of_buffer;
           *length_of_buffer = length;
-          length -= 3; 
+          length -= 3;
           p = buffer + nbytes;
        }
       *p++ = c;
index a7131b7..821df4b 100644 (file)
@@ -104,7 +104,7 @@ answer_is_yes_no_quit ( const char *s )
 }
 
 /*
-   Return 1 for okay, 0 for for cancel or DEF_ANSWER for default. 
+   Return 1 for okay, 0 for for cancel or DEF_ANSWER for default.
  */
 int
 answer_is_okay_cancel (const char *s, int def_answer)
@@ -115,7 +115,7 @@ answer_is_okay_cancel (const char *s, int def_answer)
   const char *long_cancel = _("cancel|cancel");
   const char *short_okay = _("oO");
   const char *short_cancel = _("cC");
-  
+
   /* Note: We have to use the locale dependent compare. */
   if ( match_multistr(long_okay,s) )
     return 1;
@@ -138,4 +138,3 @@ answer_is_okay_cancel (const char *s, int def_answer)
     return 0;
   return def_answer;
 }
-
index 0041bec..8cc06e1 100644 (file)
@@ -1,7 +1,6 @@
-# configure.ac - for GnuPG 2.0
-# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-#               2006, 2007, 2008, 2010, 2011,
-#               2012 Free Software Foundation, Inc.
+# configure.ac - for GnuPG 2.1
+# Copyright (C) 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1998-2014 Werner Koch
 #
 # This file is part of GnuPG.
 #
 
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.61)
-min_automake_version="1.14"
+min_automake_version="1.10"
 
 # To build a release you need to create a tag with the version number
 # (git tag -s gnupg-2.n.m) and run "./autogen.sh --force".  Please
 # bump the version number immediately *after* the release and do
 # another commit and push so that the git magic is able to work.
-m4_define([mym4_version], [2.0.31])
+m4_define([mym4_package],[gnupg])
+m4_define([mym4_major], [2])
+m4_define([mym4_minor], [1])
+m4_define([mym4_micro], [0])
+
+# To start a new development series, i.e a new major or minor number
+# you need to mark an arbitrary commit before the first beta release
+# with an annotated tag.  For example the 2.1 branch starts off with
+# the tag "gnupg-2.1-base".  This is used as the base for counting
+# beta numbers before the first release of a series.
 
 # Below is m4 magic to extract and compute the git revision number,
 # the decimalized short revision number, a beta version string and a
-# flag indicating a development version (mym4_isgit).  Note that the
+# flag indicating a development version (mym4_isbeta).  Note that the
 # m4 processing is done by autoconf and not during the configure run.
-m4_define([mym4_revision],
-          m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r']))
-m4_define([mym4_revision_dec],
-          m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))]))
-m4_define([mym4_betastring],
-          m4_esyscmd_s([git describe --match 'gnupg-2.[0-9].*[0-9]' --long|\
-                        awk -F- '$3!=0{print"-beta"$3}']))
-m4_define([mym4_isgit],m4_if(mym4_betastring,[],[no],[yes]))
-m4_define([mym4_full_version],[mym4_version[]mym4_betastring])
-
-AC_INIT([gnupg],[mym4_full_version], [http://bugs.gnupg.org])
+m4_define([mym4_verslist], m4_split(m4_esyscmd([./autogen.sh --find-version] \
+                           mym4_package mym4_major mym4_minor mym4_micro),[:]))
+m4_define([mym4_isbeta],       m4_argn(2, mym4_verslist))
+m4_define([mym4_version],      m4_argn(4, mym4_verslist))
+m4_define([mym4_revision],     m4_argn(7, mym4_verslist))
+m4_define([mym4_revision_dec], m4_argn(8, mym4_verslist))
+m4_esyscmd([echo ]mym4_version[>VERSION])
+AC_INIT([mym4_package],[mym4_version], [http://bugs.gnupg.org])
 
-NEED_GPG_ERROR_VERSION=1.11
+NEED_GPG_ERROR_VERSION=1.15
 
 NEED_LIBGCRYPT_API=1
-NEED_LIBGCRYPT_VERSION=1.5.0
+NEED_LIBGCRYPT_VERSION=1.6.0
 
 NEED_LIBASSUAN_API=2
-NEED_LIBASSUAN_VERSION=2.0.0
+NEED_LIBASSUAN_VERSION=2.1.0
 
 NEED_KSBA_API=1
-NEED_KSBA_VERSION=1.0.7
+NEED_KSBA_VERSION=1.2.0
+
+NEED_NTBTLS_API=1
+NEED_NTBTLS_VERSION=0.1.0
+
+NEED_NPTH_API=1
+NEED_NPTH_VERSION=0.91
+
+
+NEED_GNUTLS_VERSION=3.0
 
-development_version=mym4_isgit
+
+development_version=mym4_isbeta
 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)
-AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_SRCDIR([sm/gpgsm.c])
+AC_CONFIG_HEADER([config.h])
+# Note: For automake 1.13 add the option
+#          serial-tests
+AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
 AC_CANONICAL_HOST
 AB_INIT
 
@@ -74,26 +91,33 @@ have_gpg_error=no
 have_libgcrypt=no
 have_libassuan=no
 have_ksba=no
-have_pth=no
+have_ntbtls=no
+have_gnutls=no
+have_npth=no
 have_libusb=no
 have_adns=no
+gnupg_have_ldap="n/a"
 
+use_zip=yes
 use_bzip2=yes
 use_exec=yes
-disable_keyserver_path=no
+use_trust_models=yes
+card_support=yes
 use_ccid_driver=yes
-use_standard_socket=no
+dirmngr_auto_start=yes
+use_tls_library=no
 large_secmem=no
 
 GNUPG_BUILD_PROGRAM(gpg, yes)
 GNUPG_BUILD_PROGRAM(gpgsm, yes)
 GNUPG_BUILD_PROGRAM(agent, yes)
 GNUPG_BUILD_PROGRAM(scdaemon, yes)
+GNUPG_BUILD_PROGRAM(g13, yes)
+GNUPG_BUILD_PROGRAM(dirmngr, yes)
 GNUPG_BUILD_PROGRAM(tools, yes)
 GNUPG_BUILD_PROGRAM(doc, yes)
 GNUPG_BUILD_PROGRAM(symcryptrun, no)
-GNUPG_BUILD_PROGRAM(gpgtar, no)
-
+GNUPG_BUILD_PROGRAM(gpgtar, yes)
 
 AC_SUBST(PACKAGE)
 AC_SUBST(PACKAGE_GT)
@@ -108,6 +132,9 @@ 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])
+AC_DEFINE_UNQUOTED(NEED_NTBTLS_VERSION, "$NEED_NTBTLS_VERSION",
+                                       [Required version of NTBTLS])
+
 
 
 # The default is to use the modules from this package and the few
@@ -158,13 +185,33 @@ show_gnupg_protect_tool_pgm="(default)"
 test -n "$GNUPG_PROTECT_TOOL_PGM" \
       && show_gnupg_protect_tool_pgm="$GNUPG_PROTECT_TOOL_PGM"
 
+AC_ARG_WITH(dirmngr-ldap-pgm,
+    [  --with-dirmngr-ldap-pgm=PATH  Use PATH as the default for the dirmnge ldap wrapper)],
+          GNUPG_DIRMNGR_LDAP_PGM="$withval", GNUPG_DIRMNGR_LDAP_PGM="" )
+AC_SUBST(GNUPG_DIRMNGR_LDAP_PGM)
+AM_CONDITIONAL(GNUPG_DIRMNGR_LDAP_PGM, test -n "$GNUPG_DIRMNGR_LDAP_PGM")
+show_gnupg_dirmngr_ldap_pgm="(default)"
+test -n "$GNUPG_DIRMNGR_LDAP_PGM" \
+      && show_gnupg_dirmngr_ldap_pgm="$GNUPG_DIRMNGR_LDAP_PGM"
+
+#
+# On some platforms gpg2 is usually installed as gpg without using a
+# symlink.  For correct operation of gpgconf it needs to know the
+# installed name of gpg.  This option sets "gpg2"'s installed name to
+# just "gpg".  Note that it might be required to rename gpg2 to gpg
+# manually after the build process.
+#
+AC_ARG_ENABLE(gpg2-is-gpg,
+    AC_HELP_STRING([--enable-gpg2-is-gpg],[Set installed name of gpg2 to gpg]),
+    gpg2_is_gpg=$enableval)
+if test "$gpg2_is_gpg" = "yes"; then
+   name_of_installed_gpg=gpg
+else
+   name_of_installed_gpg=gpg2
+fi
+AC_DEFINE_UNQUOTED(NAME_OF_INSTALLED_GPG, "$name_of_installed_gpg",
+                   [The name of the installed GPG tool])
 
-# Some folks want to use only the agent from 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)
 
 # SELinux support includes tracking of sensitive files to avoid
 # leaking their contents through processing these files by gpg itself
@@ -190,6 +237,59 @@ fi
 AC_DEFINE_UNQUOTED(SECMEM_BUFFER_SIZE,$SECMEM_BUFFER_SIZE,
                    [Size of secure memory buffer])
 
+AC_MSG_CHECKING([whether to enable trust models])
+AC_ARG_ENABLE(trust-models,
+              AC_HELP_STRING([--disable-trust-models],
+                             [disable all trust models except "always"]),
+              use_trust_models=$enableval)
+AC_MSG_RESULT($use_trust_models)
+if test "$use_trust_models" = no ; then
+    AC_DEFINE(NO_TRUST_MODELS, 1,
+             [Define to include only trust-model always])
+fi
+
+
+#
+# Options to disable algorithm
+#
+
+GNUPG_GPG_DISABLE_ALGO([rsa],[RSA public key])
+# Elgamal is a MUST algorithm
+# DSA is a MUST algorithm
+GNUPG_GPG_DISABLE_ALGO([ecdh],[ECDH public key])
+GNUPG_GPG_DISABLE_ALGO([ecdsa],[ECDSA public key])
+GNUPG_GPG_DISABLE_ALGO([eddsa],[EdDSA public key])
+
+GNUPG_GPG_DISABLE_ALGO([idea],[IDEA cipher])
+# 3DES is a MUST algorithm
+GNUPG_GPG_DISABLE_ALGO([cast5],[CAST5 cipher])
+GNUPG_GPG_DISABLE_ALGO([blowfish],[BLOWFISH cipher])
+GNUPG_GPG_DISABLE_ALGO([aes128],[AES128 cipher])
+GNUPG_GPG_DISABLE_ALGO([aes192],[AES192 cipher])
+GNUPG_GPG_DISABLE_ALGO([aes256],[AES256 cipher])
+GNUPG_GPG_DISABLE_ALGO([twofish],[TWOFISH cipher])
+GNUPG_GPG_DISABLE_ALGO([camellia128],[CAMELLIA128 cipher])
+GNUPG_GPG_DISABLE_ALGO([camellia192],[CAMELLIA192 cipher])
+GNUPG_GPG_DISABLE_ALGO([camellia256],[CAMELLIA256 cipher])
+
+GNUPG_GPG_DISABLE_ALGO([md5],[MD5 hash])
+# SHA1 is a MUST algorithm
+GNUPG_GPG_DISABLE_ALGO([rmd160],[RIPE-MD160 hash])
+GNUPG_GPG_DISABLE_ALGO([sha224],[SHA-224 hash])
+# SHA256 is a MUST algorithm for GnuPG.
+GNUPG_GPG_DISABLE_ALGO([sha384],[SHA-384 hash])
+GNUPG_GPG_DISABLE_ALGO([sha512],[SHA-512 hash])
+
+
+# Allow disabling of zip support.
+# This is in general not a good idea because according to rfc4880 OpenPGP
+# implementations SHOULD support ZLIB.
+AC_MSG_CHECKING([whether to enable the ZIP and ZLIB compression algorithm])
+AC_ARG_ENABLE(zip,
+   AC_HELP_STRING([--disable-zip],
+                  [disable the ZIP and ZLIB compression algorithm]),
+   use_zip=$enableval)
+AC_MSG_RESULT($use_zip)
 
 # Allow disabling of bzib2 support.
 # It is defined only after we confirm the library is available later
@@ -232,61 +332,6 @@ if test "$use_exec" = yes ; then
         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
-    # LDAP is defined only after we confirm the library is available later
-    AC_MSG_CHECKING([whether LDAP keyserver support is requested])
-    AC_ARG_ENABLE(ldap,
-      AC_HELP_STRING([--disable-ldap],[disable LDAP keyserver interface only]),
-      try_ldap=$enableval, try_ldap=yes)
-    AC_MSG_RESULT($try_ldap)
-
-    AC_MSG_CHECKING([whether HKP keyserver support is requested])
-    AC_ARG_ENABLE(hkp,
-      AC_HELP_STRING([--disable-hkp],[disable HKP keyserver interface only]),
-      try_hkp=$enableval, try_hkp=yes)
-    AC_MSG_RESULT($try_hkp)
-
-    AC_MSG_CHECKING([whether finger key fetching support is requested])
-    AC_ARG_ENABLE(finger,
-      AC_HELP_STRING([--disable-finger],
-        [disable finger key fetching interface only]),
-      try_finger=$enableval, try_finger=yes)
-    AC_MSG_RESULT($try_finger)
-
-    AC_MSG_CHECKING([whether generic object key fetching support is requested])
-    AC_ARG_ENABLE(generic,
-      AC_HELP_STRING([--disable-generic],
-        [disable generic object key fetching interface only]),
-      try_generic=$enableval, try_generic=yes)
-    AC_MSG_RESULT($try_generic)
-
-    AC_MSG_CHECKING([whether email keyserver support is requested])
-    AC_ARG_ENABLE(mailto,
-      AC_HELP_STRING([--enable-mailto],
-       [enable email keyserver interface only]),
-      try_mailto=$enableval, try_mailto=no)
-    AC_MSG_RESULT($try_mailto)
-  fi
-
-  AC_MSG_CHECKING([whether keyserver exec-path is enabled])
-  AC_ARG_ENABLE(keyserver-path,
-      AC_HELP_STRING([--disable-keyserver-path],
-           [disable the exec-path option for keyserver helpers]),
-           [if test "$enableval" = no ; then
-              disable_keyserver_path=yes
-           fi],enableval=yes)
-  AC_MSG_RESULT($enableval)
 fi
 
 
@@ -324,6 +369,19 @@ AC_ARG_WITH(capabilities,
 [use_capabilities="$withval"],[use_capabilities=no])
 AC_MSG_RESULT($use_capabilities)
 
+#
+# Check whether to disable the card support
+AC_MSG_CHECKING([whether smartcard support is requested])
+AC_ARG_ENABLE(card-support,
+              AC_HELP_STRING([--disable-card-support],
+                             [disable smartcard support]),
+              card_support=$enableval)
+AC_MSG_RESULT($card_support)
+if test "$card_support" = yes ; then
+  AC_DEFINE(ENABLE_CARD_SUPPORT,1,[Define to include smartcard support])
+else
+  build_scdaemon=no
+fi
 
 #
 # Allow disabling of internal CCID support.
@@ -336,6 +394,17 @@ AC_ARG_ENABLE(ccid-driver,
               use_ccid_driver=$enableval)
 AC_MSG_RESULT($use_ccid_driver)
 
+AC_MSG_CHECKING([whether to auto start dirmngr])
+AC_ARG_ENABLE(dirmngr-auto-start,
+              AC_HELP_STRING([--disable-dirmngr-auto-start],
+                             [disable auto starting of the dirmngr]),
+              dirmngr_auto_start=$enableval)
+AC_MSG_RESULT($dirmngr_auto_start)
+if test "$dirmngr_auto_start" = yes ; then
+    AC_DEFINE(USE_DIRMNGR_AUTO_START,1,
+              [Define to enable auto starting of the dirmngr])
+fi
+
 
 #
 # To avoid double inclusion of config.h which might happen at some
@@ -386,27 +455,39 @@ AH_BOTTOM([
 #define SAFE_VERSION_DASH '-'
 
 /* Some global constants. */
-#ifdef HAVE_DRIVE_LETTERS
-#define GNUPG_DEFAULT_HOMEDIR "c:/gnupg"
+#ifdef HAVE_DOSISH_SYSTEM
+# ifdef HAVE_DRIVE_LETTERS
+#  define GNUPG_DEFAULT_HOMEDIR "c:/gnupg"
+# else
+#  define GNUPG_DEFAULT_HOMEDIR "/gnupg"
+# endif
 #elif defined(__VMS)
-#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg"
+#define GNUPG_DEFAULT_HOMEDIR "/SYS$LOGIN/gnupg"
 #else
 #define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
 #endif
-#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d"
+#define GNUPG_PRIVATE_KEYS_DIR  "private-keys-v1.d"
+#define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d"
 
 /* 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
- /* FIXME: We need to use a function to determine these values depending
-    on the actual installation directory. */
-#define GNUPG_BINDIR      "c:\\gnupg"
-#define GNUPG_LIBEXECDIR  "c:\\gnupg"
-#define GNUPG_LIBDIR      "c:\\gnupg"
-#define GNUPG_DATADIR     "c:\\gnupg"
-#define GNUPG_SYSCONFDIR  "c:\\gnupg"
+   comply with the GNU coding standards.  Note that these values are
+   only defaults.  */
+#ifdef HAVE_DOSISH_SYSTEM
+# ifdef HAVE_DRIVE_LETTERS
+#  define GNUPG_BINDIR      "c:\\gnupg"
+#  define GNUPG_LIBEXECDIR  "c:\\gnupg"
+#  define GNUPG_LIBDIR      "c:\\gnupg"
+#  define GNUPG_DATADIR     "c:\\gnupg"
+#  define GNUPG_SYSCONFDIR  "c:\\gnupg"
+# else
+#  define GNUPG_BINDIR      "\\gnupg"
+#  define GNUPG_LIBEXECDIR  "\\gnupg"
+#  define GNUPG_LIBDIR      "\\gnupg"
+#  define GNUPG_DATADIR     "\\gnupg"
+#  define GNUPG_SYSCONFDIR  "\\gnupg"
+# endif
 #endif
 
 /* Derive some other constants. */
@@ -438,10 +519,15 @@ AH_BOTTOM([
 # endif
 #endif
 
+/* Provide the es_ macro for estream.  */
+#define GPGRT_ENABLE_ES_MACROS 1
 
 /* Tell libgcrypt not to use its own libgpg-error implementation. */
 #define USE_LIBGPG_ERROR 1
 
+/* Tell Libgcrypt not to include deprecated definitions.  */
+#define GCRYPT_NO_DEPRECATED 1
+
 /* We use jnlib, so tell other modules about it.  */
 #define HAVE_JNLIB_LOGGING 1
 
@@ -453,24 +539,11 @@ AH_BOTTOM([
    handler.  */
 #define HTTP_NO_WSASTARTUP
 
-/* We always include support for the OpenPGP card.  */
-#define ENABLE_CARD_SUPPORT 1
-
-/* We don't want the old assuan codes anymore. */
-#define _ASSUAN_ONLY_GPG_ERRORS 1
+/* Under Windows we use the gettext code from libgpg-error.  */
+#define GPG_ERR_ENABLE_GETTEXT_MACROS
 
-/* We don't need any of the old gcrypt functions.  */
-#define GCRYPT_NO_DEPRECATED 1
-
-/* We explicitly need to disable PTH's soft mapping as Debian
-   currently enables it by default for no reason. */
-#define PTH_SYSCALL_SOFT 0
-
-/* We want to use the libgcrypt provided memory allocation for
-   asprintf.  */
-#define _ESTREAM_PRINTF_MALLOC        gcry_malloc
-#define _ESTREAM_PRINTF_FREE          gcry_free
-#define _ESTREAM_PRINTF_EXTRA_INCLUDE "util.h"
+/* Under WindowsCE we use the strerror replacement from libgpg-error.  */
+#define GPG_ERR_ENABLE_ERRNO_MACROS
 
 #endif /*GNUPG_CONFIG_H_INCLUDED*/
 ])
@@ -489,6 +562,7 @@ 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)
+AM_SILENT_RULES
 AC_PROG_AWK
 AC_PROG_CC
 AC_PROG_CPP
@@ -505,12 +579,11 @@ AC_CHECK_TOOL(WINDRES, windres, :)
 AC_ISC_POSIX
 gl_EARLY
 AC_SYS_LARGEFILE
-GNUPG_CHECK_FAQPROG
 GNUPG_CHECK_USTAR
 
 # We need to compile and run a program on the build machine.  A
 # comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in
-# the AC archive is broken for autoconf 2.57.  Given that tehre is no
+# the AC archive is broken for autoconf 2.57.  Given that there is no
 # newer version of that macro, we assume that it is also broken for
 # autoconf 2.61 and thus we use a simple but usually sufficient
 # approach.
@@ -526,26 +599,41 @@ AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler])
 
 
 try_gettext=yes
+require_iconv=yes
 have_dosish_system=no
 have_w32_system=no
+have_w32ce_system=no
+have_android_system=no
+run_tests=yes
 use_simple_gettext=no
+use_ldapwrapper=yes
+mmap_needed=yes
 case "${host}" 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])
+                  [Set this to limit filenames to the 8.3 format])
         AC_DEFINE(USE_SIMPLE_GETTEXT,1,
-                  [because the Unix gettext has too much overhead on
+                  [Because the Unix gettext has too much overhead on
                    MingW32 systems and these systems lack Posix functions,
                    we use a simplified version of gettext])
-        disable_keyserver_path=yes
         have_dosish_system=yes
         have_w32_system=yes
+        run_tests=no
+        use_ldapwrapper=no  # Fixme: Do this only for CE.
+        case "${host}" in
+          *-mingw32ce*)
+            have_w32ce_system=yes
+            ;;
+          *)
+            AC_DEFINE(HAVE_DRIVE_LETTERS,1,
+                      [Defined if the OS supports drive letters.])
+            ;;
+        esac
         try_gettext="no"
        use_simple_gettext=yes
+       mmap_needed=no
         ;;
     i?86-emx-os2 | i?86-*-os2*emx )
         # OS/2 with the EMX environment
@@ -563,12 +651,6 @@ case "${host}" in
         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"
@@ -592,6 +674,13 @@ case "${host}" in
         ;;
     m68k-atari-mint)
         ;;
+    *-linux-androideabi)
+        have_android_system=yes
+        # Android is fully utf-8 and we do not want to use iconv to
+        # keeps things simple
+        require_iconv=no
+        run_tests=no
+        ;;
     *)
        ;;
 esac
@@ -600,7 +689,8 @@ 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])
+              no file modes, case insensitive file names and preferred
+              use of backslashes as directory name separators.])
 fi
 AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = yes)
 
@@ -608,50 +698,27 @@ AM_CONDITIONAL(USE_SIMPLE_GETTEXT, test x"$use_simple_gettext" = xyes)
 
 if test "$have_w32_system" = yes; then
    AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system])
+   if test "$have_w32ce_system" = yes; then
+      AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE])
+   fi
 fi
 AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
+AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes)
 
-if test "$disable_keyserver_path" = yes; then
-    AC_DEFINE(DISABLE_KEYSERVER_PATH,1,
-              [Defined to disable exec-path for keyserver helpers])
+if test "$have_android_system" = yes; then
+   AC_DEFINE(HAVE_ANDROID_SYSTEM,1, [Defined if we build for an Android system])
 fi
+AM_CONDITIONAL(HAVE_ANDROID_SYSTEM, test "$have_android_system" = yes)
 
-#
-# Allows enabling the use of a standard socket by default This is
-# gpg-agent's option --[no-]use-standard-socket.  For Windows we force
-# the use of this.
-#
-AC_MSG_CHECKING([whether to use a standard socket by default])
-AC_ARG_ENABLE(standard-socket,
-              AC_HELP_STRING([--enable-standard-socket],
-                             [use a standard socket for the agent by default]),
-              use_standard_socket=$enableval)
-tmp=""
-if test "$use_standard_socket" != yes; then
-  if test "$have_w32_system" = yes; then
-    use_standard_socket=yes
-    tmp=" (forced)"
-  fi
-fi
-AC_MSG_RESULT($use_standard_socket$tmp)
-if test "$use_standard_socket" = yes; then
-  AC_DEFINE(USE_STANDARD_SOCKET,1,
-            [Use a standard socket for the agent by default])
+if test "$run_tests" = yes; then
+   AC_DEFINE(RUN_TESTS,1, [Defined if we should run the tests])
 fi
+AM_CONDITIONAL(RUN_TESTS, test "$run_tests" = yes)
 
 
 # (These need to go after AC_PROG_CC so that $EXEEXT is defined)
 AC_DEFINE_UNQUOTED(EXEEXT,"$EXEEXT",[The executable file extension, if any])
 
-if test x"$try_hkp" = xyes ; then
-  AC_SUBST(GPGKEYS_HKP,"gpg2keys_hkp$EXEEXT")
-fi
-
-if test x"$try_finger" = xyes ; then
-  AC_SUBST(GPGKEYS_FINGER,"gpg2keys_finger$EXEEXT")
-fi
-
-
 
 #
 # Checks for libraries.
@@ -681,7 +748,7 @@ AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION",
                   have_libassuan=yes,have_libassuan=no)
 if test "$have_libassuan" = "yes"; then
   AC_DEFINE_UNQUOTED(GNUPG_LIBASSUAN_VERSION, "$libassuan_version",
-            [version of the libbassuan library])
+                     [version of the libassuan library])
 fi
 
 
@@ -709,6 +776,7 @@ AC_SUBST(LIBUSB_LIBS)
 
 #
 # Check wether it is necessary to link against libdl.
+# (For example to load libpcsclite)
 #
 gnupg_dlopen_save_libs="$LIBS"
 LIBS=""
@@ -717,6 +785,20 @@ DL_LIBS=$LIBS
 AC_SUBST(DL_LIBS)
 LIBS="$gnupg_dlopen_save_libs"
 
+# Checks for g13
+
+AC_PATH_PROG(ENCFS, encfs, /usr/bin/encfs)
+AC_DEFINE_UNQUOTED(ENCFS,
+       "${ENCFS}", [defines the filename of the encfs program])
+
+AC_PATH_PROG(FUSERMOUNT, fusermount, /usr/bin/fusermount)
+AC_DEFINE_UNQUOTED(FUSERMOUNT,
+       "${FUSERMOUNT}", [defines the filename of the fusermount program])
+
+
+# Checks for dirmngr
+
+
 #
 # Checks for symcryptrun:
 #
@@ -735,27 +817,65 @@ AC_DEFINE_UNQUOTED(SHRED,
        "${SHRED}", [defines the filename of the shred program])
 
 
-
 #
-# Check whether the GNU Pth library is available
-# Note, that we include a Pth emulation for W32.
+# Check whether the nPth library is available
 #
-GNUPG_PATH_PTH
-if test "$have_pth" = "yes"; then
-  AC_DEFINE(USE_GNU_PTH, 1,
-              [Defined if the GNU Portable Thread Library should be used])
+AM_PATH_NPTH("$NEED_NPTH_API:$NEED_NPTH_VERSION",have_npth=yes,have_npth=no)
+if test "$have_npth" = "yes"; then
+  AC_DEFINE(HAVE_NPTH, 1,
+              [Defined if the New Portable Thread Library is available])
+  AC_DEFINE(USE_NPTH, 1,
+              [Defined if support for nPth is requested and nPth is available])
 else
   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
+*** To support concurrent access for example in gpg-agent and the SCdaemon
+*** we need the support of the New Portable Threads Library.
 ***]])
 fi
 
 
+#
+# NTBTLS is our TLS library.  If it is not available fallback to
+# GNUTLS.
+#
+AC_ARG_ENABLE(ntbtls,
+              AC_HELP_STRING([--disable-ntbtls],
+                             [disable the use of NTBTLS as TLS library]),
+              try_ntbtls=$enableval, try_ntbtls=yes)
+if test x"$try_ntbtls" = xyes ; then
+  AM_PATH_NTBTLS("$NEED_NTBTLS_API:$NEED_NTBTLS_VERSION",
+                 [have_ntbtls=yes],[have_ntbtls=no])
+fi
+if test "$have_ntbtls" = yes ; then
+   use_tls_library=ntbtls
+   AC_DEFINE(HTTP_USE_NTBTLS, 1, [Enable NTBTLS support in http.c])
+else
+  AC_ARG_ENABLE(gnutls,
+                AC_HELP_STRING([--disable-gnutls],
+                               [disable GNUTLS as fallback TLS library]),
+                try_gnutls=$enableval, try_gnutls=yes)
+  if test x"$try_gnutls" = xyes ; then
+    PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= $NEED_GNUTLS_VERSION],
+                                   [have_gnutls=yes],
+                                   [have_gnutls=no])
+  fi
+  if test "$have_gnutls" = "yes"; then
+    AC_SUBST([LIBGNUTLS_CFLAGS])
+    AC_SUBST([LIBGNUTLS_LIBS])
+    use_tls_library=gnutls
+    AC_DEFINE(HTTP_USE_GNUTLS, 1, [Enable GNUTLS support in http.c])
+  else
+    tmp=$(echo "$LIBGNUTLS_PKG_ERRORS" | tr '\n' '\v' | sed 's/\v/\n*** /g')
+    AC_MSG_WARN([[
+***
+*** Building without NTBTLS and GNUTLS - no TLS access to keyservers.
+***
+*** $tmp]])
+  fi
+fi
+
+
 AC_MSG_NOTICE([checking for networking options])
 
 #
@@ -797,15 +917,14 @@ AC_SUBST(ADNSLIBS)
 AC_CHECK_FUNCS(adns_free)
 
 
+
 #
 # Now try for the resolver functions so we can use DNS for SRV, PA and CERT.
 #
-if test x"$try_hkp" = xyes || test x"$try_http" = xyes ; then
-  AC_ARG_ENABLE(dns-srv,
-     AC_HELP_STRING([--disable-dns-srv],
-                    [disable the use of DNS SRV in HKP and HTTP]),
-                use_dns_srv=$enableval,use_dns_srv=yes)
-fi
+AC_ARG_ENABLE(dns-srv,
+              AC_HELP_STRING([--disable-dns-srv],
+                             [disable the use of DNS SRV in HKP and HTTP]),
+              use_dns_srv=$enableval,use_dns_srv=yes)
 
 AC_ARG_ENABLE(dns-pka,
    AC_HELP_STRING([--disable-dns-pka],
@@ -922,22 +1041,47 @@ AM_CONDITIONAL(USE_DNS_SRV, test x"$use_dns_srv" = xyes)
 #
 # Check for LDAP
 #
-if test "$try_ldap" = yes ; then
-   GNUPG_CHECK_LDAP($NETLIBS)
+# Note that running the check changes the variable
+# gnupg_have_ldap from "n/a" to "no" or "yes".
+
+AC_ARG_ENABLE(ldap,
+    AC_HELP_STRING([--disable-ldap],[disable LDAP support]),
+    [if test "$enableval" = "no"; then gnupg_have_ldap=no; fi])
+
+if test "$gnupg_have_ldap" != "no" ; then
+  if test "$build_dirmngr" = "yes" ; then
+     GNUPG_CHECK_LDAP($NETLIBS)
+     AC_CHECK_LIB(lber, ber_free,
+                  [ LBER_LIBS="$LBER_LIBS -llber"
+                    AC_DEFINE(HAVE_LBER,1,
+                             [defined if liblber is available])
+                    have_lber=yes
+                 ])
+  fi
+fi
+AC_SUBST(LBER_LIBS)
+if test "$gnupg_have_ldap" = "no"; then
+    AC_MSG_WARN([[
+***
+*** Building without LDAP support.
+*** No CRL access or X.509 certificate search available.
+***]])
 fi
 
-#
-# Check for curl.  We fake the curl API if libcurl isn't installed.
-# We require 7.10 or later as we use curl_version_info().
-#
-LIBCURL_CHECK_CONFIG([yes],[7.10],,[fake_curl=yes])
-AM_CONDITIONAL(FAKE_CURL,test x"$fake_curl" = xyes)
-
-# Generic, for us, means curl
+AM_CONDITIONAL(USE_LDAP, [test "$gnupg_have_ldap" = yes])
+if test "$gnupg_have_ldap" = yes ; then
+  AC_DEFINE(USE_LDAP,1,[Defined if LDAP is support])
+else
+ use_ldapwrapper=no
+fi
 
-if test x"$try_generic" = xyes ; then
-   AC_SUBST(GPGKEYS_CURL,"gpg2keys_curl$EXEEXT")
+if test "$use_ldapwrapper" = yes; then
+   AC_DEFINE(USE_LDAPWRAPPER,1, [Build dirmngr with LDAP wrapper process])
 fi
+AM_CONDITIONAL(USE_LDAPWRAPPER, test "$use_ldapwrapper" = yes)
+
+
+
 
 #
 # Check for sendmail
@@ -945,31 +1089,26 @@ fi
 # This isn't necessarily sendmail itself, but anything that gives a
 # sendmail-ish interface to the outside world.  That includes Exim,
 # Postfix, etc.  Basically, anything that can handle "sendmail -t".
-if test "$try_mailto" = yes ; then
-  AC_ARG_WITH(mailprog,
+AC_ARG_WITH(mailprog,
       AC_HELP_STRING([--with-mailprog=NAME],
                      [use "NAME -t" for mail transport]),
              ,with_mailprog=yes)
-
-  if test x"$with_mailprog" = xyes ; then
+if test x"$with_mailprog" = xyes ; then
     AC_PATH_PROG(SENDMAIL,sendmail,,$PATH:/usr/sbin:/usr/libexec:/usr/lib)
-    if test "$ac_cv_path_SENDMAIL" ; then
-      GPGKEYS_MAILTO="gpg2keys_mailto"
-    fi
-  elif test x"$with_mailprog" != xno ; then
+elif test x"$with_mailprog" != xno ; then
     AC_MSG_CHECKING([for a mail transport program])
     AC_SUBST(SENDMAIL,$with_mailprog)
     AC_MSG_RESULT($with_mailprog)
-    GPGKEYS_MAILTO="gpg2keys_mailto"
-  fi
 fi
 
-AC_SUBST(GPGKEYS_MAILTO)
 
 #
 # Construct a printable name of the OS
 #
 case "${host}" in
+    *-mingw32ce*)
+        PRINTABLE_OS_NAME="W32CE"
+        ;;
     *-mingw32*)
         PRINTABLE_OS_NAME="MingW32"
         ;;
@@ -997,10 +1136,13 @@ AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME",
 #
 # Checking for iconv
 #
-missing_iconv=no
-AM_ICONV
-if test "$am_cv_func_iconv" != yes; then
-   missing_iconv=yes
+if test "$require_iconv" = yes; then
+  AM_ICONV
+else
+  LIBICONV=
+  LTLIBICONV=
+  AC_SUBST(LIBICONV)
+  AC_SUBST(LTLIBICONV)
 fi
 
 
@@ -1012,7 +1154,7 @@ fi
 #
 AC_MSG_NOTICE([checking for gettext])
 AM_PO_SUBDIRS
-AM_GNU_GETTEXT_VERSION([0.19.3])
+AM_GNU_GETTEXT_VERSION([0.17])
 if test "$try_gettext" = yes; then
   AM_GNU_GETTEXT([external],[need-ngettext])
 
@@ -1035,7 +1177,7 @@ fi
 # We use HAVE_LANGINFO_CODESET in a couple of places.
 AM_LANGINFO_CODESET
 
-# Checks required for our use locales
+# Checks required for our use of locales
 gt_LC_MESSAGES
 
 
@@ -1052,8 +1194,8 @@ fi
 #
 AC_MSG_NOTICE([checking for header files])
 AC_HEADER_STDC
-AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h])
-AC_CHECK_HEADERS([pty.h utmp.h pwd.h inttypes.h])
+AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \
+                  pty.h utmp.h pwd.h inttypes.h signal.h])
 AC_HEADER_TIME
 
 
@@ -1072,6 +1214,8 @@ AC_DECL_SYS_SIGLIST
 gl_HEADER_SYS_SOCKET
 gl_TYPE_SOCKLEN_T
 
+AC_SEARCH_LIBS([inet_addr], [nsl])
+
 AC_ARG_ENABLE(endian-check,
               AC_HELP_STRING([--disable-endian-check],
              [disable the endian check and trust the OS provided macros]),
@@ -1092,6 +1236,7 @@ AC_CHECK_SIZEOF(unsigned short)
 AC_CHECK_SIZEOF(unsigned int)
 AC_CHECK_SIZEOF(unsigned long)
 AC_CHECK_SIZEOF(unsigned long long)
+AC_HEADER_TIME
 AC_CHECK_SIZEOF(time_t,,[[
 #include <stdio.h>
 #if TIME_WITH_SYS_TIME
@@ -1105,19 +1250,9 @@ AC_CHECK_SIZEOF(time_t,,[[
 # endif
 #endif
 ]])
+GNUPG_TIME_T_UNSIGNED
 
 
-# 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
@@ -1133,22 +1268,38 @@ AC_CHECK_DECLS(getpagesize)
 AC_FUNC_FSEEKO
 AC_FUNC_VPRINTF
 AC_FUNC_FORK
-AC_CHECK_FUNCS([strerror strlwr tcgetattr mmap])
-AC_CHECK_FUNCS([strcasecmp strncasecmp ctermid times gmtime_r])
-AC_CHECK_FUNCS([unsetenv fcntl ftruncate inet_ntop])
+AC_CHECK_FUNCS([strerror strlwr tcgetattr mmap canonicalize_file_name])
+AC_CHECK_FUNCS([strcasecmp strncasecmp ctermid times gmtime_r strtoull])
+AC_CHECK_FUNCS([unsetenv fcntl ftruncate inet_ntop canonicalize_file_name])
 AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime])
 AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale])
-AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe stat getaddrinfo])
-AC_CHECK_FUNCS([ttyname rand ftello fsync stat])
+AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe getaddrinfo])
+AC_CHECK_FUNCS([ttyname rand ftello fsync stat lstat])
+
+if test "$have_android_system" = yes; then
+   # On Android ttyname is a stub but prints an error message.
+   AC_DEFINE(HAVE_BROKEN_TTYNAME,1,
+             [Defined if ttyname does not work properly])
+fi
 
 AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
 
+# Dirmngr requires mmap on Unix systems.
+if test $ac_cv_func_mmap != yes -a $mmap_needed = yes; then
+  AC_MSG_ERROR([[Sorry, the current implemenation requires mmap.]])
+fi
+
 #
-# These are needed by libjnlib - fixme: we should use a jnlib.m4
+# These are needed by the jnlib parts in common.
 # Note:  We already checked pwd.h.
-AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol])
-AC_CHECK_FUNCS([memrchr isascii timegm getrusage setrlimit stat setlocale])
-AC_CHECK_FUNCS([flockfile funlockfile fopencookie funopen getpwnam getpwuid])
+AC_CHECK_HEADERS([signal.h])
+AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \
+                memrchr isascii timegm getrusage setrlimit stat setlocale   \
+                flockfile funlockfile fopencookie funopen getpwnam getpwuid \
+                getenv inet_pton])
+# end jnlib checks.
+
+
 
 #
 # gnulib checks
@@ -1226,25 +1377,27 @@ AM_CONDITIONAL(DISABLE_REGEX, test x"$use_regex" != xyes)
 # when compiling a conftest (due to the "-lz" from LIBS).
 # Note that we combine zlib and bzlib2 in ZLIBS.
 #
-missing_zlib=yes
-_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
-  ])
+if test "$use_zip" = yes ; then
+  _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_,
+  AC_CHECK_HEADER(zlib.h,
+     AC_CHECK_LIB(z, deflateInit2_,
        [
        ZLIBS="-lz"
-       missing_zlib=no
+       AC_DEFINE(HAVE_ZIP,1, [Defined if ZIP and ZLIB are supported])
        ],
        CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}),
        CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags})
+fi
+
 
 #
 # Check whether we can support bzip2
@@ -1298,9 +1451,13 @@ GNUPG_CHECK_GNUMAKE
 # mysterious reasons - the final link step should bail out.
 # W32SOCKLIBS is also defined so that if can be used for tools not
 # requiring any network stuff but linking to code in libcommon which
-# tracks in winsock stuff (e.g. init_common_subsystems.
+# tracks in winsock stuff (e.g. init_common_subsystems).
 if test "$have_w32_system" = yes; then
-   W32SOCKLIBS="-lws2_32"
+   if test "$have_w32ce_system" = yes; then
+     W32SOCKLIBS="-lws2"
+   else
+     W32SOCKLIBS="-lws2_32"
+   fi
    NETLIBS="${NETLIBS} ${W32SOCKLIBS}"
 fi
 
@@ -1321,11 +1478,11 @@ if test "$GCC" = yes; then
 #endif]],[])],[_gcc_silent_wno=yes],[_gcc_silent_wno=no])
     AC_MSG_RESULT($_gcc_silent_wno)
 
-    # Note that it is okay to use CFLAGS here because this are just
+    # Note that it is okay to use CFLAGS here because these are just
     # warning options and the user should have a chance of overriding
     # them.
     if test "$USE_MAINTAINER_MODE" = "yes"; then
-        CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
+        CFLAGS="$CFLAGS -O3 -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
         CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security"
         if test x"$_gcc_silent_wno" = xyes ; then
           _gcc_wopt=yes
@@ -1345,8 +1502,7 @@ if test "$GCC" = yes; then
         AC_MSG_CHECKING([if gcc supports -Wdeclaration-after-statement])
         _gcc_cflags_save=$CFLAGS
         CFLAGS="-Wdeclaration-after-statement"
-        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],
-                          [_gcc_wopt=yes],[_gcc_wopt=no])
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
         AC_MSG_RESULT($_gcc_wopt)
         CFLAGS=$_gcc_cflags_save;
         if test x"$_gcc_wopt" = xyes ; then
@@ -1374,20 +1530,12 @@ if test "$GCC" = yes; then
     AC_MSG_CHECKING([if gcc supports -Wpointer-arith])
     _gcc_cflags_save=$CFLAGS
     CFLAGS="-Wpointer-arith"
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],[_gcc_psign=yes],[_gcc_psign=no])
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_psign=yes,_gcc_psign=no)
     AC_MSG_RESULT($_gcc_psign)
     CFLAGS=$_gcc_cflags_save;
     if test x"$_gcc_psign" = xyes ; then
        CFLAGS="$CFLAGS -Wpointer-arith"
     fi
-
-    # The undocumented option -Wno-psabi suppresses the annoying
-    #   "the ABI of passing union with long double has changed in GCC 4.4"
-    # which is emitted in estream-printf.c but entirely irrelvant
-    # because that union is local to the file.
-    if test x"$_gcc_silent_wno" = xyes ; then
-       CFLAGS="$CFLAGS -Wno-psabi"
-    fi
 fi
 
 
@@ -1399,48 +1547,17 @@ AC_ARG_ENABLE(optimization,
    AC_HELP_STRING([--disable-optimization],
                   [disable compiler optimization]),
                   [if test $enableval = no ; then
-                      CFLAGS=`echo $CFLAGS | sed 's/-O[[0-9]]//'`
+                      CFLAGS=`echo $CFLAGS | sed s/-O[[1-9]]\ /-O0\ /g`
                    fi])
 
 #
-# Prepare building of estream
-#
-estream_INIT
-
-
-#
 # Decide what to build
 #
-if test "$have_adns" = "yes"; then
-  AC_SUBST(GPGKEYS_KDNS, "gpg2keys_kdns$EXEEXT")
-fi
-
-
-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_libusb = no; then
-     build_scdaemon_extra="${tmp}without internal CCID driver"
-     tmp=", "
+     build_scdaemon_extra="without internal CCID driver"
   fi
   if test -n "$build_scdaemon_extra"; then
      build_scdaemon_extra="(${build_scdaemon_extra})"
@@ -1448,26 +1565,98 @@ if test "$build_scdaemon" = "yes"; then
 fi
 
 
-if test "$build_agent_only" = "yes" ; then
-  build_gpg=no
-  build_gpgsm=no
-  build_scdaemon=no
-  build_tools=no
-  build_doc=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")
-AM_CONDITIONAL(BUILD_TOOLS, test "$build_tools" = "yes")
-AM_CONDITIONAL(BUILD_DOC,   test "$build_doc" = "yes")
+#
+# Set variables for use by automake makefiles.
+#
+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")
+AM_CONDITIONAL(BUILD_G13,         test "$build_g13" = "yes")
+AM_CONDITIONAL(BUILD_DIRMNGR,     test "$build_dirmngr" = "yes")
+AM_CONDITIONAL(BUILD_TOOLS,       test "$build_tools" = "yes")
+AM_CONDITIONAL(BUILD_DOC,         test "$build_doc" = "yes")
 AM_CONDITIONAL(BUILD_SYMCRYPTRUN, test "$build_symcryptrun" = "yes")
 AM_CONDITIONAL(BUILD_GPGTAR,      test "$build_gpgtar" = "yes")
 
+AM_CONDITIONAL(ENABLE_CARD_SUPPORT, test "$card_support" = yes)
+AM_CONDITIONAL(NO_TRUST_MODELS, test "$use_trust_models" = no)
+
 AM_CONDITIONAL(RUN_GPG_TESTS,
-       test x$cross_compiling = xno -a "$build_gpg" = yes )
+               test x$cross_compiling = xno -a "$build_gpg" = yes )
+
+#
+# Set some defines for use gpgconf.
+#
+if test "$build_gpg" = yes ; then
+    AC_DEFINE(BUILD_WITH_GPG,1,[Defined if GPG is to be build])
+fi
+if test "$build_gpgsm" = yes ; then
+    AC_DEFINE(BUILD_WITH_GPGSM,1,[Defined if GPGSM is to be build])
+fi
+if test "$build_agent" = yes ; then
+    AC_DEFINE(BUILD_WITH_AGENT,1,[Defined if GPG-AGENT is to be build])
+fi
+if test "$build_scdaemon" = yes ; then
+    AC_DEFINE(BUILD_WITH_SCDAEMON,1,[Defined if SCDAEMON is to be build])
+fi
+if test "$build_dirmngr" = yes ; then
+    AC_DEFINE(BUILD_WITH_DIRMNGR,1,[Defined if SCDAEMON is to be build])
+fi
+if test "$build_g13" = yes ; then
+    AC_DEFINE(BUILD_WITH_G13,1,[Defined if G13 is to be build])
+fi
+
+
+#
+# Define Name strings
+#
+AC_DEFINE_UNQUOTED(GNUPG_NAME, "GnuPG", [The name of the project])
+
+AC_DEFINE_UNQUOTED(GPG_NAME, "gpg", [The name of the OpenPGP tool])
+AC_DEFINE_UNQUOTED(GPG_DISP_NAME, "GnuPG", [The displayed name of gpg])
+
+AC_DEFINE_UNQUOTED(GPGSM_NAME, "gpgsm", [The name of the S/MIME tool])
+AC_DEFINE_UNQUOTED(GPGSM_DISP_NAME, "GPGSM", [The displayed name of gpgsm])
+
+AC_DEFINE_UNQUOTED(GPG_AGENT_NAME, "gpg-agent", [The name of the agent])
+AC_DEFINE_UNQUOTED(GPG_AGENT_DISP_NAME, "GPG Agent",
+                                        [The displayed name of gpg-agent])
+
+AC_DEFINE_UNQUOTED(SCDAEMON_NAME, "scdaemon", [The name of the scdaemon])
+AC_DEFINE_UNQUOTED(SCDAEMON_DISP_NAME, "SCDaemon",
+                                       [The displayed name of scdaemon])
+
+AC_DEFINE_UNQUOTED(DIRMNGR_NAME, "dirmngr", [The name of the dirmngr])
+AC_DEFINE_UNQUOTED(DIRMNGR_DISP_NAME, "DirMngr",
+                                      [The displayed name of dirmngr])
+
+AC_DEFINE_UNQUOTED(G13_NAME, "g13", [The name of the g13 tool])
+AC_DEFINE_UNQUOTED(G13_DISP_NAME, "G13", [The displayed name of g13])
+
+AC_DEFINE_UNQUOTED(GPGCONF_NAME, "gpgconf", [The name of the gpgconf tool])
+AC_DEFINE_UNQUOTED(GPGCONF_DISP_NAME, "GPGConf",
+                                      [The displayed name of gpgconf])
+
+AC_DEFINE_UNQUOTED(GPGTAR_NAME, "gpgtar", [The name of the gpgtar tool])
+
+AC_DEFINE_UNQUOTED(GPG_AGENT_SOCK_NAME, "S.gpg-agent",
+                   [The name of the agent socket])
+AC_DEFINE_UNQUOTED(GPG_AGENT_SSH_SOCK_NAME, "S.gpg-agent.ssh",
+                   [The name of the agent socket for ssh])
+AC_DEFINE_UNQUOTED(DIRMNGR_INFO_NAME, "DIRMNGR_INFO",
+                   [The name of the dirmngr info envvar])
+AC_DEFINE_UNQUOTED(SCDAEMON_SOCK_NAME, "S.scdaemon",
+                   [The name of the SCdaemon socket])
+AC_DEFINE_UNQUOTED(DIRMNGR_SOCK_NAME, "S.dirmngr",
+                   [The name of the dirmngr socket])
+
+AC_DEFINE_UNQUOTED(GPGEXT_GPG, "gpg", [The standard binary file suffix])
+
+if test "$have_w32_system" = yes; then
+  AC_DEFINE_UNQUOTED(GNUPG_REGISTRY_DIR, "\\\\Software\\\\GNU\\\\GnuPG",
+                     [The directory part of the W32 registry keys])
+fi
 
 
 #
@@ -1514,7 +1703,7 @@ if test "$have_libgcrypt" = "no"; then
 *** You need libgcrypt to build this program.
 **  This library is for example available at
 ***   ftp://ftp.gnupg.org/gcrypt/libgcrypt/
-*** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API is required.)
+*** (at least version $NEED_LIBGCRYPT_VERSION (API $NEED_LIBGCRYPT_API) is required.)
 ***]])
 fi
 if test "$have_libassuan" = "no"; then
@@ -1528,6 +1717,7 @@ if test "$have_libassuan" = "no"; then
 ***]])
 fi
 if test "$have_ksba" = "no"; then
+    die=yes
     AC_MSG_NOTICE([[
 ***
 *** You need libksba to build this program.
@@ -1536,38 +1726,39 @@ if test "$have_ksba" = "no"; then
 *** (at least version $NEED_KSBA_VERSION using API $NEED_KSBA_API is required).
 ***]])
 fi
-if test "$missing_pth" = "yes"; then
+if test "$gnupg_have_ldap" = yes; then
+  if test "$have_w32ce_system" = yes; then
     AC_MSG_NOTICE([[
-***
-*** It is now required to build with support for the
-*** GNU Portable Threads Library (Pth). Please install this
-*** library first.  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
-*** To build GnuPG for Windows you need to use the W32PTH
-*** package; available at:
-***   ftp://ftp.g10code.com/g10code/w32pth/
+*** Note that CeGCC might be broken, a package fixing this is:
+***    http://files.kolab.org/local/windows-ce/
+***                           source/wldap32_0.1-mingw32ce.orig.tar.gz
+***                           binary/wldap32-ce-arm-dev_0.1-1_all.deb
 ***]])
-   die=yes
+   fi
 fi
-if test "$missing_zlib" = "yes"; then
+if test "$have_npth" = "no"; then
+    die=yes
     AC_MSG_NOTICE([[
 ***
-*** The zlib compression library is required.
-*** Please install a suitable development package
-*** (e.g. Debian package zlib1g-dev) or download
-*** it from http://zlib.net and build yourself.
+*** It is now required to build with support for the
+*** New Portable Threads Library (nPth). Please install this
+*** library first.  The library is for example available at
+***   ftp://ftp.gnupg.org/gcrypt/npth/
+*** (at least version $NEED_NPTH_VERSION (API $NEED_NPTH_API) is required).
 ***]])
-   die=yes
 fi
-if test "$missing_iconv" = "yes"; then
+
+if test "$require_iconv" = yes; then
+  if test "$am_func_iconv" != yes; then
+    die=yes
     AC_MSG_NOTICE([[
 ***
-*** It is now required to build with support for iconv
-*** Please install a suitable iconv implementation.
+*** The system does not provide a working iconv function.  Please
+*** install a suitable library; for example GNU Libiconv which is
+*** available at:
+***   http://ftp.gnu.org/gnu/libiconv/
 ***]])
-   die=yes
+  fi
 fi
 
 if test "$die" = "yes"; then
@@ -1584,8 +1775,6 @@ AC_CONFIG_FILES([ m4/Makefile
 Makefile
 po/Makefile.in
 gl/Makefile
-include/Makefile
-jnlib/Makefile
 common/Makefile
 common/w32info-rc.h
 kbx/Makefile
@@ -1593,9 +1782,8 @@ g10/Makefile
 sm/Makefile
 agent/Makefile
 scd/Makefile
-keyserver/Makefile
-keyserver/gpg2keys_mailto
-keyserver/gpg2keys_test
+g13/Makefile
+dirmngr/Makefile
 tools/gpg-zip
 tools/Makefile
 doc/Makefile
@@ -1603,6 +1791,8 @@ tests/Makefile
 tests/openpgp/Makefile
 tests/pkits/Makefile
 ])
+
+
 AC_OUTPUT
 
 
@@ -1614,15 +1804,24 @@ echo "
 
         OpenPGP:   $build_gpg
         S/MIME:    $build_gpgsm
-        Agent:     $build_agent $build_agent_threaded
+        Agent:     $build_agent
         Smartcard: $build_scdaemon $build_scdaemon_extra
+        G13:       $build_g13
+        Dirmngr:   $build_dirmngr
         Gpgtar:    $build_gpgtar
 
         Protect tool:      $show_gnupg_protect_tool_pgm
+        LDAP wrapper:      $show_gnupg_dirmngr_ldap_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
+
+        Dirmngr auto start:  $dirmngr_auto_start
+        Readline support:    $gnupg_cv_have_readline
+        LDAP support:        $gnupg_have_ldap
+        DNS SRV support:     $use_dns_srv
+        TLS support:         $use_tls_library
 "
 if test x"$use_regex" != xyes ; then
 echo "
diff --git a/dirmngr/ChangeLog-2011 b/dirmngr/ChangeLog-2011
new file mode 100644 (file)
index 0000000..84cf552
--- /dev/null
@@ -0,0 +1,1602 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-11-24  Werner Koch  <wk@g10code.com>
+
+       * ks-engine-http.c (ks_http_help): Do not print help for hkp.
+       * ks-engine-hkp.c (ks_hkp_help): Print help only for hkp.
+       (send_request): Remove test code.
+       (map_host): Use xtrymalloc.
+
+       * certcache.c (classify_pattern): Remove unused variable and make
+       explicit substring search work.
+
+2011-06-01  Marcus Brinkmann  <mb@g10code.com>
+
+       * Makefile.am (dirmngr_ldap_CFLAGS): Add $(LIBGCRYPT_CFLAGS),
+       which is needed by common/util.h.
+
+2011-04-25  Werner Koch  <wk@g10code.com>
+
+       * ks-engine-hkp.c (ks_hkp_search): Mark classify_user_id for use
+       with OpenPGP.
+       (ks_hkp_get): Ditto.
+
+2011-04-12  Werner Koch  <wk@g10code.com>
+
+       * ks-engine-hkp.c (ks_hkp_search, ks_hkp_get, ks_hkp_put): Factor
+       code out to ..
+       (make_host_part): new.
+       (hostinfo_s): New.
+       (create_new_hostinfo, find_hostinfo, sort_hostpool)
+       (select_random_host, map_host, mark_host_dead)
+       (ks_hkp_print_hosttable): New.
+
+2011-02-23  Werner Koch  <wk@g10code.com>
+
+       * certcache.c (get_cert_bysubject): Take care of a NULL argument.
+       (find_cert_bysubject): Ditto.  Fixes bug#1300.
+
+2011-02-09  Werner Koch  <wk@g10code.com>
+
+       * ks-engine-kdns.c: New but only the framework.
+
+       * server.c (cmd_keyserver): Add option --help.
+       (dirmngr_status_help): New.
+       * ks-action.c (ks_print_help): New.
+       (ks_action_help): New.
+       * ks-engine-finger.c (ks_finger_help): New.
+       * ks-engine-http.c (ks_http_help): New.
+       * ks-engine-hkp.c (ks_hkp_help): New.
+
+       * ks-action.c (ks_action_fetch): Support http URLs.
+       * ks-engine-http.c: New.
+
+       * ks-engine-finger.c (ks_finger_get): Rename to ks_finger_fetch.
+       Change caller.
+
+2011-02-08  Werner Koch  <wk@g10code.com>
+
+       * server.c (cmd_ks_fetch): New.
+       * ks-action.c (ks_action_fetch): New.
+       * ks-engine-finger.c: New.
+
+2011-02-03  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_LDADD): Remove -llber.
+
+2011-01-25  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (handle_connections): Rewrite loop to use pth-select
+       so to sync timeouts to the full second.
+       (pth_thread_id): New.
+       (main) [W32CE]: Fix setting of default homedir.
+
+       * ldap-wrapper.c (ldap_wrapper_thread): Sync to the full second.
+       Increate pth_wait timeout from 1 to 2 seconds.
+
+2011-01-20  Werner Koch  <wk@g10code.com>
+
+       * server.c (release_ctrl_keyservers): New.
+       (cmd_keyserver, cmd_ks_seach, cmd_ks_get, cmd_ks_put): New.
+       * dirmngr.h (uri_item_t): New.
+       (struct server_control_s): Add field KEYSERVERS.
+       * ks-engine-hkp.c: New.
+       * ks-engine.h: New.
+       * ks-action.c, ks-action.h: New.
+       * server.c: Include ks-action.h.
+       (cmd_ks_search): New.
+       * Makefile.am (dirmngr_SOURCES): Add new files.
+
+2011-01-19  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (main): Use es_printf for --gpgconf-list.
+
+2010-12-14  Werner Koch  <wk@g10code.com>
+
+       * cdb.h (struct cdb) [W32]: Add field CDB_MAPPING.
+       * cdblib.c (cdb_init) [W32]: Save mapping handle.
+       (cdb_free) [W32]: Don't leak the mapping handle from cdb_init by
+       using the saved one.
+
+       * crlcache.c (crl_cache_insert): Close unused matching files.
+
+       * dirmngr.c (main) [W32CE]: Change homedir in daemon mode to /gnupg.
+
+2010-12-07  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (TIMERTICK_INTERVAL) [W32CE]: Change to 60s.
+
+2010-11-23  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_LDFLAGS): Add extra_bin_ldflags.
+       (dirmngr_client_LDFLAGS): Ditto.
+
+2010-10-21  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (main): Changed faked system time warning
+
+2010-10-15  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (CLEANFILES): Add no-libgcrypt.c.
+
+2010-09-16  Werner Koch  <wk@g10code.com>
+
+       * validate.c (validate_cert_chain): Use GPG_ERR_MISSING_ISSUER_CERT.
+
+2010-08-13  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_SOURCES): Add w32-ldap-help.h.
+
+       * dirmngr_ldap.c (fetch_ldap): Call ldap_unbind.
+
+       * w32-ldap-help.h: New.
+       * dirmngr_ldap.c [W32CE]: Include w32-ldap-help.h and use the
+       mapped ldap functions.
+
+2010-08-12  Werner Koch  <wk@g10code.com>
+
+       * crlcache.c (update_dir, crl_cache_insert): s/unlink/gnupg_remove/.
+
+       * dirmngr.c (dirmngr_sighup_action): New.
+
+       * server.c (cmd_killdirmngr, cmd_reloaddirmngr): New.
+       (struct server_local_s): Add field STOPME.
+       (start_command_handler): Act on STOPME.
+
+2010-08-06  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (JNLIB_NEED_AFLOCAL): Define macro.
+       (main): Use SUN_LEN macro.
+       (main) [W32]: Allow EEXIST in addition to EADDRINUSE.
+
+2010-08-05  Werner Koch  <wk@g10code.com>
+
+       * server.c (set_error, leave_cmd): New.
+       (cmd_validate, cmd_ldapserver, cmd_isvalid, cmd_checkcrl)
+       (cmd_checkocsp, cmd_lookup, cmd_listcrls, cmd_cachecert): Use
+       leave_cmd.
+       (cmd_getinfo): New.
+       (data_line_cookie_write, data_line_cookie_close): New.
+       (cmd_listcrls): Replace assuan_get_data_fp by es_fopencookie.
+
+       * misc.c (create_estream_ksba_reader, my_estream_ksba_reader_cb): New.
+       * certcache.c (load_certs_from_dir): Use create_estream_ksba_reader.
+       * crlcache.c (crl_cache_load): Ditto.
+
+2010-08-03  Werner Koch  <wk@g10code.com>
+
+       * dirmngr_ldap.c (pth_enter, pth_leave) [USE_LDAPWRAPPER]: Turn
+       into functions for use in a 'for' control stmt.
+
+2010-07-26  Werner Koch  <wk@g10code.com>
+
+       * dirmngr_ldap.c (print_ldap_entries): Remove special fwrite case
+       for W32 because that is now handles by estream.
+
+2010-07-25  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_SOURCES) [!USE_LDAPWRAPPER]: Build
+       ldap-wrapper-ce.
+       * ldap-wrapper-ce.c: New.
+
+       * dirmngr_ldap.c (opt): Remove global variable ...
+       (my_opt_t): ... and declare a type instead.
+       (main): Define a MY_OPT variable and change all references to OPT
+       to this.
+       (set_timeout, print_ldap_entries, fetch_ldap, process_url): Pass
+       MYOPT arg.
+
+2010-07-24  Werner Koch  <wk@g10code.com>
+
+       * dirmngr_ldap.c (main): Init common subsystems.  Call
+       es_set_binary.
+
+2010-07-19  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c: Include ldap-wrapper.h.
+       (launch_reaper_thread): Move code to ...
+       * ldap-wrapper.c (ldap_wrapper_launch_thread): .. here.  Change
+       callers.
+       (ldap_wrapper_thread): Rename to ...
+       (wrapper_thread): this and make local.
+
+       * ldap.c (destroy_wrapper, print_log_line)
+       (read_log_data, ldap_wrapper_thread)
+       (ldap_wrapper_wait_connections, ldap_wrapper_release_context)
+       (ldap_wrapper_connection_cleanup, reader_callback, ldap_wrapper):
+       Factor code out to ...
+       * ldap-wrapper.c: new.
+       (ldap_wrapper): Make public.
+       (read_buffer): Copy from ldap.c.
+       * ldap-wrapper.h: New.
+       * Makefile.am (dirmngr_SOURCES): Add new files.
+
+2010-07-16  Werner Koch  <wk@g10code.com>
+
+       * http.c, http.h: Remove.
+
+       * dirmngr-err.h: New.
+       * dirmngr.h: Include dirmngr-err.h instead of gpg-error.h
+
+       * cdblib.c: Replace assignments to ERRNO by a call to
+       gpg_err_set_errno.  Include dirmngr-err.h.
+       (cdb_free) [__MINGW32CE__]: Do not use get_osfhandle.
+
+       * dirmngr.c [!HAVE_SIGNAL_H]: Don't include signal.h.
+       (USE_W32_SERVICE): New.  Use this to control the use of the W32
+       service system.
+
+2010-07-06  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (main): Print note on directory name changes.
+
+       Replace almost all uses of stdio by estream.
+
+       * b64dec.c, b64enc.c: Remove.  They are duplicated in ../common/.
+
+2010-06-28  Werner Koch  <wk@g10code.com>
+
+       * dirmngr_ldap.c (my_i18n_init): Remove.
+       (main): Call i18n_init instead of above function.
+
+       * dirmngr-client.c (my_i18n_init): Remove.
+       (main): Call i18n_init instead of above function.
+
+       * Makefile.am (dirmngr_LDADD): Add ../gl/libgnu.
+       (dirmngr_ldap_LDADD, dirmngr_client_LDADD): Ditto.
+
+2010-06-09  Werner Koch  <wk@g10code.com>
+
+       * i18n.h: Remove.
+
+       * Makefile.am (no-libgcrypt.c): New rule.
+
+       * exechelp.h: Remove.
+       * exechelp.c: Remove.
+       (dirmngr_release_process): Change callers to use the gnupg func.
+       (dirmngr_wait_process): Likewise.
+       (dirmngr_kill_process): Likewise.  This actually implements it for
+       W32.
+       * ldap.c (ldap_wrapper): s/get_dirmngr_ldap_path/gnupg_module_name/.
+       (ldap_wrapper_thread): Use gnupg_wait_process and adjust for
+       changed semantics.
+       (ldap_wrapper): Replace xcalloc by xtrycalloc.  Replace spawn
+       mechanism.
+
+       * server.c (start_command_handler): Remove assuan_set_log_stream.
+
+       * validate.c: Remove gcrypt.h and ksba.h.
+
+       * ldapserver.c: s/util.h/dirmngr.h/.
+
+       * dirmngr.c (sleep) [W32]: Remove macro.
+       (main): s/sleep/gnupg_sleep/.
+       (pid_suffix_callback): Change arg type.
+       (my_gcry_logger): Remove.
+       (fixed_gcry_pth_init): New.
+       (main): Use it.
+       (FD2INT): Remove.
+
+2010-06-08  Werner Koch  <wk@g10code.com>
+
+       * misc.h (copy_time): Remove and replace by gnupg_copy_time which
+       allows to set a null date.
+       * misc.c (dump_isotime, get_time, get_isotime, set_time)
+       (check_isotime, add_isotime): Remove and replace all calls by the
+       versions from common/gettime.c.
+
+       * crlcache.c, misc.c, misc.h: s/dirmngr_isotime_t/gnupg_isotime_t/.
+       * server.c, ldap.c: Reorder include directives.
+       * crlcache.h, misc.h: Remove all include directives.
+
+       * certcache.c (cmp_simple_canon_sexp): Remove.
+       (compare_serialno): Rewrite using cmp_simple_canon_sexp from
+       common/sexputil.c
+
+       * error.h: Remove.
+
+       * dirmngr.c: Remove transitional option "--ignore-ocsp-servic-url".
+       (opts): Use ARGPARSE macros.
+       (i18n_init): Remove.
+       (main): Use GnuPG init functions.
+
+       * dirmngr.h: Remove duplicated stuff now taken from ../common.
+
+       * get-path.c, util.h: Remove.
+
+       * Makefile.am: Adjust to GnuPG system.
+       * estream.c, estream.h, estream-printf.c, estream-printf.h: Remove.
+
+2010-06-07  Werner Koch  <wk@g10code.com>
+
+       * OAUTHORS, ONEWS, ChangeLog.1: New.
+
+       * ChangeLog, Makefile.am, b64dec.c, b64enc.c, cdb.h, cdblib.c
+       * certcache.c, certcache.h, crlcache.c, crlcache.h, crlfetch.c
+       * crlfetch.h, dirmngr-client.c, dirmngr.c, dirmngr.h
+       * dirmngr_ldap.c, error.h, estream-printf.c, estream-printf.h
+       * estream.c, estream.h, exechelp.c, exechelp.h, get-path.c, http.c
+       * http.h, i18n.h, ldap-url.c, ldap-url.h, ldap.c, ldapserver.c
+       * ldapserver.h, misc.c, misc.h, ocsp.c, ocsp.h, server.c, util.h
+       * validate.c, validate.h: Imported from the current SVN of the
+       dirmngr package (only src/).
+
+2010-03-13  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (int_and_ptr_u): New.
+       (pid_suffix_callback): Trick out compiler.
+       (start_connection_thread): Ditto.
+       (handle_connections): Ditto.
+
+2010-03-09  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (set_debug): Allow numerical values.
+
+2009-12-15  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c: Add option --ignore-cert-extension.
+       (parse_rereadable_options): Implement.
+       * dirmngr.h (opt): Add IGNORED_CERT_EXTENSIONS.
+       * validate.c (unknown_criticals): Handle ignored extensions.
+
+2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       * dirmngr-client.c (start_dirmngr): Convert posix FDs to assuan fds.
+
+2009-11-25  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (start_command_handler): Use assuan_fd_t and
+       assuan_fdopen on fds.
+
+2009-11-05  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (start_command_handler): Update use of
+       assuan_init_socket_server.
+       * dirmngr-client.c (start_dirmngr): Update use of
+       assuan_pipe_connect and assuan_socket_connect.
+
+2009-11-04  Werner Koch  <wk@g10code.com>
+
+       * server.c (register_commands): Add help arg to
+       assuan_register_command.  Change all command comments to strings.
+
+2009-11-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (reset_notify): Take LINE argument, return gpg_error_t.
+
+2009-10-16  Marcus Brinkmann  <marcus@g10code.com>
+
+       * Makefile.am: (dirmngr_LDADD): Link to $(LIBASSUAN_LIBS) instead
+       of $(LIBASSUAN_PTH_LIBS).
+       * dirmngr.c: Invoke ASSUAN_SYSTEM_PTH_IMPL.
+       (main): Call assuan_set_system_hooks and assuan_sock_init.
+
+2009-09-22  Marcus Brinkmann  <marcus@g10code.de>
+
+       * dirmngr.c (main): Update to new Assuan interface.
+       * server.c (option_handler, cmd_ldapserver, cmd_isvalid)
+       (cmd_checkcrl, cmd_checkocsp, cmd_lookup, cmd_loadcrl)
+       (cmd_listcrls, cmd_cachecert, cmd_validate): Return gpg_error_t
+       instead int.
+       (register_commands): Likewise for member HANDLER.
+       (start_command_handler): Allocate context with assuan_new before
+       starting server.  Release on error.
+       * dirmngr-client.c (main): Update to new Assuan interface.
+       (start_dirmngr): Allocate context with assuan_new before
+       connecting to server.  Release on error.
+
+2009-08-12  Werner Koch  <wk@g10code.com>
+
+       * dirmngr-client.c (squid_loop_body): Flush stdout.  Suggested by
+       Philip Shin.
+
+2009-08-07  Werner Koch  <wk@g10code.com>
+
+       * crlfetch.c (my_es_read): Add explicit check for EOF.
+
+       * http.c (struct http_context_s): Turn IN_DATA and IS_HTTP_0_9 to
+       bit fields.
+       (struct cookie_s): Add CONTENT_LENGTH_VALID and CONTENT_LENGTH.
+       (parse_response): Parse the Content-Length header.
+       (cookie_read): Handle content length.
+       (http_open): Make NEED_HEADER the semi-default.
+
+       * http.h (HTTP_FLAG_IGNORE_CL): New.
+
+2009-08-04  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (ldap_wrapper_thread): Factor some code out to ...
+       (read_log_data): ... new.  Close the log fd on error.
+       (ldap_wrapper_thread): Delay cleanup until the log fd is closed.
+       (SAFE_PTH_CLOSE): New.  Use it instead of pth_close.
+
+2009-07-31  Werner Koch  <wk@g10code.com>
+
+       * server.c (cmd_loadcrl): Add option --url.
+       * dirmngr-client.c (do_loadcrl): Make use of --url.
+
+       * crlfetch.c (crl_fetch): Remove HTTP_FLAG_NO_SHUTDOWN.  Add
+       flag HTTP_FLAG_LOG_RESP with active DBG_LOOKUP.
+
+       * http.c: Require estream.  Remove P_ES macro.
+       (write_server): Remove.
+       (my_read_line): Remove.  Replace all callers by es_read_line.
+       (send_request): Use es_asprintf.  Always store the cookie.
+       (http_wait_response): Remove the need to dup the socket.  USe new
+       shutdown flag.
+       * http.h (HTTP_FLAG_NO_SHUTDOWN): Rename to HTTP_FLAG_SHUTDOWN.
+
+       * estream.c, estream.h, estream-printf.c, estream-printf.h: Update
+       from current libestream.  This is provide es_asprintf.
+
+2009-07-20  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (pid_suffix_callback): New.
+       (main): Use log_set_pid_suffix_cb.
+       (start_connection_thread): Put the fd into the tls.
+
+       * ldap.c (ldap_wrapper_thread): Print ldap worker stati.
+       (ldap_wrapper_release_context): Print a debug info.
+       (end_cert_fetch_ldap): Release the reader.  Might fix bug#999.
+
+2009-06-17  Werner Koch  <wk@g10code.com>
+
+       * util.h: Remove unused dotlock.h.
+
+2009-05-26  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (ldap_wrapper): Show reader object in diagnostics.
+       * crlcache.c (crl_cache_reload_crl): Ditto.  Change debug messages
+       to regular diagnostics.
+       * dirmngr_ldap.c (print_ldap_entries): Add extra diagnostics.
+
+2009-04-03  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.h (struct server_local_s): Move back to ...
+       * server.c (struct server_local_s): ... here.
+       (get_ldapservers_from_ctrl): New.
+       * ldapserver.h (ldapserver_iter_begin): Use it.
+
+2008-10-29  Marcus Brinkmann  <marcus@g10code.de>
+
+       * estream.c (es_getline): Add explicit cast to silence gcc -W
+       warning.
+       * crlcache.c (finish_sig_check): Likewise.
+
+       * dirmngr.c (opts): Add missing initializer to silence gcc
+       -W warning.
+       * server.c (register_commands): Likewise.
+       * dirmngr-client.c (opts): Likewise.
+       * dirmngr_ldap.c (opts): Likewise.
+
+       * dirmngr-client.c (status_cb, inq_cert, data_cb): Change return
+       type to gpg_error_t to silence gcc warning.
+
+2008-10-21  Werner Koch  <wk@g10code.com>
+
+       * certcache.c (load_certs_from_dir): Accept ".der" files.
+
+       * server.c (get_istrusted_from_client): New.
+       * validate.c (validate_cert_chain): Add new optional arg
+       R_TRUST_ANCHOR.  Adjust all callers
+       * crlcache.c (crl_cache_entry_s): Add fields USER_TRUST_REQ
+       and CHECK_TRUST_ANCHOR.
+       (release_one_cache_entry): Release CHECK_TRUST_ANCHOR.
+       (list_one_crl_entry): Print info about the new fields.
+       (open_dir, write_dir_line_crl): Support the new U-flag.
+       (crl_parse_insert): Add arg R_TRUST_ANCHOR and set it accordingly.
+       (crl_cache_insert): Store trust anchor in entry object.
+       (cache_isvalid): Ask client for trust is needed.
+
+       * crlcache.c (open_dir): Replace xcalloc by xtrycalloc.
+       (next_line_from_file): Ditt.  Add arg to return the gpg error.
+       Change all callers.
+       (update_dir): Replace sprintf and malloc by estream_asprintf.
+       (crl_cache_insert): Ditto.
+       (crl_cache_isvalid): Replace xmalloc by xtrymalloc.
+       (get_auth_key_id): Ditto.
+       (crl_cache_insert): Ditto.
+
+       * crlcache.c (start_sig_check): Remove HAVE_GCRY_MD_DEBUG test.
+       * validate.c (check_cert_sig): Ditto.  Remove workaround for bug
+       in libgcrypt 1.2.
+
+       * estream.c, estream.h, estream-printf.c, estream-printf.h: Update
+       from current libestream (svn rev 61).
+
+2008-09-30  Marcus Brinkmann  <marcus@g10code.com>
+
+       * get-path.c (get_dirmngr_ldap_path): Revert last change.
+       Instead, use dirmngr_libexecdir().
+       (find_program_at_standard_place): Don't define for now.
+
+2008-09-30  Marcus Brinkmann  <marcus@g10code.com>
+
+       * get-path.c (dirmngr_cachedir): Make COMP a pointer to const to
+       silence gcc warning.
+       (get_dirmngr_ldap_path): Look for dirmngr_ldap in the installation
+       directory.
+
+2008-08-06  Marcus Brinkmann  <marcus@g10code.com>
+
+       * dirmngr.c (main): Mark the ldapserverlist-file option as
+       read-only.
+
+2008-07-31  Werner Koch  <wk@g10code.com>
+
+       * crlcache.c (start_sig_check) [!HAVE_GCRY_MD_DEBUG]: Use
+       gcry_md_start_debug
+
+2008-06-16  Werner Koch  <wk@g10code.com>
+
+       * get-path.c (w32_commondir): New.
+       (dirmngr_sysconfdir): Use it here.
+       (dirmngr_datadir): Ditto.
+
+2008-06-12  Marcus Brinkmann  <marcus@g10code.de>
+
+       * Makefile.am (dirmngr_SOURCES): Add ldapserver.h and ldapserver.c.
+       * ldapserver.h, ldapserver.c: New files.
+       * ldap.c: Include "ldapserver.h".
+       (url_fetch_ldap): Use iterator to get session servers as well.
+       (attr_fetch_ldap, start_default_fetch_ldap): Likewise.
+       * dirmngr.c: Include "ldapserver.h".
+       (free_ldapservers_list): Removed.  Change callers to
+       ldapserver_list_free.
+       (parse_ldapserver_file): Use ldapserver_parse_one.
+       * server.c: Include "ldapserver.h".
+       (cmd_ldapserver): New command.
+       (register_commands): Add new command LDAPSERVER.
+       (reset_notify): New function.
+       (start_command_handler): Register reset notify handler.
+       Deallocate session server list.
+       (lookup_cert_by_pattern): Use iterator to get session servers as well.
+       (struct server_local_s): Move to ...
+       * dirmngr.h (struct server_local_s): ... here.  Add new member
+       ldapservers.
+
+2008-06-10  Werner Koch  <wk@g10code.com>
+
+       Support PEM encoded CRLs.  Fixes bug#927.
+
+       * crlfetch.c (struct reader_cb_context_s): New.
+       (struct file_reader_map_s): Replace FP by new context.
+       (register_file_reader, get_file_reader): Adjust accordingly.
+       (my_es_read): Detect Base64 encoded CRL and decode if needed.
+       (crl_fetch): Pass new context to the callback.
+       (crl_close_reader): Cleanup the new context.
+       * b64dec.c: New.  Taken from GnuPG.
+       * util.h (struct b64state): Add new fields STOP_SEEN and
+       INVALID_ENCODING.
+
+2008-05-26  Marcus Brinkmann  <marcus@g10code.com>
+
+       * dirmngr.c (main) [HAVE_W32_SYSTEM]: Switch to system
+       configuration on gpgconf related commands, and make all options
+       unchangeable.
+
+2008-03-25  Marcus Brinkmann  <marcus@g10code.de>
+
+       * dirmngr_ldap.c (print_ldap_entries): Add code alternative for
+       W32 console stdout (unused at this point).
+
+2008-03-21  Marcus Brinkmann  <marcus@g10code.de>
+
+       * estream.c (ESTREAM_MUTEX_DESTROY): New macro.
+       (es_create, es_destroy): Use it.
+
+2008-02-21  Werner Koch  <wk@g10code.com>
+
+       * validate.c (check_cert_sig) [HAVE_GCRY_MD_DEBUG]: Use new debug
+       function if available.
+
+       * crlcache.c (abort_sig_check): Mark unused arg.
+
+       * exechelp.c (dirmngr_release_process) [!W32]: Mark unsed arg.
+
+       * validate.c (is_root_cert): New.  Taken from GnuPG.
+       (validate_cert_chain): Use it in place of the simple DN compare.
+
+2008-02-15  Marcus Brinkmann  <marcus@g10code.de>
+
+       * dirmngr.c (main): Reinitialize assuan log stream if necessary.
+
+       * crlcache.c (update_dir) [HAVE_W32_SYSTEM]: Remove destination
+       file before rename.
+       (crl_cache_insert) [HAVE_W32_SYSTEM]: Remove destination file
+       before rename.
+
+2008-02-14  Marcus Brinkmann  <marcus@g10code.de>
+
+       * validate.c (check_cert_policy): Use ksba_free instead of xfree.
+       (validate_cert_chain): Likewise.  Free SUBJECT on error.
+       (cert_usage_p): Likewise.
+
+       * crlcache.c (finish_sig_check): Undo last change.
+       (finish_sig_check): Close md.
+       (abort_sig_check): New function.
+       (crl_parse_insert): Use abort_sig_check to clean up.
+
+       * crlcache.c (crl_cache_insert): Clean up CDB on error.
+
+2008-02-13  Marcus Brinkmann  <marcus@g10code.de>
+
+       * crlcache.c (finish_sig_check): Call gcry_md_stop_debug.
+       * exechelp.h (dirmngr_release_process): New prototype.
+       * exechelp.c (dirmngr_release_process): New function.
+       * ldap.c (ldap_wrapper_thread): Release pid.
+       (destroy_wrapper): Likewise.
+
+       * dirmngr.c (launch_reaper_thread): Destroy tattr.
+       (handle_connections): Likewise.
+
+2008-02-12  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ldap.c (pth_close) [! HAVE_W32_SYSTEM]: New macro.
+       (struct wrapper_context_s): New member log_ev.
+       (destroy_wrapper): Check FDs for != -1 rather than != 0.  Use
+       pth_close instead of close.  Free CTX->log_ev.
+       (ldap_wrapper_thread): Rewritten to use pth_wait instead of
+       select.  Also use pth_read instead of read and pth_close instead
+       of close.
+       (ldap_wrapper): Initialize CTX->log_ev.
+       (reader_callback): Use pth_close instead of close.
+       * exechelp.c (create_inheritable_pipe) [HAVE_W32_SYSTEM]: Removed.
+       (dirmngr_spawn_process) [HAVE_W32_SYSTEM]: Use pth_pipe instead.
+       * dirmngr_ldap.c [HAVE_W32_SYSTEM]: Include <fcntl.h>.
+       (main) [HAVE_W32_SYSTEM]: Set mode of stdout to binary.
+
+2008-02-01  Werner Koch  <wk@g10code.com>
+
+       * ldap.c: Remove all ldap headers as they are unused.
+
+       * dirmngr_ldap.c (LDAP_DEPRECATED): New, to have OpenLDAP use the
+       old standard API.
+
+2008-01-10  Werner Koch  <wk@g10code.com>
+
+       * dirmngr-client.c: New option --local.
+       (do_lookup): Use it.
+
+       * server.c (lookup_cert_by_pattern): Implement local lookup.
+       (return_one_cert): New.
+       * certcache.c (hexsn_to_sexp): New.
+       (classify_pattern, get_certs_bypattern): New.
+
+       * misc.c (unhexify): Allow passing NULL for RESULT.
+       (cert_log_subject): Do not call ksba_free on an unused variable.
+
+2008-01-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * Makefile.am (dirmngr_LDADD, dirmngr_ldap_LDADD)
+       (dirmngr_client_LDADD): Add $(LIBICONV).  Reported by Michael
+       Nottebrock.
+
+2007-12-11  Werner Koch  <wk@g10code.com>
+
+       * server.c (option_handler): New option audit-events.
+       * dirmngr.h (struct server_control_s): Add member AUDIT_EVENTS.
+
+2007-11-26  Marcus Brinkmann  <marcus@g10code.de>
+
+       * get-path.c (dirmngr_cachedir): Create intermediate directories.
+       (default_socket_name): Use CSIDL_WINDOWS.
+
+2007-11-21  Werner Koch  <wk@g10code.com>
+
+       * server.c (lookup_cert_by_pattern): Add args SINGLE and CACHE_ONLY.
+       (cmd_lookup): Add options --single and --cache-only.
+
+2007-11-16  Werner Koch  <wk@g10code.com>
+
+       * certcache.c (load_certs_from_dir): Also log the subject DN.
+       * misc.c (cert_log_subject): New.
+
+2007-11-14  Werner Koch  <wk@g10code.com>
+
+       * dirmngr-client.c: Replace --lookup-url by --url.
+       (main): Remove extra code for --lookup-url.
+       (do_lookup): Remove LOOKUP_URL arg and use the
+       global option OPT.URL.
+
+       * server.c (has_leading_option): New.
+       (cmd_lookup): Use it.
+
+       * crlfetch.c (fetch_cert_by_url): Use GPG_ERR_INV_CERT_OBJ.
+       (fetch_cert_by_url): Use gpg_error_from_syserror.
+
+2007-11-14  Moritz  <moritz@gnu.org>  (wk)
+
+       * dirmngr-client.c: New command: --lookup-url <URL>.
+       (do_lookup): New parameter: lookup_url.  If TRUE, include "--url"
+       switch in LOOKUP transaction.
+       (enum): New entry: oLookupUrl.
+       (opts): Likewise.
+       (main): Handle oLookupUrl.  New variable: cmd_lookup_url, set
+       during option parsing, pass to do_lookup() and substitute some
+       occurences of "cmd_lookup" with "cmd_lookup OR cmd_lookup_url".
+       * crlfetch.c (fetch_cert_by_url): New function, uses
+       url_fetch_ldap() to create a reader object and libksba functions
+       to read a single cert from that reader.
+       * server.c (lookup_cert_by_url, lookup_cert_by_pattern): New
+       functions.
+       (cmd_lookup): Moved almost complete code ...
+       (lookup_cert_by_pattern): ... here.
+       (cmd_lookup): Support new optional argument: --url.  Depending on
+       the presence of that switch, call lookup_cert_by_url() or
+       lookup_cert_by_pattern().
+       (lookup_cert_by_url): Heavily stripped down version of
+       lookup_cert_by_pattern(), using fetch_cert_by_url.
+
+2007-10-24  Marcus Brinkmann  <marcus@g10code.de>
+
+       * exechelp.c (dirmngr_spawn_process): Fix child handles.
+
+2007-10-05  Marcus Brinkmann  <marcus@g10code.de>
+
+       * dirmngr.h: Include assuan.h.
+       (start_command_handler): Change type of FD to assuan_fd_t.
+       * dirmngr.c: Do not include w32-afunix.h.
+        (socket_nonce): New global variable.
+        (create_server_socket): Use assuan socket wrappers.  Remove W32
+       specific stuff.  Save the server nonce.
+        (check_nonce): New function.
+        (start_connection_thread): Call it.
+        (handle_connections): Change args to assuan_fd_t.
+       * server.c (start_command_handler): Change type of FD to assuan_fd_t.
+
+2007-09-12  Marcus Brinkmann  <marcus@g10code.de>
+
+       * dirmngr.c (main): Percent escape pathnames in --gpgconf-list output.
+
+2007-08-27  Moritz Schulte  <moritz@g10code.com>
+
+       * src/Makefile.am (AM_CPPFLAGS): Define DIRMNGR_SOCKETDIR based on
+       $(localstatedir).
+       * src/get-path.c (default_socket_name): Use DIRMNGR_SOCKETDIR
+       instead of hard-coded "/var/run/dirmngr".
+
+2007-08-16  Werner Koch  <wk@g10code.com>
+
+       * get-path.c (get_dirmngr_ldap_path): Make PATHNAME const.
+
+       * dirmngr.c (my_ksba_hash_buffer): Mark unused arg.
+       (dirmngr_init_default_ctrl): Ditto.
+       (my_gcry_logger): Ditto.
+       * dirmngr-client.c (status_cb): Ditto.
+       * dirmngr_ldap.c (catch_alarm): Ditto.
+       * estream-printf.c (pr_bytes_so_far): Ditto.
+       * estream.c (es_func_fd_create): Ditto.
+       (es_func_fp_create): Ditto.
+       (es_write_hexstring): Ditto.
+       * server.c (cmd_listcrls): Ditto.
+       (cmd_cachecert): Ditto.
+       * crlcache.c (cache_isvalid): Ditto.
+       * ocsp.c (do_ocsp_request): Ditto.
+       * ldap.c (ldap_wrapper_thread): Ditto.
+       * http.c (http_register_tls_callback): Ditto.
+       (connect_server): Ditto.
+       (write_server) [!HTTP_USE_ESTREAM]: Don't build.
+
+2007-08-14  Werner Koch  <wk@g10code.com>
+
+       * get-path.c (dirmngr_cachedir) [W32]: Use CSIDL_LOCAL_APPDATA.
+
+2007-08-13  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (handle_connections): Use a timeout in the accept
+       function.  Block signals while creating a new thread.
+       (shutdown_pending): Needs to be volatile as also accessed bt the
+       service function.
+       (w32_service_control): Do not use the regular log fucntions here.
+       (handle_tick): New.
+       (main): With system_service in effect use aDaemon as default
+       command.
+       (main) [W32]: Only temporary redefine main for the sake of Emacs's
+       "C-x 4 a".
+
+       * dirmngr-client.c (main) [W32]: Initialize sockets.
+       (start_dirmngr): Use default_socket_name instead of a constant.
+       * Makefile.am (dirmngr_client_SOURCES): Add get-path.c
+
+2007-08-09  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (parse_ocsp_signer): New.
+       (parse_rereadable_options): Set opt.ocsp_signer to this.
+       * dirmngr.h (fingerprint_list_t): New.
+       * ocsp.c (ocsp_isvalid, check_signature, validate_responder_cert):
+       Allow for several default ocscp signers.
+       (ocsp_isvalid): Return GPG_ERR_NO_DATA for an unknwon status.
+
+       * dirmngr-client.c: New option --force-default-responder.
+
+       * server.c (has_option, skip_options): New.
+       (cmd_checkocsp): Add option --force-default-responder.
+       (cmd_isvalid): Ditto.  Also add option --only-ocsp.
+
+       * ocsp.c (ocsp_isvalid): New arg FORCE_DEFAULT_RESPONDER.
+
+       * dirmngr.c: New option --ocsp-max-period.
+       * ocsp.c (ocsp_isvalid): Implement it and take care that a missing
+       next_update is to be ignored.
+
+       * crlfetch.c (my_es_read): New.  Use it instead of es_read.
+
+       * estream.h, estream.c, estream-printf.c: Updated from current
+       libestream SVN.
+
+2007-08-08  Werner Koch  <wk@g10code.com>
+
+       * crlcache.c (crl_parse_insert): Hack to allow for a missing
+       nextUpdate.
+
+       * dirmngr_ldap.c (print_ldap_entries): Strip the extension from
+       the want_attr.
+
+       * exechelp.c (dirmngr_wait_process): Reworked for clear error
+       semantics.
+       * ldap.c (ldap_wrapper_thread): Adjust for new
+       dirmngr_wait_process semantics.
+
+2007-08-07  Werner Koch  <wk@g10code.com>
+
+       * get-path.c (default_socket_name) [!W32]: Fixed syntax error.
+
+       * ldap.c (X509CACERT, make_url, fetch_next_cert_ldap): Support
+       x509caCert as used by the Bundesnetzagentur.
+       (ldap_wrapper): Do not pass the prgtram name as the first
+       argument.  dirmngr_spawn_process takes care of that.
+
+2007-08-04  Marcus Brinkmann  <marcus@g10code.de>
+
+       * dirmngr.h (opt): Add member system_service.
+       * dirmngr.c (opts) [HAVE_W32_SYSTEM]: New entry for option
+       --service.
+       (DEFAULT_SOCKET_NAME): Removed.
+       (service_handle, service_status,
+       w32_service_control) [HAVE_W32_SYSTEM]: New symbols.
+       (main) [HAVE_W32_SYSTEM]: New entry point for --service.  Rename
+       old function to ...
+       (real_main) [HAVE_W32_SYSTEM]: ... this.  Use default_socket_name
+       instead of DEFAULT_SOCKET_NAME, and similar for other paths.
+       Allow colons in Windows socket path name, and implement --service
+       option.
+       * util.h (dirmngr_sysconfdir, dirmngr_libexecdir, dirmngr_datadir,
+       dirmngr_cachedir, default_socket_name): New prototypes.
+       * get-path.c (dirmngr_sysconfdir, dirmngr_libexecdir)
+       (dirmngr_datadir, dirmngr_cachedir, default_socket_name): New
+       functions.
+       (DIRSEP_C, DIRSEP_S): New macros.
+
+2007-08-03  Marcus Brinkmann  <marcus@g10code.de>
+
+       * get-path.c: Really add the file this time.
+
+2007-07-31  Marcus Brinkmann  <marcus@g10code.de>
+
+       * crlfetch.c: Include "estream.h".
+       (crl_fetch): Use es_read callback instead a file handle.
+       (crl_close_reader): Use es_fclose instead of fclose.
+       (struct file_reader_map_s): Change type of FP to estream_t.
+       (register_file_reader, crl_fetch, crl_close_reader): Likewise.
+       * ocsp.c: Include "estream.h".
+       (read_response): Change type of FP to estream_t.
+       (read_response, do_ocsp_request): Use es_* variants of I/O
+       functions.
+
+       * http.c: Include <pth.h>.
+       (http_wait_response) [HAVE_W32_SYSTEM]: Use DuplicateHandle.
+       (cookie_read): Use pth_read instead read.
+       (cookie_write): Use pth_write instead write.
+
+2007-07-30  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ldap-url.c (ldap_str2charray): Fix buglet in ldap_utf8_strchr
+       invocation.
+
+2007-07-27  Marcus Brinkmann  <marcus@g10code.de>
+
+       * estream.h, estream.c: Update from recent GnuPG.
+
+       * get-path.c: New file.
+       * Makefile.am (dirmngr_SOURCES): Add get-path.c.
+       * util.h (default_homedir, get_dirmngr_ldap_path): New prototypes.
+       * dirmngr.c (main): Use default_homedir().
+       * ldap-url.h: Remove japanese white space (sorry!).
+
+2007-07-26  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ldap.c (pth_yield): Remove macro.
+
+       * ldap.c (pth_yield) [HAVE_W32_SYSTEM]: Define to Sleep(0).
+
+       * dirmngr_ldap.c [HAVE_W32_SYSTEM]: Do not include <ldap.h>, but
+       <winsock2.h>, <winldap.h> and "ldap-url.h".
+       * ldap.c [HAVE_W32_SYSTEM]: Do not include <ldap.h>, but
+       <winsock2.h> and <winldap.h>.
+
+       * ldap-url.c: Do not include <ldap.h>, but <winsock2.h>,
+       <winldap.h> and "ldap-url.h".
+       (LDAP_P): New macro.
+       * ldap-url.h: New file.
+       * Makefile.am (ldap_url): Add ldap-url.h.
+
+       * Makefile.am (ldap_url): New variable.
+       (dirmngr_ldap_SOURCES): Add $(ldap_url).
+       (dirmngr_ldap_LDADD): Add $(LIBOBJS).
+       * ldap-url.c: New file, excerpted from OpenLDAP.
+       * dirmngr.c (main) [HAVE_W32_SYSTEM]: Avoid the daemonization.
+       * dirmngr_ldap.c: Include "util.h".
+       (main) [HAVE_W32_SYSTEM]: Don't set up alarm.
+       (set_timeout) [HAVE_W32_SYSTEM]: Likewise.
+       * ldap.c [HAVE_W32_SYSTEM]: Add macros for setenv and pth_yield.
+       * no-libgcrypt.h (NO_LIBGCRYPT): Define.
+       * util.h [NO_LIBGCRYPT]: Don't include <gcrypt.h>.
+
+2007-07-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * Makefile.am (dirmngr_SOURCES): Add exechelp.h and exechelp.c.
+       * exechelp.h, exechelp.c: New files.
+       * ldap.c: Don't include <sys/wait.h> but "exechelp.h".
+       (destroy_wrapper, ldap_wrapper_thread,
+       ldap_wrapper_connection_cleanup): Use dirmngr_kill_process instead
+       of kill.
+       (ldap_wrapper_thread): Use dirmngr_wait_process instead of
+       waitpid.
+       (ldap_wrapper): Use dirmngr_spawn_process.
+
+2007-07-20  Marcus Brinkmann  <marcus@g10code.de>
+
+       * certcache.c (cert_cache_lock): Do not initialize statically.
+       (init_cache_lock): New function.
+       (cert_cache_init): Call init_cache_lock.
+
+       * estream.h, estream.c, estream-printf.h, estream-printf.c: New
+       files.
+       * Makefile.am (dirmngr_SOURCES): Add estream.c, estream.h,
+       estream-printf.c, estream-printf.h.
+
+       * http.c: Update to latest version from GnuPG.
+
+       * Makefile.am (cdb_sources)
+       * cdblib.c: Port to windows (backport from tinycdb 0.76).
+
+       * crlcache.c [HAVE_W32_SYSTEM]: Don't include sys/utsname.h.
+       [MKDIR_TAKES_ONE_ARG]: Define mkdir as a macro for such systems.
+       (update_dir, crl_cache_insert) [HAVE_W32_SYSTEM]: Don't get uname.
+       * server.c (start_command_handler) [HAVE_W32_SYSTEM]: Don't log
+       peer credentials.
+
+       * dirmngr.c [HAVE_W32_SYSTEM]: Do not include sys/socket.h or
+       sys/un.h, but ../jnlib/w32-afunix.h.
+       (sleep) [HAVE_W32_SYSTEM]: New macro.
+       (main) [HAVE_W32_SYSTEM]: Don't mess with SIGPIPE.  Use W32 socket
+       API.
+       (handle_signal) [HAVE_W32_SYSTEM]: Deactivate the bunch of the
+       code.
+       (handle_connections) [HAVE_W32_SYSTEM]: don't handle signals.
+
+2006-11-29  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (my_strusage): Use macro for the bug report address
+       and the copyright line.
+       * dirmngr-client.c (my_strusage): Ditto.
+       * dirmngr_ldap.c (my_strusage): Ditto.
+
+       * Makefile.am: Do not link against LIBICONV.
+
+2006-11-19  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c: Include i18n.h.
+
+2006-11-17  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_LDADD): Use LIBASSUAN_PTH_LIBS.
+
+2006-11-16  Werner Koch  <wk@g10code.com>
+
+       * server.c (start_command_handler): Replaced
+       assuan_init_connected_socket_server by assuan_init_socket_server_ext.
+
+       * crlcache.c (update_dir): Put a diagnostic into DIR.txt.
+       (open_dir): Detect invalid and duplicate entries.
+       (update_dir): Fixed search for second field.
+
+2006-10-23  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (main): New command --gpgconf-test.
+
+2006-09-14  Werner Koch  <wk@g10code.com>
+
+       * server.c (start_command_handler): In vebose mode print
+       information about the peer.  This may later be used to restrict
+       certain commands.
+
+2006-09-12  Werner Koch  <wk@g10code.com>
+
+       * server.c (start_command_handler): Print a more informative hello
+       line.
+       * dirmngr.c: Moved config_filename into the opt struct.
+
+2006-09-11  Werner Koch  <wk@g10code.com>
+
+       Changed everything to use Assuan with gpg-error codes.
+       * maperror.c: Removed.
+       * server.c (map_to_assuan_status): Removed.
+       * dirmngr.c (main): Set assuan error source.
+       * dirmngr-client.c (main): Ditto.
+
+2006-09-04  Werner Koch  <wk@g10code.com>
+
+       * crlfetch.c (crl_fetch): Implement HTTP redirection.
+       * ocsp.c (do_ocsp_request): Ditto.
+
+       New HTTP code version taken from gnupg svn release 4236.
+       * http.c (http_get_header): New.
+       (capitalize_header_name, store_header): New.
+       (parse_response): Store headers away.
+       (send_request): Return GPG_ERR_NOT_FOUND if connect_server failed.
+       * http.h: New flag HTTP_FLAG_NEED_HEADER.
+
+2006-09-01  Werner Koch  <wk@g10code.com>
+
+       * crlfetch.c (register_file_reader, get_file_reader): New.
+       (crl_fetch): Register the file pointer for HTTP.
+       (crl_close_reader): And release it.
+
+       * http.c, http.h: Updated from GnuPG SVN trunk.  Changed all users
+       to adopt the new API.
+       * dirmngr.h: Moved inclusion of jnlib header to ...
+       * util.h: .. here.  This is required becuase http.c includes only
+       a file util.h but makes use of log_foo. Include gcrypt.h so that
+       gcry_malloc et al are declared.
+
+2006-08-31  Werner Koch  <wk@g10code.com>
+
+       * ocsp.c (check_signature): Make use of the responder id.
+
+2006-08-30  Werner Koch  <wk@g10code.com>
+
+       * validate.c (check_cert_sig): Workaround for rimemd160.
+       (allowed_ca): Always allow trusted CAs.
+
+       * dirmngr.h (cert_ref_t): New.
+       (struct server_control_s): Add field OCSP_CERTS.
+       * server.c (start_command_handler): Release new field
+       * ocsp.c (release_ctrl_ocsp_certs): New.
+       (check_signature): Store certificates in OCSP_CERTS.
+
+       * certcache.c (find_issuing_cert): Reset error if cert was found
+       by subject.
+       (put_cert): Add new arg FPR_BUFFER.  Changed callers.
+       (cache_cert_silent): New.
+
+       * dirmngr.c (parse_rereadable_options): New options
+       --ocsp-max-clock-skew and --ocsp-current-period.
+       * ocsp.c (ocsp_isvalid): Use them here.
+
+       * ocsp.c (validate_responder_cert): New optional arg signer_cert.
+       (check_signature_core): Ditto.
+       (check_signature): Use the default signer certificate here.
+
+2006-06-27  Werner Koch  <wk@g10code.com>
+
+       * dirmngr-client.c (inq_cert): Take care of SENDCERT_SKI.
+
+2006-06-26  Werner Koch  <wk@g10code.com>
+
+       * crlcache.c (lock_db_file): Count open files when needed.
+       (find_entry): Fixed deleted case.
+
+2006-06-23  Werner Koch  <wk@g10code.com>
+
+       * misc.c (cert_log_name): New.
+
+       * certcache.c (load_certs_from_dir): Also print certificate name.
+       (find_cert_bysn): Release ISSDN.
+
+       * validate.h: New VALIDATE_MODE_CERT.
+       * server.c (cmd_validate): Use it here so that no policy checks
+       are done.  Try to validated a cached copy of the target.
+
+       * validate.c (validate_cert_chain): Implement a validation cache.
+       (check_revocations): Print more diagnostics.  Actually use the
+       loop variable and not the head of the list.
+       (validate_cert_chain): Do not check revocations of CRL issuer
+       certificates in plain CRL check mode.
+       * ocsp.c (ocsp_isvalid): Make sure it is reset for a status of
+       revoked.
+
+2006-06-22  Werner Koch  <wk@g10code.com>
+
+       * validate.c (cert_use_crl_p): New.
+       (cert_usage_p): Add a mode 6 for CRL signing.
+       (validate_cert_chain): Check that the certificate may be used for
+       CRL signing.  Print a note when not running as system daemon.
+       (validate_cert_chain): Reduce the maximum depth from 50 to 10.
+
+       * certcache.c (find_cert_bysn): Minor restructuring
+       (find_cert_bysubject): Ditto.  Use get_cert_local when called
+       without KEYID.
+       * crlcache.c (get_crlissuer_cert_bysn): Removed.
+       (get_crlissuer_cert): Removed.
+       (crl_parse_insert): Use find_cert_bysubject and find_cert_bysn
+       instead of the removed functions.
+
+2006-06-19  Werner Koch  <wk@g10code.com>
+
+       * certcache.c (compare_serialno): Silly me. Using 0 as true is
+       that hard; tsss. Fixed call cases except for the only working one
+       which are both numbers of the same length.
+
+2006-05-15  Werner Koch  <wk@g10code.com>
+
+       * crlfetch.c (crl_fetch): Use no-shutdown flag for HTTP.  This
+       seems to be required for "IBM_HTTP_Server/2.0.47.1 Apache/2.0.47
+       (Unix)".
+
+       * http.c (parse_tuple): Set flag to to indicate no value.
+       (build_rel_path): Take care of it.
+
+       * crlcache.c (crl_cache_reload_crl): Also iterate over all names
+       within a DP.
+
+2005-09-28  Marcus Brinkmann  <marcus@g10code.de>
+
+       * Makefile.am (dirmngr_LDADD): Add @LIBINTL@ and @LIBICONV@.
+       (dirmngr_ldap_LDADD): Likewise.
+       (dirmngr_client_LDADD): Likewise.
+
+2005-09-12  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c: Fixed description to match the one in gpgconf.
+
+2005-06-15  Werner Koch  <wk@g10code.com>
+
+       * server.c (cmd_lookup): Take care of NO_DATA which might get
+       returned also by start_cert_fetch().
+
+2005-04-20  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (ldap_wrapper_wait_connections): Set a shutdown flag.
+       (ldap_wrapper_thread): Handle shutdown in a special way.
+
+2005-04-19  Werner Koch  <wk@g10code.com>
+
+       * server.c (get_cert_local, get_issuing_cert_local)
+       (get_cert_local_ski): Bail out if called without a local context.
+
+2005-04-18  Werner Koch  <wk@g10code.com>
+
+       * certcache.c (find_issuing_cert): Fixed last resort method which
+       should be finding by subject and not by issuer. Try to locate it
+       also using the keyIdentifier method.  Improve error reporting.
+       (cmp_simple_canon_sexp): New.
+       (find_cert_bysubject): New.
+       (find_cert_bysn): Ask back to the caller before trying an extarnl
+       lookup.
+       * server.c (get_cert_local_ski): New.
+       * crlcache.c (crl_parse_insert): Also try to locate issuer
+       certificate using the keyIdentifier.  Improved error reporting.
+
+2005-04-14  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (start_cert_fetch_ldap): Really return ERR.
+
+2005-03-17  Werner Koch  <wk@g10code.com>
+
+       * http.c (parse_response): Changed MAXLEN and LEN to size_t to
+       match the requirement of read_line.
+       * http.h (http_context_s): Ditto for BUFFER_SIZE.
+
+2005-03-15  Werner Koch  <wk@g10code.com>
+
+       * ldap.c: Included time.h.  Reported by Bernhard Herzog.
+
+2005-03-09  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c: Add a note to the help listing check the man page for
+       other options.
+
+2005-02-01  Werner Koch  <wk@g10code.com>
+
+       * crlcache.c (crl_parse_insert): Renamed a few variables and
+       changed diagnostic strings for clarity.
+       (get_issuer_cert): Renamed to get_crlissuer_cert. Try to locate
+       the certificate from the cache using the subject name.  Use new
+       fetch function.
+       (get_crlissuer_cert_bysn): New.
+       (crl_parse_insert): Use it here.
+       * crlfetch.c (ca_cert_fetch): Changed interface.
+       (fetch_next_ksba_cert): New.
+       * ldap.c (run_ldap_wrapper): Add arg MULTI_MODE.  Changed all
+       callers.
+       (start_default_fetch_ldap): New
+       * certcache.c (get_cert_bysubject): New.
+       (clean_cache_slot, put_cert): Store the subject DN if available.
+       (MAX_EXTRA_CACHED_CERTS): Increase limit of cachable certificates
+       to 1000.
+       (find_cert_bysn): Loop until a certificate with a matching S/N has
+       been found.
+
+       * dirmngr.c (main): Add honor-http-proxy to the gpgconf list.
+
+2005-01-31  Werner Koch  <wk@g10code.com>
+
+       * ldap.c: Started to work on support for userSMIMECertificates.
+
+       * dirmngr.c (main): Make sure to always pass a server control
+       structure to the caching functions.  Reported by Neil Dunbar.
+
+2005-01-05  Werner Koch  <wk@g10code.com>
+
+       * dirmngr-client.c (read_pem_certificate): Skip trailing percent
+       escaped linefeeds.
+
+2005-01-03  Werner Koch  <wk@g10code.com>
+
+       * dirmngr-client.c (read_pem_certificate): New.
+       (read_certificate): Divert to it depending on pem option.
+       (squid_loop_body): New.
+       (main): New options --pem and --squid-mode.
+
+2004-12-17  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (launch_ripper_thread): Renamed to launch_reaper_thread.
+       (shutdown_reaper): New.  Use it for --server and --daemon.
+       * ldap.c (ldap_wrapper_wait_connections): New.
+
+2004-12-17  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_ldap_LDADD): Adjusted for new LDAP checks.
+
+2004-12-16  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (ldap_wrapper): Peek on the output to detect empty output
+       early.
+
+2004-12-15  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (ldap_wrapper): Print a diagnostic after forking for the
+       ldap wrapper.
+       * certcache.h (find_cert_bysn): Add this prototype.
+       * crlcache.c (start_sig_check): Write CRL hash debug file.
+       (finish_sig_check): Dump the signer's certificate.
+       (crl_parse_insert): Try to get the issuing cert by authKeyId.
+       Moved certificate retrieval after item processing.
+
+2004-12-13  Werner Koch  <wk@g10code.com>
+
+       * dirmngr_ldap.c (catch_alarm, set_timeout): new.
+       (main): Install alarm handler. Add new option --only-search-timeout.
+       (print_ldap_entries, fetch_ldap): Use set_timeout ();
+       * dirmngr.h: Make LDAPTIMEOUT a simple unsigned int.  Change all
+       initializations.
+       * ldap.c (start_cert_fetch_ldap, run_ldap_wrapper): Pass timeout
+       option to the wrapper.
+       (INACTIVITY_TIMEOUT): Depend on LDAPTIMEOUT.
+       (run_ldap_wrapper): Add arg IGNORE_TIMEOUT.
+       (ldap_wrapper_thread): Check for special timeout exit code.
+
+       * dirmngr.c: Workaround a typo in gpgconf for
+       ignore-ocsp-service-url.
+
+2004-12-10  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (url_fetch_ldap): Use TMP and not a HOST which is always
+       NULL.
+       * misc.c (host_and_port_from_url): Fixed bad encoding detection.
+
+2004-12-03  Werner Koch  <wk@g10code.com>
+
+       * crlcache.c (crl_cache_load): Re-implement it.
+
+       * dirmngr-client.c: New command --load-crl
+       (do_loadcrl): New.
+
+       * dirmngr.c (parse_rereadable_options, main): Make --allow-ocsp,
+       --ocsp-responder, --ocsp-signer and --max-replies re-readable.
+
+       * ocsp.c (check_signature): try to get the cert from the cache
+       first.
+       (ocsp_isvalid): Print the next and this update times on time
+       conflict.
+
+       * certcache.c (load_certs_from_dir): Print the fingerprint for
+       trusted certificates.
+       (get_cert_byhexfpr): New.
+       * misc.c (get_fingerprint_hexstring_colon): New.
+
+2004-12-01  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_LDADD): Don't use LDAP_LIBS.
+
+       * validate.c (validate_cert_chain): Fixed test; as written in the
+       comment we want to do this only in daemon mode.  For clarity
+       reworked by using a linked list of certificates and include root
+       and tragte certificate.
+       (check_revocations): Likewise.  Introduced a recursion sentinel.
+
+2004-11-30  Werner Koch  <wk@g10code.com>
+
+       * crlfetch.c (ca_cert_fetch, crl_fetch_default): Do not use the
+       binary prefix as this will be handled in the driver.
+
+       * dirmngr_ldap.c: New option --log-with-pid.
+       (fetch_ldap): Handle LDAP_NO_SUCH_OBJECT.
+       * ldap.c (run_ldap_wrapper, start_cert_fetch_ldap): Use new log
+       option.
+
+
+2004-11-25  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (dirmngr_ldap_CFLAGS): Added GPG_ERROR_CFLAGS.
+       Noted by Bernhard Herzog.
+
+2004-11-24  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (ldap_wrapper): Fixed default name of the ldap wrapper.
+
+       * b64enc.c (b64enc_start, b64enc_finish): Use standard strdup/free
+       to manage memory.
+
+       * dirmngr.c: New options --ignore-http-dp, --ignore-ldap-dp and
+       --ignore-ocsp-service-url.
+       * crlcache.c (crl_cache_reload_crl): Implement them.
+       * ocsp.c (ocsp_isvalid): Ditto.
+
+2004-11-23  Werner Koch  <wk@g10code.com>
+
+       * ldap.c (ldap_wrapper_thread, reader_callback, ldap_wrapper):
+       Keep a timestamp and terminate the wrapper after some time of
+       inactivity.
+
+       * dirmngr-client.c (do_lookup): New.
+       (main): New option --lookup.
+       (data_cb): New.
+       * b64enc.c: New. Taken from GnuPG 1.9.
+       * no-libgcrypt.c (gcry_strdup): Added.
+
+       * ocsp.c (ocsp_isvalid): New arg CERT and lookup the issuer
+       certificate using the standard methods.
+
+       * server.c (cmd_lookup): Truncation is now also an indication for
+       error.
+       (cmd_checkocsp): Implemented.
+
+       * dirmngr_ldap.c (fetch_ldap): Write an error marker for a
+       truncated search.
+       * ldap.c (add_server_to_servers): Reactivated.
+       (url_fetch_ldap): Call it here and try all configured servers in
+       case of a a failed lookup.
+       (fetch_next_cert_ldap): Detect the truncation error flag.
+       * misc.c (host_and_port_from_url, remove_percent_escapes): New.
+
+2004-11-22  Werner Koch  <wk@g10code.com>
+
+       * dirmngr_ldap.c (main): New option --proxy.
+       * ocsp.c (do_ocsp_request): Take care of opt.disable_http.
+       * crlfetch.c (crl_fetch): Honor the --honor-http-proxy variable.
+       (crl_fetch): Take care of  opt.disable_http and disable_ldap.
+       (crl_fetch_default, ca_cert_fetch, start_cert_fetch):
+       * ldap.c (run_ldap_wrapper): New arg PROXY.
+       (url_fetch_ldap, attr_fetch_ldap, start_cert_fetch_ldap): Pass it.
+
+       * http.c (http_open_document): Add arg PROXY.
+       (http_open): Ditto.
+       (send_request): Ditto and implement it as an override.
+
+       * ocsp.c (validate_responder_cert): Use validate_cert_chain.
+
+       * Makefile.am (AM_CPPFLAGS): Add macros for a few system
+       directories.
+       * dirmngr.h (opt): New members homedir_data, homedir_cache,
+       ldap_wrapper_program, system_daemon, honor_http_proxy, http_proxy,
+       ldap_proxy, only_ldap_proxy, disable_ldap, disable_http.
+       * dirmngr.c (main): Initialize new opt members HOMEDIR_DATA and
+       HOMEDIR_CACHE.
+       (parse_rereadable_options): New options --ldap-wrapper-program,
+       --http-wrapper-program, --disable-ldap, --disable-http,
+       --honor-http-proxy, --http-proxy, --ldap-proxy, --only-ldap-proxy.
+       (reread_configuration): New.
+
+       * ldap.c (ldap_wrapper): Use the correct name for the wrapper.
+
+       * crlcache.c (DBDIR_D): Make it depend on opt.SYSTEM_DAEMON.
+       (cleanup_cache_dir, open_dir, update_dir, make_db_file_name)
+       (crl_cache_insert, create_directory_if_needed): Use opt.HOMEDIR_CACHE
+
+       * validate.c (check_revocations): New.
+       * crlcache.c (crl_cache_isvalid): Factored most code out to
+       (cache_isvalid): .. new.
+       (crl_cache_cert_isvalid): New.
+       * server.c (cmd_checkcrl): Cleaned up by using this new function.
+       (reload_crl): Moved to ..
+       * crlcache.c (crl_cache_reload_crl): .. here and made global.
+
+       * certcache.c (cert_compute_fpr): Renamed from computer_fpr and
+       made global.
+       (find_cert_bysn): Try to lookup missing certs.
+       (cert_cache_init): Intialize using opt.HOMEDIR_DATA.
+
+
+2004-11-19  Werner Koch  <wk@g10code.com>
+
+       * dirmngr-client.c (status_cb): New.  Use it in very verbose mode.
+
+       * server.c (start_command_handler): Malloc the control structure
+       and properly release it.  Removed the primary_connection
+       hack. Cleanup running wrappers.
+       (dirmngr_status): Return an error code.
+       (dirmngr_tick): Return an error code and detect a
+       cancellation. Use wall time and not CPU time.
+       * validate.c (validate_cert_chain): Add CTRL arg and changed callers.
+       * crlcache.c (crl_cache_isvalid):
+       * crlfetch.c (ca_cert_fetch, start_cert_fetch, crl_fetch_default)
+       (crl_fetch): Ditto.
+       * ldap.c (ldap_wrapper, run_ldap_wrapper, url_fetch_ldap)
+       (attr_fetch_ldap, start_cert_fetch_ldap): Ditto.
+       (ldap_wrapper_release_context): Reset the stored CTRL.
+       (reader_callback): Periodically call dirmngr_tick.
+       (ldap_wrapper_release_context): Print an error message for read
+       errors.
+       (ldap_wrapper_connection_cleanup): New.
+
+2004-11-18  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (main): Do not cd / if not running detached.
+
+       * dirmngr-client.c: New options --cache-cert and --validate.
+       (do_cache, do_validate): New.
+       * server.c (cmd_cachecert, cmd_validate): New.
+
+       * crlcache.c (get_issuer_cert): Make use of the certificate cache.
+       (crl_parse_insert): Validate the issuer certificate.
+
+       * dirmngr.c (handle_signal): Reinitialize the certificate cache on
+       a HUP.
+       (struct opts): Add --homedir to enable the already implemented code.
+       (handle_signal): Print stats on SIGUSR1.
+
+       * certcache.c (clean_cache_slot, cert_cache_init)
+       (cert_cache_deinit): New.
+       (acquire_cache_read_lock, acquire_cache_write_lock)
+       (release_cache_lock): New.  Use them where needed.
+       (put_cert): Renamed from put_loaded_cert.
+       (cache_cert): New.
+       (cert_cache_print_stats): New.
+       (compare_serialno): Fixed.
+
+2004-11-16  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (AM_CPPFLAGS): Define DIRMNGR_SYSCONFDIR and
+       DIRMNGR_LIBEXECDIR.
+
+       * misc.c (dump_isotime, dump_string, dump_cert): New.  Taken from
+       gnupg 1.9.
+       (dump_serial): New.
+
+2004-11-15  Werner Koch  <wk@g10code.com>
+
+       * validate.c: New. Based on gnupg's certchain.c
+
+       * ldap.c (get_cert_ldap): Removed.
+       (read_buffer): New.
+       (start_cert_fetch_ldap, fetch_next_cert_ldap)
+       (end_cert_fetch_ldap): Rewritten to make use of the ldap wrapper.
+
+2004-11-12  Werner Koch  <wk@g10code.com>
+
+       * http.c (insert_escapes): Print the percent sign too.
+
+       * dirmngr-client.c (inq_cert): Ignore "SENDCERT" and
+       "SENDISSUERCERT".
+
+       * server.c (do_get_cert_local): Limit the length of a retruned
+       certificate.  Return NULL without an error if an empry value has
+       been received.
+
+       * crlfetch.c (ca_cert_fetch): Use the ksba_reader_object.
+       (setup_funopen, fun_reader, fun_closer): Removed.
+
+       * crlcache.c (get_issuer_cert): Adjust accordingly.
+
+       * ldap.c (attr_fetch_ldap_internal, attr_fetch_fun_closer)
+       (attr_fetch_fun_reader, url_fetch_ldap_internal)
+       (get_attr_from_result_ldap): Removed.
+       (destroy_wrapper, print_log_line, ldap_wrapper_thread)
+       (ldap_wrapper_release_context, reader_callback, ldap_wrapper)
+       (run_ldap_wrapper): New.
+       (url_fetch_ldap): Make use of the new ldap wrapper and return a
+       ksba reader object instead of a stdio stream.
+       (attr_fetch_ldap): Ditto.
+       (make_url, escape4url): New.
+
+2004-11-11  Werner Koch  <wk@g10code.com>
+
+       * dirmngr.c (launch_ripper_thread): New.
+       (main): Start it wheere appropriate.  Always ignore SIGPIPE.
+       (start_connection_thread): Maintain a connection count.
+       (handle_signal, handle_connections): Use it here instead of the
+       thread count.
+
+       * crlcache.c (crl_cache_insert): Changed to use ksba reader
+       object.  Changed all callers to pass this argument.
+
+2004-11-08  Werner Koch  <wk@g10code.com>
+
+       * dirmngr_ldap.c: New.
+
+       * crlcache.c (crl_cache_init): Don't return a cache object but
+       keep it module local.  We only need one.
+       (crl_cache_deinit): Don't take cache object but work on existing
+       one.
+       (get_current_cache): New.
+       (crl_cache_insert, crl_cache_list, crl_cache_load): Use the global
+       cache object and removed the cache arg.  Changed all callers.
+
+       * dirmngr-client.c: New option --ping.
+
+       * dirmngr.c (main): New option --daemon. Initialize PTH.
+       (handle_connections, start_connection_thread): New.
+       (handle_signal): New.
+       (parse_rereadable_options): New. Changed main to make use of it.
+       (set_debug): Don't bail out on invalid debug levels.
+       (main): Init the crl_chache for server and daemon mode.
+
+       * server.c (start_command_handler): New arg FD.  Changed callers.
+
+2004-11-06  Werner Koch  <wk@g10code.com>
+
+       * server.c (map_assuan_err): Factored out to ..
+       * maperror.c: .. new file.
+       * util.h: Add prototype
+
+2004-11-05  Werner Koch  <wk@g10code.com>
+
+       * no-libgcrypt.c: New, used as helper for dirmngr-client which
+       does not need libgcrypt proper but jnlib references the memory
+       functions.  Taken from gnupg 1.9.12.
+
+       * dirmngr.h: Factored i18n and xmalloc code out to ..
+       * i18n.h, util.h: .. New.
+
+       * dirmngr-client.c: New.  Some code taken from gnupg 1.9.12.
+       * Makefile.am (bin_PROGRAMS) Add dirmngr-client.
+
+2004-11-04  Werner Koch  <wk@g10code.com>
+
+       * src/server.c (get_fingerprint_from_line, cmd_checkcrl)
+       (cmd_checkocsp): New.
+       (register_commands): Register new commands.
+       (inquire_cert_and_load_crl): Factored most code out to ..
+       (reload_crl): .. new function.
+       * src/certcache.h, src/certcache.c: New.
+       * src/Makefile.am (dirmngr_SOURCES): Add new files.
+
+2004-11-04  Werner Koch  <wk@g10code.com>
+
+       Please note that earlier entries are found in the top level
+       ChangeLog.
+       [Update after merge with GnuPG: see ./ChangeLog.1]
+
+
+ Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+          2011 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.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/dirmngr/ChangeLog.1 b/dirmngr/ChangeLog.1
new file mode 100644 (file)
index 0000000..f7b50c7
--- /dev/null
@@ -0,0 +1,806 @@
+There are old Dirmngr ChangeLog entries.
+
+2004-10-04  Werner Koch  <wk@g10code.com>
+
+       * src/dirmngr.c: Changed an help entry description.
+
+2004-09-30  Werner Koch  <wk@g10code.com>
+
+       * src/dirmngr.c (i18n_init): Always use LC_ALL.
+
+2004-09-28  Werner Koch  <wk@g10code.com>
+
+       Released 0.5.6.
+
+       * config.guess, config.sub: Updated.
+
+2004-06-21  Werner Koch  <wk@g10code.com>
+
+       * src/crlfetch.c (crl_fetch): Bad hack to use the right attribute.
+
+2004-05-13  Werner Koch  <wk@gnupg.org>
+
+        Released 0.5.5.
+
+       * src/ldap.c (start_cert_fetch_ldap, start_cert_fetch_ldap): More
+       detailed error messages.
+
+       * src/crlcache.c (update_dir): Handle i-records properly.
+
+2004-04-29  Werner Koch  <wk@gnupg.org>
+
+       Released 0.5.4.
+
+       * src/crlcache.h (crl_cache_result_t): Add CRL_CACHE_CANTUSE.
+       * src/server.c (cmd_isvalid): Handle it here.
+       * src/crlcache.c (crl_cache_isvalid): Issue this code if the CRL
+       cant be used.
+       (open_dir): Parse new fields 8,9 and 10 as well as the invalid flag.
+       (write_dir_line_crl): Write new fields.
+       (get_crl_number, get_auth_key_id): New.
+       (crl_cache_insert): Fill new fields.  Mark the entry invalid if
+       the CRL is too old after an update or an unknown critical
+       extension was seen.
+       (list_one_crl_entry): Print the new fields.
+
+2004-04-28  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Requires libksba 0.9.6.
+
+       * src/dirmngr.c: New option --ocsp-signer.
+       * src/dirmngr.h (opt): Renamed member OCSP_REPONDERS to
+       OCSP_RESPONDER and made ist a simple string. Add OCSP_SIGNER.
+       * src/ocsp.c (ocsp_isvalid): Changed it accordingly.
+       (ocsp_isvalid): Pass the ocsp_signer to check_signature.
+       (check_signature): New arg SIGNER_FPR.  Use it to retrieve the
+       certificate. Factored out common code to ..
+       (check_signature_core): .. New.
+
+2004-04-27  Werner Koch  <wk@gnupg.org>
+
+       * src/server.c (start_command_handler): Keep track of the first
+       connection.
+       (dirmngr_tick): New.
+       * src/ldap.c (attr_fetch_fun_reader): Call it from time to time.
+
+2004-04-23  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c (main): Removed the add-servers option from the
+       gpgconf list.  It is not really useful.
+
+2004-04-02  Thomas Schwinge  <schwinge@nic-nac-project.de>
+
+       * autogen.sh: Added ACLOCAL_FLAGS.
+
+2004-04-13  Werner Koch  <wk@gnupg.org>
+
+       * src/crlcache.c (update_dir): Do not double close FPOUT.
+
+2004-04-09  Werner Koch  <wk@gnupg.org>
+
+       * src/cdblib.c (cdb_make_start): Wipeout the entire buffer to
+       shutup valgrind.
+       (ewrite): Fixed writing bad data on EINTR.
+
+       * src/ldap.c (get_attr_from_result_ldap): Fixed bad copy and
+       terminate of a string.
+
+       * src/crlfetch.c (crl_fetch): Fixed freeing of VALUE on error.
+
+2004-04-07  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.h (server_control_s): Add member force_crl_refresh.
+       * src/server.c (option_handler): New.
+       (start_command_handler): Register option handler
+       * src/crlcache.c (crl_cache_isvalid): Add arg FORCE_REFRESH.
+       (crl_cache_insert): Record last refresh in memory.
+
+       * src/server.c (inquire_cert_and_load_crl): Renamed from
+       inquire_cert.
+
+2004-04-06  Werner Koch  <wk@gnupg.org>
+
+       Released 0.5.3
+
+       * doc/dirmngr.texi: Updated.
+       * doc/texinfo.tex: Updated.
+
+2004-04-05  Werner Koch  <wk@gnupg.org>
+
+       * src/ocsp.c (ocsp_isvalid): Check THIS_UPDATE.
+
+       * src/misc.c (add_isotime): New.
+       (date2jd, jd2date, days_per_month, days_per_year): New. Taken from
+       my ancient (1988) code used in Wedit (time2.c).
+
+2004-04-02  Werner Koch  <wk@gnupg.org>
+
+       * autogen.sh: Check gettext version.
+       * configure.ac: Add AM_GNU_GETTEXT.
+
+2004-04-02  gettextize  <bug-gnu-gettext@gnu.org>
+
+       * Makefile.am (SUBDIRS): Add intl.
+       (EXTRA_DIST): Add config.rpath.
+       * configure.ac (AC_CONFIG_FILES): Add intl/Makefile,
+
+2004-04-02  Werner Koch  <wk@gnupg.org>
+
+       Add i18n at most places.
+
+       * src/dirmngr.c (i18n_init): New.
+       (main): Call it.
+       * src/dirmngr.h: Add i18n stuff.
+
+2004-04-01  Werner Koch  <wk@gnupg.org>
+
+       * src/misc.c (get_fingerprint_hexstring): New.
+
+       * src/server.c (dirmngr_status): New.
+
+2004-03-26  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Add AC_SYS_LARGEFILE.
+
+       * doc/dirmngr.texi: Changed the license to the GPL as per message
+       by Mathhias Kalle Dalheimer of Klaralvdalens-Datakonsult dated
+       Jan 7, 2004.
+       * doc/fdl.texi: Removed.
+
+2004-03-25  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c (main): New command --fetch-crl.
+
+2004-03-23  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c: New option --allow-ocsp.
+       * src/server.c (cmd_isvalid): Make use of allow_ocsp.
+
+2004-03-17  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c (main) <gpgconf>: Fixed default value quoting.
+
+2004-03-16  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c (main): Add ocsp-responder to the gpgconf list.
+       Add option --debug-level.
+       (set_debug): New.
+
+2004-03-15  Werner Koch  <wk@gnupg.org>
+
+       * src/misc.c (canon_sexp_to_grcy): New.
+
+2004-03-12  Werner Koch  <wk@gnupg.org>
+
+       * src/crlfetch.c (crl_fetch): Hack to substitute http for https.
+
+2004-03-10  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c (parse_ldapserver_file): Don't skip the entire
+       file on errors.
+
+2004-03-09  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c (my_ksba_hash_buffer): New.
+       (main): Initialize the internal libksba hashing.
+
+       * src/server.c (get_issuer_cert_local): Renamed to ...
+       (get_cert_local): ... this.  Changed all callers.  Allow NULL for
+       ISSUER to return the current target cert.
+       (get_issuing_cert_local): New.
+       (do_get_cert_local): Moved common code to here.
+
+2004-03-06  Werner Koch  <wk@gnupg.org>
+
+       Released 0.5.2.
+
+       * configure.ac: Fixed last change to check the API version of
+       libgcrypt.
+
+2004-03-05  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Also check the SONAME of libgcrypt.
+
+2004-03-03  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c: New option --ocsp-responder.
+       * src/dirmngr.h (opt): Add member OCSP_RESPONDERS.
+
+2004-02-26  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * src/server.c (start_command_handler): Corrected typo and made
+       dirmngr output it's version in the greeting message.
+
+2004-02-24  Marcus Brinkmann  <marcus@g10code.de>
+
+       * src/dirmngr.c (DEFAULT_ADD_SERVERS): Removed.  If this were
+       true, there'd be no way to disable it.
+       (main): Dump options in new gpgconf format.
+
+2004-02-11  Werner Koch  <wk@gnupg.org>
+
+       * autogen.sh (check_version): Removed bashism and simplified.
+
+2004-02-06  Moritz Schulte  <mo@g10code.com>
+
+       * src/crlfetch.c (crl_fetch_default): Do not dereference VALUE,
+       when checking for non-zero.
+
+2004-02-01  Marcus Brinkmann  <marcus@g10code.de>
+
+       * src/dirmngr.c (DEFAULT_ADD_SERVERS, DEFAULT_MAX_REPLIES)
+       (DEFAULT_LDAP_TIMEOUT): New macros.
+       (main): Use them.
+       (enum cmd_and_opt_values): New command aGPGConfList.
+       (main): Add handler here.
+
+2004-01-17  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Added AC_CHECK_FUNCS tests again, because the
+       other test occurrences belong to the jnlib tests block.
+
+2004-01-15  Moritz Schulte  <mo@g10code.com>
+
+       * configure.ac: Fixed funopen replacement mechanism; removed
+       unnecessary AC_CHECK_FUNCS calls.
+
+2004-01-14  Werner Koch  <wk@gnupg.org>
+
+       * src/crlcache.c (list_one_crl_entry): Don't use putchar.
+
+       * src/server.c (cmd_listcrls): New.
+
+2003-12-23  Werner Koch  <wk@gnupg.org>
+
+       Released 0.5.1.
+
+2003-12-17  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac (CFLAGS): Add -Wformat-noliteral in gcc +
+       maintainer mode.
+       (NEED_LIBASSUAN_VERSION): Bump up to 0.6.2.
+
+2003-12-16  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Update the tests for jnlib.
+       * src/dirmngr.c (main): Ignore SIGPIPE in server mode.
+
+2003-12-12  Werner Koch  <wk@gnupg.org>
+
+       * src/crlcache.c (hash_dbfile): Also hash version info of the
+       cache file format.
+
+       * src/Makefile.am (dirmngr_SOURCES): Add http.h.
+
+       * configure.ac: Removed checking for DB2. Add checking for mmap.
+       * src/cdb.h, src/cdblib.h: New.  Add a few comments from the
+       original man page and fixed typos.
+       * src/cdblib.c (cdb_findinit, cdb_findnext): Modified to allow
+       walking over all entries.
+       * src/crlcache.h: Removed DB2/4 cruft.
+       (release_one_cache_entry, lock_db_file, crl_parse_insert)
+       (crl_cache_insert, crl_cache_isvalid, list_one_crl_entry): Use the
+       new CDB interface.
+
+       * src/dirmngr.c: Beautified the help messages.
+       (wrong_args): New.
+       (main): new option --force.  Revamped the command handling code.
+       Allow to pass multiple CRLS as well as stdin to --local-crl.
+       * src/crlcache.c (crl_cache_insert): Make --force work.
+
+2003-12-11  Werner Koch  <wk@gnupg.org>
+
+       * src/crlfetch.c (crl_fetch): Enhanced to allow fetching binary
+       data using HTTP.
+       * src/http.c, src/http.h: Replaced by the code from gnupg 1.3 and
+       modified acording to our needs.
+       (read_line): New. Based on the code from GnuPG's iobuf_read_line.
+       * configure.ac: Check for getaddrinfo.
+
+       * src/dirmngr.c (parse_ldapserver_file): Close the stream.
+       (main): Free ldapfile.
+
+       * src/ocsp.c, src/ocsp.h: New. Albeit not functionality.
+
+       * src/server.c (inquire_cert): Catch EOF when reading dist points.
+
+       * src/crlcache.c (hash_dbfile, check_dbfile): New.
+       (lock_db_file, crl_cache_insert): Use them here to detect
+       corrupted CRL files.
+       (open_dir): Read the new dbfile hash field.
+
+       * src/crlfetch.c (crl_fetch, crl_fetch_default): Changed to retrun
+       a stream.
+       (fun_reader, fun_closer, setup_funopen): New.
+       * src/server.c (inquire_cert): Changed to use the new stream interface
+       of crlfetch.c.
+
+2003-12-10  Werner Koch  <wk@gnupg.org>
+
+       * src/funopen.c: New.
+       * configure.ac (funopen): Add test.
+       * src/Makefile.am (dirmngr_LDADD): Add LIBOBJS.
+
+       * src/crlcache.c (next_line_from_file): Remove the limit on the
+       line length.
+       (crl_cache_new): Removed.
+       (open_dbcontent): New.
+       (crl_cache_init): Use it here.
+       (crl_cache_flush): The DB content fie is now in the cache
+       directory, so we can simplify it.
+       (make_db_file_name, lock_db_file, unlock_db_file): New.
+       (release_cache): Close the cached DB files.
+       (crl_cache_isvalid): Make use of the new lock_db_file.
+       (crl_cache_insert): Changed to take a stream as argument.
+       (crl_parse_insert): Rewritten to use a temporary DB and to avoid
+       using up large amounts of memory.
+       (db_entry_new): Removed.
+       (release_cache,release_one_cache_entry): Splitted up.
+       (find_entry): Take care of the new deleted flag.
+       (crl_cache_load): Simplified becuase we can now pass a FP to the
+       insert code.
+       (save_contents): Removed.
+       (update_dir): New.
+       (open_dbcontent_file): Renamed to open_dir_file.
+       (check_dbcontent_version): Renamed to check_dir_version.
+       (open_dbcontent): Renamed to open_dir.
+
+       * src/dirmngr.c: New option --faked-system-time.
+       * src/misc.c (faked_time_p, set_time, get_time): New.  Taken from GnuPG.
+       (check_isotime): New.
+       (unpercent_string): New.
+
+2003-12-09  Werner Koch  <wk@gnupg.org>
+
+       * src/crlcache.h (DBDIR,DBCONTENTFILE): Changed value.
+
+       * autogen.sh: Reworked.
+       * README.CVS: New.
+       * configure.ac: Added min_automake_version.
+
+2003-12-03  Werner Koch  <wk@gnupg.org>
+
+       * src/server.c (cmd_lookup): Send an END line after each
+       certificate.
+
+2003-11-28  Werner Koch  <wk@gnupg.org>
+
+       * src/Makefile.am (dirmngr_LDADD): Remove DB_LIBS
+       because it never got defined and -ldb{2,4} is implictly set
+       by the AC_CHECK_LIB test in configure.
+
+       * src/crlcache.c (mydbopen): DB4 needs an extra parameter; I
+       wonder who ever tested DB4 support.  Add an error statement in
+       case no DB support is configured.
+
+       * tests/Makefile.am: Don't use AM_CPPFLAGS but AM_CFLAGS, replaced
+       variables by configure templates.
+       * src/Makefile.am: Ditto.
+
+2003-11-19  Werner Koch  <wk@gnupg.org>
+
+       * src/crlcache.c (list_one_crl_entry): Define X to nothing for non
+       DB4 systems.  Thanks to Luca M. G. Centamore.
+
+2003-11-17  Werner Koch  <wk@gnupg.org>
+
+       Released 0.5.0
+
+       * src/crlcache.c (crl_cache_new): Fixed eof detection.
+
+       * src/server.c (cmd_loadcrl): Do the unescaping.
+
+       * doc/dirmngr.texi: Added a history section for this modified
+       version.
+
+2003-11-14  Werner Koch  <wk@gnupg.org>
+
+       * tests/asschk.c: New.  Taken from GnuPG.
+       * tests/Makefile.am: Added asschk.
+
+2003-11-13  Werner Koch  <wk@gnupg.org>
+
+       * src/ldap.c (fetch_next_cert_ldap): Get the pattern switching
+       right.
+
+       * tests/test-dirmngr.c: Replaced a couple of deprecated types.
+
+       * configure.ac (GPG_ERR_SOURCE_DEFAULT): Added.
+       (fopencookie, asprintf): Removed unneeded test.
+       (PRINTABLE_OS_NAME): Updated the test from gnupg.
+       (CFLAGS): Do full warnings only in maintainer mode. Add flag
+       --enable gcc-warnings to override it and to enable even more
+       warnings.
+       * acinclude.m4: Removed the libgcrypt test.
+
+       * src/ldap.c (get_attr_from_result_ldap): Simplified the binary
+       hack and return a proper gpg error.
+       (attr_fetch_ldap_internal): Changed error handling.
+       (attr_fetch_ldap): Reworked.  Return configuration error if no
+       servers are configured.
+       (url_fetch_ldap, add_server_to_servers)
+       (url_fetch_ldap_internal): Reworked.
+       (struct cert_fetch_context_s): New to get rid of a global state.
+       (start_cert_fetch_ldap): Allocate context and do a bind with a
+       timeout.  Parse pattern.
+       (end_cert_fetch_ldap): Take context and don't return anything.
+       (find_next_pattern): Removed.
+       (parse_one_pattern): Redone.
+       (get_cert_ldap): Redone.
+       * src/server.c (cmd_lookup): Changed for changed fetch functions.
+
+       * doc/dirmngr.texi: Reworked a bit to get rid of tex errors.
+
+       * configure.ac: Enable makeinfo test.
+
+       * src/crlcache.c (crl_cache_insert): Fixed for latest KSBA API
+       changes.
+       * tests/test-dirmngr.c (main): Ditto.  Also added some more error
+       checking.
+
+2003-11-11  Werner Koch  <wk@gnupg.org>
+
+       * src/cert.c (hashify_data, hexify_data, serial_hex)
+       (serial_to_buffer): Moved all to ...
+       * src/misc.c: .. here.
+       * src/Makefile.am (cert.c, cert.h): Removed.
+       * cert.c, cert.h: Removed.
+
+       * m4/: New.
+       * configure.ac, Makefile.am: Include m4 directory support, updated
+       required library versions.
+
+       * src/cert.c (make_cert): Removed.
+
+       * src/ldap.c (fetch_next_cert_ldap): Return a gpg style error.
+
+       * src/misc.h (copy_time): New.
+       * src/misc.c (get_isotime): New.
+       (iso_string2time, iso_time2string): Removed.
+       (unhexify): New.
+
+       * src/crlcache.h (DBCONTENTSVERSION): Bumbed to 0.6.
+       * src/crlcache.c (finish_sig_check): New.  Factored out from
+       crl_parse_insert and entirely redone.
+       (do_encode_md): Removed.
+       (print_time): Removed
+       (crl_cache_isvalid): Reworked.
+
+2003-11-10  Werner Koch  <wk@gnupg.org>
+
+       * src/crlcache.c (make_db_val, parse_db_val): Removed.
+
+       * src/cert.c (serial_to_buffer): New.
+
+       * src/server.c (get_issuer_cert_local): Rewritten.
+
+       * src/crlcache.c (crl_parse_insert): Rewritten.  Takes now a CTRL
+       instead of the Assuan context. Changed caller accordingly.
+       (get_issuer_cert): Cleaned up.
+
+       * src/crlfetch.c (crl_fetch): Changed VALUE to unsigned char* for
+       documentation reasons.  Make sure that VALUE is released on error.
+       (crl_fetch_default, ca_cert_fetch): Ditto.
+
+       * src/crlcache.c (release_cache): New.
+       (crl_cache_deinit): Use it here.
+       (crl_cache_flush): Redone.
+       (save_contents): Redone.
+       (crl_cache_list, list_one_crl_entry): Print error messages.
+
+2003-11-06  Werner Koch  <wk@gnupg.org>
+
+       * src/crlcache.c (create_directory_if_needed, cleanup_cache_dir):
+       New.  Factored out from crl_cache_new and mostly rewritten.
+       (crl_cache_new): Rewritten.
+       (next_line_from_file): New.
+       (find_entry): Cleaned up.
+       (crl_cache_deinit): Cleaned up.
+
+       * src/dirmngr.c (dirmngr_init_default_ctrl): New stub.
+       * src/dirmngr.h (ctrl_t): New.
+       (DBG_ASSUAN,...): Added the usual debug test macros.
+       * src/server.c: Removed the GET_PTR cruft, replaced it by ctrl_t.
+       Removed the recursion flag.
+       (get_issuer_cert_local): Allow for arbitary large
+       certificates. 4096 is definitely too small.
+       (inquire_cert): Ditto.
+       (start_command_handler): Set a hello line and call the default
+       init function.
+       (cmd_isvalid): Rewritten.
+       (inquire_cert): Removed unused arg LINE. General cleanup.
+       (map_assuan_err,map_to_assuan_status): New.  Taken from gnupg 1.9.
+       (cmd_lookup): Rewritten.
+       (cmd_loadcrl): Started to rewrite it.
+
+2003-10-29  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.c (parse_ldapserver_file): Entirely rewritten.
+       (cleanup): New.
+       (main): Cleaned up.
+
+2003-10-28  Werner Koch  <wk@gnupg.org>
+
+       * src/dirmngr.h: Renamed dirmngr_opt to opt.
+
+       * src/dirmngr.c (parse_ldapserver_file, free_ldapservers_list):
+       Moved with this file.  Cleaned up.  Replaced too deep recursion in
+       the free function.
+
+2003-10-21  Werner Koch  <wk@gnupg.org>
+
+       Changed all occurrences of assuan.h to use use the system provided
+       one.
+       * src/server.c (register_commands): Adjusted for Assuan API change.
+
+2003-08-14  Werner Koch  <wk@gnupg.org>
+
+       * src/Makefile.am: s/LIBKSBA_/KSBA_/. Changed for external Assuan lib.
+       * tests/Makefile.am: Ditto.
+
+       * configure.ac: Partly restructured, add standard checks for
+       required libraries, removed included libassuan.
+       * Makefile.am (SUBDIRS): Removed assuan becuase we now use the
+       libassuan package.
+
+       * src/dirmngr.c (main): Properly initialize Libgcrypt and libksba.
+
+2003-08-13  Werner Koch  <wk@gnupg.org>
+
+       * src/server.c (get_issuer_cert_local): Print error using
+       assuan_strerror.
+
+       * src/crlcache.c (do_encode_md, start_sig_check): Adjust for
+       changed Libgcrypt API.
+
+2003-06-19  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * configure.ac: Upped version to 0.4.7-cvs.
+
+2003-06-19  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * configure.ac: Release 0.4.6.
+
+2003-06-17  Bernhard Reiter <bernhard@intevation.de>
+
+       * src/ldap.c (url_fetch_ldap()):
+         try other default servers when an url with hostname failed
+       * AUTHORS:  added Steffen and Werner
+       * THANKS: Thanked people in the ChangeLog and the Ägypten-Team
+
+
+2003-06-16  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * configure.ac, src/crlcache.h, src/crlcache.c: Added db4 support.
+       * src/Makefile.am, tests/Makefile.am: Removed automake warning.
+       * tests/test-dirmngr.c: Removed a warning.
+
+2003-05-12  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * doc/Makefile.am: Added dirmngr.ops to DISTCLEANFILES.
+       * ChangeLog, doc/ChangeLog, src/ChangeLog: Merged dirmngr ChangeLogs
+       into one toplevel file.
+       * acinclude.m4, configure.ac: Renamed PFX to PATH for consistency.
+
+2003-05-12  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * src/ldap.c: Fixed end-of-certificates-list indication.
+
+2003-05-08  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * src/server.c: Fixed iteration over server list
+
+2003-02-23  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * src/crlcache.h, src/crlcache.c, src/dirmngr.c: Implemented --flush command.
+
+2003-02-07  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac: Release 0.4.4.
+
+2003-02-05  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * src/ldap.c: Try harder with and without ";binary" in the
+       attribute name when fetching certificates.
+       * src/ldap.c, src/server.c: Support multiple userCertificate attributes
+       per entry.
+
+2003-02-04  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * src/ldap.c: Include the sn attribute in the search filter.
+       Better log messages.
+
+2002-11-20  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Doc updates (fixes #1373)
+       * Fix for #1419 (crash in free_ldapservers_list())
+       * Fix for #1375. Dirmngr now asks back with an INQUIRE SENDCERT before
+         querying the LDAP servers for an issuer certificate to validate a CRL
+
+2002-11-12  Werner Koch  <wk@gnupg.org>
+
+       * config.sub, config.guess: Updated from ftp.gnu.org/gnu/config
+       to version 2002-11-08.
+
+2002-11-12  Werner Koch  <wk@gnupg.org>
+
+       * dirmngr.c (main) <load_crl_filename>: Better pass NULL instead
+       of an unitialized Assuan context.  Let's hope that the other
+       functions can cope with this.
+
+2002-10-25  Bernhard Reiter <bernhard@intevation.de>
+
+       * src/ldap.c (get_attr_from_result_ldap()):
+        added value extraction retry for CRLs and Certs without ";binary"
+       * changed version number to reflect cvs status to "0.4.3-cvs"
+
+2002-08-21  Werner Koch  <wk@gnupg.org>
+
+       * dirmngr.c (main): Changed default homedir to .gnupg.
+
+2002-08-07  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Added configure check to examine whether db2 cursor() uses 3 or
+       4 parameters.
+
+2002-07-31  Werner Koch  <wk@gnupg.org>
+
+       * doc/dirmngr.texi: Fixed the structure and added menu entries
+       for the other nodes.
+
+2002-07-30  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Added doc dir and first steps towards manual.
+
+2002-07-29  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Got rid of the default server for CRL lookup. We now use the
+       same list of servers that we use for cert. lookup.
+
+2002-07-29  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * New option --add-servers to allow dirmngr to add LDAP servers
+       found in CRL distribution points to the list of servers it
+       searches. NOTE: The added servers are only active in the currently
+       running dirmngr -- the info isn't written to persistens storage.
+
+2002-07-26  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Default LDAP timeout is 100 seconds now.
+
+       * Use DB2 instead of DB1. Check for libresolv, fixed bug when
+       libldap was found in the default search path.
+
+2002-07-22  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Implemented --load-crl <filename> option. Also available as
+       LOADCRL assuan command when in server mode.
+
+2002-07-22  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Implemented new option --ldaptimeout to specify the number of seconds to
+       wait for an LDAP request before timeout.
+
+       * Added --list-crls option to print the contents of the CRL cache
+       * Added some items to the dbcontents file to make printout nicer
+         and updated it's version number
+
+2002-07-02  Werner Koch  <wk@gnupg.org>
+
+       * crlcache.c (crl_parse_insert): Fixed log_debug format string.
+
+2002-07-02  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * configure.ac: Use DB->get() return value correctly.
+
+2002-06-28  Werner Koch  <wk@gnupg.org>
+
+       * crlcache.c (crl_parse_insert): Keep track of newly allocated
+       ENTRY so that we don't free existing errors after a bad signature.
+
+       * dirmngr.h: Include prototype for start_command_handler.
+
+       * crlfetch.c, crlcache.c, http.c, cert.c, ldap.c: Include
+       config.h.
+
+       * crlcache.c (crl_parse_insert): Fixed format type specifiers for
+       time_t variables in log_debug.
+
+       * error.h: Use log_debug instead of dirmngr_debug.  Changed all
+       callers.
+       * Makefile.am (dirmngr_SOURCES): Removed error.c
+
+       * dirmngr.c (main): Register gcrypt malloc functions with ksba so
+       that we don't run into problems by using the wrong free function.
+       The gcrypt malloc function have the additional benefit of a
+       providing allocation sanity checks when compiled with that
+       feature.
+
+       * crlcache.c (get_issuer_cert): Use xfree instead of ksba_free.
+
+
+2002-06-27  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * ldap.c: Look for both userCertificate and caCertificate
+
+2002-06-26  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * configure.ac: Upped version number to 0.3.1
+
+2002-06-25  Werner Koch  <wk@gnupg.org>
+
+       * server.c (cmd_lookup): Use assuan_write_status which ensures a
+       correct syntax.
+
+2002-06-20  Werner Koch  <wk@gnupg.org>
+
+       * crlcache.c (crl_cache_isvalid): Started with some nicer logging.
+       However, this will need a lot more work.
+       (get_issuer_cert): Ditto.
+
+       * dirmngr.c (main): Changed required libgcrypt version and don't
+       print the prefix when using a logfile.
+
+2002-06-20  Werner Koch  <wk@gnupg.org>
+
+       * tests/Makefile.am (TESTS): Removed test-dirmngr because it
+       is not a proper test program.
+       (EXTRA_DIST): Removed the non-existent test certificate.
+
+2002-05-21  Werner Koch  <wk@gnupg.org>
+
+       * server.c (start_command_handler): Enable assuan debugging.
+
+2002-05-08  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Replaced gdbm check with db1 check
+
+2002-05-08  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Replaced gdbm with db1, updated file format version
+
+2002-03-01  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Added gdbm configure check
+
+2002-01-23  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Return ASSUAN_CRL_Too_Old if the CRL is too old
+
+
+2002-01-17  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       Added commandline options --ldapserver <host> --ldapport <port>
+       --ldapuser <user> --ldappassword <passwd>.
+
+       Cleaned up CRL parsing, signature evaluation a bit, changed
+       datetime format in config file to ISO, added version string to
+       contents format and cache file clean up code in case of mismatch.
+
+2002-01-14  Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+
+       * Use dirmngr_opt.homedir for storing the db. Added Makefile.am to
+       tests, bugfixes.
+
+       * First code.
+         Things that work:
+               Loading/saving database (paths hardcoded)
+               Fetching CRL from hardcoded server, parsing and inserting in database
+               Answer ISVALID xxx.yyy requests
+
+         Things that are missing:
+               Some error-checking/handling
+               Proper autoconf handling of gdbm and OpenLDAP
+               Signature checking downloaded CRLs
+               Answer LOOKUP requests
+               ...
+
+         How to test:
+               cd tests
+               ldapsearch -v -x -h www.trustcenter.de -b '<some-users-DN>' userCertificate -t
+               cp /tmp/<cert-file> testcert.der
+               ./test-dirmngr
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am
new file mode 100644 (file)
index 0000000..0e9a7c7
--- /dev/null
@@ -0,0 +1,100 @@
+# Makefile.am - dirmngr
+# Copyright (C) 2002 Klarälvdalens Datakonsult AB
+# Copyright (C) 2004, 2007, 2010 g10 Code GmbH
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = OAUTHORS ONEWS ChangeLog.1 ChangeLog-2011
+
+bin_PROGRAMS = dirmngr dirmngr-client
+
+if USE_LDAPWRAPPER
+libexec_PROGRAMS = dirmngr_ldap
+endif
+
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
+
+include $(top_srcdir)/am/cmacros.am
+
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) \
+            $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) $(NPTH_CFLAGS)
+
+BUILT_SOURCES = no-libgcrypt.c
+
+CLEANFILES = no-libgcrypt.c
+
+if HAVE_W32_SYSTEM
+ldap_url = ldap-url.h ldap-url.c
+else
+ldap_url =
+endif
+
+if USE_LDAPWRAPPER
+extraldap_src = ldap-wrapper.c
+else
+extraldap_src = ldap-wrapper-ce.c  dirmngr_ldap.c
+endif
+
+noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h misc.h
+
+dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c   \
+       certcache.c certcache.h \
+       cdb.h cdblib.c misc.c dirmngr-err.h  \
+       ocsp.c ocsp.h validate.c validate.h  \
+       ks-action.c ks-action.h ks-engine.h \
+        ks-engine-hkp.c ks-engine-http.c ks-engine-finger.c ks-engine-kdns.c
+
+if USE_LDAP
+dirmngr_SOURCES += ldapserver.h ldapserver.c ldap.c w32-ldap-help.h \
+                   ldap-wrapper.h $(ldap_url) $(extraldap_src)
+ldaplibs = $(LDAPLIBS)
+else
+ldaplibs =
+endif
+
+
+dirmngr_LDADD = $(libcommontlsnpth) $(libcommonpth) \
+        ../gl/libgnu.a $(DNSLIBS) $(LIBASSUAN_LIBS) \
+       $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(NPTH_LIBS) \
+       $(NTBTLS_LIBS) $(LIBGNUTLS_LIBS) $(LIBINTL) $(LIBICONV)
+if !USE_LDAPWRAPPER
+dirmngr_LDADD += $(ldaplibs)
+endif
+dirmngr_LDFLAGS = $(extra_bin_ldflags)
+
+if USE_LDAPWRAPPER
+dirmngr_ldap_SOURCES = dirmngr_ldap.c $(ldap_url)
+dirmngr_ldap_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS)
+dirmngr_ldap_LDFLAGS =
+dirmngr_ldap_LDADD = $(libcommon) no-libgcrypt.o ../gl/libgnu.a \
+                    $(GPG_ERROR_LIBS) $(LDAPLIBS) $(LBER_LIBS) $(LIBINTL) \
+                    $(LIBICONV)
+endif
+
+dirmngr_client_SOURCES = dirmngr-client.c
+dirmngr_client_LDADD = $(libcommon) no-libgcrypt.o \
+                       ../gl/libgnu.a $(LIBASSUAN_LIBS) \
+                      $(GPG_ERROR_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV)
+dirmngr_client_LDFLAGS = $(extra_bin_ldflags)
+
+
+no-libgcrypt.c : $(top_srcdir)/tools/no-libgcrypt.c
+       cat $(top_srcdir)/tools/no-libgcrypt.c > no-libgcrypt.c
+
+
+$(PROGRAMS) : $(libcommon) $(libcommonpth) $(libcommontls) $(libcommontlsnpth)
diff --git a/dirmngr/OAUTHORS b/dirmngr/OAUTHORS
new file mode 100644 (file)
index 0000000..7832449
--- /dev/null
@@ -0,0 +1,38 @@
+The old AUTHORS file from the separate dirmngr package.
+
+ Package: dirmngr
+ Maintainer: Werner Koch <wk@gnupg.org>
+ Bug reports: bug-dirmngr@gnupg.org
+ Security related bug reports: security@gnupg.org
+ License: GPLv2+
+
+
+Steffen Hansen  <steffen@klaralvdalens-datakonsult.se>
+ - Initial code
+
+g10 Code GmbH <code@g10code.com>
+ - All stuff written since October 2003.
+
+Werner Koch     <wk@gnupg.org>, <wk@g10code.com>
+ - Help with initial code.
+
+Free Software Foundation <gnu@gnu.org>
+ - Code taken from GnuPG.
+
+Michael Tokarev <mjt@corpit.ru>
+ - src/cdb.h and src/cdblib.c from the public domain tinycdb 0.73.
+
+
+The actual code is under the GNU GPL, except for src/cdb.h and
+src/cdblib.h which are in the public domain.
+
+
+ Copyright 2003, 2004, 2006, 2007, 2008, 2010 g10 Code GmbH
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This 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/dirmngr/ONEWS b/dirmngr/ONEWS
new file mode 100644 (file)
index 0000000..cb20507
--- /dev/null
@@ -0,0 +1,240 @@
+These are NEWS entries from the old separate dirmngr package
+
+Noteworthy changes in version 1.1.0 (unreleased)
+------------------------------------------------
+
+ * Fixed a resource problem with LDAP CRLs.
+
+ * Fixed a bad EOF detection with HTTP CRLs.
+
+ * Made "dirmngr-client --url --load-crl URL" work.
+
+ * New option --ignore-cert-extension.
+
+ * Make use of libassuan 2.0 which is available as a DSO.
+
+
+Noteworthy changes in version 1.0.3 (2009-06-17)
+------------------------------------------------
+
+ * Client based trust anchors are now supported.
+
+ * Configured certificates with the suffix ".der" are now also used.
+
+ * Libgcrypt 1.4 is now required.
+
+
+Noteworthy changes in version 1.0.2 (2008-07-31)
+------------------------------------------------
+
+ * New option --url for the LOOKUP command and dirmngr-client.
+
+ * The LOOKUP command does now also consults the local cache.  New
+   option --cache-only for it and --local for dirmngr-client.
+
+ * Port to Windows completed.
+
+ * Improved certificate chain construction.
+
+ * Support loading of PEM encoded CRLs via HTTP.
+
+
+Noteworthy changes in version 1.0.1 (2007-08-16)
+------------------------------------------------
+
+ * The option --ocsp-signer may now take a filename to allow several
+   certificates to be valid signers for the default responder.
+
+ * New option --ocsp-max-period and improved the OCSP time checks.
+
+ * New option --force-default-signer for dirmngr-client.
+
+ * Ported to Windows.
+
+
+Noteworthy changes in version 1.0.0 (2006-11-29)
+------------------------------------------------
+
+ * Bumbed the version number.
+
+ * Removed included gettext.  We now require the system to provide a
+   suitable installation.
+
+
+Noteworthy changes in version 0.9.7 (2006-11-17)
+------------------------------------------------
+
+ * Internal cleanups.
+
+ * Fixed updating of DIR.txt.  Add additional diagnostics.
+
+ * Updated gettext package.
+
+
+Noteworthy changes in version 0.9.6 (2006-09-04)
+------------------------------------------------
+
+ * A couple of bug fixes for OCSP.
+
+ * OCSP does now make use of the responder ID and optionally included
+   certificates in the response to locate certificates.
+
+ * No more lost file descriptors when loading CRLs via HTTP.
+
+ * HTTP redirection for CRL and OCSP has been implemented.
+
+ * Man pages are now build and installed from the texinfo source.
+
+
+Noteworthy changes in version 0.9.5 (2006-06-27)
+------------------------------------------------
+
+ * Fixed a problems with the CRL caching and CRL certificate
+   validation.
+
+ * Improved diagnostics.
+
+
+Noteworthy changes in version 0.9.4 (2006-05-16)
+------------------------------------------------
+
+ * Try all names of each crlDP.
+
+ * Don't shutdown the socket after sending the HTTP request.
+
+
+Noteworthy changes in version 0.9.3 (2005-10-26)
+------------------------------------------------
+
+ * Minor bug fixes.
+
+
+Noteworthy changes in version 0.9.2 (2005-04-21)
+------------------------------------------------
+
+ * Make use of authorityKeyidentifier.keyIdentifier.
+
+ * Fixed a possible hang on exit.
+
+
+Noteworthy changes in version 0.9.1 (2005-02-08)
+------------------------------------------------
+
+ * New option --pem for dirmngr-client to allow requesting service
+   using a PEM encoded certificate.
+
+ * New option --squid-mode to allow using dirmngr-client directly as a
+   Squid helper.
+
+ * Bug fixes.
+
+
+Noteworthy changes in version 0.9.0 (2004-12-17)
+------------------------------------------------
+
+ * New option --daemon to start dirmngr as a system daemon.  This
+   switches to the use of different directories and also does
+   CRL signing certificate validation on its own.
+
+ * New tool dirmngr-client.
+
+ * New options: --ldap-wrapper-program, --http-wrapper-program,
+   --disable-ldap, --disable-http, --honor-http-proxy, --http-proxy,
+   --ldap-proxy, --only-ldap-proxy, --ignore-ldap-dp and
+   --ignore-http-dp.
+
+ * Uses an external ldap wrapper to cope with timeouts and general
+   LDAP problems.
+
+ * SIGHUP may be used to reread the configuration and to flush the
+   certificate cache.
+
+ * An authorithyKeyIdentifier in a CRL is now handled correctly.
+
+
+Noteworthy changes in version 0.5.6 (2004-09-28)
+------------------------------------------------
+
+ * LDAP fix.
+
+ * Logging fixes.
+
+ * Updated some configuration files.
+
+
+Noteworthy changes in version 0.5.5 (2004-05-13)
+------------------------------------------------
+
+ * Fixed the growing-dir.txt bug.
+
+ * Better LDAP error logging.
+
+
+Noteworthy changes in version 0.5.4 (2004-04-29)
+------------------------------------------------
+
+ * New commands --ocsp-responder and --ocsp-signer to define a default
+   OCSP reponder if a certificate does not contain an assigned OCSP
+   responder.
+
+
+Noteworthy changes in version 0.5.3 (2004-04-06)
+------------------------------------------------
+
+ * Basic OCSP support.
+
+
+Noteworthy changes in version 0.5.2 (2004-03-06)
+------------------------------------------------
+
+ * New Assuan command LISTCRLS.
+
+ * A couple of minor bug fixes.
+
+
+Noteworthy changes in version 0.5.1 (2003-12-23)
+------------------------------------------------
+
+* New options --faked-system-time and --force.
+
+* Changed the name of the cache directory to $HOMEDIR/dirmngr-cache.d
+  and renamed the dbcontents file.  You may delete the now obsolete
+  cache/ directory and the dbcontents file.
+
+* Dropped DB2 or DB4 use.  There is no need for it because a constant
+  database fits our needs far better.
+
+* Experimental support for retrieving CRLs via http.
+
+* 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.
+
+
+Noteworthy changes in version 0.5.0 (2003-11-17)
+------------------------------------------------
+
+* Revamped the entire thing.
+
+* Does now require Libgcrypt 1.1.90 or higher, as well as the latest
+  libksba and libassuan.
+
+* Fixed a bug in the assuan inquire processing.
+
+
+Noteworthy changes as of 2002-08-21
+------------------------------------
+
+* The default home directory is now .gnupg
+
+
+ Copyright 2003, 2004, 2005 g10 Code GmbH
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This 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/dirmngr/cdb.h b/dirmngr/cdb.h
new file mode 100644 (file)
index 0000000..0c0d270
--- /dev/null
@@ -0,0 +1,94 @@
+/* $Id: cdb.h 106 2003-12-12 17:36:49Z werner $
+ * public cdb include file
+ *
+ * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
+ * Public domain.
+ *
+ * Taken from tinycdb-0.73. By Werner Koch <wk@gnupg.org> 2003-12-12.
+ */
+
+#ifndef TINYCDB_VERSION
+#define TINYCDB_VERSION 0.73
+
+typedef unsigned int cdbi_t; /*XXX should be at least 32 bits long */
+
+/* common routines */
+cdbi_t cdb_hash(const void *buf, cdbi_t len);
+cdbi_t cdb_unpack(const unsigned char buf[4]);
+void cdb_pack(cdbi_t num, unsigned char buf[4]);
+
+struct cdb {
+  int cdb_fd;                  /* file descriptor */
+  /* private members */
+#ifdef HAVE_W32_SYSTEM
+  void *cdb_mapping;            /* Mapping handle.  */
+#endif
+  cdbi_t cdb_fsize;            /* datafile size */
+  const unsigned char *cdb_mem; /* mmap'ed file memory */
+  cdbi_t cdb_vpos, cdb_vlen;   /* found data */
+  cdbi_t cdb_kpos, cdb_klen;    /* found key (only set if cdb_findinit
+                                   was called with KEY set to NULL). */
+};
+
+#define cdb_datapos(c) ((c)->cdb_vpos)
+#define cdb_datalen(c) ((c)->cdb_vlen)
+#define cdb_keypos(c) ((c)->cdb_kpos)
+#define cdb_keylen(c) ((c)->cdb_klen)
+#define cdb_fileno(c) ((c)->cdb_fd)
+
+int cdb_init(struct cdb *cdbp, int fd);
+void cdb_free(struct cdb *cdbp);
+
+int cdb_read(const struct cdb *cdbp,
+            void *buf, unsigned len, cdbi_t pos);
+int cdb_find(struct cdb *cdbp, const void *key, unsigned klen);
+
+struct cdb_find {
+  struct cdb *cdb_cdbp;
+  cdbi_t cdb_hval;
+  const unsigned char *cdb_htp, *cdb_htab, *cdb_htend;
+  cdbi_t cdb_httodo;
+  const void *cdb_key;
+  cdbi_t cdb_klen;
+};
+
+int cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp,
+                const void *key, cdbi_t klen);
+int cdb_findnext(struct cdb_find *cdbfp);
+
+/* old simple interface */
+/* open file using standard routine, then: */
+int cdb_seek(int fd, const void *key, unsigned klen, cdbi_t *dlenp);
+int cdb_bread(int fd, void *buf, int len);
+
+/* cdb_make */
+
+struct cdb_make {
+  int cdb_fd;                  /* file descriptor */
+  /* private */
+  cdbi_t cdb_dpos;             /* data position so far */
+  cdbi_t cdb_rcnt;             /* record count so far */
+  char cdb_buf[4096];          /* write buffer */
+  char *cdb_bpos;              /* current buf position */
+  struct cdb_rl *cdb_rec[256]; /* list of arrays of record infos */
+};
+
+
+
+int cdb_make_start(struct cdb_make *cdbmp, int fd);
+int cdb_make_add(struct cdb_make *cdbmp,
+                const void *key, cdbi_t klen,
+                const void *val, cdbi_t vlen);
+int cdb_make_exists(struct cdb_make *cdbmp,
+                   const void *key, cdbi_t klen);
+int cdb_make_put(struct cdb_make *cdbmp,
+                const void *key, cdbi_t klen,
+                const void *val, cdbi_t vlen,
+                int flag);
+#define CDB_PUT_ADD    0       /* add unconditionnaly, like cdb_make_add() */
+#define CDB_PUT_REPLACE        1       /* replace: do not place to index OLD record */
+#define CDB_PUT_INSERT 2       /* add only if not already exists */
+#define CDB_PUT_WARN   3       /* add unconditionally but ret. 1 if exists */
+int cdb_make_finish(struct cdb_make *cdbmp);
+
+#endif /* include guard */
diff --git a/dirmngr/cdblib.c b/dirmngr/cdblib.c
new file mode 100644 (file)
index 0000000..9636b6c
--- /dev/null
@@ -0,0 +1,929 @@
+/* cdblib.c - all CDB library functions.
+ *
+ * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
+ * Public domain.
+ *
+ * Taken from tinycdb-0.73 and merged into one file for easier
+ * inclusion into Dirmngr.  By Werner Koch <wk@gnupg.org> 2003-12-12.
+ */
+
+/* A cdb database is a single file used to map 'keys' to 'values',
+   having records of (key,value) pairs.  File consists of 3 parts: toc
+   (table of contents), data and index (hash tables).
+
+   Toc has fixed length of 2048 bytes, containing 256 pointers to hash
+   tables inside index sections.  Every pointer consists of position
+   of a hash table in bytes from the beginning of a file, and a size
+   of a hash table in entries, both are 4-bytes (32 bits) unsigned
+   integers in little-endian form.  Hash table length may have zero
+   length, meaning that corresponding hash table is empty.
+
+   Right after toc section, data section follows without any
+   alingment.  It consists of series of records, each is a key length,
+   value (data) length, key and value.  Again, key and value length
+   are 4-byte unsigned integers.  Each next record follows previous
+   without any special alignment.
+
+   After data section, index (hash tables) section follows.  It should
+   be looked to in conjunction with toc section, where each of max 256
+   hash tables are defined.  Index section consists of series of hash
+   tables, with starting position and length defined in toc section.
+   Every hash table is a sequence of records each holds two numbers:
+   key's hash value and record position inside data section (bytes
+   from the beginning of a file to first byte of key length starting
+   data record).  If record position is zero, then this is an empty
+   hash table slot, pointed to nowhere.
+
+   CDB hash function is
+     hv = ((hv << 5) + hv) ^ c
+   for every single c byte of a key, starting with hv = 5381.
+
+   Toc section indexed by (hv % 256), i.e. hash value modulo 256
+   (number of entries in toc section).
+
+   In order to find a record, one should: first, compute the hash
+   value (hv) of a key.  Second, look to hash table number hv modulo
+   256.  If it is empty, then there is no such key exists.  If it is
+   not empty, then third, loop by slots inside that hash table,
+   starting from slot with number hv divided by 256 modulo length of
+   that table, or ((hv / 256) % htlen), searching for this hv in hash
+   table.  Stop search on empty slot (if record position is zero) or
+   when all slots was probed (note cyclic search, jumping from end to
+   beginning of a table).  When hash value in question is found in
+   hash table, look to key of corresponding record, comparing it with
+   key in question.  If them of the same length and equals to each
+   other, then record is found, overwise, repeat with next hash table
+   slot.  Note that there may be several records with the same key.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+#  define MAP_FAILED ((void*)-1)
+# endif
+#endif
+#include <sys/stat.h>
+
+#include "dirmngr-err.h"
+#include "cdb.h"
+
+#ifndef EPROTO
+# define EPROTO EINVAL
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif
+
+
+struct cdb_rec {
+  cdbi_t hval;
+  cdbi_t rpos;
+};
+
+struct cdb_rl {
+  struct cdb_rl *next;
+  cdbi_t cnt;
+  struct cdb_rec rec[254];
+};
+
+static int make_find(struct cdb_make *cdbmp,
+                  const void *key, cdbi_t klen, cdbi_t hval,
+                  struct cdb_rl **rlp);
+static int make_write(struct cdb_make *cdbmp,
+                   const char *ptr, cdbi_t len);
+
+
+
+/* Initializes structure given by CDBP pointer and associates it with
+   the open file descriptor FD.  Allocate memory for the structure
+   itself if needed and file open operation should be done by
+   application.  File FD should be opened at least read-only, and
+   should be seekable.  Routine returns 0 on success or negative value
+   on error. */
+int
+cdb_init(struct cdb *cdbp, int fd)
+{
+  struct stat st;
+  unsigned char *mem;
+#ifdef _WIN32
+  HANDLE hFile, hMapping;
+#else
+  unsigned int fsize;
+#endif
+
+  /* get file size */
+  if (fstat(fd, &st) < 0)
+    return -1;
+  /* trivial sanity check: at least toc should be here */
+  if (st.st_size < 2048) {
+    gpg_err_set_errno (EPROTO);
+    return -1;
+  }
+  /* memory-map file */
+#ifdef _WIN32
+# ifdef __MINGW32CE__
+  hFile = fd;
+# else
+  hFile = (HANDLE) _get_osfhandle(fd);
+# endif
+  if (hFile == (HANDLE) -1)
+    return -1;
+  hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+  if (!hMapping)
+    return -1;
+  mem = (unsigned char *)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
+  if (!mem)
+    return -1;
+  cdbp->cdb_mapping = hMapping;
+#else /*!_WIN32*/
+  fsize = (unsigned int)(st.st_size & 0xffffffffu);
+  mem = (unsigned char*)mmap(NULL, fsize, PROT_READ, MAP_SHARED, fd, 0);
+  if (mem == MAP_FAILED)
+    return -1;
+#endif /*!_WIN32*/
+
+  cdbp->cdb_fd = fd;
+  cdbp->cdb_fsize = st.st_size;
+  cdbp->cdb_mem = mem;
+
+#if 0
+  /* XXX don't know well about madvise syscall -- is it legal
+     to set different options for parts of one mmap() region?
+     There is also posix_madvise() exist, with POSIX_MADV_RANDOM etc...
+  */
+#ifdef MADV_RANDOM
+  /* set madvise() parameters. Ignore errors for now if system
+     doesn't support it */
+  madvise(mem, 2048, MADV_WILLNEED);
+  madvise(mem + 2048, cdbp->cdb_fsize - 2048, MADV_RANDOM);
+#endif
+#endif
+
+  cdbp->cdb_vpos = cdbp->cdb_vlen = 0;
+
+  return 0;
+}
+
+
+/* Frees the internal resources held by structure.  Note that this
+   routine does not close the file. */
+void
+cdb_free(struct cdb *cdbp)
+{
+  if (cdbp->cdb_mem) {
+#ifdef _WIN32
+    UnmapViewOfFile ((void*) cdbp->cdb_mem);
+    CloseHandle (cdbp->cdb_mapping);
+    cdbp->cdb_mapping = NULL;
+#else
+    munmap((void*)cdbp->cdb_mem, cdbp->cdb_fsize);
+#endif /* _WIN32 */
+    cdbp->cdb_mem = NULL;
+  }
+  cdbp->cdb_fsize = 0;
+}
+
+
+/* Read data from cdb file, starting at position pos of length len,
+   placing result to buf.  This routine may be used to get actual
+   value found by cdb_find() or other routines that returns position
+   and length of a data.  Returns 0 on success or negative value on
+   error. */
+int
+cdb_read(const struct cdb *cdbp, void *buf, unsigned len, cdbi_t pos)
+{
+  if (pos > cdbp->cdb_fsize || cdbp->cdb_fsize - pos < len) {
+    gpg_err_set_errno (EPROTO);
+    return -1;
+  }
+  memcpy(buf, cdbp->cdb_mem + pos, len);
+  return 0;
+}
+
+
+/* Attempts to find a key given by (key,klen) parameters.  If key
+   exists in database, routine returns 1 and places position and
+   length of value associated with this key to internal fields inside
+   cdbp structure, to be accessible by cdb_datapos() and
+   cdb_datalen().  If key is not in database, routines returns 0.  On
+   error, negative value is returned.  Note that using cdb_find() it
+   is possible to lookup only first record with a given key. */
+int
+cdb_find(struct cdb *cdbp, const void *key, cdbi_t klen)
+{
+  const unsigned char *htp;    /* hash table pointer */
+  const unsigned char *htab;   /* hash table */
+  const unsigned char *htend;  /* end of hash table */
+  cdbi_t httodo;               /* ht bytes left to look */
+  cdbi_t pos, n;
+
+  cdbi_t hval;
+
+  if (klen > cdbp->cdb_fsize)  /* if key size is larger than file */
+    return 0;
+
+  hval = cdb_hash(key, klen);
+
+  /* find (pos,n) hash table to use */
+  /* first 2048 bytes (toc) are always available */
+  /* (hval % 256) * 8 */
+  htp = cdbp->cdb_mem + ((hval << 3) & 2047); /* index in toc (256x8) */
+  n = cdb_unpack(htp + 4);     /* table size */
+  if (!n)                      /* empty table */
+    return 0;                  /* not found */
+  httodo = n << 3;             /* bytes of htab to lookup */
+  pos = cdb_unpack(htp);       /* htab position */
+  if (n > (cdbp->cdb_fsize >> 3) /* overflow of httodo ? */
+      || pos > cdbp->cdb_fsize /* htab start within file ? */
+      || httodo > cdbp->cdb_fsize - pos) /* entrie htab within file ? */
+  {
+    gpg_err_set_errno (EPROTO);
+    return -1;
+  }
+
+  htab = cdbp->cdb_mem + pos;  /* htab pointer */
+  htend = htab + httodo;       /* after end of htab */
+  /* htab starting position: rest of hval modulo htsize, 8bytes per elt */
+  htp = htab + (((hval >> 8) % n) << 3);
+
+  for(;;) {
+    pos = cdb_unpack(htp + 4); /* record position */
+    if (!pos)
+      return 0;
+    if (cdb_unpack(htp) == hval) {
+      if (pos > cdbp->cdb_fsize - 8) { /* key+val lengths */
+       gpg_err_set_errno (EPROTO);
+       return -1;
+      }
+      if (cdb_unpack(cdbp->cdb_mem + pos) == klen) {
+       if (cdbp->cdb_fsize - klen < pos + 8) {
+         gpg_err_set_errno (EPROTO);
+         return -1;
+       }
+       if (memcmp(key, cdbp->cdb_mem + pos + 8, klen) == 0) {
+         n = cdb_unpack(cdbp->cdb_mem + pos + 4);
+         pos += 8 + klen;
+         if (cdbp->cdb_fsize < n || cdbp->cdb_fsize - n < pos) {
+           gpg_err_set_errno (EPROTO);
+           return -1;
+         }
+         cdbp->cdb_vpos = pos;
+         cdbp->cdb_vlen = n;
+         return 1;
+       }
+      }
+    }
+    httodo -= 8;
+    if (!httodo)
+      return 0;
+    if ((htp += 8) >= htend)
+      htp = htab;
+  }
+
+}
+
+
+
+/* Sequential-find routines that used separate structure.  It is
+   possible to have many than one record with the same key in a
+   database, and these routines allows to enumerate all them.
+   cdb_findinit() initializes search structure pointed to by cdbfp.
+   It will return negative value on error or 0 on success.  cdb_find­
+   next() attempts to find next matching key, setting value position
+   and length in cdbfp structure.  It will return positive value if
+   given key was found, 0 if there is no more such key(s), or negative
+   value on error.  To access value position and length after
+   successeful call to cdb_findnext() (when it returned positive
+   result), use cdb_datapos() and cdb_datalen() macros with cdbp
+   pointer.  It is error to use cdb_findnext() after it returned 0 or
+   error condition.  These routines is a bit slower than
+   cdb_find().
+
+   Setting KEY to NULL will start a sequential search through the
+   entire DB.
+*/
+int
+cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp,
+             const void *key, cdbi_t klen)
+{
+  cdbi_t n, pos;
+
+  cdbfp->cdb_cdbp = cdbp;
+  cdbfp->cdb_key  = key;
+  cdbfp->cdb_klen = klen;
+  cdbfp->cdb_hval = key? cdb_hash(key, klen) : 0;
+
+  if (key)
+    {
+      cdbfp->cdb_htp = cdbp->cdb_mem + ((cdbfp->cdb_hval << 3) & 2047);
+      n = cdb_unpack(cdbfp->cdb_htp + 4);
+      cdbfp->cdb_httodo = n << 3; /* Set to size of hash table. */
+      if (!n)
+        return 0; /* The hash table is empry. */
+      pos = cdb_unpack(cdbfp->cdb_htp);
+      if (n > (cdbp->cdb_fsize >> 3)
+          || pos > cdbp->cdb_fsize
+          || cdbfp->cdb_httodo > cdbp->cdb_fsize - pos)
+        {
+          gpg_err_set_errno (EPROTO);
+          return -1;
+        }
+
+      cdbfp->cdb_htab = cdbp->cdb_mem + pos;
+      cdbfp->cdb_htend = cdbfp->cdb_htab + cdbfp->cdb_httodo;
+      cdbfp->cdb_htp = cdbfp->cdb_htab + (((cdbfp->cdb_hval >> 8) % n) << 3);
+    }
+  else /* Walk over all entries. */
+    {
+      cdbfp->cdb_hval = 0;
+      /* Force stepping in findnext. */
+      cdbfp->cdb_htp = cdbfp->cdb_htend = cdbp->cdb_mem;
+    }
+  return 0;
+}
+
+
+/* See cdb_findinit. */
+int
+cdb_findnext(struct cdb_find *cdbfp)
+{
+  cdbi_t pos, n;
+  struct cdb *cdbp = cdbfp->cdb_cdbp;
+
+  if (cdbfp->cdb_key)
+    {
+      while(cdbfp->cdb_httodo) {
+        pos = cdb_unpack(cdbfp->cdb_htp + 4);
+        if (!pos)
+          return 0;
+        n = cdb_unpack(cdbfp->cdb_htp) == cdbfp->cdb_hval;
+        if ((cdbfp->cdb_htp += 8) >= cdbfp->cdb_htend)
+          cdbfp->cdb_htp = cdbfp->cdb_htab;
+        cdbfp->cdb_httodo -= 8;
+        if (n) {
+          if (pos > cdbp->cdb_fsize - 8) {
+            gpg_err_set_errno (EPROTO);
+            return -1;
+          }
+          if (cdb_unpack(cdbp->cdb_mem + pos) == cdbfp->cdb_klen) {
+            if (cdbp->cdb_fsize - cdbfp->cdb_klen < pos + 8) {
+              gpg_err_set_errno (EPROTO);
+              return -1;
+            }
+            if (memcmp(cdbfp->cdb_key,
+                       cdbp->cdb_mem + pos + 8, cdbfp->cdb_klen) == 0) {
+              n = cdb_unpack(cdbp->cdb_mem + pos + 4);
+              pos += 8 + cdbfp->cdb_klen;
+              if (cdbp->cdb_fsize < n || cdbp->cdb_fsize - n < pos) {
+                gpg_err_set_errno (EPROTO);
+                return -1;
+              }
+              cdbp->cdb_vpos = pos;
+              cdbp->cdb_vlen = n;
+              return 1;
+            }
+          }
+        }
+      }
+    }
+  else /* Walk over all entries. */
+    {
+      do
+        {
+          while (cdbfp->cdb_htp >= cdbfp->cdb_htend)
+            {
+              if (cdbfp->cdb_hval > 255)
+                return 0; /* No more items. */
+
+              cdbfp->cdb_htp = cdbp->cdb_mem + cdbfp->cdb_hval * 8;
+              cdbfp->cdb_hval++; /* Advance for next round. */
+              pos = cdb_unpack (cdbfp->cdb_htp);     /* Offset of table. */
+              n   = cdb_unpack (cdbfp->cdb_htp + 4); /* Number of entries. */
+              cdbfp->cdb_httodo = n * 8;             /* Size of table. */
+              if (n > (cdbp->cdb_fsize / 8)
+                  || pos > cdbp->cdb_fsize
+                  || cdbfp->cdb_httodo > cdbp->cdb_fsize - pos)
+                {
+                  gpg_err_set_errno (EPROTO);
+                  return -1;
+                }
+
+              cdbfp->cdb_htab  = cdbp->cdb_mem + pos;
+              cdbfp->cdb_htend = cdbfp->cdb_htab + cdbfp->cdb_httodo;
+              cdbfp->cdb_htp   = cdbfp->cdb_htab;
+            }
+
+          pos = cdb_unpack (cdbfp->cdb_htp + 4); /* Offset of record. */
+          cdbfp->cdb_htp += 8;
+        }
+      while (!pos);
+      if (pos > cdbp->cdb_fsize - 8)
+        {
+          gpg_err_set_errno (EPROTO);
+          return -1;
+        }
+
+      cdbp->cdb_kpos = pos + 8;
+      cdbp->cdb_klen = cdb_unpack(cdbp->cdb_mem + pos);
+      cdbp->cdb_vpos = pos + 8 + cdbp->cdb_klen;
+      cdbp->cdb_vlen = cdb_unpack(cdbp->cdb_mem + pos + 4);
+      n = 8 + cdbp->cdb_klen + cdbp->cdb_vlen;
+      if ( pos > cdbp->cdb_fsize || pos > cdbp->cdb_fsize - n)
+        {
+          gpg_err_set_errno (EPROTO);
+          return -1;
+        }
+      return 1; /* Found. */
+    }
+  return 0;
+}
+
+/* Read a chunk from file, ignoring interrupts (EINTR) */
+int
+cdb_bread(int fd, void *buf, int len)
+{
+  int l;
+  while(len > 0) {
+    do l = read(fd, buf, len);
+    while(l < 0 && errno == EINTR);
+    if (l <= 0) {
+      if (!l)
+        gpg_err_set_errno (EIO);
+      return -1;
+    }
+    buf = (char*)buf + l;
+    len -= l;
+  }
+  return 0;
+}
+
+/* Find a given key in cdb file, seek a file pointer to it's value and
+   place data length to *dlenp. */
+int
+cdb_seek(int fd, const void *key, unsigned klen, cdbi_t *dlenp)
+{
+  cdbi_t htstart;              /* hash table start position */
+  cdbi_t htsize;               /* number of elements in a hash table */
+  cdbi_t httodo;               /* hash table elements left to look */
+  cdbi_t hti;                  /* hash table index */
+  cdbi_t pos;                  /* position in a file */
+  cdbi_t hval;                 /* key's hash value */
+  unsigned char rbuf[64];      /* read buffer */
+  int needseek = 1;            /* if we should seek to a hash slot */
+
+  hval = cdb_hash(key, klen);
+  pos = (hval & 0xff) << 3; /* position in TOC */
+  /* read the hash table parameters */
+  if (lseek(fd, pos, SEEK_SET) < 0 || cdb_bread(fd, rbuf, 8) < 0)
+    return -1;
+  if ((htsize = cdb_unpack(rbuf + 4)) == 0)
+    return 0;
+  hti = (hval >> 8) % htsize;  /* start position in hash table */
+  httodo = htsize;
+  htstart = cdb_unpack(rbuf);
+
+  for(;;) {
+    if (needseek && lseek(fd, htstart + (hti << 3), SEEK_SET) < 0)
+      return -1;
+    if (cdb_bread(fd, rbuf, 8) < 0)
+      return -1;
+    if ((pos = cdb_unpack(rbuf + 4)) == 0) /* not found */
+      return 0;
+
+    if (cdb_unpack(rbuf) != hval) /* hash value not matched */
+      needseek = 0;
+    else { /* hash value matched */
+      if (lseek(fd, pos, SEEK_SET) < 0 || cdb_bread(fd, rbuf, 8) < 0)
+       return -1;
+      if (cdb_unpack(rbuf) == klen) { /* key length matches */
+       /* read the key from file and compare with wanted */
+       cdbi_t l = klen, c;
+       const char *k = (const char*)key;
+       if (*dlenp)
+         *dlenp = cdb_unpack(rbuf + 4); /* save value length */
+       for(;;) {
+         if (!l) /* the whole key read and matches, return */
+           return 1;
+         c = l > sizeof(rbuf) ? sizeof(rbuf) : l;
+         if (cdb_bread(fd, rbuf, c) < 0)
+           return -1;
+         if (memcmp(rbuf, k, c) != 0) /* no, it differs, stop here */
+           break;
+         k += c; l -= c;
+       }
+      }
+      needseek = 1; /* we're looked to other place, should seek back */
+    }
+    if (!--httodo)
+      return 0;
+    if (++hti == htsize) {
+      hti = htstart;
+      needseek = 1;
+    }
+  }
+}
+
+cdbi_t
+cdb_unpack(const unsigned char buf[4])
+{
+  cdbi_t n = buf[3];
+  n <<= 8; n |= buf[2];
+  n <<= 8; n |= buf[1];
+  n <<= 8; n |= buf[0];
+  return n;
+}
+
+/* Add record with key (KEY,KLEN) and value (VAL,VLEN) to a database.
+   Returns 0 on success or negative value on error.  Note that this
+   routine does not checks if given key already exists, but cdb_find()
+   will not see second record with the same key.  It is not possible
+   to continue building a database if cdb_make_add() returned an error
+   indicator. */
+int
+cdb_make_add(struct cdb_make *cdbmp,
+            const void *key, cdbi_t klen,
+            const void *val, cdbi_t vlen)
+{
+  unsigned char rlen[8];
+  cdbi_t hval;
+  struct cdb_rl *rl;
+  if (klen > 0xffffffff - (cdbmp->cdb_dpos + 8) ||
+      vlen > 0xffffffff - (cdbmp->cdb_dpos + klen + 8)) {
+    gpg_err_set_errno (ENOMEM);
+    return -1;
+  }
+  hval = cdb_hash(key, klen);
+  rl = cdbmp->cdb_rec[hval&255];
+  if (!rl || rl->cnt >= sizeof(rl->rec)/sizeof(rl->rec[0])) {
+    rl = (struct cdb_rl*)malloc(sizeof(struct cdb_rl));
+    if (!rl) {
+      gpg_err_set_errno (ENOMEM);
+      return -1;
+    }
+    rl->cnt = 0;
+    rl->next = cdbmp->cdb_rec[hval&255];
+    cdbmp->cdb_rec[hval&255] = rl;
+  }
+  rl->rec[rl->cnt].hval = hval;
+  rl->rec[rl->cnt].rpos = cdbmp->cdb_dpos;
+  ++rl->cnt;
+  ++cdbmp->cdb_rcnt;
+  cdb_pack(klen, rlen);
+  cdb_pack(vlen, rlen + 4);
+  if (make_write(cdbmp, rlen, 8) < 0 ||
+      make_write(cdbmp, key, klen) < 0 ||
+      make_write(cdbmp, val, vlen) < 0)
+    return -1;
+  return 0;
+}
+
+int
+cdb_make_put(struct cdb_make *cdbmp,
+            const void *key, cdbi_t klen,
+            const void *val, cdbi_t vlen,
+            int flags)
+{
+  unsigned char rlen[8];
+  cdbi_t hval = cdb_hash(key, klen);
+  struct cdb_rl *rl;
+  int c, r;
+
+  switch(flags) {
+    case CDB_PUT_REPLACE:
+    case CDB_PUT_INSERT:
+    case CDB_PUT_WARN:
+      c = make_find(cdbmp, key, klen, hval, &rl);
+      if (c < 0)
+       return -1;
+      if (c) {
+       if (flags == CDB_PUT_INSERT) {
+         gpg_err_set_errno (EEXIST);
+         return 1;
+       }
+       else if (flags == CDB_PUT_REPLACE) {
+         --c;
+         r = 1;
+         break;
+       }
+       else
+         r = 1;
+      }
+      /* fall */
+
+    case CDB_PUT_ADD:
+      rl = cdbmp->cdb_rec[hval&255];
+      if (!rl || rl->cnt >= sizeof(rl->rec)/sizeof(rl->rec[0])) {
+       rl = (struct cdb_rl*)malloc(sizeof(struct cdb_rl));
+       if (!rl) {
+         gpg_err_set_errno (ENOMEM);
+         return -1;
+       }
+       rl->cnt = 0;
+       rl->next = cdbmp->cdb_rec[hval&255];
+       cdbmp->cdb_rec[hval&255] = rl;
+      }
+      c = rl->cnt;
+      r = 0;
+      break;
+
+    default:
+      gpg_err_set_errno (EINVAL);
+      return -1;
+  }
+
+  if (klen > 0xffffffff - (cdbmp->cdb_dpos + 8) ||
+      vlen > 0xffffffff - (cdbmp->cdb_dpos + klen + 8)) {
+    gpg_err_set_errno (ENOMEM);
+    return -1;
+  }
+  rl->rec[c].hval = hval;
+  rl->rec[c].rpos = cdbmp->cdb_dpos;
+  if (c == rl->cnt) {
+    ++rl->cnt;
+    ++cdbmp->cdb_rcnt;
+  }
+  cdb_pack(klen, rlen);
+  cdb_pack(vlen, rlen + 4);
+  if (make_write(cdbmp, rlen, 8) < 0 ||
+      make_write(cdbmp, key, klen) < 0 ||
+      make_write(cdbmp, val, vlen) < 0)
+    return -1;
+  return r;
+}
+
+
+static int
+match(int fd, cdbi_t pos, const char *key, cdbi_t klen)
+{
+  unsigned char buf[64]; /*XXX cdb_buf may be used here instead */
+  if (lseek(fd, pos, SEEK_SET) < 0 || read(fd, buf, 8) != 8)
+    return -1;
+  if (cdb_unpack(buf) != klen)
+    return 0;
+
+  while(klen > sizeof(buf)) {
+    if (read(fd, buf, sizeof(buf)) != sizeof(buf))
+      return -1;
+    if (memcmp(buf, key, sizeof(buf)) != 0)
+      return 0;
+    key += sizeof(buf);
+    klen -= sizeof(buf);
+  }
+  if (klen) {
+    if (read(fd, buf, klen) != klen)
+      return -1;
+    if (memcmp(buf, key, klen) != 0)
+      return 0;
+  }
+  return 1;
+}
+
+
+static int
+make_find (struct cdb_make *cdbmp,
+           const void *key, cdbi_t klen, cdbi_t hval,
+           struct cdb_rl **rlp)
+{
+  struct cdb_rl *rl = cdbmp->cdb_rec[hval&255];
+  int r, i;
+  int seeked = 0;
+  while(rl) {
+    for(i = rl->cnt - 1; i >= 0; --i) { /* search backward */
+      if (rl->rec[i].hval != hval)
+       continue;
+      /*XXX this explicit flush may be unnecessary having
+       * smarter match() that looks to cdb_buf too, but
+       * most of a time here spent in finding hash values
+       * (above), not keys */
+      if (cdbmp->cdb_bpos != cdbmp->cdb_buf) {
+        if (write(cdbmp->cdb_fd, cdbmp->cdb_buf,
+                 cdbmp->cdb_bpos - cdbmp->cdb_buf) < 0)
+          return -1;
+        cdbmp->cdb_bpos = cdbmp->cdb_buf;
+      }
+      seeked = 1;
+      r = match(cdbmp->cdb_fd, rl->rec[i].rpos, key, klen);
+      if (!r)
+       continue;
+      if (r < 0)
+       return -1;
+      if (lseek(cdbmp->cdb_fd, cdbmp->cdb_dpos, SEEK_SET) < 0)
+        return -1;
+      if (rlp)
+       *rlp = rl;
+      return i + 1;
+    }
+    rl = rl->next;
+  }
+  if (seeked && lseek(cdbmp->cdb_fd, cdbmp->cdb_dpos, SEEK_SET) < 0)
+    return -1;
+  return 0;
+}
+
+int
+cdb_make_exists(struct cdb_make *cdbmp,
+                const void *key, cdbi_t klen)
+{
+  return make_find(cdbmp, key, klen, cdb_hash(key, klen), NULL);
+}
+
+
+void
+cdb_pack(cdbi_t num, unsigned char buf[4])
+{
+  buf[0] = num & 255; num >>= 8;
+  buf[1] = num & 255; num >>= 8;
+  buf[2] = num & 255;
+  buf[3] = num >> 8;
+}
+
+
+/* Initializes structure to create a database.  File FD should be
+   opened read-write and should be seekable.  Returns 0 on success or
+   negative value on error. */
+int
+cdb_make_start(struct cdb_make *cdbmp, int fd)
+{
+  memset (cdbmp, 0, sizeof *cdbmp);
+  cdbmp->cdb_fd = fd;
+  cdbmp->cdb_dpos = 2048;
+  cdbmp->cdb_bpos = cdbmp->cdb_buf + 2048;
+  return 0;
+}
+
+
+static int
+ewrite(int fd, const char *buf, int len)
+{
+  while(len) {
+    int l = write(fd, buf, len);
+    if (l < 0 && errno != EINTR)
+      return -1;
+    if (l > 0)
+      {
+        len -= l;
+        buf += l;
+      }
+  }
+  return 0;
+}
+
+static int
+make_write(struct cdb_make *cdbmp, const char *ptr, cdbi_t len)
+{
+  cdbi_t l = sizeof(cdbmp->cdb_buf) - (cdbmp->cdb_bpos - cdbmp->cdb_buf);
+  cdbmp->cdb_dpos += len;
+  if (len > l) {
+    memcpy(cdbmp->cdb_bpos, ptr, l);
+    if (ewrite(cdbmp->cdb_fd, cdbmp->cdb_buf, sizeof(cdbmp->cdb_buf)) < 0)
+      return -1;
+    ptr += l; len -= l;
+    l = len / sizeof(cdbmp->cdb_buf);
+    if (l) {
+      l *= sizeof(cdbmp->cdb_buf);
+      if (ewrite(cdbmp->cdb_fd, ptr, l) < 0)
+       return -1;
+      ptr += l; len -= l;
+    }
+    cdbmp->cdb_bpos = cdbmp->cdb_buf;
+  }
+  if (len) {
+    memcpy(cdbmp->cdb_bpos, ptr, len);
+    cdbmp->cdb_bpos += len;
+  }
+  return 0;
+}
+
+static int
+cdb_make_finish_internal(struct cdb_make *cdbmp)
+{
+  cdbi_t hcnt[256];            /* hash table counts */
+  cdbi_t hpos[256];            /* hash table positions */
+  struct cdb_rec *htab;
+  unsigned char *p;
+  struct cdb_rl *rl;
+  cdbi_t hsize;
+  unsigned t, i;
+
+  if (((0xffffffff - cdbmp->cdb_dpos) >> 3) < cdbmp->cdb_rcnt) {
+    gpg_err_set_errno (ENOMEM);
+    return -1;
+  }
+
+  /* count htab sizes and reorder reclists */
+  hsize = 0;
+  for (t = 0; t < 256; ++t) {
+    struct cdb_rl *rlt = NULL;
+    i = 0;
+    rl = cdbmp->cdb_rec[t];
+    while(rl) {
+      struct cdb_rl *rln = rl->next;
+      rl->next = rlt;
+      rlt = rl;
+      i += rl->cnt;
+      rl = rln;
+    }
+    cdbmp->cdb_rec[t] = rlt;
+    if (hsize < (hcnt[t] = i << 1))
+      hsize = hcnt[t];
+  }
+
+  /* allocate memory to hold max htable */
+  htab = (struct cdb_rec*)malloc((hsize + 2) * sizeof(struct cdb_rec));
+  if (!htab) {
+    gpg_err_set_errno (ENOENT);
+    return -1;
+  }
+  p = (unsigned char *)htab;
+  htab += 2;
+
+  /* build hash tables */
+  for (t = 0; t < 256; ++t) {
+    cdbi_t len, hi;
+    hpos[t] = cdbmp->cdb_dpos;
+    if ((len = hcnt[t]) == 0)
+      continue;
+    for (i = 0; i < len; ++i)
+      htab[i].hval = htab[i].rpos = 0;
+    for (rl = cdbmp->cdb_rec[t]; rl; rl = rl->next)
+      for (i = 0; i < rl->cnt; ++i) {
+       hi = (rl->rec[i].hval >> 8) % len;
+       while(htab[hi].rpos)
+         if (++hi == len)
+           hi = 0;
+       htab[hi] = rl->rec[i];
+      }
+    for (i = 0; i < len; ++i) {
+      cdb_pack(htab[i].hval, p + (i << 3));
+      cdb_pack(htab[i].rpos, p + (i << 3) + 4);
+    }
+    if (make_write(cdbmp, p, len << 3) < 0) {
+      free(p);
+      return -1;
+    }
+  }
+  free(p);
+  if (cdbmp->cdb_bpos != cdbmp->cdb_buf &&
+      ewrite(cdbmp->cdb_fd, cdbmp->cdb_buf,
+            cdbmp->cdb_bpos - cdbmp->cdb_buf) != 0)
+      return -1;
+  p = cdbmp->cdb_buf;
+  for (t = 0; t < 256; ++t) {
+    cdb_pack(hpos[t], p + (t << 3));
+    cdb_pack(hcnt[t], p + (t << 3) + 4);
+  }
+  if (lseek(cdbmp->cdb_fd, 0, 0) != 0 ||
+      ewrite(cdbmp->cdb_fd, p, 2048) != 0)
+    return -1;
+
+  return 0;
+}
+
+static void
+cdb_make_free(struct cdb_make *cdbmp)
+{
+  unsigned t;
+  for(t = 0; t < 256; ++t) {
+    struct cdb_rl *rl = cdbmp->cdb_rec[t];
+    while(rl) {
+      struct cdb_rl *tm = rl;
+      rl = rl->next;
+      free(tm);
+    }
+  }
+}
+
+
+
+/* Finalizes database file, constructing all needed indexes, and frees
+   memory structures.  It does not close the file descriptor.  Returns
+   0 on success or a negative value on error. */
+int
+cdb_make_finish(struct cdb_make *cdbmp)
+{
+  int r = cdb_make_finish_internal(cdbmp);
+  cdb_make_free(cdbmp);
+  return r;
+}
+
+
+cdbi_t
+cdb_hash(const void *buf, cdbi_t len)
+{
+  register const unsigned char *p = (const unsigned char *)buf;
+  register const unsigned char *end = p + len;
+  register cdbi_t hash = 5381; /* start value */
+  while (p < end)
+    hash = (hash + (hash << 5)) ^ *p++;
+  return hash;
+}
diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c
new file mode 100644 (file)
index 0000000..969b3ec
--- /dev/null
@@ -0,0 +1,1394 @@
+/* certcache.c - Certificate caching
+ *      Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <npth.h>
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "crlfetch.h"
+#include "certcache.h"
+
+
+#define MAX_EXTRA_CACHED_CERTS 1000
+
+/* Constants used to classify search patterns.  */
+enum pattern_class
+  {
+    PATTERN_UNKNOWN = 0,
+    PATTERN_EMAIL,
+    PATTERN_EMAIL_SUBSTR,
+    PATTERN_FINGERPRINT16,
+    PATTERN_FINGERPRINT20,
+    PATTERN_SHORT_KEYID,
+    PATTERN_LONG_KEYID,
+    PATTERN_SUBJECT,
+    PATTERN_SERIALNO,
+    PATTERN_SERIALNO_ISSUER,
+    PATTERN_ISSUER,
+    PATTERN_SUBSTR
+  };
+
+
+/* A certificate cache item.  This consists of a the KSBA cert object
+   and some meta data for easier lookup.  We use a hash table to keep
+   track of all items and use the (randomly distributed) first byte of
+   the fingerprint directly as the hash which makes it pretty easy. */
+struct cert_item_s
+{
+  struct cert_item_s *next; /* Next item with the same hash value. */
+  ksba_cert_t cert;         /* The KSBA cert object or NULL is this is
+                               not a valid item.  */
+  unsigned char fpr[20];    /* The fingerprint of this object. */
+  char *issuer_dn;          /* The malloced issuer DN.  */
+  ksba_sexp_t sn;           /* The malloced serial number  */
+  char *subject_dn;         /* The malloced subject DN - maybe NULL.  */
+  struct
+  {
+    unsigned int loaded:1;  /* It has been explicitly loaded.  */
+    unsigned int trusted:1; /* This is a trusted root certificate.  */
+  } flags;
+};
+typedef struct cert_item_s *cert_item_t;
+
+/* The actual cert cache consisting of 256 slots for items indexed by
+   the first byte of the fingerprint.  */
+static cert_item_t cert_cache[256];
+
+/* This is the global cache_lock variable. In general looking is not
+   needed but it would take extra efforts to make sure that no
+   indirect use of npth functions is done, so we simply lock it
+   always.  Note: We can't use static initialization, as that is not
+   available through w32-pth.  */
+static npth_rwlock_t cert_cache_lock;
+
+/* Flag to track whether the cache has been initialized.  */
+static int initialization_done;
+
+/* Total number of certificates loaded during initialization and
+   cached during operation.  */
+static unsigned int total_loaded_certificates;
+static unsigned int total_extra_certificates;
+
+
+\f
+/* Helper to do the cache locking.  */
+static void
+init_cache_lock (void)
+{
+  int err;
+
+  err = npth_rwlock_init (&cert_cache_lock, NULL);
+  if (err)
+    log_fatal (_("can't initialize certificate cache lock: %s\n"),
+              strerror (err));
+}
+
+static void
+acquire_cache_read_lock (void)
+{
+  int err;
+
+  err = npth_rwlock_rdlock (&cert_cache_lock);
+  if (err)
+    log_fatal (_("can't acquire read lock on the certificate cache: %s\n"),
+               strerror (err));
+}
+
+static void
+acquire_cache_write_lock (void)
+{
+  int err;
+
+  err = npth_rwlock_wrlock (&cert_cache_lock);
+  if (err)
+    log_fatal (_("can't acquire write lock on the certificate cache: %s\n"),
+               strerror (err));
+}
+
+static void
+release_cache_lock (void)
+{
+  int err;
+
+  err = npth_rwlock_unlock (&cert_cache_lock);
+  if (err)
+    log_fatal (_("can't release lock on the certificate cache: %s\n"),
+               strerror (err));
+}
+
+
+/* Return false if both serial numbers match.  Can't be used for
+   sorting. */
+static int
+compare_serialno (ksba_sexp_t serial1, ksba_sexp_t serial2 )
+{
+  unsigned char *a = serial1;
+  unsigned char *b = serial2;
+  return cmp_simple_canon_sexp (a, b);
+}
+
+
+
+/* Return a malloced canonical S-Expression with the serialnumber
+   converted from the hex string HEXSN.  Return NULL on memory
+   error. */
+ksba_sexp_t
+hexsn_to_sexp (const char *hexsn)
+{
+  char *buffer, *p;
+  size_t len;
+  char numbuf[40];
+
+  len = unhexify (NULL, hexsn);
+  snprintf (numbuf, sizeof numbuf, "(%u:", (unsigned int)len);
+  buffer = xtrymalloc (strlen (numbuf) + len + 2 );
+  if (!buffer)
+    return NULL;
+  p = stpcpy (buffer, numbuf);
+  len = unhexify (p, hexsn);
+  p[len] = ')';
+  p[len+1] = 0;
+
+  return buffer;
+}
+
+
+/* Compute the fingerprint of the certificate CERT and put it into
+   the 20 bytes large buffer DIGEST.  Return address of this buffer.  */
+unsigned char *
+cert_compute_fpr (ksba_cert_t cert, unsigned char *digest)
+{
+  gpg_error_t err;
+  gcry_md_hd_t md;
+
+  err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+  if (err)
+    log_fatal ("gcry_md_open failed: %s\n", gpg_strerror (err));
+
+  err = ksba_cert_hash (cert, 0, HASH_FNC, md);
+  if (err)
+    {
+      log_error ("oops: ksba_cert_hash failed: %s\n", gpg_strerror (err));
+      memset (digest, 0xff, 20); /* Use a dummy value. */
+    }
+  else
+    {
+      gcry_md_final (md);
+      memcpy (digest, gcry_md_read (md, GCRY_MD_SHA1), 20);
+    }
+  gcry_md_close (md);
+  return digest;
+}
+
+
+/* Cleanup one slot.  This releases all resourses but keeps the actual
+   slot in the cache marked for reuse. */
+static void
+clean_cache_slot (cert_item_t ci)
+{
+  ksba_cert_t cert;
+
+  if (!ci->cert)
+    return; /* Already cleaned.  */
+
+  ksba_free (ci->sn);
+  ci->sn = NULL;
+  ksba_free (ci->issuer_dn);
+  ci->issuer_dn = NULL;
+  ksba_free (ci->subject_dn);
+  ci->subject_dn = NULL;
+  cert = ci->cert;
+  ci->cert = NULL;
+
+  ksba_cert_release (cert);
+}
+
+
+/* Put the certificate CERT into the cache.  It is assumed that the
+   cache is locked while this function is called. If FPR_BUFFER is not
+   NULL the fingerprint of the certificate will be stored there.
+   FPR_BUFFER neds to point to a buffer of at least 20 bytes. The
+   fingerprint will be stored on success or when the function returns
+   gpg_err_code(GPG_ERR_DUP_VALUE). */
+static gpg_error_t
+put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer)
+{
+  unsigned char help_fpr_buffer[20], *fpr;
+  cert_item_t ci;
+
+  fpr = fpr_buffer? fpr_buffer : &help_fpr_buffer;
+
+  /* If we already reached the caching limit, drop a couple of certs
+     from the cache.  Our dropping strategy is simple: We keep a
+     static index counter and use this to start looking for
+     certificates, then we drop 5 percent of the oldest certificates
+     starting at that index.  For a large cache this is a fair way of
+     removing items. An LRU strategy would be better of course.
+     Because we append new entries to the head of the list and we want
+     to remove old ones first, we need to do this from the tail.  The
+     implementation is not very efficient but compared to the long
+     time it takes to retrieve a certifciate from an external resource
+     it seems to be reasonable. */
+  if (!is_loaded && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS)
+    {
+      static int idx;
+      cert_item_t ci_mark;
+      int i;
+      unsigned int drop_count;
+
+      drop_count = MAX_EXTRA_CACHED_CERTS / 20;
+      if (drop_count < 2)
+        drop_count = 2;
+
+      log_info (_("dropping %u certificates from the cache\n"), drop_count);
+      assert (idx < 256);
+      for (i=idx; drop_count; i = ((i+1)%256))
+        {
+          ci_mark = NULL;
+          for (ci = cert_cache[i]; ci; ci = ci->next)
+            if (ci->cert && !ci->flags.loaded)
+              ci_mark = ci;
+          if (ci_mark)
+            {
+              clean_cache_slot (ci_mark);
+              drop_count--;
+              total_extra_certificates--;
+            }
+        }
+      if (i==idx)
+        idx++;
+      else
+        idx = i;
+      idx %= 256;
+    }
+
+  cert_compute_fpr (cert, fpr);
+  for (ci=cert_cache[*fpr]; ci; ci = ci->next)
+    if (ci->cert && !memcmp (ci->fpr, fpr, 20))
+      return gpg_error (GPG_ERR_DUP_VALUE);
+  /* Try to reuse an existing entry.  */
+  for (ci=cert_cache[*fpr]; ci; ci = ci->next)
+    if (!ci->cert)
+      break;
+  if (!ci)
+    { /* No: Create a new entry.  */
+      ci = xtrycalloc (1, sizeof *ci);
+      if (!ci)
+        return gpg_error_from_errno (errno);
+      ci->next = cert_cache[*fpr];
+      cert_cache[*fpr] = ci;
+    }
+  else
+    memset (&ci->flags, 0, sizeof ci->flags);
+
+  ksba_cert_ref (cert);
+  ci->cert = cert;
+  memcpy (ci->fpr, fpr, 20);
+  ci->sn = ksba_cert_get_serial (cert);
+  ci->issuer_dn = ksba_cert_get_issuer (cert, 0);
+  if (!ci->issuer_dn || !ci->sn)
+    {
+      clean_cache_slot (ci);
+      return gpg_error (GPG_ERR_INV_CERT_OBJ);
+    }
+  ci->subject_dn = ksba_cert_get_subject (cert, 0);
+  ci->flags.loaded  = !!is_loaded;
+  ci->flags.trusted = !!is_trusted;
+
+  if (is_loaded)
+    total_loaded_certificates++;
+  else
+    total_extra_certificates++;
+
+  return 0;
+}
+
+
+/* Load certificates from the directory DIRNAME.  All certificates
+   matching the pattern "*.crt" or "*.der"  are loaded.  We assume that
+   certificates are DER encoded and not PEM encapsulated. The cache
+   should be in a locked state when calling this fucntion.  */
+static gpg_error_t
+load_certs_from_dir (const char *dirname, int are_trusted)
+{
+  gpg_error_t err;
+  DIR *dir;
+  struct dirent *ep;
+  char *p;
+  size_t n;
+  estream_t fp;
+  ksba_reader_t reader;
+  ksba_cert_t cert;
+  char *fname = NULL;
+
+  dir = opendir (dirname);
+  if (!dir)
+    {
+      if (opt.system_daemon)
+        log_info (_("can't access directory '%s': %s\n"),
+                  dirname, strerror (errno));
+      return 0; /* We do not consider this a severe error.  */
+    }
+
+  while ( (ep=readdir (dir)) )
+    {
+      p = ep->d_name;
+      if (*p == '.' || !*p)
+        continue; /* Skip any hidden files and invalid entries.  */
+      n = strlen (p);
+      if ( n < 5 || (strcmp (p+n-4,".crt") && strcmp (p+n-4,".der")))
+        continue; /* Not the desired "*.crt" or "*.der" pattern.  */
+
+      xfree (fname);
+      fname = make_filename (dirname, p, NULL);
+      fp = es_fopen (fname, "rb");
+      if (!fp)
+        {
+          log_error (_("can't open '%s': %s\n"),
+                     fname, strerror (errno));
+          continue;
+        }
+
+      err = create_estream_ksba_reader (&reader, fp);
+      if (err)
+        {
+          es_fclose (fp);
+          continue;
+        }
+
+      err = ksba_cert_new (&cert);
+      if (!err)
+        err = ksba_cert_read_der (cert, reader);
+      ksba_reader_release (reader);
+      es_fclose (fp);
+      if (err)
+        {
+          log_error (_("can't parse certificate '%s': %s\n"),
+                     fname, gpg_strerror (err));
+          ksba_cert_release (cert);
+          continue;
+        }
+
+      err = put_cert (cert, 1, are_trusted, NULL);
+      if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
+        log_info (_("certificate '%s' already cached\n"), fname);
+      else if (!err)
+        {
+          if (are_trusted)
+            log_info (_("trusted certificate '%s' loaded\n"), fname);
+          else
+            log_info (_("certificate '%s' loaded\n"), fname);
+          if (opt.verbose)
+            {
+              p = get_fingerprint_hexstring_colon (cert);
+              log_info (_("  SHA1 fingerprint = %s\n"), p);
+              xfree (p);
+
+              cert_log_name (_("   issuer ="), cert);
+              cert_log_subject (_("  subject ="), cert);
+            }
+        }
+      else
+        log_error (_("error loading certificate '%s': %s\n"),
+                     fname, gpg_strerror (err));
+      ksba_cert_release (cert);
+    }
+
+  xfree (fname);
+  closedir (dir);
+  return 0;
+}
+
+
+/* Initialize the certificate cache if not yet done.  */
+void
+cert_cache_init (void)
+{
+  char *dname;
+
+  if (initialization_done)
+    return;
+  init_cache_lock ();
+  acquire_cache_write_lock ();
+
+  dname = make_filename (opt.homedir, "trusted-certs", NULL);
+  load_certs_from_dir (dname, 1);
+  xfree (dname);
+
+  dname = make_filename (opt.homedir_data, "extra-certs", NULL);
+  load_certs_from_dir (dname, 0);
+  xfree (dname);
+
+  initialization_done = 1;
+  release_cache_lock ();
+
+  cert_cache_print_stats ();
+}
+
+/* Deinitialize the certificate cache.  With FULL set to true even the
+   unused certificate slots are released. */
+void
+cert_cache_deinit (int full)
+{
+  cert_item_t ci, ci2;
+  int i;
+
+  if (!initialization_done)
+    return;
+
+  acquire_cache_write_lock ();
+
+  for (i=0; i < 256; i++)
+    for (ci=cert_cache[i]; ci; ci = ci->next)
+      clean_cache_slot (ci);
+
+  if (full)
+    {
+      for (i=0; i < 256; i++)
+        {
+          for (ci=cert_cache[i]; ci; ci = ci2)
+            {
+              ci2 = ci->next;
+              xfree (ci);
+            }
+          cert_cache[i] = NULL;
+        }
+    }
+
+  total_loaded_certificates = 0;
+  total_extra_certificates = 0;
+  initialization_done = 0;
+  release_cache_lock ();
+}
+
+/* Print some statistics to the log file.  */
+void
+cert_cache_print_stats (void)
+{
+  log_info (_("permanently loaded certificates: %u\n"),
+            total_loaded_certificates);
+  log_info (_("    runtime cached certificates: %u\n"),
+            total_extra_certificates);
+}
+
+
+/* Put CERT into the certificate cache.  */
+gpg_error_t
+cache_cert (ksba_cert_t cert)
+{
+  gpg_error_t err;
+
+  acquire_cache_write_lock ();
+  err = put_cert (cert, 0, 0, NULL);
+  release_cache_lock ();
+  if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
+    log_info (_("certificate already cached\n"));
+  else if (!err)
+    log_info (_("certificate cached\n"));
+  else
+    log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
+  return err;
+}
+
+
+/* Put CERT into the certificate cache and store the fingerprint of
+   the certificate into FPR_BUFFER.  If the certificate is already in
+   the cache do not print a warning; just store the
+   fingerprint. FPR_BUFFER needs to be at least 20 bytes. */
+gpg_error_t
+cache_cert_silent (ksba_cert_t cert, void *fpr_buffer)
+{
+  gpg_error_t err;
+
+  acquire_cache_write_lock ();
+  err = put_cert (cert, 0, 0, fpr_buffer);
+  release_cache_lock ();
+  if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
+    err = 0;
+  if (err)
+    log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
+  return err;
+}
+
+
+\f
+/* Return a certificate object for the given fingerprint.  FPR is
+   expected to be a 20 byte binary SHA-1 fingerprint.  If no matching
+   certificate is available in the cache NULL is returned.  The caller
+   must release a returned certificate.  Note that although we are
+   using reference counting the caller should not just compare the
+   pointers to check for identical certificates. */
+ksba_cert_t
+get_cert_byfpr (const unsigned char *fpr)
+{
+  cert_item_t ci;
+
+  acquire_cache_read_lock ();
+  for (ci=cert_cache[*fpr]; ci; ci = ci->next)
+    if (ci->cert && !memcmp (ci->fpr, fpr, 20))
+      {
+        ksba_cert_ref (ci->cert);
+        release_cache_lock ();
+        return ci->cert;
+      }
+
+  release_cache_lock ();
+  return NULL;
+}
+
+/* Return a certificate object for the given fingerprint.  STRING is
+   expected to be a SHA-1 fingerprint in standard hex notation with or
+   without colons.  If no matching certificate is available in the
+   cache NULL is returned.  The caller must release a returned
+   certificate.  Note that although we are using reference counting
+   the caller should not just compare the pointers to check for
+   identical certificates. */
+ksba_cert_t
+get_cert_byhexfpr (const char *string)
+{
+  unsigned char fpr[20];
+  const char *s;
+  int i;
+
+  if (strchr (string, ':'))
+    {
+      for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1);)
+        {
+          if (s[2] && s[2] != ':')
+            break; /* Invalid string. */
+          fpr[i++] = xtoi_2 (s);
+          s += 2;
+          if (i!= 20 && *s == ':')
+            s++;
+        }
+    }
+  else
+    {
+      for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1); s+=2 )
+        fpr[i++] = xtoi_2 (s);
+    }
+  if (i!=20 || *s)
+    {
+      log_error (_("invalid SHA1 fingerprint string '%s'\n"), string);
+      return NULL;
+    }
+
+  return get_cert_byfpr (fpr);
+}
+
+
+
+/* Return the certificate matching ISSUER_DN and SERIALNO.  */
+ksba_cert_t
+get_cert_bysn (const char *issuer_dn, ksba_sexp_t serialno)
+{
+  /* Simple and inefficient implementation.   fixme! */
+  cert_item_t ci;
+  int i;
+
+  acquire_cache_read_lock ();
+  for (i=0; i < 256; i++)
+    {
+      for (ci=cert_cache[i]; ci; ci = ci->next)
+        if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn)
+            && !compare_serialno (ci->sn, serialno))
+          {
+            ksba_cert_ref (ci->cert);
+            release_cache_lock ();
+            return ci->cert;
+          }
+    }
+
+  release_cache_lock ();
+  return NULL;
+}
+
+
+/* Return the certificate matching ISSUER_DN.  SEQ should initially be
+   set to 0 and bumped up to get the next issuer with that DN. */
+ksba_cert_t
+get_cert_byissuer (const char *issuer_dn, unsigned int seq)
+{
+  /* Simple and very inefficient implementation and API.  fixme! */
+  cert_item_t ci;
+  int i;
+
+  acquire_cache_read_lock ();
+  for (i=0; i < 256; i++)
+    {
+      for (ci=cert_cache[i]; ci; ci = ci->next)
+        if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn))
+          if (!seq--)
+            {
+              ksba_cert_ref (ci->cert);
+              release_cache_lock ();
+              return ci->cert;
+            }
+    }
+
+  release_cache_lock ();
+  return NULL;
+}
+
+
+/* Return the certificate matching SUBJECT_DN.  SEQ should initially be
+   set to 0 and bumped up to get the next subject with that DN. */
+ksba_cert_t
+get_cert_bysubject (const char *subject_dn, unsigned int seq)
+{
+  /* Simple and very inefficient implementation and API.  fixme! */
+  cert_item_t ci;
+  int i;
+
+  if (!subject_dn)
+    return NULL;
+
+  acquire_cache_read_lock ();
+  for (i=0; i < 256; i++)
+    {
+      for (ci=cert_cache[i]; ci; ci = ci->next)
+        if (ci->cert && ci->subject_dn
+            && !strcmp (ci->subject_dn, subject_dn))
+          if (!seq--)
+            {
+              ksba_cert_ref (ci->cert);
+              release_cache_lock ();
+              return ci->cert;
+            }
+    }
+
+  release_cache_lock ();
+  return NULL;
+}
+
+
+
+/* Return a value decribing the the class of PATTERN.  The offset of
+   the actual string to be used for the comparison is stored at
+   R_OFFSET.  The offset of the serialnumer is stored at R_SN_OFFSET. */
+static enum pattern_class
+classify_pattern (const char *pattern, size_t *r_offset, size_t *r_sn_offset)
+{
+  enum pattern_class result;
+  const char *s;
+  int hexprefix = 0;
+  int hexlength;
+
+  *r_offset = *r_sn_offset = 0;
+
+  /* Skip leading spaces. */
+  for(s = pattern; *s && spacep (s); s++ )
+    ;
+
+  switch (*s)
+    {
+    case 0:  /* Empty string is an error. */
+      result = PATTERN_UNKNOWN;
+      break;
+
+    case '.': /* An email address, compare from end.  */
+      result = PATTERN_UNKNOWN;  /* Not implemented.  */
+      break;
+
+    case '<': /* An email address.  */
+      result = PATTERN_EMAIL;
+      s++;
+      break;
+
+    case '@': /* Part of an email address.  */
+      result = PATTERN_EMAIL_SUBSTR;
+      s++;
+      break;
+
+    case '=':  /* Exact compare. */
+      result = PATTERN_UNKNOWN; /* Does not make sense for X.509.  */
+      break;
+
+    case '*':  /* Case insensitive substring search.  */
+      result = PATTERN_SUBSTR;
+      s++;
+      break;
+
+    case '+':  /* Compare individual words. */
+      result = PATTERN_UNKNOWN;  /* Not implemented.  */
+      break;
+
+    case '/': /* Subject's DN. */
+      s++;
+      if (!*s || spacep (s))
+        result = PATTERN_UNKNOWN; /* No DN or prefixed with a space. */
+      else
+        result = PATTERN_SUBJECT;
+      break;
+
+    case '#': /* Serial number or issuer DN. */
+      {
+        const char *si;
+
+        s++;
+        if ( *s == '/')
+          {
+            /* An issuer's DN is indicated by "#/" */
+            s++;
+            if (!*s || spacep (s))
+              result = PATTERN_UNKNOWN; /* No DN or prefixed with a space. */
+            else
+              result = PATTERN_ISSUER;
+          }
+        else
+          { /* Serialnumber + optional issuer ID. */
+            for (si=s; *si && *si != '/'; si++)
+              if (!strchr("01234567890abcdefABCDEF", *si))
+                break;
+            if (*si && *si != '/')
+              result = PATTERN_UNKNOWN; /* Invalid digit in serial number. */
+            else
+              {
+                *r_sn_offset = s - pattern;
+                if (!*si)
+                  result = PATTERN_SERIALNO;
+                else
+                  {
+                    s = si+1;
+                    if (!*s || spacep (s))
+                      result = PATTERN_UNKNOWN; /* No DN or prefixed
+                                                   with a space. */
+                    else
+                      result = PATTERN_SERIALNO_ISSUER;
+                  }
+              }
+          }
+      }
+      break;
+
+    case ':': /* Unified fingerprint. */
+      {
+        const char *se, *si;
+        int i;
+
+        se = strchr (++s, ':');
+        if (!se)
+          result = PATTERN_UNKNOWN;
+        else
+          {
+            for (i=0, si=s; si < se; si++, i++ )
+              if (!strchr("01234567890abcdefABCDEF", *si))
+                break;
+            if ( si < se )
+              result = PATTERN_UNKNOWN; /* Invalid digit. */
+            else if (i == 32)
+              result = PATTERN_FINGERPRINT16;
+            else if (i == 40)
+              result = PATTERN_FINGERPRINT20;
+            else
+              result = PATTERN_UNKNOWN; /* Invalid length for a fingerprint. */
+          }
+      }
+      break;
+
+    case '&': /* Keygrip. */
+      result = PATTERN_UNKNOWN;  /* Not implemented.  */
+      break;
+
+    default:
+      if (s[0] == '0' && s[1] == 'x')
+        {
+          hexprefix = 1;
+          s += 2;
+        }
+
+      hexlength = strspn(s, "0123456789abcdefABCDEF");
+
+      /* Check if a hexadecimal number is terminated by EOS or blank. */
+      if (hexlength && s[hexlength] && !spacep (s+hexlength))
+        {
+          /* If the "0x" prefix is used a correct termination is required. */
+          if (hexprefix)
+            {
+              result = PATTERN_UNKNOWN;
+              break; /* switch */
+            }
+          hexlength = 0;  /* Not a hex number.  */
+        }
+
+      if (hexlength == 8 || (!hexprefix && hexlength == 9 && *s == '0'))
+        {
+          if (hexlength == 9)
+            s++;
+          result = PATTERN_SHORT_KEYID;
+        }
+      else if (hexlength == 16 || (!hexprefix && hexlength == 17 && *s == '0'))
+        {
+          if (hexlength == 17)
+            s++;
+          result = PATTERN_LONG_KEYID;
+        }
+      else if (hexlength == 32 || (!hexprefix && hexlength == 33 && *s == '0'))
+        {
+          if (hexlength == 33)
+            s++;
+          result = PATTERN_FINGERPRINT16;
+        }
+      else if (hexlength == 40 || (!hexprefix && hexlength == 41 && *s == '0'))
+        {
+          if (hexlength == 41)
+            s++;
+          result = PATTERN_FINGERPRINT20;
+        }
+      else if (!hexprefix)
+        {
+          /* The fingerprints used with X.509 are often delimited by
+             colons, so we try to single this case out. */
+          result = PATTERN_UNKNOWN;
+          hexlength = strspn (s, ":0123456789abcdefABCDEF");
+          if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength)))
+            {
+              int i, c;
+
+              for (i=0; i < 20; i++, s += 3)
+                {
+                  c = hextobyte(s);
+                  if (c == -1 || (i < 19 && s[2] != ':'))
+                    break;
+                }
+              if (i == 20)
+                result = PATTERN_FINGERPRINT20;
+            }
+          if (result == PATTERN_UNKNOWN) /* Default to substring match. */
+            {
+              result = PATTERN_SUBSTR;
+            }
+        }
+      else /* A hex number with a prefix but with a wrong length.  */
+        result = PATTERN_UNKNOWN;
+    }
+
+  if (result != PATTERN_UNKNOWN)
+    *r_offset = s - pattern;
+  return result;
+}
+
+
+
+/* Given PATTERN, which is a string as used by GnuPG to specify a
+   certificate, return all matching certificates by calling the
+   supplied function RETFNC.  */
+gpg_error_t
+get_certs_bypattern (const char *pattern,
+                     gpg_error_t (*retfnc)(void*,ksba_cert_t),
+                     void *retfnc_data)
+{
+  gpg_error_t err = GPG_ERR_BUG;
+  enum pattern_class class;
+  size_t offset, sn_offset;
+  const char *hexserialno;
+  ksba_sexp_t serialno = NULL;
+  ksba_cert_t cert = NULL;
+  unsigned int seq;
+
+  if (!pattern || !retfnc)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  class = classify_pattern (pattern, &offset, &sn_offset);
+  hexserialno = pattern + sn_offset;
+  pattern += offset;
+  switch (class)
+    {
+    case PATTERN_UNKNOWN:
+      err = gpg_error (GPG_ERR_INV_NAME);
+      break;
+
+    case PATTERN_FINGERPRINT20:
+      cert = get_cert_byhexfpr (pattern);
+      err = cert? 0 : gpg_error (GPG_ERR_NOT_FOUND);
+      break;
+
+    case PATTERN_SERIALNO_ISSUER:
+      serialno = hexsn_to_sexp (hexserialno);
+      if (!serialno)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          cert = get_cert_bysn (pattern, serialno);
+          err = cert? 0 : gpg_error (GPG_ERR_NOT_FOUND);
+        }
+      break;
+
+    case PATTERN_ISSUER:
+      for (seq=0,err=0; !err && (cert = get_cert_byissuer (pattern, seq)); seq++)
+        {
+          err = retfnc (retfnc_data, cert);
+          ksba_cert_release (cert);
+          cert = NULL;
+        }
+      if (!err && !seq)
+        err = gpg_error (GPG_ERR_NOT_FOUND);
+      break;
+
+    case PATTERN_SUBJECT:
+      for (seq=0,err=0; !err && (cert = get_cert_bysubject (pattern, seq));seq++)
+        {
+          err = retfnc (retfnc_data, cert);
+          ksba_cert_release (cert);
+          cert = NULL;
+        }
+      if (!err && !seq)
+        err = gpg_error (GPG_ERR_NOT_FOUND);
+      break;
+
+    case PATTERN_EMAIL:
+    case PATTERN_EMAIL_SUBSTR:
+    case PATTERN_FINGERPRINT16:
+    case PATTERN_SHORT_KEYID:
+    case PATTERN_LONG_KEYID:
+    case PATTERN_SUBSTR:
+    case PATTERN_SERIALNO:
+      /* Not supported.  */
+      err = gpg_error (GPG_ERR_INV_NAME);
+    }
+
+
+  if (!err && cert)
+    err = retfnc (retfnc_data, cert);
+  ksba_cert_release (cert);
+  xfree (serialno);
+  return err;
+}
+
+
+
+
+\f
+/* Return the certificate matching ISSUER_DN and SERIALNO; if it is
+   not already in the cache, try to find it from other resources.  */
+ksba_cert_t
+find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno)
+{
+  gpg_error_t err;
+  ksba_cert_t cert;
+  cert_fetch_context_t context = NULL;
+  char *hexsn, *buf;
+
+  /* First check whether it has already been cached.  */
+  cert = get_cert_bysn (issuer_dn, serialno);
+  if (cert)
+    return cert;
+
+  /* Ask back to the service requester to return the certificate.
+     This is because we can assume that he already used the
+     certificate while checking for the CRL. */
+  hexsn = serial_hex (serialno);
+  if (!hexsn)
+    {
+      log_error ("serial_hex() failed\n");
+      return NULL;
+    }
+  buf = xtrymalloc (1 + strlen (hexsn) + 1 + strlen (issuer_dn) + 1);
+  if (!buf)
+    {
+      log_error ("can't allocate enough memory: %s\n", strerror (errno));
+      xfree (hexsn);
+      return NULL;
+    }
+  strcpy (stpcpy (stpcpy (stpcpy (buf, "#"), hexsn),"/"), issuer_dn);
+  xfree (hexsn);
+  cert = get_cert_local (ctrl, buf);
+  xfree (buf);
+  if (cert)
+    {
+      cache_cert (cert);
+      return cert; /* Done. */
+    }
+
+  if (DBG_LOOKUP)
+    log_debug ("find_cert_bysn: certificate not returned by caller"
+               " - doing lookup\n");
+
+  /* Retrieve the certificate from external resources. */
+  while (!cert)
+    {
+      ksba_sexp_t sn;
+      char *issdn;
+
+      if (!context)
+        {
+          err = ca_cert_fetch (ctrl, &context, issuer_dn);
+          if (err)
+            {
+              log_error (_("error fetching certificate by S/N: %s\n"),
+                         gpg_strerror (err));
+              break;
+            }
+        }
+
+      err = fetch_next_ksba_cert (context, &cert);
+      if (err)
+        {
+          log_error (_("error fetching certificate by S/N: %s\n"),
+                     gpg_strerror (err) );
+          break;
+        }
+
+      issdn = ksba_cert_get_issuer (cert, 0);
+      if (strcmp (issuer_dn, issdn))
+        {
+          log_debug ("find_cert_bysn: Ooops: issuer DN does not match\n");
+          ksba_cert_release (cert);
+          cert = NULL;
+          ksba_free (issdn);
+          break;
+        }
+
+      sn = ksba_cert_get_serial (cert);
+
+      if (DBG_LOOKUP)
+        {
+          log_debug ("   considering certificate (#");
+          dump_serial (sn);
+          log_printf ("/");
+          dump_string (issdn);
+          log_printf (")\n");
+        }
+
+      if (!compare_serialno (serialno, sn))
+        {
+          ksba_free (sn);
+          ksba_free (issdn);
+          cache_cert (cert);
+          if (DBG_LOOKUP)
+            log_debug ("   found\n");
+          break; /* Ready.  */
+        }
+
+      ksba_free (sn);
+      ksba_free (issdn);
+      ksba_cert_release (cert);
+      cert = NULL;
+    }
+
+  end_cert_fetch (context);
+  return cert;
+}
+
+
+/* Return the certificate matching SUBJECT_DN and (if not NULL)
+   KEYID. If it is not already in the cache, try to find it from other
+   resources.  Note, that the external search does not work for user
+   certificates because the LDAP lookup is on the caCertificate
+   attribute. For our purposes this is just fine.  */
+ksba_cert_t
+find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid)
+{
+  gpg_error_t err;
+  int seq;
+  ksba_cert_t cert = NULL;
+  cert_fetch_context_t context = NULL;
+  ksba_sexp_t subj;
+
+  /* If we have certificates from an OCSP request we first try to use
+     them.  This is because these certificates will really be the
+     required ones and thus even in the case that they can't be
+     uniquely located by the following code we can use them.  This is
+     for example required by Telesec certificates where a keyId is
+     used but the issuer certificate comes without a subject keyId! */
+  if (ctrl->ocsp_certs && subject_dn)
+    {
+      cert_item_t ci;
+      cert_ref_t cr;
+      int i;
+
+      /* For efficiency reasons we won't use get_cert_bysubject here. */
+      acquire_cache_read_lock ();
+      for (i=0; i < 256; i++)
+        for (ci=cert_cache[i]; ci; ci = ci->next)
+          if (ci->cert && ci->subject_dn
+              && !strcmp (ci->subject_dn, subject_dn))
+            for (cr=ctrl->ocsp_certs; cr; cr = cr->next)
+              if (!memcmp (ci->fpr, cr->fpr, 20))
+                {
+                  ksba_cert_ref (ci->cert);
+                  release_cache_lock ();
+                  return ci->cert; /* We use this certificate. */
+                }
+      release_cache_lock ();
+      if (DBG_LOOKUP)
+        log_debug ("find_cert_bysubject: certificate not in ocsp_certs\n");
+    }
+
+
+  /* First we check whether the certificate is cached.  */
+  for (seq=0; (cert = get_cert_bysubject (subject_dn, seq)); seq++)
+    {
+      if (!keyid)
+        break; /* No keyid requested, so return the first one found. */
+      if (!ksba_cert_get_subj_key_id (cert, NULL, &subj)
+          && !cmp_simple_canon_sexp (keyid, subj))
+        {
+          xfree (subj);
+          break; /* Found matching cert. */
+        }
+      xfree (subj);
+      ksba_cert_release (cert);
+    }
+  if (cert)
+    return cert; /* Done.  */
+
+  if (DBG_LOOKUP)
+    log_debug ("find_cert_bysubject: certificate not in cache\n");
+
+  /* Ask back to the service requester to return the certificate.
+     This is because we can assume that he already used the
+     certificate while checking for the CRL. */
+  if (keyid)
+    cert = get_cert_local_ski (ctrl, subject_dn, keyid);
+  else
+    {
+      /* In contrast to get_cert_local_ski, get_cert_local uses any
+         passed pattern, so we need to make sure that an exact subject
+         search is done. */
+      char *buf;
+
+      buf = xtrymalloc (1 + strlen (subject_dn) + 1);
+      if (!buf)
+        {
+          log_error ("can't allocate enough memory: %s\n", strerror (errno));
+          return NULL;
+        }
+      strcpy (stpcpy (buf, "/"), subject_dn);
+      cert = get_cert_local (ctrl, buf);
+      xfree (buf);
+    }
+  if (cert)
+    {
+      cache_cert (cert);
+      return cert; /* Done. */
+    }
+
+  if (DBG_LOOKUP)
+    log_debug ("find_cert_bysubject: certificate not returned by caller"
+               " - doing lookup\n");
+
+  /* Locate the certificate using external resources. */
+  while (!cert)
+    {
+      char *subjdn;
+
+      if (!context)
+        {
+          err = ca_cert_fetch (ctrl, &context, subject_dn);
+          if (err)
+            {
+              log_error (_("error fetching certificate by subject: %s\n"),
+                         gpg_strerror (err));
+              break;
+            }
+        }
+
+      err = fetch_next_ksba_cert (context, &cert);
+      if (err)
+        {
+          log_error (_("error fetching certificate by subject: %s\n"),
+                     gpg_strerror (err) );
+          break;
+        }
+
+      subjdn = ksba_cert_get_subject (cert, 0);
+      if (strcmp (subject_dn, subjdn))
+        {
+          log_info ("find_cert_bysubject: subject DN does not match\n");
+          ksba_cert_release (cert);
+          cert = NULL;
+          ksba_free (subjdn);
+          continue;
+        }
+
+
+      if (DBG_LOOKUP)
+        {
+          log_debug ("   considering certificate (/");
+          dump_string (subjdn);
+          log_printf (")\n");
+        }
+      ksba_free (subjdn);
+
+      /* If no key ID has been provided, we return the first match.  */
+      if (!keyid)
+        {
+          cache_cert (cert);
+          if (DBG_LOOKUP)
+            log_debug ("   found\n");
+          break; /* Ready.  */
+        }
+
+      /* With the key ID given we need to compare it.  */
+      if (!ksba_cert_get_subj_key_id (cert, NULL, &subj))
+        {
+          if (!cmp_simple_canon_sexp (keyid, subj))
+            {
+              ksba_free (subj);
+              cache_cert (cert);
+              if (DBG_LOOKUP)
+                log_debug ("   found\n");
+              break; /* Ready.  */
+            }
+        }
+
+      ksba_free (subj);
+      ksba_cert_release (cert);
+      cert = NULL;
+    }
+
+  end_cert_fetch (context);
+  return cert;
+}
+
+
+
+/* Return 0 if the certificate is a trusted certificate. Returns
+   GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
+   case of systems errors. */
+gpg_error_t
+is_trusted_cert (ksba_cert_t cert)
+{
+  unsigned char fpr[20];
+  cert_item_t ci;
+
+  cert_compute_fpr (cert, fpr);
+
+  acquire_cache_read_lock ();
+  for (ci=cert_cache[*fpr]; ci; ci = ci->next)
+    if (ci->cert && !memcmp (ci->fpr, fpr, 20))
+      {
+        if (ci->flags.trusted)
+          {
+            release_cache_lock ();
+            return 0; /* Yes, it is trusted. */
+          }
+        break;
+      }
+
+  release_cache_lock ();
+  return gpg_error (GPG_ERR_NOT_TRUSTED);
+}
+
+
+\f
+/* Given the certificate CERT locate the issuer for this certificate
+   and return it at R_CERT.  Returns 0 on success or
+   GPG_ERR_NOT_FOUND.  */
+gpg_error_t
+find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert)
+{
+  gpg_error_t err;
+  char *issuer_dn;
+  ksba_cert_t issuer_cert = NULL;
+  ksba_name_t authid;
+  ksba_sexp_t authidno;
+  ksba_sexp_t keyid;
+
+  *r_cert = NULL;
+
+  issuer_dn = ksba_cert_get_issuer (cert, 0);
+  if (!issuer_dn)
+    {
+      log_error (_("no issuer found in certificate\n"));
+      err = gpg_error (GPG_ERR_BAD_CERT);
+      goto leave;
+    }
+
+  /* First we need to check whether we can return that certificate
+     using the authorithyKeyIdentifier.  */
+  err = ksba_cert_get_auth_key_id (cert, &keyid, &authid, &authidno);
+  if (err)
+    {
+      log_info (_("error getting authorityKeyIdentifier: %s\n"),
+                gpg_strerror (err));
+    }
+  else
+    {
+      const char *s = ksba_name_enum (authid, 0);
+      if (s && *authidno)
+        {
+          issuer_cert = find_cert_bysn (ctrl, s, authidno);
+        }
+      if (!issuer_cert && keyid)
+        {
+          /* Not found by issuer+s/n.  Now that we have an AKI
+             keyIdentifier look for a certificate with a matching
+             SKI. */
+          issuer_cert = find_cert_bysubject (ctrl, issuer_dn, keyid);
+        }
+      /* 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 (!issuer_cert)
+        {
+          log_info ("issuer certificate ");
+          if (keyid)
+            {
+              log_printf ("{");
+              dump_serial (keyid);
+              log_printf ("} ");
+            }
+          if (authidno)
+            {
+              log_printf ("(#");
+              dump_serial (authidno);
+              log_printf ("/");
+              dump_string (s);
+              log_printf (") ");
+            }
+          log_printf ("not found using authorityKeyIdentifier\n");
+        }
+      ksba_name_release (authid);
+      xfree (authidno);
+      xfree (keyid);
+    }
+
+  /* If this did not work, try just with the issuer's name and assume
+     that there is only one such certificate.  We only look into our
+     cache then. */
+  if (err || !issuer_cert)
+    {
+      issuer_cert = get_cert_bysubject (issuer_dn, 0);
+      if (issuer_cert)
+        err = 0;
+    }
+
+ leave:
+  if (!err && !issuer_cert)
+    err = gpg_error (GPG_ERR_NOT_FOUND);
+
+  xfree (issuer_dn);
+
+  if (err)
+    ksba_cert_release (issuer_cert);
+  else
+    *r_cert = issuer_cert;
+
+  return err;
+}
diff --git a/dirmngr/certcache.h b/dirmngr/certcache.h
new file mode 100644 (file)
index 0000000..9986f15
--- /dev/null
@@ -0,0 +1,103 @@
+/* certcache.h - Certificate caching
+ *      Copyright (C) 2004, 2008 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 CERTCACHE_H
+#define CERTCACHE_H
+
+/* First time initialization of the certificate cache.  */
+void cert_cache_init (void);
+
+/* Deinitialize the certificate cache.  */
+void cert_cache_deinit (int full);
+
+/* Print some statistics to the log file.  */
+void cert_cache_print_stats (void);
+
+/* Compute the fingerprint of the certificate CERT and put it into
+   the 20 bytes large buffer DIGEST.  Return address of this buffer.  */
+unsigned char *cert_compute_fpr (ksba_cert_t cert, unsigned char *digest);
+
+/* Put CERT into the certificate cache.  */
+gpg_error_t cache_cert (ksba_cert_t cert);
+
+/* Put CERT into the certificate cache and return the fingerprint. */
+gpg_error_t cache_cert_silent (ksba_cert_t cert, void *fpr_buffer);
+
+/* Return 0 if the certificate is a trusted certificate. Returns
+   GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
+   case of systems errors. */
+gpg_error_t is_trusted_cert (ksba_cert_t cert);
+
+
+/* Return a certificate object for the given fingerprint.  FPR is
+   expected to be a 20 byte binary SHA-1 fingerprint.  If no matching
+   certificate is available in the cache NULL is returned.  The caller
+   must release a returned certificate.  */
+ksba_cert_t get_cert_byfpr (const unsigned char *fpr);
+
+/* Return a certificate object for the given fingerprint.  STRING is
+   expected to be a SHA-1 fingerprint in standard hex notation with or
+   without colons.  If no matching certificate is available in the
+   cache NULL is returned.  The caller must release a returned
+   certificate.  */
+ksba_cert_t get_cert_byhexfpr (const char *string);
+
+/* Return the certificate matching ISSUER_DN and SERIALNO.  */
+ksba_cert_t get_cert_bysn (const char *issuer_dn, ksba_sexp_t serialno);
+
+/* Return the certificate matching ISSUER_DN.  SEQ should initially be
+   set to 0 and bumped up to get the next issuer with that DN. */
+ksba_cert_t get_cert_byissuer (const char *issuer_dn, unsigned int seq);
+
+/* Return the certificate matching SUBJECT_DN.  SEQ should initially be
+   set to 0 and bumped up to get the next issuer with that DN. */
+ksba_cert_t get_cert_bysubject (const char *subject_dn, unsigned int seq);
+
+/* Given PATTERN, which is a string as used by GnuPG to specify a
+   certificate, return all matching certificates by calling the
+   supplied function RETFNC.  */
+gpg_error_t get_certs_bypattern (const char *pattern,
+                                 gpg_error_t (*retfnc)(void*,ksba_cert_t),
+                                 void *retfnc_data);
+
+/* Return the certificate matching ISSUER_DN and SERIALNO; if it is
+   not already in the cache, try to find it from other resources.  */
+ksba_cert_t find_cert_bysn (ctrl_t ctrl,
+                            const char *issuer_dn, ksba_sexp_t serialno);
+
+
+/* Return the certificate matching SUBJECT_DN and (if not NULL) KEYID. If
+   it is not already in the cache, try to find it from other
+   resources.  Note, that the external search does not work for user
+   certificates because the LDAP lookup is on the caCertificate
+   attribute. For our purposes this is just fine.  */
+ksba_cert_t find_cert_bysubject (ctrl_t ctrl,
+                                 const char *subject_dn, ksba_sexp_t keyid);
+
+/* Given the certificate CERT locate the issuer for this certificate
+   and return it at R_CERT.  Returns 0 on success or
+   GPG_ERR_NOT_FOUND.  */
+gpg_error_t find_issuing_cert (ctrl_t ctrl,
+                               ksba_cert_t cert, ksba_cert_t *r_cert);
+
+
+
+
+#endif /*CERTCACHE_H*/
diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c
new file mode 100644 (file)
index 0000000..d10e3ca
--- /dev/null
@@ -0,0 +1,2580 @@
+/* crlcache.c - LDAP access
+ * Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ * Copyright (C) 2003, 2004, 2005, 2008 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+
+   1. To keep track of the CRLs actually cached and to store the meta
+      information of the CRLs a simple record oriented text file is
+      used.  Fields in the file are colon (':') separated and values
+      containing colons or linefeeds are percent escaped (e.g. a colon
+      itself is represented as "%3A").
+
+      The first field is a record type identifier, so that the file is
+      useful to keep track of other meta data too.
+
+      The name of the file is "DIR.txt".
+
+
+   1.1. Comment record
+
+        Field 1: Constant beginning with "#".
+
+        Other fields are not defined and such a record is simply
+        skipped during processing.
+
+   1.2. Version record
+
+        Field 1: Constant "v"
+        Field 2: Version number of this file.  Must be 1.
+
+        This record must be the first non-comment record record and
+        there shall only exist one record of this type.
+
+   1.3. CRL cache record
+
+        Field 1: Constant "c", "u" or "i".
+                 A "c" or "u" indicate a valid cache entry, however
+                 "u" requires that a user root certificate check needs
+                 to be done.
+                 An "i" indicates an invalid cache entry which should
+                 not be used but still exists so that it can be
+                 updated at NEXT_UPDATE.
+        Field 2: Hexadecimal encoded SHA-1 hash of the issuer DN using
+                 uppercase letters.
+        Field 3: Issuer DN in RFC-2253 notation.
+        Field 4: URL used to retrieve the corresponding CRL.
+        Field 5: 15 character ISO timestamp with THIS_UPDATE.
+        Field 6: 15 character ISO timestamp with NEXT_UPDATE.
+        Field 7: Hexadecimal encoded MD-5 hash of the DB file to detect
+                 accidental modified (i.e. deleted and created) cache files.
+        Field 8: optional CRL number as a hex string.
+        Field 9:  AuthorityKeyID.issuer, each Name separated by 0x01
+        Field 10: AuthorityKeyID.serial
+        Field 11: Hex fingerprint of trust anchor if field 1 is 'u'.
+
+   2. Layout of the standard CRL Cache DB file:
+
+      We use records of variable length with this structure
+
+      n  bytes  Serialnumber (binary) used as key
+                thus there is no need to store the length explicitly with DB2.
+      1  byte   Reason for revocation
+                (currently the KSBA reason flags are used)
+      15 bytes  ISO date of revocation (e.g. 19980815T142000)
+                Note that there is no terminating 0 stored.
+
+      The filename used is the hexadecimal (using uppercase letters)
+      SHA-1 hash value of the issuer DN prefixed with a "crl-" and
+      suffixed with a ".db".  Thus the length of the filename is 47.
+
+
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifndef HAVE_W32_SYSTEM
+#include <sys/utsname.h>
+#endif
+#ifdef MKDIR_TAKES_ONE_ARG
+#undef mkdir
+#define mkdir(a,b) mkdir(a)
+#endif
+
+#include "dirmngr.h"
+#include "validate.h"
+#include "certcache.h"
+#include "crlcache.h"
+#include "crlfetch.h"
+#include "misc.h"
+#include "cdb.h"
+
+/* Change this whenever the format changes */
+#define DBDIR_D (opt.system_daemon? "crls.d" : "dirmngr-cache.d")
+#define DBDIRFILE "DIR.txt"
+#define DBDIRVERSION 1
+
+/* The number of DB files we may have open at one time.  We need to
+   limit this because there is no guarantee that the number of issuers
+   has a upper limit.  We are currently using mmap, so it is a good
+   idea anyway to limit the number of opened cache files. */
+#define MAX_OPEN_DB_FILES 5
+
+
+static const char oidstr_crlNumber[] = "2.5.29.20";
+static const char oidstr_issuingDistributionPoint[] = "2.5.29.28";
+static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
+
+
+/* Definition of one cached item. */
+struct crl_cache_entry_s
+{
+  struct crl_cache_entry_s *next;
+  int deleted;        /* True if marked for deletion. */
+  int mark;           /* Internally used by update_dir. */
+  unsigned int lineno;/* A 0 indicates a new entry. */
+  char *release_ptr;  /* The actual allocated memory. */
+  char *url;          /* Points into RELEASE_PTR. */
+  char *issuer;       /* Ditto. */
+  char *issuer_hash;  /* Ditto. */
+  char *dbfile_hash;  /* MD5 sum of the cache file, points into RELEASE_PTR.*/
+  int invalid;        /* Can't use this CRL. */
+  int user_trust_req; /* User supplied root certificate required.  */
+  char *check_trust_anchor;  /* Malloced fingerprint.  */
+  ksba_isotime_t this_update;
+  ksba_isotime_t next_update;
+  ksba_isotime_t last_refresh; /* Use for the force_crl_refresh feature. */
+  char *crl_number;
+  char *authority_issuer;
+  char *authority_serialno;
+
+  struct cdb *cdb;             /* The cache file handle or NULL if not open. */
+
+  unsigned int cdb_use_count;  /* Current use count. */
+  unsigned int cdb_lru_count;  /* Used for LRU purposes. */
+  int dbfile_checked;          /* Set to true if the dbfile_hash value has
+                                  been checked one. */
+};
+
+
+/* Definition of the entire cache object. */
+struct crl_cache_s
+{
+  crl_cache_entry_t entries;
+};
+
+typedef struct crl_cache_s *crl_cache_t;
+
+
+/* Prototypes.  */
+static crl_cache_entry_t find_entry (crl_cache_entry_t first,
+                                     const char *issuer_hash);
+
+
+
+/* The currently loaded cache object.  This is usually initialized
+   right at startup.  */
+static crl_cache_t current_cache;
+
+
+
+
+\f
+/* Return the current cache object or bail out if it is has not yet
+   been initialized.  */
+static crl_cache_t
+get_current_cache (void)
+{
+  if (!current_cache)
+    log_fatal ("CRL cache has not yet been initialized\n");
+  return current_cache;
+}
+
+
+/*
+   Create ae directory if it does not yet exists.  Returns on
+   success, or -1 on error.
+ */
+static int
+create_directory_if_needed (const char *name)
+{
+  DIR *dir;
+  char *fname;
+
+  fname = make_filename (opt.homedir_cache, name, NULL);
+  dir = opendir (fname);
+  if (!dir)
+    {
+      log_info (_("creating directory '%s'\n"), fname);
+      if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
+        {
+          int save_errno = errno;
+          log_error (_("error creating directory '%s': %s\n"),
+                     fname, strerror (errno));
+          xfree (fname);
+          gpg_err_set_errno (save_errno);
+          return -1;
+        }
+    }
+  else
+    closedir (dir);
+  xfree (fname);
+  return 0;
+}
+
+/* Remove all files from the cache directory.  If FORCE is not true,
+   some sanity checks on the filenames are done. Return 0 if
+   everything went fine. */
+static int
+cleanup_cache_dir (int force)
+{
+  char *dname = make_filename (opt.homedir_cache, DBDIR_D, NULL);
+  DIR *dir;
+  struct dirent *de;
+  int problem = 0;
+
+  if (!force)
+    { /* Very minor sanity checks. */
+      if (!strcmp (dname, "~/") || !strcmp (dname, "/" ))
+        {
+          log_error (_("ignoring database dir '%s'\n"), dname);
+          xfree (dname);
+          return -1;
+        }
+    }
+
+  dir = opendir (dname);
+  if (!dir)
+    {
+      log_error (_("error reading directory '%s': %s\n"),
+                 dname, strerror (errno));
+      xfree (dname);
+      return -1;
+    }
+
+  while ((de = readdir (dir)))
+    {
+      if (strcmp (de->d_name, "." ) && strcmp (de->d_name, ".."))
+        {
+          char *cdbname = make_filename (dname, de->d_name, NULL);
+          int okay;
+          struct stat sbuf;
+
+          if (force)
+            okay = 1;
+          else
+            okay = (!stat (cdbname, &sbuf) && S_ISREG (sbuf.st_mode));
+
+          if (okay)
+            {
+              log_info (_("removing cache file '%s'\n"), cdbname);
+              if (gnupg_remove (cdbname))
+                {
+                  log_error ("failed to remove '%s': %s\n",
+                             cdbname, strerror (errno));
+                  problem = -1;
+                }
+            }
+          else
+            log_info (_("not removing file '%s'\n"), cdbname);
+          xfree (cdbname);
+        }
+    }
+  xfree (dname);
+  closedir (dir);
+  return problem;
+}
+
+
+/* Read the next line from the file FP and return the line in an
+   malloced buffer.  Return NULL on error or EOF.  There is no
+   limitation os the line length.  The trailing linefeed has been
+   removed, the function will read the last line of a file, even if
+   that is not terminated by a LF. */
+static char *
+next_line_from_file (estream_t fp, gpg_error_t *r_err)
+{
+  char buf[300];
+  char *largebuf = NULL;
+  size_t buflen;
+  size_t len = 0;
+  unsigned char *p;
+  int c;
+  char *tmpbuf;
+
+  *r_err = 0;
+  p = buf;
+  buflen = sizeof buf - 1;
+  while ((c=es_getc (fp)) != EOF && c != '\n')
+    {
+      if (len >= buflen)
+        {
+          if (!largebuf)
+            {
+              buflen += 1024;
+              largebuf = xtrymalloc ( buflen + 1 );
+              if (!largebuf)
+                {
+                  *r_err = gpg_error_from_syserror ();
+                  return NULL;
+                }
+              memcpy (largebuf, buf, len);
+            }
+          else
+            {
+              buflen += 1024;
+              tmpbuf = xtryrealloc (largebuf, buflen + 1);
+              if (!tmpbuf)
+                {
+                  *r_err = gpg_error_from_syserror ();
+                  xfree (largebuf);
+                  return NULL;
+                }
+              largebuf = tmpbuf;
+            }
+          p = largebuf;
+        }
+      p[len++] = c;
+    }
+  if (c == EOF && !len)
+    return NULL;
+  p[len] = 0;
+
+  if (largebuf)
+    tmpbuf = xtryrealloc (largebuf, len+1);
+  else
+    tmpbuf = xtrystrdup (buf);
+  if (!tmpbuf)
+    {
+      *r_err = gpg_error_from_syserror ();
+      xfree (largebuf);
+    }
+  return tmpbuf;
+}
+
+
+/* Release one cache entry.  */
+static void
+release_one_cache_entry (crl_cache_entry_t entry)
+{
+  if (entry)
+    {
+      if (entry->cdb)
+        {
+          int fd = cdb_fileno (entry->cdb);
+          cdb_free (entry->cdb);
+          xfree (entry->cdb);
+          if (close (fd))
+            log_error (_("error closing cache file: %s\n"), strerror(errno));
+        }
+      xfree (entry->release_ptr);
+      xfree (entry->check_trust_anchor);
+      xfree (entry);
+    }
+}
+
+
+/* Release the CACHE object. */
+static void
+release_cache (crl_cache_t cache)
+{
+  crl_cache_entry_t entry, entry2;
+
+  if (!cache)
+    return;
+
+  for (entry = cache->entries; entry; entry = entry2)
+    {
+      entry2 = entry->next;
+      release_one_cache_entry (entry);
+    }
+  cache->entries = NULL;
+  xfree (cache);
+}
+
+
+/* Open the dir file FNAME or create a new one if it does not yet
+   exist. */
+static estream_t
+open_dir_file (const char *fname)
+{
+  estream_t fp;
+
+  fp = es_fopen (fname, "r");
+  if (!fp)
+    {
+      log_error (_("failed to open cache dir file '%s': %s\n"),
+                 fname, strerror (errno));
+
+      /* Make sure that the directory exists, try to create if otherwise. */
+      if (create_directory_if_needed (NULL)
+          || create_directory_if_needed (DBDIR_D))
+        return NULL;
+      fp = es_fopen (fname, "w");
+      if (!fp)
+        {
+          log_error (_("error creating new cache dir file '%s': %s\n"),
+                     fname, strerror (errno));
+          return NULL;
+        }
+      es_fprintf (fp, "v:%d:\n", DBDIRVERSION);
+      if (es_ferror (fp))
+        {
+          log_error (_("error writing new cache dir file '%s': %s\n"),
+                     fname, strerror (errno));
+          es_fclose (fp);
+          return NULL;
+        }
+      if (es_fclose (fp))
+        {
+          log_error (_("error closing new cache dir file '%s': %s\n"),
+                     fname, strerror (errno));
+          return NULL;
+        }
+
+      log_info (_("new cache dir file '%s' created\n"), fname);
+
+      fp = es_fopen (fname, "r");
+      if (!fp)
+        {
+          log_error (_("failed to re-open cache dir file '%s': %s\n"),
+                     fname, strerror (errno));
+          return NULL;
+        }
+    }
+
+  return fp;
+}
+
+/* Helper for open_dir. */
+static gpg_error_t
+check_dir_version (estream_t *fpadr, const char *fname,
+                         unsigned int *lineno,
+                         int cleanup_on_mismatch)
+{
+  char *line;
+  gpg_error_t lineerr = 0;
+  estream_t fp = *fpadr;
+  int created = 0;
+
+ retry:
+  while ((line = next_line_from_file (fp, &lineerr)))
+    {
+      ++*lineno;
+      if (*line == 'v' && line[1] == ':')
+        break;
+      else if (*line != '#')
+        {
+          log_error (_("first record of '%s' is not the version\n"), fname);
+          xfree (line);
+          return gpg_error (GPG_ERR_CONFIGURATION);
+        }
+      xfree (line);
+    }
+  if (lineerr)
+    return lineerr;
+
+  if (strtol (line+2, NULL, 10) != DBDIRVERSION)
+    {
+      if (!created && cleanup_on_mismatch)
+        {
+          log_error (_("old version of cache directory - cleaning up\n"));
+          es_fclose (fp);
+          *fpadr = NULL;
+          if (!cleanup_cache_dir (1))
+            {
+              *lineno = 0;
+              fp = *fpadr = open_dir_file (fname);
+              if (!fp)
+                {
+                  xfree (line);
+                  return gpg_error (GPG_ERR_CONFIGURATION);
+                }
+              created = 1;
+              goto retry;
+            }
+        }
+      log_error (_("old version of cache directory - giving up\n"));
+      xfree (line);
+      return gpg_error (GPG_ERR_CONFIGURATION);
+    }
+  xfree (line);
+  return 0;
+}
+
+
+/* Open the dir file and read in all available information.  Store
+   that in a newly allocated cache object and return that if
+   everything worked out fine.  Create the cache directory and the dir
+   if it does not yet exist.  Remove all files in that directory if
+   the version does not match. */
+static gpg_error_t
+open_dir (crl_cache_t *r_cache)
+{
+  crl_cache_t cache;
+  char *fname;
+  char *line = NULL;
+  gpg_error_t lineerr = 0;
+  estream_t fp;
+  crl_cache_entry_t entry, *entrytail;
+  unsigned int lineno;
+  gpg_error_t err = 0;
+  int anyerr = 0;
+
+  cache = xtrycalloc (1, sizeof *cache);
+  if (!cache)
+    return gpg_error_from_syserror ();
+
+  fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL);
+
+  lineno = 0;
+  fp = open_dir_file (fname);
+  if (!fp)
+    {
+      err = gpg_error (GPG_ERR_CONFIGURATION);
+      goto leave;
+    }
+
+  err = check_dir_version (&fp, fname, &lineno, 1);
+  if (err)
+    goto leave;
+
+
+  /* Read in all supported entries from the dir file. */
+  cache->entries = NULL;
+  entrytail = &cache->entries;
+  xfree (line);
+  while ((line = next_line_from_file (fp, &lineerr)))
+    {
+      int fieldno;
+      char *p, *endp;
+
+      lineno++;
+      if ( *line == 'c' || *line == 'u' || *line == 'i' )
+        {
+          entry = xtrycalloc (1, sizeof *entry);
+          if (!entry)
+            {
+              err = gpg_error_from_syserror ();
+              goto leave;
+            }
+          entry->lineno = lineno;
+          entry->release_ptr = line;
+          if (*line == 'i')
+            {
+              entry->invalid = atoi (line+1);
+              if (entry->invalid < 1)
+                entry->invalid = 1;
+            }
+          else if (*line == 'u')
+            entry->user_trust_req = 1;
+
+          for (fieldno=1, p = line; p; p = endp, fieldno++)
+            {
+              endp = strchr (p, ':');
+              if (endp)
+                *endp++ = '\0';
+
+              switch (fieldno)
+                {
+                case 1: /* record type */ break;
+                case 2: entry->issuer_hash = p; break;
+                case 3: entry->issuer = unpercent_string (p); break;
+                case 4: entry->url = unpercent_string (p); break;
+                case 5:
+                 strncpy (entry->this_update, p, 15);
+                 entry->this_update[15] = 0;
+                 break;
+                case 6:
+                 strncpy (entry->next_update, p, 15);
+                 entry->next_update[15] = 0;
+                 break;
+                case 7: entry->dbfile_hash = p; break;
+                case 8: if (*p) entry->crl_number = p; break;
+                case 9:
+                  if (*p)
+                    entry->authority_issuer = unpercent_string (p);
+                  break;
+                case 10:
+                  if (*p)
+                    entry->authority_serialno = unpercent_string (p);
+                  break;
+                case 11:
+                  if (*p)
+                    entry->check_trust_anchor = xtrystrdup (p);
+                  break;
+                default:
+                  if (*p)
+                    log_info (_("extra field detected in crl record of "
+                                "'%s' line %u\n"), fname, lineno);
+                  break;
+                }
+            }
+
+          if (!entry->issuer_hash)
+            {
+              log_info (_("invalid line detected in '%s' line %u\n"),
+                        fname, lineno);
+              xfree (entry);
+              entry = NULL;
+            }
+          else if (find_entry (cache->entries, entry->issuer_hash))
+            {
+              /* Fixme: The duplicate checking used is not very
+                 effective for large numbers of issuers. */
+              log_info (_("duplicate entry detected in '%s' line %u\n"),
+                        fname, lineno);
+              xfree (entry);
+              entry = NULL;
+            }
+          else
+            {
+              line = NULL;
+              *entrytail = entry;
+              entrytail = &entry->next;
+            }
+        }
+      else if (*line == '#')
+        ;
+      else
+        log_info (_("unsupported record type in '%s' line %u skipped\n"),
+                  fname, lineno);
+
+      if (line)
+        xfree (line);
+    }
+  if (lineerr)
+    {
+      err = lineerr;
+      log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
+      goto leave;
+    }
+  if (es_ferror (fp))
+    {
+      log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
+      err = gpg_error (GPG_ERR_CONFIGURATION);
+      goto leave;
+    }
+
+  /* Now do some basic checks on the data. */
+  for (entry = cache->entries; entry; entry = entry->next)
+    {
+      assert (entry->lineno);
+      if (strlen (entry->issuer_hash) != 40)
+        {
+          anyerr++;
+          log_error (_("invalid issuer hash in '%s' line %u\n"),
+                     fname, entry->lineno);
+        }
+      else if ( !*entry->issuer )
+        {
+          anyerr++;
+          log_error (_("no issuer DN in '%s' line %u\n"),
+                     fname, entry->lineno);
+        }
+      else if ( check_isotime (entry->this_update)
+                || check_isotime (entry->next_update))
+        {
+          anyerr++;
+          log_error (_("invalid timestamp in '%s' line %u\n"),
+                     fname, entry->lineno);
+        }
+
+      /* Checks not leading to an immediate fail. */
+      if (strlen (entry->dbfile_hash) != 32)
+        log_info (_("WARNING: invalid cache file hash in '%s' line %u\n"),
+                  fname, entry->lineno);
+    }
+
+  if (anyerr)
+    {
+      log_error (_("detected errors in cache dir file\n"));
+      log_info (_("please check the reason and manually delete that file\n"));
+      err = gpg_error (GPG_ERR_CONFIGURATION);
+    }
+
+
+ leave:
+  es_fclose (fp);
+  xfree (line);
+  xfree (fname);
+  if (err)
+    {
+      release_cache (cache);
+      cache = NULL;
+    }
+  *r_cache = cache;
+  return err;
+}
+
+static void
+write_percented_string (const char *s, estream_t fp)
+{
+  for (; *s; s++)
+    if (*s == ':')
+      es_fputs ("%3A", fp);
+    else if (*s == '\n')
+      es_fputs ("%0A", fp);
+    else if (*s == '\r')
+      es_fputs ("%0D", fp);
+    else
+      es_putc (*s, fp);
+}
+
+
+static void
+write_dir_line_crl (estream_t fp, crl_cache_entry_t e)
+{
+  if (e->invalid)
+    es_fprintf (fp, "i%d", e->invalid);
+  else if (e->user_trust_req)
+    es_putc ('u', fp);
+  else
+    es_putc ('c', fp);
+  es_putc (':', fp);
+  es_fputs (e->issuer_hash, fp);
+  es_putc (':', fp);
+  write_percented_string (e->issuer, fp);
+  es_putc (':', fp);
+  write_percented_string (e->url, fp);
+  es_putc (':', fp);
+  es_fwrite (e->this_update, 15, 1, fp);
+  es_putc (':', fp);
+  es_fwrite (e->next_update, 15, 1, fp);
+  es_putc (':', fp);
+  es_fputs (e->dbfile_hash, fp);
+  es_putc (':', fp);
+  if (e->crl_number)
+    es_fputs (e->crl_number, fp);
+  es_putc (':', fp);
+  if (e->authority_issuer)
+    write_percented_string (e->authority_issuer, fp);
+  es_putc (':', fp);
+  if (e->authority_serialno)
+    es_fputs (e->authority_serialno, fp);
+  es_putc (':', fp);
+  if (e->check_trust_anchor && e->user_trust_req)
+    es_fputs (e->check_trust_anchor, fp);
+  es_putc ('\n', fp);
+}
+
+
+/* Update the current dir file using the cache. */
+static gpg_error_t
+update_dir (crl_cache_t cache)
+{
+  char *fname = NULL;
+  char *tmpfname = NULL;
+  char *line = NULL;
+  gpg_error_t lineerr = 0;
+  estream_t fp;
+  estream_t fpout = NULL;
+  crl_cache_entry_t e;
+  unsigned int lineno;
+  gpg_error_t err = 0;
+
+  fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL);
+
+  /* Fixme: Take an update file lock here. */
+
+  for (e= cache->entries; e; e = e->next)
+    e->mark = 1;
+
+  lineno = 0;
+  fp = es_fopen (fname, "r");
+  if (!fp)
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("failed to open cache dir file '%s': %s\n"),
+                 fname, strerror (errno));
+      goto leave;
+    }
+  err = check_dir_version (&fp, fname, &lineno, 0);
+  if (err)
+    goto leave;
+  es_rewind (fp);
+  lineno = 0;
+
+  /* Create a temporary DIR file. */
+  {
+    char *tmpbuf, *p;
+    const char *nodename;
+#ifndef HAVE_W32_SYSTEM
+    struct utsname utsbuf;
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+    nodename = "unknown";
+#else
+    if (uname (&utsbuf))
+      nodename = "unknown";
+    else
+      nodename = utsbuf.nodename;
+#endif
+
+    gpgrt_asprintf (&tmpbuf, "DIR-tmp-%s-%u-%p.txt.tmp",
+                    nodename, (unsigned int)getpid (), &tmpbuf);
+    if (!tmpbuf)
+      {
+        err = gpg_error_from_errno (errno);
+        log_error (_("failed to create temporary cache dir file '%s': %s\n"),
+                   tmpfname, strerror (errno));
+        goto leave;
+      }
+    for (p=tmpbuf; *p; p++)
+      if (*p == '/')
+        *p = '.';
+    tmpfname = make_filename (opt.homedir_cache, DBDIR_D, tmpbuf, NULL);
+    xfree (tmpbuf);
+  }
+  fpout = es_fopen (tmpfname, "w");
+  if (!fpout)
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("failed to create temporary cache dir file '%s': %s\n"),
+                 tmpfname, strerror (errno));
+      goto leave;
+    }
+
+  while ((line = next_line_from_file (fp, &lineerr)))
+    {
+      lineno++;
+      if (*line == 'c' || *line == 'u' || *line == 'i')
+        {
+          /* Extract the issuer hash field. */
+          char *fieldp, *endp;
+
+          fieldp = strchr (line, ':');
+          endp = fieldp? strchr (++fieldp, ':') : NULL;
+          if (endp)
+            {
+              /* There should be no percent within the issuer hash
+                 field, thus we can compare it pretty easily. */
+              *endp = 0;
+              e = find_entry ( cache->entries, fieldp);
+              *endp = ':'; /* Restore orginal line. */
+              if (e && e->deleted)
+                {
+                  /* Marked for deletion, so don't write it. */
+                  e->mark = 0;
+                }
+              else if (e)
+                {
+                  /* Yep, this is valid entry we know about; write it out */
+                  write_dir_line_crl (fpout, e);
+                  e->mark = 0;
+                }
+              else
+                { /* We ignore entries we don't have in our cache
+                     because they may have been added in the meantime
+                     by other instances of dirmngr. */
+                  es_fprintf (fpout, "# Next line added by "
+                              "another process; our pid is %lu\n",
+                              (unsigned long)getpid ());
+                  es_fputs (line, fpout);
+                  es_putc ('\n', fpout);
+                }
+            }
+          else
+            {
+              es_fputs ("# Invalid line detected: ", fpout);
+              es_fputs (line, fpout);
+              es_putc ('\n', fpout);
+            }
+        }
+      else
+        {
+          /* Write out all non CRL lines as they are. */
+          es_fputs (line, fpout);
+          es_putc ('\n', fpout);
+        }
+
+      xfree (line);
+    }
+  if (!es_ferror (fp) && !es_ferror (fpout) && !lineerr)
+    {
+      /* Write out the remaining entries. */
+      for (e= cache->entries; e; e = e->next)
+        if (e->mark)
+          {
+            if (!e->deleted)
+              write_dir_line_crl (fpout, e);
+            e->mark = 0;
+          }
+    }
+  if (lineerr)
+    {
+      err = lineerr;
+      log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
+      goto leave;
+    }
+  if (es_ferror (fp))
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
+    }
+  if (es_ferror (fpout))
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("error writing '%s': %s\n"), tmpfname, strerror (errno));
+    }
+  if (err)
+    goto leave;
+
+  /* Rename the files. */
+  es_fclose (fp);
+  fp = NULL;
+  if (es_fclose (fpout))
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("error closing '%s': %s\n"), tmpfname, strerror (errno));
+      goto leave;
+    }
+  fpout = NULL;
+
+#ifdef HAVE_W32_SYSTEM
+  /* No atomic mv on W32 systems.  */
+  gnupg_remove (fname);
+#endif
+  if (rename (tmpfname, fname))
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("error renaming '%s' to '%s': %s\n"),
+                 tmpfname, fname, strerror (errno));
+      goto leave;
+    }
+
+ leave:
+  /* Fixme: Relinquish update lock. */
+  xfree (line);
+  es_fclose (fp);
+  xfree (fname);
+  if (fpout)
+    {
+      es_fclose (fpout);
+      if (err && tmpfname)
+        gnupg_remove (tmpfname);
+    }
+  xfree (tmpfname);
+  return err;
+}
+
+
+
+
+/* Create the filename for the cache file from the 40 byte ISSUER_HASH
+   string. Caller must release the return string. */
+static char *
+make_db_file_name (const char *issuer_hash)
+{
+  char bname[50];
+
+  assert (strlen (issuer_hash) == 40);
+  memcpy (bname, "crl-", 4);
+  memcpy (bname + 4, issuer_hash, 40);
+  strcpy (bname + 44, ".db");
+  return make_filename (opt.homedir_cache, DBDIR_D, bname, NULL);
+}
+
+
+/* Hash the file FNAME and return the MD5 digest in MD5BUFFER. The
+   caller must allocate MD%buffer wityh at least 16 bytes. Returns 0
+   on success. */
+static int
+hash_dbfile (const char *fname, unsigned char *md5buffer)
+{
+  estream_t fp;
+  char *buffer;
+  size_t n;
+  gcry_md_hd_t md5;
+  gpg_err_code_t err;
+
+  buffer = xtrymalloc (65536);
+  fp = buffer? es_fopen (fname, "rb") : NULL;
+  if (!fp)
+    {
+      log_error (_("can't hash '%s': %s\n"), fname, strerror (errno));
+      xfree (buffer);
+      return -1;
+    }
+
+  err = gcry_md_open (&md5, GCRY_MD_MD5, 0);
+  if (err)
+    {
+      log_error (_("error setting up MD5 hash context: %s\n"),
+                 gpg_strerror (err));
+      xfree (buffer);
+      es_fclose (fp);
+      return -1;
+    }
+
+  /* We better hash some information about the cache file layout in. */
+  sprintf (buffer, "%.100s/%.100s:%d", DBDIR_D, DBDIRFILE, DBDIRVERSION);
+  gcry_md_write (md5, buffer, strlen (buffer));
+
+  for (;;)
+    {
+      n = es_fread (buffer, 1, 65536, fp);
+      if (n < 65536 && es_ferror (fp))
+        {
+          log_error (_("error hashing '%s': %s\n"), fname, strerror (errno));
+          xfree (buffer);
+          es_fclose (fp);
+          gcry_md_close (md5);
+          return -1;
+        }
+      if (!n)
+        break;
+      gcry_md_write (md5, buffer, n);
+    }
+  es_fclose (fp);
+  xfree (buffer);
+  gcry_md_final (md5);
+
+  memcpy (md5buffer, gcry_md_read (md5, GCRY_MD_MD5), 16);
+  gcry_md_close (md5);
+  return 0;
+}
+
+/* Compare the file FNAME against the dexified MD5 hash MD5HASH and
+   return 0 if they match. */
+static int
+check_dbfile (const char *fname, const char *md5hexvalue)
+{
+  unsigned char buffer1[16], buffer2[16];
+
+  if (strlen (md5hexvalue) != 32)
+    {
+      log_error (_("invalid formatted checksum for '%s'\n"), fname);
+      return -1;
+    }
+  unhexify (buffer1, md5hexvalue);
+
+  if (hash_dbfile (fname, buffer2))
+    return -1;
+
+  return memcmp (buffer1, buffer2, 16);
+}
+
+
+/* Open the cache file for ENTRY.  This function implements a caching
+   strategy and might close unused cache files. It is required to use
+   unlock_db_file after using the file. */
+static struct cdb *
+lock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
+{
+  char *fname;
+  int fd;
+  int open_count;
+  crl_cache_entry_t e;
+
+  if (entry->cdb)
+    {
+      entry->cdb_use_count++;
+      return entry->cdb;
+    }
+
+  for (open_count = 0, e = cache->entries; e; e = e->next)
+    {
+      if (e->cdb)
+        open_count++;
+/*       log_debug ("CACHE: cdb=%p use_count=%u lru_count=%u\n", */
+/*                  e->cdb,e->cdb_use_count,e->cdb_lru_count); */
+    }
+
+  /* If there are too many file open, find the least recent used DB
+     file and close it.  Note that for Pth thread safeness we need to
+     use a loop here. */
+  while (open_count >= MAX_OPEN_DB_FILES )
+    {
+      crl_cache_entry_t last_e = NULL;
+      unsigned int last_lru = (unsigned int)(-1);
+
+      for (e = cache->entries; e; e = e->next)
+        if (e->cdb && !e->cdb_use_count && e->cdb_lru_count < last_lru)
+          {
+            last_lru = e->cdb_lru_count;
+            last_e = e;
+          }
+      if (!last_e)
+        {
+          log_error (_("too many open cache files; can't open anymore\n"));
+          return NULL;
+        }
+
+/*       log_debug ("CACHE: closing file at cdb=%p\n", last_e->cdb); */
+
+      fd = cdb_fileno (last_e->cdb);
+      cdb_free (last_e->cdb);
+      xfree (last_e->cdb);
+      last_e->cdb = NULL;
+      if (close (fd))
+        log_error (_("error closing cache file: %s\n"), strerror(errno));
+      open_count--;
+    }
+
+
+  fname = make_db_file_name (entry->issuer_hash);
+  if (opt.verbose)
+    log_info (_("opening cache file '%s'\n"), fname );
+
+  if (!entry->dbfile_checked)
+    {
+      if (!check_dbfile (fname, entry->dbfile_hash))
+        entry->dbfile_checked = 1;
+      /* Note, in case of an error we don't print an error here but
+         let require the caller to do that check. */
+    }
+
+  entry->cdb = xtrycalloc (1, sizeof *entry->cdb);
+  if (!entry->cdb)
+    {
+      xfree (fname);
+      return NULL;
+    }
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      log_error (_("error opening cache file '%s': %s\n"),
+                 fname, strerror (errno));
+      xfree (entry->cdb);
+      entry->cdb = NULL;
+      xfree (fname);
+      return NULL;
+    }
+  if (cdb_init (entry->cdb, fd))
+    {
+      log_error (_("error initializing cache file '%s' for reading: %s\n"),
+                 fname, strerror (errno));
+      xfree (entry->cdb);
+      entry->cdb = NULL;
+      close (fd);
+      xfree (fname);
+      return NULL;
+    }
+  xfree (fname);
+
+  entry->cdb_use_count = 1;
+  entry->cdb_lru_count = 0;
+
+  return entry->cdb;
+}
+
+/* Unlock a cache file, so that it can be reused. */
+static void
+unlock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
+{
+  if (!entry->cdb)
+    log_error (_("calling unlock_db_file on a closed file\n"));
+  else if (!entry->cdb_use_count)
+    log_error (_("calling unlock_db_file on an unlocked file\n"));
+  else
+    {
+      entry->cdb_use_count--;
+      entry->cdb_lru_count++;
+    }
+
+  /* If the entry was marked for deletion in the meantime do it now.
+     We do this for the sake of Pth thread safeness. */
+  if (!entry->cdb_use_count && entry->deleted)
+    {
+      crl_cache_entry_t eprev, enext;
+
+      enext = entry->next;
+      for (eprev = cache->entries;
+           eprev && eprev->next != entry; eprev = eprev->next)
+        ;
+      assert (eprev);
+      if (eprev == cache->entries)
+        cache->entries = enext;
+      else
+        eprev->next = enext;
+      /* FIXME: Do we leak ENTRY? */
+    }
+}
+
+
+/* Find ISSUER_HASH in our cache FIRST. This may be used to enumerate
+   the linked list we use to keep the CRLs of an issuer. */
+static crl_cache_entry_t
+find_entry (crl_cache_entry_t first, const char *issuer_hash)
+{
+  while (first && (first->deleted || strcmp (issuer_hash, first->issuer_hash)))
+    first = first->next;
+  return first;
+}
+
+
+/* Create a new CRL cache. This fucntion is usually called only once.
+   never fail. */
+void
+crl_cache_init(void)
+{
+  crl_cache_t cache = NULL;
+  gpg_error_t err;
+
+  if (current_cache)
+    {
+      log_error ("crl cache has already been initialized - not doing twice\n");
+      return;
+    }
+
+  err = open_dir (&cache);
+  if (err)
+    log_fatal (_("failed to create a new cache object: %s\n"),
+               gpg_strerror (err));
+  current_cache = cache;
+}
+
+
+/* Remove the cache information and all its resources.  Note that we
+   still keep the cache on disk. */
+void
+crl_cache_deinit (void)
+{
+  if (current_cache)
+    {
+      release_cache (current_cache);
+      current_cache = NULL;
+    }
+}
+
+
+/* Delete the cache from disk. Return 0 on success.*/
+int
+crl_cache_flush (void)
+{
+  int rc;
+
+  rc = cleanup_cache_dir (0)? -1 : 0;
+
+  return rc;
+}
+
+
+/* Check whether the certificate identified by ISSUER_HASH and
+   SN/SNLEN is valid; i.e. not listed in our cache.  With
+   FORCE_REFRESH set to true, a new CRL will be retrieved even if the
+   cache has not yet expired.  We use a 30 minutes threshold here so
+   that invoking this function several times won't load the CRL over
+   and over.  */
+static crl_cache_result_t
+cache_isvalid (ctrl_t ctrl, const char *issuer_hash,
+               const unsigned char *sn, size_t snlen,
+               int force_refresh)
+{
+  crl_cache_t cache = get_current_cache ();
+  crl_cache_result_t retval;
+  struct cdb *cdb;
+  int rc;
+  crl_cache_entry_t entry;
+  gnupg_isotime_t current_time;
+  size_t n;
+
+  (void)ctrl;
+
+  entry = find_entry (cache->entries, issuer_hash);
+  if (!entry)
+    {
+      log_info (_("no CRL available for issuer id %s\n"), issuer_hash );
+      return CRL_CACHE_DONTKNOW;
+    }
+
+  gnupg_get_isotime (current_time);
+  if (strcmp (entry->next_update, current_time) < 0 )
+    {
+      log_info (_("cached CRL for issuer id %s too old; update required\n"),
+                issuer_hash);
+      return CRL_CACHE_DONTKNOW;
+    }
+  if (force_refresh)
+    {
+      gnupg_isotime_t tmptime;
+
+      if (*entry->last_refresh)
+        {
+          gnupg_copy_time (tmptime, entry->last_refresh);
+          add_seconds_to_isotime (tmptime, 30 * 60);
+          if (strcmp (tmptime, current_time) < 0 )
+            {
+              log_info (_("force-crl-refresh active and %d minutes passed for"
+                          " issuer id %s; update required\n"),
+                        30, issuer_hash);
+              return CRL_CACHE_DONTKNOW;
+            }
+        }
+      else
+        {
+          log_info (_("force-crl-refresh active for"
+                      " issuer id %s; update required\n"),
+                    issuer_hash);
+          return CRL_CACHE_DONTKNOW;
+        }
+    }
+
+  if (entry->invalid)
+    {
+      log_info (_("available CRL for issuer ID %s can't be used\n"),
+                issuer_hash);
+      return CRL_CACHE_CANTUSE;
+    }
+
+  cdb = lock_db_file (cache, entry);
+  if (!cdb)
+    return CRL_CACHE_DONTKNOW; /* Hmmm, not the best error code. */
+
+  if (!entry->dbfile_checked)
+    {
+      log_error (_("cached CRL for issuer id %s tampered; we need to update\n")
+                 , issuer_hash);
+      unlock_db_file (cache, entry);
+      return CRL_CACHE_DONTKNOW;
+    }
+
+  rc = cdb_find (cdb, sn, snlen);
+  if (rc == 1)
+    {
+      n = cdb_datalen (cdb);
+      if (n != 16)
+        {
+          log_error (_("WARNING: invalid cache record length for S/N "));
+          log_printhex ("", sn, snlen);
+        }
+      else if (opt.verbose)
+        {
+          unsigned char record[16];
+          char *tmp = hexify_data (sn, snlen);
+
+          if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
+            log_error (_("problem reading cache record for S/N %s: %s\n"),
+                       tmp, strerror (errno));
+          else
+            log_info (_("S/N %s is not valid; reason=%02X  date=%.15s\n"),
+                      tmp, *record, record+1);
+          xfree (tmp);
+        }
+      retval = CRL_CACHE_INVALID;
+    }
+  else if (!rc)
+    {
+      if (opt.verbose)
+        {
+          char *serialno = hexify_data (sn, snlen);
+          log_info (_("S/N %s is valid, it is not listed in the CRL\n"),
+                    serialno );
+          xfree (serialno);
+        }
+      retval = CRL_CACHE_VALID;
+    }
+  else
+    {
+      log_error (_("error getting data from cache file: %s\n"),
+                 strerror (errno));
+      retval = CRL_CACHE_DONTKNOW;
+    }
+
+
+  if (entry->user_trust_req
+      && (retval == CRL_CACHE_VALID || retval == CRL_CACHE_INVALID))
+    {
+      if (!entry->check_trust_anchor)
+        {
+          log_error ("inconsistent data on user trust check\n");
+          retval = CRL_CACHE_CANTUSE;
+        }
+      else if (get_istrusted_from_client (ctrl, entry->check_trust_anchor))
+        {
+          if (opt.verbose)
+            log_info ("no system trust and client does not trust either\n");
+          retval = CRL_CACHE_CANTUSE;
+        }
+      else
+        {
+          /* Okay, the CRL is considered valid by the client and thus
+             we can return the result as is.  */
+        }
+    }
+
+  unlock_db_file (cache, entry);
+
+  return retval;
+}
+
+
+/* Check whether the certificate identified by ISSUER_HASH and
+   SERIALNO is valid; i.e. not listed in our cache.  With
+   FORCE_REFRESH set to true, a new CRL will be retrieved even if the
+   cache has not yet expired.  We use a 30 minutes threshold here so
+   that invoking this function several times won't load the CRL over
+   and over.  */
+crl_cache_result_t
+crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno,
+                   int force_refresh)
+{
+  crl_cache_result_t result;
+  unsigned char snbuf_buffer[50];
+  unsigned char *snbuf;
+  size_t n;
+
+  n = strlen (serialno)/2+1;
+  if (n < sizeof snbuf_buffer - 1)
+    snbuf = snbuf_buffer;
+  else
+    {
+      snbuf = xtrymalloc (n);
+      if (!snbuf)
+        return CRL_CACHE_DONTKNOW;
+    }
+
+  n = unhexify (snbuf, serialno);
+
+  result = cache_isvalid (ctrl, issuer_hash, snbuf, n, force_refresh);
+
+  if (snbuf != snbuf_buffer)
+    xfree (snbuf);
+
+  return result;
+}
+
+
+/* Check whether the certificate CERT is valid; i.e. not listed in our
+   cache.  With FORCE_REFRESH set to true, a new CRL will be retrieved
+   even if the cache has not yet expired.  We use a 30 minutes
+   threshold here so that invoking this function several times won't
+   load the CRL over and over.  */
+gpg_error_t
+crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
+                        int force_refresh)
+{
+  gpg_error_t err;
+  crl_cache_result_t result;
+  unsigned char issuerhash[20];
+  char issuerhash_hex[41];
+  ksba_sexp_t serial;
+  unsigned char *sn;
+  size_t snlen;
+  char *endp, *tmp;
+  int i;
+
+  /* Compute the hash value of the issuer name.  */
+  tmp = ksba_cert_get_issuer (cert, 0);
+  if (!tmp)
+    {
+      log_error ("oops: issuer missing in certificate\n");
+      return gpg_error (GPG_ERR_INV_CERT_OBJ);
+    }
+  gcry_md_hash_buffer (GCRY_MD_SHA1, issuerhash, tmp, strlen (tmp));
+  xfree (tmp);
+  for (i=0,tmp=issuerhash_hex; i < 20; i++, tmp += 2)
+    sprintf (tmp, "%02X", issuerhash[i]);
+
+  /* Get the serial number.  */
+  serial = ksba_cert_get_serial (cert);
+  if (!serial)
+    {
+      log_error ("oops: S/N missing in certificate\n");
+      return gpg_error (GPG_ERR_INV_CERT_OBJ);
+    }
+  sn = serial;
+  if (*sn != '(')
+    {
+      log_error ("oops: invalid S/N\n");
+      xfree (serial);
+      return gpg_error (GPG_ERR_INV_CERT_OBJ);
+    }
+  sn++;
+  snlen = strtoul (sn, &endp, 10);
+  sn = endp;
+  if (*sn != ':')
+    {
+      log_error ("oops: invalid S/N\n");
+      xfree (serial);
+      return gpg_error (GPG_ERR_INV_CERT_OBJ);
+    }
+  sn++;
+
+  /* Check the cache.  */
+  result = cache_isvalid (ctrl, issuerhash_hex, sn, snlen, force_refresh);
+  switch (result)
+    {
+    case CRL_CACHE_VALID:
+      err = 0;
+      break;
+    case CRL_CACHE_INVALID:
+      err = gpg_error (GPG_ERR_CERT_REVOKED);
+      break;
+    case CRL_CACHE_DONTKNOW:
+      err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+    case CRL_CACHE_CANTUSE:
+      err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+      break;
+    default:
+      log_fatal ("cache_isvalid returned invalid status code %d\n", result);
+    }
+
+  xfree (serial);
+  return err;
+}
+
+
+/* Prepare a hash context for the signature verification.  Input is
+   the CRL and the output is the hash context MD as well as the uses
+   algorithm identifier ALGO. */
+static gpg_error_t
+start_sig_check (ksba_crl_t crl, gcry_md_hd_t *md, int *algo)
+{
+  gpg_error_t err;
+  const char *algoid;
+
+  algoid = ksba_crl_get_digest_algo (crl);
+  *algo = gcry_md_map_name (algoid);
+  if (!*algo)
+    {
+      log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
+      return gpg_error (GPG_ERR_DIGEST_ALGO);
+    }
+
+  err = gcry_md_open (md, *algo, 0);
+  if (err)
+    {
+      log_error (_("gcry_md_open for algorithm %d failed: %s\n"),
+                 *algo, gcry_strerror (err));
+      return err;
+    }
+  if (DBG_HASHING)
+    gcry_md_debug (*md, "hash.cert");
+
+  ksba_crl_set_hash_function (crl, HASH_FNC, *md);
+  return 0;
+}
+
+
+/* Finish a hash context and verify the signature.  This function
+   should return 0 on a good signature, GPG_ERR_BAD_SIGNATURE if the
+   signature does not verify or any other error code. CRL is the CRL
+   object we are working on, MD the hash context and ISSUER_CERT the
+   certificate of the CRL issuer.  This function closes MD.  */
+static gpg_error_t
+finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
+                  ksba_cert_t issuer_cert)
+{
+  gpg_error_t err;
+  ksba_sexp_t sigval = NULL, pubkey = NULL;
+  const char *s;
+  char algoname[50];
+  size_t n;
+  gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
+  unsigned int i;
+
+  /* This also stops debugging on the MD.  */
+  gcry_md_final (md);
+
+  /* Get and convert the signature value. */
+  sigval = ksba_crl_get_sig_val (crl);
+  n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
+  if (!n)
+    {
+      log_error (_("got an invalid S-expression from libksba\n"));
+      err = gpg_error (GPG_ERR_INV_SEXP);
+      goto leave;
+    }
+  err = gcry_sexp_sscan (&s_sig, NULL, sigval, n);
+  if (err)
+    {
+      log_error (_("converting S-expression failed: %s\n"),
+                 gcry_strerror (err));
+      goto leave;
+    }
+
+  /* Get and convert the public key for the issuer certificate. */
+  if (DBG_X509)
+    dump_cert ("crl_issuer_cert", issuer_cert);
+  pubkey = ksba_cert_get_public_key (issuer_cert);
+  n = gcry_sexp_canon_len (pubkey, 0, NULL, NULL);
+  if (!n)
+    {
+      log_error (_("got an invalid S-expression from libksba\n"));
+      err = gpg_error (GPG_ERR_INV_SEXP);
+      goto leave;
+    }
+  err = gcry_sexp_sscan (&s_pkey, NULL, pubkey, n);
+  if (err)
+    {
+      log_error (_("converting S-expression failed: %s\n"),
+                 gcry_strerror (err));
+      goto leave;
+    }
+
+  /* Create an S-expression with the actual hash value. */
+  s = gcry_md_algo_name (algo);
+  for (i = 0; *s && i < sizeof(algoname) - 1; s++, i++)
+    algoname[i] = ascii_tolower (*s);
+  algoname[i] = 0;
+  err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))",
+                         algoname,
+                         gcry_md_get_algo_dlen (algo), gcry_md_read (md, algo));
+  if (err)
+    {
+      log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
+      goto leave;
+    }
+
+  /* Pass this on to the signature verification. */
+  err = gcry_pk_verify (s_sig, s_hash, s_pkey);
+  if (DBG_X509)
+    log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
+
+ leave:
+  xfree (sigval);
+  xfree (pubkey);
+  gcry_sexp_release (s_sig);
+  gcry_sexp_release (s_hash);
+  gcry_sexp_release (s_pkey);
+  gcry_md_close (md);
+
+  return err;
+}
+
+
+/* Call this to match a start_sig_check that can not be completed
+   normally.  */
+static void
+abort_sig_check (ksba_crl_t crl, gcry_md_hd_t md)
+{
+  (void)crl;
+  gcry_md_close (md);
+}
+
+
+/* Workhorse of the CRL loading machinery.  The CRL is read using the
+   CRL object and stored in the data base file DB with the name FNAME
+   (only used for printing error messages).  That DB should be a
+   temporary one and not the actual one.  If the function fails the
+   caller should delete this temporary database file.  CTRL is
+   required to retrieve certificates using the general dirmngr
+   callback service.  R_CRLISSUER returns an allocated string with the
+   crl-issuer DN, THIS_UPDATE and NEXT_UPDATE are filled with the
+   corresponding data from the CRL.  Note that these values might get
+   set even if the CRL processing fails at a later step; thus the
+   caller should free *R_ISSUER even if the function returns with an
+   error.  R_TRUST_ANCHOR is set on exit to NULL or a string with the
+   hexified fingerprint of the root certificate, if checking this
+   certificate for trustiness is required.
+*/
+static int
+crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
+                  struct cdb_make *cdb, const char *fname,
+                  char **r_crlissuer,
+                  ksba_isotime_t thisupdate, ksba_isotime_t nextupdate,
+                  char **r_trust_anchor)
+{
+  gpg_error_t err;
+  ksba_stop_reason_t stopreason;
+  ksba_cert_t crlissuer_cert = NULL;
+  gcry_md_hd_t md = NULL;
+  int algo = 0;
+  size_t n;
+
+  (void)fname;
+
+  *r_crlissuer = NULL;
+  *thisupdate = *nextupdate = 0;
+  *r_trust_anchor = NULL;
+
+  /* Start of the KSBA parser loop. */
+  do
+    {
+      err = ksba_crl_parse (crl, &stopreason);
+      if (err)
+        {
+          log_error (_("ksba_crl_parse failed: %s\n"), gpg_strerror (err) );
+          goto failure;
+        }
+
+      switch (stopreason)
+        {
+        case KSBA_SR_BEGIN_ITEMS:
+          {
+            if (start_sig_check (crl, &md, &algo ))
+              goto failure;
+
+            err = ksba_crl_get_update_times (crl, thisupdate, nextupdate);
+            if (err)
+              {
+                log_error (_("error getting update times of CRL: %s\n"),
+                           gpg_strerror (err));
+                err = gpg_error (GPG_ERR_INV_CRL);
+                goto failure;
+              }
+
+            if (opt.verbose || !*nextupdate)
+              log_info (_("update times of this CRL: this=%s next=%s\n"),
+                        thisupdate, nextupdate);
+            if (!*nextupdate)
+              {
+                log_info (_("nextUpdate not given; "
+                            "assuming a validity period of one day\n"));
+                gnupg_copy_time (nextupdate, thisupdate);
+                add_seconds_to_isotime (nextupdate, 86400);
+              }
+          }
+          break;
+
+        case KSBA_SR_GOT_ITEM:
+          {
+            ksba_sexp_t serial;
+            const unsigned char *p;
+            ksba_isotime_t rdate;
+            ksba_crl_reason_t reason;
+            int rc;
+            unsigned char record[1+15];
+
+            err = ksba_crl_get_item (crl, &serial, rdate, &reason);
+            if (err)
+              {
+                log_error (_("error getting CRL item: %s\n"),
+                           gpg_strerror (err));
+                err = gpg_error (GPG_ERR_INV_CRL);
+                ksba_free (serial);
+                goto failure;
+              }
+            p = serial_to_buffer (serial, &n);
+            if (!p)
+              BUG ();
+            record[0] = (reason & 0xff);
+            memcpy (record+1, rdate, 15);
+            rc = cdb_make_add (cdb, p, n, record, 1+15);
+            if (rc)
+              {
+                err = gpg_error_from_errno (errno);
+                log_error (_("error inserting item into "
+                             "temporary cache file: %s\n"),
+                           strerror (errno));
+                goto failure;
+              }
+
+            ksba_free (serial);
+          }
+          break;
+
+        case KSBA_SR_END_ITEMS:
+          break;
+
+        case KSBA_SR_READY:
+          {
+            char *crlissuer;
+            ksba_name_t authid;
+            ksba_sexp_t authidsn;
+            ksba_sexp_t keyid;
+
+            /* We need to look for the issuer only after having read
+               all items.  The issuer itselfs comes before the items
+               but the optional authorityKeyIdentifier comes after the
+               items. */
+            err = ksba_crl_get_issuer (crl, &crlissuer);
+            if( err )
+              {
+                log_error (_("no CRL issuer found in CRL: %s\n"),
+                           gpg_strerror (err) );
+                err = gpg_error (GPG_ERR_INV_CRL);
+                goto failure;
+              }
+           /* Note: This should be released by ksba_free, not xfree.
+              May need a memory reallocation dance.  */
+            *r_crlissuer = crlissuer; /* (Do it here so we don't need
+                                         to free it later) */
+
+            if (!ksba_crl_get_auth_key_id (crl, &keyid, &authid, &authidsn))
+              {
+                const char *s;
+
+                if (opt.verbose)
+                  log_info (_("locating CRL issuer certificate by "
+                              "authorityKeyIdentifier\n"));
+
+                s = ksba_name_enum (authid, 0);
+                if (s && *authidsn)
+                  crlissuer_cert = find_cert_bysn (ctrl, s, authidsn);
+                if (!crlissuer_cert && keyid)
+                  crlissuer_cert = find_cert_bysubject (ctrl,
+                                                        crlissuer, keyid);
+
+                if (!crlissuer_cert)
+                  {
+                    log_info ("CRL issuer certificate ");
+                    if (keyid)
+                      {
+                        log_printf ("{");
+                        dump_serial (keyid);
+                        log_printf ("} ");
+                      }
+                    if (authidsn)
+                      {
+                        log_printf ("(#");
+                        dump_serial (authidsn);
+                        log_printf ("/");
+                        dump_string (s);
+                        log_printf (") ");
+                      }
+                    log_printf ("not found\n");
+                  }
+                ksba_name_release (authid);
+                xfree (authidsn);
+                xfree (keyid);
+              }
+            else
+              crlissuer_cert = find_cert_bysubject (ctrl, crlissuer, NULL);
+            err = 0;
+            if (!crlissuer_cert)
+              {
+                err = gpg_error (GPG_ERR_MISSING_CERT);
+                goto failure;
+              }
+
+            err = finish_sig_check (crl, md, algo, crlissuer_cert);
+            if (err)
+              {
+                log_error (_("CRL signature verification failed: %s\n"),
+                           gpg_strerror (err));
+                goto failure;
+              }
+           md = NULL;
+
+            err = validate_cert_chain (ctrl, crlissuer_cert, NULL,
+                                       VALIDATE_MODE_CRL_RECURSIVE,
+                                       r_trust_anchor);
+            if (err)
+              {
+                log_error (_("error checking validity of CRL "
+                             "issuer certificate: %s\n"),
+                           gpg_strerror (err));
+                goto failure;
+              }
+
+          }
+          break;
+
+        default:
+          log_debug ("crl_parse_insert: unknown stop reason\n");
+          err = gpg_error (GPG_ERR_BUG);
+          goto failure;
+        }
+    }
+  while (stopreason != KSBA_SR_READY);
+  assert (!err);
+
+
+ failure:
+  if (md)
+    abort_sig_check (crl, md);
+  ksba_cert_release (crlissuer_cert);
+  return err;
+}
+
+
+
+/* Return the crlNumber extension as an allocated hex string or NULL
+   if there is none. */
+static char *
+get_crl_number (ksba_crl_t crl)
+{
+  gpg_error_t err;
+  ksba_sexp_t number;
+  char *string;
+
+  err = ksba_crl_get_crl_number (crl, &number);
+  if (err)
+    return NULL;
+  string = serial_hex (number);
+  ksba_free (number);
+  return string;
+}
+
+
+/* Return the authorityKeyIdentifier or NULL if it is not available.
+   The issuer name may consists of several parts - they are delimted by
+   0x01. */
+static char *
+get_auth_key_id (ksba_crl_t crl, char **serialno)
+{
+  gpg_error_t err;
+  ksba_name_t name;
+  ksba_sexp_t sn;
+  int idx;
+  const char *s;
+  char *string;
+  size_t length;
+
+  *serialno = NULL;
+  err = ksba_crl_get_auth_key_id (crl, NULL, &name, &sn);
+  if (err)
+    return NULL;
+  *serialno = serial_hex (sn);
+  ksba_free (sn);
+
+  if (!name)
+    return xstrdup ("");
+
+  length = 0;
+  for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
+    {
+      char *p = ksba_name_get_uri (name, idx);
+      length += strlen (p?p:s) + 1;
+      xfree (p);
+    }
+  string = xtrymalloc (length+1);
+  if (string)
+    {
+      *string = 0;
+      for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
+        {
+          char *p = ksba_name_get_uri (name, idx);
+          if (*string)
+            strcat (string, "\x01");
+          strcat (string, p?p:s);
+          xfree (p);
+        }
+    }
+  ksba_name_release (name);
+  return string;
+}
+
+
+
+/* Insert the CRL retrieved using URL into the cache specified by
+   CACHE.  The CRL itself will be read from the stream FP and is
+   expected in binary format.
+
+   Called by:
+      crl_cache_load
+         cmd_loadcrl
+         --load-crl
+      crl_cache_reload_crl
+         cmd_isvalid
+         cmd_checkcrl
+      cmd_loadcrl
+      --fetch-crl
+
+ */
+gpg_error_t
+crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
+{
+  crl_cache_t cache = get_current_cache ();
+  gpg_error_t err, err2;
+  ksba_crl_t crl;
+  char *fname = NULL;
+  char *newfname = NULL;
+  struct cdb_make cdb;
+  int fd_cdb = -1;
+  char *issuer = NULL;
+  char *issuer_hash = NULL;
+  ksba_isotime_t thisupdate, nextupdate;
+  crl_cache_entry_t entry = NULL;
+  crl_cache_entry_t e;
+  gnupg_isotime_t current_time;
+  char *checksum = NULL;
+  int invalidate_crl = 0;
+  int idx;
+  const char *oid;
+  int critical;
+  char *trust_anchor = NULL;
+
+  /* FIXME: We should acquire a mutex for the URL, so that we don't
+     simultaneously enter the same CRL twice.  However this needs to be
+     interweaved with the checking function.*/
+
+  err2 = 0;
+
+  err = ksba_crl_new (&crl);
+  if (err)
+    {
+      log_error (_("ksba_crl_new failed: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  err = ksba_crl_set_reader (crl, reader);
+  if ( err )
+    {
+      log_error (_("ksba_crl_set_reader failed: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Create a temporary cache file to load the CRL into. */
+  {
+    char *tmpfname, *p;
+    const char *nodename;
+#ifndef HAVE_W32_SYSTEM
+    struct utsname utsbuf;
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+    nodename = "unknown";
+#else
+    if (uname (&utsbuf))
+      nodename = "unknown";
+    else
+      nodename = utsbuf.nodename;
+#endif
+
+    gpgrt_asprintf (&tmpfname, "crl-tmp-%s-%u-%p.db.tmp",
+                    nodename, (unsigned int)getpid (), &tmpfname);
+    if (!tmpfname)
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+    for (p=tmpfname; *p; p++)
+      if (*p == '/')
+        *p = '.';
+    fname = make_filename (opt.homedir_cache, DBDIR_D, tmpfname, NULL);
+    xfree (tmpfname);
+    if (!gnupg_remove (fname))
+      log_info (_("removed stale temporary cache file '%s'\n"), fname);
+    else if (errno != ENOENT)
+      {
+        err = gpg_error_from_syserror ();
+        log_error (_("problem removing stale temporary cache file '%s': %s\n"),
+                   fname, gpg_strerror (err));
+        goto leave;
+      }
+  }
+
+  fd_cdb = open (fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+  if (fd_cdb == -1)
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("error creating temporary cache file '%s': %s\n"),
+                 fname, strerror (errno));
+      goto leave;
+    }
+  cdb_make_start(&cdb, fd_cdb);
+
+  err = crl_parse_insert (ctrl, crl, &cdb, fname,
+                          &issuer, thisupdate, nextupdate, &trust_anchor);
+  if (err)
+    {
+      log_error (_("crl_parse_insert failed: %s\n"), gpg_strerror (err));
+      /* Error in cleanup ignored.  */
+      cdb_make_finish (&cdb);
+      goto leave;
+    }
+
+  /* Finish the database. */
+  if (cdb_make_finish (&cdb))
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("error finishing temporary cache file '%s': %s\n"),
+                 fname, strerror (errno));
+      goto leave;
+    }
+  if (close (fd_cdb))
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("error closing temporary cache file '%s': %s\n"),
+                 fname, strerror (errno));
+      goto leave;
+    }
+  fd_cdb = -1;
+
+
+  /* Create a checksum. */
+  {
+    unsigned char md5buf[16];
+
+    if (hash_dbfile (fname, md5buf))
+      {
+        err = gpg_error (GPG_ERR_CHECKSUM);
+        goto leave;
+      }
+    checksum = hexify_data (md5buf, 16);
+  }
+
+
+  /* Check whether that new CRL is still not expired. */
+  gnupg_get_isotime (current_time);
+  if (strcmp (nextupdate, current_time) < 0 )
+    {
+      if (opt.force)
+        log_info (_("WARNING: new CRL still too old; it expired on %s "
+                    "- loading anyway\n"),  nextupdate);
+      else
+        {
+          log_error (_("new CRL still too old; it expired on %s\n"),
+                     nextupdate);
+          if (!err2)
+            err2 = gpg_error (GPG_ERR_CRL_TOO_OLD);
+          invalidate_crl |= 1;
+        }
+    }
+
+  /* Check for unknown critical extensions. */
+  for (idx=0; !(err=ksba_crl_get_extension (crl, idx, &oid, &critical,
+                                              NULL, NULL)); idx++)
+    {
+      if (!critical
+          || !strcmp (oid, oidstr_authorityKeyIdentifier)
+          || !strcmp (oid, oidstr_crlNumber) )
+        continue;
+      log_error (_("unknown critical CRL extension %s\n"), oid);
+      if (!err2)
+        err2 = gpg_error (GPG_ERR_INV_CRL);
+      invalidate_crl |= 2;
+    }
+  if (gpg_err_code (err) == GPG_ERR_EOF
+      || gpg_err_code (err) == GPG_ERR_NO_DATA )
+    err = 0;
+  if (err)
+    {
+      log_error (_("error reading CRL extensions: %s\n"), gpg_strerror (err));
+      err = gpg_error (GPG_ERR_INV_CRL);
+    }
+
+
+  /* Create an hex encoded SHA-1 hash of the issuer DN to be
+     used as the key for the cache. */
+  issuer_hash = hashify_data (issuer, strlen (issuer));
+
+  /* Create an ENTRY. */
+  entry = xtrycalloc (1, sizeof *entry);
+  if (!entry)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  entry->release_ptr = xtrymalloc (strlen (issuer_hash) + 1
+                                   + strlen (issuer) + 1
+                                   + strlen (url) + 1
+                                   + strlen (checksum) + 1);
+  if (!entry->release_ptr)
+    {
+      err = gpg_error_from_syserror ();
+      xfree (entry);
+      entry = NULL;
+      goto leave;
+    }
+  entry->issuer_hash = entry->release_ptr;
+  entry->issuer = stpcpy (entry->issuer_hash, issuer_hash) + 1;
+  entry->url = stpcpy (entry->issuer, issuer) + 1;
+  entry->dbfile_hash = stpcpy (entry->url, url) + 1;
+  strcpy (entry->dbfile_hash, checksum);
+  gnupg_copy_time (entry->this_update, thisupdate);
+  gnupg_copy_time (entry->next_update, nextupdate);
+  gnupg_copy_time (entry->last_refresh, current_time);
+  entry->crl_number = get_crl_number (crl);
+  entry->authority_issuer = get_auth_key_id (crl, &entry->authority_serialno);
+  entry->invalid = invalidate_crl;
+  entry->user_trust_req = !!trust_anchor;
+  entry->check_trust_anchor = trust_anchor;
+  trust_anchor = NULL;
+
+  /* Check whether we already have an entry for this issuer and mark
+     it as deleted. We better use a loop, just in case duplicates got
+     somehow into the list. */
+  for (e = cache->entries; (e=find_entry (e, entry->issuer_hash)); e = e->next)
+    e->deleted = 1;
+
+  /* Rename the temporary DB to the real name. */
+  newfname = make_db_file_name (entry->issuer_hash);
+  if (opt.verbose)
+    log_info (_("creating cache file '%s'\n"), newfname);
+
+  /* Just in case close unused matching files.  Actually we need this
+     only under Windows but saving file descriptors is never bad.  */
+  {
+    int any;
+    do
+      {
+        any = 0;
+        for (e = cache->entries; e; e = e->next)
+          if (!e->cdb_use_count && e->cdb
+              && !strcmp (e->issuer_hash, entry->issuer_hash))
+            {
+              int fd = cdb_fileno (e->cdb);
+              cdb_free (e->cdb);
+              xfree (e->cdb);
+              e->cdb = NULL;
+              if (close (fd))
+                log_error (_("error closing cache file: %s\n"),
+                           strerror(errno));
+              any = 1;
+              break;
+            }
+      }
+    while (any);
+  }
+#ifdef HAVE_W32_SYSTEM
+  gnupg_remove (newfname);
+#endif
+  if (rename (fname, newfname))
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("problem renaming '%s' to '%s': %s\n"),
+                 fname, newfname, gpg_strerror (err));
+      goto leave;
+    }
+  xfree (fname); fname = NULL; /*(let the cleanup code not try to remove it)*/
+
+  /* Link the new entry in. */
+  entry->next = cache->entries;
+  cache->entries = entry;
+  entry = NULL;
+
+  err = update_dir (cache);
+  if (err)
+    {
+      log_error (_("updating the DIR file failed - "
+                   "cache entry will get lost with the next program start\n"));
+      err = 0; /* Keep on running. */
+    }
+
+
+ leave:
+  release_one_cache_entry (entry);
+  if (fd_cdb != -1)
+    close (fd_cdb);
+  if (fname)
+    {
+      gnupg_remove (fname);
+      xfree (fname);
+    }
+  xfree (newfname);
+  ksba_crl_release (crl);
+  xfree (issuer);
+  xfree (issuer_hash);
+  xfree (checksum);
+  xfree (trust_anchor);
+  return err ? err : err2;
+}
+
+
+/* Print one cached entry E in a human readable format to stream
+   FP. Return 0 on success. */
+static gpg_error_t
+list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp)
+{
+  struct cdb_find cdbfp;
+  struct cdb *cdb;
+  int rc;
+  int warn = 0;
+  const unsigned char *s;
+
+  es_fputs ("--------------------------------------------------------\n", fp );
+  es_fprintf (fp, _("Begin CRL dump (retrieved via %s)\n"), e->url );
+  es_fprintf (fp, " Issuer:\t%s\n", e->issuer );
+  es_fprintf (fp, " Issuer Hash:\t%s\n", e->issuer_hash );
+  es_fprintf (fp, " This Update:\t%s\n", e->this_update );
+  es_fprintf (fp, " Next Update:\t%s\n", e->next_update );
+  es_fprintf (fp, " CRL Number :\t%s\n", e->crl_number? e->crl_number: "none");
+  es_fprintf (fp, " AuthKeyId  :\t%s\n",
+              e->authority_serialno? e->authority_serialno:"none");
+  if (e->authority_serialno && e->authority_issuer)
+    {
+      es_fputs ("             \t", fp);
+      for (s=e->authority_issuer; *s; s++)
+        if (*s == '\x01')
+          es_fputs ("\n             \t", fp);
+        else
+          es_putc (*s, fp);
+      es_putc ('\n', fp);
+    }
+  es_fprintf (fp, " Trust Check:\t%s\n",
+              !e->user_trust_req? "[system]" :
+              e->check_trust_anchor? e->check_trust_anchor:"[missing]");
+
+  if ((e->invalid & 1))
+    es_fprintf (fp, _(" ERROR: The CRL will not be used "
+                      "because it was still too old after an update!\n"));
+  if ((e->invalid & 2))
+    es_fprintf (fp, _(" ERROR: The CRL will not be used "
+                      "due to an unknown critical extension!\n"));
+  if ((e->invalid & ~3))
+    es_fprintf (fp, _(" ERROR: The CRL will not be used\n"));
+
+  cdb = lock_db_file (cache, e);
+  if (!cdb)
+    return gpg_error (GPG_ERR_GENERAL);
+
+  if (!e->dbfile_checked)
+    es_fprintf (fp, _(" ERROR: This cached CRL may have been tampered with!\n"));
+
+  es_putc ('\n', fp);
+
+  rc = cdb_findinit (&cdbfp, cdb, NULL, 0);
+  while (!rc && (rc=cdb_findnext (&cdbfp)) > 0 )
+    {
+      unsigned char keyrecord[256];
+      unsigned char record[16];
+      int reason;
+      int any = 0;
+      cdbi_t n;
+      cdbi_t i;
+
+      rc = 0;
+      n = cdb_datalen (cdb);
+      if (n != 16)
+        {
+          log_error (_(" WARNING: invalid cache record length\n"));
+          warn = 1;
+          continue;
+        }
+
+      if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
+        {
+          log_error (_("problem reading cache record: %s\n"),
+                     strerror (errno));
+          warn = 1;
+          continue;
+        }
+
+      n = cdb_keylen (cdb);
+      if (n > sizeof keyrecord)
+        n = sizeof keyrecord;
+      if (cdb_read (cdb, keyrecord, n, cdb_keypos (cdb)))
+        {
+          log_error (_("problem reading cache key: %s\n"), strerror (errno));
+          warn = 1;
+          continue;
+        }
+
+      reason = *record;
+      es_fputs ("  ", fp);
+      for (i = 0; i < n; i++)
+        es_fprintf (fp, "%02X", keyrecord[i]);
+      es_fputs (":\t reasons( ", fp);
+
+      if (reason & KSBA_CRLREASON_UNSPECIFIED)
+        es_fputs( "unspecified ", fp ), any = 1;
+      if (reason & KSBA_CRLREASON_KEY_COMPROMISE )
+        es_fputs( "key_compromise ", fp ), any = 1;
+      if (reason & KSBA_CRLREASON_CA_COMPROMISE )
+        es_fputs( "ca_compromise ", fp ), any = 1;
+      if (reason & KSBA_CRLREASON_AFFILIATION_CHANGED )
+        es_fputs( "affiliation_changed ", fp ), any = 1;
+      if (reason & KSBA_CRLREASON_SUPERSEDED )
+        es_fputs( "superseeded", fp ), any = 1;
+      if (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION )
+        es_fputs( "cessation_of_operation", fp ), any = 1;
+      if (reason & KSBA_CRLREASON_CERTIFICATE_HOLD )
+        es_fputs( "certificate_hold", fp ), any = 1;
+      if (reason && !any)
+        es_fputs( "other", fp );
+
+      es_fprintf (fp, ") rdate: %.15s\n", record+1);
+    }
+  if (rc)
+    log_error (_("error reading cache entry from db: %s\n"), strerror (rc));
+
+  unlock_db_file (cache, e);
+  es_fprintf (fp, _("End CRL dump\n") );
+  es_putc ('\n', fp);
+
+  return (rc||warn)? gpg_error (GPG_ERR_GENERAL) : 0;
+}
+
+
+/* Print the contents of the CRL CACHE in a human readable format to
+   stream FP. */
+gpg_error_t
+crl_cache_list (estream_t fp)
+{
+  crl_cache_t cache = get_current_cache ();
+  crl_cache_entry_t entry;
+  gpg_error_t err = 0;
+
+  for (entry = cache->entries;
+       entry && !entry->deleted && !err;
+       entry = entry->next )
+    err = list_one_crl_entry (cache, entry, fp);
+
+  return err;
+}
+
+
+/* Load the CRL containing the file named FILENAME into our CRL cache. */
+gpg_error_t
+crl_cache_load (ctrl_t ctrl, const char *filename)
+{
+  gpg_error_t err;
+  estream_t fp;
+  ksba_reader_t reader;
+
+  fp = es_fopen (filename, "r");
+  if (!fp)
+    {
+      err = gpg_error_from_errno (errno);
+      log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
+      return err;
+    }
+
+  err = create_estream_ksba_reader (&reader, fp);
+  if (!err)
+    {
+      err = crl_cache_insert (ctrl, filename, reader);
+      ksba_reader_release (reader);
+    }
+  es_fclose (fp);
+  return err;
+}
+
+
+/* Locate the corresponding CRL for the certificate CERT, read and
+   verify the CRL and store it in the cache.  */
+gpg_error_t
+crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
+{
+  gpg_error_t err;
+  ksba_reader_t reader = NULL;
+  char *issuer = NULL;
+  ksba_name_t distpoint = NULL;
+  ksba_name_t issuername = NULL;
+  char *distpoint_uri = NULL;
+  char *issuername_uri = NULL;
+  int any_dist_point = 0;
+  int seq;
+
+  /* Loop over all distribution points, get the CRLs and put them into
+     the cache. */
+  if (opt.verbose)
+    log_info ("checking distribution points\n");
+  seq = 0;
+  while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++,
+                                                &distpoint,
+                                                &issuername, NULL )))
+    {
+      int name_seq;
+      gpg_error_t last_err = 0;
+
+      if (!distpoint && !issuername)
+        {
+          if (opt.verbose)
+            log_info ("no issuer name and no distribution point\n");
+          break; /* Not allowed; i.e. an invalid certificate.  We give
+                    up here and hope that the default method returns a
+                    suitable CRL. */
+        }
+
+      xfree (issuername_uri); issuername_uri = NULL;
+
+      /* Get the URIs.  We do this in a loop to iterate over all names
+         in the crlDP. */
+      for (name_seq=0; ksba_name_enum (distpoint, name_seq); name_seq++)
+        {
+          xfree (distpoint_uri); distpoint_uri = NULL;
+          distpoint_uri = ksba_name_get_uri (distpoint, name_seq);
+          if (!distpoint_uri)
+            continue;
+
+          if (!strncmp (distpoint_uri, "ldap:", 5)
+              || !strncmp (distpoint_uri, "ldaps:", 6))
+            {
+              if (opt.ignore_ldap_dp)
+                continue;
+            }
+          else if (!strncmp (distpoint_uri, "http:", 5)
+                   || !strncmp (distpoint_uri, "https:", 6))
+            {
+              if (opt.ignore_http_dp)
+                continue;
+            }
+          else
+            continue; /* Skip unknown schemes. */
+
+          any_dist_point = 1;
+
+          if (opt.verbose)
+            log_info ("fetching CRL from '%s'\n", distpoint_uri);
+          err = crl_fetch (ctrl, distpoint_uri, &reader);
+          if (err)
+            {
+              log_error (_("crl_fetch via DP failed: %s\n"),
+                         gpg_strerror (err));
+              last_err = err;
+              continue; /* with the next name. */
+            }
+
+          if (opt.verbose)
+            log_info ("inserting CRL (reader %p)\n", reader);
+          err = crl_cache_insert (ctrl, distpoint_uri, reader);
+          if (err)
+            {
+              log_error (_("crl_cache_insert via DP failed: %s\n"),
+                         gpg_strerror (err));
+              last_err = err;
+              continue; /* with the next name. */
+            }
+          last_err = 0;
+          break; /* Ready. */
+        }
+      if (last_err)
+        {
+          err = last_err;
+          goto leave;
+        }
+
+      ksba_name_release (distpoint); distpoint = NULL;
+
+      /* We don't do anything with issuername_uri yet but we keep the
+         code for documentation. */
+      issuername_uri =  ksba_name_get_uri (issuername, 0);
+      ksba_name_release (issuername); issuername = NULL;
+
+    }
+  if (gpg_err_code (err) == GPG_ERR_EOF)
+    err = 0;
+
+  /* If we did not found any distpoint, try something reasonable. */
+  if (!any_dist_point )
+    {
+      if (opt.verbose)
+        log_info ("no distribution point - trying issuer name\n");
+
+      if (reader)
+        {
+          crl_close_reader (reader);
+          reader = NULL;
+        }
+
+      issuer = ksba_cert_get_issuer (cert, 0);
+      if (!issuer)
+        {
+          log_error ("oops: issuer missing in certificate\n");
+          err = gpg_error (GPG_ERR_INV_CERT_OBJ);
+          goto leave;
+        }
+
+      if (opt.verbose)
+        log_info ("fetching CRL from default location\n");
+      err = crl_fetch_default (ctrl, issuer, &reader);
+      if (err)
+          {
+            log_error ("crl_fetch via issuer failed: %s\n",
+                       gpg_strerror (err));
+            goto leave;
+          }
+
+      if (opt.verbose)
+        log_info ("inserting CRL (reader %p)\n", reader);
+      err = crl_cache_insert (ctrl, "default location(s)", reader);
+      if (err)
+        {
+          log_error (_("crl_cache_insert via issuer failed: %s\n"),
+                     gpg_strerror (err));
+          goto leave;
+        }
+    }
+
+ leave:
+  if (reader)
+    crl_close_reader (reader);
+  xfree (distpoint_uri);
+  xfree (issuername_uri);
+  ksba_name_release (distpoint);
+  ksba_name_release (issuername);
+  ksba_free (issuer);
+  return err;
+}
diff --git a/dirmngr/crlcache.h b/dirmngr/crlcache.h
new file mode 100644 (file)
index 0000000..6e9dc28
--- /dev/null
@@ -0,0 +1,70 @@
+/* crlcache.h - LDAP access
+ *      Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 CRLCACHE_H
+#define CRLCACHE_H
+
+
+typedef enum
+  {
+    CRL_CACHE_VALID = 0,
+    CRL_CACHE_INVALID,
+    CRL_CACHE_DONTKNOW,
+    CRL_CACHE_CANTUSE
+  }
+crl_cache_result_t;
+
+typedef enum foo
+  {
+    CRL_SIG_OK = 0,
+    CRL_SIG_NOT_OK,
+    CRL_TOO_OLD,
+    CRL_SIG_ERROR,
+    CRL_GENERAL_ERROR
+  }
+crl_sig_result_t;
+
+struct crl_cache_entry_s;
+typedef struct crl_cache_entry_s *crl_cache_entry_t;
+
+
+void crl_cache_init (void);
+void crl_cache_deinit (void);
+int crl_cache_flush(void);
+
+crl_cache_result_t crl_cache_isvalid (ctrl_t ctrl,
+                                      const char *issuer_hash,
+                                      const char *cert_id,
+                                      int force_refresh);
+
+gpg_error_t crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
+                                    int force_refresh);
+
+gpg_error_t crl_cache_insert (ctrl_t ctrl, const char *url,
+                              ksba_reader_t reader);
+
+gpg_error_t crl_cache_list (estream_t fp);
+
+gpg_error_t crl_cache_load (ctrl_t ctrl, const char *filename);
+
+gpg_error_t crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert);
+
+
+#endif /* CRLCACHE_H */
diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c
new file mode 100644 (file)
index 0000000..2471ca2
--- /dev/null
@@ -0,0 +1,540 @@
+/* crlfetch.c - LDAP access
+ *      Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ *      Copyright (C) 2003, 2004, 2005, 2006, 2007 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <npth.h>
+
+#include "crlfetch.h"
+#include "dirmngr.h"
+#include "misc.h"
+#include "http.h"
+
+#if USE_LDAP
+# include "ldap-wrapper.h"
+#endif
+
+/* For detecting armored CRLs received via HTTP (yes, such CRLS really
+   exits, e.g. http://grid.fzk.de/ca/gridka-crl.pem at least in June
+   2008) we need a context in the reader callback.  */
+struct reader_cb_context_s
+{
+  estream_t fp;             /* The stream used with the ksba reader.  */
+  int checked:1;            /* PEM/binary detection ahs been done.    */
+  int is_pem:1;             /* The file stream is PEM encoded.        */
+  struct b64state b64state; /* The state used for Base64 decoding.    */
+};
+
+
+/* We need to associate a reader object with the reader callback
+   context.  This table is used for it. */
+struct file_reader_map_s
+{
+  ksba_reader_t reader;
+  struct reader_cb_context_s *cb_ctx;
+};
+#define MAX_FILE_READER 50
+static struct file_reader_map_s file_reader_map[MAX_FILE_READER];
+
+/* Associate FP with READER.  If the table is full wait until another
+   thread has removed an entry.  */
+static void
+register_file_reader (ksba_reader_t reader, struct reader_cb_context_s *cb_ctx)
+{
+  int i;
+
+  for (;;)
+    {
+      for (i=0; i < MAX_FILE_READER; i++)
+        if (!file_reader_map[i].reader)
+          {
+            file_reader_map[i].reader = reader;
+            file_reader_map[i].cb_ctx = cb_ctx;
+            return;
+          }
+      log_info (_("reader to file mapping table full - waiting\n"));
+      npth_sleep (2);
+    }
+}
+
+/* Scan the table for an entry matching READER, remove that entry and
+   return the associated file pointer. */
+static struct reader_cb_context_s *
+get_file_reader (ksba_reader_t reader)
+{
+  struct reader_cb_context_s *cb_ctx = NULL;
+  int i;
+
+  for (i=0; i < MAX_FILE_READER; i++)
+    if (file_reader_map[i].reader == reader)
+      {
+        cb_ctx = file_reader_map[i].cb_ctx;
+        file_reader_map[i].reader = NULL;
+        file_reader_map[i].cb_ctx = NULL;
+        break;
+      }
+  return cb_ctx;
+}
+
+
+
+static int
+my_es_read (void *opaque, char *buffer, size_t nbytes, size_t *nread)
+{
+  struct reader_cb_context_s *cb_ctx = opaque;
+  int result;
+
+  result = es_read (cb_ctx->fp, buffer, nbytes, nread);
+  if (result)
+    return result;
+  /* Fixme we should check whether the semantics of es_read are okay
+     and well defined.  I have some doubts.  */
+  if (nbytes && !*nread && es_feof (cb_ctx->fp))
+    return gpg_error (GPG_ERR_EOF);
+  if (!nread && es_ferror (cb_ctx->fp))
+    return gpg_error (GPG_ERR_EIO);
+
+  if (!cb_ctx->checked && *nread)
+    {
+      int c = *(unsigned char *)buffer;
+
+      cb_ctx->checked = 1;
+      if ( ((c & 0xc0) >> 6) == 0 /* class: universal */
+           && (c & 0x1f) == 16    /* sequence */
+           && (c & 0x20)          /* is constructed */ )
+        ; /* Binary data.  */
+      else
+        {
+          cb_ctx->is_pem = 1;
+          b64dec_start (&cb_ctx->b64state, "");
+        }
+    }
+  if (cb_ctx->is_pem && *nread)
+    {
+      size_t nread2;
+
+      if (b64dec_proc (&cb_ctx->b64state, buffer, *nread, &nread2))
+        {
+          /* EOF from decoder. */
+          *nread = 0;
+          result = gpg_error (GPG_ERR_EOF);
+        }
+      else
+        *nread = nread2;
+    }
+
+  return result;
+}
+
+
+/* Fetch CRL from URL and return the entire CRL using new ksba reader
+   object in READER.  Note that this reader object should be closed
+   only using ldap_close_reader. */
+gpg_error_t
+crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+{
+  gpg_error_t err;
+  parsed_uri_t uri;
+  char *free_this = NULL;
+  int redirects_left = 2; /* We allow for 2 redirect levels.  */
+
+#ifndef USE_LDAP
+  (void)ctrl;
+#endif
+
+  *reader = NULL;
+
+ once_more:
+  err = http_parse_uri (&uri, url, 0);
+  http_release_parsed_uri (uri);
+  if (err && url && !strncmp (url, "https:", 6))
+    {
+      /* Our HTTP code does not support TLS, thus we can't use this
+         scheme and it is frankly not useful for CRL retrieval anyway.
+         We resort to using http, assuming that the server also
+         provides plain http access. */
+      free_this = xtrymalloc (strlen (url) + 1);
+      if (free_this)
+        {
+          strcpy (stpcpy (free_this,"http:"), url+6);
+          err = http_parse_uri (&uri, free_this, 0);
+          http_release_parsed_uri (uri);
+          if (!err)
+            {
+              log_info (_("using \"http\" instead of \"https\"\n"));
+              url = free_this;
+            }
+        }
+    }
+  if (!err) /* Yes, our HTTP code groks that. */
+    {
+      http_t hd;
+
+      if (opt.disable_http)
+        {
+          log_error (_("CRL access not possible due to disabled %s\n"),
+                     "HTTP");
+          err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+        }
+      else
+        err = http_open_document (&hd, url, NULL,
+                                  (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+                                  |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0),
+                                  opt.http_proxy, NULL, NULL, NULL);
+
+      switch ( err? 99999 : http_get_status_code (hd) )
+        {
+        case 200:
+          {
+            estream_t fp = http_get_read_ptr (hd);
+            struct reader_cb_context_s *cb_ctx;
+
+            cb_ctx = xtrycalloc (1, sizeof *cb_ctx);
+            if (!cb_ctx)
+              err = gpg_error_from_syserror ();
+            if (!err)
+              err = ksba_reader_new (reader);
+            if (!err)
+              {
+                cb_ctx->fp = fp;
+                err = ksba_reader_set_cb (*reader, &my_es_read, cb_ctx);
+              }
+            if (err)
+              {
+                log_error (_("error initializing reader object: %s\n"),
+                           gpg_strerror (err));
+                ksba_reader_release (*reader);
+                *reader = NULL;
+                http_close (hd, 0);
+              }
+            else
+              {
+                /* The ksba reader misses a user pointer thus we need
+                   to come up with our own way of associating a file
+                   pointer (or well the callback context) with the
+                   reader.  It is only required when closing the
+                   reader thus there is no performance issue doing it
+                   this way.  FIXME: We now have a close notification
+                   which might be used here. */
+                register_file_reader (*reader, cb_ctx);
+                http_close (hd, 1);
+              }
+          }
+          break;
+
+        case 301: /* Redirection (perm.). */
+        case 302: /* Redirection (temp.). */
+          {
+            const char *s = http_get_header (hd, "Location");
+
+            log_info (_("URL '%s' redirected to '%s' (%u)\n"),
+                      url, s?s:"[none]", http_get_status_code (hd));
+            if (s && *s && redirects_left-- )
+              {
+                xfree (free_this); url = NULL;
+                free_this = xtrystrdup (s);
+                if (!free_this)
+                  err = gpg_error_from_errno (errno);
+                else
+                  {
+                    url = free_this;
+                    http_close (hd, 0);
+                    /* Note, that our implementation of redirection
+                       actually handles a redirect to LDAP.  */
+                    goto once_more;
+                  }
+              }
+            else
+              err = gpg_error (GPG_ERR_NO_DATA);
+            log_error (_("too many redirections\n")); /* Or no "Location". */
+            http_close (hd, 0);
+          }
+          break;
+
+        case 99999: /* Made up status code for error reporting.  */
+          log_error (_("error retrieving '%s': %s\n"),
+                     url, gpg_strerror (err));
+          break;
+
+        default:
+          log_error (_("error retrieving '%s': http status %u\n"),
+                     url, http_get_status_code (hd));
+          err = gpg_error (GPG_ERR_NO_DATA);
+          http_close (hd, 0);
+        }
+    }
+  else /* Let the LDAP code try other schemes. */
+    {
+      if (opt.disable_ldap)
+        {
+          log_error (_("CRL access not possible due to disabled %s\n"),
+                     "LDAP");
+          err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+        }
+      else
+        {
+#       if USE_LDAP
+          err = url_fetch_ldap (ctrl, url, NULL, 0, reader);
+#       else /*!USE_LDAP*/
+          err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#       endif /*!USE_LDAP*/
+        }
+    }
+
+  xfree (free_this);
+  return err;
+}
+
+
+/* Fetch CRL for ISSUER using a default server. Return the entire CRL
+   as a newly opened stream returned in R_FP. */
+gpg_error_t
+crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader)
+{
+  if (opt.disable_ldap)
+    {
+      log_error (_("CRL access not possible due to disabled %s\n"),
+                 "LDAP");
+      return gpg_error (GPG_ERR_NOT_SUPPORTED);
+    }
+#if USE_LDAP
+  return attr_fetch_ldap (ctrl, issuer, "certificateRevocationList",
+                          reader);
+#else
+  (void)ctrl;
+  (void)issuer;
+  (void)reader;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif
+}
+
+
+/* Fetch a CA certificate for DN using the default server. This
+   function only initiates the fetch; fetch_next_cert must be used to
+   actually read the certificate; end_cert_fetch to end the
+   operation. */
+gpg_error_t
+ca_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, const char *dn)
+{
+  if (opt.disable_ldap)
+    {
+      log_error (_("CRL access not possible due to disabled %s\n"),
+                 "LDAP");
+      return gpg_error (GPG_ERR_NOT_SUPPORTED);
+    }
+#if USE_LDAP
+  return start_default_fetch_ldap (ctrl, context, dn, "cACertificate");
+#else
+  (void)ctrl;
+  (void)context;
+  (void)dn;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif
+}
+
+
+gpg_error_t
+start_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context,
+                  strlist_t patterns, const ldap_server_t server)
+{
+  if (opt.disable_ldap)
+    {
+      log_error (_("certificate search not possible due to disabled %s\n"),
+                 "LDAP");
+      return gpg_error (GPG_ERR_NOT_SUPPORTED);
+    }
+#if USE_LDAP
+  return start_cert_fetch_ldap (ctrl, context, patterns, server);
+#else
+  (void)ctrl;
+  (void)context;
+  (void)patterns;
+  (void)server;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif
+}
+
+
+gpg_error_t
+fetch_next_cert (cert_fetch_context_t context,
+                 unsigned char **value, size_t * valuelen)
+{
+#if USE_LDAP
+  return fetch_next_cert_ldap (context, value, valuelen);
+#else
+  (void)context;
+  (void)value;
+  (void)valuelen;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif
+}
+
+
+/* Fetch the next data from CONTEXT, assuming it is a certificate and return
+   it as a cert object in R_CERT.  */
+gpg_error_t
+fetch_next_ksba_cert (cert_fetch_context_t context, ksba_cert_t *r_cert)
+{
+  gpg_error_t err;
+  unsigned char *value;
+  size_t valuelen;
+  ksba_cert_t cert;
+
+  *r_cert = NULL;
+
+#if USE_LDAP
+  err = fetch_next_cert_ldap (context, &value, &valuelen);
+  if (!err && !value)
+    err = gpg_error (GPG_ERR_BUG);
+#else
+  (void)context;
+  err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif
+  if (err)
+    return err;
+
+  err = ksba_cert_new (&cert);
+  if (err)
+    {
+      xfree (value);
+      return err;
+    }
+
+  err = ksba_cert_init_from_mem (cert, value, valuelen);
+  xfree (value);
+  if (err)
+    {
+      ksba_cert_release (cert);
+      return err;
+    }
+  *r_cert = cert;
+  return 0;
+}
+
+
+void
+end_cert_fetch (cert_fetch_context_t context)
+{
+#if USE_LDAP
+  end_cert_fetch_ldap (context);
+#else
+  (void)context;
+#endif
+}
+
+
+/* Lookup a cert by it's URL.  */
+gpg_error_t
+fetch_cert_by_url (ctrl_t ctrl, const char *url,
+                  unsigned char **value, size_t *valuelen)
+{
+  const unsigned char *cert_image;
+  size_t cert_image_n;
+  ksba_reader_t reader;
+  ksba_cert_t cert;
+  gpg_error_t err;
+
+  *value = NULL;
+  *valuelen = 0;
+  cert_image = NULL;
+  reader = NULL;
+  cert = NULL;
+
+#if USE_LDAP
+  err = url_fetch_ldap (ctrl, url, NULL, 0, &reader);
+#else
+  (void)ctrl;
+  (void)url;
+  err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#endif /*USE_LDAP*/
+  if (err)
+    goto leave;
+
+  err = ksba_cert_new (&cert);
+  if (err)
+    goto leave;
+
+  err = ksba_cert_read_der (cert, reader);
+  if (err)
+    goto leave;
+
+  cert_image = ksba_cert_get_image (cert, &cert_image_n);
+  if (!cert_image || !cert_image_n)
+    {
+      err = gpg_error (GPG_ERR_INV_CERT_OBJ);
+      goto leave;
+    }
+
+  *value = xtrymalloc (cert_image_n);
+  if (!*value)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  memcpy (*value, cert_image, cert_image_n);
+  *valuelen = cert_image_n;
+
+ leave:
+
+  ksba_cert_release (cert);
+#if USE_LDAP
+  ldap_wrapper_release_context (reader);
+#endif /*USE_LDAP*/
+
+  return err;
+}
+
+/* This function is to be used to close the reader object.  In
+   addition to running ksba_reader_release it also releases the LDAP
+   or HTTP contexts associated with that reader.  */
+void
+crl_close_reader (ksba_reader_t reader)
+{
+  struct reader_cb_context_s *cb_ctx;
+
+  if (!reader)
+    return;
+
+  /* Check whether this is a HTTP one. */
+  cb_ctx = get_file_reader (reader);
+  if (cb_ctx)
+    {
+      /* This is an HTTP context. */
+      if (cb_ctx->fp)
+        es_fclose (cb_ctx->fp);
+      /* Release the base64 decoder state.  */
+      if (cb_ctx->is_pem)
+        b64dec_finish (&cb_ctx->b64state);
+      /* Release the callback context.  */
+      xfree (cb_ctx);
+    }
+  else /* This is an ldap wrapper context (Currently not used). */
+    {
+#if USE_LDAP
+      ldap_wrapper_release_context (reader);
+#endif /*USE_LDAP*/
+    }
+
+  /* Now get rid of the reader object. */
+  ksba_reader_release (reader);
+}
diff --git a/dirmngr/crlfetch.h b/dirmngr/crlfetch.h
new file mode 100644 (file)
index 0000000..dd28238
--- /dev/null
@@ -0,0 +1,88 @@
+/* crlfetch.h - LDAP access
+ *      Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CRLFETCH_H
+#define CRLFETCH_H
+
+#include "dirmngr.h"
+
+
+struct cert_fetch_context_s;
+typedef struct cert_fetch_context_s *cert_fetch_context_t;
+
+
+/* Fetch CRL from URL. */
+gpg_error_t crl_fetch (ctrl_t ctrl, const char* url, ksba_reader_t *reader);
+
+/* Fetch CRL for ISSUER using default server. */
+gpg_error_t crl_fetch_default (ctrl_t ctrl,
+                               const char* issuer, ksba_reader_t *reader);
+
+
+/* Fetch cert for DN. */
+gpg_error_t ca_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context,
+                           const char *dn);
+
+
+/* Query the server for certs matching patterns. */
+gpg_error_t start_cert_fetch (ctrl_t ctrl,
+                              cert_fetch_context_t *context,
+                              strlist_t patterns,
+                              const ldap_server_t server);
+gpg_error_t fetch_next_cert(cert_fetch_context_t context,
+                            unsigned char **value, size_t *valuelen);
+gpg_error_t fetch_next_ksba_cert (cert_fetch_context_t context,
+                                  ksba_cert_t *r_cert);
+void end_cert_fetch (cert_fetch_context_t context);
+
+/* Lookup a cert by it's URL.  */
+gpg_error_t fetch_cert_by_url (ctrl_t ctrl, const char *url,
+                              unsigned char **value, size_t *valuelen);
+
+/* Close a reader object. */
+void crl_close_reader (ksba_reader_t reader);
+
+
+
+/*-- ldap.c --*/
+gpg_error_t url_fetch_ldap (ctrl_t ctrl,
+                            const char *url, const char *host, int port,
+                            ksba_reader_t *reader);
+gpg_error_t attr_fetch_ldap (ctrl_t ctrl,
+                             const char *dn, const char *attr,
+                             ksba_reader_t *reader);
+
+
+gpg_error_t start_default_fetch_ldap (ctrl_t ctrl,
+                                      cert_fetch_context_t *context,
+                                      const char *dn, const char *attr);
+gpg_error_t start_cert_fetch_ldap( ctrl_t ctrl,
+                                   cert_fetch_context_t *context,
+                                   strlist_t patterns,
+                                   const ldap_server_t server );
+gpg_error_t fetch_next_cert_ldap (cert_fetch_context_t context,
+                                  unsigned char **value, size_t *valuelen );
+void end_cert_fetch_ldap (cert_fetch_context_t context);
+
+
+
+
+
+
+#endif /* CRLFETCH_H */
diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c
new file mode 100644 (file)
index 0000000..0e62764
--- /dev/null
@@ -0,0 +1,1031 @@
+/* dirmngr-client.c  -  A client for the dirmngr daemon
+ *     Copyright (C) 2004, 2007 g10 Code GmbH
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <gpg-error.h>
+#include <assuan.h>
+
+#define JNLIB_NEED_LOG_LOGV
+#include "../common/logging.h"
+#include "../common/argparse.h"
+#include "../common/stringhelp.h"
+#include "../common/mischelp.h"
+#include "../common/strlist.h"
+
+#include "i18n.h"
+#include "util.h"
+
+
+/* Constants for the options.  */
+enum
+  {
+    oQuiet       = 'q',
+    oVerbose     = 'v',
+    oLocal        = 'l',
+    oUrl          = 'u',
+
+    oOCSP         = 500,
+    oPing,
+    oCacheCert,
+    oValidate,
+    oLookup,
+    oLoadCRL,
+    oSquidMode,
+    oPEM,
+    oEscapedPEM,
+    oForceDefaultResponder
+  };
+
+
+/* The list of options as used by the argparse.c code.  */
+static ARGPARSE_OPTS opts[] = {
+  { oVerbose,  "verbose",   0, N_("verbose") },
+  { oQuiet,    "quiet",     0, N_("be somewhat more quiet") },
+  { oOCSP,     "ocsp",      0, N_("use OCSP instead of CRLs") },
+  { oPing,     "ping",      0, N_("check whether a dirmngr is running")},
+  { oCacheCert,"cache-cert",0, N_("add a certificate to the cache")},
+  { oValidate, "validate",  0, N_("validate a certificate")},
+  { oLookup,   "lookup",    0, N_("lookup a certificate")},
+  { oLocal,    "local",     0, N_("lookup only locally stored certificates")},
+  { oUrl,      "url",       0, N_("expect an URL for --lookup")},
+  { oLoadCRL,  "load-crl",  0, N_("load a CRL into the dirmngr")},
+  { oSquidMode,"squid-mode",0, N_("special mode for use by Squid")},
+  { oPEM,      "pem",       0, N_("expect certificates in PEM format")},
+  { oForceDefaultResponder, "force-default-responder", 0,
+    N_("force the use of the default OCSP responder")},
+  { 0, NULL, 0, NULL }
+};
+
+
+/* The usual structure for the program flags.  */
+static struct
+{
+  int quiet;
+  int verbose;
+  const char *dirmngr_program;
+  int force_pipe_server;
+  int force_default_responder;
+  int pem;
+  int escaped_pem; /* PEM is additional percent encoded.  */
+  int url;         /* Expect an URL.  */
+  int local;       /* Lookup up only local certificates.  */
+
+  int use_ocsp;
+} opt;
+
+
+/* Communication structure for the certificate inquire callback. */
+struct inq_cert_parm_s
+{
+  assuan_context_t ctx;
+  const unsigned char *cert;
+  size_t certlen;
+};
+
+
+/* Base64 conversion tables. */
+static unsigned char bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                  "abcdefghijklmnopqrstuvwxyz"
+                                 "0123456789+/";
+static unsigned char asctobin[256]; /* runtime initialized */
+
+
+/* Prototypes.  */
+static assuan_context_t start_dirmngr (int only_daemon);
+static gpg_error_t read_certificate (const char *fname,
+                                     unsigned char **rbuf, size_t *rbuflen);
+static gpg_error_t do_check (assuan_context_t ctx,
+                             const unsigned char *cert, size_t certlen);
+static gpg_error_t do_cache (assuan_context_t ctx,
+                             const unsigned char *cert, size_t certlen);
+static gpg_error_t do_validate (assuan_context_t ctx,
+                                const unsigned char *cert, size_t certlen);
+static gpg_error_t do_loadcrl (assuan_context_t ctx, const char *filename);
+static gpg_error_t do_lookup (assuan_context_t ctx, const char *pattern);
+static gpg_error_t squid_loop_body (assuan_context_t ctx);
+
+
+
+/* Function called by argparse.c to display information.  */
+static const char *
+my_strusage (int level)
+{
+  const char *p;
+
+  switch(level)
+    {
+    case 11: p = "dirmngr-client (@GNUPG@)";
+      break;
+    case 13: p = VERSION; break;
+    case 17: p = PRINTABLE_OS_NAME; break;
+    case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
+    case 49: p = PACKAGE_BUGREPORT; break;
+    case 1:
+    case 40: p =
+                 _("Usage: dirmngr-client [options] "
+                   "[certfile|pattern] (-h for help)\n");
+      break;
+    case 41: p =
+          _("Syntax: dirmngr-client [options] [certfile|pattern]\n"
+            "Test an X.509 certificate against a CRL or do an OCSP check\n"
+            "The process returns 0 if the certificate is valid, 1 if it is\n"
+            "not valid and other error codes for general failures\n");
+      break;
+
+    default: p = NULL;
+    }
+  return p;
+}
+
+
+
+int
+main (int argc, char **argv )
+{
+  ARGPARSE_ARGS pargs;
+  assuan_context_t ctx;
+  gpg_error_t err;
+  unsigned char *certbuf;
+  size_t certbuflen = 0;
+  int cmd_ping = 0;
+  int cmd_cache_cert = 0;
+  int cmd_validate = 0;
+  int cmd_lookup = 0;
+  int cmd_loadcrl = 0;
+  int cmd_squid_mode = 0;
+
+  set_strusage (my_strusage);
+  log_set_prefix ("dirmngr-client",
+                  JNLIB_LOG_WITH_PREFIX);
+
+  /* For W32 we need to initialize the socket subsystem.  Becuase we
+     don't use Pth we need to do this explicit. */
+#ifdef HAVE_W32_SYSTEM
+ {
+   WSADATA wsadat;
+
+   WSAStartup (0x202, &wsadat);
+ }
+#endif /*HAVE_W32_SYSTEM*/
+
+  /* Init Assuan.  */
+  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
+  assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
+
+  /* Setup I18N. */
+  i18n_init();
+
+  /* Parse the command line.  */
+  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 oOCSP: opt.use_ocsp++; break;
+        case oPing: cmd_ping = 1; break;
+        case oCacheCert: cmd_cache_cert = 1; break;
+        case oValidate: cmd_validate = 1; break;
+        case oLookup: cmd_lookup = 1; break;
+        case oUrl: opt.url = 1; break;
+        case oLocal: opt.local = 1; break;
+        case oLoadCRL: cmd_loadcrl = 1; break;
+        case oPEM: opt.pem = 1; break;
+        case oSquidMode:
+          opt.pem = 1;
+          opt.escaped_pem = 1;
+          cmd_squid_mode = 1;
+          break;
+        case oForceDefaultResponder: opt.force_default_responder = 1; break;
+
+        default : pargs.err = 2; break;
+       }
+    }
+  if (log_get_errorcount (0))
+    exit (2);
+
+  /* Build the helptable for radix64 to bin conversion. */
+  if (opt.pem)
+    {
+      int i;
+      unsigned char *s;
+
+      for (i=0; i < 256; i++ )
+        asctobin[i] = 255; /* Used to detect invalid characters. */
+      for (s=bintoasc, i=0; *s; s++, i++)
+        asctobin[*s] = i;
+    }
+
+
+  if (cmd_ping)
+    err = 0;
+  else if (cmd_lookup || cmd_loadcrl)
+    {
+      if (!argc)
+        usage (1);
+      err = 0;
+    }
+  else if (cmd_squid_mode)
+    {
+      err = 0;
+      if (argc)
+        usage (1);
+    }
+  else if (!argc)
+    {
+      err = read_certificate (NULL, &certbuf, &certbuflen);
+      if (err)
+        log_error (_("error reading certificate from stdin: %s\n"),
+                   gpg_strerror (err));
+    }
+  else if (argc == 1)
+    {
+      err = read_certificate (*argv, &certbuf, &certbuflen);
+      if (err)
+        log_error (_("error reading certificate from '%s': %s\n"),
+                   *argv, gpg_strerror (err));
+    }
+  else
+    {
+      err = 0;
+      usage (1);
+    }
+
+  if (log_get_errorcount (0))
+    exit (2);
+
+  if (certbuflen > 20000)
+    {
+      log_error (_("certificate too large to make any sense\n"));
+      exit (2);
+    }
+
+  ctx = start_dirmngr (1);
+  if (!ctx)
+    exit (2);
+
+  if (cmd_ping)
+    ;
+  else if (cmd_squid_mode)
+    {
+      while (!(err = squid_loop_body (ctx)))
+        ;
+      if (gpg_err_code (err) == GPG_ERR_EOF)
+        err = 0;
+    }
+  else if (cmd_lookup)
+    {
+      int last_err = 0;
+
+      for (; argc; argc--, argv++)
+        {
+          err = do_lookup (ctx, *argv);
+          if (err)
+            {
+              log_error (_("lookup failed: %s\n"), gpg_strerror (err));
+              last_err = err;
+            }
+        }
+      err = last_err;
+    }
+  else if (cmd_loadcrl)
+    {
+      int last_err = 0;
+
+      for (; argc; argc--, argv++)
+        {
+          err = do_loadcrl (ctx, *argv);
+          if (err)
+            {
+              log_error (_("loading CRL '%s' failed: %s\n"),
+                         *argv, gpg_strerror (err));
+              last_err = err;
+            }
+        }
+      err = last_err;
+    }
+  else if (cmd_cache_cert)
+    {
+      err = do_cache (ctx, certbuf, certbuflen);
+      xfree (certbuf);
+    }
+  else if (cmd_validate)
+    {
+      err = do_validate (ctx, certbuf, certbuflen);
+      xfree (certbuf);
+    }
+  else
+    {
+      err = do_check (ctx, certbuf, certbuflen);
+      xfree (certbuf);
+    }
+
+  assuan_release (ctx);
+
+  if (cmd_ping)
+    {
+      if (!opt.quiet)
+        log_info (_("a dirmngr daemon is up and running\n"));
+      return 0;
+    }
+  else if (cmd_lookup|| cmd_loadcrl || cmd_squid_mode)
+    return err? 1:0;
+  else if (cmd_cache_cert)
+    {
+      if (err && gpg_err_code (err) == GPG_ERR_DUP_VALUE )
+        {
+          if (!opt.quiet)
+            log_info (_("certificate already cached\n"));
+        }
+      else if (err)
+        {
+          log_error (_("error caching certificate: %s\n"),
+                     gpg_strerror (err));
+          return 1;
+        }
+      return 0;
+    }
+  else if (cmd_validate && err)
+    {
+      log_error (_("validation of certificate failed: %s\n"),
+                 gpg_strerror (err));
+      return 1;
+    }
+  else if (!err)
+    {
+      if (!opt.quiet)
+        log_info (_("certificate is valid\n"));
+      return 0;
+    }
+  else if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED )
+    {
+      if (!opt.quiet)
+        log_info (_("certificate has been revoked\n"));
+      return 1;
+    }
+  else
+    {
+      log_error (_("certificate check failed: %s\n"), gpg_strerror (err));
+      return 2;
+    }
+}
+
+
+/* Print status line from the assuan protocol.  */
+static gpg_error_t
+status_cb (void *opaque, const char *line)
+{
+  (void)opaque;
+
+  if (opt.verbose > 2)
+    log_info (_("got status: '%s'\n"), line);
+  return 0;
+}
+
+/* Print data as retrieved by the lookup function.  */
+static gpg_error_t
+data_cb (void *opaque, const void *buffer, size_t length)
+{
+  gpg_error_t err;
+  struct b64state *state = opaque;
+
+  if (buffer)
+    {
+      err = b64enc_write (state, buffer, length);
+      if (err)
+        log_error (_("error writing base64 encoding: %s\n"),
+                   gpg_strerror (err));
+    }
+  return 0;
+}
+
+
+/* Try to connect to the dirmngr via socket or fork it off and work by
+   pipes.  Handle the server's initial greeting */
+static assuan_context_t
+start_dirmngr (int only_daemon)
+{
+  int rc;
+  char *infostr, *p;
+  assuan_context_t ctx;
+  int try_default = 0;
+
+  infostr = opt.force_pipe_server? NULL : getenv (DIRMNGR_INFO_NAME);
+  if (only_daemon && (!infostr || !*infostr))
+    {
+      if (dirmngr_user_socket_name ())
+        infostr = xstrdup (dirmngr_user_socket_name ());
+      else
+        infostr = xstrdup (dirmngr_sys_socket_name ());
+      try_default = 1;
+    }
+
+  rc = assuan_new (&ctx);
+  if (rc)
+    {
+      log_error (_("failed to allocate assuan context: %s\n"),
+                 gpg_strerror (rc));
+      return NULL;
+    }
+
+  if (!infostr || !*infostr)
+    {
+      const char *pgmname;
+      const char *argv[3];
+      assuan_fd_t no_close_list[3];
+      int i;
+
+      if (only_daemon)
+        {
+          log_error (_("apparently no running dirmngr\n"));
+          return NULL;
+        }
+
+      if (opt.verbose)
+        log_info (_("no running dirmngr - starting one\n"));
+
+      if (!opt.dirmngr_program || !*opt.dirmngr_program)
+        opt.dirmngr_program = "./dirmngr";
+      if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
+        pgmname = opt.dirmngr_program;
+      else
+        pgmname++;
+
+      argv[0] = pgmname;
+      argv[1] = "--server";
+      argv[2] = NULL;
+
+      i=0;
+      if (log_get_fd () != -1)
+        no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
+      no_close_list[i++] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
+      no_close_list[i] = ASSUAN_INVALID_FD;
+
+      /* Connect to the agent and perform initial handshaking.  */
+      rc = assuan_pipe_connect (ctx, opt.dirmngr_program, argv,
+                                no_close_list, NULL, NULL, 0);
+    }
+  else /* Connect to a daemon.  */
+    {
+      int prot;
+      int pid;
+
+      infostr = xstrdup (infostr);
+      if (!try_default && *infostr)
+        {
+          if ( !(p = strchr (infostr, ':')) || p == infostr)
+            {
+              log_error (_("malformed %s environment variable\n"),
+                         DIRMNGR_INFO_NAME);
+              xfree (infostr);
+              if (only_daemon)
+                return NULL;
+              /* Try again by starting a new instance.  */
+              opt.force_pipe_server = 1;
+              return start_dirmngr (0);
+            }
+          *p++ = 0;
+          pid = atoi (p);
+          while (*p && *p != ':')
+            p++;
+          prot = *p? atoi (p+1) : 0;
+          if (prot != 1)
+            {
+              log_error (_("dirmngr protocol version %d is not supported\n"),
+                         prot);
+              xfree (infostr);
+              if (only_daemon)
+                return NULL;
+              opt.force_pipe_server = 1;
+              return start_dirmngr (0);
+            }
+        }
+      else
+        pid = -1;
+
+      rc = assuan_socket_connect (ctx, infostr, pid, 0);
+      xfree (infostr);
+      if (gpg_err_code(rc) == GPG_ERR_ASS_CONNECT_FAILED && !only_daemon)
+        {
+          log_error (_("can't connect to the dirmngr - trying fall back\n"));
+          opt.force_pipe_server = 1;
+          return start_dirmngr (0);
+        }
+    }
+
+  if (rc)
+    {
+      assuan_release (ctx);
+      log_error (_("can't connect to the dirmngr: %s\n"),
+                 gpg_strerror (rc));
+      return NULL;
+    }
+
+  return ctx;
+}
+
+
+/* Read the first PEM certificate from the file FNAME.  If fname is
+   NULL the next certificate is read from stdin.  The certificate is
+   returned in an alloced buffer whose address will be returned in
+   RBUF and its length in RBUFLEN.  */
+static gpg_error_t
+read_pem_certificate (const char *fname, unsigned char **rbuf, size_t *rbuflen)
+{
+  FILE *fp;
+  int c;
+  int pos;
+  int value;
+  unsigned char *buf;
+  size_t bufsize, buflen;
+  enum {
+    s_init, s_idle, s_lfseen, s_begin,
+    s_b64_0, s_b64_1, s_b64_2, s_b64_3,
+    s_waitend
+  } state = s_init;
+
+  fp = fname? fopen (fname, "r") : stdin;
+  if (!fp)
+    return gpg_error_from_errno (errno);
+
+  pos = 0;
+  value = 0;
+  bufsize = 8192;
+  buf = xmalloc (bufsize);
+  buflen = 0;
+  while ((c=getc (fp)) != EOF)
+    {
+      int escaped_c = 0;
+
+      if (opt.escaped_pem)
+        {
+          if (c == '%')
+            {
+              char tmp[2];
+              if ((c = getc(fp)) == EOF)
+                break;
+              tmp[0] = c;
+              if ((c = getc(fp)) == EOF)
+                break;
+              tmp[1] = c;
+              if (!hexdigitp (tmp) || !hexdigitp (tmp+1))
+                {
+                  log_error ("invalid percent escape sequence\n");
+                  state = s_idle; /* Force an error. */
+                  /* Skip to end of line.  */
+                  while ( (c=getc (fp)) != EOF && c != '\n')
+                    ;
+                  goto ready;
+                }
+              c = xtoi_2 (tmp);
+              escaped_c = 1;
+            }
+          else if (c == '\n')
+            goto ready; /* Ready.  */
+        }
+      switch (state)
+        {
+        case s_idle:
+          if (c == '\n')
+            {
+              state = s_lfseen;
+              pos = 0;
+            }
+          break;
+        case s_init:
+          state = s_lfseen;
+        case s_lfseen:
+          if (c != "-----BEGIN "[pos])
+            state = s_idle;
+          else if (pos == 10)
+            state = s_begin;
+          else
+            pos++;
+          break;
+        case s_begin:
+          if (c == '\n')
+            state = s_b64_0;
+          break;
+        case s_b64_0:
+        case s_b64_1:
+        case s_b64_2:
+        case s_b64_3:
+          {
+            if (buflen >= bufsize)
+              {
+                bufsize += 8192;
+                buf = xrealloc (buf, bufsize);
+              }
+
+            if (c == '-')
+              state = s_waitend;
+            else if ((c = asctobin[c & 0xff]) == 255 )
+              ; /* Just skip invalid base64 characters. */
+            else if (state == s_b64_0)
+              {
+                value = c << 2;
+                state = s_b64_1;
+              }
+            else if (state == s_b64_1)
+              {
+                value |= (c>>4)&3;
+                buf[buflen++] = value;
+                value = (c<<4)&0xf0;
+                state = s_b64_2;
+              }
+            else if (state == s_b64_2)
+              {
+                value |= (c>>2)&15;
+                buf[buflen++] = value;
+                value = (c<<6)&0xc0;
+                state = s_b64_3;
+              }
+            else
+              {
+                value |= c&0x3f;
+                buf[buflen++] = value;
+                state = s_b64_0;
+              }
+          }
+          break;
+        case s_waitend:
+          /* Note that we do not check that the base64 decoder has
+             been left in the expected state.  We assume that the PEM
+             header is just fine.  However we need to wait for the
+             real LF and not a trailing percent escaped one. */
+          if (c== '\n' && !escaped_c)
+            goto ready;
+          break;
+        default:
+          BUG();
+        }
+    }
+ ready:
+  if (fname)
+    fclose (fp);
+
+  if (state == s_init && c == EOF)
+    {
+      xfree (buf);
+      return gpg_error (GPG_ERR_EOF);
+    }
+  else if (state != s_waitend)
+    {
+      log_error ("no certificate or invalid encoded\n");
+      xfree (buf);
+      return gpg_error (GPG_ERR_INV_ARMOR);
+    }
+
+  *rbuf = buf;
+  *rbuflen = buflen;
+  return 0;
+}
+
+/* Read a binary certificate from the file FNAME.  If fname is NULL the
+   file is read from stdin.  The certificate is returned in an alloced
+   buffer whose address will be returned in RBUF and its length in
+   RBUFLEN.  */
+static gpg_error_t
+read_certificate (const char *fname, unsigned char **rbuf, size_t *rbuflen)
+{
+  gpg_error_t err;
+  FILE *fp;
+  unsigned char *buf;
+  size_t nread, bufsize, buflen;
+
+  if (opt.pem)
+    return read_pem_certificate (fname, rbuf, rbuflen);
+
+  fp = fname? fopen (fname, "rb") : stdin;
+  if (!fp)
+    return gpg_error_from_errno (errno);
+
+  buf = NULL;
+  bufsize = buflen = 0;
+#define NCHUNK 8192
+  do
+    {
+      bufsize += NCHUNK;
+      if (!buf)
+        buf = xmalloc (bufsize);
+      else
+        buf = xrealloc (buf, bufsize);
+
+      nread = fread (buf+buflen, 1, NCHUNK, fp);
+      if (nread < NCHUNK && ferror (fp))
+        {
+          err = gpg_error_from_errno (errno);
+          xfree (buf);
+          if (fname)
+            fclose (fp);
+          return err;
+        }
+      buflen += nread;
+    }
+  while (nread == NCHUNK);
+#undef NCHUNK
+  if (fname)
+    fclose (fp);
+  *rbuf = buf;
+  *rbuflen = buflen;
+  return 0;
+}
+
+
+/* Callback for the inquire fiunction to send back the certificate.  */
+static gpg_error_t
+inq_cert (void *opaque, const char *line)
+{
+  struct inq_cert_parm_s *parm = opaque;
+  gpg_error_t err;
+
+  if (!strncmp (line, "TARGETCERT", 10) && (line[10] == ' ' || !line[10]))
+    {
+      err = assuan_send_data (parm->ctx, parm->cert, parm->certlen);
+    }
+  else if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
+    {
+      /* We don't support this but dirmngr might ask for it.  So
+         simply ignore it by sending back and empty value. */
+      err = assuan_send_data (parm->ctx, NULL, 0);
+    }
+  else if (!strncmp (line, "SENDCERT_SKI", 12)
+           && (line[12]==' ' || !line[12]))
+    {
+      /* We don't support this but dirmngr might ask for it.  So
+         simply ignore it by sending back an empty value. */
+      err = assuan_send_data (parm->ctx, NULL, 0);
+    }
+  else if (!strncmp (line, "SENDISSUERCERT", 14)
+           && (line[14] == ' ' || !line[14]))
+    {
+      /* We don't support this but dirmngr might ask for it.  So
+         simply ignore it by sending back an empty value. */
+      err = assuan_send_data (parm->ctx, NULL, 0);
+    }
+  else
+    {
+      log_info (_("unsupported inquiry '%s'\n"), line);
+      err = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
+      /* Note that this error will let assuan_transact terminate
+         immediately instead of return the error to the caller.  It is
+         not clear whether this is the desired behaviour - it may
+         change in future. */
+    }
+
+  return err;
+}
+
+
+/* Check the certificate CERT,CERTLEN for validity using a CRL or OCSP.
+   Return a proper error code. */
+static gpg_error_t
+do_check (assuan_context_t ctx, const unsigned char *cert, size_t certlen)
+{
+  gpg_error_t err;
+  struct inq_cert_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+  parm.ctx = ctx;
+  parm.cert = cert;
+  parm.certlen = certlen;
+
+  err = assuan_transact (ctx,
+                         (opt.use_ocsp && opt.force_default_responder
+                          ? "CHECKOCSP --force-default-responder"
+                          : opt.use_ocsp? "CHECKOCSP" : "CHECKCRL"),
+                         NULL, NULL, inq_cert, &parm, status_cb, NULL);
+  if (opt.verbose > 1)
+    log_info ("response of dirmngr: %s\n", err? gpg_strerror (err): "okay");
+  return err;
+}
+
+/* Check the certificate CERT,CERTLEN for validity using a CRL or OCSP.
+   Return a proper error code. */
+static gpg_error_t
+do_cache (assuan_context_t ctx, const unsigned char *cert, size_t certlen)
+{
+  gpg_error_t err;
+  struct inq_cert_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+  parm.ctx = ctx;
+  parm.cert = cert;
+  parm.certlen = certlen;
+
+  err = assuan_transact (ctx, "CACHECERT", NULL, NULL,
+                        inq_cert, &parm,
+                        status_cb, NULL);
+  if (opt.verbose > 1)
+    log_info ("response of dirmngr: %s\n", err? gpg_strerror (err): "okay");
+  return err;
+}
+
+/* Check the certificate CERT,CERTLEN for validity using dirmngrs
+   internal validate feature.  Return a proper error code. */
+static gpg_error_t
+do_validate (assuan_context_t ctx, const unsigned char *cert, size_t certlen)
+{
+  gpg_error_t err;
+  struct inq_cert_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+  parm.ctx = ctx;
+  parm.cert = cert;
+  parm.certlen = certlen;
+
+  err = assuan_transact (ctx, "VALIDATE", NULL, NULL,
+                        inq_cert, &parm,
+                        status_cb, NULL);
+  if (opt.verbose > 1)
+    log_info ("response of dirmngr: %s\n", err? gpg_strerror (err): "okay");
+  return err;
+}
+
+/* Load a CRL into the dirmngr.  */
+static gpg_error_t
+do_loadcrl (assuan_context_t ctx, const char *filename)
+{
+  gpg_error_t err;
+  const char *s;
+  char *fname, *line, *p;
+
+  if (opt.url)
+    fname = xstrdup (filename);
+  else
+    {
+#ifdef HAVE_CANONICALIZE_FILE_NAME
+      fname = canonicalize_file_name (filename);
+      if (!fname)
+        {
+          log_error ("error canonicalizing '%s': %s\n",
+                     filename, strerror (errno));
+          return gpg_error (GPG_ERR_GENERAL);
+        }
+#else
+      fname = xstrdup (filename);
+#endif
+      if (*fname != '/')
+        {
+          log_error (_("absolute file name expected\n"));
+          return gpg_error (GPG_ERR_GENERAL);
+        }
+    }
+
+  line = xmalloc (8 + 6 + strlen (fname) * 3 + 1);
+  p = stpcpy (line, "LOADCRL ");
+  if (opt.url)
+    p = stpcpy (p, "--url ");
+  for (s = fname; *s; s++)
+    {
+      if (*s < ' ' || *s == '+')
+        {
+          sprintf (p, "%%%02X", *s);
+          p += 3;
+        }
+      else if (*s == ' ')
+        *p++ = '+';
+      else
+        *p++ = *s;
+        }
+  *p = 0;
+
+  err = assuan_transact (ctx, line, NULL, NULL,
+                        NULL, NULL,
+                        status_cb, NULL);
+  if (opt.verbose > 1)
+    log_info ("response of dirmngr: %s\n", err? gpg_strerror (err): "okay");
+  xfree (line);
+  xfree (fname);
+  return err;
+}
+
+
+/* Do a LDAP lookup using PATTERN and print the result in a base-64
+   encoded format.  */
+static gpg_error_t
+do_lookup (assuan_context_t ctx, const char *pattern)
+{
+  gpg_error_t err;
+  const unsigned char *s;
+  char *line, *p;
+  struct b64state state;
+
+  if (opt.verbose)
+    log_info (_("looking up '%s'\n"), pattern);
+
+  err = b64enc_start (&state, stdout, NULL);
+  if (err)
+    return err;
+
+  line = xmalloc (10 + 6 + 13 + strlen (pattern)*3 + 1);
+
+  p = stpcpy (line, "LOOKUP ");
+  if (opt.url)
+    p = stpcpy (p, "--url ");
+  if (opt.local)
+    p = stpcpy (p, "--cache-only ");
+  for (s=pattern; *s; s++)
+    {
+      if (*s < ' ' || *s == '+')
+        {
+          sprintf (p, "%%%02X", *s);
+          p += 3;
+        }
+      else if (*s == ' ')
+        *p++ = '+';
+      else
+        *p++ = *s;
+    }
+  *p = 0;
+
+
+  err = assuan_transact (ctx, line,
+                         data_cb, &state,
+                         NULL, NULL,
+                         status_cb, NULL);
+  if (opt.verbose > 1)
+    log_info ("response of dirmngr: %s\n", err? gpg_strerror (err): "okay");
+
+  err = b64enc_finish (&state);
+
+  xfree (line);
+  return err;
+}
+
+/* The body of an endless loop: Read a line from stdin, retrieve the
+   certificate from it, validate it and print "ERR" or "OK" to stdout.
+   Continue.  */
+static gpg_error_t
+squid_loop_body (assuan_context_t ctx)
+{
+  gpg_error_t err;
+  unsigned char *certbuf;
+  size_t certbuflen = 0;
+
+  err = read_pem_certificate (NULL, &certbuf, &certbuflen);
+  if (gpg_err_code (err) == GPG_ERR_EOF)
+    return err;
+  if (err)
+    {
+      log_error (_("error reading certificate from stdin: %s\n"),
+                 gpg_strerror (err));
+      puts ("ERROR");
+      return 0;
+    }
+
+  err = do_check (ctx, certbuf, certbuflen);
+  xfree (certbuf);
+  if (!err)
+    {
+      if (opt.verbose)
+        log_info (_("certificate is valid\n"));
+      puts ("OK");
+    }
+  else
+    {
+      if (!opt.quiet)
+        {
+          if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED )
+            log_info (_("certificate has been revoked\n"));
+          else
+            log_error (_("certificate check failed: %s\n"),
+                       gpg_strerror (err));
+        }
+      puts ("ERROR");
+    }
+
+  fflush (stdout);
+
+  return 0;
+}
diff --git a/dirmngr/dirmngr-err.h b/dirmngr/dirmngr-err.h
new file mode 100644 (file)
index 0000000..17e8255
--- /dev/null
@@ -0,0 +1,12 @@
+/* Definition of the gpg-error source.  */
+
+#ifndef DIRMNGR_ERR_H
+#define DIRMNGR_ERR_H
+
+#ifdef GPG_ERR_SOURCE_DEFAULT
+#error GPG_ERR_SOURCE_DEFAULT already defined
+#endif
+#define GPG_ERR_SOURCE_DEFAULT  GPG_ERR_SOURCE_DIRMNGR
+#include <gpg-error.h>
+
+#endif /*DIRMNGR_ERR_H*/
diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
new file mode 100644 (file)
index 0000000..95f9058
--- /dev/null
@@ -0,0 +1,2032 @@
+/* dirmngr.c - Keyserver and X.509 LDAP access
+ * Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2010, 2011 g10 Code GmbH
+ * Copyright (C) 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <fcntl.h>
+#ifndef HAVE_W32_SYSTEM
+#include <sys/socket.h>
+#include <sys/un.h>
+#endif
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+#include <npth.h>
+
+#include "dirmngr-err.h"
+
+#if  HTTP_USE_NTBTLS
+# include <ntbtls.h>
+#elif HTTP_USE_GNUTLS
+# include <gnutls/gnutls.h>
+#endif /*HTTP_USE_GNUTLS*/
+
+
+#define JNLIB_NEED_LOG_LOGV
+#define JNLIB_NEED_AFLOCAL
+#include "dirmngr.h"
+
+#include <assuan.h>
+
+#include "certcache.h"
+#include "crlcache.h"
+#include "crlfetch.h"
+#include "misc.h"
+#if USE_LDAP
+# include "ldapserver.h"
+#endif
+#include "asshelp.h"
+#if USE_LDAP
+# include "ldap-wrapper.h"
+#endif
+#include "../common/init.h"
+#include "gc-opt-flags.h"
+
+/* The plain Windows version uses the windows service system.  For
+   example to start the service you may use "sc start dirmngr".
+   WindowsCE does not support this; the service system over there is
+   based on a single process with all services being DLLs - we can't
+   support this easily.  */
+#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
+# define USE_W32_SERVICE 1
+#endif
+
+
+enum cmd_and_opt_values {
+  aNull = 0,
+  oCsh           = 'c',
+  oQuiet         = 'q',
+  oSh            = 's',
+  oVerbose       = 'v',
+  oNoVerbose = 500,
+
+  aServer,
+  aDaemon,
+  aService,
+  aListCRLs,
+  aLoadCRL,
+  aFetchCRL,
+  aShutdown,
+  aFlush,
+  aGPGConfList,
+  aGPGConfTest,
+
+  oOptions,
+  oDebug,
+  oDebugAll,
+  oDebugWait,
+  oDebugLevel,
+  oGnutlsDebug,
+  oNoGreeting,
+  oNoOptions,
+  oHomedir,
+  oNoDetach,
+  oLogFile,
+  oBatch,
+  oDisableHTTP,
+  oDisableLDAP,
+  oIgnoreLDAPDP,
+  oIgnoreHTTPDP,
+  oIgnoreOCSPSvcUrl,
+  oHonorHTTPProxy,
+  oHTTPProxy,
+  oLDAPProxy,
+  oOnlyLDAPProxy,
+  oLDAPFile,
+  oLDAPTimeout,
+  oLDAPAddServers,
+  oOCSPResponder,
+  oOCSPSigner,
+  oOCSPMaxClockSkew,
+  oOCSPMaxPeriod,
+  oOCSPCurrentPeriod,
+  oMaxReplies,
+  oHkpCaCert,
+  oFakedSystemTime,
+  oForce,
+  oAllowOCSP,
+  oSocketName,
+  oLDAPWrapperProgram,
+  oHTTPWrapperProgram,
+  oIgnoreCertExtension,
+  aTest
+};
+
+
+
+static ARGPARSE_OPTS opts[] = {
+
+  ARGPARSE_group (300, N_("@Commands:\n ")),
+
+  ARGPARSE_c (aServer,   "server",  N_("run in server mode (foreground)") ),
+  ARGPARSE_c (aDaemon,   "daemon",  N_("run in daemon mode (background)") ),
+#ifdef USE_W32_SERVICE
+  ARGPARSE_c (aService,  "service", N_("run as windows service (background)")),
+#endif
+  ARGPARSE_c (aListCRLs, "list-crls", N_("list the contents of the CRL cache")),
+  ARGPARSE_c (aLoadCRL,  "load-crl",  N_("|FILE|load CRL from FILE into cache")),
+  ARGPARSE_c (aFetchCRL, "fetch-crl", N_("|URL|fetch a CRL from URL")),
+  ARGPARSE_c (aShutdown, "shutdown",  N_("shutdown the dirmngr")),
+  ARGPARSE_c (aFlush,    "flush",     N_("flush the cache")),
+  ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
+  ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
+
+  ARGPARSE_group (301, N_("@\nOptions:\n ")),
+
+  ARGPARSE_s_n (oVerbose,  "verbose",   N_("verbose")),
+  ARGPARSE_s_n (oQuiet,    "quiet",     N_("be somewhat more quiet")),
+  ARGPARSE_s_n (oSh,       "sh",        N_("sh-style command output")),
+  ARGPARSE_s_n (oCsh,      "csh",       N_("csh-style command output")),
+  ARGPARSE_s_s (oOptions,  "options",   N_("|FILE|read options from FILE")),
+  ARGPARSE_s_s (oDebugLevel, "debug-level",
+                N_("|LEVEL|set the debugging level to LEVEL")),
+  ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
+  ARGPARSE_s_s (oLogFile,  "log-file",
+                N_("|FILE|write server mode logs to FILE")),
+  ARGPARSE_s_n (oBatch,    "batch",       N_("run without asking a user")),
+  ARGPARSE_s_n (oForce,    "force",       N_("force loading of outdated CRLs")),
+  ARGPARSE_s_n (oAllowOCSP, "allow-ocsp", N_("allow sending OCSP requests")),
+  ARGPARSE_s_n (oDisableHTTP, "disable-http", N_("inhibit the use of HTTP")),
+  ARGPARSE_s_n (oDisableLDAP, "disable-ldap", N_("inhibit the use of LDAP")),
+  ARGPARSE_s_n (oIgnoreHTTPDP,"ignore-http-dp",
+                N_("ignore HTTP CRL distribution points")),
+  ARGPARSE_s_n (oIgnoreLDAPDP,"ignore-ldap-dp",
+                N_("ignore LDAP CRL distribution points")),
+  ARGPARSE_s_n (oIgnoreOCSPSvcUrl, "ignore-ocsp-service-url",
+                N_("ignore certificate contained OCSP service URLs")),
+
+  ARGPARSE_s_s (oHTTPProxy,  "http-proxy",
+                N_("|URL|redirect all HTTP requests to URL")),
+  ARGPARSE_s_s (oLDAPProxy,  "ldap-proxy",
+                N_("|HOST|use HOST for LDAP queries")),
+  ARGPARSE_s_n (oOnlyLDAPProxy, "only-ldap-proxy",
+                N_("do not use fallback hosts with --ldap-proxy")),
+
+  ARGPARSE_s_s (oLDAPFile, "ldapserverlist-file",
+                N_("|FILE|read LDAP server list from FILE")),
+  ARGPARSE_s_n (oLDAPAddServers, "add-servers",
+                N_("add new servers discovered in CRL distribution"
+                   " points to serverlist")),
+  ARGPARSE_s_i (oLDAPTimeout, "ldaptimeout",
+                N_("|N|set LDAP timeout to N seconds")),
+
+  ARGPARSE_s_s (oOCSPResponder, "ocsp-responder",
+                N_("|URL|use OCSP responder at URL")),
+  ARGPARSE_s_s (oOCSPSigner, "ocsp-signer",
+                N_("|FPR|OCSP response signed by FPR")),
+  ARGPARSE_s_i (oOCSPMaxClockSkew, "ocsp-max-clock-skew", "@"),
+  ARGPARSE_s_i (oOCSPMaxPeriod,    "ocsp-max-period", "@"),
+  ARGPARSE_s_i (oOCSPCurrentPeriod, "ocsp-current-period", "@"),
+
+  ARGPARSE_s_i (oMaxReplies, "max-replies",
+                N_("|N|do not return more than N items in one query")),
+
+  ARGPARSE_s_s (oHkpCaCert, "hkp-cacert",
+                N_("|FILE|use the CA certificates in FILE for HKP over TLS")),
+
+
+  ARGPARSE_s_s (oSocketName, "socket-name", "@"),  /* Only for debugging.  */
+
+  ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
+  ARGPARSE_p_u (oDebug,    "debug", "@"),
+  ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
+  ARGPARSE_s_i (oGnutlsDebug, "gnutls-debug", "@"),
+  ARGPARSE_s_i (oGnutlsDebug, "tls-debug", "@"),
+  ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
+  ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
+  ARGPARSE_s_s (oHomedir, "homedir", "@"),
+  ARGPARSE_s_s (oLDAPWrapperProgram, "ldap-wrapper-program", "@"),
+  ARGPARSE_s_s (oHTTPWrapperProgram, "http-wrapper-program", "@"),
+  ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy", "@"),
+  ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"),
+
+  ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
+                         "of all commands and options)\n")),
+
+  ARGPARSE_end ()
+};
+
+#define DEFAULT_MAX_REPLIES 10
+#define DEFAULT_LDAP_TIMEOUT 100 /* arbitrary large timeout */
+
+/* For the cleanup handler we need to keep track of the socket's name. */
+static const char *socket_name;
+
+/* We need to keep track of the server's nonces (these are dummies for
+   POSIX systems). */
+static assuan_sock_nonce_t socket_nonce;
+
+/* Only if this flag has been set we will remove the socket file.  */
+static int cleanup_socket;
+
+/* Keep track of the current log file so that we can avoid updating
+   the log file after a SIGHUP if it didn't changed. Malloced. */
+static char *current_logfile;
+
+/* Helper to implement --debug-level. */
+static const char *debug_level;
+
+/* Helper to set the NTBTLS or GNUTLS log level.  */
+static int opt_gnutls_debug = -1;
+
+/* Flag indicating that a shutdown has been requested.  */
+static volatile int shutdown_pending;
+
+/* Counter for the active connections.  */
+static int active_connections;
+
+/* The timer tick used for housekeeping stuff.  For Windows we use a
+   longer period as the SetWaitableTimer seems to signal earlier than
+   the 2 seconds.  All values are in seconds. */
+#if defined(HAVE_W32CE_SYSTEM)
+# define TIMERTICK_INTERVAL         (60)
+#elif defined(HAVE_W32_SYSTEM)
+# define TIMERTICK_INTERVAL          (4)
+#else
+# define TIMERTICK_INTERVAL          (2)
+#endif
+
+#define HOUSEKEEPING_INTERVAL      (600)
+
+
+/* This union is used to avoid compiler warnings in case a pointer is
+   64 bit and an int 32 bit.  We store an integer in a pointer and get
+   it back later (npth_getspecific et al.).  */
+union int_and_ptr_u
+{
+  int  aint;
+  assuan_fd_t afd;
+  void *aptr;
+};
+
+
+
+/* The key used to store the current file descriptor in the thread
+   local storage.  We use this in conjunction with the
+   log_set_pid_suffix_cb feature..  */
+#ifndef HAVE_W32_SYSTEM
+static int my_tlskey_current_fd;
+#endif
+
+/* Prototypes. */
+static void cleanup (void);
+#if USE_LDAP
+static ldap_server_t parse_ldapserver_file (const char* filename);
+#endif /*USE_LDAP*/
+static fingerprint_list_t parse_ocsp_signer (const char *string);
+static void handle_connections (assuan_fd_t listen_fd);
+
+/* NPth wrapper function definitions. */
+ASSUAN_SYSTEM_NPTH_IMPL;
+
+static const char *
+my_strusage( int level )
+{
+  const char *p;
+  switch ( level )
+    {
+    case 11: p = "@DIRMNGR@ (@GNUPG@)";
+      break;
+    case 13: p = VERSION; break;
+    case 17: p = PRINTABLE_OS_NAME; break;
+      /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug
+         reporting address.  This is so that we can change the
+         reporting address without breaking the translations.  */
+    case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
+    case 49: p = PACKAGE_BUGREPORT; break;
+    case 1:
+    case 40: p = _("Usage: @DIRMNGR@ [options] (-h for help)");
+      break;
+    case 41: p = _("Syntax: @DIRMNGR@ [options] [command [args]]\n"
+                   "Keyserver, CRL, and OCSP access for @GNUPG@\n");
+      break;
+
+    default: p = NULL;
+    }
+  return p;
+}
+
+
+/* Callback from libksba to hash a provided buffer.  Our current
+   implementation does only allow SHA-1 for hashing. This may be
+   extended by mapping the name, testing for algorithm availibility
+   and adjust the length checks accordingly. */
+static gpg_error_t
+my_ksba_hash_buffer (void *arg, const char *oid,
+                     const void *buffer, size_t length, size_t resultsize,
+                     unsigned char *result, size_t *resultlen)
+{
+  (void)arg;
+
+  if (oid && strcmp (oid, "1.3.14.3.2.26"))
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+  if (resultsize < 20)
+    return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+  gcry_md_hash_buffer (2, result, buffer, length);
+  *resultlen = 20;
+  return 0;
+}
+
+
+/* GNUTLS log function callback.  */
+static void
+my_gnutls_log (int level, const char *text)
+{
+  int n;
+
+  n = strlen (text);
+  while (n && text[n-1] == '\n')
+    n--;
+
+  log_debug ("gnutls:L%d: %.*s\n", level, n, text);
+}
+
+
+/* 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 (void)
+{
+  int numok = (debug_level && digitp (debug_level));
+  int numlvl = numok? atoi (debug_level) : 0;
+
+  if (!debug_level)
+    ;
+  else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
+    opt.debug = 0;
+  else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
+    opt.debug = DBG_ASSUAN_VALUE;
+  else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
+    opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE);
+  else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
+    opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE
+                 |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE);
+  else if (!strcmp (debug_level, "guru") || numok)
+    {
+      opt.debug = ~0;
+      /* Unless the "guru" string has been used we don't want to allow
+         hashing debugging.  The rationale is that people tend to
+         select the highest debug value and would then clutter their
+         disk with debug files which may reveal confidential data.  */
+      if (numok)
+        opt.debug &= ~(DBG_HASHING_VALUE);
+    }
+  else
+    {
+      log_error (_("invalid debug-level '%s' given\n"), debug_level);
+      log_info (_("valid debug levels are: %s\n"),
+                "none, basic, advanced, expert, guru");
+      opt.debug = 0; /* Reset debugging, so that prior debug
+                        statements won't have an undesired effect. */
+    }
+
+
+  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_CRYPTO_VALUE )
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
+
+#if HTTP_USE_NTBTLS
+  if (opt_gnutls_debug >= 0)
+    {
+      ntbtls_set_debug (opt_gnutls_debug, NULL, NULL);
+    }
+#elif HTTP_USE_GNUTLS
+  if (opt_gnutls_debug >= 0)
+    {
+      gnutls_global_set_log_function (my_gnutls_log);
+      gnutls_global_set_log_level (opt_gnutls_debug);
+    }
+#endif /*HTTP_USE_GNUTLS*/
+}
+
+
+static void
+wrong_args (const char *text)
+{
+  es_fprintf (es_stderr, _("usage: %s [options] "), DIRMNGR_NAME);
+  es_fputs (text, es_stderr);
+  es_putc ('\n', es_stderr);
+  dirmngr_exit (2);
+}
+
+
+/* Helper to stop the reaper thread for the ldap wrapper.  */
+static void
+shutdown_reaper (void)
+{
+#if USE_LDAP
+  ldap_wrapper_wait_connections ();
+#endif
+}
+
+
+/* Handle options which are allowed to be reset after program start.
+   Return true if the current option in PARGS could be handled and
+   false if not.  As a special feature, passing a value of NULL for
+   PARGS, resets the options to the default.  REREAD should be set
+   true if it is not the initial option parsing. */
+static int
+parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+{
+  if (!pargs)
+    { /* Reset mode. */
+      opt.quiet = 0;
+      opt.verbose = 0;
+      opt.debug = 0;
+      opt.ldap_wrapper_program = NULL;
+      opt.disable_http = 0;
+      opt.disable_ldap = 0;
+      opt.honor_http_proxy = 0;
+      opt.http_proxy = NULL;
+      opt.ldap_proxy = NULL;
+      opt.only_ldap_proxy = 0;
+      opt.ignore_http_dp = 0;
+      opt.ignore_ldap_dp = 0;
+      opt.ignore_ocsp_service_url = 0;
+      opt.allow_ocsp = 0;
+      opt.ocsp_responder = NULL;
+      opt.ocsp_max_clock_skew = 10 * 60;      /* 10 minutes.  */
+      opt.ocsp_max_period = 90 * 86400;       /* 90 days.  */
+      opt.ocsp_current_period = 3 * 60 * 60;  /* 3 hours. */
+      opt.max_replies = DEFAULT_MAX_REPLIES;
+      while (opt.ocsp_signer)
+        {
+          fingerprint_list_t tmp = opt.ocsp_signer->next;
+          xfree (opt.ocsp_signer);
+          opt.ocsp_signer = tmp;
+        }
+      FREE_STRLIST (opt.ignored_cert_extensions);
+      http_register_tls_ca (NULL);
+      return 1;
+    }
+
+  switch (pargs->r_opt)
+    {
+    case oQuiet:   opt.quiet = 1; break;
+    case oVerbose: opt.verbose++; 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 oGnutlsDebug: opt_gnutls_debug = pargs->r.ret_int; break;
+
+    case oLogFile:
+      if (!reread)
+        return 0; /* Not handled. */
+      if (!current_logfile || !pargs->r.ret_str
+          || strcmp (current_logfile, pargs->r.ret_str))
+        {
+          log_set_file (pargs->r.ret_str);
+          xfree (current_logfile);
+          current_logfile = xtrystrdup (pargs->r.ret_str);
+        }
+      break;
+
+    case oLDAPWrapperProgram:
+      opt.ldap_wrapper_program = pargs->r.ret_str;
+      break;
+    case oHTTPWrapperProgram:
+      opt.http_wrapper_program = pargs->r.ret_str;
+      break;
+
+    case oDisableHTTP: opt.disable_http = 1; break;
+    case oDisableLDAP: opt.disable_ldap = 1; break;
+    case oHonorHTTPProxy: opt.honor_http_proxy = 1; break;
+    case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break;
+    case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break;
+    case oOnlyLDAPProxy: opt.only_ldap_proxy = 1; break;
+    case oIgnoreHTTPDP: opt.ignore_http_dp = 1; break;
+    case oIgnoreLDAPDP: opt.ignore_ldap_dp = 1; break;
+    case oIgnoreOCSPSvcUrl: opt.ignore_ocsp_service_url = 1; break;
+
+    case oAllowOCSP: opt.allow_ocsp = 1; break;
+    case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
+    case oOCSPSigner:
+      opt.ocsp_signer = parse_ocsp_signer (pargs->r.ret_str);
+      break;
+    case oOCSPMaxClockSkew: opt.ocsp_max_clock_skew = pargs->r.ret_int; break;
+    case oOCSPMaxPeriod: opt.ocsp_max_period = pargs->r.ret_int; break;
+    case oOCSPCurrentPeriod: opt.ocsp_current_period = pargs->r.ret_int; break;
+
+    case oMaxReplies: opt.max_replies = pargs->r.ret_int; break;
+
+    case oHkpCaCert:
+      http_register_tls_ca (pargs->r.ret_str);
+      break;
+
+    case oIgnoreCertExtension:
+      add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
+      break;
+
+    default:
+      return 0; /* Not handled. */
+    }
+
+  return 1; /* Handled. */
+}
+
+
+#ifdef USE_W32_SERVICE
+/* The global status of our service.  */
+SERVICE_STATUS_HANDLE service_handle;
+SERVICE_STATUS service_status;
+
+DWORD WINAPI
+w32_service_control (DWORD control, DWORD event_type, LPVOID event_data,
+                    LPVOID context)
+{
+  (void)event_type;
+  (void)event_data;
+  (void)context;
+
+  /* event_type and event_data are not used here.  */
+  switch (control)
+    {
+    case SERVICE_CONTROL_SHUTDOWN:
+      /* For shutdown we will try to force termination.  */
+      service_status.dwCurrentState = SERVICE_STOP_PENDING;
+      SetServiceStatus (service_handle, &service_status);
+      shutdown_pending = 3;
+      break;
+
+    case SERVICE_CONTROL_STOP:
+      service_status.dwCurrentState = SERVICE_STOP_PENDING;
+      SetServiceStatus (service_handle, &service_status);
+      shutdown_pending = 1;
+      break;
+
+    default:
+      break;
+    }
+  return 0;
+}
+#endif /*USE_W32_SERVICE*/
+
+#ifndef HAVE_W32_SYSTEM
+static int
+pid_suffix_callback (unsigned long *r_suffix)
+{
+  union int_and_ptr_u value;
+
+  value.aptr = npth_getspecific (my_tlskey_current_fd);
+  *r_suffix = value.aint;
+  return (*r_suffix != -1);  /* Use decimal representation.  */
+}
+#endif /*!HAVE_W32_SYSTEM*/
+
+
+#ifdef USE_W32_SERVICE
+# define main real_main
+#endif
+int
+main (int argc, char **argv)
+{
+#ifdef USE_W32_SERVICE
+# undef main
+#endif
+  enum cmd_and_opt_values cmd = 0;
+  ARGPARSE_ARGS pargs;
+  int orig_argc;
+  char **orig_argv;
+  FILE *configfp = NULL;
+  char *configname = NULL;
+  const char *shell;
+  unsigned configlineno;
+  int parse_debug = 0;
+  int default_config =1;
+  int greeting = 0;
+  int nogreeting = 0;
+  int nodetach = 0;
+  int csh_style = 0;
+  char *logfile = NULL;
+#if USE_LDAP
+  char *ldapfile = NULL;
+#endif /*USE_LDAP*/
+  int debug_wait = 0;
+  int rc;
+  int homedir_seen = 0;
+  struct assuan_malloc_hooks malloc_hooks;
+
+#ifdef USE_W32_SERVICE
+  /* The option will be set by main() below if we should run as a
+     system daemon.  */
+  if (opt.system_service)
+    {
+      service_handle
+       = RegisterServiceCtrlHandlerEx ("DirMngr",
+                                       &w32_service_control, NULL /*FIXME*/);
+      if (service_handle == 0)
+       log_error ("failed to register service control handler: ec=%d",
+                  (int) GetLastError ());
+      service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+      service_status.dwCurrentState = SERVICE_START_PENDING;
+      service_status.dwControlsAccepted
+       = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+      service_status.dwWin32ExitCode = NO_ERROR;
+      service_status.dwServiceSpecificExitCode = NO_ERROR;
+      service_status.dwCheckPoint = 0;
+      service_status.dwWaitHint = 10000; /* 10 seconds timeout.  */
+      SetServiceStatus (service_handle, &service_status);
+    }
+#endif /*USE_W32_SERVICE*/
+
+  set_strusage (my_strusage);
+  log_set_prefix (DIRMNGR_NAME, 1|4);
+
+  /* Make sure that our subsystems are ready.  */
+  i18n_init ();
+  init_common_subsystems (&argc, &argv);
+
+  npth_init ();
+
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ /* Check that the libraries are suitable.  Do it here because
+    the option parsing may need services of the libraries. */
+
+  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
+    log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
+               NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
+  if (!ksba_check_version (NEED_KSBA_VERSION) )
+    log_fatal( _("%s is too old (need %s, have %s)\n"), "libksba",
+               NEED_KSBA_VERSION, ksba_check_version (NULL) );
+
+  ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
+  ksba_set_hash_buffer_function (my_ksba_hash_buffer, NULL);
+
+  /* Init TLS library.  */
+#if HTTP_USE_NTBTLS
+  if (!ntbtls_check_version (NEED_NTBTLS_VERSION) )
+    log_fatal( _("%s is too old (need %s, have %s)\n"), "ntbtls",
+               NEED_NTBTLS_VERSION, ntbtls_check_version (NULL) );
+#elif HTTP_USE_GNUTLS
+  rc = gnutls_global_init ();
+  if (rc)
+    log_fatal ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));
+#endif /*HTTP_USE_GNUTLS*/
+
+  /* Init Assuan. */
+  malloc_hooks.malloc = gcry_malloc;
+  malloc_hooks.realloc = gcry_realloc;
+  malloc_hooks.free = gcry_free;
+  assuan_set_malloc_hooks (&malloc_hooks);
+  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
+  assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
+  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
+  assuan_sock_init ();
+  setup_libassuan_logging (&opt.debug);
+
+  setup_libgcrypt_logging ();
+
+  /* Setup defaults. */
+  shell = getenv ("SHELL");
+  if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
+    csh_style = 1;
+
+  opt.homedir = default_homedir ();
+
+  /* Now with NPth running we can set the logging callback.  Our
+     windows implementation does not yet feature the NPth TLS
+     functions.  */
+#ifndef HAVE_W32_SYSTEM
+  if (npth_key_create (&my_tlskey_current_fd, NULL) == 0)
+    if (npth_setspecific (my_tlskey_current_fd, NULL) == 0)
+      log_set_pid_suffix_cb (pid_suffix_callback);
+#endif /*!HAVE_W32_SYSTEM*/
+
+  /* Reset rereadable options to default values. */
+  parse_rereadable_options (NULL, 0);
+
+  /* LDAP defaults.  */
+  opt.add_new_ldapservers = 0;
+  opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT;
+
+  /* Other defaults.  */
+
+  /* Check whether we have a config file given 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 option 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;
+          homedir_seen = 1;
+        }
+      else if (pargs.r_opt == aDaemon)
+        opt.system_daemon = 1;
+      else if (pargs.r_opt == aService)
+        {
+         /* Redundant.  The main function takes care of it.  */
+         opt.system_service = 1;
+         opt.system_daemon = 1;
+       }
+#ifdef HAVE_W32_SYSTEM
+      else if (pargs.r_opt == aGPGConfList || pargs.r_opt == aGPGConfTest)
+       /* We set this so we switch to the system configuration
+          directory below.  This is a crutch to solve the problem
+          that the user configuration is never used on Windows.  Also
+          see below at aGPGConfList.  */
+        opt.system_daemon = 1;
+#endif
+    }
+
+  /* If --daemon has been given on the command line but not --homedir,
+     we switch to /etc/gnupg as default home directory.  Note, that
+     this also overrides the GNUPGHOME environment variable.  */
+  if (opt.system_daemon && !homedir_seen)
+    {
+#ifdef HAVE_W32CE_SYSTEM
+      opt.homedir = DIRSEP_S "gnupg";
+#else
+      opt.homedir = gnupg_sysconfdir ();
+#endif
+      opt.homedir_data = gnupg_datadir ();
+      opt.homedir_cache = gnupg_cachedir ();
+      socket_name = dirmngr_sys_socket_name ();
+    }
+  else if (dirmngr_user_socket_name ())
+    socket_name = dirmngr_user_socket_name ();
+  else
+    socket_name = dirmngr_sys_socket_name ();
+
+  if (default_config)
+    configname = make_filename (opt.homedir, DIRMNGR_NAME".conf", 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) );
+              exit(2);
+           }
+          xfree (configname);
+          configname = NULL;
+       }
+      if (parse_debug && configname )
+        log_info (_("reading options from '%s'\n"), configname );
+      default_config = 0;
+    }
+
+  while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
+    {
+      if (parse_rereadable_options (&pargs, 0))
+        continue; /* Already handled */
+      switch (pargs.r_opt)
+        {
+        case aServer:
+        case aDaemon:
+        case aService:
+        case aShutdown:
+        case aFlush:
+       case aListCRLs:
+       case aLoadCRL:
+        case aFetchCRL:
+       case aGPGConfList:
+       case aGPGConfTest:
+          cmd = pargs.r_opt;
+          break;
+
+        case oQuiet: opt.quiet = 1; break;
+        case oVerbose: opt.verbose++; break;
+        case oBatch: opt.batch=1; 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 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 oNoGreeting: nogreeting = 1; break;
+        case oNoVerbose: opt.verbose = 0; break;
+        case oNoOptions: break; /* no-options */
+        case oHomedir: /* Ignore this option here. */; break;
+        case oNoDetach: nodetach = 1; break;
+        case oLogFile: logfile = pargs.r.ret_str; break;
+        case oCsh: csh_style = 1; break;
+        case oSh: csh_style = 0; break;
+       case oLDAPFile:
+#        if USE_LDAP
+          ldapfile = pargs.r.ret_str;
+#        endif /*USE_LDAP*/
+          break;
+       case oLDAPAddServers: opt.add_new_ldapservers = 1; break;
+       case oLDAPTimeout:
+         opt.ldaptimeout = pargs.r.ret_int;
+         break;
+
+        case oFakedSystemTime:
+          gnupg_set_time ((time_t)pargs.r.ret_ulong, 0);
+          break;
+
+        case oForce: opt.force = 1; break;
+
+        case oSocketName: socket_name = pargs.r.ret_str; break;
+
+        default : pargs.err = configfp? 1:2; break;
+       }
+    }
+  if (configfp)
+    {
+      fclose (configfp);
+      configfp = NULL;
+      /* Keep a copy of the name so that it can be read on SIGHUP. */
+      opt.config_filename = configname;
+      configname = NULL;
+      goto next_pass;
+    }
+  xfree (configname);
+  configname = NULL;
+  if (log_get_errorcount(0))
+    exit(2);
+  if (nogreeting )
+    greeting = 0;
+
+  if (!opt.homedir_data)
+    opt.homedir_data = opt.homedir;
+  if (!opt.homedir_cache)
+    opt.homedir_cache = opt.homedir;
+
+  if (greeting)
+    {
+      es_fprintf (es_stderr, "%s %s; %s\n",
+                  strusage(11), strusage(13), strusage(14) );
+      es_fprintf (es_stderr, "%s\n", strusage(15) );
+    }
+
+#ifdef IS_DEVELOPMENT_VERSION
+  log_info ("NOTE: this is a development version!\n");
+#endif
+
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+    {
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
+    }
+
+  if (!access ("/etc/"DIRMNGR_NAME, F_OK) && !strncmp (opt.homedir, "/etc/", 5))
+    log_info
+      ("NOTE: DirMngr is now a proper part of %s.  The configuration and"
+       " other directory names changed.  Please check that no other version"
+       " of dirmngr is still installed.  To disable this warning, remove the"
+       " directory '/etc/dirmngr'.\n", GNUPG_NAME);
+
+  if (gnupg_faked_time_p ())
+    {
+      gnupg_isotime_t tbuf;
+
+      log_info (_("WARNING: running with faked system time: "));
+      gnupg_get_isotime (tbuf);
+      dump_isotime (tbuf);
+      log_printf ("\n");
+    }
+
+  set_debug ();
+
+  /* Get LDAP server list from file. */
+#if USE_LDAP
+  if (!ldapfile)
+    {
+      ldapfile = make_filename (opt.homedir,
+                                opt.system_daemon?
+                                "ldapservers.conf":"dirmngr_ldapservers.conf",
+                                NULL);
+      opt.ldapservers = parse_ldapserver_file (ldapfile);
+      xfree (ldapfile);
+    }
+  else
+      opt.ldapservers = parse_ldapserver_file (ldapfile);
+#endif /*USE_LDAP*/
+
+#ifndef HAVE_W32_SYSTEM
+  /* We need to ignore the PIPE signal because the we might log to a
+     socket and that code handles EPIPE properly.  The ldap wrapper
+     also requires us to ignore this silly signal. Assuan would set
+     this signal to ignore anyway.*/
+  signal (SIGPIPE, SIG_IGN);
+#endif
+
+  /* Ready.  Now to our duties. */
+  if (!cmd && opt.system_service)
+    cmd = aDaemon;
+  else if (!cmd)
+    cmd = aServer;
+  rc = 0;
+
+  if (cmd == aServer)
+    {
+      /* Note that this server mode is mainly useful for debugging.  */
+      if (argc)
+        wrong_args ("--server");
+
+      if (logfile)
+        {
+          log_set_file (logfile);
+          log_set_prefix (NULL, 2|4);
+        }
+
+      if (debug_wait)
+        {
+          log_debug ("waiting for debugger - my pid is %u .....\n",
+                     (unsigned int)getpid());
+          gnupg_sleep (debug_wait);
+          log_debug ("... okay\n");
+        }
+
+#if USE_LDAP
+      ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
+
+      cert_cache_init ();
+      crl_cache_init ();
+      start_command_handler (ASSUAN_INVALID_FD);
+      shutdown_reaper ();
+    }
+  else if (cmd == aDaemon)
+    {
+      assuan_fd_t fd;
+      pid_t pid;
+      int len;
+      struct sockaddr_un serv_addr;
+
+      if (argc)
+        wrong_args ("--daemon");
+
+      /* Now start with logging to a file if this is desired. */
+      if (logfile)
+        {
+          log_set_file (logfile);
+          log_set_prefix (NULL, (JNLIB_LOG_WITH_PREFIX
+                                 |JNLIB_LOG_WITH_TIME
+                                 |JNLIB_LOG_WITH_PID));
+          current_logfile = xstrdup (logfile);
+        }
+
+#ifndef HAVE_W32_SYSTEM
+      if (strchr (socket_name, ':'))
+        {
+          log_error (_("colons are not allowed in the socket name\n"));
+          dirmngr_exit (1);
+        }
+#endif
+      if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path )
+        {
+          log_error (_("name of socket too long\n"));
+          dirmngr_exit (1);
+        }
+
+      fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
+      if (fd == ASSUAN_INVALID_FD)
+        {
+          log_error (_("can't create socket: %s\n"), strerror (errno));
+          cleanup ();
+          dirmngr_exit (1);
+        }
+
+      memset (&serv_addr, 0, sizeof serv_addr);
+      serv_addr.sun_family = AF_UNIX;
+      strcpy (serv_addr.sun_path, socket_name);
+      len = SUN_LEN (&serv_addr);
+
+      rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
+      if (rc == -1
+          && (errno == EADDRINUSE
+#ifdef HAVE_W32_SYSTEM
+              || errno == EEXIST
+#endif
+              ))
+       {
+          /* Fixme: We should test whether a dirmngr is already running. */
+         gnupg_remove (socket_name);
+         rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
+       }
+      if (rc != -1
+         && (rc = assuan_sock_get_nonce ((struct sockaddr*) &serv_addr, len, &socket_nonce)))
+       log_error (_("error getting nonce for the socket\n"));
+      if (rc == -1)
+        {
+          log_error (_("error binding socket to '%s': %s\n"),
+                     serv_addr.sun_path, gpg_strerror (gpg_error_from_errno (errno)));
+          assuan_sock_close (fd);
+          dirmngr_exit (1);
+        }
+      cleanup_socket = 1;
+
+      if (listen (FD2INT (fd), 5) == -1)
+        {
+          log_error (_("listen() failed: %s\n"), strerror (errno));
+          assuan_sock_close (fd);
+          dirmngr_exit (1);
+        }
+
+      if (opt.verbose)
+        log_info (_("listening on socket '%s'\n"), socket_name );
+
+      es_fflush (NULL);
+
+      /* Note: We keep the dirmngr_info output only for the sake of
+         existing scripts which might use this to detect a successful
+         start of the dirmngr.  */
+#ifdef HAVE_W32_SYSTEM
+      (void)csh_style;
+      (void)nodetach;
+
+      pid = getpid ();
+      es_printf ("set %s=%s;%lu;1\n",
+                 DIRMNGR_INFO_NAME, socket_name, (ulong) pid);
+#else
+      pid = fork();
+      if (pid == (pid_t)-1)
+        {
+          log_fatal (_("error forking process: %s\n"), strerror (errno));
+          dirmngr_exit (1);
+        }
+
+      if (pid)
+        { /* We are the parent */
+          char *infostr;
+
+          /* Don't let cleanup() remove the socket - the child is
+             responsible for doing that.  */
+          cleanup_socket = 0;
+
+          close (fd);
+
+          /* Create the info string: <name>:<pid>:<protocol_version> */
+          if (asprintf (&infostr, "%s=%s:%lu:1",
+                        DIRMNGR_INFO_NAME, socket_name, (ulong)pid ) < 0)
+            {
+              log_error (_("out of core\n"));
+              kill (pid, SIGTERM);
+              dirmngr_exit (1);
+            }
+          /* Print the environment string, so that the caller can use
+             shell's eval to set it.  But see above.  */
+          if (csh_style)
+            {
+              *strchr (infostr, '=') = ' ';
+              es_printf ( "setenv %s;\n", infostr);
+            }
+          else
+            {
+              es_printf ( "%s; export %s;\n", infostr, DIRMNGR_INFO_NAME);
+            }
+          free (infostr);
+          exit (0);
+          /*NEVER REACHED*/
+        } /* end parent */
+
+
+      /*
+         This is the child
+       */
+
+      /* Detach from tty and put process into a new session */
+      if (!nodetach )
+        {
+          int i;
+          unsigned int oldflags;
+
+          /* Close stdin, stdout and stderr unless it is the log stream */
+          for (i=0; i <= 2; i++)
+            {
+              if (!log_test_fd (i) && i != fd )
+                close (i);
+            }
+          if (setsid() == -1)
+            {
+              log_error ("setsid() failed: %s\n", strerror(errno) );
+              dirmngr_exit (1);
+            }
+
+          log_get_prefix (&oldflags);
+          log_set_prefix (NULL, oldflags | JNLIB_LOG_RUN_DETACHED);
+          opt.running_detached = 1;
+
+          if (chdir("/"))
+            {
+              log_error ("chdir to / failed: %s\n", strerror (errno));
+              dirmngr_exit (1);
+            }
+        }
+#endif
+
+#if USE_LDAP
+      ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
+
+      cert_cache_init ();
+      crl_cache_init ();
+#ifdef USE_W32_SERVICE
+      if (opt.system_service)
+       {
+         service_status.dwCurrentState = SERVICE_RUNNING;
+         SetServiceStatus (service_handle, &service_status);
+       }
+#endif
+      handle_connections (fd);
+      assuan_sock_close (fd);
+      shutdown_reaper ();
+#ifdef USE_W32_SERVICE
+      if (opt.system_service)
+       {
+         service_status.dwCurrentState = SERVICE_STOPPED;
+         SetServiceStatus (service_handle, &service_status);
+       }
+#endif
+    }
+  else if (cmd == aListCRLs)
+    {
+      /* Just list the CRL cache and exit. */
+      if (argc)
+        wrong_args ("--list-crls");
+#if USE_LDAP
+      ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
+      crl_cache_init ();
+      crl_cache_list (es_stdout);
+    }
+  else if (cmd == aLoadCRL)
+    {
+      struct server_control_s ctrlbuf;
+
+      memset (&ctrlbuf, 0, sizeof ctrlbuf);
+      dirmngr_init_default_ctrl (&ctrlbuf);
+
+#if USE_LDAP
+      ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
+      cert_cache_init ();
+      crl_cache_init ();
+      if (!argc)
+        rc = crl_cache_load (&ctrlbuf, NULL);
+      else
+        {
+          for (; !rc && argc; argc--, argv++)
+            rc = crl_cache_load (&ctrlbuf, *argv);
+        }
+    }
+  else if (cmd == aFetchCRL)
+    {
+      ksba_reader_t reader;
+      struct server_control_s ctrlbuf;
+
+      if (argc != 1)
+        wrong_args ("--fetch-crl URL");
+
+      memset (&ctrlbuf, 0, sizeof ctrlbuf);
+      dirmngr_init_default_ctrl (&ctrlbuf);
+
+#if USE_LDAP
+      ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
+      cert_cache_init ();
+      crl_cache_init ();
+      rc = crl_fetch (&ctrlbuf, argv[0], &reader);
+      if (rc)
+        log_error (_("fetching CRL from '%s' failed: %s\n"),
+                     argv[0], gpg_strerror (rc));
+      else
+        {
+          rc = crl_cache_insert (&ctrlbuf, argv[0], reader);
+          if (rc)
+            log_error (_("processing CRL from '%s' failed: %s\n"),
+                       argv[0], gpg_strerror (rc));
+          crl_close_reader (reader);
+        }
+    }
+  else if (cmd == aFlush)
+    {
+      /* Delete cache and exit. */
+      if (argc)
+        wrong_args ("--flush");
+      rc = crl_cache_flush();
+    }
+  else if (cmd == aGPGConfTest)
+    dirmngr_exit (0);
+  else if (cmd == aGPGConfList)
+    {
+      unsigned long flags = 0;
+      char *filename;
+      char *filename_esc;
+
+#ifdef HAVE_W32_SYSTEM
+      /* On Windows systems, dirmngr always runs as system daemon, and
+        the per-user configuration is never used.  So we short-cut
+        everything to use the global system configuration of dirmngr
+        above, and here we set the no change flag to make these
+        read-only.  */
+      flags |= GC_OPT_FLAG_NO_CHANGE;
+#endif
+
+      /* First the configuration file.  This is not an option, but it
+        is vital information for GPG Conf.  */
+      if (!opt.config_filename)
+        opt.config_filename = make_filename (opt.homedir,
+                                             "dirmngr.conf", NULL );
+
+      filename = percent_escape (opt.config_filename, NULL);
+      es_printf ("gpgconf-dirmngr.conf:%lu:\"%s\n",
+              GC_OPT_FLAG_DEFAULT, filename);
+      xfree (filename);
+
+      es_printf ("verbose:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("quiet:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("debug-level:%lu:\"none\n", flags | GC_OPT_FLAG_DEFAULT);
+      es_printf ("log-file:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("force:%lu:\n", flags | GC_OPT_FLAG_NONE);
+
+      /* --csh and --sh are mutually exclusive, something we can not
+         express in GPG Conf.  --options is only usable from the
+         command line, really.  --debug-all interacts with --debug,
+         and having both of them is thus problematic.  --no-detach is
+         also only usable on the command line.  --batch is unused.  */
+
+      filename = make_filename (opt.homedir,
+                                opt.system_daemon?
+                                "ldapservers.conf":"dirmngr_ldapservers.conf",
+                                NULL);
+      filename_esc = percent_escape (filename, NULL);
+      es_printf ("ldapserverlist-file:%lu:\"%s\n", flags | GC_OPT_FLAG_DEFAULT,
+             filename_esc);
+      xfree (filename_esc);
+      xfree (filename);
+
+      es_printf ("ldaptimeout:%lu:%u\n",
+              flags | GC_OPT_FLAG_DEFAULT, DEFAULT_LDAP_TIMEOUT);
+      es_printf ("max-replies:%lu:%u\n",
+              flags | GC_OPT_FLAG_DEFAULT, DEFAULT_MAX_REPLIES);
+      es_printf ("allow-ocsp:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("ocsp-responder:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("ocsp-signer:%lu:\n", flags | GC_OPT_FLAG_NONE);
+
+      es_printf ("faked-system-time:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("no-greeting:%lu:\n", flags | GC_OPT_FLAG_NONE);
+
+      es_printf ("disable-http:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("disable-ldap:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("honor-http-proxy:%lu\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("http-proxy:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("ldap-proxy:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("only-ldap-proxy:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("ignore-ldap-dp:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("ignore-http-dp:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("ignore-ocsp-service-url:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      /* Note: The next one is to fix a typo in gpgconf - should be
+         removed eventually. */
+      es_printf ("ignore-ocsp-servic-url:%lu:\n", flags | GC_OPT_FLAG_NONE);
+    }
+  cleanup ();
+  return !!rc;
+}
+
+
+#ifdef USE_W32_SERVICE
+static void WINAPI
+call_real_main (DWORD argc, LPSTR *argv)
+{
+  real_main (argc, argv);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int i;
+
+  /* Find out if we run in daemon mode or on the command line.  */
+  for (i = 1; i < argc; i++)
+    if (!strcmp (argv[i], "--service"))
+      {
+       opt.system_service = 1;
+       opt.system_daemon = 1;
+       break;
+      }
+
+  if (!opt.system_service)
+    return real_main (argc, argv);
+  else
+    {
+      SERVICE_TABLE_ENTRY DispatchTable [] =
+       {
+         { "DirMngr", &call_real_main },
+         { NULL, NULL }
+       };
+
+      if (!StartServiceCtrlDispatcher (DispatchTable))
+        return 1;
+      return 0;
+    }
+}
+#endif /*USE_W32_SERVICE*/
+
+
+static void
+cleanup (void)
+{
+  crl_cache_deinit ();
+  cert_cache_deinit (1);
+
+#if USE_LDAP
+  ldapserver_list_free (opt.ldapservers);
+#endif /*USE_LDAP*/
+  opt.ldapservers = NULL;
+
+  if (cleanup_socket)
+    {
+      cleanup_socket = 0;
+      if (socket_name && *socket_name)
+        gnupg_remove (socket_name);
+    }
+}
+
+
+void
+dirmngr_exit (int rc)
+{
+  cleanup ();
+  exit (rc);
+}
+
+
+void
+dirmngr_init_default_ctrl (ctrl_t ctrl)
+{
+  (void)ctrl;
+
+  /* Nothing for now. */
+}
+
+
+/* Create a list of LDAP servers from the file FILENAME. Returns the
+   list or NULL in case of errors.
+
+   The format fo such a file is line oriented where empty lines and
+   lines starting with a hash mark are ignored.  All other lines are
+   assumed to be colon seprated with these fields:
+
+   1. field: Hostname
+   2. field: Portnumber
+   3. field: Username
+   4. field: Password
+   5. field: Base DN
+
+*/
+#if USE_LDAP
+static ldap_server_t
+parse_ldapserver_file (const char* filename)
+{
+  char buffer[1024];
+  char *p;
+  ldap_server_t server, serverstart, *serverend;
+  int c;
+  unsigned int lineno = 0;
+  estream_t fp;
+
+  fp = es_fopen (filename, "r");
+  if (!fp)
+    {
+      log_error (_("error opening '%s': %s\n"), filename, strerror (errno));
+      return NULL;
+    }
+
+  serverstart = NULL;
+  serverend = &serverstart;
+  while (es_fgets (buffer, sizeof buffer, fp))
+    {
+      lineno++;
+      if (!*buffer || buffer[strlen(buffer)-1] != '\n')
+        {
+          if (*buffer && es_feof (fp))
+            ; /* Last line not terminated - continue. */
+          else
+            {
+              log_error (_("%s:%u: line too long - skipped\n"),
+                         filename, lineno);
+              while ( (c=es_fgetc (fp)) != EOF && c != '\n')
+                ; /* Skip until end of line. */
+              continue;
+            }
+        }
+      /* Skip empty and comment lines.*/
+      for (p=buffer; spacep (p); p++)
+        ;
+      if (!*p || *p == '\n' || *p == '#')
+        continue;
+
+      /* Parse the colon separated fields. */
+      server = ldapserver_parse_one (buffer, filename, lineno);
+      if (server)
+        {
+          *serverend = server;
+          serverend = &server->next;
+        }
+    }
+
+  if (es_ferror (fp))
+    log_error (_("error reading '%s': %s\n"), filename, strerror (errno));
+  es_fclose (fp);
+
+  return serverstart;
+}
+#endif /*USE_LDAP*/
+
+static fingerprint_list_t
+parse_ocsp_signer (const char *string)
+{
+  gpg_error_t err;
+  char *fname;
+  estream_t fp;
+  char line[256];
+  char *p;
+  fingerprint_list_t list, *list_tail, item;
+  unsigned int lnr = 0;
+  int c, i, j;
+  int errflag = 0;
+
+
+  /* Check whether this is not a filename and treat it as a direct
+     fingerprint specification.  */
+  if (!strpbrk (string, "/.~\\"))
+    {
+      item = xcalloc (1, sizeof *item);
+      for (i=j=0; (string[i] == ':' || hexdigitp (string+i)) && j < 40; i++)
+        if ( string[i] != ':' )
+          item->hexfpr[j++] = string[i] >= 'a'? (string[i] & 0xdf): string[i];
+      item->hexfpr[j] = 0;
+      if (j != 40 || !(spacep (string+i) || !string[i]))
+        {
+          log_error (_("%s:%u: invalid fingerprint detected\n"),
+                     "--ocsp-signer", 0);
+          xfree (item);
+          return NULL;
+        }
+      return item;
+    }
+
+  /* Well, it is a filename.  */
+  if (*string == '/' || (*string == '~' && string[1] == '/'))
+    fname = make_filename (string, NULL);
+  else
+    {
+      if (string[0] == '.' && string[1] == '/' )
+        string += 2;
+      fname = make_filename (opt.homedir, string, NULL);
+    }
+
+  fp = es_fopen (fname, "r");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err));
+      xfree (fname);
+      return NULL;
+    }
+
+  list = NULL;
+  list_tail = &list;
+  for (;;)
+    {
+      if (!es_fgets (line, DIM(line)-1, fp) )
+        {
+          if (!es_feof (fp))
+            {
+              err = gpg_error_from_syserror ();
+              log_error (_("%s:%u: read error: %s\n"),
+                         fname, lnr, gpg_strerror (err));
+              errflag = 1;
+            }
+          es_fclose (fp);
+          if (errflag)
+            {
+              while (list)
+                {
+                  fingerprint_list_t tmp = list->next;
+                  xfree (list);
+                  list = tmp;
+                }
+            }
+          xfree (fname);
+          return list; /* Ready.  */
+        }
+
+      lnr++;
+      if (!*line || line[strlen(line)-1] != '\n')
+        {
+          /* Eat until end of line. */
+          while ( (c=es_getc (fp)) != EOF && c != '\n')
+            ;
+          err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
+                           /* */: GPG_ERR_INCOMPLETE_LINE);
+          log_error (_("%s:%u: read error: %s\n"),
+                     fname, lnr, gpg_strerror (err));
+          errflag = 1;
+          continue;
+        }
+
+      /* Allow for empty lines and spaces */
+      for (p=line; spacep (p); p++)
+        ;
+      if (!*p || *p == '\n' || *p == '#')
+        continue;
+
+      item = xcalloc (1, sizeof *item);
+      *list_tail = item;
+      list_tail = &item->next;
+
+      for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
+        if ( p[i] != ':' )
+          item->hexfpr[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
+      item->hexfpr[j] = 0;
+      if (j != 40 || !(spacep (p+i) || p[i] == '\n'))
+        {
+          log_error (_("%s:%u: invalid fingerprint detected\n"), fname, lnr);
+          errflag = 1;
+        }
+      i++;
+      while (spacep (p+i))
+        i++;
+      if (p[i] && p[i] != '\n')
+        log_info (_("%s:%u: garbage at end of line ignored\n"), fname, lnr);
+    }
+  /*NOTREACHED*/
+}
+
+
+
+\f
+/*
+   Stuff used in daemon mode.
+ */
+
+
+
+/* Reread parts of the configuration.  Note, that this function is
+   obviously not thread-safe and should only be called from the NPTH
+   signal handler.
+
+   Fixme: Due to the way the argument parsing works, we create a
+   memory leak here for all string type arguments.  There is currently
+   no clean way to tell whether the memory for the argument has been
+   allocated or points into the process' original arguments.  Unless
+   we have a mechanism to tell this, we need to live on with this. */
+static void
+reread_configuration (void)
+{
+  ARGPARSE_ARGS pargs;
+  FILE *fp;
+  unsigned int configlineno = 0;
+  int dummy;
+
+  if (!opt.config_filename)
+    return; /* No config file. */
+
+  fp = fopen (opt.config_filename, "r");
+  if (!fp)
+    {
+      log_error (_("option file '%s': %s\n"),
+                 opt.config_filename, strerror(errno) );
+      return;
+    }
+
+  parse_rereadable_options (NULL, 1); /* Start from the default values. */
+
+  memset (&pargs, 0, sizeof pargs);
+  dummy = 0;
+  pargs.argc = &dummy;
+  pargs.flags = 1;  /* do not remove the args */
+  while (optfile_parse (fp, opt.config_filename, &configlineno, &pargs, opts) )
+    {
+      if (pargs.r_opt < -1)
+        pargs.err = 1; /* Print a warning. */
+      else /* Try to parse this option - ignore unchangeable ones. */
+        parse_rereadable_options (&pargs, 1);
+    }
+  fclose (fp);
+
+  set_debug ();
+}
+
+
+/* A global function which allows us to trigger the reload stuff from
+   other places.  */
+void
+dirmngr_sighup_action (void)
+{
+  log_info (_("SIGHUP received - "
+              "re-reading configuration and flushing caches\n"));
+  reread_configuration ();
+  cert_cache_deinit (0);
+  crl_cache_deinit ();
+  cert_cache_init ();
+  crl_cache_init ();
+}
+
+
+
+/* The signal handler. */
+#ifndef HAVE_W32_SYSTEM
+static void
+handle_signal (int signo)
+{
+  switch (signo)
+    {
+    case SIGHUP:
+      dirmngr_sighup_action ();
+      break;
+
+    case SIGUSR1:
+      cert_cache_print_stats ();
+      break;
+
+    case SIGUSR2:
+      log_info (_("SIGUSR2 received - no action defined\n"));
+      break;
+
+    case SIGTERM:
+      if (!shutdown_pending)
+        log_info (_("SIGTERM received - shutting down ...\n"));
+      else
+        log_info (_("SIGTERM received - still %d active connections\n"),
+                  active_connections);
+      shutdown_pending++;
+      if (shutdown_pending > 2)
+        {
+          log_info (_("shutdown forced\n"));
+          log_info ("%s %s stopped\n", strusage(11), strusage(13) );
+          cleanup ();
+          dirmngr_exit (0);
+       }
+      break;
+
+    case SIGINT:
+      log_info (_("SIGINT received - immediate shutdown\n"));
+      log_info( "%s %s stopped\n", strusage(11), strusage(13));
+      cleanup ();
+      dirmngr_exit (0);
+      break;
+
+    default:
+      log_info (_("signal %d received - no action defined\n"), signo);
+    }
+}
+#endif /*!HAVE_W32_SYSTEM*/
+
+
+/* Thread to do the housekeeping.  */
+static void *
+housekeeping_thread (void *arg)
+{
+  static int sentinel;
+  time_t curtime;
+
+  (void)arg;
+
+  curtime = gnupg_get_time ();
+  if (sentinel)
+    {
+      log_info ("housekeeping is already going on\n");
+      return NULL;
+    }
+  sentinel++;
+  if (opt.verbose)
+    log_info ("starting housekeeping\n");
+
+  ks_hkp_housekeeping (curtime);
+
+  if (opt.verbose)
+    log_info ("ready with housekeeping\n");
+  sentinel--;
+  return NULL;
+
+}
+
+
+#if JNLIB_GCC_HAVE_PUSH_PRAGMA
+# pragma GCC push_options
+# pragma GCC optimize ("no-strict-overflow")
+#endif
+static int
+time_for_housekeeping_p (time_t curtime)
+{
+  static time_t last_housekeeping;
+
+  if (!last_housekeeping)
+    last_housekeeping = curtime;
+
+  if (last_housekeeping + HOUSEKEEPING_INTERVAL <= curtime
+      || last_housekeeping > curtime /*(be prepared for y2038)*/)
+    {
+      last_housekeeping = curtime;
+      return 1;
+    }
+  return 0;
+}
+#if JNLIB_GCC_HAVE_PUSH_PRAGMA
+# pragma GCC pop_options
+#endif
+
+
+/* This is the worker for the ticker.  It is called every few seconds
+   and may only do fast operations. */
+static void
+handle_tick (void)
+{
+  /* Under Windows we don't use signals and need a way for the loop to
+     check for the shutdown flag.  */
+#ifdef HAVE_W32_SYSTEM
+  if (shutdown_pending)
+    log_info (_("SIGTERM received - shutting down ...\n"));
+  if (shutdown_pending > 2)
+    {
+      log_info (_("shutdown forced\n"));
+      log_info ("%s %s stopped\n", strusage(11), strusage(13) );
+      cleanup ();
+      dirmngr_exit (0);
+    }
+#endif /*HAVE_W32_SYSTEM*/
+
+  if (time_for_housekeeping_p (gnupg_get_time ()))
+    {
+      npth_t thread;
+      npth_attr_t tattr;
+      int err;
+
+      err = npth_attr_init (&tattr);
+      if (err)
+        log_error ("error preparing housekeeping thread: %s\n", strerror (err));
+      else
+        {
+          npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+          err = npth_create (&thread, &tattr, housekeeping_thread, NULL);
+          if (err)
+            log_error ("error spawning housekeeping thread: %s\n",
+                       strerror (err));
+          npth_attr_destroy (&tattr);
+        }
+    }
+}
+
+
+/* Check the nonce on a new connection.  This is a NOP unless we we
+   are using our Unix domain socket emulation under Windows.  */
+static int
+check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
+{
+  if (assuan_sock_check_nonce (fd, nonce))
+    {
+      log_info (_("error reading nonce on fd %d: %s\n"),
+                FD2INT (fd), strerror (errno));
+      assuan_sock_close (fd);
+      return -1;
+    }
+  else
+    return 0;
+}
+
+
+/* Helper to call a connection's main fucntion. */
+static void *
+start_connection_thread (void *arg)
+{
+  union int_and_ptr_u argval;
+  gnupg_fd_t fd;
+
+  argval.aptr = arg;
+  fd = argval.afd;
+
+  if (check_nonce (fd, &socket_nonce))
+    {
+      log_error ("handler nonce check FAILED\n");
+      return NULL;
+    }
+
+#ifndef HAVE_W32_SYSTEM
+  npth_setspecific (my_tlskey_current_fd, argval.aptr);
+#endif
+
+  active_connections++;
+  if (opt.verbose)
+    log_info (_("handler for fd %d started\n"), FD2INT (fd));
+
+  start_command_handler (fd);
+
+  if (opt.verbose)
+    log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
+  active_connections--;
+
+#ifndef HAVE_W32_SYSTEM
+  argval.afd = ASSUAN_INVALID_FD;
+  npth_setspecific (my_tlskey_current_fd, argval.aptr);
+#endif
+
+  return NULL;
+}
+
+
+/* Main loop in daemon mode. */
+static void
+handle_connections (assuan_fd_t listen_fd)
+{
+  npth_attr_t tattr;
+#ifndef HAVE_W32_SYSTEM
+  int signo;
+#endif
+  struct sockaddr_un paddr;
+  socklen_t plen = sizeof( paddr );
+  gnupg_fd_t fd;
+  int nfd, ret;
+  fd_set fdset, read_fdset;
+  struct timespec abstime;
+  struct timespec curtime;
+  struct timespec timeout;
+  int saved_errno;
+
+  npth_attr_init (&tattr);
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+
+#ifndef HAVE_W32_SYSTEM /* FIXME */
+  npth_sigev_init ();
+  npth_sigev_add (SIGHUP);
+  npth_sigev_add (SIGUSR1);
+  npth_sigev_add (SIGUSR2);
+  npth_sigev_add (SIGINT);
+  npth_sigev_add (SIGTERM);
+  npth_sigev_fini ();
+#endif
+
+  /* Setup the fdset.  It has only one member.  This is because we use
+     pth_select instead of pth_accept to properly sync timeouts with
+     to full second.  */
+  FD_ZERO (&fdset);
+  FD_SET (FD2INT (listen_fd), &fdset);
+  nfd = FD2INT (listen_fd);
+
+  npth_clock_gettime (&abstime);
+  abstime.tv_sec += TIMERTICK_INTERVAL;
+
+  /* Main loop.  */
+  for (;;)
+    {
+      /* Shutdown test.  */
+      if (shutdown_pending)
+        {
+          if (!active_connections)
+            break; /* ready */
+
+          /* Do not accept new connections but keep on running the
+             loop to cope with the timer events.  */
+          FD_ZERO (&fdset);
+       }
+
+      /* Take a copy of the fdset.  */
+      read_fdset = fdset;
+
+      npth_clock_gettime (&curtime);
+      if (!(npth_timercmp (&curtime, &abstime, <)))
+       {
+         /* Timeout.  */
+         handle_tick ();
+         npth_clock_gettime (&abstime);
+         abstime.tv_sec += TIMERTICK_INTERVAL;
+       }
+      npth_timersub (&abstime, &curtime, &timeout);
+
+#ifndef HAVE_W32_SYSTEM
+      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+      saved_errno = errno;
+
+      while (npth_sigev_get_pending(&signo))
+       handle_signal (signo);
+#else
+      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
+      saved_errno = errno;
+#endif
+
+      if (ret == -1 && saved_errno != EINTR)
+       {
+          log_error (_("npth_pselect failed: %s - waiting 1s\n"),
+                     strerror (saved_errno));
+          npth_sleep (1);
+          continue;
+       }
+
+      if (ret <= 0)
+       /* Interrupt or timeout.  Will be handled when calculating the
+          next timeout.  */
+       continue;
+
+      if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset))
+       {
+          plen = sizeof paddr;
+         fd = INT2FD (npth_accept (FD2INT(listen_fd),
+                                   (struct sockaddr *)&paddr, &plen));
+         if (fd == GNUPG_INVALID_FD)
+           {
+             log_error ("accept failed: %s\n", strerror (errno));
+           }
+          else
+            {
+              char threadname[50];
+              union int_and_ptr_u argval;
+             npth_t thread;
+
+              argval.afd = fd;
+              snprintf (threadname, sizeof threadname-1,
+                        "conn fd=%d", FD2INT(fd));
+              threadname[sizeof threadname -1] = 0;
+
+              ret = npth_create (&thread, &tattr, start_connection_thread, argval.aptr);
+             if (ret)
+                {
+                  log_error ("error spawning connection handler: %s\n",
+                             strerror (ret) );
+                  assuan_sock_close (fd);
+                }
+             npth_setname_np (thread, threadname);
+            }
+          fd = GNUPG_INVALID_FD;
+       }
+    }
+
+  npth_attr_destroy (&tattr);
+  cleanup ();
+  log_info ("%s %s stopped\n", strusage(11), strusage(13));
+}
diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
new file mode 100644 (file)
index 0000000..bb368f2
--- /dev/null
@@ -0,0 +1,206 @@
+/* dirmngr.h - Common definitions for the dirmngr
+ * Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ * Copyright (C) 2004 g10 Code GmbH
+ * Copyright (C) 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIRMNGR_H
+#define DIRMNGR_H
+
+#include "./dirmngr-err.h"
+#define map_assuan_err(a) \
+        map_assuan_err_with_source (GPG_ERR_SOURCE_DEFAULT, (a))
+#include <errno.h>
+#include <gcrypt.h>
+#include <ksba.h>
+
+#include "../common/util.h"
+#include "../common/membuf.h"
+#include "../common/sysutils.h" /* (gnupg_fd_t) */
+#include "../common/i18n.h"
+#include "../common/http.h"     /* (parsed_uri_t) */
+
+/* This objects keeps information about a particular LDAP server and
+   is used as item of a single linked list of servers. */
+struct ldap_server_s
+{
+  struct ldap_server_s* next;
+
+  char *host;
+  int   port;
+  char *user;
+  char *pass;
+  char *base;
+};
+typedef struct ldap_server_s *ldap_server_t;
+
+
+/* This objects is used to build a list of URI consisting of the
+   original and the parsed URI.  */
+struct uri_item_s
+{
+  struct uri_item_s *next;
+  parsed_uri_t parsed_uri;  /* The broken down URI.  */
+  char uri[1];              /* The original URI.  */
+};
+typedef struct uri_item_s *uri_item_t;
+
+
+/* A list of fingerprints.  */
+struct fingerprint_list_s;
+typedef struct fingerprint_list_s *fingerprint_list_t;
+struct fingerprint_list_s
+{
+  fingerprint_list_t next;
+  char hexfpr[20+20+1];
+};
+
+
+/* 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 dry_run;        /* don't change any persistent data */
+  int batch;          /* batch mode */
+  const char *homedir;      /* Configuration directory name */
+  const char *homedir_data; /* Ditto for data files (/usr/share/dirmngr).  */
+  const char *homedir_cache; /* Ditto for cache files (/var/cache/dirmngr).  */
+
+  char *config_filename;     /* Name of a config file, which will be
+                                reread on a HUP if it is not NULL. */
+
+  char *ldap_wrapper_program; /* Override value for the LDAP wrapper
+                                 program.  */
+  char *http_wrapper_program; /* Override value for the HTTP wrapper
+                                 program.  */
+
+  int system_service;   /* We are running as W32 service (implies daemon).  */
+  int system_daemon;    /* We are running in system daemon mode.  */
+  int running_detached; /* We are running in detached mode.  */
+
+  int force;          /* Force loading outdated CRLs. */
+
+  int disable_http;       /* Do not use HTTP at all.  */
+  int disable_ldap;       /* Do not use LDAP at all.  */
+  int honor_http_proxy;   /* Honor the http_proxy env variable. */
+  const char *http_proxy; /* Use given HTTP proxy.  */
+  const char *ldap_proxy; /* Use given LDAP proxy.  */
+  int only_ldap_proxy;    /* Only use the LDAP proxy; no fallback.  */
+  int ignore_http_dp;     /* Ignore HTTP CRL distribution points.  */
+  int ignore_ldap_dp;     /* Ignore LDAP CRL distribution points.  */
+  int ignore_ocsp_service_url; /* Ignore OCSP service URLs as given in
+                                  the certificate.  */
+
+  /* A list of certificate extension OIDs which are ignored so that
+     one can claim that a critical extension has been handled.  One
+     OID per string.  */
+  strlist_t ignored_cert_extensions;
+
+  int allow_ocsp;     /* Allow using OCSP. */
+
+  int max_replies;
+  unsigned int ldaptimeout;
+
+  ldap_server_t ldapservers;
+  int add_new_ldapservers;
+
+  const char *ocsp_responder;     /* Standard OCSP responder's URL. */
+  fingerprint_list_t ocsp_signer; /* The list of fingerprints with allowed
+                                     standard OCSP signer certificates.  */
+
+  unsigned int ocsp_max_clock_skew; /* Allowed seconds of clocks skew. */
+  unsigned int ocsp_max_period;     /* Seconds a response is at maximum
+                                       considered valid after thisUpdate. */
+  unsigned int ocsp_current_period; /* Seconds a response is considered
+                                       current after nextUpdate. */
+} opt;
+
+
+#define DBG_X509_VALUE    1    /* debug x.509 parsing */
+#define DBG_LOOKUP_VALUE  2    /* debug lookup 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_LOOKUP  (opt.debug & DBG_LOOKUP_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)
+
+/* A simple list of certificate references. */
+struct cert_ref_s
+{
+  struct cert_ref_s *next;
+  unsigned char fpr[20];
+};
+typedef struct cert_ref_s *cert_ref_t;
+
+/* Forward references; access only through server.c.  */
+struct server_local_s;
+
+/* Connection control structure.  */
+struct server_control_s
+{
+  int refcount;      /* Count additional references to this object.  */
+  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 force_crl_refresh; /* Always load a fresh CRL. */
+
+  int check_revocations_nest_level; /* Internal to check_revovations.  */
+  cert_ref_t ocsp_certs; /* Certificates from the current OCSP
+                            response. */
+
+  int audit_events;  /* Send audit events to client.  */
+  uri_item_t keyservers; /* List of keyservers.  */
+};
+
+
+/*-- dirmngr.c --*/
+void dirmngr_exit( int );  /* Wrapper for exit() */
+void dirmngr_init_default_ctrl (ctrl_t ctrl);
+void dirmngr_sighup_action (void);
+
+
+/*-- Various housekeeping functions.  --*/
+void ks_hkp_housekeeping (time_t curtime);
+
+
+/*-- server.c --*/
+ldap_server_t get_ldapservers_from_ctrl (ctrl_t ctrl);
+ksba_cert_t get_cert_local (ctrl_t ctrl, const char *issuer);
+ksba_cert_t get_issuing_cert_local (ctrl_t ctrl, const char *issuer);
+ksba_cert_t get_cert_local_ski (ctrl_t ctrl,
+                                const char *name, ksba_sexp_t keyid);
+gpg_error_t get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr);
+void start_command_handler (gnupg_fd_t fd);
+gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
+gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text);
+gpg_error_t dirmngr_tick (ctrl_t ctrl);
+
+
+
+#endif /*DIRMNGR_H*/
diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c
new file mode 100644 (file)
index 0000000..daa2d1b
--- /dev/null
@@ -0,0 +1,718 @@
+/* dirmngr-ldap.c  -  The LDAP helper for dirmngr.
+ * Copyright (C) 2004 g10 Code GmbH
+ * Copyright (C) 2010 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <unistd.h>
+#ifndef USE_LDAPWRAPPER
+# include <npth.h>
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+# include <winsock2.h>
+# include <winldap.h>
+# include <winber.h>
+# include <fcntl.h>
+# include "ldap-url.h"
+#else
+  /* For OpenLDAP, to enable the API that we're using. */
+# define LDAP_DEPRECATED 1
+# include <ldap.h>
+#endif
+
+
+#define JNLIB_NEED_LOG_LOGV
+#include <gpg-error.h>
+#include "../common/logging.h"
+#include "../common/argparse.h"
+#include "../common/stringhelp.h"
+#include "../common/mischelp.h"
+#include "../common/strlist.h"
+
+#include "i18n.h"
+#include "util.h"
+#include "../common/init.h"
+
+/* With the ldap wrapper, there is no need for the npth_unprotect and leave
+   functions; thus we redefine them to nops.  If we are not using the
+   ldap wrapper process we need to include the prototype for our
+   module's main function.  */
+#ifdef USE_LDAPWRAPPER
+static void npth_unprotect (void) { }
+static void npth_protect (void) { }
+#else
+# include "./ldap-wrapper.h"
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+# include "w32-ldap-help.h"
+# define my_ldap_init(a,b)                      \
+  _dirmngr_ldap_init ((a), (b))
+# define my_ldap_simple_bind_s(a,b,c)           \
+  _dirmngr_ldap_simple_bind_s ((a),(b),(c))
+# define my_ldap_search_st(a,b,c,d,e,f,g,h)     \
+  _dirmngr_ldap_search_st ((a), (b), (c), (d), (e), (f), (g), (h))
+# define my_ldap_first_attribute(a,b,c)         \
+  _dirmngr_ldap_first_attribute ((a),(b),(c))
+# define my_ldap_next_attribute(a,b,c)          \
+  _dirmngr_ldap_next_attribute ((a),(b),(c))
+# define my_ldap_get_values_len(a,b,c)          \
+  _dirmngr_ldap_get_values_len ((a),(b),(c))
+# define my_ldap_free_attr(a)                   \
+  xfree ((a))
+#else
+# define my_ldap_init(a,b)              ldap_init ((a), (b))
+# define my_ldap_simple_bind_s(a,b,c)   ldap_simple_bind_s ((a), (b), (c))
+# define my_ldap_search_st(a,b,c,d,e,f,g,h)     \
+  ldap_search_st ((a), (b), (c), (d), (e), (f), (g), (h))
+# define my_ldap_first_attribute(a,b,c) ldap_first_attribute ((a),(b),(c))
+# define my_ldap_next_attribute(a,b,c)  ldap_next_attribute ((a),(b),(c))
+# define my_ldap_get_values_len(a,b,c)  ldap_get_values_len ((a),(b),(c))
+# define my_ldap_free_attr(a)           ldap_memfree ((a))
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+ typedef LDAP_TIMEVAL  my_ldap_timeval_t;
+#else
+ typedef struct timeval my_ldap_timeval_t;
+#endif
+
+#define DEFAULT_LDAP_TIMEOUT 100 /* Arbitrary long timeout. */
+
+
+/* Constants for the options.  */
+enum
+  {
+    oQuiet       = 'q',
+    oVerbose     = 'v',
+
+    oTimeout      = 500,
+    oMulti,
+    oProxy,
+    oHost,
+    oPort,
+    oUser,
+    oPass,
+    oEnvPass,
+    oDN,
+    oFilter,
+    oAttr,
+
+    oOnlySearchTimeout,
+    oLogWithPID
+  };
+
+
+/* The list of options as used by the argparse.c code.  */
+static ARGPARSE_OPTS opts[] = {
+  { oVerbose,  "verbose",   0, N_("verbose") },
+  { oQuiet,    "quiet",     0, N_("be somewhat more quiet") },
+  { oTimeout,  "timeout",   1, N_("|N|set LDAP timeout to N seconds")},
+  { oMulti,    "multi",     0, N_("return all values in"
+                                  " a record oriented format")},
+  { oProxy,    "proxy",     2,
+    N_("|NAME|ignore host part and connect through NAME")},
+  { oHost,     "host",      2, N_("|NAME|connect to host NAME")},
+  { oPort,     "port",      1, N_("|N|connect to port N")},
+  { oUser,     "user",      2, N_("|NAME|use user NAME for authentication")},
+  { oPass,     "pass",      2, N_("|PASS|use password PASS"
+                                  " for authentication")},
+  { oEnvPass,  "env-pass",  0, N_("take password from $DIRMNGR_LDAP_PASS")},
+  { oDN,       "dn",        2, N_("|STRING|query DN STRING")},
+  { oFilter,   "filter",    2, N_("|STRING|use STRING as filter expression")},
+  { oAttr,     "attr",      2, N_("|STRING|return the attribute STRING")},
+  { oOnlySearchTimeout, "only-search-timeout", 0, "@"},
+  { oLogWithPID,"log-with-pid", 0, "@"},
+  { 0, NULL, 0, NULL }
+};
+
+
+/* A structure with module options.  This is not a static variable
+   because if we are not build as a standalone binary, each thread
+   using this module needs to handle its own values.  */
+struct my_opt_s
+{
+  int quiet;
+  int verbose;
+  my_ldap_timeval_t timeout;/* Timeout for the LDAP search functions.  */
+  unsigned int alarm_timeout; /* And for the alarm based timeout.  */
+  int multi;
+
+  estream_t outstream;    /* Send output to thsi stream.  */
+
+  /* Note that we can't use const for the strings because ldap_* are
+     not defined that way.  */
+  char *proxy; /* Host and Port override.  */
+  char *user;  /* Authentication user.  */
+  char *pass;  /* Authentication password.  */
+  char *host;  /* Override host.  */
+  int port;    /* Override port.  */
+  char *dn;    /* Override DN.  */
+  char *filter;/* Override filter.  */
+  char *attr;  /* Override attribute.  */
+};
+typedef struct my_opt_s *my_opt_t;
+
+
+/* Prototypes.  */
+#ifndef HAVE_W32_SYSTEM
+static void catch_alarm (int dummy);
+#endif
+static int process_url (my_opt_t myopt, const char *url);
+
+
+
+/* Function called by argparse.c to display information.  */
+#ifdef USE_LDAPWRAPPER
+static const char *
+my_strusage (int level)
+{
+  const char *p;
+
+  switch(level)
+    {
+    case 11: p = "dirmngr_ldap (@GNUPG@)";
+      break;
+    case 13: p = VERSION; break;
+    case 17: p = PRINTABLE_OS_NAME; break;
+    case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
+    case 49: p = PACKAGE_BUGREPORT; break;
+    case 1:
+    case 40: p =
+               _("Usage: dirmngr_ldap [options] [URL] (-h for help)\n");
+      break;
+    case 41: p =
+          _("Syntax: dirmngr_ldap [options] [URL]\n"
+            "Internal LDAP helper for Dirmngr\n"
+            "Interface and options may change without notice\n");
+      break;
+
+    default: p = NULL;
+    }
+  return p;
+}
+#endif /*!USE_LDAPWRAPPER*/
+
+
+int
+#ifdef USE_LDAPWRAPPER
+main (int argc, char **argv)
+#else
+ldap_wrapper_main (char **argv, estream_t outstream)
+#endif
+{
+#ifndef USE_LDAPWRAPPER
+  int argc;
+#endif
+  ARGPARSE_ARGS pargs;
+  int any_err = 0;
+  char *p;
+  int only_search_timeout = 0;
+  struct my_opt_s my_opt_buffer;
+  my_opt_t myopt = &my_opt_buffer;
+  char *malloced_buffer1 = NULL;
+
+  memset (&my_opt_buffer, 0, sizeof my_opt_buffer);
+
+#ifdef USE_LDAPWRAPPER
+  set_strusage (my_strusage);
+  log_set_prefix ("dirmngr_ldap", JNLIB_LOG_WITH_PREFIX);
+
+  /* Setup I18N and common subsystems. */
+  i18n_init();
+
+  init_common_subsystems (&argc, &argv);
+
+  es_set_binary (es_stdout);
+  myopt->outstream = es_stdout;
+#else /*!USE_LDAPWRAPPER*/
+  myopt->outstream = outstream;
+  for (argc=0; argv[argc]; argc++)
+    ;
+#endif /*!USE_LDAPWRAPPER*/
+
+  /* LDAP defaults */
+  myopt->timeout.tv_sec = DEFAULT_LDAP_TIMEOUT;
+  myopt->timeout.tv_usec = 0;
+  myopt->alarm_timeout = 0;
+
+  /* Parse the command line.  */
+  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: myopt->verbose++; break;
+        case oQuiet: myopt->quiet++; break;
+       case oTimeout:
+         myopt->timeout.tv_sec = pargs.r.ret_int;
+         myopt->timeout.tv_usec = 0;
+          myopt->alarm_timeout = pargs.r.ret_int;
+         break;
+        case oOnlySearchTimeout: only_search_timeout = 1; break;
+        case oMulti: myopt->multi = 1; break;
+        case oUser: myopt->user = pargs.r.ret_str; break;
+        case oPass: myopt->pass = pargs.r.ret_str; break;
+        case oEnvPass:
+          myopt->pass = getenv ("DIRMNGR_LDAP_PASS");
+          break;
+        case oProxy: myopt->proxy = pargs.r.ret_str; break;
+        case oHost: myopt->host = pargs.r.ret_str; break;
+        case oPort: myopt->port = pargs.r.ret_int; break;
+        case oDN:   myopt->dn = pargs.r.ret_str; break;
+        case oFilter: myopt->filter = pargs.r.ret_str; break;
+        case oAttr: myopt->attr = pargs.r.ret_str; break;
+        case oLogWithPID:
+          {
+            unsigned int oldflags;
+            log_get_prefix (&oldflags);
+            log_set_prefix (NULL, oldflags | JNLIB_LOG_WITH_PID);
+          }
+          break;
+
+        default :
+#ifdef USE_LDAPWRAPPER
+          pargs.err = ARGPARSE_PRINT_ERROR;
+#else
+          pargs.err = ARGPARSE_PRINT_WARNING;  /* No exit() please.  */
+#endif
+          break;
+       }
+    }
+
+  if (only_search_timeout)
+    myopt->alarm_timeout = 0;
+
+  if (myopt->proxy)
+    {
+      malloced_buffer1 = xtrystrdup (myopt->proxy);
+      if (!malloced_buffer1)
+        {
+          log_error ("error copying string: %s\n", strerror (errno));
+          return 1;
+        }
+      myopt->host = malloced_buffer1;
+      p = strchr (myopt->host, ':');
+      if (p)
+        {
+          *p++ = 0;
+          myopt->port = atoi (p);
+        }
+      if (!myopt->port)
+        myopt->port = 389;  /* make sure ports gets overridden.  */
+    }
+
+  if (myopt->port < 0 || myopt->port > 65535)
+    log_error (_("invalid port number %d\n"), myopt->port);
+
+#ifdef USE_LDAPWRAPPER
+  if (log_get_errorcount (0))
+    exit (2);
+  if (argc < 1)
+    usage (1);
+#else
+  /* All passed arguments should be fine in this case.  */
+  assert (argc);
+#endif
+
+#ifdef USE_LDAPWRAPPER
+  if (myopt->alarm_timeout)
+    {
+#ifndef HAVE_W32_SYSTEM
+# if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
+      struct sigaction act;
+
+      act.sa_handler = catch_alarm;
+      sigemptyset (&act.sa_mask);
+      act.sa_flags = 0;
+      if (sigaction (SIGALRM,&act,NULL))
+# else
+      if (signal (SIGALRM, catch_alarm) == SIG_ERR)
+# endif
+          log_fatal ("unable to register timeout handler\n");
+#endif
+    }
+#endif /*USE_LDAPWRAPPER*/
+
+  for (; argc; argc--, argv++)
+    if (process_url (myopt, *argv))
+      any_err = 1;
+
+  xfree (malloced_buffer1);
+  return any_err;
+}
+
+#ifndef HAVE_W32_SYSTEM
+static void
+catch_alarm (int dummy)
+{
+  (void)dummy;
+  _exit (10);
+}
+#endif
+
+static void
+set_timeout (my_opt_t myopt)
+{
+#ifdef HAVE_W32_SYSTEM
+  /* FIXME for W32.  */
+  (void)myopt;
+#else
+  if (myopt->alarm_timeout)
+    alarm (myopt->alarm_timeout);
+#endif
+}
+
+
+/* Helper for fetch_ldap().  */
+static int
+print_ldap_entries (my_opt_t myopt, LDAP *ld, LDAPMessage *msg, char *want_attr)
+{
+  LDAPMessage *item;
+  int any = 0;
+
+  for (npth_unprotect (), item = ldap_first_entry (ld, msg), npth_protect ();
+       item;
+       npth_unprotect (), item = ldap_next_entry (ld, item), npth_protect ())
+    {
+      BerElement *berctx;
+      char *attr;
+
+      if (myopt->verbose > 1)
+        log_info (_("scanning result for attribute '%s'\n"),
+                  want_attr? want_attr : "[all]");
+
+      if (myopt->multi)
+        { /*  Write item marker. */
+          if (es_fwrite ("I\0\0\0\0", 5, 1, myopt->outstream) != 1)
+            {
+              log_error (_("error writing to stdout: %s\n"),
+                         strerror (errno));
+              return -1;
+            }
+        }
+
+
+      for (npth_unprotect (), attr = my_ldap_first_attribute (ld, item, &berctx),
+             npth_protect ();
+           attr;
+           npth_unprotect (), attr = my_ldap_next_attribute (ld, item, berctx),
+             npth_protect ())
+        {
+          struct berval **values;
+          int idx;
+
+          if (myopt->verbose > 1)
+            log_info (_("          available attribute '%s'\n"), attr);
+
+          set_timeout (myopt);
+
+          /* I case we want only one attribute we do a case
+             insensitive compare without the optional extension
+             (i.e. ";binary").  Case insensitive is not really correct
+             but the best we can do.  */
+          if (want_attr)
+            {
+              char *cp1, *cp2;
+              int cmpres;
+
+              cp1 = strchr (want_attr, ';');
+              if (cp1)
+                *cp1 = 0;
+              cp2 = strchr (attr, ';');
+              if (cp2)
+                *cp2 = 0;
+              cmpres = ascii_strcasecmp (want_attr, attr);
+              if (cp1)
+                *cp1 = ';';
+              if (cp2)
+                *cp2 = ';';
+              if (cmpres)
+                {
+                  my_ldap_free_attr (attr);
+                  continue; /* Not found:  Try next attribute.  */
+                }
+            }
+
+          npth_unprotect ();
+          values = my_ldap_get_values_len (ld, item, attr);
+          npth_protect ();
+
+          if (!values)
+            {
+              if (myopt->verbose)
+                log_info (_("attribute '%s' not found\n"), attr);
+              my_ldap_free_attr (attr);
+              continue;
+            }
+
+          if (myopt->verbose)
+            {
+              log_info (_("found attribute '%s'\n"), attr);
+              if (myopt->verbose > 1)
+                for (idx=0; values[idx]; idx++)
+                  log_info ("         length[%d]=%d\n",
+                            idx, (int)values[0]->bv_len);
+
+            }
+
+          if (myopt->multi)
+            { /*  Write attribute marker. */
+              unsigned char tmp[5];
+              size_t n = strlen (attr);
+
+              tmp[0] = 'A';
+              tmp[1] = (n >> 24);
+              tmp[2] = (n >> 16);
+              tmp[3] = (n >> 8);
+              tmp[4] = (n);
+              if (es_fwrite (tmp, 5, 1, myopt->outstream) != 1
+                  || es_fwrite (attr, n, 1, myopt->outstream) != 1)
+                {
+                  log_error (_("error writing to stdout: %s\n"),
+                             strerror (errno));
+                  ldap_value_free_len (values);
+                  my_ldap_free_attr (attr);
+                  ber_free (berctx, 0);
+                  return -1;
+                }
+            }
+
+          for (idx=0; values[idx]; idx++)
+            {
+              if (myopt->multi)
+                { /* Write value marker.  */
+                  unsigned char tmp[5];
+                  size_t n = values[0]->bv_len;
+
+                  tmp[0] = 'V';
+                  tmp[1] = (n >> 24);
+                  tmp[2] = (n >> 16);
+                  tmp[3] = (n >> 8);
+                  tmp[4] = (n);
+
+                  if (es_fwrite (tmp, 5, 1, myopt->outstream) != 1)
+                    {
+                      log_error (_("error writing to stdout: %s\n"),
+                                 strerror (errno));
+                      ldap_value_free_len (values);
+                      my_ldap_free_attr (attr);
+                      ber_free (berctx, 0);
+                      return -1;
+                    }
+                }
+
+             if (es_fwrite (values[0]->bv_val, values[0]->bv_len,
+                             1, myopt->outstream) != 1)
+                {
+                  log_error (_("error writing to stdout: %s\n"),
+                             strerror (errno));
+                  ldap_value_free_len (values);
+                  my_ldap_free_attr (attr);
+                  ber_free (berctx, 0);
+                  return -1;
+                }
+
+              any = 1;
+              if (!myopt->multi)
+                break; /* Print only the first value.  */
+            }
+          ldap_value_free_len (values);
+          my_ldap_free_attr (attr);
+          if (want_attr || !myopt->multi)
+            break; /* We only want to return the first attribute.  */
+        }
+      ber_free (berctx, 0);
+    }
+
+  if (myopt->verbose > 1 && any)
+    log_info ("result has been printed\n");
+
+  return any?0:-1;
+}
+
+
+
+/* Helper for the URL based LDAP query. */
+static int
+fetch_ldap (my_opt_t myopt, const char *url, const LDAPURLDesc *ludp)
+{
+  LDAP *ld;
+  LDAPMessage *msg;
+  int rc = 0;
+  char *host, *dn, *filter, *attrs[2], *attr;
+  int port;
+  int ret;
+
+  host     = myopt->host?   myopt->host   : ludp->lud_host;
+  port     = myopt->port?   myopt->port   : ludp->lud_port;
+  dn       = myopt->dn?     myopt->dn     : ludp->lud_dn;
+  filter   = myopt->filter? myopt->filter : ludp->lud_filter;
+  attrs[0] = myopt->attr?   myopt->attr   : ludp->lud_attrs? ludp->lud_attrs[0]:NULL;
+  attrs[1] = NULL;
+  attr = attrs[0];
+
+  if (!port)
+    port = (ludp->lud_scheme && !strcmp (ludp->lud_scheme, "ldaps"))? 636:389;
+
+  if (myopt->verbose)
+    {
+      log_info (_("processing url '%s'\n"), url);
+      if (myopt->user)
+        log_info (_("          user '%s'\n"), myopt->user);
+      if (myopt->pass)
+        log_info (_("          pass '%s'\n"), *myopt->pass?"*****":"");
+      if (host)
+        log_info (_("          host '%s'\n"), host);
+      log_info (_("          port %d\n"), port);
+      if (dn)
+        log_info (_("            DN '%s'\n"), dn);
+      if (filter)
+        log_info (_("        filter '%s'\n"), filter);
+      if (myopt->multi && !myopt->attr && ludp->lud_attrs)
+        {
+          int i;
+          for (i=0; ludp->lud_attrs[i]; i++)
+            log_info (_("          attr '%s'\n"), ludp->lud_attrs[i]);
+        }
+      else if (attr)
+        log_info (_("          attr '%s'\n"), attr);
+    }
+
+
+  if (!host || !*host)
+    {
+      log_error (_("no host name in '%s'\n"), url);
+      return -1;
+    }
+  if (!myopt->multi && !attr)
+    {
+      log_error (_("no attribute given for query '%s'\n"), url);
+      return -1;
+    }
+
+  if (!myopt->multi && !myopt->attr
+      && ludp->lud_attrs && ludp->lud_attrs[0] && ludp->lud_attrs[1])
+    log_info (_("WARNING: using first attribute only\n"));
+
+
+  set_timeout (myopt);
+  npth_unprotect ();
+  ld = my_ldap_init (host, port);
+  npth_protect ();
+  if (!ld)
+    {
+      log_error (_("LDAP init to '%s:%d' failed: %s\n"),
+                 host, port, strerror (errno));
+      return -1;
+    }
+  npth_unprotect ();
+  /* Fixme:  Can we use MYOPT->user or is it shared with other theeads?.  */
+  ret = my_ldap_simple_bind_s (ld, myopt->user, myopt->pass);
+  npth_protect ();
+  if (ret)
+    {
+      log_error (_("binding to '%s:%d' failed: %s\n"),
+                 host, port, strerror (errno));
+      ldap_unbind (ld);
+      return -1;
+    }
+
+  set_timeout (myopt);
+  npth_unprotect ();
+  rc = my_ldap_search_st (ld, dn, ludp->lud_scope, filter,
+                          myopt->multi && !myopt->attr && ludp->lud_attrs?
+                          ludp->lud_attrs:attrs,
+                          0,
+                          &myopt->timeout, &msg);
+  npth_protect ();
+  if (rc == LDAP_SIZELIMIT_EXCEEDED && myopt->multi)
+    {
+      if (es_fwrite ("E\0\0\0\x09truncated", 14, 1, myopt->outstream) != 1)
+        {
+          log_error (_("error writing to stdout: %s\n"), strerror (errno));
+          return -1;
+        }
+    }
+  else if (rc)
+    {
+#ifdef HAVE_W32CE_SYSTEM
+      log_error ("searching '%s' failed: %d\n", url, rc);
+#else
+      log_error (_("searching '%s' failed: %s\n"),
+                 url, ldap_err2string (rc));
+#endif
+      if (rc != LDAP_NO_SUCH_OBJECT)
+        {
+          /* FIXME: Need deinit (ld)?  */
+          /* Hmmm: Do we need to released MSG in case of an error? */
+          return -1;
+        }
+    }
+
+  rc = print_ldap_entries (myopt, ld, msg, myopt->multi? NULL:attr);
+
+  ldap_msgfree (msg);
+  ldap_unbind (ld);
+  return rc;
+}
+
+
+
+
+/* Main processing.  Take the URL and run the LDAP query. The result
+   is printed to stdout, errors are logged to the log stream. */
+static int
+process_url (my_opt_t myopt, const char *url)
+{
+  int rc;
+  LDAPURLDesc *ludp = NULL;
+
+
+  if (!ldap_is_ldap_url (url))
+    {
+      log_error (_("'%s' is not an LDAP URL\n"), url);
+      return -1;
+    }
+
+  if (ldap_url_parse (url, &ludp))
+    {
+      log_error (_("'%s' is an invalid LDAP URL\n"), url);
+      return -1;
+    }
+
+  rc = fetch_ldap (myopt, url, ludp);
+
+  ldap_free_urldesc (ludp);
+  return rc;
+}
diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c
new file mode 100644 (file)
index 0000000..e4cd8f1
--- /dev/null
@@ -0,0 +1,332 @@
+/* ks-action.c - OpenPGP keyserver actions
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2011, 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "ks-engine.h"
+#include "ks-action.h"
+
+
+/* Copy all data from IN to OUT.  */
+static gpg_error_t
+copy_stream (estream_t in, estream_t out)
+{
+  char buffer[512];
+  size_t nread;
+
+  while (!es_read (in, buffer, sizeof buffer, &nread))
+    {
+      if (!nread)
+        return 0; /* EOF */
+      if (es_write (out, buffer, nread, NULL))
+        break;
+
+    }
+  return gpg_error_from_syserror ();
+}
+
+
+/* Called by the engine's help functions to print the actual help.  */
+gpg_error_t
+ks_print_help (ctrl_t ctrl, const char *text)
+{
+  return dirmngr_status_help (ctrl, text);
+}
+
+
+/* Called by the engine's help functions to print the actual help.  */
+gpg_error_t
+ks_printf_help (ctrl_t ctrl, const char *format, ...)
+{
+  va_list arg_ptr;
+  gpg_error_t err;
+  char *buf;
+
+  va_start (arg_ptr, format);
+  buf = es_vbsprintf (format, arg_ptr);
+  err = buf? 0 : gpg_error_from_syserror ();
+  va_end (arg_ptr);
+  if (!err)
+    err = dirmngr_status_help (ctrl, buf);
+  es_free (buf);
+  return err;
+}
+
+
+/* Run the help command for the engine responsible for URI.  */
+gpg_error_t
+ks_action_help (ctrl_t ctrl, const char *url)
+{
+  gpg_error_t err;
+  parsed_uri_t parsed_uri;  /* The broken down URI.  */
+
+  if (!url || !*url)
+    {
+      ks_print_help (ctrl, "Known schemata:\n");
+      parsed_uri = NULL;
+    }
+  else
+    {
+      err = http_parse_uri (&parsed_uri, url, 1);
+      if (err)
+        return err;
+    }
+
+  /* Call all engines to give them a chance to print a help sting.  */
+  err = ks_hkp_help (ctrl, parsed_uri);
+  if (!err)
+    err = ks_http_help (ctrl, parsed_uri);
+  if (!err)
+    err = ks_finger_help (ctrl, parsed_uri);
+  if (!err)
+    err = ks_kdns_help (ctrl, parsed_uri);
+
+  if (!parsed_uri)
+    ks_print_help (ctrl,
+                   "(Use an URL for engine specific help.)");
+  else
+    http_release_parsed_uri (parsed_uri);
+  return err;
+}
+
+
+/* Resolve all host names.  This is useful for looking at the status
+   of configured keyservers.  */
+gpg_error_t
+ks_action_resolve (ctrl_t ctrl)
+{
+  gpg_error_t err = 0;
+  int any_server = 0;
+  uri_item_t uri;
+
+  for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+    {
+      if (uri->parsed_uri->is_http)
+        {
+          any_server = 1;
+          err = ks_hkp_resolve (ctrl, uri->parsed_uri);
+          if (err)
+            break;
+        }
+    }
+
+  if (!any_server)
+    err = gpg_error (GPG_ERR_NO_KEYSERVER);
+  return err;
+}
+
+
+/* Search all configured keyservers for keys matching PATTERNS and
+   write the result to the provided output stream.  */
+gpg_error_t
+ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
+{
+  gpg_error_t err = 0;
+  int any_server = 0;
+  uri_item_t uri;
+  estream_t infp;
+
+  if (!patterns)
+    return gpg_error (GPG_ERR_NO_USER_ID);
+
+  /* FIXME: We only take care of the first pattern.  To fully support
+     multiple patterns we might either want to run several queries in
+     parallel and merge them.  We also need to decide what to do with
+     errors - it might not be the best idea to ignore an error from
+     one server and silently continue with another server.  For now we
+     stop at the first error. */
+  for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+    {
+      if (uri->parsed_uri->is_http)
+        {
+          any_server = 1;
+          err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d, &infp);
+          if (!err)
+            {
+              err = copy_stream (infp, outfp);
+              es_fclose (infp);
+              break;
+            }
+        }
+    }
+
+  if (!any_server)
+    err = gpg_error (GPG_ERR_NO_KEYSERVER);
+  return err;
+}
+
+
+/* Get the requested keys (matching PATTERNS) using all configured
+   keyservers and write the result to the provided output stream.  */
+gpg_error_t
+ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
+{
+  gpg_error_t err = 0;
+  gpg_error_t first_err = 0;
+  int any_server = 0;
+  int any_data = 0;
+  strlist_t sl;
+  uri_item_t uri;
+  estream_t infp;
+
+  if (!patterns)
+    return gpg_error (GPG_ERR_NO_USER_ID);
+
+  /* FIXME: We only take care of the first keyserver.  To fully
+     support multiple keyservers we need to track the result for each
+     pattern and use the next keyserver if one key was not found.  The
+     keyservers might not all be fully synced thus it is not clear
+     whether the first keyserver has the freshest copy of the key.
+     Need to think about a better strategy.  */
+  for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+    {
+      if (uri->parsed_uri->is_http)
+        {
+          any_server = 1;
+          for (sl = patterns; !err && sl; sl = sl->next)
+            {
+              err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
+              if (err)
+                {
+                  /* It is possible that a server does not carry a
+                     key, thus we only save the error and continue
+                     with the next pattern.  FIXME: It is an open
+                     question how to return such an error condition to
+                     the caller.  */
+                  first_err = err;
+                  err = 0;
+                }
+              else
+                {
+                  err = copy_stream (infp, outfp);
+                  /* Reading from the keyserver should never fail, thus
+                     return this error.  */
+                  if (!err)
+                    any_data = 1;
+                  es_fclose (infp);
+                  infp = NULL;
+                }
+            }
+        }
+      if (any_data)
+        break; /* Stop loop after a keyserver returned something.  */
+    }
+
+  if (!any_server)
+    err = gpg_error (GPG_ERR_NO_KEYSERVER);
+  else if (!err && first_err && !any_data)
+    err = first_err;
+  return err;
+}
+
+
+/* Retrieve keys from URL and write the result to the provided output
+   stream OUTFP.  */
+gpg_error_t
+ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp)
+{
+  gpg_error_t err = 0;
+  estream_t infp;
+  parsed_uri_t parsed_uri;  /* The broken down URI.  */
+
+  if (!url)
+    return gpg_error (GPG_ERR_INV_URI);
+
+  err = http_parse_uri (&parsed_uri, url, 1);
+  if (err)
+    return err;
+
+  if (parsed_uri->is_http)
+    {
+      err = ks_http_fetch (ctrl, url, &infp);
+      if (!err)
+        {
+          err = copy_stream (infp, outfp);
+          es_fclose (infp);
+        }
+    }
+  else if (!parsed_uri->opaque)
+    {
+      err = gpg_error (GPG_ERR_INV_URI);
+    }
+  else if (!strcmp (parsed_uri->scheme, "finger"))
+    {
+      err = ks_finger_fetch (ctrl, parsed_uri, &infp);
+      if (!err)
+        {
+          err = copy_stream (infp, outfp);
+          es_fclose (infp);
+        }
+    }
+  else if (!strcmp (parsed_uri->scheme, "kdns"))
+    {
+      err = ks_kdns_fetch (ctrl, parsed_uri, &infp);
+      if (!err)
+        {
+          err = copy_stream (infp, outfp);
+          es_fclose (infp);
+        }
+    }
+  else
+    err = gpg_error (GPG_ERR_INV_URI);
+
+  http_release_parsed_uri (parsed_uri);
+  return err;
+}
+
+
+
+/* Send an OpenPGP key to all keyservers.  The key in {DATA,DATALEN}
+   is expected in OpenPGP binary transport format.  */
+gpg_error_t
+ks_action_put (ctrl_t ctrl, const void *data, size_t datalen)
+{
+  gpg_error_t err = 0;
+  gpg_error_t first_err = 0;
+  int any_server = 0;
+  uri_item_t uri;
+
+  for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+    {
+      if (uri->parsed_uri->is_http)
+        {
+          any_server = 1;
+          err = ks_hkp_put (ctrl, uri->parsed_uri, data, datalen);
+          if (err)
+            {
+              first_err = err;
+              err = 0;
+            }
+        }
+    }
+
+  if (!any_server)
+    err = gpg_error (GPG_ERR_NO_KEYSERVER);
+  else if (!err && first_err)
+    err = first_err;
+  return err;
+}
diff --git a/dirmngr/ks-action.h b/dirmngr/ks-action.h
new file mode 100644 (file)
index 0000000..5c8a5cd
--- /dev/null
@@ -0,0 +1,31 @@
+/* ks-action.h - OpenPGP keyserver actions definitions
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIRMNGR_KS_ACTION_H
+#define DIRMNGR_KS_ACTION_H 1
+
+gpg_error_t ks_action_help (ctrl_t ctrl, const char *url);
+gpg_error_t ks_action_resolve (ctrl_t ctrl);
+gpg_error_t ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp);
+gpg_error_t ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp);
+gpg_error_t ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp);
+gpg_error_t ks_action_put (ctrl_t ctrl, const void *data, size_t datalen);
+
+
+#endif /*DIRMNGR_KS_ACTION_H*/
diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
new file mode 100644 (file)
index 0000000..57dd340
--- /dev/null
@@ -0,0 +1,123 @@
+/* ks-engine-finger.c - Finger OpenPGP key access
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "userids.h"
+#include "ks-engine.h"
+
+/* Print a help output for the schemata supported by this module. */
+gpg_error_t
+ks_finger_help (ctrl_t ctrl, parsed_uri_t uri)
+{
+  char const data[] =
+    "Handler for FINGER:\n"
+    "  finger:<user>@<host>\n"
+    "Supported methods: fetch\n"
+    "Example:\n"
+    "  finger:joe@example.org\n";
+  gpg_error_t err;
+
+  if (!uri)
+    err = ks_print_help (ctrl, "  finger");
+  else if (!strcmp (uri->scheme, "finger"))
+    err = ks_print_help (ctrl, data);
+  else
+    err = 0;
+
+  return err;
+}
+
+
+/* Get the key from URI which is expected to specify a finger scheme.
+   On success R_FP has an open stream to read the data.  */
+gpg_error_t
+ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
+{
+  gpg_error_t err;
+  estream_t fp;
+  char *server;
+  char *name;
+  http_t http;
+
+  (void)ctrl;
+  *r_fp = NULL;
+
+  if (strcmp (uri->scheme, "finger") || !uri->opaque || !uri->path)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  name = xtrystrdup (uri->path);
+  if (!name)
+    return gpg_error_from_syserror ();
+
+  server = strchr (name, '@');
+  if (!server)
+    {
+      err = gpg_error (GPG_ERR_INV_URI);
+      xfree (name);
+      return err;
+    }
+  *server++ = 0;
+
+  err = http_raw_connect (&http, server, 79, 0, NULL);
+  if (err)
+    {
+      xfree (name);
+      return err;
+    }
+
+  fp = http_get_write_ptr (http);
+  if (!fp)
+    {
+      err = gpg_error (GPG_ERR_INTERNAL);
+      http_close (http, 0);
+      xfree (name);
+      return err;
+    }
+
+  if (es_fputs (name, fp) || es_fputs ("\r\n", fp) || es_fflush (fp))
+    {
+      err = gpg_error_from_syserror ();
+      http_close (http, 0);
+      xfree (name);
+      return err;
+    }
+  xfree (name);
+  es_fclose (fp);
+
+  fp = http_get_read_ptr (http);
+  if (!fp)
+    {
+      err = gpg_error (GPG_ERR_INTERNAL);
+      http_close (http, 0);
+      return err;
+    }
+
+  http_close (http, 1 /* Keep read ptr.  */);
+
+  *r_fp = fp;
+  return 0;
+}
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
new file mode 100644 (file)
index 0000000..12b1778
--- /dev/null
@@ -0,0 +1,1477 @@
+/* ks-engine-hkp.c - HKP keyserver engine
+ * Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2011, 2012, 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#ifdef HAVE_W32_SYSTEM
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
+# include <windows.h>
+#else /*!HAVE_W32_SYSTEM*/
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netdb.h>
+#endif /*!HAVE_W32_SYSTEM*/
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "userids.h"
+#include "ks-engine.h"
+
+/* Substitutes for missing Mingw macro.  The EAI_SYSTEM mechanism
+   seems not to be available (probably because there is only one set
+   of error codes anyway).  For now we use WSAEINVAL. */
+#ifndef EAI_OVERFLOW
+# define EAI_OVERFLOW EAI_FAIL
+#endif
+#ifdef HAVE_W32_SYSTEM
+# ifndef EAI_SYSTEM
+#  define EAI_SYSTEM WSAEINVAL
+# endif
+#endif
+
+
+/* Number of seconds after a host is marked as resurrected.  */
+#define RESURRECT_INTERVAL  (3600*3)  /* 3 hours */
+
+/* To match the behaviour of our old gpgkeys helper code we escape
+   more characters than actually needed. */
+#define EXTRA_ESCAPE_CHARS "@!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
+
+/* How many redirections do we allow.  */
+#define MAX_REDIRECTS 2
+
+/* Number of retries done for a dead host etc.  */
+#define SEND_REQUEST_RETRIES 3
+
+/* Objects used to maintain information about hosts.  */
+struct hostinfo_s;
+typedef struct hostinfo_s *hostinfo_t;
+struct hostinfo_s
+{
+  time_t lastfail;   /* Time we tried to connect and failed.  */
+  time_t lastused;   /* Time of last use.  */
+  int *pool;         /* A -1 terminated array with indices into
+                        HOSTTABLE or NULL if NAME is not a pool
+                        name.  */
+  int poolidx;       /* Index into POOL with the used host.  -1 if not set.  */
+  unsigned int v4:1; /* Host supports AF_INET.  */
+  unsigned int v6:1; /* Host supports AF_INET6.  */
+  unsigned int dead:1; /* Host is currently unresponsive.  */
+  time_t died_at;    /* The time the host was marked dead.  If this is
+                        0 the host has been manually marked dead.  */
+  char *cname;       /* Canonical name of the host.  Only set if this
+                        is a pool.  */
+  char *v4addr;      /* A string with the v4 IP address of the host.
+                        NULL if NAME has a numeric IP address or no v4
+                        address is available.  */
+  char *v6addr;      /* A string with the v6 IP address of the host.
+                        NULL if NAME has a numeric IP address or no v4
+                        address is available.  */
+  char name[1];      /* The hostname.  */
+};
+
+
+/* An array of hostinfo_t for all hosts requested by the caller or
+   resolved from a pool name and its allocated size.*/
+static hostinfo_t *hosttable;
+static int hosttable_size;
+
+/* The number of host slots we initally allocate for HOSTTABLE.  */
+#define INITIAL_HOSTTABLE_SIZE 10
+
+
+/* Create a new hostinfo object, fill in NAME and put it into
+   HOSTTABLE.  Return the index into hosttable on success or -1 on
+   error. */
+static int
+create_new_hostinfo (const char *name)
+{
+  hostinfo_t hi, *newtable;
+  int newsize;
+  int idx, rc;
+
+  hi = xtrymalloc (sizeof *hi + strlen (name));
+  if (!hi)
+    return -1;
+  strcpy (hi->name, name);
+  hi->pool = NULL;
+  hi->poolidx = -1;
+  hi->lastused = (time_t)(-1);
+  hi->lastfail = (time_t)(-1);
+  hi->v4 = 0;
+  hi->v6 = 0;
+  hi->dead = 0;
+  hi->died_at = 0;
+  hi->cname = NULL;
+  hi->v4addr = NULL;
+  hi->v6addr = NULL;
+
+  /* Add it to the hosttable. */
+  for (idx=0; idx < hosttable_size; idx++)
+    if (!hosttable[idx])
+      {
+        hosttable[idx] = hi;
+        return idx;
+      }
+  /* Need to extend the hosttable.  */
+  newsize = hosttable_size + INITIAL_HOSTTABLE_SIZE;
+  newtable = xtryrealloc (hosttable, newsize * sizeof *hosttable);
+  if (!newtable)
+    {
+      xfree (hi);
+      return -1;
+    }
+  hosttable = newtable;
+  idx = hosttable_size;
+  hosttable_size = newsize;
+  rc = idx;
+  hosttable[idx++] = hi;
+  while (idx < hosttable_size)
+    hosttable[idx++] = NULL;
+
+  return rc;
+}
+
+
+/* Find the host NAME in our table.  Return the index into the
+   hosttable or -1 if not found.  */
+static int
+find_hostinfo (const char *name)
+{
+  int idx;
+
+  for (idx=0; idx < hosttable_size; idx++)
+    if (hosttable[idx] && !ascii_strcasecmp (hosttable[idx]->name, name))
+      return idx;
+  return -1;
+}
+
+
+static int
+sort_hostpool (const void *xa, const void *xb)
+{
+  int a = *(int *)xa;
+  int b = *(int *)xb;
+
+  assert (a >= 0 && a < hosttable_size);
+  assert (b >= 0 && b < hosttable_size);
+  assert (hosttable[a]);
+  assert (hosttable[b]);
+
+  return ascii_strcasecmp (hosttable[a]->name, hosttable[b]->name);
+}
+
+
+/* Return true if the host with the hosttable index TBLIDX is in POOL.  */
+static int
+host_in_pool_p (int *pool, int tblidx)
+{
+  int i, pidx;
+
+  for (i=0; (pidx = pool[i]) != -1; i++)
+    if (pidx == tblidx && hosttable[pidx])
+      return 1;
+  return 0;
+}
+
+
+/* Select a random host.  Consult TABLE which indices into the global
+   hosttable.  Returns index into TABLE or -1 if no host could be
+   selected.  */
+static int
+select_random_host (int *table)
+{
+  int *tbl;
+  size_t tblsize;
+  int pidx, idx;
+
+  /* We create a new table so that we randomly select only from
+     currently alive hosts.  */
+  for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
+    if (hosttable[pidx] && !hosttable[pidx]->dead)
+      tblsize++;
+  if (!tblsize)
+    return -1; /* No hosts.  */
+
+  tbl = xtrymalloc (tblsize * sizeof *tbl);
+  if (!tbl)
+    return -1;
+  for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
+    if (hosttable[pidx] && !hosttable[pidx]->dead)
+      tbl[tblsize++] = pidx;
+
+  if (tblsize == 1)  /* Save a get_uint_nonce.  */
+    pidx = tbl[0];
+  else
+    pidx = tbl[get_uint_nonce () % tblsize];
+
+  xfree (tbl);
+  return pidx;
+}
+
+
+/* Simplified version of getnameinfo which also returns a numeric
+   hostname inside of brackets.  The caller should provide a buffer
+   for HOST which is 2 bytes larger than the largest hostname.  If
+   NUMERIC is true the returned value is numeric IP address.  Returns
+   0 on success or an EAI error code.  True is stored at R_ISNUMERIC
+   if HOST has a numeric IP address. */
+static int
+my_getnameinfo (struct addrinfo *ai, char *host, size_t hostlen,
+                int numeric, int *r_isnumeric)
+{
+  int ec;
+  char *p;
+
+  *r_isnumeric = 0;
+
+  if (hostlen < 5)
+    return EAI_OVERFLOW;
+
+  if (numeric)
+    ec = EAI_NONAME;
+  else
+    ec = getnameinfo (ai->ai_addr, ai->ai_addrlen,
+                      host, hostlen, NULL, 0, NI_NAMEREQD);
+
+  if (!ec && *host == '[')
+    ec = EAI_FAIL;  /* A name may never start with a bracket.  */
+  else if (ec == EAI_NONAME)
+    {
+      p = host;
+      if (ai->ai_family == AF_INET6)
+        {
+          *p++ = '[';
+          hostlen -= 2;
+        }
+      ec = getnameinfo (ai->ai_addr, ai->ai_addrlen,
+                        p, hostlen, NULL, 0, NI_NUMERICHOST);
+      if (!ec && ai->ai_family == AF_INET6)
+        strcat (host, "]");
+
+      *r_isnumeric = 1;
+    }
+
+  return ec;
+}
+
+
+/* Check whether NAME is an IP address.  */
+static int
+is_ip_address (const char *name)
+{
+  int ndots, n;
+
+  if (*name == '[')
+    return 1;
+  /* Check whether it is legacy IP address.  */
+  if (*name == '.')
+    return 0; /* No.  */
+  ndots = n = 0;
+  for (; *name; name++)
+    {
+      if (*name == '.')
+        {
+          if (name[1] == '.')
+            return 0; /* No. */
+          if (atoi (name+1) > 255)
+            return 0; /* Value too large.  */
+          ndots++;
+          n = 0;
+        }
+      else if (!strchr ("012345678", *name))
+        return 0; /* Not a digit.  */
+      else if (++n > 3)
+        return 0; /* More than 3 digits.  */
+    }
+  return !!(ndots == 3);
+}
+
+
+/* Map the host name NAME to the actual to be used host name.  This
+   allows us to manage round robin DNS names.  We use our own strategy
+   to choose one of the hosts.  For example we skip those hosts which
+   failed for some time and we stick to one host for a time
+   independent of DNS retry times.  If FORCE_RESELECT is true a new
+   host is always selected.  If R_HTTPFLAGS is not NULL if will
+   receive flags which are to be passed to http_open.  If R_HOST is
+   not NULL a malloced name of the pool is stored or NULL if it is not
+   a pool. */
+static char *
+map_host (ctrl_t ctrl, const char *name, int force_reselect,
+          unsigned int *r_httpflags, char **r_host)
+{
+  hostinfo_t hi;
+  int idx;
+
+  if (r_httpflags)
+    *r_httpflags = 0;
+  if (r_host)
+    *r_host = NULL;
+
+  /* No hostname means localhost.  */
+  if (!name || !*name)
+    return xtrystrdup ("localhost");
+
+  /* See whether the host is in our table.  */
+  idx = find_hostinfo (name);
+  if (idx == -1)
+    {
+      /* We never saw this host.  Allocate a new entry.  */
+      struct addrinfo hints, *aibuf, *ai;
+      int *reftbl;
+      size_t reftblsize;
+      int refidx;
+      int is_pool = 0;
+
+      reftblsize = 100;
+      reftbl = xtrymalloc (reftblsize * sizeof *reftbl);
+      if (!reftbl)
+        return NULL;
+      refidx = 0;
+
+      idx = create_new_hostinfo (name);
+      if (idx == -1)
+        {
+          xfree (reftbl);
+          return NULL;
+        }
+      hi = hosttable[idx];
+
+      /* Find all A records for this entry and put them into the pool
+         list - if any.  */
+      memset (&hints, 0, sizeof (hints));
+      hints.ai_family = AF_UNSPEC;
+      hints.ai_socktype = SOCK_STREAM;
+      hints.ai_flags = AI_CANONNAME;
+      /* We can't use the the AI_IDN flag because that does the
+         conversion using the current locale.  However, GnuPG always
+         used UTF-8.  To support IDN we would need to make use of the
+         libidn API.  */
+      if (!getaddrinfo (name, NULL, &hints, &aibuf))
+        {
+          int n_v6, n_v4;
+
+          /* First figure out whether this is a pool.  For a pool we
+             use a different strategy than for a plains erver: We use
+             the canonical name of the pool as the virtual host along
+             with the IP addresses.  If it is not a pool, we use the
+             specified name. */
+          n_v6 = n_v4 = 0;
+          for (ai = aibuf; ai; ai = ai->ai_next)
+            {
+              if (ai->ai_family != AF_INET6)
+                n_v6++;
+              else if (ai->ai_family != AF_INET)
+                n_v4++;
+            }
+          if (n_v6 > 1 || n_v4 > 1)
+            is_pool = 1;
+          if (is_pool && aibuf->ai_canonname)
+            hi->cname = xtrystrdup (aibuf->ai_canonname);
+
+          for (ai = aibuf; ai; ai = ai->ai_next)
+            {
+              char tmphost[NI_MAXHOST + 2];
+              int tmpidx;
+              int is_numeric;
+              int ec;
+              int i;
+
+              if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+                continue;
+
+              dirmngr_tick (ctrl);
+
+              if (!is_pool && !is_ip_address (name))
+                {
+                  /* This is a hostname but not a pool.  Use the name
+                     as given without going through getnameinfo.  */
+                  if (strlen (name)+1 > sizeof tmphost)
+                    {
+                      ec = EAI_SYSTEM;
+                      gpg_err_set_errno (EINVAL);
+                    }
+                  else
+                    {
+                      ec = 0;
+                      strcpy (tmphost, name);
+                    }
+                  is_numeric = 0;
+                }
+              else
+                ec = my_getnameinfo (ai, tmphost, sizeof tmphost,
+                                     0, &is_numeric);
+
+              if (ec)
+                {
+                  log_info ("getnameinfo failed while checking '%s': %s\n",
+                            name, gai_strerror (ec));
+                }
+              else if (refidx+1 >= reftblsize)
+                {
+                  log_error ("getnameinfo returned for '%s': '%s'"
+                            " [index table full - ignored]\n", name, tmphost);
+                }
+              else
+                {
+                  tmpidx = find_hostinfo (tmphost);
+                  log_info ("getnameinfo returned for '%s': '%s'%s\n",
+                            name, tmphost,
+                            tmpidx == -1? "" : " [already known]");
+
+                  if (tmpidx == -1) /* Create a new entry.  */
+                    tmpidx = create_new_hostinfo (tmphost);
+
+                  if (tmpidx == -1)
+                    {
+                      log_error ("map_host for '%s' problem: %s - '%s'"
+                                 " [ignored]\n",
+                                 name, strerror (errno), tmphost);
+                    }
+                  else  /* Set or update the entry. */
+                    {
+                      char *ipaddr = NULL;
+
+                      if (!is_numeric)
+                        {
+                          ec = my_getnameinfo (ai, tmphost, sizeof tmphost,
+                                               1, &is_numeric);
+                          if (!ec && !(ipaddr = xtrystrdup (tmphost)))
+                            ec = EAI_SYSTEM;
+                          if (ec)
+                            log_info ("getnameinfo failed: %s\n",
+                                      gai_strerror (ec));
+                        }
+
+                      if (ai->ai_family == AF_INET6)
+                        {
+                          hosttable[tmpidx]->v6 = 1;
+                          xfree (hosttable[tmpidx]->v6addr);
+                          hosttable[tmpidx]->v6addr = ipaddr;
+                        }
+                      else if (ai->ai_family == AF_INET)
+                        {
+                          hosttable[tmpidx]->v4 = 1;
+                          xfree (hosttable[tmpidx]->v4addr);
+                          hosttable[tmpidx]->v4addr = ipaddr;
+                        }
+                      else
+                        BUG ();
+
+                      for (i=0; i < refidx; i++)
+                        if (reftbl[i] == tmpidx)
+                          break;
+                      if (!(i < refidx) && tmpidx != idx)
+                        reftbl[refidx++] = tmpidx;
+                    }
+                }
+            }
+          freeaddrinfo (aibuf);
+        }
+      reftbl[refidx] = -1;
+      if (refidx && is_pool)
+        {
+          assert (!hi->pool);
+          hi->pool = xtryrealloc (reftbl, (refidx+1) * sizeof *reftbl);
+          if (!hi->pool)
+            {
+              log_error ("shrinking index table in map_host failed: %s\n",
+                         strerror (errno));
+              xfree (reftbl);
+            }
+          qsort (reftbl, refidx, sizeof *reftbl, sort_hostpool);
+        }
+      else
+        xfree (reftbl);
+    }
+
+  hi = hosttable[idx];
+  if (hi->pool)
+    {
+      /* If the currently selected host is now marked dead, force a
+         re-selection .  */
+      if (force_reselect)
+        hi->poolidx = -1;
+      else if (hi->poolidx >= 0 && hi->poolidx < hosttable_size
+               && hosttable[hi->poolidx] && hosttable[hi->poolidx]->dead)
+        hi->poolidx = -1;
+
+      /* Select a host if needed.  */
+      if (hi->poolidx == -1)
+        {
+          hi->poolidx = select_random_host (hi->pool);
+          if (hi->poolidx == -1)
+            {
+              log_error ("no alive host found in pool '%s'\n", name);
+              return NULL;
+            }
+        }
+
+      assert (hi->poolidx >= 0 && hi->poolidx < hosttable_size);
+      hi = hosttable[hi->poolidx];
+      assert (hi);
+    }
+
+  if (hi->dead)
+    {
+      log_error ("host '%s' marked as dead\n", hi->name);
+      return NULL;
+    }
+
+  if (r_httpflags)
+    {
+      /* If the hosttable does not indicate that a certain host
+         supports IPv<N>, we explicit set the corresponding http
+         flags.  The reason for this is that a host might be listed in
+         a pool as not v6 only but actually support v6 when later
+         the name is resolved by our http layer.  */
+      if (!hi->v4)
+        *r_httpflags |= HTTP_FLAG_IGNORE_IPv4;
+      if (!hi->v6)
+        *r_httpflags |= HTTP_FLAG_IGNORE_IPv6;
+    }
+
+  if (r_host && hi->pool && hi->cname)
+    *r_host = xtrystrdup (hi->cname);
+
+  return xtrystrdup (hi->name);
+}
+
+
+/* Mark the host NAME as dead.  NAME may be given as an URL.  Returns
+   true if a host was really marked as dead or was already marked dead
+   (e.g. by a concurrent session).  */
+static int
+mark_host_dead (const char *name)
+{
+  const char *host;
+  char *host_buffer = NULL;
+  parsed_uri_t parsed_uri = NULL;
+  int done = 0;
+
+  if (name && *name && !http_parse_uri (&parsed_uri, name, 1))
+    {
+      if (parsed_uri->v6lit)
+        {
+          host_buffer = strconcat ("[", parsed_uri->host, "]", NULL);
+          if (!host_buffer)
+            log_error ("out of core in mark_host_dead");
+          host = host_buffer;
+        }
+      else
+        host = parsed_uri->host;
+    }
+  else
+    host = name;
+
+  if (host && *host && strcmp (host, "localhost"))
+    {
+      hostinfo_t hi;
+      int idx;
+
+      idx = find_hostinfo (host);
+      if (idx != -1)
+        {
+          hi = hosttable[idx];
+          log_info ("marking host '%s' as dead%s\n",
+                    hi->name, hi->dead? " (again)":"");
+          hi->dead = 1;
+          hi->died_at = gnupg_get_time ();
+          if (!hi->died_at)
+            hi->died_at = 1;
+          done = 1;
+        }
+    }
+
+  http_release_parsed_uri (parsed_uri);
+  xfree (host_buffer);
+  return done;
+}
+
+
+/* Mark a host in the hosttable as dead or - if ALIVE is true - as
+   alive.  */
+gpg_error_t
+ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
+{
+  gpg_error_t err = 0;
+  hostinfo_t hi, hi2;
+  int idx, idx2, idx3, n;
+
+  if (!name || !*name || !strcmp (name, "localhost"))
+    return 0;
+
+  idx = find_hostinfo (name);
+  if (idx == -1)
+    return gpg_error (GPG_ERR_NOT_FOUND);
+
+  hi = hosttable[idx];
+  if (alive && hi->dead)
+    {
+      hi->dead = 0;
+      err = ks_printf_help (ctrl, "marking '%s' as alive", name);
+    }
+  else if (!alive && !hi->dead)
+    {
+      hi->dead = 1;
+      hi->died_at = 0; /* Manually set dead.  */
+      err = ks_printf_help (ctrl, "marking '%s' as dead", name);
+    }
+
+  /* If the host is a pool mark all member hosts. */
+  if (!err && hi->pool)
+    {
+      for (idx2=0; !err && (n=hi->pool[idx2]) != -1; idx2++)
+        {
+          assert (n >= 0 && n < hosttable_size);
+
+          if (!alive)
+            {
+              /* Do not mark a host from a pool dead if it is also a
+                 member in another pool.  */
+              for (idx3=0; idx3 < hosttable_size; idx3++)
+                {
+                  if (hosttable[idx3] && hosttable[idx3]
+                      && hosttable[idx3]->pool
+                      && idx3 != idx
+                      && host_in_pool_p (hosttable[idx3]->pool, n))
+                    break;
+                }
+              if (idx3 < hosttable_size)
+                continue;  /* Host is also a member of another pool.  */
+            }
+
+          hi2 = hosttable[n];
+          if (!hi2)
+            ;
+          else if (alive && hi2->dead)
+            {
+              hi2->dead = 0;
+              err = ks_printf_help (ctrl, "marking '%s' as alive",
+                                    hi2->name);
+            }
+          else if (!alive && !hi2->dead)
+            {
+              hi2->dead = 1;
+              hi2->died_at = 0; /* Manually set dead. */
+              err = ks_printf_help (ctrl, "marking '%s' as dead",
+                                    hi2->name);
+            }
+        }
+    }
+
+  return err;
+}
+
+
+/* Debug function to print the entire hosttable.  */
+gpg_error_t
+ks_hkp_print_hosttable (ctrl_t ctrl)
+{
+  gpg_error_t err;
+  int idx, idx2;
+  hostinfo_t hi;
+  membuf_t mb;
+  time_t curtime;
+  char *p, *died;
+  const char *diedstr;
+
+  err = ks_print_help (ctrl, "hosttable (idx, ipv6, ipv4, dead, name, time):");
+  if (err)
+    return err;
+
+  curtime = gnupg_get_time ();
+  for (idx=0; idx < hosttable_size; idx++)
+    if ((hi=hosttable[idx]))
+      {
+        if (hi->dead && hi->died_at)
+          {
+            died = elapsed_time_string (hi->died_at, curtime);
+            diedstr = died? died : "error";
+          }
+        else
+          diedstr = died = NULL;
+        err = ks_printf_help (ctrl, "%3d %s %s %s %s%s%s%s%s%s%s%s\n",
+                              idx, hi->v6? "6":" ", hi->v4? "4":" ",
+                              hi->dead? "d":" ",
+                              hi->name,
+                              hi->v6addr? " v6=":"",
+                              hi->v6addr? hi->v6addr:"",
+                              hi->v4addr? " v4=":"",
+                              hi->v4addr? hi->v4addr:"",
+                              diedstr? "  (":"",
+                              diedstr? diedstr:"",
+                              diedstr? ")":""   );
+        xfree (died);
+        if (err)
+          return err;
+
+        if (hi->cname)
+          err = ks_printf_help (ctrl, "  .       %s", hi->cname);
+        if (err)
+          return err;
+
+        if (hi->pool)
+          {
+            init_membuf (&mb, 256);
+            put_membuf_printf (&mb, "  .   -->");
+            for (idx2=0; hi->pool[idx2] != -1; idx2++)
+              {
+                put_membuf_printf (&mb, " %d", hi->pool[idx2]);
+                if (hi->poolidx == hi->pool[idx2])
+                  put_membuf_printf (&mb, "*");
+              }
+            put_membuf( &mb, "", 1);
+            p = get_membuf (&mb, NULL);
+            if (!p)
+              return gpg_error_from_syserror ();
+            err = ks_print_help (ctrl, p);
+            xfree (p);
+            if (err)
+              return err;
+          }
+      }
+  return 0;
+}
+
+
+
+/* Print a help output for the schemata supported by this module. */
+gpg_error_t
+ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
+{
+  const char const data[] =
+    "Handler for HKP URLs:\n"
+    "  hkp://\n"
+    "  hkps://\n"
+    "Supported methods: search, get, put\n";
+  gpg_error_t err;
+
+  if (!uri)
+    err = ks_print_help (ctrl, "  hkp\n  hkps");
+  else if (uri->is_http && (!strcmp (uri->scheme, "hkp")
+                            || !strcmp (uri->scheme, "hkps")))
+    err = ks_print_help (ctrl, data);
+  else
+    err = 0;
+
+  return err;
+}
+
+
+/* Build the remote part of the URL from SCHEME, HOST and an optional
+   PORT.  Returns an allocated string or NULL on failure and sets
+   ERRNO.  If R_HTTPHOST is not NULL it receive a mallcoed string with
+   the poolname.  */
+static char *
+make_host_part (ctrl_t ctrl,
+                const char *scheme, const char *host, unsigned short port,
+                int force_reselect,
+                unsigned int *r_httpflags, char **r_httphost)
+{
+  char portstr[10];
+  char *hostname;
+  char *hostport;
+
+  /* Map scheme and port.  */
+  if (!strcmp (scheme, "hkps") || !strcmp (scheme,"https"))
+    {
+      scheme = "https";
+      strcpy (portstr, "443");
+    }
+  else /* HKP or HTTP.  */
+    {
+      scheme = "http";
+      strcpy (portstr, "11371");
+    }
+  if (port)
+    snprintf (portstr, sizeof portstr, "%hu", port);
+  else
+    {
+      /*fixme_do_srv_lookup ()*/
+    }
+
+  hostname = map_host (ctrl, host, force_reselect, r_httpflags, r_httphost);
+  if (!hostname)
+    return NULL;
+
+  hostport = strconcat (scheme, "://", hostname, ":", portstr, NULL);
+  xfree (hostname);
+  return hostport;
+}
+
+
+/* Resolve all known keyserver names and update the hosttable.  This
+   is mainly useful for debugging because the resolving is anyway done
+   on demand.  */
+gpg_error_t
+ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
+{
+  gpg_error_t err;
+  char *hostport = NULL;
+
+  hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, 1,
+                             NULL, NULL);
+  if (!hostport)
+    {
+      err = gpg_error_from_syserror ();
+      err = ks_printf_help (ctrl, "%s://%s:%hu: resolve failed: %s",
+                            uri->scheme, uri->host, uri->port,
+                            gpg_strerror (err));
+    }
+  else
+    {
+      err = ks_printf_help (ctrl, "%s", hostport);
+      xfree (hostport);
+    }
+  return err;
+}
+
+
+/* Housekeeping function called from the housekeeping thread.  It is
+   used to mark dead hosts alive so that they may be tried again after
+   some time.  */
+void
+ks_hkp_housekeeping (time_t curtime)
+{
+  int idx;
+  hostinfo_t hi;
+
+  for (idx=0; idx < hosttable_size; idx++)
+    {
+      hi = hosttable[idx];
+      if (!hi)
+        continue;
+      if (!hi->dead)
+        continue;
+      if (!hi->died_at)
+        continue; /* Do not resurrect manually shot hosts.  */
+      if (hi->died_at + RESURRECT_INTERVAL <= curtime
+          || hi->died_at > curtime)
+        {
+          hi->dead = 0;
+          log_info ("resurrected host '%s'", hi->name);
+        }
+    }
+}
+
+
+/* Send an HTTP request.  On success returns an estream object at
+   R_FP.  HOSTPORTSTR is only used for diagnostics.  If HTTPHOST is
+   not NULL it will be used as HTTP "Host" header.  If POST_CB is not
+   NULL a post request is used and that callback is called to allow
+   writing the post data.  */
+static gpg_error_t
+send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+              const char *httphost, unsigned int httpflags,
+              gpg_error_t (*post_cb)(void *, http_t), void *post_cb_value,
+              estream_t *r_fp)
+{
+  gpg_error_t err;
+  http_session_t session = NULL;
+  http_t http = NULL;
+  int redirects_left = MAX_REDIRECTS;
+  estream_t fp = NULL;
+  char *request_buffer = NULL;
+
+  *r_fp = NULL;
+
+  err = http_session_new (&session, NULL);
+  if (err)
+    goto leave;
+  http_session_set_log_cb (session, cert_log_cb);
+
+ once_more:
+  err = http_open (&http,
+                   post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
+                   request,
+                   httphost,
+                   /* fixme: AUTH */ NULL,
+                   httpflags,
+                   /* fixme: proxy*/ NULL,
+                   session,
+                   NULL,
+                   /*FIXME curl->srvtag*/NULL);
+  if (!err)
+    {
+      fp = http_get_write_ptr (http);
+      /* Avoid caches to get the most recent copy of the key.  We set
+         both the Pragma and Cache-Control versions of the header, so
+         we're good with both HTTP 1.0 and 1.1.  */
+      es_fputs ("Pragma: no-cache\r\n"
+                "Cache-Control: no-cache\r\n", fp);
+      if (post_cb)
+        err = post_cb (post_cb_value, http);
+      if (!err)
+        {
+          http_start_data (http);
+          if (es_ferror (fp))
+            err = gpg_error_from_syserror ();
+        }
+    }
+  if (err)
+    {
+      /* Fixme: After a redirection we show the old host name.  */
+      log_error (_("error connecting to '%s': %s\n"),
+                 hostportstr, gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Wait for the response.  */
+  dirmngr_tick (ctrl);
+  err = http_wait_response (http);
+  if (err)
+    {
+      log_error (_("error reading HTTP response for '%s': %s\n"),
+                 hostportstr, gpg_strerror (err));
+      goto leave;
+    }
+
+  if (http_get_tls_info (http, NULL))
+    {
+      /* Update the httpflags so that a redirect won't fallback to an
+         unencrypted connection.  */
+      httpflags |= HTTP_FLAG_FORCE_TLS;
+    }
+
+  switch (http_get_status_code (http))
+    {
+    case 200:
+      err = 0;
+      break; /* Success.  */
+
+    case 301:
+    case 302:
+    case 307:
+      {
+        const char *s = http_get_header (http, "Location");
+
+        log_info (_("URL '%s' redirected to '%s' (%u)\n"),
+                  request, s?s:"[none]", http_get_status_code (http));
+        if (s && *s && redirects_left-- )
+          {
+            xfree (request_buffer);
+            request_buffer = xtrystrdup (s);
+            if (request_buffer)
+              {
+                request = request_buffer;
+                http_close (http, 0);
+                http = NULL;
+                goto once_more;
+              }
+            err = gpg_error_from_syserror ();
+          }
+        else
+          err = gpg_error (GPG_ERR_NO_DATA);
+        log_error (_("too many redirections\n"));
+      }
+      goto leave;
+
+    default:
+      log_error (_("error accessing '%s': http status %u\n"),
+                 request, http_get_status_code (http));
+      err = gpg_error (GPG_ERR_NO_DATA);
+      goto leave;
+    }
+
+  /* FIXME: We should register a permanent redirection and whether a
+     host has ever used TLS so that future calls will always use
+     TLS. */
+
+  fp = http_get_read_ptr (http);
+  if (!fp)
+    {
+      err = gpg_error (GPG_ERR_BUG);
+      goto leave;
+    }
+
+  /* Return the read stream and close the HTTP context.  */
+  *r_fp = fp;
+  http_close (http, 1);
+  http = NULL;
+
+ leave:
+  http_close (http, 0);
+  http_session_release (session);
+  xfree (request_buffer);
+  return err;
+}
+
+
+/* Helper to evaluate the error code ERR form a send_request() call
+   with REQUEST.  The function returns true if the caller shall try
+   again.  TRIES_LEFT points to a variable to track the number of
+   retries; this function decrements it and won't return true if it is
+   down to zero. */
+static int
+handle_send_request_error (gpg_error_t err, const char *request,
+                           unsigned int *tries_left)
+{
+  int retry = 0;
+
+  switch (gpg_err_code (err))
+    {
+    case GPG_ERR_ECONNREFUSED:
+    case GPG_ERR_ENETUNREACH:
+      if (mark_host_dead (request) && *tries_left)
+        retry = 1;
+      break;
+
+    case GPG_ERR_ETIMEDOUT:
+      if (*tries_left)
+        {
+          log_info ("selecting a different host due to a timeout\n");
+          retry = 1;
+        }
+
+    default:
+      break;
+    }
+
+  if (*tries_left)
+    --*tries_left;
+
+  return retry;
+}
+
+static gpg_error_t
+armor_data (char **r_string, const void *data, size_t datalen)
+{
+  gpg_error_t err;
+  struct b64state b64state;
+  estream_t fp;
+  long length;
+  char *buffer;
+  size_t nread;
+
+  *r_string = NULL;
+
+  fp = es_fopenmem (0, "rw,samethread");
+  if (!fp)
+    return gpg_error_from_syserror ();
+
+  if ((err=b64enc_start_es (&b64state, fp, "PGP PUBLIC KEY BLOCK"))
+      || (err=b64enc_write (&b64state, data, datalen))
+      || (err = b64enc_finish (&b64state)))
+    {
+      es_fclose (fp);
+      return err;
+    }
+
+  /* FIXME: To avoid the extra buffer allocation estream should
+     provide a function to snatch the internal allocated memory from
+     such a memory stream.  */
+  length = es_ftell (fp);
+  if (length < 0)
+    {
+      err = gpg_error_from_syserror ();
+      es_fclose (fp);
+      return err;
+    }
+
+  buffer = xtrymalloc (length+1);
+  if (!buffer)
+    {
+      err = gpg_error_from_syserror ();
+      es_fclose (fp);
+      return err;
+    }
+
+  es_rewind (fp);
+  if (es_read (fp, buffer, length, &nread))
+    {
+      err = gpg_error_from_syserror ();
+      es_fclose (fp);
+      return err;
+    }
+  buffer[nread] = 0;
+  es_fclose (fp);
+
+  *r_string = buffer;
+  return 0;
+}
+
+
+\f
+/* Search the keyserver identified by URI for keys matching PATTERN.
+   On success R_FP has an open stream to read the data.  */
+gpg_error_t
+ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
+               estream_t *r_fp)
+{
+  gpg_error_t err;
+  KEYDB_SEARCH_DESC desc;
+  char fprbuf[2+40+1];
+  char *hostport = NULL;
+  char *request = NULL;
+  estream_t fp = NULL;
+  int reselect;
+  unsigned int httpflags;
+  char *httphost = NULL;
+  unsigned int tries = SEND_REQUEST_RETRIES;
+
+  *r_fp = NULL;
+
+  /* Remove search type indicator and adjust PATTERN accordingly.
+     Note that HKP keyservers like the 0x to be present when searching
+     by keyid.  We need to re-format the fingerprint and keyids so to
+     remove the gpg specific force-use-of-this-key flag ("!").  */
+  err = classify_user_id (pattern, &desc, 1);
+  if (err)
+    return err;
+  switch (desc.mode)
+    {
+    case KEYDB_SEARCH_MODE_EXACT:
+    case KEYDB_SEARCH_MODE_SUBSTR:
+    case KEYDB_SEARCH_MODE_MAIL:
+    case KEYDB_SEARCH_MODE_MAILSUB:
+      pattern = desc.u.name;
+      break;
+    case KEYDB_SEARCH_MODE_SHORT_KID:
+      snprintf (fprbuf, sizeof fprbuf, "0x%08lX", (ulong)desc.u.kid[1]);
+      pattern = fprbuf;
+      break;
+    case KEYDB_SEARCH_MODE_LONG_KID:
+      snprintf (fprbuf, sizeof fprbuf, "0x%08lX%08lX",
+                (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]);
+      pattern = fprbuf;
+      break;
+    case KEYDB_SEARCH_MODE_FPR16:
+      bin2hex (desc.u.fpr, 16, fprbuf);
+      pattern = fprbuf;
+      break;
+    case KEYDB_SEARCH_MODE_FPR20:
+    case KEYDB_SEARCH_MODE_FPR:
+      bin2hex (desc.u.fpr, 20, fprbuf);
+      pattern = fprbuf;
+      break;
+    default:
+      return gpg_error (GPG_ERR_INV_USER_ID);
+    }
+
+  /* Build the request string.  */
+  reselect = 0;
+ again:
+  {
+    char *searchkey;
+
+    xfree (hostport);
+    xfree (httphost); httphost = NULL;
+    hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
+                               reselect, &httpflags, &httphost);
+    if (!hostport)
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+
+    searchkey = http_escape_string (pattern, EXTRA_ESCAPE_CHARS);
+    if (!searchkey)
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+
+    xfree (request);
+    request = strconcat (hostport,
+                         "/pks/lookup?op=index&options=mr&search=",
+                         searchkey,
+                         NULL);
+    xfree (searchkey);
+    if (!request)
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+  }
+
+  /* Send the request.  */
+  err = send_request (ctrl, request, hostport, httphost, httpflags,
+                      NULL, NULL, &fp);
+  if (handle_send_request_error (err, request, &tries))
+    {
+      reselect = 1;
+      goto again;
+    }
+  if (err)
+    goto leave;
+
+  err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
+  if (err)
+    goto leave;
+
+  /* Peek at the response.  */
+  {
+    int c = es_getc (fp);
+    if (c == -1)
+      {
+        err = es_ferror (fp)?gpg_error_from_syserror ():gpg_error (GPG_ERR_EOF);
+        log_error ("error reading response: %s\n", gpg_strerror (err));
+        goto leave;
+      }
+    if (c == '<')
+      {
+        /* The document begins with a '<': Assume a HTML response,
+           which we don't support.  */
+        err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
+        goto leave;
+      }
+    es_ungetc (c, fp);
+  }
+
+  /* Return the read stream.  */
+  *r_fp = fp;
+  fp = NULL;
+
+ leave:
+  es_fclose (fp);
+  xfree (request);
+  xfree (hostport);
+  xfree (httphost);
+  return err;
+}
+
+
+/* Get the key described key the KEYSPEC string from the keyserver
+   identified by URI.  On success R_FP has an open stream to read the
+   data.  */
+gpg_error_t
+ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
+{
+  gpg_error_t err;
+  KEYDB_SEARCH_DESC desc;
+  char kidbuf[2+40+1];
+  const char *exactname = NULL;
+  char *searchkey = NULL;
+  char *hostport = NULL;
+  char *request = NULL;
+  estream_t fp = NULL;
+  int reselect;
+  char *httphost = NULL;
+  unsigned int httpflags;
+  unsigned int tries = SEND_REQUEST_RETRIES;
+
+  *r_fp = NULL;
+
+  /* Remove search type indicator and adjust PATTERN accordingly.
+     Note that HKP keyservers like the 0x to be present when searching
+     by keyid.  We need to re-format the fingerprint and keyids so to
+     remove the gpg specific force-use-of-this-key flag ("!").  */
+  err = classify_user_id (keyspec, &desc, 1);
+  if (err)
+    return err;
+  switch (desc.mode)
+    {
+    case KEYDB_SEARCH_MODE_SHORT_KID:
+      snprintf (kidbuf, sizeof kidbuf, "0x%08lX", (ulong)desc.u.kid[1]);
+      break;
+    case KEYDB_SEARCH_MODE_LONG_KID:
+      snprintf (kidbuf, sizeof kidbuf, "0x%08lX%08lX",
+               (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]);
+      break;
+    case KEYDB_SEARCH_MODE_FPR20:
+    case KEYDB_SEARCH_MODE_FPR:
+      /* This is a v4 fingerprint. */
+      kidbuf[0] = '0';
+      kidbuf[1] = 'x';
+      bin2hex (desc.u.fpr, 20, kidbuf+2);
+      break;
+
+    case KEYDB_SEARCH_MODE_EXACT:
+      exactname = desc.u.name;
+      break;
+
+    case KEYDB_SEARCH_MODE_FPR16:
+      log_error ("HKP keyservers do not support v3 fingerprints\n");
+    default:
+      return gpg_error (GPG_ERR_INV_USER_ID);
+    }
+
+  searchkey = http_escape_string (exactname? exactname : kidbuf,
+                                  EXTRA_ESCAPE_CHARS);
+  if (!searchkey)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  reselect = 0;
+ again:
+  /* Build the request string.  */
+  xfree (hostport);
+  xfree (httphost); httphost = NULL;
+  hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
+                             reselect, &httpflags, &httphost);
+  if (!hostport)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  xfree (request);
+  request = strconcat (hostport,
+                       "/pks/lookup?op=get&options=mr&search=",
+                       searchkey,
+                       exactname? "&exact=on":"",
+                       NULL);
+  if (!request)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  /* Send the request.  */
+  err = send_request (ctrl, request, hostport, httphost, httpflags,
+                      NULL, NULL, &fp);
+  if (handle_send_request_error (err, request, &tries))
+    {
+      reselect = 1;
+      goto again;
+    }
+  if (err)
+    goto leave;
+
+  err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
+  if (err)
+    goto leave;
+
+  /* Return the read stream and close the HTTP context.  */
+  *r_fp = fp;
+  fp = NULL;
+
+ leave:
+  es_fclose (fp);
+  xfree (request);
+  xfree (hostport);
+  xfree (httphost);
+  xfree (searchkey);
+  return err;
+}
+
+
+
+\f
+/* Callback parameters for put_post_cb.  */
+struct put_post_parm_s
+{
+  char *datastring;
+};
+
+
+/* Helper for ks_hkp_put.  */
+static gpg_error_t
+put_post_cb (void *opaque, http_t http)
+{
+  struct put_post_parm_s *parm = opaque;
+  gpg_error_t err = 0;
+  estream_t fp;
+  size_t len;
+
+  fp = http_get_write_ptr (http);
+  len = strlen (parm->datastring);
+
+  es_fprintf (fp,
+              "Content-Type: application/x-www-form-urlencoded\r\n"
+              "Content-Length: %zu\r\n", len+8 /* 8 is for "keytext" */);
+  http_start_data (http);
+  if (es_fputs ("keytext=", fp) || es_write (fp, parm->datastring, len, NULL))
+    err = gpg_error_from_syserror ();
+  return err;
+}
+
+
+/* Send the key in {DATA,DATALEN} to the keyserver identified by  URI.  */
+gpg_error_t
+ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
+{
+  gpg_error_t err;
+  char *hostport = NULL;
+  char *request = NULL;
+  estream_t fp = NULL;
+  struct put_post_parm_s parm;
+  char *armored = NULL;
+  int reselect;
+  char *httphost = NULL;
+  unsigned int httpflags;
+  unsigned int tries = SEND_REQUEST_RETRIES;
+
+  parm.datastring = NULL;
+
+  err = armor_data (&armored, data, datalen);
+  if (err)
+    goto leave;
+
+  parm.datastring = http_escape_string (armored, EXTRA_ESCAPE_CHARS);
+  if (!parm.datastring)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  xfree (armored);
+  armored = NULL;
+
+  /* Build the request string.  */
+  reselect = 0;
+ again:
+  xfree (hostport);
+  xfree (httphost); httphost = NULL;
+  hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
+                             reselect, &httpflags, &httphost);
+  if (!hostport)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  xfree (request);
+  request = strconcat (hostport, "/pks/add", NULL);
+  if (!request)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  /* Send the request.  */
+  err = send_request (ctrl, request, hostport, httphost, 0,
+                      put_post_cb, &parm, &fp);
+  if (handle_send_request_error (err, request, &tries))
+    {
+      reselect = 1;
+      goto again;
+    }
+  if (err)
+    goto leave;
+
+ leave:
+  es_fclose (fp);
+  xfree (parm.datastring);
+  xfree (armored);
+  xfree (request);
+  xfree (hostport);
+  xfree (httphost);
+  return err;
+}
diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
new file mode 100644 (file)
index 0000000..e4c2b78
--- /dev/null
@@ -0,0 +1,172 @@
+/* ks-engine-http.c - HTTP OpenPGP key access
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "ks-engine.h"
+
+/* How many redirections do we allow.  */
+#define MAX_REDIRECTS 2
+
+/* Print a help output for the schemata supported by this module. */
+gpg_error_t
+ks_http_help (ctrl_t ctrl, parsed_uri_t uri)
+{
+  const char const data[] =
+    "Handler for HTTP URLs:\n"
+    "  http://\n"
+    "  https://\n"
+    "Supported methods: fetch\n";
+  gpg_error_t err;
+
+  if (!uri)
+    err = ks_print_help (ctrl, "  http");
+  else if (uri->is_http && strcmp (uri->scheme, "hkp"))
+    err = ks_print_help (ctrl, data);
+  else
+    err = 0;
+
+  return err;
+}
+
+
+/* Get the key from URL which is expected to specify a http style
+   scheme.  On success R_FP has an open stream to read the data.  */
+gpg_error_t
+ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
+{
+  gpg_error_t err;
+  http_session_t session = NULL;
+  http_t http = NULL;
+  int redirects_left = MAX_REDIRECTS;
+  estream_t fp = NULL;
+  char *request_buffer = NULL;
+
+  err = http_session_new (&session, NULL);
+  if (err)
+    goto leave;
+  http_session_set_log_cb (session, cert_log_cb);
+
+  *r_fp = NULL;
+ once_more:
+  err = http_open (&http,
+                   HTTP_REQ_GET,
+                   url,
+                   /* httphost */ NULL,
+                   /* fixme: AUTH */ NULL,
+                   0,
+                   /* fixme: proxy*/ NULL,
+                   session,
+                   NULL,
+                   /*FIXME curl->srvtag*/NULL);
+  if (!err)
+    {
+      fp = http_get_write_ptr (http);
+      /* Avoid caches to get the most recent copy of the key.  We set
+         both the Pragma and Cache-Control versions of the header, so
+         we're good with both HTTP 1.0 and 1.1.  */
+      es_fputs ("Pragma: no-cache\r\n"
+                "Cache-Control: no-cache\r\n", fp);
+      http_start_data (http);
+      if (es_ferror (fp))
+        err = gpg_error_from_syserror ();
+    }
+  if (err)
+    {
+      /* Fixme: After a redirection we show the old host name.  */
+      log_error (_("error connecting to '%s': %s\n"),
+                 url, gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Wait for the response.  */
+  dirmngr_tick (ctrl);
+  err = http_wait_response (http);
+  if (err)
+    {
+      log_error (_("error reading HTTP response for '%s': %s\n"),
+                 url, gpg_strerror (err));
+      goto leave;
+    }
+
+  switch (http_get_status_code (http))
+    {
+    case 200:
+      err = 0;
+      break; /* Success.  */
+
+    case 301:
+    case 302:
+    case 307:
+      {
+        const char *s = http_get_header (http, "Location");
+
+        log_info (_("URL '%s' redirected to '%s' (%u)\n"),
+                  url, s?s:"[none]", http_get_status_code (http));
+        if (s && *s && redirects_left-- )
+          {
+            xfree (request_buffer);
+            request_buffer = xtrystrdup (s);
+            if (request_buffer)
+              {
+                url = request_buffer;
+                http_close (http, 0);
+                http = NULL;
+                goto once_more;
+              }
+            err = gpg_error_from_syserror ();
+          }
+        else
+          err = gpg_error (GPG_ERR_NO_DATA);
+        log_error (_("too many redirections\n"));
+      }
+      goto leave;
+
+    default:
+      log_error (_("error accessing '%s': http status %u\n"),
+                 url, http_get_status_code (http));
+      err = gpg_error (GPG_ERR_NO_DATA);
+      goto leave;
+    }
+
+  fp = http_get_read_ptr (http);
+  if (!fp)
+    {
+      err = gpg_error (GPG_ERR_BUG);
+      goto leave;
+    }
+
+  /* Return the read stream and close the HTTP context.  */
+  *r_fp = fp;
+  http_close (http, 1);
+  http = NULL;
+
+ leave:
+  http_close (http, 0);
+  http_session_release (session);
+  xfree (request_buffer);
+  return err;
+}
diff --git a/dirmngr/ks-engine-kdns.c b/dirmngr/ks-engine-kdns.c
new file mode 100644 (file)
index 0000000..748274d
--- /dev/null
@@ -0,0 +1,79 @@
+/* ks-engine-kdns.c - KDNS OpenPGP key access
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "userids.h"
+#include "ks-engine.h"
+
+/* Print a help output for the schemata supported by this module. */
+gpg_error_t
+ks_kdns_help (ctrl_t ctrl, parsed_uri_t uri)
+{
+  const char const data[] =
+    "This keyserver engine accepts URLs of the form:\n"
+    "  kdns://[NAMESERVER]/[ROOT][?at=STRING]\n"
+    "with\n"
+    "  NAMESERVER  used for queries (default: system standard)\n"
+    "  ROOT        a DNS name appended to the query (default: none)\n"
+    "  STRING      a string to replace the '@' (default: \".\")\n"
+    "If a long answer is expected add the parameter \"usevc=1\".\n"
+    "Supported methods: fetch\n"
+    "Example:\n"
+    "A query for \"hacker@gnupg.org\" with\n"
+    "  kdns://10.0.0.1/example.net?at=_key_&usevc=1\n"
+    "setup as --auto-key-lookup in gpg does a CERT record query\n"
+    "with type PGP on the nameserver 10.0.0.1 for\n"
+    "  hacker._key_.gnupg.org.example.net";
+  gpg_error_t err;
+
+  if (!uri)
+    err = ks_print_help (ctrl, "  kdns");
+  else if (!strcmp (uri->scheme, "kdns"))
+    err = ks_print_help (ctrl, data);
+  else
+    err = 0;
+
+  return err;
+}
+
+
+/* Get the key from URI which is expected to specify a kdns scheme.
+   On success R_FP has an open stream to read the data.  */
+gpg_error_t
+ks_kdns_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
+{
+  gpg_error_t err;
+
+  (void)ctrl;
+  *r_fp = NULL;
+
+  if (strcmp (uri->scheme, "kdns"))
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  return err;
+}
diff --git a/dirmngr/ks-engine.h b/dirmngr/ks-engine.h
new file mode 100644 (file)
index 0000000..dc950cf
--- /dev/null
@@ -0,0 +1,57 @@
+/* ks-engine.h - Keyserver engines definitions
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIRMNGR_KS_ENGINE_H
+#define DIRMNGR_KS_ENGINE_H 1
+
+#include "../common/http.h"
+
+/*-- ks-action.c --*/
+gpg_error_t ks_print_help (ctrl_t ctrl, const char *text);
+gpg_error_t ks_printf_help (ctrl_t ctrl, const char *format,
+                            ...) JNLIB_GCC_A_PRINTF(2,3);
+
+/*-- ks-engine-hkp.c --*/
+gpg_error_t ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri);
+gpg_error_t ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive);
+gpg_error_t ks_hkp_print_hosttable (ctrl_t ctrl);
+gpg_error_t ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri);
+gpg_error_t ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
+                           estream_t *r_fp);
+gpg_error_t ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri,
+                        const char *keyspec, estream_t *r_fp);
+gpg_error_t ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri,
+                        const void *data, size_t datalen);
+
+/*-- ks-engine-http.c --*/
+gpg_error_t ks_http_help (ctrl_t ctrl, parsed_uri_t uri);
+gpg_error_t ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp);
+
+
+/*-- ks-engine-finger.c --*/
+gpg_error_t ks_finger_help (ctrl_t ctrl, parsed_uri_t uri);
+gpg_error_t ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp);
+
+/*-- ks-engine-kdns.c --*/
+gpg_error_t ks_kdns_help (ctrl_t ctrl, parsed_uri_t uri);
+gpg_error_t ks_kdns_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp);
+
+
+
+#endif /*DIRMNGR_KS_ENGINE_H*/
diff --git a/dirmngr/ldap-url.c b/dirmngr/ldap-url.c
new file mode 100644 (file)
index 0000000..8308514
--- /dev/null
@@ -0,0 +1,935 @@
+/* The following code comes from the OpenLDAP project.  The references
+   to the COPYRIGHT file below refer to the corresponding file in the
+   OpenLDAP distribution, which is reproduced here in full:
+
+Copyright 1998-2004 The OpenLDAP Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted only as authorized by the OpenLDAP
+Public License.
+
+A copy of this license is available in the file LICENSE in the
+top-level directory of the distribution or, alternatively, at
+<http://www.OpenLDAP.org/license.html>.
+
+OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+
+Individual files and/or contributed packages may be copyright by
+other parties and subject to additional restrictions.
+
+This work is derived from the University of Michigan LDAP v3.3
+distribution.  Information concerning this software is available
+at <http://www.umich.edu/~dirsvcs/ldap/>.
+
+This work also contains materials derived from public sources.
+
+Additional information about OpenLDAP can be obtained at
+<http://www.openldap.org/>.
+
+---
+
+Portions Copyright 1998-2004 Kurt D. Zeilenga.
+Portions Copyright 1998-2004 Net Boolean Incorporated.
+Portions Copyright 2001-2004 IBM Corporation.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted only as authorized by the OpenLDAP
+Public License.
+
+---
+
+Portions Copyright 1999-2003 Howard Y.H. Chu.
+Portions Copyright 1999-2003 Symas Corporation.
+Portions Copyright 1998-2003 Hallvard B. Furuseth.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that this notice is preserved.
+The names of the copyright holders may not be used to endorse or
+promote products derived from this software without their specific
+prior written permission.  This software is provided `'as is''
+without express or implied warranty.
+
+---
+
+Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
+All rights reserved.
+
+Redistribution and use in source and binary forms are permitted
+provided that this notice is preserved and that due credit is given
+to the University of Michigan at Ann Arbor.  The name of the
+University may not be used to endorse or promote products derived
+from this software without specific prior written permission.  This
+software is provided `'as is'' without express or implied warranty.  */
+
+
+#include <config.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <winsock2.h>
+#include <winldap.h>
+#include "ldap-url.h"
+#define LDAP_P(protos)         protos
+#define LDAP_URL_URLCOLON      "URL:"
+#define LDAP_URL_URLCOLON_LEN   (sizeof(LDAP_URL_URLCOLON)-1)
+#define LDAP_URL_PREFIX         "ldap://"
+#define LDAP_URL_PREFIX_LEN     (sizeof(LDAP_URL_PREFIX)-1)
+#define LDAPS_URL_PREFIX        "ldaps://"
+#define LDAPS_URL_PREFIX_LEN    (sizeof(LDAPS_URL_PREFIX)-1)
+#define LDAPI_URL_PREFIX        "ldapi://"
+#define LDAPI_URL_PREFIX_LEN    (sizeof(LDAPI_URL_PREFIX)-1)
+#define LDAP_VFREE(v)           { int _i; for (_i = 0; (v)[_i]; _i++) free((v)[_i]); }
+#define LDAP_FREE              free
+#define LDAP_STRDUP            strdup
+#define LDAP_CALLOC            calloc
+#define LDAP_MALLOC            malloc
+#define LDAP_REALLOC           realloc
+#define ldap_utf8_strchr       strchr
+#define ldap_utf8_strtok(n,d)   strtok (n,d)
+#define Debug(a,b,c,d,e)
+void ldap_pvt_hex_unescape( char *s );
+
+
+#ifndef LDAP_SCOPE_DEFAULT
+# define LDAP_SCOPE_DEFAULT -1
+#endif
+
+
+\f
+/* $OpenLDAP: pkg/ldap/libraries/libldap/charray.c,v 1.9.2.2 2003/03/03 17:10:04 kurt Exp $ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* charray.c - routines for dealing with char * arrays */
+
+int
+ldap_charray_add(
+    char       ***a,
+    char       *s
+)
+{
+       int     n;
+
+       if ( *a == NULL ) {
+               *a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
+               n = 0;
+
+               if( *a == NULL ) {
+                       return -1;
+               }
+
+       } else {
+               char **new;
+
+               for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
+                       ;       /* NULL */
+               }
+
+               new = (char **) LDAP_REALLOC( (char *) *a,
+                   (n + 2) * sizeof(char *) );
+
+               if( new == NULL ) {
+                       /* caller is required to call ldap_charray_free(*a) */
+                       return -1;
+               }
+
+               *a = new;
+       }
+
+       (*a)[n] = LDAP_STRDUP(s);
+
+       if( (*a)[n] == NULL ) {
+               return 1;
+       }
+
+       (*a)[++n] = NULL;
+
+       return 0;
+}
+
+int
+ldap_charray_merge(
+    char       ***a,
+    char       **s
+)
+{
+       int     i, n, nn;
+       char **aa;
+
+       for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
+               ;       /* NULL */
+       }
+       for ( nn = 0; s[nn] != NULL; nn++ ) {
+               ;       /* NULL */
+       }
+
+       aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
+
+       if( aa == NULL ) {
+               return -1;
+       }
+
+       *a = aa;
+
+       for ( i = 0; i < nn; i++ ) {
+               (*a)[n + i] = LDAP_STRDUP(s[i]);
+
+               if( (*a)[n + i] == NULL ) {
+                       for( --i ; i >= 0 ; i-- ) {
+                               LDAP_FREE( (*a)[n + i] );
+                               (*a)[n + i] = NULL;
+                       }
+                       return -1;
+               }
+       }
+
+       (*a)[n + nn] = NULL;
+       return 0;
+}
+
+void
+ldap_charray_free( char **a )
+{
+       char    **p;
+
+       if ( a == NULL ) {
+               return;
+       }
+
+       for ( p = a; *p != NULL; p++ ) {
+               if ( *p != NULL ) {
+                       LDAP_FREE( *p );
+               }
+       }
+
+       LDAP_FREE( (char *) a );
+}
+
+int
+ldap_charray_inlist(
+    char       **a,
+    char       *s
+)
+{
+       int     i;
+
+       if( a == NULL ) return 0;
+
+       for ( i=0; a[i] != NULL; i++ ) {
+               if ( strcasecmp( s, a[i] ) == 0 ) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+char **
+ldap_charray_dup( char **a )
+{
+       int     i;
+       char    **new;
+
+       for ( i = 0; a[i] != NULL; i++ )
+               ;       /* NULL */
+
+       new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
+
+       if( new == NULL ) {
+               return NULL;
+       }
+
+       for ( i = 0; a[i] != NULL; i++ ) {
+               new[i] = LDAP_STRDUP( a[i] );
+
+               if( new[i] == NULL ) {
+                       for( --i ; i >= 0 ; i-- ) {
+                               LDAP_FREE( new[i] );
+                       }
+                       LDAP_FREE( new );
+                       return NULL;
+               }
+       }
+       new[i] = NULL;
+
+       return( new );
+}
+
+char **
+ldap_str2charray( const char *str_in, const char *brkstr )
+{
+       char    **res;
+       char    *str, *s;
+       int     i;
+
+       /* protect the input string from strtok */
+       str = LDAP_STRDUP( str_in );
+       if( str == NULL ) {
+               return NULL;
+       }
+
+       i = 1;
+       for ( s = str; *s; s++ ) {
+               if ( ldap_utf8_strchr( brkstr, *s ) != NULL ) {
+                       i++;
+               }
+       }
+
+       res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
+
+       if( res == NULL ) {
+               LDAP_FREE( str );
+               return NULL;
+       }
+
+       i = 0;
+
+       for ( s = ldap_utf8_strtok( str, brkstr);
+               s != NULL;
+               s = ldap_utf8_strtok( NULL, brkstr) )
+       {
+               res[i] = LDAP_STRDUP( s );
+
+               if(res[i] == NULL) {
+                       for( --i ; i >= 0 ; i-- ) {
+                               LDAP_FREE( res[i] );
+                       }
+                       LDAP_FREE( res );
+                       LDAP_FREE( str );
+                       return NULL;
+               }
+
+               i++;
+       }
+
+       res[i] = NULL;
+
+       LDAP_FREE( str );
+       return( res );
+}
+
+char * ldap_charray2str( char **a, const char *sep )
+{
+       char *s, **v, *p;
+       int len;
+       int slen;
+
+       if( sep == NULL ) sep = " ";
+
+       slen = strlen( sep );
+       len = 0;
+
+       for ( v = a; *v != NULL; v++ ) {
+               len += strlen( *v ) + slen;
+       }
+
+       if ( len == 0 ) {
+               return NULL;
+       }
+
+       /* trim extra sep len */
+       len -= slen;
+
+       s = LDAP_MALLOC ( len + 1 );
+
+       if ( s == NULL ) {
+               return NULL;
+       }
+
+       p = s;
+       for ( v = a; *v != NULL; v++ ) {
+               if ( v != a ) {
+                       strncpy( p, sep, slen );
+                       p += slen;
+               }
+
+               len = strlen( *v );
+               strncpy( p, *v, len );
+               p += len;
+       }
+
+       *p = '\0';
+       return s;
+}
+
+
+\f
+/* $OpenLDAP: pkg/ldap/libraries/libldap/url.c,v 1.64.2.5 2003/03/03 17:10:05 kurt Exp $ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*  Portions
+ *  Copyright (c) 1996 Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  LIBLDAP url.c -- LDAP URL (RFC 2255) related routines
+ *
+ *  LDAP URLs look like this:
+ *    ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
+ *
+ *  where:
+ *   attributes is a comma separated list
+ *   scope is one of these three strings:  base one sub (default=base)
+ *   filter is an string-represented filter as in RFC 2254
+ *
+ *  e.g.,  ldap://host:port/dc=com?o,cn?base?(o=openldap)?extension
+ *
+ *  We also tolerate URLs that look like: <ldapurl> and <URL:ldapurl>
+ */
+
+/* local functions */
+static const char* skip_url_prefix LDAP_P((
+       const char *url,
+       int *enclosedp,
+       const char **scheme ));
+
+int
+ldap_is_ldap_url( LDAP_CONST char *url )
+{
+       int     enclosed;
+       const char * scheme;
+
+       if( url == NULL ) {
+               return 0;
+       }
+
+       if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
+               return 0;
+       }
+
+       return 1;
+}
+
+
+static const char*
+skip_url_prefix(
+       const char *url,
+       int *enclosedp,
+       const char **scheme )
+{
+       /*
+        * return non-zero if this looks like a LDAP URL; zero if not
+        * if non-zero returned, *urlp will be moved past "ldap://" part of URL
+        */
+       const char *p;
+
+       if ( url == NULL ) {
+               return( NULL );
+       }
+
+       p = url;
+
+       /* skip leading '<' (if any) */
+       if ( *p == '<' ) {
+               *enclosedp = 1;
+               ++p;
+       } else {
+               *enclosedp = 0;
+       }
+
+       /* skip leading "URL:" (if any) */
+       if ( strncasecmp( p, LDAP_URL_URLCOLON, LDAP_URL_URLCOLON_LEN ) == 0 ) {
+               p += LDAP_URL_URLCOLON_LEN;
+       }
+
+       /* check for "ldap://" prefix */
+       if ( strncasecmp( p, LDAP_URL_PREFIX, LDAP_URL_PREFIX_LEN ) == 0 ) {
+               /* skip over "ldap://" prefix and return success */
+               p += LDAP_URL_PREFIX_LEN;
+               *scheme = "ldap";
+               return( p );
+       }
+
+       /* check for "ldaps://" prefix */
+       if ( strncasecmp( p, LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) {
+               /* skip over "ldaps://" prefix and return success */
+               p += LDAPS_URL_PREFIX_LEN;
+               *scheme = "ldaps";
+               return( p );
+       }
+
+       /* check for "ldapi://" prefix */
+       if ( strncasecmp( p, LDAPI_URL_PREFIX, LDAPI_URL_PREFIX_LEN ) == 0 ) {
+               /* skip over "ldapi://" prefix and return success */
+               p += LDAPI_URL_PREFIX_LEN;
+               *scheme = "ldapi";
+               return( p );
+       }
+
+#ifdef LDAP_CONNECTIONLESS
+       /* check for "cldap://" prefix */
+       if ( strncasecmp( p, LDAPC_URL_PREFIX, LDAPC_URL_PREFIX_LEN ) == 0 ) {
+               /* skip over "cldap://" prefix and return success */
+               p += LDAPC_URL_PREFIX_LEN;
+               *scheme = "cldap";
+               return( p );
+       }
+#endif
+
+       return( NULL );
+}
+
+
+static int str2scope( const char *p )
+{
+       if ( strcasecmp( p, "one" ) == 0 ) {
+               return LDAP_SCOPE_ONELEVEL;
+
+       } else if ( strcasecmp( p, "onetree" ) == 0 ) {
+               return LDAP_SCOPE_ONELEVEL;
+
+       } else if ( strcasecmp( p, "base" ) == 0 ) {
+               return LDAP_SCOPE_BASE;
+
+       } else if ( strcasecmp( p, "sub" ) == 0 ) {
+               return LDAP_SCOPE_SUBTREE;
+
+       } else if ( strcasecmp( p, "subtree" ) == 0 ) {
+               return LDAP_SCOPE_SUBTREE;
+       }
+
+       return( -1 );
+}
+
+
+int
+ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
+{
+/*
+ *  Pick apart the pieces of an LDAP URL.
+ */
+
+       LDAPURLDesc     *ludp;
+       char    *p, *q, *r;
+       int             i, enclosed;
+       const char *scheme = NULL;
+       const char *url_tmp;
+       char *url;
+
+       if( url_in == NULL || ludpp == NULL ) {
+               return LDAP_URL_ERR_PARAM;
+       }
+
+#ifndef LDAP_INT_IN_KERNEL
+       /* Global options may not be created yet
+        * We can't test if the global options are initialized
+        * because a call to LDAP_INT_GLOBAL_OPT() will try to allocate
+        * the options and cause infinite recursion
+        */
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, ENTRY, "ldap_url_parse_ext(%s)\n", url_in, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "ldap_url_parse_ext(%s)\n", url_in, 0, 0 );
+#endif
+#endif
+
+       *ludpp = NULL;  /* pessimistic */
+
+       url_tmp = skip_url_prefix( url_in, &enclosed, &scheme );
+
+       if ( url_tmp == NULL ) {
+               return LDAP_URL_ERR_BADSCHEME;
+       }
+
+       assert( scheme );
+
+       /* make working copy of the remainder of the URL */
+       url = LDAP_STRDUP( url_tmp );
+       if ( url == NULL ) {
+               return LDAP_URL_ERR_MEM;
+       }
+
+       if ( enclosed ) {
+               p = &url[strlen(url)-1];
+
+               if( *p != '>' ) {
+                       LDAP_FREE( url );
+                       return LDAP_URL_ERR_BADENCLOSURE;
+               }
+
+               *p = '\0';
+       }
+
+       /* allocate return struct */
+       ludp = (LDAPURLDesc *)LDAP_CALLOC( 1, sizeof( LDAPURLDesc ));
+
+       if ( ludp == NULL ) {
+               LDAP_FREE( url );
+               return LDAP_URL_ERR_MEM;
+       }
+
+       ludp->lud_next = NULL;
+       ludp->lud_host = NULL;
+       ludp->lud_port = 0;
+       ludp->lud_dn = NULL;
+       ludp->lud_attrs = NULL;
+       ludp->lud_filter = NULL;
+       ludp->lud_scope = LDAP_SCOPE_DEFAULT;
+       ludp->lud_filter = NULL;
+       ludp->lud_exts = NULL;
+
+       ludp->lud_scheme = LDAP_STRDUP( scheme );
+
+       if ( ludp->lud_scheme == NULL ) {
+               LDAP_FREE( url );
+               ldap_free_urldesc( ludp );
+               return LDAP_URL_ERR_MEM;
+       }
+
+       /* scan forward for '/' that marks end of hostport and begin. of dn */
+       p = strchr( url, '/' );
+
+       if( p != NULL ) {
+               /* terminate hostport; point to start of dn */
+               *p++ = '\0';
+       }
+
+       /* IPv6 syntax with [ip address]:port */
+       if ( *url == '[' ) {
+               r = strchr( url, ']' );
+               if ( r == NULL ) {
+                       LDAP_FREE( url );
+                       ldap_free_urldesc( ludp );
+                       return LDAP_URL_ERR_BADURL;
+               }
+               *r++ = '\0';
+               q = strchr( r, ':' );
+       } else {
+               q = strchr( url, ':' );
+       }
+
+       if ( q != NULL ) {
+               *q++ = '\0';
+               ldap_pvt_hex_unescape( q );
+
+               if( *q == '\0' ) {
+                       LDAP_FREE( url );
+                       ldap_free_urldesc( ludp );
+                       return LDAP_URL_ERR_BADURL;
+               }
+
+               ludp->lud_port = atoi( q );
+       }
+
+       ldap_pvt_hex_unescape( url );
+
+       /* If [ip address]:port syntax, url is [ip and we skip the [ */
+       ludp->lud_host = LDAP_STRDUP( url + ( *url == '[' ) );
+
+       if( ludp->lud_host == NULL ) {
+               LDAP_FREE( url );
+               ldap_free_urldesc( ludp );
+               return LDAP_URL_ERR_MEM;
+       }
+
+       /*
+        * Kludge.  ldap://111.222.333.444:389??cn=abc,o=company
+        *
+        * On early Novell releases, search references/referrals were returned
+        * in this format, i.e., the dn was kind of in the scope position,
+        * but the required slash is missing. The whole thing is illegal syntax,
+        * but we need to account for it. Fortunately it can't be confused with
+        * anything real.
+        */
+       if( (p == NULL) && (q != NULL) && ((q = strchr( q, '?')) != NULL)) {
+               q++;
+               /* ? immediately followed by question */
+               if( *q == '?') {
+                       q++;
+                       if( *q != '\0' ) {
+                               /* parse dn part */
+                               ldap_pvt_hex_unescape( q );
+                               ludp->lud_dn = LDAP_STRDUP( q );
+                       } else {
+                               ludp->lud_dn = LDAP_STRDUP( "" );
+                       }
+
+                       if( ludp->lud_dn == NULL ) {
+                               LDAP_FREE( url );
+                               ldap_free_urldesc( ludp );
+                               return LDAP_URL_ERR_MEM;
+                       }
+               }
+       }
+
+       if( p == NULL ) {
+               LDAP_FREE( url );
+               *ludpp = ludp;
+               return LDAP_URL_SUCCESS;
+       }
+
+       /* scan forward for '?' that may marks end of dn */
+       q = strchr( p, '?' );
+
+       if( q != NULL ) {
+               /* terminate dn part */
+               *q++ = '\0';
+       }
+
+       if( *p != '\0' ) {
+               /* parse dn part */
+               ldap_pvt_hex_unescape( p );
+               ludp->lud_dn = LDAP_STRDUP( p );
+       } else {
+               ludp->lud_dn = LDAP_STRDUP( "" );
+       }
+
+       if( ludp->lud_dn == NULL ) {
+               LDAP_FREE( url );
+               ldap_free_urldesc( ludp );
+               return LDAP_URL_ERR_MEM;
+       }
+
+       if( q == NULL ) {
+               /* no more */
+               LDAP_FREE( url );
+               *ludpp = ludp;
+               return LDAP_URL_SUCCESS;
+       }
+
+       /* scan forward for '?' that may marks end of attributes */
+       p = q;
+       q = strchr( p, '?' );
+
+       if( q != NULL ) {
+               /* terminate attributes part */
+               *q++ = '\0';
+       }
+
+       if( *p != '\0' ) {
+               /* parse attributes */
+               ldap_pvt_hex_unescape( p );
+               ludp->lud_attrs = ldap_str2charray( p, "," );
+
+               if( ludp->lud_attrs == NULL ) {
+                       LDAP_FREE( url );
+                       ldap_free_urldesc( ludp );
+                       return LDAP_URL_ERR_BADATTRS;
+               }
+       }
+
+       if ( q == NULL ) {
+               /* no more */
+               LDAP_FREE( url );
+               *ludpp = ludp;
+               return LDAP_URL_SUCCESS;
+       }
+
+       /* scan forward for '?' that may marks end of scope */
+       p = q;
+       q = strchr( p, '?' );
+
+       if( q != NULL ) {
+               /* terminate the scope part */
+               *q++ = '\0';
+       }
+
+       if( *p != '\0' ) {
+               /* parse the scope */
+               ldap_pvt_hex_unescape( p );
+               ludp->lud_scope = str2scope( p );
+
+               if( ludp->lud_scope == -1 ) {
+                       LDAP_FREE( url );
+                       ldap_free_urldesc( ludp );
+                       return LDAP_URL_ERR_BADSCOPE;
+               }
+       }
+
+       if ( q == NULL ) {
+               /* no more */
+               LDAP_FREE( url );
+               *ludpp = ludp;
+               return LDAP_URL_SUCCESS;
+       }
+
+       /* scan forward for '?' that may marks end of filter */
+       p = q;
+       q = strchr( p, '?' );
+
+       if( q != NULL ) {
+               /* terminate the filter part */
+               *q++ = '\0';
+       }
+
+       if( *p != '\0' ) {
+               /* parse the filter */
+               ldap_pvt_hex_unescape( p );
+
+               if( ! *p ) {
+                       /* missing filter */
+                       LDAP_FREE( url );
+                       ldap_free_urldesc( ludp );
+                       return LDAP_URL_ERR_BADFILTER;
+               }
+
+               LDAP_FREE( ludp->lud_filter );
+               ludp->lud_filter = LDAP_STRDUP( p );
+
+               if( ludp->lud_filter == NULL ) {
+                       LDAP_FREE( url );
+                       ldap_free_urldesc( ludp );
+                       return LDAP_URL_ERR_MEM;
+               }
+       }
+
+       if ( q == NULL ) {
+               /* no more */
+               LDAP_FREE( url );
+               *ludpp = ludp;
+               return LDAP_URL_SUCCESS;
+       }
+
+       /* scan forward for '?' that may marks end of extensions */
+       p = q;
+       q = strchr( p, '?' );
+
+       if( q != NULL ) {
+               /* extra '?' */
+               LDAP_FREE( url );
+               ldap_free_urldesc( ludp );
+               return LDAP_URL_ERR_BADURL;
+       }
+
+       /* parse the extensions */
+       ludp->lud_exts = ldap_str2charray( p, "," );
+
+       if( ludp->lud_exts == NULL ) {
+               LDAP_FREE( url );
+               ldap_free_urldesc( ludp );
+               return LDAP_URL_ERR_BADEXTS;
+       }
+
+       for( i=0; ludp->lud_exts[i] != NULL; i++ ) {
+               ldap_pvt_hex_unescape( ludp->lud_exts[i] );
+
+               if( *ludp->lud_exts[i] == '!' ) {
+                       /* count the number of critical extensions */
+                       ludp->lud_crit_exts++;
+               }
+       }
+
+       if( i == 0 ) {
+               /* must have 1 or more */
+               LDAP_FREE( url );
+               ldap_free_urldesc( ludp );
+               return LDAP_URL_ERR_BADEXTS;
+       }
+
+       /* no more */
+       *ludpp = ludp;
+       LDAP_FREE( url );
+       return LDAP_URL_SUCCESS;
+}
+
+int
+ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
+{
+       int rc = ldap_url_parse_ext( url_in, ludpp );
+
+       if( rc != LDAP_URL_SUCCESS ) {
+               return rc;
+       }
+
+       if ((*ludpp)->lud_scope == LDAP_SCOPE_DEFAULT) {
+               (*ludpp)->lud_scope = LDAP_SCOPE_BASE;
+       }
+
+       if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
+               LDAP_FREE( (*ludpp)->lud_host );
+               (*ludpp)->lud_host = NULL;
+       }
+
+       if ((*ludpp)->lud_port == 0) {
+               if( strcmp((*ludpp)->lud_scheme, "ldap") == 0 ) {
+                       (*ludpp)->lud_port = LDAP_PORT;
+#ifdef LDAP_CONNECTIONLESS
+               } else if( strcmp((*ludpp)->lud_scheme, "cldap") == 0 ) {
+                       (*ludpp)->lud_port = LDAP_PORT;
+#endif
+               } else if( strcmp((*ludpp)->lud_scheme, "ldaps") == 0 ) {
+                       (*ludpp)->lud_port = LDAPS_PORT;
+               }
+       }
+
+       return rc;
+}
+
+
+void
+ldap_free_urldesc( LDAPURLDesc *ludp )
+{
+       if ( ludp == NULL ) {
+               return;
+       }
+
+       if ( ludp->lud_scheme != NULL ) {
+               LDAP_FREE( ludp->lud_scheme );
+       }
+
+       if ( ludp->lud_host != NULL ) {
+               LDAP_FREE( ludp->lud_host );
+       }
+
+       if ( ludp->lud_dn != NULL ) {
+               LDAP_FREE( ludp->lud_dn );
+       }
+
+       if ( ludp->lud_filter != NULL ) {
+               LDAP_FREE( ludp->lud_filter);
+       }
+
+       if ( ludp->lud_attrs != NULL ) {
+               LDAP_VFREE( ludp->lud_attrs );
+       }
+
+       if ( ludp->lud_exts != NULL ) {
+               LDAP_VFREE( ludp->lud_exts );
+       }
+
+       LDAP_FREE( ludp );
+}
+
+
+static int
+ldap_int_unhex( int c )
+{
+       return( c >= '0' && c <= '9' ? c - '0'
+           : c >= 'A' && c <= 'F' ? c - 'A' + 10
+           : c - 'a' + 10 );
+}
+
+void
+ldap_pvt_hex_unescape( char *s )
+{
+       /*
+        * Remove URL hex escapes from s... done in place.  The basic concept for
+        * this routine is borrowed from the WWW library HTUnEscape() routine.
+        */
+       char    *p;
+
+       for ( p = s; *s != '\0'; ++s ) {
+               if ( *s == '%' ) {
+                       if ( *++s == '\0' ) {
+                               break;
+                       }
+                       *p = ldap_int_unhex( *s ) << 4;
+                       if ( *++s == '\0' ) {
+                               break;
+                       }
+                       *p++ += ldap_int_unhex( *s );
+               } else {
+                       *p++ = *s;
+               }
+       }
+
+       *p = '\0';
+}
diff --git a/dirmngr/ldap-url.h b/dirmngr/ldap-url.h
new file mode 100644 (file)
index 0000000..f3104d8
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright 2007 g10 Code GmbH
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This 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.  */
+
+#ifndef LDAP_URL_H
+#define LDAP_URL_H 1
+
+#define LDAP_CONST const
+
+typedef struct ldap_url_desc
+{
+  struct ldap_url_desc *lud_next;
+  char *lud_scheme;
+  char *lud_host;
+  int lud_port;
+  char *lud_dn;
+  char **lud_attrs;
+  int lud_scope;
+  char *lud_filter;
+  char **lud_exts;
+  int lud_crit_exts;
+} LDAPURLDesc;
+
+#define LDAP_URL_SUCCESS       0x00
+#define LDAP_URL_ERR_MEM       0x01
+#define LDAP_URL_ERR_PARAM     0x02
+
+#define LDAP_URL_ERR_BADSCHEME 0x03
+#define LDAP_URL_ERR_BADENCLOSURE 0x04
+#define LDAP_URL_ERR_BADURL    0x05
+#define LDAP_URL_ERR_BADHOST   0x06
+#define LDAP_URL_ERR_BADATTRS  0x07
+#define LDAP_URL_ERR_BADSCOPE  0x08
+#define LDAP_URL_ERR_BADFILTER 0x09
+#define LDAP_URL_ERR_BADEXTS   0x0a
+
+#define LDAPS_PORT 636
+
+int ldap_is_ldap_url (LDAP_CONST char *url);
+int ldap_url_parse (LDAP_CONST char *url_in, LDAPURLDesc **ludpp);
+void ldap_free_urldesc (LDAPURLDesc *ludp);
+
+#endif /* !LDAP_URL_H */
diff --git a/dirmngr/ldap-wrapper-ce.c b/dirmngr/ldap-wrapper-ce.c
new file mode 100644 (file)
index 0000000..ce63ea6
--- /dev/null
@@ -0,0 +1,571 @@
+/* ldap-wrapper-ce.c - LDAP access via W32 threads
+ * Copyright (C) 2010 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+   Alternative wrapper for use with WindowsCE.  Under WindowsCE the
+   number of processes is strongly limited (32 processes including the
+   kernel processes) and thus we don't use the process approach but
+   implement a wrapper based on native threads.
+
+   See ldap-wrapper.c for  the standard wrapper interface.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <npth.h>
+#include <assert.h>
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "ldap-wrapper.h"
+
+#ifdef USE_LDAPWRAPPER
+# error This module is not expected to be build.
+#endif
+
+
+
+/* Read a fixed amount of data from READER into BUFFER.  */
+static gpg_error_t
+read_buffer (ksba_reader_t reader, unsigned char *buffer, size_t count)
+{
+  gpg_error_t err;
+  size_t nread;
+
+  while (count)
+    {
+      err = ksba_reader_read (reader, buffer, count, &nread);
+      if (err)
+        return err;
+      buffer += nread;
+      count -= nread;
+    }
+  return 0;
+}
+
+
+
+
+/* Start the reaper thread for this wrapper.  */
+void
+ldap_wrapper_launch_thread (void)
+{
+  /* Not required.  */
+}
+
+
+
+
+
+/* Wait until all ldap wrappers have terminated.  We assume that the
+   kill has already been sent to all of them.  */
+void
+ldap_wrapper_wait_connections ()
+{
+  /* Not required.  */
+}
+
+
+/* Cleanup all resources held by the connection associated with
+   CTRL.  This is used after a cancel to kill running wrappers.  */
+void
+ldap_wrapper_connection_cleanup (ctrl_t ctrl)
+{
+  (void)ctrl;
+
+  /* Not required.  */
+}
+
+
+\f
+/* The cookie we use to implement the outstream of the wrapper thread.  */
+struct outstream_cookie_s
+{
+  int refcount; /* Reference counter - possible values are 1 and 2.  */
+
+  /* We don't need a mutex for the conditions, as npth provides a
+     simpler condition interface that relies on the global lock.  This
+     can be used if we never yield between testing the condition and
+     waiting on it.  */
+  npth_cond_t wait_data; /* Condition that data is available.  */
+  npth_cond_t wait_space; /* Condition that space is available.  */
+
+  int eof_seen;       /* EOF indicator.  */
+  char buffer[4000];  /* Data ring buffer.  */
+  size_t buffer_len;  /* The amount of data in the BUFFER.  */
+  size_t buffer_pos;  /* The next read position of the BUFFER.  */
+};
+
+#define BUFFER_EMPTY(c) ((c)->buffer_len == 0)
+#define BUFFER_FULL(c) ((c)->buffer_len == DIM((c)->buffer))
+#define BUFFER_DATA_AVAILABLE(c) ((c)->buffer_len)
+#define BUFFER_SPACE_AVAILABLE(c) (DIM((c)->buffer) - (c)->buffer_len)
+#define BUFFER_INC_POS(c,n) (c)->buffer_pos = ((c)->buffer_pos + (n)) % DIM((c)->buffer)
+#define BUFFER_CUR_POS(c) (&(c)->buffer[(c)->buffer_pos])
+
+static int
+buffer_get_data (struct outstream_cookie_s *cookie, char *dst, int cnt)
+{
+  int amount;
+  int left;
+  int chunk;
+
+  amount = cnt;
+  if (BUFFER_DATA_AVAILABLE (cookie) < amount)
+    amount = BUFFER_DATA_AVAILABLE (cookie);
+  left = amount;
+
+  /* How large is the part up to the end of the buffer array?  */
+  chunk = DIM(cookie->buffer) - cookie->buffer_pos;
+  if (chunk > left)
+    chunk = left;
+
+  memcpy (dst, BUFFER_CUR_POS (cookie), chunk);
+  BUFFER_INC_POS (cookie, chunk);
+  left -= chunk;
+  dst += chunk;
+
+  if (left)
+    {
+      memcpy (dst, BUFFER_CUR_POS (cookie), left);
+      BUFFER_INC_POS (cookie, left);
+    }
+
+  return amount;
+}
+
+
+static int
+buffer_put_data (struct outstream_cookie_s *cookie, const char *src, int cnt)
+{
+  int amount;
+  int remain;
+  int left;
+  int chunk;
+
+  remain = DIM(cookie->buffer) - cookie->buffer_len;
+
+  amount = cnt;
+  if (remain < amount)
+    amount = remain;
+  left = amount;
+
+  /* How large is the part up to the end of the buffer array?  */
+  chunk = DIM(cookie->buffer) - cookie->buffer_pos;
+  if (chunk > left)
+    chunk = left;
+
+  memcpy (BUFFER_CUR_POS (cookie), src, chunk);
+  BUFFER_INC_POS (cookie, chunk);
+  left -= chunk;
+  src += chunk;
+
+  if (left)
+    {
+      memcpy (BUFFER_CUR_POS (cookie), src, left);
+      BUFFER_INC_POS (cookie, left);
+    }
+
+  cookie->buffer_len -= amount;
+  return amount;
+}
+
+
+/* The writer function for the outstream.  This is used to transfer
+   the output of the ldap wrapper thread to the ksba reader object.  */
+static ssize_t
+outstream_cookie_writer (void *cookie_arg, const void *buffer, size_t size)
+{
+  struct outstream_cookie_s *cookie = cookie_arg;
+  const char *src;
+  ssize_t nwritten = 0;
+  int res;
+  ssize_t amount = 0;
+
+  src = buffer;
+  do
+    {
+      int was_empty = 0;
+
+      /* Wait for free space.  */
+      while (BUFFER_FULL(cookie))
+        {
+          /* Buffer is full:  Wait for space.  */
+          res = npth_cond_wait (&cookie->wait_space, NULL);
+         if (res)
+           {
+             gpg_err_set_errno (res);
+             return -1;
+           }
+        }
+
+      if (BUFFER_EMPTY(cookie))
+       was_empty = 1;
+
+      /* Copy data.  */
+      nwritten = buffer_put_data (cookie, buffer, size);
+      size -= nwritten;
+      src += nwritten;
+      amount += nwritten;
+
+      if (was_empty)
+       npth_cond_signal (&cookie->wait_data);
+    }
+  while (size);  /* Until done.  */
+
+  return amount;
+}
+
+
+static void
+outstream_release_cookie (struct outstream_cookie_s *cookie)
+{
+  cookie->refcount--;
+  if (!cookie->refcount)
+    {
+      npth_cond_destroy (&cookie->wait_data);
+      npth_cond_destroy (&cookie->wait_space);
+      xfree (cookie);
+    }
+}
+
+
+/* Closer function for the outstream.  This deallocates the cookie if
+   it won't be used anymore.  */
+static int
+outstream_cookie_closer (void *cookie_arg)
+{
+  struct outstream_cookie_s *cookie = cookie_arg;
+
+  if (!cookie)
+    return 0;  /* Nothing to do.  */
+
+  cookie->eof_seen = 1; /* (only useful if refcount > 1)  */
+
+  assert (cookie->refcount > 0);
+  outstream_release_cookie (cookie);
+  return 0;
+}
+
+
+/* The KSBA reader callback which takes the output of the ldap thread
+   form the outstream_cookie_writer and make it available to the ksba
+   reader.  */
+static int
+outstream_reader_cb (void *cb_value, char *buffer, size_t count,
+                     size_t *r_nread)
+{
+  struct outstream_cookie_s *cookie = cb_value;
+  size_t nread = 0;
+  int was_full = 0;
+
+  if (!buffer && !count && !r_nread)
+    return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Rewind is not supported.  */
+
+  *r_nread = 0;
+
+  while (BUFFER_EMPTY(cookie))
+    {
+      if (cookie->eof_seen)
+        return gpg_error (GPG_ERR_EOF);
+
+      /* Wait for data to become available.  */
+      npth_cond_wait (&cookie->wait_data, NULL);
+    }
+
+  if (BUFFER_FULL(cookie))
+    was_full = 1;
+
+  nread = buffer_get_data (cookie, buffer, count);
+
+  if (was_full)
+    {
+      npth_cond_signal (&cookie->wait_space);
+    }
+
+  *r_nread = nread;
+  return 0; /* Success.  */
+}
+
+
+/* This function is called by ksba_reader_release.  */
+static void
+outstream_reader_released (void *cb_value, ksba_reader_t r)
+{
+  struct outstream_cookie_s *cookie = cb_value;
+
+  (void)r;
+
+  assert (cookie->refcount > 0);
+  outstream_release_cookie (cookie);
+}
+
+
+
+/* This function is to be used to release a context associated with the
+   given reader object.  This does not release the reader object, though. */
+void
+ldap_wrapper_release_context (ksba_reader_t reader)
+{
+  (void)reader;
+  /* Nothing to do.  */
+}
+
+
+\f
+/* Free a NULL terminated array of malloced strings and the array
+   itself.  */
+static void
+free_arg_list (char **arg_list)
+{
+  int i;
+
+  if (arg_list)
+    {
+      for (i=0; arg_list[i]; i++)
+        xfree (arg_list[i]);
+      xfree (arg_list);
+    }
+}
+
+
+/* Copy ARGV into a new array and prepend one element as name of the
+   program (which is more or less a stub).  We need to allocate all
+   the strings to get ownership of them.  */
+static gpg_error_t
+create_arg_list (const char *argv[], char ***r_arg_list)
+{
+  gpg_error_t err;
+  char **arg_list;
+  int i, j;
+
+  for (i = 0; argv[i]; i++)
+    ;
+  arg_list = xtrycalloc (i + 2, sizeof *arg_list);
+  if (!arg_list)
+    goto outofcore;
+
+  i = 0;
+  arg_list[i] = xtrystrdup ("<ldap-wrapper-thread>");
+  if (!arg_list[i])
+    goto outofcore;
+  i++;
+  for (j=0; argv[j]; j++)
+    {
+      arg_list[i] = xtrystrdup (argv[j]);
+      if (!arg_list[i])
+        goto outofcore;
+      i++;
+    }
+  arg_list[i] = NULL;
+  *r_arg_list = arg_list;
+  return 0;
+
+ outofcore:
+  err = gpg_error_from_syserror ();
+  log_error (_("error allocating memory: %s\n"), strerror (errno));
+  free_arg_list (arg_list);
+  *r_arg_list = NULL;
+  return err;
+
+}
+
+
+/* Parameters passed to the wrapper thread. */
+struct ldap_wrapper_thread_parms
+{
+  char **arg_list;
+  estream_t outstream;
+};
+
+/* The thread which runs the LDAP wrapper.  */
+static void *
+ldap_wrapper_thread (void *opaque)
+{
+  struct ldap_wrapper_thread_parms *parms = opaque;
+
+  /*err =*/ ldap_wrapper_main (parms->arg_list, parms->outstream);
+
+  /* FIXME: Do we need to return ERR?  */
+
+  free_arg_list (parms->arg_list);
+  es_fclose (parms->outstream);
+  xfree (parms);
+  return NULL;
+}
+
+
+
+/* Start a new LDAP thread and returns a new libksba reader
+   object at READER.  ARGV is a NULL terminated list of arguments for
+   the wrapper.  The function returns 0 on success or an error code.  */
+gpg_error_t
+ldap_wrapper (ctrl_t ctrl, ksba_reader_t *r_reader, const char *argv[])
+{
+  gpg_error_t err;
+  struct ldap_wrapper_thread_parms *parms;
+  npth_attr_t tattr;
+  es_cookie_io_functions_t outstream_func = { NULL };
+  struct outstream_cookie_s *outstream_cookie;
+  ksba_reader_t reader;
+  int res;
+  npth_t thread;
+
+  (void)ctrl;
+
+  *r_reader = NULL;
+
+  parms = xtrycalloc (1, sizeof *parms);
+  if (!parms)
+    return gpg_error_from_syserror ();
+
+  err = create_arg_list (argv, &parms->arg_list);
+  if (err)
+    {
+      xfree (parms);
+      return err;
+    }
+
+  outstream_cookie = xtrycalloc (1, sizeof *outstream_cookie);
+  if (!outstream_cookie)
+    {
+      err = gpg_error_from_syserror ();
+      free_arg_list (parms->arg_list);
+      xfree (parms);
+      return err;
+    }
+  outstream_cookie->refcount++;
+
+  res = npth_cond_init (&outstream_cookie->wait_data, NULL);
+  if (res)
+    {
+      free_arg_list (parms->arg_list);
+      xfree (parms);
+      return gpg_error_from_errno (res);
+    }
+  res = npth_cond_init (&outstream_cookie->wait_space, NULL);
+  if (res)
+    {
+      npth_cond_destroy (&outstream_cookie->wait_data);
+      free_arg_list (parms->arg_list);
+      xfree (parms);
+      return gpg_error_from_errno (res);
+    }
+
+  err = ksba_reader_new (&reader);
+  if (!err)
+    err = ksba_reader_set_release_notify (reader,
+                                          outstream_reader_released,
+                                          outstream_cookie);
+  if (!err)
+    err = ksba_reader_set_cb (reader,
+                              outstream_reader_cb, outstream_cookie);
+  if (err)
+    {
+      log_error (_("error initializing reader object: %s\n"),
+                 gpg_strerror (err));
+      ksba_reader_release (reader);
+      outstream_release_cookie (outstream_cookie);
+      free_arg_list (parms->arg_list);
+      xfree (parms);
+      return err;
+    }
+
+
+  outstream_func.func_write = outstream_cookie_writer;
+  outstream_func.func_close = outstream_cookie_closer;
+  parms->outstream = es_fopencookie (outstream_cookie, "wb", outstream_func);
+  if (!parms->outstream)
+    {
+      err = gpg_error_from_syserror ();
+      ksba_reader_release (reader);
+      outstream_release_cookie (outstream_cookie);
+      free_arg_list (parms->arg_list);
+      xfree (parms);
+      return err;
+    }
+  outstream_cookie->refcount++;
+
+  res = npth_attr_init(&tattr);
+  if (res)
+    {
+      err = gpg_error_from_errno (res);
+      ksba_reader_release (reader);
+      free_arg_list (parms->arg_list);
+      es_fclose (parms->outstream);
+      xfree (parms);
+      return err;
+    }
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+
+  res = npth_create (&thread, &tattr, ldap_wrapper_thread, parms);
+  npth_attr_destroy (&tattr);
+  if (res)
+    {
+      err = gpg_error_from_errno (res);
+      log_error ("error spawning ldap wrapper thread: %s\n",
+                 strerror (res) );
+    }
+  else
+    parms = NULL; /* Now owned by the thread.  */
+
+  if (parms)
+    {
+      free_arg_list (parms->arg_list);
+      es_fclose (parms->outstream);
+      xfree (parms);
+    }
+  if (err)
+    {
+      ksba_reader_release (reader);
+      return err;
+    }
+
+  /* Need to wait for the first byte so we are able to detect an empty
+     output and not let the consumer see an EOF without further error
+     indications.  The CRL loading logic assumes that after return
+     from this function, a failed search (e.g. host not found ) is
+     indicated right away. */
+  {
+    unsigned char c;
+
+    err = read_buffer (reader, &c, 1);
+    if (err)
+      {
+        ksba_reader_release (reader);
+        reader = NULL;
+        if (gpg_err_code (err) == GPG_ERR_EOF)
+          return gpg_error (GPG_ERR_NO_DATA);
+        else
+          return err;
+      }
+    ksba_reader_unread (reader, &c, 1);
+  }
+
+  *r_reader = reader;
+
+  return 0;
+}
diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c
new file mode 100644 (file)
index 0000000..f2aaf59
--- /dev/null
@@ -0,0 +1,788 @@
+/* ldap-wrapper.c - LDAP access via a wrapper process
+ * Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
+ * Copyright (C) 2010 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+   We can't use LDAP directly for these reasons:
+
+   1. On some systems the LDAP library uses (indirectly) pthreads and
+      that is not compatible with PTh.
+
+   2. It is huge library in particular if TLS comes into play.  So
+      problems with unfreed memory might turn up and we don't want
+      this in a long running daemon.
+
+   3. There is no easy way for timeouts. In particular the timeout
+      value does not work for DNS lookups (well, this is usual) and it
+      seems not to work while loading a large attribute like a
+      CRL. Having a separate process allows us to either tell the
+      process to commit suicide or have our own housekepping function
+      kill it after some time.  The latter also allows proper
+      cancellation of a query at any point of time.
+
+   4. Given that we are going out to the network and usually get back
+      a long response, the fork/exec overhead is acceptable.
+
+   Note that under WindowsCE the number of processes is strongly
+   limited (32 processes including the kernel processes) and thus we
+   don't use the process approach but implement a different wrapper in
+   ldap-wrapper-ce.c.
+*/
+
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <npth.h>
+
+#include "dirmngr.h"
+#include "exechelp.h"
+#include "misc.h"
+#include "ldap-wrapper.h"
+
+
+#ifdef HAVE_W32_SYSTEM
+#define setenv(a,b,c) SetEnvironmentVariable ((a),(b))
+#else
+#define pth_close(fd) close(fd)
+#endif
+
+#ifndef USE_LDAPWRAPPER
+# error This module is not expected to be build.
+#endif
+
+/* In case sysconf does not return a value we need to have a limit. */
+#ifdef _POSIX_OPEN_MAX
+#define MAX_OPEN_FDS _POSIX_OPEN_MAX
+#else
+#define MAX_OPEN_FDS 20
+#endif
+
+#define INACTIVITY_TIMEOUT (opt.ldaptimeout + 60*5)  /* seconds */
+
+#define TIMERTICK_INTERVAL 2
+
+/* To keep track of the LDAP wrapper state we use this structure.  */
+struct wrapper_context_s
+{
+  struct wrapper_context_s *next;
+
+  pid_t pid;    /* The pid of the wrapper process. */
+  int printable_pid; /* Helper to print diagnostics after the process has
+                        been cleaned up. */
+  int fd;       /* Connected with stdout of the ldap wrapper.  */
+  gpg_error_t fd_error; /* Set to the gpg_error of the last read error
+                           if any.  */
+  int log_fd;   /* Connected with stderr of the ldap wrapper.  */
+  ctrl_t ctrl;  /* Connection data. */
+  int ready;    /* Internally used to mark to be removed contexts. */
+  ksba_reader_t reader; /* The ksba reader object or NULL. */
+  char *line;     /* Used to print the log lines (malloced). */
+  size_t linesize;/* Allocated size of LINE.  */
+  size_t linelen; /* Use size of LINE.  */
+  time_t stamp;   /* The last time we noticed ativity.  */
+};
+
+
+
+/* We keep a global list of spawed wrapper process.  A separate thread
+   makes use of this list to log error messages and to watch out for
+   finished processes. */
+static struct wrapper_context_s *wrapper_list;
+
+/* We need to know whether we are shutting down the process.  */
+static int shutting_down;
+
+/* Close the pth file descriptor FD and set it to -1.  */
+#define SAFE_CLOSE(fd) \
+  do { int _fd = fd; if (_fd != -1) { close (_fd); fd = -1;} } while (0)
+
+
+
+\f
+/* Read a fixed amount of data from READER into BUFFER.  */
+static gpg_error_t
+read_buffer (ksba_reader_t reader, unsigned char *buffer, size_t count)
+{
+  gpg_error_t err;
+  size_t nread;
+
+  while (count)
+    {
+      err = ksba_reader_read (reader, buffer, count, &nread);
+      if (err)
+        return err;
+      buffer += nread;
+      count -= nread;
+    }
+  return 0;
+}
+
+
+/* Release the wrapper context and kill a running wrapper process. */
+static void
+destroy_wrapper (struct wrapper_context_s *ctx)
+{
+  if (ctx->pid != (pid_t)(-1))
+    {
+      gnupg_kill_process (ctx->pid);
+      gnupg_release_process (ctx->pid);
+    }
+  ksba_reader_release (ctx->reader);
+  SAFE_CLOSE (ctx->fd);
+  SAFE_CLOSE (ctx->log_fd);
+  xfree (ctx->line);
+  xfree (ctx);
+}
+
+
+/* Print the content of LINE to thye log stream but make sure to only
+   print complete lines.  Using NULL for LINE will flush any pending
+   output.  LINE may be modified by this fucntion. */
+static void
+print_log_line (struct wrapper_context_s *ctx, char *line)
+{
+  char *s;
+  size_t n;
+
+  if (!line)
+    {
+      if (ctx->line && ctx->linelen)
+        {
+
+          log_info ("%s\n", ctx->line);
+          ctx->linelen = 0;
+        }
+      return;
+    }
+
+  while ((s = strchr (line, '\n')))
+    {
+      *s = 0;
+      if (ctx->line && ctx->linelen)
+        {
+          log_info ("%s", ctx->line);
+          ctx->linelen = 0;
+          log_printf ("%s\n", line);
+        }
+      else
+        log_info ("%s\n", line);
+      line = s + 1;
+    }
+  n = strlen (line);
+  if (n)
+    {
+      if (ctx->linelen + n + 1 >= ctx->linesize)
+        {
+          char *tmp;
+          size_t newsize;
+
+          newsize = ctx->linesize + ((n + 255) & ~255) + 1;
+          tmp = (ctx->line ? xtryrealloc (ctx->line, newsize)
+                           : xtrymalloc (newsize));
+          if (!tmp)
+            {
+              log_error (_("error printing log line: %s\n"), strerror (errno));
+              return;
+            }
+          ctx->line = tmp;
+          ctx->linesize = newsize;
+        }
+      memcpy (ctx->line + ctx->linelen, line, n);
+      ctx->linelen += n;
+      ctx->line[ctx->linelen] = 0;
+    }
+}
+
+
+/* Read data from the log stream.  Returns true if the log stream
+   indicated EOF or error.  */
+static int
+read_log_data (struct wrapper_context_s *ctx)
+{
+  int n;
+  char line[256];
+
+  /* We must use the npth_read function for pipes, always.  */
+  do
+    n = npth_read (ctx->log_fd, line, sizeof line - 1);
+  while (n < 0 && errno == EINTR);
+
+  if (n <= 0) /* EOF or error. */
+    {
+      if (n < 0)
+        log_error (_("error reading log from ldap wrapper %d: %s\n"),
+                   ctx->pid, strerror (errno));
+      print_log_line (ctx, NULL);
+      SAFE_CLOSE (ctx->log_fd);
+      return 1;
+    }
+
+  line[n] = 0;
+  print_log_line (ctx, line);
+  if (ctx->stamp != (time_t)(-1))
+    ctx->stamp = time (NULL);
+  return 0;
+}
+
+
+/* This function is run by a separate thread to maintain the list of
+   wrappers and to log error messages from these wrappers.  */
+void *
+ldap_wrapper_thread (void *dummy)
+{
+  int nfds;
+  struct wrapper_context_s *ctx;
+  struct wrapper_context_s *ctx_prev;
+  struct timespec abstime;
+  struct timespec curtime;
+  struct timespec timeout;
+  int saved_errno;
+  fd_set fdset, read_fdset;
+  int ret;
+  time_t exptime;
+
+  (void)dummy;
+
+  FD_ZERO (&fdset);
+  nfds = -1;
+  for (ctx = wrapper_list; ctx; ctx = ctx->next)
+    {
+      if (ctx->log_fd != -1)
+       {
+         FD_SET (ctx->log_fd, &fdset);
+         if (ctx->log_fd > nfds)
+           nfds = ctx->log_fd;
+       }
+    }
+  nfds++;
+
+  npth_clock_gettime (&abstime);
+  abstime.tv_sec += TIMERTICK_INTERVAL;
+
+  for (;;)
+    {
+      int any_action = 0;
+
+      /* POSIX says that fd_set should be implemented as a structure,
+         thus a simple assignment is fine to copy the entire set.  */
+      read_fdset = fdset;
+
+      npth_clock_gettime (&curtime);
+      if (!(npth_timercmp (&curtime, &abstime, <)))
+       {
+         /* Inactivity is checked below.  Nothing else to do.  */
+         // handle_tick ();
+         npth_clock_gettime (&abstime);
+         abstime.tv_sec += TIMERTICK_INTERVAL;
+       }
+      npth_timersub (&abstime, &curtime, &timeout);
+
+      /* FIXME: For Windows, we have to use a reader thread on the
+        pipe that signals an event (and a npth_select_ev variant).  */
+      ret = npth_pselect (nfds + 1, &read_fdset, NULL, NULL, &timeout, NULL);
+      saved_errno = errno;
+
+      if (ret == -1 && saved_errno != EINTR)
+       {
+          log_error (_("npth_select failed: %s - waiting 1s\n"),
+                     strerror (saved_errno));
+          npth_sleep (1);
+          continue;
+       }
+
+      if (ret <= 0)
+       /* Interrupt or timeout.  Will be handled when calculating the
+          next timeout.  */
+       continue;
+
+      /* All timestamps before exptime should be considered expired.  */
+      exptime = time (NULL);
+      if (exptime > INACTIVITY_TIMEOUT)
+        exptime -= INACTIVITY_TIMEOUT;
+
+      /* Note that there is no need to lock the list because we always
+         add entries at the head (with a pending event status) and
+         thus traversing the list will even work if we have a context
+         switch in waitpid (which should anyway only happen with Pth's
+         hard system call mapping).  */
+      for (ctx = wrapper_list; ctx; ctx = ctx->next)
+        {
+          /* Check whether there is any logging to be done. */
+          if (nfds && ctx->log_fd != -1 && FD_ISSET (ctx->log_fd, &read_fdset))
+            {
+              if (read_log_data (ctx))
+                any_action = 1;
+            }
+
+          /* Check whether the process is still running.  */
+          if (ctx->pid != (pid_t)(-1))
+            {
+              gpg_error_t err;
+             int status;
+
+             err = gnupg_wait_process ("[dirmngr_ldap]", ctx->pid, 0,
+                                        &status);
+              if (!err)
+                {
+                 log_info (_("ldap wrapper %d ready"), (int)ctx->pid);
+                  ctx->ready = 1;
+                 gnupg_release_process (ctx->pid);
+                  ctx->pid = (pid_t)(-1);
+                  any_action = 1;
+                }
+              else if (gpg_err_code (err) == GPG_ERR_GENERAL)
+                {
+                  if (status == 10)
+                    log_info (_("ldap wrapper %d ready: timeout\n"),
+                              (int)ctx->pid);
+                  else
+                    log_info (_("ldap wrapper %d ready: exitcode=%d\n"),
+                              (int)ctx->pid, status);
+                  ctx->ready = 1;
+                 gnupg_release_process (ctx->pid);
+                  ctx->pid = (pid_t)(-1);
+                  any_action = 1;
+                }
+              else if (gpg_err_code (err) != GPG_ERR_TIMEOUT)
+                {
+                  log_error (_("waiting for ldap wrapper %d failed: %s\n"),
+                             (int)ctx->pid, gpg_strerror (err));
+                  any_action = 1;
+                }
+            }
+
+          /* Check whether we should terminate the process. */
+          if (ctx->pid != (pid_t)(-1)
+              && ctx->stamp != (time_t)(-1) && ctx->stamp < exptime)
+            {
+              gnupg_kill_process (ctx->pid);
+              ctx->stamp = (time_t)(-1);
+              log_info (_("ldap wrapper %d stalled - killing\n"),
+                        (int)ctx->pid);
+              /* We need to close the log fd because the cleanup loop
+                 waits for it.  */
+              SAFE_CLOSE (ctx->log_fd);
+              any_action = 1;
+            }
+        }
+
+      /* If something has been printed to the log file or we got an
+         EOF from a wrapper, we now print the list of active
+         wrappers.  */
+      if (any_action && DBG_LOOKUP)
+        {
+          log_info ("ldap worker stati:\n");
+          for (ctx = wrapper_list; ctx; ctx = ctx->next)
+            log_info ("  c=%p pid=%d/%d rdr=%p ctrl=%p/%d la=%lu rdy=%d\n",
+                      ctx,
+                      (int)ctx->pid, (int)ctx->printable_pid,
+                      ctx->reader,
+                      ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0,
+                      (unsigned long)ctx->stamp, ctx->ready);
+        }
+
+
+      /* Use a separate loop to check whether ready marked wrappers
+         may be removed.  We may only do so if the ksba reader object
+         is not anymore in use or we are in shutdown state.  */
+     again:
+      for (ctx_prev=NULL, ctx=wrapper_list; ctx; ctx_prev=ctx, ctx=ctx->next)
+        if (ctx->ready
+            && ((ctx->log_fd == -1 && !ctx->reader) || shutting_down))
+          {
+            if (ctx_prev)
+              ctx_prev->next = ctx->next;
+            else
+              wrapper_list = ctx->next;
+            destroy_wrapper (ctx);
+            /* We need to restart because destroy_wrapper might have
+               done a context switch. */
+            goto again;
+          }
+    }
+  /*NOTREACHED*/
+  return NULL; /* Make the compiler happy.  */
+}
+
+
+
+/* Start the reaper thread for the ldap wrapper.  */
+void
+ldap_wrapper_launch_thread (void)
+{
+  static int done;
+  npth_attr_t tattr;
+  npth_t thread;
+  int err;
+
+  if (done)
+    return;
+  done = 1;
+
+  npth_attr_init (&tattr);
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+
+  err = npth_create (&thread, &tattr, ldap_wrapper_thread, NULL);
+  if (err)
+    {
+      log_error (_("error spawning ldap wrapper reaper thread: %s\n"),
+                 strerror (err) );
+      dirmngr_exit (1);
+    }
+  npth_setname_np (thread, "ldap-reaper");
+  npth_attr_destroy (&tattr);
+}
+
+
+
+
+
+/* Wait until all ldap wrappers have terminated.  We assume that the
+   kill has already been sent to all of them.  */
+void
+ldap_wrapper_wait_connections ()
+{
+  shutting_down = 1;
+  /* FIXME: This is a busy wait.  */
+  while (wrapper_list)
+    npth_usleep (200);
+}
+
+
+/* This function is to be used to release a context associated with the
+   given reader object. */
+void
+ldap_wrapper_release_context (ksba_reader_t reader)
+{
+  struct wrapper_context_s *ctx;
+
+  if (!reader )
+    return;
+
+  for (ctx=wrapper_list; ctx; ctx=ctx->next)
+    if (ctx->reader == reader)
+      {
+        if (DBG_LOOKUP)
+          log_info ("releasing ldap worker c=%p pid=%d/%d rdr=%p ctrl=%p/%d\n",
+                    ctx,
+                    (int)ctx->pid, (int)ctx->printable_pid,
+                    ctx->reader,
+                    ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0);
+
+        ctx->reader = NULL;
+        SAFE_CLOSE (ctx->fd);
+        if (ctx->ctrl)
+          {
+            ctx->ctrl->refcount--;
+            ctx->ctrl = NULL;
+          }
+        if (ctx->fd_error)
+          log_info (_("reading from ldap wrapper %d failed: %s\n"),
+                    ctx->printable_pid, gpg_strerror (ctx->fd_error));
+        break;
+      }
+}
+
+/* Cleanup all resources held by the connection associated with
+   CTRL.  This is used after a cancel to kill running wrappers.  */
+void
+ldap_wrapper_connection_cleanup (ctrl_t ctrl)
+{
+  struct wrapper_context_s *ctx;
+
+  for (ctx=wrapper_list; ctx; ctx=ctx->next)
+    if (ctx->ctrl && ctx->ctrl == ctrl)
+      {
+        ctx->ctrl->refcount--;
+        ctx->ctrl = NULL;
+        if (ctx->pid != (pid_t)(-1))
+          gnupg_kill_process (ctx->pid);
+        if (ctx->fd_error)
+          log_info (_("reading from ldap wrapper %d failed: %s\n"),
+                    ctx->printable_pid, gpg_strerror (ctx->fd_error));
+      }
+}
+
+
+/* This is the callback used by the ldap wrapper to feed the ksba
+   reader with the wrappers stdout.  See the description of
+   ksba_reader_set_cb for details.  */
+static int
+reader_callback (void *cb_value, char *buffer, size_t count,  size_t *nread)
+{
+  struct wrapper_context_s *ctx = cb_value;
+  size_t nleft = count;
+  int nfds;
+  struct timespec abstime;
+  struct timespec curtime;
+  struct timespec timeout;
+  int saved_errno;
+  fd_set fdset, read_fdset;
+  int ret;
+
+  /* FIXME: We might want to add some internal buffering because the
+     ksba code does not do any buffering for itself (because a ksba
+     reader may be detached from another stream to read other data and
+     the it would be cumbersome to get back already buffered
+     stuff).  */
+
+  if (!buffer && !count && !nread)
+    return -1; /* Rewind is not supported. */
+
+  /* If we ever encountered a read error don't allow to continue and
+     possible overwrite the last error cause.  Bail out also if the
+     file descriptor has been closed. */
+  if (ctx->fd_error || ctx->fd == -1)
+    {
+      *nread = 0;
+      return -1;
+    }
+
+  FD_ZERO (&fdset);
+  FD_SET (ctx->fd, &fdset);
+  nfds = ctx->fd + 1;
+
+  npth_clock_gettime (&abstime);
+  abstime.tv_sec += TIMERTICK_INTERVAL;
+
+  while (nleft > 0)
+    {
+      int n;
+      gpg_error_t err;
+
+      npth_clock_gettime (&curtime);
+      if (!(npth_timercmp (&curtime, &abstime, <)))
+       {
+         err = dirmngr_tick (ctx->ctrl);
+          if (err)
+            {
+              ctx->fd_error = err;
+              SAFE_CLOSE (ctx->fd);
+              return -1;
+            }
+         npth_clock_gettime (&abstime);
+         abstime.tv_sec += TIMERTICK_INTERVAL;
+       }
+      npth_timersub (&abstime, &curtime, &timeout);
+
+      read_fdset = fdset;
+      ret = npth_pselect (nfds, &read_fdset, NULL, NULL, &timeout, NULL);
+      saved_errno = errno;
+
+      if (ret == -1 && saved_errno != EINTR)
+       {
+          ctx->fd_error = gpg_error_from_errno (errno);
+          SAFE_CLOSE (ctx->fd);
+          return -1;
+        }
+      if (ret <= 0)
+       /* Timeout.  Will be handled when calculating the next timeout.  */
+       continue;
+
+      /* This should not block now that select returned with a file
+        descriptor.  So it shouldn't be necessary to use npth_read
+        (and it is slightly dangerous in the sense that a concurrent
+        thread might (accidentially?) change the status of ctx->fd
+        before we read.  FIXME: Set ctx->fd to nonblocking?  */
+      n = read (ctx->fd, buffer, nleft);
+      if (n < 0)
+        {
+          ctx->fd_error = gpg_error_from_errno (errno);
+          SAFE_CLOSE (ctx->fd);
+          return -1;
+        }
+      else if (!n)
+        {
+          if (nleft == count)
+           return -1; /* EOF. */
+          break;
+        }
+      nleft -= n;
+      buffer += n;
+      if (n > 0 && ctx->stamp != (time_t)(-1))
+        ctx->stamp = time (NULL);
+    }
+  *nread = count - nleft;
+
+  return 0;
+}
+
+/* Fork and exec the LDAP wrapper and returns a new libksba reader
+   object at READER.  ARGV is a NULL terminated list of arguments for
+   the wrapper.  The function returns 0 on success or an error code.
+
+   Special hack to avoid passing a password through the command line
+   which is globally visible: If the first element of ARGV is "--pass"
+   it will be removed and instead the environment variable
+   DIRMNGR_LDAP_PASS will be set to the next value of ARGV.  On modern
+   OSes the environment is not visible to other users.  For those old
+   systems where it can't be avoided, we don't want to go into the
+   hassle of passing the password via stdin; it's just too complicated
+   and an LDAP password used for public directory lookups should not
+   be that confidential.  */
+gpg_error_t
+ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[])
+{
+  gpg_error_t err;
+  pid_t pid;
+  struct wrapper_context_s *ctx;
+  int i;
+  int j;
+  const char **arg_list;
+  const char *pgmname;
+  int outpipe[2], errpipe[2];
+
+  /* It would be too simple to connect stderr just to our logging
+     stream.  The problem is that if we are running multi-threaded
+     everything gets intermixed.  Clearly we don't want this.  So the
+     only viable solutions are either to have another thread
+     responsible for logging the messages or to add an option to the
+     wrapper module to do the logging on its own.  Given that we anyway
+     need a way to rip the child process and this is best done using a
+     general ripping thread, that thread can do the logging too. */
+
+  *reader = NULL;
+
+  /* Files: We need to prepare stdin and stdout.  We get stderr from
+     the function.  */
+  if (!opt.ldap_wrapper_program || !*opt.ldap_wrapper_program)
+    pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR_LDAP);
+  else
+    pgmname = opt.ldap_wrapper_program;
+
+  /* Create command line argument array.  */
+  for (i = 0; argv[i]; i++)
+    ;
+  arg_list = xtrycalloc (i + 2, sizeof *arg_list);
+  if (!arg_list)
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("error allocating memory: %s\n"), strerror (errno));
+      return err;
+    }
+  for (i = j = 0; argv[i]; i++, j++)
+    if (!i && argv[i + 1] && !strcmp (*argv, "--pass"))
+      {
+       arg_list[j] = "--env-pass";
+       setenv ("DIRMNGR_LDAP_PASS", argv[1], 1);
+       i++;
+      }
+    else
+      arg_list[j] = (char*) argv[i];
+
+  ctx = xtrycalloc (1, sizeof *ctx);
+  if (!ctx)
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("error allocating memory: %s\n"), strerror (errno));
+      xfree (arg_list);
+      return err;
+    }
+
+  err = gnupg_create_inbound_pipe (outpipe);
+  if (!err)
+    {
+      err = gnupg_create_inbound_pipe (errpipe);
+      if (err)
+        {
+          close (outpipe[0]);
+          close (outpipe[1]);
+        }
+    }
+  if (err)
+    {
+      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+      xfree (arg_list);
+      xfree (ctx);
+      return err;
+    }
+
+  err = gnupg_spawn_process_fd (pgmname, arg_list,
+                                -1, outpipe[1], errpipe[1], &pid);
+  xfree (arg_list);
+  close (outpipe[1]);
+  close (errpipe[1]);
+  if (err)
+    {
+      close (outpipe[0]);
+      close (errpipe[0]);
+      xfree (ctx);
+      return err;
+    }
+
+  ctx->pid = pid;
+  ctx->printable_pid = (int) pid;
+  ctx->fd = outpipe[0];
+  ctx->log_fd = errpipe[0];
+  ctx->ctrl = ctrl;
+  ctrl->refcount++;
+  ctx->stamp = time (NULL);
+
+  err = ksba_reader_new (reader);
+  if (!err)
+    err = ksba_reader_set_cb (*reader, reader_callback, ctx);
+  if (err)
+    {
+      log_error (_("error initializing reader object: %s\n"),
+                 gpg_strerror (err));
+      destroy_wrapper (ctx);
+      ksba_reader_release (*reader);
+      *reader = NULL;
+      return err;
+    }
+
+  /* Hook the context into our list of running wrappers.  */
+  ctx->reader = *reader;
+  ctx->next = wrapper_list;
+  wrapper_list = ctx;
+  if (opt.verbose)
+    log_info ("ldap wrapper %d started (reader %p)\n",
+              (int)ctx->pid, ctx->reader);
+
+  /* Need to wait for the first byte so we are able to detect an empty
+     output and not let the consumer see an EOF without further error
+     indications.  The CRL loading logic assumes that after return
+     from this function, a failed search (e.g. host not found ) is
+     indicated right away. */
+  {
+    unsigned char c;
+
+    err = read_buffer (*reader, &c, 1);
+    if (err)
+      {
+        ldap_wrapper_release_context (*reader);
+        ksba_reader_release (*reader);
+        *reader = NULL;
+        if (gpg_err_code (err) == GPG_ERR_EOF)
+          return gpg_error (GPG_ERR_NO_DATA);
+        else
+          return err;
+      }
+    ksba_reader_unread (*reader, &c, 1);
+  }
+
+  return 0;
+}
diff --git a/dirmngr/ldap-wrapper.h b/dirmngr/ldap-wrapper.h
new file mode 100644 (file)
index 0000000..f7f5680
--- /dev/null
@@ -0,0 +1,40 @@
+/* ldap-wrapper.h - Interface to an LDAP access wrapper.
+ * Copyright (C) 2010 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LDAP_WRAPPER_H
+#define LDAP_WRAPPER_H
+
+#include <ksba.h>
+
+/* ldap-wrapper.c or ldap-wrapper-ce.c */
+void ldap_wrapper_launch_thread (void);
+void ldap_wrapper_wait_connections (void);
+void ldap_wrapper_release_context (ksba_reader_t reader);
+void ldap_wrapper_connection_cleanup (ctrl_t);
+gpg_error_t ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader,
+                          const char *argv[]);
+
+
+/* dirmngr_ldap.c  */
+#ifndef USE_LDAPWRAPPER
+int ldap_wrapper_main (char **argv, estream_t outstream);
+#endif
+
+
+#endif /*LDAP_WRAPPER_H*/
diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c
new file mode 100644 (file)
index 0000000..478fdfd
--- /dev/null
@@ -0,0 +1,843 @@
+/* ldap.c - LDAP access
+ * Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2010 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 <fcntl.h>
+#include <time.h>
+#include <npth.h>
+
+#include "dirmngr.h"
+#include "exechelp.h"
+#include "crlfetch.h"
+#include "ldapserver.h"
+#include "misc.h"
+#include "ldap-wrapper.h"
+
+
+#define UNENCODED_URL_CHARS "abcdefghijklmnopqrstuvwxyz"   \
+                            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"   \
+                            "01234567890"                  \
+                            "$-_.+!*'(),"
+#define USERCERTIFICATE "userCertificate"
+#define CACERTIFICATE   "caCertificate"
+#define X509CACERT      "x509caCert"
+#define USERSMIMECERTIFICATE "userSMIMECertificate"
+
+
+/* Definition for the context of the cert fetch functions. */
+struct cert_fetch_context_s
+{
+  ksba_reader_t reader;  /* The reader used (shallow copy). */
+  unsigned char *tmpbuf; /* Helper buffer.  */
+  size_t tmpbufsize;     /* Allocated size of tmpbuf.  */
+  int truncated;         /* Flag to indicate a truncated output.  */
+};
+
+
+
+\f
+/* Add HOST and PORT to our list of LDAP servers.  Fixme: We should
+   better use an extra list of servers. */
+static void
+add_server_to_servers (const char *host, int port)
+{
+  ldap_server_t server;
+  ldap_server_t last = NULL;
+  const char *s;
+
+  if (!port)
+    port = 389;
+
+  for (server=opt.ldapservers; server; server = server->next)
+    {
+      if (!strcmp (server->host, host) && server->port == port)
+         return; /* already in list... */
+      last = server;
+    }
+
+  /* We assume that the host names are all supplied by our
+     configuration files and thus are sane.  To keep this assumption
+     we must reject all invalid host names. */
+  for (s=host; *s; s++)
+    if (!strchr ("abcdefghijklmnopqrstuvwxyz"
+                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                 "01234567890.-", *s))
+      {
+        log_error (_("invalid char 0x%02x in host name - not added\n"), *s);
+        return;
+      }
+
+  log_info (_("adding '%s:%d' to the ldap server list\n"), host, port);
+  server = xtrycalloc (1, sizeof *s);
+  if (!server)
+    log_error (_("malloc failed: %s\n"), strerror (errno));
+  else
+    {
+      server->host = xstrdup (host);
+      server->port = port;
+      if (last)
+        last->next = server;
+      else
+        opt.ldapservers = server;
+    }
+}
+
+
+
+
+/* Perform an LDAP query.  Returns an gpg error code or 0 on success.
+   The function returns a new reader object at READER. */
+static gpg_error_t
+run_ldap_wrapper (ctrl_t ctrl,
+                  int ignore_timeout,
+                  int multi_mode,
+                  const char *proxy,
+                  const char *host, int port,
+                  const char *user, const char *pass,
+                  const char *dn, const char *filter, const char *attr,
+                  const char *url,
+                  ksba_reader_t *reader)
+{
+  const char *argv[40];
+  int argc;
+  char portbuf[30], timeoutbuf[30];
+
+
+  *reader = NULL;
+
+  argc = 0;
+  if (pass)  /* Note, that the password most be the first item.  */
+    {
+      argv[argc++] = "--pass";
+      argv[argc++] = pass;
+    }
+  if (opt.verbose)
+    argv[argc++] = "-vv";
+  argv[argc++] = "--log-with-pid";
+  if (multi_mode)
+    argv[argc++] = "--multi";
+  if (opt.ldaptimeout)
+    {
+      sprintf (timeoutbuf, "%u", opt.ldaptimeout);
+      argv[argc++] = "--timeout";
+      argv[argc++] = timeoutbuf;
+      if (ignore_timeout)
+        argv[argc++] = "--only-search-timeout";
+    }
+  if (proxy)
+    {
+      argv[argc++] = "--proxy";
+      argv[argc++] = proxy;
+    }
+  if (host)
+    {
+      argv[argc++] = "--host";
+      argv[argc++] = host;
+    }
+  if (port)
+    {
+      sprintf (portbuf, "%d", port);
+      argv[argc++] = "--port";
+      argv[argc++] = portbuf;
+    }
+  if (user)
+    {
+      argv[argc++] = "--user";
+      argv[argc++] = user;
+    }
+  if (dn)
+    {
+      argv[argc++] = "--dn";
+      argv[argc++] = dn;
+    }
+  if (filter)
+    {
+      argv[argc++] = "--filter";
+      argv[argc++] = filter;
+    }
+  if (attr)
+    {
+      argv[argc++] = "--attr";
+      argv[argc++] = attr;
+    }
+  argv[argc++] = url? url : "ldap://";
+  argv[argc] = NULL;
+
+  return ldap_wrapper (ctrl, reader, argv);
+}
+
+
+
+
+/* Perform a LDAP query using a given URL. On success a new ksba
+   reader is returned.  If HOST or PORT are not 0, they are used to
+   override the values from the URL. */
+gpg_error_t
+url_fetch_ldap (ctrl_t ctrl, const char *url, const char *host, int port,
+                ksba_reader_t *reader)
+{
+  gpg_error_t err;
+
+  err = run_ldap_wrapper (ctrl,
+                          1, /* Ignore explicit timeout because CRLs
+                                might be very large. */
+                          0,
+                          opt.ldap_proxy,
+                          host, port,
+                          NULL, NULL,
+                          NULL, NULL, NULL, url,
+                          reader);
+
+  /* FIXME: This option might be used for DoS attacks.  Because it
+     will enlarge the list of servers to consult without a limit and
+     all LDAP queries w/o a host are will then try each host in
+     turn. */
+  if (!err && opt.add_new_ldapservers && !opt.ldap_proxy)
+    {
+      if (host)
+        add_server_to_servers (host, port);
+      else if (url)
+        {
+          char *tmp = host_and_port_from_url (url, &port);
+          if (tmp)
+            {
+              add_server_to_servers (tmp, port);
+              xfree (tmp);
+            }
+        }
+    }
+
+  /* If the lookup failed and we are not only using the proxy, we try
+     again using our default list of servers.  */
+  if (err && !(opt.ldap_proxy && opt.only_ldap_proxy))
+    {
+      struct ldapserver_iter iter;
+
+      if (DBG_LOOKUP)
+        log_debug ("no hostname in URL or query failed; "
+                   "trying all default hostnames\n");
+
+      for (ldapserver_iter_begin (&iter, ctrl);
+          err && ! ldapserver_iter_end_p (&iter);
+          ldapserver_iter_next (&iter))
+        {
+         ldap_server_t server = iter.server;
+
+          err = run_ldap_wrapper (ctrl,
+                                  0,
+                                  0,
+                                  NULL,
+                                  server->host, server->port,
+                                  NULL, NULL,
+                                  NULL, NULL, NULL, url,
+                                  reader);
+          if (!err)
+            break;
+        }
+    }
+
+  return err;
+}
+
+
+
+/* Perform an LDAP query on all configured servers.  On error the
+   error code of the last try is returned.  */
+gpg_error_t
+attr_fetch_ldap (ctrl_t ctrl,
+                 const char *dn, const char *attr, ksba_reader_t *reader)
+{
+  gpg_error_t err = gpg_error (GPG_ERR_CONFIGURATION);
+  struct ldapserver_iter iter;
+
+  *reader = NULL;
+
+  /* FIXME; we might want to look at the Base SN to try matching
+     servers first. */
+  for (ldapserver_iter_begin (&iter, ctrl); ! ldapserver_iter_end_p (&iter);
+       ldapserver_iter_next (&iter))
+    {
+      ldap_server_t server = iter.server;
+
+      err = run_ldap_wrapper (ctrl,
+                              0,
+                              0,
+                              opt.ldap_proxy,
+                              server->host, server->port,
+                              server->user, server->pass,
+                              dn, "objectClass=*", attr, NULL,
+                              reader);
+      if (!err)
+        break; /* Probably found a result. Ready. */
+    }
+  return err;
+}
+
+\f
+/* Parse PATTERN and return a new strlist to be used for the actual
+   LDAP query.  Bit 0 of the flags field is set if that pattern is
+   actually a base specification.  Caller must release the returned
+   strlist.  NULL is returned on error.
+
+ * Possible patterns:
+ *
+ *   KeyID
+ *   Fingerprint
+ *   OpenPGP userid
+ * x Email address  Indicated by a left angle bracket.
+ *   Exact word match in user id or subj. name
+ * x Subj. DN  indicated bu a leading slash
+ *   Issuer DN
+ *   Serial number + subj. DN
+ * x Substring match indicated by a leading '*; is also the default.
+ */
+
+strlist_t
+parse_one_pattern (const char *pattern)
+{
+  strlist_t result = NULL;
+  char *p;
+
+  switch (*pattern)
+    {
+    case '<':                  /* Email. */
+      {
+        pattern++;
+       result = xmalloc (sizeof *result + 5 + strlen (pattern));
+        result->next = NULL;
+        result->flags = 0;
+       p = stpcpy (stpcpy (result->d, "mail="), pattern);
+       if (p[-1] == '>')
+         *--p = 0;
+        if (!*result->d) /* Error. */
+          {
+            xfree (result);
+            result = NULL;
+          }
+       break;
+      }
+    case '/':                  /* Subject DN. */
+      pattern++;
+      if (*pattern)
+        {
+          result = xmalloc (sizeof *result + strlen (pattern));
+          result->next = NULL;
+          result->flags = 1; /* Base spec. */
+          strcpy (result->d, pattern);
+        }
+      break;
+    case '#':                  /* Issuer DN. */
+      pattern++;
+      if (*pattern == '/')  /* Just issuer DN. */
+        {
+          pattern++;
+       }
+      else  /* Serial number + issuer DN */
+       {
+        }
+      break;
+    case '*':
+      pattern++;
+    default:                   /* Take as substring match. */
+      {
+       const char format[] = "(|(sn=*%s*)(|(cn=*%s*)(mail=*%s*)))";
+
+        if (*pattern)
+          {
+            result = xmalloc (sizeof *result
+                              + strlen (format) + 3 * strlen (pattern));
+            result->next = NULL;
+            result->flags = 0;
+            sprintf (result->d, format, pattern, pattern, pattern);
+          }
+      }
+      break;
+    }
+
+  return result;
+}
+
+/* Take the string STRING and escape it accoring to the URL rules.
+   Retun a newly allocated string. */
+static char *
+escape4url (const char *string)
+{
+  const char *s;
+  char *buf, *p;
+  size_t n;
+
+  if (!string)
+    string = "";
+
+  for (s=string,n=0; *s; s++)
+    if (strchr (UNENCODED_URL_CHARS, *s))
+      n++;
+    else
+      n += 3;
+
+  buf = malloc (n+1);
+  if (!buf)
+    return NULL;
+
+  for (s=string,p=buf; *s; s++)
+    if (strchr (UNENCODED_URL_CHARS, *s))
+      *p++ = *s;
+    else
+      {
+        sprintf (p, "%%%02X", *(const unsigned char *)s);
+        p += 3;
+      }
+  *p = 0;
+
+  return buf;
+}
+
+
+
+/* Create a LDAP URL from DN and FILTER and return it in URL.  We don't
+   need the host and port because this will be specified using the
+   override options. */
+static gpg_error_t
+make_url (char **url, const char *dn, const char *filter)
+{
+  gpg_error_t err;
+  char *u_dn, *u_filter;
+  char const attrs[] = (USERCERTIFICATE ","
+/*                         USERSMIMECERTIFICATE "," */
+                        CACERTIFICATE ","
+                        X509CACERT );
+
+  *url = NULL;
+
+  u_dn = escape4url (dn);
+  if (!u_dn)
+      return gpg_error_from_errno (errno);
+
+  u_filter = escape4url (filter);
+  if (!u_filter)
+    {
+      err = gpg_error_from_errno (errno);
+      xfree (u_dn);
+      return err;
+    }
+  *url = malloc ( 8 + strlen (u_dn)
+                 + 1 + strlen (attrs)
+                 + 5 + strlen (u_filter) + 1 );
+  if (!*url)
+    {
+      err = gpg_error_from_errno (errno);
+      xfree (u_dn);
+      xfree (u_filter);
+      return err;
+    }
+
+  stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (*url, "ldap:///"),
+                                          u_dn),
+                                  "?"),
+                          attrs),
+                  "?sub?"),
+          u_filter);
+  xfree (u_dn);
+  xfree (u_filter);
+  return 0;
+}
+
+
+/* Prepare an LDAP query to return the attribute ATTR for the DN.  All
+   configured default servers are queried until one responds.  This
+   function returns an error code or 0 and a CONTEXT on success. */
+gpg_error_t
+start_default_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context,
+                          const char *dn, const char *attr)
+{
+  gpg_error_t err;
+  struct ldapserver_iter iter;
+
+  *context = xtrycalloc (1, sizeof **context);
+  if (!*context)
+    return gpg_error_from_errno (errno);
+
+  /* FIXME; we might want to look at the Base SN to try matching
+     servers first. */
+  err = gpg_error (GPG_ERR_CONFIGURATION);
+
+  for (ldapserver_iter_begin (&iter, ctrl); ! ldapserver_iter_end_p (&iter);
+       ldapserver_iter_next (&iter))
+    {
+      ldap_server_t server = iter.server;
+
+      err = run_ldap_wrapper (ctrl,
+                              0,
+                              1,
+                              opt.ldap_proxy,
+                              server->host, server->port,
+                              server->user, server->pass,
+                              dn, "objectClass=*", attr, NULL,
+                              &(*context)->reader);
+      if (!err)
+        break; /* Probably found a result. */
+    }
+
+  if (err)
+    {
+      xfree (*context);
+      *context = NULL;
+    }
+  return err;
+}
+
+
+/* Prepare an LDAP query to return certificates maching PATTERNS using
+   the SERVER.  This function returns an error code or 0 and a CONTEXT
+   on success. */
+gpg_error_t
+start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context,
+                       strlist_t patterns, const ldap_server_t server)
+{
+  gpg_error_t err;
+  const char *host;
+  int port;
+  const char *user;
+  const char *pass;
+  const char *base;
+  const char *argv[50];
+  int argc;
+  char portbuf[30], timeoutbuf[30];
+
+
+  *context = NULL;
+  if (server)
+    {
+      host = server->host;
+      port = server->port;
+      user = server->user;
+      pass = server->pass;
+      base = server->base;
+    }
+  else /* Use a default server. */
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  if (!base)
+    base = "";
+
+  argc = 0;
+  if (pass) /* Note: Must be the first item. */
+    {
+      argv[argc++] = "--pass";
+      argv[argc++] = pass;
+    }
+  if (opt.verbose)
+    argv[argc++] = "-vv";
+  argv[argc++] = "--log-with-pid";
+  argv[argc++] = "--multi";
+  if (opt.ldaptimeout)
+    {
+      sprintf (timeoutbuf, "%u", opt.ldaptimeout);
+      argv[argc++] = "--timeout";
+      argv[argc++] = timeoutbuf;
+    }
+  if (opt.ldap_proxy)
+    {
+      argv[argc++] = "--proxy";
+      argv[argc++] = opt.ldap_proxy;
+    }
+  if (host)
+    {
+      argv[argc++] = "--host";
+      argv[argc++] = host;
+    }
+  if (port)
+    {
+      sprintf (portbuf, "%d", port);
+      argv[argc++] = "--port";
+      argv[argc++] = portbuf;
+    }
+  if (user)
+    {
+      argv[argc++] = "--user";
+      argv[argc++] = user;
+    }
+
+
+  for (; patterns; patterns = patterns->next)
+    {
+      strlist_t sl;
+      char *url;
+
+      if (argc >= sizeof argv -1)
+        {
+          /* Too many patterns.  It does not make sense to allow an
+             arbitrary number of patters because the length of the
+             command line is limited anyway.  */
+          /* fixme: cleanup. */
+          return gpg_error (GPG_ERR_RESOURCE_LIMIT);
+        }
+      sl = parse_one_pattern (patterns->d);
+      if (!sl)
+        {
+          log_error (_("start_cert_fetch: invalid pattern '%s'\n"),
+                     patterns->d);
+          /* fixme: cleanup argv.  */
+          return gpg_error (GPG_ERR_INV_USER_ID);
+        }
+      if ((sl->flags & 1))
+        err = make_url (&url, sl->d, "objectClass=*");
+      else
+        err = make_url (&url, base, sl->d);
+      free_strlist (sl);
+      if (err)
+        {
+          /* fixme: cleanup argv. */
+          return err;
+        }
+      argv[argc++] = url;
+    }
+  argv[argc] = NULL;
+
+  *context = xtrycalloc (1, sizeof **context);
+  if (!*context)
+    return gpg_error_from_errno (errno);
+
+  err = ldap_wrapper (ctrl, &(*context)->reader, argv);
+
+  if (err)
+    {
+      xfree (*context);
+      *context = NULL;
+    }
+
+  return err;
+}
+
+
+/* Read a fixed amount of data from READER into BUFFER.  */
+static gpg_error_t
+read_buffer (ksba_reader_t reader, unsigned char *buffer, size_t count)
+{
+  gpg_error_t err;
+  size_t nread;
+
+  while (count)
+    {
+      err = ksba_reader_read (reader, buffer, count, &nread);
+      if (err)
+        return err;
+      buffer += nread;
+      count -= nread;
+    }
+  return 0;
+}
+
+
+/* Fetch the next certificate. Return 0 on success, GPG_ERR_EOF if no
+   (more) certificates are available or any other error
+   code. GPG_ERR_TRUNCATED may be returned to indicate that the result
+   has been truncated. */
+gpg_error_t
+fetch_next_cert_ldap (cert_fetch_context_t context,
+                      unsigned char **value, size_t *valuelen)
+{
+  gpg_error_t err;
+  unsigned char hdr[5];
+  char *p, *pend;
+  int n;
+  int okay = 0;
+  /* int is_cms = 0; */
+
+  *value = NULL;
+  *valuelen = 0;
+
+  err = 0;
+  while (!err)
+    {
+      err = read_buffer (context->reader, hdr, 5);
+      if (err)
+        break;
+      n = (hdr[1] << 24)|(hdr[2]<<16)|(hdr[3]<<8)|hdr[4];
+      if (*hdr == 'V' && okay)
+        {
+#if 0  /* That code is not yet ready.  */
+
+          if (is_cms)
+            {
+              /* The certificate needs to be parsed from CMS data. */
+              ksba_cms_t cms;
+              ksba_stop_reason_t stopreason;
+              int i;
+
+              err = ksba_cms_new (&cms);
+              if (err)
+                goto leave;
+              err = ksba_cms_set_reader_writer (cms, context->reader, NULL);
+              if (err)
+                {
+                  log_error ("ksba_cms_set_reader_writer failed: %s\n",
+                             gpg_strerror (err));
+                  goto leave;
+                }
+
+              do
+                {
+                  err = ksba_cms_parse (cms, &stopreason);
+                  if (err)
+                    {
+                      log_error ("ksba_cms_parse failed: %s\n",
+                                 gpg_strerror (err));
+                      goto leave;
+                    }
+
+                  if (stopreason == KSBA_SR_BEGIN_DATA)
+                    log_error ("userSMIMECertificate is 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
+#endif
+            {
+              *value = xtrymalloc (n);
+              if (!*value)
+                return gpg_error_from_errno (errno);
+              *valuelen = n;
+              err = read_buffer (context->reader, *value, n);
+              break; /* Ready or error.  */
+            }
+        }
+      else if (!n && *hdr == 'A')
+        okay = 0;
+      else if (n)
+        {
+          if (n > context->tmpbufsize)
+            {
+              xfree (context->tmpbuf);
+              context->tmpbufsize = 0;
+              context->tmpbuf = xtrymalloc (n+1);
+              if (!context->tmpbuf)
+                return gpg_error_from_errno (errno);
+              context->tmpbufsize = n;
+            }
+          err = read_buffer (context->reader, context->tmpbuf, n);
+          if (err)
+            break;
+          if (*hdr == 'A')
+            {
+              p = context->tmpbuf;
+              p[n] = 0; /*(we allocated one extra byte for this.)*/
+              /* fixme: is_cms = 0; */
+              if ( (pend = strchr (p, ';')) )
+                *pend = 0; /* Strip off the extension. */
+              if (!ascii_strcasecmp (p, USERCERTIFICATE))
+                {
+                  if (DBG_LOOKUP)
+                    log_debug ("fetch_next_cert_ldap: got attribute '%s'\n",
+                               USERCERTIFICATE);
+                  okay = 1;
+                }
+              else if (!ascii_strcasecmp (p, CACERTIFICATE))
+                {
+                  if (DBG_LOOKUP)
+                    log_debug ("fetch_next_cert_ldap: got attribute '%s'\n",
+                               CACERTIFICATE);
+                  okay = 1;
+                }
+              else if (!ascii_strcasecmp (p, X509CACERT))
+                {
+                  if (DBG_LOOKUP)
+                    log_debug ("fetch_next_cert_ldap: got attribute '%s'\n",
+                               CACERTIFICATE);
+                  okay = 1;
+                }
+/*               else if (!ascii_strcasecmp (p, USERSMIMECERTIFICATE)) */
+/*                 { */
+/*                   if (DBG_LOOKUP) */
+/*                     log_debug ("fetch_next_cert_ldap: got attribute '%s'\n", */
+/*                                USERSMIMECERTIFICATE); */
+/*                   okay = 1; */
+/*                   is_cms = 1; */
+/*                 } */
+              else
+                {
+                  if (DBG_LOOKUP)
+                    log_debug ("fetch_next_cert_ldap: got attribute '%s'"
+                               " -  ignored\n", p);
+                  okay = 0;
+                }
+            }
+          else if (*hdr == 'E')
+            {
+              p = context->tmpbuf;
+              p[n] = 0; /*(we allocated one extra byte for this.)*/
+              if (!strcmp (p, "truncated"))
+                {
+                  context->truncated = 1;
+                  log_info (_("ldap_search hit the size limit of"
+                              " the server\n"));
+                }
+            }
+        }
+    }
+
+  if (err)
+    {
+      xfree (*value);
+      *value = NULL;
+      *valuelen = 0;
+      if (gpg_err_code (err) == GPG_ERR_EOF && context->truncated)
+        {
+          context->truncated = 0; /* So that the next call would return EOF. */
+          err = gpg_error (GPG_ERR_TRUNCATED);
+        }
+    }
+
+  return err;
+}
+
+
+void
+end_cert_fetch_ldap (cert_fetch_context_t context)
+{
+  if (context)
+    {
+      ksba_reader_t reader = context->reader;
+
+      xfree (context->tmpbuf);
+      xfree (context);
+      ldap_wrapper_release_context (reader);
+      ksba_reader_release (reader);
+    }
+}
diff --git a/dirmngr/ldapserver.c b/dirmngr/ldapserver.c
new file mode 100644 (file)
index 0000000..20a574c
--- /dev/null
@@ -0,0 +1,131 @@
+/* dirmngr.c - LDAP access
+   Copyright (C) 2008 g10 Code GmbH
+
+   This file is part of DirMngr.
+
+   DirMngr 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.
+
+   DirMngr is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "dirmngr.h"
+#include "ldapserver.h"
+
+\f
+/* Release the list of SERVERS.  As usual it is okay to call this
+   function with SERVERS passed as NULL.  */
+void
+ldapserver_list_free (ldap_server_t servers)
+{
+  while (servers)
+    {
+      ldap_server_t tmp = servers->next;
+      xfree (servers->host);
+      xfree (servers->user);
+      if (servers->pass)
+        memset (servers->pass, 0, strlen (servers->pass));
+      xfree (servers->pass);
+      xfree (servers->base);
+      xfree (servers);
+      servers = tmp;
+    }
+}
+
+
+/* Parse a single LDAP server configuration line.  Returns the server
+   or NULL in case of errors.  The configuration lineis assumed to be
+   colon seprated with these fields:
+
+   1. field: Hostname
+   2. field: Portnumber
+   3. field: Username
+   4. field: Password
+   5. field: Base DN
+
+   FILENAME and LINENO are used for diagnostic purposes only.
+*/
+ldap_server_t
+ldapserver_parse_one (char *line,
+                     const char *filename, unsigned int lineno)
+{
+  char *p;
+  char *endp;
+  ldap_server_t server;
+  int fieldno;
+  int fail = 0;
+
+  /* Parse the colon separated fields.  */
+  server = xcalloc (1, sizeof *server);
+  for (fieldno = 1, p = line; p; p = endp, fieldno++ )
+    {
+      endp = strchr (p, ':');
+      if (endp)
+       *endp++ = '\0';
+      trim_spaces (p);
+      switch (fieldno)
+       {
+       case 1:
+         if (*p)
+           server->host = xstrdup (p);
+         else
+           {
+             log_error (_("%s:%u: no hostname given\n"),
+                        filename, lineno);
+             fail = 1;
+           }
+         break;
+
+       case 2:
+         if (*p)
+           server->port = atoi (p);
+         break;
+
+       case 3:
+         if (*p)
+           server->user = xstrdup (p);
+         break;
+
+       case 4:
+         if (*p && !server->user)
+           {
+             log_error (_("%s:%u: password given without user\n"),
+                        filename, lineno);
+             fail = 1;
+           }
+         else if (*p)
+           server->pass = xstrdup (p);
+         break;
+
+       case 5:
+         if (*p)
+           server->base = xstrdup (p);
+         break;
+
+       default:
+         /* (We silently ignore extra fields.) */
+         break;
+       }
+    }
+
+  if (fail)
+    {
+      log_info (_("%s:%u: skipping this line\n"), filename, lineno);
+      ldapserver_list_free (server);
+    }
+
+  return server;
+}
diff --git a/dirmngr/ldapserver.h b/dirmngr/ldapserver.h
new file mode 100644 (file)
index 0000000..8056e67
--- /dev/null
@@ -0,0 +1,90 @@
+/* ldapserver.h
+   Copyright (C) 2008 g10 Code GmbH
+
+   This file is part of DirMngr.
+
+   DirMngr 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.
+
+   DirMngr 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef LDAPSERVER_H
+#define LDAPSERVER_H
+
+#include "dirmngr.h"
+
+/* Release the list of SERVERS.  As usual it is okay to call this
+   function with SERVERS passed as NULL.  */
+void ldapserver_list_free (ldap_server_t servers);
+
+
+/* Parse a single LDAP server configuration line.  Returns the server
+   or NULL in case of errors.  The configuration line is assumed to be
+   colon separated with these fields:
+
+   1. field: Hostname
+   2. field: Portnumber
+   3. field: Username
+   4. field: Password
+   5. field: Base DN
+
+   FILENAME and LINENO are used for diagnostic purposes only.
+*/
+ldap_server_t ldapserver_parse_one (char *line,
+                                   const char *filename, unsigned int lineno);
+
+\f
+/* Iterate over all servers.  */
+
+struct ldapserver_iter
+{
+  ctrl_t ctrl;
+  enum { LDAPSERVER_SESSION, LDAPSERVER_OPT } group;
+  ldap_server_t server;
+};
+
+
+static inline void
+ldapserver_iter_next (struct ldapserver_iter *iter)
+{
+  if (iter->server)
+    iter->server = iter->server->next;
+
+  if (! iter->server)
+    {
+      if (iter->group == LDAPSERVER_SESSION)
+       {
+         iter->group = LDAPSERVER_OPT;
+         iter->server = opt.ldapservers;
+       }
+    }
+}
+
+
+static inline int
+ldapserver_iter_end_p (struct ldapserver_iter *iter)
+{
+  return (iter->group == LDAPSERVER_OPT && iter->server == NULL);
+}
+
+
+static inline void
+ldapserver_iter_begin (struct ldapserver_iter *iter, ctrl_t ctrl)
+{
+  iter->ctrl = ctrl;
+  iter->group = LDAPSERVER_SESSION;
+  iter->server = get_ldapservers_from_ctrl (ctrl);
+
+  while (iter->server == NULL && ! ldapserver_iter_end_p (iter))
+    ldapserver_iter_next (iter);
+}
+
+#endif /* LDAPSERVER_H */
diff --git a/dirmngr/misc.c b/dirmngr/misc.c
new file mode 100644 (file)
index 0000000..25652a2
--- /dev/null
@@ -0,0 +1,564 @@
+/* misc.c - miscellaneous
+ *     Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ *      Copyright (C) 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 <time.h>
+#include <errno.h>
+
+#include "dirmngr.h"
+#include "util.h"
+#include "misc.h"
+
+
+/* Convert the hex encoded STRING back into binary and store the
+   result into the provided buffer RESULT.  The actual size of that
+   buffer will be returned.  The caller should provide RESULT of at
+   least strlen(STRING)/2 bytes.  There is no error detection, the
+   parsing stops at the first non hex character.  With RESULT given as
+   NULL, the fucntion does only return the size of the buffer which
+   would be needed.  */
+size_t
+unhexify (unsigned char *result, const char *string)
+{
+  const char *s;
+  size_t n;
+
+  for (s=string,n=0; hexdigitp (s) && hexdigitp(s+1); s += 2)
+    {
+      if (result)
+        result[n] = xtoi_2 (s);
+      n++;
+    }
+  return n;
+}
+
+
+char*
+hashify_data( const char* data, size_t len )
+{
+  unsigned char buf[20];
+  gcry_md_hash_buffer (GCRY_MD_SHA1, buf, data, len);
+  return hexify_data( buf, 20 );
+}
+
+char*
+hexify_data( const unsigned char* data, size_t len )
+{
+  int i;
+  char* result = xmalloc( sizeof( char ) * (2*len+1));
+
+  for( i = 0; i < 2*len; i+=2 )
+    sprintf( result+i, "%02X", *data++);
+  return result;
+}
+
+char *
+serial_hex (ksba_sexp_t serial )
+{
+  unsigned char* p = serial;
+  char *endp;
+  unsigned long n;
+  char *certid;
+
+  if (!p)
+    return NULL;
+  else {
+    p++; /* ignore initial '(' */
+    n = strtoul (p, (char**)&endp, 10);
+    p = endp;
+    if (*p!=':')
+      return NULL;
+    else {
+      int i = 0;
+      certid = xmalloc( sizeof( char )*(2*n + 1 ) );
+      for (p++; n; n--, p++) {
+       sprintf ( certid+i , "%02X", *p);
+       i += 2;
+      }
+    }
+  }
+  return certid;
+}
+
+
+/* Take an S-Expression encoded blob and return a pointer to the
+   actual data as well as its length.  Return NULL for an invalid
+   S-Expression.*/
+const unsigned char *
+serial_to_buffer (const ksba_sexp_t serial, size_t *length)
+{
+  unsigned char *p = serial;
+  char *endp;
+  unsigned long n;
+
+  if (!p || *p != '(')
+    return NULL;
+  p++;
+  n = strtoul (p, &endp, 10);
+  p = endp;
+  if (*p != ':')
+    return NULL;
+  p++;
+  *length = n;
+  return p;
+}
+
+
+/* Do an in-place percent unescaping of STRING. Returns STRING. Noet
+   that this function does not do a '+'-to-space unescaping.*/
+char *
+unpercent_string (char *string)
+{
+  char *s = string;
+  char *d = string;
+
+  while (*s)
+    {
+      if (*s == '%' && s[1] && s[2])
+        {
+          s++;
+          *d++ = xtoi_2 ( s);
+          s += 2;
+        }
+      else
+        *d++ = *s++;
+    }
+  *d = 0;
+  return string;
+}
+
+/* Convert a canonical encoded S-expression in CANON into the GCRY
+   type. */
+gpg_error_t
+canon_sexp_to_gcry (const unsigned char *canon, gcry_sexp_t *r_sexp)
+{
+  gpg_error_t err;
+  size_t n;
+  gcry_sexp_t sexp;
+
+  *r_sexp = NULL;
+  n = gcry_sexp_canon_len (canon, 0, NULL, NULL);
+  if (!n)
+    {
+      log_error (_("invalid canonical S-expression found\n"));
+      err = gpg_error (GPG_ERR_INV_SEXP);
+    }
+  else if ((err = gcry_sexp_sscan (&sexp, NULL, canon, n)))
+    log_error (_("converting S-expression failed: %s\n"), gcry_strerror (err));
+  else
+    *r_sexp = sexp;
+  return err;
+}
+
+
+/* Return an allocated buffer with the formatted fingerprint as one
+   large hexnumber */
+char *
+get_fingerprint_hexstring (ksba_cert_t cert)
+{
+  unsigned char digest[20];
+  gcry_md_hd_t md;
+  int rc;
+  char *buf;
+  int i;
+
+  rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+  if (rc)
+    log_fatal (_("gcry_md_open failed: %s\n"), gpg_strerror (rc));
+
+  rc = ksba_cert_hash (cert, 0, HASH_FNC, md);
+  if (rc)
+    {
+      log_error (_("oops: ksba_cert_hash failed: %s\n"), gpg_strerror (rc));
+      memset (digest, 0xff, 20); /* Use a dummy value. */
+    }
+  else
+    {
+      gcry_md_final (md);
+      memcpy (digest, gcry_md_read (md, GCRY_MD_SHA1), 20);
+    }
+  gcry_md_close (md);
+  buf = xmalloc (41);
+  *buf = 0;
+  for (i=0; i < 20; i++ )
+    sprintf (buf+strlen(buf), "%02X", digest[i]);
+  return buf;
+}
+
+/* Return an allocated buffer with the formatted fingerprint as one
+   large hexnumber.  This version inserts the usual colons. */
+char *
+get_fingerprint_hexstring_colon (ksba_cert_t cert)
+{
+  unsigned char digest[20];
+  gcry_md_hd_t md;
+  int rc;
+  char *buf;
+  int i;
+
+  rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+  if (rc)
+    log_fatal (_("gcry_md_open failed: %s\n"), gpg_strerror (rc));
+
+  rc = ksba_cert_hash (cert, 0, HASH_FNC, md);
+  if (rc)
+    {
+      log_error (_("oops: ksba_cert_hash failed: %s\n"), gpg_strerror (rc));
+      memset (digest, 0xff, 20); /* Use a dummy value. */
+    }
+  else
+    {
+      gcry_md_final (md);
+      memcpy (digest, gcry_md_read (md, GCRY_MD_SHA1), 20);
+    }
+  gcry_md_close (md);
+  buf = xmalloc (61);
+  *buf = 0;
+  for (i=0; i < 20; i++ )
+    sprintf (buf+strlen(buf), "%02X:", digest[i]);
+  buf[strlen(buf)-1] = 0; /* Remove railing colon. */
+  return buf;
+}
+
+
+/* Dump the serial number SERIALNO to the log stream.  */
+void
+dump_serial (ksba_sexp_t serialno)
+{
+  char *p;
+
+  p = serial_hex (serialno);
+  log_printf ("%s", p?p:"?");
+  xfree (p);
+}
+
+
+/* Dump STRING to the log file but choose the best readable
+   format.  */
+void
+dump_string (const char *string)
+{
+
+  if (!string)
+    log_printf ("[error]");
+  else
+    {
+      const unsigned char *s;
+
+      for (s=string; *s; s++)
+        {
+          if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0))
+            break;
+        }
+      if (!*s && *string != '[')
+        log_printf ("%s", string);
+      else
+        {
+          log_printf ( "[ ");
+          log_printhex (NULL, string, strlen (string));
+          log_printf ( " ]");
+        }
+    }
+}
+
+/* Dump an KSBA cert object to the log stream. Prefix the output with
+   TEXT.  This is used for debugging. */
+void
+dump_cert (const char *text, ksba_cert_t cert)
+{
+  ksba_sexp_t sexp;
+  char *p;
+  ksba_isotime_t t;
+
+  log_debug ("BEGIN Certificate '%s':\n", text? text:"");
+  if (cert)
+    {
+      sexp = ksba_cert_get_serial (cert);
+      p = serial_hex (sexp);
+      log_debug ("     serial: %s\n", p?p:"?");
+      xfree (p);
+      ksba_free (sexp);
+
+      ksba_cert_get_validity (cert, 0, t);
+      log_debug ("  notBefore: ");
+      dump_isotime (t);
+      log_printf ("\n");
+      ksba_cert_get_validity (cert, 1, t);
+      log_debug ("   notAfter: ");
+      dump_isotime (t);
+      log_printf ("\n");
+
+      p = ksba_cert_get_issuer (cert, 0);
+      log_debug ("     issuer: ");
+      dump_string (p);
+      ksba_free (p);
+      log_printf ("\n");
+
+      p = ksba_cert_get_subject (cert, 0);
+      log_debug ("    subject: ");
+      dump_string (p);
+      ksba_free (p);
+      log_printf ("\n");
+
+      log_debug ("  hash algo: %s\n", ksba_cert_get_digest_algo (cert));
+
+      p = get_fingerprint_hexstring (cert);
+      log_debug ("  SHA1 fingerprint: %s\n", p);
+      xfree (p);
+    }
+  log_debug ("END Certificate\n");
+}
+
+
+
+/* Log the certificate's name in "#SN/ISSUERDN" format along with
+   TEXT. */
+void
+cert_log_name (const char *text, ksba_cert_t cert)
+{
+  log_info ("%s", text? text:"certificate" );
+  if (cert)
+    {
+      ksba_sexp_t sn;
+      char *p;
+
+      p = ksba_cert_get_issuer (cert, 0);
+      sn = ksba_cert_get_serial (cert);
+      if (p && sn)
+        {
+          log_printf (" #");
+          dump_serial (sn);
+          log_printf ("/");
+          dump_string (p);
+        }
+      else
+        log_printf (" [invalid]");
+      ksba_free (sn);
+      xfree (p);
+    }
+  log_printf ("\n");
+}
+
+
+/* Log the certificate's subject DN along with TEXT. */
+void
+cert_log_subject (const char *text, ksba_cert_t cert)
+{
+  log_info ("%s", text? text:"subject" );
+  if (cert)
+    {
+      char *p;
+
+      p = ksba_cert_get_subject (cert, 0);
+      if (p)
+        {
+          log_printf (" /");
+          dump_string (p);
+          xfree (p);
+        }
+      else
+        log_printf (" [invalid]");
+    }
+  log_printf ("\n");
+}
+
+
+/* Callback to print infos about the TLS certificates.  */
+void
+cert_log_cb (http_session_t sess, gpg_error_t err,
+             const char *hostname, const void **certs, size_t *certlens)
+{
+  ksba_cert_t cert;
+  size_t n;
+
+  (void)sess;
+
+  if (!err)
+    return; /* No error - no need to log anything  */
+
+  log_debug ("expected hostname: %s\n", hostname);
+  for (n=0; certs[n]; n++)
+    {
+      err = ksba_cert_new (&cert);
+      if (!err)
+        err = ksba_cert_init_from_mem (cert, certs[n], certlens[n]);
+      if (err)
+        log_error ("error parsing cert for logging: %s\n", gpg_strerror (err));
+      else
+        {
+          char textbuf[20];
+          snprintf (textbuf, sizeof textbuf, "server[%u]", (unsigned int)n);
+          dump_cert (textbuf, cert);
+        }
+
+      ksba_cert_release (cert);
+    }
+}
+
+
+/****************
+ * Remove all %xx escapes; this is done inplace.
+ * Returns: New length of the string.
+ */
+static int
+remove_percent_escapes (unsigned char *string)
+{
+  int n = 0;
+  unsigned char *p, *s;
+
+  for (p = s = string; *s; s++)
+    {
+      if (*s == '%')
+        {
+          if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
+            {
+              s++;
+              *p = xtoi_2 (s);
+              s++;
+              p++;
+              n++;
+            }
+          else
+            {
+              *p++ = *s++;
+              if (*s)
+                *p++ = *s++;
+              if (*s)
+                *p++ = *s++;
+              if (*s)
+                *p = 0;
+              return -1;   /* Bad URI. */
+            }
+        }
+      else
+        {
+          *p++ = *s;
+          n++;
+        }
+    }
+  *p = 0;  /* Always keep a string terminator. */
+  return n;
+}
+
+
+/* Return the host name and the port (0 if none was given) from the
+   URL.  Return NULL on error or if host is not included in the
+   URL.  */
+char *
+host_and_port_from_url (const char *url, int *port)
+{
+  const char *s, *s2;
+  char *buf, *p;
+  int n;
+
+  s = url;
+
+  *port = 0;
+
+  /* Find the scheme */
+  if ( !(s2 = strchr (s, ':')) || s2 == s )
+    return NULL;  /* No scheme given. */
+  s = s2+1;
+
+  /* Find the hostname */
+  if (*s != '/')
+    return NULL; /* Does not start with a slash. */
+
+  s++;
+  if (*s != '/')
+    return NULL; /* No host name.  */
+  s++;
+
+  buf = xtrystrdup (s);
+  if (!buf)
+    {
+      log_error (_("malloc failed: %s\n"), strerror (errno));
+      return NULL;
+    }
+  if ((p = strchr (buf, '/')))
+    *p++ = 0;
+  strlwr (buf);
+  if ((p = strchr (p, ':')))
+    {
+      *p++ = 0;
+      *port = atoi (p);
+    }
+
+  /* Remove quotes and make sure that no Nul has been encoded. */
+  if ((n = remove_percent_escapes (buf)) < 0
+      || n != strlen (buf) )
+    {
+      log_error (_("bad URL encoding detected\n"));
+      xfree (buf);
+      return NULL;
+    }
+
+  return buf;
+}
+
+
+/* A KSBA reader callback to read from an estream.  */
+static int
+my_estream_ksba_reader_cb (void *cb_value, char *buffer, size_t count,
+                           size_t *r_nread)
+{
+  estream_t fp = cb_value;
+
+  if (!fp)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!buffer && !count && !r_nread)
+    {
+      es_rewind (fp);
+      return 0;
+    }
+
+  *r_nread = es_fread (buffer, 1, count, fp);
+  if (!*r_nread)
+    return -1; /* EOF or error.  */
+  return 0; /* Success.  */
+}
+
+
+/* Create a KSBA reader object and connect it to the estream FP.  */
+gpg_error_t
+create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp)
+{
+  gpg_error_t err;
+  ksba_reader_t reader;
+
+  *r_reader = NULL;
+  err = ksba_reader_new (&reader);
+  if (!err)
+    err = ksba_reader_set_cb (reader, my_estream_ksba_reader_cb, fp);
+  if (err)
+    {
+      log_error (_("error initializing reader object: %s\n"),
+                 gpg_strerror (err));
+      ksba_reader_release (reader);
+      return err;
+    }
+  *r_reader = reader;
+  return 0;
+}
diff --git a/dirmngr/misc.h b/dirmngr/misc.h
new file mode 100644 (file)
index 0000000..2dc2985
--- /dev/null
@@ -0,0 +1,85 @@
+/* misc.h - miscellaneous
+ *      Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 MISC_H
+#define MISC_H
+
+/* Convert hex encoded string back to binary. */
+size_t unhexify (unsigned char *result, const char *string);
+
+/* Returns SHA1 hash of the data. */
+char* hashify_data( const char* data, size_t len );
+
+/* Returns data as a hex string. */
+char* hexify_data( const unsigned char* data, size_t len );
+
+/* Returns the serial number as a hex string.  */
+char* serial_hex ( ksba_sexp_t serial );
+
+/* Take an S-Expression encoded blob and return a pointer to the
+   actual data as well as its length. */
+const unsigned char *serial_to_buffer (const ksba_sexp_t serial,
+                                       size_t *length);
+
+/* Do an in-place percent unescaping of STRING. Returns STRING. */
+char *unpercent_string (char *string);
+
+gpg_error_t canon_sexp_to_gcry (const unsigned char *canon,
+                                gcry_sexp_t *r_sexp);
+
+/* Return an allocated hex-string with the SHA-1 fingerprint of
+   CERT. */
+char *get_fingerprint_hexstring (ksba_cert_t cert);
+/* Return an allocated hex-string with the SHA-1 fingerprint of
+   CERT.  This version inserts the usual colons. */
+char *get_fingerprint_hexstring_colon (ksba_cert_t cert);
+
+/* Log CERT in short format with s/n and issuer DN prefixed by TEXT.  */
+void cert_log_name (const char *text, ksba_cert_t cert);
+
+/* Log CERT in short format with the subject DN prefixed by TEXT.  */
+void cert_log_subject (const char *text, ksba_cert_t cert);
+
+/* Dump the serial number SERIALNO to the log stream.  */
+void dump_serial (ksba_sexp_t serialno);
+
+/* Dump STRING to the log file but choose the best readable
+   format.  */
+void dump_string (const char *string);
+
+/* Dump an KSBA cert object to the log stream. Prefix the output with
+   TEXT.  This is used for debugging. */
+void dump_cert (const char *text, ksba_cert_t cert);
+
+/* Callback to print infos about the TLS certificates.  */
+void cert_log_cb (http_session_t sess, gpg_error_t err,
+                  const char *hostname, const void **certs, size_t *certlens);
+
+/* Return the host name and the port (0 if none was given) from the
+   URL.  Return NULL on error or if host is not included in the
+   URL.  */
+char *host_and_port_from_url (const char *url, int *port);
+
+/* Create a KSBA reader object and connect it to the estream FP.  */
+gpg_error_t create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp);
+
+
+
+#endif /* MISC_H */
diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
new file mode 100644 (file)
index 0000000..f8c437d
--- /dev/null
@@ -0,0 +1,796 @@
+/* ocsp.c - OCSP management
+ *      Copyright (C) 2004, 2007 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 <errno.h>
+#include <assert.h>
+
+#include "dirmngr.h"
+#include "misc.h"
+#include "http.h"
+#include "validate.h"
+#include "certcache.h"
+#include "ocsp.h"
+
+/* The maximum size we allow as a response from an OCSP reponder. */
+#define MAX_RESPONSE_SIZE 65536
+
+
+static const char oidstr_ocsp[] = "1.3.6.1.5.5.7.48.1";
+
+
+/* Telesec attribute used to implement a positive confirmation.
+
+   CertHash ::= SEQUENCE {
+      HashAlgorithm    AlgorithmIdentifier,
+      certificateHash OCTET STRING }
+ */
+static const char oidstr_certHash[] = "1.3.36.8.3.13";
+
+
+
+
+/* Read from FP and return a newly allocated buffer in R_BUFFER with the
+   entire data read from FP. */
+static gpg_error_t
+read_response (estream_t fp, unsigned char **r_buffer, size_t *r_buflen)
+{
+  gpg_error_t err;
+  unsigned char *buffer;
+  size_t bufsize, nbytes;
+
+  *r_buffer = NULL;
+  *r_buflen = 0;
+
+  bufsize = 4096;
+  buffer = xtrymalloc (bufsize);
+  if (!buffer)
+    return gpg_error_from_errno (errno);
+
+  nbytes = 0;
+  for (;;)
+    {
+      unsigned char *tmp;
+      size_t nread = 0;
+
+      assert (nbytes < bufsize);
+      nread = es_fread (buffer+nbytes, 1, bufsize-nbytes, fp);
+      if (nread < bufsize-nbytes && es_ferror (fp))
+        {
+          err = gpg_error_from_errno (errno);
+          log_error (_("error reading from responder: %s\n"),
+                     strerror (errno));
+          xfree (buffer);
+          return err;
+        }
+      if ( !(nread == bufsize-nbytes && !es_feof (fp)))
+        { /* Response succesfully received. */
+          nbytes += nread;
+          *r_buffer = buffer;
+          *r_buflen = nbytes;
+          return 0;
+        }
+
+      nbytes += nread;
+
+      /* Need to enlarge the buffer. */
+      if (bufsize >= MAX_RESPONSE_SIZE)
+        {
+          log_error (_("response from server too large; limit is %d bytes\n"),
+                     MAX_RESPONSE_SIZE);
+          xfree (buffer);
+          return gpg_error (GPG_ERR_TOO_LARGE);
+        }
+
+      bufsize += 4096;
+      tmp = xtryrealloc (buffer, bufsize);
+      if (!tmp)
+        {
+          err = gpg_error_from_errno (errno);
+          xfree (buffer);
+          return err;
+        }
+      buffer = tmp;
+    }
+}
+
+
+/* Construct an OCSP request, send it to the configured OCSP responder
+   and parse the response. On success the OCSP context may be used to
+   further process the reponse. */
+static gpg_error_t
+do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
+                 const char *url, ksba_cert_t cert, ksba_cert_t issuer_cert)
+{
+  gpg_error_t err;
+  unsigned char *request, *response;
+  size_t requestlen, responselen;
+  http_t http;
+  ksba_ocsp_response_status_t response_status;
+  const char *t;
+  int redirects_left = 2;
+  char *free_this = NULL;
+
+  (void)ctrl;
+
+  if (opt.disable_http)
+    {
+      log_error (_("OCSP request not possible due to disabled HTTP\n"));
+      return gpg_error (GPG_ERR_NOT_SUPPORTED);
+    }
+
+  err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
+  if (err)
+    {
+      log_error (_("error setting OCSP target: %s\n"), gpg_strerror (err));
+      return err;
+    }
+
+  {
+    size_t n;
+    unsigned char nonce[32];
+
+    n = ksba_ocsp_set_nonce (ocsp, NULL, 0);
+    if (n > sizeof nonce)
+      n = sizeof nonce;
+    gcry_create_nonce (nonce, n);
+    ksba_ocsp_set_nonce (ocsp, nonce, n);
+  }
+
+  err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
+  if (err)
+    {
+      log_error (_("error building OCSP request: %s\n"), gpg_strerror (err));
+      return err;
+    }
+
+ once_more:
+  err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
+                   (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0),
+                   opt.http_proxy, NULL, NULL, NULL);
+  if (err)
+    {
+      log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err));
+      xfree (free_this);
+      return err;
+    }
+
+  es_fprintf (http_get_write_ptr (http),
+             "Content-Type: application/ocsp-request\r\n"
+             "Content-Length: %lu\r\n",
+             (unsigned long)requestlen );
+  http_start_data (http);
+  if (es_fwrite (request, requestlen, 1, http_get_write_ptr (http)) != 1)
+    {
+      err = gpg_error_from_errno (errno);
+      log_error ("error sending request to '%s': %s\n", url, strerror (errno));
+      http_close (http, 0);
+      xfree (request);
+      xfree (free_this);
+      return err;
+    }
+  xfree (request);
+  request = NULL;
+
+  err = http_wait_response (http);
+  if (err || http_get_status_code (http) != 200)
+    {
+      if (err)
+        log_error (_("error reading HTTP response for '%s': %s\n"),
+                   url, gpg_strerror (err));
+      else
+        {
+          switch (http_get_status_code (http))
+            {
+            case 301:
+            case 302:
+              {
+                const char *s = http_get_header (http, "Location");
+
+                log_info (_("URL '%s' redirected to '%s' (%u)\n"),
+                          url, s?s:"[none]", http_get_status_code (http));
+                if (s && *s && redirects_left-- )
+                  {
+                    xfree (free_this); url = NULL;
+                    free_this = xtrystrdup (s);
+                    if (!free_this)
+                      err = gpg_error_from_errno (errno);
+                    else
+                      {
+                        url = free_this;
+                        http_close (http, 0);
+                        goto once_more;
+                      }
+                  }
+                else
+                  err = gpg_error (GPG_ERR_NO_DATA);
+                log_error (_("too many redirections\n"));
+              }
+              break;
+
+            default:
+              log_error (_("error accessing '%s': http status %u\n"),
+                         url, http_get_status_code (http));
+              err = gpg_error (GPG_ERR_NO_DATA);
+              break;
+            }
+        }
+      http_close (http, 0);
+      xfree (free_this);
+      return err;
+    }
+
+  err = read_response (http_get_read_ptr (http), &response, &responselen);
+  http_close (http, 0);
+  if (err)
+    {
+      log_error (_("error reading HTTP response for '%s': %s\n"),
+                 url, gpg_strerror (err));
+      xfree (free_this);
+      return err;
+    }
+
+  err = ksba_ocsp_parse_response (ocsp, response, responselen,
+                                  &response_status);
+  if (err)
+    {
+      log_error (_("error parsing OCSP response for '%s': %s\n"),
+                 url, gpg_strerror (err));
+      xfree (response);
+      xfree (free_this);
+      return err;
+    }
+
+  switch (response_status)
+    {
+    case KSBA_OCSP_RSPSTATUS_SUCCESS:      t = "success"; break;
+    case KSBA_OCSP_RSPSTATUS_MALFORMED:    t = "malformed"; break;
+    case KSBA_OCSP_RSPSTATUS_INTERNAL:     t = "internal error"; break;
+    case KSBA_OCSP_RSPSTATUS_TRYLATER:     t = "try later"; break;
+    case KSBA_OCSP_RSPSTATUS_SIGREQUIRED:  t = "must sign request"; break;
+    case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;
+    case KSBA_OCSP_RSPSTATUS_REPLAYED:     t = "replay detected"; break;
+    case KSBA_OCSP_RSPSTATUS_OTHER:        t = "other (unknown)"; break;
+    case KSBA_OCSP_RSPSTATUS_NONE:         t = "no status"; break;
+    default:                               t = "[unknown status]"; break;
+    }
+  if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
+    {
+      if (opt.verbose)
+        log_info (_("OCSP responder at '%s' status: %s\n"), url, t);
+
+      err = ksba_ocsp_hash_response (ocsp, response, responselen,
+                                     HASH_FNC, md);
+      if (err)
+        log_error (_("hashing the OCSP response for '%s' failed: %s\n"),
+                   url, gpg_strerror (err));
+    }
+  else
+    {
+      log_error (_("OCSP responder at '%s' status: %s\n"), url, t);
+      err = gpg_error (GPG_ERR_GENERAL);
+    }
+
+  xfree (response);
+  xfree (free_this);
+  return err;
+}
+
+
+/* Validate that CERT is indeed valid to sign an OCSP response. If
+   SIGNER_FPR_LIST is not NULL we simply check that CERT matches one
+   of the fingerprints in this list. */
+static gpg_error_t
+validate_responder_cert (ctrl_t ctrl, ksba_cert_t cert,
+                         fingerprint_list_t signer_fpr_list)
+{
+  gpg_error_t err;
+  char *fpr;
+
+  if (signer_fpr_list)
+    {
+      fpr = get_fingerprint_hexstring (cert);
+      for (; signer_fpr_list && strcmp (signer_fpr_list->hexfpr, fpr);
+           signer_fpr_list = signer_fpr_list->next)
+        ;
+      if (signer_fpr_list)
+        err = 0;
+      else
+        {
+          log_error (_("not signed by a default OCSP signer's certificate"));
+          err = gpg_error (GPG_ERR_BAD_CA_CERT);
+        }
+      xfree (fpr);
+    }
+  else if (opt.system_daemon)
+    {
+      err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_OCSP, NULL);
+    }
+  else
+    {
+      /* We avoid duplicating the entire certificate validation code
+         from gpgsm here.  Because we have no way calling back to the
+         client and letting it compute the validity, we use the ugly
+         hack of telling the client that the response will only be
+         valid if the certificate given in this status message is
+         valid.
+
+         Note, that in theory we could simply ask the client via an
+         inquire to validate a certificate but this might involve
+         calling DirMngr again recursivly - we can't do that as of now
+         (neither DirMngr nor gpgsm have the ability for concurrent
+         access to DirMngr.   */
+
+      /* FIXME: We should cache this certificate locally, so that the next
+         call to dirmngr won't need to look it up - if this works at
+         all. */
+      fpr = get_fingerprint_hexstring (cert);
+      dirmngr_status (ctrl, "ONLY_VALID_IF_CERT_VALID", fpr, NULL);
+      xfree (fpr);
+      err = 0;
+    }
+
+  return err;
+}
+
+
+/* Helper for check_signature. */
+static int
+check_signature_core (ctrl_t ctrl, ksba_cert_t cert, gcry_sexp_t s_sig,
+                      gcry_sexp_t s_hash, fingerprint_list_t signer_fpr_list)
+{
+  gpg_error_t err;
+  ksba_sexp_t pubkey;
+  gcry_sexp_t s_pkey = NULL;
+
+  pubkey = ksba_cert_get_public_key (cert);
+  if (!pubkey)
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  else
+    err = canon_sexp_to_gcry (pubkey, &s_pkey);
+  xfree (pubkey);
+  if (!err)
+    err = gcry_pk_verify (s_sig, s_hash, s_pkey);
+  if (!err)
+    err = validate_responder_cert (ctrl, cert, signer_fpr_list);
+  if (!err)
+    {
+      gcry_sexp_release (s_pkey);
+      return 0; /* Successfully verified the signature. */
+    }
+
+  /* We simply ignore all errors. */
+  gcry_sexp_release (s_pkey);
+  return -1;
+}
+
+
+/* Check the signature of an OCSP repsonse.  OCSP is the context,
+   S_SIG the signature value and MD the handle of the hash we used for
+   the response.  This function automagically finds the correct public
+   key.  If SIGNER_FPR_LIST is not NULL, the default OCSP reponder has been
+   used and thus the certificate is one of those identified by
+   the fingerprints. */
+static gpg_error_t
+check_signature (ctrl_t ctrl,
+                 ksba_ocsp_t ocsp, gcry_sexp_t s_sig, gcry_md_hd_t md,
+                 fingerprint_list_t signer_fpr_list)
+{
+  gpg_error_t err;
+  int algo, cert_idx;
+  gcry_sexp_t s_hash;
+  ksba_cert_t cert;
+
+  /* Create a suitable S-expression with the hash value of our response. */
+  gcry_md_final (md);
+  algo = gcry_md_get_algo (md);
+  if (algo != GCRY_MD_SHA1 )
+    {
+      log_error (_("only SHA-1 is supported for OCSP responses\n"));
+      return gpg_error (GPG_ERR_DIGEST_ALGO);
+    }
+  err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash sha1 %b))",
+                         gcry_md_get_algo_dlen (algo),
+                         gcry_md_read (md, algo));
+  if (err)
+    {
+      log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
+      return err;
+    }
+
+  /* Get rid of old OCSP specific certificate references. */
+  release_ctrl_ocsp_certs (ctrl);
+
+  if (signer_fpr_list && !signer_fpr_list->next)
+    {
+      /* There is exactly one signer fingerprint given. Thus we use
+         the default OCSP responder's certificate and instantly know
+         the certificate to use.  */
+      cert = get_cert_byhexfpr (signer_fpr_list->hexfpr);
+      if (!cert)
+        cert = get_cert_local (ctrl, signer_fpr_list->hexfpr);
+      if (cert)
+        {
+          err = check_signature_core (ctrl, cert, s_sig, s_hash,
+                                      signer_fpr_list);
+          ksba_cert_release (cert);
+          cert = NULL;
+          if (!err)
+            {
+              gcry_sexp_release (s_hash);
+              return 0; /* Successfully verified the signature. */
+            }
+        }
+    }
+  else
+    {
+      char *name;
+      ksba_sexp_t keyid;
+
+      /* Put all certificates included in the response into the cache
+         and setup a list of those certificate which will later be
+         preferred used when locating certificates.  */
+      for (cert_idx=0; (cert = ksba_ocsp_get_cert (ocsp, cert_idx));
+           cert_idx++)
+        {
+          cert_ref_t cref;
+
+          cref = xtrymalloc (sizeof *cref);
+          if (!cref)
+            log_error (_("allocating list item failed: %s\n"),
+                       gcry_strerror (err));
+          else if (!cache_cert_silent (cert, &cref->fpr))
+            {
+              cref->next = ctrl->ocsp_certs;
+              ctrl->ocsp_certs = cref;
+            }
+          else
+            xfree (cref);
+        }
+
+      /* Get the certificate by means of the responder ID. */
+      err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
+      if (err)
+        {
+          log_error (_("error getting responder ID: %s\n"),
+                     gcry_strerror (err));
+          return err;
+        }
+      cert = find_cert_bysubject (ctrl, name, keyid);
+      if (!cert)
+        {
+          log_error ("responder certificate ");
+          if (name)
+            log_printf ("'/%s' ", name);
+          if (keyid)
+            {
+              log_printf ("{");
+              dump_serial (keyid);
+              log_printf ("} ");
+            }
+          log_printf ("not found\n");
+        }
+      ksba_free (name);
+      ksba_free (keyid);
+
+      if (cert)
+        {
+          err = check_signature_core (ctrl, cert, s_sig, s_hash,
+                                      signer_fpr_list);
+          ksba_cert_release (cert);
+          if (!err)
+            {
+              gcry_sexp_release (s_hash);
+              return 0; /* Successfully verified the signature. */
+            }
+        }
+    }
+
+  gcry_sexp_release (s_hash);
+  log_error (_("no suitable certificate found to verify the OCSP response\n"));
+  return gpg_error (GPG_ERR_NO_PUBKEY);
+}
+
+
+/* Check whether the certificate either given by fingerprint CERT_FPR
+   or directly through the CERT object is valid by running an OCSP
+   transaction.  With FORCE_DEFAULT_RESPONDER set only the configured
+   default responder is used. */
+gpg_error_t
+ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr,
+              int force_default_responder)
+{
+  gpg_error_t err;
+  ksba_ocsp_t ocsp = NULL;
+  ksba_cert_t issuer_cert = NULL;
+  ksba_sexp_t sigval = NULL;
+  gcry_sexp_t s_sig = NULL;
+  ksba_isotime_t current_time;
+  ksba_isotime_t this_update, next_update, revocation_time, produced_at;
+  ksba_isotime_t tmp_time;
+  ksba_status_t status;
+  ksba_crl_reason_t reason;
+  char *url_buffer = NULL;
+  const char *url;
+  gcry_md_hd_t md = NULL;
+  int i, idx;
+  char *oid;
+  ksba_name_t name;
+  fingerprint_list_t default_signer = NULL;
+
+  /* Get the certificate.  */
+  if (cert)
+    {
+      ksba_cert_ref (cert);
+
+      err = find_issuing_cert (ctrl, cert, &issuer_cert);
+      if (err)
+        {
+          log_error (_("issuer certificate not found: %s\n"),
+                     gpg_strerror (err));
+          goto leave;
+        }
+    }
+  else
+    {
+      cert = get_cert_local (ctrl, cert_fpr);
+      if (!cert)
+        {
+          log_error (_("caller did not return the target certificate\n"));
+          err = gpg_error (GPG_ERR_GENERAL);
+          goto leave;
+        }
+      issuer_cert = get_issuing_cert_local (ctrl, NULL);
+      if (!issuer_cert)
+        {
+          log_error (_("caller did not return the issuing certificate\n"));
+          err = gpg_error (GPG_ERR_GENERAL);
+          goto leave;
+        }
+    }
+
+  /* Create an OCSP instance.  */
+  err = ksba_ocsp_new (&ocsp);
+  if (err)
+    {
+      log_error (_("failed to allocate OCSP context: %s\n"),
+                 gpg_strerror (err));
+      goto leave;
+    }
+
+
+
+  /* Figure out the OCSP responder to use.
+     1. Try to get the reponder from the certificate.
+        We do only take http and https style URIs into account.
+     2. If this fails use the default responder, if any.
+   */
+  url = NULL;
+  for (idx=0; !url && !opt.ignore_ocsp_service_url && !force_default_responder
+         && !(err=ksba_cert_get_authority_info_access (cert, idx,
+                                                       &oid, &name)); idx++)
+    {
+      if ( !strcmp (oid, oidstr_ocsp) )
+        {
+          for (i=0; !url && ksba_name_enum (name, i); i++)
+            {
+              char *p = ksba_name_get_uri (name, i);
+              if (p && (!ascii_strncasecmp (p, "http:", 5)
+                        || !ascii_strncasecmp (p, "https:", 6)))
+                url = url_buffer = p;
+              else
+                xfree (p);
+            }
+        }
+      ksba_name_release (name);
+      ksba_free (oid);
+    }
+  if (err && gpg_err_code (err) != GPG_ERR_EOF)
+    {
+      log_error (_("can't get authorityInfoAccess: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+  if (!url)
+    {
+      if (!opt.ocsp_responder || !*opt.ocsp_responder)
+        {
+          log_info (_("no default OCSP responder defined\n"));
+          err = gpg_error (GPG_ERR_CONFIGURATION);
+          goto leave;
+        }
+      if (!opt.ocsp_signer)
+        {
+          log_info (_("no default OCSP signer defined\n"));
+          err = gpg_error (GPG_ERR_CONFIGURATION);
+          goto leave;
+        }
+      url = opt.ocsp_responder;
+      default_signer = opt.ocsp_signer;
+      if (opt.verbose)
+        log_info (_("using default OCSP responder '%s'\n"), url);
+    }
+  else
+    {
+      if (opt.verbose)
+        log_info (_("using OCSP responder '%s'\n"), url);
+    }
+
+  /* Ask the OCSP responder. */
+  err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+  if (err)
+    {
+      log_error (_("failed to establish a hashing context for OCSP: %s\n"),
+                 gpg_strerror (err));
+      goto leave;
+    }
+  err = do_ocsp_request (ctrl, ocsp, md, url, cert, issuer_cert);
+  if (err)
+    goto leave;
+
+  /* We got a useful answer, check that the answer has a valid signature. */
+  sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
+  if (!sigval || !*produced_at)
+    {
+      err = gpg_error (GPG_ERR_INV_OBJ);
+      goto leave;
+    }
+  if ( (err = canon_sexp_to_gcry (sigval, &s_sig)) )
+    goto leave;
+  xfree (sigval);
+  sigval = NULL;
+  err = check_signature (ctrl, ocsp, s_sig, md, default_signer);
+  if (err)
+    goto leave;
+
+  /* We only support one certificate per request.  Check that the
+     answer matches the right certificate. */
+  err = ksba_ocsp_get_status (ocsp, cert,
+                              &status, this_update, next_update,
+                              revocation_time, &reason);
+  if (err)
+    {
+      log_error (_("error getting OCSP status for target certificate: %s\n"),
+                 gpg_strerror (err));
+      goto leave;
+    }
+
+  /* In case the certificate has been revoked, we better invalidate
+     our cached validation status. */
+  if (status == KSBA_STATUS_REVOKED)
+    {
+      time_t validated_at = 0; /* That is: No cached validation available. */
+      err = ksba_cert_set_user_data (cert, "validated_at",
+                                     &validated_at, sizeof (validated_at));
+      if (err)
+        {
+          log_error ("set_user_data(validated_at) failed: %s\n",
+                     gpg_strerror (err));
+          err = 0; /* The certificate is anyway revoked, and that is a
+                      more important message than the failure of our
+                      cache. */
+        }
+    }
+
+
+  if (opt.verbose)
+    {
+      log_info (_("certificate status is: %s  (this=%s  next=%s)\n"),
+                status == KSBA_STATUS_GOOD? _("good"):
+                status == KSBA_STATUS_REVOKED? _("revoked"):
+                status == KSBA_STATUS_UNKNOWN? _("unknown"):
+                status == KSBA_STATUS_NONE? _("none"): "?",
+                this_update, next_update);
+      if (status == KSBA_STATUS_REVOKED)
+        log_info (_("certificate has been revoked at: %s due to: %s\n"),
+                  revocation_time,
+                  reason == KSBA_CRLREASON_UNSPECIFIED?   "unspecified":
+                  reason == KSBA_CRLREASON_KEY_COMPROMISE? "key compromise":
+                  reason == KSBA_CRLREASON_CA_COMPROMISE?   "CA compromise":
+                  reason == KSBA_CRLREASON_AFFILIATION_CHANGED?
+                                                      "affiliation changed":
+                  reason == KSBA_CRLREASON_SUPERSEDED?   "superseeded":
+                  reason == KSBA_CRLREASON_CESSATION_OF_OPERATION?
+                                                  "cessation of operation":
+                  reason == KSBA_CRLREASON_CERTIFICATE_HOLD?
+                                                  "certificate on hold":
+                  reason == KSBA_CRLREASON_REMOVE_FROM_CRL?
+                                                  "removed from CRL":
+                  reason == KSBA_CRLREASON_PRIVILEGE_WITHDRAWN?
+                                                  "privilege withdrawn":
+                  reason == KSBA_CRLREASON_AA_COMPROMISE? "AA compromise":
+                  reason == KSBA_CRLREASON_OTHER?   "other":"?");
+
+    }
+
+
+  if (status == KSBA_STATUS_REVOKED)
+    err = gpg_error (GPG_ERR_CERT_REVOKED);
+  else if (status == KSBA_STATUS_UNKNOWN)
+    err = gpg_error (GPG_ERR_NO_DATA);
+  else if (status != KSBA_STATUS_GOOD)
+    err = gpg_error (GPG_ERR_GENERAL);
+
+  /* Allow for some clock skew. */
+  gnupg_get_isotime (current_time);
+  add_seconds_to_isotime (current_time, opt.ocsp_max_clock_skew);
+
+  if (strcmp (this_update, current_time) > 0 )
+    {
+      log_error (_("OCSP responder returned a status in the future\n"));
+      log_info ("used now: %s  this_update: %s\n", current_time, this_update);
+      if (!err)
+        err = gpg_error (GPG_ERR_TIME_CONFLICT);
+    }
+
+  /* Check that THIS_UPDATE is not too far back in the past. */
+  gnupg_copy_time (tmp_time, this_update);
+  add_seconds_to_isotime (tmp_time,
+                          opt.ocsp_max_period+opt.ocsp_max_clock_skew);
+  if (!*tmp_time || strcmp (tmp_time, current_time) < 0 )
+    {
+      log_error (_("OCSP responder returned a non-current status\n"));
+      log_info ("used now: %s  this_update: %s\n",
+                current_time, this_update);
+      if (!err)
+        err = gpg_error (GPG_ERR_TIME_CONFLICT);
+    }
+
+  /* Check that we are not beyound NEXT_UPDATE  (plus some extra time). */
+  if (*next_update)
+    {
+      gnupg_copy_time (tmp_time, next_update);
+      add_seconds_to_isotime (tmp_time,
+                              opt.ocsp_current_period+opt.ocsp_max_clock_skew);
+      if (!*tmp_time && strcmp (tmp_time, current_time) < 0 )
+        {
+          log_error (_("OCSP responder returned an too old status\n"));
+          log_info ("used now: %s  next_update: %s\n",
+                    current_time, next_update);
+          if (!err)
+            err = gpg_error (GPG_ERR_TIME_CONFLICT);
+        }
+    }
+
+
+ leave:
+  gcry_md_close (md);
+  gcry_sexp_release (s_sig);
+  xfree (sigval);
+  ksba_cert_release (issuer_cert);
+  ksba_cert_release (cert);
+  ksba_ocsp_release (ocsp);
+  xfree (url_buffer);
+  return err;
+}
+
+
+/* Release the list of OCSP certificates hold in the CTRL object. */
+void
+release_ctrl_ocsp_certs (ctrl_t ctrl)
+{
+  while (ctrl->ocsp_certs)
+    {
+      cert_ref_t tmp = ctrl->ocsp_certs->next;
+      xfree (ctrl->ocsp_certs);
+      ctrl->ocsp_certs = tmp;
+    }
+}
diff --git a/dirmngr/ocsp.h b/dirmngr/ocsp.h
new file mode 100644 (file)
index 0000000..cfab7dd
--- /dev/null
@@ -0,0 +1,31 @@
+/* ocsp.h - OCSP management
+ *      Copyright (C) 2003 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef OCSP_H
+#define OCSP_H
+
+gpg_error_t ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr,
+                          int force_default_responder);
+
+/* Release the list of OCSP certificates hold in the CTRL object. */
+void release_ctrl_ocsp_certs (ctrl_t ctrl);
+
+#endif /*OCSP_H*/
diff --git a/dirmngr/server.c b/dirmngr/server.c
new file mode 100644 (file)
index 0000000..9b4cdb2
--- /dev/null
@@ -0,0 +1,2183 @@
+/* server.c - LDAP and Keyserver access server
+ * Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011 g10 Code GmbH
+ * Copyright (C) 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define JNLIB_NEED_LOG_LOGV
+#include "dirmngr.h"
+#include <assuan.h>
+
+#include "crlcache.h"
+#include "crlfetch.h"
+#if USE_LDAP
+# include "ldapserver.h"
+#endif
+#include "ocsp.h"
+#include "certcache.h"
+#include "validate.h"
+#include "misc.h"
+#if USE_LDAP
+# include "ldap-wrapper.h"
+#endif
+#include "ks-action.h"
+#include "ks-engine.h"  /* (ks_hkp_print_hosttable) */
+
+/* To avoid DoS attacks we limit the size of a certificate to
+   something reasonable. */
+#define MAX_CERT_LENGTH (8*1024)
+
+/* The same goes for OpenPGP keyblocks, but here we need to allow for
+   much longer blocks; a 200k keyblock is not too unusual for keys
+   with a lot of signatures (e.g. 0x5b0358a2).  */
+#define MAX_KEYBLOCK_LENGTH (512*1024)
+
+
+#define PARM_ERROR(t) assuan_set_error (ctx, \
+                                        gpg_error (GPG_ERR_ASS_PARAMETER), (t))
+#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
+
+
+
+/* Control structure per connection. */
+struct server_local_s
+{
+  /* Data used to associate an Assuan context with local server data */
+  assuan_context_t assuan_ctx;
+
+  /* Per-session LDAP servers.  */
+  ldap_server_t ldapservers;
+
+  /* If this flag is set to true this dirmngr process will be
+     terminated after the end of this session.  */
+  int stopme;
+};
+
+
+/* Cookie definition for assuan data line output.  */
+static ssize_t data_line_cookie_write (void *cookie,
+                                       const void *buffer, size_t size);
+static int data_line_cookie_close (void *cookie);
+static es_cookie_io_functions_t data_line_cookie_functions =
+  {
+    NULL,
+    data_line_cookie_write,
+    NULL,
+    data_line_cookie_close
+  };
+
+
+
+
+\f
+/* Accessor for the local ldapservers variable. */
+ldap_server_t
+get_ldapservers_from_ctrl (ctrl_t ctrl)
+{
+  if (ctrl && ctrl->server_local)
+    return ctrl->server_local->ldapservers;
+  else
+    return NULL;
+}
+
+
+/* Release all configured keyserver info from CTRL.  */
+void
+release_ctrl_keyservers (ctrl_t ctrl)
+{
+  while (ctrl->keyservers)
+    {
+      uri_item_t tmp = ctrl->keyservers->next;
+      http_release_parsed_uri (ctrl->keyservers->parsed_uri);
+      xfree (ctrl->keyservers);
+      ctrl->keyservers = tmp;
+    }
+}
+
+
+
+/* Helper to print a message while leaving a command.  */
+static gpg_error_t
+leave_cmd (assuan_context_t ctx, gpg_error_t err)
+
+{
+  if (err)
+    {
+      const char *name = assuan_get_command_name (ctx);
+      if (!name)
+        name = "?";
+      if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
+        log_error ("command '%s' failed: %s\n", name,
+                   gpg_strerror (err));
+      else
+        log_error ("command '%s' failed: %s <%s>\n", name,
+                   gpg_strerror (err), gpg_strsource (err));
+    }
+  return err;
+}
+
+/* A write handler used by es_fopencookie to write assuan data
+   lines.  */
+static ssize_t
+data_line_cookie_write (void *cookie, const void *buffer_arg, size_t size)
+{
+  assuan_context_t ctx = cookie;
+  const char *buffer = buffer_arg;
+
+  if (opt.verbose && buffer && size)
+    {
+      /* Ease reading of output by sending a physical line at each LF.  */
+      const char *p;
+      size_t n, nbytes;
+
+      nbytes = size;
+      do
+        {
+          p = memchr (buffer, '\n', nbytes);
+          n = p ? (p - buffer) + 1 : nbytes;
+          if (assuan_send_data (ctx, buffer, n))
+            {
+              gpg_err_set_errno (EIO);
+              return -1;
+            }
+          buffer += n;
+          nbytes -= n;
+          if (nbytes && assuan_send_data (ctx, NULL, 0)) /* Flush line. */
+            {
+              gpg_err_set_errno (EIO);
+              return -1;
+            }
+        }
+      while (nbytes);
+    }
+  else
+    {
+      if (assuan_send_data (ctx, buffer, size))
+        {
+          gpg_err_set_errno (EIO);
+          return -1;
+        }
+    }
+
+  return size;
+}
+
+static int
+data_line_cookie_close (void *cookie)
+{
+  assuan_context_t ctx = cookie;
+
+  if (assuan_send_data (ctx, NULL, 0))
+    {
+      gpg_err_set_errno (EIO);
+      return -1;
+    }
+
+  return 0;
+}
+
+
+/* Copy the % and + escaped string S into the buffer D and replace the
+   escape sequences.  Note, that it is sufficient to allocate the
+   target string D as long as the source string S, i.e.: strlen(s)+1.
+   Note further that if S contains an escaped binary Nul the resulting
+   string D will contain the 0 as well as all other characters but it
+   will be impossible to know whether this is the original EOS or a
+   copied Nul. */
+static void
+strcpy_escaped_plus (char *d, const unsigned char *s)
+{
+  while (*s)
+    {
+      if (*s == '%' && s[1] && s[2])
+        {
+          s++;
+          *d++ = xtoi_2 ( s);
+          s += 2;
+        }
+      else if (*s == '+')
+        *d++ = ' ', s++;
+      else
+        *d++ = *s++;
+    }
+  *d = 0;
+}
+
+
+/* Check whether the option NAME appears in LINE */
+static int
+has_option (const char *line, const char *name)
+{
+  const char *s;
+  int n = strlen (name);
+
+  s = strstr (line, name);
+  return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
+}
+
+/* Same as has_option but only considers options at the begin of the
+   line.  This is useful for commands which allow arbitrary strings on
+   the line.  */
+static int
+has_leading_option (const char *line, const char *name)
+{
+  const char *s;
+  int n;
+
+  if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2))
+    return 0;
+  n = strlen (name);
+  while ( *line == '-' && line[1] == '-' )
+    {
+      s = line;
+      while (*line && !spacep (line))
+        line++;
+      if (n == (line - s) && !strncmp (s, name, n))
+        return 1;
+      while (spacep (line))
+        line++;
+    }
+  return 0;
+}
+
+
+/* Same as has_option but does only test for the name of the option
+   and ignores an argument, i.e. with NAME being "--hash" it would
+   return a pointer for "--hash" as well as for "--hash=foo".  If
+   thhere is no such option NULL is returned.  The pointer returned
+   points right behind the option name, this may be an equal sign, Nul
+   or a space.  */
+/* static const char * */
+/* has_option_name (const char *line, const char *name) */
+/* { */
+/*   const char *s; */
+/*   int n = strlen (name); */
+
+/*   s = strstr (line, name); */
+/*   return (s && (s == line || spacep (s-1)) */
+/*           && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL; */
+/* } */
+
+
+/* Skip over options.  It is assumed that leading spaces have been
+   removed (this is the case for lines passed to a handler from
+   assuan).  Blanks after the options are also removed. */
+static char *
+skip_options (char *line)
+{
+  while ( *line == '-' && line[1] == '-' )
+    {
+      while (*line && !spacep (line))
+        line++;
+      while (spacep (line))
+        line++;
+    }
+  return line;
+}
+
+
+/* Return an error if the assuan context does not belong to the owner
+   of the process or to root.  On error FAILTEXT is set as Assuan
+   error string.  */
+static gpg_error_t
+check_owner_permission (assuan_context_t ctx, const char *failtext)
+{
+#ifdef HAVE_W32_SYSTEM
+  /* Under Windows the dirmngr is always run under the control of the
+     user.  */
+  (void)ctx;
+  (void)failtext;
+#else
+  gpg_err_code_t ec;
+  assuan_peercred_t cred;
+
+  ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
+  if (!ec && cred->uid && cred->uid != getuid ())
+    ec = GPG_ERR_EPERM;
+  if (ec)
+    return set_error (ec, failtext);
+#endif
+  return 0;
+}
+
+
+
+/* Common code for get_cert_local and get_issuer_cert_local. */
+static ksba_cert_t
+do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
+{
+  unsigned char *value;
+  size_t valuelen;
+  int rc;
+  char *buf;
+  ksba_cert_t cert;
+
+  if (name)
+    {
+      buf = xmalloc ( strlen (command) + 1 + strlen(name) + 1);
+      strcpy (stpcpy (stpcpy (buf, command), " "), name);
+    }
+  else
+    buf = xstrdup (command);
+
+  rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
+                       &value, &valuelen, MAX_CERT_LENGTH);
+  xfree (buf);
+  if (rc)
+    {
+      log_error (_("assuan_inquire(%s) failed: %s\n"),
+                 command, gpg_strerror (rc));
+      return NULL;
+    }
+
+  if (!valuelen)
+    {
+      xfree (value);
+      return NULL;
+    }
+
+  rc = ksba_cert_new (&cert);
+  if (!rc)
+    {
+      rc = ksba_cert_init_from_mem (cert, value, valuelen);
+      if (rc)
+        {
+          ksba_cert_release (cert);
+          cert = NULL;
+        }
+    }
+  xfree (value);
+  return cert;
+}
+
+
+
+/* Ask back to return a certificate for name, given as a regular
+   gpgsm certificate indentificates (e.g. fingerprint or one of the
+   other methods).  Alternatively, NULL may be used for NAME to
+   return the current target certificate. Either return the certificate
+   in a KSBA object or NULL if it is not available.
+*/
+ksba_cert_t
+get_cert_local (ctrl_t ctrl, const char *name)
+{
+  if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
+    {
+      if (opt.debug)
+        log_debug ("get_cert_local called w/o context\n");
+      return NULL;
+    }
+  return do_get_cert_local (ctrl, name, "SENDCERT");
+
+}
+
+/* Ask back to return the issuing certificate for name, given as a
+   regular gpgsm certificate indentificates (e.g. fingerprint or one
+   of the other methods).  Alternatively, NULL may be used for NAME to
+   return thecurrent target certificate. Either return the certificate
+   in a KSBA object or NULL if it is not available.
+
+*/
+ksba_cert_t
+get_issuing_cert_local (ctrl_t ctrl, const char *name)
+{
+  if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
+    {
+      if (opt.debug)
+        log_debug ("get_issuing_cert_local called w/o context\n");
+      return NULL;
+    }
+  return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
+}
+
+/* Ask back to return a certificate with subject NAME and a
+   subjectKeyIdentifier of KEYID. */
+ksba_cert_t
+get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
+{
+  unsigned char *value;
+  size_t valuelen;
+  int rc;
+  char *buf;
+  ksba_cert_t cert;
+  char *hexkeyid;
+
+  if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
+    {
+      if (opt.debug)
+        log_debug ("get_cert_local_ski called w/o context\n");
+      return NULL;
+    }
+  if (!name || !keyid)
+    {
+      log_debug ("get_cert_local_ski called with insufficient arguments\n");
+      return NULL;
+    }
+
+  hexkeyid = serial_hex (keyid);
+  if (!hexkeyid)
+    {
+      log_debug ("serial_hex() failed\n");
+      return NULL;
+    }
+
+  buf = xtrymalloc (15 + strlen (hexkeyid) + 2 + strlen(name) + 1);
+  if (!buf)
+    {
+
+      log_error ("can't allocate enough memory: %s\n", strerror (errno));
+      xfree (hexkeyid);
+      return NULL;
+    }
+  strcpy (stpcpy (stpcpy (stpcpy (buf, "SENDCERT_SKI "), hexkeyid)," /"),name);
+  xfree (hexkeyid);
+
+  rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
+                       &value, &valuelen, MAX_CERT_LENGTH);
+  xfree (buf);
+  if (rc)
+    {
+      log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
+                 gpg_strerror (rc));
+      return NULL;
+    }
+
+  if (!valuelen)
+    {
+      xfree (value);
+      return NULL;
+    }
+
+  rc = ksba_cert_new (&cert);
+  if (!rc)
+    {
+      rc = ksba_cert_init_from_mem (cert, value, valuelen);
+      if (rc)
+        {
+          ksba_cert_release (cert);
+          cert = NULL;
+        }
+    }
+  xfree (value);
+  return cert;
+}
+
+
+/* Ask the client via an inquiry to check the istrusted status of the
+   certificate specified by the hexified fingerprint HEXFPR.  Returns
+   0 if the certificate is trusted by the client or an error code.  */
+gpg_error_t
+get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
+{
+  unsigned char *value;
+  size_t valuelen;
+  int rc;
+  char request[100];
+
+  if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
+      || !hexfpr)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
+  rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
+                       &value, &valuelen, 100);
+  if (rc)
+    {
+      log_error (_("assuan_inquire(%s) failed: %s\n"),
+                 request, gpg_strerror (rc));
+      return rc;
+    }
+  /* The expected data is: "1" or "1 cruft" (not a C-string).  */
+  if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
+    rc = 0;
+  else
+    rc = gpg_error (GPG_ERR_NOT_TRUSTED);
+  xfree (value);
+  return rc;
+}
+
+
+
+
+/* Ask the client to return the certificate associated with the
+   current command. This is sometimes needed because the client usually
+   sends us just the cert ID, assuming that the request can be
+   satisfied from the cache, where the cert ID is used as key. */
+static int
+inquire_cert_and_load_crl (assuan_context_t ctx)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  unsigned char *value = NULL;
+  size_t valuelen;
+  ksba_cert_t cert = NULL;
+
+  err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
+  if (err)
+    return err;
+
+/*   { */
+/*     FILE *fp = fopen ("foo.der", "r"); */
+/*     value = xmalloc (2000); */
+/*     valuelen = fread (value, 1, 2000, fp); */
+/*     fclose (fp); */
+/*   } */
+
+  if (!valuelen) /* No data returned; return a comprehensible error. */
+    return gpg_error (GPG_ERR_MISSING_CERT);
+
+  err = ksba_cert_new (&cert);
+  if (err)
+    goto leave;
+  err = ksba_cert_init_from_mem (cert, value, valuelen);
+  if(err)
+    goto leave;
+  xfree (value); value = NULL;
+
+  err = crl_cache_reload_crl (ctrl, cert);
+
+ leave:
+  ksba_cert_release (cert);
+  xfree (value);
+  return err;
+}
+
+
+/* Handle OPTION commands. */
+static gpg_error_t
+option_handler (assuan_context_t ctx, const char *key, const char *value)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+
+  if (!strcmp (key, "force-crl-refresh"))
+    {
+      int i = *value? atoi (value) : 0;
+      ctrl->force_crl_refresh = i;
+    }
+  else if (!strcmp (key, "audit-events"))
+    {
+      int i = *value? atoi (value) : 0;
+      ctrl->audit_events = i;
+    }
+  else
+    return gpg_error (GPG_ERR_UNKNOWN_OPTION);
+
+  return 0;
+}
+
+static const char hlp_ldapserver[] =
+  "LDAPSERVER <data>\n"
+  "\n"
+  "Add a new LDAP server to the list of configured LDAP servers.\n"
+  "DATA is in the same format as expected in the configure file.";
+static gpg_error_t
+cmd_ldapserver (assuan_context_t ctx, char *line)
+{
+#if USE_LDAP
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  ldap_server_t server;
+  ldap_server_t *last_next_p;
+
+  while (spacep (line))
+    line++;
+  if (*line == '\0')
+    return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
+
+  server = ldapserver_parse_one (line, "", 0);
+  if (! server)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
+
+  last_next_p = &ctrl->server_local->ldapservers;
+  while (*last_next_p)
+    last_next_p = &(*last_next_p)->next;
+  *last_next_p = server;
+  return leave_cmd (ctx, 0);
+#else
+  (void)line;
+  return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
+#endif
+}
+
+
+static const char hlp_isvalid[] =
+  "ISVALID [--only-ocsp] [--force-default-responder]"
+  " <certificate_id>|<certificate_fpr>\n"
+  "\n"
+  "This command checks whether the certificate identified by the\n"
+  "certificate_id is valid.  This is done by consulting CRLs or\n"
+  "whatever has been configured.  Note, that the returned error codes\n"
+  "are from gpg-error.h.  The command may callback using the inquire\n"
+  "function.  See the manual for details.\n"
+  "\n"
+  "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
+  "delimited by a single dot.  The first part is the SHA-1 hash of the\n"
+  "issuer name and the second part the serial number.\n"
+  "\n"
+  "Alternatively the certificate's fingerprint may be given in which\n"
+  "case an OCSP request is done before consulting the CRL.\n"
+  "\n"
+  "If the option --only-ocsp is given, no fallback to a CRL check will\n"
+  "be used.\n"
+  "\n"
+  "If the option --force-default-responder is given, only the default\n"
+  "OCSP responder will be used and any other methods of obtaining an\n"
+  "OCSP responder URL won't be used.";
+static gpg_error_t
+cmd_isvalid (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  char *issuerhash, *serialno;
+  gpg_error_t err;
+  int did_inquire = 0;
+  int ocsp_mode = 0;
+  int only_ocsp;
+  int force_default_responder;
+
+  only_ocsp = has_option (line, "--only-ocsp");
+  force_default_responder = has_option (line, "--force-default-responder");
+  line = skip_options (line);
+
+  issuerhash = xstrdup (line); /* We need to work on a copy of the
+                                  line because that same Assuan
+                                  context may be used for an inquiry.
+                                  That is because Assuan reuses its
+                                  line buffer.
+                                   */
+
+  serialno = strchr (issuerhash, '.');
+  if (serialno)
+    *serialno++ = 0;
+  else
+    {
+      char *endp = strchr (issuerhash, ' ');
+      if (endp)
+        *endp = 0;
+      if (strlen (issuerhash) != 40)
+        {
+          xfree (issuerhash);
+          return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
+        }
+      ocsp_mode = 1;
+    }
+
+
+ again:
+  if (ocsp_mode)
+    {
+      /* Note, that we ignore the given issuer hash and instead rely
+         on the current certificate semantics used with this
+         command. */
+      if (!opt.allow_ocsp)
+        err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      else
+        err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
+      /* Fixme: If we got no ocsp response and --only-ocsp is not used
+         we should fall back to CRL mode.  Thus we need to clear
+         OCSP_MODE, get the issuerhash and the serialno from the
+         current certificate and jump to again. */
+    }
+  else if (only_ocsp)
+    err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+  else
+    {
+      switch (crl_cache_isvalid (ctrl,
+                                 issuerhash, serialno,
+                                 ctrl->force_crl_refresh))
+        {
+        case CRL_CACHE_VALID:
+          err = 0;
+          break;
+        case CRL_CACHE_INVALID:
+          err = gpg_error (GPG_ERR_CERT_REVOKED);
+          break;
+        case CRL_CACHE_DONTKNOW:
+          if (did_inquire)
+            err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+          else if (!(err = inquire_cert_and_load_crl (ctx)))
+            {
+              did_inquire = 1;
+              goto again;
+            }
+          break;
+        case CRL_CACHE_CANTUSE:
+          err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+          break;
+        default:
+          log_fatal ("crl_cache_isvalid returned invalid code\n");
+        }
+    }
+
+  xfree (issuerhash);
+  return leave_cmd (ctx, err);
+}
+
+
+/* If the line contains a SHA-1 fingerprint as the first argument,
+   return the FPR vuffer on success.  The function checks that the
+   fingerprint consists of valid characters and prints and error
+   message if it does not and returns NULL.  Fingerprints are
+   considered optional and thus no explicit error is returned. NULL is
+   also returned if there is no fingerprint at all available.
+   FPR must be a caller provided buffer of at least 20 bytes.
+
+   Note that colons within the fingerprint are allowed to separate 2
+   hex digits; this allows for easier cutting and pasting using the
+   usual fingerprint rendering.
+*/
+static unsigned char *
+get_fingerprint_from_line (const char *line, unsigned char *fpr)
+{
+  const char *s;
+  int i;
+
+  for (s=line, i=0; *s && *s != ' '; s++ )
+    {
+      if ( hexdigitp (s) && hexdigitp (s+1) )
+        {
+          if ( i >= 20 )
+            return NULL;  /* Fingerprint too long.  */
+          fpr[i++] = xtoi_2 (s);
+          s++;
+        }
+      else if ( *s != ':' )
+        return NULL; /* Invalid.  */
+    }
+  if ( i != 20 )
+    return NULL; /* Fingerprint to short.  */
+  return fpr;
+}
+
+
+
+static const char hlp_checkcrl[] =
+  "CHECKCRL [<fingerprint>]\n"
+  "\n"
+  "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
+  "entire X.509 certificate blob) is valid or not by consulting the\n"
+  "CRL responsible for this certificate.  If the fingerprint has not\n"
+  "been given or the certificate is not known, the function \n"
+  "inquires the certificate using an\n"
+  "\n"
+  "  INQUIRE TARGETCERT\n"
+  "\n"
+  "and the caller is expected to return the certificate for the\n"
+  "request (which should match FINGERPRINT) as a binary blob.\n"
+  "Processing then takes place without further interaction; in\n"
+  "particular dirmngr tries to locate other required certificate by\n"
+  "its own mechanism which includes a local certificate store as well\n"
+  "as a list of trusted root certificates.\n"
+  "\n"
+  "The return value is the usual gpg-error code or 0 for ducesss;\n"
+  "i.e. the certificate validity has been confirmed by a valid CRL.";
+static gpg_error_t
+cmd_checkcrl (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  unsigned char fprbuffer[20], *fpr;
+  ksba_cert_t cert;
+
+  fpr = get_fingerprint_from_line (line, fprbuffer);
+  cert = fpr? get_cert_byfpr (fpr) : NULL;
+
+  if (!cert)
+    {
+      /* We do not have this certificate yet or the fingerprint has
+         not been given.  Inquire it from the client.  */
+      unsigned char *value = NULL;
+      size_t valuelen;
+
+      err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
+                           &value, &valuelen, MAX_CERT_LENGTH);
+      if (err)
+        {
+          log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
+          goto leave;
+        }
+
+      if (!valuelen) /* No data returned; return a comprehensible error. */
+        err = gpg_error (GPG_ERR_MISSING_CERT);
+      else
+        {
+          err = ksba_cert_new (&cert);
+          if (!err)
+            err = ksba_cert_init_from_mem (cert, value, valuelen);
+        }
+      xfree (value);
+      if(err)
+        goto leave;
+    }
+
+  assert (cert);
+
+  err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
+  if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
+    {
+      err = crl_cache_reload_crl (ctrl, cert);
+      if (!err)
+        err = crl_cache_cert_isvalid (ctrl, cert, 0);
+    }
+
+ leave:
+  ksba_cert_release (cert);
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_checkocsp[] =
+  "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
+  "\n"
+  "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
+  "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
+  "responder responsible for this certificate.  The optional\n"
+  "fingerprint may be used for a quick check in case an OCSP check has\n"
+  "been done for this certificate recently (we always cache OCSP\n"
+  "responses for a couple of minutes). If the fingerprint has not been\n"
+  "given or there is no cached result, the function inquires the\n"
+  "certificate using an\n"
+  "\n"
+  "   INQUIRE TARGETCERT\n"
+  "\n"
+  "and the caller is expected to return the certificate for the\n"
+  "request (which should match FINGERPRINT) as a binary blob.\n"
+  "Processing then takes place without further interaction; in\n"
+  "particular dirmngr tries to locate other required certificates by\n"
+  "its own mechanism which includes a local certificate store as well\n"
+  "as a list of trusted root certifciates.\n"
+  "\n"
+  "If the option --force-default-responder is given, only the default\n"
+  "OCSP responder will be used and any other methods of obtaining an\n"
+  "OCSP responder URL won't be used.\n"
+  "\n"
+  "The return value is the usual gpg-error code or 0 for ducesss;\n"
+  "i.e. the certificate validity has been confirmed by a valid CRL.";
+static gpg_error_t
+cmd_checkocsp (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  unsigned char fprbuffer[20], *fpr;
+  ksba_cert_t cert;
+  int force_default_responder;
+
+  force_default_responder = has_option (line, "--force-default-responder");
+  line = skip_options (line);
+
+  fpr = get_fingerprint_from_line (line, fprbuffer);
+  cert = fpr? get_cert_byfpr (fpr) : NULL;
+
+  if (!cert)
+    {
+      /* We do not have this certificate yet or the fingerprint has
+         not been given.  Inquire it from the client.  */
+      unsigned char *value = NULL;
+      size_t valuelen;
+
+      err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
+                           &value, &valuelen, MAX_CERT_LENGTH);
+      if (err)
+        {
+          log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
+          goto leave;
+        }
+
+      if (!valuelen) /* No data returned; return a comprehensible error. */
+        err = gpg_error (GPG_ERR_MISSING_CERT);
+      else
+        {
+          err = ksba_cert_new (&cert);
+          if (!err)
+            err = ksba_cert_init_from_mem (cert, value, valuelen);
+        }
+      xfree (value);
+      if(err)
+        goto leave;
+    }
+
+  assert (cert);
+
+  if (!opt.allow_ocsp)
+    err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+  else
+    err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
+
+ leave:
+  ksba_cert_release (cert);
+  return leave_cmd (ctx, err);
+}
+
+
+
+static int
+lookup_cert_by_url (assuan_context_t ctx, const char *url)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+  unsigned char *value = NULL;
+  size_t valuelen;
+
+  /* Fetch single certificate given it's URL.  */
+  err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
+  if (err)
+    {
+      log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Send the data, flush the buffer and then send an END. */
+  err = assuan_send_data (ctx, value, valuelen);
+  if (!err)
+    err = assuan_send_data (ctx, NULL, 0);
+  if (!err)
+    err = assuan_write_line (ctx, "END");
+  if (err)
+    {
+      log_error (_("error sending data: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+ leave:
+
+  return err;
+}
+
+
+/* Send the certificate, flush the buffer and then send an END. */
+static gpg_error_t
+return_one_cert (void *opaque, ksba_cert_t cert)
+{
+  assuan_context_t ctx = opaque;
+  gpg_error_t err;
+  const unsigned char *der;
+  size_t derlen;
+
+  der = ksba_cert_get_image (cert, &derlen);
+  if (!der)
+    err = gpg_error (GPG_ERR_INV_CERT_OBJ);
+  else
+    {
+      err = assuan_send_data (ctx, der, derlen);
+      if (!err)
+        err = assuan_send_data (ctx, NULL, 0);
+      if (!err)
+        err = assuan_write_line (ctx, "END");
+    }
+  if (err)
+    log_error (_("error sending data: %s\n"), gpg_strerror (err));
+  return err;
+}
+
+
+/* Lookup certificates from the internal cache or using the ldap
+   servers. */
+static int
+lookup_cert_by_pattern (assuan_context_t ctx, char *line,
+                        int single, int cache_only)
+{
+  gpg_error_t err = 0;
+  char *p;
+  strlist_t sl, list = NULL;
+  int truncated = 0, truncation_forced = 0;
+  int count = 0;
+  int local_count = 0;
+#if USE_LDAP
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  unsigned char *value = NULL;
+  size_t valuelen;
+  struct ldapserver_iter ldapserver_iter;
+  cert_fetch_context_t fetch_context;
+#endif /*USE_LDAP*/
+  int any_no_data = 0;
+
+  /* Break the line down into an STRLIST */
+  for (p=line; *p; line = p)
+    {
+      while (*p && *p != ' ')
+        p++;
+      if (*p)
+        *p++ = 0;
+
+      if (*line)
+        {
+          sl = xtrymalloc (sizeof *sl + strlen (line));
+          if (!sl)
+            {
+              err = gpg_error_from_errno (errno);
+              goto leave;
+            }
+          memset (sl, 0, sizeof *sl);
+          strcpy_escaped_plus (sl->d, line);
+          sl->next = list;
+          list = sl;
+        }
+    }
+
+  /* First look through the internal cache.  The certifcates retruned
+     here are not counted towards the truncation limit.  */
+  if (single && !cache_only)
+    ; /* Do not read from the local cache in this case.  */
+  else
+    {
+      for (sl=list; sl; sl = sl->next)
+        {
+          err = get_certs_bypattern (sl->d, return_one_cert, ctx);
+          if (!err)
+            local_count++;
+          if (!err && single)
+            goto ready;
+
+          if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+            {
+              err = 0;
+              if (cache_only)
+                any_no_data = 1;
+            }
+          else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
+            {
+              /* No real fault because the internal pattern lookup
+                 can't yet cope with all types of pattern.  */
+              err = 0;
+            }
+          if (err)
+            goto ready;
+        }
+    }
+
+  /* Loop over all configured servers unless we want only the
+     certificates from the cache.  */
+#if USE_LDAP
+  for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
+       !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
+        && ldapserver_iter.server->host && !truncation_forced;
+       ldapserver_iter_next (&ldapserver_iter))
+    {
+      ldap_server_t ldapserver = ldapserver_iter.server;
+
+      if (DBG_LOOKUP)
+        log_debug ("cmd_lookup: trying %s:%d base=%s\n",
+                   ldapserver->host, ldapserver->port,
+                   ldapserver->base?ldapserver->base : "[default]");
+
+      /* Fetch certificates matching pattern */
+      err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
+      if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
+        {
+          if (DBG_LOOKUP)
+            log_debug ("cmd_lookup: no data\n");
+          err = 0;
+          any_no_data = 1;
+          continue;
+        }
+      if (err)
+        {
+          log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
+          goto leave;
+        }
+
+      /* Fetch the certificates for this query. */
+      while (!truncation_forced)
+        {
+          xfree (value); value = NULL;
+          err = fetch_next_cert (fetch_context, &value, &valuelen);
+          if (gpg_err_code (err) == GPG_ERR_NO_DATA )
+            {
+              err = 0;
+              any_no_data = 1;
+              break; /* Ready. */
+            }
+          if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
+            {
+              truncated = 1;
+              err = 0;
+              break;  /* Ready.  */
+            }
+          if (gpg_err_code (err) == GPG_ERR_EOF)
+            {
+              err = 0;
+              break; /* Ready. */
+            }
+          if (!err && !value)
+            {
+              err = gpg_error (GPG_ERR_BUG);
+              goto leave;
+            }
+          if (err)
+            {
+              log_error (_("fetch_next_cert failed: %s\n"),
+                         gpg_strerror (err));
+              end_cert_fetch (fetch_context);
+              goto leave;
+            }
+
+          if (DBG_LOOKUP)
+            log_debug ("cmd_lookup: returning one cert%s\n",
+                       truncated? " (truncated)":"");
+
+          /* Send the data, flush the buffer and then send an END line
+             as a certificate delimiter. */
+          err = assuan_send_data (ctx, value, valuelen);
+          if (!err)
+            err = assuan_send_data (ctx, NULL, 0);
+          if (!err)
+            err = assuan_write_line (ctx, "END");
+          if (err)
+            {
+              log_error (_("error sending data: %s\n"), gpg_strerror (err));
+              end_cert_fetch (fetch_context);
+              goto leave;
+            }
+
+          if (++count >= opt.max_replies )
+            {
+              truncation_forced = 1;
+              log_info (_("max_replies %d exceeded\n"), opt.max_replies );
+            }
+          if (single)
+            break;
+        }
+
+      end_cert_fetch (fetch_context);
+    }
+#endif /*USE_LDAP*/
+
+ ready:
+  if (truncated || truncation_forced)
+    {
+      char str[50];
+
+      sprintf (str, "%d", count);
+      assuan_write_status (ctx, "TRUNCATED", str);
+    }
+
+  if (!err && !count && !local_count && any_no_data)
+    err = gpg_error (GPG_ERR_NO_DATA);
+
+ leave:
+  free_strlist (list);
+  return err;
+}
+
+
+static const char hlp_lookup[] =
+  "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
+  "\n"
+  "Lookup certificates matching PATTERN. With --url the pattern is\n"
+  "expected to be one URL.\n"
+  "\n"
+  "If --url is not given:  To allow for multiple patterns (which are ORed)\n"
+  "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
+  "obviously this requires that the usual escape quoting rules are applied.\n"
+  "\n"
+  "If --url is given no special escaping is required because URLs are\n"
+  "already escaped this way.\n"
+  "\n"
+  "If --single is given the first and only the first match will be\n"
+  "returned.  If --cache-only is _not_ given, no local query will be\n"
+  "done.\n"
+  "\n"
+  "If --cache-only is given no external lookup is done so that only\n"
+  "certificates from the cache may get returned.";
+static gpg_error_t
+cmd_lookup (assuan_context_t ctx, char *line)
+{
+  gpg_error_t err;
+  int lookup_url, single, cache_only;
+
+  lookup_url = has_leading_option (line, "--url");
+  single = has_leading_option (line, "--single");
+  cache_only = has_leading_option (line, "--cache-only");
+  line = skip_options (line);
+
+  if (lookup_url && cache_only)
+    err = gpg_error (GPG_ERR_NOT_FOUND);
+  else if (lookup_url && single)
+    err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  else if (lookup_url)
+    err = lookup_cert_by_url (ctx, line);
+  else
+    err = lookup_cert_by_pattern (ctx, line, single, cache_only);
+
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_loadcrl[] =
+  "LOADCRL [--url] <filename|url>\n"
+  "\n"
+  "Load the CRL in the file with name FILENAME into our cache.  Note\n"
+  "that FILENAME should be given with an absolute path because\n"
+  "Dirmngrs cwd is not known.  With --url the CRL is directly loaded\n"
+  "from the given URL.\n"
+  "\n"
+  "This command is usually used by gpgsm using the invocation \"gpgsm\n"
+  "--call-dirmngr loadcrl <filename>\".  A direct invocation of Dirmngr\n"
+  "is not useful because gpgsm might need to callback gpgsm to ask for\n"
+  "the CA's certificate.";
+static gpg_error_t
+cmd_loadcrl (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+  int use_url = has_leading_option (line, "--url");
+
+  line = skip_options (line);
+
+  if (use_url)
+    {
+      ksba_reader_t reader;
+
+      err = crl_fetch (ctrl, line, &reader);
+      if (err)
+        log_error (_("fetching CRL from '%s' failed: %s\n"),
+                   line, gpg_strerror (err));
+      else
+        {
+          err = crl_cache_insert (ctrl, line, reader);
+          if (err)
+            log_error (_("processing CRL from '%s' failed: %s\n"),
+                       line, gpg_strerror (err));
+          crl_close_reader (reader);
+        }
+    }
+  else
+    {
+      char *buf;
+
+      buf = xtrymalloc (strlen (line)+1);
+      if (!buf)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          strcpy_escaped_plus (buf, line);
+          err = crl_cache_load (ctrl, buf);
+          xfree (buf);
+        }
+    }
+
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_listcrls[] =
+  "LISTCRLS\n"
+  "\n"
+  "List the content of all CRLs in a readable format.  This command is\n"
+  "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
+  "listcrls\".  It may also be used directly using \"dirmngr\n"
+  "--list-crls\".";
+static gpg_error_t
+cmd_listcrls (assuan_context_t ctx, char *line)
+{
+  gpg_error_t err;
+  estream_t fp;
+
+  (void)line;
+
+  fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
+  if (!fp)
+    err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
+  else
+    {
+      err = crl_cache_list (fp);
+      es_fclose (fp);
+    }
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_cachecert[] =
+  "CACHECERT\n"
+  "\n"
+  "Put a certificate into the internal cache.  This command might be\n"
+  "useful if a client knows in advance certificates required for a\n"
+  "test and wants to make sure they get added to the internal cache.\n"
+  "It is also helpful for debugging.  To get the actual certificate,\n"
+  "this command immediately inquires it using\n"
+  "\n"
+  "  INQUIRE TARGETCERT\n"
+  "\n"
+  "and the caller is expected to return the certificate for the\n"
+  "request as a binary blob.";
+static gpg_error_t
+cmd_cachecert (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  ksba_cert_t cert = NULL;
+  unsigned char *value = NULL;
+  size_t valuelen;
+
+  (void)line;
+
+  err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
+                       &value, &valuelen, MAX_CERT_LENGTH);
+  if (err)
+    {
+      log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  if (!valuelen) /* No data returned; return a comprehensible error. */
+    err = gpg_error (GPG_ERR_MISSING_CERT);
+  else
+    {
+      err = ksba_cert_new (&cert);
+      if (!err)
+        err = ksba_cert_init_from_mem (cert, value, valuelen);
+    }
+  xfree (value);
+  if(err)
+    goto leave;
+
+  err = cache_cert (cert);
+
+ leave:
+  ksba_cert_release (cert);
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_validate[] =
+  "VALIDATE\n"
+  "\n"
+  "Validate a certificate using the certificate validation function\n"
+  "used internally by dirmngr.  This command is only useful for\n"
+  "debugging.  To get the actual certificate, this command immediately\n"
+  "inquires it using\n"
+  "\n"
+  "  INQUIRE TARGETCERT\n"
+  "\n"
+  "and the caller is expected to return the certificate for the\n"
+  "request as a binary blob.";
+static gpg_error_t
+cmd_validate (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  ksba_cert_t cert = NULL;
+  unsigned char *value = NULL;
+  size_t valuelen;
+
+  (void)line;
+
+  err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
+                       &value, &valuelen, MAX_CERT_LENGTH);
+  if (err)
+    {
+      log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  if (!valuelen) /* No data returned; return a comprehensible error. */
+    err = gpg_error (GPG_ERR_MISSING_CERT);
+  else
+    {
+      err = ksba_cert_new (&cert);
+      if (!err)
+        err = ksba_cert_init_from_mem (cert, value, valuelen);
+    }
+  xfree (value);
+  if(err)
+    goto leave;
+
+  /* If we have this certificate already in our cache, use the cached
+     version for validation because this will take care of any cached
+     results. */
+  {
+    unsigned char fpr[20];
+    ksba_cert_t tmpcert;
+
+    cert_compute_fpr (cert, fpr);
+    tmpcert = get_cert_byfpr (fpr);
+    if (tmpcert)
+      {
+        ksba_cert_release (cert);
+        cert = tmpcert;
+      }
+  }
+
+  err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
+
+ leave:
+  ksba_cert_release (cert);
+  return leave_cmd (ctx, err);
+}
+
+\f
+static const char hlp_keyserver[] =
+  "KEYSERVER [<options>] [<uri>|<host>]\n"
+  "Options are:\n"
+  "  --help\n"
+  "  --clear      Remove all configured keyservers\n"
+  "  --resolve    Resolve HKP host names and rotate\n"
+  "  --hosttable  Print table of known hosts and pools\n"
+  "  --dead       Mark <host> as dead\n"
+  "  --alive      Mark <host> as alive\n"
+  "\n"
+  "If called without arguments list all configured keyserver URLs.\n"
+  "If called with an URI add this as keyserver.  Note that keyservers\n"
+  "are configured on a per-session base.  A default keyserver may already be\n"
+  "present, thus the \"--clear\" option must be used to get full control.\n"
+  "If \"--clear\" and an URI are used together the clear command is\n"
+  "obviously executed first.  A RESET command does not change the list\n"
+  "of configured keyservers.";
+static gpg_error_t
+cmd_keyserver (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+  int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
+  int dead_flag, alive_flag;
+  uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
+                             is always initialized.  */
+
+  clear_flag = has_option (line, "--clear");
+  help_flag = has_option (line, "--help");
+  resolve_flag = has_option (line, "--resolve");
+  host_flag = has_option (line, "--hosttable");
+  dead_flag = has_option (line, "--dead");
+  alive_flag = has_option (line, "--alive");
+  line = skip_options (line);
+  add_flag = !!*line;
+
+  if (help_flag)
+    {
+      err = ks_action_help (ctrl, line);
+      goto leave;
+    }
+
+  if (resolve_flag)
+    {
+      err = ks_action_resolve (ctrl);
+      if (err)
+        goto leave;
+    }
+
+  if (alive_flag && dead_flag)
+    {
+      err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
+      goto leave;
+    }
+  if (dead_flag)
+    {
+      err = check_owner_permission (ctx, "no permission to use --dead");
+      if (err)
+        goto leave;
+    }
+  if (alive_flag || dead_flag)
+    {
+      if (!*line)
+        {
+          err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
+          goto leave;
+        }
+
+      err = ks_hkp_mark_host (ctrl, line, alive_flag);
+      if (err)
+        goto leave;
+    }
+
+  if (host_flag)
+    {
+      err = ks_hkp_print_hosttable (ctrl);
+      if (err)
+        goto leave;
+    }
+  if (resolve_flag || host_flag || alive_flag || dead_flag)
+    goto leave;
+
+  if (add_flag)
+    {
+      item = xtrymalloc (sizeof *item + strlen (line));
+      if (!item)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      item->next = NULL;
+      item->parsed_uri = NULL;
+      strcpy (item->uri, line);
+
+      err = http_parse_uri (&item->parsed_uri, line, 1);
+      if (err)
+        {
+          xfree (item);
+          goto leave;
+        }
+    }
+  if (clear_flag)
+    release_ctrl_keyservers (ctrl);
+  if (add_flag)
+    {
+      item->next = ctrl->keyservers;
+      ctrl->keyservers = item;
+    }
+
+  if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers.  */
+    {
+      uri_item_t u;
+
+      for (u=ctrl->keyservers; u; u = u->next)
+        dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
+    }
+  err = 0;
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_ks_search[] =
+  "KS_SEARCH {<pattern>}\n"
+  "\n"
+  "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
+  "for keys matching PATTERN";
+static gpg_error_t
+cmd_ks_search (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  strlist_t list, sl;
+  char *p;
+  estream_t outfp;
+
+  /* No options for now.  */
+  line = skip_options (line);
+
+  /* Break the line down into an strlist.  Each pattern is
+     percent-plus escaped. */
+  list = NULL;
+  for (p=line; *p; line = p)
+    {
+      while (*p && *p != ' ')
+        p++;
+      if (*p)
+        *p++ = 0;
+      if (*line)
+        {
+          sl = xtrymalloc (sizeof *sl + strlen (line));
+          if (!sl)
+            {
+              err = gpg_error_from_syserror ();
+              free_strlist (list);
+              goto leave;
+            }
+          sl->flags = 0;
+          strcpy_escaped_plus (sl->d, line);
+          sl->next = list;
+          list = sl;
+        }
+    }
+
+  /* Setup an output stream and perform the search.  */
+  outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
+  if (!outfp)
+    err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
+  else
+    {
+      err = ks_action_search (ctrl, list, outfp);
+      es_fclose (outfp);
+    }
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_ks_get[] =
+  "KS_GET {<pattern>}\n"
+  "\n"
+  "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
+  "(see command KEYSERVER).  Each pattern should be a keyid, a fingerprint,\n"
+  "or an exact name indicastes by the '=' prefix.";
+static gpg_error_t
+cmd_ks_get (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  strlist_t list, sl;
+  char *p;
+  estream_t outfp;
+
+  /* No options for now.  */
+  line = skip_options (line);
+
+  /* Break the line down into an strlist.  Each pattern is by
+     definition percent-plus escaped.  However we only support keyids
+     and fingerprints and thus the client has no need to apply the
+     escaping.  */
+  list = NULL;
+  for (p=line; *p; line = p)
+    {
+      while (*p && *p != ' ')
+        p++;
+      if (*p)
+        *p++ = 0;
+      if (*line)
+        {
+          sl = xtrymalloc (sizeof *sl + strlen (line));
+          if (!sl)
+            {
+              err = gpg_error_from_syserror ();
+              free_strlist (list);
+              goto leave;
+            }
+          sl->flags = 0;
+          strcpy_escaped_plus (sl->d, line);
+          sl->next = list;
+          list = sl;
+        }
+    }
+
+  /* Setup an output stream and perform the get.  */
+  outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
+  if (!outfp)
+    err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
+  else
+    {
+      err = ks_action_get (ctrl, list, outfp);
+      es_fclose (outfp);
+    }
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_ks_fetch[] =
+  "KS_FETCH <URL>\n"
+  "\n"
+  "Get the key(s) from URL.";
+static gpg_error_t
+cmd_ks_fetch (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  estream_t outfp;
+
+  /* No options for now.  */
+  line = skip_options (line);
+
+  /* Setup an output stream and perform the get.  */
+  outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
+  if (!outfp)
+    err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
+  else
+    {
+      err = ks_action_fetch (ctrl, line, outfp);
+      es_fclose (outfp);
+    }
+
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_ks_put[] =
+  "KS_PUT\n"
+  "\n"
+  "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
+  "is then requested by Dirmngr using\n"
+  "\n"
+  "  INQUIRE KEYBLOCK\n"
+  "\n"
+  "The client shall respond with a binary version of the keyblock.  For LDAP\n"
+  "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
+  "using:\n"
+  "\n"
+  "  INQUIRE KEYBLOCK_INFO\n"
+  "\n"
+  "The client shall respond with a colon delimited info lines";
+static gpg_error_t
+cmd_ks_put (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  unsigned char *value = NULL;
+  size_t valuelen;
+  unsigned char *info = NULL;
+  size_t infolen;
+
+  /* No options for now.  */
+  line = skip_options (line);
+
+  /* Ask for the key material.  */
+  err = assuan_inquire (ctx, "KEYBLOCK",
+                        &value, &valuelen, MAX_KEYBLOCK_LENGTH);
+  if (err)
+    {
+      log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  if (!valuelen) /* No data returned; return a comprehensible error. */
+    {
+      err = gpg_error (GPG_ERR_MISSING_CERT);
+      goto leave;
+    }
+
+  /* Ask for the key meta data. Not actually needed for HKP servers
+     but we do it anyway test the client implementaion.  */
+  err = assuan_inquire (ctx, "KEYBLOCK_INFO",
+                        &info, &infolen, MAX_KEYBLOCK_LENGTH);
+  if (err)
+    {
+      log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Send the key.  */
+  err = ks_action_put (ctrl, value, valuelen);
+
+ leave:
+  xfree (info);
+  xfree (value);
+  return leave_cmd (ctx, err);
+}
+
+
+
+\f
+static const char hlp_getinfo[] =
+  "GETINFO <what>\n"
+  "\n"
+  "Multi purpose command to return certain information.  \n"
+  "Supported values of WHAT are:\n"
+  "\n"
+  "version     - Return the version of the program.\n"
+  "pid         - Return the process id of the server.\n"
+  "\n"
+  "socket_name - Return the name of the socket.\n";
+static gpg_error_t
+cmd_getinfo (assuan_context_t ctx, char *line)
+{
+  gpg_error_t err;
+
+  if (!strcmp (line, "version"))
+    {
+      const char *s = VERSION;
+      err = assuan_send_data (ctx, s, strlen (s));
+    }
+  else if (!strcmp (line, "pid"))
+    {
+      char numbuf[50];
+
+      snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
+      err = assuan_send_data (ctx, numbuf, strlen (numbuf));
+    }
+  else if (!strcmp (line, "socket_name"))
+    {
+      const char *s = dirmngr_user_socket_name ();
+
+      if (!s)
+        s = dirmngr_sys_socket_name ();
+
+      if (s)
+        err = assuan_send_data (ctx, s, strlen (s));
+      else
+        err = gpg_error (GPG_ERR_NO_DATA);
+    }
+  else
+    err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
+
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+static const char hlp_killdirmngr[] =
+  "KILLDIRMNGR\n"
+  "\n"
+  "This command allows a user - given sufficient permissions -\n"
+  "to kill this dirmngr process.\n";
+static gpg_error_t
+cmd_killdirmngr (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+
+  (void)line;
+
+  if (opt.system_daemon)
+    {
+      if (opt.system_service)
+        err = set_error (GPG_ERR_NOT_SUPPORTED,
+                         "can't do that whilst running as system service");
+      else
+        err = check_owner_permission (ctx,
+                                      "no permission to kill this process");
+    }
+  else
+    err = 0;
+
+  if (!err)
+    {
+      ctrl->server_local->stopme = 1;
+      err = gpg_error (GPG_ERR_EOF);
+    }
+  return err;
+}
+
+
+static const char hlp_reloaddirmngr[] =
+  "RELOADDIRMNGR\n"
+  "\n"
+  "This command is an alternative to SIGHUP\n"
+  "to reload the configuration.";
+static gpg_error_t
+cmd_reloaddirmngr (assuan_context_t ctx, char *line)
+{
+  (void)ctx;
+  (void)line;
+
+ if (opt.system_daemon)
+    {
+#ifndef HAVE_W32_SYSTEM
+      {
+        gpg_err_code_t ec;
+        assuan_peercred_t cred;
+
+        ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
+        if (!ec && cred->uid)
+          ec = GPG_ERR_EPERM; /* Only root may terminate.  */
+        if (ec)
+          return set_error (ec, "no permission to reload this process");
+      }
+#endif
+    }
+
+  dirmngr_sighup_action ();
+  return 0;
+}
+
+
+
+\f
+/* Tell the assuan library about our commands. */
+static int
+register_commands (assuan_context_t ctx)
+{
+  static struct {
+    const char *name;
+    assuan_handler_t handler;
+    const char * const help;
+  } table[] = {
+    { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
+    { "ISVALID",    cmd_isvalid,    hlp_isvalid },
+    { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
+    { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
+    { "LOOKUP",     cmd_lookup,     hlp_lookup },
+    { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
+    { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
+    { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
+    { "VALIDATE",   cmd_validate,   hlp_validate },
+    { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
+    { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
+    { "KS_GET",     cmd_ks_get,     hlp_ks_get },
+    { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
+    { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
+    { "GETINFO",    cmd_getinfo,    hlp_getinfo },
+    { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
+    { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
+    { NULL, NULL }
+  };
+  int i, j, rc;
+
+  for (i=j=0; table[i].name; i++)
+    {
+      rc = assuan_register_command (ctx, table[i].name, table[i].handler,
+                                    table[i].help);
+      if (rc)
+        return rc;
+    }
+  return 0;
+}
+
+
+/* Note that we do not reset the list of configured keyservers.  */
+static gpg_error_t
+reset_notify (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  (void)line;
+
+#if USE_LDAP
+  ldapserver_list_free (ctrl->server_local->ldapservers);
+#endif /*USE_LDAP*/
+  ctrl->server_local->ldapservers = NULL;
+  return 0;
+}
+
+
+/* Startup the server and run the main command loop.  With FD = -1
+   used stdin/stdout. */
+void
+start_command_handler (assuan_fd_t fd)
+{
+  static const char hello[] = "Dirmngr " VERSION " at your service";
+  static char *hello_line;
+  int rc;
+  assuan_context_t ctx;
+  ctrl_t ctrl;
+
+  ctrl = xtrycalloc (1, sizeof *ctrl);
+  if (ctrl)
+    ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
+  if (!ctrl || !ctrl->server_local)
+    {
+      log_error (_("can't allocate control structure: %s\n"),
+                 strerror (errno));
+      xfree (ctrl);
+      return;
+    }
+
+  dirmngr_init_default_ctrl (ctrl);
+
+  rc = assuan_new (&ctx);
+  if (rc)
+    {
+      log_error (_("failed to allocate assuan context: %s\n"),
+                gpg_strerror (rc));
+      dirmngr_exit (2);
+    }
+
+  if (fd == ASSUAN_INVALID_FD)
+    {
+      assuan_fd_t filedes[2];
+
+      filedes[0] = assuan_fdopen (0);
+      filedes[1] = assuan_fdopen (1);
+      rc = assuan_init_pipe_server (ctx, filedes);
+    }
+  else
+    {
+      rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
+    }
+
+  if (rc)
+    {
+      assuan_release (ctx);
+      log_error (_("failed to initialize the server: %s\n"),
+                 gpg_strerror(rc));
+      dirmngr_exit (2);
+    }
+
+  rc = register_commands (ctx);
+  if (rc)
+    {
+      log_error (_("failed to the register commands with Assuan: %s\n"),
+                 gpg_strerror(rc));
+      dirmngr_exit (2);
+    }
+
+
+  if (!hello_line)
+    {
+      size_t n;
+      const char *cfgname;
+
+      cfgname = opt.config_filename? opt.config_filename : "[none]";
+
+      n = (30 + strlen (opt.homedir) + strlen (cfgname)
+           + strlen (hello) + 1);
+      hello_line = xmalloc (n+1);
+      snprintf (hello_line, n,
+                "Home: %s\n"
+                "Config: %s\n"
+                "%s",
+                opt.homedir,
+                cfgname,
+                hello);
+      hello_line[n] = 0;
+    }
+
+  ctrl->server_local->assuan_ctx = ctx;
+  assuan_set_pointer (ctx, ctrl);
+
+  assuan_set_hello_line (ctx, hello_line);
+  assuan_register_option_handler (ctx, option_handler);
+  assuan_register_reset_notify (ctx, reset_notify);
+
+  for (;;)
+    {
+      rc = assuan_accept (ctx);
+      if (rc == -1)
+        break;
+      if (rc)
+        {
+          log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
+          break;
+        }
+
+#ifndef HAVE_W32_SYSTEM
+      if (opt.verbose)
+        {
+         assuan_peercred_t peercred;
+
+          if (!assuan_get_peercred (ctx, &peercred))
+            log_info ("connection from process %ld (%ld:%ld)\n",
+                      (long)peercred->pid, (long)peercred->uid,
+                     (long)peercred->gid);
+        }
+#endif
+
+      rc = assuan_process (ctx);
+      if (rc)
+        {
+          log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
+          continue;
+        }
+    }
+
+#if USE_LDAP
+  ldap_wrapper_connection_cleanup (ctrl);
+
+  ldapserver_list_free (ctrl->server_local->ldapservers);
+#endif /*USE_LDAP*/
+  ctrl->server_local->ldapservers = NULL;
+
+  ctrl->server_local->assuan_ctx = NULL;
+  assuan_release (ctx);
+
+  if (ctrl->server_local->stopme)
+    dirmngr_exit (0);
+
+  if (ctrl->refcount)
+    log_error ("oops: connection control structure still referenced (%d)\n",
+               ctrl->refcount);
+  else
+    {
+      release_ctrl_ocsp_certs (ctrl);
+      xfree (ctrl->server_local);
+      xfree (ctrl);
+    }
+}
+
+
+/* Send a status line back to the client.  KEYWORD is the status
+   keyword, the optional string arguments are blank separated added to
+   the line, the last argument must be a NULL. */
+gpg_error_t
+dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
+{
+  gpg_error_t err = 0;
+  va_list arg_ptr;
+  const char *text;
+
+  va_start (arg_ptr, keyword);
+
+  if (ctrl->server_local)
+    {
+      assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+      char buf[950], *p;
+      size_t n;
+
+      p = buf;
+      n = 0;
+      while ( (text = va_arg (arg_ptr, const char *)) )
+        {
+          if (n)
+            {
+              *p++ = ' ';
+              n++;
+            }
+          for ( ; *text && n < DIM (buf)-2; n++)
+            *p++ = *text++;
+        }
+      *p = 0;
+      err = assuan_write_status (ctx, keyword, buf);
+    }
+
+  va_end (arg_ptr);
+  return err;
+}
+
+
+/* Print a help status line.  TEXTLEN gives the length of the text
+   from TEXT to be printed.  The function splits text at LFs.  */
+gpg_error_t
+dirmngr_status_help (ctrl_t ctrl, const char *text)
+{
+  gpg_error_t err = 0;
+
+  if (ctrl->server_local)
+    {
+      assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+      char buf[950], *p;
+      size_t n;
+
+      do
+        {
+          p = buf;
+          n = 0;
+          for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
+            *p++ = *text++;
+          if (*text == '\n')
+            text++;
+          *p = 0;
+          err = assuan_write_status (ctx, "#", buf);
+        }
+      while (!err && *text);
+    }
+
+  return err;
+}
+
+/* Send a tick progress indicator back.  Fixme: This is only done for
+   the currently active channel.  */
+gpg_error_t
+dirmngr_tick (ctrl_t ctrl)
+{
+  static time_t next_tick = 0;
+  gpg_error_t err = 0;
+  time_t now = time (NULL);
+
+  if (!next_tick)
+    {
+      next_tick = now + 1;
+    }
+  else if ( now > next_tick )
+    {
+      if (ctrl)
+        {
+          err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
+          if (err)
+            {
+              /* Take this as in indication for a cancel request.  */
+              err = gpg_error (GPG_ERR_CANCELED);
+            }
+          now = time (NULL);
+        }
+
+      next_tick = now + 1;
+    }
+  return err;
+}
diff --git a/dirmngr/sks-keyservers.netCA.pem b/dirmngr/sks-keyservers.netCA.pem
new file mode 100644 (file)
index 0000000..24a2ad2
--- /dev/null
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFizCCA3OgAwIBAgIJAK9zyLTPn4CPMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNV
+BAYTAk5PMQ0wCwYDVQQIDARPc2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5u
+ZXQgQ0ExHjAcBgNVBAMMFXNrcy1rZXlzZXJ2ZXJzLm5ldCBDQTAeFw0xMjEwMDkw
+MDMzMzdaFw0yMjEwMDcwMDMzMzdaMFwxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARP
+c2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5uZXQgQ0ExHjAcBgNVBAMMFXNr
+cy1rZXlzZXJ2ZXJzLm5ldCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBANdsWy4PXWNUCkS3L//nrd0GqN3dVwoBGZ6w94Tw2jPDPifegwxQozFXkG6I
+6A4TK1CJLXPvfz0UP0aBYyPmTNadDinaB9T4jIwd4rnxl+59GiEmqkN3IfPsv5Jj
+MkKUmJnvOT0DEVlEaO1UZIwx5WpfprB3mR81/qm4XkAgmYrmgnLXd/pJDAMk7y1F
+45b5zWofiD5l677lplcIPRbFhpJ6kDTODXh/XEdtF71EAeaOdEGOvyGDmCO0GWqS
+FDkMMPTlieLA/0rgFTcz4xwUYj/cD5e0ZBuSkYsYFAU3hd1cGfBue0cPZaQH2HYx
+Qk4zXD8S3F4690fRhr+tki5gyG6JDR67aKp3BIGLqm7f45WkX1hYp+YXywmEziM4
+aSbGYhx8hoFGfq9UcfPEvp2aoc8u5sdqjDslhyUzM1v3m3ZGbhwEOnVjljY6JJLx
+MxagxnZZSAY424ZZ3t71E/Mn27dm2w+xFRuoy8JEjv1d+BT3eChM5KaNwrj0IO/y
+u8kFIgWYA1vZ/15qMT+tyJTfyrNVV/7Df7TNeWyNqjJ5rBmt0M6NpHG7CrUSkBy9
+p8JhimgjP5r0FlEkgg+lyD+V79H98gQfVgP3pbJICz0SpBQf2F/2tyS4rLm+49rP
+fcOajiXEuyhpcmzgusAj/1FjrtlynH1r9mnNaX4e+rLWzvU5AgMBAAGjUDBOMB0G
+A1UdDgQWBBTkwyoJFGfYTVISTpM8E+igjdq28zAfBgNVHSMEGDAWgBTkwyoJFGfY
+TVISTpM8E+igjdq28zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQAR
+OXnYwu3g1ZjHyley3fZI5aLPsaE17cOImVTehC8DcIphm2HOMR/hYTTL+V0G4P+u
+gH+6xeRLKSHMHZTtSBIa6GDL03434y9CBuwGvAFCMU2GV8w92/Z7apkAhdLToZA/
+X/iWP2jeaVJhxgEcH8uPrnSlqoPBcKC9PrgUzQYfSZJkLmB+3jEa3HKruy1abJP5
+gAdQvwvcPpvYRnIzUc9fZODsVmlHVFBCl2dlu/iHh2h4GmL4Da2rRkUMlbVTdioB
+UYIvMycdOkpH5wJftzw7cpjsudGas0PARDXCFfGyKhwBRFY7Xp7lbjtU5Rz0Gc04
+lPrhDf0pFE98Aw4jJRpFeWMjpXUEaG1cq7D641RpgcMfPFvOHY47rvDTS7XJOaUT
+BwRjmDt896s6vMDcaG/uXJbQjuzmmx3W2Idyh3s5SI0GTHb0IwMKYb4eBUIpQOnB
+cE77VnCYqKvN1NVYAqhWjXbY7XasZvszCRcOG+W3FqNaHOK/n/0ueb0uijdLan+U
+f4p1bjbAox8eAOQS/8a3bzkJzdyBNUKGx1BIK2IBL9bn/HravSDOiNRSnZ/R3l9G
+ZauX0tu7IIDlRCILXSyeazu0aj/vdT3YFQXPcvt5Fkf5wiNTo53f72/jYEJd6qph
+WrpoKqrwGwTpRUCMhYIUt65hsTxCiJJ5nKe39h46sg==
+-----END CERTIFICATE-----
diff --git a/dirmngr/validate.c b/dirmngr/validate.c
new file mode 100644 (file)
index 0000000..574eca6
--- /dev/null
@@ -0,0 +1,1159 @@
+/* validate.c - Validate a certificate chain.
+ * Copyright (C) 2001, 2003, 2004, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2006, 2008 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 <errno.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "dirmngr.h"
+#include "certcache.h"
+#include "crlcache.h"
+#include "validate.h"
+#include "misc.h"
+
+/* While running the validation function we need to keep track of the
+   certificates and the validation outcome of each.  We use this type
+   for it.  */
+struct chain_item_s
+{
+  struct chain_item_s *next;
+  ksba_cert_t cert;      /* The certificate.  */
+  unsigned char fpr[20]; /* Fingerprint of the certificate.  */
+  int is_self_signed;    /* This certificate is self-signed.  */
+  int is_valid;          /* The certifiate is valid except for revocations.  */
+};
+typedef struct chain_item_s *chain_item_t;
+
+
+/* A couple of constants with Object Identifiers.  */
+static const char oid_kp_serverAuth[]     = "1.3.6.1.5.5.7.3.1";
+static const char oid_kp_clientAuth[]     = "1.3.6.1.5.5.7.3.2";
+static const char oid_kp_codeSigning[]    = "1.3.6.1.5.5.7.3.3";
+static const char oid_kp_emailProtection[]= "1.3.6.1.5.5.7.3.4";
+static const char oid_kp_timeStamping[]   = "1.3.6.1.5.5.7.3.8";
+static const char oid_kp_ocspSigning[]    = "1.3.6.1.5.5.7.3.9";
+
+
+/* Prototypes.  */
+static gpg_error_t check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert);
+
+
+
+
+/* Check whether CERT contains critical extensions we don't know
+   about.  */
+static gpg_error_t
+unknown_criticals (ksba_cert_t cert)
+{
+  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 */
+    NULL
+  };
+  int i, idx, crit;
+  const char *oid;
+  int unsupported;
+  strlist_t sl;
+  gpg_error_t err, rc;
+
+  rc = 0;
+  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++)
+        ;
+      unsupported = !known[i];
+
+      /* If this critical extension is not supported, check the list
+         of to be ignored extensions to see whether we claim that it
+         is supported.  */
+      if (unsupported && opt.ignored_cert_extensions)
+        {
+          for (sl=opt.ignored_cert_extensions;
+               sl && strcmp (sl->d, oid); sl = sl->next)
+            ;
+          if (sl)
+            unsupported = 0;
+        }
+
+      if (unsupported)
+        {
+          log_error (_("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; /* Such an error takes precendence.  */
+
+  return rc;
+}
+
+
+/* Basic check for supported policies.  */
+static gpg_error_t
+check_cert_policy (ksba_cert_t cert)
+{
+  static const char *allowed[] = {
+    "2.289.9.9",
+    NULL
+  };
+  gpg_error_t err;
+  int idx;
+  char *p, *haystack;
+  char *policies;
+  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)
+    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");
+
+  /* See whether we find ALLOWED (which is an OID) in POLICIES */
+  for (idx=0; allowed[idx]; idx++)
+    {
+      for (haystack=policies; (p=strstr (haystack, allowed[idx]));
+           haystack = p+1)
+        {
+          if ( !(p == policies || p[-1] == '\n') )
+            continue; /* Does not match the begin of a line. */
+          if (p[strlen (allowed[idx])] != ':')
+            continue; /* The length does not match. */
+          /* Yep - it does match: Return okay. */
+          ksba_free (policies);
+          return 0;
+        }
+    }
+
+  if (!any_critical)
+    {
+      log_info (_("Note: non-critical certificate policy not allowed"));
+      err = 0;
+    }
+  else
+    {
+      log_info (_("certificate policy not allowed"));
+      err = gpg_error (GPG_ERR_NO_POLICY_MATCH);
+    }
+
+  ksba_free (policies);
+  return err;
+}
+
+
+static gpg_error_t
+allowed_ca (ksba_cert_t cert, int *chainlen)
+{
+  gpg_error_t err;
+  int flag;
+
+  err = ksba_cert_is_ca (cert, &flag, chainlen);
+  if (err)
+    return err;
+  if (!flag)
+    {
+      if (!is_trusted_cert (cert))
+        {
+          /* The German SigG Root CA's certificate does not flag
+             itself as a CA; thus we relax this requirement if we
+             trust a root CA.  I think this is reasonable.  Note, that
+             gpgsm implements a far stricter scheme here. */
+          if (chainlen)
+            *chainlen = 3; /* That is what the SigG implements. */
+          if (opt.verbose)
+            log_info (_("accepting root CA not marked as a CA"));
+        }
+      else
+        {
+          log_error (_("issuer certificate is not marked as a CA"));
+          return gpg_error (GPG_ERR_BAD_CA_CERT);
+        }
+    }
+  return 0;
+}
+
+/* Helper for validate_cert_chain.  */
+static gpg_error_t
+check_revocations (ctrl_t ctrl, chain_item_t chain)
+{
+  gpg_error_t err = 0;
+  int any_revoked = 0;
+  int any_no_crl = 0;
+  int any_crl_too_old = 0;
+  chain_item_t ci;
+
+  assert (ctrl->check_revocations_nest_level >= 0);
+  assert (chain);
+
+  if (ctrl->check_revocations_nest_level > 10)
+    {
+      log_error (_("CRL checking too deeply nested\n"));
+      return gpg_error(GPG_ERR_BAD_CERT_CHAIN);
+    }
+  ctrl->check_revocations_nest_level++;
+
+
+  for (ci=chain; ci; ci = ci->next)
+    {
+      assert (ci->cert);
+      if (ci == chain)
+        {
+          /* It does not make sense to check the root certificate for
+             revocations.  In almost all cases this will lead to a
+             catch-22 as the root certificate is the final trust
+             anchor for the certificates and the CRLs.  We expect the
+             user to remove root certificates from the list of trusted
+             certificates in case they have been revoked. */
+          if (opt.verbose)
+            cert_log_name (_("not checking CRL for"), ci->cert);
+          continue;
+        }
+
+      if (opt.verbose)
+        cert_log_name (_("checking CRL for"), ci->cert);
+      err = crl_cache_cert_isvalid (ctrl, ci->cert, 0);
+      if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
+        {
+          err = crl_cache_reload_crl (ctrl, ci->cert);
+          if (!err)
+            err = crl_cache_cert_isvalid (ctrl, ci->cert, 0);
+        }
+      switch (gpg_err_code (err))
+        {
+        case 0: err = 0; break;
+        case GPG_ERR_CERT_REVOKED: any_revoked = 1; err = 0; break;
+        case GPG_ERR_NO_CRL_KNOWN: any_no_crl = 1; err = 0; break;
+        case GPG_ERR_CRL_TOO_OLD: any_crl_too_old = 1; err = 0; break;
+        default: break;
+        }
+    }
+  ctrl->check_revocations_nest_level--;
+
+
+  if (err)
+    ;
+  else if (any_revoked)
+    err = gpg_error (GPG_ERR_CERT_REVOKED);
+  else if (any_no_crl)
+    err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+  else if (any_crl_too_old)
+    err = gpg_error (GPG_ERR_CRL_TOO_OLD);
+  else
+    err = 0;
+  return err;
+}
+
+
+/* Check whether CERT is a root certificate.  ISSUERDN and SUBJECTDN
+   are the DNs already extracted by the caller from CERT.  Returns
+   True if this is the case. */
+static int
+is_root_cert (ksba_cert_t cert, const char *issuerdn, const char *subjectdn)
+{
+  gpg_error_t err;
+  int result = 0;
+  ksba_sexp_t serialno;
+  ksba_sexp_t ak_keyid;
+  ksba_name_t ak_name;
+  ksba_sexp_t ak_sn;
+  const char *ak_name_str;
+  ksba_sexp_t subj_keyid = NULL;
+
+  if (!issuerdn || !subjectdn)
+    return 0;  /* No.  */
+
+  if (strcmp (issuerdn, subjectdn))
+    return 0;  /* No.  */
+
+  err = ksba_cert_get_auth_key_id (cert, &ak_keyid, &ak_name, &ak_sn);
+  if (err)
+    {
+      if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+        return 1; /* Yes. Without a authorityKeyIdentifier this needs
+                     to be the Root certifcate (our trust anchor).  */
+      log_error ("error getting authorityKeyIdentifier: %s\n",
+                 gpg_strerror (err));
+      return 0; /* Well, it is broken anyway.  Return No. */
+    }
+
+  serialno = ksba_cert_get_serial (cert);
+  if (!serialno)
+    {
+      log_error ("error getting serialno: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Check whether the auth name's matches the issuer name+sn.  If
+     that is the case this is a root certificate.  */
+  ak_name_str = ksba_name_enum (ak_name, 0);
+  if (ak_name_str
+      && !strcmp (ak_name_str, issuerdn)
+      && !cmp_simple_canon_sexp (ak_sn, serialno))
+    {
+      result = 1;  /* Right, CERT is self-signed.  */
+      goto leave;
+    }
+
+  /* Similar for the ak_keyid. */
+  if (ak_keyid && !ksba_cert_get_subj_key_id (cert, NULL, &subj_keyid)
+      && !cmp_simple_canon_sexp (ak_keyid, subj_keyid))
+    {
+      result = 1;  /* Right, CERT is self-signed.  */
+      goto leave;
+    }
+
+
+ leave:
+  ksba_free (subj_keyid);
+  ksba_free (ak_keyid);
+  ksba_name_release (ak_name);
+  ksba_free (ak_sn);
+  ksba_free (serialno);
+  return result;
+}
+
+
+/* Validate the certificate CHAIN up to the trust anchor. Optionally
+   return the closest expiration time in R_EXPTIME (this is useful for
+   caching issues).  MODE is one of the VALIDATE_MODE_* constants.
+
+   If R_TRUST_ANCHOR is not NULL and the validation would fail only
+   because the root certificate is not trusted, the hexified
+   fingerprint of that root certificate is stored at R_TRUST_ANCHOR
+   and success is returned.  The caller needs to free the value at
+   R_TRUST_ANCHOR; in all other cases NULL is stored there.  */
+gpg_error_t
+validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
+                     int mode, char **r_trust_anchor)
+{
+  gpg_error_t err = 0;
+  int depth, maxdepth;
+  char *issuer = NULL;
+  char *subject = NULL;
+  ksba_cert_t subject_cert = NULL, issuer_cert = NULL;
+  ksba_isotime_t current_time;
+  ksba_isotime_t exptime;
+  int any_expired = 0;
+  int any_no_policy_match = 0;
+  chain_item_t chain;
+
+
+  if (r_exptime)
+    *r_exptime = 0;
+  *exptime = 0;
+
+  if (r_trust_anchor)
+    *r_trust_anchor = NULL;
+
+  if (!opt.system_daemon)
+    {
+      /* For backward compatibility we only do this in daemon mode.  */
+      log_info (_("running in compatibility mode - "
+                  "certificate chain not checked!\n"));
+      return 0; /* Okay. */
+    }
+
+  if (DBG_X509)
+    dump_cert ("subject", cert);
+
+  /* May the target certificate be used for this purpose?  */
+  switch (mode)
+    {
+    case VALIDATE_MODE_OCSP:
+      err = cert_use_ocsp_p (cert);
+      break;
+    case VALIDATE_MODE_CRL:
+    case VALIDATE_MODE_CRL_RECURSIVE:
+      err = cert_use_crl_p (cert);
+      break;
+    default:
+      err = 0;
+      break;
+    }
+  if (err)
+    return err;
+
+  /* If we already validated the certificate not too long ago, we can
+     avoid the excessive computations and lookups unless the caller
+     asked for the expiration time.  */
+  if (!r_exptime)
+    {
+      size_t buflen;
+      time_t validated_at;
+
+      err = ksba_cert_get_user_data (cert, "validated_at",
+                                     &validated_at, sizeof (validated_at),
+                                     &buflen);
+      if (err || buflen != sizeof (validated_at) || !validated_at)
+        err = 0; /* Not available or other error. */
+      else
+        {
+          /* If the validation is not older than 30 minutes we are ready. */
+          if (validated_at < gnupg_get_time () + (30*60))
+            {
+              if (opt.verbose)
+                log_info ("certificate is good (cached)\n");
+              /* Note, that we can't jump to leave here as this would
+                 falsely updated the validation timestamp.  */
+              return 0;
+            }
+        }
+    }
+
+  /* Get the current time. */
+  gnupg_get_isotime (current_time);
+
+  /* We walk up the chain until we find a trust anchor. */
+  subject_cert = cert;
+  maxdepth = 10;
+  chain = NULL;
+  depth = 0;
+  for (;;)
+    {
+      /* Get the subject and issuer name from the current
+         certificate.  */
+      ksba_free (issuer);
+      ksba_free (subject);
+      issuer = ksba_cert_get_issuer (subject_cert, 0);
+      subject = ksba_cert_get_subject (subject_cert, 0);
+
+      if (!issuer)
+        {
+          log_error (_("no issuer found in certificate\n"));
+          err = gpg_error (GPG_ERR_BAD_CERT);
+          goto leave;
+        }
+
+      /* Handle the notBefore and notAfter timestamps.  */
+      {
+        ksba_isotime_t not_before, not_after;
+
+        err = ksba_cert_get_validity (subject_cert, 0, not_before);
+        if (!err)
+          err = ksba_cert_get_validity (subject_cert, 1, not_after);
+        if (err)
+          {
+            log_error (_("certificate with invalid validity: %s"),
+                       gpg_strerror (err));
+            err = gpg_error (GPG_ERR_BAD_CERT);
+            goto leave;
+          }
+
+        /* Keep track of the nearest expiration time in EXPTIME.  */
+        if (*not_after)
+          {
+            if (!*exptime)
+              gnupg_copy_time (exptime, not_after);
+            else if (strcmp (not_after, exptime) < 0 )
+              gnupg_copy_time (exptime, not_after);
+          }
+
+        /* Check whether the certificate is already valid.  */
+        if (*not_before && strcmp (current_time, not_before) < 0 )
+          {
+            log_error (_("certificate not yet valid"));
+            log_info ("(valid from ");
+            dump_isotime (not_before);
+            log_printf (")\n");
+            err = gpg_error (GPG_ERR_CERT_TOO_YOUNG);
+            goto leave;
+          }
+
+        /* Now check whether the certificate has expired.  */
+        if (*not_after && strcmp (current_time, not_after) > 0 )
+          {
+            log_error (_("certificate has expired"));
+            log_info ("(expired at ");
+            dump_isotime (not_after);
+            log_printf (")\n");
+            any_expired = 1;
+          }
+      }
+
+      /* Do we have any critical extensions in the certificate we
+         can't handle? */
+      err = unknown_criticals (subject_cert);
+      if (err)
+        goto leave; /* yes. */
+
+      /* Check that given policies are allowed.  */
+      err = check_cert_policy (subject_cert);
+      if (gpg_err_code (err) == GPG_ERR_NO_POLICY_MATCH)
+        {
+          any_no_policy_match = 1;
+          err = 0;
+        }
+      else if (err)
+        goto leave;
+
+      /* Is this a self-signed certificate? */
+      if (is_root_cert ( subject_cert, issuer, subject))
+        {
+          /* Yes, this is our trust anchor.  */
+          if (check_cert_sig (subject_cert, subject_cert) )
+            {
+              log_error (_("selfsigned certificate has a BAD signature"));
+              err = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN
+                                    : GPG_ERR_BAD_CERT);
+              goto leave;
+            }
+
+          /* Is this certificate allowed to act as a CA.  */
+          err = allowed_ca (subject_cert, NULL);
+          if (err)
+            goto leave;  /* No. */
+
+          err = is_trusted_cert (subject_cert);
+          if (!err)
+            ; /* Yes we trust this cert.  */
+          else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED)
+            {
+              char *fpr;
+
+              log_error (_("root certificate is not marked trusted"));
+              fpr = get_fingerprint_hexstring (subject_cert);
+              log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
+              dump_cert ("issuer", subject_cert);
+              if (r_trust_anchor)
+                {
+                  /* Caller wants to do another trustiness check.  */
+                  *r_trust_anchor = fpr;
+                  err = 0;
+                }
+              else
+                xfree (fpr);
+            }
+          else
+            {
+              log_error (_("checking trustworthiness of "
+                           "root certificate failed: %s\n"),
+                         gpg_strerror (err));
+            }
+          if (err)
+            goto leave;
+
+          /* Prepend the certificate to our list.  */
+          {
+            chain_item_t ci;
+
+            ci = xtrycalloc (1, sizeof *ci);
+            if (!ci)
+              {
+                err = gpg_error_from_errno (errno);
+                goto leave;
+              }
+            ksba_cert_ref (subject_cert);
+            ci->cert = subject_cert;
+            cert_compute_fpr (subject_cert, ci->fpr);
+            ci->next = chain;
+            chain = ci;
+          }
+
+          if (opt.verbose)
+            {
+              if (r_trust_anchor && *r_trust_anchor)
+                log_info ("root certificate is good but not trusted\n");
+              else
+                log_info ("root certificate is good and trusted\n");
+            }
+
+          break;  /* Okay: a self-signed certicate is an end-point. */
+        }
+
+      /* To avoid loops, we use an arbitary limit on the length of
+         the chain. */
+      depth++;
+      if (depth > maxdepth)
+        {
+          log_error (_("certificate chain too long\n"));
+          err = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
+          goto leave;
+        }
+
+      /* Find the next cert up the tree. */
+      ksba_cert_release (issuer_cert); issuer_cert = NULL;
+      err = find_issuing_cert (ctrl, subject_cert, &issuer_cert);
+      if (err)
+        {
+          if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+            {
+              log_error (_("issuer certificate not found"));
+              log_info ("issuer certificate: #/");
+              dump_string (issuer);
+              log_printf ("\n");
+            }
+          else
+            log_error (_("issuer certificate not found: %s\n"),
+                         gpg_strerror (err));
+          /* Use a better understandable error code.  */
+          err = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
+          goto leave;
+        }
+
+/*     try_another_cert: */
+      if (DBG_X509)
+        {
+          log_debug ("got issuer's certificate:\n");
+          dump_cert ("issuer", issuer_cert);
+        }
+
+      /* Now check the signature of the certificate.  Well, we
+         should delay this until later so that faked certificates
+         can't be turned into a DoS easily.  */
+      err = check_cert_sig (issuer_cert, subject_cert);
+      if (err)
+        {
+          log_error (_("certificate has a BAD signature"));
+#if 0
+          if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
+            {
+              /* We now try to find other issuer certificates which
+                 might have been used.  This is required because some
+                 CAs are reusing the issuer and subject DN for new
+                 root certificates without using a  authorityKeyIdentifier. */
+              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;
+                    }
+                }
+            }
+#endif
+          /* We give a more descriptive error code than the one
+             returned from the signature checking. */
+          err = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
+          goto leave;
+        }
+
+      /* Check that the length of the chain is not longer than allowed
+         by the CA.  */
+      {
+        int chainlen;
+
+        err = allowed_ca (issuer_cert, &chainlen);
+        if (err)
+          goto leave;
+        if (chainlen >= 0 && (depth - 1) > chainlen)
+          {
+            log_error (_("certificate chain longer than allowed by CA (%d)"),
+                       chainlen);
+            err = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
+            goto leave;
+          }
+      }
+
+      /* May that certificate be used for certification? */
+      err = cert_use_cert_p (issuer_cert);
+      if (err)
+        goto leave;  /* No.  */
+
+      /* Prepend the certificate to our list.  */
+      {
+        chain_item_t ci;
+
+        ci = xtrycalloc (1, sizeof *ci);
+        if (!ci)
+          {
+            err = gpg_error_from_errno (errno);
+            goto leave;
+          }
+        ksba_cert_ref (subject_cert);
+        ci->cert = subject_cert;
+        cert_compute_fpr (subject_cert, ci->fpr);
+        ci->next = chain;
+        chain = ci;
+      }
+
+      if (opt.verbose)
+        log_info (_("certificate is good\n"));
+
+      /* Now to the next level up.  */
+      subject_cert = issuer_cert;
+      issuer_cert = NULL;
+    }
+
+  if (!err)
+    { /* If we encountered an error somewhere during the checks, set
+         the error code to the most critical one */
+      if (any_expired)
+        err = gpg_error (GPG_ERR_CERT_EXPIRED);
+      else if (any_no_policy_match)
+        err = gpg_error (GPG_ERR_NO_POLICY_MATCH);
+    }
+
+  if (!err && opt.verbose)
+    {
+      chain_item_t citem;
+
+      log_info (_("certificate chain is good\n"));
+      for (citem = chain; citem; citem = citem->next)
+        cert_log_name ("  certificate", citem->cert);
+    }
+
+  if (!err && mode != VALIDATE_MODE_CRL)
+    { /* Now that everything is fine, walk the chain and check each
+         certificate for revocations.
+
+         1. item in the chain  - The root certificate.
+         2. item               - the CA below the root
+         last item             - the target certificate.
+
+         Now for each certificate in the chain check whether it has
+         been included in a CRL and thus be revoked.  We don't do OCSP
+         here because this does not seem to make much sense.  This
+         might become a recursive process and we should better cache
+         our validity results to avoid double work.  Far worse a
+         catch-22 may happen for an improper setup hierachy and we
+         need a way to break up such a deadlock. */
+      err = check_revocations (ctrl, chain);
+    }
+
+  if (!err && opt.verbose)
+    {
+      if (r_trust_anchor && *r_trust_anchor)
+        log_info ("target certificate may be valid\n");
+      else
+        log_info ("target certificate is valid\n");
+    }
+  else if (err && opt.verbose)
+    log_info ("target certificate is NOT valid\n");
+
+
+ leave:
+  if (!err && !(r_trust_anchor && *r_trust_anchor))
+    {
+      /* With no error we can update the validation cache.  We do this
+         for all certificates in the chain.  Note that we can't use
+         the cache if the caller requested to check the trustiness of
+         the root certificate himself.  Adding such a feature would
+         require us to also store the fingerprint of root
+         certificate.  */
+      chain_item_t citem;
+      time_t validated_at = gnupg_get_time ();
+
+      for (citem = chain; citem; citem = citem->next)
+        {
+          err = ksba_cert_set_user_data (citem->cert, "validated_at",
+                                         &validated_at, sizeof (validated_at));
+          if (err)
+            {
+              log_error ("set_user_data(validated_at) failed: %s\n",
+                         gpg_strerror (err));
+              err = 0;
+            }
+        }
+    }
+
+  if (r_exptime)
+    gnupg_copy_time (r_exptime, exptime);
+  ksba_free (issuer);
+  ksba_free (subject);
+  ksba_cert_release (issuer_cert);
+  if (subject_cert != cert)
+    ksba_cert_release (subject_cert);
+  while (chain)
+    {
+      chain_item_t ci_next = chain->next;
+      if (chain->cert)
+        ksba_cert_release (chain->cert);
+      xfree (chain);
+      chain = ci_next;
+    }
+  if (err && r_trust_anchor && *r_trust_anchor)
+    {
+      xfree (*r_trust_anchor);
+      *r_trust_anchor = NULL;
+    }
+  return err;
+}
+
+
+\f
+/* 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. */
+static gpg_error_t
+check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
+{
+  gpg_error_t err;
+  const char *algoid;
+  gcry_md_hd_t md;
+  int i, algo;
+  ksba_sexp_t p;
+  size_t n;
+  gcry_sexp_t s_sig, s_hash, s_pkey;
+  const char *s;
+  char algo_name[16+1]; /* hash algorithm name converted to lower case. */
+  int digestlen;
+  unsigned char *digest;
+
+  /* Hash the target certificate using the algorithm from that certificate.  */
+  algoid = ksba_cert_get_digest_algo (cert);
+  algo = gcry_md_map_name (algoid);
+  if (!algo)
+    {
+      log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+  s = gcry_md_algo_name (algo);
+  for (i=0; *s && i < sizeof algo_name - 1; s++, i++)
+    algo_name[i] = tolower (*s);
+  algo_name[i] = 0;
+
+  err = gcry_md_open (&md, algo, 0);
+  if (err)
+    {
+      log_error ("md_open failed: %s\n", gpg_strerror (err));
+      return err;
+    }
+  if (DBG_HASHING)
+    gcry_md_debug (md, "hash.cert");
+
+  err = ksba_cert_hash (cert, 1, HASH_FNC, md);
+  if (err)
+    {
+      log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (err));
+      gcry_md_close (md);
+      return err;
+    }
+  gcry_md_final (md);
+
+  /* Get the signature value out of the target certificate.  */
+  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_CRYPTO)
+    {
+      int j;
+      log_debug ("signature value:");
+      for (j=0; j < n; j++)
+        log_printf (" %02X", p[j]);
+      log_printf ("\n");
+    }
+
+  err = gcry_sexp_sscan ( &s_sig, NULL, p, n);
+  ksba_free (p);
+  if (err)
+    {
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (err));
+      gcry_md_close (md);
+      return err;
+    }
+
+  /* Get the public key from the issuer certificate.  */
+  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);
+    }
+  err = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
+  ksba_free (p);
+  if (err)
+    {
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (err));
+      gcry_md_close (md);
+      gcry_sexp_release (s_sig);
+      return err;
+    }
+
+
+  /* Prepare the values for signature verification. At this point we
+     have these values:
+
+     S_PKEY    - S-expression with the issuer's public key.
+     S_SIG     - Signature value as given in the certrificate.
+     MD        - Finalized hash context with hash of the certificate.
+     ALGO_NAME - Lowercase hash algorithm name
+   */
+  digestlen = gcry_md_get_algo_dlen (algo);
+  digest = gcry_md_read (md, algo);
+  if (pk_algo_from_sexp (s_pkey) == GCRY_PK_DSA)
+    {
+      if (digestlen != 20)
+        {
+          log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
+          gcry_md_close (md);
+          gcry_sexp_release (s_sig);
+          gcry_sexp_release (s_pkey);
+          return gpg_error (GPG_ERR_INTERNAL);
+        }
+      if ( gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))",
+                            (int)digestlen, digest) )
+        BUG ();
+    }
+  else /* Not DSA.  */
+    {
+      if ( gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))",
+                            algo_name, (int)digestlen, digest) )
+        BUG ();
+
+    }
+
+  err = gcry_pk_verify (s_sig, s_hash, s_pkey);
+  if (DBG_X509)
+    log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
+  gcry_md_close (md);
+  gcry_sexp_release (s_sig);
+  gcry_sexp_release (s_hash);
+  gcry_sexp_release (s_pkey);
+  return err;
+}
+
+
+\f
+/* Return 0 if the cert is usable for encryption.  A MODE of 0 checks
+   for signing, a MODE of 1 checks for encryption, a MODE of 2 checks
+   for verification and a MODE of 3 for decryption (just for
+   debugging).  MODE 4 is for certificate signing, MODE 5 for OCSP
+   response signing, MODE 6 is for CRL signing. */
+static int
+cert_usage_p (ksba_cert_t cert, int mode)
+{
+  gpg_error_t err;
+  unsigned int use;
+  char *extkeyusages;
+  int have_ocsp_signing = 0;
+
+  err = ksba_cert_get_ext_key_usages (cert, &extkeyusages);
+  if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+    err = 0; /* No policy given. */
+  if (!err)
+    {
+      unsigned int extusemask = ~0; /* Allow all. */
+
+      if (extkeyusages)
+        {
+          char *p, *pend;
+          int any_critical = 0;
+
+          extusemask = 0;
+
+          p = extkeyusages;
+          while (p && (pend=strchr (p, ':')))
+            {
+              *pend++ = 0;
+              /* Only care about critical flagged usages. */
+              if ( *pend == 'C' )
+                {
+                  any_critical = 1;
+                  if ( !strcmp (p, oid_kp_serverAuth))
+                    extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
+                                   | KSBA_KEYUSAGE_KEY_ENCIPHERMENT
+                                   | KSBA_KEYUSAGE_KEY_AGREEMENT);
+                  else if ( !strcmp (p, oid_kp_clientAuth))
+                    extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
+                                   | KSBA_KEYUSAGE_KEY_AGREEMENT);
+                  else if ( !strcmp (p, oid_kp_codeSigning))
+                    extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE);
+                  else if ( !strcmp (p, oid_kp_emailProtection))
+                    extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
+                                   | KSBA_KEYUSAGE_NON_REPUDIATION
+                                   | KSBA_KEYUSAGE_KEY_ENCIPHERMENT
+                                   | KSBA_KEYUSAGE_KEY_AGREEMENT);
+                  else if ( !strcmp (p, oid_kp_timeStamping))
+                    extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
+                                   | KSBA_KEYUSAGE_NON_REPUDIATION);
+                }
+
+              /* This is a hack to cope with OCSP.  Note that we do
+                 not yet fully comply with the requirements and that
+                 the entire CRL/OCSP checking thing should undergo a
+                 thorough review and probably redesign. */
+              if ( !strcmp (p, oid_kp_ocspSigning))
+                have_ocsp_signing = 1;
+
+              if ((p = strchr (pend, '\n')))
+                p++;
+            }
+          ksba_free (extkeyusages);
+          extkeyusages = NULL;
+
+          if (!any_critical)
+            extusemask = ~0; /* Reset to the don't care mask. */
+        }
+
+
+      err = ksba_cert_get_key_usage (cert, &use);
+      if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+        {
+          err = 0;
+          if (opt.verbose && mode < 2)
+            log_info (_("no key usage specified - assuming all usages\n"));
+          use = ~0;
+        }
+
+      /* Apply extKeyUsage. */
+      use &= extusemask;
+
+    }
+  if (err)
+    {
+      log_error (_("error getting key usage information: %s\n"),
+                 gpg_strerror (err));
+      ksba_free (extkeyusages);
+      return err;
+    }
+
+  if (mode == 4)
+    {
+      if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN)))
+        return 0;
+      log_info (_("certificate should not have "
+                  "been used for certification\n"));
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
+
+  if (mode == 5)
+    {
+      if (use != ~0
+          && (have_ocsp_signing
+              || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN
+                         |KSBA_KEYUSAGE_CRL_SIGN))))
+        return 0;
+      log_info (_("certificate should not have "
+                  "been used for OCSP response signing\n"));
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
+
+  if (mode == 6)
+    {
+      if ((use & (KSBA_KEYUSAGE_CRL_SIGN)))
+        return 0;
+      log_info (_("certificate should not have "
+                  "been used for CRL signing\n"));
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
+
+  if ((use & ((mode&1)?
+              (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT):
+              (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
+      )
+    return 0;
+
+  log_info (mode==3? _("certificate should not have been used "
+                       "for encryption\n"):
+            mode==2? _("certificate should not have been used for signing\n"):
+            mode==1? _("certificate is not usable for encryption\n"):
+                     _("certificate is not usable for signing\n"));
+  return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+}
+
+/* Return 0 if the certificate CERT is usable for certification.  */
+gpg_error_t
+cert_use_cert_p (ksba_cert_t cert)
+{
+  return cert_usage_p (cert, 4);
+}
+
+/* Return 0 if the certificate CERT is usable for signing OCSP
+   responses.  */
+gpg_error_t
+cert_use_ocsp_p (ksba_cert_t cert)
+{
+  return cert_usage_p (cert, 5);
+}
+
+/* Return 0 if the certificate CERT is usable for signing CRLs. */
+gpg_error_t
+cert_use_crl_p (ksba_cert_t cert)
+{
+  return cert_usage_p (cert, 6);
+}
diff --git a/dirmngr/validate.h b/dirmngr/validate.h
new file mode 100644 (file)
index 0000000..0d9283c
--- /dev/null
@@ -0,0 +1,55 @@
+/* validate.h - Certificate validation
+ *      Copyright (C) 2004 g10 Code GmbH
+ *
+ * This file is part of DirMngr.
+ *
+ * DirMngr 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.
+ *
+ * DirMngr 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 VALIDATE_H
+#define VALIDATE_H
+
+
+enum {
+  /* Simple certificate validation mode. */
+  VALIDATE_MODE_CERT = 0,
+  /* Standard CRL issuer certificate validation; i.e. CRLs are not
+     considered for CRL issuer certificates. */
+  VALIDATE_MODE_CRL = 1,
+  /* Full CRL validation. */
+  VALIDATE_MODE_CRL_RECURSIVE = 2,
+  /* Validation as used for OCSP. */
+  VALIDATE_MODE_OCSP = 3
+};
+
+
+/* Validate the certificate CHAIN up to the trust anchor. Optionally
+   return the closest expiration time in R_EXPTIME. */
+gpg_error_t validate_cert_chain (ctrl_t ctrl,
+                                 ksba_cert_t cert, ksba_isotime_t r_exptime,
+                                 int mode, char **r_trust_anchor);
+
+/* Return 0 if the certificate CERT is usable for certification.  */
+gpg_error_t cert_use_cert_p (ksba_cert_t cert);
+
+/* Return 0 if the certificate CERT is usable for signing OCSP
+   responses.  */
+gpg_error_t cert_use_ocsp_p (ksba_cert_t cert);
+
+/* Return 0 if the certificate CERT is usable for signing CRLs. */
+gpg_error_t cert_use_crl_p (ksba_cert_t cert);
+
+
+#endif /*VALIDATE_H*/
diff --git a/dirmngr/w32-ldap-help.h b/dirmngr/w32-ldap-help.h
new file mode 100644 (file)
index 0000000..80668d9
--- /dev/null
@@ -0,0 +1,169 @@
+/* w32-ldap-help.h - Map utf8 based API into a wchar_t API.
+ * Copyright (C) 2010 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef W32_LDAP_HELP_H
+#define W32_LDAP_HELP_H
+
+#ifndef HAVE_W32CE_SYSTEM
+# error This is only required for W32CE.
+#endif
+
+
+static inline LDAP *
+_dirmngr_ldap_init (const char *host, unsigned short port)
+{
+  LDAP *ld;
+  wchar_t *whost = NULL;
+
+  if (host)
+    {
+      whost = utf8_to_wchar (host);
+      if (!whost)
+        return NULL;
+    }
+  ld = ldap_init (whost, port);
+  xfree (whost);
+  return ld;
+}
+
+
+static inline ULONG
+_dirmngr_ldap_simple_bind_s (LDAP *ld, const char *user, const char *pass)
+{
+  ULONG ret;
+  wchar_t *wuser, *wpass;
+
+  wuser = user? utf8_to_wchar (user) : NULL;
+  wpass = pass? utf8_to_wchar (pass) : NULL;
+  /* We can't easily map errnos to ldap_errno, thus we pass a NULL to
+     the function in the hope that the server will throw an error.  */
+  ret = ldap_simple_bind_s (ld, wuser, wpass);
+  xfree (wpass);
+  xfree (wuser);
+  return ret;
+}
+
+
+static inline ULONG
+_dirmngr_ldap_search_st (LDAP *ld, const char *base, ULONG scope,
+                         const char *filter, char **attrs,
+                         ULONG attrsonly, struct timeval *timeout,
+                         LDAPMessage **res)
+{
+  ULONG ret = LDAP_NO_MEMORY;
+  wchar_t *wbase = NULL;
+  wchar_t *wfilter = NULL;
+  wchar_t **wattrs = NULL;
+  int i;
+
+  if (base)
+    {
+      wbase = utf8_to_wchar (base);
+      if (!wbase)
+        goto leave;
+    }
+  if (filter)
+    {
+      wfilter = utf8_to_wchar (filter);
+      if (!wfilter)
+        goto leave;
+    }
+  if (attrs)
+    {
+      for (i=0; attrs[i]; i++)
+        ;
+      wattrs = xtrycalloc (i+1, sizeof *wattrs);
+      if (!wattrs)
+        goto leave;
+      for (i=0; attrs[i]; i++)
+        {
+          wattrs[i] = utf8_to_wchar (attrs[i]);
+          if (!wattrs[i])
+            goto leave;
+        }
+    }
+
+  ret = ldap_search_st (ld, wbase, scope, wfilter, wattrs, attrsonly,
+                        (struct l_timeval *)timeout, res);
+
+ leave:
+  if (wattrs)
+    {
+      for (i=0; wattrs[i]; i++)
+        xfree (wattrs[i]);
+      xfree (wattrs);
+    }
+  xfree (wfilter);
+  xfree (wbase);
+  return ret;
+}
+
+
+static inline char *
+_dirmngr_ldap_first_attribute (LDAP *ld, LDAPMessage *msg, BerElement **elem)
+{
+  wchar_t *wattr;
+  char *attr;
+
+  wattr = ldap_first_attribute (ld, msg, elem);
+  if (!wattr)
+    return NULL;
+  attr = wchar_to_utf8 (wattr);
+  ldap_memfree (wattr);
+  return attr;
+}
+
+
+static inline char *
+_dirmngr_ldap_next_attribute (LDAP *ld, LDAPMessage *msg, BerElement *elem)
+{
+  wchar_t *wattr;
+  char *attr;
+
+  wattr = ldap_next_attribute (ld, msg, elem);
+  if (!wattr)
+    return NULL;
+  attr = wchar_to_utf8 (wattr);
+  ldap_memfree (wattr);
+  return attr;
+}
+
+static inline BerValue **
+_dirmngr_ldap_get_values_len (LDAP *ld, LDAPMessage *msg, const char *attr)
+{
+  BerValue **ret;
+  wchar_t *wattr;
+
+  if (attr)
+    {
+      wattr = utf8_to_wchar (attr);
+      if (!wattr)
+        return NULL;
+    }
+  else
+    wattr = NULL;
+
+  ret = ldap_get_values_len (ld, msg, wattr);
+  xfree (wattr);
+
+  return ret;
+}
+
+
+#endif /*W32_LDAP_HELP_H*/
index 680affa..b830c0e 100644 (file)
@@ -1,21 +1,90 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-01-13  Werner Koch  <wk@g10code.com>
+2011-10-12  Werner Koch  <wk@g10code.com>
 
+       * gpg.texi: Add a bunch of opindex items.
+
+       * yat2m.c (parse_file): Add hack to allow table indentation.
+
+2011-08-12  Werner Koch  <wk@g10code.com>
+
+       * texi.css: Override some elements.
+       * gnupg-log-tr.png: New.
+       * gnupg.texi:  Use transparent logo.
+
+2011-03-01  Werner Koch  <wk@g10code.com>
+
+       * gpgsm.texi (CSR and certificate creation): New.
+       * gpg.texi (Unattended GPG key generation): New.
+
+2010-10-29  David Shaw  <dshaw@jabberwocky.com>
+
+       * gpg.texi (GPG Configuration Options): Clarify that show-photos
+       doesn't work with --with-colons.  --personal-digest-preferences
+       does not have a default any longer.
+
+2010-10-18  Werner Koch  <wk@g10code.com>
+
+       * DETAILS: Fix description of IMPORT_RES.  Reported by Nicholas Cole.
+
+2010-10-11  Daniel Kahn Gillmor  <dkg@fifthhorseman.net>  (wk)
+
+       * gpg.texi (GPG Configuration Options) <photo-viewer>: Describe %v
+       and %V.
+
+2010-10-05  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (faq.txt faq.html, faq-online): New.
+
+2010-10-04  Werner Koch  <wk@g10code.com>
+
+       * faq.org: New.
        * FAQ: Make it a static file with a pointer to the online location.
        * Makefile.am (EXTRA_DIST): Remove faq.raw and faq.html.
        (FAQ, faq.html): Remove these targets
 
-2010-03-05  Werner Koch  <wk@g10code.com>
+2010-09-28  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (AM_MAKEINFOFLAGS): Add define gpgtwoone.
+
+2010-09-28  David Shaw  <dshaw@jabberwocky.com>
+
+       * gpg.texi (OpenPGP Options): Clarify that --force-v3-sigs
+       disables (not enables) v4 options.  --force-v3-sigs defaults to
+       no.
+
+2010-08-18  Werner Koch  <wk@g10code.com>
+
+       * tools.texi (watchgnupg): Add examples section.
+
+2010-06-10  Werner Koch  <wk@g10code.com>
 
-       * gpg.texi (GPG Configuration Options): Mention that
-       show-uid-validity does only work with public keys.  Noted by
-       Daniel Kahn Gillmor.
+       * Makefile.am (gnupg_TEXINFOS): Add dirmngr.texi.
+       (myman_sources): Ditto.
+       (myman_pages): Add dirmngr and dirmngr-client pages.
+       (noinst_MANS): Move gnupg.7 to man_MANS.
+
+       * gnupg.texi: Include dirmngr.texi and add a menu entry.
+       * dirmngr.texi: New.  Taken from the current SVN of the dirmngr
+       package and adjusted to fit into the GnuPG manual.  Moved
+       dirmngr-cleint stuff to ...
+       * tools.texi (dirmngr-client): ... new.
+
+2009-11-18  Werner Koch  <wk@g10code.com>
+
+       * gpg.texi (GPG Key related Options): Describe
+       --skip-hidden-recipients.
+
+2009-10-19  David Shaw  <dshaw@jabberwocky.com>
+
+       * gpg.texi (GPG Configuration Options): Clarify that ca-cert-file
+       is a generic store, the details of which depend on the underlying
+       libraries.
 
 2009-08-24  David Shaw  <dshaw@jabberwocky.com>
 
        * gnupg.texi: Include gpg.texi
 
        * tools.texi: Add a few @command markups.
-       * gpgsm.texi: Ditto.
+       * gpgsm.texi: Ditto
        * gpg-agent.texi: Ditto.
        * scdaemon.texi: Ditto.
 
 
        * Makefile.am, gpgsm.texi: New.
 
- Copyright 2002, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright 2002, 2004, 2005, 2006, 2007, 2008, 2010 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
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/doc/DCO b/doc/DCO
new file mode 100644 (file)
index 0000000..bae7bff
--- /dev/null
+++ b/doc/DCO
@@ -0,0 +1,29 @@
+GnuPG Developer's Certificate of Origin.  Version 1.0
+=====================================================
+
+By making a contribution to the GnuPG project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+    have the right to submit it under the free software license
+    indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the
+    best of my knowledge, is covered under an appropriate free
+    software license and I have the right under that license to
+    submit that work with modifications, whether created in whole
+    or in part by me, under the same free software license
+    (unless I am permitted to submit under a different license),
+    as indicated in the file; or
+
+(c) The contribution was provided directly to me by some other
+    person who certified (a), (b) or (c) and I have not modified
+    it.
+
+(d) I understand and agree that this project and the contribution
+    are public and that a record of the contribution (including
+    all personal information I submit with it, including my
+    sign-off) is maintained indefinitely and may be redistributed
+    consistent with this project or the free software license(s)
+    involved.
+
+Signed-off-by: [Your name and mail address]
index 645814a..a1e96f4 100644 (file)
@@ -1,11 +1,26 @@
-                                                              -*- text -*-
-Format of colon listings
-========================
-First an example:
-
+# doc/DETAILS                                                -*- org -*-
+#+TITLE: GnuPG Details
+# Globally disable superscripts and subscripts:
+#+OPTIONS: ^:{}
+#
+
+# Note: This file uses org-mode; it should be easy to read as plain
+# text but be aware of some markup peculiarities: Verbatim code is
+# enclosed in #+begin-example, #+end-example blocks or marked by a
+# colon as the first non-white-space character, words bracketed with
+# equal signs indicate a monospace font, and the usual /italics/,
+# *bold*, and _underline_ conventions are recognized.
+
+This is the DETAILS file for GnuPG which specifies some internals and
+parts of the external API for GPG and GPGSM.
+
+* Format of the colon listings
+  The format is a based on colon separated record, each recods starts
+  with a tag string and extends to the end of the line.  Here is an
+  example:
+#+begin_example
 $ gpg --with-colons --list-keys \
       --with-fingerprint --with-fingerprint wk@gnupg.org
-
 pub:f:1024:17:6C7EE1B8621CC013:899817715:1055898235::m:::scESC:
 fpr:::::::::ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013:
 uid:f::::::::Werner Koch <wk@g10code.com>:
@@ -14,980 +29,896 @@ sub:f:1536:16:06AD222CADF6A6E1:919537416:1036177416:::::e:
 fpr:::::::::CF8BCC4B18DE08FCD8A1615906AD222CADF6A6E1:
 sub:r:1536:20:5CE086B5B5A18FF4:899817788:1025961788:::::esc:
 fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4:
+#+end_example
+
+The double =--with-fingerprint= prints the fingerprint for the subkeys
+too.  Old versions of gpg used a slighrly different format and required
+the use of the option =--fixed-list-mode= to conform to the format
+described here.
+
+** Description of the fields
+*** Field 1 - Type of record
+
+    - pub :: Public key
+    - crt :: X.509 certificate
+    - crs :: X.509 certificate and private key available
+    - sub :: Subkey (secondary key)
+    - sec :: Secret key
+    - ssb :: Secret subkey (secondary key)
+    - uid :: User id (only field 10 is used).
+    - uat :: User attribute (same as user id except for field 10).
+    - sig :: Signature
+    - rev :: Revocation signature
+    - fpr :: Fingerprint (fingerprint is in field 10)
+    - pkd :: Public key data [*]
+    - grp :: Keygrip
+    - rvk :: Revocation key
+    - tru :: Trust database information [*]
+    - spk :: Signature subpacket [*]
+    - cfg :: Configuration data [*]
+
+    Records marked with an asterisk are described at [[*Special%20field%20formats][*Special fields]].
+
+*** Field 2 - Validity
+
+    This is a letter describing the computed validity of a key.
+    Currently this is a single letter, but be prepared that additional
+    information may follow in some future versions. Note that GnuPG <
+    2.1 does not set this field for secret key listings.
+
+    - o :: Unknown (this key is new to the system)
+    - i :: The key is invalid (e.g. due to a missing self-signature)
+    - d :: The key has been disabled
+          (deprecated - use the 'D' in field 12 instead)
+    - r :: The key has been revoked
+    - e :: The key has expired
+    - - :: Unknown validity (i.e. no value assigned)
+    - q :: Undefined validity.  '-' and 'q' may safely be treated as
+           the same value for most purposes
+    - n :: The key is not valid
+    - m :: The key is marginal valid.
+    - f :: The key is fully valid
+    - u :: The key is ultimately valid.  This often means that the
+           secret key is available, but any key may be marked as
+           ultimately valid.
+    - w :: The key has a well known private part.
+    - s :: The key has special validity.  This means that it might be
+           self-signed and expected to be used in the STEED sytem.
+
+    If the validity information is given for a UID or UAT record, it
+    describes the validity calculated based on this user ID.  If given
+    for a key record it describes the validity taken from the best
+    rated user ID.
+
+    For X.509 certificates a 'u' is used for a trusted root
+    certificate (i.e. for the trust anchor) and an 'f' for all other
+    valid certificates.
+
+*** Field 3 - Key length
+
+    The length of key in bits.
+
+*** Field 4 - Public key algorithm
+
+    The values here are those from the OpenPGP specs or if they are
+    greather than 255 the algorithm ids as used by Libgcrypt.
+
+*** Field 5 - KeyID
+
+    This is the 64 bit keyid as specified by OpenPGP and the last 64
+    bit of the SHA-1 fingerprint of an X.509 certifciate.
+
+*** Field 6 - Creation date
+
+    The creation date of the key is given in UTC.  For UID and UAT
+    records, this is used for the self-signature date.  Note that the
+    date is usally printed in seconds since epoch, however, we are
+    migrating to an ISO 8601 format (e.g. "19660205T091500").  This is
+    currently only relevant for X.509.  A simple way to detect the new
+    format is to scan for the 'T'.  Note that old versions of gpg
+    without using the =--fixed-list-mode= option used a "yyyy-mm-tt"
+    format.
+
+*** Field 7 - Expiration date
+
+    Key or UID/UAT expiration date or empty if it does not expire.
+
+*** Field 8 - Certificate S/N, UID hash, trust signature info
+
+    Used for serial number in crt records.  For UID and UAT records,
+    this is a hash of the user ID contents used to represent that
+    exact user ID.  For trust signatures, this is the trust depth
+    seperated by the trust value by a space.
+
+*** Field 9 -  Ownertrust
+
+    This is only used on primary keys.  This is a single letter, but
+    be prepared that additional information may follow in future
+    versions.  For trust signatures with a regular expression, this is
+    the regular expression value, quoted as in field 10.
+
+*** Field 10 - User-ID
+    The value is quoted like a C string to avoid control characters
+    (the colon is quoted =\x3a=).  For a "pub" record this field is
+    not used on --fixed-list-mode.  A UAT record puts the attribute
+    subpacket count here, a space, and then the total attribute
+    subpacket size.  In gpgsm the issuer name comes here.  A FPR
+    record stores the fingerprint here.  The fingerprint of a
+    revocation key is stored here.
+*** Field 11 - Signature class
+
+    Signature class as per RFC-4880.  This is a 2 digit hexnumber
+    followed by either the letter 'x' for an exportable signature or
+    the letter 'l' for a local-only signature.  The class byte of an
+    revocation key is also given here, 'x' and 'l' is used the same
+    way.  This field if not used for X.509.
+
+*** Field 12 - Key capabilities
+
+    The defined capabilities are:
+
+    - e :: Encrypt
+    - s :: Sign
+    - c :: Certify
+    - a :: Authentication
+    - ? :: Unknown capability
+
+    A key may have any combination of them in any order.  In addition
+    to these letters, the primary key has uppercase versions of the
+    letters to denote the _usable_ capabilities of the entire key, and
+    a potential letter 'D' to indicate a disabled key.
+
+*** Field 13 - Issuer certificate fingerprint or other info
+
+    Used in FPR records for S/MIME keys to store the fingerprint of
+    the issuer certificate.  This is useful to build the certificate
+    path based on certificates stored in the local key database it is
+    only filled if the issuer certificate is available. The root has
+    been reached if this is the same string as the fingerprint. The
+    advantage of using this value is that it is guaranteed to have
+    been been build by the same lookup algorithm as gpgsm uses.
+
+    For "uid" records this field lists the preferences in the same way
+    gpg's --edit-key menu does.
+
+    For "sig" records, this is the fingerprint of the key that issued
+    the signature.  Note that this is only filled in if the signature
+    verified correctly.  Note also that for various technical reasons,
+    this fingerprint is only available if --no-sig-cache is used.
+
+*** Field 14 - Flag field
+
+    Flag field used in the --edit menu output
+
+*** Field 15 - S/N of a token
+
+    Used in sec/sbb to print the serial number of a token (internal
+    protect mode 1002) or a '#' if that key is a simple stub (internal
+    protect mode 1001).  If the option --with-secret is used and a
+    secret key is available for the public key, a '+' indicates this.
+
+*** Field 16 - Hash algorithm
+
+    For sig records, this is the used hash algorithm.  For example:
+    2 = SHA-1, 8 = SHA-256.
+
+*** Field 17 - Curve name
 
-The double --with-fingerprint prints the fingerprint for the subkeys
-too. --fixed-list-mode is the modern listing way printing dates in
-seconds since Epoch and does not merge the first userID with the pub
-record; gpg2 does this by default and the option is a dummy.
-
-
- 1. Field:  Type of record
-           pub = public key
-            crt = X.509 certificate
-            crs = X.509 certificate and private key available
-           sub = subkey (secondary key)
-           sec = secret key
-           ssb = secret subkey (secondary key)
-           uid = user id (only field 10 is used).
-           uat = user attribute (same as user id except for field 10).
-            sig = signature
-            rev = revocation signature
-           fpr = fingerprint: (fingerprint is in field 10)
-           pkd = public key data (special field format, see below)
-            grp = keygrip
-            rvk = revocation key
-            tru = trust database information
-            spk = signature subpacket
-
- 2. Field:  A letter describing the calculated validity. This is a single
-           letter, but be prepared that additional information may follow
-           in some future versions. (not used for secret keys)
-               o = Unknown (this key is new to the system)
-                i = The key is invalid (e.g. due to a missing self-signature)
-               d = The key has been disabled
-                   (deprecated - use the 'D' in field 12 instead)
-               r = The key has been revoked
-               e = The key has expired
-               - = Unknown validity (i.e. no value assigned)
-               q = Undefined validity
-                   '-' and 'q' may safely be treated as the same
-                   value for most purposes
-               n = The key is valid
-               m = The key is marginal valid.
-               f = The key is fully valid
-               u = The key is ultimately valid.  This often means
-                   that the secret key is available, but any key may
-                   be marked as ultimately valid.
-
-            If the validity information is given for a UID or UAT
-            record, it describes the validity calculated based on this
-            user ID.  If given for a key record it describes the best
-            validity taken from the best rated user ID.
-
-            For X.509 certificates a 'u' is used for a trusted root
-            certificate (i.e. for the trust anchor) and an 'f' for all
-            other valid certificates.
-
- 3. Field:  length of key in bits.
-
- 4. Field:  Algorithm: 1 = RSA
-                      16 = Elgamal (encrypt only)
-                      17 = DSA (sometimes called DH, sign only)
-                      20 = Elgamal (sign and encrypt - don't use them!)
-           (for other id's see include/cipher.h)
-
- 5. Field:  KeyID
-
- 6. Field:  Creation Date (in UTC).  For UID and UAT records, this is
-            the self-signature date.  Note that the date is usally
-            printed in seconds since epoch, however, we are migrating
-            to an ISO 8601 format (e.g. "19660205T091500").  This is
-            currently only relevant for X.509.  A simple way to detect
-            the new format is to scan for the 'T'.
-
- 7. Field:  Key or user ID/user attribute expiration date or empty if none.
-
- 8. Field:  Used for serial number in crt records (used to be the Local-ID).
-            For UID and UAT records, this is a hash of the user ID contents
-            used to represent that exact user ID.  For trust signatures,
-            this is the trust depth seperated by the trust value by a
-            space.
-
- 9. Field:  Ownertrust (primary public keys only)
-           This is a single letter, but be prepared that additional
-           information may follow in some future versions.  For trust
-           signatures with a regular expression, this is the regular
-           expression value, quoted as in field 10.
-
-10. Field:  User-ID.  The value is quoted like a C string to avoid
-           control characters (the colon is quoted "\x3a").
-            For a "pub" record this field is not used on --fixed-list-mode.
-            A UAT record puts the attribute subpacket count here, a
-           space, and then the total attribute subpacket size.
-            In gpgsm the issuer name comes here
-            An FPR record stores the fingerprint here.
-            The fingerprint of an revocation key is stored here.
-
-11. Field:  Signature class as per RFC-4880.  This is a 2 digit
-            hexnumber followed by either the letter 'x' for an
-            exportable signature or the letter 'l' for a local-only
-            signature.  The class byte of an revocation key is also
-            given here, 'x' and 'l' is used the same way.  IT is not
-            used for X.509.
-
-12. Field:  Key capabilities:
-                e = encrypt
-                s = sign
-                c = certify
-                a = authentication
-           A key may have any combination of them in any order.  In
-           addition to these letters, the primary key has uppercase
-           versions of the letters to denote the _usable_
-           capabilities of the entire key, and a potential letter 'D'
-           to indicate a disabled key.
-
-13. Field:  Used in FPR records for S/MIME keys to store the
-            fingerprint of the issuer certificate.  This is useful to
-            build the certificate path based on certificates stored in
-            the local keyDB; it is only filled if the issuer
-            certificate is available. The root has been reached if
-            this is the same string as the fingerprint. The advantage
-            of using this value is that it is guaranteed to have been
-            been build by the same lookup algorithm as gpgsm uses.
-            For "uid" records this lists the preferences in the same
-            way the gpg's --edit-key menu does.
-           For "sig" records, this is the fingerprint of the key that
-           issued the signature.  Note that this is only filled in if
-           the signature verified correctly.  Note also that for
-           various technical reasons, this fingerprint is only
-           available if --no-sig-cache is used.
-
-14. Field   Flag field used in the --edit menu output:
-
-15. Field   Used in sec/sbb to print the serial number of a token
-            (internal protect mode 1002) or a '#' if that key is a
-            simple stub (internal protect mode 1001)
-16. Field:  For sig records, this is the used hash algorithm:
-                2 = SHA-1
-                8 = SHA-256
-           (for other id's see include/cipher.h)
-
-All dates are displayed in the format yyyy-mm-dd unless you use the
-option --fixed-list-mode in which case they are displayed as seconds
-since Epoch.  More fields may be added later, so parsers should be
-prepared for this. When parsing a number the parser should stop at the
-first non-number character so that additional information can later be
-added.
-
-If field 1 has the tag "pkd", a listing looks like this:
+    For pub, sub, sec, and sbb records this field is used for the ECC
+    curve name.
+
+** Special fields
+
+*** PKD - Public key data
+
+    If field 1 has the tag "pkd", a listing looks like this:
+#+begin_example
 pkd:0:1024:B665B1435F4C2 .... FF26ABB:
     !  !   !-- the value
     !  !------ for information number of bits in the value
     !--------- index (eg. DSA goes from 0 to 3: p,q,g,y)
+#+end_example
+
+*** TRU - Trust database information
+    Example for a "tru" trust base record:
+#+begin_example
+    tru:o:0:1166697654:1:3:1:5
+#+end_example
+
+    - Field 2 :: Reason for staleness of trust.  If this field is
+                 empty, then the trustdb is not stale.  This field may
+                 have multiple flags in it:
 
+                 - o :: Trustdb is old
+                 - t :: Trustdb was built with a different trust model
+                        than the one we are using now.
 
-Example for a "tru" trust base record:
-
-   tru:o:0:1166697654:1:3:1:5
-
- The fields are:
-
- 2: Reason for staleness of trust.  If this field is empty, then the
-    trustdb is not stale.  This field may have multiple flags in it:
-
-    o: Trustdb is old
-    t: Trustdb was built with a different trust model than the one we
-       are using now.
-
- 3: Trust model:
-    0: Classic trust model, as used in PGP 2.x.
-    1: PGP trust model, as used in PGP 6 and later.  This is the same
-       as the classic trust model, except for the addition of trust
-       signatures.
-
-    GnuPG before version 1.4 used the classic trust model by default.
-    GnuPG 1.4 and later uses the PGP trust model by default.
-
- 4: Date trustdb was created in seconds since 1970-01-01.
- 5: Date trustdb will expire in seconds since 1970-01-01.
- 6: Number of marginally trusted users to introduce a new key signer
-    (gpg's option --marginals-needed)
- 7: Number of completely trusted users to introduce a new key signer.
-    (gpg's option --completes-needed)
- 8: Maximum depth of a certification chain.
-    *gpg's option --max-cert-depth)
-
-The "spk" signature subpacket records have the fields:
-
- 2: Subpacket number as per RFC-4880 and later.
- 3: Flags in hex.  Currently the only two bits assigned are 1, to
-    indicate that the subpacket came from the hashed part of the
-    signature, and 2, to indicate the subpacket was marked critical.
- 4: Length of the subpacket.  Note that this is the length of the
-    subpacket, and not the length of field 5 below.  Due to the need
-    for %-encoding, the length of field 5 may be up to 3x this value.
- 5: The subpacket data.  Printable ASCII is shown as ASCII, but other
-    values are rendered as %XX where XX is the hex value for the byte.
-
-
-Format of the "--status-fd" output
-==================================
-Every line is prefixed with "[GNUPG:] ", followed by a keyword with
-the type of the status line and a some arguments depending on the
-type (maybe none); an application should always be prepared to see
-more arguments in future versions.
-
-
-    NEWSIG
-        Is issued right before a signature verification starts.  This is
-        useful to define a context for parsing ERROR status messages.  No
-        arguments are currently defined.
-
-    GOODSIG  <long_keyid_or_fpr>  <username>
-       The signature with the keyid is good.  For each signature only
-        one of the codes GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG
-        or ERRSIG will be emitted.  In the past they were used as a
-        marker for a new signature; new code should use the NEWSIG
-        status instead.  The username is the primary one encoded in
-        UTF-8 and %XX escaped. The fingerprint may be used instead of
-        the long keyid if it is available.  This is the case with CMS
-        and might eventually also be available for OpenPGP.
-
-    EXPSIG  <long_keyid_or_fpr>  <username>
-       The signature with the keyid is good, but the signature is
-       expired. The username is the primary one encoded in UTF-8 and
-       %XX escaped. The fingerprint may be used instead of the long
-       keyid if it is available.  This is the case with CMS and might
-       eventually also be available for OpenPGP.
-
-    EXPKEYSIG  <long_keyid_or_fpr> <username>
-        The signature with the keyid is good, but the signature was
-       made by an expired key. The username is the primary one
-       encoded in UTF-8 and %XX escaped.  The fingerprint may be used
-       instead of the long keyid if it is available.  This is the
-       case with CMS and might eventually also be available for
-       OpenPGP.
-
-    REVKEYSIG  <long_keyid_or_fpr>  <username>
-       The signature with the keyid is good, but the signature was
-       made by a revoked key. The username is the primary one encoded
-       in UTF-8 and %XX escaped. The fingerprint may be used instead
-       of the long keyid if it is available.  This is the case with
-       CMS and might eventually also be available for OpenPGP.
-
-    BADSIG  <long_keyid_or_fpr>  <username>
-       The signature with the keyid has not been verified okay.  The
-        username is the primary one encoded in UTF-8 and %XX
-        escaped. The fingerprint may be used instead of the long keyid
-        if it is available.  This is the case with CMS and might
-        eventually also be available for OpenPGP.
-
-    ERRSIG  <long_keyid_or_fpr>  <pubkey_algo> <hash_algo> \
-           <sig_class> <timestamp> <rc>
-       It was not possible to check the signature.  This may be
-       caused by a missing public key or an unsupported algorithm.  A
-       RC of 4 indicates unknown algorithm, a 9 indicates a missing
-       public key. The other fields give more information about this
-       signature.  sig_class is a 2 byte hex-value.  The fingerprint
-       may be used instead of the long keyid if it is available.
-       This is the case with CMS and might eventually also be
-       available for OpenPGP.
-
-        Note, that TIMESTAMP may either be a number with seconds since
-        epoch or an ISO 8601 string which can be detected by the
-        presence of the letter 'T' inside.
-
-    VALIDSIG   <fingerprint in hex> <sig_creation_date> <sig-timestamp>
-               <expire-timestamp>  <sig-version> <reserved> <pubkey-algo>
-               <hash-algo> <sig-class> [ <primary-key-fpr> ]
-
-       The signature with the keyid is good. This is the same as
-       GOODSIG but has the fingerprint as the argument. Both status
-       lines are emitted for a good signature.  All arguments here
-       are on one long line.  sig-timestamp is the signature creation
-       time in seconds after the epoch. expire-timestamp is the
-       signature expiration time in seconds after the epoch (zero
-       means "does not expire"). sig-version, pubkey-algo, hash-algo,
-       and sig-class (a 2-byte hex value) are all straight from the
-       signature packet.  PRIMARY-KEY-FPR is the fingerprint of the
-       primary key or identical to the first argument.  This is
-       useful to get back to the primary key without running gpg
-       again for this purpose.
-
-        The primary-key-fpr parameter is used for OpenPGP and not
-        available for CMS signatures.  The sig-version as well as the
-        sig class is not defined for CMS and currently set to 0 and 00.
-
-        Note, that *-TIMESTAMP may either be a number with seconds
-        since epoch or an ISO 8601 string which can be detected by the
-        presence of the letter 'T' inside.
-
-    SIG_ID  <radix64_string>  <sig_creation_date>  <sig-timestamp>
-       This is emitted only for signatures of class 0 or 1 which
-       have been verified okay.  The string is a signature id
-       and may be used in applications to detect replay attacks
-       of signed messages.  Note that only DLP algorithms give
-       unique ids - others may yield duplicated ones when they
-       have been created in the same second.
-
-        Note, that SIG-TIMESTAMP may either be a number with seconds
-        since epoch or an ISO 8601 string which can be detected by the
-        presence of the letter 'T' inside.
-
-    ENC_TO  <long_keyid>  <keytype>  <keylength>
-       The message is encrypted to this LONG_KEYID.  KEYTYPE is the
-       numerical value of the public key algorithm or 0 if it is not
-       known, KEYLENGTH is the length of the key or 0 if it is not
-       known (which is currently always the case).  Gpg prints this
-       line always; Gpgsm only if it knows the certificate.
-
-    NODATA  <what>
-       No data has been found. Codes for what are:
-           1 - No armored data.
-           2 - Expected a packet but did not found one.
-           3 - Invalid packet found, this may indicate a non OpenPGP
-                message.
-            4 - signature expected but not found
-       You may see more than one of these status lines.
-
-    UNEXPECTED <what>
-        Unexpected data has been encountered
-            0 - not further specified               1
-
-
-    TRUST_UNDEFINED <error token>
-    TRUST_NEVER     <error token>
-    TRUST_MARGINAL  [0  [<validation_model>]]
-    TRUST_FULLY     [0  [<validation_model>]]
-    TRUST_ULTIMATE  [0  [<validation_model>]]
-       For good signatures one of these status lines are emitted to
-       indicate the validity of the key used to create the signature.
-       The error token values are currently only emitted by gpgsm.
-       VALIDATION_MODEL describes the algorithm used to check the
-       validity of the key.  The defaults are the standard Web of
-       Trust model for gpg and the the standard X.509 model for
-       gpgsm.  The defined values are
-
-           "pgp"   for the standard PGP WoT.
-          "shell" for the standard X.509 model.
-          "chain" for the chain model.
-
-        Note that we use the term "TRUST_" in the status names for
-        historic reasons; we now speak of validity.
-
-    PKA_TRUST_GOOD <mailbox>
-    PKA_TRUST_BAD  <mailbox>
-        Depending on the outcome of the PKA check one of the above
-        status codes is emitted in addition to a TRUST_* status.
-        Without PKA info available or
-
-    SIGEXPIRED
-       This is deprecated in favor of KEYEXPIRED.
-
-    KEYEXPIRED <expire-timestamp>
-       The key has expired.  expire-timestamp is the expiration time
-       in seconds since Epoch.  This status line is not very useful
-       because it will also be emitted for expired subkeys even if
-       this subkey is not used.  To check whether a key used to sign
-       a message has expired, the EXPKEYSIG status line is to be
-       used.
-
-        Note, that TIMESTAMP may either be a number with seconds since
-        epoch or an ISO 8601 string which can be detected by the
-        presence of the letter 'T' inside.
-
-    KEYREVOKED
-       The used key has been revoked by its owner.  No arguments yet.
-
-    BADARMOR
-       The ASCII armor is corrupted.  No arguments yet.
-
-    RSA_OR_IDEA
-       The IDEA algorithms has been used in the data.  A
-       program might want to fallback to another program to handle
-       the data if GnuPG failed.  This status message used to be emitted
-        also for RSA but this has been dropped after the RSA patent expired.
-        However we can't change the name of the message.
-
-    SHM_INFO
-    SHM_GET
-    SHM_GET_BOOL
-    SHM_GET_HIDDEN
-
-    GET_BOOL
-    GET_LINE
-    GET_HIDDEN
-    GOT_IT
-
-    NEED_PASSPHRASE <long main keyid> <long keyid> <keytype> <keylength>
-       Issued whenever a passphrase is needed.
-       keytype is the numerical value of the public key algorithm
-       or 0 if this is not applicable, keylength is the length
-       of the key or 0 if it is not known (this is currently always the case).
-
-    NEED_PASSPHRASE_SYM <cipher_algo> <s2k_mode> <s2k_hash>
-       Issued whenever a passphrase for symmetric encryption is needed.
-
-    NEED_PASSPHRASE_PIN <card_type> <chvno> [<serialno>]
-        Issued whenever a PIN is requested to unlock a card.
-
-    MISSING_PASSPHRASE
-       No passphrase was supplied.  An application which encounters this
-       message may want to stop parsing immediately because the next message
-       will probably be a BAD_PASSPHRASE.  However, if the application
-       is a wrapper around the key edit menu functionality it might not
-       make sense to stop parsing but simply ignoring the following
-       BAD_PASSPHRASE.
-
-    BAD_PASSPHRASE <long keyid>
-       The supplied passphrase was wrong or not given.  In the latter case
-       you may have seen a MISSING_PASSPHRASE.
-
-    GOOD_PASSPHRASE
-       The supplied passphrase was good and the secret key material
-       is therefore usable.
-
-    DECRYPTION_FAILED
-       The symmetric decryption failed - one reason could be a wrong
-       passphrase for a symmetrical encrypted message.
-
-    DECRYPTION_OKAY
-       The decryption process succeeded.  This means, that either the
-       correct secret key has been used or the correct passphrase
-       for a symmetric with passphrase encrypted message was given.
-        The program itself may return an errorcode because it may not
-        be possible to verify a signature for some reasons.
-
-    NO_PUBKEY  <long keyid>
-    NO_SECKEY  <long keyid>
-       The key is not available
-
-    IMPORT_CHECK <long keyid> <fingerprint> <user ID>
-        This status is emitted in interactive mode right before
-        the "import.okay" prompt.
-
-    IMPORTED   <long keyid>  <username>
-       The keyid and name of the signature just imported
-
-    IMPORT_OK  <reason> [<fingerprint>]
-        The key with the primary key's FINGERPRINT has been imported.
-        Reason flags:
-          0 := Not actually changed
-          1 := Entirely new key.
-          2 := New user IDs
-          4 := New signatures
-          8 := New subkeys
-         16 := Contains private key.
-        The flags may be ORed.
-
-    IMPORT_PROBLEM <reason> [<fingerprint>]
-        Issued for each import failure.  Reason codes are:
-          0 := "No specific reason given".
-          1 := "Invalid Certificate".
-          2 := "Issuer Certificate missing".
-          3 := "Certificate Chain too long".
-          4 := "Error storing certificate".
-
-    IMPORT_RES <count> <no_user_id> <imported> <imported_rsa> <unchanged>
-       <n_uids> <n_subk> <n_sigs> <n_revoc> <sec_read> <sec_imported>
-        <sec_dups> <skipped_new_keys> <not_imported>
-       Final statistics on import process (this is one long line)
-
-    FILE_START <what> <filename>
-       Start processing a file <filename>.  <what> indicates the performed
-       operation:
-           1 - verify
-            2 - encrypt
-            3 - decrypt
-
-    FILE_DONE
-       Marks the end of a file processing which has been started
-       by FILE_START.
-
-    BEGIN_DECRYPTION
-    END_DECRYPTION
-       Mark the start and end of the actual decryption process.  These
-       are also emitted when in --list-only mode.
-
-    BEGIN_ENCRYPTION  <mdc_method> <sym_algo>
-    END_ENCRYPTION
-       Mark the start and end of the actual encryption process.
-
-    BEGIN_SIGNING
-       Mark the start of the actual signing process. This may be used
-       as an indication that all requested secret keys are ready for
-       use.
-
-    DELETE_PROBLEM reason_code
-       Deleting a key failed.  Reason codes are:
-           1 - No such key
-           2 - Must delete secret key first
-            3 - Ambigious specification
-
-    PROGRESS what char cur total
-       Used by the primegen and Public key functions to indicate progress.
-       "char" is the character displayed with no --status-fd enabled, with
-       the linefeed replaced by an 'X'.  "cur" is the current amount
-       done and "total" is amount to be done; a "total" of 0 indicates that
-       the total amount is not known.  The condition
-           TOATL && CUR == TOTAL
-        may be used to detect the end of an operation.
-        Well known values for WHAT:
-             "pk_dsa"   - DSA key generation
-             "pk_elg"   - Elgamal key generation
-             "primegen" - Prime generation
-             "need_entropy" - Waiting for new entropy in the RNG
-             "file:XXX" - processing file XXX
-                          (note that current gpg versions leave out the
-                           "file:" prefix).
-             "tick"     - generic tick without any special meaning - useful
-                          for letting clients know that the server is
-                          still working.
-             "starting_agent" - A gpg-agent was started because it is not
-                          running as a daemon.
-             "learncard"  Send by the agent and gpgsm while learing
-                         the data of a smartcard.
-             "card_busy"  A smartcard is still working
-
-    SIG_CREATED <type> <pubkey algo> <hash algo> <class> <timestamp> <key fpr>
-       A signature has been created using these parameters.
-           type:  'D' = detached
-                  'C' = cleartext
-                  'S' = standard
-                  (only the first character should be checked)
-           class: 2 hex digits with the signature class
-
-        Note, that TIMESTAMP may either be a number with seconds since
-        epoch or an ISO 8601 string which can be detected by the
-        presence of the letter 'T' inside.
-
-    KEY_CREATED <type> <fingerprint> [<handle>]
-        A key has been created
-            type: 'B' = primary and subkey
-                  'P' = primary
-                  'S' = subkey
-        The fingerprint is one of the primary key for type B and P and
-        the one of the subkey for S.  Handle is an arbitrary
-        non-whitespace string used to match key parameters from batch
-        key creation run.
-
-    KEY_NOT_CREATED [<handle>]
-        The key from batch run has not been created due to errors.
-
-
-    SESSION_KEY  <algo>:<hexdigits>
-       The session key used to decrypt the message.  This message will
-       only be emitted when the special option --show-session-key
-       is used.  The format is suitable to be passed to the option
-       --override-session-key
-
-    NOTATION_NAME <name>
-    NOTATION_DATA <string>
-        name and string are %XX escaped; the data may be split
-        among several NOTATION_DATA lines.
-
-    USERID_HINT <long main keyid> <string>
-        Give a hint about the user ID for a certain keyID.
-
-    POLICY_URL <string>
-        string is %XX escaped
-
-    BEGIN_STREAM
-    END_STREAM
-        Issued by pipemode.
-
-    INV_RECP <reason> <requested_recipient>
-    INV_SGNR <reason> <requested_sender>
-        Issued for each unusable recipient/sender. The reasons codes
-        currently in use are:
-          0 := "No specific reason given".
-          1 := "Not Found"
-          2 := "Ambigious specification"
-          3 := "Wrong key usage"
-          4 := "Key revoked"
-          5 := "Key expired"
-          6 := "No CRL known"
-          7 := "CRL too old"
-          8 := "Policy mismatch"
-          9 := "Not a secret key"
-        10 := "Key not trusted"
-         11 := "Missing certificate"
-         12 := "Missing issuer certificate"
-
-        Note that for historical reasons the INV_RECP status is also
-        used for gpgsm's SIGNER command where it relates to signer's
-        of course.  Newer GnuPG versions are using INV_SGNR;
-        applications should ignore the INV_RECP during the sender's
-        command processing once they have seen an INV_SGNR.  We use
-        different code so that we can distinguish them while doing an
-        encrypt+sign.
-
-
-    NO_RECP <reserved>
-    NO_SGNR <reserved>
-        Issued when no recipients/senders are usable.
-
-    ALREADY_SIGNED <long-keyid>
-        Warning: This is experimental and might be removed at any time.
-
-    TRUNCATED <maxno>
-        The output was truncated to MAXNO items.  This status code is issued
-        for certain external requests
-
-    ERROR <error location> <error code> [<more>]
-
-        This is a generic error status message, it might be followed
-        by error location specific data. <error code> and
-        <error_location> should not contain spaces.  The error code is
-        a either a string commencing with a letter or such a string
-        prefixed with a numerical error code and an underscore; e.g.:
-        "151011327_EOF".
-
-    SUCCESS [<location>]
-        Postive confirimation that an operation succeeded.  <location>
-        is optional but if given should not contain spaces.
-        Used only with a few commands.
-
-
-    ATTRIBUTE <fpr> <octets> <type> <index> <count>
-             <timestamp> <expiredate> <flags>
-       This is one long line issued for each attribute subpacket when
-       an attribute packet is seen during key listing.  <fpr> is the
-       fingerprint of the key. <octets> is the length of the
-       attribute subpacket. <type> is the attribute type
-       (1==image). <index>/<count> indicates that this is the Nth
-       indexed subpacket of count total subpackets in this attribute
-       packet.  <timestamp> and <expiredate> are from the
-       self-signature on the attribute packet.  If the attribute
-       packet does not have a valid self-signature, then the
-       timestamp is 0.  <flags> are a bitwise OR of:
-               0x01 = this attribute packet is a primary uid
-               0x02 = this attribute packet is revoked
-               0x04 = this attribute packet is expired
-
-    CARDCTRL <what> [<serialno>]
-        This is used to control smartcard operations.
-        Defined values for WHAT are:
-           1 = Request insertion of a card.  Serialnumber may be given
-               to request a specific card.  Used by gpg 1.4 w/o scdaemon.
-           2 = Request removal of a card.  Used by gpg 1.4 w/o scdaemon.
-           3 = Card with serialnumber detected
-           4 = No card available.
-           5 = No card reader available
-           6 = No card support available
-
-    PLAINTEXT <format> <timestamp> <filename>
-        This indicates the format of the plaintext that is about to be
-        written.  The format is a 1 byte hex code that shows the
-        format of the plaintext: 62 ('b') is binary data, 74 ('t') is
-        text data with no character set specified, and 75 ('u') is
-        text data encoded in the UTF-8 character set.  The timestamp
-        is in seconds since the epoch.  If a filename is available it
-        gets printed as the third argument, percent-escaped as usual.
-
-    PLAINTEXT_LENGTH <length>
-        This indicates the length of the plaintext that is about to be
-        written.  Note that if the plaintext packet has partial length
-        encoding it is not possible to know the length ahead of time.
-        In that case, this status tag does not appear.
-
-    SIG_SUBPACKET <type> <flags> <len> <data>
-        This indicates that a signature subpacket was seen.  The
-        format is the same as the "spk" record above.
-
-    SC_OP_FAILURE [<code>]
-        An operation on a smartcard definitely failed.  Currently
-        there is no indication of the actual error code, but
-        application should be prepared to later accept more arguments.
-        Defined values for CODE are:
-           0 - unspecified error (identically to a missing CODE)
-           1 - canceled
-           2 - bad PIN
-
-    SC_OP_SUCCESS
-        A smart card operaion succeeded.  This status is only printed
-        for certain operation and is mostly useful to check whether a
-        PIN change really worked.
-
-    BACKUP_KEY_CREATED fingerprint fname
-        A backup key named FNAME has been created for the key with
-        KEYID.
-
-    MOUNTPOINT <name>
-        NAME is a percent-plus escaped filename describing the
-        mountpoint for the current operation (e.g. g13 --mount).  This
-        may either be the specified mountpoint or one randomly choosen
-        by g13.
-
-    DECRYPTION_INFO <mdc_method> <sym_algo>
-        Print information about the symmetric encryption algorithm and
-        the MDC method.  This will be emitted even if the decryption
-        fails.
-
-
-
-Format of the "--attribute-fd" output
-=====================================
-
-When --attribute-fd is set, during key listings (--list-keys,
---list-secret-keys) GnuPG dumps each attribute packet to the file
-descriptor specified.  --attribute-fd is intended for use with
---status-fd as part of the required information is carried on the
-ATTRIBUTE status tag (see above).
-
-The contents of the attribute data is specified by RFC 4880.  For
-convenience, here is the Photo ID format, as it is currently the only
-attribute defined:
-
-   Byte 0-1:  The length of the image header.  Due to a historical
-              accident (i.e. oops!) back in the NAI PGP days, this is
-              a little-endian number.  Currently 16 (0x10 0x00).
-
-   Byte 2:    The image header version.  Currently 0x01.
-
-   Byte 3:    Encoding format.  0x01 == JPEG.
-
-   Byte 4-15: Reserved, and currently unused.
-
-   All other data after this header is raw image (JPEG) data.
-
-
-Format of the "--list-config" output
-====================================
-
---list-config outputs information about the GnuPG configuration for
-the benefit of frontends or other programs that call GnuPG.  There are
-several list-config items, all colon delimited like the rest of the
---with-colons output.  The first field is always "cfg" to indicate
-configuration information.  The second field is one of (with
-examples):
-
-version: the third field contains the version of GnuPG.
-
-   cfg:version:1.3.5
-
-pubkey: the third field contains the public key algorithmdcaiphers
-       this version of GnuPG supports, separated by semicolons.  The
-       algorithm numbers are as specified in RFC-4880.  Note that in
-       contrast to the --status-fd interface these are _not_ the
-       Libgcrypt identifiers.
-
-   cfg:pubkey:1;2;3;16;17
-
-cipher: the third field contains the symmetric ciphers this version of
-       GnuPG supports, separated by semicolons.  The cipher numbers
-       are as specified in RFC-4880.
-
-   cfg:cipher:2;3;4;7;8;9;10
-
-digest: the third field contains the digest (hash) algorithms this
-       version of GnuPG supports, separated by semicolons.  The
-       digest numbers are as specified in RFC-4880.
-
-   cfg:digest:1;2;3;8;9;10
-
-compress: the third field contains the compression algorithms this
-         version of GnuPG supports, separated by semicolons.  The
-         algorithm numbers are as specified in RFC-4880.
-
-   cfg:compress:0;1;2;3
-
-group: the third field contains the name of the group, and the fourth
-       field contains the values that the group expands to, separated
-       by semicolons.
-
-For example, a group of:
-   group mynames = paige 0x12345678 joe patti
-
-would result in:
-   cfg:group:mynames:patti;joe;0x12345678;paige
-
-
-Key generation
-==============
-    See the Libcrypt manual.
-
-
-Unattended key generation
-=========================
-This feature allows unattended generation of keys controlled by a
-parameter file.  To use this feature, you use --gen-key together with
---batch and feed the parameters either from stdin or from a file given
-on the commandline.
-
-The format of this file is as follows:
-  o Text only, line length is limited to about 1000 chars.
-  o You must use UTF-8 encoding to specify non-ascii characters.
-  o Empty lines are ignored.
-  o Leading and trailing spaces are ignored.
-  o A hash sign as the first non white space character indicates a comment line.
-  o Control statements are indicated by a leading percent sign, the
-    arguments are separated by white space from the keyword.
-  o Parameters are specified by a keyword, followed by a colon.  Arguments
-    are separated by white space.
-  o The first parameter must be "Key-Type", control statements
-    may be placed anywhere.
-  o Key generation takes place when either the end of the parameter file
-    is reached, the next "Key-Type" parameter is encountered or at the
-    control statement "%commit"
-  o Control statements:
-    %echo <text>
-       Print <text>.
-    %dry-run
-       Suppress actual key generation (useful for syntax checking).
-    %commit
-       Perform the key generation.  An implicit commit is done
-       at the next "Key-Type" parameter.
-    %pubring <filename>
-    %secring <filename>
-       Do not write the key to the default or commandline given
-       keyring but to <filename>.  This must be given before the first
-       commit to take place, duplicate specification of the same filename
-       is ignored, the last filename before a commit is used.
-       The filename is used until a new filename is used (at commit points)
-       and all keys are written to that file.  If a new filename is given,
-       this file is created (and overwrites an existing one).
-        GnuPG < 2.1:  Both control statements must be given.
-        GnuPG >= 2.1: "%secring" is now a no-op.
-    %ask-passphrase
-        Enable a mode where the command "passphrase" is ignored and
-        instead the usual passphrase dialog is used.  This does not
-        make sense for batch key generation; however the unattended
-        key generation feature is also used by GUIs and this feature
-        relinquishes the GUI from implementing its own passphrase
-        entry code.  This is a global option.
-    %no-ask-passphrase
-        Disable the ask-passphrase mode.
-    %no-protection
-        With GnuPG 2.1 it is not anymore possible to specify a
-        passphrase for unattended key generation.  The passphrase
-        command is simply ignored and %ask-passpharse is thus
-        implicitly enabled.  Using this option allows to the creation
-        of keys without any passphrases.  This option is mainly
-        intended for regression tests.
-    %transient-key
-        If given the keys are created using a faster and a somewhat
-        less secure random number generator.  This option may be used
-        for keys which are only used for a short time and do not
-        require full cryptographic strength.  It takes only effect if
-        used together with the option no-protection.
-
-   o The order of the parameters does not matter except for "Key-Type"
-     which must be the first parameter.  The parameters are only for the
-     generated keyblock and parameters from previous key generations are not
-     used. Some syntactically checks may be performed.
-     The currently defined parameters are:
-     Key-Type: <algo-number>|<algo-string>
-       Starts a new parameter block by giving the type of the primary
-       key. The algorithm must be capable of signing.  This is a
-       required parameter.  It may be "default" to use the default
-       one; in this case don't give a Key-Usage and use "default" for
-       the Subkey-Type.
-     Key-Length: <length-in-bits>
-       Length of the key in bits.  The default is returned by running
-        the command "gpg --gpgconf-list".
-     Key-Usage: <usage-list>
-        Space or comma delimited list of key usage, allowed values are
-        "encrypt", "sign", and "auth".  This is used to generate the
-        key flags.  Please make sure that the algorithm is capable of
-        this usage.  Note that OpenPGP requires that all primary keys
-        are capable of certification, so no matter what usage is given
-        here, the "cert" flag will be on.  If no Key-Usage is
-        specified and the key-type is not "default", all allowed
-        usages for that particular algorithm are used; if it is not
-        given but "default" is used the usage will be "sign".
-     Subkey-Type: <algo-number>|<algo-string>
-       This generates a secondary key.  Currently only one subkey
-       can be handled.  "default" is also supported.
-     Subkey-Length: <length-in-bits>
-       Length of the subkey in bits.  The default is returned by running
-        the command "gpg --gpgconf-list".
-     Subkey-Usage: <usage-list>
-        Similar to Key-Usage.
-     Passphrase: <string>
-       If you want to specify a passphrase for the secret key,
-       enter it here.  Default is not to use any passphrase.
-     Name-Real: <string>
-     Name-Comment: <string>
-     Name-Email: <string>
-       The 3 parts of a key. Remember to use UTF-8 here.
-       If you don't give any of them, no user ID is created.
-     Expire-Date: <iso-date>|(<number>[d|w|m|y])
-       Set the expiration date for the key (and the subkey).  It may
-       either be entered in ISO date format (2000-08-15) or as number
-       of days, weeks, month or years.  The special notation
-       "seconds=N" is also allowed to directly give an Epoch
-       value. Without a letter days are assumed.  Note that there is
-       no check done on the overflow of the type used by OpenPGP for
-       timestamps.  Thus you better make sure that the given value
-       make sense.  Although OpenPGP works with time intervals, GnuPG
-       uses an absolute value internally and thus the last year we
-       can represent is 2105.
-     Creation-Date: <iso-date>
-        Set the creation date of the key as stored in the key
-        information and which is also part of the fingerprint
-        calculation.  Either a date like "1986-04-26" or a full
-        timestamp like "19860426T042640" may be used.  The time is
-        considered to be UTC.  If it is not given the current time
-        is used.
-     Preferences: <string>
-        Set the cipher, hash, and compression preference values for
-       this key.  This expects the same type of string as "setpref"
-       in the --edit menu.
-     Revoker: <algo>:<fpr> [sensitive]
-        Add a designated revoker to the generated key.  Algo is the
-       public key algorithm of the designated revoker (i.e. RSA=1,
-       DSA=17, etc.)  Fpr is the fingerprint of the designated
-       revoker.  The optional "sensitive" flag marks the designated
-       revoker as sensitive information.  Only v4 keys may be
-       designated revokers.
-     Handle: <string>
-        This is an optional parameter only used with the status lines
-        KEY_CREATED and KEY_NOT_CREATED.  STRING may be up to 100
-        characters and should not contain spaces.  It is useful for
-        batch key generation to associate a key parameter block with a
-        status line.
-     Keyserver: <string>
-        This is an optional parameter that specifies the preferred
-        keyserver URL for the key.
-
-
-Here is an example on how to create a key:
-$ cat >foo <<EOF
-     %echo Generating a basic OpenPGP key
-     Key-Type: DSA
-     Key-Length: 1024
-     Subkey-Type: ELG-E
-     Subkey-Length: 1024
-     Name-Real: Joe Tester
-     Name-Comment: with stupid passphrase
-     Name-Email: joe@foo.bar
-     Expire-Date: 0
-     Passphrase: abc
-     %pubring foo.pub
-     %secring foo.sec
-     # Do a commit here, so that we can later print "done" :-)
-     %commit
-     %echo done
-EOF
-$ gpg --batch --gen-key foo
- [...]
-$ gpg --no-default-keyring --secret-keyring ./foo.sec \
-                                 --keyring ./foo.pub --list-secret-keys
-/home/wk/work/gnupg-stable/scratch/foo.sec
-------------------------------------------
-sec  1024D/915A878D 2000-03-09 Joe Tester (with stupid passphrase) <joe@foo.bar>
-ssb  1024g/8F70E2C0 2000-03-09
-
-If you want to create a key with the default algorithms you would
-use these parameters:
-
-     %echo Generating a default key
-     Key-Type: default
-     Subkey-Type: default
-     Name-Real: Joe Tester
-     Name-Comment: with stupid passphrase
-     Name-Email: joe@foo.bar
-     Expire-Date: 0
-     Passphrase: abc
-     %pubring foo.pub
-     %secring foo.sec
-     # Do a commit here, so that we can later print "done" :-)
-     %commit
-     %echo done
-
-
-
-
-Layout of the TrustDB
-=====================
-The TrustDB is built from fixed length records, where the first byte
-describes the record type.  All numeric values are stored in network
-byte order. The length of each record is 40 bytes. The first record of
-the DB is always of type 1 and this is the only record of this type.
-
-FIXME:  The layout changed, document it here.
+    - Field 3 :: Trust model
 
+                 - 0 :: Classic trust model, as used in PGP 2.x.
+                 - 1 :: PGP trust model, as used in PGP 6 and later.
+                        This is the same as the classic trust model,
+                        except for the addition of trust signatures.
+
+                 GnuPG before version 1.4 used the classic trust model
+                 by default. GnuPG 1.4 and later uses the PGP trust
+                 model by default.
+
+    - Field 4 :: Date trustdb was created in seconds since Epoch.
+    - Field 5 :: Date trustdb will expire in seconds since Epoch.
+    - Field 6 :: Number of marginally trusted users to introduce a new
+                 key signer (gpg's option --marginals-needed).
+    - Field 7 :: Number of completely trusted users to introduce a new
+                 key signer.  (gpg's option --completes-needed)
+
+    - Field 8 :: Maximum depth of a certification chain. (gpg's option
+                 --max-cert-depth)
+
+*** SPK - Signature subpacket records
+
+    - Field 2 :: Subpacket number as per RFC-4880 and later.
+    - Field 3 :: Flags in hex.  Currently the only two bits assigned
+                 are 1, to indicate that the subpacket came from the
+                 hashed part of the signature, and 2, to indicate the
+                 subpacket was marked critical.
+    - Field 4 :: Length of the subpacket.  Note that this is the
+                 length of the subpacket, and not the length of field
+                 5 below.  Due to the need for %-encoding, the length
+                 of field 5 may be up to 3x this value.
+    - Field 5 :: The subpacket data.  Printable ASCII is shown as
+                 ASCII, but other values are rendered as %XX where XX
+                 is the hex value for the byte.
+
+*** CFG - Configuration data
+
+    --list-config outputs information about the GnuPG configuration
+    for the benefit of frontends or other programs that call GnuPG.
+    There are several list-config items, all colon delimited like the
+    rest of the --with-colons output.  The first field is always "cfg"
+    to indicate configuration information.  The second field is one of
+    (with examples):
+
+    - version :: The third field contains the version of GnuPG.
+
+                 : cfg:version:1.3.5
+
+    - pubkey :: The third field contains the public key algorithms
+                this version of GnuPG supports, separated by
+                semicolons.  The algorithm numbers are as specified in
+                RFC-4880.  Note that in contrast to the --status-fd
+                interface these are _not_ the Libgcrypt identifiers.
+
+                 : cfg:pubkey:1;2;3;16;17
+
+    - cipher :: The third field contains the symmetric ciphers this
+                version of GnuPG supports, separated by semicolons.
+                The cipher numbers are as specified in RFC-4880.
+
+                 : cfg:cipher:2;3;4;7;8;9;10
+
+    - digest :: The third field contains the digest (hash) algorithms
+                this version of GnuPG supports, separated by
+                semicolons.  The digest numbers are as specified in
+                RFC-4880.
+
+                 : cfg:digest:1;2;3;8;9;10
+
+    - compress :: The third field contains the compression algorithms
+                  this version of GnuPG supports, separated by
+                  semicolons.  The algorithm numbers are as specified
+                  in RFC-4880.
+
+                 : cfg:compress:0;1;2;3
+
+    - group :: The third field contains the name of the group, and the
+               fourth field contains the values that the group expands
+               to, separated by semicolons.
+
+               For example, a group of:
+                 : group mynames = paige 0x12345678 joe patti
+               would result in:
+                 : cfg:group:mynames:patti;joe;0x12345678;paige
+
+
+* Format of the --status-fd output
+
+  Every line is prefixed with "[GNUPG:] ", followed by a keyword with
+  the type of the status line and some arguments depending on the type
+  (maybe none); an application should always be prepared to see more
+  arguments in future versions.
+
+** General status codes
+*** NEWSIG
+    May be issued right before a signature verification starts.  This
+    is useful to define a context for parsing ERROR status messages.
+    No arguments are currently defined.
+
+*** GOODSIG  <long_keyid_or_fpr>  <username>
+    The signature with the keyid is good.  For each signature only one
+    of the codes GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG or
+    ERRSIG will be emitted.  In the past they were used as a marker
+    for a new signature; new code should use the NEWSIG status
+    instead.  The username is the primary one encoded in UTF-8 and %XX
+    escaped. The fingerprint may be used instead of the long keyid if
+    it is available.  This is the case with CMS and might eventually
+    also be available for OpenPGP.
+
+*** EXPSIG  <long_keyid_or_fpr>  <username>
+    The signature with the keyid is good, but the signature is
+    expired. The username is the primary one encoded in UTF-8 and %XX
+    escaped. The fingerprint may be used instead of the long keyid if
+    it is available.  This is the case with CMS and might eventually
+    also be available for OpenPGP.
+
+*** EXPKEYSIG  <long_keyid_or_fpr> <username>
+    The signature with the keyid is good, but the signature was made
+    by an expired key. The username is the primary one encoded in
+    UTF-8 and %XX escaped.  The fingerprint may be used instead of the
+    long keyid if it is available.  This is the case with CMS and
+    might eventually also be available for OpenPGP.
+
+*** REVKEYSIG  <long_keyid_or_fpr>  <username>
+    The signature with the keyid is good, but the signature was made
+    by a revoked key. The username is the primary one encoded in UTF-8
+    and %XX escaped. The fingerprint may be used instead of the long
+    keyid if it is available.  This is the case with CMS and might
+    eventually also beñ available for OpenPGP.
+
+*** BADSIG  <long_keyid_or_fpr>  <username>
+    The signature with the keyid has not been verified okay.  The
+    username is the primary one encoded in UTF-8 and %XX escaped. The
+    fingerprint may be used instead of the long keyid if it is
+    available.  This is the case with CMS and might eventually also be
+    available for OpenPGP.
+
+*** ERRSIG  <keyid>  <pkalgo> <hashalgo> <sig_class> <time> <rc>
+    It was not possible to check the signature.  This may be caused by
+    a missing public key or an unsupported algorithm.  A RC of 4
+    indicates unknown algorithm, a 9 indicates a missing public
+    key. The other fields give more information about this signature.
+    sig_class is a 2 byte hex-value.  The fingerprint may be used
+    instead of the keyid if it is available.  This is the case with
+    gpgsm and might eventually also be available for OpenPGP.
+
+    Note, that TIME may either be the number of seconds since Epoch or
+    an ISO 8601 string.  The latter can be detected by the presence of
+    the letter 'T'.
+
+*** VALIDSIG <args>
+
+    The args are:
+
+    - <fingerprint_in_hex>
+    - <sig_creation_date>
+    - <sig-timestamp>
+    - <expire-timestamp>
+    - <sig-version>
+    - <reserved>
+    - <pubkey-algo>
+    - <hash-algo>
+    - <sig-class>
+    - [ <primary-key-fpr> ]
+
+    This status indicates that the signature is good. This is the same
+    as GOODSIG but has the fingerprint as the argument. Both status
+    lines are emitted for a good signature.  All arguments here are on
+    one long line.  sig-timestamp is the signature creation time in
+    seconds after the epoch. expire-timestamp is the signature
+    expiration time in seconds after the epoch (zero means "does not
+    expire"). sig-version, pubkey-algo, hash-algo, and sig-class (a
+    2-byte hex value) are all straight from the signature packet.
+    PRIMARY-KEY-FPR is the fingerprint of the primary key or identical
+    to the first argument.  This is useful to get back to the primary
+    key without running gpg again for this purpose.
+
+    The primary-key-fpr parameter is used for OpenPGP and not
+    class is not defined for CMS and currently set to 0 and 00.
+    available for CMS signatures.  The sig-version as well as the sig
+
+    Note, that *-TIMESTAMP may either be a number of seconds since
+    Epoch or an ISO 8601 string which can be detected by the presence
+    of the letter 'T'.
+
+*** SIG_ID  <radix64_string>  <sig_creation_date>  <sig-timestamp>
+    This is emitted only for signatures of class 0 or 1 which have
+    been verified okay.  The string is a signature id and may be used
+    in applications to detect replay attacks of signed messages.  Note
+    that only DLP algorithms give unique ids - others may yield
+    duplicated ones when they have been created in the same second.
+
+    Note, that SIG-TIMESTAMP may either be a number of seconds since
+    Epoch or an ISO 8601 string which can be detected by the presence
+    of the letter 'T'.
+
+*** ENC_TO  <long_keyid>  <keytype>  <keylength>
+    The message is encrypted to this LONG_KEYID.  KEYTYPE is the
+    numerical value of the public key algorithm or 0 if it is not
+    known, KEYLENGTH is the length of the key or 0 if it is not known
+    (which is currently always the case).  Gpg prints this line
+    always; Gpgsm only if it knows the certificate.
+
+*** BEGIN_DECRYPTION
+    Mark the start of the actual decryption process.  This is also
+    emitted when in --list-only mode.
+*** END_DECRYPTION
+    Mark the end of the actual decryption process.  This are also
+    emitted when in --list-only mode.
+*** DECRYPTION_INFO <mdc_method> <sym_algo>
+    Print information about the symmetric encryption algorithm and the
+    MDC method.  This will be emitted even if the decryption fails.
+
+*** DECRYPTION_FAILED
+    The symmetric decryption failed - one reason could be a wrong
+    passphrase for a symmetrical encrypted message.
+
+*** DECRYPTION_OKAY
+    The decryption process succeeded.  This means, that either the
+    correct secret key has been used or the correct passphrase for a
+    conventional encrypted message was given.  The program itself may
+    return an errorcode because it may not be possible to verify a
+    signature for some reasons.
+
+*** SESSION_KEY <algo>:<hexdigits>
+    The session key used to decrypt the message.  This message will
+    only be emitted if the option --show-session-key is used.  The
+    format is suitable to be passed as value for the option
+    --override-session-key.  It is not an indication that the
+    decryption will or has succeeded.
+
+*** BEGIN_ENCRYPTION  <mdc_method> <sym_algo>
+    Mark the start of the actual encryption process.
+
+*** END_ENCRYPTION
+    Mark the end of the actual encryption process.
+
+*** FILE_START <what> <filename>
+    Start processing a file <filename>.  <what> indicates the performed
+    operation:
+    - 1 :: verify
+    - 2 :: encrypt
+    - 3 :: decrypt
+
+*** FILE_DONE
+    Marks the end of a file processing which has been started
+    by FILE_START.
+
+*** BEGIN_SIGNING
+    Mark the start of the actual signing process. This may be used as
+    an indication that all requested secret keys are ready for use.
+
+*** ALREADY_SIGNED <long-keyid>
+    Warning: This is experimental and might be removed at any time.
+
+*** SIG_CREATED <type> <pk_algo> <hash_algo> <class> <timestamp> <keyfpr>
+    A signature has been created using these parameters.
+    Values for type <type> are:
+      - D :: detached
+      - C :: cleartext
+      - S :: standard
+    (only the first character should be checked)
+
+    <class> are 2 hex digits with the OpenPGP signature class.
+
+    Note, that TIMESTAMP may either be a number of seconds since Epoch
+    or an ISO 8601 string which can be detected by the presence of the
+    letter 'T'.
+
+*** NOTATION_
+    There are actually two related status codes to convey notation
+    data:
+
+    - NOTATION_NAME <name>
+    - NOTATION_DATA <string>
+
+    <name> and <string> are %XX escaped; the data may be split among
+    several NOTATION_DATA lines.
+
+*** POLICY_URL <string>
+    Note that URL in <string> is %XX escaped.
+
+*** PLAINTEXT <format> <timestamp> <filename>
+    This indicates the format of the plaintext that is about to be
+    written.  The format is a 1 byte hex code that shows the format of
+    the plaintext: 62 ('b') is binary data, 74 ('t') is text data with
+    no character set specified, and 75 ('u') is text data encoded in
+    the UTF-8 character set.  The timestamp is in seconds since the
+    epoch.  If a filename is available it gets printed as the third
+    argument, percent-escaped as usual.
+
+*** PLAINTEXT_LENGTH <length>
+    This indicates the length of the plaintext that is about to be
+    written.  Note that if the plaintext packet has partial length
+    encoding it is not possible to know the length ahead of time.  In
+    that case, this status tag does not appear.
+
+*** ATTRIBUTE <arguments>
+    The list or argemnts are:
+    - <fpr>
+    - <octets>
+    - <type>
+    - <index>
+    - <count>
+    - <timestamp>
+    - <expiredate>
+    - <flags>
+
+    This is one long line issued for each attribute subpacket when an
+    attribute packet is seen during key listing.  <fpr> is the
+    fingerprint of the key.  <octets> is the length of the attribute
+    subpacket.  <type> is the attribute type (e.g. 1 for an image).
+    <index> and <count> indicate that this is the N-th indexed
+    subpacket of count total subpackets in this attribute packet.
+    <timestamp> and <expiredate> are from the self-signature on the
+    attribute packet.  If the attribute packet does not have a valid
+    self-signature, then the timestamp is 0.  <flags> are a bitwise OR
+    of:
+    - 0x01 :: this attribute packet is a primary uid
+    - 0x02 :: this attribute packet is revoked
+    - 0x04 :: this attribute packet is expired
+
+*** SIG_SUBPACKET <type> <flags> <len> <data>
+    This indicates that a signature subpacket was seen.  The format is
+    the same as the "spk" record above.
+
+** Key related
+*** INV_RECP, INV_SGNR
+    The two similar status codes:
+
+    - INV_RECP <reason> <requested_recipient>
+    - INV_SGNR <reason> <requested_sender>
+
+    are issued for each unusable recipient/sender. The reasons codes
+    currently in use are:
+
+       -  0 :: No specific reason given
+       -  1 :: Not Found
+       -  2 :: Ambigious specification
+       -  3 :: Wrong key usage
+       -  4 :: Key revoked
+       -  5 :: Key expired
+       -  6 :: No CRL known
+       -  7 :: CRL too old
+       -  8 :: Policy mismatch
+       -  9 :: Not a secret key
+       - 10 :: Key not trusted
+       - 11 :: Missing certificate
+       - 12 :: Missing issuer certificate
+       - 13 :: Key disabled
+       - 14 :: Syntax error in specification
+
+    Note that for historical reasons the INV_RECP status is also used
+    for gpgsm's SIGNER command where it relates to signer's of course.
+    Newer GnuPG versions are using INV_SGNR; applications should
+    ignore the INV_RECP during the sender's command processing once
+    they have seen an INV_SGNR.  Different codes are used so that they
+    can be distinguish while doing an encrypt+sign operation.
+*** NO_RECP <reserved>
+    Issued if no recipients are usable.
+
+*** NO_SGNR <reserved>
+    Issued if no senders are usable.
+
+*** KEYEXPIRED <expire-timestamp>
+    The key has expired.  expire-timestamp is the expiration time in
+    seconds since Epoch.  This status line is not very useful because
+    it will also be emitted for expired subkeys even if this subkey is
+    not used.  To check whether a key used to sign a message has
+    expired, the EXPKEYSIG status line is to be used.
+
+    Note, that the TIMESTAMP may either be a number of seconds since
+    Epoch or an ISO 8601 string which can be detected by the presence
+    of the letter 'T'.
+
+*** KEYREVOKED
+    The used key has been revoked by its owner.  No arguments yet.
+
+*** NO_PUBKEY  <long keyid>
+    The public key is not available
+
+*** NO_SECKEY  <long keyid>
+    The secret key is not available
+
+*** KEY_CREATED <type> <fingerprint> [<handle>]
+    A key has been created.  Values for <type> are:
+      - B :: primary and subkey
+      - P :: primary
+      - S :: subkey
+    The fingerprint is one of the primary key for type B and P and the
+    one of the subkey for S.  Handle is an arbitrary non-whitespace
+    string used to match key parameters from batch key creation run.
+
+*** KEY_NOT_CREATED [<handle>]
+    The key from batch run has not been created due to errors.
+
+*** TRUST_
+    These are several similar status codes:
+
+    - TRUST_UNDEFINED <error_token>
+    - TRUST_NEVER     <error_token>
+    - TRUST_MARGINAL  [0  [<validation_model>]]
+    - TRUST_FULLY     [0  [<validation_model>]]
+    - TRUST_ULTIMATE  [0  [<validation_model>]]
+
+    For good signatures one of these status lines are emitted to
+    indicate the validity of the key used to create the signature.
+    The error token values are currently only emitted by gpgsm.
+
+    VALIDATION_MODEL describes the algorithm used to check the
+    validity of the key.  The defaults are the standard Web of Trust
+    model for gpg and the the standard X.509 model for gpgsm.  The
+    defined values are
+
+       - pgp   :: The standard PGP WoT.
+       - shell :: The standard X.509 model.
+       - chain :: The chain model.
+       - steed :: The STEED model.
+
+    Note that the term =TRUST_= in the status names is used for
+    historic reasons; we now speak of validity.
+
+*** PKA_TRUST_
+    This is is one:
+
+    - PKA_TRUST_GOOD <mailbox>
+    - PKA_TRUST_BAD  <mailbox>
+
+    Depending on the outcome of the PKA check one of the above status
+    codes is emitted in addition to a =TRUST_*= status.
+
+** Remote control
+*** GET_BOOL, GET_LINE, GET_HIDDEN, GOT_IT
+
+    These status line are used with --command-fd for interactive
+    control of the process.
+
+*** USERID_HINT <long main keyid> <string>
+    Give a hint about the user ID for a certain keyID.
+
+*** NEED_PASSPHRASE <long keyid> <long main keyid> <keytype> <keylength>
+    Issued whenever a passphrase is needed.  KEYTYPE is the numerical
+    value of the public key algorithm or 0 if this is not applicable,
+    KEYLENGTH is the length of the key or 0 if it is not known (this
+    is currently always the case).
+
+*** NEED_PASSPHRASE_SYM <cipher_algo> <s2k_mode> <s2k_hash>
+    Issued whenever a passphrase for symmetric encryption is needed.
+
+*** NEED_PASSPHRASE_PIN <card_type> <chvno> [<serialno>]
+    Issued whenever a PIN is requested to unlock a card.
+
+*** MISSING_PASSPHRASE
+    No passphrase was supplied.  An application which encounters this
+    message may want to stop parsing immediately because the next
+    message will probably be a BAD_PASSPHRASE.  However, if the
+    application is a wrapper around the key edit menu functionality it
+    might not make sense to stop parsing but simply ignoring the
+    following BAD_PASSPHRASE.
+
+*** BAD_PASSPHRASE <long keyid>
+    The supplied passphrase was wrong or not given.  In the latter
+    case you may have seen a MISSING_PASSPHRASE.
+
+*** GOOD_PASSPHRASE
+    The supplied passphrase was good and the secret key material
+    is therefore usable.
+
+** Import/Export
+*** IMPORT_CHECK <long keyid> <fingerprint> <user ID>
+    This status is emitted in interactive mode right before
+    the "import.okay" prompt.
+
+*** IMPORTED   <long keyid>  <username>
+    The keyid and name of the signature just imported
+
+*** IMPORT_OK  <reason> [<fingerprint>]
+    The key with the primary key's FINGERPRINT has been imported.
+    REASON flags are:
+
+    - 0 :: Not actually changed
+    - 1 :: Entirely new key.
+    - 2 :: New user IDs
+    - 4 :: New signatures
+    - 8 :: New subkeys
+    - 16 :: Contains private key.
+
+    The flags may be ORed.
+
+*** IMPORT_PROBLEM <reason> [<fingerprint>]
+    Issued for each import failure.  Reason codes are:
+
+    - 0 :: No specific reason given.
+    - 1 :: Invalid Certificate.
+    - 2 :: Issuer Certificate missing.
+    - 3 :: Certificate Chain too long.
+    - 4 :: Error storing certificate.
+
+*** IMPORT_RES <args>
+    Final statistics on import process (this is one long line). The
+    args are a list of unsigned numbers separated by white space:
+
+    - <count>
+    - <no_user_id>
+    - <imported>
+    - always 0 (formerly used for the number of RSA keys)
+    - <unchanged>
+    - <n_uids>
+    - <n_subk>
+    - <n_sigs>
+    - <n_revoc>
+    - <sec_read>
+    - <sec_imported>
+    - <sec_dups>
+    - <skipped_new_keys>
+    - <not_imported>
+
+** Smartcard related
+*** CARDCTRL <what> [<serialno>]
+    This is used to control smartcard operations.  Defined values for
+    WHAT are:
+
+      - 1 :: Request insertion of a card.  Serialnumber may be given
+             to request a specific card.  Used by gpg 1.4 w/o
+             scdaemon
+      - 2 :: Request removal of a card.  Used by gpg 1.4 w/o scdaemon.
+      - 3 :: Card with serialnumber detected
+      - 4 :: No card available
+      - 5 :: No card reader available
+      - 6 :: No card support available
+
+*** SC_OP_FAILURE [<code>]
+    An operation on a smartcard definitely failed.  Currently there is
+    no indication of the actual error code, but application should be
+    prepared to later accept more arguments.  Defined values for
+    <code> are:
+
+      - 0 :: unspecified error (identically to a missing CODE)
+      - 1 :: canceled
+      - 2 :: bad PIN
+
+*** SC_OP_SUCCESS
+    A smart card operaion succeeded.  This status is only printed for
+    certain operation and is mostly useful to check whether a PIN
+    change really worked.
+
+** Miscellaneous status codes
+*** NODATA  <what>
+    No data has been found.  Codes for WHAT are:
+
+    - 1 :: No armored data.
+    - 2 :: Expected a packet but did not found one.
+    - 3 :: Invalid packet found, this may indicate a non OpenPGP
+           message.
+    - 4 :: Signature expected but not found
+
+    You may see more than one of these status lines.
+
+*** UNEXPECTED <what>
+    Unexpected data has been encountered.  Codes for WHAT are:
+    - 0 :: Not further specified
+    - 1 :: Corrupted message structure
+
+*** TRUNCATED <maxno>
+    The output was truncated to MAXNO items.  This status code is
+    issued for certain external requests.
+
+*** ERROR <error location> <error code> [<more>]
+    This is a generic error status message, it might be followed by
+    error location specific data. <error code> and <error_location>
+    should not contain spaces.  The error code is a either a string
+    commencing with a letter or such a string prefixed with a
+    numerical error code and an underscore; e.g.: "151011327_EOF".
+
+*** SUCCESS [<location>]
+    Postive confirimation that an operation succeeded.  <location> is
+    optional but if given should not contain spaces.  Used only with a
+    few commands.
+
+*** BADARMOR
+    The ASCII armor is corrupted.  No arguments yet.
+
+*** DELETE_PROBLEM <reason_code>
+    Deleting a key failed.  Reason codes are:
+    - 1 :: No such key
+    - 2 :: Must delete secret key first
+    - 3 :: Ambigious specification
+    - 4 :: Key is stored on a smartcard.
+
+*** PROGRESS <what> <char> <cur> <total>
+    Used by the primegen and Public key functions to indicate
+    progress.  <char> is the character displayed with no --status-fd
+    enabled, with the linefeed replaced by an 'X'.  <cur> is the
+    current amount done and <total> is amount to be done; a <total> of
+    0 indicates that the total amount is not known. The condition
+      :       TOTAL && CUR == TOTAL
+    may be used to detect the end of an operation.
+
+    Well known values for WHAT are:
+
+           - pk_dsa   :: DSA key generation
+           - pk_elg   :: Elgamal key generation
+           - primegen :: Prime generation
+           - need_entropy :: Waiting for new entropy in the RNG
+           - tick :: Generic tick without any special meaning - useful
+                     for letting clients know that the server is still
+                     working.
+           - starting_agent :: A gpg-agent was started because it is not
+                                running as a daemon.
+           - learncard :: Send by the agent and gpgsm while learing
+                          the data of a smartcard.
+           - card_busy :: A smartcard is still working
+
+*** BACKUP_KEY_CREATED <fingerprint> <fname>
+    A backup of a key identified by <fingerprint> has been writte to
+    the file <fname>; <fname> is percent-escaped.
+
+*** MOUNTPOINT <name>
+    <name> is a percent-plus escaped filename describing the
+    mountpoint for the current operation (e.g. used by "g13 --mount").
+    This may either be the specified mountpoint or one randomly
+    choosen by g13.
+
+*** PINENTRY_LAUNCHED <pid>
+    This status line is emitted by gpg to notify a client that a
+    Pinentry has been launched.  <pid> is the PID of the Pinentry.  It
+    may be used to display a hint to the user but can't be used to
+    synchronize with Pinentry.  Note that there is also an Assuan
+    inquiry line with the same name used internally or, if enabled,
+    send to the client instead of this status line.  Such an inquiry
+    may be used to sync with Pinentry
+
+** Obsolete status codes
+*** SIGEXPIRED
+    Removed on 2011-02-04.  This is deprecated in favor of KEYEXPIRED.
+*** RSA_OR_IDEA
+    Obsolete.  This status message used to be emitted for requests to
+    use the IDEA or RSA algorithms.  It has been dropped from GnuPG
+    2.1 after the respective patents expired.
+*** SHM_INFO, SHM_GET, SHM_GET_BOOL, SHM_GET_HIDDEN
+    These were used for the ancient shared memory based co-processing.
+*** BEGIN_STREAM, END_STREAM
+    Used to issued by the experimental pipemode.
+
+
+* Format of the --attribute-fd output
+
+  When --attribute-fd is set, during key listings (--list-keys,
+  --list-secret-keys) GnuPG dumps each attribute packet to the file
+  descriptor specified.  --attribute-fd is intended for use with
+  --status-fd as part of the required information is carried on the
+  ATTRIBUTE status tag (see above).
+
+  The contents of the attribute data is specified by RFC 4880.  For
+  convenience, here is the Photo ID format, as it is currently the
+  only attribute defined:
+
+  - Byte 0-1 :: The length of the image header.  Due to a historical
+                accident (i.e. oops!) back in the NAI PGP days, this
+                is a little-endian number.  Currently 16 (0x10 0x00).
+
+  - Byte 2 :: The image header version.  Currently 0x01.
+
+  - Byte 3 :: Encoding format.  0x01 == JPEG.
+
+  - Byte 4-15 :: Reserved, and currently unused.
+
+  All other data after this header is raw image (JPEG) data.
+
+
+* Unattended key generation
+
+   Please see the GnuPG manual for a description.
+
+
+* Layout of the TrustDB
+
+  The TrustDB is built from fixed length records, where the first byte
+  describes the record type.  All numeric values are stored in network
+  byte order. The length of each record is 40 bytes. The first record
+  of the DB is always of type 1 and this is the only record of this
+  type.
+
+  FIXME:  The layout changed, document it here.
+#+begin_example
   Record type 0:
   --------------
     Unused record, can be reused for any purpose.
@@ -1187,145 +1118,119 @@ FIXME:  The layout changed, document it here.
      1 byte  value 254
      1 byte  reserved (0)
      1 u32   next_free
+#+end_example
 
 
+* GNU extensions to the S2K algorithm
 
-GNU extensions to the S2K algorithm
-===================================
-S2K mode 101 is used to identify these extensions.
-After the hash algorithm the 3 bytes "GNU" are used to make
-clear that these are extensions for GNU, the next bytes gives the
-GNU protection mode - 1000.  Defined modes are:
-  1001 - do not store the secret part at all
-  1002 - a stub to access smartcards (not used in 1.2.x)
-
-
-
-Other Notes
-===========
-    * For packet version 3 we calculate the keyids this way:
-       RSA     := low 64 bits of n
-       ELGAMAL := build a v3 pubkey packet (with CTB 0x99) and calculate
-                  a rmd160 hash value from it. This is used as the
-                  fingerprint and the low 64 bits are the keyid.
-
-    * Revocation certificates consist only of the signature packet;
-      "import" knows how to handle this.  The rationale behind it is
-      to keep them small.
+  S2K mode 101 is used to identify these extensions.
+  After the hash algorithm the 3 bytes "GNU" are used to make
+  clear that these are extensions for GNU, the next bytes gives the
+  GNU protection mode - 1000.  Defined modes are:
+  - 1001 :: Do not store the secret part at all.
+  - 1002 :: A stub to access smartcards (not used in 1.2.x)
 
+* Keyserver helper message format
 
-OIDs below the GnuPG arc:
-=========================
+  The keyserver may be contacted by a Unix Domain socket or via TCP.
 
- 1.3.6.1.4.1.11591.2          GnuPG
- 1.3.6.1.4.1.11591.2.1          notation
- 1.3.6.1.4.1.11591.2.1.1          pkaAddress
- 1.3.6.1.4.1.11591.2.12242973   invalid encoded OID
+  The format of a request is:
+#+begin_example
+  command-tag
+  "Content-length:" digits
+  CRLF
+#+end_example
 
+  Where command-tag is
 
-
-Keyserver Message Format
-=========================
-
-The keyserver may be contacted by a Unix Domain socket or via TCP.
-
-The format of a request is:
-
-====
-command-tag
-"Content-length:" digits
-CRLF
-=======
-
-Where command-tag is
-
-NOOP
-GET <user-name>
-PUT
-DELETE <user-name>
-
+#+begin_example
+  NOOP
+  GET <user-name>
+  PUT
+  DELETE <user-name>
+#+end_example
 
 The format of a response is:
 
-======
-"GNUPG/1.0" status-code status-text
-"Content-length:" digits
-CRLF
-============
+#+begin_example
+  "GNUPG/1.0" status-code status-text
+  "Content-length:" digits
+  CRLF
+#+end_example
 followed by <digits> bytes of data
 
-
 Status codes are:
 
-     o 1xx: Informational - Request received, continuing process
+  - 1xx :: Informational - Request received, continuing process
+
+  - 2xx :: Success - The action was successfully received, understood,
+           and accepted
 
-     o 2xx: Success - The action was successfully received, understood,
-       and accepted
+  - 4xx :: Client Error - The request contains bad syntax or cannot be
+           fulfilled
 
-     o 4xx: Client Error - The request contains bad syntax or cannot be
-       fulfilled
+  - 5xx :: Server Error - The server failed to fulfill an apparently
+           valid request
 
-     o 5xx: Server Error - The server failed to fulfill an apparently
-       valid request
 
+* Object identifiers
 
+  OIDs below the GnuPG arc:
 
-Documentation on HKP (the http keyserver protocol):
+#+begin_example
+  1.3.6.1.4.1.11591.2          GnuPG
+  1.3.6.1.4.1.11591.2.1          notation
+  1.3.6.1.4.1.11591.2.1.1          pkaAddress
+  1.3.6.1.4.1.11591.2.2          X.509 extensions
+  1.3.6.1.4.1.11591.2.2.1          standaloneCertificate
+  1.3.6.1.4.1.11591.2.2.2          wellKnownPrivateKey
+  1.3.6.1.4.1.11591.2.12242973   invalid encoded OID
+#+end_example
 
-A minimalistic HTTP server on port 11371 recognizes a GET for /pks/lookup.
-The standard http URL encoded query parameters are this (always key=value):
 
-- op=index (like pgp -kv), op=vindex (like pgp -kvv) and op=get (like
-  pgp -kxa)
 
-- search=<stringlist>. This is a list of words that must occur in the key.
-  The words are delimited with space, points, @ and so on. The delimiters
-  are not searched for and the order of the words doesn't matter (but see
-  next option).
+* Miscellaneous notes
 
-- exact=on. This switch tells the hkp server to only report exact matching
-  keys back. In this case the order and the "delimiters" are important.
+** v3 fingerprints
+   For packet version 3 we calculate the keyids this way:
+    - RSA :: Low 64 bits of n
+    - ELGAMAL :: Build a v3 pubkey packet (with CTB 0x99) and
+                 calculate a RMD160 hash value from it. This is used
+                 as the fingerprint and the low 64 bits are the keyid.
 
-- fingerprint=on. Also reports the fingerprints when used with 'index' or
-  'vindex'
+** Simplified revocation certificates
+  Revocation certificates consist only of the signature packet;
+  "--import" knows how to handle this.  The rationale behind it is to
+  keep them small.
 
-The keyserver also recognizes http-POSTs to /pks/add. Use this to upload
-keys.
+** Documentation on HKP (the http keyserver protocol):
 
+   A minimalistic HTTP server on port 11371 recognizes a GET for
+   /pks/lookup.  The standard http URL encoded query parameters are
+   this (always key=value):
 
-A better way to do this would be a request like:
+   - op=index (like pgp -kv), op=vindex (like pgp -kvv) and op=get (like
+     pgp -kxa)
 
-   /pks/lookup/<gnupg_formatierte_user_id>?op=<operation>
+   - search=<stringlist>. This is a list of words that must occur in the key.
+     The words are delimited with space, points, @ and so on. The delimiters
+     are not searched for and the order of the words doesn't matter (but see
+     next option).
 
-This can be implemented using Hurd's translator mechanism.
-However, I think the whole key server stuff has to be re-thought;
-I have some ideas and probably create a white paper.
+   - exact=on. This switch tells the hkp server to only report exact matching
+     keys back. In this case the order and the "delimiters" are important.
 
+   - fingerprint=on. Also reports the fingerprints when used with 'index' or
+     'vindex'
 
-Algorithm names for the "keygen.algo" prompt
-============================================
+   The keyserver also recognizes http-POSTs to /pks/add. Use this to upload
+   keys.
 
-  When using a --command-fd controlled key generation or "addkey"
-  there is way to know the number to enter on the "keygen.algo"
-  prompt.  The displayed numbers are for human reception and may
-  change with releases.  To provide a stable way to enter a desired
-  algorithm choice the prompt also accepts predefined names for the
-  algorithms, which will not change.
 
-   | Name    | No | Description                     |
-   |---------+----+---------------------------------|
-   | rsa+rsa |  1 | RSA and RSA (default)           |
-   | dsa+elg |  2 | DSA and Elgamal                 |
-   | dsa     |  3 | DSA (sign only)                 |
-   | rsa/s   |  4 | RSA (sign only)                 |
-   | elg     |  5 | Elgamal (encrypt only)          |
-   | rsa/e   |  6 | RSA (encrypt only)              |
-   | dsa/*   |  7 | DSA (set your own capabilities) |
-   | rsa/*   |  8 | RSA (set your own capabilities) |
+   A better way to do this would be a request like:
 
-   If one of the "foo/*" names are used a "keygen.flags" prompt needs
-   to be answered as well.  Instead of toggling the predefined flags,
-   it is also possible to set them direct: Use a "=" character
-   directly followed by a comination of "a" (for authentication), "s"
-   (for signing), or "c" (for certification).
+      /pks/lookup/<gnupg_formatierte_user_id>?op=<operation>
 
+   This can be implemented using Hurd's translator mechanism.
+   However, I think the whole key server stuff has to be re-thought;
+   I have some ideas and probably create a white paper.
index e1b83b7..252bc42 100644 (file)
@@ -1,14 +1,15 @@
-                     A Hacker's Guide to GNUPG
-                  ================================
-                  (Some notes on GNUPG internals.)
+# HACKING                                                       -*- org -*-
+#+TITLE: A Hacker's Guide to GnuPG
+#+TEXT: Some notes on GnuPG internals
+#+STARTUP: showall
+#+OPTIONS: ^:{}
 
-      ************************************************************
-      *** Please see the file HACKING in the GIT master branch ***
-      ***            for up-to-date information.               ***
-      ************************************************************
+* How to contribute
 
+  The following stuff explains some basic procedures you need to
+  follow if you want to contribute code or documentation.
 
-* No more ChangeLog files
+** No more ChangeLog files
 
 Do not modify any of the ChangeLog files in GnuPG.  Starting on
 December 1st, 2011 we put change information only in the GIT commit
@@ -17,27 +18,123 @@ time.  As such, there are strict requirements on the form of the
 commit log messages.  The old ChangeLog files have all be renamed to
 ChangeLog-2011
 
+** Commit log requirements
 
-* Commit log requirements
+Your commit log should always start with a one-line summary, the
+second line should be blank, and the remaining lines are usually
+ChangeLog-style entries for all affected files.  However, it's fine
+--- even recommended --- to write a few lines of prose describing the
+change, when the summary and ChangeLog entries don't give enough of
+the big picture.  Omit the leading TABs that you are seeing in a
+"real" ChangeLog file, but keep the maximum line length at 72 or
+smaller, so that the generated ChangeLog lines, each with its leading
+TAB, will not exceed 80 columns.  If you want to add text which shall
+not be copied to the ChangeLog, separate it by a line consisting of
+two dashes at the begin of a line.
 
-Your commit log should always start with a one-line summary, the second
-line should be blank, and the remaining lines are usually ChangeLog-style
-entries for all affected files.  However, it's fine -- even recommended --
-to write a few lines of prose describing the change, when the summary
-and ChangeLog entries don't give enough of the big picture.  Omit the
-leading TABs that you're used to seeing in a "real" ChangeLog file, but
-keep the maximum line length at 72 or smaller, so that the generated
-ChangeLog lines, each with its leading TAB, will not exceed 80 columns.
+Typo fixes and documentation updates don't need a ChangeLog Entry,
+thus you would use a commit message like
 
+#+begin_example
+Fix type in a comment
 
+--
+#+end_example
 
+The marker line here is important; without it the first line would
+appear in the ChangeLog.
 
-===> What follows is probably out of date <===
+** License policy
 
+  GnuPG is licensed under the GPLv3+ with some files under a mixed
+  LGPLv3+/GPLv2+ license.  It is thus important, that all contributed
+  code allows for an update of the license; for example we can't
+  accept code under the GPLv2(only).
 
+  GnuPG used to have a strict policy of requiring copyright
+  assignments to the FSF.  To avoid this major organizational overhead
+  and to allow inclusion of code, not copyrighted by the FSF, this
+  policy has been relaxed on 2013-03-29.  It is now also possible to
+  contribute code by asserting that the contribution is in accordance
+  to the "Libgcrypt Developer's Certificate of Origin" as found in the
+  file "DCO".  (Except for a slight wording change, this DCO is
+  identical to the one used by the Linux kernel.)
 
-RFCs
-====
+  If your want to contribute code or documentation to GnuPG and you
+  didn't signed a copyright assignment with the FSF in the past, you
+  need to take these simple steps:
+
+  - Decide which mail address you want to use.  Please have your real
+    name in the address and not a pseudonym.  Anonymous contributions
+    can only be done if you find a proxy who certifies for you.
+
+  - If your employer or school might claim ownership of code written
+    by you; you need to talk to them to make sure that you have the
+    right to contribute under the DCO.
+
+  - Send an OpenPGP signed mail to the gnupg-devel@gnupg.org mailing
+    list from your mail address.  Include a copy of the DCO as found
+    in the official master branch.  Insert your name and email address
+    into the DCO in the same way you want to use it later.  Example:
+
+      Signed-off-by: Joe R. Hacker <joe@example.org>
+
+    (If you really need it, you may perform simple transformations of
+    the mail address: Replacing "@" by " at " or "." by " dot ".)
+
+  - That's it.  From now on you only need to add a "Signed-off-by:"
+    line with your name and mail address to the commit message.  It is
+    recommended to send the patches using a PGP/MIME signed mail.
+
+** Coding standards
+
+  Please follow the GNU coding standards.  If you are in doubt consult
+  the existing code as an example.  Do no re-indent code without a
+  need.  If you really need to do it, use a separate commit for such a
+  change.
+
+* Windows
+** How to build an installer for Windows
+
+   Your best bet is to use a decent Debian System for development.
+   You need to install a long list of tools for building.  This list
+   still needs to be compiled.  However, the build process will stop
+   if a tool is missing.  GNU make is required (on non GNU systems
+   often installed as "gmake").  The installer requires a couple of
+   extra software to be available either as tarballs or as local git
+   repositories.  In case this file here is part of a gnupg-w32-2.*.xz
+   complete tarball as distributed from the same place as a binary
+   installer, all such tarballs are already included.
+
+   Cd to the GnuPG source directory and use one of one of these
+   command:
+
+   - If sources are included (gnupg-w32-*.tar.xz)
+
+     make -f build-aux/speedo.mk WHAT=this installer
+
+   - To build from tarballs
+
+     make -f build-aux/speedo.mk WHAT=release TARBALLS=TARDIR installer
+
+   - To build from local GIT repos
+
+     make -f build-aux/speedo.mk WHAT=git TARBALLS=TARDIR installer
+
+   Note that also you need to supply tarballs with supporting
+   libraries even if you build from git.  The makefile expects only
+   the core GnuPG software to be available as local GIT repositories.
+   speedo.mk has the versions of the tarballs and the branch names of
+   the git repositories.  In case of problems, don't hesitate to ask
+   on the gnupg-devel mailing for help.
+
+
+* Debug hints
+
+  See the manual for some hints.
+
+* Standards
+** RFCs
 
 1423  Privacy Enhancement for Internet Electronic Mail:
       Part III: Algorithms, Modes, and Identifiers.
@@ -46,120 +143,124 @@ RFCs
 
 1750  Randomness Recommendations for Security.
 
-1991  PGP Message Exchange Formats.
-
-2015  MIME Security with Pretty Good Privacy (PGP).
+1991  PGP Message Exchange Formats (obsolete)
 
 2144  The CAST-128 Encryption Algorithm.
 
 2279  UTF-8, a transformation format of ISO 10646.
 
-2440  OpenPGP.
-
-
-
-Directory Layout
-----------------
-  ./          Readme, configure
-  ./agent      Gpg-agent and related tools
-  ./doc        Documentation
-  ./doc        Documentation
-  ./g10        Gpg program here called gpg2
-  ./jnlib      Utility functions
-  ./kbx        Keybox library
-  ./scd        Smartcard daemon
-  ./scripts    Scripts needed by configure and others
-  ./sm         Gpgsm program
-
-
-Detailed Roadmap
-----------------
-g10/gpg.c      Main module with option parsing and all the stuff you have
-               to do on startup.  Also has the exout handler and some
-               helper functions.
-g10/sign.c      Create signature and optionally encrypt
-
-g10/parse-packet.c
-g10/build-packet.c
-g10/free-packet.c
-               Parsing and creating of OpenPGP message packets.
-
-g10/getkey.c    Key selection code
-g10/pkclist.c   Build a list of public keys
-g10/skclist.c   Build a list of secret keys
-g10/ringedit.c  Keyring I/O
-g10/keydb.h
-
-g10/keyid.c    Helper functions to get the keyid, fingerprint etc.
-
-
-g10/trustdb.c
-g10/trustdb.h
-g10/tdbdump.c
-               Management of the trustdb.gpg
-
-g10/compress.c Filter to handle compression
-g10/filter.h   Declarations for all filter functions
-g10/delkey.c   Delete a key
-g10/kbnode.c   Helper for the KBNODE linked list
-g10/main.h     Prototypes and some constants
-g10/mainproc.c Message processing
-g10/armor.c    Ascii armor filter
-g10/mdfilter.c Filter to calculate hashs
-g10/textfilter.c Filter to handle CR/LF and trailing white space
-g10/cipher.c   En-/Decryption filter
-g10/misc.c     Utlity functions
-g10/options.h  Structure with all the command line options
-               and related constants
-g10/openfile.c Create/Open Files
-g10/tdbio.c    I/O handling for the trustdb.gpg
-g10/tdbio.h
-g10/hkp.h      Keyserver access
-g10/hkp.c
-g10/packet.h   Defintion of OpenPGP structures.
-g10/passphrase.c  Passphrase handling code
-g10/pubkey-enc.c
-g10/seckey-cert.c
-g10/seskey.c
-g10/import.c
-g10/export.c
-g10/comment.c
-g10/status.c
-g10/status.h
-g10/sign.c
-g10/plaintext.c
-g10/encr-data.c
-g10/encode.c
-g10/revoke.c
-g10/keylist.c
-g10/sig-check.c
-g10/signal.c
-g10/helptext.c
-g10/verify.c
-g10/decrypt.c
-g10/keyedit.c
-g10/dearmor.c
-g10/keygen.c
-
-
-
-Memory allocation
------------------
+2440  OpenPGP (obsolete).
+
+3156  MIME Security with Pretty Good Privacy (PGP).
+
+4880  Current OpenPGP specification.
+
+6337  Elliptic Curve Cryptography (ECC) in OpenPGP
+
+* Various information
+
+** Directory Layout
+
+  - ./       :: Readme, configure
+  - ./agent   :: Gpg-agent and related tools
+  - ./doc     :: Documentation
+  - ./g10     :: Gpg program here called gpg2
+  - ./sm      :: Gpgsm program
+  - ./jnlib   :: Not used (formerly used utility functions)
+  - ./common  :: Utility functions
+  - ./kbx     :: Keybox library
+  - ./scd     :: Smartcard daemon
+  - ./scripts :: Scripts needed by configure and others
+  - ./dirmngr :: The directory manager
+
+** Detailed Roadmap
+
+  This list of file is not up to date!
+
+  - g10/gpg.c :: Main module with option parsing and all the stuff you
+                 have to do on startup.  Also has the exout handler
+                 and some helper functions.
+
+  - g10/sign.c :: Create signature and optionally encrypt
+
+  - g10/parse-packet.c ::
+  - g10/build-packet.c ::
+  - g10/free-packet.c :: Parsing and creating of OpenPGP message packets.
+
+  - g10/getkey.c   :: Key selection code
+  - g10/pkclist.c  :: Build a list of public keys
+  - g10/skclist.c  :: Build a list of secret keys
+  - g10/ringedit.c :: Keyring I/O
+  - g10/keydb.h    ::
+
+  - g10/keyid.c        :: Helper functions to get the keyid, fingerprint etc.
+
+
+  - g10/trustdb.c ::
+  - g10/trustdb.h ::
+  - g10/tdbdump.c :: Management of the trustdb.gpg
+  - g10/tdbio.c   ::
+  - g10/tdbio.h   :: I/O handling for the trustdb.gpg
+
+  - g10/compress.c :: Filter to handle compression
+  - g10/filter.h   :: Declarations for all filter functions
+  - g10/delkey.c   :: Delete a key
+  - g10/kbnode.c   :: Helper for the KBNODE linked list
+  - g10/main.h     :: Prototypes and some constants
+  - g10/mainproc.c :: Message processing
+  - g10/armor.c    :: Ascii armor filter
+  - g10/mdfilter.c :: Filter to calculate hashs
+  - g10/textfilter.c :: Filter to handle CR/LF and trailing white space
+  - g10/cipher.c   :: En-/Decryption filter
+  - g10/misc.c     :: Utlity functions
+  - g10/options.h  :: Structure with all the command line options
+                      and related constants
+  - g10/openfile.c :: Create/Open Files
+  - g10/hkp.h      :: Keyserver access
+  - g10/hkp.c      :: Ditto.
+  - g10/packet.h   :: Defintion of OpenPGP structures.
+  - g10/passphrase.c :: Passphrase handling code
+
+  - g10/pubkey-enc.c ::
+  - g10/seckey-cert.c ::
+  - g10/seskey.c     ::
+  - g10/import.c     ::
+  - g10/export.c     ::
+  - g10/comment.c    ::
+  - g10/status.c     ::
+  - g10/status.h     ::
+  - g10/sign.c       ::
+  - g10/plaintext.c  ::
+  - g10/encr-data.c  ::
+  - g10/encode.c     ::
+  - g10/revoke.c     ::
+  - g10/keylist.c    ::
+  - g10/sig-check.c  ::
+  - g10/signal.c     ::
+  - g10/helptext.c   ::
+  - g10/verify.c     ::
+  - g10/decrypt.c    ::
+  - g10/keyedit.c    ::
+  - g10/dearmor.c    ::
+  - g10/keygen.c     ::
+
+** Memory allocation
+
 Use only the functions:
 
   xmalloc
   xmalloc_secure
   xtrymalloc
   xtrymalloc_secure
   xcalloc
   xcalloc_secure
   xtrycalloc
   xtrycalloc_secure
   xrealloc
   xtryrealloc
   xstrdup
   xtrystrdup
   xfree
- xmalloc
- xmalloc_secure
- xtrymalloc
- xtrymalloc_secure
- xcalloc
- xcalloc_secure
- xtrycalloc
- xtrycalloc_secure
- xrealloc
- xtryrealloc
- xstrdup
- xtrystrdup
- xfree
 
 
 The *secure versions allocated memory in the secure memory. That is,
@@ -170,37 +271,31 @@ k.  In general the function don't print a memeory message and
 terminate the process if there is not enough memory available.  The
 "try" versions of the functions return NULL instead.
 
+** Logging
 
-Logging
--------
-
-
-
-
-
+ TODO
 
-Option parsing
----------------
-GNUPG does not use getopt or GNU getopt but functions of it's own.  See
-util/argparse.c for details.  The advantage of these functions is that
-it is more easy to display and maintain the help texts for the options.
-The same option table is also used to parse resource files.
+** Option parsing
 
+GnuPG does not use getopt or GNU getopt but functions of it's own.
+See util/argparse.c for details.  The advantage of these functions is
+that it is more easy to display and maintain the help texts for the
+options.  The same option table is also used to parse resource files.
 
+** What is an IOBUF
 
-What is an IOBUF
-----------------
-This is the data structure used for most I/O of gnupg. It is similar
-to System V Streams but much simpler.  Because OpenPGP messages are nested
-in different ways; the use of such a system has big advantages.  Here is
-an example, how it works:  If the parser sees a packet header with a partial
-length, it pushes the block_filter onto the IOBUF to handle these partial
-length packets: from now on you don't have to worry about this.  When it sees
-a compressed packet it pushes the uncompress filter and the next read byte
-is one which has already been uncompressed by this filter. Same goes for
-enciphered packet, plaintext packets and so on.  The file g10/encode.c
-might be a good staring point to see how it is used  - actually this is
-the other way: constructing messages using pushed filters but it may be
-easier to understand.
+This is the data structure used for most I/O of gnupg. It is similar
+to System V Streams but much simpler.  Because OpenPGP messages are
+nested in different ways; the use of such a system has big advantages.
+Here is an example, how it works: If the parser sees a packet header
+with a partial length, it pushes the block_filter onto the IOBUF to
+handle these partial length packets: from now on you don't have to
+worry about this.  When it sees a compressed packet it pushes the
+uncompress filter and the next read byte is one which has already been
+uncompressed by this filter. Same goes for enciphered packet,
+plaintext packets and so on.  The file g10/encode.c might be a good
+staring point to see how it is used - actually this is the other way:
+constructing messages using pushed filters but it may be easier to
+understand.
 
 
index af24196..a308444 100644 (file)
@@ -28,13 +28,13 @@ helpfiles = help.txt help.be.txt help.ca.txt help.cs.txt            \
             help.pt_BR.txt help.ro.txt help.ru.txt help.sk.txt         \
             help.sv.txt help.tr.txt help.zh_CN.txt help.zh_TW.txt
 
-EXTRA_DIST = samplekeys.asc ChangeLog-2011 \
-            gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png \
+EXTRA_DIST = samplekeys.asc mksamplekeys \
+            gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png gnupg-logo-tr.png\
              gnupg-card-architecture.eps gnupg-card-architecture.png \
              gnupg-card-architecture.pdf \
              FAQ gnupg7.texi \
              opt-homedir.texi see-also-note.texi specify-user-id.texi \
-            gpgv.texi yat2m.c
+            gpgv.texi yat2m.c ChangeLog-2011 whats-new-in-2.1.txt
 
 BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \
                 gnupg-card-architecture.pdf
@@ -43,49 +43,52 @@ info_TEXINFOS = gnupg.texi
 
 dist_pkgdata_DATA = qualified.txt com-certs.pem $(helpfiles)
 
-nobase_dist_doc_DATA = FAQ DETAILS HACKING TRANSLATE OpenPGP KEYSERVER \
+nobase_dist_doc_DATA = FAQ DETAILS HACKING DCO TRANSLATE OpenPGP KEYSERVER \
                        $(examples)
 
+#dist_html_DATA =
+
 
 gnupg_TEXINFOS = \
        gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi instguide.texi \
        tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \
-       sysnotes.texi gnupg-card-architecture.fig \
+       sysnotes.texi gnupg-card-architecture.fig dirmngr.texi \
        howtos.texi howto-create-a-server-cert.texi
 
 DVIPS = TEXINPUTS="$(srcdir)$(PATH_SEPARATOR)$$TEXINPUTS" dvips
 
-AM_MAKEINFOFLAGS = -I $(srcdir) --css-ref=/share/site.css
+AM_MAKEINFOFLAGS = -I $(srcdir) --css-ref=/share/site.css -D gpgtwoone
 
-YAT2M_OPTIONS = -I $(srcdir) \
-        --release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard"
+YAT2M_OPTIONS = -I $(srcdir) -D gpgtwoone \
+        --release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard 2.1"
 
 myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \
-                scdaemon.texi tools.texi
-myman_pages   = gpg2.1 gpgsm.1 gpg-agent.1 scdaemon.1 gpgv2.1 \
+               dirmngr.texi scdaemon.texi tools.texi
+myman_pages   = gpg2.1 gpgsm.1 gpg-agent.1 dirmngr.8 scdaemon.1 gpgv2.1 \
                 watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \
                gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 \
-               gpgsm-gencert.sh.1 applygnupgdefaults.8
+               gpgsm-gencert.sh.1 applygnupgdefaults.8 gpg-zip.1 \
+               dirmngr-client.1
 
-man_MANS = $(myman_pages)
-noinst_MANS = gnupg.7
+man_MANS = $(myman_pages) gnupg.7
 
 watchgnupg_SOURCE = gnupg.texi
 
 
-CLEANFILES = yat2m faq.txt
+CLEANFILES = yat2m faq.txt faq.html
 
 DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \
-                $(myman_pages) gpg-zip.1 gnupg.7
+                $(myman_pages) gnupg.7
 
 yat2m: yat2m.c
        $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c
 
+
 .fig.png:
        fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
 
 .fig.jpg:
-       fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@
+       fig2dev -L jpeg `test -f '$<' || echo '$(srcdir)/'`$< $@
 
 .fig.eps:
        fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@
@@ -93,13 +96,14 @@ yat2m: yat2m.c
 .fig.pdf:
        fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
 
+
 yat2m-stamp: $(myman_sources)
-       rm -f yat2m-stamp.tmp
-       touch yat2m-stamp.tmp
+       @rm -f yat2m-stamp.tmp
+       @touch yat2m-stamp.tmp
        for file in $(myman_sources) ; do \
               ./yat2m $(YAT2M_OPTIONS) --store \
                  `test -f '$$file' || echo '$(srcdir)/'`$$file ; done
-       mv -f yat2m-stamp.tmp $@
+       @mv -f yat2m-stamp.tmp $@
 
 yat2m-stamp: yat2m
 
@@ -122,26 +126,37 @@ $(myman_pages) gnupg.7 : yat2m-stamp
 gnupg.texi : $(gnupg_TEXINFOS)
        touch $(srcdir)/gnupg.texi
 
-# Copy shared files from the master branch.  We keep the texinfo files
-# all in master so that we need to modify only one source.  Macros are
-# used to customize them for a specific version.
-update-source:
-       @set -e; cd $(srcdir); \
-        for i in $(gnupg_TEXINFOS) yat2m.c ; do \
-          echo "updating from master:doc/$$i" >&2 ; \
-          git show master:doc/$$i >$$i ; \
-        done
-
 online: gnupg.html gnupg.pdf
        set -e; \
        echo "Uploading current manuals to www.gnupg.org ..."; \
-       cp $(srcdir)/gnupg-logo.png gnupg.html/; \
-        user=werner ; webhost=ftp.gnupg.org; dashdevel="" ; \
-        if echo "@PACKAGE_VERSION@" | grep -- "-git" >/dev/null; then \
+       cp $(srcdir)/gnupg-logo-tr.png gnupg.html/; \
+        user=werner ; webhost="ftp.gnupg.org" ; dashdevel="" ; \
+        if echo "@PACKAGE_VERSION@" | grep -- "-beta" >/dev/null; then \
          dashdevel="-devel" ; \
        else \
-          scp gnupg.pdf $${user}@$${webhost}:webspace/manuals/gnupg-2.0.pdf ; \
+          rsync -v gnupg.pdf $${user}@$${webhost}:webspace/manuals/ ; \
         fi ; \
        cd gnupg.html ; \
         rsync -vr --exclude='.git' .  \
-         $${user}@$${webhost}:webspace/manuals/gnupg-2.0$${dashdevel}/
+         $${user}@$${webhost}:webspace/manuals/gnupg$${dashdevel}/
+
+# Note that you need a recent version of emacs23 with org-mode 7.01h
+faq.txt faq.html: faq.org
+       @set -e; expopt="t nil nil nil \"$$(pwd)\""; \
+        emacs  --batch \
+         --eval "(require 'org)" \
+         --visit "$(srcdir)/faq.org" \
+          --eval "(setq org-export-ascii-entities 'utf8)" \
+          --eval "(org-export-as-ascii org-export-headline-levels $${expopt})"\
+         --visit "$(srcdir)/faq.org" \
+          --eval "(setq org-export-html-style-include-default nil)" \
+          --eval "(setq org-export-html-style-include-scripts nil)" \
+          --eval "(org-export-as-html org-export-headline-levels $${expopt})"
+
+faq-online: faq.txt faq.html
+       set -e; \
+        user=werner ; webhost="ftp.gnupg.org" ; ftphost="ftp.gnupg.org" ; \
+       echo "Uploading current FAQ to {www,ftp}.gnupg.org ..."; \
+       scp faq.html $${user}@$${webhost}:webspace/manuals/GnuPG-FAQ.html ; \
+       scp faq.txt  $${user}@$${ftphost}:gcrypt/gnupg/GnuPG-FAQ.txt ; \
+       echo "...ready"
index 96223d7..794f669 100644 (file)
@@ -9,6 +9,15 @@
   ===================
    GnuPG (>=1.0.3) is in compliance with RFC2440 despite these exceptions:
 
+    * With GnuPG >= 2.1.0 all support for version 3 keys has been
+      removed.  Thus there is no more compatibility with PGP-2.  Users
+      who need to be able to decrypt old PGP 2 messages should use
+      GnuPG 1.4.x along with the option --allow-weak-digest-algos.
+
+    * With GnuPG >= 2.1.0 all signatures (on messages and keys) are
+      created using version 4 signatures.  Support for verifying
+      version 3 signature is still available.
+
     * (9.2) states that IDEA SHOULD be implemented.  This is not done
       due to patent problems.
       UPDATE: Since version 1.4.13 (or GnuPG 2.x with Libgcrypt 1.6)
index 8dfc183..38a6fd9 100644 (file)
@@ -57,6 +57,5 @@ also strongly advise to get subscribed to i18n@gnupg.org and request
 assistance if it is not clear on how to translate certain strings.  A
 wrongly translated string may lead to a security problem.
 
-A copyright disclaimer to the FSF is required by all translators.
-
-
+A copyright disclaimer to the FSF is not anymore required since
+December 2012.
index 43e93b7..33dd40c 100644 (file)
@@ -46,439 +46,22 @@ zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
 omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
 -----END CERTIFICATE-----
 
-Issuer ...: /CN=6R-Ca 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE
-Serial ...: 32D18D
-Subject ..: /CN=6R-Ca 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE
 
------BEGIN CERTIFICATE-----
-MIICaDCCAdSgAwIBAgIDMtGNMAoGBiskAwMBAgUAMG8xCzAJBgNVBAYTAkRFMT0w
-OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0
-aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNhIDE6UE4w
-IhgPMjAwMTAyMDEwOTUyMTdaGA8yMDA1MDYwMTA5NTIxN1owbzELMAkGA1UEBhMC
-REUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11
-bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg
-MTpQTjCBoTANBgkqhkiG9w0BAQEFAAOBjwAwgYsCgYEAg6KrFSTNXKqe+2GKGeW2
-wTmbVeflNkp5H/YxA9K1zmEn5XjKm0S0jH4Wfms6ipPlURVaFwTfnB1s++AnJAWf
-mayaE9BP/pdIY6WtZGgW6aZc32VDMCMKPWyBNyagsJVDmzlakIA5cXBVa7Xqqd3P
-ew8i2feMnQXcqHfDv02CW88CBQDAAAABoxIwEDAOBgNVHQ8BAf8EBAMCAQYwCgYG
-KyQDAwECBQADgYEAOkqkUwdaTCt8wcJLA2zLuOwL5ADHMWLhv6gr5zEF+VckA6qe
-IVLVf8e7fYlRmzQd+5OJcGglCQJLGT+ZplI3Mjnrd4plkoTNKV4iOzBcvJD7K4tn
-XPvs9wCFcC7QU7PLvc1FDsAlr7e4wyefZRDL+wbqNfI7QZTSF1ubLd9AzeQ=
------END CERTIFICATE-----
-
-Issuer ...: /CN=10R-CA 1:PN/O=Bundesnetzagentur/C=DE
-Serial ...: 2A
-Subject ..: /CN=10R-CA 1:PN/O=Bundesnetzagentur/C=DE
-
------BEGIN CERTIFICATE-----
-MIIDoTCCAw2gAwIBAgIBKjAKBgYrJAMDAQIFADA/MQswCQYDVQQGEwJERTEaMBgG
-A1UECgwRQnVuZGVzbmV0emFnZW50dXIxFDASBgNVBAMMCzEwUi1DQSAxOlBOMB4X
-DTA1MDgwMzE1MzAzNloXDTA3MTIzMTE1MDkyM1owPzELMAkGA1UEBhMCREUxGjAY
-BgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxMFItQ0EgMTpQTjCB
-oDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEAiHXC5/hw6rYNc/4cilHLjd/SqwS3
-4LaogQHZVFciyYJ0+5gAfca/kLnPEvOUuYSYNfb2ar0e/iDPxZAAEfqfVGuRT9Pa
-R7hWvPiZUFpoGcNvyOVxKuM9Iyx/i1wan/wS6u12QIgGBUek5ig1+TTwuuNcanlW
-kQPuodHs+BoUGHMCBEAAAIGjggGwMIIBrDAOBgNVHQ8BAf8EBAMCAgQwGAYIKwYB
-BQUHAQMEDDAKMAgGBgQAjkYBATBKBggrBgEFBQcBAQQ+MDwwOgYIKwYBBQUHMAGG
-Lmh0dHA6Ly9vY3NwLm5yY2EtZHMuZGU6ODA4MC9vY3NwLW9jc3ByZXNwb25kZXIw
-EgYDVR0gBAswCTAHBgUrJAgBATCBsQYDVR0fBIGpMIGmMIGjoIGgoIGdhoGabGRh
-cDovL2xkYXAubnJjYS1kcy5kZTozODkvQ049Q1JMLE89QnVuZGVzbmV0emFnZW50
-dXIsQz1ERSxkYz1sZGFwLGRjPW5yY2EtZHMsZGM9ZGU/Y2VydGlmaWNhdGVSZXZv
-Y2F0aW9uTGlzdDtiaW5hcnk/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRp
-b25Qb2ludDAbBgkrBgEEAcBtAwUEDjAMBgorBgEEAcBtAwUBMA8GA1UdEwEB/wQF
-MAMBAf8wHwYDVR0jBBgwFoAUw8916sARU0UT/pdlYwBpUwKWuWQwHQYDVR0OBBYE
-FMPPderAEVNFE/6XZWMAaVMClrlkMAoGBiskAwMBAgUAA4GBAGXK8m/O9KmfaZuA
-1GzMyasIHx8Lu+V0da8NTZzAmqAl+44MtS4QNcZdtxsDvOcqHHs1Tosh9D398hSG
-hXd6gjniKWxMKvjL8TQKu999QIn6YKLCowjUYpp8v4B9X8jNa9vJy2EzoPOBmdWT
-l5hhXfvWpPe68kN9zaEmcDO+m60H
------END CERTIFICATE-----
-
-Issuer ...: /CN=9R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE
-Serial ...: 02
-Subject ..: /CN=9R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE
-
------BEGIN CERTIFICATE-----
-MIIEEjCCA36gAwIBAgIBAjAKBgYrJAMDAQIFADBhMQswCQYDVQQGEwJERTE9MDsG
-A1UECgw0UmVndWxpZXJ1bmdzYmVow7ZyZGUgZsO8ciBUZWxla29tbXVuaWthdGlv
-biB1bmQgUG9zdDETMBEGA1UEAwwKOVItQ0EgMTpQTjAeFw0wNDExMjUxNDU5MTFa
-Fw0wNzEyMzExNDU2NTlaMGExCzAJBgNVBAYTAkRFMT0wOwYDVQQKDDRSZWd1bGll
-cnVuZ3NiZWjDtnJkZSBmw7xyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MRMw
-EQYDVQQDDAo5Ui1DQSAxOlBOMIGgMA0GCSqGSIb3DQEBAQUAA4GOADCBigKBgQCN
-0ECEO2KjPsHBz2cmOSePEmKEH33Q/vRUl1u8D2Uus3txZgqRvCs0F7HzAtDJKSap
-C1+qj5t1R4g8jrlWwsqi+oOc3bpUuPMLo+ys9PG7ODK+xZuwFlezO6rj30mEj+y0
-HMxCaTAedim2J5CmWcqQtATGGzwqYHEVFYo0y5kuuQIEQAAAgaOCAd0wggHZMA4G
-A1UdDwEB/wQEAwICBDAYBggrBgEFBQcBAwQMMAowCAYGBACORgEBMEoGCCsGAQUF
-BwEBBD4wPDA6BggrBgEFBQcwAYYuaHR0cDovL29jc3AubnJjYS1kcy5kZTo4MDgw
-L29jc3Atb2NzcHJlc3BvbmRlcjASBgNVHSAECzAJMAcGBSskCAEBMIHeBgNVHR8E
-gdYwgdMwgdCggc2ggcqGgcdsZGFwOi8vbGRhcC5ucmNhLWRzLmRlOjM4OS9DTj1D
-UkwsTz1SZWd1bGllcnVuZ3NiZWglRjZyZGUlMjBmJUZDciUyMFRlbGVrb21tdW5p
-a2F0aW9uJTIwdW5kJTIwUG9zdCxDPURFLGRjPWxkYXAsZGM9bnJjYS1kcyxkYz1k
-ZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeT9iYXNlP29iamVjdENs
-YXNzPWNSTERpc3RyaWJ1dGlvblBvaW50MBsGCSsGAQQBwG0DBQQOMAwGCisGAQQB
-wG0DBQEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRnBgT5ZxC7e1vJLBj+
-92+P1kZrJzAdBgNVHQ4EFgQUZwYE+WcQu3tbySwY/vdvj9ZGaycwCgYGKyQDAwEC
-BQADgYEACAnkgbAd47VgJqu5CY3B6AlxbGkor2guYHXO+KgBkQeXDVWt4ZvN9hY2
-blhPMc/sLv+Tmg9zjyzjqQdxhWXUDoctorBny8LQQQvMqAtc8qk6DL+X0heq1U2k
-s1e8wj9AUGOfvmSL/r1BWPzLOCWay2bHQCQ1sU5QnvNbmJO21GI=
------END CERTIFICATE-----
-
-Issuer ...: /CN=11R-CA 1:PN/O=Bundesnetzagentur/C=DE
-Serial ...: 2D
-Subject ..: /CN=11R-CA 1:PN/O=Bundesnetzagentur/C=DE
-
------BEGIN CERTIFICATE-----
-MIIDoTCCAw2gAwIBAgIBLTAKBgYrJAMDAQIFADA/MQswCQYDVQQGEwJERTEaMBgG
-A1UECgwRQnVuZGVzbmV0emFnZW50dXIxFDASBgNVBAMMCzExUi1DQSAxOlBOMB4X
-DTA1MDgwMzE4MDk0OVoXDTA3MTIzMTE4MDQyOFowPzELMAkGA1UEBhMCREUxGjAY
-BgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxMVItQ0EgMTpQTjCB
-oDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEAkodoSFtoGjJphYloxQLsmyOe/M5h
-UpURxSkop41MtGlrHeOeQsxMSRdCJInwjLKZg9Pxd92QFsB3f6AJUGTO7z6PJ/ST
-+m0EBksoPtciWLYtlRXtD/RK6mUB7CG5CfqK6AUHbWtXW6mNAZLoJOd0jLsQCUi8
-XmHP92vfmW2ptSkCBEAAAIGjggGwMIIBrDAOBgNVHQ8BAf8EBAMCAgQwGAYIKwYB
-BQUHAQMEDDAKMAgGBgQAjkYBATBKBggrBgEFBQcBAQQ+MDwwOgYIKwYBBQUHMAGG
-Lmh0dHA6Ly9vY3NwLm5yY2EtZHMuZGU6ODA4MC9vY3NwLW9jc3ByZXNwb25kZXIw
-EgYDVR0gBAswCTAHBgUrJAgBATCBsQYDVR0fBIGpMIGmMIGjoIGgoIGdhoGabGRh
-cDovL2xkYXAubnJjYS1kcy5kZTozODkvQ049Q1JMLE89QnVuZGVzbmV0emFnZW50
-dXIsQz1ERSxkYz1sZGFwLGRjPW5yY2EtZHMsZGM9ZGU/Y2VydGlmaWNhdGVSZXZv
-Y2F0aW9uTGlzdDtiaW5hcnk/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRp
-b25Qb2ludDAbBgkrBgEEAcBtAwUEDjAMBgorBgEEAcBtAwUBMA8GA1UdEwEB/wQF
-MAMBAf8wHwYDVR0jBBgwFoAUXYAPovSdSBb8oBS7lEJmWSK6incwHQYDVR0OBBYE
-FF2AD6L0nUgW/KAUu5RCZlkiuop3MAoGBiskAwMBAgUAA4GBAIxx56h5+p2lqK0v
-hRVwkWAAPduspH4U9q7QsFIWbEkFe+2TcXx7MV9NAUe4kN9MsN9CEgSSeLDfpIFA
-uyHndqgmDaqXmWSDl2QutHQwSj8a04bSNbY7s0FUCMqrr/465Rf6quIWi7qXhwDe
-yDmXv3nzPTGVM3F+aavJCybjJ1qk
------END CERTIFICATE-----
-
-Issuer ...: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE
-Serial ...: 0139
-Subject ..: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE
-
------BEGIN CERTIFICATE-----
-MIIErTCCA5WgAwIBAgICATkwDQYJKoZIhvcNAQENBQAwPzELMAkGA1UEBhMCREUx
-GjAYBgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxMlItQ0EgMTpQ
-TjAeFw0wNzA1MjUxMTAxNDRaFw0xMjA1MjUxMDU2MDdaMD8xCzAJBgNVBAYTAkRF
-MRowGAYDVQQKDBFCdW5kZXNuZXR6YWdlbnR1cjEUMBIGA1UEAwwLMTJSLUNBIDE6
-UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIBAQCYOqYxUqr6ZdlIuVaz
-1raETmld82tCCFjUnIlHGpaTbBGQ9ddW4pdkdNmK4dHDesAnGFB6tgZzFTYivjTY
-Jyzv3NunMth8AjwCivQ0u2RBlunY2jg6dNSeTwGlmOlG709HgWPHvvAboqLDoV81
-knMbNbG4P7Ff/+lsTnbN/gT0X5fHUz5UO3eowyl2kD6GBZwb+noR/86U0V39yXsk
-ZD/NNBXKOzKo9VXx09S1Uq027Cc+VIa62DWUeUGiUDjCXXJoaAF2wQcD/crrAJlU
-zeOVZkSzRJXpjpG8kZhKgSgOpgfnpjDXAXWbkJuyDL2fqXLPxAyBq3ThgUHZT99s
-QSd3AgRAAACBo4IBsDCCAawwDgYDVR0PAQH/BAQDAgIEMBgGCCsGAQUFBwEDBAww
-CjAIBgYEAI5GAQEwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzABhi5odHRwOi8v
-b2NzcC5ucmNhLWRzLmRlOjgwODAvb2NzcC1vY3NwcmVzcG9uZGVyMBIGA1UdIAQL
-MAkwBwYFKyQIAQEwgbEGA1UdHwSBqTCBpjCBo6CBoKCBnYaBmmxkYXA6Ly9sZGFw
-Lm5yY2EtZHMuZGU6Mzg5L0NOPUNSTCxPPUJ1bmRlc25ldHphZ2VudHVyLEM9REUs
-ZGM9bGRhcCxkYz1ucmNhLWRzLGRjPWRlP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxp
-c3Q7YmluYXJ5P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQw
-GwYJKwYBBAHAbQMFBA4wDAYKKwYBBAHAbQMFATAPBgNVHRMBAf8EBTADAQH/MB8G
-A1UdIwQYMBaAFATenX/fQ3KJumlJAfToSSjeAhlvMB0GA1UdDgQWBBQE3p1/30Ny
-ibppSQH06Eko3gIZbzANBgkqhkiG9w0BAQ0FAAOCAQEADf4IOMHGmSpkPc1UP0LS
-sK8Y/xXvOgdHPx4f2CpcgUKRRk+Ue9MKiZG0KCFaNK9Qpnxejuk42Iu3flC5kn8T
-fPQWtxC3ZQqD8sd6EX/FDdfkHJFJ9rIYKiSG6m2PDBUcbpQZ9kwhC7qCKE1coUhb
-FW3WbntkDtrQycz7ZyQ6Ip+PpRoxwToJqTsExb+8whukhOo1vsgdaMZS/6iwwVkt
-rJvl7EWMJVWctm15iDQzp4sawgSOg7U5icyTb1q+FqI5KlAfd/dRbv2yvThiOl7+
-bfN9Brosoxtwi/uJO8vSGOCIUUkiGhIk7+OX+mvppTG+7R1Jn6Af6AOzGSbQz5Ks
-Uw==
------END CERTIFICATE-----
-
-Issuer ...: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE
-Serial ...: 013C
-Subject ..: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE
-
------BEGIN CERTIFICATE-----
-MIIErTCCA5WgAwIBAgICATwwDQYJKoZIhvcNAQENBQAwPzELMAkGA1UEBhMCREUx
-GjAYBgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxM1ItQ0EgMTpQ
-TjAeFw0wNzA1MjkxMTAyMzdaFw0xMjA1MjkxMDU1NTRaMD8xCzAJBgNVBAYTAkRF
-MRowGAYDVQQKDBFCdW5kZXNuZXR6YWdlbnR1cjEUMBIGA1UEAwwLMTNSLUNBIDE6
-UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIBAQCaXK0TY+Vp+Hxx8B9D
-lrHkc0zRdhXNuDP4Cedl9e6wPwdi90HVEjDK3FoDv7UPBtgGwMzRUQVIz/etbcQr
-tnGwSQlsDI/Q5R1HAh241+/rWYodi6OqNsNeb065RRBlwHAa4uvT3b/Cj/OJI5Kp
-6qRPquK0iuMaFwuxGCxfhTLOmmGVNYOE7/9UzKXA2yvthY3jfmIm18l/z08PgUYj
-rjENdrez3ZRgjZ/XsXSNw3B2K3cZQ+xRP4rqfkmfPO8T6UhOeoiQFx2v1PizBWRQ
-uiUtFjrCiaDeBjo3kfGgbpdPnHzqUEoEOyAlsglFLJC9xaCiLtt2ic1/1OFFlNgQ
-tLJLAgRAAACBo4IBsDCCAawwDgYDVR0PAQH/BAQDAgIEMBgGCCsGAQUFBwEDBAww
-CjAIBgYEAI5GAQEwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzABhi5odHRwOi8v
-b2NzcC5ucmNhLWRzLmRlOjgwODAvb2NzcC1vY3NwcmVzcG9uZGVyMBIGA1UdIAQL
-MAkwBwYFKyQIAQEwgbEGA1UdHwSBqTCBpjCBo6CBoKCBnYaBmmxkYXA6Ly9sZGFw
-Lm5yY2EtZHMuZGU6Mzg5L0NOPUNSTCxPPUJ1bmRlc25ldHphZ2VudHVyLEM9REUs
-ZGM9bGRhcCxkYz1ucmNhLWRzLGRjPWRlP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxp
-c3Q7YmluYXJ5P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQw
-GwYJKwYBBAHAbQMFBA4wDAYKKwYBBAHAbQMFATAPBgNVHRMBAf8EBTADAQH/MB8G
-A1UdIwQYMBaAFAYenQPZrutto05LK939ru/TEqiNMB0GA1UdDgQWBBQGHp0D2a7r
-baNOSyvd/a7v0xKojTANBgkqhkiG9w0BAQ0FAAOCAQEADrtfqJ8lnYsVyV5YK/H/
-evPf9LY1AfuuQkMkm9UP9a9BBQINoIULB+n+gF/c0dxEboF74Ikp08dhDOq0mjvj
-f0lpsBPgX/eN9IOWdMBs3rKIXn7suOoUtnBuFgW6fJ32CPTLUQd5Dqv9DizTiKMf
-X66oMBQD784IKya1bLaJd7x1UXtP1h2DAej1scF9DbiDDDieuid0wyibrPDgjUN1
-tbYiLH2did0zZRLlp6gDpgh4t8Efqb7XDijKzQHvWKzr4IALTpYoD42yeslMa5yV
-mm15NhiRGAdX+JbvYgfP3aDIMX/yoaMB8GXEUq7CmFhAwpxfhy/oyvswX5MyE8D2
-Lw==
------END CERTIFICATE-----
-
-
-Issuer ...: /CN=8R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE
+Issuer ...: /CN=The STEED Self-Signing Nonthority
 Serial ...: 01
-Subject ..: /CN=8R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE
-
------BEGIN CERTIFICATE-----
-MIIEEjCCA36gAwIBAgIBATAKBgYrJAMDAQIFADBhMQswCQYDVQQGEwJERTE9MDsG
-A1UECgw0UmVndWxpZXJ1bmdzYmVow7ZyZGUgZsO8ciBUZWxla29tbXVuaWthdGlv
-biB1bmQgUG9zdDETMBEGA1UEAwwKOFItQ0EgMTpQTjAeFw0wNDExMjUxNDEwMzda
-Fw0wNzEyMzExNDA0MDNaMGExCzAJBgNVBAYTAkRFMT0wOwYDVQQKDDRSZWd1bGll
-cnVuZ3NiZWjDtnJkZSBmw7xyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MRMw
-EQYDVQQDDAo4Ui1DQSAxOlBOMIGgMA0GCSqGSIb3DQEBAQUAA4GOADCBigKBgQCS
-DvtngJbI4K8sbCHFfCalXaDa7xgc2pdsL2oQlgZygt1EY5ZgZB93JThnDSaDzdLj
-ZIPrXJLxCOLq6Kmxj63V9p9WUaF5nz/6PVRMmLzI7cvh5QDjsX4ZmEzm/it7e/YH
-vC1Yiw5bTULjwVZ27vqO64mhplQM3HKVgk6FX51XnwIEQAAAgaOCAd0wggHZMA4G
-A1UdDwEB/wQEAwICBDAYBggrBgEFBQcBAwQMMAowCAYGBACORgEBMEoGCCsGAQUF
-BwEBBD4wPDA6BggrBgEFBQcwAYYuaHR0cDovL29jc3AubnJjYS1kcy5kZTo4MDgw
-L29jc3Atb2NzcHJlc3BvbmRlcjASBgNVHSAECzAJMAcGBSskCAEBMIHeBgNVHR8E
-gdYwgdMwgdCggc2ggcqGgcdsZGFwOi8vbGRhcC5ucmNhLWRzLmRlOjM4OS9DTj1D
-UkwsTz1SZWd1bGllcnVuZ3NiZWglRjZyZGUlMjBmJUZDciUyMFRlbGVrb21tdW5p
-a2F0aW9uJTIwdW5kJTIwUG9zdCxDPURFLGRjPWxkYXAsZGM9bnJjYS1kcyxkYz1k
-ZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeT9iYXNlP29iamVjdENs
-YXNzPWNSTERpc3RyaWJ1dGlvblBvaW50MBsGCSsGAQQBwG0DBQQOMAwGCisGAQQB
-wG0DBQEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTuKY5dMBMWc1wFL/fr
-arlCuHKNBDAdBgNVHQ4EFgQU7imOXTATFnNcBS/362q5QrhyjQQwCgYGKyQDAwEC
-BQADgYEAbDMwH4zJB/0qgmbBWvvCGJsm9lmLzLdOcB8HCm1EvlCLqaCX7TwoUuBN
-voxU9OHt1wAbChNP+ueDmI/0u2KRNv6/t4cOB8d4navwsW5nmknSzdZ6UZTUfmCr
-n6XIdUtl2hkiFlQpCvCIBFj/+PjQRMdovRN42EQ9XVhb5B2MGv8=
------END CERTIFICATE-----
-
-Issuer ...: /CN=7R-CA 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE
-Serial ...: 00C48C8D
-Subject ..: /CN=7R-CA 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE
+Subject ..: /CN=The STEED Self-Signing Nonthority
 
 -----BEGIN CERTIFICATE-----
-MIICaTCCAdWgAwIBAgIEAMSMjTAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9
-MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWth
-dGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBO
-MCIYDzIwMDExMDE1MTExNTE1WhgPMjAwNjAyMTUxMTE1MTVaMG8xCzAJBgNVBAYT
-AkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21t
-dW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjdSLUNB
-IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIqJA/4+pRD+BXsRd+ej
-qVObXlKRhn1CoyKxVwR3O/RtE1M4FcajKDdT1p1pLULyqPBE2roMS5D/f83192gE
-Mw1uGZIusehg6n8tPQIJPkSb4X22yM0ZFeLAQXKNJ+98e03xv/TU4Fa//elPiPs/
-9Y99Gm6DOvTpCxIY8QK9Pxm7AgUAwAAAAaMSMBAwDgYDVR0PAQH/BAQDAgEGMAoG
-BiskAwMBAgUAA4GBADnITH+fLD0qsWcAncwPztzTAnqUw9O0+yvfmxvEU0zcJRuF
-Tl8DK+/aKp4SwVhRJZlWxenHzkjWynsUXBUv878gizllRpA7265REyHQki4NnxAi
-OGxEVGe/NbGeU88Pgnk7alhtdA/Ty8/WX9a3U/0G4pLaJppxGSm+ypQZ0XOY
+MIICKDCCAZGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAsMSowKAYDVQQDEyFUaGUg
+U1RFRUQgU2VsZi1TaWduaW5nIE5vbnRob3JpdHkwIBcNMTExMTExMDAwMDAwWhgP
+MjEwNjAyMDYwMDAwMDBaMCwxKjAoBgNVBAMTIVRoZSBTVEVFRCBTZWxmLVNpZ25p
+bmcgTm9udGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAk2h9kqe8
+0eb8ESY7UGV6j6S5zuP5DiM4TWJ3jKG2y+D2CyA1Sl90iZ6zyN3zCB0yR1xxhpuw
+xdrwBRovRFludAbx3MeynYhzXkk0Hwn038q1oIt2YUw3Igz34s24o455ZE86JQ/6
+5dC7ppF8Z1I9KBL96NO+qZR/alVAKxYAwS8CAwEAAaNYMFYwEgYDVR0TAQH/BAgw
+BgEB/wIBATARBgorBgEEAdpHAgICBAMBAf8wHQYDVR0OBBYEFGimOJmN+rrFEOpk
+XONPloay7ffqMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQB3JwUn
+AbOdGv5ErojNSSP+yGZIy5av4wnkzK840Uj3jY6A5cuHroZGOD60hqLV2Hy0npox
+zte4phWEKWmZiXd8SCmd3MFNgZSieiixye0qxSmuqYft2j6NhEXD5xc/iTTjFT42
+SjGPLKAICuMBuGPnoozOEVlgqwaDqKOUph5sqw==
 -----END CERTIFICATE-----
-
-
-Issuer ...: /CN=D-TRUST Qualified Root CA 1 2006:PN/O=D-Trust GmbH/C=DE
-Serial ...: 00B95F
-Subject ..: /CN=D-TRUST Qualified Root CA 1 2006:PN/O=D-Trust GmbH/C=DE
-    aka ..: info@d-trust.net
-    aka ..: (uri http://www.d-trust.net)
-
------BEGIN CERTIFICATE-----
-MIIFCjCCA/KgAwIBAgIDALlfMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxLDAqBgNVBAMMI0QtVFJVU1QgUXVhbGlm
-aWVkIFJvb3QgQ0EgMSAyMDA2OlBOMB4XDTA2MDQyNzEyNDA1NFoXDTExMDQyNzEy
-NDA1NFowUjELMAkGA1UEBhMCREUxFTATBgNVBAoMDEQtVHJ1c3QgR21iSDEsMCoG
-A1UEAwwjRC1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAxIDIwMDY6UE4wggEkMA0G
-CSqGSIb3DQEBAQUAA4IBEQAwggEMAoIBAQCPACqp8H/KTbDBUM8BTiRzsfCJmN5G
-Uxv8x3wsYLMtZ8meq04vEun2OneNeKZ2LxJy3UchUWitYP9pLPt9M8yt0pyuOXOQ
-5r2RPAM46OlfStoPbZ+lCxpZbNcQGLM+/OcQU9GoCNWWkDSctwIN8T4mUf7vSzuT
-jM4n5NHW7Y8bANhH7lh2fwkfIk7PxsxFw9amptlqzDqbBPz8/SdBUFt0G8t52Niw
-lcYHWDV2YH4Qs1SAxOsyG0O8hpYKiKIwRHxPu5ZD3bMgDJXA3d+9zXlrLlmL0YFC
-tvlPxmvqUhmMsL4vGEj/xWivULCTVOz6KcJ9edWwK9JxyO/KmGyDLwKxAgUApBVt
-/aOCAeUwggHhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJr+c6YCNnohJ6M3
-fhSzwwTq2CkWMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29j
-c3AuZC10cnVzdC5uZXQwFwYDVR0gBBAwDjAMBgorBgEEAaU0Ah4BMDMGA1UdEQQs
-MCqBEGluZm9AZC10cnVzdC5uZXSGFmh0dHA6Ly93d3cuZC10cnVzdC5uZXQwGAYI
-KwYBBQUHAQMEDDAKMAgGBgQAjkYBATAOBgNVHQ8BAf8EBAMCAQYwggEABgNVHR8E
-gfgwgfUwgfKgge+ggeyGgaVsZGFwOi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NO
-PUQtVFJVU1QlMjBRdWFsaWZpZWQlMjBSb290JTIwQ0ElMjAxJTIwMjAwNiUzQVBO
-LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0
-P2Jhc2U/b2JqZWN0Q2xhc3M9Y3JsRGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly93
-d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfcXVhbGlmaWVkX3Jvb3RfY2FfMV8y
-MDA2X3BuLmNybDANBgkqhkiG9w0BAQUFAAOCAQEABsVNHg5zVMB+A4swJ8/vW+RV
-mW8KZiJb5AVytFzBeZkkF2+DXFMtursZ0sICIcRCSsNyAQcqHqzcgnDWCHASlu4o
-Em3TeBsmWo8r/uGpbFVAOhjq2VOFwjjIr3TC7zmMoLE+WGBRSuZh4/5wnxQ+NNbY
-8HHE52UPI6VyV7RZeE0IZfbjkejw8WpvNtRfc6NxOCxf1LYibiCUaYs+EBDD+eod
-lWwpmHwPSj4GCzR9wBdbWML/GQZ6iFVOuEmApm2B11KEn4hvKtRMEp1CdHIn8Jwx
-51E89XcjJOIitO0lUozimqvlUb0lEynXe1/CUOhAsiAnLvq0GbnjFN6+9GRnqg==
------END CERTIFICATE-----
-
-Issuer ...: /CN=D-TRUST Qualified Root CA 2 2006:PN/O=D-Trust GmbH/C=DE
-Serial ...: 00B960
-Subject ..: /CN=D-TRUST Qualified Root CA 2 2006:PN/O=D-Trust GmbH/C=DE
-    aka ..: info@d-trust.net
-    aka ..: (uri http://www.d-trust.net)
-
------BEGIN CERTIFICATE-----
-MIIFBjCCA+6gAwIBAgIDALlgMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxLDAqBgNVBAMMI0QtVFJVU1QgUXVhbGlm
-aWVkIFJvb3QgQ0EgMiAyMDA2OlBOMB4XDTA2MDQyNzEyNDA1NFoXDTExMDQyNzEy
-NDA1NFowUjELMAkGA1UEBhMCREUxFTATBgNVBAoMDEQtVHJ1c3QgR21iSDEsMCoG
-A1UEAwwjRC1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAyIDIwMDY6UE4wggEkMA0G
-CSqGSIb3DQEBAQUAA4IBEQAwggEMAoIBAQC9p9EZM645WSti4m3Lp/m5Cu2PCeAf
-DYMsN2UQab5SAD94wc0xB68rhD0QiyXT1bhqnHKGhdsmmNwVbFLWyFWVc69+5pbx
-jkEa1Z5oYbftpLZlqblas/iPG1C546c/O5JUHehrpyJziTaIqvDm0hMCarEGrd4i
-hdwP7XsLNLeHFVdpVMWKUIJjUud18Wyr6MVRGs85YTme2gPki8JZMjeOteTA8dnY
-unohiJM1rs8YQiYgIfQJV5oBd7OWZQLSuoh5tddYnP4KDFZUCCsC1OkBD+MnVlcv
-IEfrDDuWdvFgOdS8FB5l4E3D0eYPpn536EDpWeGuCnn8joQPdiMwwGL7AgUAuaHl
-M6OCAeEwggHdMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFILMyG0qJl9Aqmsa
-DhPJE4d+Xp/JMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29j
-c3AuZC10cnVzdC5uZXQwFwYDVR0gBBAwDjAMBgorBgEEAaU0Ah4BMDMGA1UdEQQs
-MCqBEGluZm9AZC10cnVzdC5uZXSGFmh0dHA6Ly93d3cuZC10cnVzdC5uZXQwGAYI
-KwYBBQUHAQMEDDAKMAgGBgQAjkYBATAOBgNVHQ8BAf8EBAMCAQYwgf0GA1UdHwSB
-9TCB8jCB76CB7KCB6YaBpWxkYXA6Ly9kaXJlY3RvcnkuZC10cnVzdC5uZXQvQ049
-RC1UUlVTVCUyMFF1YWxpZmllZCUyMFJvb3QlMjBDQSUyMDIlMjAyMDA2JTNBUE4s
-Tz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3Q/
-YmFzZT9vYmplY3RDbGFzcz1jcmxEaXN0cmlidXRpb25Qb2ludIY/aHR0cDovL3d3
-dy5kLXRydXN0Lm5ldC9jcmwvZC10cnVzdF9xdWFsaWZpZWRfcm9vdF9jYV8yXzIw
-MDYuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQB/TeSQASSUVjLVpTMB+S2bEYZWL04N
-5UO5sIdV5MQFxmbmQNam4odnkOx/GjHy0uuf14Pz7lztlLh4EMvEZbvoQ8wRsrrl
-vMjWBUSnhTMPhohj4gUCEJDBq50qi0057Jos9DF4iLaFgiWBER+FeSHD8uEy6WGG
-UrQ9fw8wRa+CRUeZldtZ25VSR++wxBuX3bkF/hRBuSk9PzT6jZojZDWKsqhPGo0W
-dK4V81hS4Zri3b3gSD/3iOAJ4EO8jdyeSVomw/u1UOapVFnWhpN7H6Nwekij66eO
-4WNzbeTNgJtkdOlzW2AcsWe3mS43BE286z7l/DzDs8JK36va/TRHb29p
------END CERTIFICATE-----
-
-
-Issuer ...: /CN=S-TRUST Qualified Root CA 2006-001:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart
-            /ST=Baden-Wuerttemberg (BW)/C=DE
-Serial ...: 00DF749F80AA51F0EDC0CB1FC183E97EE2
-Subject ..: /CN=S-TRUST Qualified Root CA 2006-001:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart
-            /ST=Baden-Wuerttemberg (BW)/C=DE
-
------BEGIN CERTIFICATE-----
-MIIETDCCAzSgAwIBAgIRAN90n4CqUfDtwMsfwYPpfuIwDQYJKoZIhvcNAQEFBQAw
-gZ4xCzAJBgNVBAYTAkRFMSAwHgYDVQQIExdCYWRlbi1XdWVydHRlbWJlcmcgKEJX
-KTESMBAGA1UEBxMJU3R1dHRnYXJ0MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmth
-c3NlbiBWZXJsYWcgR21iSDEuMCwGA1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9v
-dCBDQSAyMDA2LTAwMTpQTjAeFw0wNjAxMDEwMDAwMDBaFw0xMDEyMzAyMzU5NTla
-MIGeMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4tV3VlcnR0ZW1iZXJnIChC
-VykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNjaGVyIFNwYXJr
-YXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1QgUXVhbGlmaWVkIFJv
-b3QgQ0EgMjAwNi0wMDE6UE4wggEkMA0GCSqGSIb3DQEBAQUAA4IBEQAwggEMAoIB
-AQCCp5M7qIP3WgNNE9t4kxFLb2HdwE2pivcWfEjFh9AJcwZIaD781+OhuNxhMEil
-C+B9N3bYgLMj7r/LbIFwRVmUf9E64kBDrY/wLAlXLpiicOiKE7rS1tcOAdD69s7I
-5jaBXCz/eQo20QLsp11/btwYos9PlfptLqHjS8AUwUaMyolqmWqaxLD33ZfoQswP
-FpyFFzAnRondt/5WUt244kpqgTlwP4o9J1AZamK5o/kKEXl8hDT6CulFoK51cX/J
-C9lEA10mwchVfv+9cel9b2ryPXg3hPf1XFFR+l90/ZYlreaSKz5+LluI6a/ALtYl
-hqJpvndXm6YZDzKKtxT3LZ1DAgUA8A8a46OBgDB+MBIGA1UdEwEB/wQIMAYBAf8C
-AQEwDgYDVR0PAQH/BAQDAgEGMBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwHQYD
-VR0OBBYEFKhXJN3CR/Jkirm68N+VHxcd09zBMB8GA1UdIwQYMBaAFKhXJN3CR/Jk
-irm68N+VHxcd09zBMA0GCSqGSIb3DQEBBQUAA4IBAQBB8UGGU179RK9v5SglLn8m
-AdBrwG5B4x0nlI3Ayj+GuP9R8ALcMEBwcFgSZTav7N8ERKa8VlCRNria7Fvf3kOu
-+f67smpShBvEkrHy+ThvezBUtLfSSd1HzvaPnfwu86DMVnTIOkEcl0KLrpc/ZjEt
-u81iHuiHBemf6gWdTCApiJ+CN4tARi3irvWcjhz/IIcA/ZwAaCW22Z1ysDklCIPS
-9OnX9ki1f73PR+kdo4G7Dfo7TbuvV5Kzeh54sZ77A5utdvKer4ZHBmn9CGmk4VeI
-BWdFlE7Fispzm+jZCduF0TcazvP/tYontx71GQnHRwLfiY4xnuzXEoSNXoaHzhzO
------END CERTIFICATE-----
-
-Issuer ...: /CN=S-TRUST Qualified Root CA 2007-001:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart
-            /ST=Baden-Wuerttemberg (BW)/C=DE
-Serial ...: 00BC098E0402E92956B8D7DE74977E26F7
-Subject ..: /CN=S-TRUST Qualified Root CA 2007-001:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart
-            /ST=Baden-Wuerttemberg (BW)/C=DE
-
------BEGIN CERTIFICATE-----
-MIIESzCCAzOgAwIBAgIRALwJjgQC6SlWuNfedJd+JvcwDQYJKoZIhvcNAQELBQAw
-gZ4xCzAJBgNVBAYTAkRFMSAwHgYDVQQIExdCYWRlbi1XdWVydHRlbWJlcmcgKEJX
-KTESMBAGA1UEBxMJU3R1dHRnYXJ0MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmth
-c3NlbiBWZXJsYWcgR21iSDEuMCwGA1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9v
-dCBDQSAyMDA3LTAwMTpQTjAeFw0wNzAxMDEwMDAwMDBaFw0xMTEyMzAyMzU5NTla
-MIGeMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4tV3VlcnR0ZW1iZXJnIChC
-VykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNjaGVyIFNwYXJr
-YXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1QgUXVhbGlmaWVkIFJv
-b3QgQ0EgMjAwNy0wMDE6UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIB
-AQCnJdNNiDQLKpPIfHTC3ifleXWTf96hLfvP58q41fuywQ+rXju453yjPgr/ej5i
-RgYPyJnSc498wyu/XtPLIC3gQvowfiI8WmSj/eEToHUhrLIAtx1VXSi/Rugt3E1Y
-uYGkPn/gnrkk+RtPJQuBl1NRxKEVi7rg1Ch5RJvWsUTOmxgeWlr8qZnPoLkA2y6N
-lhL6LP3Th+OQIH4RFFfazNYWpH4Cg6I5nzyieHaR6LrGk0L7GfDKdZG4Eqan3JvI
-ilrFHzzCm7qudd+31jcRamReqZqJ0wzBmY1LNAzDyCAC3Y+YWEz8crhDW3mK/wFY
-H0RHHeow06RMTEVwls+FrhWfAgRAAACBo4GAMH4wEgYDVR0TAQH/BAgwBgEB/wIB
-ATAOBgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAKMAgGBgQAjkYBATAdBgNV
-HQ4EFgQUPAujGBtjPCldr0A+EM4YCZSIX1cwHwYDVR0jBBgwFoAUPAujGBtjPCld
-r0A+EM4YCZSIX1cwDQYJKoZIhvcNAQELBQADggEBAJ1pVXXcVb9m0yRPjvE4Rvko
-tdjIm29YnY13ILCrPqjfgtpSlId6NHPhykGLkw3ratNlWQp3rmen/8EqQJa0rsPD
-CiB20ilLb1CmF8/SViJ26C+K0ayzk8s2v7S/m7/Tx9Dgd2PXWwy2XjeGG/2SkISH
-5CtSjbm8U+xTh5SQMgK1MX/bDiNJebDOO0N2lxAjtcGmw7K6OTWS7KnFfjzv6fKK
-L7Ed2Gpd2gBkbuJVe/wX2mDP2P4rpcCEkXrDoWbi9WWc+eP5fCgE4Nj7/VhnbPf6
-DJCvmUG571uf1oukFaoeeyzpw2q28Ly1KR8DNPw+B/3PzJUIjXYzPGyUjv3aPew=
------END CERTIFICATE-----
-
-
-Issuer ...: /CN=S-TRUST Qualified Root CA 2008-001:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
-Serial ...: 00B3963E0E6C2D65125853E970665402E5
-Subject ..: /CN=S-TRUST Qualified Root CA 2008-001:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
-
------BEGIN CERTIFICATE-----
-MIIFODCCBCCgAwIBAgIRALOWPg5sLWUSWFPpcGZUAuUwDQYJKoZIhvcNAQELBQAw
-fDELMAkGA1UEBhMCREUxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1
-dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1Qg
-UXVhbGlmaWVkIFJvb3QgQ0EgMjAwOC0wMDE6UE4wHhcNMDgwMTAxMDAwMDAwWhcN
-MTIxMjMwMjM1OTU5WjB8MQswCQYDVQQGEwJERTESMBAGA1UEBxMJU3R1dHRnYXJ0
-MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmthc3NlbiBWZXJsYWcgR21iSDEuMCwG
-A1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAyMDA4LTAwMTpQTjCCASMw
-DQYJKoZIhvcNAQEBBQADggEQADCCAQsCggEBAKfUBh+i0NSWzddPtWG15DdTqbPM
-SJmeWw6dXutkR6UNonxC+yAm6rfZJhb83tPGB09qlAcNn7fcdR/g4SNdu3McwT+J
-HKHou6hhbMZmsza72Qcj9P/AwWq/o5oJa2eI4pU7I5YjS3x3oGtvmhJkwYiehIyx
-7DI+wHKcohwJV83jlZW3YrPmKgpaOZsc5lJM/+Ha4Q77MLPWHdCnxUkrbL1+Q/Ea
-qY+DoMMa9wxY+UmwbKe8ANfAf2NIMfJwmb748f+7EJMLjUA8nxrQ4iAPJ1lSrfZs
-d9cjzjdXZnhLvR9T2nNa2nROOHk2ARCOPAJgxk9EheRr4B6RbJ4hinuydJUCBEAA
-AIGjggGyMIIBrjASBgNVHRMBAf8ECDAGAQH/AgEBMIIBLAYDVR0fBIIBIzCCAR8w
-ggEboIIBF6CCAROGZWh0dHA6Ly9vbnNpdGVjcmwucy10cnVzdC5kZS9EZXV0c2No
-ZXJTcGFya2Fzc2VuVmVybGFnR21iSFNUUlVTVFF1YWxpZmllZFJvb3RDQTIwMDgw
-MDFQTi9MYXRlc3RDUkwuY3JshoGpbGRhcDovL2RpcmVjdG9yeS5zLXRydXN0LmRl
-L0NOPVMtVFJVU1QlMjBRdWFsaWZpZWQlMjBSb290JTIwQ0ElMjAyMDA4LTAwMSUz
-QVBOLE89RGV1dHNjaGVyJTIwU3Bhcmthc3NlbiUyMFZlcmxhZyUyMEdtYkgsTD1T
-dHV0dGdhcnQsQz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeTAO
-BgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAKMAgGBgQAjkYBATAdBgNVHQ4E
-FgQU7UBDbxBuOWcii/O2xVNRExXxPj0wHwYDVR0jBBgwFoAU7UBDbxBuOWcii/O2
-xVNRExXxPj0wDQYJKoZIhvcNAQELBQADggEBAEdeesrApdpV+0cz698ZM+fsbcmk
-AYTy8U1vcnEPzcxaEAvUO57ndJlSdBK7+5yFbVuFW7CTp90TPgljoDqWDOI2hsLU
-YxrHUfDCwsm/ALLDpImRKWGZ07nKxOHGAOxB4tQUaDUHwaClbw3UB3nBi9++f9d0
-FLM9oOVxbhKGco4/qo3LP+QfJU6xjL8itqaf0WHXcnN69CD/5D7e/iziwHvLWLEU
-0cUXVDzdyWKEvJ3RpFIk6EUulKFHZrCctis1ixg/iQybKs2DWG/RtCo6CGhtydT8
-I1y6qAwPL2gAt+ypf+Mk4SLewnpXlw6ZVDQlLEBLGto72DAyJTxRh8f6BpY=
------END CERTIFICATE-----
-
-Issuer ...: /CN=S-TRUST Qualified Root CA 2008-002:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
-Serial ...: 00C4216083F35C54F67B09A80C3C55FE7D
-Subject ..: /CN=S-TRUST Qualified Root CA 2008-002:PN
-            /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
-
------BEGIN CERTIFICATE-----
-MIIFODCCBCCgAwIBAgIRAMQhYIPzXFT2ewmoDDxV/n0wDQYJKoZIhvcNAQELBQAw
-fDELMAkGA1UEBhMCREUxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1
-dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1Qg
-UXVhbGlmaWVkIFJvb3QgQ0EgMjAwOC0wMDI6UE4wHhcNMDgwMTAxMDAwMDAwWhcN
-MTIxMjMwMjM1OTU5WjB8MQswCQYDVQQGEwJERTESMBAGA1UEBxMJU3R1dHRnYXJ0
-MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmthc3NlbiBWZXJsYWcgR21iSDEuMCwG
-A1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAyMDA4LTAwMjpQTjCCASMw
-DQYJKoZIhvcNAQEBBQADggEQADCCAQsCggEBAJCrKgvHaZdd5LpNAlVZVf8a3CJY
-lBUt4Awwlu5q9wnkObVGHyekGLG6h7wMrY9OCL4uqWn9vIz+5vGXMEvU+NniMXIn
-JodZS8CbBBYUxS42PgZp7TNCd4gglEA1xOhsQH8T9iRZzdRCLyZYjysYsHiujn/x
-7y0+nxQsYu2mONaPFZq7ZBsDlAk5BPdIZCrutHDHe5inKwbpDUdpnKFlM1UDZ3eS
-4dl+YT/3t4QSJAVHVFz/Pzf1tevpMFYP4M7jHaktp327GMtrhYlpeoSZRc1cizHU
-Vdhj6Foyj1wWkQMwvb1ChPbRxS+4V3b6R+vgelULDBqFSF0Rtj/kRUgT/q8CBEAA
-AIGjggGyMIIBrjASBgNVHRMBAf8ECDAGAQH/AgEBMIIBLAYDVR0fBIIBIzCCAR8w
-ggEboIIBF6CCAROGZWh0dHA6Ly9vbnNpdGVjcmwucy10cnVzdC5kZS9EZXV0c2No
-ZXJTcGFya2Fzc2VuVmVybGFnR21iSFNUUlVTVFF1YWxpZmllZFJvb3RDQTIwMDgw
-MDJQTi9MYXRlc3RDUkwuY3JshoGpbGRhcDovL2RpcmVjdG9yeS5zLXRydXN0LmRl
-L0NOPVMtVFJVU1QlMjBRdWFsaWZpZWQlMjBSb290JTIwQ0ElMjAyMDA4LTAwMiUz
-QVBOLE89RGV1dHNjaGVyJTIwU3Bhcmthc3NlbiUyMFZlcmxhZyUyMEdtYkgsTD1T
-dHV0dGdhcnQsQz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeTAO
-BgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAKMAgGBgQAjkYBATAdBgNVHQ4E
-FgQUIQpnbAV/rAz9qSo/4q/3/TlplqwwHwYDVR0jBBgwFoAUIQpnbAV/rAz9qSo/
-4q/3/TlplqwwDQYJKoZIhvcNAQELBQADggEBAHRr6IiNPkWJYHVa8vi4tufRG9nE
-Yy8t2ll8xbu4ar+LXCqbttdaQzVU/7RCX4S1aPm6wb9WFJU+/JfZHpez+gJ9uIFy
-6rYJDxZ4qTxaGnIKGguZbEkpvne38/vtyjR5RuCj5AwEuP7Vy7/j5O1WZDoROMoD
-rRsBHLtg90aDVou0IG+wK5+RPOixSMjfMf79uixHrsriMHrzulTEMmX+S+VfXGmO
-G1RRiCiWgYaEtSIDAP0V9ehpcghfJLlmMBnxSf4n7OZvkd1whvme2rXaQxnZi2qV
-d2qclY03eJ7zx6Zpq8VFuVvOxvmFZ4mMe706runhCq+rHc5x6x0/oIMhDrk=
------END CERTIFICATE-----
-
index c83ab1e..f26d1aa 100644 (file)
@@ -177,10 +177,13 @@ you created the signing request.  By running the command
 
 you get a listing of all private keys under control of @command{gpg-agent}.
 Pick the key which best matches the creation time and run the command
+
+@cartouche
 @smallexample
-  /usr/local/libexec/gpg-protect-tool --p12-export ~/.gnupg/private-keys-v1.d/@var{foo} >@var{foo}.p12
+  /usr/local/libexec/gpg-protect-tool --p12-export \
+     ~/.gnupg/private-keys-v1.d/@var{foo} >@var{foo}.p12
 @end smallexample
+@end cartouche
 
 (Please adjust the path to @command{gpg-protect-tool} to the appropriate
 location). @var{foo} is the name of the key file you picked (it should
@@ -188,11 +191,13 @@ have the suffix @file{.key}).  A Pinentry box will pop up and ask you
 for the current passphrase of the key and a new passphrase to protect it
 in the pkcs#12 file.
 
-To import the created file on the machine you use this command:  
+To import the created file on the machine you use this command:
 
+@cartouche
 @smallexample
   /usr/local/libexec/gpg-protect-tool --p12-import --store  @var{foo}.p12
 @end smallexample
+@end cartouche
 
 You will be asked for the pkcs#12 passphrase and a new passphrase to
 protect the imported private key at its new location.
@@ -230,7 +235,7 @@ gpg: fatal: WriteConsole failed: Access denied
 @end smallexample
 
 @noindent
-The solution is to use the command @command{wineconsole}. 
+The solution is to use the command @command{wineconsole}.
 
 Some operations like gen-key really want to talk to the console directly
 for increased security (for example to prevent the passphrase from
diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
new file mode 100644 (file)
index 0000000..7b2f92c
--- /dev/null
@@ -0,0 +1,1051 @@
+@c Copyright (C) 2002 Klar"alvdalens Datakonsult AB
+@c Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
+@c This is part of the GnuPG manual.
+@c For copying conditions, see the file gnupg.texi.
+
+@node Invoking DIRMNGR
+@chapter Invoking DIRMNGR
+@cindex DIRMNGR command options
+@cindex command options
+@cindex options, DIRMNGR command
+
+@manpage dirmngr.8
+@ifset manverb
+.B dirmngr
+\- CRL and OCSP daemon
+@end ifset
+
+@mansect synopsis
+@ifset manverb
+.B  dirmngr
+.RI [ options ]
+.I command
+.RI [ args ]
+@end ifset
+
+@mansect description
+Dirmngr is a server for managing and downloading certificate revocation
+lists (CRLs) for X.509 certificates and for downloading the certificates
+themselves. Dirmngr also handles OCSP requests as an alternative to
+CRLs. Dirmngr is either invoked internally by gpgsm or when running as a
+system daemon through the @command{dirmngr-client} tool.
+
+If @command{dirmngr} is started in system daemon mode, it uses a
+directory layout as common for system daemons and does not make use of
+the default @file{~/.gnupg} directory.
+
+
+@manpause
+@noindent
+@xref{Option Index},for an index to @command{DIRMNGR}'s commands and
+options.
+@mancont
+
+@menu
+* Dirmngr Commands::      List of all commands.
+* Dirmngr Options::       List of all options.
+* Dirmngr Configuration:: Configuration files.
+* Dirmngr Signals::       Use of signals.
+* Dirmngr Examples::      Some usage examples.
+* Dirmngr Protocol::      The protocol dirmngr uses.
+@end menu
+
+
+@node Dirmngr Commands
+@section Commands
+@mansect commands
+
+Commands are not distinguished from options except for the fact that
+only one command is allowed.
+
+@table @gnupgtabopt
+@item --version
+@opindex version
+Print the program version and licensing information.  Note that you cannot
+abbreviate this command.
+
+@item --help, -h
+@opindex help
+Print a usage message summarizing the most useful command-line options.
+Not that you cannot abbreviate this command.
+
+@item --dump-options
+@opindex dump-options
+Print a list of all available options and commands.  Note that you cannot
+abbreviate this command.
+
+@item --server
+@opindex server
+Run in server mode and wait for commands on the @code{stdin}.  The
+default mode is to create a socket and listen for commands there.
+
+@item --daemon
+@opindex daemon
+Run in background daemon mode and listen for commands on a socket.
+Note that this also changes the default home directory and enables the
+internal certificate validation code.
+
+@item --list-crls
+@opindex list-crls
+List the contents of the CRL cache on @code{stdout}. This is probably
+only useful for debugging purposes.
+
+@item --load-crl @var{file}
+@opindex load-crl
+This command requires a filename as additional argument, and it will
+make Dirmngr try to import the CRL in @var{file} into it's cache.
+Note, that this is only possible if Dirmngr is able to retrieve the
+CA's certificate directly by its own means.  In general it is better
+to use @code{gpgsm}'s @code{--call-dirmngr loadcrl filename} command
+so that @code{gpgsm} can help dirmngr.
+
+@item --fetch-crl @var{url}
+@opindex fetch-crl
+This command requires an URL as additional argument, and it will make
+dirmngr try to retrieve an import the CRL from that @var{url} into
+it's cache.  This is mainly useful for debugging purposes.  The
+@command{dirmngr-client} provides the same feature for a running dirmngr.
+
+@item --shutdown
+@opindex shutdown
+This commands shuts down an running instance of Dirmngr.  This command
+has currently no effect.
+
+@item --flush
+@opindex flush
+This command removes all CRLs from Dirmngr's cache.  Client requests
+will thus trigger reading of fresh CRLs.
+
+@end table
+
+
+@mansect options
+@node Dirmngr Options
+@section Option Summary
+
+@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{dirmngr.conf} and expected in the home directory.
+
+@item --homedir @var{dir}
+@opindex options
+Set the name of the home directory to @var{dir}.  This option is only
+effective when used on the command line.  The default depends on the
+running mode:
+
+@table @asis
+
+@item With @code{--daemon} given on the commandline
+the directory named @file{/etc/gnupg} for configuration files,
+@file{/var/lib/gnupg/} for extra data and @file{/var/cache/gnupg}
+for cached CRLs.
+
+@item Without @code{--daemon} given on the commandline
+the directory named @file{.gnupg} directly below the home directory
+of the user unless the environment variable @code{GNUPGHOME} has been set
+in which case its value will be used.  All kind of data is stored below
+this directory.
+@end table
+
+
+@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{dirmngr}, such as @option{-vv}.
+
+
+@item --log-file @var{file}
+@opindex log-file
+Append all logging output to @var{file}.  This is very helpful in
+seeing what the agent actually does.
+
+@item --debug-level @var{level}
+@opindex debug-level
+Select the debug level for investigating problems.  @var{level} may be a
+numeric value or by a keyword:
+
+@table @code
+@item none
+No debugging at all.  A value of less than 1 may be used instead of
+the keyword.
+@item basic
+Some basic debug messages.  A value between 1 and 2 may be used
+instead of the keyword.
+@item advanced
+More verbose debug messages.  A value between 3 and 5 may be used
+instead of the keyword.
+@item expert
+Even more detailed messages.  A value between 6 and 8 may be used
+instead of the keyword.
+@item guru
+All of the debug messages you can get. A value greater than 8 may be
+used instead of the keyword.  The creation of hash tracing files is
+only enabled if the keyword is used.
+@end table
+
+How these messages are mapped to the actual debugging flags is not
+specified and may change with newer releases 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.  FLAGS are bit encoded and may be given in
+usual C-Syntax.
+
+@item --debug-all
+@opindex debug-all
+Same as @code{--debug=0xffffffff}
+
+@item --gnutls-debug @var{level}
+@opindex gnutls-debug
+Enable debugging of GNUTLS at @var{level}.
+
+@item --debug-wait @var{n}
+@opindex debug-wait
+When running in server mode, wait @var{n} seconds before entering the
+actual processing loop and print the pid.  This gives time to attach a
+debugger.
+
+@item -s
+@itemx --sh
+@itemx -c
+@itemx --csh
+@opindex s
+@opindex sh
+@opindex c
+@opindex csh
+Format the info output in daemon mode for use with the standard Bourne
+shell respective the C-shell . The default ist to guess it based on the
+environment variable @code{SHELL} which is in almost all cases
+sufficient.
+
+@item --force
+@opindex force
+Enabling this option forces loading of expired CRLs; this is only
+useful for debugging.
+
+@item --disable-ldap
+@opindex disable-ldap
+Entirely disables the use of LDAP.
+
+@item --disable-http
+@opindex disable-http
+Entirely disables the use of HTTP.
+
+@item --ignore-http-dp
+@opindex ignore-http-dp
+When looking for the location of a CRL, the to be tested certificate
+usually contains so called @dfn{CRL Distribution Point} (DP) entries
+which are URLs describing the way to access the CRL.  The first found DP
+entry is used.  With this option all entries using the @acronym{HTTP}
+scheme are ignored when looking for a suitable DP.
+
+@item --ignore-ldap-dp
+@opindex ignore-ldap-dp
+This is similar to @option{--ignore-http-dp} but ignores entries using
+the @acronym{LDAP} scheme.  Both options may be combined resulting in
+ignoring DPs entirely.
+
+@item --ignore-ocsp-service-url
+@opindex ignore-ocsp-service-url
+Ignore all OCSP URLs contained in the certificate.  The effect is to
+force the use of the default responder.
+
+@item --honor-http-proxy
+@opindex honor-http-proxy
+If the environment variable @env{http_proxy} has been set, use its
+value to access HTTP servers.
+
+@item --http-proxy @var{host}[:@var{port}]
+@opindex http-proxy
+Use @var{host} and @var{port} to access HTTP servers.  The use of this
+options overrides the environment variable @env{http_proxy} regardless
+whether @option{--honor-http-proxy} has been set.
+
+
+@item --ldap-proxy @var{host}[:@var{port}]
+@opindex ldap-proxy
+Use @var{host} and @var{port} to connect to LDAP servers.  If @var{port}
+is ommitted, port 389 (standard LDAP port) is used.  This overrides any
+specified host and port part in a LDAP URL and will also be used if host
+and port have been ommitted from the URL.
+
+@item --only-ldap-proxy
+@opindex only-ldap-proxy
+Never use anything else but the LDAP "proxy" as configured with
+@option{--ldap-proxy}.  Usually @command{dirmngr} tries to use other
+configured LDAP server if the connection using the "proxy" failed.
+
+
+@item --ldapserverlist-file @var{file}
+@opindex ldapserverlist-file
+Read the list of LDAP servers to consult for CRLs and certificates from
+file instead of the default per-user ldap server list file. The default
+value for @var{file} is @file{dirmngr_ldapservers.conf} or
+@file{ldapservers.conf} when running in @option{--daemon} mode.
+
+This server list file contains one LDAP server per line in the format
+
+@sc{hostname:port:username:password:base_dn}
+
+Lines starting with a  @samp{#} are comments.
+
+Note that as usual all strings entered are expected to be UTF-8 encoded.
+Obviously this will lead to problems if the password has orginally been
+encoded as Latin-1.  There is no other solution here than to put such a
+password in the binary encoding into the file (i.e. non-ascii characters
+won't show up readable).@footnote{The @command{gpgconf} tool might be
+helpful for frontends as it allows to edit this configuration file using
+percent escaped strings.}
+
+
+@item --ldaptimeout @var{secs}
+@opindex ldaptimeout
+Specify the number of seconds to wait for an LDAP query before timing
+out. The default is currently 100 seconds.  0 will never timeout.
+
+
+@item --add-servers
+@opindex add-servers
+This options makes dirmngr add any servers it discovers when validating
+certificates against CRLs to the internal list of servers to consult for
+certificates and CRLs.
+
+This options is useful when trying to validate a certificate that has
+a CRL distribution point that points to a server that is not already
+listed in the ldapserverlist. Dirmngr will always go to this server and
+try to download the CRL, but chances are high that the certificate used
+to sign the CRL is located on the same server. So if dirmngr doesn't add
+that new server to list, it will often not be able to verify the
+signature of the CRL unless the @code{--add-servers} option is used.
+
+Note: The current version of dirmngr has this option disabled by default.
+
+
+@item --allow-ocsp
+@opindex allow-ocsp
+This option enables OCSP support if requested by the client.
+
+OCSP requests are rejected by default because they may violate the
+privacy of the user; for example it is possible to track the time when
+a user is reading a mail.
+
+
+@item --ocsp-responder @var{url}
+@opindex ocsp-responder
+Use @var{url} as the default OCSP Responder if the certificate does
+not contain information about an assigned responder.  Note, that
+@code{--ocsp-signer} must also be set to a valid certificate.
+
+@item --ocsp-signer @var{fpr}|@var{file}
+@opindex ocsp-signer
+Use the certificate with the fingerprint @var{fpr} to check the
+responses of the default OCSP Responder.  Alternativly a filename can be
+given in which case the respinse is expected to be signed by one of the
+certificates described in that file.  Any argument which contains a
+slash, dot or tilde is considered a filename.  Usual filename expansion
+takes place: A tilde at the start followed by a slash is replaced by the
+content of @env{HOME}, no slash at start describes a relative filename
+which will be searched at the home directory.  To make sure that the
+@var{file} is searched in the home directory, either prepend the name
+with "./" or use a name which contains a dot.
+
+If a response has been signed by a certificate described by these
+fingerprints no further check upon the validity of this certificate is
+done.
+
+The format of the @var{FILE} is a list of SHA-1 fingerprint, one per
+line with optional colons between the bytes.  Empty lines and lines
+prefix with a hash mark are ignored.
+
+
+@item --ocsp-max-clock-skew @var{n}
+@opindex ocsp-max-clock-skew
+The number of seconds a skew between the OCSP responder and them local
+clock is accepted.  Default is 600 (20 minutes).
+
+@item --ocsp-max-period @var{n}
+@opindex ocsp-max-period
+Seconds a response is at maximum considered valid after the time given
+in the thisUpdate field.  Default is 7776000 (90 days).
+
+@item --ocsp-current-period @var{n}
+@opindex ocsp-current-period
+The number of seconds an OCSP response is considered valid after the
+time given in the NEXT_UPDATE datum.  Default is 10800 (3 hours).
+
+
+@item --max-replies @var{n}
+@opindex max-replies
+Do not return more that @var{n} items in one query.  The default is
+10.
+
+@item --ignore-cert-extension @var{oid}
+@opindex ignore-cert-extension
+Add @var{oid} to the list of ignored certificate extensions.  The
+@var{oid} is expected to be in dotted decimal form, like
+@code{2.5.29.3}.  This option may be used more than once.  Critical
+flagged certificate extensions matching one of the OIDs in the list
+are treated as if they are actually handled and thus the certificate
+won't be rejected due to an unknown critical extension.  Use this
+option with care because extensions are usually flagged as critical
+for a reason.
+
+@item --hkp-cacert @var{file}
+Use the root certificates in @var{file} for verification of the TLS
+certificates used with @code{hkps} (keyserver access over TLS).  If
+the file is in PEM format a suffix of @code{.pem} is expected for
+@var{file}.  This option may be given multiple times to add more
+root certificates.
+
+@end table
+
+
+@c
+@c Dirmngr Configuration
+@c
+@mansect files
+@node Dirmngr Configuration
+@section Configuration
+
+Dirmngr makes use of several directories when running in daemon mode:
+
+@table @file
+
+@item /etc/gnupg
+This is where all the configuration files are expected by default.
+
+@item /etc/gnupg/trusted-certs
+This directory should be filled with certificates of Root CAs you are
+trusting in checking the CRLS and signing OCSP Reponses.  Usually
+these are the same certificates you use with the applications making
+use of dirmngr.  It is expected that each of these certificate files
+contain exactly one @acronym{DER} encoded certificate in a file with
+the suffix @file{.crt} or @file{.der}.  @command{dirmngr} reads those
+certificates on startup and when given a SIGHUP.  Certificates which
+are not readable or do not make up a proper X.509 certificate are
+ignored; see the log file for details.
+
+Note that for OCSP responses the certificate specified using the option
+@option{--ocsp-signer} is always considered valid to sign OCSP requests.
+
+
+@item /var/lib/gnupg/extra-certs
+This directory may contain extra certificates which are preloaded into
+the interal cache on startup.  This is convenient in cases you have a
+couple intermediate CA certificates or certificates ususally used to
+sign OCSP reponses.  These certificates are first tried before going out
+to the net to look for them.  These certificates must also be
+@acronym{DER} encoded and suffixed with @file{.crt} or @file{.der}.
+
+@item /var/run/gnupg
+This directory keeps the socket file for accsing @command{dirmngr} services.
+The name of the socket file will be @file{S.dirmngr}.  Make sure that this
+directory has the proper permissions to let @command{dirmngr} create the
+socket file and that eligible users may read and write to that socket.
+
+@item /var/cache/gnupg/crls.d
+This directory is used to store cached CRLs.  The @file{crls.d} part
+will be created by dirmngr if it does not exists but you need to make
+sure that the upper directory exists.
+
+@end table
+@manpause
+
+To be able to see what's going on you should create the configure file
+@file{/etc/dirmngr/dirmngr.conf} with at least one line:
+
+@example
+log-file /var/log/gnupg/dirmngr.log
+@end example
+
+To be able to perform OCSP requests you probably want to add the line:
+
+@example
+allow-ocsp
+@end example
+
+Now you may start dirmngr as a system daemon using:
+
+@example
+dirmngr --daemon
+@end example
+
+Please ignore the output; it is not needed anymore.  Check the log file
+to see whether all trusted root certificates have been loaded correctly.
+
+
+@c
+@c Dirmngr Signals
+@c
+@mansect signals
+@node Dirmngr Signals
+@section Use of signals.
+
+A running @command{dirmngr} may be controlled by signals, i.e. using
+the @command{kill} command to send a signal to the process.
+
+Here is a list of supported signals:
+
+@table @gnupgtabopt
+
+@item SIGHUP
+@cpindex SIGHUP
+This signals flushes all internally cached CRLs as well as any cached
+certificates.  Then the certificate cache is reinitialized as on
+startup.  Options are re-read from the configuration file.
+
+@item SIGTERM
+@cpindex SIGTERM
+Shuts down the process but waits until all current requests are
+fulfilled.  If the process has received 3 of these signals and requests
+are still pending, a shutdown is forced.
+
+@item SIGINT
+@cpindex SIGINT
+Shuts down the process immediately.
+
+
+@item SIGUSR1
+@cpindex SIGUSR1
+This prints some caching statistics to the log file.
+
+@end table
+
+
+
+@c
+@c  Examples
+@c
+@mansect examples
+@node Dirmngr Examples
+@section Examples
+
+
+Dirmngr is supposed to be used as a system wide daemon, it should be
+started like:
+
+@example
+  dirmngr --daemon
+@end example
+
+This will force it to go into the backround, read the default
+certificates (including the trusted root certificates) and listen on a
+socket for client requests.  It does also print information about the
+socket used but they are only for compatibilty reasons with old GnuPG
+versions and may be ignored.
+
+For debugging purposes it is also possible to start Dirmngr in the
+foreground:
+
+@example
+  dirmngr --server -v
+@end example
+
+
+
+@c
+@c  Assuan Protocol
+@c
+@manpause
+@node Dirmngr Protocol
+@section Dirmngr's Assuan Protocol
+
+Assuan is the IPC protocol used to access dirmngr.  This is a
+description of the commands implemented by dirmngr.
+
+@menu
+* Dirmngr LOOKUP::      Look up a certificate via LDAP
+* Dirmngr ISVALID::     Validate a certificate using a CRL or OCSP.
+* Dirmngr CHECKCRL::    Validate a certificate using a CRL.
+* Dirmngr CHECKOCSP::   Validate a certificate using OCSP.
+* Dirmngr CACHECERT::   Put a certificate into the internal cache.
+* Dirmngr VALIDATE::    Validate a certificate for debugging.
+@end menu
+
+@node Dirmngr LOOKUP
+@subsection Return the certificate(s) found
+
+Lookup certificate.  To allow multiple patterns (which are ORed)
+quoting is required: Spaces are to be translated into "+" or into
+"%20"; obviously this requires that the usual escape quoting rules
+are applied.  The server responds with:
+
+@example
+  S: D <DER encoded certificate>
+  S: END
+  S: D <second DER encoded certificate>
+  S: END
+  S: OK
+@end example
+
+In this example 2 certificates are returned.  The server may return
+any number of certificates; OK will also be returned when no
+certificates were found.  The dirmngr might return a status line
+
+@example
+  S: S TRUNCATED <n>
+@end example
+
+
+To indicate that the output was truncated to N items due to a
+limitation of the server or by an arbitrary set limit.
+
+The option @option{--url} may be used if instead of a search pattern a
+complete URL to the certificate is known:
+
+@example
+  C: LOOKUP --url CN%3DWerner%20Koch,o%3DIntevation%20GmbH,c%3DDE?userCertificate
+@end example
+
+If the option @option{--cache-only} is given, no external lookup is done
+so that only certificates from the cache are returned.
+
+With the option @option{--single}, the first and only the first match
+will be returned.  Unless option @option{--cache-only} is also used, no
+local lookup will be done in this case.
+
+
+
+@node Dirmngr ISVALID
+@subsection Validate a certificate using a CRL or OCSP
+
+@example
+  ISVALID [--only-ocsp] [--force-default-responder] @var{certid}|@var{certfpr}
+@end example
+
+Check whether the certificate described by the @var{certid} has been
+revoked.  Due to caching, the Dirmngr is able to answer immediately in
+most cases.
+
+The @var{certid} is a hex encoded string consisting of two parts,
+delimited by a single dot.  The first part is the SHA-1 hash of the
+issuer name and the second part the serial number.
+
+Alternatively the certificate's SHA-1 fingerprint @var{certfpr} may be
+given in which case an OCSP request is done before consulting the CRL.
+If the option @option{--only-ocsp} is given, no fallback to a CRL check
+will be used.  If the option @option{--force-default-responder} is
+given, only the default OCSP responder will be used and any other
+methods of obtaining an OCSP responder URL won't be used.
+
+@noindent
+Common return values are:
+
+@table @code
+@item GPG_ERR_NO_ERROR (0)
+This is the positive answer: The certificate is not revoked and we have
+an up-to-date revocation list for that certificate.  If OCSP was used
+the responder confirmed that the certificate has not been revoked.
+
+@item GPG_ERR_CERT_REVOKED
+This is the negative answer: The certificate has been revoked.  Either
+it is in a CRL and that list is up to date or an OCSP responder informed
+us that it has been revoked.
+
+@item GPG_ERR_NO_CRL_KNOWN
+No CRL is known for this certificate or the CRL is not valid or out of
+date.
+
+@item GPG_ERR_NO_DATA
+The OCSP responder returned an ``unknown'' status.  This means that it
+is not aware of the certificate's status.
+
+@item GPG_ERR_NOT_SUPPORTED
+This is commonly seen if OCSP support has not been enabled in the
+configuration.
+@end table
+
+If DirMngr has not enough information about the given certificate (which
+is the case for not yet cached certificates), it will will inquire the
+missing data:
+
+@example
+  S: INQUIRE SENDCERT <CertID>
+  C: D <DER encoded certificate>
+  C: END
+@end example
+
+A client should be aware that DirMngr may ask for more than one
+certificate.
+
+If Dirmngr has a certificate but the signature of the certificate
+could not been validated because the root certificate is not known to
+dirmngr as trusted, it may ask back to see whether the client trusts
+this the root certificate:
+
+@example
+  S: INQUIRE ISTRUSTED <CertHexfpr>
+  C: D 1
+  C: END
+@end example
+
+Only this answer will let Dirmngr consider the CRL as valid.
+
+
+@node Dirmngr CHECKCRL
+@subsection Validate a certificate using a CRL
+
+Check whether the certificate with FINGERPRINT (SHA-1 hash of the
+entire X.509 certificate blob) is valid or not by consulting the CRL
+responsible for this certificate.  If the fingerprint has not been
+given or the certificate is not know, the function inquires the
+certificate using:
+
+@example
+  S: INQUIRE TARGETCERT
+  C: D <DER encoded certificate>
+  C: END
+@end example
+
+Thus the caller is expected to return the certificate for the request
+(which should match FINGERPRINT) as a binary blob.  Processing then
+takes place without further interaction; in particular dirmngr tries
+to locate other required certificate by its own mechanism which
+includes a local certificate store as well as a list of trusted root
+certificates.
+
+@noindent
+The return code is 0 for success; i.e. the certificate has not been
+revoked or one of the usual error codes from libgpg-error.
+
+@node Dirmngr CHECKOCSP
+@subsection Validate a certificate using OCSP
+
+@example
+  CHECKOCSP [--force-default-responder] [@var{fingerprint}]
+@end example
+
+Check whether the certificate with @var{fingerprint} (the SHA-1 hash of
+the entire X.509 certificate blob) is valid by consulting the appropiate
+OCSP responder.  If the fingerprint has not been given or the
+certificate is not known by Dirmngr, the function inquires the
+certificate using:
+
+@example
+  S: INQUIRE TARGETCERT
+  C: D <DER encoded certificate>
+  C: END
+@end example
+
+Thus the caller is expected to return the certificate for the request
+(which should match @var{fingerprint}) as a binary blob.  Processing
+then takes place without further interaction; in particular dirmngr
+tries to locate other required certificates by its own mechanism which
+includes a local certificate store as well as a list of trusted root
+certificates.
+
+If the option @option{--force-default-responder} is given, only the
+default OCSP responder is used.  This option is the per-command variant
+of the global option @option{--ignore-ocsp-service-url}.
+
+
+@noindent
+The return code is 0 for success; i.e. the certificate has not been
+revoked or one of the usual error codes from libgpg-error.
+
+@node Dirmngr CACHECERT
+@subsection Put a certificate into the internal cache
+
+Put a certificate into the internal cache.  This command might be
+useful if a client knows in advance certificates required for a test and
+wnats to make sure they get added to the internal cache.  It is also
+helpful for debugging.  To get the actual certificate, this command
+immediately inquires it using
+
+@example
+  S: INQUIRE TARGETCERT
+  C: D <DER encoded certificate>
+  C: END
+@end example
+
+Thus the caller is expected to return the certificate for the request
+as a binary blob.
+
+@noindent
+The return code is 0 for success; i.e. the certificate has not been
+succesfully cached or one of the usual error codes from libgpg-error.
+
+@node Dirmngr VALIDATE
+@subsection Validate a certificate for debugging
+
+Validate a certificate using the certificate validation function used
+internally by dirmngr.  This command is only useful for debugging.  To
+get the actual certificate, this command immediately inquires it using
+
+@example
+  S: INQUIRE TARGETCERT
+  C: D <DER encoded certificate>
+  C: END
+@end example
+
+Thus the caller is expected to return the certificate for the request
+as a binary blob.
+
+
+@mansect see also
+@ifset isman
+@command{gpgsm}(1),
+@command{dirmngr-client}(1)
+@end ifset
+@include see-also-note.texi
+
+@c
+@c !!! UNDER CONSTRUCTION !!!
+@c
+@c
+@c @section Verifying a Certificate
+@c
+@c There are several ways to request services from Dirmngr.  Almost all of
+@c them are done using the Assuan protocol.  What we describe here is the
+@c Assuan command CHECKCRL as used for example by the dirmnr-client tool if
+@c invoked as
+@c
+@c @example
+@c   dirmngr-client foo.crt
+@c @end example
+@c
+@c This command will send an Assuan request to an already running Dirmngr
+@c instance.  foo.crt is expected to be a standard X.509 certificate and
+@c dirmngr will receive the Assuan command
+@c
+@c @example
+@c    CHECKCRL @var [{fingerprint}]
+@c @end example
+@c
+@c @var{fingerprint} is optional and expected to be the SHA-1 has of the
+@c DER encoding of the certificate under question.  It is to be HEX
+@c encoded.  The rationale for sending the fingerprint is that it allows
+@c dirmngr to reply immediatly if it has already cached such a request.  If
+@c this is not the case and no certificate has been found in dirmngr's
+@c internal certificate storage, dirmngr will request the certificate using
+@c the Assuan inquiry
+@c
+@c @example
+@c       INQUIRE TARGETCERT
+@c @end example
+@c
+@c The caller (in our example dirmngr-client) is then expected to return
+@c the certificate for the request (which should match @var{fingerprint})
+@c as a binary blob.
+@c
+@c Dirmngr now passes control to @code{crl_cache_cert_isvalid}.  This
+@c function checks whether a CRL item exists for target certificate.  These
+@c CRL items are kept in a database of already loaded and verified CRLs.
+@c This mechanism is called the CRL cache.  Obviously timestamps are kept
+@c there with each item to cope with the expiration date of the CRL.  The
+@c possible return values are: @code{0} to indicate that a valid CRL is
+@c available for the certificate and the certificate itself is not listed
+@c in this CRL, @code{GPG_ERR_CERT_REVOKED} to indicate that the certificate is
+@c listed in the CRL or @code{GPG_ERR_NO_CRL_KNOWN} in cases where no CRL or no
+@c information is available.  The first two codes are immediatly returned to
+@c the caller and the processing of this request has been done.
+@c
+@c Only the @code{GPG_ERR_NO_CRL_KNOWN} needs more attention: Dirmngr now
+@c calls @code{clr_cache_reload_crl} and if this succeeds calls
+@c @code{crl_cache_cert_isvald) once more.  All further errors are
+@c immediately returned to the caller.
+@c
+@c @code{crl_cache_reload_crl} is the actual heart of the CRL management.
+@c It locates the corresponding CRL for the target certificate, reads and
+@c verifies this CRL and stores it in the CRL cache.  It works like this:
+@c
+@c * Loop over all crlDPs in the target certificate.
+@c     * If the crlDP is invalid immediately terminate the loop.
+@c     * Loop over all names in the current crlDP.
+@c         * If the URL scheme is unknown or not enabled
+@c           (--ignore-http-dp, --ignore-ldap-dp) continues with
+@c           the next name.
+@c         * @code{crl_fetch} is called to actually retrieve the CRL.
+@c           In case of problems this name is ignore and we continue with
+@c           the next name.  Note that @code{crl_fetch} does only return
+@c           a descriptor for the CRL for further reading so does the CRL
+@c           does not yet end up in memory.
+@c         * @code{crl_cache_insert} is called with that descriptor to
+@c           actually read the CRL into the cache. See below for a
+@c           description of this function.  If there is any error (e.g. read
+@c           problem, CRL not correctly signed or verification of signature
+@c           not possible), this descriptor is rejected and we continue
+@c           with the next name.  If the CRL has been successfully loaded,
+@c           the loop is terminated.
+@c * If no crlDP has been found in the previous loop use a default CRL.
+@c   Note, that if any crlDP has been found but loading of the CRL failed,
+@c   this condition is not true.
+@c     * Try to load a CRL from all configured servers (ldapservers.conf)
+@c       in turn.  The first server returning a CRL is used.
+@c     * @code(crl_cache_insert) is then used to actually insert the CRL
+@c       into the cache.  If this failed we give up immediatley without
+@c       checking the rest of the servers from the first step.
+@c * Ready.
+@c
+@c
+@c The @code{crl_cache_insert} function takes care of reading the bulk of
+@c the CRL, parsing it and checking the signature.  It works like this: A
+@c new database file is created using a temporary file name.  The CRL
+@c parsing machinery is started and all items of the CRL are put into
+@c this database file.  At the end the issuer certificate of the CRL
+@c needs to be retrieved.  Three cases are to be distinguished:
+@c
+@c  a) An authorityKeyIdentifier with an issuer and serialno exits: The
+@c     certificate is retrieved using @code{find_cert_bysn}.  If
+@c     the certificate is in the certificate cache, it is directly
+@c     returned. Then the requester (i.e. the client who requested the
+@c     CRL check) is asked via the Assuan inquiry ``SENDCERT'' whether
+@c     he can provide this certificate.  If this succeed the returned
+@c     certificate gets cached and returned.  Note, that dirmngr does not
+@c     verify in any way whether the expected certificate is returned.
+@c     It is in the interest of the client to return a useful certificate
+@c     as otherwise the service request will fail due to a bad signature.
+@c     The last way to get the certificate is by looking it up at
+@c     external resources.  This is done using the @code{ca_cert_fetch}
+@c     and @code{fetch_next_ksba_cert} and comparing the returned
+@c     certificate to match the requested issuer and seriano (This is
+@c     needed because the LDAP layer may return several certificates as
+@c     LDAP as no standard way to retrieve by serial number).
+@c
+@c  b) An authorityKeyIdentifier with a key ID exists: The certificate is
+@c     retrieved using @code{find_cert_bysubject}.  If the certificate is
+@c     in the certificate cache, it is directly returned.  Then the
+@c     requester is asked via the Assuan inquiry ``SENDCERT_SKI'' whether
+@c     he can provide this certificate.  If this succeed the returned
+@c     certificate gets cached and returned.  Note, that dirmngr does not
+@c     verify in any way whether the expected certificate is returned.
+@c     It is in the interest of the client to return a useful certificate
+@c     as otherwise the service request will fail due to a bad signature.
+@c     The last way to get the certificate is by looking it up at
+@c     external resources.  This is done using the @code{ca_cert_fetch}
+@c     and @code{fetch_next_ksba_cert} and comparing the returned
+@c     certificate to match the requested subject and key ID.
+@c
+@c  c) No authorityKeyIdentifier exits: The certificate is retrieved
+@c     using @code{find_cert_bysubject} without the key ID argument.  If
+@c     the certificate is in the certificate cache the first one with a
+@c     matching subject is is directly returned.  Then the requester is
+@c     asked via the Assuan inquiry ``SENDCERT'' and an exact
+@c     specification of the subject whether he can
+@c     provide this certificate.  If this succeed the returned
+@c     certificate gets cached and returned.  Note, that dirmngr does not
+@c     verify in any way whether the expected certificate is returned.
+@c     It is in the interest of the client to return a useful certificate
+@c     as otherwise the service request will fail due to a bad signature.
+@c     The last way to get the certificate is by looking it up at
+@c     external resources.  This is done using the @code{ca_cert_fetch}
+@c     and @code{fetch_next_ksba_cert} and comparing the returned
+@c     certificate to match the requested subject; the first certificate
+@c     with a matching subject is then returned.
+@c
+@c If no certificate was found, the function returns with the error
+@c GPG_ERR_MISSING_CERT.  Now the signature is verified.  If this fails,
+@c the erro is returned.  On success the @code{validate_cert_chain} is
+@c used to verify that the certificate is actually valid.
+@c
+@c Here we may encounter a recursive situation:
+@c @code{validate_cert_chain} needs to look at other certificates and
+@c also at CRLs to check whether tehse other certificates and well, the
+@c CRL issuer certificate itself are not revoked.  FIXME: We need to make
+@c sure that @code{validate_cert_chain} does not try to lookup the CRL we
+@c are currently processing. This would be a catch-22 and may indicate a
+@c broken PKI.  However, due to overlapping expiring times and imprecise
+@c clocks thsi may actually happen.
+@c
+@c For historical reasons the Assuan command ISVALID is a bit different
+@c to CHECKCRL but this is mainly due to different calling conventions.
+@c In the end the same fucntionality is used, albeit hidden by a couple
+@c of indirection and argument and result code mangling.  It furthere
+@c ingetrages OCSP checking depending on options are the way it is
+@c called.  GPGSM still uses this command but might eventuall switch over
+@c to CHECKCRL and CHECKOCSP so that ISVALID can be retired.
+@c
+@c
+@c @section Validating a certificate
+@c
+@c We describe here how the internal function @code{validate_cert_chain}
+@c works. Note that mainly testing purposes this functionality may be
+@c called directly using @cmd{dirmngr-client --validate @file{foo.crt}}.
+@c
+@c For backward compatibility this function returns success if Dirmngr is
+@c not used as a system daemon.  Thus not validating the certicates at
+@c all. FIXME:  This is definitely not correct and should be fixed ASAP.
+@c
+@c The function takes the target certificate and a mode argument as
+@c parameters and returns an error code and optionally the closes
+@c expiration time of all certificates in the chain.
+@c
+@c We first check that the certificate may be used for the requested
+@c purpose (i.e. OCSP or CRL signing).  If this is not the case
+@c GPG_ERR_WRONG_KEY_USAGE is returned.
+@c
+@c The next step is to find the trust anchor (root certificate) and to
+@c assemble the chain in memory: Starting with the target certificate,
+@c the expiration time is checked against the current date, unknown
+@c critical extensions are detected and certificate policies are matched
+@c (We only allow 2.289.9.9 but I have no clue about that OID and from
+@c where I got it - it does not even seem to be assigned - debug cruft?).
+@c
+@c Now if this certificate is a self-signed one, we have reached the
+@c trust anchor.  In this case we check that the signature is good, the
+@c certificate is allowed to act as a CA, that it is a trusted one (by
+@c checking whether it is has been put into the trusted-certs
+@c configuration directory) and finally prepend into to our list
+@c representing the certificate chain.  This steps ends then.
+@c
+@c If it is not a self-signed certificate, we check that the chain won't
+@c get too long (current limit is 100), if this is the case we terminate
+@c with the error GPG_ERR_BAD_CERT_CHAIN.
+@c
+@c Now the issuer's certificate is looked up: If an
+@c authorityKeyIdentifier is available, this one is used to locate the
+@c certificate either using issuer and serialnumber or subject DN
+@c (i.e. the issuer's DN) and the keyID.  The functions
+@c @code{find_cert_bysn) and @code{find_cert_bysubject} are used
+@c respectively. The have already been described above under the
+@c description of @code{crl_cache_insert}.  If no certificate was found
+@c or with no authorityKeyIdentifier, only the cache is consulted using
+@c @code{get_cert_bysubject}.  The latter is is done under the assumption
+@c that a matching certificate has explicitly been put into the
+@c certificate cache.  If the issuer's certificate could not be found,
+@c the validation terminates with the error code @code{GPG_ERR_MISSING_CERT}.
+@c
+@c If the issuer's certificate has been found, the signature of the
+@c actual certificate is checked and in case this fails the error
+@c #code{GPG_ERR_BAD_CERT_CHAIN} is returned.  If the signature checks out, the
+@c maximum cahin length of the issueing certificate is checked as well as
+@c the capiblity of the certificate (i.e. whether he may be used for
+@c certificate signing).  Then the certificate is prepended to our list
+@c representing the certificate chain.  Finally the loop is continued now
+@c with the issuer's certificate as the current certificate.
+@c
+@c After the end of the loop and if no error as been encountered
+@c (i.e. the certificate chain has been assempled correctly), a check is
+@c done whether any certificate expired or a critical policy has not been
+@c met.  In any of these cases the validation terminates with an
+@c appropriate error.
+@c
+@c Finally the function @code{check_revocations} is called to verify no
+@c certificate in the assempled chain has been revoked: This is an
+@c recursive process because a CRL has to be checked for each certificate
+@c in the chain except for the root certificate, of which we already know
+@c that it is trusted and we avoid checking a CRL here due to common
+@c setup problems and the assumption that a revoked root certifcate has
+@c been removed from the list of trusted certificates.
+@c
+@c
+@c
+@c
+@c @section Looking up certificates through LDAP.
+@c
+@c This describes the LDAP layer to retrieve certificates.
+@c the functions @code{ca_cert_fetch} and @code{fetch_next_ksba_cert} are
+@c used for this.  The first one starts a search and the second one is
+@c used to retrieve certificate after certificate.
+@c
+
+
diff --git a/doc/faq.org b/doc/faq.org
new file mode 100644 (file)
index 0000000..e4e9187
--- /dev/null
@@ -0,0 +1,1558 @@
+# faq.org                                          -*- coding: utf-8; -*-
+#+STARTUP:   overview
+#+OPTIONS:   H:2 num:t toc:t \n:nil @:t ::t |:t ^:t *:t TeX:t
+#+EMAIL:     wk@gnupg.org
+#+AUTHOR:    GnuPG users
+#+LANGUAGE:  en
+#+TITLE:     GnuPG Frequently Asked Questions
+#+OPTIONS:   H:3 num:nil toc:t \n:nil @:t ::t |:t ^:{} -:t f:t *:t TeX:t LaTeX:t skip:nil d:(HIDE) tags:not-in-toc
+#+LINK: gnupgweb http://www.gnupg.org/
+#+LINK: roundup https://bugs.g10code.com/gnupg/issue
+#+STYLE: <link rel="stylesheet" type="text/css" href="http://www.gnupg.org/share/site.css" />
+
+# FIXME: This FAQ needs a heavy cleanup.  For now I only switched to
+#        org-mode format for easier maintenance.
+
+#+begin_html
+<a href="/"><img src="http://gnupg.org/share/logo-gnupg-light-purple-bg.png" class="logo-link" /></a>
+#+end_html
+
+*WARNING: This FAQ is heavily outdated*.  Mentioned versions of GnuPG
+have reached end of life many years ago.  Almost all bugs and problems
+have been fixed in the now current versions of GnuPG.  We will try to
+update this FAQ in the next month.  See the section "Changes" for recent updates.
+
+
+* Welcome
+  :PROPERTIES:
+  :CUSTOM_ID: welcome
+  :END:
+
+  Welcome to the GnuPG FAQ.  The latest HTML version is available at\\
+  [[http://www.gnupg.org/faq/GnuPG-FAQ.html]]; \\
+  a plain text Gversion at \\
+  ftp://ftp.gnupg.org/gcrypt/gnupg/GnuPG-FAQ.txt.
+
+  See the end of this file for the release date.
+
+  The index is generated automatically, so there may be errors. Not
+  all questions may be in the section they belong to. Suggestions
+  about how to improve the structure of this FAQ are welcome.
+
+  Please send additions and corrections to the gnupg-users mailing
+  list. It would be most convenient if you could provide the answer to
+  be included here as well. Your help is very much appreciated!
+
+  Please, don't send message like "This should be a FAQ - what's the
+  answer?". If it hasn't been asked before, it isn't a FAQ. In that
+  case you could search in the mailing list archive.
+
+** What conventions are used in this FAQ?
+   :PROPERTIES:
+   :CUSTOM_ID: what-conventions-are-used-in-this-faq
+   :END:
+
+    Although GnuPG is being developed for several operating systems
+    (often in parallel), the conventions used in this FAQ reflect a
+    UNIX shell environment. For Win32 users, references to a shell
+    prompt (=$=) should be interpreted as a command prompt (=>=),
+    directory names separated by a forward slash (=/=) may need to be
+    converted to a back slash (=\=), and a tilde (=~=) represents a
+    user's "home" directory (reference question [[id:how-do-i-put-my-keyring-in-a-different-directory][How do I put my keyring in a different directory?]] for an example).
+
+    Some command-lines presented in this FAQ are too long to properly
+    display in some browsers for the web page version of this file, and
+    have been split into two or more lines. For these commands please
+    remember to enter the entire command-string on one line or the
+    command will error, or at minimum not give the desired results.
+
+    Please keep in mind that this FAQ contains information that may not
+    apply to your particular version, as new features and bug fixes are
+    added on a continuing basis (reference the NEWS file included with
+    the source or package for noteworthy changes between versions). One
+    item to note is that starting with GnuPG version 1.1.92 the file
+    containing user options and settings has been renamed from "options"
+    to "gpg.conf". Information in the FAQ that relates to the options
+    file may be interchangable with the newer gpg.conf file in many
+    instances. See question
+    [[#gnupg-no-longer-installs-a-options-file-is-it-missing][GnuPG no longer installs a ~/.gnupg/options file. Is it missing?]]
+    for details.
+
+* General Questions
+
+** What is GnuPG?
+   :PROPERTIES:
+   :CUSTOM_ID: what-is-gnupg
+   :END:
+
+    [[gnupgweb][GnuPG]] stands for GNU Privacy Guard and is GNU's tool for secure
+    communication and data storage. It can be used to encrypt data and
+    to create digital signatures. It includes an advanced key
+    management facility and is compliant with the proposed OpenPGP
+    Internet standard as described in [[http://www.rfc-editor.org/rfc/rfc4880.txt][RFC-4880]].  As such, it is aimed
+    to be compatible with PGP from PGP Corp. and other OpenPGP tools
+
+** Is GnuPG compatible with PGP?
+   :PROPERTIES:
+   :CUSTOM_ID: is-gnupg-compatible-with-pgp
+   :END:
+
+    In general, yes. GnuPG and newer PGP releases should be implementing
+    the OpenPGP standard. But there are some interoperability problems.
+    See question
+    [[#how-can-i-encrypt-a-message-so-that-pgp-is-able-to-decrypt-it][How can I encrypt a message with GnuPG so that PGP is able to decrypt it?]]
+    for details.
+
+** Is GnuPG free to use for personal or commercial use?
+   :PROPERTIES:
+   :CUSTOM_ID: is-gnupg-free-to-use
+   :END:
+
+    Yes. GnuPG is part of the GNU family of tools and applications built
+    and provided in accordance with the Free Software Foundation (FSF)
+    General Public License (GPL). Therefore the software is free to copy,
+    use, modify and distribute in accordance with that license. Please
+    read the file titled COPYING that accompanies the application for
+    more information.
+
+
+* Sources of Information
+
+** Where can I find more information on GnuPG?
+   :PROPERTIES:
+   :CUSTOM_ID: more-information-on-gnupg
+   :END:
+
+   On-line resources:
+
+   - The documentation page is located at [[gnupgweb:documentation/]].
+     Also, have a look at the HOWTOs and the GNU Privacy Handbook
+     (GPH, available in English, Spanish and Russian).  The latter
+     provides a detailed user's guide to GnuPG.  You'll also find a
+     document about how to convert from PGP 2.x to GnuPG.
+
+   - At [[gnupgweb:documentation/mailing-lists.html]] you'll find an
+     online archive of the GnuPG mailing lists.  Most interesting
+     should be gnupg-users for all user-related issues and gnupg-devel
+     if you want to get in touch with the developers.
+
+     In addition, searchable archives can be found on MARC, e.g.:\\
+     For gnupg-users : [[http://marc.theaimsgroup.com/?l=gnupg-users&r=1&w=2]]\\
+     For gnupg-devel : [[http://marc.theaimsgroup.com/?l=gnupg-devel&r=1&w=2]]
+
+     *Please:* Before posting to a list, read this FAQ and the
+     available documentation.  In addition, search the list archive
+     --- maybe your question has already been discussed. This way you
+     help people focus on topics that have not yet been resolved.
+
+   - The GnuPG source distribution contains a subdirectory:
+
+     : ./doc
+
+     where some additional documentation is located (mainly
+     interesting for hackers, not the casual user).
+
+
+** Where do I get GnuPG?
+   :PROPERTIES:
+   :CUSTOM_ID: where-do-i-get-gnupg
+   :END:
+
+    You can download the GNU Privacy Guard from its primary FTP server
+    [[ftp://ftp.gnupg.org/gcrypt/gnupg/][ftp.gnupg.org]] or from one of its [[gnupgweb:download/mirrors.html][mirrors]].
+
+    The current stable version is FIXME. Please upgrade to this
+    version as it includes additional features, functions and security
+    fixes that may not have existed in prior versions.
+
+* Installation
+
+** Which OSes does GnuPG run on?
+   :PROPERTIES:
+   :CUSTOM_ID: which-oses-does-gnupg-run-on
+   :END:
+
+    It should run on most Unices as well as Windows versions
+    (including Windows NT/2000) and Macintosh OS/X.  A list of OSes
+    reported to be OK is presented at:
+
+    [[gnupgweb:download/supported_systems.html]]
+
+** Which random data gatherer should I use?
+   :PROPERTIES:
+   :CUSTOM_ID: which-random-data-gatherer-should-i-use
+   :END:
+
+    "Good" random numbers are crucial for the security of your encryption.
+    Different operating systems provide a variety of more or less quality
+    random data. Linux and *BSD provide kernel generated random data
+    through /dev/random - this should be the preferred choice on these
+    systems. Also Solaris users with the SUNWski package installed have
+    a /dev/random. In these cases, use the configure option:
+
+    : --enable-static-rnd=linux
+
+    In addition, there's also the kernel random device by Andi Maier
+    [[http://www.cosy.sbg.ac.at/~andi/SUNrand/]], but it's still beta. Use
+    at your own risk!
+
+    On other systems, the Entropy Gathering Daemon (EGD) is a good choice.
+    It is a perl-daemon that monitors system activity and hashes it into
+    random data. See the download page [[gnupgweb:download/]]
+    to obtain EGD. Use:
+
+    : --enable-static-rnd=egd
+
+    here.
+
+    If the above options do not work, you can use the random number
+    generator "unix". This is *very slow* and should be avoided. The
+    random quality isn't very good so don't use it on sensitive data.
+
+** How do I include support for RSA and IDEA?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-include-support-for-rsa-and-idea
+   :END:
+
+    RSA is included as of GnuPG version 1.0.3.
+
+    The official GnuPG distribution does not contain IDEA due to a patent
+    restriction. The patent does not expire before 2007 so don't expect
+    official support before then.
+
+    However, there is an unofficial module to include it even in earlier
+    versions of GnuPG. It's available from
+    [[ftp://ftp.gnupg.dk/pub/contrib-dk/]]. Look for:
+
+    : idea.c.gz        (c module)
+    : idea.c.gz.sig    (signature file)
+
+    : ideadll.zip      (c module and win32 dll)
+    : ideadll.zip.sig  (signature file)
+
+    Compilation directives are in the headers of these files. You will
+    then need to add the following line to your =~/.gnupg/gpg.conf= or
+    =~/.gnupg/options= file:
+
+    : load-extension idea
+
+
+* Usage
+
+** What is the recommended key size?
+   :PROPERTIES:
+   :CUSTOM_ID: what-is-the-recommended-key-size
+   :END:
+
+    1024 bit for DSA signatures; even for plain Elgamal signatures.
+    This is sufficient as the size of the hash is probably the weakest
+    link if the key size is larger than 1024 bits. Encryption keys may
+    have greater sizes, but you should then check the fingerprint of
+    this key:
+
+    : $ gpg --fingerprint <user ID>
+
+    As for the key algorithms, you should stick with the default (i.e.,
+    DSA signature and Elgamal encryption). An Elgamal signing key has
+    the following disadvantages: the signature is larger, it is hard
+    to create such a key useful for signatures which can withstand some
+    real world attacks, you don't get any extra security compared to
+    DSA, and there might be compatibility problems with certain PGP
+    versions. It has only been introduced because at the time it was
+    not clear whether there was a patent on DSA.
+
+** Why does it sometimes take so long to create keys?
+   :PROPERTIES:
+   :CUSTOM_ID: why-does-it-sometimes-take-so-long-to-create-keys
+   :END:
+
+    The problem here is that we need a lot of random bytes and for that
+    we (on Linux the /dev/random device) must collect some random data.
+    It is really not easy to fill the Linux internal entropy buffer; I
+    talked to Ted Ts'o and he commented that the best way to fill the
+    buffer is to play with your keyboard. Good security has its price.
+    What I do is to hit several times on the shift, control, alternate,
+    and caps lock keys, because these keys do not produce output to the
+    screen. This way you get your keys really fast (it's the same thing
+    PGP2 does).
+
+    Another problem might be another program which eats up your random
+    bytes (a program (look at your daemons) that reads from /dev/random).
+
+** And it really takes long when I work on a remote system. Why?
+   :PROPERTIES:
+   :CUSTOM_ID: it-really-takes-long-when-i-work-on-a-remote-system
+   :END:
+
+    Don't do this at all! You should never create keys or even use GnuPG
+    on a remote system because you normally have no physical control
+    over your secret key ring (which is in most cases vulnerable to
+    advanced dictionary attacks) - I strongly encourage everyone to only
+    create keys on a local computer (a disconnected laptop is probably
+    the best choice) and if you need it on your connected box (I know,
+    we all do this) be sure to have a strong password for both your
+    account and for your secret key, and that you can trust your system
+    administrator.
+
+    When I check GnuPG on a remote system via ssh (I have no Alpha here)
+    ;-) I have the same problem. It takes a *very* long time to create
+    the keys, so I use a special option, --quick-random, to generate
+    insecure keys which are only good for some tests.
+
+** What is the difference between options and commands?
+   :PROPERTIES:
+   :CUSTOM_ID: difference-between-options-and-commands
+   :END:
+
+    If you do a 'gpg --help', you will get two separate lists. The first
+    is a list of commands. The second is a list of options. Whenever you
+    run GPG, you *must* pick exactly one command (with one exception,
+    see below). You *may* pick one or more options. The command should,
+    just by convention, come at the end of the argument list, after all
+    the options. If the command takes a file (all the basic ones do),
+    the filename comes at the very end. So the basic way to run gpg is:
+
+    : $ gpg [--option something] [--option2] [--option3 something] --command file
+
+    Some options take arguments. For example, the --output option (which
+    can be abbreviated as -o) is an option that takes a filename. The
+    option's argument must follow immediately after the option itself,
+    otherwise gpg doesn't know which option the argument is supposed to
+    paired with. As an option, --output and its filename must come before
+    the command. The --recipient (-r) option takes a name or keyID to
+    encrypt the message to, which must come right after the -r option.
+    The --encrypt (or -e) command comes after all the options and is
+    followed by the file you wish to encrypt. Therefore in this example
+    the command-line issued would be:
+
+    : $ gpg -r alice -o secret.txt -e test.txt
+
+    If you write the options out in full, it is easier to read:
+
+    : $ gpg --recipient alice --output secret.txt --encrypt test.txt
+
+    If you're encrypting to a file with the extension ".txt", then you'd
+    probably expect to see ASCII-armored text in the file (not binary),
+    so you need to add the --armor (-a) option, which doesn't take any
+    arguments:
+
+    : $ gpg --armor --recipient alice --output secret.txt --encrypt test.txt
+
+    If you imagine square brackets around the optional parts, it becomes
+    a bit clearer:
+
+    : $ gpg [--armor] [--recipient alice] [--output secret.txt] --encrypt test.txt
+
+    The optional parts can be rearranged any way you want:
+
+    : $ gpg --output secret.txt --recipient alice --armor --encrypt test.txt
+
+    If your filename begins with a hyphen (e.g. "-a.txt"), GnuPG assumes
+    this is an option and may complain. To avoid this you have to either
+    use =./-a.txt=, or stop the option and command processing with two
+    hyphens: =-- -a.txt=.
+
+    *The exception to using only one command*: signing and encrypting
+    at the same time. For this you can combine both commands, such as in:
+
+    : $ gpg [--options] --sign --encrypt foo.txt
+
+** I can't delete a user ID on my secret keyring because it has already been deleted on my public keyring. What can I do?
+   :PROPERTIES:
+   :CUSTOM_ID: delete-user-id-from-secring-if-already-deleted-from-pubring
+   :END:
+
+    Because you can only select from the public key ring, there is no
+    direct way to do this. However it is not very complicated to do
+    anyway. Create a new user ID with exactly the same name and you
+    will see that there are now two identical user IDs on the secret
+    ring. Now select this user ID and delete it. Both user IDs will be
+    removed from the secret ring.
+
+** I can't delete my secret key because the public key disappeared.  What can I do?
+   :PROPERTIES:
+   :CUSTOM_ID: delete-my-secret-key-because-the-public-key-disappeared
+   :END:
+
+    To select a key a search is always done on the public keyring,
+    therefore it is not possible to select a secret key without
+    having the public key. Normally it should never happen that the
+    public key got lost but the secret key is still available. The
+    reality is different, so GnuPG implements a special way to deal
+    with it: Simply use the long keyID to specify the key to delete,
+    which can be obtained by using the --with-colons options (it is
+    the fifth field in the lines beginning with "sec").
+
+    If you've lost your public key and need to recreate it instead
+    for continued use with your secret key, you may be able to use
+    gpgsplit as detailed in question
+    [[#i-still-have-my-secret-key-but-lost-my-public-key][I still have my secret key, but lost my public key. What can I do?]].
+
+
+
+** What are trust, validity and ownertrust?
+   :PROPERTIES:
+   :CUSTOM_ID: what-are-trust-validity-and-ownertrust
+   :END:
+
+    With GnuPG, the term "ownertrust" is used instead of "trust" to
+    help clarify that this is the value you have assigned to a key
+    to express how much you trust the owner of this key to correctly
+    sign (and thereby introduce) other keys. The "validity", or
+    calculated trust, is a value which indicates how much GnuPG
+    considers a key as being valid (that it really belongs to the
+    one who claims to be the owner of the key). For more information
+    on trust values see the chapter "The Web of Trust" in The GNU
+    Privacy Handbook.
+
+** How do I sign a patch file?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-sign-a-patch-file
+   :END:
+
+    Use "gpg --clearsign --not-dash-escaped ...". The problem with
+    --clearsign is that all lines starting with a dash are quoted with
+    "- "; obviously diff produces many lines starting with a dash and
+    these are then quoted and that is not good for a patch ;-). To use
+    a patch file without removing the cleartext signature, the special
+    option --not-dash-escaped may be used to suppress generation of
+    these escape sequences. You should not mail such a patch because
+    spaces and line endings are also subject to the signature and a
+    mailer may not preserve these. If you want to mail a file you can
+    simply sign it using your MUA (Mail User Agent).
+
+** Where is the "encrypt-to-self" option?
+   :PROPERTIES:
+   :CUSTOM_ID: where-is-the-encrypt-to-self-option
+   :END:
+
+    Use "--encrypt-to your_keyID". You can use more than one of these
+    options. To temporarily override the use of this additional key,
+    you can use the option "--no-encrypt-to".
+
+** How can I get rid of the Version and Comment headers in armored messages?
+   :PROPERTIES:
+   :CUSTOM_ID: get-rid-of-the-version-and-comment-headers-in-armored-messages
+   :END:
+
+    Use
+
+    : --no-version --comment ''
+
+    Note that the left over blank line
+    is required by the protocol.
+
+** What does the "You are using the xxxx character set." mean?
+   :PROPERTIES:
+   :CUSTOM_ID: what-does-the-you-are-using-the-xxx-character-set-mean
+   :END:
+
+   This note is printed when UTF-8 mapping has to be done. Make sure
+   that the displayed character set is the one you have activated on
+   your system. Since "iso-8859-1" is the character set most used,
+   this is the default. You can change the charset with the option
+   =--charset=. It is important that your active character set matches
+   the one displayed --- if not, restrict yourself to plain 7 bit
+   ASCII and no mapping has to be done.
+
+** How can I get list of key IDs used to encrypt a message?
+   :PROPERTIES:
+   :CUSTOM_ID: how-can-i-get-list-of-key-ids-used-to-encrypt-a-message
+   :END:
+
+   : $ gpg --batch --decrypt --list-only --status-fd 1 2>/dev/null | \
+   :   awk '/^\[GNUPG:\] ENC_TO / { print $3 }'
+
+** Why can't I decrypt files encrypted as symmetrical-only (-c) with a version of GnuPG prior to 1.0.1.
+   :PROPERTIES:
+   :CUSTOM_ID: why-cant-i-decrypt-symmetrical-only-with-gnupg-prior-to-1.0.1
+   :END:
+
+   There was a bug in GnuPG versions prior to 1.0.1 which affected files
+   only if 3DES or Twofish was used for symmetric-only encryption (this has
+   never been the default). The bug has been fixed, but to enable decryption
+   of old files you should run gpg with the option =--emulate-3des-s2k-bug=,
+   decrypt the file and encrypt it again without this option.
+
+   NOTE: This option was removed in GnuPG development version 1.1.0 and later
+   updates, so you will need to use a version between 1.0.1 and 1.0.7 to
+   re-encrypt any affected files.
+
+** How can I use GnuPG in an automated environment?
+   :PROPERTIES:
+   :CUSTOM_ID: how-can-i-use-gnupg-in-an-automated-environment
+   :END:
+
+   You should use the option =--batch= and don't use passphrases as
+   there is usually no way to store it more securely than on the
+   secret keyring itself. The suggested way to create keys for an
+   automated environment is:
+
+   On a secure machine:
+
+   1. If you want to do automatic signing, create a signing subkey for
+      your key.  Use the interactive key editing menu by issueing the
+      command
+      : gpg --edit-key keyID
+      enter "addkey" and select the DSA key type).
+
+   1. Make sure that you use a passphrase (needed by the current
+      implementation).
+
+   1.
+      :  gpg --export-secret-subkeys --no-comment foo >secring.auto
+
+   1. Copy secring.auto and the public keyring to a test directory.
+
+   1. Change to this directory.
+
+   1. Run the command
+      : gpg --homedir . --edit foo
+
+     and use the sub-command =passwd= to remove the passphrase from the
+     subkeys. You may also want to remove all unused subkeys.
+
+   1. Copy secring.auto to a floppy and carry it to the target box.
+
+   On the target machine:
+
+   1. Install secring.auto as the secret keyring.
+   1. Now you can start your new service. It's also a good idea to
+      install an intrusion detection system so that you hopefully get
+      a notice of an successful intrusion, so that you in turn can
+      revoke all the subkeys installed on that machine and install new
+      subkeys.
+
+** Which email-client can I use with GnuPG?
+   :PROPERTIES:
+   :CUSTOM_ID: which-email-client-can-i-use-with-gnupg
+   :END:
+
+    Using GnuPG to encrypt email is one of the most popular uses.
+    Several mail clients or mail user agents (MUAs) support GnuPG to
+    varying degrees. Simplifying a bit, there are two ways mail can be
+    encrypted with GnuPG: the "old style" ASCII armor (i.e. cleartext
+    encryption), and RFC 2015 style (previously PGP/MIME, now OpenPGP).
+    The latter has full MIME support. Some MUAs support only one of
+    them, so whichever you actually use depends on your needs as well
+    as the capabilities of your addressee. As well, support may be
+    native to the MUA, or provided via "plug-ins" or external tools.
+
+    The following list is not exhaustive:
+
+    | MUA             | OpenPGP | ASCII | How? (N,P,T)         |
+    |-----------------+---------+-------+----------------------|
+    | Calypso         | N       | Y     | P (Unixmail)         |
+    | Elm             | N       | Y     | T (mailpgp,morepgp)  |
+    | Elm ME+         | N       | Y     | N                    |
+    | Emacs/Gnus      | Y       | Y     | T (Mailcrypt,gpg.el) |
+    | Emacs/Mew       | Y       | Y     | N                    |
+    | Emacs/VM        | N       | Y     | T (Mailcrypt)        |
+    | Evolution       | Y       | Y     | N                    |
+    | Exmh            | Y       | Y     | N                    |
+    | GNUMail.app     | Y       | Y     | P (PGPBundle)        |
+    | GPGMail         | Y       | Y     | N                    |
+    | KMail (<=1.4.x) | N       | Y     | N                    |
+    | KMail (1.5.x)   | Y(P)    | Y(N)  | P/N                  |
+    | Mozilla         | Y       | Y     | P (Enigmail)         |
+    | Mulberry        | Y       | Y     | P                    |
+    | Mutt            | Y       | Y     | N                    |
+    | Sylpheed        | Y       | Y     | N                    |
+    | Claws-mail      | Y       | Y     | N                    |
+    | TkRat           | Y       | Y     | N                    |
+    | XEmacs/Gnus     | Y       | Y     | T (Mailcrypt)        |
+    | XEmacs/Mew      | Y       | Y     | N                    |
+    | XEmacs/VM       | N       | Y     | T (Mailcrypt)        |
+    | XFmail          | Y       | Y     | N                    |
+
+    ( N - Native, P - Plug-in, T - External Tool)
+
+    The following table lists proprietary MUAs. The GNU Project
+    suggests against the use of these programs, but they are listed
+    for interoperability reasons for your convenience.
+
+    | MUA              | OpenPGP | ASCII | How? (N,P,T)             |
+    |------------------+---------+-------+--------------------------|
+    | Apple Mail       | Y       | Y     | P (GPGMail)              |
+    | Becky2           | Y       | Y     | P (BkGnuPG)              |
+    | Eudora           | Y       | Y     | P (EuroraGPG)            |
+    | Eudora Pro       | Y       | Y     | P (EudoraGPG)            |
+    | Lotus Notes      | N       | Y     | P                        |
+    | Netscape 4.x     | N       | Y     | P                        |
+    | Netscape 7.x     | Y       | Y     | P (Enigmail)             |
+    | Novell Groupwise | N       | Y     | P                        |
+    | Outlook          | N       | Y     | P (G-Data)               |
+    | Outlook Express  | N       | Y     | P (GPGOE)                |
+    | Pegasus          | N       | Y     | P (QDPGP,PM-PGP)         |
+    | Pine             | N       | Y     | T (pgpenvelope,gpg4pine) |
+    | Postme           | N       | Y     | P (GPGPPL)               |
+    | The Bat!         | N       | Y     | P (Ritlabs)              |
+
+    Good overviews of OpenPGP-support can be found at:\\
+    [[http://www.openpgp.fr.st/courrier_en.html]] \\
+    http://www.bretschneidernet.de/tips/secmua.html
+
+    Users of Win32 MUAs that lack OpenPGP support may look into using
+    GPGrelay http://gpgrelay.sourceforge.net, a small email-relaying
+    server that uses GnuPG to enable many email clients to send and
+    receive emails that conform to PGP-MIME (RFC 2015).
+
+** Can't we have a gpg library?
+   :PROPERTIES:
+   :CUSTOM_ID: cant-we-have-a-gpg-library
+   :END:
+
+    This has been frequently requested. However, the current viewpoint
+    of the GnuPG maintainers is that this would lead to several security
+    issues and will therefore not be implemented in the foreseeable
+    future. However, for some areas of application gpgme could do the
+    trick. You'll find it at [[gnupgweb:related_software/gpgme]].
+
+** I have successfully generated a revocation certificate, but I don't understand how to send it to the key servers.
+   :PROPERTIES:
+   :CUSTOM_ID: how-to-send-a-revocation-to-the-keyservers
+   :END:
+
+   Most keyservers don't accept a 'bare' revocation certificate. You
+   have to import the certificate into gpg first:
+
+   : $ gpg --import my-revocation.asc
+
+   then send the revoked key to the keyservers:
+
+   : $ gpg --keyserver certserver.pgp.com --send-keys mykeyid
+
+   (or use a keyserver web interface for this).
+
+** How do I put my keyring in a different directory?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-put-my-keyring-in-a-different-directory
+   :END:
+
+   GnuPG keeps several files in a special homedir directory. These
+   include the options file, pubring.gpg, secring.gpg, trustdb.gpg,
+   and others. GnuPG will always create and use these files. On
+   unices, the homedir is usually ~/.gnupg; on Windows it is name
+   "gnupg" and found below the user's application directory.  Run the
+   gpg and pass the option --version to see the name of that
+   directory.
+
+   If you want to put your keyrings somewhere else, use the option:
+
+   : --homedir /my/path/
+
+   to make GnuPG create all its files in that directory. Your keyring
+   will be "/my/path/pubring.gpg". This way you can store your secrets
+   on a floppy disk. Don't use "--keyring" as its purpose is to specify
+   additional keyring files.
+
+** How do I verify signed packages?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-verify-signed-packages
+   :END:
+
+   must first have the vendor, organisation, or issueing person's key
+   Before you can verify the signature that accompanies a package, you
+   imported into your public keyring. To prevent GnuPG warning
+   messages the key should also be validated (or locally signed).
+
+    You will also need to download the detached signature file along
+    with the package. These files will usually have the same name as
+    the package, with either a binary (.sig) or ASCII armor (.asc)
+    extension.
+
+    Once their key has been imported, and the package and accompanying
+    signature files have been downloaded, use:
+
+    : $ gpg --verify sigfile signed-file
+
+    If the signature file has the same base name as the package file,
+    the package can also be verified by specifying just the signature
+    file, as GnuPG will derive the package's file name from the name
+    given (less the .sig or .asc extension). For example, to verify a
+    package named foobar.tar.gz against its detached binary signature
+    file, use:
+
+    : $ gpg --verify foobar.tar.gz.sig
+
+** How do I export a keyring with only selected signatures (keys)?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-export-a-keyring-with-only-selected-signatures
+   :END:
+
+    If you're wanting to create a keyring with only a subset of keys
+    selected from a master keyring (for a club, user group, or company
+    department for example), simply specify the keys you want to export:
+
+    : $ gpg --armor --export key1 key2 key3 key4 > keys1-4.asc
+
+** I still have my secret key, but lost my public key. What can I do?
+   :PROPERTIES:
+   :CUSTOM_ID: i-still-have-my-secret-key-but-lost-my-public-key
+   :END:
+
+    All OpenPGP secret keys have a copy of the public key inside them,
+    and in a worst-case scenario, you can create yourself a new public
+    key using the secret key.
+
+    A tool to convert a secret key into a public one has been included
+    (it's actually a new option for gpgsplit) and is available with GnuPG
+    versions 1.2.1 or later (or can be found in CVS). It works like this:
+
+    : $ gpgsplit --no-split --secret-to-public secret.gpg >publickey.gpg
+
+    One should first try to export the secret key and convert just this
+    one. Using the entire secret keyring should work too. After this has
+    been done, the publickey.gpg file can be imported into GnuPG as usual.
+
+** Clearsigned messages sent from my web-mail account have an invalid signature. Why?
+   :PROPERTIES:
+   :CUSTOM_ID: clearsig-sent-from-webmail-have-an-invalid-signature
+   :END:
+
+    Check to make sure the settings for your web-based email account
+    do not use HTML formatting for the pasted clearsigned message. This can
+    alter the message with embedded HTML markup tags or spaces, resulting
+    in an invalid signature. The recipient may be able to copy the signed
+    message block to a text file for verification, or the web email
+    service may allow you to attach the clearsigned message as a file
+    if plaintext messages are not an option.
+
+
+* Compatibility Issues
+
+** How can I encrypt a message with GnuPG so that PGP is able to decrypt it?
+   :PROPERTIES:
+   :CUSTOM_ID: how-can-i-encrypt-a-message-so-that-pgp-is-able-to-decrypt-it
+   :END:
+
+    It depends on the PGP version.
+
+    - PGP 2.x ::
+
+      You can't do that because PGP 2.x normally uses IDEA which is
+      not supported by GnuPG as it is patented (see [[#how-do-i-include-support-for-rsa-and-idea][How do I include
+      support for RSA and IDEA?]]), but if you have a modified version
+      of PGP you can try this:
+
+      : $ gpg --rfc1991 --cipher-algo 3des ...
+
+      Please don't pipe the data to encrypt to gpg but provide it
+      using a filename; otherwise, PGP 2 will not be able to handle
+      it.
+
+      As for conventional encryption, you can't do this for PGP 2.
+
+    - PGP 5.x and higher ::
+
+      You need to provide two additional options:
+
+      : --compress-algo 1 --cipher-algo cast5
+
+      You may also use "3des" instead of "cast5", and "blowfish" does
+      not work with all versions of PGP 5. You may also want to put:
+
+      : compress-algo 1
+
+      into your =~/.gnupg/options= file --- this does not affect
+      normal GnuPG operation.
+
+    This applies to conventional encryption as well.
+
+** How do I migrate from PGP 2.x to GnuPG?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-migrate-from-pgp2-to-gnupg
+   :END:
+
+    PGP 2 uses the RSA and IDEA encryption algorithms. Whereas the RSA
+    patent has expired and RSA is included as of GnuPG 1.0.3, the IDEA
+    algorithm is still patented until 2007. Under certain conditions you
+    may use IDEA even today. In that case, you may refer to Question
+    [[*How%20do%20I%20include%20support%20for%20RSA%20and%20IDEA][How do I include support for RSA and IDEA?]] about how to add
+    IDEA support to GnuPG and read
+    [[gnupgweb:gph/en/pgp2x.html]] to perform the migration.
+
+** Why is PGP 5.x not able to encrypt messages with some keys?
+   :PROPERTIES:
+   :CUSTOM_ID: why-is-pgp5-not-able-to-encrypt-messages-with-some-keys
+   :END:
+
+    PGP, Inc. refuses to accept Elgamal keys of type 20 even for
+    encryption. They only support type 16 (which is identical at least
+    for decryption). To be more inter-operable, GnuPG (starting with
+    version 0.3.3) now also uses type 16 for the Elgamal subkey which is
+    created if the default key algorithm is chosen. You may add a type
+    16 Elgamal key to your public key, which is easy as your key
+    signatures are still valid.
+
+** Why is PGP 5.x not able to verify my messages?
+   :PROPERTIES:
+   :CUSTOM_ID: why-is-pgp5-not-able-to-verify-my-messages
+   :END:
+
+    PGP 5.x does not accept v4 signatures for data material but OpenPGP
+    requests generation of v4 signatures for all kind of data, that's why
+    GnuPG defaults to them. Use the option "--force-v3-sigs" to generate
+    v3 signatures for data.
+
+** How do I transfer owner trust values from PGP to GnuPG?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-transfer-owner-trust-values-from-pgp-to-gnupg
+   :END:
+
+    There is a script in the tools directory to help you. After you have
+    imported the PGP keyring you can give this command:
+
+    : $ lspgpot pgpkeyring | gpg --import-ownertrust
+
+    where pgpkeyring is the original keyring and not the GnuPG keyring
+    you might have created in the first step.
+
+** PGP does not like my secret key.
+   :PROPERTIES:
+   :CUSTOM_ID: pgp-does-not-like-my-secret-key
+   :END:
+
+    Older PGPs probably bail out on some private comment packets used by
+    GnuPG. These packets are fully in compliance with OpenPGP; however
+    PGP is not really OpenPGP aware. A workaround is to export the
+    secret keys with this command:
+
+    : $ gpg --export-secret-keys --no-comment -a your-KeyID
+
+    Another possibility is this: by default, GnuPG encrypts your secret
+    key using the Blowfish symmetric algorithm. Older PGPs will only
+    understand 3DES, CAST5, or IDEA symmetric algorithms. Using the
+    following method you can re-encrypt your secret gpg key with a
+    different algo:
+
+    : $ gpg --s2k-cipher-algo=CAST5 --s2k-digest-algo=SHA1 \
+    :       --compress-algo=1  --edit-key <username>
+
+    Then use passwd to change the password (just change it to the same
+    thing, but it will encrypt the key with CAST5 this time).
+
+    Now you can export it and PGP should be able to handle it.
+
+    For PGP 6.x the following options work to export a key:
+
+    : $ gpg --s2k-cipher-algo 3des --compress-algo 1 --rfc1991 \
+    :       --export-secret-keys <KeyID>
+
+** GnuPG no longer installs a ~/.gnupg/options file. Is it missing?
+   :PROPERTIES:
+   :CUSTOM_ID: gnupg-no-longer-installs-a-options-file-is-it-missing
+   :END:
+
+    No. The ~/.gnupg/options file has been renamed to
+    ~/.gnupg/gpg.conf for new installs as of version 1.1.92. If an
+    existing ~/.gnupg/options file is found during an upgrade it will
+    still be used, but this change was required to have a more
+    consistent naming scheme with forthcoming tools.  An existing
+    options file can be renamed to gpg.conf for users upgrading, or
+    receiving the message that the "old default options file" is
+    ignored (occurs if both a gpg.conf and an options file are found).
+
+** How do you export GnuPG keys for use with PGP?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-you-export-gnupg-keys-for-use-with-pgp
+   :END:
+
+    This has come up fairly often, so here's the HOWTO:
+
+    PGP can (for most key types) use secret keys generated by GnuPG. The
+    problems that come up occasionally are generally because GnuPG
+    supports a few more features from the OpenPGP standard than PGP does.
+    If your secret key has any of those features in use, then PGP will
+    reject the key or you will have problems communicating later. Note
+    that PGP doesn't do Elgamal signing keys at all, so they are not
+    usable with any version.
+
+    These instructions should work for GnuPG 1.0.7 and later, and PGP
+    7.0.3 and later.
+
+    Start by editing the key. Most of this line is not really necessary
+    as the default values are correct, but it does not hurt to repeat the
+    values, as this will override them in case you have something else set
+    in your options file.
+
+    : $ gpg --s2k-cipher-algo cast5 --s2k-digest-algo sha1 --s2k-mode 3 \
+    :       --simple-sk-checksum --edit KeyID
+
+    Turn off some features. Set the list of preferred ciphers, hashes,
+    and compression algorithms to things that PGP can handle. (Yes, I
+    know this is an odd list of ciphers, but this is what PGP itself uses,
+    minus IDEA).
+
+    : > setpref S9 S8 S7 S3 S2 S10 H2 H3 Z1 Z0
+
+    Now put the list of preferences onto the key.
+
+    : > updpref
+
+    Finally we must decrypt and re-encrypt the key, making sure that we
+    encrypt with a cipher that PGP likes. We set this up in the --edit
+    line above, so now we just need to change the passphrase to make it
+    take effect. You can use the same passphrase if you like, or take
+    this opportunity to actually change it.
+
+    : > passwd
+
+    Save our work.
+
+    : > save
+
+    Now we can do the usual export:
+
+    : $ gpg --export KeyID > mypublickey.pgp[H br]
+    : $ gpg --export-secret-key KeyID > mysecretkey.pgp
+
+    Thanks to David Shaw for this information!
+
+** What are DH/DSS keys?
+   :PROPERTIES:
+   :CUSTOM_ID: what-are-dh-dss-keys
+   :END:
+
+   PGP uses a different name for the former default encryption
+   algorithm Elgamal: They name it DH, which usually stands for the
+   Diffie-Hellman key exchange algorithm.  It has been said that this
+   had historic patent and business reasons.  It is however exactly
+   the same thing as the Elgamal algorithm.
+
+   They also use the acronym DSS (Digital Signature Standard) instead
+   of the DSA (Digital Signature Algorithm).  The difference is that
+   DSS requires the use of certain hash algorithms; however OpenPGP
+   allows the use of more than those hash algorithms, thus GPG usually
+   uses the term DSA.
+
+* Problems and Error Messages
+
+** Why do I get "gpg: Warning: using insecure memory!"
+   :PROPERTIES:
+   :CUSTOM_ID: why-do-i-get-gpg_warning_using_insecure_memory
+   :END:
+
+   You see this warning if GPG is not able to lock pages against being
+   swapped out to disk.
+
+   However, on most modern system you should not see this message
+   anymore because these systems allow any process to prevent a small
+   number of memory pages from being swapped out to disk (using the
+   mlock system call).  Other (mostly older) systems don't allow this
+   unless you install GPG as setuid(root).
+
+   Locking pages against being swapped out is not necessary if your
+   system uses an encrypted swap partition.  In fact that is the best
+   way to protect sensitive data from ending up on a disk.  If your
+   system allows for encrypted swap partitions, please make use of
+   that feature.  Note that GPG does not know about encrypted swap
+   partitions and might print the warning; thus you should disabled
+   the warning if your swap partition is encrypted.  You may also want
+   to disable this warning if you can't or don't want to install GnuPG
+   setuid(root).  To disable the warning you put a line
+
+   : no-secmem-warning
+
+   into your ~/.gnupg/gpg.conf file.
+
+   What follows is a short description on how to install GPG
+   setuid(root); for those who need this.
+
+   On some systems this program should be installed as setuid(root).
+   This is necessary to lock memory pages. Locking memory pages
+   prevents the operating system from writing them to disk and thereby
+   keeping your secret keys really secret. If you get no warning
+   message about insecure memory your operating system supports
+   locking without being root. The program drops root privileges as
+   soon as locked memory is allocated.
+
+   To setuid(root) permissions on the gpg binary you can either use:
+
+   : $ chmod u+s /path/to/gpg
+
+   or
+
+   : $ chmod 4755 /path/to/gpg
+
+   Some refrain from using setuid(root) unless absolutely required for
+   security reasons. Please check with your system administrator if
+   you are not able to make these determinations yourself.
+
+   On UnixWare 2.x and 7.x you should install GnuPG with the 'plock'
+   privilege to get the same effect:
+
+   : $ filepriv -f plock /path/to/gpg
+
+   On some systems (e.g., Windows) GnuPG does not lock memory pages
+   and older GnuPG versions (<=1.0.4) issue the warning:
+
+   : gpg: Please note that you don't have secure memory
+
+   This warning can't be switched off by the above option because it
+   was thought to be too serious an issue. However, it confused users
+   too much, so the warning was eventually removed.
+
+** Large File Support doesn't work
+   :PROPERTIES:
+   :CUSTOM_ID: large-file-support-does-not-work
+   :END:
+
+   LFS works correctly in post-1.0.4 versions. If configure doesn't
+   detect it, try a different (i.e., better) compiler. egcs 1.1.2
+   works fine, other gccs sometimes don't. BTW, several compilation
+   problems of GnuPG 1.0.3 and 1.0.4 on HP-UX and Solaris were due to
+   broken LFS support.
+
+** In the edit menu the trust values are not displayed correctly after signing uids. Why?
+   :PROPERTIES:
+   :CUSTOM_ID: edit-menu-trust-not-show-correctly-after-signing-uids
+   :END:
+
+    This happens because some information is stored immediately in
+    the trustdb, but the actual trust calculation can be done after the
+    save command. This is a "not easy to fix" design bug which will be
+    addressed in some future release.
+
+** What does "skipping pubkey 1: already loaded" mean?
+   :PROPERTIES:
+   :CUSTOM_ID: what-does-skipping_pubkey_1_already_loaded-mean
+   :END:
+
+    As of GnuPG 1.0.3, the RSA algorithm is included. If you still have
+    a "load-extension rsa" in your options file, the above message
+    occurs. Just remove the load command from the options file.
+
+** GnuPG 1.0.4 doesn't create ~/.gnupg ...
+   :PROPERTIES:
+   :CUSTOM_ID: gnupg-1.0.4-does-not-create-.gnupg
+   :END:
+
+    That's a known bug, already fixed in newer versions.
+
+** An Elgamal signature does not verify anymore since version 1.0.2
+   :PROPERTIES:
+   :CUSTOM_ID: an-elgamal-signature-does-not-verify-anymore-since-version-1.0.2
+   :END:
+
+    Use the option --emulate-md-encode-bug.
+
+** Old versions of GnuPG can't verify Elgamal signatures
+   :PROPERTIES:
+   :CUSTOM_ID: old-versions-of-gnupg-cant-verify-elgamal-signatures
+   :END:
+
+    Update to GnuPG 1.0.2 or newer.
+
+** When I use --clearsign, the plain text has sometimes extra dashes in it - why?
+   :PROPERTIES:
+   :CUSTOM_ID: extra-dashes-in-clearsign-messages
+   :END:
+
+    This is called dash-escaped text and is required by OpenPGP.
+    It always happens when a line starts with a dash ("-") and is
+    needed to make the lines that structure signature and text
+    (i.e., "-----BEGIN PGP SIGNATURE-----") to be the only lines
+    that start with two dashes.
+
+    If you use GnuPG to process those messages, the extra dashes
+    are removed. Good mail clients remove those extra dashes when
+    displaying such a message.
+
+** What is the thing with "can't handle multiple signatures"?
+   :PROPERTIES:
+   :CUSTOM_ID: what-is-the-thing-with-cant_handle_multiple_signatures
+   :END:
+
+    Due to different message formats GnuPG is not always able to split
+    a file with multiple signatures unambiguously into its parts. This
+    error message informs you that there is something wrong with the input.
+
+    The only way to have multiple signatures in a file is by using the
+    OpenPGP format with one-pass-signature packets (which is GnuPG's
+    default) or the cleartext signed format.
+
+** If I submit a key to a keyserver, nothing happens
+   :PROPERTIES:
+   :CUSTOM_ID: if-i-submit-a-key-to-a-keyserver-nothing-happens
+   :END:
+
+    You are most likely using GnuPG 1.0.2 or older on Windows. That's
+    feature isn't yet implemented, but it's a bug not to say it. Newer
+    versions issue a warning. Upgrade to 1.4.5 or newer.
+
+** I get "gpg: waiting for lock ..."
+   :PROPERTIES:
+   :CUSTOM_ID: i-get-gpg_waiting_for_lock
+   :END:
+
+    A previous instance of gpg has most likely exited abnormally and left
+    a lock file. Go to ~/.gnupg and look for .*.lock files and remove them.
+
+** Older gpg binaries (e.g., 1.0) have problems with keys from newer gpg binaries
+   :PROPERTIES:
+   :CUSTOM_ID: gpg-1.0-has-problems-with-keys-from-newer-gpg-versions
+   :END:
+
+    As of 1.0.3, keys generated with gpg are created with preferences to
+    TWOFISH (and AES since 1.0.4) and that also means that they have the
+    capability to use the new MDC encryption method. This will go into
+    OpenPGP soon, and is also suppoted by PGP 7. This new method avoids
+    a (not so new) attack on all email encryption systems.
+
+    This in turn means that pre-1.0.3 gpg binaries have problems with
+    newer keys. Because of security and bug fixes, you should keep your
+    GnuPG installation in a recent state anyway. As a workaround, you can
+    force gpg to use a previous default cipher algo by putting:
+
+    : cipher-algo cast5
+
+    into your options file.
+
+** With 1.0.4, I get "this cipher algorithm is deprecated ..."
+   :PROPERTIES:
+   :CUSTOM_ID: with-1.0.4-i-get-this_cipher_algorithm_is_deprecated
+   :END:
+
+    If you just generated a new key and get this message while
+    encrypting, you've witnessed a bug in 1.0.4. It uses the new AES
+    cipher Rijndael that is incorrectly being referred as "deprecated".
+    Ignore this warning, more recent versions of gpg are corrected.
+
+** Some dates are displayed as ????-??-??. Why?
+   :PROPERTIES:
+   :CUSTOM_ID: some-dates-are-displayed-as-question-marks
+   :END:
+
+    Due to constraints in most libc implementations, dates beyond
+    2038-01-19 can't be displayed correctly. 64-bit OSes are not
+    affected by this problem. To avoid printing wrong dates, GnuPG
+    instead prints some question marks. To see the correct value, you
+    can use the options --with-colons and --fixed-list-mode.
+
+** I still have a problem. How do I report a bug?
+   :PROPERTIES:
+   :CUSTOM_ID: i-still-have-a-problem-how-do-i-report-a-bug
+   :END:
+
+    Are you sure that it's not been mentioned somewhere on the mailing
+    lists? Did you have a look at the bug list (you'll find a link to
+    the list of reported bugs on the documentation page). If you're
+    not sure about it being a bug, you can send mail to the
+    gnupg-devel list. Otherwise, use the bug tracking system
+    [[http://bugs.gnupg.org][bugs.gnupg.org]].
+
+** Why doesn't GnuPG support X.509 certificates?
+   :PROPERTIES:
+   :CUSTOM_ID: why-doesnt-gnupg-support-x509-certificates
+   :END:
+
+    That is only the case for GnuPG version 1.x.  GnuPG 2.x fully
+    supports X.509 and S/MIME using the gpgsm tool.
+
+** Why do national characters in my user ID look funny?
+   :PROPERTIES:
+   :CUSTOM_ID: why-do-national-characters-in-my-user-id-look-funny
+   :END:
+
+    According to OpenPGP, GnuPG encodes user ID strings (and other
+    things) using UTF-8. In this encoding of Unicode, most national
+    characters get encoded as two- or three-byte sequences. For
+    example, &aring; (0xE5 in ISO-8859-1) becomes &Atilde;&yen; (0xC3,
+    0xA5). This might also be the reason why keyservers can't find
+    your key.
+
+** I get 'sed' errors when running ./configure on Mac OS X ...
+   :PROPERTIES:
+   :CUSTOM_ID: i-get-sed-errors-when-running-configure-on-mac-os-x
+   :END:
+
+    This problem has been fixed for all modern GnuPG versions.
+    (By using an autoconf 2.50 generated configure script).
+
+** Why does GnuPG 1.0.6 bail out on keyrings used with 1.0.7?
+   :PROPERTIES:
+   :CUSTOM_ID: why-does-gnupg-1.0.6-bail-out-on-keyrings-used-with-1.0.7
+   :END:
+
+    There is a small bug in 1.0.6 which didn't parse trust packets
+    correctly. You may want to apply this patch if you can't upgrade:
+    [[http://www.gnupg.org/developer/gpg-woody-fix.txt]].
+
+** I upgraded to GnuPG version 1.0.7 and now it takes longer to load my keyrings. What can I do?
+   :PROPERTIES:
+   :CUSTOM_ID: with-gpg-1.0.7-it-takes-longer-to-load-my-keyrings
+   :END:
+
+    The way signature states are stored has changed so that v3 signatures
+    can be supported. You can use the new --rebuild-keydb-caches migration
+    command, which was built into this release and increases the speed of
+    many operations for existing keyrings.
+
+** Doesn't a fully trusted user ID on a key prevent warning messages when encrypting to other IDs on the key?
+   :PROPERTIES:
+   :CUSTOM_ID: key-validation-bug-in-gpg-1.2.1
+   :END:
+
+    No. That was actually a key validity bug in GnuPG 1.2.1 and earlier
+    versions. As part of the development of GnuPG 1.2.2, a bug was
+    discovered in the key validation code.  This bug causes keys with
+    more than one user ID to give all user IDs on the key the amount of
+    validity given to the most-valid key. The bug has been fixed in GnuPG
+    release 1.2.2, and upgrading is the recommended fix for this problem.
+    More information and a patch for a some pre-1.2.2 versions of GnuPG
+    can be found at:
+
+    [[http://lists.gnupg.org/pipermail/gnupg-announce/2003q2/000268.html]].
+
+** I just compiled GnuPG from source on my GNU/Linux RPM-based system and it's not working. Why?
+   :PROPERTIES:
+   :CUSTOM_ID: compiled-on-gnu-linux-rpm-based-system-and-not-working
+   :END:
+
+    Many GNU/Linux distributions that are RPM-based will install a
+    version of GnuPG as part of its standard installation, placing the
+    binaries in the /usr/bin directory. Later, compiling and installing
+    GnuPG from source other than from a source RPM won't normally
+    overwrite these files, as the default location for placement of
+    GnuPG binaries is in /usr/local/bin unless the '--prefix' switch
+    is used during compile to specify an alternate location. Since the
+    /usr/bin directory more than likely appears in your path before
+    /usr/local/bin, the older RPM-version binaries will continue to
+    be used when called since they were not replaced.
+
+    To resolve this, uninstall the RPM-based version with 'rpm -e gnupg'
+    before installing the binaries compiled from source. If dependency
+    errors are displayed when attempting to uninstall the RPM (such as
+    when Red Hat's up2date is also installed, which uses GnuPG), uninstall
+    the RPM with 'rpm -e gnupg --nodeps' to force the uninstall. Any
+    dependent files should be automatically replaced during the install
+    of the compiled version. If the default /usr/local/bin directory is
+    used, some packages such as SuSE's Yast Online Update may need to be
+    configured to look for GnuPG binaries in the /usr/local/bin directory,
+    or symlinks can be created in /usr/bin that point to the binaries
+    located in /usr/local/bin.
+
+
+* Advanced Topics
+
+** How does this whole thing work?
+   :PROPERTIES:
+   :CUSTOM_ID: how-does-this-whole-thing-work
+   :END:
+
+    To generate a secret/public keypair, run:
+
+    : $ gpg --gen-key
+
+    and choose the default values.
+
+    Data that is encrypted with a public key can only be decrypted by
+    the matching secret key. The secret key is protected by a password,
+    the public key is not.
+
+    So to send your friend a message, you would encrypt your message
+    with his public key, and he would only be able to decrypt it by
+    having the secret key and putting in the password to use his secret
+    key.
+
+    GnuPG is also useful for signing things. Files that are encrypted
+    with the secret key can be decrypted with the public key. To sign
+    something, a hash is taken of the data, and then the hash is in some
+    form encoded with the secret key. If someone has your public key, they
+    can verify that it is from you and that it hasn't changed by checking
+    the encoded form of the hash with the public key.
+
+    A keyring is just a large file that stores keys. You have a public
+    keyring where you store yours and your friend's public keys. You have
+    a secret keyring that you keep your secret key on, and should be very
+    careful with. Never ever give anyone else access to it and use a *good*
+    passphrase to protect the data in it.
+
+    You can 'conventionally' encrypt something by using the option 'gpg -c'.
+    It is encrypted using a passphrase, and does not use public and secret
+    keys. If the person you send the data to knows that passphrase, they
+    can decrypt it. This is usually most useful for encrypting things to
+    yourself, although you can encrypt things to your own public key in the
+    same way. It should be used for communication with partners you know
+    and where it is easy to exchange the passphrases (e.g. with your boy
+    friend or your wife). The advantage is that you can change the
+    passphrase from time to time and decrease the risk, that many old
+    messages may be decrypted by people who accidently got your passphrase.
+
+    You can add and copy keys to and from your keyring with the 'gpg
+    --import' and 'gpg --export' command. 'gpg --export-secret-keys' will
+    export secret keys. This is normally not useful, but you can generate
+    the key on one machine then move it to another machine.
+
+    Keys can be signed under the 'gpg --edit-key' option. When you sign a
+    key, you are saying that you are certain that the key belongs to the
+    person it says it comes from. You should be very sure that is really
+    that person: You should verify the key fingerprint with:
+
+    : $ gpg --fingerprint KeyID
+
+    over the phone (if you really know the voice of the other person), at
+    a key signing party (which are often held at computer conferences),
+    or at a meeting of your local GNU/Linux User Group.
+
+    Hmm, what else. You may use the option '-o filename' to force output
+    to this filename (use '-' to force output to stdout). '-r' just lets
+    you specify the recipient (which public key you encrypt with) on the
+    command line instead of typing it interactively.
+
+    Oh yeah, this is important. By default all data is encrypted in some
+    weird binary format. If you want to have things appear in ASCII text
+    that is readable, just add the '-a' option. But the preferred method
+    is to use a MIME aware mail reader (Mutt, Pine and many more).
+
+    There is a small security glitch in the OpenPGP (and therefore GnuPG)
+    system; to avoid this you should always sign and encrypt a message
+    instead of only encrypting it.
+
+** Why are some signatures with an ELG-E key valid?
+   :PROPERTIES:
+   :CUSTOM_ID: why-are-some-signatures-with-an-elg-e-key-valid
+   :END:
+
+    These are Elgamal keys generated by GnuPG in v3 (RFC 1991) packets.
+    The OpenPGP draft later changed the algorithm identifier for Elgamal
+    keys which are usable for signatures and encryption from 16 to 20.
+    GnuPG now uses 20 when it generates new Elgamal keys but still
+    accepts 16 (which is according to OpenPGP "encryption only") if this
+    key is in a v3 packet. GnuPG is the only program which had used
+    these v3 Elgamal keys - so this assumption is quite safe.
+
+** How does the whole trust thing work?
+   :PROPERTIES:
+   :CUSTOM_ID: how-does-the-whole-trust-thing-work
+   :END:
+
+    It works more or less like PGP. The difference is that the trust is
+    computed at the time it is needed. This is one of the reasons for
+    the trustdb which holds a list of valid key signatures. If you are
+    not running in batch mode you will be asked to assign a trust
+    parameter (ownertrust) to a key.
+
+    You can see the validity (calculated trust value) using this
+    command.
+
+    : $ gpg --list-keys --with-colons
+
+    If the first field is "pub" or "uid", the second field shows you the
+    trust:
+
+    :   o = Unknown (this key is new to the system)
+    :   e = The key has expired
+    :   q = Undefined (no value assigned)
+    :   n = Don't trust this key at all
+    :   m = There is marginal trust in this key
+    :   f = The key is full trusted
+    :   u = The key is ultimately trusted; this is only used
+    :       for keys for which the secret key is also available.
+    :   r = The key has been revoked
+    :   d = The key has been disabled
+
+    The value in the "pub" record is the best one of all "uid" records.
+    You can get a list of the assigned trust values (how much you trust
+    the owner to correctly sign another person's key) with:
+
+    : $ gpg --export-ownertrust
+
+    The first field is the fingerprint of the primary key, the second
+    field is the assigned value:
+
+    :  - = No ownertrust value yet assigned or calculated.
+    :  n = Never trust this keyholder to correctly verify others signatures.
+    :  m = Have marginal trust in the keyholders capability to sign other
+    :      keys.
+    :  f = Assume that the key holder really knows how to sign keys.
+    :  u = No need to trust ourself because we have the secret key.
+
+    Keep these values confidential because they express your opinions
+    about others. PGP stores this information with the keyring thus it
+    is not a good idea to publish a PGP keyring instead of exporting
+    the keyring. GnuPG stores the trust in the trustdb.gpg file so it
+    is okay to give a gpg keyring away (but we have a --export command
+    too).
+
+** What kind of output is this: "key C26EE891.298, uid 09FB: ...."?
+   :PROPERTIES:
+   :CUSTOM_ID: trustb-diagnostics-output-key-uid
+   :END:
+
+    This is the internal representation of a user ID in the trustdb.
+    "C26EE891" is the keyid, "298" is the local ID (a record number in
+    the trustdb) and "09FB" is the last two bytes of a ripe-md-160 hash
+    of the user ID for this key.
+
+** How do I interpret some of the informational outputs?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-interpret-some-of-the-informational-outputs
+   :END:
+
+    While checking the validity of a key, GnuPG sometimes prints some
+    information which is prefixed with information about the checked
+    item.
+
+    : "key 12345678.3456"
+
+    This is about the key with key ID 12345678 and the internal number
+    3456, which is the record number of the so called directory record
+    in the trustdb.
+
+    : "uid 12345678.3456/ACDE"
+
+    This is about the user ID for the same key. To identify the user ID
+    the last two bytes of a ripe-md-160 over the user ID ring is printed.
+
+    : "sig 12345678.3456/ACDE/9A8B7C6D"
+
+    This is about the signature with key ID 9A8B7C6D for the above key
+    and user ID, if it is a signature which is direct on a key, the user
+    ID part is empty (..//..).
+
+** Are the header lines of a cleartext signature part of the signed material?
+   :PROPERTIES:
+   :CUSTOM_ID: are-header-lines-of-cleartext-sigs-part-of-the-signed-material
+   :END:
+
+    No. For example you can add or remove "Comment:" lines. They have
+    a purpose like the mail header lines. However a "Hash:" line is
+    needed for OpenPGP signatures to tell the parser which hash
+    algorithm to use.
+
+** What is the list of preferred algorithms?
+   :PROPERTIES:
+   :CUSTOM_ID: what-is-the-list-of-preferred-algorithms
+   :END:
+
+    The list of preferred algorithms is a list of cipher, hash and
+    compression algorithms stored in the self-signature of a key during
+    key generation. When you encrypt a document, GnuPG uses this list
+    (which is then part of a public key) to determine which algorithms
+    to use. Basically it tells other people what algorithms the
+    recipient is able to handle and provides an order of preference.
+
+** How do I change the list of preferred algorithms?
+   :PROPERTIES:
+   :CUSTOM_ID: how-do-i-change-the-list-of-preferred-algorithms
+   :END:
+
+    In version 1.0.7 or later, you can use the edit menu and set the
+    new list of preference using the command "setpref"; the format of
+    this command resembles the output of the command "pref". The
+    preference is not changed immediately but the set preference will
+    be used when a new user ID is created. If you want to update the
+    preferences for existing user IDs, select those user IDs (or select
+    none to update all) and enter the command "updpref". Note that the
+    timestamp of the self-signature is increased by one second when
+    running this command.
+
+** How can I import all the missing signer keys?
+   :PROPERTIES:
+   :CUSTOM_ID: how-can-i-import-all-the-missing-signer-keys
+   :END:
+
+    If you imported a key and you want to also import all the signer's
+    keys, you can do this with this command:
+
+    :  gpg --check-sigs --with-colon KEYID \
+    :   | awk -F: '$1 == "sig" && $2 == "?"  { print $5 }' \
+    :   | sort | uniq | xargs echo gpg --recv-keys
+
+    Note that the invocation of sort is also required to wait for the
+    of the listing before before starting the import.
+
+
+* Bug reporting and hacking
+  :PROPERTIES:
+  :CUSTOM_ID: bugreports-et-al
+  :END:
+
+** Copyright assignments
+  :PROPERTIES:
+  :CUSTOM_ID: copyright-assignments
+  :END:
+
+Like most core GNU projects, GnuPG requires the signing of a copyright
+assignment to the FSF.  Without such an assignment we may only accept
+trivial patches.  As a rule of thumb the sum of all changed lines by
+one contributor may not exceed about 15 lines.  Exceptions are typo
+corrections and translations.  See
+http://www.gnu.org/prep/maintain/html_node/Copyright-Papers.html for
+details.
+
+** U.S. export restrictions
+  :PROPERTIES:
+  :CUSTOM_ID: us-export-restrictions
+  :END:
+
+GnuPG has originally been developed in Germany because we have been
+able to do that without being affected by the US export restrictions.
+We had to reject any contributions from US citizens or from people
+living the the US.  That changed by end of 2000 when the export
+restrictions were basically dropped for all kind of freely available
+software.  However there are still some requirements in the US.
+Quoting David Shaw: mail
+#+begin_quote
+For each release of GPG that I contributed to, I sent an email
+containing a pointer to the new source code to the Commerce
+Department.  The rules changed slightly in 2004, so that you could
+send a single email and then be done until the information in that
+email changed, so I just sent "www.gnupg.org" and haven't bothered
+with the email since.
+#+end_quote
+
+The rules: http://www.bis.doc.gov/encryption/pubavailencsourcecodenofify.html
+The 2004 rule change: http://edocket.access.gpo.gov/2004/04-26992.htm
+
+
+* Acknowledgements
+  :PROPERTIES:
+  :CUSTOM_ID: acknowledgements
+  :END:
+
+  Many thanks to Nils Ellmenreich for maintaining this FAQ file for
+  such a long time, David D. Scribner for continuing maintenance,
+  Werner Koch for the original FAQ file, and to all posters to
+  gnupg-users and gnupg-devel.  They all provided most of the answers.
+  Converted to org-mode and removed from the tarballs in October 2010.
+
+  Copyright (C) 2000, 2001, 2002, 2003, 2010 Free Software Foundation,
+  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
+
+  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.
+
+* Changes
+
+  - 2010-11-14: Update "gpg: Warning: using insecure memory!"
+
+
+
+
+* COMMENT HTML style specifications
+
+#+begin_src emacs-lisp
+  (defun org-faq-make-target ()
+    "Make hard target for current headline."
+    (interactive)
+    (if (not (org-on-heading-p))
+        (error "Not on a headline"))
+    (let ((h (org-trim (org-get-heading 'no-tags))))
+      (if (string-match "[ \t]*\\?\\'" h)
+          (setq h (replace-match "" t t h)))
+      (while (string-match "[ \t]+" h)
+        (setq h (replace-match "-" t t h)))
+      (setq h (downcase h))
+      (org-entry-put nil "CUSTOM_ID" h)))
+#+end_src
+
+
+
+# Local Variables:
+# org-export-html-style-include-default: nil
+# org-export-html-style-include-scripts: nil
+# End:
diff --git a/doc/faq.raw b/doc/faq.raw
deleted file mode 100644 (file)
index 0e45027..0000000
+++ /dev/null
@@ -1,1354 +0,0 @@
-[$htmltitle=GnuPG FAQ]
-[$htmlcharset=<meta http-equiv="content-type" content="text/html; charset=utf-8">]
-[$sfaqheader=The GnuPG FAQ says:]
-[$sfaqfooter=
-The most recent version of the FAQ is available from
-<http://www.gnupg.org/>
-]
-[$usenetheader=
-]
-[$maintainer=David D. Scribner, <faq 'at' gnupg.org>]
-[$hGPGHTTP=http://www.gnupg.org]
-[$hGPGFTP=ftp://ftp.gnupg.org]
-[$hVERSION=1.2.2]
-
-[H body bgcolor=#ffffff text=#000000 link=#1f00ff alink=#ff0000 vlink=#9900dd]
-[H h1]GnuPG Frequently Asked Questions[H /h1]
-
-
-[H p]
-Version: 1.6.3[H br]
-Last-Modified: Jul 30, 2003[H br]
-Maintained-by: [$maintainer]
-[H /p]
-
-
-This is the GnuPG FAQ. The latest HTML version is available
-[H a href=[$hGPGHTTP]/documentation/faqs.html]here[H/a].
-
-The index is generated automatically, so there may be errors. Not all
-questions may be in the section they belong to. Suggestions about how
-to improve the structure of this FAQ are welcome.
-
-Please send additions and corrections to the maintainer. It would be
-most convenient if you could provide the answer to be included here
-as well. Your help is very much appreciated!
-
-Please, don't send message like "This should be a FAQ - what's the
-answer?". If it hasn't been asked before, it isn't a FAQ. In that case
-you could search in the mailing list archive.
-
-[H hr]
-<C>
-[H hr]
-
-
-<S> GENERAL
-
-<Q> What is GnuPG?
-
-    [H a href=[$hGPGHTTP]]GnuPG[H /a] stands for GNU Privacy Guard and
-    is GNU's tool for secure communication and data storage. It can be
-    used to encrypt data and to create digital signatures. It includes
-    an advanced key management facility and is compliant with the
-    proposed OpenPGP Internet standard as described in [H a href=http://www.rfc-editor.org/]RFC 2440[H/a].
-    As such, it is aimed to be compatible with PGP from PGP Corp. and
-    other OpenPGP tools
-
-<Q> Is GnuPG compatible with PGP?
-
-    In general, yes. GnuPG and newer PGP releases should be implementing
-    the OpenPGP standard. But there are some interoperability problems.
-    See question <Rcompat> for details.
-
-<Q> Is GnuPG free to use for personal or commercial use?
-
-    Yes. GnuPG is part of the GNU family of tools and applications built
-    and provided in accordance with the Free Software Foundation (FSF)
-    General Public License (GPL). Therefore the software is free to copy,
-    use, modify and distribute in accordance with that license. Please
-    read the file titled COPYING that accompanies the application for
-    more information.
-
-<Q> What conventions are used in this FAQ?
-
-    Although GnuPG is being developed for several operating systems
-    (often in parallel), the conventions used in this FAQ reflect a
-    UNIX shell environment. For Win32 users, references to a shell
-    prompt (`$') should be interpreted as a command prompt (`>'),
-    directory names separated by a forward slash (`/') may need to be
-    converted to a back slash (`\'), and a tilde (`~') represents a
-    user's "home" directory (reference question <Rhomedir> for an example).
-
-    Some command-lines presented in this FAQ are too long to properly
-    display in some browsers for the web page version of this file, and
-    have been split into two or more lines. For these commands please
-    remember to enter the entire command-string on one line or the
-    command will error, or at minimum not give the desired results. 
-
-    Please keep in mind that this FAQ contains information that may not
-    apply to your particular version, as new features and bug fixes are
-    added on a continuing basis (reference the NEWS file included with
-    the source or package for noteworthy changes between versions). One
-    item to note is that starting with GnuPG version 1.1.92 the file
-    containing user options and settings has been renamed from "options"
-    to "gpg.conf". Information in the FAQ that relates to the options
-    file may be interchangable with the newer gpg.conf file in many
-    instances. See question <Roptions> for details.
-
-
-<S> SOURCES of INFORMATION
-
-<Q> Where can I find more information on GnuPG?
-
-    On-line resources:
-
-    [H ul] 
-    [H li]The documentation page is located at [H a href=[$hGPGHTTP]/documentation/]<[$hGPGHTTP]/documentation/>[H/a].
-    Also, have a look at the HOWTOs and the GNU Privacy Handbook (GPH,
-    available in English, Spanish and Russian). The latter provides a
-    detailed user's guide to GnuPG. You'll also find a document about how
-    to convert from PGP 2.x to GnuPG.
-
-    [H li]At [H a href=[$hGPGHTTP]/documentation/mailing-lists.html]<[$hGPGHTTP]/documentation/mailing-lists.html>[H/a] you'll find
-    an online archive of the GnuPG mailing lists. Most interesting should
-    be gnupg-users for all user-related issues and gnupg-devel if you want
-    to get in touch with the developers.
-
-    In addition, searchable archives can be found on MARC, e.g.: [H br]
-    gnupg-users: [H a href=http://marc.theaimsgroup.com/?l=gnupg-users&r=1&w=2]<http://marc.theaimsgroup.com/?l=gnupg-users&r=1&w=2>[H/a][H br]
-    gnupg-devel: [H a href=http://marc.theaimsgroup.com/?l=gnupg-devel&r=1&w=2]<http://marc.theaimsgroup.com/?l=gnupg-devel&r=1&w=2>[H/a][H br]
-
-    [H b]PLEASE:[H /b]
-    Before posting to a list, read this FAQ and the available documentation.
-    In addition, search the list archive - maybe your question has already
-    been discussed. This way you help people focus on topics that have not
-    yet been resolved.
-
-    [H li]The GnuPG source distribution contains a subdirectory:
-
-    [H samp]
-       ./doc
-    [H /samp]
-
-    where some additional documentation is located (mainly interesting
-    for hackers, not the casual user).
-    [H /ul]
-
-<Q> Where do I get GnuPG?
-
-    You can download the GNU Privacy Guard from its primary FTP server
-    [H a href=[$hGPGFTP]/gcrypt/]<[$hGPGFTP]/gcrypt/>[H /a] or from one of the mirrors:
-
-    [H a href=[$hGPGHTTP]/download/mirrors.html]
-       <[$hGPGHTTP]/download/mirrors.html>
-    [H /a]
-
-    The current stable version is [$hVERSION]. Please upgrade to this version as
-    it includes additional features, functions and security fixes that may
-    not have existed in prior versions.
-
-
-<S> INSTALLATION 
-
-<Q> Which OSes does GnuPG run on?
-
-    It should run on most Unices as well as Windows versions (including
-    Windows NT/2000) and Macintosh OS/X. A list of OSes reported to be OK
-    is presented at:
-
-    [H a href=[$hGPGHTTP]/download/supported_systems.html]
-       <[$hGPGHTTP]/download/supported_systems.html>
-    [H /a]
-
-<Q> Which random data gatherer should I use?
-
-    "Good" random numbers are crucial for the security of your encryption.
-    Different operating systems provide a variety of more or less quality
-    random data. Linux and *BSD provide kernel generated random data
-    through /dev/random - this should be the preferred choice on these
-    systems. Also Solaris users with the SUNWski package installed have
-    a /dev/random. In these cases, use the configure option:
-
-    [H samp]
-       --enable-static-rnd=linux
-    [H /samp]
-
-    In addition, there's also the kernel random device by Andi Maier
-    [H a href= http://www.cosy.sbg.ac.at/~andi/SUNrand/]<http://www.cosy.sbg.ac.at/~andi/SUNrand/>[H /a], but it's still beta. Use at your
-    own risk!
-
-    On other systems, the Entropy Gathering Daemon (EGD) is a good choice.
-    It is a perl-daemon that monitors system activity and hashes it into
-    random data. See the download page [H a href=[$hGPGHTTP]/download/]<[$hGPGHTTP]/download/>[H /a]
-    to obtain EGD. Use:
-
-    [H samp]
-       --enable-static-rnd=egd
-    [H /samp]
-
-    here.
-
-    If the above options do not work, you can use the random number
-    generator "unix". This is [H B]very[H /B] slow and should be avoided. The
-    random quality isn't very good so don't use it on sensitive data.
-
-<Didea>
-<Q> How do I include support for RSA and IDEA?
-
-    RSA is included as of GnuPG version 1.0.3.
-
-    The official GnuPG distribution does not contain IDEA due to a patent
-    restriction. The patent does not expire before 2007 so don't expect
-    official support before then.
-
-    However, there is an unofficial module to include it even in earlier
-    versions of GnuPG. It's available from
-    [H a href=ftp://ftp.gnupg.dk/pub/contrib-dk/]<ftp://ftp.gnupg.dk/pub/contrib-dk/>[H /a]. Look for:
-
-    [H pre]
-       idea.c.gz        (c module)
-       idea.c.gz.sig    (signature file)
-    [H /pre]
-
-    [H pre]
-       ideadll.zip      (c module and win32 dll)
-       ideadll.zip.sig  (signature file)
-    [H /pre]
-
-    Compilation directives are in the headers of these files. You will
-    then need to add the following line to your ~/.gnupg/gpg.conf or
-    ~/.gnupg/options file:
-
-    [H samp]
-       load-extension idea
-    [H /samp]
-
-
-<S> USAGE
-
-<Q> What is the recommended key size?
-
-    1024 bit for DSA signatures; even for plain Elgamal signatures.
-    This is sufficient as the size of the hash is probably the weakest
-    link if the key size is larger than 1024 bits. Encryption keys may
-    have greater sizes, but you should then check the fingerprint of
-    this key:
-
-    [H samp]
-       $ gpg --fingerprint <user ID>
-    [H /samp]
-
-    As for the key algorithms, you should stick with the default (i.e.,
-    DSA signature and Elgamal encryption). An Elgamal signing key has
-    the following disadvantages: the signature is larger, it is hard
-    to create such a key useful for signatures which can withstand some
-    real world attacks, you don't get any extra security compared to
-    DSA, and there might be compatibility problems with certain PGP
-    versions. It has only been introduced because at the time it was
-    not clear whether there was a patent on DSA.
-
-<Q> Why does it sometimes take so long to create keys?
-
-    The problem here is that we need a lot of random bytes and for that
-    we (on Linux the /dev/random device) must collect some random data.
-    It is really not easy to fill the Linux internal entropy buffer; I
-    talked to Ted Ts'o and he commented that the best way to fill the
-    buffer is to play with your keyboard. Good security has its price.
-    What I do is to hit several times on the shift, control, alternate,
-    and caps lock keys, because these keys do not produce output to the
-    screen. This way you get your keys really fast (it's the same thing
-    PGP2 does).
-
-    Another problem might be another program which eats up your random
-    bytes (a program (look at your daemons) that reads from /dev/random).
-
-<Q> And it really takes long when I work on a remote system. Why?
-
-    Don't do this at all! You should never create keys or even use GnuPG
-    on a remote system because you normally have no physical control
-    over your secret key ring (which is in most cases vulnerable to
-    advanced dictionary attacks) - I strongly encourage everyone to only
-    create keys on a local computer (a disconnected laptop is probably
-    the best choice) and if you need it on your connected box (I know,
-    we all do this) be sure to have a strong password for both your
-    account and for your secret key, and that you can trust your system
-    administrator.
-
-    When I check GnuPG on a remote system via ssh (I have no Alpha here)
-    ;-) I have the same problem. It takes a *very* long time to create
-    the keys, so I use a special option, --quick-random, to generate
-    insecure keys which are only good for some tests.
-
-<Q> What is the difference between options and commands?
-
-    If you do a 'gpg --help', you will get two separate lists. The first
-    is a list of commands. The second is a list of options. Whenever you
-    run GPG, you [H b]must[H /b] pick exactly one command (with one exception,
-    see below). You [H b]may[H /b] pick one or more options. The command should,
-    just by convention, come at the end of the argument list, after all
-    the options. If the command takes a file (all the basic ones do),
-    the filename comes at the very end. So the basic way to run gpg is:
-
-    [H samp]
-       $ gpg [--option something] [--option2] [--option3 something] --command file
-    [H /samp]
-
-    Some options take arguments. For example, the --output option (which
-    can be abbreviated as -o) is an option that takes a filename. The
-    option's argument must follow immediately after the option itself,
-    otherwise gpg doesn't know which option the argument is supposed to
-    paired with. As an option, --output and its filename must come before
-    the command. The --recipient (-r) option takes a name or keyID to
-    encrypt the message to, which must come right after the -r option.
-    The --encrypt (or -e) command comes after all the options and is
-    followed by the file you wish to encrypt. Therefore in this example
-    the command-line issued would be:
-
-    [H samp]
-       $ gpg -r alice -o secret.txt -e test.txt
-    [H /samp]
-
-    If you write the options out in full, it is easier to read:
-
-    [H samp]
-       $ gpg --recipient alice --output secret.txt --encrypt test.txt
-    [H /samp]
-
-    If you're encrypting to a file with the extension ".txt", then you'd
-    probably expect to see ASCII-armored text in the file (not binary),
-    so you need to add the --armor (-a) option, which doesn't take any
-    arguments:
-
-    [H samp]
-       $ gpg --armor --recipient alice --output secret.txt --encrypt test.txt
-    [H /samp]
-
-    If you imagine square brackets around the optional parts, it becomes
-    a bit clearer:
-
-    [H samp]
-       $ gpg [--armor] [--recipient alice] [--output secret.txt] --encrypt test.txt
-    [H /samp]
-
-    The optional parts can be rearranged any way you want:
-
-    [H samp]
-       $ gpg --output secret.txt --recipient alice --armor --encrypt test.txt
-    [H /samp]
-
-    If your filename begins with a hyphen (e.g. "-a.txt"), GnuPG assumes
-    this is an option and may complain. To avoid this you have to either
-    use "./-a.txt", or stop the option and command processing with two
-    hyphens: "-- -a.txt".
-
-    [H B]The exception to using only one command:[H /B] signing and encrypting
-    at the same time. For this you can combine both commands, such as in:
-
-    [H samp]
-       $ gpg [--options] --sign --encrypt foo.txt
-    [H /samp]
-
-<Q> I can't delete a user ID on my secret keyring because it has
-    already been deleted on my public keyring. What can I do?
-
-    Because you can only select from the public key ring, there is no
-    direct way to do this. However it is not very complicated to do
-    anyway. Create a new user ID with exactly the same name and you
-    will see that there are now two identical user IDs on the secret
-    ring. Now select this user ID and delete it. Both user IDs will be
-    removed from the secret ring.
-
-<Q> I can't delete my secret key because the public key disappeared.
-    What can I do?
-
-    To select a key a search is always done on the public keyring,
-    therefore it is not possible to select a secret key without
-    having the public key. Normally it should never happen that the
-    public key got lost but the secret key is still available. The
-    reality is different, so GnuPG implements a special way to deal
-    with it: Simply use the long keyID to specify the key to delete,
-    which can be obtained by using the --with-colons options (it is
-    the fifth field in the lines beginning with "sec").
-
-    If you've lost your public key and need to recreate it instead
-    for continued use with your secret key, you may be able to use
-    gpgsplit as detailed in question <Rgpgsplit>.
-
-<Q> What are trust, validity and ownertrust?
-
-    With GnuPG, the term "ownertrust" is used instead of "trust" to
-    help clarify that this is the value you have assigned to a key
-    to express how much you trust the owner of this key to correctly
-    sign (and thereby introduce) other keys. The "validity", or
-    calculated trust, is a value which indicates how much GnuPG
-    considers a key as being valid (that it really belongs to the
-    one who claims to be the owner of the key). For more information
-    on trust values see the chapter "The Web of Trust" in The GNU
-    Privacy Handbook.
-
-<Q> How do I sign a patch file?
-
-    Use "gpg --clearsign --not-dash-escaped ...". The problem with
-    --clearsign is that all lines starting with a dash are quoted with
-    "- "; obviously diff produces many lines starting with a dash and
-    these are then quoted and that is not good for a patch ;-). To use
-    a patch file without removing the cleartext signature, the special
-    option --not-dash-escaped may be used to suppress generation of
-    these escape sequences. You should not mail such a patch because
-    spaces and line endings are also subject to the signature and a
-    mailer may not preserve these. If you want to mail a file you can
-    simply sign it using your MUA (Mail User Agent).
-
-<Q> Where is the "encrypt-to-self" option?
-
-    Use "--encrypt-to your_keyID". You can use more than one of these
-    options. To temporarily override the use of this additional key,
-    you can use the option "--no-encrypt-to".
-
-<Q> How can I get rid of the Version and Comment headers in armored
-    messages?
-
-    Use "--no-version --comment ''". Note that the left over blank line
-    is required by the protocol.
-
-<Q> What does the "You are using the xxxx character set." mean?
-
-    This note is printed when UTF-8 mapping has to be done. Make sure
-    that the displayed character set is the one you have activated on
-    your system. Since "iso-8859-1" is the character set most used,
-    this is the default. You can change the charset with the option
-    "--charset". It is important that your active character set matches
-    the one displayed - if not, restrict yourself to plain 7 bit ASCII
-    and no mapping has to be done.
-
-<Q> How can I get list of key IDs used to encrypt a message?
-
-    [H samp]
-       $ gpg --batch --decrypt --list-only --status-fd 1 2>/dev/null |
-         awk '/^\[GNUPG:\] ENC_TO / { print $3 }'
-    [H /samp]
-
-<Q> Why can't I decrypt files encrypted as symmetrical-only (-c) with
-    a version of GnuPG prior to 1.0.1.
-
-    There was a bug in GnuPG versions prior to 1.0.1 which affected files
-    only if 3DES or Twofish was used for symmetric-only encryption (this has
-    never been the default). The bug has been fixed, but to enable decryption
-    of old files you should run gpg with the option "--emulate-3des-s2k-bug",
-    decrypt the file and encrypt it again without this option.
-
-    NOTE: This option was removed in GnuPG development version 1.1.0 and later
-    updates, so you will need to use a version between 1.0.1 and 1.0.7 to
-    re-encrypt any affected files.
-
-<Q> How can I use GnuPG in an automated environment?
-
-    You should use the option --batch and don't use passphrases as
-    there is usually no way to store it more securely than on the
-    secret keyring itself. The suggested way to create keys for an
-    automated environment is:
-
-    On a secure machine:
-    [H ol]
-    [H li] If you want to do automatic signing, create a signing subkey
-           for your key (use the interactive key editing menu by issueing
-           the command 'gpg --edit-key keyID', enter "addkey" and select
-           the DSA key type).
-    [H li] Make sure that you use a passphrase (needed by the current
-           implementation).
-    [H li] gpg --export-secret-subkeys --no-comment foo >secring.auto
-    [H li] Copy secring.auto and the public keyring to a test directory.
-    [H li] Change to this directory.
-    [H li] gpg --homedir . --edit foo and use "passwd" to remove the
-           passphrase from the subkeys. You may also want to remove all
-           unused subkeys.
-    [H li] Copy secring.auto to a floppy and carry it to the target box.
-    [H /ol]
-
-    On the target machine:
-    [H ol]
-    [H li] Install secring.auto as the secret keyring.
-    [H li] Now you can start your new service. It's also a good idea to
-           install an intrusion detection system so that you hopefully
-           get a notice of an successful intrusion, so that you in turn
-           can revoke all the subkeys installed on that machine and
-           install new subkeys.
-    [H /ol]
-
-<Q> Which email-client can I use with GnuPG?
-
-    Using GnuPG to encrypt email is one of the most popular uses.
-    Several mail clients or mail user agents (MUAs) support GnuPG to
-    varying degrees. Simplifying a bit, there are two ways mail can be
-    encrypted with GnuPG: the "old style" ASCII armor (i.e. cleartext
-    encryption), and RFC 2015 style (previously PGP/MIME, now OpenPGP).
-    The latter has full MIME support. Some MUAs support only one of
-    them, so whichever you actually use depends on your needs as well
-    as the capabilities of your addressee. As well, support may be
-    native to the MUA, or provided via "plug-ins" or external tools.
-
-    The following list is not exhaustive:
-
-    [H pre]
-       MUA            OpenPGP ASCII   How? (N,P,T)
-       -------------------------------------------------------------
-       Calypso           N      Y      P (Unixmail)
-       Elm               N      Y      T (mailpgp,morepgp)
-       Elm ME+           N      Y      N
-       Emacs/Gnus        Y      Y      T (Mailcrypt,gpg.el)
-       Emacs/Mew         Y      Y      N
-       Emacs/VM          N      Y      T (Mailcrypt)
-       Evolution         Y      Y      N
-       Exmh              Y      Y      N
-       GNUMail.app       Y      Y      P (PGPBundle)
-       GPGMail           Y      Y      N
-       KMail (<=1.4.x)   N      Y      N
-       KMail (1.5.x)     Y(P)   Y(N)   P/N
-       Mozilla           Y      Y      P (Enigmail)
-       Mulberry          Y      Y      P
-       Mutt              Y      Y      N
-       Sylpheed          Y      Y      N
-       Claws-mail        Y      Y      N
-       TkRat             Y      Y      N
-       XEmacs/Gnus       Y      Y      T (Mailcrypt)
-       XEmacs/Mew        Y      Y      N
-       XEmacs/VM         N      Y      T (Mailcrypt)
-       XFmail            Y      Y      N
-
-       N - Native, P - Plug-in, T - External Tool
-    [H /pre]
-
-    The following table lists proprietary MUAs. The GNU Project
-    suggests against the use of these programs, but they are listed
-    for interoperability reasons for your convenience.
-
-    [H pre]
-       MUA            OpenPGP ASCII   How? (N,P,T)
-       -------------------------------------------------------------
-       Apple Mail        Y      Y      P (GPGMail)
-       Becky2            Y      Y      P (BkGnuPG)
-       Eudora            Y      Y      P (EuroraGPG)
-       Eudora Pro        Y      Y      P (EudoraGPG)
-       Lotus Notes       N      Y      P
-       Netscape 4.x      N      Y      P
-       Netscape 7.x      Y      Y      P (Enigmail)
-       Novell Groupwise  N      Y      P
-       Outlook           N      Y      P (G-Data)
-       Outlook Express   N      Y      P (GPGOE)
-       Pegasus           N      Y      P (QDPGP,PM-PGP)
-       Pine              N      Y      T (pgpenvelope,(gpg|pgp)4pine)
-       Postme            N      Y      P (GPGPPL)
-       The Bat!          N      Y      P (Ritlabs)
-    [H /pre]
-
-    Good overviews of OpenPGP-support can be found at:[H br]
-    [H a href=http://www.openpgp.fr.st/courrier_en.html]<http://www.openpgp.fr.st/courrier_en.html>[H /a] and[H br]
-    [H a href=http://www.bretschneidernet.de/tips/secmua.html]<http://www.bretschneidernet.de/tips/secmua.html>[H /a].
-
-    Users of Win32 MUAs that lack OpenPGP support may look into
-    using GPGrelay [H a href=http://gpgrelay.sourceforge.net]<http://gpgrelay.sourceforge.net>[H /a], a small
-    email-relaying server that uses GnuPG to enable many email clients
-    to send and receive emails that conform to PGP-MIME (RFC 2015).
-
-<Q> Can't we have a gpg library?
-
-    This has been frequently requested. However, the current viewpoint
-    of the GnuPG maintainers is that this would lead to several security
-    issues and will therefore not be implemented in the foreseeable
-    future. However, for some areas of application gpgme could do the
-    trick. You'll find it at [H a href=[$hGPGFTP]/gcrypt/alpha/gpgme]<[$hGPGFTP]/gcrypt/alpha/gpgme>[H /a].
-
-<Q> I have successfully generated a revocation certificate, but I don't
-    understand how to send it to the key servers.
-
-    Most keyservers don't accept a 'bare' revocation certificate. You
-    have to import the certificate into gpg first:
-
-    [H samp]
-       $ gpg --import my-revocation.asc
-    [H /samp]
-
-    then send the revoked key to the keyservers:
-
-    [H samp]
-       $ gpg --keyserver certserver.pgp.com --send-keys mykeyid
-    [H /samp]
-
-    (or use a keyserver web interface for this).
-
-<Dhomedir>
-<Q> How do I put my keyring in a different directory?
-
-    GnuPG keeps several files in a special homedir directory. These
-    include the options file, pubring.gpg, secring.gpg, trustdb.gpg,
-    and others. GnuPG will always create and use these files. On unices,
-    the homedir is usually ~/.gnupg; on Windows it is name "gnupg" and
-    found below the user's application directory.  Run the gpg and
-    pass the option --version to see the name of that directory.
-
-    If you want to put your keyrings somewhere else, use the option:
-
-    [H samp]
-       --homedir /my/path/
-    [H /samp]
-
-    to make GnuPG create all its files in that directory. Your keyring
-    will be "/my/path/pubring.gpg". This way you can store your secrets
-    on a floppy disk. Don't use "--keyring" as its purpose is to specify
-    additional keyring files.
-
-<Q> How do I verify signed packages?
-
-    Before you can verify the signature that accompanies a package,
-    you must first have the vendor, organisation, or issueing person's
-    key imported into your public keyring. To prevent GnuPG warning
-    messages the key should also be validated (or locally signed).
-
-    You will also need to download the detached signature file along
-    with the package. These files will usually have the same name as
-    the package, with either a binary (.sig) or ASCII armor (.asc)
-    extension.
-
-    Once their key has been imported, and the package and accompanying
-    signature files have been downloaded, use:
-
-    [H samp]
-       $ gpg --verify sigfile signed-file
-    [H /samp]
-
-    If the signature file has the same base name as the package file,
-    the package can also be verified by specifying just the signature
-    file, as GnuPG will derive the package's file name from the name
-    given (less the .sig or .asc extension). For example, to verify a
-    package named foobar.tar.gz against its detached binary signature
-    file, use:
-
-    [H samp]
-       $ gpg --verify foobar.tar.gz.sig
-    [H /samp]
-
-<Q> How do I export a keyring with only selected signatures (keys)?
-
-    If you're wanting to create a keyring with only a subset of keys
-    selected from a master keyring (for a club, user group, or company
-    department for example), simply specify the keys you want to export:
-
-    [H samp]
-       $ gpg --armor --export key1 key2 key3 key4 > keys1-4.asc
-    [H /samp]
-
-<Dgpgsplit>
-<Q> I still have my secret key, but lost my public key. What can I do?
-
-    All OpenPGP secret keys have a copy of the public key inside them,
-    and in a worst-case scenario, you can create yourself a new public
-    key using the secret key.
-
-    A tool to convert a secret key into a public one has been included
-    (it's actually a new option for gpgsplit) and is available with GnuPG
-    versions 1.2.1 or later (or can be found in CVS). It works like this:
-
-    [H samp]
-       $ gpgsplit --no-split --secret-to-public secret.gpg >publickey.gpg
-    [H /samp]
-
-    One should first try to export the secret key and convert just this
-    one. Using the entire secret keyring should work too. After this has
-    been done, the publickey.gpg file can be imported into GnuPG as usual.
-
-<Q> Clearsigned messages sent from my web-mail account have an invalid
-    signature. Why?
-
-    Check to make sure the settings for your web-based email account
-    do not use HTML formatting for the pasted clearsigned message. This can
-    alter the message with embedded HTML markup tags or spaces, resulting
-    in an invalid signature. The recipient may be able to copy the signed
-    message block to a text file for verification, or the web email
-    service may allow you to attach the clearsigned message as a file
-    if plaintext messages are not an option.
-
-
-<S> COMPATIBILITY ISSUES
-
-<Dcompat>
-<Q> How can I encrypt a message with GnuPG so that PGP is able to decrypt it?
-
-    It depends on the PGP version.
-
-    [H ul]
-    [H li]PGP 2.x[H br]
-    You can't do that because PGP 2.x normally uses IDEA which is not
-    supported by GnuPG as it is patented (see <Ridea>), but if you have a
-    modified version of PGP you can try this:
-
-    [H samp]
-       $ gpg --rfc1991 --cipher-algo 3des ...
-    [H /samp]
-
-    Please don't pipe the data to encrypt to gpg but provide it using a
-    filename; otherwise, PGP 2 will not be able to handle it.
-
-    As for conventional encryption, you can't do this for PGP 2.
-
-    [H li]PGP 5.x and higher[H br]
-    You need to provide two additional options:
-
-    [H samp]
-       --compress-algo 1 --cipher-algo cast5
-    [H /samp]
-
-    You may also use "3des" instead of "cast5", and "blowfish" does not
-    work with all versions of PGP 5. You may also want to put:
-
-    [H samp]
-       compress-algo 1
-    [H /samp]
-
-    into your ~/.gnupg/options file - this does not affect normal GnuPG
-    operation.
-
-    This applies to conventional encryption as well.
-    [H /UL]
-
-<Q> How do I migrate from PGP 2.x to GnuPG?
-
-    PGP 2 uses the RSA and IDEA encryption algorithms. Whereas the RSA
-    patent has expired and RSA is included as of GnuPG 1.0.3, the IDEA
-    algorithm is still patented until 2007. Under certain conditions you
-    may use IDEA even today. In that case, you may refer to Question
-    <Ridea> about how to add IDEA support to GnuPG and read
-    [H a href=[$hGPGHTTP]/gph/en/pgp2x.html]<[$hGPGHTTP]/gph/en/pgp2x.html>[H /a] to perform the migration.
-
-<Q> (removed)
-
-    (empty)
-
-<Q> Why is PGP 5.x not able to encrypt messages with some keys?
-
-    PGP, Inc. refuses to accept Elgamal keys of type 20 even for
-    encryption. They only support type 16 (which is identical at least
-    for decryption). To be more inter-operable, GnuPG (starting with
-    version 0.3.3) now also uses type 16 for the Elgamal subkey which is
-    created if the default key algorithm is chosen. You may add a type
-    16 Elgamal key to your public key, which is easy as your key
-    signatures are still valid.
-
-<Q> Why is PGP 5.x not able to verify my messages?
-
-    PGP 5.x does not accept v4 signatures for data material but OpenPGP
-    requests generation of v4 signatures for all kind of data, that's why
-    GnuPG defaults to them. Use the option "--force-v3-sigs" to generate
-    v3 signatures for data.
-
-<Q> How do I transfer owner trust values from PGP to GnuPG?
-
-    There is a script in the tools directory to help you. After you have
-    imported the PGP keyring you can give this command:
-
-    [H samp]
-       $ lspgpot pgpkeyring | gpg --import-ownertrust
-    [H /samp]
-
-    where pgpkeyring is the original keyring and not the GnuPG keyring
-    you might have created in the first step.
-
-<Q> PGP does not like my secret key.
-
-    Older PGPs probably bail out on some private comment packets used by
-    GnuPG. These packets are fully in compliance with OpenPGP; however
-    PGP is not really OpenPGP aware. A workaround is to export the
-    secret keys with this command:
-
-    [H samp]
-       $ gpg --export-secret-keys --no-comment -a your-KeyID
-    [H /samp]
-
-    Another possibility is this: by default, GnuPG encrypts your secret
-    key using the Blowfish symmetric algorithm. Older PGPs will only
-    understand 3DES, CAST5, or IDEA symmetric algorithms. Using the
-    following method you can re-encrypt your secret gpg key with a
-    different algo:
-
-    [H samp]
-       $ gpg --s2k-cipher-algo=CAST5 --s2k-digest-algo=SHA1
-         --compress-algo=1  --edit-key <username>
-    [H /samp]
-
-    Then use passwd to change the password (just change it to the same
-    thing, but it will encrypt the key with CAST5 this time).
-
-    Now you can export it and PGP should be able to handle it.
-
-    For PGP 6.x the following options work to export a key:
-
-    [H samp]
-       $ gpg --s2k-cipher-algo 3des --compress-algo 1 --rfc1991
-         --export-secret-keys <KeyID>
-    [H /samp]
-
-<Doptions>
-<Q> GnuPG no longer installs a ~/.gnupg/options file. Is it missing?
-
-    No. The ~/.gnupg/options file has been renamed to ~/.gnupg/gpg.conf for
-    new installs as of version 1.1.92. If an existing ~/.gnupg/options file
-    is found during an upgrade it will still be used, but this change was
-    required to have a more consistent naming scheme with forthcoming tools.
-    An existing options file can be renamed to gpg.conf for users upgrading,
-    or receiving the message that the "old default options file" is ignored
-    (occurs if both a gpg.conf and an options file are found).
-
-<Q> How do you export GnuPG keys for use with PGP?
-
-    This has come up fairly often, so here's the HOWTO:
-
-    PGP can (for most key types) use secret keys generated by GnuPG. The
-    problems that come up occasionally are generally because GnuPG
-    supports a few more features from the OpenPGP standard than PGP does.
-    If your secret key has any of those features in use, then PGP will
-    reject the key or you will have problems communicating later. Note
-    that PGP doesn't do Elgamal signing keys at all, so they are not
-    usable with any version.
-
-    These instructions should work for GnuPG 1.0.7 and later, and PGP
-    7.0.3 and later.
-
-    Start by editing the key. Most of this line is not really necessary
-    as the default values are correct, but it does not hurt to repeat the
-    values, as this will override them in case you have something else set
-    in your options file.
-
-    [H samp]
-       $ gpg --s2k-cipher-algo cast5 --s2k-digest-algo sha1 --s2k-mode 3
-         --simple-sk-checksum --edit KeyID
-    [H /samp]
-
-    Turn off some features. Set the list of preferred ciphers, hashes,
-    and compression algorithms to things that PGP can handle. (Yes, I
-    know this is an odd list of ciphers, but this is what PGP itself uses,
-    minus IDEA).
-
-    [H samp]
-       > setpref S9 S8 S7 S3 S2 S10 H2 H3 Z1 Z0
-    [H /samp]
-
-    Now put the list of preferences onto the key.
-
-    [H samp]
-       > updpref
-    [H /samp]
-
-    Finally we must decrypt and re-encrypt the key, making sure that we
-    encrypt with a cipher that PGP likes. We set this up in the --edit
-    line above, so now we just need to change the passphrase to make it
-    take effect. You can use the same passphrase if you like, or take
-    this opportunity to actually change it.
-
-    [H samp]
-       > passwd
-    [H /samp]
-
-    Save our work.
-
-    [H samp]
-       > save
-    [H /samp]
-
-    Now we can do the usual export:
-
-    [H samp]
-       $ gpg --export KeyID > mypublickey.pgp[H br]
-       $ gpg --export-secret-key KeyID > mysecretkey.pgp
-    [H /samp]
-
-    Thanks to David Shaw for this information!
-
-
-<S> PROBLEMS and ERROR MESSAGES
-
-<Q> Why do I get "gpg: Warning: using insecure memory!"
-
-    On many systems this program should be installed as setuid(root).
-    This is necessary to lock memory pages. Locking memory pages prevents
-    the operating system from writing them to disk and thereby keeping your
-    secret keys really secret. If you get no warning message about insecure
-    memory your operating system supports locking without being root. The
-    program drops root privileges as soon as locked memory is allocated.
-
-    To setuid(root) permissions on the gpg binary you can either use:
-
-    [H samp]
-       $ chmod u+s /path/to/gpg
-    [H /samp]
-
-    or
-
-    [H samp]
-       $ chmod 4755 /path/to/gpg
-    [H /samp]
-
-    Some refrain from using setuid(root) unless absolutely required for
-    security reasons. Please check with your system administrator if you
-    are not able to make these determinations yourself. 
-
-    On UnixWare 2.x and 7.x you should install GnuPG with the 'plock'
-    privilege to get the same effect:
-
-    [H samp]
-       $ filepriv -f plock /path/to/gpg
-    [H /samp]
-
-    If you can't or don't want to install GnuPG setuid(root), you can
-    use the option "--no-secmem-warning" or put:
-
-    [H samp]
-       no-secmem-warning
-    [H /samp]
-
-    in your ~/.gnupg/options or ~/.gnupg/gpg.conf file (this disables
-    the warning).
-
-    On some systems (e.g., Windows) GnuPG does not lock memory pages
-    and older GnuPG versions (<=1.0.4) issue the warning:
-
-    [H samp]
-       gpg: Please note that you don't have secure memory
-    [H /samp]
-
-    This warning can't be switched off by the above option because it
-    was thought to be too serious an issue. However, it confused users
-    too much, so the warning was eventually removed.
-
-<Q> Large File Support doesn't work ...
-
-    LFS works correctly in post-1.0.4 versions. If configure doesn't
-    detect it, try a different (i.e., better) compiler. egcs 1.1.2 works
-    fine, other gccs sometimes don't. BTW, several compilation problems
-    of GnuPG 1.0.3 and 1.0.4 on HP-UX and Solaris were due to broken LFS
-    support.
-
-<Q> In the edit menu the trust values are not displayed correctly after
-    signing uids. Why?
-
-    This happens because some information is stored immediately in
-    the trustdb, but the actual trust calculation can be done after the
-    save command. This is a "not easy to fix" design bug which will be
-    addressed in some future release.
-
-<Q> What does "skipping pubkey 1: already loaded" mean?
-
-    As of GnuPG 1.0.3, the RSA algorithm is included. If you still have
-    a "load-extension rsa" in your options file, the above message
-    occurs. Just remove the load command from the options file.
-
-<Q> GnuPG 1.0.4 doesn't create ~/.gnupg ...
-
-    That's a known bug, already fixed in newer versions.
-
-<Q> An Elgamal signature does not verify anymore since version 1.0.2 ...
-
-    Use the option --emulate-md-encode-bug.
-
-<Q> Old versions of GnuPG can't verify Elgamal signatures
-
-    Update to GnuPG 1.0.2 or newer.
-
-<Q> When I use --clearsign, the plain text has sometimes extra dashes
-    in it - why?
-
-    This is called dash-escaped text and is required by OpenPGP.
-    It always happens when a line starts with a dash ("-") and is
-    needed to make the lines that structure signature and text
-    (i.e., "-----BEGIN PGP SIGNATURE-----") to be the only lines
-    that start with two dashes.
-
-    If you use GnuPG to process those messages, the extra dashes
-    are removed. Good mail clients remove those extra dashes when
-    displaying such a message.      
-
-<Q> What is the thing with "can't handle multiple signatures"?
-
-    Due to different message formats GnuPG is not always able to split
-    a file with multiple signatures unambiguously into its parts. This
-    error message informs you that there is something wrong with the input.
-
-    The only way to have multiple signatures in a file is by using the
-    OpenPGP format with one-pass-signature packets (which is GnuPG's
-    default) or the cleartext signed format.
-
-<Q> If I submit a key to a keyserver, nothing happens ...
-
-    You are most likely using GnuPG 1.0.2 or older on Windows. That's
-    feature isn't yet implemented, but it's a bug not to say it. Newer
-    versions issue a warning. Upgrade to 1.4.5 or newer.
-
-<Q> I get "gpg: waiting for lock ..."
-
-    A previous instance of gpg has most likely exited abnormally and left
-    a lock file. Go to ~/.gnupg and look for .*.lock files and remove them.
-
-<Q> Older gpg binaries (e.g., 1.0) have problems with keys from newer
-    gpg binaries ...
-
-    As of 1.0.3, keys generated with gpg are created with preferences to
-    TWOFISH (and AES since 1.0.4) and that also means that they have the
-    capability to use the new MDC encryption method. This will go into
-    OpenPGP soon, and is also suppoted by PGP 7. This new method avoids
-    a (not so new) attack on all email encryption systems.
-
-    This in turn means that pre-1.0.3 gpg binaries have problems with
-    newer keys. Because of security and bug fixes, you should keep your
-    GnuPG installation in a recent state anyway. As a workaround, you can
-    force gpg to use a previous default cipher algo by putting:
-
-    [H samp]
-       cipher-algo cast5
-    [H /samp]
-
-    into your options file.
-
-<Q> With 1.0.4, I get "this cipher algorithm is deprecated ..."
-
-    If you just generated a new key and get this message while
-    encrypting, you've witnessed a bug in 1.0.4. It uses the new AES
-    cipher Rijndael that is incorrectly being referred as "deprecated".
-    Ignore this warning, more recent versions of gpg are corrected.
-
-<Q> Some dates are displayed as ????-??-??. Why?
-
-    Due to constraints in most libc implementations, dates beyond
-    2038-01-19 can't be displayed correctly. 64-bit OSes are not
-    affected by this problem. To avoid printing wrong dates, GnuPG
-    instead prints some question marks. To see the correct value, you
-    can use the options --with-colons and --fixed-list-mode.
-
-<Q> I still have a problem. How do I report a bug?
-
-    Are you sure that it's not been mentioned somewhere on the mailing
-    lists? Did you have a look at the bug list (you'll find a link to
-    the list of reported bugs on the documentation page). If you're not
-    sure about it being a bug, you can send mail to the gnupg-devel
-    list. Otherwise, use the bug tracking system 
-    [H a href=http://bugs.gnupg.org]<http://bugs.gnupg.org>[H /a].
-
-<Q> Why doesn't GnuPG support X.509 certificates?
-
-    That is only the case for GnuPG version 1.x.  GnuPG 2.x fully
-    supports X.509 and S/MIME using the gpgsm tool.
-
-<Q> Why do national characters in my user ID look funny?
-
-    According to OpenPGP, GnuPG encodes user ID strings (and other
-    things) using UTF-8. In this encoding of Unicode, most national
-    characters get encoded as two- or three-byte sequences. For
-    example, &aring; (0xE5 in ISO-8859-1) becomes &Atilde;&yen; (0xC3,
-    0xA5). This might also be the reason why keyservers can't find
-    your key.
-
-<Q> I get 'sed' errors when running ./configure on Mac OS X ...
-
-    This will be fixed after GnuPG has been upgraded to autoconf-2.50.
-    Until then, find the line setting CDPATH in the configure script
-    and place an:
-
-    [H samp]
-       unset CDPATH
-    [H /samp]
-
-    statement below it.
-
-<Q> Why does GnuPG 1.0.6 bail out on keyrings used with 1.0.7?
-
-    There is a small bug in 1.0.6 which didn't parse trust packets
-    correctly. You may want to apply this patch if you can't upgrade:
-
-    [H a href=http://www.gnupg.org/developer/gpg-woody-fix.txt]<http://www.gnupg.org/developer/gpg-woody-fix.txt>[H /a]
-
-<Q> I upgraded to GnuPG version 1.0.7 and now it takes longer to load my
-    keyrings. What can I do?
-
-    The way signature states are stored has changed so that v3 signatures
-    can be supported. You can use the new --rebuild-keydb-caches migration
-    command, which was built into this release and increases the speed of
-    many operations for existing keyrings.
-
-<Q> Doesn't a fully trusted user ID on a key prevent warning messages
-    when encrypting to other IDs on the key?
-
-    No. That was actually a key validity bug in GnuPG 1.2.1 and earlier
-    versions. As part of the development of GnuPG 1.2.2, a bug was
-    discovered in the key validation code.  This bug causes keys with
-    more than one user ID to give all user IDs on the key the amount of
-    validity given to the most-valid key. The bug has been fixed in GnuPG
-    release 1.2.2, and upgrading is the recommended fix for this problem.
-    More information and a patch for a some pre-1.2.2 versions of GnuPG
-    can be found at:
-
-    [H a href=http://lists.gnupg.org/pipermail/gnupg-announce/2003q2/000268.html]<http://lists.gnupg.org/pipermail/gnupg-announce/2003q2/000268.html>[H /a]
-
-<Q> I just compiled GnuPG from source on my GNU/Linux RPM-based system
-    and it's not working. Why?
-
-    Many GNU/Linux distributions that are RPM-based will install a
-    version of GnuPG as part of its standard installation, placing the
-    binaries in the /usr/bin directory. Later, compiling and installing
-    GnuPG from source other than from a source RPM won't normally
-    overwrite these files, as the default location for placement of
-    GnuPG binaries is in /usr/local/bin unless the '--prefix' switch
-    is used during compile to specify an alternate location. Since the
-    /usr/bin directory more than likely appears in your path before
-    /usr/local/bin, the older RPM-version binaries will continue to
-    be used when called since they were not replaced.
-
-    To resolve this, uninstall the RPM-based version with 'rpm -e gnupg'
-    before installing the binaries compiled from source. If dependency
-    errors are displayed when attempting to uninstall the RPM (such as
-    when Red Hat's up2date is also installed, which uses GnuPG), uninstall
-    the RPM with 'rpm -e gnupg --nodeps' to force the uninstall. Any
-    dependent files should be automatically replaced during the install
-    of the compiled version. If the default /usr/local/bin directory is
-    used, some packages such as SuSE's Yast Online Update may need to be
-    configured to look for GnuPG binaries in the /usr/local/bin directory,
-    or symlinks can be created in /usr/bin that point to the binaries
-    located in /usr/local/bin.
-
-
-<S> ADVANCED TOPICS
-
-<Q> How does this whole thing work?
-
-    To generate a secret/public keypair, run:
-
-    [H samp]
-       $ gpg --gen-key
-    [H /samp]
-
-    and choose the default values.
-
-    Data that is encrypted with a public key can only be decrypted by
-    the matching secret key. The secret key is protected by a password,
-    the public key is not.
-
-    So to send your friend a message, you would encrypt your message
-    with his public key, and he would only be able to decrypt it by
-    having the secret key and putting in the password to use his secret
-    key.
-
-    GnuPG is also useful for signing things. Files that are encrypted
-    with the secret key can be decrypted with the public key. To sign
-    something, a hash is taken of the data, and then the hash is in some
-    form encoded with the secret key. If someone has your public key, they
-    can verify that it is from you and that it hasn't changed by checking
-    the encoded form of the hash with the public key.
-
-    A keyring is just a large file that stores keys. You have a public
-    keyring where you store yours and your friend's public keys. You have
-    a secret keyring that you keep your secret key on, and should be very
-    careful with. Never ever give anyone else access to it and use a *good*
-    passphrase to protect the data in it.
-
-    You can 'conventionally' encrypt something by using the option 'gpg -c'.
-    It is encrypted using a passphrase, and does not use public and secret
-    keys. If the person you send the data to knows that passphrase, they
-    can decrypt it. This is usually most useful for encrypting things to
-    yourself, although you can encrypt things to your own public key in the
-    same way. It should be used for communication with partners you know
-    and where it is easy to exchange the passphrases (e.g. with your boy
-    friend or your wife). The advantage is that you can change the
-    passphrase from time to time and decrease the risk, that many old
-    messages may be decrypted by people who accidently got your passphrase.
-
-    You can add and copy keys to and from your keyring with the 'gpg
-    --import' and 'gpg --export' command. 'gpg --export-secret-keys' will
-    export secret keys. This is normally not useful, but you can generate
-    the key on one machine then move it to another machine.
-
-    Keys can be signed under the 'gpg --edit-key' option. When you sign a
-    key, you are saying that you are certain that the key belongs to the
-    person it says it comes from. You should be very sure that is really
-    that person: You should verify the key fingerprint with:
-
-    [H samp]
-       $ gpg --fingerprint KeyID
-    [H /samp]
-
-    over the phone (if you really know the voice of the other person), at
-    a key signing party (which are often held at computer conferences),
-    or at a meeting of your local GNU/Linux User Group.
-
-    Hmm, what else. You may use the option '-o filename' to force output
-    to this filename (use '-' to force output to stdout). '-r' just lets
-    you specify the recipient (which public key you encrypt with) on the
-    command line instead of typing it interactively.
-
-    Oh yeah, this is important. By default all data is encrypted in some
-    weird binary format. If you want to have things appear in ASCII text
-    that is readable, just add the '-a' option. But the preferred method
-    is to use a MIME aware mail reader (Mutt, Pine and many more).
-
-    There is a small security glitch in the OpenPGP (and therefore GnuPG)
-    system; to avoid this you should always sign and encrypt a message
-    instead of only encrypting it.
-
-<Q> Why are some signatures with an ELG-E key valid?
-
-    These are Elgamal keys generated by GnuPG in v3 (RFC 1991) packets.
-    The OpenPGP draft later changed the algorithm identifier for Elgamal
-    keys which are usable for signatures and encryption from 16 to 20.
-    GnuPG now uses 20 when it generates new Elgamal keys but still
-    accepts 16 (which is according to OpenPGP "encryption only") if this
-    key is in a v3 packet. GnuPG is the only program which had used
-    these v3 Elgamal keys - so this assumption is quite safe.
-
-<Q> How does the whole trust thing work?
-
-    It works more or less like PGP. The difference is that the trust is
-    computed at the time it is needed. This is one of the reasons for
-    the trustdb which holds a list of valid key signatures. If you are
-    not running in batch mode you will be asked to assign a trust
-    parameter (ownertrust) to a key.
-
-    You can see the validity (calculated trust value) using this
-    command.
-
-    [H samp]
-       $ gpg --list-keys --with-colons
-    [H /samp] 
-
-    If the first field is "pub" or "uid", the second field shows you the
-    trust:
-
-    [H pre]
-       o = Unknown (this key is new to the system)
-       e = The key has expired
-       q = Undefined (no value assigned)
-       n = Don't trust this key at all
-       m = There is marginal trust in this key
-       f = The key is full trusted
-       u = The key is ultimately trusted; this is only used
-           for keys for which the secret key is also available.
-       r = The key has been revoked
-       d = The key has been disabled
-    [H /pre]
-
-    The value in the "pub" record is the best one of all "uid" records.
-    You can get a list of the assigned trust values (how much you trust
-    the owner to correctly sign another person's key) with:
-
-    [H samp]
-       $ gpg --list-ownertrust
-    [H /samp]
-
-    The first field is the fingerprint of the primary key, the second
-    field is the assigned value:
-
-    [H pre]
-       - = No ownertrust value yet assigned or calculated.
-       n = Never trust this keyholder to correctly verify others signatures.
-       m = Have marginal trust in the keyholders capability to sign other
-           keys.
-       f = Assume that the key holder really knows how to sign keys.
-       u = No need to trust ourself because we have the secret key.
-    [H /pre]
-
-    Keep these values confidential because they express your opinions
-    about others. PGP stores this information with the keyring thus it
-    is not a good idea to publish a PGP keyring instead of exporting the
-    keyring. GnuPG stores the trust in the trustdb.gpg file so it is okay
-    to give a gpg keyring away (but we have a --export command too).
-
-<Q> What kind of output is this: "key C26EE891.298, uid 09FB: ...."?
-
-    This is the internal representation of a user ID in the trustdb.
-    "C26EE891" is the keyid, "298" is the local ID (a record number in
-    the trustdb) and "09FB" is the last two bytes of a ripe-md-160 hash
-    of the user ID for this key.
-
-<Q> How do I interpret some of the informational outputs?
-
-    While checking the validity of a key, GnuPG sometimes prints some
-    information which is prefixed with information about the checked
-    item.
-
-    [H samp]
-       "key 12345678.3456"
-    [H /samp]
-
-    This is about the key with key ID 12345678 and the internal number
-    3456, which is the record number of the so called directory record
-    in the trustdb.
-
-    [H samp]
-       "uid 12345678.3456/ACDE"
-    [H /samp]
-
-    This is about the user ID for the same key. To identify the user ID
-    the last two bytes of a ripe-md-160 over the user ID ring is printed.
-
-    [H samp]
-       "sig 12345678.3456/ACDE/9A8B7C6D"
-    [H /samp]
-
-    This is about the signature with key ID 9A8B7C6D for the above key
-    and user ID, if it is a signature which is direct on a key, the user
-    ID part is empty (..//..).
-
-<Q> Are the header lines of a cleartext signature part of the signed
-    material?
-
-    No. For example you can add or remove "Comment:" lines. They have
-    a purpose like the mail header lines. However a "Hash:" line is
-    needed for OpenPGP signatures to tell the parser which hash
-    algorithm to use.
-
-<Q> What is the list of preferred algorithms?
-
-    The list of preferred algorithms is a list of cipher, hash and
-    compression algorithms stored in the self-signature of a key during
-    key generation. When you encrypt a document, GnuPG uses this list
-    (which is then part of a public key) to determine which algorithms
-    to use. Basically it tells other people what algorithms the
-    recipient is able to handle and provides an order of preference.
-
-<Q> How do I change the list of preferred algorithms?
-
-    In version 1.0.7 or later, you can use the edit menu and set the
-    new list of preference using the command "setpref"; the format of
-    this command resembles the output of the command "pref". The
-    preference is not changed immediately but the set preference will
-    be used when a new user ID is created. If you want to update the
-    preferences for existing user IDs, select those user IDs (or select
-    none to update all) and enter the command "updpref". Note that the
-    timestamp of the self-signature is increased by one second when
-    running this command.
-
-<Q> How can I import all the missing signer keys?
-
-    If you imported a key and you want to also import all the signer's
-    keys, you can do this with this command:
-
-      gpg --check-sigs --with-colon KEYID \
-        | awk -F: '$1 == "sig" && $2 == "?"  { print $5 }' \
-        | sort | uniq | xargs echo gpg --recv-keys
-
-    Note that the invocation of sort is also required to wait for the
-    of the listing before before starting the import.
-
-
-<S> ACKNOWLEDGEMENTS
-
-    Many thanks to Nils Ellmenreich for maintaining this FAQ file for
-    such a long time, Werner Koch for the original FAQ file, and to all
-    posters to gnupg-users and gnupg-devel. They all provided most of
-    the answers.
-
-    Also thanks to Casper Dik for providing us with a script to generate
-    this FAQ (he uses it for the excellent Solaris2 FAQ).
-
-[H hr]
-
-Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
-
-Verbatim copying and distribution of this entire article is permitted in
-any medium, provided this notice is preserved.
diff --git a/doc/gnupg-logo-tr.png b/doc/gnupg-logo-tr.png
new file mode 100644 (file)
index 0000000..af21af9
Binary files /dev/null and b/doc/gnupg-logo-tr.png differ
index 84a3470..a2aab4a 100644 (file)
Binary files a/doc/gnupg-logo.pdf and b/doc/gnupg-logo.pdf differ
index 73cf00a..a1556df 100644 (file)
Binary files a/doc/gnupg-logo.png and b/doc/gnupg-logo.png differ
index 7bb54af..875b8e4 100644 (file)
@@ -5,12 +5,12 @@
 @settitle Using the GNU Privacy Guard
 
 @c A couple of macros with no effect on texinfo
-@c but used by the yat2m processor. 
+@c but used by the yat2m processor.
 @macro manpage {a}
 @end macro
 @macro mansect {a}
 @end macro
-@macro manpause 
+@macro manpause
 @end macro
 @macro mancont
 @end macro
@@ -29,12 +29,13 @@ This is the @cite{The GNU Privacy Guard Manual} (version
 @value{VERSION}, @value{UPDATED-MONTH}).
 
 @iftex
-Published by the Free Software Foundation@*
-51 Franklin St, Fifth Floor@*
-Boston, MA 02110-1301 USA
+Published by The GnuPG Project@*
+@url{https://gnupg.org}@*
+(or @url{http://ic6au7wa3f6naxjq.onion})
 @end iftex
 
-Copyright @copyright{} 2002, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.
+@copyright{} 2002, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.@*
+@copyright{} 2013, 2014 Werner Koch.
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -92,11 +93,11 @@ section entitled ``Copying''.
 
 @sp 3
 
-@image{gnupg-logo,16cm,,The GnuPG Logo}
+@image{gnupg-logo,,,The GnuPG Logo}
 
 @sp 3
 
-@author Werner Koch (@email{wk@@gnupg.org})
+@author The GnuPG Project (@url{https://gnupg.org})
 
 @page
 @vskip 0pt plus 1filll
@@ -110,12 +111,12 @@ section entitled ``Copying''.
 @end ifnothtml
 
 @ifhtml
-@center @image{gnupg-logo,6cm,,The GnuPG Logo}
+@center @image{gnupg-logo-tr,6cm,,The GnuPG Logo}
 @end ifhtml
 
 @ifnottex
 @node Top
-@top 
+@top
 @insertcopying
 
 This manual documents how to use the GNU Privacy Guard system as well as
@@ -207,14 +208,14 @@ the administration and the architecture.
 
 @c @node History
 @c @unnumbered History
-@c 
-@c Here are the notices from the old dirmngr manual: 
+@c
+@c Here are the notices from the old dirmngr manual:
 @c
 @c @itemize
 @c @item Using DirMngr, 2002, Steffen Hansen, Klar"alvdalens Datakonsult AB.
 @c @item Using DirMngr, 2004, 2005, 2006, 2008 Werner Koch, g10 Code GmbH.
 @c @end itemize
-@c 
+@c
 
 
 @bye
index 9f20704..a4079d7 100644 (file)
@@ -53,10 +53,10 @@ independently from any protocol.  It is used as a backend for
 utilities.
 
 @ifset gpgtwoone
-The agent is usualy started on demand by @command{gpg}, @command{gpgsm},
-@command{gpgconf} or @command{gpg-connect-agent}.  Thus there is no
-reason to start it manually.  In case you want to use the included
-Secure Shell Agent you may start the agent using:
+The agent is automatically started on demand by @command{gpg},
+@command{gpgsm}, @command{gpgconf}, or @command{gpg-connect-agent}.
+Thus there is no reason to start it manually.  In case you want to use
+the included Secure Shell Agent you may start the agent using:
 
 @example
 gpg-connect-agent /bye
@@ -174,11 +174,15 @@ default mode is to create a socket and listen for commands there.
 @item --daemon [@var{command line}]
 @opindex daemon
 Start the gpg-agent as a daemon; that is, detach it from the console
-and run it in the background.  Because @command{gpg-agent} prints out
+and run it in the background.
+@ifclear gpgtwoone
+Because @command{gpg-agent} prints out
 important information required for further use, a common way of
 invoking gpg-agent is: @code{eval $(gpg-agent --daemon)} to setup the
 environment variables.  The option @option{--write-env-file} is
-another way commonly used to do this.  Yet another way is creating
+another way commonly used to do this.
+@end ifclear
+Yet another way is creating
 a new process as a child of gpg-agent: @code{gpg-agent --daemon
 /bin/sh}.  This way you get a new shell with the environment setup
 properly; if you exit from this shell, gpg-agent terminates as well.
@@ -289,6 +293,14 @@ When running in server mode, wait @var{n} seconds before entering the
 actual processing loop and print the pid.  This gives time to attach a
 debugger.
 
+@item --debug-quick-random
+@opindex debug-quick-random
+This option inhibits the use the very secure random quality level
+(Libgcrypt’s @code{GCRY_VERY_STRONG_RANDOM}) and degrades all request
+down to standard random quality.  It is only used for testing and
+shall not be used for any production quality keys.  This option is
+only effective when given on the command line.
+
 @item --no-detach
 @opindex no-detach
 Don't detach the process from the console.  This is mainly useful for
@@ -305,6 +317,7 @@ shell or the C-shell respectively.  The default is to guess it based on
 the environment variable @code{SHELL} which is correct in almost all
 cases.
 
+@ifclear gpgtwoone
 @item --write-env-file @var{file}
 @opindex write-env-file
 Often it is required to connect to the agent from a process not being an
@@ -319,7 +332,7 @@ to be evaluated by a Bourne shell like in this simple example:
 eval $(cat @var{file})
 eval $(cut -d= -f 1 < @var{file} | xargs echo export)
 @end example
-
+@end ifclear
 
 
 @item --no-grab
@@ -344,6 +357,12 @@ Allow clients to mark keys as trusted, i.e. put them into the
 @file{trustlist.txt} file.  This is by default not allowed to make it
 harder for users to inadvertently accept Root-CA keys.
 
+@anchor{option --allow-preset-passphrase}
+@item --allow-preset-passphrase
+@opindex allow-preset-passphrase
+This option allows the use of @command{gpg-preset-passphrase} to seed the
+internal cache of @command{gpg-agent} with passphrases.
+
 @ifset gpgtwoone
 @anchor{option --allow-loopback-pinentry}
 @item --allow-loopback-pinentry
@@ -352,17 +371,6 @@ Allow clients to use the loopback pinentry features; see the option
 @option{pinentry-mode} for details.
 @end ifset
 
-@item --no-allow-external-cache
-@opindex no-allow-external-cache
-Tell Pinentry not to enable features which use an external cache for
-passphrases.
-
-Some desktop environments prefer to unlock all
-credentials with one master password and may have installed a Pinentry
-which employs an additional external cache to implement such a policy.
-By using this option the Pinentry is advised not to make use of such a
-cache and instead always ask the user for the requested passphrase.
-
 @item --ignore-cache-for-signing
 @opindex ignore-cache-for-signing
 This option will let @command{gpg-agent} bypass the passphrase cache for all
@@ -477,6 +485,11 @@ debugging purposes.
 @itemx --no-use-standard-socket
 @opindex use-standard-socket
 @opindex no-use-standard-socket
+@ifset gpgtwoone
+Since GnuPG 2.1 the standard socket is always used.  These options
+have no more effect.
+@end ifset
+@ifclear gpgtwoone
 By enabling this option @command{gpg-agent} will listen on the socket
 named @file{S.gpg-agent}, located in the home directory, and not create
 a random socket below a temporary directory.  Tools connecting to
@@ -485,19 +498,16 @@ environment variable @var{GPG_AGENT_INFO} and then fall back to this
 socket.  This option may not be used if the home directory is mounted on
 a remote file system which does not support special files like fifos or
 sockets.
-@ifset gpgtwoone
-Note, that @option{--use-standard-socket} is the default on all
-systems since GnuPG 2.1.
-@end ifset
-@ifclear gpgtwoone
+
 Note, that @option{--use-standard-socket} is the default on
 Windows systems.
-@end ifclear
+
 The default may be changed at build time.  It is
 possible to test at runtime whether the agent has been configured for
 use with the standard socket by issuing the command @command{gpg-agent
 --use-standard-socket-p} which returns success if the standard socket
 option has been enabled.
+@end ifclear
 
 @item --display @var{string}
 @itemx --ttyname @var{string}
@@ -608,7 +618,8 @@ agent. By default they may all be found in the current home directory
   Here is an example where two keys are marked as ultimately trusted
   and one as not trusted:
 
-  @example
+  @cartouche
+  @smallexample
   # CN=Wurzel ZS 3,O=Intevation GmbH,C=DE
   A6935DD34EF3087973C706FC311AA2CCF733765B S
 
@@ -617,7 +628,8 @@ agent. By default they may all be found in the current home directory
 
   # CN=Root-CA/O=Schlapphuete/L=Pullach/C=DE
   !14:56:98:D3:FE:9C:CA:5A:31:6E:BC:81:D3:11:4E:00:90:A3:44:C2 S
-  @end example
+  @end smallexample
+  @end cartouche
 
 Before entering a key into this file, you need to ensure its
 authenticity.  How to do this depends on your organisation; your
@@ -680,11 +692,13 @@ The following example lists exactly one key.  Note that keys available
 through a OpenPGP smartcard in the active smartcard reader are
 implicitly added to this list; i.e. there is no need to list them.
 
-  @example
-  # Key added on: 2011-07-20 20:38:46
-  # Fingerprint:  5e:8d:c4:ad:e7:af:6e:27:8a:d6:13:e4:79:ad:0b:81
-  34B62F25E277CF13D3C6BCEBFD3F85D08F0A864B 0 confirm
-  @end example
+@cartouche
+@smallexample
+       # Key added on: 2011-07-20 20:38:46
+       # Fingerprint:  5e:8d:c4:ad:e7:af:6e:27:8a:d6:13:e4:79:ad:0b:81
+       34B62F25E277CF13D3C6BCEBFD3F85D08F0A864B 0 confirm
+@end smallexample
+@end cartouche
 
 @item private-keys-v1.d/
 
@@ -724,7 +738,6 @@ again.  Only certain options are honored: @code{quiet},
 @code{verbose}, @code{debug}, @code{debug-all}, @code{debug-level},
 @code{no-grab}, @code{pinentry-program}, @code{default-cache-ttl},
 @code{max-cache-ttl}, @code{ignore-cache-for-signing},
-@code{no-allow-external-cache},
 @code{allow-mark-trusted}, @code{disable-scdaemon}, and
 @code{disable-check-own-socket}.  @code{scdaemon-program} is also
 supported but due to the current implementation, which calls the
@@ -759,6 +772,30 @@ This signal is used for internal purposes.
 @node Agent Examples
 @section Examples
 
+@ifset gpgtwoone
+It is important to set the GPG_TTY environment variable in
+your login shell, for example in the @file{~/.bashrc} init script:
+
+@cartouche
+@example
+  export GPG_TTY=$(tty)
+@end example
+@end cartouche
+
+If you enabled the Ssh Agent Support, you also need to tell ssh about
+it by adding this to your init script:
+
+@cartouche
+@example
+unset SSH_AGENT_PID
+if [ "$@{gnupg_SSH_AUTH_SOCK_by:-0@}" -ne $$ ]; then
+  export SSH_AUTH_SOCK="$@{HOME@}/.gnupg/S.gpg-agent.ssh"
+fi
+@end example
+@end cartouche
+@end ifset
+
+@ifclear gpgtwoone
 The usual way to invoke @command{gpg-agent} is
 
 @example
@@ -794,6 +831,7 @@ and add something like (for Bourne shells)
 
 @noindent
 to your shell initialization file (e.g. @file{~/.bashrc}).
+@end ifclear
 
 @c
 @c  Assuan Protocol
@@ -805,15 +843,21 @@ to your shell initialization file (e.g. @file{~/.bashrc}).
 Note: this section does only document the protocol, which is used by
 GnuPG components; it does not deal with the ssh-agent protocol.
 
+@ifset gpgtwoone
+The @command{gpg-agent} daemon is started on demand by the GnuPG
+components.
+@end ifset
+@ifclear gpgtwoone
 The @command{gpg-agent} should be started by the login shell and set an
 environment variable to tell clients about the socket to be used.
 Clients should deny to access an agent with a socket name which does
 not match its own configuration.  An application may choose to start
-an instance of the gpgagent if it does not figure that any has been
-started; it should not do this if a gpgagent is running but not
+an instance of the gpg-agent if it does not figure that any has been
+started; it should not do this if a gpg-agent is running but not
 usable.  Because @command{gpg-agent} can only be used in background mode, no
 special command line option is required to activate the use of the
 protocol.
+@end ifclear
 
 To identify a key we use a thing called keygrip which is the SHA-1 hash
 of an canonical encoded S-Expression of the public key as used in
@@ -904,8 +948,8 @@ If the decryption was successful the decrypted data is returned by
 means of "D" lines.
 
 Here is an example session:
-
-@example
+@cartouche
+@smallexample
    C: PKDECRYPT
    S: INQUIRE CIPHERTEXT
    C: D (enc-val elg (a 349324324)
@@ -915,7 +959,8 @@ Here is an example session:
    S: S PADDING 0
    S: D (value 1234567890ABCDEF0)
    S: OK descryption successful
-@end example
+@end smallexample
+@end cartouche
 
 The “PADDING” status line is only send if gpg-agent can tell what kind
 of padding is used.  As of now only the value 0 is used to indicate
@@ -949,10 +994,15 @@ must be given.  Valid names for <name> are:
 
 @table @code
 @item sha1
+The SHA-1 hash algorithm
 @item sha256
+The SHA-256 hash algorithm
 @item rmd160
+The RIPE-MD160 hash algorithm
 @item md5
+The old and broken MD5 hash algorithm
 @item tls-md5sha1
+A combined hash algorithm as used by the TLS protocol.
 @end table
 
 @noindent
@@ -989,8 +1039,8 @@ caching.
 
 
 Here is an example session:
-
-@example
+@cartouche
+@smallexample
    C: SIGKEY <keyGrip>
    S: OK key available
    C: SIGKEY <keyGrip>
@@ -1004,8 +1054,8 @@ Here is an example session:
    S: # signature follows
    S: D (sig-val rsa (s 45435453654612121212))
    S: OK
-@end example
-
+@end smallexample
+@end cartouche
 
 @node Agent GENKEY
 @subsection Generating a Key
@@ -1055,8 +1105,8 @@ like S-Expression like this:
 @end example
 
 Here is an example session:
-
-@example
+@cartouche
+@smallexample
    C: GENKEY
    S: INQUIRE KEYPARM
    C: D (genkey (rsa (nbits  1024)))
@@ -1064,7 +1114,8 @@ Here is an example session:
    S: D (public-key
    S: D   (rsa (n 326487324683264) (e 10001)))
    S  OK key created
-@end example
+@end smallexample
+@end cartouche
 
 @ifset gpgtwoone
 The @option{--no-protection} option may be used to prevent prompting for a
@@ -1177,12 +1228,14 @@ Replaced by a single @code{@@}
 @subsection Ask for a passphrase
 
 This function is usually used to ask for a passphrase to be used for
-symmetric encryption, but may also be used by programs which need
+conventional encryption, but may also be used by programs which need
 special handling of passphrases.  This command uses a syntax which helps
 clients to use the agent with minimum effort.
 
 @example
-  GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] [--qualitybar] @var{cache_id} [@var{error_message} @var{prompt} @var{description}]
+  GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] \
+                 [--qualitybar] @var{cache_id}                \
+                 [@var{error_message} @var{prompt} @var{description}]
 @end example
 
 @var{cache_id} is expected to be a string used to identify a cached
index cde27a5..cfd46a6 100644 (file)
@@ -1,12 +1,11 @@
-@c Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ @c Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
 @c               2008, 2009, 2010 Free Software Foundation, Inc.
 @c This is part of the GnuPG manual.
 @c For copying conditions, see the file gnupg.texi.
 
-@c Note that we use this texinfo file for all versions of GnuPG: 1.4.x,
-@c 2.0 and 2.1.  The macro "gpgone" controls parts which are only valid
-@c for GnuPG 1.4, the macro "gpgtwoone" controls parts which are only
-@c valid for GnupG 2.1 and later.
+@c Note that we use this texinfo file for all GnuPG-2 branches.
+@c The macro "gpgtwoone" controls parts which are only
+@c valid for GnuPG 2.1 and later.
 
 @node Invoking GPG
 @chapter Invoking GPG
 @cindex command options
 @cindex options, GPG command
 
-@c Begin GnuPG 1.x specific stuff
-@ifset gpgone
-@macro gpgname
-gpg
-@end macro
-@manpage gpg.1
-@ifset manverb
-.B gpg
-\- OpenPGP encryption and signing tool
-@end ifset
+@c Begin algorithm defaults
 
-@mansect synopsis
-@ifset manverb
-.B  gpg
-.RB [ \-\-homedir
-.IR dir ]
-.RB [ \-\-options
-.IR file ]
-.RI [ options ]
-.I command
-.RI [ args ]
-@end ifset
+@ifclear gpgtwoone
+@set DEFSYMENCALGO CAST5
+@end ifclear
+
+@ifset gpgtwoone
+@set DEFSYMENCALGO AES128
 @end ifset
-@c End GnuPG 1.x specific stuff
 
-@c Begin GnuPG 2 specific stuff
-@ifclear gpgone
+@c End algorithm defaults
+
+
 @macro gpgname
 gpg2
 @end macro
@@ -61,8 +46,7 @@ gpg2
 .I command
 .RI [ args ]
 @end ifset
-@end ifclear
-@c Begin GnuPG 2 specific stuff
+
 
 @mansect description
 @command{@gpgname} is the OpenPGP part of the GNU Privacy Guard (GnuPG). It
@@ -71,28 +55,17 @@ OpenPGP standard. @command{@gpgname} features complete key management and
 all bells and whistles you can expect from a decent OpenPGP
 implementation.
 
-@ifset gpgone
-This is the standalone version of @command{gpg}.  For desktop use you
-should consider using @command{gpg2} @footnote{On some platforms gpg2 is
-installed under the name @command{gpg}}.
-@end ifset
-
-@ifclear gpgone
-In contrast to the standalone version @command{gpg}, which is more
-suited for server and embedded platforms, this version is commonly
-installed under the name @command{gpg2} and more targeted to the desktop
-as it requires several other modules to be installed.  The standalone
-version will be kept maintained and it is possible to install both
-versions on the same system.  If you need to use different configuration
-files, you should make use of something like @file{gpg.conf-2} instead
-of just @file{gpg.conf}.
-@end ifclear
+In contrast to the standalone command gpg from GnuPG 1.x, which is
+might be better suited for server and embedded platforms, the 2.x
+version is commonly installed under the name @command{gpg2} and
+targeted to the desktop as it requires several other modules to be
+installed.
 
 @manpause
-@ifclear gpgone
-Documentation for the old standard @command{gpg} is available as a man
-page and at @inforef{Top,GnuPG 1,gpg}.
-@end ifclear
+The old 1.x version will be kept maintained and it is possible to
+install both versions on the same system.  Documentation for the old
+GnuPG 1.x command is available as a man page and at
+@inforef{Top,GnuPG 1,gpg}.
 
 @xref{Option Index}, for an index to @command{@gpgname}'s commands and options.
 @mancont
@@ -217,7 +190,7 @@ decrypted via a secret key or a passphrase).
 @itemx -c
 @opindex symmetric
 Encrypt with a symmetric cipher using a passphrase. The default
-symmetric cipher used is CAST5, but may be chosen with the
+symmetric cipher used is @value{DEFSYMENCALGO}, but may be chosen with the
 @option{--cipher-algo} option. This option may be combined with
 @option{--sign} (for a signed and symmetrically encrypted message),
 @option{--encrypt} (for a message that may be decrypted via a secret key
@@ -287,12 +260,6 @@ Identical to @option{--multifile --decrypt}.
 @opindex list-keys
 List all keys from the public keyrings, or just the keys given on the
 command line.
-@ifset gpgone
-@option{-k} is slightly different from @option{--list-keys} in that it
-allows only for one argument and takes the second argument as the
-keyring to search.  This is for command line compatibility with PGP 2
-and has been removed in @command{gpg2}.
-@end ifset
 
 Avoid using the output of this command in scripts or other programs as
 it is likely to change as GnuPG changes. See @option{--with-colons} for a
@@ -310,10 +277,8 @@ secret key is not usable (for example, if it was created via
 @item --list-sigs
 @opindex list-sigs
 Same as @option{--list-keys}, but the signatures are listed too.
-@ifclear gpgone
 This command has the same effect as
 using @option{--list-keys} with @option{--with-sig-list}.
-@end ifclear
 
 For each signature listed, there are several flags in between the "sig"
 tag and keyid. These flags give additional information about each
@@ -333,10 +298,8 @@ command "tsign").
 Same as @option{--list-sigs}, but the signatures are verified.  Note
 that for performance reasons the revocation status of a signing key is
 not shown.
-@ifclear gpgone
 This command has the same effect as
 using @option{--list-keys} with @option{--with-sig-check}.
-@end ifclear
 
 The status of the verification is indicated by a flag directly following
 the "sig" tag (and thus before the flags described above for
@@ -345,7 +308,6 @@ successfully verified, a "-" denotes a bad signature and a "%" is used
 if an error occurred while checking the signature (e.g. a non supported
 algorithm).
 
-@ifclear gpgone
 @item --locate-keys
 @opindex locate-keys
 Locate the keys given as arguments.  This command basically uses the
@@ -353,8 +315,6 @@ same algorithm as used when locating keys for encryption or signing and
 may thus be used to see what keys @command{@gpgname} might use.  In
 particular external methods as defined by @option{--auto-key-locate} may
 be used to locate a key.  Only public keys are listed.
-@end ifclear
-
 
 @item --fingerprint
 @opindex fingerprint
@@ -376,7 +336,7 @@ useful for debugging.
 Present a menu to work with a smartcard. The subcommand "help" provides
 an overview on available commands. For a detailed description, please
 see the Card HOWTO at
-https://gnupg.org/documentation/howtos.html#GnuPG-cardHOWTO .
+http://www.gnupg.org/documentation/howtos.html#GnuPG-cardHOWTO .
 
 @item --card-status
 @opindex card-status
@@ -592,14 +552,36 @@ This section explains the main commands for key management
 
 @table @gnupgtabopt
 
+@ifset gpgtwoone
+@item --quick-gen-key @code{user-id}
+@opindex quick-gen-key
+This is simple command to generate a standard key with one user id.
+In contrast to @option{--gen-key} the key is generated directly
+without the need to answer a bunch of prompts.  Unless the option
+@option{--yes} is given, the key creation will be canceled if the
+given user id already exists in the key ring.
+
+If invoked directly on the console without any special options an
+answer to a ``Continue?'' style confirmation prompt is required.  In
+case the user id already exists in the key ring a second prompt to
+force the creation of the key will show up.
+@end ifset
+
 @item --gen-key
 @opindex gen-key
-Generate a new key pair. This command is normally only used
-interactively.
+Generate a new key pair using teh current default parameters.  This is
+the standard command to create a new key.
+
+@ifset gpgtwoone
+@item --full-gen-key
+@opindex gen-key
+Generate a new key pair with dialogs for all options.  This is an
+extended version of @option{--gen-key}.
 
-There is an experimental feature which allows you to create keys in
-batch mode. See the file @file{doc/DETAILS} in the source distribution
-on how to use this.
+@end ifset
+There is also a feature which allows you to create keys in batch
+mode. See the the manual section ``Unattended key generation'' on how
+to use this.
 
 @item --gen-revoke @code{name}
 @opindex gen-revoke
@@ -924,7 +906,7 @@ from @option{--edit-key}.
 
 @ifset gpgtwoone
 @item --quick-sign-key @code{fpr} [@code{names}]
-@itemx --quick-lsign-key @code{name}
+@itemx --quick-lsign-key @code{fpr} [@code{names}]
 @opindex quick-sign-key
 @opindex quick-lsign-key
 Directly sign a key from the passphrase without any further user
@@ -932,21 +914,21 @@ interaction.  The @code{fpr} must be the verified primary fingerprint
 of a key in the local keyring. If no @code{names} are given, all
 useful user ids are signed; with given [@code{names}] only useful user
 ids matching one of theses names are signed.  The command
-@option{--quick-lsign-key} marks the signatures as non-exportable.
+@option{--quick-lsign-key} marks the signatures as non-exportable.  If
+such a non-exportable signature already exists the
+@option{--quick-sign-key} turns it into a exportable signature.
 
 This command uses reasonable defaults and thus does not provide the
 full flexibility of the "sign" subcommand from @option{--edit-key}.
-Its intended use to help unattended signing using a list of verified
-fingerprints.
+Its intended use is to help unattended key signing by utilizing a list
+of verified fingerprints.
 @end ifset
 
-@ifclear gpgone
 @item --passwd @var{user_id}
 @opindex passwd
 Change the passphrase of the secret key belonging to the certificate
 specified as @var{user_id}.  This is a shortcut for the sub-command
 @code{passwd} of the edit key menu.
-@end ifclear
 
 @end table
 
@@ -1079,6 +1061,13 @@ give the opposite meaning.  The options are:
   see @option{--attribute-fd} for the appropriate way to get photo data
   for scripts and other frontends.
 
+  @item show-usage
+  @opindex list-options:show-usage
+  Show usage information for keys and subkeys in the standard key
+  listing.  This is a list of letters indicating the allowed usage for a
+  key (@code{E}=encryption, @code{S}=signing, @code{C}=certification,
+  @code{A}=authentication).  Defaults to no.
+
   @item show-policy-urls
   @opindex list-options:show-policy-urls
   Show policy URLs in the @option{--list-sigs} or @option{--check-sigs}
@@ -1251,7 +1240,13 @@ use the specified keyring alone, use @option{--keyring} along with
 
 @item --secret-keyring @code{file}
 @opindex secret-keyring
+@ifset gpgtwoone
+This is an obsolete option and ignored.  All secret keys are stored in
+the @file{private-keys-v1.d} directory below the GnuPG home directory.
+@end ifset
+@ifclear gpgtwoone
 Same as @option{--keyring} but for the secret keyrings.
+@end ifclear
 
 @item --primary-keyring @code{file}
 @opindex primary-keyring
@@ -1267,41 +1262,9 @@ the filename does not contain a slash, it is assumed to be in the GnuPG
 home directory (@file{~/.gnupg} if @option{--homedir} or $GNUPGHOME is
 not used).
 
-@ifset gpgone
-@anchor{option --homedir}
-@end ifset
 @include opt-homedir.texi
 
 
-@ifset gpgone
-@item --pcsc-driver @code{file}
-@opindex pcsc-driver
-Use @code{file} to access the smartcard reader. The current default is
-`libpcsclite.so.1' for GLIBC based systems,
-`/System/Library/Frameworks/PCSC.framework/PCSC' for MAC OS X,
-`winscard.dll' for Windows and `libpcsclite.so' for other systems.
-@end ifset
-
-@ifset gpgone
-@item --disable-ccid
-@opindex disable-ccid
-Disable the integrated support for CCID compliant readers. This
-allows to fall back to one of the other drivers even if the internal
-CCID driver can handle the reader. Note, that CCID support is only
-available if libusb was available at build time.
-@end ifset
-
-@ifset gpgone
-@item --reader-port @code{number_or_string}
-@opindex reader-port
-This option may be used to specify the port of the card terminal. A
-value of 0 refers to the first serial device; add 32768 to access USB
-devices. The default is 32768 (first USB device). PC/SC or CCID
-readers might need a string here; run the program in verbose mode to get
-a list of available readers. The default is then the first reader
-found.
-@end ifset
-
 @item --display-charset @code{name}
 @opindex display-charset
 Set the name of the native character set. This is used to convert
@@ -1461,7 +1424,7 @@ Set what trust model GnuPG should follow. The models are:
 
   @item classic
   @opindex trust-mode:classic
-  This is the standard Web of Trust as used in PGP 2.x and earlier.
+  This is the standard Web of Trust as introduced by PGP 2.
 
   @item direct
   @opindex trust-mode:direct
@@ -1471,7 +1434,7 @@ Set what trust model GnuPG should follow. The models are:
   @item always
   @opindex trust-mode:always
   Skip key validation and assume that used keys are always fully
-  trusted. You generally won't use this unless you are using some
+  valid. You generally won't use this unless you are using some
   external validation scheme. This option also suppresses the
   "[uncertain]" tag printed with signature checks when there is no
   evidence that the user ID is bound to the key.  Note that this
@@ -1719,7 +1682,12 @@ can be done if someone else has write access to your public keyring.
 
 @item --no-sig-create-check
 @opindex no-sig-create-check
-This option is obsolete.  It has no function.
+GnuPG normally verifies each signature right after creation to protect
+against bugs and hardware malfunctions which could leak out bits from
+the secret key. This extra verification needs some time (about 115%
+for DSA keys), and so this option can be used to disable it.
+However, due to the fact that the signature creation needs manual
+interaction, this performance penalty does not matter in most settings.
 
 @item --auto-check-trustdb
 @itemx --no-auto-check-trustdb
@@ -1732,33 +1700,22 @@ process. @option{--no-auto-check-trustdb} disables this option.
 @item --use-agent
 @itemx --no-use-agent
 @opindex use-agent
-@ifclear gpgone
 This is dummy option. @command{@gpgname} always requires the agent.
-@end ifclear
-@ifset gpgone
-Try to use the GnuPG-Agent.  With this option, GnuPG first tries to
-connect to the agent before it asks for a
-passphrase. @option{--no-use-agent} disables this option.
-@end ifset
 
 @item --gpg-agent-info
 @opindex gpg-agent-info
-@ifclear gpgone
 This is dummy option. It has no effect when used with @command{gpg2}.
-@end ifclear
-@ifset gpgone
-Override the value of the environment variable
-@samp{GPG_AGENT_INFO}. This is only used when @option{--use-agent} has
-been given.  Given that this option is not anymore used by
-@command{gpg2}, it should be avoided if possible.
-@end ifset
 
 
-@ifclear gpgone
 @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/bin/gpg-agent}.  This is only used
+default value is determined by running @command{gpgconf} with the
+option @option{--list-dirs}.  Note that the pipe symbol (@code{|}) is
+used for a regression test suite hack and may thus not be used in the
+file name.
+@ifclear gpgtwoone
+This is only used
 as a fallback when the environment variable @code{GPG_AGENT_INFO} is not
 set or a running agent cannot be connected.
 @end ifclear
@@ -2034,15 +1991,6 @@ opposite meaning. The options are:
   generally useful unless a shared keyring scheme is being used.
   Defaults to no.
 
-  @item import-keep-ownertrust
-  Normally possible still existing ownertrust values of a key are
-  cleared if a key is imported.  This is in general desirable so that
-  a formerly deleted key does not automatically gain an ownertrust
-  values merely due to import.  On the other hand it is sometimes
-  necessary to re-import a trusted set of keys again but keeping
-  already assigned ownertrust values.  This can be achived by using
-  this option.
-
   @item repair-pks-subkey-bug
   During import, attempt to repair the damage caused by the PKS keyserver
   bug (pre version 0.9.6) that mangles keys with multiple subkeys. Note
@@ -2133,10 +2081,8 @@ source distribution.
 @opindex fixed-list-mode
 Do not merge primary user ID and primary key in @option{--with-colon}
 listing mode and print all timestamps as seconds since 1970-01-01.
-@ifclear gpgone
 Since GnuPG 2.0.10, this mode is always used and thus this option is
 obsolete; it does not harm to use it though.
-@end ifclear
 
 @ifset gpgtwoone
 @item --legacy-list-mode
@@ -2186,14 +2132,7 @@ platforms that have different line ending conventions (UNIX-like to Mac,
 Mac to Windows, etc). @option{--no-textmode} disables this option, and
 is the default.
 
-@ifset gpgone
-If @option{-t} (but not @option{--textmode}) is used together with
-armoring and signing, this enables clearsigned messages. This kludge is
-needed for command-line compatibility with command-line versions of PGP;
-normally you would use @option{--sign} or @option{--clearsign} to select
-the type of the signature.
-@end ifset
-
+@ifclear gpgtwoone
 @item --force-v3-sigs
 @itemx --no-force-v3-sigs
 @opindex force-v3-sigs
@@ -2212,6 +2151,15 @@ Defaults to no.
 Always use v4 key signatures even on v3 keys. This option also
 changes the default hash algorithm for v3 RSA keys from MD5 to SHA-1.
 @option{--no-force-v4-certs} disables this option.
+@end ifclear
+
+@ifset gpgtwoone
+@item --force-v3-sigs
+@itemx --no-force-v3-sigs
+@item --force-v4-certs
+@itemx --no-force-v4-certs
+These options are obsolete and have no effect since GnuPG 2.1.
+@end ifset
 
 @item --force-mdc
 @opindex force-mdc
@@ -2261,9 +2209,9 @@ to consider (e.g. @option{--symmetric}).
 @item --s2k-cipher-algo @code{name}
 @opindex s2k-cipher-algo
 Use @code{name} as the cipher algorithm used to protect secret keys.
-The default cipher is CAST5. This cipher is also used for symmetric
-encryption with a passphrase if @option{--personal-cipher-preferences}
-and @option{--cipher-algo} is not given.
+The default cipher is @value{DEFSYMENCALGO}. This cipher is also used for
+conventional encryption if @option{--personal-cipher-preferences} and
+@option{--cipher-algo} is not given.
 
 @item --s2k-digest-algo @code{name}
 @opindex s2k-digest-algo
@@ -2276,7 +2224,7 @@ Selects how passphrases are mangled. If @code{n} is 0 a plain
 passphrase (which is not recommended) will be used, a 1 adds a salt to
 the passphrase and a 3 (the default) iterates the whole process a
 number of times (see --s2k-count).  Unless @option{--rfc1991} is used,
-this mode is also used for symmetric encryption with a passphrase.
+this mode is also used for conventional encryption.
 
 @item --s2k-count @code{n}
 @opindex s2k-count
@@ -2331,9 +2279,11 @@ behavior. Note that this is currently the same thing as
 Reset all packet, cipher and digest options to strict RFC-2440
 behavior.
 
+@ifclear gpgtowone
 @item --rfc1991
 @opindex rfc1991
-Try to be more RFC-1991 (PGP 2.x) compliant.
+Try to be more RFC-1991 (PGP 2.x) compliant.  This option is
+deprecated will be removed in GnuPG 2.1.
 
 @item --pgp2
 @opindex pgp2
@@ -2344,18 +2294,17 @@ a message that PGP 2.x will not be able to handle. Note that `PGP
 available, but the MIT release is a good common baseline.
 
 This option implies
-@ifset gpgone
-@option{--rfc1991 --disable-mdc --no-force-v4-certs
---escape-from-lines --force-v3-sigs
---cipher-algo IDEA --digest-algo MD5 --compress-algo ZIP}.
-@end ifset
-@ifclear gpgone
 @option{--rfc1991 --disable-mdc --no-force-v4-certs
---escape-from-lines --force-v3-sigs --allow-weak-digest-algos
---cipher-algo IDEA --digest-algo MD5 --compress-algo ZIP}.
-@end ifclear
+ --escape-from-lines  --force-v3-sigs --allow-weak-digest-algos
+ --cipher-algo IDEA --digest-algo MD5 --compress-algo ZIP}.
 It also disables @option{--textmode} when encrypting.
 
+This option is deprecated will be removed in GnuPG 2.1.  The reason
+for dropping PGP-2 support is that the PGP 2 format is not anymore
+considered safe (for example due to the use of the broken MD5 algorithm).
+Note that the decryption of PGP-2 created messages will continue to work.
+@end ifclear
+
 @item --pgp6
 @opindex pgp6
 Set up all options to be as PGP 6 compliant as possible. This
@@ -2365,8 +2314,12 @@ compression algorithms none and ZIP. This also disables
 --throw-keyids, and making signatures with signing subkeys as PGP 6
 does not understand signatures made by signing subkeys.
 
-This option implies @option{--disable-mdc --escape-from-lines
---force-v3-sigs}.
+@ifclear gpgtwoone
+This option implies @option{--disable-mdc --escape-from-lines --force-v3-sigs}.
+@end ifclear
+@ifset gpgtwoone
+This option implies @option{--disable-mdc --escape-from-lines}.
+@end ifset
 
 @item --pgp7
 @opindex pgp7
@@ -2448,6 +2401,13 @@ be given in C syntax (e.g. 0x0042).
 @opindex debug-all
 Set all useful debugging flags.
 
+@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.  Alternatively @var{epoch} may be given as a full ISO time string
+(e.g. "20070924T154812").
+
 @item --enable-progress-filter
 @opindex enable-progress-filter
 Enable certain PROGRESS status outputs. This option allows frontends
@@ -2504,9 +2464,9 @@ protected by the signature.
 @opindex emit-version
 Force inclusion of the version string in ASCII armored output.  If
 given once only the name of the program and the major number is
-emitted, given twice the minor is also emitted, given triple
+emitted (default), given twice the minor is also emitted, given triple
 the micro is added, and given quad an operating system identification
-is also emitted.  @option{--no-emit-version} (default) disables the version
+is also emitted.  @option{--no-emit-version} disables the version
 line.
 
 @item --sig-notation @code{name=value}
@@ -2690,10 +2650,9 @@ Read the passphrase from file descriptor @code{n}. Only the first line
 will be read from file descriptor @code{n}. If you use 0 for @code{n},
 the passphrase will be read from STDIN. This can only be used if only
 one passphrase is supplied.
-@ifclear gpgone
+
 Note that this passphrase is only used if the option @option{--batch}
-has also been given.  This is different from @command{gpg}.
-@end ifclear
+has also been given.  This is different from GnuPG version 1.x.
 
 @item --passphrase-file @code{file}
 @opindex passphrase-file
@@ -2702,10 +2661,8 @@ be read from file @code{file}. This can only be used if only one
 passphrase is supplied. Obviously, a passphrase stored in a file is
 of questionable security if other users can read this file. Don't use
 this option if you can avoid it.
-@ifclear gpgone
 Note that this passphrase is only used if the option @option{--batch}
-has also been given.  This is different from @command{gpg}.
-@end ifclear
+has also been given.  This is different from GnuPG version 1.x.
 
 @item --passphrase @code{string}
 @opindex passphrase
@@ -2713,10 +2670,8 @@ Use @code{string} as the passphrase. This can only be used if only one
 passphrase is supplied. Obviously, this is of very questionable
 security on a multi-user system. Don't use this option if you can
 avoid it.
-@ifclear gpgone
 Note that this passphrase is only used if the option @option{--batch}
-has also been given.  This is different from @command{gpg}.
-@end ifclear
+has also been given.  This is different from GnuPG version 1.x.
 
 @ifset gpgtwoone
 @item --pinentry-mode @code{mode}
@@ -2796,13 +2751,11 @@ necessary to get as much data as possible out of the corrupt message.
 However, be aware that a MDC protection failure may also mean that the
 message was tampered with intentionally by an attacker.
 
-@ifclear gpgone
 @item --allow-weak-digest-algos
 @opindex allow-weak-digest-algos
 Signatures made with the broken MD5 algorithm are normally rejected
 with an ``invalid digest algorithm'' message.  This option allows the
 verification of signatures made with such weak algorithms.
-@end ifclear
 
 @item --no-default-keyring
 @opindex no-default-keyring
@@ -2967,15 +2920,6 @@ on the configuration file.
 
 @table @gnupgtabopt
 
-@ifset gpgone
-@item --load-extension @code{name}
-@opindex load-extension
-Load an extension module. If @code{name} does not contain a slash it is
-searched for in the directory configured when GnuPG was built
-(generally "/usr/local/lib/gnupg"). Extensions are not generally
-useful anymore, and the use of this option is deprecated.
-@end ifset
-
 @item --show-photos
 @itemx --no-show-photos
 @opindex show-photos
@@ -2992,14 +2936,6 @@ Display the keyring name at the head of key listings to show which
 keyring a given key resides on. This option is deprecated: use
 @option{--list-options [no-]show-keyring} instead.
 
-@ifset gpgone
-@item --ctapi-driver @code{file}
-@opindex ctapi-driver
-Use @code{file} to access the smartcard reader. The current default
-is `libtowitoko.so'. Note that the use of this interface is
-deprecated; it may be removed in future releases.
-@end ifset
-
 @item --always-trust
 @opindex always-trust
 Identical to @option{--trust-model always}. This option is deprecated.
@@ -3054,10 +2990,8 @@ current home directory (@pxref{option --homedir}).
 Note that on larger installations, it is useful to put predefined files
 into the directory @file{/etc/skel/.gnupg/} so that newly created users
 start up with a working configuration.
-@ifclear gpgone
-For existing users the a small
+For existing users a small
 helper script is provided to create these files (@pxref{addgnupghome}).
-@end ifclear
 
 For internal purposes @command{@gpgname} creates and maintains a few other
 files; They all live in in the current home directory (@pxref{option
@@ -3105,6 +3039,16 @@ files; They all live in in the current home directory (@pxref{option
   @item ~/.gnupg/secring.gpg.lock
   The lock file for the secret keyring.
 
+  @item ~/.gnupg/openpgp-revocs.d/
+  This is the directory where gpg stores pre-generated revocation
+  certificates.  The file name corresponds to the OpenPGP fingerprint of
+  the respective key.  It is suggested to backup those certificates and
+  if the primary private key is not stored on the disk to move them to
+  an external storage device.  Anyone who can access theses files is
+  able to revoke the corresponding key.  You may want to print them out.
+  You should backup all files in this directory and take care to keep
+  this backup closed away.
+
   @item /usr[/local]/share/gnupg/options.skel
   The skeleton options file.
 
@@ -3125,15 +3069,18 @@ Operation is further controlled by a few environment variables:
   If set directory used instead of "~/.gnupg".
 
   @item GPG_AGENT_INFO
-  Used to locate the gpg-agent.
-@ifset gpgone
-  This is only honored when @option{--use-agent} is set.
+@ifset gpgtwoone
+  This variable was used by GnuPG versions before 2.1
 @end ifset
+@ifclear gpgtwoone
+  Used to locate the gpg-agent.
+
   The value consists of 3 colon delimited fields: The first is the path
   to the Unix Domain Socket, the second the PID of the gpg-agent and the
   protocol version which should be set to 1. When starting the gpg-agent
   as described in its documentation, this variable is set to the correct
   value. The option @option{--gpg-agent-info} can be used to override it.
+@end ifclear
 
   @item PINENTRY_USER_DATA
   This value is passed via gpg-agent to pinentry.  It is useful to convey
@@ -3365,12 +3312,18 @@ control statements must be given. For GnuPG 2.1 and later
 
 @item %ask-passphrase
 @itemx %no-ask-passphrase
+@ifclear gpgtwoone
 Enable (or disable) a mode where the command @option{passphrase} is
 ignored and instead the usual passphrase dialog is used.  This does
 not make sense for batch key generation; however the unattended key
 generation feature is also used by GUIs and this feature relinquishes
 the GUI from implementing its own passphrase entry code.  These are
 global control statements and affect all future key genrations.
+@end ifclear
+@ifset gpgtwoone
+This option is a no-op for GnuPG 2.1 and later.
+@end ifset
+
 
 @item %no-protection
 Since GnuPG version 2.1 it is not anymore possible to specify a
@@ -3454,7 +3407,7 @@ sense.  Although OpenPGP works with time intervals, GnuPG uses an
 absolute value internally and thus the last year we can represent is
 2105.
 
-@item Creation-Date: @var{iso-date}
+@item  Creation-Date: @var{iso-date}
 Set the creation date of the key as stored in the key information and
 which is also part of the fingerprint calculation.  Either a date like
 "1986-04-26" or a full timestamp like "19860426T042640" may be used.
@@ -3542,9 +3495,7 @@ these parameters:
 @mansect see also
 @ifset isman
 @command{gpgv}(1),
-@ifclear gpgone
 @command{gpgsm}(1),
 @command{gpg-agent}(1)
-@end ifclear
 @end ifset
 @include see-also-note.texi
index b0882b8..2ddedcd 100644 (file)
@@ -358,9 +358,14 @@ 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
+default value is determined by running the command @command{gpgconf}.
+Note that the pipe symbol (@code{|}) is used for a regression test
+suite hack and may thus not be used in the file name.
+@ifclear gpgtwoone
+This is only used
 as a fallback when the environment variable @code{GPG_AGENT_INFO} is not
 set or a running agent cannot be connected.
+@end ifclear
 
 @item --dirmngr-program @var{file}
 @opindex dirmngr-program
@@ -609,7 +614,7 @@ certificates starting with the signer cert.  The default is -2.
 Use the cipher algorithm with the ASN.1 object identifier @var{oid} for
 encryption.  For convenience the strings @code{3DES}, @code{AES} and
 @code{AES256} may be used instead of their OIDs.  The default is
-@code{AES} (2.16.840.1.101.3.4.1.2).
+@code{3DES} (1.2.840.113549.3.7).
 
 @item --digest-algo @code{name}
 Use @code{name} as the message digest algorithm.  Usually this
@@ -892,8 +897,12 @@ other programs of this software too.
 
 @item S.gpg-agent
 @cindex S.gpg-agent
-If this file exists and the environment variable @env{GPG_AGENT_INFO} is
-not set, @command{gpgsm} will first try to connect to this socket for
+If this file exists
+@ifclear gpgtwoone
+and the environment variable @env{GPG_AGENT_INFO} is
+not set,
+@end ifclear
+@command{gpgsm} will first try to connect to this socket for
 accessing @command{gpg-agent} before starting a new @command{gpg-agent}
 instance.  Under Windows this socket (which in reality be a plain file
 describing a regular TCP listening port) is the standard way of
@@ -991,7 +1000,7 @@ only create a CSR.
 
 The command @option{--gen-key} may be used along with the option
 @option{--batch} to either create a certificate signing request (CSR)
-or an X.509 certificate. The is controlled by a parameter file; the
+or an X.509 certificate.  This is controlled by a parameter file; the
 format of this file is as follows:
 
 @itemize @bullet
@@ -1127,7 +1136,7 @@ keygrip with a @samp{&}.
 Use @var{hash-algo} for this CSR or certificate.  The supported hash
 algorithms are: @samp{sha1}, @samp{sha256}, @samp{sha384} and
 @samp{sha512}; they may also be specified with uppercase letters.  The
-default is @samp{sha256}.
+default is @samp{sha1}.
 
 @end table
 
index b6047f4..0cb2360 100644 (file)
@@ -62,10 +62,15 @@ the public keys used to make the signature are valid. There are
 no configuration files and only a few options are implemented.
 
 @code{@gpgvname} assumes that all keys in the keyring are trustworthy.
-By default it uses a keyring named @file{trustedkeys.gpg} which is
-assumed to be in the home directory as defined by GnuPG or set by an
-option or an environment variable. An option may be used to specify
-another keyring or even multiple keyrings.
+That does also mean that it does not check for expired or revoked
+keys.
+
+By default a keyring named @file{trustedkeys.gpg} is used.  This
+default keyring is assumed to be in the home directory of GnuPG,
+either the default home directory or the one set by an option or an
+environment variable.  The option @code{--keyring} may be used to
+specify a different keyring or even multiple keyrings.
+
 
 @noindent
 @mansect options
index 5a98cb3..bd4ae14 100644 (file)
@@ -1,6 +1,5 @@
-# help.ru.txt - Russian GnuPG online help
+# help.ru.txt - ru GnuPG online help
 # Copyright (C) 2007 Free Software Foundation, Inc.
-# Copyright (C) 2016 Ineiev <ineiev@gnu.org> (translation)
 #
 # This file is part of GnuPG.
 #
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
 
-# The translated revision was taken from HEAD b8bb16c6c08d3c2947f1ff67
-# which is the same as the revision from STABLE-BRANCH-2-0 776bee6d370
-
-.#pinentry.qualitybar.tooltip
-# [remove the hash mark from the key to enable this text]
-# This entry is just an example on how to customize the tooltip shown
-# when hovering over the quality bar of the pinentry.  We don't
-# install this text so that the hardcoded translation takes
-# precedence.  An administrator should write up a short help to tell
-# the users about the configured passphrase constraints and save that
-# to /etc/gnupg/help.txt.  The help text should not be longer than
-# about 800 characters.
-Этот индикатор показывает качество введенной выше фразы-пароля.
-
-Пока индикатор красный, GnuPG считает фразу-пароль неприемлемо слабой.
-Уточните у своего администратора принятые требования к фразе-паролю.
-.
-
-
-.gnupg.agent-problem
-# There was a problem accessing or starting the agent.
-К запущенному Gpg-Agent было невозможно подключиться, либо возникла
-проблема соединения с ним.
-
-Система использует фоновый процесс под названием Gpg-Agent
-для обработки секретных ключей и запроса фраз-паролей. Обычно процесс
-запускается при входе пользователя в систему и работает, пока
-пользователь не выйдет. Если процесс недоступен, система пытается
-запустить его на ходу, но функции этой версий несколько ограничены,
-это может привести к небольшим проблемам.
-
-Вероятно, для решения проблемы нужно обратиться к администратору.
-В качестве временной меры можно выйти и снова войти в систему;
-может быть, это поможет. В любом случае сообщите об этом
-администратору, потому что это указывает на недочет в программе.
-.
-
-
-.gnupg.dirmngr-problem
-# There was a problen accessing the dirmngr.
-К запущенному Dirmngr было невозможно подключиться, либо возникла
-проблема соединения с ним.
-
-Для просмотра списков отзыва сертификатов во время проверки
-сертификатов и для поиска ключей на локальных серверах система
-пользуется внешней служебной программой Dirmngr. Обычно она работает
-как системная служба (демон) и не нуждается в каких-либо действиях
-со стороны пользователя. В случае проблем система может запускать
-новую копию Dirmngr по каждому запросу; это запасной вариант
-с ухудшенными характеристиками.
-
-Если Вы столкнулись с этой проблемой, обратитесь к системному
-администратору. В качестве временного решения можно попробовать
-отключить проверку списков отзыва сертификатов в настройках gpgsm.
-.
-
 
 .gpg.edit_ownertrust.value
-# The help identies prefixed with "gpg." used to be hard coded in gpg
-# but may now be overridden by help texts from this file.
-Если хотите, поставьте здесь значение; оно никогда не будет выводиться
-для третьих сторон. Нам оно нужно для реализации сети доверия; оно
-никак не связано с (неявно создаваемой) сетью сертификатов.
+Вы должны ввести здесь значение; оно никогда не будет экспортировано
+третьей стороне.  Это необходимо для реализации Сети Доверия;
+и не имеет ничего общего с (неявно созданной) сетью сертификатов.
 .
 
 .gpg.edit_ownertrust.set_ultimate.okay
-Для построения Сети доверия GnuPG нужно знать, каким ключам доверять
-полностью - обычно это ключи, секретные части которых у Вас есть.
-Ответ "да" установит полное доверие этому ключу.
+Для построения Сети Доверия, GnuPG должен знать, к каким ключам
+имеется абсолютное доверие - обычно это ключи для которых у Вас есть
+секретный ключ.  Ответьте "yes" для присвоения абсолютного доверия
+данному ключу
 
+.
 
 .gpg.untrusted_key.override
-Если Вы хотите все равно пользоваться этим недоверенным ключом,
-ответьте "да".
+Если хотите использовать данный недоверяемый ключ - ответьте "yes".
 .
 
 .gpg.pklist.user_id.enter
-Введите ID пользователя - получателя Вашего сообщения.
+Введите User ID адресата, которому хотите отправить сообщение.
 .
 
 .gpg.keygen.algo
 Выберите алгоритм.
 
-DSA (он же DSS) можно применять только для подписей.
+DSA (aka DSS) - Digital Signature Algorithm может использоваться
+только для подписей.
 
-Elgamal - алгоритм только для шифрования.
+Elgamal - алгоритм используемый только для шифрования.
 
-RSA Ð¼Ð¾Ð¶Ð½Ð¾ Ð¿Ñ\80именÑ\8fÑ\82Ñ\8c Ð´Ð»Ñ\8f Ñ\88иÑ\84Ñ\80ованиÑ\8f Ð¸Ð»Ð¸ Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей.
+RSA Ð¼Ð¾Ð¶ÐµÑ\82 Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8cÑ\81Ñ\8f Ð¸ Ð´Ð»Ñ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и, Ð¸ Ð´Ð»Ñ\8f Ñ\88иÑ\84Ñ\80ованиÑ\8f.
 
\9fеÑ\80вÑ\8bй (пеÑ\80виÑ\87нÑ\8bй) ÐºÐ»Ñ\8eÑ\87 Ð²Ñ\81егда Ð´Ð¾Ð»Ð¶ÐµÐ½ Ð±Ñ\8bÑ\82Ñ\8c Ð¿Ñ\80игоден Ð´Ð»Ñ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей.
\9fеÑ\80вÑ\8bй (он Ð¶Ðµ Ð³Ð»Ð°Ð²Ð½Ñ\8bй) ÐºÐ»Ñ\8eÑ\87 Ð²Ñ\81егда Ð´Ð¾Ð»Ð¶ÐµÐ½ Ð±Ñ\8bÑ\82Ñ\8c Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8bваÑ\8eÑ\89им.
 .
 
-
 .gpg.keygen.algo.rsa_se
-В целом неразумно пользоваться одним и тем же ключом и для подписи,
-и для шифрования. Это может быть полезно только в определенных
-случаях. Проконсультируйтесь со своим экспертом по безопасности.
-.
-
-
-.gpg.keygen.flags
-Поменять функции ключа.
-
-Переключать можно только функции, доступные для выбранного
-алгоритма.
-
-Для быстрой установки сразу всех возможностей введите сначала '=',
-а за ним список букв, задающих набор функций: '1' - подпись, '2' -
-шифрование, '3' - аутентификация. Неправильные буквы и функции
-не учитываются. Сразу после быстрого ввода это подменю закрывается.
+Обычно не рекомендуется использовать один ключ и для подписи, и для шифрования.
+Данный алгоритм следует использовтаь только в некоторых случаях.
+Проконсультируйтесь с Вашим экспертом по безопасности перед тем,
+как использовать данный ключ.
 .
 
-
 .gpg.keygen.size
-Введите размер ключа.
-
-Предлагаемое значение обычно хорошо подходит.
-
-Если Вам нужен ключ большого размера, например, 4096 бит, подумайте,
-действительно ли это для Вас имеет смысл. См. комикс на странице
-http://www.xkcd.com/538/ .
+Введите размер ключа
 .
 
 .gpg.keygen.size.huge.okay
\9eÑ\82веÑ\87айÑ\82е "да" Ð¸Ð»Ð¸ "неÑ\82".
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" Ð¸Ð»Ð¸ "no"
 .
 
-
 .gpg.keygen.size.large.okay
\9eÑ\82веÑ\87айÑ\82е "да" Ð¸Ð»Ð¸ "неÑ\82".
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" Ð¸Ð»Ð¸ "no"
 .
 
-
 .gpg.keygen.valid
-Введите нужное значение, как показано в приглашении.
\9cожно Ð²Ð²ÐµÑ\81Ñ\82и Ð´Ð°Ñ\82Ñ\83 Ð\98СÐ\9e (Ð\93Ð\93Ð\93Ð\93\9cÐ\9c\94Ð\94), Ð½Ð¾ Ñ\81ообÑ\89ениÑ\8f Ð¾Ð± Ð¾Ñ\88ибкаÑ\85 Ð±Ñ\83дÑ\83Ñ\82
-неудобочитаемыми: система пытается интерпретировать данное значение
-как интервал.
+Введите требуемое значение, как показано в подсказке.
\9cожно Ð²Ð²ÐµÑ\81Ñ\82и Ð´Ð°Ñ\82Ñ\83 Ð² ISO Ñ\84оÑ\80маÑ\82е (YYYY-MM-DD), Ð½Ð¾ Ð\92Ñ\8b Ð½Ðµ Ð¿Ð¾Ð»Ñ\83Ñ\87иÑ\82е
+уведомление при ошибке в формате - вместо этого система попробует
¸Ð½Ñ\82еÑ\80пÑ\80еÑ\82иÑ\80оваÑ\82Ñ\8c Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ\87ение ÐºÐ°Ðº Ð¸Ð½Ñ\82еÑ\80вал.
 .
 
 .gpg.keygen.valid.okay
\9eÑ\82веÑ\87айÑ\82е "да" Ð¸Ð»Ð¸ "неÑ\82".
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" Ð¸Ð»Ð¸ "no"
 .
 
-
 .gpg.keygen.name
-Введите имя владельца ключа.
-Символы "<" и ">" недопустимы.
-Пример: Вася Пушкин
+Введите имя владельца ключа
 .
 
-
 .gpg.keygen.email
-Введите, пожалуйста, адрес электронной почты (необязательно,
-но очень рекомендуется).
-Пример: vp@test.ru
+введите необязательный, но очень рекомендуемый email адрес
 .
 
 .gpg.keygen.comment
-Введите, пожалуйста, необязательное примечание.
-Символы "(" и ")" недопустимы.
-В общем и целом оно не нужно.
+Введите необязательный комментарий
 .
 
-
 .gpg.keygen.userid.cmd
-# (Keep a leading empty line)
-
-N  сменить имя.
-C  сменить примечание.
-E  сменить адрес.
+N  изменить имя.
+C  изменить комментарий.
+E  изменить email адрес.
 O  продолжить создание ключа.
-Q  Ð¿Ñ\80екÑ\80аÑ\82ить создание ключа.
+Q  Ð²Ñ\8bйÑ\82и Ð¸ Ð¿Ñ\80еÑ\80вать создание ключа.
 .
 
 .gpg.keygen.sub.okay
\92ведиÑ\82е "да" (или "y"), Ñ\87Ñ\82обÑ\8b Ñ\80азÑ\80еÑ\88иÑ\82Ñ\8c Ñ\81оздание ÐºÐ»Ñ\8eÑ\87а.
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" (или Ñ\82олÑ\8cко "y"), ÐµÑ\81ли Ð³Ð¾Ñ\82овÑ\8b Ñ\81оздаваÑ\82Ñ\8c Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87.
 .
 
 .gpg.sign_uid.okay
\9eÑ\82веÑ\87айÑ\82е "да" Ð¸Ð»Ð¸ "неÑ\82".
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" Ð¸Ð»Ð¸ "no"
 .
 
 .gpg.sign_uid.class
\9aогда Ð\92Ñ\8b Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8bваеÑ\82е Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\82оÑ\80 Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f Ð² ÐºÐ»Ñ\8eÑ\87е, Ð½Ñ\83жно Ñ\81наÑ\87ала
-удостовериться, что ключ принадлежит указанному в идентификаторе лицу.
\94Ñ\80Ñ\83гим Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾ Ð·Ð½Ð°Ñ\82Ñ\8c, Ð½Ð°Ñ\81колÑ\8cко Ñ\82Ñ\89аÑ\82елÑ\8cно Ð\92Ñ\8b Ñ\8dÑ\82о Ð¿Ñ\80овеÑ\80или.
\9fеÑ\80ед Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8bванием User ID ÐºÐ»Ñ\8eÑ\87а, Ñ\81ледÑ\83еÑ\82 Ð¿Ñ\80ежде Ñ\83доÑ\81Ñ\82овеÑ\80иÑ\82Ñ\8cÑ\81Ñ\8f, Ñ\87Ñ\82о
+ключ действительно принадлежит человеку указанному в User ID. Это очень важно
´Ð»Ñ\8f Ñ\82еÑ\85, ÐºÑ\82о Ñ\83Ñ\87иÑ\82Ñ\8bваеÑ\82 ÐºÐ°Ðº Ñ\85оÑ\80оÑ\88о Ð\92Ñ\8b Ð¿Ñ\80овеÑ\80Ñ\8fеÑ\82е Ð´Ð¾Ñ\81Ñ\82овеÑ\80ноÑ\81Ñ\82Ñ\8c User ID.
 
-"0" значит, что Вы не указываете, насколько тщательно вы проверяли ключ.
+"0" означает, что Вы не можете сказать, как хорошо Вы проверили ключ.
+"1" означает, что Вы полагаете, что ключ принадлежит человеку, который
+    указан в нем, но Вы не могли или не проводили проверку ключа совсем.
+    Это полезно, когда Вы подписываете ключ с псевдонимом человека.
 
-"1" значит, что Вы считаете, что ключ принадлежит заявленному лицу, но Вы
-    Ð½Ðµ Ð¼Ð¾Ð³Ð»Ð¸ Ð¿Ñ\80овеÑ\80иÑ\82Ñ\8c Ð¸Ð»Ð¸ Ð½Ðµ Ð¿Ñ\80овеÑ\80Ñ\8fли ÐºÐ»Ñ\8eÑ\87. Ð­Ñ\82о Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾ Ð´Ð»Ñ\8f Ð¿Ñ\80овеÑ\80ки
-    "инкогнито", когда вы подписываете ключ с псевдонимом.
+"2" означает, что Вы делали неаккуратную проверку ключа.  Например, это может
+    Ð¾Ð·Ð½Ð°Ñ\87аÑ\82Ñ\8c, Ñ\87Ñ\82о Ð\92Ñ\8b Ð¿Ñ\80овеÑ\80или Ð¾Ñ\82пеÑ\87аÑ\82ок ÐºÐ»Ñ\8eÑ\87а Ð¸ Ð¿Ñ\80овеÑ\80или User ID Ð½Ð°
+    ключе на основании фото ID.
 
-"2" значит, что Вы провели частичную проверку ключа. Например, проверили
-    отпечаток ключа и идентификатор пользователя из ключа
-    по фотоидентификатору.
+"3" означает, что Вы выполнили всестороннюю проверку ключа.  Например, это может
+    означать, что Вы сверили отпечаток ключа с владельцем ключа лично
+    и что Вы сверили всё посредством трудноподделываемого документа с
+    фотографией (таким как паспорт), что имя владельца ключа совпадает с
+    именем в User ID ключа и наконец, что Вы проверили (обменом шифрованными
+    письмами), что email адрес на ключе принадлежит владельцу ключа.
 
-"3" значит, что Вы провели тщательную проверку ключа. Например,
-    Вы проверили отпечаток ключа, а также проверили по удостоверению
-    личности (такому как паспорт), что имя владельца ключа совпадает
-    с именем человека, записанным в идентификаторе пользователя ключа;
-    наконец, Вы удостоверились (обменявшись электронной почтой), что
-    адрес электронной почты принадлежит владельцу ключа.
+Учтите, что примеры данные для уровней 2 и 3 - только примеры.
+В конечном итоге, Вам решать, как классифицировать "неаккуратно" и "всесторонне",
+при подписывании чужих ключей.
 
-Имейте в виду, что примеры, данные для уровней 2 и 3 - это *только*
-примеры. В конечном счете Вы сами решаете, что значит "частичная"
-и "тщательная" проверка, когда Вы подписываете другие ключи.
-
-Если затрудняетесь с ответом, поставьте "0".
+Если Вы не можете определиться с правильным ответом, ответьте "0".
 .
 
 .gpg.change_passwd.empty.okay
\9eÑ\82веÑ\87айÑ\82е "да" Ð¸Ð»Ð¸ "неÑ\82".
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" Ð¸Ð»Ð¸ "no"
 .
 
-
 .gpg.keyedit.save.okay
\9eÑ\82веÑ\87айÑ\82е "да" Ð¸Ð»Ð¸ "неÑ\82".
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" Ð¸Ð»Ð¸ "no"
 .
 
-
 .gpg.keyedit.cancel.okay
\9eÑ\82веÑ\87айÑ\82е "да" Ð¸Ð»Ð¸ "неÑ\82".
\9eÑ\82веÑ\82Ñ\8cÑ\82е "yes" Ð¸Ð»Ð¸ "no"
 .
 
 .gpg.keyedit.sign_all.okay
-Ответьте "да", если хотите подписать ВСЕ идентификаторы пользователя.
+Ответьте "yes", если хотите подписать ВСЕ User ID
 .
 
 .gpg.keyedit.remove.uid.okay
-Ответьте "да", если действительно хотите удалить этот идентификатор
-пользователя.
-Все сертификаты будут также удалены!
+Ответьте "yes", если действительно хотите удалить данный User ID.
+Все сертификаты также будут потеряны!
 .
 
 .gpg.keyedit.remove.subkey.okay
-Ответьте "да", если подключ можно удалить.
+Ответьте "yes", если готовы удалить подключ
 .
 
-
 .gpg.keyedit.delsig.valid
-ЭÑ\82о Ð²ÐµÑ\80наÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c ÐºÐ»Ñ\8eÑ\87а; ÐºÐ°Ðº Ð¿Ñ\80авило, ÐµÐµ Ð½Ðµ Ð½Ñ\83жно Ñ\83далÑ\8fÑ\82Ñ\8c,
-поскольку может быть важно установить отношение доверия между
-этим ключом и другими ключами.
+ЭÑ\82о Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cнаÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c Ð½Ð° ÐºÐ»Ñ\8eÑ\87е; Ð¾Ð±Ñ\8bÑ\87но Ð½Ðµ Ð¶ÐµÐ»Ð°Ñ\82елÑ\8cно
+удалять такие подписи, потому, что она может быть важна для установления
+достоверности ключа или других ключей подписанных данным ключом.
 .
 
 .gpg.keyedit.delsig.unknown
-Эту подпись нельзя проверить, поскольку отсутствует соответствующий
-ключ. Удаление ее нужно отложить до тех пор, пока не станет
-известно, какой из ключей был использован, так как подпись
-этого ключа могло бы установить отношение доверия через
-другой, уже сертифицированный ключ.
+Данная подпись не может быть проверена потому, что Вы не имеете
+соответствующего ключа.  Можете отложить ее удаление, пока не
+узнаете, какой ключ был использован, т.к. эта подпись может
+устанавливать достоверность через другие уже удостоверенные ключи.
 .
 
 .gpg.keyedit.delsig.invalid
-Подпись недействительна. Имеет смысл удалить ее из Вашей таблицы
-ключей.
+Подпись недействительна.  Это дает основания удалить ее из
+связки ключей.
 .
 
 .gpg.keyedit.delsig.selfsig
-Эта подпись связывает идентификатор пользователя с ключом. Обычно
-удалять такие подписи не следует. Это может сделать ключ непригодным
-для пользования с GnuPG. Так что делайте это только если эта
-самоподпись по какой-то причине недействительна и есть другая.
+Данная подпись является самоподписью и привязывает User ID к ключу.
+Обычно это плохая идея удалить такую подпись.  На самом деле
+GnuPG может не позволить использовать такой ключ далее.
+Делайте это только если данная самоподпись не действительна по
+каким-либо причинам и существует доступная вторая.
 .
 
 .gpg.keyedit.updpref.okay
-Изменить предпочтения для всех идентификаторов пользователя (или
-только для выбранных) на текущий список предпочтений. Дата всех
-самоподписей, которых это касается, будет сдвинута вперед
-на одну секунду.
-.
+Изменение предпочтений для всех User ID (или только для выбранных)
+на текущий список предпочтений.  Отметка времени на всех затронутых
+самоподписях будет увеличена на одну секунду.
 
+.
 
 .gpg.passphrase.enter
-# (keep a leading empty line)
+Введите фразу-пароль (это секретная строка) 
 
-Введите, пожалуйста, фразу-пароль (секретное предложение).
 .
 
-
 .gpg.passphrase.repeat
-Повторите введенную фразу-пароль, чтобы проверить, что Вы не ошиблись.
+Повторите фразу-пароль, чтобы убедиться в том, что она набрана правильно.
 .
 
 .gpg.detached_signature.filename
\97адайÑ\82е Ð¸Ð¼Ñ\8f Ñ\84айла, ÐºÐ¾Ñ\82оÑ\80Ñ\8bй Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8bваеÑ\82Ñ\81Ñ\8f.
\92ведиÑ\82е Ð¸Ð¼Ñ\8f Ñ\84айла, Ðº ÐºÐ¾Ñ\82оÑ\80омÑ\83 Ð¾Ñ\82ноÑ\81иÑ\82Ñ\81Ñ\8f Ð´Ð°Ð½Ð½Ð°Ñ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c
 .
 
 .gpg.openfile.overwrite.okay
-# openfile.c (overwrite_filep)
-Ответьте "да", если файл можно перезаписать.
+Ответьте "yes", если хотите перезаписать файл
 .
 
 .gpg.openfile.askoutname
-# openfile.c (ask_outfile_name)
-Введите новое имя файла. Если просто нажать "Enter", будет
-использован файл по умолчанию (указан в скобках).
+Введите новое имя файла. Если нажмете только RETURN будет использован
+по умолчанию тот файл, который показан в квадратных скобках.
 .
 
 .gpg.ask_revocation_reason.code
-# revoke.c (ask_revocation_reason)
\9dÑ\83жно Ñ\83казаÑ\82Ñ\8c Ð¿Ñ\80иÑ\87инÑ\83 Ð¾Ñ\82зÑ\8bва. Ð\9cожно Ð²Ñ\8bбÑ\80аÑ\82Ñ\8c Ð¸Ð· Ñ\81пиÑ\81ка:
-  "Ð\9aлÑ\8eÑ\87 Ð±Ñ\8bл Ñ\80аÑ\81кÑ\80Ñ\8bÑ\82"
-      Ð\95Ñ\81Ñ\82Ñ\8c Ð¾Ñ\81нованиÑ\8f Ð¿Ð¾Ð»Ð°Ð³Ð°Ñ\82Ñ\8c, Ñ\87Ñ\82о ÐºÐ°ÐºÐ¸Ðµ-Ñ\82о Ð»Ð¸Ñ\86а Ð¿Ð¾Ð»Ñ\83Ñ\87или
-      Ð½ÐµÑ\81анкÑ\86иониÑ\80ованнÑ\8bй Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ðº секретному ключу.
+Сейчас сможете указать причину отзыва ключа.  Основываясь на 
ºÐ¾Ð½Ñ\82екÑ\81Ñ\82е Ð¾Ñ\82зÑ\8bва - Ð¼Ð¾Ð¶ÐµÑ\82е Ð²Ñ\8bбÑ\80аÑ\82Ñ\8c Ð¾Ð´Ð¸Ð½ Ð¸Ð· Ñ\81ледÑ\83Ñ\8eÑ\89иÑ\85 Ð²Ð°Ñ\80ианÑ\82ов:
+  "Ð\9aлÑ\8eÑ\87 Ð±Ñ\8bл Ñ\81компÑ\80омеÑ\82иÑ\80ован"
+      Ð\92Ñ\8bбеÑ\80иÑ\82е, ÐµÑ\81ли Ð¿Ñ\80едполагаеÑ\82е, Ñ\87Ñ\82о Ð¿Ð¾Ñ\81Ñ\82оÑ\80онний Ñ\87еловек
+      Ð¿Ð¾Ð»Ñ\83Ñ\87ил Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ðº Ð\92аÑ\88емÑ\83 секретному ключу.
   "Ключ заменен другим"
-      Вы заменили ключ на новый.
+      Выберите, если заменяете данный ключ на другой.
   "Ключ больше не используется"
-      Вы дали ключу отставку.
-  "ID пользователя больше не действителен"
-      ID пользователя больше не должен употребляться; обычно это значит,
-      что адрес электронной почты недействителен.
-.
+      Выберите, если отказываетесь от использования данного ключа.
+  "User ID больше не действителен"
+      Выберите, если больше не собираетесь использовать данный User ID.
+      Обычно используется, для указания, что данный e-mail больше
+      не используется
 
-.gpg.ask_revocation_reason.text
-# revoke.c (ask_revocation_reason)
-Если хотите, можете ввести текст, поясняющий причину, по которой
-выпущен этот сертификат отзыва. Выражайтесь, пожалуйста, ясно.
-Текст заканчивается пустой строкой.
 .
 
+.gpg.ask_revocation_reason.text
+При необходимости здесь можно прокомментировать причины
+создания сертификата отзыва.  Будьте кратки.
+Для завершения введите пустую строку.
 
+.
 
 
-.gpgsm.root-cert-not-trusted
-# This text gets displayed by the audit log if
-# a root certificates was not trusted.
-Нет доверия к корневому сертификату. В зависимости от настроек
-Вам могли предложить пометить этот корневой сертификат как доверенный
-или вручную указать GnuPG, что этому сертификату нужно доверять.
-Доверенные сертификаты задаются в файле trustlist.txt в домашнем
-каталоге GnuPG. Если сомневаетесь, спросите своего системного
-администратора, следует ли Вам доверять этому сертификату.
-
-
-.gpgsm.crl-problem
-# This tex is displayed by the audit log for problems with
-# the CRL or OCSP checking.
-В зависимости от настроек возникла проблема в получении списка
-отозванных сертификатов или в выполнении проверки по протоколу
-OCSP. Это могло случиться по очень многим причинам. Обратитесь
-к документации за возможными решениями.
-
 
 # Local variables:
-# mode: default-generic
+# mode: fundamental
 # coding: utf-8
 # End:
index d6815e2..aff3955 100644 (file)
@@ -13,7 +13,7 @@ include brief information on how to set up the whole thing.  Please
 watch the GnuPG website for updates of the documentation.  In the
 meantime you may search the GnuPG mailing list archives or ask on the
 gnupg-users mailing listsfor advise on how to solve problems or how to
-get that whole thing up and running. 
+get that whole thing up and running.
 
 ** Building the software
 
@@ -22,7 +22,7 @@ that you are already reading this documentation we can only give some
 extra hints
 
 To comply with the rules on GNU systems you should have build time
-configured @command{dirmngr} using:
+configured @command{gnupg} using:
 
 @example
 ./configure --sysconfdir=/etc --localstatedir=/var
@@ -36,19 +36,7 @@ the binaries get installed.  If you selected to use the
 the default then.
 
 
-
-** Explain how to setup a root CA key as trusted
-
-
-Such questions may also help to write a proper installation guide.
-
-[to be written]
-
-
-XXX Tell how to setup the system, install certificates, how dirmngr relates
-to GnuPG etc.
-
-** Explain how to setup a root CA key as trusted
+** Notes on setting a root CA key to trusted
 
 X.509 is based on a hierarchical key infrastructure.  At the root of the
 tree a trusted anchor (root certificate) is required.  There are usually
@@ -64,28 +52,26 @@ contains a few root certificates.  Most installations will need more.
 
 @item
 Let @command{gpgsm} ask you whether you want to insert a new root
-certificate.  To enable this feature you need to set the option
-@option{allow-mark-trusted} into @file{gpg-agent.conf}.  In general it
-is not a good idea to do it this way.  Checking whether a root
-certificate is really trustworthy requires decisions, which casual
-users are not up to.  Thus, by default this option is not enabled.
+certificate.  This feature is enabled by default; you may disable it
+using the option @option{no-allow-mark-trusted} into
+@file{gpg-agent.conf}.
 
-@item 
+@item
 Manually maintain the list of trusted root certificates. For a multi
 user installation this can be done once for all users on a machine.
-Specific changes on a per-user base are also possible. 
+Specific changes on a per-user base are also possible.
 @end itemize
 
-XXX decribe how to maintain trustlist.txt and /etc/gnupg/trustlist.txt.
-
-
-** How to get the ssh support running
+@c decribe how to maintain trustlist.txt and /etc/gnupg/trustlist.txt.
 
-XXX How to use the ssh support.
 
+@c ** How to get the ssh support running
+@c
+@c XXX How to use the ssh support.
 
-@section Installation Overview 
 
-XXXX
+@c @section Installation Overview
+@c
+@c XXXX
 
 
diff --git a/doc/mksamplekeys b/doc/mksamplekeys
new file mode 100755 (executable)
index 0000000..cd56b21
--- /dev/null
@@ -0,0 +1,10 @@
+#/bin/sh
+# Generate a samplekeys.asc
+
+keys='1E42B367 99242560 87978569 4F25E3B6 5B0358A2 57548DCD B2D7795E 1CE0C630'
+
+for i in $keys; do
+  gpg --list-keys $i | awk '{ if ( $0 != "") print "  " $0; else print $0; }'
+done
+echo
+gpg --export-options export-minimal --export -a $keys
index e382f63..033a901 100644 (file)
@@ -5,6 +5,18 @@ Set the name of the home directory to @var{dir}. If this option is not
 used, the home directory defaults to @file{~/.gnupg}.  It is only
 recognized when given on the command line.  It also overrides any home
 directory stated through the environment variable @env{GNUPGHOME} or
-(on W32 systems) by means of the Registry entry
+(on Windows systems) by means of the Registry entry
 @var{HKCU\Software\GNU\GnuPG:HomeDir}.
 
+On Windows systems it is possible to install GnuPG as a portable
+application.  In this case only this command line option is
+considered, all other ways to set a home directory are ignored.
+
+To install GnuPG as a portable application under Windows, create an
+empty file name @file{gpgconf.ctl} in the same directory as the tool
+@file{gpgconf.exe}.  The root of the installation is than that
+directory; or, if @file{gpgconf.exe} has been installed directly below
+a directory named @file{bin}, its parent directory.  You also need to
+make sure that the following directories exist and are writable:
+@file{ROOT/home} for the GnuPG home and @file{ROOT/var/cache/gnupg}
+for internal cache files.
index 1a4b6d7..79a5fcc 100644 (file)
@@ -178,7 +178,8 @@ show memory statistics.
 @item 9  (512)
 write hashed data to files named @code{dbgmd-000*}
 @item 10 (1024)
-trace Assuan protocol.  See also option @option{--debug-assuan-log-cats}.
+trace Assuan protocol.
+See also option @option{--debug-assuan-log-cats}.
 @item 11 (2048)
 trace APDU I/O to the card.  This may reveal sensitive data.
 @item 12 (4096)
@@ -268,10 +269,12 @@ a list of available readers.  The default is then the first reader
 found.
 
 To get a list of available CCID readers you may use this command:
+@cartouche
 @smallexample
-echo scd getinfo reader_list | gpg-connect-agent --decode | awk '/^D/ @{print $2@}'
+  echo scd getinfo reader_list \
+    | gpg-connect-agent --decode | awk '/^D/ @{print $2@}'
 @end smallexample
-
+@end cartouche
 
 @item --card-timeout @var{n}
 @opindex card-timeout
@@ -337,6 +340,7 @@ stripping off the two leading dashes.
 * DINSIG Card::           The DINSIG card application
 * PKCS#15 Card::          The PKCS#15 card application
 * Geldkarte Card::        The Geldkarte application
+* SmartCard-HSM::         The SmartCard-HSM application
 * Undefined Card::        The Undefined stub application
 @end menu
 
@@ -347,8 +351,9 @@ This application is currently only used by @command{gpg} but may in
 future also be useful with @command{gpgsm}.  Version 1 and version 2 of
 the card is supported.
 
-The specifications for these cards are available at
-@uref{http://g10code.com/docs/openpgp-card-1.0.pdf} and
+@noindent
+The specifications for these cards are available at@*
+@uref{http://g10code.com/docs/openpgp-card-1.0.pdf} and@*
 @uref{http://g10code.com/docs/openpgp-card-2.0.pdf}.
 
 @node NKS Card
@@ -378,6 +383,19 @@ This is a simple application to display information of a German
 Geldkarte.  The Geldkarte is a small amount debit card application which
 comes with almost all German banking cards.
 
+@node SmartCard-HSM
+@subsection The SmartCard-HSM card application ``sc-hsm''
+
+This application adds read/only support for keys and certificates
+stored on a @uref{http://www.smartcard-hsm.com, SmartCard-HSM}.
+
+To generate keys and store certifiates you may use
+@uref{https://github.com/OpenSC/OpenSC/wiki/SmartCardHSM, OpenSC} or
+the tools from @uref{http://www.openscdp.org, OpenSCDP}.
+
+The SmartCard-HSM cards requires a card reader that supports Extended
+Length APDUs.
+
 @node Undefined Card
 @subsection The Undefined card application ``undefined''
 
index 7d23ed8..2eee024 100644 (file)
@@ -6,7 +6,7 @@ are only valid for @command{gpg} others are only good for
 
 @itemize @bullet
 
-@item By key Id. 
+@item By key Id.
 This format is deduced from the length of the string and its content or
 @code{0x} prefix. The key Id of an X.509 certificate are the low 64 bits
 of its SHA-1 fingerprint.  The use of key Ids is just a shortcut, for
@@ -59,16 +59,17 @@ avoids any ambiguities in case that there are duplicated key IDs.
 @end cartouche
 
 @noindent
-(@command{gpgsm} also accepts colons between each pair of hexadecimal
+@command{gpgsm} also accepts colons between each pair of hexadecimal
 digits because this is the de-facto standard on how to present X.509
-fingerprints.)
+fingerprints.  @command{gpg} also allows the use of the space
+separated SHA-1 fingerprint as printed by the key listing commands.
 
 @item By exact match on OpenPGP user ID.
 This is denoted by a leading equal sign. It does not make sense for
 X.509 certificates.
 
 @cartouche
-@example 
+@example
 =Heinrich Heine <heinrichh@@uni-duesseldorf.de>
 @end example
 @end cartouche
diff --git a/doc/texi.css b/doc/texi.css
new file mode 100644 (file)
index 0000000..c1e9f48
--- /dev/null
@@ -0,0 +1,23 @@
+/* The gnupg.org standard stylesheet.  */
+  @import url(/share/site.css);
+
+/* The gnupg site sets body margins to zero.  Because we don't have
+   the table layout here we have to set our own margins for the body.  */
+body {
+    margin-left: 1em;
+    margin-right: 1em;
+}
+
+/* Make the top header larger.  */
+h1 {
+  text-align: center;
+  font-size: 200%;
+}
+
+h1:first-letter {
+  font-size: 120%;
+}
+
+
+
+
index 030f269..d556b6d 100644 (file)
@@ -1062,7 +1062,7 @@ machine startup.
 Passphrases set with this utility don't expire unless the
 @option{--forget} option is used to explicitly clear them from the
 cache --- or @command{gpg-agent} is either restarted or reloaded (by
-sending a SIGHUP to it).  Nite that the maximum cache time as set with
+sending a SIGHUP to it).  Note that the maximum cache time as set with
 @option{--max-cache-ttl} is still honored.  It is necessary to allow
 this passphrase presetting by starting @command{gpg-agent} with the
 @option{--allow-preset-passphrase}.
@@ -1199,7 +1199,11 @@ Try to be as quiet as possible.
 
 @item --agent-program @var{file}
 @opindex agent-program
-Specify the agent program to be started if none is running.
+Specify the agent program to be started if none is running.  The
+default value is determined by running @command{gpgconf} with the
+option @option{--list-dirs}.  Note that the pipe symbol (@code{|}) is
+used for a regression test suite hack and may thus not be used in the
+file name.
 
 @ifset gpgtwoone
 @item --dirmngr-program @var{file}
diff --git a/doc/vuln-announce-2010-kbx-realloc.txt b/doc/vuln-announce-2010-kbx-realloc.txt
new file mode 100644 (file)
index 0000000..fccd127
--- /dev/null
@@ -0,0 +1,94 @@
+             Realloc Bug with X.509 certificates in GnuPG
+            ==============================================
+                              2010-07-23
+
+
+Summary
+=======
+
+While trying to import a server certificate for a CDN service, a segv
+bug was found in GnuPG's GPGSM tool.  It is likely that this bug is
+exploitable by sending a special crafted signed message and having a
+user verify the signature.
+
+[ Please do not send private mail in response to this message.  The
+  mailing list gnupg-devel is the best place to discuss this problem
+  (please subscribe first so you don't need moderator approval [1]). ]
+
+
+Impact
+======
+
+All applications using GnuPG's GPGSM tool to process S/MIME messages
+or manage X.509 certificates are affected.  The bug exists in all
+versions of GnuPG including the recently released GnuPG 2.0.16.
+
+GPG (i.e. OpenPGP) is NOT affected.
+
+GnuPG 1.x is NOT affected because it does not come with the GPGSM
+tool.
+
+An exploit is not yet known but it can't be ruled out for sure that
+the problem has not already been identified by some dark forces.
+
+
+Description
+===========
+
+Importing a certificate with more than 98 Subject Alternate Names [2]
+via GPGSM's import command or implicitly while verifying a signature
+causes GPGSM to reallocate an array with the names.  The bug is that
+the reallocation code misses assigning the reallocated array to the
+old array variable and thus the old and freed array will be used.
+Usually this leads to a segv.
+
+It might be possible to use one of the techniques to exploit
+assignments to malloced and freed memory.  Such an exploit won't be
+easy to write because the attack vector must fit into a valid ASN.1
+DER encoded DN.  To further complicate the task, that DN is not used
+directly but after a transformation to RFC-2253 format.
+
+
+
+Solution
+========
+
+Apply the following patch.  The patch is required for all GnuPG
+versions < 2.0.17.  It applies to 2.0.16 but should apply to many
+older versions as well.
+
+
+--- kbx/keybox-blob.c   (revision 5367)
++++ kbx/keybox-blob.c   (working copy)
+@@ -898,6 +898,7 @@
+               rc = gpg_error_from_syserror ();
+               goto leave;
+             }
++          names = tmp;
+         }
+       names[blob->nuids++] = p;
+       if (!i && (p=x509_email_kludge (p)))
+
+
+
+
+Support 
+=======
+
+g10 Code GmbH [3], a Duesseldorf based company owned and headed by
+GnuPG's principal author, is currently funding GnuPG development.
+Support contracts or other financial backing will greatly help us to
+improve the quality of GnuPG.
+
+
+Thanks
+======
+
+Peter Gutmann for his "A mighty fortress is our PKI" mail to the
+cryptography ML which contained a pointer to a certificate to exhibit
+the problem.  This bug was created, found and fixed by Werner Koch.
+
+
+[1] See http://lists.gnupg.org/mailman/listinfo/gnupg-devel
+[2] <http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/*checkout*/trunk/tests/samplekeys/cert-with-117-akas.pem>
+[3] See http://www.gnupg.org/service.html
diff --git a/doc/whats-new-in-2.1.txt b/doc/whats-new-in-2.1.txt
new file mode 100644 (file)
index 0000000..d20239f
--- /dev/null
@@ -0,0 +1,712 @@
+                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━
+                       GNUPG - WHAT’S NEW IN 2.1
+
+
+                              Werner Koch
+                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+
+                               2014-11-04
+
+
+Table of Contents
+─────────────────
+
+1 What’s new in GnuPG 2.1
+.. 1.1 Removal of the secret keyring
+.. 1.2 Removal of PGP-2 support
+.. 1.3 Leaner key generation interface
+.. 1.4 Support for ECC
+.. 1.5 Quick generate and sign commands
+.. 1.6 Improved Pinentry support
+.. 1.7 Auto-start of the gpg-agent
+.. 1.8 Duplicate long key id fixes
+.. 1.9 Enhanced Dirmngr
+.. 1.10 Better keyserver pool support
+.. 1.11 Faster keyring format
+.. 1.12 Auto-generated revocation certificates
+.. 1.13 Improved card support
+.. 1.14 New format for key listings
+.. 1.15 Support for Putty
+.. 1.16 Improved X.509 certificate creation
+.. 1.17 Scripts to create a Windows installer
+
+
+A possibly revised version of this article can be found at:
+https://gnupg.org/faq/whats-new-in-2.1.html
+
+
+1 What’s new in GnuPG 2.1
+═════════════════════════
+
+  GnuPG version 2.1 comes with a bag of new features which changes some
+  things old-timers are used to.  This page explains the more important
+  ones.  It expects that the reader is familiar with GnuPG version 2.0
+  and aware that GnuPG consists of /gpg/, /gpgsm/, and /gpg-agent/ as
+  its main components.
+
+  • The file /secring.gpg/ is not anymore used to store the secret keys.
+    Merging of secret keys is now supported.
+
+  • All support for /PGP-2 keys/ has been removed for security reasons.
+
+  • The standard key generation interface is now much leaner.  This will
+    help a new user to quickly generate a suitable key.
+
+  • Support for /Elliptic Curve Cryptography/ (ECC) is now available.
+
+  • Commands to create and sign keys from the command line without any
+    extra prompts are now available.
+
+  • The Pinentry may now show the new passphrase entry and the
+    passphrase confirmation entry in one dialog.
+
+  • There is no more need to manually start the gpg-agent.  It is now
+    started by any part of GnuPG as needed.
+
+  • Problems with importing keys with the same long key id have been
+    addressed.
+
+  • The /dirmngr/ is now part of GnuPG proper and also takes care of
+    accessing keyserver.
+
+  • Keyserver pools are now handled in a smarter way.
+
+  • A new format for locally storing the public keys is now used.  This
+    considerable speeds up operations on large keyrings.
+
+  • /Revocation certificates/ are now created by default.
+
+  • Card support has been updated, new readers and token types are
+    supported.
+
+  • The format of the key listing has been changed to better identify
+    the properties of a key.
+
+  • The gpg-agent may now be used on Windows as /pageant/ replacement
+    for /putty/ in the same way it is used for years on Unix as
+    /ssh-agent/ replacement.
+
+  • Creation of X.509 certificates has been improved.  It is now also
+    possible to export them directly in PKCS#8 and PEM format for use on
+    TLS servers.
+
+  • The scripts to create a Windows installer are now part of GnuPG.
+
+  Now for the detailed description of these new features:
+
+
+1.1 Removal of the secret keyring
+─────────────────────────────────
+
+  gpg used to keep the public key pairs in two files: `pubring.gpg' and
+  `secring.gpg'.  The only difference is that secring stored in addition
+  to the public part also the private part of the key pair.  The secret
+  keyring thus contained only the keys for which a private key is
+  available, that is the user’s key.  It required a lot of code to keep
+  both versions of the key in sync and led to sometimes surprising
+  inconsistencies.
+
+  The design of GnuPG-2 demands that only the gpg-agent has control over
+  the private parts of the keys and the actual encryption engine (gpg or
+  gpgsm) does not know about the private key but care only about session
+  keys and keys for symmetric encryption.  This has been implemented
+  about 10 years ago for /gpgsm/ (the S/MIME part of GnuPG).  However,
+  /gpg/ (the OpenPGP part) used the gpg-agent only as passphrase entry
+  and cache device but handles the private key itself.
+
+  With GnuPG 2.1 this changed and /gpg/ now also delegates all private
+  key operations to the gpg-agent.  Thus there is no more code in the
+  /gpg/ binary for handling private keys.  En passant this allows the
+  long time requested “merging of secret keys” and several other
+  advanced key management techniques.
+
+  To ease the migration to the no-secring method, /gpg/ detects the
+  presence of a `secring.gpg' and converts the keys on-the-fly to the
+  the key store of /gpg-agent/ (this is the `private-keys-v1.d'
+  directory below the GnuPG home directory (`~/.gnupg')).  This is done
+  only once and an existing `secring.gpg' is then not anymore touched by
+  /gpg/.  This allows co-existence of older GnuPG versions with GnuPG
+  2.1.  However, any change to the private keys using the new /gpg/ will
+  not show up when using pre-2.1 versions of GnuPG and vice versa.
+
+  Note that the command `--export-secret-keys' still creates an OpenPGP
+  compliant file with the secret keys.  This is achieved by asking
+  /gpg-agent/ to convert a key and return it in the OpenPGP protected
+  format.  The export operation requires that the passphrase for the key
+  is entered so that /gpg-agent/ is able to change the protection from
+  its internal format to the OpenPGP required format.
+
+
+1.2 Removal of PGP-2 support
+────────────────────────────
+
+  Some algorithms and parts of the protocols as used by the 20 years old
+  [PGP-2] software are meanwhile considered unsafe.  In particular the
+  baked in use of the [MD5] hash algorithm limits the security of PGP-2
+  keys to non-acceptable rate.  Technically those PGP-2 keys are called
+  version 3 keys (v3) and are easily identified by a shorter fingerprint
+  which is commonly presented as 16 separate double hex digits.
+
+  With GnuPG 2.1 all support for those keys has gone.  If they are in an
+  existing keyring they will eventually be removed.  If GnuPG encounters
+  such a key on import it will not be imported due to the not anymore
+  implemented v3 key format.  Removing the v3 key support also reduces
+  complexity of the code and is thus better than to keep on handling
+  them with a specific error message.
+
+  There is one use case where PGP-2 keys may still be required: For
+  existing encrypted data.  We suggest to keep a version of GnuPG 1.4
+  around which still has support for these keys (it might be required to
+  use the `--allow-weak-digest-algos' option).  A better solution is to
+  re-encrypt the data using a modern key.
+
+
+  [PGP-2] https://en.wikipedia.org/wiki/Pretty_Good_Privacy
+
+  [MD5] https://en.wikipedia.org/wiki/MD5
+
+
+1.3 Leaner key generation interface
+───────────────────────────────────
+
+  This is best shown with an example:
+
+  ╭────
+  │ $ gpg2 --gen-key
+  │ gpg (GnuPG) 2.1.0; Copyright (C) 2014 Free Software Foundation, Inc.
+  │ This is free software: you are free to change and redistribute it.
+  │ There is NO WARRANTY, to the extent permitted by law.
+  │
+  │ gpg: keybox '/home/foo/.gnupg/pubring.kbx' created
+  │ Note: Use "gpg --full-gen-key" for a full featured key generation dialog.
+  │
+  │ GnuPG needs to construct a user ID to identify your key.
+  │
+  │ Real name: Glenn Greenwald
+  │ Email address: glenn@example.org
+  │ You selected this USER-ID:
+  │     "Glenn Greenwald <glenn@example.org>"
+  │
+  │ Change (N)ame, (E)mail, or (O)kay/(Q)uit? o
+  │ [...]
+  │ pub   rsa2048/68FD0088 2014-11-03
+  │       Key fingerprint = 0290 5ABF 17C7 81FB C390  9B00 636A 1BBD 68FD 0088
+  │ uid       [ultimate] Glenn Greenwald <glenn@example.org>
+  │ sub   rsa2048/84439DCD 2014-11-03
+  ╰────
+
+  Thus only the name and the mail address are required.  For all other
+  parameters the default values are used.  Many graphical frontends
+  works in the same way.  Note that /gpg/ prints a hint for the old time
+  gpg users on how to get the full option menu.
+
+
+1.4 Support for ECC
+───────────────────
+
+  GnuPG now support Elliptic Curve keys for public key encryption.  This
+  is defined in [RFC-6637].  Because there is no other mainstream
+  OpenPGP implementation yet available which supports ECC, the use of
+  such keys is still very limited.  Thus GnuPG 2.1 currently hides the
+  options to create an ECC key.
+
+  For those who want to experiment with ECC or already want to prepare a
+  key for future use, the command `--gen-full-key' along with the option
+  `--expert' is the enabler:
+
+  ╭────
+  │ $ gpg2 --expert --full-gen-key
+  │ gpg (GnuPG) 2.1.0; Copyright (C) 2014 Free Software Foundation, Inc.
+  │ This is free software: you are free to change and redistribute it.
+  │ There is NO WARRANTY, to the extent permitted by law.
+  │
+  │ Please select what kind of key you want:
+  │    (1) RSA and RSA (default)
+  │    (2) DSA and Elgamal
+  │    (3) DSA (sign only)
+  │    (4) RSA (sign only)
+  │    (7) DSA (set your own capabilities)
+  │    (8) RSA (set your own capabilities)
+  │    (9) ECC and ECC
+  │   (10) ECC (sign only)
+  │   (11) ECC (set your own capabilities)
+  │ Your selection? 9
+  │ Please select which elliptic curve you want:
+  │    (2) NIST P-256
+  │    (3) NIST P-384
+  │    (4) NIST P-521
+  │    (5) Brainpool P-256
+  │    (6) Brainpool P-384
+  │    (7) Brainpool P-512
+  │ Your selection? 2
+  │ Please specify how long the key should be valid.
+  │          0 = key does not expire
+  │       <n>  = key expires in n days
+  │       <n>w = key expires in n weeks
+  │       <n>m = key expires in n months
+  │       <n>y = key expires in n years
+  │ Key is valid for? (0)
+  │ Key does not expire at all
+  │ Is this correct? (y/N) y
+  │
+  │ GnuPG needs to construct a user ID to identify your key.
+  │
+  │ Real name: Edward Snowden
+  │ Email address: edward@example.org
+  │ Comment:
+  │ You selected this USER-ID:
+  │     "Edward Snowden <edward@example.org>"
+  │
+  │ Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
+  │ [...]
+  │ pub   nistp256/382660E3 2014-11-03
+  │       Key fingerprint = E630 27CF 3D68 22A7 6FF2  093E D179 9E72 3826 60E3
+  │ uid       [ultimate] Edward Snowden <edward@example.org>
+  │ sub   nistp256/48C9A997 2014-11-03 nistp256
+  ╰────
+
+  In this example we created a primary ECC key for signing and an subkey
+  for encryption.  For both we use the NIST P-256 curve.  The key may
+  now be used in the same way as any other key.  It is possible to add
+  an RSA subkey or one can create an RSA or DSA main key and add an ECC
+  subkey for signing or encryption.  Note that the list of offered
+  curves depends on the installed Libgcrypt version.
+
+  For many people the NIST and also the Brainpool curves have an
+  doubtful origin and thus the plan for GnuPG is to use Bernstein’s
+  [Curve 25519] as default.  GnuPG 2.1.0 already comes with support for
+  signing keys using the [Ed25519] variant of this curve.  This has not
+  yet been standardized by the IETF (i.e. there is no RFC) but we won’t
+  wait any longer and go ahead using the proposed format for this
+  signing algorithm.  The format for an encryption key has not yet been
+  finalized and will be added to GnuPG in one of the next point
+  releases.  Recall that an encryption subkey can be added to a key at
+  any time.  If you want to create a signing key you may do it this way:
+
+  ╭────
+  │ $ gpg2 --expert --full-gen-key
+  │ gpg (GnuPG) 2.1.0; Copyright (C) 2014 Free Software Foundation, Inc.
+  │ This is free software: you are free to change and redistribute it.
+  │ There is NO WARRANTY, to the extent permitted by law.
+  │
+  │ Please select what kind of key you want:
+  │    (1) RSA and RSA (default)
+  │    (2) DSA and Elgamal
+  │    (3) DSA (sign only)
+  │    (4) RSA (sign only)
+  │    (7) DSA (set your own capabilities)
+  │    (8) RSA (set your own capabilities)
+  │    (9) ECC and ECC
+  │   (10) ECC (sign only)
+  │   (11) ECC (set your own capabilities)
+  │ Your selection? 10
+  │ Please select which elliptic curve you want:
+  │    (1) Curve 25519
+  │    (2) NIST P-256
+  │    (3) NIST P-384
+  │    (4) NIST P-521
+  │    (5) Brainpool P-256
+  │    (6) Brainpool P-384
+  │    (7) Brainpool P-512
+  │ Your selection? 1
+  │ gpg: WARNING: Curve25519 is not yet part of the OpenPGP standard.
+  │ Use this curve anyway? (y/N) y
+  │ Please specify how long the key should be valid.
+  │          0 = key does not expire
+  │       <n>  = key expires in n days
+  │       <n>w = key expires in n weeks
+  │       <n>m = key expires in n months
+  │       <n>y = key expires in n years
+  │ Key is valid for? (0)
+  │ Key does not expire at all
+  │ Is this correct? (y/N) y
+  │
+  │ GnuPG needs to construct a user ID to identify your key.
+  │
+  │ Real name: Laura Poitras
+  │ Email address: laura@example.org
+  │ Comment:
+  │ You selected this USER-ID:
+  │     "Laura Poitras <laura@example.org>"
+  │
+  │ Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
+  │ [...]
+  │ pub   ed25519/5C1AFC2A 2014-11-03
+  │       Key fingerprint = ED85 4D98 5D8F 502F C6C5  FFB2 AA81 319E 5C1A FC2A
+  │ uid       [ultimate] Laura Poitras <laura@example.org>
+  ╰────
+
+  Support for ECC keys is available only on some keyservers but it is
+  expected that this will be fixed over the next few months.
+
+
+  [RFC-6637] https://rfc-editor.org/info/rfc6637
+
+  [Curve 25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
+
+  [Ed25519] http://dx.doi.org/10.1007/s13389-012-0027-1
+
+
+1.5 Quick generate and sign commands
+────────────────────────────────────
+
+  Sometimes it is useful to use only command line options without any
+  parameter file or interactive prompts for generating a key or to sign
+  a key.  This can now be accomplished with a few new commands:
+
+  ╭────
+  │ $ gpg2 --batch --quick-gen-key 'Daniel Ellsberg <ellsberg@example.org>'
+  │ gpg: key 911B90A9 marked as ultimately trusted
+  ╰────
+
+  If a key with that user id already exists, gpg bails out with an error
+  message.  You can force creation using the option `--yes'.  If you
+  want some more control, you may not use `--batch' and gpg will ask for
+  confirmation and show the resulting key:
+
+  ╭────
+  │ $ gpg2 --quick-gen-key 'Daniel Ellsberg <ellsberg@example.org>'
+  │ About to create a key for:
+  │     "Daniel Ellsberg <ellsberg@example.org>"
+  │
+  │ Continue? (Y/n) y
+  │ gpg: A key for "Daniel Ellsberg <ellsberg@example.org>" already exists
+  │ Create anyway? (y/N) y
+  │ gpg: creating anyway
+  │ [...]
+  │ pub   rsa2048/BD19AC1C 2014-11-04
+  │       Key fingerprint = 15CB 723E 2000 A1A8 2505  F3B7 CC00 B501 BD19 AC1C
+  │ uid       [ultimate] Daniel Ellsberg <ellsberg@example.org>
+  │ sub   rsa2048/72A4D018 2014-11-04
+  ╰────
+
+  Another common operation is to sign a key.  /gpg/ can do this directly
+  from the command line by giving the fingerprint of the to-be-signed
+  key:
+
+  ╭────
+  │ $ gpg2 --quick-sign-key  '15CB 723E 2000 A1A8 2505  F3B7 CC00 B501 BD19 AC1C'
+  │
+  │ pub  rsa2048/BD19AC1C
+  │      created: 2014-11-04  expires: never       usage: SC
+  │      trust: ultimate      validity: ultimate
+  │  Primary key fingerprint: 15CB 723E 2000 A1A8 2505  F3B7 CC00 B501 BD19 AC1C
+  │
+  │      Daniel Ellsberg <ellsberg@example.org>
+  ╰────
+
+  In case the key has already been signed, the command prints a note and
+  exits with success.  In case you want to check that it really worked,
+  use `=--check-sigs' as usual:
+
+  ╭────
+  │ $ gpg2 --check-sigs  '15CB 723E 2000 A1A8 2505  F3B7 CC00 B501 BD19 AC1C'
+  │ gpg: checking the trustdb
+  │ gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
+  │ gpg: depth: 0  valid:   6  signed:   1  trust: 0-, 0q, 0n, 0m, 0f, 6u
+  │ pub   rsa2048/BD19AC1C 2014-11-04
+  │ uid       [  full  ] Daniel Ellsberg <ellsberg@example.org>
+  │ sig!3        BD19AC1C 2014-11-04  Daniel Ellsberg <ellsberg@example.org>
+  │ sig!         68FD0088 2014-11-04  Glenn Greenwald <glenn@example.org>
+  │ sub   rsa2048/72A4D018 2014-11-04
+  │ sig!         BD19AC1C 2014-11-04  Daniel Ellsberg <ellsberg@example.org>
+  ╰────
+
+
+  The fingerprint may also be given without the spaces in which case
+  there is no need for the quotes.  If you want to sign only certain
+  user ids of a key, list those user id verbatim after the fingerprint.
+  To create a non-exportable key signature, use the command
+  `--quick-lsign-key' instead.
+
+
+1.6 Improved Pinentry support
+─────────────────────────────
+
+  When using a recent Pinentry module (0.90, GTK+ variant), the
+  gpg-agent will not anymore show two separate Pinentry dialogs to enter
+  a new passphrase and later to confirm the new passphrase.  Instead the
+  first dialog also has the confirm/repeat entry and internally checks
+  whether they match.
+
+  With any Pinentry version the several separate dialogs to inform and
+  ask for confirmation about questionable properties of a new passphrase
+  (e.g. length, only alpha letters) have been combined into one dialog
+  to show all non-asserted constraints at once.
+
+  The GTK+ Pinentry does now allow pasting of values into the entries.
+  Copying them from the entries is still inhibited on purpose.
+  Depending on the system, the option `no-grab' may be required for in
+  the `gpg-agent.conf' file to actually make use of the paste feature.
+
+
+1.7 Auto-start of the gpg-agent
+───────────────────────────────
+
+  The /gpg-agent/ is the central part of the GnuPG system.  It takes
+  care of all private (secret) keys and if required diverts operations
+  to a smartcard or other token.  It also provides support for the
+  Secure Shell by implementing the ssh-agent protocol.
+
+  The classic way to run /gpg-agent/ on Unix systems is by launching it
+  at login time and use an environment variable (`GPG_AGENT_INFO') to
+  tell the other GnuPG modules how to connect to the agent.  However,
+  correctly managing the start up and this environment variable is
+  cumbersome so that that an easier method is required.  Since GnuPG
+  2.0.16 the `--use-standard-socket' option already allowed to start the
+  agent on the fly; however the environment variable was still required.
+
+  With GnuPG 2.1 the need of `GPG_AGENT_INFO' has been completely
+  removed and the variable is ignored.  Instead a fixed Unix domain
+  socket named `S.gpg-agent' in the GnuPG home directory (by default
+  `~/.gnupg') is used.  The agent is also started on demand by all tools
+  requiring services from the agent.
+
+  If the option `--enable-ssh-support' is used the auto-start mechanism
+  does not work because /ssh/ does not know about this mechanism.
+  Instead it is required that the environment variable `SSH_AUTH_SOCK'
+  is set to the `S.gpg-agent.ssh' socket in the GnuPG home directory.
+  Further /gpg-agent/ must be started: Either by using a GnuPG command
+  which implicitly starts /gpg-agent/ or by using `gpgconf --launch
+  gpg-agent' to explicitly start it if not yet done.
+
+
+1.8 Duplicate long key id fixes
+───────────────────────────────
+
+  A deficit of the OpenPGP protocol is that signatures carry only a
+  limited indication on which public has been used to create a
+  signature.  Thus a verification engine may only use this “long key id”
+  to look up the the key in its own store or from a public keyserver.
+  Unfortunately it has now become possible to create a key with a long
+  key id matching the key id of another key.  Importing a key with a
+  long key id already used by another key in gpg’s local key store was
+  not possible due to checks done on import.  Now, if the “wrong” key
+  has been imported first /gpg/ would not allow to later import the
+  second “correct” key.  This problem has been fixed in 2.1 by allowing
+  the import and by doing trial verification against all matching keys.
+
+
+1.9 Enhanced Dirmngr
+────────────────────
+
+  Before version 2.1, /gpg/ used so-called keyserver helpers to access
+  the OpenPGP keyservers.  A problem with that is that they are short
+  living processes which are not able to keep a state.  With 2.1, the
+  formerly separate package Dirmngr (which was separate due to copyright
+  assignment reasons) has been integrated into GnuPG.
+
+  In the past /dirmngr/ was only used by /gpgsm/ for X.509 (S/MIME) CRL
+  and OCSP handling.  Being a proper part of GnuPG /dirmngr/ does now
+  also care about accessing OpenPGP keyservers.  This make its easier to
+  debug problems with the keyservers and to exchange additional
+  information about the keyserver between /gpg/ and /dirmngr/.  It will
+  eventually also be possible to run background tasks to refresh keys.
+
+  Although the ability to start /dirmngr/ as a system service is still
+  available, this is not anymore recommended and instead /dirmngr/ is
+  now by default started on-demand, very similar to /gpg-agent/.
+
+
+1.10 Better keyserver pool support
+──────────────────────────────────
+
+  For load balancing reasons, keyservers are organized in pools to
+  enable instant round-robin DNS assignment of random keyservers.  A
+  problem with that approach is that the DNS resolver is not aware of
+  the state of the keyserver.  If a keyserver has gone down or a routing
+  problems occurs, /gpg/ and its keyserver helpers were not ware of it
+  and would try over and over to use the same, dead, keyserver up until
+  the DNS information expires and a the DNS resolver assigned a new
+  server from the pool.
+
+  The new /dirmngr/ in GnuPG does not use the implicit round-robin of
+  the DNS resolver but uses its own DNS look up and keeps an internal
+  table of all hosts from the pool along with the encountered aliveness
+  state.  Thus after a failure (timeout) of a request, /dirmngr/ flags a
+  host as dead and randomly selects another one from the pool.  After a
+  few hours the flag is removed so that the host will be tried again.
+  It is also possible to mark a specif host from a pool explicitly as
+  dead so that it won’t be used in future.  To interact with the
+  /dirmngr/ the `gpg-connect-agent' tool is used:
+
+  ╭────
+  │ $ gpg-connect-agent --dirmngr 'help keyserver' /bye
+  │ $ gpg-connect-agent --dirmngr 'keyserver --hosttable' /bye
+  ╰────
+
+  The first command prints a help screen for the keyserver command and
+  the second command prints the current host table.
+
+
+1.11 Faster keyring format
+──────────────────────────
+
+  The format GnuPG has always used for the public keyring is actually a
+  slightly extended version of the on-the-wire format for OpenPGP key
+  exchange.  This format is quite inflexible to work with when random
+  access to keys in the keyring is required.  In fact /gpg/ always
+  parsed all keys in the keyring until it encountered the desired one.
+  With a large keyring (more than a few thousand keys) this could be
+  quite slow.
+
+  From its very beginning /gpgsm/ has used a different format to store
+  public keys (certificates) which we call a /keybox/. That file format
+  carries meta information about the stored keys and thus allows
+  searching without actually parsing the key and computing fingerprints
+  and such.  The /keybox/ format has been designed protocol independent
+  and with 2.1 support for OpenPGP keys has been added.  Random access
+  to the keys is now really fast and keyrings with 30000 keys and more
+  are now easily possible.  That change also enables us to easily
+  introduce other storage methods
+
+  If no `pubring.gpg' is found, /gpg/ defaults to the new /keybox/
+  format and creates a `pubring.kbx' keybox file.  If such a keybox file
+  already exists, for example due to the use of /gpgsm/, it will also be
+  used for OpenPGP keys.  However, if a `pubring.gpg' is found and no
+  keybox file with OpenPGP keys exists, the old `pubring.gpg' will be
+  used.  Take care: GnuPG versions before 2.1 will always use the
+  `pubring.gpg' file and not know anything about keys stored in the
+  keybox file.
+
+  To convert an existing `pubring.gpg' file to the keybox format, you
+  first rename the file to (for example) `publickeys' so it won’t be
+  recognized by any GnuPG version and then you run the command
+
+  ╭────
+  │ $ gpg2 --import publickeys
+  ╰────
+
+  You may then rename the `publickeys' file back so that it can be used
+  by older GnuPG versions.  Remember that in this case you have two
+  independent copies of the public keys.
+
+
+1.12 Auto-generated revocation certificates
+───────────────────────────────────────────
+
+  This version creates an ASCII armored revocation certificate for each
+  generated keypair and stores that certificate in a file named after
+  the fingerprint of the key in the `openpgp-revocs.d' directory below
+  the GnuPG home directory.  Brief instructions on how to use this
+  revocation certificate are put at the top of the file.
+
+
+1.13 Improved card support
+──────────────────────────
+
+  The /scdaemon/, which is responsible for accessing smardcards and
+  other tokens, has received may updates.  In particular plugable USB
+  readers with a fixed card now work smoothless and similar to standard
+  readers.  The latest features of the /gnuk/ token are supported.  Code
+  for the HSM smartcard has been added.  More card readers with a PIN
+  pad are supported.  The internal CCID driver does now also work with
+  certain non-auto configuration equipped readers.
+
+
+1.14 New format for key listings
+────────────────────────────────
+
+  Due to the introduction of ECC keys the old format to list keys was
+  not anymore suitable.  In particular, the length of an ECC key is
+  defined but its expressiveness is limited without the other parameters
+  of the curve.  The common way to describe an ECC key is by using the
+  assigned name of its curve.  To allow for a common description we now
+  either use the algorithm name with appended key length or use the name
+  of the curve:
+
+  ╭────
+  │ pub   2048D/1E42B367 2007-12-31 [expires: 2018-12-31]
+  │ pub   dsa2048/1E42B367 2007-12-31 [expires: 2018-12-31]
+  │ pub   ed25519/0AA914C9 2014-10-18
+  ╰────
+
+  The first two lines show the same key in the old format and in the new
+  format.  The third line shows an example of an ECC key using the
+  ed25519 curve.
+
+  As a further change the validity of a key is now shown by default;
+  that is `show-uid-validity' is implicitly used for the
+  `--list-options'.
+
+  The annotated key listing produced by the `--with-colons' options did
+  not change.  However a couple of new fields have been added, for
+  example if the new option `--with-secret-' is used the “S/N of a token
+  field” indicates the presence of a secret key even in a public key
+  listing.  This option is supported by recent [GPGME] versions and
+  makes writing of key manager software easier.
+
+
+  [GPGME] https://gnupg.org/related_software/gpgme/
+
+
+1.15 Support for Putty
+──────────────────────
+
+  On Windows the new option `--enable-putty-support' allows gpg-agent to
+  act as a replacement for [Putty]’s authentication agent /Pageant/.  It
+  is the Windows counterpart for the `--enable-ssh-support' option as
+  used on Unix.
+
+
+  [Putty] http://www.chiark.greenend.org.uk/~sgtatham/putty/
+
+
+1.16 Improved X.509 certificate creation
+────────────────────────────────────────
+
+  In addition to an improved certificate signing request menu, it is now
+  possible to create a self-signed certificate using the interactive
+  menu of /gpgsm/.
+
+  In batch mode the certificate creation dialog can now be controlled by
+  a parameter file with several new keywords.  Such a parameter file
+  allows the creation of arbitrary X.509 certificates similar to what
+  can be done with /openssl/.  It may this be used as the base for a CA
+  software.  For details see the “CSR and certificate creation” section
+  in the manual.
+
+  The new commands `--export-secret-key-p8' and –export-secret-key-raw=
+  may be used to export a secret key directly in PKCS#8 or PKCS#1
+  format.  Thus X.509 certificates for TLS use may be managed by /gpgsm/
+  and directly exported in a format suitable for OpenSSL based servers.
+
+
+1.17 Scripts to create a Windows installer
+──────────────────────────────────────────
+
+  GnuPG now comes with the /speedo/ build system which may be used to
+  quickly download and build GnuPG and all its direct dependencies on a
+  decent Unix system.  See the README file for more instructions.
+
+  The very same script may also be used to build a complete NSIS based
+  installer for Windows using the mingw-w64 cross-compiler toolchain.
+  That installer will feature GnuPG proper, GPA as graphical frontend,
+  and GpgEX as a Windows Explorer extension.  GnuPG needs to be unpacked
+  and from the top source directory you run this command
+
+  ╭────
+  │ make -f build-aux/speedo.mk w32-installer
+  ╰────
+
+  This command downloads all direct dependencies, checks the signatures
+  using the GnuPG version from the build system (all Linux distros
+  feature a suitable GnuPG tool), builds everything from source, and
+  uses NSIS to create the installer.  Although this sounds easy, some
+  experience in setting up a development machine is still required.
+  Some versions of the toolchain exhibit bugs and thus your mileage may
+  vary.  Support for keyserver access over TLS is currently not
+  available but will be added with one of the next point releases.
+
+
+
+  # Copyright 2014 The GnuPG Project.
+  # This work is licensed under the Creative Commons
+  # Attribution-ShareAlike 4.0 International License.  To view a copy of
+  # this license, visit http://creativecommons.org/licenses/by-sa/4.0/
+  # or send a letter to Creative Commons, PO Box 1866, Mountain View, CA
+  # 94042, USA.
+  #
+  # The canonical source for this article can be found in the gnupg-doc
+  # git repository as web/faq/whats-new-in-2.1.org.
index fc932d9..f780952 100644 (file)
     detects the number of white spaces in front of an @item and remove
     this number of spaces from all following lines until a new @item
     is found or there are less spaces than for the last @item.
+
+    Note that @* does only work correctly if used at the end of an
+    input line.
+
 */
 
 #include <stdio.h>
@@ -136,6 +140,9 @@ typedef struct macro_s *macro_t;
 /* List of all defined macros. */
 static macro_t macrolist;
 
+/* List of variables set by @set. */
+static macro_t variablelist;
+
 /* List of global macro names.  The value part is not used.  */
 static macro_t predefinedmacrolist;
 
@@ -375,8 +382,44 @@ set_macro (const char *macroname, char *macrovalue)
 }
 
 
-/* Return true if the macro NAME is set, i.e. not the empty string and
-   not evaluating to 0.  */
+/* Create or update a variable with name and value given in NAMEANDVALUE.  */
+static void
+set_variable (char *nameandvalue)
+{
+  macro_t m;
+  const char *value;
+  char *p;
+
+  for (p = nameandvalue; *p && *p != ' ' && *p != '\t'; p++)
+    ;
+  if (!*p)
+    value = "";
+  else
+    {
+      *p++ = 0;
+      while (*p == ' ' || *p == '\t')
+        p++;
+      value = p;
+    }
+
+  for (m=variablelist; m; m = m->next)
+    if (!strcmp (m->name, nameandvalue))
+      break;
+  if (m)
+    free (m->value);
+  else
+    {
+      m = xcalloc (1, sizeof *m + strlen (nameandvalue));
+      strcpy (m->name, nameandvalue);
+      m->next = variablelist;
+      variablelist = m;
+    }
+  m->value = xstrdup (value);
+}
+
+
+/* Return true if the macro or variable NAME is set, i.e. not the
+   empty string and not evaluating to 0.  */
 static int
 macro_set_p (const char *name)
 {
@@ -385,6 +428,10 @@ macro_set_p (const char *name)
   for (m = macrolist; m ; m = m->next)
     if (!strcmp (m->name, name))
       break;
+  if (!m)
+    for (m = variablelist; m ; m = m->next)
+      if (!strcmp (m->name, name))
+        break;
   if (!m || !m->value || !*m->value)
     return 0;
   if ((*m->value & 0x80) || !isdigit (*m->value))
@@ -609,7 +656,6 @@ write_th (FILE *fp)
   *p++ = 0;
   fprintf (fp, ".TH %s %s %s \"%s\" \"%s\"\n",
            name, p, isodatestring (), opt_release, opt_source);
-  free (name);
   return 0;
 }
 
@@ -665,8 +711,11 @@ proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
     { "table",   3 },
     { "itemize",   3 },
     { "bullet",  0, "* " },
+    { "*",       0, "\n.br"},
+    { "/",       0 },
     { "end",     4 },
     { "quotation",1, ".RS\n\\fB" },
+    { "value", 8 },
     { NULL }
   };
   size_t n;
@@ -742,11 +791,46 @@ proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
         case 7:
           ignore_args = 1;
           break;
+        case 8:
+          ignore_args = 1;
+          if (*rest != '{')
+            {
+              err ("opening brace for command '%s' missing", command);
+              return len;
+            }
+          else
+            {
+              /* Find closing brace.  */
+              for (s=rest+1, n=1; *s && n < len; s++, n++)
+                if (*s == '}')
+                  break;
+              if (*s != '}')
+                {
+                  err ("closing brace for command '%s' not found", command);
+                  return len;
+                }
+              else
+                {
+                  size_t len = s - (rest + 1);
+                  macro_t m;
+
+                  for (m = variablelist; m; m = m->next)
+                    if (strlen (m->name) == len
+                        &&!strncmp (m->name, rest+1, len))
+                      break;
+                  if (m)
+                    fputs (m->value, fp);
+                  else
+                    inf ("texinfo variable '%.*s' is not set",
+                         (int)len, rest+1);
+                }
+            }
+          break;
         default:
           break;
         }
     }
-  else
+  else /* macro */
     {
       macro_t m;
 
@@ -1216,6 +1300,10 @@ parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
               macrovalue = xmalloc ((macrovaluesize = 1024));
               macrovalueused = 0;
             }
+          else if (n == 4 && !memcmp (line, "@set", 4))
+            {
+              set_variable (p);
+            }
           else if (n == 8 && !memcmp (line, "@manpage", 8))
             {
               free (*section_name);
@@ -1326,6 +1414,13 @@ top_parse_file (const char *fname, FILE *fp)
       free (macrolist);
       macrolist = next;
     }
+  while (variablelist)
+    {
+      macro_t next = variablelist->next;
+      free (variablelist->value);
+      free (variablelist);
+      variablelist = next;
+    }
   for (m=predefinedmacrolist; m; m = m->next)
     set_macro (m->name, xstrdup ("1"));
   cond_is_active = 1;
index 48a05ad..31359d8 100644 (file)
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-11-30  Werner Koch  <wk@g10code.com>
 
-       * keyedit.c (show_key_with_all_names): Remove set but unused var
-       PK_VERION.
-       * sig-check.c (do_check): Remove set but unused var CTX.
+        * keyserver.c (keyserver_import_cert): Adjust for changed
+       get_dns_cert.
 
-       * build-packet.c (do_user_id): Return RC.
+2011-11-28  Werner Koch  <wk@g10code.com>
+
+       * keyserver.c (DEFAULT_MAX_CERT_SIZE): Increase from 16k to 64k.
+
+2011-11-22  Werner Koch  <wk@g10code.com>
+
+       * pubkey-enc.c (get_session_key): Don't print anonymous recipient
+       messages in quiet mode.  This is bug#1378.
+
+2011-11-06  Werner Koch  <wk@g10code.com>
+
+       * card-util.c (generate_card_keys): Add arg CTRL.
+
+       * call-agent.c (agent_readkey): New.
+       * keygen.c (do_create_from_keygrip): New.
+       (ask_algo): Add arg R_KEYGRIP and a prompt to enter it.
+       (generate_subkeypair): Call do_create_from_keygrip if required.
+       (generate_subkeypair): Add arg CTRL.  Change caller.
+       (ask_algo): Add arg CTRL.
+       (generate_keypair): Ditto.
+
+2011-09-23  Werner Koch  <wk@g10code.com>
+
+       * gpgv.c (disable_dotlock): Rename to dotlock_disable.
+       (create_dotlock): Rename to dotlock_create.
+       (destroy_dotlock): Rename to dotlock_destroy.
+       (make_dotlock): Rename to dotlock_take.
+       (release_dotlock): Rename to dotlock_release.
+       (lockfiles_remove): Rename to dotlock_remove_lockfiles.
+
+2011-09-20  Werner Koch  <wk@g10code.com>
+
+       * free-packet.c (free_public_key): Allow a NULL argument.
+       * keyedit.c (keyedit_passwd): No more need to check that PK is NULL.
+       (menu_addrevoker): Ditto.
+       * passphrase.c (passphrase_get, passphrase_to_dek_ext): Ditto.
+       * skclist.c (release_sk_list): Ditto.
+       * revoke.c (gen_desig_revoke): Ditto.
+       * pubkey-enc.c (get_session_key): Ditto.
+       * pkclist.c (build_pk_list): Ditto.
+
+2011-09-20  Jim Meyering  <meyering@redhat.com>
+
+       avoid use of freed pointer
+       If we free pk2 at the top of the for-loop, set it to NULL
+       so that we don't free it again just before returning.
+       * revoke.c (gen_desig_revoke): Don't use pk2 after freeing it.
+
+2011-09-20  Werner Koch  <wk@g10code.com>
+
+       * sign.c (sign_file, clearsign_file, sign_symencrypt_file):
+       s/gcry_md_start_debug/gcry_md_debug/ in preparation for Libgcrypt
+       1.6.
+       * mainproc.c (proc_plaintext, proc_tree): Ditto.
+       * decrypt-data.c (decrypt_data): Ditto.
+       * cipher.c (write_header): Ditto.
+
+2011-08-10  Werner Koch  <wk@g10code.com>
+
+       * export.c (transfer_format_to_openpgp): Don't parse unneeded CSUM.
+
+       * import.c (import_secret_one): Use arg OPTIONS instead of global
+       import options var.
+
+       * sig-check.c (do_check): Remove unused var CTX.
+
+       * build-packet.c (do_user_id): Return value.
 
 2011-07-29  Werner Koch  <wk@g10code.com>
 
        * tdbio.c (open_db): Do not print read-only warning in quiet mode.
 
-2011-07-22  Werner Koch  <wk@g10code.com>
+2011-07-18  Werner Koch  <wk@g10code.com>
 
        * parse-packet.c (parse_key): Print the decoded iteration count.
        Fixes bug#1355.
 
-2011-07-01  Werner Koch  <wk@g10code.com>
+2011-07-07  Werner Koch  <wk@g10code.com>
 
-       * keyid.c (pubkey_letter): Add letters e and E.
+       * card-util.c (ask_card_keysize): Bump key size limit to 4096.
+       * call-agent.c (scd_genkey_parm_s): New.
+       (agent_scd_genkey): Use new struct.
+       (scd_genkey_cb): Implement chunked mode for KEY-DATA.
+       (scd_genkey_cb_append_savedbytes): New.
+
+2011-06-16  Werner Koch  <wk@g10code.com>
+
+       * card-util.c (ask_card_keysize): Bump key size limit to 4096.
+       * call-agent.c (scd_genkey_parm_s): New.
+       (agent_scd_genkey): Use new struct.
+       (scd_genkey_cb): Implement chunked mode for KEY-DATA.
+       (scd_genkey_cb_append_savedbytes): New.
 
 2011-06-13  Werner Koch  <wk@g10code.com>
 
-       * pkglue.c (mpi_from_sexp, pk_decrypt): Use GCRYMPI_FMT_USG for
-       gcry_sexp_nth_mpi.  This fixes a problem with a recent bug fix in
-       Libgcrypt.
+       * pkglue.c (mpi_from_sexp): Use GCRYMPI_FMT_USG to avoid problems
+       with leading zeroed.  The latest Libgcrypt does this now
+       correctly.  Given that the default of gcry_sexp_nth_mpi would use
+       a signed MPI, which is not implemented, the assertion would fail.
+
+2011-06-01  Marcus Brinkmann  <mb@g10code.com>
+
+       * parse-packet.c (parse_pubkeyenc): Change type of N to size_t.
+       (parse_key): Likewise.
+       * seskey.c (encode_session_key): Convert nframe to int for
+       debugging.
+       * build-packet.c (gpg_mpi_write): Change type of N to unsigned int.
+       * import.c (transfer_secret_keys): Likewise.
+
+2011-04-29  Werner Koch  <wk@g10code.com>
+
+       * keydb.c (keydb_get_keyblock, keydb_add_resource): Use gpg_error.
+       (keydb_get_keyblock): Return VALUE_NOT_FOUND instead of -1.
+       (keydb_update_keyblock, keydb_insert_keyblock)
+       (keydb_delete_keyblock): Ditto.
+       (keydb_locate_writable): Ditto.
+       (keydb_search_reset): Ditto.
+       (keydb_search2): Return GPG_ERR_NOT_FOUND instead of -1.  Change
+       all callers.
+       (keydb_search_first, keydb_search_next, keydb_search_kid)
+       (keydb_search_fpr): Ditto.
+
+2011-04-29  Marcus Brinkmann  <marcus@g10code.com>
+
+       * import.c (import_secret_one): Leave all checks to import_one.
+       Cancel secret key import if public key was skipped due to
+       merge-only request.  Fix import status for non-new secret key
+       import by checking stat counter.
+
+2011-04-29  Marcus Brinkmann  <marcus@g10code.com>
+
+       * delkey.c (do_delete_key): Access public keyblock even for secret
+       key operations.  But deleting secret key is not supported yet, so
+       give an error.  Limit secret-key-exists error case to public keys.
+
+2011-04-28  Werner Koch  <wk@g10code.com>
+
+       * ecdh.c (pk_ecdh_encrypt_with_shared_point): Remove memory leak
+       of SECRET_X in the error case.  Replace an assert by an error
+       return.
+
+2011-04-26  Werner Koch  <wk@g10code.com>
+
+       * export.c (transfer_format_to_openpgp): Do not apply
+       encode_s2k_iterations to S2K_COUNT.
+
+2011-04-25  Werner Koch  <wk@g10code.com>
+
+       * delkey.c (do_delete_key): Mark classify_user_id for use with
+       OpenPGP.
+       * trustdb.c (register_trusted_key): Ditto.
+       * revoke.c (gen_revoke): Ditto.
+       * keyserver.c (keyserver_export, keyidlist, keyserver_export): Ditto.
+       * getkey.c (key_byname): Ditto.
+       * export.c (do_export_stream): Ditto.
+
+2011-04-20  Marcus Brinkmann  <mb@g10code.com>
+
+       * keylist.c (list_keyblock_colon): Use get_ownertrust_info, not
+       get_ownertrust (which lead to binary zeroes in the output!).
+
+2011-03-23  Werner Koch  <wk@g10code.com>
+
+       * parse-packet.c (read_rest): Drop unsed PARTIAL arg.  Rewrite to
+       detect premature EOF.  Suggested by Timo Schulz.
+
+2011-03-10  Werner Koch  <wk@g10code.com>
+
+       * passphrase.c (hash_passphrase): Remove.
+       (passphrase_to_dek_ext): Use gcry_kdf_derive.
+
+2011-03-03  Werner Koch  <wk@g10code.com>
+
+       * keylist.c (print_card_key_info): Re-implement using the agent.
+       * card-util.c (card_status) [GNUPG_MAJOR_VERSION!=1]: Call
+       print_card_key_info.
+
+       * keyid.c (hash_public_key): Remove shadowing NBITS.
+
+       * misc.c (pubkey_nbits): Replace GCRY_PK_ by PUBKEY_ALGO_.
+       (get_signature_count): Remove warning.
+
+       * armor.c (armor_filter): Don't take a copy of radbuf while
+       writing the checksum.  This works around a faulty gcc 4.4 warning.
+
+2011-03-02  Werner Koch  <wk@g10code.com>
+
+       * call-agent.c (agent_scd_pksign, agent_scd_pkdecrypt)
+       (hash_algo_option): Remove these unused functions.
+
+2011-02-10  Werner Koch  <wk@g10code.com>
+
+       * seskey.c (encode_md_value): Change last fix to avoid a
+       regression for DSA with SHA-2 hashes.
+
+2011-02-09  Werner Koch  <wk@g10code.com>
+
+       * keyserver.c: Replace all printf by es_printf.
+
+2011-02-08  Werner Koch  <wk@g10code.com>
+
+       * call-dirmngr.c (gpg_dirmngr_ks_fetch): New.
+       * keyserver.c (keyserver_fetch): Rewrite to use dirmngr.
+
+2011-02-07  Werner Koch  <wk@g10code.com>
+
+       * seskey.c (encode_md_value): Truncate to MDLEN and not to QBYTES
+       which makes a difference with 521 bit ECC keys.  For clarity
+       rename QBYTES to QBITS and adjust accordingly.
+
+2011-02-04  Werner Koch  <wk@g10code.com>
+
+       * sig-check.c (do_check_messages): Remove the long deprecated
+       SIGEXPIRED status line.
+
+2011-02-03  Werner Koch  <wk@g10code.com>
+
+       * export.c (transfer_format_to_openpgp) [!HAVE_GCRY_PK_GET_CURVE]:
+       Fix syntax error.
+
+       * decrypt-data.c: Include status.h.
+       (decrypt_data): Emit a DECRYPTION_INFO status line.
+
+       * misc.c (has_invalid_email_chars): Relax mailbox name checking.
+       Fixes bug#1315.
+
+       * sign.c (do_sign): Use openpgp_pk_algo_name.
+
+       * keygen.c (ask_algo): Show ECC algos only in expert mode.  Add
+       non-combined menu entries for ECDSA and ECDH.
+       (ask_key_flags): Use openpgp_pk_algo_name.
+
+2011-02-03  Werner Koch  <wk@g10code.com>
+
+       Finished ECC integration.
+       Wrote change description for 2011-01-13.
+
+2011-02-02  Werner Koch  <wk@g10code.com>
+
+       * encrypt.c (write_pubkey_enc_from_list): Don't compute the
+       fingerprint.
+       * pkglue.c (pk_encrypt): Replace PK_FP by PK and compute the
+       fingerprint only when needed.
+       * pkglue.h: Include packet.h.
+
+       * import.c (transfer_secret_keys): Make sure keyids are available.
+
+       * keyid.c (hash_public_key): Adjust for the ECC case.
+
+2011-02-01  Werner Koch  <wk@g10code.com>
+
+       * gpg.c (main): Call setup_libgcrypt_logging.
+
+       * import.c (transfer_secret_keys): Implement ECC case.
+       (one_mpi_from_pkey): New.
+       * export.c (transfer_format_to_openpgp): Ditto.
+       * keygen.c (gpg_curve_to_oid): New.
+       (ecckey_from_sexp): Factor curve name mapping out to new function.
+
+2011-01-31  Werner Koch  <wk@g10code.com>
+
+       * ecdh.c (pk_ecdh_encrypt_with_shared_point): Return an opaque MPI.
+
+       * build-packet.c (mpi_write): Rename to gpg_mpi_write and make global.
+
+2011-01-30  Werner Koch  <wk@g10code.com>
+
+       * keyid.c (keygrip_from_pk): Adjust ECC cases.
+       * pkglue.c (pk_verify): Ditto.
+
+       * parse-packet.c (parse_key): Simply ECC case.
+       (parse_pubkeyenc): Ditto.
+
+       * misc.c (pubkey_get_npkey): Special case ECC.
+       (pubkey_get_nskey): Ditto.
+       (mpi_print): Support printing of opaque values.
+       (openpgp_oid_to_str): New.
+       (pubkey_nbits): For ECC pass curve parameter.
+
+       * ecdh.c (pk_ecdh_default_params): Change to return an opaque MPI.
+
+       * build-packet.c (do_key): Automatically handle real and opaque
+       key parameters.
+       (write_fake_data): Return an error code.
+       (mpi_write): Support writing opaque MPIs.
+       (do_pubkey_enc): Simplify ECC handling.
+
+2011-01-28  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (gen_ecc): Rewrite.  Select a named curve and create a
+       keyspec based on that.
+       (pk_ecc_build_key_params): Remove.
+       (get_parameter_algo): Map algo number.
+       (ecckey_from_sexp): New.
+       * misc.c (map_pk_gcry_to_openpgp): New.
+
+2011-01-25  Werner Koch  <wk@g10code.com>
+
+       * ecdh.c (pk_ecdh_default_params_to_mpi): Remove.
+       (pk_ecdh_default_params): Rewrite.  Factor KEK table out to ..
+       (kek_params_table): .. here.
+       (pk_ecdh_generate_ephemeral_key): New.
+       (pk_ecdh_encrypt): Remove.
+       (pk_ecdh_encrypt_with_shared_point): Make public.
 
-2011-01-10  Werner Koch  <wk@g10code.com>
+       * pubkey-enc.c (get_it): Fix assertion.  Use GPG_ERR_WRONG_SECKEY
+       instead of log_fatal.  Add safety checks for NFRAME.
 
-       * keygen.c (ask_user_id): Fix duplicate test for AMAIL by correct
-       ANAME.  See bug#1307.  Reported by Steve Grubb.
+       * keygen.c (pk_ecc_keypair_gen): Make static.
+       (ask_keysize): Use proper rounding for ECC.
+       (pk_ecc_build_key_params): Remove NBITSSTR.
 
-       * import.c (import_keys_internal): Make loop code a bit more
-       readable.  See bug#1307.  Reported by Steve Grubb.
+2011-01-20  Werner Koch  <wk@g10code.com>
 
-       * sign.c (sign_file): Fix TEMP_HASHLEN computation.  See bug#1307.
-       Reported by Steve Grubb.
+       * keyserver.c: Rewrite most stuff for use with dirmngr.  Get rid
+       of all spawn code.  More work pending.
+
+       * export.c (export_pubkeys_buffer): New.
+
+       * import.c (import_keys_es_stream): New.
+
+       * call-dirmngr.c, call-dirmngr.h: New.
+       * gpg.h (server_control_s): Add DIRMNGR_LOCAL.
+       * gpg.c: Include call-dirmngr.h.
+       (gpg_deinit_default_ctrl): Call gpg_dirmngr_deinit_session_data.
+
+2011-01-13  Andrey Jivsov  <openpgp@brainhub.org>  (wk)
+
+       Integrated ECC support.  Below are the changes finally merged into
+       the git master after some cleanup by wk until 2011-02-03.
+
+       * ecdh.c: New.
+
+       * sign.c (mpi_from_sexp): Remove.
+       (match_dsa_hash): Uses SHA-512 for ECDSA with 521 bits.
+       (hash_for): Support ECDSA.
+       (make_keysig_packet): Ditto.
+
+       * seskey.c (encode_session_key): Add arg OPENPGP_PK_ALGO.  Support
+       ECDH.
+       (encode_md_value): Map pkalgo.  Extend size checks to ECDSA.
+
+       * pubkey-enc.c (get_it): Support ECDH.
+
+       * pkglue.c (mpi_from_sexp): Make global.
+       (pk_verify, pk_encrypt, pk_check_secret_key): Support ECC.
+
+       * parse-packet.c (read_size_body): New.
+       (parse_pubkeyenc): Support ECC.
+       (parse_key): Ditto.
+
+       * misc.c (map_pk_openpgp_to_gcry, map_pk_gcry_to_openpgp): New.
+       (openpgp_pk_test_algo, openpgp_pk_test_algo2): Map algo numbers.
+       (openpgp_pk_algo_usage): Support ECDH and ECDSA.
+       (openpgp_pk_algo_name): Simplify.
+       (ecdsa_qbits_from_Q): New.
+
+       * mainproc.c (proc_pubkey_enc): Support ECC.
+
+       * keyid.c (pubkey_letter): Add 'E' and 'e'.
+       (keygrip_from_pk): Supporf ECC.
+
+       * keygen.c: Include pkglue.h.
+       (ask_algo): Add option 9 for ECDSA and ECDH.
+       (ask_keysize): Support ECDSA and ECDH.
+       (do_create): Ditto.
+       (gen_ecc): New.
+       (pk_ecc_build_key_params): New.
+
+       * getkey.c (cache_public_key): Support ECC.
+
+       * encrypt.c (write_pubkey_enc_from_list): Pass PK to PK_ENCRYPT
+       and the pkalgo to encode_session_key.
+
+       * build-packet.c (do_key, do_pubkey_enc): Support ECC.
+       (write_size_body_mpi): New.
+
+2011-01-06  Werner Koch  <wk@g10code.com>
+
+       * gpg.c (main): Use keyserver_spec_t.
+
+       * options.h (struct opt): Factor definition of struct keyserver
+       out to ../common/keyserver.h.
+       (keyserver_spec_t): New.
+
+2011-01-21  Werner Koch  <wk@g10code.com>
+
+       * seskey.c (encode_md_value): Truncate the DSA hash again.
+
+       * misc.c (openpgp_pk_algo_name): Always use the gcrypt function.
+
+2010-12-09  Werner Koch  <wk@g10code.com>
+
+       * tdbio.c (tdbio_set_dbname) [W32CE]: Take care of missing errno.
+       (strerror) [W32CE]: Dummy replacement.
+       (open_db) [W32CE]: Use CreateFile.
+
+2010-12-02  Werner Koch  <wk@g10code.com>
+
+       * misc.c (openpgp_cipher_algo_name): Use gnupg_cipher_algo_name.
+
+2010-11-23  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (gpg2_LDFLAGS, gpgv2_LDFLAGS): Add extra_bin_ldflags.
+
+       * plaintext.c (handle_plaintext): Change to use estream.
+       s/rc/err/.  Replace some xmalloc by xtrymalloc.  Use more
+       gpg_strerror.
+       * options.h (struct): Change type of OUTFP to estream_t.
+       * decrypt.c (decrypt_message_fd): Adjust accordingly.
+
+2010-11-17  Werner Koch  <wk@g10code.com>
+
+       * keyedit.c (find_pk_from_sknode): Remove.
+       * misc.c (get_signature_count): Call agent.
+       * keygen.c (gen_card_key): Rework.  Remove arg PARA.
+       (generate_keypair): Change arg BACKUP_ENCRYPTION_DIR to the flag
+       CARD_BACKUP_KEY.
+       (pBACKUPENCDIR): Change to pCARDBACKUPKEY.
+       (struct output_control_s): Remove struct SEC.  Remove all usages
+       of it.
+       (gen_card_key_with_backup): Remove arg BACKUP_DIR.
+
+       * call-agent.c (agent_scd_genkey): Remove extra memset.
+
+2010-11-16  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (generate_card_subkeypair): Remove arg SEC_KEYBLOCK and
+       change to return an error code.  Rework for removed secring code.
+       * card-util.c (card_generate_subkey): Remove arg SEC_KEYBLOCK.
+       Return an error code instead of a success flag. Change caller.
 
 2010-10-29  David Shaw  <dshaw@jabberwocky.com>
 
        with SHA-1, just remove MD5 from the list altogether, and let the
        next-highest ranked algorithm be chosen.
 
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (ask_expire_interval): Do not print the y2038 if we
+       have an unsigned time_t.
+       * keyid.c (IS_INVALID_TIME_T): New.
+       (mk_datestr): Use it to detect the y2038 problem.
+
+2010-10-26  Werner Koch  <wk@g10code.com>
+
+       * keyedit.c (change_passphrase): Handle the passwd_nonce.
+       * call-agent.c (cache_nonce_parm_s): New.
+       (cache_nonce_status_cb): Use that new struct.
+       (agent_genkey, agent_import_key, agent_export_key, agent_passwd):
+       Adjust for that change.
+
+2010-10-25  Werner Koch  <wk@g10code.com>
+
+       * passphrase.c (gpg_format_keydesc): Fix printing of main keyid.
+
+       * keyedit.c (JNLIB_NEED_LOG_LOGV): Define.
+       * call-agent.c (agent_passwd): New.
+
+2010-10-21  Werner Koch  <wk@g10code.com>
+
+       * keyedit.c (keyedit_passwd): Simplify.
+       (change_passphrase): Return an error code and not the change
+       flag.  Remove editing of the keyring.
+
+       * seckey-cert.c: Remove.
+       * Makefile.am (gpg2_SOURCES): Remove seckey-cert.c
+
+       * revoke.c (gen_revoke): Check that the secret key is available.
+
+2010-10-20  Werner Koch  <wk@g10code.com>
+
+       * verify.c (verify_signatures): Use gpg_strerror on open failure
+       for consistency of error messages.
+
+       * packet.h (PKT_public_key): s/mdc_feature/flags.mdc/.  Change all
+       users.
+       (PKT_public_key): Split is_disabled into flags.disabled_valid and
+       flags.disabled.  Change all users.
+       (pk_is_disabled): Adjust for change.
+       (PKT_public_key): s/is_primary/flags.primary/. Change all users.
+       (PKT_public_key): s/is_revoked/flags.revoked/. Change all users.
+       (PKT_public_key): s/maybe_revoked/flags.maybe_revoked/. Change all
+       users.
+       (PKT_public_key): s/is_valid/flags.valid/. Change all users.
+       (PKT_public_key): s/dont_cache/flags.dont_cache/. Change all users.
+       (PKT_public_key): s/backsig/flags.backsig/. Change all users.
+
+       * sign.c (openpgp_card_v1_p): New.
+       (hash_for): Re-implement test for v1 cards.
+       * packet.h (PKT_public_key): Add field serialno and
+       flags.serialno_valid.
+       * free-packet.c (release_public_key_parts): Free serialno.
+
+       * parse-packet.c (parse_key): Cast -1 to size_t.
+       * trustdb.c (validate_keys): Cast -1 to size_t.  Suggested by
+       Steven M. Schweda.
+
+2010-10-18  Werner Koch  <wk@g10code.com>
+
+       * call-agent.c (agent_scd_pksign): Replace sprintf by bin2hex.
+       (agent_scd_pkdecrypt, agent_pksign): Ditto.
+
+       * sign.c (do_sign): Remove warning and commented old code.
+
+2010-10-14  Werner Koch  <wk@g10code.com>
+
+       * call-agent.c (agent_genkey): Add arg NO_PROTECTION.
+       * keygen.c (do_create, gen_elg, gen_dsa, gen_rsa, common_gen): Add
+       arg KEYGEN_FLAGS.
+       (read_parameter_file): Add options no-protection and transient-key.
+       (KEYGEN_FLAG_NO_PROTECTION, KEYGEN_FLAG_TRANSIENT_KEY): New.
+       (gen_rsa, gen_dsa, gen_elg): Use transient-key.
+
+2010-10-13  Werner Koch  <wk@g10code.com>
+
+       * call-agent.c (start_agent): Send option agent-awareness.
+       (status_sc_op_failure): Take care of GPG_ERR_FULLY_CANCELED.
+       * passphrase.c (passphrase_get): Ditto.
+       * import.c (transfer_secret_keys): Ditto.
+       * card-util.c (write_sc_op_status): Ditto.
+
+       * getkey.c (enum_secret_keys): Rewrite.
+
+       * pubkey-enc.c (get_session_key): Skip keys without an encryption
+       capability.  Handle GPG_ERR_FULLY_CANCELED.
+       * gpg.c: Add option --try-secret-key.
+       * options.h (struct opt): Add field secret_keys_to_try.
+
+       * passphrase.c (next_to_last_passphrase): Remove.
+
+2010-10-12  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (generate_subkeypair): Check availibility of secret parts.
+
+       * keylist.c (print_card_serialno): Change to take a hexified serialno.
+       (list_keyblock_print): Print serialno and stub key indicators.
+       (list_keyblock_colon): Ditto.
+
+       * getkey.c (have_any_secret_key): Remove.  Replace all calls by
+       agent_probe_any_secret_key.
+       * gpgv.c (agent_probe_any_secret_key): New.
+       (agent_get_keyinfo): New.
+
+2010-10-08  Werner Koch  <wk@g10code.com>
+
+       * gpg.c: Add option --with-keygrip.
+       * options.h (struct opt): Add WITH_KEYGRIP.
+       * keylist.c (list_keyblock_print, list_keyblock_colon): Implement
+       new option.
+
+2010-10-06  Werner Koch  <wk@g10code.com>
+
+       * import.c (transfer_secret_keys): Ignore missing key parameters.
+       Provide dummy IV.  Ignore stub keys.
+
+2010-10-01  Werner Koch  <wk@g10code.com>
+
+       * export.c (do_export_stream): Rewrite to take the secret keys
+       from the agent.
+       (canon_pubkey_algo, transfer_format_to_openpgp): New.
+
 2010-09-29  Werner Koch  <wk@g10code.com>
 
        * keygen.c (key_from_sexp): Fix memory leak in the error case.
 
-       * call-agent.c (agent_scd_pksign): Add missing space.
+       * call-agent.c (agent_export_key): New.
 
-2010-09-28  David Shaw  <dshaw@jabberwocky.com>  (wk)
+2010-09-29  Werner Koch  <wk@g10code.com>
 
-       * options.skel: Make the example for force-v3-sigs match
-       reality (it has defaulted to off since 2007-10-25).
+       * build-packet.c (build_packet): Fix up the pkttype.
+
+       * keyid.c (keystr_with_sub): Make SUB_KID optional.
+       (keystr_from_pk_with_sub): Ditto.
+
+       * call-agent.c (agent_scd_pksign): Add missing space.
+
+       * mainproc.c (struct mainproc_context): Add field CTRL.
+       (proc_packets): Add arg CTRL.  Change all callers.
+       (proc_signature_packets, proc_signature_packets_by_fd)
+       (proc_encryption_packets): Add arg CTRL.  Change all callers.
+       * compress.c (handle_compressed): Ditto.
+       * getkey.c (get_pubkey_byname): Ditto.
+       * keyserver.c (keyserver_spawn, keyserver_work): Ditto.
+       (show_prompt, keyserver_export, keyserver_import)
+       (keyserver_import_fprint, keyserver_import_keyid)
+       (keyserver_refresh, keyserver_search, keyserver_fetch)
+       (keyserver_import_name, keyserver_search_prompt)
+       (keyserver_import_pka, keyserver_import_cert): Ditto.
+       callers.
+       * verify.c (verify_signatures, verify_files): Ditto.
+       * sign.c (sign_file): Ditto.
+       * encrypt.c (encrypt_crypt, encrypt_crypt_files): Ditto.
+       * pkclist.c (find_and_check_key, build_pk_list): Ditto.
+       * keylist.c (locate_one, public_key_list, secret_key_list): Ditto.
+       * card-util.c (fetch_url, card_edit): Ditto.
+       * import.c (check_prefs, import_one, revocation_present): Ditto.
+       * keyedit.c (menu_addrevoker, keyedit_menu): Ditto.
+       * decrypt-data.c (decrypt_data): Ditto.
+       * decrypt.c (decrypt_message, decrypt_messages)
+       (decrypt_message_fd): Ditto.
+       * gpgv.c (main): Add CTRL structure.
 
 2010-09-28  Werner Koch  <wk@g10code.com>
 
-       * keyedit.c (show_key_with_all_names): Make revocation hint
-       more clear.  Fixes bug#1234.
+       * options.h (struct opt): Remove SIMPLE_SK_CHECKSUM.
+
+       * export.c (parse_export_options): Remove option
+       export-resert-subkey-passwd.
+       (do_export_stream, do_export, export_pubkeys)
+       (export_pubkeys_stream, export_seckeys, export_secsubkeys): Add
+       arg CTRL.  Change all callers.
 
        * call-agent.c (hash_algo_option): New.
        (agent_scd_pksign): Use it.
 
-2010-07-20  Werner Koch  <wk@g10code.com>
+2010-09-17  Werner Koch  <wk@g10code.com>
 
-       * mainproc.c (print_pkenc_list): Print a STATUS_ERROR.  Fixes
-       bug#1255.
+       * call-agent.c (agent_probe_any_secret_key): New.
+
+2010-09-28  David Shaw  <dshaw@jabberwocky.com>
+
+       * options.skel: Make the example for force-v3-sigs match
+       reality (it has defaulted to off since 2007-10-25).
 
-2010-06-18  Werner Koch  <wk@g10code.com>
+2010-09-06  Werner Koch  <wk@g10code.com>
 
-       * parse-packet.c (skip_packet, parse_gpg_control): Take care of
-       premature EOFs.  Backport from trunk.
+       * card-util.c (card_status): Remove stub creation for GnuPG >= 2.
+       (card_store_subkey): Temporary disable this code.
+
+       * keyedit.c (show_key_with_all_names): Merge secret and public key
+       parts.
+       (show_basic_key_info): Ditto.
+       * delkey.c (do_delete_key): Ditto.
+       * export.c (subkey_in_list_p, exact_subkey_match_p): Ditto.
+       (new_subkey_list_item): Ditto.
+       * keyid.c (keystr_from_sk, keystr_from_sk_with_sub)
+       (keyid_from_sk, nbits_from_sk, datestr_from_sk)
+       (expirestr_from_sk, colon_datestr_from_sk, fingerprint_from_sk)
+       (serialno_and_fpr_from_sk, do_fingerprint_md_sk): Remove.
+       * import.c (print_import_ok): Remove arg SK.
+       (import_secret_one): Adjust for seckey_info format.
+       (transfer_secret_keys): Ditto.  Use gpg_format_keydesc.
+       (sec_to_pub_keyblock): Simplify.
+       (pub_to_sec_keyblock): Remove.
+       (auto_create_card_key_stub): Remove - not anymore needed.
+       (update_sec_keyblock_with_cardinfo): Remove.
+       (import_secret_one): Use arg option instead of the global option.
+       * free-packet.c (copy_public_key): Adjust for seckey_info format.
+       (copy_public_parts_to_secret_key, copy_secret_key)
+       (cmp_secret_keys, cmp_public_secret_key): Remove.
+       * passphrase.c (gpg_format_keydesc): Add arg MODE and change all
+       callers.
+       * keyring.c (keyring_search): Remove special case for secret keys.
+       * mainproc.c (struct mainproc_context): Remove unused field
+       LAST_SECKEY.
+       * parse-packet.c (parse_key): Rewrite to cope with new seckey_info
+       format.
+       * build-packet.c (do_public_key, do_secret_key): Merge code into ...
+       (do_key): .. new.  Cope with seckey_info format.
+
+2010-09-03  Werner Koch  <wk@g10code.com>
+
+       * packet.h (struct seckey_info): New.
+       (PKT_public_key): Increase size of PKEY to allow storing of secret
+       keys.  Add field SECKEY_INFO.
+       (PKT_secret_key): Remove.
+       * free-packet.c (release_public_key_parts): Take care of change.
+       (release_secret_key_parts, free_secret_key): Remove.
+
+2010-09-02  Werner Koch  <wk@g10code.com>
+
+       * import.c (transfer_secret_keys, import_secret_one): Enable stats.
+       (import_secret_one): Enable secret key merging.
+
+2010-09-01  Werner Koch  <wk@g10code.com>
+
+       * sign.c (do_sign, write_signature_packets, complete_sig): Add arg
+       CACHE_NONCE.
+       (make_keysig_packet): Ditto.
+       * keygen.c (make_backsig, write_direct_sig, write_selfsigs)
+       (write_keybinding): Add arg CACHE_NONCE.
+       (do_generate_keypair): Use cache_nonce to avoid a pinentry for the
+       self-signatures.
+
+       * passphrase.c (gpg_format_keydesc): Remove now superfluous
+       algo_name fallback.
+
+       * keygen.c (gen_elg, gen_dsa, gen_rsa, do_create, common_gen): Add
+       arg CACHE_NONCE_ADDR.
+       (generate_subkeypair): Pass NULL for CACHE_NONCE_ADDR.
+       (do_generate_keypair): Add cache nonce handling.
+
+       * import.c (transfer_secret_keys): Support a cache nonce.
+       * call-agent.c (cache_nonce_status_cb): New.
+       (agent_genkey, agent_import_key): Add arg CACHE_NONCE_ADDR.
+       (agent_pksign): Ditto.
+
+2010-08-30  Werner Koch  <wk@g10code.com>
+
+       * keyid.c (KEYID_STR_SIZE): New
+       (keystr): Use snprintf and new macro.
+       (keystr_with_sub): New.
+       (keystr_from_sk_with_sub): New.
+       (keystr_from_pk_with_sub): New.
+
+2010-08-27  Werner Koch  <wk@g10code.com>
+
+       * gpg.c (main): Change scope of CTRL to the entire function.
+
+       * import.c (import_secret_one, import, import_keys_internal)
+       (import_keys, import_keys_stream): Add arg CTRL.
+       * call-agent.c (agent_keywrap_key): New.
+       (agent_import_key, inq_import_key_parms): New.
+
+2010-08-26  Werner Koch  <wk@g10code.com>
+
+       * misc.c (openpgp_pk_algo_name): New.
+       (openpgp_md_algo_name): New.
+
+2010-08-24  Werner Koch  <wk@g10code.com>
+
+       * options.h (IMPORT_SK2PK): Remove.
+       * import.c (parse_import_options): Turn convert-sk-to-pk into a
+       dummy option.
+       (sec_to_pub_keyblock): Use modern functions.
+
+2010-08-16  Werner Koch  <wk@g10code.com>
+
+       * gpg.c (list_config, gpgconf_list): Use es_printf.
+       (print_hex, print_hashline, print_algo_numbers)
+       (print_algo_names): Use es_printf.
+
+2010-07-20  Werner Koch  <wk@g10code.com>
+
+       * mainproc.c (print_pkenc_list): Write a STATUS_ERROR.  Fixes
+       bug#1255.
 
 2010-06-17  Werner Koch  <wk@g10code.com>
 
        * gpg.c (main): Use CAST5 as default s2k algo.  The macro
        USE_CAST5 was only used with GnuPG 1.x.
 
+2010-06-07  Werner Koch  <wk@g10code.com>
+
+       * cpr.c: Use estream for status output.
+
 2010-05-12  Werner Koch  <wk@g10code.com>
 
-       * armor.c (radix64_read): Change fix 2006-04-28 to fix bug#1179.
+       * armor.c (radix64_read): Extended 2006-04-28 fix to fix bug#1179.
 
        * plaintext.c (handle_plaintext): Check return code of fflush.
        Fixes bug#1207.
 
 2010-05-07  Werner Koch  <wk@g10code.com>
 
-       * import.c (chk_self_sigs): Check direct key signatures.  Fixes
+       * import.c (fix_bad_direct_key_sigs): New.
+       (import_one): Call it.
+       (chk_self_sigs): Re-indent, slighly re-arrange code, use test
+       macros for the sig class.  Check direct key signatures.  Fixes
        bug#1223.
-       (fix_bad_direct_key_sigs): New.
-       (import_one): Use it here.
 
-       * import.c (chk_self_sigs): Re-indent and slighly re-arrange code.
-       Use test macros for the sig class.
+2010-04-27  Werner Koch  <wk@g10code.com>
+
+       * passphrase.c (gpg_format_keydesc): New.
+       * pubkey-enc.c (get_it): Use it.
+       * sign.c (do_sign): Use it.
+
+2010-04-26  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (keygen_set_std_prefs): Explicitly include Z0 in the
+       default preferences if no compression algorithms are available.
+       Remove a possible trailing space in the dummy_string.
+
+2010-04-23  Werner Koch  <wk@g10code.com>
+
+       * pubkey-enc.c (get_it): Use the agent for decryption.
+       * call-agent.c (agent_pkdecrypt, inq_ciphertext_cb): New.
+
+2010-04-22  Werner Koch  <wk@g10code.com>
+
+       * photoid.c (show_photos): Remove arg SK.
+
+       * pubkey-enc.c (get_session_key, get_it): Change to use the public
+       key object.
+       (get_it):  Remove card related stuff.  Now automagically handled
+       by the agent.
+
+       * skclist.c (build_sk_list): Remove UNLOCK arg.
+
+       * keylist.c (print_fingerprint): Remove arg SK.
+       * mainproc.c (list_node): Disable listing of secret key packets.
+
+       * keyring.c (struct keyring_name, struct keyring_handle): Remove
+       field SECRET.
+       (keyring_register_filename, keyring_new, orename_tmp_file)
+       (do_copy): Remove arg SECRET.
+       * keydb.c (struct resource_item): Remove field SECRET.
+       (keydb_add_resource): Remove arg SECRET.
+       (keydb_new): Remove code fro secret keyrings.
+
+       * gpg.c (main): Ignore --secret-keyring.  Remove all secret
+       keyring related code.
+
+2010-04-21  Werner Koch  <wk@g10code.com>
+
+       * pkclist.c (default_recipient): Change to use public keys.
+
+       * keydb.c (keydb_new): Remove arg SECRET.  Change all callers.
+
+       * getkey.c (get_seckey): Change to take a public key.
+       (have_secret_key): Rename to have_any_secret_key and make use of
+       the agent.
+       (key_byname): Rmemove unused arg SK.
+       (get_seckey_byname2): Remove and move code to
+       (get_seckey_byname): .. here.  Remove INLOCK arg.
+       (get_seckey_bynames): Remove.
+       (get_seckey_next): Remove.
+       (get_seckey_end): Remove.  Use get_pubkey_end instead.
+       (get_seckey_byfprint, get_seckeyblock_byfprint): Change to use
+       public keys.
+       (seckey_available): Rename to ..
+       (have_secret_key_with_kid): .. this and change to employ the
+       agent.  Change all callers.
+       (sk_from_block): Remove.
+
+       * call-agent.c (agent_probe_secret_key): New.
+       (agent_havekey): Remove.
+       * gpgv.c (agent_probe_secret_key): New.
+
+       * keyedit.c (keyedit_menu)
+       (sign_uids, menu_adduid, menu_deluid, menu_delkey)
+       (menu_addrevoker, menu_expire, menu_backsign)
+       (menu_set_primary_uid, menu_set_preferences)
+       (menu_set_keyserver_url, menu_set_notation, menu_revsig)
+       (menu_revuid, menu_revkey, menu_revsubkey): Remove all code to
+       manage the secret keyring.
+
+2010-04-20  Werner Koch  <wk@g10code.com>
+
+       * keylist.c (list_keyblock_colon): Print the keygrip.
+
+       * sign.c (do_sign): Call the agent to create the signature.
+       (mpi_from_sexp): New.
+       * keyid.c (keygrip_from_pk, hexkeygrip_from_pk): New.
+       * call-agent.c (agent_pksign): New.
+
+       * pkglue.c (pk_sign): Remove.
+
+       * keygen.c (generate_keypair): Do not ask for a passphrase.
+
+2010-04-15  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (gen_dsa, gen_elg, gen_rsa): Remove args SEC_ROOT, DEK,
+       S2K and RET_SK.  Change to use the gpg-agent based key generation.
+       Factor common code out to ...
+       (common_gen): New.
+       (do_create): Remove args SEC_ROOT, DEK, S2K and RET_SK.
+       (do_generate_keypair, write_selfsigs, write_direct_sig)
+       (write_keybinding, make_backsig): Adjust for above changes.
+       (generate_subkeypair): Remove arg SEC_KEYBLOCK.
+       (genhelp_protect, genhelp_factors): Remove.
+       (get_parameter_dek, get_parameter_s2k): Remove.
+
+       * call-agent.c (start_agent): Add dummy arg CTRL.
+       (agent_havekey, keyinfo_status_cb, agent_get_keyinfo)
+       (agent_genkey): New.
+
+       * seckey-cert.c (check_secret_key): Remove
+       (is_secret_key_protected): Take a public key as arg.
+       (protect_secret_key): Remove.
+
+       * seskey.c (encode_md_value): Remove SK arg.
+
+2010-04-14  Werner Koch  <wk@g10code.com>
+
+       * cpr.c (myread) [W32CE]: Do not use raise.
+
+       * misc.c (check_compress_algo): Rewrite to handle the new HAVE_ZIP.
+       * compress.c (push_compress_filter2): Ditto.
+       (init_compress, do_compress, init_uncompress, do_uncompress)
+       (compress_filter) [!HAVE_ZIP]: Do not build.
+       * main.h (DEFAULT_COMPRESS_ALGO): Depend on HAVE_ZIP.
+       * keygen.c (keygen_set_std_prefs): Use check_compress_algo also
+       for ZIP and ZLIB.
+
+       * Makefile.am (install-exec-hook) [W32CE]: New.
+       (bin_PROGRAMS) [W32CE]: Do not build gpgv2.
+       (gpg2_LDADD): Add extra_syslibs.
+
+2010-04-06  Werner Koch  <wk@g10code.com>
+
+       * openfile.c (mkdir): Remove.
+       (try_make_homedir): Use gnupg_mkdir.
+
+2010-04-01  Werner Koch  <wk@g10code.com>
+
+       Use gpg_err_set_errno to set ERRNO.
+
+2010-03-26  Werner Koch  <wk@g10code.com>
+
+       * signal.c (pause_on_sigusr): Remove.  It was used in ancient gpg
+       version with shared memory IPC.  Last caller removed on 2006-04-18.
+
+2010-03-24  Werner Koch  <wk@g10code.com>
+
+       * openfile.c (CMP_FILENAME): Depend on HAVE_DOSISH_SYSTEM instead
+       of HAVE_DRIVE_LETTERS.
+
+2010-03-15  Werner Koch  <wk@g10code.com>
+
+       * card-util.c: Replace stdio by estream.
+       * keylist.c: Ditto.
 
 2010-03-12  Werner Koch  <wk@g10code.com>
 
        (keyedit_passwd): Return the correct error or emit a success
        status message.
 
-2010-02-25  Werner Koch  <wk@g10code.com>
+2010-03-11  Werner Koch  <wk@g10code.com>
 
-       * sign.c (hash_for): Force SHA1 only for v1 OpenPGP cards.  Fixes
-       bug#1194.
+       * misc.c (mpi_print): Change to take a estream_t arg.
 
-2010-02-17  Werner Koch  <wk@g10code.com>
+       * parse-packet.c (listfp): Change to an estream_t.  Change all
+       users to use estream functions.
 
-       * keygen.c (ask_user_id): Avoid infinite loop in case of invalid
-       data.  Fixes bug#1186.
+       * kbnode.c (dump_kbnode): Change to use log functions.
+       * pkclist.c (do_show_revocation_reason): Ditto
 
-2010-02-11  Marcus Brinkmann  <marcus@g10code.de>
+       * armor.c (parse_header_line): Replace print_string by
+       es_print_sanitized.
+       (fake_packet): Ditto.
+       * keyedit.c (print_and_check_one_sig_colon): Ditto.
+       (show_key_with_all_names_colon): Ditto.
+       (ask_revoke_sig): Ditto.
+       * keylist.c (list_keyblock_colon): Ditto.
+       * mainproc.c (print_userid, list_node): Ditto.
+       * trustdb.c (dump_key_array): Ditto.
+       * gpg.c (list_config): ditto.
 
-       From trunk 2009-09-23, 2009-11-02, 2009-11-25:
+       * gpg.c: Include "asshelp.h".
+       (main): Remove assuan_set_assuan_log_prefix.  Add
+       assuan_set_log_cb.
+       * server.c (gpg_server): Remove assuan_set_log_stream.
 
-       * call-agent.c: Include "scdaemon.h" before <assuan.h> because of
-       GPG_ERR_SOURCE_DEFAULT check.
-       (learn_status_cb, dummy_data_cb, get_serialno_cb, default_inq_cb)
-       (learn_status_cb, inq_writecert_parms, inq_writekey_parms)
-       (scd_genkey_cb, membuf_data_cb): Return gpg_error_t instead of
-       int.
-       * gpg.c: Include "scdaemon.h" before <assuan.h> because of
-       GPG_ERR_SOURCE_DEFAULT check.
-       (main): Update to new Assuan API.
-       * server.c: Include "scdaemon.h" before <assuan.h> because of
-       GPG_ERR_SOURCE_DEFAULT check.
-       (reset_notify, input_notify, output_notify): Update to
-       new assuan interface.
-       (option_handler, cmd_recipient, cmd_signer, cmd_encrypt)
-       (cmd_decrypt, cmd_verify, cmd_sign, cmd_import, cmd_export)
-       (cmd_delkeys, cmd_message, do_listkeys, cmd_listkeys)
-       (cmd_listsecretkeys, cmd_genkey, cmd_getinfo): Return gpg_error_t
-       instead of int.
-       (register_commands): Allocate assuan context before starting
-       server.  Use assuan_handler_t.  Add NULL arg to
-       assuan_register_command.
-       (gpg_server): Allocate assuan_context before starting server.
-       Use assuan_fd_t and assuan_fdopen on fds.
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (needed_libs): Remove libjnlib.a.
+
+       * main.h: Remove "estream.h".
+
+2010-03-08  Werner Koch  <wk@g10code.com>
+
+       * main.h: Include "estream.h"
+       * openfile.c (open_outfile): Replace dup/iobuf_fdopen by
+       iobuf_fdopen_nc.
+       * mainproc.c (proc_signature_packets_by_fd): Return error on
+       memory failure.
+       * plaintext.c (hash_datafile_by_fd): Ditto.
+       * verify.c (gpg_verify): Use iobuf_fdopen_nc.  Change OUT_FP to an
+       estream_t.
+       * server.c (cmd_verify): Do not dup the fds.
+
+       Use macros for iobuf_ioctl commands.
+
+2010-02-17  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (ask_user_id): Avoid infinite loop in case of invalid
+       data.  Fixes bug#1186.
 
 2010-02-02  Werner Koch  <wk@g10code.com>
 
-       * card-util.c (card_edit): Change prompt to "gpg/card".
        * keyedit.c (keyedit_menu): Change prompt to "gpg".
+       * card-util.c (card_edit): Change prompt to "gpg/card".
 
 2010-01-11  Werner Koch  <wk@g10code.com>
 
+       * sign.c (only_old_style, write_onepass_sig_packets, hash_for)
+       (write_signature_packets, print_status_sig_created)
+       (clearsign_file, make_keysig_packet, mk_notation_policy_etc)
+       (complete_sig, do_sign, update_keysig_packet): Replace all
+       secret key access by the matching public key.
+       * keylist.c (print_seckey_info): Ditto.
+       * revoke.c (gen_desig_revoke): Ditto.
+       * skclist.c (release_sk_list): Ditto.
+       * keyedit.c (sign_uids): Ditto.
+       * misc.c (get_signature_count): Ditto.
+       * main.h (struct expand_args): s/sk/pksk/.  Change all users.
+
+       * keyedit.c (keyedit_passwd): Finish implementation.
+
+2010-01-10  Werner Koch  <wk@g10code.com>
+
+       * skclist.c (GCRYCTL_FAKED_RANDOM_P): Remove because we require
+       libgcrypt 1.4.
+       (is_insecure, key_present_in_sk_list): Work with public keys.
+       (build_sk_list): Change to work on public keys.
+       * keydb.h (struct sk_list): Replace field SK by a PK field.
+
+       * keylist.c (list_keyblock_print): Always look for the public key
+       and ignore all secret key packets.
+       (list_keyblock_colon): Ditto.
+       (print_capabilities): Remove arg SK and all secret key stuff.
+       Adjust all callers.
+       (dump_attribs): Ditto.
+
+       * getkey.c (getkey_bynames, getkey_next, get_pubkey_end): New.
+       (getkey_byname): New.
+       (getkey_ctx_s): Add WANT_SECRET.
+       (key_byname): Set it.
+       (merge_keys_and_selfsig): Remove all the secret key merging.
+       (lookup): Simplify by removing secret key code.
+
+       * keylist.c (list_all): Scan public keys and use have_secret_key
+       to filter secret keys.
+       (list_one): Use the new get_key functions.
+
+       * gpg.h (kbnode_t): Add as alias for KBNODE.
+       * keydb.h (getkey_ctx_t): Add as alias for GETKEY_CTX.
+
+2010-01-09  Werner Koch  <wk@g10code.com>
+
+       * getkey.c, keylist.c: Re-indent.
+
+2010-01-08  Werner Koch  <wk@g10code.com>
+
+       * cpr.c (write_status_error): Rename to write_status_errcode.
+       Change all callers.
+       (write_status_error): New.
+
        * gpg.c: Add option --passwd.
        (aPasswd): New.
        (main): Implement.
 
 2009-12-21  Werner Koch  <wk@g10code.com>
 
-       * gpg.c (main): Add dummy options --skip-hidden-recipients and no
-       variant.
-
        * call-agent.c (agent_get_s2k_count): New.
        * gpg.c (main):  Set s2k_count to 0.
        * (encode_s2k_iterations): Move ...
        * sig-check.c (do_check_messages): Evaluate the HAS_EXPIRED flag.
        Fixes bug#1059.
 
+       * gpg.c: Add new option --faked-system-time.
+
 2009-12-15  Werner Koch  <wk@g10code.com>
 
+       * keydb.c (keydb_add_resource): s/readonly/read_only/g.
+       * keyring.c (keyring_register_filename): Ditto.
+
        * tdbio.c (tdbio_set_dbname): Do not call log_fatal after creating
        the directory.  Fixes bug#1169.  Reported by Daniel Leidert.
 
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * keyring.h: Include userids.h.
+       * gpg.h (KEYDB_SEARCH_DESC): Remove.
+       * packet.h: Include userids.h.
+       (PKT_user_id): Declare using gpg_pkt_user_id_s.
+       * keydb.h (KeydbSearchMode, struct keydb_search_desc): Remove.  We
+       now use those in ../kbx.
+       * getkey.c (classify_user_id): Remove.  It is now in common/.
+       (key_byname): Adjust for changed classify_user_id.
+       * delkey.c (do_delete_key): Ditto.
+       * trustdb.c (register_trusted_key): Ditto.
+       * revoke.c (gen_desig_revoke, gen_revoke): Ditto.
+       * keyserver.c (parse_keyrec, keyserver_export, keyserver_import)
+       (keyidlist): Ditto.
+       * export.c (do_export_stream): Ditto.
+
+       * pkclist.c (find_and_check_key): Replace GPG_ERR_INV_NAME by
+       GPG_ERR_INV_USER_ID.
+
 2009-12-04  Werner Koch  <wk@g10code.com>
 
        * keygen.c (DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE): New.
 
 2009-12-03  Werner Koch  <wk@g10code.com>
 
-       * gpg.c (set_debug): Allow for numerical debug levels.  Print
+       * gpg.c (set_debug): Allow for numerical debug leveles.  Print
        active debug flags.
 
+2009-11-27  Werner Koch  <wk@g10code.com>
+
+       * keyedit.c (cmds, keyedit_menu): New command "checkbkupkey".
+
+2009-11-25  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (gpg_server): Use assuan_fd_t and assuan_fdopen on fds.
+
+2009-11-23  Werner Koch  <wk@g10code.com>
+
        * gpg.c (gpgconf_list): Add key "default_pubkey_algo".
 
+2009-11-18  Werner Koch  <wk@g10code.com>
+
+       * gpg.c: Add option --skip-hidden-recipients and no- variant.
+       * options.h (struct opt): Add field SKIP_HIDDEN_RECIPIENTS.
+       * pubkey-enc.c (get_session_key): Implement that option.
+
+2009-11-04  Werner Koch  <wk@g10code.com>
+
+       * server.c (register_commands): Add NULL arg to
+       assuan_register_command.
+
+2009-11-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (reset_notify, input_notify, output_notify): Update to
+       new assuan interface.
+       (register_commands): Use assuan_handler_t.
+
+2009-10-19  Werner Koch  <wk@g10code.com>
+
+       * options.h (glo_ctrl): Add field LASTERR.
+       * mainproc.c (proc_encrypted): Set LASTERR.
+       * server.c (cmd_decrypt): Check LASTERR.
+
+2009-10-02  Werner Koch  <wk@g10code.com>
+
+       * server.c (cmd_encrypt, cmd_decrypt): Implement.
+       * decrypt.c (decrypt_message_fd): New.
+       * options.h (struct opt): Add field OUTFP.
+       * plaintext.c (handle_plaintext): Support opt.outfp.
+
+       * encr-data.c: Rename to decrypt-data.c to reflect the action and
+       not the processed packet type.
+
+2009-10-02  Werner Koch  <wk@g10code.com>
+
+       * encr-data.c (decode_filter_context_s): Add fields PARTIAL and
+       LENGTH.
+       (decrypt_data): Set them.  Simplify premature EOF detection.
+       (mdc_decode_filter): Take fixed length packets in account.
+       (decode_filter): Ditto.  Better EOF detection.
+       * parse-packet.c (parse_encrypted): Store ed->LEN without the MDC
+       version byte.
+
+2009-09-30  Werner Koch  <wk@g10code.com>
+
+       * parse-packet.c (skip_packet, parse_gpg_control) <list_mode>: Take
+       care of premature EOFs.
+
+       * gpg.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING.
+
+2009-09-29  Werner Koch  <wk@g10code.com>
+
+       * openfile.c (open_outfile): Re-indent.  Use xstrconcat.
+       (NAME_OF_DEV_NULL): New.
+       (open_outfile): Use it.
+       (overwrite_filep): Use it.  Also use case insensitive compare
+       when needed.  Re-indent.
+       (open_outfile): Add arg INP_FD.  Change all callers.
+
+       * encrypt.c (encrypt_crypt): Add new args FILEFD, OUTPUTFD and
+       PROVIDED_KEYS.  Change all callers.
+
 2009-09-28  Werner Koch  <wk@g10code.com>
 
+       * server.c (skip_options, has_option): New.
+       (cmd_recipient): Implement.
+
+       * keydb.h (pk_list_t): New.
+
+       * pkclist.c (send_status_inv_recp): New.  Replace direct calls.
+       (build_pk_list): Factor some code out to ...
+       (find_and_check_key): ... new.
+
+       * encode.c: Rename to encrypt.c.  Re-indent all.
+       * encrypt.c (encode_symmetric, encode_store, encode_seskey)
+       (encode_simple, encode_crypt, encode_filter)
+       (encode_crypt_files): Rename all to encrypt_*.  Change all callers.
+
        * trustdb.c (get_validity_info): Take care of a NULL PK.  Fixes
        bug#1138.
        (get_validity_string): Ditto.
        (pk_check_secret_key): Allow deprecated RSA identifiers 2 and 3.
        Fixes bug#1139.
 
+2009-09-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * call-agent.c: Include "scdaemon.h" before <assuan.h> because of
+       GPG_ERR_SOURCE_DEFAULT check.
+       (learn_status_cb, dummy_data_cb, get_serialno_cb, default_inq_cb)
+       (learn_status_cb, inq_writecert_parms, inq_writekey_parms)
+       (scd_genkey_cb, membuf_data_cb): Return gpg_error_t instead of
+       int.
+       * gpg.c: Include "scdaemon.h" before <assuan.h> because of
+       GPG_ERR_SOURCE_DEFAULT check.
+       (main): Update to new Assuan API.
+       * server.c: Include "scdaemon.h" before <assuan.h> because of
+       GPG_ERR_SOURCE_DEFAULT check.
+       (option_handler, cmd_recipient, cmd_signer, cmd_encrypt)
+       (cmd_decrypt, cmd_verify, cmd_sign, cmd_import, cmd_export)
+       (cmd_delkeys, cmd_message, do_listkeys, cmd_listkeys)
+       (cmd_listsecretkeys, cmd_genkey, cmd_getinfo): Return gpg_error_t
+       instead of int.
+       (register_commands): Allocate assuan context before starting
+       server.
+       (gpg_server): Allocate assuan_context before starting server.
+
 2009-09-04  Werner Koch  <wk@g10code.com>
 
        * keyedit.c (menu_select_uid): Use IDX ==-1 t select all.
        (keyring_is_writable): Implement readonly feature.
        (keyring_update_keyblock): Return GPG_ERR_EACCES for readonly
        keyrings.
-       (keyring_insert_keyblock, keyring_delete_keyblock):
+       (keyring_insert_keyblock, keyring_delete_keyblock): Ditto.
 
 2009-04-01  Werner Koch  <wk@g10code.com>
 
        * status.c (get_status_string): Ditto.
        * mainproc.c (proc_plaintext): Emit it if multiple messages are
        detected. Error out if more than one plaintext packet is
-        encountered.
+       encountered.
        * mainproc.c (literals_seen): New.
 
 2007-02-26  Werner Koch  <wk@g10code.com>
@@ -11030,7 +12051,7 @@ Thu Feb 12 22:24:42 1998  Werner Koch  (wk@frodo)
 
 
  Copyright 1998,1999,2000,2001,2002,2003,2004,2005,
-          2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+          2006,2007,2008,2009,2010,2011 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
@@ -11039,3 +12060,7 @@ Thu Feb 12 22:24:42 1998  Werner Koch  (wk@frodo)
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index efa427d..d0343fa 100644 (file)
@@ -1,5 +1,5 @@
 # Copyright (C) 1998, 1999, 2000, 2001, 2002,
-#               2003, 2006  Free Software Foundation, Inc.
+#               2003, 2006, 2010  Free Software Foundation, Inc.
 #
 # This file is part of GnuPG.
 #
 
 ## Process this file with automake to produce Makefile.in
 
-EXTRA_DIST = options.skel ChangeLog-2011 gpg-w32info.rc
+EXTRA_DIST = options.skel distsigkey.gpg ChangeLog-2011 gpg-w32info.rc
 
 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common \
               -I$(top_srcdir)/include -I$(top_srcdir)/intl
 
 include $(top_srcdir)/am/cmacros.am
 
-AM_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS)
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
 
-needed_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a
+needed_libs = ../kbx/libkeybox.a $(libcommon) ../gl/libgnu.a
 
-bin_PROGRAMS = gpg2 gpgv2
+bin_PROGRAMS = gpg2
+if !HAVE_W32CE_SYSTEM
+bin_PROGRAMS += gpgv2
+endif
 noinst_PROGRAMS = $(module_tests)
 TESTS = $(module_tests)
 
@@ -39,12 +42,26 @@ else
 bzip2_source =
 endif
 
+if ENABLE_CARD_SUPPORT
+card_source = card-util.c
+else
+card_source =
+endif
+
+if NO_TRUST_MODELS
+trust_source =
+else
+trust_source = trustdb.c trustdb.h tdbdump.c tdbio.c tdbio.h
+endif
+
+
 if HAVE_W32_SYSTEM
 resource_objs += gpg-w32info.o
 endif
 
 common_source =  \
              gpg.h             \
+             dek.h             \
              build-packet.c    \
              compress.c        \
              $(bzip2_source)   \
@@ -72,7 +89,8 @@ common_source =  \
              plaintext.c       \
              sig-check.c       \
              keylist.c         \
-             pkglue.c pkglue.h
+             pkglue.c pkglue.h \
+             ecdh.c
 
 gpg2_SOURCES  = gpg.c          \
              server.c          \
@@ -81,31 +99,28 @@ gpg2_SOURCES  = gpg.c               \
              skclist.c         \
              pubkey-enc.c      \
              passphrase.c      \
-             seckey-cert.c     \
-             encr-data.c       \
+             decrypt.c         \
+             decrypt-data.c    \
              cipher.c          \
-             encode.c          \
+             encrypt.c         \
              sign.c            \
              verify.c          \
              revoke.c          \
-             decrypt.c         \
              keyedit.c         \
              dearmor.c         \
              import.c          \
              export.c          \
-             trustdb.c         \
-             trustdb.h         \
-             tdbdump.c         \
-             tdbio.c           \
-             tdbio.h           \
+             migrate.c         \
              delkey.c          \
              keygen.c          \
              helptext.c        \
              keyserver.c       \
              keyserver-internal.h \
+             call-dirmngr.c call-dirmngr.h \
              photoid.c photoid.h \
              call-agent.c call-agent.h \
-             card-util.c \
+             trust.c $(trust_source) \
+             $(card_source) \
              exec.c exec.h
 
 gpgv2_SOURCES = gpgv.c           \
@@ -119,13 +134,20 @@ gpgv2_SOURCES = gpgv.c           \
 #             ks-db.h \
 #             $(common_source)
 
+# FIXME: Libkeybox.a links to libksba thus we need to add libksba
+# here, even that it is not used by gpg.  A proper solution would
+# either to split up libkeybox.a or to use a separate keybox daemon.
 LDADD =  $(needed_libs) ../common/libgpgrl.a \
-         $(ZLIBS) $(DNSLIBS) $(LIBREADLINE) \
+         $(ZLIBS) $(DNSLIBS) \
          $(LIBINTL) $(CAPLIBS) $(NETLIBS)
-gpg2_LDADD =  $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
-            $(LIBICONV) $(resource_objs)
-gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
-             $(LIBICONV) $(resource_objs)
+gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
+             $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+            $(LIBICONV) $(resource_objs) $(extra_sys_libs)
+gpg2_LDFLAGS = $(extra_bin_ldflags)
+gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \
+              $(KSBA_LIBS) $(GPG_ERROR_LIBS) \
+             $(LIBICONV) $(resource_objs) $(extra_sys_libs)
+gpgv2_LDFLAGS = $(extra_bin_ldflags)
 
 t_common_ldadd =
 module_tests = t-rmd160
@@ -139,6 +161,17 @@ install-data-local:
        $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
        $(INSTALL_DATA) $(srcdir)/options.skel \
                                $(DESTDIR)$(pkgdatadir)/gpg-conf.skel
+       $(INSTALL_DATA) $(srcdir)/distsigkey.gpg \
+                               $(DESTDIR)$(pkgdatadir)/distsigkey.gpg
 
 uninstall-local:
        -@rm $(DESTDIR)$(pkgdatadir)/gpg-conf.skel
+       -@rm $(DESTDIR)$(pkgdatadir)/distsigkey.gpg
+
+
+# There has never been a gpg for WindowsCE, thus we don't need a gpg2 here
+if HAVE_W32CE_SYSTEM
+install-exec-hook:
+       mv -f $(DESTDIR)$(bindir)/gpg2$(EXEEXT) \
+              $(DESTDIR)$(bindir)/gpg$(EXEEXT)
+endif
index de1726d..efdc92e 100644 (file)
@@ -1,4 +1,4 @@
-/* armor.c - Armor filter
+/* armor.c - Armor flter
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
  *               2007 Free Software Foundation, Inc.
  *
@@ -381,32 +381,6 @@ is_armor_header( byte *line, unsigned len )
 }
 
 
-/* Helper to parse a "KEY <keyid> FAILED <code>" line and return the
-   error code.  LINEPTR points right behind "KEY ".  */
-int
-parse_key_failed_line (const void *lineptr, unsigned int len)
-{
-  const byte *line = lineptr;
-  int code = 0;
-
-  for (; len && !spacep (line); len--, line++)
-    ;
-  for (; len && spacep (line); len--, line++)
-    ;
-  if (len > 7 && !memcmp (line, "FAILED ", 7))
-    {
-      line += 7;
-      len -= 7;
-      for (; len && digitp (line); len--, line++)
-        {
-          code *= 10;
-          code += atoi_1 (line);
-        }
-    }
-
-  return code;
-}
-
 
 /****************
  * Parse a header lines
@@ -441,9 +415,9 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
     if( !p || (RFC2440 && p[1]!=' ')
        || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
       {
-       log_error(_("invalid armor header: "));
-       print_string( stderr, line, len, 0 );
-       putc('\n', stderr);
+       log_error (_("invalid armor header: "));
+       es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
+       log_printf ("\n");
        return -1;
       }
 
@@ -453,8 +427,8 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
 
     if( opt.verbose ) {
        log_info(_("armor header: "));
-       print_string( stderr, line, len, 0 );
-       putc('\n', stderr);
+       es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
+       log_printf ("\n");
     }
 
     if( afx->in_cleartext )
@@ -479,8 +453,8 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
           signed data section is "Hash". */
 
        log_info(_("unknown armor header: "));
-       print_string( stderr, line, len, 0 );
-       putc('\n', stderr);
+       es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
+       log_printf ("\n");
       }
 
     return 1;
@@ -527,14 +501,6 @@ check_input( armor_filter_context_t *afx, IOBUF a )
     /* find the armor header */
     while(len) {
        i = is_armor_header( line, len );
-        if (i == -1 && afx->only_keyblocks
-            && !afx->key_failed_code
-            && len > 4 && !memcmp (line, "KEY ", 4))
-          {
-            /* This is probably input from a keyserver helper and we
-               have not yet seen an error line.  */
-            afx->key_failed_code = parse_key_failed_line (line+4, len-4);
-          }
        if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
            hdr_line = i;
            if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
@@ -675,8 +641,9 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
                    if( type != BEGIN_SIGNATURE )
                      {
                        log_info(_("unexpected armor: "));
-                       print_string( stderr, p, n, 0 );
-                       putc('\n', stderr);
+                       es_write_sanitized (log_get_stream (), p, n,
+                                            NULL, NULL);
+                       log_printf ("\n");
                      }
 
                    lastline = 1;
@@ -686,9 +653,9 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
            else if(!afx->not_dash_escaped)
              {
                /* Bad dash-escaping. */
-               log_info(_("invalid dash escaped line: "));
-               print_string( stderr, p, n, 0 );
-               putc('\n', stderr);
+               log_info (_("invalid dash escaped line: "));
+               es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
+               log_printf ("\n");
              }
          }
 
@@ -1112,7 +1079,7 @@ armor_filter( void *opaque, int control,
            iobuf_writestr(a,afx->eol);
            if (opt.emit_version)
              {
-               iobuf_writestr (a, "Version: GnuPG v");
+               iobuf_writestr (a, "Version: "GNUPG_NAME" v");
                 for (s=VERSION; *s && *s != '.'; s++)
                   iobuf_writebyte (a, *s);
                 if (opt.emit_version > 1 && *s)
@@ -1229,21 +1196,20 @@ armor_filter( void *opaque, int control,
            crc = afx->crc;
            idx = afx->idx;
            idx2 = afx->idx2;
-           for(i=0; i < idx; i++ )
-               radbuf[i] = afx->radbuf[i];
            if( idx ) {
-               c = bintoasc[(*radbuf>>2)&077];
+               c = bintoasc[(afx->radbuf[0]>>2)&077];
                iobuf_put(a, c);
                if( idx == 1 ) {
-                   c = bintoasc[((*radbuf << 4) & 060) & 077];
+                   c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077];
                    iobuf_put(a, c);
                    iobuf_put(a, '=');
                    iobuf_put(a, '=');
                }
                else { /* 2 */
-                   c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
+                   c = bintoasc[(((afx->radbuf[0]<<4)&060)
+                                  |((afx->radbuf[1]>>4)&017))&077];
                    iobuf_put(a, c);
-                   c = bintoasc[((radbuf[1] << 2) & 074) & 077];
+                   c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077];
                    iobuf_put(a, c);
                    iobuf_put(a, '=');
                }
index d7f2291..6bd1c9b 100644 (file)
@@ -1,6 +1,6 @@
 /* build-packet.c - assemble packets and write them
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006 Free Software Foundation, Inc.
+ *               2006, 2010, 2011  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <ctype.h>
 
 #include "gpg.h"
+#include "util.h"
 #include "packet.h"
 #include "status.h"
 #include "iobuf.h"
-#include "util.h"
-#include "cipher.h"
 #include "i18n.h"
 #include "options.h"
-#include "../include/host2net.h"
 
 static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
-static int do_public_key( IOBUF out, int ctb, PKT_public_key *pk );
-static int do_secret_key( IOBUF out, int ctb, PKT_secret_key *pk );
+static int do_key (iobuf_t out, int ctb, PKT_public_key *pk);
 static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
 static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
 static u32 calc_plaintext( PKT_plaintext *pt );
@@ -55,7 +52,6 @@ static int write_header( IOBUF out, int ctb, u32 len );
 static int write_sign_packet_header( IOBUF out, int ctb, u32 len );
 static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen );
 static int write_new_header( IOBUF out, int ctb, u32 len, int hdrlen );
-static int write_version( IOBUF out, int ctb );
 
 /****************
  * Build a packet and write it to INP
@@ -73,8 +69,16 @@ build_packet( IOBUF out, PACKET *pkt )
        log_debug("build_packet() type=%d\n", pkt->pkttype );
     assert( pkt->pkt.generic );
 
-    switch( (pkttype = pkt->pkttype) )
+    switch ((pkttype = pkt->pkttype))
       {
+      case PKT_PUBLIC_KEY:
+        if (pkt->pkt.public_key->seckey_info)
+          pkttype = PKT_SECRET_KEY;
+        break;
+      case PKT_PUBLIC_SUBKEY:
+        if (pkt->pkt.public_key->seckey_info)
+          pkttype = PKT_SECRET_SUBKEY;
+        break;
       case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
       case PKT_ENCRYPTED:
       case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
@@ -108,11 +112,9 @@ build_packet( IOBUF out, PACKET *pkt )
        break;
       case PKT_PUBLIC_SUBKEY:
       case PKT_PUBLIC_KEY:
-       rc = do_public_key( out, ctb, pkt->pkt.public_key );
-       break;
       case PKT_SECRET_SUBKEY:
       case PKT_SECRET_KEY:
-       rc = do_secret_key( out, ctb, pkt->pkt.secret_key );
+       rc = do_key (out, ctb, pkt->pkt.public_key);
        break;
       case PKT_SYMKEY_ENC:
        rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
@@ -153,32 +155,69 @@ build_packet( IOBUF out, PACKET *pkt )
 /*
  * Write the mpi A to OUT.
  */
-static int
-mpi_write (iobuf_t out, gcry_mpi_t a)
+gpg_error_t
+gpg_mpi_write (iobuf_t out, gcry_mpi_t a)
 {
-  char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
-  size_t nbytes;
   int rc;
 
-  nbytes = DIM(buffer);
-  rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
-  if( !rc )
-    rc = iobuf_write( out, buffer, nbytes );
-  else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
+  if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
     {
-      log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
-      /* The buffer was too small. We better tell the user about the MPI. */
-      rc = gpg_error (GPG_ERR_TOO_LARGE);
+      unsigned int nbits;
+      const void *p;
+      unsigned int lenhdr[2];
+
+      p = gcry_mpi_get_opaque (a, &nbits);
+      lenhdr[0] = nbits >> 8;
+      lenhdr[1] = nbits;
+      rc = iobuf_write (out, lenhdr, 2);
+      if (!rc)
+        rc = iobuf_write (out, p, (nbits+7)/8);
+    }
+  else
+    {
+      char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
+      size_t nbytes;
+
+      nbytes = DIM(buffer);
+      rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
+      if( !rc )
+        rc = iobuf_write( out, buffer, nbytes );
+      else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
+        {
+          log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
+          /* The buffer was too small. We better tell the user about the MPI. */
+          rc = gpg_error (GPG_ERR_TOO_LARGE);
+        }
     }
 
   return rc;
 }
 
 
-
-/****************
- * calculate the length of a packet described by PKT
+/*
+ * Write an opaque MPI to the output stream without length info.
  */
+gpg_error_t
+gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a)
+{
+  int rc;
+
+  if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    {
+      unsigned int nbits;
+      const void *p;
+
+      p = gcry_mpi_get_opaque (a, &nbits);
+      rc = iobuf_write (out, p, (nbits+7)/8);
+    }
+  else
+    rc = gpg_error (GPG_ERR_BAD_MPI);
+
+  return rc;
+}
+
+
+/* Calculate the length of a packet described by PKT.  */
 u32
 calc_packet_length( PACKET *pkt )
 {
@@ -212,237 +251,169 @@ calc_packet_length( PACKET *pkt )
     return n;
 }
 
-static void
+
+static gpg_error_t
 write_fake_data (IOBUF out, gcry_mpi_t a)
 {
-  if (a)
-    {
-      unsigned int n;
-      void *p;
+  unsigned int n;
+  void *p;
 
-      p = gcry_mpi_get_opaque ( a, &n );
-      if (p)
-        iobuf_write (out, p, (n+7)/8 );
-    }
+  if (!a)
+    return 0;
+  p = gcry_mpi_get_opaque ( a, &n);
+  return iobuf_write (out, p, (n+7)/8 );
 }
 
-static int
-do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
-{
-    int rc;
-
-    if( uid->attrib_data )
-      {
-        /* We need to take special care of a user ID with a length of 0:
-         * Without forcing HDRLEN to 2 in this case an indeterminate length
-         * packet would be written which is not allowed.  Note that we are
-         * always called with a CTB indicating an old packet header format,
-         * so that forcing a 2 octet header works.  */
-       write_header2 (out, ctb, uid->attrib_len, (uid->attrib_len? 0 : 2));
-       rc = iobuf_write( out, uid->attrib_data, uid->attrib_len );
-      }
-    else
-      {
-        write_header2 (out, ctb, uid->len, 2);
-       rc = iobuf_write( out, uid->name, uid->len );
-      }
-    return rc;
-}
 
 static int
-do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
+do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
 {
-  int rc = 0;
-  int n, i;
-  IOBUF a = iobuf_temp();
+  int rc;
 
-  if ( !pk->version )
-    iobuf_put( a, 3 );
-  else
-    iobuf_put( a, pk->version );
-  write_32(a, pk->timestamp );
-  if ( pk->version < 4 )
+  if (uid->attrib_data)
     {
-      u16 ndays;
-      if ( pk->expiredate )
-        ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
-      else
-        ndays = 0;
-      write_16(a, ndays );
+      write_header(out, ctb, uid->attrib_len);
+      rc = iobuf_write( out, uid->attrib_data, uid->attrib_len );
     }
-  iobuf_put (a, pk->pubkey_algo );
-  n = pubkey_get_npkey ( pk->pubkey_algo );
-  if ( !n )
-    write_fake_data( a, pk->pkey[0] );
-  for (i=0; i < n && !rc ; i++ )
-    rc = mpi_write(a, pk->pkey[i] );
-
-  if (!rc)
+  else
     {
-      write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
-      rc = iobuf_write_temp ( out, a );
+      write_header2( out, ctb, uid->len, 2 );
+      rc = iobuf_write( out, uid->name, uid->len );
     }
-
-  iobuf_close(a);
   return rc;
 }
 
 
 static int
-do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
+do_key (iobuf_t out, int ctb, PKT_public_key *pk)
 {
-  int rc = 0;
+  gpg_error_t err = 0;
   int i, nskey, npkey;
-  IOBUF a = iobuf_temp(); /* Build in a self-enlarging buffer.  */
+  iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer.  */
 
-  /* Write the version number - if none is specified, use 3 */
-  if ( !sk->version )
-    iobuf_put ( a, 3 );
+  /* Write the version number - if none is specified, use 4 */
+  if ( !pk->version )
+    iobuf_put ( a, 4 );
   else
-    iobuf_put ( a, sk->version );
-  write_32 (a, sk->timestamp );
+    iobuf_put ( a, pk->version );
+  write_32 (a, pk->timestamp );
 
-  /* v3 needs the expiration time. */
-  if ( sk->version < 4 )
-    {
-      u16 ndays;
-      if ( sk->expiredate )
-        ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L);
-      else
-        ndays = 0;
-      write_16(a, ndays);
-    }
-
-  iobuf_put (a, sk->pubkey_algo );
+  iobuf_put (a, pk->pubkey_algo );
 
   /* Get number of secret and public parameters.  They are held in one
      array first the public ones, then the secret ones.  */
-  nskey = pubkey_get_nskey ( sk->pubkey_algo );
-  npkey = pubkey_get_npkey ( sk->pubkey_algo );
+  nskey = pubkey_get_nskey (pk->pubkey_algo);
+  npkey = pubkey_get_npkey (pk->pubkey_algo);
 
   /* If we don't have any public parameters - which is the case if we
      don't know the algorithm used - the parameters are stored as one
      blob in a faked (opaque) MPI. */
-  if ( !npkey )
+  if (!npkey)
     {
-      write_fake_data( a, sk->skey[0] );
+      write_fake_data (a, pk->pkey[0]);
       goto leave;
     }
-  assert ( npkey < nskey );
+  assert (npkey < nskey);
 
-  /* Writing the public parameters is easy. */
   for (i=0; i < npkey; i++ )
-    if ((rc = mpi_write (a, sk->skey[i])))
-      goto leave;
-
-  /* Build the header for protected (encrypted) secret parameters.  */
-  if ( sk->is_protected )
     {
-      if ( is_RSA(sk->pubkey_algo)
-           && sk->version < 4
-           && !sk->protect.s2k.mode )
-        {
-          /* The simple rfc1991 (v3) way. */
-          iobuf_put (a, sk->protect.algo );
-          iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
-       }
+      if (   (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0))
+          || (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0))
+          || (pk->pubkey_algo == PUBKEY_ALGO_ECDH  && (i == 0 || i == 2)))
+        err = gpg_mpi_write_nohdr (a, pk->pkey[i]);
       else
+        err = gpg_mpi_write (a, pk->pkey[i]);
+      if (err)
+        goto leave;
+    }
+
+
+  if (pk->seckey_info)
+    {
+      /* This is a secret key packet.  */
+      struct seckey_info *ski = pk->seckey_info;
+
+      /* Build the header for protected (encrypted) secret parameters.  */
+      if (ski->is_protected)
         {
           /* OpenPGP protection according to rfc2440. */
-          iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff );
-          iobuf_put(a, sk->protect.algo );
-          if ( sk->protect.s2k.mode >= 1000 )
+          iobuf_put (a, ski->sha1chk? 0xfe : 0xff);
+          iobuf_put (a, ski->algo);
+          if (ski->s2k.mode >= 1000)
             {
               /* These modes are not possible in OpenPGP, we use them
-                 to implement our extensions, 101 can be seen as a
+                 to implement our extensions, 101 can be viewed as a
                  private/experimental extension (this is not specified
                  in rfc2440 but the same scheme is used for all other
-                 algorithm identifiers) */
-              iobuf_put(a, 101 );
-              iobuf_put(a, sk->protect.s2k.hash_algo );
-              iobuf_write(a, "GNU", 3 );
-              iobuf_put(a, sk->protect.s2k.mode - 1000 );
-           }
+                 algorithm identifiers). */
+              iobuf_put (a, 101);
+              iobuf_put (a, ski->s2k.hash_algo);
+              iobuf_write (a, "GNU", 3 );
+              iobuf_put (a, ski->s2k.mode - 1000);
+            }
           else
             {
-              iobuf_put(a, sk->protect.s2k.mode );
-              iobuf_put(a, sk->protect.s2k.hash_algo );
-           }
-          if ( sk->protect.s2k.mode == 1
-               || sk->protect.s2k.mode == 3 )
-            iobuf_write (a, sk->protect.s2k.salt, 8 );
+              iobuf_put (a, ski->s2k.mode);
+              iobuf_put (a, ski->s2k.hash_algo);
+            }
+
+          if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
+            iobuf_write (a, ski->s2k.salt, 8);
 
-          if ( sk->protect.s2k.mode == 3 )
-            iobuf_put (a, sk->protect.s2k.count );
+          if (ski->s2k.mode == 3)
+            iobuf_put (a, ski->s2k.count);
 
           /* For our special modes 1001, 1002 we do not need an IV. */
-          if ( sk->protect.s2k.mode != 1001
-               && sk->protect.s2k.mode != 1002 )
-            iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
-       }
-    }
-  else
-    iobuf_put (a, 0 );
+          if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
+            iobuf_write (a, ski->iv, ski->ivlen);
 
-  if ( sk->protect.s2k.mode == 1001 )
-    ; /* GnuPG extension - don't write a secret key at all. */
-  else if ( sk->protect.s2k.mode == 1002 )
-    {
-      /* GnuPG extension - divert to OpenPGP smartcard. */
-      iobuf_put(a, sk->protect.ivlen ); /* Length of the serial number
-                                           or 0 for no serial
-                                           number. */
-      /* The serial number gets stored in the IV field. */
-      iobuf_write(a, sk->protect.iv, sk->protect.ivlen);
-    }
-  else if ( sk->is_protected && sk->version >= 4 )
-    {
-      /* The secret key is protected - write it out as it is.  */
-      byte *p;
-      unsigned int ndatabits;
-
-      assert (gcry_mpi_get_flag (sk->skey[npkey], GCRYMPI_FLAG_OPAQUE));
-      p = gcry_mpi_get_opaque (sk->skey[npkey], &ndatabits );
-      if (p)
-        iobuf_write (a, p, (ndatabits+7)/8 );
-    }
-  else if ( sk->is_protected )
-    {
-      /* The secret key is protected the old v4 way. */
-      for ( ; i < nskey; i++ )
+        }
+      else /* Not protected. */
+        iobuf_put (a, 0 );
+
+      if (ski->s2k.mode == 1001)
+        ; /* GnuPG extension - don't write a secret key at all. */
+      else if (ski->s2k.mode == 1002)
+        {
+          /* GnuPG extension - divert to OpenPGP smartcard. */
+          /* Length of the serial number or 0 for no serial number. */
+          iobuf_put (a, ski->ivlen );
+          /* The serial number gets stored in the IV field.  */
+          iobuf_write (a, ski->iv, ski->ivlen);
+        }
+      else if (ski->is_protected)
         {
+          /* The secret key is protected - write it out as it is.  */
           byte *p;
           unsigned int ndatabits;
 
-          assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
-          p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
-          if (p)
-            iobuf_write (a, p, (ndatabits+7)/8);
+          assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE));
+          p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits);
+          iobuf_write (a, p, (ndatabits+7)/8 );
+        }
+      else
+        {
+          /* Non-protected key. */
+          for ( ; i < nskey; i++ )
+            if ( (err = gpg_mpi_write (a, pk->pkey[i])))
+              goto leave;
+          write_16 (a, ski->csum );
         }
-      write_16(a, sk->csum );
-    }
-  else
-    {
-      /* Non-protected key. */
-      for ( ; i < nskey; i++ )
-        if ( (rc = mpi_write (a, sk->skey[i])))
-          goto leave;
-      write_16 (a, sk->csum );
     }
 
  leave:
-  if (!rc)
+  if (!err)
     {
       /* Build the header of the packet - which we must do after
          writing all the other stuff, so that we know the length of
          the packet */
-      write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes);
-      /* And finally write it out the real stream */
-      rc = iobuf_write_temp( out, a );
+      write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
+      /* And finally write it out to the real stream. */
+      err = iobuf_write_temp (out, a);
     }
 
-  iobuf_close(a); /* Close the remporary buffer */
-  return rc;
+  iobuf_close (a); /* Close the temporary buffer */
+  return err;
 }
 
 static int
@@ -483,7 +454,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
   int n, i;
   IOBUF a = iobuf_temp();
 
-  write_version( a, ctb );
+  iobuf_put (a, 3); /* Version.  */
+
   if ( enc->throw_keyid )
     {
       write_32(a, 0 );  /* Don't tell Eve who can decrypt the message.  */
@@ -498,13 +470,19 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
   n = pubkey_get_nenc( enc->pubkey_algo );
   if ( !n )
     write_fake_data( a, enc->data[0] );
+
   for (i=0; i < n && !rc ; i++ )
-    rc = mpi_write(a, enc->data[i] );
+    {
+      if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
+        rc = gpg_mpi_write_nohdr (a, enc->data[i]);
+      else
+        rc = gpg_mpi_write (a, enc->data[i]);
+    }
 
   if (!rc)
     {
-      write_header(out, ctb, iobuf_get_temp_length(a) );
-      rc = iobuf_write_temp( out, a );
+      write_header (out, ctb, iobuf_get_temp_length(a) );
+      rc = iobuf_write_temp (out, a);
     }
   iobuf_close(a);
   return rc;
@@ -640,7 +618,10 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype )
        if( n == 255 ) {
            if( buflen < 4 )
                break;
-           n = buf32_to_size_t (buffer);
+           n = (((size_t)buffer[0] << 24)
+                 | (buffer[1] << 16)
+                 | (buffer[2] << 8)
+                 | buffer[3]);
            buffer += 4;
            buflen -= 4;
        }
@@ -763,7 +744,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
        /* This should never happen since we don't currently allow
           creating such a subpacket, but just in case... */
       case SIGSUBPKT_SIG_EXPIRE:
-       if (buf32_to_u32 (buffer) + sig->timestamp <= make_timestamp())
+       if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp())
          sig->flags.expired=1;
        else
          sig->flags.expired=0;
@@ -1156,7 +1137,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
   if ( !n )
     write_fake_data( a, sig->data[0] );
   for (i=0; i < n && !rc ; i++ )
-    rc = mpi_write(a, sig->data[i] );
+    rc = gpg_mpi_write (a, sig->data[i] );
 
   if (!rc)
     {
@@ -1178,7 +1159,7 @@ do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
     int rc = 0;
     IOBUF a = iobuf_temp();
 
-    write_version( a, ctb );
+    iobuf_put (a, 3);  /* Version.  */
     iobuf_put(a, ops->sig_class );
     iobuf_put(a, ops->digest_algo );
     iobuf_put(a, ops->pubkey_algo );
@@ -1358,13 +1339,3 @@ write_new_header( IOBUF out, int ctb, u32 len, int hdrlen )
     }
     return 0;
 }
-
-static int
-write_version (IOBUF out, int ctb)
-{
-  (void)ctb;
-
-  if (iobuf_put (out, 3))
-    return -1;
-  return 0;
-}
index 5669e04..bacb9d5 100644 (file)
@@ -1,7 +1,7 @@
 /* call-agent.c - Divert GPG operations to the agent.
- * Copyright (C) 2001, 2002, 2003, 2006, 2007,
- *               2008, 2009 Free Software Foundation, Inc.
- * Copyright (C) 2014  Werner Koch
+ * Copyright (C) 2001, 2002, 2003, 2006, 2007, 2008, 2009,
+ *               2010, 2011, 2013 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014  Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include "sysutils.h"
 #include "call-agent.h"
 #include "status.h"
+#include "../common/shareddefs.h"
 
 #ifndef DBG_ASSUAN
 # define DBG_ASSUAN 1
 #endif
 
+#define CONTROL_D ('D' - 'A' + 1)
+
+
 static assuan_context_t agent_ctx = NULL;
 static int did_early_card_test;
 
+struct default_inq_parm_s
+{
+  ctrl_t ctrl;
+  assuan_context_t ctx;
+  struct {
+    u32 *keyid;
+    u32 *mainkeyid;
+    int pubkey_algo;
+  } keyinfo;
+};
+
 struct cipher_parm_s
 {
+  struct default_inq_parm_s *dflt;
   assuan_context_t ctx;
-  const char *ciphertext;
+  unsigned char *ciphertext;
   size_t ciphertextlen;
 };
 
 struct writecert_parm_s
 {
-  assuan_context_t ctx;
+  struct default_inq_parm_s *dflt;
   const unsigned char *certdata;
   size_t certdatalen;
 };
 
 struct writekey_parm_s
 {
-  assuan_context_t ctx;
+  struct default_inq_parm_s *dflt;
   const unsigned char *keydata;
   size_t keydatalen;
 };
 
 struct genkey_parm_s
 {
-  assuan_context_t ctx;
-  const char *sexp;
-  size_t sexplen;
+  struct default_inq_parm_s *dflt;
+  const char *keyparms;
+};
+
+struct import_key_parm_s
+{
+  struct default_inq_parm_s *dflt;
+  const void *key;
+  size_t keylen;
+};
+
+
+struct cache_nonce_parm_s
+{
+  char **cache_nonce_addr;
+  char **passwd_nonce_addr;
 };
 
+
 struct scd_genkey_parm_s
 {
   struct agent_card_genkey_s *cgk;
@@ -97,6 +127,7 @@ status_sc_op_failure (int rc)
     case 0:
       break;
     case GPG_ERR_CANCELED:
+    case GPG_ERR_FULLY_CANCELED:
       write_status_text (STATUS_SC_OP_FAILURE, "1");
       break;
     case GPG_ERR_BAD_PIN:
@@ -120,25 +151,53 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
 }
 
 
+
 /* This is the default inquiry callback.  It mainly handles the
    Pinentry notifications.  */
 static gpg_error_t
 default_inq_cb (void *opaque, const char *line)
 {
-  (void)opaque;
+  gpg_error_t err = 0;
+  struct default_inq_parm_s *parm = opaque;
 
-  if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
+  if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
     {
-      /* There is no working server mode yet thus we use
-         AllowSetForegroundWindow window right here.  We might want to
-         do this anyway in case gpg is called on the console. */
-      gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
+      err = gpg_proxy_pinentry_notify (parm->ctrl, line);
+      if (err)
+        log_error (_("failed to proxy %s inquiry to client\n"),
+                   "PINENTRY_LAUNCHED");
       /* We do not pass errors to avoid breaking other code.  */
     }
+  else if ((has_leading_keyword (line, "PASSPHRASE")
+            || has_leading_keyword (line, "NEW_PASSPHRASE"))
+           && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
+    {
+      if (have_static_passphrase ())
+        {
+          const char *s = get_static_passphrase ();
+          err = assuan_send_data (parm->ctx, s, strlen (s));
+        }
+      else
+        {
+          char *pw;
+
+          if (parm->keyinfo.keyid)
+            emit_status_need_passphrase (parm->keyinfo.keyid,
+                                         parm->keyinfo.mainkeyid,
+                                         parm->keyinfo.pubkey_algo);
+          pw = cpr_get_hidden ("passphrase.enter", _("Enter passphrase: "));
+          cpr_kill_prompt ();
+          if (*pw == CONTROL_D && !pw[1])
+            err = gpg_error (GPG_ERR_CANCELED);
+          else
+            err = assuan_send_data (parm->ctx, pw, strlen (pw));
+          xfree (pw);
+        }
+    }
   else
-    log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
+    log_debug ("ignoring gpg-agent inquiry '%s'\n", line);
 
-  return 0;
+  return err;
 }
 
 
@@ -151,8 +210,8 @@ check_hijacking (assuan_context_t ctx)
 
   init_membuf (&mb, 64);
 
-  /* AGENT_ID is a command implemented by gnome-keyring-daemon.  IT
-     does not reatun any data but an OK line with a remark.  */
+  /* AGENT_ID is a command implemented by gnome-keyring-daemon.  It
+     does not return any data but an OK line with a remark.  */
   if (assuan_transact (ctx, "AGENT_ID",
                        membuf_data_cb, &mb, NULL, NULL, NULL, NULL))
     {
@@ -188,8 +247,12 @@ check_hijacking (assuan_context_t ctx)
           xfree (cmdargs);
           if (cmd)
             {
+              struct default_inq_parm_s dfltparm;
+
+              memset (&dfltparm, 0, sizeof dfltparm);
+              dfltparm.ctx = ctx;
               assuan_transact (ctx, cmd, NULL, NULL,
-                               default_inq_cb, NULL,
+                               default_inq_cb, &dfltparm,
                                NULL, NULL);
               xfree (cmd);
               shown = 1;
@@ -200,13 +263,16 @@ check_hijacking (assuan_context_t ctx)
 }
 
 
+
 /* Try to connect to the agent via socket or fork it off and work by
    pipes.  Handle the server's initial greeting */
 static int
-start_agent (int for_card)
+start_agent (ctrl_t ctrl, int for_card)
 {
   int rc;
 
+  (void)ctrl;  /* Not yet used.  */
+
   /* Fixme: We need a context for each thread or serialize the access
      to the agent. */
   if (agent_ctx)
@@ -228,6 +294,24 @@ start_agent (int for_card)
              agents.  */
           assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
                            NULL, NULL, NULL, NULL, NULL, NULL);
+          /* Tell the agent about what version we are aware.  This is
+             here used to indirectly enable GPG_ERR_FULLY_CANCELED.  */
+          assuan_transact (agent_ctx, "OPTION agent-awareness=2.1.0",
+                           NULL, NULL, NULL, NULL, NULL, NULL);
+          /* Pass on the pinentry mode.  */
+          if (opt.pinentry_mode)
+            {
+              char *tmp = xasprintf ("OPTION pinentry-mode=%s",
+                                     str_pinentry_mode (opt.pinentry_mode));
+              rc = assuan_transact (agent_ctx, tmp,
+                               NULL, NULL, NULL, NULL, NULL, NULL);
+              xfree (tmp);
+              if (rc)
+                log_error ("setting pinentry mode '%s' failed: %s\n",
+                           str_pinentry_mode (opt.pinentry_mode),
+                           gpg_strerror (rc));
+            }
+
           check_hijacking (agent_ctx);
         }
     }
@@ -369,6 +453,7 @@ get_serialno_cb (void *opaque, const char *line)
 }
 
 
+
 /* Release the card info structure INFO. */
 void
 agent_release_card_info (struct agent_card_info_s *info)
@@ -554,13 +639,16 @@ learn_status_cb (void *opaque, const char *line)
   return 0;
 }
 
-/* Call the agent to learn about a smartcard */
+/* Call the scdaemon to learn about a smartcard */
 int
-agent_learn (struct agent_card_info_s *info)
+agent_scd_learn (struct agent_card_info_s *info)
 {
   int rc;
+  struct default_inq_parm_s parm;
 
-  rc = start_agent (1);
+  memset (&parm, 0, sizeof parm);
+
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
@@ -576,10 +664,10 @@ agent_learn (struct agent_card_info_s *info)
   if (rc)
     return rc;
 
-
+  parm.ctx = agent_ctx;
   memset (info, 0, sizeof *info);
   rc = assuan_transact (agent_ctx, "SCD LEARN --force",
-                        dummy_data_cb, NULL, default_inq_cb, NULL,
+                        dummy_data_cb, NULL, default_inq_cb, &parm,
                         learn_status_cb, info);
   /* Also try to get the key attributes.  */
   if (!rc)
@@ -588,6 +676,57 @@ agent_learn (struct agent_card_info_s *info)
   return rc;
 }
 
+
+/* Call the agent to learn about the current smartcard.  This is
+   currently only used to have the agent create the shadow key.  */
+gpg_error_t
+agent_learn (void)
+{
+  gpg_error_t err;
+  struct default_inq_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+
+  err = start_agent (NULL, 1);
+  if (err)
+    return err;
+
+  parm.ctx = agent_ctx;
+  err = assuan_transact (agent_ctx, "LEARN",
+                         dummy_data_cb, NULL, default_inq_cb, &parm,
+                         NULL, NULL);
+
+  return err;
+}
+
+
+int
+agent_keytocard (const char *hexgrip, int keyno, int force,
+                 const char *serialno, const char *timestamp)
+{
+  int rc;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+  parm.ctx = agent_ctx;
+
+  snprintf (line, DIM(line)-1, "KEYTOCARD %s%s %s OPENPGP.%d %s",
+            force?"--force ": "", hexgrip, serialno, keyno, timestamp);
+  line[DIM(line)-1] = 0;
+
+  rc = start_agent (NULL, 1);
+  if (rc)
+    return rc;
+
+  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
+                        NULL, NULL);
+  if (rc)
+    return rc;
+
+  return rc;
+}
+\f
 /* Call the agent to retrieve a data object.  This function returns
    the data in the same structure as used by the learn command.  It is
    allowed to update such a structure using this commmand. */
@@ -596,6 +735,9 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
 
   if (!*name)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -605,11 +747,12 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
     return gpg_error (GPG_ERR_TOO_LARGE);
   stpcpy (stpcpy (line, "SCD GETATTR "), name);
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
-  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
+  parm.ctx = agent_ctx;
+  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
                         learn_status_cb, info);
 
   return rc;
@@ -627,6 +770,9 @@ agent_scd_setattr (const char *name,
   int rc;
   char line[ASSUAN_LINELENGTH];
   char *p;
+  struct default_inq_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
 
   (void)serialno;
 
@@ -655,11 +801,12 @@ agent_scd_setattr (const char *name,
     }
   *p = 0;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (!rc)
     {
+      parm.ctx = agent_ctx;
       rc = assuan_transact (agent_ctx, line, NULL, NULL,
-                            default_inq_cb, NULL, NULL, NULL);
+                            default_inq_cb, &parm, NULL, NULL);
     }
 
   status_sc_op_failure (rc);
@@ -677,12 +824,13 @@ inq_writecert_parms (void *opaque, const char *line)
   int rc;
   struct writecert_parm_s *parm = opaque;
 
-  if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
+  if (has_leading_keyword (line, "CERTDATA"))
     {
-      rc = assuan_send_data (parm->ctx, parm->certdata, parm->certdatalen);
+      rc = assuan_send_data (parm->dflt->ctx,
+                             parm->certdata, parm->certdatalen);
     }
   else
-    rc = default_inq_cb (opaque, line);
+    rc = default_inq_cb (parm->dflt, line);
 
   return rc;
 }
@@ -696,8 +844,11 @@ agent_scd_writecert (const char *certidstr,
   int rc;
   char line[ASSUAN_LINELENGTH];
   struct writecert_parm_s parms;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
@@ -705,7 +856,8 @@ agent_scd_writecert (const char *certidstr,
 
   snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr);
   line[DIM(line)-1] = 0;
-  parms.ctx = agent_ctx;
+  dfltparm.ctx = agent_ctx;
+  parms.dflt = &dfltparm;
   parms.certdata = certdata;
   parms.certdatalen = certdatalen;
 
@@ -725,12 +877,12 @@ inq_writekey_parms (void *opaque, const char *line)
   int rc;
   struct writekey_parm_s *parm = opaque;
 
-  if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
+  if (has_leading_keyword (line, "KEYDATA"))
     {
-      rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
+      rc = assuan_send_data (parm->dflt->ctx, parm->keydata, parm->keydatalen);
     }
   else
-    rc = default_inq_cb (opaque, line);
+    rc = default_inq_cb (parm->dflt, line);
 
   return rc;
 }
@@ -744,10 +896,13 @@ agent_scd_writekey (int keyno, const char *serialno,
   int rc;
   char line[ASSUAN_LINELENGTH];
   struct writekey_parm_s parms;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
   (void)serialno;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
@@ -755,7 +910,8 @@ agent_scd_writekey (int keyno, const char *serialno,
 
   snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
   line[DIM(line)-1] = 0;
-  parms.ctx = agent_ctx;
+  dfltparm.ctx = agent_ctx;
+  parms.dflt = &dfltparm;
   parms.keydata = keydata;
   parms.keydatalen = keydatalen;
 
@@ -797,7 +953,6 @@ scd_genkey_cb_append_savedbytes (struct scd_genkey_parm_s *parm,
   return err;
 }
 
-
 /* Status callback for the SCD GENKEY command. */
 static gpg_error_t
 scd_genkey_cb (void *opaque, const char *line)
@@ -870,10 +1025,9 @@ scd_genkey_cb (void *opaque, const char *line)
 }
 
 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
-   this implementation.  If CREATEDATE has been given, it will be
-   passed to SCDAEMON so that the key can be created with this
-   timestamp; note the user needs to use the returned timestamp as old
-   versions of scddaemon don't support this option.  */
+   this implementation.  If CREATEDATE is not 0, it will be passed to
+   SCDAEMON so that the key is created with this timestamp.  INFO will
+   receive information about the generated key.  */
 int
 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
                   const char *serialno, u32 createtime)
@@ -882,13 +1036,16 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
   char line[ASSUAN_LINELENGTH];
   gnupg_isotime_t tbuf;
   struct scd_genkey_parm_s parms;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
   (void)serialno;
 
   memset (&parms, 0, sizeof parms);
   parms.cgk = info;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
@@ -897,16 +1054,16 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
   else
     *tbuf = 0;
 
-  memset (info, 0, sizeof *info);
   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
             *tbuf? "--timestamp=":"", tbuf,
             force? "--force":"",
             keyno);
   line[DIM(line)-1] = 0;
 
+  dfltparm.ctx = agent_ctx;
   memset (info, 0, sizeof *info);
   rc = assuan_transact (agent_ctx, line,
-                        NULL, NULL, default_inq_cb, NULL,
+                        NULL, NULL, default_inq_cb, &dfltparm,
                         scd_genkey_cb, &parms);
 
   xfree (parms.savedbytes);
@@ -1010,155 +1167,6 @@ select_openpgp (const char *serialno)
 
 
 \f
-/* Helper returning a command option to describe the used hash
-   algorithm.  See scd/command.c:cmd_pksign.  */
-static const char *
-hash_algo_option (int algo)
-{
-  switch (algo)
-    {
-    case GCRY_MD_RMD160: return "--hash=rmd160";
-    case GCRY_MD_SHA1  : return "--hash=sha1";
-    case GCRY_MD_SHA224: return "--hash=sha224";
-    case GCRY_MD_SHA256: return "--hash=sha256";
-    case GCRY_MD_SHA384: return "--hash=sha384";
-    case GCRY_MD_SHA512: return "--hash=sha512";
-    case GCRY_MD_MD5   : return "--hash=md5";
-    default:             return "";
-    }
-}
-
-/* Send a sign command to the scdaemon via gpg-agent's pass thru
-   mechanism. */
-int
-agent_scd_pksign (const char *serialno, int hashalgo,
-                  const unsigned char *indata, size_t indatalen,
-                  unsigned char **r_buf, size_t *r_buflen)
-{
-  int rc, i;
-  char *p, line[ASSUAN_LINELENGTH];
-  membuf_t data;
-  size_t len;
-
-  /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
-
-  *r_buf = NULL;
-  *r_buflen = 0;
-
-  rc = start_agent (1);
-  if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
-      || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
-    rc = 0; /* We check later.  */
-  if (rc)
-    return rc;
-
-  if (indatalen*2 + 50 > DIM(line))
-    return gpg_error (GPG_ERR_GENERAL);
-
-  rc = select_openpgp (serialno);
-  if (rc)
-    return rc;
-
-  sprintf (line, "SCD SETDATA ");
-  p = line + strlen (line);
-  for (i=0; i < indatalen ; i++, p += 2 )
-    sprintf (p, "%02X", indata[i]);
-  rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
-  if (rc)
-    return rc;
-
-  init_membuf (&data, 1024);
-#if 0
-  if (!hashalgo) /* Temporary test hack. */
-    snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
-  else
-#endif
-    snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s",
-              hash_algo_option (hashalgo), serialno);
-  line[DIM(line)-1] = 0;
-  rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
-                        default_inq_cb, NULL, NULL, NULL);
-  if (rc)
-    {
-      xfree (get_membuf (&data, &len));
-    }
-  else
-    *r_buf = get_membuf (&data, r_buflen);
-
-  status_sc_op_failure (rc);
-  return rc;
-}
-
-
-/* Decrypt INDATA of length INDATALEN using the card identified by
-   SERIALNO.  Return the plaintext in a newly allocated buffer stored
-   at the address of R_BUF.
-
-   Note, we currently support only RSA or more exactly algorithms
-   taking one input data element. */
-int
-agent_scd_pkdecrypt (const char *serialno,
-                     const unsigned char *indata, size_t indatalen,
-                     unsigned char **r_buf, size_t *r_buflen)
-{
-  int rc, i;
-  char *p, line[ASSUAN_LINELENGTH];
-  membuf_t data;
-  size_t len;
-
-  *r_buf = NULL;
-  rc = start_agent (1);
-  if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
-      || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
-    rc = 0; /* We check later.  */
-  if (rc)
-    return rc;
-
-  /* FIXME: use secure memory where appropriate */
-
-  rc = select_openpgp (serialno);
-  if (rc)
-    return rc;
-
-  for (len = 0; len < indatalen;)
-    {
-      p = stpcpy (line, "SCD SETDATA ");
-      if (len)
-        p = stpcpy (p, "--append ");
-      for (i=0; len < indatalen && (i*2 < DIM(line)-50); i++, len++)
-        {
-          sprintf (p, "%02X", indata[len]);
-          p += 2;
-        }
-      rc = assuan_transact (agent_ctx, line,
-                            NULL, NULL, NULL, NULL, NULL, NULL);
-      if (rc)
-        return rc;
-    }
-
-  init_membuf (&data, 1024);
-  snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
-  line[DIM(line)-1] = 0;
-  rc = assuan_transact (agent_ctx, line,
-                        membuf_data_cb, &data,
-                        default_inq_cb, NULL, NULL, NULL);
-  if (rc)
-    {
-      xfree (get_membuf (&data, &len));
-    }
-  else
-    {
-      *r_buf = get_membuf (&data, r_buflen);
-      if (!*r_buf)
-        rc = gpg_error (GPG_ERR_ENOMEM);
-    }
-
-  status_sc_op_failure (rc);
-  return rc;
-}
-
-
-\f
 /* Send a READCERT command to the SCdaemon. */
 int
 agent_scd_readcert (const char *certidstr,
@@ -1168,19 +1176,25 @@ agent_scd_readcert (const char *certidstr,
   char line[ASSUAN_LINELENGTH];
   membuf_t data;
   size_t len;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
   *r_buf = NULL;
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
+  dfltparm.ctx = agent_ctx;
+
   init_membuf (&data, 2048);
 
   snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
   line[DIM(line)-1] = 0;
   rc = assuan_transact (agent_ctx, line,
                         membuf_data_cb, &data,
-                        default_inq_cb, NULL, NULL, NULL);
+                        default_inq_cb, &dfltparm,
+                        NULL, NULL);
   if (rc)
     {
       xfree (get_membuf (&data, &len));
@@ -1211,6 +1225,9 @@ agent_scd_change_pin (int chvno, const char *serialno)
   int rc;
   char line[ASSUAN_LINELENGTH];
   const char *reset = "";
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
   (void)serialno;
 
@@ -1218,14 +1235,17 @@ agent_scd_change_pin (int chvno, const char *serialno)
     reset = "--reset";
   chvno %= 100;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
+  dfltparm.ctx = agent_ctx;
 
   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
   line[DIM(line)-1] = 0;
-  rc = assuan_transact (agent_ctx, line, NULL, NULL,
-                        default_inq_cb, NULL, NULL, NULL);
+  rc = assuan_transact (agent_ctx, line,
+                        NULL, NULL,
+                        default_inq_cb, &dfltparm,
+                        NULL, NULL);
   status_sc_op_failure (rc);
   return rc;
 }
@@ -1239,16 +1259,21 @@ agent_scd_checkpin  (const char *serialno)
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
 
-  rc = start_agent (1);
+  memset (&dfltparm, 0, sizeof dfltparm);
+
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
+  dfltparm.ctx = agent_ctx;
 
   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
   line[DIM(line)-1] = 0;
   rc = assuan_transact (agent_ctx, line,
                         NULL, NULL,
-                        default_inq_cb, NULL, NULL, NULL);
+                        default_inq_cb, &dfltparm,
+                        NULL, NULL);
   status_sc_op_failure (rc);
   return rc;
 }
@@ -1284,12 +1309,16 @@ agent_get_passphrase (const char *cache_id,
   char *arg3 = NULL;
   char *arg4 = NULL;
   membuf_t data;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
   *r_passphrase = NULL;
 
-  rc = start_agent (0);
+  rc = start_agent (NULL, 0);
   if (rc)
     return rc;
+  dfltparm.ctx = agent_ctx;
 
   /* Check that the gpg-agent understands the repeat option.  */
   if (assuan_transact (agent_ctx,
@@ -1327,7 +1356,8 @@ agent_get_passphrase (const char *cache_id,
   init_membuf_secure (&data, 64);
   rc = assuan_transact (agent_ctx, line,
                         membuf_data_cb, &data,
-                        default_inq_cb, NULL, NULL, NULL);
+                        default_inq_cb, &dfltparm,
+                        NULL, NULL);
 
   if (rc)
     xfree (get_membuf (&data, NULL));
@@ -1354,18 +1384,24 @@ agent_clear_passphrase (const char *cache_id)
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
   if (!cache_id || !*cache_id)
     return 0;
 
-  rc = start_agent (0);
+  rc = start_agent (NULL, 0);
   if (rc)
     return rc;
+  dfltparm.ctx = agent_ctx;
 
   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
   line[DIM(line)-1] = 0;
-  return assuan_transact (agent_ctx, line, NULL, NULL,
-                          default_inq_cb, NULL, NULL, NULL);
+  return assuan_transact (agent_ctx, line,
+                          NULL, NULL,
+                          default_inq_cb, &dfltparm,
+                          NULL, NULL);
 }
 
 
@@ -1377,10 +1413,14 @@ gpg_agent_get_confirmation (const char *desc)
   int rc;
   char *tmp;
   char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
 
-  rc = start_agent (0);
+  rc = start_agent (NULL, 0);
   if (rc)
     return rc;
+  dfltparm.ctx = agent_ctx;
 
   tmp = percent_plus_escape (desc);
   if (!tmp)
@@ -1389,8 +1429,10 @@ gpg_agent_get_confirmation (const char *desc)
   line[DIM(line)-1] = 0;
   xfree (tmp);
 
-  rc = assuan_transact (agent_ctx, line, NULL, NULL,
-                        default_inq_cb, NULL, NULL, NULL);
+  rc = assuan_transact (agent_ctx, line,
+                        NULL, NULL,
+                        default_inq_cb, &dfltparm,
+                        NULL, NULL);
   return rc;
 }
 
@@ -1405,7 +1447,7 @@ agent_get_s2k_count (unsigned long *r_count)
 
   *r_count = 0;
 
-  err = start_agent (0);
+  err = start_agent (NULL, 0);
   if (err)
     return err;
 
@@ -1430,3 +1472,863 @@ agent_get_s2k_count (unsigned long *r_count)
   return err;
 }
 
+
+\f
+/* Ask the agent whether a secret key for the given public key is
+   available.  Returns 0 if available.  */
+gpg_error_t
+agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  char *hexgrip;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  err = hexkeygrip_from_pk (pk, &hexgrip);
+  if (err)
+    return err;
+
+  snprintf (line, sizeof line, "HAVEKEY %s", hexgrip);
+  xfree (hexgrip);
+
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+  return err;
+}
+
+/* Ask the agent whether a secret key is available for any of the
+   keys (primary or sub) in KEYBLOCK.  Returns 0 if available.  */
+gpg_error_t
+agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  char *p;
+  kbnode_t kbctx, node;
+  int nkeys;
+  unsigned char grip[20];
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  err = gpg_error (GPG_ERR_NO_SECKEY); /* Just in case no key was
+                                          found in KEYBLOCK.  */
+  p = stpcpy (line, "HAVEKEY");
+  for (kbctx=NULL, nkeys=0; (node = walk_kbnode (keyblock, &kbctx, 0)); )
+    if (node->pkt->pkttype == PKT_PUBLIC_KEY
+        || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+        || node->pkt->pkttype == PKT_SECRET_KEY
+        || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+      {
+        if (nkeys && ((p - line) + 41) > (ASSUAN_LINELENGTH - 2))
+          {
+            err = assuan_transact (agent_ctx, line,
+                                   NULL, NULL, NULL, NULL, NULL, NULL);
+            if (err != gpg_err_code (GPG_ERR_NO_SECKEY))
+              break; /* Seckey available or unexpected error - ready.  */
+            p = stpcpy (line, "HAVEKEY");
+            nkeys = 0;
+          }
+
+        err = keygrip_from_pk (node->pkt->pkt.public_key, grip);
+        if (err)
+          return err;
+        *p++ = ' ';
+        bin2hex (grip, 20, p);
+        p += 40;
+        nkeys++;
+      }
+
+  if (!err && nkeys)
+    err = assuan_transact (agent_ctx, line,
+                           NULL, NULL, NULL, NULL, NULL, NULL);
+
+  return err;
+}
+
+
+\f
+static gpg_error_t
+keyinfo_status_cb (void *opaque, const char *line)
+{
+  char **serialno = opaque;
+  const char *s, *s2;
+
+  if ((s = has_leading_keyword (line, "KEYINFO ")) && !*serialno)
+    {
+      s = strchr (s, ' ');
+      if (s && s[1] == 'T' && s[2] == ' ' && s[3])
+        {
+          s += 3;
+          s2 = strchr (s, ' ');
+          if ( s2 > s )
+            {
+              *serialno = xtrymalloc ((s2 - s)+1);
+              if (*serialno)
+                {
+                  memcpy (*serialno, s, s2 - s);
+                  (*serialno)[s2 - s] = 0;
+                }
+            }
+        }
+    }
+  return 0;
+}
+
+
+/* Return the serial number for a secret key.  If the returned serial
+   number is NULL, the key is not stored on a smartcard.  Caller needs
+   to free R_SERIALNO.  */
+gpg_error_t
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  char *serialno = NULL;
+
+  *r_serialno = NULL;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  if (!hexkeygrip || strlen (hexkeygrip) != 40)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  snprintf (line, DIM(line)-1, "KEYINFO %s", hexkeygrip);
+  line[DIM(line)-1] = 0;
+
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
+                         keyinfo_status_cb, &serialno);
+  if (!err && serialno)
+    {
+      /* Sanity check for bad characters.  */
+      if (strpbrk (serialno, ":\n\r"))
+        err = GPG_ERR_INV_VALUE;
+    }
+  if (err)
+    xfree (serialno);
+  else
+    *r_serialno = serialno;
+  return err;
+}
+
+\f
+/* Status callback for agent_import_key, agent_export_key and
+   agent_genkey.  */
+static gpg_error_t
+cache_nonce_status_cb (void *opaque, const char *line)
+{
+  struct cache_nonce_parm_s *parm = opaque;
+  const char *keyword = line;
+  int keywordlen;
+
+  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+    ;
+  while (spacep (line))
+    line++;
+
+  if (keywordlen == 11 && !memcmp (keyword, "CACHE_NONCE", keywordlen))
+    {
+      if (parm->cache_nonce_addr)
+        {
+          xfree (*parm->cache_nonce_addr);
+          *parm->cache_nonce_addr = xtrystrdup (line);
+        }
+    }
+  else if (keywordlen == 12 && !memcmp (keyword, "PASSWD_NONCE", keywordlen))
+    {
+      if (parm->passwd_nonce_addr)
+        {
+          xfree (*parm->passwd_nonce_addr);
+          *parm->passwd_nonce_addr = xtrystrdup (line);
+        }
+    }
+
+  return 0;
+}
+
+
+\f
+/* Handle a KEYPARMS inquiry.  Note, we only send the data,
+   assuan_transact takes care of flushing and writing the end */
+static gpg_error_t
+inq_genkey_parms (void *opaque, const char *line)
+{
+  struct genkey_parm_s *parm = opaque;
+  gpg_error_t err;
+
+  if (has_leading_keyword (line, "KEYPARAM"))
+    {
+      err = assuan_send_data (parm->dflt->ctx,
+                              parm->keyparms, strlen (parm->keyparms));
+    }
+  else
+    err = default_inq_cb (parm->dflt, line);
+
+  return err;
+}
+
+
+/* Call the agent to generate a new key.  KEYPARMS is the usual
+   S-expression giving the parameters of the key.  gpg-agent passes it
+   gcry_pk_genkey.  If NO_PROTECTION is true the agent is advised not
+   to protect the generated key. */
+gpg_error_t
+agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
+              const char *keyparms, int no_protection, gcry_sexp_t *r_pubkey)
+{
+  gpg_error_t err;
+  struct genkey_parm_s gk_parm;
+  struct cache_nonce_parm_s cn_parm;
+  struct default_inq_parm_s dfltparm;
+  membuf_t data;
+  size_t len;
+  unsigned char *buf;
+  char line[ASSUAN_LINELENGTH];
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+
+  *r_pubkey = NULL;
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  err = assuan_transact (agent_ctx, "RESET",
+                         NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  init_membuf (&data, 1024);
+  gk_parm.dflt     = &dfltparm;
+  gk_parm.keyparms = keyparms;
+  snprintf (line, sizeof line, "GENKEY%s%s%s",
+            no_protection? " --no-protection":"",
+            cache_nonce_addr && *cache_nonce_addr? " ":"",
+            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
+  cn_parm.cache_nonce_addr = cache_nonce_addr;
+  cn_parm.passwd_nonce_addr = NULL;
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         inq_genkey_parms, &gk_parm,
+                         cache_nonce_status_cb, &cn_parm);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    err = gpg_error_from_syserror ();
+  else
+    {
+      err = gcry_sexp_sscan (r_pubkey, NULL, buf, len);
+      xfree (buf);
+    }
+  return err;
+}
+
+
+\f
+/* Call the agent to read the public key part for a given keygrip.  If
+   FROMCARD is true, the key is directly read from the current
+   smartcard. In this case HEXKEYGRIP should be the keyID
+   (e.g. OPENPGP.3). */
+gpg_error_t
+agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
+               unsigned char **r_pubkey)
+{
+  gpg_error_t err;
+  membuf_t data;
+  size_t len;
+  unsigned char *buf;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+
+  *r_pubkey = NULL;
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  err = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  snprintf (line, DIM(line)-1, "%sREADKEY %s", fromcard? "SCD ":"", hexkeygrip);
+
+  init_membuf (&data, 1024);
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         default_inq_cb, &dfltparm,
+                         NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  if (!gcry_sexp_canon_len (buf, len, NULL, NULL))
+    {
+      xfree (buf);
+      return gpg_error (GPG_ERR_INV_SEXP);
+    }
+  *r_pubkey = buf;
+  return 0;
+}
+
+
+\f
+/* Call the agent to do a sign operation using the key identified by
+   the hex string KEYGRIP.  DESC is a description of the key to be
+   displayed if the agent needs to ask for the PIN.  DIGEST and
+   DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
+   used to compute the digest.  If CACHE_NONCE is used the agent is
+   advised to first try a passphrase associated with that nonce. */
+gpg_error_t
+agent_pksign (ctrl_t ctrl, const char *cache_nonce,
+              const char *keygrip, const char *desc,
+              u32 *keyid, u32 *mainkeyid, int pubkey_algo,
+              unsigned char *digest, size_t digestlen, int digestalgo,
+              gcry_sexp_t *r_sigval)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  membuf_t data;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+  dfltparm.keyinfo.keyid       = keyid;
+  dfltparm.keyinfo.mainkeyid   = mainkeyid;
+  dfltparm.keyinfo.pubkey_algo = pubkey_algo;
+
+  *r_sigval = NULL;
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  if (digestlen*2 + 50 > DIM(line))
+    return gpg_error (GPG_ERR_GENERAL);
+
+  err = assuan_transact (agent_ctx, "RESET",
+                         NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip);
+  line[DIM(line)-1] = 0;
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      line[DIM(line)-1] = 0;
+      err = assuan_transact (agent_ctx, line,
+                            NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  snprintf (line, sizeof line, "SETHASH %d ", digestalgo);
+  bin2hex (digest, digestlen, line + strlen (line));
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  init_membuf (&data, 1024);
+
+  snprintf (line, sizeof line, "PKSIGN%s%s",
+            cache_nonce? " -- ":"",
+            cache_nonce? cache_nonce:"");
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         default_inq_cb, &dfltparm,
+                         NULL, NULL);
+  if (err)
+    xfree (get_membuf (&data, NULL));
+  else
+    {
+      unsigned char *buf;
+      size_t len;
+
+      buf = get_membuf (&data, &len);
+      if (!buf)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          err = gcry_sexp_sscan (r_sigval, NULL, buf, len);
+          xfree (buf);
+        }
+    }
+  return err;
+}
+
+
+\f
+/* Handle a CIPHERTEXT inquiry.  Note, we only send the data,
+   assuan_transact takes care of flushing and writing the END. */
+static gpg_error_t
+inq_ciphertext_cb (void *opaque, const char *line)
+{
+  struct cipher_parm_s *parm = opaque;
+  int rc;
+
+  if (has_leading_keyword (line, "CIPHERTEXT"))
+    {
+      assuan_begin_confidential (parm->ctx);
+      rc = assuan_send_data (parm->dflt->ctx,
+                             parm->ciphertext, parm->ciphertextlen);
+      assuan_end_confidential (parm->ctx);
+    }
+  else
+    rc = default_inq_cb (parm->dflt, line);
+
+  return rc;
+}
+
+
+/* Check whether there is any padding info from the agent.  */
+static gpg_error_t
+padding_info_cb (void *opaque, const char *line)
+{
+  int *r_padding = opaque;
+  const char *s;
+
+  if ((s=has_leading_keyword (line, "PADDING")))
+    {
+      *r_padding = atoi (s);
+    }
+
+  return 0;
+}
+
+
+/* Call the agent to do a decrypt operation using the key identified
+   by the hex string KEYGRIP and the input data S_CIPHERTEXT.  On the
+   success the decoded value is stored verbatim at R_BUF and its
+   length at R_BUF; the callers needs to release it.  KEYID, MAINKEYID
+   and PUBKEY_ALGO are used to construct additional promots or status
+   messages.   The padding information is stored at R_PADDING with -1
+   for not known.  */
+gpg_error_t
+agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
+                 u32 *keyid, u32 *mainkeyid, int pubkey_algo,
+                 gcry_sexp_t s_ciphertext,
+                 unsigned char **r_buf, size_t *r_buflen, int *r_padding)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  membuf_t data;
+  size_t n, len;
+  char *p, *buf, *endp;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+  dfltparm.keyinfo.keyid       = keyid;
+  dfltparm.keyinfo.mainkeyid   = mainkeyid;
+  dfltparm.keyinfo.pubkey_algo = pubkey_algo;
+
+  if (!keygrip || strlen(keygrip) != 40
+      || !s_ciphertext || !r_buf || !r_buflen || !r_padding)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  *r_buf = NULL;
+  *r_padding = -1;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  err = assuan_transact (agent_ctx, "RESET",
+                         NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  snprintf (line, sizeof line, "SETKEY %s", keygrip);
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      line[DIM(line)-1] = 0;
+      err = assuan_transact (agent_ctx, line,
+                            NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  init_membuf_secure (&data, 1024);
+  {
+    struct cipher_parm_s parm;
+
+    parm.dflt = &dfltparm;
+    parm.ctx = agent_ctx;
+    err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen);
+    if (err)
+      return err;
+    err = assuan_transact (agent_ctx, "PKDECRYPT",
+                           membuf_data_cb, &data,
+                           inq_ciphertext_cb, &parm,
+                           padding_info_cb, r_padding);
+    xfree (parm.ciphertext);
+  }
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+
+  put_membuf (&data, "", 1); /* Make sure it is 0 terminated.  */
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  assert (len); /* (we forced Nul termination.)  */
+
+  if (*buf != '(')
+    {
+      xfree (buf);
+      return gpg_error (GPG_ERR_INV_SEXP);
+    }
+
+  if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */
+    {
+      xfree (buf);
+      return gpg_error (GPG_ERR_INV_SEXP);
+    }
+  len -= 10;   /* Count only the data of the second part. */
+  p = buf + 8; /* Skip leading parenthesis and the value tag. */
+
+  n = strtoul (p, &endp, 10);
+  if (!n || *endp != ':')
+    {
+      xfree (buf);
+      return gpg_error (GPG_ERR_INV_SEXP);
+    }
+  endp++;
+  if (endp-p+n > len)
+    {
+      xfree (buf);
+      return gpg_error (GPG_ERR_INV_SEXP); /* Oops: Inconsistent S-Exp. */
+    }
+
+  memmove (buf, endp, n);
+
+  *r_buflen = n;
+  *r_buf = buf;
+  return 0;
+}
+
+
+\f
+/* Retrieve a key encryption key from the agent.  With FOREXPORT true
+   the key shall be used for export, with false for import.  On success
+   the new key is stored at R_KEY and its length at R_KEKLEN.  */
+gpg_error_t
+agent_keywrap_key (ctrl_t ctrl, int forexport, void **r_kek, size_t *r_keklen)
+{
+  gpg_error_t err;
+  membuf_t data;
+  size_t len;
+  unsigned char *buf;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+
+  *r_kek = NULL;
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  snprintf (line, DIM(line)-1, "KEYWRAP_KEY %s",
+            forexport? "--export":"--import");
+
+  init_membuf_secure (&data, 64);
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         default_inq_cb, &dfltparm,
+                         NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  *r_kek = buf;
+  *r_keklen = len;
+  return 0;
+}
+
+
+\f
+/* Handle the inquiry for an IMPORT_KEY command.  */
+static gpg_error_t
+inq_import_key_parms (void *opaque, const char *line)
+{
+  struct import_key_parm_s *parm = opaque;
+  gpg_error_t err;
+
+  if (has_leading_keyword (line, "KEYDATA"))
+    {
+      err = assuan_send_data (parm->dflt->ctx, parm->key, parm->keylen);
+    }
+  else
+    err = default_inq_cb (parm->dflt, line);
+
+  return err;
+}
+
+
+/* Call the agent to import a key into the agent.  */
+gpg_error_t
+agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
+                  const void *key, size_t keylen, int unattended)
+{
+  gpg_error_t err;
+  struct import_key_parm_s parm;
+  struct cache_nonce_parm_s cn_parm;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      line[DIM(line)-1] = 0;
+      err = assuan_transact (agent_ctx, line,
+                            NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  parm.dflt   = &dfltparm;
+  parm.key    = key;
+  parm.keylen = keylen;
+
+  snprintf (line, sizeof line, "IMPORT_KEY%s%s%s",
+            unattended? " --unattended":"",
+            cache_nonce_addr && *cache_nonce_addr? " ":"",
+            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
+  cn_parm.cache_nonce_addr = cache_nonce_addr;
+  cn_parm.passwd_nonce_addr = NULL;
+  err = assuan_transact (agent_ctx, line,
+                         NULL, NULL,
+                         inq_import_key_parms, &parm,
+                         cache_nonce_status_cb, &cn_parm);
+  return err;
+}
+
+
+\f
+/* Receive a secret key from the agent.  HEXKEYGRIP is the hexified
+   keygrip, DESC a prompt to be displayed with the agent's passphrase
+   question (needs to be plus+percent escaped).  If CACHE_NONCE_ADDR
+   is not NULL the agent is advised to first try a passphrase
+   associated with that nonce.  On success the key is stored as a
+   canonical S-expression at R_RESULT and R_RESULTLEN.  */
+gpg_error_t
+agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
+                  char **cache_nonce_addr,
+                  unsigned char **r_result, size_t *r_resultlen)
+{
+  gpg_error_t err;
+  struct cache_nonce_parm_s cn_parm;
+  membuf_t data;
+  size_t len;
+  unsigned char *buf;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+
+  *r_result = NULL;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      err = assuan_transact (agent_ctx, line,
+                             NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  snprintf (line, DIM(line)-1, "EXPORT_KEY --openpgp %s%s %s",
+            cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
+            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
+            hexkeygrip);
+
+  init_membuf_secure (&data, 1024);
+  cn_parm.cache_nonce_addr = cache_nonce_addr;
+  cn_parm.passwd_nonce_addr = NULL;
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         default_inq_cb, &dfltparm,
+                         cache_nonce_status_cb, &cn_parm);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  *r_result = buf;
+  *r_resultlen = len;
+  return 0;
+}
+
+
+\f
+/* Ask the agent to delete the key identified by HEXKEYGRIP.  If DESC
+   is not NULL, display DESC instead of the default description
+   message.  */
+gpg_error_t
+agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  if (!hexkeygrip || strlen (hexkeygrip) != 40)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      err = assuan_transact (agent_ctx, line,
+                             NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  snprintf (line, DIM(line)-1, "DELETE_KEY %s", hexkeygrip);
+  err = assuan_transact (agent_ctx, line, NULL, NULL,
+                         default_inq_cb, &dfltparm,
+                         NULL, NULL);
+  return err;
+}
+
+
+\f
+/* Ask the agent to change the passphrase of the key identified by
+   HEXKEYGRIP.  If DESC is not NULL, display DESC instead of the
+   default description message.  If CACHE_NONCE_ADDR is not NULL the
+   agent is advised to first try a passphrase associated with that
+   nonce.  If PASSWD_NONCE_ADDR is not NULL the agent will try to use
+   the passphrase associated with that nonce.  */
+gpg_error_t
+agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
+              char **cache_nonce_addr, char **passwd_nonce_addr)
+{
+  gpg_error_t err;
+  struct cache_nonce_parm_s cn_parm;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctrl = ctrl;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+  dfltparm.ctx = agent_ctx;
+
+  if (!hexkeygrip || strlen (hexkeygrip) != 40)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      err = assuan_transact (agent_ctx, line,
+                             NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  snprintf (line, DIM(line)-1, "PASSWD %s%s %s%s %s",
+            cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
+            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
+            passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
+            passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
+            hexkeygrip);
+  cn_parm.cache_nonce_addr = cache_nonce_addr;
+  cn_parm.passwd_nonce_addr = passwd_nonce_addr;
+  err = assuan_transact (agent_ctx, line, NULL, NULL,
+                         default_inq_cb, &dfltparm,
+                         cache_nonce_status_cb, &cn_parm);
+  return err;
+}
+
+/* Return the version reported by gpg-agent.  */
+gpg_error_t
+agent_get_version (ctrl_t ctrl, char **r_version)
+{
+  gpg_error_t err;
+  membuf_t data;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  init_membuf (&data, 64);
+  err = assuan_transact (agent_ctx, "GETINFO version",
+                        membuf_data_cb, &data,
+                        NULL, NULL, NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, NULL));
+      *r_version = NULL;
+    }
+  else
+    {
+      put_membuf (&data, "", 1);
+      *r_version = get_membuf (&data, NULL);
+      if (!*r_version)
+        err = gpg_error_from_syserror ();
+    }
+  return err;
+}
index 9088e4a..a99cac9 100644 (file)
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef GNUPG_G10_CALL_AGENT_H
-#define GNUPG_G10_CALL_AGENT_H 
+#define GNUPG_G10_CALL_AGENT_H
 
 
-struct agent_card_info_s 
+struct agent_card_info_s
 {
   int error;         /* private. */
   char *apptype;     /* Malloced application type string.  */
@@ -56,7 +56,7 @@ struct agent_card_info_s
   struct {           /* Array with key attributes.  */
     int algo;              /* Algorithm identifier.  */
     unsigned int nbits;    /* Supported keysize.  */
-  } key_attr[3];      
+  } key_attr[3];
   struct {
     unsigned int ki:1;     /* Key import available.  */
     unsigned int aac:1;    /* Algorithm attributes are changeable.  */
@@ -76,11 +76,18 @@ struct agent_card_genkey_s {
 void agent_release_card_info (struct agent_card_info_s *info);
 
 /* Return card info. */
-int agent_learn (struct agent_card_info_s *info);
+int agent_scd_learn (struct agent_card_info_s *info);
+
+/* Let the agent learn about the current card.  */
+gpg_error_t agent_learn (void);
 
 /* Update INFO with the attribute NAME. */
 int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
 
+/* Send the KEYTOCARD command. */
+int agent_keytocard (const char *hexgrip, int keyno, int force,
+                     const char *serialno, const char *timestamp);
+
 /* Send a SETATTR command to the SCdaemon. */
 int agent_scd_setattr (const char *name,
                        const unsigned char *value, size_t valuelen,
@@ -98,16 +105,6 @@ int agent_scd_writekey (int keyno, const char *serialno,
 int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
                       const char *serialno, u32 createtime);
 
-/* Send a PKSIGN command to the SCdaemon. */
-int agent_scd_pksign (const char *keyid, int hashalgo,
-                      const unsigned char *indata, size_t indatalen,
-                      unsigned char **r_buf, size_t *r_buflen);
-
-/* Send a PKDECRYPT command to the SCdaemon. */
-int agent_scd_pkdecrypt (const char *serialno,
-                         const unsigned char *indata, size_t indatalen,
-                         unsigned char **r_buf, size_t *r_buflen);
-
 /* Send a READKEY command to the SCdaemon. */
 int agent_scd_readcert (const char *certidstr,
                         void **r_buf, size_t *r_buflen);
@@ -140,6 +137,66 @@ gpg_error_t gpg_agent_get_confirmation (const char *desc);
 /* Return the S2K iteration count as computed by gpg-agent.  */
 gpg_error_t agent_get_s2k_count (unsigned long *r_count);
 
+/* Check whether a secret key for public key PK is available.  Returns
+   0 if the secret key is available. */
+gpg_error_t agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk);
 
-#endif /*GNUPG_G10_CALL_AGENT_H*/
+/* Ask the agent whether a secret key is availabale for any of the
+   keys (primary or sub) in KEYBLOCK.  Returns 0 if available.  */
+gpg_error_t agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
+
+
+/* Return infos about the secret key with HEXKEYGRIP.  */
+gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+                               char **r_serialno);
+
+/* Generate a new key.  */
+gpg_error_t agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
+                          const char *keyparms, int no_protection,
+                          gcry_sexp_t *r_pubkey);
+
+/* Read a public key.  */
+gpg_error_t agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
+                           unsigned char **r_pubkey);
 
+/* Create a signature.  */
+gpg_error_t agent_pksign (ctrl_t ctrl, const char *cache_nonce,
+                          const char *hexkeygrip, const char *desc,
+                          u32 *keyid, u32 *mainkeyid, int pubkey_algo,
+                          unsigned char *digest, size_t digestlen,
+                          int digestalgo,
+                          gcry_sexp_t *r_sigval);
+
+/* Decrypt a ciphertext.  */
+gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
+                             u32 *keyid, u32 *mainkeyid, int pubkey_algo,
+                             gcry_sexp_t s_ciphertext,
+                             unsigned char **r_buf, size_t *r_buflen,
+                             int *r_padding);
+
+/* Retrieve a key encryption key.  */
+gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,
+                               void **r_kek, size_t *r_keklen);
+
+/* Send a key to the agent.  */
+gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc,
+                              char **cache_nonce_addr,
+                              const void *key, size_t keylen, int unattended);
+
+/* Receive a key from the agent.  */
+gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip,
+                              const char *desc, char **cache_nonce_addr,
+                              unsigned char **r_result, size_t *r_resultlen);
+
+/* Delete a key from the agent.  */
+gpg_error_t agent_delete_key (ctrl_t ctrl, const char *hexkeygrip,
+                              const char *desc);
+
+/* Change the passphrase of a key.  */
+gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
+                          char **cache_nonce_addr, char **passwd_nonce_addr);
+/* Get the version reported by gpg-agent.  */
+gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version);
+
+
+#endif /*GNUPG_G10_CALL_AGENT_H*/
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
new file mode 100644 (file)
index 0000000..5bddbbe
--- /dev/null
@@ -0,0 +1,737 @@
+/* call-dirmngr.c - GPG operations to the Dirmngr.
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <assert.h>
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#include "gpg.h"
+#include <assuan.h>
+#include "util.h"
+#include "membuf.h"
+#include "options.h"
+#include "i18n.h"
+#include "asshelp.h"
+#include "keyserver.h"
+#include "call-dirmngr.h"
+
+
+/* Parameter structure used to gather status info.  */
+struct ks_status_parm_s
+{
+  char *source;
+};
+
+
+/* Parameter structure used with the KS_SEARCH command.  */
+struct ks_search_parm_s
+{
+  gpg_error_t lasterr;  /* Last error code.  */
+  membuf_t saveddata;   /* Buffer to build complete lines.  */
+  char *helpbuf;        /* NULL or malloced buffer.  */
+  size_t helpbufsize;   /* Allocated size of HELPBUF.  */
+  gpg_error_t (*data_cb)(void*, int, char*);  /* Callback.  */
+  void *data_cb_value;  /* First argument for DATA_CB.  */
+  struct ks_status_parm_s *stparm; /* Link to the status parameter.  */
+};
+
+
+/* Parameter structure used with the KS_GET command.  */
+struct ks_get_parm_s
+{
+  estream_t memfp;
+};
+
+
+/* Parameter structure used with the KS_PUT command.  */
+struct ks_put_parm_s
+{
+  assuan_context_t ctx;
+  kbnode_t keyblock;  /* The optional keyblock.  */
+  const void *data;   /* The key in OpenPGP binary format.  */
+  size_t datalen;     /* The length of DATA.  */
+};
+
+
+/* Data used to associate an session with dirmngr contexts.  We can't
+   use a simple one to one mapping because we sometimes need two
+   connections to the dirmngr; for example while doing a listing and
+   being in a data callback we may want to retrieve a key.  The local
+   dirmngr data takes care of this.  At the end of the session the
+   function dirmngr_deinit_session_data is called by gpg.c to cleanup
+   these resources.  Note that gpg.h defines a typedef dirmngr_local_t
+   for this structure. */
+struct dirmngr_local_s
+{
+  /* Link to other contexts which are used simultaneously.  */
+  struct dirmngr_local_s *next;
+
+  /* The active Assuan context. */
+  assuan_context_t ctx;
+
+  /* Flag set to true while an operation is running on CTX.  */
+  int is_active;
+};
+
+
+\f
+/* Deinitialize all session data of dirmngr pertaining to CTRL.  */
+void
+gpg_dirmngr_deinit_session_data (ctrl_t ctrl)
+{
+  dirmngr_local_t dml;
+
+  while ((dml = ctrl->dirmngr_local))
+    {
+      ctrl->dirmngr_local = dml->next;
+      if (dml->is_active)
+        log_error ("oops: trying to cleanup an active dirmngr context\n");
+      else
+        assuan_release (dml->ctx);
+      xfree (dml);
+    }
+}
+
+
+/* Try to connect to the Dirmngr via a socket or spawn it if possible.
+   Handle the server's initial greeting and set global options.  */
+static gpg_error_t
+create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+
+  *r_ctx = NULL;
+  err = start_new_dirmngr (&ctx,
+                           GPG_ERR_SOURCE_DEFAULT,
+                           opt.homedir,
+                           opt.dirmngr_program,
+                           opt.verbose, DBG_ASSUAN,
+                           NULL /*gpg_status2*/, ctrl);
+  if (!err)
+    {
+      keyserver_spec_t ksi;
+
+      /* Tell the dirmngr that we want to collect audit event. */
+      /* err = assuan_transact (agent_ctx, "OPTION audit-events=1", */
+      /*                        NULL, NULL, NULL, NULL, NULL, NULL); */
+
+      /* Set all configured keyservers.  We clear existing keyservers
+         so that any keyserver configured in GPG overrides keyservers
+         possibly still configured in Dirmngr for the session (Note
+         that the keyserver list of a session in Dirmngr survives a
+         RESET. */
+      for (ksi = opt.keyserver; !err && ksi; ksi = ksi->next)
+        {
+          char *line;
+
+          line = xtryasprintf ("KEYSERVER%s %s",
+                               ksi == opt.keyserver? " --clear":"", ksi->uri);
+          if (!line)
+            err = gpg_error_from_syserror ();
+          else
+            {
+              err = assuan_transact (ctx, line,
+                                     NULL, NULL, NULL, NULL, NULL, NULL);
+              xfree (line);
+            }
+        }
+    }
+
+  if (err)
+    assuan_release (ctx);
+  else
+    {
+      /* audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err); */
+      *r_ctx = ctx;
+    }
+
+  return err;
+}
+
+
+/* Get a context for accessing dirmngr.  If no context is available a
+   new one is created and - if required - dirmngr started.  On success
+   an assuan context is stored at R_CTX.  This context may only be
+   released by means of close_context.  Note that NULL is stored at
+   R_CTX on error.  */
+static gpg_error_t
+open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
+{
+  gpg_error_t err;
+  dirmngr_local_t dml;
+
+  *r_ctx = NULL;
+  for (;;)
+    {
+      for (dml = ctrl->dirmngr_local; dml && dml->is_active; dml = dml->next)
+        ;
+      if (dml)
+        {
+          /* Found an inactive local session - return that.  */
+          assert (!dml->is_active);
+          dml->is_active = 1;
+          *r_ctx = dml->ctx;
+          return 0;
+        }
+
+      dml = xtrycalloc (1, sizeof *dml);
+      if (!dml)
+        return gpg_error_from_syserror ();
+      err = create_context (ctrl, &dml->ctx);
+      if (err)
+        {
+          xfree (dml);
+          return err;
+        }
+      /* To be on the nPth thread safe site we need to add it to a
+         list; this is far easier than to have a lock for this
+         function.  It should not happen anyway but the code is free
+         because we need it for the is_active check above.  */
+      dml->next = ctrl->dirmngr_local;
+      ctrl->dirmngr_local = dml;
+    }
+}
+
+
+/* Close the assuan context CTX or return it to a pool of unused
+   contexts.  If CTX is NULL, the function does nothing.  */
+static void
+close_context (ctrl_t ctrl, assuan_context_t ctx)
+{
+  dirmngr_local_t dml;
+
+  if (!ctx)
+    return;
+
+  for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
+    {
+      if (dml->ctx == ctx)
+        {
+          if (!dml->is_active)
+            log_fatal ("closing inactive dirmngr context %p\n", ctx);
+          dml->is_active = 0;
+          return;
+        }
+    }
+  log_fatal ("closing unknown dirmngr ctx %p\n", ctx);
+}
+
+
+\f
+/* Status callback for ks_get and ks_search.  */
+static gpg_error_t
+ks_status_cb (void *opaque, const char *line)
+{
+  struct ks_status_parm_s *parm = opaque;
+  gpg_error_t err = 0;
+  const char *s;
+
+  if ((s = has_leading_keyword (line, "SOURCE")))
+    {
+      if (!parm->source)
+        {
+          parm->source = xtrystrdup (s);
+          if (!parm->source)
+            err = gpg_error_from_syserror ();
+        }
+    }
+
+  return err;
+}
+
+
+\f
+/* Data callback for the KS_SEARCH command. */
+static gpg_error_t
+ks_search_data_cb (void *opaque, const void *data, size_t datalen)
+{
+  gpg_error_t err = 0;
+  struct ks_search_parm_s *parm = opaque;
+  const char *line, *s;
+  size_t rawlen, linelen;
+  char fixedbuf[256];
+
+  if (parm->lasterr)
+    return 0;
+
+  if (parm->stparm->source)
+    {
+      err = parm->data_cb (parm->data_cb_value, 1, parm->stparm->source);
+      if (err)
+        {
+          parm->lasterr = err;
+          return err;
+        }
+      /* Clear it so that we won't get back here unless the server
+         accidentally sends a second source status line.  Note that
+         will not see all accidentally sent source lines because it
+         depends on whether data lines have been send in between.  */
+      xfree (parm->stparm->source);
+      parm->stparm->source = NULL;
+    }
+
+  if (!data)
+    return 0;  /* Ignore END commands.  */
+
+  put_membuf (&parm->saveddata, data, datalen);
+
+ again:
+  line = peek_membuf (&parm->saveddata, &rawlen);
+  if (!line)
+    {
+      parm->lasterr = gpg_error_from_syserror ();
+      return parm->lasterr; /* Tell the server about our problem.  */
+    }
+  if ((s = memchr (line, '\n', rawlen)))
+    {
+      linelen = s - line;  /* That is the length excluding the LF.  */
+      if (linelen + 1 < sizeof fixedbuf)
+        {
+          /* We can use the static buffer.  */
+          memcpy (fixedbuf, line, linelen);
+          fixedbuf[linelen] = 0;
+          if (linelen && fixedbuf[linelen-1] == '\r')
+            fixedbuf[linelen-1] = 0;
+          err = parm->data_cb (parm->data_cb_value, 0, fixedbuf);
+        }
+      else
+        {
+          if (linelen + 1 >= parm->helpbufsize)
+            {
+              xfree (parm->helpbuf);
+              parm->helpbufsize = linelen + 1 + 1024;
+              parm->helpbuf = xtrymalloc (parm->helpbufsize);
+              if (!parm->helpbuf)
+                {
+                  parm->lasterr = gpg_error_from_syserror ();
+                  return parm->lasterr;
+                }
+            }
+          memcpy (parm->helpbuf, line, linelen);
+          parm->helpbuf[linelen] = 0;
+          if (linelen && parm->helpbuf[linelen-1] == '\r')
+            parm->helpbuf[linelen-1] = 0;
+          err = parm->data_cb (parm->data_cb_value, 0, parm->helpbuf);
+        }
+      if (err)
+        parm->lasterr = err;
+      else
+        {
+          clear_membuf (&parm->saveddata, linelen+1);
+          goto again;  /* There might be another complete line.  */
+        }
+    }
+
+  return err;
+}
+
+
+/* Run the KS_SEARCH command using the search string SEARCHSTR.  All
+   data lines are passed to the CB function.  That function is called
+   with CB_VALUE as its first argument, a 0 as second argument, and
+   the decoded data line as third argument.  The callback function may
+   modify the data line and it is guaranteed that this data line is a
+   complete line with a terminating 0 character but without the
+   linefeed.  NULL is passed to the callback to indicate EOF.  */
+gpg_error_t
+gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
+                       gpg_error_t (*cb)(void*, int, char *), void *cb_value)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  struct ks_status_parm_s stparm;
+  struct ks_search_parm_s parm;
+  char line[ASSUAN_LINELENGTH];
+
+  err = open_context (ctrl, &ctx);
+  if (err)
+    return err;
+
+  {
+    char *escsearchstr = percent_plus_escape (searchstr);
+    if (!escsearchstr)
+      {
+        err = gpg_error_from_syserror ();
+        close_context (ctrl, ctx);
+        return err;
+      }
+    snprintf (line, sizeof line, "KS_SEARCH -- %s", escsearchstr);
+    xfree (escsearchstr);
+  }
+
+  memset (&stparm, 0, sizeof stparm);
+  memset (&parm, 0, sizeof parm);
+  init_membuf (&parm.saveddata, 1024);
+  parm.data_cb = cb;
+  parm.data_cb_value = cb_value;
+  parm.stparm = &stparm;
+
+  err = assuan_transact (ctx, line, ks_search_data_cb, &parm,
+                        NULL, NULL, ks_status_cb, &stparm);
+  if (!err)
+    err = cb (cb_value, 0, NULL);  /* Send EOF.  */
+
+  xfree (get_membuf (&parm.saveddata, NULL));
+  xfree (parm.helpbuf);
+  xfree (stparm.source);
+
+  close_context (ctrl, ctx);
+  return err;
+}
+
+
+\f
+/* Data callback for the KS_GET and KS_FETCH commands. */
+static gpg_error_t
+ks_get_data_cb (void *opaque, const void *data, size_t datalen)
+{
+  gpg_error_t err = 0;
+  struct ks_get_parm_s *parm = opaque;
+  size_t nwritten;
+
+  if (!data)
+    return 0;  /* Ignore END commands.  */
+
+  if (es_write (parm->memfp, data, datalen, &nwritten))
+    err = gpg_error_from_syserror ();
+
+  return err;
+}
+
+
+/* Run the KS_GET command using the patterns in the array PATTERN.  On
+   success an estream object is returned to retrieve the keys.  On
+   error an error code is returned and NULL stored at R_FP.
+
+   The pattern may only use search specification which a keyserver can
+   use to retriev keys.  Because we know the format of the pattern we
+   don't need to escape the patterns before sending them to the
+   server.
+
+   If R_SOURCE is not NULL the source of the data is stored as a
+   malloced string there.  If a source is not known NULL is stored.
+
+   If there are too many patterns the function returns an error.  That
+   could be fixed by issuing several search commands or by
+   implementing a different interface.  However with long keyids we
+   are able to ask for (1000-10-1)/(2+8+1) = 90 keys at once.  */
+gpg_error_t
+gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern,
+                    estream_t *r_fp, char **r_source)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  struct ks_status_parm_s stparm;
+  struct ks_get_parm_s parm;
+  char *line = NULL;
+  size_t linelen;
+  membuf_t mb;
+  int idx;
+
+  memset (&stparm, 0, sizeof stparm);
+  memset (&parm, 0, sizeof parm);
+
+  *r_fp = NULL;
+  if (r_source)
+    *r_source = NULL;
+
+  err = open_context (ctrl, &ctx);
+  if (err)
+    return err;
+
+  /* Lump all patterns into one string.  */
+  init_membuf (&mb, 1024);
+  put_membuf_str (&mb, "KS_GET --");
+  for (idx=0; pattern[idx]; idx++)
+    {
+      put_membuf (&mb, " ", 1); /* Append Delimiter.  */
+      put_membuf_str (&mb, pattern[idx]);
+    }
+  put_membuf (&mb, "", 1); /* Append Nul.  */
+  line = get_membuf (&mb, &linelen);
+  if (!line)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  if (linelen + 2 >= ASSUAN_LINELENGTH)
+    {
+      err = gpg_error (GPG_ERR_TOO_MANY);
+      goto leave;
+    }
+
+  parm.memfp = es_fopenmem (0, "rwb");
+  if (!parm.memfp)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
+                         NULL, NULL, ks_status_cb, &stparm);
+  if (err)
+    goto leave;
+
+  es_rewind (parm.memfp);
+  *r_fp = parm.memfp;
+  parm.memfp = NULL;
+
+  if (r_source)
+    {
+      *r_source = stparm.source;
+      stparm.source = NULL;
+    }
+
+ leave:
+  es_fclose (parm.memfp);
+  xfree (stparm.source);
+  xfree (line);
+  close_context (ctrl, ctx);
+  return err;
+}
+
+
+/* Run the KS_FETCH and pass URL as argument.  On success an estream
+   object is returned to retrieve the keys.  On error an error code is
+   returned and NULL stored at R_FP.
+
+   The url is expected to point to a small set of keys; in many cases
+   only to one key.  However, schemes like finger may return several
+   keys.  Note that the configured keyservers are ignored by the
+   KS_FETCH command.  */
+gpg_error_t
+gpg_dirmngr_ks_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  struct ks_get_parm_s parm;
+  char *line = NULL;
+
+  memset (&parm, 0, sizeof parm);
+
+  *r_fp = NULL;
+
+  err = open_context (ctrl, &ctx);
+  if (err)
+    return err;
+
+  line = strconcat ("KS_FETCH -- ", url, NULL);
+  if (!line)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
+    {
+      err = gpg_error (GPG_ERR_TOO_LARGE);
+      goto leave;
+    }
+
+  parm.memfp = es_fopenmem (0, "rwb");
+  if (!parm.memfp)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
+                         NULL, NULL, NULL, NULL);
+  if (err)
+    goto leave;
+
+  es_rewind (parm.memfp);
+  *r_fp = parm.memfp;
+  parm.memfp = NULL;
+
+ leave:
+  es_fclose (parm.memfp);
+  xfree (line);
+  close_context (ctrl, ctx);
+  return err;
+}
+
+
+\f
+/* Handle the KS_PUT inquiries. */
+static gpg_error_t
+ks_put_inq_cb (void *opaque, const char *line)
+{
+  struct ks_put_parm_s *parm = opaque;
+  gpg_error_t err = 0;
+
+  if (has_leading_keyword (line, "KEYBLOCK"))
+    {
+      if (parm->data)
+        err = assuan_send_data (parm->ctx, parm->data, parm->datalen);
+    }
+  else if (has_leading_keyword (line, "KEYBLOCK_INFO"))
+    {
+      kbnode_t node;
+      estream_t fp;
+
+      /* Parse the keyblock and send info lines back to the server.  */
+      fp = es_fopenmem (0, "rw,samethread");
+      if (!fp)
+        err = gpg_error_from_syserror ();
+
+      for (node = parm->keyblock; !err && node; node=node->next)
+        {
+          switch(node->pkt->pkttype)
+            {
+            case PKT_PUBLIC_KEY:
+            case PKT_PUBLIC_SUBKEY:
+              {
+                PKT_public_key *pk = node->pkt->pkt.public_key;
+
+                keyid_from_pk (pk, NULL);
+
+                es_fprintf (fp, "%s:%08lX%08lX:%u:%u:%u:%u:%s%s:\n",
+                            node->pkt->pkttype==PKT_PUBLIC_KEY? "pub" : "sub",
+                            (ulong)pk->keyid[0], (ulong)pk->keyid[1],
+                            pk->pubkey_algo,
+                            nbits_from_pk (pk),
+                            pk->timestamp,
+                            pk->expiredate,
+                            pk->flags.revoked? "r":"",
+                            pk->has_expired? "e":"");
+              }
+              break;
+
+            case PKT_USER_ID:
+              {
+                PKT_user_id *uid = node->pkt->pkt.user_id;
+                int r;
+
+                if (!uid->attrib_data)
+                  {
+                    es_fprintf (fp, "uid:");
+
+                    /* Quote ':', '%', and any 8-bit characters.  */
+                    for (r=0; r < uid->len; r++)
+                      {
+                        if (uid->name[r] == ':'
+                            || uid->name[r]== '%'
+                            || (uid->name[r]&0x80))
+                          es_fprintf (fp, "%%%02X", (byte)uid->name[r]);
+                        else
+                          es_putc (uid->name[r], fp);
+                      }
+
+                    es_fprintf (fp, ":%u:%u:%s%s:\n",
+                                uid->created,uid->expiredate,
+                                uid->is_revoked? "r":"",
+                                uid->is_expired? "e":"");
+                  }
+              }
+              break;
+
+              /* This bit is really for the benefit of people who
+                 store their keys in LDAP servers.  It makes it easy
+                 to do queries for things like "all keys signed by
+                 Isabella".  */
+            case PKT_SIGNATURE:
+              {
+                PKT_signature *sig = node->pkt->pkt.signature;
+
+                if (IS_UID_SIG (sig))
+                  {
+                    es_fprintf (fp, "sig:%08lX%08lX:%X:%u:%u:\n",
+                                (ulong)sig->keyid[0],(ulong)sig->keyid[1],
+                                sig->sig_class, sig->timestamp,
+                                sig->expiredate);
+                  }
+              }
+              break;
+
+            default:
+              continue;
+            }
+          /* Given that the last operation was an es_fprintf we should
+             get the correct ERRNO if ferror indicates an error.  */
+          if (es_ferror (fp))
+            err = gpg_error_from_syserror ();
+        }
+
+      /* Without an error and if we have an keyblock at all, send the
+         data back.  */
+      if (!err && parm->keyblock)
+        {
+          int rc;
+          char buffer[512];
+          size_t nread;
+
+          es_rewind (fp);
+          while (!(rc=es_read (fp, buffer, sizeof buffer, &nread)) && nread)
+            {
+              err = assuan_send_data (parm->ctx, buffer, nread);
+              if (err)
+                break;
+            }
+          if (!err && rc)
+            err = gpg_error_from_syserror ();
+        }
+      es_fclose (fp);
+    }
+  else
+    return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
+
+  return err;
+}
+
+
+/* Send a key to the configured server.  {DATA,DATLEN} contains the
+   key in OpenPGP binary transport format.  If KEYBLOCK is not NULL it
+   has the internal representaion of that key; this is for example
+   used to convey meta data to LDAP keyservers.  */
+gpg_error_t
+gpg_dirmngr_ks_put (ctrl_t ctrl, void *data, size_t datalen, kbnode_t keyblock)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  struct ks_put_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+
+  /* We are going to parse the keyblock, thus we better make sure the
+     all information is readily available.  */
+  if (keyblock)
+    merge_keys_and_selfsig (keyblock);
+
+  err = open_context (ctrl, &ctx);
+  if (err)
+    return err;
+
+  parm.ctx = ctx;
+  parm.keyblock = keyblock;
+  parm.data = data;
+  parm.datalen = datalen;
+
+  err = assuan_transact (ctx, "KS_PUT", NULL, NULL,
+                         ks_put_inq_cb, &parm, NULL, NULL);
+
+  close_context (ctrl, ctx);
+  return err;
+}
diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h
new file mode 100644 (file)
index 0000000..481b948
--- /dev/null
@@ -0,0 +1,35 @@
+/* call-dirmngr.h - GPG operations to the Dirmngr
+ * Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GNUPG_G10_CALL_DIRMNGR_H
+#define GNUPG_G10_CALL_DIRMNGR_H
+
+void gpg_dirmngr_deinit_session_data (ctrl_t ctrl);
+
+gpg_error_t gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
+                                   gpg_error_t (*cb)(void*, int, char *),
+                                   void *cb_value);
+gpg_error_t gpg_dirmngr_ks_get (ctrl_t ctrl, char *pattern[],
+                                estream_t *r_fp, char **r_source);
+gpg_error_t gpg_dirmngr_ks_fetch (ctrl_t ctrl,
+                                  const char *url, estream_t *r_fp);
+gpg_error_t gpg_dirmngr_ks_put (ctrl_t ctrl, void *data, size_t datalen,
+                                kbnode_t keyblock);
+
+
+#endif /*GNUPG_G10_CALL_DIRMNGR_H*/
index 745ba1d..37fa9a6 100644 (file)
@@ -1,5 +1,6 @@
 /* card-util.c - Utility functions for the OpenPGP card.
- * Copyright (C) 2003, 2004, 2005, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2003-2005, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2003-2005, 2009 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -58,6 +59,7 @@ write_sc_op_status (gpg_error_t err)
       break;
 #if GNUPG_MAJOR_VERSION != 1
     case GPG_ERR_CANCELED:
+    case GPG_ERR_FULLY_CANCELED:
       write_status_text (STATUS_SC_OP_FAILURE, "1");
       break;
     case GPG_ERR_BAD_PIN:
@@ -79,7 +81,7 @@ change_pin (int unblock_v2, int allow_admin)
   struct agent_card_info_s info;
   int rc;
 
-  rc = agent_learn (&info);
+  rc = agent_scd_learn (&info);
   if (rc)
     {
       log_error (_("OpenPGP card not available: %s\n"),
@@ -203,9 +205,11 @@ get_manufacturer (unsigned int no)
     case 0x0001: return "PPC Card Systems";
     case 0x0002: return "Prism";
     case 0x0003: return "OpenFortress";
-    case 0x0004: return "Wewid AB";
+    case 0x0004: return "Wewid";
     case 0x0005: return "ZeitControl";
     case 0x0006: return "Yubico";
+    case 0x0007: return "OpenKMS";
+    case 0x0008: return "LogoEmail";
 
     case 0x002A: return "Magrathea";
 
@@ -222,7 +226,7 @@ get_manufacturer (unsigned int no)
 
 
 static void
-print_sha1_fpr (FILE *fp, const unsigned char *fpr)
+print_sha1_fpr (estream_t fp, const unsigned char *fpr)
 {
   int i;
 
@@ -242,21 +246,21 @@ print_sha1_fpr (FILE *fp, const unsigned char *fpr)
 
 
 static void
-print_sha1_fpr_colon (FILE *fp, const unsigned char *fpr)
+print_sha1_fpr_colon (estream_t fp, const unsigned char *fpr)
 {
   int i;
 
   if (fpr)
     {
       for (i=0; i < 20 ; i++, fpr++)
-        fprintf (fp, "%02X", *fpr);
+        es_fprintf (fp, "%02X", *fpr);
     }
-  putc (':', fp);
+  es_putc (':', fp);
 }
 
 
 static void
-print_name (FILE *fp, const char *text, const char *name)
+print_name (estream_t fp, const char *text, const char *name)
 {
   tty_fprintf (fp, "%s", text);
 
@@ -265,9 +269,9 @@ print_name (FILE *fp, const char *text, const char *name)
   if (name && *name)
     {
       if (fp)
-        print_utf8_string2 (fp, name, strlen (name), '\n');
+        print_utf8_buffer2 (fp, name, strlen (name), '\n');
       else
-        tty_print_utf8_string2 (name, strlen (name), 0);
+        tty_print_utf8_string2 (NULL, name, strlen (name), 0);
     }
   else
     tty_fprintf (fp, _("[not set]"));
@@ -275,10 +279,11 @@ print_name (FILE *fp, const char *text, const char *name)
 }
 
 static void
-print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
+print_isoname (estream_t fp, const char *text,
+               const char *tag, const char *name)
 {
   if (opt.with_colons)
-    fprintf (fp, "%s:", tag);
+    es_fprintf (fp, "%s:", tag);
   else
     tty_fprintf (fp, "%s", text);
 
@@ -295,36 +300,36 @@ print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
           *given = 0;
           given += 2;
           if (opt.with_colons)
-            print_string (fp, given, strlen (given), ':');
+            es_write_sanitized (fp, given, strlen (given), ":", NULL);
           else if (fp)
-            print_utf8_string2 (fp, given, strlen (given), '\n');
+            print_utf8_buffer2 (fp, given, strlen (given), '\n');
           else
-            tty_print_utf8_string2 (given, strlen (given), 0);
+            tty_print_utf8_string2 (NULL, given, strlen (given), 0);
 
           if (opt.with_colons)
-            putc (':', fp);
+            es_putc (':', fp);
           else if (*buf)
             tty_fprintf (fp, " ");
         }
 
       if (opt.with_colons)
-        print_string (fp, buf, strlen (buf), ':');
+        es_write_sanitized (fp, buf, strlen (buf), ":", NULL);
       else if (fp)
-        print_utf8_string2 (fp, buf, strlen (buf), '\n');
+        print_utf8_buffer2 (fp, buf, strlen (buf), '\n');
       else
-        tty_print_utf8_string2 (buf, strlen (buf), 0);
+        tty_print_utf8_string2 (NULL, buf, strlen (buf), 0);
       xfree (buf);
     }
   else
     {
       if (opt.with_colons)
-        putc (':', fp);
+        es_putc (':', fp);
       else
         tty_fprintf (fp, _("[not set]"));
     }
 
   if (opt.with_colons)
-    fputs (":\n", fp);
+    es_fputs (":\n", fp);
   else
     tty_fprintf (fp, "\n");
 }
@@ -355,7 +360,7 @@ fpr_is_ff (const char *fpr)
 
 /* Print all available information about the current card. */
 void
-card_status (FILE *fp, char *serialno, size_t serialnobuflen)
+card_status (estream_t fp, char *serialno, size_t serialnobuflen)
 {
   struct agent_card_info_s info;
   PKT_public_key *pk = xcalloc (1, sizeof *pk);
@@ -367,19 +372,18 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
   if (serialno && serialnobuflen)
     *serialno = 0;
 
-  rc = agent_learn (&info);
+  rc = agent_scd_learn (&info);
   if (rc)
     {
       if (opt.with_colons)
-        fputs ("AID:::\n", fp);
-      log_error (_("OpenPGP card not available: %s\n"),
-                  gpg_strerror (rc));
+        es_fputs ("AID:::\n", fp);
+      log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (rc));
       xfree (pk);
       return;
     }
 
   if (opt.with_colons)
-    fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
+    es_fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
   else
     tty_fprintf (fp, "Application ID ...: %s\n",
                  info.serialno? info.serialno : "[none]");
@@ -389,31 +393,31 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
       if (info.apptype && !strcmp (info.apptype, "NKS"))
         {
           if (opt.with_colons)
-            fputs ("netkey-card:\n", fp);
+            es_fputs ("netkey-card:\n", fp);
           log_info ("this is a NetKey card\n");
         }
       else if (info.apptype && !strcmp (info.apptype, "DINSIG"))
         {
           if (opt.with_colons)
-            fputs ("dinsig-card:\n", fp);
+            es_fputs ("dinsig-card:\n", fp);
           log_info ("this is a DINSIG compliant card\n");
         }
       else if (info.apptype && !strcmp (info.apptype, "P15"))
         {
           if (opt.with_colons)
-            fputs ("pkcs15-card:\n", fp);
+            es_fputs ("pkcs15-card:\n", fp);
           log_info ("this is a PKCS#15 compliant card\n");
         }
       else if (info.apptype && !strcmp (info.apptype, "GELDKARTE"))
         {
           if (opt.with_colons)
-            fputs ("geldkarte-card:\n", fp);
+            es_fputs ("geldkarte-card:\n", fp);
           log_info ("this is a Geldkarte compliant card\n");
         }
       else
         {
           if (opt.with_colons)
-            fputs ("unknown:\n", fp);
+            es_fputs ("unknown:\n", fp);
         }
       log_info ("not an OpenPGP card\n");
       agent_release_card_info (&info);
@@ -429,69 +433,72 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
     strcpy (serialno, info.serialno);
 
   if (opt.with_colons)
-    fputs ("openpgp-card:\n", fp);
+    es_fputs ("openpgp-card:\n", fp);
 
 
   if (opt.with_colons)
     {
-      fprintf (fp, "version:%.4s:\n", info.serialno+12);
+      es_fprintf (fp, "version:%.4s:\n", info.serialno+12);
       uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
-      fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
-      fprintf (fp, "serial:%.8s:\n", info.serialno+20);
+      es_fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
+      es_fprintf (fp, "serial:%.8s:\n", info.serialno+20);
 
       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
 
-      fputs ("lang:", fp);
+      es_fputs ("lang:", fp);
       if (info.disp_lang)
-        print_string (fp, info.disp_lang, strlen (info.disp_lang), ':');
-      fputs (":\n", fp);
+        es_write_sanitized (fp, info.disp_lang, strlen (info.disp_lang),
+                            ":", NULL);
+      es_fputs (":\n", fp);
 
-      fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
+      es_fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
                                  info.disp_sex == 2? 'f' : 'u'));
 
-      fputs ("url:", fp);
+      es_fputs ("url:", fp);
       if (info.pubkey_url)
-        print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':');
-      fputs (":\n", fp);
+        es_write_sanitized (fp, info.pubkey_url, strlen (info.pubkey_url),
+                            ":", NULL);
+      es_fputs (":\n", fp);
 
-      fputs ("login:", fp);
+      es_fputs ("login:", fp);
       if (info.login_data)
-        print_string (fp, info.login_data, strlen (info.login_data), ':');
-      fputs (":\n", fp);
+        es_write_sanitized (fp, info.login_data, strlen (info.login_data),
+                            ":", NULL);
+      es_fputs (":\n", fp);
 
-      fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
+      es_fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
       for (i=0; i < DIM (info.key_attr); i++)
         if (info.key_attr[0].algo)
-          fprintf (fp, "keyattr:%d:%d:%u:\n", i+1,
-                   info.key_attr[i].algo, info.key_attr[i].nbits);
-      fprintf (fp, "maxpinlen:%d:%d:%d:\n",
-                   info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
-      fprintf (fp, "pinretry:%d:%d:%d:\n",
-                   info.chvretry[0], info.chvretry[1], info.chvretry[2]);
-      fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
+          es_fprintf (fp, "keyattr:%d:%d:%u:\n", i+1,
+                      info.key_attr[i].algo, info.key_attr[i].nbits);
+      es_fprintf (fp, "maxpinlen:%d:%d:%d:\n",
+                  info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
+      es_fprintf (fp, "pinretry:%d:%d:%d:\n",
+                  info.chvretry[0], info.chvretry[1], info.chvretry[2]);
+      es_fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
 
       for (i=0; i < 4; i++)
         {
           if (info.private_do[i])
             {
-              fprintf (fp, "private_do:%d:", i+1);
-              print_string (fp, info.private_do[i],
-                            strlen (info.private_do[i]), ':');
-              fputs (":\n", fp);
+              es_fprintf (fp, "private_do:%d:", i+1);
+              es_write_sanitized (fp, info.private_do[i],
+                                  strlen (info.private_do[i]), ":", NULL);
+              es_fputs (":\n", fp);
             }
         }
 
-      fputs ("cafpr:", fp);
+      es_fputs ("cafpr:", fp);
       print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
       print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
       print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
-      putc ('\n', fp);
-      fputs ("fpr:", fp);
+      es_putc ('\n', fp);
+      es_fputs ("fpr:", fp);
       print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
       print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
       print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
-      putc ('\n', fp);
-      fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
+      es_putc ('\n', fp);
+      es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
                (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
                (unsigned long)info.fpr3time);
     }
@@ -546,7 +553,9 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
             tty_fprintf (fp, " %u%c",
                          info.key_attr[i].nbits,
                          info.key_attr[i].algo == 1? 'R':
-                         info.key_attr[i].algo == 17? 'D': '?');
+                         info.key_attr[i].algo == 17? 'D':
+                         info.key_attr[i].algo == 18? 'e':
+                         info.key_attr[i].algo == 19? 'E': '?');
           tty_fprintf (fp, "\n");
         }
       tty_fprintf (fp,    "Max. PIN lengths .: %d %d %d\n",
@@ -578,10 +587,11 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
       if ( thefpr && !fpr_is_ff (thefpr)
            && !get_pubkey_byfprint (pk, thefpr, 20))
         {
-          KBNODE keyblock = NULL;
+          kbnode_t keyblock = NULL;
 
           print_pubkey_info (fp, pk);
 
+#if GNUPG_MAJOR_VERSION == 1
           if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
             print_card_key_info (fp, keyblock);
           else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
@@ -599,6 +609,11 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
                 }
             }
 
+#else /* GNUPG_MAJOR_VERSION != 1 */
+          if (!get_keyblock_byfprint (&keyblock, thefpr, 20))
+            print_card_key_info (fp, keyblock);
+#endif /* GNUPG_MAJOR_VERSION != 1 */
+
           release_kbnode (keyblock);
         }
       else
@@ -717,7 +732,7 @@ change_url (void)
 /* Fetch the key from the URL given on the card or try to get it from
    the default keyserver.  */
 static int
-fetch_url(void)
+fetch_url (ctrl_t ctrl)
 {
   int rc;
   struct agent_card_info_s info;
@@ -729,21 +744,31 @@ fetch_url(void)
     log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
   else
     {
+      struct keyserver_spec *spec=NULL;
+
       rc=agent_scd_getattr("KEY-FPR",&info);
       if(rc)
        log_error("error retrieving key fingerprint from card: %s\n",
                  gpg_strerror(rc));
       else if (info.pubkey_url && *info.pubkey_url)
-        {
-          strlist_t sl = NULL;
-
-          add_to_strlist (&sl, info.pubkey_url);
-          rc = keyserver_fetch (sl);
-          free_strlist (sl);
-        }
+       {
+         spec=parse_keyserver_uri(info.pubkey_url,1,NULL,0);
+         if(spec && info.fpr1valid)
+           {
+             /* This is not perfectly right.  Currently, all card
+                fingerprints are 20 digits, but what about
+                fingerprints for a future v5 key?  We should get the
+                length from somewhere lower in the code.  In any
+                event, the fpr/keyid is not meaningful for straight
+                HTTP fetches, but using it allows the card to point
+                to HKP and LDAP servers as well. */
+             rc = keyserver_import_fprint (ctrl, info.fpr1, 20, spec);
+             free_keyserver_spec(spec);
+           }
+       }
       else if (info.fpr1valid)
        {
-          rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
+          rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver);
        }
     }
 
@@ -758,13 +783,13 @@ fetch_url(void)
 static int
 get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
 {
-  FILE *fp;
+  estream_t fp;
   char *data;
   int n;
 
   *r_buffer = NULL;
 
-  fp = fopen (fname, "rb");
+  fp = es_fopen (fname, "rb");
 #if GNUPG_MAJOR_VERSION == 1
   if (fp && is_secured_file (fileno (fp)))
     {
@@ -775,7 +800,7 @@ get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
 #endif
   if (!fp)
     {
-      tty_printf (_("can't open `%s': %s\n"), fname, strerror (errno));
+      tty_printf (_("can't open '%s': %s\n"), fname, strerror (errno));
       return -1;
     }
 
@@ -783,18 +808,18 @@ get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
   if (!data)
     {
       tty_printf (_("error allocating enough memory: %s\n"), strerror (errno));
-      fclose (fp);
+      es_fclose (fp);
       return -1;
     }
 
   if (maxlen)
-    n = fread (data, 1, maxlen, fp);
+    n = es_fread (data, 1, maxlen, fp);
   else
     n = 0;
-  fclose (fp);
+  es_fclose (fp);
   if (n < 0)
     {
-      tty_printf (_("error reading `%s': %s\n"), fname, strerror (errno));
+      tty_printf (_("error reading '%s': %s\n"), fname, strerror (errno));
       xfree (data);
       return -1;
     }
@@ -808,9 +833,9 @@ get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
 static int
 put_data_to_file (const char *fname, const void *buffer, size_t length)
 {
-  FILE *fp;
+  estream_t fp;
 
-  fp = fopen (fname, "wb");
+  fp = es_fopen (fname, "wb");
 #if GNUPG_MAJOR_VERSION == 1
   if (fp && is_secured_file (fileno (fp)))
     {
@@ -821,17 +846,17 @@ put_data_to_file (const char *fname, const void *buffer, size_t length)
 #endif
   if (!fp)
     {
-      tty_printf (_("can't create `%s': %s\n"), fname, strerror (errno));
+      tty_printf (_("can't create '%s': %s\n"), fname, strerror (errno));
       return -1;
     }
 
-  if (length && fwrite (buffer, length, 1, fp) != 1)
+  if (length && es_fwrite (buffer, length, 1, fp) != 1)
     {
-      tty_printf (_("error writing `%s': %s\n"), fname, strerror (errno));
-      fclose (fp);
+      tty_printf (_("error writing '%s': %s\n"), fname, strerror (errno));
+      es_fclose (fp);
       return -1;
     }
-  fclose (fp);
+  es_fclose (fp);
   return 0;
 }
 
@@ -1244,6 +1269,7 @@ replace_existing_key_p (struct agent_card_info_s *info, int keyno)
       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
                                   _("Replace existing key? (y/N) ")))
         return -1;
+      return 1;
     }
   return 0;
 }
@@ -1258,7 +1284,7 @@ show_keysize_warning (void)
     return;
   shown = 1;
   tty_printf
-    (_("NOTE: There is no guarantee that the card "
+    (_("Note: There is no guarantee that the card "
        "supports the requested size.\n"
        "      If the key generation does not succeed, "
        "please check the\n"
@@ -1337,7 +1363,7 @@ do_change_keysize (int keyno, unsigned int nbits)
 
 
 static void
-generate_card_keys (void)
+generate_card_keys (ctrl_t ctrl)
 {
   struct agent_card_info_s info;
   int forced_chv1;
@@ -1351,6 +1377,8 @@ generate_card_keys (void)
     {
       char *answer;
 
+      /* FIXME: Should be something like cpr_get_bool so that a status
+         GET_BOOL will be emitted.  */
       answer = cpr_get ("cardedit.genkeys.backup_enc",
                         _("Make off-card backup of encryption key? (Y/n) "));
 
@@ -1366,7 +1394,7 @@ generate_card_keys (void)
        || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
     {
       tty_printf ("\n");
-      log_info (_("NOTE: keys are already stored on the card!\n"));
+      log_info (_("Note: keys are already stored on the card!\n"));
       tty_printf ("\n");
       if ( !cpr_get_answer_is_yes ("cardedit.genkeys.replace_keys",
                                    _("Replace existing keys? (y/N) ")))
@@ -1382,7 +1410,7 @@ generate_card_keys (void)
     {
       tty_printf ("\n");
       tty_printf (_("Please note that the factory settings of the PINs are\n"
-                    "   PIN = `%s'     Admin PIN = `%s'\n"
+                    "   PIN = '%s'     Admin PIN = '%s'\n"
                     "You should change them using the command --change-pin\n"),
                   "123456", "12345678");
       tty_printf ("\n");
@@ -1414,7 +1442,7 @@ generate_card_keys (void)
          the serialnumber and thus it won't harm.  */
     }
 
-  generate_keypair (NULL, info.serialno, want_backup? opt.homedir:NULL);
+  generate_keypair (ctrl, 1, NULL, info.serialno, want_backup);
 
  leave:
   agent_release_card_info (&info);
@@ -1424,16 +1452,17 @@ generate_card_keys (void)
 
 /* This function is used by the key edit menu to generate an arbitrary
    subkey. */
-int
-card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
+gpg_error_t
+card_generate_subkey (KBNODE pub_keyblock)
 {
+  gpg_error_t err;
   struct agent_card_info_s info;
-  int okay = 0;
   int forced_chv1 = 0;
   int keyno;
 
-  if (get_info_for_key_operation (&info))
-    return 0;
+  err = get_info_for_key_operation (&info);
+  if (err)
+    return err;
 
   show_card_key_info (&info);
 
@@ -1451,6 +1480,7 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
       if (*answer == CONTROL_D)
         {
           xfree (answer);
+          err = gpg_error (GPG_ERR_CANCELED);
           goto leave;
         }
       keyno = *answer? atoi(answer): 0;
@@ -1460,10 +1490,14 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
       tty_printf(_("Invalid selection.\n"));
     }
 
-  if (replace_existing_key_p (&info, keyno))
-    goto leave;
+  if (replace_existing_key_p (&info, keyno) < 0)
+    {
+      err = gpg_error (GPG_ERR_CANCELED);
+      goto leave;
+    }
 
-  if (check_pin_for_key_operation (&info, &forced_chv1))
+  err = check_pin_for_key_operation (&info, &forced_chv1);
+  if (err)
     goto leave;
 
   /* If the cards features changeable key attributes, we ask for the
@@ -1478,7 +1512,8 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
         {
           /* Error: Better read the default key size again.  */
           agent_release_card_info (&info);
-          if (get_info_for_key_operation (&info))
+          err = get_info_for_key_operation (&info);
+          if (err)
             goto leave;
           goto ask_again;
         }
@@ -1486,13 +1521,12 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
          the serialnumber and thus it won't harm.  */
     }
 
-  okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
-                                   keyno, info.serialno);
+  err = generate_card_subkeypair (pub_keyblock, keyno, info.serialno);
 
  leave:
   agent_release_card_info (&info);
   restore_forced_chv1 (&forced_chv1);
-  return okay;
+  return err;
 }
 
 
@@ -1505,19 +1539,19 @@ card_store_subkey (KBNODE node, int use)
 {
   struct agent_card_info_s info;
   int okay = 0;
-  int rc;
-  int keyno, i;
-  PKT_secret_key *copied_sk = NULL;
-  PKT_secret_key *sk;
-  size_t n;
-  const char *s;
-  int allow_keyno[3];
   unsigned int nbits;
+  int allow_keyno[3];
+  int  keyno;
+  PKT_public_key *pk;
+  gpg_error_t err;
+  char *hexgrip;
+  int rc;
+  gnupg_isotime_t timebuf;
 
+  assert (node->pkt->pkttype == PKT_PUBLIC_KEY
+          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY);
 
-  assert (node->pkt->pkttype == PKT_SECRET_KEY
-          || node->pkt->pkttype == PKT_SECRET_SUBKEY);
-  sk = node->pkt->pkt.secret_key;
+  pk = node->pkt->pkt.public_key;
 
   if (get_info_for_key_operation (&info))
     return 0;
@@ -1529,11 +1563,9 @@ card_store_subkey (KBNODE node, int use)
       goto leave;
     }
 
-  show_card_key_info (&info);
+  nbits = nbits_from_pk (pk);
 
-  nbits = nbits_from_sk (sk);
-
-  if (!is_RSA (sk->pubkey_algo) || (!info.is_v2 && nbits != 1024) )
+  if (!info.is_v2 && nbits != 1024)
     {
       tty_printf ("You may only store a 1024 bit RSA key on the card\n");
       tty_printf ("\n");
@@ -1579,71 +1611,23 @@ card_store_subkey (KBNODE node, int use)
         tty_printf(_("Invalid selection.\n"));
     }
 
-  if (replace_existing_key_p (&info, keyno))
+  if ((rc = replace_existing_key_p (&info, keyno)) < 0)
     goto leave;
 
-  /* Unprotect key.  */
-  switch (is_secret_key_protected (sk) )
-    {
-    case 0: /* Not protected. */
-      break;
-    case -1:
-      log_error (_("unknown key protection algorithm\n"));
-      goto leave;
-    default:
-      if (sk->protect.s2k.mode == 1001)
-        {
-          log_error (_("secret parts of key are not available\n"));
-          goto leave;
-       }
-      if (sk->protect.s2k.mode == 1002)
-        {
-          log_error (_("secret key already stored on a card\n"));
-          goto leave;
-       }
-      /* We better copy the key before we unprotect it.  */
-      copied_sk = sk = copy_secret_key (NULL, sk);
-      rc = check_secret_key (sk, 0);
-      if (rc)
-        goto leave;
-    }
-
-  rc = save_unprotected_key_to_card (sk, keyno);
-  if (rc)
-    {
-      log_error (_("error writing key to card: %s\n"), gpg_strerror (rc));
-      goto leave;
-    }
-
-  /* Get back to the maybe protected original secret key.  */
-  if (copied_sk)
-    {
-      free_secret_key (copied_sk);
-      copied_sk = NULL;
-    }
-  sk = node->pkt->pkt.secret_key;
+  err = hexkeygrip_from_pk (pk, &hexgrip);
+  if (err)
+    goto leave;
 
-  /* Get rid of the secret key parameters and store the serial numer. */
-  n = pubkey_get_nskey (sk->pubkey_algo);
-  for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
-    {
-      gcry_mpi_release (sk->skey[i]);
-      sk->skey[i] = NULL;
-    }
-  i = pubkey_get_npkey (sk->pubkey_algo);
-  sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
-  sk->is_protected = 1;
-  sk->protect.s2k.mode = 1002;
-  s = info.serialno;
-  for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
-       sk->protect.ivlen++, s += 2)
-    sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
+  epoch2isotime (timebuf, (time_t)pk->timestamp);
+  agent_keytocard (hexgrip, keyno, rc, info.serialno, timebuf);
 
-  okay = 1;
+  if (rc)
+    log_error (_("KEYTOCARD failed: %s\n"), gpg_strerror (rc));
+  else
+    okay = 1;
+  xfree (hexgrip);
 
  leave:
-  if (copied_sk)
-    free_secret_key (copied_sk);
   agent_release_card_info (&info);
   return okay;
 }
@@ -1747,7 +1731,7 @@ card_edit_completion(const char *text, int start, int end)
 /* Menu to edit all user changeable values on an OpenPGP card.  Only
    Key creation is not handled here. */
 void
-card_edit (strlist_t commands)
+card_edit (ctrl_t ctrl, strlist_t commands)
 {
   enum cmdids cmd = cmdNOP;
   int have_commands = !!commands;
@@ -1779,7 +1763,7 @@ card_edit (strlist_t commands)
         {
           if (opt.with_colons)
             {
-              card_status (stdout, serialnobuf, DIM (serialnobuf));
+              card_status (es_stdout, serialnobuf, DIM (serialnobuf));
               fflush (stdout);
             }
           else
@@ -1906,7 +1890,7 @@ card_edit (strlist_t commands)
           break;
 
        case cmdFETCH:
-         fetch_url();
+         fetch_url (ctrl);
          break;
 
         case cmdLOGIN:
@@ -1956,7 +1940,7 @@ card_edit (strlist_t commands)
           break;
 
         case cmdGENERATE:
-          generate_card_keys ();
+          generate_card_keys (ctrl);
           break;
 
         case cmdPASSWD:
@@ -1984,4 +1968,3 @@ card_edit (strlist_t commands)
  leave:
   xfree (answer);
 }
-
index 10f0ebb..b72b144 100644 (file)
@@ -56,7 +56,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
     memset( &ed, 0, sizeof ed );
     ed.len = cfx->datalen;
     ed.extralen = blocksize+2;
-    ed.new_ctb = !ed.len && !RFC1991;
+    ed.new_ctb = !ed.len;
     if( cfx->dek->use_mdc ) {
        ed.mdc_method = DIGEST_ALGO_SHA1;
        gcry_md_open (&cfx->mdc_hash, DIGEST_ALGO_SHA1, 0);
index 7f9295e..085dbad 100644 (file)
@@ -106,5 +106,3 @@ make_mpi_comment_node( const char *s, gcry_mpi_t a )
     xfree (buf);
     return new_kbnode( pkt );
 }
-
-
index 1dabca1..ea80956 100644 (file)
@@ -156,7 +156,7 @@ do_uncompress( compress_filter_context_t *zfx, bz_stream *bzs,
        rc = -1; /* eof */
       else if( zrc != BZ_OK && zrc != BZ_PARAM_ERROR )
        log_fatal("bz2lib inflate problem: rc=%d\n", zrc );
-      else if (zrc == BZ_OK && eofseen 
+      else if (zrc == BZ_OK && eofseen
                && !bzs->avail_in && bzs->avail_out > 0)
         {
           log_error ("unexpected EOF in bz2lib\n");
index 6e151bc..0a6e09d 100644 (file)
@@ -1,6 +1,6 @@
 /* compress.c - compress filter
  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- *               2003, 2006 Free Software Foundation, Inc.
+ *               2003, 2006, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <unistd.h>
 #include <assert.h>
 #include <errno.h>
-#include <zlib.h>
-#if defined(__riscos__) && defined(USE_ZLIBRISCOS)
-# include "zlib-riscos.h"
-#endif 
+#ifdef HAVE_ZIP
+# include <zlib.h>
+# if defined(__riscos__) && defined(USE_ZLIBRISCOS)
+#  include "zlib-riscos.h"
+# endif
+#endif
 
 #include "gpg.h"
 #include "util.h"
@@ -46,7 +48,7 @@
 
 #ifdef __riscos__
 #define BYTEF_CAST(a) ((Bytef *)(a))
-#else 
+#else
 #define BYTEF_CAST(a) (a)
 #endif
 
@@ -55,6 +57,7 @@
 int compress_filter_bz2( void *opaque, int control,
                         IOBUF a, byte *buf, size_t *ret_len);
 
+#ifdef HAVE_ZIP
 static void
 init_compress( compress_filter_context_t *zfx, z_stream *zs )
 {
@@ -137,7 +140,7 @@ init_uncompress( compress_filter_context_t *zfx, z_stream *zs )
      * PGP uses a windowsize of 13 bits. Using a negative value for
      * it forces zlib not to expect a zlib header.  This is a
      * undocumented feature Peter Gutmann told me about.
-     *    
+     *
      * We must use 15 bits for the inflator because CryptoEx uses 15
      * bits thus the output would get scrambled w/o error indication
      * if we would use 13 bits.  For the uncompressing this does not
@@ -248,6 +251,9 @@ compress_filter( void *opaque, int control,
            memset( &cd, 0, sizeof cd );
            cd.len = 0;
            cd.algorithm = zfx->algo;
+            /* Fixme: We should force a new CTB here:
+               cd.new_ctb = zfx->new_ctb;
+            */
            init_packet( &pkt );
            pkt.pkttype = PKT_COMPRESSED;
            pkt.pkt.compressed = &cd;
@@ -285,7 +291,7 @@ compress_filter( void *opaque, int control,
        *(char**)buf = "compress_filter";
     return rc;
 }
-
+#endif /*HAVE_ZIP*/
 
 static void
 release_context (compress_filter_context_t *ctx)
@@ -297,7 +303,7 @@ release_context (compress_filter_context_t *ctx)
  * Handle a compressed packet
  */
 int
-handle_compressed( void *procctx, PKT_compressed *cd,
+handle_compressed (ctrl_t ctrl, void *procctx, PKT_compressed *cd,
                   int (*callback)(IOBUF, void *), void *passthru )
 {
     compress_filter_context_t *cfx;
@@ -312,7 +318,7 @@ handle_compressed( void *procctx, PKT_compressed *cd,
     if( callback )
        rc = callback(cd->buf, passthru );
     else
-       rc = proc_packets(procctx, cd->buf);
+      rc = proc_packets (ctrl,procctx, cd->buf);
     cd->buf = NULL;
     return rc;
 }
@@ -337,10 +343,12 @@ push_compress_filter2(IOBUF out,compress_filter_context_t *zfx,
     case COMPRESS_ALGO_NONE:
       break;
 
+#ifdef HAVE_ZIP
     case COMPRESS_ALGO_ZIP:
     case COMPRESS_ALGO_ZLIB:
       iobuf_push_filter2(out,compress_filter,zfx,rel);
       break;
+#endif
 
 #ifdef HAVE_BZIP2
     case COMPRESS_ALGO_BZIP2:
index 3142ac4..9fc9e09 100644 (file)
--- a/g10/cpr.c
+++ b/g10/cpr.c
@@ -1,6 +1,6 @@
 /* status.c - Status message and command-fd interface
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- *               2004, 2005, 2006 Free Software Foundation, Inc.
+ *               2004, 2005, 2006, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -24,7 +24,9 @@
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
-#include <signal.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 
 #include "gpg.h"
 #include "util.h"
 #include "options.h"
 #include "main.h"
 #include "i18n.h"
-#include "cipher.h" /* for progress functions */
 
 #define CONTROL_D ('D' - 'A' + 1)
 
 
-
-static FILE *statusfp;
+/* The stream to output the status information.  Output is disabled if
+   this is NULL.  */
+static estream_t statusfp;
 
 
 static void
@@ -92,40 +94,43 @@ status_currently_allowed (int no)
 
 
 void
-set_status_fd ( int fd )
+set_status_fd (int fd)
 {
-    static int last_fd = -1;
-
-    if ( fd != -1 && last_fd == fd )
-        return;
-
-    if ( statusfp && statusfp != stdout && statusfp != stderr )
-        fclose (statusfp);
-    statusfp = NULL;
-    if ( fd == -1 )
-        return;
-
-    if( fd == 1 )
-       statusfp = stdout;
-    else if( fd == 2 )
-       statusfp = stderr;
-    else
-       statusfp = fdopen( fd, "w" );
-    if( !statusfp ) {
-       log_fatal("can't open fd %d for status output: %s\n",
-                  fd, strerror(errno));
+  static int last_fd = -1;
+
+  if (fd != -1 && last_fd == fd)
+    return;
+
+  if (statusfp && statusfp != es_stdout && statusfp != es_stderr )
+    es_fclose (statusfp);
+  statusfp = NULL;
+  if (fd == -1)
+    return;
+
+  if (fd == 1)
+    statusfp = es_stdout;
+  else if (fd == 2)
+    statusfp = es_stderr;
+  else
+    statusfp = es_fdopen (fd, "w");
+  if (!statusfp)
+    {
+      log_fatal ("can't open fd %d for status output: %s\n",
+                 fd, strerror (errno));
     }
-    last_fd = fd;
+  last_fd = fd;
 
-    gcry_set_progress_handler ( progress_cb, NULL );
+  gcry_set_progress_handler (progress_cb, NULL);
 }
 
+
 int
-is_status_enabled()
+is_status_enabled ()
 {
-    return !!statusfp;
+  return !!statusfp;
 }
 
+
 void
 write_status ( int no )
 {
@@ -144,11 +149,11 @@ write_status_strings (int no, const char *text, ...)
   if (!statusfp || !status_currently_allowed (no) )
     return;  /* Not enabled or allowed. */
 
-  fputs ("[GNUPG:] ", statusfp);
-  fputs (get_status_string (no), statusfp);
+  es_fputs ("[GNUPG:] ", statusfp);
+  es_fputs (get_status_string (no), statusfp);
   if ( text )
     {
-      putc ( ' ', statusfp);
+      es_putc ( ' ', statusfp);
       va_start (arg_ptr, text);
       s = text;
       do
@@ -156,18 +161,18 @@ write_status_strings (int no, const char *text, ...)
           for (; *s; s++)
             {
               if (*s == '\n')
-                fputs ("\\n", statusfp);
+                es_fputs ("\\n", statusfp);
               else if (*s == '\r')
-                fputs ("\\r", statusfp);
+                es_fputs ("\\r", statusfp);
               else
-                fputc (*(const byte *)s, statusfp);
+                es_fputc (*(const byte *)s, statusfp);
             }
         }
       while ((s = va_arg (arg_ptr, const char*)));
       va_end (arg_ptr);
     }
-  putc ('\n', statusfp);
-  if (fflush (statusfp) && opt.exit_on_status_write_error)
+  es_putc ('\n', statusfp);
+  if (es_fflush (statusfp) && opt.exit_on_status_write_error)
     g10_exit (0);
 }
 
@@ -178,16 +183,30 @@ write_status_text (int no, const char *text)
   write_status_strings (no, text, NULL);
 }
 
+/* Wrte an ERROR status line using a full gpg-error error value.  */
+void
+write_status_error (const char *where, gpg_error_t err)
+{
+  if (!statusfp || !status_currently_allowed (STATUS_ERROR))
+    return;  /* Not enabled or allowed. */
+
+  es_fprintf (statusfp, "[GNUPG:] %s %s %u\n",
+              get_status_string (STATUS_ERROR), where, err);
+  if (es_fflush (statusfp) && opt.exit_on_status_write_error)
+    g10_exit (0);
+}
 
+
+/* Same as above but outputs the error code only.  */
 void
-write_status_error (const char *where, int errcode)
+write_status_errcode (const char *where, int errcode)
 {
   if (!statusfp || !status_currently_allowed (STATUS_ERROR))
     return;  /* Not enabled or allowed. */
 
-  fprintf (statusfp, "[GNUPG:] %s %s %u\n",
-           get_status_string (STATUS_ERROR), where, gpg_err_code (errcode));
-  if (fflush (statusfp) && opt.exit_on_status_write_error)
+  es_fprintf (statusfp, "[GNUPG:] %s %s %u\n",
+              get_status_string (STATUS_ERROR), where, gpg_err_code (errcode));
+  if (es_fflush (statusfp) && opt.exit_on_status_write_error)
     g10_exit (0);
 }
 
@@ -199,73 +218,83 @@ write_status_error (const char *where, int errcode)
  * A wrap of -1 forces spaces not to be encoded as %20.
  */
 void
-write_status_text_and_buffer ( int no, const char *string,
-                               const char *buffer, size_t len, int wrap )
+write_status_text_and_buffer (int no, const char *string,
+                              const char *buffer, size_t len, int wrap)
 {
-    const char *s, *text;
-    int esc, first;
-    int lower_limit = ' ';
-    size_t n, count, dowrap;
+  const char *s, *text;
+  int esc, first;
+  int lower_limit = ' ';
+  size_t n, count, dowrap;
 
-    if( !statusfp || !status_currently_allowed (no) )
-       return;  /* Not enabled or allowed. */
+  if (!statusfp || !status_currently_allowed (no))
+    return;  /* Not enabled or allowed. */
 
-    if (wrap == -1) {
-        lower_limit--;
-        wrap = 0;
+  if (wrap == -1)
+    {
+      lower_limit--;
+      wrap = 0;
     }
 
-    text = get_status_string (no);
-    count = dowrap = first = 1;
-    do {
-        if (dowrap) {
-            fprintf (statusfp, "[GNUPG:] %s ", text );
-            count = dowrap = 0;
-            if (first && string) {
-                fputs (string, statusfp);
-                count += strlen (string);
-                /* Make sure that there is space after the string.  */
-                if (*string && string[strlen (string)-1] != ' ')
-                  {
-                    putc (' ', statusfp);
-                    count++;
-                  }
+  text = get_status_string (no);
+  count = dowrap = first = 1;
+  do
+    {
+      if (dowrap)
+        {
+          es_fprintf (statusfp, "[GNUPG:] %s ", text);
+          count = dowrap = 0;
+          if (first && string)
+            {
+              es_fputs (string, statusfp);
+              count += strlen (string);
+              /* Make sure that there is a space after the string.  */
+              if (*string && string[strlen (string)-1] != ' ')
+                {
+                  es_putc (' ', statusfp);
+                  count++;
+                }
             }
-            first = 0;
+          first = 0;
         }
-        for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) {
-            if ( *s == '%' || *(const byte*)s <= lower_limit
-                           || *(const byte*)s == 127 )
-                esc = 1;
-            if ( wrap && ++count > wrap ) {
-                dowrap=1;
-                break;
+      for (esc=0, s=buffer, n=len; n && !esc; s++, n--)
+        {
+          if (*s == '%' || *(const byte*)s <= lower_limit
+              || *(const byte*)s == 127 )
+            esc = 1;
+          if (wrap && ++count > wrap)
+            {
+              dowrap=1;
+              break;
             }
         }
-        if (esc) {
-            s--; n++;
+      if (esc)
+        {
+          s--; n++;
         }
-        if (s != buffer)
-            fwrite (buffer, s-buffer, 1, statusfp );
-        if ( esc ) {
-            fprintf (statusfp, "%%%02X", *(const byte*)s );
-            s++; n--;
+      if (s != buffer)
+        es_fwrite (buffer, s-buffer, 1, statusfp);
+      if ( esc )
+        {
+          es_fprintf (statusfp, "%%%02X", *(const byte*)s );
+          s++; n--;
         }
-        buffer = s;
-        len = n;
-        if ( dowrap && len )
-            putc ( '\n', statusfp );
-    } while ( len );
-
-    putc ('\n',statusfp);
-    if ( fflush (statusfp) && opt.exit_on_status_write_error )
-      g10_exit (0);
+      buffer = s;
+      len = n;
+      if (dowrap && len)
+        es_putc ('\n', statusfp);
+    }
+  while (len);
+
+  es_putc ('\n',statusfp);
+  if (es_fflush (statusfp) && opt.exit_on_status_write_error)
+    g10_exit (0);
 }
 
+
 void
-write_status_buffer ( int no, const char *buffer, size_t len, int wrap )
+write_status_buffer (int no, const char *buffer, size_t len, int wrap)
 {
-    write_status_text_and_buffer (no, NULL, buffer, len, wrap);
+  write_status_text_and_buffer (no, NULL, buffer, len, wrap);
 }
 
 
@@ -278,68 +307,57 @@ write_status_begin_signing (gcry_md_hd_t md)
     {
       char buf[100];
       size_t buflen;
-      int i;
-
-      /* We use a hard coded list of possible algorithms.  Using other
-         algorithms than specified by OpenPGP does not make sense
-         anyway.  We do this out of performance reasons: Walking all
-         the 110 allowed Ids is not a good idea given the way the
-         check is implemented in libgcrypt.  Recall that the only use
-         of this status code is to create the micalg algorithm for
-         PGP/MIME. */
+      int i, ga;
+
       buflen = 0;
-      for (i=1; i <= 11; i++)
-        if (i < 4 || i > 7)
-          if ( gcry_md_is_enabled (md, i) && buflen < DIM(buf) )
+      for (i=1; i <= 110; i++)
+        {
+          ga = map_md_openpgp_to_gcry (i);
+          if (ga && gcry_md_is_enabled (md, ga) && buflen+10 < DIM(buf))
             {
               snprintf (buf+buflen, DIM(buf) - buflen - 1,
                         "%sH%d", buflen? " ":"",i);
               buflen += strlen (buf+buflen);
             }
-      write_status_text ( STATUS_BEGIN_SIGNING, buf );
+        }
+      write_status_text (STATUS_BEGIN_SIGNING, buf);
     }
   else
     write_status ( STATUS_BEGIN_SIGNING );
 }
 
 
-/* Write a FAILURE status line.  */
-void
-write_status_failure (const char *where, gpg_error_t err)
-{
-  if (!statusfp || !status_currently_allowed (STATUS_FAILURE))
-    return;  /* Not enabled or allowed. */
-
-  fprintf (statusfp, "[GNUPG:] %s %s %u\n",
-           get_status_string (STATUS_FAILURE), where, err);
-  if (fflush (statusfp) && opt.exit_on_status_write_error)
-    g10_exit (0);
-}
-
-
 static int
 myread(int fd, void *buf, size_t count)
 {
-    int rc;
-    do {
-        rc = read( fd, buf, count );
-    } while ( rc == -1 && errno == EINTR );
-    if ( !rc && count ) {
-        static int eof_emmited=0;
-        if ( eof_emmited < 3 ) {
-            *(char*)buf = CONTROL_D;
-            rc = 1;
-            eof_emmited++;
+  int rc;
+  do
+    {
+      rc = read( fd, buf, count );
+    }
+  while (rc == -1 && errno == EINTR);
+
+  if (!rc && count)
+    {
+      static int eof_emmited=0;
+      if ( eof_emmited < 3 )
+        {
+          *(char*)buf = CONTROL_D;
+          rc = 1;
+          eof_emmited++;
         }
-        else { /* Ctrl-D not caught - do something reasonable */
+      else /* Ctrl-D not caught - do something reasonable */
+        {
 #ifdef HAVE_DOSISH_SYSTEM
-            raise (SIGINT);  /* nothing to hangup under DOS */
+#ifndef HAVE_W32CE_SYSTEM
+          raise (SIGINT); /* Nothing to hangup under DOS.  */
+#endif
 #else
-            raise (SIGHUP); /* no more input data */
+          raise (SIGHUP); /* No more input data.  */
 #endif
         }
     }
-    return rc;
+  return rc;
 }
 
 
@@ -353,8 +371,8 @@ do_get_from_fd ( const char *keyword, int hidden, int getbool )
   int i, len;
   char *string;
 
-  if (statusfp != stdout)
-    fflush (stdout);
+  if (statusfp != es_stdout)
+    es_fflush (es_stdout);
 
   write_status_text (getbool? STATUS_GET_BOOL :
                      hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword);
@@ -475,7 +493,7 @@ cpr_kill_prompt(void)
 }
 
 int
-cpr_get_answer_is_yes( const char *keyword, const char *prompt )
+cpr_get_answer_is_yes_def (const char *keyword, const char *prompt, int def_yes)
 {
     int yes;
     char *p;
@@ -491,7 +509,7 @@ cpr_get_answer_is_yes( const char *keyword, const char *prompt )
        }
        else {
            tty_kill_prompt();
-           yes = answer_is_yes(p);
+           yes = answer_is_yes_no_default (p, def_yes);
            xfree(p);
            return yes;
        }
@@ -499,6 +517,12 @@ cpr_get_answer_is_yes( const char *keyword, const char *prompt )
 }
 
 int
+cpr_get_answer_is_yes (const char *keyword, const char *prompt)
+{
+  return cpr_get_answer_is_yes_def (keyword, prompt, 0);
+}
+
+int
 cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt )
 {
     int yes;
index da888ad..3fdd57d 100644 (file)
@@ -53,18 +53,18 @@ dearmor_file( const char *fname )
       {
         iobuf_close (inp);
         inp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if (!inp) {
         rc = gpg_error_from_syserror ();
-       log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]",
+       log_error(_("can't open '%s': %s\n"), fname? fname: "[stdin]",
                                        strerror(errno) );
        goto leave;
     }
 
     push_armor_filter ( afx, inp );
 
-    if( (rc = open_outfile( fname, 0, &out )) )
+    if( (rc = open_outfile (-1, fname, 0, 0, &out)) )
        goto leave;
 
     while( (c = iobuf_get(inp)) != -1 )
@@ -100,17 +100,17 @@ enarmor_file( const char *fname )
       {
         iobuf_close (inp);
         inp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if (!inp) {
         rc = gpg_error_from_syserror ();
-       log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]",
+       log_error(_("can't open '%s': %s\n"), fname? fname: "[stdin]",
                   strerror(errno) );
        goto leave;
     }
 
 
-    if( (rc = open_outfile( fname, 1, &out )) )
+    if( (rc = open_outfile (-1, fname, 1, 0, &out )) )
        goto leave;
 
     afx->what = 4;
@@ -130,5 +130,3 @@ enarmor_file( const char *fname )
     release_armor_context (afx);
     return rc;
 }
-
-
similarity index 72%
rename from g10/encr-data.c
rename to g10/decrypt-data.c
index c5c3c19..9c6ae73 100644 (file)
@@ -1,6 +1,6 @@
-/* encr-data.c -  process an encrypted data packet
+/* decrypt-data.c - Decrypt an encrypted data packet
  * Copyright (C) 1998, 1999, 2000, 2001, 2005,
- *               2006, 2009, 2012 Free Software Foundation, Inc.
+ *               2006, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -27,7 +27,6 @@
 #include "gpg.h"
 #include "util.h"
 #include "packet.h"
-#include "cipher.h"
 #include "options.h"
 #include "i18n.h"
 #include "status.h"
@@ -46,6 +45,8 @@ typedef struct decode_filter_context_s
   int  defer_filled;
   int  eof_seen;
   int  refcount;
+  int  partial;   /* Working on a partial length packet.  */
+  size_t length;  /* If !partial: Remaining bytes in the packet.  */
 } *decode_filter_ctx_t;
 
 
@@ -73,7 +74,7 @@ release_dfx_context (decode_filter_ctx_t dfx)
  * Decrypt the data, specified by ED with the key DEK.
  */
 int
-decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
+decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
 {
   decode_filter_ctx_t dfx;
   byte *p;
@@ -208,14 +209,16 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
     gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
 
   dfx->refcount++;
+  dfx->partial = ed->is_partial;
+  dfx->length = ed->len;
   if ( ed->mdc_method )
     iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
   else
     iobuf_push_filter ( ed->buf, decode_filter, dfx );
 
-  proc_packets ( procctx, ed->buf );
+  proc_packets (ctrl, procctx, ed->buf );
   ed->buf = NULL;
-  if ( ed->mdc_method && dfx->eof_seen == 2 )
+  if (dfx->eof_seen > 1 )
     rc = gpg_error (GPG_ERR_INV_PACKET);
   else if ( ed->mdc_method )
     {
@@ -257,7 +260,6 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
 
 
 
-/* I think we should merge this with cipher_filter */
 static int
 mdc_decode_filter (void *opaque, int control, IOBUF a,
                    byte *buf, size_t *ret_len)
@@ -267,6 +269,14 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
   int rc = 0;
   int c;
 
+  /* Note: We need to distinguish between a partial and a fixed length
+     packet.  The first is the usual case as created by GPG.  However
+     for short messages the format degrades to a fixed length packet
+     and other implementations might use fixed length as well.  Only
+     looking for the EOF on fixed data works only if the encrypted
+     packet is not followed by other data.  This used to be a long
+     standing bug which was fixed on 2009-10-02.  */
+
   if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
     {
       *ret_len = 0;
@@ -275,37 +285,71 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
   else if( control == IOBUFCTRL_UNDERFLOW )
     {
       assert (a);
-      assert ( size > 44 );
+      assert (size > 44); /* Our code requires at least this size.  */
 
-      /* Get at least 22 bytes and put it somewhere ahead in the buffer. */
-      for (n=22; n < 44 ; n++ )
+      /* Get at least 22 bytes and put it ahead in the buffer.  */
+      if (dfx->partial)
         {
-          if( (c = iobuf_get(a)) == -1 )
-            break;
-          buf[n] = c;
-       }
-      if ( n == 44 )
+          for (n=22; n < 44; n++)
+            {
+              if ( (c = iobuf_get(a)) == -1 )
+                break;
+              buf[n] = c;
+            }
+        }
+      else
+        {
+          for (n=22; n < 44 && dfx->length; n++, dfx->length--)
+            {
+              c = iobuf_get (a);
+              if (c == -1)
+                break; /* Premature EOF.  */
+              buf[n] = c;
+            }
+        }
+      if (n == 44)
         {
           /* We have enough stuff - flush the deferred stuff.  */
-          /* (we asserted that the buffer is large enough) */
           if ( !dfx->defer_filled )  /* First time. */
             {
-              memcpy (buf, buf+22, 22 );
+              memcpy (buf, buf+22, 22);
               n = 22;
            }
           else
             {
-              memcpy (buf, dfx->defer, 22 );
+              memcpy (buf, dfx->defer, 22);
            }
-          /* Now fill up. */
-          for (; n < size; n++ )
+          /* Fill up the buffer. */
+          if (dfx->partial)
             {
-              if ( (c = iobuf_get(a)) == -1 )
-                break;
-              buf[n] = c;
-           }
-          /* Move the last 22 bytes back to the defer buffer. */
-         /* (right, we are wasting 22 bytes of the supplied buffer.) */
+              for (; n < size; n++ )
+                {
+                  if ( (c = iobuf_get(a)) == -1 )
+                    {
+                      dfx->eof_seen = 1; /* Normal EOF. */
+                      break;
+                    }
+                  buf[n] = c;
+                }
+            }
+          else
+            {
+              for (; n < size && dfx->length; n++, dfx->length--)
+                {
+                  c = iobuf_get(a);
+                  if (c == -1)
+                    {
+                      dfx->eof_seen = 3; /* Premature EOF. */
+                      break;
+                    }
+                  buf[n] = c;
+                }
+              if (!dfx->length)
+                dfx->eof_seen = 1; /* Normal EOF.  */
+            }
+
+          /* Move the trailing 22 bytes back to the defer buffer.  We
+             have at least 44 bytes thus a memmove is not needed.  */
           n -= 22;
           memcpy (dfx->defer, buf+n, 22 );
           dfx->defer_filled = 1;
@@ -335,7 +379,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a,
       else
         {
           assert ( dfx->eof_seen );
-          rc = -1; /* eof */
+          rc = -1; /* Return EOF.  */
        }
       *ret_len = n;
     }
@@ -355,22 +399,59 @@ static int
 decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
 {
   decode_filter_ctx_t fc = opaque;
-  size_t n, size = *ret_len;
-  int rc = 0;
+  size_t size = *ret_len;
+  size_t n;
+  int c, rc = 0;
+
 
-  if ( control == IOBUFCTRL_UNDERFLOW )
+  if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen )
+    {
+      *ret_len = 0;
+      rc = -1;
+    }
+  else if ( control == IOBUFCTRL_UNDERFLOW )
     {
       assert(a);
-      n = iobuf_read ( a, buf, size );
-      if ( n == -1 )
-        n = 0;
-      if ( n )
+
+      if (fc->partial)
+        {
+          for (n=0; n < size; n++ )
+            {
+              c = iobuf_get(a);
+              if (c == -1)
+                {
+                  fc->eof_seen = 1; /* Normal EOF. */
+                  break;
+                }
+              buf[n] = c;
+            }
+        }
+      else
+        {
+          for (n=0; n < size && fc->length; n++, fc->length--)
+            {
+              c = iobuf_get(a);
+              if (c == -1)
+                {
+                  fc->eof_seen = 3; /* Premature EOF. */
+                  break;
+                }
+              buf[n] = c;
+            }
+          if (!fc->length)
+            fc->eof_seen = 1; /* Normal EOF.  */
+        }
+      if (n)
         {
           if (fc->cipher_hd)
             gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
         }
       else
-        rc = -1; /* EOF */
+        {
+          if (!fc->eof_seen)
+            fc->eof_seen = 1;
+          rc = -1; /* Return EOF. */
+        }
       *ret_len = n;
     }
   else if ( control == IOBUFCTRL_FREE )
@@ -383,4 +464,3 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
     }
   return rc;
 }
-
index ce400b0..b0240f5 100644 (file)
@@ -1,6 +1,6 @@
-/* decrypt.c - verify signed data
+/* decrypt.c - decrypt and verify data
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ *               2007, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include "status.h"
 #include "i18n.h"
 
-
-
-/****************
- * Assume that the input is an encrypted message and decrypt
+/* Assume that the input is an encrypted message and decrypt
  * (and if signed, verify the signature on) it.
  * This command differs from the default operation, as it never
  * writes to the filename which is included in the file and it
  * rejects files which don't begin with an encrypted message.
  */
-
 int
-decrypt_message( const char *filename )
+decrypt_message (ctrl_t ctrl, const char *filename)
 {
-    IOBUF fp;
-    armor_filter_context_t *afx = NULL;
-    progress_filter_context_t *pfx;
-    int rc;
-    int no_out = 0;
-
-    pfx = new_progress_context ();
-
-    /* Open the message file.  */
-    fp = iobuf_open(filename);
-    if (fp && is_secured_file (iobuf_get_fd (fp)))
-      {
-        iobuf_close (fp);
-        fp = NULL;
-        errno = EPERM;
-      }
-    if( !fp ) {
-        rc = gpg_error_from_syserror ();
-       log_error (_("can't open `%s': %s\n"), print_fname_stdin(filename),
-                   gpg_strerror (rc));
-        release_progress_context (pfx);
-       return rc;
+  IOBUF fp;
+  armor_filter_context_t *afx = NULL;
+  progress_filter_context_t *pfx;
+  int rc;
+  int no_out = 0;
+
+  pfx = new_progress_context ();
+
+  /* Open the message file.  */
+  fp = iobuf_open (filename);
+  if (fp && is_secured_file (iobuf_get_fd (fp)))
+    {
+      iobuf_close (fp);
+      fp = NULL;
+      gpg_err_set_errno (EPERM);
+    }
+  if ( !fp )
+    {
+      rc = gpg_error_from_syserror ();
+      log_error (_("can't open '%s': %s\n"), print_fname_stdin(filename),
+                 gpg_strerror (rc));
+      release_progress_context (pfx);
+      return rc;
     }
 
-    handle_progress (pfx, fp, filename);
+  handle_progress (pfx, fp, filename);
 
-    if( !opt.no_armor ) {
-       if( use_armor_filter( fp ) ) {
-            afx = new_armor_context ();
-           push_armor_filter ( afx, fp );
+  if ( !opt.no_armor )
+    {
+      if ( use_armor_filter( fp ) )
+        {
+          afx = new_armor_context ();
+          push_armor_filter ( afx, fp );
        }
     }
 
-    if( !opt.outfile ) {
-       no_out = 1;
-       opt.outfile = "-";
+  if (!opt.outfile)
+    {
+      no_out = 1;
+      opt.outfile = "-";
     }
-    rc = proc_encryption_packets( NULL, fp );
-    if( no_out )
-       opt.outfile = NULL;
-    iobuf_close(fp);
-    release_armor_context (afx);
-    release_progress_context (pfx);
-    return rc;
+  rc = proc_encryption_packets (ctrl, NULL, fp );
+  if (no_out)
+    opt.outfile = NULL;
+
+  iobuf_close (fp);
+  release_armor_context (afx);
+  release_progress_context (pfx);
+  return rc;
 }
 
+
+/* Same as decrypt_message but takes a file descriptor for input and
+   output.  */
+gpg_error_t
+decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd)
+{
+#ifdef HAVE_W32_SYSTEM
+  /* No server mode yet.  */
+  (void)ctrl;
+  (void)input_fd;
+  (void)output_fd;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#else
+  gpg_error_t err;
+  IOBUF fp;
+  armor_filter_context_t *afx = NULL;
+  progress_filter_context_t *pfx;
+
+  if (opt.outfp)
+    return gpg_error (GPG_ERR_BUG);
+
+  pfx = new_progress_context ();
+
+  /* Open the message file.  */
+  fp = iobuf_open_fd_or_name (input_fd, NULL, "rb");
+  if (fp && is_secured_file (iobuf_get_fd (fp)))
+    {
+      iobuf_close (fp);
+      fp = NULL;
+      gpg_err_set_errno (EPERM);
+    }
+  if (!fp)
+    {
+      char xname[64];
+
+      err = gpg_error_from_syserror ();
+      snprintf (xname, sizeof xname, "[fd %d]", input_fd);
+      log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err));
+      release_progress_context (pfx);
+      return err;
+    }
+
+#ifdef HAVE_W32CE_SYSTEM
+#warning Need to fix this if we want to use g13
+  opt.outfp = NULL;
+#else
+  opt.outfp = es_fdopen_nc (output_fd, "wb");
+#endif
+  if (!opt.outfp)
+    {
+      char xname[64];
+
+      err = gpg_error_from_syserror ();
+      snprintf (xname, sizeof xname, "[fd %d]", output_fd);
+      log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err));
+      iobuf_close (fp);
+      release_progress_context (pfx);
+      return err;
+    }
+
+  if (!opt.no_armor)
+    {
+      if (use_armor_filter (fp))
+        {
+          afx = new_armor_context ();
+          push_armor_filter ( afx, fp );
+       }
+    }
+
+  err = proc_encryption_packets (ctrl, NULL, fp );
+
+  iobuf_close (fp);
+  es_fclose (opt.outfp);
+  opt.outfp = NULL;
+  release_armor_context (afx);
+  release_progress_context (pfx);
+  return err;
+#endif
+}
+
+
 void
-decrypt_messages(int nfiles, char *files[])
+decrypt_messages (ctrl_t ctrl, int nfiles, char *files[])
 {
   IOBUF fp;
-  armor_filter_context_t *afx = NULL;  
+  armor_filter_context_t *afx = NULL;
   progress_filter_context_t *pfx;
   char *p, *output = NULL;
   int rc=0,use_stdin=0;
   unsigned int lno=0;
-  
+
   if (opt.outfile)
     {
       log_error(_("--output doesn't work for this command\n"));
@@ -148,22 +230,22 @@ decrypt_messages(int nfiles, char *files[])
       if(filename==NULL)
        break;
 
-      print_file_status(STATUS_FILE_START, filename, 3);      
+      print_file_status(STATUS_FILE_START, filename, 3);
       output = make_outfile_name(filename);
       if (!output)
         goto next_file;
       fp = iobuf_open(filename);
       if (fp)
-        iobuf_ioctl (fp,3,1,NULL); /* disable fd caching */
+        iobuf_ioctl (fp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
       if (fp && is_secured_file (iobuf_get_fd (fp)))
         {
           iobuf_close (fp);
           fp = NULL;
-          errno = EPERM;
+          gpg_err_set_errno (EPERM);
         }
       if (!fp)
         {
-          log_error(_("can't open `%s'\n"), print_fname_stdin(filename));
+          log_error(_("can't open '%s'\n"), print_fname_stdin(filename));
           goto next_file;
         }
 
@@ -177,7 +259,7 @@ decrypt_messages(int nfiles, char *files[])
               push_armor_filter ( afx, fp );
             }
         }
-      rc = proc_packets(NULL, fp);
+      rc = proc_packets (ctrl,NULL, fp);
       iobuf_close(fp);
       if (rc)
         log_error("%s: decryption failed: %s\n", print_fname_stdin(filename),
@@ -193,7 +275,7 @@ decrypt_messages(int nfiles, char *files[])
       reset_literals_seen();
     }
 
-  set_next_passphrase(NULL);  
+  set_next_passphrase(NULL);
   release_armor_context (afx);
   release_progress_context (pfx);
 }
diff --git a/g10/dek.h b/g10/dek.h
new file mode 100644 (file)
index 0000000..31ebbb6
--- /dev/null
+++ b/g10/dek.h
@@ -0,0 +1,35 @@
+/* dek.h - The data encryption key structure.
+ * Copyright (C) 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef G10_DEK_H
+#define G10_DEK_H
+
+
+typedef struct
+{
+  int algo;
+  int keylen;
+  int algo_info_printed;
+  int use_mdc;
+  int symmetric;
+  byte key[32]; /* This is the largest used keylen (256 bit). */
+  char s2k_cacheid[1+16+1];
+} DEK;
+
+
+#endif /*G10_DEK_H*/
index fe29d52..063de78 100644 (file)
@@ -1,6 +1,7 @@
 /* delkey.c - delete keys
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004,
  *               2005, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -39,6 +40,7 @@
 #include "ttyio.h"
 #include "status.h"
 #include "i18n.h"
+#include "call-agent.h"
 
 
 /****************
  * r_sec_avail will be set if a secret key is available and the public
  * key can't be deleted for that reason.
  */
-static int
+static gpg_error_t
 do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
 {
-    int rc = 0;
-    KBNODE keyblock = NULL;
-    KBNODE node;
-    KEYDB_HANDLE hd = keydb_new (secret);
-    PKT_public_key *pk = NULL;
-    PKT_secret_key *sk = NULL;
-    u32 keyid[2];
-    int okay=0;
-    int yes;
-    KEYDB_SEARCH_DESC desc;
-    int exactmatch;
-
-    *r_sec_avail = 0;
-
-    /* search the userid */
-    classify_user_id (username, &desc);
-    exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
-                  || desc.mode == KEYDB_SEARCH_MODE_FPR16
-                  || desc.mode == KEYDB_SEARCH_MODE_FPR20);
-    rc = desc.mode? keydb_search (hd, &desc, 1):G10ERR_INV_USER_ID;
-    if (rc) {
-       log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
-       write_status_text( STATUS_DELETE_PROBLEM, "1" );
-       goto leave;
+  gpg_error_t err;
+  kbnode_t keyblock = NULL;
+  kbnode_t node, kbctx;
+  KEYDB_HANDLE hd;
+  PKT_public_key *pk = NULL;
+  u32 keyid[2];
+  int okay=0;
+  int yes;
+  KEYDB_SEARCH_DESC desc;
+  int exactmatch;
+
+  *r_sec_avail = 0;
+
+  hd = keydb_new ();
+
+  /* Search the userid.  */
+  err = classify_user_id (username, &desc, 1);
+  exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
+                || desc.mode == KEYDB_SEARCH_MODE_FPR16
+                || desc.mode == KEYDB_SEARCH_MODE_FPR20);
+  if (!err)
+    err = keydb_search (hd, &desc, 1, NULL);
+  if (err)
+    {
+      log_error (_("key \"%s\" not found: %s\n"), username, gpg_strerror (err));
+      write_status_text (STATUS_DELETE_PROBLEM, "1");
+      goto leave;
     }
 
-    /* read the keyblock */
-    rc = keydb_get_keyblock (hd, &keyblock );
-    if (rc) {
-       log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
-       goto leave;
+  /* Read the keyblock.  */
+  err = keydb_get_keyblock (hd, &keyblock);
+  if (err)
+    {
+      log_error (_("error reading keyblock: %s\n"), gpg_strerror (err) );
+      goto leave;
     }
 
-    /* get the keyid from the keyblock */
-    node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY );
-    if( !node ) {
-       log_error("Oops; key not found anymore!\n");
-       rc = G10ERR_GENERAL;
-       goto leave;
+  /* Get the keyid from the keyblock.  */
+  node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
+  if (!node)
+    {
+      log_error ("Oops; key not found anymore!\n");
+      err = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
     }
+  pk = node->pkt->pkt.public_key;
+  keyid_from_pk (pk, keyid);
 
-    if( secret )
-      {
-       sk = node->pkt->pkt.secret_key;
-       keyid_from_sk( sk, keyid );
-      }
-    else
-      {
-       /* public */
-       pk = node->pkt->pkt.public_key;
-       keyid_from_pk( pk, keyid );
-
-       if(!force)
-         {
-           rc = seckey_available( keyid );
-           if( !rc )
-             {
-               *r_sec_avail = 1;
-               rc = -1;
-               goto leave;
-             }
-           else if( rc != G10ERR_NO_SECKEY )
-             log_error("%s: get secret key: %s\n", username, g10_errstr(rc) );
-           else
-             rc = 0;
-         }
-      }
-
-    if( rc )
-       rc = 0;
-    else if (opt.batch && exactmatch)
-        okay++;
-    else if( opt.batch && secret )
-      {
-       log_error(_("can't do this in batch mode\n"));
-        log_info (_("(unless you specify the key by fingerprint)\n"));
-      }
-    else if( opt.batch && opt.answer_yes )
-       okay++;
-    else if( opt.batch )
-      {
-       log_error(_("can't do this in batch mode without \"--yes\"\n"));
-        log_info (_("(unless you specify the key by fingerprint)\n"));
-      }
-    else {
-        if( secret )
-            print_seckey_info( sk );
-        else
-            print_pubkey_info(NULL, pk );
-       tty_printf( "\n" );
-
-       yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"
-                                          : "delete_key.okay",
-                             _("Delete this key from the keyring? (y/N) "));
-       if( !cpr_enabled() && secret && yes ) {
-           /* I think it is not required to check a passphrase; if
-            * the user is so stupid as to let others access his secret keyring
-            * (and has no backup) - it is up him to read some very
-            * basic texts about security.
-            */
-           yes = cpr_get_answer_is_yes("delete_key.secret.okay",
-                        _("This is a secret key! - really delete? (y/N) "));
+  if (!secret && !force)
+    {
+      if (have_secret_key_with_kid (keyid))
+        {
+          *r_sec_avail = 1;
+          err = gpg_error (GPG_ERR_EOF);
+          goto leave;
+        }
+      else
+        err = 0;
+    }
+
+  if (secret && !have_secret_key_with_kid (keyid))
+    {
+      err = gpg_error (GPG_ERR_NOT_FOUND);
+      log_error (_("key \"%s\" not found: %s\n"), username, gpg_strerror (err));
+      write_status_text (STATUS_DELETE_PROBLEM, "1");
+      goto leave;
+    }
+
+
+  if (opt.batch && exactmatch)
+    okay++;
+  else if (opt.batch && secret)
+    {
+      log_error(_("can't do this in batch mode\n"));
+      log_info (_("(unless you specify the key by fingerprint)\n"));
+    }
+  else if (opt.batch && opt.answer_yes)
+    okay++;
+  else if (opt.batch)
+    {
+      log_error(_("can't do this in batch mode without \"--yes\"\n"));
+      log_info (_("(unless you specify the key by fingerprint)\n"));
+    }
+  else
+    {
+      if (secret)
+        print_seckey_info (pk);
+      else
+        print_pubkey_info (NULL, pk );
+      tty_printf( "\n" );
+
+      yes = cpr_get_answer_is_yes
+        (secret? "delete_key.secret.okay": "delete_key.okay",
+         _("Delete this key from the keyring? (y/N) "));
+
+      if (!cpr_enabled() && secret && yes)
+        {
+          /* I think it is not required to check a passphrase; if the
+           * user is so stupid as to let others access his secret
+           * keyring (and has no backup) - it is up him to read some
+           * very basic texts about security.  */
+          yes = cpr_get_answer_is_yes
+            ("delete_key.secret.okay",
+             _("This is a secret key! - really delete? (y/N) "));
        }
-       if( yes )
-           okay++;
+
+      if (yes)
+        okay++;
     }
 
 
-    if( okay ) {
-       rc = keydb_delete_keyblock (hd);
-       if (rc) {
-           log_error (_("deleting keyblock failed: %s\n"), g10_errstr(rc) );
-           goto leave;
+  if (okay)
+    {
+      if (secret)
+       {
+          char *prompt;
+          gpg_error_t firsterr = 0;
+          char *hexgrip;
+
+          setup_main_keyids (keyblock);
+          for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
+            {
+              if (!(node->pkt->pkttype == PKT_PUBLIC_KEY
+                    || node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
+                continue;
+
+              if (agent_probe_secret_key (NULL, node->pkt->pkt.public_key))
+                continue;  /* No secret key for that public (sub)key.  */
+
+              prompt = gpg_format_keydesc (node->pkt->pkt.public_key,
+                                           FORMAT_KEYDESC_DELKEY, 1);
+              err = hexkeygrip_from_pk (node->pkt->pkt.public_key, &hexgrip);
+              if (!err)
+                err = agent_delete_key (NULL, hexgrip, prompt);
+              xfree (prompt);
+              xfree (hexgrip);
+              if (err)
+                {
+                  if (gpg_err_code (err) == GPG_ERR_KEY_ON_CARD)
+                    write_status_text (STATUS_DELETE_PROBLEM, "1");
+                  log_error (_("deleting secret %s failed: %s\n"),
+                             (node->pkt->pkttype == PKT_PUBLIC_KEY
+                              ? _("key"):_("subkey")),
+                             gpg_strerror (err));
+                  if (!firsterr)
+                    firsterr = err;
+                  if (gpg_err_code (err) == GPG_ERR_CANCELED
+                      || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+                    break;
+                }
+
+            }
+
+          err = firsterr;
+          if (firsterr)
+            goto leave;
+       }
+      else
+       {
+         err = keydb_delete_keyblock (hd);
+         if (err)
+            {
+              log_error (_("deleting keyblock failed: %s\n"),
+                         gpg_strerror (err));
+              goto leave;
+            }
        }
 
-       /* Note that the ownertrust being cleared will trigger a
-           revalidation_mark().  This makes sense - only deleting keys
-           that have ownertrust set should trigger this. */
+      /* Note that the ownertrust being cleared will trigger a
+        revalidation_mark().  This makes sense - only deleting keys
+        that have ownertrust set should trigger this. */
 
-        if (!secret && pk && clear_ownertrusts (pk)) {
+      if (!secret && pk && clear_ownertrusts (pk))
+        {
           if (opt.verbose)
             log_info (_("ownertrust information cleared\n"));
         }
     }
 
 leave:
-    keydb_release (hd);
-    release_kbnode (keyblock);
-    return rc;
+ leave:
+  keydb_release (hd);
+  release_kbnode (keyblock);
+  return err;
 }
 
 /****************
  * Delete a public or secret key from a keyring.
  */
-int
-delete_keys( strlist_t names, int secret, int allow_both )
+gpg_error_t
+delete_keys (strlist_t names, int secret, int allow_both)
 {
-    int rc, avail, force=(!allow_both && !secret && opt.expert);
-
-    /* Force allows us to delete a public key even if a secret key
-       exists. */
-
-    for(;names;names=names->next) {
-       rc = do_delete_key (names->d, secret, force, &avail );
-       if ( rc && avail ) { 
-        if ( allow_both ) {
-          rc = do_delete_key (names->d, 1, 0, &avail );
-          if ( !rc )
-            rc = do_delete_key (names->d, 0, 0, &avail );
-        }
-        else {
-          log_error(_(
-             "there is a secret key for public key \"%s\"!\n"),names->d);
-          log_info(_(
-             "use option \"--delete-secret-keys\" to delete it first.\n"));
-          write_status_text( STATUS_DELETE_PROBLEM, "2" );
-          return rc;
-        }
-       }
-
-       if(rc) {
-        log_error("%s: delete key failed: %s\n", names->d, g10_errstr(rc) );
-        return rc;
-       }
+  gpg_error_t err;
+  int avail;
+  int force = (!allow_both && !secret && opt.expert);
+
+  /* Force allows us to delete a public key even if a secret key
+     exists. */
+
+  for ( ;names ; names=names->next )
+    {
+      err = do_delete_key (names->d, secret, force, &avail);
+      if (err && avail)
+        {
+          if (allow_both)
+            {
+              err = do_delete_key (names->d, 1, 0, &avail);
+              if (!err)
+                err = do_delete_key (names->d, 0, 0, &avail);
+            }
+          else
+            {
+              log_error (_("there is a secret key for public key \"%s\"!\n"),
+                         names->d);
+              log_info(_("use option \"--delete-secret-keys\" to delete"
+                         " it first.\n"));
+              write_status_text (STATUS_DELETE_PROBLEM, "2");
+              return err;
+            }
+        }
+
+      if (err)
+        {
+          log_error ("%s: delete key failed: %s\n",
+                     names->d, gpg_strerror (err));
+          return err;
+        }
     }
 
-    return 0;
+  return 0;
 }
diff --git a/g10/distsigkey.gpg b/g10/distsigkey.gpg
new file mode 100644 (file)
index 0000000..8ad154a
Binary files /dev/null and b/g10/distsigkey.gpg differ
diff --git a/g10/ecdh.c b/g10/ecdh.c
new file mode 100644 (file)
index 0000000..0b06239
--- /dev/null
@@ -0,0 +1,475 @@
+/* ecdh.c - ECDH public key operations used in public key glue code
+ *     Copyright (C) 2010, 2011 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "gpg.h"
+#include "util.h"
+#include "pkglue.h"
+#include "main.h"
+#include "options.h"
+
+/* A table with the default KEK parameters used by GnuPG.  */
+static const struct
+{
+  unsigned int qbits;
+  int openpgp_hash_id;   /* KEK digest algorithm. */
+  int openpgp_cipher_id; /* KEK cipher algorithm. */
+} kek_params_table[] =
+  /* Note: Must be sorted by ascending values for QBITS.  */
+  {
+    { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES    },
+    { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 },
+
+    /* Note: 528 is 521 rounded to the 8 bit boundary */
+    { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 }
+  };
+
+
+
+/* Return KEK parameters as an opaque MPI The caller must free the
+   returned value.  Returns NULL and sets ERRNO on error.  */
+gcry_mpi_t
+pk_ecdh_default_params (unsigned int qbits)
+{
+  byte *kek_params;
+  int i;
+
+  kek_params = xtrymalloc (4);
+  if (!kek_params)
+    return NULL;
+  kek_params[0] = 3; /* Number of bytes to follow. */
+  kek_params[1] = 1; /* Version for KDF+AESWRAP.   */
+
+  /* Search for matching KEK parameter.  Defaults to the strongest
+     possible choices.  Performance is not an issue here, only
+     interoperability.  */
+  for (i=0; i < DIM (kek_params_table); i++)
+    {
+      if (kek_params_table[i].qbits >= qbits
+          || i+1 == DIM (kek_params_table))
+        {
+          kek_params[2] = kek_params_table[i].openpgp_hash_id;
+          kek_params[3] = kek_params_table[i].openpgp_cipher_id;
+          break;
+        }
+    }
+  assert (i < DIM (kek_params_table));
+  if (DBG_CIPHER)
+    log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) );
+
+  return gcry_mpi_set_opaque (NULL, kek_params, 4 * 8);
+}
+
+
+/* Encrypts/decrypts DATA using a key derived from the ECC shared
+   point SHARED_MPI using the FIPS SP 800-56A compliant method
+   key_derivation+key_wrapping.  If IS_ENCRYPT is true the function
+   encrypts; if false, it decrypts.  PKEY is the public key and PK_FP
+   the fingerprint of this public key.  On success the result is
+   stored at R_RESULT; on failure NULL is stored at R_RESULT and an
+   error code returned.  */
+gpg_error_t
+pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
+                                   const byte pk_fp[MAX_FINGERPRINT_LEN],
+                                   gcry_mpi_t data, gcry_mpi_t *pkey,
+                                   gcry_mpi_t *r_result)
+{
+  gpg_error_t err;
+  byte *secret_x;
+  int secret_x_size;
+  unsigned int nbits;
+  const unsigned char *kek_params;
+  size_t kek_params_size;
+  int kdf_hash_algo;
+  int kdf_encr_algo;
+  unsigned char message[256];
+  size_t message_size;
+
+  *r_result = NULL;
+
+  nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey);
+  if (!nbits)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+
+  {
+    size_t nbytes;
+
+    /* Extract x component of the shared point: this is the actual
+       shared secret. */
+    nbytes = (mpi_get_nbits (pkey[1] /* public point */)+7)/8;
+    secret_x = xtrymalloc_secure (nbytes);
+    if (!secret_x)
+      return gpg_error_from_syserror ();
+
+    err = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes,
+                          &nbytes, shared_mpi);
+    if (err)
+      {
+        xfree (secret_x);
+        log_error ("ECDH ephemeral export of shared point failed: %s\n",
+                   gpg_strerror (err));
+        return err;
+      }
+
+    secret_x_size = (nbits+7)/8;
+    assert (nbytes > secret_x_size);
+    memmove (secret_x, secret_x+1, secret_x_size);
+    memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
+
+    if (DBG_CIPHER)
+      log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size );
+  }
+
+  /*** We have now the shared secret bytes in secret_x. ***/
+
+  /* At this point we are done with PK encryption and the rest of the
+   * function uses symmetric key encryption techniques to protect the
+   * input DATA.  The following two sections will simply replace
+   * current secret_x with a value derived from it.  This will become
+   * a KEK.
+   */
+  if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE))
+    {
+      xfree (secret_x);
+      return gpg_error (GPG_ERR_BUG);
+    }
+  kek_params = gcry_mpi_get_opaque (pkey[2], &nbits);
+  kek_params_size = (nbits+7)/8;
+
+  if (DBG_CIPHER)
+    log_printhex ("ecdh KDF params:", kek_params, kek_params_size);
+
+  /* Expect 4 bytes  03 01 hash_alg symm_alg.  */
+  if (kek_params_size != 4 || kek_params[0] != 3 || kek_params[1] != 1)
+    {
+      xfree (secret_x);
+      return gpg_error (GPG_ERR_BAD_PUBKEY);
+    }
+
+  kdf_hash_algo = kek_params[2];
+  kdf_encr_algo = kek_params[3];
+
+  if (DBG_CIPHER)
+    log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n",
+               openpgp_md_algo_name (kdf_hash_algo),
+               openpgp_cipher_algo_name (kdf_encr_algo));
+
+  if (kdf_hash_algo != GCRY_MD_SHA256
+      && kdf_hash_algo != GCRY_MD_SHA384
+      && kdf_hash_algo != GCRY_MD_SHA512)
+    {
+      xfree (secret_x);
+      return gpg_error (GPG_ERR_BAD_PUBKEY);
+    }
+  if (kdf_encr_algo != CIPHER_ALGO_AES
+      && kdf_encr_algo != CIPHER_ALGO_AES192
+      && kdf_encr_algo != CIPHER_ALGO_AES256)
+    {
+      xfree (secret_x);
+      return gpg_error (GPG_ERR_BAD_PUBKEY);
+    }
+
+  /* Build kdf_params.  */
+  {
+    IOBUF obuf;
+
+    obuf = iobuf_temp();
+    /* variable-length field 1, curve name OID */
+    err = gpg_mpi_write_nohdr (obuf, pkey[0]);
+    /* fixed-length field 2 */
+    iobuf_put (obuf, PUBKEY_ALGO_ECDH);
+    /* variable-length field 3, KDF params */
+    err = (err ? err : gpg_mpi_write_nohdr (obuf, pkey[2]));
+    /* fixed-length field 4 */
+    iobuf_write (obuf, "Anonymous Sender    ", 20);
+    /* fixed-length field 5, recipient fp */
+    iobuf_write (obuf, pk_fp, 20);
+
+    message_size = iobuf_temp_to_buffer (obuf, message, sizeof message);
+    iobuf_close (obuf);
+    if (err)
+      {
+        xfree (secret_x);
+        return err;
+      }
+
+    if(DBG_CIPHER)
+      log_printhex ("ecdh KDF message params are:", message, message_size);
+  }
+
+  /* Derive a KEK (key wrapping key) using MESSAGE and SECRET_X. */
+  {
+    gcry_md_hd_t h;
+    int old_size;
+
+    err = gcry_md_open (&h, kdf_hash_algo, 0);
+    if (err)
+      {
+        log_error ("gcry_md_open failed for kdf_hash_algo %d: %s",
+                   kdf_hash_algo, gpg_strerror (err));
+        xfree (secret_x);
+        return err;
+      }
+    gcry_md_write(h, "\x00\x00\x00\x01", 4);      /* counter = 1 */
+    gcry_md_write(h, secret_x, secret_x_size);   /* x of the point X */
+    gcry_md_write(h, message, message_size);/* KDF parameters */
+
+    gcry_md_final (h);
+
+    assert( gcry_md_get_algo_dlen (kdf_hash_algo) >= 32 );
+
+    memcpy (secret_x, gcry_md_read (h, kdf_hash_algo),
+            gcry_md_get_algo_dlen (kdf_hash_algo));
+    gcry_md_close (h);
+
+    old_size = secret_x_size;
+    assert( old_size >= gcry_cipher_get_algo_keylen( kdf_encr_algo ) );
+    secret_x_size = gcry_cipher_get_algo_keylen( kdf_encr_algo );
+    assert( secret_x_size <= gcry_md_get_algo_dlen (kdf_hash_algo) );
+
+    /* We could have allocated more, so clean the tail before returning.  */
+    memset( secret_x+secret_x_size, old_size-secret_x_size, 0 );
+    if (DBG_CIPHER)
+      log_printhex ("ecdh KEK is:", secret_x, secret_x_size );
+  }
+
+  /* And, finally, aeswrap with key secret_x.  */
+  {
+    gcry_cipher_hd_t hd;
+    size_t nbytes;
+
+    byte *data_buf;
+    int data_buf_size;
+
+    gcry_mpi_t result;
+
+    err = gcry_cipher_open (&hd, kdf_encr_algo, GCRY_CIPHER_MODE_AESWRAP, 0);
+    if (err)
+      {
+        log_error ("ecdh failed to initialize AESWRAP: %s\n",
+                   gpg_strerror (err));
+        xfree (secret_x);
+        return err;
+      }
+
+    err = gcry_cipher_setkey (hd, secret_x, secret_x_size);
+    xfree (secret_x);
+    secret_x = NULL;
+    if (err)
+      {
+        gcry_cipher_close (hd);
+        log_error ("ecdh failed in gcry_cipher_setkey: %s\n",
+                   gpg_strerror (err));
+        return err;
+      }
+
+    data_buf_size = (gcry_mpi_get_nbits(data)+7)/8;
+    if ((data_buf_size & 7) != (is_encrypt ? 0 : 1))
+      {
+        log_error ("can't use a shared secret of %d bytes for ecdh\n",
+                   data_buf_size);
+        return gpg_error (GPG_ERR_BAD_DATA);
+      }
+
+    data_buf = xtrymalloc_secure( 1 + 2*data_buf_size + 8);
+    if (!data_buf)
+      {
+        err = gpg_error_from_syserror ();
+        gcry_cipher_close (hd);
+        return err;
+      }
+
+    if (is_encrypt)
+      {
+        byte *in = data_buf+1+data_buf_size+8;
+
+        /* Write data MPI into the end of data_buf. data_buf is size
+           aeswrap data.  */
+        err = gcry_mpi_print (GCRYMPI_FMT_USG, in,
+                             data_buf_size, &nbytes, data/*in*/);
+        if (err)
+          {
+            log_error ("ecdh failed to export DEK: %s\n", gpg_strerror (err));
+            gcry_cipher_close (hd);
+            xfree (data_buf);
+            return err;
+          }
+
+        if (DBG_CIPHER)
+          log_printhex ("ecdh encrypting  :", in, data_buf_size );
+
+        err = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8,
+                                   in, data_buf_size);
+        memset (in, 0, data_buf_size);
+        gcry_cipher_close (hd);
+        if (err)
+          {
+            log_error ("ecdh failed in gcry_cipher_encrypt: %s\n",
+                       gpg_strerror (err));
+            xfree (data_buf);
+            return err;
+          }
+        data_buf[0] = data_buf_size+8;
+
+        if (DBG_CIPHER)
+          log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] );
+
+        result = gcry_mpi_set_opaque (NULL, data_buf, 8 * (1+data_buf[0]));
+        if (!result)
+          {
+            err = gpg_error_from_syserror ();
+            xfree (data_buf);
+            log_error ("ecdh failed to create an MPI: %s\n",
+                       gpg_strerror (err));
+            return err;
+          }
+
+        *r_result = result;
+      }
+    else
+      {
+        byte *in;
+        const void *p;
+
+        p = gcry_mpi_get_opaque (data, &nbits);
+        nbytes = (nbits+7)/8;
+        if (!p || nbytes > data_buf_size || !nbytes)
+          {
+            xfree (data_buf);
+            return gpg_error (GPG_ERR_BAD_MPI);
+          }
+        memcpy (data_buf, p, nbytes);
+        if (data_buf[0] != nbytes-1)
+          {
+            log_error ("ecdh inconsistent size\n");
+            xfree (data_buf);
+            return gpg_error (GPG_ERR_BAD_MPI);
+          }
+        in = data_buf+data_buf_size;
+        data_buf_size = data_buf[0];
+
+        if (DBG_CIPHER)
+          log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size);
+
+        err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1,
+                                   data_buf_size);
+        gcry_cipher_close (hd);
+        if (err)
+          {
+            log_error ("ecdh failed in gcry_cipher_decrypt: %s\n",
+                       gpg_strerror (err));
+            xfree (data_buf);
+            return err;
+          }
+
+        data_buf_size -= 8;
+
+        if (DBG_CIPHER)
+          log_printhex ("ecdh decrypted to :", in, data_buf_size);
+
+        /* Padding is removed later.  */
+        /* if (in[data_buf_size-1] > 8 ) */
+        /*   { */
+        /*     log_error ("ecdh failed at decryption: invalid padding." */
+        /*                " 0x%02x > 8\n", in[data_buf_size-1] ); */
+        /*     return gpg_error (GPG_ERR_BAD_KEY); */
+        /*   } */
+
+        err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, in, data_buf_size, NULL);
+        xfree (data_buf);
+        if (err)
+          {
+            log_error ("ecdh failed to create a plain text MPI: %s\n",
+                       gpg_strerror (err));
+            return err;
+          }
+
+        *r_result = result;
+      }
+  }
+
+  return err;
+}
+
+
+static gcry_mpi_t
+gen_k (unsigned nbits)
+{
+  gcry_mpi_t k;
+
+  k = gcry_mpi_snew (nbits);
+  if (DBG_CIPHER)
+    log_debug ("choosing a random k of %u bits\n", nbits);
+
+  gcry_mpi_randomize (k, nbits-1, GCRY_STRONG_RANDOM);
+
+  if (DBG_CIPHER)
+    {
+      unsigned char *buffer;
+      if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, k))
+        BUG ();
+      log_debug ("ephemeral scalar MPI #0: %s\n", buffer);
+      gcry_free (buffer);
+    }
+
+  return k;
+}
+
+
+/* Generate an ephemeral key for the public ECDH key in PKEY.  On
+   success the generated key is stored at R_K; on failure NULL is
+   stored at R_K and an error code returned.  */
+gpg_error_t
+pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k)
+{
+  unsigned int nbits;
+  gcry_mpi_t k;
+
+  *r_k = NULL;
+
+  nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey);
+  if (!nbits)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+  k = gen_k (nbits);
+  if (!k)
+    BUG ();
+
+  *r_k = k;
+  return 0;
+}
+
+
+
+/* Perform ECDH decryption.   */
+int
+pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN],
+                 gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey)
+{
+  if (!data)
+    return gpg_error (GPG_ERR_BAD_MPI);
+  return pk_ecdh_encrypt_with_shared_point (0 /*=decryption*/, shared,
+                                            sk_fp, data/*encr data as an MPI*/,
+                                            skey, result);
+}
diff --git a/g10/encode.c b/g10/encode.c
deleted file mode 100644 (file)
index 88d0a69..0000000
+++ /dev/null
@@ -1,912 +0,0 @@
-/* encode.c - encode data
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006, 2009 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "options.h"
-#include "packet.h"
-#include "status.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "util.h"
-#include "main.h"
-#include "filter.h"
-#include "trustdb.h"
-#include "i18n.h"
-#include "status.h"
-#include "pkglue.h"
-
-
-static int encode_simple( const char *filename, int mode, int use_seskey );
-static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out );
-
-/****************
- * Encode FILENAME with only the symmetric cipher.  Take input from
- * stdin if FILENAME is NULL.
- */
-int
-encode_symmetric( const char *filename )
-{
-    return encode_simple( filename, 1, 0 );
-}
-
-/****************
- * Encode FILENAME as a literal data packet only. Take input from
- * stdin if FILENAME is NULL.
- */
-int
-encode_store( const char *filename )
-{
-    return encode_simple( filename, 0, 0 );
-}
-
-
-static void
-encode_seskey( DEK *dek, DEK **seskey, byte *enckey )
-{
-    gcry_cipher_hd_t hd;
-    byte buf[33];
-
-    assert ( dek->keylen <= 32 );
-    if(!*seskey)
-      {
-       *seskey=xmalloc_clear(sizeof(DEK));
-       (*seskey)->keylen=dek->keylen;
-       (*seskey)->algo=dek->algo;
-       make_session_key(*seskey);
-       /*log_hexdump( "thekey", c->key, c->keylen );*/
-      }
-
-    /* The encrypted session key is prefixed with a one-octet algorithm id.  */
-    buf[0] = (*seskey)->algo;
-    memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
-
-    /* We only pass already checked values to the following fucntion,
-       thus we consider any failure as fatal.  */
-    if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
-      BUG ();
-    if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
-      BUG ();
-    gcry_cipher_setiv (hd, NULL, 0);
-    gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0);
-    gcry_cipher_close (hd);
-
-    memcpy( enckey, buf, (*seskey)->keylen + 1 );
-    wipememory( buf, sizeof buf ); /* burn key */
-}
-
-/* We try very hard to use a MDC */
-static int
-use_mdc(PK_LIST pk_list,int algo)
-{
-  /* RFC-1991 and 2440 don't have MDC */
-  if(RFC1991 || RFC2440)
-    return 0;
-
-  /* --force-mdc overrides --disable-mdc */
-  if(opt.force_mdc)
-    return 1;
-
-  if(opt.disable_mdc)
-    return 0;
-
-  /* Do the keys really support MDC? */
-
-  if(select_mdc_from_pklist(pk_list))
-    return 1;
-
-  /* The keys don't support MDC, so now we do a bit of a hack - if any
-     of the AESes or TWOFISH are in the prefs, we assume that the user
-     can handle a MDC.  This is valid for PGP 7, which can handle MDCs
-     though it will not generate them.  2440bis allows this, by the
-     way. */
-
-  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
-                           CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES)
-    return 1;
-
-  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
-                           CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192)
-    return 1;
-
-  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
-                           CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256)
-    return 1;
-
-  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
-                           CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH)
-    return 1;
-
-  /* Last try.  Use MDC for the modern ciphers. */
-
-  if (openpgp_cipher_get_algo_blklen (algo) != 8)
-    return 1;
-
-  if (opt.verbose)
-    warn_missing_mdc_from_pklist (pk_list);
-
-  return 0; /* No MDC */
-}
-
-/* We don't want to use use_seskey yet because older gnupg versions
-   can't handle it, and there isn't really any point unless we're
-   making a message that can be decrypted by a public key or
-   passphrase. */
-static int
-encode_simple( const char *filename, int mode, int use_seskey )
-{
-    IOBUF inp, out;
-    PACKET pkt;
-    PKT_plaintext *pt = NULL;
-    STRING2KEY *s2k = NULL;
-    byte enckey[33];
-    int rc = 0;
-    int seskeylen = 0;
-    u32 filesize;
-    cipher_filter_context_t cfx;
-    armor_filter_context_t  *afx = NULL;
-    compress_filter_context_t zfx;
-    text_filter_context_t tfx;
-    progress_filter_context_t *pfx;
-    int do_compress = !RFC1991 && default_compress_algo();
-
-    pfx = new_progress_context ();
-    memset( &cfx, 0, sizeof cfx);
-    memset( &zfx, 0, sizeof zfx);
-    memset( &tfx, 0, sizeof tfx);
-    init_packet(&pkt);
-
-    /* prepare iobufs */
-    inp = iobuf_open(filename);
-    if (inp)
-      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
-    if (inp && is_secured_file (iobuf_get_fd (inp)))
-      {
-        iobuf_close (inp);
-        inp = NULL;
-        errno = EPERM;
-      }
-    if( !inp ) {
-        rc = gpg_error_from_syserror ();
-       log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]",
-                  strerror(errno) );
-        release_progress_context (pfx);
-       return rc;
-    }
-
-    handle_progress (pfx, inp, filename);
-
-    if( opt.textmode )
-       iobuf_push_filter( inp, text_filter, &tfx );
-
-    /* Due the the fact that we use don't use an IV to encrypt the
-       session key we can't use the new mode with RFC1991 because
-       it has no S2K salt. RFC1991 always uses simple S2K. */
-    if ( RFC1991 && use_seskey )
-        use_seskey = 0;
-
-    cfx.dek = NULL;
-    if( mode ) {
-        int canceled;
-
-       s2k = xmalloc_clear( sizeof *s2k );
-       s2k->mode = RFC1991? 0:opt.s2k_mode;
-       s2k->hash_algo=S2K_DIGEST_ALGO;
-       cfx.dek = passphrase_to_dek( NULL, 0,
-                                    default_cipher_algo(), s2k, 4,
-                                     NULL, &canceled);
-       if( !cfx.dek || !cfx.dek->keylen ) {
-           rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE);
-           xfree(cfx.dek);
-           xfree(s2k);
-           iobuf_close(inp);
-           log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc));
-            release_progress_context (pfx);
-           return rc;
-       }
-        if (use_seskey && s2k->mode != 1 && s2k->mode != 3) {
-            use_seskey = 0;
-            log_info (_("can't use a symmetric ESK packet "
-                        "due to the S2K mode\n"));
-        }
-
-        if ( use_seskey )
-         {
-           DEK *dek = NULL;
-
-            seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
-            encode_seskey( cfx.dek, &dek, enckey );
-            xfree( cfx.dek ); cfx.dek = dek;
-         }
-
-       if(opt.verbose)
-         log_info(_("using cipher %s\n"),
-                  openpgp_cipher_algo_name (cfx.dek->algo));
-
-       cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
-    }
-
-    if (do_compress && cfx.dek && cfx.dek->use_mdc
-       && is_file_compressed(filename, &rc))
-      {
-        if (opt.verbose)
-          log_info(_("`%s' already compressed\n"), filename);
-        do_compress = 0;
-      }
-
-    if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
-       iobuf_cancel(inp);
-       xfree(cfx.dek);
-       xfree(s2k);
-        release_progress_context (pfx);
-       return rc;
-    }
-
-    if ( opt.armor )
-      {
-        afx = new_armor_context ();
-       push_armor_filter (afx, out);
-      }
-
-    if( s2k && !RFC1991 ) {
-       PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
-       enc->version = 4;
-       enc->cipher_algo = cfx.dek->algo;
-       enc->s2k = *s2k;
-        if ( use_seskey && seskeylen ) {
-            enc->seskeylen = seskeylen + 1; /* algo id */
-            memcpy( enc->seskey, enckey, seskeylen + 1 );
-        }
-       pkt.pkttype = PKT_SYMKEY_ENC;
-       pkt.pkt.symkey_enc = enc;
-       if( (rc = build_packet( out, &pkt )) )
-           log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
-       xfree(enc);
-    }
-
-    if (!opt.no_literal)
-      pt=setup_plaintext_name(filename,inp);
-
-    /* Note that PGP 5 has problems decrypting symmetrically encrypted
-       data if the file length is in the inner packet. It works when
-       only partial length headers are use.  In the past, we always
-       used partial body length here, but since PGP 2, PGP 6, and PGP
-       7 need the file length, and nobody should be using PGP 5
-       nowadays anyway, this is now set to the file length.  Note also
-       that this only applies to the RFC-1991 style symmetric
-       messages, and not the RFC-2440 style.  PGP 6 and 7 work with
-       either partial length or fixed length with the new style
-       messages. */
-
-    if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
-      {
-        off_t tmpsize;
-        int overflow;
-
-       if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
-             && !overflow && opt.verbose)
-          log_info(_("WARNING: `%s' is an empty file\n"), filename );
-        /* We can't encode the length of very large files because
-           OpenPGP uses only 32 bit for file sizes.  So if the the
-           size of a file is larger than 2^32 minus some bytes for
-           packet headers, we switch to partial length encoding. */
-        if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
-          filesize = tmpsize;
-        else
-          filesize = 0;
-      }
-    else
-      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
-
-    if (!opt.no_literal) {
-       pt->timestamp = make_timestamp();
-       pt->mode = opt.textmode? 't' : 'b';
-       pt->len = filesize;
-       pt->new_ctb = !pt->len && !RFC1991;
-       pt->buf = inp;
-       pkt.pkttype = PKT_PLAINTEXT;
-       pkt.pkt.plaintext = pt;
-       cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
-    }
-    else
-      {
-        cfx.datalen = filesize && !do_compress ? filesize : 0;
-        pkt.pkttype = 0;
-        pkt.pkt.generic = NULL;
-      }
-
-    /* register the cipher filter */
-    if( mode )
-       iobuf_push_filter( out, cipher_filter, &cfx );
-    /* register the compress filter */
-    if( do_compress )
-      {
-        if (cfx.dek && cfx.dek->use_mdc)
-          zfx.new_ctb = 1;
-       push_compress_filter(out,&zfx,default_compress_algo());
-      }
-
-    /* do the work */
-    if (!opt.no_literal) {
-       if( (rc = build_packet( out, &pkt )) )
-           log_error("build_packet failed: %s\n", g10_errstr(rc) );
-    }
-    else {
-       /* user requested not to create a literal packet,
-        * so we copy the plain data */
-       byte copy_buffer[4096];
-       int  bytes_copied;
-       while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
-           if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) {
-               log_error ("copying input to output failed: %s\n",
-                           gpg_strerror (rc) );
-               break;
-           }
-       wipememory(copy_buffer, 4096); /* burn buffer */
-    }
-
-    /* finish the stuff */
-    iobuf_close(inp);
-    if (rc)
-       iobuf_cancel(out);
-    else {
-       iobuf_close(out); /* fixme: check returncode */
-        if (mode)
-            write_status( STATUS_END_ENCRYPTION );
-    }
-    if (pt)
-       pt->buf = NULL;
-    free_packet(&pkt);
-    xfree(cfx.dek);
-    xfree(s2k);
-    release_armor_context (afx);
-    release_progress_context (pfx);
-    return rc;
-}
-
-int
-setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek)
-{
-  int canceled;
-
-  *symkey_s2k=xmalloc_clear(sizeof(STRING2KEY));
-  (*symkey_s2k)->mode = opt.s2k_mode;
-  (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO;
-
-  *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo,
-                               *symkey_s2k, 4, NULL, &canceled);
-  if(!*symkey_dek || !(*symkey_dek)->keylen)
-    {
-      xfree(*symkey_dek);
-      xfree(*symkey_s2k);
-      return gpg_error (canceled?GPG_ERR_CANCELED:GPG_ERR_BAD_PASSPHRASE);
-    }
-
-  return 0;
-}
-
-static int
-write_symkey_enc(STRING2KEY *symkey_s2k,DEK *symkey_dek,DEK *dek,IOBUF out)
-{
-  int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
-
-  PKT_symkey_enc *enc;
-  byte enckey[33];
-  PACKET pkt;
-
-  enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
-  encode_seskey(symkey_dek,&dek,enckey);
-
-  enc->version = 4;
-  enc->cipher_algo = opt.s2k_cipher_algo;
-  enc->s2k = *symkey_s2k;
-  enc->seskeylen = seskeylen + 1; /* algo id */
-  memcpy( enc->seskey, enckey, seskeylen + 1 );
-
-  pkt.pkttype = PKT_SYMKEY_ENC;
-  pkt.pkt.symkey_enc = enc;
-
-  if((rc=build_packet(out,&pkt)))
-    log_error("build symkey_enc packet failed: %s\n",g10_errstr(rc));
-
-  xfree(enc);
-  return rc;
-}
-
-/****************
- * Encrypt the file with the given userids (or ask if none
- * is supplied).
- */
-int
-encode_crypt( const char *filename, strlist_t remusr, int use_symkey )
-{
-    IOBUF inp = NULL, out = NULL;
-    PACKET pkt;
-    PKT_plaintext *pt = NULL;
-    DEK *symkey_dek = NULL;
-    STRING2KEY *symkey_s2k = NULL;
-    int rc = 0, rc2 = 0;
-    u32 filesize;
-    cipher_filter_context_t cfx;
-    armor_filter_context_t *afx = NULL;
-    compress_filter_context_t zfx;
-    text_filter_context_t tfx;
-    progress_filter_context_t *pfx;
-    PK_LIST pk_list,work_list;
-    int do_compress = opt.compress_algo && !RFC1991;
-
-    pfx = new_progress_context ();
-    memset( &cfx, 0, sizeof cfx);
-    memset( &zfx, 0, sizeof zfx);
-    memset( &tfx, 0, sizeof tfx);
-    init_packet(&pkt);
-
-    if(use_symkey
-       && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
-      {
-        release_progress_context (pfx);
-        return rc;
-      }
-
-    if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
-      {
-        release_progress_context (pfx);
-       return rc;
-      }
-
-    if(PGP2) {
-      for(work_list=pk_list; work_list; work_list=work_list->next)
-       if(!(is_RSA(work_list->pk->pubkey_algo) &&
-            nbits_from_pk(work_list->pk)<=2048))
-         {
-           log_info(_("you can only encrypt to RSA keys of 2048 bits or "
-                      "less in --pgp2 mode\n"));
-           compliance_failure();
-           break;
-         }
-    }
-
-    /* prepare iobufs */
-    inp = iobuf_open(filename);
-    if (inp)
-      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
-    if (inp && is_secured_file (iobuf_get_fd (inp)))
-      {
-        iobuf_close (inp);
-        inp = NULL;
-        errno = EPERM;
-      }
-    if( !inp ) {
-        rc = gpg_error_from_syserror ();
-       log_error(_("can't open `%s': %s\n"),
-                  filename? filename: "[stdin]",
-                  gpg_strerror (rc) );
-       goto leave;
-    }
-    else if( opt.verbose )
-       log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
-
-    handle_progress (pfx, inp, filename);
-
-    if( opt.textmode )
-       iobuf_push_filter( inp, text_filter, &tfx );
-
-    if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
-       goto leave;
-
-    if ( opt.armor )
-      {
-        afx = new_armor_context ();
-       push_armor_filter (afx, out);
-      }
-
-    /* create a session key */
-    cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
-    if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
-       cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
-       /* The only way select_algo_from_prefs can fail here is when
-           mixing v3 and v4 keys, as v4 keys have an implicit
-           preference entry for 3DES, and the pk_list cannot be empty.
-           In this case, use 3DES anyway as it's the safest choice -
-           perhaps the v3 key is being used in an OpenPGP
-           implementation and we know that the implementation behind
-           any v4 key can handle 3DES. */
-       if( cfx.dek->algo == -1 ) {
-           cfx.dek->algo = CIPHER_ALGO_3DES;
-
-           if( PGP2 ) {
-             log_info(_("unable to use the IDEA cipher for all of the keys "
-                        "you are encrypting to.\n"));
-             compliance_failure();
-           }
-       }
-
-        /* In case 3DES has been selected, print a warning if
-           any key does not have a preference for AES.  This
-           should help to indentify why encrypting to several
-           recipients falls back to 3DES. */
-        if (opt.verbose
-            && cfx.dek->algo == CIPHER_ALGO_3DES)
-          warn_missing_aes_from_pklist (pk_list);
-    }
-    else {
-      if(!opt.expert &&
-        select_algo_from_prefs(pk_list,PREFTYPE_SYM,
-                               opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
-       log_info(_("WARNING: forcing symmetric cipher %s (%d)"
-                  " violates recipient preferences\n"),
-                openpgp_cipher_algo_name (opt.def_cipher_algo),
-                opt.def_cipher_algo);
-
-      cfx.dek->algo = opt.def_cipher_algo;
-    }
-
-    cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo);
-
-    /* Only do the is-file-already-compressed check if we are using a
-       MDC.  This forces compressed files to be re-compressed if we do
-       not have a MDC to give some protection against chosen
-       ciphertext attacks. */
-
-    if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2) )
-      {
-        if (opt.verbose)
-          log_info(_("`%s' already compressed\n"), filename);
-        do_compress = 0;
-      }
-    if (rc2)
-      {
-        rc = rc2;
-        goto leave;
-      }
-
-    make_session_key( cfx.dek );
-    if( DBG_CIPHER )
-       log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
-
-    rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
-    if( rc  )
-       goto leave;
-
-    /* We put the passphrase (if any) after any public keys as this
-       seems to be the most useful on the recipient side - there is no
-       point in prompting a user for a passphrase if they have the
-       secret key needed to decrypt. */
-    if(use_symkey && (rc=write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
-      goto leave;
-
-    if (!opt.no_literal)
-      pt=setup_plaintext_name(filename,inp);
-
-    if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
-      {
-        off_t tmpsize;
-        int overflow;
-
-       if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
-             && !overflow && opt.verbose)
-          log_info(_("WARNING: `%s' is an empty file\n"), filename );
-        /* We can't encode the length of very large files because
-           OpenPGP uses only 32 bit for file sizes.  So if the the
-           size of a file is larger than 2^32 minus some bytes for
-           packet headers, we switch to partial length encoding. */
-        if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
-          filesize = tmpsize;
-        else
-          filesize = 0;
-      }
-    else
-      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
-
-    if (!opt.no_literal) {
-       pt->timestamp = make_timestamp();
-       pt->mode = opt.textmode ? 't' : 'b';
-       pt->len = filesize;
-       pt->new_ctb = !pt->len && !RFC1991;
-       pt->buf = inp;
-       pkt.pkttype = PKT_PLAINTEXT;
-       pkt.pkt.plaintext = pt;
-       cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
-    }
-    else
-       cfx.datalen = filesize && !do_compress ? filesize : 0;
-
-    /* register the cipher filter */
-    iobuf_push_filter( out, cipher_filter, &cfx );
-
-    /* register the compress filter */
-    if( do_compress ) {
-       int compr_algo = opt.compress_algo;
-
-       if(compr_algo==-1)
-         {
-           if((compr_algo=
-               select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
-             compr_algo=DEFAULT_COMPRESS_ALGO;
-           /* Theoretically impossible to get here since uncompressed
-              is implicit. */
-         }
-       else if(!opt.expert &&
-               select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
-                                      compr_algo,NULL)!=compr_algo)
-         log_info(_("WARNING: forcing compression algorithm %s (%d)"
-                    " violates recipient preferences\n"),
-                  compress_algo_to_string(compr_algo),compr_algo);
-
-       /* algo 0 means no compression */
-       if( compr_algo )
-         {
-            if (cfx.dek && cfx.dek->use_mdc)
-              zfx.new_ctb = 1;
-           push_compress_filter(out,&zfx,compr_algo);
-         }
-    }
-
-    /* do the work */
-    if (!opt.no_literal) {
-       if( (rc = build_packet( out, &pkt )) )
-           log_error("build_packet failed: %s\n", g10_errstr(rc) );
-    }
-    else {
-       /* user requested not to create a literal packet, so we copy
-           the plain data */
-       byte copy_buffer[4096];
-       int  bytes_copied;
-       while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
-           if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) {
-               log_error ("copying input to output failed: %s\n",
-                           gpg_strerror (rc));
-               break;
-           }
-       wipememory(copy_buffer, 4096); /* burn buffer */
-    }
-
-    /* finish the stuff */
-  leave:
-    iobuf_close(inp);
-    if( rc )
-       iobuf_cancel(out);
-    else {
-       iobuf_close(out); /* fixme: check returncode */
-        write_status( STATUS_END_ENCRYPTION );
-    }
-    if( pt )
-       pt->buf = NULL;
-    free_packet(&pkt);
-    xfree(cfx.dek);
-    xfree(symkey_dek);
-    xfree(symkey_s2k);
-    release_pk_list( pk_list );
-    release_armor_context (afx);
-    release_progress_context (pfx);
-    return rc;
-}
-
-
-
-
-/****************
- * Filter to do a complete public key encryption.
- */
-int
-encrypt_filter( void *opaque, int control,
-              IOBUF a, byte *buf, size_t *ret_len)
-{
-    size_t size = *ret_len;
-    encrypt_filter_context_t *efx = opaque;
-    int rc=0;
-
-    if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
-       BUG(); /* not used */
-    }
-    else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
-       if( !efx->header_okay ) {
-           efx->cfx.dek = xmalloc_secure_clear( sizeof *efx->cfx.dek );
-
-           if( !opt.def_cipher_algo  ) { /* try to get it from the prefs */
-               efx->cfx.dek->algo =
-                 select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL);
-               if( efx->cfx.dek->algo == -1 ) {
-                    /* because 3DES is implicitly in the prefs, this can only
-                     * happen if we do not have any public keys in the list */
-                   efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
-                }
-
-                /* In case 3DES has been selected, print a warning if
-                   any key does not have a preference for AES.  This
-                   should help to indentify why encrypting to several
-                   recipients falls back to 3DES. */
-                if (opt.verbose
-                    && efx->cfx.dek->algo == CIPHER_ALGO_3DES)
-                  warn_missing_aes_from_pklist (efx->pk_list);
-           }
-           else {
-             if(!opt.expert &&
-                select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,
-                                       opt.def_cipher_algo,
-                                       NULL)!=opt.def_cipher_algo)
-               log_info(_("forcing symmetric cipher %s (%d) "
-                          "violates recipient preferences\n"),
-                        openpgp_cipher_algo_name (opt.def_cipher_algo),
-                        opt.def_cipher_algo);
-
-             efx->cfx.dek->algo = opt.def_cipher_algo;
-           }
-
-            efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo);
-
-           make_session_key( efx->cfx.dek );
-           if( DBG_CIPHER )
-               log_printhex ("DEK is: ",
-                              efx->cfx.dek->key, efx->cfx.dek->keylen );
-
-           rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a );
-           if( rc )
-               return rc;
-
-           if(efx->symkey_s2k && efx->symkey_dek)
-             {
-               rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek,
-                                   efx->cfx.dek,a);
-               if(rc)
-                 return rc;
-             }
-
-           iobuf_push_filter( a, cipher_filter, &efx->cfx );
-
-           efx->header_okay = 1;
-       }
-       rc = iobuf_write( a, buf, size );
-
-    }
-    else if( control == IOBUFCTRL_FREE )
-      {
-       xfree(efx->symkey_dek);
-       xfree(efx->symkey_s2k);
-      }
-    else if( control == IOBUFCTRL_DESC ) {
-       *(char**)buf = "encrypt_filter";
-    }
-    return rc;
-}
-
-
-/****************
- * Write pubkey-enc packets from the list of PKs to OUT.
- */
-static int
-write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
-{
-    PACKET pkt;
-    PKT_public_key *pk;
-    PKT_pubkey_enc  *enc;
-    int rc;
-
-    for( ; pk_list; pk_list = pk_list->next ) {
-       gcry_mpi_t frame;
-
-       pk = pk_list->pk;
-
-       print_pubkey_algo_note( pk->pubkey_algo );
-       enc = xmalloc_clear( sizeof *enc );
-       enc->pubkey_algo = pk->pubkey_algo;
-       keyid_from_pk( pk, enc->keyid );
-       enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1));
-
-       if(opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8))
-         {
-           log_info(_("you may not use %s while in %s mode\n"),
-                    "--throw-keyid",compliance_option_string());
-           compliance_failure();
-         }
-
-       /* Okay, what's going on: We have the session key somewhere in
-        * the structure DEK and want to encode this session key in
-        * an integer value of n bits.  pubkey_nbits gives us the
-        * number of bits we have to use.  We then encode the session
-        * key in some way and we get it back in the big intger value
-        * FRAME.  Then we use FRAME, the public key PK->PKEY and the
-        * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
-        * which returns the encrypted value in the array ENC->DATA.
-        * This array has a size which depends on the used algorithm
-        * (e.g. 2 for Elgamal).  We don't need frame anymore because we
-        * have everything now in enc->data which is the passed to
-        * build_packet()
-        */
-       frame = encode_session_key (dek, pubkey_nbits (pk->pubkey_algo,
-                                                       pk->pkey) );
-       rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk->pkey);
-       gcry_mpi_release (frame);
-       if( rc )
-           log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
-       else {
-           if( opt.verbose ) {
-               char *ustr = get_user_id_string_native (enc->keyid);
-               log_info(_("%s/%s encrypted for: \"%s\"\n"),
-                         openpgp_pk_algo_name (enc->pubkey_algo),
-                         openpgp_cipher_algo_name (dek->algo),
-                         ustr );
-               xfree(ustr);
-           }
-           /* and write it */
-           init_packet(&pkt);
-           pkt.pkttype = PKT_PUBKEY_ENC;
-           pkt.pkt.pubkey_enc = enc;
-           rc = build_packet( out, &pkt );
-           if( rc )
-              log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
-       }
-       free_pubkey_enc(enc);
-       if( rc )
-           return rc;
-    }
-    return 0;
-}
-
-void
-encode_crypt_files(int nfiles, char **files, strlist_t remusr)
-{
-  int rc = 0;
-
-  if (opt.outfile)
-    {
-      log_error(_("--output doesn't work for this command\n"));
-      return;
-    }
-
-  if (!nfiles)
-    {
-      char line[2048];
-      unsigned int lno = 0;
-      while ( fgets(line, DIM(line), stdin) )
-        {
-          lno++;
-          if (!*line || line[strlen(line)-1] != '\n')
-            {
-              log_error("input line %u too long or missing LF\n", lno);
-              return;
-            }
-          line[strlen(line)-1] = '\0';
-          print_file_status(STATUS_FILE_START, line, 2);
-          if ( (rc = encode_crypt(line, remusr, 0)) )
-            log_error("encryption of `%s' failed: %s\n",
-                      print_fname_stdin(line), g10_errstr(rc) );
-          write_status( STATUS_FILE_DONE );
-        }
-    }
-  else
-    {
-      while (nfiles--)
-        {
-          print_file_status(STATUS_FILE_START, *files, 2);
-          if ( (rc = encode_crypt(*files, remusr, 0)) )
-            log_error("encryption of `%s' failed: %s\n",
-                      print_fname_stdin(*files), g10_errstr(rc) );
-          write_status( STATUS_FILE_DONE );
-          files++;
-        }
-    }
-}
diff --git a/g10/encrypt.c b/g10/encrypt.c
new file mode 100644 (file)
index 0000000..d1ce933
--- /dev/null
@@ -0,0 +1,969 @@
+/* encrypt.c - Main encryption driver
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ *               2006, 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "gpg.h"
+#include "options.h"
+#include "packet.h"
+#include "status.h"
+#include "iobuf.h"
+#include "keydb.h"
+#include "util.h"
+#include "main.h"
+#include "filter.h"
+#include "trustdb.h"
+#include "i18n.h"
+#include "status.h"
+#include "pkglue.h"
+
+
+static int encrypt_simple( const char *filename, int mode, int use_seskey );
+static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
+
+/****************
+ * Encrypt FILENAME with only the symmetric cipher.  Take input from
+ * stdin if FILENAME is NULL.
+ */
+int
+encrypt_symmetric (const char *filename)
+{
+  return encrypt_simple( filename, 1, 0 );
+}
+
+
+/****************
+ * Encrypt FILENAME as a literal data packet only. Take input from
+ * stdin if FILENAME is NULL.
+ */
+int
+encrypt_store (const char *filename)
+{
+  return encrypt_simple( filename, 0, 0 );
+}
+
+
+static void
+encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey)
+{
+  gcry_cipher_hd_t hd;
+  byte buf[33];
+
+  assert ( dek->keylen <= 32 );
+  if (!*seskey)
+    {
+      *seskey=xmalloc_clear(sizeof(DEK));
+      (*seskey)->keylen=dek->keylen;
+      (*seskey)->algo=dek->algo;
+      make_session_key(*seskey);
+      /*log_hexdump( "thekey", c->key, c->keylen );*/
+    }
+
+  /* The encrypted session key is prefixed with a one-octet algorithm id.  */
+  buf[0] = (*seskey)->algo;
+  memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
+
+  /* We only pass already checked values to the following fucntion,
+     thus we consider any failure as fatal.  */
+  if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
+    BUG ();
+  if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
+    BUG ();
+  gcry_cipher_setiv (hd, NULL, 0);
+  gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0);
+  gcry_cipher_close (hd);
+
+  memcpy( enckey, buf, (*seskey)->keylen + 1 );
+  wipememory( buf, sizeof buf ); /* burn key */
+}
+
+
+/* We try very hard to use a MDC */
+static int
+use_mdc(PK_LIST pk_list,int algo)
+{
+  /* RFC-2440 don't has MDC */
+  if (RFC2440)
+    return 0;
+
+  /* --force-mdc overrides --disable-mdc */
+  if(opt.force_mdc)
+    return 1;
+
+  if(opt.disable_mdc)
+    return 0;
+
+  /* Do the keys really support MDC? */
+
+  if(select_mdc_from_pklist(pk_list))
+    return 1;
+
+  /* The keys don't support MDC, so now we do a bit of a hack - if any
+     of the AESes or TWOFISH are in the prefs, we assume that the user
+     can handle a MDC.  This is valid for PGP 7, which can handle MDCs
+     though it will not generate them.  2440bis allows this, by the
+     way. */
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES)
+    return 1;
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192)
+    return 1;
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256)
+    return 1;
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH)
+    return 1;
+
+  /* Last try.  Use MDC for the modern ciphers. */
+
+  if (openpgp_cipher_get_algo_blklen (algo) != 8)
+    return 1;
+
+  if (opt.verbose)
+    warn_missing_mdc_from_pklist (pk_list);
+
+  return 0; /* No MDC */
+}
+
+
+/* We don't want to use use_seskey yet because older gnupg versions
+   can't handle it, and there isn't really any point unless we're
+   making a message that can be decrypted by a public key or
+   passphrase. */
+static int
+encrypt_simple (const char *filename, int mode, int use_seskey)
+{
+  iobuf_t inp, out;
+  PACKET pkt;
+  PKT_plaintext *pt = NULL;
+  STRING2KEY *s2k = NULL;
+  byte enckey[33];
+  int rc = 0;
+  int seskeylen = 0;
+  u32 filesize;
+  cipher_filter_context_t cfx;
+  armor_filter_context_t  *afx = NULL;
+  compress_filter_context_t zfx;
+  text_filter_context_t tfx;
+  progress_filter_context_t *pfx;
+  int do_compress = !!default_compress_algo();
+
+  pfx = new_progress_context ();
+  memset( &cfx, 0, sizeof cfx);
+  memset( &zfx, 0, sizeof zfx);
+  memset( &tfx, 0, sizeof tfx);
+  init_packet(&pkt);
+
+  /* Prepare iobufs. */
+  inp = iobuf_open(filename);
+  if (inp)
+    iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
+  if (inp && is_secured_file (iobuf_get_fd (inp)))
+    {
+      iobuf_close (inp);
+      inp = NULL;
+      gpg_err_set_errno (EPERM);
+    }
+  if (!inp)
+    {
+      rc = gpg_error_from_syserror ();
+      log_error(_("can't open '%s': %s\n"), filename? filename: "[stdin]",
+                strerror(errno) );
+      release_progress_context (pfx);
+      return rc;
+    }
+
+  handle_progress (pfx, inp, filename);
+
+  if (opt.textmode)
+    iobuf_push_filter( inp, text_filter, &tfx );
+
+  cfx.dek = NULL;
+  if ( mode )
+    {
+      int canceled;
+
+      s2k = xmalloc_clear( sizeof *s2k );
+      s2k->mode = opt.s2k_mode;
+      s2k->hash_algo = S2K_DIGEST_ALGO;
+      cfx.dek = passphrase_to_dek (NULL, 0,
+                                   default_cipher_algo(), s2k, 4,
+                                   NULL, &canceled);
+      if ( !cfx.dek || !cfx.dek->keylen )
+        {
+          rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE);
+          xfree (cfx.dek);
+          xfree (s2k);
+          iobuf_close (inp);
+          log_error (_("error creating passphrase: %s\n"), gpg_strerror (rc));
+          release_progress_context (pfx);
+          return rc;
+        }
+      if (use_seskey && s2k->mode != 1 && s2k->mode != 3)
+        {
+          use_seskey = 0;
+          log_info (_("can't use a symmetric ESK packet "
+                      "due to the S2K mode\n"));
+        }
+
+      if ( use_seskey )
+        {
+          DEK *dek = NULL;
+
+          seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
+          encrypt_seskey( cfx.dek, &dek, enckey );
+          xfree( cfx.dek ); cfx.dek = dek;
+        }
+
+      if (opt.verbose)
+        log_info(_("using cipher %s\n"),
+                 openpgp_cipher_algo_name (cfx.dek->algo));
+
+      cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
+    }
+
+  if (do_compress && cfx.dek && cfx.dek->use_mdc
+      && is_file_compressed(filename, &rc))
+    {
+      if (opt.verbose)
+        log_info(_("'%s' already compressed\n"), filename);
+      do_compress = 0;
+    }
+
+  if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out )))
+    {
+      iobuf_cancel (inp);
+      xfree (cfx.dek);
+      xfree (s2k);
+      release_progress_context (pfx);
+      return rc;
+    }
+
+  if ( opt.armor )
+    {
+      afx = new_armor_context ();
+      push_armor_filter (afx, out);
+    }
+
+  if ( s2k )
+    {
+      PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
+      enc->version = 4;
+      enc->cipher_algo = cfx.dek->algo;
+      enc->s2k = *s2k;
+      if ( use_seskey && seskeylen )
+        {
+          enc->seskeylen = seskeylen + 1; /* algo id */
+          memcpy (enc->seskey, enckey, seskeylen + 1 );
+        }
+      pkt.pkttype = PKT_SYMKEY_ENC;
+      pkt.pkt.symkey_enc = enc;
+      if ((rc = build_packet( out, &pkt )))
+        log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
+      xfree (enc);
+    }
+
+  if (!opt.no_literal)
+    pt = setup_plaintext_name (filename, inp);
+
+  /* Note that PGP 5 has problems decrypting symmetrically encrypted
+     data if the file length is in the inner packet. It works when
+     only partial length headers are use.  In the past, we always used
+     partial body length here, but since PGP 2, PGP 6, and PGP 7 need
+     the file length, and nobody should be using PGP 5 nowadays
+     anyway, this is now set to the file length.  Note also that this
+     only applies to the RFC-1991 style symmetric messages, and not
+     the RFC-2440 style.  PGP 6 and 7 work with either partial length
+     or fixed length with the new style messages. */
+
+  if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
+    {
+      off_t tmpsize;
+      int overflow;
+
+      if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
+           && !overflow && opt.verbose)
+        log_info(_("WARNING: '%s' is an empty file\n"), filename );
+      /* We can't encode the length of very large files because
+         OpenPGP uses only 32 bit for file sizes.  So if the the
+         size of a file is larger than 2^32 minus some bytes for
+         packet headers, we switch to partial length encoding. */
+      if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
+        filesize = tmpsize;
+      else
+        filesize = 0;
+    }
+  else
+    filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
+
+  if (!opt.no_literal)
+    {
+      pt->timestamp = make_timestamp();
+      pt->mode = opt.textmode? 't' : 'b';
+      pt->len = filesize;
+      pt->new_ctb = !pt->len;
+      pt->buf = inp;
+      pkt.pkttype = PKT_PLAINTEXT;
+      pkt.pkt.plaintext = pt;
+      cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
+    }
+  else
+    {
+      cfx.datalen = filesize && !do_compress ? filesize : 0;
+      pkt.pkttype = 0;
+      pkt.pkt.generic = NULL;
+    }
+
+  /* Register the cipher filter. */
+  if (mode)
+    iobuf_push_filter ( out, cipher_filter, &cfx );
+
+  /* Register the compress filter. */
+  if ( do_compress )
+    {
+      if (cfx.dek && cfx.dek->use_mdc)
+        zfx.new_ctb = 1;
+      push_compress_filter (out, &zfx, default_compress_algo());
+    }
+
+  /* Do the work. */
+  if (!opt.no_literal)
+    {
+      if ( (rc = build_packet( out, &pkt )) )
+        log_error("build_packet failed: %s\n", g10_errstr(rc) );
+    }
+  else
+    {
+      /* User requested not to create a literal packet, so we copy the
+         plain data.  */
+    byte copy_buffer[4096];
+    int  bytes_copied;
+    while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
+      if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) {
+        log_error ("copying input to output failed: %s\n",
+                   gpg_strerror (rc) );
+        break;
+      }
+    wipememory (copy_buffer, 4096); /* burn buffer */
+    }
+
+  /* Finish the stuff.  */
+  iobuf_close (inp);
+  if (rc)
+    iobuf_cancel(out);
+  else
+    {
+      iobuf_close (out); /* fixme: check returncode */
+      if (mode)
+        write_status ( STATUS_END_ENCRYPTION );
+    }
+  if (pt)
+    pt->buf = NULL;
+  free_packet (&pkt);
+  xfree (cfx.dek);
+  xfree (s2k);
+  release_armor_context (afx);
+  release_progress_context (pfx);
+  return rc;
+}
+
+
+int
+setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek)
+{
+  int canceled;
+
+  *symkey_s2k=xmalloc_clear(sizeof(STRING2KEY));
+  (*symkey_s2k)->mode = opt.s2k_mode;
+  (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO;
+
+  *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo,
+                               *symkey_s2k, 4, NULL, &canceled);
+  if(!*symkey_dek || !(*symkey_dek)->keylen)
+    {
+      xfree(*symkey_dek);
+      xfree(*symkey_s2k);
+      return gpg_error (canceled?GPG_ERR_CANCELED:GPG_ERR_BAD_PASSPHRASE);
+    }
+
+  return 0;
+}
+
+
+static int
+write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
+                  iobuf_t out)
+{
+  int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
+
+  PKT_symkey_enc *enc;
+  byte enckey[33];
+  PACKET pkt;
+
+  enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
+  encrypt_seskey(symkey_dek,&dek,enckey);
+
+  enc->version = 4;
+  enc->cipher_algo = opt.s2k_cipher_algo;
+  enc->s2k = *symkey_s2k;
+  enc->seskeylen = seskeylen + 1; /* algo id */
+  memcpy( enc->seskey, enckey, seskeylen + 1 );
+
+  pkt.pkttype = PKT_SYMKEY_ENC;
+  pkt.pkt.symkey_enc = enc;
+
+  if ((rc=build_packet(out,&pkt)))
+    log_error("build symkey_enc packet failed: %s\n",g10_errstr(rc));
+
+  xfree(enc);
+  return rc;
+}
+
+
+/*
+ * Encrypt the file with the given userids (or ask if none is
+ * supplied).  Either FILENAME or FILEFD must be given, but not both.
+ * The caller may provide a checked list of public keys in
+ * PROVIDED_PKS; if not the function builds a list of keys on its own.
+ */
+int
+encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
+               strlist_t remusr, int use_symkey, pk_list_t provided_keys,
+               int outputfd)
+{
+  iobuf_t inp = NULL;
+  iobuf_t out = NULL;
+  PACKET pkt;
+  PKT_plaintext *pt = NULL;
+  DEK *symkey_dek = NULL;
+  STRING2KEY *symkey_s2k = NULL;
+  int rc = 0, rc2 = 0;
+  u32 filesize;
+  cipher_filter_context_t cfx;
+  armor_filter_context_t *afx = NULL;
+  compress_filter_context_t zfx;
+  text_filter_context_t tfx;
+  progress_filter_context_t *pfx;
+  PK_LIST pk_list;
+  int do_compress;
+
+  if (filefd != -1 && filename)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  do_compress = !!opt.compress_algo;
+
+  pfx = new_progress_context ();
+  memset( &cfx, 0, sizeof cfx);
+  memset( &zfx, 0, sizeof zfx);
+  memset( &tfx, 0, sizeof tfx);
+  init_packet(&pkt);
+
+  if (use_symkey
+      && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
+    {
+      release_progress_context (pfx);
+      return rc;
+    }
+
+  if (provided_keys)
+    pk_list = provided_keys;
+  else
+    {
+      if ((rc = build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
+        {
+          release_progress_context (pfx);
+          return rc;
+        }
+    }
+
+  /* Prepare iobufs. */
+#ifdef HAVE_W32_SYSTEM
+  if (filefd == -1)
+    inp = iobuf_open_fd_or_name (GNUPG_INVALID_FD, filename, "rb");
+  else
+    {
+      inp = NULL;
+      gpg_err_set_errno (ENOSYS);
+    }
+#else
+  inp = iobuf_open_fd_or_name (filefd, filename, "rb");
+#endif
+  if (inp)
+    iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
+  if (inp && is_secured_file (iobuf_get_fd (inp)))
+    {
+      iobuf_close (inp);
+      inp = NULL;
+      gpg_err_set_errno (EPERM);
+    }
+  if (!inp)
+    {
+      char xname[64];
+
+      rc = gpg_error_from_syserror ();
+      if (filefd != -1)
+        snprintf (xname, sizeof xname, "[fd %d]", filefd);
+      else if (!filename)
+        strcpy (xname, "[stdin]");
+      else
+        *xname = 0;
+      log_error (_("can't open '%s': %s\n"),
+                 *xname? xname : filename, gpg_strerror (rc) );
+      goto leave;
+    }
+
+  if (opt.verbose)
+    log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp));
+
+  handle_progress (pfx, inp, filename);
+
+  if (opt.textmode)
+    iobuf_push_filter (inp, text_filter, &tfx);
+
+  rc = open_outfile (outputfd, filename, opt.armor? 1:0, 0, &out);
+  if (rc)
+    goto leave;
+
+  if (opt.armor)
+    {
+      afx = new_armor_context ();
+      push_armor_filter (afx, out);
+    }
+
+  /* Create a session key. */
+  cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
+  if (!opt.def_cipher_algo)
+    {
+      /* Try to get it from the prefs.  */
+      cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL);
+      /* The only way select_algo_from_prefs can fail here is when
+         mixing v3 and v4 keys, as v4 keys have an implicit preference
+         entry for 3DES, and the pk_list cannot be empty.  In this
+         case, use 3DES anyway as it's the safest choice - perhaps the
+         v3 key is being used in an OpenPGP implementation and we know
+         that the implementation behind any v4 key can handle 3DES. */
+      if (cfx.dek->algo == -1)
+        {
+          cfx.dek->algo = CIPHER_ALGO_3DES;
+        }
+
+      /* In case 3DES has been selected, print a warning if any key
+         does not have a preference for AES.  This should help to
+         indentify why encrypting to several recipients falls back to
+         3DES. */
+      if (opt.verbose && cfx.dek->algo == CIPHER_ALGO_3DES)
+        warn_missing_aes_from_pklist (pk_list);
+    }
+  else
+    {
+      if (!opt.expert
+          && (select_algo_from_prefs (pk_list, PREFTYPE_SYM,
+                                      opt.def_cipher_algo, NULL)
+              != opt.def_cipher_algo))
+        {
+          log_info(_("WARNING: forcing symmetric cipher %s (%d)"
+                     " violates recipient preferences\n"),
+                   openpgp_cipher_algo_name (opt.def_cipher_algo),
+                   opt.def_cipher_algo);
+        }
+
+      cfx.dek->algo = opt.def_cipher_algo;
+    }
+
+  cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);
+
+  /* Only do the is-file-already-compressed check if we are using a
+     MDC.  This forces compressed files to be re-compressed if we do
+     not have a MDC to give some protection against chosen ciphertext
+     attacks. */
+
+  if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2))
+    {
+      if (opt.verbose)
+        log_info(_("'%s' already compressed\n"), filename);
+      do_compress = 0;
+    }
+  if (rc2)
+    {
+      rc = rc2;
+      goto leave;
+    }
+
+  make_session_key (cfx.dek);
+  if (DBG_CIPHER)
+    log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
+
+  rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
+  if (rc)
+    goto leave;
+
+  /* We put the passphrase (if any) after any public keys as this
+     seems to be the most useful on the recipient side - there is no
+     point in prompting a user for a passphrase if they have the
+     secret key needed to decrypt.  */
+  if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
+    goto leave;
+
+  if (!opt.no_literal)
+    pt = setup_plaintext_name (filename, inp);
+
+  if (filefd != -1
+      && !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
+    {
+      off_t tmpsize;
+      int overflow;
+
+      if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
+           && !overflow && opt.verbose)
+        log_info(_("WARNING: '%s' is an empty file\n"), filename );
+      /* We can't encode the length of very large files because
+         OpenPGP uses only 32 bit for file sizes.  So if the the size
+         of a file is larger than 2^32 minus some bytes for packet
+         headers, we switch to partial length encoding. */
+      if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
+        filesize = tmpsize;
+      else
+        filesize = 0;
+    }
+  else
+    filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
+
+  if (!opt.no_literal)
+    {
+      pt->timestamp = make_timestamp();
+      pt->mode = opt.textmode ? 't' : 'b';
+      pt->len = filesize;
+      pt->new_ctb = !pt->len;
+      pt->buf = inp;
+      pkt.pkttype = PKT_PLAINTEXT;
+      pkt.pkt.plaintext = pt;
+      cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
+    }
+  else
+    cfx.datalen = filesize && !do_compress ? filesize : 0;
+
+  /* Register the cipher filter. */
+  iobuf_push_filter (out, cipher_filter, &cfx);
+
+  /* Register the compress filter. */
+  if (do_compress)
+    {
+      int compr_algo = opt.compress_algo;
+
+      if (compr_algo == -1)
+        {
+          compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL);
+          if (compr_algo == -1)
+            compr_algo = DEFAULT_COMPRESS_ALGO;
+          /* Theoretically impossible to get here since uncompressed
+             is implicit.  */
+        }
+      else if (!opt.expert
+               && select_algo_from_prefs(pk_list, PREFTYPE_ZIP,
+                                         compr_algo, NULL) != compr_algo)
+        {
+          log_info (_("WARNING: forcing compression algorithm %s (%d)"
+                      " violates recipient preferences\n"),
+                    compress_algo_to_string(compr_algo), compr_algo);
+        }
+
+      /* Algo 0 means no compression. */
+      if (compr_algo)
+        {
+          if (cfx.dek && cfx.dek->use_mdc)
+            zfx.new_ctb = 1;
+          push_compress_filter (out,&zfx,compr_algo);
+        }
+    }
+
+  /* Do the work. */
+  if (!opt.no_literal)
+    {
+      if ((rc = build_packet( out, &pkt )))
+        log_error ("build_packet failed: %s\n", g10_errstr(rc));
+    }
+  else
+    {
+      /* User requested not to create a literal packet, so we copy the
+         plain data. */
+      byte copy_buffer[4096];
+      int  bytes_copied;
+      while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
+        {
+          rc = iobuf_write (out, copy_buffer, bytes_copied);
+          if (rc)
+            {
+              log_error ("copying input to output failed: %s\n",
+                         gpg_strerror (rc));
+              break;
+            }
+        }
+      wipememory (copy_buffer, 4096); /* Burn the buffer. */
+    }
+
+  /* Finish the stuff. */
+ leave:
+  iobuf_close (inp);
+  if (rc)
+    iobuf_cancel (out);
+  else
+    {
+      iobuf_close (out); /* fixme: check returncode */
+      write_status (STATUS_END_ENCRYPTION);
+    }
+  if (pt)
+    pt->buf = NULL;
+  free_packet (&pkt);
+  xfree (cfx.dek);
+  xfree (symkey_dek);
+  xfree (symkey_s2k);
+  if (!provided_keys)
+    release_pk_list (pk_list);
+  release_armor_context (afx);
+  release_progress_context (pfx);
+  return rc;
+}
+
+
+/*
+ * Filter to do a complete public key encryption.
+ */
+int
+encrypt_filter (void *opaque, int control,
+                iobuf_t a, byte *buf, size_t *ret_len)
+{
+  size_t size = *ret_len;
+  encrypt_filter_context_t *efx = opaque;
+  int rc = 0;
+
+  if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
+    {
+      BUG(); /* not used */
+    }
+  else if ( control == IOBUFCTRL_FLUSH ) /* encrypt */
+    {
+      if ( !efx->header_okay )
+        {
+          efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek );
+          if ( !opt.def_cipher_algo  )
+            {
+              /* Try to get it from the prefs. */
+              efx->cfx.dek->algo =
+                select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL);
+              if (efx->cfx.dek->algo == -1 )
+                {
+                  /* Because 3DES is implicitly in the prefs, this can
+                     only happen if we do not have any public keys in
+                     the list.  */
+                  efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
+                }
+
+              /* In case 3DES has been selected, print a warning if
+                 any key does not have a preference for AES.  This
+                 should help to indentify why encrypting to several
+                 recipients falls back to 3DES. */
+              if (opt.verbose
+                  && efx->cfx.dek->algo == CIPHER_ALGO_3DES)
+                warn_missing_aes_from_pklist (efx->pk_list);
+           }
+          else
+            {
+             if (!opt.expert
+                  && select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM,
+                                             opt.def_cipher_algo,
+                                             NULL) != opt.def_cipher_algo)
+               log_info(_("forcing symmetric cipher %s (%d) "
+                          "violates recipient preferences\n"),
+                        openpgp_cipher_algo_name (opt.def_cipher_algo),
+                        opt.def_cipher_algo);
+
+             efx->cfx.dek->algo = opt.def_cipher_algo;
+           }
+
+          efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo);
+
+          make_session_key ( efx->cfx.dek );
+          if (DBG_CIPHER)
+            log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
+
+          rc = write_pubkey_enc_from_list (efx->pk_list, efx->cfx.dek, a);
+          if (rc)
+            return rc;
+
+           if(efx->symkey_s2k && efx->symkey_dek)
+             {
+               rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek,
+                                   efx->cfx.dek,a);
+               if(rc)
+                 return rc;
+             }
+
+           iobuf_push_filter (a, cipher_filter, &efx->cfx);
+
+           efx->header_okay = 1;
+       }
+      rc = iobuf_write (a, buf, size);
+
+    }
+  else if (control == IOBUFCTRL_FREE)
+    {
+      xfree (efx->symkey_dek);
+      xfree (efx->symkey_s2k);
+    }
+  else if ( control == IOBUFCTRL_DESC )
+    {
+      *(char**)buf = "encrypt_filter";
+    }
+  return rc;
+}
+
+
+/*
+ * Write pubkey-enc packets from the list of PKs to OUT.
+ */
+static int
+write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
+{
+  PACKET pkt;
+  PKT_public_key *pk;
+  PKT_pubkey_enc  *enc;
+  int rc;
+
+  for ( ; pk_list; pk_list = pk_list->next )
+    {
+      gcry_mpi_t frame;
+
+      pk = pk_list->pk;
+
+      print_pubkey_algo_note ( pk->pubkey_algo );
+      enc = xmalloc_clear ( sizeof *enc );
+      enc->pubkey_algo = pk->pubkey_algo;
+      keyid_from_pk( pk, enc->keyid );
+      enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1));
+
+      if (opt.throw_keyid && (PGP6 || PGP7 || PGP8))
+        {
+          log_info(_("you may not use %s while in %s mode\n"),
+                   "--throw-keyid",compliance_option_string());
+          compliance_failure();
+        }
+
+      /* Okay, what's going on: We have the session key somewhere in
+       * the structure DEK and want to encode this session key in an
+       * integer value of n bits. pubkey_nbits gives us the number of
+       * bits we have to use.  We then encode the session key in some
+       * way and we get it back in the big intger value FRAME.  Then
+       * we use FRAME, the public key PK->PKEY and the algorithm
+       * number PK->PUBKEY_ALGO and pass it to pubkey_encrypt which
+       * returns the encrypted value in the array ENC->DATA.  This
+       * array has a size which depends on the used algorithm (e.g. 2
+       * for Elgamal).  We don't need frame anymore because we have
+       * everything now in enc->data which is the passed to
+       * build_packet().  */
+      frame = encode_session_key (pk->pubkey_algo, dek,
+                                  pubkey_nbits (pk->pubkey_algo, pk->pkey));
+      rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk, pk->pkey);
+      gcry_mpi_release (frame);
+      if (rc)
+        log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
+      else
+        {
+          if ( opt.verbose )
+            {
+              char *ustr = get_user_id_string_native (enc->keyid);
+              log_info (_("%s/%s encrypted for: \"%s\"\n"),
+                        openpgp_pk_algo_name (enc->pubkey_algo),
+                        openpgp_cipher_algo_name (dek->algo),
+                        ustr );
+              xfree (ustr);
+           }
+          /* And write it. */
+          init_packet (&pkt);
+          pkt.pkttype = PKT_PUBKEY_ENC;
+          pkt.pkt.pubkey_enc = enc;
+          rc = build_packet (out, &pkt);
+          if (rc)
+            log_error ("build_packet(pubkey_enc) failed: %s\n",
+                       g10_errstr (rc));
+       }
+      free_pubkey_enc(enc);
+      if (rc)
+        return rc;
+    }
+  return 0;
+}
+
+
+void
+encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr)
+{
+  int rc = 0;
+
+  if (opt.outfile)
+    {
+      log_error(_("--output doesn't work for this command\n"));
+      return;
+    }
+
+  if (!nfiles)
+    {
+      char line[2048];
+      unsigned int lno = 0;
+      while ( fgets(line, DIM(line), stdin) )
+        {
+          lno++;
+          if (!*line || line[strlen(line)-1] != '\n')
+            {
+              log_error("input line %u too long or missing LF\n", lno);
+              return;
+            }
+          line[strlen(line)-1] = '\0';
+          print_file_status(STATUS_FILE_START, line, 2);
+          rc = encrypt_crypt (ctrl, -1, line, remusr, 0, NULL, -1);
+          if (rc)
+            log_error ("encryption of '%s' failed: %s\n",
+                       print_fname_stdin(line), g10_errstr(rc) );
+          write_status( STATUS_FILE_DONE );
+        }
+    }
+  else
+    {
+      while (nfiles--)
+        {
+          print_file_status(STATUS_FILE_START, *files, 2);
+          if ( (rc = encrypt_crypt (ctrl, -1, *files, remusr, 0, NULL, -1)) )
+            log_error("encryption of '%s' failed: %s\n",
+                      print_fname_stdin(*files), g10_errstr(rc) );
+          write_status( STATUS_FILE_DONE );
+          files++;
+        }
+    }
+}
index 331c5ec..b0ff2ea 100644 (file)
@@ -77,6 +77,9 @@ set_exec_path(const char *path) { return G10ERR_GENERAL; }
 static int
 w32_system(const char *command)
 {
+#ifdef HAVE_W32CE_SYSTEM
+#warning Change this code to use common/exechelp.c
+#else
   PROCESS_INFORMATION pi;
   STARTUPINFO si;
   char *string;
@@ -102,6 +105,7 @@ w32_system(const char *command)
   xfree(string);
 
   return 0;
+#endif
 }
 #endif
 
@@ -109,6 +113,9 @@ w32_system(const char *command)
 int
 set_exec_path(const char *path)
 {
+#ifdef HAVE_W32CE_SYSTEM
+#warning Change this code to use common/exechelp.c
+#else
   char *p;
 
   p=xmalloc(5+strlen(path)+1);
@@ -126,6 +133,7 @@ set_exec_path(const char *path)
     return G10ERR_GENERAL;
   else
     return 0;
+#endif
 }
 
 /* Makes a temp directory and filenames */
@@ -188,7 +196,7 @@ make_tempdir(struct exec_info *info)
 #endif
 
   if(mkdtemp(info->tempdir)==NULL)
-    log_error(_("can't create directory `%s': %s\n"),
+    log_error(_("can't create directory '%s': %s\n"),
              info->tempdir,strerror(errno));
   else
     {
@@ -416,10 +424,10 @@ exec_write(struct exec_info **info,const char *program,
          /* If we get this far the exec failed.  Clean up and return. */
 
          if(args_in==NULL)
-           log_error(_("unable to execute program `%s': %s\n"),
+           log_error(_("unable to execute program '%s': %s\n"),
                      program,strerror(errno));
          else
-           log_error(_("unable to execute shell `%s': %s\n"),
+           log_error(_("unable to execute shell '%s': %s\n"),
                      shell,strerror(errno));
 
          /* This mimics the POSIX sh behavior - 127 means "not found"
@@ -452,28 +460,28 @@ exec_write(struct exec_info **info,const char *program,
          goto fail;
        }
 
-      /* fd iobufs are cached?! */
-      iobuf_ioctl((*info)->fromchild,3,1,NULL);
+      /* fd iobufs are cached! */
+      iobuf_ioctl((*info)->fromchild, IOBUF_IOCTL_NO_CACHE, 1, NULL);
 
       return 0;
     }
 #endif /* !EXEC_TEMPFILE_ONLY */
 
   if(DBG_EXTPROG)
-    log_debug("using temp file `%s'\n",(*info)->tempfile_in);
+    log_debug("using temp file '%s'\n",(*info)->tempfile_in);
 
   /* It's not fork/exec/pipe, so create a temp file */
   if( is_secured_filename ((*info)->tempfile_in) )
     {
       (*info)->tochild = NULL;
-      errno = EPERM;
+      gpg_err_set_errno (EPERM);
     }
   else
     (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w");
   if((*info)->tochild==NULL)
     {
       ret = gpg_error_from_syserror ();
-      log_error(_("can't create `%s': %s\n"),
+      log_error(_("can't create '%s': %s\n"),
                (*info)->tempfile_in,strerror(errno));
       goto fail;
     }
@@ -548,7 +556,7 @@ exec_read(struct exec_info *info)
             {
               iobuf_close (info->fromchild);
               info->fromchild = NULL;
-              errno = EPERM;
+              gpg_err_set_errno (EPERM);
             }
          if(info->fromchild==NULL)
            {
@@ -559,7 +567,7 @@ exec_read(struct exec_info *info)
            }
 
          /* Do not cache this iobuf on close */
-         iobuf_ioctl(info->fromchild,3,1,NULL);
+         iobuf_ioctl(info->fromchild, IOBUF_IOCTL_NO_CACHE, 1, NULL);
        }
     }
 
@@ -599,19 +607,19 @@ exec_finish(struct exec_info *info)
       if(info->tempfile_in)
        {
          if(unlink(info->tempfile_in)==-1)
-           log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"),
+           log_info(_("WARNING: unable to remove tempfile (%s) '%s': %s\n"),
                     "in",info->tempfile_in,strerror(errno));
        }
 
       if(info->tempfile_out)
        {
          if(unlink(info->tempfile_out)==-1)
-           log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"),
+           log_info(_("WARNING: unable to remove tempfile (%s) '%s': %s\n"),
                     "out",info->tempfile_out,strerror(errno));
        }
 
       if(rmdir(info->tempdir)==-1)
-       log_info(_("WARNING: unable to remove temp directory `%s': %s\n"),
+       log_info(_("WARNING: unable to remove temp directory '%s': %s\n"),
                 info->tempdir,strerror(errno));
     }
 
index 09faa03..a92eace 100644 (file)
@@ -1,6 +1,7 @@
-/* export.c
+/* export.c - Export keys in the OpenPGP defined format.
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2005 Free Software Foundation, Inc.
+ *               2005, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -34,7 +35,7 @@
 #include "main.h"
 #include "i18n.h"
 #include "trustdb.h"
-
+#include "call-agent.h"
 
 /* An object to keep track of subkeys. */
 struct subkey_list_s
@@ -45,10 +46,12 @@ struct subkey_list_s
 typedef struct subkey_list_s *subkey_list_t;
 
 
-static int do_export( strlist_t users, int secret, unsigned int options );
-static int do_export_stream( IOBUF out, strlist_t users, int secret,
-                            KBNODE *keyblock_out, unsigned int options,
-                            int *any );
+static int do_export (ctrl_t ctrl,
+                      strlist_t users, int secret, unsigned int options );
+static int do_export_stream (ctrl_t ctrl, iobuf_t out,
+                             strlist_t users, int secret,
+                             kbnode_t *keyblock_out, unsigned int options,
+                            int *any);
 static int build_sexp (iobuf_t out, PACKET *pkt, int *indent);
 
 
@@ -63,8 +66,6 @@ parse_export_options(char *str,unsigned int *options,int noisy)
        N_("export attribute user IDs (generally photo IDs)")},
       {"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
        N_("export revocation keys marked as \"sensitive\"")},
-      {"export-reset-subkey-passwd",EXPORT_RESET_SUBKEY_PASSWD,NULL,
-       N_("remove the passphrase from exported subkeys")},
       {"export-clean",EXPORT_CLEAN,NULL,
        N_("remove unusable parts from key during export")},
       {"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
@@ -93,9 +94,9 @@ parse_export_options(char *str,unsigned int *options,int noisy)
  * options are defined in main.h.
  * If USERS is NULL, the complete ring will be exported.  */
 int
-export_pubkeys( strlist_t users, unsigned int options )
+export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options )
 {
-    return do_export( users, 0, options );
+  return do_export (ctrl, users, 0, options );
 }
 
 /****************
@@ -103,44 +104,104 @@ export_pubkeys( strlist_t users, unsigned int options )
  * been exported
  */
 int
-export_pubkeys_stream( IOBUF out, strlist_t users,
-                      KBNODE *keyblock_out, unsigned int options )
+export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
+                      kbnode_t *keyblock_out, unsigned int options )
 {
-    int any, rc;
+  int any, rc;
 
-    rc = do_export_stream( out, users, 0, keyblock_out, options, &any );
-    if( !rc && !any )
-       rc = -1;
-    return rc;
+  rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any);
+  if (!rc && !any)
+    rc = -1;
+  return rc;
+}
+
+
+/*
+ * Export a single key into a memory buffer.
+ */
+gpg_error_t
+export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
+                      kbnode_t *r_keyblock, void **r_data, size_t *r_datalen)
+{
+  gpg_error_t err;
+  iobuf_t iobuf;
+  int any;
+  strlist_t helplist;
+
+  *r_keyblock = NULL;
+  *r_data = NULL;
+  *r_datalen = 0;
+
+  helplist = NULL;
+  if (!add_to_strlist_try (&helplist, keyspec))
+    return gpg_error_from_syserror ();
+
+  iobuf = iobuf_temp ();
+  err = do_export_stream (ctrl, iobuf, helplist, 0, r_keyblock, options, &any);
+  if (!err && !any)
+    err = gpg_error (GPG_ERR_NOT_FOUND);
+  if (!err)
+    {
+      const void *src;
+      size_t datalen;
+
+      iobuf_flush_temp (iobuf);
+      src = iobuf_get_temp_buffer (iobuf);
+      datalen = iobuf_get_temp_length (iobuf);
+      if (!datalen)
+        err = gpg_error (GPG_ERR_NO_PUBKEY);
+      else if (!(*r_data = xtrymalloc (datalen)))
+        err = gpg_error_from_syserror ();
+      else
+        {
+          memcpy (*r_data, src, datalen);
+          *r_datalen = datalen;
+        }
+    }
+  iobuf_close (iobuf);
+  free_strlist (helplist);
+  if (err && *r_keyblock)
+    {
+      release_kbnode (*r_keyblock);
+      *r_keyblock = NULL;
+    }
+  return err;
 }
 
+
 int
-export_seckeys( strlist_t users )
+export_seckeys (ctrl_t ctrl, strlist_t users )
 {
   /* Use only relevant options for the secret key. */
   unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
-  return do_export( users, 1, options );
+  return do_export (ctrl, users, 1, options);
 }
 
 int
-export_secsubkeys( strlist_t users )
+export_secsubkeys (ctrl_t ctrl, strlist_t users )
 {
   /* Use only relevant options for the secret key. */
   unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
-  return do_export( users, 2, options );
+  return do_export (ctrl, users, 2, options);
 }
 
+
+/* Export the keys identified by the list of strings in USERS.  If
+   Secret is false public keys will be exported.  With secret true
+   secret keys will be exported; in this case 1 means the entire
+   secret keyblock and 2 only the subkeys.  OPTIONS are the export
+   options to apply.  */
 static int
-do_export( strlist_t users, int secret, unsigned int options )
+do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options )
 {
   IOBUF out = NULL;
   int any, rc;
   armor_filter_context_t *afx = NULL;
   compress_filter_context_t zfx;
-  
+
   memset( &zfx, 0, sizeof zfx);
-  
-  rc = open_outfile( NULL, 0, &out );
+
+  rc = open_outfile (-1, NULL, 0, !!secret, &out );
   if (rc)
     return rc;
 
@@ -152,11 +213,9 @@ do_export( strlist_t users, int secret, unsigned int options )
           afx->what = secret? 5 : 1;
           push_armor_filter (afx, out);
         }
-      if ( opt.compress_keys )
-        push_compress_filter (out,&zfx,default_compress_algo());
     }
 
-  rc = do_export_stream ( out, users, secret, NULL, options, &any );
+  rc = do_export_stream (ctrl, out, users, secret, NULL, options, &any );
 
   if ( rc || !any )
     iobuf_cancel (out);
@@ -190,11 +249,8 @@ subkey_in_list_p (subkey_list_t list, KBNODE node)
     {
       u32 kid[2];
 
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        keyid_from_pk (node->pkt->pkt.public_key, kid);
-      else
-        keyid_from_sk (node->pkt->pkt.secret_key, kid);
-      
+      keyid_from_pk (node->pkt->pkt.public_key, kid);
+
       for (; list; list = list->next)
         if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
           return 1;
@@ -208,10 +264,9 @@ new_subkey_list_item (KBNODE node)
 {
   subkey_list_t list = xcalloc (1, sizeof *list);
 
-  if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+  if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+      || node->pkt->pkttype == PKT_SECRET_SUBKEY)
     keyid_from_pk (node->pkt->pkt.public_key, list->kid);
-  else if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
-    keyid_from_sk (node->pkt->pkt.secret_key, list->kid);
 
   return list;
 }
@@ -235,25 +290,19 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
     {
     case KEYDB_SEARCH_MODE_SHORT_KID:
     case KEYDB_SEARCH_MODE_LONG_KID:
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        keyid_from_pk (node->pkt->pkt.public_key, kid);
-      else
-        keyid_from_sk (node->pkt->pkt.secret_key, kid);
+      keyid_from_pk (node->pkt->pkt.public_key, kid);
       break;
-      
+
     case KEYDB_SEARCH_MODE_FPR16:
     case KEYDB_SEARCH_MODE_FPR20:
     case KEYDB_SEARCH_MODE_FPR:
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
-      else
-        fingerprint_from_sk (node->pkt->pkt.secret_key, fpr,&fprlen);
+      fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
       break;
-      
+
     default:
       break;
     }
-  
+
   switch(desc->mode)
     {
     case KEYDB_SEARCH_MODE_SHORT_KID:
@@ -285,458 +334,1046 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
 }
 
 
-/* If keyblock_out is non-NULL, AND the exit code is zero, then it
-   contains a pointer to the first keyblock found and exported.  No
-   other keyblocks are exported.  The caller must free it. */
+/* Return a canonicalized public key algoithms.  This is used to
+   compare different flavors of algorithms (e.g. ELG and ELG_E are
+   considered the same).  */
+static enum gcry_pk_algos
+canon_pk_algo (enum gcry_pk_algos algo)
+{
+  switch (algo)
+    {
+    case GCRY_PK_RSA:
+    case GCRY_PK_RSA_E:
+    case GCRY_PK_RSA_S: return GCRY_PK_RSA;
+    case GCRY_PK_ELG:
+    case GCRY_PK_ELG_E: return GCRY_PK_ELG;
+    case GCRY_PK_ECC:
+    case GCRY_PK_ECDSA:
+    case GCRY_PK_ECDH: return GCRY_PK_ECC;
+    default: return algo;
+    }
+}
+
+
+/* Use the key transfer format given in S_PGP to create the secinfo
+   structure in PK and change the parameter array in PK to include the
+   secret parameters.  */
+static gpg_error_t
+transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
+{
+  gpg_error_t err;
+  gcry_sexp_t top_list;
+  gcry_sexp_t list = NULL;
+  char *curve = NULL;
+  const char *value;
+  size_t valuelen;
+  char *string;
+  int  idx;
+  int  is_v4, is_protected;
+  enum gcry_pk_algos pk_algo;
+  int  protect_algo = 0;
+  char iv[16];
+  int  ivlen = 0;
+  int  s2k_mode = 0;
+  int  s2k_algo = 0;
+  byte s2k_salt[8];
+  u32  s2k_count = 0;
+  int  is_ecdh = 0;
+  size_t npkey, nskey;
+  gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
+  int skeyidx = 0;
+  struct seckey_info *ski;
+
+  /* gcry_log_debugsxp ("transferkey", s_pgp); */
+  top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
+  if (!top_list)
+    goto bad_seckey;
+
+  list = gcry_sexp_find_token (top_list, "version", 0);
+  if (!list)
+    goto bad_seckey;
+  value = gcry_sexp_nth_data (list, 1, &valuelen);
+  if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
+    goto bad_seckey;
+  is_v4 = (value[0] == '4');
+
+  gcry_sexp_release (list);
+  list = gcry_sexp_find_token (top_list, "protection", 0);
+  if (!list)
+    goto bad_seckey;
+  value = gcry_sexp_nth_data (list, 1, &valuelen);
+  if (!value)
+    goto bad_seckey;
+  if (valuelen == 4 && !memcmp (value, "sha1", 4))
+    is_protected = 2;
+  else if (valuelen == 3 && !memcmp (value, "sum", 3))
+    is_protected = 1;
+  else if (valuelen == 4 && !memcmp (value, "none", 4))
+    is_protected = 0;
+  else
+    goto bad_seckey;
+  if (is_protected)
+    {
+      string = gcry_sexp_nth_string (list, 2);
+      if (!string)
+        goto bad_seckey;
+      protect_algo = gcry_cipher_map_name (string);
+      xfree (string);
+
+      value = gcry_sexp_nth_data (list, 3, &valuelen);
+      if (!value || !valuelen || valuelen > sizeof iv)
+        goto bad_seckey;
+      memcpy (iv, value, valuelen);
+      ivlen = valuelen;
+
+      string = gcry_sexp_nth_string (list, 4);
+      if (!string)
+        goto bad_seckey;
+      s2k_mode = strtol (string, NULL, 10);
+      xfree (string);
+
+      string = gcry_sexp_nth_string (list, 5);
+      if (!string)
+        goto bad_seckey;
+      s2k_algo = gcry_md_map_name (string);
+      xfree (string);
+
+      value = gcry_sexp_nth_data (list, 6, &valuelen);
+      if (!value || !valuelen || valuelen > sizeof s2k_salt)
+        goto bad_seckey;
+      memcpy (s2k_salt, value, valuelen);
+
+      string = gcry_sexp_nth_string (list, 7);
+      if (!string)
+        goto bad_seckey;
+      s2k_count = strtoul (string, NULL, 10);
+      xfree (string);
+    }
+
+  /* Parse the gcrypt PK algo and check that it is okay.  */
+  gcry_sexp_release (list);
+  list = gcry_sexp_find_token (top_list, "algo", 0);
+  if (!list)
+    goto bad_seckey;
+  string = gcry_sexp_nth_string (list, 1);
+  if (!string)
+    goto bad_seckey;
+  pk_algo = gcry_pk_map_name (string);
+  xfree (string); string = NULL;
+  if (gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
+      || gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
+      || !npkey || npkey >= nskey)
+    goto bad_seckey;
+
+  /* Check that the pubkey algo matches the one from the public key.  */
+  switch (canon_pk_algo (pk_algo))
+    {
+    case GCRY_PK_RSA:
+      if (!is_RSA (pk->pubkey_algo))
+        pk_algo = 0;  /* Does not match.  */
+      break;
+    case GCRY_PK_DSA:
+      if (!is_DSA (pk->pubkey_algo))
+        pk_algo = 0;  /* Does not match.  */
+      break;
+    case GCRY_PK_ELG:
+      if (!is_ELGAMAL (pk->pubkey_algo))
+        pk_algo = 0;  /* Does not match.  */
+      break;
+    case GCRY_PK_ECC:
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+        ;
+      else if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+        is_ecdh = 1;
+      else if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
+        ;
+      else
+        pk_algo = 0;  /* Does not match.  */
+      /* For ECC we do not have the domain parameters thus fix our info.  */
+      npkey = 1;
+      nskey = 2;
+      break;
+    default:
+      pk_algo = 0;   /* Oops.  */
+      break;
+    }
+  if (!pk_algo)
+    {
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      goto leave;
+    }
+
+  /* This check has to go after the ecc adjustments. */
+  if (nskey > PUBKEY_MAX_NSKEY)
+    goto bad_seckey;
+
+  /* Parse the key parameters.  */
+  gcry_sexp_release (list);
+  list = gcry_sexp_find_token (top_list, "skey", 0);
+  if (!list)
+    goto bad_seckey;
+  for (idx=0;;)
+    {
+      int is_enc;
+
+      value = gcry_sexp_nth_data (list, ++idx, &valuelen);
+      if (!value && skeyidx >= npkey)
+        break;  /* Ready.  */
+
+      /* Check for too many parameters.  Note that depending on the
+         protection mode and version number we may see less than NSKEY
+         (but at least NPKEY+1) parameters.  */
+      if (idx >= 2*nskey)
+        goto bad_seckey;
+      if (skeyidx >= DIM (skey)-1)
+        goto bad_seckey;
+
+      if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
+        goto bad_seckey;
+      is_enc = (value[0] == 'e');
+      value = gcry_sexp_nth_data (list, ++idx, &valuelen);
+      if (!value || !valuelen)
+        goto bad_seckey;
+      if (is_enc)
+        {
+          void *p = xtrymalloc (valuelen);
+          if (!p)
+            goto outofmem;
+          memcpy (p, value, valuelen);
+          skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
+          if (!skey[skeyidx])
+            goto outofmem;
+        }
+      else
+        {
+          if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
+                             value, valuelen, NULL))
+            goto bad_seckey;
+        }
+      skeyidx++;
+    }
+  skey[skeyidx++] = NULL;
+
+  gcry_sexp_release (list); list = NULL;
+
+  /* We have no need for the CSUM value thus we don't parse it.  */
+  /* list = gcry_sexp_find_token (top_list, "csum", 0); */
+  /* if (list) */
+  /*   { */
+  /*     string = gcry_sexp_nth_string (list, 1); */
+  /*     if (!string) */
+  /*       goto bad_seckey; */
+  /*     desired_csum = strtoul (string, NULL, 10); */
+  /*     xfree (string); */
+  /*   } */
+  /* else */
+  /*   desired_csum = 0; */
+  /* gcry_sexp_release (list); list = NULL; */
+
+  /* Get the curve name if any,  */
+  list = gcry_sexp_find_token (top_list, "curve", 0);
+  if (list)
+    {
+      curve = gcry_sexp_nth_string (list, 1);
+      gcry_sexp_release (list); list = NULL;
+    }
+
+  gcry_sexp_release (top_list); top_list = NULL;
+
+  /* log_debug ("XXX is_v4=%d\n", is_v4); */
+  /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
+  /* log_debug ("XXX is_protected=%d\n", is_protected); */
+  /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
+  /* log_printhex ("XXX iv", iv, ivlen); */
+  /* log_debug ("XXX ivlen=%d\n", ivlen); */
+  /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
+  /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
+  /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
+  /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
+  /* for (idx=0; skey[idx]; idx++) */
+  /*   { */
+  /*     int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
+  /*     log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
+  /*     if (is_enc) */
+  /*       { */
+  /*         void *p; */
+  /*         unsigned int nbits; */
+  /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
+  /*         log_printhex (NULL, p, (nbits+7)/8); */
+  /*       } */
+  /*     else */
+  /*       gcry_mpi_dump (skey[idx]); */
+  /*     log_printf ("\n"); */
+  /*   } */
+
+  if (!is_v4 || is_protected != 2 )
+    {
+      /* We only support the v4 format and a SHA-1 checksum.  */
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      goto leave;
+    }
+
+  /* We need to change the received parameters for ECC algorithms.
+     The transfer format has the curve name and the parameters
+     separate.  We put them all into the SKEY array.  */
+  if (canon_pk_algo (pk_algo) == GCRY_PK_ECC)
+    {
+      const char *oidstr;
+
+      /* Assert that all required parameters are available.  We also
+         check that the array does not contain more parameters than
+         needed (this was used by some beta versions of 2.1.  */
+      if (!curve || !skey[0] || !skey[1] || skey[2])
+        {
+          err = gpg_error (GPG_ERR_INTERNAL);
+          goto leave;
+        }
+
+      oidstr = openpgp_curve_to_oid (curve, NULL);
+      if (!oidstr)
+        {
+          log_error ("no OID known for curve '%s'\n", curve);
+          err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
+          goto leave;
+        }
+      /* Put the curve's OID into into the MPI array.  This requires
+         that we shift Q and D.  For ECDH also insert the KDF parms. */
+      if (is_ecdh)
+        {
+          skey[4] = NULL;
+          skey[3] = skey[1];
+          skey[2] = gcry_mpi_copy (pk->pkey[2]);
+        }
+      else
+        {
+          skey[3] = NULL;
+          skey[2] = skey[1];
+        }
+      skey[1] = skey[0];
+      skey[0] = NULL;
+      err = openpgp_oid_from_str (oidstr, skey + 0);
+      if (err)
+        goto leave;
+      /* Fixup the NPKEY and NSKEY to match OpenPGP reality.  */
+      npkey = 2 + is_ecdh;
+      nskey = 3 + is_ecdh;
+
+      /* for (idx=0; skey[idx]; idx++) */
+      /*   { */
+      /*     log_info ("YYY skey[%d]:", idx); */
+      /*     if (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)) */
+      /*       { */
+      /*         void *p; */
+      /*         unsigned int nbits; */
+      /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
+      /*         log_printhex (NULL, p, (nbits+7)/8); */
+      /*       } */
+      /*     else */
+      /*       gcry_mpi_dump (skey[idx]); */
+      /*     log_printf ("\n"); */
+      /*   } */
+    }
+
+  /* Do some sanity checks.  */
+  if (s2k_count > 255)
+    {
+      /* We expect an already encoded S2K count.  */
+      err = gpg_error (GPG_ERR_INV_DATA);
+      goto leave;
+    }
+  err = openpgp_cipher_test_algo (protect_algo);
+  if (err)
+    goto leave;
+  err = openpgp_md_test_algo (s2k_algo);
+  if (err)
+    goto leave;
+
+  /* Check that the public key parameters match.  Note that since
+     Libgcrypt 1.5 gcry_mpi_cmp handles opaque MPI correctly.  */
+  for (idx=0; idx < npkey; idx++)
+    if (gcry_mpi_cmp (pk->pkey[idx], skey[idx]))
+      {
+        err = gpg_error (GPG_ERR_BAD_PUBKEY);
+        goto leave;
+      }
+
+  /* Check that the first secret key parameter in SKEY is encrypted
+     and that there are no more secret key parameters.  The latter is
+     guaranteed by the v4 packet format.  */
+  if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE))
+    goto bad_seckey;
+  if (npkey+1 < DIM (skey) && skey[npkey+1])
+    goto bad_seckey;
+
+  /* Check that the secret key parameters in PK are all set to NULL. */
+  for (idx=npkey; idx < nskey; idx++)
+    if (pk->pkey[idx])
+      goto bad_seckey;
+
+  /* Now build the protection info. */
+  pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
+  if (!ski)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  ski->is_protected = 1;
+  ski->sha1chk = 1;
+  ski->algo = protect_algo;
+  ski->s2k.mode = s2k_mode;
+  ski->s2k.hash_algo = s2k_algo;
+  assert (sizeof ski->s2k.salt == sizeof s2k_salt);
+  memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt);
+  ski->s2k.count = s2k_count;
+  assert (ivlen <= sizeof ski->iv);
+  memcpy (ski->iv, iv, ivlen);
+  ski->ivlen = ivlen;
+
+  /* Store the protected secret key parameter.  */
+  pk->pkey[npkey] = skey[npkey];
+  skey[npkey] = NULL;
+
+  /* That's it.  */
+
+ leave:
+  gcry_free (curve);
+  gcry_sexp_release (list);
+  gcry_sexp_release (top_list);
+  for (idx=0; idx < skeyidx; idx++)
+    gcry_mpi_release (skey[idx]);
+  return err;
+
+ bad_seckey:
+  err = gpg_error (GPG_ERR_BAD_SECKEY);
+  goto leave;
+
+ outofmem:
+  err = gpg_error (GPG_ERR_ENOMEM);
+  goto leave;
+}
+
+/* Export the keys identified by the list of strings in USERS to the
+   stream OUT.  If Secret is false public keys will be exported.  With
+   secret true secret keys will be exported; in this case 1 means the
+   entire secret keyblock and 2 only the subkeys.  OPTIONS are the
+   export options to apply.  If KEYBLOCK_OUT is not NULL, AND the exit
+   code is zero, a pointer to the first keyblock found and exported
+   will be stored at this address; no other keyblocks are exported in
+   this case.  The caller must free it the returned keyblock.  If any
+   key has been exported true is stored at ANY. */
 static int
-do_export_stream( IOBUF out, strlist_t users, int secret,
-                 KBNODE *keyblock_out, unsigned int options, int *any )
+do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
+                 kbnode_t *keyblock_out, unsigned int options, int *any)
 {
-    int rc = 0;
-    PACKET pkt;
-    KBNODE keyblock = NULL;
-    KBNODE kbctx, node;
-    size_t ndesc, descindex;
-    KEYDB_SEARCH_DESC *desc = NULL;
-    subkey_list_t subkey_list = NULL;  /* Track alreay processed subkeys. */
-    KEYDB_HANDLE kdbhd;
-    strlist_t sl;
-    int indent = 0;
-
-    *any = 0;
-    init_packet( &pkt );
-    kdbhd = keydb_new (secret);
-
-    if (!users) {
-        ndesc = 1;
-        desc = xcalloc ( ndesc, sizeof *desc );
-        desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
+  gpg_error_t err = 0;
+  PACKET pkt;
+  KBNODE keyblock = NULL;
+  KBNODE kbctx, node;
+  size_t ndesc, descindex;
+  KEYDB_SEARCH_DESC *desc = NULL;
+  subkey_list_t subkey_list = NULL;  /* Track already processed subkeys. */
+  KEYDB_HANDLE kdbhd;
+  strlist_t sl;
+  int indent = 0;
+  gcry_cipher_hd_t cipherhd = NULL;
+  char *cache_nonce = NULL;
+
+  *any = 0;
+  init_packet (&pkt);
+  kdbhd = keydb_new ();
+
+  if (!users)
+    {
+      ndesc = 1;
+      desc = xcalloc (ndesc, sizeof *desc);
+      desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
     }
-    else {
-        for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) 
-            ;
-        desc = xmalloc ( ndesc * sizeof *desc);
-        
-        for (ndesc=0, sl=users; sl; sl = sl->next) {
-           if (classify_user_id (sl->d, desc+ndesc))
-                ndesc++;
-            else
-                log_error (_("key \"%s\" not found: %s\n"),
-                           sl->d, g10_errstr (G10ERR_INV_USER_ID));
+  else
+    {
+      for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
+        ;
+      desc = xmalloc ( ndesc * sizeof *desc);
+
+      for (ndesc=0, sl=users; sl; sl = sl->next)
+        {
+          if (!(err=classify_user_id (sl->d, desc+ndesc, 1)))
+            ndesc++;
+          else
+            log_error (_("key \"%s\" not found: %s\n"),
+                       sl->d, gpg_strerror (err));
         }
 
-        /* It would be nice to see which of the given users did
-           actually match one in the keyring.  To implement this we
-           need to have a found flag for each entry in desc and to set
-           this we must check all those entries after a match to mark
-           all matched one - currently we stop at the first match.  To
-           do this we need an extra flag to enable this feature so */
+      /* It would be nice to see which of the given users did actually
+         match one in the keyring.  To implement this we need to have
+         a found flag for each entry in desc.  To set this flag we
+         must check all those entries after a match to mark all
+         matched one - currently we stop at the first match.  To do
+         this we need an extra flag to enable this feature.  */
     }
 
 #ifdef ENABLE_SELINUX_HACKS
-    if (secret) {
-        log_error (_("exporting secret keys not allowed\n"));
-        rc = G10ERR_GENERAL;
-        goto leave;
+  if (secret)
+    {
+      log_error (_("exporting secret keys not allowed\n"));
+      err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      goto leave;
     }
 #endif
 
-    while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) {
-        int sha1_warned=0,skip_until_subkey=0;
-       u32 sk_keyid[2];
+  /* For secret key export we need to setup a decryption context.  */
+  if (secret)
+    {
+      void *kek = NULL;
+      size_t keklen;
 
-       if (!users) 
-            desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+      err = agent_keywrap_key (ctrl, 1, &kek, &keklen);
+      if (err)
+        {
+          log_error ("error getting the KEK: %s\n", gpg_strerror (err));
+          goto leave;
+        }
 
-        /* Read the keyblock. */
-        rc = keydb_get_keyblock (kdbhd, &keyblock );
-       if( rc ) {
-            log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
-           goto leave;
-       }
+      /* Prepare a cipher context.  */
+      err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
+                              GCRY_CIPHER_MODE_AESWRAP, 0);
+      if (!err)
+        err = gcry_cipher_setkey (cipherhd, kek, keklen);
+      if (err)
+        {
+          log_error ("error setting up an encryption context: %s\n",
+                     gpg_strerror (err));
+          goto leave;
+        }
+      xfree (kek);
+      kek = NULL;
+    }
 
-       if((node=find_kbnode(keyblock,PKT_SECRET_KEY)))
-         {
-           PKT_secret_key *sk=node->pkt->pkt.secret_key;
-
-           keyid_from_sk(sk,sk_keyid);
-
-           /* We can't apply GNU mode 1001 on an unprotected key. */
-           if( secret == 2 && !sk->is_protected )
-             {
-               log_info(_("key %s: not protected - skipped\n"),
-                        keystr(sk_keyid));
-               continue;
-             }
-
-           /* No v3 keys with GNU mode 1001. */
-           if( secret == 2 && sk->version == 3 )
-             {
-               log_info(_("key %s: PGP 2.x style key - skipped\n"),
-                        keystr(sk_keyid));
-               continue;
-             }
-
-            /* It does not make sense to export a key with a primary
-               key on card using a non-key stub.  We simply skip those
-               keys when used with --export-secret-subkeys. */
-            if (secret == 2 && sk->is_protected
-                && sk->protect.s2k.mode == 1002 ) 
-              {
-               log_info(_("key %s: key material on-card - skipped\n"),
-                        keystr(sk_keyid));
-               continue;
-              }
-         }
-       else
-         {
-           /* It's a public key export, so do the cleaning if
-              requested.  Note that both export-clean and
-              export-minimal only apply to UID sigs (0x10, 0x11,
-              0x12, and 0x13).  A designated revocation is never
-              stripped, even with export-minimal set. */
-
-           if(options&EXPORT_CLEAN)
-             clean_key(keyblock,opt.verbose,options&EXPORT_MINIMAL,NULL,NULL);
-         }
-
-       /* And write it. */
-       for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
-           if( skip_until_subkey )
-             {
-               if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
-                  || node->pkt->pkttype==PKT_SECRET_SUBKEY)
-                 skip_until_subkey=0;
-               else
-                 continue;
-             }
-
-           /* We used to use comment packets, but not any longer.  In
-              case we still have comments on a key, strip them here
-              before we call build_packet(). */
-           if( node->pkt->pkttype == PKT_COMMENT )
-             continue;
+  while (!(err = keydb_search (kdbhd, desc, ndesc, &descindex)))
+    {
+      int skip_until_subkey = 0;
+      u32 keyid[2];
+      PKT_public_key *pk;
+
+      if (!users)
+        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+
+      /* Read the keyblock. */
+      release_kbnode (keyblock);
+      keyblock = NULL;
+      err = keydb_get_keyblock (kdbhd, &keyblock);
+      if (err)
+        {
+          log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
+          goto leave;
+       }
 
-            /* Make sure that ring_trust packets never get exported. */
-            if (node->pkt->pkttype == PKT_RING_TRUST)
+      node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+      if (!node)
+        {
+          log_error ("public key packet not found in keyblock - skipped\n");
+          continue;
+        }
+      setup_main_keyids (keyblock);  /* gpg_format_keydesc needs it.  */
+      pk = node->pkt->pkt.public_key;
+      keyid_from_pk (pk, keyid);
+
+      /* If a secret key export is required we need to check whether
+         we have a secret key at all and if so create the seckey_info
+         structure.  */
+      if (secret)
+        {
+          if (agent_probe_any_secret_key (ctrl, keyblock))
+            continue;  /* No secret key (neither primary nor subkey).  */
+
+          /* No v3 keys with GNU mode 1001. */
+          if (secret == 2 && pk->version == 3)
+            {
+              log_info (_("key %s: PGP 2.x style key - skipped\n"),
+                        keystr (keyid));
+              continue;
+            }
+
+          /* The agent does not yet allow to export v3 packets.  It is
+             actually questionable whether we should allow them at
+             all.  */
+          if (pk->version == 3)
+            {
+              log_info ("key %s: PGP 2.x style key (v3) export "
+                        "not yet supported - skipped\n", keystr (keyid));
               continue;
+            }
+        }
 
-           /* If exact is set, then we only export what was requested
-              (plus the primary key, if the user didn't specifically
-              request it). */
-           if(desc[descindex].exact
-              && (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
-                  || node->pkt->pkttype==PKT_SECRET_SUBKEY))
-             {
-                if (!exact_subkey_match_p (desc+descindex, node))
-                  {
-                    /* Before skipping this subkey, check whether any
-                       other description wants an exact match on a
-                       subkey and include that subkey into the output
-                       too.  Need to add this subkey to a list so that
-                       it won't get processed a second time.
-                   
-                       So the first step here is to check that list and
-                       skip in any case if the key is in that list.
-
-                       We need this whole mess because the import
-                       function is not able to merge secret keys and
-                       thus it is useless to output them as two
-                       separate keys and have import merge them.  */
-                    if (subkey_in_list_p (subkey_list, node))  
-                      skip_until_subkey = 1; /* Already processed this one. */
-                    else
-                      {
-                        size_t j;
-
-                        for (j=0; j < ndesc; j++)
-                          if (j != descindex && desc[j].exact
-                              && exact_subkey_match_p (desc+j, node))
-                            break;
-                        if (!(j < ndesc))
-                          skip_until_subkey = 1; /* No other one matching. */ 
-                      }
-                  }
+      /* Always do the cleaning on the public key part if requested.
+         Note that we don't yet set this option if we are exporting
+         secret keys.  Note that both export-clean and export-minimal
+         only apply to UID sigs (0x10, 0x11, 0x12, and 0x13).  A
+         designated revocation is never stripped, even with
+         export-minimal set.  */
+      if ((options & EXPORT_CLEAN))
+        clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
+
+      /* And write it. */
+      xfree (cache_nonce);
+      cache_nonce = NULL;
+      for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
+        {
+          if (skip_until_subkey)
+            {
+              if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+                skip_until_subkey = 0;
+              else
+                continue;
+            }
+
+          /* We used to use comment packets, but not any longer.  In
+             case we still have comments on a key, strip them here
+             before we call build_packet(). */
+          if (node->pkt->pkttype == PKT_COMMENT)
+            continue;
+
+          /* Make sure that ring_trust packets never get exported. */
+          if (node->pkt->pkttype == PKT_RING_TRUST)
+            continue;
+
+          /* If exact is set, then we only export what was requested
+             (plus the primary key, if the user didn't specifically
+             request it). */
+          if (desc[descindex].exact
+              && node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+            {
+              if (!exact_subkey_match_p (desc+descindex, node))
+                {
+                  /* Before skipping this subkey, check whether any
+                     other description wants an exact match on a
+                     subkey and include that subkey into the output
+                     too.  Need to add this subkey to a list so that
+                     it won't get processed a second time.
+
+                     So the first step here is to check that list and
+                     skip in any case if the key is in that list.
+
+                     We need this whole mess because the import
+                     function of GnuPG < 2.1 is not able to merge
+                     secret keys and thus it is useless to output them
+                     as two separate keys and have import merge them.  */
+                  if (subkey_in_list_p (subkey_list, node))
+                    skip_until_subkey = 1; /* Already processed this one. */
+                  else
+                    {
+                      size_t j;
+
+                      for (j=0; j < ndesc; j++)
+                        if (j != descindex && desc[j].exact
+                            && exact_subkey_match_p (desc+j, node))
+                          break;
+                      if (!(j < ndesc))
+                        skip_until_subkey = 1; /* No other one matching. */
+                    }
+                }
 
-               if(skip_until_subkey)
-                 continue;
+              if(skip_until_subkey)
+                continue;
 
-                /* Mark this one as processed. */
+              /* Mark this one as processed. */
+              {
+                subkey_list_t tmp = new_subkey_list_item (node);
+                tmp->next = subkey_list;
+                subkey_list = tmp;
+              }
+            }
+
+          if (node->pkt->pkttype == PKT_SIGNATURE)
+            {
+              /* Do not export packets which are marked as not
+                 exportable.  */
+              if (!(options&EXPORT_LOCAL_SIGS)
+                  && !node->pkt->pkt.signature->flags.exportable)
+                continue; /* not exportable */
+
+              /* Do not export packets with a "sensitive" revocation
+                 key unless the user wants us to.  Note that we do
+                 export these when issuing the actual revocation
+                 (see revoke.c). */
+              if (!(options&EXPORT_SENSITIVE_REVKEYS)
+                  && node->pkt->pkt.signature->revkey)
                 {
-                  subkey_list_t tmp = new_subkey_list_item (node);
-                  tmp->next = subkey_list;
-                  subkey_list = tmp;
+                  int i;
+
+                  for (i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
+                    if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40))
+                      break;
+
+                  if (i < node->pkt->pkt.signature->numrevkeys)
+                    continue;
                 }
-             }
-
-           if(node->pkt->pkttype==PKT_SIGNATURE)
-             {
-               /* do not export packets which are marked as not
-                  exportable */
-               if(!(options&EXPORT_LOCAL_SIGS)
-                  && !node->pkt->pkt.signature->flags.exportable)
-                 continue; /* not exportable */
-
-               /* Do not export packets with a "sensitive" revocation
-                  key unless the user wants us to.  Note that we do
-                  export these when issuing the actual revocation
-                  (see revoke.c). */
-               if(!(options&EXPORT_SENSITIVE_REVKEYS)
-                  && node->pkt->pkt.signature->revkey)
-                 {
-                   int i;
-
-                   for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
-                     if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
-                       break;
-
-                   if(i<node->pkt->pkt.signature->numrevkeys)
-                     continue;
-                 }
-             }
-
-           /* Don't export attribs? */
-           if( !(options&EXPORT_ATTRIBUTES) &&
-               node->pkt->pkttype == PKT_USER_ID &&
-               node->pkt->pkt.user_id->attrib_data ) {
+            }
+
+          /* Don't export attribs? */
+          if (!(options&EXPORT_ATTRIBUTES)
+              && node->pkt->pkttype == PKT_USER_ID
+              && node->pkt->pkt.user_id->attrib_data )
+            {
              /* Skip until we get to something that is not an attrib
                 or a signature on an attrib */
-             while(kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) {
-               kbctx=kbctx->next;
-             }
+             while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE)
+                kbctx = kbctx->next;
+
              continue;
            }
 
-           if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY )
-             {
-               /* We don't want to export the secret parts of the
-                * primary key, this is done by using GNU protection mode 1001
-                */
-               int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
-               node->pkt->pkt.secret_key->protect.s2k.mode = 1001;
-                if ((options&EXPORT_SEXP_FORMAT))
-                  rc = build_sexp (out, node->pkt, &indent);
-                else
-                  rc = build_packet (out, node->pkt);
-               node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
-             }
-           else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY
-                     && (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD))
-              {
-                /* If the subkey is protected reset the passphrase to
-                   export an unprotected subkey.  This feature is
-                   useful in cases of a subkey copied to an unattended
-                   machine where a passphrase is not required. */
-                PKT_secret_key *sk_save, *sk;
-
-                sk_save = node->pkt->pkt.secret_key;
-                sk = copy_secret_key (NULL, sk_save);
-                node->pkt->pkt.secret_key = sk;
-
-                log_info (_("about to export an unprotected subkey\n"));
-                switch (is_secret_key_protected (sk))
-                  {
-                  case -1:
-                    rc = G10ERR_PUBKEY_ALGO;
-                    break;
-                  case 0:
-                    break;
-                  default:
-                    if (sk->protect.s2k.mode == 1001)
-                      ; /* No secret parts. */
-                    else if( sk->protect.s2k.mode == 1002 ) 
-                      ; /* Card key stub. */
-                    else 
-                      {
-                        rc = check_secret_key( sk, 0 );
-                      }
-                    break;
-                  }
-                if (rc)
+          if (secret && (node->pkt->pkttype == PKT_PUBLIC_KEY
+                         || node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
+            {
+              u32 subkidbuf[2], *subkid;
+              char *hexgrip, *serialno;
+
+              pk = node->pkt->pkt.public_key;
+              if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+                subkid = NULL;
+              else
+                {
+                  keyid_from_pk (pk, subkidbuf);
+                  subkid = subkidbuf;
+                }
+
+              if (pk->seckey_info)
+                {
+                  log_error ("key %s: oops: seckey_info already set"
+                             " - skipped\n", keystr_with_sub (keyid, subkid));
+                  skip_until_subkey = 1;
+                  continue;
+                }
+
+              err = hexkeygrip_from_pk (pk, &hexgrip);
+              if (err)
+                {
+                  log_error ("key %s: error computing keygrip: %s"
+                             " - skipped\n", keystr_with_sub (keyid, subkid),
+                             gpg_strerror (err));
+                  skip_until_subkey = 1;
+                  err = 0;
+                  continue;
+                }
+
+              if (secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
+                {
+                  /* We are asked not to export the secret parts of
+                     the primary key.  Make up an error code to create
+                     the stub.  */
+                  err = GPG_ERR_NOT_FOUND;
+                  serialno = NULL;
+                }
+              else
+                err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
+
+              if ((!err && serialno)
+                  && secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
+                {
+                  /* It does not make sense to export a key with its
+                     primary key on card using a non-key stub.  Thus
+                     we skip those keys when used with
+                     --export-secret-subkeys. */
+                  log_info (_("key %s: key material on-card - skipped\n"),
+                            keystr_with_sub (keyid, subkid));
+                  skip_until_subkey = 1;
+                }
+              else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND
+                       || (!err && serialno))
+                {
+                  /* Create a key stub.  */
+                  struct seckey_info *ski;
+                  const char *s;
+
+                  pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
+                  if (!ski)
+                    {
+                      err = gpg_error_from_syserror ();
+                      xfree (hexgrip);
+                      goto leave;
+                    }
+
+                  ski->is_protected = 1;
+                  if (err)
+                    ski->s2k.mode = 1001; /* GNU dummy (no secret key).  */
+                  else
+                    {
+                      ski->s2k.mode = 1002; /* GNU-divert-to-card.  */
+                      for (s=serialno; sizeof (ski->ivlen) && *s && s[1];
+                           ski->ivlen++, s += 2)
+                        ski->iv[ski->ivlen] = xtoi_2 (s);
+                    }
+
+                  if ((options&EXPORT_SEXP_FORMAT))
+                    err = build_sexp (out, node->pkt, &indent);
+                  else
+                    err = build_packet (out, node->pkt);
+                }
+              else if (!err)
+                {
+                  /* FIXME: Move this spaghetti code into a separate
+                     function.  */
+                  unsigned char *wrappedkey = NULL;
+                  size_t wrappedkeylen;
+                  unsigned char *key = NULL;
+                  size_t keylen, realkeylen;
+                  gcry_sexp_t s_skey;
+
+                  if (opt.verbose)
+                    log_info ("key %s: asking agent for the secret parts\n",
+                              keystr_with_sub (keyid, subkid));
+
                   {
-                    node->pkt->pkt.secret_key = sk_save;
-                    free_secret_key (sk);
-                    log_error (_("failed to unprotect the subkey: %s\n"),
-                               g10_errstr (rc));
-                    goto leave;
+                    char *prompt = gpg_format_keydesc (pk,
+                                                       FORMAT_KEYDESC_EXPORT,1);
+                    err = agent_export_key (ctrl, hexgrip, prompt, &cache_nonce,
+                                            &wrappedkey, &wrappedkeylen);
+                    xfree (prompt);
                   }
+                  if (err)
+                    goto unwraperror;
+                  if (wrappedkeylen < 24)
+                    {
+                      err = gpg_error (GPG_ERR_INV_LENGTH);
+                      goto unwraperror;
+                    }
+                  keylen = wrappedkeylen - 8;
+                  key = xtrymalloc_secure (keylen);
+                  if (!key)
+                    {
+                      err = gpg_error_from_syserror ();
+                      goto unwraperror;
+                    }
+                  err = gcry_cipher_decrypt (cipherhd, key, keylen,
+                                             wrappedkey, wrappedkeylen);
+                  if (err)
+                    goto unwraperror;
+                  realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
+                  if (!realkeylen)
+                    goto unwraperror; /* Invalid csexp.  */
+
+                  err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
+                  xfree (key);
+                  key = NULL;
+                  if (err)
+                    goto unwraperror;
+                  err = transfer_format_to_openpgp (s_skey, pk);
+                  gcry_sexp_release (s_skey);
+                  if (err)
+                    goto unwraperror;
+
+                  if ((options&EXPORT_SEXP_FORMAT))
+                    err = build_sexp (out, node->pkt, &indent);
+                  else
+                    err = build_packet (out, node->pkt);
+                  goto unwraperror_leave;
+
+                unwraperror:
+                  xfree (wrappedkey);
+                  xfree (key);
+                  if (err)
+                    {
+                      log_error ("key %s: error receiving key from agent:"
+                                 " %s%s\n",
+                                 keystr_with_sub (keyid, subkid),
+                                 gpg_strerror (err),
+                                 gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
+                                 "":_(" - skipped"));
+                      if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+                        goto leave;
+                      skip_until_subkey = 1;
+                      err = 0;
+                    }
+                unwraperror_leave:
+                  ;
+                }
+              else
+                {
+                  log_error ("key %s: error getting keyinfo from agent: %s"
+                             " - skipped\n", keystr_with_sub (keyid, subkid),
+                             gpg_strerror (err));
+                  skip_until_subkey = 1;
+                  err = 0;
+                }
 
-                if ((options&EXPORT_SEXP_FORMAT))
-                  rc = build_sexp (out, node->pkt, &indent);
-                else
-                  rc = build_packet (out, node->pkt);
-
-                node->pkt->pkt.secret_key = sk_save;
-                free_secret_key (sk);
-              }
-           else
-             {
-               /* Warn the user if the secret key or any of the secret
-                  subkeys are protected with SHA1 and we have
-                  simple_sk_checksum set. */
-               if(!sha1_warned && opt.simple_sk_checksum &&
-                  (node->pkt->pkttype==PKT_SECRET_KEY ||
-                   node->pkt->pkttype==PKT_SECRET_SUBKEY) &&
-                  node->pkt->pkt.secret_key->protect.sha1chk)
-                 {
-                   /* I hope this warning doesn't confuse people. */
-                   log_info(_("WARNING: secret key %s does not have a "
-                              "simple SK checksum\n"),keystr(sk_keyid));
-
-                   sha1_warned=1;
-                 }
-
-                if ((options&EXPORT_SEXP_FORMAT))
-                  rc = build_sexp (out, node->pkt, &indent);
-                else
-                  rc = build_packet (out, node->pkt);
-             }
-
-           if( rc ) {
-               log_error("build_packet(%d) failed: %s\n",
-                           node->pkt->pkttype, g10_errstr(rc) );
-               goto leave;
+              xfree (pk->seckey_info);
+              pk->seckey_info = NULL;
+              xfree (hexgrip);
+            }
+          else
+            {
+              if ((options&EXPORT_SEXP_FORMAT))
+                err = build_sexp (out, node->pkt, &indent);
+              else
+                err = build_packet (out, node->pkt);
+            }
+
+          if (err)
+            {
+              log_error ("build_packet(%d) failed: %s\n",
+                         node->pkt->pkttype, gpg_strerror (err));
+              goto leave;
            }
+
+          if (!skip_until_subkey)
+            *any = 1;
        }
 
-        if ((options&EXPORT_SEXP_FORMAT) && indent)
-          {
-            for (; indent; indent--)
-              iobuf_put (out, ')');
-            iobuf_put (out, '\n');
-          }
-
-       ++*any;
-       if(keyblock_out)
-         {
-           *keyblock_out=keyblock;
-           break;
-         }
+      if ((options&EXPORT_SEXP_FORMAT) && indent)
+        {
+          for (; indent; indent--)
+            iobuf_put (out, ')');
+          iobuf_put (out, '\n');
+        }
+
+      if (keyblock_out)
+        {
+          *keyblock_out = keyblock;
+          break;
+        }
     }
-    if ((options&EXPORT_SEXP_FORMAT) && indent)
-      {
-        for (; indent; indent--)
-          iobuf_put (out, ')');
-        iobuf_put (out, '\n');
-      }
-    if( rc == -1 )
-       rc = 0;
-
-  leave:
-    release_subkey_list (subkey_list);
-    xfree(desc);
-    keydb_release (kdbhd);
-    if(rc || keyblock_out==NULL)
-      release_kbnode( keyblock );
-    if( !*any )
-       log_info(_("WARNING: nothing exported\n"));
-    return rc;
+  if ((options&EXPORT_SEXP_FORMAT) && indent)
+    {
+      for (; indent; indent--)
+        iobuf_put (out, ')');
+      iobuf_put (out, '\n');
+    }
+  if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+    err = 0;
+
+ leave:
+  gcry_cipher_close (cipherhd);
+  release_subkey_list (subkey_list);
+  xfree(desc);
+  keydb_release (kdbhd);
+  if (err || !keyblock_out)
+    release_kbnode( keyblock );
+  xfree (cache_nonce);
+  if( !*any )
+    log_info(_("WARNING: nothing exported\n"));
+  return err;
 }
 
 
 
-static int
-write_sexp_line (iobuf_t out, int *indent, const char *text)
-{
-  int i;
+/* static int */
+/* write_sexp_line (iobuf_t out, int *indent, const char *text) */
+/* { */
+/*   int i; */
 
-  for (i=0; i < *indent; i++)
-    iobuf_put (out, ' ');
-  iobuf_writestr (out, text);
-  return 0;
-}
+/*   for (i=0; i < *indent; i++) */
+/*     iobuf_put (out, ' '); */
+/*   iobuf_writestr (out, text); */
+/*   return 0; */
+/* } */
 
-static int
-write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a)
-{
-  int rc;
-  unsigned char *buffer;
+/* static int */
+/* write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a) */
+/* { */
+/*   int rc; */
+/*   unsigned char *buffer; */
 
-  write_sexp_line (out, indent, "(");
-  iobuf_writestr (out, name);
-  iobuf_writestr (out, " #");
+/*   write_sexp_line (out, indent, "("); */
+/*   iobuf_writestr (out, name); */
+/*   iobuf_writestr (out, " #"); */
 
-  rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a);
-  assert (!rc);
-  iobuf_writestr (out, buffer);
-  iobuf_writestr (out, "#)");
-  gcry_free (buffer);
-  return 0;
-}
+/*   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a); */
+/*   assert (!rc); */
+/*   iobuf_writestr (out, buffer); */
+/*   iobuf_writestr (out, "#)"); */
+/*   gcry_free (buffer); */
+/*   return 0; */
+/* } */
 
 static int
 build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
 {
-  PKT_secret_key *sk = pkt->pkt.secret_key;
-  char tmpbuf[100];
-
-  if (pkt->pkttype == PKT_SECRET_KEY)
-    {
-      iobuf_writestr (out, "(openpgp-key\n");
-      (*indent)++;
-    }
-  else
-    {
-      iobuf_writestr (out, " (subkey\n");
-      (*indent)++;
-    }
-  (*indent)++;
-  write_sexp_line (out, indent, "(private-key\n");
-  (*indent)++;
-  if (is_RSA (sk->pubkey_algo) && !sk->is_protected)
-    {
-      write_sexp_line (out, indent, "(rsa\n");
-      (*indent)++;
-      write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "u", sk->skey[5]); 
-      iobuf_put (out,')'); iobuf_put (out,'\n');
-      (*indent)--;
-    }
-  else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected)
-    {
-      write_sexp_line (out, indent, "(dsa\n");
-      (*indent)++;
-      write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "x", sk->skey[4]);
-      iobuf_put (out,')'); iobuf_put (out,'\n');
-      (*indent)--;
-    }
-  else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected)
-    {
-      write_sexp_line (out, indent, "(elg\n");
-      (*indent)++;
-      write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "x", sk->skey[4]);
-      iobuf_put (out,')'); iobuf_put (out,'\n');
-      (*indent)--;
-    }
-  write_sexp_line (out, indent,  "(attrib\n"); (*indent)++;
-  sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp);
-  write_sexp_line (out, indent, tmpbuf);
-  iobuf_put (out,')'); (*indent)--; /* close created */
-  iobuf_put (out,')'); (*indent)--; /* close attrib */
-  iobuf_put (out,')'); (*indent)--; /* close private-key */
-  if (pkt->pkttype != PKT_SECRET_KEY)
-    iobuf_put (out,')'), (*indent)--; /* close subkey */
-  iobuf_put (out,'\n');
-
-  return 0;
+  (void)out;
+  (void)pkt;
+  (void)indent;
+
+  /* FIXME: Not yet implemented.  */
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  /* PKT_secret_key *sk = pkt->pkt.secret_key; */
+  /* char tmpbuf[100]; */
+
+  /* if (pkt->pkttype == PKT_SECRET_KEY) */
+  /*   { */
+  /*     iobuf_writestr (out, "(openpgp-key\n"); */
+  /*     (*indent)++; */
+  /*   } */
+  /* else */
+  /*   { */
+  /*     iobuf_writestr (out, " (subkey\n"); */
+  /*     (*indent)++; */
+  /*   } */
+  /* (*indent)++; */
+  /* write_sexp_line (out, indent, "(private-key\n"); */
+  /* (*indent)++; */
+  /* if (is_RSA (sk->pubkey_algo) && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(rsa\n"); */
+  /*     (*indent)++; */
+  /*     write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "u", sk->skey[5]);  */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
+  /* else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(dsa\n"); */
+  /*     (*indent)++; */
+  /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
+  /* else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(ecdsa\n"); */
+  /*     (*indent)++;  */
+  /*     write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "d", sk->skey[7]); */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
+  /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(elg\n"); */
+  /*     (*indent)++; */
+  /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
+  /* write_sexp_line (out, indent,  "(attrib\n"); (*indent)++; */
+  /* sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp); */
+  /* write_sexp_line (out, indent, tmpbuf); */
+  /* iobuf_put (out,')'); (*indent)--; /\* close created *\/ */
+  /* iobuf_put (out,')'); (*indent)--; /\* close attrib *\/ */
+  /* iobuf_put (out,')'); (*indent)--; /\* close private-key *\/ */
+  /* if (pkt->pkttype != PKT_SECRET_KEY) */
+  /*   iobuf_put (out,')'), (*indent)--; /\* close subkey *\/ */
+  /* iobuf_put (out,'\n'); */
+
+  /* return 0; */
 }
 
 
 /* For some packet types we write them in a S-expression format.  This
    is still EXPERIMENTAL and subject to change.  */
-static int 
+static int
 build_sexp (iobuf_t out, PACKET *pkt, int *indent)
 {
   int rc;
@@ -753,4 +1390,3 @@ build_sexp (iobuf_t out, PACKET *pkt, int *indent)
     }
   return rc;
 }
-
index 6bcb037..731ad0f 100644 (file)
@@ -21,7 +21,7 @@
 #define G10_FILTER_H
 
 #include "types.h"
-#include "cipher.h"
+#include "dek.h"
 
 typedef struct {
     gcry_md_hd_t md;      /* catch all */
@@ -39,8 +39,6 @@ typedef struct {
 
     /* these fields must be initialized to zero */
     int no_openpgp_data;    /* output flag: "No valid OpenPGP data found" */
-    int key_failed_code;    /* Error code from the first gpgkkeys_*
-                               "KEY <keyid> FAILED <err>" line.  */
 
     /* the following fields must be initialized to zero */
     int inp_checked;       /* set if the input has been checked */
@@ -154,7 +152,7 @@ int cipher_filter( void *opaque, int control,
 int text_filter( void *opaque, int control,
                 iobuf_t chain, byte *buf, size_t *ret_len);
 int copy_clearsig_text (iobuf_t out, iobuf_t inp, gcry_md_hd_t md,
-                        int escape_dash, int escape_from, int pgp2mode);
+                        int escape_dash, int escape_from);
 
 /*-- progress.c --*/
 progress_filter_context_t *new_progress_context (void);
index 9b42cfd..99e7404 100644 (file)
@@ -1,6 +1,6 @@
 /* free-packet.c - cleanup stuff for packets
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- *               2005  Free Software Foundation, Inc.
+ *               2005, 2010  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <assert.h>
 
 #include "gpg.h"
+#include "util.h"
 #include "packet.h"
 #include "../common/iobuf.h"
-#include "util.h"
-#include "cipher.h"
-#include "options.h" 
+#include "options.h"
 
 
 void
@@ -76,37 +75,60 @@ free_seckey_enc( PKT_signature *sig )
 
 
 void
-release_public_key_parts( PKT_public_key *pk )
+release_public_key_parts (PKT_public_key *pk)
 {
-    int n, i;
-    n = pubkey_get_npkey( pk->pubkey_algo );
-    if( !n )
-       mpi_release(pk->pkey[0]);
-    for(i=0; i < n; i++ ) {
-       mpi_release( pk->pkey[i] );
-       pk->pkey[i] = NULL;
+  int n, i;
+
+  if (pk->seckey_info)
+    n = pubkey_get_nskey (pk->pubkey_algo);
+  else
+    n = pubkey_get_npkey (pk->pubkey_algo);
+  if (!n)
+    mpi_release (pk->pkey[0]);
+  for (i=0; i < n; i++ )
+    {
+      mpi_release (pk->pkey[i]);
+      pk->pkey[i] = NULL;
+    }
+  if (pk->seckey_info)
+    {
+      xfree (pk->seckey_info);
+      pk->seckey_info = NULL;
     }
-    if (pk->prefs) {
-        xfree (pk->prefs);
-        pk->prefs = NULL;
+  if (pk->prefs)
+    {
+      xfree (pk->prefs);
+      pk->prefs = NULL;
+    }
+  if (pk->user_id)
+    {
+      free_user_id (pk->user_id);
+      pk->user_id = NULL;
     }
-    if (pk->user_id) {
-        free_user_id (pk->user_id);
-        pk->user_id = NULL;
+  if (pk->revkey)
+    {
+      xfree(pk->revkey);
+      pk->revkey=NULL;
+      pk->numrevkeys=0;
     }
-    if (pk->revkey) {
-        xfree(pk->revkey);
-       pk->revkey=NULL;
-       pk->numrevkeys=0;
+  if (pk->serialno)
+    {
+      xfree (pk->serialno);
+      pk->serialno = NULL;
     }
 }
 
 
+/* Free an allocated public key structure including all parts.
+   Passing NULL is allowed.  */
 void
-free_public_key( PKT_public_key *pk )
+free_public_key (PKT_public_key *pk)
 {
-    release_public_key_parts( pk );
-    xfree(pk);
+  if (pk)
+    {
+      release_public_key_parts (pk);
+      xfree(pk);
+    }
 }
 
 
@@ -125,7 +147,7 @@ cp_subpktarea (subpktarea_t *s )
 }
 
 /*
- * Return a copy of the preferences 
+ * Return a copy of the preferences
  */
 prefitem_t *
 copy_prefs (const prefitem_t *prefs)
@@ -135,7 +157,7 @@ copy_prefs (const prefitem_t *prefs)
 
     if (!prefs)
         return NULL;
-    
+
     for (n=0; prefs[n].type; n++)
         ;
     new = xmalloc ( sizeof (*new) * (n+1));
@@ -150,62 +172,52 @@ copy_prefs (const prefitem_t *prefs)
 }
 
 
+/* Copy the public key S to D.  If D is NULL allocate a new public key
+   structure.  If S has seckret key infos, only the public stuff is
+   copied.  */
 PKT_public_key *
-copy_public_key ( PKT_public_key *d, PKT_public_key *s)
+copy_public_key (PKT_public_key *d, PKT_public_key *s)
 {
-    int n, i;
+  int n, i;
 
-    if( !d )
-       d = xmalloc(sizeof *d);
-    memcpy( d, s, sizeof *d );
-    d->user_id = scopy_user_id (s->user_id);
-    d->prefs = copy_prefs (s->prefs);
-    n = pubkey_get_npkey( s->pubkey_algo );
-    if( !n )
-       d->pkey[0] = mpi_copy(s->pkey[0]);
-    else {
-       for(i=0; i < n; i++ )
-           d->pkey[i] = mpi_copy( s->pkey[i] );
+  if (!d)
+    d = xmalloc (sizeof *d);
+  memcpy (d, s, sizeof *d);
+  d->seckey_info = NULL;
+  d->user_id = scopy_user_id (s->user_id);
+  d->prefs = copy_prefs (s->prefs);
+
+  n = pubkey_get_npkey (s->pubkey_algo);
+  i = 0;
+  if (!n)
+    d->pkey[i++] = mpi_copy (s->pkey[0]);
+  else
+    {
+      for (; i < n; i++ )
+        d->pkey[i] = mpi_copy( s->pkey[i] );
     }
-    if( !s->revkey && s->numrevkeys )
-        BUG();
-    if( s->numrevkeys ) {
-        d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
-        memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
+  for (; i < PUBKEY_MAX_NSKEY; i++)
+    d->pkey[i] = NULL;
+
+  if (!s->revkey && s->numrevkeys)
+    BUG();
+  if (s->numrevkeys)
+    {
+      d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
+      memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
     }
-    else
-        d->revkey = NULL;
-    return d;
+  else
+    d->revkey = NULL;
+  return d;
 }
 
-/****************
- * Replace all common parts of a sk by the one from the public key.
- * This is a hack and a better solution will be to just store the real secret
- * parts somewhere and don't duplicate all the other stuff.
- */
-void
-copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
-    sk->expiredate  = pk->expiredate;     
-    sk->pubkey_algo = pk->pubkey_algo;    
-    sk->pubkey_usage= pk->pubkey_usage;
-    sk->req_usage   = pk->req_usage;
-    sk->req_algo    = pk->req_algo;
-    sk->has_expired = pk->has_expired;    
-    sk->is_revoked  = pk->is_revoked;     
-    sk->is_valid    = pk->is_valid;    
-    sk->main_keyid[0]= pk->main_keyid[0];
-    sk->main_keyid[1]= pk->main_keyid[1];
-    sk->keyid[0]    = pk->keyid[0];
-    sk->keyid[1]    = pk->keyid[1];
-}
 
 
 static pka_info_t *
 cp_pka_info (const pka_info_t *s)
 {
   pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
-  
+
   d->valid = s->valid;
   d->checked = s->checked;
   d->uri = s->uri? xstrdup (s->uri):NULL;
@@ -257,48 +269,6 @@ scopy_user_id (PKT_user_id *s)
 
 
 void
-release_secret_key_parts( PKT_secret_key *sk )
-{
-    int n, i;
-
-    n = pubkey_get_nskey( sk->pubkey_algo );
-    if( !n )
-       mpi_release(sk->skey[0]);
-    for(i=0; i < n; i++ ) {
-       mpi_release( sk->skey[i] );
-       sk->skey[i] = NULL;
-    }
-}
-
-void
-free_secret_key( PKT_secret_key *sk )
-{
-    release_secret_key_parts( sk );
-    xfree(sk);
-}
-
-PKT_secret_key *
-copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
-{
-    int n, i;
-
-    if( !d )
-       d = xmalloc_secure(sizeof *d);
-    else
-        release_secret_key_parts (d);
-    memcpy( d, s, sizeof *d );
-    n = pubkey_get_nskey( s->pubkey_algo );
-    if( !n )
-       d->skey[0] = mpi_copy(s->skey[0]);
-    else {
-       for(i=0; i < n; i++ )
-           d->skey[i] = mpi_copy( s->skey[i] );
-    }
-
-    return d;
-}
-
-void
 free_comment( PKT_comment *rem )
 {
     xfree(rem);
@@ -407,11 +377,9 @@ free_packet( PACKET *pkt )
        break;
       case PKT_PUBLIC_KEY:
       case PKT_PUBLIC_SUBKEY:
-       free_public_key( pkt->pkt.public_key );
-       break;
       case PKT_SECRET_KEY:
       case PKT_SECRET_SUBKEY:
-       free_secret_key( pkt->pkt.secret_key );
+       free_public_key (pkt->pkt.public_key);
        break;
       case PKT_COMMENT:
        free_comment( pkt->pkt.comment );
@@ -452,71 +420,13 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
        return -1;
 
     n = pubkey_get_npkey( b->pubkey_algo );
-    if( !n ) { /* unknown algorithm, rest is in opaque MPI */
-       if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
-           return -1; /* can't compare due to unknown algorithm */
-    } else {
-       for(i=0; i < n; i++ ) {
-           if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
-               return -1;
-       }
-    }
-
-    return 0;
-}
-
-/****************
- * Returns 0 if they match.
- * We only compare the public parts.
- */
-int
-cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
-{
-    int n, i;
-
-    if( a->timestamp != b->timestamp )
-       return -1;
-    if( a->version < 4 && a->expiredate != b->expiredate )
-       return -1;
-    if( a->pubkey_algo != b->pubkey_algo )
-       return -1;
-
-    n = pubkey_get_npkey( b->pubkey_algo );
-    if( !n ) { /* unknown algorithm, rest is in opaque MPI */
-       if( mpi_cmp( a->skey[0], b->skey[0] ) )
-           return -1;
-    } else {
-       for(i=0; i < n; i++ ) {
-           if( mpi_cmp( a->skey[i], b->skey[i] ) )
-               return -1;
-       }
-    }
-
-    return 0;
-}
-
-/****************
- * Returns 0 if they match.
- */
-int
-cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
-    int n, i;
-
-    if( pk->timestamp != sk->timestamp )
-       return -1;
-    if( pk->version < 4 && pk->expiredate != sk->expiredate )
-       return -1;
-    if( pk->pubkey_algo != sk->pubkey_algo )
-       return -1;
-
-    n = pubkey_get_npkey( pk->pubkey_algo );
     if( !n )
        return -1; /* can't compare due to unknown algorithm */
     for(i=0; i < n; i++ ) {
-       if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
+       if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
            return -1;
     }
+
     return 0;
 }
 
index 476445f..4a4dd55 100644 (file)
@@ -1,6 +1,6 @@
 /* getkey.c -  Get a key from the database
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007, 2008 Free Software Foundation, Inc.
+ *               2007, 2008, 2010  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -35,7 +35,7 @@
 #include "trustdb.h"
 #include "i18n.h"
 #include "keyserver-internal.h"
-#include "../include/host2net.h"
+#include "call-agent.h"
 
 #define MAX_PK_CACHE_ENTRIES   PK_UID_CACHE_SIZE
 #define MAX_UID_CACHE_ENTRIES  PK_UID_CACHE_SIZE
 #error We need the cache for key creation
 #endif
 
-struct getkey_ctx_s {
-    int exact;
-    KBNODE keyblock;
-    KBPOS  kbpos;
-    KBNODE found_key; /* Pointer into some keyblock. */
-    strlist_t extra_list;  /* Will be freed when releasing the context.  */
-    int last_rc;
-    int req_usage;
-    int req_algo;
-    KEYDB_HANDLE kr_handle;
-    int not_allocated;
-    int nitems;
-    KEYDB_SEARCH_DESC items[1];
+struct getkey_ctx_s
+{
+  int exact;
+  int want_secret;       /* The caller requested only secret keys.  */
+  KBNODE keyblock;
+  KBPOS kbpos;
+  KBNODE found_key;     /* Pointer into some keyblock. */
+  strlist_t extra_list;         /* Will be freed when releasing the context.  */
+  int last_rc;
+  int req_usage;
+  int req_algo;
+  KEYDB_HANDLE kr_handle;
+  int not_allocated;
+  int nitems;
+  KEYDB_SEARCH_DESC items[1];
 };
 
 #if 0
-static struct {
-    int any;
-    int okay_count;
-    int nokey_count;
-    int error_count;
+static struct
+{
+  int any;
+  int okay_count;
+  int nokey_count;
+  int error_count;
 } lkup_stats[21];
 #endif
 
-typedef struct keyid_list {
-    struct keyid_list *next;
-    u32 keyid[2];
+typedef struct keyid_list
+{
+  struct keyid_list *next;
+  char fpr[MAX_FINGERPRINT_LEN];
+  u32 keyid[2];
 } *keyid_list_t;
 
 
 #if MAX_PK_CACHE_ENTRIES
-  typedef struct pk_cache_entry {
-      struct pk_cache_entry *next;
-      u32 keyid[2];
-      PKT_public_key *pk;
-  } *pk_cache_entry_t;
-  static pk_cache_entry_t pk_cache;
-  static int pk_cache_entries;  /* number of entries in pk cache */
-  static int pk_cache_disabled;
+typedef struct pk_cache_entry
+{
+  struct pk_cache_entry *next;
+  u32 keyid[2];
+  PKT_public_key *pk;
+} *pk_cache_entry_t;
+static pk_cache_entry_t pk_cache;
+static int pk_cache_entries;   /* Number of entries in pk cache.  */
+static int pk_cache_disabled;
 #endif
 
 #if MAX_UID_CACHE_ENTRIES < 5
 #error we really need the userid cache
 #endif
-typedef struct user_id_db {
-    struct user_id_db *next;
-    keyid_list_t keyids;
-    int len;
-    char name[1];
+typedef struct user_id_db
+{
+  struct user_id_db *next;
+  keyid_list_t keyids;
+  int len;
+  char name[1];
 } *user_id_db_t;
 static user_id_db_t user_id_db;
-static int uid_cache_entries;  /* number of entries in uid cache */
+static int uid_cache_entries;  /* Number of entries in uid cache. */
 
-static void merge_selfsigs( KBNODE keyblock );
-static int lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode );
+static void merge_selfsigs (kbnode_t keyblock);
+static int lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret);
 
 #if 0
 static void
-print_stats()
+print_stats ()
 {
-    int i;
-    for(i=0; i < DIM(lkup_stats); i++ ) {
-       if( lkup_stats[i].any )
-           fprintf(stderr,
-                   "lookup stats: mode=%-2d  ok=%-6d  nokey=%-6d  err=%-6d\n",
-                   i,
-                   lkup_stats[i].okay_count,
-                   lkup_stats[i].nokey_count,
-                   lkup_stats[i].error_count );
+  int i;
+  for (i = 0; i < DIM (lkup_stats); i++)
+    {
+      if (lkup_stats[i].any)
+       fprintf (stderr,
+                "lookup stats: mode=%-2d  ok=%-6d  nokey=%-6d  err=%-6d\n",
+                i,
+                lkup_stats[i].okay_count,
+                lkup_stats[i].nokey_count, lkup_stats[i].error_count);
     }
 }
 #endif
 
 
 void
-cache_public_key( PKT_public_key *pk )
+cache_public_key (PKT_public_key * pk)
 {
 #if MAX_PK_CACHE_ENTRIES
-    pk_cache_entry_t ce;
-    u32 keyid[2];
+  pk_cache_entry_t ce, ce2;
+  u32 keyid[2];
 
-    if( pk_cache_disabled )
-       return;
+  if (pk_cache_disabled)
+    return;
 
-    if( pk->dont_cache )
-        return;
+  if (pk->flags.dont_cache)
+    return;
 
-    if( is_ELGAMAL(pk->pubkey_algo)
-       || pk->pubkey_algo == PUBKEY_ALGO_DSA
-       || is_RSA(pk->pubkey_algo) ) {
-       keyid_from_pk( pk, keyid );
+  if (is_ELGAMAL (pk->pubkey_algo)
+      || pk->pubkey_algo == PUBKEY_ALGO_DSA
+      || pk->pubkey_algo == PUBKEY_ALGO_ECDSA
+      || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
+      || pk->pubkey_algo == PUBKEY_ALGO_ECDH
+      || is_RSA (pk->pubkey_algo))
+    {
+      keyid_from_pk (pk, keyid);
     }
-    else
-       return; /* don't know how to get the keyid */
-
-    for( ce = pk_cache; ce; ce = ce->next )
-       if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
-           if( DBG_CACHE )
-               log_debug("cache_public_key: already in cache\n");
-           return;
-       }
+  else
+    return; /* Don't know how to get the keyid.  */
 
-    if( pk_cache_entries >= MAX_PK_CACHE_ENTRIES ) {
-       /* fixme: use another algorithm to free some cache slots */
-       pk_cache_disabled=1;
-       if( opt.verbose > 1 )
-           log_info(_("too many entries in pk cache - disabled\n"));
+  for (ce = pk_cache; ce; ce = ce->next)
+    if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
+      {
+       if (DBG_CACHE)
+         log_debug ("cache_public_key: already in cache\n");
        return;
-    }
-    pk_cache_entries++;
-    ce = xmalloc( sizeof *ce );
-    ce->next = pk_cache;
-    pk_cache = ce;
-    ce->pk = copy_public_key( NULL, pk );
-    ce->keyid[0] = keyid[0];
-    ce->keyid[1] = keyid[1];
+      }
+
+  if (pk_cache_entries >= MAX_PK_CACHE_ENTRIES)
+    {
+      int n;
+
+      /* Remove the last 50% of the entries.  */
+      for (ce = pk_cache, n = 0; ce && n < pk_cache_entries/2; n++)
+        ce = ce->next;
+      if (ce != pk_cache && ce->next)
+        {
+          ce2 = ce->next;
+          ce->next = NULL;
+          ce = ce2;
+          for (; ce; ce = ce2)
+            {
+              ce2 = ce->next;
+              free_public_key (ce->pk);
+              xfree (ce);
+              pk_cache_entries--;
+            }
+        }
+      assert (pk_cache_entries < MAX_PK_CACHE_ENTRIES);
+    }
+  pk_cache_entries++;
+  ce = xmalloc (sizeof *ce);
+  ce->next = pk_cache;
+  pk_cache = ce;
+  ce->pk = copy_public_key (NULL, pk);
+  ce->keyid[0] = keyid[0];
+  ce->keyid[1] = keyid[1];
 #endif
 }
 
 
 /* Return a const utf-8 string with the text "[User ID not found]".
-   This fucntion is required so that we don't need to switch gettext's
-   encoding temporary. */
+   This function is required so that we don't need to switch gettext's
+   encoding temporary.  */
 static const char *
 user_id_not_found_utf8 (void)
 {
@@ -179,39 +206,40 @@ user_id_not_found_utf8 (void)
 
 
 
-/*
- * Return the user ID from the given keyblock.
+/* Return the user ID from the given keyblock.
  * We use the primary uid flag which has been set by the merge_selfsigs
  * function.  The returned value is only valid as long as then given
- * keyblock is not changed
- */
+ * keyblock is not changed.  */
 static const char *
-get_primary_uid ( KBNODE keyblock, size_t *uidlen )
+get_primary_uid (KBNODE keyblock, size_t * uidlen)
 {
-    KBNODE k;
-    const char *s;
-
-    for (k=keyblock; k; k=k->next ) {
-        if ( k->pkt->pkttype == PKT_USER_ID
-             && !k->pkt->pkt.user_id->attrib_data
-             && k->pkt->pkt.user_id->is_primary ) {
-            *uidlen = k->pkt->pkt.user_id->len;
-            return k->pkt->pkt.user_id->name;
-        }
+  KBNODE k;
+  const char *s;
+
+  for (k = keyblock; k; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_USER_ID
+         && !k->pkt->pkt.user_id->attrib_data
+         && k->pkt->pkt.user_id->is_primary)
+       {
+         *uidlen = k->pkt->pkt.user_id->len;
+         return k->pkt->pkt.user_id->name;
+       }
     }
-    s = user_id_not_found_utf8 ();
-    *uidlen = strlen (s);
-    return s;
+  s = user_id_not_found_utf8 ();
+  *uidlen = strlen (s);
+  return s;
 }
 
 
 static void
-release_keyid_list ( keyid_list_t k )
+release_keyid_list (keyid_list_t k)
 {
-    while (  k ) {
-        keyid_list_t k2 = k->next;
-        xfree (k);
-        k = k2;
+  while (k)
+    {
+      keyid_list_t k2 = k->next;
+      xfree (k);
+      k = k2;
     }
 }
 
@@ -220,184 +248,179 @@ release_keyid_list ( keyid_list_t k )
  * Feed only public keys to this function.
  */
 static void
-cache_user_id( KBNODE keyblock )
+cache_user_id (KBNODE keyblock)
 {
-    user_id_db_t r;
-    const char *uid;
-    size_t uidlen;
-    keyid_list_t keyids = NULL;
-    KBNODE k;
-
-    for (k=keyblock; k; k = k->next ) {
-        if ( k->pkt->pkttype == PKT_PUBLIC_KEY
-             || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-            keyid_list_t a = xmalloc_clear ( sizeof *a );
-            /* Hmmm: For a long list of keyids it might be an advantage
-             * to append the keys */
-            keyid_from_pk( k->pkt->pkt.public_key, a->keyid );
-            /* first check for duplicates */
-            for(r=user_id_db; r; r = r->next ) {
-                keyid_list_t b = r->keyids;
-                for ( b = r->keyids; b; b = b->next ) {
-                    if( b->keyid[0] == a->keyid[0]
-                        && b->keyid[1] == a->keyid[1] ) {
-                        if( DBG_CACHE )
-                            log_debug("cache_user_id: already in cache\n");
-                        release_keyid_list ( keyids );
-                        xfree ( a );
-                        return;
-                    }
-                }
-            }
-            /* now put it into the cache */
-            a->next = keyids;
-            keyids = a;
-        }
+  user_id_db_t r;
+  const char *uid;
+  size_t uidlen;
+  keyid_list_t keyids = NULL;
+  KBNODE k;
+
+  for (k = keyblock; k; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_PUBLIC_KEY
+         || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       {
+         keyid_list_t a = xmalloc_clear (sizeof *a);
+         /* Hmmm: For a long list of keyids it might be an advantage
+          * to append the keys.  */
+          fingerprint_from_pk (k->pkt->pkt.public_key, a->fpr, NULL);
+         keyid_from_pk (k->pkt->pkt.public_key, a->keyid);
+         /* First check for duplicates.  */
+         for (r = user_id_db; r; r = r->next)
+           {
+             keyid_list_t b = r->keyids;
+             for (b = r->keyids; b; b = b->next)
+               {
+                 if (!memcmp (b->fpr, a->fpr, MAX_FINGERPRINT_LEN))
+                   {
+                     if (DBG_CACHE)
+                       log_debug ("cache_user_id: already in cache\n");
+                     release_keyid_list (keyids);
+                     xfree (a);
+                     return;
+                   }
+               }
+           }
+         /* Now put it into the cache.  */
+         a->next = keyids;
+         keyids = a;
+       }
     }
-    if ( !keyids )
-        BUG (); /* No key no fun */
+  if (!keyids)
+    BUG (); /* No key no fun.  */
 
 
-    uid = get_primary_uid ( keyblock, &uidlen );
+  uid = get_primary_uid (keyblock, &uidlen);
 
-    if( uid_cache_entries >= MAX_UID_CACHE_ENTRIES ) {
-       /* fixme: use another algorithm to free some cache slots */
-       r = user_id_db;
-       user_id_db = r->next;
-        release_keyid_list ( r->keyids );
-       xfree(r);
-       uid_cache_entries--;
-    }
-    r = xmalloc( sizeof *r + uidlen-1 );
-    r->keyids = keyids;
-    r->len = uidlen;
-    memcpy(r->name, uid, r->len);
-    r->next = user_id_db;
-    user_id_db = r;
-    uid_cache_entries++;
+  if (uid_cache_entries >= MAX_UID_CACHE_ENTRIES)
+    {
+      /* fixme: use another algorithm to free some cache slots */
+      r = user_id_db;
+      user_id_db = r->next;
+      release_keyid_list (r->keyids);
+      xfree (r);
+      uid_cache_entries--;
+    }
+  r = xmalloc (sizeof *r + uidlen - 1);
+  r->keyids = keyids;
+  r->len = uidlen;
+  memcpy (r->name, uid, r->len);
+  r->next = user_id_db;
+  user_id_db = r;
+  uid_cache_entries++;
 }
 
 
 void
-getkey_disable_caches()
+getkey_disable_caches ()
 {
 #if MAX_PK_CACHE_ENTRIES
-    {
-       pk_cache_entry_t ce, ce2;
+  {
+    pk_cache_entry_t ce, ce2;
 
-       for( ce = pk_cache; ce; ce = ce2 ) {
-           ce2 = ce->next;
-           free_public_key( ce->pk );
-           xfree( ce );
-       }
-       pk_cache_disabled=1;
-       pk_cache_entries = 0;
-       pk_cache = NULL;
-    }
+    for (ce = pk_cache; ce; ce = ce2)
+      {
+       ce2 = ce->next;
+       free_public_key (ce->pk);
+       xfree (ce);
+      }
+    pk_cache_disabled = 1;
+    pk_cache_entries = 0;
+    pk_cache = NULL;
+  }
 #endif
-    /* fixme: disable user id cache ? */
+  /* fixme: disable user id cache ? */
 }
 
 
 static void
-pk_from_block ( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE keyblock )
+pk_from_block (GETKEY_CTX ctx, PKT_public_key * pk, KBNODE keyblock)
 {
-    KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
+  KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
 
-    assert ( a->pkt->pkttype == PKT_PUBLIC_KEY
-             ||  a->pkt->pkttype == PKT_PUBLIC_SUBKEY );
+  assert (a->pkt->pkttype == PKT_PUBLIC_KEY
+         || a->pkt->pkttype == PKT_PUBLIC_SUBKEY);
 
-    copy_public_key ( pk, a->pkt->pkt.public_key );
+  copy_public_key (pk, a->pkt->pkt.public_key);
 }
 
-static void
-sk_from_block ( GETKEY_CTX ctx,
-                PKT_secret_key *sk, KBNODE keyblock )
-{
-    KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
-
-    assert ( a->pkt->pkttype == PKT_SECRET_KEY
-             ||  a->pkt->pkttype == PKT_SECRET_SUBKEY );
-
-    copy_secret_key( sk, a->pkt->pkt.secret_key);
-}
-
-
-/****************
- * Get a public key and store it into the allocated pk
- * can be called with PK set to NULL to just read it into some
- * internal structures.
- */
+/* Get a public key and store it into the allocated pk can be called
+ * with PK set to NULL to just read it into some internal
+ * structures.  */
 int
-get_pubkey( PKT_public_key *pk, u32 *keyid )
+get_pubkey (PKT_public_key * pk, u32 * keyid)
 {
-    int internal = 0;
-    int rc = 0;
+  int internal = 0;
+  int rc = 0;
 
 #if MAX_PK_CACHE_ENTRIES
-    if(pk)
-      {
-       /* Try to get it from the cache.  We don't do this when pk is
-          NULL as it does not guarantee that the user IDs are
-          cached. */
-       pk_cache_entry_t ce;
-       for( ce = pk_cache; ce; ce = ce->next )
-         {
-           if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] )
-             {
-               copy_public_key( pk, ce->pk );
-               return 0;
-             }
-         }
-      }
+  if (pk)
+    {
+      /* Try to get it from the cache.  We don't do this when pk is
+         NULL as it does not guarantee that the user IDs are
+         cached. */
+      pk_cache_entry_t ce;
+      for (ce = pk_cache; ce; ce = ce->next)
+       {
+         if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
+           {
+             copy_public_key (pk, ce->pk);
+             return 0;
+           }
+       }
+    }
 #endif
-    /* more init stuff */
-    if( !pk ) {
-       pk = xmalloc_clear( sizeof *pk );
-       internal++;
-    }
-
-
-    /* do a lookup */
-    {  struct getkey_ctx_s ctx;
-        KBNODE kb = NULL;
-       memset( &ctx, 0, sizeof ctx );
-        ctx.exact = 1; /* use the key ID exactly as given */
-       ctx.not_allocated = 1;
-        ctx.kr_handle = keydb_new (0);
-       ctx.nitems = 1;
-       ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
-       ctx.items[0].u.kid[0] = keyid[0];
-       ctx.items[0].u.kid[1] = keyid[1];
-        ctx.req_algo  = pk->req_algo;
-        ctx.req_usage = pk->req_usage;
-       rc = lookup( &ctx, &kb, 0 );
-        if ( !rc ) {
-            pk_from_block ( &ctx, pk, kb );
-        }
-       get_pubkey_end( &ctx );
-        release_kbnode ( kb );
+  /* More init stuff.  */
+  if (!pk)
+    {
+      pk = xmalloc_clear (sizeof *pk);
+      internal++;
     }
-    if( !rc )
-       goto leave;
 
-    rc = G10ERR_NO_PUBKEY;
 
-  leave:
-    if( !rc )
-       cache_public_key( pk );
-    if( internal )
-       free_public_key(pk);
-    return rc;
+  /* Do a lookup.  */
+  {
+    struct getkey_ctx_s ctx;
+    KBNODE kb = NULL;
+    memset (&ctx, 0, sizeof ctx);
+    ctx.exact = 1; /* Use the key ID exactly as given.  */
+    ctx.not_allocated = 1;
+    ctx.kr_handle = keydb_new ();
+    ctx.nitems = 1;
+    ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
+    ctx.items[0].u.kid[0] = keyid[0];
+    ctx.items[0].u.kid[1] = keyid[1];
+    ctx.req_algo = pk->req_algo;
+    ctx.req_usage = pk->req_usage;
+    rc = lookup (&ctx, &kb, 0);
+    if (!rc)
+      {
+       pk_from_block (&ctx, pk, kb);
+      }
+    get_pubkey_end (&ctx);
+    release_kbnode (kb);
+  }
+  if (!rc)
+    goto leave;
+
+  rc = G10ERR_NO_PUBKEY;
+
+leave:
+  if (!rc)
+    cache_public_key (pk);
+  if (internal)
+    free_public_key (pk);
+  return rc;
 }
 
 
 /* Get a public key and store it into the allocated pk.  This function
    differs from get_pubkey() in that it does not do a check of the key
    to avoid recursion.  It should be used only in very certain cases.
-   It will only retrieve primary keys. */
+   It will only retrieve primary keys.  */
 int
-get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
+get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
 {
   int rc = 0;
   KEYDB_HANDLE hd;
@@ -406,24 +429,25 @@ get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
 
   assert (pk);
 #if MAX_PK_CACHE_ENTRIES
-  { /* Try to get it from the cache */
+  {
+    /* Try to get it from the cache */
     pk_cache_entry_t ce;
 
     for (ce = pk_cache; ce; ce = ce->next)
       {
-        if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
-          {
-            if (pk)
-              copy_public_key (pk, ce->pk);
-            return 0;
-          }
+       if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
+         {
+           if (pk)
+             copy_public_key (pk, ce->pk);
+           return 0;
+         }
       }
   }
 #endif
 
-  hd = keydb_new (0);
+  hd = keydb_new ();
   rc = keydb_search_kid (hd, keyid);
-  if (rc == -1)
+  if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
     {
       keydb_release (hd);
       return G10ERR_NO_PUBKEY;
@@ -432,18 +456,19 @@ get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
   keydb_release (hd);
   if (rc)
     {
-      log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
+      log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
       return G10ERR_NO_PUBKEY;
     }
 
-  assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY
-           ||  keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY );
+  assert (keyblock && keyblock->pkt
+          && (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
+              || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY));
 
-  keyid_from_pk(keyblock->pkt->pkt.public_key,pkid);
-  if(keyid[0]==pkid[0] && keyid[1]==pkid[1])
-    copy_public_key (pk, keyblock->pkt->pkt.public_key );
+  keyid_from_pk (keyblock->pkt->pkt.public_key, pkid);
+  if (keyid[0] == pkid[0] && keyid[1] == pkid[1])
+    copy_public_key (pk, keyblock->pkt->pkt.public_key);
   else
-    rc=G10ERR_NO_PUBKEY;
+    rc = G10ERR_NO_PUBKEY;
 
   release_kbnode (keyblock);
 
@@ -455,472 +480,211 @@ get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
 
 
 KBNODE
-get_pubkeyblock( u32 *keyid )
+get_pubkeyblock (u32 * keyid)
 {
-    struct getkey_ctx_s ctx;
-    int rc = 0;
-    KBNODE keyblock = NULL;
+  struct getkey_ctx_s ctx;
+  int rc = 0;
+  KBNODE keyblock = NULL;
 
-    memset( &ctx, 0, sizeof ctx );
-    /* no need to set exact here because we want the entire block */
-    ctx.not_allocated = 1;
-    ctx.kr_handle = keydb_new (0);
-    ctx.nitems = 1;
-    ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
-    ctx.items[0].u.kid[0] = keyid[0];
-    ctx.items[0].u.kid[1] = keyid[1];
-    rc = lookup( &ctx, &keyblock, 0 );
-    get_pubkey_end( &ctx );
+  memset (&ctx, 0, sizeof ctx);
+  /* No need to set exact here because we want the entire block.  */
+  ctx.not_allocated = 1;
+  ctx.kr_handle = keydb_new ();
+  ctx.nitems = 1;
+  ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
+  ctx.items[0].u.kid[0] = keyid[0];
+  ctx.items[0].u.kid[1] = keyid[1];
+  rc = lookup (&ctx, &keyblock, 0);
+  get_pubkey_end (&ctx);
 
-    return rc ? NULL : keyblock;
+  return rc ? NULL : keyblock;
 }
 
 
 
 
-/****************
- * Get a secret key and store it into sk
+/*
+ * Get a public key and store it into PK.  This functions check that a
+ * corresponding secret key is available.  With no secret key it does
+ * not succeeed.
  */
-int
-get_seckey( PKT_secret_key *sk, u32 *keyid )
+gpg_error_t
+get_seckey (PKT_public_key *pk, u32 *keyid)
 {
-    int rc;
-    struct getkey_ctx_s ctx;
-    KBNODE kb = NULL;
-
-    memset( &ctx, 0, sizeof ctx );
-    ctx.exact = 1; /* use the key ID exactly as given */
-    ctx.not_allocated = 1;
-    ctx.kr_handle = keydb_new (1);
-    ctx.nitems = 1;
-    ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
-    ctx.items[0].u.kid[0] = keyid[0];
-    ctx.items[0].u.kid[1] = keyid[1];
-    ctx.req_algo  = sk->req_algo;
-    ctx.req_usage = sk->req_usage;
-    rc = lookup( &ctx, &kb, 1 );
-    if ( !rc ) {
-        u32 skid[2];
-
-        sk_from_block ( &ctx, sk, kb );
-        keyid_from_sk ( sk, skid );
-        /*
-         * Make sure it's exact match of keyid.
-         * If not, it's secret subkey with no public key.
-         */
-        if (!(keyid[0] == skid[0] && keyid[1] == skid[1])) {
-          log_error (_("key %s: secret key without public key"
-                       " - skipped\n"), keystr(keyid));
-          rc = G10ERR_NO_PUBKEY;
-        }
-    }
-    get_seckey_end( &ctx );
-    release_kbnode ( kb );
+  gpg_error_t err;
+  struct getkey_ctx_s ctx;
+  kbnode_t keyblock = NULL;
 
-    if( !rc ) {
-       /* check the secret key (this may prompt for a passprase to
-        * unlock the secret key
-        */
-       rc = check_secret_key( sk, 0 );
+  memset (&ctx, 0, sizeof ctx);
+  ctx.exact = 1; /* Use the key ID exactly as given.  */
+  ctx.not_allocated = 1;
+  ctx.kr_handle = keydb_new ();
+  ctx.nitems = 1;
+  ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
+  ctx.items[0].u.kid[0] = keyid[0];
+  ctx.items[0].u.kid[1] = keyid[1];
+  ctx.req_algo = pk->req_algo;
+  ctx.req_usage = pk->req_usage;
+  err = lookup (&ctx, &keyblock, 1);
+  if (!err)
+    {
+      pk_from_block (&ctx, pk, keyblock);
     }
+  get_pubkey_end (&ctx);
+  release_kbnode (keyblock);
 
-    return rc;
-}
-
-
-/****************
- * Check whether the secret key is available.  This is just a fast
- * check and does not tell us whether the secret key is valid.  It
- * merely tells other whether there is some secret key.
- * Returns: 0 := key is available
- * G10ERR_NO_SECKEY := not availabe
- */
-int
-seckey_available( u32 *keyid )
-{
-    int rc;
-    KEYDB_HANDLE hd = keydb_new (1);
-
-    rc = keydb_search_kid (hd, keyid);
-    if ( rc == -1 )
-        rc = G10ERR_NO_SECKEY;
-    keydb_release (hd);
-    return rc;
-}
-
-
-/****************
- * Return the type of the user id:
- *
- * Please use the constants KEYDB_SERCH_MODE_xxx
- *  0 = Invalid user ID
- *  1 = exact match
- *  2 = match a substring
- *  3 = match an email address
- *  4 = match a substring of an email address
- *  5 = match an email address, but compare from end
- *  6 = word match mode
- * 10 = it is a short KEYID (don't care about keyid[0])
- * 11 = it is a long  KEYID
- * 12 = it is a trustdb index (keyid is looked up)
- * 16 = it is a 16 byte fingerprint
- * 20 = it is a 20 byte fingerprint
- * 21 = Unified fingerprint :fpr:pk_algo:
- *      (We don't use pk_algo yet)
- *
- * Rules used:
- * - If the username starts with 8,9,16 or 17 hex-digits (the first one
- *   must be in the range 0..9), this is considered a keyid; depending
- *   on the length a short or complete one.
- * - If the username starts with 32,33,40 or 41 hex-digits (the first one
- *   must be in the range 0..9), this is considered a fingerprint.
- * - If the username starts with a left angle, we assume it is a complete
- *   email address and look only at this part.
- * - If the username starts with a colon we assume it is a unified
- *   key specfification.
- * - If the username starts with a '.', we assume it is the ending
- *   part of an email address
- * - If the username starts with an '@', we assume it is a part of an
- *   email address
- * - If the userid start with an '=' an exact compare is done.
- * - If the userid starts with a '*' a case insensitive substring search is
- *   done (This is the default).
- * - If the userid starts with a '+' we will compare individual words
- *   and a match requires that all the words are in the userid.
- *   Words are delimited by white space or "()<>[]{}.@-+_,;/&!"
- *   (note that you can't search for these characters). Compare
- *   is not case sensitive.
- * - If the userid starts with a '&' a 40 hex digits keygrip is expected.
- */
-
-int
-classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
-{
-    const char *s;
-    int hexprefix = 0;
-    int hexlength;
-    int mode = 0;
-    KEYDB_SEARCH_DESC dummy_desc;
-
-    if (!desc)
-        desc = &dummy_desc;
-
-    /* clear the structure so that the mode field is set to zero unless
-     * we set it to the correct value right at the end of this function */
-    memset (desc, 0, sizeof *desc);
-
-    /* skip leading spaces.  Fixme: what is with trailing spaces? */
-    for(s = name; *s && spacep (s); s++ )
-       ;
-
-    switch (*s) {
-       case 0:    /* empty string is an error */
-           return 0;
-
-#if 0
-       case '.':  /* an email address, compare from end */
-           mode = KEYDB_SEARCH_MODE_MAILEND;
-           s++;
-            desc->u.name = s;
-           break;
-#endif
-
-       case '<':  /* an email address */
-           mode = KEYDB_SEARCH_MODE_MAIL;
-            desc->u.name = s;
-           break;
-
-       case '@':  /* part of an email address */
-           mode = KEYDB_SEARCH_MODE_MAILSUB;
-           s++;
-            desc->u.name = s;
-           break;
-
-       case '=':  /* exact compare */
-           mode = KEYDB_SEARCH_MODE_EXACT;
-           s++;
-            desc->u.name = s;
-           break;
-
-       case '*':  /* case insensitive substring search */
-           mode = KEYDB_SEARCH_MODE_SUBSTR;
-           s++;
-            desc->u.name = s;
-           break;
-
-#if 0
-       case '+':  /* compare individual words */
-           mode = KEYDB_SEARCH_MODE_WORDS;
-           s++;
-            desc->u.name = s;
-           break;
-#endif
-
-       case '#':  /* local user id */
-            return 0; /* This is now obsolete and can't not be used anymore*/
-
-        case ':': /*Unified fingerprint */
-            {
-                const char *se, *si;
-                int i;
-
-                se = strchr( ++s,':');
-                if ( !se )
-                    return 0;
-                for (i=0,si=s; si < se; si++, i++ ) {
-                    if ( !strchr("01234567890abcdefABCDEF", *si ) )
-                        return 0; /* invalid digit */
-                }
-                if (i != 32 && i != 40)
-                    return 0; /* invalid length of fpr*/
-                for (i=0,si=s; si < se; i++, si +=2)
-                    desc->u.fpr[i] = hextobyte(si);
-                for ( ; i < 20; i++)
-                    desc->u.fpr[i]= 0;
-                s = se + 1;
-                mode = KEYDB_SEARCH_MODE_FPR;
-            }
-            break;
-
-       case '&':  /* keygrip */
-          return 0; /* Not yet implememted. */
-
-       default:
-           if (s[0] == '0' && s[1] == 'x') {
-               hexprefix = 1;
-               s += 2;
-           }
-
-           hexlength = strspn(s, "0123456789abcdefABCDEF");
-            if (hexlength >= 8 && s[hexlength] =='!') {
-               desc->exact = 1;
-                hexlength++; /* just for the following check */
-            }
-
-           /* check if a hexadecimal number is terminated by EOS or blank */
-           if (hexlength && s[hexlength] && !spacep(s+hexlength)) {
-               if (hexprefix)      /* a "0x" prefix without correct */
-                   return 0;       /* termination is an error */
-               else                /* The first chars looked like */
-                   hexlength = 0;  /* a hex number, but really were not. */
-           }
-
-            if (desc->exact)
-                hexlength--;
-
-           if (hexlength == 8
-                || (!hexprefix && hexlength == 9 && *s == '0')){
-               /* short keyid */
-               if (hexlength == 9)
-                   s++;
-                desc->u.kid[0] = 0;
-                desc->u.kid[1] = strtoul( s, NULL, 16 );
-               mode = KEYDB_SEARCH_MODE_SHORT_KID;
-           }
-           else if (hexlength == 16
-                     || (!hexprefix && hexlength == 17 && *s == '0')) {
-               /* complete keyid */
-               char buf[9];
-               if (hexlength == 17)
-                   s++;
-               mem2str(buf, s, 9 );
-               desc->u.kid[0] = strtoul( buf, NULL, 16 );
-               desc->u.kid[1] = strtoul( s+8, NULL, 16 );
-               mode = KEYDB_SEARCH_MODE_LONG_KID;
-           }
-           else if (hexlength == 32 || (!hexprefix && hexlength == 33
-                                                           && *s == '0')) {
-               /* md5 fingerprint */
-               int i;
-               if (hexlength == 33)
-                   s++;
-                memset(desc->u.fpr+16, 0, 4);
-                for (i=0; i < 16; i++, s+=2) {
-                    int c = hextobyte(s);
-                    if (c == -1)
-                        return 0;
-                    desc->u.fpr[i] = c;
-                }
-               mode = KEYDB_SEARCH_MODE_FPR16;
-           }
-           else if (hexlength == 40 || (!hexprefix && hexlength == 41
-                                                             && *s == '0')) {
-               /* sha1/rmd160 fingerprint */
-               int i;
-               if (hexlength == 41)
-                   s++;
-                for (i=0; i < 20; i++, s+=2) {
-                    int c = hextobyte(s);
-                    if (c == -1)
-                        return 0;
-                    desc->u.fpr[i] = c;
-                }
-               mode = KEYDB_SEARCH_MODE_FPR20;
-           }
-           else {
-               if (hexprefix)  /* This was a hex number with a prefix */
-                   return 0;   /* and a wrong length */
-
-               desc->exact = 0;
-                desc->u.name = s;
-               mode = KEYDB_SEARCH_MODE_SUBSTR;   /* default mode */
-           }
-    }
+  if (!err)
+    err = agent_probe_secret_key (/*ctrl*/NULL, pk);
 
-    desc->mode = mode;
-    return mode;
+  return err;
 }
 
 
 static int
-skip_unusable (void *dummy, u32 *keyid, PKT_user_id *uid)
+skip_unusable (void *dummy, u32 * keyid, PKT_user_id * uid)
 {
-  int unusable=0;
+  int unusable = 0;
   KBNODE keyblock;
 
-  (void)dummy;
+  (void) dummy;
 
-  keyblock=get_pubkeyblock(keyid);
-  if(!keyblock)
+  keyblock = get_pubkeyblock (keyid);
+  if (!keyblock)
     {
-      log_error("error checking usability status of %s\n",keystr(keyid));
+      log_error ("error checking usability status of %s\n", keystr (keyid));
       goto leave;
     }
 
   /* Is the user ID in question revoked/expired? */
-  if(uid)
+  if (uid)
     {
       KBNODE node;
 
-      for(node=keyblock;node;node=node->next)
+      for (node = keyblock; node; node = node->next)
        {
-         if(node->pkt->pkttype==PKT_USER_ID)
+         if (node->pkt->pkttype == PKT_USER_ID)
            {
-             if(cmp_user_ids(uid,node->pkt->pkt.user_id)==0
-                && (node->pkt->pkt.user_id->is_revoked
-                    || node->pkt->pkt.user_id->is_expired))
+             if (cmp_user_ids (uid, node->pkt->pkt.user_id) == 0
+                 && (node->pkt->pkt.user_id->is_revoked
+                     || node->pkt->pkt.user_id->is_expired))
                {
-                 unusable=1;
+                 unusable = 1;
                  break;
                }
            }
        }
     }
 
-  if(!unusable)
-    unusable=pk_is_disabled(keyblock->pkt->pkt.public_key);
+  if (!unusable)
+    unusable = pk_is_disabled (keyblock->pkt->pkt.public_key);
 
- leave:
-  release_kbnode(keyblock);
+leave:
+  release_kbnode (keyblock);
   return unusable;
 }
 
-/****************
- * Try to get the pubkey by the userid. This function looks for the
- * first pubkey certificate which has the given name in a user_id.  if
- * pk/sk has the pubkey algo set, the function will only return a
- * pubkey with that algo.  If namelist is NULL, the first key is
- * returned.  The caller should provide storage for either the pk or
- * the sk.  If ret_kb is not NULL the function will return the
- * keyblock there.
- */
 
+/* Try to get the pubkey by the userid.  This function looks for the
+ * first pubkey certificate which has the given name in a user_id.  If
+ * PK has the pubkey algo set, the function will only return a pubkey
+ * with that algo.  If NAMELIST is NULL, the first key is returned.
+ * The caller should provide storage for the PK or pass NULL if it is
+ * not needed.  If RET_KB is not NULL the function stores the entire
+ * keyblock at that address.  */
 static int
-key_bynameGETKEY_CTX *retctx, strlist_t namelist,
-           PKT_public_key *pk, PKT_secret_key *sk,
-           int secmode, int include_unusable,
-            KBNODE *ret_kb, KEYDB_HANDLE *ret_kdbhd )
+key_byname (GETKEY_CTX *retctx, strlist_t namelist,
+           PKT_public_key *pk,
+           int want_secret, int include_unusable,
+           KBNODE * ret_kb, KEYDB_HANDLE * ret_kdbhd)
 {
-    int rc = 0;
-    int n;
-    strlist_t r;
-    GETKEY_CTX ctx;
-    KBNODE help_kb = NULL;
+  int rc = 0;
+  int n;
+  strlist_t r;
+  GETKEY_CTX ctx;
+  KBNODE help_kb = NULL;
 
-    if( retctx ) {/* reset the returned context in case of error */
-        assert (!ret_kdbhd);  /* not allowed because the handle is
-                                 stored in the context */
-       *retctx = NULL;
+  if (retctx)
+    {
+      /* Reset the returned context in case of error.  */
+      assert (!ret_kdbhd); /* Not allowed because the handle is stored
+                             in the context.  */
+      *retctx = NULL;
     }
-    if (ret_kdbhd)
-        *ret_kdbhd = NULL;
+  if (ret_kdbhd)
+    *ret_kdbhd = NULL;
 
-    if(!namelist)
-      {
-       ctx = xmalloc_clear (sizeof *ctx);
-       ctx->nitems = 1;
-       ctx->items[0].mode=KEYDB_SEARCH_MODE_FIRST;
-       if(!include_unusable)
-         ctx->items[0].skipfnc=skip_unusable;
-      }
-    else
-      {
-       /* build the search context */
-       for(n=0, r=namelist; r; r = r->next )
-         n++;
+  if (!namelist)
+    {
+      ctx = xmalloc_clear (sizeof *ctx);
+      ctx->nitems = 1;
+      ctx->items[0].mode = KEYDB_SEARCH_MODE_FIRST;
+      if (!include_unusable)
+       ctx->items[0].skipfnc = skip_unusable;
+    }
+  else
+    {
+      /* Build the search context.  */
+      for (n = 0, r = namelist; r; r = r->next)
+       n++;
 
-       ctx = xmalloc_clear (sizeof *ctx + (n-1)*sizeof ctx->items );
-       ctx->nitems = n;
+      ctx = xmalloc_clear (sizeof *ctx + (n - 1) * sizeof ctx->items);
+      ctx->nitems = n;
 
-       for(n=0, r=namelist; r; r = r->next, n++ )
-         {
-           classify_user_id (r->d, &ctx->items[n]);
+      for (n = 0, r = namelist; r; r = r->next, n++)
+       {
+         gpg_error_t err;
 
-           if (ctx->items[n].exact)
-             ctx->exact = 1;
-           if (!ctx->items[n].mode)
-             {
-               xfree (ctx);
-               return G10ERR_INV_USER_ID;
-             }
-           if(!include_unusable
-              && ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID
-              && ctx->items[n].mode!=KEYDB_SEARCH_MODE_LONG_KID
-              && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR16
-              && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR20
-              && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR)
-             ctx->items[n].skipfnc=skip_unusable;
-         }
-      }
+         err = classify_user_id (r->d, &ctx->items[n], 1);
+
+         if (ctx->items[n].exact)
+           ctx->exact = 1;
+         if (err)
+           {
+             xfree (ctx);
+             return gpg_err_code (err); /* FIXME: remove gpg_err_code.  */
+           }
+         if (!include_unusable
+             && ctx->items[n].mode != KEYDB_SEARCH_MODE_SHORT_KID
+             && ctx->items[n].mode != KEYDB_SEARCH_MODE_LONG_KID
+             && ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR16
+             && ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR20
+             && ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR)
+           ctx->items[n].skipfnc = skip_unusable;
+       }
+    }
 
-    ctx->kr_handle = keydb_new (secmode);
-    if ( !ret_kb )
-        ret_kb = &help_kb;
+  ctx->want_secret = want_secret;
+  ctx->kr_handle = keydb_new ();
+  if (!ret_kb)
+    ret_kb = &help_kb;
 
-    if( secmode ) {
-        if (sk) {
-            ctx->req_algo  = sk->req_algo;
-            ctx->req_usage = sk->req_usage;
-        }
-       rc = lookup( ctx, ret_kb, 1 );
-        if ( !rc && sk ) {
-            sk_from_block ( ctx, sk, *ret_kb );
-        }
+  if (pk)
+    {
+      ctx->req_algo = pk->req_algo;
+      ctx->req_usage = pk->req_usage;
     }
-    else {
-        if (pk) {
-            ctx->req_algo  = pk->req_algo;
-            ctx->req_usage = pk->req_usage;
-        }
-       rc = lookup( ctx, ret_kb, 0 );
-        if ( !rc && pk ) {
-            pk_from_block ( ctx, pk, *ret_kb );
-        }
+
+  rc = lookup (ctx, ret_kb, want_secret);
+  if (!rc && pk)
+    {
+      pk_from_block (ctx, pk, *ret_kb);
     }
 
-    release_kbnode ( help_kb );
+  release_kbnode (help_kb);
 
-    if (retctx) /* caller wants the context */
-       *retctx = ctx;
-    else {
-        if (ret_kdbhd) {
-            *ret_kdbhd = ctx->kr_handle;
-            ctx->kr_handle = NULL;
-        }
-        get_pubkey_end (ctx);
+  if (retctx) /* Caller wants the context.  */
+    *retctx = ctx;
+  else
+    {
+      if (ret_kdbhd)
+       {
+         *ret_kdbhd = ctx->kr_handle;
+         ctx->kr_handle = NULL;
+       }
+      get_pubkey_end (ctx);
     }
 
-    return rc;
+  return rc;
 }
 
 
@@ -933,10 +697,9 @@ key_byname( GETKEY_CTX *retctx, strlist_t namelist,
    to import the key via the online mechanisms defined by
    --auto-key-locate.  */
 int
-get_pubkey_byname (GETKEY_CTX *retctx, PKT_public_key *pk,
-                  const char *name, KBNODE *ret_keyblock,
-                   KEYDB_HANDLE *ret_kdbhd, int include_unusable,
-                   int no_akl)
+get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
+                  const char *name, KBNODE * ret_keyblock,
+                  KEYDB_HANDLE * ret_kdbhd, int include_unusable, int no_akl)
 {
   int rc;
   strlist_t namelist = NULL;
@@ -950,7 +713,7 @@ get_pubkey_byname (GETKEY_CTX *retctx, PKT_public_key *pk,
 
   is_mbox = is_valid_mailbox (name);
 
-  /* Check whether we the default local search has been disabled.
+  /* Check whether the default local search has been disabled.
      This is the case if either the "nodefault" or the "local" keyword
      are in the list of auto key locate mechanisms.
 
@@ -961,19 +724,19 @@ get_pubkey_byname (GETKEY_CTX *retctx, PKT_public_key *pk,
      a followup call to get_pubkey_next shall succeed.  */
   if (!no_akl)
     {
-      for (akl=opt.auto_key_locate; akl; akl=akl->next)
-        if (akl->type == AKL_NODEFAULT || akl->type == AKL_LOCAL)
-          {
-            nodefault = 1;
-            break;
-          }
-      for (akl=opt.auto_key_locate; akl; akl=akl->next)
-        if (akl->type != AKL_NODEFAULT)
-          {
-            if (akl->type == AKL_LOCAL)
-              anylocalfirst = 1;
-            break;
-          }
+      for (akl = opt.auto_key_locate; akl; akl = akl->next)
+       if (akl->type == AKL_NODEFAULT || akl->type == AKL_LOCAL)
+         {
+           nodefault = 1;
+           break;
+         }
+      for (akl = opt.auto_key_locate; akl; akl = akl->next)
+       if (akl->type != AKL_NODEFAULT)
+         {
+           if (akl->type == AKL_LOCAL)
+             anylocalfirst = 1;
+           break;
+         }
     }
 
   if (!nodefault)
@@ -987,92 +750,94 @@ get_pubkey_byname (GETKEY_CTX *retctx, PKT_public_key *pk,
   else
     {
       add_to_strlist (&namelist, name);
-      rc = key_byname (retctx, namelist, pk, NULL, 0,
-                       include_unusable, ret_keyblock, ret_kdbhd);
+      rc = key_byname (retctx, namelist, pk, 0,
+                      include_unusable, ret_keyblock, ret_kdbhd);
     }
 
   /* If the requested name resembles a valid mailbox and automatic
      retrieval has been enabled, we try to import the key. */
   if (gpg_err_code (rc) == G10ERR_NO_PUBKEY && !no_akl && is_mbox)
     {
-      for (akl=opt.auto_key_locate; akl; akl=akl->next)
+      for (akl = opt.auto_key_locate; akl; akl = akl->next)
        {
          unsigned char *fpr = NULL;
          size_t fpr_len;
-          int did_key_byname = 0;
-          int no_fingerprint = 0;
-          const char *mechanism = "?";
+         int did_key_byname = 0;
+         int no_fingerprint = 0;
+         const char *mechanism = "?";
 
-          switch(akl->type)
+         switch (akl->type)
            {
-            case AKL_NODEFAULT:
-              /* This is a dummy mechanism.  */
-              mechanism = "None";
-              rc = G10ERR_NO_PUBKEY;
-              break;
-
-            case AKL_LOCAL:
-              mechanism = "Local";
-              did_key_byname = 1;
-              if (retctx)
-                {
-                  get_pubkey_end (*retctx);
-                  *retctx = NULL;
-                }
-              add_to_strlist (&namelist, name);
-              rc = key_byname (anylocalfirst? retctx:NULL,
-                               namelist, pk, NULL, 0,
-                               include_unusable, ret_keyblock, ret_kdbhd);
-              break;
+           case AKL_NODEFAULT:
+             /* This is a dummy mechanism.  */
+             mechanism = "None";
+             rc = G10ERR_NO_PUBKEY;
+             break;
+
+           case AKL_LOCAL:
+             mechanism = "Local";
+             did_key_byname = 1;
+             if (retctx)
+               {
+                 get_pubkey_end (*retctx);
+                 *retctx = NULL;
+               }
+             add_to_strlist (&namelist, name);
+             rc = key_byname (anylocalfirst ? retctx : NULL,
+                              namelist, pk, 0,
+                              include_unusable, ret_keyblock, ret_kdbhd);
+             break;
 
            case AKL_CERT:
-              mechanism = "DNS CERT";
+             mechanism = "DNS CERT";
              glo_ctrl.in_auto_key_retrieve++;
-             rc=keyserver_import_cert(name,&fpr,&fpr_len);
+             rc = keyserver_import_cert (ctrl, name, &fpr, &fpr_len);
              glo_ctrl.in_auto_key_retrieve--;
              break;
 
            case AKL_PKA:
-              mechanism = "PKA";
+             mechanism = "PKA";
              glo_ctrl.in_auto_key_retrieve++;
-             rc=keyserver_import_pka(name,&fpr,&fpr_len);
+             rc = keyserver_import_pka (ctrl, name, &fpr, &fpr_len);
              glo_ctrl.in_auto_key_retrieve--;
              break;
 
            case AKL_LDAP:
-              mechanism = "LDAP";
+             mechanism = "LDAP";
              glo_ctrl.in_auto_key_retrieve++;
-             rc=keyserver_import_ldap(name,&fpr,&fpr_len);
+             rc = keyserver_import_ldap (ctrl, name, &fpr, &fpr_len);
              glo_ctrl.in_auto_key_retrieve--;
              break;
 
            case AKL_KEYSERVER:
              /* Strictly speaking, we don't need to only use a valid
-                mailbox for the getname search, but it helps cut down
-                on the problem of searching for something like "john"
-                and getting a whole lot of keys back. */
-             if(opt.keyserver)
+                mailbox for the getname search, but it helps cut down
+                on the problem of searching for something like "john"
+                and getting a whole lot of keys back. */
+             if (opt.keyserver)
                {
-                  mechanism = opt.keyserver->uri;
+                 mechanism = opt.keyserver->uri;
                  glo_ctrl.in_auto_key_retrieve++;
-                 rc=keyserver_import_name(name,&fpr,&fpr_len,opt.keyserver);
+                 rc = keyserver_import_name (ctrl, name, &fpr, &fpr_len,
+                                              opt.keyserver);
                  glo_ctrl.in_auto_key_retrieve--;
                }
-              else
-                {
-                  mechanism = "Unconfigured keyserver";
-                  rc = G10ERR_NO_PUBKEY;
-                }
+             else
+               {
+                 mechanism = "Unconfigured keyserver";
+                 rc = G10ERR_NO_PUBKEY;
+               }
              break;
 
            case AKL_SPEC:
              {
                struct keyserver_spec *keyserver;
 
-                mechanism = akl->spec->uri;
-               keyserver=keyserver_match(akl->spec);
+               mechanism = akl->spec->uri;
+               keyserver = keyserver_match (akl->spec);
                glo_ctrl.in_auto_key_retrieve++;
-               rc=keyserver_import_name(name,&fpr,&fpr_len,keyserver);
+               rc = keyserver_import_name (ctrl,
+                                            name, &fpr, &fpr_len, keyserver);
                glo_ctrl.in_auto_key_retrieve--;
              }
              break;
@@ -1087,50 +852,51 @@ get_pubkey_byname (GETKEY_CTX *retctx, PKT_public_key *pk,
             won't use the attacker's key here. */
          if (!rc && fpr)
            {
-             char fpr_string[MAX_FINGERPRINT_LEN*2+1];
+             char fpr_string[MAX_FINGERPRINT_LEN * 2 + 1];
 
-             assert(fpr_len<=MAX_FINGERPRINT_LEN);
+             assert (fpr_len <= MAX_FINGERPRINT_LEN);
 
-             free_strlist(namelist);
-             namelist=NULL;
+             free_strlist (namelist);
+             namelist = NULL;
 
-              bin2hex (fpr, fpr_len, fpr_string);
+             bin2hex (fpr, fpr_len, fpr_string);
 
-             if(opt.verbose)
-               log_info("auto-key-locate found fingerprint %s\n",fpr_string);
+             if (opt.verbose)
+               log_info ("auto-key-locate found fingerprint %s\n",
+                         fpr_string);
 
-             add_to_strlist( &namelist, fpr_string );
+             add_to_strlist (&namelist, fpr_string);
            }
-          else if (!rc && !fpr && !did_key_byname)
-            {
-              no_fingerprint = 1;
-              rc = G10ERR_NO_PUBKEY;
-            }
-          xfree (fpr);
-          fpr = NULL;
+         else if (!rc && !fpr && !did_key_byname)
+           {
+             no_fingerprint = 1;
+             rc = G10ERR_NO_PUBKEY;
+           }
+         xfree (fpr);
+         fpr = NULL;
 
-          if (!rc && !did_key_byname)
-            {
-              if (retctx)
-                {
-                  get_pubkey_end (*retctx);
-                  *retctx = NULL;
-                }
-              rc = key_byname (anylocalfirst?retctx:NULL,
-                               namelist, pk, NULL, 0,
-                               include_unusable, ret_keyblock, ret_kdbhd);
-            }
-         if (!rc)
-            {
-              /* Key found.  */
-              log_info (_("automatically retrieved `%s' via %s\n"),
-                        name, mechanism);
-              break;
-            }
-          if (rc != G10ERR_NO_PUBKEY || opt.verbose || no_fingerprint)
-            log_info (_("error retrieving `%s' via %s: %s\n"),
-                      name, mechanism,
-                      no_fingerprint? _("No fingerprint"):g10_errstr(rc));
+         if (!rc && !did_key_byname)
+           {
+             if (retctx)
+               {
+                 get_pubkey_end (*retctx);
+                 *retctx = NULL;
+               }
+             rc = key_byname (anylocalfirst ? retctx : NULL,
+                              namelist, pk, 0,
+                              include_unusable, ret_keyblock, ret_kdbhd);
+           }
+         if (!rc)
+           {
+             /* Key found.  */
+             log_info (_("automatically retrieved '%s' via %s\n"),
+                       name, mechanism);
+             break;
+           }
+         if (rc != G10ERR_NO_PUBKEY || opt.verbose || no_fingerprint)
+           log_info (_("error retrieving '%s' via %s: %s\n"),
+                     name, mechanism,
+                     no_fingerprint ? _("No fingerprint") : g10_errstr (rc));
        }
     }
 
@@ -1153,70 +919,86 @@ get_pubkey_byname (GETKEY_CTX *retctx, PKT_public_key *pk,
 
 
 int
-get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk,
-                   strlist_t names, KBNODE *ret_keyblock )
+get_pubkey_bynames (GETKEY_CTX * retctx, PKT_public_key * pk,
+                   strlist_t names, KBNODE * ret_keyblock)
 {
-    return key_byname( retctx, names, pk, NULL, 0, 1, ret_keyblock, NULL);
+  return key_byname (retctx, names, pk, 0, 1, ret_keyblock, NULL);
 }
 
 int
-get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
+get_pubkey_next (GETKEY_CTX ctx, PKT_public_key * pk, KBNODE * ret_keyblock)
 {
-    int rc;
-
-    rc = lookup( ctx, ret_keyblock, 0 );
-    if ( !rc && pk && ret_keyblock )
-        pk_from_block ( ctx, pk, *ret_keyblock );
-
-    return rc;
+  return gpg_err_code (getkey_next (ctx, pk, ret_keyblock));
 }
 
 void
-get_pubkey_end( GETKEY_CTX ctx )
+get_pubkey_end (GETKEY_CTX ctx)
 {
-    if( ctx ) {
-        memset (&ctx->kbpos, 0, sizeof ctx->kbpos);
-        keydb_release (ctx->kr_handle);
-        free_strlist (ctx->extra_list);
-       if( !ctx->not_allocated )
-           xfree( ctx );
-    }
+  getkey_end (ctx);
 }
 
 
-/****************
- * Search for a key with the given fingerprint.
+/* Search for a key with the given standard fingerprint.  In contrast
+ * to get_pubkey_byfprint we assume a right padded fingerprint of the
+ * standard length.  PK may be NULL to only put the result into the
+ * internal caches.  */
+gpg_error_t
+get_pubkey_byfpr (PKT_public_key *pk, const byte *fpr)
+{
+  gpg_error_t err;
+  struct getkey_ctx_s ctx;
+  kbnode_t kb = NULL;
+
+  memset (&ctx, 0, sizeof ctx);
+  ctx.exact = 1;
+  ctx.not_allocated = 1;
+  ctx.kr_handle = keydb_new ();
+  ctx.nitems = 1;
+  ctx.items[0].mode = KEYDB_SEARCH_MODE_FPR;
+  memcpy (ctx.items[0].u.fpr, fpr, MAX_FINGERPRINT_LEN);
+  err = lookup (&ctx, &kb, 0);
+  if (!err && pk)
+    pk_from_block (&ctx, pk, kb);
+  release_kbnode (kb);
+  get_pubkey_end (&ctx);
+
+  return err;
+}
+
+
+/* Search for a key with the given fingerprint.
  * FIXME:
- * We should replace this with the _byname function.  Thiscsan be done
+ * We should replace this with the _byname function.  This can be done
  * by creating a userID conforming to the unified fingerprint style.
  */
 int
-get_pubkey_byfprint( PKT_public_key *pk,
-                     const byte *fprint, size_t fprint_len)
+get_pubkey_byfprint (PKT_public_key * pk,
+                    const byte * fprint, size_t fprint_len)
 {
-    int rc;
-
-    if( fprint_len == 20 || fprint_len == 16 ) {
-       struct getkey_ctx_s ctx;
-        KBNODE kb = NULL;
-
-       memset( &ctx, 0, sizeof ctx );
-        ctx.exact = 1 ;
-       ctx.not_allocated = 1;
-        ctx.kr_handle = keydb_new (0);
-       ctx.nitems = 1;
-       ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
-                                          : KEYDB_SEARCH_MODE_FPR20;
-       memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
-       rc = lookup( &ctx, &kb, 0 );
-        if (!rc && pk )
-            pk_from_block ( &ctx, pk, kb );
-        release_kbnode ( kb );
-       get_pubkey_end( &ctx );
-    }
-    else
-       rc = G10ERR_GENERAL; /* Oops */
-    return rc;
+  int rc;
+
+  if (fprint_len == 20 || fprint_len == 16)
+    {
+      struct getkey_ctx_s ctx;
+      KBNODE kb = NULL;
+
+      memset (&ctx, 0, sizeof ctx);
+      ctx.exact = 1;
+      ctx.not_allocated = 1;
+      ctx.kr_handle = keydb_new ();
+      ctx.nitems = 1;
+      ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16
+       : KEYDB_SEARCH_MODE_FPR20;
+      memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
+      rc = lookup (&ctx, &kb, 0);
+      if (!rc && pk)
+       pk_from_block (&ctx, pk, kb);
+      release_kbnode (kb);
+      get_pubkey_end (&ctx);
+    }
+  else
+    rc = G10ERR_GENERAL; /* Oops */
+  return rc;
 }
 
 
@@ -1224,10 +1006,10 @@ get_pubkey_byfprint( PKT_public_key *pk,
    differs from get_pubkey_byfprint() in that it does not do a check
    of the key to avoid recursion.  It should be used only in very
    certain cases.  PK may be NULL to check just for the existance of
-   the key. */
+   the key.  */
 int
-get_pubkey_byfprint_fast (PKT_public_key *pk,
-                          const byte *fprint, size_t fprint_len)
+get_pubkey_byfprint_fast (PKT_public_key * pk,
+                         const byte * fprint, size_t fprint_len)
 {
   int rc = 0;
   KEYDB_HANDLE hd;
@@ -1235,14 +1017,14 @@ get_pubkey_byfprint_fast (PKT_public_key *pk,
   byte fprbuf[MAX_FINGERPRINT_LEN];
   int i;
 
-  for (i=0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++)
+  for (i = 0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++)
     fprbuf[i] = fprint[i];
   while (i < MAX_FINGERPRINT_LEN)
     fprbuf[i++] = 0;
 
-  hd = keydb_new (0);
+  hd = keydb_new ();
   rc = keydb_search_fpr (hd, fprbuf);
-  if (rc == -1)
+  if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
     {
       keydb_release (hd);
       return G10ERR_NO_PUBKEY;
@@ -1251,14 +1033,14 @@ get_pubkey_byfprint_fast (PKT_public_key *pk,
   keydb_release (hd);
   if (rc)
     {
-      log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
+      log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
       return G10ERR_NO_PUBKEY;
     }
 
-  assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY
-           ||  keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY );
+  assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
+         || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY);
   if (pk)
-    copy_public_key (pk, keyblock->pkt->pkt.public_key );
+    copy_public_key (pk, keyblock->pkt->pkt.public_key);
   release_kbnode (keyblock);
 
   /* Not caching key here since it won't have all of the fields
@@ -1267,305 +1049,309 @@ get_pubkey_byfprint_fast (PKT_public_key *pk,
   return 0;
 }
 
-/****************
- * Search for a key with the given fingerprint and return the
- * complete keyblock which may have more than only this key.
- */
+
+/* Search for a key with the given fingerprint and return the
+ * complete keyblock which may have more than only this key.   */
 int
-get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
-                                               size_t fprint_len )
+get_keyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint,
+                      size_t fprint_len)
 {
-    int rc;
-
-    if( fprint_len == 20 || fprint_len == 16 ) {
-       struct getkey_ctx_s ctx;
+  int rc;
 
-       memset( &ctx, 0, sizeof ctx );
-       ctx.not_allocated = 1;
-        ctx.kr_handle = keydb_new (0);
-       ctx.nitems = 1;
-       ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
-                                          : KEYDB_SEARCH_MODE_FPR20;
-       memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
-       rc = lookup( &ctx, ret_keyblock, 0 );
-       get_pubkey_end( &ctx );
+  if (fprint_len == 20 || fprint_len == 16)
+    {
+      struct getkey_ctx_s ctx;
+
+      memset (&ctx, 0, sizeof ctx);
+      ctx.not_allocated = 1;
+      ctx.kr_handle = keydb_new ();
+      ctx.nitems = 1;
+      ctx.items[0].mode = (fprint_len == 16
+                           ? KEYDB_SEARCH_MODE_FPR16
+                           : KEYDB_SEARCH_MODE_FPR20);
+      memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
+      rc = lookup (&ctx, ret_keyblock, 0);
+      get_pubkey_end (&ctx);
     }
-    else
-       rc = G10ERR_GENERAL; /* Oops */
+  else
+    rc = G10ERR_GENERAL; /* Oops */
 
-    return rc;
+  return rc;
 }
 
 
-/****************
- * Get a secret key by name and store it into sk
- * If NAME is NULL use the default key
- */
-static int
-get_seckey_byname2( GETKEY_CTX *retctx,
-                   PKT_secret_key *sk, const char *name, int unprotect,
-                   KBNODE *retblock )
+/* Get a secret key by NAME and store it into PK.  If NAME is NULL use
+ * the default key.  This functions checks that a corresponding secret
+ * key is available.  With no secret key it does not succeeed. */
+gpg_error_t
+get_seckey_byname (PKT_public_key *pk, const char *name)
 {
+  gpg_error_t err;
   strlist_t namelist = NULL;
-  int rc,include_unusable=1;
+  int include_unusable = 1;
 
   /* If we have no name, try to use the default secret key.  If we
      have no default, we'll use the first usable one. */
 
-  if( !name && opt.def_secret_key && *opt.def_secret_key )
-    add_to_strlist( &namelist, opt.def_secret_key );
-  else if(name)
-    add_to_strlist( &namelist, name );
+  if (!name && opt.def_secret_key && *opt.def_secret_key)
+    add_to_strlist (&namelist, opt.def_secret_key);
+  else if (name)
+    add_to_strlist (&namelist, name);
   else
-    include_unusable=0;
-
-  rc = key_byname( retctx, namelist, NULL, sk, 1, include_unusable,
-                  retblock, NULL );
+    include_unusable = 0;
 
-  free_strlist( namelist );
+  err = key_byname (NULL, namelist, pk, 1, include_unusable, NULL, NULL);
 
-  if( !rc && unprotect )
-    rc = check_secret_key( sk, 0 );
+  free_strlist (namelist);
 
-  return rc;
+  return err;
 }
 
-int
-get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock )
-{
-    return get_seckey_byname2 ( NULL, sk, name, unlock, NULL );
-}
 
 
-int
-get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk,
-                   strlist_t names, KBNODE *ret_keyblock )
+/* Search for a key with the given fingerprint.
+ * FIXME:
+ * We should replace this with the _byname function.  This can be done
+ * by creating a userID conforming to the unified fingerprint style.   */
+gpg_error_t
+get_seckey_byfprint (PKT_public_key *pk, const byte * fprint, size_t fprint_len)
 {
-    return key_byname( retctx, names, NULL, sk, 1, 1, ret_keyblock, NULL );
+  gpg_error_t err;
+
+  if (fprint_len == 20 || fprint_len == 16)
+    {
+      struct getkey_ctx_s ctx;
+      kbnode_t kb = NULL;
+
+      memset (&ctx, 0, sizeof ctx);
+      ctx.exact = 1;
+      ctx.not_allocated = 1;
+      ctx.kr_handle = keydb_new ();
+      ctx.nitems = 1;
+      ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16
+       : KEYDB_SEARCH_MODE_FPR20;
+      memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
+      err = lookup (&ctx, &kb, 1);
+      if (!err && pk)
+       pk_from_block (&ctx, pk, kb);
+      release_kbnode (kb);
+      get_pubkey_end (&ctx);
+    }
+  else
+    err = gpg_error (GPG_ERR_BUG);
+  return err;
 }
 
 
-int
-get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
+/* Search for a secret key with the given fingerprint and return the
+   complete keyblock which may have more than only this key.  Return
+   an error if no corresponding secret key is available.  */
+gpg_error_t
+get_seckeyblock_byfprint (kbnode_t *ret_keyblock,
+                          const byte *fprint, size_t fprint_len)
 {
-    int rc;
+  gpg_error_t err;
+  struct getkey_ctx_s ctx;
+
+  if (fprint_len != 20 && fprint_len == 16)
+    return gpg_error (GPG_ERR_BUG);
 
-    rc = lookup( ctx, ret_keyblock, 1 );
-    if ( !rc && sk && ret_keyblock )
-        sk_from_block ( ctx, sk, *ret_keyblock );
+  memset (&ctx, 0, sizeof ctx);
+  ctx.not_allocated = 1;
+  ctx.kr_handle = keydb_new ();
+  ctx.nitems = 1;
+  ctx.items[0].mode = (fprint_len == 16
+                      ? KEYDB_SEARCH_MODE_FPR16 : KEYDB_SEARCH_MODE_FPR20);
+  memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
+  err = lookup (&ctx, ret_keyblock, 1);
+  get_pubkey_end (&ctx);
 
-    return rc;
+  return err;
 }
 
 
-void
-get_seckey_end( GETKEY_CTX ctx )
+\f
+/* The new function to return a key.
+   FIXME: Document it.  */
+gpg_error_t
+getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
+                strlist_t names, int want_secret, kbnode_t *ret_keyblock)
 {
-    get_pubkey_end( ctx );
+  return key_byname (retctx, names, pk, want_secret, 1,
+                     ret_keyblock, NULL);
 }
 
 
-/****************
- * Search for a key with the given fingerprint.
- * FIXME:
- * We should replace this with the _byname function.  Thiscsan be done
- * by creating a userID conforming to the unified fingerprint style.
+/* Get a key by name and store it into PK if that is not NULL.  If
+ * RETCTX is not NULL return the search context which needs to be
+ * released by the caller using getkey_end.  If NAME is NULL use the
+ * default key (see below).  On success and if RET_KEYBLOCK is not
+ * NULL the found keyblock is stored at this address.  WANT_SECRET
+ * passed as true requires that a secret key is available for the
+ * selected key.
+ *
+ * If WANT_SECRET is true and NAME is NULL and a default key has been
+ * defined that defined key is used.  In all other cases the first
+ * available key is used.
+ *
+ * FIXME: Explain what is up with unusable keys.
+ *
+ * FIXME: We also have the get_pubkey_byname function which has a
+ * different semantic.  Should be merged with this one.
  */
-int
-get_seckey_byfprint( PKT_secret_key *sk,
-                     const byte *fprint, size_t fprint_len)
+gpg_error_t
+getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
+               const char *name, int want_secret, kbnode_t *ret_keyblock)
 {
-    int rc;
-
-    if( fprint_len == 20 || fprint_len == 16 ) {
-       struct getkey_ctx_s ctx;
-        KBNODE kb = NULL;
-
-       memset( &ctx, 0, sizeof ctx );
-        ctx.exact = 1 ;
-       ctx.not_allocated = 1;
-        ctx.kr_handle = keydb_new (1);
-       ctx.nitems = 1;
-       ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
-                                          : KEYDB_SEARCH_MODE_FPR20;
-       memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
-       rc = lookup( &ctx, &kb, 1 );
-        if (!rc && sk )
-            sk_from_block ( &ctx, sk, kb );
-        release_kbnode ( kb );
-       get_seckey_end( &ctx );
-    }
-    else
-       rc = G10ERR_GENERAL; /* Oops */
-    return rc;
+  gpg_error_t err;
+  strlist_t namelist = NULL;
+  int with_unusable = 1;
+
+  if (want_secret && !name && opt.def_secret_key && *opt.def_secret_key)
+    add_to_strlist (&namelist, opt.def_secret_key);
+  else if (name)
+    add_to_strlist (&namelist, name);
+  else
+    with_unusable = 0;
+
+  err = key_byname (retctx, namelist, pk, want_secret, with_unusable,
+                    ret_keyblock, NULL);
+
+  /* FIXME: Check that we really return GPG_ERR_NO_SECKEY if
+     WANT_SECRET has been used.  */
+
+  free_strlist (namelist);
+
+  return err;
 }
 
 
-/* Search for a secret key with the given fingerprint and return the
-   complete keyblock which may have more than only this key. */
-int
-get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint,
-                          size_t fprint_len )
+/* The new function to return the next key.  */
+gpg_error_t
+getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock)
 {
-  int rc;
-  struct getkey_ctx_s ctx;
+  int rc; /* Fixme:  Make sure this is proper gpg_error */
 
-  if (fprint_len != 20 && fprint_len == 16)
-    return G10ERR_GENERAL; /* Oops */
+  /* We need to disable the caching so that for an exact key search we
+     won't get the result back from the cache and thus end up in an
+     endless loop.  Disabling this here is sufficient because although
+     the result has been cached, if won't be used then.  */
+  keydb_disable_caching (ctx->kr_handle);
 
-  memset (&ctx, 0, sizeof ctx);
-  ctx.exact = 1 ;
-  ctx.not_allocated = 1;
-  ctx.kr_handle = keydb_new (1);
-  ctx.nitems = 1;
-  ctx.items[0].mode = (fprint_len==16
-                       ? KEYDB_SEARCH_MODE_FPR16
-                       : KEYDB_SEARCH_MODE_FPR20);
-  memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
-  rc = lookup (&ctx, ret_keyblock, 1);
-  get_seckey_end (&ctx);
+  rc = lookup (ctx, ret_keyblock, ctx->want_secret);
+  if (!rc && pk && ret_keyblock)
+    pk_from_block (ctx, pk, *ret_keyblock);
 
   return rc;
 }
 
 
+/* The new function to finish a key listing.  */
+void
+getkey_end (getkey_ctx_t ctx)
+{
+  if (ctx)
+    {
+      memset (&ctx->kbpos, 0, sizeof ctx->kbpos);
+      keydb_release (ctx->kr_handle);
+      free_strlist (ctx->extra_list);
+      if (!ctx->not_allocated)
+       xfree (ctx);
+    }
+}
+
+
 \f
 /************************************************
  ************* Merging stuff ********************
  ************************************************/
 
-/****************
- * merge all selfsignatures with the keys.
- * FIXME: replace this at least for the public key parts
- *        by merge_selfsigs.
- *        It is still used in keyedit.c and
- *        at 2 or 3 other places - check whether it is really needed.
- *        It might be needed by the key edit and import stuff because
- *        the keylock is changed.
- */
+/* Set the mainkey_id fields for all keys in KEYBLOCK.  This is
+   usually done by merge_selfsigs but at some places we only need the
+   main_kid but the the full merging.  The function also guarantees
+   that all pk->keyids are computed. */
 void
-merge_keys_and_selfsig( KBNODE keyblock )
+setup_main_keyids (kbnode_t keyblock)
 {
-    PKT_public_key *pk = NULL;
-    PKT_secret_key *sk = NULL;
-    PKT_signature *sig;
-    KBNODE k;
-    u32 kid[2] = { 0, 0 };
-    u32 sigdate = 0;
-
-    if (keyblock && keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) {
-        /* divert to our new function */
-        merge_selfsigs (keyblock);
-        return;
-    }
-    /* still need the old one because the new one can't handle secret keys */
-
-    for(k=keyblock; k; k = k->next ) {
-       if( k->pkt->pkttype == PKT_PUBLIC_KEY
-           || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-           pk = k->pkt->pkt.public_key; sk = NULL;
-           if( pk->version < 4 )
-               pk = NULL; /* not needed for old keys */
-           else if( k->pkt->pkttype == PKT_PUBLIC_KEY )
-               keyid_from_pk( pk, kid );
-           else if( !pk->expiredate ) { /* and subkey */
-               /* insert the expiration date here */
-               /*FIXME!!! pk->expiredate = subkeys_expiretime( k, kid );*/
-           }
-           sigdate = 0;
-       }
-       else if( k->pkt->pkttype == PKT_SECRET_KEY
-           || k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-           pk = NULL; sk = k->pkt->pkt.secret_key;
-           if( sk->version < 4 )
-               sk = NULL;
-           else if( k->pkt->pkttype == PKT_SECRET_KEY )
-               keyid_from_sk( sk, kid );
-           sigdate = 0;
-       }
-       else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE
-                && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
-                && sig->sig_class <= 0x30 && sig->version > 3
-                && !(sig->sig_class == 0x18 || sig->sig_class == 0x28)
-                && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
-           /* okay this is a self-signature which can be used.
-            * This is not used for subkey binding signature, becuase this
-            * is done above.
-            * FIXME: We should only use this if the signature is valid
-            *        but this is time consuming - we must provide another
-            *        way to handle this
-            */
-           const byte *p;
-           u32 ed;
-
-           p = parse_sig_subpkt( sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL );
-           if( pk ) {
-               ed = p? pk->timestamp + buf32_to_u32(p):0;
-               if( sig->timestamp > sigdate ) {
-                   pk->expiredate = ed;
-                   sigdate = sig->timestamp;
-               }
-           }
-           else {
-               ed = p? sk->timestamp + buf32_to_u32(p):0;
-               if( sig->timestamp > sigdate ) {
-                   sk->expiredate = ed;
-                   sigdate = sig->timestamp;
-               }
-           }
-       }
+  u32 kid[2], mainkid[2];
+  kbnode_t kbctx, node;
+  PKT_public_key *pk;
 
-       if(pk && (pk->expiredate==0 ||
-                 (pk->max_expiredate && pk->expiredate>pk->max_expiredate)))
-         pk->expiredate=pk->max_expiredate;
+  if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
+    BUG ();
+  pk = keyblock->pkt->pkt.public_key;
 
-       if(sk && (sk->expiredate==0 ||
-                 (sk->max_expiredate && sk->expiredate>sk->max_expiredate)))
-         sk->expiredate=sk->max_expiredate;
+  keyid_from_pk (pk, mainkid);
+  for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
+    {
+      if (!(node->pkt->pkttype == PKT_PUBLIC_KEY
+            || node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
+        continue;
+      pk = node->pkt->pkt.public_key;
+      keyid_from_pk (pk, kid); /* Make sure pk->keyid is set.  */
+      if (!pk->main_keyid[0] && !pk->main_keyid[1])
+        {
+          pk->main_keyid[0] = mainkid[0];
+          pk->main_keyid[1] = mainkid[1];
+        }
     }
 }
 
+
+/* Merge all self-signatures with the keys.  */
+void
+merge_keys_and_selfsig (KBNODE keyblock)
+{
+  if (!keyblock)
+    ;
+  else if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY)
+    merge_selfsigs (keyblock);
+  else
+    log_debug ("FIXME: merging secret key blocks is not anymore available\n");
+}
+
+
 static int
-parse_key_usage(PKT_signature *sig)
+parse_key_usage (PKT_signature * sig)
 {
-  int key_usage=0;
+  int key_usage = 0;
   const byte *p;
   size_t n;
   byte flags;
 
-  p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_KEY_FLAGS,&n);
-  if(p && n)
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n);
+  if (p && n)
     {
-      /* first octet of the keyflags */
-      flags=*p;
+      /* First octet of the keyflags.  */
+      flags = *p;
 
-      if(flags & 1)
+      if (flags & 1)
        {
          key_usage |= PUBKEY_USAGE_CERT;
-         flags&=~1;
+         flags &= ~1;
        }
 
-      if(flags & 2)
+      if (flags & 2)
        {
          key_usage |= PUBKEY_USAGE_SIG;
-         flags&=~2;
+         flags &= ~2;
        }
 
       /* We do not distinguish between encrypting communications and
-        encrypting storage. */
-      if(flags & (0x04|0x08))
+         encrypting storage. */
+      if (flags & (0x04 | 0x08))
        {
          key_usage |= PUBKEY_USAGE_ENC;
-         flags&=~(0x04|0x08);
+         flags &= ~(0x04 | 0x08);
        }
 
-      if(flags & 0x20)
+      if (flags & 0x20)
        {
          key_usage |= PUBKEY_USAGE_AUTH;
-         flags&=~0x20;
+         flags &= ~0x20;
        }
 
-      if(flags)
+      if (flags)
        key_usage |= PUBKEY_USAGE_UNKNOWN;
 
       if (!key_usage)
@@ -1584,8 +1370,8 @@ parse_key_usage(PKT_signature *sig)
   return key_usage;
 }
 
-/*
- * Apply information from SIGNODE (which is the valid self-signature
+
+/* Apply information from SIGNODE (which is the valid self-signature
  * associated with that UID) to the UIDNODE:
  * - wether the UID has been revoked
  * - assumed creation date of the UID
@@ -1595,108 +1381,115 @@ parse_key_usage(PKT_signature *sig)
  * - store the preferences
  */
 static void
-fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
+fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
 {
-    PKT_user_id   *uid = uidnode->pkt->pkt.user_id;
-    PKT_signature *sig = signode->pkt->pkt.signature;
-    const byte *p, *sym, *hash, *zip;
-    size_t n, nsym, nhash, nzip;
-
-    sig->flags.chosen_selfsig = 1; /* we chose this one */
-    uid->created = 0; /* not created == invalid */
-    if ( IS_UID_REV ( sig ) )
-      {
-        uid->is_revoked = 1;
-        return; /* has been revoked */
-      }
-    else
-      uid->is_revoked = 0;
-
-    uid->expiredate = sig->expiredate;
+  PKT_user_id *uid = uidnode->pkt->pkt.user_id;
+  PKT_signature *sig = signode->pkt->pkt.signature;
+  const byte *p, *sym, *hash, *zip;
+  size_t n, nsym, nhash, nzip;
+
+  sig->flags.chosen_selfsig = 1;/* We chose this one. */
+  uid->created = 0;            /* Not created == invalid. */
+  if (IS_UID_REV (sig))
+    {
+      uid->is_revoked = 1;
+      return; /* Has been revoked.  */
+    }
+  else
+    uid->is_revoked = 0;
 
-    if (sig->flags.expired)
-      {
-       uid->is_expired = 1;
-       return; /* has expired */
-      }
-    else
-      uid->is_expired = 0;
+  uid->expiredate = sig->expiredate;
 
-    uid->created = sig->timestamp; /* this one is okay */
-    uid->selfsigversion = sig->version;
-    /* If we got this far, it's not expired :) */
+  if (sig->flags.expired)
+    {
+      uid->is_expired = 1;
+      return; /* Has expired.  */
+    }
+  else
     uid->is_expired = 0;
 
-    /* store the key flags in the helper variable for later processing */
-    uid->help_key_usage=parse_key_usage(sig);
-
-    /* ditto for the key expiration */
-    p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
-    if( p && buf32_to_u32 (p) )
-      uid->help_key_expire = keycreated + buf32_to_u32(p);
-    else
-      uid->help_key_expire = 0;
-
-    /* Set the primary user ID flag - we will later wipe out some
-     * of them to only have one in our keyblock */
-    uid->is_primary = 0;
-    p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL );
-    if ( p && *p )
-        uid->is_primary = 2;
-    /* We could also query this from the unhashed area if it is not in
-     * the hased area and then later try to decide which is the better
-     * there should be no security problem with this.
-     * For now we only look at the hashed one.
-     */
-
-    /* Now build the preferences list.  These must come from the
-       hashed section so nobody can modify the ciphers a key is
-       willing to accept. */
-    p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_SYM, &n );
-    sym = p; nsym = p?n:0;
-    p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_HASH, &n );
-    hash = p; nhash = p?n:0;
-    p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_COMPR, &n );
-    zip = p; nzip = p?n:0;
-    if (uid->prefs)
-        xfree (uid->prefs);
-    n = nsym + nhash + nzip;
-    if (!n)
-        uid->prefs = NULL;
-    else {
-        uid->prefs = xmalloc (sizeof (*uid->prefs) * (n+1));
-        n = 0;
-        for (; nsym; nsym--, n++) {
-            uid->prefs[n].type = PREFTYPE_SYM;
-            uid->prefs[n].value = *sym++;
-        }
-        for (; nhash; nhash--, n++) {
-            uid->prefs[n].type = PREFTYPE_HASH;
-            uid->prefs[n].value = *hash++;
-        }
-        for (; nzip; nzip--, n++) {
-            uid->prefs[n].type = PREFTYPE_ZIP;
-            uid->prefs[n].value = *zip++;
-        }
-        uid->prefs[n].type = PREFTYPE_NONE; /* end of list marker */
-        uid->prefs[n].value = 0;
+  uid->created = sig->timestamp; /* This one is okay. */
+  uid->selfsigversion = sig->version;
+  /* If we got this far, it's not expired :) */
+  uid->is_expired = 0;
+
+  /* Store the key flags in the helper variable for later processing.  */
+  uid->help_key_usage = parse_key_usage (sig);
+
+  /* Ditto for the key expiration.  */
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
+  if (p && buffer_to_u32 (p))
+    uid->help_key_expire = keycreated + buffer_to_u32 (p);
+  else
+    uid->help_key_expire = 0;
+
+  /* Set the primary user ID flag - we will later wipe out some
+   * of them to only have one in our keyblock.  */
+  uid->is_primary = 0;
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL);
+  if (p && *p)
+    uid->is_primary = 2;
+
+  /* We could also query this from the unhashed area if it is not in
+   * the hased area and then later try to decide which is the better
+   * there should be no security problem with this.
+   * For now we only look at the hashed one.  */
+
+  /* Now build the preferences list.  These must come from the
+     hashed section so nobody can modify the ciphers a key is
+     willing to accept.  */
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_SYM, &n);
+  sym = p;
+  nsym = p ? n : 0;
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_HASH, &n);
+  hash = p;
+  nhash = p ? n : 0;
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_COMPR, &n);
+  zip = p;
+  nzip = p ? n : 0;
+  if (uid->prefs)
+    xfree (uid->prefs);
+  n = nsym + nhash + nzip;
+  if (!n)
+    uid->prefs = NULL;
+  else
+    {
+      uid->prefs = xmalloc (sizeof (*uid->prefs) * (n + 1));
+      n = 0;
+      for (; nsym; nsym--, n++)
+       {
+         uid->prefs[n].type = PREFTYPE_SYM;
+         uid->prefs[n].value = *sym++;
+       }
+      for (; nhash; nhash--, n++)
+       {
+         uid->prefs[n].type = PREFTYPE_HASH;
+         uid->prefs[n].value = *hash++;
+       }
+      for (; nzip; nzip--, n++)
+       {
+         uid->prefs[n].type = PREFTYPE_ZIP;
+         uid->prefs[n].value = *zip++;
+       }
+      uid->prefs[n].type = PREFTYPE_NONE; /* End of list marker  */
+      uid->prefs[n].value = 0;
     }
 
-    /* see whether we have the MDC feature */
-    uid->flags.mdc = 0;
-    p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
-    if (p && n && (p[0] & 0x01))
-        uid->flags.mdc = 1;
+  /* See whether we have the MDC feature.  */
+  uid->flags.mdc = 0;
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
+  if (p && n && (p[0] & 0x01))
+    uid->flags.mdc = 1;
 
-    /* and the keyserver modify flag */
-    uid->flags.ks_modify = 1;
-    p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n);
-    if (p && n && (p[0] & 0x80))
-        uid->flags.ks_modify = 0;
+  /* And the keyserver modify flag.  */
+  uid->flags.ks_modify = 1;
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n);
+  if (p && n && (p[0] & 0x80))
+    uid->flags.ks_modify = 0;
 }
 
 static void
-sig_to_revoke_info(PKT_signature *sig,struct revoke_info *rinfo)
+sig_to_revoke_info (PKT_signature * sig, struct revoke_info *rinfo)
 {
   rinfo->date = sig->timestamp;
   rinfo->algo = sig->pubkey_algo;
@@ -1704,72 +1497,80 @@ sig_to_revoke_info(PKT_signature *sig,struct revoke_info *rinfo)
   rinfo->keyid[1] = sig->keyid[1];
 }
 
+
+/* Note that R_REVOKED may be set to 0, 1 or 2.  */
 static void
-merge_selfsigs_main(KBNODE keyblock, int *r_revoked, struct revoke_info *rinfo)
+merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
+                    struct revoke_info *rinfo)
 {
-    PKT_public_key *pk = NULL;
-    KBNODE k;
-    u32 kid[2];
-    u32 sigdate, uiddate, uiddate2;
-    KBNODE signode, uidnode, uidnode2;
-    u32 curtime = make_timestamp ();
-    unsigned int key_usage = 0;
-    u32 keytimestamp = 0;
-    u32 key_expire = 0;
-    int key_expire_seen = 0;
-    byte sigversion = 0;
-
-    *r_revoked = 0;
-    memset(rinfo,0,sizeof(*rinfo));
-
-    if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY )
-        BUG ();
-    pk = keyblock->pkt->pkt.public_key;
-    keytimestamp = pk->timestamp;
-
-    keyid_from_pk( pk, kid );
-    pk->main_keyid[0] = kid[0];
-    pk->main_keyid[1] = kid[1];
-
-    if ( pk->version < 4 ) {
-        /* before v4 the key packet itself contains the expiration
-         * date and there was no way to change it, so we start with
-         * the one from the key packet */
-        key_expire = pk->max_expiredate;
-        key_expire_seen = 1;
-    }
-
-    /* first pass: find the latest direct key self-signature.
-     * We assume that the newest one overrides all others
-     */
-
-    /* In case this key was already merged */
-    xfree(pk->revkey);
-    pk->revkey=NULL;
-    pk->numrevkeys=0;
-
-    signode = NULL;
-    sigdate = 0; /* helper to find the latest signature */
-    for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next ) {
-        if ( k->pkt->pkttype == PKT_SIGNATURE ) {
-            PKT_signature *sig = k->pkt->pkt.signature;
-            if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) {
-               if ( check_key_signature( keyblock, k, NULL ) )
-                    ; /* signature did not verify */
-                else if ( IS_KEY_REV (sig) ){
-                    /* key has been revoked - there is no way to override
-                     * such a revocation, so we theoretically can stop now.
-                     * We should not cope with expiration times for revocations
-                     * here because we have to assume that an attacker can
-                     * generate all kinds of signatures.  However due to the
-                     * fact that the key has been revoked it does not harm
-                     * either and by continuing we gather some more info on
-                     * that key.
-                     */
-                    *r_revoked = 1;
-                   sig_to_revoke_info(sig,rinfo);
-                }
-                else if ( IS_KEY_SIG (sig) ) {
+  PKT_public_key *pk = NULL;
+  KBNODE k;
+  u32 kid[2];
+  u32 sigdate, uiddate, uiddate2;
+  KBNODE signode, uidnode, uidnode2;
+  u32 curtime = make_timestamp ();
+  unsigned int key_usage = 0;
+  u32 keytimestamp = 0;
+  u32 key_expire = 0;
+  int key_expire_seen = 0;
+  byte sigversion = 0;
+
+  *r_revoked = 0;
+  memset (rinfo, 0, sizeof (*rinfo));
+
+  if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
+    BUG ();
+  pk = keyblock->pkt->pkt.public_key;
+  keytimestamp = pk->timestamp;
+
+  keyid_from_pk (pk, kid);
+  pk->main_keyid[0] = kid[0];
+  pk->main_keyid[1] = kid[1];
+
+  if (pk->version < 4)
+    {
+      /* Before v4 the key packet itself contains the expiration date
+       * and there was no way to change it, so we start with the one
+       * from the key packet.  */
+      key_expire = pk->max_expiredate;
+      key_expire_seen = 1;
+    }
+
+  /* First pass: Find the latest direct key self-signature.  We assume
+   * that the newest one overrides all others.  */
+
+  /* In case this key was already merged. */
+  xfree (pk->revkey);
+  pk->revkey = NULL;
+  pk->numrevkeys = 0;
+
+  signode = NULL;
+  sigdate = 0; /* Helper variable to find the latest signature.  */
+  for (k = keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_SIGNATURE)
+       {
+         PKT_signature *sig = k->pkt->pkt.signature;
+         if (sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1])
+           {
+             if (check_key_signature (keyblock, k, NULL))
+               ; /* Signature did not verify.  */
+             else if (IS_KEY_REV (sig))
+               {
+                 /* Key has been revoked - there is no way to
+                  * override such a revocation, so we theoretically
+                  * can stop now.  We should not cope with expiration
+                  * times for revocations here because we have to
+                  * assume that an attacker can generate all kinds of
+                  * signatures.  However due to the fact that the key
+                  * has been revoked it does not harm either and by
+                  * continuing we gather some more info on that
+                  * key.  */
+                 *r_revoked = 1;
+                 sig_to_revoke_info (sig, rinfo);
+               }
+             else if (IS_KEY_SIG (sig))
+               {
                  /* Add any revocation keys onto the pk.  This is
                     particularly interesting since we normally only
                     get data from the most recent 1F signature, but
@@ -1777,584 +1578,616 @@ merge_selfsigs_main(KBNODE keyblock, int *r_revoked, struct revoke_info *rinfo)
                     revocation keys (PGP does it this way, and a
                     revocation key could be sensitive and hence in a
                     different signature). */
-                 if(sig->revkey) {
-                   int i;
-
-                   pk->revkey=
-                     xrealloc(pk->revkey,sizeof(struct revocation_key)*
-                               (pk->numrevkeys+sig->numrevkeys));
+                 if (sig->revkey)
+                   {
+                     int i;
 
-                   for(i=0;i<sig->numrevkeys;i++)
-                     memcpy(&pk->revkey[pk->numrevkeys++],
-                            sig->revkey[i],
-                            sizeof(struct revocation_key));
-                 }
+                     pk->revkey =
+                       xrealloc (pk->revkey, sizeof (struct revocation_key) *
+                                 (pk->numrevkeys + sig->numrevkeys));
 
-                 if( sig->timestamp >= sigdate ) {
-                   if(sig->flags.expired)
-                        ; /* signature has expired - ignore it */
-                    else {
-                        sigdate = sig->timestamp;
-                        signode = k;
-                       if( sig->version > sigversion )
-                         sigversion = sig->version;
+                     for (i = 0; i < sig->numrevkeys; i++)
+                       memcpy (&pk->revkey[pk->numrevkeys++],
+                               sig->revkey[i],
+                               sizeof (struct revocation_key));
+                   }
 
+                 if (sig->timestamp >= sigdate)
+                   {
+                     if (sig->flags.expired)
+                       ; /* Signature has expired - ignore it.  */
+                     else
+                       {
+                         sigdate = sig->timestamp;
+                         signode = k;
+                         if (sig->version > sigversion)
+                           sigversion = sig->version;
+
+                       }
                    }
-                 }
-                }
-            }
-        }
+               }
+           }
+       }
     }
 
-    /* Remove dupes from the revocation keys */
+  /* Remove dupes from the revocation keys.  */
 
-    if(pk->revkey)
-      {
-       int i,j,x,changed=0;
+  if (pk->revkey)
+    {
+      int i, j, x, changed = 0;
+
+      for (i = 0; i < pk->numrevkeys; i++)
+       {
+         for (j = i + 1; j < pk->numrevkeys; j++)
+           {
+             if (memcmp (&pk->revkey[i], &pk->revkey[j],
+                         sizeof (struct revocation_key)) == 0)
+               {
+                 /* remove j */
+
+                 for (x = j; x < pk->numrevkeys - 1; x++)
+                   pk->revkey[x] = pk->revkey[x + 1];
+
+                 pk->numrevkeys--;
+                 j--;
+                 changed = 1;
+               }
+           }
+       }
+
+      if (changed)
+       pk->revkey = xrealloc (pk->revkey,
+                              pk->numrevkeys *
+                              sizeof (struct revocation_key));
+    }
 
-       for(i=0;i<pk->numrevkeys;i++)
+  if (signode)
+    {
+      /* Some information from a direct key signature take precedence
+       * over the same information given in UID sigs.  */
+      PKT_signature *sig = signode->pkt->pkt.signature;
+      const byte *p;
+
+      key_usage = parse_key_usage (sig);
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
+      if (p && buffer_to_u32 (p))
+       {
+         key_expire = keytimestamp + buffer_to_u32 (p);
+         key_expire_seen = 1;
+       }
+
+      /* Mark that key as valid: One direct key signature should
+       * render a key as valid.  */
+      pk->flags.valid = 1;
+    }
+
+  /* Pass 1.5: Look for key revocation signatures that were not made
+     by the key (i.e. did a revocation key issue a revocation for
+     us?).  Only bother to do this if there is a revocation key in the
+     first place and we're not revoked already.  */
+
+  if (!*r_revoked && pk->revkey)
+    for (k = keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next)
+      {
+       if (k->pkt->pkttype == PKT_SIGNATURE)
          {
-           for(j=i+1;j<pk->numrevkeys;j++)
+           PKT_signature *sig = k->pkt->pkt.signature;
+
+           if (IS_KEY_REV (sig) &&
+               (sig->keyid[0] != kid[0] || sig->keyid[1] != kid[1]))
              {
-               if(memcmp(&pk->revkey[i],&pk->revkey[j],
-                         sizeof(struct revocation_key))==0)
+               int rc = check_revocation_keys (pk, sig);
+               if (rc == 0)
                  {
-                   /* remove j */
+                   *r_revoked = 2;
+                   sig_to_revoke_info (sig, rinfo);
+                   /* Don't continue checking since we can't be any
+                      more revoked than this.  */
+                   break;
+                 }
+               else if (rc == G10ERR_NO_PUBKEY)
+                 pk->flags.maybe_revoked = 1;
 
-                   for(x=j;x<pk->numrevkeys-1;x++)
-                     pk->revkey[x]=pk->revkey[x+1];
+               /* A failure here means the sig did not verify, was
+                  not issued by a revocation key, or a revocation
+                  key loop was broken.  If a revocation key isn't
+                  findable, however, the key might be revoked and
+                  we don't know it.  */
 
-                   pk->numrevkeys--;
-                   j--;
-                   changed=1;
-                 }
+               /* TODO: In the future handle subkey and cert
+                  revocations?  PGP doesn't, but it's in 2440. */
              }
          }
-
-       if(changed)
-         pk->revkey=xrealloc(pk->revkey,
-                              pk->numrevkeys*sizeof(struct revocation_key));
       }
 
-    if ( signode )
-      {
-        /* some information from a direct key signature take precedence
-         * over the same information given in UID sigs.
-         */
-        PKT_signature *sig = signode->pkt->pkt.signature;
-        const byte *p;
-
-       key_usage=parse_key_usage(sig);
-
-       p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
-       if( p && buf32_to_u32 (p) )
-         {
-           key_expire = keytimestamp + buf32_to_u32 (p);
-           key_expire_seen = 1;
-         }
+  /* Second pass: Look at the self-signature of all user IDs.  */
+  signode = uidnode = NULL;
+  sigdate = 0; /* Helper variable to find the latest signature in one UID. */
+  for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_USER_ID)
+       {
+         if (uidnode && signode)
+           {
+             fixup_uidnode (uidnode, signode, keytimestamp);
+             pk->flags.valid = 1;
+           }
+         uidnode = k;
+         signode = NULL;
+         sigdate = 0;
+       }
+      else if (k->pkt->pkttype == PKT_SIGNATURE && uidnode)
+       {
+         PKT_signature *sig = k->pkt->pkt.signature;
+         if (sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1])
+           {
+             if (check_key_signature (keyblock, k, NULL))
+               ;               /* signature did not verify */
+             else if ((IS_UID_SIG (sig) || IS_UID_REV (sig))
+                      && sig->timestamp >= sigdate)
+               {
+                 /* Note: we allow to invalidate cert revocations
+                  * by a newer signature.  An attacker can't use this
+                  * because a key should be revoced with a key revocation.
+                  * The reason why we have to allow for that is that at
+                  * one time an email address may become invalid but later
+                  * the same email address may become valid again (hired,
+                  * fired, hired again).  */
+
+                 sigdate = sig->timestamp;
+                 signode = k;
+                 signode->pkt->pkt.signature->flags.chosen_selfsig = 0;
+                 if (sig->version > sigversion)
+                   sigversion = sig->version;
+               }
+           }
+       }
+    }
+  if (uidnode && signode)
+    {
+      fixup_uidnode (uidnode, signode, keytimestamp);
+      pk->flags.valid = 1;
+    }
 
-        /* mark that key as valid: one direct key signature should
-         * render a key as valid */
-        pk->is_valid = 1;
-      }
+  /* If the key isn't valid yet, and we have
+     --allow-non-selfsigned-uid set, then force it valid. */
+  if (!pk->flags.valid && opt.allow_non_selfsigned_uid)
+    {
+      if (opt.verbose)
+       log_info (_("Invalid key %s made valid by"
+                   " --allow-non-selfsigned-uid\n"), keystr_from_pk (pk));
+      pk->flags.valid = 1;
+    }
 
-    /* pass 1.5: look for key revocation signatures that were not made
-       by the key (i.e. did a revocation key issue a revocation for
-       us?).  Only bother to do this if there is a revocation key in
-       the first place and we're not revoked already. */
+  /* The key STILL isn't valid, so try and find an ultimately
+     trusted signature. */
+  if (!pk->flags.valid)
+    {
+      uidnode = NULL;
 
-    if(!*r_revoked && pk->revkey)
-      for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next )
+      for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+          k = k->next)
        {
-         if ( k->pkt->pkttype == PKT_SIGNATURE )
+         if (k->pkt->pkttype == PKT_USER_ID)
+           uidnode = k;
+         else if (k->pkt->pkttype == PKT_SIGNATURE && uidnode)
            {
              PKT_signature *sig = k->pkt->pkt.signature;
 
-             if(IS_KEY_REV(sig) &&
-                (sig->keyid[0]!=kid[0] || sig->keyid[1]!=kid[1]))
+             if (sig->keyid[0] != kid[0] || sig->keyid[1] != kid[1])
                {
-                 int rc=check_revocation_keys(pk,sig);
-                 if(rc==0)
+                 PKT_public_key *ultimate_pk;
+
+                 ultimate_pk = xmalloc_clear (sizeof (*ultimate_pk));
+
+                 /* We don't want to use the full get_pubkey to
+                    avoid infinite recursion in certain cases.
+                    There is no reason to check that an ultimately
+                    trusted key is still valid - if it has been
+                    revoked or the user should also renmove the
+                    ultimate trust flag.  */
+                 if (get_pubkey_fast (ultimate_pk, sig->keyid) == 0
+                     && check_key_signature2 (keyblock, k, ultimate_pk,
+                                              NULL, NULL, NULL, NULL) == 0
+                     && get_ownertrust (ultimate_pk) == TRUST_ULTIMATE)
                    {
-                     *r_revoked=2;
-                     sig_to_revoke_info(sig,rinfo);
-                     /* don't continue checking since we can't be any
-                        more revoked than this */
+                     free_public_key (ultimate_pk);
+                     pk->flags.valid = 1;
                      break;
                    }
-                 else if(rc==G10ERR_NO_PUBKEY)
-                   pk->maybe_revoked=1;
-
-                 /* A failure here means the sig did not verify, was
-                    not issued by a revocation key, or a revocation
-                    key loop was broken.  If a revocation key isn't
-                    findable, however, the key might be revoked and
-                    we don't know it. */
 
-                 /* TODO: In the future handle subkey and cert
-                     revocations?  PGP doesn't, but it's in 2440. */
+                 free_public_key (ultimate_pk);
                }
            }
        }
-
-    /* second pass: look at the self-signature of all user IDs */
-    signode = uidnode = NULL;
-    sigdate = 0; /* helper to find the latest signature in one user ID */
-    for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) {
-       if ( k->pkt->pkttype == PKT_USER_ID ) {
-            if ( uidnode && signode )
-             {
-                fixup_uidnode ( uidnode, signode, keytimestamp );
-               pk->is_valid=1;
-             }
-            uidnode = k;
-            signode = NULL;
-            sigdate = 0;
-       }
-        else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode ) {
-            PKT_signature *sig = k->pkt->pkt.signature;
-            if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) {
-                if ( check_key_signature( keyblock, k, NULL ) )
-                    ; /* signature did not verify */
-                else if ( (IS_UID_SIG (sig) || IS_UID_REV (sig))
-                          && sig->timestamp >= sigdate )
-                 {
-                    /* Note: we allow to invalidate cert revocations
-                     * by a newer signature.  An attacker can't use this
-                     * because a key should be revoced with a key revocation.
-                     * The reason why we have to allow for that is that at
-                     * one time an email address may become invalid but later
-                     * the same email address may become valid again (hired,
-                     * fired, hired again).
-                     */
-
-                   sigdate = sig->timestamp;
-                   signode = k;
-                   signode->pkt->pkt.signature->flags.chosen_selfsig=0;
-                   if( sig->version > sigversion )
-                     sigversion = sig->version;
-                 }
-            }
-        }
-    }
-    if ( uidnode && signode ) {
-        fixup_uidnode ( uidnode, signode, keytimestamp );
-        pk->is_valid = 1;
     }
 
-    /* If the key isn't valid yet, and we have
-       --allow-non-selfsigned-uid set, then force it valid. */
-    if(!pk->is_valid && opt.allow_non_selfsigned_uid)
-      {
-       if(opt.verbose)
-         log_info(_("Invalid key %s made valid by"
-                    " --allow-non-selfsigned-uid\n"),keystr_from_pk(pk));
-       pk->is_valid = 1;
-      }
-
-    /* The key STILL isn't valid, so try and find an ultimately
-       trusted signature. */
-    if(!pk->is_valid)
-      {
-       uidnode=NULL;
+  /* Record the highest selfsig version so we know if this is a v3
+     key through and through, or a v3 key with a v4 selfsig
+     somewhere.  This is useful in a few places to know if the key
+     must be treated as PGP2-style or OpenPGP-style.  Note that a
+     selfsig revocation with a higher version number will also raise
+     this value.  This is okay since such a revocation must be
+     issued by the user (i.e. it cannot be issued by someone else to
+     modify the key behavior.) */
 
-       for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k=k->next)
-         {
-           if ( k->pkt->pkttype == PKT_USER_ID )
-             uidnode = k;
-           else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode )
-             {
-               PKT_signature *sig = k->pkt->pkt.signature;
+  pk->selfsigversion = sigversion;
 
-               if(sig->keyid[0] != kid[0] || sig->keyid[1]!=kid[1])
-                 {
-                   PKT_public_key *ultimate_pk;
-
-                   ultimate_pk=xmalloc_clear(sizeof(*ultimate_pk));
-
-                    /* We don't want to use the full get_pubkey to
-                       avoid infinite recursion in certain cases.
-                       There is no reason to check that an ultimately
-                       trusted key is still valid - if it has been
-                       revoked or the user should also renmove the
-                       ultimate trust flag.  */
-                   if(get_pubkey_fast(ultimate_pk,sig->keyid)==0
-                      && check_key_signature2(keyblock,k,ultimate_pk,
-                                              NULL,NULL,NULL,NULL)==0
-                      && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE)
-                     {
-                       free_public_key(ultimate_pk);
-                       pk->is_valid=1;
-                       break;
-                     }
-
-                   free_public_key(ultimate_pk);
-                 }
-             }
-         }
-      }
+  /* Now that we had a look at all user IDs we can now get some information
+   * from those user IDs.
+   */
 
-    /* Record the highest selfsig version so we know if this is a v3
-       key through and through, or a v3 key with a v4 selfsig
-       somewhere.  This is useful in a few places to know if the key
-       must be treated as PGP2-style or OpenPGP-style.  Note that a
-       selfsig revocation with a higher version number will also raise
-       this value.  This is okay since such a revocation must be
-       issued by the user (i.e. it cannot be issued by someone else to
-       modify the key behavior.) */
-
-    pk->selfsigversion=sigversion;
-
-    /* Now that we had a look at all user IDs we can now get some information
-     * from those user IDs.
-     */
-
-    if ( !key_usage ) {
-        /* find the latest user ID with key flags set */
-        uiddate = 0; /* helper to find the latest user ID */
-        for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
-            k = k->next ) {
-            if ( k->pkt->pkttype == PKT_USER_ID ) {
-                PKT_user_id *uid = k->pkt->pkt.user_id;
-                if ( uid->help_key_usage && uid->created > uiddate ) {
-                    key_usage = uid->help_key_usage;
-                    uiddate = uid->created;
-                }
-            }
-       }
-    }
-    if ( !key_usage ) { /* no key flags at all: get it from the algo */
-        key_usage = openpgp_pk_algo_usage ( pk->pubkey_algo );
-    }
-    else { /* check that the usage matches the usage as given by the algo */
-        int x = openpgp_pk_algo_usage ( pk->pubkey_algo );
-        if ( x ) /* mask it down to the actual allowed usage */
-            key_usage &= x;
-    }
-
-    /* Whatever happens, it's a primary key, so it can certify. */
-    pk->pubkey_usage = key_usage|PUBKEY_USAGE_CERT;
-
-    if ( !key_expire_seen ) {
-        /* find the latest valid user ID with a key expiration set
-         * Note, that this may be a different one from the above because
-         * some user IDs may have no expiration date set */
-        uiddate = 0;
-        for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
-            k = k->next ) {
-            if ( k->pkt->pkttype == PKT_USER_ID ) {
-                PKT_user_id *uid = k->pkt->pkt.user_id;
-                if ( uid->help_key_expire && uid->created > uiddate ) {
-                    key_expire = uid->help_key_expire;
-                    uiddate = uid->created;
-                }
-            }
-       }
+  if (!key_usage)
+    {
+      /* Find the latest user ID with key flags set. */
+      uiddate = 0; /* Helper to find the latest user ID.  */
+      for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+          k = k->next)
+       {
+         if (k->pkt->pkttype == PKT_USER_ID)
+           {
+             PKT_user_id *uid = k->pkt->pkt.user_id;
+             if (uid->help_key_usage && uid->created > uiddate)
+               {
+                 key_usage = uid->help_key_usage;
+                 uiddate = uid->created;
+               }
+           }
+       }
+    }
+  if (!key_usage)
+    {
+      /* No key flags at all: get it from the algo.  */
+      key_usage = openpgp_pk_algo_usage (pk->pubkey_algo);
+    }
+  else
+    {
+      /* Check that the usage matches the usage as given by the algo.  */
+      int x = openpgp_pk_algo_usage (pk->pubkey_algo);
+      if (x) /* Mask it down to the actual allowed usage.  */
+       key_usage &= x;
     }
 
-    /* Currently only v3 keys have a maximum expiration date, but I'll
-       bet v5 keys get this feature again. */
-    if(key_expire==0 || (pk->max_expiredate && key_expire>pk->max_expiredate))
-      key_expire=pk->max_expiredate;
-
-    pk->has_expired = key_expire >= curtime? 0 : key_expire;
-    pk->expiredate = key_expire;
-
-    /* Fixme: we should see how to get rid of the expiretime fields  but
-     * this needs changes at other places too. */
+  /* Whatever happens, it's a primary key, so it can certify. */
+  pk->pubkey_usage = key_usage | PUBKEY_USAGE_CERT;
 
-    /* and now find the real primary user ID and delete all others */
-    uiddate = uiddate2 = 0;
-    uidnode = uidnode2 = NULL;
-    for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) {
-        if ( k->pkt->pkttype == PKT_USER_ID &&
-            !k->pkt->pkt.user_id->attrib_data) {
-            PKT_user_id *uid = k->pkt->pkt.user_id;
-            if (uid->is_primary)
-             {
-               if(uid->created > uiddate)
-                 {
-                   uiddate = uid->created;
-                   uidnode = k;
-                 }
-               else if(uid->created==uiddate && uidnode)
-                 {
-                   /* The dates are equal, so we need to do a
-                      different (and arbitrary) comparison.  This
-                      should rarely, if ever, happen.  It's good to
-                      try and guarantee that two different GnuPG
-                      users with two different keyrings at least pick
-                      the same primary. */
-                   if(cmp_user_ids(uid,uidnode->pkt->pkt.user_id)>0)
-                     uidnode=k;
-                 }
-             }
-           else
-             {
-               if(uid->created > uiddate2)
-                 {
-                   uiddate2 = uid->created;
+  if (!key_expire_seen)
+    {
+      /* Find the latest valid user ID with a key expiration set
+       * Note, that this may be a different one from the above because
+       * some user IDs may have no expiration date set.  */
+      uiddate = 0;
+      for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+          k = k->next)
+       {
+         if (k->pkt->pkttype == PKT_USER_ID)
+           {
+             PKT_user_id *uid = k->pkt->pkt.user_id;
+             if (uid->help_key_expire && uid->created > uiddate)
+               {
+                 key_expire = uid->help_key_expire;
+                 uiddate = uid->created;
+               }
+           }
+       }
+    }
+
+  /* Currently only v3 keys have a maximum expiration date, but I'll
+     bet v5 keys get this feature again. */
+  if (key_expire == 0
+      || (pk->max_expiredate && key_expire > pk->max_expiredate))
+    key_expire = pk->max_expiredate;
+
+  pk->has_expired = key_expire >= curtime ? 0 : key_expire;
+  pk->expiredate = key_expire;
+
+  /* Fixme: we should see how to get rid of the expiretime fields  but
+   * this needs changes at other places too. */
+
+  /* And now find the real primary user ID and delete all others.  */
+  uiddate = uiddate2 = 0;
+  uidnode = uidnode2 = NULL;
+  for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_USER_ID && !k->pkt->pkt.user_id->attrib_data)
+       {
+         PKT_user_id *uid = k->pkt->pkt.user_id;
+         if (uid->is_primary)
+           {
+             if (uid->created > uiddate)
+               {
+                 uiddate = uid->created;
+                 uidnode = k;
+               }
+             else if (uid->created == uiddate && uidnode)
+               {
+                 /* The dates are equal, so we need to do a
+                    different (and arbitrary) comparison.  This
+                    should rarely, if ever, happen.  It's good to
+                    try and guarantee that two different GnuPG
+                    users with two different keyrings at least pick
+                    the same primary. */
+                 if (cmp_user_ids (uid, uidnode->pkt->pkt.user_id) > 0)
+                   uidnode = k;
+               }
+           }
+         else
+           {
+             if (uid->created > uiddate2)
+               {
+                 uiddate2 = uid->created;
+                 uidnode2 = k;
+               }
+             else if (uid->created == uiddate2 && uidnode2)
+               {
+                 if (cmp_user_ids (uid, uidnode2->pkt->pkt.user_id) > 0)
                    uidnode2 = k;
-                 }
-               else if(uid->created==uiddate2 && uidnode2)
-                 {
-                   if(cmp_user_ids(uid,uidnode2->pkt->pkt.user_id)>0)
-                     uidnode2=k;
-                 }
-             }
-        }
+               }
+           }
+       }
     }
-    if ( uidnode ) {
-        for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
-            k = k->next ) {
-            if ( k->pkt->pkttype == PKT_USER_ID &&
-                !k->pkt->pkt.user_id->attrib_data) {
-                PKT_user_id *uid = k->pkt->pkt.user_id;
-                if ( k != uidnode )
-                    uid->is_primary = 0;
-            }
-        }
+  if (uidnode)
+    {
+      for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+          k = k->next)
+       {
+         if (k->pkt->pkttype == PKT_USER_ID &&
+             !k->pkt->pkt.user_id->attrib_data)
+           {
+             PKT_user_id *uid = k->pkt->pkt.user_id;
+             if (k != uidnode)
+               uid->is_primary = 0;
+           }
+       }
     }
-    else if( uidnode2 ) {
-        /* none is flagged primary - use the latest user ID we have,
-          and disambiguate with the arbitrary packet comparison. */
-        uidnode2->pkt->pkt.user_id->is_primary = 1;
+  else if (uidnode2)
+    {
+      /* None is flagged primary - use the latest user ID we have,
+         and disambiguate with the arbitrary packet comparison. */
+      uidnode2->pkt->pkt.user_id->is_primary = 1;
     }
-    else
-      {
-       /* None of our uids were self-signed, so pick the one that
-          sorts first to be the primary.  This is the best we can do
-          here since there are no self sigs to date the uids. */
+  else
+    {
+      /* None of our uids were self-signed, so pick the one that
+         sorts first to be the primary.  This is the best we can do
+         here since there are no self sigs to date the uids. */
 
-       uidnode = NULL;
+      uidnode = NULL;
 
-       for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
-           k = k->next )
-         {
-           if(k->pkt->pkttype==PKT_USER_ID
-              && !k->pkt->pkt.user_id->attrib_data)
-             {
-               if(!uidnode)
-                 {
-                   uidnode=k;
-                   uidnode->pkt->pkt.user_id->is_primary=1;
-                   continue;
-                 }
-               else
-                 {
-                   if(cmp_user_ids(k->pkt->pkt.user_id,
-                                   uidnode->pkt->pkt.user_id)>0)
-                     {
-                       uidnode->pkt->pkt.user_id->is_primary=0;
-                       uidnode=k;
-                       uidnode->pkt->pkt.user_id->is_primary=1;
-                     }
-                   else
-                     k->pkt->pkt.user_id->is_primary=0; /* just to be
-                                                           safe */
-                 }
-             }
-         }
-      }
+      for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+          k = k->next)
+       {
+         if (k->pkt->pkttype == PKT_USER_ID
+             && !k->pkt->pkt.user_id->attrib_data)
+           {
+             if (!uidnode)
+               {
+                 uidnode = k;
+                 uidnode->pkt->pkt.user_id->is_primary = 1;
+                 continue;
+               }
+             else
+               {
+                 if (cmp_user_ids (k->pkt->pkt.user_id,
+                                   uidnode->pkt->pkt.user_id) > 0)
+                   {
+                     uidnode->pkt->pkt.user_id->is_primary = 0;
+                     uidnode = k;
+                     uidnode->pkt->pkt.user_id->is_primary = 1;
+                   }
+                 else
+                   k->pkt->pkt.user_id->is_primary = 0;        /* just to be
+                                                                  safe */
+               }
+           }
+       }
+    }
 }
 
 /* Convert a buffer to a signature.  Useful for 0x19 embedded sigs.
    Caller must free the signature when they are done. */
 static PKT_signature *
-buf_to_sig(const byte *buf,size_t len)
+buf_to_sig (const byte * buf, size_t len)
 {
-  PKT_signature *sig=xmalloc_clear(sizeof(PKT_signature));
-  IOBUF iobuf=iobuf_temp_with_content(buf,len);
-  int save_mode=set_packet_list_mode(0);
+  PKT_signature *sig = xmalloc_clear (sizeof (PKT_signature));
+  IOBUF iobuf = iobuf_temp_with_content (buf, len);
+  int save_mode = set_packet_list_mode (0);
 
-  if(parse_signature(iobuf,PKT_SIGNATURE,len,sig)!=0)
+  if (parse_signature (iobuf, PKT_SIGNATURE, len, sig) != 0)
     {
-      xfree(sig);
-      sig=NULL;
+      xfree (sig);
+      sig = NULL;
     }
 
-  set_packet_list_mode(save_mode);
-  iobuf_close(iobuf);
+  set_packet_list_mode (save_mode);
+  iobuf_close (iobuf);
 
   return sig;
 }
 
 static void
-merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
+merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
 {
-    PKT_public_key *mainpk = NULL, *subpk = NULL;
-    PKT_signature *sig;
-    KBNODE k;
-    u32 mainkid[2];
-    u32 sigdate = 0;
-    KBNODE signode;
-    u32 curtime = make_timestamp ();
-    unsigned int key_usage = 0;
-    u32 keytimestamp = 0;
-    u32 key_expire = 0;
-    const byte *p;
-
-    if ( subnode->pkt->pkttype != PKT_PUBLIC_SUBKEY )
-        BUG ();
-    mainpk = keyblock->pkt->pkt.public_key;
-    if ( mainpk->version < 4 )
-        return; /* (actually this should never happen) */
-    keyid_from_pk( mainpk, mainkid );
-    subpk = subnode->pkt->pkt.public_key;
-    keytimestamp = subpk->timestamp;
-
-    subpk->is_valid = 0;
-    subpk->main_keyid[0] = mainpk->main_keyid[0];
-    subpk->main_keyid[1] = mainpk->main_keyid[1];
-
-    /* find the latest key binding self-signature. */
-    signode = NULL;
-    sigdate = 0; /* helper to find the latest signature */
-    for(k=subnode->next; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
-                                                        k = k->next ) {
-        if ( k->pkt->pkttype == PKT_SIGNATURE ) {
-            sig = k->pkt->pkt.signature;
-            if ( sig->keyid[0] == mainkid[0] && sig->keyid[1]==mainkid[1] ) {
-               if ( check_key_signature( keyblock, k, NULL ) )
-                    ; /* signature did not verify */
-                else if ( IS_SUBKEY_REV (sig) ) {
+  PKT_public_key *mainpk = NULL, *subpk = NULL;
+  PKT_signature *sig;
+  KBNODE k;
+  u32 mainkid[2];
+  u32 sigdate = 0;
+  KBNODE signode;
+  u32 curtime = make_timestamp ();
+  unsigned int key_usage = 0;
+  u32 keytimestamp = 0;
+  u32 key_expire = 0;
+  const byte *p;
+
+  if (subnode->pkt->pkttype != PKT_PUBLIC_SUBKEY)
+    BUG ();
+  mainpk = keyblock->pkt->pkt.public_key;
+  if (mainpk->version < 4)
+    return;/* (actually this should never happen) */
+  keyid_from_pk (mainpk, mainkid);
+  subpk = subnode->pkt->pkt.public_key;
+  keytimestamp = subpk->timestamp;
+
+  subpk->flags.valid = 0;
+  subpk->main_keyid[0] = mainpk->main_keyid[0];
+  subpk->main_keyid[1] = mainpk->main_keyid[1];
+
+  /* Find the latest key binding self-signature.  */
+  signode = NULL;
+  sigdate = 0; /* Helper to find the latest signature.  */
+  for (k = subnode->next; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+       k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_SIGNATURE)
+       {
+         sig = k->pkt->pkt.signature;
+         if (sig->keyid[0] == mainkid[0] && sig->keyid[1] == mainkid[1])
+           {
+             if (check_key_signature (keyblock, k, NULL))
+               ; /* Signature did not verify.  */
+             else if (IS_SUBKEY_REV (sig))
+               {
                  /* Note that this means that the date on a
-                     revocation sig does not matter - even if the
-                     binding sig is dated after the revocation sig,
-                     the subkey is still marked as revoked.  This
-                     seems ok, as it is just as easy to make new
-                     subkeys rather than re-sign old ones as the
-                     problem is in the distribution.  Plus, PGP (7)
-                     does this the same way.  */
-                    subpk->is_revoked = 1;
-                   sig_to_revoke_info(sig,&subpk->revoked);
-                    /* although we could stop now, we continue to
-                     * figure out other information like the old expiration
-                     * time */
-                }
-                else if ( IS_SUBKEY_SIG (sig) && sig->timestamp >= sigdate )
-                 {
-                   if(sig->flags.expired)
-                     ; /* signature has expired - ignore it */
-                    else
-                     {
-                        sigdate = sig->timestamp;
-                        signode = k;
-                       signode->pkt->pkt.signature->flags.chosen_selfsig=0;
-                     }
-                 }
-            }
-        }
+                    revocation sig does not matter - even if the
+                    binding sig is dated after the revocation sig,
+                    the subkey is still marked as revoked.  This
+                    seems ok, as it is just as easy to make new
+                    subkeys rather than re-sign old ones as the
+                    problem is in the distribution.  Plus, PGP (7)
+                    does this the same way.  */
+                 subpk->flags.revoked = 1;
+                 sig_to_revoke_info (sig, &subpk->revoked);
+                 /* Although we could stop now, we continue to
+                  * figure out other information like the old expiration
+                  * time.  */
+               }
+             else if (IS_SUBKEY_SIG (sig) && sig->timestamp >= sigdate)
+               {
+                 if (sig->flags.expired)
+                   ; /* Signature has expired - ignore it.  */
+                 else
+                   {
+                     sigdate = sig->timestamp;
+                     signode = k;
+                     signode->pkt->pkt.signature->flags.chosen_selfsig = 0;
+                   }
+               }
+           }
+       }
     }
 
-    /* no valid key binding */
-    if ( !signode )
-      return;
+  /* No valid key binding.  */
+  if (!signode)
+    return;
 
-    sig = signode->pkt->pkt.signature;
-    sig->flags.chosen_selfsig=1; /* so we know which selfsig we chose later */
+  sig = signode->pkt->pkt.signature;
+  sig->flags.chosen_selfsig = 1; /* So we know which selfsig we chose later.  */
 
-    key_usage=parse_key_usage(sig);
-    if ( !key_usage )
-      {
-       /* no key flags at all: get it from the algo */
-        key_usage = openpgp_pk_algo_usage ( subpk->pubkey_algo );
-      }
-    else
-      {
-       /* check that the usage matches the usage as given by the algo */
-        int x = openpgp_pk_algo_usage ( subpk->pubkey_algo );
-        if ( x ) /* mask it down to the actual allowed usage */
-         key_usage &= x;
-      }
+  key_usage = parse_key_usage (sig);
+  if (!key_usage)
+    {
+      /* No key flags at all: get it from the algo.  */
+      key_usage = openpgp_pk_algo_usage (subpk->pubkey_algo);
+    }
+  else
+    {
+      /* Check that the usage matches the usage as given by the algo.  */
+      int x = openpgp_pk_algo_usage (subpk->pubkey_algo);
+      if (x) /* Mask it down to the actual allowed usage.  */
+       key_usage &= x;
+    }
 
-    subpk->pubkey_usage = key_usage;
+  subpk->pubkey_usage = key_usage;
 
-    p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
-    if ( p && buf32_to_u32 (p) )
-        key_expire = keytimestamp + buf32_to_u32 (p);
-    else
-        key_expire = 0;
-    subpk->has_expired = key_expire >= curtime? 0 : key_expire;
-    subpk->expiredate = key_expire;
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
+  if (p && buffer_to_u32 (p))
+    key_expire = keytimestamp + buffer_to_u32 (p);
+  else
+    key_expire = 0;
+  subpk->has_expired = key_expire >= curtime ? 0 : key_expire;
+  subpk->expiredate = key_expire;
 
-    /* algo doesn't exist */
-    if(openpgp_pk_test_algo(subpk->pubkey_algo))
-      return;
+  /* Algo doesn't exist.  */
+  if (openpgp_pk_test_algo (subpk->pubkey_algo))
+    return;
 
-    subpk->is_valid = 1;
+  subpk->flags.valid = 1;
 
-    /* Find the most recent 0x19 embedded signature on our self-sig. */
-    if(subpk->backsig==0)
-      {
-       int seq=0;
-       size_t n;
-       PKT_signature *backsig=NULL;
+  /* Find the most recent 0x19 embedded signature on our self-sig. */
+  if (!subpk->flags.backsig)
+    {
+      int seq = 0;
+      size_t n;
+      PKT_signature *backsig = NULL;
 
-       sigdate=0;
+      sigdate = 0;
 
-       /* We do this while() since there may be other embedded
-          signatures in the future.  We only want 0x19 here. */
+      /* We do this while() since there may be other embedded
+         signatures in the future.  We only want 0x19 here. */
 
-       while((p=enum_sig_subpkt(sig->hashed,
-                                SIGSUBPKT_SIGNATURE,&n,&seq,NULL)))
-         if(n>3 && ((p[0]==3 && p[2]==0x19) || (p[0]==4 && p[1]==0x19)))
-           {
-             PKT_signature *tempsig=buf_to_sig(p,n);
-             if(tempsig)
-               {
-                 if(tempsig->timestamp>sigdate)
-                   {
-                     if(backsig)
-                       free_seckey_enc(backsig);
+      while ((p = enum_sig_subpkt (sig->hashed,
+                                  SIGSUBPKT_SIGNATURE, &n, &seq, NULL)))
+       if (n > 3
+           && ((p[0] == 3 && p[2] == 0x19) || (p[0] == 4 && p[1] == 0x19)))
+         {
+           PKT_signature *tempsig = buf_to_sig (p, n);
+           if (tempsig)
+             {
+               if (tempsig->timestamp > sigdate)
+                 {
+                   if (backsig)
+                     free_seckey_enc (backsig);
 
-                     backsig=tempsig;
-                     sigdate=backsig->timestamp;
-                   }
-                 else
-                   free_seckey_enc(tempsig);
-               }
-           }
+                   backsig = tempsig;
+                   sigdate = backsig->timestamp;
+                 }
+               else
+                 free_seckey_enc (tempsig);
+             }
+         }
 
-       seq=0;
+      seq = 0;
 
-       /* It is safe to have this in the unhashed area since the 0x19
-          is located on the selfsig for convenience, not security. */
+      /* It is safe to have this in the unhashed area since the 0x19
+         is located on the selfsig for convenience, not security. */
 
-       while((p=enum_sig_subpkt(sig->unhashed,SIGSUBPKT_SIGNATURE,
-                                &n,&seq,NULL)))
-         if(n>3 && ((p[0]==3 && p[2]==0x19) || (p[0]==4 && p[1]==0x19)))
-           {
-             PKT_signature *tempsig=buf_to_sig(p,n);
-             if(tempsig)
-               {
-                 if(tempsig->timestamp>sigdate)
-                   {
-                     if(backsig)
-                       free_seckey_enc(backsig);
+      while ((p = enum_sig_subpkt (sig->unhashed, SIGSUBPKT_SIGNATURE,
+                                  &n, &seq, NULL)))
+       if (n > 3
+           && ((p[0] == 3 && p[2] == 0x19) || (p[0] == 4 && p[1] == 0x19)))
+         {
+           PKT_signature *tempsig = buf_to_sig (p, n);
+           if (tempsig)
+             {
+               if (tempsig->timestamp > sigdate)
+                 {
+                   if (backsig)
+                     free_seckey_enc (backsig);
 
-                     backsig=tempsig;
-                     sigdate=backsig->timestamp;
-                   }
-                 else
-                   free_seckey_enc(tempsig);
-               }
-           }
+                   backsig = tempsig;
+                   sigdate = backsig->timestamp;
+                 }
+               else
+                 free_seckey_enc (tempsig);
+             }
+         }
 
-       if(backsig)
-         {
-           /* At ths point, backsig contains the most recent 0x19 sig.
-              Let's see if it is good. */
+      if (backsig)
+       {
+         /* At ths point, backsig contains the most recent 0x19 sig.
+            Let's see if it is good. */
 
-           /* 2==valid, 1==invalid, 0==didn't check */
-           if(check_backsig(mainpk,subpk,backsig)==0)
-             subpk->backsig=2;
-           else
-             subpk->backsig=1;
+         /* 2==valid, 1==invalid, 0==didn't check */
+         if (check_backsig (mainpk, subpk, backsig) == 0)
+           subpk->flags.backsig = 2;
+         else
+           subpk->flags.backsig = 1;
 
-           free_seckey_enc(backsig);
-         }
-      }
+         free_seckey_enc (backsig);
+       }
+    }
 }
 
 
@@ -2371,221 +2204,106 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
  *   FIXME the docs
  */
 static void
-merge_selfsigs( KBNODE keyblock )
+merge_selfsigs (KBNODE keyblock)
 {
-    KBNODE k;
-    int revoked;
-    struct revoke_info rinfo;
-    PKT_public_key *main_pk;
-    prefitem_t *prefs;
-    int mdc_feature;
-
-    if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) {
-        if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) {
-            log_error ("expected public key but found secret key "
-                       "- must stop\n");
-            /* we better exit here becuase a public key is expected at
-               other places too.  FIXME: Figure this out earlier and
-               don't get to here at all */
-            g10_exit (1);
-        }
-        BUG ();
+  KBNODE k;
+  int revoked;
+  struct revoke_info rinfo;
+  PKT_public_key *main_pk;
+  prefitem_t *prefs;
+  unsigned int mdc_feature;
+
+  if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
+    {
+      if (keyblock->pkt->pkttype == PKT_SECRET_KEY)
+       {
+         log_error ("expected public key but found secret key "
+                    "- must stop\n");
+         /* We better exit here because a public key is expected at
+            other places too.  FIXME: Figure this out earlier and
+            don't get to here at all */
+         g10_exit (1);
+       }
+      BUG ();
     }
 
-    merge_selfsigs_main ( keyblock, &revoked, &rinfo );
+  merge_selfsigs_main (keyblock, &revoked, &rinfo);
 
-    /* now merge in the data from each of the subkeys */
-    for(k=keyblock; k; k = k->next ) {
-       if (  k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-            merge_selfsigs_subkey ( keyblock, k );
-        }
-    }
-
-    main_pk = keyblock->pkt->pkt.public_key;
-    if ( revoked || main_pk->has_expired || !main_pk->is_valid ) {
-        /* if the primary key is revoked, expired, or invalid we
-         * better set the appropriate flags on that key and all
-         * subkeys */
-        for(k=keyblock; k; k = k->next ) {
-            if ( k->pkt->pkttype == PKT_PUBLIC_KEY
-                || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-                PKT_public_key *pk = k->pkt->pkt.public_key;
-               if(!main_pk->is_valid)
-                 pk->is_valid = 0;
-               if(revoked && !pk->is_revoked)
-                 {
-                   pk->is_revoked = revoked;
-                   memcpy(&pk->revoked,&rinfo,sizeof(rinfo));
-                 }
-                if(main_pk->has_expired)
-                 pk->has_expired = main_pk->has_expired;
-            }
+  /* Now merge in the data from each of the subkeys.  */
+  for (k = keyblock; k; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       {
+         merge_selfsigs_subkey (keyblock, k);
        }
-       return;
     }
 
-    /* set the preference list of all keys to those of the primary real
-     * user ID.  Note: we use these preferences when we don't know by
-     * which user ID the key has been selected.
-     * fixme: we should keep atoms of commonly used preferences or
-     * use reference counting to optimize the preference lists storage.
-     * FIXME: it might be better to use the intersection of
-     * all preferences.
-     * Do a similar thing for the MDC feature flag.
-     */
-    prefs = NULL;
-    mdc_feature = 0;
-    for (k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) {
-        if (k->pkt->pkttype == PKT_USER_ID
-           && !k->pkt->pkt.user_id->attrib_data
-            && k->pkt->pkt.user_id->is_primary) {
-            prefs = k->pkt->pkt.user_id->prefs;
-            mdc_feature = k->pkt->pkt.user_id->flags.mdc;
-            break;
-        }
-    }
-    for(k=keyblock; k; k = k->next ) {
-        if ( k->pkt->pkttype == PKT_PUBLIC_KEY
-             || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-            PKT_public_key *pk = k->pkt->pkt.public_key;
-            if (pk->prefs)
-                xfree (pk->prefs);
-            pk->prefs = copy_prefs (prefs);
-            pk->mdc_feature = mdc_feature;
-        }
+  main_pk = keyblock->pkt->pkt.public_key;
+  if (revoked || main_pk->has_expired || !main_pk->flags.valid)
+    {
+      /* If the primary key is revoked, expired, or invalid we
+       * better set the appropriate flags on that key and all
+       * subkeys.  */
+      for (k = keyblock; k; k = k->next)
+       {
+         if (k->pkt->pkttype == PKT_PUBLIC_KEY
+             || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+           {
+             PKT_public_key *pk = k->pkt->pkt.public_key;
+             if (!main_pk->flags.valid)
+               pk->flags.valid = 0;
+             if (revoked && !pk->flags.revoked)
+               {
+                 pk->flags.revoked = revoked;
+                 memcpy (&pk->revoked, &rinfo, sizeof (rinfo));
+               }
+             if (main_pk->has_expired)
+               pk->has_expired = main_pk->has_expired;
+           }
+       }
+      return;
     }
-}
-
 
-/*
- * Merge the secret keys from secblock into the pubblock thereby
- * replacing the public (sub)keys with their secret counterparts Hmmm:
- * It might be better to get away from the concept of entire secret
- * keys at all and have a way to store just the real secret parts
- * from the key.
- */
-static void
-merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
-{
-    KBNODE pub;
-
-    assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY );
-    assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
-
-    for (pub=pubblock; pub; pub = pub->next ) {
-        if ( pub->pkt->pkttype == PKT_PUBLIC_KEY ) {
-             PKT_public_key *pk = pub->pkt->pkt.public_key;
-             PKT_secret_key *sk = secblock->pkt->pkt.secret_key;
-             assert ( pub == pubblock ); /* only in the first node */
-             /* there is nothing to compare in this case, so just replace
-              * some information */
-             copy_public_parts_to_secret_key ( pk, sk );
-             free_public_key ( pk );
-             pub->pkt->pkttype = PKT_SECRET_KEY;
-             pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
-        }
-        else if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-            KBNODE sec;
-            PKT_public_key *pk = pub->pkt->pkt.public_key;
-
-            /* this is more complicated: it may happen that the sequence
-             * of the subkeys dosn't match, so we have to find the
-             * appropriate secret key */
-            for (sec=secblock->next; sec; sec = sec->next ) {
-                if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-                    PKT_secret_key *sk = sec->pkt->pkt.secret_key;
-                    if ( !cmp_public_secret_key ( pk, sk ) ) {
-                        copy_public_parts_to_secret_key ( pk, sk );
-                        free_public_key ( pk );
-                        pub->pkt->pkttype = PKT_SECRET_SUBKEY;
-                        pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
-                        break;
-                    }
-                }
-            }
-            if ( !sec )
-                BUG(); /* already checked in premerge */
-        }
+  /* Set the preference list of all keys to those of the primary real
+   * user ID.  Note: we use these preferences when we don't know by
+   * which user ID the key has been selected.
+   * fixme: we should keep atoms of commonly used preferences or
+   * use reference counting to optimize the preference lists storage.
+   * FIXME: it might be better to use the intersection of
+   * all preferences.
+   * Do a similar thing for the MDC feature flag.  */
+  prefs = NULL;
+  mdc_feature = 0;
+  for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_USER_ID
+         && !k->pkt->pkt.user_id->attrib_data
+         && k->pkt->pkt.user_id->is_primary)
+       {
+         prefs = k->pkt->pkt.user_id->prefs;
+         mdc_feature = k->pkt->pkt.user_id->flags.mdc;
+         break;
+       }
     }
-}
-
-/* This function checks that for every public subkey a corresponding
- * secret subkey is available and deletes the public subkey otherwise.
- * We need this function because we can't delete it later when we
- * actually merge the secret parts into the pubring.
- * The function also plays some games with the node flags.
- */
-static void
-premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
-{
-    KBNODE last, pub;
-
-    assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY );
-    assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
-
-    for (pub=pubblock,last=NULL; pub; last = pub, pub = pub->next ) {
-        pub->flag &= ~3; /* reset bits 0 and 1 */
-        if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-            KBNODE sec;
-            PKT_public_key *pk = pub->pkt->pkt.public_key;
-
-            for (sec=secblock->next; sec; sec = sec->next ) {
-                if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-                    PKT_secret_key *sk = sec->pkt->pkt.secret_key;
-                    if ( !cmp_public_secret_key ( pk, sk ) ) {
-                        if ( sk->protect.s2k.mode == 1001 ) {
-                            /* The secret parts are not available so
-                               we can't use that key for signing etc.
-                               Fix the pubkey usage */
-                            pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG
-                                                  |PUBKEY_USAGE_AUTH);
-                        }
-                        /* transfer flag bits 0 and 1 to the pubblock */
-                        pub->flag |= (sec->flag &3);
-                        break;
-                    }
-                }
-            }
-            if ( !sec ) {
-                KBNODE next, ll;
-
-                if (opt.verbose)
-                  log_info (_("no secret subkey"
-                             " for public subkey %s - ignoring\n"),
-                           keystr_from_pk (pk));
-                /* we have to remove the subkey in this case */
-                assert ( last );
-                /* find the next subkey */
-                for (next=pub->next,ll=pub;
-                     next && next->pkt->pkttype != PKT_PUBLIC_SUBKEY;
-                     ll = next, next = next->next )
-                    ;
-                /* make new link */
-                last->next = next;
-                /* release this public subkey with all sigs */
-                ll->next = NULL;
-                release_kbnode( pub );
-                /* let the loop continue */
-                pub = last;
-            }
-        }
+  for (k = keyblock; k; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_PUBLIC_KEY
+         || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       {
+         PKT_public_key *pk = k->pkt->pkt.public_key;
+         if (pk->prefs)
+           xfree (pk->prefs);
+         pk->prefs = copy_prefs (prefs);
+         pk->flags.mdc = mdc_feature;
+       }
     }
-    /* We need to copy the found bits (0 and 1) from the secret key to
-       the public key.  This has already been done for the subkeys but
-       got lost on the primary key - fix it here *. */
-    pubblock->flag |= (secblock->flag & 3);
 }
 
 
-
 \f
-/* See see whether the key fits
- * our requirements and in case we do not
- * request the primary key, we should select
- * a suitable subkey.
- * FIXME: Check against PGP 7 whether we still need a kludge
- *        to favor type 16 keys over type 20 keys when type 20
- *        has not been explitely requested.
+/* See whether the key fits our requirements and in case we do not
+ * request the primary key, select a suitable subkey.
+ *
  * Returns: True when a suitable key has been found.
  *
  * We have to distinguish four cases:  FIXME!
@@ -2605,449 +2323,464 @@ premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
  *
  * CTX ist the keyblock we are investigating, if FOUNDK is not NULL this
  * is the key we actually found by looking at the keyid or a fingerprint and
- * may eitehr point to the primary or one of the subkeys.
- */
-
+ * may either point to the primary or one of the subkeys.  */
 static int
 finish_lookup (GETKEY_CTX ctx)
 {
-    KBNODE keyblock = ctx->keyblock;
-    KBNODE k;
-    KBNODE foundk = NULL;
-    PKT_user_id *foundu = NULL;
+  KBNODE keyblock = ctx->keyblock;
+  KBNODE k;
+  KBNODE foundk = NULL;
+  PKT_user_id *foundu = NULL;
 #define USAGE_MASK  (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
-    unsigned int req_usage = ( ctx->req_usage & USAGE_MASK );
-    /* Request the primary if we're certifying another key, and also
-       if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7
-       do not understand signatures made by a signing subkey.  PGP 8
-       does. */
-    int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) ||
-      ((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG));
-    u32 latest_date;
-    KBNODE latest_key;
-    u32 curtime = make_timestamp ();
-
-    assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
-
-    ctx->found_key = NULL;
-
-    if (ctx->exact) {
-        for (k=keyblock; k; k = k->next) {
-            if ( (k->flag & 1) ) {
-                assert ( k->pkt->pkttype == PKT_PUBLIC_KEY
-                         || k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
-                foundk = k;
-                break;
-            }
-        }
+  unsigned int req_usage = (ctx->req_usage & USAGE_MASK);
+  /* Request the primary if we're certifying another key, and also
+     if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7
+     do not understand signatures made by a signing subkey.  PGP 8
+     does. */
+  int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) ||
+    ((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG));
+  u32 latest_date;
+  KBNODE latest_key;
+  u32 curtime = make_timestamp ();
+
+  assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+
+  ctx->found_key = NULL;
+
+  if (ctx->exact)
+    {
+      for (k = keyblock; k; k = k->next)
+       {
+         if ((k->flag & 1))
+           {
+             assert (k->pkt->pkttype == PKT_PUBLIC_KEY
+                     || k->pkt->pkttype == PKT_PUBLIC_SUBKEY);
+             foundk = k;
+             break;
+           }
+       }
     }
 
-    for (k=keyblock; k; k = k->next) {
-        if ( (k->flag & 2) ) {
-            assert (k->pkt->pkttype == PKT_USER_ID);
-            foundu = k->pkt->pkt.user_id;
-            break;
-        }
+  for (k = keyblock; k; k = k->next)
+    {
+      if ((k->flag & 2))
+       {
+         assert (k->pkt->pkttype == PKT_USER_ID);
+         foundu = k->pkt->pkt.user_id;
+         break;
+       }
     }
 
-    if ( DBG_CACHE )
-        log_debug( "finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
-                   (ulong)keyid_from_pk( keyblock->pkt->pkt.public_key, NULL),
-                   foundk? "one":"all", req_usage);
-
-    if (!req_usage) {
-        latest_key = foundk? foundk:keyblock;
-        goto found;
-    }
-
-    latest_date = 0;
-    latest_key  = NULL;
-    /* do not look at subkeys if a certification key is requested */
-    if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_prim) {
-        KBNODE nextk;
-        /* either start a loop or check just this one subkey */
-        for (k=foundk?foundk:keyblock; k; k = nextk ) {
-            PKT_public_key *pk;
-            nextk = k->next;
-            if ( k->pkt->pkttype != PKT_PUBLIC_SUBKEY )
-                continue;
-            if ( foundk )
-                nextk = NULL;  /* what a hack */
-            pk = k->pkt->pkt.public_key;
-            if (DBG_CACHE)
-                log_debug( "\tchecking subkey %08lX\n",
-                           (ulong)keyid_from_pk( pk, NULL));
-            if ( !pk->is_valid ) {
-                if (DBG_CACHE)
-                    log_debug( "\tsubkey not valid\n");
-                continue;
-            }
-            if ( pk->is_revoked ) {
-                if (DBG_CACHE)
-                    log_debug( "\tsubkey has been revoked\n");
-                continue;
-            }
-            if ( pk->has_expired ) {
-                if (DBG_CACHE)
-                    log_debug( "\tsubkey has expired\n");
-                continue;
-            }
-            if ( pk->timestamp > curtime && !opt.ignore_valid_from ) {
-                if (DBG_CACHE)
-                    log_debug( "\tsubkey not yet valid\n");
-                continue;
-            }
+  if (DBG_CACHE)
+    log_debug ("finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
+              (ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL),
+              foundk ? "one" : "all", req_usage);
 
-            if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) {
-                if (DBG_CACHE)
-                    log_debug( "\tusage does not match: want=%x have=%x\n",
-                               req_usage, pk->pubkey_usage );
-                continue;
-            }
+  if (!req_usage)
+    {
+      latest_key = foundk ? foundk : keyblock;
+      goto found;
+    }
 
-            if (DBG_CACHE)
-                log_debug( "\tsubkey might be fine\n");
-            /* In case a key has a timestamp of 0 set, we make sure
-               that it is used.  A better change would be to compare
-               ">=" but that might also change the selected keys and
-               is as such a more intrusive change.  */
-            if ( pk->timestamp > latest_date
-                 || (!pk->timestamp && !latest_date)) {
-                latest_date = pk->timestamp;
-                latest_key  = k;
-            }
-        }
+  latest_date = 0;
+  latest_key = NULL;
+  /* Do not look at subkeys if a certification key is requested.  */
+  if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_prim)
+    {
+      KBNODE nextk;
+      /* Either start a loop or check just this one subkey.  */
+      for (k = foundk ? foundk : keyblock; k; k = nextk)
+       {
+         PKT_public_key *pk;
+         nextk = k->next;
+         if (k->pkt->pkttype != PKT_PUBLIC_SUBKEY)
+           continue;
+         if (foundk)
+           nextk = NULL; /* what a hack */
+         pk = k->pkt->pkt.public_key;
+         if (DBG_CACHE)
+           log_debug ("\tchecking subkey %08lX\n",
+                      (ulong) keyid_from_pk (pk, NULL));
+         if (!pk->flags.valid)
+           {
+             if (DBG_CACHE)
+               log_debug ("\tsubkey not valid\n");
+             continue;
+           }
+         if (pk->flags.revoked)
+           {
+             if (DBG_CACHE)
+               log_debug ("\tsubkey has been revoked\n");
+             continue;
+           }
+         if (pk->has_expired)
+           {
+             if (DBG_CACHE)
+               log_debug ("\tsubkey has expired\n");
+             continue;
+           }
+         if (pk->timestamp > curtime && !opt.ignore_valid_from)
+           {
+             if (DBG_CACHE)
+               log_debug ("\tsubkey not yet valid\n");
+             continue;
+           }
+
+         if (!((pk->pubkey_usage & USAGE_MASK) & req_usage))
+           {
+             if (DBG_CACHE)
+               log_debug ("\tusage does not match: want=%x have=%x\n",
+                          req_usage, pk->pubkey_usage);
+             continue;
+           }
+
+         if (DBG_CACHE)
+           log_debug ("\tsubkey might be fine\n");
+         /* In case a key has a timestamp of 0 set, we make sure
+            that it is used.  A better change would be to compare
+            ">=" but that might also change the selected keys and
+            is as such a more intrusive change.  */
+         if (pk->timestamp > latest_date || (!pk->timestamp && !latest_date))
+           {
+             latest_date = pk->timestamp;
+             latest_key = k;
+           }
+       }
     }
 
-    /* Okay now try the primary key unless we want an exact
-     * key ID match on a subkey */
-    if ((!latest_key && !(ctx->exact && foundk != keyblock)) || req_prim) {
-        PKT_public_key *pk;
-        if (DBG_CACHE && !foundk && !req_prim )
-            log_debug( "\tno suitable subkeys found - trying primary\n");
-        pk = keyblock->pkt->pkt.public_key;
-        if ( !pk->is_valid ) {
-            if (DBG_CACHE)
-                log_debug( "\tprimary key not valid\n");
-        }
-        else if ( pk->is_revoked ) {
-            if (DBG_CACHE)
-                log_debug( "\tprimary key has been revoked\n");
-        }
-        else if ( pk->has_expired ) {
-            if (DBG_CACHE)
-                log_debug( "\tprimary key has expired\n");
-        }
-        else  if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) {
-            if (DBG_CACHE)
-                log_debug( "\tprimary key usage does not match: "
-                           "want=%x have=%x\n",
-                           req_usage, pk->pubkey_usage );
-        }
-        else { /* okay */
-            if (DBG_CACHE)
-                log_debug( "\tprimary key may be used\n");
-            latest_key = keyblock;
-            latest_date = pk->timestamp;
-        }
+  /* Okay now try the primary key unless we want an exact
+   * key ID match on a subkey */
+  if ((!latest_key && !(ctx->exact && foundk != keyblock)) || req_prim)
+    {
+      PKT_public_key *pk;
+      if (DBG_CACHE && !foundk && !req_prim)
+       log_debug ("\tno suitable subkeys found - trying primary\n");
+      pk = keyblock->pkt->pkt.public_key;
+      if (!pk->flags.valid)
+       {
+         if (DBG_CACHE)
+           log_debug ("\tprimary key not valid\n");
+       }
+      else if (pk->flags.revoked)
+       {
+         if (DBG_CACHE)
+           log_debug ("\tprimary key has been revoked\n");
+       }
+      else if (pk->has_expired)
+       {
+         if (DBG_CACHE)
+           log_debug ("\tprimary key has expired\n");
+       }
+      else if (!((pk->pubkey_usage & USAGE_MASK) & req_usage))
+       {
+         if (DBG_CACHE)
+           log_debug ("\tprimary key usage does not match: "
+                      "want=%x have=%x\n", req_usage, pk->pubkey_usage);
+       }
+      else /* Okay.  */
+       {
+         if (DBG_CACHE)
+           log_debug ("\tprimary key may be used\n");
+         latest_key = keyblock;
+         latest_date = pk->timestamp;
+       }
     }
 
-    if ( !latest_key ) {
-        if (DBG_CACHE)
-            log_debug("\tno suitable key found -  giving up\n");
-        return 0;
+  if (!latest_key)
+    {
+      if (DBG_CACHE)
+       log_debug ("\tno suitable key found -  giving up\n");
+      return 0; /* Not found.  */
     }
 
- found:
-    if (DBG_CACHE)
-        log_debug( "\tusing key %08lX\n",
-                (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) );
+found:
+  if (DBG_CACHE)
+    log_debug ("\tusing key %08lX\n",
+              (ulong) keyid_from_pk (latest_key->pkt->pkt.public_key, NULL));
 
-    if (latest_key) {
-        PKT_public_key *pk = latest_key->pkt->pkt.public_key;
-        if (pk->user_id)
-            free_user_id (pk->user_id);
-        pk->user_id = scopy_user_id (foundu);
+  if (latest_key)
+    {
+      PKT_public_key *pk = latest_key->pkt->pkt.public_key;
+      if (pk->user_id)
+       free_user_id (pk->user_id);
+      pk->user_id = scopy_user_id (foundu);
     }
 
-    ctx->found_key = latest_key;
+  ctx->found_key = latest_key;
 
-    if (latest_key != keyblock && opt.verbose)
-      {
-       char *tempkeystr=
-         xstrdup(keystr_from_pk(latest_key->pkt->pkt.public_key));
-        log_info(_("using subkey %s instead of primary key %s\n"),
-                 tempkeystr, keystr_from_pk(keyblock->pkt->pkt.public_key));
-       xfree(tempkeystr);
-      }
+  if (latest_key != keyblock && opt.verbose)
+    {
+      char *tempkeystr =
+       xstrdup (keystr_from_pk (latest_key->pkt->pkt.public_key));
+      log_info (_("using subkey %s instead of primary key %s\n"),
+               tempkeystr, keystr_from_pk (keyblock->pkt->pkt.public_key));
+      xfree (tempkeystr);
+    }
 
-    cache_user_id( keyblock );
+  cache_user_id (keyblock);
 
-    return 1; /* found */
+  return 1; /* Found.  */
 }
 
 
+/* The main function to lookup a key.  On success the found keyblock
+   is stored at RET_KEYBLOCK and also in CTX.  If WANT_SECRET is true
+   a corresponding secret key is required.  */
 static int
-lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
+lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret)
 {
-    int rc;
-    KBNODE secblock = NULL; /* helper */
-    int no_suitable_key = 0;
-
-    rc = 0;
-    while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) {
-        /* If we are searching for the first key we have to make sure
-           that the next iteration does not do an implicit reset.
-           This can be triggered by an empty key ring. */
-        if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST)
-            ctx->items->mode = KEYDB_SEARCH_MODE_NEXT;
-
-        rc = keydb_get_keyblock (ctx->kr_handle, &ctx->keyblock);
-        if (rc) {
-            log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
-            rc = 0;
-            goto skip;
-        }
-
-        if ( secmode ) {
-            /* find the correspondig public key and use this
-             * this one for the selection process */
-            u32 aki[2];
-            KBNODE k = ctx->keyblock;
+  int rc;
+  int no_suitable_key = 0;
 
-            if (k->pkt->pkttype != PKT_SECRET_KEY)
-                BUG();
+  rc = 0;
+  while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems, NULL)))
+    {
+      /* If we are searching for the first key we have to make sure
+         that the next iteration does not do an implicit reset.
+         This can be triggered by an empty key ring. */
+      if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST)
+       ctx->items->mode = KEYDB_SEARCH_MODE_NEXT;
+
+      rc = keydb_get_keyblock (ctx->kr_handle, &ctx->keyblock);
+      if (rc)
+       {
+         log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
+         rc = 0;
+         goto skip;
+       }
 
-            keyid_from_sk (k->pkt->pkt.secret_key, aki);
-            k = get_pubkeyblock (aki);
-            if( !k )
-             {
-                if (!opt.quiet)
-                 log_info(_("key %s: secret key without public key"
-                            " - skipped\n"), keystr(aki));
-                goto skip;
-             }
-            secblock = ctx->keyblock;
-            ctx->keyblock = k;
+      if (want_secret && agent_probe_any_secret_key (NULL, ctx->keyblock))
+        goto skip; /* No secret key available.  */
 
-            premerge_public_with_secret ( ctx->keyblock, secblock );
-        }
+      /* Warning: node flag bits 0 and 1 should be preserved by
+       * merge_selfsigs.  For secret keys, premerge did tranfer the
+       * keys to the keyblock.  */
+      merge_selfsigs (ctx->keyblock);
+      if (finish_lookup (ctx))
+       {
+         no_suitable_key = 0;
+         goto found;
+       }
+      else
+       no_suitable_key = 1;
 
-        /* warning: node flag bits 0 and 1 should be preserved by
-         * merge_selfsigs.  For secret keys, premerge did tranfer the
-         * keys to the keyblock */
-        merge_selfsigs ( ctx->keyblock );
-        if ( finish_lookup (ctx) ) {
-            no_suitable_key = 0;
-            if ( secmode ) {
-                merge_public_with_secret ( ctx->keyblock,
-                                           secblock);
-                release_kbnode (secblock);
-                secblock = NULL;
-            }
-            goto found;
-        }
-        else
-            no_suitable_key = 1;
-
-      skip:
-        /* release resources and continue search */
-        if ( secmode ) {
-            release_kbnode( secblock );
-            secblock = NULL;
-        }
-        release_kbnode( ctx->keyblock );
-        ctx->keyblock = NULL;
+    skip:
+      /* Release resources and continue search. */
+      release_kbnode (ctx->keyblock);
+      ctx->keyblock = NULL;
     }
 
-  found:
-    if( rc && rc != -1 )
-       log_error("keydb_search failed: %s\n", g10_errstr(rc));
+found:
+  if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
+    log_error ("keydb_search failed: %s\n", g10_errstr (rc));
 
-    if( !rc ) {
-        *ret_keyblock = ctx->keyblock; /* return the keyblock */
-        ctx->keyblock = NULL;
+  if (!rc)
+    {
+      *ret_keyblock = ctx->keyblock; /* Return the keyblock.  */
+      ctx->keyblock = NULL;
     }
-    else if (rc == -1 && no_suitable_key)
-        rc = secmode ? G10ERR_UNU_SECKEY : G10ERR_UNU_PUBKEY;
-    else if( rc == -1 )
-       rc = secmode ? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY;
+  else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND && no_suitable_key)
+    rc = want_secret? G10ERR_UNU_SECKEY : G10ERR_UNU_PUBKEY;
+  else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
+    rc = want_secret? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY;
 
-    if ( secmode ) {
-        release_kbnode( secblock );
-        secblock = NULL;
-    }
-    release_kbnode( ctx->keyblock );
-    ctx->keyblock = NULL;
+  release_kbnode (ctx->keyblock);
+  ctx->keyblock = NULL;
 
-    ctx->last_rc = rc;
-    return rc;
+  ctx->last_rc = rc;
+  return rc;
 }
 
 
 
 
-/****************
- * FIXME: Replace by the generic function
- *        It does not work as it is right now - it is used at
- *        2 places:  a) to get the key for an anonyous recipient
- *                   b) to get the ultimately trusted keys.
- *        The a) usage might have some problems.
- *
- * set with_subkeys true to include subkeys
- * set with_spm true to include secret-parts-missing keys
- *
- * Enumerate all primary secret keys.  Caller must use these procedure:
+/*
+ * Enumerate certain secret keys.  Caller must use these procedure:
  *  1) create a void pointer and initialize it to NULL
  *  2) pass this void pointer by reference to this function
  *     and provide space for the secret key (pass a buffer for sk)
- *  3) call this function as long as it does not return -1
- *     to indicate EOF.
+ *  3) call this function as long as it does not return an error.
+ *     The error code GPG_ERR_EOF indicates the end of the listing.
  *  4) Always call this function a last time with SK set to NULL,
  *     so that can free it's context.
  */
-int
-enum_secret_keys( void **context, PKT_secret_key *sk,
-                 int with_subkeys, int with_spm )
+gpg_error_t
+enum_secret_keys (void **context, PKT_public_key *sk)
 {
-    int rc=0;
-    struct {
-       int eof;
-        int first;
-       KEYDB_HANDLE hd;
-        KBNODE keyblock;
-        KBNODE node;
-    } *c = *context;
-
-
-    if( !c ) { /* make a new context */
-       c = xmalloc_clear( sizeof *c );
-       *context = c;
-       c->hd = keydb_new (1);
-        c->first = 1;
-        c->keyblock = NULL;
-        c->node = NULL;
-    }
-
-    if( !sk ) { /* free the context */
-        keydb_release (c->hd);
-        release_kbnode (c->keyblock);
-       xfree( c );
-       *context = NULL;
-       return 0;
-    }
-
-    if( c->eof )
-       return -1;
-
-    do {
-        /* get the next secret key from the current keyblock */
-        for (; c->node; c->node = c->node->next) {
-            if ((c->node->pkt->pkttype == PKT_SECRET_KEY
-                || (with_subkeys
-                    && c->node->pkt->pkttype == PKT_SECRET_SUBKEY) )
-               && !(c->node->pkt->pkt.secret_key->protect.s2k.mode==1001
-                    && !with_spm)) {
-                copy_secret_key (sk, c->node->pkt->pkt.secret_key );
-                c->node = c->node->next;
-                return 0; /* found */
+  gpg_error_t err = 0;
+  const char *name;
+  struct
+  {
+    int eof;
+    int state;
+    strlist_t sl;
+    kbnode_t keyblock;
+    kbnode_t node;
+  } *c = *context;
+
+  if (!c)
+    {
+      /* Make a new context.  */
+      c = xtrycalloc (1, sizeof *c);
+      if (!c)
+        return gpg_error_from_syserror ();
+      *context = c;
+    }
+
+  if (!sk)
+    {
+      /* Free the context.  */
+      release_kbnode (c->keyblock);
+      xfree (c);
+      *context = NULL;
+      return 0;
+    }
+
+  if (c->eof)
+    return gpg_error (GPG_ERR_EOF);
+
+  for (;;)
+    {
+      /* Loop until we have a keyblock.  */
+      while (!c->keyblock)
+        {
+          /* Loop over the list of secret keys.  */
+          do
+            {
+              name = NULL;
+              switch (c->state)
+                {
+                case 0: /* First try to use the --default-key.  */
+                  if (opt.def_secret_key && *opt.def_secret_key)
+                    name = opt.def_secret_key;
+                  c->state = 1;
+                  break;
+
+                case 1: /* Init list of keys to try.  */
+                  c->sl = opt.secret_keys_to_try;
+                  c->state++;
+                  break;
+
+                case 2: /* Get next item from list.  */
+                  if (c->sl)
+                    {
+                      name = c->sl->d;
+                      c->sl = c->sl->next;
+                    }
+                  else
+                    c->state++;
+                  break;
+
+                default: /* No more names to check - stop.  */
+                  c->eof = 1;
+                  return gpg_error (GPG_ERR_EOF);
+                }
             }
-        }
-        release_kbnode (c->keyblock);
-        c->keyblock = c->node = NULL;
-
-        rc = c->first? keydb_search_first (c->hd) : keydb_search_next (c->hd);
-        c->first = 0;
-        if (rc) {
-            keydb_release (c->hd); c->hd = NULL;
-            c->eof = 1;
-            return -1; /* eof */
+          while (!name || !*name);
+
+          err = getkey_byname (NULL, NULL, name, 1, &c->keyblock);
+          if (err)
+            {
+              /* getkey_byname might return a keyblock even in the
+                 error case - I have not checked.  Thus better release
+                 it.  */
+              release_kbnode (c->keyblock);
+              c->keyblock = NULL;
+            }
+          else
+            c->node = c->keyblock;
         }
 
-        rc = keydb_get_keyblock (c->hd, &c->keyblock);
-        c->node = c->keyblock;
-    } while (!rc);
+      /* Get the next key from the current keyblock.  */
+      for (; c->node; c->node = c->node->next)
+       {
+         if (c->node->pkt->pkttype == PKT_PUBLIC_KEY
+              || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+           {
+             copy_public_key (sk, c->node->pkt->pkt.public_key);
+             c->node = c->node->next;
+             return 0; /* Found.  */
+           }
+        }
 
-    return rc; /* error */
+      /* Dispose the keyblock and continue.  */
+      release_kbnode (c->keyblock);
+      c->keyblock = NULL;
+    }
 }
 
-
 \f
 /*********************************************
- ***********  user ID printing helpers *******
+ ***********  User ID printing helpers *******
  *********************************************/
 
-/****************
- * Return a string with a printable representation of the user_id.
- * this string must be freed by xfree.
- */
-char*
-get_user_id_string( u32 *keyid )
+/* Return a string with a printable representation of the user_id.
+ * this string must be freed by xfree.   */
+static char *
+get_user_id_string (u32 * keyid)
 {
   user_id_db_t r;
-  char *p;
-  int pass=0;
-  /* try it two times; second pass reads from key resources */
+  int pass = 0;
+  /* Try it two times; second pass reads from key resources.  */
   do
     {
-      for(r=user_id_db; r; r = r->next )
+      for (r = user_id_db; r; r = r->next)
        {
          keyid_list_t a;
-         for (a=r->keyids; a; a= a->next )
+         for (a = r->keyids; a; a = a->next)
            {
-             if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] )
+             if (a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1])
                {
-                 p = xmalloc( keystrlen() + 1 + r->len + 1 );
-                 sprintf(p, "%s %.*s", keystr(keyid), r->len, r->name );
-                 return p;
+                 return xasprintf ("%s %.*s", keystr (keyid), r->len, r->name);
                }
            }
-        }
-    } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
-  p = xmalloc( keystrlen() + 5 );
-  sprintf(p, "%s [?]", keystr(keyid));
-  return p;
+       }
+    }
+  while (++pass < 2 && !get_pubkey (NULL, keyid));
+  return xasprintf ("%s [?]", keystr (keyid));
 }
 
 
-char*
-get_user_id_string_native ( u32 *keyid )
+char *
+get_user_id_string_native (u32 * keyid)
 {
-  char *p = get_user_id_string( keyid );
-  char *p2 = utf8_to_native( p, strlen(p), 0 );
-  xfree(p);
+  char *p = get_user_id_string (keyid);
+  char *p2 = utf8_to_native (p, strlen (p), 0);
+  xfree (p);
   return p2;
 }
 
 
-char*
-get_long_user_id_string( u32 *keyid )
+char *
+get_long_user_id_string (u32 * keyid)
 {
-    user_id_db_t r;
-    char *p;
-    int pass=0;
-    /* try it two times; second pass reads from key resources */
-    do {
-       for(r=user_id_db; r; r = r->next ) {
-            keyid_list_t a;
-            for (a=r->keyids; a; a= a->next ) {
-                if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) {
-                    p = xmalloc( r->len + 20 );
-                    sprintf(p, "%08lX%08lX %.*s",
-                            (ulong)keyid[0], (ulong)keyid[1],
-                            r->len, r->name );
-                    return p;
-                }
-            }
-        }
-    } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
-    p = xmalloc( 25 );
-    sprintf(p, "%08lX%08lX [?]", (ulong)keyid[0], (ulong)keyid[1] );
-    return p;
+  user_id_db_t r;
+  keyid_list_t a;
+  int pass = 0;
+  /* Try it two times; second pass reads from key resources.  */
+  do
+    {
+      for (r = user_id_db; r; r = r->next)
+       {
+         for (a = r->keyids; a; a = a->next)
+           {
+             if (a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1])
+               {
+                 return xasprintf ("%08lX%08lX %.*s",
+                                    (ulong) keyid[0], (ulong) keyid[1],
+                                    r->len, r->name);
+               }
+           }
+       }
+    }
+  while (++pass < 2 && !get_pubkey (NULL, keyid));
+  return xasprintf ("%08lX%08lX [?]", (ulong) keyid[0], (ulong) keyid[1]);
 }
 
-char*
-get_user_id( u32 *keyid, size_t *rn )
+
+/* Please try to use get_user_id_native instead of this one.  */
+char *
+get_user_id (u32 * keyid, size_t * rn)
 {
   user_id_db_t r;
   char *p;
@@ -3080,108 +2813,230 @@ get_user_id( u32 *keyid, size_t *rn )
   return p;
 }
 
-char*
-get_user_id_native( u32 *keyid )
+/* Please try to use get_user_id_byfpr_native instead of this one.  */
+char *
+get_user_id_native (u32 * keyid)
+{
+  size_t rn;
+  char *p = get_user_id (keyid, &rn);
+  char *p2 = utf8_to_native (p, rn, 0);
+  xfree (p);
+  return p2;
+}
+
+
+/* Return a user id from the caching by looking it up using the FPR
+   which mustbe of size MAX_FINGERPRINT_LEN.  */
+char *
+get_user_id_byfpr (const byte *fpr, size_t *rn)
+{
+  user_id_db_t r;
+  char *p;
+  int pass = 0;
+
+  /* Try it two times; second pass reads from key resources.  */
+  do
+    {
+      for (r = user_id_db; r; r = r->next)
+       {
+         keyid_list_t a;
+         for (a = r->keyids; a; a = a->next)
+           {
+             if (!memcmp (a->fpr, fpr, MAX_FINGERPRINT_LEN))
+               {
+                  /* An empty string as user id is possible.  Make
+                     sure that the malloc allocates one byte and does
+                     not bail out.  */
+                 p = xmalloc (r->len? r->len : 1);
+                 memcpy (p, r->name, r->len);
+                 *rn = r->len;
+                 return p;
+               }
+           }
+       }
+    }
+  while (++pass < 2 && !get_pubkey_byfpr (NULL, fpr));
+  p = xstrdup (user_id_not_found_utf8 ());
+  *rn = strlen (p);
+  return p;
+}
+
+char *
+get_user_id_byfpr_native (const byte *fpr)
 {
   size_t rn;
-  char *p = get_user_id( keyid, &rn );
-  char *p2 = utf8_to_native( p, rn, 0 );
-  xfree(p);
+  char *p = get_user_id_byfpr (fpr, &rn);
+  char *p2 = utf8_to_native (p, rn, 0);
+  xfree (p);
   return p2;
 }
 
+
+
 KEYDB_HANDLE
-get_ctx_handle(GETKEY_CTX ctx)
+get_ctx_handle (GETKEY_CTX ctx)
 {
   return ctx->kr_handle;
 }
 
 static void
-free_akl(struct akl *akl)
+free_akl (struct akl *akl)
 {
-  if (! akl)
-    return;
-
-  if(akl->spec)
-    free_keyserver_spec(akl->spec);
+  if (akl->spec)
+    free_keyserver_spec (akl->spec);
 
-  xfree(akl);
+  xfree (akl);
 }
 
 void
-release_akl(void)
+release_akl (void)
 {
-  while(opt.auto_key_locate)
+  while (opt.auto_key_locate)
     {
-      struct akl *akl2=opt.auto_key_locate;
-      opt.auto_key_locate=opt.auto_key_locate->next;
-      free_akl(akl2);
+      struct akl *akl2 = opt.auto_key_locate;
+      opt.auto_key_locate = opt.auto_key_locate->next;
+      free_akl (akl2);
     }
 }
 
 /* Returns false on error. */
 int
-parse_auto_key_locate(char *options)
+parse_auto_key_locate (char *options)
 {
   char *tok;
 
-  while((tok=optsep(&options)))
+  while ((tok = optsep (&options)))
     {
-      struct akl *akl,*check,*last=NULL;
-      int dupe=0;
+      struct akl *akl, *check, *last = NULL;
+      int dupe = 0;
 
-      if(tok[0]=='\0')
+      if (tok[0] == '\0')
        continue;
 
-      akl=xmalloc_clear(sizeof(*akl));
+      akl = xmalloc_clear (sizeof (*akl));
 
-      if(ascii_strcasecmp(tok,"nodefault")==0)
-       akl->type=AKL_NODEFAULT;
-      else if(ascii_strcasecmp(tok,"local")==0)
-       akl->type=AKL_LOCAL;
-      else if(ascii_strcasecmp(tok,"ldap")==0)
-       akl->type=AKL_LDAP;
-      else if(ascii_strcasecmp(tok,"keyserver")==0)
-       akl->type=AKL_KEYSERVER;
+      if (ascii_strcasecmp (tok, "clear") == 0)
+       {
+          xfree (akl);
+          free_akl (opt.auto_key_locate);
+          opt.auto_key_locate = NULL;
+          continue;
+        }
+      else if (ascii_strcasecmp (tok, "nodefault") == 0)
+       akl->type = AKL_NODEFAULT;
+      else if (ascii_strcasecmp (tok, "local") == 0)
+       akl->type = AKL_LOCAL;
+      else if (ascii_strcasecmp (tok, "ldap") == 0)
+       akl->type = AKL_LDAP;
+      else if (ascii_strcasecmp (tok, "keyserver") == 0)
+       akl->type = AKL_KEYSERVER;
 #ifdef USE_DNS_CERT
-      else if(ascii_strcasecmp(tok,"cert")==0)
-       akl->type=AKL_CERT;
+      else if (ascii_strcasecmp (tok, "cert") == 0)
+       akl->type = AKL_CERT;
 #endif
 #ifdef USE_DNS_PKA
-      else if(ascii_strcasecmp(tok,"pka")==0)
-       akl->type=AKL_PKA;
+      else if (ascii_strcasecmp (tok, "pka") == 0)
+       akl->type = AKL_PKA;
 #endif
-      else if((akl->spec=parse_keyserver_uri(tok,1,NULL,0)))
-       akl->type=AKL_SPEC;
+      else if ((akl->spec = parse_keyserver_uri (tok, 1, NULL, 0)))
+       akl->type = AKL_SPEC;
       else
        {
-         free_akl(akl);
+         free_akl (akl);
          return 0;
        }
 
       /* We must maintain the order the user gave us */
-      for(check=opt.auto_key_locate;check;last=check,check=check->next)
+      for (check = opt.auto_key_locate; check;
+          last = check, check = check->next)
        {
          /* Check for duplicates */
-         if(check->type==akl->type
-            && (akl->type!=AKL_SPEC
-                || (akl->type==AKL_SPEC
-                    && strcmp(check->spec->uri,akl->spec->uri)==0)))
+         if (check->type == akl->type
+             && (akl->type != AKL_SPEC
+                 || (akl->type == AKL_SPEC
+                     && strcmp (check->spec->uri, akl->spec->uri) == 0)))
            {
-             dupe=1;
-             free_akl(akl);
+             dupe = 1;
+             free_akl (akl);
              break;
            }
        }
 
-      if(!dupe)
+      if (!dupe)
        {
-         if(last)
-           last->next=akl;
+         if (last)
+           last->next = akl;
          else
-           opt.auto_key_locate=akl;
+           opt.auto_key_locate = akl;
        }
     }
 
   return 1;
 }
+
+
+/* Return true if a secret key or secret subkey is available for one
+   of the public keys in KEYBLOCK.  */
+int
+have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
+{
+  kbnode_t node;
+
+  for (node = keyblock; node; node = node->next)
+    if ((node->pkt->pkttype == PKT_PUBLIC_KEY
+         || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+        && !agent_probe_secret_key (ctrl, node->pkt->pkt.public_key))
+      return 1;
+  return 0;
+}
+
+
+/* Return true if a secret key is available for the public key with
+ * the given KEYID.  This is just a fast check and does not tell us
+ * whether the secret key is valid.  It merely tells os whether there
+ * is some secret key.  */
+int
+have_secret_key_with_kid (u32 *keyid)
+{
+  gpg_error_t err;
+  KEYDB_HANDLE kdbhd;
+  KEYDB_SEARCH_DESC desc;
+  kbnode_t keyblock;
+  kbnode_t node;
+  int result = 0;
+
+  kdbhd = keydb_new ();
+  memset (&desc, 0, sizeof desc);
+  desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
+  desc.u.kid[0] = keyid[0];
+  desc.u.kid[1] = keyid[1];
+  while (!result && !(err = keydb_search (kdbhd, &desc, 1, NULL)))
+    {
+      err = keydb_get_keyblock (kdbhd, &keyblock);
+      if (err)
+        {
+          log_error (_("error reading keyblock: %s\n"), g10_errstr (err));
+          break;
+        }
+
+      for (node = keyblock; node; node = node->next)
+       {
+          /* Bit 0 of the flags is set if the search found the key
+             using that key or subkey.  */
+         if ((node->flag & 1))
+            {
+              assert (node->pkt->pkttype == PKT_PUBLIC_KEY
+                      || node->pkt->pkttype == PKT_PUBLIC_SUBKEY);
+
+              if (!agent_probe_secret_key (NULL, node->pkt->pkt.public_key))
+                {
+                  result = 1;
+                  break;
+                }
+           }
+       }
+      release_kbnode (keyblock);
+    }
+  keydb_release (kdbhd);
+  return result;
+}
index a757fe3..c188d4a 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,7 +1,6 @@
 /* gpg.c - The GnuPG utility (main for gpg)
  * Copyright (C) 1998-2011 Free Software Foundation, Inc.
- * Copyright (C) 1997-2015 Werner Koch
- * Copyright (C) 2015 g10 Code GmbH
+ * Copyright (C) 1997-2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #define INCLUDED_BY_MAIN_MODULE 1
 #include "gpg.h"
 #include <assuan.h>
-#include "packet.h"
 #include "../common/iobuf.h"
 #include "util.h"
+#include "packet.h"
 #include "membuf.h"
 #include "main.h"
 #include "options.h"
 #include "keydb.h"
 #include "trustdb.h"
-#include "cipher.h"
 #include "filter.h"
 #include "ttyio.h"
 #include "i18n.h"
 #include "keyserver-internal.h"
 #include "exec.h"
 #include "gc-opt-flags.h"
+#include "asshelp.h"
+#include "call-dirmngr.h"
+#include "../common/init.h"
+#include "../common/shareddefs.h"
 
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
 #define MY_O_BINARY  O_BINARY
@@ -103,14 +105,17 @@ enum cmd_and_opt_values
     aDecryptFiles,
     aClearsign,
     aStore,
+    aQuickKeygen,
+    aFullKeygen,
     aKeygen,
     aSignEncr,
     aSignEncrSym,
     aSignSym,
     aSignKey,
     aLSignKey,
+    aQuickSignKey,
+    aQuickLSignKey,
     aListConfig,
-    aListGcryptConfig,
     aGPGConfList,
     aGPGConfTest,
     aListPackets,
@@ -171,6 +176,8 @@ enum cmd_and_opt_values
     oNoAskCertLevel,
     oFingerprint,
     oWithFingerprint,
+    oWithKeygrip,
+    oWithSecret,
     oAnswerYes,
     oAnswerNo,
     oKeyring,
@@ -181,6 +188,7 @@ enum cmd_and_opt_values
     oDefRecipient,
     oDefRecipientSelf,
     oNoDefRecipient,
+    oTrySecretKey,
     oOptions,
     oDebug,
     oDebugLevel,
@@ -197,11 +205,9 @@ enum cmd_and_opt_values
     oMaxCertDepth,
     oLoadExtension,
     oGnuPG,
-    oRFC1991,
     oRFC2440,
     oRFC4880,
     oOpenPGP,
-    oPGP2,
     oPGP6,
     oPGP7,
     oPGP8,
@@ -218,6 +224,7 @@ enum cmd_and_opt_values
     oPassphraseFD,
     oPassphraseFile,
     oPassphraseRepeat,
+    oPinentryMode,
     oCommandFD,
     oCommandFile,
     oQuickRandom,
@@ -242,8 +249,6 @@ enum cmd_and_opt_values
     oSkipVerify,
     oSkipHiddenRecipients,
     oNoSkipHiddenRecipients,
-    oCompressKeys,
-    oCompressSigs,
     oAlwaysTrust,
     oTrustModel,
     oForceOwnertrust,
@@ -266,10 +271,6 @@ enum cmd_and_opt_values
     oShowPhotos,
     oNoShowPhotos,
     oPhotoViewer,
-    oForceV3Sigs,
-    oNoForceV3Sigs,
-    oForceV4Certs,
-    oNoForceV4Certs,
     oForceMDC,
     oNoForceMDC,
     oDisableMDC,
@@ -278,7 +279,6 @@ enum cmd_and_opt_values
     oS2KDigest,
     oS2KCipher,
     oS2KCount,
-    oSimpleSKChecksum,
     oDisplayCharset,
     oNotDashEscaped,
     oEscapeFrom,
@@ -331,7 +331,9 @@ enum cmd_and_opt_values
     oTrustedKey,
     oNoExpensiveTrustChecks,
     oFixedListMode,
+    oLegacyListMode,
     oNoSigCache,
+    oNoSigCreateCheck,
     oAutoCheckTrustDB,
     oNoAutoCheckTrustDB,
     oPreservePermissions,
@@ -341,6 +343,7 @@ enum cmd_and_opt_values
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
     oAgentProgram,
+    oDirmngrProgram,
     oDisplay,
     oTTYname,
     oTTYtype,
@@ -375,6 +378,7 @@ enum cmd_and_opt_values
     oAllowMultipleMessages,
     oNoAllowMultipleMessages,
     oAllowWeakDigestAlgos,
+    oFakedSystemTime,
 
     oNoop
   };
@@ -401,12 +405,21 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aCheckKeys, "check-sigs",N_("list and check key signatures")),
   ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")),
   ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
-  ARGPARSE_c (aKeygen,    "gen-key",  N_("generate a new key pair")),
+  ARGPARSE_c (aKeygen,     "gen-key",
+              N_("generate a new key pair")),
+  ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
+              N_("quickly generate a new key pair")),
+  ARGPARSE_c (aFullKeygen,  "full-gen-key" ,
+              N_("full featured key pair generation")),
   ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
   ARGPARSE_c (aDeleteKeys,"delete-keys",
               N_("remove keys from the public keyring")),
   ARGPARSE_c (aDeleteSecretKeys, "delete-secret-keys",
               N_("remove keys from the secret keyring")),
+  ARGPARSE_c (aQuickSignKey,  "quick-sign-key" ,
+              N_("quickly sign a key")),
+  ARGPARSE_c (aQuickLSignKey, "quick-lsign-key",
+              N_("quickly sign a key locally")),
   ARGPARSE_c (aSignKey,  "sign-key"   ,N_("sign a key")),
   ARGPARSE_c (aLSignKey, "lsign-key"  ,N_("sign a key locally")),
   ARGPARSE_c (aEditKey,  "edit-key"   ,N_("sign or edit a key")),
@@ -432,16 +445,19 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aChangePIN,  "change-pin", N_("change a card's PIN")),
 #endif
   ARGPARSE_c (aListConfig, "list-config", "@"),
-  ARGPARSE_c (aListGcryptConfig, "list-gcrypt-config", "@"),
   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@" ),
   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@" ),
   ARGPARSE_c (aListPackets, "list-packets","@"),
+
+#ifndef NO_TRUST_MODELS
   ARGPARSE_c (aExportOwnerTrust, "export-ownertrust", "@"),
   ARGPARSE_c (aImportOwnerTrust, "import-ownertrust", "@"),
   ARGPARSE_c (aUpdateTrustDB,"update-trustdb",
               N_("update the trust database")),
   ARGPARSE_c (aCheckTrustDB, "check-trustdb", "@"),
   ARGPARSE_c (aFixTrustDB, "fix-trustdb", "@"),
+#endif
+
   ARGPARSE_c (aDeArmor, "dearmor", "@"),
   ARGPARSE_c (aDeArmor, "dearmour", "@"),
   ARGPARSE_c (aEnArmor, "enarmor", "@"),
@@ -471,6 +487,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oLocalUser, "local-user",
                 N_("|USER-ID|use USER-ID to sign or decrypt")),
 
+  ARGPARSE_s_s (oTrySecretKey, "try-secret-key", "@"),
+
   ARGPARSE_s_i (oCompress, NULL,
                 N_("|N|set compress level to N (0 disables)")),
   ARGPARSE_s_i (oCompressLevel, "compress-level", "@"),
@@ -502,10 +520,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oQuiet,          "quiet",   "@"),
   ARGPARSE_s_n (oNoTTY,   "no-tty",  "@"),
 
-  ARGPARSE_s_n (oForceV3Sigs,      "force-v3-sigs", "@"),
-  ARGPARSE_s_n (oNoForceV3Sigs, "no-force-v3-sigs", "@"),
-  ARGPARSE_s_n (oForceV4Certs,     "force-v4-certs", "@"),
-  ARGPARSE_s_n (oNoForceV4Certs, "no-force-v4-certs", "@"),
   ARGPARSE_s_n (oForceMDC, "force-mdc", "@"),
   ARGPARSE_s_n (oNoForceMDC, "no-force-mdc", "@"),
   ARGPARSE_s_n (oDisableMDC, "disable-mdc", "@"),
@@ -554,11 +568,9 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oGnuPG, "no-pgp6", "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp7", "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp8", "@"),
-  ARGPARSE_s_n (oRFC1991, "rfc1991", "@"),
   ARGPARSE_s_n (oRFC2440, "rfc2440", "@"),
   ARGPARSE_s_n (oRFC4880, "rfc4880", "@"),
   ARGPARSE_s_n (oOpenPGP, "openpgp", N_("use strict OpenPGP behavior")),
-  ARGPARSE_s_n (oPGP2, "pgp2", "@"),
   ARGPARSE_s_n (oPGP6, "pgp6", "@"),
   ARGPARSE_s_n (oPGP7, "pgp7", "@"),
   ARGPARSE_s_n (oPGP8, "pgp8", "@"),
@@ -569,7 +581,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oS2KDigest, "s2k-digest-algo", "@"),
   ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
   ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
-  ARGPARSE_s_n (oSimpleSKChecksum, "simple-sk-checksum", "@"),
   ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
   ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
   ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
@@ -600,7 +611,10 @@ static ARGPARSE_OPTS opts[] = {
 
   /* More hidden commands and options. */
   ARGPARSE_c (aPrintMDs, "print-mds", "@"), /* old */
+#ifndef NO_TRUST_MODELS
   ARGPARSE_c (aListTrustDB, "list-trustdb", "@"),
+#endif
+
   /* Not yet used:
      ARGPARSE_c (aListTrustPath, "list-trust-path", "@"), */
   ARGPARSE_c (aDeleteSecretAndPublicKeys,
@@ -611,11 +625,19 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oPassphraseFD,    "passphrase-fd", "@"),
   ARGPARSE_s_s (oPassphraseFile,  "passphrase-file", "@"),
   ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
+  ARGPARSE_s_s (oPinentryMode,    "pinentry-mode", "@"),
   ARGPARSE_s_i (oCommandFD, "command-fd", "@"),
   ARGPARSE_s_s (oCommandFile, "command-file", "@"),
   ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"),
   ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
+
+#ifndef NO_TRUST_MODELS
   ARGPARSE_s_s (oTrustDBName, "trustdb-name", "@"),
+  ARGPARSE_s_n (oAutoCheckTrustDB, "auto-check-trustdb", "@"),
+  ARGPARSE_s_n (oNoAutoCheckTrustDB, "no-auto-check-trustdb", "@"),
+  ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"),
+#endif
+
   ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
   ARGPARSE_s_n (oRequireSecmem, "require-secmem", "@"),
   ARGPARSE_s_n (oNoRequireSecmem, "no-require-secmem", "@"),
@@ -638,12 +660,9 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
-  ARGPARSE_s_n (oCompressKeys, "compress-keys", "@"),
-  ARGPARSE_s_n (oCompressSigs, "compress-sigs", "@"),
   ARGPARSE_s_i (oDefCertLevel, "default-cert-check-level", "@"), /* old */
   ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"),
   ARGPARSE_s_s (oTrustModel, "trust-model", "@"),
-  ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"),
   ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
   ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"),
   ARGPARSE_s_n (oNoForYourEyesOnly, "no-for-your-eyes-only", "@"),
@@ -675,6 +694,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oUtf8Strings,      "utf8-strings", "@"),
   ARGPARSE_s_n (oNoUtf8Strings, "no-utf8-strings", "@"),
   ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
+  ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
+  ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
@@ -686,6 +707,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"),
   ARGPARSE_s_n (oFastListMode, "fast-list-mode", "@"),
   ARGPARSE_s_n (oFixedListMode, "fixed-list-mode", "@"),
+  ARGPARSE_s_n (oLegacyListMode, "legacy-list-mode", "@"),
   ARGPARSE_s_n (oListOnly, "list-only", "@"),
   ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
   ARGPARSE_s_n (oIgnoreValidFrom,    "ignore-valid-from", "@"),
@@ -697,8 +719,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oAutoKeyRetrieve, "auto-key-retrieve", "@"),
   ARGPARSE_s_n (oNoAutoKeyRetrieve, "no-auto-key-retrieve", "@"),
   ARGPARSE_s_n (oNoSigCache,         "no-sig-cache", "@"),
-  ARGPARSE_s_n (oAutoCheckTrustDB, "auto-check-trustdb", "@"),
-  ARGPARSE_s_n (oNoAutoCheckTrustDB, "no-auto-check-trustdb", "@"),
+  ARGPARSE_s_n (oNoSigCreateCheck,   "no-sig-create-check", "@"),
   ARGPARSE_s_n (oMergeOnly,      "merge-only", "@" ),
   ARGPARSE_s_n (oAllowSecretKeyImport, "allow-secret-key-import", "@"),
   ARGPARSE_s_n (oTryAllSecrets,  "try-all-secrets", "@"),
@@ -711,13 +732,16 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-preferences","@"),
   ARGPARSE_s_s (oPersonalCompressPreferences,
                                          "personal-compress-preferences", "@"),
+  ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
 
   /* Aliases.  I constantly mistype these, and assume other people do
      as well. */
   ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-prefs", "@"),
   ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-prefs", "@"),
   ARGPARSE_s_s (oPersonalCompressPreferences, "personal-compress-prefs", "@"),
+
   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
+  ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
   ARGPARSE_s_s (oDisplay,    "display",    "@"),
   ARGPARSE_s_s (oTTYname,    "ttyname",    "@"),
   ARGPARSE_s_s (oTTYtype,    "ttytype",    "@"),
@@ -775,7 +799,12 @@ static ARGPARSE_OPTS opts[] = {
   /* Dummy options.  */
   ARGPARSE_s_n (oNoop, "sk-comments", "@"),
   ARGPARSE_s_n (oNoop, "no-sk-comments", "@"),
-  ARGPARSE_s_n (oNoop, "no-sig-create-check", "@"),
+  ARGPARSE_s_n (oNoop, "compress-keys", "@"),
+  ARGPARSE_s_n (oNoop, "compress-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "force-v3-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-v3-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "force-v4-certs", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-v4-certs", "@"),
 
   ARGPARSE_end ()
 };
@@ -822,6 +851,54 @@ make_libversion (const char *libname, const char *(*getfnc)(const char*))
 }
 
 
+static int
+build_list_pk_test_algo (int algo)
+{
+  /* Show only one "RSA" string.  If RSA_E or RSA_S is available RSA
+     is also available.  */
+  if (algo == PUBKEY_ALGO_RSA_E
+      || algo == PUBKEY_ALGO_RSA_S)
+    return GPG_ERR_DIGEST_ALGO;
+
+  return openpgp_pk_test_algo (algo);
+}
+
+static const char *
+build_list_pk_algo_name (int algo)
+{
+  return openpgp_pk_algo_name (algo);
+}
+
+static int
+build_list_cipher_test_algo (int algo)
+{
+  return openpgp_cipher_test_algo (algo);
+}
+
+static const char *
+build_list_cipher_algo_name (int algo)
+{
+  return openpgp_cipher_algo_name (algo);
+}
+
+static int
+build_list_md_test_algo (int algo)
+{
+  /* By default we do not accept MD5 based signatures.  To avoid
+     confusion we do not announce support for it either.  */
+  if (algo == DIGEST_ALGO_MD5)
+    return GPG_ERR_DIGEST_ALGO;
+
+  return openpgp_md_test_algo (algo);
+}
+
+static const char *
+build_list_md_algo_name (int algo)
+{
+  return openpgp_md_algo_name (algo);
+}
+
+
 static const char *
 my_strusage( int level )
 {
@@ -829,7 +906,7 @@ my_strusage( int level )
   const char *p;
 
     switch( level ) {
-      case 11: p = "gpg (GnuPG)";
+      case 11: p = "@GPG@ (@GNUPG@)";
        break;
       case 13: p = VERSION; break;
       case 17: p = PRINTABLE_OS_NAME; break;
@@ -855,10 +932,10 @@ my_strusage( int level )
 
       case 1:
       case 40: p =
-           _("Usage: gpg [options] [files] (-h for help)");
+           _("Usage: @GPG@ [options] [files] (-h for help)");
        break;
       case 41: p =
-           _("Syntax: gpg [options] [files]\n"
+           _("Syntax: @GPG@ [options] [files]\n"
              "Sign, check, encrypt or decrypt\n"
              "Default operation depends on the input data\n");
        break;
@@ -872,23 +949,23 @@ my_strusage( int level )
       case 33: p = _("\nSupported algorithms:\n"); break;
       case 34:
        if (!pubkeys)
-            pubkeys = build_list (_("Pubkey: "), 'P',
-                                  openpgp_pk_algo_name,
-                                  openpgp_pk_test_algo );
+            pubkeys = build_list (_("Pubkey: "), 1,
+                                  build_list_pk_algo_name,
+                                  build_list_pk_test_algo );
        p = pubkeys;
        break;
       case 35:
        if( !ciphers )
            ciphers = build_list(_("Cipher: "), 'S',
-                                 openpgp_cipher_algo_name,
-                                 openpgp_cipher_test_algo );
+                                 build_list_cipher_algo_name,
+                                 build_list_cipher_test_algo );
        p = ciphers;
        break;
       case 36:
        if( !digests )
            digests = build_list(_("Hash: "), 'H',
-                                 gcry_md_algo_name,
-                                 openpgp_md_test_algo );
+                                 build_list_md_algo_name,
+                                 build_list_md_test_algo );
        p = digests;
        break;
       case 37:
@@ -924,9 +1001,6 @@ build_list (const char *text, char letter,
 
   for (i=0; i <= 110; i++ )
     {
-      if (letter == 'P' && i == 19 )
-        continue; /* No need to print a second "ECC" string.  */
-
       if (!chkf (i) && (s = mapf (i)))
         {
           if (mb.len - len > 60)
@@ -942,10 +1016,13 @@ build_list (const char *text, char letter,
             put_membuf_str (&mb, text);
 
           put_membuf_str (&mb, s);
-          if (opt.verbose && letter && letter != 'P')
+          if (opt.verbose && letter)
             {
               char num[20];
-              snprintf (num, sizeof num, " (%c%d)", letter, i);
+              if (letter == 1)
+                snprintf (num, sizeof num, " (%d)", i);
+              else
+                snprintf (num, sizeof num, " (%c%d)", letter, i);
               put_membuf_str (&mb, num);
             }
        }
@@ -962,10 +1039,8 @@ build_list (const char *text, char letter,
 static void
 wrong_args( const char *text)
 {
-    fputs(_("usage: gpg [options] "),stderr);
-    fputs(text,stderr);
-    putc('\n',stderr);
-    g10_exit(2);
+  fprintf (stderr, _("usage: %s [options] %s\n"), GPG_NAME, text);
+  g10_exit(2);
 }
 
 
@@ -1025,7 +1100,7 @@ set_debug (const char *level)
     }
   else
     {
-      log_error (_("invalid debug-level `%s' given\n"), level);
+      log_error (_("invalid debug-level '%s' given\n"), level);
       g10_exit (2);
     }
 
@@ -1042,7 +1117,7 @@ set_debug (const char *level)
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 
   if (opt.debug)
-    log_info ("enabled debug flags:%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+    log_info ("enabled debug flags:%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
               (opt.debug & DBG_PACKET_VALUE )? " packet":"",
               (opt.debug & DBG_MPI_VALUE    )? " mpi":"",
               (opt.debug & DBG_CIPHER_VALUE )? " cipher":"",
@@ -1055,7 +1130,8 @@ set_debug (const char *level)
               (opt.debug & DBG_HASHING_VALUE)? " hashing":"",
               (opt.debug & DBG_EXTPROG_VALUE)? " extprog":"",
               (opt.debug & DBG_CARD_IO_VALUE)? " cardio":"",
-              (opt.debug & DBG_ASSUAN_VALUE )? " assuan":"");
+              (opt.debug & DBG_ASSUAN_VALUE )? " assuan":"",
+              (opt.debug & DBG_CLOCK_VALUE  )? " clock":"");
 }
 
 
@@ -1125,7 +1201,7 @@ open_info_file (const char *fname, int for_write, int binary)
 /*   if (is_secured_filename (fname)) */
 /*     { */
 /*       fd = -1; */
-/*       errno = EPERM; */
+/*       gpg_err_set_errno (EPERM); */
 /*     } */
 /*   else */
 /*     { */
@@ -1140,8 +1216,8 @@ open_info_file (const char *fname, int for_write, int binary)
       while (fd == -1 && errno == EINTR);
 /*     } */
   if ( fd == -1)
-    log_error ( for_write? _("can't create `%s': %s\n")
-                         : _("can't open `%s': %s\n"), fname, strerror(errno));
+    log_error ( for_write? _("can't create '%s': %s\n")
+                         : _("can't open '%s': %s\n"), fname, strerror(errno));
 
   return fd;
 #endif
@@ -1194,7 +1270,7 @@ add_group(char *string)
   name=strsep(&string,"=");
   if(string==NULL)
     {
-      log_error(_("no = sign found in group definition `%s'\n"),name);
+      log_error(_("no = sign found in group definition '%s'\n"),name);
       return;
     }
 
@@ -1260,7 +1336,7 @@ rm_group(char *name)
 
    Returns true if the item is unsafe. */
 static int
-check_permissions(const char *path,int item)
+check_permissions (const char *path, int item)
 {
 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
   static int homedir_cache=-1;
@@ -1392,49 +1468,49 @@ check_permissions(const char *path,int item)
        {
          if(item==0)
            log_info(_("WARNING: unsafe ownership on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe ownership on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe ownership on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
       if(perm)
        {
          if(item==0)
            log_info(_("WARNING: unsafe permissions on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe permissions on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe permissions on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
       if(enc_dir_own)
        {
          if(item==0)
            log_info(_("WARNING: unsafe enclosing directory ownership on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe enclosing directory ownership on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe enclosing directory ownership on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
       if(enc_dir_perm)
        {
          if(item==0)
            log_info(_("WARNING: unsafe enclosing directory permissions on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe enclosing directory permissions on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe enclosing directory permissions on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
     }
 
@@ -1446,9 +1522,11 @@ check_permissions(const char *path,int item)
 
   return ret;
 
-#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
-
+#else /*!(HAVE_STAT && !HAVE_DOSISH_SYSTEM)*/
+  (void)path;
+  (void)item;
   return 0;
+#endif /*!(HAVE_STAT && !HAVE_DOSISH_SYSTEM)*/
 }
 
 
@@ -1465,8 +1543,8 @@ print_algo_numbers(int (*checker)(int))
          if(first)
            first=0;
          else
-           printf(";");
-         printf("%d",i);
+           es_printf (";");
+         es_printf ("%d",i);
        }
     }
 }
@@ -1484,8 +1562,8 @@ print_algo_names(int (*checker)(int),const char *(*mapper)(int))
          if(first)
            first=0;
          else
-           printf(";");
-         printf("%s",mapper(i));
+           es_printf (";");
+         es_printf ("%s",mapper(i));
        }
     }
 }
@@ -1515,18 +1593,19 @@ list_config(char *items)
            {
              strlist_t sl;
 
-             printf("cfg:group:");
-             print_string(stdout,iter->name,strlen(iter->name),':');
-             printf(":");
+             es_fprintf (es_stdout, "cfg:group:");
+             es_write_sanitized (es_stdout, iter->name, strlen(iter->name),
+                                  ":", NULL);
+             es_putc (':', es_stdout);
 
              for(sl=iter->values;sl;sl=sl->next)
                {
                  print_sanitized_string2 (stdout, sl->d, ':',';');
                  if(sl->next)
-                   printf(";");
+                    es_printf(";");
                }
 
-             printf("\n");
+              es_printf("\n");
            }
 
          any=1;
@@ -1534,33 +1613,43 @@ list_config(char *items)
 
       if(show_all || ascii_strcasecmp(name,"version")==0)
        {
-         printf("cfg:version:");
-         print_string(stdout,VERSION,strlen(VERSION),':');
-         printf("\n");
+         es_printf("cfg:version:");
+         es_write_sanitized (es_stdout, VERSION, strlen(VERSION), ":", NULL);
+          es_printf ("\n");
          any=1;
        }
 
       if(show_all || ascii_strcasecmp(name,"pubkey")==0)
        {
-         printf("cfg:pubkey:");
-         print_algo_numbers (openpgp_pk_test_algo);
-         printf("\n");
+         es_printf ("cfg:pubkey:");
+         print_algo_numbers (build_list_pk_test_algo);
+         es_printf ("\n");
+         any=1;
+       }
+
+      if(show_all || ascii_strcasecmp(name,"pubkeyname")==0)
+       {
+         es_printf ("cfg:pubkeyname:");
+         print_algo_names (build_list_pk_test_algo,
+                            build_list_pk_algo_name);
+         es_printf ("\n");
          any=1;
        }
 
       if(show_all || ascii_strcasecmp(name,"cipher")==0)
        {
-         printf("cfg:cipher:");
-         print_algo_numbers(openpgp_cipher_test_algo);
-         printf("\n");
+         es_printf ("cfg:cipher:");
+         print_algo_numbers (build_list_cipher_test_algo);
+         es_printf ("\n");
          any=1;
        }
 
       if (show_all || !ascii_strcasecmp (name,"ciphername"))
        {
-         printf ("cfg:ciphername:");
-         print_algo_names (openpgp_cipher_test_algo,openpgp_cipher_algo_name);
-         printf ("\n");
+         es_printf ("cfg:ciphername:");
+         print_algo_names (build_list_cipher_test_algo,
+                            build_list_cipher_algo_name);
+         es_printf ("\n");
          any = 1;
        }
 
@@ -1568,9 +1657,9 @@ list_config(char *items)
         || ascii_strcasecmp(name,"digest")==0
         || ascii_strcasecmp(name,"hash")==0)
        {
-         printf("cfg:digest:");
-         print_algo_numbers(openpgp_md_test_algo);
-         printf("\n");
+         es_printf ("cfg:digest:");
+         print_algo_numbers (build_list_md_test_algo);
+         es_printf ("\n");
          any=1;
        }
 
@@ -1578,17 +1667,18 @@ list_config(char *items)
           || !ascii_strcasecmp(name,"digestname")
           || !ascii_strcasecmp(name,"hashname"))
        {
-         printf ("cfg:digestname:");
-         print_algo_names (openpgp_md_test_algo, gcry_md_algo_name);
-         printf("\n");
+         es_printf ("cfg:digestname:");
+         print_algo_names (build_list_md_test_algo,
+                            build_list_md_algo_name);
+         es_printf ("\n");
          any=1;
        }
 
       if(show_all || ascii_strcasecmp(name,"compress")==0)
        {
-         printf("cfg:compress:");
+         es_printf ("cfg:compress:");
          print_algo_numbers(check_compress_algo);
-         printf("\n");
+         es_printf ("\n");
          any=1;
        }
 
@@ -1602,7 +1692,7 @@ list_config(char *items)
           for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1)
             {
               *p2 = 0;
-              printf("cfg:ccid-reader-id:%s\n", p);
+              es_printf ("cfg:ccid-reader-id:%s\n", p);
             }
           free (list);
 #endif
@@ -1613,7 +1703,7 @@ list_config(char *items)
        break;
 
       if(!any)
-       log_error(_("unknown configuration item `%s'\n"),name);
+       log_error(_("unknown configuration item '%s'\n"),name);
     }
 }
 
@@ -1628,23 +1718,26 @@ gpgconf_list (const char *configfile)
 {
   char *configfile_esc = percent_escape (configfile, NULL);
 
-  printf ("gpgconf-gpg.conf:%lu:\"%s\n",
-          GC_OPT_FLAG_DEFAULT, configfile_esc ? configfile_esc : "/dev/null");
-  printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
-  printf ("quiet:%lu:\n",   GC_OPT_FLAG_NONE);
-  printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
-  printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
-  printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE);
-  printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
-  printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
-  printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
-  printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
-  printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("%s-%s.conf:%lu:\"%s\n",
+             GPGCONF_NAME, GPG_NAME,
+             GC_OPT_FLAG_DEFAULT,
+             configfile_esc ? configfile_esc : "/dev/null");
+  es_printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("quiet:%lu:\n",   GC_OPT_FLAG_NONE);
+  es_printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("try-secret-key:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
+  es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
 
   /* The next one is an info only item and should match the macros at
-     the top of keygen.c.  */
-  printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
-          "RSA-2048");
+     the top of keygen.c  */
+  es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
+             "RSA-2048");
 
   xfree (configfile_esc);
 }
@@ -1718,6 +1811,8 @@ parse_list_options(char *str)
     {
       {"show-photos",LIST_SHOW_PHOTOS,NULL,
        N_("display photo IDs during key listings")},
+      {"show-usage",LIST_SHOW_USAGE,NULL,
+       N_("show key usage information during key listings")},
       {"show-policy-urls",LIST_SHOW_POLICY_URLS,NULL,
        N_("show policy URLs during signature listings")},
       {"show-notations",LIST_SHOW_NOTATIONS,NULL,
@@ -1799,6 +1894,8 @@ collapse_args(int argc,char *argv[])
   return str;
 }
 
+
+#ifndef NO_TRUST_MODELS
 static void
 parse_trust_model(const char *model)
 {
@@ -1813,8 +1910,9 @@ parse_trust_model(const char *model)
   else if(ascii_strcasecmp(model,"auto")==0)
     opt.trust_model=TM_AUTO;
   else
-    log_error("unknown trust model `%s'\n",model);
+    log_error("unknown trust model '%s'\n",model);
 }
+#endif /*NO_TRUST_MODELS*/
 
 
 /* This fucntion called to initialized a new control object.  It is
@@ -1832,7 +1930,7 @@ gpg_init_default_ctrl (ctrl_t ctrl)
 static void
 gpg_deinit_default_ctrl (ctrl_t ctrl)
 {
-  (void)ctrl;
+  gpg_dirmngr_deinit_session_data (ctrl);
 }
 
 
@@ -1840,8 +1938,8 @@ char *
 get_default_configname (void)
 {
   char *configname = NULL;
-  char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION);
-  char *ver = &name[strlen ("gpg" EXTSEP_S "conf-")];
+  char *name = xstrdup (GPG_NAME EXTSEP_S "conf-" SAFE_VERSION);
+  char *ver = &name[strlen (GPG_NAME EXTSEP_S "conf-")];
 
   do
     {
@@ -1867,13 +1965,13 @@ get_default_configname (void)
   xfree(name);
 
   if (! configname)
-    configname = make_filename (opt.homedir, "gpg" EXTSEP_S "conf", NULL);
+    configname = make_filename (opt.homedir, GPG_NAME EXTSEP_S "conf", NULL);
   if (! access (configname, R_OK))
     {
       /* Print a warning when both config files are present.  */
       char *p = make_filename (opt.homedir, "options", NULL);
       if (! access (p, R_OK))
-       log_info (_("NOTE: old default options file `%s' ignored\n"), p);
+       log_info (_("Note: old default options file '%s' ignored\n"), p);
       xfree (p);
     }
   else
@@ -1905,7 +2003,7 @@ main (int argc, char **argv)
     char *username;
     int may_coredump;
     strlist_t sl, remusr= NULL, locusr=NULL;
-    strlist_t nrings=NULL, sec_nrings=NULL;
+    strlist_t nrings = NULL;
     armor_filter_context_t *afx = NULL;
     int detached_sig = 0;
     FILE *configfp = NULL;
@@ -1922,7 +2020,9 @@ main (int argc, char **argv)
     int use_random_seed = 1;
     enum cmd_and_opt_values cmd = 0;
     const char *debug_level = NULL;
+#ifndef NO_TRUST_MODELS
     const char *trustdb_name = NULL;
+#endif /*!NO_TRUST_MODELS*/
     char *def_cipher_string = NULL;
     char *def_digest_string = NULL;
     char *compress_algo_string = NULL;
@@ -1939,6 +2039,7 @@ main (int argc, char **argv)
     int any_explicit_recipient = 0;
     int require_secmem=0,got_secmem=0;
     struct assuan_malloc_hooks malloc_hooks;
+    ctrl_t ctrl;
 
 #ifdef __riscos__
     opt.lock_once = 1;
@@ -1948,19 +2049,16 @@ main (int argc, char **argv)
     /* 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. */
-    gnupg_reopen_std ("gpg");
+    gnupg_reopen_std (GPG_NAME);
     trap_unaligned ();
     gnupg_rl_initialize ();
     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);
-    log_set_prefix ("gpg", 1);
+    log_set_prefix (GPG_NAME, 1);
 
     /* Make sure that our subsystems are ready.  */
     i18n_init();
-    init_common_subsystems ();
+    init_common_subsystems (&argc, &argv);
 
     /* Check that the libraries are suitable.  Do it right here because the
        option parsing may need services of the library.  */
@@ -1970,6 +2068,9 @@ main (int argc, char **argv)
                     NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
       }
 
+    /* Use our own logging handler for Libcgrypt.  */
+    setup_libgcrypt_logging ();
+
     /* Put random number into secure memory */
     gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
 
@@ -1977,7 +2078,7 @@ main (int argc, char **argv)
 
     gnupg_init_signals (0, emergency_cleanup);
 
-    create_dotlock(NULL); /* Register locking cleanup. */
+    dotlock_create (NULL, 0); /* Register lock file cleanup. */
 
     opt.session_env = session_env_new ();
     if (!opt.session_env)
@@ -1994,41 +2095,45 @@ main (int argc, char **argv)
     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
     opt.s2k_mode = 3; /* iterated+salted */
     opt.s2k_count = 0; /* Auto-calibrate when needed.  */
-    opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
+    opt.s2k_cipher_algo = DEFAULT_CIPHER_ALGO;
     opt.completes_needed = 1;
     opt.marginals_needed = 3;
     opt.max_cert_depth = 5;
     opt.pgp2_workarounds = 1;
     opt.escape_from = 1;
     opt.flags.require_cross_cert = 1;
-    opt.import_options=IMPORT_SK2PK;
-    opt.export_options=EXPORT_ATTRIBUTES;
-    opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
-    opt.keyserver_options.export_options=EXPORT_ATTRIBUTES;
-    opt.keyserver_options.options=
-      KEYSERVER_HONOR_KEYSERVER_URL|KEYSERVER_HONOR_PKA_RECORD;
-    opt.verify_options=
-      VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
-    opt.trust_model=TM_AUTO;
-    opt.mangle_dos_filenames=0;
-    opt.min_cert_level=2;
-    set_screen_dimensions();
-    opt.keyid_format=KF_SHORT;
-    opt.def_sig_expire="0";
-    opt.def_cert_expire="0";
-    set_homedir ( default_homedir () );
-    opt.passphrase_repeat=1;
-    opt.emit_version = 0;
-
-    opt.list_options   |= LIST_SHOW_UID_VALIDITY;
-    opt.verify_options |= LIST_SHOW_UID_VALIDITY;
+    opt.import_options = 0;
+    opt.export_options = EXPORT_ATTRIBUTES;
+    opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG;
+    opt.keyserver_options.export_options = EXPORT_ATTRIBUTES;
+    opt.keyserver_options.options = (KEYSERVER_HONOR_KEYSERVER_URL
+                                     | KEYSERVER_HONOR_PKA_RECORD );
+    opt.verify_options = (LIST_SHOW_UID_VALIDITY
+                          | VERIFY_SHOW_POLICY_URLS
+                          | VERIFY_SHOW_STD_NOTATIONS
+                          | VERIFY_SHOW_KEYSERVER_URLS);
+    opt.list_options   = LIST_SHOW_UID_VALIDITY;
+#ifdef NO_TRUST_MODELS
+    opt.trust_model = TM_ALWAYS;
+#else
+    opt.trust_model = TM_AUTO;
+#endif
+    opt.mangle_dos_filenames = 0;
+    opt.min_cert_level = 2;
+    set_screen_dimensions ();
+    opt.keyid_format = KF_SHORT;
+    opt.def_sig_expire = "0";
+    opt.def_cert_expire = "0";
+    set_homedir (default_homedir ());
+    opt.passphrase_repeat = 1;
+    opt.emit_version = 1; /* Limit to the major number.  */
 
     /* Check whether we have a config file on the command line.  */
     orig_argc = argc;
     orig_argv = argv;
     pargs.argc = &argc;
     pargs.argv = &argv;
-    pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
+    pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
     while( arg_parse( &pargs, opts) ) {
        if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
            parse_debug++;
@@ -2093,7 +2198,7 @@ main (int argc, char **argv)
     malloc_hooks.free = gcry_free;
     assuan_set_malloc_hooks (&malloc_hooks);
     assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
-
+    setup_libassuan_logging (&opt.debug);
 
     /* Try for a version specific config file first */
     default_configname = get_default_configname ();
@@ -2104,7 +2209,7 @@ main (int argc, char **argv)
     argv = orig_argv;
     pargs.argc = &argc;
     pargs.argv = &argv;
-    pargs.flags=  1;  /* do not remove the args */
+    pargs.flags= ARGPARSE_FLAG_KEEP;
 
     /* By this point we have a homedir, and cannot change it. */
     check_permissions(opt.homedir,0);
@@ -2128,23 +2233,23 @@ main (int argc, char **argv)
           {
             fclose (configfp);
             configfp = NULL;
-            errno = EPERM;
+            gpg_err_set_errno (EPERM);
           }
        if( !configfp ) {
            if( default_config ) {
                if( parse_debug )
-                   log_info(_("NOTE: no default option file `%s'\n"),
+                   log_info(_("Note: no default option file '%s'\n"),
                                                            configname );
            }
            else {
-               log_error(_("option file `%s': %s\n"),
+               log_error(_("option file '%s': %s\n"),
                                    configname, strerror(errno) );
                g10_exit(2);
            }
            xfree(configname); configname = NULL;
        }
        if( parse_debug && configname )
-           log_info(_("reading options from `%s'\n"), configname );
+           log_info(_("reading options from '%s'\n"), configname );
        default_config = 0;
     }
 
@@ -2155,7 +2260,6 @@ main (int argc, char **argv)
          {
          case aCheckKeys:
          case aListConfig:
-         case aListGcryptConfig:
           case aGPGConfList:
           case aGPGConfTest:
          case aListPackets:
@@ -2193,9 +2297,12 @@ main (int argc, char **argv)
          case aDeArmor:
          case aEnArmor:
          case aSign:
+         case aQuickSignKey:
+         case aQuickLSignKey:
          case aSignKey:
          case aLSignKey:
          case aStore:
+         case aQuickKeygen:
          case aExportOwnerTrust:
          case aImportOwnerTrust:
           case aRebuildKeydbCaches:
@@ -2203,6 +2310,7 @@ main (int argc, char **argv)
             break;
 
          case aKeygen:
+         case aFullKeygen:
          case aEditKey:
          case aDeleteSecretKeys:
          case aDeleteSecretAndPublicKeys:
@@ -2249,13 +2357,13 @@ main (int argc, char **argv)
 
           case oUseAgent: /* Dummy. */
             break;
+
           case oNoUseAgent:
-           obsolete_option (configname, configlineno, "--no-use-agent");
+           obsolete_option (configname, configlineno, "no-use-agent");
             break;
          case oGpgAgentInfo:
-           obsolete_option (configname, configlineno, "--gpg-agent-info");
+           obsolete_option (configname, configlineno, "gpg-agent-info");
             break;
-
           case oReaderPort:
            obsolete_scdaemon_option (configname, configlineno, "reader-port");
             break;
@@ -2273,8 +2381,8 @@ main (int argc, char **argv)
          case oAnswerNo: opt.answer_no = 1; break;
          case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
          case oPrimaryKeyring:
-           sl=append_to_strlist( &nrings, pargs.r.ret_str);
-           sl->flags=2;
+           sl = append_to_strlist (&nrings, pargs.r.ret_str);
+           sl->flags = KEYDB_RESOURCE_FLAG_PRIMARY;
            break;
          case oShowKeyring:
            deprecated_warning(configname,configlineno,"--show-keyring",
@@ -2314,9 +2422,18 @@ main (int argc, char **argv)
             fpr_maybe_cmd = 1;
             break;
 
+         case oWithKeygrip:
+            opt.with_keygrip = 1;
+            break;
+
+         case oWithSecret:
+            opt.with_secret = 1;
+            break;
+
          case oSecretKeyring:
-            append_to_strlist( &sec_nrings, pargs.r.ret_str);
+            /* Ignore this old option.  */
             break;
+
          case oOptions:
            /* config files may not be nested (silently ignore them) */
            if( !configfp ) {
@@ -2341,7 +2458,11 @@ main (int argc, char **argv)
          case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
          case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
          case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
+
+#ifndef NO_TRUST_MODELS
          case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
+
+#endif /*!NO_TRUST_MODELS*/
          case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
          case oDefRecipient:
             if( *pargs.r.ret_str )
@@ -2367,13 +2488,12 @@ main (int argc, char **argv)
 
          case oSkipVerify: opt.skip_verify=1; break;
 
-         case oSkipHiddenRecipients:
-         case oNoSkipHiddenRecipients:
-            /* Dummies for options to be used in 2.1.  */
-            break;
+         case oSkipHiddenRecipients: opt.skip_hidden_recipients = 1; break;
+         case oNoSkipHiddenRecipients: opt.skip_hidden_recipients = 0; break;
 
-         case oCompressKeys: opt.compress_keys = 1; break;
          case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
+
+#ifndef NO_TRUST_MODELS
            /* There are many programs (like mutt) that call gpg with
               --always-trust so keep this option around for a long
               time. */
@@ -2381,13 +2501,15 @@ main (int argc, char **argv)
          case oTrustModel:
            parse_trust_model(pargs.r.ret_str);
            break;
+#endif /*!NO_TRUST_MODELS*/
+
          case oForceOwnertrust:
-           log_info(_("NOTE: %s is not for normal use!\n"),
+           log_info(_("Note: %s is not for normal use!\n"),
                     "--force-ownertrust");
            opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
            if(opt.force_ownertrust==-1)
              {
-               log_error("invalid ownertrust `%s'\n",pargs.r.ret_str);
+               log_error("invalid ownertrust '%s'\n",pargs.r.ret_str);
                opt.force_ownertrust=0;
              }
            break;
@@ -2395,11 +2517,6 @@ main (int argc, char **argv)
             /* Dummy so that gpg 1.4 conf files can work. Should
                eventually be removed.  */
            break;
-         case oRFC1991:
-           opt.compliance = CO_RFC1991;
-           opt.force_v4_certs = 0;
-           opt.escape_from = 1;
-           break;
          case oOpenPGP:
          case oRFC4880:
            /* This is effectively the same as RFC2440, but with
@@ -2413,9 +2530,6 @@ main (int argc, char **argv)
            opt.allow_freeform_uid = 1;
            opt.pgp2_workarounds = 0;
            opt.escape_from = 1;
-           opt.force_v3_sigs = 0;
-           opt.compress_keys = 0;          /* not mandated, but we do it */
-           opt.compress_sigs = 0;          /* ditto. */
            opt.not_dash_escaped = 0;
            opt.def_cipher_algo = 0;
            opt.def_digest_algo = 0;
@@ -2433,9 +2547,6 @@ main (int argc, char **argv)
            opt.allow_freeform_uid = 1;
            opt.pgp2_workarounds = 0;
            opt.escape_from = 0;
-           opt.force_v3_sigs = 0;
-           opt.compress_keys = 0;          /* not mandated, but we do it */
-           opt.compress_sigs = 0;          /* ditto. */
            opt.not_dash_escaped = 0;
            opt.def_cipher_algo = 0;
            opt.def_digest_algo = 0;
@@ -2445,12 +2556,10 @@ main (int argc, char **argv)
            opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
            opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
            break;
-         case oPGP2:  opt.compliance = CO_PGP2;  break;
          case oPGP6:  opt.compliance = CO_PGP6;  break;
          case oPGP7:  opt.compliance = CO_PGP7;  break;
          case oPGP8:  opt.compliance = CO_PGP8;  break;
          case oGnuPG: opt.compliance = CO_GNUPG; break;
-         case oCompressSigs: opt.compress_sigs = 1; break;
          case oRFC2440Text: opt.rfc2440_text=1; break;
          case oNoRFC2440Text: opt.rfc2440_text=0; break;
          case oSetFilename:
@@ -2521,10 +2630,7 @@ main (int argc, char **argv)
            opt.verify_options&=~VERIFY_SHOW_PHOTOS;
            break;
          case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
-         case oForceV3Sigs: opt.force_v3_sigs = 1; break;
-         case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
-          case oForceV4Certs: opt.force_v4_certs = 1; break;
-          case oNoForceV4Certs: opt.force_v4_certs = 0; break;
+
          case oForceMDC: opt.force_mdc = 1; break;
          case oNoForceMDC: opt.force_mdc = 0; break;
          case oDisableMDC: opt.disable_mdc = 1; break;
@@ -2538,7 +2644,6 @@ main (int argc, char **argv)
             else
               opt.s2k_count = 0;  /* Auto-calibrate when needed.  */
            break;
-          case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
          case oNoEncryptTo: opt.no_encrypt_to = 1; break;
          case oEncryptTo: /* store the recipient in the second list */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
@@ -2557,6 +2662,12 @@ main (int argc, char **argv)
            sl->flags = 2;
             any_explicit_recipient = 1;
            break;
+
+         case oTrySecretKey:
+           add_to_strlist2 (&opt.secret_keys_to_try,
+                             pargs.r.ret_str, utf8_strings);
+           break;
+
          case oTextmodeShort: opt.textmode = 2; break;
          case oTextmode: opt.textmode=1;  break;
          case oNoTextmode: opt.textmode=0;  break;
@@ -2566,7 +2677,7 @@ main (int argc, char **argv)
            if(*pargs.r.ret_str!='\0')
              {
                if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
-                 log_error(_("`%s' is not a valid signature expiration\n"),
+                 log_error(_("'%s' is not a valid signature expiration\n"),
                            pargs.r.ret_str);
                else
                  opt.def_sig_expire=pargs.r.ret_str;
@@ -2578,7 +2689,7 @@ main (int argc, char **argv)
            if(*pargs.r.ret_str!='\0')
              {
                if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
-                 log_error(_("`%s' is not a valid signature expiration\n"),
+                 log_error(_("'%s' is not a valid signature expiration\n"),
                            pargs.r.ret_str);
                else
                  opt.def_cert_expire=pargs.r.ret_str;
@@ -2609,7 +2720,16 @@ main (int argc, char **argv)
          case oPassphraseFile:
             pwfd = open_info_file (pargs.r.ret_str, 0, 1);
             break;
-         case oPassphraseRepeat: opt.passphrase_repeat=pargs.r.ret_int; break;
+         case oPassphraseRepeat:
+            opt.passphrase_repeat = pargs.r.ret_int;
+            break;
+
+          case oPinentryMode:
+           opt.pinentry_mode = parse_pinentry_mode (pargs.r.ret_str);
+           if (opt.pinentry_mode == -1)
+              log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str);
+           break;
+
          case oCommandFD:
             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
             break;
@@ -2660,7 +2780,7 @@ main (int argc, char **argv)
          case oNoMDCWarn: opt.no_mdc_warn=1; break;
           case oDisplayCharset:
            if( set_native_charset( pargs.r.ret_str ) )
-               log_error(_("`%s' is not a valid character set\n"),
+               log_error(_("'%s' is not a valid character set\n"),
                          pargs.r.ret_str);
            break;
          case oNotDashEscaped: opt.not_dash_escaped = 1; break;
@@ -2668,7 +2788,7 @@ main (int argc, char **argv)
          case oNoEscapeFrom: opt.escape_from = 0; break;
          case oLockOnce: opt.lock_once = 1; break;
          case oLockNever:
-            disable_dotlock ();
+            dotlock_disable ();
             break;
          case oLockMultiple:
 #ifndef __riscos__
@@ -2679,15 +2799,15 @@ main (int argc, char **argv)
             break;
          case oKeyServer:
            {
-             struct keyserver_spec *keyserver;
-             keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
-                                           configname,configlineno);
-             if(!keyserver)
-               log_error(_("could not parse keyserver URL\n"));
+             keyserver_spec_t keyserver;
+             keyserver = parse_keyserver_uri (pargs.r.ret_str,0,
+                                               configname,configlineno);
+             if (!keyserver)
+               log_error (_("could not parse keyserver URL\n"));
              else
                {
-                 keyserver->next=opt.keyserver;
-                 opt.keyserver=keyserver;
+                 keyserver->next = opt.keyserver;
+                 opt.keyserver = keyserver;
                }
            }
            break;
@@ -2816,6 +2936,7 @@ main (int argc, char **argv)
             }
             break;
           case oNoSigCache: opt.no_sig_cache = 1; break;
+          case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
          case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
          case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
          case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
@@ -2830,6 +2951,7 @@ main (int argc, char **argv)
                break;
          case oFastListMode: opt.fast_list_mode = 1; break;
          case oFixedListMode: /* Dummy */ break;
+          case oLegacyListMode: opt.legacy_list_mode = 1; break;
          case oListOnly: opt.list_only=1; break;
          case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
          case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
@@ -2873,13 +2995,13 @@ main (int argc, char **argv)
            break;
          case oDefaultKeyserverURL:
            {
-             struct keyserver_spec *keyserver;
-             keyserver=parse_keyserver_uri(pargs.r.ret_str,1,
-                                           configname,configlineno);
-             if(!keyserver)
-               log_error(_("could not parse keyserver URL\n"));
+             keyserver_spec_t keyserver;
+             keyserver = parse_keyserver_uri (pargs.r.ret_str,1,
+                                               configname,configlineno);
+             if (!keyserver)
+               log_error (_("could not parse keyserver URL\n"));
              else
-               free_keyserver_spec(keyserver);
+               free_keyserver_spec (keyserver);
 
              opt.def_keyserver_url = pargs.r.ret_str;
            }
@@ -2894,6 +3016,7 @@ main (int argc, char **argv)
            pers_compress_list=pargs.r.ret_str;
            break;
           case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
+          case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
 
           case oDisplay:
             set_opt_session_env ("DISPLAY", pargs.r.ret_str);
@@ -2942,7 +3065,7 @@ main (int argc, char **argv)
            else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
              opt.keyid_format=KF_0xLONG;
            else
-             log_error("unknown keyid-format `%s'\n",pargs.r.ret_str);
+             log_error("unknown keyid-format '%s'\n",pargs.r.ret_str);
            break;
 
           case oExitOnStatusWriteError:
@@ -3002,6 +3125,15 @@ main (int argc, char **argv)
             opt.flags.allow_weak_digest_algos = 1;
             break;
 
+          case oFakedSystemTime:
+            {
+              time_t faked_time = isotime2epoch (pargs.r.ret_str);
+              if (faked_time == (time_t)(-1))
+                faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
+              gnupg_set_time (faked_time, 0);
+            }
+            break;
+
          case oNoop: break;
 
          default:
@@ -3010,8 +3142,8 @@ main (int argc, char **argv)
          }
       }
 
-
-    if( configfp ) {
+    if (configfp)
+      {
        fclose( configfp );
        configfp = NULL;
         /* Remember the first config file name. */
@@ -3021,10 +3153,10 @@ main (int argc, char **argv)
           xfree(configname);
         configname = NULL;
        goto next_pass;
-    }
-    xfree( configname ); configname = NULL;
-    if( log_get_errorcount(0) )
-       g10_exit(2);
+      }
+    xfree(configname); configname = NULL;
+    if (log_get_errorcount (0))
+      g10_exit(2);
 
     /* The command --gpgconf-list is pretty simple and may be called
        directly after the option parsing. */
@@ -3039,11 +3171,12 @@ main (int argc, char **argv)
     if( nogreeting )
        greeting = 0;
 
-    if( greeting ) {
-       fprintf(stderr, "%s %s; %s\n",
-                       strusage(11), strusage(13), strusage(14) );
-       fprintf(stderr, "%s\n", strusage(15) );
-    }
+    if( greeting )
+      {
+       es_fprintf (es_stderr, "%s %s; %s\n",
+                    strusage(11), strusage(13), strusage(14) );
+       es_fprintf (es_stderr, "%s\n", strusage(15) );
+      }
 #ifdef IS_DEVELOPMENT_VERSION
     if (!opt.batch)
       {
@@ -3068,17 +3201,8 @@ main (int argc, char **argv)
         log_set_prefix (NULL, 1|2|4);
       }
 
-    /* Older Libgcrypts fail with an assertion during DSA key
-       generation.  Better disable DSA2 entirely. */
-    if (opt.flags.dsa2 && !gcry_check_version ("1.4.0") )
-      {
-        log_info ("WARNING: "
-                  "DSA2 is only available with Libgcrypt 1.4 and later\n");
-        opt.flags.dsa2 = 0;
-      }
-
     if (opt.verbose > 2)
-        log_info ("using character set `%s'\n", get_native_charset ());
+        log_info ("using character set '%s'\n", get_native_charset ());
 
     if( may_coredump && !opt.quiet )
        log_info(_("WARNING: program may create a core file!\n"));
@@ -3092,7 +3216,7 @@ main (int argc, char **argv)
     }
 
     if (opt.no_literal) {
-       log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
+       log_info(_("Note: %s is not for normal use!\n"), "--no-literal");
        if (opt.textmode)
            log_error(_("%s not allowed with %s!\n"),
                       "--textmode", "--no-literal" );
@@ -3104,10 +3228,31 @@ main (int argc, char **argv)
 
 
     if (opt.set_filesize)
-       log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
+       log_info(_("Note: %s is not for normal use!\n"), "--set-filesize");
     if( opt.batch )
        tty_batchmode( 1 );
 
+    if (gnupg_faked_time_p ())
+      {
+        gnupg_isotime_t tbuf;
+
+        log_info (_("WARNING: running with faked system time: "));
+        gnupg_get_isotime (tbuf);
+        dump_isotime (tbuf);
+        log_printf ("\n");
+      }
+
+    /* Print a warning if an argument looks like an option.  */
+    if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+      {
+        int i;
+
+        for (i=0; i < argc; i++)
+          if (argv[i][0] == '-' && argv[i][1] == '-')
+            log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
+      }
+
+
     gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
 
     if(require_secmem && !got_secmem)
@@ -3118,91 +3263,23 @@ main (int argc, char **argv)
       }
 
     set_debug (debug_level);
+    if (DBG_CLOCK)
+      log_clock ("start");
 
     /* Do these after the switch(), so they can override settings. */
-    if(PGP2)
-      {
-       int unusable=0;
-
-       if(cmd==aSign && !detached_sig)
-         {
-           log_info(_("you can only make detached or clear signatures "
-                      "while in --pgp2 mode\n"));
-           unusable=1;
-         }
-       else if(cmd==aSignEncr || cmd==aSignSym)
-         {
-           log_info(_("you can't sign and encrypt at the "
-                      "same time while in --pgp2 mode\n"));
-           unusable=1;
-         }
-       else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
-         {
-           log_info(_("you must use files (and not a pipe) when "
-                      "working with --pgp2 enabled.\n"));
-           unusable=1;
-         }
-       else if(cmd==aEncr || cmd==aSym)
-         {
-           /* Everything else should work without IDEA (except using
-              a secret key encrypted with IDEA and setting an IDEA
-              preference, but those have their own error
-              messages). */
-
-           if (openpgp_cipher_test_algo(CIPHER_ALGO_IDEA))
-             {
-               log_info(_("encrypting a message in --pgp2 mode requires "
-                          "the IDEA cipher\n"));
-               idea_cipher_warn(1);
-               unusable=1;
-             }
-           else if(cmd==aSym)
-             {
-               /* This only sets IDEA for symmetric encryption
-                  since it is set via select_algo_from_prefs for
-                  pk encryption. */
-               xfree(def_cipher_string);
-               def_cipher_string = xstrdup("idea");
-             }
-
-           /* PGP2 can't handle the output from the textmode
-              filter, so we disable it for anything that could
-              create a literal packet (only encryption and
-              symmetric encryption, since we disable signing
-              above). */
-           if(!unusable)
-             opt.textmode=0;
-         }
-
-       if(unusable)
-         compliance_failure();
-       else
-         {
-           opt.force_v4_certs = 0;
-           opt.escape_from = 1;
-           opt.force_v3_sigs = 1;
-           opt.pgp2_workarounds = 1;
-           opt.ask_sig_expire = 0;
-           opt.ask_cert_expire = 0;
-            opt.flags.allow_weak_digest_algos = 1;
-           xfree(def_digest_string);
-           def_digest_string = xstrdup("md5");
-           xfree(s2k_digest_string);
-           s2k_digest_string = xstrdup("md5");
-           opt.compress_algo = COMPRESS_ALGO_ZIP;
-         }
-      }
-    else if(PGP6)
+    if(PGP6)
       {
+        /* That does not anymore work becuase we have no more support
+           for v3 signatures.  */
        opt.disable_mdc=1;
        opt.escape_from=1;
-       opt.force_v3_sigs=1;
        opt.ask_sig_expire=0;
       }
     else if(PGP7)
       {
+        /* That does not anymore work because we have no more support
+           for v3 signatures.  */
        opt.escape_from=1;
-       opt.force_v3_sigs=1;
        opt.ask_sig_expire=0;
       }
     else if(PGP8)
@@ -3213,10 +3290,6 @@ main (int argc, char **argv)
 
     if( def_cipher_string ) {
        opt.def_cipher_algo = string_to_cipher_algo (def_cipher_string);
-       if(opt.def_cipher_algo==0 &&
-          (ascii_strcasecmp(def_cipher_string,"idea")==0
-           || ascii_strcasecmp(def_cipher_string,"s1")==0))
-         idea_cipher_warn(1);
        xfree(def_cipher_string); def_cipher_string = NULL;
        if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
            log_error(_("selected cipher algorithm is invalid\n"));
@@ -3263,7 +3336,7 @@ main (int argc, char **argv)
       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
     switch( opt.s2k_mode ) {
       case 0:
-       log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
+       log_info(_("Note: simple S2K mode (0) is strongly discouraged\n"));
        break;
       case 1: case 3: break;
       default:
@@ -3366,17 +3439,17 @@ main (int argc, char **argv)
            switch(badtype)
              {
              case PREFTYPE_SYM:
-               log_info(_("you may not use cipher algorithm `%s'"
+               log_info(_("you may not use cipher algorithm '%s'"
                           " while in %s mode\n"),
                         badalg,compliance_option_string());
                break;
              case PREFTYPE_HASH:
-               log_info(_("you may not use digest algorithm `%s'"
+               log_info(_("you may not use digest algorithm '%s'"
                           " while in %s mode\n"),
                         badalg,compliance_option_string());
                break;
              case PREFTYPE_ZIP:
-               log_info(_("you may not use compression algorithm `%s'"
+               log_info(_("you may not use compression algorithm '%s'"
                           " while in %s mode\n"),
                         badalg,compliance_option_string());
                break;
@@ -3408,33 +3481,20 @@ main (int argc, char **argv)
     if( opt.verbose > 1 )
        set_packet_list_mode(1);
 
-    /* Add the keyrings, but not for some special commands.  Also
-       avoid adding the secret keyring for a couple of commands to
-       avoid unneeded access in case the secrings are stored on a
-       floppy.
-
+    /* Add the keyrings, but not for some special commands.
        We always need to add the keyrings if we are running under
        SELinux, this is so that the rings are added to the list of
        secured files. */
     if( ALWAYS_ADD_KEYRINGS
         || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) )
       {
-        if (ALWAYS_ADD_KEYRINGS
-            || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
-                && cmd != aVerify && cmd != aSym && cmd != aLocateKeys))
-          {
-            if (!sec_nrings || default_keyring) /* add default secret rings */
-              keydb_add_resource ("secring" EXTSEP_S "gpg", 4, 1);
-            for (sl = sec_nrings; sl; sl = sl->next)
-              keydb_add_resource ( sl->d, 0, 1 );
-          }
-       if( !nrings || default_keyring )  /* add default ring */
-           keydb_add_resource ("pubring" EXTSEP_S "gpg", 4, 0);
-       for(sl = nrings; sl; sl = sl->next )
-           keydb_add_resource ( sl->d, sl->flags, 0 );
+       if (!nrings || default_keyring)  /* Add default ring. */
+           keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG,
+                                KEYDB_RESOURCE_FLAG_DEFAULT);
+       for (sl = nrings; sl; sl = sl->next )
+          keydb_add_resource (sl->d, sl->flags);
       }
     FREE_STRLIST(nrings);
-    FREE_STRLIST(sec_nrings);
 
     if (cmd == aGPGConfTest)
       g10_exit(0);
@@ -3448,6 +3508,10 @@ main (int argc, char **argv)
     if(fname && utf8_strings)
       opt.flags.utf8_filename=1;
 
+    ctrl = xcalloc (1, sizeof *ctrl);
+    gpg_init_default_ctrl (ctrl);
+
+#ifndef NO_TRUST_MODELS
     switch (cmd)
       {
       case aPrimegen:
@@ -3472,7 +3536,7 @@ main (int argc, char **argv)
       }
     if (rc)
       log_error (_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
-
+#endif /*!NO_TRUST_MODELS*/
 
     switch (cmd)
       {
@@ -3489,52 +3553,76 @@ main (int argc, char **argv)
         break;
       }
 
+
+    /* Check for certain command whether we need to migrate a
+       secring.gpg to the gpg-agent. */
+    switch (cmd)
+      {
+      case aListSecretKeys:
+      case aSign:
+      case aSignEncr:
+      case aSignEncrSym:
+      case aSignSym:
+      case aClearsign:
+      case aDecrypt:
+      case aSignKey:
+      case aLSignKey:
+      case aEditKey:
+      case aPasswd:
+      case aDeleteSecretKeys:
+      case aDeleteSecretAndPublicKeys:
+      case aQuickKeygen:
+      case aFullKeygen:
+      case aKeygen:
+      case aImport:
+      case aExportSecret:
+      case aExportSecretSub:
+      case aGenRevoke:
+      case aDesigRevoke:
+      case aCardEdit:
+      case aChangePIN:
+        migrate_secring (ctrl);
+       break;
+      case aListKeys:
+        if (opt.with_secret)
+          migrate_secring (ctrl);
+        break;
+      default:
+        break;
+      }
+
+    /* The command dispatcher.  */
     switch( cmd )
       {
       case aServer:
-        {
-          ctrl_t ctrl = xtrycalloc (1, sizeof *ctrl);
-          gpg_init_default_ctrl (ctrl);
-          gpg_server (ctrl);
-          gpg_deinit_default_ctrl (ctrl);
-          xfree (ctrl);
-        }
+        gpg_server (ctrl);
         break;
 
       case aStore: /* only store the file */
        if( argc > 1 )
            wrong_args(_("--store [filename]"));
-       if( (rc = encode_store(fname)) )
-          {
-            write_status_failure ("store", rc);
-           log_error ("storing `%s' failed: %s\n",
+       if( (rc = encrypt_store(fname)) )
+           log_error ("storing '%s' failed: %s\n",
                        print_fname_stdin(fname),g10_errstr(rc) );
-          }
        break;
       case aSym: /* encrypt the given file only with the symmetric cipher */
        if( argc > 1 )
            wrong_args(_("--symmetric [filename]"));
-       if( (rc = encode_symmetric(fname)) )
-          {
-            write_status_failure ("symencrypt", rc);
-            log_error (_("symmetric encryption of `%s' failed: %s\n"),
+       if( (rc = encrypt_symmetric(fname)) )
+            log_error (_("symmetric encryption of '%s' failed: %s\n"),
                         print_fname_stdin(fname),g10_errstr(rc) );
-          }
        break;
 
       case aEncr: /* encrypt the given file */
        if(multifile)
-         encode_crypt_files(argc, argv, remusr);
+         encrypt_crypt_files (ctrl, argc, argv, remusr);
        else
          {
            if( argc > 1 )
              wrong_args(_("--encrypt [filename]"));
-           if( (rc = encode_crypt(fname,remusr,0)) )
-              {
-                write_status_failure ("encrypt", rc);
-                log_error("%s: encryption failed: %s\n",
-                          print_fname_stdin(fname), g10_errstr(rc) );
-              }
+           if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 0, NULL, -1)) )
+             log_error("%s: encryption failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
          }
        break;
 
@@ -3548,17 +3636,14 @@ main (int argc, char **argv)
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --encrypt"
                      " with --s2k-mode 0\n"));
-       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+       else if(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --encrypt"
                      " while in %s mode\n"),compliance_option_string());
        else
          {
-           if( (rc = encode_crypt(fname,remusr,1)) )
-              {
-                write_status_failure ("encrypt", rc);
-                log_error("%s: encryption failed: %s\n",
-                          print_fname_stdin(fname), g10_errstr(rc) );
-              }
+           if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) )
+             log_error("%s: encryption failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
          }
        break;
 
@@ -3576,11 +3661,8 @@ main (int argc, char **argv)
                strcpy(sl->d, fname);
            }
        }
-       if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
-          {
-            write_status_failure ("sign", rc);
+       if( (rc = sign_file (ctrl, sl, detached_sig, locusr, 0, NULL, NULL)) )
            log_error("signing failed: %s\n", g10_errstr(rc) );
-          }
        free_strlist(sl);
        break;
 
@@ -3593,12 +3675,9 @@ main (int argc, char **argv)
        }
        else
            sl = NULL;
-       if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
-          {
-            write_status_failure ("sign-encrypt", rc);
+       if ((rc = sign_file (ctrl, sl, detached_sig, locusr, 1, remusr, NULL)))
            log_error("%s: sign+encrypt failed: %s\n",
                      print_fname_stdin(fname), g10_errstr(rc) );
-          }
        free_strlist(sl);
        break;
 
@@ -3608,7 +3687,7 @@ main (int argc, char **argv)
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --sign --encrypt"
                      " with --s2k-mode 0\n"));
-       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+       else if(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --sign --encrypt"
                      " while in %s mode\n"),compliance_option_string());
        else
@@ -3620,12 +3699,10 @@ main (int argc, char **argv)
              }
            else
              sl = NULL;
-           if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
-              {
-                write_status_failure ("sign-encrypt", rc);
-                log_error("%s: symmetric+sign+encrypt failed: %s\n",
-                          print_fname_stdin(fname), g10_errstr(rc) );
-              }
+           if ((rc = sign_file (ctrl, sl, detached_sig, locusr,
+                                 2, remusr, NULL)))
+             log_error("%s: symmetric+sign+encrypt failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
            free_strlist(sl);
          }
        break;
@@ -3635,54 +3712,59 @@ main (int argc, char **argv)
            wrong_args(_("--sign --symmetric [filename]"));
        rc = sign_symencrypt_file (fname, locusr);
         if (rc)
-          {
-            write_status_failure ("sign-symencrypt", rc);
            log_error("%s: sign+symmetric failed: %s\n",
                       print_fname_stdin(fname), g10_errstr(rc) );
-          }
        break;
 
       case aClearsign: /* make a clearsig */
        if( argc > 1 )
            wrong_args(_("--clearsign [filename]"));
        if( (rc = clearsign_file(fname, locusr, NULL)) )
-          {
-            write_status_failure ("sign", rc);
            log_error("%s: clearsign failed: %s\n",
                       print_fname_stdin(fname), g10_errstr(rc) );
-          }
        break;
 
       case aVerify:
-       if(multifile)
+       if (multifile)
          {
-           if( (rc = verify_files( argc, argv ) ))
+           if ((rc = verify_files (ctrl, argc, argv)))
              log_error("verify files failed: %s\n", g10_errstr(rc) );
          }
        else
          {
-           if( (rc = verify_signatures( argc, argv ) ))
+           if ((rc = verify_signatures (ctrl, argc, argv)))
              log_error("verify signatures failed: %s\n", g10_errstr(rc) );
          }
-        if (rc)
-          write_status_failure ("verify", rc);
        break;
 
       case aDecrypt:
-        if(multifile)
-         decrypt_messages(argc, argv);
+        if (multifile)
+         decrypt_messages (ctrl, argc, argv);
        else
          {
            if( argc > 1 )
              wrong_args(_("--decrypt [filename]"));
-           if( (rc = decrypt_message( fname ) ))
-              {
-                write_status_failure ("decrypt", rc);
-                log_error("decrypt_message failed: %s\n", g10_errstr(rc));
-              }
+           if( (rc = decrypt_message (ctrl, fname) ))
+             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
          }
        break;
 
+      case aQuickSignKey:
+      case aQuickLSignKey:
+        {
+          const char *fpr;
+
+          if (argc < 1)
+            wrong_args ("--quick-[l]sign-key fingerprint [userids]");
+          fpr = *argv++; argc--;
+          sl = NULL;
+          for( ; argc; argc--, argv++)
+           append_to_strlist2 (&sl, *argv, utf8_strings);
+          keyedit_quick_sign (ctrl, fpr, sl, locusr, (cmd == aQuickLSignKey));
+          free_strlist (sl);
+        }
+       break;
+
       case aSignKey:
        if( argc != 1 )
          wrong_args(_("--sign-key user-id"));
@@ -3703,7 +3785,7 @@ main (int argc, char **argv)
 
        append_to_strlist( &sl, "save" );
        username = make_username( fname );
-       keyedit_menu (username, locusr, sl, 0, 0 );
+       keyedit_menu (ctrl, username, locusr, sl, 0, 0 );
        xfree(username);
        free_strlist(sl);
        break;
@@ -3716,11 +3798,11 @@ main (int argc, char **argv)
            sl = NULL;
            for( argc--, argv++ ; argc; argc--, argv++ )
                append_to_strlist( &sl, *argv );
-           keyedit_menu( username, locusr, sl, 0, 1 );
+           keyedit_menu (ctrl, username, locusr, sl, 0, 1 );
            free_strlist(sl);
        }
        else
-           keyedit_menu(username, locusr, NULL, 0, 1 );
+            keyedit_menu (ctrl, username, locusr, NULL, 0, 1 );
        xfree(username);
        break;
 
@@ -3730,7 +3812,7 @@ main (int argc, char **argv)
         else
           {
             username = make_username (fname);
-            keyedit_passwd (username);
+            keyedit_passwd (ctrl, username);
             xfree (username);
           }
         break;
@@ -3756,41 +3838,64 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       public_key_list( sl, 0 );
+       public_key_list (ctrl, sl, 0);
        free_strlist(sl);
        break;
       case aListSecretKeys:
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       secret_key_list( sl );
+       secret_key_list (ctrl, sl);
        free_strlist(sl);
        break;
       case aLocateKeys:
        sl = NULL;
        for (; argc; argc--, argv++)
           add_to_strlist2( &sl, *argv, utf8_strings );
-       public_key_list (sl, 1);
+       public_key_list (ctrl, sl, 1);
        free_strlist (sl);
        break;
 
+      case aQuickKeygen:
+        if (argc != 1 )
+          wrong_args("--gen-key user-id");
+        username = make_username (fname);
+        quick_generate_keypair (username);
+        xfree (username);
+        break;
+
       case aKeygen: /* generate a key */
        if( opt.batch ) {
            if( argc > 1 )
                wrong_args("--gen-key [parameterfile]");
-           generate_keypair( argc? *argv : NULL, NULL, NULL );
+           generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
        }
        else {
            if( argc )
                wrong_args("--gen-key");
-           generate_keypair(NULL, NULL, NULL);
+           generate_keypair (ctrl, 0, NULL, NULL, 0);
+       }
+       break;
+
+      case aFullKeygen: /* Generate a key with all options. */
+       if (opt.batch)
+          {
+           if (argc > 1)
+              wrong_args ("--full-gen-key [parameterfile]");
+           generate_keypair (ctrl, 1, argc? *argv : NULL, NULL, 0);
+          }
+       else
+          {
+           if (argc)
+              wrong_args("--full-gen-key");
+           generate_keypair (ctrl, 1, NULL, NULL, 0);
        }
        break;
 
       case aFastImport:
         opt.import_options |= IMPORT_FAST;
       case aImport:
-       import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
+       import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options);
        break;
 
        /* TODO: There are a number of command that use this same
@@ -3805,55 +3910,40 @@ main (int argc, char **argv)
        for( ; argc; argc--, argv++ )
            append_to_strlist2( &sl, *argv, utf8_strings );
        if( cmd == aSendKeys )
-           rc=keyserver_export( sl );
+            rc = keyserver_export (ctrl, sl );
        else if( cmd == aRecvKeys )
-           rc=keyserver_import( sl );
+            rc = keyserver_import (ctrl, sl );
        else
-           rc=export_pubkeys( sl, opt.export_options );
+            rc = export_pubkeys (ctrl, sl, opt.export_options);
        if(rc)
          {
            if(cmd==aSendKeys)
-              {
-                write_status_failure ("send-keys", rc);
-                log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
-              }
+             log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
            else if(cmd==aRecvKeys)
-              {
-                write_status_failure ("recv-keys", rc);
-                log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
-              }
+             log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
            else
-              {
-                write_status_failure ("export", rc);
-                log_error(_("key export failed: %s\n"),g10_errstr(rc));
-              }
+             log_error(_("key export failed: %s\n"),g10_errstr(rc));
          }
        free_strlist(sl);
        break;
 
      case aSearchKeys:
        sl = NULL;
-       for( ; argc; argc--, argv++ )
-         append_to_strlist2( &sl, *argv, utf8_strings );
-       rc=keyserver_search( sl );
-       if(rc)
-          {
-            write_status_failure ("search-keys", rc);
-            log_error(_("keyserver search failed: %s\n"), g10_errstr(rc));
-          }
-       free_strlist(sl);
+       for (; argc; argc--, argv++)
+         append_to_strlist2 (&sl, *argv, utf8_strings);
+       rc = keyserver_search (ctrl, sl);
+       if (rc)
+         log_error (_("keyserver search failed: %s\n"), gpg_strerror (rc));
+       free_strlist (sl);
        break;
 
       case aRefreshKeys:
        sl = NULL;
        for( ; argc; argc--, argv++ )
            append_to_strlist2( &sl, *argv, utf8_strings );
-       rc=keyserver_refresh(sl);
+       rc = keyserver_refresh (ctrl, sl);
        if(rc)
-          {
-            write_status_failure ("refresh-keys", rc);
-            log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
-          }
+         log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
        free_strlist(sl);
        break;
 
@@ -3861,12 +3951,9 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            append_to_strlist2( &sl, *argv, utf8_strings );
-       rc=keyserver_fetch(sl);
+       rc = keyserver_fetch (ctrl, sl);
        if(rc)
-          {
-            write_status_failure ("fetch-keys", rc);
-            log_error("key fetch failed: %s\n",g10_errstr(rc));
-          }
+         log_error("key fetch failed: %s\n",g10_errstr(rc));
        free_strlist(sl);
        break;
 
@@ -3874,7 +3961,7 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       export_seckeys( sl );
+       export_seckeys (ctrl, sl);
        free_strlist(sl);
        break;
 
@@ -3882,7 +3969,7 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       export_secsubkeys( sl );
+       export_secsubkeys (ctrl, sl);
        free_strlist(sl);
        break;
 
@@ -3907,10 +3994,7 @@ main (int argc, char **argv)
            wrong_args("--dearmor [file]");
        rc = dearmor_file( argc? *argv: NULL );
        if( rc )
-          {
-            write_status_failure ("dearmor", rc);
            log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
-          }
        break;
 
       case aEnArmor:
@@ -3918,10 +4002,7 @@ main (int argc, char **argv)
            wrong_args("--enarmor [file]");
        rc = enarmor_file( argc? *argv: NULL );
        if( rc )
-          {
-            write_status_failure ("enarmor", rc);
            log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
-          }
        break;
 
 
@@ -3930,29 +4011,30 @@ main (int argc, char **argv)
        {   int mode = argc < 2 ? 0 : atoi(*argv);
 
            if( mode == 1 && argc == 2 ) {
-               mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
+               mpi_print (es_stdout,
+                           generate_public_prime( atoi(argv[1]) ), 1);
            }
            else if( mode == 2 && argc == 3 ) {
-               mpi_printstdout, generate_elg_prime(
+               mpi_print (es_stdout, generate_elg_prime(
                                             0, atoi(argv[1]),
                                             atoi(argv[2]), NULL,NULL ), 1);
            }
            else if( mode == 3 && argc == 3 ) {
                MPI *factors;
-               mpi_printstdout, generate_elg_prime(
+               mpi_print (es_stdout, generate_elg_prime(
                                             1, atoi(argv[1]),
                                             atoi(argv[2]), NULL,&factors ), 1);
                putchar('\n');
-               mpi_printstdout, factors[0], 1 ); /* print q */
+               mpi_print (es_stdout, factors[0], 1 ); /* print q */
            }
            else if( mode == 4 && argc == 3 ) {
                MPI g = mpi_alloc(1);
-               mpi_printstdout, generate_elg_prime(
+               mpi_print (es_stdout, generate_elg_prime(
                                                 0, atoi(argv[1]),
                                                 atoi(argv[2]), g, NULL ), 1);
                putchar('\n');
-               mpi_printstdout, g, 1 );
-               mpi_free(g);
+               mpi_print (es_stdout, g, 1 );
+               mpi_free (g);
            }
            else
                wrong_args("--gen-prime mode bits [qbits] ");
@@ -4011,7 +4093,7 @@ main (int argc, char **argv)
            int algo = all_algos? 0 : gcry_md_map_name (*argv);
 
            if( !algo && !all_algos )
-               log_error(_("invalid hash algorithm `%s'\n"), *argv );
+               log_error(_("invalid hash algorithm '%s'\n"), *argv );
            else {
                argc--; argv++;
                if( !argc )
@@ -4033,6 +4115,7 @@ main (int argc, char **argv)
        }
        break;
 
+#ifndef NO_TRUST_MODELS
       case aListTrustDB:
        if( !argc )
            list_trustdb(NULL);
@@ -4078,6 +4161,7 @@ main (int argc, char **argv)
            wrong_args("--import-ownertrust [file]");
        import_ownertrust( argc? *argv:NULL );
        break;
+#endif /*!NO_TRUST_MODELS*/
 
       case aRebuildKeydbCaches:
         if (argc)
@@ -4089,7 +4173,7 @@ main (int argc, char **argv)
       case aCardStatus:
         if (argc)
             wrong_args ("--card-status");
-        card_status (stdout, NULL, 0);
+        card_status (es_stdout, NULL, 0);
         break;
 
       case aCardEdit:
@@ -4097,11 +4181,11 @@ main (int argc, char **argv)
             sl = NULL;
             for (argc--, argv++ ; argc; argc--, argv++)
                 append_to_strlist (&sl, *argv);
-            card_edit (sl);
+            card_edit (ctrl, sl);
             free_strlist (sl);
        }
         else
-            card_edit (NULL);
+          card_edit (ctrl, NULL);
         break;
 
       case aChangePIN:
@@ -4110,7 +4194,7 @@ main (int argc, char **argv)
         else if (argc == 1)
             change_pin (atoi (*argv),1);
         else
-          wrong_args ("--change-pin [no]");
+        wrong_args ("--change-pin [no]");
         break;
 #endif /* ENABLE_CARD_SUPPORT*/
 
@@ -4122,20 +4206,16 @@ main (int argc, char **argv)
        }
        break;
 
-      case aListGcryptConfig:
-        /* Fixme: It would be nice to integrate that with
-           --list-config but unfortunately there is no way yet to have
-           libgcrypt print it to an estream for further parsing.  */
-        gcry_control (GCRYCTL_PRINT_CONFIG, stdout);
-        break;
-
       case aListPackets:
+       opt.list_packets=2;
       default:
        if( argc > 1 )
            wrong_args(_("[filename]"));
        /* Issue some output for the unix newbie */
-       if( !fname && !opt.outfile && isatty( fileno(stdin) )
-               && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
+       if (!fname && !opt.outfile
+            && gnupg_isatty (fileno (stdin))
+            && gnupg_isatty (fileno (stdout))
+            && gnupg_isatty (fileno (stderr)))
            log_info(_("Go ahead and type your message ...\n"));
 
        a = iobuf_open(fname);
@@ -4143,10 +4223,10 @@ main (int argc, char **argv)
           {
             iobuf_close (a);
             a = NULL;
-            errno = EPERM;
+            gpg_err_set_errno (EPERM);
           }
        if( !a )
-           log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
+           log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
        else {
 
            if( !opt.no_armor ) {
@@ -4156,21 +4236,20 @@ main (int argc, char **argv)
                }
            }
            if( cmd == aListPackets ) {
-               opt.list_packets=1;
                set_packet_list_mode(1);
+               opt.list_packets=1;
            }
-           rc = proc_packets(NULL, a );
+           rc = proc_packets (ctrl, NULL, a );
            if( rc )
-              {
-                write_status_failure ("-", rc);
                log_error("processing message failed: %s\n", g10_errstr(rc) );
-              }
            iobuf_close(a);
        }
        break;
       }
 
     /* cleanup */
+    gpg_deinit_default_ctrl (ctrl);
+    xfree (ctrl);
     release_armor_context (afx);
     FREE_STRLIST(remusr);
     FREE_STRLIST(locusr);
@@ -4191,6 +4270,8 @@ void
 g10_exit( int rc )
 {
   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
+  if (DBG_CLOCK)
+    log_clock ("stop");
   if ( (opt.debug & DBG_MEMSTAT_VALUE) )
     {
       gcry_control (GCRYCTL_DUMP_MEMORY_STATS);
@@ -4210,33 +4291,33 @@ g10_exit( int rc )
    display, but there are a few other similar assumptions in the
    display code. */
 static void
-print_hex( gcry_md_hd_t md, int algo, const char *fname )
+print_hex (gcry_md_hd_t md, int algo, const char *fname)
 {
   int i,n,count,indent=0;
   const byte *p;
 
-  if(fname)
-    indent=printf("%s: ",fname);
+  if (fname)
+    indent = es_printf("%s: ",fname);
 
-  if(indent>40)
+  if (indent>40)
     {
       printf("\n");
       indent=0;
     }
 
-  if(algo==DIGEST_ALGO_RMD160)
-    indent+=printf("RMD160 = ");
-  else if(algo>0)
-    indent+=printf("%6s = ", gcry_md_algo_name (algo));
+  if (algo==DIGEST_ALGO_RMD160)
+    indent += es_printf("RMD160 = ");
+  else if (algo>0)
+    indent += es_printf("%6s = ", gcry_md_algo_name (algo));
   else
-    algo=abs(algo);
+    algo = abs(algo);
 
-  count=indent;
+  count = indent;
 
   p = gcry_md_read (md, algo);
   n = gcry_md_get_algo_dlen (algo);
 
-  count += printf ("%02X",*p++);
+  count += es_printf ("%02X",*p++);
 
   for(i=1;i<n;i++,p++)
     {
@@ -4244,14 +4325,14 @@ print_hex( gcry_md_hd_t md, int algo, const char *fname )
        {
          if(count+2>79)
            {
-             printf("\n%*s",indent," ");
-             count=indent;
+             es_printf ("\n%*s",indent," ");
+             count = indent;
            }
          else
-           count+=printf(" ");
+           count += es_printf(" ");
 
-         if(!(i%8))
-           count+=printf(" ");
+         if (!(i%8))
+           count += es_printf(" ");
        }
       else if (n==20)
        {
@@ -4259,152 +4340,168 @@ print_hex( gcry_md_hd_t md, int algo, const char *fname )
            {
              if(count+4>79)
                {
-                 printf("\n%*s",indent," ");
+                 es_printf ("\n%*s",indent," ");
                  count=indent;
                }
              else
-               count+=printf(" ");
+               count += es_printf(" ");
            }
 
-         if(!(i%10))
-           count+=printf(" ");
+         if (!(i%10))
+           count += es_printf(" ");
        }
       else
        {
          if(!(i%4))
            {
-             if(count+8>79)
+             if (count+8>79)
                {
-                 printf("\n%*s",indent," ");
+                 es_printf ("\n%*s",indent," ");
                  count=indent;
                }
              else
-               count+=printf(" ");
+               count += es_printf(" ");
            }
        }
 
-      count+=printf("%02X",*p);
+      count += es_printf("%02X",*p);
     }
 
-  printf("\n");
+  es_printf ("\n");
 }
 
 static void
 print_hashline( gcry_md_hd_t md, int algo, const char *fname )
 {
-    int i, n;
-    const byte *p;
+  int i, n;
+  const byte *p;
 
-    if ( fname ) {
-        for (p = fname; *p; p++ ) {
-            if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
-                printf("%%%02X", *p );
-            else
-                putchar( *p );
+  if ( fname )
+    {
+      for (p = fname; *p; p++ )
+        {
+          if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
+            es_printf ("%%%02X", *p );
+          else
+            es_putc (*p, es_stdout);
         }
     }
-    putchar(':');
-    printf("%d:", algo );
-    p = gcry_md_read (md, algo);
-    n = gcry_md_get_algo_dlen (algo);
-    for(i=0; i < n ; i++, p++ )
-        printf("%02X", *p );
-    putchar(':');
-    putchar('\n');
+  es_putc (':', es_stdout);
+  es_printf ("%d:", algo);
+  p = gcry_md_read (md, algo);
+  n = gcry_md_get_algo_dlen (algo);
+  for(i=0; i < n ; i++, p++ )
+    es_printf ("%02X", *p);
+  es_fputs (":\n", es_stdout);
 }
 
+
 static void
 print_mds( const char *fname, int algo )
 {
-    FILE *fp;
-    char buf[1024];
-    size_t n;
-    gcry_md_hd_t md;
+  FILE *fp;
+  char buf[1024];
+  size_t n;
+  gcry_md_hd_t md;
 
-    if( !fname ) {
-       fp = stdin;
+  if (!fname)
+    {
+      fp = stdin;
 #ifdef HAVE_DOSISH_SYSTEM
-       setmode ( fileno(fp) , O_BINARY );
+      setmode ( fileno(fp) , O_BINARY );
 #endif
     }
-    else {
-       fp = fopen( fname, "rb" );
-        if (fp && is_secured_file (fileno (fp)))
-          {
-            fclose (fp);
-            fp = NULL;
-            errno = EPERM;
-          }
+  else
+    {
+      fp = fopen (fname, "rb" );
+      if (fp && is_secured_file (fileno (fp)))
+        {
+          fclose (fp);
+          fp = NULL;
+          gpg_err_set_errno (EPERM);
+        }
     }
-    if( !fp ) {
-       log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
-       return;
+  if (!fp)
+    {
+      log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
+      return;
     }
 
-    gcry_md_open (&md, 0, 0);
-    if( algo )
-        gcry_md_enable (md, algo);
-    else {
-       gcry_md_enable (md, GCRY_MD_MD5);
-       gcry_md_enable (md, GCRY_MD_SHA1);
-       gcry_md_enable (md, GCRY_MD_RMD160);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA224))
-          gcry_md_enable (md, GCRY_MD_SHA224);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA256))
-          gcry_md_enable (md, GCRY_MD_SHA256);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA384))
-          gcry_md_enable (md, GCRY_MD_SHA384);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA512))
-          gcry_md_enable (md, GCRY_MD_SHA512);
+  gcry_md_open (&md, 0, 0);
+  if (algo)
+    gcry_md_enable (md, algo);
+  else
+    {
+      if (!gcry_md_test_algo (GCRY_MD_MD5))
+        gcry_md_enable (md, GCRY_MD_MD5);
+      gcry_md_enable (md, GCRY_MD_SHA1);
+      if (!gcry_md_test_algo (GCRY_MD_RMD160))
+        gcry_md_enable (md, GCRY_MD_RMD160);
+      if (!gcry_md_test_algo (GCRY_MD_SHA224))
+        gcry_md_enable (md, GCRY_MD_SHA224);
+      if (!gcry_md_test_algo (GCRY_MD_SHA256))
+        gcry_md_enable (md, GCRY_MD_SHA256);
+      if (!gcry_md_test_algo (GCRY_MD_SHA384))
+        gcry_md_enable (md, GCRY_MD_SHA384);
+      if (!gcry_md_test_algo (GCRY_MD_SHA512))
+        gcry_md_enable (md, GCRY_MD_SHA512);
     }
 
-    while( (n=fread( buf, 1, DIM(buf), fp )) )
-       gcry_md_write (md, buf, n);
-    if( ferror(fp) )
-       log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
-    else {
-       gcry_md_final (md);
-        if ( opt.with_colons ) {
-            if ( algo )
-                print_hashline( md, algo, fname );
-            else {
+  while ((n=fread (buf, 1, DIM(buf), fp)))
+    gcry_md_write (md, buf, n);
+
+  if (ferror(fp))
+    log_error ("%s: %s\n", fname?fname:"[stdin]", strerror(errno));
+  else
+    {
+      gcry_md_final (md);
+      if (opt.with_colons)
+        {
+          if ( algo )
+            print_hashline (md, algo, fname);
+          else
+            {
+              if (!gcry_md_test_algo (GCRY_MD_MD5))
                 print_hashline( md, GCRY_MD_MD5, fname );
-                print_hashline( md, GCRY_MD_SHA1, fname );
-                if (!gcry_md_test_algo (GCRY_MD_RMD160))
-                    print_hashline( md, GCRY_MD_RMD160, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA224))
-                    print_hashline (md, GCRY_MD_SHA224, fname);
-                if (!gcry_md_test_algo (GCRY_MD_SHA256))
-                    print_hashline( md, GCRY_MD_SHA256, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA384))
-                    print_hashline ( md, GCRY_MD_SHA384, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA512))
-                    print_hashline ( md, GCRY_MD_SHA512, fname );
+              print_hashline( md, GCRY_MD_SHA1, fname );
+              if (!gcry_md_test_algo (GCRY_MD_RMD160))
+                print_hashline( md, GCRY_MD_RMD160, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA224))
+                print_hashline (md, GCRY_MD_SHA224, fname);
+              if (!gcry_md_test_algo (GCRY_MD_SHA256))
+                print_hashline( md, GCRY_MD_SHA256, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA384))
+                print_hashline ( md, GCRY_MD_SHA384, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA512))
+                print_hashline ( md, GCRY_MD_SHA512, fname );
             }
         }
-        else {
-            if( algo )
-              print_hex(md,-algo,fname);
-            else {
-                print_hex( md, GCRY_MD_MD5, fname );
-                print_hex( md, GCRY_MD_SHA1, fname );
-                if (!gcry_md_test_algo (GCRY_MD_RMD160))
-                    print_hex( md, GCRY_MD_RMD160, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA224))
-                    print_hex (md, GCRY_MD_SHA224, fname);
-                if (!gcry_md_test_algo (GCRY_MD_SHA256))
-                    print_hex( md, GCRY_MD_SHA256, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA384))
-                    print_hex( md, GCRY_MD_SHA384, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA512))
-                    print_hex( md, GCRY_MD_SHA512, fname );
+      else
+        {
+          if (algo)
+            print_hex (md, -algo, fname);
+          else
+            {
+              if (!gcry_md_test_algo (GCRY_MD_MD5))
+                print_hex (md, GCRY_MD_MD5, fname);
+              print_hex (md, GCRY_MD_SHA1, fname );
+              if (!gcry_md_test_algo (GCRY_MD_RMD160))
+                print_hex (md, GCRY_MD_RMD160, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA224))
+                print_hex (md, GCRY_MD_SHA224, fname);
+              if (!gcry_md_test_algo (GCRY_MD_SHA256))
+                print_hex (md, GCRY_MD_SHA256, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA384))
+                print_hex (md, GCRY_MD_SHA384, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA512))
+                print_hex (md, GCRY_MD_SHA512, fname );
             }
         }
     }
-    gcry_md_close(md);
+  gcry_md_close (md);
 
-    if( fp != stdin )
-       fclose(fp);
+  if (fp != stdin)
+    fclose (fp);
 }
 
 
index 9cd84bb..ce4d253 100644 (file)
--- a/g10/gpg.h
+++ b/g10/gpg.h
@@ -1,5 +1,5 @@
 /* gpg.h - top level include file for gpg etc.
- * Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2006, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 /* Number of bits we accept when reading or writing MPIs. */
 #define MAX_EXTERN_MPI_BITS 16384
 
-/* The maximum length of a binary fingerprints.  */
+/* The maximum length of a binary fingerprints.
+   Warning: At some places we still use 20 instead of this macro. */
 #define MAX_FINGERPRINT_LEN 20
 
 
+
+/*
+    Macros formerly in cipher.h
+ */
+
+
+
+
+
 /*
    Forward declarations.
  */
 /* Object used to keep state locally to server.c . */
 struct server_local_s;
 
+/* Object used to keep state locally to call-dirmngr.c .  */
+struct dirmngr_local_s;
+typedef struct dirmngr_local_s *dirmngr_local_t;
+
 /* Object used to describe a keyblok node.  */
 typedef struct kbnode_struct *KBNODE;
 typedef struct kbnode_struct *kbnode_t;
-/* Object used for looking ob keys.  */
-typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
-
 
 
 /* Session control object.  This object is passed to most functions to
@@ -61,7 +72,11 @@ typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
    gpg_init_default_ctrl(). */
 struct server_control_s
 {
+  /* Local data for server.c  */
   struct server_local_s *server_local;
+
+  /* Local data for call-dirmngr.c  */
+  dirmngr_local_t dirmngr_local;
 };
 
 
@@ -115,9 +130,10 @@ struct server_control_s
 #define G10ERR_TRUSTDB         GPG_ERR_TRUSTDB
 #define G10ERR_UNEXPECTED      GPG_ERR_UNEXPECTED
 #define G10ERR_UNKNOWN_PACKET  GPG_ERR_UNKNOWN_PACKET
-#define G10ERR_UNSUPPORTED     GPG_ERR_NOT_SUPPORTED
+#define G10ERR_UNSUPPORTED     GPG_ERR_UNSUPPORTED
 #define G10ERR_UNU_PUBKEY      GPG_ERR_UNUSABLE_PUBKEY
 #define G10ERR_UNU_SECKEY      GPG_ERR_UNUSABLE_SECKEY
 #define G10ERR_WRONG_SECKEY    GPG_ERR_WRONG_SECKEY
 
+
 #endif /*GNUPG_G10_GPG_H*/
index 3b48a0e..d79b899 100644 (file)
 
 #define INCLUDED_BY_MAIN_MODULE 1
 #include "gpg.h"
+#include "util.h"
 #include "packet.h"
 #include "iobuf.h"
-#include "util.h"
 #include "main.h"
 #include "options.h"
 #include "keydb.h"
 #include "trustdb.h"
-#include "cipher.h"
 #include "filter.h"
 #include "ttyio.h"
 #include "i18n.h"
 #include "sysutils.h"
 #include "status.h"
 #include "call-agent.h"
+#include "../common/init.h"
 
 
 enum cmd_and_opt_values {
@@ -57,7 +57,7 @@ enum cmd_and_opt_values {
   oVerbose       = 'v',
   oBatch         = 500,
   oKeyring,
-  oIgnoreTimeConflict,                      
+  oIgnoreTimeConflict,
   oStatusFD,
   oLoggerFD,
   oHomedir,
@@ -67,10 +67,10 @@ enum cmd_and_opt_values {
 
 static ARGPARSE_OPTS opts[] = {
   ARGPARSE_group (300, N_("@\nOptions:\n ")),
-  
+
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet,   "quiet",   N_("be somewhat more quiet")),
-  ARGPARSE_s_s (oKeyring, "keyring", 
+  ARGPARSE_s_s (oKeyring, "keyring",
                 N_("|FILE|take the keys from the keyring FILE")),
   ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict",
                 N_("make timestamp conflicts only a warning")),
@@ -92,7 +92,7 @@ make_libversion (const char *libname, const char *(*getfnc)(const char*))
 {
   const char *s;
   char *result;
-  
+
   s = getfnc (NULL);
   result = xmalloc (strlen (libname) + 1 + strlen (s) + 1);
   strcpy (stpcpy (stpcpy (result, libname), " "), s);
@@ -107,7 +107,7 @@ my_strusage( int level )
 
   switch (level)
     {
-    case 11: p = "gpgv (GnuPG)";
+    case 11: p = "@GPG@v (GnuPG)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -140,15 +140,16 @@ main( int argc, char **argv )
   ARGPARSE_ARGS pargs;
   int rc=0;
   strlist_t sl;
-  strlist_t nrings=NULL;
+  strlist_t nrings = NULL;
   unsigned configlineno;
+  ctrl_t ctrl;
 
   set_strusage (my_strusage);
   log_set_prefix ("gpgv", 1);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
     {
@@ -161,18 +162,15 @@ main( int argc, char **argv )
 
   opt.command_fd = -1; /* no command fd */
   opt.pgp2_workarounds = 1;
-  opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
+  opt.keyserver_options.options |= KEYSERVER_AUTO_KEY_RETRIEVE;
   opt.trust_model = TM_ALWAYS;
-  opt.no_sig_cache = 1;
-  opt.flags.require_cross_cert = 1;
   opt.batch = 1;
 
   opt.homedir = default_homedir ();
 
   tty_no_terminal(1);
   tty_batchmode(1);
-  disable_dotlock();
-
+  dotlock_disable ();
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
   pargs.argc = &argc;
@@ -183,14 +181,14 @@ main( int argc, char **argv )
       switch (pargs.r_opt)
         {
         case oQuiet: opt.quiet = 1; break;
-        case oVerbose: 
-          opt.verbose++; 
+        case oVerbose:
+          opt.verbose++;
           opt.list_sigs=1;
           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
           break;
         case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
         case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
-        case oLoggerFD: 
+        case oLoggerFD:
           log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
           break;
         case oHomedir: opt.homedir = pargs.r.ret_str; break;
@@ -198,24 +196,29 @@ main( int argc, char **argv )
         default : pargs.err = ARGPARSE_PRINT_ERROR; break;
        }
     }
-  
+
   if (log_get_errorcount (0))
     g10_exit(2);
 
   if (opt.verbose > 1)
     set_packet_list_mode(1);
 
-  /* Note: We open all keyrings in read-only mode (flag value: 8).  */
+  /* Note: We open all keyrings in read-only mode.  */
   if (!nrings)  /* No keyring given: use default one. */
-    keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 8, 0);
+    keydb_add_resource ("trustedkeys" EXTSEP_S GPGEXT_GPG,
+                        KEYDB_RESOURCE_FLAG_READONLY);
   for (sl = nrings; sl; sl = sl->next)
-    keydb_add_resource (sl->d, 8, 0 );
-   
+    keydb_add_resource (sl->d, KEYDB_RESOURCE_FLAG_READONLY);
+
   FREE_STRLIST (nrings);
-    
-  if ( (rc = verify_signatures( argc, argv ) ))
+
+  ctrl = xcalloc (1, sizeof *ctrl);
+
+  if ((rc = verify_signatures (ctrl, argc, argv)))
     log_error("verify signatures failed: %s\n", g10_errstr(rc) );
-  
+
+  xfree (ctrl);
+
   /* cleanup */
   g10_exit (0);
   return 8; /*NOTREACHED*/
@@ -231,7 +234,7 @@ g10_exit( int rc )
 
 
 /* Stub:
- * We have to override the trustcheck from pkclist.c becuase 
+ * We have to override the trustcheck from pkclist.c becuase
  * this utility assumes that all keys in the keyring are trustworthy
  */
 int
@@ -255,7 +258,7 @@ read_trust_options(byte *trust_model, ulong *created, ulong *nextcheck,
   (void)min_cert_level;
 }
 
-/* Stub: 
+/* Stub:
  * We don't have the trustdb , so we have to provide some stub functions
  * instead
  */
@@ -268,7 +271,7 @@ cache_disabled_value(PKT_public_key *pk)
 }
 
 void
-check_trustdb_stale(void) 
+check_trustdb_stale(void)
 {
 }
 
@@ -327,7 +330,7 @@ struct keyserver_spec *
 keyserver_match (struct keyserver_spec *spec)
 {
   (void)spec;
-  return NULL; 
+  return NULL;
 }
 
 int
@@ -342,7 +345,7 @@ int
 keyserver_import_cert (const char *name)
 {
   (void)name;
-  return -1; 
+  return -1;
 }
 
 int
@@ -371,7 +374,7 @@ keyserver_import_ldap (const char *name)
 /* Stub:
  * No encryption here but mainproc links to these functions.
  */
-int
+gpg_error_t
 get_session_key (PKT_pubkey_enc *k, DEK *dek)
 {
   (void)k;
@@ -380,7 +383,7 @@ get_session_key (PKT_pubkey_enc *k, DEK *dek)
 }
 
 /* Stub: */
-int
+gpg_error_t
 get_override_session_key (DEK *dek, const char *string)
 {
   (void)dek;
@@ -390,8 +393,9 @@ get_override_session_key (DEK *dek, const char *string)
 
 /* Stub: */
 int
-decrypt_data (void *procctx, PKT_encrypted *ed, DEK *dek)
+decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
 {
+  (void)ctrl;
   (void)procctx;
   (void)ed;
   (void)dek;
@@ -412,15 +416,15 @@ display_online_help (const char *keyword)
  * We don't use secret keys, but getkey.c links to this
  */
 int
-check_secret_key (PKT_secret_key *sk, int n)
+check_secret_key (PKT_public_key *pk, int n)
 {
-  (void)sk;
+  (void)pk;
   (void)n;
   return G10ERR_GENERAL;
 }
 
 /* Stub:
- * No secret key, so no passphrase needed 
+ * No secret key, so no passphrase needed
  */
 DEK *
 passphrase_to_dek (u32 *keyid, int pubkey_algo,
@@ -448,7 +452,7 @@ passphrase_clear_cache (u32 *keyid, const char *cacheid, int algo)
 }
 
 struct keyserver_spec *
-parse_preferred_keyserver(PKT_signature *sig) 
+parse_preferred_keyserver(PKT_signature *sig)
 {
   (void)sig;
   return NULL;
@@ -465,14 +469,14 @@ parse_keyserver_uri (const char *uri, int require_scheme,
   return NULL;
 }
 
-void 
+void
 free_keyserver_spec (struct keyserver_spec *keyserver)
 {
   (void)keyserver;
 }
 
 /* Stubs to avoid linking to photoid.c */
-void 
+void
 show_photos (const struct user_attribute *attrs, int count, PKT_public_key *pk)
 {
   (void)attrs;
@@ -480,7 +484,7 @@ show_photos (const struct user_attribute *attrs, int count, PKT_public_key *pk)
   (void)pk;
 }
 
-int 
+int
 parse_image_header (const struct user_attribute *attr, byte *type, u32 *len)
 {
   (void)attr;
@@ -498,7 +502,7 @@ image_type_to_string (byte type, int string)
 }
 
 #ifdef ENABLE_CARD_SUPPORT
-int 
+int
 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
 {
   (void)name;
@@ -508,26 +512,27 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
 #endif /* ENABLE_CARD_SUPPORT */
 
 /* We do not do any locking, so use these stubs here */
-void 
-disable_dotlock (void)
+void
+dotlock_disable (void)
 {
 }
 
-DOTLOCK 
-create_dotlock (const char *file_to_lock)
+dotlock_t
+dotlock_create (const char *file_to_lock, unsigned int flags)
 {
   (void)file_to_lock;
+  (void)flags;
   return NULL;
 }
 
-void 
-destroy_dotlock (DOTLOCK h)
+void
+dotlock_destroy (dotlock_t h)
 {
   (void)h;
 }
 
 int
-make_dotlock (DOTLOCK h, long timeout)
+dotlock_take (dotlock_t h, long timeout)
 {
   (void)h;
   (void)timeout;
@@ -535,14 +540,38 @@ make_dotlock (DOTLOCK h, long timeout)
 }
 
 int
-release_dotlock (DOTLOCK h)
+dotlock_release (dotlock_t h)
 {
   (void)h;
   return 0;
 }
 
-void 
-remove_lockfiles (void)
+void
+dotlock_remove_lockfiles (void)
+{
+}
+
+gpg_error_t
+agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
+{
+  (void)ctrl;
+  (void)pk;
+  return gpg_error (GPG_ERR_NO_SECKEY);
+}
+
+gpg_error_t
+agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
 {
+  (void)ctrl;
+  (void)keyblock;
+  return gpg_error (GPG_ERR_NO_SECKEY);
 }
 
+gpg_error_t
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+{
+  (void)ctrl;
+  (void)hexkeygrip;
+  *r_serialno = NULL;
+  return gpg_error (GPG_ERR_NO_SECKEY);
+}
index bf818fa..7bca1db 100644 (file)
@@ -77,12 +77,10 @@ display_online_help( const char *keyword )
         need_final_lf = 0;
       xfree (result);
     }
-  else 
+  else
     {
-      tty_printf (_("No help available for `%s'"), keyword );
+      tty_printf (_("No help available for '%s'"), keyword );
     }
   if (need_final_lf)
     tty_printf("\n");
 }
-
-
index ab75a09..16e2b0b 100644 (file)
@@ -1,6 +1,7 @@
 /* import.c - import a key into our key storage.
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ *               2007, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2014  Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include "ttyio.h"
 #include "status.h"
 #include "keyserver-internal.h"
+#include "call-agent.h"
+#include "../common/membuf.h"
 
 struct stats_s {
     ulong count;
     ulong no_user_id;
     ulong imported;
-    ulong imported_rsa;
     ulong n_uids;
     ulong n_sigs;
     ulong n_subk;
@@ -58,19 +60,21 @@ struct stats_s {
 };
 
 
-static int import( IOBUF inp, const char* fname,struct stats_s *stats,
-                  unsigned char **fpr,size_t *fpr_len,unsigned int options,
-                  import_filter_t filter, void *filter_arg,
-                   int *r_gpgkeys_err);
+static int import (ctrl_t ctrl,
+                   IOBUF inp, const char* fname, struct stats_s *stats,
+                  unsigned char **fpr, size_t *fpr_len, unsigned int options,
+                  import_screener_t screener, void *screener_arg);
 static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
-static void revocation_present(KBNODE keyblock);
-static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats,
-                     unsigned char **fpr,size_t *fpr_len,
-                     unsigned int options,int from_sk,
-                     import_filter_t filter, void *filter_arg);
-static int import_secret_one( const char *fname, KBNODE keyblock,
-                              struct stats_s *stats, unsigned int options,
-                              import_filter_t filter, void *filter_arg);
+static void revocation_present (ctrl_t ctrl, kbnode_t keyblock);
+static int import_one (ctrl_t ctrl,
+                       const char *fname, KBNODE keyblock,struct stats_s *stats,
+                       unsigned char **fpr, size_t *fpr_len,
+                       unsigned int options, int from_sk, int silent,
+                       import_screener_t screener, void *screener_arg);
+static int import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
+                              struct stats_s *stats, int batch,
+                              unsigned int options, int for_migration,
+                              import_screener_t screener, void *screener_arg);
 static int import_revoke_cert( const char *fname, KBNODE node,
                                struct stats_s *stats);
 static int chk_self_sigs( const char *fname, KBNODE keyblock,
@@ -96,28 +100,16 @@ parse_import_options(char *str,unsigned int *options,int noisy)
     {
       {"import-local-sigs",IMPORT_LOCAL_SIGS,NULL,
        N_("import signatures that are marked as local-only")},
-
       {"repair-pks-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,
        N_("repair damage from the pks keyserver during import")},
-
-      {"keep-ownertrust", IMPORT_KEEP_OWNERTTRUST, NULL,
-       N_("do not clear the ownertrust values during import")},
-
       {"fast-import",IMPORT_FAST,NULL,
        N_("do not update the trustdb after import")},
-
-      {"convert-sk-to-pk",IMPORT_SK2PK,NULL,
-       N_("create a public key when importing a secret key")},
-
       {"merge-only",IMPORT_MERGE_ONLY,NULL,
        N_("only accept updates to existing keys")},
-
       {"import-clean",IMPORT_CLEAN,NULL,
        N_("remove unusable parts from key after import")},
-
       {"import-minimal",IMPORT_MINIMAL|IMPORT_CLEAN,NULL,
        N_("remove as much as possible from key after import")},
-
       /* Aliases for backward compatibility */
       {"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL},
       {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL},
@@ -125,6 +117,8 @@ parse_import_options(char *str,unsigned int *options,int noisy)
       {"import-unusable-sigs",0,NULL,NULL},
       {"import-clean-sigs",0,NULL,NULL},
       {"import-clean-uids",0,NULL,NULL},
+      {"convert-sk-to-pk",0, NULL,NULL}, /* Not anymore needed due to
+                                            the new design.  */
       {NULL,0,NULL,NULL}
     };
 
@@ -175,11 +169,10 @@ import_release_stats_handle (void *p)
  *
  */
 static int
-import_keys_internal( IOBUF inp, char **fnames, int nnames,
+import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
                      void *stats_handle, unsigned char **fpr, size_t *fpr_len,
                      unsigned int options,
-                     import_filter_t filter, void *filter_arg,
-                      int *r_gpgkeys_err)
+                      import_screener_t screener, void *screener_arg)
 {
     int i, rc = 0;
     struct stats_s *stats = stats_handle;
@@ -188,13 +181,14 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
         stats = import_new_stats_handle ();
 
     if (inp) {
-        rc = import (inp, "[stream]", stats, fpr, fpr_len, options,
-                     filter, filter_arg, r_gpgkeys_err);
+      rc = import (ctrl, inp, "[stream]", stats, fpr, fpr_len, options,
+                   screener, screener_arg);
     }
     else {
-        int once = (!fnames && !nnames);
+        if( !fnames && !nnames )
+           nnames = 1;  /* Ohh what a ugly hack to jump into the loop */
 
-       for(i=0; once || i < nnames; once=0, i++ ) {
+       for(i=0; i < nnames; i++ ) {
            const char *fname = fnames? fnames[i] : NULL;
            IOBUF inp2 = iobuf_open(fname);
            if( !fname )
@@ -203,21 +197,24 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
               {
                 iobuf_close (inp2);
                 inp2 = NULL;
-                errno = EPERM;
+                gpg_err_set_errno (EPERM);
               }
            if( !inp2 )
-               log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
+               log_error(_("can't open '%s': %s\n"), fname, strerror(errno) );
            else
              {
-               rc = import (inp2, fname, stats, fpr, fpr_len, options,
-                             NULL, NULL, r_gpgkeys_err);
+               rc = import (ctrl, inp2, fname, stats, fpr, fpr_len, options,
+                             screener, screener_arg);
                iobuf_close(inp2);
                 /* Must invalidate that ugly cache to actually close it. */
-                iobuf_ioctl (NULL, 2, 0, (char*)fname);
+                iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
+                             0, (char*)fname);
                if( rc )
-                 log_error("import from `%s' failed: %s\n", fname,
+                 log_error("import from '%s' failed: %s\n", fname,
                            g10_errstr(rc) );
              }
+           if( !fname )
+               break;
        }
     }
     if (!stats_handle) {
@@ -232,60 +229,87 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
        interactive or by not setting no-auto-check-trustdb */
 
     if(!(options&IMPORT_FAST))
-      trustdb_check_or_update();
+      check_or_update_trustdb ();
 
     return rc;
 }
 
+
 void
-import_keys( char **fnames, int nnames,
+import_keys (ctrl_t ctrl, char **fnames, int nnames,
             void *stats_handle, unsigned int options )
 {
-  import_keys_internal (NULL, fnames, nnames, stats_handle, NULL, NULL,
-                        options, NULL, NULL, NULL);
+  import_keys_internal (ctrl, NULL, fnames, nnames, stats_handle,
+                        NULL, NULL, options, NULL, NULL);
+}
+
+int
+import_keys_stream (ctrl_t ctrl, IOBUF inp, void *stats_handle,
+                   unsigned char **fpr, size_t *fpr_len, unsigned int options)
+{
+  return import_keys_internal (ctrl, inp, NULL, 0, stats_handle,
+                               fpr, fpr_len, options, NULL, NULL);
 }
 
 
-/* Import keys from an open stream.  */
+/* Variant of import_keys_stream reading from an estream_t.  */
 int
-import_keys_stream( IOBUF inp, void *stats_handle,
-                   unsigned char **fpr, size_t *fpr_len,unsigned int options,
-                   import_filter_t filter, void *filter_arg,
-                    int *r_gpgkeys_err)
+import_keys_es_stream (ctrl_t ctrl, estream_t fp, void *stats_handle,
+                       unsigned char **fpr, size_t *fpr_len,
+                       unsigned int options,
+                       import_screener_t screener, void *screener_arg)
 {
-  return import_keys_internal (inp, NULL, 0, stats_handle, fpr, fpr_len,
-                               options, filter, filter_arg, r_gpgkeys_err);
+  int rc;
+  iobuf_t inp;
+
+  inp = iobuf_esopen (fp, "r", 1);
+  if (!inp)
+    {
+      rc = gpg_error_from_syserror ();
+      log_error ("iobuf_esopen failed: %s\n", gpg_strerror (rc));
+      return rc;
+    }
+
+  rc = import_keys_internal (ctrl, inp, NULL, 0, stats_handle,
+                             fpr, fpr_len, options,
+                             screener, screener_arg);
+
+  iobuf_close (inp);
+  return rc;
 }
 
 
-/* Note: If R_GPGKEYS_ERR is not NULL an error code from the keyserver
-   helpers will be stored there.  */
 static int
-import (IOBUF inp, const char* fname,struct stats_s *stats,
-       unsigned char **fpr, size_t *fpr_len, unsigned int options,
-       import_filter_t filter, void *filter_arg, int *r_gpgkeys_err)
+import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats,
+       unsigned char **fpr,size_t *fpr_len, unsigned int options,
+       import_screener_t screener, void *screener_arg)
 {
     PACKET *pending_pkt = NULL;
-    KBNODE keyblock = NULL;
+    KBNODE keyblock = NULL;  /* Need to initialize because gcc can't
+                                grasp the return semantics of
+                                read_block. */
     int rc = 0;
-    armor_filter_context_t *afx = NULL;
 
     getkey_disable_caches();
 
-    if (!opt.no_armor || r_gpgkeys_err) {
-        /* armored reading is not disabled or enforced. */
+    if( !opt.no_armor ) { /* armored reading is not disabled */
+       armor_filter_context_t *afx;
+
         afx = new_armor_context ();
        afx->only_keyblocks = 1;
        push_armor_filter (afx, inp);
+        release_armor_context (afx);
     }
 
     while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
        if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
-           rc = import_one (fname, keyblock, stats, fpr, fpr_len, options, 0,
-                             filter, filter_arg);
-        else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
-            rc = import_secret_one (fname, keyblock, stats, options,
-                                    filter, filter_arg);
+          rc = import_one (ctrl, fname, keyblock,
+                           stats, fpr, fpr_len, options, 0, 0,
+                           screener, screener_arg);
+       else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
+          rc = import_secret_one (ctrl, fname, keyblock, stats,
+                                  opt.batch, options, 0,
+                                  screener, screener_arg);
        else if( keyblock->pkt->pkttype == PKT_SIGNATURE
                 && keyblock->pkt->pkt.signature->sig_class == 0x20 )
            rc = import_revoke_cert( fname, keyblock, stats );
@@ -304,14 +328,61 @@ import (IOBUF inp, const char* fname,struct stats_s *stats,
     if( rc == -1 )
        rc = 0;
     else if( rc && rc != G10ERR_INV_KEYRING )
-       log_error( _("error reading `%s': %s\n"), fname, g10_errstr(rc));
+       log_error( _("error reading '%s': %s\n"), fname, g10_errstr(rc));
 
-    if (afx && r_gpgkeys_err)
-      *r_gpgkeys_err = afx->key_failed_code;
+    return rc;
+}
 
-    release_armor_context (afx);
 
-    return rc;
+/* Helper to migrate secring.gpg to GnuPG 2.1.  */
+gpg_error_t
+import_old_secring (ctrl_t ctrl, const char *fname)
+{
+  gpg_error_t err;
+  iobuf_t inp;
+  PACKET *pending_pkt = NULL;
+  kbnode_t keyblock = NULL;  /* Need to initialize because gcc can't
+                                grasp the return semantics of
+                                read_block. */
+  struct stats_s *stats;
+
+  inp = iobuf_open (fname);
+  if (inp && is_secured_file (iobuf_get_fd (inp)))
+    {
+      iobuf_close (inp);
+      inp = NULL;
+      gpg_err_set_errno (EPERM);
+    }
+  if (!inp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err));
+      return err;
+    }
+
+  getkey_disable_caches();
+  stats = import_new_stats_handle ();
+  while (!(err = read_block (inp, &pending_pkt, &keyblock)))
+    {
+      if (keyblock->pkt->pkttype == PKT_SECRET_KEY)
+        err = import_secret_one (ctrl, fname, keyblock, stats, 1, 0, 1,
+                                 NULL, NULL);
+      release_kbnode (keyblock);
+      if (err)
+        break;
+    }
+  import_release_stats_handle (stats);
+  if (err == -1)
+    err = 0;
+  else if (err && gpg_err_code (err) != G10ERR_INV_KEYRING)
+    log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
+  else if (err)
+    log_error ("import from '%s' failed: %s\n", fname, gpg_strerror (err));
+
+  iobuf_close (inp);
+  iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname);
+
+  return err;
 }
 
 
@@ -327,10 +398,8 @@ import_print_stats (void *hd)
                                                stats->skipped_new_keys );
        if( stats->no_user_id )
            log_info(_("          w/o user IDs: %lu\n"), stats->no_user_id );
-       if( stats->imported || stats->imported_rsa ) {
+       if( stats->imported) {
            log_info(_("              imported: %lu"), stats->imported );
-           if (stats->imported_rsa)
-              log_printf ("  (RSA: %lu)", stats->imported_rsa );
            log_printf ("\n");
        }
        if( stats->unchanged )
@@ -359,11 +428,10 @@ import_print_stats (void *hd)
 
     if( is_status_enabled() ) {
        char buf[14*20];
-       sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
+       sprintf(buf, "%lu %lu %lu 0 %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
                stats->count,
                stats->no_user_id,
                stats->imported,
-               stats->imported_rsa,
                stats->unchanged,
                stats->n_uids,
                stats->n_subk,
@@ -404,7 +472,7 @@ valid_keyblock_packet (int pkttype)
  * Read the next keyblock from stream A.
  * PENDING_PKT should be initialzed to NULL
  * and not chnaged form the caller.
- * Retunr: 0 = okay, -1 no more blocks or another errorcode.
+ * Return: 0 = okay, -1 no more blocks or another errorcode.
  */
 static int
 read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root )
@@ -577,12 +645,12 @@ fix_pks_corruption(KBNODE keyblock)
    equal.  Although direct key signatures are now checked during
    import, there might still be bogus signatures sitting in a keyring.
    We need to detect and delete them before doing a merge.  This
-   fucntion returns the number of removed sigs.  */
+   function returns the number of removed sigs.  */
 static int
-fix_bad_direct_key_sigs (KBNODE keyblock, u32 *keyid)
+fix_bad_direct_key_sigs (kbnode_t keyblock, u32 *keyid)
 {
   gpg_error_t err;
-  KBNODE node;
+  kbnode_t node;
   int count = 0;
 
   for (node = keyblock->next; node; node=node->next)
@@ -611,19 +679,16 @@ fix_bad_direct_key_sigs (KBNODE keyblock, u32 *keyid)
 
 
 static void
-print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason)
+print_import_ok (PKT_public_key *pk, unsigned int reason)
 {
   byte array[MAX_FINGERPRINT_LEN], *s;
   char buf[MAX_FINGERPRINT_LEN*2+30], *p;
   size_t i, n;
 
-  sprintf (buf, "%u ", reason);
+  snprintf (buf, sizeof buf, "%u ", reason);
   p = buf + strlen (buf);
 
-  if (pk)
-    fingerprint_from_pk (pk, array, &n);
-  else
-    fingerprint_from_sk (sk, array, &n);
+  fingerprint_from_pk (pk, array, &n);
   s = array;
   for (i=0; i < n ; i++, s++, p += 2)
     sprintf (p, "%02X", *s);
@@ -661,9 +726,9 @@ check_prefs_warning(PKT_public_key *pk)
 }
 
 static void
-check_prefs(KBNODE keyblock)
+check_prefs (ctrl_t ctrl, kbnode_t keyblock)
 {
-  KBNODE node;
+  kbnode_t node;
   PKT_public_key *pk;
   int problem=0;
 
@@ -758,7 +823,7 @@ check_prefs(KBNODE keyblock)
          append_to_strlist(&sl,"updpref");
          append_to_strlist(&sl,"save");
 
-         keyedit_menu( username, locusr, sl, 1, 1 );
+         keyedit_menu (ctrl, username, locusr, sl, 1, 1 );
          free_strlist(sl);
          free_strlist(locusr);
        }
@@ -769,26 +834,33 @@ check_prefs(KBNODE keyblock)
 }
 
 /****************
- * Try to import one keyblock. Return an error only in serious cases, but
- * never for an invalid keyblock.  It uses log_error to increase the
- * internal errorcount, so that invalid input can be detected by programs
- * which called gpg.
+ * Try to import one keyblock. Return an error only in serious cases,
+ * but never for an invalid keyblock.  It uses log_error to increase
+ * the internal errorcount, so that invalid input can be detected by
+ * programs which called gpg.  If SILENT is no messages are printed -
+ * even most error messages are suppressed.
  */
 static int
-import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
-           unsigned char **fpr,size_t *fpr_len,unsigned int options,
-           int from_sk, import_filter_t filter, void *filter_arg)
+import_one (ctrl_t ctrl,
+            const char *fname, KBNODE keyblock, struct stats_s *stats,
+           unsigned char **fpr, size_t *fpr_len, unsigned int options,
+           int from_sk, int silent,
+            import_screener_t screener, void *screener_arg)
 {
     PKT_public_key *pk;
     PKT_public_key *pk_orig;
     KBNODE node, uidnode;
     KBNODE keyblock_orig = NULL;
+    byte fpr2[MAX_FINGERPRINT_LEN];
+    size_t fpr2len;
     u32 keyid[2];
     int rc = 0;
     int new_key = 0;
     int mod_key = 0;
     int same_key = 0;
     int non_self = 0;
+    size_t an;
+    char pkstrbuf[PUBKEY_STRING_SIZE];
 
     /* get the key and print some info about it */
     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
@@ -797,17 +869,19 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
 
     pk = node->pkt->pkt.public_key;
 
+    fingerprint_from_pk (pk, fpr2, &fpr2len);
+    for (an = fpr2len; an < MAX_FINGERPRINT_LEN; an++)
+      fpr2[an] = 0;
     keyid_from_pk( pk, keyid );
     uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
 
-    if( opt.verbose && !opt.interactive )
+    if (opt.verbose && !opt.interactive && !silent)
       {
-       log_info( "pub  %4u%c/%s %s  ",
-                 nbits_from_pk( pk ),
-                 pubkey_letter( pk->pubkey_algo ),
+       log_info( "pub  %s/%s %s  ",
+                 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
                  keystr_from_pk(pk), datestr_from_pk(pk) );
        if (uidnode)
-         print_utf8_string (log_get_stream (),
+         print_utf8_buffer (log_get_stream (),
                              uidnode->pkt->pkt.user_id->name,
                             uidnode->pkt->pkt.user_id->len );
        log_printf ("\n");
@@ -816,18 +890,19 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
 
     if( !uidnode )
       {
-       log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
+        if (!silent)
+          log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
        return 0;
       }
 
-    if (filter && filter (keyblock, filter_arg))
+    if (screener && screener (keyblock, screener_arg))
       {
-        log_error (_("key %s: %s\n"), keystr_from_pk(pk),
-                   _("rejected by import filter"));
+        log_error (_("key %s: %s\n"), keystr_from_pk (pk),
+                   _("rejected by import screener"));
         return 0;
       }
 
-    if (opt.interactive) {
+    if (opt.interactive && !silent) {
         if(is_status_enabled())
          print_import_check (pk, uidnode->pkt->pkt.user_id);
        merge_keys_and_selfsig (keyblock);
@@ -860,7 +935,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
        return rc== -1? 0:rc;
 
     /* If we allow such a thing, mark unsigned uids as valid */
-    if( opt.allow_non_selfsigned_uid )
+    if( opt.allow_non_selfsigned_uid)
       for( node=keyblock; node; node = node->next )
        if( node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) )
          {
@@ -873,51 +948,53 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
          }
 
     if( !delete_inv_parts( fname, keyblock, keyid, options ) ) {
-        log_error( _("key %s: no valid user IDs\n"), keystr_from_pk(pk));
-       if( !opt.quiet )
-         log_info(_("this may be caused by a missing self-signature\n"));
+        if (!silent) {
+           log_error( _("key %s: no valid user IDs\n"), keystr_from_pk(pk));
+           if( !opt.quiet )
+             log_info(_("this may be caused by a missing self-signature\n"));
+        }
        stats->no_user_id++;
        return 0;
     }
 
     /* do we have this key already in one of our pubrings ? */
     pk_orig = xmalloc_clear( sizeof *pk_orig );
-    rc = get_pubkey_fast ( pk_orig, keyid );
+    rc = get_pubkey_byfprint_fast (pk_orig, fpr2, fpr2len);
     if( rc && rc != G10ERR_NO_PUBKEY && rc != G10ERR_UNU_PUBKEY )
       {
-       log_error( _("key %s: public key not found: %s\n"),
-                  keystr(keyid), g10_errstr(rc));
+        if (!silent)
+          log_error (_("key %s: public key not found: %s\n"),
+                     keystr(keyid), g10_errstr(rc));
       }
     else if ( rc && (opt.import_options&IMPORT_MERGE_ONLY) )
       {
-       if( opt.verbose )
+       if( opt.verbose && !silent )
          log_info( _("key %s: new key - skipped\n"), keystr(keyid));
        rc = 0;
        stats->skipped_new_keys++;
       }
     else if( rc ) { /* insert this key */
-        KEYDB_HANDLE hd = keydb_new (0);
+        KEYDB_HANDLE hd = keydb_new ();
 
         rc = keydb_locate_writable (hd, NULL);
        if (rc) {
-           log_error (_("no writable keyring found: %s\n"), g10_errstr (rc));
+            log_error (_("no writable keyring found: %s\n"), g10_errstr (rc));
             keydb_release (hd);
            return G10ERR_GENERAL;
        }
        if( opt.verbose > 1 )
-           log_info (_("writing to `%s'\n"), keydb_get_resource_name (hd) );
+           log_info (_("writing to '%s'\n"), keydb_get_resource_name (hd) );
 
        rc = keydb_insert_keyblock (hd, keyblock );
         if (rc)
-          log_error (_("error writing keyring `%s': %s\n"),
+          log_error (_("error writing keyring '%s': %s\n"),
                       keydb_get_resource_name (hd), g10_errstr(rc));
-       else if (!(opt.import_options & IMPORT_KEEP_OWNERTTRUST))
+       else
          {
            /* This should not be possible since we delete the
               ownertrust when a key is deleted, but it can happen if
               the keyring and trustdb are out of sync.  It can also
-              be made to happen with the trusted-key command and by
-              importing and locally exported key. */
+              be made to happen with the trusted-key command. */
 
            clear_ownertrusts (pk);
            if(non_self)
@@ -926,11 +1003,11 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
         keydb_release (hd);
 
        /* we are ready */
-       if( !opt.quiet )
+       if( !opt.quiet && !silent)
          {
-           char *p=get_user_id_native (keyid);
-           log_info_("key %s: public key \"%s\" imported\n"),
-                     keystr(keyid),p);
+           char *p = get_user_id_byfpr_native (fpr2);
+           log_info (_("key %s: public key \"%s\" imported\n"),
+                     keystr(keyid), p);
            xfree(p);
          }
        if( is_status_enabled() )
@@ -938,11 +1015,9 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
            char *us = get_long_user_id_string( keyid );
            write_status_text( STATUS_IMPORTED, us );
            xfree(us);
-            print_import_ok (pk,NULL, 1);
+            print_import_ok (pk, 1);
          }
        stats->imported++;
-       if( is_RSA( pk->pubkey_algo ) )
-           stats->imported_rsa++;
        new_key = 1;
     }
     else { /* merge */
@@ -953,21 +1028,16 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
         * weird is going on */
        if( cmp_public_keys( pk_orig, pk ) )
          {
-           log_error( _("key %s: doesn't match our copy\n"),keystr(keyid));
+            if (!silent)
+              log_error( _("key %s: doesn't match our copy\n"),keystr(keyid));
            goto leave;
          }
 
-       /* now read the original keyblock */
-        hd = keydb_new (0);
-        {
-            byte afp[MAX_FINGERPRINT_LEN];
-            size_t an;
-
-            fingerprint_from_pk (pk_orig, afp, &an);
-            while (an < MAX_FINGERPRINT_LEN)
-                afp[an++] = 0;
-            rc = keydb_search_fpr (hd, afp);
-        }
+       /* Now read the original keyblock again so that we can use
+           that handle for updating the keyblock.  */
+        hd = keydb_new ();
+        keydb_disable_caching (hd);
+        rc = keydb_search_fpr (hd, fpr2);
        if( rc )
          {
            log_error (_("key %s: can't locate original keyblock: %s\n"),
@@ -975,7 +1045,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
             keydb_release (hd);
            goto leave;
          }
-       rc = keydb_get_keyblock (hd, &keyblock_orig );
+       rc = keydb_get_keyblock (hd, &keyblock_orig);
        if (rc)
          {
            log_error (_("key %s: can't read original keyblock: %s\n"),
@@ -1010,15 +1080,15 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
            /* keyblock_orig has been updated; write */
            rc = keydb_update_keyblock (hd, keyblock_orig);
             if (rc)
-               log_error (_("error writing keyring `%s': %s\n"),
+               log_error (_("error writing keyring '%s': %s\n"),
                             keydb_get_resource_name (hd), g10_errstr(rc) );
            else if(non_self)
              revalidation_mark ();
 
            /* we are ready */
-           if( !opt.quiet )
+           if( !opt.quiet && !silent)
              {
-               char *p=get_user_id_native(keyid);
+               char *p = get_user_id_byfpr_native (fpr2);
                if( n_uids == 1 )
                  log_info( _("key %s: \"%s\" 1 new user ID\n"),
                           keystr(keyid),p);
@@ -1058,19 +1128,18 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
            stats->n_sigs_cleaned +=n_sigs_cleaned;
            stats->n_uids_cleaned +=n_uids_cleaned;
 
-            if (is_status_enabled ())
-                 print_import_ok (pk, NULL,
-                                  ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
+            if (is_status_enabled () && !silent)
+              print_import_ok (pk, ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
        }
        else
          {
             same_key = 1;
             if (is_status_enabled ())
-             print_import_ok (pk, NULL, 0);
+             print_import_ok (pk, 0);
 
-           if( !opt.quiet )
+           if( !opt.quiet && !silent)
              {
-               char *p=get_user_id_native(keyid);
+               char *p = get_user_id_byfpr_native (fpr2);
                log_info( _("key %s: \"%s\" not changed\n"),keystr(keyid),p);
                xfree(p);
              }
@@ -1114,17 +1183,17 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
        need to check if a designated revocation is present or if the
        prefs are not rational so we can warn the user. */
 
-    if(mod_key)
+    if (mod_key)
       {
-       revocation_present(keyblock_orig);
-       if(!from_sk && seckey_available(keyid)==0)
-         check_prefs(keyblock_orig);
+       revocation_present (ctrl, keyblock_orig);
+       if (!from_sk && have_secret_key_with_kid (keyid))
+         check_prefs (ctrl, keyblock_orig);
       }
-    else if(new_key)
+    else if (new_key)
       {
-       revocation_present(keyblock);
-       if(!from_sk && seckey_available(keyid)==0)
-         check_prefs(keyblock);
+       revocation_present (ctrl, keyblock);
+       if (!from_sk && have_secret_key_with_kid (keyid))
+         check_prefs (ctrl, keyblock);
       }
 
     release_kbnode( keyblock_orig );
@@ -1133,66 +1202,323 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
     return rc;
 }
 
-/* Walk a secret keyblock and produce a public keyblock out of it. */
-static KBNODE
-sec_to_pub_keyblock(KBNODE sec_keyblock)
+
+/* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent.  The
+   function prints diagnostics and returns an error code.  If BATCH is
+   true the secret keys are stored by gpg-agent in the transfer format
+   (i.e. no re-protection and aksing for passphrases). */
+static gpg_error_t
+transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock,
+                      int batch)
 {
-  KBNODE secnode,pub_keyblock=NULL,ctx=NULL;
+  gpg_error_t err = 0;
+  void *kek = NULL;
+  size_t keklen;
+  kbnode_t ctx = NULL;
+  kbnode_t node;
+  PKT_public_key *main_pk, *pk;
+  struct seckey_info *ski;
+  int nskey;
+  membuf_t mbuf;
+  int i, j;
+  void *format_args[2*PUBKEY_MAX_NSKEY];
+  gcry_sexp_t skey, prot, tmpsexp;
+  gcry_sexp_t curve = NULL;
+  unsigned char *transferkey = NULL;
+  size_t transferkeylen;
+  gcry_cipher_hd_t cipherhd = NULL;
+  unsigned char *wrappedkey = NULL;
+  size_t wrappedkeylen;
+  char *cache_nonce = NULL;
+
+  /* Get the current KEK.  */
+  err = agent_keywrap_key (ctrl, 0, &kek, &keklen);
+  if (err)
+    {
+      log_error ("error getting the KEK: %s\n", gpg_strerror (err));
+      goto leave;
+    }
 
-  while((secnode=walk_kbnode(sec_keyblock,&ctx,0)))
+  /* Prepare a cipher context.  */
+  err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
+                          GCRY_CIPHER_MODE_AESWRAP, 0);
+  if (!err)
+    err = gcry_cipher_setkey (cipherhd, kek, keklen);
+  if (err)
+    goto leave;
+  xfree (kek);
+  kek = NULL;
+
+  main_pk = NULL;
+  while ((node = walk_kbnode (sec_keyblock, &ctx, 0)))
     {
-      KBNODE pubnode;
+      if (node->pkt->pkttype != PKT_SECRET_KEY
+          && node->pkt->pkttype != PKT_SECRET_SUBKEY)
+        continue;
+      pk = node->pkt->pkt.public_key;
+      if (!main_pk)
+        main_pk = pk;
 
-      if(secnode->pkt->pkttype==PKT_SECRET_KEY ||
-        secnode->pkt->pkttype==PKT_SECRET_SUBKEY)
-       {
-         /* Make a public key.  We only need to convert enough to
-            write the keyblock out. */
+      /* Make sure the keyids are available.  */
+      keyid_from_pk (pk, NULL);
+      if (node->pkt->pkttype == PKT_SECRET_KEY)
+        {
+          pk->main_keyid[0] = pk->keyid[0];
+          pk->main_keyid[1] = pk->keyid[1];
+        }
+      else
+        {
+          pk->main_keyid[0] = main_pk->keyid[0];
+          pk->main_keyid[1] = main_pk->keyid[1];
+        }
 
-         PKT_secret_key *sk=secnode->pkt->pkt.secret_key;
-         PACKET *pkt=xmalloc_clear(sizeof(PACKET));
-         PKT_public_key *pk=xmalloc_clear(sizeof(PKT_public_key));
-         int n;
 
-         if(secnode->pkt->pkttype==PKT_SECRET_KEY)
-           pkt->pkttype=PKT_PUBLIC_KEY;
-         else
-           pkt->pkttype=PKT_PUBLIC_SUBKEY;
+      ski = pk->seckey_info;
+      if (!ski)
+        BUG ();
 
-         pkt->pkt.public_key=pk;
+      stats->count++;
+      stats->secret_read++;
 
-         pk->version=sk->version;
-         pk->timestamp=sk->timestamp;
-         pk->expiredate=sk->expiredate;
-         pk->pubkey_algo=sk->pubkey_algo;
+      /* We ignore stub keys.  The way we handle them in other parts
+         of the code is by asking the agent whether any secret key is
+         available for a given keyblock and then concluding that we
+         have a secret key; all secret (sub)keys of the keyblock the
+         agent does not know of are then stub keys.  This works also
+         for card stub keys.  The learn command or the card-status
+         command may be used to check with the agent whether a card
+         has been inserted and a stub key is in turn generated by the
+         agent.  */
+      if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002)
+        continue;
 
-         n=pubkey_get_npkey(pk->pubkey_algo);
-         if(n==0)
-           {
-             /* we can't properly extract the pubkey without knowing
-                the number of MPIs */
-             release_kbnode(pub_keyblock);
-             return NULL;
-           }
-         else
-           {
-             int i;
+      /* Convert our internal secret key object into an S-expression.  */
+      nskey = pubkey_get_nskey (pk->pubkey_algo);
+      if (!nskey || nskey > PUBKEY_MAX_NSKEY)
+        {
+          err = gpg_error (GPG_ERR_BAD_SECKEY);
+          log_error ("internal error: %s\n", gpg_strerror (err));
+          goto leave;
+        }
 
-             for(i=0;i<n;i++)
-               pk->pkey[i]=mpi_copy(sk->skey[i]);
-           }
+      init_membuf (&mbuf, 50);
+      put_membuf_str (&mbuf, "(skey");
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
+          || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
+          || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+        {
+          /* The ECC case.  */
+          char *curvestr = openpgp_oid_to_str (pk->pkey[0]);
+          if (!curvestr)
+            err = gpg_error_from_syserror ();
+          else
+            {
+              err = gcry_sexp_build (&curve, NULL, "(curve %s)", curvestr);
+              xfree (curvestr);
+              if (!err)
+                {
+                  j = 0;
+                  /* Append the public key element Q.  */
+                  put_membuf_str (&mbuf, " _ %m");
+                  format_args[j++] = pk->pkey + 1;
+
+                  /* Append the secret key element D.  For ECDH we
+                     skip PKEY[2] because this holds the KEK which is
+                     not needed by gpg-agent.  */
+                  i = pk->pubkey_algo == PUBKEY_ALGO_ECDH? 3 : 2;
+                  if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_USER1))
+                    put_membuf_str (&mbuf, " e %m");
+                  else
+                    put_membuf_str (&mbuf, " _ %m");
+                  format_args[j++] = pk->pkey + i;
+                }
+            }
+        }
+      else
+        {
+          /* Standard case for the old (non-ECC) algorithms.  */
+          for (i=j=0; i < nskey; i++)
+            {
+              if (!pk->pkey[i])
+                continue; /* Protected keys only have NPKEY+1 elements.  */
+
+              if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_USER1))
+                put_membuf_str (&mbuf, " e %m");
+              else
+                put_membuf_str (&mbuf, " _ %m");
+              format_args[j++] = pk->pkey + i;
+            }
+        }
+      put_membuf_str (&mbuf, ")");
+      put_membuf (&mbuf, "", 1);
+      if (err)
+        xfree (get_membuf (&mbuf, NULL));
+      else
+        {
+          char *format = get_membuf (&mbuf, NULL);
+          if (!format)
+            err = gpg_error_from_syserror ();
+          else
+            err = gcry_sexp_build_array (&skey, NULL, format, format_args);
+          xfree (format);
+        }
+      if (err)
+        {
+          log_error ("error building skey array: %s\n", gpg_strerror (err));
+          goto leave;
+        }
+
+      if (ski->is_protected)
+        {
+          char countbuf[35];
+
+          /* Note that the IVLEN may be zero if we are working on a
+             dummy key.  We can't express that in an S-expression and
+             thus we send dummy data for the IV.  */
+          snprintf (countbuf, sizeof countbuf, "%lu",
+                    (unsigned long)ski->s2k.count);
+          err = gcry_sexp_build
+            (&prot, NULL,
+             " (protection %s %s %b %d %s %b %s)\n",
+             ski->sha1chk? "sha1":"sum",
+             openpgp_cipher_algo_name (ski->algo),
+             ski->ivlen? (int)ski->ivlen:1,
+             ski->ivlen? ski->iv: (const unsigned char*)"X",
+             ski->s2k.mode,
+             openpgp_md_algo_name (ski->s2k.hash_algo),
+             (int)sizeof (ski->s2k.salt), ski->s2k.salt,
+             countbuf);
+        }
+      else
+        err = gcry_sexp_build (&prot, NULL, " (protection none)\n");
+
+      tmpsexp = NULL;
+      xfree (transferkey);
+      transferkey = NULL;
+      if (!err)
+        err = gcry_sexp_build (&tmpsexp, NULL,
+                               "(openpgp-private-key\n"
+                               " (version %d)\n"
+                               " (algo %s)\n"
+                               " %S%S\n"
+                               " (csum %d)\n"
+                               " %S)\n",
+                               pk->version,
+                               openpgp_pk_algo_name (pk->pubkey_algo),
+                               curve, skey,
+                               (int)(unsigned long)ski->csum, prot);
+      gcry_sexp_release (skey);
+      gcry_sexp_release (prot);
+      if (!err)
+        err = make_canon_sexp_pad (tmpsexp, 1, &transferkey, &transferkeylen);
+      gcry_sexp_release (tmpsexp);
+      if (err)
+        {
+          log_error ("error building transfer key: %s\n", gpg_strerror (err));
+          goto leave;
+        }
+
+      /* Wrap the key.  */
+      wrappedkeylen = transferkeylen + 8;
+      xfree (wrappedkey);
+      wrappedkey = xtrymalloc (wrappedkeylen);
+      if (!wrappedkey)
+        err = gpg_error_from_syserror ();
+      else
+        err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen,
+                                   transferkey, transferkeylen);
+      if (err)
+        goto leave;
+      xfree (transferkey);
+      transferkey = NULL;
+
+      /* Send the wrapped key to the agent.  */
+      {
+        char *desc = gpg_format_keydesc (pk, FORMAT_KEYDESC_IMPORT, 1);
+        err = agent_import_key (ctrl, desc, &cache_nonce,
+                                wrappedkey, wrappedkeylen, batch);
+        xfree (desc);
+      }
+      if (!err)
+        {
+          if (opt.verbose)
+            log_info (_("key %s: secret key imported\n"),
+                      keystr_from_pk_with_sub (main_pk, pk));
+          stats->secret_imported++;
+        }
+      else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
+        {
+          if (opt.verbose)
+            log_info (_("key %s: secret key already exists\n"),
+                      keystr_from_pk_with_sub (main_pk, pk));
+          err = 0;
+          stats->secret_dups++;
+        }
+      else
+        {
+          log_error (_("key %s: error sending to agent: %s\n"),
+                     keystr_from_pk_with_sub (main_pk, pk),
+                     gpg_strerror (err));
+          if (gpg_err_code (err) == GPG_ERR_CANCELED
+              || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+            break; /* Don't try the other subkeys.  */
+        }
+    }
 
-         pubnode=new_kbnode(pkt);
+ leave:
+  gcry_sexp_release (curve);
+  xfree (cache_nonce);
+  xfree (wrappedkey);
+  xfree (transferkey);
+  gcry_cipher_close (cipherhd);
+  xfree (kek);
+  return err;
+}
+
+
+/* Walk a secret keyblock and produce a public keyblock out of it.
+   Returns a new node or NULL on error. */
+static kbnode_t
+sec_to_pub_keyblock (kbnode_t sec_keyblock)
+{
+  kbnode_t pub_keyblock = NULL;
+  kbnode_t ctx = NULL;
+  kbnode_t secnode, pubnode;
+
+  while ((secnode = walk_kbnode (sec_keyblock, &ctx, 0)))
+    {
+      if (secnode->pkt->pkttype == PKT_SECRET_KEY
+          || secnode->pkt->pkttype == PKT_SECRET_SUBKEY)
+       {
+         /* Make a public key.  */
+         PACKET *pkt;
+          PKT_public_key *pk;
+
+         pkt = xtrycalloc (1, sizeof *pkt);
+          pk = pkt? copy_public_key (NULL, secnode->pkt->pkt.public_key): NULL;
+          if (!pk)
+            {
+              xfree (pkt);
+             release_kbnode (pub_keyblock);
+              return NULL;
+            }
+         if (secnode->pkt->pkttype == PKT_SECRET_KEY)
+           pkt->pkttype = PKT_PUBLIC_KEY;
+         else
+           pkt->pkttype = PKT_PUBLIC_SUBKEY;
+         pkt->pkt.public_key = pk;
+
+         pubnode = new_kbnode (pkt);
        }
       else
        {
-         pubnode=clone_kbnode(secnode);
+         pubnode = clone_kbnode (secnode);
        }
 
-      if(pub_keyblock==NULL)
-       pub_keyblock=pubnode;
+      if (!pub_keyblock)
+       pub_keyblock = pubnode;
       else
-       add_kbnode(pub_keyblock,pubnode);
+       add_kbnode (pub_keyblock, pubnode);
     }
 
   return pub_keyblock;
@@ -1205,141 +1531,148 @@ sec_to_pub_keyblock(KBNODE sec_keyblock)
  * with the trust calculation.
  */
 static int
-import_secret_one (const char *fname, KBNODE keyblock,
-                   struct stats_s *stats, unsigned int options,
-                   import_filter_t filter, void *filter_arg)
+import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
+                   struct stats_s *stats, int batch, unsigned int options,
+                   int for_migration,
+                   import_screener_t screener, void *screener_arg)
 {
-    PKT_secret_key *sk;
-    KBNODE node, uidnode;
-    u32 keyid[2];
-    int rc = 0;
+  PKT_public_key *pk;
+  struct seckey_info *ski;
+  KBNODE node, uidnode;
+  u32 keyid[2];
+  int rc = 0;
+  int nr_prev;
+  kbnode_t pub_keyblock;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
-    /* Get the key and print some info about it. */
-    node = find_kbnode( keyblock, PKT_SECRET_KEY );
-    if( !node )
-       BUG();
+  /* Get the key and print some info about it */
+  node = find_kbnode (keyblock, PKT_SECRET_KEY);
+  if (!node)
+    BUG ();
 
-    sk = node->pkt->pkt.secret_key;
-    keyid_from_sk( sk, keyid );
-    uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
+  pk = node->pkt->pkt.public_key;
 
-    if (filter && filter (keyblock, filter_arg)) {
-        log_error (_("secret key %s: %s\n"), keystr_from_sk(sk),
-                   _("rejected by import filter"));
-        return 0;
-    }
+  keyid_from_pk (pk, keyid);
+  uidnode = find_next_kbnode (keyblock, PKT_USER_ID);
 
-    if( opt.verbose )
-      {
-       log_info( "sec  %4u%c/%s %s   ",
-                 nbits_from_sk( sk ),
-                 pubkey_letter( sk->pubkey_algo ),
-                 keystr_from_sk(sk), datestr_from_sk(sk) );
-       if( uidnode )
-         print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
-                            uidnode->pkt->pkt.user_id->len );
-       log_printf ("\n");
-      }
-    stats->secret_read++;
+  if (screener && screener (keyblock, screener_arg))
+    {
+      log_error (_("secret key %s: %s\n"), keystr_from_pk (pk),
+                 _("rejected by import screener"));
+      return 0;
+  }
 
-    if ((options & IMPORT_NO_SECKEY))
-      {
+  if (opt.verbose && !for_migration)
+    {
+      log_info ("sec  %s/%s %s   ",
+                pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                keystr_from_pk (pk), datestr_from_pk (pk));
+      if (uidnode)
+        print_utf8_buffer (log_get_stream (), uidnode->pkt->pkt.user_id->name,
+                           uidnode->pkt->pkt.user_id->len);
+      log_printf ("\n");
+    }
+  stats->secret_read++;
+
+  if ((options & IMPORT_NO_SECKEY))
+    {
+      if (!for_migration)
         log_error (_("importing secret keys not allowed\n"));
-        return 0;
-      }
+      return 0;
+    }
 
-    if( !uidnode )
-      {
-       log_error( _("key %s: no user ID\n"), keystr_from_sk(sk));
-       return 0;
-      }
+  if (!uidnode)
+    {
+      if (!for_migration)
+        log_error( _("key %s: no user ID\n"), keystr_from_pk (pk));
+      return 0;
+    }
 
-    if(sk->protect.algo>110)
-      {
-       log_error(_("key %s: secret key with invalid cipher %d"
-                   " - skipped\n"),keystr_from_sk(sk),sk->protect.algo);
-       return 0;
-      }
+  ski = pk->seckey_info;
+  if (!ski)
+    {
+      /* Actually an internal error.  */
+      log_error ("key %s: secret key info missing\n", keystr_from_pk (pk));
+      return 0;
+    }
+
+  /* A quick check to not import keys with an invalid protection
+     cipher algorithm (only checks the primary key, though).  */
+  if (ski->algo > 110)
+    {
+      if (!for_migration)
+        log_error (_("key %s: secret key with invalid cipher %d"
+                     " - skipped\n"), keystr_from_pk (pk), ski->algo);
+      return 0;
+    }
 
 #ifdef ENABLE_SELINUX_HACKS
-    if (1)
-      {
-        /* We don't allow to import secret keys because that may be used
-           to put a secret key into the keyring and the user might later
-           be tricked into signing stuff with that key.  */
-        log_error (_("importing secret keys not allowed\n"));
-        return 0;
-      }
+  if (1)
+    {
+      /* We don't allow to import secret keys because that may be used
+         to put a secret key into the keyring and the user might later
+         be tricked into signing stuff with that key.  */
+      log_error (_("importing secret keys not allowed\n"));
+      return 0;
+    }
 #endif
 
-    clear_kbnode_flags( keyblock );
-
-    /* do we have this key already in one of our secrings ? */
-    rc = seckey_available( keyid );
-    if( rc == G10ERR_NO_SECKEY && !(opt.import_options&IMPORT_MERGE_ONLY) )
-      {
-       /* simply insert this key */
-        KEYDB_HANDLE hd = keydb_new (1);
-
-       /* get default resource */
-        rc = keydb_locate_writable (hd, NULL);
-       if (rc) {
-         log_error (_("no default secret keyring: %s\n"), g10_errstr (rc));
-         keydb_release (hd);
-         return G10ERR_GENERAL;
-       }
-       rc = keydb_insert_keyblock (hd, keyblock );
-        if (rc)
-         log_error (_("error writing keyring `%s': %s\n"),
-                    keydb_get_resource_name (hd), g10_errstr(rc) );
-        keydb_release (hd);
-       /* we are ready */
-       if( !opt.quiet )
-         log_info( _("key %s: secret key imported\n"), keystr_from_sk(sk));
-       stats->secret_imported++;
-        if (is_status_enabled ())
-         print_import_ok (NULL, sk, 1|16);
+  clear_kbnode_flags (keyblock);
 
-       if(options&IMPORT_SK2PK)
-         {
-           /* Try and make a public key out of this. */
+  nr_prev = stats->skipped_new_keys;
 
-           KBNODE pub_keyblock=sec_to_pub_keyblock(keyblock);
-           if(pub_keyblock)
-             {
-               import_one (fname, pub_keyblock, stats,
-                            NULL, NULL, opt.import_options, 1,
-                            NULL, NULL);
-               release_kbnode(pub_keyblock);
-             }
-         }
-
-       /* Now that the key is definitely incorporated into the keydb,
-          if we have the public part of this key, we need to check if
-          the prefs are rational. */
-       node=get_pubkeyblock(keyid);
-       if(node)
-         {
-           check_prefs(node);
-           release_kbnode(node);
-         }
-      }
-    else if( !rc )
-      { /* we can't merge secret keys */
-       log_error( _("key %s: already in secret keyring\n"),
-                  keystr_from_sk(sk));
-       stats->secret_dups++;
-        if (is_status_enabled ())
-         print_import_ok (NULL, sk, 16);
-
-       /* TODO: if we ever do merge secret keys, make sure to handle
-          the sec_to_pub_keyblock feature as well. */
-      }
-    else
-      log_error( _("key %s: secret key not found: %s\n"),
-                keystr_from_sk(sk), g10_errstr(rc));
+  /* Make a public key out of the key. */
+  pub_keyblock = sec_to_pub_keyblock (keyblock);
+  if (!pub_keyblock)
+    log_error ("key %s: failed to create public key from secret key\n",
+                   keystr_from_pk (pk));
+  else
+    {
+      /* Note that this outputs an IMPORT_OK status message for the
+        public key block, and below we will output another one for
+        the secret keys.  FIXME?  */
+      import_one (ctrl, fname, pub_keyblock, stats,
+                 NULL, NULL, options, 1, for_migration,
+                  screener, screener_arg);
+
+      /* Fixme: We should check for an invalid keyblock and
+        cancel the secret key import in this case.  */
+      release_kbnode (pub_keyblock);
+
+      /* At least we cancel the secret key import when the public key
+        import was skipped due to MERGE_ONLY option and a new
+        key.  */
+      if (stats->skipped_new_keys <= nr_prev)
+       {
+          /* Read the keyblock again to get the effects of a merge.  */
+          /* Fixme: we should do this based on the fingerprint or
+             even better let import_one return the merged
+             keyblock.  */
+          node = get_pubkeyblock (keyid);
+          if (!node)
+            log_error ("key %s: failed to re-lookup public key\n",
+                       keystr_from_pk (pk));
+          else
+            {
+             nr_prev = stats->secret_imported;
+              if (!transfer_secret_keys (ctrl, stats, keyblock, batch))
+                {
+                 int status = 16;
+                  if (!opt.quiet)
+                    log_info (_("key %s: secret key imported\n"),
+                              keystr_from_pk (pk));
+                 if (stats->secret_imported > nr_prev)
+                   status |= 1;
+                  if (is_status_enabled ())
+                    print_import_ok (pk, status);
+                  check_prefs (ctrl, node);
+                }
+              release_kbnode (node);
+            }
+        }
+    }
 
-    return rc;
+  return rc;
 }
 
 
@@ -1381,7 +1714,7 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
       }
 
     /* read the original keyblock */
-    hd = keydb_new (0);
+    hd = keydb_new ();
     {
         byte afp[MAX_FINGERPRINT_LEN];
         size_t an;
@@ -1436,7 +1769,7 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
     /* and write the keyblock back */
     rc = keydb_update_keyblock (hd, keyblock );
     if (rc)
-       log_error (_("error writing keyring `%s': %s\n"),
+       log_error (_("error writing keyring '%s': %s\n"),
                    keydb_get_resource_name (hd), g10_errstr(rc) );
     keydb_release (hd); hd = NULL;
     /* we are ready */
@@ -1475,14 +1808,14 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
  * in this keyblock.
  */
 static int
-chk_self_sigs( const char *fname, KBNODE keyblock,
+chk_self_sigs (const char *fname, kbnode_t keyblock,
               PKT_public_key *pk, u32 *keyid, int *non_self )
 {
-  KBNODE n, knode = NULL;
+  kbnode_t n, knode = NULL;
   PKT_signature *sig;
   int rc;
-  u32 bsdate=0,rsdate=0;
-  KBNODE bsnode = NULL, rsnode = NULL;
+  u32 bsdate=0, rsdate=0;
+  kbnode_t bsnode = NULL, rsnode = NULL;
 
   (void)fname;
   (void)pk;
@@ -1666,6 +1999,7 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
   return 0;
 }
 
+
 /****************
  * delete all parts which are invalid and those signatures whose
  * public key algorithm is not available in this implemenation;
@@ -1731,7 +2065,7 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
        else if( node->pkt->pkttype == PKT_SIGNATURE &&
                 !node->pkt->pkt.signature->flags.exportable &&
                 !(options&IMPORT_LOCAL_SIGS) &&
-                seckey_available( node->pkt->pkt.signature->keyid ) )
+                !have_secret_key_with_kid (node->pkt->pkt.signature->keyid))
          {
            /* here we violate the rfc a bit by still allowing
             * to import non-exportable signature when we have the
@@ -1911,12 +2245,12 @@ collapse_uids( KBNODE *keyblock )
     {
       const char *key="???";
 
-      if( (uid1=find_kbnode( *keyblock, PKT_PUBLIC_KEY )) )
-       key=keystr_from_pk(uid1->pkt->pkt.public_key);
-      else if( (uid1 = find_kbnode( *keyblock, PKT_SECRET_KEY )) )
-       key=keystr_from_sk(uid1->pkt->pkt.secret_key);
+      if ((uid1 = find_kbnode (*keyblock, PKT_PUBLIC_KEY)) )
+       key = keystr_from_pk (uid1->pkt->pkt.public_key);
+      else if ((uid1 = find_kbnode( *keyblock, PKT_SECRET_KEY)) )
+       key = keystr_from_pk (uid1->pkt->pkt.public_key);
 
-      log_info(_("key %s: duplicated user ID detected - merged\n"),key);
+      log_info (_("key %s: duplicated user ID detected - merged\n"), key);
     }
 
   return any;
@@ -1926,10 +2260,10 @@ collapse_uids( KBNODE *keyblock )
    present.  This may be called without the benefit of merge_xxxx so
    you can't rely on pk->revkey and friends. */
 static void
-revocation_present(KBNODE keyblock)
+revocation_present (ctrl_t ctrl, kbnode_t keyblock)
 {
-  KBNODE onode,inode;
-  PKT_public_key *pk=keyblock->pkt->pkt.public_key;
+  kbnode_t onode, inode;
+  PKT_public_key *pk = keyblock->pkt->pkt.public_key;
 
   for(onode=keyblock->next;onode;onode=onode->next)
     {
@@ -1981,9 +2315,10 @@ revocation_present(KBNODE keyblock)
                              log_info(_("WARNING: key %s may be revoked:"
                                         " fetching revocation key %s\n"),
                                       tempkeystr,keystr(keyid));
-                             keyserver_import_fprint(sig->revkey[idx]->fpr,
-                                                     MAX_FINGERPRINT_LEN,
-                                                     opt.keyserver);
+                             keyserver_import_fprint (ctrl,
+                                                       sig->revkey[idx]->fpr,
+                                                       MAX_FINGERPRINT_LEN,
+                                                       opt.keyserver);
 
                              /* Do we have it now? */
                              rc=get_pubkey_byfprint_fast (NULL,
@@ -2147,8 +2482,8 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
            /* do we have this in the original keyblock? */
            for(onode=keyblock_orig->next; onode; onode=onode->next )
                if( onode->pkt->pkttype == PKT_SECRET_SUBKEY
-                   && !cmp_secret_keys( onode->pkt->pkt.secret_key,
-                                        node->pkt->pkt.secret_key ) )
+                   && !cmp_public_keys (onode->pkt->pkt.public_key,
+                                        node->pkt->pkt.public_key) )
                    break;
            if( !onode ) { /* this is a new subkey: append */
                rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
@@ -2166,14 +2501,11 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
                 || onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
            /* find the subkey in the imported keyblock */
            for(node=keyblock->next; node; node=node->next ) {
-               if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                     || node->pkt->pkttype == PKT_SECRET_SUBKEY)
                    && !cmp_public_keys( onode->pkt->pkt.public_key,
                                          node->pkt->pkt.public_key ) )
                    break;
-               else if( node->pkt->pkttype == PKT_SECRET_SUBKEY
-                   && !cmp_secret_keys( onode->pkt->pkt.secret_key,
-                                         node->pkt->pkt.secret_key ) )
-                   break;
            }
            if( node ) { /* found: merge */
                rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
@@ -2336,8 +2668,9 @@ merge_keysigs (KBNODE dst, KBNODE src, int *n_sigs,
     return 0;
 }
 
-/****************
- * append the subkey starting with NODE and all signatures to KEYBLOCK.
+
+/*
+ * Append the subkey starting with NODE and all signatures to KEYBLOCK.
  * Mark all new and copied packets by setting flag bit 0.
  */
 static int
@@ -2369,232 +2702,3 @@ append_key (KBNODE keyblock, KBNODE node, int *n_sigs,
 
     return 0;
 }
-
-
-
-/* Walk a public keyblock and produce a secret keyblock out of it.
-   Instead of inserting the secret key parameters (which we don't
-   have), we insert a stub.  */
-static KBNODE
-pub_to_sec_keyblock (KBNODE pub_keyblock)
-{
-  KBNODE pubnode, secnode;
-  KBNODE sec_keyblock = NULL;
-  KBNODE walkctx = NULL;
-
-  while((pubnode = walk_kbnode (pub_keyblock,&walkctx,0)))
-    {
-      if (pubnode->pkt->pkttype == PKT_PUBLIC_KEY
-          || pubnode->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-       {
-         /* Make a secret key.  We only need to convert enough to
-            write the keyblock out. */
-         PKT_public_key *pk = pubnode->pkt->pkt.public_key;
-         PACKET *pkt = xmalloc_clear (sizeof *pkt);
-         PKT_secret_key *sk = xmalloc_clear (sizeof *sk);
-          int i, n;
-
-          if (pubnode->pkt->pkttype == PKT_PUBLIC_KEY)
-           pkt->pkttype = PKT_SECRET_KEY;
-         else
-           pkt->pkttype = PKT_SECRET_SUBKEY;
-
-         pkt->pkt.secret_key = sk;
-
-          copy_public_parts_to_secret_key ( pk, sk );
-         sk->version     = pk->version;
-         sk->timestamp   = pk->timestamp;
-
-          n = pubkey_get_npkey (pk->pubkey_algo);
-          if (!n)
-            n = 1; /* Unknown number of parameters, however the data
-                      is stored in the first mpi. */
-          for (i=0; i < n; i++ )
-            sk->skey[i] = mpi_copy (pk->pkey[i]);
-
-          sk->is_protected = 1;
-          sk->protect.s2k.mode = 1001;
-
-         secnode = new_kbnode (pkt);
-        }
-      else
-       {
-         secnode = clone_kbnode (pubnode);
-       }
-
-      if(!sec_keyblock)
-       sec_keyblock = secnode;
-      else
-       add_kbnode (sec_keyblock, secnode);
-    }
-
-  return sec_keyblock;
-}
-
-
-/* Walk over the secret keyring SEC_KEYBLOCK and update any simple
-   stub keys with the serial number SNNUM of the card if one of the
-   fingerprints FPR1, FPR2 or FPR3 match.  Print a note if the key is
-   a duplicate (may happen in case of backed uped keys).
-
-   Returns: True if anything changed.
-*/
-static int
-update_sec_keyblock_with_cardinfo (KBNODE sec_keyblock,
-                                   const unsigned char *fpr1,
-                                   const unsigned char *fpr2,
-                                   const unsigned char *fpr3,
-                                   const char *serialnostr)
-{
-  KBNODE node;
-  KBNODE walkctx = NULL;
-  PKT_secret_key *sk;
-  byte array[MAX_FINGERPRINT_LEN];
-  size_t n;
-  int result = 0;
-  const char *s;
-
-  while((node = walk_kbnode (sec_keyblock, &walkctx, 0)))
-    {
-      if (node->pkt->pkttype != PKT_SECRET_KEY
-          && node->pkt->pkttype != PKT_SECRET_SUBKEY)
-        continue;
-      sk = node->pkt->pkt.secret_key;
-
-      fingerprint_from_sk (sk, array, &n);
-      if (n != 20)
-        continue; /* Can't be a card key.  */
-      if ( !((fpr1 && !memcmp (array, fpr1, 20))
-             || (fpr2 && !memcmp (array, fpr2, 20))
-             || (fpr3 && !memcmp (array, fpr3, 20))) )
-        continue;  /* No match.  */
-
-      if (sk->is_protected == 1 && sk->protect.s2k.mode == 1001)
-        {
-          /* Standard case: migrate that stub to a key stub.  */
-          sk->protect.s2k.mode = 1002;
-          s = serialnostr;
-          for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
-               sk->protect.ivlen++, s += 2)
-            sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
-          result = 1;
-        }
-      else if (sk->is_protected == 1 && sk->protect.s2k.mode == 1002)
-        {
-          s = serialnostr;
-          for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
-               sk->protect.ivlen++, s += 2)
-            if (sk->protect.iv[sk->protect.ivlen] != xtoi_2 (s))
-              {
-                log_info (_("NOTE: a key's S/N does not "
-                            "match the card's one\n"));
-                break;
-              }
-        }
-      else
-        {
-          if (node->pkt->pkttype != PKT_SECRET_KEY)
-            log_info (_("NOTE: primary key is online and stored on card\n"));
-          else
-            log_info (_("NOTE: secondary key is online and stored on card\n"));
-        }
-    }
-
-  return result;
-}
-
-
-
-/* Check whether a secret key stub exists for the public key PK.  If
-   not create such a stub key and store it into the secring.  If it
-   exists, add appropriate subkey stubs and update the secring.
-   Return 0 if the key could be created. */
-int
-auto_create_card_key_stub ( const char *serialnostr,
-                            const unsigned char *fpr1,
-                            const unsigned char *fpr2,
-                            const unsigned char *fpr3)
-{
-  KBNODE pub_keyblock;
-  KBNODE sec_keyblock;
-  KEYDB_HANDLE hd;
-  int rc;
-
-  /* We only want to do this for an OpenPGP card.  */
-  if (!serialnostr || strncmp (serialnostr, "D27600012401", 12)
-      || strlen (serialnostr) != 32 )
-    return G10ERR_GENERAL;
-
-  /* First get the public keyring from any of the provided fingerprints. */
-  if ( (fpr1 && !get_keyblock_byfprint (&pub_keyblock, fpr1, 20))
-       || (fpr2 && !get_keyblock_byfprint (&pub_keyblock, fpr2, 20))
-       || (fpr3 && !get_keyblock_byfprint (&pub_keyblock, fpr3, 20)))
-    ;
-  else
-    return G10ERR_GENERAL;
-
-  hd = keydb_new (1);
-
-  /* Now check whether there is a secret keyring.  */
-  {
-    PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
-    byte afp[MAX_FINGERPRINT_LEN];
-    size_t an;
-
-    fingerprint_from_pk (pk, afp, &an);
-    if (an < MAX_FINGERPRINT_LEN)
-      memset (afp+an, 0, MAX_FINGERPRINT_LEN-an);
-    rc = keydb_search_fpr (hd, afp);
-  }
-
-  if (!rc)
-    {
-      rc = keydb_get_keyblock (hd, &sec_keyblock);
-      if (rc)
-        {
-          log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
-          rc = G10ERR_GENERAL;
-        }
-      else
-        {
-          merge_keys_and_selfsig (sec_keyblock);
-
-          /* FIXME: We need to add new subkeys first.  */
-          if (update_sec_keyblock_with_cardinfo (sec_keyblock,
-                                                 fpr1, fpr2, fpr3,
-                                                 serialnostr))
-            {
-              rc = keydb_update_keyblock (hd, sec_keyblock );
-              if (rc)
-                log_error (_("error writing keyring `%s': %s\n"),
-                           keydb_get_resource_name (hd), g10_errstr(rc) );
-            }
-        }
-    }
-  else  /* A secret key does not exists - create it.  */
-    {
-      sec_keyblock = pub_to_sec_keyblock (pub_keyblock);
-      update_sec_keyblock_with_cardinfo (sec_keyblock,
-                                         fpr1, fpr2, fpr3,
-                                         serialnostr);
-
-      rc = keydb_locate_writable (hd, NULL);
-      if (rc)
-        {
-          log_error (_("no default secret keyring: %s\n"), g10_errstr (rc));
-          rc = G10ERR_GENERAL;
-        }
-      else
-        {
-          rc = keydb_insert_keyblock (hd, sec_keyblock );
-          if (rc)
-            log_error (_("error writing keyring `%s': %s\n"),
-                       keydb_get_resource_name (hd), g10_errstr(rc) );
-        }
-    }
-
-  release_kbnode (sec_keyblock);
-  release_kbnode (pub_keyblock);
-  keydb_release (hd);
-  return rc;
-}
index 3d7d9be..ad66f8a 100644 (file)
@@ -1,6 +1,6 @@
 /* kbnode.c -  keyblock node utility functions
  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- *               2005 Free Software Foundation, Inc.
+ *               2005, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 
 #include "gpg.h"
 #include "util.h"
+#include "../common/init.h"
 #include "packet.h"
 #include "keydb.h"
 
 #define USE_UNUSED_NODES 1
 
+static int cleanup_registered;
 static KBNODE unused_nodes;
 
-static KBNODE
-alloc_node(void)
+#if USE_UNUSED_NODES
+static void
+release_unused_nodes (void)
 {
-    KBNODE n;
+  while (unused_nodes)
+    {
+      kbnode_t next = unused_nodes->next;
+      xfree (unused_nodes);
+      unused_nodes = next;
+    }
+}
+#endif /*USE_UNUSED_NODES*/
 
-    n = unused_nodes;
-    if( n )
-       unused_nodes = n->next;
-    else
-       n = xmalloc( sizeof *n );
-    n->next = NULL;
-    n->pkt = NULL;
-    n->flag = 0;
-    n->private_flag=0;
-    n->recno = 0;
-    return n;
+
+static kbnode_t
+alloc_node (void)
+{
+  kbnode_t n;
+
+  n = unused_nodes;
+  if (n)
+    unused_nodes = n->next;
+  else
+    {
+      if (!cleanup_registered)
+        {
+          cleanup_registered = 1;
+          register_mem_cleanup_func (release_unused_nodes);
+        }
+      n = xmalloc (sizeof *n);
+    }
+  n->next = NULL;
+  n->pkt = NULL;
+  n->flag = 0;
+  n->private_flag=0;
+  n->recno = 0;
+  return n;
 }
 
 static void
 free_node( KBNODE n )
 {
-    if( n ) {
+  if (n)
+    {
 #if USE_UNUSED_NODES
-       n->next = unused_nodes;
-       unused_nodes = n;
+      n->next = unused_nodes;
+      unused_nodes = n;
 #else
-       xfree( n );
+      xfree (n);
 #endif
     }
 }
@@ -184,7 +208,7 @@ find_next_kbnode( KBNODE node, int pkttype )
     for( node=node->next ; node; node = node->next ) {
        if( !pkttype )
            return node;
-       else if( pkttype == PKT_USER_ID 
+       else if( pkttype == PKT_USER_ID
                 && (   node->pkt->pkttype == PKT_PUBLIC_KEY
                     || node->pkt->pkttype == PKT_SECRET_KEY ) )
            return NULL;
@@ -336,63 +360,71 @@ move_kbnode( KBNODE *root, KBNODE node, KBNODE where )
 
 
 void
-dump_kbnode( KBNODE node )
+dump_kbnode (KBNODE node)
 {
-    for(; node; node = node->next ) {
-       const char *s;
-       switch( node->pkt->pkttype ) {
-         case 0:               s="empty"; break;
-         case PKT_PUBLIC_KEY:  s="public-key"; break;
-         case PKT_SECRET_KEY:  s="secret-key"; break;
-         case PKT_SECRET_SUBKEY: s= "secret-subkey"; break;
-         case PKT_PUBKEY_ENC:  s="public-enc"; break;
-         case PKT_SIGNATURE:   s="signature"; break;
-         case PKT_ONEPASS_SIG: s="onepass-sig"; break;
-         case PKT_USER_ID:     s="user-id"; break;
-         case PKT_PUBLIC_SUBKEY: s="public-subkey"; break;
-         case PKT_COMMENT:     s="comment"; break;
-         case PKT_RING_TRUST:  s="trust"; break;
-         case PKT_PLAINTEXT:   s="plaintext"; break;
-         case PKT_COMPRESSED:  s="compressed"; break;
-         case PKT_ENCRYPTED:   s="encrypted"; break;
-          case PKT_GPG_CONTROL: s="gpg-control"; break;
-         default:              s="unknown"; break;
-       }
-       fprintf(stderr, "node %p %02x/%02x type=%s",
-               node, node->flag, node->private_flag, s);
-       if( node->pkt->pkttype == PKT_USER_ID ) {
-            PKT_user_id *uid = node->pkt->pkt.user_id;
-           fputs("  \"", stderr);
-           print_string( stderr, uid->name, uid->len, 0 );
-           fprintf (stderr, "\" %c%c%c%c\n",
-                     uid->is_expired? 'e':'.',
-                     uid->is_revoked? 'r':'.',
-                     uid->created?    'v':'.',
-                     uid->is_primary? 'p':'.' );
-       }
-       else if( node->pkt->pkttype == PKT_SIGNATURE ) {
-           fprintf(stderr, "  class=%02x keyid=%08lX ts=%lu\n",
-                  node->pkt->pkt.signature->sig_class,
-                  (ulong)node->pkt->pkt.signature->keyid[1],
-                   (ulong)node->pkt->pkt.signature->timestamp);
+  for (; node; node = node->next )
+    {
+      const char *s;
+      switch (node->pkt->pkttype)
+        {
+        case 0:                s="empty"; break;
+        case PKT_PUBLIC_KEY:   s="public-key"; break;
+        case PKT_SECRET_KEY:   s="secret-key"; break;
+        case PKT_SECRET_SUBKEY: s= "secret-subkey"; break;
+        case PKT_PUBKEY_ENC:   s="public-enc"; break;
+        case PKT_SIGNATURE:    s="signature"; break;
+        case PKT_ONEPASS_SIG: s="onepass-sig"; break;
+        case PKT_USER_ID:      s="user-id"; break;
+        case PKT_PUBLIC_SUBKEY: s="public-subkey"; break;
+        case PKT_COMMENT:      s="comment"; break;
+        case PKT_RING_TRUST:   s="trust"; break;
+        case PKT_PLAINTEXT:    s="plaintext"; break;
+        case PKT_COMPRESSED:   s="compressed"; break;
+        case PKT_ENCRYPTED:    s="encrypted"; break;
+        case PKT_GPG_CONTROL: s="gpg-control"; break;
+        default:               s="unknown"; break;
        }
-       else if( node->pkt->pkttype == PKT_GPG_CONTROL ) {
-           fprintf(stderr, " ctrl=%d len=%u\n",
-                    node->pkt->pkt.gpg_control->control,
-                    (unsigned int)node->pkt->pkt.gpg_control->datalen);
-       }
-       else if( node->pkt->pkttype == PKT_PUBLIC_KEY
-                || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-            PKT_public_key *pk = node->pkt->pkt.public_key;
-           fprintf(stderr, "  keyid=%08lX a=%d u=%d %c%c%c%c\n",
-                    (ulong)keyid_from_pk( pk, NULL ),
-                    pk->pubkey_algo, pk->pubkey_usage,
-                    pk->has_expired? 'e':'.',  
-                    pk->is_revoked?  'r':'.',  
-                    pk->is_valid?    'v':'.',
-                    pk->mdc_feature? 'm':'.');
-       }
-       else
-           fputs("\n", stderr);
+      log_debug ("node %p %02x/%02x type=%s",
+                 node, node->flag, node->private_flag, s);
+      if (node->pkt->pkttype == PKT_USER_ID)
+        {
+          PKT_user_id *uid = node->pkt->pkt.user_id;
+          log_printf ("  \"");
+          es_write_sanitized (log_get_stream (), uid->name, uid->len,
+                              NULL, NULL);
+          log_printf ("\" %c%c%c%c\n",
+                      uid->is_expired? 'e':'.',
+                      uid->is_revoked? 'r':'.',
+                      uid->created?    'v':'.',
+                      uid->is_primary? 'p':'.' );
+        }
+      else if (node->pkt->pkttype == PKT_SIGNATURE)
+        {
+          log_printf ("  class=%02x keyid=%08lX ts=%lu\n",
+                      node->pkt->pkt.signature->sig_class,
+                      (ulong)node->pkt->pkt.signature->keyid[1],
+                      (ulong)node->pkt->pkt.signature->timestamp);
+        }
+      else if (node->pkt->pkttype == PKT_GPG_CONTROL)
+        {
+          log_printf (" ctrl=%d len=%u\n",
+                      node->pkt->pkt.gpg_control->control,
+                      (unsigned int)node->pkt->pkt.gpg_control->datalen);
+        }
+      else if (node->pkt->pkttype == PKT_PUBLIC_KEY
+               || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+        {
+          PKT_public_key *pk = node->pkt->pkt.public_key;
+
+          log_printf ("  keyid=%08lX a=%d u=%d %c%c%c%c\n",
+                      (ulong)keyid_from_pk( pk, NULL ),
+                      pk->pubkey_algo, pk->pubkey_usage,
+                      pk->has_expired? 'e':'.',
+                      pk->flags.revoked? 'r':'.',
+                      pk->flags.valid?    'v':'.',
+                      pk->flags.mdc?   'm':'.');
+        }
+
+      log_flush ();
     }
 }
index 450ada7..bafae18 100644 (file)
@@ -1,6 +1,7 @@
 /* keydb.c - key database dispatcher
  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- *               2008, 2009, 2012 Free Software Foundation, Inc.
+ *               2008, 2009, 2011, 2013 Free Software Foundation, Inc.
+ * Coyrright (C) 2013 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include "main.h" /*try_make_homedir ()*/
 #include "packet.h"
 #include "keyring.h"
+#include "../kbx/keybox.h"
 #include "keydb.h"
 #include "i18n.h"
 
 static int active_handles;
 
-typedef enum {
+typedef enum
+  {
     KEYDB_RESOURCE_TYPE_NONE = 0,
     KEYDB_RESOURCE_TYPE_KEYRING,
     KEYDB_RESOURCE_TYPE_KEYBOX
-} KeydbResourceType;
+  } KeydbResourceType;
 #define MAX_KEYDB_RESOURCES 40
 
-struct resource_item {
+struct resource_item
+{
   KeydbResourceType type;
   union {
     KEYRING_HANDLE kr;
+    KEYBOX_HANDLE kb;
   } u;
   void *token;
-  int secret;
 };
 
 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
 static int used_resources;
 static void *primary_keyring=NULL;
 
-struct keydb_handle {
+struct keydb_handle
+{
   int locked;
   int found;
+  unsigned long skipped_long_blobs;
+  int no_caching;
   int current;
-  int used; /* items in active */
+  int used;   /* Number of items in ACTIVE. */
   struct resource_item active[MAX_KEYDB_RESOURCES];
 };
 
 
+/* This is a simple cache used to return the last result of a
+   successful fingerprint search.  This works only for keybox resources
+   because (due to lack of a copy_keyblock function) we need to store
+   an image of the keyblock which is fortunately instantly available
+   for keyboxes.  */
+enum keyblock_cache_states {
+  KEYBLOCK_CACHE_EMPTY,
+  KEYBLOCK_CACHE_PREPARED,
+  KEYBLOCK_CACHE_FILLED
+};
+
+struct {
+  enum keyblock_cache_states state;
+  byte fpr[MAX_FINGERPRINT_LEN];
+  iobuf_t iobuf; /* Image of the keyblock.  */
+  u32 *sigstatus;
+  int pk_no;
+  int uid_no;
+} keyblock_cache;
+
+
 static int lock_all (KEYDB_HANDLE hd);
 static void unlock_all (KEYDB_HANDLE hd);
 
 
-/* Handle the creation of a keyring if it does not yet exist.  Take
-   into acount that other processes might have the keyring already
-   locked.  This lock check does not work if the directory itself is
-   not yet available. */
+static void
+keyblock_cache_clear (void)
+{
+  keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
+  xfree (keyblock_cache.sigstatus);
+  keyblock_cache.sigstatus = NULL;
+  iobuf_close (keyblock_cache.iobuf);
+  keyblock_cache.iobuf = NULL;
+}
+
+
+/* Handle the creation of a keyring or a keybox if it does not yet
+   exist.  Take into account that other processes might have the
+   keyring/keybox already locked.  This lock check does not work if
+   the directory itself is not yet available.  If is IS_BOX is true
+   the filename is expected to be a keybox.  If FORCE_CREATE is true
+   the keyring or keybox shall be created.  */
 static int
-maybe_create_keyring (char *filename, int force)
+maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
 {
-  DOTLOCK lockhd = NULL;
+  dotlock_t lockhd = NULL;
   IOBUF iobuf;
   int rc;
   mode_t oldmask;
@@ -92,14 +133,14 @@ maybe_create_keyring (char *filename, int force)
 
   /* If we don't want to create a new file at all, there is no need to
      go any further - bail out right here.  */
-  if (!force)
+  if (!force_create)
     return gpg_error (GPG_ERR_ENOENT);
 
   /* First of all we try to create the home directory.  Note, that we
      don't do any locking here because any sane application of gpg
      would create the home directory by itself and not rely on gpg's
-     tricky auto-creation which is anyway only done for some home
-     directory name patterns. */
+     tricky auto-creation which is anyway only done for certain home
+     directory name pattern. */
   last_slash_in_filename = strrchr (filename, DIRSEP_C);
 #if HAVE_W32_SYSTEM
   {
@@ -135,32 +176,34 @@ maybe_create_keyring (char *filename, int force)
   /* To avoid races with other instances of gpg trying to create or
      update the keyring (it is removed during an update for a short
      time), we do the next stuff in a locked state. */
-  lockhd = create_dotlock (filename);
+  lockhd = dotlock_create (filename, 0);
   if (!lockhd)
     {
+      rc = gpg_error_from_syserror ();
       /* A reason for this to fail is that the directory is not
          writable. However, this whole locking stuff does not make
          sense if this is the case. An empty non-writable directory
          with no keyring is not really useful at all. */
       if (opt.verbose)
-        log_info ("can't allocate lock for `%s'\n", filename );
+        log_info ("can't allocate lock for '%s': %s\n",
+                  filename, gpg_strerror (rc));
 
-      if (!force)
-        return gpg_error (GPG_ERR_ENOENT);
+      if (!force_create)
+        return gpg_error (GPG_ERR_ENOENT);  /* Won't happen.  */
       else
-        return gpg_error (GPG_ERR_GENERAL);
+        return rc;
     }
 
-  if ( make_dotlock (lockhd, -1) )
+  if ( dotlock_take (lockhd, -1) )
     {
+      rc = gpg_error_from_syserror ();
       /* This is something bad.  Probably a stale lockfile.  */
-      log_info ("can't lock `%s'\n", filename );
-      rc = G10ERR_GENERAL;
+      log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc));
       goto leave;
     }
 
   /* Now the real test while we are locked. */
-  if (!access(filename, F_OK))
+  if (!access (filename, F_OK))
     {
       rc = 0;  /* Okay, we may access the file now.  */
       goto leave;
@@ -171,230 +214,355 @@ maybe_create_keyring (char *filename, int force)
   if (is_secured_filename (filename))
     {
       iobuf = NULL;
-      errno = EPERM;
+      gpg_err_set_errno (EPERM);
     }
   else
-    iobuf = iobuf_create (filename);
+    iobuf = iobuf_create (filename, 0);
   umask (oldmask);
   if (!iobuf)
     {
       rc = gpg_error_from_syserror ();
-      log_error ( _("error creating keyring `%s': %s\n"),
-                  filename, strerror(errno));
+      if (is_box)
+        log_error (_("error creating keybox '%s': %s\n"),
+                   filename, gpg_strerror (rc));
+      else
+        log_error (_("error creating keyring '%s': %s\n"),
+                   filename, gpg_strerror (rc));
       goto leave;
     }
 
-  if (!opt.quiet)
-    log_info (_("keyring `%s' created\n"), filename);
-
   iobuf_close (iobuf);
   /* Must invalidate that ugly cache */
-  iobuf_ioctl (NULL, 2, 0, filename);
+  iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename);
+
+  /* Make sure that at least one record is in a new keybox file, so
+     that the detection magic will work the next time it is used.  */
+  if (is_box)
+    {
+      FILE *fp = fopen (filename, "w");
+      if (!fp)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = _keybox_write_header_blob (fp, 1);
+          fclose (fp);
+        }
+      if (rc)
+        {
+          if (is_box)
+            log_error (_("error creating keybox '%s': %s\n"),
+                       filename, gpg_strerror (rc));
+          else
+            log_error (_("error creating keyring '%s': %s\n"),
+                       filename, gpg_strerror (rc));
+          goto leave;
+        }
+    }
+
+  if (!opt.quiet)
+    {
+      if (is_box)
+        log_info (_("keybox '%s' created\n"), filename);
+      else
+        log_info (_("keyring '%s' created\n"), filename);
+    }
+
   rc = 0;
 
  leave:
   if (lockhd)
     {
-      release_dotlock (lockhd);
-      destroy_dotlock (lockhd);
+      dotlock_release (lockhd);
+      dotlock_destroy (lockhd);
     }
   return rc;
 }
 
 
+/* Helper for keydb_add_resource.  Opens FILENAME to figures out the
+   resource type.  Returns the resource type and a flag at R_NOTFOUND
+   indicating whether FILENAME could be opened at all.  If the openpgp
+   flag is set in a keybox header, R_OPENPGP will be set to true.  */
+static KeydbResourceType
+rt_from_file (const char *filename, int *r_found, int *r_openpgp)
+{
+  u32 magic;
+  unsigned char verbuf[4];
+  FILE *fp;
+  KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
+
+  *r_found = *r_openpgp = 0;
+  fp = fopen (filename, "rb");
+  if (fp)
+    {
+      *r_found = 1;
+
+      if (fread (&magic, 4, 1, fp) == 1 )
+        {
+          if (magic == 0x13579ace || magic == 0xce9a5713)
+            ; /* GDBM magic - not anymore supported. */
+          else if (fread (&verbuf, 4, 1, fp) == 1
+                   && verbuf[0] == 1
+                   && fread (&magic, 4, 1, fp) == 1
+                   && !memcmp (&magic, "KBXf", 4))
+            {
+              if ((verbuf[3] & 0x02))
+                *r_openpgp = 1;
+              rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+            }
+          else
+            rt = KEYDB_RESOURCE_TYPE_KEYRING;
+        }
+      else /* Maybe empty: assume keyring. */
+        rt = KEYDB_RESOURCE_TYPE_KEYRING;
+
+      fclose (fp);
+    }
+
+  return rt;
+}
+
+
 /*
- * Register a resource (which currently may only be a keyring file).
- * The first keyring which is added by this function is
- * created if it does not exist.
- * Note: this function may be called before secure memory is
- * available.
- * Flag 1   - Force.
- * Flag 2   - Mark resource as primary.
- * Flag 4   - This is a default resources.
- * Flag 8   - Open as read-only.
+ * Register a resource (keyring or aeybox).  The first keyring or
+ * keybox which is added by this function is created if it does not
+ * exist.  FLAGS are a combination of the KEYDB_RESOURCE_FLAG_
+ * constants as defined in keydb.h.
  */
-int
-keydb_add_resource (const char *url, int flags, int secret)
+gpg_error_t
+keydb_add_resource (const char *url, unsigned int flags)
 {
-    static int any_secret, any_public;
-    const char *resname = url;
-    char *filename = NULL;
-    int force = (flags&1);
-    int readonly = !!(flags&8);
-    int rc = 0;
-    KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
-    void *token;
-
-    if (readonly)
-      force = 0;
-
-    /* Do we have an URL?
-     * gnupg-ring:filename  := this is a plain keyring
-     * filename := See what is is, but create as plain keyring.
-     */
-    if (strlen (resname) > 11) {
-       if (!strncmp( resname, "gnupg-ring:", 11) ) {
-           rt = KEYDB_RESOURCE_TYPE_KEYRING;
-           resname += 11;
-       }
-        else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) )
-          {
-            rt = KEYDB_RESOURCE_TYPE_KEYBOX;
-            resname += 10;
-          }
+  static int any_registered;
+  const char *resname = url;
+  char *filename = NULL;
+  int create;
+  int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY);
+  int is_default = !!(flags&KEYDB_RESOURCE_FLAG_DEFAULT);
+  int rc = 0;
+  KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
+  void *token;
+
+  /* Create the resource if it is the first registered one.  */
+  create = (!read_only && !any_registered);
+
+  /* Do we have an URL?
+   *   gnupg-ring:filename  := this is a plain keyring.
+   *   gnupg-kbx:filename   := this is a keybox file.
+   *   filename := See what is is, but create as plain keyring.
+   */
+  if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) )
+    {
+      rt = KEYDB_RESOURCE_TYPE_KEYRING;
+      resname += 11;
+    }
+  else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) )
+    {
+      rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+      resname += 10;
+    }
 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
-       else if (strchr (resname, ':')) {
-           log_error ("invalid key resource URL `%s'\n", url );
-           rc = G10ERR_GENERAL;
-           goto leave;
-       }
-#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
+  else if (strchr (resname, ':'))
+    {
+      log_error ("invalid key resource URL '%s'\n", url );
+      rc = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
     }
+#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
 
-    if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
-       if (strchr(resname, DIRSEP_C) )
-           filename = make_filename (resname, NULL);
-       else
-           filename = make_filename (opt.homedir, resname, NULL);
+  if (*resname != DIRSEP_C )
+    {
+      /* Do tilde expansion etc. */
+      if (strchr(resname, DIRSEP_C) )
+        filename = make_filename (resname, NULL);
+      else
+        filename = make_filename (opt.homedir, resname, NULL);
     }
-    else
-       filename = xstrdup (resname);
-
-    if (!force && !readonly)
-       force = secret? !any_secret : !any_public;
-
-    /* See whether we can determine the filetype.  */
-    if (rt == KEYDB_RESOURCE_TYPE_NONE) {
-       FILE *fp = fopen( filename, "rb" );
-
-       if (fp) {
-           u32 magic;
+  else
+    filename = xstrdup (resname);
 
-           if (fread( &magic, 4, 1, fp) == 1 ) {
-               if (magic == 0x13579ace || magic == 0xce9a5713)
-                   ; /* GDBM magic - no more support */
-                else if (fread (&magic, 4, 1, fp) == 1
-                         && !memcmp (&magic, "\x01", 1)
-                         && fread (&magic, 4, 1, fp) == 1
-                         && !memcmp (&magic, "KBXf", 4))
-                    rt = KEYDB_RESOURCE_TYPE_KEYBOX;
-               else
-                   rt = KEYDB_RESOURCE_TYPE_KEYRING;
-           }
-           else /* maybe empty: assume ring */
-               rt = KEYDB_RESOURCE_TYPE_KEYRING;
-           fclose( fp );
+  /* See whether we can determine the filetype.  */
+  if (rt == KEYDB_RESOURCE_TYPE_NONE)
+    {
+      int found, openpgp_flag;
+      int pass = 0;
+      size_t filenamelen;
+
+    check_again:
+      filenamelen = strlen (filename);
+      rt = rt_from_file (filename, &found, &openpgp_flag);
+      if (found)
+        {
+          /* The file exists and we have the resource type in RT.
+
+             Now let us check whether in addition to the "pubring.gpg"
+             a "pubring.kbx with openpgp keys exists.  This is so that
+             GPG 2.1 will use an existing "pubring.kbx" by default iff
+             that file has been created or used by 2.1.  This check is
+             needed because after creation or use of the kbx file with
+             2.1 an older version of gpg may have created a new
+             pubring.gpg for its own use.  */
+          if (!pass && is_default && rt == KEYDB_RESOURCE_TYPE_KEYRING
+              && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg"))
+            {
+              strcpy (filename+filenamelen-4, ".kbx");
+              if ((rt_from_file (filename, &found, &openpgp_flag)
+                   == KEYDB_RESOURCE_TYPE_KEYBOX) && found && openpgp_flag)
+                rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+              else /* Restore filename */
+                strcpy (filename+filenamelen-4, ".gpg");
+            }
        }
-       else /* no file yet: create ring */
-           rt = KEYDB_RESOURCE_TYPE_KEYRING;
+      else if (!pass
+               && is_default && create
+               && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg"))
+        {
+          /* The file does not exist, the default resource has been
+             requested, the file shall be created, and the file has a
+             ".gpg" suffix.  Change the suffix to ".kbx" and try once
+             more.  This way we achieve that we open an existing
+             ".gpg" keyring, but create a new keybox file with an
+             ".kbx" suffix.  */
+          strcpy (filename+filenamelen-4, ".kbx");
+          pass++;
+          goto check_again;
+        }
+      else /* No file yet: create keybox. */
+        rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     }
 
-    switch (rt) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-       log_error ("unknown type of key resource `%s'\n", url );
-       rc = G10ERR_GENERAL;
-       goto leave;
+  switch (rt)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      log_error ("unknown type of key resource '%s'\n", url );
+      rc = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
 
-      case KEYDB_RESOURCE_TYPE_KEYRING:
-        rc = maybe_create_keyring (filename, force);
+    case KEYDB_RESOURCE_TYPE_KEYRING:
+      rc = maybe_create_keyring_or_box (filename, 0, create);
+      if (rc)
+        goto leave;
+
+      if (keyring_register_filename (filename, read_only, &token))
+        {
+          if (used_resources >= MAX_KEYDB_RESOURCES)
+            rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
+          else
+            {
+              if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
+                primary_keyring = token;
+              all_resources[used_resources].type = rt;
+              all_resources[used_resources].u.kr = NULL; /* Not used here */
+              all_resources[used_resources].token = token;
+              used_resources++;
+            }
+        }
+      else
+        {
+          /* This keyring was already registered, so ignore it.
+             However, we can still mark it as primary even if it was
+             already registered.  */
+          if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
+            primary_keyring = token;
+        }
+      break;
+
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      {
+        rc = maybe_create_keyring_or_box (filename, 1, create);
         if (rc)
           goto leave;
 
-        if(keyring_register_filename (filename, secret, readonly, &token))
-         {
-           if (used_resources >= MAX_KEYDB_RESOURCES)
-             rc = G10ERR_RESOURCE_LIMIT;
-           else
-             {
-               if(flags&2)
-                 primary_keyring=token;
-               all_resources[used_resources].type = rt;
-               all_resources[used_resources].u.kr = NULL; /* Not used here */
-               all_resources[used_resources].token = token;
-               all_resources[used_resources].secret = secret;
-               used_resources++;
-             }
-         }
-       else
-         {
-           /* This keyring was already registered, so ignore it.
-              However, we can still mark it as primary even if it was
-              already registered. */
-           if(flags&2)
-             primary_keyring=token;
-         }
-       break;
-
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-       rc = G10ERR_UNSUPPORTED;
-       goto leave;
+        /* FIXME: How do we register a read-only keybox?  */
+        token = keybox_register_file (filename, 0);
+        if (token)
+          {
+            if (used_resources >= MAX_KEYDB_RESOURCES)
+              rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
+            else
+              {
+                /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
+                /*   primary_keyring = token; */
+                all_resources[used_resources].type = rt;
+                all_resources[used_resources].u.kb = NULL; /* Not used here */
+                all_resources[used_resources].token = token;
+
+                /* FIXME: Do a compress run if needed and no other
+                   user is currently using the keybox. */
+
+                used_resources++;
+              }
+          }
+        else
+          {
+            /* Already registered.  We will mark it as the primary key
+               if requested.  */
+            /* FIXME: How to do that?  Change the keybox interface?  */
+            /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
+            /*   primary_keyring = token; */
+          }
+      }
+      break;
 
       default:
-       log_error ("resource type of `%s' not supported\n", url);
-       rc = G10ERR_GENERAL;
+       log_error ("resource type of '%s' not supported\n", url);
+       rc = gpg_error (GPG_ERR_GENERAL);
        goto leave;
     }
 
-    /* fixme: check directory permissions and print a warning */
+  /* fixme: check directory permissions and print a warning */
 
-  leave:
-    if (rc)
-      {
-        /* Secret keyrings are not required in all cases.  To avoid
-           having gpg return failure we use log_info here if the
-           rewsource is a secret one and marked as default
-           resource.  */
-        if ((flags&4) && secret)
-          log_info (_("keyblock resource `%s': %s\n"),
-                    filename, g10_errstr(rc));
-        else
-          log_error (_("keyblock resource `%s': %s\n"),
-                     filename, g10_errstr(rc));
-        if (rt == KEYDB_RESOURCE_TYPE_KEYBOX)
-          log_error ("Note: This version of GPG does not support"
-                     " the Keybox format\n");
-      }
-    else if (secret)
-       any_secret = 1;
-    else
-       any_public = 1;
-    xfree (filename);
-    return rc;
+ leave:
+  if (rc)
+    log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc));
+  else
+    any_registered = 1;
+  xfree (filename);
+  return rc;
 }
 
 
 
 
 KEYDB_HANDLE
-keydb_new (int secret)
+keydb_new (void)
 {
   KEYDB_HANDLE hd;
   int i, j;
 
+  if (DBG_CLOCK)
+    log_clock ("keydb_new");
+
   hd = xmalloc_clear (sizeof *hd);
   hd->found = -1;
 
   assert (used_resources <= MAX_KEYDB_RESOURCES);
   for (i=j=0; i < used_resources; i++)
     {
-      if (!all_resources[i].secret != !secret)
-        continue;
       switch (all_resources[i].type)
         {
         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
-        case KEYDB_RESOURCE_TYPE_KEYBOX: /* ignore */
           break;
         case KEYDB_RESOURCE_TYPE_KEYRING:
           hd->active[j].type   = all_resources[i].type;
           hd->active[j].token  = all_resources[i].token;
-          hd->active[j].secret = all_resources[i].secret;
-          hd->active[j].u.kr = keyring_new (all_resources[i].token, secret);
+          hd->active[j].u.kr = keyring_new (all_resources[i].token);
           if (!hd->active[j].u.kr) {
             xfree (hd);
             return NULL; /* fixme: release all previously allocated handles*/
           }
           j++;
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          hd->active[j].type   = all_resources[i].type;
+          hd->active[j].token  = all_resources[i].token;
+          hd->active[j].u.kb   = keybox_new_openpgp (all_resources[i].token, 0);
+          if (!hd->active[j].u.kb)
+            {
+              xfree (hd);
+              return NULL; /* fixme: release all previously allocated handles*/
+            }
+          j++;
+          break;
         }
     }
   hd->used = j;
@@ -403,29 +571,45 @@ keydb_new (int secret)
   return hd;
 }
 
+
 void
 keydb_release (KEYDB_HANDLE hd)
 {
-    int i;
-
-    if (!hd)
-        return;
-    assert (active_handles > 0);
-    active_handles--;
-
-    unlock_all (hd);
-    for (i=0; i < hd->used; i++) {
-        switch (hd->active[i].type) {
-          case KEYDB_RESOURCE_TYPE_NONE:
-          case KEYDB_RESOURCE_TYPE_KEYBOX:
-            break;
-          case KEYDB_RESOURCE_TYPE_KEYRING:
-            keyring_release (hd->active[i].u.kr);
-            break;
+  int i;
+
+  if (!hd)
+    return;
+  assert (active_handles > 0);
+  active_handles--;
+
+  unlock_all (hd);
+  for (i=0; i < hd->used; i++)
+    {
+      switch (hd->active[i].type)
+        {
+        case KEYDB_RESOURCE_TYPE_NONE:
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYRING:
+          keyring_release (hd->active[i].u.kr);
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          keybox_release (hd->active[i].u.kb);
+          break;
         }
     }
 
-    xfree (hd);
+  xfree (hd);
+}
+
+
+/* Set a flag on handle to not use cached results.  This is required
+   for updating a keyring and for key listins.  Fixme: Using a new
+   parameter for keydb_new might be a better solution.  */
+void
+keydb_disable_caching (KEYDB_HANDLE hd)
+{
+  if (hd)
+    hd->no_caching = 1;
 }
 
 
@@ -440,30 +624,33 @@ keydb_release (KEYDB_HANDLE hd)
 const char *
 keydb_get_resource_name (KEYDB_HANDLE hd)
 {
-    int idx;
-    const char *s = NULL;
-
-    if (!hd)
-        return NULL;
-
-    if ( hd->found >= 0 && hd->found < hd->used)
-        idx = hd->found;
-    else if ( hd->current >= 0 && hd->current < hd->used)
-        idx = hd->current;
-    else
-        idx = 0;
-
-    switch (hd->active[idx].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        s = NULL;
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYRING:
-        s = keyring_get_resource_name (hd->active[idx].u.kr);
-        break;
-    }
-
-    return s? s: "";
+  int idx;
+  const char *s = NULL;
+
+  if (!hd)
+    return NULL;
+
+  if ( hd->found >= 0 && hd->found < hd->used)
+    idx = hd->found;
+  else if ( hd->current >= 0 && hd->current < hd->used)
+    idx = hd->current;
+  else
+    idx = 0;
+
+  switch (hd->active[idx].type)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      s = NULL;
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYRING:
+      s = keyring_get_resource_name (hd->active[idx].u.kr);
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      s = keybox_get_resource_name (hd->active[idx].u.kb);
+      break;
+    }
+
+  return s? s: "";
 }
 
 
@@ -471,57 +658,233 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
 static int
 lock_all (KEYDB_HANDLE hd)
 {
-    int i, rc = 0;
-
-    for (i=0; !rc && i < hd->used; i++) {
-        switch (hd->active[i].type) {
-          case KEYDB_RESOURCE_TYPE_NONE:
-          case KEYDB_RESOURCE_TYPE_KEYBOX:
-            break;
-          case KEYDB_RESOURCE_TYPE_KEYRING:
-            rc = keyring_lock (hd->active[i].u.kr, 1);
-            break;
+  int i, rc = 0;
+
+  /* Fixme: This locking scheme may lead to a deadlock if the resources
+     are not added in the same order by all processes.  We are
+     currently only allowing one resource so it is not a problem.
+     [Oops: Who claimed the latter]
+
+     To fix this we need to use a lock file to protect lock_all.  */
+
+  for (i=0; !rc && i < hd->used; i++)
+    {
+      switch (hd->active[i].type)
+        {
+        case KEYDB_RESOURCE_TYPE_NONE:
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYRING:
+          rc = keyring_lock (hd->active[i].u.kr, 1);
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          rc = keybox_lock (hd->active[i].u.kb, 1);
+          break;
         }
     }
 
-    if (rc) {
-        /* revert the already set locks */
-        for (i--; i >= 0; i--) {
-            switch (hd->active[i].type) {
-              case KEYDB_RESOURCE_TYPE_NONE:
-              case KEYDB_RESOURCE_TYPE_KEYBOX:
-                break;
-              case KEYDB_RESOURCE_TYPE_KEYRING:
-                keyring_lock (hd->active[i].u.kr, 0);
-                break;
+  if (rc)
+    {
+      /* Revert the already taken locks.  */
+      for (i--; i >= 0; i--)
+        {
+          switch (hd->active[i].type)
+            {
+            case KEYDB_RESOURCE_TYPE_NONE:
+              break;
+            case KEYDB_RESOURCE_TYPE_KEYRING:
+              keyring_lock (hd->active[i].u.kr, 0);
+              break;
+            case KEYDB_RESOURCE_TYPE_KEYBOX:
+              rc = keybox_lock (hd->active[i].u.kb, 0);
+              break;
             }
         }
     }
-    else
-        hd->locked = 1;
+  else
+    hd->locked = 1;
 
-    return rc;
+  return rc;
 }
 
+
 static void
 unlock_all (KEYDB_HANDLE hd)
 {
-    int i;
-
-    if (!hd->locked)
-        return;
-
-    for (i=hd->used-1; i >= 0; i--) {
-        switch (hd->active[i].type) {
-          case KEYDB_RESOURCE_TYPE_NONE:
-          case KEYDB_RESOURCE_TYPE_KEYBOX:
-            break;
-          case KEYDB_RESOURCE_TYPE_KEYRING:
-            keyring_lock (hd->active[i].u.kr, 0);
-            break;
+  int i;
+
+  if (!hd->locked)
+    return;
+
+  for (i=hd->used-1; i >= 0; i--)
+    {
+      switch (hd->active[i].type)
+        {
+        case KEYDB_RESOURCE_TYPE_NONE:
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYRING:
+          keyring_lock (hd->active[i].u.kr, 0);
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          keybox_lock (hd->active[i].u.kb, 0);
+          break;
         }
     }
-    hd->locked = 0;
+  hd->locked = 0;
+}
+
+
+static gpg_error_t
+parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
+                      const u32 *sigstatus, kbnode_t *r_keyblock)
+{
+  gpg_error_t err;
+  PACKET *pkt;
+  kbnode_t keyblock = NULL;
+  kbnode_t node, *tail;
+  int in_cert, save_mode;
+  u32 n_sigs;
+  int pk_count, uid_count;
+
+  *r_keyblock = NULL;
+
+  pkt = xtrymalloc (sizeof *pkt);
+  if (!pkt)
+    return gpg_error_from_syserror ();
+  init_packet (pkt);
+  save_mode = set_packet_list_mode (0);
+  in_cert = 0;
+  n_sigs = 0;
+  tail = NULL;
+  pk_count = uid_count = 0;
+  while ((err = parse_packet (iobuf, pkt)) != -1)
+    {
+      if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET)
+        {
+          free_packet (pkt);
+          init_packet (pkt);
+          continue;
+       }
+      if (err)
+        {
+          log_error ("parse_keyblock_image: read error: %s\n",
+                     gpg_strerror (err));
+          err = gpg_error (GPG_ERR_INV_KEYRING);
+          break;
+        }
+      if (pkt->pkttype == PKT_COMPRESSED)
+        {
+          log_error ("skipped compressed packet in keybox blob\n");
+          free_packet(pkt);
+          init_packet(pkt);
+          continue;
+        }
+      if (pkt->pkttype == PKT_RING_TRUST)
+        {
+          log_info ("skipped ring trust packet in keybox blob\n");
+          free_packet(pkt);
+          init_packet(pkt);
+          continue;
+        }
+
+      if (!in_cert && pkt->pkttype != PKT_PUBLIC_KEY)
+        {
+          log_error ("parse_keyblock_image: first packet in a keybox blob "
+                     "is not a public key packet\n");
+          err = gpg_error (GPG_ERR_INV_KEYRING);
+          break;
+        }
+      if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY
+                      || pkt->pkttype == PKT_SECRET_KEY))
+        {
+          log_error ("parse_keyblock_image: "
+                     "multiple keyblocks in a keybox blob\n");
+          err = gpg_error (GPG_ERR_INV_KEYRING);
+          break;
+        }
+      in_cert = 1;
+
+      if (pkt->pkttype == PKT_SIGNATURE && sigstatus)
+        {
+          PKT_signature *sig = pkt->pkt.signature;
+
+          n_sigs++;
+          if (n_sigs > sigstatus[0])
+            {
+              log_error ("parse_keyblock_image: "
+                         "more signatures than found in the meta data\n");
+              err = gpg_error (GPG_ERR_INV_KEYRING);
+              break;
+
+            }
+          if (sigstatus[n_sigs])
+            {
+              sig->flags.checked = 1;
+              if (sigstatus[n_sigs] == 1 )
+                ; /* missing key */
+              else if (sigstatus[n_sigs] == 2 )
+                ; /* bad signature */
+              else if (sigstatus[n_sigs] < 0x10000000)
+                ; /* bad flag */
+              else
+                {
+                  sig->flags.valid = 1;
+                  /* Fixme: Shall we set the expired flag here?  */
+                }
+            }
+        }
+
+      node = new_kbnode (pkt);
+
+      switch (pkt->pkttype)
+        {
+        case PKT_PUBLIC_KEY:
+        case PKT_PUBLIC_SUBKEY:
+        case PKT_SECRET_KEY:
+        case PKT_SECRET_SUBKEY:
+          if (++pk_count == pk_no)
+            node->flag |= 1;
+          break;
+
+        case PKT_USER_ID:
+          if (++uid_count == uid_no)
+            node->flag |= 2;
+          break;
+
+        default:
+          break;
+        }
+
+      if (!keyblock)
+        keyblock = node;
+      else
+        *tail = node;
+      tail = &node->next;
+      pkt = xtrymalloc (sizeof *pkt);
+      if (!pkt)
+        {
+          err = gpg_error_from_syserror ();
+          break;
+        }
+      init_packet (pkt);
+    }
+  set_packet_list_mode (save_mode);
+
+  if (err == -1 && keyblock)
+    err = 0; /* Got the entire keyblock.  */
+
+  if (!err && sigstatus && n_sigs != sigstatus[0])
+    {
+      log_error ("parse_keyblock_image: signature count does not match\n");
+      err = gpg_error (GPG_ERR_INV_KEYRING);
+    }
+
+  if (err)
+    release_kbnode (keyblock);
+  else
+    *r_keyblock = keyblock;
+  free_packet (pkt);
+  xfree (pkt);
+  return err;
 }
 
 
@@ -531,152 +894,333 @@ unlock_all (KEYDB_HANDLE hd)
  * the public key used to locate the keyblock or flag bit 1 set for
  * the user ID node.
  */
-int
+gpg_error_t
 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
 {
-    int rc = 0;
+  gpg_error_t err = 0;
 
-    if (!hd)
-        return G10ERR_INV_ARG;
+  *ret_kb = NULL;
 
-    if ( hd->found < 0 || hd->found >= hd->used)
-        return -1; /* nothing found */
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_ARG);
 
-    switch (hd->active[hd->found].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        rc = G10ERR_GENERAL; /* oops */
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYRING:
-        rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
-        break;
+  if (keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
+    {
+      iobuf_seek (keyblock_cache.iobuf, 0);
+      err = parse_keyblock_image (keyblock_cache.iobuf,
+                                  keyblock_cache.pk_no,
+                                  keyblock_cache.uid_no,
+                                  keyblock_cache.sigstatus,
+                                  ret_kb);
+      if (err)
+        keyblock_cache_clear ();
+      return err;
     }
 
-    return rc;
+  if (hd->found < 0 || hd->found >= hd->used)
+    return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
+
+  switch (hd->active[hd->found].type)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      err = gpg_error (GPG_ERR_GENERAL); /* oops */
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYRING:
+      err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      {
+        iobuf_t iobuf;
+        u32 *sigstatus;
+        int pk_no, uid_no;
+
+        err = keybox_get_keyblock (hd->active[hd->found].u.kb,
+                                   &iobuf, &pk_no, &uid_no, &sigstatus);
+        if (!err)
+          {
+            err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
+                                        ret_kb);
+            if (!err && keyblock_cache.state == KEYBLOCK_CACHE_PREPARED)
+              {
+                keyblock_cache.state     = KEYBLOCK_CACHE_FILLED;
+                keyblock_cache.sigstatus = sigstatus;
+                keyblock_cache.iobuf     = iobuf;
+                keyblock_cache.pk_no     = pk_no;
+                keyblock_cache.uid_no    = uid_no;
+              }
+            else
+              {
+                xfree (sigstatus);
+                iobuf_close (iobuf);
+              }
+          }
+      }
+      break;
+    }
+
+  if (keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
+    keyblock_cache_clear ();
+
+  return err;
 }
 
+
+/* Build a keyblock image from KEYBLOCK.  Returns 0 on success and
+   only then stores a new iobuf object at R_IOBUF and a signature
+   status vecotor at R_SIGSTATUS.  */
+static gpg_error_t
+build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
+{
+  gpg_error_t err;
+  iobuf_t iobuf;
+  kbnode_t kbctx, node;
+  u32 n_sigs;
+  u32 *sigstatus;
+
+  *r_iobuf = NULL;
+  if (r_sigstatus)
+    *r_sigstatus = NULL;
+
+  /* Allocate a vector for the signature cache.  This is an array of
+     u32 values with the first value giving the number of elements to
+     follow and each element descriping the cache status of the
+     signature.  */
+  if (r_sigstatus)
+    {
+      for (kbctx=NULL, n_sigs=0; (node = walk_kbnode (keyblock, &kbctx, 0));)
+        if (node->pkt->pkttype == PKT_SIGNATURE)
+          n_sigs++;
+      sigstatus = xtrycalloc (1+n_sigs, sizeof *sigstatus);
+      if (!sigstatus)
+        return gpg_error_from_syserror ();
+    }
+  else
+    sigstatus = NULL;
+
+  iobuf = iobuf_temp ();
+  for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));)
+    {
+      /* Make sure to use only packets valid on a keyblock.  */
+      switch (node->pkt->pkttype)
+        {
+        case PKT_PUBLIC_KEY:
+        case PKT_PUBLIC_SUBKEY:
+        case PKT_SIGNATURE:
+        case PKT_USER_ID:
+        case PKT_ATTRIBUTE:
+          /* Note that we don't want the ring trust packets.  They are
+             not useful. */
+          break;
+        default:
+          continue;
+        }
+
+      err = build_packet (iobuf, node->pkt);
+      if (err)
+        {
+          iobuf_close (iobuf);
+          return err;
+        }
+
+      /* Build signature status vector.  */
+      if (node->pkt->pkttype == PKT_SIGNATURE)
+        {
+          PKT_signature *sig = node->pkt->pkt.signature;
+
+          n_sigs++;
+          /* Fixme: Detect the "missing key" status.  */
+          if (sig->flags.checked && sigstatus)
+            {
+              if (sig->flags.valid)
+                {
+                  if (!sig->expiredate)
+                    sigstatus[n_sigs] = 0xffffffff;
+                  else if (sig->expiredate < 0x1000000)
+                    sigstatus[n_sigs] = 0x10000000;
+                  else
+                    sigstatus[n_sigs] = sig->expiredate;
+                }
+              else
+                sigstatus[n_sigs] = 0x00000002; /* Bad signature.  */
+            }
+        }
+    }
+  if (sigstatus)
+    sigstatus[0] = n_sigs;
+
+  *r_iobuf = iobuf;
+  if (r_sigstatus)
+    *r_sigstatus = sigstatus;
+  return 0;
+}
+
+
 /*
- * update the current keyblock with KB
+ * Update the current keyblock with the keyblock KB
  */
-int
-keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
+gpg_error_t
+keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
 {
-    int rc = 0;
+  gpg_error_t err;
 
-    if (!hd)
-        return G10ERR_INV_ARG;
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_ARG);
 
-    if ( hd->found < 0 || hd->found >= hd->used)
-        return -1; /* nothing found */
+  keyblock_cache_clear ();
 
-    if( opt.dry_run )
-       return 0;
+  if (hd->found < 0 || hd->found >= hd->used)
+    return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
 
-    rc = lock_all (hd);
-    if (rc)
-        return rc;
+  if (opt.dry_run)
+    return 0;
+
+  err = lock_all (hd);
+  if (err)
+    return err;
+
+  switch (hd->active[hd->found].type)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      err = gpg_error (GPG_ERR_GENERAL); /* oops */
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYRING:
+      err = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      {
+        iobuf_t iobuf;
 
-    switch (hd->active[hd->found].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        rc = G10ERR_GENERAL; /* oops */
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYRING:
-        rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
-        break;
+        err = build_keyblock_image (kb, &iobuf, NULL);
+        if (!err)
+          {
+            err = keybox_update_keyblock (hd->active[hd->found].u.kb,
+                                          iobuf_get_temp_buffer (iobuf),
+                                          iobuf_get_temp_length (iobuf));
+            iobuf_close (iobuf);
+          }
+      }
+      break;
     }
 
-    unlock_all (hd);
-    return rc;
+  unlock_all (hd);
+  return err;
 }
 
 
 /*
  * Insert a new KB into one of the resources.
  */
-int
-keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
+gpg_error_t
+keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
 {
-    int rc = -1;
-    int idx;
+  gpg_error_t err;
+  int idx;
+
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_ARG);
 
-    if (!hd)
-        return G10ERR_INV_ARG;
+  keyblock_cache_clear ();
 
-    if( opt.dry_run )
-       return 0;
+  if (opt.dry_run)
+    return 0;
 
-    if ( hd->found >= 0 && hd->found < hd->used)
-        idx = hd->found;
-    else if ( hd->current >= 0 && hd->current < hd->used)
-        idx = hd->current;
-    else
-        return G10ERR_GENERAL;
+  if (hd->found >= 0 && hd->found < hd->used)
+    idx = hd->found;
+  else if (hd->current >= 0 && hd->current < hd->used)
+    idx = hd->current;
+  else
+    return gpg_error (GPG_ERR_GENERAL);
 
-    rc = lock_all (hd);
-    if (rc)
-        return rc;
+  err = lock_all (hd);
+  if (err)
+    return err;
 
-    switch (hd->active[idx].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        rc = G10ERR_GENERAL; /* oops */
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYRING:
-        rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
-        break;
+  switch (hd->active[idx].type)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      err = gpg_error (GPG_ERR_GENERAL); /* oops */
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYRING:
+      err = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      { /* We need to turn our kbnode_t list of packets into a proper
+           keyblock first.  This is required by the OpenPGP key parser
+           included in the keybox code.  Eventually we can change this
+           kludge to have the caller pass the image.  */
+        iobuf_t iobuf;
+        u32 *sigstatus;
+
+        err = build_keyblock_image (kb, &iobuf, &sigstatus);
+        if (!err)
+          {
+            err = keybox_insert_keyblock (hd->active[idx].u.kb,
+                                          iobuf_get_temp_buffer (iobuf),
+                                          iobuf_get_temp_length (iobuf),
+                                          sigstatus);
+            xfree (sigstatus);
+            iobuf_close (iobuf);
+          }
+      }
+      break;
     }
 
-    unlock_all (hd);
-    return rc;
+  unlock_all (hd);
+  return err;
 }
 
 
 /*
- * The current keyblock will be deleted.
+ * Delete the current keyblock.
  */
-int
+gpg_error_t
 keydb_delete_keyblock (KEYDB_HANDLE hd)
 {
-    int rc = -1;
+  gpg_error_t rc;
 
-    if (!hd)
-        return G10ERR_INV_ARG;
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_ARG);
 
-    if ( hd->found < 0 || hd->found >= hd->used)
-        return -1; /* nothing found */
+  keyblock_cache_clear ();
 
-    if( opt.dry_run )
-       return 0;
+  if (hd->found < 0 || hd->found >= hd->used)
+    return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
 
-    rc = lock_all (hd);
-    if (rc)
-        return rc;
+  if (opt.dry_run)
+    return 0;
+
+  rc = lock_all (hd);
+  if (rc)
+    return rc;
 
-    switch (hd->active[hd->found].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        rc = G10ERR_GENERAL; /* oops */
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYRING:
-        rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
-        break;
+  switch (hd->active[hd->found].type)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      rc = gpg_error (GPG_ERR_GENERAL);
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYRING:
+      rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      rc = keybox_delete (hd->active[hd->found].u.kb);
+      break;
     }
 
-    unlock_all (hd);
-    return rc;
+  unlock_all (hd);
+  return rc;
 }
 
+
 \f
 /*
  * Locate the default writable key resource, so that the next
  * operation (which is only relevant for inserts) will be done on this
  * resource.
  */
-int
+gpg_error_t
 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
 {
-  int rc;
+  gpg_error_t rc;
 
   (void)reserved;
 
@@ -688,7 +1232,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
     return rc;
 
   /* If we have a primary set, try that one first */
-  if(primary_keyring)
+  if (primary_keyring)
     {
       for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
        {
@@ -711,17 +1255,20 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
       switch (hd->active[hd->current].type)
         {
         case KEYDB_RESOURCE_TYPE_NONE:
-        case KEYDB_RESOURCE_TYPE_KEYBOX:
           BUG();
           break;
         case KEYDB_RESOURCE_TYPE_KEYRING:
           if (keyring_is_writable (hd->active[hd->current].token))
             return 0; /* found (hd->current is set to it) */
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          if (keybox_is_writable (hd->active[hd->current].token))
+            return 0; /* found (hd->current is set to it) */
+          break;
         }
     }
 
-  return -1;
+  return gpg_error (GPG_ERR_NOT_FOUND);
 }
 
 /*
@@ -732,16 +1279,15 @@ keydb_rebuild_caches (int noisy)
 {
   int i, rc;
 
+  keyblock_cache_clear ();
+
   for (i=0; i < used_resources; i++)
     {
-      if (all_resources[i].secret)
-        continue;
       if (!keyring_is_writable (all_resources[i].token))
         continue;
       switch (all_resources[i].type)
         {
         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
-        case KEYDB_RESOURCE_TYPE_KEYBOX: /* ignore */
           break;
         case KEYDB_RESOURCE_TYPE_KEYRING:
           rc = keyring_rebuild_cache (all_resources[i].token,noisy);
@@ -749,112 +1295,236 @@ keydb_rebuild_caches (int noisy)
             log_error (_("failed to rebuild keyring cache: %s\n"),
                        g10_errstr (rc));
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          /* N/A.  */
+          break;
         }
     }
 }
 
 
+/* Return the number of skipped blocks since the last search reset.  */
+unsigned long
+keydb_get_skipped_counter (KEYDB_HANDLE hd)
+{
+  return hd ? hd->skipped_long_blobs : 0;
+}
+
 
 /*
  * Start the next search on this handle right at the beginning
  */
-int
+gpg_error_t
 keydb_search_reset (KEYDB_HANDLE hd)
 {
-    int i, rc = 0;
-
-    if (!hd)
-        return G10ERR_INV_ARG;
-
-    hd->current = 0;
-    hd->found = -1;
-    /* and reset all resources */
-    for (i=0; !rc && i < hd->used; i++) {
-        switch (hd->active[i].type) {
-          case KEYDB_RESOURCE_TYPE_NONE:
-          case KEYDB_RESOURCE_TYPE_KEYBOX:
-            break;
-          case KEYDB_RESOURCE_TYPE_KEYRING:
-            rc = keyring_search_reset (hd->active[i].u.kr);
-            break;
+  gpg_error_t rc = 0;
+  int i;
+
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  keyblock_cache_clear ();
+
+  if (DBG_CLOCK)
+    log_clock ("keydb_search_reset");
+
+  if (DBG_CACHE)
+    log_debug ("keydb_search: reset  (hd=%p)", hd);
+
+  hd->skipped_long_blobs = 0;
+  hd->current = 0;
+  hd->found = -1;
+  /* Now reset all resources.  */
+  for (i=0; !rc && i < hd->used; i++)
+    {
+      switch (hd->active[i].type)
+        {
+        case KEYDB_RESOURCE_TYPE_NONE:
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYRING:
+          rc = keyring_search_reset (hd->active[i].u.kr);
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          rc = keybox_search_reset (hd->active[i].u.kb);
+          break;
+        }
+    }
+  return rc;
+}
+
+
+static void
+dump_search_desc (KEYDB_HANDLE hd, const char *text,
+                  KEYDB_SEARCH_DESC *desc, size_t ndesc)
+{
+  int n;
+  const char *s;
+
+  for (n=0; n < ndesc; n++)
+    {
+      switch (desc[n].mode)
+        {
+        case KEYDB_SEARCH_MODE_NONE:      s = "none";      break;
+        case KEYDB_SEARCH_MODE_EXACT:     s = "exact";     break;
+        case KEYDB_SEARCH_MODE_SUBSTR:    s = "substr";    break;
+        case KEYDB_SEARCH_MODE_MAIL:      s = "mail";      break;
+        case KEYDB_SEARCH_MODE_MAILSUB:   s = "mailsub";   break;
+        case KEYDB_SEARCH_MODE_MAILEND:   s = "mailend";   break;
+        case KEYDB_SEARCH_MODE_WORDS:     s = "words";     break;
+        case KEYDB_SEARCH_MODE_SHORT_KID: s = "short_kid"; break;
+        case KEYDB_SEARCH_MODE_LONG_KID:  s = "long_kid";  break;
+        case KEYDB_SEARCH_MODE_FPR16:     s = "fpr16";     break;
+        case KEYDB_SEARCH_MODE_FPR20:     s = "fpr20";     break;
+        case KEYDB_SEARCH_MODE_FPR:       s = "fpr";       break;
+        case KEYDB_SEARCH_MODE_ISSUER:    s = "issuer";    break;
+        case KEYDB_SEARCH_MODE_ISSUER_SN: s = "issuer_sn"; break;
+        case KEYDB_SEARCH_MODE_SN:        s = "sn";        break;
+        case KEYDB_SEARCH_MODE_SUBJECT:   s = "subject";   break;
+        case KEYDB_SEARCH_MODE_KEYGRIP:   s = "keygrip";   break;
+        case KEYDB_SEARCH_MODE_FIRST:     s = "first";     break;
+        case KEYDB_SEARCH_MODE_NEXT:      s = "next";      break;
+        default:                          s = "?";         break;
         }
+      if (!n)
+        log_debug ("%s: mode=%s  (hd=%p)", text, s, hd);
+      else
+        log_debug ("%*s  mode=%s", (int)strlen (text), "", s);
+      if (desc[n].mode == KEYDB_SEARCH_MODE_LONG_KID)
+        log_printf (" %08lX%08lX", (unsigned long)desc[n].u.kid[0],
+                    (unsigned long)desc[n].u.kid[1]);
+      else if (desc[n].mode == KEYDB_SEARCH_MODE_SHORT_KID)
+        log_printf (" %08lX", (unsigned long)desc[n].u.kid[1]);
+      else if (desc[n].mode == KEYDB_SEARCH_MODE_SUBSTR)
+        log_printf (" '%s'", desc[n].u.name);
     }
-    return rc;
 }
 
 
 /*
- * Search through all keydb resources, starting at the current position,
- * for a keyblock which contains one of the keys described in the DESC array.
+ * Search through all keydb resources, starting at the current
+ * position, for a keyblock which contains one of the keys described
+ * in the DESC array.  Returns GPG_ERR_NOT_FOUND if no matching
+ * keyring was found.
  */
-int
-keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
-              size_t ndesc, size_t *descindex)
+gpg_error_t
+keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
+              size_t ndesc, size_t *descindex)
 {
-    int rc = -1;
-
-    if (!hd)
-        return G10ERR_INV_ARG;
-
-    while (rc == -1 && hd->current >= 0 && hd->current < hd->used) {
-        switch (hd->active[hd->current].type) {
-          case KEYDB_RESOURCE_TYPE_NONE:
-          case KEYDB_RESOURCE_TYPE_KEYBOX:
-            BUG(); /* we should never see it here */
-            break;
-          case KEYDB_RESOURCE_TYPE_KEYRING:
-            rc = keyring_search (hd->active[hd->current].u.kr, desc,
-                                ndesc, descindex);
-            break;
+  gpg_error_t rc;
+
+  if (descindex)
+    *descindex = 0; /* Make sure it is always set on return.  */
+
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  if (DBG_CLOCK)
+    log_clock ("keydb_search enter");
+
+  if (DBG_CACHE)
+    dump_search_desc (hd, "keydb_search", desc, ndesc);
+
+  if (!hd->no_caching
+      && ndesc == 1
+      && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
+          || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
+      && keyblock_cache.state  == KEYBLOCK_CACHE_FILLED
+      && !memcmp (keyblock_cache.fpr, desc[0].u.fpr, 20))
+    {
+      /* (DESCINDEX is already set).  */
+      if (DBG_CLOCK)
+        log_clock ("keydb_search leave (cached)");
+      return 0;
+    }
+
+  rc = -1;
+  while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
+         && hd->current >= 0 && hd->current < hd->used)
+    {
+      switch (hd->active[hd->current].type)
+        {
+        case KEYDB_RESOURCE_TYPE_NONE:
+          BUG(); /* we should never see it here */
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYRING:
+          rc = keyring_search (hd->active[hd->current].u.kr, desc,
+                               ndesc, descindex);
+          break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          rc = keybox_search (hd->active[hd->current].u.kb, desc,
+                              ndesc, KEYBOX_BLOBTYPE_PGP,
+                              descindex, &hd->skipped_long_blobs);
+          break;
+        }
+      if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
+        {
+          /* EOF -> switch to next resource */
+          hd->current++;
         }
-        if (rc == -1) /* EOF -> switch to next resource */
-            hd->current++;
-        else if (!rc)
-            hd->found = hd->current;
+      else if (!rc)
+        hd->found = hd->current;
     }
 
-    return rc;
+  rc = ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
+        ? gpg_error (GPG_ERR_NOT_FOUND)
+        : rc);
+
+  keyblock_cache_clear ();
+  if (!hd->no_caching
+      && !rc
+      && ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
+                        || desc[0].mode == KEYDB_SEARCH_MODE_FPR))
+    {
+      keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
+      memcpy (keyblock_cache.fpr, desc[0].u.fpr, 20);
+    }
+
+  if (DBG_CLOCK)
+    log_clock (rc? "keydb_search leave (not found)"
+                 : "keydb_search leave (found)");
+  return rc;
 }
 
-int
+
+gpg_error_t
 keydb_search_first (KEYDB_HANDLE hd)
 {
-    KEYDB_SEARCH_DESC desc;
+  KEYDB_SEARCH_DESC desc;
 
-    memset (&desc, 0, sizeof desc);
-    desc.mode = KEYDB_SEARCH_MODE_FIRST;
-    return keydb_search (hd, &desc, 1);
+  memset (&desc, 0, sizeof desc);
+  desc.mode = KEYDB_SEARCH_MODE_FIRST;
+  return keydb_search (hd, &desc, 1, NULL);
 }
 
-int
+gpg_error_t
 keydb_search_next (KEYDB_HANDLE hd)
 {
-    KEYDB_SEARCH_DESC desc;
+  KEYDB_SEARCH_DESC desc;
 
-    memset (&desc, 0, sizeof desc);
-    desc.mode = KEYDB_SEARCH_MODE_NEXT;
-    return keydb_search (hd, &desc, 1);
+  memset (&desc, 0, sizeof desc);
+  desc.mode = KEYDB_SEARCH_MODE_NEXT;
+  return keydb_search (hd, &desc, 1, NULL);
 }
 
-int
+gpg_error_t
 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
 {
-    KEYDB_SEARCH_DESC desc;
+  KEYDB_SEARCH_DESC desc;
 
-    memset (&desc, 0, sizeof desc);
-    desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
-    desc.u.kid[0] = kid[0];
-    desc.u.kid[1] = kid[1];
-    return keydb_search (hd, &desc, 1);
+  memset (&desc, 0, sizeof desc);
+  desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
+  desc.u.kid[0] = kid[0];
+  desc.u.kid[1] = kid[1];
+  return keydb_search (hd, &desc, 1, NULL);
 }
 
-int
+gpg_error_t
 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
 {
-    KEYDB_SEARCH_DESC desc;
+  KEYDB_SEARCH_DESC desc;
 
-    memset (&desc, 0, sizeof desc);
-    desc.mode = KEYDB_SEARCH_MODE_FPR;
-    memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
-    return keydb_search (hd, &desc, 1);
+  memset (&desc, 0, sizeof desc);
+  desc.mode = KEYDB_SEARCH_MODE_FPR;
+  memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
+  return keydb_search (hd, &desc, 1, NULL);
 }
index 52ede16..c61e0ae 100644 (file)
@@ -1,6 +1,6 @@
 /* keydb.h - Key database
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006 Free Software Foundation, Inc.
+ *               2006, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -24,8 +24,8 @@
 #include <assuan.h>
 
 #include "types.h"
+#include "util.h"
 #include "packet.h"
-#include "cipher.h"
 
 /* What qualifies as a certification (rather than a signature?) */
 #define IS_CERT(s)       (IS_KEY_SIG(s) || IS_UID_SIG(s) || IS_SUBKEY_SIG(s) \
@@ -40,6 +40,7 @@
 
 struct getkey_ctx_s;
 typedef struct getkey_ctx_s *GETKEY_CTX;
+typedef struct getkey_ctx_s *getkey_ctx_t;
 
 /****************
  * A Keyblock is all packets which form an entire certificate;
@@ -83,20 +84,23 @@ struct keyblock_pos_struct {
 };
 typedef struct keyblock_pos_struct KBPOS;
 
-/* structure to hold a couple of public key certificates */
-typedef struct pk_list *PK_LIST;
-struct pk_list {
-    PK_LIST next;
-    PKT_public_key *pk;
-    int flags; /* flag bit 1==throw_keyid */
+/* Structure to hold a couple of public key certificates. */
+typedef struct pk_list *PK_LIST;  /* Deprecated. */
+typedef struct pk_list *pk_list_t;
+struct pk_list
+{
+  PK_LIST next;
+  PKT_public_key *pk;
+  int flags; /* flag bit 1==throw_keyid */
 };
 
-/* structure to hold a couple of secret key certificates */
+/* Structure to hold a list of secret key certificates.  */
 typedef struct sk_list *SK_LIST;
-struct sk_list {
-    SK_LIST next;
-    PKT_secret_key *sk;
-    int mark; /* not used */
+struct sk_list
+{
+  SK_LIST next;
+  PKT_public_key *pk;
+  int mark; /* not used */
 };
 
 /* structure to collect all information which can be used to
@@ -113,35 +117,6 @@ struct pubkey_find_info {
 
 typedef struct keydb_handle *KEYDB_HANDLE;
 
-typedef enum {
-    KEYDB_SEARCH_MODE_NONE,
-    KEYDB_SEARCH_MODE_EXACT,
-    KEYDB_SEARCH_MODE_SUBSTR,
-    KEYDB_SEARCH_MODE_MAIL,
-    KEYDB_SEARCH_MODE_MAILSUB,
-    KEYDB_SEARCH_MODE_MAILEND,
-    KEYDB_SEARCH_MODE_WORDS,
-    KEYDB_SEARCH_MODE_SHORT_KID,
-    KEYDB_SEARCH_MODE_LONG_KID,
-    KEYDB_SEARCH_MODE_FPR16,
-    KEYDB_SEARCH_MODE_FPR20,
-    KEYDB_SEARCH_MODE_FPR,
-    KEYDB_SEARCH_MODE_FIRST,
-    KEYDB_SEARCH_MODE_NEXT
-} KeydbSearchMode;
-
-struct keydb_search_desc {
-    KeydbSearchMode mode;
-    int (*skipfnc)(void *,u32*,PKT_user_id*);
-    void *skipfncvalue;
-    union {
-        const char *name;
-        byte fpr[MAX_FINGERPRINT_LEN];
-        u32  kid[2];
-    } u;
-    int exact;
-};
-
 
 /* Helper type for preference fucntions. */
 union pref_hint
@@ -152,35 +127,42 @@ union pref_hint
 
 /*-- keydb.c --*/
 
-/*
-  Flag 1 == force
-  Flag 2 == default
-*/
-int keydb_add_resource (const char *url, int flags, int secret);
-KEYDB_HANDLE keydb_new (int secret);
+#define KEYDB_RESOURCE_FLAG_PRIMARY  2  /* The primary resource.  */
+#define KEYDB_RESOURCE_FLAG_DEFAULT  4  /* The default one.  */
+#define KEYDB_RESOURCE_FLAG_READONLY 8  /* Open in read only mode.  */
+
+gpg_error_t keydb_add_resource (const char *url, unsigned int flags);
+
+KEYDB_HANDLE keydb_new (void);
 void keydb_release (KEYDB_HANDLE hd);
+void keydb_disable_caching (KEYDB_HANDLE hd);
 const char *keydb_get_resource_name (KEYDB_HANDLE hd);
-int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
-int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-int keydb_delete_keyblock (KEYDB_HANDLE hd);
-int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
+gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
+gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
+gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
+gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd);
+gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
 void keydb_rebuild_caches (int noisy);
-int keydb_search_reset (KEYDB_HANDLE hd);
-#define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL)
-int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
-                  size_t ndesc, size_t *descindex);
-int keydb_search_first (KEYDB_HANDLE hd);
-int keydb_search_next (KEYDB_HANDLE hd);
-int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
-int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
-
+unsigned long keydb_get_skipped_counter (KEYDB_HANDLE hd);
+gpg_error_t keydb_search_reset (KEYDB_HANDLE hd);
+gpg_error_t keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
+                          size_t ndesc, size_t *descindex);
+gpg_error_t keydb_search_first (KEYDB_HANDLE hd);
+gpg_error_t keydb_search_next (KEYDB_HANDLE hd);
+gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
+gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
 
 /*-- pkclist.c --*/
 void show_revocation_reason( PKT_public_key *pk, int mode );
 int  check_signatures_trust( PKT_signature *sig );
-void release_pk_list( PK_LIST pk_list );
-int  build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use );
+
+void release_pk_list (PK_LIST pk_list);
+int  build_pk_list (ctrl_t ctrl,
+                    strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use);
+gpg_error_t find_and_check_key (ctrl_t ctrl,
+                                const char *name, unsigned int use,
+                                int mark_hidden, pk_list_t *pk_list_addr);
+
 int  algo_available( preftype_t preftype, int algo,
                     const union pref_hint *hint );
 int  select_algo_from_prefs( PK_LIST pk_list, int preftype,
@@ -192,14 +174,15 @@ void warn_missing_aes_from_pklist (PK_LIST pk_list);
 /*-- skclist.c --*/
 int  random_is_faked (void);
 void release_sk_list( SK_LIST sk_list );
-int  build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list,
-                                           int unlock, unsigned use );
+gpg_error_t  build_sk_list (strlist_t locusr, SK_LIST *ret_sk_list,
+                            unsigned use);
 
 /*-- passphrase.h --*/
 unsigned char encode_s2k_iterations (int iterations);
 assuan_context_t agent_open (int try, const char *orig_codeset);
 void agent_close (assuan_context_t ctx);
 int  have_static_passphrase(void);
+const char *get_static_passphrase (void);
 void set_passphrase_from_string(const char *pass);
 void read_passphrase_from_fd( int fd );
 void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo );
@@ -215,87 +198,104 @@ void set_next_passphrase( const char *s );
 char *get_last_passphrase(void);
 void next_to_last_passphrase(void);
 
+void emit_status_need_passphrase (u32 *keyid, u32 *mainkeyid, int pubkey_algo);
+
+#define FORMAT_KEYDESC_NORMAL  0
+#define FORMAT_KEYDESC_IMPORT  1
+#define FORMAT_KEYDESC_EXPORT  2
+#define FORMAT_KEYDESC_DELKEY  3
+char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped);
+
+
 /*-- getkey.c --*/
-int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc);
 void cache_public_key( PKT_public_key *pk );
 void getkey_disable_caches(void);
 int get_pubkey( PKT_public_key *pk, u32 *keyid );
 int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
 KBNODE get_pubkeyblock( u32 *keyid );
-int get_pubkey_byname (GETKEY_CTX *rx, PKT_public_key *pk,  const char *name,
+int get_pubkey_byname (ctrl_t ctrl,
+                       GETKEY_CTX *rx, PKT_public_key *pk,  const char *name,
                        KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
                       int include_unusable, int no_akl );
 int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
                        strlist_t names, KBNODE *ret_keyblock );
 int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );
 void get_pubkey_end( GETKEY_CTX ctx );
-int get_seckey( PKT_secret_key *sk, u32 *keyid );
-int get_primary_seckey( PKT_secret_key *sk, u32 *keyid );
+gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid);
+gpg_error_t get_pubkey_byfpr (PKT_public_key *pk, const byte *fpr);
 int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint,
                                                 size_t fprint_len );
 int get_pubkey_byfprint_fast (PKT_public_key *pk,
                               const byte *fprint, size_t fprint_len);
 int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
                                                 size_t fprint_len );
-int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid );
-int seckey_available( u32 *keyid );
-int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
-int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
-                       strlist_t names, KBNODE *ret_keyblock );
-int get_seckey_next (GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock);
-void get_seckey_end( GETKEY_CTX ctx );
 
-int get_seckey_byfprint( PKT_secret_key *sk,
-                        const byte *fprint, size_t fprint_len);
-int get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint,
-                              size_t fprint_len );
+int have_secret_key_with_kid (u32 *keyid);
 
+gpg_error_t get_seckey_byname (PKT_public_key *pk, const char *name);
 
-int enum_secret_keys( void **context, PKT_secret_key *sk,
-                     int with_subkeys, int with_spm );
+gpg_error_t get_seckey_byfprint (PKT_public_key *pk,
+                                 const byte *fprint, size_t fprint_len);
+gpg_error_t get_seckeyblock_byfprint (kbnode_t *ret_keyblock,
+                                      const byte *fprint, size_t fprint_len);
+
+gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
+                            strlist_t names, int want_secret,
+                            kbnode_t *ret_keyblock);
+gpg_error_t getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
+                           const char *name, int want_secret,
+                           kbnode_t *ret_keyblock);
+gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk,
+                         kbnode_t *ret_keyblock);
+void getkey_end (getkey_ctx_t ctx);
+
+gpg_error_t enum_secret_keys (void **context, PKT_public_key *pk);
+
+void setup_main_keyids (kbnode_t keyblock);
 void merge_keys_and_selfsig( KBNODE keyblock );
-char*get_user_id_string( u32 *keyid );
 char*get_user_id_string_native( u32 *keyid );
 char*get_long_user_id_string( u32 *keyid );
 char*get_user_id( u32 *keyid, size_t *rn );
 char*get_user_id_native( u32 *keyid );
+char *get_user_id_byfpr (const byte *fpr, size_t *rn);
+char *get_user_id_byfpr_native (const byte *fpr);
 KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
 void release_akl(void);
 int parse_auto_key_locate(char *options);
 
 /*-- keyid.c --*/
 int pubkey_letter( int algo );
+char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize);
+#define PUBKEY_STRING_SIZE 32
 u32 v3_keyid (gcry_mpi_t a, u32 *ki);
 void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk );
 size_t keystrlen(void);
 const char *keystr(u32 *keyid);
+const char *keystr_with_sub (u32 *main_kid, u32 *sub_kid);
 const char *keystr_from_pk(PKT_public_key *pk);
-const char *keystr_from_sk(PKT_secret_key *sk);
+const char *keystr_from_pk_with_sub (PKT_public_key *main_pk,
+                                     PKT_public_key *sub_pk);
 const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc);
-u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
 u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
 u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
 u32 keyid_from_fingerprint(const byte *fprint, size_t fprint_len, u32 *keyid);
 byte *namehash_from_uid(PKT_user_id *uid);
 unsigned nbits_from_pk( PKT_public_key *pk );
-unsigned nbits_from_sk( PKT_secret_key *sk );
 const char *datestr_from_pk( PKT_public_key *pk );
-const char *datestr_from_sk( PKT_secret_key *sk );
 const char *datestr_from_sig( PKT_signature *sig );
 const char *expirestr_from_pk( PKT_public_key *pk );
-const char *expirestr_from_sk( PKT_secret_key *sk );
 const char *expirestr_from_sig( PKT_signature *sig );
 const char *revokestr_from_pk( PKT_public_key *pk );
-const char *usagestr_from_pk( PKT_public_key *pk );
+const char *usagestr_from_pk (PKT_public_key *pk, int fill);
 const char *colon_strtime (u32 t);
 const char *colon_datestr_from_pk (PKT_public_key *pk);
-const char *colon_datestr_from_sk (PKT_secret_key *sk);
 const char *colon_datestr_from_sig (PKT_signature *sig);
 const char *colon_expirestr_from_sig (PKT_signature *sig);
-byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
 byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
-char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
-                                PKT_secret_key *sk);
+char *hexfingerprint (PKT_public_key *pk);
+gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array);
+gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip);
+
 
 /*-- kbnode.c --*/
 KBNODE new_kbnode( PACKET *pkt );
index bfad4f8..a8e6f5d 100644 (file)
@@ -1,6 +1,7 @@
 /* keyedit.c - keyedit stuff
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- *               2008, 2009, 2010, 2015 Free Software Foundation, Inc.
+ *               2008, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include <assert.h>
 #include <ctype.h>
 #ifdef HAVE_LIBREADLINE
-#define GNUPG_LIBREADLINE_H_INCLUDED
-#include <readline/readline.h>
+# define GNUPG_LIBREADLINE_H_INCLUDED
+# include <readline/readline.h>
 #endif
 
+#define JNLIB_NEED_LOG_LOGV
 #include "gpg.h"
 #include "options.h"
 #include "packet.h"
 #include "status.h"
 #include "i18n.h"
 #include "keyserver-internal.h"
-
-static void show_prefs( PKT_user_id *uid, PKT_signature *selfsig, int verbose);
-static void show_names(KBNODE keyblock,PKT_public_key *pk,
-                      unsigned int flag,int with_prefs);
-static void show_key_with_all_names( KBNODE keyblock, int only_marked,
-           int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
-static void show_key_and_fingerprint( KBNODE keyblock );
+#include "call-agent.h"
+
+static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
+                       int verbose);
+static void show_names (estream_t fp, KBNODE keyblock, PKT_public_key * pk,
+                       unsigned int flag, int with_prefs);
+static void show_key_with_all_names (estream_t fp,
+                                     KBNODE keyblock, int only_marked,
+                                    int with_revoker, int with_fpr,
+                                    int with_subkeys, int with_prefs,
+                                     int nowarn);
+static void show_key_and_fingerprint (KBNODE keyblock);
 static void subkey_expire_warning (kbnode_t keyblock);
-static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock,
-                       int photo, const char *photo_name );
-static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_delsig( KBNODE pub_keyblock );
-static int menu_clean(KBNODE keyblock,int self_only);
-static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_addrevoker( KBNODE pub_keyblock,
-                           KBNODE sec_keyblock, int sensitive );
-static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock);
-static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_keyserver_url (const char *url,
-                                  KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_notation(const char *string,
-                            KBNODE pub_keyblock,KBNODE sec_keyblock);
-static int menu_select_uid( KBNODE keyblock, int idx );
-static int menu_select_uid_namehash( KBNODE keyblock, const char *namehash );
-static int menu_select_key( KBNODE keyblock, int idx );
-static int count_uids( KBNODE keyblock );
-static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
-static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
-static int count_selected_uids( KBNODE keyblock );
-static int real_uids_left( KBNODE keyblock );
-static int count_selected_keys( KBNODE keyblock );
-static int menu_revsig( KBNODE keyblock );
-static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
-static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int enable_disable_key( KBNODE keyblock, int disable );
-static void menu_showphoto( KBNODE keyblock );
-
-static int update_trust=0;
+static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name);
+static void menu_deluid (KBNODE pub_keyblock);
+static int menu_delsig (KBNODE pub_keyblock);
+static int menu_clean (KBNODE keyblock, int self_only);
+static void menu_delkey (KBNODE pub_keyblock);
+static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
+static int menu_expire (KBNODE pub_keyblock);
+static int menu_backsign (KBNODE pub_keyblock);
+static int menu_set_primary_uid (KBNODE pub_keyblock);
+static int menu_set_preferences (KBNODE pub_keyblock);
+static int menu_set_keyserver_url (const char *url, KBNODE pub_keyblock);
+static int menu_set_notation (const char *string, KBNODE pub_keyblock);
+static int menu_select_uid (KBNODE keyblock, int idx);
+static int menu_select_uid_namehash (KBNODE keyblock, const char *namehash);
+static int menu_select_key (KBNODE keyblock, int idx);
+static int count_uids (KBNODE keyblock);
+static int count_uids_with_flag (KBNODE keyblock, unsigned flag);
+static int count_keys_with_flag (KBNODE keyblock, unsigned flag);
+static int count_selected_uids (KBNODE keyblock);
+static int real_uids_left (KBNODE keyblock);
+static int count_selected_keys (KBNODE keyblock);
+static int menu_revsig (KBNODE keyblock);
+static int menu_revuid (KBNODE keyblock);
+static int menu_revkey (KBNODE pub_keyblock);
+static int menu_revsubkey (KBNODE pub_keyblock);
+#ifndef NO_TRUST_MODELS
+static int enable_disable_key (KBNODE keyblock, int disable);
+#endif /*!NO_TRUST_MODELS*/
+static void menu_showphoto (KBNODE keyblock);
+
+static int update_trust = 0;
 
 #define CONTROL_D ('D' - 'A' + 1)
 
-#define NODFLG_BADSIG (1<<0)  /* bad signature */
-#define NODFLG_NOKEY  (1<<1)  /* no public key */
-#define NODFLG_SIGERR (1<<2)  /* other sig error */
-
-#define NODFLG_MARK_A (1<<4)  /* temporary mark */
-#define NODFLG_DELSIG (1<<5)  /* to be deleted */
+#define NODFLG_BADSIG (1<<0)   /* Bad signature.  */
+#define NODFLG_NOKEY  (1<<1)   /* No public key.  */
+#define NODFLG_SIGERR (1<<2)   /* Other sig error.  */
 
-#define NODFLG_SELUID (1<<8)  /* indicate the selected userid */
-#define NODFLG_SELKEY (1<<9)  /* indicate the selected key */
-#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
-
-struct sign_attrib {
-    int non_exportable,non_revocable;
-    struct revocation_reason_info *reason;
-    byte trust_depth,trust_value;
-    char *trust_regexp;
-};
+#define NODFLG_MARK_A (1<<4)   /* Temporary mark.  */
+#define NODFLG_DELSIG (1<<5)   /* To be deleted.  */
 
+#define NODFLG_SELUID (1<<8)   /* Indicate the selected userid. */
+#define NODFLG_SELKEY (1<<9)   /* Indicate the selected key.  */
+#define NODFLG_SELSIG (1<<10)  /* Indicate a selected signature.  */
 
-#ifdef ENABLE_CARD_SUPPORT
-/* Given a node SEC_NODE with a secret key or subkey, locate the
-   corresponding public key from pub_keyblock. */
-static PKT_public_key *
-find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node)
+struct sign_attrib
 {
-  KBNODE node = pub_keyblock;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-
-  if (sec_node->pkt->pkttype == PKT_SECRET_KEY
-      && node->pkt->pkttype == PKT_PUBLIC_KEY)
-    return node->pkt->pkt.public_key;
-  if (sec_node->pkt->pkttype != PKT_SECRET_SUBKEY)
-    return NULL;
-  sk = sec_node->pkt->pkt.secret_key;
-  for (; node; node = node->next)
-    if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-      {
-        pk = node->pkt->pkt.public_key;
-        if (pk->keyid[0] == sk->keyid[0] && pk->keyid[1] == sk->keyid[1])
-          return pk;
-      }
+  int non_exportable, non_revocable;
+  struct revocation_reason_info *reason;
+  byte trust_depth, trust_value;
+  char *trust_regexp;
+};
 
-  return NULL;
-}
-#endif /* ENABLE_CARD_SUPPORT */
 
 
 /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
    code in keylist.c. */
 static int
-print_and_check_one_sig_colonKBNODE keyblock, KBNODE node,
+print_and_check_one_sig_colon (KBNODE keyblock, KBNODE node,
                               int *inv_sigs, int *no_key, int *oth_err,
-                              int *is_selfsig, int print_without_key )
+                              int *is_selfsig, int print_without_key)
 {
   PKT_signature *sig = node->pkt->pkt.signature;
   int rc, sigrc;
@@ -150,1126 +128,1051 @@ print_and_check_one_sig_colon( KBNODE keyblock, KBNODE node,
   /* TODO: Make sure a cached sig record here still has the pk that
      issued it.  See also keylist.c:list_keyblock_print */
 
-  switch((rc=check_key_signature(keyblock,node,is_selfsig)))
+  switch ((rc = check_key_signature (keyblock, node, is_selfsig)))
     {
     case 0:
-      node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
+      node->flag &= ~(NODFLG_BADSIG | NODFLG_NOKEY | NODFLG_SIGERR);
       sigrc = '!';
       break;
     case G10ERR_BAD_SIGN:
       node->flag = NODFLG_BADSIG;
       sigrc = '-';
-      if( inv_sigs )
-       ++*inv_sigs;
+      if (inv_sigs)
+       ++ * inv_sigs;
       break;
     case G10ERR_NO_PUBKEY:
     case G10ERR_UNU_PUBKEY:
       node->flag = NODFLG_NOKEY;
       sigrc = '?';
-      if( no_key )
-       ++*no_key;
+      if (no_key)
+       ++ * no_key;
       break;
     default:
       node->flag = NODFLG_SIGERR;
       sigrc = '%';
-      if( oth_err )
-       ++*oth_err;
+      if (oth_err)
+       ++ * oth_err;
       break;
     }
 
-  if( sigrc != '?' || print_without_key )
+  if (sigrc != '?' || print_without_key)
     {
-      printf("sig:%c::%d:%08lX%08lX:%lu:%lu:",
-            sigrc,sig->pubkey_algo,(ulong)sig->keyid[0],(ulong)sig->keyid[1],
-            (ulong)sig->timestamp,(ulong)sig->expiredate);
+      printf ("sig:%c::%d:%08lX%08lX:%lu:%lu:",
+             sigrc, sig->pubkey_algo, (ulong) sig->keyid[0],
+             (ulong) sig->keyid[1], (ulong) sig->timestamp,
+             (ulong) sig->expiredate);
 
-      if(sig->trust_depth || sig->trust_value)
-       printf("%d %d",sig->trust_depth,sig->trust_value);
+      if (sig->trust_depth || sig->trust_value)
+       printf ("%d %d", sig->trust_depth, sig->trust_value);
 
-      printf(":");
+      printf (":");
 
-      if(sig->trust_regexp)
-       print_string(stdout,sig->trust_regexp,strlen(sig->trust_regexp),':');
+      if (sig->trust_regexp)
+       es_write_sanitized (es_stdout,
+                           sig->trust_regexp, strlen (sig->trust_regexp),
+                           ":", NULL);
 
-      printf("::%02x%c\n",sig->sig_class,sig->flags.exportable?'x':'l');
+      printf ("::%02x%c\n", sig->sig_class,
+             sig->flags.exportable ? 'x' : 'l');
 
-      if(opt.show_subpackets)
-       print_subpackets_colon(sig);
+      if (opt.show_subpackets)
+       print_subpackets_colon (sig);
     }
 
   return (sigrc == '!');
 }
 
 
-/****************
+/*
  * Print information about a signature, check it and return true
  * if the signature is okay. NODE must be a signature packet.
  */
 static int
-print_and_check_one_sigKBNODE keyblock, KBNODE node,
+print_and_check_one_sig (KBNODE keyblock, KBNODE node,
                         int *inv_sigs, int *no_key, int *oth_err,
-                       int *is_selfsig, int print_without_key )
+                        int *is_selfsig, int print_without_key)
 {
-    PKT_signature *sig = node->pkt->pkt.signature;
-    int rc, sigrc;
-    int is_rev = sig->sig_class == 0x30;
+  PKT_signature *sig = node->pkt->pkt.signature;
+  int rc, sigrc;
+  int is_rev = sig->sig_class == 0x30;
 
-    /* TODO: Make sure a cached sig record here still has the pk that
-       issued it.  See also keylist.c:list_keyblock_print */
+  /* TODO: Make sure a cached sig record here still has the pk that
+     issued it.  See also keylist.c:list_keyblock_print */
 
-    switch( (rc = check_key_signature( keyblock, node, is_selfsig)) ) {
-      case 0:
-       node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
-       sigrc = '!';
-       break;
-      case G10ERR_BAD_SIGN:
-       node->flag = NODFLG_BADSIG;
-       sigrc = '-';
-       if( inv_sigs )
-           ++*inv_sigs;
-       break;
-      case G10ERR_NO_PUBKEY:
-      case G10ERR_UNU_PUBKEY:
-       node->flag = NODFLG_NOKEY;
-       sigrc = '?';
-       if( no_key )
-           ++*no_key;
-       break;
-      default:
-       node->flag = NODFLG_SIGERR;
-       sigrc = '%';
-       if( oth_err )
-           ++*oth_err;
-       break;
+  switch ((rc = check_key_signature (keyblock, node, is_selfsig)))
+    {
+    case 0:
+      node->flag &= ~(NODFLG_BADSIG | NODFLG_NOKEY | NODFLG_SIGERR);
+      sigrc = '!';
+      break;
+    case G10ERR_BAD_SIGN:
+      node->flag = NODFLG_BADSIG;
+      sigrc = '-';
+      if (inv_sigs)
+       ++ * inv_sigs;
+      break;
+    case G10ERR_NO_PUBKEY:
+    case G10ERR_UNU_PUBKEY:
+      node->flag = NODFLG_NOKEY;
+      sigrc = '?';
+      if (no_key)
+       ++ * no_key;
+      break;
+    default:
+      node->flag = NODFLG_SIGERR;
+      sigrc = '%';
+      if (oth_err)
+       ++ * oth_err;
+      break;
     }
-    if( sigrc != '?' || print_without_key ) {
-        tty_printf("%s%c%c %c%c%c%c%c%c %s %s",
-                  is_rev? "rev":"sig",sigrc,
-                  (sig->sig_class-0x10>0 &&
-                   sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
-                  sig->flags.exportable?' ':'L',
-                  sig->flags.revocable?' ':'R',
-                  sig->flags.policy_url?'P':' ',
-                  sig->flags.notation?'N':' ',
-                   sig->flags.expired?'X':' ',
-                  (sig->trust_depth>9)?'T':
-                  (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
-                  keystr(sig->keyid),datestr_from_sig(sig));
-       if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
-         tty_printf(" %s",expirestr_from_sig(sig));
-       tty_printf("  ");
-       if( sigrc == '%' )
-           tty_printf("[%s] ", g10_errstr(rc) );
-       else if( sigrc == '?' )
-           ;
-       else if( *is_selfsig ) {
-           tty_printf( is_rev? _("[revocation]")
-                             : _("[self-signature]") );
+  if (sigrc != '?' || print_without_key)
+    {
+      tty_printf ("%s%c%c %c%c%c%c%c%c %s %s",
+                 is_rev ? "rev" : "sig", sigrc,
+                 (sig->sig_class - 0x10 > 0 &&
+                  sig->sig_class - 0x10 <
+                  4) ? '0' + sig->sig_class - 0x10 : ' ',
+                 sig->flags.exportable ? ' ' : 'L',
+                 sig->flags.revocable ? ' ' : 'R',
+                 sig->flags.policy_url ? 'P' : ' ',
+                 sig->flags.notation ? 'N' : ' ',
+                 sig->flags.expired ? 'X' : ' ',
+                 (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
+                                                 0) ? '0' +
+                 sig->trust_depth : ' ', keystr (sig->keyid),
+                 datestr_from_sig (sig));
+      if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
+       tty_printf (" %s", expirestr_from_sig (sig));
+      tty_printf ("  ");
+      if (sigrc == '%')
+       tty_printf ("[%s] ", g10_errstr (rc));
+      else if (sigrc == '?')
+       ;
+      else if (*is_selfsig)
+       {
+         tty_printf (is_rev ? _("[revocation]") : _("[self-signature]"));
        }
-       else
-         {
-           size_t n;
-           char *p = get_user_id( sig->keyid, &n );
-           tty_print_utf8_string2(p, n, opt.screen_columns-keystrlen()-26-
-                              ((opt.list_options&LIST_SHOW_SIG_EXPIRE)?11:0));
-           xfree(p);
-         }
-       tty_printf("\n");
+      else
+       {
+         size_t n;
+         char *p = get_user_id (sig->keyid, &n);
+         tty_print_utf8_string2 (NULL, p, n,
+                                 opt.screen_columns - keystrlen () - 26 -
+                                 ((opt.
+                                   list_options & LIST_SHOW_SIG_EXPIRE) ? 11
+                                  : 0));
+         xfree (p);
+       }
+      tty_printf ("\n");
 
-       if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY_URLS))
-         show_policy_url(sig,3,0);
+      if (sig->flags.policy_url && (opt.list_options & LIST_SHOW_POLICY_URLS))
+       show_policy_url (sig, 3, 0);
 
-       if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATIONS))
-         show_notation(sig,3,0,
-                       ((opt.list_options&LIST_SHOW_STD_NOTATIONS)?1:0)+
-                       ((opt.list_options&LIST_SHOW_USER_NOTATIONS)?2:0));
+      if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
+       show_notation (sig, 3, 0,
+                      ((opt.
+                        list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) +
+                      ((opt.
+                        list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0));
 
-       if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER_URLS))
-         show_keyserver_url(sig,3,0);
+      if (sig->flags.pref_ks && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
+       show_keyserver_url (sig, 3, 0);
     }
 
-    return (sigrc == '!');
+  return (sigrc == '!');
 }
 
 
 
-/****************
+/*
  * Check the keysigs and set the flags to indicate errors.
  * Returns true if error found.
  */
 static int
-check_all_keysigs( KBNODE keyblock, int only_selected )
+check_all_keysigs (KBNODE keyblock, int only_selected)
 {
-    KBNODE kbctx;
-    KBNODE node;
-    int inv_sigs = 0;
-    int no_key = 0;
-    int oth_err = 0;
-    int has_selfsig = 0;
-    int mis_selfsig = 0;
-    int selected = !only_selected;
-    int anyuid = 0;
-
-    for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
-       if( node->pkt->pkttype == PKT_USER_ID ) {
-           PKT_user_id *uid = node->pkt->pkt.user_id;
-
-           if( only_selected )
-               selected = (node->flag & NODFLG_SELUID);
-           if( selected ) {
-               tty_printf("uid  ");
-               tty_print_utf8_string( uid->name, uid->len );
-               tty_printf("\n");
-               if( anyuid && !has_selfsig )
-                   mis_selfsig++;
-               has_selfsig = 0;
-               anyuid = 1;
+  KBNODE kbctx;
+  KBNODE node;
+  int inv_sigs = 0;
+  int no_key = 0;
+  int oth_err = 0;
+  int has_selfsig = 0;
+  int mis_selfsig = 0;
+  int selected = !only_selected;
+  int anyuid = 0;
+
+  for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         PKT_user_id *uid = node->pkt->pkt.user_id;
+
+         if (only_selected)
+           selected = (node->flag & NODFLG_SELUID);
+         if (selected)
+           {
+             tty_printf ("uid  ");
+             tty_print_utf8_string (uid->name, uid->len);
+             tty_printf ("\n");
+             if (anyuid && !has_selfsig)
+               mis_selfsig++;
+             has_selfsig = 0;
+             anyuid = 1;
            }
        }
-       else if( selected && node->pkt->pkttype == PKT_SIGNATURE
-                && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
-                    || node->pkt->pkt.signature->sig_class == 0x30 )  ) {
-           int selfsig;
-
-           if( print_and_check_one_sig( keyblock, node, &inv_sigs,
-                                       &no_key, &oth_err, &selfsig, 0 ) ) {
-               if( selfsig )
-                   has_selfsig = 1;
+      else if (selected && node->pkt->pkttype == PKT_SIGNATURE
+              && ((node->pkt->pkt.signature->sig_class & ~3) == 0x10
+                  || node->pkt->pkt.signature->sig_class == 0x30))
+       {
+         int selfsig;
+
+         if (print_and_check_one_sig (keyblock, node, &inv_sigs,
+                                      &no_key, &oth_err, &selfsig, 0))
+           {
+             if (selfsig)
+               has_selfsig = 1;
            }
-           /* Hmmm: should we update the trustdb here? */
+         /* Hmmm: should we update the trustdb here? */
        }
     }
-    if( !has_selfsig )
-       mis_selfsig++;
-    if( inv_sigs == 1 )
-       tty_printf(_("1 bad signature\n") );
-    else if( inv_sigs )
-       tty_printf(_("%d bad signatures\n"), inv_sigs );
-    if( no_key == 1 )
-       tty_printf(_("1 signature not checked due to a missing key\n") );
-    else if( no_key )
-       tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
-    if( oth_err == 1 )
-       tty_printf(_("1 signature not checked due to an error\n") );
-    else if( oth_err )
-       tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
-    if( mis_selfsig == 1 )
-       tty_printf(_("1 user ID without valid self-signature detected\n"));
-    else if( mis_selfsig  )
-       tty_printf(_("%d user IDs without valid self-signatures detected\n"),
-                                                                   mis_selfsig);
-
-    return inv_sigs || no_key || oth_err || mis_selfsig;
+  if (!has_selfsig)
+    mis_selfsig++;
+  if (inv_sigs == 1)
+    tty_printf (_("1 bad signature\n"));
+  else if (inv_sigs)
+    tty_printf (_("%d bad signatures\n"), inv_sigs);
+  if (no_key == 1)
+    tty_printf (_("1 signature not checked due to a missing key\n"));
+  else if (no_key)
+    tty_printf (_("%d signatures not checked due to missing keys\n"), no_key);
+  if (oth_err == 1)
+    tty_printf (_("1 signature not checked due to an error\n"));
+  else if (oth_err)
+    tty_printf (_("%d signatures not checked due to errors\n"), oth_err);
+  if (mis_selfsig == 1)
+    tty_printf (_("1 user ID without valid self-signature detected\n"));
+  else if (mis_selfsig)
+    tty_printf (_("%d user IDs without valid self-signatures detected\n"),
+               mis_selfsig);
+
+  return inv_sigs || no_key || oth_err || mis_selfsig;
 }
 
 
 static int
-sign_mk_attrib( PKT_signature *sig, void *opaque )
+sign_mk_attrib (PKT_signature * sig, void *opaque)
 {
-    struct sign_attrib *attrib = opaque;
-    byte buf[8];
+  struct sign_attrib *attrib = opaque;
+  byte buf[8];
 
-    if( attrib->non_exportable ) {
-       buf[0] = 0; /* not exportable */
-       build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
+  if (attrib->non_exportable)
+    {
+      buf[0] = 0;              /* not exportable */
+      build_sig_subpkt (sig, SIGSUBPKT_EXPORTABLE, buf, 1);
     }
 
-    if( attrib->non_revocable ) {
-       buf[0] = 0; /* not revocable */
-       build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
+  if (attrib->non_revocable)
+    {
+      buf[0] = 0;              /* not revocable */
+      build_sig_subpkt (sig, SIGSUBPKT_REVOCABLE, buf, 1);
     }
 
-    if( attrib->reason )
-       revocation_reason_build_cb( sig, attrib->reason );
+  if (attrib->reason)
+    revocation_reason_build_cb (sig, attrib->reason);
 
-    if(attrib->trust_depth)
-      {
-       /* Not critical.  If someone doesn't understand trust sigs,
-          this can still be a valid regular signature. */
-        buf[0] = attrib->trust_depth;
-       buf[1] = attrib->trust_value;
-       build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
-
-       /* Critical.  If someone doesn't understands regexps, this
-          whole sig should be invalid.  Note the +1 for the length -
-          regexps are null terminated. */
-       if(attrib->trust_regexp)
-         build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
-                          attrib->trust_regexp,
-                          strlen(attrib->trust_regexp)+1);
-      }
+  if (attrib->trust_depth)
+    {
+      /* Not critical.  If someone doesn't understand trust sigs,
+         this can still be a valid regular signature. */
+      buf[0] = attrib->trust_depth;
+      buf[1] = attrib->trust_value;
+      build_sig_subpkt (sig, SIGSUBPKT_TRUST, buf, 2);
+
+      /* Critical.  If someone doesn't understands regexps, this
+         whole sig should be invalid.  Note the +1 for the length -
+         regexps are null terminated. */
+      if (attrib->trust_regexp)
+       build_sig_subpkt (sig, SIGSUBPKT_FLAG_CRITICAL | SIGSUBPKT_REGEXP,
+                         attrib->trust_regexp,
+                         strlen (attrib->trust_regexp) + 1);
+    }
 
-    return 0;
+  return 0;
 }
 
+
 static void
-trustsig_prompt(byte *trust_value,byte *trust_depth,char **regexp)
+trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp)
 {
   char *p;
 
-  *trust_value=0;
-  *trust_depth=0;
-  *regexp=NULL;
+  *trust_value = 0;
+  *trust_depth = 0;
+  *regexp = NULL;
 
   /* Same string as pkclist.c:do_edit_ownertrust */
-  tty_printf(_("Please decide how far you trust this user to correctly verify"
+  tty_printf (_
+             ("Please decide how far you trust this user to correctly verify"
               " other users' keys\n(by looking at passports, checking"
               " fingerprints from different sources, etc.)\n"));
-  tty_printf("\n");
+  tty_printf ("\n");
   tty_printf (_("  %d = I trust marginally\n"), 1);
   tty_printf (_("  %d = I trust fully\n"), 2);
-  tty_printf("\n");
+  tty_printf ("\n");
 
-  while(*trust_value==0)
+  while (*trust_value == 0)
     {
-      p = cpr_get("trustsig_prompt.trust_value",_("Your selection? "));
-      trim_spaces(p);
-      cpr_kill_prompt();
+      p = cpr_get ("trustsig_prompt.trust_value", _("Your selection? "));
+      trim_spaces (p);
+      cpr_kill_prompt ();
       /* 60 and 120 are as per RFC2440 */
-      if(p[0]=='1' && !p[1])
-       *trust_value=60;
-      else if(p[0]=='2' && !p[1])
-       *trust_value=120;
-      xfree(p);
+      if (p[0] == '1' && !p[1])
+       *trust_value = 60;
+      else if (p[0] == '2' && !p[1])
+       *trust_value = 120;
+      xfree (p);
     }
 
-  tty_printf("\n");
+  tty_printf ("\n");
 
-  tty_printf(_(
-             "Please enter the depth of this trust signature.\n"
-             "A depth greater than 1 allows the key you are signing to make\n"
-             "trust signatures on your behalf.\n"));
-  tty_printf("\n");
+  tty_printf (_("Please enter the depth of this trust signature.\n"
+               "A depth greater than 1 allows the key you are signing to make\n"
+               "trust signatures on your behalf.\n"));
+  tty_printf ("\n");
 
-  while(*trust_depth==0)
+  while (*trust_depth == 0)
     {
-      p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? "));
-      trim_spaces(p);
-      cpr_kill_prompt();
-      *trust_depth=atoi(p);
-      xfree(p);
+      p = cpr_get ("trustsig_prompt.trust_depth", _("Your selection? "));
+      trim_spaces (p);
+      cpr_kill_prompt ();
+      *trust_depth = atoi (p);
+      xfree (p);
     }
 
-  tty_printf("\n");
+  tty_printf ("\n");
 
-  tty_printf(_("Please enter a domain to restrict this signature, "
-              "or enter for none.\n"));
+  tty_printf (_("Please enter a domain to restrict this signature, "
+               "or enter for none.\n"));
 
-  tty_printf("\n");
+  tty_printf ("\n");
 
-  p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? "));
-  trim_spaces(p);
-  cpr_kill_prompt();
+  p = cpr_get ("trustsig_prompt.trust_regexp", _("Your selection? "));
+  trim_spaces (p);
+  cpr_kill_prompt ();
 
-  if(strlen(p)>0)
+  if (strlen (p) > 0)
     {
-      char *q=p;
-      int regexplen=100,ind;
+      char *q = p;
+      int regexplen = 100, ind;
 
-      *regexp=xmalloc(regexplen);
+      *regexp = xmalloc (regexplen);
 
       /* Now mangle the domain the user entered into a regexp.  To do
-        this, \-escape everything that isn't alphanumeric, and attach
-        "<[^>]+[@.]" to the front, and ">$" to the end. */
+         this, \-escape everything that isn't alphanumeric, and attach
+         "<[^>]+[@.]" to the front, and ">$" to the end. */
 
-      strcpy(*regexp,"<[^>]+[@.]");
-      ind=strlen(*regexp);
+      strcpy (*regexp, "<[^>]+[@.]");
+      ind = strlen (*regexp);
 
-      while(*q)
+      while (*q)
        {
-         if(!((*q>='A' && *q<='Z')
-              || (*q>='a' && *q<='z') || (*q>='0' && *q<='9')))
-           (*regexp)[ind++]='\\';
+         if (!((*q >= 'A' && *q <= 'Z')
+               || (*q >= 'a' && *q <= 'z') || (*q >= '0' && *q <= '9')))
+           (*regexp)[ind++] = '\\';
 
-         (*regexp)[ind++]=*q;
+         (*regexp)[ind++] = *q;
 
-         if((regexplen-ind)<3)
+         if ((regexplen - ind) < 3)
            {
-             regexplen+=100;
-             *regexp=xrealloc(*regexp,regexplen);
+             regexplen += 100;
+             *regexp = xrealloc (*regexp, regexplen);
            }
 
          q++;
        }
 
-      (*regexp)[ind]='\0';
-      strcat(*regexp,">$");
+      (*regexp)[ind] = '\0';
+      strcat (*regexp, ">$");
     }
 
-  xfree(p);
-  tty_printf("\n");
+  xfree (p);
+  tty_printf ("\n");
 }
 
-/****************
- * Loop over all locusr and and sign the uids after asking.
- * If no user id is marked, all user ids will be signed;
- * if some user_ids are marked those will be signed.
+
+/*
+ * Loop over all LOCUSR and and sign the uids after asking.  If no
+ * user id is marked, all user ids will be signed; if some user_ids
+ * are marked only those will be signed.  If QUICK is true the
+ * function won't ask the user and use sensible defaults.
  */
 static int
-sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
-          int local, int nonrevocable, int trust, int interactive )
+sign_uids (estream_t fp,
+           kbnode_t keyblock, strlist_t locusr, int *ret_modified,
+          int local, int nonrevocable, int trust, int interactive,
+           int quick)
 {
-    int rc = 0;
-    SK_LIST sk_list = NULL;
-    SK_LIST sk_rover = NULL;
-    PKT_secret_key *sk = NULL;
-    KBNODE node, uidnode;
-    PKT_public_key *primary_pk=NULL;
-    int select_all = !count_selected_uids(keyblock) || interactive;
-    int all_v3=1;
-
-    /* Are there any non-v3 sigs on this key already? */
-    if(PGP2)
-      for(node=keyblock;node;node=node->next)
-       if(node->pkt->pkttype==PKT_SIGNATURE &&
-          node->pkt->pkt.signature->version>3)
-         {
-           all_v3=0;
-           break;
-         }
+  int rc = 0;
+  SK_LIST sk_list = NULL;
+  SK_LIST sk_rover = NULL;
+  PKT_public_key *pk = NULL;
+  KBNODE node, uidnode;
+  PKT_public_key *primary_pk = NULL;
+  int select_all = !count_selected_uids (keyblock) || interactive;
+
+  /* Build a list of all signators.
+   *
+   * We use the CERT flag to request the primary which must always
+   * be one which is capable of signing keys.  I can't see a reason
+   * why to sign keys using a subkey.  Implementation of USAGE_CERT
+   * is just a hack in getkey.c and does not mean that a subkey
+   * marked as certification capable will be used. */
+  rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_CERT);
+  if (rc)
+    goto leave;
 
-    /* build a list of all signators.
-     *
-     * We use the CERT flag to request the primary which must always
-     * be one which is capable of signing keys.  I can't see a reason
-     * why to sign keys using a subkey.  Implementation of USAGE_CERT
-     * is just a hack in getkey.c and does not mean that a subkey
-     * marked as certification capable will be used. */
-    rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_CERT);
-    if( rc )
-       goto leave;
-
-    /* loop over all signators */
-    for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-        u32 sk_keyid[2],pk_keyid[2];
-       char *p,*trust_regexp=NULL;
-       int force_v4=0,class=0,selfsig=0;
-       u32 duration=0,timestamp=0;
-       byte trust_depth=0,trust_value=0;
-
-       if(local || nonrevocable || trust ||
-          opt.cert_policy_url || opt.cert_notations)
-         force_v4=1;
-
-       /* we have to use a copy of the sk, because make_keysig_packet
-        * may remove the protection from sk and if we did other
-        * changes to the secret key, we would save the unprotected
-        * version */
-       if( sk )
-           free_secret_key(sk);
-       sk = copy_secret_key( NULL, sk_rover->sk );
-       keyid_from_sk( sk, sk_keyid );
-       /* set mark A for all selected user ids */
-       for( node=keyblock; node; node = node->next ) {
-           if( select_all || (node->flag & NODFLG_SELUID) )
-               node->flag |= NODFLG_MARK_A;
-           else
-               node->flag &= ~NODFLG_MARK_A;
+  /* Loop over all signators.  */
+  for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
+    {
+      u32 sk_keyid[2], pk_keyid[2];
+      char *p, *trust_regexp = NULL;
+      int class = 0, selfsig = 0;
+      u32 duration = 0, timestamp = 0;
+      byte trust_depth = 0, trust_value = 0;
+
+      pk = sk_rover->pk;
+      keyid_from_pk (pk, sk_keyid);
+
+      /* Set mark A for all selected user ids.  */
+      for (node = keyblock; node; node = node->next)
+       {
+         if (select_all || (node->flag & NODFLG_SELUID))
+           node->flag |= NODFLG_MARK_A;
+         else
+           node->flag &= ~NODFLG_MARK_A;
        }
-       /* reset mark for uids which are already signed */
-       uidnode = NULL;
-       for( node=keyblock; node; node = node->next ) {
-           if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
-               primary_pk=node->pkt->pkt.public_key;
-               keyid_from_pk( primary_pk, pk_keyid );
-
-               /* Is this a self-sig? */
-               if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1])
-                 {
-                   selfsig=1;
-                   /* Do not force a v4 sig here, otherwise it would
-                       be difficult to remake a v3 selfsig.  If this
-                       is a v3->v4 promotion case, then we set
-                       force_v4 later anyway. */
-                   force_v4=0;
-                 }
+
+      /* Reset mark for uids which are already signed.  */
+      uidnode = NULL;
+      for (node = keyblock; node; node = node->next)
+       {
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+           {
+             primary_pk = node->pkt->pkt.public_key;
+             keyid_from_pk (primary_pk, pk_keyid);
+
+             /* Is this a self-sig? */
+             if (pk_keyid[0] == sk_keyid[0] && pk_keyid[1] == sk_keyid[1])
+                selfsig = 1;
            }
-           else if( node->pkt->pkttype == PKT_USER_ID )
-             {
-               uidnode = (node->flag & NODFLG_MARK_A)? node : NULL;
-               if(uidnode)
-                 {
-                   int yesreally=0;
-                   char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
-                                             uidnode->pkt->pkt.user_id->len,
-                                             0);
+         else if (node->pkt->pkttype == PKT_USER_ID)
+           {
+             uidnode = (node->flag & NODFLG_MARK_A) ? node : NULL;
+             if (uidnode)
+               {
+                 int yesreally = 0;
+                 char *user;
 
-                   if(uidnode->pkt->pkt.user_id->is_revoked)
-                     {
-                       tty_printf(_("User ID \"%s\" is revoked."),user);
+                  user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
+                                         uidnode->pkt->pkt.user_id->len, 0);
 
-                       if(selfsig)
-                         tty_printf("\n");
-                       else if(opt.expert)
-                         {
-                           tty_printf("\n");
-                           /* No, so remove the mark and continue */
-                           if(!cpr_get_answer_is_yes("sign_uid.revoke_okay",
+                 if (uidnode->pkt->pkt.user_id->is_revoked)
+                   {
+                     tty_fprintf (fp, _("User ID \"%s\" is revoked."), user);
+
+                     if (selfsig)
+                       tty_fprintf (fp, "\n");
+                     else if (opt.expert && !quick)
+                       {
+                         tty_fprintf (fp, "\n");
+                         /* No, so remove the mark and continue */
+                         if (!cpr_get_answer_is_yes ("sign_uid.revoke_okay",
                                                      _("Are you sure you "
                                                        "still want to sign "
                                                        "it? (y/N) ")))
-                             {
-                               uidnode->flag &= ~NODFLG_MARK_A;
-                               uidnode=NULL;
-                             }
-                           else if(interactive)
-                             yesreally=1;
-                         }
-                       else
-                         {
-                           uidnode->flag &= ~NODFLG_MARK_A;
-                           uidnode=NULL;
-                           tty_printf(_("  Unable to sign.\n"));
-                         }
-                     }
-                   else if(uidnode->pkt->pkt.user_id->is_expired)
-                     {
-                       tty_printf(_("User ID \"%s\" is expired."),user);
+                           {
+                             uidnode->flag &= ~NODFLG_MARK_A;
+                             uidnode = NULL;
+                           }
+                         else if (interactive)
+                           yesreally = 1;
+                       }
+                     else
+                       {
+                         uidnode->flag &= ~NODFLG_MARK_A;
+                         uidnode = NULL;
+                         tty_fprintf (fp, _("  Unable to sign.\n"));
+                       }
+                   }
+                 else if (uidnode->pkt->pkt.user_id->is_expired)
+                   {
+                     tty_fprintf (fp, _("User ID \"%s\" is expired."), user);
 
-                       if(selfsig)
-                         tty_printf("\n");
-                       else if(opt.expert)
-                         {
-                           tty_printf("\n");
-                           /* No, so remove the mark and continue */
-                           if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
+                     if (selfsig)
+                       tty_fprintf (fp, "\n");
+                     else if (opt.expert && !quick)
+                       {
+                         tty_fprintf (fp, "\n");
+                         /* No, so remove the mark and continue */
+                         if (!cpr_get_answer_is_yes ("sign_uid.expire_okay",
                                                      _("Are you sure you "
                                                        "still want to sign "
                                                        "it? (y/N) ")))
-                             {
-                               uidnode->flag &= ~NODFLG_MARK_A;
-                               uidnode=NULL;
-                             }
-                           else if(interactive)
-                             yesreally=1;
-                         }
-                       else
-                         {
-                           uidnode->flag &= ~NODFLG_MARK_A;
-                           uidnode=NULL;
-                           tty_printf(_("  Unable to sign.\n"));
-                         }
-                     }
-                   else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
-                     {
-                       tty_printf(_("User ID \"%s\" is not self-signed."),
-                                  user);
+                           {
+                             uidnode->flag &= ~NODFLG_MARK_A;
+                             uidnode = NULL;
+                           }
+                         else if (interactive)
+                           yesreally = 1;
+                       }
+                     else
+                       {
+                         uidnode->flag &= ~NODFLG_MARK_A;
+                         uidnode = NULL;
+                         tty_fprintf (fp, _("  Unable to sign.\n"));
+                       }
+                   }
+                 else if (!uidnode->pkt->pkt.user_id->created && !selfsig)
+                   {
+                     tty_fprintf (fp, _("User ID \"%s\" is not self-signed."),
+                                   user);
 
-                       if(opt.expert)
-                         {
-                           tty_printf("\n");
-                           /* No, so remove the mark and continue */
-                           if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
+                     if (opt.expert && !quick)
+                       {
+                         tty_fprintf (fp, "\n");
+                         /* No, so remove the mark and continue */
+                         if (!cpr_get_answer_is_yes ("sign_uid.nosig_okay",
                                                      _("Are you sure you "
                                                        "still want to sign "
                                                        "it? (y/N) ")))
-                             {
-                               uidnode->flag &= ~NODFLG_MARK_A;
-                               uidnode=NULL;
-                             }
-                           else if(interactive)
-                             yesreally=1;
-                         }
-                       else
-                         {
-                           uidnode->flag &= ~NODFLG_MARK_A;
-                           uidnode=NULL;
-                           tty_printf(_("  Unable to sign.\n"));
-                         }
-                     }
+                           {
+                             uidnode->flag &= ~NODFLG_MARK_A;
+                             uidnode = NULL;
+                           }
+                         else if (interactive)
+                           yesreally = 1;
+                       }
+                     else
+                       {
+                         uidnode->flag &= ~NODFLG_MARK_A;
+                         uidnode = NULL;
+                         tty_fprintf (fp, _("  Unable to sign.\n"));
+                       }
+                   }
 
-                   if(uidnode && interactive && !yesreally)
-                     {
-                       tty_printf(_("User ID \"%s\" is signable.  "),user);
-                       if(!cpr_get_answer_is_yes("sign_uid.sign_okay",
+                 if (uidnode && interactive && !yesreally && !quick)
+                   {
+                     tty_fprintf (fp,
+                                   _("User ID \"%s\" is signable.  "), user);
+                     if (!cpr_get_answer_is_yes ("sign_uid.sign_okay",
                                                  _("Sign it? (y/N) ")))
-                         {
-                           uidnode->flag &= ~NODFLG_MARK_A;
-                           uidnode=NULL;
-                         }
-                     }
+                       {
+                         uidnode->flag &= ~NODFLG_MARK_A;
+                         uidnode = NULL;
+                       }
+                   }
 
-                   xfree(user);
-                 }
-             }
-           else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE
-               && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
-               if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
-                   && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) {
-                    char buf[50];
-                   char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
-                                             uidnode->pkt->pkt.user_id->len,
-                                             0);
-
-                   /* It's a v3 self-sig.  Make it into a v4 self-sig? */
-                   if(node->pkt->pkt.signature->version<4 && selfsig)
-                     {
-                       tty_printf(_("The self-signature on \"%s\"\n"
-                                    "is a PGP 2.x-style signature.\n"),user);
+                 xfree (user);
+               }
+           }
+         else if (uidnode && node->pkt->pkttype == PKT_SIGNATURE
+                  && (node->pkt->pkt.signature->sig_class & ~3) == 0x10)
+           {
+             if (sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
+                 && sk_keyid[1] == node->pkt->pkt.signature->keyid[1])
+               {
+                 char buf[50];
+                 char *user;
+
+                  user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
+                                         uidnode->pkt->pkt.user_id->len, 0);
 
-                       /* Note that the regular PGP2 warning below
-                          still applies if there are no v4 sigs on
-                          this key at all. */
+                 /* It's a v3 self-sig.  Make it into a v4 self-sig? */
+                 if (node->pkt->pkt.signature->version < 4
+                      && selfsig && !quick)
+                   {
+                     tty_fprintf (fp,
+                                   _("The self-signature on \"%s\"\n"
+                                     "is a PGP 2.x-style signature.\n"), user);
+
+                     /* Note that the regular PGP2 warning below
+                        still applies if there are no v4 sigs on
+                        this key at all. */
 
-                       if(opt.expert)
-                         if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay",
+                     if (opt.expert)
+                       if (cpr_get_answer_is_yes ("sign_uid.v4_promote_okay",
                                                   _("Do you want to promote "
                                                     "it to an OpenPGP self-"
                                                     "signature? (y/N) ")))
-                           {
-                             force_v4=1;
-                             node->flag|=NODFLG_DELSIG;
-                             xfree(user);
-                             continue;
-                           }
-                     }
-
-                   /* Is the current signature expired? */
-                   if(node->pkt->pkt.signature->flags.expired)
-                     {
-                       tty_printf(_("Your current signature on \"%s\"\n"
-                                    "has expired.\n"),user);
-
-                       if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay",
-                                                _("Do you want to issue a "
-                                                  "new signature to replace "
-                                                  "the expired one? (y/N) ")))
                          {
-                           /* Mark these for later deletion.  We
-                               don't want to delete them here, just in
-                               case the replacement signature doesn't
-                               happen for some reason.  We only delete
-                               these after the replacement is already
-                               in place. */
-
-                           node->flag|=NODFLG_DELSIG;
-                           xfree(user);
+                           node->flag |= NODFLG_DELSIG;
+                           xfree (user);
                            continue;
                          }
-                     }
+                   }
 
-                   if(!node->pkt->pkt.signature->flags.exportable && !local)
-                     {
-                       /* It's a local sig, and we want to make a
-                           exportable sig. */
-                       tty_printf(_("Your current signature on \"%s\"\n"
-                                    "is a local signature.\n"),user);
-
-                       if(cpr_get_answer_is_yes("sign_uid.local_promote_okay",
-                                                _("Do you want to promote "
-                                                  "it to a full exportable "
-                                                  "signature? (y/N) ")))
-                         {
-                           /* Mark these for later deletion.  We
-                               don't want to delete them here, just in
-                               case the replacement signature doesn't
-                               happen for some reason.  We only delete
-                               these after the replacement is already
-                               in place. */
-
-                           node->flag|=NODFLG_DELSIG;
-                           xfree(user);
-                           continue;
-                         }
-                     }
+                 /* Is the current signature expired? */
+                 if (node->pkt->pkt.signature->flags.expired)
+                   {
+                     tty_fprintf (fp, _("Your current signature on \"%s\"\n"
+                                         "has expired.\n"), user);
+
+                     if (quick || cpr_get_answer_is_yes
+                         ("sign_uid.replace_expired_okay",
+                          _("Do you want to issue a "
+                            "new signature to replace "
+                            "the expired one? (y/N) ")))
+                       {
+                         /* Mark these for later deletion.  We
+                            don't want to delete them here, just in
+                            case the replacement signature doesn't
+                            happen for some reason.  We only delete
+                            these after the replacement is already
+                            in place. */
+
+                         node->flag |= NODFLG_DELSIG;
+                         xfree (user);
+                         continue;
+                       }
+                   }
+
+                 if (!node->pkt->pkt.signature->flags.exportable && !local)
+                   {
+                     /* It's a local sig, and we want to make a
+                        exportable sig. */
+                     tty_fprintf (fp, _("Your current signature on \"%s\"\n"
+                                         "is a local signature.\n"), user);
+
+                     if (quick || cpr_get_answer_is_yes
+                         ("sign_uid.local_promote_okay",
+                          _("Do you want to promote "
+                            "it to a full exportable " "signature? (y/N) ")))
+                       {
+                         /* Mark these for later deletion.  We
+                            don't want to delete them here, just in
+                            case the replacement signature doesn't
+                            happen for some reason.  We only delete
+                            these after the replacement is already
+                            in place. */
+
+                         node->flag |= NODFLG_DELSIG;
+                         xfree (user);
+                         continue;
+                       }
+                   }
+
+                 /* Fixme: see whether there is a revocation in which
+                  * case we should allow to sign it again. */
+                 if (!node->pkt->pkt.signature->flags.exportable && local)
+                   tty_fprintf ( fp,
+                       _("\"%s\" was already locally signed by key %s\n"),
+                       user, keystr_from_pk (pk));
+                 else
+                   tty_fprintf (fp,
+                                _("\"%s\" was already signed by key %s\n"),
+                               user, keystr_from_pk (pk));
 
-                   /* Fixme: see whether there is a revocation in which
-                    * case we should allow to sign it again. */
-                    if (!node->pkt->pkt.signature->flags.exportable && local)
-                      tty_printf(_(
-                             "\"%s\" was already locally signed by key %s\n"),
-                                user,keystr_from_sk(sk));
-                    else
-                      tty_printf(_("\"%s\" was already signed by key %s\n"),
-                                 user,keystr_from_sk(sk));
-
-                   if(opt.expert
-                      && cpr_get_answer_is_yes("sign_uid.dupe_okay",
+                 if (opt.expert && !quick
+                     && cpr_get_answer_is_yes ("sign_uid.dupe_okay",
                                                _("Do you want to sign it "
                                                  "again anyway? (y/N) ")))
-                     {
-                       /* Don't delete the old sig here since this is
-                          an --expert thing. */
-                       xfree(user);
-                       continue;
-                     }
+                   {
+                     /* Don't delete the old sig here since this is
+                        an --expert thing. */
+                     xfree (user);
+                     continue;
+                   }
 
-                    sprintf (buf, "%08lX%08lX",
-                             (ulong)sk->keyid[0], (ulong)sk->keyid[1] );
-                    write_status_text (STATUS_ALREADY_SIGNED, buf);
-                   uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
+                 snprintf (buf, sizeof buf, "%08lX%08lX",
+                           (ulong) pk->keyid[0], (ulong) pk->keyid[1]);
+                 write_status_text (STATUS_ALREADY_SIGNED, buf);
+                 uidnode->flag &= ~NODFLG_MARK_A;      /* remove mark */
 
-                   xfree(user);
+                 xfree (user);
                }
            }
        }
 
-       /* check whether any uids are left for signing */
-       if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) )
-         {
-           tty_printf(_("Nothing to sign with key %s\n"),keystr_from_sk(sk));
-           continue;
-         }
+      /* Check whether any uids are left for signing.  */
+      if (!count_uids_with_flag (keyblock, NODFLG_MARK_A))
+       {
+         tty_fprintf (fp, _("Nothing to sign with key %s\n"),
+                     keystr_from_pk (pk));
+         continue;
+       }
 
-       /* Ask whether we really should sign these user id(s) */
-       tty_printf("\n");
-       show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 );
-       tty_printf("\n");
+      /* Ask whether we really should sign these user id(s). */
+      tty_fprintf (fp, "\n");
+      show_key_with_all_names (fp, keyblock, 1, 0, 1, 0, 0, 0);
+      tty_fprintf (fp, "\n");
 
-       if(primary_pk->expiredate && !selfsig)
-         {
-           u32 now=make_timestamp();
+      if (primary_pk->expiredate && !selfsig)
+       {
+         u32 now = make_timestamp ();
 
-           if(primary_pk->expiredate<=now)
-             {
-               tty_printf(_("This key has expired!"));
+         if (primary_pk->expiredate <= now)
+           {
+             tty_fprintf (fp, _("This key has expired!"));
 
-               if(opt.expert)
-                 {
-                   tty_printf("  ");
-                   if(!cpr_get_answer_is_yes("sign_uid.expired_okay",
+             if (opt.expert && !quick)
+               {
+                 tty_fprintf (fp, "  ");
+                 if (!cpr_get_answer_is_yes ("sign_uid.expired_okay",
                                              _("Are you sure you still "
                                                "want to sign it? (y/N) ")))
-                     continue;
-                 }
-               else
-                 {
-                   tty_printf(_("  Unable to sign.\n"));
                    continue;
-                 }
-             }
-           else
-             {
-               tty_printf(_("This key is due to expire on %s.\n"),
-                          expirestr_from_pk(primary_pk));
+               }
+             else
+               {
+                 tty_fprintf (fp, _("  Unable to sign.\n"));
+                 continue;
+               }
+           }
+         else
+           {
+             tty_fprintf (fp, _("This key is due to expire on %s.\n"),
+                           expirestr_from_pk (primary_pk));
 
-               if(opt.ask_cert_expire)
-                 {
-                   char *answer=cpr_get("sign_uid.expire",
-                                        _("Do you want your signature to "
-                                          "expire at the same time? (Y/n) "));
-                   if(answer_is_yes_no_default(answer,1))
-                     {
-                       /* This fixes the signature timestamp we're
-                          going to make as now.  This is so the
-                          expiration date is exactly correct, and not
-                          a few seconds off (due to the time it takes
-                          to answer the questions, enter the
-                          passphrase, etc). */
-                       timestamp=now;
-                       duration=primary_pk->expiredate-now;
-                       force_v4=1;
-                     }
+             if (opt.ask_cert_expire && !quick)
+               {
+                 char *answer = cpr_get ("sign_uid.expire",
+                                         _("Do you want your signature to "
+                                           "expire at the same time? (Y/n) "));
+                 if (answer_is_yes_no_default (answer, 1))
+                   {
+                     /* This fixes the signature timestamp we're
+                        going to make as now.  This is so the
+                        expiration date is exactly correct, and not
+                        a few seconds off (due to the time it takes
+                        to answer the questions, enter the
+                        passphrase, etc). */
+                     timestamp = now;
+                     duration = primary_pk->expiredate - now;
+                   }
 
-                   cpr_kill_prompt();
-                   xfree(answer);
-                 }
-             }
-         }
+                 cpr_kill_prompt ();
+                 xfree (answer);
+               }
+           }
+       }
 
-       /* Only ask for duration if we haven't already set it to match
-           the expiration of the pk */
-       if(!duration && !selfsig)
-         {
-           if(opt.ask_cert_expire)
-             duration=ask_expire_interval(1,opt.def_cert_expire);
-           else
-             duration=parse_expire_string(opt.def_cert_expire);
-         }
+      /* Only ask for duration if we haven't already set it to match
+         the expiration of the pk */
+      if (!duration && !selfsig)
+       {
+         if (opt.ask_cert_expire && !quick)
+           duration = ask_expire_interval (1, opt.def_cert_expire);
+         else
+           duration = parse_expire_string (opt.def_cert_expire);
+       }
 
-       if(duration)
-         force_v4=1;
+      if (selfsig)
+       ;
+      else
+       {
+         if (opt.batch || !opt.ask_cert_level || quick)
+           class = 0x10 + opt.def_cert_level;
+         else
+           {
+             char *answer;
+
+             tty_fprintf (fp,
+                           _("How carefully have you verified the key you are "
+                           "about to sign actually belongs\nto the person "
+                           "named above?  If you don't know what to "
+                           "answer, enter \"0\".\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("   (0) I will not answer.%s\n"),
+                         opt.def_cert_level == 0 ? " (default)" : "");
+             tty_fprintf (fp, _("   (1) I have not checked at all.%s\n"),
+                         opt.def_cert_level == 1 ? " (default)" : "");
+             tty_fprintf (fp, _("   (2) I have done casual checking.%s\n"),
+                         opt.def_cert_level == 2 ? " (default)" : "");
+             tty_fprintf (fp,
+                           _("   (3) I have done very careful checking.%s\n"),
+                         opt.def_cert_level == 3 ? " (default)" : "");
+             tty_fprintf (fp, "\n");
+
+             while (class == 0)
+               {
+                 answer = cpr_get ("sign_uid.class",
+                                    _("Your selection? "
+                                      "(enter '?' for more information): "));
+                 if (answer[0] == '\0')
+                   class = 0x10 + opt.def_cert_level;  /* Default */
+                 else if (ascii_strcasecmp (answer, "0") == 0)
+                   class = 0x10;       /* Generic */
+                 else if (ascii_strcasecmp (answer, "1") == 0)
+                   class = 0x11;       /* Persona */
+                 else if (ascii_strcasecmp (answer, "2") == 0)
+                   class = 0x12;       /* Casual */
+                 else if (ascii_strcasecmp (answer, "3") == 0)
+                   class = 0x13;       /* Positive */
+                 else
+                   tty_fprintf (fp, _("Invalid selection.\n"));
 
-       /* Is --pgp2 on, it's a v3 key, all the sigs on the key are
-          currently v3 and we're about to sign it with a v4 sig?  If
-          so, danger! */
-       if(PGP2 && all_v3 &&
-          (sk->version>3 || force_v4) && primary_pk->version<=3)
-         {
-           tty_printf(_("You may not make an OpenPGP signature on a "
-                        "PGP 2.x key while in --pgp2 mode.\n"));
-           tty_printf(_("This would make the key unusable in PGP 2.x.\n"));
+                 xfree (answer);
+               }
+           }
 
-           if(opt.expert)
-             {
-               if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay",
-                                         _("Are you sure you still "
-                                           "want to sign it? (y/N) ")))
-                 continue;
+         if (trust && !quick)
+           trustsig_prompt (&trust_value, &trust_depth, &trust_regexp);
+       }
 
-               all_v3=0;
-             }
-           else
-             continue;
-         }
+      if (!quick)
+        {
+          p = get_user_id_native (sk_keyid);
+          tty_fprintf (fp,
+                   _("Are you sure that you want to sign this key with your\n"
+                     "key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
+          xfree (p);
+        }
 
-       if(selfsig)
-         ;
-       else
-         {
-           if(opt.batch || !opt.ask_cert_level)
-             class=0x10+opt.def_cert_level;
-           else
-             {
-               char *answer;
-
-               tty_printf(_("How carefully have you verified the key you are "
-                            "about to sign actually belongs\nto the person "
-                            "named above?  If you don't know what to "
-                            "answer, enter \"0\".\n"));
-               tty_printf("\n");
-               tty_printf(_("   (0) I will not answer.%s\n"),
-                          opt.def_cert_level==0?" (default)":"");
-               tty_printf(_("   (1) I have not checked at all.%s\n"),
-                          opt.def_cert_level==1?" (default)":"");
-               tty_printf(_("   (2) I have done casual checking.%s\n"),
-                          opt.def_cert_level==2?" (default)":"");
-               tty_printf(_("   (3) I have done very careful checking.%s\n"),
-                          opt.def_cert_level==3?" (default)":"");
-               tty_printf("\n");
-
-               while(class==0)
-                 {
-                   answer = cpr_get("sign_uid.class",_("Your selection? "
-                                       "(enter `?' for more information): "));
-                   if(answer[0]=='\0')
-                     class=0x10+opt.def_cert_level; /* Default */
-                   else if(ascii_strcasecmp(answer,"0")==0)
-                     class=0x10; /* Generic */
-                   else if(ascii_strcasecmp(answer,"1")==0)
-                     class=0x11; /* Persona */
-                   else if(ascii_strcasecmp(answer,"2")==0)
-                     class=0x12; /* Casual */
-                   else if(ascii_strcasecmp(answer,"3")==0)
-                     class=0x13; /* Positive */
-                   else
-                     tty_printf(_("Invalid selection.\n"));
-
-                   xfree(answer);
-                 }
-             }
+      if (selfsig)
+       {
+         tty_fprintf (fp, "\n");
+         tty_fprintf (fp, _("This will be a self-signature.\n"));
 
-           if(trust)
-             trustsig_prompt(&trust_value,&trust_depth,&trust_regexp);
-         }
+         if (local)
+           {
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("WARNING: the signature will not be marked "
+                                 "as non-exportable.\n"));
+           }
 
-       p=get_user_id_native(sk_keyid);
-       tty_printf(_("Are you sure that you want to sign this key with your\n"
-                    "key \"%s\" (%s)\n"),p,keystr_from_sk(sk));
-       xfree(p);
+         if (nonrevocable)
+           {
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("WARNING: the signature will not be marked "
+                                 "as non-revocable.\n"));
+           }
+       }
+      else
+       {
+         if (local)
+           {
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp,
+                 _("The signature will be marked as non-exportable.\n"));
+           }
 
-       if(selfsig)
-         {
-            tty_printf("\n");
-           tty_printf(_("This will be a self-signature.\n"));
-
-           if( local )
-              {
-                tty_printf("\n");
-                tty_printf(
-                        _("WARNING: the signature will not be marked "
-                          "as non-exportable.\n"));
-              }
-
-           if( nonrevocable )
-              {
-                tty_printf("\n");
-                tty_printf(
-                        _("WARNING: the signature will not be marked "
-                          "as non-revocable.\n"));
-              }
-         }
-       else
-         {
-           if( local )
-              {
-                tty_printf("\n");
-                tty_printf(
-                    _("The signature will be marked as non-exportable.\n"));
-              }
-
-           if( nonrevocable )
-              {
-                tty_printf("\n");
-                tty_printf(
-                     _("The signature will be marked as non-revocable.\n"));
-              }
-
-           switch(class)
-             {
-             case 0x11:
-                tty_printf("\n");
-               tty_printf(_("I have not checked this key at all.\n"));
-               break;
+         if (nonrevocable)
+           {
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp,
+                 _("The signature will be marked as non-revocable.\n"));
+           }
 
-             case 0x12:
-                tty_printf("\n");
-               tty_printf(_("I have checked this key casually.\n"));
-               break;
+         switch (class)
+           {
+           case 0x11:
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("I have not checked this key at all.\n"));
+             break;
 
-             case 0x13:
-                tty_printf("\n");
-               tty_printf(_("I have checked this key very carefully.\n"));
-               break;
-             }
-         }
+           case 0x12:
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("I have checked this key casually.\n"));
+             break;
 
-       tty_printf("\n");
+           case 0x13:
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("I have checked this key very carefully.\n"));
+             break;
+           }
+       }
 
-       if( opt.batch && opt.answer_yes )
-         ;
-       else if( !cpr_get_answer_is_yes("sign_uid.okay",
-                                       _("Really sign? (y/N) ")) )
-           continue;
+      tty_fprintf (fp, "\n");
 
-       /* now we can sign the user ids */
-      reloop: /* (must use this, because we are modifing the list) */
-       primary_pk = NULL;
-       for( node=keyblock; node; node = node->next ) {
-           if( node->pkt->pkttype == PKT_PUBLIC_KEY )
-               primary_pk = node->pkt->pkt.public_key;
-           else if( node->pkt->pkttype == PKT_USER_ID
-                    && (node->flag & NODFLG_MARK_A) ) {
-               PACKET *pkt;
-               PKT_signature *sig;
-               struct sign_attrib attrib;
-
-               assert( primary_pk );
-               memset( &attrib, 0, sizeof attrib );
-               attrib.non_exportable = local;
-               attrib.non_revocable = nonrevocable;
-               attrib.trust_depth = trust_depth;
-               attrib.trust_value = trust_value;
-               attrib.trust_regexp = trust_regexp;
-               node->flag &= ~NODFLG_MARK_A;
-
-                /* we force creation of a v4 signature for local
-                 * signatures, otherwise we would not generate the
-                 * subpacket with v3 keys and the signature becomes
-                 * exportable */
-
-               if(selfsig)
-                 rc = make_keysig_packet( &sig, primary_pk,
-                                          node->pkt->pkt.user_id,
-                                          NULL,
-                                          sk,
-                                          0x13, 0, force_v4?4:0, 0, 0,
-                                          keygen_add_std_prefs, primary_pk);
-               else
-                 rc = make_keysig_packet( &sig, primary_pk,
-                                          node->pkt->pkt.user_id,
-                                          NULL,
-                                          sk,
-                                          class, 0, force_v4?4:0,
-                                          timestamp, duration,
-                                          sign_mk_attrib, &attrib );
-               if( rc ) {
-                   log_error(_("signing failed: %s\n"), g10_errstr(rc));
-                   goto leave;
+      if (opt.batch && opt.answer_yes)
+       ;
+      else if (quick)
+        ;
+      else if (!cpr_get_answer_is_yes ("sign_uid.okay",
+                                      _("Really sign? (y/N) ")))
+       continue;
+
+      /* Now we can sign the user ids.  */
+    reloop:  /* (Must use this, because we are modifing the list.)  */
+      primary_pk = NULL;
+      for (node = keyblock; node; node = node->next)
+       {
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+           primary_pk = node->pkt->pkt.public_key;
+         else if (node->pkt->pkttype == PKT_USER_ID
+                  && (node->flag & NODFLG_MARK_A))
+           {
+             PACKET *pkt;
+             PKT_signature *sig;
+             struct sign_attrib attrib;
+
+             assert (primary_pk);
+             memset (&attrib, 0, sizeof attrib);
+             attrib.non_exportable = local;
+             attrib.non_revocable = nonrevocable;
+             attrib.trust_depth = trust_depth;
+             attrib.trust_value = trust_value;
+             attrib.trust_regexp = trust_regexp;
+             node->flag &= ~NODFLG_MARK_A;
+
+             /* We force creation of a v4 signature for local
+              * signatures, otherwise we would not generate the
+              * subpacket with v3 keys and the signature becomes
+              * exportable.  */
+
+             if (selfsig)
+               rc = make_keysig_packet (&sig, primary_pk,
+                                        node->pkt->pkt.user_id,
+                                        NULL,
+                                        pk,
+                                        0x13, 0, 0, 0,
+                                        keygen_add_std_prefs, primary_pk,
+                                         NULL);
+             else
+               rc = make_keysig_packet (&sig, primary_pk,
+                                        node->pkt->pkt.user_id,
+                                        NULL,
+                                        pk,
+                                        class, 0,
+                                        timestamp, duration,
+                                        sign_mk_attrib, &attrib,
+                                         NULL);
+             if (rc)
+               {
+                 log_error (_("signing failed: %s\n"), g10_errstr (rc));
+                 goto leave;
                }
 
-               *ret_modified = 1; /* we changed the keyblock */
-               update_trust = 1;
+             *ret_modified = 1;        /* We changed the keyblock. */
+             update_trust = 1;
 
-               pkt = xmalloc_clear( sizeof *pkt );
-               pkt->pkttype = PKT_SIGNATURE;
-               pkt->pkt.signature = sig;
-               insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE );
-               goto reloop;
+             pkt = xmalloc_clear (sizeof *pkt);
+             pkt->pkttype = PKT_SIGNATURE;
+             pkt->pkt.signature = sig;
+             insert_kbnode (node, new_kbnode (pkt), PKT_SIGNATURE);
+             goto reloop;
            }
        }
 
-       /* Delete any sigs that got promoted */
-       for( node=keyblock; node; node = node->next )
-         if( node->flag & NODFLG_DELSIG)
-           delete_kbnode(node);
-    } /* end loop over signators */
-
-  leave:
-    release_sk_list( sk_list );
-    if( sk )
-       free_secret_key(sk);
-    return rc;
-}
+      /* Delete any sigs that got promoted */
+      for (node = keyblock; node; node = node->next)
+       if (node->flag & NODFLG_DELSIG)
+         delete_kbnode (node);
+    } /* End loop over signators.  */
 
+ leave:
+  release_sk_list (sk_list);
+  return rc;
+}
 
 
-/****************
- * Change the passphrase of the primary and all secondary keys.
- * We use only one passphrase for all keys.
+/*
+ * Change the passphrase of the primary and all secondary keys.  Note
+ * that it is common to use only one passphrase for the primary and
+ * all subkeys.  However, this is now (since GnuPG 2.1) all up to the
+ * gpg-agent.  Returns 0 on success or an error code.
  */
-static int
-change_passphrase (KBNODE keyblock, int *r_err)
+static gpg_error_t
+change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
 {
-    int rc = 0;
-    int changed=0;
-    KBNODE node;
-    PKT_secret_key *sk;
-    char *passphrase = NULL;
-    int no_primary_secrets = 0;
-    int any;
-
-    node = find_kbnode( keyblock, PKT_SECRET_KEY );
-    if( !node ) {
-       log_error("Oops; secret key not found anymore!\n");
-       goto leave;
-    }
-    sk = node->pkt->pkt.secret_key;
-
-    for (any = 0, node=keyblock; node; node = node->next) {
-       if (node->pkt->pkttype == PKT_SECRET_KEY
-            || node->pkt->pkttype == PKT_SECRET_SUBKEY) {
-           PKT_secret_key *tmpsk = node->pkt->pkt.secret_key;
-            if (!(tmpsk->is_protected
-                  && (tmpsk->protect.s2k.mode == 1001
-                      || tmpsk->protect.s2k.mode == 1002))) {
-                any = 1;
-                break;
-            }
-        }
-    }
-    if (!any) {
-        tty_printf (_("Key has only stub or on-card key items - "
-                      "no passphrase to change.\n"));
-        goto leave;
+  gpg_error_t err;
+  kbnode_t node;
+  PKT_public_key *pk;
+  int any;
+  u32 keyid[2], subid[2];
+  char *hexgrip = NULL;
+  char *cache_nonce = NULL;
+  char *passwd_nonce = NULL;
+
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node)
+    {
+      log_error ("Oops; public key missing!\n");
+      err = gpg_error (GPG_ERR_INTERNAL);
+      goto leave;
     }
+  pk = node->pkt->pkt.public_key;
+  keyid_from_pk (pk, keyid);
 
-    /* See how to handle this key.  */
-    switch( is_secret_key_protected( sk ) ) {
-      case -1:
-       rc = G10ERR_PUBKEY_ALGO;
-       break;
-      case 0:
-       tty_printf(_("This key is not protected.\n"));
-       break;
-      default:
-       if( sk->protect.s2k.mode == 1001 ) {
-           tty_printf(_("Secret parts of primary key are not available.\n"));
-           no_primary_secrets = 1;
-       }
-       else if( sk->protect.s2k.mode == 1002 ) {
-           tty_printf(_("Secret parts of primary key are stored on-card.\n"));
-           no_primary_secrets = 1;
-       }
-       else {
-            u32 keyid[2];
-
-           tty_printf(_("Key is protected.\n"));
-
-            /* Clear the passphrase cache so that the user is required
-               to enter the old passphrase.  */
-            keyid_from_sk (sk, keyid);
-            passphrase_clear_cache (keyid, NULL, 0);
-
-           rc = check_secret_key( sk, 0 );
-           if( !rc )
-               passphrase = get_last_passphrase();
+  /* Check whether it is likely that we will be able to change the
+     passphrase for any subkey.  */
+  for (any = 0, node = keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+         || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       {
+          char *serialno;
+
+          pk = node->pkt->pkt.public_key;
+          keyid_from_pk (pk, subid);
+
+          xfree (hexgrip);
+          err = hexkeygrip_from_pk (pk, &hexgrip);
+          if (err)
+            goto leave;
+          err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
+          if (!err && serialno)
+            ; /* Key on card.  */
+          else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+            ; /* Maybe stub key. */
+          else if (!err)
+            any = 1; /* Key is known.  */
+          else
+            log_error ("key %s: error getting keyinfo from agent: %s\n",
+                       keystr_with_sub (keyid, subid), gpg_strerror (err));
+          xfree (serialno);
        }
-       break;
     }
-
-    /* Unprotect all subkeys (use the supplied passphrase or ask)*/
-    for(node=keyblock; !rc && node; node = node->next ) {
-       if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-           PKT_secret_key *subsk = node->pkt->pkt.secret_key;
-            if ( !(subsk->is_protected
-                   && (subsk->protect.s2k.mode == 1001
-                       || subsk->protect.s2k.mode == 1002))) {
-                set_next_passphrase( passphrase );
-                rc = check_secret_key( subsk, 0 );
-                if( !rc && !passphrase )
-                    passphrase = get_last_passphrase();
-            }
-       }
+  err = 0;
+  if (!any)
+    {
+      tty_printf (_("Key has only stub or on-card key items - "
+                   "no passphrase to change.\n"));
+      goto leave;
     }
 
-    if( rc )
-       tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
-    else {
-       DEK *dek = NULL;
-       STRING2KEY *s2k = xmalloc_secure( sizeof *s2k );
-        const char *errtext = NULL;
-
-       tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
-
-       set_next_passphrase( NULL );
-       for(;;) {
-            int canceled;
-
-           s2k->mode = opt.s2k_mode;
-           s2k->hash_algo = S2K_DIGEST_ALGO;
-           dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
-                                     s2k, 2, errtext, &canceled);
-            if (!dek && canceled) {
-                rc = GPG_ERR_CANCELED;
-                break;
-            }
-           else if( !dek ) {
-               errtext = N_("passphrase not correctly repeated; try again");
-               tty_printf ("%s.\n", _(errtext));
-           }
-           else if( !dek->keylen ) {
-               rc = 0;
-               tty_printf(_( "You don't want a passphrase -"
-                           " this is probably a *bad* idea!\n\n"));
-               if( cpr_get_answer_is_yes("change_passwd.empty.okay",
-                              _("Do you really want to do this? (y/N) ")))
-                 {
-                   changed++;
-                   break;
-                 }
-           }
-           else { /* okay */
-               rc = 0;
-               if( !no_primary_secrets ) {
-                   sk->protect.algo = dek->algo;
-                   sk->protect.s2k = *s2k;
-                   rc = protect_secret_key( sk, dek );
-               }
-               for(node=keyblock; !rc && node; node = node->next ) {
-                   if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-                       PKT_secret_key *subsk = node->pkt->pkt.secret_key;
-                        if ( !(subsk->is_protected
-                               && (subsk->protect.s2k.mode == 1001
-                                   || subsk->protect.s2k.mode == 1002))) {
-                            subsk->protect.algo = dek->algo;
-                            subsk->protect.s2k = *s2k;
-                            rc = protect_secret_key( subsk, dek );
-                        }
-                   }
-               }
-               if( rc )
-                   log_error("protect_secret_key failed: %s\n",
-                              g10_errstr(rc) );
-               else
-                  {
-                    u32 keyid[2];
-
-                    /* Clear the cahce again so that the user is
-                       required to enter the new passphrase at the
-                       next operation.  */
-                    keyid_from_sk (sk, keyid);
-                    passphrase_clear_cache (keyid, NULL, 0);
-
-                   changed++;
-                  }
-               break;
-           }
-       }
-       xfree(s2k);
-       xfree(dek);
+  /* Change the passphrase for all keys.  */
+  for (any = 0, node = keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+         || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+        {
+          char *desc;
+
+          pk = node->pkt->pkt.public_key;
+          keyid_from_pk (pk, subid);
+
+          xfree (hexgrip);
+          err = hexkeygrip_from_pk (pk, &hexgrip);
+          if (err)
+            goto leave;
+
+          desc = gpg_format_keydesc (pk, FORMAT_KEYDESC_NORMAL, 1);
+          err = agent_passwd (ctrl, hexgrip, desc, &cache_nonce, &passwd_nonce);
+          xfree (desc);
+
+          if (err)
+            log_log ((gpg_err_code (err) == GPG_ERR_CANCELED
+                      || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+                     ? JNLIB_LOG_INFO : JNLIB_LOG_ERROR,
+                     _("key %s: error changing passphrase: %s\n"),
+                       keystr_with_sub (keyid, subid),
+                       gpg_strerror (err));
+          if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+            break;
+        }
     }
 
-  leave:
-    xfree( passphrase );
-    set_next_passphrase( NULL );
-    if (r_err)
-      *r_err = rc;
-    return changed && !rc;
+ leave:
+  xfree (hexgrip);
+  xfree (cache_nonce);
+  xfree (passwd_nonce);
+  return err;
 }
 
 
-/****************
+\f
+/*
  * There are some keys out (due to a bug in gnupg), where the sequence
  * of the packets is wrong.  This function fixes that.
  * Returns: true if the keyblock has been fixed.
@@ -1277,61 +1180,67 @@ change_passphrase (KBNODE keyblock, int *r_err)
  * Note:  This function does not work if there is more than one user ID.
  */
 static int
-fix_keyblock( KBNODE keyblock )
+fix_keyblock (KBNODE keyblock)
 {
-    KBNODE node, last, subkey;
-    int fixed=0;
-
-    /* locate key signatures of class 0x10..0x13 behind sub key packets */
-    for( subkey=last=NULL, node = keyblock; node;
-                                           last=node, node = node->next ) {
-       switch( node->pkt->pkttype ) {
-         case PKT_PUBLIC_SUBKEY:
-         case PKT_SECRET_SUBKEY:
-           if( !subkey )
-               subkey = last; /* actually it is the one before the subkey */
-           break;
-         case PKT_SIGNATURE:
-           if( subkey ) {
-               PKT_signature *sig = node->pkt->pkt.signature;
-               if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
-                   log_info(_(
-                       "moving a key signature to the correct place\n"));
-                   last->next = node->next;
-                   node->next = subkey->next;
-                   subkey->next = node;
-                   node = last;
-                   fixed=1;
+  KBNODE node, last, subkey;
+  int fixed = 0;
+
+  /* Locate key signatures of class 0x10..0x13 behind sub key packets.  */
+  for (subkey = last = NULL, node = keyblock; node;
+       last = node, node = node->next)
+    {
+      switch (node->pkt->pkttype)
+       {
+       case PKT_PUBLIC_SUBKEY:
+       case PKT_SECRET_SUBKEY:
+         if (!subkey)
+           subkey = last; /* Actually it is the one before the subkey.  */
+         break;
+       case PKT_SIGNATURE:
+         if (subkey)
+           {
+             PKT_signature *sig = node->pkt->pkt.signature;
+             if (sig->sig_class >= 0x10 && sig->sig_class <= 0x13)
+               {
+                 log_info (_("moving a key signature to the correct place\n"));
+                 last->next = node->next;
+                 node->next = subkey->next;
+                 subkey->next = node;
+                 node = last;
+                 fixed = 1;
                }
            }
-           break;
-         default: break;
+         break;
+       default:
+         break;
        }
     }
 
-    return fixed;
+  return fixed;
 }
 
+
 static int
-parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
+parse_sign_type (const char *str, int *localsig, int *nonrevokesig,
+                int *trustsig)
 {
-  const char *p=str;
+  const char *p = str;
 
-  while(*p)
+  while (*p)
     {
-      if(ascii_strncasecmp(p,"l",1)==0)
+      if (ascii_strncasecmp (p, "l", 1) == 0)
        {
-         *localsig=1;
+         *localsig = 1;
          p++;
        }
-      else if(ascii_strncasecmp(p,"nr",2)==0)
+      else if (ascii_strncasecmp (p, "nr", 2) == 0)
        {
-         *nonrevokesig=1;
-         p+=2;
+         *nonrevokesig = 1;
+         p += 2;
        }
-      else if(ascii_strncasecmp(p,"t",1)==0)
+      else if (ascii_strncasecmp (p, "t", 1) == 0)
        {
-         *trustsig=1;
+         *trustsig = 1;
          p++;
        }
       else
@@ -1341,13 +1250,14 @@ parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
   return 1;
 }
 
+
 \f
-/****************
+/*
  * Menu driven key editor.  If seckey_check is true, then a secret key
  * that matches username will be looked for.  If it is false, not all
  * commands will be available.
  *
- * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
+ * Note: to keep track of certain selections we use node->mark MARKBIT_xxxx.
  */
 
 /* Need an SK for this command */
@@ -1360,17 +1270,21 @@ parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
 #define KEYEDIT_TAIL_MATCH 8
 
 enum cmdids
-  {
-    cmdNONE = 0,
-    cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
-    cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
-    cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
-    cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
-    cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
-    cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
-    cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN,
-    cmdMINIMIZE, cmdNOP
-  };
+{
+  cmdNONE = 0,
+  cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
+  cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
+  cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
+  cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
+  cmdEXPIRE, cmdBACKSIGN,
+#ifndef NO_TRUST_MODELS
+  cmdENABLEKEY, cmdDISABLEKEY,
+#endif /*!NO_TRUST_MODELS*/
+  cmdSHOWPREF,
+  cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
+  cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCHECKBKUPKEY,
+  cmdCLEAN, cmdMINIMIZE, cmdNOP
+};
 
 static struct
 {
@@ -1379,954 +1293,947 @@ static struct
   int flags;
   const char *desc;
 } cmds[] =
-  {
-    { "quit"    , cmdQUIT      , 0, N_("quit this menu") },
-    { "q"       , cmdQUIT      , 0, NULL   },
-    { "save"    , cmdSAVE      , 0, N_("save and quit") },
-    { "help"    , cmdHELP      , 0, N_("show this help") },
-    { "?"       , cmdHELP      , 0, NULL   },
-    { "fpr"     , cmdFPR       , 0, N_("show key fingerprint") },
-    { "list"    , cmdLIST      , 0, N_("list key and user IDs") },
-    { "l"       , cmdLIST      , 0, NULL   },
-    { "uid"     , cmdSELUID    , 0, N_("select user ID N") },
-    { "key"     , cmdSELKEY    , 0, N_("select subkey N") },
-    { "check"   , cmdCHECK     , 0, N_("check signatures") },
-    { "c"       , cmdCHECK     , 0, NULL },
-    { "cross-certify", cmdBACKSIGN  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
-    { "backsign", cmdBACKSIGN  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
-    { "sign"    , cmdSIGN      , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
-      N_("sign selected user IDs [* see below for related commands]") },
-    { "s"       , cmdSIGN      , KEYEDIT_NOT_SK, NULL },
+{
+  { "quit", cmdQUIT, 0, N_("quit this menu")},
+  { "q", cmdQUIT, 0, NULL},
+  { "save", cmdSAVE, 0, N_("save and quit")},
+  { "help", cmdHELP, 0, N_("show this help")},
+  { "?", cmdHELP, 0, NULL},
+  { "fpr", cmdFPR, 0, N_("show key fingerprint")},
+  { "list", cmdLIST, 0, N_("list key and user IDs")},
+  { "l", cmdLIST, 0, NULL},
+  { "uid", cmdSELUID, 0, N_("select user ID N")},
+  { "key", cmdSELKEY, 0, N_("select subkey N")},
+  { "check", cmdCHECK, 0, N_("check signatures")},
+  { "c", cmdCHECK, 0, NULL},
+  { "cross-certify", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
+  { "backsign", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
+  { "sign", cmdSIGN, KEYEDIT_NOT_SK | KEYEDIT_TAIL_MATCH,
+    N_("sign selected user IDs [* see below for related commands]")},
+  { "s", cmdSIGN, KEYEDIT_NOT_SK, NULL},
     /* "lsign" and friends will never match since "sign" comes first
        and it is a tail match.  They are just here so they show up in
        the help menu. */
-    { "lsign"   , cmdNOP       , 0, N_("sign selected user IDs locally") },
-    { "tsign"   , cmdNOP       , 0,
-      N_("sign selected user IDs with a trust signature") },
-    { "nrsign"  , cmdNOP       , 0,
-      N_("sign selected user IDs with a non-revocable signature") },
-
-    { "debug"   , cmdDEBUG     , 0, NULL },
-    { "adduid"  , cmdADDUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("add a user ID") },
-    { "addphoto", cmdADDPHOTO  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("add a photo ID") },
-    { "deluid"  , cmdDELUID    , KEYEDIT_NOT_SK,
-      N_("delete selected user IDs") },
+  { "lsign", cmdNOP, 0, N_("sign selected user IDs locally")},
+  { "tsign", cmdNOP, 0, N_("sign selected user IDs with a trust signature")},
+  { "nrsign", cmdNOP, 0,
+    N_("sign selected user IDs with a non-revocable signature")},
+  { "debug", cmdDEBUG, 0, NULL},
+  { "adduid", cmdADDUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a user ID")},
+  { "addphoto", cmdADDPHOTO, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("add a photo ID")},
+  { "deluid", cmdDELUID, KEYEDIT_NOT_SK, N_("delete selected user IDs")},
     /* delphoto is really deluid in disguise */
-    { "delphoto", cmdDELUID    , KEYEDIT_NOT_SK, NULL },
-
-    { "addkey"  , cmdADDKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("add a subkey") },
-
+  { "delphoto", cmdDELUID, KEYEDIT_NOT_SK, NULL},
+  { "addkey", cmdADDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a subkey")},
 #ifdef ENABLE_CARD_SUPPORT
-    { "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("add a key to a smartcard") },
-    { "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
-      N_("move a key to a smartcard")},
-    { "bkuptocard", cmdBKUPTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
-      N_("move a backup key to a smartcard")},
-#endif /*ENABLE_CARD_SUPPORT*/
-
-    { "delkey"  , cmdDELKEY    , KEYEDIT_NOT_SK,
-      N_("delete selected subkeys") },
-    { "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("add a revocation key") },
-    { "delsig"  , cmdDELSIG    , KEYEDIT_NOT_SK,
-      N_("delete signatures from the selected user IDs") },
-    { "expire"  , cmdEXPIRE    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("change the expiration date for the key or selected subkeys") },
-    { "primary" , cmdPRIMARY   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("flag the selected user ID as primary")},
-    { "toggle"  , cmdTOGGLE    , KEYEDIT_NEED_SK,
-      N_("toggle between the secret and public key listings") },
-    { "t"       , cmdTOGGLE    , KEYEDIT_NEED_SK, NULL },
-    { "pref"    , cmdPREF      , KEYEDIT_NOT_SK,
-      N_("list preferences (expert)")},
-    { "showpref", cmdSHOWPREF  , KEYEDIT_NOT_SK,
-      N_("list preferences (verbose)") },
-    { "setpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("set preference list for the selected user IDs") },
-    /* Alias */
-    { "updpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
-
-    { "keyserver",cmdPREFKS    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("set the preferred keyserver URL for the selected user IDs")},
-    { "notation", cmdNOTATION  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("set a notation for the selected user IDs")},
-    { "passwd"  , cmdPASSWD    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("change the passphrase") },
-    /* Alias */
-    { "password", cmdPASSWD    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
-
-    { "trust"   , cmdTRUST     , KEYEDIT_NOT_SK, N_("change the ownertrust") },
-    { "revsig"  , cmdREVSIG    , KEYEDIT_NOT_SK,
-      N_("revoke signatures on the selected user IDs") },
-    { "revuid"  , cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("revoke selected user IDs") },
-    /* Alias */
-    { "revphoto", cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
-
-    { "revkey"  , cmdREVKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
-      N_("revoke key or selected subkeys") },
-    { "enable"  , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
-    { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
-    { "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
-    { "clean",    cmdCLEAN     , KEYEDIT_NOT_SK,
-      N_("compact unusable user IDs and remove unusable signatures from key")},
-    { "minimize", cmdMINIMIZE  , KEYEDIT_NOT_SK,
-      N_("compact unusable user IDs and remove all signatures from key") },
-    { NULL, cmdNONE, 0, NULL }
-  };
+  { "addcardkey", cmdADDCARDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("add a key to a smartcard")},
+  { "keytocard", cmdKEYTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
+    N_("move a key to a smartcard")},
+  { "bkuptocard", cmdBKUPTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
+    N_("move a backup key to a smartcard")},
+  { "checkbkupkey", cmdCHECKBKUPKEY, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK, NULL},
+#endif /*ENABLE_CARD_SUPPORT */
+  { "delkey", cmdDELKEY, KEYEDIT_NOT_SK, N_("delete selected subkeys")},
+  { "addrevoker", cmdADDREVOKER, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("add a revocation key")},
+  { "delsig", cmdDELSIG, KEYEDIT_NOT_SK,
+    N_("delete signatures from the selected user IDs")},
+  { "expire", cmdEXPIRE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("change the expiration date for the key or selected subkeys")},
+  { "primary", cmdPRIMARY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("flag the selected user ID as primary")},
+  { "toggle", cmdTOGGLE, KEYEDIT_NEED_SK,
+    N_("toggle between the secret and public key listings")},
+  { "t", cmdTOGGLE, KEYEDIT_NEED_SK, NULL},
+  { "pref", cmdPREF, KEYEDIT_NOT_SK, N_("list preferences (expert)")},
+  { "showpref", cmdSHOWPREF, KEYEDIT_NOT_SK, N_("list preferences (verbose)")},
+  { "setpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("set preference list for the selected user IDs")},
+  { "updpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
+  { "keyserver", cmdPREFKS, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("set the preferred keyserver URL for the selected user IDs")},
+  { "notation", cmdNOTATION, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("set a notation for the selected user IDs")},
+  { "passwd", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("change the passphrase")},
+  { "password", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
+#ifndef NO_TRUST_MODELS
+  { "trust", cmdTRUST, KEYEDIT_NOT_SK, N_("change the ownertrust")},
+#endif /*!NO_TRUST_MODELS*/
+  { "revsig", cmdREVSIG, KEYEDIT_NOT_SK,
+    N_("revoke signatures on the selected user IDs")},
+  { "revuid", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("revoke selected user IDs")},
+  { "revphoto", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
+  { "revkey", cmdREVKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+    N_("revoke key or selected subkeys")},
+#ifndef NO_TRUST_MODELS
+  { "enable", cmdENABLEKEY, KEYEDIT_NOT_SK, N_("enable key")},
+  { "disable", cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key")},
+#endif /*!NO_TRUST_MODELS*/
+  { "showphoto", cmdSHOWPHOTO, 0, N_("show selected photo IDs")},
+  { "clean", cmdCLEAN, KEYEDIT_NOT_SK,
+    N_("compact unusable user IDs and remove unusable signatures from key")},
+  { "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK,
+    N_("compact unusable user IDs and remove all signatures from key")},
+
+  { NULL, cmdNONE, 0, NULL}
+};
 
+
+\f
 #ifdef HAVE_LIBREADLINE
 
-/* These two functions are used by readline for command completion. */
+/*
+   These two functions are used by readline for command completion.
+ */
 
 static char *
-command_generator(const char *text,int state)
+command_generator (const char *text, int state)
 {
-  static int list_index,len;
+  static int list_index, len;
   const char *name;
 
   /* If this is a new word to complete, initialize now.  This includes
      saving the length of TEXT for efficiency, and initializing the
      index variable to 0. */
-  if(!state)
+  if (!state)
     {
-      list_index=0;
-      len=strlen(text);
+      list_index = 0;
+      len = strlen (text);
     }
 
   /* Return the next partial match */
-  while((name=cmds[list_index].name))
+  while ((name = cmds[list_index].name))
     {
       /* Only complete commands that have help text */
-      if(cmds[list_index++].desc && strncmp(name,text,len)==0)
-       return strdup(name);
+      if (cmds[list_index++].desc && strncmp (name, text, len) == 0)
+       return strdup (name);
     }
 
   return NULL;
 }
 
 static char **
-keyedit_completion(const char *text, int start, int end)
+keyedit_completion (const char *text, int start, int end)
 {
   /* If we are at the start of a line, we try and command-complete.
      If not, just do nothing for now. */
 
-  (void)end;
+  (void) end;
 
-  if(start==0)
-    return rl_completion_matches(text,command_generator);
+  if (start == 0)
+    return rl_completion_matches (text, command_generator);
 
-  rl_attempted_completion_over=1;
+  rl_attempted_completion_over = 1;
 
   return NULL;
 }
 #endif /* HAVE_LIBREADLINE */
 
 
+\f
+/* Main function of the menu driven key editor.  */
 void
-keyedit_menu( const char *username, strlist_t locusr,
-             strlist_t commands, int quiet, int seckey_check )
+keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
+             strlist_t commands, int quiet, int seckey_check)
 {
-    enum cmdids cmd = 0;
-    int rc = 0;
-    KBNODE keyblock = NULL;
-    KEYDB_HANDLE kdbhd = NULL;
-    KBNODE sec_keyblock = NULL;
-    KEYDB_HANDLE sec_kdbhd = NULL;
-    KBNODE cur_keyblock;
-    char *answer = NULL;
-    int redisplay = 1;
-    int modified = 0;
-    int sec_modified = 0;
-    int run_subkey_warnings = 0;
-    int toggle;
-    int have_commands = !!commands;
-
-    if ( opt.command_fd != -1 )
-        ;
-    else if( opt.batch && !have_commands )
-      {
-       log_error(_("can't do this in batch mode\n"));
-       goto leave;
-      }
+  enum cmdids cmd = 0;
+  gpg_error_t err = 0;
+  KBNODE keyblock = NULL;
+  KEYDB_HANDLE kdbhd = NULL;
+  int have_seckey = 0;
+  char *answer = NULL;
+  int redisplay = 1;
+  int modified = 0;
+  int run_subkey_warnings = 0;
+  int toggle;
+  int have_commands = !!commands;
+
+  if (opt.command_fd != -1)
+    ;
+  else if (opt.batch && !have_commands)
+    {
+      log_error (_("can't do this in batch mode\n"));
+      goto leave;
+    }
 
 #ifdef HAVE_W32_SYSTEM
-    /* Due to Windows peculiarities we need to make sure that the
-       trustdb stale check is done before we open another file
-       (i.e. by searching for a key).  In theory we could make sure
-       that the files are closed after use but the open/close caches
-       inhibits that and flushing the cache right before the stale
-       check is not easy to implement.  Thus we take the easy way out
-       and run the stale check as early as possible.  Note, that for
-       non- W32 platforms it is run indirectly trough a call to
-       get_validity ().  */
-    check_trustdb_stale ();
+  /* Due to Windows peculiarities we need to make sure that the
+     trustdb stale check is done before we open another file
+     (i.e. by searching for a key).  In theory we could make sure
+     that the files are closed after use but the open/close caches
+     inhibits that and flushing the cache right before the stale
+     check is not easy to implement.  Thus we take the easy way out
+     and run the stale check as early as possible.  Note, that for
+     non- W32 platforms it is run indirectly trough a call to
+     get_validity ().  */
+  check_trustdb_stale ();
 #endif
 
-    /* Get the public key */
-    rc = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
-    if( rc )
-      {
-        log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
-       goto leave;
-      }
-
-    if( fix_keyblock( keyblock ) )
-       modified++;
-    if( collapse_uids( &keyblock ) )
-       modified++;
-    reorder_keyblock(keyblock);
-    /* We modified the keyblock, so let's make sure the flags are
-       right. */
-    if (modified)
-      merge_keys_and_selfsig (keyblock);
-
-    if(seckey_check)
-      {/* see whether we have a matching secret key */
-        PKT_public_key *pk = keyblock->pkt->pkt.public_key;
-
-        sec_kdbhd = keydb_new (1);
-        {
-            byte afp[MAX_FINGERPRINT_LEN];
-            size_t an;
-
-            fingerprint_from_pk (pk, afp, &an);
-            while (an < MAX_FINGERPRINT_LEN)
-                afp[an++] = 0;
-            rc = keydb_search_fpr (sec_kdbhd, afp);
-        }
-       if (!rc)
-         {
-           rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
-           if (rc)
-             {
-               log_error (_("error reading secret keyblock \"%s\": %s\n"),
-                          username, g10_errstr(rc));
-             }
-            else
-             {
-                merge_keys_and_selfsig( sec_keyblock );
-                if( fix_keyblock( sec_keyblock ) )
-                 sec_modified++;
-             }
-         }
+  /* Get the public key */
+  err = get_pubkey_byname (ctrl, NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
+  if (err)
+    {
+      log_error (_("key \"%s\" not found: %s\n"), username, gpg_strerror (err));
+      goto leave;
+    }
+  if (fix_keyblock (keyblock))
+    modified++;
+  if (collapse_uids (&keyblock))
+    modified++;
+  reorder_keyblock (keyblock);
+  /* We modified the keyblock, so let's make sure the flags are
+     right. */
+  if (modified)
+    merge_keys_and_selfsig (keyblock);
+
+  /* See whether we have a matching secret key.  */
+  if (seckey_check)
+    {
+      have_seckey = !agent_probe_any_secret_key (ctrl, keyblock);
+      if (have_seckey && !quiet)
+       tty_printf (_("Secret key is available.\n"));
+    }
 
-        if (rc) {
-            sec_keyblock = NULL;
-            keydb_release (sec_kdbhd); sec_kdbhd = NULL;
-            rc = 0;
-        }
+  toggle = 0;
 
-       if( sec_keyblock && !quiet )
-         tty_printf(_("Secret key is available.\n"));
-    }
+  /* Main command loop.  */
+  for (;;)
+    {
+      int i, arg_number, photo;
+      const char *arg_string = "";
+      char *p;
+      PKT_public_key *pk = keyblock->pkt->pkt.public_key;
 
-    toggle = 0;
-    cur_keyblock = keyblock;
-    for(;;) { /* main loop */
-       int i, arg_number, photo;
-        const char *arg_string = "";
-       char *p;
-       PKT_public_key *pk=keyblock->pkt->pkt.public_key;
+      tty_printf ("\n");
 
-       tty_printf("\n");
+      if (redisplay && !quiet)
+       {
+         show_key_with_all_names (NULL, keyblock, 0, 1, 0, 1, 0, 0);
+         tty_printf ("\n");
+         redisplay = 0;
+       }
 
-       if( redisplay && !quiet )
-         {
-           show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
-           tty_printf("\n");
-           redisplay = 0;
-         }
+      if (run_subkey_warnings)
+        {
+          run_subkey_warnings = 0;
+          if (!count_selected_keys (keyblock))
+            subkey_expire_warning (keyblock);
+        }
 
-        if (run_subkey_warnings)
-          {
-            run_subkey_warnings = 0;
-            if (!count_selected_keys (keyblock))
-              subkey_expire_warning (keyblock);
-          }
-
-       do {
-           xfree(answer);
-           if( have_commands ) {
-               if( commands ) {
-                   answer = xstrdup( commands->d );
-                   commands = commands->next;
+      do
+       {
+         xfree (answer);
+         if (have_commands)
+           {
+             if (commands)
+               {
+                 answer = xstrdup (commands->d);
+                 commands = commands->next;
                }
-               else if( opt.batch ) {
-                   answer = xstrdup("quit");
+             else if (opt.batch)
+               {
+                 answer = xstrdup ("quit");
                }
-               else
-                   have_commands = 0;
+             else
+               have_commands = 0;
            }
-           if( !have_commands )
-             {
+         if (!have_commands)
+           {
 #ifdef HAVE_LIBREADLINE
-               tty_enable_completion(keyedit_completion);
+             tty_enable_completion (keyedit_completion);
 #endif
-               answer = cpr_get_no_help("keyedit.prompt", "gpg> ");
-               cpr_kill_prompt();
-               tty_disable_completion();
-             }
-           trim_spaces(answer);
-       } while( *answer == '#' );
-
-       arg_number = 0; /* Yes, here is the init which egcc complains about */
-       photo = 0; /* This too */
-       if( !*answer )
-           cmd = cmdLIST;
-       else if( *answer == CONTROL_D )
-           cmd = cmdQUIT;
-       else if( digitp(answer ) ) {
-           cmd = cmdSELUID;
-           arg_number = atoi(answer);
+             answer = cpr_get_no_help ("keyedit.prompt", GPG_NAME "> ");
+             cpr_kill_prompt ();
+             tty_disable_completion ();
+           }
+         trim_spaces (answer);
+       }
+      while (*answer == '#');
+
+      arg_number = 0; /* Here is the init which egcc complains about.  */
+      photo = 0;      /* Same here. */
+      if (!*answer)
+       cmd = cmdLIST;
+      else if (*answer == CONTROL_D)
+       cmd = cmdQUIT;
+      else if (digitp (answer))
+       {
+         cmd = cmdSELUID;
+         arg_number = atoi (answer);
        }
-       else {
-           if( (p=strchr(answer,' ')) ) {
-               *p++ = 0;
-               trim_spaces(answer);
-               trim_spaces(p);
-               arg_number = atoi(p);
-                arg_string = p;
+      else
+       {
+         if ((p = strchr (answer, ' ')))
+           {
+             *p++ = 0;
+             trim_spaces (answer);
+             trim_spaces (p);
+             arg_number = atoi (p);
+             arg_string = p;
            }
 
-           for(i=0; cmds[i].name; i++ )
-             {
-               if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
-                 {
-                   size_t l=strlen(cmds[i].name);
-                   size_t a=strlen(answer);
-                   if(a>=l)
-                     {
-                       if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
-                         {
-                           answer[a-l]='\0';
-                           break;
-                         }
-                     }
-                 }
-               else if( !ascii_strcasecmp( answer, cmds[i].name ) )
-                 break;
-             }
-           if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
-             {
-               tty_printf(_("Need the secret key to do this.\n"));
-               cmd = cmdNOP;
-             }
-           else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
-                    && toggle)
-                    ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
+         for (i = 0; cmds[i].name; i++)
+           {
+             if (cmds[i].flags & KEYEDIT_TAIL_MATCH)
+               {
+                 size_t l = strlen (cmds[i].name);
+                 size_t a = strlen (answer);
+                 if (a >= l)
+                   {
+                     if (!ascii_strcasecmp (&answer[a - l], cmds[i].name))
+                       {
+                         answer[a - l] = '\0';
+                         break;
+                       }
+                   }
+               }
+             else if (!ascii_strcasecmp (answer, cmds[i].name))
+               break;
+           }
+         if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
+           {
+             tty_printf (_("Need the secret key to do this.\n"));
+             cmd = cmdNOP;
+           }
+         else if (((cmds[i].flags & KEYEDIT_NOT_SK) && have_seckey && toggle)
+                  || ((cmds[i].flags & KEYEDIT_ONLY_SK) && have_seckey
                       && !toggle))
-             {
-               tty_printf(_("Please use the command \"toggle\" first.\n"));
-               cmd = cmdNOP;
-             }
-           else
-             cmd = cmds[i].id;
+           {
+             tty_printf (_("Please use the command \"toggle\" first.\n"));
+             cmd = cmdNOP;
+           }
+         else
+           cmd = cmds[i].id;
        }
-       switch( cmd )
-         {
-         case cmdHELP:
-           for(i=0; cmds[i].name; i++ )
-             {
-               if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
-                 ; /* skip if we do not have the secret key */
-               else if( cmds[i].desc )
-                 tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
-             }
 
-           tty_printf("\n");
-           tty_printf(_(
-"* The `sign' command may be prefixed with an `l' for local "
-"signatures (lsign),\n"
-"  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
-"  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
+      /* Dispatch the command.  */
+      switch (cmd)
+       {
+       case cmdHELP:
+         for (i = 0; cmds[i].name; i++)
+           {
+             if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
+               ; /* Skip those item if we do not have the secret key.  */
+             else if (cmds[i].desc)
+               tty_printf ("%-11s %s\n", cmds[i].name, _(cmds[i].desc));
+           }
 
-           break;
+         tty_printf ("\n");
+         tty_printf
+            (_("* The 'sign' command may be prefixed with an 'l' for local "
+               "signatures (lsign),\n"
+               "  a 't' for trust signatures (tsign), an 'nr' for "
+               "non-revocable signatures\n"
+               "  (nrsign), or any combination thereof (ltsign, "
+               "tnrsign, etc.).\n"));
+         break;
 
-         case cmdLIST:
-           redisplay = 1;
-           break;
+       case cmdLIST:
+         redisplay = 1;
+         break;
 
-         case cmdFPR:
-           show_key_and_fingerprint( keyblock );
-           break;
+       case cmdFPR:
+         show_key_and_fingerprint (keyblock);
+         break;
 
-         case cmdSELUID:
-           if(strlen(arg_string)==NAMEHASH_LEN*2)
-             redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
-           else
-              {
-                if (*arg_string == '*'
-                    && (!arg_string[1] || spacep (arg_string+1)))
-                  arg_number = -1; /* Select all. */
-                redisplay = menu_select_uid (cur_keyblock, arg_number);
-              }
-           break;
+       case cmdSELUID:
+         if (strlen (arg_string) == NAMEHASH_LEN * 2)
+           redisplay = menu_select_uid_namehash (keyblock, arg_string);
+         else
+           {
+             if (*arg_string == '*'
+                 && (!arg_string[1] || spacep (arg_string + 1)))
+               arg_number = -1;        /* Select all. */
+             redisplay = menu_select_uid (keyblock, arg_number);
+           }
+         break;
 
-         case cmdSELKEY:
-            {
-              if (*arg_string == '*'
-                  && (!arg_string[1] || spacep (arg_string+1)))
-                arg_number = -1; /* Select all. */
-              if (menu_select_key( cur_keyblock, arg_number))
-               redisplay = 1;
-            }
-           break;
+       case cmdSELKEY:
+         {
+           if (*arg_string == '*'
+               && (!arg_string[1] || spacep (arg_string + 1)))
+             arg_number = -1;  /* Select all. */
+           if (menu_select_key (keyblock, arg_number))
+             redisplay = 1;
+         }
+         break;
 
-         case cmdCHECK:
-           /* we can only do this with the public key becuase the
-            * check functions can't cope with secret keys and it
-            * is questionable whether this would make sense at all */
-           check_all_keysigs( keyblock, count_selected_uids(keyblock) );
-           break;
+       case cmdCHECK:
+         check_all_keysigs (keyblock, count_selected_uids (keyblock));
+         break;
 
-         case cmdSIGN: /* sign (only the public key) */
-           {
-             int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
+       case cmdSIGN:
+         {
+           int localsig = 0, nonrevokesig = 0, trustsig = 0, interactive = 0;
 
-             if( pk->is_revoked )
-               {
-                 tty_printf(_("Key is revoked."));
+           if (pk->flags.revoked)
+             {
+               tty_printf (_("Key is revoked."));
 
-                 if(opt.expert)
-                   {
-                     tty_printf("  ");
-                     if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
-                                               _("Are you sure you still want"
-                                                 " to sign it? (y/N) ")))
-                       break;
-                   }
-                 else
-                   {
-                     tty_printf(_("  Unable to sign.\n"));
+               if (opt.expert)
+                 {
+                   tty_printf ("  ");
+                   if (!cpr_get_answer_is_yes
+                        ("keyedit.sign_revoked.okay",
+                         _("Are you sure you still want to sign it? (y/N) ")))
                      break;
-                   }
-               }
-
-             if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
-                && !cpr_get_answer_is_yes("keyedit.sign_all.okay",
-                                          _("Really sign all user IDs?"
-                                            " (y/N) ")))
-                {
-                  if(opt.interactive)
-                   interactive=1;
-                 else
-                    {
-                     tty_printf(_("Hint: Select the user IDs to sign\n"));
-                      have_commands = 0;
-                      break;
-                    }
+                 }
+               else
+                 {
+                   tty_printf (_("  Unable to sign.\n"));
+                   break;
+                 }
+             }
 
-                }
-             /* What sort of signing are we doing? */
-             if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
-               {
-                 tty_printf(_("Unknown signature type `%s'\n"),answer);
-                 break;
-               }
+           if (count_uids (keyblock) > 1 && !count_selected_uids (keyblock)
+               && !cpr_get_answer_is_yes ("keyedit.sign_all.okay",
+                                          _("Really sign all user IDs?"
+                                            " (y/N) ")))
+             {
+               if (opt.interactive)
+                 interactive = 1;
+               else
+                 {
+                   tty_printf (_("Hint: Select the user IDs to sign\n"));
+                   have_commands = 0;
+                   break;
+                 }
 
-             sign_uids(keyblock, locusr, &modified,
-                       localsig, nonrevokesig, trustsig, interactive);
-           }
-           break;
+             }
+           /* What sort of signing are we doing? */
+           if (!parse_sign_type
+               (answer, &localsig, &nonrevokesig, &trustsig))
+             {
+               tty_printf (_("Unknown signature type '%s'\n"), answer);
+               break;
+             }
 
-         case cmdDEBUG:
-           dump_kbnode( cur_keyblock );
-           break;
+           sign_uids (NULL, keyblock, locusr, &modified,
+                      localsig, nonrevokesig, trustsig, interactive, 0);
+         }
+         break;
 
-         case cmdTOGGLE:
-           toggle = !toggle;
-           cur_keyblock = toggle? sec_keyblock : keyblock;
-           redisplay = 1;
-           break;
+       case cmdDEBUG:
+         dump_kbnode (keyblock);
+         break;
+
+       case cmdTOGGLE:
+          /* The toggle command is a leftover from old gpg versions
+             where we worked with a secret and a public keyring.  It
+             is not necessary anymore but we keep this command for the
+             sake of scripts using it.  */
+         toggle = !toggle;
+         redisplay = 1;
+         break;
+
+       case cmdADDPHOTO:
+         if (RFC2440)
+           {
+             tty_printf (_("This command is not allowed while in %s mode.\n"),
+                         compliance_option_string ());
+             break;
+           }
+         photo = 1;
+         /* fall through */
+       case cmdADDUID:
+         if (menu_adduid (keyblock, photo, arg_string))
+           {
+             update_trust = 1;
+             redisplay = 1;
+             modified = 1;
+             merge_keys_and_selfsig (keyblock);
+           }
+         break;
 
-         case cmdADDPHOTO:
-            if (RFC2440 || RFC1991 || PGP2)
-              {
-                tty_printf(
-                   _("This command is not allowed while in %s mode.\n"),
-                  compliance_option_string());
-                break;
-              }
-           photo=1;
-           /* fall through */
-
-         case cmdADDUID:
-           if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
+       case cmdDELUID:
+         {
+           int n1;
+
+           if (!(n1 = count_selected_uids (keyblock)))
+             tty_printf (_("You must select at least one user ID.\n"));
+           else if (real_uids_left (keyblock) < 1)
+             tty_printf (_("You can't delete the last user ID!\n"));
+           else if (cpr_get_answer_is_yes
+                     ("keyedit.remove.uid.okay",
+                      n1 > 1 ? _("Really remove all selected user IDs? (y/N) ")
+                      :        _("Really remove this user ID? (y/N) ")))
              {
-               update_trust = 1;
+               menu_deluid (keyblock);
                redisplay = 1;
-               sec_modified = modified = 1;
-               merge_keys_and_selfsig( sec_keyblock );
-               merge_keys_and_selfsig( keyblock );
+               modified = 1;
              }
-           break;
-
-         case cmdDELUID: {
-               int n1;
-
-               if( !(n1=count_selected_uids(keyblock)) )
-                   tty_printf(_("You must select at least one user ID.\n"));
-               else if( real_uids_left(keyblock) < 1 )
-                   tty_printf(_("You can't delete the last user ID!\n"));
-               else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
-               n1 > 1? _("Really remove all selected user IDs? (y/N) ")
-                           : _("Really remove this user ID? (y/N) ")
-                      ) ) {
-                   menu_deluid( keyblock, sec_keyblock );
-                   redisplay = 1;
-                   modified = 1;
-                   if( sec_keyblock )
-                      sec_modified = 1;
-               }
-           }
-           break;
+         }
+         break;
 
-         case cmdDELSIG: {
-               int n1;
+       case cmdDELSIG:
+         {
+           int n1;
 
-               if( !(n1=count_selected_uids(keyblock)) )
-                   tty_printf(_("You must select at least one user ID.\n"));
-               else if( menu_delsig( keyblock ) ) {
-                   /* no redisplay here, because it may scroll away some
-                    * status output of delsig */
-                   modified = 1;
-               }
-           }
-           break;
+           if (!(n1 = count_selected_uids (keyblock)))
+             tty_printf (_("You must select at least one user ID.\n"));
+           else if (menu_delsig (keyblock))
+             {
+               /* No redisplay here, because it may scroll away some
+                * of the status output of this command.  */
+               modified = 1;
+             }
+         }
+         break;
 
-         case cmdADDKEY:
-           if( generate_subkeypair( keyblock, sec_keyblock ) ) {
-               redisplay = 1;
-               sec_modified = modified = 1;
-               merge_keys_and_selfsig( sec_keyblock );
-               merge_keys_and_selfsig( keyblock );
+       case cmdADDKEY:
+         if (!generate_subkeypair (ctrl, keyblock))
+           {
+             redisplay = 1;
+             modified = 1;
+             merge_keys_and_selfsig (keyblock);
            }
-           break;
+         break;
 
 #ifdef ENABLE_CARD_SUPPORT
-         case cmdADDCARDKEY:
-           if (card_generate_subkey (keyblock, sec_keyblock)) {
-               redisplay = 1;
-               sec_modified = modified = 1;
-               merge_keys_and_selfsig( sec_keyblock );
-               merge_keys_and_selfsig( keyblock );
+       case cmdADDCARDKEY:
+         if (!card_generate_subkey (keyblock))
+           {
+             redisplay = 1;
+             modified = 1;
+             merge_keys_and_selfsig (keyblock);
            }
-           break;
+         break;
 
-        case cmdKEYTOCARD:
+       case cmdKEYTOCARD:
          {
-           KBNODE node=NULL;
-           switch ( count_selected_keys (sec_keyblock) )
+           KBNODE node = NULL;
+           switch (count_selected_keys (keyblock))
              {
              case 0:
-                if (cpr_get_answer_is_yes
+               if (cpr_get_answer_is_yes
                     ("keyedit.keytocard.use_primary",
                      /* TRANSLATORS: Please take care: This is about
                         moving the key and not about removing it.  */
                      _("Really move the primary key? (y/N) ")))
-                 node = sec_keyblock;
+                 node = keyblock;
                break;
              case 1:
-               for (node = sec_keyblock; node; node = node->next )
+               for (node = keyblock; node; node = node->next)
                  {
-                   if (node->pkt->pkttype == PKT_SECRET_SUBKEY
+                   if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
                        && node->flag & NODFLG_SELKEY)
                      break;
                  }
                break;
              default:
-               tty_printf(_("You must select exactly one key.\n"));
+               tty_printf (_("You must select exactly one key.\n"));
                break;
              }
            if (node)
              {
-               PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
-               if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
+               PKT_public_key *xxpk = node->pkt->pkt.public_key;
+               if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
                  {
                    redisplay = 1;
-                   sec_modified = 1;
+                   /* Only the secret key has been modified; thus
+                       there is no need to set the modified flag.  */
                  }
              }
          }
-          break;
+         break;
 
-        case cmdBKUPTOCARD:
+       case cmdBKUPTOCARD:
+       case cmdCHECKBKUPKEY:
+          log_debug ("FIXME: This needs to be changed\n");
          {
-            /* Ask for a filename, check whether this is really a
-               backup key as generated by the card generation, parse
-               that key and store it on card. */
+           /* Ask for a filename, check whether this is really a
+              backup key as generated by the card generation, parse
+              that key and store it on card. */
            KBNODE node;
-            const char *fname;
-            PACKET *pkt;
-            IOBUF a;
-
-            fname = arg_string;
-            if (!*fname)
-              {
-                tty_printf (_("Command expects a filename argument\n"));
-                break;
-              }
-
-            /* Open that file.  */
-            a = iobuf_open (fname);
-            if (a && is_secured_file (iobuf_get_fd (a)))
-              {
-                iobuf_close (a);
-                a = NULL;
-                errno = EPERM;
-              }
-            if (!a)
-              {
-               tty_printf (_("Can't open `%s': %s\n"),
-                            fname, strerror(errno));
-                break;
-              }
-
-            /* Parse and check that file.  */
-            pkt = xmalloc (sizeof *pkt);
-            init_packet (pkt);
-            rc = parse_packet (a, pkt);
-            iobuf_close (a);
-            iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache).  */
-            if (!rc
-                && pkt->pkttype != PKT_SECRET_KEY
-                && pkt->pkttype != PKT_SECRET_SUBKEY)
-              rc = G10ERR_NO_SECKEY;
-            if (rc)
-              {
-                tty_printf(_("Error reading backup key from `%s': %s\n"),
-                           fname, g10_errstr (rc));
-                free_packet (pkt);
-                xfree (pkt);
-                break;
-              }
-            node = new_kbnode (pkt);
-
-            /* Store it.  */
-            if (card_store_subkey (node, 0))
-              {
-                redisplay = 1;
-                sec_modified = 1;
-              }
-            release_kbnode (node);
+           const char *fname;
+           PACKET *pkt;
+           IOBUF a;
+
+           fname = arg_string;
+           if (!*fname)
+             {
+               tty_printf (_("Command expects a filename argument\n"));
+               break;
+             }
+
+           /* Open that file.  */
+           a = iobuf_open (fname);
+           if (a && is_secured_file (iobuf_get_fd (a)))
+             {
+               iobuf_close (a);
+               a = NULL;
+               gpg_err_set_errno (EPERM);
+             }
+           if (!a)
+             {
+               tty_printf (_("Can't open '%s': %s\n"),
+                           fname, strerror (errno));
+               break;
+             }
+
+           /* Parse and check that file.  */
+           pkt = xmalloc (sizeof *pkt);
+           init_packet (pkt);
+           err = parse_packet (a, pkt);
+           iobuf_close (a);
+           iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname);
+           if (!err && pkt->pkttype != PKT_SECRET_KEY
+               && pkt->pkttype != PKT_SECRET_SUBKEY)
+             err = G10ERR_NO_SECKEY;
+           if (err)
+             {
+               tty_printf (_("Error reading backup key from '%s': %s\n"),
+                           fname, g10_errstr (err));
+               free_packet (pkt);
+               xfree (pkt);
+               break;
+             }
+           node = new_kbnode (pkt);
+
+           if (cmd == cmdCHECKBKUPKEY)
+             {
+               /* PKT_public_key *sk = node->pkt->pkt.secret_key; */
+               /* switch (is_secret_key_protected (sk)) */
+               /*   { */
+               /*   case 0:    /\* Not protected. *\/ */
+               /*     tty_printf (_("This key is not protected.\n")); */
+               /*     break; */
+               /*   case -1: */
+               /*     log_error (_("unknown key protection algorithm\n")); */
+               /*     break; */
+               /*   default: */
+               /*     if (sk->protect.s2k.mode == 1001) */
+               /*       tty_printf (_("Secret parts of key" */
+               /*                  " are not available.\n")); */
+               /*     if (sk->protect.s2k.mode == 1002) */
+               /*       tty_printf (_("Secret parts of key" */
+               /*                  " are stored on-card.\n")); */
+                   /* else */
+                   /*   check_secret_key (sk, 0); */
+                 /* } */
+             }
+           else                /* Store it.  */
+             {
+               if (card_store_subkey (node, 0))
+                 {
+                   redisplay = 1;
+                   /* FIXME:sec_modified = 1;*/
+                 }
+             }
+           release_kbnode (node);
          }
-          break;
+         break;
 
 #endif /* ENABLE_CARD_SUPPORT */
 
-         case cmdDELKEY: {
-               int n1;
-
-               if( !(n1=count_selected_keys( keyblock )) )
-                   tty_printf(_("You must select at least one key.\n"));
-               else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
-                      n1 > 1?
-                  _("Do you really want to delete the selected keys? (y/N) "):
-                       _("Do you really want to delete this key? (y/N) ")
-                      ))
-                   ;
-               else {
-                   menu_delkey( keyblock, sec_keyblock );
-                   redisplay = 1;
-                   modified = 1;
-                   if( sec_keyblock )
-                      sec_modified = 1;
-               }
-           }
-           break;
+       case cmdDELKEY:
+         {
+           int n1;
+
+           if (!(n1 = count_selected_keys (keyblock)))
+             tty_printf (_("You must select at least one key.\n"));
+           else if (!cpr_get_answer_is_yes
+                     ("keyedit.remove.subkey.okay",
+                      n1 > 1 ? _("Do you really want to delete the "
+                                 "selected keys? (y/N) ")
+                      :  _("Do you really want to delete this key? (y/N) ")))
+             ;
+           else
+             {
+               menu_delkey (keyblock);
+               redisplay = 1;
+               modified = 1;
+             }
+         }
+         break;
 
-         case cmdADDREVOKER:
-           {
-             int sensitive=0;
+       case cmdADDREVOKER:
+         {
+           int sensitive = 0;
 
-             if(ascii_strcasecmp(arg_string,"sensitive")==0)
-               sensitive=1;
-             if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
+           if (ascii_strcasecmp (arg_string, "sensitive") == 0)
+             sensitive = 1;
+           if (menu_addrevoker (ctrl, keyblock, sensitive))
+             {
                redisplay = 1;
-               sec_modified = modified = 1;
-               merge_keys_and_selfsig( sec_keyblock );
-               merge_keys_and_selfsig( keyblock );
+               modified = 1;
+               merge_keys_and_selfsig (keyblock);
              }
-           }
-           break;
+         }
+         break;
 
-         case cmdREVUID: {
-               int n1;
-
-               if( !(n1=count_selected_uids(keyblock)) )
-                   tty_printf(_("You must select at least one user ID.\n"));
-               else if( cpr_get_answer_is_yes(
-                           "keyedit.revoke.uid.okay",
-                      n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
-                            : _("Really revoke this user ID? (y/N) ")
-                      ) ) {
-                 if(menu_revuid(keyblock,sec_keyblock))
-                   {
-                     modified=1;
-                     redisplay=1;
-                   }
-               }
-           }
-           break;
+       case cmdREVUID:
+         {
+           int n1;
+
+           if (!(n1 = count_selected_uids (keyblock)))
+             tty_printf (_("You must select at least one user ID.\n"));
+           else if (cpr_get_answer_is_yes
+                     ("keyedit.revoke.uid.okay",
+                      n1 > 1 ? _("Really revoke all selected user IDs? (y/N) ")
+                     :        _("Really revoke this user ID? (y/N) ")))
+             {
+               if (menu_revuid (keyblock))
+                 {
+                   modified = 1;
+                   redisplay = 1;
+                 }
+             }
+         }
+         break;
 
-         case cmdREVKEY:
-           {
-             int n1;
+       case cmdREVKEY:
+         {
+           int n1;
 
-             if( !(n1=count_selected_keys( keyblock )) )
-               {
-                 if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
+           if (!(n1 = count_selected_keys (keyblock)))
+             {
+               if (cpr_get_answer_is_yes ("keyedit.revoke.subkey.okay",
                                           _("Do you really want to revoke"
                                             " the entire key? (y/N) ")))
-                   {
-                     if(menu_revkey(keyblock,sec_keyblock))
-                       modified=1;
+                 {
+                   if (menu_revkey (keyblock))
+                     modified = 1;
 
-                     redisplay=1;
-                   }
-               }
-             else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
-                                           n1 > 1?
-                                           _("Do you really want to revoke"
-                                             " the selected subkeys? (y/N) "):
+                   redisplay = 1;
+                 }
+             }
+           else if (cpr_get_answer_is_yes ("keyedit.revoke.subkey.okay",
+                                           n1 > 1 ?
                                            _("Do you really want to revoke"
-                                             " this subkey? (y/N) ")))
-               {
-                 if( menu_revsubkey( keyblock, sec_keyblock ) )
-                   modified = 1;
-
-                 redisplay = 1;
-               }
-
-             if(modified)
-               merge_keys_and_selfsig( keyblock );
-           }
-           break;
-
-         case cmdEXPIRE:
-           if( menu_expire( keyblock, sec_keyblock ) )
+                                             " the selected subkeys? (y/N) ")
+                                           : _("Do you really want to revoke"
+                                               " this subkey? (y/N) ")))
              {
-               merge_keys_and_selfsig( sec_keyblock );
-               merge_keys_and_selfsig( keyblock );
-                run_subkey_warnings = 1;
-               sec_modified = 1;
-               modified = 1;
-               redisplay = 1;
-             }
-           break;
+               if (menu_revsubkey (keyblock))
+                 modified = 1;
 
-         case cmdBACKSIGN:
-           if(menu_backsign(keyblock,sec_keyblock))
-             {
-               sec_modified = 1;
-               modified = 1;
                redisplay = 1;
              }
-           break;
 
-         case cmdPRIMARY:
-           if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
-               merge_keys_and_selfsig( keyblock );
-               modified = 1;
-               redisplay = 1;
+           if (modified)
+             merge_keys_and_selfsig (keyblock);
+         }
+         break;
+
+       case cmdEXPIRE:
+         if (menu_expire (keyblock))
+           {
+             merge_keys_and_selfsig (keyblock);
+              run_subkey_warnings = 1;
+             modified = 1;
+             redisplay = 1;
            }
-           break;
+         break;
 
-         case cmdPASSWD:
-           if (change_passphrase (sec_keyblock, NULL))
-               sec_modified = 1;
-           break;
+       case cmdBACKSIGN:
+         if (menu_backsign (keyblock))
+           {
+             modified = 1;
+             redisplay = 1;
+           }
+         break;
 
-         case cmdTRUST:
-           if(opt.trust_model==TM_EXTERNAL)
-             {
-               tty_printf (_("Owner trust may not be set while "
-                             "using a user provided trust database\n"));
-               break;
-             }
+       case cmdPRIMARY:
+         if (menu_set_primary_uid (keyblock))
+           {
+             merge_keys_and_selfsig (keyblock);
+             modified = 1;
+             redisplay = 1;
+           }
+         break;
 
-           show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
-           tty_printf("\n");
-           if( edit_ownertrust( find_kbnode( keyblock,
-                                 PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
-               redisplay = 1;
-               /* No real need to set update_trust here as
-                  edit_ownertrust() calls revalidation_mark()
-                  anyway. */
-               update_trust=1;
-            }
-           break;
+       case cmdPASSWD:
+         change_passphrase (ctrl, keyblock);
+         break;
 
-         case cmdPREF:
+#ifndef NO_TRUST_MODELS
+       case cmdTRUST:
+         if (opt.trust_model == TM_EXTERNAL)
            {
-             int count=count_selected_uids(keyblock);
-             assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-             show_names(keyblock,keyblock->pkt->pkt.public_key,
-                        count?NODFLG_SELUID:0,1);
+             tty_printf (_("Owner trust may not be set while "
+                           "using a user provided trust database\n"));
+             break;
            }
-           break;
 
-         case cmdSHOWPREF:
+         show_key_with_all_names (NULL, keyblock, 0, 0, 0, 1, 0, 0);
+         tty_printf ("\n");
+         if (edit_ownertrust (find_kbnode (keyblock,
+                                           PKT_PUBLIC_KEY)->pkt->pkt.
+                              public_key, 1))
            {
-             int count=count_selected_uids(keyblock);
-             assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-             show_names(keyblock,keyblock->pkt->pkt.public_key,
-                        count?NODFLG_SELUID:0,2);
+             redisplay = 1;
+             /* No real need to set update_trust here as
+                edit_ownertrust() calls revalidation_mark()
+                anyway. */
+             update_trust = 1;
            }
-           break;
+         break;
+#endif /*!NO_TRUST_MODELS*/
 
-          case cmdSETPREF:
-           {
-             PKT_user_id *tempuid;
+       case cmdPREF:
+         {
+           int count = count_selected_uids (keyblock);
+           assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+           show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
+                       count ? NODFLG_SELUID : 0, 1);
+         }
+         break;
 
-             keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
+       case cmdSHOWPREF:
+         {
+           int count = count_selected_uids (keyblock);
+           assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+           show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
+                       count ? NODFLG_SELUID : 0, 2);
+         }
+         break;
 
-             tempuid=keygen_get_std_prefs();
-             tty_printf(_("Set preference list to:\n"));
-             show_prefs(tempuid,NULL,1);
-             free_user_id(tempuid);
+       case cmdSETPREF:
+         {
+           PKT_user_id *tempuid;
 
-             if(cpr_get_answer_is_yes("keyedit.setpref.okay",
-                                      count_selected_uids (keyblock)?
-                                      _("Really update the preferences"
-                                        " for the selected user IDs? (y/N) "):
-                                      _("Really update the preferences? (y/N) ")))
-               {
-                 if ( menu_set_preferences (keyblock, sec_keyblock) )
-                   {
-                     merge_keys_and_selfsig (keyblock);
-                     modified = 1;
-                     redisplay = 1;
-                   }
-               }
-           }
-           break;
+           keygen_set_std_prefs (!*arg_string ? "default" : arg_string, 0);
 
-         case cmdPREFKS:
-           if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
-                                        keyblock, sec_keyblock ) )
-             {
-               merge_keys_and_selfsig( keyblock );
-               modified = 1;
-               redisplay = 1;
-             }
-           break;
+           tempuid = keygen_get_std_prefs ();
+           tty_printf (_("Set preference list to:\n"));
+           show_prefs (tempuid, NULL, 1);
+           free_user_id (tempuid);
 
-         case cmdNOTATION:
-           if( menu_set_notation ( *arg_string?arg_string:NULL,
-                                   keyblock, sec_keyblock ) )
+           if (cpr_get_answer_is_yes
+                ("keyedit.setpref.okay",
+                 count_selected_uids (keyblock) ?
+                 _("Really update the preferences"
+                   " for the selected user IDs? (y/N) ")
+                 : _("Really update the preferences? (y/N) ")))
              {
-               merge_keys_and_selfsig( keyblock );
-               modified = 1;
-               redisplay = 1;
+               if (menu_set_preferences (keyblock))
+                 {
+                   merge_keys_and_selfsig (keyblock);
+                   modified = 1;
+                   redisplay = 1;
+                 }
              }
-           break;
+         }
+         break;
 
-         case cmdNOP:
-           break;
+       case cmdPREFKS:
+         if (menu_set_keyserver_url (*arg_string ? arg_string : NULL,
+                                     keyblock))
+           {
+             merge_keys_and_selfsig (keyblock);
+             modified = 1;
+             redisplay = 1;
+           }
+         break;
 
-         case cmdREVSIG:
-           if( menu_revsig( keyblock ) ) {
-               redisplay = 1;
-               modified = 1;
+       case cmdNOTATION:
+         if (menu_set_notation (*arg_string ? arg_string : NULL,
+                                keyblock))
+           {
+             merge_keys_and_selfsig (keyblock);
+             modified = 1;
+             redisplay = 1;
            }
-           break;
+         break;
 
-         case cmdENABLEKEY:
-         case cmdDISABLEKEY:
-           if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
-               redisplay = 1;
-               modified = 1;
+       case cmdNOP:
+         break;
+
+       case cmdREVSIG:
+         if (menu_revsig (keyblock))
+           {
+             redisplay = 1;
+             modified = 1;
            }
-           break;
+         break;
 
-         case cmdSHOWPHOTO:
-           menu_showphoto(keyblock);
-           break;
+#ifndef NO_TRUST_MODELS
+       case cmdENABLEKEY:
+       case cmdDISABLEKEY:
+         if (enable_disable_key (keyblock, cmd == cmdDISABLEKEY))
+           {
+             redisplay = 1;
+             modified = 1;
+           }
+         break;
+#endif /*!NO_TRUST_MODELS*/
 
-         case cmdCLEAN:
-           if(menu_clean(keyblock,0))
-             redisplay=modified=1;
-           break;
+       case cmdSHOWPHOTO:
+         menu_showphoto (keyblock);
+         break;
 
-         case cmdMINIMIZE:
-           if(menu_clean(keyblock,1))
-             redisplay=modified=1;
-           break;
+       case cmdCLEAN:
+         if (menu_clean (keyblock, 0))
+           redisplay = modified = 1;
+         break;
 
-         case cmdQUIT:
-           if( have_commands )
-               goto leave;
-           if( !modified && !sec_modified )
+       case cmdMINIMIZE:
+         if (menu_clean (keyblock, 1))
+           redisplay = modified = 1;
+         break;
+
+       case cmdQUIT:
+         if (have_commands)
+           goto leave;
+         if (!modified)
+           goto leave;
+         if (!cpr_get_answer_is_yes ("keyedit.save.okay",
+                                     _("Save changes? (y/N) ")))
+           {
+             if (cpr_enabled ()
+                 || cpr_get_answer_is_yes ("keyedit.cancel.okay",
+                                           _("Quit without saving? (y/N) ")))
                goto leave;
-           if( !cpr_get_answer_is_yes("keyedit.save.okay",
-                                       _("Save changes? (y/N) ")) ) {
-               if( cpr_enabled()
-                   || cpr_get_answer_is_yes("keyedit.cancel.okay",
-                                            _("Quit without saving? (y/N) ")))
-                   goto leave;
-               break;
+             break;
            }
-           /* fall thru */
-         case cmdSAVE:
-           if( modified || sec_modified  ) {
-               if( modified ) {
-                   rc = keydb_update_keyblock (kdbhd, keyblock);
-                   if( rc ) {
-                       log_error(_("update failed: %s\n"), g10_errstr(rc) );
-                       break;
-                   }
-               }
-               if( sec_modified ) {
-                   rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
-                   if( rc ) {
-                       log_error( _("update secret failed: %s\n"),
-                                   g10_errstr(rc) );
-                       break;
-                   }
-               }
+         /* fall thru */
+       case cmdSAVE:
+         if (modified)
+           {
+              err = keydb_update_keyblock (kdbhd, keyblock);
+              if (err)
+                {
+                  log_error (_("update failed: %s\n"), g10_errstr (err));
+                  break;
+                }
            }
-           else
-               tty_printf(_("Key not changed so no update needed.\n"));
+         else
+           tty_printf (_("Key not changed so no update needed.\n"));
 
-           if( update_trust )
-             {
-               revalidation_mark ();
-               update_trust=0;
-             }
-           goto leave;
+         if (update_trust)
+           {
+             revalidation_mark ();
+             update_trust = 0;
+           }
+         goto leave;
 
-         case cmdINVCMD:
-         default:
-           tty_printf("\n");
-           tty_printf(_("Invalid command  (try \"help\")\n"));
-           break;
+       case cmdINVCMD:
+       default:
+         tty_printf ("\n");
+         tty_printf (_("Invalid command  (try \"help\")\n"));
+         break;
        }
-    } /* end main loop */
+    } /* End of the main command loop.  */
 
-  leave:
-    release_kbnode( keyblock );
-    release_kbnode( sec_keyblock );
-    keydb_release (kdbhd);
-    xfree(answer);
+ leave:
+  release_kbnode (keyblock);
+  keydb_release (kdbhd);
+  xfree (answer);
 }
 
 
 /* Change the passphrase of the secret key identified by USERNAME.  */
 void
-keyedit_passwd (const char *username)
+keyedit_passwd (ctrl_t ctrl, const char *username)
 {
   gpg_error_t err;
   PKT_public_key *pk;
-  unsigned char fpr[MAX_FINGERPRINT_LEN];
-  size_t fprlen;
-  KEYDB_HANDLE kdh = NULL;
-  KBNODE keyblock = NULL;
+  kbnode_t keyblock = NULL;
 
   pk = xtrycalloc (1, sizeof *pk);
   if (!pk)
@@ -2334,430 +2241,579 @@ keyedit_passwd (const char *username)
       err = gpg_error_from_syserror ();
       goto leave;
     }
-  err = get_pubkey_byname (NULL, pk, username, NULL, NULL, 1, 1);
+  err = getkey_byname (NULL, pk, username, 1, &keyblock);
   if (err)
     goto leave;
-  fingerprint_from_pk (pk, fpr, &fprlen);
-  while (fprlen < MAX_FINGERPRINT_LEN)
-    fpr[fprlen++] = 0;
 
-  kdh = keydb_new (1);
-  if (!kdh)
+  err = change_passphrase (ctrl, keyblock);
+
+leave:
+  release_kbnode (keyblock);
+  free_public_key (pk);
+  if (err)
     {
-      err = gpg_error (GPG_ERR_GENERAL);
-      goto leave;
+      log_info ("error changing the passphrase for '%s': %s\n",
+               username, gpg_strerror (err));
+      write_status_error ("keyedit.passwd", err);
     }
+  else
+    write_status_text (STATUS_SUCCESS, "keyedit.passwd");
+}
 
-  err = keydb_search_fpr (kdh, fpr);
-  if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
-    err = gpg_error (GPG_ERR_NO_SECKEY);
-  if (err)
-    goto leave;
 
-  err = keydb_get_keyblock (kdh, &keyblock);
-  if (err)
-    goto leave;
+/* Unattended key signing function.  If the key specifified by FPR is
+   availabale and FPR is the primary fingerprint all user ids of the
+   user ids of the key are signed using the default signing key.  If
+   UIDS is an empty list all usable UIDs are signed, if it is not
+   empty, only those user ids matching one of the entries of the loist
+   are signed.  With LOCAL being true kthe signatures are marked as
+   non-exportable.  */
+void
+keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
+                    strlist_t locusr, int local)
+{
+  gpg_error_t err;
+  kbnode_t keyblock = NULL;
+  KEYDB_HANDLE kdbhd = NULL;
+  int modified = 0;
+  KEYDB_SEARCH_DESC desc;
+  PKT_public_key *pk;
+  kbnode_t node;
+  strlist_t sl;
+  int any;
 
-  if (!change_passphrase (keyblock, &err))
-    goto leave;
+#ifdef HAVE_W32_SYSTEM
+  /* See keyedit_menu for why we need this.  */
+  check_trustdb_stale ();
+#endif
 
-  err = keydb_update_keyblock (kdh, keyblock);
+  /* We require a fingerprint because only this uniquely identifies a
+     key and may thus be used to select a key for unattended key
+     signing.  */
+  if (classify_user_id (fpr, &desc, 1)
+      || !(desc.mode == KEYDB_SEARCH_MODE_FPR
+           || desc.mode == KEYDB_SEARCH_MODE_FPR16
+           || desc.mode == KEYDB_SEARCH_MODE_FPR20))
+    {
+      log_error (_("\"%s\" is not a fingerprint\n"), fpr);
+      goto leave;
+    }
+  err = get_pubkey_byname (ctrl, NULL, NULL, fpr, &keyblock, &kdbhd, 1, 1);
   if (err)
-    log_error( _("update secret failed: %s\n"), gpg_strerror (err));
+    {
+      log_error (_("key \"%s\" not found: %s\n"), fpr, gpg_strerror (err));
+      goto leave;
+    }
+  if (fix_keyblock (keyblock))
+    modified++;
+  if (collapse_uids (&keyblock))
+    modified++;
+  reorder_keyblock (keyblock);
 
- leave:
-  release_kbnode (keyblock);
-  if (pk)
-    free_public_key (pk);
-  keydb_release (kdh);
-  if (err)
+  /* Check that the primary fingerprint has been given. */
+  {
+    byte fprbin[MAX_FINGERPRINT_LEN];
+    size_t fprlen;
+
+    fingerprint_from_pk (keyblock->pkt->pkt.public_key, fprbin, &fprlen);
+    if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR16
+        && !memcmp (fprbin, desc.u.fpr, 16))
+      ;
+    else if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR
+             && !memcmp (fprbin, desc.u.fpr, 16)
+             && !desc.u.fpr[16]
+             && !desc.u.fpr[17]
+             && !desc.u.fpr[18]
+             && !desc.u.fpr[19])
+      ;
+    else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
+                              || desc.mode == KEYDB_SEARCH_MODE_FPR)
+             && !memcmp (fprbin, desc.u.fpr, 20))
+      ;
+    else
+      {
+        log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
+        goto leave;
+      }
+  }
+
+  /* If we modified the keyblock, make sure the flags are right. */
+  if (modified)
+    merge_keys_and_selfsig (keyblock);
+
+  /* Give some info in verbose.  */
+  if (opt.verbose)
+    {
+      show_key_with_all_names (es_stdout, keyblock, 0,
+                               1/*with_revoker*/, 1/*with_fingerprint*/,
+                               0, 0, 1);
+      es_fflush (es_stdout);
+    }
+
+  pk = keyblock->pkt->pkt.public_key;
+  if (pk->flags.revoked)
+    {
+      if (!opt.verbose)
+        show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+      log_error ("%s%s", _("Key is revoked."), _("  Unable to sign.\n"));
+      goto leave;
+    }
+
+  /* Set the flags according to the UIDS list.  Fixme: We may want to
+     use classify_user_id along with dedicated compare functions so
+     that we match the same way as in the key lookup. */
+  any = 0;
+  menu_select_uid (keyblock, 0);   /* Better clear the flags first. */
+  for (sl=uids; sl; sl = sl->next)
+    {
+      for (node = keyblock; node; node = node->next)
+        {
+          if (node->pkt->pkttype == PKT_USER_ID)
+            {
+              PKT_user_id *uid = node->pkt->pkt.user_id;
+
+              if (!uid->attrib_data
+                  && ascii_memistr (uid->name, uid->len, sl->d))
+                {
+                  node->flag |= NODFLG_SELUID;
+                  any = 1;
+                }
+            }
+        }
+    }
+
+  if (uids && !any)
     {
-      log_info ("error changing the passphrase for `%s': %s\n",
-                username, gpg_strerror (err));
-      write_status_error ("keyedit.passwd", gpg_err_code (err));
+      if (!opt.verbose)
+        show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+      es_fflush (es_stdout);
+      log_error ("%s  %s", _("No matching user IDs."), _("Nothing to sign.\n"));
+      goto leave;
+    }
+
+  /* Sign. */
+  sign_uids (es_stdout, keyblock, locusr, &modified, local, 0, 0, 0, 1);
+  es_fflush (es_stdout);
+
+  if (modified)
+    {
+      err = keydb_update_keyblock (kdbhd, keyblock);
+      if (err)
+        {
+          log_error (_("update failed: %s\n"), gpg_strerror (err));
+          goto leave;
+        }
     }
   else
-    write_status_text (STATUS_SUCCESS, "keyedit.passwd");
+    log_info (_("Key not changed so no update needed.\n"));
+
+  if (update_trust)
+    revalidation_mark ();
+
+
+ leave:
+  release_kbnode (keyblock);
+  keydb_release (kdbhd);
 }
 
 
+\f
 static void
-tty_print_notations(int indent,PKT_signature *sig)
+tty_print_notations (int indent, PKT_signature * sig)
 {
-  int first=1;
-  struct notation *notation,*nd;
+  int first = 1;
+  struct notation *notation, *nd;
 
-  if(indent<0)
+  if (indent < 0)
     {
-      first=0;
-      indent=-indent;
+      first = 0;
+      indent = -indent;
     }
 
-  notation=sig_to_notation(sig);
+  notation = sig_to_notation (sig);
 
-  for(nd=notation;nd;nd=nd->next)
+  for (nd = notation; nd; nd = nd->next)
     {
-      if(!first)
-       tty_printf("%*s",indent,"");
+      if (!first)
+       tty_printf ("%*s", indent, "");
       else
-       first=0;
+       first = 0;
 
-      tty_print_utf8_string(nd->name,strlen(nd->name));
-      tty_printf("=");
-      tty_print_utf8_string(nd->value,strlen(nd->value));
-      tty_printf("\n");
+      tty_print_utf8_string (nd->name, strlen (nd->name));
+      tty_printf ("=");
+      tty_print_utf8_string (nd->value, strlen (nd->value));
+      tty_printf ("\n");
     }
 
-  free_notation(notation);
+  free_notation (notation);
 }
 
-/****************
- * show preferences of a public keyblock.
+
+/*
+ * Show preferences of a public keyblock.
  */
 static void
-show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
+show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
 {
-    const prefitem_t fake={0,0};
-    const prefitem_t *prefs;
-    int i;
+  const prefitem_t fake = { 0, 0 };
+  const prefitem_t *prefs;
+  int i;
 
-    if( !uid )
-        return;
+  if (!uid)
+    return;
 
-    if( uid->prefs )
-        prefs=uid->prefs;
-    else if(verbose)
-        prefs=&fake;
-    else
-      return;
+  if (uid->prefs)
+    prefs = uid->prefs;
+  else if (verbose)
+    prefs = &fake;
+  else
+    return;
 
-    if (verbose) {
-        int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
-
-        tty_printf ("     ");
-       tty_printf (_("Cipher: "));
-        for(i=any=0; prefs[i].type; i++ ) {
-            if( prefs[i].type == PREFTYPE_SYM ) {
-                if (any)
-                    tty_printf (", ");
-                any = 1;
-                /* We don't want to display strings for experimental algos */
-                if (!openpgp_cipher_test_algo (prefs[i].value)
-                    && prefs[i].value < 100 )
-                    tty_printf ("%s",
-                                openpgp_cipher_algo_name (prefs[i].value));
-                else
-                    tty_printf ("[%d]", prefs[i].value);
-                if (prefs[i].value == CIPHER_ALGO_3DES )
-                    des_seen = 1;
-            }
-        }
-        if (!des_seen) {
-            if (any)
-                tty_printf (", ");
-            tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
-        }
-        tty_printf ("\n     ");
-       tty_printf (_("Digest: "));
-        for(i=any=0; prefs[i].type; i++ ) {
-            if( prefs[i].type == PREFTYPE_HASH ) {
-                if (any)
-                    tty_printf (", ");
-                any = 1;
-                /* We don't want to display strings for experimental algos */
-                if (!gcry_md_test_algo (prefs[i].value)
-                    && prefs[i].value < 100 )
-                    tty_printf ("%s", gcry_md_algo_name (prefs[i].value) );
-                else
-                    tty_printf ("[%d]", prefs[i].value);
-                if (prefs[i].value == DIGEST_ALGO_SHA1 )
-                    sha1_seen = 1;
-            }
-        }
-        if (!sha1_seen) {
-            if (any)
-                tty_printf (", ");
-            tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
-        }
-        tty_printf ("\n     ");
-       tty_printf (_("Compression: "));
-        for(i=any=0; prefs[i].type; i++ ) {
-            if( prefs[i].type == PREFTYPE_ZIP ) {
-                const char *s=compress_algo_to_string(prefs[i].value);
-
-                if (any)
-                    tty_printf (", ");
-                any = 1;
-                /* We don't want to display strings for experimental algos */
-                if (s && prefs[i].value < 100 )
-                    tty_printf ("%s", s );
-                else
-                    tty_printf ("[%d]", prefs[i].value);
-                if (prefs[i].value == COMPRESS_ALGO_NONE )
-                    uncomp_seen = 1;
-            }
-        }
-        if (!uncomp_seen) {
-            if (any)
-                tty_printf (", ");
-           else {
-             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
+  if (verbose)
+    {
+      int any, des_seen = 0, sha1_seen = 0, uncomp_seen = 0;
+
+      tty_printf ("     ");
+      tty_printf (_("Cipher: "));
+      for (i = any = 0; prefs[i].type; i++)
+       {
+         if (prefs[i].type == PREFTYPE_SYM)
+           {
+             if (any)
+               tty_printf (", ");
+             any = 1;
+             /* We don't want to display strings for experimental algos */
+             if (!openpgp_cipher_test_algo (prefs[i].value)
+                 && prefs[i].value < 100)
+               tty_printf ("%s", openpgp_cipher_algo_name (prefs[i].value));
+             else
+               tty_printf ("[%d]", prefs[i].value);
+             if (prefs[i].value == CIPHER_ALGO_3DES)
+               des_seen = 1;
+           }
+       }
+      if (!des_seen)
+       {
+         if (any)
+           tty_printf (", ");
+         tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
+       }
+      tty_printf ("\n     ");
+      tty_printf (_("Digest: "));
+      for (i = any = 0; prefs[i].type; i++)
+       {
+         if (prefs[i].type == PREFTYPE_HASH)
+           {
+             if (any)
+               tty_printf (", ");
+             any = 1;
+             /* We don't want to display strings for experimental algos */
+             if (!gcry_md_test_algo (prefs[i].value) && prefs[i].value < 100)
+               tty_printf ("%s", gcry_md_algo_name (prefs[i].value));
+             else
+               tty_printf ("[%d]", prefs[i].value);
+             if (prefs[i].value == DIGEST_ALGO_SHA1)
+               sha1_seen = 1;
+           }
+       }
+      if (!sha1_seen)
+       {
+         if (any)
+           tty_printf (", ");
+         tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
+       }
+      tty_printf ("\n     ");
+      tty_printf (_("Compression: "));
+      for (i = any = 0; prefs[i].type; i++)
+       {
+         if (prefs[i].type == PREFTYPE_ZIP)
+           {
+             const char *s = compress_algo_to_string (prefs[i].value);
+
+             if (any)
+               tty_printf (", ");
+             any = 1;
+             /* We don't want to display strings for experimental algos */
+             if (s && prefs[i].value < 100)
+               tty_printf ("%s", s);
+             else
+               tty_printf ("[%d]", prefs[i].value);
+             if (prefs[i].value == COMPRESS_ALGO_NONE)
+               uncomp_seen = 1;
+           }
+       }
+      if (!uncomp_seen)
+       {
+         if (any)
+           tty_printf (", ");
+         else
+           {
+             tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_ZIP));
              tty_printf (", ");
            }
-           tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
-        }
-       if(uid->flags.mdc || !uid->flags.ks_modify)
-         {
-           tty_printf ("\n     ");
-           tty_printf (_("Features: "));
-           any=0;
-           if(uid->flags.mdc)
-             {
-               tty_printf ("MDC");
-               any=1;
-             }
-           if(!uid->flags.ks_modify)
-             {
-               if(any)
-                 tty_printf (", ");
-               tty_printf (_("Keyserver no-modify"));
-             }
-         }
-       tty_printf("\n");
+         tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_NONE));
+       }
+      if (uid->flags.mdc || !uid->flags.ks_modify)
+       {
+         tty_printf ("\n     ");
+         tty_printf (_("Features: "));
+         any = 0;
+         if (uid->flags.mdc)
+           {
+             tty_printf ("MDC");
+             any = 1;
+           }
+         if (!uid->flags.ks_modify)
+           {
+             if (any)
+               tty_printf (", ");
+             tty_printf (_("Keyserver no-modify"));
+           }
+       }
+      tty_printf ("\n");
 
-       if(selfsig)
-         {
-           const byte *pref_ks;
-           size_t pref_ks_len;
+      if (selfsig)
+       {
+         const byte *pref_ks;
+         size_t pref_ks_len;
 
-           pref_ks=parse_sig_subpkt(selfsig->hashed,
-                                    SIGSUBPKT_PREF_KS,&pref_ks_len);
-           if(pref_ks && pref_ks_len)
-             {
-               tty_printf ("     ");
-               tty_printf(_("Preferred keyserver: "));
-               tty_print_utf8_string(pref_ks,pref_ks_len);
-               tty_printf("\n");
-             }
+         pref_ks = parse_sig_subpkt (selfsig->hashed,
+                                     SIGSUBPKT_PREF_KS, &pref_ks_len);
+         if (pref_ks && pref_ks_len)
+           {
+             tty_printf ("     ");
+             tty_printf (_("Preferred keyserver: "));
+             tty_print_utf8_string (pref_ks, pref_ks_len);
+             tty_printf ("\n");
+           }
 
-           if(selfsig->flags.notation)
-             {
-               tty_printf ("     ");
-               tty_printf(_("Notations: "));
-               tty_print_notations(5+strlen(_("Notations: ")),selfsig);
-             }
-         }
+         if (selfsig->flags.notation)
+           {
+             tty_printf ("     ");
+             tty_printf (_("Notations: "));
+             tty_print_notations (5 + strlen (_("Notations: ")), selfsig);
+           }
+       }
     }
-    else {
-        tty_printf("    ");
-        for(i=0; prefs[i].type; i++ ) {
-            tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
-                                 prefs[i].type == PREFTYPE_HASH  ? 'H' :
-                                 prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
-                                 prefs[i].value);
-        }
-        if (uid->flags.mdc)
-            tty_printf (" [mdc]");
-        if (!uid->flags.ks_modify)
-            tty_printf (" [no-ks-modify]");
-        tty_printf("\n");
+  else
+    {
+      tty_printf ("    ");
+      for (i = 0; prefs[i].type; i++)
+       {
+         tty_printf (" %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
+                     prefs[i].type == PREFTYPE_HASH ? 'H' :
+                     prefs[i].type == PREFTYPE_ZIP ? 'Z' : '?',
+                     prefs[i].value);
+       }
+      if (uid->flags.mdc)
+       tty_printf (" [mdc]");
+      if (!uid->flags.ks_modify)
+       tty_printf (" [no-ks-modify]");
+      tty_printf ("\n");
     }
 }
 
+
 /* This is the version of show_key_with_all_names used when
    opt.with_colons is used.  It prints all available data in a easy to
    parse format and does not translate utf8 */
 static void
-show_key_with_all_names_colon (KBNODE keyblock)
+show_key_with_all_names_colon (estream_t fp, kbnode_t keyblock)
 {
   KBNODE node;
-  int i, j, ulti_hack=0;
-  byte pk_version=0;
-  PKT_public_key *primary=NULL;
+  int i, j, ulti_hack = 0;
+  byte pk_version = 0;
+  PKT_public_key *primary = NULL;
+
+  if (!fp)
+    fp = es_stdout;
 
   /* the keys */
-  for ( node = keyblock; node; node = node->next )
+  for (node = keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_PUBLIC_KEY
-          || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
-        {
-          PKT_public_key *pk = node->pkt->pkt.public_key;
-          u32 keyid[2];
+         || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
+       {
+         PKT_public_key *pk = node->pkt->pkt.public_key;
+         u32 keyid[2];
 
-          if (node->pkt->pkttype == PKT_PUBLIC_KEY)
-            {
-              pk_version = pk->version;
-             primary=pk;
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+           {
+             pk_version = pk->version;
+             primary = pk;
            }
 
-          keyid_from_pk (pk, keyid);
-
-          fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
-          if (!pk->is_valid)
-            putchar ('i');
-          else if (pk->is_revoked)
-            putchar ('r');
-          else if (pk->has_expired)
-            putchar ('e');
-          else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
+         keyid_from_pk (pk, keyid);
+
+         es_fputs (node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub:" : "sub:",
+                    fp);
+         if (!pk->flags.valid)
+           es_putc ('i', fp);
+         else if (pk->flags.revoked)
+           es_putc ('r', fp);
+         else if (pk->has_expired)
+           es_putc ('e', fp);
+         else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks))
            {
              int trust = get_validity_info (pk, NULL);
-             if(trust=='u')
-               ulti_hack=1;
-             putchar (trust);
+             if (trust == 'u')
+               ulti_hack = 1;
+             es_putc (trust, fp);
            }
 
-          printf (":%u:%d:%08lX%08lX:%lu:%lu::",
-                  nbits_from_pk (pk),
-                  pk->pubkey_algo,
-                  (ulong)keyid[0], (ulong)keyid[1],
-                  (ulong)pk->timestamp,
-                  (ulong)pk->expiredate );
-          if (node->pkt->pkttype==PKT_PUBLIC_KEY
-             && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
-           putchar(get_ownertrust_info (pk));
-          putchar(':');
-          putchar (':');
-          putchar (':');
-          /* Print capabilities.  */
-          if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) )
-            putchar ('e');
-          if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) )
-            putchar ('s');
-          if ( (pk->pubkey_usage & PUBKEY_USAGE_CERT) )
-            putchar ('c');
-          if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) )
-            putchar ('a');
-          putchar('\n');
-
-          print_fingerprint (pk, NULL, 0);
-         print_revokers(pk);
-        }
+         es_fprintf (fp, ":%u:%d:%08lX%08lX:%lu:%lu::",
+                      nbits_from_pk (pk),
+                      pk->pubkey_algo,
+                      (ulong) keyid[0], (ulong) keyid[1],
+                      (ulong) pk->timestamp, (ulong) pk->expiredate);
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY
+             && !(opt.fast_list_mode || opt.no_expensive_trust_checks))
+           es_putc (get_ownertrust_info (pk), fp);
+         es_putc (':', fp);
+         es_putc (':', fp);
+         es_putc (':', fp);
+         /* Print capabilities.  */
+         if ((pk->pubkey_usage & PUBKEY_USAGE_ENC))
+           es_putc ('e', fp);
+         if ((pk->pubkey_usage & PUBKEY_USAGE_SIG))
+           es_putc ('s', fp);
+         if ((pk->pubkey_usage & PUBKEY_USAGE_CERT))
+           es_putc ('c', fp);
+         if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
+           es_putc ('a', fp);
+         es_putc ('\n', fp);
+
+         print_fingerprint (fp, pk, 0);
+         print_revokers (fp, pk);
+       }
     }
 
-    /* the user ids */
-    i = 0;
-    for (node = keyblock; node; node = node->next)
-      {
-       if ( node->pkt->pkttype == PKT_USER_ID )
-          {
-            PKT_user_id *uid = node->pkt->pkt.user_id;
+  /* the user ids */
+  i = 0;
+  for (node = keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         PKT_user_id *uid = node->pkt->pkt.user_id;
 
-           ++i;
+         ++i;
 
-           if(uid->attrib_data)
-             printf("uat:");
-           else
-             printf("uid:");
-
-           if ( uid->is_revoked )
-             printf("r::::::::");
-           else if ( uid->is_expired )
-             printf("e::::::::");
-           else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
-             printf("::::::::");
-           else
-             {
-               int uid_validity;
+         if (uid->attrib_data)
+           es_fputs ("uat:", fp);
+         else
+           es_fputs ("uid:", fp);
+
+         if (uid->is_revoked)
+           es_fputs ("r::::::::", fp);
+         else if (uid->is_expired)
+           es_fputs ("e::::::::", fp);
+         else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
+           es_fputs ("::::::::", fp);
+         else
+           {
+             int uid_validity;
 
-               if( primary && !ulti_hack )
-                 uid_validity = get_validity_info( primary, uid );
-               else
-                 uid_validity = 'u';
-               printf("%c::::::::",uid_validity);
-             }
+             if (primary && !ulti_hack)
+               uid_validity = get_validity_info (primary, uid);
+             else
+               uid_validity = 'u';
+             es_fprintf (fp, "%c::::::::", uid_validity);
+           }
 
-           if(uid->attrib_data)
-             printf ("%u %lu",uid->numattribs,uid->attrib_len);
-           else
-             print_string (stdout, uid->name, uid->len, ':');
-
-            putchar (':');
-            /* signature class */
-            putchar (':');
-            /* capabilities */
-            putchar (':');
-            /* preferences */
-            if (pk_version>3 || uid->selfsigversion>3)
-              {
-                const prefitem_t *prefs = uid->prefs;
-
-                for (j=0; prefs && prefs[j].type; j++)
-                  {
-                    if (j)
-                      putchar (' ');
-                    printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
-                            prefs[j].type == PREFTYPE_HASH  ? 'H' :
-                            prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
-                            prefs[j].value);
-                  }
-                if (uid->flags.mdc)
-                  printf (",mdc");
-                if (!uid->flags.ks_modify)
-                  printf (",no-ks-modify");
-              }
-            putchar (':');
-            /* flags */
-            printf ("%d,", i);
-            if (uid->is_primary)
-              putchar ('p');
-            if (uid->is_revoked)
-              putchar ('r');
-            if (uid->is_expired)
-              putchar ('e');
-            if ((node->flag & NODFLG_SELUID))
-              putchar ('s');
-            if ((node->flag & NODFLG_MARK_A))
-              putchar ('m');
-            putchar (':');
-            putchar('\n');
-          }
-      }
+         if (uid->attrib_data)
+           es_fprintf (fp, "%u %lu", uid->numattribs, uid->attrib_len);
+         else
+           es_write_sanitized (fp, uid->name, uid->len, ":", NULL);
+
+         es_putc (':', fp);
+         /* signature class */
+         es_putc (':', fp);
+         /* capabilities */
+         es_putc (':', fp);
+         /* preferences */
+         if (pk_version > 3 || uid->selfsigversion > 3)
+           {
+             const prefitem_t *prefs = uid->prefs;
+
+             for (j = 0; prefs && prefs[j].type; j++)
+               {
+                 if (j)
+                   es_putc (' ', fp);
+                 es_fprintf (fp,
+                              "%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
+                              prefs[j].type == PREFTYPE_HASH ? 'H' :
+                              prefs[j].type == PREFTYPE_ZIP ? 'Z' : '?',
+                              prefs[j].value);
+               }
+             if (uid->flags.mdc)
+               es_fputs (",mdc", fp);
+             if (!uid->flags.ks_modify)
+               es_fputs (",no-ks-modify", fp);
+           }
+         es_putc (':', fp);
+         /* flags */
+         es_fprintf (fp, "%d,", i);
+         if (uid->is_primary)
+           es_putc ('p', fp);
+         if (uid->is_revoked)
+           es_putc ('r', fp);
+         if (uid->is_expired)
+           es_putc ('e', fp);
+         if ((node->flag & NODFLG_SELUID))
+           es_putc ('s', fp);
+         if ((node->flag & NODFLG_MARK_A))
+           es_putc ('m', fp);
+         es_putc (':', fp);
+         es_putc ('\n', fp);
+       }
+    }
 }
 
+
 static void
-show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
+show_names (estream_t fp,
+            KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
+           int with_prefs)
 {
   KBNODE node;
-  int i=0;
+  int i = 0;
 
-  for( node = keyblock; node; node = node->next )
+  for (node = keyblock; node; node = node->next)
     {
-      if( node->pkt->pkttype == PKT_USER_ID
-         && !is_deleted_kbnode(node))
+      if (node->pkt->pkttype == PKT_USER_ID && !is_deleted_kbnode (node))
        {
          PKT_user_id *uid = node->pkt->pkt.user_id;
          ++i;
-         if(!flag || (flag && (node->flag & flag)))
+         if (!flag || (flag && (node->flag & flag)))
            {
-             if(!(flag&NODFLG_MARK_A) && pk)
-               tty_printf("%s ",uid_trust_string_fixed(pk,uid));
-
-             if( flag & NODFLG_MARK_A )
-               tty_printf("     ");
-             else if( node->flag & NODFLG_SELUID )
-               tty_printf("(%d)* ", i);
-             else if( uid->is_primary )
-               tty_printf("(%d). ", i);
+             if (!(flag & NODFLG_MARK_A) && pk)
+               tty_fprintf (fp, "%s ", uid_trust_string_fixed (pk, uid));
+
+             if (flag & NODFLG_MARK_A)
+               tty_fprintf (fp, "     ");
+             else if (node->flag & NODFLG_SELUID)
+               tty_fprintf (fp, "(%d)* ", i);
+             else if (uid->is_primary)
+               tty_fprintf (fp, "(%d). ", i);
              else
-               tty_printf("(%d)  ", i);
-             tty_print_utf8_string( uid->name, uid->len );
-             tty_printf("\n");
-             if(with_prefs && pk)
+               tty_fprintf (fp, "(%d)  ", i);
+             tty_print_utf8_string2 (fp, uid->name, uid->len, 0);
+             tty_fprintf (fp, "\n");
+             if (with_prefs && pk)
                {
-                 if(pk->version>3 || uid->selfsigversion>3)
+                 if (pk->version > 3 || uid->selfsigversion > 3)
                    {
-                     PKT_signature *selfsig=NULL;
+                     PKT_signature *selfsig = NULL;
                      KBNODE signode;
 
-                     for(signode=node->next;
-                         signode && signode->pkt->pkttype==PKT_SIGNATURE;
-                         signode=signode->next)
+                     for (signode = node->next;
+                          signode && signode->pkt->pkttype == PKT_SIGNATURE;
+                          signode = signode->next)
                        {
-                         if(signode->pkt->pkt.signature->
-                            flags.chosen_selfsig)
+                         if (signode->pkt->pkt.signature->
+                             flags.chosen_selfsig)
                            {
-                             selfsig=signode->pkt->pkt.signature;
+                             selfsig = signode->pkt->pkt.signature;
                              break;
                            }
                        }
@@ -2765,197 +2821,213 @@ show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
                      show_prefs (uid, selfsig, with_prefs == 2);
                    }
                  else
-                   tty_printf(_("There are no preferences on a"
-                                " PGP 2.x-style user ID.\n"));
+                   tty_fprintf (fp, _("There are no preferences on a"
+                                       " PGP 2.x-style user ID.\n"));
                }
            }
        }
     }
 }
 
-/****************
- * Display the key a the user ids, if only_marked is true, do only
- * so for user ids with mark A flag set and dont display the index number
+
+/*
+ * Display the key a the user ids, if only_marked is true, do only so
+ * for user ids with mark A flag set and do not display the index
+ * number.  If FP is not NULL print to the given stream and not to the
+ * tty (ignored in with-colons mode).
  */
 static void
-show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
-                        int with_fpr, int with_subkeys, int with_prefs )
+show_key_with_all_names (estream_t fp,
+                         KBNODE keyblock, int only_marked, int with_revoker,
+                        int with_fpr, int with_subkeys, int with_prefs,
+                         int nowarn)
 {
-    KBNODE node;
-    int i;
-    int do_warn = 0;
-    PKT_public_key *primary=NULL;
+  KBNODE node;
+  int i;
+  int do_warn = 0;
+  PKT_public_key *primary = NULL;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
-    if (opt.with_colons)
-      {
-        show_key_with_all_names_colon (keyblock);
-        return;
-      }
+  if (opt.with_colons)
+    {
+      show_key_with_all_names_colon (fp, keyblock);
+      return;
+    }
 
-    /* the keys */
-    for( node = keyblock; node; node = node->next ) {
-       if( node->pkt->pkttype == PKT_PUBLIC_KEY
-           || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-               && !is_deleted_kbnode(node)) ) {
-           PKT_public_key *pk = node->pkt->pkt.public_key;
-           const char *otrust="err",*trust="err";
-
-           if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
-               /* do it here, so that debug messages don't clutter the
-                * output */
-                static int did_warn = 0;
-
-                trust = get_validity_string (pk, NULL);
-               otrust = get_ownertrust_string (pk);
-
-                /* Show a warning once */
-                if (!did_warn
-                    && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
-                    did_warn = 1;
-                    do_warn = 1;
-                }
+  /* the keys */
+  for (node = keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+         || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+             && !is_deleted_kbnode (node)))
+       {
+         PKT_public_key *pk = node->pkt->pkt.public_key;
+         const char *otrust = "err";
+         const char *trust = "err";
 
-               primary=pk;
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+           {
+             /* do it here, so that debug messages don't clutter the
+              * output */
+             static int did_warn = 0;
+
+             trust = get_validity_string (pk, NULL);
+             otrust = get_ownertrust_string (pk);
+
+             /* Show a warning once */
+             if (!did_warn
+                 && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK))
+               {
+                 did_warn = 1;
+                 do_warn = 1;
+               }
+
+             primary = pk;
            }
 
-           if(pk->is_revoked)
-             {
-               char *user=get_user_id_string_native(pk->revoked.keyid);
-               const char *algo = openpgp_pk_algo_name (pk->revoked.algo);
-               tty_printf (_("The following key was revoked on"
-                              " %s by %s key %s\n"),
-                          revokestr_from_pk(pk),algo?algo:"?",user);
-               xfree(user);
-             }
+         if (pk->flags.revoked)
+           {
+             char *user = get_user_id_string_native (pk->revoked.keyid);
+              tty_fprintf (fp,
+                           _("The following key was revoked on"
+                            " %s by %s key %s\n"),
+                         revokestr_from_pk (pk),
+                          gcry_pk_algo_name (pk->revoked.algo), user);
+             xfree (user);
+           }
 
-           if(with_revoker)
-             {
-               if( !pk->revkey && pk->numrevkeys )
-                 BUG();
-               else
-                 for(i=0;i<pk->numrevkeys;i++)
-                   {
-                     u32 r_keyid[2];
-                     char *user;
-                     const char *algo;
+         if (with_revoker)
+           {
+             if (!pk->revkey && pk->numrevkeys)
+               BUG ();
+             else
+               for (i = 0; i < pk->numrevkeys; i++)
+                 {
+                   u32 r_keyid[2];
+                   char *user;
+                   const char *algo;
 
-                      algo = openpgp_pk_algo_name (pk->revkey[i].algid);
-                     keyid_from_fingerprint(pk->revkey[i].fpr,
-                                            MAX_FINGERPRINT_LEN,r_keyid);
+                   algo = gcry_pk_algo_name (pk->revkey[i].algid);
+                   keyid_from_fingerprint (pk->revkey[i].fpr,
+                                           MAX_FINGERPRINT_LEN, r_keyid);
 
-                     user=get_user_id_string_native(r_keyid);
-                     tty_printf(_("This key may be revoked by %s key %s"),
-                                algo?algo:"?",user);
+                   user = get_user_id_string_native (r_keyid);
+                   tty_fprintf (fp,
+                                 _("This key may be revoked by %s key %s"),
+                                 algo ? algo : "?", user);
 
-                     if(pk->revkey[i].class&0x40)
-                       {
-                         tty_printf(" ");
-                         tty_printf(_("(sensitive)"));
-                       }
+                   if (pk->revkey[i].class & 0x40)
+                     {
+                       tty_fprintf (fp, " ");
+                       tty_fprintf (fp, _("(sensitive)"));
+                     }
+
+                   tty_fprintf (fp, "\n");
+                   xfree (user);
+                 }
+           }
+
+         keyid_from_pk (pk, NULL);
+         tty_fprintf (fp, "%s%c %s/%s",
+                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+                     node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
+                     (node->flag & NODFLG_SELKEY) ? '*' : ' ',
+                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                     keystr (pk->keyid));
+
+          if (opt.legacy_list_mode)
+            tty_fprintf (fp, "  ");
+          else
+            tty_fprintf (fp, "\n     ");
+
+          tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
+         tty_fprintf (fp, "  ");
+         if (pk->flags.revoked)
+           tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
+         else if (pk->has_expired)
+           tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
+         else
+           tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
+         tty_fprintf (fp, "  ");
+         tty_fprintf (fp, _("usage: %s"), usagestr_from_pk (pk, 1));
+         tty_fprintf (fp, "\n");
+
+         if (pk->seckey_info
+              && pk->seckey_info->is_protected
+              && pk->seckey_info->s2k.mode == 1002)
+           {
+             tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
+                           _("card-no: "));
+             if (pk->seckey_info->ivlen == 16
+                 && !memcmp (pk->seckey_info->iv,
+                              "\xD2\x76\x00\x01\x24\x01", 6))
+               {
+                  /* This is an OpenPGP card. */
+                 for (i = 8; i < 14; i++)
+                   {
+                     if (i == 10)
+                       tty_fprintf (fp, " ");
+                     tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
+                   }
+               }
+             else
+               {
+                  /* Unknown card: Print all. */
+                 for (i = 0; i < pk->seckey_info->ivlen; i++)
+                   tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
+               }
+             tty_fprintf (fp, "\n");
+           }
 
-                     tty_printf ("\n");
-                     xfree(user);
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY
+              || node->pkt->pkttype == PKT_SECRET_KEY)
+           {
+             if (opt.trust_model != TM_ALWAYS)
+               {
+                 tty_fprintf (fp, "%*s",
+                               opt.legacy_list_mode?
+                               ((int) keystrlen () + 13):5, "");
+                 /* Ownertrust is only meaningful for the PGP or
+                    classic trust models */
+                 if (opt.trust_model == TM_PGP
+                     || opt.trust_model == TM_CLASSIC)
+                   {
+                     int width = 14 - strlen (otrust);
+                     if (width <= 0)
+                       width = 1;
+                     tty_fprintf (fp, _("trust: %s"), otrust);
+                     tty_fprintf (fp, "%*s", width, "");
                    }
-             }
 
-           keyid_from_pk(pk,NULL);
-           tty_printf("%s%c %4u%c/%s  ",
-                      node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
-                      (node->flag & NODFLG_SELKEY)? '*':' ',
-                      nbits_from_pk( pk ),
-                      pubkey_letter( pk->pubkey_algo ),
-                      keystr(pk->keyid));
-
-           tty_printf(_("created: %s"),datestr_from_pk(pk));
-           tty_printf("  ");
-           if(pk->is_revoked)
-             tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
-           else if(pk->has_expired)
-             tty_printf(_("expired: %s"),expirestr_from_pk(pk));
-           else
-             tty_printf(_("expires: %s"),expirestr_from_pk(pk));
-           tty_printf("  ");
-            tty_printf(_("usage: %s"),usagestr_from_pk(pk));
-           tty_printf("\n");
-
-           if( node->pkt->pkttype == PKT_PUBLIC_KEY )
-             {
-               if(opt.trust_model!=TM_ALWAYS)
-                 {
-                   tty_printf("%*s", (int)keystrlen()+13,"");
-                   /* Ownertrust is only meaningful for the PGP or
-                      classic trust models */
-                   if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
-                     {
-                       int width=14-strlen(otrust);
-                       if(width<=0)
-                         width=1;
-                       tty_printf(_("trust: %s"), otrust);
-                       tty_printf("%*s",width,"");
-                     }
-
-                   tty_printf(_("validity: %s"), trust );
-                   tty_printf("\n");
-                 }
-               if( node->pkt->pkttype == PKT_PUBLIC_KEY
-                   && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
-                 {
-                   tty_printf("*** ");
-                   tty_printf(_("This key has been disabled"));
-                   tty_printf("\n");
-                 }
-             }
+                 tty_fprintf (fp, _("validity: %s"), trust);
+                 tty_fprintf (fp, "\n");
+               }
+             if (node->pkt->pkttype == PKT_PUBLIC_KEY
+                 && (get_ownertrust (pk) & TRUST_FLAG_DISABLED))
+               {
+                 tty_fprintf (fp, "*** ");
+                 tty_fprintf (fp, _("This key has been disabled"));
+                 tty_fprintf (fp, "\n");
+               }
+           }
 
-           if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
-             {
-               print_fingerprint ( pk, NULL, 2 );
-               tty_printf("\n");
-             }
+         if ((node->pkt->pkttype == PKT_PUBLIC_KEY
+               || node->pkt->pkttype == PKT_SECRET_KEY) && with_fpr)
+           {
+              print_fingerprint (fp, pk, 2);
+             tty_fprintf (fp, "\n");
+           }
        }
-       else if( node->pkt->pkttype == PKT_SECRET_KEY
-           || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
-         {
-           PKT_secret_key *sk = node->pkt->pkt.secret_key;
-           tty_printf("%s%c %4u%c/%s  ",
-                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
-                      (node->flag & NODFLG_SELKEY)? '*':' ',
-                      nbits_from_sk( sk ),
-                      pubkey_letter( sk->pubkey_algo ),
-                      keystr_from_sk(sk));
-           tty_printf(_("created: %s"),datestr_from_sk(sk));
-           tty_printf("  ");
-           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
-           tty_printf("\n");
-            if (sk->is_protected && sk->protect.s2k.mode == 1002)
-              {
-               tty_printf("                     ");
-                tty_printf(_("card-no: "));
-                if (sk->protect.ivlen == 16
-                    && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
-                  { /* This is an OpenPGP card. */
-                    for (i=8; i < 14; i++)
-                      {
-                        if (i == 10)
-                          tty_printf (" ");
-                        tty_printf ("%02X", sk->protect.iv[i]);
-                      }
-                  }
-                else
-                  { /* Something is wrong: Print all. */
-                    for (i=0; i < sk->protect.ivlen; i++)
-                      tty_printf ("%02X", sk->protect.iv[i]);
-                  }
-                tty_printf ("\n");
-              }
-         }
     }
 
-    show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
+  show_names (fp,
+              keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
 
-    if (do_warn)
-        tty_printf (_("Please note that the shown key validity"
-                      " is not necessarily correct\n"
-                      "unless you restart the program.\n"));
+  if (do_warn && !nowarn)
+    tty_fprintf (fp, _("Please note that the shown key validity"
+                       " is not necessarily correct\n"
+                       "unless you restart the program.\n"));
 }
 
 
@@ -2964,127 +3036,116 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
    a secret key.*/
 void
-show_basic_key_info ( KBNODE keyblock )
+show_basic_key_info (KBNODE keyblock)
 {
   KBNODE node;
   int i;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
   /* The primary key */
   for (node = keyblock; node; node = node->next)
     {
-      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
-        {
-          PKT_public_key *pk = node->pkt->pkt.public_key;
-
-          /* Note, we use the same format string as in other show
-             functions to make the translation job easier. */
-          tty_printf ("%s  %4u%c/%s  ",
-                      node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
-                      nbits_from_pk( pk ),
-                      pubkey_letter( pk->pubkey_algo ),
-                      keystr_from_pk(pk));
-         tty_printf(_("created: %s"),datestr_from_pk(pk));
-         tty_printf("  ");
-         tty_printf(_("expires: %s"),expirestr_from_pk(pk));
-          tty_printf("\n");
-          print_fingerprint ( pk, NULL, 3 );
-          tty_printf("\n");
-       }
-      else if (node->pkt->pkttype == PKT_SECRET_KEY)
-        {
-          PKT_secret_key *sk = node->pkt->pkt.secret_key;
-          tty_printf("%s  %4u%c/%s",
-                     node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
-                     nbits_from_sk( sk ),
-                     pubkey_letter( sk->pubkey_algo ),
-                     keystr_from_sk(sk));
-         tty_printf(_("created: %s"),datestr_from_sk(sk));
-         tty_printf("  ");
-         tty_printf(_("expires: %s"),expirestr_from_sk(sk));
-          tty_printf("\n");
-          print_fingerprint (NULL, sk, 3 );
-          tty_printf("\n");
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+          || node->pkt->pkttype == PKT_SECRET_KEY)
+       {
+         PKT_public_key *pk = node->pkt->pkt.public_key;
+
+         /* Note, we use the same format string as in other show
+            functions to make the translation job easier. */
+         tty_printf ("%s  %s/%s  ",
+                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+                     node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" :"ssb",
+                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                     keystr_from_pk (pk));
+         tty_printf (_("created: %s"), datestr_from_pk (pk));
+         tty_printf ("  ");
+         tty_printf (_("expires: %s"), expirestr_from_pk (pk));
+         tty_printf ("\n");
+         print_fingerprint (NULL, pk, 3);
+         tty_printf ("\n");
        }
     }
 
   /* The user IDs. */
-  for (i=0, node = keyblock; node; node = node->next)
+  for (i = 0, node = keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_USER_ID)
-        {
-          PKT_user_id *uid = node->pkt->pkt.user_id;
-          ++i;
-
-          tty_printf ("     ");
-          if (uid->is_revoked)
-            tty_printf("[%s] ",_("revoked"));
-          else if ( uid->is_expired )
-            tty_printf("[%s] ",_("expired"));
-          tty_print_utf8_string (uid->name, uid->len);
-          tty_printf ("\n");
-        }
+       {
+         PKT_user_id *uid = node->pkt->pkt.user_id;
+         ++i;
+
+         tty_printf ("     ");
+         if (uid->is_revoked)
+           tty_printf ("[%s] ", _("revoked"));
+         else if (uid->is_expired)
+           tty_printf ("[%s] ", _("expired"));
+         tty_print_utf8_string (uid->name, uid->len);
+         tty_printf ("\n");
+       }
     }
 }
 
 static void
-show_key_and_fingerprint( KBNODE keyblock )
+show_key_and_fingerprint (KBNODE keyblock)
 {
   KBNODE node;
   PKT_public_key *pk = NULL;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
-  for( node = keyblock; node; node = node->next )
+  for (node = keyblock; node; node = node->next)
     {
-      if( node->pkt->pkttype == PKT_PUBLIC_KEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
          pk = node->pkt->pkt.public_key;
-         tty_printf("pub   %4u%c/%s %s ",
-                    nbits_from_pk( pk ),
-                    pubkey_letter( pk->pubkey_algo ),
-                    keystr_from_pk(pk),
-                    datestr_from_pk(pk) );
+         tty_printf ("pub   %s/%s %s ",
+                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                      keystr_from_pk(pk),
+                      datestr_from_pk (pk));
        }
-      else if( node->pkt->pkttype == PKT_USER_ID )
+      else if (node->pkt->pkttype == PKT_USER_ID)
        {
          PKT_user_id *uid = node->pkt->pkt.user_id;
-         tty_print_utf8_string( uid->name, uid->len );
+         tty_print_utf8_string (uid->name, uid->len);
          break;
        }
     }
-  tty_printf("\n");
-  if( pk )
-    print_fingerprint( pk, NULL, 2 );
+  tty_printf ("\n");
+  if (pk)
+    print_fingerprint (NULL, pk, 2);
 }
 
 
 /* Show a warning if no uids on the key have the primary uid flag
    set. */
 static void
-no_primary_warning(KBNODE keyblock)
+no_primary_warning (KBNODE keyblock)
 {
   KBNODE node;
-  int have_primary=0,uid_count=0;
+  int have_primary = 0, uid_count = 0;
 
   /* TODO: if we ever start behaving differently with a primary or
      non-primary attribute ID, we will need to check for attributes
      here as well. */
 
-  for(node=keyblock; node; node = node->next)
+  for (node = keyblock; node; node = node->next)
     {
-      if(node->pkt->pkttype==PKT_USER_ID
-        && node->pkt->pkt.user_id->attrib_data==NULL)
+      if (node->pkt->pkttype == PKT_USER_ID
+         && node->pkt->pkt.user_id->attrib_data == NULL)
        {
          uid_count++;
 
-         if(node->pkt->pkt.user_id->is_primary==2)
+         if (node->pkt->pkt.user_id->is_primary == 2)
            {
-             have_primary=1;
+             have_primary = 1;
              break;
            }
        }
     }
 
-  if(uid_count>1 && !have_primary)
-    log_info(_("WARNING: no user ID has been marked as primary.  This command"
+  if (uid_count > 1 && !have_primary)
+    log_info (_
+             ("WARNING: no user ID has been marked as primary.  This command"
               " may\n              cause a different user ID to become"
               " the assumed primary.\n"));
 }
@@ -3105,13 +3166,19 @@ subkey_expire_warning (kbnode_t keyblock)
 
   for (node = keyblock; node; node = node->next)
     {
+      /* if (node->pkt->pkttype == PKT_PUBLIC_KEY) */
+      /*   { */
+      /*     pk = node->pkt->pkt.public_key; */
+      /*     mainexpire = pk->expiredate; */
+      /*   } */
+
       if (node->pkt->pkttype != PKT_PUBLIC_SUBKEY)
         continue;
       pk = node->pkt->pkt.public_key;
 
-      if (!pk->is_valid)
+      if (!pk->flags.valid)
         continue;
-      if (pk->is_revoked)
+      if (pk->flags.revoked)
         continue;
       if (pk->timestamp > curtime)
         continue; /* Ignore future keys.  */
@@ -3136,50 +3203,41 @@ subkey_expire_warning (kbnode_t keyblock)
 }
 
 
-/****************
- * Ask for a new user id, do the selfsignature and put it into
- * both keyblocks.
+/*
+ * Ask for a new user id, add the self-signature and update the keyblock.
  * Return true if there is a new user id
  */
 static int
-menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
-            int photo, const char *photo_name)
+menu_adduid (KBNODE pub_keyblock, int photo, const char *photo_name)
 {
-    PKT_user_id *uid;
-    PKT_public_key *pk=NULL;
-    PKT_secret_key *sk=NULL;
-    PKT_signature *sig=NULL;
-    PACKET *pkt;
-    KBNODE node;
-    KBNODE pub_where=NULL, sec_where=NULL;
-    int rc;
-
-    for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
-       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
-           pk = node->pkt->pkt.public_key;
-       else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-           break;
-    }
-    if( !node ) /* no subkey */
-       pub_where = NULL;
-    for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
-       if( node->pkt->pkttype == PKT_SECRET_KEY )
-           sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-       else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
-           break;
+  PKT_user_id *uid;
+  PKT_public_key *pk = NULL;
+  PKT_signature *sig = NULL;
+  PACKET *pkt;
+  KBNODE node;
+  KBNODE pub_where = NULL;
+  gpg_error_t err;
+
+  for (node = pub_keyblock; node; pub_where = node, node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+       pk = node->pkt->pkt.public_key;
+      else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       break;
     }
-    if( !node ) /* no subkey */
-       sec_where = NULL;
-    assert(pk && sk);
+  if (!node) /* No subkey.  */
+    pub_where = NULL;
+  assert (pk);
 
-    if(photo) {
-      int hasattrib=0;
+  if (photo)
+    {
+      int hasattrib = 0;
 
-      for( node = pub_keyblock; node; node = node->next )
-       ifnode->pkt->pkttype == PKT_USER_ID &&
-           node->pkt->pkt.user_id->attrib_data!=NULL)
+      for (node = pub_keyblock; node; node = node->next)
+       if (node->pkt->pkttype == PKT_USER_ID &&
+           node->pkt->pkt.user_id->attrib_data != NULL)
          {
-           hasattrib=1;
+           hasattrib = 1;
            break;
          }
 
@@ -3188,822 +3246,675 @@ menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
          anymore.  Also, PGP may not expect a photo on a v3 key.
          Don't bother to ask this if the key already has a photo - any
          damage has already been done at that point. -dms */
-      if(pk->version==3 && !hasattrib)
+      if (pk->version == 3 && !hasattrib)
        {
-         if(opt.expert)
+         if (opt.expert)
            {
-             tty_printf(_("WARNING: This is a PGP2-style key.  "
-                          "Adding a photo ID may cause some versions\n"
-                          "         of PGP to reject this key.\n"));
+             tty_printf (_("WARNING: This is a PGP2-style key.  "
+                           "Adding a photo ID may cause some versions\n"
+                           "         of PGP to reject this key.\n"));
 
-             if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
-                                       _("Are you sure you still want "
-                                         "to add it? (y/N) ")))
+             if (!cpr_get_answer_is_yes ("keyedit.v3_photo.okay",
+                                         _("Are you sure you still want "
+                                           "to add it? (y/N) ")))
                return 0;
            }
          else
            {
-             tty_printf(_("You may not add a photo ID to "
-                          "a PGP2-style key.\n"));
+             tty_printf (_("You may not add a photo ID to "
+                           "a PGP2-style key.\n"));
              return 0;
            }
        }
 
-      uid = generate_photo_id(pk,photo_name);
-    } else
-      uid = generate_user_id (pub_keyblock);
-    if( !uid )
-       return 0;
+      uid = generate_photo_id (pk, photo_name);
+    }
+  else
+    uid = generate_user_id (pub_keyblock);
+  if (!uid)
+    return 0;
 
-    rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
-                            keygen_add_std_prefs, pk );
-    free_secret_key( sk );
-    if( rc ) {
-       log_error("signing failed: %s\n", g10_errstr(rc) );
-       free_user_id(uid);
-       return 0;
+  err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0,
+                            keygen_add_std_prefs, pk, NULL);
+  if (err)
+    {
+      log_error ("signing failed: %s\n", g10_errstr (err));
+      free_user_id (uid);
+      return 0;
     }
 
-    /* insert/append to secret keyblock */
-    pkt = xmalloc_clear( sizeof *pkt );
-    pkt->pkttype = PKT_USER_ID;
-    pkt->pkt.user_id = scopy_user_id(uid);
-    node = new_kbnode(pkt);
-    if( sec_where )
-       insert_kbnode( sec_where, node, 0 );
-    else
-       add_kbnode( sec_keyblock, node );
-    pkt = xmalloc_clear( sizeof *pkt );
-    pkt->pkttype = PKT_SIGNATURE;
-    pkt->pkt.signature = copy_signature(NULL, sig);
-    if( sec_where )
-       insert_kbnode( node, new_kbnode(pkt), 0 );
-    else
-       add_kbnode( sec_keyblock, new_kbnode(pkt) );
-    /* insert/append to public keyblock */
-    pkt = xmalloc_clear( sizeof *pkt );
-    pkt->pkttype = PKT_USER_ID;
-    pkt->pkt.user_id = uid;
-    node = new_kbnode(pkt);
-    if( pub_where )
-       insert_kbnode( pub_where, node, 0 );
-    else
-       add_kbnode( pub_keyblock, node );
-    pkt = xmalloc_clear( sizeof *pkt );
-    pkt->pkttype = PKT_SIGNATURE;
-    pkt->pkt.signature = copy_signature(NULL, sig);
-    if( pub_where )
-       insert_kbnode( node, new_kbnode(pkt), 0 );
-    else
-       add_kbnode( pub_keyblock, new_kbnode(pkt) );
-    return 1;
+  /* Insert/append to public keyblock */
+  pkt = xmalloc_clear (sizeof *pkt);
+  pkt->pkttype = PKT_USER_ID;
+  pkt->pkt.user_id = uid;
+  node = new_kbnode (pkt);
+  if (pub_where)
+    insert_kbnode (pub_where, node, 0);
+  else
+    add_kbnode (pub_keyblock, node);
+  pkt = xmalloc_clear (sizeof *pkt);
+  pkt->pkttype = PKT_SIGNATURE;
+  pkt->pkt.signature = copy_signature (NULL, sig);
+  if (pub_where)
+    insert_kbnode (node, new_kbnode (pkt), 0);
+  else
+    add_kbnode (pub_keyblock, new_kbnode (pkt));
+  return 1;
 }
 
 
-/****************
- * Remove all selected userids from the keyrings
+/*
+ * Remove all selected userids from the keyring
  */
 static void
-menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_deluid (KBNODE pub_keyblock)
 {
-    KBNODE node;
-    int selected=0;
-
-    for( node = pub_keyblock; node; node = node->next ) {
-       if( node->pkt->pkttype == PKT_USER_ID ) {
-           selected = node->flag & NODFLG_SELUID;
-           if( selected ) {
-               /* Only cause a trust update if we delete a
-                   non-revoked user id */
-               if(!node->pkt->pkt.user_id->is_revoked)
-                 update_trust=1;
-               delete_kbnode( node );
-               if( sec_keyblock ) {
-                   KBNODE snode;
-                   int s_selected = 0;
-                   PKT_user_id *uid = node->pkt->pkt.user_id;
-                   for( snode = sec_keyblock; snode; snode = snode->next ) {
-                       if( snode->pkt->pkttype == PKT_USER_ID ) {
-                           PKT_user_id *suid = snode->pkt->pkt.user_id;
-
-                           s_selected =
-                               (uid->len == suid->len
-                                && !memcmp( uid->name, suid->name, uid->len));
-                           if( s_selected )
-                               delete_kbnode( snode );
-                       }
-                       else if( s_selected
-                                && snode->pkt->pkttype == PKT_SIGNATURE )
-                           delete_kbnode( snode );
-                       else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
-                           s_selected = 0;
-                   }
-               }
+  KBNODE node;
+  int selected = 0;
+
+  for (node = pub_keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         selected = node->flag & NODFLG_SELUID;
+         if (selected)
+           {
+             /* Only cause a trust update if we delete a
+                non-revoked user id */
+             if (!node->pkt->pkt.user_id->is_revoked)
+               update_trust = 1;
+             delete_kbnode (node);
            }
        }
-       else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
-           delete_kbnode( node );
-       else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-           selected = 0;
+      else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
+       delete_kbnode (node);
+      else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       selected = 0;
     }
-    commit_kbnode( &pub_keyblock );
-    if( sec_keyblock )
-       commit_kbnode( &sec_keyblock );
+  commit_kbnode (&pub_keyblock);
 }
 
 
 static int
-menu_delsig( KBNODE pub_keyblock )
+menu_delsig (KBNODE pub_keyblock)
 {
-    KBNODE node;
-    PKT_user_id *uid = NULL;
-    int changed=0;
+  KBNODE node;
+  PKT_user_id *uid = NULL;
+  int changed = 0;
 
-    for( node = pub_keyblock; node; node = node->next ) {
-       if( node->pkt->pkttype == PKT_USER_ID ) {
-           uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
+  for (node = pub_keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         uid = (node->flag & NODFLG_SELUID) ? node->pkt->pkt.user_id : NULL;
        }
-       else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
-          int okay, valid, selfsig, inv_sig, no_key, other_err;
-
-           tty_printf("uid  ");
-           tty_print_utf8_string( uid->name, uid->len );
-           tty_printf("\n");
-
-           okay = inv_sig = no_key = other_err = 0;
-           if(opt.with_colons)
-             valid = print_and_check_one_sig_colon( pub_keyblock, node,
-                                              &inv_sig, &no_key, &other_err,
-                                              &selfsig, 1 );
-           else
-             valid = print_and_check_one_sig( pub_keyblock, node,
-                                              &inv_sig, &no_key, &other_err,
-                                              &selfsig, 1 );
-
-          if( valid ) {
-              okay = cpr_get_answer_yes_no_quit(
-                  "keyedit.delsig.valid",
-                  _("Delete this good signature? (y/N/q)"));
-
-              /* Only update trust if we delete a good signature.
-                  The other two cases do not affect trust. */
-              if(okay)
-                update_trust=1;
-          }
-          else if( inv_sig || other_err )
-              okay = cpr_get_answer_yes_no_quit(
-                  "keyedit.delsig.invalid",
-                  _("Delete this invalid signature? (y/N/q)"));
-          else if( no_key )
-              okay = cpr_get_answer_yes_no_quit(
-                  "keyedit.delsig.unknown",
-                  _("Delete this unknown signature? (y/N/q)"));
-
-           if( okay == -1 )
-               break;
-          if( okay && selfsig && !cpr_get_answer_is_yes(
-                              "keyedit.delsig.selfsig",
-                             _("Really delete this self-signature? (y/N)") ))
-               okay = 0;
-           if( okay ) {
-               delete_kbnode( node );
-               changed++;
+      else if (uid && node->pkt->pkttype == PKT_SIGNATURE)
+       {
+         int okay, valid, selfsig, inv_sig, no_key, other_err;
+
+         tty_printf ("uid  ");
+         tty_print_utf8_string (uid->name, uid->len);
+         tty_printf ("\n");
+
+         okay = inv_sig = no_key = other_err = 0;
+         if (opt.with_colons)
+           valid = print_and_check_one_sig_colon (pub_keyblock, node,
+                                                  &inv_sig, &no_key,
+                                                  &other_err, &selfsig, 1);
+         else
+           valid = print_and_check_one_sig (pub_keyblock, node,
+                                            &inv_sig, &no_key, &other_err,
+                                            &selfsig, 1);
+
+         if (valid)
+           {
+             okay = cpr_get_answer_yes_no_quit
+                ("keyedit.delsig.valid",
+                 _("Delete this good signature? (y/N/q)"));
+
+             /* Only update trust if we delete a good signature.
+                The other two cases do not affect trust. */
+             if (okay)
+               update_trust = 1;
+           }
+         else if (inv_sig || other_err)
+           okay = cpr_get_answer_yes_no_quit
+              ("keyedit.delsig.invalid",
+               _("Delete this invalid signature? (y/N/q)"));
+         else if (no_key)
+           okay = cpr_get_answer_yes_no_quit
+              ("keyedit.delsig.unknown",
+               _("Delete this unknown signature? (y/N/q)"));
+
+         if (okay == -1)
+           break;
+         if (okay && selfsig
+             && !cpr_get_answer_is_yes
+              ("keyedit.delsig.selfsig",
+               _("Really delete this self-signature? (y/N)")))
+           okay = 0;
+         if (okay)
+           {
+             delete_kbnode (node);
+             changed++;
            }
 
        }
-       else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-           uid = NULL;
+      else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       uid = NULL;
     }
 
-    if( changed ) {
-       commit_kbnode( &pub_keyblock );
-       tty_printf( changed == 1? _("Deleted %d signature.\n")
-                               : _("Deleted %d signatures.\n"), changed );
+  if (changed)
+    {
+      commit_kbnode (&pub_keyblock);
+      tty_printf (changed == 1 ? _("Deleted %d signature.\n")
+                 : _("Deleted %d signatures.\n"), changed);
     }
-    else
-       tty_printf( _("Nothing deleted.\n") );
+  else
+    tty_printf (_("Nothing deleted.\n"));
 
-    return changed;
+  return changed;
 }
 
+
 static int
-menu_clean(KBNODE keyblock,int self_only)
+menu_clean (KBNODE keyblock, int self_only)
 {
   KBNODE uidnode;
-  int modified=0,select_all=!count_selected_uids(keyblock);
+  int modified = 0, select_all = !count_selected_uids (keyblock);
 
-  for(uidnode=keyblock->next;
-      uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
-      uidnode=uidnode->next)
+  for (uidnode = keyblock->next;
+       uidnode && uidnode->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+       uidnode = uidnode->next)
     {
-      if(uidnode->pkt->pkttype==PKT_USER_ID
-        && (uidnode->flag&NODFLG_SELUID || select_all))
+      if (uidnode->pkt->pkttype == PKT_USER_ID
+         && (uidnode->flag & NODFLG_SELUID || select_all))
        {
-         int uids=0,sigs=0;
-         char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
-                                   uidnode->pkt->pkt.user_id->len,
-                                   0);
-
-         clean_one_uid(keyblock,uidnode,opt.verbose,self_only,&uids,&sigs);
-         if(uids)
+         int uids = 0, sigs = 0;
+         char *user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
+                                      uidnode->pkt->pkt.user_id->len,
+                                      0);
+
+         clean_one_uid (keyblock, uidnode, opt.verbose, self_only, &uids,
+                        &sigs);
+         if (uids)
            {
              const char *reason;
 
-             if(uidnode->pkt->pkt.user_id->is_revoked)
-               reason=_("revoked");
-             else if(uidnode->pkt->pkt.user_id->is_expired)
-               reason=_("expired");
+             if (uidnode->pkt->pkt.user_id->is_revoked)
+               reason = _("revoked");
+             else if (uidnode->pkt->pkt.user_id->is_expired)
+               reason = _("expired");
              else
-               reason=_("invalid");
+               reason = _("invalid");
 
              tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason);
 
-             modified=1;
+             modified = 1;
            }
-         else if(sigs)
+         else if (sigs)
            {
-             tty_printf(sigs==1?
-                        _("User ID \"%s\": %d signature removed\n") :
-                        _("User ID \"%s\": %d signatures removed\n"),
-                        user,sigs);
+             tty_printf (sigs == 1 ?
+                         _("User ID \"%s\": %d signature removed\n") :
+                         _("User ID \"%s\": %d signatures removed\n"),
+                         user, sigs);
 
-             modified=1;
+             modified = 1;
            }
          else
            {
-             tty_printf (self_only==1?
-                          _("User ID \"%s\": already minimized\n") :
-                          _("User ID \"%s\": already clean\n"),
-                          user);
+             tty_printf (self_only == 1 ?
+                         _("User ID \"%s\": already minimized\n") :
+                         _("User ID \"%s\": already clean\n"), user);
            }
 
-         xfree(user);
+         xfree (user);
        }
     }
 
   return modified;
 }
 
-/****************
+
+/*
  * Remove some of the secondary keys
  */
 static void
-menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_delkey (KBNODE pub_keyblock)
 {
-    KBNODE node;
-    int selected=0;
-
-    for( node = pub_keyblock; node; node = node->next ) {
-       if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-           selected = node->flag & NODFLG_SELKEY;
-           if( selected ) {
-               delete_kbnode( node );
-               if( sec_keyblock ) {
-                   KBNODE snode;
-                   int s_selected = 0;
-                   u32 ki[2];
-
-                   keyid_from_pk( node->pkt->pkt.public_key, ki );
-                   for( snode = sec_keyblock; snode; snode = snode->next ) {
-                       if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-                           u32 ki2[2];
-
-                           keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
-                           s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
-                           if( s_selected )
-                               delete_kbnode( snode );
-                       }
-                       else if( s_selected
-                                && snode->pkt->pkttype == PKT_SIGNATURE )
-                           delete_kbnode( snode );
-                       else
-                           s_selected = 0;
-                   }
-               }
-           }
+  KBNODE node;
+  int selected = 0;
+
+  for (node = pub_keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       {
+         selected = node->flag & NODFLG_SELKEY;
+         if (selected)
+            delete_kbnode (node);
        }
-       else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
-           delete_kbnode( node );
-       else
-           selected = 0;
+      else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
+       delete_kbnode (node);
+      else
+       selected = 0;
     }
-    commit_kbnode( &pub_keyblock );
-    if( sec_keyblock )
-       commit_kbnode( &sec_keyblock );
+  commit_kbnode (&pub_keyblock);
 
-    /* No need to set update_trust here since signing keys are no
-       longer used to certify other keys, so there is no change in
-       trust when revoking/removing them */
+  /* No need to set update_trust here since signing keys are no
+     longer used to certify other keys, so there is no change in
+     trust when revoking/removing them.   */
 }
 
 
-/****************
- * Ask for a new revoker, do the selfsignature and put it into
- * both keyblocks.
- * Return true if there is a new revoker
+/*
+ * Ask for a new revoker, create the self-signature and put it into
+ * the keyblock.  Returns true if there is a new revoker.
  */
 static int
-menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
+menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive)
 {
-  PKT_public_key *pk=NULL,*revoker_pk=NULL;
-  PKT_secret_key *sk=NULL;
-  PKT_signature *sig=NULL;
+  PKT_public_key *pk = NULL;
+  PKT_public_key *revoker_pk = NULL;
+  PKT_signature *sig = NULL;
   PACKET *pkt;
   struct revocation_key revkey;
   size_t fprlen;
   int rc;
 
-  assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-  assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
+  assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
 
-  pk=pub_keyblock->pkt->pkt.public_key;
+  pk = pub_keyblock->pkt->pkt.public_key;
 
-  if(pk->numrevkeys==0 && pk->version==3)
+  if (pk->numrevkeys == 0 && pk->version == 3)
     {
       /* It is legal but bad for compatibility to add a revoker to a
          v3 key as it means that PGP2 will not be able to use that key
          anymore.  Also, PGP may not expect a revoker on a v3 key.
          Don't bother to ask this if the key already has a revoker -
          any damage has already been done at that point. -dms */
-      if(opt.expert)
+      if (opt.expert)
        {
-         tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
-                      "Adding a designated revoker may cause\n"
-                      "         some versions of PGP to reject this key.\n"));
+         tty_printf (_("WARNING: This is a PGP 2.x-style key.  "
+                       "Adding a designated revoker may cause\n"
+                       "         some versions of PGP to reject this key.\n"));
 
-         if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
-                                   _("Are you sure you still want "
-                                     "to add it? (y/N) ")))
+         if (!cpr_get_answer_is_yes ("keyedit.v3_revoker.okay",
+                                     _("Are you sure you still want "
+                                       "to add it? (y/N) ")))
            return 0;
        }
       else
        {
-         tty_printf(_("You may not add a designated revoker to "
-                      "a PGP 2.x-style key.\n"));
+         tty_printf (_("You may not add a designated revoker to "
+                       "a PGP 2.x-style key.\n"));
          return 0;
        }
     }
 
-  sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
-
-  for(;;)
+  for (;;)
     {
       char *answer;
 
-      if(revoker_pk)
-       free_public_key(revoker_pk);
+      free_public_key (revoker_pk);
+      revoker_pk = xmalloc_clear (sizeof (*revoker_pk));
 
-      revoker_pk=xmalloc_clear(sizeof(*revoker_pk));
+      tty_printf ("\n");
 
-      tty_printf("\n");
-
-      answer=cpr_get_utf8("keyedit.add_revoker",
-                         _("Enter the user ID of the designated revoker: "));
-      if(answer[0]=='\0' || answer[0]=='\004')
+      answer = cpr_get_utf8
+        ("keyedit.add_revoker",
+         _("Enter the user ID of the designated revoker: "));
+      if (answer[0] == '\0' || answer[0] == CONTROL_D)
        {
-         xfree(answer);
+         xfree (answer);
          goto fail;
        }
 
       /* Note that I'm requesting CERT here, which usually implies
-        primary keys only, but some casual testing shows that PGP and
-        GnuPG both can handle a designated revokation from a
-        subkey. */
-      revoker_pk->req_usage=PUBKEY_USAGE_CERT;
-      rc=get_pubkey_byname (NULL, revoker_pk,answer,NULL,NULL,1, 1);
-      if(rc)
+         primary keys only, but some casual testing shows that PGP and
+         GnuPG both can handle a designated revocation from a subkey. */
+      revoker_pk->req_usage = PUBKEY_USAGE_CERT;
+      rc = get_pubkey_byname (ctrl, NULL, revoker_pk, answer, NULL, NULL, 1, 1);
+      if (rc)
        {
-         log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
-         xfree(answer);
+         log_error (_("key \"%s\" not found: %s\n"), answer,
+                    g10_errstr (rc));
+         xfree (answer);
          continue;
        }
 
-      xfree(answer);
+      xfree (answer);
 
-      fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
-      if(fprlen!=20)
+      fingerprint_from_pk (revoker_pk, revkey.fpr, &fprlen);
+      if (fprlen != 20)
        {
-         log_error(_("cannot appoint a PGP 2.x style key as a "
-                     "designated revoker\n"));
+         log_error (_("cannot appoint a PGP 2.x style key as a "
+                      "designated revoker\n"));
          continue;
        }
 
-      revkey.class=0x80;
-      if(sensitive)
-       revkey.class|=0x40;
-      revkey.algid=revoker_pk->pubkey_algo;
+      revkey.class = 0x80;
+      if (sensitive)
+       revkey.class |= 0x40;
+      revkey.algid = revoker_pk->pubkey_algo;
 
-      if(cmp_public_keys(revoker_pk,pk)==0)
+      if (cmp_public_keys (revoker_pk, pk) == 0)
        {
          /* This actually causes no harm (after all, a key that
             designates itself as a revoker is the same as a
             regular key), but it's easy enough to check. */
-         log_error(_("you cannot appoint a key as its own "
-                     "designated revoker\n"));
+         log_error (_("you cannot appoint a key as its own "
+                      "designated revoker\n"));
 
          continue;
        }
 
-      keyid_from_pk(pk,NULL);
+      keyid_from_pk (pk, NULL);
 
       /* Does this revkey already exist? */
-      if(!pk->revkey && pk->numrevkeys)
-       BUG();
+      if (!pk->revkey && pk->numrevkeys)
+       BUG ();
       else
        {
          int i;
 
-         for(i=0;i<pk->numrevkeys;i++)
+         for (i = 0; i < pk->numrevkeys; i++)
            {
-             if(memcmp(&pk->revkey[i],&revkey,
-                       sizeof(struct revocation_key))==0)
+             if (memcmp (&pk->revkey[i], &revkey,
+                         sizeof (struct revocation_key)) == 0)
                {
                  char buf[50];
 
-                 log_error(_("this key has already been designated "
-                             "as a revoker\n"));
+                 log_error (_("this key has already been designated "
+                              "as a revoker\n"));
 
-                 sprintf(buf,"%08lX%08lX",
-                         (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
-                 write_status_text(STATUS_ALREADY_SIGNED,buf);
+                 sprintf (buf, "%08lX%08lX",
+                          (ulong) pk->keyid[0], (ulong) pk->keyid[1]);
+                 write_status_text (STATUS_ALREADY_SIGNED, buf);
 
                  break;
                }
            }
 
-         if(i<pk->numrevkeys)
+         if (i < pk->numrevkeys)
            continue;
        }
 
-      print_pubkey_info(NULL,revoker_pk);
-      print_fingerprint(revoker_pk,NULL,2);
-      tty_printf("\n");
+      print_pubkey_info (NULL, revoker_pk);
+      print_fingerprint (NULL, revoker_pk, 2);
+      tty_printf ("\n");
 
-      tty_printf(_("WARNING: appointing a key as a designated revoker "
-                  "cannot be undone!\n"));
+      tty_printf (_("WARNING: appointing a key as a designated revoker "
+                   "cannot be undone!\n"));
 
-      tty_printf("\n");
+      tty_printf ("\n");
 
-      if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
-                               _("Are you sure you want to appoint this "
-                                 "key as a designated revoker? (y/N) ")))
+      if (!cpr_get_answer_is_yes ("keyedit.add_revoker.okay",
+                                 _("Are you sure you want to appoint this "
+                                   "key as a designated revoker? (y/N) ")))
        continue;
 
-      free_public_key(revoker_pk);
-      revoker_pk=NULL;
+      free_public_key (revoker_pk);
+      revoker_pk = NULL;
       break;
     }
 
-  /* The 1F signature must be at least v4 to carry the revocation key
-     subpacket. */
-  rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
-                          keygen_add_revkey,&revkey );
-  if( rc )
+  rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 0, 0,
+                          keygen_add_revkey, &revkey, NULL);
+  if (rc)
     {
-      log_error("signing failed: %s\n", g10_errstr(rc) );
+      log_error ("signing failed: %s\n", g10_errstr (rc));
       goto fail;
     }
 
-  free_secret_key(sk);
-  sk=NULL;
-
-  /* insert into secret keyblock */
-  pkt = xmalloc_clear( sizeof *pkt );
-  pkt->pkttype = PKT_SIGNATURE;
-  pkt->pkt.signature = copy_signature(NULL, sig);
-  insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
-
-  /* insert into public keyblock */
-  pkt = xmalloc_clear( sizeof *pkt );
+  /* Insert into public keyblock.  */
+  pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
-  insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
+  insert_kbnode (pub_keyblock, new_kbnode (pkt), PKT_SIGNATURE);
 
   return 1;
 
- fail:
-  if(sk)
-    free_secret_key(sk);
-  if(sig)
-    free_seckey_enc(sig);
-  if(revoker_pk)
-    free_public_key(revoker_pk);
+fail:
+  if (sig)
+    free_seckey_enc (sig);
+  free_public_key (revoker_pk);
 
   return 0;
 }
 
 
 static int
-menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_expire (KBNODE pub_keyblock)
 {
-    int n1, signumber, rc;
-    u32 expiredate;
-    int mainkey=0;
-    PKT_secret_key *sk;    /* copy of the main sk */
-    PKT_public_key *main_pk, *sub_pk;
-    PKT_user_id *uid;
-    KBNODE node;
-    u32 keyid[2];
-
-    if( count_selected_keys( sec_keyblock ) ) {
-       tty_printf(_("Please remove selections from the secret keys.\n"));
-       return 0;
-    }
+  int n1, signumber, rc;
+  u32 expiredate;
+  int mainkey = 0;
+  PKT_public_key *main_pk, *sub_pk;
+  PKT_user_id *uid;
+  KBNODE node;
+  u32 keyid[2];
 
-    n1 = count_selected_keys( pub_keyblock );
-    if( n1 > 1 ) {
-       tty_printf(_("Please select at most one subkey.\n"));
-       return 0;
+  n1 = count_selected_keys (pub_keyblock);
+  if (n1 > 1)
+    {
+      tty_printf (_("Please select at most one subkey.\n"));
+      return 0;
+    }
+  else if (n1)
+    tty_printf (_("Changing expiration time for a subkey.\n"));
+  else
+    {
+      tty_printf (_("Changing expiration time for the primary key.\n"));
+      mainkey = 1;
+      no_primary_warning (pub_keyblock);
     }
-    else if( n1 )
-       tty_printf(_("Changing expiration time for a subkey.\n"));
-    else
-      {
-       tty_printf(_("Changing expiration time for the primary key.\n"));
-       mainkey=1;
-       no_primary_warning(pub_keyblock);
-      }
 
-    expiredate = ask_expiredate();
-    node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-    sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
-    /* Now we can actually change the self signature(s) */
-    main_pk = sub_pk = NULL;
-    uid = NULL;
-    signumber = 0;
-    for( node=pub_keyblock; node; node = node->next ) {
-       if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
-           main_pk = node->pkt->pkt.public_key;
-           keyid_from_pk( main_pk, keyid );
-           main_pk->expiredate = expiredate;
+  expiredate = ask_expiredate ();
+
+  /* Now we can actually change the self-signature(s) */
+  main_pk = sub_pk = NULL;
+  uid = NULL;
+  signumber = 0;
+  for (node = pub_keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+       {
+         main_pk = node->pkt->pkt.public_key;
+         keyid_from_pk (main_pk, keyid);
+         main_pk->expiredate = expiredate;
        }
-       else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-                && (node->flag & NODFLG_SELKEY ) ) {
-           sub_pk = node->pkt->pkt.public_key;
-           sub_pk->expiredate = expiredate;
+      else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+              && (node->flag & NODFLG_SELKEY))
+       {
+         sub_pk = node->pkt->pkt.public_key;
+         sub_pk->expiredate = expiredate;
        }
-       else if( node->pkt->pkttype == PKT_USER_ID )
-           uid = node->pkt->pkt.user_id;
-       else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
-                && ( mainkey || sub_pk ) ) {
-           PKT_signature *sig = node->pkt->pkt.signature;
-           if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-               && ( (mainkey && uid
-                     && uid->created && (sig->sig_class&~3) == 0x10)
-                    || (!mainkey && sig->sig_class == 0x18)  )
-               && sig->flags.chosen_selfsig )
-             {
-               /* this is a selfsignature which is to be replaced */
-               PKT_signature *newsig;
-               PACKET *newpkt;
-               KBNODE sn;
-               int signumber2 = 0;
-
-               signumber++;
-
-               if( (mainkey && main_pk->version < 4)
-                   || (!mainkey && sub_pk->version < 4 ) ) {
-                   log_info(_(
-                       "You can't change the expiration date of a v3 key\n"));
-                   free_secret_key( sk );
-                   return 0;
-               }
+      else if (node->pkt->pkttype == PKT_USER_ID)
+       uid = node->pkt->pkt.user_id;
+      else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
+              && (mainkey || sub_pk))
+       {
+         PKT_signature *sig = node->pkt->pkt.signature;
+         if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+             && ((mainkey && uid
+                  && uid->created && (sig->sig_class & ~3) == 0x10)
+                 || (!mainkey && sig->sig_class == 0x18))
+             && sig->flags.chosen_selfsig)
+           {
+             /* This is a self-signature which is to be replaced.  */
+             PKT_signature *newsig;
+             PACKET *newpkt;
 
-               /* find the corresponding secret self-signature */
-               for( sn=sec_keyblock; sn; sn = sn->next ) {
-                   if( sn->pkt->pkttype == PKT_SIGNATURE ) {
-                       PKT_signature *b = sn->pkt->pkt.signature;
-                       if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
-                           && sig->sig_class == b->sig_class
-                           && ++signumber2 == signumber )
-                           break;
-                   }
-               }
-               if( !sn )
-                   log_info(_("No corresponding signature in secret ring\n"));
+             signumber++;
 
-               if( mainkey )
-                 rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
-                                           sk, keygen_add_key_expire, main_pk);
-               else
-                 rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
-                                           sk, keygen_add_key_expire, sub_pk );
-               if( rc ) {
-                   log_error("make_keysig_packet failed: %s\n",
-                                                   g10_errstr(rc));
-                   free_secret_key( sk );
-                   return 0;
+             if ((mainkey && main_pk->version < 4)
+                 || (!mainkey && sub_pk->version < 4))
+               {
+                 log_info
+                    (_("You can't change the expiration date of a v3 key\n"));
+                 return 0;
                }
-               /* replace the packet */
-               newpkt = xmalloc_clear( sizeof *newpkt );
-               newpkt->pkttype = PKT_SIGNATURE;
-               newpkt->pkt.signature = newsig;
-               free_packet( node->pkt );
-               xfree( node->pkt );
-               node->pkt = newpkt;
-               if( sn ) {
-                   newpkt = xmalloc_clear( sizeof *newpkt );
-                   newpkt->pkttype = PKT_SIGNATURE;
-                   newpkt->pkt.signature = copy_signature( NULL, newsig );
-                   free_packet( sn->pkt );
-                   xfree( sn->pkt );
-                   sn->pkt = newpkt;
+
+             if (mainkey)
+               rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
+                                          main_pk, keygen_add_key_expire,
+                                          main_pk);
+             else
+               rc =
+                 update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
+                                       main_pk, keygen_add_key_expire, sub_pk);
+             if (rc)
+               {
+                 log_error ("make_keysig_packet failed: %s\n",
+                            g10_errstr (rc));
+                 return 0;
                }
-               sub_pk = NULL;
+
+             /* Replace the packet.  */
+             newpkt = xmalloc_clear (sizeof *newpkt);
+             newpkt->pkttype = PKT_SIGNATURE;
+             newpkt->pkt.signature = newsig;
+             free_packet (node->pkt);
+             xfree (node->pkt);
+             node->pkt = newpkt;
+             sub_pk = NULL;
            }
        }
     }
 
-    free_secret_key( sk );
-    update_trust=1;
-    return 1;
+  update_trust = 1;
+  return 1;
 }
 
+
 static int
-menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
+menu_backsign (KBNODE pub_keyblock)
 {
-  int rc,modified=0;
+  int rc, modified = 0;
   PKT_public_key *main_pk;
-  PKT_secret_key *main_sk,*sub_sk=NULL;
   KBNODE node;
   u32 timestamp;
 
-  assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-  assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
+  assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
 
-  merge_keys_and_selfsig(pub_keyblock);
-  main_pk=pub_keyblock->pkt->pkt.public_key;
-  main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
-  keyid_from_pk(main_pk,NULL);
+  merge_keys_and_selfsig (pub_keyblock);
+  main_pk = pub_keyblock->pkt->pkt.public_key;
+  keyid_from_pk (main_pk, NULL);
 
   /* We use the same timestamp for all backsigs so that we don't
      reveal information about the used machine.  */
   timestamp = make_timestamp ();
 
-  for(node=pub_keyblock;node;node=node->next)
+  for (node = pub_keyblock; node; node = node->next)
     {
-      PKT_public_key *sub_pk=NULL;
-      KBNODE node2,sig_pk=NULL,sig_sk=NULL;
-      char *passphrase;
-
-      if(sub_sk)
-       {
-         free_secret_key(sub_sk);
-         sub_sk=NULL;
-       }
+      PKT_public_key *sub_pk = NULL;
+      KBNODE node2, sig_pk = NULL /*,sig_sk = NULL*/;
+      /* char *passphrase; */
 
       /* Find a signing subkey with no backsig */
-      if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
        {
-         if(node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
+         if (node->pkt->pkt.public_key->pubkey_usage & PUBKEY_USAGE_SIG)
            {
-             if(node->pkt->pkt.public_key->backsig)
-               tty_printf(_("signing subkey %s is already cross-certified\n"),
-                          keystr_from_pk(node->pkt->pkt.public_key));
+             if (node->pkt->pkt.public_key->flags.backsig)
+               tty_printf (_
+                           ("signing subkey %s is already cross-certified\n"),
+                           keystr_from_pk (node->pkt->pkt.public_key));
              else
-               sub_pk=node->pkt->pkt.public_key;
+               sub_pk = node->pkt->pkt.public_key;
            }
          else
-           tty_printf(_("subkey %s does not sign and so does"
-                        " not need to be cross-certified\n"),
-                      keystr_from_pk(node->pkt->pkt.public_key));
+           tty_printf (_("subkey %s does not sign and so does"
+                         " not need to be cross-certified\n"),
+                       keystr_from_pk (node->pkt->pkt.public_key));
        }
 
-      if(!sub_pk)
+      if (!sub_pk)
        continue;
 
       /* Find the selected selfsig on this subkey */
-      for(node2=node->next;
-         node2 && node2->pkt->pkttype==PKT_SIGNATURE;
-         node2=node2->next)
-       if(node2->pkt->pkt.signature->version>=4
-          && node2->pkt->pkt.signature->flags.chosen_selfsig)
+      for (node2 = node->next;
+          node2 && node2->pkt->pkttype == PKT_SIGNATURE; node2 = node2->next)
+       if (node2->pkt->pkt.signature->version >= 4
+           && node2->pkt->pkt.signature->flags.chosen_selfsig)
          {
-           sig_pk=node2;
+           sig_pk = node2;
            break;
          }
 
-      if(!sig_pk)
+      if (!sig_pk)
        continue;
 
       /* Find the secret subkey that matches the public subkey */
-      for(node2=sec_keyblock;node2;node2=node2->next)
-       if(node2->pkt->pkttype==PKT_SECRET_SUBKEY
-          && !cmp_public_secret_key(sub_pk,node2->pkt->pkt.secret_key))
-         {
-           sub_sk=copy_secret_key(NULL,node2->pkt->pkt.secret_key);
-           break;
-         }
-
-      if(!sub_sk)
-       {
-         tty_printf(_("no secret subkey for public subkey %s - ignoring\n"),
-                    keystr_from_pk(sub_pk));
-         continue;
-       }
-
-      /* Now finally find the matching selfsig on the secret subkey.
-        We can't use chosen_selfsig here (it's not set for secret
-        keys), so we just pick the selfsig with the right class.
-        This is what menu_expire does as well. */
-      for(node2=node2->next;
-         node2 && node2->pkt->pkttype!=PKT_SECRET_SUBKEY;
-         node2=node2->next)
-       if(node2->pkt->pkttype==PKT_SIGNATURE
-          && node2->pkt->pkt.signature->version>=4
-          && node2->pkt->pkt.signature->keyid[0]==sig_pk->pkt->pkt.signature->keyid[0]
-          && node2->pkt->pkt.signature->keyid[1]==sig_pk->pkt->pkt.signature->keyid[1]
-          && node2->pkt->pkt.signature->sig_class==sig_pk->pkt->pkt.signature->sig_class)
-         {
-           sig_sk=node2;
-           break;
-         }
+      log_debug ("FIXME: Check whether a secret subkey is available.\n");
+      /* if (!sub_sk) */
+      /*   { */
+      /*     tty_printf (_("no secret subkey for public subkey %s - ignoring\n"), */
+      /*             keystr_from_pk (sub_pk)); */
+      /*     continue; */
+      /*   } */
 
-      /* Now we can get to work.  We have a main key and secret part,
-        a signing subkey with signature and secret part possibly with
-        signature. */
 
-      passphrase=get_last_passphrase();
-      set_next_passphrase(passphrase);
-      xfree(passphrase);
+      /* Now we can get to work.  */
 
-      rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_sk,
-                         timestamp);
-      if(rc==0)
+      rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_pk,
+                        timestamp, NULL);
+      if (!rc)
        {
          PKT_signature *newsig;
          PACKET *newpkt;
 
-         passphrase=get_last_passphrase();
-         set_next_passphrase(passphrase);
-         xfree(passphrase);
-
-         rc=update_keysig_packet(&newsig,sig_pk->pkt->pkt.signature,main_pk,
-                                 NULL,sub_pk,main_sk,NULL,NULL);
-         if(rc==0)
+         rc = update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature,
+                                     main_pk, NULL, sub_pk, main_pk,
+                                     NULL, NULL);
+         if (!rc)
            {
              /* Put the new sig into place on the pubkey */
-             newpkt=xmalloc_clear(sizeof(*newpkt));
-             newpkt->pkttype=PKT_SIGNATURE;
-             newpkt->pkt.signature=newsig;
-             free_packet(sig_pk->pkt);
-             xfree(sig_pk->pkt);
-             sig_pk->pkt=newpkt;
-
-             if(sig_sk)
-               {
-                 /* Put the new sig into place on the seckey */
-                 newpkt=xmalloc_clear(sizeof(*newpkt));
-                 newpkt->pkttype=PKT_SIGNATURE;
-                 newpkt->pkt.signature=copy_signature(NULL,newsig);
-                 free_packet(sig_sk->pkt);
-                 xfree(sig_sk->pkt);
-                 sig_sk->pkt=newpkt;
-               }
-
-             modified=1;
+             newpkt = xmalloc_clear (sizeof (*newpkt));
+             newpkt->pkttype = PKT_SIGNATURE;
+             newpkt->pkt.signature = newsig;
+             free_packet (sig_pk->pkt);
+             xfree (sig_pk->pkt);
+             sig_pk->pkt = newpkt;
+
+             modified = 1;
            }
          else
            {
-             log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
+             log_error ("update_keysig_packet failed: %s\n",
+                        g10_errstr (rc));
              break;
            }
        }
       else
        {
-         log_error("make_backsig failed: %s\n",g10_errstr(rc));
+         log_error ("make_backsig failed: %s\n", g10_errstr (rc));
          break;
        }
     }
 
-  set_next_passphrase(NULL);
-
-  free_secret_key(main_sk);
-  if(sub_sk)
-    free_secret_key(sub_sk);
-
   return modified;
 }
 
 
 static int
-change_primary_uid_cb ( PKT_signature *sig, void *opaque )
+change_primary_uid_cb (PKT_signature * sig, void *opaque)
 {
-    byte buf[1];
+  byte buf[1];
 
-    /* first clear all primary uid flags so that we are sure none are
-     * lingering around */
-    delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
-    delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
+  /* first clear all primary uid flags so that we are sure none are
+   * lingering around */
+  delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
+  delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
 
-    /* if opaque is set,we want to set the primary id */
-    if (opaque) {
-        buf[0] = 1;
-        build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
+  /* if opaque is set,we want to set the primary id */
+  if (opaque)
+    {
+      buf[0] = 1;
+      build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1);
     }
 
-    return 0;
+  return 0;
 }
 
 
@@ -4016,289 +3927,288 @@ change_primary_uid_cb ( PKT_signature *sig, void *opaque )
  * sufficient to updated a signature during import.
  */
 static int
-menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_set_primary_uid (KBNODE pub_keyblock)
 {
-    PKT_secret_key *sk;    /* copy of the main sk */
-    PKT_public_key *main_pk;
-    PKT_user_id *uid;
-    KBNODE node;
-    u32 keyid[2];
-    int selected;
-    int attribute = 0;
-    int modified = 0;
-
-    if ( count_selected_uids (pub_keyblock) != 1 ) {
-       tty_printf(_("Please select exactly one user ID.\n"));
-       return 0;
+  PKT_public_key *main_pk;
+  PKT_user_id *uid;
+  KBNODE node;
+  u32 keyid[2];
+  int selected;
+  int attribute = 0;
+  int modified = 0;
+
+  if (count_selected_uids (pub_keyblock) != 1)
+    {
+      tty_printf (_("Please select exactly one user ID.\n"));
+      return 0;
+    }
+
+  main_pk = NULL;
+  uid = NULL;
+  selected = 0;
+
+  /* Is our selected uid an attribute packet? */
+  for (node = pub_keyblock; node; node = node->next)
+    if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
+      attribute = (node->pkt->pkt.user_id->attrib_data != NULL);
+
+  for (node = pub_keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       break; /* No more user ids expected - ready.  */
+
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+       {
+         main_pk = node->pkt->pkt.public_key;
+         keyid_from_pk (main_pk, keyid);
+       }
+      else if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         uid = node->pkt->pkt.user_id;
+         selected = node->flag & NODFLG_SELUID;
+       }
+      else if (main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE)
+       {
+         PKT_signature *sig = node->pkt->pkt.signature;
+         if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+             && (uid && (sig->sig_class & ~3) == 0x10)
+             && attribute == (uid->attrib_data != NULL)
+             && sig->flags.chosen_selfsig)
+           {
+             if (sig->version < 4)
+               {
+                 char *user =
+                   utf8_to_native (uid->name, strlen (uid->name), 0);
+
+                 log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
+                            user);
+                 xfree (user);
+               }
+             else
+               {
+                 /* This is a selfsignature which is to be replaced.
+                    We can just ignore v3 signatures because they are
+                    not able to carry the primary ID flag.  We also
+                    ignore self-sigs on user IDs that are not of the
+                    same type that we are making primary.  That is, if
+                    we are making a user ID primary, we alter user IDs.
+                    If we are making an attribute packet primary, we
+                    alter attribute packets. */
+
+                 /* FIXME: We must make sure that we only have one
+                    self-signature per user ID here (not counting
+                    revocations) */
+                 PKT_signature *newsig;
+                 PACKET *newpkt;
+                 const byte *p;
+                 int action;
+
+                 /* See whether this signature has the primary UID flag.  */
+                 p = parse_sig_subpkt (sig->hashed,
+                                       SIGSUBPKT_PRIMARY_UID, NULL);
+                 if (!p)
+                   p = parse_sig_subpkt (sig->unhashed,
+                                         SIGSUBPKT_PRIMARY_UID, NULL);
+                 if (p && *p)  /* yes */
+                   action = selected ? 0 : -1;
+                 else          /* no */
+                   action = selected ? 1 : 0;
+
+                 if (action)
+                   {
+                     int rc = update_keysig_packet (&newsig, sig,
+                                                    main_pk, uid, NULL,
+                                                    main_pk,
+                                                    change_primary_uid_cb,
+                                                    action > 0 ? "x" : NULL);
+                     if (rc)
+                       {
+                         log_error ("update_keysig_packet failed: %s\n",
+                                    g10_errstr (rc));
+                         return 0;
+                       }
+                     /* replace the packet */
+                     newpkt = xmalloc_clear (sizeof *newpkt);
+                     newpkt->pkttype = PKT_SIGNATURE;
+                     newpkt->pkt.signature = newsig;
+                     free_packet (node->pkt);
+                     xfree (node->pkt);
+                     node->pkt = newpkt;
+                     modified = 1;
+                   }
+               }
+           }
+       }
     }
 
-    node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-    sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
+  return modified;
+}
+
+
+/*
+ * Set preferences to new values for the selected user IDs
+ */
+static int
+menu_set_preferences (KBNODE pub_keyblock)
+{
+  PKT_public_key *main_pk;
+  PKT_user_id *uid;
+  KBNODE node;
+  u32 keyid[2];
+  int selected, select_all;
+  int modified = 0;
 
-    /* Now we can actually change the self signature(s) */
-    main_pk = NULL;
-    uid = NULL;
-    selected = 0;
+  no_primary_warning (pub_keyblock);
 
-    /* Is our selected uid an attribute packet? */
-    for ( node=pub_keyblock; node; node = node->next )
-      if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
-       attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
+  select_all = !count_selected_uids (pub_keyblock);
 
-    for ( node=pub_keyblock; node; node = node->next ) {
-       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-            break; /* ready */
+  /* Now we can actually change the self signature(s) */
+  main_pk = NULL;
+  uid = NULL;
+  selected = 0;
+  for (node = pub_keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       break; /* No more user-ids expected - ready.  */
 
-       if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
-           main_pk = node->pkt->pkt.public_key;
-           keyid_from_pk( main_pk, keyid );
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+       {
+         main_pk = node->pkt->pkt.public_key;
+         keyid_from_pk (main_pk, keyid);
        }
-       else if ( node->pkt->pkttype == PKT_USER_ID ) {
-           uid = node->pkt->pkt.user_id;
-                   selected = node->flag & NODFLG_SELUID;
-        }
-       else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
-           PKT_signature *sig = node->pkt->pkt.signature;
-           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-                && (uid && (sig->sig_class&~3) == 0x10)
-                && attribute == (uid->attrib_data!=NULL)
-                && sig->flags.chosen_selfsig )
-             {
-             if(sig->version < 4) {
-               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
-
-               log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
-                        user);
-               xfree(user);
-             }
-             else {
-               /* This is a selfsignature which is to be replaced.
-                  We can just ignore v3 signatures because they are
-                  not able to carry the primary ID flag.  We also
-                  ignore self-sigs on user IDs that are not of the
-                  same type that we are making primary.  That is, if
-                  we are making a user ID primary, we alter user IDs.
-                  If we are making an attribute packet primary, we
-                  alter attribute packets. */
-
-                /* FIXME: We must make sure that we only have one
-                   self-signature per user ID here (not counting
-                   revocations) */
-               PKT_signature *newsig;
-               PACKET *newpkt;
-                const byte *p;
-                int action;
-
-                /* see whether this signature has the primary UID flag */
-                p = parse_sig_subpkt (sig->hashed,
-                                      SIGSUBPKT_PRIMARY_UID, NULL );
-                if ( !p )
-                    p = parse_sig_subpkt (sig->unhashed,
-                                          SIGSUBPKT_PRIMARY_UID, NULL );
-                if ( p && *p ) /* yes */
-                    action = selected? 0 : -1;
-                else /* no */
-                    action = selected? 1 : 0;
-
-                if (action) {
-                    int rc = update_keysig_packet (&newsig, sig,
-                                              main_pk, uid, NULL,
-                                               sk,
-                                               change_primary_uid_cb,
-                                               action > 0? "x":NULL );
-                    if( rc ) {
-                        log_error ("update_keysig_packet failed: %s\n",
-                                   g10_errstr(rc));
-                        free_secret_key( sk );
-                        return 0;
-                    }
-                    /* replace the packet */
-                    newpkt = xmalloc_clear( sizeof *newpkt );
-                    newpkt->pkttype = PKT_SIGNATURE;
-                    newpkt->pkt.signature = newsig;
-                    free_packet( node->pkt );
-                    xfree( node->pkt );
-                    node->pkt = newpkt;
-                    modified = 1;
-               }
-             }
-           }
+      else if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         uid = node->pkt->pkt.user_id;
+         selected = select_all || (node->flag & NODFLG_SELUID);
        }
-    }
-
-    free_secret_key( sk );
-    return modified;
-}
+      else if (main_pk && uid && selected
+              && node->pkt->pkttype == PKT_SIGNATURE)
+       {
+         PKT_signature *sig = node->pkt->pkt.signature;
+         if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+             && (uid && (sig->sig_class & ~3) == 0x10)
+             && sig->flags.chosen_selfsig)
+           {
+             if (sig->version < 4)
+               {
+                 char *user =
+                   utf8_to_native (uid->name, strlen (uid->name), 0);
 
+                 log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
+                           user);
+                 xfree (user);
+               }
+             else
+               {
+                 /* This is a selfsignature which is to be replaced
+                  * We have to ignore v3 signatures because they are
+                  * not able to carry the preferences.  */
+                 PKT_signature *newsig;
+                 PACKET *newpkt;
+                 int rc;
 
-/*
- * Set preferences to new values for the selected user IDs
- */
-static int
-menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
-    PKT_secret_key *sk;    /* copy of the main sk */
-    PKT_public_key *main_pk;
-    PKT_user_id *uid;
-    KBNODE node;
-    u32 keyid[2];
-    int selected, select_all;
-    int modified = 0;
-
-    no_primary_warning(pub_keyblock);
-
-    select_all = !count_selected_uids (pub_keyblock);
-
-    node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-    sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
-    /* Now we can actually change the self signature(s) */
-    main_pk = NULL;
-    uid = NULL;
-    selected = 0;
-    for ( node=pub_keyblock; node; node = node->next ) {
-       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-            break; /* ready */
-
-       if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
-           main_pk = node->pkt->pkt.public_key;
-           keyid_from_pk( main_pk, keyid );
-       }
-       else if ( node->pkt->pkttype == PKT_USER_ID ) {
-           uid = node->pkt->pkt.user_id;
-                   selected = select_all || (node->flag & NODFLG_SELUID);
-        }
-       else if ( main_pk && uid && selected
-                  && node->pkt->pkttype == PKT_SIGNATURE ) {
-           PKT_signature *sig = node->pkt->pkt.signature;
-           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-                && (uid && (sig->sig_class&~3) == 0x10)
-                && sig->flags.chosen_selfsig ) {
-             if( sig->version < 4 ) {
-               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
-
-               log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
-                        user);
-               xfree(user);
-             }
-             else {
-               /* This is a selfsignature which is to be replaced
-                 * We have to ignore v3 signatures because they are
-                 * not able to carry the preferences */
-               PKT_signature *newsig;
-               PACKET *newpkt;
-                int rc;
-
-                rc = update_keysig_packet (&newsig, sig,
-                                           main_pk, uid, NULL,
-                                           sk,
-                                           keygen_upd_std_prefs,
-                                           NULL );
-                if( rc ) {
-                    log_error ("update_keysig_packet failed: %s\n",
-                               g10_errstr(rc));
-                    free_secret_key( sk );
-                    return 0;
-                }
-                /* replace the packet */
-                newpkt = xmalloc_clear( sizeof *newpkt );
-                newpkt->pkttype = PKT_SIGNATURE;
-                newpkt->pkt.signature = newsig;
-                free_packet( node->pkt );
-                xfree( node->pkt );
-                node->pkt = newpkt;
-                modified = 1;
-             }
-            }
+                 rc = update_keysig_packet (&newsig, sig,
+                                            main_pk, uid, NULL, main_pk,
+                                             keygen_upd_std_prefs, NULL);
+                 if (rc)
+                   {
+                     log_error ("update_keysig_packet failed: %s\n",
+                                g10_errstr (rc));
+                     return 0;
+                   }
+                 /* replace the packet */
+                 newpkt = xmalloc_clear (sizeof *newpkt);
+                 newpkt->pkttype = PKT_SIGNATURE;
+                 newpkt->pkt.signature = newsig;
+                 free_packet (node->pkt);
+                 xfree (node->pkt);
+                 node->pkt = newpkt;
+                 modified = 1;
+               }
+           }
        }
     }
 
-    free_secret_key( sk );
-    return modified;
+  return modified;
 }
 
 
 static int
-menu_set_keyserver_url (const char *url,
-                       KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_set_keyserver_url (const char *url, KBNODE pub_keyblock)
 {
-  PKT_secret_key *sk;    /* copy of the main sk */
   PKT_public_key *main_pk;
   PKT_user_id *uid;
   KBNODE node;
   u32 keyid[2];
   int selected, select_all;
   int modified = 0;
-  char *answer,*uri;
+  char *answer, *uri;
 
-  no_primary_warning(pub_keyblock);
+  no_primary_warning (pub_keyblock);
 
-  if(url)
-    answer=xstrdup(url);
+  if (url)
+    answer = xstrdup (url);
   else
     {
-      answer=cpr_get_utf8("keyedit.add_keyserver",
-                         _("Enter your preferred keyserver URL: "));
-      if(answer[0]=='\0' || answer[0]=='\004')
+      answer = cpr_get_utf8 ("keyedit.add_keyserver",
+                            _("Enter your preferred keyserver URL: "));
+      if (answer[0] == '\0' || answer[0] == CONTROL_D)
        {
-         xfree(answer);
+         xfree (answer);
          return 0;
        }
     }
 
-  if(ascii_strcasecmp(answer,"none")==0)
-    uri=NULL;
+  if (ascii_strcasecmp (answer, "none") == 0)
+    uri = NULL;
   else
     {
-      struct keyserver_spec *keyserver=NULL;
+      struct keyserver_spec *keyserver = NULL;
       /* Sanity check the format */
-      keyserver=parse_keyserver_uri(answer,1,NULL,0);
-      xfree(answer);
-      if(!keyserver)
+      keyserver = parse_keyserver_uri (answer, 1, NULL, 0);
+      xfree (answer);
+      if (!keyserver)
        {
-         log_info(_("could not parse keyserver URL\n"));
+         log_info (_("could not parse keyserver URL\n"));
          return 0;
        }
-      uri=xstrdup(keyserver->uri);
-      free_keyserver_spec(keyserver);
+      uri = xstrdup (keyserver->uri);
+      free_keyserver_spec (keyserver);
     }
 
   select_all = !count_selected_uids (pub_keyblock);
 
-  node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-  sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
   /* Now we can actually change the self signature(s) */
   main_pk = NULL;
   uid = NULL;
   selected = 0;
-  for ( node=pub_keyblock; node; node = node->next )
+  for (node = pub_keyblock; node; node = node->next)
     {
-      if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
        break; /* ready */
 
-      if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
          main_pk = node->pkt->pkt.public_key;
-         keyid_from_pk( main_pk, keyid );
+         keyid_from_pk (main_pk, keyid);
        }
-      else if ( node->pkt->pkttype == PKT_USER_ID )
+      else if (node->pkt->pkttype == PKT_USER_ID)
        {
          uid = node->pkt->pkt.user_id;
          selected = select_all || (node->flag & NODFLG_SELUID);
        }
-      else if ( main_pk && uid && selected
-               && node->pkt->pkttype == PKT_SIGNATURE )
+      else if (main_pk && uid && selected
+              && node->pkt->pkttype == PKT_SIGNATURE)
        {
          PKT_signature *sig = node->pkt->pkt.signature;
-         if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-              && (uid && (sig->sig_class&~3) == 0x10)
-              && sig->flags.chosen_selfsig)
+         if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+             && (uid && (sig->sig_class & ~3) == 0x10)
+             && sig->flags.chosen_selfsig)
            {
-             char *user=utf8_to_native(uid->name,strlen(uid->name),0);
-             if( sig->version < 4 )
-               log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
-                        user);
+             char *user = utf8_to_native (uid->name, strlen (uid->name), 0);
+             if (sig->version < 4)
+               log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
+                         user);
              else
                {
                  /* This is a selfsignature which is to be replaced
@@ -4310,61 +4220,60 @@ menu_set_keyserver_url (const char *url,
                  const byte *p;
                  size_t plen;
 
-                 p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
-                 if(p && plen)
+                 p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &plen);
+                 if (p && plen)
                    {
-                     tty_printf("Current preferred keyserver for user"
-                                " ID \"%s\": ",user);
-                     tty_print_utf8_string(p,plen);
-                     tty_printf("\n");
-                     if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
-                        uri?_("Are you sure you want to replace it? (y/N) "):
-                            _("Are you sure you want to delete it? (y/N) ")))
+                     tty_printf ("Current preferred keyserver for user"
+                                 " ID \"%s\": ", user);
+                     tty_print_utf8_string (p, plen);
+                     tty_printf ("\n");
+                     if (!cpr_get_answer_is_yes
+                          ("keyedit.confirm_keyserver",
+                           uri
+                           ? _("Are you sure you want to replace it? (y/N) ")
+                           : _("Are you sure you want to delete it? (y/N) ")))
                        continue;
                    }
-                 else if(uri==NULL)
+                 else if (uri == NULL)
                    {
                      /* There is no current keyserver URL, so there
-                        is no point in trying to un-set it. */
+                        is no point in trying to un-set it. */
                      continue;
                    }
 
                  rc = update_keysig_packet (&newsig, sig,
                                             main_pk, uid, NULL,
-                                            sk,
-                                            keygen_add_keyserver_url, uri );
-                 if( rc )
+                                            main_pk,
+                                            keygen_add_keyserver_url, uri);
+                 if (rc)
                    {
                      log_error ("update_keysig_packet failed: %s\n",
-                                g10_errstr(rc));
-                     free_secret_key( sk );
-                     xfree(uri);
+                                g10_errstr (rc));
+                     xfree (uri);
                      return 0;
                    }
                  /* replace the packet */
-                 newpkt = xmalloc_clear( sizeof *newpkt );
+                 newpkt = xmalloc_clear (sizeof *newpkt);
                  newpkt->pkttype = PKT_SIGNATURE;
                  newpkt->pkt.signature = newsig;
-                 free_packet( node->pkt );
-                 xfree( node->pkt );
+                 free_packet (node->pkt);
+                 xfree (node->pkt);
                  node->pkt = newpkt;
                  modified = 1;
                }
 
-             xfree(user);
+             xfree (user);
            }
        }
     }
 
-  xfree(uri);
-  free_secret_key( sk );
+  xfree (uri);
   return modified;
 }
 
 static int
-menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
+menu_set_notation (const char *string, KBNODE pub_keyblock)
 {
-  PKT_secret_key *sk;    /* copy of the main sk */
   PKT_public_key *main_pk;
   PKT_user_id *uid;
   KBNODE node;
@@ -4374,88 +4283,85 @@ menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
   char *answer;
   struct notation *notation;
 
-  no_primary_warning(pub_keyblock);
+  no_primary_warning (pub_keyblock);
 
-  if(string)
-    answer=xstrdup(string);
+  if (string)
+    answer = xstrdup (string);
   else
     {
-      answer=cpr_get_utf8("keyedit.add_notation",
-                         _("Enter the notation: "));
-      if(answer[0]=='\0' || answer[0]=='\004')
+      answer = cpr_get_utf8 ("keyedit.add_notation",
+                            _("Enter the notation: "));
+      if (answer[0] == '\0' || answer[0] == CONTROL_D)
        {
-         xfree(answer);
+         xfree (answer);
          return 0;
        }
     }
 
-  if(ascii_strcasecmp(answer,"none")==0
-     || ascii_strcasecmp(answer,"-")==0)
-    notation=NULL; /* delete them all */
+  if (!ascii_strcasecmp (answer, "none")
+      || !ascii_strcasecmp (answer, "-"))
+    notation = NULL; /* Delete them all.  */
   else
     {
-      notation=string_to_notation(answer,0);
-      if(!notation)
+      notation = string_to_notation (answer, 0);
+      if (!notation)
        {
-         xfree(answer);
+         xfree (answer);
          return 0;
        }
     }
 
-  xfree(answer);
+  xfree (answer);
 
   select_all = !count_selected_uids (pub_keyblock);
 
-  node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-  sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
   /* Now we can actually change the self signature(s) */
   main_pk = NULL;
   uid = NULL;
   selected = 0;
-  for ( node=pub_keyblock; node; node = node->next )
+  for (node = pub_keyblock; node; node = node->next)
     {
-      if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
        break; /* ready */
 
-      if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
          main_pk = node->pkt->pkt.public_key;
-         keyid_from_pk( main_pk, keyid );
+         keyid_from_pk (main_pk, keyid);
        }
-      else if ( node->pkt->pkttype == PKT_USER_ID )
+      else if (node->pkt->pkttype == PKT_USER_ID)
        {
          uid = node->pkt->pkt.user_id;
          selected = select_all || (node->flag & NODFLG_SELUID);
        }
-      else if ( main_pk && uid && selected
-               && node->pkt->pkttype == PKT_SIGNATURE )
+      else if (main_pk && uid && selected
+              && node->pkt->pkttype == PKT_SIGNATURE)
        {
          PKT_signature *sig = node->pkt->pkt.signature;
-         if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-              && (uid && (sig->sig_class&~3) == 0x10)
-              && sig->flags.chosen_selfsig)
+         if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+             && (uid && (sig->sig_class & ~3) == 0x10)
+             && sig->flags.chosen_selfsig)
            {
-             char *user=utf8_to_native(uid->name,strlen(uid->name),0);
-             if( sig->version < 4 )
-               log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
-                        user);
+             char *user = utf8_to_native (uid->name, strlen (uid->name), 0);
+             if (sig->version < 4)
+               log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
+                         user);
              else
                {
                  PKT_signature *newsig;
                  PACKET *newpkt;
-                 int rc,skip=0,addonly=1;
+                 int rc, skip = 0, addonly = 1;
 
-                 if(sig->flags.notation)
+                 if (sig->flags.notation)
                    {
-                     tty_printf("Current notations for user ID \"%s\":\n",
-                                user);
-                     tty_print_notations(-9,sig);
+                     tty_printf ("Current notations for user ID \"%s\":\n",
+                                 user);
+                     tty_print_notations (-9, sig);
                    }
                  else
                    {
-                     tty_printf("No notations on user ID \"%s\"\n",user);
-                     if(notation==NULL)
+                     tty_printf ("No notations on user ID \"%s\"\n", user);
+                     if (notation == NULL)
                        {
                          /* There are no current notations, so there
                             is no point in trying to un-set them. */
@@ -4463,37 +4369,37 @@ menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
                        }
                    }
 
-                 if(notation)
+                 if (notation)
                    {
                      struct notation *n;
-                     int deleting=0;
+                     int deleting = 0;
 
-                     notation->next=sig_to_notation(sig);
+                     notation->next = sig_to_notation (sig);
 
-                     for(n=notation->next;n;n=n->next)
-                       if(strcmp(n->name,notation->name)==0)
+                     for (n = notation->next; n; n = n->next)
+                       if (strcmp (n->name, notation->name) == 0)
                          {
-                           if(notation->value)
+                           if (notation->value)
                              {
-                               if(strcmp(n->value,notation->value)==0)
+                               if (strcmp (n->value, notation->value) == 0)
                                  {
-                                   if(notation->flags.ignore)
+                                   if (notation->flags.ignore)
                                      {
                                        /* Value match with a delete
                                           flag. */
-                                       n->flags.ignore=1;
-                                       deleting=1;
+                                       n->flags.ignore = 1;
+                                       deleting = 1;
                                      }
                                    else
                                      {
                                        /* Adding the same notation
                                           twice, so don't add it at
                                           all. */
-                                       skip=1;
-                                       tty_printf("Skipping notation:"
-                                                  " %s=%s\n",
-                                                  notation->name,
-                                                  notation->value);
+                                       skip = 1;
+                                       tty_printf ("Skipping notation:"
+                                                   " %s=%s\n",
+                                                   notation->name,
+                                                   notation->value);
                                        break;
                                      }
                                  }
@@ -4501,76 +4407,75 @@ menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
                            else
                              {
                                /* No value, so it means delete. */
-                               n->flags.ignore=1;
-                               deleting=1;
+                               n->flags.ignore = 1;
+                               deleting = 1;
                              }
 
-                           if(n->flags.ignore)
+                           if (n->flags.ignore)
                              {
-                               tty_printf("Removing notation: %s=%s\n",
-                                          n->name,n->value);
-                               addonly=0;
+                               tty_printf ("Removing notation: %s=%s\n",
+                                           n->name, n->value);
+                               addonly = 0;
                              }
                          }
 
-                     if(!notation->flags.ignore && !skip)
-                       tty_printf("Adding notation: %s=%s\n",
-                                  notation->name,notation->value);
+                     if (!notation->flags.ignore && !skip)
+                       tty_printf ("Adding notation: %s=%s\n",
+                                   notation->name, notation->value);
 
-                     /* We tried to delete, but had no matches */
-                     if(notation->flags.ignore && !deleting)
+                     /* We tried to delete, but had no matches */
+                     if (notation->flags.ignore && !deleting)
                        continue;
                    }
                  else
                    {
-                     tty_printf("Removing all notations\n");
-                     addonly=0;
+                     tty_printf ("Removing all notations\n");
+                     addonly = 0;
                    }
 
-                 if(skip
-                    || (!addonly
-                        && !cpr_get_answer_is_yes("keyedit.confirm_notation",
-                                                  _("Proceed? (y/N) "))))
+                 if (skip
+                     || (!addonly
+                         &&
+                         !cpr_get_answer_is_yes ("keyedit.confirm_notation",
+                                                 _("Proceed? (y/N) "))))
                    continue;
 
                  rc = update_keysig_packet (&newsig, sig,
                                             main_pk, uid, NULL,
-                                            sk,
-                                            keygen_add_notations, notation );
-                 if( rc )
+                                            main_pk,
+                                            keygen_add_notations, notation);
+                 if (rc)
                    {
                      log_error ("update_keysig_packet failed: %s\n",
-                                g10_errstr(rc));
-                     free_secret_key( sk );
-                     free_notation(notation);
-                     xfree(user);
+                                g10_errstr (rc));
+                     free_notation (notation);
+                     xfree (user);
                      return 0;
                    }
 
                  /* replace the packet */
-                 newpkt = xmalloc_clear( sizeof *newpkt );
+                 newpkt = xmalloc_clear (sizeof *newpkt);
                  newpkt->pkttype = PKT_SIGNATURE;
                  newpkt->pkt.signature = newsig;
-                 free_packet( node->pkt );
-                 xfree( node->pkt );
+                 free_packet (node->pkt);
+                 xfree (node->pkt);
                  node->pkt = newpkt;
                  modified = 1;
 
-                 if(notation)
+                 if (notation)
                    {
                      /* Snip off the notation list from the sig */
-                     free_notation(notation->next);
-                     notation->next=NULL;
+                     free_notation (notation->next);
+                     notation->next = NULL;
                    }
 
-                 xfree(user);
+                 xfree (user);
                }
            }
        }
     }
 
-  free_notation(notation);
-  free_secret_key( sk );
+  free_notation (notation);
   return modified;
 }
 
@@ -4585,46 +4490,46 @@ menu_select_uid (KBNODE keyblock, int idx)
   KBNODE node;
   int i;
 
-  if (idx == -1) /* Select all. */
+  if (idx == -1)               /* Select all. */
     {
       for (node = keyblock; node; node = node->next)
-        if (node->pkt->pkttype == PKT_USER_ID)
-          node->flag |= NODFLG_SELUID;
+       if (node->pkt->pkttype == PKT_USER_ID)
+         node->flag |= NODFLG_SELUID;
       return 1;
     }
-  else if (idx) /* Toggle.  */
+  else if (idx)                        /* Toggle.  */
     {
-      for (i=0, node = keyblock; node; node = node->next)
-        {
-          if (node->pkt->pkttype == PKT_USER_ID)
-            if (++i == idx)
-              break;
+      for (i = 0, node = keyblock; node; node = node->next)
+       {
+         if (node->pkt->pkttype == PKT_USER_ID)
+           if (++i == idx)
+             break;
        }
       if (!node)
-        {
-          tty_printf (_("No user ID with index %d\n"), idx );
-          return 0;
+       {
+         tty_printf (_("No user ID with index %d\n"), idx);
+         return 0;
        }
 
-      for (i=0, node = keyblock; node; node = node->next)
-        {
-          if (node->pkt->pkttype == PKT_USER_ID)
-            {
-              if (++i == idx)
-                {
-                  if ((node->flag & NODFLG_SELUID))
-                    node->flag &= ~NODFLG_SELUID;
-                  else
-                    node->flag |= NODFLG_SELUID;
-                }
-            }
-        }
+      for (i = 0, node = keyblock; node; node = node->next)
+       {
+         if (node->pkt->pkttype == PKT_USER_ID)
+           {
+             if (++i == idx)
+               {
+                 if ((node->flag & NODFLG_SELUID))
+                   node->flag &= ~NODFLG_SELUID;
+                 else
+                   node->flag |= NODFLG_SELUID;
+               }
+           }
+       }
     }
-  else /* Unselect all */
+  else                         /* Unselect all */
     {
       for (node = keyblock; node; node = node->next)
-        if (node->pkt->pkttype == PKT_USER_ID)
-          node->flag &= ~NODFLG_SELUID;
+       if (node->pkt->pkttype == PKT_USER_ID)
+         node->flag &= ~NODFLG_SELUID;
     }
 
   return 1;
@@ -4633,25 +4538,26 @@ menu_select_uid (KBNODE keyblock, int idx)
 
 /* Search in the keyblock for a uid that matches namehash */
 static int
-menu_select_uid_namehash( KBNODE keyblock, const char *namehash )
+menu_select_uid_namehash (KBNODE keyblock, const char *namehash)
 {
   byte hash[NAMEHASH_LEN];
   KBNODE node;
   int i;
 
-  assert(strlen(namehash)==NAMEHASH_LEN*2);
+  assert (strlen (namehash) == NAMEHASH_LEN * 2);
 
-  for(i=0;i<NAMEHASH_LEN;i++)
-    hash[i]=hextobyte(&namehash[i*2]);
+  for (i = 0; i < NAMEHASH_LEN; i++)
+    hash[i] = hextobyte (&namehash[i * 2]);
 
-  for(node=keyblock->next;node;node=node->next)
+  for (node = keyblock->next; node; node = node->next)
     {
-      if(node->pkt->pkttype==PKT_USER_ID)
+      if (node->pkt->pkttype == PKT_USER_ID)
        {
-         namehash_from_uid(node->pkt->pkt.user_id);
-         if(memcmp(node->pkt->pkt.user_id->namehash,hash,NAMEHASH_LEN)==0)
+         namehash_from_uid (node->pkt->pkt.user_id);
+         if (memcmp (node->pkt->pkt.user_id->namehash, hash, NAMEHASH_LEN) ==
+             0)
            {
-             if(node->flag&NODFLG_SELUID)
+             if (node->flag & NODFLG_SELUID)
                node->flag &= ~NODFLG_SELUID;
              else
                node->flag |= NODFLG_SELUID;
@@ -4661,16 +4567,17 @@ menu_select_uid_namehash( KBNODE keyblock, const char *namehash )
        }
     }
 
-    if(!node)
-      {
-       tty_printf(_("No user ID with hash %s\n"),namehash);
-       return 0;
-      }
+  if (!node)
+    {
+      tty_printf (_("No user ID with hash %s\n"), namehash);
+      return 0;
+    }
 
   return 1;
 }
 
-/****************
+
+/*
  * Select secondary keys
  * Returns: True if the selection changed.
  */
@@ -4680,47 +4587,47 @@ menu_select_key (KBNODE keyblock, int idx)
   KBNODE node;
   int i;
 
-  if (idx == -1) /* Select all.  */
+  if (idx == -1)               /* Select all.  */
     {
       for (node = keyblock; node; node = node->next)
-        if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-            || node->pkt->pkttype == PKT_SECRET_SUBKEY)
-          node->flag |= NODFLG_SELKEY;
+       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+           || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+         node->flag |= NODFLG_SELKEY;
     }
-  else if (idx) /* Toggle selection.  */
+  else if (idx)                        /* Toggle selection.  */
     {
-      for (i=0, node = keyblock; node; node = node->next)
-        {
-          if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-              || node->pkt->pkttype == PKT_SECRET_SUBKEY)
-            if (++i == idx)
-              break;
-        }
+      for (i = 0, node = keyblock; node; node = node->next)
+       {
+         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+           if (++i == idx)
+             break;
+       }
       if (!node)
-        {
-          tty_printf (_("No subkey with index %d\n"), idx );
-          return 0;
-        }
+       {
+         tty_printf (_("No subkey with index %d\n"), idx);
+         return 0;
+       }
 
-      for (i=0, node = keyblock; node; node = node->next)
-        {
-          if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-              || node->pkt->pkttype == PKT_SECRET_SUBKEY )
-            if (++i == idx)
-              {
-                if ((node->flag & NODFLG_SELKEY))
-                  node->flag &= ~NODFLG_SELKEY;
-                else
-                  node->flag |= NODFLG_SELKEY;
-              }
-        }
+      for (i = 0, node = keyblock; node; node = node->next)
+       {
+         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+           if (++i == idx)
+             {
+               if ((node->flag & NODFLG_SELKEY))
+                 node->flag &= ~NODFLG_SELKEY;
+               else
+                 node->flag |= NODFLG_SELKEY;
+             }
+       }
     }
-  else /* Unselect all. */
+  else                         /* Unselect all. */
     {
       for (node = keyblock; node; node = node->next)
-        if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-            || node->pkt->pkttype == PKT_SECRET_SUBKEY)
-          node->flag &= ~NODFLG_SELKEY;
+       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+           || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+         node->flag &= ~NODFLG_SELKEY;
     }
 
   return 1;
@@ -4728,331 +4635,352 @@ menu_select_key (KBNODE keyblock, int idx)
 
 
 static int
-count_uids_with_flag( KBNODE keyblock, unsigned flag )
+count_uids_with_flag (KBNODE keyblock, unsigned flag)
 {
-    KBNODE node;
-    int i=0;
+  KBNODE node;
+  int i = 0;
 
-    for( node = keyblock; node; node = node->next )
-       if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
-           i++;
-    return i;
+  for (node = keyblock; node; node = node->next)
+    if (node->pkt->pkttype == PKT_USER_ID && (node->flag & flag))
+      i++;
+  return i;
 }
 
+
 static int
-count_keys_with_flag( KBNODE keyblock, unsigned flag )
+count_keys_with_flag (KBNODE keyblock, unsigned flag)
 {
-    KBNODE node;
-    int i=0;
+  KBNODE node;
+  int i = 0;
 
-    for( node = keyblock; node; node = node->next )
-       if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
-           && (node->flag & flag) )
-           i++;
-    return i;
+  for (node = keyblock; node; node = node->next)
+    if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+        || node->pkt->pkttype == PKT_SECRET_SUBKEY) && (node->flag & flag))
+      i++;
+  return i;
 }
 
+
 static int
-count_uids( KBNODE keyblock )
+count_uids (KBNODE keyblock)
 {
-    KBNODE node;
-    int i=0;
+  KBNODE node;
+  int i = 0;
 
-    for( node = keyblock; node; node = node->next )
-       if( node->pkt->pkttype == PKT_USER_ID )
-           i++;
-    return i;
+  for (node = keyblock; node; node = node->next)
+    if (node->pkt->pkttype == PKT_USER_ID)
+      i++;
+  return i;
 }
 
 
-/****************
+/*
  * Returns true if there is at least one selected user id
  */
 static int
-count_selected_uids( KBNODE keyblock )
+count_selected_uids (KBNODE keyblock)
 {
-    return count_uids_with_flag( keyblock, NODFLG_SELUID);
+  return count_uids_with_flag (keyblock, NODFLG_SELUID);
 }
 
+
 static int
-count_selected_keys( KBNODE keyblock )
+count_selected_keys (KBNODE keyblock)
 {
-    return count_keys_with_flag( keyblock, NODFLG_SELKEY);
+  return count_keys_with_flag (keyblock, NODFLG_SELKEY);
 }
 
-/* returns how many real (i.e. not attribute) uids are unmarked */
+
+/* Returns how many real (i.e. not attribute) uids are unmarked.  */
 static int
-real_uids_left( KBNODE keyblock )
+real_uids_left (KBNODE keyblock)
 {
   KBNODE node;
-  int real=0;
+  int real = 0;
 
-  for(node=keyblock;node;node=node->next)
-    if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
-       !node->pkt->pkt.user_id->attrib_data)
+  for (node = keyblock; node; node = node->next)
+    if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & NODFLG_SELUID) &&
+       !node->pkt->pkt.user_id->attrib_data)
       real++;
 
   return real;
 }
 
+
 /*
  * Ask whether the signature should be revoked.  If the user commits this,
  * flag bit MARK_A is set on the signature and the user ID.
  */
 static void
-ask_revoke_sig( KBNODE keyblock, KBNODE node )
+ask_revoke_sig (KBNODE keyblock, KBNODE node)
 {
-    int doit=0;
-    PKT_user_id *uid;
-    PKT_signature *sig = node->pkt->pkt.signature;
-    KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
-
-    if( !unode ) {
-       log_error("Oops: no user ID for signature\n");
-       return;
+  int doit = 0;
+  PKT_user_id *uid;
+  PKT_signature *sig = node->pkt->pkt.signature;
+  KBNODE unode = find_prev_kbnode (keyblock, node, PKT_USER_ID);
+
+  if (!unode)
+    {
+      log_error ("Oops: no user ID for signature\n");
+      return;
     }
 
-    uid=unode->pkt->pkt.user_id;
+  uid = unode->pkt->pkt.user_id;
 
-    if(opt.with_colons)
-      {
-       if(uid->attrib_data)
-         printf("uat:::::::::%u %lu",uid->numattribs,uid->attrib_len);
-       else
-         {
-           printf("uid:::::::::");
-           print_string (stdout, uid->name, uid->len, ':');
-         }
+  if (opt.with_colons)
+    {
+      if (uid->attrib_data)
+       printf ("uat:::::::::%u %lu", uid->numattribs, uid->attrib_len);
+      else
+       {
+         printf ("uid:::::::::");
+         es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
+       }
 
-       printf("\n");
+      printf ("\n");
 
-       print_and_check_one_sig_colon(keyblock,node,NULL,NULL,NULL,NULL,1);
-      }
-    else
-      {
-       char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
-                        unode->pkt->pkt.user_id->len,0);
-       tty_printf(_("user ID: \"%s\"\n"),p);
-       xfree(p);
-
-       tty_printf(_("signed by your key %s on %s%s%s\n"),
-                  keystr(sig->keyid),datestr_from_sig(sig),
-                  sig->flags.exportable?"":_(" (non-exportable)"),"");
-      }
-    if(sig->flags.expired)
-      {
-       tty_printf(_("This signature expired on %s.\n"),
-                  expirestr_from_sig(sig));
-       /* Use a different question so we can have different help text */
-       doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
-                       _("Are you sure you still want to revoke it? (y/N) "));
-      }
-    else
-      doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
-             _("Create a revocation certificate for this signature? (y/N) "));
+      print_and_check_one_sig_colon (keyblock, node, NULL, NULL, NULL, NULL,
+                                    1);
+    }
+  else
+    {
+      char *p = utf8_to_native (unode->pkt->pkt.user_id->name,
+                               unode->pkt->pkt.user_id->len, 0);
+      tty_printf (_("user ID: \"%s\"\n"), p);
+      xfree (p);
+
+      tty_printf (_("signed by your key %s on %s%s%s\n"),
+                 keystr (sig->keyid), datestr_from_sig (sig),
+                 sig->flags.exportable ? "" : _(" (non-exportable)"), "");
+    }
+  if (sig->flags.expired)
+    {
+      tty_printf (_("This signature expired on %s.\n"),
+                 expirestr_from_sig (sig));
+      /* Use a different question so we can have different help text */
+      doit = cpr_get_answer_is_yes
+        ("ask_revoke_sig.expired",
+         _("Are you sure you still want to revoke it? (y/N) "));
+    }
+  else
+    doit = cpr_get_answer_is_yes
+      ("ask_revoke_sig.one",
+       _("Create a revocation certificate for this signature? (y/N) "));
 
-    if(doit) {
+  if (doit)
+    {
       node->flag |= NODFLG_MARK_A;
       unode->flag |= NODFLG_MARK_A;
     }
 }
 
-/****************
+
+/*
  * Display all user ids of the current public key together with signatures
  * done by one of our keys.  Then walk over all this sigs and ask the user
  * whether he wants to revoke this signature.
  * Return: True when the keyblock has changed.
  */
 static int
-menu_revsig( KBNODE keyblock )
+menu_revsig (KBNODE keyblock)
 {
-    PKT_signature *sig;
-    PKT_public_key *primary_pk;
-    KBNODE node;
-    int changed = 0;
-    int rc, any, skip=1, all=!count_selected_uids(keyblock);
-    struct revocation_reason_info *reason = NULL;
-
-    assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-
-    /* First check whether we have any signatures at all.  */
-    any = 0;
-    for (node = keyblock; node; node = node->next )
-      {
-       node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
-       if (node->pkt->pkttype == PKT_USER_ID) {
-          if (node->flag&NODFLG_SELUID || all)
-            skip = 0;
-          else
-            skip = 1;
+  PKT_signature *sig;
+  PKT_public_key *primary_pk;
+  KBNODE node;
+  int changed = 0;
+  int rc, any, skip = 1, all = !count_selected_uids (keyblock);
+  struct revocation_reason_info *reason = NULL;
+
+  assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+
+  /* First check whether we have any signatures at all.  */
+  any = 0;
+  for (node = keyblock; node; node = node->next)
+    {
+      node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         if (node->flag & NODFLG_SELUID || all)
+           skip = 0;
+         else
+           skip = 1;
        }
-       else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
-                 && ((sig = node->pkt->pkt.signature),
-                     !seckey_available(sig->keyid)     ))
-         {
-           if ((sig->sig_class&~3) == 0x10)
-             {
-                any = 1;
-                break;
-              }
-         }
-      }
+      else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
+              && ((sig = node->pkt->pkt.signature),
+                  have_secret_key_with_kid (sig->keyid)))
+       {
+         if ((sig->sig_class & ~3) == 0x10)
+           {
+             any = 1;
+             break;
+           }
+       }
+    }
 
-    if (!any)
-      {
-        tty_printf (_("Not signed by you.\n"));
-        return 0;
-      }
+  if (!any)
+    {
+      tty_printf (_("Not signed by you.\n"));
+      return 0;
+    }
 
 
-    /* FIXME: detect duplicates here  */
-    tty_printf(_("You have signed these user IDs on key %s:\n"),
-              keystr_from_pk(keyblock->pkt->pkt.public_key));
-    for( node = keyblock; node; node = node->next ) {
-       node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
-       if( node->pkt->pkttype == PKT_USER_ID ) {
-           if( node->flag&NODFLG_SELUID || all ) {
+  /* FIXME: detect duplicates here  */
+  tty_printf (_("You have signed these user IDs on key %s:\n"),
+             keystr_from_pk (keyblock->pkt->pkt.public_key));
+  for (node = keyblock; node; node = node->next)
+    {
+      node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         if (node->flag & NODFLG_SELUID || all)
+           {
              PKT_user_id *uid = node->pkt->pkt.user_id;
              /* Hmmm: Should we show only UIDs with a signature? */
-             tty_printf("     ");
-             tty_print_utf8_string( uid->name, uid->len );
-             tty_printf("\n");
-             skip=0;
+             tty_printf ("     ");
+             tty_print_utf8_string (uid->name, uid->len);
+             tty_printf ("\n");
+             skip = 0;
+           }
+         else
+           skip = 1;
+       }
+      else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
+              && ((sig = node->pkt->pkt.signature),
+                  have_secret_key_with_kid (sig->keyid)))
+       {
+         if ((sig->sig_class & ~3) == 0x10)
+           {
+             tty_printf ("   ");
+             tty_printf (_("signed by your key %s on %s%s%s\n"),
+                         keystr (sig->keyid), datestr_from_sig (sig),
+                         sig->flags.exportable ? "" : _(" (non-exportable)"),
+                         sig->flags.revocable ? "" : _(" (non-revocable)"));
+             if (sig->flags.revocable)
+               node->flag |= NODFLG_SELSIG;
+           }
+         else if (sig->sig_class == 0x30)
+           {
+             tty_printf ("   ");
+             tty_printf (_("revoked by your key %s on %s\n"),
+                         keystr (sig->keyid), datestr_from_sig (sig));
            }
-           else
-             skip=1;
        }
-       else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
-               && ((sig = node->pkt->pkt.signature),
-                     !seckey_available(sig->keyid)  ) )
-         {
-           if( (sig->sig_class&~3) == 0x10 )
-             {
-               tty_printf("   ");
-               tty_printf(_("signed by your key %s on %s%s%s\n"),
-                          keystr(sig->keyid), datestr_from_sig(sig),
-                          sig->flags.exportable?"":_(" (non-exportable)"),
-                          sig->flags.revocable?"":_(" (non-revocable)"));
-               if(sig->flags.revocable)
-                 node->flag |= NODFLG_SELSIG;
-             }
-           else if( sig->sig_class == 0x30 )
-             {
-               tty_printf("   ");
-               tty_printf(_("revoked by your key %s on %s\n"),
-                          keystr(sig->keyid),datestr_from_sig(sig));
-             }
-         }
     }
 
-    tty_printf("\n");
+  tty_printf ("\n");
 
-    /* ask */
-    for( node = keyblock; node; node = node->next ) {
-       if( !(node->flag & NODFLG_SELSIG) )
-           continue;
-       ask_revoke_sig( keyblock, node );
+  /* ask */
+  for (node = keyblock; node; node = node->next)
+    {
+      if (!(node->flag & NODFLG_SELSIG))
+       continue;
+      ask_revoke_sig (keyblock, node);
     }
 
-    /* present selected */
-    any = 0;
-    for( node = keyblock; node; node = node->next ) {
-       if( !(node->flag & NODFLG_MARK_A) )
-           continue;
-       if( !any ) {
-           any = 1;
-           tty_printf(_("You are about to revoke these signatures:\n"));
+  /* present selected */
+  any = 0;
+  for (node = keyblock; node; node = node->next)
+    {
+      if (!(node->flag & NODFLG_MARK_A))
+       continue;
+      if (!any)
+       {
+         any = 1;
+         tty_printf (_("You are about to revoke these signatures:\n"));
        }
-       if( node->pkt->pkttype == PKT_USER_ID ) {
-           PKT_user_id *uid = node->pkt->pkt.user_id;
-           tty_printf("     ");
-           tty_print_utf8_string( uid->name, uid->len );
-           tty_printf("\n");
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         PKT_user_id *uid = node->pkt->pkt.user_id;
+         tty_printf ("     ");
+         tty_print_utf8_string (uid->name, uid->len);
+         tty_printf ("\n");
        }
-       else if( node->pkt->pkttype == PKT_SIGNATURE ) {
-           sig = node->pkt->pkt.signature;
-           tty_printf("   ");
-           tty_printf(_("signed by your key %s on %s%s%s\n"),
-                      keystr(sig->keyid), datestr_from_sig(sig),"",
-                      sig->flags.exportable?"":_(" (non-exportable)") );
+      else if (node->pkt->pkttype == PKT_SIGNATURE)
+       {
+         sig = node->pkt->pkt.signature;
+         tty_printf ("   ");
+         tty_printf (_("signed by your key %s on %s%s%s\n"),
+                     keystr (sig->keyid), datestr_from_sig (sig), "",
+                     sig->flags.exportable ? "" : _(" (non-exportable)"));
        }
     }
-    if( !any )
-       return 0; /* none selected */
+  if (!any)
+    return 0;                  /* none selected */
 
-    if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
-        _("Really create the revocation certificates? (y/N) ")) )
-       return 0; /* forget it */
+  if (!cpr_get_answer_is_yes
+      ("ask_revoke_sig.okay",
+       _("Really create the revocation certificates? (y/N) ")))
+    return 0;                  /* forget it */
 
-    reason = ask_revocation_reason( 0, 1, 0 );
-    if( !reason ) { /* user decided to cancel */
-       return 0;
+  reason = ask_revocation_reason (0, 1, 0);
+  if (!reason)
+    {                          /* user decided to cancel */
+      return 0;
     }
 
-    /* now we can sign the user ids */
-  reloop: /* (must use this, because we are modifing the list) */
-    primary_pk = keyblock->pkt->pkt.public_key;
-    for( node=keyblock; node; node = node->next ) {
-       KBNODE unode;
-       PACKET *pkt;
-       struct sign_attrib attrib;
-       PKT_secret_key *sk;
-
-       if( !(node->flag & NODFLG_MARK_A)
-           || node->pkt->pkttype != PKT_SIGNATURE )
-           continue;
-       unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
-       assert( unode ); /* we already checked this */
+  /* now we can sign the user ids */
+reloop:                        /* (must use this, because we are modifing the list) */
+  primary_pk = keyblock->pkt->pkt.public_key;
+  for (node = keyblock; node; node = node->next)
+    {
+      KBNODE unode;
+      PACKET *pkt;
+      struct sign_attrib attrib;
+      PKT_public_key *signerkey;
+
+      if (!(node->flag & NODFLG_MARK_A)
+         || node->pkt->pkttype != PKT_SIGNATURE)
+       continue;
+      unode = find_prev_kbnode (keyblock, node, PKT_USER_ID);
+      assert (unode);          /* we already checked this */
 
-       memset( &attrib, 0, sizeof attrib );
-       attrib.reason = reason;
-       attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
+      memset (&attrib, 0, sizeof attrib);
+      attrib.reason = reason;
+      attrib.non_exportable = !node->pkt->pkt.signature->flags.exportable;
 
-       node->flag &= ~NODFLG_MARK_A;
-       sk = xmalloc_secure_clear( sizeof *sk );
-       if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
-           log_info(_("no secret key\n"));
-           continue;
+      node->flag &= ~NODFLG_MARK_A;
+      signerkey = xmalloc_secure_clear (sizeof *signerkey);
+      if (get_seckey (signerkey, node->pkt->pkt.signature->keyid))
+       {
+         log_info (_("no secret key\n"));
+          free_public_key (signerkey);
+         continue;
        }
-       rc = make_keysig_packet( &sig, primary_pk,
-                                      unode->pkt->pkt.user_id,
-                                      NULL,
-                                      sk,
-                                      0x30, 0, 0, 0, 0,
-                                      sign_mk_attrib,
-                                      &attrib );
-       free_secret_key(sk);
-       if( rc ) {
-           log_error(_("signing failed: %s\n"), g10_errstr(rc));
-           release_revocation_reason_info( reason );
-           return changed;
+      rc = make_keysig_packet (&sig, primary_pk,
+                              unode->pkt->pkt.user_id,
+                              NULL, signerkey, 0x30, 0, 0, 0,
+                               sign_mk_attrib, &attrib, NULL);
+      free_public_key (signerkey);
+      if (rc)
+       {
+         log_error (_("signing failed: %s\n"), g10_errstr (rc));
+         release_revocation_reason_info (reason);
+         return changed;
        }
-       changed = 1; /* we changed the keyblock */
-       update_trust = 1;
-       /* Are we revoking our own uid? */
-       if(primary_pk->keyid[0]==sig->keyid[0] &&
-          primary_pk->keyid[1]==sig->keyid[1])
-         unode->pkt->pkt.user_id->is_revoked=1;
-       pkt = xmalloc_clear( sizeof *pkt );
-       pkt->pkttype = PKT_SIGNATURE;
-       pkt->pkt.signature = sig;
-       insert_kbnode( unode, new_kbnode(pkt), 0 );
-       goto reloop;
+      changed = 1;             /* we changed the keyblock */
+      update_trust = 1;
+      /* Are we revoking our own uid? */
+      if (primary_pk->keyid[0] == sig->keyid[0] &&
+         primary_pk->keyid[1] == sig->keyid[1])
+       unode->pkt->pkt.user_id->is_revoked = 1;
+      pkt = xmalloc_clear (sizeof *pkt);
+      pkt->pkttype = PKT_SIGNATURE;
+      pkt->pkt.signature = sig;
+      insert_kbnode (unode, new_kbnode (pkt), 0);
+      goto reloop;
     }
 
-    release_revocation_reason_info( reason );
-    return changed;
+  release_revocation_reason_info (reason);
+  return changed;
 }
 
+
 /* Revoke a user ID (i.e. revoke a user ID selfsig).  Return true if
-   keyblock changed. */
+   keyblock changed.  */
 static int
-menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_revuid (KBNODE pub_keyblock)
 {
   PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
-  PKT_secret_key *sk = copy_secret_key( NULL,
-                                       sec_keyblock->pkt->pkt.secret_key );
   KBNODE node;
   int changed = 0;
   int rc;
@@ -5063,268 +4991,271 @@ menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
      sig class, but PGP 2.x did not actually implement it, so it would
      probably be safe to use v4 revocations everywhere. -ds */
 
-  for( node = pub_keyblock; node; node = node->next )
-    if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
-                        node->pkt->pkt.user_id->selfsigversion>3))
+  for (node = pub_keyblock; node; node = node->next)
+    if (pk->version > 3 || (node->pkt->pkttype == PKT_USER_ID &&
+                           node->pkt->pkt.user_id->selfsigversion > 3))
       {
-       if((reason = ask_revocation_reason( 0, 1, 4 )))
+       if ((reason = ask_revocation_reason (0, 1, 4)))
          break;
        else
          goto leave;
       }
 
  reloop: /* (better this way because we are modifing the keyring) */
-  for( node = pub_keyblock; node; node = node->next )
-    if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
+  for (node = pub_keyblock; node; node = node->next)
+    if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
       {
-       PKT_user_id *uid=node->pkt->pkt.user_id;
+       PKT_user_id *uid = node->pkt->pkt.user_id;
 
-       if(uid->is_revoked)
+       if (uid->is_revoked)
          {
-           char *user=utf8_to_native(uid->name,uid->len,0);
-           log_info(_("user ID \"%s\" is already revoked\n"),user);
-           xfree(user);
+           char *user = utf8_to_native (uid->name, uid->len, 0);
+           log_info (_("user ID \"%s\" is already revoked\n"), user);
+           xfree (user);
          }
        else
          {
            PACKET *pkt;
            PKT_signature *sig;
            struct sign_attrib attrib;
-           u32 timestamp=make_timestamp();
+           u32 timestamp = make_timestamp ();
 
-           if(uid->created>=timestamp)
+           if (uid->created >= timestamp)
              {
                /* Okay, this is a problem.  The user ID selfsig was
                   created in the future, so we need to warn the user and
                   set our revocation timestamp one second after that so
                   everything comes out clean. */
 
-               log_info(_("WARNING: a user ID signature is dated %d"
-                          " seconds in the future\n"),uid->created-timestamp);
+               log_info (_("WARNING: a user ID signature is dated %d"
+                           " seconds in the future\n"),
+                         uid->created - timestamp);
 
-               timestamp=uid->created+1;
+               timestamp = uid->created + 1;
              }
 
-           memset( &attrib, 0, sizeof attrib );
+           memset (&attrib, 0, sizeof attrib);
            attrib.reason = reason;
 
            node->flag &= ~NODFLG_SELUID;
 
-           rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
-                                    (reason==NULL)?3:0, timestamp, 0,
-                                    sign_mk_attrib, &attrib );
-           if( rc )
+           rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0,
+                                    timestamp, 0,
+                                    sign_mk_attrib, &attrib, NULL);
+           if (rc)
              {
-               log_error(_("signing failed: %s\n"), g10_errstr(rc));
+               log_error (_("signing failed: %s\n"), g10_errstr (rc));
                goto leave;
              }
            else
              {
-               pkt = xmalloc_clear( sizeof *pkt );
+               pkt = xmalloc_clear (sizeof *pkt);
                pkt->pkttype = PKT_SIGNATURE;
                pkt->pkt.signature = sig;
-               insert_kbnode( node, new_kbnode(pkt), 0 );
+               insert_kbnode (node, new_kbnode (pkt), 0);
 
+#ifndef NO_TRUST_MODELS
                /* If the trustdb has an entry for this key+uid then the
                   trustdb needs an update. */
-               if(!update_trust
-                  && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
-                 update_trust=1;
+               if (!update_trust
+                   && (get_validity (pk, uid) & TRUST_MASK) >=
+                   TRUST_UNDEFINED)
+                 update_trust = 1;
+#endif /*!NO_TRUST_MODELS*/
 
                changed = 1;
-               node->pkt->pkt.user_id->is_revoked=1;
+               node->pkt->pkt.user_id->is_revoked = 1;
 
                goto reloop;
              }
          }
       }
 
-  if(changed)
-    commit_kbnode( &pub_keyblock );
+  if (changed)
+    commit_kbnode (&pub_keyblock);
 
- leave:
-  free_secret_key(sk);
-  release_revocation_reason_info( reason );
+leave:
+  release_revocation_reason_info (reason);
   return changed;
 }
 
-/****************
+
+/*
  * Revoke the whole key.
  */
 static int
-menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_revkey (KBNODE pub_keyblock)
 {
-  PKT_public_key *pk=pub_keyblock->pkt->pkt.public_key;
-  PKT_secret_key *sk;
-  int rc,changed = 0;
+  PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
+  int rc, changed = 0;
   struct revocation_reason_info *reason;
   PACKET *pkt;
   PKT_signature *sig;
 
-  if(pk->is_revoked)
+  if (pk->flags.revoked)
     {
-      tty_printf(_("Key %s is already revoked.\n"),keystr_from_pk(pk));
+      tty_printf (_("Key %s is already revoked.\n"), keystr_from_pk (pk));
       return 0;
     }
 
-  reason = ask_revocation_reason( 1, 0, 0 );
+  reason = ask_revocation_reason (1, 0, 0);
   /* user decided to cancel */
-  if( !reason )
+  if (!reason)
     return 0;
 
-  sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
-  rc = make_keysig_packet( &sig, pk, NULL, NULL, sk,
-                          0x20, 0, opt.force_v4_certs?4:0, 0, 0,
-                          revocation_reason_build_cb, reason );
-  free_secret_key(sk);
-  if( rc )
+  rc = make_keysig_packet (&sig, pk, NULL, NULL, pk,
+                          0x20, 0, 0, 0,
+                          revocation_reason_build_cb, reason, NULL);
+  if (rc)
     {
-      log_error(_("signing failed: %s\n"), g10_errstr(rc));
+      log_error (_("signing failed: %s\n"), g10_errstr (rc));
       goto scram;
     }
 
-  changed = 1; /* we changed the keyblock */
+  changed = 1;                 /* we changed the keyblock */
 
-  pkt = xmalloc_clear( sizeof *pkt );
+  pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
-  insert_kbnode( pub_keyblock, new_kbnode(pkt), 0 );
-  commit_kbnode( &pub_keyblock );
+  insert_kbnode (pub_keyblock, new_kbnode (pkt), 0);
+  commit_kbnode (&pub_keyblock);
 
-  update_trust=1;
+  update_trust = 1;
 
  scram:
-  release_revocation_reason_info( reason );
+  release_revocation_reason_info (reason);
   return changed;
 }
 
+
 static int
-menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_revsubkey (KBNODE pub_keyblock)
 {
-    PKT_public_key *mainpk;
-    KBNODE node;
-    int changed = 0;
-    int rc;
-    struct revocation_reason_info *reason = NULL;
-
-    reason = ask_revocation_reason( 1, 0, 0 );
-    if( !reason ) { /* user decided to cancel */
-       return 0;
-    }
+  PKT_public_key *mainpk;
+  KBNODE node;
+  int changed = 0;
+  int rc;
+  struct revocation_reason_info *reason = NULL;
 
-  reloop: /* (better this way because we are modifing the keyring) */
-    mainpk = pub_keyblock->pkt->pkt.public_key;
-    for( node = pub_keyblock; node; node = node->next ) {
-       if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-           && (node->flag & NODFLG_SELKEY) ) {
-           PACKET *pkt;
-           PKT_signature *sig;
-           PKT_secret_key *sk;
-           PKT_public_key *subpk = node->pkt->pkt.public_key;
-           struct sign_attrib attrib;
+  reason = ask_revocation_reason (1, 0, 0);
+  if (!reason)
+      return 0; /* User decided to cancel.  */
 
-           if(subpk->is_revoked)
-             {
-               tty_printf(_("Subkey %s is already revoked.\n"),
-                          keystr_from_pk(subpk));
-               continue;
-             }
+ reloop: /* (better this way because we are modifing the keyring) */
+  mainpk = pub_keyblock->pkt->pkt.public_key;
+  for (node = pub_keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+         && (node->flag & NODFLG_SELKEY))
+       {
+         PACKET *pkt;
+         PKT_signature *sig;
+         PKT_public_key *subpk = node->pkt->pkt.public_key;
+         struct sign_attrib attrib;
 
-           memset( &attrib, 0, sizeof attrib );
-           attrib.reason = reason;
+         if (subpk->flags.revoked)
+           {
+             tty_printf (_("Subkey %s is already revoked.\n"),
+                         keystr_from_pk (subpk));
+             continue;
+           }
+
+         memset (&attrib, 0, sizeof attrib);
+         attrib.reason = reason;
 
-           node->flag &= ~NODFLG_SELKEY;
-           sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
-           rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
-                                     0x28, 0, 0, 0, 0,
-                                    sign_mk_attrib, &attrib );
-           free_secret_key(sk);
-           if( rc ) {
-               log_error(_("signing failed: %s\n"), g10_errstr(rc));
-               release_revocation_reason_info( reason );
-               return changed;
+         node->flag &= ~NODFLG_SELKEY;
+         rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk,
+                                  0x28, 0, 0, 0, sign_mk_attrib, &attrib,
+                                   NULL);
+         if (rc)
+           {
+             log_error (_("signing failed: %s\n"), g10_errstr (rc));
+             release_revocation_reason_info (reason);
+             return changed;
            }
-           changed = 1; /* we changed the keyblock */
+         changed = 1;          /* we changed the keyblock */
 
-           pkt = xmalloc_clear( sizeof *pkt );
-           pkt->pkttype = PKT_SIGNATURE;
-           pkt->pkt.signature = sig;
-           insert_kbnode( node, new_kbnode(pkt), 0 );
-           goto reloop;
+         pkt = xmalloc_clear (sizeof *pkt);
+         pkt->pkttype = PKT_SIGNATURE;
+         pkt->pkt.signature = sig;
+         insert_kbnode (node, new_kbnode (pkt), 0);
+         goto reloop;
        }
     }
-    commit_kbnode( &pub_keyblock );
-    /*commit_kbnode( &sec_keyblock );*/
+  commit_kbnode (&pub_keyblock);
 
-    /* No need to set update_trust here since signing keys no longer
-       are used to certify other keys, so there is no change in trust
-       when revoking/removing them */
+  /* No need to set update_trust here since signing keys no longer
+     are used to certify other keys, so there is no change in trust
+     when revoking/removing them */
 
-    release_revocation_reason_info( reason );
-    return changed;
+  release_revocation_reason_info (reason);
+  return changed;
 }
 
+
 /* Note that update_ownertrust is going to mark the trustdb dirty when
    enabling or disabling a key.  This is arguably sub-optimal as
    disabled keys are still counted in the web of trust, but perhaps
    not worth adding extra complexity to change. -ds */
+#ifndef NO_TRUST_MODELS
 static int
-enable_disable_key( KBNODE keyblock, int disable )
+enable_disable_key (KBNODE keyblock, int disable)
 {
-    PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
-                           ->pkt->pkt.public_key;
-    unsigned int trust, newtrust;
-
-    trust = newtrust = get_ownertrust (pk);
-    newtrust &= ~TRUST_FLAG_DISABLED;
-    if( disable )
-       newtrust |= TRUST_FLAG_DISABLED;
-    if( trust == newtrust )
-       return 0; /* already in that state */
-    update_ownertrust(pk, newtrust );
-    return 0;
+  PKT_public_key *pk =
+    find_kbnode (keyblock, PKT_PUBLIC_KEY)->pkt->pkt.public_key;
+  unsigned int trust, newtrust;
+
+  trust = newtrust = get_ownertrust (pk);
+  newtrust &= ~TRUST_FLAG_DISABLED;
+  if (disable)
+    newtrust |= TRUST_FLAG_DISABLED;
+  if (trust == newtrust)
+    return 0;                  /* already in that state */
+  update_ownertrust (pk, newtrust);
+  return 0;
 }
+#endif /*!NO_TRUST_MODELS*/
 
 
 static void
-menu_showphoto( KBNODE keyblock )
+menu_showphoto (KBNODE keyblock)
 {
   KBNODE node;
-  int select_all = !count_selected_uids(keyblock);
-  int count=0;
-  PKT_public_key *pk=NULL;
+  int select_all = !count_selected_uids (keyblock);
+  int count = 0;
+  PKT_public_key *pk = NULL;
 
   /* Look for the public key first.  We have to be really, really,
      explicit as to which photo this is, and what key it is a UID on
      since people may want to sign it. */
 
-  for( node = keyblock; node; node = node->next )
+  for (node = keyblock; node; node = node->next)
     {
-      if( node->pkt->pkttype == PKT_PUBLIC_KEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        pk = node->pkt->pkt.public_key;
-      else if( node->pkt->pkttype == PKT_USER_ID )
+      else if (node->pkt->pkttype == PKT_USER_ID)
        {
          PKT_user_id *uid = node->pkt->pkt.user_id;
          count++;
 
-         if((select_all || (node->flag & NODFLG_SELUID)) &&
-            uid->attribs!=NULL)
+         if ((select_all || (node->flag & NODFLG_SELUID)) &&
+             uid->attribs != NULL)
            {
              int i;
 
-             for(i=0;i<uid->numattribs;i++)
+             for (i = 0; i < uid->numattribs; i++)
                {
                  byte type;
                  u32 size;
 
-                 if(uid->attribs[i].type==ATTRIB_IMAGE &&
-                    parse_image_header(&uid->attribs[i],&type,&size))
+                 if (uid->attribs[i].type == ATTRIB_IMAGE &&
+                     parse_image_header (&uid->attribs[i], &type, &size))
                    {
-                     tty_printf(_("Displaying %s photo ID of size %ld for "
-                                  "key %s (uid %d)\n"),
-                                image_type_to_string(type,1),
-                                (ulong)size,keystr_from_pk(pk),count);
-                     show_photos(&uid->attribs[i],1,pk,NULL,uid);
+                     tty_printf (_("Displaying %s photo ID of size %ld for "
+                                   "key %s (uid %d)\n"),
+                                 image_type_to_string (type, 1),
+                                 (ulong) size, keystr_from_pk (pk), count);
+                     show_photos (&uid->attribs[i], 1, pk, uid);
                    }
                }
            }
index 1ad39bf..2610af5 100644 (file)
@@ -1,6 +1,7 @@
 /* keygen.c - generate a key pair
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ *               2007, 2009, 2010, 2011  Free Software Foundation, Inc.
+ * Copyright (C) 2014  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -33,7 +34,6 @@
 #include "util.h"
 #include "main.h"
 #include "packet.h"
-#include "cipher.h"
 #include "ttyio.h"
 #include "options.h"
 #include "keydb.h"
 #include "i18n.h"
 #include "keyserver-internal.h"
 #include "call-agent.h"
-#include "host2net.h"
+#include "pkglue.h"
 
 /* The default algorithms.  If you change them remember to change them
    also in gpg.c:gpgconf_list.  You should also check that the value
    is inside the bounds enforced by ask_keysize and gen_xxx.  */
-#define DEFAULT_STD_ALGO    GCRY_PK_RSA
-#define DEFAULT_STD_KEYSIZE 2048
-
-
+#define DEFAULT_STD_ALGO       PUBKEY_ALGO_RSA
+#define DEFAULT_STD_KEYSIZE    2048
+#define DEFAULT_STD_CURVE      NULL
+#define DEFAULT_STD_SUBALGO    PUBKEY_ALGO_RSA
+#define DEFAULT_STD_SUBKEYSIZE 2048
+#define DEFAULT_STD_SUBCURVE   NULL
+
+/* Flag bits used during key generation.  */
+#define KEYGEN_FLAG_NO_PROTECTION 1
+#define KEYGEN_FLAG_TRANSIENT_KEY 2
+
+/* Maximum number of supported algorithm preferences.  */
 #define MAX_PREFS 30
 
 enum para_name {
   pKEYTYPE,
   pKEYLENGTH,
+  pKEYCURVE,
   pKEYUSAGE,
   pSUBKEYTYPE,
   pSUBKEYLENGTH,
+  pSUBKEYCURVE,
   pSUBKEYUSAGE,
   pAUTHKEYTYPE,
   pNAMEREAL,
@@ -73,10 +83,8 @@ enum para_name {
   pKEYEXPIRE, /* in n seconds */
   pSUBKEYEXPIRE, /* in n seconds */
   pPASSPHRASE,
-  pPASSPHRASE_DEK,
-  pPASSPHRASE_S2K,
   pSERIALNO,
-  pBACKUPENCDIR,
+  pCARDBACKUPKEY,
   pHANDLE,
   pKEYSERVER
 };
@@ -86,8 +94,6 @@ struct para_data_s {
     int lnr;
     enum para_name key;
     union {
-        DEK *dek;
-        STRING2KEY *s2k;
         u32 expire;
         u32 creation;
         unsigned int usage;
@@ -96,23 +102,18 @@ struct para_data_s {
     } u;
 };
 
-struct output_control_s {
-    int lnr;
-    int dryrun;
-    int ask_passphrase;
-    int use_files;
-    struct {
-       char  *fname;
-       char  *newfname;
-       IOBUF stream;
-       armor_filter_context_t *afx;
-    } pub;
-    struct {
-       char  *fname;
-       char  *newfname;
-       IOBUF stream;
-       armor_filter_context_t *afx;
-    } sec;
+struct output_control_s
+{
+  int lnr;
+  int dryrun;
+  unsigned int keygen_flags;
+  int use_files;
+  struct {
+    char  *fname;
+    char  *newfname;
+    IOBUF stream;
+    armor_filter_context_t *afx;
+  } pub;
 };
 
 
@@ -133,17 +134,13 @@ static int mdc_available,ks_modify;
 
 static void do_generate_keypair( struct para_data_s *para,
                                 struct output_control_s *outctrl, int card );
-static int  write_keyblock( IOBUF out, KBNODE node );
-static int gen_card_key (int algo, int keyno, int is_primary,
-                         KBNODE pub_root, KBNODE sec_root,
-                        PKT_secret_key **ret_sk,
-                         u32 *timestamp,
-                         u32 expireval, struct para_data_s *para);
+static int write_keyblock (iobuf_t out, kbnode_t node);
+static gpg_error_t gen_card_key (int algo, int keyno, int is_primary,
+                                 kbnode_t pub_root,
+                                 u32 *timestamp, u32 expireval);
 static int gen_card_key_with_backup (int algo, int keyno, int is_primary,
-                                     KBNODE pub_root, KBNODE sec_root,
-                                     u32 timestamp,
-                                     u32 expireval, struct para_data_s *para,
-                                     const char *backup_dir);
+                                     kbnode_t pub_root, u32 timestamp,
+                                     u32 expireval, struct para_data_s *para);
 
 
 static void
@@ -225,43 +222,46 @@ do_add_key_flags (PKT_signature *sig, unsigned int use)
 
 
 int
-keygen_add_key_expire( PKT_signature *sig, void *opaque )
+keygen_add_key_expire (PKT_signature *sig, void *opaque)
 {
-    PKT_public_key *pk = opaque;
-    byte buf[8];
-    u32  u;
+  PKT_public_key *pk = opaque;
+  byte buf[8];
+  u32  u;
 
-    if( pk->expiredate ) {
-        if(pk->expiredate > pk->timestamp)
-         u= pk->expiredate - pk->timestamp;
-       else
-         u= 1;
+  if (pk->expiredate)
+    {
+      if (pk->expiredate > pk->timestamp)
+        u = pk->expiredate - pk->timestamp;
+      else
+        u = 1;
 
-       buf[0] = (u >> 24) & 0xff;
-       buf[1] = (u >> 16) & 0xff;
-       buf[2] = (u >>  8) & 0xff;
-       buf[3] = u & 0xff;
-       build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 );
+      buf[0] = (u >> 24) & 0xff;
+      buf[1] = (u >> 16) & 0xff;
+      buf[2] = (u >>   8) & 0xff;
+      buf[3] = u & 0xff;
+      build_sig_subpkt (sig, SIGSUBPKT_KEY_EXPIRE, buf, 4);
+    }
+  else
+    {
+      /* Make sure we don't leave a key expiration subpacket lying
+         around */
+      delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE);
     }
-    else
-      {
-       /* Make sure we don't leave a key expiration subpacket lying
-          around */
-       delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE);
-      }
 
-    return 0;
+  return 0;
 }
 
+
 static int
 keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque)
 {
-    struct opaque_data_usage_and_pk *oduap = opaque;
+  struct opaque_data_usage_and_pk *oduap = opaque;
 
-    do_add_key_flags (sig, oduap->usage);
-    return keygen_add_key_expire (sig, oduap->pk);
+  do_add_key_flags (sig, oduap->usage);
+  return keygen_add_key_expire (sig, oduap->pk);
 }
 
+
 static int
 set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf)
 {
@@ -270,7 +270,7 @@ set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf)
     for (i=0; i < *nbuf; i++ )
       if (buf[i] == val)
        {
-         log_info (_("preference `%s' duplicated\n"), item);
+         log_info (_("preference '%s' duplicated\n"), item);
          return -1;
         }
 
@@ -313,6 +313,7 @@ keygen_set_std_prefs (const char *string,int personal)
          string=opt.def_preference_list;
        else
          {
+            int any_compress = 0;
            dummy_string[0]='\0';
 
             /* The rationale why we use the order AES256,192,128 is
@@ -336,33 +337,14 @@ keygen_set_std_prefs (const char *string,int personal)
              strcat(dummy_string,"S8 ");
            if ( !openpgp_cipher_test_algo (CIPHER_ALGO_AES) )
              strcat(dummy_string,"S7 ");
-           if ( !openpgp_cipher_test_algo (CIPHER_ALGO_CAST5) )
-             strcat(dummy_string,"S3 ");
            strcat(dummy_string,"S2 "); /* 3DES */
-           /* If we have it, IDEA goes *after* 3DES so it won't be
-              used unless we're encrypting along with a V3 key.
-              Ideally, we would only put the S1 preference in if the
-              key was RSA and <=2048 bits, as that is what won't
-              break PGP2, but that is difficult with the current
-              code, and not really worth checking as a non-RSA <=2048
-              bit key wouldn't be usable by PGP2 anyway. -dms */
-           if ( !openpgp_cipher_test_algo (CIPHER_ALGO_IDEA) )
-             strcat(dummy_string,"S1 ");
-
 
             /* The default hash algo order is:
-                 SHA-256, SHA-1, SHA-384, SHA-512, SHA-224.
-               Ordering SHA-1 before SHA-384 might be viewed as a bit
-               strange; it is done because we expect that soon enough
-               SHA-3 will be available and at that point there should
-               be no more need for SHA-384 etc.  Anyway this order is
-               just a default and can easily be changed by a config
-               option.  */
+                 SHA-256, SHA-384, SHA-512, SHA-224, SHA-1.
+             */
            if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256))
              strcat (dummy_string, "H8 ");
 
-           strcat (dummy_string, "H2 "); /* SHA-1 */
-
            if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384))
              strcat (dummy_string, "H9 ");
 
@@ -372,15 +354,34 @@ keygen_set_std_prefs (const char *string,int personal)
            if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224))
              strcat (dummy_string, "H11 ");
 
+           strcat (dummy_string, "H2 "); /* SHA-1 */
 
-           /* ZLIB */
-           strcat(dummy_string,"Z2 ");
+           if(!check_compress_algo(COMPRESS_ALGO_ZLIB))
+              {
+                strcat(dummy_string,"Z2 ");
+                any_compress = 1;
+              }
 
            if(!check_compress_algo(COMPRESS_ALGO_BZIP2))
-             strcat(dummy_string,"Z3 ");
-
-           /* ZIP */
-           strcat(dummy_string,"Z1");
+              {
+                strcat(dummy_string,"Z3 ");
+                any_compress = 1;
+              }
+
+           if(!check_compress_algo(COMPRESS_ALGO_ZIP))
+              {
+                strcat(dummy_string,"Z1 ");
+                any_compress = 1;
+              }
+
+            /* In case we have no compress algo at all, declare that
+               we prefer no compresssion.  */
+            if (!any_compress)
+              strcat(dummy_string,"Z0 ");
+
+            /* Remove the trailing space.  */
+            if (*dummy_string && dummy_string[strlen (dummy_string)-1] == ' ')
+              dummy_string[strlen (dummy_string)-1] = 0;
 
            string=dummy_string;
          }
@@ -421,13 +422,7 @@ keygen_set_std_prefs (const char *string,int personal)
              modify=0;
            else
              {
-               log_info (_("invalid item `%s' in preference string\n"),tok);
-
-               /* Complain if IDEA is not available. */
-               if(ascii_strcasecmp(tok,"s1")==0
-                  || ascii_strcasecmp(tok,"idea")==0)
-                 idea_cipher_warn(1);
-
+               log_info (_("invalid item '%s' in preference string\n"),tok);
                rc=-1;
              }
          }
@@ -696,19 +691,18 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque)
 /****************
  * Add preference to the self signature packet.
  * This is only called for packets with version > 3.
-
  */
 int
-keygen_add_std_prefs( PKT_signature *sig, void *opaque )
+keygen_add_std_prefs (PKT_signature *sig, void *opaque)
 {
-    PKT_public_key *pk = opaque;
+  PKT_public_key *pk = opaque;
 
-    do_add_key_flags (sig, pk->pubkey_usage);
-    keygen_add_key_expire( sig, opaque );
-    keygen_upd_std_prefs (sig, opaque);
-    keygen_add_keyserver_url(sig,NULL);
+  do_add_key_flags (sig, pk->pubkey_usage);
+  keygen_add_key_expire (sig, opaque );
+  keygen_upd_std_prefs (sig, opaque);
+  keygen_add_keyserver_url (sig,NULL);
 
-    return 0;
+  return 0;
 }
 
 int
@@ -777,23 +771,23 @@ keygen_add_notations(PKT_signature *sig,void *opaque)
 }
 
 int
-keygen_add_revkey(PKT_signature *sig, void *opaque)
+keygen_add_revkey (PKT_signature *sig, void *opaque)
 {
-  struct revocation_key *revkey=opaque;
+  struct revocation_key *revkey = opaque;
   byte buf[2+MAX_FINGERPRINT_LEN];
 
-  buf[0]=revkey->class;
-  buf[1]=revkey->algid;
-  memcpy(&buf[2],revkey->fpr,MAX_FINGERPRINT_LEN);
+  buf[0] = revkey->class;
+  buf[1] = revkey->algid;
+  memcpy (&buf[2], revkey->fpr, MAX_FINGERPRINT_LEN);
 
-  build_sig_subpkt(sig,SIGSUBPKT_REV_KEY,buf,2+MAX_FINGERPRINT_LEN);
+  build_sig_subpkt (sig, SIGSUBPKT_REV_KEY, buf, 2+MAX_FINGERPRINT_LEN);
 
-  /* All sigs with revocation keys set are nonrevocable */
-  sig->flags.revocable=0;
+  /* All sigs with revocation keys set are nonrevocable */
+  sig->flags.revocable = 0;
   buf[0] = 0;
-  build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
+  build_sig_subpkt (sig, SIGSUBPKT_REVOCABLE, buf, 1);
 
-  parse_revkeys(sig);
+  parse_revkeys (sig);
 
   return 0;
 }
@@ -802,72 +796,75 @@ keygen_add_revkey(PKT_signature *sig, void *opaque)
 
 /* Create a back-signature.  If TIMESTAMP is not NULL, use it for the
    signature creation time.  */
-int
-make_backsig (PKT_signature *sig,PKT_public_key *pk,
-              PKT_public_key *sub_pk,PKT_secret_key *sub_sk,
-              u32 timestamp)
+gpg_error_t
+make_backsig (PKT_signature *sig, PKT_public_key *pk,
+              PKT_public_key *sub_pk, PKT_public_key *sub_psk,
+              u32 timestamp, const char *cache_nonce)
 {
+  gpg_error_t err;
   PKT_signature *backsig;
-  int rc;
 
-  cache_public_key(sub_pk);
+  cache_public_key (sub_pk);
 
-  rc = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_sk, 0x19,
-                           0, 0, timestamp, 0, NULL, NULL);
-  if(rc)
-    log_error("make_keysig_packet failed for backsig: %s\n",g10_errstr(rc));
+  err = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_psk, 0x19,
+                            0, timestamp, 0, NULL, NULL, cache_nonce);
+  if (err)
+    log_error ("make_keysig_packet failed for backsig: %s\n", g10_errstr(err));
   else
     {
       /* Get it into a binary packed form. */
-      IOBUF backsig_out=iobuf_temp();
+      IOBUF backsig_out = iobuf_temp();
       PACKET backsig_pkt;
 
-      init_packet(&backsig_pkt);
-      backsig_pkt.pkttype=PKT_SIGNATURE;
-      backsig_pkt.pkt.signature=backsig;
-      rc=build_packet(backsig_out,&backsig_pkt);
-      free_packet(&backsig_pkt);
-      if(rc)
-       log_error("build_packet failed for backsig: %s\n",g10_errstr(rc));
+      init_packet (&backsig_pkt);
+      backsig_pkt.pkttype = PKT_SIGNATURE;
+      backsig_pkt.pkt.signature = backsig;
+      err = build_packet (backsig_out, &backsig_pkt);
+      free_packet (&backsig_pkt);
+      if (err)
+       log_error ("build_packet failed for backsig: %s\n", g10_errstr(err));
       else
        {
-         size_t pktlen=0;
-         byte *buf=iobuf_get_temp_buffer(backsig_out);
+         size_t pktlen = 0;
+         byte *buf = iobuf_get_temp_buffer (backsig_out);
 
-         /* Remove the packet header */
+         /* Remove the packet header. */
          if(buf[0]&0x40)
            {
-             if(buf[1]<192)
+             if (buf[1] < 192)
                {
-                 pktlen=buf[1];
-                 buf+=2;
+                 pktlen = buf[1];
+                 buf += 2;
                }
-             else if(buf[1]<224)
+             else if(buf[1] < 224)
                {
-                 pktlen=(buf[1]-192)*256;
-                 pktlen+=buf[2]+192;
-                 buf+=3;
+                 pktlen = (buf[1]-192)*256;
+                 pktlen += buf[2]+192;
+                 buf += 3;
                }
-             else if(buf[1]==255)
+             else if (buf[1] == 255)
                {
-                  pktlen = buf32_to_size_t (buf+2);
-                 buf+=6;
+                 pktlen  = buf[2] << 24;
+                 pktlen |= buf[3] << 16;
+                 pktlen |= buf[4] << 8;
+                 pktlen |= buf[5];
+                 buf += 6;
                }
              else
-               BUG();
+               BUG ();
            }
          else
            {
-             int mark=1;
+             int mark = 1;
 
-             switch(buf[0]&3)
+             switch (buf[0]&3)
                {
                case 3:
-                 BUG();
+                 BUG ();
                  break;
 
                case 2:
-                 pktlen  = (size_t)buf[mark++] << 24;
+                 pktlen  = buf[mark++] << 24;
                  pktlen |= buf[mark++] << 16;
 
                case 1:
@@ -877,37 +874,41 @@ make_backsig (PKT_signature *sig,PKT_public_key *pk,
                  pktlen |= buf[mark++];
                }
 
-             buf+=mark;
+             buf += mark;
            }
 
          /* Now make the binary blob into a subpacket.  */
-         build_sig_subpkt(sig,SIGSUBPKT_SIGNATURE,buf,pktlen);
+         build_sig_subpkt (sig, SIGSUBPKT_SIGNATURE, buf, pktlen);
 
-         iobuf_close(backsig_out);
+         iobuf_close (backsig_out);
        }
     }
 
-  return rc;
+  return err;
 }
 
 
-static int
-write_direct_sig (KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
-                 struct revocation_key *revkey, u32 timestamp)
+/* Write a direct key signature to the first key in ROOT using the key
+   PSK.  REVKEY is describes the direct key signature and TIMESTAMP is
+   the timestamp to set on the signature.  */
+static gpg_error_t
+write_direct_sig (KBNODE root, PKT_public_key *psk,
+                  struct revocation_key *revkey, u32 timestamp,
+                  const char *cache_nonce)
 {
+  gpg_error_t err;
   PACKET *pkt;
   PKT_signature *sig;
-  int rc=0;
   KBNODE node;
   PKT_public_key *pk;
 
-  if( opt.verbose )
-    log_info(_("writing direct signature\n"));
+  if (opt.verbose)
+    log_info (_("writing direct signature\n"));
 
   /* Get the pk packet from the pub_tree. */
-  node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
-  if( !node )
-    BUG();
+  node = find_kbnode (root, PKT_PUBLIC_KEY);
+  if (!node)
+    BUG ();
   pk = node->pkt->pkt.public_key;
 
   /* We have to cache the key, so that the verification of the
@@ -915,48 +916,54 @@ write_direct_sig (KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
   cache_public_key (pk);
 
   /* Make the signature.  */
-  rc = make_keysig_packet (&sig,pk,NULL,NULL,sk,0x1F,
-                           0, 0, timestamp, 0,
-                           keygen_add_revkey, revkey);
-  if( rc )
+  err = make_keysig_packet (&sig, pk, NULL,NULL, psk, 0x1F,
+                            0, timestamp, 0,
+                            keygen_add_revkey, revkey, cache_nonce);
+  if (err)
     {
-      log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
-      return rc;
+      log_error ("make_keysig_packet failed: %s\n", g10_errstr (err) );
+      return err;
     }
 
-  pkt = xmalloc_clear( sizeof *pkt );
+  pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
-  add_kbnode( root, new_kbnode( pkt ) );
-  return rc;
+  add_kbnode (root, new_kbnode (pkt));
+  return err;
 }
 
 
-static int
-write_selfsigs( KBNODE sec_root, KBNODE pub_root, PKT_secret_key *sk,
-               unsigned int use, u32 timestamp )
+
+/* Write a self-signature to the first user id in ROOT using the key
+   PSK.  USE and TIMESTAMP give the extra data we need for the
+   signature.  */
+static gpg_error_t
+write_selfsigs (KBNODE root, PKT_public_key *psk,
+               unsigned int use, u32 timestamp, const char *cache_nonce)
 {
+  gpg_error_t err;
   PACKET *pkt;
   PKT_signature *sig;
   PKT_user_id *uid;
-  int rc=0;
   KBNODE node;
   PKT_public_key *pk;
 
-  if( opt.verbose )
-    log_info(_("writing self signature\n"));
+  if (opt.verbose)
+    log_info (_("writing self signature\n"));
 
   /* Get the uid packet from the list. */
-  node = find_kbnode( pub_root, PKT_USER_ID );
-  if( !node )
+  node = find_kbnode (root, PKT_USER_ID);
+  if (!node)
     BUG(); /* No user id packet in tree.  */
   uid = node->pkt->pkt.user_id;
 
   /* Get the pk packet from the pub_tree. */
-  node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
-  if( !node )
+  node = find_kbnode (root, PKT_PUBLIC_KEY);
+  if (!node)
     BUG();
   pk = node->pkt->pkt.public_key;
+
+  /* The usage has not yet been set - do it now. */
   pk->pubkey_usage = use;
 
   /* We have to cache the key, so that the verification of the
@@ -964,48 +971,45 @@ write_selfsigs( KBNODE sec_root, KBNODE pub_root, PKT_secret_key *sk,
   cache_public_key (pk);
 
   /* Make the signature.  */
-  rc = make_keysig_packet (&sig, pk, uid, NULL, sk, 0x13,
-                           0, 0, timestamp, 0,
-                           keygen_add_std_prefs, pk);
-  if( rc )
+  err = make_keysig_packet (&sig, pk, uid, NULL, psk, 0x13,
+                            0, timestamp, 0,
+                            keygen_add_std_prefs, pk, cache_nonce);
+  if (err)
     {
-      log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
-      return rc;
+      log_error ("make_keysig_packet failed: %s\n", g10_errstr (err));
+      return err;
     }
 
-  pkt = xmalloc_clear( sizeof *pkt );
+  pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
-  add_kbnode( sec_root, new_kbnode( pkt ) );
+  add_kbnode (root, new_kbnode (pkt));
 
-  pkt = xmalloc_clear( sizeof *pkt );
-  pkt->pkttype = PKT_SIGNATURE;
-  pkt->pkt.signature = copy_signature(NULL,sig);
-  add_kbnode( pub_root, new_kbnode( pkt ) );
-  return rc;
+  return err;
 }
 
 
 /* Write the key binding signature.  If TIMESTAMP is not NULL use the
-   signature creation times.  */
+   signature creation time.  PRI_PSK is the key use for signing.
+   SUB_PSK is a key used to create a back-signature; that one is only
+   used if USE has the PUBKEY_USAGE_SIG capability.  */
 static int
-write_keybinding (KBNODE root, KBNODE pub_root,
-                 PKT_secret_key *pri_sk, PKT_secret_key *sub_sk,
-                  unsigned int use, u32 timestamp)
+write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
+                  unsigned int use, u32 timestamp, const char *cache_nonce)
 {
+  gpg_error_t err;
   PACKET *pkt;
   PKT_signature *sig;
-  int rc=0;
   KBNODE node;
   PKT_public_key *pri_pk, *sub_pk;
   struct opaque_data_usage_and_pk oduap;
 
-  if ( opt.verbose )
+  if (opt.verbose)
     log_info(_("writing key binding signature\n"));
 
-  /* Get the pk packet from the pub_tree.  */
-  node = find_kbnode ( pub_root, PKT_PUBLIC_KEY );
-  if ( !node )
+  /* Get the primary pk packet from the tree.  */
+  node = find_kbnode (root, PKT_PUBLIC_KEY);
+  if (!node)
     BUG();
   pri_pk = node->pkt->pkt.public_key;
 
@@ -1015,9 +1019,9 @@ write_keybinding (KBNODE root, KBNODE pub_root,
 
   /* Find the last subkey. */
   sub_pk = NULL;
-  for (node=pub_root; node; node = node->next )
+  for (node = root; node; node = node->next )
     {
-      if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
         sub_pk = node->pkt->pkt.public_key;
     }
   if (!sub_pk)
@@ -1026,32 +1030,121 @@ write_keybinding (KBNODE root, KBNODE pub_root,
   /* Make the signature.  */
   oduap.usage = use;
   oduap.pk = sub_pk;
-  rc = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_sk, 0x18,
-                           0, 0, timestamp, 0,
-                           keygen_add_key_flags_and_expire, &oduap );
-  if (rc)
+  err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18,
+                            0, timestamp, 0,
+                            keygen_add_key_flags_and_expire, &oduap,
+                            cache_nonce);
+  if (err)
     {
-      log_error ("make_keysig_packet failed: %s\n", g10_errstr(rc) );
-      return rc;
+      log_error ("make_keysig_packeto failed: %s\n", g10_errstr (err));
+      return err;
     }
 
   /* Make a backsig.  */
-  if (use&PUBKEY_USAGE_SIG)
+  if (use & PUBKEY_USAGE_SIG)
     {
-      rc = make_backsig (sig, pri_pk, sub_pk, sub_sk, timestamp);
-      if (rc)
-        return rc;
+      err = make_backsig (sig, pri_pk, sub_pk, sub_psk, timestamp, cache_nonce);
+      if (err)
+        return err;
     }
 
   pkt = xmalloc_clear ( sizeof *pkt );
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
   add_kbnode (root, new_kbnode (pkt) );
-  return rc;
+  return err;
 }
 
 
+static gpg_error_t
+ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
+{
+  gpg_error_t err;
+  gcry_sexp_t list, l2;
+  char *curve;
+  int i;
+  const char *oidstr;
+  unsigned int nbits;
+
+  array[0] = NULL;
+  array[1] = NULL;
+  array[2] = NULL;
+
+  list = gcry_sexp_find_token (sexp, "public-key", 0);
+  if (!list)
+    return gpg_error (GPG_ERR_INV_OBJ);
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  if (!list)
+    return gpg_error (GPG_ERR_NO_OBJ);
+
+  l2 = gcry_sexp_find_token (list, "curve", 0);
+  if (!l2)
+    {
+      err = gpg_error (GPG_ERR_NO_OBJ);
+      goto leave;
+    }
+  curve = gcry_sexp_nth_string (l2, 1);
+  if (!curve)
+    {
+      err = gpg_error (GPG_ERR_NO_OBJ);
+      goto leave;
+    }
+  gcry_sexp_release (l2);
+  oidstr = openpgp_curve_to_oid (curve, &nbits);
+  if (!oidstr)
+    {
+      /* That can't happen because we used one of the curves
+         gpg_curve_to_oid knows about.  */
+      err = gpg_error (GPG_ERR_INV_OBJ);
+      goto leave;
+    }
+  err = openpgp_oid_from_str (oidstr, &array[0]);
+  if (err)
+    goto leave;
+
+  l2 = gcry_sexp_find_token (list, "q", 0);
+  if (!l2)
+    {
+      err = gpg_error (GPG_ERR_NO_OBJ);
+      goto leave;
+    }
+  array[1] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+  gcry_sexp_release (l2);
+  if (!array[1])
+    {
+      err = gpg_error (GPG_ERR_INV_OBJ);
+      goto leave;
+    }
+  gcry_sexp_release (list);
+
+  if (algo == PUBKEY_ALGO_ECDH)
+    {
+      array[2] = pk_ecdh_default_params (nbits);
+      if (!array[2])
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+    }
+
+ leave:
+  if (err)
+    {
+      for (i=0; i < 3; i++)
+        {
+          gcry_mpi_release (array[i]);
+          array[i] = NULL;
+        }
+    }
+  return err;
+}
+
 
+/* Extract key parameters from SEXP and store them in ARRAY.  ELEMS is
+   a string where each character denotes a parameter name.  TOPNAME is
+   the name of the top element above the elements.  */
 static int
 key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
                const char *topname, const char *elems)
@@ -1102,187 +1195,226 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
 }
 
 
+/* Create a keyblock using the given KEYGRIP.  ALGO is the OpenPGP
+   algorithm of that keygrip.  */
 static int
-genhelp_protect (DEK *dek, STRING2KEY *s2k, PKT_secret_key *sk)
+do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
+                        kbnode_t pub_root, u32 timestamp, u32 expireval,
+                        int is_subkey)
 {
-  int rc = 0;
+  int err;
+  PACKET *pkt;
+  PKT_public_key *pk;
+  gcry_sexp_t s_key;
+  const char *algoelem;
 
-  if (dek)
+  if (hexkeygrip[0] == '&')
+    hexkeygrip++;
+
+  switch (algo)
     {
-      sk->protect.algo = dek->algo;
-      sk->protect.s2k = *s2k;
-      rc = protect_secret_key (sk, dek);
-      if (rc)
-        log_error ("protect_secret_key failed: %s\n", gpg_strerror (rc) );
+    case PUBKEY_ALGO_RSA:       algoelem = "ne"; break;
+    case PUBKEY_ALGO_DSA:       algoelem = "pqgy"; break;
+    case PUBKEY_ALGO_ELGAMAL_E: algoelem = "pgy"; break;
+    case PUBKEY_ALGO_ECDH:
+    case PUBKEY_ALGO_ECDSA:     algoelem = ""; break;
+    case PUBKEY_ALGO_EDDSA:     algoelem = ""; break;
+    default: return gpg_error (GPG_ERR_INTERNAL);
     }
 
-  return rc;
-}
 
-static void
-genhelp_factors (gcry_sexp_t misc_key_info, KBNODE sec_root)
-{
-  (void)misc_key_info;
-  (void)sec_root;
-#if 0 /* Not used anymore */
-  size_t n;
-  char *buf;
+  /* Ask the agent for the public key matching HEXKEYGRIP.  */
+  {
+    unsigned char *public;
+
+    err = agent_readkey (ctrl, 0, hexkeygrip, &public);
+    if (err)
+      return err;
+    err = gcry_sexp_sscan (&s_key, NULL,
+                           public, gcry_sexp_canon_len (public, 0, NULL, NULL));
+    xfree (public);
+    if (err)
+      return err;
+  }
 
-  if (misc_key_info)
+  /* Build a public key packet.  */
+  pk = xtrycalloc (1, sizeof *pk);
+  if (!pk)
     {
-      /* DSA: don't know whether it makes sense to have the factors, so for now
-         we store them in the secret keyring (but they are not secret)
-         p = 2 * q * f1 * f2 * ... * fn
-         We store only f1 to f_n-1;  fn can be calculated because p and q
-         are known. */
-      n = gcry_sexp_sprint (misc_key_info, 0, NULL, 0);
-      buf = xmalloc (n+4);
-      strcpy (buf, "#::");
-      n = gcry_sexp_sprint (misc_key_info, 0, buf+3, n);
-      if (n)
-        {
-          n += 3;
-          add_kbnode (sec_root, make_comment_node_from_buffer (buf, n));
-        }
-      xfree (buf);
-      gcry_sexp_release (misc_key_info);
+      err = gpg_error_from_syserror ();
+      gcry_sexp_release (s_key);
+      return err;
     }
-#endif
-}
-
 
-/* Generate an Elgamal encryption key pair. TIMESTAMP is the creatuion
-   time to be put into the key structure.  */
-static int
-gen_elg (int algo, unsigned int nbits,
-         KBNODE pub_root, KBNODE sec_root, DEK *dek,
-         STRING2KEY *s2k, PKT_secret_key **ret_sk,
-         u32 timestamp, u32 expireval, int is_subkey)
-{
-  int rc;
-  PACKET *pkt;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-  gcry_sexp_t s_parms, s_key;
-  gcry_sexp_t misc_key_info;
-
-  assert( is_ELGAMAL(algo) );
+  pk->timestamp = timestamp;
+  pk->version = 4;
+  if (expireval)
+    pk->expiredate = pk->timestamp + expireval;
+  pk->pubkey_algo = algo;
 
-  if (nbits < 1024)
-    {
-      nbits = 2048;
-      log_info (_("keysize invalid; using %u bits\n"), nbits );
-    }
-  else if (nbits > 4096)
+  if (algo == PUBKEY_ALGO_ECDSA
+      || algo == PUBKEY_ALGO_EDDSA
+      || algo == PUBKEY_ALGO_ECDH )
+    err = ecckey_from_sexp (pk->pkey, s_key, algo);
+  else
+    err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
+  if (err)
     {
-      nbits = 4096;
-      log_info (_("keysize invalid; using %u bits\n"), nbits );
+      log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) );
+      gcry_sexp_release (s_key);
+      free_public_key (pk);
+      return err;
     }
+  gcry_sexp_release (s_key);
 
-  if ((nbits % 32))
+  pkt = xtrycalloc (1, sizeof *pkt);
+  if (!pkt)
     {
-      nbits = ((nbits + 31) / 32) * 32;
-      log_info (_("keysize rounded up to %u bits\n"), nbits );
+      err = gpg_error_from_syserror ();
+      free_public_key (pk);
+      return err;
     }
 
+  pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
+  pkt->pkt.public_key = pk;
+  add_kbnode (pub_root, new_kbnode (pkt));
 
-  rc = gcry_sexp_build ( &s_parms, NULL,
-                         "(genkey(%s(nbits %d)))",
-                         algo == GCRY_PK_ELG_E ? "openpgp-elg" :
-                         algo == GCRY_PK_ELG    ? "elg" : "x-oops" ,
-                         (int)nbits);
-  if (rc)
-    log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
+  return 0;
+}
 
-  rc = gcry_pk_genkey (&s_key, s_parms);
-  gcry_sexp_release (s_parms);
-  if (rc)
-    {
-      log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
-      return rc;
-    }
 
-  sk = xmalloc_clear( sizeof *sk );
-  pk = xmalloc_clear( sizeof *pk );
-  sk->timestamp = pk->timestamp = timestamp;
-  sk->version = pk->version = 4;
-  if (expireval)
+/* Common code for the key generation fucntion gen_xxx.  */
+static int
+common_gen (const char *keyparms, int algo, const char *algoelem,
+            kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey,
+            int keygen_flags, char **cache_nonce_addr)
+{
+  int err;
+  PACKET *pkt;
+  PKT_public_key *pk;
+  gcry_sexp_t s_key;
+
+  err = agent_genkey (NULL, cache_nonce_addr, keyparms,
+                      !!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION), &s_key);
+  if (err)
     {
-      sk->expiredate = pk->expiredate = sk->timestamp + expireval;
+      log_error ("agent_genkey failed: %s\n", gpg_strerror (err) );
+      return err;
     }
-  sk->pubkey_algo = pk->pubkey_algo = algo;
 
-  rc = key_from_sexp (pk->pkey, s_key, "public-key", "pgy");
-  if (rc)
+  pk = xtrycalloc (1, sizeof *pk);
+  if (!pk)
     {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
+      err = gpg_error_from_syserror ();
       gcry_sexp_release (s_key);
-      free_secret_key (sk);
-      free_public_key (pk);
-      return rc;
+      return err;
     }
-  rc = key_from_sexp (sk->skey, s_key, "private-key", "pgyx");
-  if (rc)
+
+  pk->timestamp = timestamp;
+  pk->version = 4;
+  if (expireval)
+    pk->expiredate = pk->timestamp + expireval;
+  pk->pubkey_algo = algo;
+
+  if (algo == PUBKEY_ALGO_ECDSA
+      || algo == PUBKEY_ALGO_EDDSA
+      || algo == PUBKEY_ALGO_ECDH )
+    err = ecckey_from_sexp (pk->pkey, s_key, algo);
+  else
+    err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
+  if (err)
     {
-      log_error("key_from_sexp failed: %s\n", gpg_strerror (rc) );
+      log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) );
       gcry_sexp_release (s_key);
-      free_secret_key (sk);
       free_public_key (pk);
-      return rc;
+      return err;
     }
-  misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0);
   gcry_sexp_release (s_key);
 
-  sk->is_protected = 0;
-  sk->protect.algo = 0;
-
-  sk->csum = checksum_mpi (sk->skey[3]);
-  if (ret_sk) /* Return an unprotected version of the sk.  */
-    *ret_sk = copy_secret_key ( NULL, sk );
-
-  rc = genhelp_protect (dek, s2k, sk);
-  if (rc)
+  pkt = xtrycalloc (1, sizeof *pkt);
+  if (!pkt)
     {
+      err = gpg_error_from_syserror ();
       free_public_key (pk);
-      free_secret_key (sk);
-      gcry_sexp_release (misc_key_info);
-      return rc;
+      return err;
     }
 
-  pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
   pkt->pkt.public_key = pk;
-  add_kbnode (pub_root, new_kbnode( pkt ));
-
-  /* Don't know whether it makes sense to have access to the factors,
-     so for now we store them in the secret keyring (but they are not
-     secret).  */
-  pkt = xmalloc_clear (sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode (sec_root, new_kbnode( pkt ));
-
-  genhelp_factors (misc_key_info, sec_root);
+  add_kbnode (pub_root, new_kbnode (pkt));
 
   return 0;
 }
 
 
-/****************
- * Generate a DSA key
+/*
+ * Generate an Elgamal key.
  */
 static int
-gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
-         STRING2KEY *s2k, PKT_secret_key **ret_sk,
-         u32 timestamp, u32 expireval, int is_subkey)
+gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
+         u32 timestamp, u32 expireval, int is_subkey,
+         int keygen_flags, char **cache_nonce_addr)
 {
-  int rc;
-  PACKET *pkt;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-  gcry_sexp_t s_parms, s_key;
-  gcry_sexp_t misc_key_info;
+  int err;
+  char *keyparms;
+  char nbitsstr[35];
+
+  assert (is_ELGAMAL (algo));
+
+  if (nbits < 1024)
+    {
+      nbits = 2048;
+      log_info (_("keysize invalid; using %u bits\n"), nbits );
+    }
+  else if (nbits > 4096)
+    {
+      nbits = 4096;
+      log_info (_("keysize invalid; using %u bits\n"), nbits );
+    }
+
+  if ((nbits % 32))
+    {
+      nbits = ((nbits + 31) / 32) * 32;
+      log_info (_("keysize rounded up to %u bits\n"), nbits );
+    }
+
+  /* Note that we use transient-key only if no-protection has also
+     been enabled.  */
+  snprintf (nbitsstr, sizeof nbitsstr, "%u", nbits);
+  keyparms = xtryasprintf ("(genkey(%s(nbits %zu:%s)%s))",
+                           algo == GCRY_PK_ELG_E ? "openpgp-elg" :
+                           algo == GCRY_PK_ELG  ? "elg" : "x-oops" ,
+                           strlen (nbitsstr), nbitsstr,
+                           ((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
+                            && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
+                           "(transient-key)" : "" );
+  if (!keyparms)
+    err = gpg_error_from_syserror ();
+  else
+    {
+      err = common_gen (keyparms, algo, "pgy",
+                        pub_root, timestamp, expireval, is_subkey,
+                        keygen_flags, cache_nonce_addr);
+      xfree (keyparms);
+    }
+
+  return err;
+}
+
+
+/*
+ * Generate an DSA key
+ */
+static gpg_error_t
+gen_dsa (unsigned int nbits, KBNODE pub_root,
+         u32 timestamp, u32 expireval, int is_subkey,
+         int keygen_flags, char **cache_nonce_addr)
+{
+  int err;
   unsigned int qbits;
+  char *keyparms;
+  char nbitsstr[35];
+  char qbitsstr[35];
 
   if (nbits < 768)
     {
@@ -1335,100 +1467,89 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
     log_info (_("WARNING: some OpenPGP programs can't"
                 " handle a DSA key with this digest size\n"));
 
-  rc = gcry_sexp_build (&s_parms, NULL,
-                        "(genkey(dsa(nbits %d)(qbits %d)))",
-                        (int)nbits, (int)qbits);
-  if (rc)
-    log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-
-  rc = gcry_pk_genkey (&s_key, s_parms);
-  gcry_sexp_release (s_parms);
-  if (rc)
+  snprintf (nbitsstr, sizeof nbitsstr, "%u", nbits);
+  snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits);
+  keyparms = xtryasprintf ("(genkey(dsa(nbits %zu:%s)(qbits %zu:%s)%s))",
+                           strlen (nbitsstr), nbitsstr,
+                           strlen (qbitsstr), qbitsstr,
+                           ((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
+                            && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
+                           "(transient-key)" : "" );
+  if (!keyparms)
+    err = gpg_error_from_syserror ();
+  else
     {
-      log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
-      return rc;
+      err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy",
+                        pub_root, timestamp, expireval, is_subkey,
+                        keygen_flags, cache_nonce_addr);
+      xfree (keyparms);
     }
 
-  sk = xmalloc_clear( sizeof *sk );
-  pk = xmalloc_clear( sizeof *pk );
-  sk->timestamp = pk->timestamp = timestamp;
-  sk->version = pk->version = 4;
-  if (expireval)
-    sk->expiredate = pk->expiredate = sk->timestamp + expireval;
-  sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA;
-
-  rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy");
-  if (rc)
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc));
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  rc = key_from_sexp (sk->skey, s_key, "private-key", "pqgyx");
-  if (rc)
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0);
-  gcry_sexp_release (s_key);
+  return err;
+}
 
-  sk->is_protected = 0;
-  sk->protect.algo = 0;
 
-  sk->csum = checksum_mpi ( sk->skey[4] );
-  if( ret_sk ) /* return an unprotected version of the sk */
-    *ret_sk = copy_secret_key( NULL, sk );
 
-  rc = genhelp_protect (dek, s2k, sk);
-  if (rc)
+/*
+ * Generate an ECC key
+ */
+static gpg_error_t
+gen_ecc (int algo, const char *curve, kbnode_t pub_root,
+         u32 timestamp, u32 expireval, int is_subkey,
+         int keygen_flags, char **cache_nonce_addr)
+{
+  gpg_error_t err;
+  char *keyparms;
+
+  assert (algo == PUBKEY_ALGO_ECDSA
+          || algo == PUBKEY_ALGO_EDDSA
+          || algo == PUBKEY_ALGO_ECDH);
+
+  if (!curve || !*curve)
+    return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+
+  /* Note that we use the "comp" flag with EdDSA to request the use of
+     a 0x40 compression prefix octet.  */
+  if (algo == PUBKEY_ALGO_EDDSA)
+    keyparms = xtryasprintf
+      ("(genkey(ecc(curve %zu:%s)(flags eddsa comp%s)))",
+       strlen (curve), curve,
+       (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
+         && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
+        " transient-key" : ""));
+  else
+    keyparms = xtryasprintf
+      ("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))",
+       strlen (curve), curve,
+       (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
+         && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
+        " transient-key" : ""));
+
+  if (!keyparms)
+    err = gpg_error_from_syserror ();
+  else
     {
-      free_public_key (pk);
-      free_secret_key (sk);
-      gcry_sexp_release (misc_key_info);
-      return rc;
+      err = common_gen (keyparms, algo, "",
+                        pub_root, timestamp, expireval, is_subkey,
+                        keygen_flags, cache_nonce_addr);
+      xfree (keyparms);
     }
 
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
-  pkt->pkt.public_key = pk;
-  add_kbnode(pub_root, new_kbnode( pkt ));
-
-  /* Don't know whether it makes sense to have the factors, so for now
-   * we store them in the secret keyring (but they are not secret)
-   * p = 2 * q * f1 * f2 * ... * fn
-   * We store only f1 to f_n-1;  fn can be calculated because p and q
-   * are known.
-   */
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode(sec_root, new_kbnode( pkt ));
-
-  genhelp_factors (misc_key_info, sec_root);
-
-  return 0;
-}
+  return err;
+}
 
 
 /*
  * Generate an RSA key.
  */
 static int
-gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
-         STRING2KEY *s2k, PKT_secret_key **ret_sk,
-         u32 timestamp, u32 expireval, int is_subkey)
+gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
+         u32 timestamp, u32 expireval, int is_subkey,
+         int keygen_flags, char **cache_nonce_addr)
 {
-  int rc;
-  PACKET *pkt;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-  gcry_sexp_t s_parms, s_key;
+  int err;
+  char *keyparms;
+  char nbitsstr[35];
   const unsigned maxsize = (opt.flags.large_rsa ? 8192 : 4096);
 
   assert (is_RSA(algo));
@@ -1453,79 +1574,23 @@ gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
       log_info (_("keysize rounded up to %u bits\n"), nbits );
     }
 
-  rc = gcry_sexp_build (&s_parms, NULL,
-                        "(genkey(rsa(nbits %d)))",
-                        (int)nbits);
-  if (rc)
-    log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-
-  rc = gcry_pk_genkey (&s_key, s_parms);
-  gcry_sexp_release (s_parms);
-  if (rc)
-    {
-      log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
-      return rc;
-    }
-
-  sk = xmalloc_clear( sizeof *sk );
-  pk = xmalloc_clear( sizeof *pk );
-  sk->timestamp = pk->timestamp = timestamp;
-  sk->version = pk->version = 4;
-  if (expireval)
-    {
-      sk->expiredate = pk->expiredate = sk->timestamp + expireval;
-    }
-  sk->pubkey_algo = pk->pubkey_algo = algo;
-
-  rc = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
-  if (rc)
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc));
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  rc = key_from_sexp (sk->skey, s_key, "private-key", "nedpqu");
-  if (rc)
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  gcry_sexp_release (s_key);
-
-  sk->is_protected = 0;
-  sk->protect.algo = 0;
-
-  sk->csum  = checksum_mpi (sk->skey[2] );
-  sk->csum += checksum_mpi (sk->skey[3] );
-  sk->csum += checksum_mpi (sk->skey[4] );
-  sk->csum += checksum_mpi (sk->skey[5] );
-  if( ret_sk ) /* return an unprotected version of the sk */
-    *ret_sk = copy_secret_key( NULL, sk );
-
-  rc = genhelp_protect (dek, s2k, sk);
-  if (rc)
+  snprintf (nbitsstr, sizeof nbitsstr, "%u", nbits);
+  keyparms = xtryasprintf ("(genkey(rsa(nbits %zu:%s)%s))",
+                           strlen (nbitsstr), nbitsstr,
+                           ((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
+                            && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
+                           "(transient-key)" : "" );
+  if (!keyparms)
+    err = gpg_error_from_syserror ();
+  else
     {
-      free_public_key (pk);
-      free_secret_key (sk);
-      return rc;
+      err = common_gen (keyparms, algo, "ne",
+                        pub_root, timestamp, expireval, is_subkey,
+                        keygen_flags, cache_nonce_addr);
+      xfree (keyparms);
     }
 
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
-  pkt->pkt.public_key = pk;
-  add_kbnode(pub_root, new_kbnode( pkt ));
-
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode(sec_root, new_kbnode( pkt ));
-
-  return 0;
+  return err;
 }
 
 
@@ -1649,6 +1714,13 @@ ask_key_flags(int algo,int subkey)
                 current |= PUBKEY_USAGE_ENC;
               else if ((*s == 'a' || *s == 'A') && (possible&PUBKEY_USAGE_AUTH))
                 current |= PUBKEY_USAGE_AUTH;
+              else if (!subkey && *s == 'c')
+                {
+                  /* Accept 'c' for the primary key because USAGE_CERT
+                     will will be set anyway.  This is for folks who
+                     want to experiment with a cert-only primary key.  */
+                  current |= PUBKEY_USAGE_CERT;
+                }
             }
           break;
         }
@@ -1690,15 +1762,62 @@ ask_key_flags(int algo,int subkey)
 }
 
 
+/* Check whether we have a key for the key with HEXGRIP.  Returns 0 if
+   there is no such key or the OpenPGP algo number for the key.  */
+static int
+check_keygrip (ctrl_t ctrl, const char *hexgrip)
+{
+  gpg_error_t err;
+  unsigned char *public;
+  size_t publiclen;
+  const char *algostr;
+
+  if (hexgrip[0] == '&')
+    hexgrip++;
+
+  err = agent_readkey (ctrl, 0, hexgrip, &public);
+  if (err)
+    return 0;
+  publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
+
+  get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
+  xfree (public);
+
+  /* FIXME: Mapping of ECC algorithms is probably not correct. */
+  if (!algostr)
+    return 0;
+  else if (!strcmp (algostr, "rsa"))
+    return PUBKEY_ALGO_RSA;
+  else if (!strcmp (algostr, "dsa"))
+    return PUBKEY_ALGO_DSA;
+  else if (!strcmp (algostr, "elg"))
+    return PUBKEY_ALGO_ELGAMAL_E;
+  else if (!strcmp (algostr, "ecc"))
+    return PUBKEY_ALGO_ECDH;
+  else if (!strcmp (algostr, "ecdsa"))
+    return PUBKEY_ALGO_ECDSA;
+  else if (!strcmp (algostr, "eddsa"))
+    return PUBKEY_ALGO_EDDSA;
+  else
+    return 0;
+}
+
+
+
 /* Ask for an algorithm.  The function returns the algorithm id to
  * create. If ADDMODE is false the function won't show an option to
  * create the primary and subkey combined and won't set R_USAGE
  * either.  If a combined algorithm has been selected, the subkey
- * algorithm is stored at R_SUBKEY_ALGO.  */
+ * algorithm is stored at R_SUBKEY_ALGO.  If R_KEYGRIP is given, the
+ * user has the choice to enter the keygrip of an existing key.  That
+ * keygrip is then stored at this address.  The caller needs to free
+ * it. */
 static int
-ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
+ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
+          char **r_keygrip)
 {
-  char *answer = NULL;
+  char *keygrip = NULL;
+  char *answer;
   int algo;
   int dummy_algo;
 
@@ -1707,87 +1826,165 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
 
   tty_printf (_("Please select what kind of key you want:\n"));
 
+#if GPG_USE_RSA
   if (!addmode)
     tty_printf (_("   (%d) RSA and RSA (default)\n"), 1 );
+#endif
+
   if (!addmode)
     tty_printf (_("   (%d) DSA and Elgamal\n"), 2 );
 
   tty_printf (_("   (%d) DSA (sign only)\n"), 3 );
+#if GPG_USE_RSA
   tty_printf (_("   (%d) RSA (sign only)\n"), 4 );
+#endif
 
   if (addmode)
     {
       tty_printf (_("   (%d) Elgamal (encrypt only)\n"), 5 );
+#if GPG_USE_RSA
       tty_printf (_("   (%d) RSA (encrypt only)\n"), 6 );
+#endif
     }
   if (opt.expert)
     {
       tty_printf (_("   (%d) DSA (set your own capabilities)\n"), 7 );
+#if GPG_USE_RSA
       tty_printf (_("   (%d) RSA (set your own capabilities)\n"), 8 );
+#endif
     }
 
-  for(;;)
+#if GPG_USE_ECDSA || GPG_USE_ECDH || GPG_USE_EDDSA
+  if (opt.expert && !addmode)
+    tty_printf (_("   (%d) ECC and ECC\n"), 9 );
+  if (opt.expert)
+    tty_printf (_("  (%d) ECC (sign only)\n"), 10 );
+  if (opt.expert)
+    tty_printf (_("  (%d) ECC (set your own capabilities)\n"), 11 );
+  if (opt.expert && addmode)
+    tty_printf (_("  (%d) ECC (encrypt only)\n"), 12 );
+#endif
+
+  if (opt.expert && r_keygrip)
+    tty_printf (_("  (%d) Existing key\n"), 13 );
+
+  for (;;)
     {
       *r_usage = 0;
       *r_subkey_algo = 0;
-      xfree (answer);
       answer = cpr_get ("keygen.algo", _("Your selection? "));
       cpr_kill_prompt ();
       algo = *answer? atoi (answer) : 1;
-      if ((algo == 1 || !strcmp (answer, "rsa+rsa")) && !addmode)
+      xfree(answer);
+      answer = NULL;
+      if (algo == 1 && !addmode)
         {
           algo = PUBKEY_ALGO_RSA;
           *r_subkey_algo = PUBKEY_ALGO_RSA;
           break;
        }
-      else if ((algo == 2 || !strcmp (answer, "dsa+elg")) && !addmode)
+      else if (algo == 2 && !addmode)
         {
           algo = PUBKEY_ALGO_DSA;
           *r_subkey_algo = PUBKEY_ALGO_ELGAMAL_E;
           break;
        }
-      else if (algo == 3 || !strcmp (answer, "dsa"))
+      else if (algo == 3)
         {
           algo = PUBKEY_ALGO_DSA;
           *r_usage = PUBKEY_USAGE_SIG;
           break;
        }
-      else if (algo == 4 || !strcmp (answer, "rsa/s"))
+      else if (algo == 4)
         {
           algo = PUBKEY_ALGO_RSA;
           *r_usage = PUBKEY_USAGE_SIG;
           break;
        }
-      else if ((algo == 5 || !strcmp (answer, "elg")) && addmode)
+      else if (algo == 5 && addmode)
         {
           algo = PUBKEY_ALGO_ELGAMAL_E;
           *r_usage = PUBKEY_USAGE_ENC;
           break;
        }
-      else if ((algo == 6 || !strcmp (answer, "rsa/e")) && addmode)
+      else if (algo == 6 && addmode)
         {
           algo = PUBKEY_ALGO_RSA;
           *r_usage = PUBKEY_USAGE_ENC;
           break;
        }
-      else if ((algo == 7 || !strcmp (answer, "dsa/*")) && opt.expert)
+      else if (algo == 7 && opt.expert)
         {
           algo = PUBKEY_ALGO_DSA;
           *r_usage = ask_key_flags (algo, addmode);
           break;
        }
-      else if ((algo == 8 || !strcmp (answer, "rsa/*")) && opt.expert)
+      else if (algo == 8 && opt.expert)
         {
           algo = PUBKEY_ALGO_RSA;
           *r_usage = ask_key_flags (algo, addmode);
           break;
        }
+      else if (algo == 9 && opt.expert && !addmode)
+        {
+          algo = PUBKEY_ALGO_ECDSA;
+          *r_subkey_algo = PUBKEY_ALGO_ECDH;
+          break;
+       }
+      else if (algo == 10 && opt.expert)
+        {
+          algo = PUBKEY_ALGO_ECDSA;
+          *r_usage = PUBKEY_USAGE_SIG;
+          break;
+       }
+      else if (algo == 11 && opt.expert)
+        {
+          algo = PUBKEY_ALGO_ECDSA;
+          *r_usage = ask_key_flags (algo, addmode);
+          break;
+       }
+      else if (algo == 12 && opt.expert && addmode)
+        {
+          algo = PUBKEY_ALGO_ECDH;
+          *r_usage = PUBKEY_USAGE_ENC;
+          break;
+       }
+      else if (algo == 13 && opt.expert && r_keygrip)
+        {
+          for (;;)
+            {
+              xfree (answer);
+              answer = tty_get (_("Enter the keygrip: "));
+              tty_kill_prompt ();
+              trim_spaces (answer);
+              if (!*answer)
+                {
+                  xfree (answer);
+                  answer = NULL;
+                  continue;
+                }
+
+              if (strlen (answer) != 40 &&
+                       !(answer[0] == '&' && strlen (answer+1) == 40))
+                tty_printf
+                  (_("Not a valid keygrip (expecting 40 hex digits)\n"));
+              else if (!(algo = check_keygrip (ctrl, answer)) )
+                tty_printf (_("No key with this keygrip\n"));
+              else
+                break; /* Okay.  */
+            }
+          xfree (keygrip);
+          keygrip = answer;
+          answer = NULL;
+          *r_usage = ask_key_flags (algo, addmode);
+          break;
+       }
       else
         tty_printf (_("Invalid selection.\n"));
-
     }
 
-  xfree(answer);
+  if (r_keygrip)
+    *r_keygrip = keygrip;
   return algo;
 }
 
@@ -1802,8 +1999,8 @@ ask_keysize (int algo, unsigned int primary_keysize)
   int for_subkey = !!primary_keysize;
   int autocomp = 0;
 
-  if(opt.expert && algo == PUBKEY_ALGO_DSA)
-    min=768;
+  if(opt.expert)
+    min=512;
   else
     min=1024;
 
@@ -1828,6 +2025,19 @@ ask_keysize (int algo, unsigned int primary_keysize)
       max=3072;
       break;
 
+    case PUBKEY_ALGO_ECDSA:
+    case PUBKEY_ALGO_ECDH:
+      min=256;
+      def=256;
+      max=521;
+      break;
+
+    case PUBKEY_ALGO_EDDSA:
+      min=255;
+      def=255;
+      max=441;
+      break;
+
     case PUBKEY_ALGO_RSA:
       min=1024;
       break;
@@ -1836,7 +2046,7 @@ ask_keysize (int algo, unsigned int primary_keysize)
   tty_printf(_("%s keys may be between %u and %u bits long.\n"),
             openpgp_pk_algo_name (algo), min, max);
 
-  for(;;)
+  for (;;)
     {
       char *prompt, *answer;
 
@@ -1858,26 +2068,188 @@ ask_keysize (int algo, unsigned int primary_keysize)
        break;
     }
 
-  tty_printf(_("Requested keysize is %u bits\n"), nbits );
+  tty_printf (_("Requested keysize is %u bits\n"), nbits);
 
  leave:
-  if( algo == PUBKEY_ALGO_DSA && (nbits % 64) )
+  if (algo == PUBKEY_ALGO_DSA && (nbits % 64))
     {
       nbits = ((nbits + 63) / 64) * 64;
       if (!autocomp)
-        tty_printf(_("rounded up to %u bits\n"), nbits );
+        tty_printf (_("rounded up to %u bits\n"), nbits);
+    }
+  else if (algo == PUBKEY_ALGO_EDDSA)
+    {
+      if (nbits != 255 && nbits != 441)
+        {
+          if (nbits < 256)
+            nbits = 255;
+          else
+            nbits = 441;
+          if (!autocomp)
+            tty_printf (_("rounded to %u bits\n"), nbits);
+        }
     }
-  else if( (nbits % 32) )
+  else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
+    {
+      if (nbits != 256 && nbits != 384 && nbits != 521)
+        {
+          if (nbits < 256)
+            nbits = 256;
+          else if (nbits < 384)
+            nbits = 384;
+          else
+            nbits = 521;
+          if (!autocomp)
+            tty_printf (_("rounded to %u bits\n"), nbits);
+        }
+    }
+  else if ((nbits % 32))
     {
       nbits = ((nbits + 31) / 32) * 32;
       if (!autocomp)
-        tty_printf(_("rounded up to %u bits\n"), nbits );
+        tty_printf (_("rounded up to %u bits\n"), nbits );
     }
 
   return nbits;
 }
 
 
+/* Ask for the curve.  ALGO is the selected algorithm which this
+   function may adjust.  Returns a malloced string with the name of
+   the curve.  BOTH tells that gpg creates a primary and subkey. */
+static char *
+ask_curve (int *algo, int both)
+{
+  struct {
+    const char *name;
+    int available;
+    int expert_only;
+    int fix_curve;
+    const char *pretty_name;
+  } curves[] = {
+#if GPG_USE_EDDSA
+    { "Curve25519",      0, 0, 1, "Curve 25519" },
+#endif
+#if GPG_USE_ECDSA || GPG_USE_ECDH
+    { "NIST P-256",      0, 1, 0, },
+    { "NIST P-384",      0, 0, 0, },
+    { "NIST P-521",      0, 1, 0, },
+    { "brainpoolP256r1", 0, 1, 0, "Brainpool P-256" },
+    { "brainpoolP384r1", 0, 1, 0, "Brainpool P-384" },
+    { "brainpoolP512r1", 0, 1, 0, "Brainpool P-512" },
+    { "secp256k1",       0, 1, 0  },
+#endif
+  };
+  int idx;
+  char *answer;
+  char *result = NULL;
+  gcry_sexp_t keyparms;
+
+  tty_printf (_("Please select which elliptic curve you want:\n"));
+
+ again:
+  keyparms = NULL;
+  for (idx=0; idx < DIM(curves); idx++)
+    {
+      int rc;
+
+      curves[idx].available = 0;
+      if (!opt.expert && curves[idx].expert_only)
+        continue;
+
+      /* FIXME: The strcmp below is a temporary hack during
+         development.  It shall be removed as soon as we have proper
+         Curve25519 support in Libgcrypt.  */
+      gcry_sexp_release (keyparms);
+      rc = gcry_sexp_build (&keyparms, NULL,
+                            "(public-key(ecc(curve %s)))",
+                            (!strcmp (curves[idx].name, "Curve25519")
+                             ? "Ed25519" : curves[idx].name));
+      if (rc)
+        continue;
+      if (!gcry_pk_get_curve (keyparms, 0, NULL))
+        continue;
+      if (both && curves[idx].fix_curve)
+        {
+          /* Both Curve 25519 keys are to be created.  Check that
+             Libgcrypt also supports the real Curve25519.  */
+          gcry_sexp_release (keyparms);
+          rc = gcry_sexp_build (&keyparms, NULL,
+                                "(public-key(ecc(curve %s)))",
+                                 curves[idx].name);
+          if (rc)
+            continue;
+          if (!gcry_pk_get_curve (keyparms, 0, NULL))
+            continue;
+        }
+
+      curves[idx].available = 1;
+      tty_printf ("   (%d) %s\n", idx + 1,
+                  curves[idx].pretty_name?
+                  curves[idx].pretty_name:curves[idx].name);
+    }
+  gcry_sexp_release (keyparms);
+
+
+  for (;;)
+    {
+      answer = cpr_get ("keygen.curve", _("Your selection? "));
+      cpr_kill_prompt ();
+      idx = *answer? atoi (answer) : 1;
+      if (*answer && !idx)
+        {
+          /* See whether the user entered the name of the curve.  */
+          for (idx=0; idx < DIM(curves); idx++)
+            {
+              if (!opt.expert && curves[idx].expert_only)
+                continue;
+              if (!stricmp (curves[idx].name, answer)
+                  || (curves[idx].pretty_name
+                      && !stricmp (curves[idx].pretty_name, answer)))
+                break;
+            }
+          if (idx == DIM(curves))
+            idx = -1;
+        }
+      else
+        idx--;
+      xfree(answer);
+      answer = NULL;
+      if (idx < 0 || idx >= DIM (curves) || !curves[idx].available)
+        tty_printf (_("Invalid selection.\n"));
+      else
+        {
+          if (curves[idx].fix_curve)
+            {
+              log_info ("WARNING: Curve25519 is not yet part of the"
+                        " OpenPGP standard.\n");
+
+              if (!cpr_get_answer_is_yes("experimental_curve.override",
+                                         "Use this curve anyway? (y/N) ")  )
+                goto again;
+            }
+
+          /* If the user selected a signing algorithm and Curve25519
+             we need to update the algo and and the curve name.  */
+          if ((*algo == PUBKEY_ALGO_ECDSA || *algo == PUBKEY_ALGO_EDDSA)
+              && curves[idx].fix_curve)
+            {
+              *algo = PUBKEY_ALGO_EDDSA;
+              result = xstrdup ("Ed25519");
+            }
+          else
+            result = xstrdup (curves[idx].name);
+          break;
+        }
+    }
+
+  if (!result)
+    result = xstrdup (curves[0].name);
+
+  return result;
+}
+
+
 /****************
  * Parse an expire string and return its value in seconds.
  * Returns (u32)-1 on error.
@@ -2020,7 +2392,7 @@ ask_expire_interval(int object,const char *def_expire)
                       ? _("Key expires at %s\n")
                       : _("Signature expires at %s\n"),
                       asctimestamp((ulong)(curtime + interval) ) );
-#if SIZEOF_TIME_T <= 4
+#if SIZEOF_TIME_T <= 4 && !defined (HAVE_UNSIGNED_TIME_T)
            if ( (time_t)((ulong)(curtime+interval)) < 0 )
              tty_printf (_("Your system can't display dates beyond 2038.\n"
                             "However, it will be correctly handled up to"
@@ -2070,9 +2442,9 @@ uid_from_string (const char *string)
 /* Ask for a user ID.  With a MODE of 1 an extra help prompt is
    printed for use during a new key creation.  If KEYBLOCK is not NULL
    the function prevents the creation of an already existing user
-   ID.  */
+   ID.  IF FULL is not set some prompts are not shown.  */
 static char *
-ask_user_id (int mode, KBNODE keyblock)
+ask_user_id (int mode, int full, KBNODE keyblock)
 {
     char *answer;
     char *aname, *acomment, *amail, *uid;
@@ -2081,9 +2453,9 @@ ask_user_id (int mode, KBNODE keyblock)
       {
         /* TRANSLATORS: This is the new string telling the user what
            gpg is now going to do (i.e. ask for the parts of the user
-           ID).  Note that if you do not tyranslated this string, a
-           different string will be used used, which might still have
-           a correct transaltion.  */
+           ID).  Note that if you do not translate this string, a
+           different string will be used, which might still have
+           a correct translation.  */
        const char *s1 =
           N_("\n"
              "GnuPG needs to construct a user ID to identify your key.\n"
@@ -2150,7 +2522,8 @@ ask_user_id (int mode, KBNODE keyblock)
                    break;
            }
        }
-       if( !acomment ) {
+       if (!acomment) {
+          if (full) {
            for(;;) {
                xfree(acomment);
                acomment = cpr_get("keygen.comment",_("Comment: "));
@@ -2163,6 +2536,11 @@ ask_user_id (int mode, KBNODE keyblock)
                else
                    break;
            }
+          }
+          else {
+            xfree (acomment);
+            acomment = xstrdup ("");
+          }
        }
 
 
@@ -2181,7 +2559,7 @@ ask_user_id (int mode, KBNODE keyblock)
        /* print a note in case that UTF8 mapping has to be done */
        for(p=uid; *p; p++ ) {
            if( *p & 0x80 ) {
-               tty_printf(_("You are using the `%s' character set.\n"),
+               tty_printf(_("You are using the '%s' character set.\n"),
                           get_native_charset() );
                break;
            }
@@ -2231,11 +2609,17 @@ ask_user_id (int mode, KBNODE keyblock)
                 answer = xstrdup (ansstr + (fail?8:6));
                answer[1] = 0;
            }
-           else {
+            else if (full) {
                answer = cpr_get("keygen.userid.cmd", fail?
                  _("Change (N)ame, (C)omment, (E)mail or (Q)uit? ") :
                  _("Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "));
                cpr_kill_prompt();
+            }
+            else {
+               answer = cpr_get("keygen.userid.cmd", fail?
+                 _("Change (N)ame, (E)mail, or (Q)uit? ") :
+                 _("Change (N)ame, (E)mail, or (O)kay/(Q)uit? "));
+               cpr_kill_prompt();
            }
            if( strlen(answer) > 1 )
                ;
@@ -2272,7 +2656,7 @@ ask_user_id (int mode, KBNODE keyblock)
            xfree(answer);
        }
        xfree(answer);
-       if( !aname && !acomment && !amail )
+       if( !amail && !acomment && !amail )
            break;
        xfree(uid); uid = NULL;
     }
@@ -2287,6 +2671,7 @@ ask_user_id (int mode, KBNODE keyblock)
 
 /*  MODE  0 - standard
           1 - Ask for passphrase of the card backup key.  */
+#if 0
 static DEK *
 do_ask_passphrase (STRING2KEY **ret_s2k, int mode, int *r_canceled)
 {
@@ -2331,37 +2716,45 @@ do_ask_passphrase (STRING2KEY **ret_s2k, int mode, int *r_canceled)
     *ret_s2k = s2k;
     return dek;
 }
+#endif /* 0 */
 
 
 /* Basic key generation.  Here we divert to the actual generation
    routines based on the requested algorithm.  */
 static int
-do_create (int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root,
-          DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk,
-           u32 timestamp, u32 expiredate, int is_subkey )
+do_create (int algo, unsigned int nbits, const char *curve, KBNODE pub_root,
+           u32 timestamp, u32 expiredate, int is_subkey,
+           int keygen_flags, char **cache_nonce_addr)
 {
-  int rc=0;
+  gpg_error_t err;
 
-  if( !opt.batch )
-    tty_printf(_(
+  /* Fixme: The entropy collecting message should be moved to a
+     libgcrypt progress handler.  */
+  if (!opt.batch)
+    tty_printf (_(
 "We need to generate a lot of random bytes. It is a good idea to perform\n"
 "some other action (type on the keyboard, move the mouse, utilize the\n"
 "disks) during the prime generation; this gives the random number\n"
 "generator a better chance to gain enough entropy.\n") );
 
-  if( algo == PUBKEY_ALGO_ELGAMAL_E )
-    rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk,
-                 timestamp, expiredate, is_subkey);
-  else if( algo == PUBKEY_ALGO_DSA )
-    rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk,
-                 timestamp, expiredate, is_subkey);
-  else if( algo == PUBKEY_ALGO_RSA )
-    rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk,
-                 timestamp, expiredate, is_subkey);
+  if (algo == PUBKEY_ALGO_ELGAMAL_E)
+    err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey,
+                   keygen_flags, cache_nonce_addr);
+  else if (algo == PUBKEY_ALGO_DSA)
+    err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey,
+                   keygen_flags, cache_nonce_addr);
+  else if (algo == PUBKEY_ALGO_ECDSA
+           || algo == PUBKEY_ALGO_EDDSA
+           || algo == PUBKEY_ALGO_ECDH)
+    err = gen_ecc (algo, curve, pub_root, timestamp, expiredate, is_subkey,
+                   keygen_flags, cache_nonce_addr);
+  else if (algo == PUBKEY_ALGO_RSA)
+    err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey,
+                   keygen_flags, cache_nonce_addr);
   else
     BUG();
 
-  return rc;
+  return err;
 }
 
 
@@ -2373,26 +2766,33 @@ generate_user_id (KBNODE keyblock)
 {
   char *p;
 
-  p = ask_user_id (1, keyblock);
+  p = ask_user_id (1, 1, keyblock);
   if (!p)
     return NULL;  /* Canceled. */
   return uid_from_string (p);
 }
 
 
+/* Append R to the linked list PARA.  */
 static void
-release_parameter_list( struct para_data_s *r )
+append_to_parameter (struct para_data_s *para, struct para_data_s *r)
 {
-    struct para_data_s *r2;
+  assert (para);
+  while (para->next)
+    para = para->next;
+  para->next = r;
+}
 
-    for( ; r ; r = r2 ) {
-       r2 = r->next;
-       if( r->key == pPASSPHRASE_DEK )
-           xfree( r->u.dek );
-       else if( r->key == pPASSPHRASE_S2K )
-           xfree( r->u.s2k );
+/* Release the parameter list R.  */
+static void
+release_parameter_list (struct para_data_s *r)
+{
+  struct para_data_s *r2;
 
-       xfree(r);
+  for (; r ; r = r2)
+    {
+      r2 = r->next;
+      xfree (r);
     }
 }
 
@@ -2438,9 +2838,9 @@ get_parameter_algo( struct para_data_s *para, enum para_name key,
     i = atoi( r->u.value );
   else if (!strcmp (r->u.value, "ELG-E")
            || !strcmp (r->u.value, "ELG"))
-    i = GCRY_PK_ELG_E;
+    i = PUBKEY_ALGO_ELGAMAL_E;
   else
-    i = gcry_pk_map_name (r->u.value);
+    i = map_pk_gcry_to_openpgp (gcry_pk_map_name (r->u.value));
 
   if (i == PUBKEY_ALGO_RSA_E || i == PUBKEY_ALGO_RSA_S)
     i = 0; /* we don't want to allow generation of these algorithms */
@@ -2559,20 +2959,6 @@ get_parameter_uint( struct para_data_s *para, enum para_name key )
     return get_parameter_u32( para, key );
 }
 
-static DEK *
-get_parameter_dek( struct para_data_s *para, enum para_name key )
-{
-    struct para_data_s *r = get_parameter( para, key );
-    return r? r->u.dek : NULL;
-}
-
-static STRING2KEY *
-get_parameter_s2k( struct para_data_s *para, enum para_name key )
-{
-    struct para_data_s *r = get_parameter( para, key );
-    return r? r->u.s2k : NULL;
-}
-
 static struct revocation_key *
 get_parameter_revkey( struct para_data_s *para, enum para_name key )
 {
@@ -2619,8 +3005,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
       r->u.usage = (is_default
                     ? (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG)
                     : openpgp_pk_algo_usage(algo));
-      r->next = para;
-      para = r;
+      append_to_parameter (para, r);
     }
   else if (err == -1)
     return -1;
@@ -2656,8 +3041,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
          r->u.usage = (is_default
                         ? PUBKEY_USAGE_ENC
                         : openpgp_pk_algo_usage (algo));
-         r->next = para;
-         para = r;
+          append_to_parameter (para, r);
        }
       else if (err == -1)
        return -1;
@@ -2694,8 +3078,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
            p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")");
          if( s3 )
            p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">");
-         r->next = para;
-         para = r;
+          append_to_parameter (para, r);
          have_user_id=1;
        }
     }
@@ -2732,70 +3115,6 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
   if (parse_revocation_key (fname, para, pREVOKER))
     return -1;
 
-  /* Make DEK and S2K from the Passphrase. */
-  if (outctrl->ask_passphrase)
-    {
-      /* %ask-passphrase is active - ignore pPASSPRASE and ask.  This
-         feature is required so that GUIs are able to do a key
-         creation but have gpg-agent ask for the passphrase.  */
-      int canceled = 0;
-      STRING2KEY *s2k;
-      DEK *dek;
-
-      dek = do_ask_passphrase (&s2k, 0, &canceled);
-      if (dek)
-        {
-          r = xmalloc_clear( sizeof *r );
-          r->key = pPASSPHRASE_DEK;
-          r->u.dek = dek;
-          r->next = para;
-          para = r;
-          r = xmalloc_clear( sizeof *r );
-          r->key = pPASSPHRASE_S2K;
-          r->u.s2k = s2k;
-          r->next = para;
-          para = r;
-        }
-
-      if (canceled)
-        {
-         log_error ("%s:%d: key generation canceled\n", fname, r->lnr );
-          return -1;
-        }
-    }
-  else
-    {
-      r = get_parameter( para, pPASSPHRASE );
-      if ( r && *r->u.value )
-        {
-          /* We have a plain text passphrase - create a DEK from it.
-           * It is a little bit ridiculous to keep it in secure memory
-           * but because we do this always, why not here.  */
-          STRING2KEY *s2k;
-          DEK *dek;
-
-          s2k = xmalloc_secure ( sizeof *s2k );
-          s2k->mode = opt.s2k_mode;
-          s2k->hash_algo = S2K_DIGEST_ALGO;
-          set_next_passphrase ( r->u.value );
-          dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2,
-                                   NULL, NULL);
-          set_next_passphrase (NULL );
-          assert (dek);
-          memset (r->u.value, 0, strlen(r->u.value));
-
-          r = xmalloc_clear (sizeof *r);
-          r->key = pPASSPHRASE_S2K;
-          r->u.s2k = s2k;
-          r->next = para;
-          para = r;
-          r = xmalloc_clear (sizeof *r);
-          r->key = pPASSPHRASE_DEK;
-          r->u.dek = dek;
-          r->next = para;
-          para = r;
-        }
-    }
 
   /* Make KEYCREATIONDATE from Creation-Date.  */
   r = get_parameter (para, pCREATIONDATE);
@@ -2831,15 +3150,9 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
       r = xmalloc_clear( sizeof *r + 20 );
       r->key = pSUBKEYEXPIRE;
       r->u.expire = seconds;
-      r->next = para;
-      para = r;
+      append_to_parameter (para, r);
     }
 
-  if( !!outctrl->pub.newfname ^ !!outctrl->sec.newfname ) {
-    log_error("%s:%d: only one ring name is set\n", fname, outctrl->lnr );
-    return -1;
-  }
-
   do_generate_keypair( para, outctrl, card );
   return 0;
 }
@@ -2858,9 +3171,11 @@ read_parameter_file( const char *fname )
     } keywords[] = {
        { "Key-Type",       pKEYTYPE},
        { "Key-Length",     pKEYLENGTH },
+       { "Key-Curve",      pKEYCURVE },
        { "Key-Usage",      pKEYUSAGE },
        { "Subkey-Type",    pSUBKEYTYPE },
        { "Subkey-Length",  pSUBKEYLENGTH },
+       { "Subkey-Curve",   pSUBKEYCURVE },
        { "Subkey-Usage",   pSUBKEYUSAGE },
        { "Name-Real",      pNAMEREAL },
        { "Name-Email",     pNAMEEMAIL },
@@ -2886,7 +3201,6 @@ read_parameter_file( const char *fname )
 
     memset( &outctrl, 0, sizeof( outctrl ) );
     outctrl.pub.afx = new_armor_context ();
-    outctrl.sec.afx = new_armor_context ();
 
     if( !fname || !*fname)
       fname = "-";
@@ -2896,13 +3210,13 @@ read_parameter_file( const char *fname )
       {
         iobuf_close (fp);
         fp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if (!fp) {
-      log_error (_("can't open `%s': %s\n"), fname, strerror(errno) );
+      log_error (_("can't open '%s': %s\n"), fname, strerror(errno) );
       return;
     }
-    iobuf_ioctl (fp, 3, 1, NULL); /* No file caching. */
+    iobuf_ioctl (fp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
 
     lnr = 0;
     err = NULL;
@@ -2936,9 +3250,13 @@ read_parameter_file( const char *fname )
            else if( !ascii_strcasecmp( keyword, "%dry-run" ) )
                outctrl.dryrun = 1;
            else if( !ascii_strcasecmp( keyword, "%ask-passphrase" ) )
-               outctrl.ask_passphrase = 1;
+              ; /* Dummy for backward compatibility. */
            else if( !ascii_strcasecmp( keyword, "%no-ask-passphrase" ) )
-               outctrl.ask_passphrase = 0;
+             ; /* Dummy for backward compatibility. */
+           else if( !ascii_strcasecmp( keyword, "%no-protection" ) )
+                outctrl.keygen_flags |= KEYGEN_FLAG_NO_PROTECTION;
+           else if( !ascii_strcasecmp( keyword, "%transient-key" ) )
+                outctrl.keygen_flags |= KEYGEN_FLAG_TRANSIENT_KEY;
            else if( !ascii_strcasecmp( keyword, "%commit" ) ) {
                outctrl.lnr = lnr;
                if (proc_parameter_file( para, fname, &outctrl, 0 ))
@@ -2957,16 +3275,10 @@ read_parameter_file( const char *fname )
                }
            }
            else if( !ascii_strcasecmp( keyword, "%secring" ) ) {
-               if( outctrl.sec.fname && !strcmp( outctrl.sec.fname, value ) )
-                   ; /* still the same file - ignore it */
-               else {
-                  xfree( outctrl.sec.newfname );
-                  outctrl.sec.newfname = xstrdup( value );
-                  outctrl.use_files = 1;
-               }
+              /* Ignore this command.  */
            }
            else
-               log_info("skipping control `%s' (%s)\n", keyword, value );
+               log_info("skipping control '%s' (%s)\n", keyword, value );
 
 
            continue;
@@ -3039,43 +3351,161 @@ read_parameter_file( const char *fname )
 
     if( outctrl.use_files ) { /* close open streams */
        iobuf_close( outctrl.pub.stream );
-       iobuf_close( outctrl.sec.stream );
 
         /* Must invalidate that ugly cache to actually close it.  */
         if (outctrl.pub.fname)
-          iobuf_ioctl (NULL, 2, 0, (char*)outctrl.pub.fname);
-        if (outctrl.sec.fname)
-          iobuf_ioctl (NULL, 2, 0, (char*)outctrl.sec.fname);
+          iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
+                       0, (char*)outctrl.pub.fname);
 
        xfree( outctrl.pub.fname );
        xfree( outctrl.pub.newfname );
-       xfree( outctrl.sec.fname );
-       xfree( outctrl.sec.newfname );
     }
 
     release_parameter_list( para );
     iobuf_close (fp);
     release_armor_context (outctrl.pub.afx);
-    release_armor_context (outctrl.sec.afx);
+}
+
+
+/* Helper for quick_generate_keypair.  */
+static struct para_data_s *
+quickgen_set_para (struct para_data_s *para, int for_subkey,
+                   int algo, int nbits, const char *curve)
+{
+  struct para_data_s *r;
+
+  r = xmalloc_clear (sizeof *r + 20);
+  r->key = for_subkey? pSUBKEYUSAGE :  pKEYUSAGE;
+  strcpy (r->u.value, for_subkey ? "encrypt" : "sign");
+  r->next = para;
+  para = r;
+  r = xmalloc_clear (sizeof *r + 20);
+  r->key = for_subkey? pSUBKEYTYPE : pKEYTYPE;
+  sprintf (r->u.value, "%d", algo);
+  r->next = para;
+  para = r;
+
+  if (curve)
+    {
+      r = xmalloc_clear (sizeof *r + strlen (curve));
+      r->key = for_subkey? pSUBKEYCURVE : pKEYCURVE;
+      strcpy (r->u.value, curve);
+      r->next = para;
+      para = r;
+    }
+  else
+    {
+      r = xmalloc_clear (sizeof *r + 20);
+      r->key = for_subkey? pSUBKEYLENGTH : pKEYLENGTH;
+      sprintf (r->u.value, "%u", nbits);
+      r->next = para;
+      para = r;
+    }
+
+  return para;
+}
+
+
+/*
+ * Unattended generation of a standard key.
+ */
+void
+quick_generate_keypair (const char *uid)
+{
+  gpg_error_t err;
+  struct para_data_s *para = NULL;
+  struct para_data_s *r;
+  struct output_control_s outctrl;
+  int use_tty;
+
+  memset (&outctrl, 0, sizeof outctrl);
+
+  use_tty = (!opt.batch && !opt.answer_yes
+             && !cpr_enabled ()
+             && gnupg_isatty (fileno (stdin))
+             && gnupg_isatty (fileno (stdout))
+             && gnupg_isatty (fileno (stderr)));
+
+  r = xmalloc_clear (sizeof *r + strlen (uid));
+  r->key = pUSERID;
+  strcpy (r->u.value, uid);
+  r->next = para;
+  para = r;
+
+  uid = trim_spaces (r->u.value);
+  if (!*uid || (!opt.allow_freeform_uid && !is_valid_user_id (uid)))
+    {
+      log_error (_("Key generation failed: %s\n"),
+                 gpg_strerror (GPG_ERR_INV_USER_ID));
+      goto leave;
+    }
+
+  /* If gpg is directly used on the console ask whether a key with the
+     given user id shall really be created.  */
+  if (use_tty)
+    {
+      tty_printf (_("About to create a key for:\n    \"%s\"\n\n"), uid);
+      if (!cpr_get_answer_is_yes_def ("quick_keygen.okay",
+                                      _("Continue? (Y/n) "), 1))
+        goto leave;
+    }
+
+  /* Check whether such a user ID already exists.  */
+  {
+    KEYDB_HANDLE kdbhd;
+    KEYDB_SEARCH_DESC desc;
+
+    memset (&desc, 0, sizeof desc);
+    desc.mode = KEYDB_SEARCH_MODE_EXACT;
+    desc.u.name = uid;
+
+    kdbhd = keydb_new ();
+    err = keydb_search (kdbhd, &desc, 1, NULL);
+    keydb_release (kdbhd);
+    if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
+      {
+        log_info (_("A key for \"%s\" already exists\n"), uid);
+        if (opt.answer_yes)
+          ;
+        else if (!use_tty
+                 || !cpr_get_answer_is_yes_def ("quick_keygen.force",
+                                                _("Create anyway? (y/N) "), 0))
+          {
+            log_inc_errorcount ();  /* we used log_info */
+            goto leave;
+          }
+        log_info (_("creating anyway\n"));
+      }
+  }
+
+  para = quickgen_set_para (para, 0,
+                            DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
+                            DEFAULT_STD_CURVE);
+  para = quickgen_set_para (para, 1,
+                            DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
+                            DEFAULT_STD_SUBCURVE);
+
+  proc_parameter_file (para, "[internal]", &outctrl, 0);
+ leave:
+  release_parameter_list (para);
 }
 
 
 /*
  * Generate a keypair (fname is only used in batch mode) If
  * CARD_SERIALNO is not NULL the function will create the keys on an
- * OpenPGP Card.  If BACKUP_ENCRYPTION_DIR has been set and
- * CARD_SERIALNO is NOT NULL, the encryption key for the card gets
- * generate in software, imported to the card and a backup file
- * written to directory given by this argument .
+ * OpenPGP Card.  If CARD_BACKUP_KEY has been set and CARD_SERIALNO is
+ * NOT NULL, the encryption key for the card is generated on the host,
+ * imported to the card and a backup file created by gpg-agent.  If
+ * FULL is not set only the basic prompts are used (except for batch
+ * mode).
  */
 void
-generate_keypair (const char *fname, const char *card_serialno,
-                  const char *backup_encryption_dir)
+generate_keypair (ctrl_t ctrl, int full, const char *fname,
+                  const char *card_serialno, int card_backup_key)
 {
   unsigned int nbits;
   char *uid = NULL;
-  DEK *dek;
-  STRING2KEY *s2k;
   int algo;
   unsigned int use;
   int both = 0;
@@ -3083,7 +3513,10 @@ generate_keypair (const char *fname, const char *card_serialno,
   struct para_data_s *para = NULL;
   struct para_data_s *r;
   struct output_control_s outctrl;
-  int canceled;
+
+#ifndef ENABLE_CARD_SUPPORT
+  (void)card_backup_key;
+#endif
 
   memset( &outctrl, 0, sizeof( outctrl ) );
 
@@ -3139,36 +3572,61 @@ generate_keypair (const char *fname, const char *card_serialno,
       r->next = para;
       para = r;
 
-      if (backup_encryption_dir)
+      if (card_backup_key)
         {
-          r = xcalloc (1, sizeof *r + strlen (backup_encryption_dir) );
-          r->key = pBACKUPENCDIR;
-          strcpy (r->u.value, backup_encryption_dir);
+          r = xcalloc (1, sizeof *r + 1);
+          r->key = pCARDBACKUPKEY;
+          strcpy (r->u.value, "1");
           r->next = para;
           para = r;
         }
 #endif /*ENABLE_CARD_SUPPORT*/
     }
-  else
+  else if (full)  /* Full featured key generation.  */
     {
       int subkey_algo;
+      char *curve = NULL;
 
-      algo = ask_algo (0, &subkey_algo, &use);
+      /* Fixme: To support creating a primary key by keygrip we better
+         also define the keyword for the parameter file.  Note that
+         the subkey case will never be asserted if a keygrip has been
+         given.  */
+      algo = ask_algo (ctrl, 0, &subkey_algo, &use, NULL);
       if (subkey_algo)
         {
           /* Create primary and subkey at once.  */
           both = 1;
-          r = xmalloc_clear( sizeof *r + 20 );
-          r->key = pKEYTYPE;
-          sprintf( r->u.value, "%d", algo );
-          r->next = para;
-          para = r;
-         nbits = ask_keysize (algo, 0);
-         r = xmalloc_clear( sizeof *r + 20 );
-         r->key = pKEYLENGTH;
-         sprintf( r->u.value, "%u", nbits);
-         r->next = para;
-         para = r;
+          if (algo == PUBKEY_ALGO_ECDSA
+              || algo == PUBKEY_ALGO_EDDSA
+              || algo == PUBKEY_ALGO_ECDH)
+            {
+              curve = ask_curve (&algo, both);
+              r = xmalloc_clear( sizeof *r + 20 );
+              r->key = pKEYTYPE;
+              sprintf( r->u.value, "%d", algo);
+              r->next = para;
+              para = r;
+              nbits = 0;
+              r = xmalloc_clear (sizeof *r + strlen (curve));
+              r->key = pKEYCURVE;
+              strcpy (r->u.value, curve);
+              r->next = para;
+              para = r;
+            }
+          else
+            {
+              r = xmalloc_clear( sizeof *r + 20 );
+              r->key = pKEYTYPE;
+              sprintf( r->u.value, "%d", algo);
+              r->next = para;
+              para = r;
+              nbits = ask_keysize (algo, 0);
+              r = xmalloc_clear( sizeof *r + 20 );
+              r->key = pKEYLENGTH;
+              sprintf( r->u.value, "%u", nbits);
+              r->next = para;
+              para = r;
+            }
           r = xmalloc_clear( sizeof *r + 20 );
           r->key = pKEYUSAGE;
           strcpy( r->u.value, "sign" );
@@ -3185,9 +3643,43 @@ generate_keypair (const char *fname, const char *card_serialno,
           strcpy( r->u.value, "encrypt" );
           r->next = para;
           para = r;
+
+          if (algo == PUBKEY_ALGO_ECDSA
+              || algo == PUBKEY_ALGO_EDDSA
+              || algo == PUBKEY_ALGO_ECDH)
+            {
+              if (algo == PUBKEY_ALGO_EDDSA
+                  && subkey_algo == PUBKEY_ALGO_ECDH)
+                {
+                  /* Need to switch to a different curve for the
+                     encryption key.  */
+                  xfree (curve);
+                  curve = xstrdup ("Curve25519");
+                }
+              r = xmalloc_clear (sizeof *r + strlen (curve));
+              r->key = pSUBKEYCURVE;
+              strcpy (r->u.value, curve);
+              r->next = para;
+              para = r;
+            }
         }
-      else
+      else /* Create only a single key.  */
         {
+          /* For ECC we need to ask for the curve before storing the
+             algo because ask_curve may change the algo.  */
+          if (algo == PUBKEY_ALGO_ECDSA
+              || algo == PUBKEY_ALGO_EDDSA
+              || algo == PUBKEY_ALGO_ECDH)
+            {
+              curve = ask_curve (&algo, 0);
+              nbits = 0;
+              r = xmalloc_clear (sizeof *r + strlen (curve));
+              r->key = pKEYCURVE;
+              strcpy (r->u.value, curve);
+              r->next = para;
+              para = r;
+            }
+
           r = xmalloc_clear( sizeof *r + 20 );
           r->key = pKEYTYPE;
           sprintf( r->u.value, "%d", algo );
@@ -3208,64 +3700,69 @@ generate_keypair (const char *fname, const char *card_serialno,
           nbits = 0;
         }
 
-      nbits = ask_keysize (both? subkey_algo : algo, nbits);
-      r = xmalloc_clear( sizeof *r + 20 );
-      r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
-      sprintf( r->u.value, "%u", nbits);
-      r->next = para;
-      para = r;
+      if (algo == PUBKEY_ALGO_ECDSA
+          || algo == PUBKEY_ALGO_EDDSA
+          || algo == PUBKEY_ALGO_ECDH)
+        {
+          /* The curve has already been set.  */
+        }
+      else
+        {
+          nbits = ask_keysize (both? subkey_algo : algo, nbits);
+          r = xmalloc_clear( sizeof *r + 20 );
+          r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
+          sprintf( r->u.value, "%u", nbits);
+          r->next = para;
+          para = r;
+        }
+
+      xfree (curve);
     }
+  else /* Default key generation.  */
+    {
+      tty_printf ( _("Note: Use \"%s %s\""
+                     " for a full featured key generation dialog.\n"),
+                   NAME_OF_INSTALLED_GPG, "--full-gen-key" );
+      para = quickgen_set_para (para, 0,
+                                DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
+                                DEFAULT_STD_CURVE);
+      para = quickgen_set_para (para, 1,
+                                DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
+                                DEFAULT_STD_SUBCURVE);
+    }
+
 
-  expire = ask_expire_interval(0,NULL);
-  r = xmalloc_clear( sizeof *r + 20 );
+  expire = full? ask_expire_interval (0, NULL) : 0;
+  r = xcalloc (1, sizeof *r + 20);
   r->key = pKEYEXPIRE;
   r->u.expire = expire;
   r->next = para;
   para = r;
-  r = xmalloc_clear( sizeof *r + 20 );
+  r = xcalloc (1, sizeof *r + 20);
   r->key = pSUBKEYEXPIRE;
   r->u.expire = expire;
   r->next = para;
   para = r;
 
-  uid = ask_user_id (0, NULL);
-  if( !uid )
+  uid = ask_user_id (0, full, NULL);
+  if (!uid)
     {
       log_error(_("Key generation canceled.\n"));
       release_parameter_list( para );
       return;
     }
-  r = xmalloc_clear( sizeof *r + strlen(uid) );
+  r = xcalloc (1, sizeof *r + strlen (uid));
   r->key = pUSERID;
-  strcpy( r->u.value, uid );
+  strcpy (r->u.value, uid);
   r->next = para;
   para = r;
 
-  canceled = 0;
-  dek = card_serialno? NULL : do_ask_passphrase (&s2k, 0, &canceled);
-  if( dek )
-    {
-      r = xmalloc_clear( sizeof *r );
-      r->key = pPASSPHRASE_DEK;
-      r->u.dek = dek;
-      r->next = para;
-      para = r;
-      r = xmalloc_clear( sizeof *r );
-      r->key = pPASSPHRASE_S2K;
-      r->u.s2k = s2k;
-      r->next = para;
-      para = r;
-    }
-
-  if (canceled)
-    log_error (_("Key generation canceled.\n"));
-  else
-    proc_parameter_file( para, "[internal]", &outctrl, !!card_serialno);
-  release_parameter_list( para );
+  proc_parameter_file (para, "[internal]", &outctrl, !!card_serialno);
+  release_parameter_list (para);
 }
 
 
-#ifdef ENABLE_CARD_SUPPORT
+#if 0 /* not required */
 /* Generate a raw key and return it as a secret key packet.  The
    function will ask for the passphrase and return a protected as well
    as an unprotected copy of a new secret key packet.  0 is returned
@@ -3380,16 +3877,17 @@ static void
 do_generate_keypair (struct para_data_s *para,
                     struct output_control_s *outctrl, int card)
 {
+  gpg_error_t err;
   KBNODE pub_root = NULL;
-  KBNODE sec_root = NULL;
-  PKT_secret_key *pri_sk = NULL, *sub_sk = NULL;
   const char *s;
+  PKT_public_key *pri_psk = NULL;
+  PKT_public_key *sub_psk = NULL;
   struct revocation_key *revkey;
-  int rc;
   int did_sub = 0;
   u32 timestamp;
+  char *cache_nonce = NULL;
 
-  if( outctrl->dryrun )
+  if (outctrl->dryrun)
     {
       log_info("dry-run mode - key generation skipped\n");
       return;
@@ -3402,7 +3900,8 @@ do_generate_keypair (struct para_data_s *para,
           iobuf_close(outctrl->pub.stream);
           outctrl->pub.stream = NULL;
           if (outctrl->pub.fname)
-            iobuf_ioctl (NULL, 2, 0, (char*)outctrl->pub.fname);
+            iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
+                         0, (char*)outctrl->pub.fname);
           xfree( outctrl->pub.fname );
           outctrl->pub.fname =  outctrl->pub.newfname;
           outctrl->pub.newfname = NULL;
@@ -3410,13 +3909,13 @@ do_generate_keypair (struct para_data_s *para,
           if (is_secured_filename (outctrl->pub.fname) )
             {
               outctrl->pub.stream = NULL;
-              errno = EPERM;
+              gpg_err_set_errno (EPERM);
             }
           else
-            outctrl->pub.stream = iobuf_create( outctrl->pub.fname );
+            outctrl->pub.stream = iobuf_create (outctrl->pub.fname, 0);
           if (!outctrl->pub.stream)
             {
-              log_error(_("can't create `%s': %s\n"), outctrl->pub.newfname,
+              log_error(_("can't create '%s': %s\n"), outctrl->pub.newfname,
                         strerror(errno) );
               return;
             }
@@ -3426,50 +3925,9 @@ do_generate_keypair (struct para_data_s *para,
               push_armor_filter (outctrl->pub.afx, outctrl->pub.stream);
             }
         }
-      if (outctrl->sec.newfname)
-        {
-          mode_t oldmask;
-
-          iobuf_close(outctrl->sec.stream);
-          outctrl->sec.stream = NULL;
-          if (outctrl->sec.fname)
-            iobuf_ioctl (NULL, 2, 0, (char*)outctrl->sec.fname);
-          xfree( outctrl->sec.fname );
-          outctrl->sec.fname =  outctrl->sec.newfname;
-          outctrl->sec.newfname = NULL;
-
-          oldmask = umask (077);
-          if (is_secured_filename (outctrl->sec.fname) )
-            {
-              outctrl->sec.stream = NULL;
-              errno = EPERM;
-            }
-          else
-            outctrl->sec.stream = iobuf_create( outctrl->sec.fname );
-          umask (oldmask);
-          if (!outctrl->sec.stream)
-            {
-              log_error(_("can't create `%s': %s\n"), outctrl->sec.newfname,
-                        strerror(errno) );
-              return;
-            }
-          if (opt.armor)
-            {
-              outctrl->sec.afx->what = 5;
-              push_armor_filter (outctrl->sec.afx, outctrl->sec.stream);
-            }
-        }
       assert( outctrl->pub.stream );
-      assert( outctrl->sec.stream );
       if (opt.verbose)
-        {
-          log_info (_("writing public key to `%s'\n"), outctrl->pub.fname );
-          if (card)
-            log_info (_("writing secret key stub to `%s'\n"),
-                      outctrl->sec.fname);
-          else
-            log_info(_("writing secret key to `%s'\n"), outctrl->sec.fname );
-        }
+        log_info (_("writing public key to '%s'\n"), outctrl->pub.fname );
     }
 
 
@@ -3479,7 +3937,6 @@ do_generate_keypair (struct para_data_s *para,
      deleted.  The very first packet must always be a KEY packet.  */
 
   start_tree (&pub_root);
-  start_tree (&sec_root);
 
   timestamp = get_parameter_u32 (para, pKEYCREATIONDATE);
   if (!timestamp)
@@ -3495,42 +3952,34 @@ do_generate_keypair (struct para_data_s *para,
      current timestamp.  */
 
   if (!card)
-    {
-      rc = do_create (get_parameter_algo( para, pKEYTYPE, NULL ),
-                      get_parameter_uint( para, pKEYLENGTH ),
-                      pub_root, sec_root,
-                      get_parameter_dek( para, pPASSPHRASE_DEK ),
-                      get_parameter_s2k( para, pPASSPHRASE_S2K ),
-                      &pri_sk,
-                      timestamp,
-                      get_parameter_u32( para, pKEYEXPIRE ), 0 );
-    }
+    err = do_create (get_parameter_algo( para, pKEYTYPE, NULL ),
+                     get_parameter_uint( para, pKEYLENGTH ),
+                     get_parameter_value (para, pKEYCURVE),
+                     pub_root,
+                     timestamp,
+                     get_parameter_u32( para, pKEYEXPIRE ), 0,
+                     outctrl->keygen_flags, &cache_nonce);
   else
-    {
-      rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, NULL,
-                         &timestamp,
-                         get_parameter_u32 (para, pKEYEXPIRE), para);
-      if (!rc)
-        {
-          pri_sk = sec_root->next->pkt->pkt.secret_key;
-          assert (pri_sk);
-        }
-    }
+    err = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root,
+                        &timestamp,
+                        get_parameter_u32 (para, pKEYEXPIRE));
 
-  if(!rc && (revkey=get_parameter_revkey(para,pREVOKER)))
+  /* Get the pointer to the generated public key packet.  */
+  if (!err)
     {
-      rc = write_direct_sig (pub_root, pub_root, pri_sk, revkey, timestamp);
-      if (!rc)
-        rc = write_direct_sig (sec_root, pub_root, pri_sk, revkey, timestamp);
+      pri_psk = pub_root->next->pkt->pkt.public_key;
+      assert (pri_psk);
     }
 
-  if( !rc && (s=get_parameter_value(para, pUSERID)) )
+  if (!err && (revkey = get_parameter_revkey (para, pREVOKER)))
+    err = write_direct_sig (pub_root, pri_psk, revkey, timestamp, cache_nonce);
+
+  if (!err && (s = get_parameter_value (para, pUSERID)))
     {
       write_uid (pub_root, s );
-      write_uid (sec_root, s );
-
-      rc = write_selfsigs (sec_root, pub_root, pri_sk,
-                           get_parameter_uint (para, pKEYUSAGE), timestamp);
+      err = write_selfsigs (pub_root, pri_psk,
+                            get_parameter_uint (para, pKEYUSAGE), timestamp,
+                            cache_nonce);
     }
 
   /* Write the auth key to the card before the encryption key.  This
@@ -3540,129 +3989,97 @@ do_generate_keypair (struct para_data_s *para,
      actually an encryption type.  In this case, the auth key is an
      RSA key so it succeeds. */
 
-  if (!rc && card && get_parameter (para, pAUTHKEYTYPE))
+  if (!err && card && get_parameter (para, pAUTHKEYTYPE))
     {
-      rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, NULL,
-                         &timestamp,
-                         get_parameter_u32 (para, pKEYEXPIRE), para);
-
-      if (!rc)
-        rc = write_keybinding (pub_root, pub_root, pri_sk, sub_sk,
-                               PUBKEY_USAGE_AUTH, timestamp);
-      if (!rc)
-        rc = write_keybinding (sec_root, pub_root, pri_sk, sub_sk,
-                               PUBKEY_USAGE_AUTH, timestamp);
+      err = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root,
+                          &timestamp,
+                          get_parameter_u32 (para, pKEYEXPIRE));
+      if (!err)
+        err = write_keybinding (pub_root, pri_psk, NULL,
+                                PUBKEY_USAGE_AUTH, timestamp, cache_nonce);
     }
 
-  if( !rc && get_parameter( para, pSUBKEYTYPE ) )
+  if (!err && get_parameter (para, pSUBKEYTYPE))
     {
+      sub_psk = NULL;
       if (!card)
         {
-          rc = do_create( get_parameter_algo( para, pSUBKEYTYPE, NULL ),
-                          get_parameter_uint( para, pSUBKEYLENGTH ),
-                          pub_root, sec_root,
-                          get_parameter_dek( para, pPASSPHRASE_DEK ),
-                          get_parameter_s2k( para, pPASSPHRASE_S2K ),
-                          &sub_sk,
-                          timestamp,
-                          get_parameter_u32( para, pSUBKEYEXPIRE ), 1 );
+          err = do_create (get_parameter_algo (para, pSUBKEYTYPE, NULL),
+                           get_parameter_uint (para, pSUBKEYLENGTH),
+                           get_parameter_value (para, pSUBKEYCURVE),
+                           pub_root,
+                           timestamp,
+                           get_parameter_u32 (para, pSUBKEYEXPIRE), 1,
+                           outctrl->keygen_flags, &cache_nonce);
+          /* Get the pointer to the generated public subkey packet.  */
+          if (!err)
+            {
+              kbnode_t node;
+
+              for (node = pub_root; node; node = node->next)
+                if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+                  sub_psk = node->pkt->pkt.public_key;
+              assert (sub_psk);
+            }
         }
       else
         {
-          if ((s = get_parameter_value (para, pBACKUPENCDIR)))
+          if ((s = get_parameter_value (para, pCARDBACKUPKEY)))
             {
               /* A backup of the encryption key has been requested.
                  Generate the key in software and import it then to
                  the card.  Write a backup file. */
-              rc = gen_card_key_with_backup (PUBKEY_ALGO_RSA, 2, 0,
-                                             pub_root, sec_root,
-                                             timestamp,
-                                             get_parameter_u32 (para,
-                                                                pKEYEXPIRE),
-                                             para, s);
+              err = gen_card_key_with_backup
+                (PUBKEY_ALGO_RSA, 2, 0, pub_root, timestamp,
+                 get_parameter_u32 (para, pKEYEXPIRE), para);
             }
           else
             {
-              rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root,
-                                 NULL,
-                                 &timestamp,
-                                 get_parameter_u32 (para, pKEYEXPIRE), para);
+              err = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root,
+                                  &timestamp,
+                                  get_parameter_u32 (para, pKEYEXPIRE));
             }
         }
 
-      if( !rc )
-        rc = write_keybinding(pub_root, pub_root, pri_sk, sub_sk,
-                              get_parameter_uint (para, pSUBKEYUSAGE),
-                              timestamp);
-      if( !rc )
-        rc = write_keybinding(sec_root, pub_root, pri_sk, sub_sk,
-                              get_parameter_uint (para, pSUBKEYUSAGE),
-                              timestamp);
+      if (!err)
+        err = write_keybinding (pub_root, pri_psk, sub_psk,
+                                get_parameter_uint (para, pSUBKEYUSAGE),
+                                timestamp, cache_nonce);
       did_sub = 1;
     }
 
-  if (!rc && outctrl->use_files)  /* Direct write to specified files.  */
+  if (!err && outctrl->use_files)  /* Direct write to specified files.  */
     {
-      rc = write_keyblock( outctrl->pub.stream, pub_root );
-      if (rc)
-        log_error ("can't write public key: %s\n", g10_errstr(rc) );
-      if (!rc)
-        {
-          rc = write_keyblock( outctrl->sec.stream, sec_root );
-          if(rc)
-            log_error ("can't write secret key: %s\n", g10_errstr(rc) );
-        }
+      err = write_keyblock (outctrl->pub.stream, pub_root);
+      if (err)
+        log_error ("can't write public key: %s\n", g10_errstr (err));
     }
-  else if (!rc) /* Write to the standard keyrings.  */
+  else if (!err) /* Write to the standard keyrings.  */
     {
-      KEYDB_HANDLE pub_hd = keydb_new (0);
-      KEYDB_HANDLE sec_hd = keydb_new (1);
+      KEYDB_HANDLE pub_hd = keydb_new ();
 
-      rc = keydb_locate_writable (pub_hd, NULL);
-      if (rc)
+      err = keydb_locate_writable (pub_hd, NULL);
+      if (err)
         log_error (_("no writable public keyring found: %s\n"),
-                   g10_errstr (rc));
-
-      if (!rc)
-        {
-          rc = keydb_locate_writable (sec_hd, NULL);
-          if (rc)
-            log_error (_("no writable secret keyring found: %s\n"),
-                       g10_errstr (rc));
-        }
+                   g10_errstr (err));
 
-      if (!rc && opt.verbose)
+      if (!err && opt.verbose)
         {
-          log_info (_("writing public key to `%s'\n"),
+          log_info (_("writing public key to '%s'\n"),
                     keydb_get_resource_name (pub_hd));
-          if (card)
-            log_info (_("writing secret key stub to `%s'\n"),
-                      keydb_get_resource_name (sec_hd));
-          else
-            log_info (_("writing secret key to `%s'\n"),
-                      keydb_get_resource_name (sec_hd));
         }
 
-      if (!rc)
-        {
-          rc = keydb_insert_keyblock (pub_hd, pub_root);
-          if (rc)
-            log_error (_("error writing public keyring `%s': %s\n"),
-                       keydb_get_resource_name (pub_hd), g10_errstr(rc));
-        }
-
-      if (!rc)
+      if (!err)
         {
-          rc = keydb_insert_keyblock (sec_hd, sec_root);
-          if (rc)
-            log_error (_("error writing secret keyring `%s': %s\n"),
-                       keydb_get_resource_name (pub_hd), g10_errstr(rc));
+          err = keydb_insert_keyblock (pub_hd, pub_root);
+          if (err)
+            log_error (_("error writing public keyring '%s': %s\n"),
+                       keydb_get_resource_name (pub_hd), g10_errstr(err));
         }
 
       keydb_release (pub_hd);
-      keydb_release (sec_hd);
 
-      if (!rc)
+      if (!err)
         {
           int no_enc_rsa;
           PKT_public_key *pk;
@@ -3675,17 +4092,19 @@ do_generate_keypair (struct para_data_s *para,
 
           pk = find_kbnode (pub_root, PKT_PUBLIC_KEY)->pkt->pkt.public_key;
 
-          keyid_from_pk(pk,pk->main_keyid);
-          register_trusted_keyid(pk->main_keyid);
+          keyid_from_pk (pk, pk->main_keyid);
+          register_trusted_keyid (pk->main_keyid);
 
           update_ownertrust (pk, ((get_ownertrust (pk) & ~TRUST_MASK)
                                   | TRUST_ULTIMATE ));
 
+          gen_standard_revoke (pk, cache_nonce);
+
           if (!opt.batch)
             {
               tty_printf (_("public and secret key created and signed.\n") );
               tty_printf ("\n");
-              list_keyblock(pub_root,0,1,NULL);
+              list_keyblock (pub_root, 0, 1, 1, NULL);
             }
 
 
@@ -3702,13 +4121,13 @@ do_generate_keypair (struct para_data_s *para,
         }
     }
 
-  if (rc)
+  if (err)
     {
       if (opt.batch)
-        log_error ("key generation failed: %s\n", g10_errstr(rc) );
+        log_error ("key generation failed: %s\n", g10_errstr(err) );
       else
-        tty_printf (_("Key generation failed: %s\n"), g10_errstr(rc) );
-      write_status_error (card? "card_key_generate":"key_generate", rc);
+        tty_printf (_("Key generation failed: %s\n"), g10_errstr(err) );
+      write_status_error (card? "card_key_generate":"key_generate", err);
       print_status_key_not_created ( get_parameter_value (para, pHANDLE) );
     }
   else
@@ -3718,231 +4137,189 @@ do_generate_keypair (struct para_data_s *para,
       print_status_key_created (did_sub? 'B':'P', pk,
                                 get_parameter_value (para, pHANDLE));
     }
-  release_kbnode( pub_root );
-  release_kbnode( sec_root );
 
-  if (pri_sk && !card)        /* The unprotected secret key unless we */
-    free_secret_key (pri_sk); /* have a shallow copy in card mode. */
-  if (sub_sk)
-    free_secret_key(sub_sk);
+  release_kbnode (pub_root);
+  xfree (cache_nonce);
 }
 
 
-/* Add a new subkey to an existing key.  Returns true if a new key has
+/* Add a new subkey to an existing key.  Returns 0 if a new key has
    been generated and put into the keyblocks.  */
-int
-generate_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock)
+gpg_error_t
+generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
 {
-  int okay=0, rc=0;
-  KBNODE node;
-  PKT_secret_key *pri_sk = NULL, *sub_sk = NULL;
+  gpg_error_t err = 0;
+  kbnode_t node;
+  PKT_public_key *pri_psk = NULL;
+  PKT_public_key *sub_psk = NULL;
   int algo;
   unsigned int use;
   u32 expire;
-  unsigned nbits;
-  char *passphrase = NULL;
-  DEK *dek = NULL;
-  STRING2KEY *s2k = NULL;
+  unsigned int nbits = 0;
+  char *curve = NULL;
   u32 cur_time;
-  int ask_pass = 0;
-  int canceled;
+  char *hexgrip = NULL;
+  char *serialno = NULL;
 
-  /* Break out the primary secret key.  */
-  node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-  if( !node )
+  /* Break out the primary key.  */
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node)
     {
-      log_error ("Oops; secret key not found anymore!\n");
+      log_error ("Oops; primary key missing in keyblock!\n");
+      err = gpg_error (GPG_ERR_BUG);
       goto leave;
     }
+  pri_psk = node->pkt->pkt.public_key;
 
-  /* Make a copy of the sk to keep the protected one in the keyblock. */
-  pri_sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
-
-  cur_time = make_timestamp();
+  cur_time = make_timestamp ();
 
-  if (pri_sk->timestamp > cur_time)
+  if (pri_psk->timestamp > cur_time)
     {
-      ulong d = pri_sk->timestamp - cur_time;
+      ulong d = pri_psk->timestamp - cur_time;
       log_info ( d==1 ? _("key has been created %lu second "
                           "in future (time warp or clock problem)\n")
                  : _("key has been created %lu seconds "
                      "in future (time warp or clock problem)\n"), d );
       if (!opt.ignore_time_conflict)
         {
-          rc = G10ERR_TIME_CONFLICT;
+          err = gpg_error (GPG_ERR_TIME_CONFLICT);
           goto leave;
         }
     }
 
-  if (pri_sk->version < 4)
+  if (pri_psk->version < 4)
     {
-      log_info (_("NOTE: creating subkeys for v3 keys "
+      log_info (_("Note: creating subkeys for v3 keys "
                   "is not OpenPGP compliant\n"));
+      err = gpg_error (GPG_ERR_CONFLICT);
       goto leave;
     }
 
-  if (pri_sk->is_protected && pri_sk->protect.s2k.mode == 1001)
+  err = hexkeygrip_from_pk (pri_psk, &hexgrip);
+  if (err)
+    goto leave;
+  if (agent_get_keyinfo (NULL, hexgrip, &serialno))
     {
       tty_printf (_("Secret parts of primary key are not available.\n"));
-      rc = G10ERR_NO_SECKEY;
       goto leave;
     }
+  if (serialno)
+    tty_printf (_("Secret parts of primary key are stored on-card.\n"));
 
+  xfree (hexgrip);
+  hexgrip = NULL;
+  algo = ask_algo (ctrl, 1, NULL, &use, &hexgrip);
+  assert (algo);
 
-  /* Unprotect to get the passphrase.  */
-  switch (is_secret_key_protected (pri_sk) )
-    {
-    case -1:
-      rc = G10ERR_PUBKEY_ALGO;
-      break;
-    case 0:
-      tty_printf (_("This key is not protected.\n"));
-      break;
-    case -2:
-      tty_printf (_("Secret parts of primary key are stored on-card.\n"));
-      ask_pass = 1;
-      break;
-    default:
-      tty_printf (_("Key is protected.\n"));
-      rc = check_secret_key ( pri_sk, 0 );
-      if (!rc)
-        passphrase = get_last_passphrase();
-      break;
-    }
-  if (rc)
-    goto leave;
+  if (hexgrip)
+    nbits = 0;
+  else if (algo == PUBKEY_ALGO_ECDSA
+           || algo == PUBKEY_ALGO_EDDSA
+           || algo == PUBKEY_ALGO_ECDH)
+    curve = ask_curve (&algo, 0);
+  else
+    nbits = ask_keysize (algo, 0);
 
-  algo = ask_algo (1, NULL, &use);
-  assert (algo);
-  nbits = ask_keysize (algo, 0);
   expire = ask_expire_interval (0, NULL);
   if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
                                                _("Really create? (y/N) ")))
-    goto leave;
-
-  canceled = 0;
-  if (ask_pass)
-    dek = do_ask_passphrase (&s2k, 0, &canceled);
-  else if (passphrase)
     {
-      s2k = xmalloc_secure ( sizeof *s2k );
-      s2k->mode = opt.s2k_mode;
-      s2k->hash_algo = S2K_DIGEST_ALGO;
-      set_next_passphrase ( passphrase );
-      dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2,
-                               NULL, NULL );
+      err = gpg_error (GPG_ERR_CANCELED);
+      goto leave;
     }
 
-  if (canceled)
-    rc = GPG_ERR_CANCELED;
+  if (hexgrip)
+    err = do_create_from_keygrip (ctrl, algo, hexgrip,
+                                  keyblock, cur_time, expire, 1);
+  else
+    err = do_create (algo, nbits, curve,
+                     keyblock, cur_time, expire, 1, 0, NULL);
+  if (err)
+    goto leave;
 
-  if (!rc)
-    rc = do_create (algo, nbits, pub_keyblock, sec_keyblock,
-                    dek, s2k, &sub_sk, cur_time, expire, 1 );
-  xfree (dek);
-  if (!rc)
-    rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk,
-                          use, cur_time);
-  if (!rc)
-    rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk,
-                           use, cur_time);
-  if (!rc)
-    {
-      okay = 1;
-      write_status_text (STATUS_KEY_CREATED, "S");
-    }
+  /* Get the pointer to the generated public subkey packet.  */
+  for (node = keyblock; node; node = node->next)
+    if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+      sub_psk = node->pkt->pkt.public_key;
+
+  /* Write the binding signature.  */
+  err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time, NULL);
+  if (err)
+    goto leave;
+
+  write_status_text (STATUS_KEY_CREATED, "S");
 
  leave:
-  if (rc)
-    log_error (_("Key generation failed: %s\n"), g10_errstr(rc) );
-  xfree (passphrase);
-  xfree (s2k);
-  /* Release the copy of the (now unprotected) secret keys.  */
-  if (pri_sk)
-    free_secret_key (pri_sk);
-  if (sub_sk)
-    free_secret_key (sub_sk);
-  set_next_passphrase (NULL);
-  return okay;
+  xfree (curve);
+  xfree (hexgrip);
+  xfree (serialno);
+  if (err)
+    log_error (_("Key generation failed: %s\n"), g10_errstr (err) );
+  return err;
 }
 
 
 #ifdef ENABLE_CARD_SUPPORT
 /* Generate a subkey on a card. */
-int
-generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
+gpg_error_t
+generate_card_subkeypair (kbnode_t pub_keyblock,
                           int keyno, const char *serialno)
 {
-  int okay=0, rc=0;
-  KBNODE node;
-  PKT_secret_key *pri_sk = NULL, *sub_sk;
+  gpg_error_t err = 0;
+  kbnode_t node;
+  PKT_public_key *pri_pk = NULL;
   int algo;
   unsigned int use;
   u32 expire;
-  char *passphrase = NULL;
   u32 cur_time;
   struct para_data_s *para = NULL;
 
   assert (keyno >= 1 && keyno <= 3);
 
-  para = xcalloc (1, sizeof *para + strlen (serialno) );
+  para = xtrycalloc (1, sizeof *para + strlen (serialno) );
+  if (!para)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
   para->key = pSERIALNO;
   strcpy (para->u.value, serialno);
 
   /* Break out the primary secret key */
-  node = find_kbnode (sec_keyblock, PKT_SECRET_KEY);
+  node = find_kbnode (pub_keyblock, PKT_PUBLIC_KEY);
   if (!node)
     {
-      log_error("Oops; secret key not found anymore!\n");
+      log_error ("Oops; publkic key lost!\n");
+      err = gpg_error (GPG_ERR_INTERNAL);
       goto leave;
     }
-
-  /* Make a copy of the sk to keep the protected one in the keyblock */
-  pri_sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
+  pri_pk = node->pkt->pkt.public_key;
 
   cur_time = make_timestamp();
-  if (pri_sk->timestamp > cur_time)
+  if (pri_pk->timestamp > cur_time)
     {
-      ulong d = pri_sk->timestamp - cur_time;
+      ulong d = pri_pk->timestamp - cur_time;
       log_info (d==1 ? _("key has been created %lu second "
                          "in future (time warp or clock problem)\n")
                      : _("key has been created %lu seconds "
                          "in future (time warp or clock problem)\n"), d );
        if (!opt.ignore_time_conflict)
           {
-           rc = G10ERR_TIME_CONFLICT;
+           err = gpg_error (GPG_ERR_TIME_CONFLICT);
            goto leave;
           }
     }
 
-  if (pri_sk->version < 4)
+  if (pri_pk->version < 4)
     {
-      log_info (_("NOTE: creating subkeys for v3 keys "
+      log_info (_("Note: creating subkeys for v3 keys "
                   "is not OpenPGP compliant\n"));
+      err = gpg_error (GPG_ERR_NOT_SUPPORTED);
       goto leave;
     }
 
-  /* Unprotect to get the passphrase. */
-  switch( is_secret_key_protected (pri_sk) )
-    {
-    case -1:
-      rc = G10ERR_PUBKEY_ALGO;
-      break;
-    case 0:
-      tty_printf("This key is not protected.\n");
-      break;
-    default:
-      tty_printf("Key is protected.\n");
-      rc = check_secret_key( pri_sk, 0 );
-      if (!rc)
-        passphrase = get_last_passphrase();
-      break;
-    }
-  if (rc)
-    goto leave;
-
   algo = PUBKEY_ALGO_RSA;
-  expire = ask_expire_interval (0,NULL);
+  expire = ask_expire_interval (0, NULL);
   if (keyno == 1)
     use = PUBKEY_USAGE_SIG;
   else if (keyno == 2)
@@ -3951,41 +4328,37 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
     use = PUBKEY_USAGE_AUTH;
   if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.cardsub.okay",
                                                _("Really create? (y/N) ")))
-    goto leave;
-
-  if (passphrase)
-    set_next_passphrase (passphrase);
+    {
+      err = gpg_error (GPG_ERR_CANCELED);
+      goto leave;
+    }
 
   /* Note, that depending on the backend, the card key generation may
      update CUR_TIME.  */
-  rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock,
-                    &sub_sk, &cur_time, expire, para);
-  if (!rc)
-    rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk,
-                           use, cur_time);
-  if (!rc)
-    rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk,
-                           use, cur_time);
-  if (!rc)
+  err = gen_card_key (algo, keyno, 0, pub_keyblock, &cur_time, expire);
+  /* Get the pointer to the generated public subkey packet.  */
+  if (!err)
     {
-      okay = 1;
-      write_status_text (STATUS_KEY_CREATED, "S");
+      PKT_public_key *sub_pk = NULL;
+
+      for (node = pub_keyblock; node; node = node->next)
+        if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+          sub_pk = node->pkt->pkt.public_key;
+      assert (sub_pk);
+      err = write_keybinding (pub_keyblock, pri_pk, sub_pk,
+                              use, cur_time, NULL);
     }
 
  leave:
-  if (rc)
-    log_error (_("Key generation failed: %s\n"), g10_errstr(rc) );
-  xfree (passphrase);
-  /* Release the copy of the (now unprotected) secret keys. */
-  if (pri_sk)
-    free_secret_key (pri_sk);
-  set_next_passphrase( NULL );
+  if (err)
+    log_error (_("Key generation failed: %s\n"), g10_errstr(err) );
+  else
+    write_status_text (STATUS_KEY_CREATED, "S");
   release_parameter_list (para);
-  return okay;
+  return err;
 }
 #endif /* !ENABLE_CARD_SUPPORT */
 
-
 /*
  * Write a keyblock to an output stream
  */
@@ -4011,88 +4384,96 @@ write_keyblock( IOBUF out, KBNODE node )
 
 
 /* Note that timestamp is an in/out arg. */
-static int
-gen_card_key (int algo, int keyno, int is_primary,
-              KBNODE pub_root, KBNODE sec_root, PKT_secret_key **ret_sk,
-              u32 *timestamp, u32 expireval, struct para_data_s *para)
+static gpg_error_t
+gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
+              u32 *timestamp, u32 expireval)
 {
 #ifdef ENABLE_CARD_SUPPORT
-  int rc;
-  const char *s;
+  gpg_error_t err;
   struct agent_card_genkey_s info;
   PACKET *pkt;
-  PKT_secret_key *sk;
   PKT_public_key *pk;
 
-  assert (algo == PUBKEY_ALGO_RSA);
-
-  /* Fixme: We don't have the serialnumber available, thus passing NULL. */
-  rc = agent_scd_genkey (&info, keyno, 1, NULL, *timestamp);
-/*    if (gpg_err_code (rc) == GPG_ERR_EEXIST) */
-/*      { */
-/*        tty_printf ("\n"); */
-/*        log_error ("WARNING: key does already exists!\n"); */
-/*        tty_printf ("\n"); */
-/*        if ( cpr_get_answer_is_yes( "keygen.card.replace_key", */
-/*                                    _("Replace existing key? "))) */
-/*          rc = agent_scd_genkey (&info, keyno, 1); */
-/*      } */
+  if (algo != PUBKEY_ALGO_RSA)
+    return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
-  if (rc)
+  pk = xtrycalloc (1, sizeof *pk );
+  if (!pk)
+    return gpg_error_from_syserror ();
+  pkt = xtrycalloc (1, sizeof *pkt);
+  if (!pkt)
     {
-      log_error ("key generation failed: %s\n", gpg_strerror (rc));
-      return rc;
+      xfree (pk);
+      return gpg_error_from_syserror ();
     }
-  if ( !info.n || !info.e )
+
+  /* Note: SCD knows the serialnumber, thus there is no point in passing it.  */
+  err = agent_scd_genkey (&info, keyno, 1, NULL, *timestamp);
+  /*  The code below is not used because we force creation of
+   *  the a card key (3rd arg).
+   * if (gpg_err_code (rc) == GPG_ERR_EEXIST)
+   *   {
+   *     tty_printf ("\n");
+   *     log_error ("WARNING: key does already exists!\n");
+   *     tty_printf ("\n");
+   *     if ( cpr_get_answer_is_yes( "keygen.card.replace_key",
+   *                                 _("Replace existing key? ")))
+   *       rc = agent_scd_genkey (&info, keyno, 1);
+   *   }
+  */
+  if (!err && (!info.n || !info.e))
     {
       log_error ("communication error with SCD\n");
       gcry_mpi_release (info.n);
       gcry_mpi_release (info.e);
-      return gpg_error (GPG_ERR_GENERAL);
+      err =  gpg_error (GPG_ERR_GENERAL);
+    }
+  if (err)
+    {
+      log_error ("key generation failed: %s\n", gpg_strerror (err));
+      xfree (pkt);
+      xfree (pk);
+      return err;
+    }
+
+  /* Send the learn command so that the agent creates a shadow key for
+     card key.  We need to do that now so that we are able to create
+     the self-signatures. */
+  err = agent_learn ();
+  if (err)
+    {
+      /* Oops: Card removed during generation.  */
+      log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err));
+      xfree (pkt);
+      xfree (pk);
+      return err;
     }
 
   if (*timestamp != info.created_at)
-    log_info ("Note that the key does not use the suggested creation date\n");
+    log_info ("NOTE: the key does not use the suggested creation date\n");
   *timestamp = info.created_at;
 
-  pk = xcalloc (1, sizeof *pk );
-  sk = xcalloc (1, sizeof *sk );
-  sk->timestamp = pk->timestamp = info.created_at;
-  sk->version = pk->version = 4;
+  pk->timestamp = info.created_at;
+  pk->version = 4;
   if (expireval)
-      sk->expiredate = pk->expiredate = pk->timestamp + expireval;
-  sk->pubkey_algo = pk->pubkey_algo = algo;
+    pk->expiredate = pk->timestamp + expireval;
+  pk->pubkey_algo = algo;
   pk->pkey[0] = info.n;
   pk->pkey[1] = info.e;
-  sk->skey[0] = gcry_mpi_copy (pk->pkey[0]);
-  sk->skey[1] = gcry_mpi_copy (pk->pkey[1]);
-  sk->skey[2] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
-  sk->is_protected = 1;
-  sk->protect.s2k.mode = 1002;
-  s = get_parameter_value (para, pSERIALNO);
-  if (s)
-    {
-      for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
-           sk->protect.ivlen++, s += 2)
-        sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
-    }
 
-  if( ret_sk )
-    *ret_sk = sk;
-
-  pkt = xcalloc (1,sizeof *pkt);
   pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
   pkt->pkt.public_key = pk;
-  add_kbnode(pub_root, new_kbnode( pkt ));
-
-  pkt = xcalloc (1,sizeof *pkt);
-  pkt->pkttype = is_primary ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode(sec_root, new_kbnode( pkt ));
+  add_kbnode (pub_root, new_kbnode (pkt));
 
   return 0;
 #else
-  return -1;
+  (void)algo;
+  (void)keyno;
+  (void)is_primary;
+  (void)pub_root;
+  (void)timestamp;
+  (void)expireval;
+  return gpg_error (GPG_ERR_NOT_SUPPORTED);
 #endif /*!ENABLE_CARD_SUPPORT*/
 }
 
@@ -4100,12 +4481,11 @@ gen_card_key (int algo, int keyno, int is_primary,
 
 static int
 gen_card_key_with_backup (int algo, int keyno, int is_primary,
-                          KBNODE pub_root, KBNODE sec_root,
-                          u32 timestamp,
-                          u32 expireval, struct para_data_s *para,
-                          const char *backup_dir)
+                          KBNODE pub_root, u32 timestamp,
+                          u32 expireval, struct para_data_s *para)
 {
-#ifdef ENABLE_CARD_SUPPORT
+#if ENABLE_CARD_SUPPORT && 0
+  /* FIXME: Move this to gpg-agent.  */
   int rc;
   const char *s;
   PACKET *pkt;
@@ -4141,7 +4521,7 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
       log_error (_("storing key onto card failed: %s\n"), g10_errstr (rc));
       free_secret_key (sk_unprotected);
       free_secret_key (sk_protected);
-      write_status_error ("save_key_to_card", rc);
+      write_status_errcode ("save_key_to_card", rc);
       return rc;
     }
 
@@ -4175,19 +4555,22 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
               (ulong)sk->keyid[0], (ulong)sk->keyid[1]);
 
     fname = make_filename (backup_dir, name_buffer, NULL);
+    /* Note that the umask call is not anymore needed because
+       iobuf_create now takes care of it.  However, it does not harm
+       and thus we keep it.  */
     oldmask = umask (077);
     if (is_secured_filename (fname))
       {
         fp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     else
-      fp = iobuf_create (fname);
+      fp = iobuf_create (fname, 1);
     umask (oldmask);
     if (!fp)
       {
         rc = gpg_error_from_syserror ();
-       log_error (_("can't create backup file `%s': %s\n"),
+       log_error (_("can't create backup file '%s': %s\n"),
                    fname, strerror(errno) );
         xfree (fname);
         free_secret_key (sk_unprotected);
@@ -4212,8 +4595,8 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
         char *fprbuf, *p;
 
         iobuf_close (fp);
-        iobuf_ioctl (NULL, 2, 0, (char*)fname);
-        log_info (_("NOTE: backup of card key saved to `%s'\n"), fname);
+        iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname);
+        log_info (_("Note: backup of card key saved to '%s'\n"), fname);
 
         fingerprint_from_sk (sk, array, &n);
         p = fprbuf = xmalloc (MAX_FINGERPRINT_LEN*2 + 1 + 1);
@@ -4262,14 +4645,24 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
 
   return 0;
 #else
-  return -1;
+# if __GCC__ && ENABLE_CARD_SUPPORT
+#  warning Card support still missing
+# endif
+  (void)algo;
+  (void)keyno;
+  (void)is_primary;
+  (void)pub_root;
+  (void)timestamp;
+  (void)expireval;
+  (void)para;
+  return gpg_error (GPG_ERR_NOT_SUPPORTED);
 #endif /*!ENABLE_CARD_SUPPORT*/
 }
 
 
-#ifdef ENABLE_CARD_SUPPORT
+#if 0
 int
-save_unprotected_key_to_card (PKT_secret_key *sk, int keyno)
+save_unprotected_key_to_card (PKT_public_key *sk, int keyno)
 {
   int rc;
   unsigned char *rsa_n = NULL;
index 83020e9..662806b 100644 (file)
@@ -1,6 +1,7 @@
 /* keyid.c - key ID and fingerprint handling
  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
- *               2004, 2006 Free Software Foundation, Inc.
+ *               2004, 2006, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include "keydb.h"
 #include "i18n.h"
 #include "rmd160.h"
-#include "host2net.h"
 
+#define KEYID_STR_SIZE 19
+
+#ifdef HAVE_UNSIGNED_TIME_T
+# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
+#else
+  /* Error or 32 bit time_t and value after 2038-01-19.  */
+# define IS_INVALID_TIME_T(a) ((a) < 0)
+#endif
+
+
+/* Return a letter describing the public key algorithms.  */
 int
 pubkey_letter( int algo )
 {
-    switch( algo ) {
-      case PUBKEY_ALGO_RSA:    return 'R' ;
-      case PUBKEY_ALGO_RSA_E:  return 'r' ;
-      case PUBKEY_ALGO_RSA_S:  return 's' ;
-      case PUBKEY_ALGO_ELGAMAL_E: return 'g';
-      case PUBKEY_ALGO_ELGAMAL: return 'G' ;
-      case PUBKEY_ALGO_DSA:    return 'D' ;
-      case PUBKEY_ALGO_ECDSA:  return 'E' ;    /* ECC DSA (sign only)   */
-      case PUBKEY_ALGO_ECDH:   return 'e' ;    /* ECC DH (encrypt only) */
-      default: return '?';
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:      return 'R' ;
+    case PUBKEY_ALGO_RSA_E:    return 'r' ;
+    case PUBKEY_ALGO_RSA_S:    return 's' ;
+    case PUBKEY_ALGO_ELGAMAL_E: return 'g' ;
+    case PUBKEY_ALGO_ELGAMAL:   return 'G' ;
+    case PUBKEY_ALGO_DSA:      return 'D' ;
+    case PUBKEY_ALGO_ECDH:     return 'e' ;    /* ECC DH (encrypt only) */
+    case PUBKEY_ALGO_ECDSA:    return 'E' ;    /* ECC DSA (sign only)   */
+    case PUBKEY_ALGO_EDDSA:    return 'E' ;    /* ECC EdDSA (sign only) */
+    default: return '?';
+    }
+}
+
+/* Return a string describing the public key algorithm and the
+   keysize.  For elliptic curves the functions prints the name of the
+   curve because the keysize is a property of the curve.  The string
+   is copied to the supplied buffer up a length of BUFSIZE-1.
+   Examples for the output are:
+
+   "rsa2048"  - RSA with 2048 bit
+   "elg1024"  - Elgamal with 1024 bit
+   "ed25519"  - ECC using the curve Ed25519.
+   "E_1.2.3.4"  - ECC using the unsupported curve with OID "1.2.3.4".
+   "E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID.
+   "unknown_N"  - Unknown OpenPGP algorithm N.
+
+   If the option --legacy-list-mode is active, the output use the
+   legacy format:
+
+   "2048R" - RSA with 2048 bit
+   "1024g" - Elgamal with 1024 bit
+   "256E"  - ECDSA using a curve with 256 bit
+
+   The macro PUBKEY_STRING_SIZE may be used to allocate a buffer with
+   a suitable size.*/
+char *
+pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
+{
+  const char *prefix = NULL;
+
+  if (opt.legacy_list_mode)
+    {
+      snprintf (buffer, bufsize, "%4u%c",
+                nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo));
+      return buffer;
+    }
+
+  switch (pk->pubkey_algo)
+    {
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:    prefix = "rsa"; break;
+    case PUBKEY_ALGO_ELGAMAL_E: prefix = "elg"; break;
+    case PUBKEY_ALGO_DSA:      prefix = "dsa"; break;
+    case PUBKEY_ALGO_ELGAMAL:   prefix = "xxx"; break;
+    case PUBKEY_ALGO_ECDH:
+    case PUBKEY_ALGO_ECDSA:
+    case PUBKEY_ALGO_EDDSA:     prefix = "";    break;
+    }
+
+  if (prefix && *prefix)
+    snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
+  else if (prefix)
+    {
+      char *curve = openpgp_oid_to_str (pk->pkey[0]);
+      const char *name = openpgp_oid_to_curve (curve);
+
+      if (*name && *name != '?')
+        snprintf (buffer, bufsize, "%s", name);
+      else if (curve)
+        snprintf (buffer, bufsize, "E_%s", curve);
+      else
+        snprintf (buffer, bufsize, "E_error");
+      xfree (curve);
     }
+  else
+    snprintf (buffer, bufsize, "unknown_%u", (unsigned int)pk->pubkey_algo);
+
+  return buffer;
 }
 
-/* This function is useful for v4 fingerprints and v3 or v4 key
-   signing. */
+
+/* Hash a public key.  This function is useful for v4 fingerprints and
+   for v3 or v4 key signing. */
 void
-hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
+hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
 {
   unsigned int n = 6;
   unsigned int nn[PUBKEY_MAX_NPKEY];
@@ -65,10 +147,11 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
   size_t nbytes;
   int npkey = pubkey_get_npkey (pk->pubkey_algo);
 
-  /* Two extra bytes for the expiration date in v3 */
-  if(pk->version<4)
-    n+=2;
-
+  /* FIXME: We can avoid the extra malloc by calling only the first
+     mpi_print here which computes the required length and calling the
+     real mpi_print only at the end.  The speed advantage would only be
+     for ECC (opaque MPIs) or if we could implement an mpi_print
+     variant with a callback handler to do the hashing.  */
   if (npkey==0 && pk->pkey[0]
       && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
     {
@@ -77,17 +160,41 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
       n+=nn[0];
     }
   else
-    for(i=0; i < npkey; i++ )
-      {
-       if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i]))
-          BUG ();
-       pp[i] = xmalloc (nbytes);
-       if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
-                            &nbytes, pk->pkey[i]))
-          BUG ();
-        nn[i] = nbytes;
-       n += nn[i];
-      }
+    {
+      for (i=0; i < npkey; i++ )
+        {
+          if (!pk->pkey[i])
+            {
+              /* This case may only happen if the parsing of the MPI
+                 failed but the key was anyway created.  May happen
+                 during "gpg KEYFILE".  */
+              pp[i] = NULL;
+              nn[i] = 0;
+            }
+          else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
+            {
+              const void *p;
+
+              p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
+              pp[i] = xmalloc ((nbits+7)/8);
+              memcpy (pp[i], p, (nbits+7)/8);
+              nn[i] = (nbits+7)/8;
+              n += nn[i];
+            }
+          else
+            {
+              if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
+                                  &nbytes, pk->pkey[i]))
+                BUG ();
+              pp[i] = xmalloc (nbytes);
+              if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
+                                  &nbytes, pk->pkey[i]))
+                BUG ();
+              nn[i] = nbytes;
+              n += nn[i];
+            }
+        }
+    }
 
   gcry_md_putc ( md, 0x99 );     /* ctb */
   /* What does it mean if n is greater than than 0xFFFF ? */
@@ -100,35 +207,22 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
   gcry_md_putc ( md, pk->timestamp >>  8 );
   gcry_md_putc ( md, pk->timestamp       );
 
-  if(pk->version<4)
-    {
-      u16 days=0;
-      if(pk->expiredate)
-       days=(u16)((pk->expiredate - pk->timestamp) / 86400L);
-
-      gcry_md_putc ( md, days >> 8 );
-      gcry_md_putc ( md, days );
-    }
-
   gcry_md_putc ( md, pk->pubkey_algo );
 
   if(npkey==0 && pk->pkey[0]
      && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
     {
-      if (pp[0])
-        gcry_md_write (md, pp[0], nn[0]);
+      gcry_md_write (md, pp[0], nn[0]);
     }
   else
-    {
-      for(i=0; i < npkey; i++ )
-        {
-          if (pp[i])
-            gcry_md_write ( md, pp[i], nn[i] );
-          xfree(pp[i]);
-        }
-    }
+    for(i=0; i < npkey; i++ )
+      {
+       gcry_md_write ( md, pp[i], nn[i] );
+       xfree(pp[i]);
+      }
 }
 
+
 static gcry_md_hd_t
 do_fingerprint_md( PKT_public_key *pk )
 {
@@ -142,27 +236,9 @@ do_fingerprint_md( PKT_public_key *pk )
   return md;
 }
 
-static gcry_md_hd_t
-do_fingerprint_md_sk( PKT_secret_key *sk )
-{
-    PKT_public_key pk;
-    int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */
-    int i;
-
-    if(npkey==0)
-      return NULL;
-
-    pk.pubkey_algo = sk->pubkey_algo;
-    pk.version    = sk->version;
-    pk.timestamp = sk->timestamp;
-    pk.expiredate = sk->expiredate;
-    pk.pubkey_algo = sk->pubkey_algo;
-    for( i=0; i < npkey; i++ )
-      pk.pkey[i] = sk->skey[i];
-    return do_fingerprint_md( &pk );
-}
-
 
+/* fixme: Check whether we can replace this function or if not
+   describe why we need it.  */
 u32
 v3_keyid (gcry_mpi_t a, u32 *ki)
 {
@@ -180,9 +256,9 @@ v3_keyid (gcry_mpi_t a, u32 *ki)
   else
     {
       p = buffer + nbytes - 8;
-      ki[0] = buf32_to_u32 (p);
+      ki[0] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3];
       p += 4;
-      ki[1] = buf32_to_u32 (p);
+      ki[1] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3];
     }
   xfree (buffer);
   return ki[1];
@@ -211,33 +287,36 @@ keystrlen(void)
     }
 }
 
+
 const char *
-keystr(u32 *keyid)
+keystr (u32 *keyid)
 {
-  static char keyid_str[19];
+  static char keyid_str[KEYID_STR_SIZE];
 
-  switch(opt.keyid_format)
+  switch (opt.keyid_format)
     {
     case KF_SHORT:
-      sprintf(keyid_str,"%08lX",(ulong)keyid[1]);
+      snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
       break;
 
     case KF_LONG:
-      if(keyid[0])
-       sprintf(keyid_str,"%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
+      if (keyid[0])
+       snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
+                  (ulong)keyid[0], (ulong)keyid[1]);
       else
-       sprintf(keyid_str,"%08lX",(ulong)keyid[1]);
+       snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
       break;
 
     case KF_0xSHORT:
-      sprintf(keyid_str,"0x%08lX",(ulong)keyid[1]);
+      snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
       break;
 
     case KF_0xLONG:
       if(keyid[0])
-       sprintf(keyid_str,"0x%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
+       snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
+                  (ulong)keyid[0],(ulong)keyid[1]);
       else
-       sprintf(keyid_str,"0x%08lX",(ulong)keyid[1]);
+       snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
       break;
 
     default:
@@ -247,6 +326,24 @@ keystr(u32 *keyid)
   return keyid_str;
 }
 
+
+const char *
+keystr_with_sub (u32 *main_kid, u32 *sub_kid)
+{
+  static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
+  char *p;
+
+  mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
+  if (sub_kid)
+    {
+      p = buffer + strlen (buffer);
+      *p++ = '/';
+      mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
+    }
+  return buffer;
+}
+
+
 const char *
 keystr_from_pk(PKT_public_key *pk)
 {
@@ -255,14 +352,19 @@ keystr_from_pk(PKT_public_key *pk)
   return keystr(pk->keyid);
 }
 
+
 const char *
-keystr_from_sk(PKT_secret_key *sk)
+keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
 {
-  keyid_from_sk(sk,NULL);
+  keyid_from_pk (main_pk, NULL);
+  if (sub_pk)
+    keyid_from_pk (sub_pk, NULL);
 
-  return keystr(sk->keyid);
+  return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL);
 }
 
+
+
 const char *
 keystr_from_desc(KEYDB_SEARCH_DESC *desc)
 {
@@ -276,8 +378,15 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc)
       {
        u32 keyid[2];
 
-       keyid[0] = buf32_to_u32 (desc->u.fpr+12);
-       keyid[1] = buf32_to_u32 (desc->u.fpr+16);
+       keyid[0] = ((unsigned char)desc->u.fpr[12] << 24
+                    | (unsigned char)desc->u.fpr[13] << 16
+                    | (unsigned char)desc->u.fpr[14] << 8
+                    | (unsigned char)desc->u.fpr[15]);
+       keyid[1] = ((unsigned char)desc->u.fpr[16] << 24
+                    | (unsigned char)desc->u.fpr[17] << 16
+                    | (unsigned char)desc->u.fpr[18] << 8
+                    | (unsigned char)desc->u.fpr[19]);
+
        return keystr(keyid);
       }
 
@@ -289,72 +398,18 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc)
     }
 }
 
-/****************
- * Get the keyid from the secret key and put it into keyid
- * if this is not NULL. Return the 32 low bits of the keyid.
- */
-u32
-keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
-{
-  u32 lowbits;
-  u32 dummy_keyid[2];
-
-  if( !keyid )
-    keyid = dummy_keyid;
-
-  if( sk->keyid[0] || sk->keyid[1] )
-    {
-      keyid[0] = sk->keyid[0];
-      keyid[1] = sk->keyid[1];
-      lowbits = keyid[1];
-    }
-  else if( sk->version < 4 )
-    {
-      if( is_RSA(sk->pubkey_algo) )
-       {
-         lowbits = (pubkey_get_npkey (sk->pubkey_algo) ?
-                     v3_keyid( sk->skey[0], keyid ) : 0); /* Take n. */
-         sk->keyid[0]=keyid[0];
-         sk->keyid[1]=keyid[1];
-       }
-      else
-       sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
-    }
-  else
-    {
-      const byte *dp;
-      gcry_md_hd_t md;
-
-      md = do_fingerprint_md_sk(sk);
-      if(md)
-       {
-         dp = gcry_md_read (md, 0);
-         keyid[0] = buf32_to_u32 (dp+12);
-         keyid[1] = buf32_to_u32 (dp+16);
-         lowbits = keyid[1];
-         gcry_md_close (md);
-         sk->keyid[0] = keyid[0];
-         sk->keyid[1] = keyid[1];
-       }
-      else
-       sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
-    }
-
-  return lowbits;
-}
-
 
-/****************
+/*
  * Get the keyid from the public key and put it into keyid
  * if this is not NULL. Return the 32 low bits of the keyid.
  */
 u32
-keyid_from_pk( PKT_public_key *pk, u32 *keyid )
+keyid_from_pk (PKT_public_key *pk, u32 *keyid)
 {
   u32 lowbits;
   u32 dummy_keyid[2];
 
-  if( !keyid )
+  if (!keyid)
     keyid = dummy_keyid;
 
   if( pk->keyid[0] || pk->keyid[1] )
@@ -363,18 +418,6 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid )
       keyid[1] = pk->keyid[1];
       lowbits = keyid[1];
     }
-  else if( pk->version < 4 )
-    {
-      if( is_RSA(pk->pubkey_algo) )
-       {
-         lowbits = (pubkey_get_npkey (pk->pubkey_algo) ?
-                     v3_keyid ( pk->pkey[0], keyid ) : 0); /* From n. */
-         pk->keyid[0] = keyid[0];
-         pk->keyid[1] = keyid[1];
-       }
-      else
-       pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
-    }
   else
     {
       const byte *dp;
@@ -384,8 +427,8 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid )
       if(md)
        {
          dp = gcry_md_read ( md, 0 );
-         keyid[0] = buf32_to_u32 (dp+12);
-         keyid[1] = buf32_to_u32 (dp+16);
+         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
          lowbits = keyid[1];
          gcry_md_close (md);
          pk->keyid[0] = keyid[0];
@@ -399,61 +442,66 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid )
 }
 
 
-/****************
+/*
  * Get the keyid from the fingerprint. This function is simple for most
  * keys, but has to do a keylookup for old stayle keys.
  */
 u32
 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
 {
-    u32 dummy_keyid[2];
-
-    if( !keyid )
-       keyid = dummy_keyid;
-
-    if( fprint_len != 20 ) {
-       /* This is special as we have to lookup the key first */
-       PKT_public_key pk;
-       int rc;
-
-       memset( &pk, 0, sizeof pk );
-       rc = get_pubkey_byfprint( &pk, fprint, fprint_len );
-       if( rc ) {
-           log_error("Oops: keyid_from_fingerprint: no pubkey\n");
-           keyid[0] = 0;
-           keyid[1] = 0;
-       }
-       else
-           keyid_from_pk( &pk, keyid );
+  u32 dummy_keyid[2];
+
+  if( !keyid )
+    keyid = dummy_keyid;
+
+  if (fprint_len != 20)
+    {
+      /* This is special as we have to lookup the key first.  */
+      PKT_public_key pk;
+      int rc;
+
+      memset (&pk, 0, sizeof pk);
+      rc = get_pubkey_byfprint (&pk, fprint, fprint_len);
+      if( rc )
+        {
+          log_error("Oops: keyid_from_fingerprint: no pubkey\n");
+          keyid[0] = 0;
+          keyid[1] = 0;
+        }
+      else
+        keyid_from_pk (&pk, keyid);
     }
-    else {
-       const byte *dp = fprint;
-       keyid[0] = buf32_to_u32 (dp+12);
-       keyid[1] = buf32_to_u32 (dp+16);
+  else
+    {
+      const byte *dp = fprint;
+      keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+      keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
     }
 
-    return keyid[1];
+  return keyid[1];
 }
 
 
 u32
-keyid_from_sig( PKT_signature *sig, u32 *keyid )
+keyid_from_sig (PKT_signature *sig, u32 *keyid)
 {
-    if( keyid ) {
-       keyid[0] = sig->keyid[0];
-       keyid[1] = sig->keyid[1];
+  if( keyid )
+    {
+      keyid[0] = sig->keyid[0];
+      keyid[1] = sig->keyid[1];
     }
-    return sig->keyid[1];
+  return sig->keyid[1];
 }
 
+
 byte *
-namehash_from_uid(PKT_user_id *uid)
+namehash_from_uid (PKT_user_id *uid)
 {
   if (!uid->namehash)
     {
       uid->namehash = xmalloc (20);
 
-      if(uid->attrib_data)
+      if (uid->attrib_data)
        rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
       else
        rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
@@ -462,122 +510,100 @@ namehash_from_uid(PKT_user_id *uid)
   return uid->namehash;
 }
 
-/****************
- * return the number of bits used in the pk
- */
-unsigned
-nbits_from_pk( PKT_public_key *pk )
-{
-    return pubkey_nbits( pk->pubkey_algo, pk->pkey );
-}
 
-/****************
- * return the number of bits used in the sk
+/*
+ * Return the number of bits used in PK.
  */
-unsigned
-nbits_from_sk( PKT_secret_key *sk )
+unsigned int
+nbits_from_pk (PKT_public_key *pk)
 {
-    return pubkey_nbits( sk->pubkey_algo, sk->skey );
+    return pubkey_nbits (pk->pubkey_algo, pk->pkey);
 }
 
+
 static const char *
 mk_datestr (char *buffer, time_t atime)
 {
-    struct tm *tp;
-
-    if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
-        strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
-    else {
-        tp = gmtime (&atime);
-        sprintf (buffer,"%04d-%02d-%02d",
-                 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
+  struct tm *tp;
+
+  if (IS_INVALID_TIME_T (atime))
+    strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
+  else
+    {
+      tp = gmtime (&atime);
+      sprintf (buffer,"%04d-%02d-%02d",
+               1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     }
-    return buffer;
+  return buffer;
 }
 
-/****************
+
+/*
  * return a string with the creation date of the pk
  * Note: this is alloced in a static buffer.
  *    Format is: yyyy-mm-dd
  */
 const char *
-datestr_from_pk( PKT_public_key *pk )
+datestr_from_pk (PKT_public_key *pk)
 {
-    static char buffer[11+5];
-    time_t atime = pk->timestamp;
+  static char buffer[11+5];
+  time_t atime = pk->timestamp;
 
-    return mk_datestr (buffer, atime);
+  return mk_datestr (buffer, atime);
 }
 
-const char *
-datestr_from_sk( PKT_secret_key *sk )
-{
-    static char buffer[11+5];
-    time_t atime = sk->timestamp;
-
-    return mk_datestr (buffer, atime);
-}
 
 const char *
-datestr_from_sigPKT_signature *sig )
+datestr_from_sig (PKT_signature *sig )
 {
-    static char buffer[11+5];
-    time_t atime = sig->timestamp;
+  static char buffer[11+5];
+  time_t atime = sig->timestamp;
 
-    return mk_datestr (buffer, atime);
+  return mk_datestr (buffer, atime);
 }
 
-const char *
-expirestr_from_pk( PKT_public_key *pk )
-{
-    static char buffer[11+5];
-    time_t atime;
-
-    if( !pk->expiredate )
-       return _("never     ");
-    atime = pk->expiredate;
-    return mk_datestr (buffer, atime);
-}
 
 const char *
-expirestr_from_sk( PKT_secret_key *sk )
+expirestr_from_pk (PKT_public_key *pk)
 {
-    static char buffer[11+5];
-    time_t atime;
+  static char buffer[11+5];
+  time_t atime;
 
-    if( !sk->expiredate )
-       return _("never     ");
-    atime = sk->expiredate;
-    return mk_datestr (buffer, atime);
+  if (!pk->expiredate)
+    return _("never     ");
+  atime = pk->expiredate;
+  return mk_datestr (buffer, atime);
 }
 
+
 const char *
-expirestr_from_sig( PKT_signature *sig )
+expirestr_from_sig (PKT_signature *sig)
 {
-    static char buffer[11+5];
-    time_t atime;
+  static char buffer[11+5];
+  time_t atime;
 
-    if(!sig->expiredate)
-      return _("never     ");
-    atime=sig->expiredate;
-    return mk_datestr (buffer, atime);
+  if (!sig->expiredate)
+    return _("never     ");
+  atime=sig->expiredate;
+  return mk_datestr (buffer, atime);
 }
 
+
 const char *
 revokestr_from_pk( PKT_public_key *pk )
 {
-    static char buffer[11+5];
-    time_t atime;
+  static char buffer[11+5];
+  time_t atime;
 
-    if(!pk->revoked.date)
-      return _("never     ");
-    atime=pk->revoked.date;
-    return mk_datestr (buffer, atime);
+  if(!pk->revoked.date)
+    return _("never     ");
+  atime=pk->revoked.date;
+  return mk_datestr (buffer, atime);
 }
 
 
 const char *
-usagestr_from_pk( PKT_public_key *pk )
+usagestr_from_pk (PKT_public_key *pk, int fill)
 {
   static char buffer[10];
   int i = 0;
@@ -595,7 +621,7 @@ usagestr_from_pk( PKT_public_key *pk )
   if ( (use & PUBKEY_USAGE_AUTH) )
     buffer[i++] = 'A';
 
-  while (i < 4)
+  while (fill && i < 4)
     buffer[i++] = ' ';
 
   buffer[i] = 0;
@@ -623,14 +649,6 @@ colon_datestr_from_pk (PKT_public_key *pk)
   return buf;
 }
 
-const char *
-colon_datestr_from_sk (PKT_secret_key *sk)
-{
-  static char buf[20];
-
-  snprintf (buf, sizeof buf, "%lu", (ulong)sk->timestamp);
-  return buf;
-}
 
 const char *
 colon_datestr_from_sig (PKT_signature *sig)
@@ -654,176 +672,153 @@ colon_expirestr_from_sig (PKT_signature *sig)
 }
 
 
-/**************** .
+/*
  * Return a byte array with the fingerprint for the given PK/SK
  * The length of the array is returned in ret_len. Caller must free
  * the array or provide an array of length MAX_FINGERPRINT_LEN.
  */
-
 byte *
-fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
+fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
 {
-  byte *buf;
   const byte *dp;
-  size_t len, nbytes;
-  int i;
+  size_t len;
+  gcry_md_hd_t md;
 
-  if ( pk->version < 4 )
-    {
-      if (is_RSA(pk->pubkey_algo))
-        {
-          /* RSA in version 3 packets is special. */
-          gcry_md_hd_t md;
+  md = do_fingerprint_md(pk);
+  dp = gcry_md_read( md, 0 );
+  len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
+  assert( len <= MAX_FINGERPRINT_LEN );
+  if (!array)
+    array = xmalloc ( len );
+  memcpy (array, dp, len );
+  pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+  pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
+  gcry_md_close( md);
+
+  if (ret_len)
+    *ret_len = len;
+  return array;
+}
 
-          if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
-            BUG ();
-          if ( pubkey_get_npkey (pk->pubkey_algo) > 1 )
-            {
-              for (i=0; i < 2; i++)
-                {
-                  if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
-                                      &nbytes, pk->pkey[i]))
-                    BUG ();
-                  /* fixme: Better allocate BUF on the stack */
-                  buf = xmalloc (nbytes);
-                  if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes,
-                                      NULL, pk->pkey[i]))
-                    BUG ();
-                  gcry_md_write (md, buf, nbytes);
-                  xfree (buf);
-                }
-            }
-          gcry_md_final (md);
-          if (!array)
-            array = xmalloc (16);
-          len = 16;
-          memcpy (array, gcry_md_read (md, DIGEST_ALGO_MD5), 16);
-          gcry_md_close(md);
-        }
-      else
-        {
-          if (!array)
-            array = xmalloc(16);
-          len = 16;
-          memset (array,0,16);
-        }
-    }
-  else
-    {
-      gcry_md_hd_t md;
 
-      md = do_fingerprint_md(pk);
-      dp = gcry_md_read( md, 0 );
-      len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
-      assert( len <= MAX_FINGERPRINT_LEN );
-      if (!array)
-        array = xmalloc ( len );
-      memcpy (array, dp, len );
-      pk->keyid[0] = buf32_to_u32 (dp+12);
-      pk->keyid[1] = buf32_to_u32 (dp+16);
-      gcry_md_close( md);
-    }
+/* Return an allocated buffer with the fingerprint of PK formatted as
+   a plain hexstring.  */
+char *
+hexfingerprint (PKT_public_key *pk)
+{
+  unsigned char fpr[MAX_FINGERPRINT_LEN];
+  size_t len;
+  char *result;
 
-  *ret_len = len;
-  return array;
+  fingerprint_from_pk (pk, fpr, &len);
+  result = xmalloc (2 * len + 1);
+  bin2hex (fpr, len, result);
+  return result;
 }
 
-byte *
-fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
+
+\f
+/* Return the so called KEYGRIP which is the SHA-1 hash of the public
+   key parameters expressed as an canoncial encoded S-Exp.  ARRAY must
+   be 20 bytes long.  Returns 0 on sucess or an error code.  */
+gpg_error_t
+keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
 {
-  byte *buf;
-  const char *dp;
-  size_t len, nbytes;
-  int i;
+  gpg_error_t err;
+  gcry_sexp_t s_pkey;
+
+  if (DBG_PACKET)
+    log_debug ("get_keygrip for public key\n");
 
-  if (sk->version < 4)
+  switch (pk->pubkey_algo)
     {
-      if ( is_RSA(sk->pubkey_algo) )
-        {
-          /* RSA in version 3 packets is special. */
-          gcry_md_hd_t md;
+    case GCRY_PK_DSA:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                             pk->pkey[0], pk->pkey[1],
+                             pk->pkey[2], pk->pkey[3]);
+      break;
 
-          if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
-            BUG ();
-          if (pubkey_get_npkey( sk->pubkey_algo ) > 1)
-            {
-              for (i=0; i < 2; i++)
-                {
-                  if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
-                                      &nbytes, sk->skey[i]))
-                    BUG ();
-                  /* fixme: Better allocate BUF on the stack */
-                  buf = xmalloc (nbytes);
-                  if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes,
-                                      NULL, sk->skey[i]))
-                    BUG ();
-                  gcry_md_write (md, buf, nbytes);
-                  xfree (buf);
-                }
-           }
-          gcry_md_final(md);
-          if (!array)
-            array = xmalloc (16);
-          len = 16;
-          memcpy (array, gcry_md_read (md, DIGEST_ALGO_MD5), 16);
-          gcry_md_close (md);
-        }
-      else
-        {
-          if (!array)
-            array = xmalloc (16);
-          len=16;
-          memset (array,0,16);
-        }
+    case GCRY_PK_ELG:
+    case GCRY_PK_ELG_E:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(elg(p%m)(g%m)(y%m)))",
+                             pk->pkey[0], pk->pkey[1], pk->pkey[2]);
+      break;
+
+    case GCRY_PK_RSA:
+    case GCRY_PK_RSA_S:
+    case GCRY_PK_RSA_E:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(rsa(n%m)(e%m)))",
+                             pk->pkey[0], pk->pkey[1]);
+      break;
+
+    case PUBKEY_ALGO_EDDSA:
+    case PUBKEY_ALGO_ECDSA:
+    case PUBKEY_ALGO_ECDH:
+      {
+        char *curve = openpgp_oid_to_str (pk->pkey[0]);
+        if (!curve)
+          err = gpg_error_from_syserror ();
+        else
+          {
+            err = gcry_sexp_build (&s_pkey, NULL,
+                                   pk->pubkey_algo == PUBKEY_ALGO_EDDSA ?
+                                   "(public-key(ecc(curve%s)(flags eddsa)(q%m)))"
+                                   : "(public-key(ecc(curve%s)(q%m)))",
+                                   curve, pk->pkey[1]);
+            xfree (curve);
+          }
+      }
+      break;
+
+    default:
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      break;
+    }
+
+  if (err)
+    return err;
+
+  if (!gcry_pk_get_keygrip (s_pkey, array))
+    {
+      log_info ("error computing keygrip\n");
+      memset (array, 0, 20);
+      err = gpg_error (GPG_ERR_GENERAL);
     }
   else
     {
-      gcry_md_hd_t md;
-
-      md = do_fingerprint_md_sk(sk);
-      if (md)
-        {
-          dp = gcry_md_read ( md, 0 );
-          len = gcry_md_get_algo_dlen ( gcry_md_get_algo (md) );
-          assert ( len <= MAX_FINGERPRINT_LEN );
-          if (!array)
-            array = xmalloc( len );
-          memcpy (array, dp, len);
-          gcry_md_close (md);
-        }
-      else
-        {
-          len = MAX_FINGERPRINT_LEN;
-          if (!array)
-            array = xmalloc (len);
-          memset (array, 0, len);
-        }
+      if (DBG_PACKET)
+        log_printhex ("keygrip=", array, 20);
+      /* FIXME: Save the keygrip in PK.  */
     }
+  gcry_sexp_release (s_pkey);
 
-  *ret_len = len;
-  return array;
+  return 0;
 }
 
 
-/* Create a serialno/fpr string from the serial number and the secret
-   key.  Caller must free the returned string.  There is no error
-   return.  */
-char *
-serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
-                          PKT_secret_key *sk)
+/* Store an allocated buffer with the keygrip of PK encoded as a
+   hexstring at r_GRIP.  Returns 0 on success.  */
+gpg_error_t
+hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
 {
-  unsigned char fpr[MAX_FINGERPRINT_LEN];
-  size_t fprlen;
-  char *buffer, *p;
-  int i;
+  gpg_error_t err;
+  unsigned char grip[20];
 
-  fingerprint_from_sk (sk, fpr, &fprlen);
-  buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1);
-  for (i=0; i < snlen; i++, p+=2)
-    sprintf (p, "%02X", sn[i]);
-  *p++ = '/';
-  for (i=0; i < fprlen; i++, p+=2)
-    sprintf (p, "%02X", fpr[i]);
-  *p = 0;
-  return buffer;
+  *r_grip = NULL;
+  err = keygrip_from_pk (pk, grip);
+  if (!err)
+    {
+      char * buf = xtrymalloc (20*2+1);
+      if (!buf)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          bin2hex (grip, 20, buf);
+          *r_grip = buf;
+        }
+    }
+  return err;
 }
index 8db2147..b5ea84d 100644 (file)
@@ -1,6 +1,7 @@
-/* keylist.c - print keys
+/* keylist.c - Print information about OpenPGP keys
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2008, 2012 Free Software Foundation, Inc.
+ *               2008, 2010, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -25,7 +26,7 @@
 #include <errno.h>
 #include <assert.h>
 #ifdef HAVE_DOSISH_SYSTEM
-#include <fcntl.h> /* for setmode() */
+#include <fcntl.h>             /* for setmode() */
 #endif
 
 #include "gpg.h"
 #include "main.h"
 #include "i18n.h"
 #include "status.h"
+#include "call-agent.h"
 
-static void list_all(int);
-static void list_one( strlist_t names, int secret);
-static void locate_one (strlist_t names);
-static void print_card_serialno (PKT_secret_key *sk);
+static void list_all (int, int);
+static void list_one (strlist_t names, int secret, int mark_secret);
+static void locate_one (ctrl_t ctrl, strlist_t names);
+static void print_card_serialno (const char *serialno);
 
 struct sig_stats
 {
@@ -54,52 +56,53 @@ struct sig_stats
 };
 
 /* The stream used to write attribute packets to.  */
-static FILE *attrib_fp = NULL;
+static estream_t attrib_fp;
 
-/****************
- * List the keys
- * If list is NULL, all available keys are listed
- */
+
+/* List the keys.  If list is NULL, all available keys are listed.
+   With LOCATE_MODE set the locate algorithm is used to find a
  key.  */
 void
-public_key_list( strlist_t list, int locate_mode )
+public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
 {
+#ifndef NO_TRUST_MODELS
   if (opt.with_colons)
     {
-      byte trust_model,marginals,completes,cert_depth,min_cert_level;
-      ulong created,nextcheck;
+      byte trust_model, marginals, completes, cert_depth, min_cert_level;
+      ulong created, nextcheck;
 
-      read_trust_options(&trust_model,&created,&nextcheck,
-                        &marginals,&completes,&cert_depth,&min_cert_level);
+      read_trust_options (&trust_model, &created, &nextcheck,
+                         &marginals, &completes, &cert_depth, &min_cert_level);
 
-      printf("tru:");
+      es_fprintf (es_stdout, "tru:");
 
-      if(nextcheck && nextcheck <= make_timestamp())
-       printf("o");
-      if(trust_model!=opt.trust_model)
-       printf("t");
-      if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
+      if (nextcheck && nextcheck <= make_timestamp ())
+       es_fprintf (es_stdout, "o");
+      if (trust_model != opt.trust_model)
+       es_fprintf (es_stdout, "t");
+      if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC)
        {
-         if(marginals!=opt.marginals_needed)
-           printf("m");
-         if(completes!=opt.completes_needed)
-           printf("c");
-         if(cert_depth!=opt.max_cert_depth)
-           printf("d");
-         if(min_cert_level!=opt.min_cert_level)
-           printf("l");
+         if (marginals != opt.marginals_needed)
+           es_fprintf (es_stdout, "m");
+         if (completes != opt.completes_needed)
+           es_fprintf (es_stdout, "c");
+         if (cert_depth != opt.max_cert_depth)
+           es_fprintf (es_stdout, "d");
+         if (min_cert_level != opt.min_cert_level)
+           es_fprintf (es_stdout, "l");
        }
 
-      printf(":%d:%lu:%lu",trust_model,created,nextcheck);
+      es_fprintf (es_stdout, ":%d:%lu:%lu", trust_model, created, nextcheck);
 
       /* Only show marginals, completes, and cert_depth in the classic
-        or PGP trust models since they are not meaningful
-        otherwise. */
-
-      if(trust_model==TM_PGP || trust_model==TM_CLASSIC)
-       printf(":%d:%d:%d",marginals,completes,cert_depth);
+         or PGP trust models since they are not meaningful
+         otherwise. */
 
-      printf("\n");
+      if (trust_model == TM_PGP || trust_model == TM_CLASSIC)
+       es_fprintf (es_stdout, ":%d:%d:%d", marginals, completes, cert_depth);
+      es_fprintf (es_stdout, "\n");
     }
+#endif /*!NO_TRUST_MODELS*/
 
   /* We need to do the stale check right here because it might need to
      update the keyring while we already have the keyring open.  This
@@ -109,185 +112,196 @@ public_key_list( strlist_t list, int locate_mode )
   check_trustdb_stale ();
 
   if (locate_mode)
-    locate_one (list);
+    locate_one (ctrl, list);
   else if (!list)
-    list_all (0);
+    list_all (0, opt.with_secret);
   else
-    list_one (list, 0);
+    list_one (list, 0, opt.with_secret);
 }
 
 
 void
-secret_key_list( strlist_t list )
+secret_key_list (ctrl_t ctrl, strlist_t list)
 {
-    check_trustdb_stale ();
+  (void)ctrl;
 
-    if( !list )
-       list_all(1);
-    else  /* List by user id */
-       list_one( list, 1 );
+  check_trustdb_stale ();
+
+  if (!list)
+    list_all (1, 0);
+  else                         /* List by user id */
+    list_one (list, 1, 0);
 }
 
 void
-print_seckey_info (PKT_secret_key *sk)
+print_seckey_info (PKT_public_key *pk)
 {
   u32 keyid[2];
   char *p;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
-  keyid_from_sk (sk, keyid);
-  p=get_user_id_native(keyid);
+  keyid_from_pk (pk, keyid);
+  p = get_user_id_native (keyid);
 
-  tty_printf ("\nsec  %4u%c/%s %s %s\n",
-             nbits_from_sk (sk),
-             pubkey_letter (sk->pubkey_algo),
-             keystr(keyid), datestr_from_sk (sk), p);
+  tty_printf ("\nsec  %s/%s %s %s\n",
+              pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+             keystr (keyid), datestr_from_pk (pk), p);
 
   xfree (p);
 }
 
 /* Print information about the public key.  With FP passed as NULL,
    the tty output interface is used, otherwise output is directted to
-   the given stream. */
+   the given stream.  */
 void
-print_pubkey_info (FILE *fp, PKT_public_key *pk)
+print_pubkey_info (estream_t fp, PKT_public_key * pk)
 {
   u32 keyid[2];
   char *p;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
   keyid_from_pk (pk, keyid);
 
   /* If the pk was chosen by a particular user ID, that is the one to
-     print. */
-  if(pk->user_id)
-    p=utf8_to_native(pk->user_id->name,pk->user_id->len,0);
+     print.  */
+  if (pk->user_id)
+    p = utf8_to_native (pk->user_id->name, pk->user_id->len, 0);
   else
-    p=get_user_id_native(keyid);
+    p = get_user_id_native (keyid);
 
   if (fp)
-    fprintf (fp, "%s  %4u%c/%s %s %s\n",
-             pk->is_primary? "pub":"sub",
-             nbits_from_pk (pk),
-             pubkey_letter (pk->pubkey_algo),
-             keystr(keyid), datestr_from_pk (pk), p);
-  else
-    tty_printf ("\n%s  %4u%c/%s %s %s\n",
-                pk->is_primary? "pub":"sub",
-                nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo),
-                keystr(keyid), datestr_from_pk (pk), p);
-
+    tty_printf ("\n");
+  tty_fprintf (fp, "pub  %s/%s %s %s\n",
+               pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+               keystr (keyid), datestr_from_pk (pk), p);
   xfree (p);
 }
 
 
 /* Print basic information of a secret key including the card serial
-   number information. */
+   number information.  */
+#ifdef ENABLE_CARD_SUPPORT
 void
-print_card_key_info (FILE *fp, KBNODE keyblock)
+print_card_key_info (estream_t fp, kbnode_t keyblock)
 {
-  KBNODE node;
-  int i;
+  kbnode_t node;
+  char *hexgrip;
+  char *serialno;
+  int s2k_char;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
-  for (node = keyblock; node; node = node->next )
+  for (node = keyblock; node; node = node->next)
     {
-      if (node->pkt->pkttype == PKT_SECRET_KEY
-          || (node->pkt->pkttype == PKT_SECRET_SUBKEY) )
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
         {
-          PKT_secret_key *sk = node->pkt->pkt.secret_key;
-
-          tty_fprintf (fp, "%s%c  %4u%c/%s  ",
-                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
-                       (sk->protect.s2k.mode==1001)?'#':
-                       (sk->protect.s2k.mode==1002)?'>':' ',
-                      nbits_from_sk (sk),
-                      pubkey_letter (sk->pubkey_algo),
-                      keystr_from_sk(sk));
-          tty_fprintf (fp, _("created: %s"), datestr_from_sk (sk));
+          int rc;
+          PKT_public_key *pk = node->pkt->pkt.public_key;
+
+          serialno = NULL;
+          rc = hexkeygrip_from_pk (pk, &hexgrip);
+          if (rc)
+            {
+              log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
+              s2k_char = '?';
+            }
+          else if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
+            s2k_char = serialno? '>':' ';
+          else
+            s2k_char = '#';  /* Key not found.  */
+
+          tty_fprintf (fp, "%s%c  %s/%s  ",
+                       node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb",
+                       s2k_char,
+                       pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                       keystr_from_pk (pk));
+          tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
           tty_fprintf (fp, "  ");
-          tty_fprintf (fp, _("expires: %s"), expirestr_from_sk (sk));
-          if (sk->is_protected && sk->protect.s2k.mode == 1002)
+          tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
+          if (serialno)
             {
               tty_fprintf (fp, "\n                      ");
               tty_fprintf (fp, _("card-no: "));
-              if (sk->protect.ivlen == 16
-                  && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
+              if (strlen (serialno) == 32
+                  && !strncmp (serialno, "D27600012401", 12))
                 {
-                  /* This is an OpenPGP card. */
-                  for (i=8; i < 14; i++)
-                    {
-                      if (i == 10)
-                        tty_fprintf (fp, " ");
-                      tty_fprintf (fp, "%02X", sk->protect.iv[i]);
-                    }
+                  /* This is an OpenPGP card.  Print the relevant part.  */
+                  /* Example: D2760001240101010001000003470000 */
+                  /*                          xxxxyyyyyyyy     */
+                  tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
                 }
               else
-                { /* Something is wrong: Print all. */
-                  for (i=0; i < sk->protect.ivlen; i++)
-                    tty_fprintf (fp, "%02X", sk->protect.iv[i]);
-                }
+                tty_fprintf (fp, "%s", serialno);
             }
           tty_fprintf (fp, "\n");
+          xfree (hexgrip);
+          xfree (serialno);
         }
     }
 }
+#endif /*ENABLE_CARD_SUPPORT*/
 
 
-
-/* Flags = 0x01 hashed 0x02 critical */
+/* Flags = 0x01 hashed 0x02 critical.  */
 static void
-status_one_subpacket(sigsubpkttype_t type,size_t len,int flags,const byte *buf)
+status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
+                     const byte * buf)
 {
   char status[40];
 
   /* Don't print these. */
-  if(len>256)
+  if (len > 256)
     return;
 
-  sprintf(status,"%d %u %u ",type,flags,(unsigned int)len);
+  snprintf (status, sizeof status,
+            "%d %u %u ", type, flags, (unsigned int) len);
 
-  write_status_text_and_buffer(STATUS_SIG_SUBPACKET,status,buf,len,0);
+  write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
 }
 
-/*
-  mode=0 for stdout.
-  mode=1 for log_info + status messages
-  mode=2 for status messages only
-*/
 
+/* Print a policy URL.  Allowed values for MODE are:
+ *   0 - print to stdout.
+ *   1 - use log_info and emit status messages.
+ *   2 - emit only status messages.
+ */
 void
-show_policy_url(PKT_signature *sig,int indent,int mode)
+show_policy_url (PKT_signature * sig, int indent, int mode)
 {
   const byte *p;
   size_t len;
-  int seq=0,crit;
-  FILE *fp=mode?log_get_stream():stdout;
+  int seq = 0, crit;
+  estream_t fp = mode ? log_get_stream () : es_stdout;
 
-  while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len,&seq,&crit)))
+  while ((p =
+         enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit)))
     {
-      if(mode!=2)
+      if (mode != 2)
        {
          int i;
          const char *str;
 
-         for(i=0;i<indent;i++)
-           putchar(' ');
+         for (i = 0; i < indent; i++)
+           es_putc (' ', fp);
 
-         if(crit)
-           str=_("Critical signature policy: ");
+         if (crit)
+           str = _("Critical signature policy: ");
          else
-           str=_("Signature policy: ");
-         if(mode)
-           log_info("%s",str);
+           str = _("Signature policy: ");
+         if (mode)
+           log_info ("%s", str);
          else
-           printf("%s",str);
-         print_utf8_string(fp,p,len);
-         fprintf(fp,"\n");
+           es_fprintf (fp, "%s", str);
+         print_utf8_buffer (fp, p, len);
+         es_fprintf (fp, "\n");
        }
 
-      if(mode)
-       write_status_buffer ( STATUS_POLICY_URL, p, len, 0 );
+      if (mode)
+       write_status_buffer (STATUS_POLICY_URL, p, len, 0);
     }
 }
 
+
 /*
   mode=0 for stdout.
   mode=1 for log_info + status messages
@@ -295,37 +309,40 @@ show_policy_url(PKT_signature *sig,int indent,int mode)
 */
 /* TODO: use this */
 void
-show_keyserver_url(PKT_signature *sig,int indent,int mode)
+show_keyserver_url (PKT_signature * sig, int indent, int mode)
 {
   const byte *p;
   size_t len;
-  int seq=0,crit;
-  FILE *fp=mode?log_get_stream():stdout;
+  int seq = 0, crit;
+  estream_t fp = mode ? log_get_stream () : es_stdout;
 
-  while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit)))
+  while ((p =
+         enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq,
+                          &crit)))
     {
-      if(mode!=2)
+      if (mode != 2)
        {
          int i;
          const char *str;
 
-         for(i=0;i<indent;i++)
-           putchar(' ');
+         for (i = 0; i < indent; i++)
+           es_putc (' ', es_stdout);
 
-         if(crit)
-           str=_("Critical preferred keyserver: ");
+         if (crit)
+           str = _("Critical preferred keyserver: ");
          else
-           str=_("Preferred keyserver: ");
-         if(mode)
-           log_info("%s",str);
+           str = _("Preferred keyserver: ");
+         if (mode)
+           log_info ("%s", str);
          else
-           printf("%s",str);
-         print_utf8_string(fp,p,len);
-         fprintf(fp,"\n");
+           es_fprintf (es_stdout, "%s", str);
+         print_utf8_buffer (fp, p, len);
+         es_fprintf (fp, "\n");
        }
 
-      if(mode)
-       status_one_subpacket(SIGSUBPKT_PREF_KS,len,(crit?0x02:0)|0x01,p);
+      if (mode)
+       status_one_subpacket (SIGSUBPKT_PREF_KS, len,
+                             (crit ? 0x02 : 0) | 0x01, p);
     }
 }
 
@@ -334,214 +351,221 @@ show_keyserver_url(PKT_signature *sig,int indent,int mode)
   mode=1 for log_info + status messages
   mode=2 for status messages only
 
-  which bits:
-  1 == standard notations
-  2 == user notations
+  Defined bits in WHICH:
+    1 == standard notations
+    2 == user notations
 */
-
 void
-show_notation(PKT_signature *sig,int indent,int mode,int which)
+show_notation (PKT_signature * sig, int indent, int mode, int which)
 {
-  FILE *fp=mode?log_get_stream():stdout;
-  struct notation *nd,*notations;
+  estream_t fp = mode ? log_get_stream () : es_stdout;
+  struct notation *nd, *notations;
 
-  if(which==0)
-    which=3;
+  if (which == 0)
+    which = 3;
 
-  notations=sig_to_notation(sig);
+  notations = sig_to_notation (sig);
 
   /* There may be multiple notations in the same sig. */
-  for(nd=notations;nd;nd=nd->next)
+  for (nd = notations; nd; nd = nd->next)
     {
-      if(mode!=2)
+      if (mode != 2)
        {
-         int has_at=!!strchr(nd->name,'@');
+         int has_at = !!strchr (nd->name, '@');
 
-         if((which&1 && !has_at) || (which&2 && has_at))
+         if ((which & 1 && !has_at) || (which & 2 && has_at))
            {
              int i;
              const char *str;
 
-             for(i=0;i<indent;i++)
-               putchar(' ');
+             for (i = 0; i < indent; i++)
+               es_putc (' ', es_stdout);
 
-             if(nd->flags.critical)
-               str=_("Critical signature notation: ");
+             if (nd->flags.critical)
+               str = _("Critical signature notation: ");
              else
-               str=_("Signature notation: ");
-             if(mode)
-               log_info("%s",str);
+               str = _("Signature notation: ");
+             if (mode)
+               log_info ("%s", str);
              else
-               printf("%s",str);
+               es_fprintf (es_stdout, "%s", str);
              /* This is all UTF8 */
-             print_utf8_string(fp,nd->name,strlen(nd->name));
-             fprintf(fp,"=");
-             print_utf8_string(fp,nd->value,strlen(nd->value));
-             fprintf(fp,"\n");
+             print_utf8_buffer (fp, nd->name, strlen (nd->name));
+             es_fprintf (fp, "=");
+             print_utf8_buffer (fp, nd->value, strlen (nd->value));
+             es_fprintf (fp, "\n");
            }
        }
 
-      if(mode)
+      if (mode)
        {
-         write_status_buffer(STATUS_NOTATION_NAME,
-                             nd->name,strlen(nd->name),0);
-         write_status_buffer(STATUS_NOTATION_DATA,
-                             nd->value,strlen(nd->value),50);
+         write_status_buffer (STATUS_NOTATION_NAME,
+                              nd->name, strlen (nd->name), 0);
+         write_status_buffer (STATUS_NOTATION_DATA,
+                              nd->value, strlen (nd->value), 50);
        }
     }
 
-  free_notation(notations);
+  free_notation (notations);
 }
 
 static void
-print_signature_stats(struct sig_stats *s)
+print_signature_stats (struct sig_stats *s)
 {
-  if( s->inv_sigs == 1 )
-    tty_printf(_("1 bad signature\n") );
-  else if( s->inv_sigs )
-    tty_printf(_("%d bad signatures\n"), s->inv_sigs );
-  if( s->no_key == 1 )
-    tty_printf(_("1 signature not checked due to a missing key\n") );
-  else if( s->no_key )
-    tty_printf(_("%d signatures not checked due to missing keys\n"),s->no_key);
-  if( s->oth_err == 1 )
-    tty_printf(_("1 signature not checked due to an error\n") );
-  else if( s->oth_err )
-    tty_printf(_("%d signatures not checked due to errors\n"), s->oth_err );
+  if (s->inv_sigs == 1)
+    tty_printf (_("1 bad signature\n"));
+  else if (s->inv_sigs)
+    tty_printf (_("%d bad signatures\n"), s->inv_sigs);
+  if (s->no_key == 1)
+    tty_printf (_("1 signature not checked due to a missing key\n"));
+  else if (s->no_key)
+    tty_printf (_("%d signatures not checked due to missing keys\n"),
+               s->no_key);
+  if (s->oth_err == 1)
+    tty_printf (_("1 signature not checked due to an error\n"));
+  else if (s->oth_err)
+    tty_printf (_("%d signatures not checked due to errors\n"), s->oth_err);
 }
 
+
+/* List all keys.  If SECRET is true only secret keys are listed.  If
+   MARK_SECRET is true secret keys are indicated in a public key
+   listing.  */
 static void
-list_all( int secret )
+list_all (int secret, int mark_secret)
 {
-    KEYDB_HANDLE hd;
-    KBNODE keyblock = NULL;
-    int rc=0;
-    const char *lastresname, *resname;
-    struct sig_stats stats;
-
-    memset(&stats,0,sizeof(stats));
-
-    hd = keydb_new (secret);
-    if (!hd)
-        rc = G10ERR_GENERAL;
-    else
-        rc = keydb_search_first (hd);
-    if( rc ) {
-       if( rc != -1 )
-           log_error("keydb_search_first failed: %s\n", g10_errstr(rc) );
-       goto leave;
+  KEYDB_HANDLE hd;
+  KBNODE keyblock = NULL;
+  int rc = 0;
+  int any_secret;
+  const char *lastresname, *resname;
+  struct sig_stats stats;
+
+  memset (&stats, 0, sizeof (stats));
+
+  hd = keydb_new ();
+  if (!hd)
+    rc = gpg_error (GPG_ERR_GENERAL);
+  else
+    rc = keydb_search_first (hd);
+  if (rc)
+    {
+      if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
+       log_error ("keydb_search_first failed: %s\n", g10_errstr (rc));
+      goto leave;
     }
 
-    lastresname = NULL;
-    do {
-        rc = keydb_get_keyblock (hd, &keyblock);
-        if (rc) {
-            log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
-            goto leave;
+  lastresname = NULL;
+  do
+    {
+      rc = keydb_get_keyblock (hd, &keyblock);
+      if (rc)
+       {
+         log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
+         goto leave;
+       }
+
+      if (secret || mark_secret)
+        any_secret = !agent_probe_any_secret_key (NULL, keyblock);
+      else
+        any_secret = 0;
+
+      if (secret && !any_secret)
+        ; /* Secret key listing requested but this isn't one.  */
+      else
+        {
+          if (!opt.with_colons)
+            {
+              resname = keydb_get_resource_name (hd);
+              if (lastresname != resname)
+                {
+                  int i;
+
+                  es_fprintf (es_stdout, "%s\n", resname);
+                  for (i = strlen (resname); i; i--)
+                    es_putc ('-', es_stdout);
+                  es_putc ('\n', es_stdout);
+                  lastresname = resname;
+                }
+            }
+          merge_keys_and_selfsig (keyblock);
+          list_keyblock (keyblock, secret, any_secret, opt.fingerprint,
+                         opt.check_sigs ? &stats : NULL);
         }
-       if(!opt.with_colons)
-         {
-           resname = keydb_get_resource_name (hd);
-           if (lastresname != resname )
-             {
-               int i;
-
-               printf("%s\n", resname );
-               for(i=strlen(resname); i; i-- )
-                 putchar('-');
-               putchar('\n');
-               lastresname = resname;
-             }
-         }
-        merge_keys_and_selfsig( keyblock );
-       list_keyblock( keyblock, secret, opt.fingerprint,
-                      opt.check_sigs?&stats:NULL);
-       release_kbnode( keyblock );
-        keyblock = NULL;
-    } while (!(rc = keydb_search_next (hd)));
-    if( rc && rc != -1 )
-       log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
-
-    if(opt.check_sigs && !opt.with_colons)
-      print_signature_stats(&stats);
-
-  leave:
-    release_kbnode (keyblock);
-    keydb_release (hd);
+      release_kbnode (keyblock);
+      keyblock = NULL;
+    }
+  while (!(rc = keydb_search_next (hd)));
+  es_fflush (es_stdout);
+  if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
+    log_error ("keydb_search_next failed: %s\n", g10_errstr (rc));
+  if (keydb_get_skipped_counter (hd))
+    log_info (_("Warning: %lu key(s) skipped due to their large size\n"),
+              keydb_get_skipped_counter (hd));
+
+  if (opt.check_sigs && !opt.with_colons)
+    print_signature_stats (&stats);
+
+leave:
+  release_kbnode (keyblock);
+  keydb_release (hd);
 }
 
 
 static void
-list_one( strlist_t names, int secret )
+list_one (strlist_t names, int secret, int mark_secret)
 {
-    int rc = 0;
-    KBNODE keyblock = NULL;
-    GETKEY_CTX ctx;
-    const char *resname;
-    const char *keyring_str = _("Keyring");
-    int i;
-    struct sig_stats stats;
-
-    memset(&stats,0,sizeof(stats));
-
-    /* fixme: using the bynames function has the disadvantage that we
-     * don't know wether one of the names given was not found.  OTOH,
-     * this function has the advantage to list the names in the
-     * sequence as defined by the keyDB and does not duplicate
-     * outputs.  A solution could be do test whether all given have
-     * been listed (this needs a way to use the keyDB search
-     * functions) or to have the search function return indicators for
-     * found names.  Yet another way is to use the keydb search
-     * facilities directly. */
-    if( secret ) {
-       rc = get_seckey_bynames( &ctx, NULL, names, &keyblock );
-       if( rc ) {
-           log_error("error reading key: %s\n",  g10_errstr(rc) );
-           get_seckey_end( ctx );
-           return;
-       }
-       do {
-           if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) {
-               resname = keydb_get_resource_name (get_ctx_handle(ctx));
-               printf("%s: %s\n", keyring_str, resname);
-               for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- )
-                   putchar('-');
-               putchar('\n');
-           }
-           list_keyblock( keyblock, 1, opt.fingerprint, NULL );
-           release_kbnode( keyblock );
-       } while( !get_seckey_next( ctx, NULL, &keyblock ) );
-       get_seckey_end( ctx );
+  int rc = 0;
+  KBNODE keyblock = NULL;
+  GETKEY_CTX ctx;
+  const char *resname;
+  const char *keyring_str = _("Keyring");
+  int i;
+  struct sig_stats stats;
+
+  memset (&stats, 0, sizeof (stats));
+
+  /* fixme: using the bynames function has the disadvantage that we
+   * don't know wether one of the names given was not found.  OTOH,
+   * this function has the advantage to list the names in the
+   * sequence as defined by the keyDB and does not duplicate
+   * outputs.  A solution could be do test whether all given have
+   * been listed (this needs a way to use the keyDB search
+   * functions) or to have the search function return indicators for
+   * found names.  Yet another way is to use the keydb search
+   * facilities directly. */
+  rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
+  if (rc)
+    {
+      log_error ("error reading key: %s\n", g10_errstr (rc));
+      get_pubkey_end (ctx);
+      return;
     }
-    else {
-       rc = get_pubkey_bynames( &ctx, NULL, names, &keyblock );
-       if( rc ) {
-           log_error("error reading key: %s\n", g10_errstr(rc) );
-           get_pubkey_end( ctx );
-           return;
-       }
-       do {
-         if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) {
-               resname = keydb_get_resource_name (get_ctx_handle(ctx));
-               printf("%s: %s\n", keyring_str, resname);
-               for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- )
-                   putchar('-');
-               putchar('\n');
-           }
-           list_keyblock( keyblock, 0, opt.fingerprint,
-                          opt.check_sigs?&stats:NULL );
-           release_kbnode( keyblock );
-       } while( !get_pubkey_next( ctx, NULL, &keyblock ) );
-       get_pubkey_end( ctx );
+
+  do
+    {
+      if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
+        {
+          resname = keydb_get_resource_name (get_ctx_handle (ctx));
+          es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
+          for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
+            es_putc ('-', es_stdout);
+          es_putc ('\n', es_stdout);
+        }
+      list_keyblock (keyblock, secret, mark_secret, opt.fingerprint,
+                     (!secret && opt.check_sigs)? &stats : NULL);
+      release_kbnode (keyblock);
     }
+  while (!getkey_next (ctx, NULL, &keyblock));
+  getkey_end (ctx);
 
-    if(opt.check_sigs && !opt.with_colons)
-      print_signature_stats(&stats);
+  if (opt.check_sigs && !opt.with_colons)
+    print_signature_stats (&stats);
 }
 
 
 static void
-locate_one (strlist_t names)
+locate_one (ctrl_t ctrl, strlist_t names)
 {
   int rc = 0;
   strlist_t sl;
@@ -549,27 +573,27 @@ locate_one (strlist_t names)
   KBNODE keyblock = NULL;
   struct sig_stats stats;
 
-  memset (&stats,0,sizeof(stats));
+  memset (&stats, 0, sizeof (stats));
 
-  for (sl=names; sl; sl = sl->next)
+  for (sl = names; sl; sl = sl->next)
     {
-      rc = get_pubkey_byname (&ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
+      rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
       if (rc)
-        {
-          if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
-            log_error ("error reading key: %s\n", g10_errstr(rc) );
+       {
+         if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
+           log_error ("error reading key: %s\n", g10_errstr (rc));
        }
       else
-        {
-          do
-            {
-              list_keyblock (keyblock, 0, opt.fingerprint,
-                             opt.check_sigs? &stats : NULL );
-              release_kbnode (keyblock);
-            }
-          while ( ctx && !get_pubkey_next (ctx, NULL, &keyblock));
-          get_pubkey_end (ctx);
-          ctx = NULL;
+       {
+         do
+           {
+             list_keyblock (keyblock, 0, 0, opt.fingerprint,
+                            opt.check_sigs ? &stats : NULL);
+             release_kbnode (keyblock);
+           }
+         while (ctx && !get_pubkey_next (ctx, NULL, &keyblock));
+         get_pubkey_end (ctx);
+         ctx = NULL;
        }
     }
 
@@ -579,827 +603,905 @@ locate_one (strlist_t names)
 
 
 static void
-print_key_data( PKT_public_key *pk )
+print_key_data (PKT_public_key * pk)
 {
-    int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
-    int i;
-
-    for(i=0; i < n; i++ ) {
-       printf("pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
-       mpi_print(stdout, pk->pkey[i], 1 );
-       putchar(':');
-       putchar('\n');
+  int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
+      mpi_print (es_stdout, pk->pkey[i], 1);
+      es_putc (':', es_stdout);
+      es_putc ('\n', es_stdout);
     }
 }
 
 static void
-print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock)
+print_capabilities (PKT_public_key *pk, KBNODE keyblock)
 {
-  if(pk || (sk && sk->protect.s2k.mode!=1001))
+  unsigned int use = pk->pubkey_usage;
+  int c_printed = 0;
+
+  if (use & PUBKEY_USAGE_ENC)
+    es_putc ('e', es_stdout);
+
+  if (use & PUBKEY_USAGE_SIG)
     {
-      unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage;
-      int c_printed = 0;
+      es_putc ('s', es_stdout);
+      if (pk->flags.primary)
+        {
+          es_putc ('c', es_stdout);
+          /* The PUBKEY_USAGE_CERT flag was introduced later and we
+             used to always print 'c' for a primary key.  To avoid any
+             regression here we better track whether we printed 'c'
+             already.  */
+          c_printed = 1;
+        }
+    }
 
-      if ( use & PUBKEY_USAGE_ENC )
-        putchar ('e');
+  if ((use & PUBKEY_USAGE_CERT) && !c_printed)
+    es_putc ('c', es_stdout);
 
-      if ( use & PUBKEY_USAGE_SIG )
-       {
-         putchar ('s');
-         if( pk? pk->is_primary : sk->is_primary )
-            {
-              putchar ('c');
-              /* The PUBKEY_USAGE_CERT flag was introduced later and
-                 we used to always print 'c' for a primary key.  To
-                 avoid any regression here we better track whether we
-                 printed 'c' already.  */
-              c_printed = 1;
-            }
-       }
+  if ((use & PUBKEY_USAGE_AUTH))
+    es_putc ('a', es_stdout);
 
-      if ( (use & PUBKEY_USAGE_CERT) && !c_printed )
-        putchar ('c');
+  if ((use & PUBKEY_USAGE_UNKNOWN))
+    es_putc ('?', es_stdout);
 
-      if ( (use & PUBKEY_USAGE_AUTH) )
-        putchar ('a');
-    }
+  if (keyblock)
+    {
+      /* Figure out the usable capabilities.  */
+      KBNODE k;
+      int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
 
-    if ( keyblock ) { /* figure out the usable capabilities */
-        KBNODE k;
-        int enc=0, sign=0, cert=0, auth=0, disabled=0;
-
-        for (k=keyblock; k; k = k->next ) {
-            if ( k->pkt->pkttype == PKT_PUBLIC_KEY
-                 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-                pk = k->pkt->pkt.public_key;
-
-               if(pk->is_primary)
-                 disabled=pk_is_disabled(pk);
-
-                if ( pk->is_valid && !pk->is_revoked && !pk->has_expired ) {
-                    if ( pk->pubkey_usage & PUBKEY_USAGE_ENC )
-                        enc = 1;
-                    if ( pk->pubkey_usage & PUBKEY_USAGE_SIG )
-                     {
-                       sign = 1;
-                       if(pk->is_primary)
-                         cert = 1;
-                     }
-                    if ( pk->pubkey_usage & PUBKEY_USAGE_CERT )
-                      cert = 1;
-                    if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) )
-                      auth = 1;
-                }
-            }
-            else if ( k->pkt->pkttype == PKT_SECRET_KEY
-                      || k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-                sk = k->pkt->pkt.secret_key;
-                if ( sk->is_valid && !sk->is_revoked && !sk->has_expired
-                    && sk->protect.s2k.mode!=1001 ) {
-                    if ( sk->pubkey_usage & PUBKEY_USAGE_ENC )
-                        enc = 1;
-                    if ( sk->pubkey_usage & PUBKEY_USAGE_SIG )
-                     {
-                       sign = 1;
-                       if(sk->is_primary)
-                         cert = 1;
-                     }
-                    if ( (sk->pubkey_usage & PUBKEY_USAGE_CERT) )
-                        cert = 1;
-                    if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) )
-                        auth = 1;
-                }
-            }
-        }
-        if (enc)
-            putchar ('E');
-        if (sign)
-            putchar ('S');
-        if (cert)
-            putchar ('C');
-        if (auth)
-            putchar ('A');
-        if (disabled)
-            putchar ('D');
+      for (k = keyblock; k; k = k->next)
+       {
+         if (k->pkt->pkttype == PKT_PUBLIC_KEY
+             || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+           {
+             pk = k->pkt->pkt.public_key;
+
+             if (pk->flags.primary)
+               disabled = pk_is_disabled (pk);
+
+             if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
+               {
+                 if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
+                   enc = 1;
+                 if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
+                   {
+                     sign = 1;
+                     if (pk->flags.primary)
+                       cert = 1;
+                   }
+                 if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
+                   cert = 1;
+                 if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
+                   auth = 1;
+               }
+           }
+       }
+      if (enc)
+       es_putc ('E', es_stdout);
+      if (sign)
+       es_putc ('S', es_stdout);
+      if (cert)
+       es_putc ('C', es_stdout);
+      if (auth)
+       es_putc ('A', es_stdout);
+      if (disabled)
+       es_putc ('D', es_stdout);
     }
 
-    putchar(':');
+  es_putc (':', es_stdout);
 }
 
-/* Flags = 0x01 hashed 0x02 critical */
+
+/* FLAGS: 0x01 hashed
+          0x02 critical  */
 static void
-print_one_subpacket(sigsubpkttype_t type,size_t len,int flags,const byte *buf)
+print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
+                    const byte * buf)
 {
   size_t i;
 
-  printf("spk:%d:%u:%u:",type,flags,(unsigned int)len);
+  es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
 
-  for(i=0;i<len;i++)
+  for (i = 0; i < len; i++)
     {
       /* printable ascii other than : and % */
-      if(buf[i]>=32 && buf[i]<=126 && buf[i]!=':' && buf[i]!='%')
-       printf("%c",buf[i]);
+      if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
+       es_fprintf (es_stdout, "%c", buf[i]);
       else
-       printf("%%%02X",buf[i]);
+       es_fprintf (es_stdout, "%%%02X", buf[i]);
     }
 
-  printf("\n");
+  es_fprintf (es_stdout, "\n");
 }
 
+
 void
-print_subpackets_colon(PKT_signature *sig)
+print_subpackets_colon (PKT_signature * sig)
 {
   byte *i;
 
-  assert(opt.show_subpackets);
+  assert (opt.show_subpackets);
 
-  for(i=opt.show_subpackets;*i;i++)
+  for (i = opt.show_subpackets; *i; i++)
     {
       const byte *p;
       size_t len;
-      int seq,crit;
+      int seq, crit;
 
-      seq=0;
+      seq = 0;
 
-      while((p=enum_sig_subpkt(sig->hashed,*i,&len,&seq,&crit)))
-       print_one_subpacket(*i,len,0x01|(crit?0x02:0),p);
+      while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
+       print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
 
-      seq=0;
+      seq = 0;
 
-      while((p=enum_sig_subpkt(sig->unhashed,*i,&len,&seq,&crit)))
-       print_one_subpacket(*i,len,0x00|(crit?0x02:0),p);
+      while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
+       print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
     }
 }
 
+
 void
-dump_attribs(const PKT_user_id *uid,PKT_public_key *pk,PKT_secret_key *sk)
+dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
 {
   int i;
 
-  if(!attrib_fp)
+  if (!attrib_fp)
     return;
 
-  for(i=0;i<uid->numattribs;i++)
+  for (i = 0; i < uid->numattribs; i++)
     {
-      if(is_status_enabled())
+      if (is_status_enabled ())
        {
          byte array[MAX_FINGERPRINT_LEN], *p;
-         char buf[(MAX_FINGERPRINT_LEN*2)+90];
-         size_t j,n;
+         char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
+         size_t j, n;
 
-         if(pk)
-           fingerprint_from_pk( pk, array, &n );
-         else if(sk)
-           fingerprint_from_sk( sk, array, &n );
-         else
-           BUG();
+          if (!pk)
+            BUG ();
+          fingerprint_from_pk (pk, array, &n);
 
          p = array;
-         for(j=0; j < n ; j++, p++ )
-           sprintf(buf+2*j, "%02X", *p );
-
-         sprintf(buf+strlen(buf)," %lu %u %u %u %lu %lu %u",
-                 (ulong)uid->attribs[i].len,uid->attribs[i].type,i+1,
-                 uid->numattribs,(ulong)uid->created,(ulong)uid->expiredate,
-                 ((uid->is_primary?0x01:0)|
-                  (uid->is_revoked?0x02:0)|
-                  (uid->is_expired?0x04:0)));
-         write_status_text(STATUS_ATTRIBUTE,buf);
+         for (j = 0; j < n; j++, p++)
+           sprintf (buf + 2 * j, "%02X", *p);
+
+         sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
+                  (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
+                  uid->numattribs, (ulong) uid->created,
+                  (ulong) uid->expiredate,
+                  ((uid->is_primary ? 0x01 : 0) | (uid->
+                                                   is_revoked ? 0x02 : 0) |
+                   (uid->is_expired ? 0x04 : 0)));
+         write_status_text (STATUS_ATTRIBUTE, buf);
        }
 
-      fwrite(uid->attribs[i].data,uid->attribs[i].len,1,attrib_fp);
-      fflush (attrib_fp);
+      es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
+      es_fflush (attrib_fp);
     }
 }
 
+
 static void
-list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
+list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
 {
-    int rc = 0;
-    KBNODE kbctx;
-    KBNODE node;
-    PKT_public_key *pk;
-    PKT_secret_key *sk;
-    struct sig_stats *stats=opaque;
-    int skip_sigs=0;
-
-    /* get the keyid from the keyblock */
-    node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
-    if( !node ) {
-       log_error("Oops; key lost!\n");
-       dump_kbnode( keyblock );
-       return;
+  int rc;
+  KBNODE kbctx;
+  KBNODE node;
+  PKT_public_key *pk;
+  struct sig_stats *stats = opaque;
+  int skip_sigs = 0;
+  int s2k_char;
+  char *hexgrip = NULL;
+  char *serialno = NULL;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
+
+  /* Get the keyid from the keyblock.  */
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node)
+    {
+      log_error ("Oops; key lost!\n");
+      dump_kbnode (keyblock);
+      return;
+    }
+
+  pk = node->pkt->pkt.public_key;
+
+  if (secret || opt.with_keygrip)
+    {
+      rc = hexkeygrip_from_pk (pk, &hexgrip);
+      if (rc)
+        log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
+    }
+
+  if (secret)
+    {
+      if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
+        s2k_char = serialno? '>':' ';
+      else
+        s2k_char = '#';  /* Key not found.  */
     }
+  else
+    s2k_char = ' ';
 
-    if( secret )
-      {
-       pk = NULL;
-       sk = node->pkt->pkt.secret_key;
-
-        printf("sec%c  %4u%c/%s %s",(sk->protect.s2k.mode==1001)?'#':
-              (sk->protect.s2k.mode==1002)?'>':' ',
-              nbits_from_sk( sk ),pubkey_letter( sk->pubkey_algo ),
-              keystr_from_sk(sk),datestr_from_sk( sk ));
-
-       if(sk->has_expired)
-         {
-           printf(" [");
-           printf(_("expired: %s"),expirestr_from_sk(sk));
-           printf("]");
-         }
-       else if(sk->expiredate )
-         {
-           printf(" [");
-           printf(_("expires: %s"),expirestr_from_sk(sk));
-           printf("]");
-         }
-
-       printf("\n");
-      }
-    else
-      {
-       pk = node->pkt->pkt.public_key;
-       sk = NULL;
-
-       check_trustdb_stale();
-
-       printf("pub   %4u%c/%s %s",
-              nbits_from_pk(pk),pubkey_letter(pk->pubkey_algo),
-              keystr_from_pk(pk),datestr_from_pk( pk ));
-
-       /* We didn't include this before in the key listing, but there
-          is room in the new format, so why not? */
-
-       if(pk->is_revoked)
-         {
-           printf(" [");
-           printf(_("revoked: %s"),revokestr_from_pk(pk));
-           printf("]");
-         }
-       else if(pk->has_expired)
-         {
-           printf(" [");
-           printf(_("expired: %s"),expirestr_from_pk(pk));
-           printf("]");
-         }
-       else if(pk->expiredate)
-         {
-           printf(" [");
-           printf(_("expires: %s"),expirestr_from_pk(pk));
-           printf("]");
-         }
+  check_trustdb_stale ();
+
+
+  es_fprintf (es_stdout, "%s%c  %s/%s %s",
+              secret? "sec":"pub",
+              s2k_char,
+              pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+              keystr_from_pk (pk), datestr_from_pk (pk));
+
+  if ((opt.list_options & LIST_SHOW_USAGE))
+    {
+      es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk, 0));
+    }
+  if (pk->flags.revoked)
+    {
+      es_fprintf (es_stdout, " [");
+      es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
+      es_fprintf (es_stdout, "]");
+    }
+  else if (pk->has_expired)
+    {
+      es_fprintf (es_stdout, " [");
+      es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
+      es_fprintf (es_stdout, "]");
+    }
+  else if (pk->expiredate)
+    {
+      es_fprintf (es_stdout, " [");
+      es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
+      es_fprintf (es_stdout, "]");
+    }
 
 #if 0
-       /* I need to think about this some more.  It's easy enough to
-          include, but it looks sort of confusing in the
-          listing... */
-       if(opt.list_options&LIST_SHOW_VALIDITY)
-         {
-           int validity=get_validity(pk,NULL);
-           printf(" [%s]",trust_value_to_string(validity));
-         }
+  /* I need to think about this some more.  It's easy enough to
+     include, but it looks sort of confusing in the listing... */
+  if (opt.list_options & LIST_SHOW_VALIDITY)
+    {
+      int validity = get_validity (pk, NULL);
+      es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
+    }
 #endif
 
-       printf("\n");
-      }
-
-    if( fpr )
-      print_fingerprint( pk, sk, 0 );
-    print_card_serialno (sk);
-    if( opt.with_key_data )
-      print_key_data( pk );
-
-    for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
-       if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
-           PKT_user_id *uid=node->pkt->pkt.user_id;
-
-           if(pk && (uid->is_expired || uid->is_revoked)
-              && !(opt.list_options&LIST_SHOW_UNUSABLE_UIDS))
-             {
-               skip_sigs=1;
-               continue;
-             }
-           else
-             skip_sigs=0;
-
-           if(attrib_fp && uid->attrib_data!=NULL)
-             dump_attribs(uid,pk,sk);
-
-           if((uid->is_revoked || uid->is_expired)
-              || ((opt.list_options&LIST_SHOW_UID_VALIDITY) && pk))
-             {
-               const char *validity;
-               int indent;
-
-               validity=uid_trust_string_fixed(pk,uid);
-               indent=(keystrlen()+9)-atoi(uid_trust_string_fixed(NULL,NULL));
-
-               if(indent<0 || indent>40)
-                 indent=0;
-
-               printf("uid%*s%s ",indent,"",validity);
-             }
-           else
-             printf("uid%*s", (int)keystrlen()+10,"");
-
-            print_utf8_string( stdout, uid->name, uid->len );
-           putchar('\n');
-
-           if((opt.list_options&LIST_SHOW_PHOTOS) && uid->attribs!=NULL)
-             show_photos(uid->attribs,uid->numattribs,pk,sk,uid);
-       }
-       else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-         {
-           PKT_public_key *pk2 = node->pkt->pkt.public_key;
-
-           if((pk2->is_revoked || pk2->has_expired)
-              && !(opt.list_options&LIST_SHOW_UNUSABLE_SUBKEYS))
-             {
-               skip_sigs=1;
-               continue;
-             }
-           else
-             skip_sigs=0;
-
-            printf("sub   %4u%c/%s %s",
-                  nbits_from_pk( pk2 ),pubkey_letter( pk2->pubkey_algo ),
-                  keystr_from_pk(pk2),datestr_from_pk(pk2));
-           if( pk2->is_revoked )
-             {
-               printf(" [");
-               printf(_("revoked: %s"),revokestr_from_pk(pk2));
-               printf("]");
-             }
-           else if( pk2->has_expired )
-             {
-               printf(" [");
-               printf(_("expired: %s"),expirestr_from_pk(pk2));
-               printf("]");
-             }
-           else if( pk2->expiredate )
-             {
-               printf(" [");
-               printf(_("expires: %s"),expirestr_from_pk(pk2));
-               printf("]");
-             }
-            putchar('\n');
-           if( fpr > 1 )
-             print_fingerprint( pk2, NULL, 0 );
-           if( opt.with_key_data )
-             print_key_data( pk2 );
-         }
-       else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
-         {
-           PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
-
-            printf("ssb%c  %4u%c/%s %s",
-                   (sk2->protect.s2k.mode==1001)?'#':
-                   (sk2->protect.s2k.mode==1002)?'>':' ',
-                  nbits_from_sk( sk2 ),pubkey_letter( sk2->pubkey_algo ),
-                  keystr_from_sk(sk2),datestr_from_sk( sk2 ) );
-            if( sk2->expiredate )
-             {
-               printf(" [");
-               printf(_("expires: %s"),expirestr_from_sk(sk2));
-               printf("]");
-             }
-           putchar('\n');
-           if( fpr > 1 )
-              {
-                print_fingerprint( NULL, sk2, 0 );
-                print_card_serialno (sk2);
-              }
-         }
-       else if( opt.list_sigs
-                && node->pkt->pkttype == PKT_SIGNATURE
-                && !skip_sigs ) {
-           PKT_signature *sig = node->pkt->pkt.signature;
-           int sigrc;
-            char *sigstr;
-
-           if( stats ) {
-                /*fflush(stdout);*/
-               rc = check_key_signature( keyblock, node, NULL );
-               switch( gpg_err_code (rc) ) {
-                case 0:                sigrc = '!'; break;
-                case GPG_ERR_BAD_SIGNATURE:
-                   stats->inv_sigs++; sigrc = '-'; break;
-                case GPG_ERR_NO_PUBKEY:
-                case GPG_ERR_UNUSABLE_PUBKEY: stats->no_key++; continue;
-                default:               stats->oth_err++; sigrc = '%'; break;
-               }
+  if (pk->pubkey_algo >= 100)
+    es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
+
+  es_fprintf (es_stdout, "\n");
+
+  if (fpr)
+    print_fingerprint (NULL, pk, 0);
+
+  if (opt.with_keygrip && hexgrip)
+    es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
+
+  if (serialno)
+    print_card_serialno (serialno);
 
-               /* TODO: Make sure a cached sig record here still has
-                   the pk that issued it.  See also
-                   keyedit.c:print_and_check_one_sig */
+  if (opt.with_key_data)
+    print_key_data (pk);
+
+  for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
+       {
+         PKT_user_id *uid = node->pkt->pkt.user_id;
+
+         if (pk && (uid->is_expired || uid->is_revoked)
+             && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
+           {
+             skip_sigs = 1;
+             continue;
            }
-           else {
-               rc = 0;
-               sigrc = ' ';
+         else
+           skip_sigs = 0;
+
+         if (attrib_fp && uid->attrib_data != NULL)
+           dump_attribs (uid, pk);
+
+         if ((uid->is_revoked || uid->is_expired)
+             || ((opt.list_options & LIST_SHOW_UID_VALIDITY) && pk))
+           {
+             const char *validity;
+             int indent;
+
+             validity = uid_trust_string_fixed (pk, uid);
+             indent =
+               (keystrlen () + 9) -
+               atoi (uid_trust_string_fixed (NULL, NULL));
+
+             if (indent < 0 || indent > 40)
+               indent = 0;
+
+             es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
            }
+         else
+           es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
 
-           if( sig->sig_class == 0x20 || sig->sig_class == 0x28
-                                      || sig->sig_class == 0x30 )
-              sigstr = "rev";
-           else if( (sig->sig_class&~3) == 0x10 )
-              sigstr = "sig";
-           else if( sig->sig_class == 0x18 )
-              sigstr = "sig";
-           else if( sig->sig_class == 0x1F )
-              sigstr = "sig";
-           else {
-                printf("sig                             "
-                      "[unexpected signature class 0x%02x]\n",sig->sig_class );
-               continue;
+         print_utf8_buffer (es_stdout, uid->name, uid->len);
+         es_putc ('\n', es_stdout);
+
+         if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
+           show_photos (uid->attribs, uid->numattribs, pk, uid);
+       }
+      else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       {
+         PKT_public_key *pk2 = node->pkt->pkt.public_key;
+
+         if ((pk2->flags.revoked || pk2->has_expired)
+             && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
+           {
+             skip_sigs = 1;
+             continue;
            }
+         else
+           skip_sigs = 0;
 
-            fputs( sigstr, stdout );
-           printf("%c%c %c%c%c%c%c%c %s %s",
-                   sigrc,(sig->sig_class-0x10>0 &&
-                          sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
-                   sig->flags.exportable?' ':'L',
-                   sig->flags.revocable?' ':'R',
-                   sig->flags.policy_url?'P':' ',
-                   sig->flags.notation?'N':' ',
-                   sig->flags.expired?'X':' ',
-                  (sig->trust_depth>9)?'T':
-                  (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
-                  keystr(sig->keyid),datestr_from_sig(sig));
-           if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
-             printf(" %s", expirestr_from_sig(sig));
-           printf("  ");
-           if( sigrc == '%' )
-               printf("[%s] ", g10_errstr(rc) );
-           else if( sigrc == '?' )
-               ;
-           else if ( !opt.fast_list_mode ) {
-               size_t n;
-               char *p = get_user_id( sig->keyid, &n );
-                print_utf8_string( stdout, p, n );
-               xfree(p);
+          xfree (serialno); serialno = NULL;
+          xfree (hexgrip); hexgrip = NULL;
+          if (secret || opt.with_keygrip)
+            {
+              rc = hexkeygrip_from_pk (pk2, &hexgrip);
+              if (rc)
+                log_error ("error computing a keygrip: %s\n",
+                           gpg_strerror (rc));
+            }
+          if (secret)
+            {
+              if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
+                s2k_char = serialno? '>':' ';
+              else
+                s2k_char = '#';  /* Key not found.  */
+            }
+          else
+            s2k_char = ' ';
+
+         es_fprintf (es_stdout, "%s%c  %s/%s %s",
+                  secret? "ssb":"sub",
+                  s2k_char,
+                  pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
+                 keystr_from_pk (pk2), datestr_from_pk (pk2));
+
+          if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
+              || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
+              || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
+            {
+              char *curve = openpgp_oid_to_str (pk2->pkey[0]);
+              const char *name = openpgp_oid_to_curve (curve);
+              if (!*name || *name == '?')
+                name = curve;
+              es_fprintf (es_stdout, " %s", name);
+              xfree (curve);
+            }
+
+          if ((opt.list_options & LIST_SHOW_USAGE))
+            {
+              es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
+            }
+         if (pk2->flags.revoked)
+           {
+             es_fprintf (es_stdout, " [");
+             es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
+             es_fprintf (es_stdout, "]");
+           }
+         else if (pk2->has_expired)
+           {
+             es_fprintf (es_stdout, " [");
+             es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
+             es_fprintf (es_stdout, "]");
+           }
+         else if (pk2->expiredate)
+           {
+             es_fprintf (es_stdout, " [");
+             es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
+             es_fprintf (es_stdout, "]");
            }
-           putchar('\n');
+         es_putc ('\n', es_stdout);
+         if (fpr > 1)
+            {
+              print_fingerprint (NULL, pk2, 0);
+              if (serialno)
+                print_card_serialno (serialno);
+            }
+          if (opt.with_keygrip && hexgrip)
+            es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
+         if (opt.with_key_data)
+           print_key_data (pk2);
+       }
+      else if (opt.list_sigs
+              && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
+       {
+         PKT_signature *sig = node->pkt->pkt.signature;
+         int sigrc;
+         char *sigstr;
 
-           if(sig->flags.policy_url
-              && (opt.list_options&LIST_SHOW_POLICY_URLS))
-             show_policy_url(sig,3,0);
+         if (stats)
+           {
+             rc = check_key_signature (keyblock, node, NULL);
+             switch (gpg_err_code (rc))
+               {
+               case 0:
+                 sigrc = '!';
+                 break;
+               case GPG_ERR_BAD_SIGNATURE:
+                 stats->inv_sigs++;
+                 sigrc = '-';
+                 break;
+               case GPG_ERR_NO_PUBKEY:
+               case GPG_ERR_UNUSABLE_PUBKEY:
+                 stats->no_key++;
+                 continue;
+               default:
+                 stats->oth_err++;
+                 sigrc = '%';
+                 break;
+               }
 
-           if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATIONS))
-             show_notation(sig,3,0,
-                           ((opt.list_options&LIST_SHOW_STD_NOTATIONS)?1:0)+
-                           ((opt.list_options&LIST_SHOW_USER_NOTATIONS)?2:0));
+             /* TODO: Make sure a cached sig record here still has
+                the pk that issued it.  See also
+                keyedit.c:print_and_check_one_sig */
+           }
+         else
+           {
+             rc = 0;
+             sigrc = ' ';
+           }
 
-           if(sig->flags.pref_ks
-              && (opt.list_options&LIST_SHOW_KEYSERVER_URLS))
-             show_keyserver_url(sig,3,0);
+         if (sig->sig_class == 0x20 || sig->sig_class == 0x28
+             || sig->sig_class == 0x30)
+           sigstr = "rev";
+         else if ((sig->sig_class & ~3) == 0x10)
+           sigstr = "sig";
+         else if (sig->sig_class == 0x18)
+           sigstr = "sig";
+         else if (sig->sig_class == 0x1F)
+           sigstr = "sig";
+         else
+           {
+             es_fprintf (es_stdout, "sig                             "
+                     "[unexpected signature class 0x%02x]\n",
+                     sig->sig_class);
+             continue;
+           }
 
-           /* fixme: check or list other sigs here */
+         es_fputs (sigstr, es_stdout);
+         es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
+                 sigrc, (sig->sig_class - 0x10 > 0 &&
+                         sig->sig_class - 0x10 <
+                         4) ? '0' + sig->sig_class - 0x10 : ' ',
+                 sig->flags.exportable ? ' ' : 'L',
+                 sig->flags.revocable ? ' ' : 'R',
+                 sig->flags.policy_url ? 'P' : ' ',
+                 sig->flags.notation ? 'N' : ' ',
+                 sig->flags.expired ? 'X' : ' ',
+                 (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
+                                                 0) ? '0' +
+                 sig->trust_depth : ' ', keystr (sig->keyid),
+                 datestr_from_sig (sig));
+         if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
+           es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
+         es_fprintf (es_stdout, "  ");
+         if (sigrc == '%')
+           es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
+         else if (sigrc == '?')
+           ;
+         else if (!opt.fast_list_mode)
+           {
+             size_t n;
+             char *p = get_user_id (sig->keyid, &n);
+             print_utf8_buffer (es_stdout, p, n);
+             xfree (p);
+           }
+         es_putc ('\n', es_stdout);
+
+         if (sig->flags.policy_url
+             && (opt.list_options & LIST_SHOW_POLICY_URLS))
+           show_policy_url (sig, 3, 0);
+
+         if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
+           show_notation (sig, 3, 0,
+                          ((opt.
+                            list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
+                          +
+                          ((opt.
+                            list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
+                           0));
+
+         if (sig->flags.pref_ks
+             && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
+           show_keyserver_url (sig, 3, 0);
+
+         /* fixme: check or list other sigs here */
        }
     }
-    putchar('\n');
+  es_putc ('\n', es_stdout);
+  xfree (serialno);
+  xfree (hexgrip);
 }
 
 void
-print_revokers(PKT_public_key *pk)
+print_revokers (estream_t fp, PKT_public_key * pk)
 {
   /* print the revoker record */
-  if( !pk->revkey && pk->numrevkeys )
-    BUG();
+  if (!pk->revkey && pk->numrevkeys)
+    BUG ();
   else
     {
-      int i,j;
+      int i, j;
 
-      for (i=0; i < pk->numrevkeys; i++)
+      for (i = 0; i < pk->numrevkeys; i++)
        {
          byte *p;
 
-         printf ("rvk:::%d::::::", pk->revkey[i].algid);
+         es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
          p = pk->revkey[i].fpr;
-         for (j=0; j < 20; j++, p++ )
-           printf ("%02X", *p);
-         printf (":%02x%s:\n", pk->revkey[i].class,
-                 (pk->revkey[i].class&0x40)?"s":"");
+         for (j = 0; j < 20; j++, p++)
+           es_fprintf (fp, "%02X", *p);
+         es_fprintf (fp, ":%02x%s:\n",
+                      pk->revkey[i].class,
+                      (pk->revkey[i].class & 0x40) ? "s" : "");
        }
     }
 }
 
+
+/* List a key in colon mode.  If SECRET is true this is a secret key
+   record (i.e. requested via --list-secret-key).  If HAS_SECRET a
+   secret key is available even if SECRET is not set.  */
 static void
-list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
+list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
 {
-  int rc = 0;
+  int rc;
   KBNODE kbctx;
   KBNODE node;
   PKT_public_key *pk;
-  PKT_secret_key *sk;
   u32 keyid[2];
   int trustletter = 0;
   int ulti_hack = 0;
   int i;
+  char *p;
+  char *hexgrip = NULL;
+  char *serialno = NULL;
+  int stubkey;
 
-  /* get the keyid from the keyblock */
-  node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
-  if ( !node )
+  /* Get the keyid from the keyblock.  */
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node)
     {
-      log_error("Oops; key lost!\n");
-      dump_kbnode( keyblock );
+      log_error ("Oops; key lost!\n");
+      dump_kbnode (keyblock);
       return;
     }
 
-  if ( secret )
+  pk = node->pkt->pkt.public_key;
+  if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
     {
-      pk = NULL;
-      sk = node->pkt->pkt.secret_key;
-      keyid_from_sk ( sk, keyid );
-      printf ("sec::%u:%d:%08lX%08lX:%s:%s:::",
-              nbits_from_sk( sk ),
-              sk->pubkey_algo,
-              (ulong)keyid[0],(ulong)keyid[1],
-              colon_datestr_from_sk( sk ),
-              colon_strtime (sk->expiredate)
-              /* fixme: add LID here */ );
+      rc = hexkeygrip_from_pk (pk, &hexgrip);
+      if (rc)
+        log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
     }
+  stubkey = 0;
+  if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
+    stubkey = 1;  /* Key not found.  */
+
+  keyid_from_pk (pk, keyid);
+  es_fputs (secret? "sec:":"pub:", es_stdout);
+  if (!pk->flags.valid)
+    es_putc ('i', es_stdout);
+  else if (pk->flags.revoked)
+    es_putc ('r', es_stdout);
+  else if (pk->has_expired)
+    es_putc ('e', es_stdout);
+  else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
+    ;
   else
     {
-      pk = node->pkt->pkt.public_key;
-      sk = NULL;
-      keyid_from_pk( pk, keyid );
-      fputs( "pub:", stdout );
-      if ( !pk->is_valid )
-        putchar ('i');
-      else if ( pk->is_revoked )
-        putchar ('r');
-      else if ( pk->has_expired )
-        putchar ('e');
-      else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
-      ;
-      else
-        {
-          trustletter = get_validity_info ( pk, NULL );
-          if ( trustletter == 'u' )
-            ulti_hack = 1;
-          putchar(trustletter);
-        }
-      printf (":%u:%d:%08lX%08lX:%s:%s::",
-              nbits_from_pk( pk ),
-              pk->pubkey_algo,
-              (ulong)keyid[0],(ulong)keyid[1],
-              colon_datestr_from_pk( pk ),
-              colon_strtime (pk->expiredate) );
-      if ( !opt.fast_list_mode && !opt.no_expensive_trust_checks  )
-        putchar( get_ownertrust_info(pk) );
-      putchar(':');
+      trustletter = get_validity_info (pk, NULL);
+      if (trustletter == 'u')
+        ulti_hack = 1;
+      es_putc (trustletter, es_stdout);
     }
 
-  putchar (':');
-  putchar (':');
-  print_capabilities (pk, sk, keyblock);
-  if (secret)
+  es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
+          nbits_from_pk (pk),
+          pk->pubkey_algo,
+          (ulong) keyid[0], (ulong) keyid[1],
+          colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
+
+  if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
+    es_putc (get_ownertrust_info (pk), es_stdout);
+  es_putc (':', es_stdout);
+
+  es_putc (':', es_stdout);
+  es_putc (':', es_stdout);
+  print_capabilities (pk, keyblock);
+  es_putc (':', es_stdout);            /* End of field 13. */
+  es_putc (':', es_stdout);            /* End of field 14. */
+  if (secret || has_secret)
     {
-      putchar (':'); /* End of field 13. */
-      putchar (':'); /* End of field 14. */
-      if (sk->protect.s2k.mode == 1001)
-        putchar ('#'); /* Key is just a stub. */
-      else if (sk->protect.s2k.mode == 1002)
-        {
-          /* Key is stored on an external token (card) or handled by
-             the gpg-agent.  Print the serial number of that token
-             here. */
-          for (i=0; i < sk->protect.ivlen; i++)
-            printf ("%02X", sk->protect.iv[i]);
-        }
-      putchar (':'); /* End of field 15. */
+      if (stubkey)
+       es_putc ('#', es_stdout);
+      else if (serialno)
+        es_fputs (serialno, es_stdout);
+      else if (has_secret)
+        es_putc ('+', es_stdout);
     }
-  putchar('\n');
-  if (pk)
-    print_revokers (pk);
-  if (fpr)
-    print_fingerprint (pk, sk, 0);
-  if (opt.with_key_data)
-    print_key_data (pk);
+  es_putc (':', es_stdout);            /* End of field 15. */
+  es_putc (':', es_stdout);            /* End of field 16. */
+  if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
+      || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
+      || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+    {
+      char *curve = openpgp_oid_to_str (pk->pkey[0]);
+      const char *name = openpgp_oid_to_curve (curve);
+      if (!*name || *name == '?')
+        name = curve;
+      es_fputs (name, es_stdout);
+      xfree (curve);
+    }
+  es_putc (':', es_stdout);            /* End of field 17. */
+  es_putc ('\n', es_stdout);
 
+  print_revokers (es_stdout, pk);
+  if (fpr)
+    print_fingerprint (NULL, pk, 0);
+  if (opt.with_key_data || opt.with_keygrip)
+    {
+      if (hexgrip)
+        es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
+      if (opt.with_key_data)
+        print_key_data (pk);
+    }
 
-  for ( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; )
+  for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
     {
-      if ( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode )
-        {
-          char *str;
-          PKT_user_id *uid=node->pkt->pkt.user_id;
-
-          if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
-            dump_attribs (node->pkt->pkt.user_id,pk,sk);
-          /*
-           * Fixme: We need a is_valid flag here too
-           */
-          str = uid->attrib_data? "uat":"uid";
-          /* If we're listing a secret key, leave out the validity
-             values for now.  This is handled better in 1.9. */
-          if (sk)
-            printf ("%s:::::",str);
-          else if ( uid->is_revoked )
-            printf ("%s:r::::",str);
-          else if ( uid->is_expired )
-            printf ("%s:e::::",str);
-          else if ( opt.no_expensive_trust_checks )
-            printf ("%s:::::",str);
-          else
-            {
-              int uid_validity;
+      if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
+       {
+         char *str;
+         PKT_user_id *uid = node->pkt->pkt.user_id;
+
+         if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
+           dump_attribs (node->pkt->pkt.user_id, pk);
+         /*
+          * Fixme: We need a valid flag here too
+          */
+         str = uid->attrib_data ? "uat" : "uid";
+         if (uid->is_revoked)
+           es_fprintf (es_stdout, "%s:r::::", str);
+         else if (uid->is_expired)
+           es_fprintf (es_stdout, "%s:e::::", str);
+         else if (opt.no_expensive_trust_checks)
+           es_fprintf (es_stdout, "%s:::::", str);
+         else
+           {
+             int uid_validity;
 
-              if ( pk && !ulti_hack )
-                uid_validity=get_validity_info (pk, uid);
-              else
-                uid_validity = 'u';
-              printf ("%s:%c::::",str,uid_validity);
-            }
+             if (pk && !ulti_hack)
+               uid_validity = get_validity_info (pk, uid);
+             else
+               uid_validity = 'u';
+             es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
+           }
 
-          printf ("%s:", colon_strtime (uid->created));
-          printf ("%s:", colon_strtime (uid->expiredate));
+         es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
+         es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
 
-          namehash_from_uid (uid);
+         namehash_from_uid (uid);
 
-          for (i=0; i < 20; i++ )
-            printf ("%02X",uid->namehash[i]);
+         for (i = 0; i < 20; i++)
+           es_fprintf (es_stdout, "%02X", uid->namehash[i]);
 
-          printf ("::");
+         es_fprintf (es_stdout, "::");
 
-          if (uid->attrib_data)
-            printf ("%u %lu",uid->numattribs,uid->attrib_len);
-          else
-            print_string (stdout,uid->name,uid->len, ':' );
-          putchar (':');
-          putchar ('\n');
-        }
-      else if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-        {
-          u32 keyid2[2];
-          PKT_public_key *pk2 = node->pkt->pkt.public_key;
-
-          keyid_from_pk ( pk2, keyid2 );
-          fputs ("sub:", stdout );
-          if ( !pk2->is_valid )
-            putchar ('i');
-          else if ( pk2->is_revoked )
-            putchar ('r');
-          else if ( pk2->has_expired )
-            putchar ('e');
-          else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
-            ;
-          else
-            {
-              /* TRUSTLETTER should always be defined here. */
-              if (trustletter)
-                printf ("%c", trustletter );
-            }
-          printf(":%u:%d:%08lX%08lX:%s:%s:::::",
-                 nbits_from_pk( pk2 ),
-                 pk2->pubkey_algo,
-                 (ulong)keyid2[0],(ulong)keyid2[1],
-                 colon_datestr_from_pk( pk2 ),
-                 colon_strtime (pk2->expiredate)
-                 /* fixme: add LID and ownertrust here */
-                 );
-          print_capabilities (pk2, NULL, NULL);
-          putchar ('\n');
-          if ( fpr > 1 )
-            print_fingerprint ( pk2, NULL, 0 );
-          if ( opt.with_key_data )
-            print_key_data( pk2 );
-        }
-      else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
-        {
-          u32 keyid2[2];
-          PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
-
-          keyid_from_sk ( sk2, keyid2 );
-          printf ("ssb::%u:%d:%08lX%08lX:%s:%s:::::",
-                  nbits_from_sk( sk2 ),
-                  sk2->pubkey_algo,
-                  (ulong)keyid2[0],(ulong)keyid2[1],
-                  colon_datestr_from_sk( sk2 ),
-                  colon_strtime (sk2->expiredate)
-                  /* fixme: add LID */ );
-          print_capabilities (NULL, sk2, NULL);
-          putchar(':'); /* End of field 13. */
-          putchar(':'); /* End of field 14. */
-          if (sk2->protect.s2k.mode == 1001)
-            putchar ('#'); /* Key is just a stub. */
-          else if (sk2->protect.s2k.mode == 1002)
-            {
-              /* Key is stored on an external token (card) or handled by
-                 the gpg-agent.  Print the serial number of that token
-                 here. */
-              for (i=0; i < sk2->protect.ivlen; i++)
-                printf ("%02X", sk2->protect.iv[i]);
-            }
-          putchar(':'); /* End of field 15. */
-          putchar ('\n');
+         if (uid->attrib_data)
+           es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
+         else
+           es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
+         es_putc (':', es_stdout);
+         es_putc ('\n', es_stdout);
+       }
+      else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+       {
+         u32 keyid2[2];
+         PKT_public_key *pk2;
 
-          if ( fpr > 1 )
-            print_fingerprint ( NULL, sk2, 0 );
-        }
-      else if ( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE )
-        {
-          PKT_signature *sig = node->pkt->pkt.signature;
-          int sigrc,fprokay=0;
-          char *sigstr;
-          size_t fplen;
-          byte fparray[MAX_FINGERPRINT_LEN];
-
-          if ( sig->sig_class == 0x20 || sig->sig_class == 0x28
-               || sig->sig_class == 0x30 )
-            sigstr = "rev";
-          else if ( (sig->sig_class&~3) == 0x10 )
-            sigstr = "sig";
-          else if ( sig->sig_class == 0x18 )
-            sigstr = "sig";
-          else if ( sig->sig_class == 0x1F )
-            sigstr = "sig";
-          else
+          pk2 = node->pkt->pkt.public_key;
+          xfree (hexgrip); hexgrip = NULL;
+          xfree (serialno); serialno = NULL;
+          if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
             {
-              printf ("sig::::::::::%02x%c:\n",
-                      sig->sig_class, sig->flags.exportable?'x':'l');
-              continue;
+              rc = hexkeygrip_from_pk (pk2, &hexgrip);
+              if (rc)
+                log_error ("error computing a keygrip: %s\n",
+                           gpg_strerror (rc));
             }
-
-          if ( opt.check_sigs )
+          stubkey = 0;
+          if ((secret||has_secret)
+              && agent_get_keyinfo (NULL, hexgrip, &serialno))
+            stubkey = 1;  /* Key not found.  */
+
+         keyid_from_pk (pk2, keyid2);
+         es_fputs (secret? "ssb:":"sub:", es_stdout);
+         if (!pk2->flags.valid)
+           es_putc ('i', es_stdout);
+         else if (pk2->flags.revoked)
+           es_putc ('r', es_stdout);
+         else if (pk2->has_expired)
+           es_putc ('e', es_stdout);
+         else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
+           ;
+         else
+           {
+             /* TRUSTLETTER should always be defined here. */
+             if (trustletter)
+               es_fprintf (es_stdout, "%c", trustletter);
+           }
+         es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
+                 nbits_from_pk (pk2),
+                 pk2->pubkey_algo,
+                 (ulong) keyid2[0], (ulong) keyid2[1],
+                 colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
+                 /* fixme: add LID and ownertrust here */
+           );
+         print_capabilities (pk2, NULL);
+          es_putc (':', es_stdout);    /* End of field 13. */
+          es_putc (':', es_stdout);    /* End of field 14. */
+          if (secret || has_secret)
             {
-              PKT_public_key *signer_pk=NULL;
-
-              fflush (stdout);
-              if (opt.no_sig_cache)
-                signer_pk = xmalloc_clear (sizeof(PKT_public_key));
-
-              rc = check_key_signature2 ( keyblock, node, NULL, signer_pk,
-                                          NULL, NULL, NULL );
-              switch ( gpg_err_code (rc) )
-                {
-                case 0:                              sigrc = '!'; break;
-                case GPG_ERR_BAD_SIGNATURE:   sigrc = '-'; break;
-                case GPG_ERR_NO_PUBKEY:
-                case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break;
-                default:                     sigrc = '%'; break;
-                }
-
-              if (opt.no_sig_cache)
-                {
-                  if (!rc)
-                    {
-                      fingerprint_from_pk (signer_pk, fparray, &fplen);
-                      fprokay = 1;
-                    }
-                  free_public_key(signer_pk);
-                }
+              if (stubkey)
+                es_putc ('#', es_stdout);
+              else if (serialno)
+                es_fputs (serialno, es_stdout);
+              else if (has_secret)
+                es_putc ('+', es_stdout);
             }
-          else
+          es_putc (':', es_stdout);    /* End of field 15. */
+          es_putc (':', es_stdout);    /* End of field 16. */
+          if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
+              || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
+              || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
             {
-              rc = 0;
-              sigrc = ' ';
+              char *curve = openpgp_oid_to_str (pk->pkey[0]);
+              const char *name = openpgp_oid_to_curve (curve);
+              if (!*name || *name == '?')
+                name = curve;
+              es_fputs (name, es_stdout);
+              xfree (curve);
             }
-          fputs ( sigstr, stdout );
-          putchar (':');
-          if ( sigrc != ' ' )
-            putchar (sigrc);
-          printf ("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
-                  (ulong)sig->keyid[0], (ulong)sig->keyid[1],
-                  colon_datestr_from_sig(sig),
-                  colon_expirestr_from_sig(sig));
-
-          if (sig->trust_depth || sig->trust_value)
-            printf("%d %d",sig->trust_depth,sig->trust_value);
-          printf (":");
-
-          if (sig->trust_regexp)
-            print_string (stdout,sig->trust_regexp,
-                          strlen(sig->trust_regexp),':');
-          printf(":");
-
-          if ( sigrc == '%' )
-            printf("[%s] ", g10_errstr(rc) );
-          else if ( sigrc == '?' )
-            ;
-          else if ( !opt.fast_list_mode )
+          es_putc (':', es_stdout);    /* End of field 17. */
+         es_putc ('\n', es_stdout);
+         if (fpr > 1)
+           print_fingerprint (NULL, pk2, 0);
+         if (opt.with_key_data || opt.with_keygrip)
             {
-              size_t n;
-              char *p = get_user_id( sig->keyid, &n );
-              print_string( stdout, p, n, ':' );
-              xfree(p);
+              if (hexgrip)
+                es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
+              if (opt.with_key_data)
+                print_key_data (pk2);
             }
-          printf (":%02x%c::", sig->sig_class,sig->flags.exportable?'x':'l');
+       }
+      else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
+       {
+         PKT_signature *sig = node->pkt->pkt.signature;
+         int sigrc, fprokay = 0;
+         char *sigstr;
+         size_t fplen;
+         byte fparray[MAX_FINGERPRINT_LEN];
+
+         if (sig->sig_class == 0x20 || sig->sig_class == 0x28
+             || sig->sig_class == 0x30)
+           sigstr = "rev";
+         else if ((sig->sig_class & ~3) == 0x10)
+           sigstr = "sig";
+         else if (sig->sig_class == 0x18)
+           sigstr = "sig";
+         else if (sig->sig_class == 0x1F)
+           sigstr = "sig";
+         else
+           {
+             es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
+                     sig->sig_class, sig->flags.exportable ? 'x' : 'l');
+             continue;
+           }
 
-          if (opt.no_sig_cache && opt.check_sigs && fprokay)
-            {
-              for (i=0; i < fplen ; i++ )
-                printf ("%02X", fparray[i] );
-            }
+         if (opt.check_sigs)
+           {
+             PKT_public_key *signer_pk = NULL;
+
+             fflush (stdout);
+             if (opt.no_sig_cache)
+               signer_pk = xmalloc_clear (sizeof (PKT_public_key));
+
+             rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
+                                        NULL, NULL, NULL);
+             switch (gpg_err_code (rc))
+               {
+               case 0:
+                 sigrc = '!';
+                 break;
+               case GPG_ERR_BAD_SIGNATURE:
+                 sigrc = '-';
+                 break;
+               case GPG_ERR_NO_PUBKEY:
+               case GPG_ERR_UNUSABLE_PUBKEY:
+                 sigrc = '?';
+                 break;
+               default:
+                 sigrc = '%';
+                 break;
+               }
 
-          printf (":::%d:\n", sig->digest_algo);
+             if (opt.no_sig_cache)
+               {
+                 if (!rc)
+                   {
+                     fingerprint_from_pk (signer_pk, fparray, &fplen);
+                     fprokay = 1;
+                   }
+                 free_public_key (signer_pk);
+               }
+           }
+         else
+           {
+             rc = 0;
+             sigrc = ' ';
+           }
+         es_fputs (sigstr, es_stdout);
+         es_putc (':', es_stdout);
+         if (sigrc != ' ')
+           es_putc (sigrc, es_stdout);
+         es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
+                 (ulong) sig->keyid[0], (ulong) sig->keyid[1],
+                 colon_datestr_from_sig (sig),
+                 colon_expirestr_from_sig (sig));
+
+         if (sig->trust_depth || sig->trust_value)
+           es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
+         es_fprintf (es_stdout, ":");
+
+         if (sig->trust_regexp)
+           es_write_sanitized (es_stdout, sig->trust_regexp,
+                                strlen (sig->trust_regexp), ":", NULL);
+         es_fprintf (es_stdout, ":");
+
+         if (sigrc == '%')
+           es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
+         else if (sigrc == '?')
+           ;
+         else if (!opt.fast_list_mode)
+           {
+             size_t n;
+             p = get_user_id (sig->keyid, &n);
+             es_write_sanitized (es_stdout, p, n, ":", NULL);
+             xfree (p);
+           }
+         es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
+                 sig->flags.exportable ? 'x' : 'l');
 
-          if (opt.show_subpackets)
-            print_subpackets_colon (sig);
+         if (opt.no_sig_cache && opt.check_sigs && fprokay)
+           {
+             for (i = 0; i < fplen; i++)
+               es_fprintf (es_stdout, "%02X", fparray[i]);
+           }
 
-          /* fixme: check or list other sigs here */
-        }
+         es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
+
+         if (opt.show_subpackets)
+           print_subpackets_colon (sig);
+
+         /* fixme: check or list other sigs here */
+       }
     }
+
+  xfree (hexgrip);
+  xfree (serialno);
 }
 
 /*
@@ -1407,232 +1509,186 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
  * packet) comes first.  Fixme: Replace this by a generic sort
  * function.  */
 static void
-do_reorder_keyblock (KBNODE keyblock,int attr)
+do_reorder_keyblock (KBNODE keyblock, int attr)
 {
-    KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
-    KBNODE last, node;
-
-    for (node=keyblock; node; primary0=node, node = node->next) {
-       if( node->pkt->pkttype == PKT_USER_ID &&
-           ((attr && node->pkt->pkt.user_id->attrib_data) ||
-            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
-            node->pkt->pkt.user_id->is_primary ) {
-            primary = primary2 = node;
-            for (node=node->next; node; primary2=node, node = node->next ) {
-                if( node->pkt->pkttype == PKT_USER_ID
-                    || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-                    || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-                    break;
-                }
-            }
-            break;
-        }
+  KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
+  KBNODE last, node;
+
+  for (node = keyblock; node; primary0 = node, node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID &&
+         ((attr && node->pkt->pkt.user_id->attrib_data) ||
+          (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
+         node->pkt->pkt.user_id->is_primary)
+       {
+         primary = primary2 = node;
+         for (node = node->next; node; primary2 = node, node = node->next)
+           {
+             if (node->pkt->pkttype == PKT_USER_ID
+                 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+               {
+                 break;
+               }
+           }
+         break;
+       }
     }
-    if ( !primary )
-        return;  /* no primary key flag found (should not happen) */
+  if (!primary)
+    return; /* No primary key flag found (should not happen).  */
 
-    for (last=NULL, node=keyblock; node; last = node, node = node->next) {
-       if( node->pkt->pkttype == PKT_USER_ID )
-            break;
+  for (last = NULL, node = keyblock; node; last = node, node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID)
+       break;
     }
-    assert (node);
-    assert (last); /* the user ID is never the first packet */
-    assert (primary0);  /* ditto (this is the node before primary) */
-    if ( node == primary )
-        return; /* already the first one */
-
-    last->next = primary;
-    primary0->next = primary2->next;
-    primary2->next = node;
+  assert (node);
+  assert (last);        /* The user ID is never the first packet.  */
+  assert (primary0);    /* Ditto (this is the node before primary).  */
+  if (node == primary)
+    return; /* Already the first one.  */
+
+  last->next = primary;
+  primary0->next = primary2->next;
+  primary2->next = node;
 }
 
 void
 reorder_keyblock (KBNODE keyblock)
 {
-  do_reorder_keyblock(keyblock,1);
-  do_reorder_keyblock(keyblock,0);
+  do_reorder_keyblock (keyblock, 1);
+  do_reorder_keyblock (keyblock, 0);
 }
 
 void
-list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque )
+list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr,
+               void *opaque)
 {
-    reorder_keyblock (keyblock);
-    if (opt.with_colons)
-        list_keyblock_colon (keyblock, secret, fpr );
-    else
-        list_keyblock_print (keyblock, secret, fpr, opaque );
+  reorder_keyblock (keyblock);
+  if (opt.with_colons)
+    list_keyblock_colon (keyblock, secret, has_secret, fpr);
+  else
+    list_keyblock_print (keyblock, secret, fpr, opaque);
 }
 
 /*
- * standard function to print the finperprint.
+ * Function to print the finperprint.
  * mode 0: as used in key listings, opt.with_colons is honored
  *      1: print using log_info ()
  *      2: direct use of tty
  *      3: direct use of tty but only primary key.
- * modes 1 and 2 will try and print both subkey and primary key fingerprints
+ *
+ * Modes 1 and 2 will try and print both subkey and primary key
+ * fingerprints.  A MODE with bit 7 set is used internally.  If
+ * OVERRIDE_FP is not NULL that stream will be used in  0 instead
+ * of es_stdout or instead of the TTY in modes 2 and 3.
  */
 void
-print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode )
+print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
 {
-    byte array[MAX_FINGERPRINT_LEN], *p;
-    size_t i, n;
-    FILE *fp;
-    const char *text;
-    int primary=0;
-
-    if(sk)
-      {
-       if(sk->main_keyid[0]==sk->keyid[0] && sk->main_keyid[1]==sk->keyid[1])
-         primary=1;
-      }
-    else
-      {
-       if(pk->main_keyid[0]==pk->keyid[0] && pk->main_keyid[1]==pk->keyid[1])
-         primary=1;
-      }
-
-    /* Just to be safe */
-    if(mode&0x80 && !primary)
-      {
-       log_error("primary key is not really primary!\n");
-       return;
-      }
-
-    mode&=~0x80;
-
-    if(!primary && (mode==1 || mode==2))
-      {
-       if(sk)
-         {
-           PKT_secret_key *primary_sk=xmalloc_clear(sizeof(*primary_sk));
-           get_seckey(primary_sk,sk->main_keyid);
-           print_fingerprint(NULL,primary_sk,mode|0x80);
-           free_secret_key(primary_sk);
-         }
-       else
-         {
-           PKT_public_key *primary_pk=xmalloc_clear(sizeof(*primary_pk));
-           get_pubkey(primary_pk,pk->main_keyid);
-           print_fingerprint(primary_pk,NULL,mode|0x80);
-           free_public_key(primary_pk);
-         }
-      }
-
-    if (mode == 1) {
-        fp = log_get_stream ();
-       if(primary)
-         text = _("Primary key fingerprint:");
-       else
-         text = _("     Subkey fingerprint:");
+  byte array[MAX_FINGERPRINT_LEN], *p;
+  size_t i, n;
+  estream_t fp;
+  const char *text;
+  int primary = 0;
+
+  if (pk->main_keyid[0] == pk->keyid[0]
+      && pk->main_keyid[1] == pk->keyid[1])
+    primary = 1;
+
+  /* Just to be safe */
+  if ((mode & 0x80) && !primary)
+    {
+      log_error ("primary key is not really primary!\n");
+      return;
+    }
+
+  mode &= ~0x80;
+
+  if (!primary && (mode == 1 || mode == 2))
+    {
+      PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
+      get_pubkey (primary_pk, pk->main_keyid);
+      print_fingerprint (override_fp, primary_pk, (mode | 0x80));
+      free_public_key (primary_pk);
+    }
+
+  if (mode == 1)
+    {
+      fp = log_get_stream ();
+      if (primary)
+       text = _("Primary key fingerprint:");
+      else
+       text = _("     Subkey fingerprint:");
     }
-    else if (mode == 2) {
-        fp = NULL; /* use tty */
-       if(primary)
-          /* TRANSLATORS: this should fit into 24 bytes to that the
-           * fingerprint data is properly aligned with the user ID */
-         text = _(" Primary key fingerprint:");
-       else
-         text = _("      Subkey fingerprint:");
+  else if (mode == 2)
+    {
+      fp = override_fp; /* Use tty or given stream.  */
+      if (primary)
+       /* TRANSLATORS: this should fit into 24 bytes to that the
+        * fingerprint data is properly aligned with the user ID */
+       text = _(" Primary key fingerprint:");
+      else
+       text = _("      Subkey fingerprint:");
     }
-    else if (mode == 3) {
-        fp = NULL; /* use tty */
-       text = _("      Key fingerprint =");
+  else if (mode == 3)
+    {
+      fp = override_fp; /* Use tty or given stream.  */
+      text = _("      Key fingerprint =");
     }
-    else {
-        fp = stdout;
-       text = _("      Key fingerprint =");
+  else
+    {
+      fp = override_fp? override_fp : es_stdout;
+      text = _("      Key fingerprint =");
     }
 
-    if (sk)
-       fingerprint_from_sk (sk, array, &n);
-    else
-       fingerprint_from_pk (pk, array, &n);
-    p = array;
-    if (opt.with_colons && !mode) {
-       fprintf (fp, "fpr:::::::::");
-       for (i=0; i < n ; i++, p++ )
-           fprintf (fp, "%02X", *p );
-       putc(':', fp);
+  fingerprint_from_pk (pk, array, &n);
+  p = array;
+  if (opt.with_colons && !mode)
+    {
+      es_fprintf (fp, "fpr:::::::::");
+      for (i = 0; i < n; i++, p++)
+       es_fprintf (fp, "%02X", *p);
+      es_putc (':', fp);
     }
-    else {
-        if (fp)
-            fputs (text, fp);
-        else
-            tty_printf ("%s", text);
-       if (n == 20) {
-           for (i=0; i < n ; i++, i++, p += 2 ) {
-                if (fp) {
-                    if (i == 10 )
-                        putc(' ', fp);
-                    fprintf (fp, " %02X%02X", *p, p[1] );
-                }
-                else {
-                    if (i == 10 )
-                        tty_printf (" ");
-                    tty_printf (" %02X%02X", *p, p[1]);
-                }
-           }
+  else
+    {
+      tty_fprintf (fp, "%s", text);
+      if (n == 20)
+       {
+         for (i = 0; i < n; i++, i++, p += 2)
+            tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]);
        }
-       else {
-           for (i=0; i < n ; i++, p++ ) {
-                if (fp) {
-                    if (i && !(i%8) )
-                        putc (' ', fp);
-                    fprintf (fp, " %02X", *p );
-                }
-                else {
-                    if (i && !(i%8) )
-                        tty_printf (" ");
-                    tty_printf (" %02X", *p );
-                }
-           }
+      else
+       {
+         for (i = 0; i < n; i++, p++)
+            tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p);
        }
     }
-    if (fp)
-        putc ('\n', fp);
-    else
-        tty_printf ("\n");
-
-    if (n==16 && !opt.with_colons && !opt.flags.allow_weak_digest_algos)
-      {
-        if (fp)
-          fprintf (fp, _("WARNING: a PGP-2 fingerprint is not safe\n"));
-        else
-          tty_printf (_("WARNING: a PGP-2 fingerprint is not safe\n"));
-      }
+  tty_fprintf (fp, "\n");
 }
 
-/* Print the serial number of an OpenPGP card if available. */
+/* Print the serial number of an OpenPGP card if available.  */
 static void
-print_card_serialno (PKT_secret_key *sk)
+print_card_serialno (const char *serialno)
 {
-  int i;
-
-  if (!sk)
+  if (!serialno)
     return;
-  if (!sk->is_protected || sk->protect.s2k.mode != 1002)
-    return; /* Not a card. */
   if (opt.with_colons)
     return; /* Handled elsewhere. */
 
-  fputs (_("      Card serial no. ="), stdout);
-  putchar (' ');
-  if (sk->protect.ivlen == 16
-      && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6) )
-    { /* This is an OpenPGP card. Just print the relevant part. */
-      for (i=8; i < 14; i++)
-        {
-          if (i == 10)
-            putchar (' ');
-          printf ("%02X", sk->protect.iv[i]);
-        }
-    }
-  else
-    { /* Something is wrong: Print all. */
-      for (i=0; i < sk->protect.ivlen; i++)
-        printf ("%02X", sk->protect.iv[i]);
+  es_fputs (_("      Card serial no. ="), es_stdout);
+  es_putc (' ', es_stdout);
+  if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
+    {
+      /* This is an OpenPGP card.  Print the relevant part.  */
+      /* Example: D2760001240101010001000003470000 */
+      /*                          xxxxyyyyyyyy     */
+      es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
     }
-  putchar ('\n');
+ else
+   es_fputs (serialno, es_stdout);
+  es_putc ('\n', es_stdout);
 }
 
 
@@ -1640,31 +1696,31 @@ print_card_serialno (PKT_secret_key *sk)
 void
 set_attrib_fd (int fd)
 {
-  static int last_fd=-1;
+  static int last_fd = -1;
 
-  if ( fd != -1 && last_fd == fd )
+  if (fd != -1 && last_fd == fd)
     return;
 
-  if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr
-       && attrib_fp != log_get_stream () )
-    fclose (attrib_fp);
+  /* Fixme: Do we need to check for the log stream here?  */
+  if (attrib_fp && attrib_fp != log_get_stream ())
+    es_fclose (attrib_fp);
   attrib_fp = NULL;
-  if ( fd == -1 )
+  if (fd == -1)
     return;
 
 #ifdef HAVE_DOSISH_SYSTEM
   setmode (fd, O_BINARY);
 #endif
-  if( fd == 1 )
-    attrib_fp = stdout;
-  else if( fd == 2 )
-    attrib_fp = stderr;
+  if (fd == 1)
+    attrib_fp = es_stdout;
+  else if (fd == 2)
+    attrib_fp = es_stderr;
   else
-    attrib_fp = fdopen (fd, "wb");
+    attrib_fp = es_fdopen (fd, "wb");
   if (!attrib_fp)
     {
-      log_fatal("can't open fd %d for attribute output: %s\n",
-                fd, strerror(errno));
+      log_fatal ("can't open fd %d for attribute output: %s\n",
+                fd, strerror (errno));
     }
 
   last_fd = fd;
index fec238d..a1936b3 100644 (file)
@@ -1,5 +1,5 @@
 /* keyring.c - keyring file handling
- * Copyright (C) 2001, 2004, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2004, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -53,9 +53,8 @@ typedef struct keyring_name *KR_NAME;
 struct keyring_name
 {
   struct keyring_name *next;
-  int secret;
-  int readonly;
-  DOTLOCK lockhd;
+  int read_only;
+  dotlock_t lockhd;
   int is_locked;
   int did_full_scan;
   char fname[1];
@@ -69,9 +68,9 @@ static OffsetHashTable kr_offtbl;
 static int kr_offtbl_ready;
 
 
-struct keyring_handle {
+struct keyring_handle
+{
   CONST_KR_NAME resource;
-  int secret;             /* this is for a secret keyring */
   struct {
     CONST_KR_NAME kr;
     IOBUF iobuf;
@@ -93,7 +92,7 @@ struct keyring_handle {
 
 
 
-static int do_copy (int mode, const char *fname, KBNODE root, int secret,
+static int do_copy (int mode, const char *fname, KBNODE root,
                     off_t start_offset, unsigned int n_packets );
 
 
@@ -201,8 +200,7 @@ update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off)
  * if a new keyring was registered.
 */
 int
-keyring_register_filename (const char *fname, int secret, int readonly,
-                           void **ptr)
+keyring_register_filename (const char *fname, int read_only, void **ptr)
 {
     KR_NAME kr;
 
@@ -214,20 +212,16 @@ keyring_register_filename (const char *fname, int secret, int readonly,
         if (same_file_p (kr->fname, fname))
          {
             /* Already registered. */
-            if (readonly)
-              kr->readonly = 1;
+            if (read_only)
+              kr->read_only = 1;
             *ptr=kr;
            return 0;
          }
       }
 
-    if (secret)
-      register_secured_file (fname);
-
     kr = xmalloc (sizeof *kr + strlen (fname));
     strcpy (kr->fname, fname);
-    kr->secret = !!secret;
-    kr->readonly = readonly;
+    kr->read_only = read_only;
     kr->lockhd = NULL;
     kr->is_locked = 0;
     kr->did_full_scan = 0;
@@ -249,26 +243,24 @@ keyring_is_writable (void *token)
 {
   KR_NAME r = token;
 
-  return r? (r->readonly || !access (r->fname, W_OK)) : 0;
+  return r? (r->read_only || !access (r->fname, W_OK)) : 0;
 }
 
 
 \f
-/* Create a new handle for the resource associated with TOKEN.  SECRET
-   is just just as a cross-check.
+/* Create a new handle for the resource associated with TOKEN.
 
    The returned handle must be released using keyring_release (). */
 KEYRING_HANDLE
-keyring_new (void *token, int secret)
+keyring_new (void *token)
 {
   KEYRING_HANDLE hd;
   KR_NAME resource = token;
 
-  assert (resource && !resource->secret == !secret);
+  assert (resource);
 
   hd = xmalloc_clear (sizeof *hd);
   hd->resource = resource;
-  hd->secret = !!secret;
   active_handles++;
   return hd;
 }
@@ -314,9 +306,9 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
             if (!keyring_is_writable(kr))
                 continue;
             if (!kr->lockhd) {
-                kr->lockhd = create_dotlock( kr->fname );
+                kr->lockhd = dotlock_create (kr->fname, 0);
                 if (!kr->lockhd) {
-                    log_info ("can't allocate lock for `%s'\n", kr->fname );
+                    log_info ("can't allocate lock for '%s'\n", kr->fname );
                     rc = G10ERR_GENERAL;
                 }
             }
@@ -330,8 +322,8 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
                 continue;
             if (kr->is_locked)
                 ;
-            else if (make_dotlock (kr->lockhd, -1) ) {
-                log_info ("can't lock `%s'\n", kr->fname );
+            else if (dotlock_take (kr->lockhd, -1) ) {
+                log_info ("can't lock '%s'\n", kr->fname );
                 rc = G10ERR_GENERAL;
             }
             else
@@ -345,8 +337,8 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
                 continue;
             if (!kr->is_locked)
                 ;
-            else if (release_dotlock (kr->lockhd))
-                log_info ("can't unlock `%s'\n", kr->fname );
+            else if (dotlock_release (kr->lockhd))
+                log_info ("can't unlock '%s'\n", kr->fname );
             else
                 kr->is_locked = 0;
         }
@@ -384,12 +376,12 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
     a = iobuf_open (hd->found.kr->fname);
     if (!a)
       {
-       log_error(_("can't open `%s'\n"), hd->found.kr->fname);
+       log_error(_("can't open '%s'\n"), hd->found.kr->fname);
        return G10ERR_KEYRING_OPEN;
       }
 
     if (iobuf_seek (a, hd->found.offset) ) {
-        log_error ("can't seek `%s'\n", hd->found.kr->fname);
+        log_error ("can't seek '%s'\n", hd->found.kr->fname);
        iobuf_close(a);
        return G10ERR_KEYRING_OPEN;
     }
@@ -412,26 +404,8 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
             rc = G10ERR_INV_KEYRING;
             break;
         }
-
-        /* Filter allowed packets.  */
-        switch (pkt->pkttype){
-          case PKT_PUBLIC_KEY:
-          case PKT_PUBLIC_SUBKEY:
-          case PKT_SECRET_KEY:
-          case PKT_SECRET_SUBKEY:
-          case PKT_USER_ID:
-          case PKT_ATTRIBUTE:
-          case PKT_SIGNATURE:
-            break; /* Allowed per RFC.  */
-          case PKT_RING_TRUST:
-          case PKT_OLD_COMMENT:
-          case PKT_COMMENT:
-          case PKT_GPG_CONTROL:
-            break; /* Allowed by us.  */
-
-          default:
-           log_error ("skipped packet of type %d in keyring\n",
-                       (int)pkt->pkttype);
+       if (pkt->pkttype == PKT_COMPRESSED) {
+           log_error ("skipped compressed packet in keyring\n");
            free_packet(pkt);
            init_packet(pkt);
            continue;
@@ -452,18 +426,11 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
                  && (pkt->pkt.ring_trust->sigcache & 1) ) {
                 /* This is a ring trust packet with a checked signature
                  * status cache following directly a signature paket.
-                 * Set the cache status into that signature packet.
-                 *
-                 * We do not use cached signatures made with MD5 to
-                 * avoid using a cached status created with an older
-                 * version of gpg.  */
+                 * Set the cache status into that signature packet.  */
                 PKT_signature *sig = lastnode->pkt->pkt.signature;
 
-                if (sig->digest_algo != DIGEST_ALGO_MD5)
-                  {
-                    sig->flags.checked = 1;
-                    sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
-                  }
+                sig->flags.checked = 1;
+                sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
             }
             /* Reset LASTNODE, so that we set the cache status only from
              * the ring trust packet immediately following a signature. */
@@ -509,17 +476,14 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
     if (rc || !ret_kb)
        release_kbnode (keyblock);
     else {
-        /*(duplicated from the loop body)*/
+        /*(duplicated form the loop body)*/
         if ( pkt && pkt->pkttype == PKT_RING_TRUST
              && lastnode
              && lastnode->pkt->pkttype == PKT_SIGNATURE
              && (pkt->pkt.ring_trust->sigcache & 1) ) {
             PKT_signature *sig = lastnode->pkt->pkt.signature;
-            if (sig->digest_algo != DIGEST_ALGO_MD5)
-              {
-                sig->flags.checked = 1;
-                sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
-              }
+            sig->flags.checked = 1;
+            sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
         }
        *ret_kb = keyblock;
     }
@@ -544,7 +508,7 @@ keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb)
     if (!hd->found.kr)
         return -1; /* no successful prior search */
 
-    if (hd->found.kr->readonly)
+    if (hd->found.kr->read_only)
       return gpg_error (GPG_ERR_EACCES);
 
     if (!hd->found.n_packets) {
@@ -565,10 +529,10 @@ keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb)
     hd->current.iobuf = NULL;
 
     /* do the update */
-    rc = do_copy (3, hd->found.kr->fname, kb, hd->secret,
+    rc = do_copy (3, hd->found.kr->fname, kb,
                   hd->found.offset, hd->found.n_packets );
     if (!rc) {
-      if (!hd->secret && kr_offtbl)
+      if (kr_offtbl)
         {
           update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
         }
@@ -590,13 +554,13 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
     else if (hd->found.kr)
       {
         fname = hd->found.kr->fname;
-        if (hd->found.kr->readonly)
+        if (hd->found.kr->read_only)
           return gpg_error (GPG_ERR_EACCES);
       }
     else if (hd->current.kr)
       {
         fname = hd->current.kr->fname;
-        if (hd->current.kr->readonly)
+        if (hd->current.kr->read_only)
           return gpg_error (GPG_ERR_EACCES);
       }
     else
@@ -613,8 +577,8 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
     hd->current.iobuf = NULL;
 
     /* do the insert */
-    rc = do_copy (1, fname, kb, hd->secret, 0, 0 );
-    if (!rc && !hd->secret && kr_offtbl)
+    rc = do_copy (1, fname, kb, 0, 0 );
+    if (!rc && kr_offtbl)
       {
         update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
       }
@@ -631,7 +595,7 @@ keyring_delete_keyblock (KEYRING_HANDLE hd)
     if (!hd->found.kr)
         return -1; /* no successful prior search */
 
-    if (hd->found.kr->readonly)
+    if (hd->found.kr->read_only)
       return gpg_error (GPG_ERR_EACCES);
 
     if (!hd->found.n_packets) {
@@ -653,7 +617,7 @@ keyring_delete_keyblock (KEYRING_HANDLE hd)
     hd->current.iobuf = NULL;
 
     /* do the delete */
-    rc = do_copy (2, hd->found.kr->fname, NULL, hd->secret,
+    rc = do_copy (2, hd->found.kr->fname, NULL,
                   hd->found.offset, hd->found.n_packets );
     if (!rc) {
         /* better reset the found info */
@@ -723,7 +687,7 @@ prepare_search (KEYRING_HANDLE hd)
     if (!hd->current.iobuf)
       {
         hd->current.error = gpg_error_from_syserror ();
-        log_error(_("can't open `%s'\n"), hd->current.kr->fname );
+        log_error(_("can't open '%s'\n"), hd->current.kr->fname );
         return hd->current.error;
       }
 
@@ -935,7 +899,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
   int use_offtbl;
   PKT_user_id *uid = NULL;
   PKT_public_key *pk = NULL;
-  PKT_secret_key *sk = NULL;
   u32 aki[2];
 
   /* figure out what information we need */
@@ -981,7 +944,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
   if (rc)
     return rc;
 
-  use_offtbl = !hd->secret && kr_offtbl;
+  use_offtbl = !!kr_offtbl;
   if (!use_offtbl)
     ;
   else if (!kr_offtbl_ready)
@@ -1053,10 +1016,11 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
         }
 
       pk = NULL;
-      sk = NULL;
       uid = NULL;
       if (   pkt.pkttype == PKT_PUBLIC_KEY
-             || pkt.pkttype == PKT_PUBLIC_SUBKEY)
+             || pkt.pkttype == PKT_PUBLIC_SUBKEY
+             || pkt.pkttype == PKT_SECRET_KEY
+             || pkt.pkttype == PKT_SECRET_SUBKEY)
         {
           pk = pkt.pkt.public_key;
           ++pk_no;
@@ -1077,21 +1041,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
           uid = pkt.pkt.user_id;
           ++uid_no;
         }
-      else if (    pkt.pkttype == PKT_SECRET_KEY
-                   || pkt.pkttype == PKT_SECRET_SUBKEY)
-        {
-          sk = pkt.pkt.secret_key;
-          ++pk_no;
-
-          if (need_fpr) {
-            fingerprint_from_sk (sk, afp, &an);
-            while (an < 20) /* fill up to 20 bytes */
-              afp[an++] = 0;
-          }
-          if (need_keyid)
-            keyid_from_sk (sk, aki);
-
-        }
 
       for (n=0; n < ndesc; n++)
         {
@@ -1112,29 +1061,29 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
             break;
 
           case KEYDB_SEARCH_MODE_SHORT_KID:
-            if ((pk||sk) && desc[n].u.kid[1] == aki[1])
+            if (pk && desc[n].u.kid[1] == aki[1])
               goto found;
             break;
           case KEYDB_SEARCH_MODE_LONG_KID:
-            if ((pk||sk) && desc[n].u.kid[0] == aki[0]
+            if (pk && desc[n].u.kid[0] == aki[0]
                 && desc[n].u.kid[1] == aki[1])
               goto found;
             break;
           case KEYDB_SEARCH_MODE_FPR16:
-            if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16))
+            if (pk && !memcmp (desc[n].u.fpr, afp, 16))
               goto found;
             break;
           case KEYDB_SEARCH_MODE_FPR20:
           case KEYDB_SEARCH_MODE_FPR:
-            if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20))
+            if (pk && !memcmp (desc[n].u.fpr, afp, 20))
               goto found;
             break;
           case KEYDB_SEARCH_MODE_FIRST:
-            if (pk||sk)
+            if (pk)
               goto found;
             break;
           case KEYDB_SEARCH_MODE_NEXT:
-            if (pk||sk)
+            if (pk)
               goto found;
             break;
           default:
@@ -1164,7 +1113,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
     {
       hd->found.offset = main_offset;
       hd->found.kr = hd->current.kr;
-      hd->found.pk_no = (pk||sk)? pk_no : 0;
+      hd->found.pk_no = pk? pk_no : 0;
       hd->found.uid_no = uid? uid_no : 0;
     }
   else if (rc == -1)
@@ -1176,11 +1125,10 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
         {
           KR_NAME kr;
 
-          /* First set the did_full_scan flag for this keyring (ignore
-             secret keyrings) */
+          /* First set the did_full_scan flag for this keyring.  */
           for (kr=kr_names; kr; kr = kr->next)
             {
-              if (!kr->secret && hd->resource == kr)
+              if (hd->resource == kr)
                 {
                   kr->did_full_scan = 1;
                   break;
@@ -1190,7 +1138,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
              offtbl ready */
           for (kr=kr_names; kr; kr = kr->next)
             {
-              if (!kr->secret && !kr->did_full_scan)
+              if (!kr->did_full_scan)
                 break;
             }
           if (!kr)
@@ -1223,7 +1171,7 @@ create_tmp_file (const char *template,
    * works.  So we replace .gpg by .bak or .tmp
    */
   if (strlen (template) > 4
-      && !strcmp (template+strlen(template)-4, EXTSEP_S "gpg") )
+      && !strcmp (template+strlen(template)-4, EXTSEP_S GPGEXT_GPG) )
     {
       bakfname = xmalloc (strlen (template) + 1);
       strcpy (bakfname, template);
@@ -1249,20 +1197,22 @@ create_tmp_file (const char *template,
     strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp");
 # endif /* Posix filename */
 
-    /* Create the temp file with limited access */
+    /* Create the temp file with limited access.  Note that the umask
+       call is not anymore needed because iobuf_create now takes care
+       of it.  However, it does not harm and thus we keep it.  */
     oldmask=umask(077);
     if (is_secured_filename (tmpfname))
       {
         *r_fp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     else
-      *r_fp = iobuf_create (tmpfname);
+      *r_fp = iobuf_create (tmpfname, 1);
     umask(oldmask);
     if (!*r_fp)
       {
         int rc = gpg_error_from_syserror ();
-       log_error(_("can't create `%s': %s\n"), tmpfname, strerror(errno) );
+       log_error(_("can't create '%s': %s\n"), tmpfname, strerror(errno) );
         xfree (tmpfname);
         xfree (bakfname);
        return rc;
@@ -1275,54 +1225,39 @@ create_tmp_file (const char *template,
 
 
 static int
-rename_tmp_file (const char *bakfname, const char *tmpfname,
-                 const char *fname, int secret )
+rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname)
 {
   int rc = 0;
 
-  /* It's a secret keyring, so let's force a fsync just to be safe on
-     filesystems that may not sync data and metadata together
-     (e.g. ext4). */
-  if (secret && iobuf_ioctl (NULL, 4, 0, (char*)tmpfname))
-    {
-      rc = gpg_error_from_syserror ();
-      goto fail;
-    }
-
   /* Invalidate close caches.  */
-  if (iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ))
+  if (iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)tmpfname ))
     {
       rc = gpg_error_from_syserror ();
       goto fail;
     }
-  iobuf_ioctl (NULL, 2, 0, (char*)bakfname );
-  iobuf_ioctl (NULL, 2, 0, (char*)fname );
+  iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)bakfname );
+  iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname );
 
-  /* first make a backup file except for secret keyrings */
-  if (!secret)
-    {
+  /* First make a backup file. */
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-      remove (bakfname);
+  gnupg_remove (bakfname);
 #endif
-      if (rename (fname, bakfname) )
-        {
-          rc = gpg_error_from_syserror ();
-          log_error ("renaming `%s' to `%s' failed: %s\n",
-                     fname, bakfname, strerror(errno) );
-          return rc;
-       }
+  if (rename (fname, bakfname) )
+    {
+      rc = gpg_error_from_syserror ();
+      log_error ("renaming '%s' to '%s' failed: %s\n",
+                 fname, bakfname, strerror(errno) );
+      return rc;
     }
 
   /* then rename the file */
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-  remove( fname );
+  gnupg_remove( fname );
 #endif
-  if (secret)
-    unregister_secured_file (fname);
   if (rename (tmpfname, fname) )
     {
       rc = gpg_error_from_syserror ();
-      log_error (_("renaming `%s' to `%s' failed: %s\n"),
+      log_error (_("renaming '%s' to '%s' failed: %s\n"),
                  tmpfname, fname, strerror(errno) );
       register_secured_file (fname);
       goto fail;
@@ -1336,12 +1271,10 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
 
     statbuf.st_mode=S_IRUSR | S_IWUSR;
 
-    if (((secret && !opt.preserve_permissions)
-         || !stat (bakfname,&statbuf))
-        && !chmod (fname,statbuf.st_mode))
+    if (!stat (bakfname, &statbuf) && !chmod (fname, statbuf.st_mode))
       ;
     else
-      log_error ("WARNING: unable to restore permissions to `%s': %s",
+      log_error ("WARNING: unable to restore permissions to '%s': %s",
                  fname, strerror(errno));
   }
 #endif
@@ -1349,13 +1282,6 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
   return 0;
 
  fail:
-  if (secret)
-    {
-      log_info(_("WARNING: 2 files with confidential information exists.\n"));
-      log_info(_("%s is the unchanged one\n"), fname );
-      log_info(_("%s is the new one\n"), tmpfname );
-      log_info(_("Please fix this possible security flaw\n"));
-    }
   return rc;
 }
 
@@ -1382,7 +1308,7 @@ write_keyblock (IOBUF fp, KBNODE keyblock)
           PKT_signature *sig = node->pkt->pkt.signature;
           unsigned int cacheval = 0;
 
-          if (sig->flags.checked && sig->digest_algo != DIGEST_ALGO_MD5)
+          if (sig->flags.checked)
             {
               cacheval |= 1;
               if (sig->flags.valid)
@@ -1420,7 +1346,7 @@ keyring_rebuild_cache (void *token,int noisy)
   int rc;
   ulong count = 0, sigcount = 0;
 
-  hd = keyring_new (token, 0);
+  hd = keyring_new (token);
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_FIRST;
 
@@ -1439,7 +1365,7 @@ keyring_rebuild_cache (void *token,int noisy)
               if (iobuf_close (tmpfp))
                 {
                   rc = gpg_error_from_syserror ();
-                  log_error ("error closing `%s': %s\n",
+                  log_error ("error closing '%s': %s\n",
                              tmpfilename, strerror (errno));
                   goto leave;
                 }
@@ -1448,14 +1374,14 @@ keyring_rebuild_cache (void *token,int noisy)
               tmpfp = NULL;
             }
           rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
-                                             lastresname, 0) : 0;
+                                             lastresname) : 0;
           xfree (tmpfilename);  tmpfilename = NULL;
           xfree (bakfilename);  bakfilename = NULL;
           if (rc)
             goto leave;
           lastresname = resname;
           if (noisy && !opt.quiet)
-            log_info (_("caching keyring `%s'\n"), resname);
+            log_info (_("caching keyring '%s'\n"), resname);
           rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp);
           if (rc)
             goto leave;
@@ -1477,46 +1403,57 @@ keyring_rebuild_cache (void *token,int noisy)
                      keyblock->pkt->pkttype, noisy? " - deleted":"");
           if (noisy)
             continue;
-          log_info ("Hint: backup your keys and try running `%s'\n",
+          log_info ("Hint: backup your keys and try running '%s'\n",
                     "gpg --rebuild-keydb-caches");
           rc = gpg_error (GPG_ERR_INV_KEYRING);
           goto leave;
         }
 
-      /* check all signature to set the signature's cache flags */
-      for (node=keyblock; node; node=node->next)
+      if (keyblock->pkt->pkt.public_key->version < 4)
+        {
+          /* We do not copy/cache v3 keys or any other unknown
+             packets.  It is better to remove them from the keyring.
+             The code required to keep them in the keyring would be
+             too complicated.  Given that we do not touch the old
+             secring.gpg a suitable backup for decryption of v3 stuff
+             using an older gpg version will always be available.  */
+        }
+      else
         {
-         /* Note that this doesn't cache the result of a revocation
-            issued by a designated revoker.  This is because the pk
-            in question does not carry the revkeys as we haven't
-            merged the key and selfsigs.  It is questionable whether
-            this matters very much since there are very very few
-            designated revoker revocation packets out there. */
-
-          if (node->pkt->pkttype == PKT_SIGNATURE)
+          /* Check all signature to set the signature's cache flags. */
+          for (node=keyblock; node; node=node->next)
             {
-             PKT_signature *sig=node->pkt->pkt.signature;
+              /* Note that this doesn't cache the result of a
+                 revocation issued by a designated revoker.  This is
+                 because the pk in question does not carry the revkeys
+                 as we haven't merged the key and selfsigs.  It is
+                 questionable whether this matters very much since
+                 there are very very few designated revoker revocation
+                 packets out there. */
+              if (node->pkt->pkttype == PKT_SIGNATURE)
+                {
+                  PKT_signature *sig=node->pkt->pkt.signature;
 
-             if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
-                && (openpgp_md_test_algo(sig->digest_algo)
-                    || openpgp_pk_test_algo(sig->pubkey_algo)))
-               sig->flags.checked=sig->flags.valid=0;
-             else
-               check_key_signature (keyblock, node, NULL);
+                  if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
+                     && (openpgp_md_test_algo(sig->digest_algo)
+                         || openpgp_pk_test_algo(sig->pubkey_algo)))
+                    sig->flags.checked=sig->flags.valid=0;
+                  else
+                    check_key_signature (keyblock, node, NULL);
 
-              sigcount++;
+                  sigcount++;
+                }
             }
-        }
-
-      /* write the keyblock to the temporary file */
-      rc = write_keyblock (tmpfp, keyblock);
-      if (rc)
-        goto leave;
 
-      if ( !(++count % 50) && noisy && !opt.quiet)
-        log_info(_("%lu keys cached so far (%lu signatures)\n"),
-                 count, sigcount );
+          /* Write the keyblock to the temporary file.  */
+          rc = write_keyblock (tmpfp, keyblock);
+          if (rc)
+            goto leave;
 
+          if ( !(++count % 50) && noisy && !opt.quiet)
+            log_info(_("%lu keys cached so far (%lu signatures)\n"),
+                     count, sigcount );
+        }
     } /* end main loop */
   if (rc == -1)
     rc = 0;
@@ -1532,7 +1469,7 @@ keyring_rebuild_cache (void *token,int noisy)
       if (iobuf_close (tmpfp))
         {
           rc = gpg_error_from_syserror ();
-          log_error ("error closing `%s': %s\n",
+          log_error ("error closing '%s': %s\n",
                      tmpfilename, strerror (errno));
           goto leave;
         }
@@ -1541,7 +1478,7 @@ keyring_rebuild_cache (void *token,int noisy)
       tmpfp = NULL;
     }
   rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
-                                     lastresname, 0) : 0;
+                                     lastresname) : 0;
   xfree (tmpfilename);  tmpfilename = NULL;
   xfree (bakfilename);  bakfilename = NULL;
 
@@ -1564,7 +1501,7 @@ keyring_rebuild_cache (void *token,int noisy)
  *     3 = update
  */
 static int
-do_copy (int mode, const char *fname, KBNODE root, int secret,
+do_copy (int mode, const char *fname, KBNODE root,
          off_t start_offset, unsigned int n_packets )
 {
     IOBUF fp, newfp;
@@ -1584,17 +1521,17 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
        mode_t oldmask;
 
        oldmask=umask(077);
-        if (!secret && is_secured_filename (fname)) {
+        if (is_secured_filename (fname)) {
             newfp = NULL;
-            errno = EPERM;
+            gpg_err_set_errno (EPERM);
         }
         else
-            newfp = iobuf_create (fname);
+            newfp = iobuf_create (fname, 1);
        umask(oldmask);
        if( !newfp )
          {
             rc = gpg_error_from_syserror ();
-           log_error (_("can't create `%s': %s\n"), fname, strerror(errno));
+           log_error (_("can't create '%s': %s\n"), fname, strerror(errno));
            return rc;
          }
        if( !opt.quiet )
@@ -1620,7 +1557,7 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
     if( !fp )
       {
         rc = gpg_error_from_syserror ();
-       log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
+       log_error(_("can't open '%s': %s\n"), fname, strerror(errno) );
        goto leave;
       }
 
@@ -1630,18 +1567,14 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
        iobuf_close(fp);
        goto leave;
     }
-    if (secret)
-      register_secured_file (tmpfname);
 
     if( mode == 1 ) { /* insert */
        /* copy everything to the new file */
        rc = copy_all_packets (fp, newfp);
        if( rc != -1 ) {
-           log_error("%s: copy to `%s' failed: %s\n",
+           log_error("%s: copy to '%s' failed: %s\n",
                      fname, tmpfname, g10_errstr(rc) );
            iobuf_close(fp);
-            if (secret)
-              unregister_secured_file (tmpfname);
            iobuf_cancel(newfp);
            goto leave;
        }
@@ -1652,11 +1585,9 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
        /* copy first part to the new file */
        rc = copy_some_packets( fp, newfp, start_offset );
        if( rc ) { /* should never get EOF here */
-           log_error ("%s: copy to `%s' failed: %s\n",
+           log_error ("%s: copy to '%s' failed: %s\n",
                        fname, tmpfname, g10_errstr(rc) );
            iobuf_close(fp);
-            if (secret)
-              unregister_secured_file (tmpfname);
            iobuf_cancel(newfp);
            goto leave;
        }
@@ -1667,8 +1598,6 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
            log_error("%s: skipping %u packets failed: %s\n",
                            fname, n_packets, g10_errstr(rc));
            iobuf_close(fp);
-            if (secret)
-              unregister_secured_file (tmpfname);
            iobuf_cancel(newfp);
            goto leave;
        }
@@ -1678,8 +1607,6 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
         rc = write_keyblock (newfp, root);
         if (rc) {
           iobuf_close(fp);
-          if (secret)
-            unregister_secured_file (tmpfname);
           iobuf_cancel(newfp);
           goto leave;
         }
@@ -1689,11 +1616,9 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
        /* copy the rest */
        rc = copy_all_packets( fp, newfp );
        if( rc != -1 ) {
-           log_error("%s: copy to `%s' failed: %s\n",
+           log_error("%s: copy to '%s' failed: %s\n",
                      fname, tmpfname, g10_errstr(rc) );
            iobuf_close(fp);
-            if (secret)
-              unregister_secured_file (tmpfname);
            iobuf_cancel(newfp);
            goto leave;
        }
@@ -1712,7 +1637,7 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
        goto leave;
     }
 
-    rc = rename_tmp_file (bakfname, tmpfname, fname, secret);
+    rc = rename_tmp_file (bakfname, tmpfname, fname);
 
   leave:
     xfree(bakfname);
index 928605c..f83c2cb 100644 (file)
 #ifndef GPG_KEYRING_H
 #define GPG_KEYRING_H 1
 
+#include "../common/userids.h"
 
 typedef struct keyring_handle *KEYRING_HANDLE;
 
-int keyring_register_filename (const char *fname, int secret, int readonly,
-                               void **ptr);
+int keyring_register_filename (const char *fname, int read_only, void **ptr);
 int keyring_is_writable (void *token);
 
-KEYRING_HANDLE keyring_new (void *token, int secret);
+KEYRING_HANDLE keyring_new (void *token);
 void keyring_release (KEYRING_HANDLE hd);
 const char *keyring_get_resource_name (KEYRING_HANDLE hd);
 int keyring_lock (KEYRING_HANDLE hd, int yes);
index 9f05c18..2b1b64e 100644 (file)
@@ -33,20 +33,23 @@ struct keyserver_spec *parse_keyserver_uri(const char *string,
                                           const char *configname,
                                           unsigned int configlineno);
 struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig);
-int keyserver_export(strlist_t users);
-int keyserver_import(strlist_t users);
-int keyserver_import_fprint(const byte *fprint,size_t fprint_len,
-                           struct keyserver_spec *keyserver);
-int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver);
-int keyserver_refresh(strlist_t users);
-int keyserver_search(strlist_t tokens);
-int keyserver_fetch(strlist_t urilist);
-int keyserver_import_cert(const char *name,
-                         unsigned char **fpr,size_t *fpr_len);
-int keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len);
-int keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
-                         struct keyserver_spec *keyserver);
-int keyserver_import_ldap(const char *name,
-                         unsigned char **fpr,size_t *fpr_len);
+int keyserver_export (ctrl_t ctrl, strlist_t users);
+int keyserver_import (ctrl_t ctrl, strlist_t users);
+int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
+                             struct keyserver_spec *keyserver);
+int keyserver_import_keyid (ctrl_t ctrl, u32 *keyid,
+                            struct keyserver_spec *keyserver);
+int keyserver_refresh (ctrl_t ctrl, strlist_t users);
+gpg_error_t keyserver_search (ctrl_t ctrl, strlist_t tokens);
+int keyserver_fetch (ctrl_t ctrl, strlist_t urilist);
+int keyserver_import_cert (ctrl_t ctrl, const char *name,
+                           unsigned char **fpr,size_t *fpr_len);
+int keyserver_import_pka (ctrl_t ctrl,
+                          const char *name,unsigned char **fpr,size_t *fpr_len);
+int keyserver_import_name (ctrl_t ctrl,
+                           const char *name,unsigned char **fpr,size_t *fpr_len,
+                           struct keyserver_spec *keyserver);
+int keyserver_import_ldap (ctrl_t ctrl, const char *name,
+                           unsigned char **fpr,size_t *fpr_len);
 
 #endif /* !_KEYSERVER_INTERNAL_H_ */
index dc49e1b..1b2e128 100644 (file)
@@ -1,6 +1,7 @@
 /* keyserver.c - generic keyserver code
  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- *               2009, 2012 Free Software Foundation, Inc.
+ *               2009, 2011, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -45,6 +46,8 @@
 #ifdef USE_DNS_SRV
 #include "srv.h"
 #endif
+#include "membuf.h"
+#include "call-dirmngr.h"
 
 #ifdef HAVE_W32_SYSTEM
 /* It seems Vista doesn't grok X_OK and so fails access() tests.
@@ -64,6 +67,24 @@ struct keyrec
   unsigned int lines;
 };
 
+/* Parameters for the search line handler.  */
+struct search_line_handler_parm_s
+{
+  ctrl_t ctrl;     /* The session control structure.  */
+  char *searchstr_disp;  /* Native encoded search string or NULL.  */
+  KEYDB_SEARCH_DESC *desc; /* Array with search descriptions.  */
+  int count;      /* Number of keys we are currently prepared to
+                     handle.  This is the size of the DESC array.  If
+                     it is too small, it will grow safely.  */
+  int validcount; /* Enable the "Key x-y of z" messages. */
+  int nkeys;      /* Number of processed records.  */
+  int any_lines;  /* At least one line has been processed.  */
+  unsigned int numlines;  /* Counter for displayed lines.  */
+  int eof_seen;   /* EOF encountered.  */
+  int not_found;  /* Set if no keys have been found.  */
+};
+
+
 enum ks_action {KS_UNKNOWN=0,KS_GET,KS_GETNAME,KS_SEND,KS_SEARCH};
 
 static struct parse_options keyserver_opts[]=
@@ -88,13 +109,17 @@ static struct parse_options keyserver_opts[]=
     {NULL,0,NULL,NULL}
   };
 
-static int keyserver_work(enum ks_action action,strlist_t list,
-                         KEYDB_SEARCH_DESC *desc,int count,
-                         unsigned char **fpr,size_t *fpr_len,
-                         struct keyserver_spec *keyserver);
+static gpg_error_t keyserver_get (ctrl_t ctrl,
+                                  KEYDB_SEARCH_DESC *desc, int ndesc,
+                                  struct keyserver_spec *keyserver,
+                                  unsigned char **r_fpr, size_t *r_fprlen);
+static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
+                                  struct keyserver_spec *keyserver);
 
-/* Reasonable guess */
-#define DEFAULT_MAX_CERT_SIZE 16384
+
+/* Reasonable guess.  The commonly used test key simon.josefsson.org
+   is larger than 32k, thus we need at least this value. */
+#define DEFAULT_MAX_CERT_SIZE 65536
 
 static size_t max_cert_size=DEFAULT_MAX_CERT_SIZE;
 
@@ -150,7 +175,7 @@ parse_keyserver_options(char *options)
 #ifdef EXEC_TEMPFILE_ONLY
       if(ascii_strncasecmp(tok,"use-temp-files",14)==0 ||
              ascii_strncasecmp(tok,"no-use-temp-files",17)==0)
-       log_info(_("WARNING: keyserver option `%s' is not used"
+       log_info(_("WARNING: keyserver option '%s' is not used"
                   " on this platform\n"),tok);
 #else
       if(ascii_strncasecmp(tok,"use-temp-files",14)==0)
@@ -235,9 +260,9 @@ keyserver_match(struct keyserver_spec *spec)
    parser any longer so it can be removed, or at least moved to
    keyserver/ksutil.c for limited use in gpgkeys_ldap or the like. */
 
-struct keyserver_spec *
-parse_keyserver_uri(const char *string,int require_scheme,
-                   const char *configname,unsigned int configlineno)
+keyserver_spec_t
+parse_keyserver_uri (const char *string,int require_scheme,
+                    const char *configname,unsigned int configlineno)
 {
   int assume_hkp=0;
   struct keyserver_spec *keyserver;
@@ -476,20 +501,21 @@ print_keyrec(int number,struct keyrec *keyrec)
 
   iobuf_writebyte(keyrec->uidbuf,0);
   iobuf_flush_temp(keyrec->uidbuf);
-  printf("(%d)\t%s  ",number,iobuf_get_temp_buffer(keyrec->uidbuf));
+  es_printf ("(%d)\t%s  ", number, iobuf_get_temp_buffer (keyrec->uidbuf));
 
-  if(keyrec->size>0)
-    printf("%d bit ",keyrec->size);
+  if (keyrec->size>0)
+    es_printf ("%d bit ", keyrec->size);
 
   if(keyrec->type)
     {
       const char *str;
 
       str = openpgp_pk_algo_name (keyrec->type);
-      if(str && strcmp (str, "?"))
-       printf("%s ",str);
+
+      if (str && strcmp (str, "?"))
+       es_printf ("%s ",str);
       else
-       printf("unknown ");
+       es_printf ("unknown ");
     }
 
   switch(keyrec->desc.mode)
@@ -498,24 +524,24 @@ print_keyrec(int number,struct keyrec *keyrec)
         choice but to use it.  Do check --keyid-format to add a 0x if
         needed. */
     case KEYDB_SEARCH_MODE_SHORT_KID:
-      printf("key %s%08lX",
-            (opt.keyid_format==KF_0xSHORT
-             || opt.keyid_format==KF_0xLONG)?"0x":"",
-            (ulong)keyrec->desc.u.kid[1]);
+      es_printf ("key %s%08lX",
+                 (opt.keyid_format==KF_0xSHORT
+                  || opt.keyid_format==KF_0xLONG)?"0x":"",
+                 (ulong)keyrec->desc.u.kid[1]);
       break;
 
       /* However, if it gave us a long keyid, we can honor
         --keyid-format via keystr(). */
     case KEYDB_SEARCH_MODE_LONG_KID:
-      printf("key %s",keystr(keyrec->desc.u.kid));
+      es_printf ("key %s",keystr(keyrec->desc.u.kid));
       break;
 
       /* If it gave us a PGP 2.x fingerprint, not much we can do
         beyond displaying it. */
     case KEYDB_SEARCH_MODE_FPR16:
-      printf("key ");
+      es_printf ("key ");
       for(i=0;i<16;i++)
-       printf("%02X",keyrec->desc.u.fpr[i]);
+       es_printf ("%02X",keyrec->desc.u.fpr[i]);
       break;
 
       /* If we get a modern fingerprint, we have the most
@@ -524,7 +550,7 @@ print_keyrec(int number,struct keyrec *keyrec)
       {
        u32 kid[2];
        keyid_from_fingerprint(keyrec->desc.u.fpr,20,kid);
-       printf("key %s",keystr(kid));
+       es_printf("key %s",keystr(kid));
       }
       break;
 
@@ -535,24 +561,24 @@ print_keyrec(int number,struct keyrec *keyrec)
 
   if(keyrec->createtime>0)
     {
-      printf(", ");
-      printf(_("created: %s"),strtimestamp(keyrec->createtime));
+      es_printf (", ");
+      es_printf (_("created: %s"), strtimestamp(keyrec->createtime));
     }
 
   if(keyrec->expiretime>0)
     {
-      printf(", ");
-      printf(_("expires: %s"),strtimestamp(keyrec->expiretime));
+      es_printf (", ");
+      es_printf (_("expires: %s"), strtimestamp(keyrec->expiretime));
     }
 
-  if(keyrec->flags&1)
-    printf(" (%s)",_("revoked"));
+  if (keyrec->flags&1)
+    es_printf (" (%s)", _("revoked"));
   if(keyrec->flags&2)
-    printf(" (%s)",_("disabled"));
+    es_printf (" (%s)", _("disabled"));
   if(keyrec->flags&4)
-    printf(" (%s)",_("expired"));
+    es_printf (" (%s)", _("expired"));
 
-  printf("\n");
+  es_printf ("\n");
 }
 
 /* Returns a keyrec (which must be freed) once a key is complete, and
@@ -561,6 +587,8 @@ print_keyrec(int number,struct keyrec *keyrec)
 static struct keyrec *
 parse_keyrec(char *keystring)
 {
+  /* FIXME: Remove the static and put the data into the parms we use
+     for the caller anyway.  */
   static struct keyrec *work=NULL;
   struct keyrec *ret=NULL;
   char *record;
@@ -589,12 +617,7 @@ parse_keyrec(char *keystring)
       work->uidbuf=iobuf_temp();
     }
 
-  /* Remove trailing whitespace */
-  for(i=strlen(keystring);i>0;i--)
-    if(ascii_isspace(keystring[i-1]))
-      keystring[i-1]='\0';
-    else
-      break;
+  trim_trailing_ws (keystring, strlen (keystring));
 
   if((record=strsep(&keystring,":"))==NULL)
     return ret;
@@ -602,6 +625,7 @@ parse_keyrec(char *keystring)
   if(ascii_strcasecmp("pub",record)==0)
     {
       char *tok;
+      gpg_error_t err;
 
       if(work->desc.mode)
        {
@@ -613,11 +637,11 @@ parse_keyrec(char *keystring)
       if((tok=strsep(&keystring,":"))==NULL)
        return ret;
 
-      classify_user_id(tok,&work->desc);
-      if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID
-        && work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID
-        && work->desc.mode!=KEYDB_SEARCH_MODE_FPR16
-        && work->desc.mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (tok, &work->desc, 1);
+      if (err || (work->desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR16
+                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR20))
        {
          work->desc.mode=KEYDB_SEARCH_MODE_NONE;
          return ret;
@@ -732,271 +756,306 @@ parse_keyrec(char *keystring)
   return ret;
 }
 
-/* TODO: do this as a list sent to keyserver_work rather than calling
-   it once for each key to get the correct counts after the import
-   (cosmetics, really) and to better take advantage of the keyservers
-   that can do multiple fetches in one go (LDAP). */
-static int
-show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
+/* Show a prompt and allow the user to select keys for retrieval.  */
+static gpg_error_t
+show_prompt (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int numdesc,
+             int count, const char *search)
 {
-  char *answer;
+  gpg_error_t err;
+  char *answer = NULL;
 
-  fflush (stdout);
+  es_fflush (es_stdout);
 
-  if(count && opt.command_fd==-1)
+  if (count && opt.command_fd == -1)
     {
-      static int from=1;
-      tty_printf("Keys %d-%d of %d for \"%s\".  ",from,numdesc,count,search);
-      from=numdesc+1;
+      static int from = 1;
+      tty_printf ("Keys %d-%d of %d for \"%s\".  ",
+                  from, numdesc, count, search);
+      from = numdesc + 1;
     }
 
-  answer=cpr_get_no_help("keysearch.prompt",
-                        _("Enter number(s), N)ext, or Q)uit > "));
+ again:
+  err = 0;
+  xfree (answer);
+  answer = cpr_get_no_help ("keysearch.prompt",
+                            _("Enter number(s), N)ext, or Q)uit > "));
   /* control-d */
-  if(answer[0]=='\x04')
+  if (answer[0]=='\x04')
     {
-      printf("Q\n");
-      answer[0]='q';
+      tty_printf ("Q\n");
+      answer[0] = 'q';
     }
 
-  if(answer[0]=='q' || answer[0]=='Q')
-    {
-      xfree(answer);
-      return 1;
-    }
-  else if(atoi(answer)>=1 && atoi(answer)<=numdesc)
+  if (answer[0]=='q' || answer[0]=='Q')
+    err = gpg_error (GPG_ERR_CANCELED);
+  else if (atoi (answer) >= 1 && atoi (answer) <= numdesc)
     {
-      char *split=answer,*num;
-
-      while((num=strsep(&split," ,"))!=NULL)
-       if(atoi(num)>=1 && atoi(num)<=numdesc)
-         keyserver_work(KS_GET,NULL,&desc[atoi(num)-1],1,
-                        NULL,NULL,opt.keyserver);
+      char *split = answer;
+      char *num;
+      int numarray[50];
+      int numidx = 0;
+      int idx;
+
+      while ((num = strsep (&split, " ,")))
+       if (atoi (num) >= 1 && atoi (num) <= numdesc)
+          {
+            if (numidx >= DIM (numarray))
+              {
+                tty_printf ("Too many keys selected\n");
+                goto again;
+              }
+            numarray[numidx++] = atoi (num);
+          }
+
+      if (!numidx)
+        goto again;
 
-      xfree(answer);
-      return 1;
+      {
+        KEYDB_SEARCH_DESC *selarray;
+
+        selarray = xtrymalloc (numidx * sizeof *selarray);
+        if (!selarray)
+          {
+            err = gpg_error_from_syserror ();
+            goto leave;
+          }
+        for (idx = 0; idx < numidx; idx++)
+          selarray[idx] = desc[numarray[idx]-1];
+        err = keyserver_get (ctrl, selarray, numidx, NULL, NULL, NULL);
+        xfree (selarray);
+      }
     }
 
-  return 0;
+ leave:
+  xfree (answer);
+  return err;
 }
 
-/* Count and searchstr are just for cosmetics.  If the count is too
-   small, it will grow safely.  If negative it disables the "Key x-y
-   of z" messages.  searchstr should be UTF-8 (rather than native). */
-static void
-keyserver_search_prompt(IOBUF buffer,const char *searchstr)
-{
-  int i=0,validcount=0,started=0,header=0,count=1;
-  unsigned int maxlen,buflen,numlines=0;
-  KEYDB_SEARCH_DESC *desc;
-  byte *line=NULL;
-  char *localstr=NULL;
 
-  if(searchstr)
-    localstr=utf8_to_native(searchstr,strlen(searchstr),0);
-
-  desc=xmalloc(count*sizeof(KEYDB_SEARCH_DESC));
+/* This is a callback used by call-dirmngr.c to process the result of
+   KS_SEARCH command.  If SPECIAL is 0, LINE is the actual data line
+   received with all escaping removed and guaranteed to be exactly one
+   line with stripped LF; an EOF is indicated by LINE passed as NULL.
+   If special is 1, the line contains the source of the information
+   (usually an URL).  LINE may be modified after return.  */
+static gpg_error_t
+search_line_handler (void *opaque, int special, char *line)
+{
+  struct search_line_handler_parm_s *parm = opaque;
+  gpg_error_t err = 0;
+  struct keyrec *keyrec;
 
-  for(;;)
+  if (special == 1)
+    {
+      log_info ("data source: %s\n", line);
+      return 0;
+    }
+  else if (special)
     {
-      struct keyrec *keyrec;
-      int rl;
+      log_debug ("unknown value %d for special search callback", special);
+      return 0;
+    }
 
-      maxlen=1024;
-      rl=iobuf_read_line(buffer,&line,&buflen,&maxlen);
+  if (parm->eof_seen && line)
+    {
+      log_debug ("ooops: unexpected data after EOF\n");
+      line = NULL;
+    }
 
-      if(opt.with_colons)
-       {
-         if(!header && ascii_strncasecmp("SEARCH ",line,7)==0
-            && ascii_strncasecmp(" BEGIN",&line[strlen(line)-7],6)==0)
-           {
-             header=1;
-             continue;
-           }
-         else if(ascii_strncasecmp("SEARCH ",line,7)==0
-                 && ascii_strncasecmp(" END",&line[strlen(line)-5],4)==0)
-           continue;
+  /* Print the received line.  */
+  if (opt.with_colons && line)
+    {
+      es_printf ("%s\n", line);
+    }
 
-         printf("%s",line);
-       }
+  /* Look for an info: line.  The only current info: values defined
+     are the version and key count. */
+  if (line && !parm->any_lines && !ascii_strncasecmp ("info:", line, 5))
+    {
+      char *str = line + 5;
+      char *tok;
 
-      /* Look for an info: line.  The only current info: values
-        defined are the version and key count. */
-      if(!started && rl>0 && ascii_strncasecmp("info:",line,5)==0)
-       {
-         char *tok,*str=&line[5];
+      if ((tok = strsep (&str, ":")))
+        {
+          int version;
 
-         if((tok=strsep(&str,":"))!=NULL)
-           {
-             int version;
+          if (sscanf (tok, "%d", &version) !=1 )
+            version = 1;
 
-             if(sscanf(tok,"%d",&version)!=1)
-               version=1;
+          if (version !=1 )
+            {
+              log_error (_("invalid keyserver protocol "
+                           "(us %d!=handler %d)\n"), 1, version);
+              return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+            }
+        }
 
-             if(version!=1)
-               {
-                 log_error(_("invalid keyserver protocol "
-                             "(us %d!=handler %d)\n"),1,version);
-                 break;
-               }
-           }
+      if ((tok = strsep (&str, ":"))
+          && sscanf (tok, "%d", &parm->count) == 1)
+        {
+          if (!parm->count)
+            parm->not_found = 1;/* Server indicated that no items follow.  */
+          else if (parm->count < 0)
+            parm->count = 10;   /* Bad value - assume something reasonable.  */
+          else
+            parm->validcount = 1; /* COUNT seems to be okay.  */
+        }
 
-         if((tok=strsep(&str,":"))!=NULL && sscanf(tok,"%d",&count)==1)
-           {
-             if(count==0)
-               goto notfound;
-             else if(count<0)
-               count=10;
-             else
-               validcount=1;
+      parm->any_lines = 1;
+      return 0; /* Line processing finished.  */
+    }
 
-             desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
-           }
+ again:
+  if (line)
+    keyrec = parse_keyrec (line);
+  else
+    {
+      /* Received EOF - flush data */
+      parm->eof_seen = 1;
+      keyrec = parse_keyrec (NULL);
+      if (!keyrec)
+        {
+          if (!parm->nkeys)
+            parm->not_found = 1;  /* No keys at all.  */
+          else
+            {
+              if (parm->nkeys != parm->count)
+                parm->validcount = 0;
+
+              if (!(opt.with_colons && opt.batch))
+                {
+                  err = show_prompt (parm->ctrl, parm->desc, parm->nkeys,
+                                     parm->validcount? parm->count : 0,
+                                     parm->searchstr_disp);
+                  return err;
+                }
+            }
+        }
+    }
 
-         started=1;
-         continue;
-       }
+  /* Save the key in the key array.  */
+  if (keyrec)
+    {
+      /* Allocate or enlarge the key array if needed.  */
+      if (!parm->desc)
+        {
+          if (parm->count < 1)
+            {
+              parm->count = 10;
+              parm->validcount = 0;
+            }
+          parm->desc = xtrymalloc (parm->count * sizeof *parm->desc);
+          if (!parm->desc)
+            {
+              err = gpg_error_from_syserror ();
+              iobuf_close (keyrec->uidbuf);
+              xfree (keyrec);
+              return err;
+            }
+        }
+      else if (parm->nkeys == parm->count)
+        {
+          /* Keyserver sent more keys than claimed in the info: line. */
+          KEYDB_SEARCH_DESC *tmp;
+          int newcount = parm->count + 10;
 
-      if(rl==0)
-       {
-         keyrec=parse_keyrec(NULL);
+          tmp = xtryrealloc (parm->desc, newcount * sizeof *parm->desc);
+          if (!tmp)
+            {
+              err = gpg_error_from_syserror ();
+              iobuf_close (keyrec->uidbuf);
+              xfree (keyrec);
+              return err;
+            }
+          parm->count = newcount;
+          parm->desc = tmp;
+          parm->validcount = 0;
+        }
 
-         if(keyrec==NULL)
-           {
-             if(i==0)
-               {
-                 count=0;
-                 break;
-               }
+      parm->desc[parm->nkeys] = keyrec->desc;
 
-             if(i!=count)
-               validcount=0;
+      if (!opt.with_colons)
+        {
+          /* SCREEN_LINES - 1 for the prompt. */
+          if (parm->numlines + keyrec->lines > opt.screen_lines - 1)
+            {
+              err = show_prompt (parm->ctrl, parm->desc, parm->nkeys,
+                                 parm->validcount ? parm->count:0,
+                                 parm->searchstr_disp);
+              if (err)
+                return err;
+              parm->numlines = 0;
+            }
 
-              if (opt.with_colons && opt.batch)
-                break;
+          print_keyrec (parm->nkeys+1, keyrec);
+        }
 
-             for(;;)
-               {
-                 if(show_prompt(desc,i,validcount?count:0,localstr))
-                   break;
-                 validcount=0;
-               }
+      parm->numlines += keyrec->lines;
+      iobuf_close (keyrec->uidbuf);
+      xfree (keyrec);
 
-             break;
-           }
-       }
-      else
-       keyrec=parse_keyrec(line);
+      parm->any_lines = 1;
+      parm->nkeys++;
 
-      if(i==count)
-       {
-         /* keyserver helper sent more keys than they claimed in the
-            info: line. */
-         count+=10;
-         desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
-         validcount=0;
-       }
+      /* If we are here due to a flush after the EOF, run again for
+         the last prompt.  Fixme: Make this code better readable. */
+      if (parm->eof_seen)
+        goto again;
+    }
 
-      if(keyrec)
-       {
-         desc[i]=keyrec->desc;
+  return 0;
+}
 
-         if(!opt.with_colons)
-           {
-             /* screen_lines - 1 for the prompt. */
-             if(numlines+keyrec->lines>opt.screen_lines-1)
-               {
-                 if(show_prompt(desc,i,validcount?count:0,localstr))
-                   break;
-                 else
-                   numlines=0;
-               }
 
-             print_keyrec(i+1,keyrec);
-           }
 
-         numlines+=keyrec->lines;
-         iobuf_close(keyrec->uidbuf);
-         xfree(keyrec);
+int
+keyserver_export (ctrl_t ctrl, strlist_t users)
+{
+  gpg_error_t err;
+  strlist_t sl=NULL;
+  KEYDB_SEARCH_DESC desc;
+  int rc=0;
 
-         started=1;
-         i++;
+  /* Weed out descriptors that we don't support sending */
+  for(;users;users=users->next)
+    {
+      err = classify_user_id (users->d, &desc, 1);
+      if (err || (desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && desc.mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && desc.mode != KEYDB_SEARCH_MODE_FPR16
+                  && desc.mode != KEYDB_SEARCH_MODE_FPR20))
+       {
+         log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
+         continue;
        }
+      else
+       append_to_strlist(&sl,users->d);
     }
 
- notfound:
-  /* Leave this commented out or now, and perhaps for a very long
-     time.  All HKPish servers return HTML error messages for
-     no-key-found. */
-  /*
-     if(!started)
-     log_info(_("keyserver does not support searching\n"));
-     else
-  */
-  if(count==0)
+  if(sl)
     {
-      if(localstr)
-       log_info(_("key \"%s\" not found on keyserver\n"),localstr);
-      else
-       log_info(_("key not found on keyserver\n"));
+      rc = keyserver_put (ctrl, sl, opt.keyserver);
+      free_strlist(sl);
     }
 
-  xfree(localstr);
-  xfree(desc);
-  xfree(line);
-}
-
-/* We sometimes want to use a different gpgkeys_xxx for a given
-   protocol (for example, ldaps is handled by gpgkeys_ldap).  Map
-   these here. */
-static const char *
-keyserver_typemap(const char *type)
-{
-  if(strcmp(type,"ldaps")==0)
-    return "ldap";
-  else if(strcmp(type,"hkps")==0)
-    return "hkp";
-  else
-    return type;
-}
-
-/* The PGP LDAP and the curl fetch-a-LDAP-object methodologies are
-   sufficiently different that we can't use curl to do LDAP. */
-static int
-direct_uri_map(const char *scheme,unsigned int is_direct)
-{
-  if(is_direct && strcmp(scheme,"ldap")==0)
-    return 1;
-
-  return 0;
+  return rc;
 }
 
-#if GNUPG_MAJOR_VERSION == 2
-#define GPGKEYS_PREFIX "gpg2keys_"
-#else
-#define GPGKEYS_PREFIX "gpgkeys_"
-#endif
-#define GPGKEYS_CURL GPGKEYS_PREFIX "curl" EXEEXT
-#define GPGKEYS_PREFIX_LEN (strlen(GPGKEYS_CURL))
-#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
-#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
-
 
-/* Structure to convey the arg to keyserver_retrieval_filter.  */
-struct ks_retrieval_filter_arg_s
+/* Structure to convey the arg to keyserver_retrieval_screener.  */
+struct ks_retrieval_screener_arg_s
 {
   KEYDB_SEARCH_DESC *desc;
   int ndesc;
 };
 
 
-/* Check whether a key matches the search description.  The filter
-   returns 0 if the key shall be imported.  Note that this kind of
-   filter is not related to the iobuf filters. */
-static int
-keyserver_retrieval_filter (kbnode_t keyblock, void *opaque)
+/* Check whether a key matches the search description.  The function
+   returns 0 if the key shall be imported.  */
+static gpg_error_t
+keyserver_retrieval_screener (kbnode_t keyblock, void *opaque)
 {
-  struct ks_retrieval_filter_arg_s *arg = opaque;
+  struct ks_retrieval_screener_arg_s *arg = opaque;
   KEYDB_SEARCH_DESC *desc = arg->desc;
   int ndesc = arg->ndesc;
   kbnode_t node;
@@ -1014,7 +1073,7 @@ keyserver_retrieval_filter (kbnode_t keyblock, void *opaque)
      limited checks.  */
   node = find_kbnode (keyblock, PKT_SECRET_KEY);
   if (node)
-    return G10ERR_GENERAL;   /* Do not import. */
+    return gpg_error (GPG_ERR_GENERAL);   /* Do not import. */
 
   if (!ndesc)
     return 0; /* Okay if no description given.  */
@@ -1058,724 +1117,14 @@ keyserver_retrieval_filter (kbnode_t keyblock, void *opaque)
         }
     }
 
-  return G10ERR_GENERAL;
-}
-
-
-static const char *
-keyserver_errstr (int code)
-{
-  const char *s;
-
-  switch (code)
-    {
-    case KEYSERVER_OK:            s = "success"; break;
-    case KEYSERVER_INTERNAL_ERROR:s = "keyserver helper internal error"; break;
-    case KEYSERVER_NOT_SUPPORTED: s =gpg_strerror (GPG_ERR_NOT_SUPPORTED);break;
-    case KEYSERVER_VERSION_ERROR: s = "keyserver helper version mismatch";break;
-    case KEYSERVER_GENERAL_ERROR: s = "keyserver helper general error"; break;
-    case KEYSERVER_NO_MEMORY:     s = "keyserver helper is out of core"; break;
-    case KEYSERVER_KEY_NOT_FOUND: s =gpg_strerror (GPG_ERR_NOT_FOUND); break;
-    case KEYSERVER_KEY_EXISTS:    s = "key exists"; break;
-    case KEYSERVER_KEY_INCOMPLETE:s = "key incomplete (EOF)"; break;
-    case KEYSERVER_UNREACHABLE:   s =gpg_strerror (GPG_ERR_UNKNOWN_HOST);break;
-    case KEYSERVER_TIMEOUT:       s =gpg_strerror (GPG_ERR_TIMEOUT); break;
-    default:                      s = "?"; break;
-    }
-  return s;
-}
-
-
-static int
-keyserver_spawn (enum ks_action action, strlist_t list, KEYDB_SEARCH_DESC *desc,
-                 int count, int *prog, unsigned char **fpr, size_t *fpr_len,
-                 struct keyserver_spec *keyserver)
-{
-  int ret=0,i,gotversion=0,outofband=0;
-  strlist_t temp;
-  unsigned int maxlen,buflen;
-  char *command,*end,*searchstr=NULL;
-  byte *line=NULL;
-  struct exec_info *spawn;
-  const char *scheme;
-  const char *libexecdir = gnupg_libexecdir ();
-
-  assert(keyserver);
-
-#ifdef EXEC_TEMPFILE_ONLY
-  opt.keyserver_options.options|=KEYSERVER_USE_TEMP_FILES;
-#endif
-
-  /* Build the filename for the helper to execute */
-  scheme=keyserver_typemap(keyserver->scheme);
-
-#ifdef DISABLE_KEYSERVER_PATH
-  /* Destroy any path we might have.  This is a little tricky,
-     portability-wise.  It's not correct to delete the PATH
-     environment variable, as that may fall back to a system built-in
-     PATH.  Similarly, it is not correct to set PATH to the null
-     string (PATH="") since this actually deletes the PATH environment
-     variable under MinGW.  The safest thing to do here is to force
-     PATH to be GNUPG_LIBEXECDIR.  All this is not that meaningful on
-     Unix-like systems (since we're going to give a full path to
-     gpgkeys_foo), but on W32 it prevents loading any DLLs from
-     directories in %PATH%.
-
-     After some more thinking about this we came to the conclusion
-     that it is better to load the helpers from the directory where
-     the program of this process lives.  Fortunately Windows provides
-     a way to retrieve this and our gnupg_libexecdir function has been
-     modified to return just this.  Setting the exec-path is not
-     anymore required.
-       set_exec_path(libexecdir);
- */
-#else
-  if(opt.exec_path_set)
-    {
-      /* If exec-path was set, and DISABLE_KEYSERVER_PATH is
-        undefined, then don't specify a full path to gpgkeys_foo, so
-        that the PATH can work. */
-      command=xmalloc(GPGKEYS_PREFIX_LEN+strlen(scheme)+3+strlen(EXEEXT)+1);
-      command[0]='\0';
-    }
-  else
-#endif
-    {
-      /* Specify a full path to gpgkeys_foo. */
-      command=xmalloc(strlen(libexecdir)+strlen(DIRSEP_S)+
-                     GPGKEYS_PREFIX_LEN+strlen(scheme)+3+strlen(EXEEXT)+1);
-      strcpy(command,libexecdir);
-      strcat(command,DIRSEP_S);
-    }
-
-  end=command+strlen(command);
-
-  /* Build a path for the keyserver helper.  If it is direct_uri
-     (i.e. an object fetch and not a keyserver), then add "_uri" to
-     the end to distinguish the keyserver helper from an object
-     fetcher that can speak that protocol (this is a problem for
-     LDAP). */
-
-  strcat(command,GPGKEYS_PREFIX);
-  strcat(command,scheme);
-
-  /* This "_uri" thing is in case we need to call a direct handler
-     instead of the keyserver handler.  This lets us use gpgkeys_curl
-     or gpgkeys_ldap_uri (we don't provide it, but a user might)
-     instead of gpgkeys_ldap to fetch things like
-     ldap://keyserver.pgp.com/o=PGP%20keys?pgpkey?sub?pgpkeyid=99242560 */
-
-  if(direct_uri_map(scheme,keyserver->flags.direct_uri))
-    strcat(command,"_uri");
-
-  strcat(command,EXEEXT);
-
-  /* Can we execute it?  If not, try curl as our catchall. */
-  if(path_access(command,X_OK)!=0)
-    strcpy(end,GPGKEYS_CURL);
-
-  if(opt.keyserver_options.options&KEYSERVER_USE_TEMP_FILES)
-    {
-      if(opt.keyserver_options.options&KEYSERVER_KEEP_TEMP_FILES)
-       {
-         command=xrealloc(command,strlen(command)+
-                           strlen(KEYSERVER_ARGS_KEEP)+1);
-         strcat(command,KEYSERVER_ARGS_KEEP);
-       }
-      else
-       {
-         command=xrealloc(command,strlen(command)+
-                           strlen(KEYSERVER_ARGS_NOKEEP)+1);
-         strcat(command,KEYSERVER_ARGS_NOKEEP);
-       }
-
-      ret=exec_write(&spawn,NULL,command,NULL,0,0);
-    }
-  else
-    ret=exec_write(&spawn,command,NULL,NULL,0,0);
-
-  xfree(command);
-
-  if(ret)
-    return ret;
-
-  fprintf(spawn->tochild,
-         "# This is a GnuPG %s keyserver communications file\n",VERSION);
-  fprintf(spawn->tochild,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
-  fprintf(spawn->tochild,"PROGRAM %s\n",VERSION);
-  fprintf(spawn->tochild,"SCHEME %s\n",keyserver->scheme);
-
-  if(keyserver->opaque)
-    fprintf(spawn->tochild,"OPAQUE %s\n",keyserver->opaque);
-  else
-    {
-      if(keyserver->auth)
-       fprintf(spawn->tochild,"AUTH %s\n",keyserver->auth);
-
-      if(keyserver->host)
-       fprintf(spawn->tochild,"HOST %s\n",keyserver->host);
-
-      if(keyserver->port)
-       fprintf(spawn->tochild,"PORT %s\n",keyserver->port);
-
-      if(keyserver->path)
-       fprintf(spawn->tochild,"PATH %s\n",keyserver->path);
-    }
-
-  /* Write global options */
-
-  for(temp=opt.keyserver_options.other;temp;temp=temp->next)
-    fprintf(spawn->tochild,"OPTION %s\n",temp->d);
-
-  /* Write per-keyserver options */
-
-  for(temp=keyserver->options;temp;temp=temp->next)
-    fprintf(spawn->tochild,"OPTION %s\n",temp->d);
-
-  switch(action)
-    {
-    case KS_GET:
-      {
-       fprintf(spawn->tochild,"COMMAND GET\n\n");
-
-       /* Which keys do we want? */
-
-       for(i=0;i<count;i++)
-         {
-           int quiet=0;
-
-           if(desc[i].mode==KEYDB_SEARCH_MODE_FPR20)
-             {
-               int f;
-
-               fprintf(spawn->tochild,"0x");
-
-               for(f=0;f<MAX_FINGERPRINT_LEN;f++)
-                 fprintf(spawn->tochild,"%02X",desc[i].u.fpr[f]);
-
-               fprintf(spawn->tochild,"\n");
-             }
-           else if(desc[i].mode==KEYDB_SEARCH_MODE_FPR16)
-             {
-               int f;
-
-               fprintf(spawn->tochild,"0x");
-
-               for(f=0;f<16;f++)
-                 fprintf(spawn->tochild,"%02X",desc[i].u.fpr[f]);
-
-               fprintf(spawn->tochild,"\n");
-             }
-           else if(desc[i].mode==KEYDB_SEARCH_MODE_LONG_KID)
-             fprintf(spawn->tochild,"0x%08lX%08lX\n",
-                     (ulong)desc[i].u.kid[0],
-                     (ulong)desc[i].u.kid[1]);
-           else if(desc[i].mode==KEYDB_SEARCH_MODE_SHORT_KID)
-             fprintf(spawn->tochild,"0x%08lX\n",
-                     (ulong)desc[i].u.kid[1]);
-           else if(desc[i].mode==KEYDB_SEARCH_MODE_EXACT)
-             {
-               fprintf(spawn->tochild,"0x0000000000000000\n");
-               quiet=1;
-             }
-           else if(desc[i].mode==KEYDB_SEARCH_MODE_NONE)
-             continue;
-           else
-             BUG();
-
-           if(!quiet)
-             {
-               if(keyserver->host)
-                 log_info(_("requesting key %s from %s server %s\n"),
-                          keystr_from_desc(&desc[i]),
-                          keyserver->scheme,keyserver->host);
-               else
-                 log_info(_("requesting key %s from %s\n"),
-                          keystr_from_desc(&desc[i]),keyserver->uri);
-             }
-         }
-
-       fprintf(spawn->tochild,"\n");
-
-       break;
-      }
-
-    case KS_GETNAME:
-      {
-       strlist_t key;
-
-       fprintf(spawn->tochild,"COMMAND GETNAME\n\n");
-
-       /* Which names do we want? */
-
-       for(key=list;key!=NULL;key=key->next)
-         fprintf(spawn->tochild,"%s\n",key->d);
-
-       fprintf(spawn->tochild,"\n");
-
-       if(keyserver->host)
-         log_info(_("searching for names from %s server %s\n"),
-                  keyserver->scheme,keyserver->host);
-       else
-         log_info(_("searching for names from %s\n"),keyserver->uri);
-
-       break;
-      }
-
-    case KS_SEND:
-      {
-       strlist_t key;
-
-       /* Note the extra \n here to send an empty keylist block */
-       fprintf(spawn->tochild,"COMMAND SEND\n\n\n");
-
-       for(key=list;key!=NULL;key=key->next)
-         {
-           armor_filter_context_t *afx;
-           IOBUF buffer = iobuf_temp ();
-           KBNODE block;
-
-           temp=NULL;
-           add_to_strlist(&temp,key->d);
-
-           afx = new_armor_context ();
-           afx->what = 1;
-           /* Tell the armor filter to use Unix-style \n line
-              endings, since we're going to fprintf this to a file
-              that (on Win32) is open in text mode.  The win32 stdio
-              will transform the \n to \r\n and we'll end up with the
-              proper line endings on win32.  This is a no-op on
-              Unix. */
-           afx->eol[0] = '\n';
-           push_armor_filter (afx, buffer);
-            release_armor_context (afx);
-
-           /* TODO: Remove Comment: lines from keys exported this
-              way? */
-
-           if(export_pubkeys_stream(buffer,temp,&block,
-                                    opt.keyserver_options.export_options)==-1)
-             iobuf_close(buffer);
-           else
-             {
-               KBNODE node;
-
-               iobuf_flush_temp(buffer);
-
-               merge_keys_and_selfsig(block);
-
-               fprintf(spawn->tochild,"INFO %08lX%08lX BEGIN\n",
-                       (ulong)block->pkt->pkt.public_key->keyid[0],
-                       (ulong)block->pkt->pkt.public_key->keyid[1]);
-
-               for(node=block;node;node=node->next)
-                 {
-                   switch(node->pkt->pkttype)
-                     {
-                     default:
-                       continue;
-
-                     case PKT_PUBLIC_KEY:
-                     case PKT_PUBLIC_SUBKEY:
-                       {
-                         PKT_public_key *pk=node->pkt->pkt.public_key;
-
-                         keyid_from_pk(pk,NULL);
-
-                         fprintf(spawn->tochild,"%sb:%08lX%08lX:%u:%u:%u:%u:",
-                                 node->pkt->pkttype==PKT_PUBLIC_KEY?"pu":"su",
-                                 (ulong)pk->keyid[0],(ulong)pk->keyid[1],
-                                 pk->pubkey_algo,
-                                 nbits_from_pk(pk),
-                                 pk->timestamp,
-                                 pk->expiredate);
-
-                         if(pk->is_revoked)
-                           fprintf(spawn->tochild,"r");
-                         if(pk->has_expired)
-                           fprintf(spawn->tochild,"e");
-
-                         fprintf(spawn->tochild,"\n");
-                       }
-                       break;
-
-                     case PKT_USER_ID:
-                       {
-                         PKT_user_id *uid=node->pkt->pkt.user_id;
-                         int r;
-
-                         if(uid->attrib_data)
-                           continue;
-
-                         fprintf(spawn->tochild,"uid:");
-
-                         /* Quote ':', '%', and any 8-bit
-                            characters */
-                         for(r=0;r<uid->len;r++)
-                           {
-                             if(uid->name[r]==':' || uid->name[r]=='%'
-                                || uid->name[r]&0x80)
-                               fprintf(spawn->tochild,"%%%02X",
-                                       (byte)uid->name[r]);
-                             else
-                               fprintf(spawn->tochild,"%c",uid->name[r]);
-                           }
-
-                         fprintf(spawn->tochild,":%u:%u:",
-                                 uid->created,uid->expiredate);
-
-                         if(uid->is_revoked)
-                           fprintf(spawn->tochild,"r");
-                         if(uid->is_expired)
-                           fprintf(spawn->tochild,"e");
-
-                         fprintf(spawn->tochild,"\n");
-                       }
-                       break;
-
-                       /* This bit is really for the benefit of
-                          people who store their keys in LDAP
-                          servers.  It makes it easy to do queries
-                          for things like "all keys signed by
-                          Isabella". */
-                     case PKT_SIGNATURE:
-                       {
-                         PKT_signature *sig=node->pkt->pkt.signature;
-
-                         if(!IS_UID_SIG(sig))
-                           continue;
-
-                         fprintf(spawn->tochild,"sig:%08lX%08lX:%X:%u:%u\n",
-                                 (ulong)sig->keyid[0],(ulong)sig->keyid[1],
-                                 sig->sig_class,sig->timestamp,
-                                 sig->expiredate);
-                       }
-                       break;
-                     }
-                 }
-
-               fprintf(spawn->tochild,"INFO %08lX%08lX END\n",
-                       (ulong)block->pkt->pkt.public_key->keyid[0],
-                       (ulong)block->pkt->pkt.public_key->keyid[1]);
-
-               fprintf(spawn->tochild,"KEY %08lX%08lX BEGIN\n",
-                       (ulong)block->pkt->pkt.public_key->keyid[0],
-                       (ulong)block->pkt->pkt.public_key->keyid[1]);
-               fwrite(iobuf_get_temp_buffer(buffer),
-                      iobuf_get_temp_length(buffer),1,spawn->tochild);
-               fprintf(spawn->tochild,"KEY %08lX%08lX END\n",
-                       (ulong)block->pkt->pkt.public_key->keyid[0],
-                       (ulong)block->pkt->pkt.public_key->keyid[1]);
-
-               iobuf_close(buffer);
-
-               if(keyserver->host)
-                 log_info(_("sending key %s to %s server %s\n"),
-                          keystr(block->pkt->pkt.public_key->keyid),
-                          keyserver->scheme,keyserver->host);
-               else
-                 log_info(_("sending key %s to %s\n"),
-                          keystr(block->pkt->pkt.public_key->keyid),
-                          keyserver->uri);
-
-               release_kbnode(block);
-             }
-
-           free_strlist(temp);
-         }
-
-       break;
-      }
-
-    case KS_SEARCH:
-      {
-       strlist_t key;
-
-       fprintf(spawn->tochild,"COMMAND SEARCH\n\n");
-
-       /* Which keys do we want?  Remember that the gpgkeys_ program
-           is going to lump these together into a search string. */
-
-       for(key=list;key!=NULL;key=key->next)
-         {
-           fprintf(spawn->tochild,"%s\n",key->d);
-           if(key!=list)
-             {
-               searchstr=xrealloc(searchstr,
-                                   strlen(searchstr)+strlen(key->d)+2);
-               strcat(searchstr," ");
-             }
-           else
-             {
-               searchstr=xmalloc(strlen(key->d)+1);
-               searchstr[0]='\0';
-             }
-
-           strcat(searchstr,key->d);
-         }
-
-       fprintf(spawn->tochild,"\n");
-
-       if(keyserver->host)
-         log_info(_("searching for \"%s\" from %s server %s\n"),
-                  searchstr,keyserver->scheme,keyserver->host);
-       else
-         log_info(_("searching for \"%s\" from %s\n"),
-                  searchstr,keyserver->uri);
-
-       break;
-      }
-
-    default:
-      log_fatal(_("no keyserver action!\n"));
-      break;
-    }
-
-  /* Done sending, so start reading. */
-  ret=exec_read(spawn);
-  if(ret)
-    goto fail;
-
-  /* Now handle the response */
-
-  for(;;)
-    {
-      int plen;
-      char *ptr;
-
-      maxlen=1024;
-      if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0)
-       {
-         ret = gpg_error_from_syserror ();
-         goto fail; /* i.e. EOF */
-       }
-
-      ptr=line;
-
-      /* remove trailing whitespace */
-      plen=strlen(ptr);
-      while(plen>0 && ascii_isspace(ptr[plen-1]))
-       plen--;
-      plen[ptr]='\0';
-
-      /* Stop at the first empty line but not if we are sending keys.
-         In the latter case we won't continue reading later and thus
-         we need to watch out for errors right in this loop.  */
-      if(*ptr=='\0' && action != KS_SEND)
-        break;
-
-      if(ascii_strncasecmp(ptr,"VERSION ",8)==0)
-       {
-         gotversion=1;
-
-         if(atoi(&ptr[8])!=KEYSERVER_PROTO_VERSION)
-           {
-             log_error(_("invalid keyserver protocol (us %d!=handler %d)\n"),
-                       KEYSERVER_PROTO_VERSION,atoi(&ptr[8]));
-             goto fail;
-           }
-       }
-      else if(ascii_strncasecmp(ptr,"PROGRAM ",8)==0)
-       {
-         if(ascii_strncasecmp(&ptr[8],VERSION,strlen(VERSION))!=0)
-           log_info(_("WARNING: keyserver handler from a different"
-                      " version of GnuPG (%s)\n"),&ptr[8]);
-       }
-      else if(ascii_strncasecmp(ptr,"OPTION OUTOFBAND",16)==0)
-       outofband=1; /* Currently the only OPTION */
-      else if (action == KS_SEND
-               && ascii_strncasecmp(ptr,"KEY ",4)==0)
-        {
-          ret = parse_key_failed_line (ptr+4, strlen (ptr+4));
-          break;  /* We stop at the first KEY line so that we won't
-                     run into an EOF which would return an unspecified
-                     error message (due to iobuf_read_line).  */
-        }
-    }
-
-  if(!gotversion)
-    {
-      log_error(_("keyserver did not send VERSION\n"));
-      goto fail;
-    }
-
-  if(!outofband)
-    switch(action)
-      {
-      case KS_GET:
-      case KS_GETNAME:
-       {
-         void *stats_handle;
-          struct ks_retrieval_filter_arg_s filterarg;
-          int gpgkeys_err;
-
-         stats_handle=import_new_stats_handle();
-
-         /* Slurp up all the key data.  In the future, it might be
-            nice to look for KEY foo OUTOFBAND and FAILED indicators.
-            It's harmless to ignore them, but ignoring them does make
-            gpg complain about "no valid OpenPGP data found".  One
-            way to do this could be to continue parsing this
-            line-by-line and make a temp iobuf for each key.  Note
-            that we don't allow the import of secret keys from a
-            keyserver.  Keyservers should never accept or send them
-            but we better protect against rogue keyservers. */
-          filterarg.desc = desc;
-          filterarg.ndesc = count;
-          gpgkeys_err = 0;
-         import_keys_stream (spawn->fromchild, stats_handle, fpr, fpr_len,
-                             (opt.keyserver_options.import_options
-                              | IMPORT_NO_SECKEY),
-                              keyserver_retrieval_filter, &filterarg,
-                              &gpgkeys_err);
-
-         import_print_stats(stats_handle);
-         import_release_stats_handle(stats_handle);
-          if (gpgkeys_err)
-            {
-              log_error (_("keyserver communications error: %s\n"),
-                         keyserver_errstr (gpgkeys_err));
-              ret = gpgkeys_err;
-            }
-         break;
-       }
-
-       /* Nothing to do here */
-      case KS_SEND:
-       break;
-
-      case KS_SEARCH:
-       keyserver_search_prompt(spawn->fromchild,searchstr);
-       break;
-
-      default:
-       log_fatal(_("no keyserver action!\n"));
-       break;
-      }
-
- fail:
-  xfree(line);
-  xfree(searchstr);
-
-  *prog=exec_finish(spawn);
-
-  return ret;
-}
-
-
-static int
-keyserver_work (enum ks_action action, strlist_t list, KEYDB_SEARCH_DESC *desc,
-                int count, unsigned char **fpr, size_t *fpr_len,
-                struct keyserver_spec *keyserver)
-{
-  int rc = 0;
-  int ret = 0;
-
-  if(!keyserver)
-    {
-      log_error(_("no keyserver known (use option --keyserver)\n"));
-      return G10ERR_BAD_URI;
-    }
-
-#ifdef DISABLE_KEYSERVER_HELPERS
-
-  log_error(_("external keyserver calls are not supported in this build\n"));
-  return G10ERR_KEYSERVER;
-
-#else
-  /* Spawn a handler.  The use of RC and RET is a mess.  We use a
-     kludge to return a suitable error message.  */
-  rc=keyserver_spawn(action,list,desc,count,&ret,fpr,fpr_len,keyserver);
-  if (ret == KEYSERVER_INTERNAL_ERROR && rc)
-    ret = rc;
-  if(ret)
-    {
-      switch(ret)
-       {
-       case KEYSERVER_SCHEME_NOT_FOUND:
-         log_error(_("no handler for keyserver scheme `%s'\n"),
-                   keyserver->scheme);
-         break;
-
-       case KEYSERVER_NOT_SUPPORTED:
-         log_error(_("action `%s' not supported with keyserver "
-                     "scheme `%s'\n"),
-                   action==KS_GET?"get":action==KS_SEND?"send":
-                   action==KS_SEARCH?"search":"unknown",
-                   keyserver->scheme);
-         break;
-
-       case KEYSERVER_VERSION_ERROR:
-         log_error(_(GPGKEYS_PREFIX "%s does not support"
-                     " handler version %d\n"),
-                   keyserver_typemap(keyserver->scheme),
-                   KEYSERVER_PROTO_VERSION);
-         break;
-
-       case KEYSERVER_TIMEOUT:
-         log_error(_("keyserver timed out\n"));
-         break;
-
-        case KEYSERVER_UNREACHABLE:
-          return gpg_error (GPG_ERR_UNKNOWN_HOST);
-
-       case KEYSERVER_INTERNAL_ERROR:
-       default:
-         log_error(_("keyserver internal error\n"));
-         break;
-       }
-
-      return G10ERR_KEYSERVER;
-    }
-
-  if(rc)
-    {
-      log_error(_("keyserver communications error: %s\n"),g10_errstr(rc));
-
-      return rc;
-    }
-
-  return 0;
-#endif /* ! DISABLE_KEYSERVER_HELPERS*/
-}
-
-
-int
-keyserver_export(strlist_t users)
-{
-  strlist_t sl=NULL;
-  KEYDB_SEARCH_DESC desc;
-  int rc=0;
-
-  /* Weed out descriptors that we don't support sending */
-  for(;users;users=users->next)
-    {
-      classify_user_id (users->d, &desc);
-      if(desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
-        desc.mode!=KEYDB_SEARCH_MODE_LONG_KID &&
-        desc.mode!=KEYDB_SEARCH_MODE_FPR16 &&
-        desc.mode!=KEYDB_SEARCH_MODE_FPR20)
-       {
-         log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
-         continue;
-       }
-      else
-       append_to_strlist(&sl,users->d);
-    }
-
-  if(sl)
-    {
-      rc=keyserver_work(KS_SEND,sl,NULL,0,NULL,NULL,opt.keyserver);
-      free_strlist(sl);
-    }
-
-  return rc;
+  return gpg_error (GPG_ERR_GENERAL);
 }
 
 
 int
-keyserver_import(strlist_t users)
+keyserver_import (ctrl_t ctrl, strlist_t users)
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC *desc;
   int num=100,count=0;
   int rc=0;
@@ -1785,13 +1134,13 @@ keyserver_import(strlist_t users)
 
   for(;users;users=users->next)
     {
-      classify_user_id (users->d, &desc[count]);
-      if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
-        desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID &&
-        desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 &&
-        desc[count].mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (users->d, &desc[count], 1);
+      if (err || (desc[count].mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && desc[count].mode != KEYDB_SEARCH_MODE_FPR16
+                  && desc[count].mode != KEYDB_SEARCH_MODE_FPR20))
        {
-         log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
+         log_error (_("\"%s\" not a key ID: skipping\n"), users->d);
          continue;
        }
 
@@ -1804,16 +1153,34 @@ keyserver_import(strlist_t users)
     }
 
   if(count>0)
-    rc=keyserver_work(KS_GET,NULL,desc,count,NULL,NULL,opt.keyserver);
+    rc=keyserver_get (ctrl, desc, count, NULL, NULL, NULL);
 
   xfree(desc);
 
   return rc;
 }
 
+
+/* Import all keys that exactly match NAME */
 int
-keyserver_import_fprint(const byte *fprint,size_t fprint_len,
-                       struct keyserver_spec *keyserver)
+keyserver_import_name (ctrl_t ctrl, const char *name,
+                       unsigned char **fpr, size_t *fprlen,
+                       struct keyserver_spec *keyserver)
+{
+  KEYDB_SEARCH_DESC desc;
+
+  memset (&desc, 0, sizeof desc);
+
+  desc.mode = KEYDB_SEARCH_MODE_EXACT;
+  desc.u.name = name;
+
+  return keyserver_get (ctrl, &desc, 1, keyserver, fpr, fprlen);
+}
+
+
+int
+keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
+                        struct keyserver_spec *keyserver)
 {
   KEYDB_SEARCH_DESC desc;
 
@@ -1830,11 +1197,12 @@ keyserver_import_fprint(const byte *fprint,size_t fprint_len,
 
   /* TODO: Warn here if the fingerprint we got doesn't match the one
      we asked for? */
-  return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver);
+  return keyserver_get (ctrl, &desc, 1, keyserver, NULL, NULL);
 }
 
 int
-keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver)
+keyserver_import_keyid (ctrl_t ctrl,
+                        u32 *keyid,struct keyserver_spec *keyserver)
 {
   KEYDB_SEARCH_DESC desc;
 
@@ -1844,17 +1212,14 @@ keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver)
   desc.u.kid[0]=keyid[0];
   desc.u.kid[1]=keyid[1];
 
-  return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver);
+  return keyserver_get (ctrl, &desc,1, keyserver, NULL, NULL);
 }
 
-
-/* Code mostly stolen from do_export_stream */
+/* code mostly stolen from do_export_stream */
 static int
 keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
 {
-  int rc = 0;
-  int num = 100;
-  int ndesc;
+  int rc=0,ndesc,num=100;
   KBNODE keyblock=NULL,node;
   KEYDB_HANDLE kdbhd;
   KEYDB_SEARCH_DESC *desc;
@@ -1864,7 +1229,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
 
   *klist=xmalloc(sizeof(KEYDB_SEARCH_DESC)*num);
 
-  kdbhd=keydb_new(0);
+  kdbhd=keydb_new ();
 
   if(!users)
     {
@@ -1880,15 +1245,16 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
 
       for (ndesc=0, sl=users; sl; sl = sl->next)
        {
-         if(classify_user_id (sl->d, desc+ndesc))
+          gpg_error_t err;
+         if (!(err = classify_user_id (sl->d, desc+ndesc, 1)))
            ndesc++;
          else
            log_error (_("key \"%s\" not found: %s\n"),
-                      sl->d, g10_errstr (G10ERR_INV_USER_ID));
+                      sl->d, gpg_strerror (err));
        }
     }
 
-  while (!(rc = keydb_search (kdbhd, desc, ndesc)))
+  while (!(rc = keydb_search (kdbhd, desc, ndesc, NULL)))
     {
       if (!users)
        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
@@ -1991,8 +1357,8 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
        }
     }
 
-  if(rc==-1)
-    rc=0;
+  if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
+    rc = 0;
 
  leave:
   if(rc)
@@ -2008,7 +1374,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
    usernames to refresh only part of the keyring. */
 
 int
-keyserver_refresh(strlist_t users)
+keyserver_refresh (ctrl_t ctrl, strlist_t users)
 {
   int rc,count,numdesc,fakev3=0;
   KEYDB_SEARCH_DESC *desc;
@@ -2050,8 +1416,7 @@ keyserver_refresh(strlist_t users)
              /* We use the keyserver structure we parsed out before.
                 Note that a preferred keyserver without a scheme://
                 will be interpreted as hkp:// */
-
-             rc=keyserver_work(KS_GET,NULL,&desc[i],1,NULL,NULL,keyserver);
+             rc = keyserver_get (ctrl, &desc[i], 1, keyserver, NULL, NULL);
              if(rc)
                log_info(_("WARNING: unable to refresh key %s"
                           " via %s: %s\n"),keystr_from_desc(&desc[i]),
@@ -2081,7 +1446,7 @@ keyserver_refresh(strlist_t users)
                     count,opt.keyserver->uri);
        }
 
-      rc=keyserver_work(KS_GET,NULL,desc,numdesc,NULL,NULL,opt.keyserver);
+      rc=keyserver_get (ctrl, desc, numdesc, NULL, NULL, NULL);
     }
 
   xfree(desc);
@@ -2091,74 +1456,378 @@ keyserver_refresh(strlist_t users)
   /* If the original options didn't have fast import, and the trustdb
      is dirty, rebuild. */
   if(!(opt.keyserver_options.import_options&IMPORT_FAST))
-    trustdb_check_or_update();
+    check_or_update_trustdb ();
 
   return rc;
 }
 
-int
-keyserver_search(strlist_t tokens)
+
+/* Search for keys on the keyservers.  The patterns are given in the
+   string list TOKENS.  */
+gpg_error_t
+keyserver_search (ctrl_t ctrl, strlist_t tokens)
 {
-  if(tokens)
-    return keyserver_work(KS_SEARCH,tokens,NULL,0,NULL,NULL,opt.keyserver);
-  else
-    return 0;
+  gpg_error_t err;
+  char *searchstr;
+  struct search_line_handler_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+
+  if (!tokens)
+    return 0;  /* Return success if no patterns are given.  */
+
+  if (!opt.keyserver)
+    {
+      log_error (_("no keyserver known (use option --keyserver)\n"));
+      return gpg_error (GPG_ERR_NO_KEYSERVER);
+    }
+
+  /* Write global options */
+
+  /* for(temp=opt.keyserver_options.other;temp;temp=temp->next) */
+  /*   fprintf(spawn->tochild,"OPTION %s\n",temp->d); */
+
+  /* Write per-keyserver options */
+
+  /* for(temp=keyserver->options;temp;temp=temp->next) */
+  /*   fprintf(spawn->tochild,"OPTION %s\n",temp->d); */
+
+  {
+    membuf_t mb;
+    strlist_t item;
+
+    init_membuf (&mb, 1024);
+    for (item = tokens; item; item = item->next)
+    {
+      if (item != tokens)
+        put_membuf (&mb, " ", 1);
+      put_membuf_str (&mb, item->d);
+    }
+    put_membuf (&mb, "", 1); /* Append Nul.  */
+    searchstr = get_membuf (&mb, NULL);
+    if (!searchstr)
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+  }
+  /* FIXME: Enable the next line */
+  /* log_info (_("searching for \"%s\" from %s\n"), searchstr, keyserver->uri); */
+
+  parm.ctrl = ctrl;
+  if (searchstr)
+    parm.searchstr_disp = utf8_to_native (searchstr, strlen (searchstr), 0);
+
+  err = gpg_dirmngr_ks_search (ctrl, searchstr, search_line_handler, &parm);
+
+  if (parm.not_found)
+    {
+      if (parm.searchstr_disp)
+        log_info (_("key \"%s\" not found on keyserver\n"),
+                  parm.searchstr_disp);
+      else
+        log_info (_("key not found on keyserver\n"));
+    }
+
+  if (gpg_err_code (err) == GPG_ERR_NO_KEYSERVER)
+    log_error (_("no keyserver known (use option --keyserver)\n"));
+  else if (err)
+    log_error ("error searching keyserver: %s\n", gpg_strerror (err));
+
+  /* switch(ret) */
+  /*   { */
+  /*   case KEYSERVER_SCHEME_NOT_FOUND: */
+  /*     log_error(_("no handler for keyserver scheme '%s'\n"), */
+  /*               opt.keyserver->scheme); */
+  /*     break; */
+
+  /*   case KEYSERVER_NOT_SUPPORTED: */
+  /*     log_error(_("action '%s' not supported with keyserver " */
+  /*                 "scheme '%s'\n"), "search", opt.keyserver->scheme); */
+  /*     break; */
+
+  /*   case KEYSERVER_TIMEOUT: */
+  /*     log_error(_("keyserver timed out\n")); */
+  /*     break; */
+
+  /*   case KEYSERVER_INTERNAL_ERROR: */
+  /*   default: */
+  /*     log_error(_("keyserver internal error\n")); */
+  /*     break; */
+  /*   } */
+
+  /* return gpg_error (GPG_ERR_KEYSERVER); */
+
+
+ leave:
+  xfree (parm.desc);
+  xfree (parm.searchstr_disp);
+  xfree(searchstr);
+
+  return err;
 }
 
+
+
+/* Retrieve a key from a keyserver.  The search pattern are in
+   (DESC,NDESC).  Allowed search modes are keyid, fingerprint, and
+   exact searches.  KEYSERVER gives an optional override keyserver. If
+   (R_FPR,R_FPRLEN) are not NULL, the may retrun the fingerprint of
+   one imported key.  */
+static gpg_error_t
+keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
+               struct keyserver_spec *keyserver,
+               unsigned char **r_fpr, size_t *r_fprlen)
+
+{
+  gpg_error_t err = 0;
+  char **pattern;
+  int idx, npat;
+  estream_t datastream;
+  char *source = NULL;
+
+  /* Create an array filled with a search pattern for each key.  The
+     array is delimited by a NULL entry.  */
+  pattern = xtrycalloc (ndesc+1, sizeof *pattern);
+  if (!pattern)
+    return gpg_error_from_syserror ();
+  for (npat=idx=0; idx < ndesc; idx++)
+    {
+      int quiet = 0;
+
+      if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20
+          || desc[idx].mode == KEYDB_SEARCH_MODE_FPR16)
+        {
+          pattern[npat] = xtrymalloc (2+2*20+1);
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            {
+              strcpy (pattern[npat], "0x");
+              bin2hex (desc[idx].u.fpr,
+                       desc[idx].mode == KEYDB_SEARCH_MODE_FPR20? 20 : 16,
+                       pattern[npat]+2);
+              npat++;
+            }
+        }
+      else if(desc[idx].mode == KEYDB_SEARCH_MODE_LONG_KID)
+        {
+          pattern[npat] = xtryasprintf ("0x%08lX%08lX",
+                                        (ulong)desc[idx].u.kid[0],
+                                        (ulong)desc[idx].u.kid[1]);
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            npat++;
+        }
+      else if(desc[idx].mode == KEYDB_SEARCH_MODE_SHORT_KID)
+        {
+          pattern[npat] = xtryasprintf ("0x%08lX", (ulong)desc[idx].u.kid[1]);
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            npat++;
+        }
+      else if(desc[idx].mode == KEYDB_SEARCH_MODE_EXACT)
+        {
+          /* The Dirmngr uses also classify_user_id to detect the type
+             of the search string.  By adding the '=' prefix we force
+             Dirmngr's KS_GET to consider this an exact search string.
+             (In gpg 1.4 and gpg 2.0 the keyserver helpers used the
+             KS_GETNAME command to indicate this.)  */
+          pattern[npat] = strconcat ("=", desc[idx].u.name, NULL);
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            {
+              npat++;
+              quiet = 1;
+            }
+        }
+      else if (desc[idx].mode == KEYDB_SEARCH_MODE_NONE)
+        continue;
+      else
+        BUG();
+
+      if (err)
+        {
+          for (idx=0; idx < npat; idx++)
+            xfree (pattern[idx]);
+          xfree (pattern);
+          return err;
+        }
+
+      if (!quiet && keyserver)
+        {
+          if (keyserver->host)
+            log_info (_("requesting key %s from %s server %s\n"),
+                      keystr_from_desc (&desc[idx]),
+                      keyserver->scheme, keyserver->host);
+          else
+            log_info (_("requesting key %s from %s\n"),
+                      keystr_from_desc (&desc[idx]), keyserver->uri);
+        }
+    }
+
+
+  err = gpg_dirmngr_ks_get (ctrl, pattern, &datastream, &source);
+  for (idx=0; idx < npat; idx++)
+    xfree (pattern[idx]);
+  xfree (pattern);
+  if (opt.verbose && source)
+    log_info ("data source: %s\n", source);
+
+  if (!err)
+    {
+      void *stats_handle;
+      struct ks_retrieval_screener_arg_s screenerarg;
+
+      stats_handle = import_new_stats_handle();
+
+      /* FIXME: Check whether this comment should be moved to dirmngr.
+
+         Slurp up all the key data.  In the future, it might be nice
+         to look for KEY foo OUTOFBAND and FAILED indicators.  It's
+         harmless to ignore them, but ignoring them does make gpg
+         complain about "no valid OpenPGP data found".  One way to do
+         this could be to continue parsing this line-by-line and make
+         a temp iobuf for each key.  Note that we don't allow the
+         import of secret keys from a keyserver.  Keyservers should
+         never accept or send them but we better protect against rogue
+         keyservers. */
+
+      screenerarg.desc = desc;
+      screenerarg.ndesc = ndesc;
+      import_keys_es_stream (ctrl, datastream, stats_handle,
+                             r_fpr, r_fprlen,
+                             (opt.keyserver_options.import_options
+                              | IMPORT_NO_SECKEY),
+                             keyserver_retrieval_screener, &screenerarg);
+
+      import_print_stats (stats_handle);
+      import_release_stats_handle (stats_handle);
+    }
+  es_fclose (datastream);
+  xfree (source);
+
+  return err;
+}
+
+
+/* Send all keys specified by KEYSPECS to the KEYSERVERS.  */
+static gpg_error_t
+keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
+               struct keyserver_spec *keyserver)
+
+{
+  gpg_error_t err;
+  strlist_t kspec;
+
+  if (!keyspecs)
+    return 0;  /* Return success if the list is empty.  */
+
+  if (!opt.keyserver)
+    {
+      log_error (_("no keyserver known (use option --keyserver)\n"));
+      return gpg_error (GPG_ERR_NO_KEYSERVER);
+    }
+
+  for (kspec = keyspecs; kspec; kspec = kspec->next)
+    {
+      void *data;
+      size_t datalen;
+      kbnode_t keyblock;
+
+      err = export_pubkey_buffer (ctrl, kspec->d,
+                                  opt.keyserver_options.export_options,
+                                  &keyblock, &data, &datalen);
+      if (err)
+        log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err));
+      else
+        {
+          if (keyserver->host)
+            log_info (_("sending key %s to %s server %s\n"),
+                      keystr (keyblock->pkt->pkt.public_key->keyid),
+                      keyserver->scheme, keyserver->host);
+          else
+            log_info (_("sending key %s to %s\n"),
+                      keystr (keyblock->pkt->pkt.public_key->keyid),
+                      keyserver->uri);
+
+          err = gpg_dirmngr_ks_put (ctrl, data, datalen, keyblock);
+          release_kbnode (keyblock);
+          xfree (data);
+          if (err)
+            log_error (_("keyserver send failed: %s\n"), gpg_strerror (err));
+        }
+    }
+
+
+  return err;
+
+}
+
+
+/* Loop over all URLs in STRLIST and fetch the key at that URL.  Note
+   that the fetch operation ignores the configured key servers and
+   instead directly retrieves the keys.  */
 int
-keyserver_fetch(strlist_t urilist)
+keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
 {
-  KEYDB_SEARCH_DESC desc;
+  gpg_error_t err;
   strlist_t sl;
-  unsigned int options=opt.keyserver_options.import_options;
+  estream_t datastream;
+  unsigned int save_options = opt.keyserver_options.import_options;
 
   /* Switch on fast-import, since fetch can handle more than one
      import and we don't want each set to rebuild the trustdb.
      Instead we do it once at the end. */
-  opt.keyserver_options.import_options|=IMPORT_FAST;
-
-  /* A dummy desc since we're not actually fetching a particular key
-     ID */
-  memset(&desc,0,sizeof(desc));
-  desc.mode=KEYDB_SEARCH_MODE_EXACT;
+  opt.keyserver_options.import_options |= IMPORT_FAST;
 
-  for(sl=urilist;sl;sl=sl->next)
+  for (sl=urilist; sl; sl=sl->next)
     {
-      struct keyserver_spec *spec;
+      if (!opt.quiet)
+        log_info (_("requesting key from '%s'\n"), sl->d);
 
-      spec=parse_keyserver_uri(sl->d,1,NULL,0);
-      if(spec)
-       {
-         int rc;
+      err = gpg_dirmngr_ks_fetch (ctrl, sl->d, &datastream);
+      if (!err)
+        {
+          void *stats_handle;
 
-         rc=keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,spec);
-         if(rc)
-           log_info (_("WARNING: unable to fetch URI %s: %s\n"),
-                    sl->d,g10_errstr(rc));
+          stats_handle = import_new_stats_handle();
+          import_keys_es_stream (ctrl, datastream, stats_handle, NULL, NULL,
+                                 opt.keyserver_options.import_options,
+                                 NULL, NULL);
 
-         free_keyserver_spec(spec);
-       }
+          import_print_stats (stats_handle);
+          import_release_stats_handle (stats_handle);
+        }
       else
-       log_info (_("WARNING: unable to parse URI %s\n"),sl->d);
+        log_info (_("WARNING: unable to fetch URI %s: %s\n"),
+                  sl->d, gpg_strerror (err));
+      es_fclose (datastream);
     }
 
-  opt.keyserver_options.import_options=options;
+  opt.keyserver_options.import_options = save_options;
 
   /* If the original options didn't have fast import, and the trustdb
      is dirty, rebuild. */
-  if(!(opt.keyserver_options.import_options&IMPORT_FAST))
-    trustdb_check_or_update();
+  if (!(opt.keyserver_options.import_options&IMPORT_FAST))
+    check_or_update_trustdb ();
 
   return 0;
 }
 
+
 /* Import key in a CERT or pointed to by a CERT */
 int
-keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
+keyserver_import_cert (ctrl_t ctrl,
+                       const char *name,unsigned char **fpr,size_t *fpr_len)
 {
+  gpg_error_t err;
   char *domain,*look,*url;
-  IOBUF key;
-  int type,rc=G10ERR_GENERAL;
+  estream_t key;
+
 
   look=xstrdup(name);
 
@@ -2166,30 +1835,27 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
   if(domain)
     *domain='.';
 
-  type=get_dns_cert(look,max_cert_size,&key,fpr,fpr_len,&url);
-  if (!type || type == -1)
-    {
-      /* There might be an error in res_query which leads to an error
-         return (-1) in the case that nothing was found.  Thus we take
-         all errors as key not found.  */
-      rc = G10ERR_NO_PUBKEY;
-    }
-  else if (type==1)
+  err = get_dns_cert (look, &key, fpr, fpr_len, &url);
+  if (err)
+    ;
+  else if (key)
     {
       int armor_status=opt.no_armor;
 
       /* CERTs are always in binary format */
       opt.no_armor=1;
 
-      rc=import_keys_stream (key, NULL, fpr, fpr_len,
-                             (opt.keyserver_options.import_options
-                              | IMPORT_NO_SECKEY), NULL, NULL, NULL);
+      err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
+                                   (opt.keyserver_options.import_options
+                                    | IMPORT_NO_SECKEY),
+                                   NULL, NULL);
 
       opt.no_armor=armor_status;
 
-      iobuf_close(key);
+      es_fclose (key);
+      key = NULL;
     }
-  else if(type==2 && *fpr)
+  else if (*fpr)
     {
       /* We only consider the IPGP type if a fingerprint was provided.
         This lets us select the right key regardless of what a URL
@@ -2201,7 +1867,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
          spec=parse_keyserver_uri(url,1,NULL,0);
          if(spec)
            {
-             rc=keyserver_import_fprint(*fpr,*fpr_len,spec);
+             err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec);
              free_keyserver_spec(spec);
            }
        }
@@ -2210,7 +1876,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
          /* If only a fingerprint is provided, try and fetch it from
             our --keyserver */
 
-         rc=keyserver_import_fprint(*fpr,*fpr_len,opt.keyserver);
+         err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver);
        }
       else
        log_info(_("no keyserver known (use option --keyserver)\n"));
@@ -2219,18 +1885,19 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
         found, but no keyserver" " known (use option
         --keyserver)\n" ? */
 
-      xfree(url);
     }
 
+  xfree(url);
   xfree(look);
 
-  return rc;
+  return err;
 }
 
 /* Import key pointed to by a PKA record. Return the requested
    fingerprint in fpr. */
 int
-keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len)
+keyserver_import_pka (ctrl_t ctrl,
+                      const char *name,unsigned char **fpr,size_t *fpr_len)
 {
   char *uri;
   int rc = G10ERR_NO_PUBKEY;
@@ -2246,7 +1913,7 @@ keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len)
       spec = parse_keyserver_uri (uri, 1, NULL, 0);
       if (spec)
        {
-         rc = keyserver_import_fprint (*fpr, 20, spec);
+         rc = keyserver_import_fprint (ctrl, *fpr, 20, spec);
          free_keyserver_spec (spec);
        }
       xfree (uri);
@@ -2261,27 +1928,18 @@ keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len)
   return rc;
 }
 
-/* Import all keys that match name */
-int
-keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
-                     struct keyserver_spec *keyserver)
-{
-  strlist_t list=NULL;
-  int rc;
-
-  append_to_strlist(&list,name);
-
-  rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver);
-
-  free_strlist(list);
-
-  return rc;
-}
 
 /* Import a key by name using LDAP */
 int
-keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
+keyserver_import_ldap (ctrl_t ctrl,
+                       const char *name, unsigned char **fpr, size_t *fprlen)
 {
+  (void)ctrl;
+  (void)name;
+  (void)fpr;
+  (void)fprlen;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED); /*FIXME*/
+#if 0
   char *domain;
   struct keyserver_spec *keyserver;
   strlist_t list=NULL;
@@ -2343,11 +2001,14 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
 
   append_to_strlist(&list,name);
 
-  rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver);
+  rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); /*FIXME*/
+       /* keyserver_work (ctrl, KS_GETNAME, list, NULL, */
+       /*                 0, fpr, fpr_len, keyserver); */
 
   free_strlist(list);
 
   free_keyserver_spec(keyserver);
 
   return rc;
+#endif
 }
index 86fbabe..76541c7 100644 (file)
@@ -1,6 +1,6 @@
 /* main.h
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- *               2008, 2009 Free Software Foundation, Inc.
+ *               2008, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 
 #include "types.h"
 #include "iobuf.h"
-#include "cipher.h"
 #include "keydb.h"
 #include "util.h"
 
-
 /* It could be argued that the default cipher should be 3DES rather
-   than CAST5, and the default compression should be 0
+   than AES128, and the default compression should be 0
    (i.e. uncompressed) rather than 1 (zip).  However, the real world
    issues of speed and size come into play here. */
 
-#define DEFAULT_CIPHER_ALGO     CIPHER_ALGO_CAST5
+#if GPG_USE_AES128
+# define DEFAULT_CIPHER_ALGO     CIPHER_ALGO_AES
+#elif GPG_USE_CAST5
+# define DEFAULT_CIPHER_ALGO     CIPHER_ALGO_CAST5
+#else
+# define DEFAULT_CIPHER_ALGO     CIPHER_ALGO_3DES
+#endif
+
 #define DEFAULT_DIGEST_ALGO     ((GNUPG)? DIGEST_ALGO_SHA256:DIGEST_ALGO_SHA1)
-#define DEFAULT_COMPRESS_ALGO   COMPRESS_ALGO_ZIP
 #define DEFAULT_S2K_DIGEST_ALGO DIGEST_ALGO_SHA1
+#ifdef HAVE_ZIP
+# define DEFAULT_COMPRESS_ALGO   COMPRESS_ALGO_ZIP
+#else
+# define DEFAULT_COMPRESS_ALGO   COMPRESS_ALGO_NONE
+#endif
+
 
 #define S2K_DIGEST_ALGO (opt.s2k_digest_algo?opt.s2k_digest_algo:DEFAULT_S2K_DIGEST_ALGO)
 
+
+/* Various data objects.  */
+
 typedef struct
 {
   int header_okay;
@@ -48,6 +61,7 @@ typedef struct
   cipher_filter_context_t cfx;
 } encrypt_filter_context_t;
 
+
 struct groupitem
 {
   char *name;
@@ -55,6 +69,7 @@ struct groupitem
   struct groupitem *next;
 };
 
+
 /*-- gpg.c --*/
 extern int g10_errors_seen;
 
@@ -63,10 +78,13 @@ extern int g10_errors_seen;
 #else
   void g10_exit(int rc);
 #endif
+void print_pubkey_algo_note (pubkey_algo_t algo);
+void print_cipher_algo_note (cipher_algo_t algo);
+void print_digest_algo_note (digest_algo_t algo);
+void print_md5_rejected_note (void);
 
 /*-- armor.c --*/
 char *make_radix64_string( const byte *data, size_t len );
-int parse_key_failed_line (const void *lineptr, unsigned int len);
 
 /*-- misc.c --*/
 void trap_unaligned(void);
@@ -78,35 +96,34 @@ int  is_secured_filename (const char *fname);
 u16 checksum_u16( unsigned n );
 u16 checksum( byte *p, unsigned n );
 u16 checksum_mpi( gcry_mpi_t a );
+u32 buffer_to_u32( const byte *buffer );
 const byte *get_session_marker( size_t *rlen );
-void print_pubkey_algo_note( int algo );
-void print_cipher_algo_note( int algo );
-void print_digest_algo_note( int algo );
-void print_md5_rejected_note (void);
-int map_cipher_openpgp_to_gcry (int algo);
-#define openpgp_cipher_open(_a,_b,_c,_d) gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d))
-#define openpgp_cipher_get_algo_keylen(_a) gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a)))
-#define openpgp_cipher_get_algo_blklen(_a) gcry_cipher_get_algo_blklen(map_cipher_openpgp_to_gcry((_a)))
-int openpgp_cipher_blocklen (int algo);
-int openpgp_cipher_test_algo( int algo );
-const char *openpgp_cipher_algo_name (int algo);
-int map_pk_openpgp_to_gcry (int algo);
-int openpgp_pk_test_algo( int algo );
-int openpgp_pk_test_algo2 ( int algo, unsigned int use );
+
+enum gcry_cipher_algos map_cipher_openpgp_to_gcry (cipher_algo_t algo);
+#define openpgp_cipher_open(_a,_b,_c,_d) \
+  gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d))
+#define openpgp_cipher_get_algo_keylen(_a) \
+  gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a)))
+#define openpgp_cipher_get_algo_blklen(_a) \
+  gcry_cipher_get_algo_blklen(map_cipher_openpgp_to_gcry((_a)))
+int openpgp_cipher_blocklen (cipher_algo_t algo);
+int openpgp_cipher_test_algo(cipher_algo_t algo);
+const char *openpgp_cipher_algo_name (cipher_algo_t algo);
+
+pubkey_algo_t map_pk_gcry_to_openpgp (enum gcry_pk_algos algo);
+int openpgp_pk_test_algo (pubkey_algo_t algo);
+int openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use);
 int openpgp_pk_algo_usage ( int algo );
-const char *openpgp_pk_algo_name (int algo);
-int openpgp_md_test_algo( int algo );
+const char *openpgp_pk_algo_name (pubkey_algo_t algo);
 
-#ifdef USE_IDEA
-void idea_cipher_warn( int show );
-#else
-#define idea_cipher_warn(a)  do { } while (0)
-#endif
+enum gcry_md_algos map_md_openpgp_to_gcry (digest_algo_t algo);
+int openpgp_md_test_algo (digest_algo_t algo);
+const char *openpgp_md_algo_name (int algo);
 
 struct expando_args
 {
   PKT_public_key *pk;
-  PKT_secret_key *sk;
+  PKT_public_key *pksk;
   byte imagetype;
   int validity_info;
   const char *validity_string;
@@ -147,23 +164,27 @@ int parse_options(char *str,unsigned int *options,
                  struct parse_options *opts,int noisy);
 int has_invalid_email_chars (const char *s);
 int is_valid_mailbox (const char *name);
+int is_valid_user_id (const char *uid);
 const char *get_libexecdir (void);
 int path_access(const char *file,int mode);
 
+int pubkey_get_npkey (pubkey_algo_t algo);
+int pubkey_get_nskey (pubkey_algo_t algo);
+int pubkey_get_nsig (pubkey_algo_t algo);
+int pubkey_get_nenc (pubkey_algo_t algo);
+
 /* Temporary helpers. */
-int pubkey_get_npkey( int algo );
-int pubkey_get_nskey( int algo );
-int pubkey_get_nsig( int algo );
-int pubkey_get_nenc( int algo );
 unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey );
-int mpi_print( FILE *fp, gcry_mpi_t a, int mode );
+int mpi_print (estream_t stream, gcry_mpi_t a, int mode);
+unsigned int ecdsa_qbits_from_Q (unsigned int qbits);
+
 
 /*-- status.c --*/
 void set_status_fd ( int fd );
 int  is_status_enabled ( void );
 void write_status ( int no );
-void write_status_error (const char *where, int errcode);
-void write_status_failure (const char *where, gpg_error_t err);
+void write_status_error (const char *where, gpg_error_t err);
+void write_status_errcode (const char *where, int errcode);
 void write_status_text ( int no, const char *text );
 void write_status_strings (int no, const char *text,
                            ...) GNUPG_GCC_A_SENTINEL(0);
@@ -181,6 +202,8 @@ char *cpr_get_no_help( const char *keyword, const char *prompt );
 char *cpr_get_utf8( const char *keyword, const char *prompt );
 char *cpr_get_hidden( const char *keyword, const char *prompt );
 void cpr_kill_prompt(void);
+int  cpr_get_answer_is_yes_def (const char *keyword, const char *prompt,
+                                int def_yes);
 int  cpr_get_answer_is_yes( const char *keyword, const char *prompt );
 int  cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt );
 int  cpr_get_answer_okay_cancel (const char *keyword,
@@ -191,18 +214,22 @@ int  cpr_get_answer_okay_cancel (const char *keyword,
 void display_online_help( const char *keyword );
 
 /*-- encode.c --*/
-int setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek);
-int encode_symmetric( const char *filename );
-int encode_store( const char *filename );
-int encode_crypt( const char *filename, strlist_t remusr, int use_symkey );
-void encode_crypt_files(int nfiles, char **files, strlist_t remusr);
-int encrypt_filter( void *opaque, int control,
+int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
+int encrypt_symmetric (const char *filename );
+int encrypt_store (const char *filename );
+int encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
+                   strlist_t remusr, int use_symkey, pk_list_t provided_keys,
+                   int outputfd);
+void encrypt_crypt_files (ctrl_t ctrl,
+                          int nfiles, char **files, strlist_t remusr);
+int encrypt_filter (void *opaque, int control,
                    iobuf_t a, byte *buf, size_t *ret_len);
 
 
 /*-- sign.c --*/
-int complete_sig( PKT_signature *sig, PKT_secret_key *sk, gcry_md_hd_t md );
-int sign_file( strlist_t filenames, int detached, strlist_t locusr,
+int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
+                  const char *cache_nonce);
+int sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
               int do_encrypt, strlist_t remusr, const char *outfile );
 int clearsign_file( const char *fname, strlist_t locusr, const char *outfile );
 int sign_symencrypt_file (const char *fname, strlist_t locusr);
@@ -217,20 +244,23 @@ int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
                          u32 *r_expiredate, int *r_expired );
 
 /*-- delkey.c --*/
-int delete_keys( strlist_t names, int secret, int allow_both );
+gpg_error_t delete_keys (strlist_t names, int secret, int allow_both);
 
 /*-- keyedit.c --*/
-void keyedit_menu( const char *username, strlist_t locusr,
+void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
                   strlist_t commands, int quiet, int seckey_check );
-void keyedit_passwd (const char *username);
+void keyedit_passwd (ctrl_t ctrl, const char *username);
+void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
+                         strlist_t uids, strlist_t locusr, int local);
 void show_basic_key_info (KBNODE keyblock);
 
 /*-- keygen.c --*/
 u32 parse_expire_string(const char *string);
 u32 ask_expire_interval(int object,const char *def_expire);
 u32 ask_expiredate(void);
-void generate_keypair( const char *fname, const char *card_serialno,
-                       const char *backup_encryption_dir );
+void quick_generate_keypair (const char *uid);
+void generate_keypair (ctrl_t ctrl, int full, const char *fname,
+                       const char *card_serialno, int card_backup_key);
 int keygen_set_std_prefs (const char *string,int personal);
 PKT_user_id *keygen_get_std_prefs (void);
 int keygen_add_key_expire( PKT_signature *sig, void *opaque );
@@ -239,67 +269,73 @@ int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
 int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
 int keygen_add_notations(PKT_signature *sig,void *opaque);
 int keygen_add_revkey(PKT_signature *sig, void *opaque);
-int make_backsig(PKT_signature *sig,PKT_public_key *pk,
-                PKT_public_key *sub_pk,PKT_secret_key *sub_sk,
-                 u32 timestamp);
-int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
+gpg_error_t make_backsig (PKT_signature *sig, PKT_public_key *pk,
+                          PKT_public_key *sub_pk, PKT_public_key *sub_psk,
+                          u32 timestamp, const char *cache_nonce);
+gpg_error_t generate_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock);
 #ifdef ENABLE_CARD_SUPPORT
-int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
-                              int keyno, const char *serialno);
-int save_unprotected_key_to_card (PKT_secret_key *sk, int keyno);
+gpg_error_t generate_card_subkeypair (kbnode_t pub_keyblock,
+                                      int keyno, const char *serialno);
+int save_unprotected_key_to_card (PKT_public_key *sk, int keyno);
 #endif
 
+
 /*-- openfile.c --*/
 int overwrite_filep( const char *fname );
 char *make_outfile_name( const char *iname );
 char *ask_outfile_name( const char *name, size_t namelen );
-int   open_outfile( const char *iname, int mode, iobuf_t *a );
-char *get_matching_datafile (const char *sigfilename);
-iobuf_t open_sigfile (const char *sigfilename, progress_filter_context_t *pfx);
+int open_outfile (int inp_fd, const char *iname, int mode,
+                  int restrictedperm, iobuf_t *a);
+iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx );
 void try_make_homedir( const char *fname );
+char *get_openpgp_revocdir (const char *home);
 
 /*-- seskey.c --*/
 void make_session_key( DEK *dek );
-gcry_mpi_t encode_session_key( DEK *dek, unsigned nbits );
-gcry_mpi_t encode_md_value( PKT_public_key *pk, PKT_secret_key *sk,
+gcry_mpi_t encode_session_key( int openpgp_pk_algo, DEK *dek, unsigned nbits );
+gcry_mpi_t encode_md_value (PKT_public_key *pk,
                             gcry_md_hd_t md, int hash_algo );
 
 /*-- import.c --*/
-
-typedef int (*import_filter_t)(kbnode_t keyblock, void *arg);
+typedef gpg_error_t (*import_screener_t)(kbnode_t keyblock, void *arg);
 
 int parse_import_options(char *str,unsigned int *options,int noisy);
-void import_keys( char **fnames, int nnames,
-                 void *stats_hd, unsigned int options );
-int import_keys_stream (iobuf_t inp, void *stats_hd, unsigned char **fpr,
-                        size_t *fpr_len, unsigned int options,
-                        import_filter_t filter, void *filter_arg,
-                        int *r_gpgkeys_err);
+void import_keys (ctrl_t ctrl, char **fnames, int nnames,
+                 void *stats_hd, unsigned int options);
+int import_keys_stream (ctrl_t ctrl, iobuf_t inp, void *stats_hd,
+                        unsigned char **fpr,
+                       size_t *fpr_len, unsigned int options);
+int import_keys_es_stream (ctrl_t ctrl, estream_t fp, void *stats_handle,
+                           unsigned char **fpr, size_t *fpr_len,
+                           unsigned int options,
+                           import_screener_t screener, void *screener_arg);
+gpg_error_t import_old_secring (ctrl_t ctrl, const char *fname);
 void *import_new_stats_handle (void);
 void import_release_stats_handle (void *p);
 void import_print_stats (void *hd);
 
 int collapse_uids( KBNODE *keyblock );
 
-int auto_create_card_key_stub ( const char *serialnostr,
-                                const unsigned char *fpr1,
-                                const unsigned char *fpr2,
-                                const unsigned char *fpr3);
 
 /*-- export.c --*/
 int parse_export_options(char *str,unsigned int *options,int noisy);
-int export_pubkeys( strlist_t users, unsigned int options );
-int export_pubkeys_stream( iobuf_t out, strlist_t users,
-                          KBNODE *keyblock_out, unsigned int options );
-int export_seckeys( strlist_t users );
-int export_secsubkeys( strlist_t users );
-
-/* dearmor.c --*/
+int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options );
+int export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
+                          kbnode_t *keyblock_out, unsigned int options );
+gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec,
+                                  unsigned int options,
+                                  kbnode_t *r_keyblock,
+                                  void **r_data, size_t *r_datalen);
+int export_seckeys (ctrl_t ctrl, strlist_t users);
+int export_secsubkeys (ctrl_t ctrl, strlist_t users);
+
+/*-- dearmor.c --*/
 int dearmor_file( const char *fname );
 int enarmor_file( const char *fname );
 
 /*-- revoke.c --*/
 struct revocation_reason_info;
+int gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce);
 int gen_revoke( const char *uname );
 int gen_desig_revoke( const char *uname, strlist_t locusr);
 int revocation_reason_build_cb( PKT_signature *sig, void *opaque );
@@ -308,32 +344,33 @@ struct revocation_reason_info *
 void release_revocation_reason_info( struct revocation_reason_info *reason );
 
 /*-- keylist.c --*/
-void public_key_list( strlist_t list, int locate_mode );
-void secret_key_list( strlist_t list );
+void public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode );
+void secret_key_list (ctrl_t ctrl, strlist_t list );
 void print_subpackets_colon(PKT_signature *sig);
 void reorder_keyblock (KBNODE keyblock);
-void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
-void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode);
-void print_revokers(PKT_public_key *pk);
+void list_keyblock (kbnode_t keyblock, int secret, int has_secret,
+                    int fpr, void *opaque);
+void print_fingerprint (estream_t fp, PKT_public_key *pk, int mode);
+void print_revokers (estream_t fp, PKT_public_key *pk);
 void show_policy_url(PKT_signature *sig,int indent,int mode);
 void show_keyserver_url(PKT_signature *sig,int indent,int mode);
 void show_notation(PKT_signature *sig,int indent,int mode,int which);
-void dump_attribs(const PKT_user_id *uid,
-                 PKT_public_key *pk,PKT_secret_key *sk);
+void dump_attribs (const PKT_user_id *uid, PKT_public_key *pk);
 void set_attrib_fd(int fd);
-void print_seckey_info (PKT_secret_key *sk);
-void print_pubkey_info (FILE *fp, PKT_public_key *pk);
-void print_card_key_info (FILE *fp, KBNODE keyblock);
+void print_seckey_info (PKT_public_key *pk);
+void print_pubkey_info (estream_t fp, PKT_public_key *pk);
+void print_card_key_info (estream_t fp, KBNODE keyblock);
 
 /*-- verify.c --*/
 void print_file_status( int status, const char *name, int what );
-int verify_signatures( int nfiles, char **files );
-int verify_files( int nfiles, char **files );
-int gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, FILE *out_fp);
+int verify_signatures (ctrl_t ctrl, int nfiles, char **files );
+int verify_files (ctrl_t ctrl, int nfiles, char **files );
+int gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp);
 
 /*-- decrypt.c --*/
-int decrypt_message( const char *filename );
-void decrypt_messages(int nfiles, char *files[]);
+int decrypt_message (ctrl_t ctrl, const char *filename );
+gpg_error_t decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd);
+void decrypt_messages (ctrl_t ctrl, int nfiles, char *files[]);
 
 /*-- plaintext.c --*/
 int hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2,
@@ -344,22 +381,27 @@ PKT_plaintext *setup_plaintext_name(const char *filename,IOBUF iobuf);
 
 /*-- signal.c --*/
 void init_signals(void);
-void pause_on_sigusr( int which );
 void block_all_signals(void);
 void unblock_all_signals(void);
 
 /*-- server.c --*/
 int gpg_server (ctrl_t);
+gpg_error_t gpg_proxy_pinentry_notify (ctrl_t ctrl,
+                                       const unsigned char *line);
 
 #ifdef ENABLE_CARD_SUPPORT
 /*-- card-util.c --*/
 void change_pin (int no, int allow_admin);
-void card_status (FILE *fp, char *serialno, size_t serialnobuflen);
-void card_edit (strlist_t commands);
-int  card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
+void card_status (estream_t fp, char *serialno, size_t serialnobuflen);
+void card_edit (ctrl_t ctrl, strlist_t commands);
+gpg_error_t  card_generate_subkey (KBNODE pub_keyblock);
 int  card_store_subkey (KBNODE node, int use);
 #endif
 
 #define S2K_DECODE_COUNT(_val) ((16ul + ((_val) & 15)) << (((_val) >> 4) + 6))
 
+/*-- migrate.c --*/
+void migrate_secring (ctrl_t ctrl);
+
+
 #endif /*G10_MAIN_H*/
index 8c2d2e1..50d1d27 100644 (file)
@@ -1,7 +1,7 @@
 /* mainproc.c - handle packets
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
  *               2008, 2009 Free Software Foundation, Inc.
- * Copyright (C) 2013 Werner Koch
+ * Copyright (C) 2013, 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include <time.h>
 
 #include "gpg.h"
+#include "util.h"
 #include "packet.h"
 #include "iobuf.h"
 #include "options.h"
-#include "util.h"
-#include "cipher.h"
 #include "keydb.h"
 #include "filter.h"
 #include "main.h"
@@ -62,9 +61,9 @@ struct kidlist_item {
 typedef struct mainproc_context *CTX;
 struct mainproc_context
 {
+  ctrl_t ctrl;
   struct mainproc_context *anchor;  /* May be useful in the future. */
   PKT_public_key *last_pubkey;
-  PKT_secret_key *last_seckey;
   PKT_user_id     *last_user_id;
   md_filter_context_t mfx;
   int sigs_only;    /* Process only signatures and reject all other stuff. */
@@ -84,7 +83,7 @@ struct mainproc_context
     /* A list of filenames with the data files or NULL. This is only
        used if DATA_FD is -1. */
     strlist_t data_names;
-    /* Flag to indicated that either one of the next previous fieldss
+    /* Flag to indicated that either one of the next previous fields
        is used.  This is only needed for better readability. */
     int used;
   } signed_data;
@@ -261,12 +260,6 @@ symkey_decrypt_seskey( DEK *dek, byte *seskey, size_t slen )
   if(dek->keylen > DIM(dek->key))
     BUG ();
 
-  /* This is not completely accurate, since a bad passphrase may have
-     resulted in a garbage algorithm byte, but it's close enough since
-     a bogus byte here will fail later. */
-  if(dek->algo==CIPHER_ALGO_IDEA)
-    idea_cipher_warn(0);
-
   memcpy(dek->key, seskey + 1, dek->keylen);
 
   /*log_hexdump( "thekey", dek->key, dek->keylen );*/
@@ -372,7 +365,13 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
 
     if( is_status_enabled() ) {
        char buf[50];
-       sprintf(buf, "%08lX%08lX %d 0",
+        /* FIXME: For ECC support we need to map the OpenPGP algo
+           number to the Libgcrypt definef one.  This is due a
+           chicken-egg problem: We need to have code in libgcrypt for
+           a new algorithm so to implement a proposed new algorithm
+           before the IANA will finally assign an OpenPGP
+           indentifier.  */
+       snprintf (buf, sizeof buf, "%08lX%08lX %d 0",
                (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo );
        write_status_text( STATUS_ENC_TO, buf );
     }
@@ -387,9 +386,12 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
            xfree(c->dek); c->dek = NULL;
        }
     }
-    else if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E
-             || enc->pubkey_algo == PUBKEY_ALGO_RSA
-             || enc->pubkey_algo == PUBKEY_ALGO_RSA_E
+    else if( is_ELGAMAL(enc->pubkey_algo)
+             || enc->pubkey_algo == PUBKEY_ALGO_DSA
+             || enc->pubkey_algo == PUBKEY_ALGO_ECDSA
+             || enc->pubkey_algo == PUBKEY_ALGO_EDDSA
+             || enc->pubkey_algo == PUBKEY_ALGO_ECDH
+             || is_RSA(enc->pubkey_algo)
              || enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL) {
       /* Note that we also allow type 20 Elgamal keys for decryption.
          There are still a couple of those keys in active use as a
@@ -400,7 +402,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
          experience if wildcard keyids are used.  */
        if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
                           || opt.try_all_secrets
-                         || !seckey_available( enc->keyid )) ) {
+                         || have_secret_key_with_kid (enc->keyid)) ) {
            if( opt.list_only )
                result = -1;
            else {
@@ -520,9 +522,7 @@ proc_encrypted( CTX c, PACKET *pkt )
        result = -1;
     else if( !c->dek && !c->last_was_session_key ) {
         int algo;
-        STRING2KEY s2kbuf;
-        STRING2KEY *s2k = NULL;
-        int canceled;
+        STRING2KEY s2kbuf, *s2k = NULL;
 
        if(opt.override_session_key)
          {
@@ -546,7 +546,6 @@ proc_encrypted( CTX c, PACKET *pkt )
                algo = opt.def_cipher_algo;
                if (!algo)
                  algo = opt.s2k_cipher_algo;
-               idea_cipher_warn(1);
                log_info (_("IDEA cipher unavailable, "
                            "optimistically attempting to use %s instead\n"),
                          openpgp_cipher_algo_name (algo));
@@ -564,20 +563,16 @@ proc_encrypted( CTX c, PACKET *pkt )
                log_info (_("assuming %s encrypted data\n"), "IDEA");
              }
 
-           c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 3, NULL,&canceled);
+           c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 3, NULL, NULL );
            if (c->dek)
              c->dek->algo_info_printed = 1;
-            else if (canceled)
-              result = gpg_error (GPG_ERR_CANCELED);
-            else
-              result = gpg_error (GPG_ERR_INV_PASSPHRASE);
          }
     }
     else if( !c->dek )
        result = G10ERR_NO_SECKEY;
 
-    if( !result )
-       result = decrypt_data( c, pkt->pkt.encrypted, c->dek );
+    if (!result)
+      result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
 
     if( result == -1 )
        ;
@@ -591,7 +586,8 @@ proc_encrypted( CTX c, PACKET *pkt )
        else if(!opt.no_mdc_warn)
            log_info (_("WARNING: message was not integrity protected\n"));
     }
-    else if( gpg_err_code (result) == G10ERR_BAD_SIGN ) {
+    else if( result == G10ERR_BAD_SIGN ) {
+        glo_ctrl.lasterr = result;
        log_error(_("WARNING: encrypted message has been manipulated!\n"));
        write_status( STATUS_BADMDC );
        write_status( STATUS_DECRYPTION_FAILED );
@@ -604,6 +600,7 @@ proc_encrypted( CTX c, PACKET *pkt )
                      c->dek->s2k_cacheid);
            passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0);
          }
+        glo_ctrl.lasterr = result;
        write_status( STATUS_DECRYPTION_FAILED );
        log_error(_("decryption failed: %s\n"), g10_errstr(result));
        /* Hmmm: does this work when we have encrypted using multiple
@@ -626,7 +623,7 @@ proc_plaintext( CTX c, PACKET *pkt )
     literals_seen++;
 
     if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) )
-       log_info(_("NOTE: sender requested \"for-your-eyes-only\"\n"));
+       log_info(_("Note: sender requested \"for-your-eyes-only\"\n"));
     else if( opt.verbose )
        log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name);
     free_md_filter_context( &c->mfx );
@@ -697,7 +694,8 @@ proc_plaintext( CTX c, PACKET *pkt )
        gcry_md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
        gcry_md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
       }
-    if( opt.pgp2_workarounds && only_md5 && !opt.skip_verify ) {
+    if (opt.pgp2_workarounds && only_md5 && !opt.skip_verify
+        && opt.flags.allow_weak_digest_algos) {
        /* This is a kludge to work around a bug in pgp2.  It does only
         * catch those mails which are armored.  To catch the non-armored
         * pgp mails we could see whether there is the signature packet
@@ -758,18 +756,19 @@ proc_compressed_cb( IOBUF a, void *info )
 {
   if ( ((CTX)info)->signed_data.used
        && ((CTX)info)->signed_data.data_fd != -1)
-    return proc_signature_packets_by_fd (info, a,
+    return proc_signature_packets_by_fd (((CTX)info)->ctrl, info, a,
                                          ((CTX)info)->signed_data.data_fd);
   else
-    return proc_signature_packets (info, a,
+    return proc_signature_packets (((CTX)info)->ctrl, info, a,
                                    ((CTX)info)->signed_data.data_names,
                                    ((CTX)info)->sigfilename );
 }
 
 static int
-proc_encrypt_cbIOBUF a, void *info )
+proc_encrypt_cb (IOBUF a, void *info )
 {
-    return proc_encryption_packets( info, a );
+  CTX c = info;
+  return proc_encryption_packets (c->ctrl, info, a );
 }
 
 static int
@@ -780,11 +779,11 @@ proc_compressed( CTX c, PACKET *pkt )
 
   /*printf("zip: compressed data packet\n");*/
   if (c->sigs_only)
-    rc = handle_compressed (c, zd, proc_compressed_cb, c);
-  else if (c->encrypt_only)
-    rc = handle_compressed (c, zd, proc_encrypt_cb, c);
+    rc = handle_compressed (c->ctrl, c, zd, proc_compressed_cb, c);
+  else if( c->encrypt_only )
+    rc = handle_compressed (c->ctrl, c, zd, proc_encrypt_cb, c);
   else
-    rc = handle_compressed (c, zd, NULL, NULL);
+    rc = handle_compressed (c->ctrl, c, zd, NULL, NULL);
 
   if (gpg_err_code (rc) == GPG_ERR_BAD_DATA)
     {
@@ -794,13 +793,13 @@ proc_compressed( CTX c, PACKET *pkt )
 
           for (cc=c; cc; cc = cc->anchor)
             cc->any.uncompress_failed = 1;
-          log_error ("uncompressing failed: %s\n", g10_errstr(rc));
+          log_error ("uncompressing failed: %s\n", gpg_strerror (rc));
         }
-      }
+    }
   else if (rc)
-    log_error("uncompressing failed: %s\n", g10_errstr(rc));
+    log_error ("uncompressing failed: %s\n", gpg_strerror (rc));
 
-  free_packet (pkt);
+  free_packet(pkt);
   c->last_was_session_key = 0;
   return rc;
 }
@@ -907,12 +906,12 @@ print_userid( PACKET *pkt )
                 pkt->pkt.user_id->numattribs,
                 pkt->pkt.user_id->attrib_len);
        else
-         print_string( stdout,  pkt->pkt.user_id->name,
-                       pkt->pkt.user_id->len, ':');
+         es_write_sanitized (es_stdout, pkt->pkt.user_id->name,
+                              pkt->pkt.user_id->len, ":", NULL);
       }
     else
-       print_utf8_string( stdout,  pkt->pkt.user_id->name,
-                                    pkt->pkt.user_id->len );
+       print_utf8_buffer (es_stdout, pkt->pkt.user_id->name,
+                           pkt->pkt.user_id->len );
 }
 
 
@@ -923,237 +922,214 @@ print_userid( PACKET *pkt )
 static void
 list_node( CTX c, KBNODE node )
 {
-    int mainkey;
+  int mainkey;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
-    if( !node )
-       ;
-    else if( (mainkey = (node->pkt->pkttype == PKT_PUBLIC_KEY) )
-            || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-       PKT_public_key *pk = node->pkt->pkt.public_key;
+  if (!node)
+    ;
+  else if ((mainkey = (node->pkt->pkttype == PKT_PUBLIC_KEY))
+           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+    {
+      PKT_public_key *pk = node->pkt->pkt.public_key;
 
-       if( opt.with_colons )
-         {
-           u32 keyid[2];
-           keyid_from_pk( pk, keyid );
-           if( mainkey )
-             c->trustletter = opt.fast_list_mode?
-               0 : get_validity_info( pk, NULL );
-           printf("%s:", mainkey? "pub":"sub" );
-           if( c->trustletter )
-             putchar( c->trustletter );
-           printf(":%u:%d:%08lX%08lX:%s:%s::",
-                  nbits_from_pk( pk ),
-                  pk->pubkey_algo,
-                  (ulong)keyid[0],(ulong)keyid[1],
-                  colon_datestr_from_pk( pk ),
-                  colon_strtime (pk->expiredate) );
-           if( mainkey && !opt.fast_list_mode )
-             putchar( get_ownertrust_info (pk) );
-           putchar(':');
-          }
-       else
-          {
-            printf("%s  %4u%c/%s %s",
-                   mainkey? "pub":"sub", nbits_from_pk( pk ),
-                   pubkey_letter( pk->pubkey_algo ), keystr_from_pk( pk ),
+      if (opt.with_colons)
+        {
+          u32 keyid[2];
+
+          keyid_from_pk( pk, keyid );
+          if (mainkey)
+            c->trustletter = (opt.fast_list_mode?
+                              0 : get_validity_info( pk, NULL));
+          es_printf ("%s:", mainkey? "pub":"sub" );
+          if (c->trustletter)
+            es_putc (c->trustletter, es_stdout);
+          es_printf (":%u:%d:%08lX%08lX:%s:%s::",
+                     nbits_from_pk( pk ),
+                     pk->pubkey_algo,
+                     (ulong)keyid[0],(ulong)keyid[1],
+                     colon_datestr_from_pk( pk ),
+                     colon_strtime (pk->expiredate) );
+          if (mainkey && !opt.fast_list_mode)
+            es_putc (get_ownertrust_info (pk), es_stdout);
+          es_putc (':', es_stdout);
+        }
+      else
+        es_printf ("%s  %s/%s %s",
+                   mainkey? "pub":"sub",
+                   pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                   keystr_from_pk (pk),
                    datestr_from_pk (pk));
-          }
-
-        if (pk->is_revoked)
-          {
-            printf(" [");
-            printf(_("revoked: %s"),revokestr_from_pk(pk));
-            printf("]\n");
-          }
-        else if (pk->expiredate && !opt.with_colons)
-          {
-            printf(" [");
-            printf(_("expires: %s"),expirestr_from_pk(pk));
-            printf("]\n");
-          }
-        else
-          putchar ('\n');
 
-        if ((mainkey && opt.fingerprint) || opt.fingerprint > 1)
-          print_fingerprint (pk, NULL, 0);
+      if (pk->flags.revoked)
+        {
+          es_printf (" [");
+          es_printf (_("revoked: %s"), revokestr_from_pk (pk));
+          es_printf ("]\n");
+        }
+      else if( pk->expiredate && !opt.with_colons)
+        {
+          es_printf (" [");
+          es_printf (_("expires: %s"), expirestr_from_pk (pk));
+          es_printf ("]\n");
+        }
+      else
+        es_putc ('\n', es_stdout);
 
-       if (opt.with_colons)
-         {
-           if (node->next && node->next->pkt->pkttype == PKT_RING_TRUST)
-             printf("rtv:1:%u:\n", node->next->pkt->pkt.ring_trust->trustval);
-         }
+      if ((mainkey && opt.fingerprint) || opt.fingerprint > 1)
+        print_fingerprint (NULL, pk, 0);
 
-       if( mainkey ) {
-           /* and now list all userids with their signatures */
-           for( node = node->next; node; node = node->next ) {
-               if( node->pkt->pkttype == PKT_SIGNATURE ) {
-                   list_node(c,  node );
-               }
-               else if( node->pkt->pkttype == PKT_USER_ID ) {
-                    if( opt.with_colons )
-                      printf("%s:::::::::",
-                             node->pkt->pkt.user_id->attrib_data?"uat":"uid");
-                    else
-                      printf( "uid%*s", 28, "" );
-                   print_userid( node->pkt );
-                   if( opt.with_colons )
-                       putchar(':');
-                   putchar('\n');
-                   if( opt.with_colons
-                        && node->next
-                       && node->next->pkt->pkttype == PKT_RING_TRUST ) {
-                       printf("rtv:2:%u:\n",
-                               node->next->pkt->pkt.ring_trust?
-                               node->next->pkt->pkt.ring_trust->trustval : 0);
-                   }
-               }
-               else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-                  list_node(c,  node );
-               }
-           }
-       }
-    }
-    else if( (mainkey = (node->pkt->pkttype == PKT_SECRET_KEY) )
-            || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
-       PKT_secret_key *sk = node->pkt->pkt.secret_key;
+      if (opt.with_colons)
+        {
+          if (node->next && node->next->pkt->pkttype == PKT_RING_TRUST)
+            es_printf ("rtv:1:%u:\n",
+                       node->next->pkt->pkt.ring_trust->trustval);
+        }
 
-       if( opt.with_colons )
-         {
-           u32 keyid[2];
-           keyid_from_sk( sk, keyid );
-           printf("%s::%u:%d:%08lX%08lX:%s:%s:::",
-                  mainkey? "sec":"ssb",
-                  nbits_from_sk( sk ),
-                  sk->pubkey_algo,
-                  (ulong)keyid[0],(ulong)keyid[1],
-                  colon_datestr_from_sk( sk ),
-                  colon_strtime (sk->expiredate));
-         }
-       else
-         printf("%s  %4u%c/%s %s ", mainkey? "sec":"ssb",
-                nbits_from_sk( sk ), pubkey_letter( sk->pubkey_algo ),
-                keystr_from_sk( sk ), datestr_from_sk( sk ));
-
-        putchar ('\n');
-        if ((mainkey && opt.fingerprint) || opt.fingerprint > 1)
-          print_fingerprint (NULL, sk,0);
-
-       if( mainkey ) {
-           /* and now list all userids with their signatures */
-           for( node = node->next; node; node = node->next ) {
-               if( node->pkt->pkttype == PKT_SIGNATURE ) {
-                   list_node(c,  node );
-               }
-               else if( node->pkt->pkttype == PKT_USER_ID ) {
-                    if( opt.with_colons )
-                       printf("%s:::::::::",
+      if (mainkey)
+        {
+          /* Now list all userids with their signatures. */
+          for (node = node->next; node; node = node->next)
+            {
+              if (node->pkt->pkttype == PKT_SIGNATURE)
+                {
+                  list_node (c,  node );
+                }
+              else if (node->pkt->pkttype == PKT_USER_ID)
+                {
+                  if (opt.with_colons)
+                    es_printf ("%s:::::::::",
                                node->pkt->pkt.user_id->attrib_data?"uat":"uid");
-                    else
-                        printf( "uid%*s", 28, "" );
-                   print_userid( node->pkt );
-                   if( opt.with_colons )
-                       putchar(':');
-                   putchar('\n');
+                  else
+                    es_printf ("uid%*s", 28, "" );
+                  print_userid (node->pkt);
+                  if (opt.with_colons)
+                    es_putc (':', es_stdout);
+                  es_putc ('\n', es_stdout);
+                  if (opt.with_colons
+                      && node->next
+                      && node->next->pkt->pkttype == PKT_RING_TRUST)
+                    {
+                      es_printf ("rtv:2:%u:\n",
+                                 node->next->pkt->pkt.ring_trust?
+                                 node->next->pkt->pkt.ring_trust->trustval : 0);
+                    }
                }
-               else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
+              else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+                {
                   list_node(c,  node );
-               }
-           }
-       }
+                }
+            }
+        }
     }
-    else if( node->pkt->pkttype == PKT_SIGNATURE  ) {
-       PKT_signature *sig = node->pkt->pkt.signature;
-       int is_selfsig = 0;
-       int rc2=0;
-       size_t n;
-       char *p;
-       int sigrc = ' ';
+  else if ((mainkey = (node->pkt->pkttype == PKT_SECRET_KEY) )
+           || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+    {
 
-       if( !opt.verbose )
-           return;
+      log_debug ("FIXME: No way to print secret key packets here\n");
+      /* fixme: We may use a fucntion to turn a secret key packet into
+         a public key one and use that here.  */
+    }
+  else if (node->pkt->pkttype == PKT_SIGNATURE)
+    {
+      PKT_signature *sig = node->pkt->pkt.signature;
+      int is_selfsig = 0;
+      int rc2 = 0;
+      size_t n;
+      char *p;
+      int sigrc = ' ';
+
+      if (!opt.verbose)
+        return;
 
-       if( sig->sig_class == 0x20 || sig->sig_class == 0x30 )
-           fputs("rev", stdout);
-       else
-           fputs("sig", stdout);
-       if( opt.check_sigs ) {
-           fflush(stdout);
-           rc2=do_check_sig( c, node, &is_selfsig, NULL, NULL );
-           switch (gpg_err_code (rc2)) {
-             case 0:                        sigrc = '!'; break;
-             case GPG_ERR_BAD_SIGNATURE:    sigrc = '-'; break;
-             case GPG_ERR_NO_PUBKEY:
-             case GPG_ERR_UNUSABLE_PUBKEY:  sigrc = '?'; break;
-             default:                       sigrc = '%'; break;
+      if (sig->sig_class == 0x20 || sig->sig_class == 0x30)
+        es_fputs ("rev", es_stdout);
+      else
+        es_fputs ("sig", es_stdout);
+      if (opt.check_sigs)
+        {
+          fflush (stdout);
+          rc2 = do_check_sig (c, node, &is_selfsig, NULL, NULL);
+          switch (gpg_err_code (rc2))
+            {
+            case 0:                      sigrc = '!'; break;
+            case GPG_ERR_BAD_SIGNATURE:   sigrc = '-'; break;
+            case GPG_ERR_NO_PUBKEY:
+            case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break;
+            default:                     sigrc = '%'; break;
            }
        }
-       else {  /* check whether this is a self signature */
-           u32 keyid[2];
+      else /* Check whether this is a self signature.  */
+        {
+          u32 keyid[2];
 
-           if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
-               || c->list->pkt->pkttype == PKT_SECRET_KEY ) {
-               if( c->list->pkt->pkttype == PKT_PUBLIC_KEY )
-                   keyid_from_pk( c->list->pkt->pkt.public_key, keyid );
-               else
-                   keyid_from_sk( c->list->pkt->pkt.secret_key, keyid );
+          if (c->list->pkt->pkttype == PKT_PUBLIC_KEY
+              || c->list->pkt->pkttype == PKT_SECRET_KEY )
+            {
+              keyid_from_pk (c->list->pkt->pkt.public_key, keyid);
 
-               if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
-                   is_selfsig = 1;
-           }
+              if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1])
+                is_selfsig = 1;
+            }
        }
-       if( opt.with_colons ) {
-           putchar(':');
-           if( sigrc != ' ' )
-               putchar(sigrc);
-           printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
-                  (ulong)sig->keyid[0], (ulong)sig->keyid[1],
-                  colon_datestr_from_sig(sig),
-                  colon_expirestr_from_sig(sig));
-
-           if(sig->trust_depth || sig->trust_value)
-             printf("%d %d",sig->trust_depth,sig->trust_value);
-           printf(":");
-
-           if(sig->trust_regexp)
-             print_string(stdout,sig->trust_regexp,
-                          strlen(sig->trust_regexp),':');
-           printf(":");
+
+      if (opt.with_colons)
+        {
+          es_putc (':', es_stdout);
+          if (sigrc != ' ')
+            es_putc (sigrc, es_stdout);
+          es_printf ("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
+                     (ulong)sig->keyid[0], (ulong)sig->keyid[1],
+                     colon_datestr_from_sig (sig),
+                     colon_expirestr_from_sig (sig));
+
+          if (sig->trust_depth || sig->trust_value)
+            es_printf ("%d %d",sig->trust_depth,sig->trust_value);
+          es_putc (':', es_stdout);
+
+          if (sig->trust_regexp)
+            es_write_sanitized (es_stdout, sig->trust_regexp,
+                                strlen (sig->trust_regexp), ":", NULL);
+          es_putc (':', es_stdout);
        }
-       else
-         printf("%c       %s %s   ",
-                sigrc, keystr(sig->keyid), datestr_from_sig(sig));
-       if( sigrc == '%' )
-           printf("[%s] ", g10_errstr(rc2) );
-       else if( sigrc == '?' )
-           ;
-       else if( is_selfsig ) {
-           if( opt.with_colons )
-               putchar(':');
-           fputs( sig->sig_class == 0x18? "[keybind]":"[selfsig]", stdout);
-           if( opt.with_colons )
-               putchar(':');
+      else
+        es_printf ("%c       %s %s   ",
+                   sigrc, keystr (sig->keyid), datestr_from_sig(sig));
+      if (sigrc == '%')
+        es_printf ("[%s] ", g10_errstr(rc2) );
+      else if (sigrc == '?')
+        ;
+      else if (is_selfsig)
+        {
+          if (opt.with_colons)
+            es_putc (':', es_stdout);
+          es_fputs (sig->sig_class == 0x18? "[keybind]":"[selfsig]", es_stdout);
+          if (opt.with_colons)
+            es_putc (':', es_stdout);
        }
-       else if( !opt.fast_list_mode ) {
-           p = get_user_id( sig->keyid, &n );
-           print_string( stdout, p, n, opt.with_colons );
-           xfree(p);
+      else if (!opt.fast_list_mode)
+        {
+          p = get_user_id (sig->keyid, &n);
+          es_write_sanitized (es_stdout, p, n,
+                              opt.with_colons?":":NULL, NULL );
+          xfree (p);
        }
-       if( opt.with_colons )
-           printf(":%02x%c:", sig->sig_class, sig->flags.exportable?'x':'l');
-       putchar('\n');
+      if (opt.with_colons)
+        es_printf (":%02x%c:", sig->sig_class, sig->flags.exportable?'x':'l');
+      es_putc ('\n', es_stdout);
     }
-    else
-       log_error("invalid node with packet of type %d\n", node->pkt->pkttype);
+  else
+    log_error ("invalid node with packet of type %d\n", node->pkt->pkttype);
 }
 
 
 
 int
-proc_packets( void *anchor, IOBUF a )
+proc_packets (ctrl_t ctrl, void *anchor, IOBUF a )
 {
     int rc;
     CTX c = xmalloc_clear( sizeof *c );
 
+    c->ctrl = ctrl;
     c->anchor = anchor;
     rc = do_proc_packets( c, a );
     xfree( c );
@@ -1163,12 +1139,13 @@ proc_packets( void *anchor, IOBUF a )
 
 
 int
-proc_signature_packets( void *anchor, IOBUF a,
+proc_signature_packets (ctrl_t ctrl, void *anchor, IOBUF a,
                        strlist_t signedfiles, const char *sigfilename )
 {
     CTX c = xmalloc_clear( sizeof *c );
     int rc;
 
+    c->ctrl = ctrl;
     c->anchor = anchor;
     c->sigs_only = 1;
 
@@ -1201,12 +1178,19 @@ proc_signature_packets( void *anchor, IOBUF a,
     return rc;
 }
 
+
 int
-proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd )
+proc_signature_packets_by_fd (ctrl_t ctrl,
+                              void *anchor, IOBUF a, int signed_data_fd )
 {
   int rc;
-  CTX c = xcalloc (1, sizeof *c);
+  CTX c;
+
+  c = xtrycalloc (1, sizeof *c);
+  if (!c)
+    return gpg_error_from_syserror ();
 
+  c->ctrl = ctrl;
   c->anchor = anchor;
   c->sigs_only = 1;
 
@@ -1239,11 +1223,12 @@ proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd )
 
 
 int
-proc_encryption_packets( void *anchor, IOBUF a )
+proc_encryption_packets (ctrl_t ctrl, void *anchor, IOBUF a )
 {
     CTX c = xmalloc_clear( sizeof *c );
     int rc;
 
+    c->ctrl = ctrl;
     c->anchor = anchor;
     c->encrypt_only = 1;
     rc = do_proc_packets( c, a );
@@ -1292,7 +1277,7 @@ do_proc_packets( CTX c, IOBUF a )
             /* stop processing when an invalid packet has been encountered
              * but don't do so when we are doing a --list-packets. */
            if (gpg_err_code (rc) == GPG_ERR_INV_PACKET
-                && opt.list_packets == 0 )
+                && opt.list_packets != 2 )
                break;
            continue;
        }
@@ -1480,12 +1465,45 @@ pka_uri_from_sig (PKT_signature *sig)
 }
 
 
+static void
+print_good_bad_signature (int statno, const char *keyid_str, kbnode_t un,
+                          PKT_signature *sig, int rc)
+{
+  char *p;
+
+  write_status_text_and_buffer (statno, keyid_str,
+                                un? un->pkt->pkt.user_id->name:"[?]",
+                                un? un->pkt->pkt.user_id->len:3,
+                                -1);
+
+  if (un)
+    p = utf8_to_native (un->pkt->pkt.user_id->name,
+                        un->pkt->pkt.user_id->len, 0);
+  else
+    p = xstrdup ("[?]");
+
+  if (rc)
+    log_info (_("BAD signature from \"%s\""), p);
+  else if (sig->flags.expired)
+    log_info (_("Expired signature from \"%s\""), p);
+  else
+    log_info (_("Good signature from \"%s\""), p);
+
+  xfree (p);
+}
+
+
 static int
-check_sig_and_print( CTX c, KBNODE node )
+check_sig_and_print (CTX c, KBNODE node)
 {
   PKT_signature *sig = node->pkt->pkt.signature;
   const char *astr;
-  int rc, is_expkey=0, is_revkey=0;
+  int rc;
+  int is_expkey = 0;
+  int is_revkey = 0;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
+
+  *pkstrbuf = 0;
 
   if (opt.skip_verify)
     {
@@ -1601,430 +1619,377 @@ check_sig_and_print( CTX c, KBNODE node )
         log_error(_("can't handle this ambiguous signature data\n"));
         return 0;
       }
-
   }
 
-  write_status_text (STATUS_NEWSIG, NULL);
-
-  /* (Indendation below not yet changed to GNU style.) */
-
-    astr = openpgp_pk_algo_name ( sig->pubkey_algo );
-    if(keystrlen()>8)
-      {
-       log_info(_("Signature made %s\n"),asctimestamp(sig->timestamp));
-       log_info(_("               using %s key %s\n"),
-                astr? astr: "?",keystr(sig->keyid));
-      }
-    else
-      log_info(_("Signature made %s using %s key ID %s\n"),
-              asctimestamp(sig->timestamp), astr? astr: "?",
-              keystr(sig->keyid));
+  astr = openpgp_pk_algo_name ( sig->pubkey_algo );
+  if (keystrlen () > 8)
+    {
+      log_info (_("Signature made %s\n"), asctimestamp(sig->timestamp));
+      log_info (_("               using %s key %s\n"),
+                astr? astr: "?",keystr(sig->keyid));
+    }
+  else
+    log_info (_("Signature made %s using %s key ID %s\n"),
+              asctimestamp(sig->timestamp), astr? astr: "?",
+              keystr(sig->keyid));
 
-    rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
+  rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
 
-    /* If the key isn't found, check for a preferred keyserver */
+  /* If the key isn't found, check for a preferred keyserver */
 
-    if(rc==G10ERR_NO_PUBKEY && sig->flags.pref_ks)
-      {
-       const byte *p;
-       int seq=0;
-       size_t n;
+  if (gpg_err_code (rc) == G10ERR_NO_PUBKEY && sig->flags.pref_ks)
+    {
+      const byte *p;
+      int seq = 0;
+      size_t n;
 
-       while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
-         {
-           /* According to my favorite copy editor, in English
-              grammar, you say "at" if the key is located on a web
-              page, but "from" if it is located on a keyserver.  I'm
-              not going to even try to make two strings here :) */
-           log_info(_("Key available at: ") );
-           print_utf8_string( log_get_stream(), p, n );
-           log_printf ("\n");
-
-           if(opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE
-              && opt.keyserver_options.options&KEYSERVER_HONOR_KEYSERVER_URL)
-             {
-               struct keyserver_spec *spec;
+      while ((p=enum_sig_subpkt (sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
+        {
+          /* According to my favorite copy editor, in English grammar,
+             you say "at" if the key is located on a web page, but
+             "from" if it is located on a keyserver.  I'm not going to
+             even try to make two strings here :) */
+          log_info(_("Key available at: ") );
+          print_utf8_buffer (log_get_stream(), p, n);
+          log_printf ("\n");
+
+          if (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE
+              && opt.keyserver_options.options&KEYSERVER_HONOR_KEYSERVER_URL)
+            {
+              struct keyserver_spec *spec;
 
-               spec=parse_preferred_keyserver(sig);
-               if(spec)
-                 {
-                   int res;
+              spec = parse_preferred_keyserver (sig);
+              if (spec)
+                {
+                  int res;
 
-                   glo_ctrl.in_auto_key_retrieve++;
-                   res=keyserver_import_keyid(sig->keyid,spec);
-                   glo_ctrl.in_auto_key_retrieve--;
-                   if(!res)
-                     rc=do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
-                   free_keyserver_spec(spec);
+                  glo_ctrl.in_auto_key_retrieve++;
+                  res = keyserver_import_keyid (c->ctrl, sig->keyid,spec);
+                  glo_ctrl.in_auto_key_retrieve--;
+                  if (!res)
+                    rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
+                  free_keyserver_spec (spec);
 
-                   if(!rc)
-                     break;
-                 }
-             }
-         }
-      }
+                  if (!rc)
+                    break;
+                }
+            }
+        }
+    }
 
-    /* If the preferred keyserver thing above didn't work, our second
-       try is to use the URI from a DNS PKA record. */
-    if ( rc == G10ERR_NO_PUBKEY
-        && opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE
-         && opt.keyserver_options.options&KEYSERVER_HONOR_PKA_RECORD)
-      {
-        const char *uri = pka_uri_from_sig (sig);
+  /* If the preferred keyserver thing above didn't work, our second
+     try is to use the URI from a DNS PKA record. */
+  if (gpg_err_code (rc) == G10ERR_NO_PUBKEY
+      && (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE)
+      && (opt.keyserver_options.options & KEYSERVER_HONOR_PKA_RECORD))
+    {
+      const char *uri = pka_uri_from_sig (sig);
 
-        if (uri)
-          {
-            /* FIXME: We might want to locate the key using the
-               fingerprint instead of the keyid. */
-            int res;
-            struct keyserver_spec *spec;
+      if (uri)
+        {
+          /* FIXME: We might want to locate the key using the
+             fingerprint instead of the keyid. */
+          int res;
+          struct keyserver_spec *spec;
 
-            spec = parse_keyserver_uri (uri, 1, NULL, 0);
-            if (spec)
-              {
-                glo_ctrl.in_auto_key_retrieve++;
-                res = keyserver_import_keyid (sig->keyid, spec);
+          spec = parse_keyserver_uri (uri, 1, NULL, 0);
+          if (spec)
+            {
+              glo_ctrl.in_auto_key_retrieve++;
+              res = keyserver_import_keyid (c->ctrl, sig->keyid, spec);
                 glo_ctrl.in_auto_key_retrieve--;
                 free_keyserver_spec (spec);
                 if (!res)
-                  rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
-              }
-          }
-      }
+                  rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
+            }
+        }
+    }
 
-    /* If the preferred keyserver thing above didn't work and we got
+  /* If the preferred keyserver thing above didn't work and we got
        no information from the DNS PKA, this is a third try. */
 
-    if( rc == G10ERR_NO_PUBKEY && opt.keyserver
-       && opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
-      {
-       int res;
-
-       glo_ctrl.in_auto_key_retrieve++;
-       res=keyserver_import_keyid ( sig->keyid, opt.keyserver );
-       glo_ctrl.in_auto_key_retrieve--;
-       if(!res)
-         rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
-      }
+  if (gpg_err_code (rc) == G10ERR_NO_PUBKEY
+      && opt.keyserver
+      && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE))
+    {
+      int res;
 
-    if( !rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) {
-       KBNODE un, keyblock;
-       int count=0, statno;
-        char keyid_str[50];
-       PKT_public_key *pk=NULL;
-
-       if(rc)
-         statno=STATUS_BADSIG;
-       else if(sig->flags.expired)
-         statno=STATUS_EXPSIG;
-       else if(is_expkey)
-         statno=STATUS_EXPKEYSIG;
-       else if(is_revkey)
-         statno=STATUS_REVKEYSIG;
-       else
-         statno=STATUS_GOODSIG;
+      glo_ctrl.in_auto_key_retrieve++;
+      res=keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver );
+      glo_ctrl.in_auto_key_retrieve--;
+      if (!res)
+        rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
+    }
 
-       keyblock = get_pubkeyblock( sig->keyid );
+  if (!rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE)
+    {
+      kbnode_t un, keyblock;
+      int count = 0;
+      int statno;
+      char keyid_str[50];
+      PKT_public_key *pk = NULL;
+
+      if (rc)
+        statno = STATUS_BADSIG;
+      else if (sig->flags.expired)
+        statno = STATUS_EXPSIG;
+      else if (is_expkey)
+        statno = STATUS_EXPKEYSIG;
+      else if(is_revkey)
+        statno = STATUS_REVKEYSIG;
+      else
+        statno = STATUS_GOODSIG;
+
+      keyblock = get_pubkeyblock (sig->keyid);
+
+      snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX [uncertain] ",
+                (ulong)sig->keyid[0], (ulong)sig->keyid[1]);
+
+      /* Find and print the primary user ID.  */
+      for (un=keyblock; un; un = un->next)
+        {
+          int valid;
 
-        sprintf (keyid_str, "%08lX%08lX [uncertain] ",
-                 (ulong)sig->keyid[0], (ulong)sig->keyid[1]);
+          if (un->pkt->pkttype==PKT_PUBLIC_KEY)
+            {
+              pk=un->pkt->pkt.public_key;
+              continue;
+            }
+          if (un->pkt->pkttype != PKT_USER_ID)
+            continue;
+          if (!un->pkt->pkt.user_id->created)
+            continue;
+          if (un->pkt->pkt.user_id->is_revoked)
+            continue;
+          if (un->pkt->pkt.user_id->is_expired)
+            continue;
+          if (!un->pkt->pkt.user_id->is_primary)
+            continue;
+          /* We want the textual primary user ID here */
+          if (un->pkt->pkt.user_id->attrib_data)
+            continue;
 
-        /* find and print the primary user ID */
-       for( un=keyblock; un; un = un->next ) {
-           char *p;
-           int valid;
-           if(un->pkt->pkttype==PKT_PUBLIC_KEY)
-             {
-               pk=un->pkt->pkt.public_key;
-               continue;
-             }
-           if( un->pkt->pkttype != PKT_USER_ID )
-               continue;
-           if ( !un->pkt->pkt.user_id->created )
-               continue;
-            if ( un->pkt->pkt.user_id->is_revoked )
-                continue;
-            if ( un->pkt->pkt.user_id->is_expired )
-                continue;
-           if ( !un->pkt->pkt.user_id->is_primary )
-               continue;
-           /* We want the textual primary user ID here */
-           if ( un->pkt->pkt.user_id->attrib_data )
-               continue;
+          assert (pk);
 
-           assert(pk);
+          /* Get it before we print anything to avoid interrupting the
+             output with the "please do a --check-trustdb" line. */
+          valid = get_validity (pk, un->pkt->pkt.user_id);
 
-           /* Get it before we print anything to avoid interrupting
-              the output with the "please do a --check-trustdb"
-              line. */
-           valid=get_validity(pk,un->pkt->pkt.user_id);
+          keyid_str[17] = 0; /* cut off the "[uncertain]" part */
 
-            keyid_str[17] = 0; /* cut off the "[uncertain]" part */
-            write_status_text_and_buffer (statno, keyid_str,
-                                          un->pkt->pkt.user_id->name,
-                                          un->pkt->pkt.user_id->len,
-                                          -1 );
-
-           p=utf8_to_native(un->pkt->pkt.user_id->name,
-                            un->pkt->pkt.user_id->len,0);
-
-           if(rc)
-             log_info(_("BAD signature from \"%s\""),p);
-           else if(sig->flags.expired)
-             log_info(_("Expired signature from \"%s\""),p);
-           else
-             log_info(_("Good signature from \"%s\""),p);
+          print_good_bad_signature (statno, keyid_str, un, sig, rc);
 
-           xfree(p);
+          if ((opt.verify_options & VERIFY_SHOW_UID_VALIDITY))
+            log_printf (" [%s]\n",trust_value_to_string(valid));
+          else
+            log_printf ("\n");
 
-           if(opt.verify_options&VERIFY_SHOW_UID_VALIDITY)
-             log_printf (" [%s]\n",trust_value_to_string(valid));
-           else
-             log_printf ("\n");
-            count++;
+          pubkey_string (pk, pkstrbuf, sizeof pkstrbuf);
+          count++;
        }
-       if( !count ) {  /* just in case that we have no valid textual
-                           userid */
-           char *p;
 
-           /* Try for an invalid textual userid */
-            for( un=keyblock; un; un = un->next ) {
-                if( un->pkt->pkttype == PKT_USER_ID &&
-                   !un->pkt->pkt.user_id->attrib_data )
-                    break;
+      if (!count)  /* Just in case that we have no valid textual userid */
+        {
+          /* Try for an invalid textual userid */
+          for (un=keyblock; un; un = un->next)
+            {
+              if (un->pkt->pkttype == PKT_USER_ID
+                  && !un->pkt->pkt.user_id->attrib_data)
+                break;
             }
 
-           /* Try for any userid at all */
-           if(!un) {
-               for( un=keyblock; un; un = un->next ) {
-                    if( un->pkt->pkttype == PKT_USER_ID )
-                        break;
+          /* Try for any userid at all */
+          if (!un)
+            {
+              for (un=keyblock; un; un = un->next)
+                {
+                  if (un->pkt->pkttype == PKT_USER_ID)
+                    break;
                }
            }
 
-            if (opt.trust_model==TM_ALWAYS || !un)
-                keyid_str[17] = 0; /* cut off the "[uncertain]" part */
-
-            write_status_text_and_buffer (statno, keyid_str,
-                                          un? un->pkt->pkt.user_id->name:"[?]",
-                                          un? un->pkt->pkt.user_id->len:3,
-                                          -1 );
+          if (opt.trust_model==TM_ALWAYS || !un)
+            keyid_str[17] = 0; /* cut off the "[uncertain]" part */
 
-           if(un)
-             p=utf8_to_native(un->pkt->pkt.user_id->name,
-                               un->pkt->pkt.user_id->len,0);
-           else
-             p=xstrdup("[?]");
+          print_good_bad_signature (statno, keyid_str, un, sig, rc);
 
-           if(rc)
-             log_info(_("BAD signature from \"%s\""),p);
-           else if(sig->flags.expired)
-             log_info(_("Expired signature from \"%s\""),p);
-           else
-             log_info(_("Good signature from \"%s\""),p);
-            if (opt.trust_model!=TM_ALWAYS && un)
-              log_printf (" %s",_("[uncertain]") );
-           log_printf ("\n");
+          if (opt.trust_model != TM_ALWAYS && un)
+            log_printf (" %s",_("[uncertain]") );
+          log_printf ("\n");
        }
 
-        /* If we have a good signature and already printed
-         * the primary user ID, print all the other user IDs */
-        if ( count && !rc
-             && !(opt.verify_options&VERIFY_SHOW_PRIMARY_UID_ONLY)) {
-           char *p;
-            for( un=keyblock; un; un = un->next ) {
-                if( un->pkt->pkttype != PKT_USER_ID )
-                    continue;
-                if((un->pkt->pkt.user_id->is_revoked
-                   || un->pkt->pkt.user_id->is_expired)
-                  && !(opt.verify_options&VERIFY_SHOW_UNUSABLE_UIDS))
-                 continue;
-               /* Only skip textual primaries */
-                if ( un->pkt->pkt.user_id->is_primary &&
-                    !un->pkt->pkt.user_id->attrib_data )
-                   continue;
-
-               if(un->pkt->pkt.user_id->attrib_data)
-                 {
-                   dump_attribs(un->pkt->pkt.user_id,pk,NULL);
+      /* If we have a good signature and already printed
+       * the primary user ID, print all the other user IDs */
+      if (count
+          && !rc
+          && !(opt.verify_options & VERIFY_SHOW_PRIMARY_UID_ONLY))
+        {
+          char *p;
+          for( un=keyblock; un; un = un->next)
+            {
+              if (un->pkt->pkttype != PKT_USER_ID)
+                continue;
+              if ((un->pkt->pkt.user_id->is_revoked
+                   || un->pkt->pkt.user_id->is_expired)
+                  && !(opt.verify_options & VERIFY_SHOW_UNUSABLE_UIDS))
+                continue;
+              /* Only skip textual primaries */
+              if (un->pkt->pkt.user_id->is_primary
+                  && !un->pkt->pkt.user_id->attrib_data )
+                continue;
 
-                   if(opt.verify_options&VERIFY_SHOW_PHOTOS)
-                     show_photos(un->pkt->pkt.user_id->attribs,
-                                 un->pkt->pkt.user_id->numattribs,
-                                 pk,NULL,un->pkt->pkt.user_id);
-                 }
+              if (un->pkt->pkt.user_id->attrib_data)
+                {
+                  dump_attribs (un->pkt->pkt.user_id, pk);
 
-               p=utf8_to_native(un->pkt->pkt.user_id->name,
-                                un->pkt->pkt.user_id->len,0);
-               log_info(_("                aka \"%s\""),p);
-               xfree(p);
+                  if (opt.verify_options&VERIFY_SHOW_PHOTOS)
+                    show_photos (un->pkt->pkt.user_id->attribs,
+                                 un->pkt->pkt.user_id->numattribs,
+                                 pk ,un->pkt->pkt.user_id);
+                }
 
-               if(opt.verify_options&VERIFY_SHOW_UID_VALIDITY)
-                 {
-                   const char *valid;
-                   if(un->pkt->pkt.user_id->is_revoked)
-                     valid=_("revoked");
-                   else if(un->pkt->pkt.user_id->is_expired)
-                     valid=_("expired");
-                   else
-                     valid=trust_value_to_string(get_validity(pk,
-                                                              un->pkt->
-                                                              pkt.user_id));
-                   log_printf (" [%s]\n",valid);
-                 }
-               else
-                 log_printf ("\n");
+              p = utf8_to_native (un->pkt->pkt.user_id->name,
+                                 un->pkt->pkt.user_id->len, 0);
+              log_info (_("                aka \"%s\""), p);
+              xfree (p);
+
+              if ((opt.verify_options & VERIFY_SHOW_UID_VALIDITY))
+                {
+                  const char *valid;
+
+                  if (un->pkt->pkt.user_id->is_revoked)
+                    valid = _("revoked");
+                  else if (un->pkt->pkt.user_id->is_expired)
+                    valid = _("expired");
+                  else
+                    valid = (trust_value_to_string
+                             (get_validity (pk, un->pkt->pkt.user_id)));
+                  log_printf (" [%s]\n",valid);
+                }
+              else
+                log_printf ("\n");
             }
        }
-       release_kbnode( keyblock );
+      release_kbnode( keyblock );
 
-       if( !rc )
-         {
-           if(opt.verify_options&VERIFY_SHOW_POLICY_URLS)
-             show_policy_url(sig,0,1);
-           else
-             show_policy_url(sig,0,2);
-
-           if(opt.verify_options&VERIFY_SHOW_KEYSERVER_URLS)
-             show_keyserver_url(sig,0,1);
-           else
-             show_keyserver_url(sig,0,2);
+      if (!rc)
+        {
+          if ((opt.verify_options & VERIFY_SHOW_POLICY_URLS))
+            show_policy_url (sig, 0, 1);
+          else
+            show_policy_url (sig, 0, 2);
+
+          if ((opt.verify_options & VERIFY_SHOW_KEYSERVER_URLS))
+            show_keyserver_url (sig, 0, 1);
+          else
+            show_keyserver_url (sig, 0, 2);
+
+          if ((opt.verify_options & VERIFY_SHOW_NOTATIONS))
+            show_notation
+              (sig, 0, 1,
+               (((opt.verify_options&VERIFY_SHOW_STD_NOTATIONS)?1:0)
+                + ((opt.verify_options&VERIFY_SHOW_USER_NOTATIONS)?2:0)));
+          else
+            show_notation (sig, 0, 2, 0);
+        }
 
-           if(opt.verify_options&VERIFY_SHOW_NOTATIONS)
-             show_notation(sig,0,1,
-                       ((opt.verify_options&VERIFY_SHOW_STD_NOTATIONS)?1:0)+
-                       ((opt.verify_options&VERIFY_SHOW_USER_NOTATIONS)?2:0));
-           else
-             show_notation(sig,0,2,0);
-         }
+      if (!rc && is_status_enabled ())
+        {
+          /* Print a status response with the fingerprint. */
+          PKT_public_key *vpk = xmalloc_clear (sizeof *vpk);
 
-       if( !rc && is_status_enabled() ) {
-           /* print a status response with the fingerprint */
-           PKT_public_key *vpk = xmalloc_clear( sizeof *vpk );
-
-           if( !get_pubkey( vpk, sig->keyid ) ) {
-               byte array[MAX_FINGERPRINT_LEN], *p;
-               char buf[MAX_FINGERPRINT_LEN*4+90], *bufp;
-               size_t i, n;
-
-                bufp = buf;
-               fingerprint_from_pk( vpk, array, &n );
-               p = array;
-               for(i=0; i < n ; i++, p++, bufp += 2)
-                    sprintf(bufp, "%02X", *p );
-               /* TODO: Replace the reserved '0' in the field below
-                  with bits for status flags (policy url, notation,
-                  etc.).  Remember to make the buffer larger to
-                  match! */
-               sprintf(bufp, " %s %lu %lu %d 0 %d %d %02X ",
-                        strtimestamp( sig->timestamp ),
-                        (ulong)sig->timestamp,(ulong)sig->expiredate,
-                       sig->version,sig->pubkey_algo,sig->digest_algo,
-                       sig->sig_class);
-                bufp = bufp + strlen (bufp);
-                if (!vpk->is_primary) {
-                   u32 akid[2];
-
-                   akid[0] = vpk->main_keyid[0];
-                   akid[1] = vpk->main_keyid[1];
-                   free_public_key (vpk);
-                   vpk = xmalloc_clear( sizeof *vpk );
-                   if (get_pubkey (vpk, akid)) {
-                     /* impossible error, we simply return a zeroed out fpr */
-                     n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20;
-                     memset (array, 0, n);
-                   }
-                   else
-                     fingerprint_from_pk( vpk, array, &n );
+          if (!get_pubkey (vpk, sig->keyid))
+            {
+              byte array[MAX_FINGERPRINT_LEN], *p;
+              char buf[MAX_FINGERPRINT_LEN*4+90], *bufp;
+              size_t i, n;
+
+              bufp = buf;
+              fingerprint_from_pk (vpk, array, &n);
+              p = array;
+              for(i=0; i < n ; i++, p++, bufp += 2)
+                sprintf (bufp, "%02X", *p );
+              /* TODO: Replace the reserved '0' in the field below
+                 with bits for status flags (policy url, notation,
+                 etc.).  Remember to make the buffer larger to match! */
+              sprintf (bufp, " %s %lu %lu %d 0 %d %d %02X ",
+                       strtimestamp( sig->timestamp ),
+                       (ulong)sig->timestamp,(ulong)sig->expiredate,
+                       sig->version,sig->pubkey_algo,sig->digest_algo,
+                       sig->sig_class);
+              bufp = bufp + strlen (bufp);
+              if (!vpk->flags.primary)
+                {
+                  u32 akid[2];
+
+                  akid[0] = vpk->main_keyid[0];
+                  akid[1] = vpk->main_keyid[1];
+                  free_public_key (vpk);
+                  vpk = xmalloc_clear (sizeof *vpk);
+                  if (get_pubkey (vpk, akid))
+                    {
+                      /* Impossible error, we simply return a zeroed out fpr */
+                      n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20;
+                      memset (array, 0, n);
+                    }
+                  else
+                    fingerprint_from_pk( vpk, array, &n );
                 }
-               p = array;
-               for(i=0; i < n ; i++, p++, bufp += 2)
-                    sprintf(bufp, "%02X", *p );
-               write_status_text( STATUS_VALIDSIG, buf );
+              p = array;
+              for (i=0; i < n ; i++, p++, bufp += 2)
+                sprintf(bufp, "%02X", *p );
+              write_status_text (STATUS_VALIDSIG, buf);
            }
-           free_public_key( vpk );
+          free_public_key (vpk);
        }
 
-       if (!rc)
-          {
-           if(opt.verify_options&VERIFY_PKA_LOOKUPS)
-             pka_uri_from_sig (sig); /* Make sure PKA info is available. */
-           rc = check_signatures_trust( sig );
-          }
-
-       if(sig->flags.expired)
-         {
-           log_info(_("Signature expired %s\n"),
-                    asctimestamp(sig->expiredate));
-           rc=G10ERR_GENERAL; /* need a better error here? */
-         }
-       else if(sig->expiredate)
-         log_info(_("Signature expires %s\n"),asctimestamp(sig->expiredate));
-
-       if(opt.verbose)
-         log_info(_("%s signature, digest algorithm %s\n"),
-                  sig->sig_class==0x00?_("binary"):
-                  sig->sig_class==0x01?_("textmode"):_("unknown"),
-                  gcry_md_algo_name (sig->digest_algo));
-
-        if (!rc && !c->signed_data.used)
-          {
-            /* Signature is basically good but we test whether the
-               deprecated command
-                 gpg --verify FILE.sig
-               was used instead of
-                 gpg --verify FILE.sig FILE
-               to verify a detached signature.  If we figure out that a
-               data file with a matching name exists, we print a warning.
-
-               The problem is that the first form would also verify a
-               standard signature.  This behavior could be used to
-               create a made up .sig file for a tarball by creating a
-               standard signature from a valid detached signature packet
-               (for example from a signed git tag).  Then replace the
-               sig file on the FTP server along with a changed tarball.
-               Using the first form the verify command would correctly
-               verify the signature but don't even consider the tarball.  */
-            kbnode_t n;
-            char *dfile;
-
-            dfile = get_matching_datafile (c->sigfilename);
-            if (dfile)
-              {
-                for (n = c->list; n; n = n->next)
-                  if (n->pkt->pkttype != PKT_SIGNATURE)
-                    break;
-                if (n)
-                  {
-                    /* Not only signature packets in the tree thus this
-                       is not a detached signature.  */
-                    log_info (_("WARNING: not a detached signature; "
-                                "file '%s' was NOT verified!\n"), dfile);
-                  }
-                xfree (dfile);
-              }
-          }
+      if (!rc)
+        {
+          if ((opt.verify_options & VERIFY_PKA_LOOKUPS))
+            pka_uri_from_sig (sig); /* Make sure PKA info is available. */
+          rc = check_signatures_trust (sig);
+        }
 
-       if( rc )
-           g10_errors_seen = 1;
-       if( opt.batch && rc )
-           g10_exit(1);
+      if (sig->flags.expired)
+        {
+          log_info (_("Signature expired %s\n"), asctimestamp(sig->expiredate));
+          rc = G10ERR_GENERAL; /* need a better error here? */
+        }
+      else if (sig->expiredate)
+        log_info (_("Signature expires %s\n"), asctimestamp(sig->expiredate));
+
+      if (opt.verbose)
+        log_info (_("%s signature, digest algorithm %s%s%s\n"),
+                  sig->sig_class==0x00?_("binary"):
+                  sig->sig_class==0x01?_("textmode"):_("unknown"),
+                  gcry_md_algo_name (sig->digest_algo),
+                  *pkstrbuf?_(", key algorithm "):"",
+                  pkstrbuf);
+
+      if (rc)
+        g10_errors_seen = 1;
+      if (opt.batch && rc)
+        g10_exit (1);
     }
-    else {
-       char buf[50];
-       sprintf(buf, "%08lX%08lX %d %d %02x %lu %d",
-                    (ulong)sig->keyid[0], (ulong)sig->keyid[1],
-                    sig->pubkey_algo, sig->digest_algo,
-                    sig->sig_class, (ulong)sig->timestamp, rc );
-       write_status_text( STATUS_ERRSIG, buf );
-       if( rc == G10ERR_NO_PUBKEY ) {
-           buf[16] = 0;
-           write_status_text( STATUS_NO_PUBKEY, buf );
+  else
+    {
+      char buf[50];
+
+      snprintf (buf, sizeof buf, "%08lX%08lX %d %d %02x %lu %d",
+                (ulong)sig->keyid[0], (ulong)sig->keyid[1],
+                sig->pubkey_algo, sig->digest_algo,
+                sig->sig_class, (ulong)sig->timestamp, rc);
+      write_status_text (STATUS_ERRSIG, buf);
+      if (gpg_err_code (rc) == G10ERR_NO_PUBKEY)
+        {
+          buf[16] = 0;
+          write_status_text (STATUS_NO_PUBKEY, buf);
        }
-       if( rc != G10ERR_NOT_PROCESSED )
-           log_error(_("Can't check signature: %s\n"), g10_errstr(rc) );
+      if (gpg_err_code (rc) != G10ERR_NOT_PROCESSED)
+        log_error (_("Can't check signature: %s\n"), g10_errstr(rc));
     }
-    return rc;
+
+  return rc;
 }
 
 
@@ -2168,7 +2133,8 @@ proc_tree( CTX c, KBNODE node )
            if( !opt.pgp2_workarounds )
                ;
            else if( sig->digest_algo == DIGEST_ALGO_MD5
-                    && is_RSA( sig->pubkey_algo ) ) {
+                    && is_RSA( sig->pubkey_algo)
+                     && opt.flags.allow_weak_digest_algos) {
                /* enable a workaround for a pgp2 bug */
                 if (gcry_md_open (&c->mfx.md2, DIGEST_ALGO_MD5, 0))
                   BUG ();
@@ -2181,16 +2147,17 @@ proc_tree( CTX c, KBNODE node )
               if (gcry_md_open (&c->mfx.md2, sig->digest_algo, 0 ))
                 BUG ();
            }
-#if 0 /* workaround disabled */
-           /* Here we have another hack to work around a pgp 2 bug
-            * It works by not using the textmode for detached signatures;
-            * this will let the first signature check (on md) fail
-            * but the second one (on md2) which adds an extra CR should
-            * then produce the "correct" hash.  This is very, very ugly
-            * hack but it may help in some cases (and break others)
-            */
-                   /*  c->mfx.md2? 0 :(sig->sig_class == 0x01) */
-#endif
+
+           /* Here we used to have another hack to work around a pgp
+            * 2 bug: It worked by not using the textmode for detached
+            * signatures; this would let the first signature check
+            * (on md) fail but the second one (on md2), which adds an
+            * extra CR would then have produced the "correct" hash.
+            * This is very, very ugly hack but it may haved help in
+            * some cases (and break others).
+            *   c->mfx.md2? 0 :(sig->sig_class == 0x01)
+             */
+
             if ( DBG_HASHING ) {
                 gcry_md_debug( c->mfx.md, "verify" );
                 if ( c->mfx.md2  )
index a005164..708bdcd 100644 (file)
@@ -72,4 +72,3 @@ free_md_filter_context( md_filter_context_t *mfx )
     mfx->md2 = NULL;
     mfx->maxbuf_size = 0;
 }
-
diff --git a/g10/migrate.c b/g10/migrate.c
new file mode 100644 (file)
index 0000000..96ca5c2
--- /dev/null
@@ -0,0 +1,118 @@
+/* migrate.c - Migrate from earlier GnupG versions.
+ * Copyright (C) 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "gpg.h"
+#include "options.h"
+#include "keydb.h"
+#include "util.h"
+#include "main.h"
+#include "call-agent.h"
+
+
+#ifdef HAVE_DOSISH_SYSTEM
+# define V21_MIGRATION_FNAME "gpg-v21-migrated"
+#else
+# define V21_MIGRATION_FNAME ".gpg-v21-migrated"
+#endif
+
+
+/* Check whether a default secring.gpg from GnuPG < 2.1 exists and
+   import it if not yet done.  */
+void
+migrate_secring (ctrl_t ctrl)
+{
+  dotlock_t lockhd = NULL;
+  char *secring = NULL;
+  char *flagfile = NULL;
+  char *agent_version = NULL;
+
+  secring = make_filename (opt.homedir, "secring" EXTSEP_S "gpg", NULL);
+  if (access (secring, F_OK))
+    goto leave; /* Does not exist or is not readable.  */
+  flagfile = make_filename (opt.homedir, V21_MIGRATION_FNAME, NULL);
+  if (!access (flagfile, F_OK))
+    goto leave; /* Does exist - fine.  */
+
+  log_info ("starting migration from earlier GnuPG versions\n");
+
+  lockhd = dotlock_create (flagfile, 0);
+  if (!lockhd)
+    {
+      log_error ("can't allocate lock for '%s': %s\n",
+                 flagfile, gpg_strerror (gpg_error_from_syserror ()));
+      goto leave;
+    }
+  if (dotlock_take (lockhd, -1))
+    {
+      log_error ("can't lock '%s': %s\n",
+                 flagfile, gpg_strerror (gpg_error_from_syserror ()));
+      dotlock_destroy (lockhd);
+      lockhd = NULL;
+      goto leave;
+    }
+
+  if (!agent_get_version (ctrl, &agent_version))
+    {
+      if (!gnupg_compare_version (agent_version, "2.1.0"))
+        {
+          log_error ("error: GnuPG agent version \"%s\" is too old. ",
+                     agent_version);
+          log_info ("Please make sure that a recent gpg-agent is running.\n");
+          log_info ("(restarting the user session may achieve this.)\n");
+          log_info ("migration aborted\n");
+          xfree (agent_version);
+          goto leave;
+        }
+      xfree (agent_version);
+    }
+  else
+    {
+      log_error ("error: GnuPG agent unusable. "
+                 "Please check that a GnuPG agent can be started.\n");
+      log_error ("migration aborted\n");
+      goto leave;
+    }
+
+  log_info ("porting secret keys from '%s' to gpg-agent\n", secring);
+  if (!import_old_secring (ctrl, secring))
+    {
+      FILE *fp = fopen (flagfile, "w");
+      if (!fp || fclose (fp))
+        log_error ("error creating flag file '%s': %s\n",
+                   flagfile, gpg_strerror (gpg_error_from_syserror ()));
+      else
+        log_info ("migration succeeded\n");
+    }
+
+ leave:
+  if (lockhd)
+    {
+      dotlock_release (lockhd);
+      dotlock_destroy (lockhd);
+    }
+  xfree (flagfile);
+  xfree (secring);
+}
index 4df2488..c47d6dc 100644 (file)
@@ -1,6 +1,7 @@
 /* misc.c - miscellaneous functions
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- *               2008, 2009 Free Software Foundation, Inc.
+ *               2008, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -67,6 +68,7 @@
 #include "call-agent.h"
 #include "i18n.h"
 
+#include <assert.h>
 
 static int
 string_count_chr (const char *string, int c)
@@ -109,9 +111,9 @@ register_secured_file (const char *fname)
 
   /* Note that we stop immediatley if something goes wrong here. */
   if (stat (fname, &buf))
-    log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname,
+    log_fatal (_("fstat of '%s' failed in %s: %s\n"), fname,
                "register_secured_file", strerror (errno));
-/*   log_debug ("registering `%s' i=%lu.%lu\n", fname, */
+/*   log_debug ("registering '%s' i=%lu.%lu\n", fname, */
 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
   for (sf=secured_files; sf; sf = sf->next)
     {
@@ -139,11 +141,11 @@ unregister_secured_file (const char *fname)
 
   if (stat (fname, &buf))
     {
-      log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
+      log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
                  "unregister_secured_file", strerror (errno));
       return;
     }
-/*   log_debug ("unregistering `%s' i=%lu.%lu\n", fname,  */
+/*   log_debug ("unregistering '%s' i=%lu.%lu\n", fname,  */
 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
   for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
     {
@@ -215,7 +217,7 @@ is_secured_filename (const char *fname)
     {
       if (errno == ENOENT || errno == EPERM || errno == EACCES)
         return 0;
-      log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
+      log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
                  "is_secured_filename", strerror (errno));
       return 1;
     }
@@ -276,8 +278,19 @@ checksum_mpi (gcry_mpi_t a)
   return csum;
 }
 
+u32
+buffer_to_u32( const byte *buffer )
+{
+    unsigned long a;
+    a =  *buffer << 24;
+    a |= buffer[1] << 16;
+    a |= buffer[2] << 8;
+    a |= buffer[3];
+    return a;
+}
+
 void
-print_pubkey_algo_note( int algo )
+print_pubkey_algo_note (pubkey_algo_t algo)
 {
   if(algo >= 100 && algo <= 110)
     {
@@ -285,18 +298,20 @@ print_pubkey_algo_note( int algo )
       if(!warn)
        {
          warn=1;
+          es_fflush (es_stdout);
          log_info (_("WARNING: using experimental public key algorithm %s\n"),
                    openpgp_pk_algo_name (algo));
        }
     }
-  else if (algo == 20)
+  else if (algo == PUBKEY_ALGO_ELGAMAL)
     {
+      es_fflush (es_stdout);
       log_info (_("WARNING: Elgamal sign+encrypt keys are deprecated\n"));
     }
 }
 
 void
-print_cipher_algo_note( int algo )
+print_cipher_algo_note (cipher_algo_t algo)
 {
   if(algo >= 100 && algo <= 110)
     {
@@ -304,6 +319,7 @@ print_cipher_algo_note( int algo )
       if(!warn)
        {
          warn=1;
+          es_fflush (es_stdout);
          log_info (_("WARNING: using experimental cipher algorithm %s\n"),
                     openpgp_cipher_algo_name (algo));
        }
@@ -311,7 +327,7 @@ print_cipher_algo_note( int algo )
 }
 
 void
-print_digest_algo_note( int algo )
+print_digest_algo_note (digest_algo_t algo)
 {
   if(algo >= 100 && algo <= 110)
     {
@@ -319,13 +335,17 @@ print_digest_algo_note( int algo )
       if(!warn)
        {
          warn=1;
+          es_fflush (es_stdout);
          log_info (_("WARNING: using experimental digest algorithm %s\n"),
                     gcry_md_algo_name (algo));
        }
     }
   else if(algo==DIGEST_ALGO_MD5)
-    log_info (_("WARNING: digest algorithm %s is deprecated\n"),
-              gcry_md_algo_name (algo));
+    {
+      es_fflush (es_stdout);
+      log_info (_("WARNING: digest algorithm %s is deprecated\n"),
+                gcry_md_algo_name (algo));
+    }
 }
 
 
@@ -336,7 +356,7 @@ print_md5_rejected_note (void)
 
   if (!shown)
     {
-      fflush (stdout);
+      es_fflush (es_stdout);
       log_info
         (_("Note: signatures using the %s algorithm are rejected\n"),
          "MD5");
@@ -348,35 +368,118 @@ print_md5_rejected_note (void)
 /* Map OpenPGP algo numbers to those used by Libgcrypt.  We need to do
    this for algorithms we implemented in Libgcrypt after they become
    part of OpenPGP.  */
-int
-map_cipher_openpgp_to_gcry (int algo)
+enum gcry_cipher_algos
+map_cipher_openpgp_to_gcry (cipher_algo_t algo)
 {
   switch (algo)
     {
-    case CIPHER_ALGO_CAMELLIA128: return 310;
-    case CIPHER_ALGO_CAMELLIA192: return 311;
-    case CIPHER_ALGO_CAMELLIA256: return 312;
-    default: return algo;
+    case CIPHER_ALGO_NONE:        return GCRY_CIPHER_NONE;
+
+#ifdef GPG_USE_IDEA
+    case CIPHER_ALGO_IDEA:        return GCRY_CIPHER_IDEA;
+#else
+    case CIPHER_ALGO_IDEA:        return 0;
+#endif
+
+    case CIPHER_ALGO_3DES:       return GCRY_CIPHER_3DES;
+
+#ifdef GPG_USE_CAST5
+    case CIPHER_ALGO_CAST5:      return GCRY_CIPHER_CAST5;
+#else
+    case CIPHER_ALGO_CAST5:      return 0;
+#endif
+
+#ifdef GPG_USE_BLOWFISH
+    case CIPHER_ALGO_BLOWFISH:    return GCRY_CIPHER_BLOWFISH;
+#else
+    case CIPHER_ALGO_BLOWFISH:    return 0;
+#endif
+
+#ifdef GPG_USE_AES128
+    case CIPHER_ALGO_AES:         return GCRY_CIPHER_AES;
+#else
+    case CIPHER_ALGO_AES:         return 0;
+#endif
+
+#ifdef GPG_USE_AES192
+    case CIPHER_ALGO_AES192:      return GCRY_CIPHER_AES192;
+#else
+    case CIPHER_ALGO_AES192:      return 0;
+#endif
+
+#ifdef GPG_USE_AES256
+    case CIPHER_ALGO_AES256:      return GCRY_CIPHER_AES256;
+#else
+    case CIPHER_ALGO_AES256:      return 0;
+#endif
+
+#ifdef GPG_USE_TWOFISH
+    case CIPHER_ALGO_TWOFISH:     return GCRY_CIPHER_TWOFISH;
+#else
+    case CIPHER_ALGO_TWOFISH:     return 0;
+#endif
+
+#ifdef GPG_USE_CAMELLIA128
+    case CIPHER_ALGO_CAMELLIA128: return GCRY_CIPHER_CAMELLIA128;
+#else
+    case CIPHER_ALGO_CAMELLIA128: return 0;
+#endif
+
+#ifdef GPG_USE_CAMELLIA192
+    case CIPHER_ALGO_CAMELLIA192: return GCRY_CIPHER_CAMELLIA192;
+#else
+    case CIPHER_ALGO_CAMELLIA192: return 0;
+#endif
+
+#ifdef GPG_USE_CAMELLIA256
+    case CIPHER_ALGO_CAMELLIA256: return GCRY_CIPHER_CAMELLIA256;
+#else
+    case CIPHER_ALGO_CAMELLIA256: return 0;
+#endif
     }
+  return 0;
 }
 
-/* The inverse fucntion of above.  */
-static int
-map_cipher_gcry_to_openpgp (int algo)
+/* The inverse function of above.  */
+static cipher_algo_t
+map_cipher_gcry_to_openpgp (enum gcry_cipher_algos algo)
 {
   switch (algo)
     {
-    case 310: return CIPHER_ALGO_CAMELLIA128;
-    case 311: return CIPHER_ALGO_CAMELLIA192;
-    case 312: return CIPHER_ALGO_CAMELLIA256;
-    default: return algo;
+    case GCRY_CIPHER_NONE:        return CIPHER_ALGO_NONE;
+    case GCRY_CIPHER_IDEA:        return CIPHER_ALGO_IDEA;
+    case GCRY_CIPHER_3DES:        return CIPHER_ALGO_3DES;
+    case GCRY_CIPHER_CAST5:       return CIPHER_ALGO_CAST5;
+    case GCRY_CIPHER_BLOWFISH:    return CIPHER_ALGO_BLOWFISH;
+    case GCRY_CIPHER_AES:         return CIPHER_ALGO_AES;
+    case GCRY_CIPHER_AES192:      return CIPHER_ALGO_AES192;
+    case GCRY_CIPHER_AES256:      return CIPHER_ALGO_AES256;
+    case GCRY_CIPHER_TWOFISH:     return CIPHER_ALGO_TWOFISH;
+    case GCRY_CIPHER_CAMELLIA128: return CIPHER_ALGO_CAMELLIA128;
+    case GCRY_CIPHER_CAMELLIA192: return CIPHER_ALGO_CAMELLIA192;
+    case GCRY_CIPHER_CAMELLIA256: return CIPHER_ALGO_CAMELLIA256;
+    default: return 0;
+    }
+}
+
+/* Map Gcrypt public key algorithm numbers to those used by OpenPGP.
+   FIXME: This mapping is used at only two places - we should get rid
+   of it.  */
+pubkey_algo_t
+map_pk_gcry_to_openpgp (enum gcry_pk_algos algo)
+{
+  switch (algo)
+    {
+    case GCRY_PK_ECDSA:  return PUBKEY_ALGO_ECDSA;
+    case GCRY_PK_ECDH:   return PUBKEY_ALGO_ECDH;
+    default: return algo < 110 ? algo : 0;
     }
 }
 
 
 /* Return the block length of an OpenPGP cipher algorithm.  */
 int
-openpgp_cipher_blocklen (int algo)
+openpgp_cipher_blocklen (cipher_algo_t algo)
 {
   /* We use the numbers from OpenPGP to be sure that we get the right
      block length.  This is so that the packet parsing code works even
@@ -387,9 +490,13 @@ openpgp_cipher_blocklen (int algo)
      size. */
   switch (algo)
     {
-    case 7: case 8: case 9: /* AES */
-    case 10: /* Twofish */
-    case 11: case 12: case 13: /* Camellia */
+    case CIPHER_ALGO_AES:
+    case CIPHER_ALGO_AES192:
+    case CIPHER_ALGO_AES256:
+    case CIPHER_ALGO_TWOFISH:
+    case CIPHER_ALGO_CAMELLIA128:
+    case CIPHER_ALGO_CAMELLIA192:
+    case CIPHER_ALGO_CAMELLIA256:
       return 16;
 
     default:
@@ -402,82 +509,105 @@ openpgp_cipher_blocklen (int algo)
  * the OpenPGP contraints for the algo ID.
  */
 int
-openpgp_cipher_test_algo( int algo )
+openpgp_cipher_test_algo (cipher_algo_t algo)
 {
-  /* (5 and 6 are marked reserved by rfc4880.)  */
-  if ( algo < 0 || algo > 110 || algo == 5 || algo == 6 )
+  enum gcry_cipher_algos ga;
+
+  ga = map_cipher_openpgp_to_gcry (algo);
+  if (!ga)
     return gpg_error (GPG_ERR_CIPHER_ALGO);
 
-  return gcry_cipher_test_algo (map_cipher_openpgp_to_gcry (algo));
+  return gcry_cipher_test_algo (ga);
 }
 
 /* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
    string representation of the algorithm name.  For unknown algorithm
    IDs this function returns "?".  */
 const char *
-openpgp_cipher_algo_name (int algo)
-{
-  return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
-}
-
-
-/* Map OpenPGP public key algorithm numbers to those used by
-   Libgcrypt.  */
-int
-map_pk_openpgp_to_gcry (int algo)
+openpgp_cipher_algo_name (cipher_algo_t algo)
 {
   switch (algo)
     {
-    case PUBKEY_ALGO_ECDSA:     return 301 /*GCRY_PK_ECDSA*/;
-    case PUBKEY_ALGO_ECDH:      return 302 /*GCRY_PK_ECDH*/;
-    case PUBKEY_ALGO_ELGAMAL_E: return GCRY_PK_ELG;
-    default: return algo;
+    case CIPHER_ALGO_NONE:        break;
+    case CIPHER_ALGO_IDEA:        return "IDEA";
+    case CIPHER_ALGO_3DES:       return "3DES";
+    case CIPHER_ALGO_CAST5:      return "CAST5";
+    case CIPHER_ALGO_BLOWFISH:    return "BLOWFISH";
+    case CIPHER_ALGO_AES:         return "AES";
+    case CIPHER_ALGO_AES192:      return "AES192";
+    case CIPHER_ALGO_AES256:      return "AES256";
+    case CIPHER_ALGO_TWOFISH:     return "TWOFISH";
+    case CIPHER_ALGO_CAMELLIA128: return "CAMELLIA128";
+    case CIPHER_ALGO_CAMELLIA192: return "CAMELLIA192";
+    case CIPHER_ALGO_CAMELLIA256: return "CAMELLIA256";
     }
+  return "?";
 }
 
 
+/* Return 0 if ALGO is a supported OpenPGP public key algorithm.  */
 int
-openpgp_pk_test_algo( int algo )
+openpgp_pk_test_algo (pubkey_algo_t algo)
 {
-  /* ECC is not yet supported even if supported by Libgcrypt.  */
-  if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
-    return gpg_error (GPG_ERR_PUBKEY_ALGO);
-
-  /* Dont't allow type 20 keys unless in rfc2440 mode.  */
-  if (!RFC2440 && algo == 20)
-    return gpg_error (GPG_ERR_PUBKEY_ALGO);
-
-  if (algo == PUBKEY_ALGO_ELGAMAL_E)
-    algo = GCRY_PK_ELG;
-
-  if (algo < 0 || algo > 110)
-    return gpg_error (GPG_ERR_PUBKEY_ALGO);
-  return gcry_pk_test_algo (map_pk_openpgp_to_gcry (algo));
+  return openpgp_pk_test_algo2 (algo, 0);
 }
 
+
+/* Return 0 if ALGO is a supported OpenPGP public key algorithm and
+   allows the usage USE.  */
 int
-openpgp_pk_test_algo2( int algo, unsigned int use )
+openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
 {
+  enum gcry_pk_algos ga = 0;
   size_t use_buf = use;
 
-  /* ECC is not yet supported even if supported by Libgcrypt.  */
-  if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
-    return gpg_error (GPG_ERR_PUBKEY_ALGO);
+  switch (algo)
+    {
+#ifdef GPG_USE_RSA
+    case PUBKEY_ALGO_RSA:       ga = GCRY_PK_RSA;   break;
+    case PUBKEY_ALGO_RSA_E:     ga = GCRY_PK_RSA_E; break;
+    case PUBKEY_ALGO_RSA_S:     ga = GCRY_PK_RSA_S; break;
+#else
+    case PUBKEY_ALGO_RSA:       break;
+    case PUBKEY_ALGO_RSA_E:     break;
+    case PUBKEY_ALGO_RSA_S:     break;
+#endif
 
-  /* Dont't allow type 20 keys unless in rfc2440 mode.  */
-  if (!RFC2440 && algo == 20)
-    return gpg_error (GPG_ERR_PUBKEY_ALGO);
+    case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG;   break;
+    case PUBKEY_ALGO_DSA:       ga = GCRY_PK_DSA;   break;
+
+#ifdef GPG_USE_ECDH
+    case PUBKEY_ALGO_ECDH:      ga = GCRY_PK_ECC;   break;
+#else
+    case PUBKEY_ALGO_ECDH:      break;
+#endif
 
-  if (algo == PUBKEY_ALGO_ELGAMAL_E)
-    algo = GCRY_PK_ELG;
+#ifdef GPG_USE_ECDSA
+    case PUBKEY_ALGO_ECDSA:     ga = GCRY_PK_ECC;   break;
+#else
+    case PUBKEY_ALGO_ECDSA:     break;
+#endif
+
+#ifdef GPG_USE_EDDSA
+    case PUBKEY_ALGO_EDDSA:     ga = GCRY_PK_ECC;   break;
+#else
+    case PUBKEY_ALGO_EDDSA:     break;
+#endif
 
-  if (algo < 0 || algo > 110)
+    case PUBKEY_ALGO_ELGAMAL:
+      /* Dont't allow type 20 keys unless in rfc2440 mode.  */
+      if (RFC2440)
+        ga = GCRY_PK_ELG;
+      break;
+    }
+  if (!ga)
     return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
-  return gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo),
-                            GCRYCTL_TEST_ALGO, NULL, &use_buf);
+  /* No check whether Libgcrypt has support for the algorithm.  */
+  return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
 }
 
+
 int
 openpgp_pk_algo_usage ( int algo )
 {
@@ -490,6 +620,7 @@ openpgp_pk_algo_usage ( int algo )
                  | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
           break;
       case PUBKEY_ALGO_RSA_E:
+      case PUBKEY_ALGO_ECDH:
           use = PUBKEY_USAGE_ENC;
           break;
       case PUBKEY_ALGO_RSA_S:
@@ -505,75 +636,132 @@ openpgp_pk_algo_usage ( int algo )
       case PUBKEY_ALGO_DSA:
           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
           break;
-      case PUBKEY_ALGO_ECDH:
-          use = PUBKEY_USAGE_ENC;
-          break;
       case PUBKEY_ALGO_ECDSA:
+      case PUBKEY_ALGO_EDDSA:
           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
-          break;
       default:
           break;
     }
     return use;
 }
 
-
-/* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
+/* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a
    string representation of the algorithm name.  For unknown algorithm
    IDs this function returns "?".  */
 const char *
-openpgp_pk_algo_name (int algo)
+openpgp_pk_algo_name (pubkey_algo_t algo)
 {
-  return gcry_pk_algo_name (map_pk_openpgp_to_gcry (algo));
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:     return "RSA";
+    case PUBKEY_ALGO_ELGAMAL:
+    case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
+    case PUBKEY_ALGO_DSA:       return "DSA";
+    case PUBKEY_ALGO_ECDH:      return "ECDH";
+    case PUBKEY_ALGO_ECDSA:     return "ECDSA";
+    case PUBKEY_ALGO_EDDSA:     return "EDDSA";
+    }
+  return "?";
 }
 
 
+/* Explicit mapping of OpenPGP digest algos to Libgcrypt.  */
+/* FIXME: We do not yes use it everywhere.  */
+enum gcry_md_algos
+map_md_openpgp_to_gcry (digest_algo_t algo)
+{
+  switch (algo)
+    {
+#ifdef GPG_USE_MD5
+    case DIGEST_ALGO_MD5:    return GCRY_MD_MD5;
+#else
+    case DIGEST_ALGO_MD5:    return 0;
+#endif
+
+    case DIGEST_ALGO_SHA1:   return GCRY_MD_SHA1;
+
+#ifdef GPG_USE_RMD160
+    case DIGEST_ALGO_RMD160: return GCRY_MD_RMD160;
+#else
+    case DIGEST_ALGO_RMD160: return 0;
+#endif
+
+#ifdef GPG_USE_SHA224
+    case DIGEST_ALGO_SHA224: return GCRY_MD_SHA224;
+#else
+    case DIGEST_ALGO_SHA224: return 0;
+#endif
+
+    case DIGEST_ALGO_SHA256: return GCRY_MD_SHA256;
+
+#ifdef GPG_USE_SHA384
+    case DIGEST_ALGO_SHA384: return GCRY_MD_SHA384;
+#else
+    case DIGEST_ALGO_SHA384: return 0;
+#endif
+
+#ifdef GPG_USE_SHA512
+    case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
+#else
+    case DIGEST_ALGO_SHA512: return 0;
+#endif
+    }
+  return 0;
+}
+
+
+/* Return 0 if ALGO is suitable and implemented OpenPGP hash
+   algorithm.  */
 int
-openpgp_md_test_algo( int algo )
+openpgp_md_test_algo (digest_algo_t algo)
 {
-  /* Note: If the list of actual supported OpenPGP algorithms changes,
-     make sure that our hard coded values at
-     print_status_begin_signing() gets updated. */
-  /* 4, 5, 6, 7 are defined by rfc2440 but will be removed from the
-     next revision of the standard.  */
-  if (algo < 0 || algo > 110 || (algo >= 4 && algo <= 7))
+  enum gcry_md_algos ga;
+
+  ga = map_md_openpgp_to_gcry (algo);
+  if (!ga)
     return gpg_error (GPG_ERR_DIGEST_ALGO);
-  return gcry_md_test_algo (algo);
+
+  return gcry_md_test_algo (ga);
 }
 
-#ifdef USE_IDEA
-/* Special warning for the IDEA cipher */
-void
-idea_cipher_warn(int show)
-{
-  static int warned=0;
 
-  if(!warned || show)
+/* Map the OpenPGP digest algorithm whose ID is contained in ALGO to a
+   string representation of the algorithm name.  For unknown algorithm
+   IDs this function returns "?".  */
+const char *
+openpgp_md_algo_name (int algo)
+{
+  switch (algo)
     {
-      log_info(_("the IDEA cipher plugin is not present\n"));
-      log_info(_("please see %s for more information\n"),
-               "https://gnupg.org/faq/why-not-idea.html");
-      warned=1;
+    case DIGEST_ALGO_MD5:    return "MD5";
+    case DIGEST_ALGO_SHA1:   return "SHA1";
+    case DIGEST_ALGO_RMD160: return "RIPEMD160";
+    case DIGEST_ALGO_SHA256: return "SHA256";
+    case DIGEST_ALGO_SHA384: return "SHA384";
+    case DIGEST_ALGO_SHA512: return "SHA512";
+    case DIGEST_ALGO_SHA224: return "SHA224";
     }
+  return "?";
 }
-#endif
 
 
 static unsigned long
-get_signature_count (PKT_secret_key *sk)
+get_signature_count (PKT_public_key *pk)
 {
 #ifdef ENABLE_CARD_SUPPORT
-  if(sk && sk->is_protected && sk->protect.s2k.mode==1002)
-    {
-      struct agent_card_info_s info;
-      if(agent_scd_getattr("SIG-COUNTER",&info)==0)
-       return info.sig_counter;
-    }
-#endif
-
-  /* How to do this without a card? */
+  struct agent_card_info_s info;
 
+  (void)pk;
+  if (!agent_scd_getattr ("SIG-COUNTER",&info))
+    return info.sig_counter;
+  else
+    return 0;
+#else
+  (void)pk;
   return 0;
+#endif
 }
 
 /* Expand %-strings.  Returns a string which must be xfreed.  Returns
@@ -589,13 +777,13 @@ pct_expando(const char *string,struct expando_args *args)
   if(args->pk)
     keyid_from_pk(args->pk,pk_keyid);
 
-  if(args->sk)
-    keyid_from_sk(args->sk,sk_keyid);
+  if(args->pksk)
+    keyid_from_pk (args->pksk, sk_keyid);
 
   /* This is used so that %k works in photoid command strings in
      --list-secret-keys (which of course has a sk, but no pk). */
-  if(!args->pk && args->sk)
-    keyid_from_sk(args->sk,pk_keyid);
+  if(!args->pk && args->pksk)
+    keyid_from_pk (args->pksk, pk_keyid);
 
   while(*ch!='\0')
     {
@@ -673,7 +861,7 @@ pct_expando(const char *string,struct expando_args *args)
            case 'c': /* signature count from card, if any. */
              if(idx+10<maxlen)
                {
-                 sprintf(&ret[idx],"%lu",get_signature_count(args->sk));
+                 sprintf (&ret[idx],"%lu", get_signature_count (args->pksk));
                  idx+=strlen(&ret[idx]);
                  done=1;
                }
@@ -687,28 +875,31 @@ pct_expando(const char *string,struct expando_args *args)
                size_t len;
                int i;
 
-               if((*(ch+1))=='p' && args->sk)
+               if((*(ch+1))=='p' && args->pksk)
                  {
-                   if(args->sk->is_primary)
-                     fingerprint_from_sk(args->sk,array,&len);
-                   else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
+                   if(args->pksk->flags.primary)
+                     fingerprint_from_pk (args->pksk, array, &len);
+                   else if (args->pksk->main_keyid[0]
+                             || args->pksk->main_keyid[1])
                      {
+                        /* FIXME: Document teh code and check whether
+                           it is still needed.  */
                        PKT_public_key *pk=
                          xmalloc_clear(sizeof(PKT_public_key));
 
-                       if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
-                         fingerprint_from_pk(pk,array,&len);
+                       if (!get_pubkey_fast (pk,args->pksk->main_keyid))
+                         fingerprint_from_pk (pk, array, &len);
                        else
-                         memset(array,0,(len=MAX_FINGERPRINT_LEN));
-                       free_public_key(pk);
+                         memset (array, 0, (len=MAX_FINGERPRINT_LEN));
+                       free_public_key (pk);
                      }
                    else
                      memset(array,0,(len=MAX_FINGERPRINT_LEN));
                  }
                else if((*(ch+1))=='f' && args->pk)
-                 fingerprint_from_pk(args->pk,array,&len);
-               else if((*(ch+1))=='g' && args->sk)
-                 fingerprint_from_sk(args->sk,array,&len);
+                 fingerprint_from_pk (args->pk, array, &len);
+               else if((*(ch+1))=='g' && args->pksk)
+                 fingerprint_from_pk (args->pksk, array, &len);
                else
                  memset(array,0,(len=MAX_FINGERPRINT_LEN));
 
@@ -851,8 +1042,8 @@ obsolete_option (const char *configname, unsigned int configlineno,
     log_info (_("%s:%u: obsolete option \"%s\" - it has no effect\n"),
               configname, configlineno, name);
   else
-    log_info (_("WARNING: \"%s\" is an obsolete option - it has no effect\n"),
-              name);
+    log_info (_("WARNING: \"%s%s\" is an obsolete option - it has no effect\n"),
+              "--", name);
 }
 
 
@@ -861,12 +1052,13 @@ obsolete_scdaemon_option (const char *configname, unsigned int configlineno,
                           const char *name)
 {
   if (configname)
-    log_info (_("%s:%u: \"%s%s\" is obsolete in this file"
+    log_info (_("%s:%u: \"%s\" is obsolete in this file"
                 " - it only has effect in %s\n"),
-              configname, configlineno, name, "--", "scdaemon.conf");
+              configname, configlineno, name, SCDAEMON_NAME EXTSEP_S "conf");
   else
     log_info (_("WARNING: \"%s%s\" is an obsolete option"
-                " - it has no effect except on %s\n"), "--", name, "scdaemon");
+                " - it has no effect except on %s\n"),
+              "--", name, SCDAEMON_NAME);
 }
 
 
@@ -902,6 +1094,8 @@ string_to_digest_algo (const char *string)
 {
   int val;
 
+  /* FIXME: We should make use of our wrapper fucntion and not assume
+     that there is a 1 to 1 mapping between OpenPGP and Libgcrypt.  */
   val = gcry_md_map_name (string);
   if (!val && string && (string[0]=='H' || string[0]=='h'))
     {
@@ -982,15 +1176,18 @@ string_to_compress_algo(const char *string)
 int
 check_compress_algo(int algo)
 {
+  switch (algo)
+    {
+    case 0: return 0;
+#ifdef HAVE_ZIP
+    case 1:
+    case 2: return 0;
+#endif
 #ifdef HAVE_BZIP2
-  if(algo>=0 && algo<=3)
-    return 0;
-#else
-  if(algo>=0 && algo<=2)
-    return 0;
+    case 3: return 0;
 #endif
-
-  return G10ERR_COMPR_ALGO;
+    default: return G10ERR_COMPR_ALGO;
+    }
 }
 
 int
@@ -1028,8 +1225,6 @@ compliance_option_string(void)
     case CO_GNUPG:   return "--gnupg";
     case CO_RFC4880: return "--openpgp";
     case CO_RFC2440: return "--rfc2440";
-    case CO_RFC1991: return "--rfc1991";
-    case CO_PGP2:    return "--pgp2";
     case CO_PGP6:    return "--pgp6";
     case CO_PGP7:    return "--pgp7";
     case CO_PGP8:    return "--pgp8";
@@ -1057,14 +1252,6 @@ compliance_failure(void)
       ver="OpenPGP (older)";
       break;
 
-    case CO_RFC1991:
-      ver="old PGP";
-      break;
-
-    case CO_PGP2:
-      ver="PGP 2.x";
-      break;
-
     case CO_PGP6:
       ver="PGP 6.x";
       break;
@@ -1253,7 +1440,7 @@ parse_options(char *str,unsigned int *options,
                      if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
                        {
                          if(noisy)
-                           log_info(_("ambiguous option `%s'\n"),otok);
+                           log_info(_("ambiguous option '%s'\n"),otok);
                          return 0;
                        }
                    }
@@ -1278,7 +1465,7 @@ parse_options(char *str,unsigned int *options,
       if(!opts[i].name)
        {
          if(noisy)
-           log_info(_("unknown option `%s'\n"),otok);
+           log_info(_("unknown option '%s'\n"),otok);
          return 0;
        }
     }
@@ -1310,7 +1497,8 @@ has_invalid_email_chars (const char *s)
         continue; /* We only care about ASCII.  */
       if ( *s == '@' )
         at_seen=1;
-      else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
+      else if ( !at_seen && !(strchr (valid_chars, *s)
+                              || strchr ("!#$%&'*+/=?^`{|}~", *s)))
         return 1;
       else if ( at_seen && !strchr( valid_chars, *s ) )
         return 1;
@@ -1335,6 +1523,20 @@ is_valid_mailbox (const char *name)
 }
 
 
+/* Check whether UID is a valid standard user id of the form
+     "Heinrich Heine <heinrichh@duesseldorf.de>"
+   and return true if this is the case. */
+int
+is_valid_user_id (const char *uid)
+{
+  if (!uid || !*uid)
+    return 0;
+
+  return 1;
+}
+
+
+
 /* Similar to access(2), but uses PATH to find the file. */
 int
 path_access(const char *file,int mode)
@@ -1381,96 +1583,82 @@ path_access(const char *file,int mode)
 
 
 \f
-/* Temporary helper. */
+/* Return the number of public key parameters as used by OpenPGP.  */
 int
-pubkey_get_npkey( int algo )
+pubkey_get_npkey (pubkey_algo_t algo)
 {
-  size_t n;
-
-  /* ECC is special in that domain parameters are given by an OID.  */
-  if (algo == PUBKEY_ALGO_ECDSA)
-    return 0; /* We don't support the key format.  */
-  else if (algo == PUBKEY_ALGO_ECDH)
-    return 0; /* We don't support the key format.  */
-
-  if (algo == GCRY_PK_ELG_E)
-    algo = GCRY_PK_ELG;
-  else if (algo == GCRY_PK_RSA_E || algo == GCRY_PK_RSA_S)
-    algo = GCRY_PK_RSA;
-
-  if (gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo),
-                         GCRYCTL_GET_ALGO_NPKEY, NULL, &n))
-    n = 0;
-  return n;
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:     return 2;
+    case PUBKEY_ALGO_ELGAMAL_E: return 3;
+    case PUBKEY_ALGO_DSA:       return 4;
+    case PUBKEY_ALGO_ECDH:      return 3;
+    case PUBKEY_ALGO_ECDSA:     return 2;
+    case PUBKEY_ALGO_ELGAMAL:   return 3;
+    case PUBKEY_ALGO_EDDSA:     return 2;
+    }
+  return 0;
 }
 
-/* Temporary helper. */
+
+/* Return the number of secret key parameters as used by OpenPGP.  */
 int
-pubkey_get_nskey( int algo )
+pubkey_get_nskey (pubkey_algo_t algo)
 {
-  size_t n;
-
-  /* ECC is special in that domain parameters are given by an OID.  */
-  if (algo == PUBKEY_ALGO_ECDSA)
-    return 0; /* We don't support the key format.  */
-  else if (algo == PUBKEY_ALGO_ECDH)
-    return 0; /* We don't support the key format.  */
-
-  if (algo == GCRY_PK_ELG_E)
-    algo = GCRY_PK_ELG;
-  else if (algo == GCRY_PK_RSA_E || algo == GCRY_PK_RSA_S)
-    algo = GCRY_PK_RSA;
-
-  if (gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo),
-                         GCRYCTL_GET_ALGO_NSKEY, NULL, &n ))
-    n = 0;
-  return n;
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:     return 6;
+    case PUBKEY_ALGO_ELGAMAL_E: return 4;
+    case PUBKEY_ALGO_DSA:       return 5;
+    case PUBKEY_ALGO_ECDH:      return 4;
+    case PUBKEY_ALGO_ECDSA:     return 3;
+    case PUBKEY_ALGO_ELGAMAL:   return 4;
+    case PUBKEY_ALGO_EDDSA:     return 3;
+    }
+  return 0;
 }
 
 /* Temporary helper. */
 int
-pubkey_get_nsig( int algo )
+pubkey_get_nsig (pubkey_algo_t algo)
 {
-  size_t n;
-
-  /* ECC is special.  */
-  if (algo == PUBKEY_ALGO_ECDSA)
-    return 0;  /* We don't support the key format.  */
-  else if (algo == PUBKEY_ALGO_ECDH)
-    return 0;
-
-  if (algo == GCRY_PK_ELG_E)
-    algo = GCRY_PK_ELG;
-  else if (algo == GCRY_PK_RSA_E || algo == GCRY_PK_RSA_S)
-    algo = GCRY_PK_RSA;
-
-  if (gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo),
-                         GCRYCTL_GET_ALGO_NSIGN, NULL, &n))
-    n = 0;
-  return n;
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:     return 1;
+    case PUBKEY_ALGO_ELGAMAL_E: return 0;
+    case PUBKEY_ALGO_DSA:       return 2;
+    case PUBKEY_ALGO_ECDH:      return 0;
+    case PUBKEY_ALGO_ECDSA:     return 2;
+    case PUBKEY_ALGO_ELGAMAL:   return 2;
+    case PUBKEY_ALGO_EDDSA:     return 2;
+    }
+  return 0;
 }
 
+
 /* Temporary helper. */
 int
-pubkey_get_nenc( int algo )
+pubkey_get_nenc (pubkey_algo_t algo)
 {
-  size_t n;
-
-  /* ECC is special.  */
-  if (algo == PUBKEY_ALGO_ECDSA)
-    return 0;
-  else if (algo == PUBKEY_ALGO_ECDH)
-    return 0;  /* We don't support the key format.  */
-
-  if (algo == GCRY_PK_ELG_E)
-    algo = GCRY_PK_ELG;
-  else if (algo == GCRY_PK_RSA_E || algo == GCRY_PK_RSA_S)
-    algo = GCRY_PK_RSA;
-
-  if (gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo),
-                         GCRYCTL_GET_ALGO_NENCR, NULL, &n ))
-    n = 0;
-  return n;
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:     return 1;
+    case PUBKEY_ALGO_ELGAMAL_E: return 2;
+    case PUBKEY_ALGO_DSA:       return 0;
+    case PUBKEY_ALGO_ECDH:      return 2;
+    case PUBKEY_ALGO_ECDSA:     return 0;
+    case PUBKEY_ALGO_ELGAMAL:   return 2;
+    case PUBKEY_ALGO_EDDSA:     return 0;
+    }
+  return 0;
 }
 
 
@@ -1478,61 +1666,110 @@ pubkey_get_nenc( int algo )
 unsigned int
 pubkey_nbits( int algo, gcry_mpi_t *key )
 {
-    int rc, nbits;
-    gcry_sexp_t sexp;
+  int rc, nbits;
+  gcry_sexp_t sexp;
 
-    if( algo == GCRY_PK_DSA ) {
-       rc = gcry_sexp_build ( &sexp, NULL,
-                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
-                                 key[0], key[1], key[2], key[3] );
+  if (algo == PUBKEY_ALGO_DSA
+      && key[0] && key[1] && key[2] && key[3])
+    {
+      rc = gcry_sexp_build (&sexp, NULL,
+                            "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                            key[0], key[1], key[2], key[3] );
+    }
+  else if ((algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
+           && key[0] && key[1] && key[2])
+    {
+      rc = gcry_sexp_build (&sexp, NULL,
+                            "(public-key(elg(p%m)(g%m)(y%m)))",
+                            key[0], key[1], key[2] );
     }
-    else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
-       rc = gcry_sexp_build ( &sexp, NULL,
-                             "(public-key(elg(p%m)(g%m)(y%m)))",
-                                 key[0], key[1], key[2] );
+  else if (is_RSA (algo)
+           && key[0] && key[1])
+    {
+      rc = gcry_sexp_build (&sexp, NULL,
+                            "(public-key(rsa(n%m)(e%m)))",
+                            key[0], key[1] );
     }
-    else if (algo == GCRY_PK_RSA
-             || algo == GCRY_PK_RSA_S
-             || algo == GCRY_PK_RSA_E ) {
-       rc = gcry_sexp_build ( &sexp, NULL,
-                             "(public-key(rsa(n%m)(e%m)))",
-                                 key[0], key[1] );
+  else if ((algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
+            || algo == PUBKEY_ALGO_EDDSA)
+           && key[0] && key[1])
+    {
+      char *curve = openpgp_oid_to_str (key[0]);
+      if (!curve)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = gcry_sexp_build (&sexp, NULL,
+                                "(public-key(ecc(curve%s)(q%m)))",
+                                curve, key[1]);
+          xfree (curve);
+        }
     }
-    else
-       return 0;
+  else
+    return 0;
 
-    if ( rc )
-       BUG ();
+  if (rc)
+    BUG ();
 
-    nbits = gcry_pk_get_nbits( sexp );
-    gcry_sexp_release( sexp );
-    return nbits;
+  nbits = gcry_pk_get_nbits (sexp);
+  gcry_sexp_release (sexp);
+  return nbits;
 }
 
 
 
-/* FIXME: Use gcry_mpi_print directly. */
 int
-mpi_print( FILE *fp, gcry_mpi_t a, int mode )
+mpi_print (estream_t fp, gcry_mpi_t a, int mode)
 {
-    int n=0;
-
-    if( !a )
-       return fprintf(fp, "[MPI_NULL]");
-    if( !mode ) {
-       unsigned int n1;
-       n1 = gcry_mpi_get_nbits(a);
-       n += fprintf(fp, "[%u bits]", n1);
+  int n=0;
+
+  if (!a)
+    return es_fprintf (fp, "[MPI_NULL]");
+  if (!mode)
+    {
+      unsigned int n1;
+      n1 = gcry_mpi_get_nbits(a);
+      n += es_fprintf (fp, "[%u bits]", n1);
+    }
+  else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    {
+      unsigned int nbits;
+      unsigned char *p = gcry_mpi_get_opaque (a, &nbits);
+      if (!p)
+        n += es_fprintf (fp, "[invalid opaque value]");
+      else
+        {
+          nbits = (nbits + 7)/8;
+          for (; nbits; nbits--, p++)
+            n += es_fprintf (fp, "%02X", *p);
+        }
     }
-    else {
-       unsigned char *buffer;
-
-       if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a))
-          BUG ();
-       fputs( buffer, fp );
-       n += strlen(buffer);
-       gcry_free( buffer );
+  else
+    {
+      unsigned char *buffer;
+
+      if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a))
+        BUG ();
+      es_fputs (buffer, fp);
+      n += strlen (buffer);
+      gcry_free (buffer);
     }
-    return n;
+  return n;
 }
 
+
+/* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
+   i.e.  04 <x> <y> */
+unsigned int
+ecdsa_qbits_from_Q (unsigned int qbits)
+{
+  if ((qbits%8) > 3)
+    {
+      log_error (_("ECDSA public key is expected to be in SEC encoding "
+                   "multiple of 8 bits\n"));
+      return 0;
+    }
+  qbits -= qbits%8;
+  qbits /= 2;
+  return qbits;
+}
index dc9dfd0..5a43648 100644 (file)
@@ -1,6 +1,6 @@
 /* openfile.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2005 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #define SKELEXT EXTSEP_S "skel"
 #endif
 
+#ifdef HAVE_W32_SYSTEM
+#define NAME_OF_DEV_NULL "nul"
+#else
+#define NAME_OF_DEV_NULL "/dev/null"
+#endif
+
+
 #if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
 #define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
 #else
 #define CMP_FILENAME(a,b) strcmp( (a), (b) )
 #endif
 
-#ifdef MKDIR_TAKES_ONE_ARG
-#undef mkdir
-#define mkdir(a,b) mkdir(a)
-#endif
 
 /* FIXME:  Implement opt.interactive. */
 
 int
 overwrite_filep( const char *fname )
 {
-    if( iobuf_is_pipe_filename (fname) )
-       return 1; /* Writing to stdout is always okay */
-
-    if( access( fname, F_OK ) )
-       return 1; /* does not exist */
-
-#ifndef HAVE_DOSISH_SYSTEM
-    if ( !strcmp ( fname, "/dev/null" ) )
-        return 1; /* does not do any harm */
-#endif
-#ifdef HAVE_W32_SYSTEM
-    if ( !strcmp ( fname, "nul" ) )
-        return 1;
-#endif
-
-    /* fixme: add some backup stuff in case of overwrite */
-    if( opt.answer_yes )
-       return 1;
-    if( opt.answer_no || opt.batch )
-       return 0;  /* do not overwrite */
-
-    tty_printf(_("File `%s' exists. "), fname);
-    if( cpr_enabled () )
-        tty_printf ("\n");
-    if( cpr_get_answer_is_yes("openfile.overwrite.okay",
-                              _("Overwrite? (y/N) ")) )
-       return 1;
-    return 0;
+  if ( iobuf_is_pipe_filename (fname) )
+    return 1; /* Writing to stdout is always okay.  */
+
+  if ( access( fname, F_OK ) )
+    return 1; /* Does not exist.  */
+
+  if ( !compare_filenames (fname, NAME_OF_DEV_NULL) )
+    return 1; /* Does not do any harm.  */
+
+  if (opt.answer_yes)
+    return 1;
+  if (opt.answer_no || opt.batch)
+    return 0;  /* Do not overwrite.  */
+
+  tty_printf (_("File '%s' exists. "), fname);
+  if (cpr_enabled ())
+    tty_printf ("\n");
+  if (cpr_get_answer_is_yes ("openfile.overwrite.okay",
+                             _("Overwrite? (y/N) ")) )
+    return 1;
+  return 0;
 }
 
 
@@ -109,7 +105,7 @@ make_outfile_name( const char *iname )
        return xstrdup("-");
 
     n = strlen(iname);
-    if( n > 4 && (    !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg")
+    if( n > 4 && (    !CMP_FILENAME(iname+n-4, EXTSEP_S GPGEXT_GPG)
                   || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
                   || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
                   || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) {
@@ -178,179 +174,175 @@ ask_outfile_name( const char *name, size_t namelen )
  * Mode 0 = use ".gpg"
  *     1 = use ".asc"
  *     2 = use ".sig"
+ *      3 = use ".rev"
+ *
+ * If INP_FD is not -1 the function simply creates an IOBUF for that
+ * file descriptor and ignore INAME and MODE.  Note that INP_FD won't
+ * be closed if the returned IOBUF is closed.  With RESTRICTEDPERM a
+ * file will be created with mode 700 if possible.
  */
 int
-open_outfile( const char *iname, int mode, IOBUF *a )
+open_outfile (int inp_fd, const char *iname, int mode, int restrictedperm,
+              iobuf_t *a)
 {
   int rc = 0;
 
   *a = NULL;
-  if( iobuf_is_pipe_filename (iname) && !opt.outfile ) {
-    *a = iobuf_create(NULL);
-    if( !*a ) {
-      rc = gpg_error_from_syserror ();
-      log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
+  if (inp_fd != -1)
+    {
+      char xname[64];
+
+      *a = iobuf_fdopen_nc (inp_fd, "wb");
+      if (!*a)
+        {
+          rc = gpg_error_from_syserror ();
+          snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
+          log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (rc));
+        }
+      else if (opt.verbose)
+        {
+          snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
+          log_info (_("writing to '%s'\n"), xname);
+        }
     }
-    else if( opt.verbose )
-      log_info(_("writing to stdout\n"));
-  }
-  else {
-    char *buf = NULL;
-    const char *name;
-
-    if ( opt.dry_run )
-      {
-#ifdef HAVE_W32_SYSTEM
-        name = "nul";
-#else
-        name = "/dev/null";
-#endif
-      }
-    else if( opt.outfile )
-      name = opt.outfile;
-    else {
+  else if (iobuf_is_pipe_filename (iname) && !opt.outfile)
+    {
+      *a = iobuf_create (NULL, 0);
+      if ( !*a )
+        {
+          rc = gpg_error_from_syserror ();
+          log_error (_("can't open '%s': %s\n"), "[stdout]", strerror(errno) );
+        }
+      else if ( opt.verbose )
+        log_info (_("writing to stdout\n"));
+    }
+  else
+    {
+      char *buf = NULL;
+      const char *name;
+
+      if (opt.dry_run)
+        name = NAME_OF_DEV_NULL;
+      else if (opt.outfile)
+        name = opt.outfile;
+      else
+        {
 #ifdef USE_ONLY_8DOT3
-      if (opt.mangle_dos_filenames)
+          if (opt.mangle_dos_filenames)
+            {
+              /* It is quite common for DOS systems to have only one
+                 dot in a filename.  If we have something like this,
+                 we simple replace the suffix except in cases where
+                 the suffix is larger than 3 characters and not the
+                 same as the new one.  We don't map the filenames to
+                 8.3 because this is a duty of the file system.  */
+              char *dot;
+              const char *newsfx;
+
+              newsfx = (mode==1 ? ".asc" :
+                        mode==2 ? ".sig" :
+                        mode==3 ? ".rev" : ".gpg");
+
+              buf = xmalloc (strlen(iname)+4+1);
+              strcpy (buf, iname);
+              dot = strchr (buf, '.' );
+              if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
+                   && CMP_FILENAME (newsfx, dot) )
+                strcpy (dot, newsfx);
+              else if (dot && !dot[1]) /* Do not duplicate a dot.  */
+                strcpy (dot, newsfx+1);
+              else
+                strcat (buf, newsfx);
+            }
+          if (!buf)
+#endif /* USE_ONLY_8DOT3 */
+            {
+              buf = xstrconcat (iname,
+                                (mode==1 ? EXTSEP_S "asc" :
+                                 mode==2 ? EXTSEP_S "sig" :
+                                 mode==3 ? EXTSEP_S "rev" :
+                                 /*     */ EXTSEP_S GPGEXT_GPG),
+                                NULL);
+            }
+          name = buf;
+        }
+
+      rc = 0;
+      while ( !overwrite_filep (name) )
         {
-          /* It is quite common DOS system to have only one dot in a
-           * a filename So if we have something like this, we simple
-           * replace the suffix execpt in cases where the suffix is
-           * larger than 3 characters and not the same as.
-           * We should really map the filenames to 8.3 but this tends to
-           * be more complicated and is probaly a duty of the filesystem
-           */
-          char *dot;
-          const char *newsfx = mode==1 ? ".asc" :
-                               mode==2 ? ".sig" : ".gpg";
-
-          buf = xmalloc(strlen(iname)+4+1);
-          strcpy(buf,iname);
-          dot = strchr(buf, '.' );
-          if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
-                                 && CMP_FILENAME(newsfx, dot) )
+          char *tmp = ask_outfile_name (NULL, 0);
+          if ( !tmp || !*tmp )
             {
-              strcpy(dot, newsfx );
+              xfree (tmp);
+              rc = gpg_error (GPG_ERR_EEXIST);
+              break;
             }
-          else if ( dot && !dot[1] ) /* don't duplicate a dot */
-            strcpy( dot, newsfx+1 );
-          else
-            strcat ( buf, newsfx );
+          xfree (buf);
+          name = buf = tmp;
         }
-      if (!buf)
-#endif /* USE_ONLY_8DOT3 */
+
+      if ( !rc )
         {
-          buf = xmalloc(strlen(iname)+4+1);
-          strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
-                                  mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
+          if (is_secured_filename (name) )
+            {
+              *a = NULL;
+              gpg_err_set_errno (EPERM);
+            }
+          else
+            *a = iobuf_create (name, restrictedperm);
+          if (!*a)
+            {
+              rc = gpg_error_from_syserror ();
+              log_error(_("can't create '%s': %s\n"), name, strerror(errno) );
+            }
+          else if( opt.verbose )
+            log_info (_("writing to '%s'\n"), name );
         }
-      name = buf;
+      xfree(buf);
     }
 
-    rc = 0;
-    while( !overwrite_filep (name) )
-      {
-        char *tmp = ask_outfile_name (NULL, 0);
-        if ( !tmp || !*tmp )
-          {
-            xfree (tmp);
-            rc = gpg_error (GPG_ERR_EEXIST);
-            break;
-          }
-        xfree (buf);
-        name = buf = tmp;
-      }
-
-    if( !rc )
-      {
-        if (is_secured_filename (name) )
-          {
-            *a = NULL;
-            errno = EPERM;
-          }
-        else
-          *a = iobuf_create( name );
-        if( !*a )
-          {
-            rc = gpg_error_from_syserror ();
-            log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
-          }
-        else if( opt.verbose )
-          log_info(_("writing to `%s'\n"), name );
-      }
-    xfree(buf);
-  }
-
   if (*a)
-    iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
+    iobuf_ioctl (*a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
 
   return rc;
 }
 
 
-/* Find a matching data file for the signature file SIGFILENAME and
-   return it as a malloced string.  If no matching data file is found,
-   return NULL.  */
-char *
-get_matching_datafile (const char *sigfilename)
-{
-  char *fname = NULL;
-  size_t len;
-
-  if (iobuf_is_pipe_filename (sigfilename))
-    return NULL;
-
-  len = strlen (sigfilename);
-  if (len > 4
-      && (!strcmp (sigfilename + len - 4, EXTSEP_S "sig")
-          || (len > 5 && !strcmp(sigfilename + len - 5, EXTSEP_S "sign"))
-          || !strcmp(sigfilename + len - 4, EXTSEP_S "asc")))
-    {
-
-      fname = xstrdup (sigfilename);
-      fname[len-(fname[len-1]=='n'?5:4)] = 0 ;
-      if (access (fname, R_OK ))
-        {
-          /* Not found or other error.  */
-          xfree (fname);
-          fname = NULL;
-        }
-    }
-
-  return fname;
-}
-
-
 /****************
  * Try to open a file without the extension ".sig" or ".asc"
  * Return NULL if such a file is not available.
  */
-iobuf_t
-open_sigfile (const char *sigfilename, progress_filter_context_t *pfx)
+IOBUF
+open_sigfile( const char *iname, progress_filter_context_t *pfx )
 {
-  iobuf_t a = NULL;
-  char *buf;
-
-  buf = get_matching_datafile (sigfilename);
-  if (buf)
-    {
-      a = iobuf_open (buf);
-      if (a && is_secured_file (iobuf_get_fd (a)))
-        {
-          iobuf_close (a);
-          a = NULL;
-          gpg_err_set_errno (EPERM);
-        }
-      if (a)
-        log_info (_("assuming signed data in '%s'\n"), buf);
-      if (a && pfx)
-        handle_progress (pfx, a, buf);
-      xfree (buf);
+    IOBUF a = NULL;
+    size_t len;
+
+    if( !iobuf_is_pipe_filename (iname) ) {
+       len = strlen(iname);
+       if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig")
+                        || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") )
+                        || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) {
+           char *buf;
+           buf = xstrdup(iname);
+           buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
+           a = iobuf_open( buf );
+            if (a && is_secured_file (iobuf_get_fd (a)))
+              {
+                iobuf_close (a);
+                a = NULL;
+                gpg_err_set_errno (EPERM);
+              }
+           if( a && opt.verbose )
+               log_info(_("assuming signed data in '%s'\n"), buf );
+           if (a && pfx)
+             handle_progress (pfx, a, buf);
+            xfree(buf);
+       }
     }
-
-  return a;
+    return a;
 }
 
-
 /****************
  * Copy the option file skeleton to the given directory.
  */
@@ -376,25 +368,25 @@ copy_options_file( const char *destdir )
       {
         fclose (src);
         src = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if( !src ) {
-       log_info (_("can't open `%s': %s\n"), fname, strerror(errno) );
+       log_info (_("can't open '%s': %s\n"), fname, strerror(errno) );
        xfree(fname);
        return;
     }
-    strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" );
+    strcpy(stpcpy(fname, destdir), DIRSEP_S GPGEXT_GPG EXTSEP_S "conf" );
     oldmask=umask(077);
     if ( is_secured_filename (fname) )
       {
         dst = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     else
       dst = fopen( fname, "w" );
     umask(oldmask);
     if( !dst ) {
-       log_info (_("can't create `%s': %s\n"), fname, strerror(errno) );
+       log_info (_("can't create '%s': %s\n"), fname, strerror(errno) );
        fclose( src );
        xfree(fname);
        return;
@@ -421,9 +413,9 @@ copy_options_file( const char *destdir )
     }
     fclose( dst );
     fclose( src );
-    log_info(_("new configuration file `%s' created\n"), fname );
+    log_info(_("new configuration file '%s' created\n"), fname );
     if (any_option)
-        log_info (_("WARNING: options in `%s'"
+        log_info (_("WARNING: options in '%s'"
                     " are not yet active during this run\n"),
                   fname);
     xfree(fname);
@@ -454,12 +446,32 @@ try_make_homedir (const char *fname)
 #endif
       )
     {
-      if ( mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
-        log_fatal ( _("can't create directory `%s': %s\n"),
+      if (gnupg_mkdir (fname, "-rwx"))
+        log_fatal ( _("can't create directory '%s': %s\n"),
                     fname, strerror(errno) );
       else if (!opt.quiet )
-        log_info ( _("directory `%s' created\n"), fname );
+        log_info ( _("directory '%s' created\n"), fname );
       copy_options_file( fname );
+    }
+}
+
+
+/* Get and if needed create a string with the directory used to store
+   openpgp revocations.  */
+char *
+get_openpgp_revocdir (const char *home)
+{
+  char *fname;
+  struct stat statbuf;
 
+  fname = make_filename (home, GNUPG_OPENPGP_REVOC_DIR, NULL);
+  if (stat (fname, &statbuf) && errno == ENOENT)
+    {
+      if (gnupg_mkdir (fname, "-rwx"))
+        log_error (_("can't create directory '%s': %s\n"),
+                   fname, strerror (errno) );
+      else if (!opt.quiet)
+        log_info (_("directory '%s' created\n"), fname);
     }
+  return fname;
 }
index b02c0d9..0875eb5 100644 (file)
@@ -1,6 +1,6 @@
 /* options.h
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ *               2007, 2010, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #endif
 #endif
 
+/* Declaration of a keyserver spec type.  The definition is found in
+   ../common/keyserver.h.  */
+struct keyserver_spec;
+typedef struct keyserver_spec *keyserver_spec_t;
+
+
+/* Global options for GPG.  */
 EXTERN_UNLESS_MAIN_MODULE
 struct
 {
@@ -43,6 +50,7 @@ struct
   unsigned debug;
   int armor;
   char *outfile;
+  estream_t outfp;  /* Hack, sometimes used in place of outfile.  */
   off_t max_output;
   int dry_run;
   int list_only;
@@ -58,14 +66,14 @@ struct
   int check_sigs; /* check key signatures */
   int with_colons;
   int with_key_data;
-  int with_fingerprint; /* opt --with-fingerprint active */
+  int with_fingerprint; /* Option --with-fingerprint active.  */
+  int with_keygrip;     /* Option --with-keygrip active.  */
+  int with_secret;      /* Option --with-secret active.  */
   int fingerprint; /* list fingerprints */
   int list_sigs;   /* list signatures */
   int no_armor;
-  int list_packets; /* Option --list-packets active.  */
+  int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/
   int def_cipher_algo;
-  int force_v3_sigs;
-  int force_v4_certs;
   int force_mdc;
   int disable_mdc;
   int def_digest_algo;
@@ -77,6 +85,8 @@ struct
   const char *def_secret_key;
   char *def_recipient;
   int def_recipient_self;
+  strlist_t secret_keys_to_try;
+
   int def_cert_level;
   int min_cert_level;
   int ask_cert_level;
@@ -90,6 +100,7 @@ struct
   int max_cert_depth;
   const char *homedir;
   const char *agent_program;
+  const char *dirmngr_program;
 
   /* Options to be passed to the gpg-agent */
   session_env_t session_env;
@@ -97,8 +108,8 @@ struct
   char *lc_messages;
 
   int skip_verify;
-  int compress_keys;
-  int compress_sigs;
+  int skip_hidden_recipients;
+
   /* TM_CLASSIC must be zero to accomodate trustdbs generated before
      we started storing the trust model inside the trustdb. */
   enum
@@ -108,7 +119,7 @@ struct
   int force_ownertrust;
   enum
     {
-      CO_GNUPG, CO_RFC4880, CO_RFC2440, CO_RFC1991, CO_PGP2,
+      CO_GNUPG, CO_RFC4880, CO_RFC2440,
       CO_PGP6, CO_PGP7, CO_PGP8
     } compliance;
   enum
@@ -126,27 +137,10 @@ struct
   int s2k_cipher_algo;
   unsigned char s2k_count; /* This is the encoded form, not the raw
                              count */
-  int simple_sk_checksum; /* create the deprecated rfc2440 secret key
-                            protection */
   int not_dash_escaped;
   int escape_from;
   int lock_once;
-  struct keyserver_spec
-  {
-    char *uri;
-    char *scheme;
-    char *auth;
-    char *host;
-    char *port;
-    char *path;
-    char *opaque;
-    strlist_t options;
-    struct
-    {
-      unsigned int direct_uri:1;
-    } flags;
-    struct keyserver_spec *next;
-  } *keyserver;
+  keyserver_spec_t keyserver;  /* The list of configured keyservers.  */
   struct
   {
     unsigned int options;
@@ -182,6 +176,7 @@ struct
   int no_literal;
   ulong set_filesize;
   int fast_list_mode;
+  int legacy_list_mode;
   int ignore_time_conflict;
   int ignore_valid_from;
   int ignore_crc_error;
@@ -194,6 +189,7 @@ struct
   int try_all_secrets;
   int no_expensive_trust_checks;
   int no_sig_cache;
+  int no_sig_create_check;
   int no_auto_check_trustdb;
   int preserve_permissions;
   int no_homedir_creation;
@@ -247,11 +243,12 @@ struct
       AKL_KEYSERVER,
       AKL_SPEC
     } type;
-    struct keyserver_spec *spec;
+    keyserver_spec_t spec;
     struct akl *next;
   } *auto_key_locate;
 
   int passphrase_repeat;
+  int pinentry_mode;
 } opt;
 
 /* CTRL is used to keep some global variables we currently can't
@@ -261,6 +258,11 @@ EXTERN_UNLESS_MAIN_MODULE
 struct {
   int in_auto_key_retrieve; /* True if we are doing an
                                auto_key_retrieve. */
+  /* Hack to store the last error.  We currently need it because the
+     proc_packet machinery is not able to reliabale return error
+     codes.  Thus for the --server purposes we store some of the error
+     codes here.  FIXME! */
+  gpg_error_t lasterr;
 } glo_ctrl;
 
 #define DBG_PACKET_VALUE  1    /* debug packet reading/writing */
@@ -276,6 +278,7 @@ struct {
 #define DBG_HASHING_VALUE 512  /* debug hashing operations */
 #define DBG_EXTPROG_VALUE 1024  /* debug external program calls */
 #define DBG_CARD_IO_VALUE 2048  /* debug smart card I/O.  */
+#define DBG_CLOCK_VALUE   4096
 
 /* Fixme: For now alias this value.  */
 #define DBG_ASSUAN_VALUE  DBG_EXTPROG_VALUE
@@ -291,6 +294,7 @@ struct {
 #define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE)
 #define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE)
 #define DBG_ASSUAN  (opt.debug & DBG_ASSUAN_VALUE)
+#define DBG_CLOCK   (opt.debug & DBG_CLOCK_VALUE)
 
 /* FIXME: We need to check whey we did not put this into opt. */
 #define DBG_MEMORY    memory_debug_mode
@@ -300,16 +304,14 @@ EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode;
 EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
 
 
-
+/* Compatibility flags.  */
 #define GNUPG   (opt.compliance==CO_GNUPG)
-#define RFC1991 (opt.compliance==CO_RFC1991 || opt.compliance==CO_PGP2)
 #define RFC2440 (opt.compliance==CO_RFC2440)
 #define RFC4880 (opt.compliance==CO_RFC4880)
-#define PGP2    (opt.compliance==CO_PGP2)
 #define PGP6    (opt.compliance==CO_PGP6)
 #define PGP7    (opt.compliance==CO_PGP7)
 #define PGP8    (opt.compliance==CO_PGP8)
-#define PGPX    (PGP2 || PGP6 || PGP7 || PGP8)
+#define PGPX    (PGP6 || PGP7 || PGP8)
 
 /* Various option flags.  Note that there should be no common string
    names between the IMPORT_ and EXPORT_ flags as they can be mixed in
@@ -318,12 +320,10 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
 #define IMPORT_LOCAL_SIGS                (1<<0)
 #define IMPORT_REPAIR_PKS_SUBKEY_BUG     (1<<1)
 #define IMPORT_FAST                      (1<<2)
-#define IMPORT_SK2PK                     (1<<3)
 #define IMPORT_MERGE_ONLY                (1<<4)
 #define IMPORT_MINIMAL                   (1<<5)
 #define IMPORT_CLEAN                     (1<<6)
 #define IMPORT_NO_SECKEY                 (1<<7)
-#define IMPORT_KEEP_OWNERTTRUST          (1<<8)
 
 #define EXPORT_LOCAL_SIGS                (1<<0)
 #define EXPORT_ATTRIBUTES                (1<<1)
@@ -345,6 +345,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
 #define LIST_SHOW_KEYRING                (1<<8)
 #define LIST_SHOW_SIG_EXPIRE             (1<<9)
 #define LIST_SHOW_SIG_SUBPACKETS         (1<<10)
+#define LIST_SHOW_USAGE                  (1<<11)
 
 #define VERIFY_SHOW_PHOTOS               (1<<0)
 #define VERIFY_SHOW_POLICY_URLS          (1<<1)
@@ -365,4 +366,5 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
 #define KEYSERVER_HONOR_KEYSERVER_URL    (1<<4)
 #define KEYSERVER_HONOR_PKA_RECORD       (1<<5)
 
+
 #endif /*G10_OPTIONS_H*/
index e21431b..20b5711 100644 (file)
@@ -2,8 +2,8 @@
 # the users home directory.
 # $Id$
 # Options for GnuPG
-# Copyright 1998, 1999, 2000, 2001, 2002, 2003,
-#           2010 Free Software Foundation, Inc.
+# Copyright 1998-2003, 2010 Free Software Foundation, Inc.
+# Copyright 1998-2003, 2010 Werner Koch
 #
 # This file is free software; as a special exception the author gives
 # unlimited permission to copy and/or distribute it, with or without
@@ -196,4 +196,3 @@ keyserver hkp://keys.gnupg.net
 #
 # Use your MIME handler to view photos:
 # photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG"
-
index cb2f0c9..ba43638 100644 (file)
 
 #include "types.h"
 #include "../common/iobuf.h"
-#include "../jnlib/strlist.h"
-#include "cipher.h"
+#include "../common/strlist.h"
+#include "dek.h"
 #include "filter.h"
 #include "../common/openpgpdefs.h"
+#include "../common/userids.h"
 
 #define DEBUG_PARSE_PACKET 1
 
 
+/* Constants to allocate static MPI arrays. */
+#define PUBKEY_MAX_NPKEY  5
+#define PUBKEY_MAX_NSKEY  7
+#define PUBKEY_MAX_NSIG   2
+#define PUBKEY_MAX_NENC   2
+
+/* Usage flags */
+#define PUBKEY_USAGE_SIG     GCRY_PK_USAGE_SIGN  /* Good for signatures. */
+#define PUBKEY_USAGE_ENC     GCRY_PK_USAGE_ENCR  /* Good for encryption. */
+#define PUBKEY_USAGE_CERT    GCRY_PK_USAGE_CERT  /* Also good to certify keys.*/
+#define PUBKEY_USAGE_AUTH    GCRY_PK_USAGE_AUTH  /* Good for authentication. */
+#define PUBKEY_USAGE_UNKNOWN GCRY_PK_USAGE_UNKN  /* Unknown usage flag. */
+#define PUBKEY_USAGE_NONE    256                 /* No usage given. */
+#if  (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR | GCRY_PK_USAGE_CERT \
+      | GCRY_PK_USAGE_AUTH | GCRY_PK_USAGE_UNKN) >= 256
+# error Please choose another value for PUBKEY_USAGE_NONE
+#endif
+
+/* Helper macros.  */
+#define is_RSA(a)     ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
+                      || (a)==PUBKEY_ALGO_RSA_S )
+#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL_E)
+#define is_DSA(a)     ((a)==PUBKEY_ALGO_DSA)
+
+/* A pointer to the packet object.  */
 typedef struct packet_struct PACKET;
 
 /* PKT_GPG_CONTROL types */
@@ -48,15 +74,16 @@ typedef enum {
 } preftype_t;
 
 typedef struct {
-    byte type; 
+    byte type;
     byte value;
 } prefitem_t;
 
-typedef struct {
-    int  mode;
-    byte hash_algo;
-    byte salt[8];
-    u32  count;
+typedef struct
+{
+  int  mode;      /* Must be an integer due to the GNU modes 1001 et al.  */
+  byte hash_algo;
+  byte salt[8];
+  u32  count;
 } STRING2KEY;
 
 typedef struct {
@@ -112,9 +139,9 @@ typedef struct
 
 
 /* Object to keep information pertaining to a signature. */
-typedef struct 
+typedef struct
 {
-  struct 
+  struct
   {
     unsigned checked:1;         /* Signature has been checked. */
     unsigned valid:1;           /* Signature is good (if checked is set). */
@@ -151,14 +178,16 @@ typedef struct
 
 #define ATTRIB_IMAGE 1
 
-/* This is the cooked form of attributes */
+/* This is the cooked form of attributes */
 struct user_attribute {
   byte type;
   const byte *data;
   u32 len;
 };
 
-typedef struct
+
+/* (See also keybox-search-desc.h) */
+struct gpg_pkt_user_id_s
 {
   int ref;              /* reference counter */
   int len;             /* length of the name */
@@ -181,12 +210,15 @@ typedef struct
   struct
   {
     /* TODO: Move more flags here */
-    unsigned mdc:1;
-    unsigned ks_modify:1;
-    unsigned compacted:1;
+    unsigned int mdc:1;
+    unsigned int ks_modify:1;
+    unsigned int compacted:1;
   } flags;
   char name[1];
-} PKT_user_id;
+};
+typedef struct gpg_pkt_user_id_s PKT_user_id;
+
+
 
 struct revoke_info
 {
@@ -198,82 +230,91 @@ struct revoke_info
   byte algo;
 };
 
+
+/* Information pertaining to secret keys. */
+struct seckey_info
+{
+  int is_protected:1;  /* The secret info is protected and must */
+                       /* be decrypted before use, the protected */
+                       /* MPIs are simply (void*) pointers to memory */
+                       /* and should never be passed to a mpi_xxx() */
+  int sha1chk:1;        /* SHA1 is used instead of a 16 bit checksum */
+  u16 csum;            /* Checksum for old protection modes.  */
+  byte algo;            /* Cipher used to protect the secret information. */
+  STRING2KEY s2k;       /* S2K parameter.  */
+  byte ivlen;           /* Used length of the IV.  */
+  byte iv[16];          /* Initialization vector for CFB mode.  */
+};
+
+
 /****************
- * Note about the pkey/skey elements:  We assume that the secret keys
- * has the same elemts as the public key at the begin of the array, so
- * that npkey < nskey and it is possible to compare the secret and
- * public keys by comparing the first npkey elements of pkey againts skey.
+ * We assume that secret keys have the same number of parameters as
+ * the public key and that the public parameters are the first items
+ * in the PKEY array.  Thus NPKEY is always less than NSKEY and it is
+ * possible to compare the secret and public keys by comparing the
+ * first NPKEY elements of the PKEY array.  Note that since GnuPG 2.1
+ * we don't use secret keys anymore directly because they are managed
+ * by gpg-agent.  However for parsing OpenPGP key files we need a way
+ * to temporary store those secret keys.  We do this by putting them
+ * into the public key structure and extending the PKEY field to NSKEY
+ * elements; the extra secret key information are stored in the
+ * SECKEY_INFO field.
  */
-typedef struct {
-    u32     timestamp;     /* key made */
-    u32     expiredate;     /* expires at this date or 0 if not at all */
-    u32     max_expiredate; /* must not expire past this date */
-    struct revoke_info revoked;
-    byte    hdrbytes;      /* number of header bytes */
-    byte    version;
-    byte    selfsigversion; /* highest version of all of the self-sigs */
-    byte    pubkey_algo;    /* algorithm used for public key scheme */
-    byte    pubkey_usage;   /* for now only used to pass it to getkey() */
-    byte    req_usage;      /* hack to pass a request to getkey() */
-    byte    req_algo;       /* Ditto */
-    u32     has_expired;    /* set to the expiration date if expired */ 
-    int     is_revoked;     /* key has been revoked, 1 if by the
-                              owner, 2 if by a designated revoker */
-    int     maybe_revoked;  /* a designated revocation is present, but
-                              without the key to check it */
-    int     is_valid;       /* key (especially subkey) is valid */
-    int     dont_cache;     /* do not cache this */
-    byte    backsig;        /* 0=none, 1=bad, 2=good */
-    u32     main_keyid[2];  /* keyid of the primary key */
-    u32     keyid[2];      /* calculated by keyid_from_pk() */
-    byte    is_primary;
-    byte    is_disabled;    /* 0 for unset, 1 for enabled, 2 for disabled. */
-    prefitem_t *prefs;      /* list of preferences (may be NULL) */
-    int     mdc_feature;    /* mdc feature set */
-    PKT_user_id *user_id;   /* if != NULL: found by that uid */
-    struct revocation_key *revkey;
-    int     numrevkeys;
-    u32     trust_timestamp;
-    byte    trust_depth;
-    byte    trust_value;
-    const byte *trust_regexp;
-    gcry_mpi_t     pkey[PUBKEY_MAX_NPKEY];
+typedef struct
+{
+  u32     timestamp;       /* key made */
+  u32     expiredate;     /* expires at this date or 0 if not at all */
+  u32     max_expiredate; /* must not expire past this date */
+  struct revoke_info revoked;
+  byte    hdrbytes;        /* number of header bytes */
+  byte    version;
+  byte    selfsigversion; /* highest version of all of the self-sigs */
+  byte    pubkey_algo;    /* algorithm used for public key scheme */
+  byte    pubkey_usage;   /* for now only used to pass it to getkey() */
+  byte    req_usage;      /* hack to pass a request to getkey() */
+  byte    req_algo;       /* Ditto */
+  u32     has_expired;    /* set to the expiration date if expired */
+  u32     main_keyid[2];  /* keyid of the primary key */
+  u32     keyid[2];        /* calculated by keyid_from_pk() */
+  prefitem_t *prefs;      /* list of preferences (may be NULL) */
+  struct
+  {
+    unsigned int mdc:1;           /* MDC feature set.  */
+    unsigned int disabled_valid:1;/* The next flag is valid.  */
+    unsigned int disabled:1;      /* The key has been disabled.  */
+    unsigned int primary:1;       /* This is a primary key.  */
+    unsigned int revoked:2;       /* Key has been revoked.
+                                     1 = revoked by the owner
+                                     2 = revoked by designated revoker.  */
+    unsigned int maybe_revoked:1; /* A designated revocation is
+                                     present, but without the key to
+                                     check it.  */
+    unsigned int valid:1;         /* Key (especially subkey) is valid.  */
+    unsigned int dont_cache:1;    /* Do not cache this key.  */
+    unsigned int backsig:2;       /* 0=none, 1=bad, 2=good.  */
+    unsigned int serialno_valid:1;/* SERIALNO below is valid.  */
+  } flags;
+  PKT_user_id *user_id;   /* If != NULL: found by that uid. */
+  struct revocation_key *revkey;
+  int     numrevkeys;
+  u32     trust_timestamp;
+  byte    trust_depth;
+  byte    trust_value;
+  const byte *trust_regexp;
+  char    *serialno;      /* Malloced hex string or NULL if it is
+                             likely not on a card.  See also
+                             flags.serialno_valid.  */
+  struct seckey_info *seckey_info;  /* If not NULL this malloced
+                                       structure describes a secret
+                                       key.  */
+  gcry_mpi_t  pkey[PUBKEY_MAX_NSKEY]; /* Right, NSKEY elements.  */
 } PKT_public_key;
 
 /* Evaluates as true if the pk is disabled, and false if it isn't.  If
    there is no disable value cached, fill one in. */
-#define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a))))
-
-typedef struct {
-    u32     timestamp;     /* key made */
-    u32     expiredate;     /* expires at this date or 0 if not at all */
-    u32     max_expiredate; /* must not expire past this date */
-    byte    hdrbytes;      /* number of header bytes */
-    byte    version;
-    byte    pubkey_algo;    /* algorithm used for public key scheme */
-    byte    pubkey_usage;
-    byte    req_usage;
-    byte    req_algo;
-    u32     has_expired;    /* set to the expiration date if expired */ 
-    int     is_revoked;     /* key has been revoked */
-    int     is_valid;       /* key (especially subkey) is valid */
-    u32     main_keyid[2];  /* keyid of the primary key */
-    u32     keyid[2];   
-    byte is_primary;
-    byte is_protected; /* The secret info is protected and must */
-                       /* be decrypted before use, the protected */
-                       /* MPIs are simply (void*) pointers to memory */
-                       /* and should never be passed to a mpi_xxx() */
-    struct {
-       byte algo;  /* cipher used to protect the secret information*/
-        byte sha1chk;  /* SHA1 is used instead of a 16 bit checksum */ 
-       STRING2KEY s2k;
-       byte ivlen;  /* used length of the iv */
-       byte iv[16]; /* initialization vector for CFB mode */
-    } protect;
-    gcry_mpi_t skey[PUBKEY_MAX_NSKEY];
-    u16 csum;          /* checksum */
-} PKT_secret_key;
+#define pk_is_disabled(a)                                       \
+  (((a)->flags.disabled_valid)?                                 \
+   ((a)->flags.disabled):(cache_disabled_value((a))))
 
 
 typedef struct {
@@ -289,8 +330,8 @@ typedef struct {
 } PKT_compressed;
 
 typedef struct {
-    u32  len;            /* length of encrypted data */
-    int  extralen;        /* this is (blocksize+2) */
+    u32  len;            /* Remaining length of encrypted data. */
+    int  extralen;        /* This is (blocksize+2).  Used by build_packet. */
     byte new_ctb;        /* uses a new CTB */
     byte is_partial;      /* partial length encoded */
     byte mdc_method;     /* > 0: integrity protected encrypted data packet */
@@ -333,7 +374,7 @@ struct packet_struct {
        PKT_onepass_sig *onepass_sig;   /* PKT_ONEPASS_SIG */
        PKT_signature   *signature;     /* PKT_SIGNATURE */
        PKT_public_key  *public_key;    /* PKT_PUBLIC_[SUB)KEY */
-       PKT_secret_key  *secret_key;    /* PKT_SECRET_[SUB]KEY */
+       PKT_public_key  *secret_key;    /* PKT_SECRET_[SUB]KEY */
        PKT_comment     *comment;       /* PKT_COMMENT */
        PKT_user_id     *user_id;       /* PKT_USER_ID */
        PKT_compressed  *compressed;    /* PKT_COMPRESSED */
@@ -367,11 +408,12 @@ struct notation
 
 /*-- mainproc.c --*/
 void reset_literals_seen(void);
-int proc_packets( void *ctx, iobuf_t a );
-int proc_signature_packets( void *ctx, iobuf_t a,
+int proc_packets (ctrl_t ctrl, void *ctx, iobuf_t a );
+int proc_signature_packets (ctrl_t ctrl, void *ctx, iobuf_t a,
                            strlist_t signedfiles, const char *sigfile );
-int proc_signature_packets_by_fd ( void *anchor, IOBUF a, int signed_data_fd );
-int proc_encryption_packets( void *ctx, iobuf_t a );
+int proc_signature_packets_by_fd (ctrl_t ctrl,
+                                  void *anchor, IOBUF a, int signed_data_fd );
+int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a);
 int list_packets( iobuf_t a );
 
 /*-- parse-packet.c --*/
@@ -427,6 +469,8 @@ PACKET *create_gpg_control ( ctrlpkttype_t type,
 
 /*-- build-packet.c --*/
 int build_packet( iobuf_t inp, PACKET *pkt );
+gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a);
+gpg_error_t gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a);
 u32 calc_packet_length( PACKET *pkt );
 void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
                        const byte *buffer, size_t buflen );
@@ -446,22 +490,16 @@ void free_seckey_enc( PKT_signature *enc );
 int  digest_algo_from_sig( PKT_signature *sig );
 void release_public_key_parts( PKT_public_key *pk );
 void free_public_key( PKT_public_key *key );
-void release_secret_key_parts( PKT_secret_key *sk );
-void free_secret_key( PKT_secret_key *sk );
 void free_attributes(PKT_user_id *uid);
 void free_user_id( PKT_user_id *uid );
 void free_comment( PKT_comment *rem );
 void free_packet( PACKET *pkt );
 prefitem_t *copy_prefs (const prefitem_t *prefs);
 PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
-void copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
-PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
 PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
 PKT_user_id *scopy_user_id (PKT_user_id *sd );
 int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
-int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
 int cmp_signatures( PKT_signature *a, PKT_signature *b );
-int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
 int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
 
 
@@ -470,21 +508,17 @@ int signature_check( PKT_signature *sig, gcry_md_hd_t digest );
 int signature_check2( PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
                      int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
 
-/*-- seckey-cert.c --*/
-int is_secret_key_protected( PKT_secret_key *sk );
-int check_secret_key( PKT_secret_key *sk, int retries );
-int protect_secret_key( PKT_secret_key *sk, DEK *dek );
 
 /*-- pubkey-enc.c --*/
-int get_session_key( PKT_pubkey_enc *k, DEK *dek );
-int get_override_session_key( DEK *dek, const char *string );
+gpg_error_t get_session_key (PKT_pubkey_enc *k, DEK *dek);
+gpg_error_t get_override_session_key (DEK *dek, const char *string);
 
 /*-- compress.c --*/
-int handle_compressed( void *ctx, PKT_compressed *cd,
+int handle_compressed (ctrl_t ctrl, void *ctx, PKT_compressed *cd,
                       int (*callback)(iobuf_t, void *), void *passthru );
 
 /*-- encr-data.c --*/
-int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek );
+int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek );
 
 /*-- plaintext.c --*/
 int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
@@ -495,16 +529,17 @@ int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
 /*-- sign.c --*/
 int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
                        PKT_user_id *uid, PKT_public_key *subpk,
-                       PKT_secret_key *sk, int sigclass, int digest_algo,
-                       int sigversion, u32 timestamp, u32 duration,
+                       PKT_public_key *pksk, int sigclass, int digest_algo,
+                       u32 timestamp, u32 duration,
                        int (*mksubpkt)(PKT_signature *, void *),
-                       void *opaque  );
+                       void *opaque,
+                        const char *cache_nonce);
 int update_keysig_packet( PKT_signature **ret_sig,
                       PKT_signature *orig_sig,
                       PKT_public_key *pk,
                       PKT_user_id *uid,
                       PKT_public_key *subpk,
-                      PKT_secret_key *sk,
+                      PKT_public_key *pksk,
                       int (*mksubpkt)(PKT_signature *, void *),
                       void *opaque   );
 
index 1030204..039f085 100644 (file)
@@ -1,6 +1,7 @@
 /* parse-packet.c  - read packets
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ *               2007, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include <assert.h>
 
 #include "gpg.h"
+#include "util.h"
 #include "packet.h"
 #include "iobuf.h"
-#include "util.h"
-#include "cipher.h"
 #include "filter.h"
 #include "photoid.h"
 #include "options.h"
 #include "main.h"
 #include "i18n.h"
-#include "host2net.h"
-
-
-/* Maximum length of packets to avoid excessive memory allocation.  */
-#define MAX_KEY_PACKET_LENGTH     (256 * 1024)
-#define MAX_UID_PACKET_LENGTH     (  2 * 1024)
-#define MAX_COMMENT_PACKET_LENGTH ( 64 * 1024)
-#define MAX_ATTR_PACKET_LENGTH    ( 16 * 1024*1024)
-
 
 static int mpi_print_mode;
 static int list_mode;
-static FILE *listfp;
+static estream_t listfp;
 
-static int  parse( IOBUF inp, PACKET *pkt, int onlykeypkts,
-                  off_t *retpos, int *skip, IOBUF out, int do_skip
+static int parse (IOBUF inp, PACKET * pkt, int onlykeypkts,
+                 off_t * retpos, int *skip, IOBUF out, int do_skip
 #ifdef DEBUG_PARSE_PACKET
-                  ,const char *dbg_w, const char *dbg_f, int dbg_l
+                 const char *dbg_w, const char *dbg_f, int dbg_l
 #endif
-                );
-static int  copy_packet( IOBUF inp, IOBUF out, int pkttype,
-                        unsigned long pktlen, int partial );
-static void skip_packetIOBUF inp, int pkttype,
-                        unsigned long pktlen, int partial );
-static void *read_rest( IOBUF inp, size_t pktlen, int partial );
-static int  parse_marker( IOBUF inp, int pkttype, unsigned long pktlen );
-static int  parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen,
-                                                            PACKET *packet );
-static int  parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen,
-                                                            PACKET *packet );
-static int  parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
-                                                       PKT_onepass_sig *ops );
-static int  parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
-                                     byte *hdr, int hdrlen, PACKET *packet );
-static int  parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
-                                                          PACKET *packet );
-static int  parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen,
-                                                          PACKET *packet );
-static int  parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
-                                                          PACKET *packet );
-static void parse_trustIOBUF inp, int pkttype, unsigned long pktlen,
-                                                          PACKET *packet );
-static int  parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
-                            PACKET *packet, int new_ctb, int partial);
-static int  parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
-                                              PACKET *packet, int new_ctb );
-static int  parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
-                            PACKET *packet, int new_ctb, int partial);
-static int  parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
-                                              PACKET *packet, int new_ctb);
-static int  parse_gpg_control( IOBUF inp, int pkttype, unsigned long pktlen,
-                               PACKET *packet, int partial );
+  );
+static int copy_packet (IOBUF inp, IOBUF out, int pkttype,
+                       unsigned long pktlen, int partial);
+static void skip_packet (IOBUF inp, int pkttype,
+                        unsigned long pktlen, int partial);
+static void *read_rest (IOBUF inp, size_t pktlen);
+static int parse_marker (IOBUF inp, int pkttype, unsigned long pktlen);
+static int parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
+                           PACKET * packet);
+static int parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
+                           PACKET * packet);
+static int parse_onepass_sig (IOBUF inp, int pkttype, unsigned long pktlen,
+                             PKT_onepass_sig * ops);
+static int parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
+                     byte * hdr, int hdrlen, PACKET * packet);
+static int parse_user_id (IOBUF inp, int pkttype, unsigned long pktlen,
+                         PACKET * packet);
+static int parse_attribute (IOBUF inp, int pkttype, unsigned long pktlen,
+                           PACKET * packet);
+static int parse_comment (IOBUF inp, int pkttype, unsigned long pktlen,
+                         PACKET * packet);
+static void parse_trust (IOBUF inp, int pkttype, unsigned long pktlen,
+                        PACKET * packet);
+static int parse_plaintext (IOBUF inp, int pkttype, unsigned long pktlen,
+                           PACKET * packet, int new_ctb, int partial);
+static int parse_compressed (IOBUF inp, int pkttype, unsigned long pktlen,
+                            PACKET * packet, int new_ctb);
+static int parse_encrypted (IOBUF inp, int pkttype, unsigned long pktlen,
+                           PACKET * packet, int new_ctb, int partial);
+static int parse_mdc (IOBUF inp, int pkttype, unsigned long pktlen,
+                     PACKET * packet, int new_ctb);
+static int parse_gpg_control (IOBUF inp, int pkttype, unsigned long pktlen,
+                             PACKET * packet, int partial);
 
 static unsigned short
-read_16(IOBUF inp)
+read_16 (IOBUF inp)
 {
-    unsigned short a;
-    a = (unsigned short)iobuf_get_noeof(inp) << 8;
-    a |= iobuf_get_noeof(inp);
-    return a;
+  unsigned short a;
+  a = iobuf_get_noeof (inp) << 8;
+  a |= iobuf_get_noeof (inp);
+  return a;
 }
 
+
 static unsigned long
-read_32(IOBUF inp)
+read_32 (IOBUF inp)
 {
-    unsigned long a;
-    a =  (unsigned long)iobuf_get_noeof(inp) << 24;
-    a |= iobuf_get_noeof(inp) << 16;
-    a |= iobuf_get_noeof(inp) << 8;
-    a |= iobuf_get_noeof(inp);
-    return a;
+  unsigned long a;
+  a = iobuf_get_noeof (inp) << 24;
+  a |= iobuf_get_noeof (inp) << 16;
+  a |= iobuf_get_noeof (inp) << 8;
+  a |= iobuf_get_noeof (inp);
+  return a;
 }
 
 
@@ -112,13 +104,10 @@ read_32(IOBUF inp)
  * external format is a 16 bit unsigned value stored in network byte
  * order, giving the number of bits for the following integer. The
  * integer is stored with MSB first (left padded with zeroes to align
- * on a byte boundary).
- */
+ * on a byte boundary).  */
 static gcry_mpi_t
 mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure)
 {
-  /*FIXME: Needs to be synced with gnupg14/mpi/mpicoder.c*/
-
   int c, c1, c2, i;
   unsigned int nmax = *ret_nread;
   unsigned int nbits, nbytes;
@@ -130,45 +119,36 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure)
   if (!nmax)
     goto overflow;
 
-  if ( (c = c1 = iobuf_get (inp)) == -1 )
+  if ((c = c1 = iobuf_get (inp)) == -1)
     goto leave;
   if (++nread == nmax)
     goto overflow;
   nbits = c << 8;
-  if ( (c = c2 = iobuf_get (inp)) == -1 )
+  if ((c = c2 = iobuf_get (inp)) == -1)
     goto leave;
   ++nread;
   nbits |= c;
-  if ( nbits > MAX_EXTERN_MPI_BITS )
+  if (nbits > MAX_EXTERN_MPI_BITS)
     {
-      log_error("mpi too large (%u bits)\n", nbits);
+      log_error ("mpi too large (%u bits)\n", nbits);
       goto leave;
     }
 
-  nbytes = (nbits+7) / 8;
+  nbytes = (nbits + 7) / 8;
   buf = secure ? gcry_xmalloc_secure (nbytes + 2) : gcry_xmalloc (nbytes + 2);
   p = buf;
   p[0] = c1;
   p[1] = c2;
-  for ( i=0 ; i < nbytes; i++ )
+  for (i = 0; i < nbytes; i++)
     {
-      p[i+2] = iobuf_get(inp) & 0xff;
+      p[i + 2] = iobuf_get (inp) & 0xff;
       if (nread == nmax)
         goto overflow;
       nread++;
     }
 
-  if (nread >= 2 && !(buf[0] << 8 | buf[1]))
-    {
-      /* Libgcrypt < 1.5.0 accidently rejects zero-length (i.e. zero)
-         MPIs.  We fix this here.  */
-      a = gcry_mpi_new (0);
-    }
-  else
-    {
-      if ( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) )
-        a = NULL;
-    }
+  if (gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buf, nread, &nread))
+    a = NULL;
 
   *ret_nread = nread;
   gcry_free(buf);
@@ -183,969 +163,1155 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure)
 }
 
 
-
-
 int
-set_packet_list_mode( int mode )
+set_packet_list_mode (int mode)
 {
-    int old = list_mode;
-    list_mode = mode;
-   /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */
-    /* We use stdout print only if invoked by the --list-packets
-       command but switch to stderr in all otehr cases.  This breaks
-       the previous behaviour but that seems to be more of a bug than
-       intentional.  I don't believe that any application makes use of
-       this long standing annoying way of printing to stdout except
-       when doing a --list-packets. If this assumption fails, it will
-       be easy to add an option for the listing stream.  Note that we
-       initialize it only once; mainly because some code may switch
-       the option value later back to 1 and we want to have all output
-       to the same stream.
-
-       Using stderr is not actually very clean because it bypasses the
-       logging code but it is a special thing anyay.  I am not sure
-       whether using log_stream() would be better.  Perhaps we should
-       enable the list mdoe only with a special option. */
-    if (!listfp)
-        listfp = opt.list_packets ? stdout : stderr;
-    return old;
+  int old = list_mode;
+  list_mode = mode;
+  /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */
+  /* We use stdout print only if invoked by the --list-packets command
+     but switch to stderr in all other cases.  This breaks the
+     previous behaviour but that seems to be more of a bug than
+     intentional.  I don't believe that any application makes use of
+     this long standing annoying way of printing to stdout except when
+     doing a --list-packets. If this assumption fails, it will be easy
+     to add an option for the listing stream.  Note that we initialize
+     it only once; mainly because some code may switch the option
+     value later back to 1 and we want to have all output to the same
+     stream.
+
+     Using stderr is not actually very clean because it bypasses the
+     logging code but it is a special thing anyway.  I am not sure
+     whether using log_stream() would be better.  Perhaps we should
+     enable the list mdoe only with a special option. */
+  if (!listfp)
+    listfp = opt.list_packets == 2 ? es_stdout : es_stderr;
+  return old;
 }
 
+
 static void
-unknown_pubkey_warning( int algo )
+unknown_pubkey_warning (int algo)
 {
-    static byte unknown_pubkey_algos[256];
+  static byte unknown_pubkey_algos[256];
 
-    algo &= 0xff;
-    if( !unknown_pubkey_algos[algo] ) {
-       if( opt.verbose )
-           log_info(_("can't handle public key algorithm %d\n"), algo );
-       unknown_pubkey_algos[algo] = 1;
+  /* First check whether the algorithm is usable but not suitable for
+     encryption/signing.  */
+  if (pubkey_get_npkey (algo))
+    {
+      if (opt.verbose)
+        {
+          if (!pubkey_get_nsig (algo))
+            log_info ("public key algorithm %s not suitable for %s\n",
+                      openpgp_pk_algo_name (algo), "signing");
+          if (!pubkey_get_nenc (algo))
+            log_info ("public key algorithm %s not suitable for %s\n",
+                      openpgp_pk_algo_name (algo), "encryption");
+        }
+    }
+  else
+    {
+      algo &= 0xff;
+      if (!unknown_pubkey_algos[algo])
+        {
+          if (opt.verbose)
+            log_info (_("can't handle public key algorithm %d\n"), algo);
+          unknown_pubkey_algos[algo] = 1;
+        }
     }
 }
 
-/****************
- * Parse a Packet and return it in packet
+
+/* Parse a packet and return it in packet structure.
  * Returns: 0 := valid packet in pkt
  *        -1 := no more packets
  *        >0 := error
  * Note: The function may return an error and a partly valid packet;
- * caller must free this packet.
- */
+ * caller must free this packet.   */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_parse_packet( IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l )
+dbg_parse_packet (IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l)
 {
-    int skip, rc;
+  int skip, rc;
 
-    do {
-       rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l );
-    } while( skip );
-    return rc;
+  do
+    {
+      rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l);
+    }
+  while (skip);
+  return rc;
 }
-#else
+#else /*!DEBUG_PARSE_PACKET*/
 int
-parse_packet( IOBUF inp, PACKET *pkt )
+parse_packet (IOBUF inp, PACKET * pkt)
 {
-    int skip, rc;
+  int skip, rc;
 
-    do {
-       rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
-    } while( skip );
-    return rc;
+  do
+    {
+      rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0);
+    }
+  while (skip);
+  return rc;
 }
-#endif
+#endif /*!DEBUG_PARSE_PACKET*/
 
-/****************
- * Like parse packet, but only return secret or public (sub)key packets.
+
+/*
+ * Like parse packet, but only return secret or public (sub)key
+ * packets.
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid,
-                  const char *dbg_f, int dbg_l )
+dbg_search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid,
+                  const char *dbg_f, int dbg_l)
 {
-    int skip, rc;
+  int skip, rc;
 
-    do {
-       rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
-    } while( skip );
-    return rc;
+  do
+    {
+      rc =
+       parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0, "search",
+              dbg_f, dbg_l);
+    }
+  while (skip);
+  return rc;
 }
-#else
+#else /*!DEBUG_PARSE_PACKET*/
 int
-search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid )
+search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid)
 {
-    int skip, rc;
+  int skip, rc;
 
-    do {
-       rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 );
-    } while( skip );
-    return rc;
+  do
+    {
+      rc = parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0);
+    }
+  while (skip);
+  return rc;
 }
-#endif
+#endif /*!DEBUG_PARSE_PACKET*/
 
-/****************
+
+/*
  * Copy all packets from INP to OUT, thereby removing unused spaces.
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_copy_all_packets( IOBUF inp, IOBUF out,
-                  const char *dbg_f, int dbg_l )
+dbg_copy_all_packets (IOBUF inp, IOBUF out, const char *dbg_f, int dbg_l)
 {
-    PACKET pkt;
-    int skip, rc=0;
-    do {
-       init_packet(&pkt);
-    } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l )));
-    return rc;
+  PACKET pkt;
+  int skip, rc = 0;
+  do
+    {
+      init_packet (&pkt);
+    }
+  while (!
+        (rc =
+         parse (inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l)));
+  return rc;
 }
-#else
+#else /*!DEBUG_PARSE_PACKET*/
 int
-copy_all_packets( IOBUF inp, IOBUF out )
+copy_all_packets (IOBUF inp, IOBUF out)
 {
-    PACKET pkt;
-    int skip, rc=0;
-    do {
-       init_packet(&pkt);
-    } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
-    return rc;
+  PACKET pkt;
+  int skip, rc = 0;
+  do
+    {
+      init_packet (&pkt);
+    }
+  while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0)));
+  return rc;
 }
-#endif
+#endif /*!DEBUG_PARSE_PACKET*/
 
-/****************
+
+/*
  * Copy some packets from INP to OUT, thereby removing unused spaces.
- * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets)
+ * Stop at offset STOPoff (i.e. don't copy packets at this or later
+ * offsets)
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_copy_some_packetsIOBUF inp, IOBUF out, off_t stopoff,
-                  const char *dbg_f, int dbg_l )
+dbg_copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff,
+                      const char *dbg_f, int dbg_l)
 {
-    PACKET pkt;
-    int skip, rc=0;
-    do {
-       if( iobuf_tell(inp) >= stopoff )
-           return 0;
-       init_packet(&pkt);
-    } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0,
-                                    "some", dbg_f, dbg_l )) );
-    return rc;
+  PACKET pkt;
+  int skip, rc = 0;
+  do
+    {
+      if (iobuf_tell (inp) >= stopoff)
+       return 0;
+      init_packet (&pkt);
+    }
+  while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0,
+                      "some", dbg_f, dbg_l)));
+  return rc;
 }
-#else
+#else /*!DEBUG_PARSE_PACKET*/
 int
-copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff )
+copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff)
 {
-    PACKET pkt;
-    int skip, rc=0;
-    do {
-       if( iobuf_tell(inp) >= stopoff )
-           return 0;
-       init_packet(&pkt);
-    } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
-    return rc;
+  PACKET pkt;
+  int skip, rc = 0;
+  do
+    {
+      if (iobuf_tell (inp) >= stopoff)
+       return 0;
+      init_packet (&pkt);
+    }
+  while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0)));
+  return rc;
 }
-#endif
+#endif /*!DEBUG_PARSE_PACKET*/
 
-/****************
+
+/*
  * Skip over N packets
  */
 #ifdef DEBUG_PARSE_PACKET
 int
-dbg_skip_some_packets( IOBUF inp, unsigned n,
-                  const char *dbg_f, int dbg_l )
+dbg_skip_some_packets (IOBUF inp, unsigned n, const char *dbg_f, int dbg_l)
 {
-    int skip, rc=0;
-    PACKET pkt;
+  int skip, rc = 0;
+  PACKET pkt;
 
-    for( ;n && !rc; n--) {
-       init_packet(&pkt);
-       rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l );
+  for (; n && !rc; n--)
+    {
+      init_packet (&pkt);
+      rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l);
     }
-    return rc;
+  return rc;
 }
-#else
+#else /*!DEBUG_PARSE_PACKET*/
 int
-skip_some_packets( IOBUF inp, unsigned n )
+skip_some_packets (IOBUF inp, unsigned n)
 {
-    int skip, rc=0;
-    PACKET pkt;
+  int skip, rc = 0;
+  PACKET pkt;
 
-    for( ;n && !rc; n--) {
-       init_packet(&pkt);
-       rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
+  for (; n && !rc; n--)
+    {
+      init_packet (&pkt);
+      rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1);
     }
-    return rc;
+  return rc;
 }
-#endif
+#endif /*!DEBUG_PARSE_PACKET*/
 
 
-/****************
- * Parse packet. Set the variable skip points to 1 if the packet
- * should be skipped; this is the case if either ONLYKEYPKTS is set
- * and the parsed packet isn't one or the
- * packet-type is 0, indicating deleted stuff.
- * if OUT is not NULL, a special copymode is used.
+/*
+ * Parse packet.  Stores 1 at SKIP 1 if the packet should be skipped;
+ * this is the case if either ONLYKEYPKTS is set and the parsed packet
+ * isn't a key packet or the packet-type is 0, indicating deleted
+ * stuff.  If OUT is not NULL, a special copymode is used.
  */
 static int
-parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
+parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos,
        int *skip, IOBUF out, int do_skip
 #ifdef DEBUG_PARSE_PACKET
-       ,const char *dbg_w, const char *dbg_f, int dbg_l
+       , const char *dbg_w, const char *dbg_f, int dbg_l
 #endif
-     )
+       )
 {
-    int rc=0, c, ctb, pkttype, lenbytes;
-    unsigned long pktlen;
-    byte hdr[8];
-    int hdrlen;
-    int new_ctb = 0, partial=0;
-    int with_uid = (onlykeypkts == 2);
-
-    *skip = 0;
-    assert( !pkt->pkt.generic );
-    if( retpos )
-       *retpos = iobuf_tell(inp);
-
-    if( (ctb = iobuf_get(inp)) == -1 ) {
-       rc = -1;
-       goto leave;
-    }
-    hdrlen=0;
-    hdr[hdrlen++] = ctb;
-    if( !(ctb & 0x80) ) {
-        log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb );
-       rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    pktlen = 0;
-    new_ctb = !!(ctb & 0x40);
-    if( new_ctb ) {
-        pkttype = ctb & 0x3f;
-       if( (c = iobuf_get(inp)) == -1 ) {
-           log_error("%s: 1st length byte missing\n", iobuf_where(inp) );
-           rc = gpg_error (GPG_ERR_INV_PACKET);
-           goto leave;
+  int rc = 0, c, ctb, pkttype, lenbytes;
+  unsigned long pktlen;
+  byte hdr[8];
+  int hdrlen;
+  int new_ctb = 0, partial = 0;
+  int with_uid = (onlykeypkts == 2);
+  off_t pos;
+
+  *skip = 0;
+  assert (!pkt->pkt.generic);
+  if (retpos || list_mode)
+    {
+      pos = iobuf_tell (inp);
+      if (retpos)
+        *retpos = pos;
+    }
+  else
+    pos = 0; /* (silence compiler warning) */
+
+  if ((ctb = iobuf_get (inp)) == -1)
+    {
+      rc = -1;
+      goto leave;
+    }
+  hdrlen = 0;
+  hdr[hdrlen++] = ctb;
+  if (!(ctb & 0x80))
+    {
+      log_error ("%s: invalid packet (ctb=%02x)\n", iobuf_where (inp), ctb);
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  pktlen = 0;
+  new_ctb = !!(ctb & 0x40);
+  if (new_ctb)
+    {
+      pkttype = ctb & 0x3f;
+      if ((c = iobuf_get (inp)) == -1)
+       {
+         log_error ("%s: 1st length byte missing\n", iobuf_where (inp));
+         rc = gpg_error (GPG_ERR_INV_PACKET);
+         goto leave;
        }
 
-/* The follwing code has been here for ages (2002-08-30) but it is
-   clearly wrong: For example passing a 0 as second argument to
-   iobuf_set_partial_block_mode stops the partial block mode which we
-   definitely do not want.  Also all values < 224 or 255 are not
-   valid.  Let's disable it and put PKT_COMPRESSED into the list of
-   allowed packets with partial header until someone complains. */
-/*         if (pkttype == PKT_COMPRESSED) { */
-/*              iobuf_set_partial_block_mode(inp, c & 0xff); */
-/*              pktlen = 0;  /\* to indicate partial length *\/ */
-/*          partial=1; */
-/*         } */
-/*         else  */
+
+      hdr[hdrlen++] = c;
+      if (c < 192)
+        pktlen = c;
+      else if (c < 224)
+        {
+          pktlen = (c - 192) * 256;
+          if ((c = iobuf_get (inp)) == -1)
+            {
+              log_error ("%s: 2nd length byte missing\n",
+                         iobuf_where (inp));
+              rc = gpg_error (GPG_ERR_INV_PACKET);
+              goto leave;
+            }
+          hdr[hdrlen++] = c;
+          pktlen += c + 192;
+        }
+      else if (c == 255)
         {
-             hdr[hdrlen++] = c;
-             if( c < 192 )
-              pktlen = c;
-             else if( c < 224 )
-              {
-                pktlen = (c - 192) * 256;
-                if( (c = iobuf_get(inp)) == -1 )
-                  {
-                    log_error("%s: 2nd length byte missing\n",
-                              iobuf_where(inp) );
-                     rc = gpg_error (GPG_ERR_INV_PACKET);
-                    goto leave;
-                  }
-                hdr[hdrlen++] = c;
-                pktlen += c + 192;
-              }
-             else if( c == 255 )
-              {
-                pktlen  =
-                   (unsigned long)(hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24;
-                pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16;
-                pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8;
-                if( (c = iobuf_get(inp)) == -1 )
-                  {
-                    log_error("%s: 4 byte length invalid\n",
-                              iobuf_where(inp) );
-                     rc = gpg_error (GPG_ERR_INV_PACKET);
-                    goto leave;
-                  }
-                pktlen |= (hdr[hdrlen++] = c );
-              }
-             else
-              {
-                /* Partial body length.  */
-                 switch (pkttype)
-                   {
-                   case PKT_PLAINTEXT:
-                   case PKT_ENCRYPTED:
-                  case PKT_ENCRYPTED_MDC:
-                   case PKT_COMPRESSED:
-                    iobuf_set_partial_block_mode(inp, c & 0xff);
-                    pktlen = 0;/* To indicate partial length.  */
-                    partial=1;
-                     break;
-
-                  default:
-                    log_error("%s: partial length for invalid"
-                              " packet type %d\n", iobuf_where(inp),pkttype);
-                     rc = gpg_error (GPG_ERR_INV_PACKET);
-                    goto leave;
-                  }
-              }
+          pktlen = (hdr[hdrlen++] = iobuf_get_noeof (inp)) << 24;
+          pktlen |= (hdr[hdrlen++] = iobuf_get_noeof (inp)) << 16;
+          pktlen |= (hdr[hdrlen++] = iobuf_get_noeof (inp)) << 8;
+          if ((c = iobuf_get (inp)) == -1)
+            {
+              log_error ("%s: 4 byte length invalid\n", iobuf_where (inp));
+              rc = gpg_error (GPG_ERR_INV_PACKET);
+              goto leave;
+            }
+          pktlen |= (hdr[hdrlen++] = c);
+        }
+      else /* Partial body length.  */
+        {
+          switch (pkttype)
+            {
+            case PKT_PLAINTEXT:
+            case PKT_ENCRYPTED:
+            case PKT_ENCRYPTED_MDC:
+            case PKT_COMPRESSED:
+              iobuf_set_partial_block_mode (inp, c & 0xff);
+              pktlen = 0;      /* To indicate partial length.  */
+              partial = 1;
+              break;
+
+            default:
+              log_error ("%s: partial length for invalid"
+                         " packet type %d\n", iobuf_where (inp), pkttype);
+              rc = gpg_error (GPG_ERR_INV_PACKET);
+              goto leave;
+            }
+        }
+
+    }
+  else
+    {
+      pkttype = (ctb >> 2) & 0xf;
+      lenbytes = ((ctb & 3) == 3) ? 0 : (1 << (ctb & 3));
+      if (!lenbytes)
+       {
+         pktlen = 0;   /* Don't know the value.  */
+         /* This isn't really partial, but we can treat it the same
+            in a "read until the end" sort of way.  */
+         partial = 1;
+         if (pkttype != PKT_ENCRYPTED && pkttype != PKT_PLAINTEXT
+             && pkttype != PKT_COMPRESSED)
+           {
+             log_error ("%s: indeterminate length for invalid"
+                        " packet type %d\n", iobuf_where (inp), pkttype);
+             rc = gpg_error (GPG_ERR_INV_PACKET);
+             goto leave;
+           }
+       }
+      else
+       {
+         for (; lenbytes; lenbytes--)
+           {
+             pktlen <<= 8;
+             pktlen |= hdr[hdrlen++] = iobuf_get_noeof (inp);
+           }
        }
     }
-    else
-      {
-       pkttype = (ctb>>2)&0xf;
-       lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
-       if( !lenbytes )
-         {
-           pktlen = 0; /* don't know the value */
-           /* This isn't really partial, but we can treat it the same
-              in a "read until the end" sort of way. */
-           partial=1;
-           if(pkttype!=PKT_ENCRYPTED && pkttype!=PKT_PLAINTEXT
-              && pkttype!=PKT_COMPRESSED)
-             {
-               log_error ("%s: indeterminate length for invalid"
-                          " packet type %d\n", iobuf_where(inp), pkttype );
-                rc = gpg_error (GPG_ERR_INV_PACKET);
-               goto leave;
-             }
-         }
-       else
-         {
-           for( ; lenbytes; lenbytes-- )
-             {
-               pktlen <<= 8;
-               pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp);
-             }
-         }
-      }
 
-    if (pktlen == (unsigned long)(-1)) {
-        /* With some probability this is caused by a problem in the
-         * the uncompressing layer - in some error cases it just loops
-         * and spits out 0xff bytes. */
-        log_error ("%s: garbled packet detected\n", iobuf_where(inp) );
-       g10_exit (2);
+  if (pktlen == (unsigned long) (-1))
+    {
+      /* With some probability this is caused by a problem in the
+       * the uncompressing layer - in some error cases it just loops
+       * and spits out 0xff bytes. */
+      log_error ("%s: garbled packet detected\n", iobuf_where (inp));
+      g10_exit (2);
     }
 
-    if( out && pkttype ) {
+  if (out && pkttype)
+    {
       rc = iobuf_write (out, hdr, hdrlen);
       if (!rc)
-           rc = copy_packet(inp, out, pkttype, pktlen, partial );
+       rc = copy_packet (inp, out, pkttype, pktlen, partial);
       goto leave;
     }
 
-    if (with_uid && pkttype == PKT_USER_ID)
-        ;
-    else if( do_skip
-        || !pkttype
-        || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
-                        && pkttype != PKT_PUBLIC_KEY
-                        && pkttype != PKT_SECRET_SUBKEY
-                        && pkttype != PKT_SECRET_KEY  ) ) {
-       iobuf_skip_rest(inp, pktlen, partial);
-       *skip = 1;
-       rc = 0;
-       goto leave;
+  if (with_uid && pkttype == PKT_USER_ID)
+    ;
+  else if (do_skip
+          || !pkttype
+          || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
+              && pkttype != PKT_PUBLIC_KEY
+              && pkttype != PKT_SECRET_SUBKEY && pkttype != PKT_SECRET_KEY))
+    {
+      iobuf_skip_rest (inp, pktlen, partial);
+      *skip = 1;
+      rc = 0;
+      goto leave;
     }
 
-    if( DBG_PACKET ) {
+  if (DBG_PACKET)
+    {
 #ifdef DEBUG_PARSE_PACKET
-       log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n",
-                  iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"",
-                   dbg_w, dbg_f, dbg_l );
+      log_debug ("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n",
+                iobuf_id (inp), pkttype, pktlen, new_ctb ? " (new_ctb)" : "",
+                dbg_w, dbg_f, dbg_l);
 #else
-       log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n",
-                  iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" );
+      log_debug ("parse_packet(iob=%d): type=%d length=%lu%s\n",
+                iobuf_id (inp), pkttype, pktlen,
+                new_ctb ? " (new_ctb)" : "");
 #endif
     }
-    pkt->pkttype = pkttype;
-    rc = G10ERR_UNKNOWN_PACKET; /* default error */
-    switch( pkttype ) {
-      case PKT_PUBLIC_KEY:
-      case PKT_PUBLIC_SUBKEY:
-       pkt->pkt.public_key = xmalloc_clear(sizeof *pkt->pkt.public_key );
-       rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
-       break;
-      case PKT_SECRET_KEY:
-      case PKT_SECRET_SUBKEY:
-       pkt->pkt.secret_key = xmalloc_clear(sizeof *pkt->pkt.secret_key );
-       rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
-       break;
-      case PKT_SYMKEY_ENC:
-       rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
-       break;
-      case PKT_PUBKEY_ENC:
-       rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
-       break;
-      case PKT_SIGNATURE:
-       pkt->pkt.signature = xmalloc_clear(sizeof *pkt->pkt.signature );
-       rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
-       break;
-      case PKT_ONEPASS_SIG:
-       pkt->pkt.onepass_sig = xmalloc_clear(sizeof *pkt->pkt.onepass_sig );
-       rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
-       break;
-      case PKT_USER_ID:
-       rc = parse_user_id(inp, pkttype, pktlen, pkt );
-       break;
-      case PKT_ATTRIBUTE:
-       pkt->pkttype = pkttype = PKT_USER_ID;  /* we store it in the userID */
-       rc = parse_attribute(inp, pkttype, pktlen, pkt);
-       break;
-      case PKT_OLD_COMMENT:
-      case PKT_COMMENT:
-       rc = parse_comment(inp, pkttype, pktlen, pkt);
-       break;
-      case PKT_RING_TRUST:
-       parse_trust(inp, pkttype, pktlen, pkt);
-       rc = 0;
-       break;
-      case PKT_PLAINTEXT:
-       rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb, partial );
-       break;
-      case PKT_COMPRESSED:
-       rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb );
-       break;
-      case PKT_ENCRYPTED:
-      case PKT_ENCRYPTED_MDC:
-       rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb, partial );
-       break;
-      case PKT_MDC:
-       rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb );
-       break;
-      case PKT_GPG_CONTROL:
-        rc = parse_gpg_control(inp, pkttype, pktlen, pkt, partial );
-        break;
+
+  if (list_mode)
+    es_fprintf (listfp, "# off=%lu ctb=%02x tag=%d hlen=%d plen=%lu%s%s\n",
+                (unsigned long)pos, ctb, pkttype, hdrlen, pktlen,
+                partial? " partial":"",
+                new_ctb? " new-ctb":"");
+
+  pkt->pkttype = pkttype;
+  rc = G10ERR_UNKNOWN_PACKET;  /* default error */
+  switch (pkttype)
+    {
+    case PKT_PUBLIC_KEY:
+    case PKT_PUBLIC_SUBKEY:
+    case PKT_SECRET_KEY:
+    case PKT_SECRET_SUBKEY:
+      pkt->pkt.public_key = xmalloc_clear (sizeof *pkt->pkt.public_key);
+      rc = parse_key (inp, pkttype, pktlen, hdr, hdrlen, pkt);
+      break;
+    case PKT_SYMKEY_ENC:
+      rc = parse_symkeyenc (inp, pkttype, pktlen, pkt);
+      break;
+    case PKT_PUBKEY_ENC:
+      rc = parse_pubkeyenc (inp, pkttype, pktlen, pkt);
+      break;
+    case PKT_SIGNATURE:
+      pkt->pkt.signature = xmalloc_clear (sizeof *pkt->pkt.signature);
+      rc = parse_signature (inp, pkttype, pktlen, pkt->pkt.signature);
+      break;
+    case PKT_ONEPASS_SIG:
+      pkt->pkt.onepass_sig = xmalloc_clear (sizeof *pkt->pkt.onepass_sig);
+      rc = parse_onepass_sig (inp, pkttype, pktlen, pkt->pkt.onepass_sig);
+      break;
+    case PKT_USER_ID:
+      rc = parse_user_id (inp, pkttype, pktlen, pkt);
+      break;
+    case PKT_ATTRIBUTE:
+      pkt->pkttype = pkttype = PKT_USER_ID;    /* we store it in the userID */
+      rc = parse_attribute (inp, pkttype, pktlen, pkt);
+      break;
+    case PKT_OLD_COMMENT:
+    case PKT_COMMENT:
+      rc = parse_comment (inp, pkttype, pktlen, pkt);
+      break;
+    case PKT_RING_TRUST:
+      parse_trust (inp, pkttype, pktlen, pkt);
+      rc = 0;
+      break;
+    case PKT_PLAINTEXT:
+      rc = parse_plaintext (inp, pkttype, pktlen, pkt, new_ctb, partial);
+      break;
+    case PKT_COMPRESSED:
+      rc = parse_compressed (inp, pkttype, pktlen, pkt, new_ctb);
+      break;
+    case PKT_ENCRYPTED:
+    case PKT_ENCRYPTED_MDC:
+      rc = parse_encrypted (inp, pkttype, pktlen, pkt, new_ctb, partial);
+      break;
+    case PKT_MDC:
+      rc = parse_mdc (inp, pkttype, pktlen, pkt, new_ctb);
+      break;
+    case PKT_GPG_CONTROL:
+      rc = parse_gpg_control (inp, pkttype, pktlen, pkt, partial);
+      break;
     case PKT_MARKER:
-        rc = parse_marker(inp,pkttype,pktlen);
-       break;
-      default:
-       skip_packet(inp, pkttype, pktlen, partial);
-       break;
+      rc = parse_marker (inp, pkttype, pktlen);
+      break;
+    default:
+      skip_packet (inp, pkttype, pktlen, partial);
+      break;
     }
 
-  leave:
-    if( !rc && iobuf_error(inp) )
-       rc = G10ERR_INV_KEYRING;
-    return rc;
+ leave:
+  /* FIXME: Do we leak in case of an error?  */
+  if (!rc && iobuf_error (inp))
+    rc = G10ERR_INV_KEYRING;
+  return rc;
 }
 
+
 static void
-dump_hex_line( int c, int *i )
+dump_hex_line (int c, int *i)
 {
-    if( *i && !(*i%8) ) {
-       if( *i && !(*i%24) )
-           fprintf (listfp, "\n%4d:", *i );
-       else
-           putc (' ', listfp);
+  if (*i && !(*i % 8))
+    {
+      if (*i && !(*i % 24))
+       es_fprintf (listfp, "\n%4d:", *i);
+      else
+       es_putc (' ', listfp);
     }
-    if( c == -1 )
-       fprintf (listfp, " EOF" );
-    else
-       fprintf (listfp, " %02x", c );
-    ++*i;
+  if (c == -1)
+    es_fprintf (listfp, " EOF");
+  else
+    es_fprintf (listfp, " %02x", c);
+  ++*i;
 }
 
 
 static int
-copy_packetIOBUF inp, IOBUF out, int pkttype,
-            unsigned long pktlen, int partial )
+copy_packet (IOBUF inp, IOBUF out, int pkttype,
+            unsigned long pktlen, int partial)
 {
-    int rc;
-    int n;
-    char buf[100];
-
-    if( partial ) {
-       while( (n = iobuf_read( inp, buf, 100 )) != -1 )
-           if( (rc=iobuf_write(out, buf, n )) )
-               return rc; /* write error */
-    }
-    else if( !pktlen && pkttype == PKT_COMPRESSED ) {
-       log_debug("copy_packet: compressed!\n");
-       /* compressed packet, copy till EOF */
-       while( (n = iobuf_read( inp, buf, 100 )) != -1 )
-           if( (rc=iobuf_write(out, buf, n )) )
-               return rc; /* write error */
-    }
-    else {
-       for( ; pktlen; pktlen -= n ) {
-           n = pktlen > 100 ? 100 : pktlen;
-           n = iobuf_read( inp, buf, n );
-           if( n == -1 )
-               return gpg_error (GPG_ERR_EOF);
-           if( (rc=iobuf_write(out, buf, n )) )
-               return rc; /* write error */
+  int rc;
+  int n;
+  char buf[100];
+
+  if (partial)
+    {
+      while ((n = iobuf_read (inp, buf, 100)) != -1)
+       if ((rc = iobuf_write (out, buf, n)))
+         return rc;            /* write error */
+    }
+  else if (!pktlen && pkttype == PKT_COMPRESSED)
+    {
+      log_debug ("copy_packet: compressed!\n");
+      /* compressed packet, copy till EOF */
+      while ((n = iobuf_read (inp, buf, 100)) != -1)
+       if ((rc = iobuf_write (out, buf, n)))
+         return rc;            /* write error */
+    }
+  else
+    {
+      for (; pktlen; pktlen -= n)
+       {
+         n = pktlen > 100 ? 100 : pktlen;
+         n = iobuf_read (inp, buf, n);
+         if (n == -1)
+           return gpg_error (GPG_ERR_EOF);
+         if ((rc = iobuf_write (out, buf, n)))
+           return rc;          /* write error */
        }
     }
-    return 0;
+  return 0;
 }
 
 
 static void
-skip_packet( IOBUF inp, int pkttype, unsigned long pktlen, int partial )
+skip_packet (IOBUF inp, int pkttype, unsigned long pktlen, int partial)
 {
-  if( list_mode )
+  if (list_mode)
     {
-      fprintf (listfp, ":unknown packet: type %2d, length %lu\n",
-              pkttype, pktlen);
-      if( pkttype )
+      es_fprintf (listfp, ":unknown packet: type %2d, length %lu\n",
+                  pkttype, pktlen);
+      if (pkttype)
        {
-         int c, i=0 ;
-         fputs("dump:", listfp );
-         if( partial )
+         int c, i = 0;
+         es_fputs ("dump:", listfp);
+         if (partial)
            {
-             while( (c=iobuf_get(inp)) != -1 )
-               dump_hex_line(c, &i);
+             while ((c = iobuf_get (inp)) != -1)
+               dump_hex_line (c, &i);
            }
          else
            {
-             for( ; pktlen; pktlen-- )
-                {
-                  dump_hex_line ((c=iobuf_get(inp)), &i);
-                  if (c == -1)
-                    break;
-                }
+             for (; pktlen; pktlen--)
+               {
+                 dump_hex_line ((c = iobuf_get (inp)), &i);
+                 if (c == -1)
+                   break;
+               }
            }
-         putc ('\n', listfp);
+         es_putc ('\n', listfp);
          return;
        }
     }
-  iobuf_skip_rest(inp,pktlen,partial);
+  iobuf_skip_rest (inp, pktlen, partial);
 }
 
+
+/* Read PKTLEN bytes form INP and return them in a newly allocated
+   buffer.  In case of an error NULL is returned and a error messages
+   printed.  */
 static void *
-read_rest( IOBUF inp, size_t pktlen, int partial )
+read_rest (IOBUF inp, size_t pktlen)
 {
-    byte *p;
-    int i;
+  int c;
+  byte *buf, *p;
 
-    if( partial ) {
-       log_error("read_rest: can't store stream data\n");
-       p = NULL;
+  buf = xtrymalloc (pktlen);
+  if (!buf)
+    {
+      gpg_error_t err = gpg_error_from_syserror ();
+      log_error ("error reading rest of packet: %s\n", gpg_strerror (err));
+      return NULL;
+    }
+  for (p = buf; pktlen; pktlen--)
+    {
+      c = iobuf_get (inp);
+      if (c == -1)
+        {
+          log_error ("premature eof while reading rest of packet\n");
+          xfree (buf);
+          return NULL;
+        }
+      *p++ = c;
     }
-    else {
-       p = xmalloc( pktlen );
-       for(i=0; pktlen; pktlen--, i++ )
-           p[i] = iobuf_get(inp);
+
+  return buf;
+}
+
+
+/* Read a special size+body from INP.  On success store an opaque MPI
+   with it at R_DATA.  On error return an error code and store NULL at
+   R_DATA.  Even in the error case store the number of read bytes at
+   R_NREAD.  The caller shall pass the remaining size of the packet in
+   PKTLEN.  */
+static gpg_error_t
+read_size_body (iobuf_t inp, int pktlen, size_t *r_nread,
+                gcry_mpi_t *r_data)
+{
+  char buffer[256];
+  char *tmpbuf;
+  int i, c, nbytes;
+
+  *r_nread = 0;
+  *r_data = NULL;
+
+  if (!pktlen)
+    return gpg_error (GPG_ERR_INV_PACKET);
+  c = iobuf_readbyte (inp);
+  if (c < 0)
+    return gpg_error (GPG_ERR_INV_PACKET);
+  pktlen--;
+  ++*r_nread;
+  nbytes = c;
+  if (nbytes < 2 || nbytes > 254)
+    return gpg_error (GPG_ERR_INV_PACKET);
+  if (nbytes > pktlen)
+    return gpg_error (GPG_ERR_INV_PACKET);
+
+  buffer[0] = nbytes;
+
+  for (i = 0; i < nbytes; i++)
+    {
+      c = iobuf_get (inp);
+      if (c < 0)
+        return gpg_error (GPG_ERR_INV_PACKET);
+      ++*r_nread;
+      buffer[1+i] = c;
+    }
+
+  tmpbuf = xtrymalloc (1 + nbytes);
+  if (!tmpbuf)
+    return gpg_error_from_syserror ();
+  memcpy (tmpbuf, buffer, 1 + nbytes);
+  *r_data = gcry_mpi_set_opaque (NULL, tmpbuf, 8 * (1 + nbytes));
+  if (!*r_data)
+    {
+      xfree (tmpbuf);
+      return gpg_error_from_syserror ();
     }
-    return p;
+  return 0;
 }
 
+
+/* Parse a marker packet.  */
 static int
-parse_marker( IOBUF inp, int pkttype, unsigned long pktlen )
+parse_marker (IOBUF inp, int pkttype, unsigned long pktlen)
 {
-  (void)pkttype;
+  (void) pkttype;
 
-  if(pktlen!=3)
+  if (pktlen != 3)
     goto fail;
 
-  if(iobuf_get(inp)!='P')
+  if (iobuf_get (inp) != 'P')
     {
       pktlen--;
       goto fail;
     }
 
-  if(iobuf_get(inp)!='G')
+  if (iobuf_get (inp) != 'G')
     {
       pktlen--;
       goto fail;
     }
 
-  if(iobuf_get(inp)!='P')
+  if (iobuf_get (inp) != 'P')
     {
       pktlen--;
       goto fail;
     }
 
-  if(list_mode)
-    fputs(":marker packet: PGP\n", listfp );
+  if (list_mode)
+    es_fputs (":marker packet: PGP\n", listfp);
 
   return 0;
 
  fail:
-  log_error("invalid marker packet\n");
-  iobuf_skip_rest(inp,pktlen,0);
+  log_error ("invalid marker packet\n");
+  if (list_mode)
+    es_fputs (":marker packet: [invalid]\n", listfp);
+  iobuf_skip_rest (inp, pktlen, 0);
   return G10ERR_INVALID_PACKET;
 }
 
+
 static int
-parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
+parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
+                PACKET * packet)
 {
-    PKT_symkey_enc *k;
-    int rc = 0;
-    int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
-
-    if( pktlen < 4 ) {
-       log_error("packet(%d) too short\n", pkttype);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    version = iobuf_get_noeof(inp); pktlen--;
-    if( version != 4 ) {
-       log_error("packet(%d) with unknown version %d\n", pkttype, version);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
-       log_error("packet(%d) too large\n", pkttype);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    cipher_algo = iobuf_get_noeof(inp); pktlen--;
-    s2kmode = iobuf_get_noeof(inp); pktlen--;
-    hash_algo = iobuf_get_noeof(inp); pktlen--;
-    switch( s2kmode ) {
-      case 0:  /* simple s2k */
-       minlen = 0;
-       break;
-      case 1:  /* salted s2k */
-       minlen = 8;
-       break;
-      case 3:  /* iterated+salted s2k */
-       minlen = 9;
-       break;
-      default:
-       log_error("unknown S2K %d\n", s2kmode );
-       goto leave;
-    }
-    if( minlen > pktlen ) {
-       log_error("packet with S2K %d too short\n", s2kmode );
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    seskeylen = pktlen - minlen;
-    k = packet->pkt.symkey_enc = xmalloc_clear( sizeof *packet->pkt.symkey_enc
-                                               + seskeylen - 1 );
-    k->version = version;
-    k->cipher_algo = cipher_algo;
-    k->s2k.mode = s2kmode;
-    k->s2k.hash_algo = hash_algo;
-    if( s2kmode == 1 || s2kmode == 3 ) {
-       for(i=0; i < 8 && pktlen; i++, pktlen-- )
-           k->s2k.salt[i] = iobuf_get_noeof(inp);
-    }
-    if( s2kmode == 3 ) {
-       k->s2k.count = iobuf_get(inp); pktlen--;
-    }
-    k->seskeylen = seskeylen;
-    if(k->seskeylen)
-      {
-       for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
-         k->seskey[i] = iobuf_get_noeof(inp);
-
-       /* What we're watching out for here is a session key decryptor
-          with no salt.  The RFC says that using salt for this is a
-          MUST. */
-       if(s2kmode!=1 && s2kmode!=3)
-         log_info(_("WARNING: potentially insecure symmetrically"
-                    " encrypted session key\n"));
-      }
-    assert( !pktlen );
-
-    if( list_mode ) {
-       fprintf (listfp, ":symkey enc packet: version %d, cipher %d, s2k %d, hash %d",
-              version, cipher_algo, s2kmode, hash_algo);
-       if(seskeylen)
-         fprintf (listfp, ", seskey %d bits",(seskeylen-1)*8);
-       fprintf (listfp, "\n");
-       if( s2kmode == 1 || s2kmode == 3 ) {
-           fprintf (listfp, "\tsalt ");
-           for(i=0; i < 8; i++ )
-               fprintf (listfp, "%02x", k->s2k.salt[i]);
-           if( s2kmode == 3 )
-               fprintf (listfp, ", count %lu (%lu)",
-                        S2K_DECODE_COUNT((ulong)k->s2k.count),
-                        (ulong)k->s2k.count );
-           fprintf (listfp, "\n");
-       }
+  PKT_symkey_enc *k;
+  int rc = 0;
+  int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
+
+  if (pktlen < 4)
+    {
+      log_error ("packet(%d) too short\n", pkttype);
+      if (list_mode)
+        es_fprintf (listfp, ":symkey enc packet: [too short]\n");
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  version = iobuf_get_noeof (inp);
+  pktlen--;
+  if (version != 4)
+    {
+      log_error ("packet(%d) with unknown version %d\n", pkttype, version);
+      if (list_mode)
+        es_fprintf (listfp, ":symkey enc packet: [unknown version]\n");
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  if (pktlen > 200)
+    {                          /* (we encode the seskeylen in a byte) */
+      log_error ("packet(%d) too large\n", pkttype);
+      if (list_mode)
+        es_fprintf (listfp, ":symkey enc packet: [too large]\n");
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  cipher_algo = iobuf_get_noeof (inp);
+  pktlen--;
+  s2kmode = iobuf_get_noeof (inp);
+  pktlen--;
+  hash_algo = iobuf_get_noeof (inp);
+  pktlen--;
+  switch (s2kmode)
+    {
+    case 0: /* Simple S2K.  */
+      minlen = 0;
+      break;
+    case 1: /* Salted S2K.  */
+      minlen = 8;
+      break;
+    case 3: /* Iterated+salted S2K.  */
+      minlen = 9;
+      break;
+    default:
+      log_error ("unknown S2K mode %d\n", s2kmode);
+      if (list_mode)
+        es_fprintf (listfp, ":symkey enc packet: [unknown S2K mode]\n");
+      goto leave;
     }
+  if (minlen > pktlen)
+    {
+      log_error ("packet with S2K %d too short\n", s2kmode);
+      if (list_mode)
+        es_fprintf (listfp, ":symkey enc packet: [too short]\n");
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  seskeylen = pktlen - minlen;
+  k = packet->pkt.symkey_enc = xmalloc_clear (sizeof *packet->pkt.symkey_enc
+                                             + seskeylen - 1);
+  k->version = version;
+  k->cipher_algo = cipher_algo;
+  k->s2k.mode = s2kmode;
+  k->s2k.hash_algo = hash_algo;
+  if (s2kmode == 1 || s2kmode == 3)
+    {
+      for (i = 0; i < 8 && pktlen; i++, pktlen--)
+       k->s2k.salt[i] = iobuf_get_noeof (inp);
+    }
+  if (s2kmode == 3)
+    {
+      k->s2k.count = iobuf_get (inp);
+      pktlen--;
+    }
+  k->seskeylen = seskeylen;
+  if (k->seskeylen)
+    {
+      for (i = 0; i < seskeylen && pktlen; i++, pktlen--)
+       k->seskey[i] = iobuf_get_noeof (inp);
 
-  leave:
-    iobuf_skip_rest(inp, pktlen, 0);
-    return rc;
-}
+      /* What we're watching out for here is a session key decryptor
+         with no salt.  The RFC says that using salt for this is a
+         MUST. */
+      if (s2kmode != 1 && s2kmode != 3)
+       log_info (_("WARNING: potentially insecure symmetrically"
+                   " encrypted session key\n"));
+    }
+  assert (!pktlen);
 
-static int
-parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
-{
-    unsigned int n;
-    int rc = 0;
-    int i, ndata;
-    PKT_pubkey_enc *k;
-
-    k = packet->pkt.pubkey_enc = xmalloc_clear(sizeof *packet->pkt.pubkey_enc);
-    if( pktlen < 12 ) {
-       log_error("packet(%d) too short\n", pkttype);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    k->version = iobuf_get_noeof(inp); pktlen--;
-    if( k->version != 2 && k->version != 3 ) {
-       log_error("packet(%d) with unknown version %d\n", pkttype, k->version);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    k->keyid[0] = read_32(inp); pktlen -= 4;
-    k->keyid[1] = read_32(inp); pktlen -= 4;
-    k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
-    k->throw_keyid = 0; /* only used as flag for build_packet */
-    if( list_mode )
-       fprintf (listfp, ":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
-         k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
-
-    ndata = pubkey_get_nenc(k->pubkey_algo);
-    if( !ndata ) {
-       if( list_mode )
-           fprintf (listfp, "\tunsupported algorithm %d\n", k->pubkey_algo );
-       unknown_pubkey_warning( k->pubkey_algo );
-       k->data[0] = NULL;  /* no need to store the encrypted data */
-    }
-    else {
-       for( i=0; i < ndata; i++ ) {
-           n = pktlen;
-           k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
-           if( list_mode ) {
-               fprintf (listfp, "\tdata: ");
-               mpi_print(listfp, k->data[i], mpi_print_mode );
-               putc ('\n', listfp);
-           }
-            if (!k->data[i])
-                rc = gpg_error (GPG_ERR_INV_PACKET);
+  if (list_mode)
+    {
+      es_fprintf (listfp,
+                  ":symkey enc packet: version %d, cipher %d, s2k %d, hash %d",
+                  version, cipher_algo, s2kmode, hash_algo);
+      if (seskeylen)
+       es_fprintf (listfp, ", seskey %d bits", (seskeylen - 1) * 8);
+      es_fprintf (listfp, "\n");
+      if (s2kmode == 1 || s2kmode == 3)
+       {
+         es_fprintf (listfp, "\tsalt ");
+          es_write_hexstring (listfp, k->s2k.salt, 8, 0, NULL);
+         if (s2kmode == 3)
+           es_fprintf (listfp, ", count %lu (%lu)",
+                        S2K_DECODE_COUNT ((ulong) k->s2k.count),
+                        (ulong) k->s2k.count);
+         es_fprintf (listfp, "\n");
        }
     }
 
 leave:
-    iobuf_skip_rest(inp, pktlen, 0);
-    return rc;
+ leave:
+  iobuf_skip_rest (inp, pktlen, 0);
+  return rc;
 }
 
 
-static void
-dump_sig_subpkt( int hashed, int type, int critical,
-                const byte *buffer, size_t buflen, size_t length )
+static int
+parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
+                PACKET * packet)
 {
-    const char *p=NULL;
-    int i;
-
-    /* The CERT has warning out with explains how to use GNUPG to
-     * detect the ARRs - we print our old message here when it is a faked
-     * ARR and add an additional notice */
-    if ( type == SIGSUBPKT_ARR && !hashed ) {
-        fprintf (listfp,
-                 "\tsubpkt %d len %u (additional recipient request)\n"
-                 "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
-                 "encrypt to this key and thereby reveal the plaintext to "
-                 "the owner of this ARR key. Detailed info follows:\n",
-                 type, (unsigned)length );
-    }
-
-    buffer++;
-    length--;
-
-    fprintf (listfp, "\t%s%ssubpkt %d len %u (", /*)*/
-             critical ? "critical ":"",
-             hashed ? "hashed ":"", type, (unsigned)length );
-    if( length > buflen ) {
-       fprintf (listfp, "too short: buffer is only %u)\n", (unsigned)buflen );
-       return;
-    }
-    switch( type ) {
-      case SIGSUBPKT_SIG_CREATED:
-       if( length >= 4 )
-           fprintf (listfp, "sig created %s",
-                     strtimestamp (buf32_to_u32(buffer)) );
-       break;
-      case SIGSUBPKT_SIG_EXPIRE:
-       if( length >= 4 )
-         {
-           if(buf32_to_u32(buffer))
-             fprintf (listfp, "sig expires after %s",
-                      strtimevalue( buf32_to_u32(buffer) ) );
-           else
-             fprintf (listfp, "sig does not expire");
-         }
-       break;
-      case SIGSUBPKT_EXPORTABLE:
-       if( length )
-           fprintf (listfp, "%sexportable", *buffer? "":"not ");
-       break;
-      case SIGSUBPKT_TRUST:
-       if(length!=2)
-         p="[invalid trust subpacket]";
-       else
-         fprintf (listfp, "trust signature of depth %d, value %d",buffer[0],buffer[1]);
-       break;
-      case SIGSUBPKT_REGEXP:
-       if(!length)
-         p="[invalid regexp subpacket]";
+  int rc = 0;
+  int i, ndata;
+  PKT_pubkey_enc *k;
+
+  k = packet->pkt.pubkey_enc = xmalloc_clear (sizeof *packet->pkt.pubkey_enc);
+  if (pktlen < 12)
+    {
+      log_error ("packet(%d) too short\n", pkttype);
+      if (list_mode)
+        es_fputs (":pubkey enc packet: [too short]\n", listfp);
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  k->version = iobuf_get_noeof (inp);
+  pktlen--;
+  if (k->version != 2 && k->version != 3)
+    {
+      log_error ("packet(%d) with unknown version %d\n", pkttype, k->version);
+      if (list_mode)
+        es_fputs (":pubkey enc packet: [unknown version]\n", listfp);
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  k->keyid[0] = read_32 (inp);
+  pktlen -= 4;
+  k->keyid[1] = read_32 (inp);
+  pktlen -= 4;
+  k->pubkey_algo = iobuf_get_noeof (inp);
+  pktlen--;
+  k->throw_keyid = 0;  /* Only used as flag for build_packet.  */
+  if (list_mode)
+    es_fprintf (listfp,
+                ":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
+                k->version, k->pubkey_algo, (ulong) k->keyid[0],
+                (ulong) k->keyid[1]);
+
+  ndata = pubkey_get_nenc (k->pubkey_algo);
+  if (!ndata)
+    {
+      if (list_mode)
+       es_fprintf (listfp, "\tunsupported algorithm %d\n", k->pubkey_algo);
+      unknown_pubkey_warning (k->pubkey_algo);
+      k->data[0] = NULL; /* No need to store the encrypted data.  */
+    }
+  else
+    {
+      for (i = 0; i < ndata; i++)
+        {
+          if (k->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
+            {
+              size_t n;
+             rc = read_size_body (inp, pktlen, &n, k->data+i);
+              pktlen -= n;
+            }
+          else
+            {
+             int n = pktlen;
+              k->data[i] = mpi_read (inp, &n, 0);
+              pktlen -= n;
+              if (!k->data[i])
+                rc = gpg_error (GPG_ERR_INV_PACKET);
+            }
+          if (rc)
+            goto leave;
+          if (list_mode)
+            {
+              es_fprintf (listfp, "\tdata: ");
+              mpi_print (listfp, k->data[i], mpi_print_mode);
+              es_putc ('\n', listfp);
+            }
+        }
+    }
+
+ leave:
+  iobuf_skip_rest (inp, pktlen, 0);
+  return rc;
+}
+
+
+static void
+dump_sig_subpkt (int hashed, int type, int critical,
+                const byte * buffer, size_t buflen, size_t length)
+{
+  const char *p = NULL;
+  int i;
+
+  /* The CERT has warning out with explains how to use GNUPG to detect
+   * the ARRs - we print our old message here when it is a faked ARR
+   * and add an additional notice.  */
+  if (type == SIGSUBPKT_ARR && !hashed)
+    {
+      es_fprintf (listfp,
+                  "\tsubpkt %d len %u (additional recipient request)\n"
+                  "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
+                  "encrypt to this key and thereby reveal the plaintext to "
+                  "the owner of this ARR key. Detailed info follows:\n",
+                  type, (unsigned) length);
+    }
+
+  buffer++;
+  length--;
+
+  es_fprintf (listfp, "\t%s%ssubpkt %d len %u (",      /*) */
+              critical ? "critical " : "",
+              hashed ? "hashed " : "", type, (unsigned) length);
+  if (length > buflen)
+    {
+      es_fprintf (listfp, "too short: buffer is only %u)\n", (unsigned) buflen);
+      return;
+    }
+  switch (type)
+    {
+    case SIGSUBPKT_SIG_CREATED:
+      if (length >= 4)
+       es_fprintf (listfp, "sig created %s",
+                    strtimestamp (buffer_to_u32 (buffer)));
+      break;
+    case SIGSUBPKT_SIG_EXPIRE:
+      if (length >= 4)
+       {
+         if (buffer_to_u32 (buffer))
+           es_fprintf (listfp, "sig expires after %s",
+                        strtimevalue (buffer_to_u32 (buffer)));
+         else
+           es_fprintf (listfp, "sig does not expire");
+       }
+      break;
+    case SIGSUBPKT_EXPORTABLE:
+      if (length)
+       es_fprintf (listfp, "%sexportable", *buffer ? "" : "not ");
+      break;
+    case SIGSUBPKT_TRUST:
+      if (length != 2)
+       p = "[invalid trust subpacket]";
+      else
+       es_fprintf (listfp, "trust signature of depth %d, value %d", buffer[0],
+                    buffer[1]);
+      break;
+    case SIGSUBPKT_REGEXP:
+      if (!length)
+       p = "[invalid regexp subpacket]";
+      else
+       es_fprintf (listfp, "regular expression: \"%s\"", buffer);
+      break;
+    case SIGSUBPKT_REVOCABLE:
+      if (length)
+       es_fprintf (listfp, "%srevocable", *buffer ? "" : "not ");
+      break;
+    case SIGSUBPKT_KEY_EXPIRE:
+      if (length >= 4)
+       {
+         if (buffer_to_u32 (buffer))
+           es_fprintf (listfp, "key expires after %s",
+                        strtimevalue (buffer_to_u32 (buffer)));
+         else
+           es_fprintf (listfp, "key does not expire");
+       }
+      break;
+    case SIGSUBPKT_PREF_SYM:
+      es_fputs ("pref-sym-algos:", listfp);
+      for (i = 0; i < length; i++)
+       es_fprintf (listfp, " %d", buffer[i]);
+      break;
+    case SIGSUBPKT_REV_KEY:
+      es_fputs ("revocation key: ", listfp);
+      if (length < 22)
+       p = "[too short]";
+      else
+       {
+         es_fprintf (listfp, "c=%02x a=%d f=", buffer[0], buffer[1]);
+         for (i = 2; i < length; i++)
+           es_fprintf (listfp, "%02X", buffer[i]);
+       }
+      break;
+    case SIGSUBPKT_ISSUER:
+      if (length >= 8)
+       es_fprintf (listfp, "issuer key ID %08lX%08lX",
+                    (ulong) buffer_to_u32 (buffer),
+                    (ulong) buffer_to_u32 (buffer + 4));
+      break;
+    case SIGSUBPKT_NOTATION:
+      {
+       es_fputs ("notation: ", listfp);
+       if (length < 8)
+         p = "[too short]";
        else
-          {
-            fprintf (listfp, "regular expression: \"");
-            print_string (listfp, buffer, length, '\"');
-            p = "\"";
-          }
-       break;
-      case SIGSUBPKT_REVOCABLE:
-       if( length )
-           fprintf (listfp, "%srevocable", *buffer? "":"not ");
-       break;
-      case SIGSUBPKT_KEY_EXPIRE:
-       if( length >= 4 )
          {
-           if(buf32_to_u32(buffer))
-             fprintf (listfp, "key expires after %s",
-                      strtimevalue( buf32_to_u32(buffer) ) );
+           const byte *s = buffer;
+           size_t n1, n2;
+
+           n1 = (s[4] << 8) | s[5];
+           n2 = (s[6] << 8) | s[7];
+           s += 8;
+           if (8 + n1 + n2 != length)
+             p = "[error]";
            else
-             fprintf (listfp, "key does not expire");
+             {
+               es_write_sanitized (listfp, s, n1, ")", NULL);
+               es_putc ('=', listfp);
+
+               if (*buffer & 0x80)
+                 es_write_sanitized (listfp, s + n1, n2, ")", NULL);
+               else
+                 p = "[not human readable]";
+             }
          }
-       break;
-      case SIGSUBPKT_PREF_SYM:
-       fputs("pref-sym-algos:", listfp );
-       for( i=0; i < length; i++ )
-           fprintf (listfp, " %d", buffer[i] );
-       break;
-      case SIGSUBPKT_REV_KEY:
-       fputs("revocation key: ", listfp );
-       if( length < 22 )
-           p = "[too short]";
-       else {
-           fprintf (listfp, "c=%02x a=%d f=", buffer[0], buffer[1] );
-           for( i=2; i < length; i++ )
-               fprintf (listfp, "%02X", buffer[i] );
-       }
-       break;
-      case SIGSUBPKT_ISSUER:
-       if( length >= 8 )
-           fprintf (listfp, "issuer key ID %08lX%08lX",
-                     buf32_to_ulong (buffer),
-                     buf32_to_ulong (buffer+4));
-       break;
-      case SIGSUBPKT_NOTATION:
+      }
+      break;
+    case SIGSUBPKT_PREF_HASH:
+      es_fputs ("pref-hash-algos:", listfp);
+      for (i = 0; i < length; i++)
+       es_fprintf (listfp, " %d", buffer[i]);
+      break;
+    case SIGSUBPKT_PREF_COMPR:
+      es_fputs ("pref-zip-algos:", listfp);
+      for (i = 0; i < length; i++)
+       es_fprintf (listfp, " %d", buffer[i]);
+      break;
+    case SIGSUBPKT_KS_FLAGS:
+      es_fputs ("key server preferences:", listfp);
+      for (i = 0; i < length; i++)
+       es_fprintf (listfp, " %02X", buffer[i]);
+      break;
+    case SIGSUBPKT_PREF_KS:
+      es_fputs ("preferred key server: ", listfp);
+      es_write_sanitized (listfp, buffer, length, ")", NULL);
+      break;
+    case SIGSUBPKT_PRIMARY_UID:
+      p = "primary user ID";
+      break;
+    case SIGSUBPKT_POLICY:
+      es_fputs ("policy: ", listfp);
+      es_write_sanitized (listfp, buffer, length, ")", NULL);
+      break;
+    case SIGSUBPKT_KEY_FLAGS:
+      es_fputs ("key flags:", listfp);
+      for (i = 0; i < length; i++)
+       es_fprintf (listfp, " %02X", buffer[i]);
+      break;
+    case SIGSUBPKT_SIGNERS_UID:
+      p = "signer's user ID";
+      break;
+    case SIGSUBPKT_REVOC_REASON:
+      if (length)
        {
-           fputs("notation: ", listfp );
-           if( length < 8 )
-               p = "[too short]";
-           else {
-               const byte *s = buffer;
-               size_t n1, n2;
-
-               n1 = (s[4] << 8) | s[5];
-               n2 = (s[6] << 8) | s[7];
-               s += 8;
-               if( 8+n1+n2 != length )
-                   p = "[error]";
-               else {
-                   print_string( listfp, s, n1, ')' );
-                   putc( '=', listfp );
-
-                   if( *buffer & 0x80 )
-                     print_string( listfp, s+n1, n2, ')' );
-                   else
-                     p = "[not human readable]";
-               }
-           }
+         es_fprintf (listfp, "revocation reason 0x%02x (", *buffer);
+         es_write_sanitized (listfp, buffer + 1, length - 1, ")", NULL);
+         p = ")";
        }
-       break;
-      case SIGSUBPKT_PREF_HASH:
-       fputs("pref-hash-algos:", listfp );
-       for( i=0; i < length; i++ )
-           fprintf (listfp, " %d", buffer[i] );
-       break;
-      case SIGSUBPKT_PREF_COMPR:
-       fputs("pref-zip-algos:", listfp );
-       for( i=0; i < length; i++ )
-           fprintf (listfp, " %d", buffer[i] );
-       break;
-      case SIGSUBPKT_KS_FLAGS:
-       fputs("key server preferences:",listfp);
-       for(i=0;i<length;i++)
-         fprintf (listfp, " %02X", buffer[i]);
-       break;
-      case SIGSUBPKT_PREF_KS:
-       fputs("preferred key server: ", listfp );
-       print_string( listfp, buffer, length, ')' );
-       break;
-      case SIGSUBPKT_PRIMARY_UID:
-       p = "primary user ID";
-       break;
-      case SIGSUBPKT_POLICY:
-       fputs("policy: ", listfp );
-       print_string( listfp, buffer, length, ')' );
-       break;
-      case SIGSUBPKT_KEY_FLAGS:
-        fputs ( "key flags:", listfp );
-        for( i=0; i < length; i++ )
-            fprintf (listfp, " %02X", buffer[i] );
-       break;
-      case SIGSUBPKT_SIGNERS_UID:
-       p = "signer's user ID";
-       break;
-      case SIGSUBPKT_REVOC_REASON:
-        if( length ) {
-           fprintf (listfp, "revocation reason 0x%02x (", *buffer );
-           print_string( listfp, buffer+1, length-1, ')' );
-           p = ")";
-       }
-       break;
-      case SIGSUBPKT_ARR:
-        fputs("Big Brother's key (ignored): ", listfp );
-       if( length < 22 )
-           p = "[too short]";
-       else {
-           fprintf (listfp, "c=%02x a=%d f=", buffer[0], buffer[1] );
-           for( i=2; i < length; i++ )
-               fprintf (listfp, "%02X", buffer[i] );
+      break;
+    case SIGSUBPKT_ARR:
+      es_fputs ("Big Brother's key (ignored): ", listfp);
+      if (length < 22)
+       p = "[too short]";
+      else
+       {
+         es_fprintf (listfp, "c=%02x a=%d f=", buffer[0], buffer[1]);
+          if (length > 2)
+            es_write_hexstring (listfp, buffer+2, length-2, 0, NULL);
        }
-        break;
-      case SIGSUBPKT_FEATURES:
-        fputs ( "features:", listfp );
-        for( i=0; i < length; i++ )
-            fprintf (listfp, " %02x", buffer[i] );
-       break;
-      case SIGSUBPKT_SIGNATURE:
-       fputs("signature: ",listfp);
-       if(length<17)
-         p="[too short]";
-       else
-         fprintf (listfp, "v%d, class 0x%02X, algo %d, digest algo %d",
-                buffer[0],
-                buffer[0]==3?buffer[2]:buffer[1],
-                buffer[0]==3?buffer[15]:buffer[2],
-                buffer[0]==3?buffer[16]:buffer[3]);
-       break;
-      default:
-       if(type>=100 && type<=110)
-         p="experimental / private subpacket";
-       else
-         p = "?";
-       break;
+      break;
+    case SIGSUBPKT_FEATURES:
+      es_fputs ("features:", listfp);
+      for (i = 0; i < length; i++)
+       es_fprintf (listfp, " %02x", buffer[i]);
+      break;
+    case SIGSUBPKT_SIGNATURE:
+      es_fputs ("signature: ", listfp);
+      if (length < 17)
+       p = "[too short]";
+      else
+       es_fprintf (listfp, "v%d, class 0x%02X, algo %d, digest algo %d",
+                    buffer[0],
+                    buffer[0] == 3 ? buffer[2] : buffer[1],
+                    buffer[0] == 3 ? buffer[15] : buffer[2],
+                    buffer[0] == 3 ? buffer[16] : buffer[3]);
+      break;
+    default:
+      if (type >= 100 && type <= 110)
+       p = "experimental / private subpacket";
+      else
+       p = "?";
+      break;
     }
 
-    fprintf (listfp, "%s)\n", p? p: "");
+  es_fprintf (listfp, "%s)\n", p ? p : "");
 }
 
-/****************
+
+/*
  * Returns: >= 0 use this offset into buffer
  *         -1 explicitly reject returning this type
  *         -2 subpacket too short
  */
 int
-parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
+parse_one_sig_subpkt (const byte * buffer, size_t n, int type)
 {
-  switch( type )
+  switch (type)
     {
     case SIGSUBPKT_REV_KEY:
-      if(n < 22)
+      if (n < 22)
        break;
       return 0;
     case SIGSUBPKT_SIG_CREATED:
     case SIGSUBPKT_SIG_EXPIRE:
     case SIGSUBPKT_KEY_EXPIRE:
-      if( n < 4 )
+      if (n < 4)
        break;
       return 0;
     case SIGSUBPKT_KEY_FLAGS:
@@ -1162,58 +1328,61 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
     case SIGSUBPKT_EXPORTABLE:
     case SIGSUBPKT_REVOCABLE:
     case SIGSUBPKT_REVOC_REASON:
-      if( !n )
+      if (!n)
        break;
       return 0;
-    case SIGSUBPKT_ISSUER: /* issuer key ID */
-      if( n < 8 )
+    case SIGSUBPKT_ISSUER:     /* issuer key ID */
+      if (n < 8)
        break;
       return 0;
     case SIGSUBPKT_NOTATION:
       /* minimum length needed, and the subpacket must be well-formed
-        where the name length and value length all fit inside the
-        packet. */
-      if(n<8 || 8+((buffer[4]<<8)|buffer[5])+((buffer[6]<<8)|buffer[7]) != n)
+         where the name length and value length all fit inside the
+         packet. */
+      if (n < 8
+         || 8 + ((buffer[4] << 8) | buffer[5]) +
+         ((buffer[6] << 8) | buffer[7]) != n)
        break;
       return 0;
     case SIGSUBPKT_PRIMARY_UID:
-      if ( n != 1 )
+      if (n != 1)
        break;
       return 0;
     case SIGSUBPKT_TRUST:
-      if ( n != 2 )
+      if (n != 2)
        break;
       return 0;
-    default: return 0;
+    default:
+      return 0;
     }
   return -2;
 }
 
-/* Not many critical notations we understand yet... */
+
+/* Return true if we understand the critical notation.  */
 static int
-can_handle_critical_notation(const byte *name,size_t len)
+can_handle_critical_notation (const byte * name, size_t len)
 {
-  if(len==32 && memcmp(name,"preferred-email-encoding@pgp.com",32)==0)
+  if (len == 32 && memcmp (name, "preferred-email-encoding@pgp.com", 32) == 0)
     return 1;
-  if(len==21 && memcmp(name,"pka-address@gnupg.org",21)==0)
+  if (len == 21 && memcmp (name, "pka-address@gnupg.org", 21) == 0)
     return 1;
 
   return 0;
 }
 
+
 static int
-can_handle_critical( const byte *buffer, size_t n, int type )
+can_handle_critical (const byte * buffer, size_t n, int type)
 {
-  switch( type )
+  switch (type)
     {
     case SIGSUBPKT_NOTATION:
       if (n >= 8)
-       {
-         size_t notation_len = ((buffer[4] << 8) | buffer[5]);
-         if (n - 8 >= notation_len)
-           return can_handle_critical_notation (buffer + 8, notation_len);
-       }
-      return 0;
+       return can_handle_critical_notation (buffer + 8,
+                                            (buffer[4] << 8) | buffer[5]);
+      else
+       return 0;
     case SIGSUBPKT_SIGNATURE:
     case SIGSUBPKT_SIG_CREATED:
     case SIGSUBPKT_SIG_EXPIRE:
@@ -1221,7 +1390,7 @@ can_handle_critical( const byte *buffer, size_t n, int type )
     case SIGSUBPKT_EXPORTABLE:
     case SIGSUBPKT_REVOCABLE:
     case SIGSUBPKT_REV_KEY:
-    case SIGSUBPKT_ISSUER:/* issuer key ID */
+    case SIGSUBPKT_ISSUER:     /* issuer key ID */
     case SIGSUBPKT_PREF_SYM:
     case SIGSUBPKT_PREF_HASH:
     case SIGSUBPKT_PREF_COMPR:
@@ -1242,1325 +1411,1386 @@ can_handle_critical( const byte *buffer, size_t n, int type )
 
 
 const byte *
-enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype,
-                size_t *ret_n, int *start, int *critical )
+enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype,
+                size_t * ret_n, int *start, int *critical)
 {
-    const byte *buffer;
-    int buflen;
-    int type;
-    int critical_dummy;
-    int offset;
-    size_t n;
-    int seq = 0;
-    int reqseq = start? *start: 0;
-
-    if(!critical)
-      critical=&critical_dummy;
-
-    if( !pktbuf || reqseq == -1 ) {
-       static char dummy[] = "x";
-       /* Return a value different from NULL to indicate that
-        * there is no critical bit we do not understand.  */
-       return reqtype ==       SIGSUBPKT_TEST_CRITICAL ? dummy : NULL;
-    }
-    buffer = pktbuf->data;
-    buflen = pktbuf->len;
-    while( buflen ) {
-       n = *buffer++; buflen--;
-       if( n == 255 ) { /* 4 byte length header */
-           if( buflen < 4 )
-               goto too_short;
-            n = buf32_to_size_t (buffer);
-           buffer += 4;
-           buflen -= 4;
-       }
-       else if( n >= 192 ) { /* 2 byte special encoded length header */
-           if( buflen < 2 )
-               goto too_short;
-           n = (( n - 192 ) << 8) + *buffer + 192;
-           buffer++;
-           buflen--;
+  const byte *buffer;
+  int buflen;
+  int type;
+  int critical_dummy;
+  int offset;
+  size_t n;
+  int seq = 0;
+  int reqseq = start ? *start : 0;
+
+  if (!critical)
+    critical = &critical_dummy;
+
+  if (!pktbuf || reqseq == -1)
+    {
+      static char dummy[] = "x";
+      /* Return a value different from NULL to indicate that
+       * there is no critical bit we do not understand.  */
+      return reqtype ==        SIGSUBPKT_TEST_CRITICAL ? dummy : NULL;
+    }
+  buffer = pktbuf->data;
+  buflen = pktbuf->len;
+  while (buflen)
+    {
+      n = *buffer++;
+      buflen--;
+      if (n == 255) /* 4 byte length header.  */
+       {
+         if (buflen < 4)
+           goto too_short;
+         n = (buffer[0] << 24) | (buffer[1] << 16)
+           | (buffer[2] << 8) | buffer[3];
+         buffer += 4;
+         buflen -= 4;
        }
-       if( buflen < n )
+      else if (n >= 192) /* 4 byte special encoded length header.  */
+       {
+         if (buflen < 2)
            goto too_short;
-       type = *buffer;
-       if( type & 0x80 ) {
-           type &= 0x7f;
-           *critical = 1;
+         n = ((n - 192) << 8) + *buffer + 192;
+         buffer++;
+         buflen--;
        }
-       else
-           *critical = 0;
-       if( !(++seq > reqseq) )
-           ;
-       else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
-           if( *critical ) {
-               if( n-1 > buflen+1 )
-                   goto too_short;
-               if( !can_handle_critical(buffer+1, n-1, type ) )
-                 {
-                   if(opt.verbose)
-                     log_info(_("subpacket of type %d has "
-                                "critical bit set\n"),type);
-                   if( start )
-                     *start = seq;
-                   return NULL; /* this is an error */
-                 }
-           }
+      if (buflen < n)
+       goto too_short;
+      type = *buffer;
+      if (type & 0x80)
+       {
+         type &= 0x7f;
+         *critical = 1;
        }
-       else if( reqtype < 0 ) /* list packets */
-           dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
-                                   type, *critical, buffer, buflen, n );
-       else if( type == reqtype ) { /* found */
-           buffer++;
-           n--;
-           if( n > buflen )
+      else
+       *critical = 0;
+      if (!(++seq > reqseq))
+       ;
+      else if (reqtype == SIGSUBPKT_TEST_CRITICAL)
+       {
+         if (*critical)
+           {
+             if (n - 1 > buflen + 1)
                goto too_short;
-           if( ret_n )
-               *ret_n = n;
-           offset = parse_one_sig_subpkt(buffer, n, type );
-           switch( offset ) {
-             case -2:
-               log_error("subpacket of type %d too short\n", type);
-               return NULL;
-             case -1:
-               return NULL;
-             default:
-               break;
+             if (!can_handle_critical (buffer + 1, n - 1, type))
+               {
+                 if (opt.verbose)
+                   log_info (_("subpacket of type %d has "
+                               "critical bit set\n"), type);
+                 if (start)
+                   *start = seq;
+                 return NULL;  /* This is an error.  */
+               }
            }
-           if( start )
-               *start = seq;
-           return buffer+offset;
        }
-       buffer += n; buflen -=n;
-    }
-    if( reqtype == SIGSUBPKT_TEST_CRITICAL )
-       return buffer; /* as value true to indicate that there is no */
-                      /* critical bit we don't understand */
-    if( start )
-       *start = -1;
-    return NULL; /* end of packets; not found */
-
-  too_short:
-    if(opt.verbose)
-      log_info("buffer shorter than subpacket\n");
-    if( start )
-       *start = -1;
-    return NULL;
+      else if (reqtype < 0) /* List packets.  */
+       dump_sig_subpkt (reqtype == SIGSUBPKT_LIST_HASHED,
+                        type, *critical, buffer, buflen, n);
+      else if (type == reqtype) /* Found.  */
+       {
+         buffer++;
+         n--;
+         if (n > buflen)
+           goto too_short;
+         if (ret_n)
+           *ret_n = n;
+         offset = parse_one_sig_subpkt (buffer, n, type);
+         switch (offset)
+           {
+           case -2:
+             log_error ("subpacket of type %d too short\n", type);
+             return NULL;
+           case -1:
+             return NULL;
+           default:
+             break;
+           }
+         if (start)
+           *start = seq;
+         return buffer + offset;
+       }
+      buffer += n;
+      buflen -= n;
+    }
+  if (reqtype == SIGSUBPKT_TEST_CRITICAL)
+    return buffer;  /* Used as True to indicate that there is no. */
+
+  /* Critical bit we don't understand. */
+  if (start)
+    *start = -1;
+  return NULL; /* End of packets; not found.  */
+
+ too_short:
+  if (opt.verbose)
+    log_info ("buffer shorter than subpacket\n");
+  if (start)
+    *start = -1;
+  return NULL;
 }
 
 
 const byte *
-parse_sig_subpkt (const subpktarea_t *buffer, sigsubpkttype_t reqtype,
-                  size_t *ret_n)
+parse_sig_subpkt (const subpktarea_t * buffer, sigsubpkttype_t reqtype,
+                 size_t * ret_n)
 {
-    return enum_sig_subpkt( buffer, reqtype, ret_n, NULL, NULL );
+  return enum_sig_subpkt (buffer, reqtype, ret_n, NULL, NULL);
 }
 
+
 const byte *
-parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype,
-                   size_t *ret_n )
+parse_sig_subpkt2 (PKT_signature * sig, sigsubpkttype_t reqtype,
+                  size_t * ret_n)
 {
-    const byte *p;
+  const byte *p;
 
-    p = parse_sig_subpkt (sig->hashed, reqtype, ret_n );
-    if( !p )
-       p = parse_sig_subpkt (sig->unhashed, reqtype, ret_n );
-    return p;
+  p = parse_sig_subpkt (sig->hashed, reqtype, ret_n);
+  if (!p)
+    p = parse_sig_subpkt (sig->unhashed, reqtype, ret_n);
+  return p;
 }
 
-/* Find all revocation keys. Look in hashed area only. */
-void parse_revkeys(PKT_signature *sig)
+
+/* Find all revocation keys.  Look in hashed area only.  */
+void
+parse_revkeys (PKT_signature * sig)
 {
   struct revocation_key *revkey;
-  int seq=0;
+  int seq = 0;
   size_t len;
 
-  if(sig->sig_class!=0x1F)
+  if (sig->sig_class != 0x1F)
     return;
 
-  while((revkey=
-        (struct revocation_key *)enum_sig_subpkt(sig->hashed,
-                                                 SIGSUBPKT_REV_KEY,
-                                                 &len,&seq,NULL)))
+  while ((revkey =
+         (struct revocation_key *) enum_sig_subpkt (sig->hashed,
+                                                    SIGSUBPKT_REV_KEY,
+                                                    &len, &seq, NULL)))
     {
-      if(len==sizeof(struct revocation_key) &&
-        (revkey->class&0x80)) /* 0x80 bit must be set */
+      if (len == sizeof (struct revocation_key)
+          && (revkey->class & 0x80))  /* 0x80 bit must be set.  */
        {
-         sig->revkey=xrealloc(sig->revkey,
-                         sizeof(struct revocation_key *)*(sig->numrevkeys+1));
-         sig->revkey[sig->numrevkeys]=revkey;
+         sig->revkey = xrealloc (sig->revkey,
+                                 sizeof (struct revocation_key *) *
+                                 (sig->numrevkeys + 1));
+         sig->revkey[sig->numrevkeys] = revkey;
          sig->numrevkeys++;
        }
     }
 }
 
+
 int
-parse_signatureIOBUF inp, int pkttype, unsigned long pktlen,
-                                         PKT_signature *sig )
+parse_signature (IOBUF inp, int pkttype, unsigned long pktlen,
+                PKT_signature * sig)
 {
-    int md5_len=0;
-    unsigned n;
-    int is_v4=0;
-    int rc=0;
-    int i, ndata;
-
-    if( pktlen < 16 ) {
-       log_error("packet(%d) too short\n", pkttype);
-       goto leave;
-    }
-    sig->version = iobuf_get_noeof(inp); pktlen--;
-    if( sig->version == 4 )
-       is_v4=1;
-    else if( sig->version != 2 && sig->version != 3 ) {
-       log_error("packet(%d) with unknown version %d\n",
-                  pkttype, sig->version);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-
-    if( !is_v4 ) {
-       md5_len = iobuf_get_noeof(inp); pktlen--;
-    }
-    sig->sig_class = iobuf_get_noeof(inp); pktlen--;
-    if( !is_v4 ) {
-       sig->timestamp = read_32(inp); pktlen -= 4;
-       sig->keyid[0] = read_32(inp); pktlen -= 4;
-       sig->keyid[1] = read_32(inp); pktlen -= 4;
-    }
-    sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
-    sig->digest_algo = iobuf_get_noeof(inp); pktlen--;
-    sig->flags.exportable=1;
-    sig->flags.revocable=1;
-    if( is_v4 ) { /* read subpackets */
-       n = read_16(inp); pktlen -= 2; /* length of hashed data */
-       if( n > 10000 ) {
-           log_error("signature packet: hashed data too long\n");
-           rc = G10ERR_INVALID_PACKET;
-           goto leave;
+  int md5_len = 0;
+  unsigned n;
+  int is_v4 = 0;
+  int rc = 0;
+  int i, ndata;
+
+  if (pktlen < 16)
+    {
+      log_error ("packet(%d) too short\n", pkttype);
+      if (list_mode)
+        es_fputs (":signature packet: [too short]\n", listfp);
+      goto leave;
+    }
+  sig->version = iobuf_get_noeof (inp);
+  pktlen--;
+  if (sig->version == 4)
+    is_v4 = 1;
+  else if (sig->version != 2 && sig->version != 3)
+    {
+      log_error ("packet(%d) with unknown version %d\n",
+                pkttype, sig->version);
+      if (list_mode)
+        es_fputs (":signature packet: [unknown version]\n", listfp);
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+
+  if (!is_v4)
+    {
+      md5_len = iobuf_get_noeof (inp);
+      pktlen--;
+    }
+  sig->sig_class = iobuf_get_noeof (inp);
+  pktlen--;
+  if (!is_v4)
+    {
+      sig->timestamp = read_32 (inp);
+      pktlen -= 4;
+      sig->keyid[0] = read_32 (inp);
+      pktlen -= 4;
+      sig->keyid[1] = read_32 (inp);
+      pktlen -= 4;
+    }
+  sig->pubkey_algo = iobuf_get_noeof (inp);
+  pktlen--;
+  sig->digest_algo = iobuf_get_noeof (inp);
+  pktlen--;
+  sig->flags.exportable = 1;
+  sig->flags.revocable = 1;
+  if (is_v4) /* Read subpackets.  */
+    {
+      n = read_16 (inp);
+      pktlen -= 2;  /* Length of hashed data. */
+      if (n > 10000)
+       {
+         log_error ("signature packet: hashed data too long\n");
+          if (list_mode)
+            es_fputs (":signature packet: [hashed data too long]\n", listfp);
+         rc = G10ERR_INVALID_PACKET;
+         goto leave;
        }
-       if( n ) {
-           sig->hashed = xmalloc (sizeof (*sig->hashed) + n - 1 );
-            sig->hashed->size = n;
-           sig->hashed->len = n;
-           if( iobuf_read (inp, sig->hashed->data, n ) != n ) {
-               log_error ("premature eof while reading "
-                           "hashed signature data\n");
-               rc = -1;
-               goto leave;
+      if (n)
+       {
+         sig->hashed = xmalloc (sizeof (*sig->hashed) + n - 1);
+         sig->hashed->size = n;
+         sig->hashed->len = n;
+         if (iobuf_read (inp, sig->hashed->data, n) != n)
+           {
+             log_error ("premature eof while reading "
+                        "hashed signature data\n");
+              if (list_mode)
+                es_fputs (":signature packet: [premature eof]\n", listfp);
+             rc = -1;
+             goto leave;
            }
-           pktlen -= n;
+         pktlen -= n;
        }
-       n = read_16(inp); pktlen -= 2; /* length of unhashed data */
-       if( n > 10000 ) {
-           log_error("signature packet: unhashed data too long\n");
-           rc = G10ERR_INVALID_PACKET;
-           goto leave;
+      n = read_16 (inp);
+      pktlen -= 2;  /* Length of unhashed data.  */
+      if (n > 10000)
+       {
+         log_error ("signature packet: unhashed data too long\n");
+          if (list_mode)
+            es_fputs (":signature packet: [unhashed data too long]\n", listfp);
+         rc = G10ERR_INVALID_PACKET;
+         goto leave;
        }
-       if( n ) {
-           sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n - 1 );
-            sig->unhashed->size = n;
-           sig->unhashed->len = n;
-           if( iobuf_read(inp, sig->unhashed->data, n ) != n ) {
-               log_error("premature eof while reading "
-                          "unhashed signature data\n");
-               rc = -1;
-               goto leave;
+      if (n)
+       {
+         sig->unhashed = xmalloc (sizeof (*sig->unhashed) + n - 1);
+         sig->unhashed->size = n;
+         sig->unhashed->len = n;
+         if (iobuf_read (inp, sig->unhashed->data, n) != n)
+           {
+             log_error ("premature eof while reading "
+                        "unhashed signature data\n");
+              if (list_mode)
+                es_fputs (":signature packet: [premature eof]\n", listfp);
+             rc = -1;
+             goto leave;
            }
-           pktlen -= n;
+         pktlen -= n;
        }
     }
 
-    if( pktlen < 5 ) { /* sanity check */
-       log_error("packet(%d) too short\n", pkttype);
-       rc = G10ERR_INVALID_PACKET;
-       goto leave;
+  if (pktlen < 5)  /* Sanity check.  */
+    {
+      log_error ("packet(%d) too short\n", pkttype);
+      if (list_mode)
+        es_fputs (":signature packet: [too short]\n", listfp);
+      rc = G10ERR_INVALID_PACKET;
+      goto leave;
     }
 
-    sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--;
-    sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--;
+  sig->digest_start[0] = iobuf_get_noeof (inp);
+  pktlen--;
+  sig->digest_start[1] = iobuf_get_noeof (inp);
+  pktlen--;
 
-    if( is_v4 && sig->pubkey_algo )
-      { /*extract required information */
-       const byte *p;
-       size_t len;
-
-       /* set sig->flags.unknown_critical if there is a
-        * critical bit set for packets which we do not understand */
-       if( !parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
-           || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL,
-                                 NULL) )
-         sig->flags.unknown_critical = 1;
+  if (is_v4 && sig->pubkey_algo)  /* Extract required information.  */
+    {
+      const byte *p;
+      size_t len;
+
+      /* Set sig->flags.unknown_critical if there is a critical bit
+       * set for packets which we do not understand.  */
+      if (!parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
+         || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL, NULL))
+       sig->flags.unknown_critical = 1;
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL);
+      if (p)
+       sig->timestamp = buffer_to_u32 (p);
+      else if (!(sig->pubkey_algo >= 100 && sig->pubkey_algo <= 110)
+              && opt.verbose)
+       log_info ("signature packet without timestamp\n");
+
+      p = parse_sig_subpkt2 (sig, SIGSUBPKT_ISSUER, NULL);
+      if (p)
+       {
+         sig->keyid[0] = buffer_to_u32 (p);
+         sig->keyid[1] = buffer_to_u32 (p + 4);
+       }
+      else if (!(sig->pubkey_algo >= 100 && sig->pubkey_algo <= 110)
+              && opt.verbose)
+       log_info ("signature packet without keyid\n");
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL);
+      if (p && buffer_to_u32 (p))
+       sig->expiredate = sig->timestamp + buffer_to_u32 (p);
+      if (sig->expiredate && sig->expiredate <= make_timestamp ())
+       sig->flags.expired = 1;
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, NULL);
+      if (p)
+       sig->flags.policy_url = 1;
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, NULL);
+      if (p)
+       sig->flags.pref_ks = 1;
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_NOTATION, NULL);
+      if (p)
+       sig->flags.notation = 1;
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_REVOCABLE, NULL);
+      if (p && *p == 0)
+       sig->flags.revocable = 0;
+
+      p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_TRUST, &len);
+      if (p && len == 2)
+       {
+         sig->trust_depth = p[0];
+         sig->trust_value = p[1];
+
+         /* Only look for a regexp if there is also a trust
+            subpacket. */
+         sig->trust_regexp =
+           parse_sig_subpkt (sig->hashed, SIGSUBPKT_REGEXP, &len);
+
+         /* If the regular expression is of 0 length, there is no
+            regular expression. */
+         if (len == 0)
+           sig->trust_regexp = NULL;
+       }
 
-       p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
-       if(p)
-         sig->timestamp = buf32_to_u32 (p);
-       else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110)
-               && opt.verbose)
-         log_info ("signature packet without timestamp\n");
+      /* We accept the exportable subpacket from either the hashed or
+         unhashed areas as older versions of gpg put it in the
+         unhashed area.  In theory, anyway, we should never see this
+         packet off of a local keyring. */
 
-       p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
-       if(p)
-         {
-           sig->keyid[0] = buf32_to_u32 (p);
-           sig->keyid[1] = buf32_to_u32 (p+4);
-         }
-       else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110)
-               && opt.verbose)
-         log_info ("signature packet without keyid\n");
-
-       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
-       if(p && buf32_to_u32 (p))
-         sig->expiredate = sig->timestamp + buf32_to_u32 (p);
-       if(sig->expiredate && sig->expiredate<=make_timestamp())
-         sig->flags.expired=1;
-
-       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
-       if(p)
-         sig->flags.policy_url=1;
-
-       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL);
-       if(p)
-         sig->flags.pref_ks=1;
-
-       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
-       if(p)
-         sig->flags.notation=1;
-
-       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
-       if(p && *p==0)
-         sig->flags.revocable=0;
-
-       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_TRUST,&len);
-       if(p && len==2)
-         {
-           sig->trust_depth=p[0];
-           sig->trust_value=p[1];
-
-           /* Only look for a regexp if there is also a trust
-              subpacket. */
-           sig->trust_regexp=
-             parse_sig_subpkt(sig->hashed,SIGSUBPKT_REGEXP,&len);
-
-           /* If the regular expression is of 0 length, there is no
-              regular expression. */
-           if(len==0)
-             sig->trust_regexp=NULL;
-         }
+      p = parse_sig_subpkt2 (sig, SIGSUBPKT_EXPORTABLE, NULL);
+      if (p && *p == 0)
+       sig->flags.exportable = 0;
 
-       /* We accept the exportable subpacket from either the hashed
-          or unhashed areas as older versions of gpg put it in the
-          unhashed area.  In theory, anyway, we should never see this
-          packet off of a local keyring. */
+      /* Find all revocation keys.  */
+      if (sig->sig_class == 0x1F)
+       parse_revkeys (sig);
+    }
 
-       p=parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
-       if(p && *p==0)
-         sig->flags.exportable=0;
+  if (list_mode)
+    {
+      es_fprintf (listfp, ":signature packet: algo %d, keyid %08lX%08lX\n"
+                  "\tversion %d, created %lu, md5len %d, sigclass 0x%02x\n"
+                  "\tdigest algo %d, begin of digest %02x %02x\n",
+                  sig->pubkey_algo,
+                  (ulong) sig->keyid[0], (ulong) sig->keyid[1],
+                  sig->version, (ulong) sig->timestamp, md5_len, sig->sig_class,
+                  sig->digest_algo, sig->digest_start[0], sig->digest_start[1]);
+      if (is_v4)
+       {
+         parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL);
+         parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
+       }
+    }
 
-       /* Find all revocation keys. */
-       if(sig->sig_class==0x1F)
-         parse_revkeys(sig);
-      }
+  ndata = pubkey_get_nsig (sig->pubkey_algo);
+  if (!ndata)
+    {
+      if (list_mode)
+       es_fprintf (listfp, "\tunknown algorithm %d\n", sig->pubkey_algo);
+      unknown_pubkey_warning (sig->pubkey_algo);
 
-    if( list_mode ) {
-       fprintf (listfp, ":signature packet: algo %d, keyid %08lX%08lX\n"
-              "\tversion %d, created %lu, md5len %d, sigclass 0x%02x\n"
-              "\tdigest algo %d, begin of digest %02x %02x\n",
-               sig->pubkey_algo,
-               (ulong)sig->keyid[0], (ulong)sig->keyid[1],
-               sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
-               sig->digest_algo,
-               sig->digest_start[0], sig->digest_start[1] );
-       if( is_v4 ) {
-           parse_sig_subpkt (sig->hashed,   SIGSUBPKT_LIST_HASHED, NULL );
-           parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
+      /* We store the plain material in data[0], so that we are able
+       * to write it back with build_packet().  */
+      if (pktlen > (5 * MAX_EXTERN_MPI_BITS / 8))
+       {
+         /* We include a limit to avoid too trivial DoS attacks by
+            having gpg allocate too much memory.  */
+         log_error ("signature packet: too much data\n");
+         rc = G10ERR_INVALID_PACKET;
+       }
+      else
+       {
+         sig->data[0] =
+           gcry_mpi_set_opaque (NULL, read_rest (inp, pktlen), pktlen * 8);
+         pktlen = 0;
        }
     }
-
-    ndata = pubkey_get_nsig(sig->pubkey_algo);
-    if( !ndata ) {
-       if( list_mode )
-           fprintf (listfp, "\tunknown algorithm %d\n", sig->pubkey_algo );
-       unknown_pubkey_warning( sig->pubkey_algo );
-       /* We store the plain material in data[0], so that we are able
-        * to write it back with build_packet() */
-        if (pktlen > (5 * MAX_EXTERN_MPI_BITS/8))
-          {
-            /* However we include a limit to avoid too trivial DoS
-               attacks by having gpg allocate too much memory.  */
-           log_error ("signature packet: too much data\n");
-           rc = G10ERR_INVALID_PACKET;
-          }
-        else
-          {
-            sig->data[0]= gcry_mpi_set_opaque (NULL, read_rest(inp, pktlen, 0),
-                                               pktlen*8 );
-            pktlen = 0;
-          }
-    }
-    else {
-       for( i=0; i < ndata; i++ ) {
-           n = pktlen;
-           sig->data[i] = mpi_read(inp, &n, 0 );
-           pktlen -=n;
-           if( list_mode ) {
-               fprintf (listfp, "\tdata: ");
-               mpi_print(listfp, sig->data[i], mpi_print_mode );
-               putc ('\n', listfp);
+  else
+    {
+      for (i = 0; i < ndata; i++)
+       {
+         n = pktlen;
+         sig->data[i] = mpi_read (inp, &n, 0);
+         pktlen -= n;
+         if (list_mode)
+           {
+             es_fprintf (listfp, "\tdata: ");
+             mpi_print (listfp, sig->data[i], mpi_print_mode);
+             es_putc ('\n', listfp);
            }
-            if (!sig->data[i])
-                rc = G10ERR_INVALID_PACKET;
+         if (!sig->data[i])
+           rc = G10ERR_INVALID_PACKET;
        }
     }
 
 leave:
-    iobuf_skip_rest(inp, pktlen, 0);
-    return rc;
+ leave:
+  iobuf_skip_rest (inp, pktlen, 0);
+  return rc;
 }
 
 
 static int
-parse_onepass_sigIOBUF inp, int pkttype, unsigned long pktlen,
-                                            PKT_onepass_sig *ops )
+parse_onepass_sig (IOBUF inp, int pkttype, unsigned long pktlen,
+                  PKT_onepass_sig * ops)
 {
-    int version;
-    int rc = 0;
-
-    if( pktlen < 13 ) {
-       log_error("packet(%d) too short\n", pkttype);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    version = iobuf_get_noeof(inp); pktlen--;
-    if( version != 3 ) {
-       log_error("onepass_sig with unknown version %d\n", version);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    ops->sig_class = iobuf_get_noeof(inp); pktlen--;
-    ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
-    ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
-    ops->keyid[0] = read_32(inp); pktlen -= 4;
-    ops->keyid[1] = read_32(inp); pktlen -= 4;
-    ops->last = iobuf_get_noeof(inp); pktlen--;
-    if( list_mode )
-       fprintf (listfp,
-                 ":onepass_sig packet: keyid %08lX%08lX\n"
-                 "\tversion %d, sigclass 0x%02x, digest %d, pubkey %d, "
-                 "last=%d\n",
-               (ulong)ops->keyid[0], (ulong)ops->keyid[1],
-               version, ops->sig_class,
-               ops->digest_algo, ops->pubkey_algo, ops->last );
-
-
-  leave:
-    iobuf_skip_rest(inp, pktlen, 0);
-    return rc;
-}
-
-
-static gcry_mpi_t
-read_protected_v3_mpi (IOBUF inp, unsigned long *length)
-{
-  int c;
-  unsigned int nbits, nbytes;
-  unsigned char *buf, *p;
-  gcry_mpi_t val;
-
-  if (*length < 2)
-    {
-      log_error ("mpi too small\n");
-      return NULL;
-    }
-
-  if ((c=iobuf_get (inp)) == -1)
-    return NULL;
-  --*length;
-  nbits = c << 8;
-  if ((c=iobuf_get(inp)) == -1)
-    return NULL;
-  --*length;
-  nbits |= c;
+  int version;
+  int rc = 0;
 
-  if (nbits > 16384)
+  if (pktlen < 13)
     {
-      log_error ("mpi too large (%u bits)\n", nbits);
-      return NULL;
+      log_error ("packet(%d) too short\n", pkttype);
+      if (list_mode)
+        es_fputs (":onepass_sig packet: [too short]\n", listfp);
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
     }
-  nbytes = (nbits+7) / 8;
-  buf = p = xmalloc (2 + nbytes);
-  *p++ = nbits >> 8;
-  *p++ = nbits;
-  for (; nbytes && *length; nbytes--, --*length)
-    *p++ = iobuf_get (inp);
-  if (nbytes)
+  version = iobuf_get_noeof (inp);
+  pktlen--;
+  if (version != 3)
     {
-      log_error ("packet shorter than mpi\n");
-      xfree (buf);
-      return NULL;
+      log_error ("onepass_sig with unknown version %d\n", version);
+      if (list_mode)
+        es_fputs (":onepass_sig packet: [unknown version]\n", listfp);
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
     }
+  ops->sig_class = iobuf_get_noeof (inp);
+  pktlen--;
+  ops->digest_algo = iobuf_get_noeof (inp);
+  pktlen--;
+  ops->pubkey_algo = iobuf_get_noeof (inp);
+  pktlen--;
+  ops->keyid[0] = read_32 (inp);
+  pktlen -= 4;
+  ops->keyid[1] = read_32 (inp);
+  pktlen -= 4;
+  ops->last = iobuf_get_noeof (inp);
+  pktlen--;
+  if (list_mode)
+    es_fprintf (listfp,
+                ":onepass_sig packet: keyid %08lX%08lX\n"
+                "\tversion %d, sigclass 0x%02x, digest %d, pubkey %d, "
+                "last=%d\n",
+                (ulong) ops->keyid[0], (ulong) ops->keyid[1],
+                version, ops->sig_class,
+                ops->digest_algo, ops->pubkey_algo, ops->last);
+
 
-  /* convert buffer into an opaque MPI */
-  val = gcry_mpi_set_opaque (NULL, buf, (p-buf)*8);
-  return val;
+ leave:
+  iobuf_skip_rest (inp, pktlen, 0);
+  return rc;
 }
 
 
 static int
 parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
-           byte *hdr, int hdrlen, PACKET *pkt)
+          byte * hdr, int hdrlen, PACKET * pkt)
 {
-    int i, version, algorithm;
-    unsigned n;
-    unsigned long timestamp, expiredate, max_expiredate;
-    int npkey, nskey;
-    int is_v4=0;
-    int rc=0;
-    u32 keyid[2];
-
-    (void)hdr;
-
-    version = iobuf_get_noeof(inp); pktlen--;
-    if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
-       /* early versions of G10 use old PGP comments packets;
-        * luckily all those comments are started by a hash */
-       if( list_mode ) {
-           fprintf (listfp, ":rfc1991 comment packet: \"" );
-           for( ; pktlen; pktlen-- ) {
-               int c;
-               c = iobuf_get_noeof(inp);
-               if( c >= ' ' && c <= 'z' )
-                   putc (c, listfp);
-               else
-                   fprintf (listfp, "\\x%02x", c );
+  gpg_error_t err = 0;
+  int i, version, algorithm;
+  unsigned long timestamp, expiredate, max_expiredate;
+  int npkey, nskey;
+  int rc = 0;
+  u32 keyid[2];
+  PKT_public_key *pk;
+
+  (void) hdr;
+
+  pk = pkt->pkt.public_key; /* PK has been cleared. */
+
+  version = iobuf_get_noeof (inp);
+  pktlen--;
+  if (pkttype == PKT_PUBLIC_SUBKEY && version == '#')
+    {
+      /* Early versions of G10 used the old PGP comments packets;
+       * luckily all those comments are started by a hash.  */
+      if (list_mode)
+       {
+         es_fprintf (listfp, ":rfc1991 comment packet: \"");
+         for (; pktlen; pktlen--)
+           {
+             int c;
+             c = iobuf_get (inp);
+              if (c == -1)
+                break; /* Ooops: shorter than indicated.  */
+             if (c >= ' ' && c <= 'z')
+               es_putc (c, listfp);
+             else
+               es_fprintf (listfp, "\\x%02x", c);
            }
-           fprintf (listfp, "\"\n");
+         es_fprintf (listfp, "\"\n");
        }
-       iobuf_skip_rest(inp, pktlen, 0);
-       return 0;
+      iobuf_skip_rest (inp, pktlen, 0);
+      return 0;
+    }
+  else if (version == 4)
+    {
+      /* The only supported version.  Use an older gpg
+         versions (i.e. gpg 1.4 to parse v3 packets).  */
+    }
+  else if (version == 2 || version == 3)
+    {
+      if (opt.verbose > 1)
+        log_info ("packet(%d) with obsolete version %d\n", pkttype, version);
+      if (list_mode)
+        es_fprintf (listfp, ":key packet: [obsolete version %d]\n", version);
+      pk->version = version;
+      err = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  else
+    {
+      log_error ("packet(%d) with unknown version %d\n", pkttype, version);
+      if (list_mode)
+        es_fputs (":key packet: [unknown version]\n", listfp);
+      err = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
     }
-    else if( version == 4 )
-       is_v4=1;
-    else if( version != 2 && version != 3 ) {
-       log_error("packet(%d) with unknown version %d\n", pkttype, version);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-
-    if( pktlen < 11 ) {
-       log_error("packet(%d) too short\n", pkttype);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    else if (pktlen > MAX_KEY_PACKET_LENGTH) {
-        log_error ("packet(%d) too large\n", pkttype);
-        if (list_mode)
-            fputs (":key packet: [too large]\n", listfp);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-        goto leave;
-    }
-
-    timestamp = read_32(inp); pktlen -= 4;
-    if( is_v4 ) {
-       expiredate = 0; /* have to get it from the selfsignature */
-       max_expiredate = 0;
-    }
-    else {
-       unsigned short ndays;
-       ndays = read_16(inp); pktlen -= 2;
-       if( ndays )
-           expiredate = timestamp + ndays * 86400L;
-       else
-           expiredate = 0;
-
-       max_expiredate=expiredate;
-    }
-    algorithm = iobuf_get_noeof(inp); pktlen--;
-    if( list_mode )
-       fprintf (listfp, ":%s key packet:\n"
-              "\tversion %d, algo %d, created %lu, expires %lu\n",
-               pkttype == PKT_PUBLIC_KEY? "public" :
-               pkttype == PKT_SECRET_KEY? "secret" :
-               pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
-               pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
-               version, algorithm, timestamp, expiredate );
-
-    if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY )  {
-       PKT_secret_key *sk = pkt->pkt.secret_key;
-
-       sk->timestamp = timestamp;
-       sk->expiredate = expiredate;
-       sk->max_expiredate = max_expiredate;
-       sk->hdrbytes = hdrlen;
-       sk->version = version;
-       sk->is_primary = pkttype == PKT_SECRET_KEY;
-       sk->pubkey_algo = algorithm;
-       sk->req_usage = 0;
-       sk->pubkey_usage = 0; /* not yet used */
-    }
-    else {
-       PKT_public_key *pk = pkt->pkt.public_key;
-
-       pk->timestamp = timestamp;
-       pk->expiredate = expiredate;
-       pk->max_expiredate = max_expiredate;
-       pk->hdrbytes    = hdrlen;
-       pk->version     = version;
-       pk->is_primary = pkttype == PKT_PUBLIC_KEY;
-       pk->pubkey_algo = algorithm;
-       pk->req_usage = 0;
-       pk->pubkey_usage = 0; /* not yet used */
-        pk->is_revoked = 0;
-       pk->is_disabled = 0;
-       pk->keyid[0] = 0;
-       pk->keyid[1] = 0;
-    }
-    nskey = pubkey_get_nskey( algorithm );
-    npkey = pubkey_get_npkey( algorithm );
-    if( !npkey ) {
-       if( list_mode )
-           fprintf (listfp, "\tunknown algorithm %d\n", algorithm );
-       unknown_pubkey_warning( algorithm );
-    }
-
-
-    if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
-       PKT_secret_key *sk = pkt->pkt.secret_key;
-       byte temp[16];
-        size_t snlen = 0;
-
-        if (pktlen < 1)
-          {
-            rc = GPG_ERR_INV_PACKET;
-            goto leave;
-          }
 
-       if( !npkey ) {
-           sk->skey[0] = gcry_mpi_set_opaque (NULL, read_rest(inp, pktlen, 0),
-                                               pktlen*8 );
-           pktlen = 0;
-           goto leave;
-       }
+  if (pktlen < 11)
+    {
+      log_error ("packet(%d) too short\n", pkttype);
+      if (list_mode)
+        es_fputs (":key packet: [too short]\n", listfp);
+      err = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
 
-       for(i=0; i < npkey; i++ ) {
-           n = pktlen;
-            sk->skey[i] = mpi_read(inp, &n, 0 );
-            pktlen -=n;
-           if( list_mode ) {
-               fprintf (listfp,   "\tskey[%d]: ", i);
-               mpi_print(listfp, sk->skey[i], mpi_print_mode  );
-               putc ('\n', listfp);
-           }
-            if (!sk->skey[i])
-                rc = G10ERR_INVALID_PACKET;
-       }
-        if (rc) /* one of the MPIs were bad */
+  timestamp = read_32 (inp);
+  pktlen -= 4;
+  expiredate = 0;              /* have to get it from the selfsignature */
+  max_expiredate = 0;
+  algorithm = iobuf_get_noeof (inp);
+  pktlen--;
+  if (list_mode)
+    es_fprintf (listfp, ":%s key packet:\n"
+                "\tversion %d, algo %d, created %lu, expires %lu\n",
+                pkttype == PKT_PUBLIC_KEY ? "public" :
+                pkttype == PKT_SECRET_KEY ? "secret" :
+                pkttype == PKT_PUBLIC_SUBKEY ? "public sub" :
+                pkttype == PKT_SECRET_SUBKEY ? "secret sub" : "??",
+                version, algorithm, timestamp, expiredate);
+
+  pk->timestamp = timestamp;
+  pk->expiredate = expiredate;
+  pk->max_expiredate = max_expiredate;
+  pk->hdrbytes = hdrlen;
+  pk->version = version;
+  pk->flags.primary = (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY);
+  pk->pubkey_algo = algorithm;
+
+  nskey = pubkey_get_nskey (algorithm);
+  npkey = pubkey_get_npkey (algorithm);
+  if (!npkey)
+    {
+      if (list_mode)
+       es_fprintf (listfp, "\tunknown algorithm %d\n", algorithm);
+      unknown_pubkey_warning (algorithm);
+    }
+
+  if (!npkey)
+    {
+      /* Unknown algorithm - put data into an opaque MPI.  */
+      pk->pkey[0] = gcry_mpi_set_opaque (NULL,
+                                         read_rest (inp, pktlen), pktlen * 8);
+      pktlen = 0;
+      goto leave;
+    }
+  else
+    {
+      for (i = 0; i < npkey; i++)
+        {
+          if (    (algorithm == PUBKEY_ALGO_ECDSA && (i == 0))
+               || (algorithm == PUBKEY_ALGO_EDDSA && (i == 0))
+               || (algorithm == PUBKEY_ALGO_ECDH  && (i == 0 || i == 2)))
+            {
+              /* Read the OID (i==1) or the KDF params (i==2).  */
+              size_t n;
+             err = read_size_body (inp, pktlen, &n, pk->pkey+i);
+              pktlen -= n;
+            }
+          else
+            {
+              unsigned int n = pktlen;
+              pk->pkey[i] = mpi_read (inp, &n, 0);
+              pktlen -= n;
+              if (!pk->pkey[i])
+                err = gpg_error (GPG_ERR_INV_PACKET);
+            }
+          if (err)
             goto leave;
-       sk->protect.algo = iobuf_get_noeof(inp);
-        pktlen--;
-        sk->protect.sha1chk = 0;
-       if( sk->protect.algo ) {
-           sk->is_protected = 1;
-           sk->protect.s2k.count = 0;
-           if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
-               if( pktlen < 3 ) {
-                   rc = G10ERR_INVALID_PACKET;
-                   goto leave;
+          if (list_mode)
+            {
+              es_fprintf (listfp, "\tpkey[%d]: ", i);
+              mpi_print (listfp, pk->pkey[i], mpi_print_mode);
+              if ((algorithm == PUBKEY_ALGO_ECDSA
+                   || algorithm == PUBKEY_ALGO_EDDSA
+                   || algorithm == PUBKEY_ALGO_ECDH) && i==0)
+                {
+                  char *curve = openpgp_oid_to_str (pk->pkey[0]);
+                  es_fprintf (listfp, " %s (%s)",
+                              openpgp_oid_to_curve (curve), curve);
+                  xfree (curve);
+                }
+              es_putc ('\n', listfp);
+            }
+        }
+    }
+  if (list_mode)
+    keyid_from_pk (pk, keyid);
+
+  if (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY)
+    {
+      struct seckey_info *ski;
+      byte temp[16];
+      size_t snlen = 0;
+
+      pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
+      if (!pk->seckey_info)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+
+      ski->algo = iobuf_get_noeof (inp);
+      pktlen--;
+      if (ski->algo)
+       {
+         ski->is_protected = 1;
+         ski->s2k.count = 0;
+         if (ski->algo == 254 || ski->algo == 255)
+           {
+             if (pktlen < 3)
+               {
+                 err = gpg_error (GPG_ERR_INV_PACKET);
+                 goto leave;
                }
-                sk->protect.sha1chk = (sk->protect.algo == 254);
-               sk->protect.algo = iobuf_get_noeof(inp);
-                pktlen--;
-               /* Note that a sk->protect.algo > 110 is illegal, but
-                  I'm not erroring on it here as otherwise there
-                  would be no way to delete such a key. */
-               sk->protect.s2k.mode  = iobuf_get_noeof(inp);
-                pktlen--;
-               sk->protect.s2k.hash_algo = iobuf_get_noeof(inp);
-                pktlen--;
-               /* check for the special GNU extension */
-               if( is_v4 && sk->protect.s2k.mode == 101 ) {
-                   for(i=0; i < 4 && pktlen; i++, pktlen-- )
-                       temp[i] = iobuf_get_noeof(inp);
-                   if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
-                       if( list_mode )
-                           fprintf (listfp,   "\tunknown S2K %d\n",
-                                               sk->protect.s2k.mode );
-                       rc = G10ERR_INVALID_PACKET;
-                       goto leave;
+             ski->sha1chk = (ski->algo == 254);
+             ski->algo = iobuf_get_noeof (inp);
+             pktlen--;
+             /* Note that a ski->algo > 110 is illegal, but I'm not
+                erroring on it here as otherwise there would be no
+                way to delete such a key.  */
+             ski->s2k.mode = iobuf_get_noeof (inp);
+             pktlen--;
+             ski->s2k.hash_algo = iobuf_get_noeof (inp);
+             pktlen--;
+             /* Check for the special GNU extension.  */
+             if (ski->s2k.mode == 101)
+               {
+                 for (i = 0; i < 4 && pktlen; i++, pktlen--)
+                   temp[i] = iobuf_get_noeof (inp);
+                 if (i < 4 || memcmp (temp, "GNU", 3))
+                   {
+                     if (list_mode)
+                       es_fprintf (listfp, "\tunknown S2K %d\n",
+                                    ski->s2k.mode);
+                     err = gpg_error (GPG_ERR_INV_PACKET);
+                     goto leave;
                    }
-                   /* here we know that it is a gnu extension
-                    * What follows is the GNU protection mode:
-                    * All values have special meanings
-                    * and they are mapped in the mode with a base of 1000.
-                    */
-                   sk->protect.s2k.mode = 1000 + temp[3];
+                 /* Here we know that it is a GNU extension.  What
+                  * follows is the GNU protection mode: All values
+                  * have special meanings and they are mapped to MODE
+                  * with a base of 1000.  */
+                 ski->s2k.mode = 1000 + temp[3];
                }
-               switch( sk->protect.s2k.mode ) {
-                 case 1:
-                 case 3:
-                   for(i=0; i < 8 && pktlen; i++, pktlen-- )
-                       temp[i] = iobuf_get_noeof(inp);
-                   memcpy(sk->protect.s2k.salt, temp, 8 );
-                   break;
+
+              /* Read the salt.  */
+             switch (ski->s2k.mode)
+               {
+               case 1:
+               case 3:
+                 for (i = 0; i < 8 && pktlen; i++, pktlen--)
+                   temp[i] = iobuf_get_noeof (inp);
+                 memcpy (ski->s2k.salt, temp, 8);
+                 break;
                }
-               switch( sk->protect.s2k.mode ) {
-                 case 0: if( list_mode ) fprintf (listfp, "\tsimple S2K" );
-                   break;
-                 case 1: if( list_mode ) fprintf (listfp, "\tsalted S2K" );
-                   break;
-                 case 3: if( list_mode ) fprintf (listfp, "\titer+salt S2K" );
-                   break;
-                 case 1001: if( list_mode ) fprintf (listfp,
-                                                      "\tgnu-dummy S2K" );
-                   break;
-                 case 1002: if (list_mode) fprintf (listfp,
-                                                  "\tgnu-divert-to-card S2K");
-                   break;
-                 default:
-                   if( list_mode )
-                       fprintf (listfp,   "\tunknown %sS2K %d\n",
-                                sk->protect.s2k.mode < 1000? "":"GNU ",
-                                                  sk->protect.s2k.mode );
-                   rc = G10ERR_INVALID_PACKET;
-                   goto leave;
+
+              /* Check the mode.  */
+             switch (ski->s2k.mode)
+               {
+               case 0:
+                 if (list_mode)
+                   es_fprintf (listfp, "\tsimple S2K");
+                 break;
+               case 1:
+                 if (list_mode)
+                   es_fprintf (listfp, "\tsalted S2K");
+                 break;
+               case 3:
+                 if (list_mode)
+                   es_fprintf (listfp, "\titer+salt S2K");
+                 break;
+               case 1001:
+                 if (list_mode)
+                   es_fprintf (listfp, "\tgnu-dummy S2K");
+                 break;
+               case 1002:
+                 if (list_mode)
+                   es_fprintf (listfp, "\tgnu-divert-to-card S2K");
+                 break;
+               default:
+                 if (list_mode)
+                   es_fprintf (listfp, "\tunknown %sS2K %d\n",
+                                ski->s2k.mode < 1000 ? "" : "GNU ",
+                                ski->s2k.mode);
+                 err = gpg_error (GPG_ERR_INV_PACKET);
+                 goto leave;
                }
 
-               if( list_mode ) {
-                   fprintf (listfp, ", algo: %d,%s hash: %d",
-                                    sk->protect.algo,
-                                     sk->protect.sha1chk?" SHA1 protection,"
-                                                        :" simple checksum,",
-                                    sk->protect.s2k.hash_algo );
-                   if( sk->protect.s2k.mode == 1
-                       || sk->protect.s2k.mode == 3 ) {
-                       fprintf (listfp, ", salt: ");
-                       for(i=0; i < 8; i++ )
-                           fprintf (listfp, "%02x", sk->protect.s2k.salt[i]);
+              /* Print some info.  */
+             if (list_mode)
+               {
+                 es_fprintf (listfp, ", algo: %d,%s hash: %d",
+                              ski->algo,
+                              ski->sha1chk ? " SHA1 protection,"
+                              : " simple checksum,", ski->s2k.hash_algo);
+                 if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
+                   {
+                     es_fprintf (listfp, ", salt: ");
+                      es_write_hexstring (listfp, ski->s2k.salt, 8, 0, NULL);
                    }
-                   putc ('\n', listfp);
+                 es_putc ('\n', listfp);
                }
 
-               if( sk->protect.s2k.mode == 3 ) {
-                   if( pktlen < 1 ) {
-                       rc = G10ERR_INVALID_PACKET;
-                       goto leave;
+              /* Read remaining protection parameters.  */
+             if (ski->s2k.mode == 3)
+               {
+                 if (pktlen < 1)
+                   {
+                     err = gpg_error (GPG_ERR_INV_PACKET);
+                     goto leave;
                    }
-                   sk->protect.s2k.count = iobuf_get(inp);
-                   pktlen--;
-                   if( list_mode )
-                       fprintf (listfp, "\tprotect count: %lu (%lu)\n",
-                                 (ulong)S2K_DECODE_COUNT
-                                 ((ulong)sk->protect.s2k.count),
-                                 (ulong)sk->protect.s2k.count);
+                 ski->s2k.count = iobuf_get (inp);
+                 pktlen--;
+                 if (list_mode)
+                   es_fprintf (listfp, "\tprotect count: %lu (%lu)\n",
+                                (ulong)S2K_DECODE_COUNT ((ulong)ski->s2k.count),
+                                (ulong) ski->s2k.count);
                }
-               else if( sk->protect.s2k.mode == 1002 ) {
-                    /* Read the serial number. */
-                    if (pktlen < 1) {
-                      rc = G10ERR_INVALID_PACKET;
-                       goto leave;
+             else if (ski->s2k.mode == 1002)
+               {
+                 /* Read the serial number. */
+                 if (pktlen < 1)
+                   {
+                     err = gpg_error (GPG_ERR_INV_PACKET);
+                     goto leave;
+                   }
+                 snlen = iobuf_get (inp);
+                 pktlen--;
+                 if (pktlen < snlen || snlen == (size_t)(-1))
+                   {
+                     err = gpg_error (GPG_ERR_INV_PACKET);
+                     goto leave;
                    }
-                   snlen = iobuf_get (inp);
-                   pktlen--;
-                    if (pktlen < snlen || snlen == -1) {
-                       rc = G10ERR_INVALID_PACKET;
-                       goto leave;
-                    }
                }
            }
-           /* Note that a sk->protect.algo > 110 is illegal, but I'm
-              not erroring on it here as otherwise there would be no
-              way to delete such a key. */
-           else { /* old version; no S2K, so we set mode to 0, hash MD5 */
-               sk->protect.s2k.mode = 0;
-               sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
-               if( list_mode )
-                   fprintf (listfp,   "\tprotect algo: %d  (hash algo: %d)\n",
-                        sk->protect.algo, sk->protect.s2k.hash_algo );
+         else /* Old version; no S2K, so we set mode to 0, hash MD5.  */
+           {
+              /* Note that a ski->algo > 110 is illegal, but I'm not
+                 erroring on it here as otherwise there would be no
+                 way to delete such a key.  */
+             ski->s2k.mode = 0;
+             ski->s2k.hash_algo = DIGEST_ALGO_MD5;
+             if (list_mode)
+               es_fprintf (listfp, "\tprotect algo: %d  (hash algo: %d)\n",
+                            ski->algo, ski->s2k.hash_algo);
            }
-           /* It is really ugly that we don't know the size
-            * of the IV here in cases we are not aware of the algorithm.
-            * so a
-            *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
-            * won't work.  The only solution I see is to hardwire it.
-            * NOTE: if you change the ivlen above 16, don't forget to
-            * enlarge temp.
-            */
-            sk->protect.ivlen = openpgp_cipher_blocklen (sk->protect.algo);
-            assert (sk->protect.ivlen <= sizeof (temp));
-
-           if( sk->protect.s2k.mode == 1001 )
-               sk->protect.ivlen = 0;
-           else if( sk->protect.s2k.mode == 1002 )
-               sk->protect.ivlen = snlen < 16? snlen : 16;
-
-           if( pktlen < sk->protect.ivlen ) {
-               rc = G10ERR_INVALID_PACKET;
-               goto leave;
+
+         /* It is really ugly that we don't know the size
+          * of the IV here in cases we are not aware of the algorithm.
+          * so a
+          *   ski->ivlen = cipher_get_blocksize (ski->algo);
+          * won't work.  The only solution I see is to hardwire it.
+          * NOTE: if you change the ivlen above 16, don't forget to
+          * enlarge temp.  */
+         ski->ivlen = openpgp_cipher_blocklen (ski->algo);
+         assert (ski->ivlen <= sizeof (temp));
+
+         if (ski->s2k.mode == 1001)
+           ski->ivlen = 0;
+         else if (ski->s2k.mode == 1002)
+           ski->ivlen = snlen < 16 ? snlen : 16;
+
+         if (pktlen < ski->ivlen)
+           {
+              err = gpg_error (GPG_ERR_INV_PACKET);
+             goto leave;
            }
-           for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
-               temp[i] = iobuf_get_noeof(inp);
-           if( list_mode ) {
-               fprintf (listfp,
-                         sk->protect.s2k.mode == 1002? "\tserial-number: "
-                                                     : "\tprotect IV: ");
-               for(i=0; i < sk->protect.ivlen; i++ )
-                   fprintf (listfp, " %02x", temp[i] );
-               putc ('\n', listfp);
+         for (i = 0; i < ski->ivlen && pktlen; i++, pktlen--)
+           temp[i] = iobuf_get_noeof (inp);
+         if (list_mode)
+           {
+             es_fprintf (listfp,
+                          ski->s2k.mode == 1002 ? "\tserial-number: "
+                          : "\tprotect IV: ");
+             for (i = 0; i < ski->ivlen; i++)
+               es_fprintf (listfp, " %02x", temp[i]);
+             es_putc ('\n', listfp);
            }
-           memcpy(sk->protect.iv, temp, sk->protect.ivlen );
+         memcpy (ski->iv, temp, ski->ivlen);
        }
-       else
-           sk->is_protected = 0;
-       /* It does not make sense to read it into secure memory.
-        * If the user is so careless, not to protect his secret key,
-        * we can assume, that he operates an open system :=(.
-        * So we put the key into secure memory when we unprotect it. */
-       if( sk->protect.s2k.mode == 1001
-            || sk->protect.s2k.mode == 1002 ) {
-           /* better set some dummy stuff here */
-           sk->skey[npkey] = gcry_mpi_set_opaque(NULL,
-                                                  xstrdup("dummydata"), 10*8);
-           pktlen = 0;
+
+      /* It does not make sense to read it into secure memory.
+       * If the user is so careless, not to protect his secret key,
+       * we can assume, that he operates an open system :=(.
+       * So we put the key into secure memory when we unprotect it. */
+      if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002)
+       {
+         /* Better set some dummy stuff here.  */
+         pk->pkey[npkey] = gcry_mpi_set_opaque (NULL,
+                                                xstrdup ("dummydata"),
+                                                10 * 8);
+         pktlen = 0;
        }
-       else if( is_v4 && sk->is_protected ) {
-           /* ugly; the length is encrypted too, so we read all
-            * stuff up to the end of the packet into the first
-            * skey element */
-           if (pktlen < 2) /* At least two bytes for the length.  */
-             {
-                rc = GPG_ERR_INV_PACKET;
-                goto leave;
-             }
-           sk->skey[npkey] = gcry_mpi_set_opaque (NULL,
-                                                   read_rest(inp, pktlen, 0),
-                                                   pktlen*8);
-           pktlen = 0;
-           if( list_mode ) {
-               fprintf (listfp, "\tencrypted stuff follows\n");
-           }
+      else if (ski->is_protected)
+       {
+         /* Ugly: The length is encrypted too, so we read all stuff
+          * up to the end of the packet into the first SKEY
+          * element.  */
+         pk->pkey[npkey] = gcry_mpi_set_opaque (NULL,
+                                                read_rest (inp, pktlen),
+                                                pktlen * 8);
+          /* Mark that MPI as protected - we need this information for
+             importing a key.  The OPAQUE flag can't be used because
+             we also store public EdDSA values in opaque MPIs.  */
+          if (pk->pkey[npkey])
+            gcry_mpi_set_flag (pk->pkey[npkey], GCRYMPI_FLAG_USER1);
+         pktlen = 0;
+         if (list_mode)
+            es_fprintf (listfp, "\tskey[%d]: [v4 protected]\n", npkey);
        }
-       else { /* v3 method: the mpi length is not encrypted */
-           for(i=npkey; i < nskey; i++ ) {
-                if ( sk->is_protected ) {
-                    sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
-                    if( list_mode )
-                        fprintf (listfp,   "\tskey[%d]: [encrypted]\n", i);
-                }
-                else {
-                    if (pktlen < 2) /* At least two bytes for the length.  */
-                      {
-                        rc = GPG_ERR_INV_PACKET;
-                        goto leave;
-                     }
-                    n = pktlen;
-                    sk->skey[i] = mpi_read(inp, &n, 0 );
-                    pktlen -=n;
-                    if( list_mode ) {
-                        fprintf (listfp,   "\tskey[%d]: ", i);
-                        mpi_print(listfp, sk->skey[i], mpi_print_mode  );
-                        putc ('\n', listfp);
-                    }
+      else
+       {
+          /* Not encrypted.  */
+         for (i = npkey; i < nskey; i++)
+           {
+              unsigned int n = pktlen;
+              pk->pkey[i] = mpi_read (inp, &n, 0);
+              pktlen -= n;
+              if (list_mode)
+                {
+                  es_fprintf (listfp, "\tskey[%d]: ", i);
+                  mpi_print (listfp, pk->pkey[i], mpi_print_mode);
+                  es_putc ('\n', listfp);
                 }
 
-                if (!sk->skey[i])
-                    rc = G10ERR_INVALID_PACKET;
+             if (!pk->pkey[i])
+               err = gpg_error (GPG_ERR_INV_PACKET);
            }
-            if (rc)
-                goto leave;
-
-            if (pktlen < 2)
-              {
-                rc = GPG_ERR_INV_PACKET;
-                goto leave;
-              }
-           sk->csum = read_16(inp);
-            pktlen -= 2;
-           if( list_mode ) {
-               fprintf (listfp, "\tchecksum: %04hx\n", sk->csum);
-           }
-       }
-
-        if (list_mode)
-          keyid_from_sk (sk, keyid);
-    }
-    else {
-       PKT_public_key *pk = pkt->pkt.public_key;
-
-        if (pktlen < 1)
-          {
-            rc = GPG_ERR_INV_PACKET;
-            goto leave;
-          }
-
-       if( !npkey ) {
-           pk->pkey[0] = gcry_mpi_set_opaque ( NULL,
-                                                read_rest(inp, pktlen, 0),
-                                                pktlen*8 );
-           pktlen = 0;
+         if (err)
            goto leave;
-       }
 
-       for(i=0; i < npkey; i++ ) {
-           n = pktlen;
-            pk->pkey[i] = mpi_read(inp, &n, 0 );
-            pktlen -=n;
-           if( list_mode ) {
-               fprintf (listfp,   "\tpkey[%d]: ", i);
-               mpi_print(listfp, pk->pkey[i], mpi_print_mode  );
-               putc ('\n', listfp);
-           }
-            if (!pk->pkey[i])
-                rc = G10ERR_INVALID_PACKET;
+         ski->csum = read_16 (inp);
+         pktlen -= 2;
+         if (list_mode)
+            es_fprintf (listfp, "\tchecksum: %04hx\n", ski->csum);
        }
-        if (rc)
-            goto leave;
-        if (list_mode)
-          keyid_from_pk (pk, keyid);
     }
 
-    if (list_mode)
-      fprintf (listfp, "\tkeyid: %08lX%08lX\n",
-               (ulong)keyid[0], (ulong)keyid[1]);
+  if (list_mode)
+    es_fprintf (listfp, "\tkeyid: %08lX%08lX\n",
+                (ulong) keyid[0], (ulong) keyid[1]);
 
 leave:
-    iobuf_skip_rest(inp, pktlen, 0);
-    return rc;
+ leave:
+  iobuf_skip_rest (inp, pktlen, 0);
+  return rc;
 }
 
+
 /* Attribute subpackets have the same format as v4 signature
    subpackets.  This is not part of OpenPGP, but is done in several
-   versions of PGP nevertheless. */
+   versions of PGP nevertheless.  */
 int
-parse_attribute_subpkts(PKT_user_id *uid)
+parse_attribute_subpkts (PKT_user_id * uid)
 {
   size_t n;
-  int count=0;
-  struct user_attribute *attribs=NULL;
-  const byte *buffer=uid->attrib_data;
-  int buflen=uid->attrib_len;
+  int count = 0;
+  struct user_attribute *attribs = NULL;
+  const byte *buffer = uid->attrib_data;
+  int buflen = uid->attrib_len;
   byte type;
 
-  xfree(uid->attribs);
+  xfree (uid->attribs);
 
-  while(buflen)
+  while (buflen)
     {
-      n = *buffer++; buflen--;
-      if( n == 255 ) { /* 4 byte length header */
-       if( buflen < 4 )
-         goto too_short;
-        n = buf32_to_size_t (buffer);
-        buffer += 4;
-       buflen -= 4;
-      }
-      else if( n >= 192 ) { /* 2 byte special encoded length header */
-       if( buflen < 2 )
-         goto too_short;
-       n = (( n - 192 ) << 8) + *buffer + 192;
-       buffer++;
-       buflen--;
-      }
-      if( buflen < n )
+      n = *buffer++;
+      buflen--;
+      if (n == 255)  /* 4 byte length header.  */
+       {
+         if (buflen < 4)
+           goto too_short;
+         n = (buffer[0] << 24) | (buffer[1] << 16)
+           | (buffer[2] << 8) | buffer[3];
+         buffer += 4;
+         buflen -= 4;
+       }
+      else if (n >= 192)  /* 2 byte special encoded length header.  */
+       {
+         if (buflen < 2)
+           goto too_short;
+         n = ((n - 192) << 8) + *buffer + 192;
+         buffer++;
+         buflen--;
+       }
+      if (buflen < n)
        goto too_short;
 
-      if (!n)
-        {
-          /* Too short to encode the subpacket type.  */
-          if (opt.verbose)
-            log_info ("attribute subpacket too short\n");
-          break;
-        }
-
-      attribs=xrealloc(attribs,(count+1)*sizeof(struct user_attribute));
-      memset(&attribs[count],0,sizeof(struct user_attribute));
+      attribs =
+       xrealloc (attribs, (count + 1) * sizeof (struct user_attribute));
+      memset (&attribs[count], 0, sizeof (struct user_attribute));
 
-      type=*buffer;
+      type = *buffer;
       buffer++;
       buflen--;
       n--;
 
-      attribs[count].type=type;
-      attribs[count].data=buffer;
-      attribs[count].len=n;
-      buffer+=n;
-      buflen-=n;
+      attribs[count].type = type;
+      attribs[count].data = buffer;
+      attribs[count].len = n;
+      buffer += n;
+      buflen -= n;
       count++;
     }
 
-  uid->attribs=attribs;
-  uid->numattribs=count;
+  uid->attribs = attribs;
+  uid->numattribs = count;
   return count;
 
  too_short:
-  if(opt.verbose)
-    log_info("buffer shorter than attribute subpacket\n");
-  uid->attribs=attribs;
-  uid->numattribs=count;
+  if (opt.verbose)
+    log_info ("buffer shorter than attribute subpacket\n");
+  uid->attribs = attribs;
+  uid->numattribs = count;
   return count;
 }
 
 
 static int
-parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
+parse_user_id (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * packet)
 {
-    byte *p;
+  byte *p;
 
-    /* Cap the size of a user ID at 2k: a value absurdly large enough
-       that there is no sane user ID string (which is printable text
-       as of RFC2440bis) that won't fit in it, but yet small enough to
-       avoid allocation problems.  A large pktlen may not be
-       allocatable, and a very large pktlen could actually cause our
-       allocation to wrap around in xmalloc to a small number. */
+  /* Cap the size of a user ID at 2k: a value absurdly large enough
+     that there is no sane user ID string (which is printable text
+     as of RFC2440bis) that won't fit in it, but yet small enough to
+     avoid allocation problems.  A large pktlen may not be
+     allocatable, and a very large pktlen could actually cause our
+     allocation to wrap around in xmalloc to a small number. */
 
-    if (pktlen > MAX_UID_PACKET_LENGTH)
-      {
-       log_error ("packet(%d) too large\n", pkttype);
-       iobuf_skip_rest(inp, pktlen, 0);
-       return G10ERR_INVALID_PACKET;
-      }
+  if (pktlen > 2048)
+    {
+      log_error ("packet(%d) too large\n", pkttype);
+      if (list_mode)
+        es_fprintf (listfp, ":user ID packet: [too large]\n");
+      iobuf_skip_rest (inp, pktlen, 0);
+      return G10ERR_INVALID_PACKET;
+    }
 
-    packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen);
-    packet->pkt.user_id->len = pktlen;
-    packet->pkt.user_id->ref=1;
-
-    p = packet->pkt.user_id->name;
-    for( ; pktlen; pktlen--, p++ )
-       *p = iobuf_get_noeof(inp);
-    *p = 0;
-
-    if( list_mode ) {
-       int n = packet->pkt.user_id->len;
-       fprintf (listfp, ":user ID packet: \"");
-       /* fixme: Hey why don't we replace this with print_string?? */
-       for(p=packet->pkt.user_id->name; n; p++, n-- ) {
-           if( *p >= ' ' && *p <= 'z' )
-               putc (*p, listfp);
-           else
-               fprintf (listfp, "\\x%02x", *p );
+  packet->pkt.user_id = xmalloc_clear (sizeof *packet->pkt.user_id + pktlen);
+  packet->pkt.user_id->len = pktlen;
+  packet->pkt.user_id->ref = 1;
+
+  p = packet->pkt.user_id->name;
+  for (; pktlen; pktlen--, p++)
+    *p = iobuf_get_noeof (inp);
+  *p = 0;
+
+  if (list_mode)
+    {
+      int n = packet->pkt.user_id->len;
+      es_fprintf (listfp, ":user ID packet: \"");
+      /* fixme: Hey why don't we replace this with es_write_sanitized?? */
+      for (p = packet->pkt.user_id->name; n; p++, n--)
+       {
+         if (*p >= ' ' && *p <= 'z')
+           es_putc (*p, listfp);
+         else
+           es_fprintf (listfp, "\\x%02x", *p);
        }
-       fprintf (listfp, "\"\n");
+      es_fprintf (listfp, "\"\n");
     }
-    return 0;
+  return 0;
 }
 
 
 void
-make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
+make_attribute_uidname (PKT_user_id * uid, size_t max_namelen)
 {
-  assert ( max_namelen > 70 );
-  if(uid->numattribs<=0)
-    sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
-  else if(uid->numattribs>1)
-    sprintf(uid->name,"[%d attributes of size %lu]",
-           uid->numattribs,uid->attrib_len);
+  assert (max_namelen > 70);
+  if (uid->numattribs <= 0)
+    sprintf (uid->name, "[bad attribute packet of size %lu]",
+            uid->attrib_len);
+  else if (uid->numattribs > 1)
+    sprintf (uid->name, "[%d attributes of size %lu]",
+            uid->numattribs, uid->attrib_len);
   else
     {
       /* Only one attribute, so list it as the "user id" */
 
-      if(uid->attribs->type==ATTRIB_IMAGE)
+      if (uid->attribs->type == ATTRIB_IMAGE)
        {
          u32 len;
          byte type;
 
-         if(parse_image_header(uid->attribs,&type,&len))
-           sprintf(uid->name,"[%.20s image of size %lu]",
-                   image_type_to_string(type,1),(ulong)len);
+         if (parse_image_header (uid->attribs, &type, &len))
+           sprintf (uid->name, "[%.20s image of size %lu]",
+                    image_type_to_string (type, 1), (ulong) len);
          else
-           sprintf(uid->name,"[invalid image]");
+           sprintf (uid->name, "[invalid image]");
        }
       else
-       sprintf(uid->name,"[unknown attribute of size %lu]",
-               (ulong)uid->attribs->len);
+       sprintf (uid->name, "[unknown attribute of size %lu]",
+                (ulong) uid->attribs->len);
     }
 
-  uid->len = strlen(uid->name);
+  uid->len = strlen (uid->name);
 }
 
+
 static int
-parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
+parse_attribute (IOBUF inp, int pkttype, unsigned long pktlen,
+                PACKET * packet)
 {
-    byte *p;
-
-    (void)pkttype;
-
-    /* We better cap the size of an attribute packet to make DoS not
-       too easy.  16MB should be more then enough for one attribute
-       packet (ie. a photo).  */
-    if (pktlen > MAX_ATTR_PACKET_LENGTH) {
-        log_error ("packet(%d) too large\n", pkttype);
-        if (list_mode)
-          fprintf (listfp, ":attribute packet: [too large]\n");
-        iobuf_skip_rest (inp, pktlen, 0);
-        return G10ERR_INVALID_PACKET;
-      }
+  byte *p;
+
+  (void) pkttype;
+
+  /* We better cap the size of an attribute packet to make DoS not too
+     easy.  16MB should be more then enough for one attribute packet
+     (ie. a photo).  */
+  if (pktlen > 16*1024*1024)
+    {
+      log_error ("packet(%d) too large\n", pkttype);
+      if (list_mode)
+        es_fprintf (listfp, ":attribute packet: [too large]\n");
+      iobuf_skip_rest (inp, pktlen, 0);
+      return G10ERR_INVALID_PACKET;
+    }
 
 #define EXTRA_UID_NAME_SPACE 71
-    packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id
-                                       + EXTRA_UID_NAME_SPACE);
-    packet->pkt.user_id->ref=1;
-    packet->pkt.user_id->attrib_data = xmalloc(pktlen? pktlen:1);
-    packet->pkt.user_id->attrib_len = pktlen;
+  packet->pkt.user_id = xmalloc_clear (sizeof *packet->pkt.user_id
+                                      + EXTRA_UID_NAME_SPACE);
+  packet->pkt.user_id->ref = 1;
+  packet->pkt.user_id->attrib_data = xmalloc (pktlen? pktlen:1);
+  packet->pkt.user_id->attrib_len = pktlen;
 
-    p = packet->pkt.user_id->attrib_data;
-    for( ; pktlen; pktlen--, p++ )
-       *p = iobuf_get_noeof(inp);
+  p = packet->pkt.user_id->attrib_data;
+  for (; pktlen; pktlen--, p++)
+    *p = iobuf_get_noeof (inp);
 
-    /* Now parse out the individual attribute subpackets.  This is
-       somewhat pointless since there is only one currently defined
-       attribute type (jpeg), but it is correct by the spec. */
-    parse_attribute_subpkts(packet->pkt.user_id);
+  /* Now parse out the individual attribute subpackets.  This is
+     somewhat pointless since there is only one currently defined
+     attribute type (jpeg), but it is correct by the spec. */
+  parse_attribute_subpkts (packet->pkt.user_id);
 
-    make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
+  make_attribute_uidname (packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
 
-    if( list_mode ) {
-       fprintf (listfp, ":attribute packet: %s\n", packet->pkt.user_id->name );
+  if (list_mode)
+    {
+      es_fprintf (listfp, ":attribute packet: %s\n", packet->pkt.user_id->name);
     }
-    return 0;
+  return 0;
 }
 
 
 static int
-parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
+parse_comment (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * packet)
 {
-    byte *p;
+  byte *p;
 
-    /* Cap comment packet at a reasonable value to avoid an integer
-       overflow in the malloc below.  Comment packets are actually not
-       anymore define my OpenPGP and we even stopped to use our
-       private comment packet. */
-    if (pktlen > MAX_COMMENT_PACKET_LENGTH)
-      {
-       log_error ("packet(%d) too large\n", pkttype);
-       iobuf_skip_rest (inp, pktlen, 0);
-       return G10ERR_INVALID_PACKET;
-      }
-    packet->pkt.comment = xmalloc(sizeof *packet->pkt.comment + pktlen - 1);
-    packet->pkt.comment->len = pktlen;
-    p = packet->pkt.comment->data;
-    for( ; pktlen; pktlen--, p++ )
-       *p = iobuf_get_noeof(inp);
-
-    if( list_mode ) {
-       int n = packet->pkt.comment->len;
-       fprintf (listfp, ":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
-                                        "OpenPGP draft " : "" );
-       for(p=packet->pkt.comment->data; n; p++, n-- ) {
-           if( *p >= ' ' && *p <= 'z' )
-               putc (*p, listfp);
-           else
-               fprintf (listfp, "\\x%02x", *p );
+  /* Cap comment packet at a reasonable value to avoid an integer
+     overflow in the malloc below.  Comment packets are actually not
+     anymore define my OpenPGP and we even stopped to use our
+     private comment packet.  */
+  if (pktlen > 65536)
+    {
+      log_error ("packet(%d) too large\n", pkttype);
+      if (list_mode)
+        es_fprintf (listfp, ":%scomment packet: [too large]\n",
+                    pkttype == PKT_OLD_COMMENT ? "OpenPGP draft " : "");
+      iobuf_skip_rest (inp, pktlen, 0);
+      return G10ERR_INVALID_PACKET;
+    }
+  packet->pkt.comment = xmalloc (sizeof *packet->pkt.comment + pktlen - 1);
+  packet->pkt.comment->len = pktlen;
+  p = packet->pkt.comment->data;
+  for (; pktlen; pktlen--, p++)
+    *p = iobuf_get_noeof (inp);
+
+  if (list_mode)
+    {
+      int n = packet->pkt.comment->len;
+      es_fprintf (listfp, ":%scomment packet: \"", pkttype == PKT_OLD_COMMENT ?
+                  "OpenPGP draft " : "");
+      for (p = packet->pkt.comment->data; n; p++, n--)
+       {
+         if (*p >= ' ' && *p <= 'z')
+           es_putc (*p, listfp);
+         else
+           es_fprintf (listfp, "\\x%02x", *p);
        }
-       fprintf (listfp, "\"\n");
+      es_fprintf (listfp, "\"\n");
     }
-    return 0;
+  return 0;
 }
 
 
 static void
-parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
+parse_trust (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * pkt)
 {
   int c;
 
-  (void)pkttype;
+  (void) pkttype;
 
-  pkt->pkt.ring_trust = xmalloc( sizeof *pkt->pkt.ring_trust );
   if (pktlen)
     {
-      c = iobuf_get_noeof(inp);
+      c = iobuf_get_noeof (inp);
       pktlen--;
+      pkt->pkt.ring_trust = xmalloc (sizeof *pkt->pkt.ring_trust);
       pkt->pkt.ring_trust->trustval = c;
       pkt->pkt.ring_trust->sigcache = 0;
-      if (!c && pktlen==1)
-        {
-          c = iobuf_get_noeof (inp);
-          pktlen--;
-          /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
-          if ( !(c & 0x80) )
-            pkt->pkt.ring_trust->sigcache = c;
-        }
-      if( list_mode )
-       fprintf (listfp, ":trust packet: flag=%02x sigcache=%02x\n",
-               pkt->pkt.ring_trust->trustval,
-               pkt->pkt.ring_trust->sigcache);
+      if (!c && pktlen == 1)
+       {
+         c = iobuf_get_noeof (inp);
+         pktlen--;
+         /* We require that bit 7 of the sigcache is 0 (easier eof
+             handling).  */
+         if (!(c & 0x80))
+           pkt->pkt.ring_trust->sigcache = c;
+       }
+      if (list_mode)
+       es_fprintf (listfp, ":trust packet: flag=%02x sigcache=%02x\n",
+                    pkt->pkt.ring_trust->trustval,
+                    pkt->pkt.ring_trust->sigcache);
     }
   else
     {
-      pkt->pkt.ring_trust->trustval = 0;
-      pkt->pkt.ring_trust->sigcache = 0;
       if (list_mode)
-        fprintf (listfp, ":trust packet: empty\n");
+       es_fprintf (listfp, ":trust packet: empty\n");
     }
   iobuf_skip_rest (inp, pktlen, 0);
 }
 
 
 static int
-parse_plaintextIOBUF inp, int pkttype, unsigned long pktlen,
-                PACKET *pkt, int new_ctb, int partial )
+parse_plaintext (IOBUF inp, int pkttype, unsigned long pktlen,
+                PACKET * pkt, int new_ctb, int partial)
 {
-    int rc = 0;
-    int mode, namelen;
-    PKT_plaintext *pt;
-    byte *p;
-    int c, i;
-
-    if( !partial && pktlen < 6 ) {
-       log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
-        rc = gpg_error (GPG_ERR_INV_PACKET);
-       goto leave;
-    }
-    mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
-    namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
-    /* Note that namelen will never exceed 255 bytes. */
-    pt = pkt->pkt.plaintext = xmalloc(sizeof *pkt->pkt.plaintext + namelen -1);
-    pt->new_ctb = new_ctb;
-    pt->mode = mode;
-    pt->namelen = namelen;
-    pt->is_partial = partial;
-    if( pktlen ) {
-       for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
-           pt->name[i] = iobuf_get_noeof(inp);
-    }
-    else {
-       for( i=0; i < namelen; i++ )
-           if( (c=iobuf_get(inp)) == -1 )
-               break;
-           else
-               pt->name[i] = c;
-    }
-    pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
-    pt->len = pktlen;
-    pt->buf = inp;
-    pktlen = 0;
-
-    if( list_mode ) {
-       fprintf (listfp, ":literal data packet:\n"
-              "\tmode %c (%X), created %lu, name=\"",
-                   mode >= ' ' && mode <'z'? mode : '?', mode,
-                   (ulong)pt->timestamp );
-       for(p=pt->name,i=0; i < namelen; p++, i++ ) {
-           if( *p >= ' ' && *p <= 'z' )
-               putc (*p, listfp);
-           else
-               fprintf (listfp, "\\x%02x", *p );
-       }
-       fprintf (listfp, "\",\n\traw data: ");
-       if(partial)
-         fprintf (listfp, "unknown length\n");
+  int rc = 0;
+  int mode, namelen;
+  PKT_plaintext *pt;
+  byte *p;
+  int c, i;
+
+  if (!partial && pktlen < 6)
+    {
+      log_error ("packet(%d) too short (%lu)\n", pkttype, (ulong) pktlen);
+      if (list_mode)
+        es_fputs (":literal data packet: [too short]\n", listfp);
+      rc = gpg_error (GPG_ERR_INV_PACKET);
+      goto leave;
+    }
+  mode = iobuf_get_noeof (inp);
+  if (pktlen)
+    pktlen--;
+  namelen = iobuf_get_noeof (inp);
+  if (pktlen)
+    pktlen--;
+  /* Note that namelen will never exceed 255 bytes. */
+  pt = pkt->pkt.plaintext =
+    xmalloc (sizeof *pkt->pkt.plaintext + namelen - 1);
+  pt->new_ctb = new_ctb;
+  pt->mode = mode;
+  pt->namelen = namelen;
+  pt->is_partial = partial;
+  if (pktlen)
+    {
+      for (i = 0; pktlen > 4 && i < namelen; pktlen--, i++)
+       pt->name[i] = iobuf_get_noeof (inp);
+    }
+  else
+    {
+      for (i = 0; i < namelen; i++)
+       if ((c = iobuf_get (inp)) == -1)
+         break;
        else
-         fprintf (listfp, "%lu bytes\n", (ulong)pt->len );
+         pt->name[i] = c;
     }
+  pt->timestamp = read_32 (inp);
+  if (pktlen)
+    pktlen -= 4;
+  pt->len = pktlen;
+  pt->buf = inp;
+  pktlen = 0;
 
-  leave:
-    return rc;
+  if (list_mode)
+    {
+      es_fprintf (listfp, ":literal data packet:\n"
+                  "\tmode %c (%X), created %lu, name=\"",
+                  mode >= ' ' && mode < 'z' ? mode : '?', mode,
+                  (ulong) pt->timestamp);
+      for (p = pt->name, i = 0; i < namelen; p++, i++)
+       {
+         if (*p >= ' ' && *p <= 'z')
+           es_putc (*p, listfp);
+         else
+           es_fprintf (listfp, "\\x%02x", *p);
+       }
+      es_fprintf (listfp, "\",\n\traw data: ");
+      if (partial)
+       es_fprintf (listfp, "unknown length\n");
+      else
+       es_fprintf (listfp, "%lu bytes\n", (ulong) pt->len);
+    }
+
+ leave:
+  return rc;
 }
 
 
 static int
-parse_compressedIOBUF inp, int pkttype, unsigned long pktlen,
-                 PACKET *pkt, int new_ctb )
+parse_compressed (IOBUF inp, int pkttype, unsigned long pktlen,
+                 PACKET * pkt, int new_ctb)
 {
   PKT_compressed *zd;
 
   /* PKTLEN is here 0, but data follows (this should be the last
      object in a file or the compress algorithm should know the
      length).  */
-  (void)pkttype;
-  (void)pktlen;
+  (void) pkttype;
+  (void) pktlen;
 
   zd = pkt->pkt.compressed = xmalloc (sizeof *pkt->pkt.compressed);
-  zd->algorithm = iobuf_get_noeof(inp);
-  zd->len = 0; /* not used */
+  zd->algorithm = iobuf_get_noeof (inp);
+  zd->len = 0;                 /* not used */
   zd->new_ctb = new_ctb;
   zd->buf = inp;
   if (list_mode)
-    fprintf (listfp, ":compressed packet: algo=%d\n", zd->algorithm);
+    es_fprintf (listfp, ":compressed packet: algo=%d\n", zd->algorithm);
   return 0;
 }
 
 
 static int
-parse_encryptedIOBUF inp, int pkttype, unsigned long pktlen,
-                PACKET *pkt, int new_ctb, int partial )
+parse_encrypted (IOBUF inp, int pkttype, unsigned long pktlen,
+                PACKET * pkt, int new_ctb, int partial)
 {
-    int rc = 0;
-    PKT_encrypted *ed;
-    unsigned long orig_pktlen = pktlen;
-
-    ed = pkt->pkt.encrypted =  xmalloc(sizeof *pkt->pkt.encrypted );
-    ed->len = pktlen;
-    /* we don't know the extralen which is (cipher_blocksize+2)
-       because the algorithm ist not specified in this packet.
-       However, it is only important to know this for some sanity
-       checks on the packet length - it doesn't matter that we can't
-       do it */
-    ed->extralen = 0;
-    ed->buf = NULL;
-    ed->new_ctb = new_ctb;
-    ed->is_partial = partial;
-    ed->mdc_method = 0;
-    if( pkttype == PKT_ENCRYPTED_MDC ) {
-       /* fixme: add some pktlen sanity checks */
-       int version;
-
-       version = iobuf_get_noeof(inp);
-        if (orig_pktlen)
-            pktlen--;
-       if( version != 1 ) {
-           log_error("encrypted_mdc packet with unknown version %d\n",
-                                                               version);
-            /*skip_rest(inp, pktlen); should we really do this? */
-            rc = gpg_error (GPG_ERR_INV_PACKET);
-           goto leave;
+  int rc = 0;
+  PKT_encrypted *ed;
+  unsigned long orig_pktlen = pktlen;
+
+  ed = pkt->pkt.encrypted = xmalloc (sizeof *pkt->pkt.encrypted);
+  /* ed->len is set below.  */
+  ed->extralen = 0;  /* Unknown here; only used in build_packet.  */
+  ed->buf = NULL;
+  ed->new_ctb = new_ctb;
+  ed->is_partial = partial;
+  if (pkttype == PKT_ENCRYPTED_MDC)
+    {
+      /* Fixme: add some pktlen sanity checks.  */
+      int version;
+
+      version = iobuf_get_noeof (inp);
+      if (orig_pktlen)
+       pktlen--;
+      if (version != 1)
+       {
+         log_error ("encrypted_mdc packet with unknown version %d\n",
+                    version);
+          if (list_mode)
+            es_fputs (":encrypted data packet: [unknown version]\n", listfp);
+         /*skip_rest(inp, pktlen); should we really do this? */
+         rc = gpg_error (GPG_ERR_INV_PACKET);
+         goto leave;
        }
-       ed->mdc_method = DIGEST_ALGO_SHA1;
-    }
-    if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
-       log_error("packet(%d) too short\n", pkttype);
-        rc = G10ERR_INVALID_PACKET;
-       iobuf_skip_rest(inp, pktlen, partial);
-       goto leave;
-    }
-    if( list_mode ) {
-       if( orig_pktlen )
-           fprintf (listfp, ":encrypted data packet:\n\tlength: %lu\n",
-                     orig_pktlen);
-       else
-           fprintf (listfp, ":encrypted data packet:\n\tlength: unknown\n");
-       if( ed->mdc_method )
-           fprintf (listfp, "\tmdc_method: %d\n", ed->mdc_method );
+      ed->mdc_method = DIGEST_ALGO_SHA1;
+    }
+  else
+    ed->mdc_method = 0;
+
+  /* A basic sanity check.  We need at least an 8 byte IV plus the 2
+     detection bytes.  Note that we don't known the algorithm and thus
+     we may only check against the minimum blocksize.  */
+  if (orig_pktlen && pktlen < 10)
+    {
+      /* Actually this is blocksize+2.  */
+      log_error ("packet(%d) too short\n", pkttype);
+      if (list_mode)
+        es_fputs (":encrypted data packet: [too short]\n", listfp);
+      rc = G10ERR_INVALID_PACKET;
+      iobuf_skip_rest (inp, pktlen, partial);
+      goto leave;
     }
 
-    ed->buf = inp;
+  /* Store the remaining length of the encrypted data (i.e. without
+     the MDC version number but with the IV etc.).  This value is
+     required during decryption.  */
+  ed->len = pktlen;
 
-  leave:
-    return rc;
+  if (list_mode)
+    {
+      if (orig_pktlen)
+       es_fprintf (listfp, ":encrypted data packet:\n\tlength: %lu\n",
+                    orig_pktlen);
+      else
+       es_fprintf (listfp, ":encrypted data packet:\n\tlength: unknown\n");
+      if (ed->mdc_method)
+       es_fprintf (listfp, "\tmdc_method: %d\n", ed->mdc_method);
+    }
+
+  ed->buf = inp;
+
+ leave:
+  return rc;
 }
 
 
-/* Note, that this code is not anymore used in real life because now
-   the MDC checking is done right after the encryption in
-   decrypt_data. */
+/* Note, that this code is not anymore used in real life because the
+   MDC checking is now done right after the decryption in
+   decrypt_data.  */
 static int
 parse_mdc (IOBUF inp, int pkttype, unsigned long pktlen,
-           PACKET *pkt, int new_ctb)
+          PACKET * pkt, int new_ctb)
 {
   int rc = 0;
   PKT_mdc *mdc;
   byte *p;
 
-  (void)pkttype;
+  (void) pkttype;
 
-  mdc = pkt->pkt.mdc = xmalloc(sizeof *pkt->pkt.mdc );
+  mdc = pkt->pkt.mdc = xmalloc (sizeof *pkt->pkt.mdc);
   if (list_mode)
-    fprintf (listfp, ":mdc packet: length=%lu\n", pktlen);
+    es_fprintf (listfp, ":mdc packet: length=%lu\n", pktlen);
   if (!new_ctb || pktlen != 20)
     {
-      log_error("mdc_packet with invalid encoding\n");
+      log_error ("mdc_packet with invalid encoding\n");
       rc = gpg_error (GPG_ERR_INV_PACKET);
       goto leave;
     }
   p = mdc->hash;
   for (; pktlen; pktlen--, p++)
-    *p = iobuf_get_noeof(inp);
+    *p = iobuf_get_noeof (inp);
 
  leave:
   return rc;
@@ -2568,94 +2798,100 @@ parse_mdc (IOBUF inp, int pkttype, unsigned long pktlen,
 
 
 /*
- * This packet is internally generated by PGG (by armor.c) to
- * transfer some information to the lower layer.  To make sure that
- * this packet is really a GPG faked one and not one comming from outside,
- * we first check that tehre is a unique tag in it.
+ * This packet is internally generated by us (ibn armor.c) to transfer
+ * some information to the lower layer.  To make sure that this packet
+ * is really a GPG faked one and not one comming from outside, we
+ * first check that there is a unique tag in it.
+ *
  * The format of such a control packet is:
  *   n byte  session marker
  *   1 byte  control type CTRLPKT_xxxxx
  *   m byte  control data
  */
-
 static int
 parse_gpg_control (IOBUF inp, int pkttype, unsigned long pktlen,
-                   PACKET *packet, int partial)
+                  PACKET * packet, int partial)
 {
-    byte *p;
-    const byte *sesmark;
-    size_t sesmarklen;
-    int i;
-
-    (void)pkttype;
-
-    if ( list_mode )
-        fprintf (listfp, ":packet 63: length %lu ",  pktlen);
-
-    sesmark = get_session_marker ( &sesmarklen );
-    if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
-        goto skipit;
-    for( i=0; i < sesmarklen; i++, pktlen-- ) {
-       if ( sesmark[i] != iobuf_get_noeof(inp) )
-            goto skipit;
-    }
-    if (pktlen > 4096)
-      goto skipit; /* Definitely too large.  We skip it to avoid an
-                      overflow in the malloc. */
-    if ( list_mode )
-        puts ("- gpg control packet");
-
-    packet->pkt.gpg_control = xmalloc(sizeof *packet->pkt.gpg_control
-                                      + pktlen - 1);
-    packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
-    packet->pkt.gpg_control->datalen = pktlen;
-    p = packet->pkt.gpg_control->data;
-    for( ; pktlen; pktlen--, p++ )
-       *p = iobuf_get_noeof(inp);
-
-    return 0;
+  byte *p;
+  const byte *sesmark;
+  size_t sesmarklen;
+  int i;
+
+  (void) pkttype;
+
+  if (list_mode)
+    es_fprintf (listfp, ":packet 63: length %lu ", pktlen);
+
+  sesmark = get_session_marker (&sesmarklen);
+  if (pktlen < sesmarklen + 1) /* 1 is for the control bytes */
+    goto skipit;
+  for (i = 0; i < sesmarklen; i++, pktlen--)
+    {
+      if (sesmark[i] != iobuf_get_noeof (inp))
+       goto skipit;
+    }
+  if (pktlen > 4096)
+    goto skipit;  /* Definitely too large.  We skip it to avoid an
+                     overflow in the malloc.  */
+  if (list_mode)
+    puts ("- gpg control packet");
+
+  packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control
+                                    + pktlen - 1);
+  packet->pkt.gpg_control->control = iobuf_get_noeof (inp);
+  pktlen--;
+  packet->pkt.gpg_control->datalen = pktlen;
+  p = packet->pkt.gpg_control->data;
+  for (; pktlen; pktlen--, p++)
+    *p = iobuf_get_noeof (inp);
+
+  return 0;
 
  skipit:
-    if ( list_mode ) {
-        int c;
-
-        i=0;
-        fprintf (listfp, "- private (rest length %lu)\n",  pktlen);
-        if( partial ) {
-            while( (c=iobuf_get(inp)) != -1 )
-                dump_hex_line(c, &i);
-        }
-        else {
-            for( ; pktlen; pktlen-- )
-              {
-                dump_hex_line ((c=iobuf_get (inp)), &i);
-                if (c == -1)
-                  break;
-              }
-        }
-        putc ('\n', listfp);
+  if (list_mode)
+    {
+      int c;
+
+      i = 0;
+      es_fprintf (listfp, "- private (rest length %lu)\n", pktlen);
+      if (partial)
+       {
+         while ((c = iobuf_get (inp)) != -1)
+           dump_hex_line (c, &i);
+       }
+      else
+       {
+         for (; pktlen; pktlen--)
+           {
+             dump_hex_line ((c = iobuf_get (inp)), &i);
+             if (c == -1)
+               break;
+           }
+       }
+      es_putc ('\n', listfp);
     }
-    iobuf_skip_rest(inp,pktlen, 0);
-    return gpg_error (GPG_ERR_INV_PACKET);
+  iobuf_skip_rest (inp, pktlen, 0);
+  return gpg_error (GPG_ERR_INV_PACKET);
 }
 
-/* create a gpg control packet to be used internally as a placeholder */
+
+/* Create a GPG control packet to be used internally as a placeholder.  */
 PACKET *
-create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
+create_gpg_control (ctrlpkttype_t type, const byte * data, size_t datalen)
 {
-    PACKET *packet;
-    byte *p;
-
-    packet = xmalloc( sizeof *packet );
-    init_packet(packet);
-    packet->pkttype = PKT_GPG_CONTROL;
-    packet->pkt.gpg_control = xmalloc(sizeof *packet->pkt.gpg_control
-                                      + datalen - 1);
-    packet->pkt.gpg_control->control = type;
-    packet->pkt.gpg_control->datalen = datalen;
-    p = packet->pkt.gpg_control->data;
-    for( ; datalen; datalen--, p++ )
-       *p = *data++;
-
-    return packet;
+  PACKET *packet;
+  byte *p;
+
+  packet = xmalloc (sizeof *packet);
+  init_packet (packet);
+  packet->pkttype = PKT_GPG_CONTROL;
+  packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control
+                                    + datalen - 1);
+  packet->pkt.gpg_control->control = type;
+  packet->pkt.gpg_control->datalen = datalen;
+  p = packet->pkt.gpg_control->data;
+  for (; datalen; datalen--, p++)
+    *p = *data++;
+
+  return packet;
 }
index 54caf72..4d0fda6 100644 (file)
@@ -1,6 +1,6 @@
 /* passphrase.c -  Get a passphrase
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+ *               2005, 2006, 2007, 2009, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include "util.h"
 #include "options.h"
 #include "ttyio.h"
-#include "cipher.h"
 #include "keydb.h"
 #include "main.h"
 #include "i18n.h"
 #include "status.h"
 #include "call-agent.h"
-
+#include "../common/shareddefs.h"
 
 static char *fd_passwd = NULL;
 static char *next_pw = NULL;
@@ -101,87 +100,24 @@ encode_s2k_iterations (int iterations)
 }
 
 
-
-/* Hash a passphrase using the supplied s2k.
-   Always needs: dek->algo, s2k->mode, s2k->hash_algo.  */
-static void
-hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k)
+int
+have_static_passphrase()
 {
-  gcry_md_hd_t md;
-  int pass, i;
-  int used = 0;
-  int pwlen = strlen(pw);
-
-  assert ( s2k->hash_algo );
-  dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
-  if ( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
-    BUG();
-
-  if (gcry_md_open (&md, s2k->hash_algo, 1))
-    BUG ();
-  for (pass=0; used < dek->keylen ; pass++ )
-    {
-      if ( pass )
-        {
-          gcry_md_reset (md);
-          for (i=0; i < pass; i++ ) /* Preset the hash context.  */
-            gcry_md_putc (md, 0 );
-       }
-
-      if ( s2k->mode == 1 || s2k->mode == 3 )
-        {
-          int len2 = pwlen + 8;
-          ulong count = len2;
-
-          if ( s2k->mode == 3 )
-            {
-              count = S2K_DECODE_COUNT(s2k->count);
-              if ( count < len2 )
-                count = len2;
-           }
-
-          /* Fixme: To avoid DoS attacks by sending an sym-encrypted
-             packet with a very high S2K count, we should either cap
-             the iteration count or CPU seconds based timeout.  */
-
-          /* A little bit complicated because we need a ulong for count. */
-          while ( count > len2 )  /* maybe iterated+salted */
-            {
-              gcry_md_write ( md, s2k->salt, 8 );
-              gcry_md_write ( md, pw, pwlen );
-              count -= len2;
-           }
-          if ( count < 8 )
-            gcry_md_write ( md, s2k->salt, count );
-          else
-            {
-              gcry_md_write ( md, s2k->salt, 8 );
-              count -= 8;
-              gcry_md_write ( md, pw, count );
-           }
-       }
-      else
-        gcry_md_write ( md, pw, pwlen );
-      gcry_md_final( md );
-
-      i = gcry_md_get_algo_dlen ( s2k->hash_algo );
-      if ( i > dek->keylen - used )
-        i = dek->keylen - used;
-
-      memcpy (dek->key+used, gcry_md_read (md, s2k->hash_algo), i);
-      used += i;
-    }
-  gcry_md_close(md);
+  return (!!fd_passwd
+          && (opt.batch || opt.pinentry_mode == PINENTRY_MODE_LOOPBACK));
 }
 
-
-
-int
-have_static_passphrase()
+/* Return a static passphrase.  The returned value is only valid as
+   long as no other passphrase related function is called.  NULL may
+   be returned if no passphrase has been set; better use
+   have_static_passphrase first.  */
+const char *
+get_static_passphrase (void)
 {
-  return !!fd_passwd && opt.batch;
+  return fd_passwd;
 }
 
+
 /****************
  * Set the passphrase to be used for the next query and only for the next
  * one.
@@ -211,17 +147,6 @@ get_last_passphrase()
   return p;
 }
 
-/* As if we had used the passphrase - make it the last_pw. */
-void
-next_to_last_passphrase(void)
-{
-  if (next_pw)
-    {
-      last_pw=next_pw;
-      next_pw=NULL;
-    }
-}
-
 /* Here's an interesting question: since this passphrase was passed in
    on the command line, is there really any point in using secure
    memory for it?  I'm going with 'yes', since it doesn't hurt, and
@@ -242,7 +167,7 @@ read_passphrase_from_fd( int fd )
   int i, len;
   char *pw;
 
-  if ( !opt.batch )
+  if ( !opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK)
     { /* Not used but we have to do a dummy read, so that it won't end
          up at the begin of the message if the quite usual trick to
          prepend the passphtrase to the message is used. */
@@ -273,7 +198,7 @@ read_passphrase_from_fd( int fd )
         break;
     }
   pw[i] = 0;
-  if (!opt.batch)
+  if (!opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK)
     tty_printf("\b\b\b   \n" );
 
   xfree ( fd_passwd );
@@ -321,8 +246,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
   memset (fpr, 0, MAX_FINGERPRINT_LEN );
   if( keyid && get_pubkey( pk, keyid ) )
     {
-      if (pk)
-        free_public_key( pk );
+      free_public_key (pk);
       pk = NULL; /* oops: no key for some reason */
     }
 
@@ -334,7 +258,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
     {
       char *uid;
       size_t uidlen;
-      const char *algo_name = openpgp_pk_algo_name (pk->pubkey_algo);
+      const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo );
       const char *timestr;
       char *maink;
 
@@ -396,7 +320,8 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
 
   if (!rc)
     ;
-  else if ( gpg_err_code (rc) == GPG_ERR_CANCELED )
+  else if (gpg_err_code (rc) == GPG_ERR_CANCELED
+            || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
     {
       log_info (_("cancelled by user\n") );
       if (canceled)
@@ -415,11 +340,10 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
       if (canceled)
         *canceled = 1;
 
-      write_status_error ("get_passphrase", rc);
+      write_status_errcode ("get_passphrase", rc);
     }
 
-  if (pk)
-    free_public_key( pk );
+  free_public_key (pk);
   if (rc)
     {
       xfree (pw);
@@ -534,30 +458,9 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
 
       if ( keyid )
         {
-          u32 used_kid[2];
-          char *us;
-
-          if ( keyid[2] && keyid[3] )
-            {
-              used_kid[0] = keyid[2];
-              used_kid[1] = keyid[3];
-            }
-          else
-            {
-              used_kid[0] = keyid[0];
-              used_kid[1] = keyid[1];
-            }
-
-          us = get_long_user_id_string ( keyid );
-          write_status_text ( STATUS_USERID_HINT, us );
-          xfree(us);
-
-          snprintf (buf, sizeof buf -1, "%08lX%08lX %08lX%08lX %d 0",
-                    (ulong)keyid[0], (ulong)keyid[1],
-                    (ulong)used_kid[0], (ulong)used_kid[1],
-                    pubkey_algo );
-
-          write_status_text ( STATUS_NEED_PASSPHRASE, buf );
+          emit_status_need_passphrase (keyid,
+                                       keyid[2] && keyid[3]? keyid+2:NULL,
+                                       pubkey_algo);
        }
       else
         {
@@ -584,7 +487,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
 
       if ( !get_pubkey( pk, keyid ) )
         {
-          const char *s = openpgp_pk_algo_name (pk->pubkey_algo);
+          const char *s = openpgp_pk_algo_name ( pk->pubkey_algo );
 
           tty_printf (_("%u-bit %s key, ID %s, created %s"),
                       nbits_from_pk( pk ), s?s:"?", keystr(keyid),
@@ -605,8 +508,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
        }
 
       tty_printf("\n");
-      if (pk)
-        free_public_key( pk );
+      free_public_key (pk);
     }
 
   if ( next_pw )
@@ -654,7 +556,28 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
   if ( (!pw || !*pw) && (mode == 2 || mode == 4))
     dek->keylen = 0;
   else
-    hash_passphrase (dek, pw, s2k);
+    {
+      gpg_error_t err;
+
+      dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
+      if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key)))
+        BUG ();
+      err = gcry_kdf_derive (pw, strlen (pw),
+                             s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
+                             s2k->mode == 1? GCRY_KDF_SALTED_S2K :
+                             /* */           GCRY_KDF_SIMPLE_S2K,
+                             s2k->hash_algo, s2k->salt, 8,
+                             S2K_DECODE_COUNT(s2k->count),
+                             dek->keylen, dek->key);
+      if (err)
+        {
+          log_error ("gcry_kdf_derive failed: %s", gpg_strerror (err));
+          xfree (pw);
+          xfree (dek);
+         write_status( STATUS_MISSING_PASSPHRASE );
+          return NULL;
+        }
+    }
   if (s2k_cacheid)
     memcpy (dek->s2k_cacheid, s2k_cacheid, sizeof dek->s2k_cacheid);
   xfree(last_pw);
@@ -672,3 +595,115 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
                                 s2k, mode, tryagain_text, NULL, NULL,
                                 canceled);
 }
+
+
+/* Emit the USERID_HINT and the NEED_PASSPHRASE status messages.
+   MAINKEYID may be NULL. */
+void
+emit_status_need_passphrase (u32 *keyid, u32 *mainkeyid, int pubkey_algo)
+{
+  char buf[50];
+  char *us;
+
+  us = get_long_user_id_string (keyid);
+  write_status_text (STATUS_USERID_HINT, us);
+  xfree (us);
+
+  snprintf (buf, sizeof buf -1, "%08lX%08lX %08lX%08lX %d 0",
+            (ulong)keyid[0],
+            (ulong)keyid[1],
+            (ulong)(mainkeyid? mainkeyid[0]:keyid[0]),
+            (ulong)(mainkeyid? mainkeyid[1]:keyid[1]),
+            pubkey_algo);
+
+  write_status_text (STATUS_NEED_PASSPHRASE, buf);
+}
+
+
+/* Return an allocated utf-8 string describing the key PK.  If ESCAPED
+   is true spaces and control characters are percent or plus escaped.
+   MODE describes the use of the key description; use one of the
+   FORMAT_KEYDESC_ macros. */
+char *
+gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
+{
+  char *uid;
+  size_t uidlen;
+  const char *algo_name;
+  const char *timestr;
+  char *orig_codeset;
+  char *maink;
+  char *desc;
+  const char *prompt;
+  const char *trailer = "";
+  int is_subkey;
+
+  is_subkey = (pk->main_keyid[0] && pk->main_keyid[1]
+               && pk->keyid[0] != pk->main_keyid[0]
+               && pk->keyid[1] != pk->main_keyid[1]);
+  algo_name = openpgp_pk_algo_name (pk->pubkey_algo);
+  timestr = strtimestamp (pk->timestamp);
+  uid = get_user_id (is_subkey? pk->main_keyid:pk->keyid, &uidlen);
+
+  orig_codeset = i18n_switchto_utf8 ();
+
+  if (is_subkey)
+    maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
+  else
+    maink = NULL;
+
+  switch (mode)
+    {
+    case FORMAT_KEYDESC_NORMAL:
+      prompt = _("Please enter the passphrase to unlock the"
+                 " OpenPGP secret key:");
+      break;
+    case FORMAT_KEYDESC_IMPORT:
+      prompt = _("Please enter the passphrase to import the"
+                 " OpenPGP secret key:");
+      break;
+    case FORMAT_KEYDESC_EXPORT:
+      if (is_subkey)
+        prompt = _("Please enter the passphrase to export the"
+                   " OpenPGP secret subkey:");
+      else
+        prompt = _("Please enter the passphrase to export the"
+                   " OpenPGP secret key:");
+      break;
+    case FORMAT_KEYDESC_DELKEY:
+      if (is_subkey)
+        prompt = _("Do you really want to permanently delete the"
+                   " OpenPGP secret subkey key:");
+      else
+        prompt = _("Do you really want to permanently delete the"
+                   " OpenPGP secret key:");
+      trailer = "?";
+      break;
+    default:
+      prompt = "?";
+      break;
+    }
+
+  desc = xtryasprintf (_("%s\n"
+                         "\"%.*s\"\n"
+                         "%u-bit %s key, ID %s,\n"
+                         "created %s%s.\n%s"),
+                       prompt,
+                       (int)uidlen, uid,
+                       nbits_from_pk (pk), algo_name,
+                       keystr (pk->keyid), timestr,
+                       maink?maink:"", trailer);
+  xfree (maink);
+  xfree (uid);
+
+  i18n_switchback (orig_codeset);
+
+  if (escaped)
+    {
+      char *tmp = percent_plus_escape (desc);
+      xfree (desc);
+      desc = tmp;
+    }
+
+  return desc;
+}
index 517fa21..f6e625a 100644 (file)
 #endif
 
 #include "gpg.h"
+#include "util.h"
 #include "packet.h"
 #include "status.h"
 #include "exec.h"
 #include "keydb.h"
-#include "util.h"
 #include "i18n.h"
 #include "iobuf.h"
 #include "options.h"
@@ -113,11 +113,11 @@ generate_photo_id(PKT_public_key *pk,const char *photo_name)
         {
           iobuf_close (file);
           file = NULL;
-          errno = EPERM;
+          gpg_err_set_errno (EPERM);
         }
       if(!file)
        {
-         log_error(_("unable to open JPEG file `%s': %s\n"),
+         log_error(_("unable to open JPEG file '%s': %s\n"),
                    filename,strerror(errno));
          xfree(filename);
          filename=NULL;
@@ -146,7 +146,7 @@ generate_photo_id(PKT_public_key *pk,const char *photo_name)
       /* Is it a JPEG? */
       if(photo[0]!=0xFF || photo[1]!=0xD8)
        {
-         log_error(_("`%s' is not a JPEG file\n"),filename);
+         log_error(_("'%s' is not a JPEG file\n"),filename);
          xfree(photo);
          photo=NULL;
          xfree(filename);
@@ -163,7 +163,7 @@ generate_photo_id(PKT_public_key *pk,const char *photo_name)
          "user" may not be able to dismiss a viewer window! */
       if(opt.command_fd==-1)
        {
-         show_photos(uid->attribs,uid->numattribs,pk,NULL,uid);
+         show_photos (uid->attribs, uid->numattribs, pk, uid);
          switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay",
                                         _("Is this photo correct (y/N/q)? ")))
            {
@@ -287,11 +287,15 @@ static const char *get_default_photo_command(void)
 #endif
 
 void
-show_photos(const struct user_attribute *attrs,
-           int count,PKT_public_key *pk,PKT_secret_key *sk,
-           PKT_user_id *uid)
+show_photos(const struct user_attribute *attrs, int count,
+            PKT_public_key *pk, PKT_user_id *uid)
 {
-#ifndef DISABLE_PHOTO_VIEWER
+#ifdef DISABLE_PHOTO_VIEWER
+  (void)attrs;
+  (void)count;
+  (void)pk;
+  (void)uid;
+#else /*!DISABLE_PHOTO_VIEWER*/
   int i;
   struct expando_args args;
   u32 len;
@@ -304,10 +308,8 @@ show_photos(const struct user_attribute *attrs,
   namehash_from_uid (uid);
   args.namehash = uid->namehash;
 
-  if(pk)
-    keyid_from_pk(pk,kid);
-  else if(sk)
-    keyid_from_sk(sk,kid);
+  if (pk)
+    keyid_from_pk (pk, kid);
 
   for(i=0;i<count;i++)
     if(attrs[i].type==ATTRIB_IMAGE &&
@@ -375,5 +377,5 @@ show_photos(const struct user_attribute *attrs,
 
  fail:
   log_error(_("unable to display photo ID!\n"));
-#endif
+#endif /*!DISABLE_PHOTO_VIEWER*/
 }
index 58728ed..ec2b55f 100644 (file)
@@ -27,7 +27,7 @@
 PKT_user_id *generate_photo_id(PKT_public_key *pk,const char *filename);
 int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len);
 char *image_type_to_string(byte type,int style);
-void show_photos(const struct user_attribute *attrs,int count,
-                PKT_public_key *pk,PKT_secret_key *sk,PKT_user_id *uid);
+void show_photos (const struct user_attribute *attrs, int count,
+                  PKT_public_key *pk, PKT_user_id *uid);
 
 #endif /* !_PHOTOID_H_ */
index 1d0b2d2..1032b01 100644 (file)
 
 #define CONTROL_D ('D' - 'A' + 1)
 
+static void
+send_status_inv_recp (int reason, const char *name)
+{
+  char buf[40];
+
+  snprintf (buf, sizeof buf, "%d ", reason);
+  write_status_text_and_buffer (STATUS_INV_RECP, buf,
+                                name, strlen (name),
+                                -1);
+}
+
+
 /****************
  * Show the revocation reason as it is stored with the given signature
  */
@@ -69,12 +81,11 @@ do_show_revocation_reason( PKT_signature *sig )
        else
            text = NULL;
 
-       log_info( _("reason for revocation: ") );
-       if( text )
-           fputs( text, log_get_stream() );
+       log_info ( _("reason for revocation: "));
+       if (text)
+          log_printf ("%s\n", text);
        else
-           fprintf( log_get_stream(), "code=%02x", *p );
-       log_printf ("\n");
+          log_printf ("code=%02x\n", *p );
        n--; p++;
        pp = NULL;
        do {
@@ -87,7 +98,7 @@ do_show_revocation_reason( PKT_signature *sig )
                pp = memchr( p, '\n', n );
                nn = pp? pp - p : n;
                log_info ( _("revocation comment: ") );
-               print_string ( log_get_stream(), p, nn, 0 );
+               es_write_sanitized (log_get_stream(), p, nn, NULL, NULL);
                log_printf ("\n");
                p += nn; n -= nn;
            }
@@ -165,6 +176,7 @@ show_revocation_reason( PKT_public_key *pk, int mode )
  *       0 = nothing changed
  *       1 = new ownertrust now in new_trust
  */
+#ifndef NO_TRUST_MODELS
 static int
 do_edit_ownertrust (PKT_public_key *pk, int mode,
                     unsigned *new_trust, int defer_help )
@@ -176,7 +188,8 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
   int show=0;
   int min_num;
   int did_help=defer_help;
-  unsigned int minimum=get_min_ownertrust(pk);
+  unsigned int minimum = tdb_get_min_ownertrust (pk);
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
   switch(minimum)
     {
@@ -210,8 +223,8 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
             KBNODE keyblock, un;
 
             tty_printf(_("No trust value assigned to:\n"));
-           tty_printf("%4u%c/%s %s\n",nbits_from_pk( pk ),
-                      pubkey_letter( pk->pubkey_algo ),
+           tty_printf("%s/%s %s\n",
+                       pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
                        keystr(keyid), datestr_from_pk( pk ) );
            p=get_user_id_native(keyid);
            tty_printf(_("      \"%s\"\n"),p);
@@ -235,9 +248,9 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
 
                if((opt.verify_options&VERIFY_SHOW_PHOTOS)
                   && un->pkt->pkt.user_id->attrib_data)
-                 show_photos(un->pkt->pkt.user_id->attribs,
-                             un->pkt->pkt.user_id->numattribs,pk,NULL,
-                             un->pkt->pkt.user_id);
+                 show_photos (un->pkt->pkt.user_id->attribs,
+                               un->pkt->pkt.user_id->numattribs, pk,
+                               un->pkt->pkt.user_id);
 
                p=utf8_to_native(un->pkt->pkt.user_id->name,
                                 un->pkt->pkt.user_id->len,0);
@@ -245,7 +258,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
                tty_printf(_("  aka \"%s\"\n"),p);
              }
 
-            print_fingerprint (pk, NULL, 2);
+            print_fingerprint (NULL, pk, 2);
             tty_printf("\n");
            release_kbnode (keyblock);
           }
@@ -353,12 +366,15 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
   xfree(p);
   return show? -2: quit? -1 : changed;
 }
+#endif /*!NO_TRUST_MODELS*/
+
 
 /*
  * Display a menu to change the ownertrust of the key PK (which should
  * be a primary key).
  * For mode values see do_edit_ownertrust ()
  */
+#ifndef NO_TRUST_MODELS
 int
 edit_ownertrust (PKT_public_key *pk, int mode )
 {
@@ -384,6 +400,7 @@ edit_ownertrust (PKT_public_key *pk, int mode )
         }
     }
 }
+#endif /*!NO_TRUST_MODELS*/
 
 
 /****************
@@ -403,7 +420,7 @@ do_we_trust( PKT_public_key *pk, unsigned int trustlevel )
   if( opt.trust_model==TM_ALWAYS )
     {
       if( opt.verbose )
-       log_info("No trust check due to `--trust-model always' option\n");
+       log_info("No trust check due to '--trust-model always' option\n");
       return 1;
     }
 
@@ -453,7 +470,7 @@ do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel )
   if( !opt.batch && !rc )
     {
       print_pubkey_info(NULL,pk);
-      print_fingerprint (pk, NULL, 2);
+      print_fingerprint (NULL, pk, 2);
       tty_printf("\n");
 
       tty_printf(
@@ -512,11 +529,11 @@ check_signatures_trust( PKT_signature *sig )
       if( !opt.quiet )
         log_info(_("WARNING: Using untrusted key!\n"));
       if (opt.with_fingerprint)
-        print_fingerprint (pk, NULL, 1);
+        print_fingerprint (NULL, pk, 1);
       goto leave;
     }
 
-  if(pk->maybe_revoked && !pk->is_revoked)
+  if(pk->flags.maybe_revoked && !pk->flags.revoked)
     log_info(_("WARNING: this key might be revoked (revocation key"
               " not present)\n"));
 
@@ -525,7 +542,7 @@ check_signatures_trust( PKT_signature *sig )
   if ( (trustlevel & TRUST_FLAG_REVOKED) )
     {
       write_status( STATUS_KEYREVOKED );
-      if(pk->is_revoked==2)
+      if(pk->flags.revoked == 2)
        log_info(_("WARNING: This key has been revoked by its"
                   " designated revoker!\n"));
       else
@@ -561,14 +578,14 @@ check_signatures_trust( PKT_signature *sig )
         {
           okay = 1;
           write_status_text (STATUS_PKA_TRUST_GOOD, sig->pka_info->email);
-          log_info (_("Note: Verified signer's address is `%s'\n"),
+          log_info (_("Note: Verified signer's address is '%s'\n"),
                     sig->pka_info->email);
         }
       else
         {
           okay = 0;
           write_status_text (STATUS_PKA_TRUST_BAD, sig->pka_info->email);
-          log_info (_("Note: Signer's address `%s' "
+          log_info (_("Note: Signer's address '%s' "
                       "does not match DNS entry\n"), sig->pka_info->email);
         }
 
@@ -600,7 +617,7 @@ check_signatures_trust( PKT_signature *sig )
     {
     case TRUST_EXPIRED:
       log_info(_("Note: This key has expired!\n"));
-      print_fingerprint (pk, NULL, 1);
+      print_fingerprint (NULL, pk, 1);
       break;
 
     default:
@@ -614,7 +631,7 @@ check_signatures_trust( PKT_signature *sig )
                  " a trusted signature!\n"));
       log_info(_("         There is no indication that the "
                  "signature belongs to the owner.\n" ));
-      print_fingerprint (pk, NULL, 1);
+      print_fingerprint (NULL, pk, 1);
       break;
 
     case TRUST_NEVER:
@@ -623,7 +640,7 @@ check_signatures_trust( PKT_signature *sig )
       log_info(_("WARNING: We do NOT trust this key!\n"));
       log_info(_("         The signature is probably a FORGERY.\n"));
       if (opt.with_fingerprint)
-        print_fingerprint (pk, NULL, 1);
+        print_fingerprint (NULL, pk, 1);
       rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
       break;
 
@@ -633,19 +650,19 @@ check_signatures_trust( PKT_signature *sig )
                  " sufficiently trusted signatures!\n"));
       log_info(_("         It is not certain that the"
                  " signature belongs to the owner.\n" ));
-      print_fingerprint (pk, NULL, 1);
+      print_fingerprint (NULL, pk, 1);
       break;
 
     case TRUST_FULLY:
       write_status( STATUS_TRUST_FULLY );
       if (opt.with_fingerprint)
-        print_fingerprint (pk, NULL, 1);
+        print_fingerprint (NULL, pk, 1);
       break;
 
     case TRUST_ULTIMATE:
       write_status( STATUS_TRUST_ULTIMATE );
       if (opt.with_fingerprint)
-        print_fingerprint (pk, NULL, 1);
+        print_fingerprint (NULL, pk, 1);
       break;
     }
 
@@ -656,14 +673,15 @@ check_signatures_trust( PKT_signature *sig )
 
 
 void
-release_pk_list( PK_LIST pk_list )
+release_pk_list (pk_list_t pk_list)
 {
-    PK_LIST pk_rover;
+  PK_LIST pk_rover;
 
-    for( ; pk_list; pk_list = pk_rover ) {
-       pk_rover = pk_list->next;
-       free_public_key( pk_list->pk );
-       xfree( pk_list );
+  for ( ; pk_list; pk_list = pk_rover)
+    {
+      pk_rover = pk_list->next;
+      free_public_key ( pk_list->pk );
+      xfree ( pk_list );
     }
 }
 
@@ -680,12 +698,12 @@ key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
 
 
 /****************
- * Return a malloced string with a default reciepient if there is any
+ * Return a malloced string with a default recipient if there is any
  */
 static char *
 default_recipient(void)
 {
-    PKT_secret_key *sk;
+    PKT_public_key *pk;
     byte fpr[MAX_FINGERPRINT_LEN+1];
     size_t n;
     char *p;
@@ -695,15 +713,15 @@ default_recipient(void)
        return xstrdup( opt.def_recipient );
     if( !opt.def_recipient_self )
        return NULL;
-    sk = xmalloc_clear( sizeof *sk );
-    i = get_seckey_byname( sk, NULL, 0 );
+    pk = xmalloc_clear( sizeof *pk );
+    i = get_seckey_byname (pk, NULL);
     if( i ) {
-       free_secret_key( sk );
+       free_public_key( pk );
        return NULL;
     }
     n = MAX_FINGERPRINT_LEN;
-    fingerprint_from_sk( sk, fpr, &n );
-    free_secret_key( sk );
+    fingerprint_from_pk( pk, fpr, &n );
+    free_public_key( pk );
     p = xmalloc( 2*n+3 );
     *p++ = '0';
     *p++ = 'x';
@@ -760,6 +778,106 @@ expand_group(strlist_t input)
 }
 
 
+/* Helper for build_pk_list to find and check one key.  This helper is
+   also used directly in server mode by the RECIPIENTS command.  On
+   success the new key is added to PK_LIST_ADDR.  NAME is the user id
+   of the key. USE the requested usage and a set MARK_HIDDEN will mark
+   the key in the updated list as a hidden recipient. */
+gpg_error_t
+find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
+                    int mark_hidden, pk_list_t *pk_list_addr)
+{
+  int rc;
+  PKT_public_key *pk;
+  int trustlevel;
+
+  if (!name || !*name)
+    return gpg_error (GPG_ERR_INV_USER_ID);
+
+  pk = xtrycalloc (1, sizeof *pk);
+  if (!pk)
+    return gpg_error_from_syserror ();
+  pk->req_usage = use;
+
+  rc = get_pubkey_byname (ctrl, NULL, pk, name, NULL, NULL, 0, 0);
+  if (rc)
+    {
+      int code;
+
+      /* Key not found or other error. */
+      log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) );
+      switch (gpg_err_code (rc))
+        {
+        case GPG_ERR_NO_SECKEY:
+        case GPG_ERR_NO_PUBKEY:   code =  1; break;
+        case GPG_ERR_INV_USER_ID: code = 14; break;
+        default: code = 0; break;
+        }
+      send_status_inv_recp (code, name);
+      free_public_key (pk);
+      return rc;
+    }
+
+  rc = openpgp_pk_test_algo2 (pk->pubkey_algo, use);
+  if (rc)
+    {
+      /* Key found but not usable for us (e.g. sign-only key). */
+      send_status_inv_recp (3, name); /* Wrong key usage */
+      log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) );
+      free_public_key (pk);
+      return rc;
+    }
+
+  /* Key found and usable.  Check validity. */
+  trustlevel = get_validity (pk, pk->user_id);
+  if ( (trustlevel & TRUST_FLAG_DISABLED) )
+    {
+      /* Key has been disabled. */
+      send_status_inv_recp (13, name);
+      log_info (_("%s: skipped: public key is disabled\n"), name);
+      free_public_key (pk);
+      return G10ERR_UNU_PUBKEY;
+    }
+
+  if ( !do_we_trust_pre (pk, trustlevel) )
+    {
+      /* We don't trust this key.  */
+      send_status_inv_recp (10, name);
+      free_public_key (pk);
+      return G10ERR_UNU_PUBKEY;
+    }
+  /* Note: do_we_trust may have changed the trustlevel. */
+
+  /* Skip the actual key if the key is already present in the
+     list.  */
+  if (!key_present_in_pk_list (*pk_list_addr, pk))
+    {
+      if (!opt.quiet)
+        log_info (_("%s: skipped: public key already present\n"), name);
+      free_public_key (pk);
+    }
+  else
+    {
+      pk_list_t r;
+
+      r = xtrymalloc (sizeof *r);
+      if (!r)
+        {
+          rc = gpg_error_from_syserror ();
+          free_public_key (pk);
+          return rc;
+        }
+      r->pk = pk;
+      r->next = *pk_list_addr;
+      r->flags = mark_hidden? 1:0;
+      *pk_list_addr = r;
+    }
+
+  return 0;
+}
+
+
+
 /* This is the central function to collect the keys for recipients.
    It is thus used to prepare a public key encryption. encrypt-to
    keys, default keys and the keys for the actual recipients are all
@@ -781,7 +899,8 @@ expand_group(strlist_t input)
    not changed.
  */
 int
-build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
+build_pk_list (ctrl_t ctrl,
+               strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
 {
   PK_LIST pk_list = NULL;
   PKT_public_key *pk=NULL;
@@ -789,6 +908,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
   int any_recipients=0;
   strlist_t rov,remusr;
   char *def_rec = NULL;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
   /* Try to expand groups if any have been defined. */
   if (opt.grouplist)
@@ -808,7 +928,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
 
           /* Hidden recipients are not allowed while in PGP mode,
              issue a warning and switch into GnuPG mode. */
-          if ((rov->flags&2) && (PGP2 || PGP6 || PGP7 || PGP8))
+          if ((rov->flags&2) && (PGP6 || PGP7 || PGP8))
             {
               log_info(_("you may not use %s while in %s mode\n"),
                        "--hidden-recipient",
@@ -825,18 +945,14 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
           pk->req_usage = use;
 
           /* We explicitly allow encrypt-to to an disabled key; thus
-             we pass 1for the second last argument and 1 as the last
+             we pass 1 for the second last argument and 1 as the last
              argument to disable AKL. */
-          if ( (rc = get_pubkey_byname (NULL, pk, rov->d, NULL, NULL, 1, 1)) )
+          if ( (rc = get_pubkey_byname (ctrl,
+                                        NULL, pk, rov->d, NULL, NULL, 1, 1)) )
             {
               free_public_key ( pk ); pk = NULL;
               log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
-              write_status_text_and_buffer (STATUS_INV_RECP,
-                                            (rc == GPG_ERR_NO_PUBKEY
-                                             || rc == GPG_ERR_NO_SECKEY)? "1 ":
-                                            (rc == GPG_ERR_INV_USER_ID)? "14 ":
-                                            "0 ",
-                                            rov->d, strlen (rov->d), -1);
+              send_status_inv_recp (0, rov->d);
               goto fail;
             }
           else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
@@ -862,7 +978,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
                   /* Hidden encrypt-to recipients are not allowed while
                      in PGP mode, issue a warning and switch into
                      GnuPG mode. */
-                  if ((r->flags&1) && (PGP2 || PGP6 || PGP7 || PGP8))
+                  if ((r->flags&1) && (PGP6 || PGP7 || PGP8))
                     {
                       log_info(_("you may not use %s while in %s mode\n"),
                                "--hidden-encrypt-to",
@@ -874,12 +990,10 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
             }
           else
             {
-              /* The public key is not usable for encryption or not
-                 available. */
+              /* The public key is not usable for encryption. */
               free_public_key( pk ); pk = NULL;
               log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
-              write_status_text_and_buffer (STATUS_INV_RECP, "3 ",
-                                            rov->d, strlen (rov->d), -1);
+              send_status_inv_recp (3, rov->d); /* Wrong key usage */
               goto fail;
             }
         }
@@ -928,11 +1042,11 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
                   u32 keyid[2];
 
                   keyid_from_pk(iter->pk,keyid);
-                  tty_printf("%4u%c/%s %s \"",
-                             nbits_from_pk(iter->pk),
-                             pubkey_letter(iter->pk->pubkey_algo),
-                             keystr(keyid),
-                             datestr_from_pk(iter->pk));
+                  tty_printf ("%s/%s %s \"",
+                              pubkey_string (iter->pk,
+                                             pkstrbuf, sizeof pkstrbuf),
+                              keystr(keyid),
+                              datestr_from_pk (iter->pk));
 
                   if (iter->pk->user_id)
                     tty_print_utf8_string(iter->pk->user_id->name,
@@ -967,11 +1081,10 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
             continue;
 
           /* Get and check key for the current name. */
-          if (pk)
-            free_public_key (pk);
+          free_public_key (pk);
           pk = xmalloc_clear( sizeof *pk );
           pk->req_usage = use;
-          rc = get_pubkey_byname (NULL, pk, answer, NULL, NULL, 0, 0 );
+          rc = get_pubkey_byname (ctrl, NULL, pk, answer, NULL, NULL, 0, 0 );
           if (rc)
             tty_printf(_("No such user ID.\n"));
           else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
@@ -981,7 +1094,8 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
                   /* No validation for a default recipient. */
                   if (!key_present_in_pk_list(pk_list, pk))
                     {
-                      free_public_key (pk); pk = NULL;
+                      free_public_key (pk);
+                      pk = NULL;
                       log_info (_("skipped: public key "
                                   "already set as default recipient\n") );
                     }
@@ -1011,7 +1125,8 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
                        * present in the list */
                       if (!key_present_in_pk_list(pk_list, pk))
                         {
-                          free_public_key(pk); pk = NULL;
+                          free_public_key (pk);
+                          pk = NULL;
                           log_info(_("skipped: public key already set\n") );
                         }
                       else
@@ -1045,7 +1160,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
 
       /* The default recipient is allowed to be disabled; thus pass 1
          as second last argument.  We also don't want an AKL. */
-      rc = get_pubkey_byname (NULL, pk, def_rec, NULL, NULL, 1, 1);
+      rc = get_pubkey_byname (ctrl, NULL, pk, def_rec, NULL, NULL, 1, 1);
       if (rc)
         log_error(_("unknown default recipient \"%s\"\n"), def_rec );
       else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) )
@@ -1083,90 +1198,11 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
           if ( (remusr->flags & 1) )
             continue; /* encrypt-to keys are already handled. */
 
-          pk = xmalloc_clear( sizeof *pk );
-          pk->req_usage = use;
-          if ((rc = get_pubkey_byname (NULL, pk, remusr->d, NULL, NULL, 0, 0)))
-            {
-              /* Key not found or other error. */
-              free_public_key( pk ); pk = NULL;
-              log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
-              write_status_text_and_buffer (STATUS_INV_RECP,
-                                            (rc == G10ERR_NO_PUBKEY
-                                             || rc == G10ERR_NO_SECKEY)? "1 ":
-                                            (rc == G10ERR_INV_USER_ID)? "14 ":
-                                            "0 ",
-                                            remusr->d, strlen (remusr->d),
-                                            -1);
-              goto fail;
-            }
-          else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use )) )
-            {
-              /* Key found and usable.  Check validity. */
-              int trustlevel;
-
-              trustlevel = get_validity (pk, pk->user_id);
-              if ( (trustlevel & TRUST_FLAG_DISABLED) )
-                {
-                  /*Key has been disabled. */
-                  free_public_key(pk); pk = NULL;
-                  log_info(_("%s: skipped: public key is disabled\n"),
-                           remusr->d);
-                  write_status_text_and_buffer (STATUS_INV_RECP, "13 ",
-                                                remusr->d,
-                                                strlen (remusr->d),
-                                                -1);
-                  rc=G10ERR_UNU_PUBKEY;
-                  goto fail;
-                }
-              else if ( do_we_trust_pre( pk, trustlevel ) )
-                {
-                  /* Note: do_we_trust may have changed the trustlevel */
-
-                  /* We have at least one valid recipient. It doesn't
-                   * matters if this recipient is already present. */
-                  any_recipients = 1;
-
-                  /* Skip the actual key if the key is already present
-                   * in the list */
-                  if (!key_present_in_pk_list(pk_list, pk))
-                    {
-                      free_public_key(pk); pk = NULL;
-                      if (!opt.quiet)
-                        log_info(_("%s: skipped: public key already present\n"),
-                                 remusr->d);
-                    }
-                  else
-                    {
-                      PK_LIST r;
-                      r = xmalloc( sizeof *r );
-                      r->pk = pk; pk = NULL;
-                      r->next = pk_list;
-                      r->flags = (remusr->flags&2)?1:0;
-                      pk_list = r;
-                    }
-                }
-              else
-                { /* We don't trust this key. */
-                  free_public_key( pk ); pk = NULL;
-                  write_status_text_and_buffer (STATUS_INV_RECP, "10 ",
-                                                remusr->d,
-                                                strlen (remusr->d),
-                                                -1);
-                  rc=G10ERR_UNU_PUBKEY;
-                  goto fail;
-                }
-            }
-          else
-            {
-              /* Key found but not usable for us (e.g. sign-only key). */
-              free_public_key( pk ); pk = NULL;
-              write_status_text_and_buffer (STATUS_INV_RECP, "3 ",
-                                            remusr->d,
-                                            strlen (remusr->d),
-                                            -1);
-              log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
-              goto fail;
-            }
+          rc = find_and_check_key (ctrl, remusr->d, use, !!(remusr->flags&2),
+                                   &pk_list);
+          if (rc)
+            goto fail;
+          any_recipients = 1;
         }
     }
 
@@ -1308,10 +1344,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype,
             dropped from 4880 but is still relevant to GPG's 1991
             support.  All this doesn't mean IDEA is actually
             available, of course. */
-         if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4)
-           implicit=CIPHER_ALGO_IDEA;
-         else
-           implicit=CIPHER_ALGO_3DES;
+          implicit=CIPHER_ALGO_3DES;
 
          break;
 
@@ -1323,12 +1356,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype,
             mode, and that's the only time PREFTYPE_HASH is used
             anyway. -dms */
 
-         /* MD5 is there for v3 keys with v3 selfsigs when --pgp2 is
-            on. */
-         if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4)
-           implicit=DIGEST_ALGO_MD5;
-         else
-           implicit=DIGEST_ALGO_SHA1;
+          implicit=DIGEST_ALGO_SHA1;
 
          break;
 
@@ -1487,7 +1515,7 @@ select_mdc_from_pklist (PK_LIST pk_list)
       if (pkr->pk->user_id) /* selected by user ID */
         mdc = pkr->pk->user_id->flags.mdc;
       else
-        mdc = pkr->pk->mdc_feature;
+        mdc = pkr->pk->flags.mdc;
       if (!mdc)
         return 0;  /* At least one recipient does not support it. */
     }
@@ -1508,7 +1536,7 @@ warn_missing_mdc_from_pklist (PK_LIST pk_list)
       if (pkr->pk->user_id) /* selected by user ID */
         mdc = pkr->pk->user_id->flags.mdc;
       else
-        mdc = pkr->pk->mdc_feature;
+        mdc = pkr->pk->flags.mdc;
       if (!mdc)
         log_info (_("Note: key %s has no %s feature\n"),
                   keystr_from_pk (pkr->pk), "MDC");
index 5c47511..684ce8a 100644 (file)
@@ -1,5 +1,6 @@
 /* pkglue.c - public key operations glue code
- *     Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2000, 2003, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
 #include "gpg.h"
 #include "util.h"
 #include "pkglue.h"
+#include "main.h"
+#include "options.h"
 
-
-static gcry_mpi_t
-mpi_from_sexp (gcry_sexp_t sexp, const char * item)
+/* FIXME: Better chnage the fucntion name because mpi_ is used by
+   gcrypt macros.  */
+gcry_mpi_t
+get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt)
 {
   gcry_sexp_t list;
   gcry_mpi_t data;
 
   list = gcry_sexp_find_token (sexp, item, 0);
   assert (list);
-  data = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
+  data = gcry_sexp_nth_mpi (list, 1, mpifmt);
   assert (data);
   gcry_sexp_release (list);
   return data;
 }
 
 
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey)
-{
-  gcry_sexp_t s_sig, s_hash, s_skey;
-  int rc;
-
-  /* make a sexp from skey */
-  if (algo == GCRY_PK_DSA)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
-                           skey[0], skey[1], skey[2], skey[3], skey[4]);
-    }
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
-                           skey[0], skey[1], skey[2], skey[3], skey[4],
-                           skey[5]);
-    }
-  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
-                           skey[0], skey[1], skey[2], skey[3]);
-    }
-  else
-    return GPG_ERR_PUBKEY_ALGO;
-
-  if (rc)
-    BUG ();
-
-  /* put hash into a S-Exp s_hash */
-  if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
-    BUG ();
-
-  rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
-  gcry_sexp_release (s_hash);
-  gcry_sexp_release (s_skey);
-
-  if (rc)
-    ;
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
-    data[0] = mpi_from_sexp (s_sig, "s");
-  else
-    {
-      data[0] = mpi_from_sexp (s_sig, "r");
-      data[1] = mpi_from_sexp (s_sig, "s");
-    }
-
-  gcry_sexp_release (s_sig);
-  return rc;
-}
 
 /****************
  * Emulate our old PK interface here - sometime in the future we might
  * change the internal design to directly fit to libgcrypt.
  */
 int
-pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
+pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
+           gcry_mpi_t *data, gcry_mpi_t *pkey)
 {
   gcry_sexp_t s_sig, s_hash, s_pkey;
   int rc;
 
-  /* make a sexp from pkey */
-  if (algo == GCRY_PK_DSA)
+  /* Make a sexp from pkey.  */
+  if (pkalgo == PUBKEY_ALGO_DSA)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
                            pkey[0], pkey[1], pkey[2], pkey[3]);
     }
-  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
+  else if (pkalgo == PUBKEY_ALGO_ELGAMAL_E || pkalgo == PUBKEY_ALGO_ELGAMAL)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(elg(p%m)(g%m)(y%m)))",
                            pkey[0], pkey[1], pkey[2]);
     }
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
+  else if (pkalgo == PUBKEY_ALGO_RSA || pkalgo == PUBKEY_ALGO_RSA_S)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
     }
+  else if (pkalgo == PUBKEY_ALGO_ECDSA)
+    {
+      char *curve = openpgp_oid_to_str (pkey[0]);
+      if (!curve)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = gcry_sexp_build (&s_pkey, NULL,
+                                "(public-key(ecdsa(curve %s)(q%m)))",
+                                curve, pkey[1]);
+          xfree (curve);
+        }
+    }
+  else if (pkalgo == PUBKEY_ALGO_EDDSA)
+    {
+      char *curve = openpgp_oid_to_str (pkey[0]);
+      if (!curve)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = gcry_sexp_build (&s_pkey, NULL,
+                                "(public-key(ecc(curve %s)"
+                                "(flags eddsa)(q%m)))",
+                                curve, pkey[1]);
+          xfree (curve);
+        }
+    }
   else
     return GPG_ERR_PUBKEY_ALGO;
 
   if (rc)
     BUG ();  /* gcry_sexp_build should never fail.  */
 
-  /* put hash into a S-Exp s_hash */
-  if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
-    BUG (); /* gcry_sexp_build should never fail.  */
+  /* Put hash into a S-Exp s_hash. */
+  if (pkalgo == PUBKEY_ALGO_EDDSA)
+    {
+      if (gcry_sexp_build (&s_hash, NULL,
+                           "(data(flags eddsa)(hash-algo sha512)(value %m))",
+                           hash))
+        BUG (); /* gcry_sexp_build should never fail.  */
+    }
+  else
+    {
+      if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
+        BUG (); /* gcry_sexp_build should never fail.  */
+    }
 
   /* Put data into a S-Exp s_sig. */
   s_sig = NULL;
-  if (algo == GCRY_PK_DSA)
+  if (pkalgo == PUBKEY_ALGO_DSA)
     {
       if (!data[0] || !data[1])
         rc = gpg_error (GPG_ERR_BAD_MPI);
@@ -150,7 +135,23 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
         rc = gcry_sexp_build (&s_sig, NULL,
                               "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
     }
-  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
+  else if (pkalgo == PUBKEY_ALGO_ECDSA)
+    {
+      if (!data[0] || !data[1])
+        rc = gpg_error (GPG_ERR_BAD_MPI);
+      else
+        rc = gcry_sexp_build (&s_sig, NULL,
+                              "(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]);
+    }
+  else if (pkalgo == PUBKEY_ALGO_EDDSA)
+    {
+      if (!data[0] || !data[1])
+        rc = gpg_error (GPG_ERR_BAD_MPI);
+      else
+        rc = gcry_sexp_build (&s_sig, NULL,
+                              "(sig-val(eddsa(r%M)(s%M)))", data[0], data[1]);
+    }
+  else if (pkalgo == PUBKEY_ALGO_ELGAMAL || pkalgo == PUBKEY_ALGO_ELGAMAL_E)
     {
       if (!data[0] || !data[1])
         rc = gpg_error (GPG_ERR_BAD_MPI);
@@ -158,7 +159,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
         rc = gcry_sexp_build (&s_sig, NULL,
                               "(sig-val(elg(r%m)(s%m)))", data[0], data[1]);
     }
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
+  else if (pkalgo == PUBKEY_ALGO_RSA || pkalgo == PUBKEY_ALGO_RSA_S)
     {
       if (!data[0])
         rc = gpg_error (GPG_ERR_BAD_MPI);
@@ -183,152 +184,177 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
 /****************
  * Emulate our old PK interface here - sometime in the future we might
  * change the internal design to directly fit to libgcrypt.
+ * PK is only required to compute the fingerprint for ECDH.
  */
 int
-pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey)
+pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+            PKT_public_key *pk, gcry_mpi_t *pkey)
 {
-  gcry_sexp_t s_ciph, s_data, s_pkey;
+  gcry_sexp_t s_ciph = NULL;
+  gcry_sexp_t s_data = NULL;
+  gcry_sexp_t s_pkey = NULL;
   int rc;
 
-  /* make a sexp from pkey */
-  if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
+  /* Make a sexp from pkey.  */
+  if (algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(elg(p%m)(g%m)(y%m)))",
                            pkey[0], pkey[1], pkey[2]);
+      /* Put DATA into a simplified S-expression.  */
+      if (!rc)
+        rc = gcry_sexp_build (&s_data, NULL, "%m", data);
     }
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E)
+  else if (algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(rsa(n%m)(e%m)))",
                            pkey[0], pkey[1]);
+      /* Put DATA into a simplified S-expression.  */
+      if (!rc)
+        rc = gcry_sexp_build (&s_data, NULL, "%m", data);
+    }
+  else if (algo == PUBKEY_ALGO_ECDH)
+    {
+      gcry_mpi_t k;
+
+      rc = pk_ecdh_generate_ephemeral_key (pkey, &k);
+      if (!rc)
+        {
+          char *curve;
+
+          curve = openpgp_oid_to_str (pkey[0]);
+          if (!curve)
+            rc = gpg_error_from_syserror ();
+          else
+            {
+              /* Now use the ephemeral secret to compute the shared point.  */
+              rc = gcry_sexp_build (&s_pkey, NULL,
+                                    "(public-key(ecdh(curve%s)(q%m)))",
+                                    curve, pkey[1]);
+              xfree (curve);
+              /* Put K into a simplified S-expression.  */
+              if (!rc)
+                rc = gcry_sexp_build (&s_data, NULL, "%m", k);
+            }
+          gcry_mpi_release (k);
+        }
     }
   else
-    return GPG_ERR_PUBKEY_ALGO;
+    rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
 
-  if (rc)
-    BUG ();
-
-  /* put the data into a simple list */
-  if (gcry_sexp_build (&s_data, NULL, "%m", data))
-    BUG ();
+  /* Pass it to libgcrypt. */
+  if (!rc)
+    rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
 
-  /* pass it to libgcrypt */
-  rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
   gcry_sexp_release (s_data);
   gcry_sexp_release (s_pkey);
 
   if (rc)
     ;
-  else
-    { /* add better error handling or make gnupg use S-Exp directly */
-      resarr[0] = mpi_from_sexp (s_ciph, "a");
-      if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E)
-        resarr[1] = mpi_from_sexp (s_ciph, "b");
-    }
-
-  gcry_sexp_release (s_ciph);
-  return rc;
-}
-
-
-
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data,
-           gcry_mpi_t * skey)
-{
-  gcry_sexp_t s_skey, s_data, s_plain;
-  int rc;
-
-  *result = NULL;
-  /* make a sexp from skey */
-  if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
-                           skey[0], skey[1], skey[2], skey[3]);
-    }
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
-                           skey[0], skey[1], skey[2], skey[3], skey[4],
-                           skey[5]);
-    }
-  else
-    return GPG_ERR_PUBKEY_ALGO;
-
-  if (rc)
-    BUG ();
-
-  /* put data into a S-Exp s_data */
-  if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
+  else if (algo == PUBKEY_ALGO_ECDH)
     {
-      if (!data[0] || !data[1])
-        rc = gpg_error (GPG_ERR_BAD_MPI);
+      gcry_mpi_t shared, public, result;
+      byte fp[MAX_FINGERPRINT_LEN];
+      size_t fpn;
+
+      /* Get the shared point and the ephemeral public key.  */
+      shared = get_mpi_from_sexp (s_ciph, "s", GCRYMPI_FMT_USG);
+      public = get_mpi_from_sexp (s_ciph, "e", GCRYMPI_FMT_USG);
+      gcry_sexp_release (s_ciph);
+      s_ciph = NULL;
+      if (DBG_CIPHER)
+        {
+          log_debug ("ECDH ephemeral key:");
+          gcry_mpi_dump (public);
+          log_printf ("\n");
+        }
+
+      result = NULL;
+      fingerprint_from_pk (pk, fp, &fpn);
+      if (fpn != 20)
+        rc = gpg_error (GPG_ERR_INV_LENGTH);
       else
-        rc = gcry_sexp_build (&s_data, NULL,
-                              "(enc-val(elg(a%m)(b%m)))", data[0], data[1]);
-    }
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E)
-    {
-      if (!data[0])
-        rc = gpg_error (GPG_ERR_BAD_MPI);
+        rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared,
+                                                fp, data, pkey, &result);
+      gcry_mpi_release (shared);
+      if (!rc)
+        {
+          resarr[0] = public;
+          resarr[1] = result;
+        }
       else
-        rc = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data[0]);
+        {
+          gcry_mpi_release (public);
+          gcry_mpi_release (result);
+        }
+    }
+  else /* Elgamal or RSA case.  */
+    { /* Fixme: Add better error handling or make gnupg use
+         S-expressions directly.  */
+      resarr[0] = get_mpi_from_sexp (s_ciph, "a", GCRYMPI_FMT_USG);
+      if (!is_RSA (algo))
+        resarr[1] = get_mpi_from_sexp (s_ciph, "b", GCRYMPI_FMT_USG);
     }
-  else
-    BUG ();
-
-  if (rc)
-    BUG ();
-
-  rc = gcry_pk_decrypt (&s_plain, s_data, s_skey);
-  gcry_sexp_release (s_skey);
-  gcry_sexp_release (s_data);
-  if (rc)
-    return rc;
-
-  *result = gcry_sexp_nth_mpi (s_plain, 0, GCRYMPI_FMT_USG);
-  gcry_sexp_release (s_plain);
-  if (!*result)
-    return -1;                 /* oops */
 
-  return 0;
+  gcry_sexp_release (s_ciph);
+  return rc;
 }
 
 
 /* Check whether SKEY is a suitable secret key. */
 int
-pk_check_secret_key (int algo, gcry_mpi_t *skey)
+pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey)
 {
   gcry_sexp_t s_skey;
   int rc;
 
-  if (algo == GCRY_PK_DSA)
+  if (pkalgo == PUBKEY_ALGO_DSA)
     {
       rc = gcry_sexp_build (&s_skey, NULL,
                            "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
                            skey[0], skey[1], skey[2], skey[3], skey[4]);
     }
-  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
+  else if (pkalgo == PUBKEY_ALGO_ELGAMAL || pkalgo == PUBKEY_ALGO_ELGAMAL_E)
     {
       rc = gcry_sexp_build (&s_skey, NULL,
                            "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
                            skey[0], skey[1], skey[2], skey[3]);
     }
-  else if (algo == GCRY_PK_RSA
-           || algo == GCRY_PK_RSA_S || algo == GCRY_PK_RSA_E)
+  else if (is_RSA (pkalgo))
     {
       rc = gcry_sexp_build (&s_skey, NULL,
                            "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
                            skey[0], skey[1], skey[2], skey[3], skey[4],
                            skey[5]);
     }
+  else if (pkalgo == PUBKEY_ALGO_ECDSA || pkalgo == PUBKEY_ALGO_ECDH)
+    {
+      char *curve = openpgp_oid_to_str (skey[0]);
+      if (!curve)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = gcry_sexp_build (&s_skey, NULL,
+                                "(private-key(ecc(curve%s)(q%m)(d%m)))",
+                                curve, skey[1], skey[2]);
+          xfree (curve);
+        }
+    }
+  else if (pkalgo == PUBKEY_ALGO_EDDSA)
+    {
+      char *curve = openpgp_oid_to_str (skey[0]);
+      if (!curve)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = gcry_sexp_build (&s_skey, NULL,
+                                "(private-key(ecc(curve %s)"
+                                "(flags eddsa)(q%m)(d%m)))",
+                                curve, skey[1], skey[2]);
+          xfree (curve);
+        }
+    }
   else
     return GPG_ERR_PUBKEY_ALGO;
 
index 89d2216..ba1097c 100644 (file)
@@ -1,5 +1,5 @@
 /* pkglue.h - public key operations definitions
- *     Copyright (C) 2003 Free Software Foundation, Inc.
+ *     Copyright (C) 2003, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #ifndef GNUPG_G10_PKGLUE_H
 #define GNUPG_G10_PKGLUE_H
 
-int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash,
-             gcry_mpi_t *skey);
-int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
+#include "packet.h"  /* For PKT_public_key.  */
+
+/*-- pkglue.c --*/
+gcry_mpi_t get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt);
+
+int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data,
                gcry_mpi_t *pkey);
-int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
-                gcry_mpi_t *pkey);
-int pk_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
-                gcry_mpi_t *skey);
-int pk_check_secret_key (int algo, gcry_mpi_t *skey);
+int pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+               PKT_public_key *pk, gcry_mpi_t *pkey);
+int pk_check_secret_key (pubkey_algo_t algo, gcry_mpi_t *skey);
+
+
+/*-- ecdh.c --*/
+gcry_mpi_t  pk_ecdh_default_params (unsigned int qbits);
+gpg_error_t pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k);
+gpg_error_t pk_ecdh_encrypt_with_shared_point
+/*         */  (int is_encrypt, gcry_mpi_t shared_mpi,
+                const byte pk_fp[MAX_FINGERPRINT_LEN],
+                gcry_mpi_t data, gcry_mpi_t *pkey,
+                gcry_mpi_t *out);
+
+int pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN],
+                     gcry_mpi_t data, gcry_mpi_t * pkey);
+int pk_ecdh_decrypt (gcry_mpi_t *result, const byte sk_fp[MAX_FINGERPRINT_LEN],
+                     gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey);
 
 
 #endif /*GNUPG_G10_PKGLUE_H*/
index d24c640..5454198 100644 (file)
@@ -1,6 +1,6 @@
 /* plaintext.c -  process plaintext packets
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006 Free Software Foundation, Inc.
+ *               2006, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -26,7 +26,7 @@
 #include <assert.h>
 #include <sys/types.h>
 #ifdef HAVE_DOSISH_SYSTEM
-#include <fcntl.h> /* for setmode() */
+# include <fcntl.h> /* for setmode() */
 #endif
 
 #include "gpg.h"
 #include "i18n.h"
 
 
-/****************
- * Handle a plaintext packet.  If MFX is not NULL, update the MDs
- * Note: we should use the filter stuff here, but we have to add some
- *      easy mimic to set a read limit, so we calculate only the
- *      bytes from the plaintext.
- */
+/* Handle a plaintext packet.  If MFX is not NULL, update the MDs
+ * Note: We should have used the filter stuff here, but we have to add
+ * some easy mimic to set a read limit, so we calculate only the bytes
+ * from the plaintext.  */
 int
-handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
-                 int nooutput, int clearsig )
+handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
+                 int nooutput, int clearsig)
 {
-    char *fname = NULL;
-    FILE *fp = NULL;
-    static off_t count=0;
-    int rc = 0;
-    int c;
-    int convert = (pt->mode == 't' || pt->mode == 'u');
+  char *fname = NULL;
+  estream_t fp = NULL;
+  static off_t count = 0;
+  int err = 0;
+  int c;
+  int convert = (pt->mode == 't' || pt->mode == 'u');
 #ifdef __riscos__
-    int filetype = 0xfff;
+  int filetype = 0xfff;
 #endif
 
-    /* Let people know what the plaintext info is. This allows the
-       receiving program to try and do something different based on
-       the format code (say, recode UTF-8 to local). */
-    if(!nooutput && is_status_enabled())
-      {
-       char status[50];
-
-        /* Better make sure that stdout has been flushed in case the
-           output will be written to it.  This is to make sure that no
-           not-yet-flushed stuff will be written after the plaintext
-           status message.  */
-        fflush (stdout);
-
-       sprintf(status,"%X %lu ",(byte)pt->mode,(ulong)pt->timestamp);
-       write_status_text_and_buffer(STATUS_PLAINTEXT,
-                                    status,pt->name,pt->namelen,0);
-
-       if(!pt->is_partial)
-         {
-           sprintf(status,"%lu",(ulong)pt->len);
-           write_status_text(STATUS_PLAINTEXT_LENGTH,status);
-         }
-      }
-
-    /* create the filename as C string */
-    if( nooutput )
-       ;
-    else if( opt.outfile ) {
-       fname = xmalloc( strlen( opt.outfile ) + 1);
-       strcpy(fname, opt.outfile );
+  /* Let people know what the plaintext info is. This allows the
+     receiving program to try and do something different based on the
+     format code (say, recode UTF-8 to local). */
+  if (!nooutput && is_status_enabled ())
+    {
+      char status[50];
+
+      /* Better make sure that stdout has been flushed in case the
+         output will be written to it.  This is to make sure that no
+         not-yet-flushed stuff will be written after the plaintext
+         status message.  */
+      es_fflush (es_stdout);
+
+      snprintf (status, sizeof status,
+                "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
+      write_status_text_and_buffer (STATUS_PLAINTEXT,
+                                   status, pt->name, pt->namelen, 0);
+
+      if (!pt->is_partial)
+       {
+         snprintf (status, sizeof status, "%lu", (ulong) pt->len);
+         write_status_text (STATUS_PLAINTEXT_LENGTH, status);
+       }
+    }
+
+  /* Create the filename as C string.  */
+  if (nooutput)
+    ;
+  else if (opt.outfp)
+    {
+      fname = xtrystrdup ("[FP]");
+      if (!fname)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
-    else if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) {
-       log_info(_("data not saved; use option \"--output\" to save it\n"));
-       nooutput = 1;
+  else if (opt.outfile)
+    {
+      fname = xtrystrdup (opt.outfile);
+      if (!fname)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
-    else if( !opt.flags.use_embedded_filename ) {
-       fname = make_outfile_name( iobuf_get_real_fname(pt->buf) );
-       if( !fname )
-           fname = ask_outfile_name( pt->name, pt->namelen );
-       if( !fname ) {
-             rc = gpg_error (GPG_ERR_GENERAL); /* Can't create file. */
-             goto leave;
+  else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8))
+    {
+      log_info (_("data not saved; use option \"--output\" to save it\n"));
+      nooutput = 1;
+    }
+  else if (!opt.flags.use_embedded_filename)
+    {
+      fname = make_outfile_name (iobuf_get_real_fname (pt->buf));
+      if (!fname)
+       fname = ask_outfile_name (pt->name, pt->namelen);
+      if (!fname)
+       {
+         err = gpg_error (GPG_ERR_GENERAL);    /* Can't create file. */
+         goto leave;
        }
     }
-    else
-      fname=utf8_to_native(pt->name,pt->namelen,0);
-
-    if( nooutput )
-       ;
-    else if ( iobuf_is_pipe_filename (fname) || !*fname)
-      {
-       /* No filename or "-" given; write to stdout. */
-       fp = stdout;
-#ifdef HAVE_DOSISH_SYSTEM
-       setmode ( fileno(fp) , O_BINARY );
-#endif
-      }
-    else {
-       while( !overwrite_filep (fname) ) {
-            char *tmp = ask_outfile_name (NULL, 0);
-            if ( !tmp || !*tmp ) {
-                xfree (tmp);
-                rc = gpg_error (GPG_ERR_GENERAL); /* G10ERR_CREATE_FILE*/
-                goto leave;
-            }
-            xfree (fname);
-            fname = tmp;
-        }
+  else
+    fname = utf8_to_native (pt->name, pt->namelen, 0);
+
+  if (nooutput)
+    ;
+  else if (opt.outfp)
+    {
+      fp = opt.outfp;
+      es_set_binary (fp);
+    }
+  else if (iobuf_is_pipe_filename (fname) || !*fname)
+    {
+      /* No filename or "-" given; write to stdout. */
+      fp = es_stdout;
+      es_set_binary (fp);
+    }
+  else
+    {
+      while (!overwrite_filep (fname))
+       {
+         char *tmp = ask_outfile_name (NULL, 0);
+         if (!tmp || !*tmp)
+           {
+             xfree (tmp);
+              /* FIXME: Below used to be G10ERR_CREATE_FILE */
+             err = gpg_error (GPG_ERR_GENERAL);
+             goto leave;
+           }
+         xfree (fname);
+         fname = tmp;
+       }
     }
 
 #ifndef __riscos__
-    if( fp || nooutput )
-       ;
-    else if (is_secured_filename (fname))
-      {
-        errno = EPERM;
-       rc = gpg_error_from_syserror ();
-       log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
-       goto leave;
-      }
-    else if( !(fp = fopen(fname,"wb")) ) {
-       rc = gpg_error_from_syserror ();
-       log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
-       goto leave;
+  if (opt.outfp && is_secured_file (es_fileno (opt.outfp)))
+    {
+      err = gpg_error (GPG_ERR_EPERM);
+      log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
+      goto leave;
+    }
+  else if (fp || nooutput)
+    ;
+  else if (is_secured_filename (fname))
+    {
+      gpg_err_set_errno (EPERM);
+      err = gpg_error_from_syserror ();
+      log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
+      goto leave;
+    }
+  else if (!(fp = es_fopen (fname, "wb")))
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
+      goto leave;
     }
 #else /* __riscos__ */
-    /* If no output filename was given, i.e. we constructed it,
-       convert all '.' in fname to '/' but not vice versa as
-       we don't create directories! */
-    if( !opt.outfile )
-        for( c=0; fname[c]; ++c )
-            if( fname[c] == '.' )
-                fname[c] = '/';
-
-    if( fp || nooutput )
-       ;
-    else {
-        fp = fopen(fname,"wb");
-        if( !fp ) {
-            log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
-            rc = G10ERR_CREATE_FILE;
-            if (errno == 106)
-                log_info("Do output file and input file have the same name?\n");
-            goto leave;
+  /* If no output filename was given, i.e. we constructed it, convert
+     all '.' in fname to '/' but not vice versa as we don't create
+     directories! */
+  if (!opt.outfile)
+    for (c = 0; fname[c]; ++c)
+      if (fname[c] == '.')
+       fname[c] = '/';
+
+  if (fp || nooutput)
+    ;
+  else
+    {
+      /* Note: riscos stuff is not expected to wrok anymore.  If we
+         want to port it again to riscos we should do most of the suff
+         in estream.  FIXME: Consider to remove all riscos special
+         cases.  */
+      fp = fopen (fname, "wb");
+      if (!fp)
+       {
+         log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
+         err = G10ERR_CREATE_FILE;
+         if (errno == 106)
+           log_info ("Do output file and input file have the same name?\n");
+         goto leave;
        }
 
-        /* If there's a ,xxx extension in the embedded filename,
-           use that, else check whether the user input (in fname)
-           has a ,xxx appended, then use that in preference */
-        if( (c = riscos_get_filetype_from_string( pt->name,
-                                                  pt->namelen )) != -1 )
-            filetype = c;
-        if( (c = riscos_get_filetype_from_string( fname,
-                                                  strlen(fname) )) != -1 )
-            filetype = c;
-        riscos_set_filetype_by_number(fname, filetype);
+      /* If there's a ,xxx extension in the embedded filename,
+         use that, else check whether the user input (in fname)
+         has a ,xxx appended, then use that in preference */
+      if ((c = riscos_get_filetype_from_string (pt->name, pt->namelen)) != -1)
+       filetype = c;
+      if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
+       filetype = c;
+      riscos_set_filetype_by_number (fname, filetype);
     }
 #endif /* __riscos__ */
 
-    if( !pt->is_partial ) {
-        /* We have an actual length (which might be zero). */
+  if (!pt->is_partial)
+    {
+      /* We have an actual length (which might be zero). */
 
-        if (clearsig) {
-            log_error ("clearsig encountered while not expected\n");
-            rc = G10ERR_UNEXPECTED;
-            goto leave;
-        }
+      if (clearsig)
+       {
+         log_error ("clearsig encountered while not expected\n");
+         err = gpg_error (GPG_ERR_UNEXPECTED);
+         goto leave;
+       }
 
-       if( convert ) { /* text mode */
-           for( ; pt->len; pt->len-- ) {
-               if( (c = iobuf_get(pt->buf)) == -1 ) {
-                    rc = gpg_error_from_syserror ();
-                   log_error ("problem reading source (%u bytes remaining)\n",
-                               (unsigned)pt->len);
-                    goto leave;
+      if (convert) /* Text mode.  */
+       {
+         for (; pt->len; pt->len--)
+           {
+             if ((c = iobuf_get (pt->buf)) == -1)
+               {
+                 err = gpg_error_from_syserror ();
+                 log_error ("problem reading source (%u bytes remaining)\n",
+                            (unsigned) pt->len);
+                 goto leave;
                }
-               if( mfx->md )
-                   gcry_md_putc (mfx->md, c );
+             if (mfx->md)
+               gcry_md_putc (mfx->md, c);
 #ifndef HAVE_DOSISH_SYSTEM
-               if( c == '\r' )  /* convert to native line ending */
-                   continue;    /* fixme: this hack might be too simple */
+             if (c == '\r')    /* convert to native line ending */
+               continue;       /* fixme: this hack might be too simple */
 #endif
-               if( fp )
-                 {
-                   if(opt.max_output && (++count)>opt.max_output)
-                     {
-                       log_error ("error writing to `%s': %s\n",
-                                   fname,"exceeded --max-output limit\n");
-                       rc = gpg_error (GPG_ERR_TOO_LARGE);
-                       goto leave;
-                     }
-                   else if( putc( c, fp ) == EOF )
-                     {
-                        if (ferror (fp))
-                          rc = gpg_error_from_syserror ();
-                        else
-                          rc = gpg_error (GPG_ERR_EOF);
-                       log_error ("error writing to `%s': %s\n",
-                                   fname, strerror(errno) );
-                       goto leave;
-                     }
-                 }
+             if (fp)
+               {
+                 if (opt.max_output && (++count) > opt.max_output)
+                   {
+                     log_error ("error writing to '%s': %s\n",
+                                fname, "exceeded --max-output limit\n");
+                     err = gpg_error (GPG_ERR_TOO_LARGE);
+                     goto leave;
+                   }
+                 else if (es_putc (c, fp) == EOF)
+                   {
+                     if (es_ferror (fp))
+                       err = gpg_error_from_syserror ();
+                     else
+                       err = gpg_error (GPG_ERR_EOF);
+                     log_error ("error writing to '%s': %s\n",
+                                fname, gpg_strerror (err));
+                     goto leave;
+                   }
+               }
            }
        }
-       else { /* binary mode */
-           byte *buffer = xmalloc( 32768 );
-           while( pt->len ) {
-               int len = pt->len > 32768 ? 32768 : pt->len;
-               len = iobuf_read( pt->buf, buffer, len );
-               if( len == -1 ) {
-                    rc = gpg_error_from_syserror ();
-                   log_error ("problem reading source (%u bytes remaining)\n",
-                               (unsigned)pt->len);
-                   xfree( buffer );
-                   goto leave;
+      else  /* Binary mode.  */
+       {
+         byte *buffer = xmalloc (32768);
+         while (pt->len)
+           {
+             int len = pt->len > 32768 ? 32768 : pt->len;
+             len = iobuf_read (pt->buf, buffer, len);
+             if (len == -1)
+               {
+                 err = gpg_error_from_syserror ();
+                 log_error ("problem reading source (%u bytes remaining)\n",
+                            (unsigned) pt->len);
+                 xfree (buffer);
+                 goto leave;
                }
-               if( mfx->md )
-                   gcry_md_write ( mfx->md, buffer, len );
-               if( fp )
-                 {
-                   if(opt.max_output && (count+=len)>opt.max_output)
-                     {
-                       log_error ("error writing to `%s': %s\n",
-                                   fname,"exceeded --max-output limit\n");
-                       rc = gpg_error (GPG_ERR_TOO_LARGE);
-                       xfree( buffer );
-                       goto leave;
-                     }
-                   else if( fwrite( buffer, 1, len, fp ) != len )
-                     {
-                        rc = gpg_error_from_syserror ();
-                       log_error ("error writing to `%s': %s\n",
-                                   fname, strerror(errno) );
-                       xfree( buffer );
-                       goto leave;
-                     }
-                 }
-               pt->len -= len;
+             if (mfx->md)
+               gcry_md_write (mfx->md, buffer, len);
+             if (fp)
+               {
+                 if (opt.max_output && (count += len) > opt.max_output)
+                   {
+                     log_error ("error writing to '%s': %s\n",
+                                fname, "exceeded --max-output limit\n");
+                     err = gpg_error (GPG_ERR_TOO_LARGE);
+                     xfree (buffer);
+                     goto leave;
+                   }
+                 else if (es_fwrite (buffer, 1, len, fp) != len)
+                   {
+                     err = gpg_error_from_syserror ();
+                     log_error ("error writing to '%s': %s\n",
+                                fname, gpg_strerror (err));
+                     xfree (buffer);
+                     goto leave;
+                   }
+               }
+             pt->len -= len;
            }
-           xfree( buffer );
+         xfree (buffer);
        }
     }
-    else if( !clearsig ) {
-       if( convert ) { /* text mode */
-           while( (c = iobuf_get(pt->buf)) != -1 ) {
-               if( mfx->md )
-                   gcry_md_putc (mfx->md, c );
+  else if (!clearsig)
+    {
+      if (convert)
+       {                       /* text mode */
+         while ((c = iobuf_get (pt->buf)) != -1)
+           {
+             if (mfx->md)
+               gcry_md_putc (mfx->md, c);
 #ifndef HAVE_DOSISH_SYSTEM
-               if( convert && c == '\r' )
-                   continue; /* fixme: this hack might be too simple */
+             if (convert && c == '\r')
+               continue;       /* fixme: this hack might be too simple */
 #endif
-               if( fp )
-                 {
-                   if(opt.max_output && (++count)>opt.max_output)
-                     {
-                       log_error("Error writing to `%s': %s\n",
-                                 fname,"exceeded --max-output limit\n");
-                       rc = gpg_error (GPG_ERR_TOO_LARGE);
-                       goto leave;
-                     }
-                   else if( putc( c, fp ) == EOF )
-                     {
-                        if ( ferror (fp ) )
-                          rc = gpg_error_from_syserror ();
-                        else
-                          rc = gpg_error (GPG_ERR_EOF);
-                       log_error("error writing to `%s': %s\n",
-                                 fname, strerror(errno) );
-                       goto leave;
-                     }
-                 }
+             if (fp)
+               {
+                 if (opt.max_output && (++count) > opt.max_output)
+                   {
+                     log_error ("Error writing to '%s': %s\n",
+                                fname, "exceeded --max-output limit\n");
+                     err = gpg_error (GPG_ERR_TOO_LARGE);
+                     goto leave;
+                   }
+                 else if (es_putc (c, fp) == EOF)
+                   {
+                     if (es_ferror (fp))
+                       err = gpg_error_from_syserror ();
+                     else
+                       err = gpg_error (GPG_ERR_EOF);
+                     log_error ("error writing to '%s': %s\n",
+                                fname, gpg_strerror (err));
+                     goto leave;
+                   }
+               }
            }
        }
-       else { /* binary mode */
-           byte *buffer = xmalloc( 32768 );
-           int eof_seen = 0;
-
-           while ( !eof_seen ) {
-               /* Why do we check for len < 32768:
-                * If we won't, we would practically read 2 EOFs but
-                * the first one has already popped the block_filter
-                * off and therefore we don't catch the boundary.
-                * So, always assume EOF if iobuf_read returns less bytes
-                * then requested */
-               int len = iobuf_read( pt->buf, buffer, 32768 );
-               if( len == -1 )
-                   break;
-               if( len < 32768 )
-                   eof_seen = 1;
-               if( mfx->md )
-                   gcry_md_write ( mfx->md, buffer, len );
-               if( fp )
-                 {
-                   if(opt.max_output && (count+=len)>opt.max_output)
-                     {
-                       log_error("error writing to `%s': %s\n",
-                                 fname,"exceeded --max-output limit\n");
-                       rc = gpg_error (GPG_ERR_TOO_LARGE);
-                       xfree( buffer );
-                       goto leave;
-                     }
-                   else if( fwrite( buffer, 1, len, fp ) != len ) {
-                     rc = (errno? gpg_error_from_syserror ()
-                            : gpg_error (GPG_ERR_INTERNAL));
-                     log_error ("error writing to `%s': %s\n",
-                               fname, strerror(errno) );
-                     xfree( buffer );
+      else
+       {                       /* binary mode */
+         byte *buffer;
+         int eof_seen = 0;
+
+          buffer = xtrymalloc (32768);
+          if (!buffer)
+            {
+              err = gpg_error_from_syserror ();
+              goto leave;
+            }
+
+         while (!eof_seen)
+           {
+             /* Why do we check for len < 32768:
+              * If we won't, we would practically read 2 EOFs but
+              * the first one has already popped the block_filter
+              * off and therefore we don't catch the boundary.
+              * So, always assume EOF if iobuf_read returns less bytes
+              * then requested */
+             int len = iobuf_read (pt->buf, buffer, 32768);
+             if (len == -1)
+               break;
+             if (len < 32768)
+               eof_seen = 1;
+             if (mfx->md)
+               gcry_md_write (mfx->md, buffer, len);
+             if (fp)
+               {
+                 if (opt.max_output && (count += len) > opt.max_output)
+                   {
+                     log_error ("error writing to '%s': %s\n",
+                                fname, "exceeded --max-output limit\n");
+                     err = gpg_error (GPG_ERR_TOO_LARGE);
+                     xfree (buffer);
+                     goto leave;
+                   }
+                 else if (es_fwrite (buffer, 1, len, fp) != len)
+                   {
+                     err = gpg_error_from_syserror ();
+                     log_error ("error writing to '%s': %s\n",
+                                fname, gpg_strerror (err));
+                     xfree (buffer);
                      goto leave;
                    }
-                 }
+               }
            }
-           xfree( buffer );
+         xfree (buffer);
        }
-       pt->buf = NULL;
+      pt->buf = NULL;
     }
-    else {  /* clear text signature - don't hash the last cr,lf  */
-       int state = 0;
-
-       while( (c = iobuf_get(pt->buf)) != -1 ) {
-           if( fp )
-             {
-               if(opt.max_output && (++count)>opt.max_output)
-                 {
-                   log_error ("error writing to `%s': %s\n",
-                             fname,"exceeded --max-output limit\n");
-                    rc = gpg_error (GPG_ERR_TOO_LARGE);
-                   goto leave;
-                 }
-               else if( putc( c, fp ) == EOF )
-                 {
-                    rc = (errno? gpg_error_from_syserror ()
-                          : gpg_error (GPG_ERR_INTERNAL));
-                   log_error ("error writing to `%s': %s\n",
-                             fname, strerror(errno) );
-                   goto leave;
-                 }
-             }
-           if( !mfx->md )
-               continue;
-           if( state == 2 ) {
-               gcry_md_putc (mfx->md, '\r' );
-               gcry_md_putc (mfx->md, '\n' );
-               state = 0;
+  else /* Clear text signature - don't hash the last CR,LF.   */
+    {
+      int state = 0;
+
+      while ((c = iobuf_get (pt->buf)) != -1)
+       {
+         if (fp)
+           {
+             if (opt.max_output && (++count) > opt.max_output)
+               {
+                 log_error ("error writing to '%s': %s\n",
+                            fname, "exceeded --max-output limit\n");
+                 err = gpg_error (GPG_ERR_TOO_LARGE);
+                 goto leave;
+               }
+             else if (es_putc (c, fp) == EOF)
+               {
+                 err = gpg_error_from_syserror ();
+                 log_error ("error writing to '%s': %s\n",
+                            fname, gpg_strerror (err));
+                 goto leave;
+               }
            }
-           if( !state ) {
-               if( c == '\r'  )
-                   state = 1;
-               else if( c == '\n'  )
-                   state = 2;
-               else
-                   gcry_md_putc(mfx->md, c );
+         if (!mfx->md)
+           continue;
+         if (state == 2)
+           {
+             gcry_md_putc (mfx->md, '\r');
+             gcry_md_putc (mfx->md, '\n');
+             state = 0;
+           }
+         if (!state)
+           {
+             if (c == '\r')
+               state = 1;
+             else if (c == '\n')
+               state = 2;
+             else
+               gcry_md_putc (mfx->md, c);
            }
-           else if( state == 1 ) {
-               if( c == '\n'  )
-                   state = 2;
-               else {
-                   gcry_md_putc(mfx->md, '\r' );
-                   if( c == '\r'  )
-                       state = 1;
-                   else {
-                       state = 0;
-                       gcry_md_putc(mfx->md, c );
+         else if (state == 1)
+           {
+             if (c == '\n')
+               state = 2;
+             else
+               {
+                 gcry_md_putc (mfx->md, '\r');
+                 if (c == '\r')
+                   state = 1;
+                 else
+                   {
+                     state = 0;
+                     gcry_md_putc (mfx->md, c);
                    }
                }
            }
        }
-       pt->buf = NULL;
+      pt->buf = NULL;
     }
 
-    if( fp && fp != stdout && fclose(fp) ) {
-        rc = (errno? gpg_error_from_syserror ()
-              : gpg_error (GPG_ERR_INTERNAL));
-       log_error ("error closing `%s': %s\n", fname, strerror(errno) );
-       fp = NULL;
-       goto leave;
+  if (fp && fp != es_stdout && fp != opt.outfp && es_fclose (fp))
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
+      fp = NULL;
+      goto leave;
     }
-    fp = NULL;
-
-  leave:
-    /* Make sure that stdout gets flushed after the plaintext has
-       been handled.  This is for extra security as we do a
-       flush anyway before checking the signature.  */
-    if (fflush (stdout))
-      {
-        /* We need to check the return code to detect errors like disk
-           full for short plaintexts.  See bug#1207.  Checking return
-           values is a good idea in any case.  */
-        if (!rc)
-          rc = gpg_error_from_syserror ();
-        log_error ("error flushing `%s': %s\n", "[stdout]", strerror (errno) );
-      }
-
-    if( fp && fp != stdout )
-      fclose (fp);
-    xfree(fname);
-    return rc;
+  fp = NULL;
+
+ leave:
+  /* Make sure that stdout gets flushed after the plaintext has been
+     handled.  This is for extra security as we do a flush anyway
+     before checking the signature.  */
+  if (es_fflush (es_stdout))
+    {
+      /* We need to check the return code to detect errors like disk
+         full for short plaintexts.  See bug#1207.  Checking return
+         values is a good idea in any case.  */
+      if (!err)
+        err = gpg_error_from_syserror ();
+      log_error ("error flushing '%s': %s\n", "[stdout]",
+                 gpg_strerror (err));
+    }
+
+  if (fp && fp != es_stdout && fp != opt.outfp)
+    es_fclose (fp);
+  xfree (fname);
+  return err;
 }
 
+
 static void
-do_hash( gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode )
+do_hash (gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode)
 {
-    text_filter_context_t tfx;
-    int c;
+  text_filter_context_t tfx;
+  int c;
 
-    if( textmode ) {
-       memset( &tfx, 0, sizeof tfx);
-       iobuf_push_filter( fp, text_filter, &tfx );
+  if (textmode)
+    {
+      memset (&tfx, 0, sizeof tfx);
+      iobuf_push_filter (fp, text_filter, &tfx);
     }
-    if( md2 ) { /* work around a strange behaviour in pgp2 */
-       /* It seems that at least PGP5 converts a single CR to a CR,LF too */
-       int lc = -1;
-       while( (c = iobuf_get(fp)) != -1 ) {
-           if( c == '\n' && lc == '\r' )
-               gcry_md_putc (md2, c);
-           else if( c == '\n' ) {
-               gcry_md_putc (md2, '\r');
-               gcry_md_putc (md2, c);
+  if (md2)
+    {                          /* work around a strange behaviour in pgp2 */
+      /* It seems that at least PGP5 converts a single CR to a CR,LF too */
+      int lc = -1;
+      while ((c = iobuf_get (fp)) != -1)
+       {
+         if (c == '\n' && lc == '\r')
+           gcry_md_putc (md2, c);
+         else if (c == '\n')
+           {
+             gcry_md_putc (md2, '\r');
+             gcry_md_putc (md2, c);
            }
-           else if( c != '\n' && lc == '\r' ) {
-               gcry_md_putc (md2, '\n');
-               gcry_md_putc (md2, c);
+         else if (c != '\n' && lc == '\r')
+           {
+             gcry_md_putc (md2, '\n');
+             gcry_md_putc (md2, c);
            }
-           else
-               gcry_md_putc (md2, c);
+         else
+           gcry_md_putc (md2, c);
 
-           if( md )
-               gcry_md_putc (md, c );
-           lc = c;
+         if (md)
+           gcry_md_putc (md, c);
+         lc = c;
        }
     }
-    else {
-       while( (c = iobuf_get(fp)) != -1 ) {
-           if( md )
-               gcry_md_putc (md, c );
+  else
+    {
+      while ((c = iobuf_get (fp)) != -1)
+       {
+         if (md)
+           gcry_md_putc (md, c);
        }
     }
 }
@@ -465,68 +534,75 @@ do_hash( gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode )
  */
 int
 ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
-                          const char *inname, int textmode )
+                          const char *inname, int textmode)
 {
-    progress_filter_context_t *pfx;
-    char *answer = NULL;
-    IOBUF fp;
-    int rc = 0;
-
-    pfx = new_progress_context ();
-    fp = open_sigfile ( inname, pfx ); /* Open default file. */
-
-    if( !fp && !opt.batch ) {
-       int any=0;
-       tty_printf(_("Detached signature.\n"));
-       do {
-           char *name;
-
-           xfree(answer);
-           tty_enable_completion(NULL);
-           name = cpr_get("detached_signature.filename",
-                          _("Please enter name of data file: "));
-           tty_disable_completion();
-           cpr_kill_prompt();
-           answer=make_filename(name,(void *)NULL);
-           xfree(name);
-
-           if( any && !*answer ) {
-                rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE*/
-               goto leave;
+  progress_filter_context_t *pfx;
+  char *answer = NULL;
+  IOBUF fp;
+  int rc = 0;
+
+  pfx = new_progress_context ();
+  fp = open_sigfile (inname, pfx);     /* Open default file. */
+
+  if (!fp && !opt.batch)
+    {
+      int any = 0;
+      tty_printf (_("Detached signature.\n"));
+      do
+       {
+         char *name;
+
+         xfree (answer);
+         tty_enable_completion (NULL);
+         name = cpr_get ("detached_signature.filename",
+                         _("Please enter name of data file: "));
+         tty_disable_completion ();
+         cpr_kill_prompt ();
+         answer = make_filename (name, (void *) NULL);
+         xfree (name);
+
+         if (any && !*answer)
+           {
+             rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE */
+             goto leave;
+           }
+         fp = iobuf_open (answer);
+         if (fp && is_secured_file (iobuf_get_fd (fp)))
+           {
+             iobuf_close (fp);
+             fp = NULL;
+             gpg_err_set_errno (EPERM);
+           }
+         if (!fp && errno == ENOENT)
+           {
+             tty_printf ("No such file, try again or hit enter to quit.\n");
+             any++;
            }
-           fp = iobuf_open(answer);
-            if (fp && is_secured_file (iobuf_get_fd (fp)))
-              {
-                iobuf_close (fp);
-                fp = NULL;
-                errno = EPERM;
-              }
-           if( !fp && errno == ENOENT ) {
-               tty_printf("No such file, try again or hit enter to quit.\n");
-               any++;
+         else if (!fp)
+           {
+             rc = gpg_error_from_syserror ();
+             log_error (_("can't open '%s': %s\n"), answer,
+                        strerror (errno));
+             goto leave;
            }
-           else if( !fp )
-             {
-                rc = gpg_error_from_syserror ();
-               log_error(_("can't open `%s': %s\n"), answer, strerror(errno));
-               goto leave;
-             }
-       } while( !fp );
+       }
+      while (!fp);
     }
 
-    if( !fp ) {
-       if( opt.verbose )
-           log_info(_("reading stdin ...\n"));
-       fp = iobuf_open( NULL );
-       assert(fp);
+  if (!fp)
+    {
+      if (opt.verbose)
+       log_info (_("reading stdin ...\n"));
+      fp = iobuf_open (NULL);
+      assert (fp);
     }
-    do_hash( md, md2, fp, textmode );
-    iobuf_close(fp);
+  do_hash (md, md2, fp, textmode);
+  iobuf_close (fp);
 
-  leave:
-    xfree(answer);
-    release_progress_context (pfx);
-    return rc;
+leave:
+  xfree (answer);
+  release_progress_context (pfx);
+  return rc;
 }
 
 
@@ -536,93 +612,90 @@ ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
  * If FILES is NULL, hash stdin.
  */
 int
-hash_datafilesgcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files,
-               const char *sigfilename, int textmode )
+hash_datafiles (gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files,
+               const char *sigfilename, int textmode)
 {
-    progress_filter_context_t *pfx;
-    IOBUF fp;
-    strlist_t sl;
-
-    pfx = new_progress_context ();
-
-    if( !files ) {
-      /* Check whether we can open the signed material.  We avoid
-         trying to open a file if run in batch mode.  This assumed
-         data file for a sig file feature is just a convenience thing
-         for the command line and the user needs to read possible
-         warning messages. */
-      if (!opt.batch)
-        {
-          fp = open_sigfile( sigfilename, pfx );
-          if( fp )
-            {
-              do_hash( md, md2, fp, textmode );
-              iobuf_close(fp);
-              release_progress_context (pfx);
-              return 0;
-            }
-        }
+  progress_filter_context_t *pfx;
+  IOBUF fp;
+  strlist_t sl;
+
+  pfx = new_progress_context ();
+
+  if (!files)
+    {
+      /* check whether we can open the signed material */
+      fp = open_sigfile (sigfilename, pfx);
+      if (fp)
+       {
+         do_hash (md, md2, fp, textmode);
+         iobuf_close (fp);
+         release_progress_context (pfx);
+         return 0;
+       }
       log_error (_("no signed data\n"));
       release_progress_context (pfx);
       return gpg_error (GPG_ERR_NO_DATA);
     }
 
 
-    for (sl=files; sl; sl = sl->next ) {
-       fp = iobuf_open( sl->d );
-        if (fp && is_secured_file (iobuf_get_fd (fp)))
-          {
-            iobuf_close (fp);
-            fp = NULL;
-            errno = EPERM;
-          }
-       if( !fp ) {
-            int rc = gpg_error_from_syserror ();
-           log_error(_("can't open signed data `%s'\n"),
-                                               print_fname_stdin(sl->d));
-            release_progress_context (pfx);
-           return rc;
+  for (sl = files; sl; sl = sl->next)
+    {
+      fp = iobuf_open (sl->d);
+      if (fp && is_secured_file (iobuf_get_fd (fp)))
+       {
+         iobuf_close (fp);
+         fp = NULL;
+         gpg_err_set_errno (EPERM);
        }
-        handle_progress (pfx, fp, sl->d);
-       do_hash( md, md2, fp, textmode );
-       iobuf_close(fp);
+      if (!fp)
+       {
+         int rc = gpg_error_from_syserror ();
+         log_error (_("can't open signed data '%s'\n"),
+                    print_fname_stdin (sl->d));
+         release_progress_context (pfx);
+         return rc;
+       }
+      handle_progress (pfx, fp, sl->d);
+      do_hash (md, md2, fp, textmode);
+      iobuf_close (fp);
     }
 
-    release_progress_context (pfx);
-    return 0;
+  release_progress_context (pfx);
+  return 0;
 }
 
 
 /* Hash the data from file descriptor DATA_FD and append the hash to hash
    contexts MD and MD2.  */
 int
-hash_datafile_by_fd ( gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd,
-                      int textmode )
+hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd,
+                    int textmode)
 {
   progress_filter_context_t *pfx = new_progress_context ();
   iobuf_t fp;
 
-  fp = iobuf_fdopen (data_fd, "rb");
-  if (fp && is_secured_file (data_fd))
+  if (is_secured_file (data_fd))
     {
-      iobuf_close (fp);
       fp = NULL;
-      errno = EPERM;
+      gpg_err_set_errno (EPERM);
     }
-  if ( !fp )
+  else
+    fp = iobuf_fdopen_nc (data_fd, "rb");
+
+  if (!fp)
     {
       int rc = gpg_error_from_syserror ();
-      log_error ( _("can't open signed data fd=%d: %s\n"),
-                  data_fd, strerror (errno));
+      log_error (_("can't open signed data fd=%d: %s\n"),
+                data_fd, strerror (errno));
       release_progress_context (pfx);
       return rc;
     }
 
   handle_progress (pfx, fp, NULL);
 
-  do_hash ( md, md2, fp, textmode);
+  do_hash (md, md2, fp, textmode);
 
-  iobuf_close(fp);
+  iobuf_close (fp);
 
   release_progress_context (pfx);
   return 0;
@@ -635,7 +708,7 @@ hash_datafile_by_fd ( gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd,
    filenames at all, set the field empty. */
 
 PKT_plaintext *
-setup_plaintext_name(const char *filename,IOBUF iobuf)
+setup_plaintext_name (const char *filename, IOBUF iobuf)
 {
   PKT_plaintext *pt;
 
@@ -644,18 +717,18 @@ setup_plaintext_name(const char *filename,IOBUF iobuf)
     {
       char *s;
 
-      if(opt.set_filename)
-       s=make_basename(opt.set_filename,iobuf_get_real_fname(iobuf));
-      else if(filename && !opt.flags.utf8_filename)
+      if (opt.set_filename)
+       s = make_basename (opt.set_filename, iobuf_get_real_fname (iobuf));
+      else if (filename && !opt.flags.utf8_filename)
        {
-         char *tmp=native_to_utf8(filename);
-         s=make_basename(tmp,iobuf_get_real_fname(iobuf));
-         xfree(tmp);
+         char *tmp = native_to_utf8 (filename);
+         s = make_basename (tmp, iobuf_get_real_fname (iobuf));
+         xfree (tmp);
        }
       else
-       s=make_basename(filename,iobuf_get_real_fname(iobuf));
+       s = make_basename (filename, iobuf_get_real_fname (iobuf));
 
-      pt = xmalloc (sizeof *pt + strlen(s) - 1);
+      pt = xmalloc (sizeof *pt + strlen (s) - 1);
       pt->namelen = strlen (s);
       memcpy (pt->name, s, pt->namelen);
       xfree (s);
index d0aa926..ca20223 100644 (file)
@@ -115,9 +115,9 @@ progress_filter (void *opaque, int control,
          || timestamp - pfx->last_time > 0)
        {
          char buffer[50];
-         
+
          sprintf (buffer, "%.20s ? %lu %lu",
-                   pfx->what? pfx->what : "?", 
+                   pfx->what? pfx->what : "?",
                    pfx->offset,
                   pfx->total);
          write_status_text (STATUS_PROGRESS, buffer);
index c0167b1..e79199e 100644 (file)
@@ -1,6 +1,6 @@
-/* pubkey-enc.c -  public key encoded packet handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- *               2006, 2009 Free Software Foundation, Inc.
+/* pubkey-enc.c - Process a public key encoded packet.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2009,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -29,7 +29,6 @@
 #include "packet.h"
 #include "keydb.h"
 #include "trustdb.h"
-#include "cipher.h"
 #include "status.h"
 #include "options.h"
 #include "main.h"
 #include "call-agent.h"
 
 
-static int get_it( PKT_pubkey_enc *k,
-                  DEK *dek, PKT_secret_key *sk, u32 *keyid );
+static gpg_error_t get_it (PKT_pubkey_enc *k,
+                           DEK *dek, PKT_public_key *sk, u32 *keyid);
 
 
-/* check that the given algo is mentioned in one of the valid user IDs */
+/* Check that the given algo is mentioned in one of the valid user-ids. */
 static int
-is_algo_in_prefs ( KBNODE keyblock, preftype_t type, int algo )
+is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo)
 {
-    KBNODE k;
-
-    for (k=keyblock; k; k=k->next) {
-        if (k->pkt->pkttype == PKT_USER_ID) {
-            PKT_user_id *uid = k->pkt->pkt.user_id;
-            prefitem_t *prefs = uid->prefs;
-            
-            if (uid->created && prefs &&
-               !uid->is_revoked && !uid->is_expired ) {
-                for (; prefs->type; prefs++ )
-                    if (prefs->type == type && prefs->value == algo)
-                        return 1;
+  kbnode_t k;
+
+  for (k = keyblock; k; k = k->next)
+    {
+      if (k->pkt->pkttype == PKT_USER_ID)
+        {
+          PKT_user_id *uid = k->pkt->pkt.user_id;
+          prefitem_t *prefs = uid->prefs;
+
+          if (uid->created && prefs && !uid->is_revoked && !uid->is_expired)
+            {
+              for (; prefs->type; prefs++)
+                if (prefs->type == type && prefs->value == algo)
+                  return 1;
             }
         }
     }
-    return 0;
+  return 0;
 }
 
 
-/****************
- * Get the session key from a pubkey enc packet and return
- * it in DEK, which should have been allocated in secure memory.
+/*
+ * Get the session key from a pubkey enc packet and return it in DEK,
+ * which should have been allocated in secure memory by the caller.
  */
-int
-get_session_key( PKT_pubkey_enc *k, DEK *dek )
+gpg_error_t
+get_session_key (PKT_pubkey_enc * k, DEK * dek)
 {
-    PKT_secret_key *sk = NULL;
-    int rc;
-
-    rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
-    if( rc )
-       goto leave;
-
-    if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) {
-       sk = xmalloc_clear( sizeof *sk );
-       sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/
-       if( !(rc = get_seckey( sk, k->keyid )) )
-           rc = get_it( k, dek, sk, k->keyid );
+  PKT_public_key *sk = NULL;
+  int rc;
+
+  if (DBG_CLOCK)
+    log_clock ("get_session_key enter");
+
+  rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
+  if (rc)
+    goto leave;
+
+  if ((k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets)
+    {
+      sk = xmalloc_clear (sizeof *sk);
+      sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo.  */
+      if (!(rc = get_seckey (sk, k->keyid)))
+        rc = get_it (k, dek, sk, k->keyid);
     }
-    else { /* anonymous receiver: Try all available secret keys */
-       void *enum_context = NULL;
-       u32 keyid[2];
-       char *p;
-
-       for(;;) {
-           if( sk )
-               free_secret_key( sk );
-           sk = xmalloc_clear( sizeof *sk );
-           rc=enum_secret_keys( &enum_context, sk, 1, 0);
-           if( rc ) {
-               rc = G10ERR_NO_SECKEY;
-               break;
-           }
-           if( sk->pubkey_algo != k->pubkey_algo )
-               continue;
-           keyid_from_sk( sk, keyid );
-           log_info(_("anonymous recipient; trying secret key %s ...\n"),
-                     keystr(keyid));
-
-           if(!opt.try_all_secrets && !is_status_enabled())
-             {
-               p=get_last_passphrase();
-               set_next_passphrase(p);
-               xfree(p);
-             }
-
-           rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask
-                                                                     only
-                                                                     once */
-           if( !rc )
-             {
-               rc = get_it( k, dek, sk, keyid );
-               /* Successfully checked the secret key (either it was
-                  a card, had no passphrase, or had the right
-                  passphrase) but couldn't decrypt the session key,
-                  so thus that key is not the anonymous recipient.
-                  Move the next passphrase into last for the next
-                  round.  We only do this if the secret key was
-                  successfully checked as in the normal case,
-                  check_secret_key handles this for us via
-                  passphrase_to_dek */
-               if(rc)
-                 next_to_last_passphrase();
-             }
-
-           if( !rc )
-             {
-               log_info(_("okay, we are the anonymous recipient.\n") );
-               break;
-             }
-       }
-       enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */
+  else if (opt.skip_hidden_recipients)
+    rc = gpg_error (GPG_ERR_NO_SECKEY);
+  else  /* Anonymous receiver: Try all available secret keys.  */
+    {
+      void *enum_context = NULL;
+      u32 keyid[2];
+
+      for (;;)
+        {
+          free_public_key (sk);
+          sk = xmalloc_clear (sizeof *sk);
+          rc = enum_secret_keys (&enum_context, sk);
+          if (rc)
+            {
+              rc = G10ERR_NO_SECKEY;
+              break;
+            }
+          if (sk->pubkey_algo != k->pubkey_algo)
+            continue;
+          if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
+            continue;
+          keyid_from_pk (sk, keyid);
+          if (!opt.quiet)
+            log_info (_("anonymous recipient; trying secret key %s ...\n"),
+                      keystr (keyid));
+
+          rc = get_it (k, dek, sk, keyid);
+          if (!rc)
+            {
+              if (!opt.quiet)
+                log_info (_("okay, we are the anonymous recipient.\n"));
+              break;
+            }
+          else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
+            break; /* Don't try any more secret keys.  */
+        }
+      enum_secret_keys (&enum_context, NULL);  /* free context */
     }
 
-  leave:
-    if( sk )
-       free_secret_key( sk );
-    return rc;
+leave:
+  free_public_key (sk);
+  if (DBG_CLOCK)
+    log_clock ("get_session_key leave");
+  return rc;
 }
 
 
-static int
-get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
+static gpg_error_t
+get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
 {
-  int rc;
-  gcry_mpi_t plain_dek  = NULL;
+  gpg_error_t err;
   byte *frame = NULL;
   unsigned int n;
   size_t nframe;
   u16 csum, csum2;
-  
-  int card = 0;
-
-  if (sk->is_protected && sk->protect.s2k.mode == 1002)
-    { /* Note, that we only support RSA for now. */
-#ifdef ENABLE_CARD_SUPPORT
-      unsigned char *rbuf;
-      size_t rbuflen;
-      char *snbuf;
-      unsigned char *indata = NULL;
-      size_t indatalen;
-
-      snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
-
-      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
-        BUG ();
-
-      rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
-      xfree (snbuf);
-      xfree (indata);
-      if (rc)
-        goto leave;
-
-      frame = rbuf;
-      nframe = rbuflen;
-      card = 1;
-#else
-      rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
-      goto leave;
-#endif /*!ENABLE_CARD_SUPPORT*/
+  int padding;
+  gcry_sexp_t s_data;
+  char *desc;
+  char *keygrip;
+  byte fp[MAX_FINGERPRINT_LEN];
+  size_t fpn;
+
+  if (DBG_CLOCK)
+    log_clock ("decryption start");
+
+  /* Get the keygrip.  */
+  err = hexkeygrip_from_pk (sk, &keygrip);
+  if (err)
+    goto leave;
+
+  /* Convert the data to an S-expression.  */
+  if (sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
+      || sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
+    {
+      if (!enc->data[0] || !enc->data[1])
+        err = gpg_error (GPG_ERR_BAD_MPI);
+      else
+        err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))",
+                               enc->data[0], enc->data[1]);
+    }
+  else if (sk->pubkey_algo == PUBKEY_ALGO_RSA
+           || sk->pubkey_algo == PUBKEY_ALGO_RSA_E)
+    {
+      if (!enc->data[0])
+        err = gpg_error (GPG_ERR_BAD_MPI);
+      else
+        err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))",
+                               enc->data[0]);
+    }
+  else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
+    {
+      if (!enc->data[0] || !enc->data[1])
+        err = gpg_error (GPG_ERR_BAD_MPI);
+      else
+        err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
+                               enc->data[1], enc->data[0]);
     }
   else
+    err = gpg_error (GPG_ERR_BUG);
+
+  if (err)
+    goto leave;
+
+  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
     {
-      rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
-      if( rc )
-       goto leave;
-      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
-        BUG();
-      gcry_mpi_release (plain_dek); plain_dek = NULL;
+      fingerprint_from_pk (sk, fp, &fpn);
+      assert (fpn == 20);
     }
 
-    /* Now get the DEK (data encryption key) from the frame
-     *
-     * Old versions encode the DEK in in this format (msb is left):
-     *
-     *    0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
-     *
-     * Later versions encode the DEK like this:
-     *
-     *    0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
-     *
-     * (mpi_get_buffer already removed the leading zero).
-     *
-     * RND are non-zero randow bytes.
-     * A   is the cipher algorithm
-     * DEK is the encryption key (session key) with length k
-     * CSUM
-     */
-    if (DBG_CIPHER)
-      log_printhex ("DEK frame:", frame, nframe );
-    n=0;
-    if (!card)
-      {
-        if( n + 7 > nframe )
-          { rc = G10ERR_WRONG_SECKEY; goto leave; }
-        if( frame[n] == 1 && frame[nframe-1] == 2 ) {
-          log_info(_("old encoding of the DEK is not supported\n"));
-          rc = G10ERR_CIPHER_ALGO;
+  /* Decrypt. */
+  desc = gpg_format_keydesc (sk, FORMAT_KEYDESC_NORMAL, 1);
+  err = agent_pkdecrypt (NULL, keygrip,
+                         desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
+                         s_data, &frame, &nframe, &padding);
+  xfree (desc);
+  gcry_sexp_release (s_data);
+  if (err)
+    goto leave;
+
+  /* Now get the DEK (data encryption key) from the frame
+   *
+   * Old versions encode the DEK in in this format (msb is left):
+   *
+   *     0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
+   *
+   * Later versions encode the DEK like this:
+   *
+   *     0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
+   *
+   * (mpi_get_buffer already removed the leading zero).
+   *
+   * RND are non-zero randow bytes.
+   * A   is the cipher algorithm
+   * DEK is the encryption key (session key) with length k
+   * CSUM
+   */
+  if (DBG_CIPHER)
+    log_printhex ("DEK frame:", frame, nframe);
+  n = 0;
+
+  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
+    {
+      gcry_mpi_t shared_mpi;
+      gcry_mpi_t decoded;
+
+      /* At the beginning the frame are the bytes of shared point MPI.  */
+      err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL);
+      if (err)
+        {
+          err = gpg_error (GPG_ERR_WRONG_SECKEY);
           goto leave;
         }
-        if( frame[n] != 2 )  /* somethink is wrong */
-          { rc = G10ERR_WRONG_SECKEY; goto leave; }
-        for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
-          ;
-        n++; /* and the zero byte */
-      }
 
-    if( n + 4 > nframe )
-       { rc = G10ERR_WRONG_SECKEY; goto leave; }
-
-    dek->keylen = nframe - (n+1) - 2;
-    dek->algo = frame[n++];
-    if( dek->algo ==  CIPHER_ALGO_IDEA )
-       write_status(STATUS_RSA_OR_IDEA);
-    rc = openpgp_cipher_test_algo (dek->algo);
-    if( rc ) {
-       if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
-           log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
-                     dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
-           if(dek->algo==CIPHER_ALGO_IDEA)
-             idea_cipher_warn (0);
-       }
-       dek->algo = 0;
-       goto leave;
-    }
-    if ( dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo) ) {
-       rc = GPG_ERR_WRONG_SECKEY;
-       goto leave;
-    }
+      err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/,
+                             shared_mpi, sk->pkey);
+      mpi_release (shared_mpi);
+      if(err)
+        goto leave;
 
-    /* copy the key to DEK and compare the checksum */
-    csum  = frame[nframe-2] << 8;
-    csum |= frame[nframe-1];
-    memcpy( dek->key, frame+n, dek->keylen );
-    for( csum2=0, n=0; n < dek->keylen; n++ )
-       csum2 += dek->key[n];
-    if( csum != csum2 ) {
-       rc = G10ERR_WRONG_SECKEY;
-       goto leave;
-    }
-    if( DBG_CIPHER )
-        log_printhex ("DEK is:", dek->key, dek->keylen );
-    /* check that the algo is in the preferences and whether it has expired */
-    {
-       PKT_public_key *pk = NULL;
-        KBNODE pkb = get_pubkeyblock (keyid);
+      /* Reuse NFRAME, which size is sufficient to include the session key.  */
+      err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded);
+      mpi_release (decoded);
+      if (err)
+        goto leave;
+
+      /* Now the frame are the bytes decrypted but padded session key.  */
 
-       if( !pkb ) {
-            rc = -1;
-           log_error("oops: public key not found for preference check\n");
+      /* Allow double padding for the benefit of DEK size concealment.
+         Higher than this is wasteful. */
+      if (!nframe || frame[nframe-1] > 8*2 || nframe <= 8
+          || frame[nframe-1] > nframe)
+        {
+          err = gpg_error (GPG_ERR_WRONG_SECKEY);
+          goto leave;
         }
-       else if(pkb->pkt->pkt.public_key->selfsigversion > 3
-               && dek->algo != CIPHER_ALGO_3DES
-               && !opt.quiet
-               && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ))
-         log_info (_("WARNING: cipher algorithm %s not found in recipient"
-                      " preferences\n"), openpgp_cipher_algo_name (dek->algo));
-        if (!rc) {
-            KBNODE k;
-            
-            for (k=pkb; k; k = k->next) {
-                if (k->pkt->pkttype == PKT_PUBLIC_KEY 
-                    || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
-                    u32 aki[2];
-                   keyid_from_pk(k->pkt->pkt.public_key, aki);
-
-                    if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
-                        pk = k->pkt->pkt.public_key;
-                        break;
-                    }
-                }
+      nframe -= frame[nframe-1]; /* Remove padding.  */
+      assert (!n); /* (used just below) */
+    }
+  else
+    {
+      if (padding)
+        {
+          if (n + 7 > nframe)
+            {
+              err = gpg_error (GPG_ERR_WRONG_SECKEY);
+              goto leave;
             }
-            if (!pk)
-                BUG ();
-            if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
-                log_info(_("NOTE: secret key %s expired at %s\n"),
-                         keystr(keyid), asctimestamp( pk->expiredate) );
+          if (frame[n] == 1 && frame[nframe - 1] == 2)
+            {
+              log_info (_("old encoding of the DEK is not supported\n"));
+              err = gpg_error (GPG_ERR_CIPHER_ALGO);
+              goto leave;
             }
+          if (frame[n] != 2) /* Something went wrong.  */
+            {
+              err = gpg_error (GPG_ERR_WRONG_SECKEY);
+              goto leave;
+            }
+          for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes.  */
+            ;
+          n++; /* Skip the zero byte.  */
         }
+    }
 
-        if ( pk &&  pk->is_revoked ) {
-            log_info( _("NOTE: key has been revoked") );
-            log_printf ("\n");
-            show_revocation_reason( pk, 1 );
+  if (n + 4 > nframe)
+    {
+      err = gpg_error (GPG_ERR_WRONG_SECKEY);
+      goto leave;
+    }
+
+  dek->keylen = nframe - (n + 1) - 2;
+  dek->algo = frame[n++];
+  err = openpgp_cipher_test_algo (dek->algo);
+  if (err)
+    {
+      if (!opt.quiet && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
+        {
+          log_info (_("cipher algorithm %d%s is unknown or disabled\n"),
+                    dek->algo,
+                    dek->algo == CIPHER_ALGO_IDEA ? " (IDEA)" : "");
         }
+      dek->algo = 0;
+      goto leave;
+    }
+  if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
+    {
+      err = gpg_error (GPG_ERR_WRONG_SECKEY);
+      goto leave;
+    }
 
-       release_kbnode (pkb);
-       rc = 0;
+  /* Copy the key to DEK and compare the checksum.  */
+  csum = frame[nframe - 2] << 8;
+  csum |= frame[nframe - 1];
+  memcpy (dek->key, frame + n, dek->keylen);
+  for (csum2 = 0, n = 0; n < dek->keylen; n++)
+    csum2 += dek->key[n];
+  if (csum != csum2)
+    {
+      err = gpg_error (GPG_ERR_WRONG_SECKEY);
+      goto leave;
     }
+  if (DBG_CLOCK)
+    log_clock ("decryption ready");
+  if (DBG_CIPHER)
+    log_printhex ("DEK is:", dek->key, dek->keylen);
 
+  /* Check that the algo is in the preferences and whether it has expired.  */
+  {
+    PKT_public_key *pk = NULL;
+    KBNODE pkb = get_pubkeyblock (keyid);
 
-  leave:
-    gcry_mpi_release (plain_dek);
-    xfree (frame);
-    return rc;
+    if (!pkb)
+      {
+        err = -1;
+        log_error ("oops: public key not found for preference check\n");
+      }
+    else if (pkb->pkt->pkt.public_key->selfsigversion > 3
+             && dek->algo != CIPHER_ALGO_3DES
+             && !opt.quiet
+             && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo))
+      log_info (_("WARNING: cipher algorithm %s not found in recipient"
+                  " preferences\n"), openpgp_cipher_algo_name (dek->algo));
+    if (!err)
+      {
+        KBNODE k;
+
+        for (k = pkb; k; k = k->next)
+          {
+            if (k->pkt->pkttype == PKT_PUBLIC_KEY
+                || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+              {
+                u32 aki[2];
+                keyid_from_pk (k->pkt->pkt.public_key, aki);
+
+                if (aki[0] == keyid[0] && aki[1] == keyid[1])
+                  {
+                    pk = k->pkt->pkt.public_key;
+                    break;
+                  }
+              }
+          }
+        if (!pk)
+          BUG ();
+        if (pk->expiredate && pk->expiredate <= make_timestamp ())
+          {
+            log_info (_("Note: secret key %s expired at %s\n"),
+                      keystr (keyid), asctimestamp (pk->expiredate));
+          }
+      }
+
+    if (pk && pk->flags.revoked)
+      {
+        log_info (_("Note: key has been revoked"));
+        log_printf ("\n");
+        show_revocation_reason (pk, 1);
+      }
+
+    release_kbnode (pkb);
+    err = 0;
+  }
+
+ leave:
+  xfree (frame);
+  xfree (keygrip);
+  return err;
 }
 
 
-/****************
+/*
  * Get the session key from the given string.
  * String is supposed to be formatted as this:
  *  <algo-id>:<even-number-of-hex-digits>
  */
-int
-get_override_session_key( DEK *dek, const char *string )
+gpg_error_t
+get_override_session_key (DEK *dek, const char *string)
 {
-    const char *s;
-    int i;
-
-    if ( !string )
-       return G10ERR_BAD_KEY;
-    dek->algo = atoi(string);
-    if ( dek->algo < 1 )
-       return G10ERR_BAD_KEY;
-    if ( !(s = strchr ( string, ':' )) )
-       return G10ERR_BAD_KEY;
-    s++;
-    for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) {
-       int c = hextobyte ( s );
-       if (c == -1)
-           return G10ERR_BAD_KEY;
-       dek->key[i] = c;
+  const char *s;
+  int i;
+
+  if (!string)
+    return G10ERR_BAD_KEY;
+  dek->algo = atoi (string);
+  if (dek->algo < 1)
+    return G10ERR_BAD_KEY;
+  if (!(s = strchr (string, ':')))
+    return G10ERR_BAD_KEY;
+  s++;
+  for (i = 0; i < DIM (dek->key) && *s; i++, s += 2)
+    {
+      int c = hextobyte (s);
+      if (c == -1)
+        return G10ERR_BAD_KEY;
+      dek->key[i] = c;
     }
-    if ( *s )
-       return G10ERR_BAD_KEY;
-    dek->keylen = i;
-    return 0;
+  if (*s)
+    return G10ERR_BAD_KEY;
+  dek->keylen = i;
+  return 0;
 }
-
index cce6d69..6b9e709 100644 (file)
@@ -36,7 +36,7 @@
 #include "ttyio.h"
 #include "status.h"
 #include "i18n.h"
-
+#include "call-agent.h"
 
 struct revocation_reason_info {
     int code;
@@ -113,7 +113,7 @@ export_minimal_pk(IOBUF out,KBNODE keyblock,
       rc=build_packet(out,&pkt);
       if(rc)
        {
-         log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
+         log_error("build_packet failed: %s\n", g10_errstr(rc) );
          return rc;
        }
     }
@@ -200,7 +200,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
     int rc = 0;
     armor_filter_context_t *afx;
     PKT_public_key *pk = NULL;
-    PKT_secret_key *sk = NULL;
+    PKT_public_key *pk2 = NULL;
     PKT_signature *sig = NULL;
     IOBUF out = NULL;
     struct revocation_reason_info *reason = NULL;
@@ -219,9 +219,10 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
 
     afx = new_armor_context ();
 
-    kdbhd = keydb_new (0);
-    classify_user_id (uname, &desc);
-    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
+    kdbhd = keydb_new ();
+    rc = classify_user_id (uname, &desc, 1);
+    if (!rc)
+      rc = keydb_search (kdbhd, &desc, 1, NULL);
     if (rc) {
        log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
        goto leave;
@@ -238,7 +239,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
 
     /* get the key from the keyblock */
     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
-    if( !node ) 
+    if( !node )
       BUG ();
 
     pk=node->pkt->pkt.public_key;
@@ -247,7 +248,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
 
     if(locusr)
       {
-       rc=build_sk_list(locusr,&sk_list,0,PUBKEY_USAGE_CERT);
+       rc=build_sk_list(locusr, &sk_list, PUBKEY_USAGE_CERT);
        if(rc)
          goto leave;
       }
@@ -261,8 +262,8 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
       {
        SK_LIST list;
 
-       if(sk)
-         free_secret_key(sk);
+        free_public_key (pk2);
+        pk2 = NULL;
 
        if(sk_list)
          {
@@ -271,7 +272,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
                byte fpr[MAX_FINGERPRINT_LEN];
                size_t fprlen;
 
-               fingerprint_from_sk(list->sk,fpr,&fprlen);
+               fingerprint_from_pk (list->pk, fpr, &fprlen);
 
                /* Don't get involved with keys that don't have 160
                   bit fingerprints */
@@ -282,18 +283,19 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
                  break;
              }
 
-           if(list)
-             sk=copy_secret_key(NULL,list->sk);
+           if (list)
+             pk2 = copy_public_key (NULL, list->pk);
            else
              continue;
          }
        else
          {
-           sk=xmalloc_secure_clear(sizeof(*sk));
-           rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
+           pk2 = xmalloc_clear (sizeof *pk2);
+           rc = get_pubkey_byfprint (pk2,
+                                      pk->revkey[i].fpr, MAX_FINGERPRINT_LEN);
          }
 
-       /* We have the revocation key */
+       /* We have the revocation key */
        if(!rc)
          {
            PKT_signature *revkey = NULL;
@@ -304,7 +306,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
            tty_printf ("\n");
 
            tty_printf (_("To be revoked by:\n"));
-            print_seckey_info (sk);
+            print_seckey_info (pk2);
 
            if(pk->revkey[i].class&0x40)
              tty_printf(_("(This is a sensitive revocation key)\n"));
@@ -319,14 +321,14 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
            if( !reason )
              continue;
 
-           rc = check_secret_key( sk, 0 );
-           if( rc )
+           rc = -1;/*FIXME: check_secret_key (pk2, 0 );*/
+           if (rc)
              continue;
 
            if( !opt.armor )
              tty_printf(_("ASCII armored output forced.\n"));
 
-           if( (rc = open_outfile( NULL, 0, &out )) )
+           if( (rc = open_outfile (-1, NULL, 0, 1, &out )) )
              goto leave;
 
            afx->what = 1;
@@ -335,9 +337,10 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
            push_armor_filter (afx, out);
 
            /* create it */
-           rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
-                                    0, 0, 0,
-                                    revocation_reason_build_cb, reason );
+           rc = make_keysig_packet( &sig, pk, NULL, NULL, pk2, 0x20, 0,
+                                    0, 0,
+                                    revocation_reason_build_cb, reason,
+                                     NULL);
            if( rc ) {
              log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
              goto leave;
@@ -411,10 +414,8 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
       log_error(_("no revocation keys found for \"%s\"\n"),uname);
 
   leave:
-    if( pk )
-       free_public_key( pk );
-    if( sk )
-       free_secret_key( sk );
+    free_public_key (pk);
+    free_public_key (pk2);
     if( sig )
        free_seckey_enc( sig );
 
@@ -430,184 +431,253 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
 }
 
 
-/****************
- * Generate a revocation certificate for UNAME
- */
-int
-gen_revoke( const char *uname )
+/* Common core to create the revocation. FILENAME may be NULL to write
+   to stdout or the filename given by --output.  REASON describes the
+   revocation reason.  PSK is the public primary key - we expect that
+   a corresponding secret key is available.  KEYBLOCK is the entire
+   KEYBLOCK which is used in PGP mode to write a a minimal key and not
+   just the naked revocation signature; it may be NULL.  If LEADINTEXT
+   is not NULL, it is written right before the (armored) output.*/
+static int
+create_revocation (const char *filename,
+                   struct revocation_reason_info *reason,
+                   PKT_public_key *psk,
+                   kbnode_t keyblock,
+                   const char *leadintext, int suffix,
+                   const char *cache_nonce)
 {
-    int rc = 0;
-    armor_filter_context_t *afx;
-    PACKET pkt;
-    PKT_secret_key *sk; /* used as pointer into a kbnode */
-    PKT_public_key *pk = NULL;
-    PKT_signature *sig = NULL;
-    u32 sk_keyid[2];
-    IOBUF out = NULL;
-    KBNODE keyblock = NULL, pub_keyblock = NULL;
-    KBNODE node;
-    KEYDB_HANDLE kdbhd;
-    struct revocation_reason_info *reason = NULL;
-    KEYDB_SEARCH_DESC desc;
+  int rc;
+  iobuf_t out = NULL;
+  armor_filter_context_t *afx;
+  PKT_signature *sig = NULL;
+  PACKET pkt;
 
-    if( opt.batch )
-      {
-       log_error(_("can't do this in batch mode\n"));
-       return G10ERR_GENERAL;
-      }
+  afx = new_armor_context ();
 
-    afx = new_armor_context ();
-    init_packet( &pkt );
-
-    /* search the userid: 
-     * We don't want the whole getkey stuff here but the entire keyblock
-     */
-    kdbhd = keydb_new (1);
-    classify_user_id (uname, &desc);
-    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
-    if (rc)
-      {
-       log_error (_("secret key \"%s\" not found: %s\n"),
-                   uname, g10_errstr (rc));
-       goto leave;
-      }
+  if ((rc = open_outfile (-1, filename, suffix, 1, &out)))
+    goto leave;
 
-    rc = keydb_get_keyblock (kdbhd, &keyblock );
-    if( rc ) {
-       log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
-       goto leave;
+  if (leadintext )
+    iobuf_writestr (out, leadintext);
+
+  afx->what = 1;
+  afx->hdrlines = "Comment: This is a revocation certificate\n";
+  push_armor_filter (afx, out);
+
+  rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
+                           0, 0,
+                           revocation_reason_build_cb, reason, cache_nonce);
+  if (rc)
+    {
+      log_error (_("make_keysig_packet failed: %s\n"), g10_errstr (rc));
+      goto leave;
     }
 
-    /* get the keyid from the keyblock */
-    node = find_kbnode( keyblock, PKT_SECRET_KEY );
-    if( !node ) 
-       BUG ();
+  if (keyblock && (PGP6 || PGP7 || PGP8))
+    {
+      /* Use a minimal pk for PGPx mode, since PGP can't import bare
+         revocation certificates. */
+      rc = export_minimal_pk (out, keyblock, sig, NULL);
+      if (rc)
+        goto leave;
+    }
+  else
+    {
+      init_packet (&pkt);
+      pkt.pkttype = PKT_SIGNATURE;
+      pkt.pkt.signature = sig;
+
+      rc = build_packet (out, &pkt);
+      if (rc)
+        {
+          log_error (_("build_packet failed: %s\n"), g10_errstr (rc));
+          goto leave;
+        }
+    }
 
-    /* fixme: should make a function out of this stuff,
-     * it's used all over the source */
-    sk = node->pkt->pkt.secret_key;
-    keyid_from_sk( sk, sk_keyid );
-    print_seckey_info (sk);
+ leave:
+  if (sig)
+    free_seckey_enc (sig);
+  if (rc)
+    iobuf_cancel (out);
+  else
+    iobuf_close (out);
+  release_armor_context (afx);
+  return rc;
+}
 
-    /* FIXME: We should get the public key direct from the secret one */
 
-    pub_keyblock=get_pubkeyblock(sk_keyid);
-    if(!pub_keyblock)
-      {
-       log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) );
-       goto leave;
-      }
+/* This function is used to generate a standard revocation certificate
+   by gpg's interactive key generation function.  The certificate is
+   stored at a dedicated place in a slightly modified form to avoid an
+   accidental import.  PSK is the primary key; a corresponding secret
+   key must be available.  CACHE_NONCE is optional but can be used to
+   help gpg-agent to avoid an extra passphrase prompt. */
+int
+gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce)
+{
+  int rc;
+  estream_t memfp;
+  struct revocation_reason_info reason;
+  char *dir, *tmpstr, *fname;
+  void *leadin;
+  size_t len;
+  u32 keyid[2];
+  char pkstrbuf[PUBKEY_STRING_SIZE];
+  char *orig_codeset;
 
-    node=find_kbnode(pub_keyblock,PKT_PUBLIC_KEY);
-    if(!node)
-      BUG();
+  dir = get_openpgp_revocdir (opt.homedir);
+  tmpstr = hexfingerprint (psk);
+  fname = xstrconcat (dir, DIRSEP_S, tmpstr, NULL);
+  xfree (tmpstr);
+  xfree (dir);
 
-    pk=node->pkt->pkt.public_key;
+  keyid_from_pk (psk, keyid);
 
-    if( cmp_public_secret_key( pk, sk ) ) {
-       log_error(_("public key does not match secret key!\n") );
-       rc = G10ERR_GENERAL;
-       goto leave;
-    }
+  memfp = es_fopenmem (0, "r+");
+  if (!memfp)
+    log_fatal ("error creating memory stream\n");
 
-    tty_printf("\n");
-    if( !cpr_get_answer_is_yes("gen_revoke.okay",
-                 _("Create a revocation certificate for this key? (y/N) ")) )
-      {
-       rc = 0;
-       goto leave;
-      }
+  orig_codeset = i18n_switchto_utf8 ();
 
-    if(sk->version>=4 || opt.force_v4_certs) {
-      /* get the reason for the revocation */
-      reason = ask_revocation_reason( 1, 0, 1 );
-      if( !reason ) { /* user decided to cancel */
-       rc = 0;
-       goto leave;
-      }
+  es_fprintf (memfp, "%s\n\n",
+              _("This is a revocation certificate for the OpenPGP key:"));
+
+  es_fprintf (memfp, "pub  %s/%s %s\n",
+              pubkey_string (psk, pkstrbuf, sizeof pkstrbuf),
+              keystr (keyid),
+              datestr_from_pk (psk));
+
+  print_fingerprint (memfp, psk, 3);
+
+  tmpstr = get_user_id (keyid, &len);
+  es_fprintf (memfp, "uid%*s%.*s\n\n",
+              (int)keystrlen () + 10, "",
+              (int)len, tmpstr);
+  xfree (tmpstr);
+
+  es_fprintf (memfp, "%s\n\n%s\n\n:",
+     _("Use it to revoke this key in case of a compromise or loss of\n"
+       "the secret key.  However, if the secret key is still accessible,\n"
+       "it is better to generate a new revocation certificate and give\n"
+       "a reason for the revocation."),
+     _("To avoid an accidental use of this file, a colon has been inserted\n"
+       "before the 5 dashes below.  Remove this colon with a text editor\n"
+       "before making use of this revocation certificate."));
+
+  es_putc (0, memfp);
+
+  i18n_switchback (orig_codeset);
+
+  if (es_fclose_snatch (memfp, &leadin, NULL))
+    log_fatal ("error snatching memory stream\n");
+
+  reason.code = 0x00; /* No particular reason.  */
+  reason.desc = NULL;
+  rc = create_revocation (fname, &reason, psk, NULL, leadin, 3, cache_nonce);
+  xfree (leadin);
+  xfree (fname);
+
+  return rc;
+}
+
+
+
+/****************
+ * Generate a revocation certificate for UNAME
+ */
+int
+gen_revoke (const char *uname)
+{
+  int rc = 0;
+  PKT_public_key *psk;
+  u32 keyid[2];
+  kbnode_t keyblock = NULL;
+  kbnode_t node;
+  KEYDB_HANDLE kdbhd;
+  struct revocation_reason_info *reason = NULL;
+  KEYDB_SEARCH_DESC desc;
+
+  if( opt.batch )
+    {
+      log_error(_("can't do this in batch mode\n"));
+      return G10ERR_GENERAL;
     }
 
-    switch( is_secret_key_protected( sk ) ) {
-      case -1:
-       log_error(_("unknown protection algorithm\n"));
-       rc = G10ERR_PUBKEY_ALGO;
-       break;
-      case -3:
-       tty_printf (_("Secret parts of primary key are not available.\n"));
-        rc = G10ERR_NO_SECKEY;
-        break;
-      case 0:
-       tty_printf(_("NOTE: This key is not protected!\n"));
-       break;
-      default:
-        rc = check_secret_key( sk, 0 );
-       break;
+  /* Search the userid; we don't want the whole getkey stuff here.  */
+  kdbhd = keydb_new ();
+  rc = classify_user_id (uname, &desc, 1);
+  if (!rc)
+    rc = keydb_search (kdbhd, &desc, 1, NULL);
+  if (rc)
+    {
+      log_error (_("secret key \"%s\" not found: %s\n"),
+                 uname, g10_errstr (rc));
+      goto leave;
     }
-    if( rc )
-       goto leave;
 
+  rc = keydb_get_keyblock (kdbhd, &keyblock );
+  if (rc)
+    {
+      log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
+      goto leave;
+    }
 
-    if( !opt.armor )
-       tty_printf(_("ASCII armored output forced.\n"));
+  /* Get the keyid from the keyblock.  */
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node)
+    BUG ();
 
-    if( (rc = open_outfile( NULL, 0, &out )) )
-       goto leave;
+  psk = node->pkt->pkt.public_key;
+  rc = agent_probe_secret_key (NULL, psk);
+  if (rc)
+    {
+      log_error (_("secret key \"%s\" not found: %s\n"),
+                 uname, gpg_strerror (rc));
+      goto leave;
+    }
 
-    afx->what = 1;
-    afx->hdrlines = "Comment: A revocation certificate should follow\n";
-    push_armor_filter (afx, out);
+  keyid_from_pk (psk, keyid );
+  print_seckey_info (psk);
 
-    /* create it */
-    rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
-                            opt.force_v4_certs?4:0, 0, 0,
-                            revocation_reason_build_cb, reason );
-    if( rc ) {
-       log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
-       goto leave;
+  tty_printf("\n");
+  if (!cpr_get_answer_is_yes ("gen_revoke.okay",
+                _("Create a revocation certificate for this key? (y/N) ")))
+    {
+      rc = 0;
+      goto leave;
     }
 
-    if(PGP2 || PGP6 || PGP7 || PGP8)
-      {
-       /* Use a minimal pk for PGPx mode, since PGP can't import bare
-          revocation certificates. */
-       rc=export_minimal_pk(out,pub_keyblock,sig,NULL);
-       if(rc)
-         goto leave;
-      }
-    else
-      {
-       init_packet( &pkt );
-       pkt.pkttype = PKT_SIGNATURE;
-       pkt.pkt.signature = sig;
+  /* Get the reason for the revocation.  */
+  reason = ask_revocation_reason (1, 0, 1);
+  if (!reason)
+    {
+      /* User decided to cancel.  */
+      rc = 0;
+      goto leave;
+    }
 
-       rc = build_packet( out, &pkt );
-       if( rc ) {
-         log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
-         goto leave;
-       }
-      }
+  if (!opt.armor)
+    tty_printf (_("ASCII armored output forced.\n"));
 
-    /* and issue a usage notice */
-    tty_printf(_("Revocation certificate created.\n\n"
+  rc = create_revocation (NULL, reason, psk, keyblock, NULL, 0, NULL);
+  if (rc)
+    goto leave;
+
+  /* and issue a usage notice */
+  tty_printf (_(
+"Revocation certificate created.\n\n"
 "Please move it to a medium which you can hide away; if Mallory gets\n"
 "access to this certificate he can use it to make your key unusable.\n"
 "It is smart to print this certificate and store it away, just in case\n"
 "your media become unreadable.  But have some caution:  The print system of\n"
 "your machine might store the data and make it available to others!\n"));
 
-  leave:
-    if( sig )
-       free_seckey_enc( sig );
-    release_kbnode( keyblock );
-    release_kbnode( pub_keyblock );
-    keydb_release (kdbhd);
-    if( rc )
-       iobuf_cancel(out);
-    else
-       iobuf_close(out);
-    release_revocation_reason_info( reason );
-    release_armor_context (afx);
-    return rc;
+ leave:
+  release_kbnode (keyblock);
+  keydb_release (kdbhd);
+  release_revocation_reason_info( reason );
+  return rc;
 }
 
 
index f891937..8eb005f 100644 (file)
@@ -35,7 +35,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "../jnlib/types.h"
+#include "../common/types.h"
 #include "rmd160.h"
 
 /*
@@ -55,7 +55,7 @@ rol (u32 x, int n)
 #endif
 
 /* Structure holding the context for the RIPE-MD160 computation.  */
-typedef struct 
+typedef struct
 {
   u32 h0, h1, h2, h3, h4;
   u32 nblocks;
@@ -88,10 +88,10 @@ transform (rmd160_context_t *hd, const unsigned char *data)
   u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
 #ifdef BIG_ENDIAN_HOST
   u32 x[16];
-  { 
+  {
     int i;
     unsigned char *p2, *p1;
-    for (i=0, p1=data, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) 
+    for (i=0, p1=data, p2=(unsigned char*)x; i < 16; i++, p2 += 4 )
       {
         p2[3] = *p1++;
         p2[2] = *p1++;
@@ -315,8 +315,8 @@ transform (rmd160_context_t *hd, const unsigned char *data)
 static void
 rmd160_write (rmd160_context_t *hd, const unsigned char *inbuf, size_t inlen)
 {
-  if( hd->count == 64 ) 
-    { 
+  if( hd->count == 64 )
+    {
       /* Flush the buffer.  */
       transform (hd, hd->buf);
       hd->count = 0;
@@ -371,7 +371,7 @@ rmd160_final( rmd160_context_t *hd )
   msb |= t >> 29;
 
   if (hd->count < 56)
-    { 
+    {
       /* Enough room.  */
       hd->buf[hd->count++] = 0x80; /* Pad character. */
       while (hd->count < 56)
@@ -396,7 +396,7 @@ rmd160_final( rmd160_context_t *hd )
   hd->buf[62] = msb >> 16;
   hd->buf[63] = msb >> 24;
   transform (hd, hd->buf);
-  
+
   p = hd->buf;
 #define X(a) do { *p++ = hd->h##a;       *p++ = hd->h##a >> 8; \
                   *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
@@ -417,7 +417,7 @@ void
 rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length)
 {
   rmd160_context_t hd;
-  
+
   rmd160_init (&hd);
   rmd160_write (&hd, buffer, length);
   rmd160_final (&hd);
index ad2f52d..1dde6f9 100644 (file)
@@ -1,4 +1,4 @@
-/* seckey-cert.c -  secret key certificate packet handling
+/* seckey-cert.c - Not anymore used
  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
  *               2006, 2009 Free Software Foundation, Inc.
  *
@@ -18,6 +18,8 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#error Not anymore used - only kept for reference in the repository.
+
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "pkglue.h"
 
 static int
-do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
-          int *canceled )
+xxxx_do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
+               int *canceled )
 {
     gpg_error_t err;
+    byte *buffer;
     u16 csum=0;
     int i, res;
     size_t nbytes;
@@ -59,11 +62,6 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
        if( openpgp_cipher_test_algo( sk->protect.algo ) ) {
            log_info(_("protection algorithm %d%s is not supported\n"),
                        sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" );
-           if (sk->protect.algo==CIPHER_ALGO_IDEA)
-              {
-                write_status (STATUS_RSA_OR_IDEA);
-                idea_cipher_warn (0);
-              }
            return G10ERR_CIPHER_ALGO;
        }
        if(gcry_md_test_algo (sk->protect.s2k.hash_algo))
@@ -74,10 +72,11 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
          }
        keyid_from_sk( sk, keyid );
        keyid[2] = keyid[3] = 0;
-       if( !sk->is_primary ) {
+       if (!sk->flags.primary)
+          {
             keyid[2] = sk->main_keyid[0];
             keyid[3] = sk->main_keyid[1];
-       }
+          }
        dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
                                 &sk->protect.s2k, mode,
                                  tryagain_text, canceled );
@@ -115,13 +114,10 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
             p = gcry_mpi_get_opaque ( sk->skey[i], &ndatabits );
             ndata = (ndatabits+7)/8;
 
-            if ( ndata > 1 && p )
+            if ( ndata > 1 )
                 csumc = p[ndata-2] << 8 | p[ndata-1];
            data = xmalloc_secure ( ndata );
-            if (p)
-              gcry_cipher_decrypt ( cipher_hd, data, ndata, p, ndata );
-            else
-              memset (data, 0, ndata);
+           gcry_cipher_decrypt ( cipher_hd, data, ndata, p, ndata );
            gcry_mpi_release (sk->skey[i]); sk->skey[i] = NULL ;
 
            p = data;
@@ -199,28 +195,21 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
 
                 assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
                 p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
-                if (!p)
-                  err = -1;
-                else
-                  {
-                    byte *buffer;
-
-                    ndata = (ndatabits+7)/8;
-                    assert (ndata >= 2);
-                    assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
-                    buffer = xmalloc_secure (ndata);
-                    gcry_cipher_sync (cipher_hd);
-                    buffer[0] = p[0];
-                    buffer[1] = p[1];
-                    gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2,
-                                         p+2, ndata-2);
-                    csum += checksum (buffer, ndata);
-                    gcry_mpi_release (sk->skey[i]);
-
-                    err = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
-                                         buffer, ndata, &ndata );
-                    xfree (buffer);
-                  }
+                ndata = (ndatabits+7)/8;
+                assert (ndata >= 2);
+                assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
+                buffer = xmalloc_secure (ndata);
+               gcry_cipher_sync (cipher_hd);
+                buffer[0] = p[0];
+                buffer[1] = p[1];
+                gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2,
+                                     p+2, ndata-2);
+                csum += checksum (buffer, ndata);
+                gcry_mpi_release (sk->skey[i]);
+
+               err = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
+                                    buffer, ndata, &ndata );
+               xfree (buffer);
                 if (err)
                   {
                     /* Checksum was okay, but not correctly
@@ -265,218 +254,3 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
 
     return 0;
 }
-
-
-
-/****************
- * Check the secret key
- * Ask up to 3 (or n) times for a correct passphrase
- * If n is negative, disable the key info prompt and make n=abs(n)
- */
-int
-check_secret_key( PKT_secret_key *sk, int n )
-{
-    int rc = gpg_error (GPG_ERR_BAD_PASSPHRASE);
-    int i,mode;
-
-    if (sk && sk->is_protected && sk->protect.s2k.mode == 1002)
-      return 0; /* Let the scdaemon handle this. */
-
-    if(n<0)
-      {
-       n=abs(n);
-       mode=1;
-      }
-    else
-      mode=0;
-
-    if( n < 1 )
-       n = 3; /* Use the default value */
-
-    for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) {
-        int canceled = 0;
-        const char *tryagain = NULL;
-       if (i) {
-            tryagain = N_("Invalid passphrase; please try again");
-            log_info (_("%s ...\n"), _(tryagain));
-        }
-       rc = do_check( sk, tryagain, mode, &canceled );
-       if ( gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
-             && is_status_enabled () ) {
-           u32 kid[2];
-           char buf[50];
-
-           keyid_from_sk( sk, kid );
-           sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]);
-           write_status_text( STATUS_BAD_PASSPHRASE, buf );
-       }
-       if( have_static_passphrase() || canceled)
-           break;
-    }
-
-    if( !rc )
-       write_status( STATUS_GOOD_PASSPHRASE );
-
-    return rc;
-}
-
-/****************
- * check whether the secret key is protected.
- * Returns: 0 not protected, -1 on error or the protection algorithm
- *                           -2 indicates a card stub.
- *                           -3 indicates a not-online stub.
- */
-int
-is_secret_key_protected( PKT_secret_key *sk )
-{
-    return sk->is_protected?
-               sk->protect.s2k.mode == 1002? -2 :
-               sk->protect.s2k.mode == 1001? -3 : sk->protect.algo : 0;
-}
-
-
-
-/****************
- * Protect the secret key with the passphrase from DEK
- */
-int
-protect_secret_key( PKT_secret_key *sk, DEK *dek )
-{
-    int i,j, rc = 0;
-    byte *buffer;
-    size_t nbytes;
-    u16 csum;
-
-    if( !dek )
-       return 0;
-
-    if( !sk->is_protected ) { /* okay, apply the protection */
-       gcry_cipher_hd_t cipher_hd=NULL;
-
-       if ( openpgp_cipher_test_algo ( sk->protect.algo ) ) {
-            /* Unsupport protection algorithm. */
-            rc = gpg_error (GPG_ERR_CIPHER_ALGO);
-        }
-       else {
-           print_cipher_algo_note( sk->protect.algo );
-
-           if ( openpgp_cipher_open (&cipher_hd, sk->protect.algo,
-                                     GCRY_CIPHER_MODE_CFB,
-                                     (GCRY_CIPHER_SECURE
-                                      | (sk->protect.algo >= 100 ?
-                                         0 : GCRY_CIPHER_ENABLE_SYNC))) )
-              BUG();
-           if ( gcry_cipher_setkey ( cipher_hd, dek->key, dek->keylen ) )
-               log_info(_("WARNING: Weak key detected"
-                          " - please change passphrase again.\n"));
-           sk->protect.ivlen = openpgp_cipher_get_algo_blklen (sk->protect.algo);
-           assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
-           if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 )
-               BUG(); /* yes, we are very careful */
-           gcry_create_nonce (sk->protect.iv, sk->protect.ivlen);
-           gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen);
-           if( sk->version >= 4 ) {
-                byte *bufarr[PUBKEY_MAX_NSKEY];
-               size_t narr[PUBKEY_MAX_NSKEY];
-               unsigned int nbits[PUBKEY_MAX_NSKEY];
-               int ndata=0;
-               byte *p, *data;
-
-               for (j=0, i = pubkey_get_npkey(sk->pubkey_algo);
-                       i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ )
-                  {
-                   assert (!gcry_mpi_get_flag (sk->skey[i],
-                                                GCRYMPI_FLAG_OPAQUE));
-                   if (gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j,
-                                         narr+j, sk->skey[i]))
-                      BUG();
-                   nbits[j] = gcry_mpi_get_nbits (sk->skey[i]);
-                   ndata += narr[j] + 2;
-                  }
-               for ( ; j < PUBKEY_MAX_NSKEY; j++ )
-                  bufarr[j] = NULL;
-
-               ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */
-
-               data = xmalloc_secure( ndata );
-               p = data;
-               for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) {
-                   p[0] = nbits[j] >> 8 ;
-                   p[1] = nbits[j];
-                   p += 2;
-                   memcpy(p, bufarr[j], narr[j] );
-                   p += narr[j];
-                   xfree(bufarr[j]);
-               }
-
-                if (opt.simple_sk_checksum) {
-                    log_info (_("generating the deprecated 16-bit checksum"
-                              " for secret key protection\n"));
-                    csum = checksum( data, ndata-2);
-                    sk->csum = csum;
-                    *p++ =     csum >> 8;
-                    *p++ =     csum;
-                    sk->protect.sha1chk = 0;
-                }
-                else {
-                    gcry_md_hd_t h;
-
-                    if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
-                      BUG(); /* Algo not available. */
-                    gcry_md_write (h, data, ndata - 20);
-                    gcry_md_final (h);
-                    memcpy (p, gcry_md_read (h, DIGEST_ALGO_SHA1), 20);
-                    p += 20;
-                    gcry_md_close (h);
-                    sk->csum = csum = 0;
-                    sk->protect.sha1chk = 1;
-                }
-                assert( p == data+ndata );
-
-               gcry_cipher_encrypt (cipher_hd, data, ndata, NULL, 0);
-               for (i = pubkey_get_npkey(sk->pubkey_algo);
-                     i < pubkey_get_nskey(sk->pubkey_algo); i++ )
-                  {
-                   gcry_mpi_release (sk->skey[i]);
-                   sk->skey[i] = NULL;
-                  }
-               i = pubkey_get_npkey(sk->pubkey_algo);
-               sk->skey[i] = gcry_mpi_set_opaque (NULL, data, ndata*8 );
-           }
-           else {
-               csum = 0;
-               for(i=pubkey_get_npkey(sk->pubkey_algo);
-                       i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
-                    byte *data;
-                   unsigned int nbits;
-
-                   csum += checksum_mpi (sk->skey[i]);
-
-                   if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer,
-                                         &nbytes, sk->skey[i] ))
-                      BUG();
-                   gcry_cipher_sync (cipher_hd);
-                   assert (!gcry_mpi_get_flag (sk->skey[i],
-                                                GCRYMPI_FLAG_OPAQUE));
-
-                    data = xmalloc (nbytes+2);  /* fixme: need xtrymalloc. */
-                    nbits = gcry_mpi_get_nbits (sk->skey[i]);
-                    assert (nbytes == (nbits + 7)/8);
-                    data[0] = nbits >> 8;
-                    data[1] = nbits;
-                   gcry_cipher_encrypt (cipher_hd, data+2, nbytes,
-                                         buffer, nbytes);
-                   xfree( buffer );
-
-                    gcry_mpi_release (sk->skey[i]);
-                    sk->skey[i] = gcry_mpi_set_opaque (NULL,
-                                                       data, (nbytes+2)*8 );
-               }
-               sk->csum = csum;
-           }
-           sk->is_protected = 1;
-           gcry_cipher_close (cipher_hd);
-       }
-    }
-    return rc;
-}
index 6f3b881..d02f20e 100644 (file)
 #include "i18n.h"
 #include "options.h"
 #include "../common/sysutils.h"
+#include "status.h"
 
 
 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
 
 
 /* Data used to associate an Assuan context with local server data.  */
-struct server_local_s 
+struct server_local_s
 {
   /* Our current Assuan context. */
-  assuan_context_t assuan_ctx;  
+  assuan_context_t assuan_ctx;
   /* File descriptor as set by the MESSAGE command. */
-  gnupg_fd_t message_fd;               
+  gnupg_fd_t message_fd;
+
+  /* List of prepared recipients.  */
+  pk_list_t recplist;
+
+  /* Set if pinentry notifications should be passed back to the
+     client. */
+  int allow_pinentry_notify;
 };
 
 
 \f
 /* Helper to close the message fd if it is open. */
-static void 
+static void
 close_message_fd (ctrl_t ctrl)
 {
   if (ctrl->server_local->message_fd != GNUPG_INVALID_FD)
     {
       assuan_sock_close (ctrl->server_local->message_fd);
       ctrl->server_local->message_fd = GNUPG_INVALID_FD;
-    } 
+    }
+}
+
+
+/* Skip over options.  Blanks after the options are also removed.  */
+static char *
+skip_options (const char *line)
+{
+  while (spacep (line))
+    line++;
+  while ( *line == '-' && line[1] == '-' )
+    {
+      while (*line && !spacep (line))
+        line++;
+      while (spacep (line))
+        line++;
+    }
+  return (char*)line;
+}
+
+
+/* Check whether the option NAME appears in LINE.  */
+static int
+has_option (const char *line, const char *name)
+{
+  const char *s;
+  int n = strlen (name);
+
+  s = strstr (line, name);
+  if (s && s >= skip_options (line))
+    return 0;
+  return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
 }
 
 
+
+
 \f
 /* Called by libassuan for Assuan options.  See the Assuan manual for
    details. */
 static gpg_error_t
 option_handler (assuan_context_t ctx, const char *key, const char *value)
 {
-/*   ctrl_t ctrl = assuan_get_pointer (ctx); */
+  ctrl_t ctrl = assuan_get_pointer (ctx);
 
-  (void)ctx;
   (void)value;
 
   /* Fixme: Implement the tty and locale args. */
@@ -98,6 +138,10 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
     {
       /* This is for now a dummy option. */
     }
+  else if (!strcmp (key, "allow-pinentry-notify"))
+    {
+      ctrl->server_local->allow_pinentry_notify = 1;
+    }
   else
     return gpg_error (GPG_ERR_UNKNOWN_OPTION);
 
@@ -113,6 +157,9 @@ reset_notify (assuan_context_t ctx, char *line)
 
   (void)line;
 
+  release_pk_list (ctrl->server_local->recplist);
+  ctrl->server_local->recplist = NULL;
+
   close_message_fd (ctrl);
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
@@ -147,7 +194,7 @@ static gpg_error_t
 output_notify (assuan_context_t ctx, char *line)
 {
 /*   ctrl_t ctrl = assuan_get_pointer (ctx); */
-  
+
   (void)ctx;
 
   if (strstr (line, "--armor"))
@@ -162,7 +209,7 @@ output_notify (assuan_context_t ctx, char *line)
 
 
 \f
-/*  RECIPIENT <userID>
+/*  RECIPIENT [--hidden] <userID>
 
    Set the recipient for the encryption.  <userID> should be the
    internal representation of the key; the server may accept any other
@@ -176,9 +223,26 @@ output_notify (assuan_context_t ctx, char *line)
 static gpg_error_t
 cmd_recipient (assuan_context_t ctx, char *line)
 {
-  (void)ctx;
-  (void)line;
-  return gpg_error (GPG_ERR_NOT_SUPPORTED);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  int hidden;
+
+  hidden = has_option (line,"--hidden");
+  line = skip_options (line);
+
+  /* FIXME: Expand groups
+  if (opt.grouplist)
+    remusr = expand_group (rcpts);
+  else
+    remusr = rcpts;
+  */
+
+  err = find_and_check_key (ctrl, line, PUBKEY_USAGE_ENC, hidden,
+                            &ctrl->server_local->recplist);
+
+  if (err)
+    log_error ("command '%s' failed: %s\n", "RECIPIENT", gpg_strerror (err));
+  return err;
 }
 
 
@@ -208,39 +272,116 @@ cmd_signer (assuan_context_t ctx, char *line)
 
 
 \f
-/*  ENCRYPT 
+/*  ENCRYPT
 
    Do the actual encryption process.  Takes the plaintext from the
-   INPUT command, writes to the ciphertext to the file descriptor set
-   with the OUTPUT command, take the recipients form 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.  GPG 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.  */
+   INPUT command, writes the ciphertext to the file descriptor set
+   with the OUTPUT command, take the recipients from all the
+   recipients set so far with RECIPIENTS.
+
+   If this command fails the clients should try to delete all output
+   currently done or otherwise mark it as invalid.  GPG does ensure
+   that there won't be any security problem with leftover data on the
+   output in this case.
+
+   In most cases this command won't fail because most necessary checks
+   have been done while setting the recipients.  However some checks
+   can only be done right here and thus error may occur anyway (for
+   example, no recipients at all).
+
+   The input, output and message pipes are closed after this
+   command.  */
 static gpg_error_t
 cmd_encrypt (assuan_context_t ctx, char *line)
 {
-  (void)ctx;
-  (void)line;
-  return gpg_error (GPG_ERR_NOT_SUPPORTED);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  int inp_fd, out_fd;
+
+  (void)line; /* LINE is not used.  */
+
+  if ( !ctrl->server_local->recplist )
+    {
+      write_status_text (STATUS_NO_RECP, "0");
+      err = gpg_error (GPG_ERR_NO_USER_ID);
+      goto leave;
+    }
+
+  inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
+  if (inp_fd == -1)
+    {
+      err = set_error (GPG_ERR_ASS_NO_INPUT, NULL);
+      goto leave;
+    }
+  out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
+  if (out_fd == -1)
+    {
+      err = set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
+      goto leave;
+    }
+
+
+  /* FIXME: GPGSM does this here: Add all encrypt-to marked recipients
+     from the default list. */
+
+  /* fixme: err = ctrl->audit? 0 : start_audit_session (ctrl);*/
+
+  err = encrypt_crypt (ctrl, inp_fd, NULL, NULL, 0,
+                       ctrl->server_local->recplist,
+                       out_fd);
+
+ leave:
+  /* Release the recipient list on success.  */
+  if (!err)
+    {
+      release_pk_list (ctrl->server_local->recplist);
+      ctrl->server_local->recplist = NULL;
+    }
+
+  /* Close and reset the fds. */
+  close_message_fd (ctrl);
+  assuan_close_input_fd (ctx);
+  assuan_close_output_fd (ctx);
+
+  if (err)
+    log_error ("command '%s' failed: %s\n", "ENCRYPT", gpg_strerror (err));
+  return err;
 }
 
 
 \f
 /*  DECRYPT
 
-   This performs the decrypt operation after doing some checks on the
-   internal state (e.g. that only needed data has been set).   */
+    This performs the decrypt operation.  */
 static gpg_error_t
 cmd_decrypt (assuan_context_t ctx, char *line)
 {
-  (void)ctx;
-  (void)line;
-  return gpg_error (GPG_ERR_NOT_SUPPORTED);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  int inp_fd, out_fd;
+
+  (void)line; /* LINE is not used.  */
+
+  inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
+  if (inp_fd == -1)
+    return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
+  out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
+  if (out_fd == -1)
+    return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
+
+  glo_ctrl.lasterr = 0;
+  err = decrypt_message_fd (ctrl, inp_fd, out_fd);
+  if (!err)
+    err = glo_ctrl.lasterr;
+
+  /* Close and reset the fds. */
+  close_message_fd (ctrl);
+  assuan_close_input_fd (ctx);
+  assuan_close_output_fd (ctx);
+
+  if (err)
+    log_error ("command '%s' failed: %s\n", "DECRYPT", gpg_strerror (err));
+  return err;
 }
 
 
@@ -250,7 +391,7 @@ cmd_decrypt (assuan_context_t ctx, char *line)
    This 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.
  */
@@ -258,10 +399,18 @@ static gpg_error_t
 cmd_verify (assuan_context_t ctx, char *line)
 {
   int rc;
+#ifdef HAVE_W32_SYSTEM
+  (void)ctx;
+  (void)line;
+  rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#else
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gnupg_fd_t fd = assuan_get_input_fd (ctx);
   gnupg_fd_t out_fd = assuan_get_output_fd (ctx);
-  FILE *out_fp = NULL;
+  estream_t out_fp = NULL;
+
+  /* FIXME: Revamp this code it is nearly to 3 years old and was only
+     intended as a quick test.  */
 
   (void)line;
 
@@ -270,27 +419,33 @@ cmd_verify (assuan_context_t ctx, char *line)
 
   if (out_fd != GNUPG_INVALID_FD)
     {
-      out_fp = fdopen ( dup (FD2INT (out_fd)), "w");
+      es_syshd_t syshd;
+
+#ifdef HAVE_W32_SYSTEM
+      syshd.type = ES_SYSHD_HANDLE;
+      syshd.u.handle = out_fd;
+#else
+      syshd.type = ES_SYSHD_FD;
+      syshd.u.fd = out_fd;
+#endif
+      out_fp = es_sysopen_nc (&syshd, "w");
       if (!out_fp)
-        return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
+        return set_error (gpg_err_code_from_syserror (), "fdopen() failed");
     }
 
-  log_debug ("WARNING: The server mode work "
-             "in progress and not ready for use\n");
+  log_debug ("WARNING: The server mode is WORK "
+             "IN PROGRESS and not ready for use\n");
 
-  /* Need to dup it because it might get closed and libassuan won't
-     know about it then. */
-  rc = gpg_verify (ctrl,
-                   dup ( FD2INT (fd)), 
-                   dup ( FD2INT (ctrl->server_local->message_fd)),
-                   out_fp);
+  rc = gpg_verify (ctrl, fd, ctrl->server_local->message_fd, out_fp);
 
-  if (out_fp)
-    fclose (out_fp);
+  es_fclose (out_fp);
   close_message_fd (ctrl);
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
+#endif
 
+  if (rc)
+    log_error ("command '%s' failed: %s\n", "VERIFY", gpg_strerror (rc));
   return rc;
 }
 
@@ -457,16 +612,36 @@ cmd_getinfo (assuan_context_t ctx, char *line)
   return rc;
 }
 
+static const char hlp_passwd[] =
+  "PASSWD <userID>\n"
+  "\n"
+  "Change the passphrase of the secret key for USERID.";
+static gpg_error_t
+cmd_passwd (assuan_context_t ctx, char *line)
+{
+  /* ctrl_t ctrl = assuan_get_pointer (ctx); */
+  gpg_error_t err;
+
+  (void)ctx;
+  line = skip_options (line);
+
+  err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  return err;
+}
+
+
 
 \f
 /* Helper to register our commands with libassuan. */
 static int
 register_commands (assuan_context_t ctx)
 {
-  static struct 
+  static struct
   {
     const char *name;
     assuan_handler_t handler;
+    const char * const help;
   } table[] = {
     { "RECIPIENT",     cmd_recipient },
     { "SIGNER",        cmd_signer    },
@@ -476,24 +651,26 @@ register_commands (assuan_context_t ctx)
     { "SIGN",          cmd_sign      },
     { "IMPORT",        cmd_import    },
     { "EXPORT",        cmd_export    },
-    { "INPUT",         NULL          }, 
-    { "OUTPUT",        NULL          }, 
+    { "INPUT",         NULL          },
+    { "OUTPUT",        NULL          },
     { "MESSAGE",       cmd_message   },
     { "LISTKEYS",      cmd_listkeys  },
     { "LISTSECRETKEYS",cmd_listsecretkeys },
     { "GENKEY",        cmd_genkey    },
     { "DELKEYS",       cmd_delkeys   },
     { "GETINFO",       cmd_getinfo   },
+    { "PASSWD",        cmd_passwd,  hlp_passwd},
     { NULL }
   };
   int i, rc;
 
   for (i=0; table[i].name; i++)
     {
-      rc = assuan_register_command (ctx, table[i].name, table[i].handler, NULL);
+      rc = assuan_register_command (ctx, table[i].name,
+                                    table[i].handler, table[i].help);
       if (rc)
         return rc;
-    } 
+    }
   return 0;
 }
 
@@ -506,7 +683,9 @@ int
 gpg_server (ctrl_t ctrl)
 {
   int rc;
+#ifndef HAVE_W32_SYSTEM
   int filedes[2];
+#endif
   assuan_context_t ctx = NULL;
   static const char hello[] = ("GNU Privacy Guard's OpenPGP server "
                                VERSION " ready");
@@ -514,8 +693,10 @@ gpg_server (ctrl_t ctrl)
   /* We use a pipe based server so that we can work from scripts.
      assuan_init_pipe_server will automagically detect when we are
      called with a socketpair and ignore FILEDES in this case.  */
+#ifndef HAVE_W32_SYSTEM
   filedes[0] = assuan_fdopen (0);
   filedes[1] = assuan_fdopen (1);
+#endif
   rc = assuan_new (&ctx);
   if (rc)
     {
@@ -523,8 +704,12 @@ gpg_server (ctrl_t ctrl)
                 gpg_strerror (rc));
       goto leave;
     }
-  
+
+#ifdef HAVE_W32_SYSTEM
+  rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#else
   rc = assuan_init_pipe_server (ctx, filedes);
+#endif
   if (rc)
     {
       log_error ("failed to initialize the server: %s\n", gpg_strerror (rc));
@@ -543,20 +728,17 @@ gpg_server (ctrl_t ctrl)
   if (opt.verbose || opt.debug)
     {
       char *tmp = NULL;
-      const char *s1 = getenv ("GPG_AGENT_INFO");
-
-      if (asprintf (&tmp,
-                    "Home: %s\n"
-                    "Config: %s\n"
-                    "AgentInfo: %s\n"
-                    "%s",
-                    opt.homedir,
-                    "fixme: need config filename",
-                    s1?s1:"[not set]",
-                    hello) > 0)
+
+      tmp = xtryasprintf ("Home: %s\n"
+                          "Config: %s\n"
+                          "%s",
+                          opt.homedir,
+                          "fixme: need config filename",
+                          hello);
+      if (tmp)
         {
           assuan_set_hello_line (ctx, tmp);
-          free (tmp);
+          xfree (tmp);
         }
     }
   else
@@ -575,9 +757,6 @@ gpg_server (ctrl_t ctrl)
   ctrl->server_local->assuan_ctx = ctx;
   ctrl->server_local->message_fd = GNUPG_INVALID_FD;
 
-  if (DBG_ASSUAN)
-    assuan_set_log_stream (ctx, log_get_stream ());
-
   for (;;)
     {
       rc = assuan_accept (ctx);
@@ -591,7 +770,7 @@ gpg_server (ctrl_t ctrl)
           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
           break;
         }
-      
+
       rc = assuan_process (ctx);
       if (rc)
         {
@@ -601,9 +780,39 @@ gpg_server (ctrl_t ctrl)
     }
 
  leave:
-  xfree (ctrl->server_local);
-  ctrl->server_local = NULL;
+  if (ctrl->server_local)
+    {
+      release_pk_list (ctrl->server_local->recplist);
+
+      xfree (ctrl->server_local);
+      ctrl->server_local = NULL;
+    }
   assuan_release (ctx);
   return rc;
 }
 
+
+/* Helper to notify the client about Pinentry events.  Because that
+   might disturb some older clients, this is only done when enabled
+   via an option.  If it is not enabled we tell Windows to allow
+   setting the foreground window right here.  Returns an gpg error
+   code. */
+gpg_error_t
+gpg_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
+{
+  if (!ctrl || !ctrl->server_local
+      || !ctrl->server_local->allow_pinentry_notify)
+    {
+      gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
+      /* Client might be interested in that event - send as status line.  */
+      if (!strncmp (line, "PINENTRY_LAUNCHED", 17)
+          && (line[17]==' '||!line[17]))
+        {
+          for (line += 17; *line && spacep (line); line++)
+            ;
+          write_status_text (STATUS_PINENTRY_LAUNCHED, line);
+        }
+      return 0;
+    }
+  return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
+}
index ccbfe30..410f0bf 100644 (file)
@@ -1,6 +1,6 @@
 /* seskey.c -  make sesssion keys etc.
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2006, 2009 Free Software Foundation, Inc.
+ *               2006, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -26,7 +26,7 @@
 
 #include "gpg.h"
 #include "util.h"
-#include "cipher.h"
+#include "options.h"
 #include "main.h"
 #include "i18n.h"
 
@@ -48,10 +48,10 @@ make_session_key( DEK *dek )
                                 0 : GCRY_CIPHER_ENABLE_SYNC))) )
       BUG();
     gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
-    for (i=0; i < 16; i++ ) 
+    for (i=0; i < 16; i++ )
       {
        rc = gcry_cipher_setkey (chd, dek->key, dek->keylen);
-       if (!rc) 
+       if (!rc)
           {
            gcry_cipher_close (chd);
            return;
@@ -73,81 +73,127 @@ make_session_key( DEK *dek )
  * returns: A mpi with the session key (caller must free)
  */
 gcry_mpi_t
-encode_session_key (DEK *dek, unsigned int nbits)
+encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits)
 {
-    size_t nframe = (nbits+7) / 8;
-    byte *p;
-    byte *frame;
-    int i,n;
-    u16 csum;
-    gcry_mpi_t a;
-
-    /* The current limitation is that we can only use a session key
-     * whose length is a multiple of BITS_PER_MPI_LIMB
-     * I think we can live with that.
-     */
-    if( dek->keylen + 7 > nframe || !nframe )
-       log_bug("can't encode a %d bit key in a %d bits frame\n",
-                   dek->keylen*8, nbits );
-
-    /* We encode the session key in this way:
-     *
-     *    0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
-     *
-     * (But how can we store the leading 0 - the external representaion
-     * of MPIs doesn't allow leading zeroes =:-)
-     *
-     * RND are non-zero random bytes.
-     * A   is the cipher algorithm
-     * DEK is the encryption key (session key) length k depends on the
-     *    cipher algorithm (20 is used with blowfish160).
-     * CSUM is the 16 bit checksum over the DEK
-     */
-    csum = 0;
-    for( p = dek->key, i=0; i < dek->keylen; i++ )
-       csum += *p++;
+  size_t nframe = (nbits+7) / 8;
+  byte *p;
+  byte *frame;
+  int i,n;
+  u16 csum;
+  gcry_mpi_t a;
+
+  if (DBG_CIPHER)
+    log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen);
+
+  csum = 0;
+  for (p = dek->key, i=0; i < dek->keylen; i++)
+    csum += *p++;
+
+  /* Shortcut for ECDH.  It's padding is minimal to simply make the
+     output be a multiple of 8 bytes.  */
+  if (openpgp_pk_algo == PUBKEY_ALGO_ECDH)
+    {
+      /* Pad to 8 byte granulatiry; the padding byte is the number of
+       * padded bytes.
+       *
+       * A  DEK(k bytes)  CSUM(2 bytes) 0x 0x 0x 0x ... 0x
+       *                                +---- x times ---+
+       */
+      nframe = (( 1 + dek->keylen + 2 /* The value so far is always odd. */
+                  + 7 ) & (~7));
+
+      /* alg+key+csum fit and the size is congruent to 8.  */
+      assert (!(nframe%8) && nframe > 1 + dek->keylen + 2 );
+
+      frame = xmalloc_secure (nframe);
+      n = 0;
+      frame[n++] = dek->algo;
+      memcpy (frame+n, dek->key, dek->keylen);
+      n += dek->keylen;
+      frame[n++] = csum >> 8;
+      frame[n++] = csum;
+      i = nframe - n;         /* Number of padded bytes.  */
+      memset (frame+n, i, i); /* Use it as the value of each padded byte.  */
+      assert (n+i == nframe);
+
+      if (DBG_CIPHER)
+        log_debug ("encode_session_key: "
+                   "[%d] %02x  %02x %02x ...  %02x %02x %02x\n",
+                   (int) nframe, frame[0], frame[1], frame[2],
+                   frame[nframe-3], frame[nframe-2], frame[nframe-1]);
+
+      if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe))
+        BUG();
+      xfree(frame);
+      return a;
+    }
 
-    frame = xmalloc_secure( nframe );
-    n = 0;
-    frame[n++] = 0;
-    frame[n++] = 2;
-    i = nframe - 6 - dek->keylen;
-    assert( i > 0 );
-    p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
-    /* Replace zero bytes by new values. */
-    for(;;) {
-       int j, k;
-       byte *pp;
-
-       /* count the zero bytes */
-       for(j=k=0; j < i; j++ )
-           if( !p[j] )
-               k++;
-       if( !k )
-           break; /* okay: no zero bytes */
-       k += k/128 + 3; /* better get some more */
-       pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
-       for(j=0; j < i && k ;) {
-           if( !p[j] )
-               p[j] = pp[--k];
-            if (p[j])
-              j++;
+  /* The current limitation is that we can only use a session key
+   * whose length is a multiple of BITS_PER_MPI_LIMB
+   * I think we can live with that.
+   */
+  if (dek->keylen + 7 > nframe || !nframe)
+    log_bug ("can't encode a %d bit key in a %d bits frame\n",
+             dek->keylen*8, nbits );
+
+  /* We encode the session key in this way:
+   *
+   *      0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
+   *
+   * (But how can we store the leading 0 - the external representaion
+   *  of MPIs doesn't allow leading zeroes =:-)
+   *
+   * RND are non-zero random bytes.
+   * A   is the cipher algorithm
+   * DEK is the encryption key (session key) length k depends on the
+   *      cipher algorithm (20 is used with blowfish160).
+   * CSUM is the 16 bit checksum over the DEK
+   */
+
+  frame = xmalloc_secure( nframe );
+  n = 0;
+  frame[n++] = 0;
+  frame[n++] = 2;
+  i = nframe - 6 - dek->keylen;
+  assert( i > 0 );
+  p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
+  /* Replace zero bytes by new values.  */
+  for (;;)
+    {
+      int j, k;
+      byte *pp;
+
+      /* Count the zero bytes. */
+      for (j=k=0; j < i; j++ )
+        if (!p[j])
+          k++;
+      if (!k)
+        break; /* Okay: no zero bytes. */
+      k += k/128 + 3; /* Better get some more. */
+      pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
+      for (j=0; j < i && k ;)
+        {
+          if (!p[j])
+            p[j] = pp[--k];
+          if (p[j])
+            j++;
         }
-       xfree(pp);
+      xfree (pp);
     }
-    memcpy( frame+n, p, i );
-    xfree(p);
-    n += i;
-    frame[n++] = 0;
-    frame[n++] = dek->algo;
-    memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen;
-    frame[n++] = csum >>8;
-    frame[n++] = csum;
-    assert( n == nframe );
-    if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
-      BUG();
-    xfree(frame);
-    return a;
+  memcpy (frame+n, p, i);
+  xfree (p);
+  n += i;
+  frame[n++] = 0;
+  frame[n++] = dek->algo;
+  memcpy (frame+n, dek->key, dek->keylen );
+  n += dek->keylen;
+  frame[n++] = csum >>8;
+  frame[n++] = csum;
+  assert (n == nframe);
+  if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
+    BUG();
+  xfree (frame);
+  return a;
 }
 
 
@@ -161,8 +207,8 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
     gcry_mpi_t a;
 
     if( len + asnlen + 4  > nframe )
-       log_bug("can't encode a %d bit MD into a %d bits frame\n",
-                   (int)(len*8), (int)nbits);
+      log_bug ("can't encode a %d bit MD into a %d bits frame, algo=%d\n",
+               (int)(len*8), (int)nbits, algo);
 
     /* We encode the MD in this way:
      *
@@ -206,23 +252,35 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
  * bits.
  */
 gcry_mpi_t
-encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
-                gcry_md_hd_t md, int hash_algo)
+encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
 {
   gcry_mpi_t frame;
+  size_t mdlen;
 
-  assert(hash_algo);
-  assert(pk || sk);
+  assert (hash_algo);
+  assert (pk);
 
-  if((pk?pk->pubkey_algo:sk->pubkey_algo) == GCRY_PK_DSA)
+  if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
+    {
+      /* EdDSA signs data of arbitrary length.  Thus no special
+         treatment is required.  */
+      frame = gcry_mpi_set_opaque_copy (NULL, gcry_md_read (md, hash_algo),
+                                        8*gcry_md_get_algo_dlen (hash_algo));
+    }
+  else if (pk->pubkey_algo == PUBKEY_ALGO_DSA
+           || pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
     {
-      /* It's a DSA signature, so find out the size of q. */
+      /* It's a DSA signature, so find out the size of q.  */
 
-      size_t qbytes = gcry_mpi_get_nbits (pk?pk->pkey[1]:sk->skey[1]);
+      size_t qbits = gcry_mpi_get_nbits (pk->pkey[1]);
 
-      /* Make sure it is a multiple of 8 bits. */
+      /* pkey[1] is Q for ECDSA, which is an uncompressed point,
+         i.e.  04 <x> <y>  */
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+        qbits = ecdsa_qbits_from_Q (qbits);
 
-      if(qbytes%8)
+      /* Make sure it is a multiple of 8 bits. */
+      if ((qbits%8))
        {
          log_error(_("DSA requires the hash length to be a"
                      " multiple of 8 bits\n"));
@@ -235,28 +293,38 @@ encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
         or something like that, which would look correct but allow
         trivial forgeries.  Yes, I know this rules out using MD5 with
         DSA. ;) */
-      if (qbytes < 160)
+      if (qbits < 160)
        {
-         log_error (_("DSA key %s uses an unsafe (%u bit) hash\n"),
-                     pk?keystr_from_pk(pk):keystr_from_sk(sk),
-                     (unsigned int)qbytes);
+         log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"),
+                     openpgp_pk_algo_name (pk->pubkey_algo),
+                     keystr_from_pk (pk), qbits);
          return NULL;
        }
 
-      qbytes/=8;
+
+      /* ECDSA 521 is special has it is larger than the largest hash
+         we have (SHA-512).  Thus we chnage the size for further
+         processing to 512.  */
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && qbits > 512)
+        qbits = 512;
 
       /* Check if we're too short.  Too long is safe as we'll
-        automatically left-truncate. */
-      if (gcry_md_get_algo_dlen (hash_algo) < qbytes)
+        automatically left-truncate.  */
+      mdlen = gcry_md_get_algo_dlen (hash_algo);
+      if (mdlen < qbits/8)
        {
-         log_error (_("DSA key %s requires a %u bit or larger hash\n"),
-                     pk?keystr_from_pk(pk):keystr_from_sk(sk),
-                     (unsigned int)(qbytes*8));
+         log_error (_("%s key %s requires a %zu bit or larger hash "
+                       "(hash is %s)\n"),
+                     openpgp_pk_algo_name (pk->pubkey_algo),
+                     keystr_from_pk (pk), qbits,
+                     gcry_md_algo_name (hash_algo));
          return NULL;
        }
 
+     /* Note that we do the truncation by passing QBITS/8 as length to
+        mpi_scan.  */
       if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG,
-                         gcry_md_read (md, hash_algo), qbytes, &qbytes))
+                         gcry_md_read (md, hash_algo), qbits/8, NULL))
         BUG();
     }
   else
@@ -269,12 +337,13 @@ encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
       if (rc)
         log_fatal ("can't get OID of digest algorithm %d: %s\n",
                    hash_algo, gpg_strerror (rc));
-      asn = xmalloc (asnlen);
+      asn = xtrymalloc (asnlen);
+      if (!asn)
+        return NULL;
       if ( gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, asn, &asnlen) )
         BUG();
       frame = do_encode_md (md, hash_algo, gcry_md_get_algo_dlen (hash_algo),
-                            gcry_mpi_get_nbits (pk?pk->pkey[0]:sk->skey[0]),
-                            asn, asnlen);
+                            gcry_mpi_get_nbits (pk->pkey[0]), asn, asnlen);
       xfree (asn);
     }
 
index 7178d06..f563862 100644 (file)
@@ -28,7 +28,6 @@
 #include "util.h"
 #include "packet.h"
 #include "keydb.h"
-#include "cipher.h"
 #include "main.h"
 #include "status.h"
 #include "i18n.h"
@@ -82,9 +81,9 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
       }
     else if( get_pubkey( pk, sig->keyid ) )
        rc = G10ERR_NO_PUBKEY;
-    else if(!pk->is_valid)
+    else if(!pk->flags.valid && !pk->flags.primary)
         rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
-                                invalid key */
+                                invalid subkey */
     else
       {
         if(r_expiredate)
@@ -98,21 +97,21 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
           them as their own.  The attacker couldn't actually use the
           subkey, but they could try and claim ownership of any
           signaures issued by it. */
-       if(rc==0 && !pk->is_primary && pk->backsig<2)
+       if(rc==0 && !pk->flags.primary && pk->flags.backsig < 2)
          {
-           if(pk->backsig==0)
+           if (!pk->flags.backsig)
              {
                log_info(_("WARNING: signing subkey %s is not"
                           " cross-certified\n"),keystr_from_pk(pk));
                log_info(_("please see %s for more information\n"),
-                        "https://gnupg.org/faq/subkey-cross-certify.html");
+                        "http://www.gnupg.org/faq/subkey-cross-certify.html");
                /* --require-cross-certification makes this warning an
                      error.  TODO: change the default to require this
                      after more keys have backsigs. */
                if(opt.flags.require_cross_cert)
                  rc=G10ERR_GENERAL;
              }
-           else if(pk->backsig==1)
+           else if(pk->flags.backsig == 1)
              {
                log_info(_("WARNING: signing subkey %s has an invalid"
                           " cross-certification\n"),keystr_from_pk(pk));
@@ -236,20 +235,18 @@ do_check_messages( PKT_public_key *pk, PKT_signature *sig,
     if( pk->has_expired || (pk->expiredate && pk->expiredate < cur_time)) {
         char buf[11];
         if (opt.verbose)
-         log_info(_("NOTE: signature key %s expired %s\n"),
+         log_info(_("Note: signature key %s expired %s\n"),
                   keystr_from_pk(pk), asctimestamp( pk->expiredate ) );
-       /* SIGEXPIRED is deprecated.  Use KEYEXPIRED. */
-       snprintf (buf, sizeof buf,"%lu",(ulong)pk->expiredate);
+       sprintf(buf,"%lu",(ulong)pk->expiredate);
        write_status_text(STATUS_KEYEXPIRED,buf);
-       write_status(STATUS_SIGEXPIRED);
        if(r_expired)
          *r_expired = 1;
     }
 
-    if (pk->is_revoked)
+    if (pk->flags.revoked)
       {
         if (opt.verbose)
-         log_info (_("NOTE: signature key %s has been revoked\n"),
+         log_info (_("Note: signature key %s has been revoked\n"),
                     keystr_from_pk(pk));
         if (r_revoked)
           *r_revoked=1;
@@ -321,7 +318,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest,
     }
     gcry_md_final( digest );
 
-    result = encode_md_value( pk, NULL, digest, sig->digest_algo );
+    result = encode_md_value (pk, digest, sig->digest_algo );
     if (!result)
         return G10ERR_GENERAL;
     rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey );
@@ -416,13 +413,12 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
   assert(IS_KEY_REV(sig));
   assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
 
-  if(busy)
+  if (busy)
     {
-      /* return an error (i.e. not revoked), but mark the pk as
+      /* Return an error (i.e. not revoked), but mark the pk as
          uncacheable as we don't really know its revocation status
-         until it is checked directly. */
-
-      pk->dont_cache=1;
+         until it is checked directly.  */
+      pk->flags.dont_cache = 1;
       return rc;
     }
 
@@ -540,11 +536,9 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
     /* Check whether we have cached the result of a previous signature
        check.  Note that we may no longer have the pubkey or hash
        needed to verify a sig, but can still use the cached value.  A
-       cache refresh detects and clears these cases.
-       For safety reasons we ignore cache entries from MD5 signatures.  */
+       cache refresh detects and clears these cases. */
     if ( !opt.no_sig_cache ) {
-        if (sig->flags.checked && sig->digest_algo != DIGEST_ALGO_MD5) {
-            /*cached status available*/
+        if (sig->flags.checked) { /*cached status available*/
            if( is_selfsig ) {
                u32 keyid[2];
 
index 58bc981..e7d4a68 100644 (file)
@@ -57,8 +57,8 @@ static int recipient_digest_algo=0;
  * a valid NAME=VALUE format.
  */
 static void
-mk_notation_policy_etcPKT_signature *sig,
-                       PKT_public_key *pk, PKT_secret_key *sk )
+mk_notation_policy_etc (PKT_signature *sig,
+                       PKT_public_key *pk, PKT_public_key *pksk)
 {
     const char *string;
     char *s=NULL;
@@ -70,7 +70,7 @@ mk_notation_policy_etc( PKT_signature *sig,
 
     memset(&args,0,sizeof(args));
     args.pk=pk;
-    args.sk=sk;
+    args.pksk=pksk;
 
     /* notation data */
     if(IS_SIG(sig) && opt.sig_notations)
@@ -155,30 +155,32 @@ mk_notation_policy_etc( PKT_signature *sig,
 static void
 hash_uid (gcry_md_hd_t md, int sigversion, const PKT_user_id *uid)
 {
-    if ( sigversion >= 4 ) {
-        byte buf[5];
-
-       if(uid->attrib_data) {
-         buf[0] = 0xd1;                   /* indicates an attribute packet */
-         buf[1] = uid->attrib_len >> 24;  /* always use 4 length bytes */
-         buf[2] = uid->attrib_len >> 16;
-         buf[3] = uid->attrib_len >>  8;
-         buf[4] = uid->attrib_len;
-       }
-       else {
-         buf[0] = 0xb4;            /* indicates a userid packet */
-         buf[1] = uid->len >> 24;  /* always use 4 length bytes */
-         buf[2] = uid->len >> 16;
-         buf[3] = uid->len >>  8;
-         buf[4] = uid->len;
-       }
-        gcry_md_write( md, buf, 5 );
+  byte buf[5];
+
+  (void)sigversion;
+
+  if (uid->attrib_data)
+    {
+      buf[0] = 0xd1;                  /* Indicates an attribute packet.  */
+      buf[1] = uid->attrib_len >> 24;  /* Always use 4 length bytes.  */
+      buf[2] = uid->attrib_len >> 16;
+      buf[3] = uid->attrib_len >>  8;
+      buf[4] = uid->attrib_len;
     }
+  else
+    {
+      buf[0] = 0xb4;                  /* Indicates a userid packet.  */
+      buf[1] = uid->len >> 24;         /* Always use 4 length bytes.  */
+      buf[2] = uid->len >> 16;
+      buf[3] = uid->len >>  8;
+      buf[4] = uid->len;
+    }
+  gcry_md_write( md, buf, 5 );
 
-    if(uid->attrib_data)
-      gcry_md_write (md, uid->attrib_data, uid->attrib_len );
-    else
-      gcry_md_write (md, uid->name, uid->len );
+  if (uid->attrib_data)
+    gcry_md_write (md, uid->attrib_data, uid->attrib_len );
+  else
+    gcry_md_write (md, uid->name, uid->len );
 }
 
 
@@ -188,161 +190,201 @@ hash_uid (gcry_md_hd_t md, int sigversion, const PKT_user_id *uid)
 static void
 hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
 {
-    if (sig->version >= 4)
-        gcry_md_putc (md, sig->version);
-    gcry_md_putc (md, sig->sig_class);
-    if (sig->version < 4) {
-        u32 a = sig->timestamp;
-        gcry_md_putc (md, (a >> 24) & 0xff );
-        gcry_md_putc (md, (a >> 16) & 0xff );
-        gcry_md_putc (md, (a >>  8) & 0xff );
-        gcry_md_putc (md,  a          & 0xff );
+  byte buf[6];
+  size_t n;
+
+  gcry_md_putc (md, sig->version);
+  gcry_md_putc (md, sig->sig_class);
+  gcry_md_putc (md, sig->pubkey_algo);
+  gcry_md_putc (md, sig->digest_algo);
+  if (sig->hashed)
+    {
+      n = sig->hashed->len;
+      gcry_md_putc (md, (n >> 8) );
+      gcry_md_putc (md,  n       );
+      gcry_md_write (md, sig->hashed->data, n );
+      n += 6;
     }
-    else {
-        byte buf[6];
-        size_t n;
-
-        gcry_md_putc (md, sig->pubkey_algo);
-        gcry_md_putc (md, sig->digest_algo);
-        if (sig->hashed) {
-            n = sig->hashed->len;
-            gcry_md_putc (md, (n >> 8) );
-            gcry_md_putc (md,  n       );
-            gcry_md_write (md, sig->hashed->data, n );
-            n += 6;
-        }
-        else {
-            gcry_md_putc (md, 0);  /* always hash the length of the subpacket*/
-            gcry_md_putc (md, 0);
-            n = 6;
-        }
-        /* add some magic */
-        buf[0] = sig->version;
-        buf[1] = 0xff;
-        buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
-        buf[3] = n >> 16;
-        buf[4] = n >>  8;
-        buf[5] = n;
-        gcry_md_write (md, buf, 6);
+  else
+    {
+      gcry_md_putc (md, 0);  /* Always hash the length of the subpacket.  */
+      gcry_md_putc (md, 0);
+      n = 6;
     }
+  /* Add some magic.  */
+  buf[0] = sig->version;
+  buf[1] = 0xff;
+  buf[2] = n >> 24;         /* (n is only 16 bit, so this is always 0) */
+  buf[3] = n >> 16;
+  buf[4] = n >>  8;
+  buf[5] = n;
+  gcry_md_write (md, buf, 6);
 }
 
 
+/* Perform the sign operation.  If CACHE_NONCE is given the agent is
+   advised to use that cached passphrase fro the key.  */
 static int
-do_sign( PKT_secret_key *sk, PKT_signature *sig,
-        gcry_md_hd_t md, int digest_algo )
+do_sign (PKT_public_key *pksk, PKT_signature *sig,
+        gcry_md_hd_t md, int mdalgo, const char *cache_nonce)
 {
-    gcry_mpi_t frame;
-    byte *dp;
-    int rc;
-
-    if( sk->timestamp > sig->timestamp ) {
-       ulong d = sk->timestamp - sig->timestamp;
-       log_info( d==1 ? _("key has been created %lu second "
-                          "in future (time warp or clock problem)\n")
-                      : _("key has been created %lu seconds "
-                          "in future (time warp or clock problem)\n"), d );
-       if( !opt.ignore_time_conflict )
-           return G10ERR_TIME_CONFLICT;
+  gpg_error_t err;
+  gcry_mpi_t frame;
+  byte *dp;
+  char *hexgrip;
+
+  if (pksk->timestamp > sig->timestamp )
+    {
+      ulong d = pksk->timestamp - sig->timestamp;
+      log_info (d==1 ? _("key has been created %lu second "
+                         "in future (time warp or clock problem)\n")
+                : _("key has been created %lu seconds "
+                    "in future (time warp or clock problem)\n"), d );
+      if (!opt.ignore_time_conflict)
+        return gpg_error (GPG_ERR_TIME_CONFLICT);
     }
 
 
-    print_pubkey_algo_note(sk->pubkey_algo);
+  print_pubkey_algo_note (pksk->pubkey_algo);
 
-    if( !digest_algo )
-       digest_algo = gcry_md_get_algo (md);
+  if (!mdalgo)
+    mdalgo = gcry_md_get_algo (md);
 
-    print_digest_algo_note( digest_algo );
-    dp = gcry_md_read ( md, digest_algo );
-    sig->digest_algo = digest_algo;
-    sig->digest_start[0] = dp[0];
-    sig->digest_start[1] = dp[1];
-    if (sk->is_protected && sk->protect.s2k.mode == 1002)
-      {
-#ifdef ENABLE_CARD_SUPPORT
-        unsigned char *rbuf;
-        size_t rbuflen;
-        char *snbuf;
-
-        snbuf = serialno_and_fpr_from_sk (sk->protect.iv,
-                                          sk->protect.ivlen, sk);
-        rc = agent_scd_pksign (snbuf, digest_algo,
-                               gcry_md_read (md, digest_algo),
-                               gcry_md_get_algo_dlen (digest_algo),
-                               &rbuf, &rbuflen);
-        xfree (snbuf);
-        if (!rc)
-          {
-            if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG,
-                               rbuf, rbuflen, NULL))
-              BUG ();
-            xfree (rbuf);
-          }
-#else
-        return gpg_error (GPG_ERR_NOT_SUPPORTED);
-#endif /* ENABLE_CARD_SUPPORT */
-      }
-    else
-      {
-        frame = encode_md_value( NULL, sk, md, digest_algo );
-        if (!frame)
-          return G10ERR_GENERAL;
-        rc = pk_sign( sk->pubkey_algo, sig->data, frame, sk->skey );
-        gcry_mpi_release (frame);
-      }
+  print_digest_algo_note (mdalgo);
+  dp = gcry_md_read  (md, mdalgo);
+  sig->digest_algo = mdalgo;
+  sig->digest_start[0] = dp[0];
+  sig->digest_start[1] = dp[1];
+  sig->data[0] = NULL;
+  sig->data[1] = NULL;
 
-    if (!rc
-#if GCRYPT_VERSION_NUMBER >= 0x010700 /* Libgcrypt >= 1.7 */
-        && is_DSA (sk->pubkey_algo)
-#endif /* Libgcrypt >= 1.7 */
-        )
-      {
-        /* Check that the signature verification worked and nothing is
-         * fooling us e.g. by a bug in the signature creation code or by
-         * deliberately introduced faults.  Libgcrypt 1.7 includes
-         * this check for RSA and thus we don't need it in that case.  */
-        PKT_public_key *pk = xmalloc_clear (sizeof *pk);
-
-        if( get_pubkey( pk, sig->keyid ) )
-            rc = G10ERR_NO_PUBKEY;
-        else {
-           frame = encode_md_value (pk, NULL, md, sig->digest_algo );
-            if (!frame)
-              rc = G10ERR_GENERAL;
-            else
-              rc = pk_verify (pk->pubkey_algo, frame, sig->data, pk->pkey );
-            gcry_mpi_release (frame);
+
+  err = hexkeygrip_from_pk (pksk, &hexgrip);
+  if (!err)
+    {
+      char *desc;
+      gcry_sexp_t s_sigval;
+
+      desc = gpg_format_keydesc (pksk, FORMAT_KEYDESC_NORMAL, 1);
+      err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc,
+                          pksk->keyid, pksk->main_keyid, pksk->pubkey_algo,
+                          dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
+                          &s_sigval);
+      xfree (desc);
+
+      if (err)
+        ;
+      else if (pksk->pubkey_algo == GCRY_PK_RSA
+               || pksk->pubkey_algo == GCRY_PK_RSA_S)
+        sig->data[0] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_USG);
+      else if (openpgp_oid_is_ed25519 (pksk->pkey[0]))
+        {
+          sig->data[0] = get_mpi_from_sexp (s_sigval, "r", GCRYMPI_FMT_OPAQUE);
+          sig->data[1] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_OPAQUE);
         }
-        if (rc)
-            log_error (_("checking created signature failed: %s\n"),
-                         g10_errstr (rc));
-        free_public_key (pk);
+      else
+        {
+          sig->data[0] = get_mpi_from_sexp (s_sigval, "r", GCRYMPI_FMT_USG);
+          sig->data[1] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_USG);
+        }
+
+      gcry_sexp_release (s_sigval);
     }
+  xfree (hexgrip);
 
-    if( rc )
-       log_error(_("signing failed: %s\n"), g10_errstr(rc) );
-    else {
-       if( opt.verbose ) {
-           char *ustr = get_user_id_string_native (sig->keyid);
-           log_info(_("%s/%s signature from: \"%s\"\n"),
-                    openpgp_pk_algo_name (sk->pubkey_algo),
-                    gcry_md_algo_name (sig->digest_algo),
-                    ustr );
-           xfree(ustr);
+  /* Check that the signature verification worked and nothing is
+   * fooling us e.g. by a bug in the signature create code or by
+   * deliberately introduced faults.  */
+  if (!err && !opt.no_sig_create_check)
+    {
+      PKT_public_key *pk = xmalloc_clear (sizeof *pk);
+
+      if (get_pubkey (pk, sig->keyid ))
+        err = gpg_error (GPG_ERR_NO_PUBKEY);
+      else
+        {
+          frame = encode_md_value (pk, md, sig->digest_algo );
+          if (!frame)
+            err = gpg_error (GPG_ERR_GENERAL);
+          else
+            err = pk_verify (pk->pubkey_algo, frame, sig->data, pk->pkey);
+          gcry_mpi_release (frame);
+        }
+      if (err)
+        log_error (_("checking created signature failed: %s\n"),
+                   g10_errstr (err));
+      free_public_key (pk);
+    }
+
+  if (err)
+    log_error (_("signing failed: %s\n"), g10_errstr (err));
+  else
+    {
+      if (opt.verbose)
+        {
+          char *ustr = get_user_id_string_native (sig->keyid);
+          log_info (_("%s/%s signature from: \"%s\"\n"),
+                    openpgp_pk_algo_name (pksk->pubkey_algo),
+                    openpgp_md_algo_name (sig->digest_algo),
+                    ustr);
+          xfree (ustr);
        }
     }
-    return rc;
+  return err;
 }
 
 
 int
-complete_sig( PKT_signature *sig, PKT_secret_key *sk, gcry_md_hd_t md )
+complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
+              const char *cache_nonce)
 {
-    int rc=0;
+  int rc;
 
-    if( !(rc=check_secret_key( sk, 0 )) )
-       rc = do_sign( sk, sig, md, 0 );
-    return rc;
+  /* if (!(rc = check_secret_key (pksk, 0))) */
+  rc = do_sign (pksk, sig, md, 0, cache_nonce);
+  return rc;
+}
+
+
+/* Return true if the key seems to be on a version 1 OpenPGP card.
+   This works by asking the agent and may fail if the card has not yet
+   been used with the agent.  */
+static int
+openpgp_card_v1_p (PKT_public_key *pk)
+{
+  gpg_error_t err;
+  int result;
+
+  /* Shortcut if we are not using RSA: The v1 cards only support RSA
+     thus there is no point in looking any further.  */
+  if (!is_RSA (pk->pubkey_algo))
+    return 0;
+
+  if (!pk->flags.serialno_valid)
+    {
+      char *hexgrip;
+
+      err = hexkeygrip_from_pk (pk, &hexgrip);
+      if (err)
+        {
+          log_error ("error computing a keygrip: %s\n", gpg_strerror (err));
+          return 0; /* Ooops.  */
+        }
+
+      xfree (pk->serialno);
+      agent_get_keyinfo (NULL, hexgrip, &pk->serialno);
+      xfree (hexgrip);
+      pk->flags.serialno_valid = 1;
+    }
+
+  if (!pk->serialno)
+    result = 0; /* Error from a past agent_get_keyinfo or no card.  */
+  else
+    {
+      /* The version number of the card is included in the serialno.  */
+      result = !strncmp (pk->serialno, "D2760001240101", 14);
+    }
+  return result;
 }
 
 
@@ -362,7 +404,7 @@ match_dsa_hash (unsigned int qbytes)
   if (qbytes <= 48)
     return DIGEST_ALGO_SHA384;
 
-  if (qbytes <= 64)
+  if (qbytes <= 66 )   /* 66 corresponds to 521 (64 to 512) */
     return DIGEST_ALGO_SHA512;
 
   return DEFAULT_DIGEST_ALGO;
@@ -380,20 +422,41 @@ match_dsa_hash (unsigned int qbytes)
   usable for the pubkey algorithm.  If --personal-digest-prefs isn't
   set, then take the OpenPGP default (i.e. SHA-1).
 
+  Note that Ed25519+EdDSA takes an input of arbitrary length and thus
+  we don't enforce any particular algorithm like we do for standard
+  ECDSA. However, we use SHA256 as the default algorithm.
+
   Possible improvement: Use the highest-ranked usable algorithm from
   the signing key prefs either before or after using the personal
   list?
 */
 static int
-hash_for(PKT_secret_key *sk)
+hash_for (PKT_public_key *pk)
 {
-  if( opt.def_digest_algo )
-    return opt.def_digest_algo;
-  else if( recipient_digest_algo )
-    return recipient_digest_algo;
-  else if(sk->pubkey_algo==PUBKEY_ALGO_DSA)
+  if (opt.def_digest_algo)
+    {
+      return opt.def_digest_algo;
+    }
+  else if (recipient_digest_algo)
+    {
+      return recipient_digest_algo;
+    }
+  else if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA
+           && openpgp_oid_is_ed25519 (pk->pkey[0]))
     {
-      unsigned int qbytes = gcry_mpi_get_nbits (sk->skey[1]) / 8;
+      if (opt.personal_digest_prefs)
+        return opt.personal_digest_prefs[0].value;
+      else
+        return DIGEST_ALGO_SHA256;
+    }
+  else if (pk->pubkey_algo == PUBKEY_ALGO_DSA
+           || pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+    {
+      unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]);
+
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+        qbytes = ecdsa_qbits_from_Q (qbytes);
+      qbytes = qbytes/8;
 
       /* It's a DSA key, so find a hash that is the same size as q or
         larger.  If q is 160, assume it is an old DSA key and use a
@@ -422,9 +485,7 @@ hash_for(PKT_secret_key *sk)
 
       return match_dsa_hash(qbytes);
     }
-  else if (sk->is_protected && sk->protect.s2k.mode == 1002
-           && sk->protect.ivlen == 16
-           && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01\x01", 7))
+  else if (openpgp_card_v1_p (pk))
     {
       /* The sk lives on a smartcard, and old smartcards only handle
         SHA-1 and RIPEMD/160.  Newer smartcards (v2.0) don't have
@@ -443,12 +504,7 @@ hash_for(PKT_secret_key *sk)
 
       return DIGEST_ALGO_SHA1;
     }
-  else if (PGP2 && sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
-    {
-      /* Old-style PGP only understands MD5 */
-      return DIGEST_ALGO_MD5;
-    }
-  else if ( opt.personal_digest_prefs )
+  else if (opt.personal_digest_prefs)
     {
       /* It's not DSA, so we can use whatever the first hash algorithm
         is in the pref list */
@@ -459,42 +515,20 @@ hash_for(PKT_secret_key *sk)
 }
 
 
-static int
-only_old_style( SK_LIST sk_list )
-{
-    SK_LIST sk_rover = NULL;
-    int old_style = 0;
-
-    /* if there are only old style capable key we use the old sytle */
-    for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-       PKT_secret_key *sk = sk_rover->sk;
-       if( sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
-           old_style = 1;
-       else
-           return 0;
-    }
-    return old_style;
-}
-
-
-
 static void
-print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
+print_status_sig_created (PKT_public_key *pk, PKT_signature *sig, int what)
 {
-    byte array[MAX_FINGERPRINT_LEN], *p;
-    char buf[100+MAX_FINGERPRINT_LEN*2];
-    size_t i, n;
-
-    sprintf(buf, "%c %d %d %02x %lu ",
-           what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
-           (ulong)sig->timestamp );
+  byte array[MAX_FINGERPRINT_LEN];
+  char buf[100+MAX_FINGERPRINT_LEN*2];
+  size_t n;
 
-    fingerprint_from_sk( sk, array, &n );
-    p = buf + strlen(buf);
-    for(i=0; i < n ; i++ )
-       sprintf(p+2*i, "%02X", array[i] );
+  snprintf (buf, sizeof buf - 2*MAX_FINGERPRINT_LEN, "%c %d %d %02x %lu ",
+            what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
+            (ulong)sig->timestamp );
+  fingerprint_from_pk (pk, array, &n);
+  bin2hex (array, n, buf + strlen (buf));
 
-    write_status_text( STATUS_SIG_CREATED, buf );
+  write_status_text( STATUS_SIG_CREATED, buf );
 }
 
 
@@ -514,7 +548,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
         skcount++;
 
     for (; skcount; skcount--) {
-        PKT_secret_key *sk;
+        PKT_public_key *pk;
         PKT_onepass_sig *ops;
         PACKET pkt;
         int i, rc;
@@ -524,12 +558,12 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
                 break;
         }
 
-        sk = sk_rover->sk;
+        pk = sk_rover->pk;
         ops = xmalloc_clear (sizeof *ops);
         ops->sig_class = sigclass;
-        ops->digest_algo = hash_for (sk);
-        ops->pubkey_algo = sk->pubkey_algo;
-        keyid_from_sk (sk, ops->keyid);
+        ops->digest_algo = hash_for (pk);
+        ops->pubkey_algo = pk->pubkey_algo;
+        keyid_from_pk (pk, ops->keyid);
         ops->last = (skcount == 1);
 
         init_packet(&pkt);
@@ -568,7 +602,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
 
         if( !(tmpsize = iobuf_get_filelength(inp, &overflow))
             && !overflow && opt.verbose)
-         log_info (_("WARNING: `%s' is an empty file\n"), fname);
+         log_info (_("WARNING: '%s' is an empty file\n"), fname);
 
         /* We can't encode the length of very large files because
            OpenPGP uses only 32 bit for file sizes.  So if the size of
@@ -595,7 +629,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
         pt->timestamp = make_timestamp ();
         pt->mode = ptmode;
         pt->len = filesize;
-        pt->new_ctb = !pt->len && !RFC1991;
+        pt->new_ctb = !pt->len;
         pt->buf = inp;
         init_packet(&pkt);
         pkt.pkttype = PKT_PLAINTEXT;
@@ -630,75 +664,73 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
 static int
 write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
                          int sigclass, u32 timestamp, u32 duration,
-                        int status_letter)
+                        int status_letter, const char *cache_nonce)
 {
-    SK_LIST sk_rover;
-
-    /* loop over the secret certificates */
-    for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
-       PKT_secret_key *sk;
-       PKT_signature *sig;
-       gcry_md_hd_t md;
-        int rc;
-
-       sk = sk_rover->sk;
-
-       /* build the signature packet */
-       sig = xmalloc_clear (sizeof *sig);
-       if(opt.force_v3_sigs || RFC1991)
-         sig->version=3;
-       else if(duration || opt.sig_policy_url
-               || opt.sig_notations || opt.sig_keyserver_url)
-         sig->version=4;
-       else
-         sig->version=sk->version;
-       keyid_from_sk (sk, sig->keyid);
-       sig->digest_algo = hash_for(sk);
-       sig->pubkey_algo = sk->pubkey_algo;
-       if(timestamp)
-         sig->timestamp = timestamp;
-       else
-         sig->timestamp = make_timestamp();
-       if(duration)
-         sig->expiredate = sig->timestamp+duration;
-       sig->sig_class = sigclass;
-
-       if (gcry_md_copy (&md, hash))
-          BUG ();
-
-       if (sig->version >= 4)
-          {
-           build_sig_subpkt_from_sig (sig);
-            mk_notation_policy_etc (sig, NULL, sk);
-          }
+  SK_LIST sk_rover;
 
-        hash_sigversion_to_magic (md, sig);
-       gcry_md_final (md);
-
-       rc = do_sign( sk, sig, md, hash_for (sk) );
-       gcry_md_close (md);
-       if( !rc ) { /* and write it */
-            PACKET pkt;
-
-           init_packet(&pkt);
-           pkt.pkttype = PKT_SIGNATURE;
-           pkt.pkt.signature = sig;
-           rc = build_packet (out, &pkt);
-           if (!rc && is_status_enabled()) {
-               print_status_sig_created ( sk, sig, status_letter);
-           }
-           free_packet (&pkt);
-           if (rc)
-               log_error ("build signature packet failed: %s\n",
-                           g10_errstr(rc) );
+  /* Loop over the certificates with secret keys. */
+  for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
+    {
+      PKT_public_key *pk;
+      PKT_signature *sig;
+      gcry_md_hd_t md;
+      int rc;
+
+      pk = sk_rover->pk;
+
+      /* Build the signature packet.  */
+      sig = xmalloc_clear (sizeof *sig);
+      if (duration || opt.sig_policy_url
+          || opt.sig_notations || opt.sig_keyserver_url)
+        sig->version = 4;
+      else
+        sig->version = pk->version;
+
+      keyid_from_pk (pk, sig->keyid);
+      sig->digest_algo = hash_for (pk);
+      sig->pubkey_algo = pk->pubkey_algo;
+      if (timestamp)
+        sig->timestamp = timestamp;
+      else
+        sig->timestamp = make_timestamp();
+      if (duration)
+        sig->expiredate = sig->timestamp + duration;
+      sig->sig_class = sigclass;
+
+      if (gcry_md_copy (&md, hash))
+        BUG ();
+
+      build_sig_subpkt_from_sig (sig);
+      mk_notation_policy_etc (sig, pk, NULL);
+
+      hash_sigversion_to_magic (md, sig);
+      gcry_md_final (md);
+
+      rc = do_sign (pk, sig, md, hash_for (pk), cache_nonce);
+      gcry_md_close (md);
+      if (!rc)
+        {
+          /* Write the packet.  */
+          PACKET pkt;
+
+          init_packet (&pkt);
+          pkt.pkttype = PKT_SIGNATURE;
+          pkt.pkt.signature = sig;
+          rc = build_packet (out, &pkt);
+          if (!rc && is_status_enabled())
+            print_status_sig_created (pk, sig, status_letter);
+          free_packet (&pkt);
+          if (rc)
+            log_error ("build signature packet failed: %s\n", gpg_strerror (rc));
        }
-       if( rc )
-           return rc;;
+      if (rc)
+        return rc;
     }
 
-    return 0;
+  return 0;
 }
 
+
 /****************
  * Sign the files whose names are in FILENAME.
  * If DETACHED has the value true,
@@ -712,7 +744,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
  * uncompressed, non-armored and in binary mode.
  */
 int
-sign_file( strlist_t filenames, int detached, strlist_t locusr,
+sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
           int encryptflag, strlist_t remusr, const char *outfile )
 {
     const char *fname;
@@ -752,25 +784,18 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
        && (rc=setup_symkey(&efx.symkey_s2k,&efx.symkey_dek)))
       goto leave;
 
-    if(!opt.force_v3_sigs && !RFC1991)
-      {
-       if(opt.ask_sig_expire && !opt.batch)
-         duration=ask_expire_interval(1,opt.def_sig_expire);
-       else
-         duration=parse_expire_string(opt.def_sig_expire);
-      }
+    if (opt.ask_sig_expire && !opt.batch)
+      duration = ask_expire_interval(1,opt.def_sig_expire);
+    else
+      duration = parse_expire_string(opt.def_sig_expire);
 
-    if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) )
+    /* Note: In the old non-agent version the following call used to
+       unprotect the secret key.  This is now done on demand by the agent.  */
+    if( (rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_SIG )) )
        goto leave;
 
-    if(PGP2 && !only_old_style(sk_list))
-      {
-       log_info(_("you can only detach-sign with PGP 2.x style keys "
-                  "while in --pgp2 mode\n"));
-       compliance_failure();
-      }
-
-    if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )))
+    if (encryptflag
+        && (rc=build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
       goto leave;
 
     /* prepare iobufs */
@@ -782,12 +807,12 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
         {
           iobuf_close (inp);
           inp = NULL;
-          errno = EPERM;
+          gpg_err_set_errno (EPERM);
         }
       if( !inp )
         {
           rc = gpg_error_from_syserror ();
-          log_error (_("can't open `%s': %s\n"), fname? fname: "[stdin]",
+          log_error (_("can't open '%s': %s\n"), fname? fname: "[stdin]",
                      strerror(errno) );
           goto leave;
        }
@@ -798,20 +823,21 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
     if( outfile ) {
         if (is_secured_filename ( outfile )) {
             out = NULL;
-            errno = EPERM;
+            gpg_err_set_errno (EPERM);
         }
         else
-            out = iobuf_create( outfile );
+          out = iobuf_create (outfile, 0);
        if( !out )
          {
             rc = gpg_error_from_syserror ();
-           log_error(_("can't create `%s': %s\n"), outfile, strerror(errno) );
+           log_error(_("can't create '%s': %s\n"), outfile, strerror(errno) );
            goto leave;
          }
        else if( opt.verbose )
-           log_info(_("writing to `%s'\n"), outfile );
+           log_info(_("writing to '%s'\n"), outfile );
     }
-    else if( (rc = open_outfile( fname, opt.armor? 1: detached? 2:0, &out )))
+    else if( (rc = open_outfile (-1, fname,
+                                 opt.armor? 1: detached? 2:0, 0, &out)))
        goto leave;
 
     /* prepare to calculate the MD over the input */
@@ -827,7 +853,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
       gcry_md_debug (mfx.md, "sign");
 
     /* If we're encrypting and signing, it is reasonable to pick the
-       hash algorithm to use out of the recepient key prefs.  This is
+       hash algorithm to use out of the recipient key prefs.  This is
        best effort only, as in a DSA2 and smartcard world there are
        cases where we cannot please everyone with a single hash (DSA2
        wants >160 and smartcards want =160).  In the future this could
@@ -872,10 +898,16 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
 
            for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
              {
-               if (sk_rover->sk->pubkey_algo == PUBKEY_ALGO_DSA)
+               if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA
+                    || (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_EDDSA
+                        && !openpgp_oid_is_ed25519 (sk_rover->pk->pkey[1])))
                  {
                    int temp_hashlen = (gcry_mpi_get_nbits
-                      (sk_rover->sk->skey[1])+7)/8;
+                                        (sk_rover->pk->pkey[1]));
+
+                   if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
+                     temp_hashlen = ecdsa_qbits_from_Q (temp_hashlen);
+                   temp_hashlen = (temp_hashlen+7)/8;
 
                    /* Pick a hash that is large enough for our
                       largest q */
@@ -883,9 +915,10 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
                    if (hint.digest_length<temp_hashlen)
                      hint.digest_length=temp_hashlen;
                  }
-               else if (sk_rover->sk->is_protected
-                         && sk_rover->sk->protect.s2k.mode == 1002)
-                 smartcard = 1;
+                /* FIXME: need toall gpg-agent */
+               /* else if (sk_rover->pk->is_protected */
+                /*          && sk_rover->pk->protect.s2k.mode == 1002) */
+               /*   smartcard = 1;  */
              }
 
            /* Current smartcards only do 160-bit hashes.  If we have
@@ -902,15 +935,13 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
          }
       }
 
-    for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-       PKT_secret_key *sk = sk_rover->sk;
-       gcry_md_enable (mfx.md, hash_for(sk));
-    }
+    for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
+      gcry_md_enable (mfx.md, hash_for (sk_rover->pk));
 
     if( !multifile )
        iobuf_push_filter( inp, md_filter, &mfx );
 
-    if( detached && !encryptflag && !RFC1991 )
+    if( detached && !encryptflag)
        afx->what = 2;
 
     if( opt.armor && !outfile  )
@@ -922,7 +953,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
        iobuf_push_filter( out, encrypt_filter, &efx );
     }
 
-    if( opt.compress_algo && !outfile && ( !detached || opt.compress_sigs) )
+    if (opt.compress_algo && !outfile && !detached)
       {
         int compr_algo=opt.compress_algo;
 
@@ -953,7 +984,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
       }
 
     /* Write the one-pass signature packets if needed */
-    if (!detached && !RFC1991) {
+    if (!detached) {
         rc = write_onepass_sig_packets (sk_list, out,
                                         opt.textmode && !outfile ? 0x01:0x00);
         if (rc)
@@ -977,18 +1008,18 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
                   {
                     iobuf_close (inp);
                     inp = NULL;
-                    errno = EPERM;
+                    gpg_err_set_errno (EPERM);
                   }
                if( !inp )
                  {
                     rc = gpg_error_from_syserror ();
-                   log_error(_("can't open `%s': %s\n"),
+                   log_error(_("can't open '%s': %s\n"),
                              sl->d,strerror(errno));
                    goto leave;
                  }
                 handle_progress (pfx, inp, sl->d);
                if( opt.verbose )
-                   fprintf(stderr, " `%s'", sl->d );
+                   fprintf(stderr, " '%s'", sl->d );
                if(opt.textmode)
                  {
                    memset( &tfx, 0, sizeof tfx);
@@ -1020,7 +1051,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
     /* write the signatures */
     rc = write_signature_packets (sk_list, out, mfx.md,
                                   opt.textmode && !outfile? 0x01 : 0x00,
-                                 0, duration, detached ? 'D':'S');
+                                 0, duration, detached ? 'D':'S', NULL);
     if( rc )
         goto leave;
 
@@ -1059,46 +1090,33 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
     int rc = 0;
     SK_LIST sk_list = NULL;
     SK_LIST sk_rover = NULL;
-    int old_style = RFC1991;
-    int only_md5 = 0;
     u32 duration=0;
 
     pfx = new_progress_context ();
     afx = new_armor_context ();
     init_packet( &pkt );
 
-    if(!opt.force_v3_sigs && !RFC1991)
-      {
-       if(opt.ask_sig_expire && !opt.batch)
-         duration=ask_expire_interval(1,opt.def_sig_expire);
-       else
-         duration=parse_expire_string(opt.def_sig_expire);
-      }
+    if (opt.ask_sig_expire && !opt.batch)
+      duration = ask_expire_interval (1,opt.def_sig_expire);
+    else
+      duration = parse_expire_string (opt.def_sig_expire);
 
-    if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) )
+    /* Note: In the old non-agent version the following call used to
+       unprotect the secret key.  This is now done on demand by the agent.  */
+    if( (rc=build_sk_list( locusr, &sk_list, PUBKEY_USAGE_SIG )) )
        goto leave;
 
-    if( !old_style && !duration )
-       old_style = only_old_style( sk_list );
-
-    if(PGP2 && !only_old_style(sk_list))
-      {
-       log_info(_("you can only clearsign with PGP 2.x style keys "
-                  "while in --pgp2 mode\n"));
-       compliance_failure();
-      }
-
     /* prepare iobufs */
     inp = iobuf_open(fname);
     if (inp && is_secured_file (iobuf_get_fd (inp)))
       {
         iobuf_close (inp);
         inp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if( !inp ) {
         rc = gpg_error_from_syserror ();
-       log_error (_("can't open `%s': %s\n"),
+       log_error (_("can't open '%s': %s\n"),
                    fname? fname: "[stdin]", strerror(errno) );
        goto leave;
     }
@@ -1107,35 +1125,25 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
     if( outfile ) {
         if (is_secured_filename (outfile) ) {
             outfile = NULL;
-            errno = EPERM;
+            gpg_err_set_errno (EPERM);
         }
         else
-            out = iobuf_create( outfile );
+          out = iobuf_create (outfile, 0);
        if( !out )
          {
             rc = gpg_error_from_syserror ();
-           log_error(_("can't create `%s': %s\n"), outfile, strerror(errno) );
+           log_error(_("can't create '%s': %s\n"), outfile, strerror(errno) );
            goto leave;
          }
        else if( opt.verbose )
-           log_info(_("writing to `%s'\n"), outfile );
+           log_info(_("writing to '%s'\n"), outfile );
     }
-    else if( (rc = open_outfile( fname, 1, &out )) )
+    else if ((rc = open_outfile (-1, fname, 1, 0, &out)))
        goto leave;
 
     iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
 
-    for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-       PKT_secret_key *sk = sk_rover->sk;
-       if( hash_for(sk) == DIGEST_ALGO_MD5 )
-           only_md5 = 1;
-       else {
-           only_md5 = 0;
-           break;
-       }
-    }
-
-    if( !(old_style && only_md5) ) {
+    {
        const char *s;
        int any = 0;
        byte hashs_seen[256];
@@ -1143,8 +1151,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
        memset( hashs_seen, 0, sizeof hashs_seen );
        iobuf_writestr(out, "Hash: " );
        for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-           PKT_secret_key *sk = sk_rover->sk;
-           int i = hash_for(sk);
+           int i = hash_for (sk_rover->pk);
 
            if( !hashs_seen[ i & 0xff ] ) {
                s = gcry_md_algo_name ( i );
@@ -1163,28 +1170,29 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
 
     if( opt.not_dash_escaped )
       iobuf_writestr( out,
-                 "NotDashEscaped: You need GnuPG to verify this message" LF );
+                      "NotDashEscaped: You need "GPG_NAME
+                      " to verify this message" LF );
     iobuf_writestr(out, LF );
 
     if ( gcry_md_open (&textmd, 0, 0) )
       BUG ();
-    for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-       PKT_secret_key *sk = sk_rover->sk;
-       gcry_md_enable (textmd, hash_for(sk));
-    }
+    for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
+      gcry_md_enable (textmd, hash_for(sk_rover->pk));
+
     if ( DBG_HASHING )
       gcry_md_debug ( textmd, "clearsign" );
 
-    copy_clearsig_textout, inp, textmd, !opt.not_dash_escaped,
-                       opt.escape_from, (old_style && only_md5) );
+    copy_clearsig_text (out, inp, textmd, !opt.not_dash_escaped,
+                        opt.escape_from);
     /* fixme: check for read errors */
 
     /* now write the armor */
     afx->what = 2;
     push_armor_filter (afx, out);
 
-    /* write the signatures */
-    rc=write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C');
+    /* Write the signatures.  */
+    rc = write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C',
+                                  NULL);
     if( rc )
         goto leave;
 
@@ -1232,15 +1240,14 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
     memset( &cfx, 0, sizeof cfx);
     init_packet( &pkt );
 
-    if(!opt.force_v3_sigs && !RFC1991)
-      {
-       if(opt.ask_sig_expire && !opt.batch)
-         duration=ask_expire_interval(1,opt.def_sig_expire);
-       else
-         duration=parse_expire_string(opt.def_sig_expire);
-      }
+    if (opt.ask_sig_expire && !opt.batch)
+      duration = ask_expire_interval (1, opt.def_sig_expire);
+    else
+      duration = parse_expire_string (opt.def_sig_expire);
 
-    rc = build_sk_list (locusr, &sk_list, 1, PUBKEY_USAGE_SIG);
+    /* Note: In the old non-agent version the following call used to
+       unprotect the secret key.  This is now done on demand by the agent.  */
+    rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_SIG);
     if (rc)
        goto leave;
 
@@ -1250,11 +1257,11 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
       {
         iobuf_close (inp);
         inp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if( !inp ) {
         rc = gpg_error_from_syserror ();
-       log_error (_("can't open `%s': %s\n"),
+       log_error (_("can't open '%s': %s\n"),
                    fname? fname: "[stdin]", strerror(errno) );
        goto leave;
     }
@@ -1262,7 +1269,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
 
     /* prepare key */
     s2k = xmalloc_clear( sizeof *s2k );
-    s2k->mode = RFC1991? 0:opt.s2k_mode;
+    s2k->mode = opt.s2k_mode;
     s2k->hash_algo = S2K_DIGEST_ALGO;
 
     algo = default_cipher_algo();
@@ -1285,7 +1292,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
       cfx.dek->use_mdc=1;
 
     /* now create the outfile */
-    rc = open_outfile (fname, opt.armor? 1:0, &out);
+    rc = open_outfile (-1, fname, opt.armor? 1:0, 0, &out);
     if (rc)
        goto leave;
 
@@ -1297,10 +1304,8 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
     if ( DBG_HASHING )
       gcry_md_debug (mfx.md, "symc-sign");
 
-    for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
-       PKT_secret_key *sk = sk_rover->sk;
-       gcry_md_enable (mfx.md, hash_for (sk));
-    }
+    for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
+      gcry_md_enable (mfx.md, hash_for (sk_rover->pk));
 
     iobuf_push_filter (inp, md_filter, &mfx);
 
@@ -1310,7 +1315,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
 
     /* Write the symmetric key packet */
     /*(current filters: armor)*/
-    if (!RFC1991) {
+    {
        PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc );
        enc->version = 4;
        enc->cipher_algo = cfx.dek->algo;
@@ -1331,12 +1336,10 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
 
     /* Write the one-pass signature packets */
     /*(current filters: zip - encrypt - armor)*/
-    if (!RFC1991) {
-        rc = write_onepass_sig_packets (sk_list, out,
-                                        opt.textmode? 0x01:0x00);
-        if (rc)
-            goto leave;
-    }
+    rc = write_onepass_sig_packets (sk_list, out,
+                                    opt.textmode? 0x01:0x00);
+    if (rc)
+      goto leave;
 
     write_status_begin_signing (mfx.md);
 
@@ -1350,7 +1353,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
     /*(current filters: zip - encrypt - armor)*/
     rc = write_signature_packets (sk_list, out, mfx.md,
                                  opt.textmode? 0x01 : 0x00,
-                                 0, duration, 'S');
+                                 0, duration, 'S', NULL);
     if( rc )
         goto leave;
 
@@ -1383,54 +1386,50 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
  * applied (actually: dropped) when a v3 key is used.  TIMESTAMP is
  * the timestamp to use for the signature. 0 means "now" */
 int
-make_keysig_packetPKT_signature **ret_sig, PKT_public_key *pk,
+make_keysig_packet (PKT_signature **ret_sig, PKT_public_key *pk,
                    PKT_user_id *uid, PKT_public_key *subpk,
-                   PKT_secret_key *sk,
+                   PKT_public_key *pksk,
                    int sigclass, int digest_algo,
-                    int sigversion, u32 timestamp, u32 duration,
-                   int (*mksubpkt)(PKT_signature *, void *), void *opaque
-                  )
+                    u32 timestamp, u32 duration,
+                   int (*mksubpkt)(PKT_signature *, void *), void *opaque,
+                    const char *cache_nonce)
 {
     PKT_signature *sig;
     int rc=0;
+    int sigversion;
     gcry_md_hd_t md;
 
     assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
            || sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x19
            || sigclass == 0x30 || sigclass == 0x28 );
 
-    if (opt.force_v4_certs)
-        sigversion = 4;
-
-    if (sigversion < sk->version)
-        sigversion = sk->version;
-
-    /* If you are making a signature on a v4 key using your v3 key, it
-       doesn't make sense to generate a v3 sig.  After all, no v3-only
-       PGP implementation could understand the v4 key in the first
-       place.  Note that this implies that a signature on an attribute
-       uid is usually going to be v4 as well, since they are not
-       generally found on v3 keys. */
-    if (sigversion < pk->version)
-        sigversion = pk->version;
+    sigversion = 4;
+    if (sigversion < pksk->version)
+        sigversion = pksk->version;
 
     if( !digest_algo )
       {
-       /* Basically, this means use SHA1 always unless it's a v3 RSA
-          key making a v3 cert (use MD5), or the user specified
-          something (use whatever they said), or it's DSA (use the
-          best match).  They still can't pick an inappropriate hash
-          for DSA or the signature will fail.  Note that this still
-          allows the caller of make_keysig_packet to override the
-          user setting if it must. */
+       /* Basically, this means use SHA1 always unless the user
+          specified something (use whatever they said), or it's DSA
+          (use the best match).  They still can't pick an
+          inappropriate hash for DSA or the signature will fail.
+          Note that this still allows the caller of
+          make_keysig_packet to override the user setting if it
+          must. */
 
        if(opt.cert_digest_algo)
          digest_algo=opt.cert_digest_algo;
-       else if(sk->pubkey_algo==PUBKEY_ALGO_RSA
-               && pk->version<4 && sigversion<4)
-         digest_algo = DIGEST_ALGO_MD5;
-       else if(sk->pubkey_algo==PUBKEY_ALGO_DSA)
-         digest_algo = match_dsa_hash (gcry_mpi_get_nbits (sk->skey[1])/8);
+       else if(pksk->pubkey_algo == PUBKEY_ALGO_DSA)
+         digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8);
+        else if (pksk->pubkey_algo == PUBKEY_ALGO_ECDSA
+                 || pksk->pubkey_algo == PUBKEY_ALGO_EDDSA)
+          {
+            if (openpgp_oid_is_ed25519 (pksk->pkey[0]))
+              digest_algo = DIGEST_ALGO_SHA256;
+            else
+              digest_algo = match_dsa_hash
+                (ecdsa_qbits_from_Q (gcry_mpi_get_nbits (pksk->pkey[1]))/8);
+          }
        else
          digest_algo = DEFAULT_DIGEST_ALGO;
       }
@@ -1456,8 +1455,8 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
     sig->version = sigversion;
     sig->flags.exportable=1;
     sig->flags.revocable=1;
-    keyid_from_sk( sk, sig->keyid );
-    sig->pubkey_algo = sk->pubkey_algo;
+    keyid_from_pk (pksk, sig->keyid);
+    sig->pubkey_algo = pksk->pubkey_algo;
     sig->digest_algo = digest_algo;
     if(timestamp)
       sig->timestamp=timestamp;
@@ -1466,26 +1465,24 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
     if(duration)
       sig->expiredate=sig->timestamp+duration;
     sig->sig_class = sigclass;
-    if( sig->version >= 4 )
-      {
-       build_sig_subpkt_from_sig( sig );
-       mk_notation_policy_etc( sig, pk, sk );
-      }
+
+    build_sig_subpkt_from_sig( sig );
+    mk_notation_policy_etc (sig, pk, pksk);
 
     /* Crucial that the call to mksubpkt comes LAST before the calls
        to finalize the sig as that makes it possible for the mksubpkt
        function to get a reliable pointer to the subpacket area. */
-    if( sig->version >= 4 && mksubpkt )
+    if (mksubpkt)
        rc = (*mksubpkt)( sig, opaque );
 
     if( !rc ) {
         hash_sigversion_to_magic (md, sig);
        gcry_md_final (md);
 
-       rc = complete_sig( sig, sk, md );
+       rc = complete_sig (sig, pksk, md, cache_nonce);
     }
 
-    gcry_md_close ( md );
+    gcry_md_close (md);
     if( rc )
        free_seckey_enc( sig );
     else
@@ -1498,6 +1495,9 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
 /****************
  * Create a new signature packet based on an existing one.
  * Only user ID signatures are supported for now.
+ * PK is the public key to work on.
+ * PKSK is the key used to make the signature.
+ *
  * TODO: Merge this with make_keysig_packet.
  */
 int
@@ -1506,16 +1506,16 @@ update_keysig_packet( PKT_signature **ret_sig,
                       PKT_public_key *pk,
                       PKT_user_id *uid,
                       PKT_public_key *subpk,
-                      PKT_secret_key *sk,
+                      PKT_public_key *pksk,
                       int (*mksubpkt)(PKT_signature *, void *),
-                      void *opaque )
+                      void *opaque)
 {
     PKT_signature *sig;
     int rc = 0;
     int digest_algo;
     gcry_md_hd_t md;
 
-    if ((!orig_sig || !pk || !sk)
+    if ((!orig_sig || !pk || !pksk)
        || (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid)
        || (orig_sig->sig_class == 0x18 && !subpk))
       return G10ERR_GENERAL;
@@ -1557,23 +1557,20 @@ update_keysig_packet( PKT_signature **ret_sig,
        duration of 1) since build-packet.c:build_sig_subpkt_from_sig
        detects this case. */
 
-    if( sig->version >= 4 )
-      {
-       /* Put the updated timestamp into the sig.  Note that this
-          will automagically lower any sig expiration dates to
-          correctly correspond to the differences in the timestamps
-          (i.e. the duration will shrink). */
-       build_sig_subpkt_from_sig( sig );
-
-       if (mksubpkt)
-         rc = (*mksubpkt)(sig, opaque);
-      }
+    /* Put the updated timestamp into the sig.  Note that this will
+       automagically lower any sig expiration dates to correctly
+       correspond to the differences in the timestamps (i.e. the
+       duration will shrink).  */
+    build_sig_subpkt_from_sig( sig );
+
+    if (mksubpkt)
+      rc = (*mksubpkt)(sig, opaque);
 
     if (!rc) {
         hash_sigversion_to_magic (md, sig);
        gcry_md_final (md);
 
-       rc = complete_sig( sig, sk, md );
+       rc = complete_sig (sig, pksk, md, NULL);
     }
 
     gcry_md_close (md);
index c9e683f..6c8a40b 100644 (file)
@@ -36,7 +36,6 @@
 
 #ifdef HAVE_DOSISH_SYSTEM
 void init_signals(void) {}
-void pause_on_sigusr(int which) {}
 #else
 static volatile int caught_fatal_sig = 0;
 static volatile int caught_sigusr1 = 0;
@@ -58,7 +57,7 @@ init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
     sigemptyset (&nact.sa_mask);
     nact.sa_flags = 0;
     sigaction ( sig, &nact, NULL);
-#else 
+#else
     RETSIGTYPE (*ohandler)(int);
 
     ohandler = signal (sig, handler);
@@ -133,31 +132,6 @@ init_signals()
 }
 
 
-void
-pause_on_sigusr( int which )
-{
-#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
-    sigset_t mask, oldmask;
-
-    assert( which == 1 );
-    sigemptyset( &mask );
-    sigaddset( &mask, SIGUSR1 );
-
-    sigprocmask( SIG_BLOCK, &mask, &oldmask );
-    while( !caught_sigusr1 )
-       sigsuspend( &oldmask );
-    caught_sigusr1 = 0;
-    sigprocmask( SIG_UNBLOCK, &mask, NULL );
-#else 
-     assert (which == 1);
-     sighold (SIGUSR1);
-     while (!caught_sigusr1)
-         sigpause(SIGUSR1);
-     caught_sigusr1 = 0;
-     sigrelse(SIGUSR1);
-#endif /*! HAVE_SIGPROCMASK && HAVE_SIGSET_T */
-}
-
 /* Disabled - see comment in tdbio.c:tdbio_begin_transaction() */
 #if 0
 static void
index 70b375a..53d6f77 100644 (file)
@@ -1,5 +1,6 @@
 /* skclist.c - Build a list of secret keys
- * Copyright (C) 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2006,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include "keydb.h"
 #include "util.h"
 #include "i18n.h"
-#include "cipher.h"
 
-#ifndef GCRYCTL_FAKED_RANDOM_P
-#define GCRYCTL_FAKED_RANDOM_P 51
-#endif
 
 /* Return true if Libgcrypt's RNG is in faked mode.  */
 int
 random_is_faked (void)
 {
-  return !!gcry_control ( GCRYCTL_FAKED_RANDOM_P, 0);
+  return !!gcry_control (GCRYCTL_FAKED_RANDOM_P, 0);
 }
 
 
-
 void
-release_sk_list( SK_LIST sk_list )
+release_sk_list (SK_LIST sk_list)
 {
-    SK_LIST sk_rover;
+  SK_LIST sk_rover;
 
-    for( ; sk_list; sk_list = sk_rover ) {
-       sk_rover = sk_list->next;
-       free_secret_key( sk_list->sk );
-       xfree( sk_list );
+  for (; sk_list; sk_list = sk_rover)
+    {
+      sk_rover = sk_list->next;
+      free_public_key (sk_list->pk);
+      xfree (sk_list);
     }
 }
 
 
 /* Check that we are only using keys which don't have
  * the string "(insecure!)" or "not secure" or "do not use"
- * in one of the user ids
- */
+ * in one of the user ids.  */
 static int
-is_insecure( PKT_secret_key *sk )
+is_insecure (PKT_public_key *pk)
 {
-    u32 keyid[2];
-    KBNODE node = NULL, u;
-    int insecure = 0;
+  u32 keyid[2];
+  KBNODE node = NULL, u;
+  int insecure = 0;
 
-    keyid_from_sk( sk, keyid );
-    node = get_pubkeyblock( keyid );
-    for ( u = node; u; u = u->next ) {
-        if ( u->pkt->pkttype == PKT_USER_ID ) {
-            PKT_user_id *id = u->pkt->pkt.user_id;
-            if ( id->attrib_data )
-                continue; /* skip attribute packets */
-            if ( strstr( id->name, "(insecure!)" )
-                 || strstr( id->name, "not secure" )
-                 || strstr( id->name, "do not use" )
-                 || strstr( id->name, "(INSECURE!)" ) ) {
-                insecure = 1;
-                break;
-            }
-        }
+  keyid_from_pk (pk, keyid);
+  node = get_pubkeyblock (keyid);
+  for (u = node; u; u = u->next)
+    {
+      if (u->pkt->pkttype == PKT_USER_ID)
+       {
+         PKT_user_id *id = u->pkt->pkt.user_id;
+         if (id->attrib_data)
+           continue;           /* skip attribute packets */
+         if (strstr (id->name, "(insecure!)")
+             || strstr (id->name, "not secure")
+             || strstr (id->name, "do not use")
+             || strstr (id->name, "(INSECURE!)"))
+           {
+             insecure = 1;
+             break;
+           }
+       }
     }
-    release_kbnode( node );
-    
-    return insecure;
+  release_kbnode (node);
+
+  return insecure;
 }
 
 static int
-key_present_in_sk_list(SK_LIST sk_list, PKT_secret_key *sk)
+key_present_in_sk_list (SK_LIST sk_list, PKT_public_key *pk)
 {
-    for (; sk_list; sk_list = sk_list->next) {
-       if ( !cmp_secret_keys(sk_list->sk, sk) )
-           return 0;
+  for (; sk_list; sk_list = sk_list->next)
+    {
+      if (!cmp_public_keys (sk_list->pk, pk))
+       return 0;
     }
-    return -1;
+  return -1;
 }
 
 static int
 is_duplicated_entry (strlist_t list, strlist_t item)
 {
-    for(; list && list != item; list = list->next) {
-        if ( !strcmp (list->d, item->d) )
-            return 1;
+  for (; list && list != item; list = list->next)
+    {
+      if (!strcmp (list->d, item->d))
+       return 1;
     }
-    return 0;
+  return 0;
 }
 
 
-int
-build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list,
-               int unlock, unsigned int use )
+gpg_error_t
+build_sk_list (strlist_t locusr, SK_LIST *ret_sk_list, unsigned int use)
 {
-    SK_LIST sk_list = NULL;
-    int rc;
+  gpg_error_t err;
+  SK_LIST sk_list = NULL;
 
-    if( !locusr )
-      { /* use the default one */
-       PKT_secret_key *sk;
+  if (!locusr) /* No user ids given - use the default key.  */
+    {
+      PKT_public_key *pk;
 
-       sk = xmalloc_clear( sizeof *sk );
-       sk->req_usage = use;
-       if( (rc = get_seckey_byname( sk, NULL, unlock )) ) {
-         free_secret_key( sk ); sk = NULL;
-         log_error("no default secret key: %s\n", g10_errstr(rc) );
-          write_status_text (STATUS_INV_SGNR,
-                             get_inv_recpsgnr_code (GPG_ERR_NO_SECKEY));
+      pk = xmalloc_clear (sizeof *pk);
+      pk->req_usage = use;
+      if ((err = getkey_byname (NULL, pk, NULL, 1, NULL)))
+       {
+         free_public_key (pk);
+         pk = NULL;
+         log_error ("no default secret key: %s\n", gpg_strerror (err));
+         write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (err));
        }
-       else if( !(rc=openpgp_pk_test_algo2 (sk->pubkey_algo, use)) )
-         {
-           SK_LIST r;
+      else if ((err = openpgp_pk_test_algo2 (pk->pubkey_algo, use)))
+       {
+         free_public_key (pk);
+         pk = NULL;
+         log_error ("invalid default secret key: %s\n", gpg_strerror (err));
+         write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (err));
+       }
+      else
+       {
+         SK_LIST r;
 
-           if( random_is_faked() && !is_insecure( sk ) )
-             {
-               log_info(_("key is not flagged as insecure - "
-                          "can't use it with the faked RNG!\n"));
-               free_secret_key( sk ); sk = NULL;
-                write_status_text (STATUS_INV_SGNR, 
-                                   get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED));
-             }
-           else
-             {
-               r = xmalloc( sizeof *r );
-               r->sk = sk; sk = NULL;
-               r->next = sk_list;
-               r->mark = 0;
-               sk_list = r;
-             }
-         }
-       else
-         {
-           free_secret_key( sk ); sk = NULL;
-           log_error("invalid default secret key: %s\n", g10_errstr(rc) );
-            write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc));
-         }
-      }
-    else {
-        strlist_t locusr_orig = locusr;
-       for(; locusr; locusr = locusr->next ) {
-           PKT_secret_key *sk;
-            
-            rc = 0;
-            /* Do an early check agains duplicated entries.  However this
-             * won't catch all duplicates because the user IDs may be
-             * specified in different ways.
-             */
-            if ( is_duplicated_entry ( locusr_orig, locusr ) )
-             {
-               log_info (_("skipped \"%s\": duplicated\n"), locusr->d );
-                continue;
-             }
-           sk = xmalloc_clear( sizeof *sk );
-           sk->req_usage = use;
-           if( (rc = get_seckey_byname( sk, locusr->d, 0 )) )
-             {
-               free_secret_key( sk ); sk = NULL;
-               log_error(_("skipped \"%s\": %s\n"),
-                         locusr->d, g10_errstr(rc) );
-                write_status_text_and_buffer 
-                  (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc), 
-                   locusr->d, strlen (locusr->d), -1);
-             }
-            else if ( key_present_in_sk_list(sk_list, sk) == 0) {
-                free_secret_key(sk); sk = NULL;
-                log_info(_("skipped: secret key already present\n"));
-            }
-            else if ( unlock && (rc = check_secret_key( sk, 0 )) )
-             {
-               free_secret_key( sk ); sk = NULL;
-               log_error(_("skipped \"%s\": %s\n"),
-                         locusr->d, g10_errstr(rc) );
-                write_status_text_and_buffer 
-                  (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc), 
-                   locusr->d, strlen (locusr->d), -1);
-             }
-           else if( !(rc=openpgp_pk_test_algo2 (sk->pubkey_algo, use)) ) {
-               SK_LIST r;
+         if (random_is_faked () && !is_insecure (pk))
+           {
+             log_info (_("key is not flagged as insecure - "
+                         "can't use it with the faked RNG!\n"));
+             free_public_key (pk);
+             pk = NULL;
+             write_status_text (STATUS_INV_SGNR,
+                                get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED));
+           }
+         else
+           {
+             r = xmalloc (sizeof *r);
+             r->pk = pk;
+             pk = NULL;
+             r->next = sk_list;
+             r->mark = 0;
+             sk_list = r;
+           }
+       }
+    }
+  else /* Check the given user ids.  */
+    {
+      strlist_t locusr_orig = locusr;
 
-               if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
-                   && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E )
-                 {
-                   log_info(_("skipped \"%s\": %s\n"),locusr->d,
-                            _("this is a PGP generated Elgamal key which"
-                              " is not secure for signatures!"));
-                   free_secret_key( sk ); sk = NULL;
-                    write_status_text_and_buffer 
-                      (STATUS_INV_SGNR, 
-                       get_inv_recpsgnr_code (GPG_ERR_WRONG_KEY_USAGE), 
-                       locusr->d, strlen (locusr->d), -1);
-                 }
-               else if( random_is_faked() && !is_insecure( sk ) ) {
-                   log_info(_("key is not flagged as insecure - "
-                              "can't use it with the faked RNG!\n"));
-                   free_secret_key( sk ); sk = NULL;
-                    write_status_text_and_buffer 
-                      (STATUS_INV_SGNR, 
-                       get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED), 
-                       locusr->d, strlen (locusr->d), -1);
+      for (; locusr; locusr = locusr->next)
+       {
+         PKT_public_key *pk;
+
+         err = 0;
+         /* Do an early check against duplicated entries.  However
+          * this won't catch all duplicates because the user IDs may
+          * be specified in different ways.  */
+         if (is_duplicated_entry (locusr_orig, locusr))
+           {
+             log_info (_("skipped \"%s\": duplicated\n"), locusr->d);
+             continue;
+           }
+         pk = xmalloc_clear (sizeof *pk);
+         pk->req_usage = use;
+          if ((err = getkey_byname (NULL, pk, locusr->d, 1, NULL)))
+           {
+             free_public_key (pk);
+             pk = NULL;
+             log_error (_("skipped \"%s\": %s\n"),
+                        locusr->d, gpg_strerror (err));
+             write_status_text_and_buffer
+               (STATUS_INV_SGNR, get_inv_recpsgnr_code (err),
+                locusr->d, strlen (locusr->d), -1);
+           }
+         else if (!key_present_in_sk_list (sk_list, pk))
+           {
+             free_public_key (pk);
+             pk = NULL;
+             log_info (_("skipped: secret key already present\n"));
+           }
+         else if ((err = openpgp_pk_test_algo2 (pk->pubkey_algo, use)))
+           {
+             free_public_key (pk);
+             pk = NULL;
+             log_error ("skipped \"%s\": %s\n", locusr->d, gpg_strerror (err));
+             write_status_text_and_buffer
+               (STATUS_INV_SGNR, get_inv_recpsgnr_code (err),
+                locusr->d, strlen (locusr->d), -1);
+           }
+         else
+           {
+             SK_LIST r;
+
+             if (pk->version == 4 && (use & PUBKEY_USAGE_SIG)
+                 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
+               {
+                 log_info (_("skipped \"%s\": %s\n"), locusr->d,
+                           _("this is a PGP generated Elgamal key which"
+                             " is not secure for signatures!"));
+                 free_public_key (pk);
+                 pk = NULL;
+                 write_status_text_and_buffer
+                   (STATUS_INV_SGNR,
+                    get_inv_recpsgnr_code (GPG_ERR_WRONG_KEY_USAGE),
+                    locusr->d, strlen (locusr->d), -1);
                }
-               else {
-                   r = xmalloc( sizeof *r );
-                   r->sk = sk; sk = NULL;
-                   r->next = sk_list;
-                   r->mark = 0;
-                   sk_list = r;
+             else if (random_is_faked () && !is_insecure (pk))
+               {
+                 log_info (_("key is not flagged as insecure - "
+                             "can't use it with the faked RNG!\n"));
+                 free_public_key (pk);
+                 pk = NULL;
+                 write_status_text_and_buffer
+                   (STATUS_INV_SGNR,
+                    get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED),
+                    locusr->d, strlen (locusr->d), -1);
+               }
+             else
+               {
+                 r = xmalloc (sizeof *r);
+                 r->pk = pk;
+                 pk = NULL;
+                 r->next = sk_list;
+                 r->mark = 0;
+                 sk_list = r;
                }
-           }
-           else {
-               free_secret_key( sk ); sk = NULL;
-               log_error("skipped \"%s\": %s\n", locusr->d, g10_errstr(rc) );
-                write_status_text_and_buffer 
-                  (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc), 
-                   locusr->d, strlen (locusr->d), -1);
            }
        }
     }
 
-
-    if( !rc && !sk_list ) {
-       log_error("no valid signators\n");
-        write_status_text (STATUS_NO_SGNR, "0");
-       rc = G10ERR_NO_USER_ID;
+  if (!err && !sk_list)
+    {
+      log_error ("no valid signators\n");
+      write_status_text (STATUS_NO_SGNR, "0");
+      err = gpg_error (GPG_ERR_NO_USER_ID);
     }
 
-    if( rc )
-       release_sk_list( sk_list );
-    else
-       *ret_sk_list = sk_list;
-    return rc;
+  if (err)
+    release_sk_list (sk_list);
+  else
+    *ret_sk_list = sk_list;
+  return err;
 }
-
index d48e3f2..ea2933f 100644 (file)
@@ -33,7 +33,7 @@
 static void
 run_test (void)
 {
-  static struct 
+  static struct
   {
     const char *data;
     const char *expect;
@@ -71,7 +71,7 @@ run_test (void)
 
   for (idx=0; testtbl[idx].data; idx++)
     {
-      rmd160_hash_buffer (digest, 
+      rmd160_hash_buffer (digest,
                           testtbl[idx].data, strlen(testtbl[idx].data));
       if (memcmp (digest, testtbl[idx].expect, 20))
         fail (idx);
@@ -84,9 +84,8 @@ main (int argc, char **argv)
 {
   (void)argc;
   (void)argv;
-  
+
   run_test ();
 
   return 0;
 }
-
index 4c3b888..92d70a7 100644 (file)
@@ -68,16 +68,16 @@ void
 list_trustdb( const char *username )
 {
   TRUSTREC rec;
-  
+
   (void)username;
-  
+
   init_trustdb();
   /* For now we ignore the user ID. */
   if (1)
     {
       ulong recnum;
       int i;
-      
+
       printf("TrustDB: %s\n", tdbio_get_dbname() );
       for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- )
         putchar('-');
@@ -139,15 +139,15 @@ import_ownertrust( const char *fname )
        is_stdin = 1;
     }
     else if( !(fp = fopen( fname, "r" )) ) {
-       log_error ( _("can't open `%s': %s\n"), fname, strerror(errno) );
+       log_error ( _("can't open '%s': %s\n"), fname, strerror(errno) );
        return;
     }
 
     if (is_secured_file (fileno (fp)))
       {
         fclose (fp);
-        errno = EPERM;
-       log_error (_("can't open `%s': %s\n"), fname, strerror(errno) );
+        gpg_err_set_errno (EPERM);
+       log_error (_("can't open '%s': %s\n"), fname, strerror(errno) );
        return;
       }
 
@@ -158,7 +158,7 @@ import_ownertrust( const char *fname )
            continue;
        n = strlen(line);
        if( line[n-1] != '\n' ) {
-           log_error (_("error in `%s': %s\n"), fname, _("line too long") );
+           log_error (_("error in '%s': %s\n"), fname, _("line too long") );
            /* ... or last line does not have a LF */
            break; /* can't continue */
        }
@@ -166,17 +166,17 @@ import_ownertrust( const char *fname )
            if( !hexdigitp(p) )
                break;
        if( *p != ':' ) {
-           log_error (_("error in `%s': %s\n"), fname, _("colon missing") );
+           log_error (_("error in '%s': %s\n"), fname, _("colon missing") );
            continue;
        }
        fprlen = p - line;
        if( fprlen != 32 && fprlen != 40 ) {
-           log_error (_("error in `%s': %s\n"),
+           log_error (_("error in '%s': %s\n"),
                        fname, _("invalid fingerprint") );
            continue;
        }
        if( sscanf(p, ":%u:", &otrust ) != 1 ) {
-           log_error (_("error in `%s': %s\n"),
+           log_error (_("error in '%s': %s\n"),
                        fname, _("ownertrust value missing"));
            continue;
        }
@@ -187,7 +187,7 @@ import_ownertrust( const char *fname )
            fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
        while (fprlen < 20)
            fpr[fprlen++] = 0;
-        
+
        rc = tdbio_search_trust_byfpr (fpr, &rec);
        if( !rc ) { /* found: update */
            if (rec.r.trust.ownertrust != otrust)
@@ -213,14 +213,14 @@ import_ownertrust( const char *fname )
             any = 1;
        }
        else /* error */
-           log_error (_("error finding trust record in `%s': %s\n"),
+           log_error (_("error finding trust record in '%s': %s\n"),
                        fname, g10_errstr(rc));
     }
     if( ferror(fp) )
-       log_error ( _("read error in `%s': %s\n"), fname, strerror(errno) );
+       log_error ( _("read error in '%s': %s\n"), fname, strerror(errno) );
     if( !is_stdin )
        fclose(fp);
-    
+
     if (any)
       {
         revalidation_mark ();
@@ -228,7 +228,5 @@ import_ownertrust( const char *fname )
         if (rc)
           log_error (_("trustdb: sync failed: %s\n"), g10_errstr(rc) );
       }
-    
-}
-
 
+}
index 725c3c2..aff565c 100644 (file)
@@ -38,7 +38,7 @@
 #include "trustdb.h"
 #include "tdbio.h"
 
-#if defined(HAVE_DOSISH_SYSTEM)
+#if defined(HAVE_DOSISH_SYSTEM) && !defined(ftruncate)
 #define ftruncate chsize
 #endif
 
 #define MY_O_BINARY  0
 #endif
 
+/* We use ERRNO despite that the cegcc provided open/read/write
+   functions don't set ERRNO - at least show that ERRNO does not make
+   sense.  */
+#ifdef HAVE_W32CE_SYSTEM
+#undef strerror
+#define strerror(a) ("[errno not available]")
+#endif
 
 /****************
  * Yes, this is a very simple implementation. We should really
@@ -86,41 +93,14 @@ struct cmp_xdir_struct {
 
 
 static char *db_name;
-static DOTLOCK lockhandle;
+static dotlock_t lockhandle;
 static int is_locked;
 static int  db_fd = -1;
 static int in_transaction;
 
 static void open_db(void);
-static void create_hashtable (TRUSTREC *vr, int type);
 
-static int
-take_write_lock (void)
-{
-  if (!lockhandle)
-    lockhandle = create_dotlock (db_name);
-  if (!lockhandle)
-    log_fatal ( _("can't create lock for `%s'\n"), db_name );
 
-  if (!is_locked)
-    {
-      if (make_dotlock (lockhandle, -1) )
-        log_fatal ( _("can't lock `%s'\n"), db_name );
-      else
-        is_locked = 1;
-      return 0;
-    }
-  else
-    return 1;
-}
-
-static void
-release_write_lock (void)
-{
-  if (!opt.lock_once)
-    if (!release_dotlock (lockhandle))
-      is_locked = 0;
-}
 \f
 /*************************************
  ************* record cache **********
@@ -276,7 +256,12 @@ put_record_into_cache( ulong recno, const char *data )
        int n = dirty_count / 5; /* discard some dirty entries */
        if( !n )
            n = 1;
-        take_write_lock ();
+       if( !is_locked ) {
+           if( dotlock_take( lockhandle, -1 ) )
+               log_fatal("can't acquire lock - giving up\n");
+           else
+               is_locked = 1;
+       }
        for( unused = NULL, r = cache_list; r; r = r->next ) {
            if( r->flags.used && r->flags.dirty ) {
                int rc = write_cache_item( r );
@@ -290,7 +275,10 @@ put_record_into_cache( ulong recno, const char *data )
                    break;
            }
        }
-        release_write_lock ();
+       if( !opt.lock_once ) {
+           if( !dotlock_release( lockhandle ) )
+               is_locked = 0;
+       }
        assert( unused );
        r = unused;
        r->flags.used = 1;
@@ -329,9 +317,13 @@ tdbio_sync()
     if( !cache_is_dirty )
        return 0;
 
-    if (!take_write_lock ())
-        did_lock = 1;
-
+    if( !is_locked ) {
+       if( dotlock_take( lockhandle, -1 ) )
+           log_fatal("can't acquire lock - giving up\n");
+       else
+           is_locked = 1;
+       did_lock = 1;
+    }
     for( r = cache_list; r; r = r->next ) {
        if( r->flags.used && r->flags.dirty ) {
            int rc = write_cache_item( r );
@@ -340,8 +332,10 @@ tdbio_sync()
        }
     }
     cache_is_dirty = 0;
-    if (did_lock)
-        release_write_lock ();
+    if( did_lock && !opt.lock_once ) {
+       if( !dotlock_release (lockhandle) )
+           is_locked = 0;
+    }
 
     return 0;
 }
@@ -378,12 +372,20 @@ tdbio_end_transaction()
 
     if( !in_transaction )
        log_bug("tdbio: no active transaction\n");
-    take_write_lock ();
+    if( !is_locked ) {
+       if( dotlock_take( lockhandle, -1 ) )
+           log_fatal("can't acquire lock - giving up\n");
+       else
+           is_locked = 1;
+    }
     block_all_signals();
     in_transaction = 0;
     rc = tdbio_sync();
     unblock_all_signals();
-    release_write_lock ();
+    if( !opt.lock_once ) {
+       if( !dotlock_release (lockhandle) )
+           is_locked = 0;
+    }
     return rc;
 }
 
@@ -421,7 +423,7 @@ static void
 cleanup(void)
 {
     if( is_locked ) {
-       if( !release_dotlock(lockhandle) )
+       if( !dotlock_release (lockhandle) )
            is_locked = 0;
     }
 }
@@ -472,10 +474,6 @@ create_version_record (void)
   rc = tdbio_write_record( &rec );
   if( !rc )
     tdbio_sync();
-
-  if (!rc)
-    create_hashtable (&rec, 0);
-
   return rc;
 }
 
@@ -484,10 +482,8 @@ create_version_record (void)
 int
 tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
 {
-    char *fname, *p;
-    struct stat statbuf;
+    char *fname;
     static int initialized = 0;
-    int save_slash;
 
     if( !initialized ) {
        atexit( cleanup );
@@ -497,7 +493,7 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
     *r_nofile = 0;
 
     if(new_dbname==NULL)
-      fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL);
+      fname=make_filename(opt.homedir,"trustdb" EXTSEP_S GPGEXT_GPG, NULL);
     else if (*new_dbname != DIRSEP_C )
       {
        if (strchr(new_dbname, DIRSEP_C) )
@@ -508,90 +504,96 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
     else
       fname = xstrdup (new_dbname);
 
-    xfree (db_name);
-    db_name = fname;
-
-    /*
-     * Quick check for (likely) case where there is trustdb.gpg
-     * already.  This check is not required in theory, but it helps in
-     * practice, avoiding costly operations of preparing and taking
-     * the lock.
-     */
-    if (stat (fname, &statbuf) == 0 && statbuf.st_size > 0)
-      /* OK, we have the valid trustdb.gpg already.  */
-      return 0;
-    else if (!create)
-      {
-        *r_nofile = 1;
-        return 0;
-      }
-
-  /* Here comes: No valid trustdb.gpg AND CREATE==1 */
+    if( access( fname, R_OK ) ) {
+#ifdef HAVE_W32CE_SYSTEM
+      /* We know how the cegcc implementation of access works ;-). */
+      if (GetLastError () == ERROR_FILE_NOT_FOUND)
+        gpg_err_set_errno (ENOENT);
+      else
+        gpg_err_set_errno (EIO);
+#endif /*HAVE_W32CE_SYSTEM*/
+       if( errno != ENOENT ) {
+           log_error( _("can't access '%s': %s\n"), fname, strerror(errno) );
+           xfree(fname);
+           return G10ERR_TRUSTDB;
+       }
+       if (!create)
+          *r_nofile = 1;
+        else {
+           FILE *fp;
+           TRUSTREC rec;
+           int rc;
+           char *p = strrchr( fname, DIRSEP_C );
+           mode_t oldmask;
+            int save_slash;
 
-    /*
-     * Make sure the directory exists.  This should be done before
-     * acquiring the lock, which assumes the existence of the directory.
-     */
-    p = strrchr( fname, DIRSEP_C );
 #if HAVE_W32_SYSTEM
-    {
-      /* Windows may either have a slash or a backslash.  Take
-         care of it.  */
-      char *pp = strrchr (fname, '/');
-      if (!p || pp > p)
-        p = pp;
-    }
+            {
+              /* Windows may either have a slash or a backslash.  Take
+                 care of it.  */
+              char *pp = strrchr (fname, '/');
+              if (!p || pp > p)
+                p = pp;
+            }
 #endif /*HAVE_W32_SYSTEM*/
-    assert (p);
-    save_slash = *p;
-    *p = 0;
-    if ( access( fname, F_OK ) ) {
-        try_make_homedir( fname );
-        if (access (fname, F_OK ))
-          log_fatal (_("%s: directory does not exist!\n"), fname);
-    }
-    *p = save_slash;
+           assert (p);
+            save_slash = *p;
+           *p = 0;
+           if( access( fname, F_OK ) ) {
+               try_make_homedir( fname );
+                if (access (fname, F_OK ))
+                  log_fatal (_("%s: directory does not exist!\n"), fname);
+           }
+           *p = save_slash;
+
+           xfree(db_name);
+           db_name = fname;
+#ifdef __riscos__
+           if( !lockhandle )
+              lockhandle = dotlock_create (db_name, 0);
+           if( !lockhandle )
+               log_fatal( _("can't create lock for '%s'\n"), db_name );
+            if( dotlock_make (lockhandle, -1) )
+                log_fatal( _("can't lock '%s'\n"), db_name );
+#endif /* __riscos__ */
+           oldmask=umask(077);
+            if (is_secured_filename (fname)) {
+                fp = NULL;
+                gpg_err_set_errno (EPERM);
+            }
+            else
+                fp =fopen( fname, "wb" );
+           umask(oldmask);
+           if( !fp )
+               log_fatal( _("can't create '%s': %s\n"), fname, strerror(errno) );
+           fclose(fp);
+           db_fd = open( db_name, O_RDWR | MY_O_BINARY );
+           if( db_fd == -1 )
+               log_fatal( _("can't open '%s': %s\n"), db_name, strerror(errno) );
+
+#ifndef __riscos__
+           if( !lockhandle )
+              lockhandle = dotlock_create (db_name, 0);
+           if( !lockhandle )
+               log_fatal( _("can't create lock for '%s'\n"), db_name );
+#endif /* !__riscos__ */
+
+            rc = create_version_record ();
+           if( rc )
+               log_fatal( _("%s: failed to create version record: %s"),
+                                                  fname, g10_errstr(rc));
+           /* and read again to check that we are okay */
+           if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
+               log_fatal( _("%s: invalid trustdb created\n"), db_name );
 
-    take_write_lock ();
+           if( !opt.quiet )
+               log_info(_("%s: trustdb created\n"), db_name);
 
-    if( access( fname, R_OK ) ) {
-        FILE *fp;
-        TRUSTREC rec;
-        int rc;
-        mode_t oldmask;
-
-        if( errno != ENOENT )
-            log_fatal( _("can't access `%s': %s\n"), fname, strerror(errno) );
-
-
-        oldmask=umask(077);
-        if (is_secured_filename (fname)) {
-            fp = NULL;
-            errno = EPERM;
-        }
-        else
-            fp =fopen( fname, "wb" );
-        umask(oldmask);
-        if( !fp )
-            log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) );
-        fclose(fp);
-        db_fd = open( db_name, O_RDWR | MY_O_BINARY );
-        if( db_fd == -1 )
-            log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) );
-
-        rc = create_version_record ();
-        if( rc )
-            log_fatal( _("%s: failed to create version record: %s"),
-                     fname, g10_errstr(rc));
-        /* and read again to check that we are okay */
-        if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
-            log_fatal( _("%s: invalid trustdb created\n"), db_name );
-
-        if( !opt.quiet )
-            log_info(_("%s: trustdb created\n"), db_name);
+           return 0;
+       }
     }
-
-    release_write_lock ();
+    xfree(db_name);
+    db_name = fname;
     return 0;
 }
 
@@ -611,6 +613,30 @@ open_db()
 
   assert( db_fd == -1 );
 
+  if (!lockhandle )
+    lockhandle = dotlock_create (db_name, 0);
+  if (!lockhandle )
+    log_fatal( _("can't create lock for '%s'\n"), db_name );
+#ifdef __riscos__
+  if (dotlock_take (lockhandle, -1) )
+    log_fatal( _("can't lock '%s'\n"), db_name );
+#endif /* __riscos__ */
+#ifdef HAVE_W32CE_SYSTEM
+  {
+    DWORD prevrc = 0;
+    wchar_t *wname = utf8_to_wchar (db_name);
+    if (wname)
+      {
+        db_fd = (int)CreateFile (wname, GENERIC_READ|GENERIC_WRITE,
+                                 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
+                                 OPEN_EXISTING, 0, NULL);
+        xfree (wname);
+      }
+    if (db_fd == -1)
+      log_fatal ("can't open '%s': %d, %d\n", db_name,
+                 (int)prevrc, (int)GetLastError ());
+  }
+#else /*!HAVE_W32CE_SYSTEM*/
   db_fd = open (db_name, O_RDWR | MY_O_BINARY );
   if (db_fd == -1 && (errno == EACCES
 #ifdef EROFS
@@ -618,12 +644,14 @@ open_db()
 #endif
                       )
       ) {
+      /* Take care of read-only trustdbs.  */
       db_fd = open (db_name, O_RDONLY | MY_O_BINARY );
       if (db_fd != -1 && !opt.quiet)
-          log_info (_("NOTE: trustdb not writable\n"));
+          log_info (_("Note: trustdb not writable\n"));
   }
   if ( db_fd == -1 )
-    log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) );
+    log_fatal( _("can't open '%s': %s\n"), db_name, strerror(errno) );
+#endif /*!HAVE_W32CE_SYSTEM*/
   register_secured_file (db_name);
 
   /* Read the version record. */
@@ -768,6 +796,8 @@ get_trusthashrec(void)
        if( rc )
            log_fatal( _("%s: error reading version record: %s\n"),
                                            db_name, g10_errstr(rc) );
+       if( !vr.r.ver.trusthashtbl )
+           create_hashtable( &vr, 0 );
 
        trusthashtbl = vr.r.ver.trusthashtbl;
     }
@@ -1213,7 +1243,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
       case 0:  /* unused (free) record */
        break;
       case RECTYPE_VER: /* version record */
-       if( memcmp(buf+1, "gpg", 3 ) ) {
+       if( memcmp(buf+1, GPGEXT_GPG, 3 ) ) {
            log_error( _("%s: not a trustdb file\n"), db_name );
            err = gpg_error (GPG_ERR_TRUSTDB);
        }
@@ -1225,13 +1255,13 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
        rec->r.ver.trust_model = *p++;
        rec->r.ver.min_cert_level = *p++;
        p += 2;
-       rec->r.ver.created  = buf32_to_ulong (p); p += 4;
-       rec->r.ver.nextcheck = buf32_to_ulong (p); p += 4;
+       rec->r.ver.created  = buftoulong(p); p += 4;
+       rec->r.ver.nextcheck = buftoulong(p); p += 4;
        p += 4;
        p += 4;
-       rec->r.ver.firstfree =buf32_to_ulong (p); p += 4;
+       rec->r.ver.firstfree =buftoulong(p); p += 4;
        p += 4;
-       rec->r.ver.trusthashtbl =buf32_to_ulong (p); p += 4;
+       rec->r.ver.trusthashtbl =buftoulong(p); p += 4;
        if( recnum ) {
            log_error( _("%s: version record with recnum %lu\n"), db_name,
                                                             (ulong)recnum );
@@ -1244,17 +1274,17 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
        }
        break;
       case RECTYPE_FREE:
-       rec->r.free.next  = buf32_to_ulong (p); p += 4;
+       rec->r.free.next  = buftoulong(p); p += 4;
        break;
       case RECTYPE_HTBL:
        for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
-           rec->r.htbl.item[i] = buf32_to_ulong (p); p += 4;
+           rec->r.htbl.item[i] = buftoulong(p); p += 4;
        }
        break;
       case RECTYPE_HLST:
-       rec->r.hlst.next = buf32_to_ulong (p); p += 4;
+       rec->r.hlst.next = buftoulong(p); p += 4;
        for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
-           rec->r.hlst.rnum[i] = buf32_to_ulong (p); p += 4;
+           rec->r.hlst.rnum[i] = buftoulong(p); p += 4;
        }
        break;
       case RECTYPE_TRUST:
@@ -1263,12 +1293,12 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
         rec->r.trust.depth = *p++;
         rec->r.trust.min_ownertrust = *p++;
         p++;
-       rec->r.trust.validlist = buf32_to_ulong (p); p += 4;
+       rec->r.trust.validlist = buftoulong(p); p += 4;
        break;
       case RECTYPE_VALID:
        memcpy( rec->r.valid.namehash, p, 20); p+=20;
         rec->r.valid.validity = *p++;
-       rec->r.valid.next = buf32_to_ulong (p); p += 4;
+       rec->r.valid.next = buftoulong(p); p += 4;
        rec->r.valid.full_count = *p++;
        rec->r.valid.marginal_count = *p++;
        break;
@@ -1305,7 +1335,7 @@ tdbio_write_record( TRUSTREC *rec )
       case RECTYPE_VER: /* version record */
        if( recnum )
            BUG();
-       memcpy(p-1, "gpg", 3 ); p += 2;
+       memcpy(p-1, GPGEXT_GPG, 3 ); p += 2;
        *p++ = rec->r.ver.version;
        *p++ = rec->r.ver.marginals;
        *p++ = rec->r.ver.completes;
@@ -1519,4 +1549,3 @@ tdbio_invalid(void)
   how_to_fix_the_trustdb ();
   g10_exit (2);
 }
-
index 14bf699..394d9c3 100644 (file)
@@ -161,7 +161,7 @@ text_filter( void *opaque, int control,
  */
 int
 copy_clearsig_text( IOBUF out, IOBUF inp, gcry_md_hd_t md,
-                   int escape_dash, int escape_from, int pgp2mode )
+                   int escape_dash, int escape_from)
 {
     unsigned int maxlen;
     byte *buffer = NULL;    /* malloced buffer */
@@ -170,10 +170,7 @@ copy_clearsig_text( IOBUF out, IOBUF inp, gcry_md_hd_t md,
     int truncated = 0;
     int pending_lf = 0;
 
-    if( !opt.pgp2_workarounds )
-       pgp2mode = 0;
-
-    if( !escape_dash )
+   if( !escape_dash )
        escape_from = 0;
 
     write_status_begin_signing (md);
@@ -194,9 +191,7 @@ copy_clearsig_text( IOBUF out, IOBUF inp, gcry_md_hd_t md,
                gcry_md_putc ( md, '\n' );
            }
            gcry_md_write ( md, buffer,
-                            len_without_trailing_chars (buffer, n,
-                                                        pgp2mode?
-                                                        " \r\n":" \t\r\n"));
+                            len_without_trailing_chars (buffer, n, " \t\r\n"));
        }
        else
             gcry_md_write ( md, buffer, n );
diff --git a/g10/trust.c b/g10/trust.c
new file mode 100644 (file)
index 0000000..c8a1c2c
--- /dev/null
@@ -0,0 +1,740 @@
+/* trust.c - High level trust functions
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ *               2008, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "gpg.h"
+#include "keydb.h"
+#include "util.h"
+#include "options.h"
+#include "packet.h"
+#include "main.h"
+#include "i18n.h"
+#include "trustdb.h"
+
+
+/* Return true if key is disabled.  Note that this is usually used via
+   the pk_is_disabled macro.  */
+int
+cache_disabled_value (PKT_public_key *pk)
+{
+#ifdef NO_TRUST_MODELS
+  (void)pk;
+  return 0;
+#else
+  return tdb_cache_disabled_value (pk);
+#endif
+}
+
+
+void
+register_trusted_keyid (u32 *keyid)
+{
+#ifdef NO_TRUST_MODELS
+  (void)keyid;
+#else
+  tdb_register_trusted_keyid (keyid);
+#endif
+}
+
+
+void
+register_trusted_key (const char *string)
+{
+#ifdef NO_TRUST_MODELS
+  (void)string;
+#else
+  tdb_register_trusted_key (string);
+#endif
+}
+
+
+\f
+/*
+ * This function returns a letter for a trust value.  Trust flags
+ * are ignored.
+ */
+static int
+trust_letter (unsigned int value)
+{
+  switch( (value & TRUST_MASK) )
+    {
+    case TRUST_UNKNOWN:   return '-';
+    case TRUST_EXPIRED:   return 'e';
+    case TRUST_UNDEFINED: return 'q';
+    case TRUST_NEVER:     return 'n';
+    case TRUST_MARGINAL:  return 'm';
+    case TRUST_FULLY:     return 'f';
+    case TRUST_ULTIMATE:  return 'u';
+    default:              return '?';
+    }
+}
+
+
+/* The strings here are similar to those in
+   pkclist.c:do_edit_ownertrust() */
+const char *
+trust_value_to_string (unsigned int value)
+{
+  switch ((value & TRUST_MASK))
+    {
+    case TRUST_UNKNOWN:   return _("unknown");
+    case TRUST_EXPIRED:   return _("expired");
+    case TRUST_UNDEFINED: return _("undefined");
+    case TRUST_NEVER:     return _("never");
+    case TRUST_MARGINAL:  return _("marginal");
+    case TRUST_FULLY:     return _("full");
+    case TRUST_ULTIMATE:  return _("ultimate");
+    default:              return "err";
+    }
+}
+
+
+int
+string_to_trust_value (const char *str)
+{
+  if (!ascii_strcasecmp (str, "undefined"))
+    return TRUST_UNDEFINED;
+  else if (!ascii_strcasecmp (str, "never"))
+    return TRUST_NEVER;
+  else if (!ascii_strcasecmp (str, "marginal"))
+    return TRUST_MARGINAL;
+  else if (!ascii_strcasecmp (str, "full"))
+    return TRUST_FULLY;
+  else if (!ascii_strcasecmp(str, "ultimate"))
+    return TRUST_ULTIMATE;
+  else
+    return -1;
+}
+
+
+const char *
+uid_trust_string_fixed (PKT_public_key *key, PKT_user_id *uid)
+{
+  if (!key && !uid)
+    {
+      /* TRANSLATORS: these strings are similar to those in
+         trust_value_to_string(), but are a fixed length.  This is needed to
+         make attractive information listings where columns line up
+         properly.  The value "10" should be the length of the strings you
+         choose to translate to.  This is the length in printable columns.
+         It gets passed to atoi() so everything after the number is
+         essentially a comment and need not be translated.  Either key and
+         uid are both NULL, or neither are NULL. */
+      return _("10 translator see trust.c:uid_trust_string_fixed");
+    }
+  else if(uid->is_revoked || (key && key->flags.revoked))
+    return                         _("[ revoked]");
+  else if(uid->is_expired)
+    return                         _("[ expired]");
+  else if(key)
+    {
+      switch (get_validity(key,uid)&TRUST_MASK)
+        {
+        case TRUST_UNKNOWN:   return _("[ unknown]");
+        case TRUST_EXPIRED:   return _("[ expired]");
+        case TRUST_UNDEFINED: return _("[  undef ]");
+        case TRUST_MARGINAL:  return _("[marginal]");
+        case TRUST_FULLY:     return _("[  full  ]");
+        case TRUST_ULTIMATE:  return _("[ultimate]");
+        }
+    }
+
+  return "err";
+}
+
+
+\f
+/*
+ * Return the assigned ownertrust value for the given public key.
+ * The key should be the primary key.
+ */
+unsigned int
+get_ownertrust (PKT_public_key *pk)
+{
+#ifdef NO_TRUST_MODELS
+  (void)pk;
+  return TRUST_UNKNOWN;
+#else
+  return tdb_get_ownertrust (pk);
+#endif
+}
+
+
+/*
+ * Same as get_ownertrust but this takes the minimum ownertrust value
+ * into into account, and will bump up the value as needed.
+ */
+static int
+get_ownertrust_with_min (PKT_public_key *pk)
+{
+#ifdef NO_TRUST_MODELS
+  (void)pk;
+  return TRUST_UNKNOWN;
+#else
+  unsigned int otrust, otrust_min;
+
+  otrust = (tdb_get_ownertrust (pk) & TRUST_MASK);
+  otrust_min = tdb_get_min_ownertrust (pk);
+  if (otrust < otrust_min)
+    {
+      /* If the trust that the user has set is less than the trust
+        that was calculated from a trust signature chain, use the
+        higher of the two.  We do this here and not in
+        get_ownertrust since the underlying ownertrust should not
+        really be set - just the appearance of the ownertrust. */
+
+      otrust = otrust_min;
+    }
+
+  return otrust;
+#endif
+}
+
+
+/*
+ * Same as get_ownertrust but return a trust letter instead of an
+ * value.  This takes the minimum ownertrust value into account.
+ */
+int
+get_ownertrust_info (PKT_public_key *pk)
+{
+  return trust_letter (get_ownertrust_with_min (pk));
+}
+
+
+/*
+ * Same as get_ownertrust but return a trust string instead of an
+ * value.  This takes the minimum ownertrust value into account.
+ */
+const char *
+get_ownertrust_string (PKT_public_key *pk)
+{
+  return trust_value_to_string (get_ownertrust_with_min (pk));
+}
+
+
+/*
+ * Set the trust value of the given public key to the new value.
+ * The key should be a primary one.
+ */
+void
+update_ownertrust (PKT_public_key *pk, unsigned int new_trust)
+{
+#ifdef NO_TRUST_MODELS
+  (void)pk;
+  (void)new_trust;
+#else
+  tdb_update_ownertrust (pk, new_trust);
+#endif
+}
+
+
+int
+clear_ownertrusts (PKT_public_key *pk)
+{
+#ifdef NO_TRUST_MODELS
+  (void)pk;
+  return 0;
+#else
+  return tdb_clear_ownertrusts (pk);
+#endif
+}
+
+
+void
+revalidation_mark (void)
+{
+#ifndef NO_TRUST_MODELS
+  tdb_revalidation_mark ();
+#endif
+}
+
+
+void
+check_trustdb_stale (void)
+{
+#ifndef NO_TRUST_MODELS
+  tdb_check_trustdb_stale ();
+#endif
+}
+
+
+void
+check_or_update_trustdb (void)
+{
+#ifndef NO_TRUST_MODELS
+  tdb_check_or_update ();
+#endif
+}
+
+
+/*
+ * Return the validity information for PK.  If the namehash is not
+ * NULL, the validity of the corresponsing user ID is returned,
+ * otherwise, a reasonable value for the entire key is returned.
+ */
+unsigned int
+get_validity (PKT_public_key *pk, PKT_user_id *uid)
+{
+  int rc;
+  unsigned int validity;
+  u32 kid[2];
+  PKT_public_key *main_pk;
+
+  if (uid)
+    namehash_from_uid (uid);
+
+  keyid_from_pk (pk, kid);
+  if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1])
+    {
+      /* This is a subkey - get the mainkey. */
+      main_pk = xmalloc_clear (sizeof *main_pk);
+      rc = get_pubkey (main_pk, pk->main_keyid);
+      if (rc)
+        {
+         char *tempkeystr = xstrdup (keystr (pk->main_keyid));
+          log_error ("error getting main key %s of subkey %s: %s\n",
+                     tempkeystr, keystr (kid), g10_errstr (rc));
+         xfree (tempkeystr);
+          validity = TRUST_UNKNOWN;
+          goto leave;
+       }
+    }
+  else
+    main_pk = pk;
+
+#ifdef NO_TRUST_MODELS
+  validity = TRUST_UNKNOWN;
+#else
+  validity = tdb_get_validity_core (pk, uid, main_pk);
+#endif
+
+ leave:
+  /* Set some flags direct from the key */
+  if (main_pk->flags.revoked)
+    validity |= TRUST_FLAG_REVOKED;
+  if (main_pk != pk && pk->flags.revoked)
+    validity |= TRUST_FLAG_SUB_REVOKED;
+  /* Note: expiration is a trust value and not a flag - don't know why
+   * I initially designed it that way.  */
+  if (main_pk->has_expired || pk->has_expired)
+    validity = ((validity & (~TRUST_MASK | TRUST_FLAG_PENDING_CHECK))
+                | TRUST_EXPIRED);
+
+  if (main_pk != pk)
+    free_public_key (main_pk);
+  return validity;
+}
+
+
+int
+get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
+{
+  int trustlevel;
+
+  if (!pk)
+    return '?';  /* Just in case a NULL PK is passed.  */
+
+  trustlevel = get_validity (pk, uid);
+  if ((trustlevel & TRUST_FLAG_REVOKED))
+    return 'r';
+  return trust_letter (trustlevel);
+}
+
+
+const char *
+get_validity_string (PKT_public_key *pk, PKT_user_id *uid)
+{
+  int trustlevel;
+
+  if (!pk)
+    return "err";  /* Just in case a NULL PK is passed.  */
+
+  trustlevel = get_validity (pk, uid);
+  if ((trustlevel & TRUST_FLAG_REVOKED))
+    return _("revoked");
+  return trust_value_to_string (trustlevel);
+}
+
+
+\f
+/*
+ * Mark the signature of the given UID which are used to certify it.
+ * To do this, we first revmove all signatures which are not valid and
+ * from the remain ones we look for the latest one.  If this is not a
+ * certification revocation signature we mark the signature by setting
+ * node flag bit 8.  Revocations are marked with flag 11, and sigs
+ * from unavailable keys are marked with flag 12.  Note that flag bits
+ * 9 and 10 are used for internal purposes.
+ */
+void
+mark_usable_uid_certs (kbnode_t keyblock, kbnode_t uidnode,
+                       u32 *main_kid, struct key_item *klist,
+                       u32 curtime, u32 *next_expire)
+{
+  kbnode_t node;
+  PKT_signature *sig;
+
+  /* First check all signatures.  */
+  for (node=uidnode->next; node; node = node->next)
+    {
+      int rc;
+
+      node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
+      if (node->pkt->pkttype == PKT_USER_ID
+          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+        break; /* ready */
+      if (node->pkt->pkttype != PKT_SIGNATURE)
+        continue;
+      sig = node->pkt->pkt.signature;
+      if (main_kid
+         && sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
+        continue; /* ignore self-signatures if we pass in a main_kid */
+      if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
+        continue; /* we only look at these signature classes */
+      if(sig->sig_class>=0x11 && sig->sig_class<=0x13 &&
+        sig->sig_class-0x10<opt.min_cert_level)
+       continue; /* treat anything under our min_cert_level as an
+                    invalid signature */
+      if (klist && !is_in_klist (klist, sig))
+        continue;  /* no need to check it then */
+      if ((rc=check_key_signature (keyblock, node, NULL)))
+       {
+         /* we ignore anything that won't verify, but tag the
+            no_pubkey case */
+         if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY)
+            node->flag |= 1<<12;
+          continue;
+        }
+      node->flag |= 1<<9;
+    }
+  /* Reset the remaining flags. */
+  for (; node; node = node->next)
+    node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
+
+  /* kbnode flag usage: bit 9 is here set for signatures to consider,
+   * bit 10 will be set by the loop to keep track of keyIDs already
+   * processed, bit 8 will be set for the usable signatures, and bit
+   * 11 will be set for usable revocations. */
+
+  /* For each cert figure out the latest valid one.  */
+  for (node=uidnode->next; node; node = node->next)
+    {
+      KBNODE n, signode;
+      u32 kid[2];
+      u32 sigdate;
+
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+        break;
+      if ( !(node->flag & (1<<9)) )
+        continue; /* not a node to look at */
+      if ( (node->flag & (1<<10)) )
+        continue; /* signature with a keyID already processed */
+      node->flag |= (1<<10); /* mark this node as processed */
+      sig = node->pkt->pkt.signature;
+      signode = node;
+      sigdate = sig->timestamp;
+      kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
+
+      /* Now find the latest and greatest signature */
+      for (n=uidnode->next; n; n = n->next)
+        {
+          if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+            break;
+          if ( !(n->flag & (1<<9)) )
+            continue;
+          if ( (n->flag & (1<<10)) )
+            continue; /* shortcut already processed signatures */
+          sig = n->pkt->pkt.signature;
+          if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1])
+            continue;
+          n->flag |= (1<<10); /* mark this node as processed */
+
+         /* If signode is nonrevocable and unexpired and n isn't,
+             then take signode (skip).  It doesn't matter which is
+             older: if signode was older then we don't want to take n
+             as signode is nonrevocable.  If n was older then we're
+             automatically fine. */
+
+         if(((IS_UID_SIG(signode->pkt->pkt.signature) &&
+              !signode->pkt->pkt.signature->flags.revocable &&
+              (signode->pkt->pkt.signature->expiredate==0 ||
+               signode->pkt->pkt.signature->expiredate>curtime))) &&
+            (!(IS_UID_SIG(n->pkt->pkt.signature) &&
+               !n->pkt->pkt.signature->flags.revocable &&
+               (n->pkt->pkt.signature->expiredate==0 ||
+                n->pkt->pkt.signature->expiredate>curtime))))
+           continue;
+
+         /* If n is nonrevocable and unexpired and signode isn't,
+             then take n.  Again, it doesn't matter which is older: if
+             n was older then we don't want to take signode as n is
+             nonrevocable.  If signode was older then we're
+             automatically fine. */
+
+         if((!(IS_UID_SIG(signode->pkt->pkt.signature) &&
+               !signode->pkt->pkt.signature->flags.revocable &&
+               (signode->pkt->pkt.signature->expiredate==0 ||
+                signode->pkt->pkt.signature->expiredate>curtime))) &&
+            ((IS_UID_SIG(n->pkt->pkt.signature) &&
+              !n->pkt->pkt.signature->flags.revocable &&
+              (n->pkt->pkt.signature->expiredate==0 ||
+               n->pkt->pkt.signature->expiredate>curtime))))
+            {
+              signode = n;
+              sigdate = sig->timestamp;
+             continue;
+            }
+
+         /* At this point, if it's newer, it goes in as the only
+             remaining possibilities are signode and n are both either
+             revocable or expired or both nonrevocable and unexpired.
+             If the timestamps are equal take the later ordered
+             packet, presuming that the key packets are hopefully in
+             their original order. */
+
+          if (sig->timestamp >= sigdate)
+            {
+              signode = n;
+              sigdate = sig->timestamp;
+            }
+        }
+
+      sig = signode->pkt->pkt.signature;
+      if (IS_UID_SIG (sig))
+        { /* this seems to be a usable one which is not revoked.
+           * Just need to check whether there is an expiration time,
+           * We do the expired certification after finding a suitable
+           * certification, the assumption is that a signator does not
+           * want that after the expiration of his certificate the
+           * system falls back to an older certification which has a
+           * different expiration time */
+          const byte *p;
+          u32 expire;
+
+          p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL );
+          expire = p? sig->timestamp + buffer_to_u32(p) : 0;
+
+          if (expire==0 || expire > curtime )
+            {
+              signode->flag |= (1<<8); /* yeah, found a good cert */
+              if (next_expire && expire && expire < *next_expire)
+                *next_expire = expire;
+            }
+        }
+      else
+       signode->flag |= (1<<11);
+    }
+}
+
+
+static int
+clean_sigs_from_uid (kbnode_t keyblock, kbnode_t uidnode,
+                     int noisy, int self_only)
+{
+  int deleted = 0;
+  kbnode_t node;
+  u32 keyid[2];
+
+  assert (keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
+
+  keyid_from_pk (keyblock->pkt->pkt.public_key, keyid);
+
+  /* Passing in a 0 for current time here means that we'll never weed
+     out an expired sig.  This is correct behavior since we want to
+     keep the most recent expired sig in a series. */
+  mark_usable_uid_certs (keyblock, uidnode, NULL, NULL, 0, NULL);
+
+  /* What we want to do here is remove signatures that are not
+     considered as part of the trust calculations.  Thus, all invalid
+     signatures are out, as are any signatures that aren't the last of
+     a series of uid sigs or revocations It breaks down like this:
+     coming out of mark_usable_uid_certs, if a sig is unflagged, it is
+     not even a candidate.  If a sig has flag 9 or 10, that means it
+     was selected as a candidate and vetted.  If a sig has flag 8 it
+     is a usable signature.  If a sig has flag 11 it is a usable
+     revocation.  If a sig has flag 12 it was issued by an unavailable
+     key.  "Usable" here means the most recent valid
+     signature/revocation in a series from a particular signer.
+
+     Delete everything that isn't a usable uid sig (which might be
+     expired), a usable revocation, or a sig from an unavailable
+     key. */
+
+  for (node=uidnode->next;
+       node && node->pkt->pkttype==PKT_SIGNATURE;
+       node=node->next)
+    {
+      int keep;
+
+      keep = self_only? (node->pkt->pkt.signature->keyid[0] == keyid[0]
+                         && node->pkt->pkt.signature->keyid[1] == keyid[1]) : 1;
+
+      /* Keep usable uid sigs ... */
+      if ((node->flag & (1<<8)) && keep)
+       continue;
+
+      /* ... and usable revocations... */
+      if ((node->flag & (1<<11)) && keep)
+       continue;
+
+      /* ... and sigs from unavailable keys. */
+      /* disabled for now since more people seem to want sigs from
+        unavailable keys removed altogether.  */
+      /*
+       if(node->flag & (1<<12))
+       continue;
+      */
+
+      /* Everything else we delete */
+
+      /* At this point, if 12 is set, the signing key was unavailable.
+        If 9 or 10 is set, it's superseded.  Otherwise, it's
+        invalid. */
+
+      if (noisy)
+       log_info ("removing signature from key %s on user ID \"%s\": %s\n",
+                  keystr (node->pkt->pkt.signature->keyid),
+                  uidnode->pkt->pkt.user_id->name,
+                  node->flag&(1<<12)? "key unavailable":
+                  node->flag&(1<<9)?  "signature superseded"
+                  /* */               :"invalid signature"  );
+
+      delete_kbnode (node);
+      deleted++;
+    }
+
+  return deleted;
+}
+
+
+/* This is substantially easier than clean_sigs_from_uid since we just
+   have to establish if the uid has a valid self-sig, is not revoked,
+   and is not expired.  Note that this does not take into account
+   whether the uid has a trust path to it - just whether the keyholder
+   themselves has certified the uid.  Returns true if the uid was
+   compacted.  To "compact" a user ID, we simply remove ALL signatures
+   except the self-sig that caused the user ID to be remove-worthy.
+   We don't actually remove the user ID packet itself since it might
+   be ressurected in a later merge.  Note that this function requires
+   that the caller has already done a merge_keys_and_selfsig().
+
+   TODO: change the import code to allow importing a uid with only a
+   revocation if the uid already exists on the keyring. */
+
+static int
+clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy)
+{
+  kbnode_t node;
+  PKT_user_id *uid = uidnode->pkt->pkt.user_id;
+  int deleted = 0;
+
+  assert (keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
+  assert (uidnode->pkt->pkttype==PKT_USER_ID);
+
+  /* Skip valid user IDs, compacted user IDs, and non-self-signed user
+     IDs if --allow-non-selfsigned-uid is set. */
+  if (uid->created
+      || uid->flags.compacted
+      || (!uid->is_expired && !uid->is_revoked && opt.allow_non_selfsigned_uid))
+    return 0;
+
+  for (node=uidnode->next;
+       node && node->pkt->pkttype == PKT_SIGNATURE;
+      node=node->next)
+    {
+      if (!node->pkt->pkt.signature->flags.chosen_selfsig)
+        {
+          delete_kbnode (node);
+          deleted = 1;
+          uidnode->pkt->pkt.user_id->flags.compacted = 1;
+        }
+    }
+
+  if (noisy)
+    {
+      const char *reason;
+      char *user = utf8_to_native (uid->name, uid->len, 0);
+
+      if (uid->is_revoked)
+       reason = _("revoked");
+      else if (uid->is_expired)
+       reason = _("expired");
+      else
+       reason = _("invalid");
+
+      log_info ("compacting user ID \"%s\" on key %s: %s\n",
+                user, keystr_from_pk (keyblock->pkt->pkt.public_key),
+                reason);
+
+      xfree (user);
+    }
+
+  return deleted;
+}
+
+
+/* Needs to be called after a merge_keys_and_selfsig() */
+void
+clean_one_uid (kbnode_t keyblock, kbnode_t uidnode, int noisy, int self_only,
+               int *uids_cleaned, int *sigs_cleaned)
+{
+  int dummy;
+
+  assert (keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
+  assert (uidnode->pkt->pkttype==PKT_USER_ID);
+
+  if (!uids_cleaned)
+    uids_cleaned = &dummy;
+
+  if (!sigs_cleaned)
+    sigs_cleaned = &dummy;
+
+  /* Do clean_uid_from_key first since if it fires off, we don't have
+     to bother with the other.  */
+  *uids_cleaned += clean_uid_from_key (keyblock, uidnode, noisy);
+  if (!uidnode->pkt->pkt.user_id->flags.compacted)
+    *sigs_cleaned += clean_sigs_from_uid (keyblock, uidnode, noisy, self_only);
+}
+
+
+void
+clean_key (kbnode_t keyblock, int noisy, int self_only,
+           int *uids_cleaned, int *sigs_cleaned)
+{
+  kbnode_t uidnode;
+
+  merge_keys_and_selfsig (keyblock);
+
+  for (uidnode = keyblock->next;
+       uidnode && uidnode->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+       uidnode = uidnode->next)
+    {
+      if (uidnode->pkt->pkttype == PKT_USER_ID)
+        clean_one_uid (keyblock, uidnode,noisy, self_only,
+                       uids_cleaned, sigs_cleaned);
+    }
+}
index bc90161..1bf664b 100644 (file)
 #include "trustdb.h"
 
 
-/*
- * A structure to store key identification as well as some stuff needed
- * for validation
- */
-struct key_item {
-  struct key_item *next;
-  unsigned int ownertrust,min_ownertrust;
-  byte trust_depth;
-  byte trust_value;
-  char *trust_regexp;
-  u32 kid[2];
-};
-
-
 typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
 
 /*
@@ -63,20 +49,22 @@ typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
  * the item right after the last one has a keyblock set to NULL.
  * Maybe we can drop this thing and replace it by key_item
  */
-struct key_array {
+struct key_array
+{
   KBNODE keyblock;
 };
 
 
-/* control information for the trust DB */
-static struct {
-    int init;
-    int level;
-    char *dbname;
-    int no_trustdb;   /* Set if a trustdb file is not available.  */
+/* Control information for the trust DB.  */
+static struct
+{
+  int init;
+  int level;
+  char *dbname;
+  int no_trustdb;
 } trustdb_args;
 
-/* some globals */
+/* Some globals.  */
 static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */
 static struct key_item *utk_list;      /* all ultimately trusted keys */
 
@@ -201,7 +189,7 @@ release_key_array ( struct key_array *keys )
  * FIXME: Should be replaced by a function to add those keys to the trustdb.
  */
 void
-register_trusted_keyid(u32 *keyid)
+tdb_register_trusted_keyid (u32 *keyid)
 {
   struct key_item *k;
 
@@ -213,13 +201,15 @@ register_trusted_keyid(u32 *keyid)
 }
 
 void
-register_trusted_key( const char *string )
+tdb_register_trusted_key( const char *string )
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC desc;
 
-  if (classify_user_id (string, &desc) != KEYDB_SEARCH_MODE_LONG_KID )
+  err = classify_user_id (string, &desc, 1);
+  if (err || desc.mode != KEYDB_SEARCH_MODE_LONG_KID )
     {
-      log_error(_("`%s' is not a valid long keyID\n"), string );
+      log_error(_("'%s' is not a valid long keyID\n"), string );
       return;
     }
 
@@ -307,9 +297,9 @@ verify_own_keys(void)
                     keystr(k->kid));
           else
            {
-             update_ownertrust (&pk,
-                                ((get_ownertrust (&pk) & ~TRUST_MASK)
-                                 | TRUST_ULTIMATE ));
+             tdb_update_ownertrust (&pk,
+                                     ((tdb_get_ownertrust (&pk) & ~TRUST_MASK)
+                                      | TRUST_ULTIMATE ));
              release_public_key_parts (&pk);
            }
 
@@ -430,7 +420,7 @@ how_to_fix_the_trustdb ()
 
 
 void
-init_trustdb()
+init_trustdb ()
 {
   int level = trustdb_args.level;
   const char* dbname = trustdb_args.dbname;
@@ -442,7 +432,7 @@ init_trustdb()
 
   if(level==0 || level==1)
     {
-      int rc = tdbio_set_dbname (dbname, !!level, &trustdb_args.no_trustdb);
+      int rc = tdbio_set_dbnamedbname, !!level, &trustdb_args.no_trustdb);
       if( rc )
        log_fatal("can't init trustdb: %s\n", g10_errstr(rc) );
     }
@@ -482,96 +472,6 @@ init_trustdb()
 }
 
 
-/***********************************************
- ************* Print helpers   ****************
- ***********************************************/
-
-/****************
- * This function returns a letter for a trustvalue  Trust flags
- * are ignore.
- */
-static int
-trust_letter (unsigned int value)
-{
-  switch( (value & TRUST_MASK) )
-    {
-    case TRUST_UNKNOWN:   return '-';
-    case TRUST_EXPIRED:   return 'e';
-    case TRUST_UNDEFINED: return 'q';
-    case TRUST_NEVER:     return 'n';
-    case TRUST_MARGINAL:  return 'm';
-    case TRUST_FULLY:     return 'f';
-    case TRUST_ULTIMATE:  return 'u';
-    default:              return '?';
-    }
-}
-
-const char *
-uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid)
-{
-  if(!key && !uid)
-/* TRANSLATORS: these strings are similar to those in
-   trust_value_to_string(), but are a fixed length.  This is needed to
-   make attractive information listings where columns line up
-   properly.  The value "10" should be the length of the strings you
-   choose to translate to.  This is the length in printable columns.
-   It gets passed to atoi() so everything after the number is
-   essentially a comment and need not be translated.  Either key and
-   uid are both NULL, or neither are NULL. */
-    return _("10 translator see trustdb.c:uid_trust_string_fixed");
-  else if(uid->is_revoked || (key && key->is_revoked))
-    return                         _("[ revoked]");
-  else if(uid->is_expired)
-    return                         _("[ expired]");
-  else if(key)
-    switch(get_validity(key,uid)&TRUST_MASK)
-      {
-      case TRUST_UNKNOWN:   return _("[ unknown]");
-      case TRUST_EXPIRED:   return _("[ expired]");
-      case TRUST_UNDEFINED: return _("[  undef ]");
-      case TRUST_MARGINAL:  return _("[marginal]");
-      case TRUST_FULLY:     return _("[  full  ]");
-      case TRUST_ULTIMATE:  return _("[ultimate]");
-      }
-
-  return "err";
-}
-
-/* The strings here are similar to those in
-   pkclist.c:do_edit_ownertrust() */
-const char *
-trust_value_to_string (unsigned int value)
-{
-  switch( (value & TRUST_MASK) )
-    {
-    case TRUST_UNKNOWN:   return _("unknown");
-    case TRUST_EXPIRED:   return _("expired");
-    case TRUST_UNDEFINED: return _("undefined");
-    case TRUST_NEVER:     return _("never");
-    case TRUST_MARGINAL:  return _("marginal");
-    case TRUST_FULLY:     return _("full");
-    case TRUST_ULTIMATE:  return _("ultimate");
-    default:              return "err";
-    }
-}
-
-int
-string_to_trust_value (const char *str)
-{
-  if(ascii_strcasecmp(str,"undefined")==0)
-    return TRUST_UNDEFINED;
-  else if(ascii_strcasecmp(str,"never")==0)
-    return TRUST_NEVER;
-  else if(ascii_strcasecmp(str,"marginal")==0)
-    return TRUST_MARGINAL;
-  else if(ascii_strcasecmp(str,"full")==0)
-    return TRUST_FULLY;
-  else if(ascii_strcasecmp(str,"ultimate")==0)
-    return TRUST_ULTIMATE;
-  else
-    return -1;
-}
-
 /****************
  * Recreate the WoT but do not ask for new ownertrusts.  Special
  * feature: In batch mode and without a forced yes, this is only done
@@ -605,7 +505,7 @@ check_trustdb ()
       validate_keys (0);
     }
   else
-    log_info (_("no need for a trustdb check with `%s' trust model\n"),
+    log_info (_("no need for a trustdb check with '%s' trust model\n"),
              trust_model_string());
 }
 
@@ -620,21 +520,21 @@ update_trustdb()
   if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
     validate_keys (1);
   else
-    log_info (_("no need for a trustdb update with `%s' trust model\n"),
+    log_info (_("no need for a trustdb update with '%s' trust model\n"),
              trust_model_string());
 }
 
 void
-revalidation_mark (void)
+tdb_revalidation_mark (void)
 {
   init_trustdb();
   if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
     return;
 
-  /* we simply set the time for the next check to 1 (far back in 1970)
-   * so that a --update-trustdb will be scheduled */
+  /* We simply set the time for the next check to 1 (far back in 1970)
+     so that a --update-trustdb will be scheduled.  */
   if (tdbio_write_nextcheck (1))
-      do_sync ();
+    do_sync ();
   pending_check_trustdb = 1;
 }
 
@@ -647,7 +547,7 @@ trustdb_pending_check(void)
 /* If the trustdb is dirty, and we're interactive, update it.
    Otherwise, check it unless no-auto-check-trustdb is set. */
 void
-trustdb_check_or_update(void)
+tdb_check_or_update (void)
 {
   if(trustdb_pending_check())
     {
@@ -669,7 +569,7 @@ read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
   if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
     memset (&opts, 0, sizeof opts);
   else
-    read_record(0,&opts,RECTYPE_VER);
+    read_record (0, &opts, RECTYPE_VER);
 
   if(trust_model)
     *trust_model=opts.r.ver.trust_model;
@@ -722,7 +622,7 @@ read_trust_record (PKT_public_key *pk, TRUSTREC *rec)
  * The key should be the primary key.
  */
 unsigned int
-get_ownertrust ( PKT_public_key *pk)
+tdb_get_ownertrust ( PKT_public_key *pk)
 {
   TRUSTREC rec;
   int rc;
@@ -742,8 +642,9 @@ get_ownertrust ( PKT_public_key *pk)
   return rec.r.trust.ownertrust;
 }
 
+
 unsigned int
-get_min_ownertrust (PKT_public_key *pk)
+tdb_get_min_ownertrust (PKT_public_key *pk)
 {
   TRUSTREC rec;
   int rc;
@@ -763,57 +664,13 @@ get_min_ownertrust (PKT_public_key *pk)
   return rec.r.trust.min_ownertrust;
 }
 
-/*
- * Same as get_ownertrust but this takes the minimum ownertrust value
- * into into account, and will bump up the value as needed.
- */
-static int
-get_ownertrust_with_min (PKT_public_key *pk)
-{
-  unsigned int otrust,otrust_min;
-
-  otrust = (get_ownertrust (pk) & TRUST_MASK);
-  otrust_min = get_min_ownertrust (pk);
-  if(otrust<otrust_min)
-    {
-      /* If the trust that the user has set is less than the trust
-        that was calculated from a trust signature chain, use the
-        higher of the two.  We do this here and not in
-        get_ownertrust since the underlying ownertrust should not
-        really be set - just the appearance of the ownertrust. */
-
-      otrust=otrust_min;
-    }
-
-  return otrust;
-}
-
-/*
- * Same as get_ownertrust but return a trust letter instead of an
- * value.  This takes the minimum ownertrust value into account.
- */
-int
-get_ownertrust_info (PKT_public_key *pk)
-{
-  return trust_letter(get_ownertrust_with_min(pk));
-}
-
-/*
- * Same as get_ownertrust but return a trust string instead of an
- * value.  This takes the minimum ownertrust value into account.
- */
-const char *
-get_ownertrust_string (PKT_public_key *pk)
-{
-  return trust_value_to_string(get_ownertrust_with_min(pk));
-}
 
 /*
  * Set the trust value of the given public key to the new value.
  * The key should be a primary one.
  */
 void
-update_ownertrust (PKT_public_key *pk, unsigned int new_trust )
+tdb_update_ownertrust (PKT_public_key *pk, unsigned int new_trust )
 {
   TRUSTREC rec;
   int rc;
@@ -831,7 +688,7 @@ update_ownertrust (PKT_public_key *pk, unsigned int new_trust )
         {
           rec.r.trust.ownertrust = new_trust;
           write_record( &rec );
-          revalidation_mark ();
+          tdb_revalidation_mark ();
           do_sync ();
         }
     }
@@ -848,7 +705,7 @@ update_ownertrust (PKT_public_key *pk, unsigned int new_trust )
       fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
       rec.r.trust.ownertrust = new_trust;
       write_record (&rec);
-      revalidation_mark ();
+      tdb_revalidation_mark ();
       do_sync ();
       rc = 0;
     }
@@ -888,7 +745,7 @@ update_min_ownertrust (u32 *kid, unsigned int new_trust )
         {
           rec.r.trust.min_ownertrust = new_trust;
           write_record( &rec );
-          revalidation_mark ();
+          tdb_revalidation_mark ();
           do_sync ();
         }
     }
@@ -905,7 +762,7 @@ update_min_ownertrust (u32 *kid, unsigned int new_trust )
       fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
       rec.r.trust.min_ownertrust = new_trust;
       write_record (&rec);
-      revalidation_mark ();
+      tdb_revalidation_mark ();
       do_sync ();
       rc = 0;
     }
@@ -915,15 +772,16 @@ update_min_ownertrust (u32 *kid, unsigned int new_trust )
     }
 }
 
+
 /* Clear the ownertrust and min_ownertrust values.  Return true if a
    change actually happened. */
 int
-clear_ownertrusts (PKT_public_key *pk)
+tdb_clear_ownertrusts (PKT_public_key *pk)
 {
   TRUSTREC rec;
   int rc;
 
-  init_trustdb();
+  init_trustdb ();
 
   if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS)
     return 0;
@@ -943,7 +801,7 @@ clear_ownertrusts (PKT_public_key *pk)
           rec.r.trust.ownertrust = 0;
           rec.r.trust.min_ownertrust = 0;
           write_record( &rec );
-          revalidation_mark ();
+          tdb_revalidation_mark ();
           do_sync ();
           return 1;
         }
@@ -1018,18 +876,20 @@ update_validity (PKT_public_key *pk, PKT_user_id *uid,
  *********  Query trustdb values  **************
  ***********************************************/
 
-/* Return true if key is disabled */
+/* Return true if key is disabled.  Note that this is usually used via
+   the pk_is_disabled macro.  */
 int
-cache_disabled_value(PKT_public_key *pk)
+tdb_cache_disabled_value (PKT_public_key *pk)
 {
   int rc;
   TRUSTREC trec;
-  int disabled=0;
+  int disabled = 0;
 
-  if(pk->is_disabled)
-    return (pk->is_disabled==2);
+  if (pk->flags.disabled_valid)
+    return pk->flags.disabled;
 
   init_trustdb();
+
   if (trustdb_args.no_trustdb)
     return 0;  /* No trustdb => not disabled.  */
 
@@ -1042,26 +902,26 @@ cache_disabled_value(PKT_public_key *pk)
   if (rc == -1) /* no record found, so assume not disabled */
     goto leave;
 
-  if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
-    disabled=1;
+  if (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
+    disabled = 1;
 
   /* Cache it for later so we don't need to look at the trustdb every
      time */
-  if(disabled)
-    pk->is_disabled=2;
-  else
-    pk->is_disabled=1;
+  pk->flags.disabled = disabled;
+  pk->flags.disabled_valid = 1;
 
  leave:
    return disabled;
 }
 
+
 void
-check_trustdb_stale(void)
+tdb_check_trustdb_stale (void)
 {
   static int did_nextcheck=0;
 
   init_trustdb ();
+
   if (trustdb_args.no_trustdb)
     return;  /* No trustdb => can't be stale.  */
 
@@ -1090,22 +950,17 @@ check_trustdb_stale(void)
 }
 
 /*
- * Return the validity information for PK.  If the namehash is not
- * NULL, the validity of the corresponsing user ID is returned,
- * otherwise, a reasonable value for the entire key is returned.
+ * Return the validity information for PK.  This is the core of
+ * get_validity.
  */
 unsigned int
-get_validity (PKT_public_key *pk, PKT_user_id *uid)
+tdb_get_validity_core (PKT_public_key *pk, PKT_user_id *uid,
+                       PKT_public_key *main_pk)
 {
   TRUSTREC trec, vrec;
   int rc;
   ulong recno;
   unsigned int validity;
-  u32 kid[2];
-  PKT_public_key *main_pk;
-
-  if(uid)
-    namehash_from_uid(uid);
 
   init_trustdb ();
 
@@ -1118,29 +973,11 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid)
 
   check_trustdb_stale();
 
-  keyid_from_pk (pk, kid);
-  if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1])
-    { /* this is a subkey - get the mainkey */
-      main_pk = xmalloc_clear (sizeof *main_pk);
-      rc = get_pubkey (main_pk, pk->main_keyid);
-      if (rc)
-        {
-         char *tempkeystr=xstrdup(keystr(pk->main_keyid));
-          log_error ("error getting main key %s of subkey %s: %s\n",
-                     tempkeystr, keystr(kid), g10_errstr(rc));
-         xfree(tempkeystr);
-          validity = TRUST_UNKNOWN;
-          goto leave;
-       }
-    }
-  else
-    main_pk = pk;
-
   if(opt.trust_model==TM_DIRECT)
     {
       /* Note that this happens BEFORE any user ID stuff is checked.
         The direct trust model applies to keys as a whole. */
-      validity=get_ownertrust(main_pk);
+      validity = tdb_get_ownertrust (main_pk);
       goto leave;
     }
 
@@ -1189,57 +1026,19 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid)
   if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) )
     {
       validity |= TRUST_FLAG_DISABLED;
-      pk->is_disabled=2;
+      pk->flags.disabled = 1;
     }
   else
-    pk->is_disabled=1;
+    pk->flags.disabled = 0;
+  pk->flags.disabled_valid = 1;
 
  leave:
-  /* set some flags direct from the key */
-  if (main_pk->is_revoked)
-    validity |= TRUST_FLAG_REVOKED;
-  if (main_pk != pk && pk->is_revoked)
-    validity |= TRUST_FLAG_SUB_REVOKED;
-  /* Note: expiration is a trust value and not a flag - don't know why
-   * I initially designed it that way */
-  if (main_pk->has_expired || pk->has_expired)
-    validity = (validity & ~TRUST_MASK) | TRUST_EXPIRED;
-
   if (pending_check_trustdb)
     validity |= TRUST_FLAG_PENDING_CHECK;
 
-  if (main_pk != pk)
-    free_public_key (main_pk);
   return validity;
 }
 
-int
-get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
-{
-  int trustlevel;
-
-  if (!pk)
-    return '?';  /* Just in case a NULL PK is passed.  */
-
-  trustlevel = get_validity (pk, uid);
-  if ( (trustlevel & TRUST_FLAG_REVOKED) )
-    return 'r';
-  return trust_letter (trustlevel);
-}
-
-const char *
-get_validity_string (PKT_public_key *pk, PKT_user_id *uid)
-{
-  int trustlevel;
-
-  if (!pk)
-    return "err";  /* Just in case a NULL PK is passed.  */
-
-  trustlevel = get_validity (pk, uid);
-  if( trustlevel & TRUST_FLAG_REVOKED )
-    return _("revoked");
-  return trust_value_to_string(trustlevel);
-}
 
 static void
 get_validity_counts (PKT_public_key *pk, PKT_user_id *uid)
@@ -1352,14 +1151,14 @@ ask_ownertrust (u32 *kid,int minimum)
     {
       log_info("force trust for key %s to %s\n",
               keystr(kid),trust_value_to_string(opt.force_ownertrust));
-      update_ownertrust(pk,opt.force_ownertrust);
+      tdb_update_ownertrust (pk, opt.force_ownertrust);
       ot=opt.force_ownertrust;
     }
   else
     {
       ot=edit_ownertrust(pk,0);
       if(ot>0)
-       ot = get_ownertrust (pk);
+       ot = tdb_get_ownertrust (pk);
       else if(ot==0)
        ot = minimum?minimum:TRUST_UNDEFINED;
       else
@@ -1414,7 +1213,8 @@ dump_key_array (int depth, struct key_array *keys)
                       (node->flag & 4)? 'f':
                       (node->flag & 2)? 'm':
                       (node->flag & 1)? 'q':'-');
-              print_string (stdout,  node->pkt->pkt.user_id->name, len, ':');
+              es_write_sanitized (es_stdout, node->pkt->pkt.user_id->name,
+                                  len, ":", NULL);
               putchar (':');
               putchar ('\n');
             }
@@ -1460,373 +1260,10 @@ store_validation_status (int depth, KBNODE keyblock, KeyHashTable stored)
     do_sync ();
 }
 
-/*
- * check whether the signature sig is in the klist k
- */
-static struct key_item *
-is_in_klist (struct key_item *k, PKT_signature *sig)
-{
-  for (; k; k = k->next)
-    {
-      if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1])
-        return k;
-    }
-  return NULL;
-}
-
-/*
- * Mark the signature of the given UID which are used to certify it.
- * To do this, we first revmove all signatures which are not valid and
- * from the remain ones we look for the latest one.  If this is not a
- * certification revocation signature we mark the signature by setting
- * node flag bit 8.  Revocations are marked with flag 11, and sigs
- * from unavailable keys are marked with flag 12.  Note that flag bits
- * 9 and 10 are used for internal purposes.
- */
-static void
-mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
-                       u32 *main_kid, struct key_item *klist,
-                       u32 curtime, u32 *next_expire)
-{
-  KBNODE node;
-  PKT_signature *sig;
-
-  /* first check all signatures */
-  for (node=uidnode->next; node; node = node->next)
-    {
-      int rc;
-
-      node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
-      if (node->pkt->pkttype == PKT_USER_ID
-          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        break; /* ready */
-      if (node->pkt->pkttype != PKT_SIGNATURE)
-        continue;
-      sig = node->pkt->pkt.signature;
-      if (main_kid
-         && sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
-        continue; /* ignore self-signatures if we pass in a main_kid */
-      if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
-        continue; /* we only look at these signature classes */
-      if(sig->sig_class>=0x11 && sig->sig_class<=0x13 &&
-        sig->sig_class-0x10<opt.min_cert_level)
-       continue; /* treat anything under our min_cert_level as an
-                    invalid signature */
-      if (klist && !is_in_klist (klist, sig))
-        continue;  /* no need to check it then */
-      if ((rc=check_key_signature (keyblock, node, NULL)))
-       {
-         /* we ignore anything that won't verify, but tag the
-            no_pubkey case */
-         if(rc==G10ERR_NO_PUBKEY)
-           node->flag |= 1<<12;
-         continue;
-       }
-      node->flag |= 1<<9;
-    }
-  /* reset the remaining flags */
-  for (; node; node = node->next)
-      node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
-
-  /* kbnode flag usage: bit 9 is here set for signatures to consider,
-   * bit 10 will be set by the loop to keep track of keyIDs already
-   * processed, bit 8 will be set for the usable signatures, and bit
-   * 11 will be set for usable revocations. */
-
-  /* for each cert figure out the latest valid one */
-  for (node=uidnode->next; node; node = node->next)
-    {
-      KBNODE n, signode;
-      u32 kid[2];
-      u32 sigdate;
-
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        break;
-      if ( !(node->flag & (1<<9)) )
-        continue; /* not a node to look at */
-      if ( (node->flag & (1<<10)) )
-        continue; /* signature with a keyID already processed */
-      node->flag |= (1<<10); /* mark this node as processed */
-      sig = node->pkt->pkt.signature;
-      signode = node;
-      sigdate = sig->timestamp;
-      kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
-
-      /* Now find the latest and greatest signature */
-      for (n=uidnode->next; n; n = n->next)
-        {
-          if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-            break;
-          if ( !(n->flag & (1<<9)) )
-            continue;
-          if ( (n->flag & (1<<10)) )
-            continue; /* shortcut already processed signatures */
-          sig = n->pkt->pkt.signature;
-          if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1])
-            continue;
-          n->flag |= (1<<10); /* mark this node as processed */
-
-         /* If signode is nonrevocable and unexpired and n isn't,
-             then take signode (skip).  It doesn't matter which is
-             older: if signode was older then we don't want to take n
-             as signode is nonrevocable.  If n was older then we're
-             automatically fine. */
-
-         if(((IS_UID_SIG(signode->pkt->pkt.signature) &&
-              !signode->pkt->pkt.signature->flags.revocable &&
-              (signode->pkt->pkt.signature->expiredate==0 ||
-               signode->pkt->pkt.signature->expiredate>curtime))) &&
-            (!(IS_UID_SIG(n->pkt->pkt.signature) &&
-               !n->pkt->pkt.signature->flags.revocable &&
-               (n->pkt->pkt.signature->expiredate==0 ||
-                n->pkt->pkt.signature->expiredate>curtime))))
-           continue;
-
-         /* If n is nonrevocable and unexpired and signode isn't,
-             then take n.  Again, it doesn't matter which is older: if
-             n was older then we don't want to take signode as n is
-             nonrevocable.  If signode was older then we're
-             automatically fine. */
-
-         if((!(IS_UID_SIG(signode->pkt->pkt.signature) &&
-               !signode->pkt->pkt.signature->flags.revocable &&
-               (signode->pkt->pkt.signature->expiredate==0 ||
-                signode->pkt->pkt.signature->expiredate>curtime))) &&
-            ((IS_UID_SIG(n->pkt->pkt.signature) &&
-              !n->pkt->pkt.signature->flags.revocable &&
-              (n->pkt->pkt.signature->expiredate==0 ||
-               n->pkt->pkt.signature->expiredate>curtime))))
-            {
-              signode = n;
-              sigdate = sig->timestamp;
-             continue;
-            }
-
-         /* At this point, if it's newer, it goes in as the only
-             remaining possibilities are signode and n are both either
-             revocable or expired or both nonrevocable and unexpired.
-             If the timestamps are equal take the later ordered
-             packet, presuming that the key packets are hopefully in
-             their original order. */
-
-          if (sig->timestamp >= sigdate)
-            {
-              signode = n;
-              sigdate = sig->timestamp;
-            }
-        }
-
-      sig = signode->pkt->pkt.signature;
-      if (IS_UID_SIG (sig))
-        { /* this seems to be a usable one which is not revoked.
-           * Just need to check whether there is an expiration time,
-           * We do the expired certification after finding a suitable
-           * certification, the assumption is that a signator does not
-           * want that after the expiration of his certificate the
-           * system falls back to an older certification which has a
-           * different expiration time */
-          const byte *p;
-          u32 expire;
-
-          p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL );
-          expire = p? sig->timestamp + buf32_to_u32 (p) : 0;
-
-          if (expire==0 || expire > curtime )
-            {
-              signode->flag |= (1<<8); /* yeah, found a good cert */
-              if (next_expire && expire && expire < *next_expire)
-                *next_expire = expire;
-            }
-        }
-      else
-       signode->flag |= (1<<11);
-    }
-}
-
-static int
-clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy,int self_only)
-{
-  int deleted=0;
-  KBNODE node;
-  u32 keyid[2];
-
-  assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-
-  keyid_from_pk(keyblock->pkt->pkt.public_key,keyid);
-
-  /* Passing in a 0 for current time here means that we'll never weed
-     out an expired sig.  This is correct behavior since we want to
-     keep the most recent expired sig in a series. */
-  mark_usable_uid_certs(keyblock,uidnode,NULL,NULL,0,NULL);
-
-  /* What we want to do here is remove signatures that are not
-     considered as part of the trust calculations.  Thus, all invalid
-     signatures are out, as are any signatures that aren't the last of
-     a series of uid sigs or revocations It breaks down like this:
-     coming out of mark_usable_uid_certs, if a sig is unflagged, it is
-     not even a candidate.  If a sig has flag 9 or 10, that means it
-     was selected as a candidate and vetted.  If a sig has flag 8 it
-     is a usable signature.  If a sig has flag 11 it is a usable
-     revocation.  If a sig has flag 12 it was issued by an unavailable
-     key.  "Usable" here means the most recent valid
-     signature/revocation in a series from a particular signer.
-
-     Delete everything that isn't a usable uid sig (which might be
-     expired), a usable revocation, or a sig from an unavailable
-     key. */
-
-  for(node=uidnode->next;
-      node && node->pkt->pkttype==PKT_SIGNATURE;
-      node=node->next)
-    {
-      int keep=self_only?(node->pkt->pkt.signature->keyid[0]==keyid[0]
-                         && node->pkt->pkt.signature->keyid[1]==keyid[1]):1;
-
-      /* Keep usable uid sigs ... */
-      if((node->flag & (1<<8)) && keep)
-       continue;
-
-      /* ... and usable revocations... */
-      if((node->flag & (1<<11)) && keep)
-       continue;
-
-      /* ... and sigs from unavailable keys. */
-      /* disabled for now since more people seem to want sigs from
-        unavailable keys removed altogether.  */
-      /*
-       if(node->flag & (1<<12))
-       continue;
-      */
-
-      /* Everything else we delete */
-
-      /* At this point, if 12 is set, the signing key was unavailable.
-        If 9 or 10 is set, it's superseded.  Otherwise, it's
-        invalid. */
-
-      if(noisy)
-       log_info("removing signature from key %s on user ID \"%s\": %s\n",
-                keystr(node->pkt->pkt.signature->keyid),
-                uidnode->pkt->pkt.user_id->name,
-                node->flag&(1<<12)?"key unavailable":
-                node->flag&(1<<9)?"signature superseded":"invalid signature");
-
-      delete_kbnode(node);
-      deleted++;
-    }
-
-  return deleted;
-}
-
-/* This is substantially easier than clean_sigs_from_uid since we just
-   have to establish if the uid has a valid self-sig, is not revoked,
-   and is not expired.  Note that this does not take into account
-   whether the uid has a trust path to it - just whether the keyholder
-   themselves has certified the uid.  Returns true if the uid was
-   compacted.  To "compact" a user ID, we simply remove ALL signatures
-   except the self-sig that caused the user ID to be remove-worthy.
-   We don't actually remove the user ID packet itself since it might
-   be ressurected in a later merge.  Note that this function requires
-   that the caller has already done a merge_keys_and_selfsig().
-
-   TODO: change the import code to allow importing a uid with only a
-   revocation if the uid already exists on the keyring. */
-
-static int
-clean_uid_from_key(KBNODE keyblock,KBNODE uidnode,int noisy)
-{
-  KBNODE node;
-  PKT_user_id *uid=uidnode->pkt->pkt.user_id;
-  int deleted=0;
-
-  assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-  assert(uidnode->pkt->pkttype==PKT_USER_ID);
-
-  /* Skip valid user IDs, compacted user IDs, and non-self-signed user
-     IDs if --allow-non-selfsigned-uid is set. */
-  if(uid->created || uid->flags.compacted
-     || (!uid->is_expired && !uid->is_revoked
-        && opt.allow_non_selfsigned_uid))
-    return 0;
-
-  for(node=uidnode->next;
-      node && node->pkt->pkttype==PKT_SIGNATURE;
-      node=node->next)
-    if(!node->pkt->pkt.signature->flags.chosen_selfsig)
-      {
-       delete_kbnode(node);
-       deleted=1;
-       uidnode->pkt->pkt.user_id->flags.compacted=1;
-      }
-
-  if(noisy)
-    {
-      const char *reason;
-      char *user=utf8_to_native(uid->name,uid->len,0);
-
-      if(uid->is_revoked)
-       reason=_("revoked");
-      else if(uid->is_expired)
-       reason=_("expired");
-      else
-       reason=_("invalid");
-
-      log_info("compacting user ID \"%s\" on key %s: %s\n",
-              user,keystr_from_pk(keyblock->pkt->pkt.public_key),
-              reason);
-
-      xfree(user);
-    }
-
-  return deleted;
-}
-
-/* Needs to be called after a merge_keys_and_selfsig() */
-void
-clean_one_uid(KBNODE keyblock,KBNODE uidnode,int noisy,int self_only,
-             int *uids_cleaned,int *sigs_cleaned)
-{
-  int dummy;
-
-  assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
-  assert(uidnode->pkt->pkttype==PKT_USER_ID);
-
-  if(!uids_cleaned)
-    uids_cleaned=&dummy;
-
-  if(!sigs_cleaned)
-    sigs_cleaned=&dummy;
-
-  /* Do clean_uid_from_key first since if it fires off, we don't
-     have to bother with the other */
-  *uids_cleaned+=clean_uid_from_key(keyblock,uidnode,noisy);
-  if(!uidnode->pkt->pkt.user_id->flags.compacted)
-    *sigs_cleaned+=clean_sigs_from_uid(keyblock,uidnode,noisy,self_only);
-}
-
-void
-clean_key(KBNODE keyblock,int noisy,int self_only,
-         int *uids_cleaned,int *sigs_cleaned)
-{
-  KBNODE uidnode;
-
-  merge_keys_and_selfsig(keyblock);
-
-  for(uidnode=keyblock->next;
-      uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
-      uidnode=uidnode->next)
-    if(uidnode->pkt->pkttype==PKT_USER_ID)
-      clean_one_uid(keyblock,uidnode,noisy,self_only,
-                   uids_cleaned,sigs_cleaned);
-}
 
 /* Returns a sanitized copy of the regexp (which might be "", but not
    NULL). */
 #ifndef DISABLE_REGEX
-/* Operator charactors except '.' and backslash.
-   See regex(7) on BSD.  */
-#define REGEXP_OPERATOR_CHARS "^[$()|*+?{"
-
 static char *
 sanitize_regexp(const char *old)
 {
@@ -1866,7 +1303,7 @@ sanitize_regexp(const char *old)
     {
       if(!escaped && old[start]=='\\')
        escaped=1;
-      else if (!escaped && strchr (REGEXP_OPERATOR_CHARS, old[start]))
+      else if(!escaped && old[start]!='.')
        new[idx++]='\\';
       else
        escaped=0;
@@ -1896,6 +1333,8 @@ static int
 check_regexp(const char *expr,const char *string)
 {
 #ifdef DISABLE_REGEX
+  (void)expr;
+  (void)string;
   /* When DISABLE_REGEX is defined, assume all regexps do not
      match. */
   return 0;
@@ -1922,7 +1361,7 @@ check_regexp(const char *expr,const char *string)
 #endif
 
   if(DBG_TRUST)
-    log_debug("regexp `%s' (`%s') on `%s': %s\n",
+    log_debug("regexp '%s' ('%s') on '%s': %s\n",
              regexp,expr,string,ret==0?"YES":"NO");
 
   xfree(regexp);
@@ -2147,8 +1586,8 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
   desc.mode = KEYDB_SEARCH_MODE_FIRST;
   desc.skipfnc = search_skipfnc;
   desc.skipfncvalue = full_trust;
-  rc = keydb_search (hd, &desc, 1);
-  if (rc == -1)
+  rc = keydb_search (hd, &desc, 1, NULL);
+  if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
     {
       keys[nkeys].keyblock = NULL;
       return keys;
@@ -2186,7 +1625,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
       merge_keys_and_selfsig (keyblock);
       clear_kbnode_flags (keyblock);
       pk = keyblock->pkt->pkt.public_key;
-      if (pk->has_expired || pk->is_revoked)
+      if (pk->has_expired || pk->flags.revoked)
         {
           /* it does not make sense to look further at those keys */
           mark_keyblock_seen (full_trust, keyblock);
@@ -2221,8 +1660,9 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
       release_kbnode (keyblock);
       keyblock = NULL;
     }
-  while ( !(rc = keydb_search (hd, &desc, 1)) );
-  if (rc && rc != -1)
+  while (!(rc = keydb_search (hd, &desc, 1, NULL)));
+
+  if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
     {
       log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
       xfree (keys);
@@ -2324,7 +1764,7 @@ validate_keys (int interactive)
   used = new_key_hash_table ();
   full_trust = new_key_hash_table ();
 
-  kdb = keydb_new (0);
+  kdb = keydb_new ();
   reset_trust_records();
 
   /* Fixme: Instead of always building a UTK list, we could just build it
@@ -2396,7 +1836,7 @@ validate_keys (int interactive)
            {
              k->ownertrust = ask_ownertrust (k->kid,min);
 
-             if (k->ownertrust == -1)
+             if (k->ownertrust == (unsigned int)(-1))
                {
                  quit=1;
                  goto leave;
@@ -2411,7 +1851,7 @@ validate_keys (int interactive)
            {
              if(DBG_TRUST)
                log_debug("key %08lX%08lX:"
-                         " overriding ownertrust `%s' with `%s'\n",
+                         " overriding ownertrust '%s' with '%s'\n",
                          (ulong)k->kid[0],(ulong)k->kid[1],
                          trust_value_to_string(k->ownertrust),
                          trust_value_to_string(min));
@@ -2449,17 +1889,16 @@ validate_keys (int interactive)
         ;
 
       /* Store the calculated valididation status somewhere */
-      if (opt.verbose > 1 && DBG_TRUST)
+      if (opt.verbose > 1)
         dump_key_array (depth, keys);
 
       for (kar=keys; kar->keyblock; kar++)
           store_validation_status (depth, kar->keyblock, stored);
 
-      if (!opt.quiet)
-        log_info (_("depth: %d  valid: %3d  signed: %3d"
-                    "  trust: %d-, %dq, %dn, %dm, %df, %du\n"),
-                  depth, valids, key_count, ot_unknown, ot_undefined,
-                  ot_never, ot_marginal, ot_full, ot_ultimate );
+      log_info (_("depth: %d  valid: %3d  signed: %3d"
+                  "  trust: %d-, %dq, %dn, %dm, %df, %du\n"),
+                depth, valids, key_count, ot_unknown, ot_undefined,
+                ot_never, ot_marginal, ot_full, ot_ultimate );
 
       /* Build a new kdlist from all fully valid keys in KEYS */
       if (klist != utk_list)
@@ -2486,10 +1925,10 @@ validate_keys (int interactive)
                      k->kid[0]=kid[0];
                      k->kid[1]=kid[1];
                      k->ownertrust =
-                       (get_ownertrust (kar->keyblock->pkt->pkt.public_key)
-                        & TRUST_MASK);
-                     k->min_ownertrust =
-                       get_min_ownertrust(kar->keyblock->pkt->pkt.public_key);
+                       (tdb_get_ownertrust
+                         (kar->keyblock->pkt->pkt.public_key) & TRUST_MASK);
+                     k->min_ownertrust = tdb_get_min_ownertrust
+                        (kar->keyblock->pkt->pkt.public_key);
                      k->trust_depth=
                        kar->keyblock->pkt->pkt.public_key->trust_depth;
                      k->trust_value=
@@ -2525,9 +1964,8 @@ validate_keys (int interactive)
       else
         {
           tdbio_write_nextcheck (next_expire);
-          if (!opt.quiet)
-            log_info (_("next trustdb check due at %s\n"),
-                      strtimestamp (next_expire));
+          log_info (_("next trustdb check due at %s\n"),
+                    strtimestamp (next_expire));
         }
 
       if(tdbio_update_version_record()!=0)
index 0a9ce33..f190f72 100644 (file)
 
 #define NAMEHASH_LEN  20
 
+
+/*
+ * A structure to store key identification as well as some stuff needed
+ * for validation
+ */
+struct key_item {
+  struct key_item *next;
+  unsigned int ownertrust,min_ownertrust;
+  byte trust_depth;
+  byte trust_value;
+  char *trust_regexp;
+  u32 kid[2];
+};
+
+
+/*
+ * Check whether the signature SIG is in the klist K.
+ */
+static inline struct key_item *
+is_in_klist (struct key_item *k, PKT_signature *sig)
+{
+  for (; k; k = k->next)
+    {
+      if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1])
+        return k;
+    }
+  return NULL;
+}
+
+
+
+/*-- trust.c --*/
+int cache_disabled_value (PKT_public_key *pk);
+void register_trusted_keyid (u32 *keyid);
+void register_trusted_key (const char *string);
+
+const char *trust_value_to_string (unsigned int value);
+int string_to_trust_value (const char *str);
+const char *uid_trust_string_fixed (PKT_public_key *key, PKT_user_id *uid);
+
+unsigned int get_ownertrust (PKT_public_key *pk);
+void update_ownertrust (PKT_public_key *pk, unsigned int new_trust);
+int clear_ownertrusts (PKT_public_key *pk);
+
+void revalidation_mark (void);
+void check_trustdb_stale (void);
+void check_or_update_trustdb (void);
+
+unsigned int get_validity (PKT_public_key *pk, PKT_user_id *uid);
+int get_validity_info (PKT_public_key *pk, PKT_user_id *uid);
+const char *get_validity_string (PKT_public_key *pk, PKT_user_id *uid);
+
+void mark_usable_uid_certs (kbnode_t keyblock, kbnode_t uidnode,
+                            u32 *main_kid, struct key_item *klist,
+                            u32 curtime, u32 *next_expire);
+
+void clean_one_uid (kbnode_t keyblock, kbnode_t uidnode,
+                    int noisy, int self_only,
+                    int *uids_cleaned, int *sigs_cleaned);
+void clean_key (kbnode_t keyblock, int noisy, int self_only,
+                int *uids_cleaned,int *sigs_cleaned);
+
+
+
 /*-- trustdb.c --*/
-void register_trusted_keyid(u32 *keyid);
-void register_trusted_key( const char *string );
+void tdb_register_trusted_keyid (u32 *keyid);
+void tdb_register_trusted_key (const char *string);
 void check_trustdb (void);
 void update_trustdb (void);
 int setup_trustdb( int level, const char *dbname );
 void how_to_fix_the_trustdb (void);
 void init_trustdb( void );
-void check_trustdb_stale(void);
+void tdb_check_trustdb_stale (void);
 void sync_trustdb( void );
 
-const char *uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid);
-const char *trust_value_to_string (unsigned int value);
-int string_to_trust_value (const char *str);
-
-void revalidation_mark (void);
+void tdb_revalidation_mark (void);
 int trustdb_pending_check(void);
-void trustdb_check_or_update(void);
+void tdb_check_or_update (void);
 
-int cache_disabled_value(PKT_public_key *pk);
+int tdb_cache_disabled_value (PKT_public_key *pk);
 
-unsigned int get_validity (PKT_public_key *pk, PKT_user_id *uid);
-int get_validity_info (PKT_public_key *pk, PKT_user_id *uid);
-const char *get_validity_string (PKT_public_key *pk, PKT_user_id *uid);
+unsigned int tdb_get_validity_core (PKT_public_key *pk, PKT_user_id *uid,
+                                    PKT_public_key *main_pk);
 
 void list_trust_path( const char *username );
 int enum_cert_paths( void **context, ulong *lid,
@@ -73,18 +132,13 @@ void read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
                        byte *marginals,byte *completes,byte *cert_depth,
                        byte *min_cert_level);
 
-unsigned int get_ownertrust (PKT_public_key *pk);
-unsigned int get_min_ownertrust (PKT_public_key *pk);
+unsigned int tdb_get_ownertrust (PKT_public_key *pk);
+unsigned int tdb_get_min_ownertrust (PKT_public_key *pk);
 int get_ownertrust_info (PKT_public_key *pk);
 const char *get_ownertrust_string (PKT_public_key *pk);
 
-void update_ownertrust (PKT_public_key *pk, unsigned int new_trust );
-int clear_ownertrusts (PKT_public_key *pk);
-
-void clean_one_uid(KBNODE keyblock,KBNODE uidnode,int noisy,int self_only,
-                  int *uids_cleaned,int *sigs_cleaned);
-void clean_key(KBNODE keyblock,int noisy,int self_only,
-              int *uids_cleaned,int *sigs_cleaned);
+void tdb_update_ownertrust (PKT_public_key *pk, unsigned int new_trust);
+int tdb_clear_ownertrusts (PKT_public_key *pk);
 
 /*-- tdbdump.c --*/
 void list_trustdb(const char *username);
index 484fd9c..2d5aab4 100644 (file)
@@ -1,6 +1,6 @@
 /* verify.c - Verify signed data
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ *               2007, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -39,7 +39,6 @@
 #include "i18n.h"
 
 
-
 /****************
  * Assume that the input is a signature and verify it without
  * generating any output.  With no arguments, the signature packet
@@ -51,7 +50,7 @@
  */
 
 int
-verify_signatures( int nfiles, char **files )
+verify_signatures (ctrl_t ctrl, int nfiles, char **files )
 {
     IOBUF fp;
     armor_filter_context_t *afx = NULL;
@@ -81,9 +80,9 @@ verify_signatures( int nfiles, char **files )
      * case 4 with a file2 of "-".
      *
      * Actually we don't have to change anything here but can handle
-     * that all quite easily in mainproc.c 
+     * that all quite easily in mainproc.c
      */
-     
+
     sigfile = nfiles? *files : NULL;
 
     /* open the signature file */
@@ -92,12 +91,12 @@ verify_signatures( int nfiles, char **files )
       {
         iobuf_close (fp);
         fp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if( !fp ) {
         rc = gpg_error_from_syserror ();
-       log_error(_("can't open `%s': %s\n"),
-                  print_fname_stdin(sigfile), strerror (errno));
+       log_error(_("can't open '%s': %s\n"),
+                  print_fname_stdin(sigfile), gpg_strerror (rc));
         goto leave;
     }
     handle_progress (pfx, fp, sigfile);
@@ -111,7 +110,7 @@ verify_signatures( int nfiles, char **files )
     sl = NULL;
     for(i=nfiles-1 ; i > 0 ; i-- )
        add_to_strlist( &sl, files[i] );
-    rc = proc_signature_packets( NULL, fp, sl, sigfile );
+    rc = proc_signature_packets (ctrl, NULL, fp, sl, sigfile );
     free_strlist(sl);
     iobuf_close(fp);
     if( (afx && afx->no_openpgp_data && rc == -1) || rc == G10ERR_NO_DATA ) {
@@ -140,7 +139,7 @@ print_file_status( int status, const char *name, int what )
 
 
 static int
-verify_one_file( const char *name )
+verify_one_file (ctrl_t ctrl, const char *name )
 {
     IOBUF fp;
     armor_filter_context_t *afx = NULL;
@@ -150,16 +149,16 @@ verify_one_file( const char *name )
     print_file_status( STATUS_FILE_START, name, 1 );
     fp = iobuf_open(name);
     if (fp)
-      iobuf_ioctl (fp,3,1,NULL); /* disable fd caching */
+      iobuf_ioctl (fp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
     if (fp && is_secured_file (iobuf_get_fd (fp)))
       {
         iobuf_close (fp);
         fp = NULL;
-        errno = EPERM;
+        gpg_err_set_errno (EPERM);
       }
     if( !fp ) {
         rc = gpg_error_from_syserror ();
-       log_error(_("can't open `%s': %s\n"),
+       log_error(_("can't open '%s': %s\n"),
                   print_fname_stdin(name), strerror (errno));
        print_file_status( STATUS_FILE_ERROR, name, 1 );
         goto leave;
@@ -173,7 +172,7 @@ verify_one_file( const char *name )
        }
     }
 
-    rc = proc_signature_packets( NULL, fp, NULL, name );
+    rc = proc_signature_packets (ctrl, NULL, fp, NULL, name );
     iobuf_close(fp);
     write_status( STATUS_FILE_DONE );
 
@@ -191,7 +190,7 @@ verify_one_file( const char *name )
  * Note:  This function can not handle detached signatures.
  */
 int
-verify_files( int nfiles, char **files )
+verify_files (ctrl_t ctrl, int nfiles, char **files )
 {
     int i;
 
@@ -209,13 +208,13 @@ verify_files( int nfiles, char **files )
             * also no script languages available.  We don't strip any
             * spaces, so that we can process nearly all filenames */
            line[strlen(line)-1] = 0;
-           verify_one_file( line );
+           verify_one_file (ctrl, line );
        }
 
     }
     else {  /* take filenames from the array */
        for(i=0; i < nfiles; i++ )
-           verify_one_file( files[i] );
+            verify_one_file (ctrl, files[i] );
     }
     return 0;
 }
@@ -226,12 +225,12 @@ verify_files( int nfiles, char **files )
 /* Perform a verify operation.  To verify detached signatures, DATA_FD
    shall be the descriptor of the signed data; for regular signatures
    it needs to be -1.  If OUT_FP is not NULL and DATA_FD is not -1 the
-   the signed material gets written that stream. 
+   the signed material gets written that stream.
 
    FIXME: OUTFP is not yet implemented.
 */
 int
-gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, FILE *out_fp)
+gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp)
 {
   int rc;
   iobuf_t fp;
@@ -241,13 +240,14 @@ gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, FILE *out_fp)
   (void)ctrl;
   (void)out_fp;
 
-  fp = iobuf_fdopen (sig_fd, "rb");
-  if (fp && is_secured_file (sig_fd))
+  if (is_secured_file (sig_fd))
     {
       fp = NULL;
-      errno = EPERM;
+      gpg_err_set_errno (EPERM);
     }
-  if ( !fp )
+  else
+    fp = iobuf_fdopen_nc (sig_fd, "rb");
+  if (!fp)
     {
       rc = gpg_error_from_syserror ();
       log_error (_("can't open fd %d: %s\n"), sig_fd, strerror (errno));
@@ -262,17 +262,15 @@ gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, FILE *out_fp)
       push_armor_filter (afx, fp);
     }
 
-  rc = proc_signature_packets_by_fd ( NULL, fp, data_fd );
+  rc = proc_signature_packets_by_fd (ctrl, NULL, fp, data_fd);
 
   if ( afx && afx->no_openpgp_data
        && (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) )
     rc = gpg_error (GPG_ERR_NO_DATA);
 
- leave:  
-  if (fp)
-    iobuf_close (fp);
+ leave:
+  iobuf_close (fp);
   release_progress_context (pfx);
   release_armor_context (afx);
   return rc;
 }
-
similarity index 100%
rename from include/zlib-riscos.h
rename to g10/zlib-riscos.h
diff --git a/g13/ChangeLog-2011 b/g13/ChangeLog-2011
new file mode 100644 (file)
index 0000000..5d372c2
--- /dev/null
@@ -0,0 +1,14 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2009-11-04  Werner Koch  <wk@g10code.com>
+
+       Under initial development - no need for a ChangeLog.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/g13/Makefile.am b/g13/Makefile.am
new file mode 100644 (file)
index 0000000..745ec40
--- /dev/null
@@ -0,0 +1,47 @@
+# g13/Makefile.am
+# Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = ChangeLog-2011
+
+bin_PROGRAMS = g13
+
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
+
+include $(top_srcdir)/am/cmacros.am
+
+AM_CFLAGS =  $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
+
+g13_SOURCES = \
+       g13.c g13.h \
+       keyblob.h \
+       utils.c utils.h \
+       server.c server.h \
+       create.c create.h \
+       mount.c mount.h \
+       mountinfo.c mountinfo.h \
+       call-gpg.c call-gpg.h \
+       runner.c runner.h \
+       backend.c backend.h \
+       be-encfs.c be-encfs.h \
+       be-truecrypt.c be-truecrypt.h
+
+g13_LDADD = $(libcommonpth) ../gl/libgnu.a \
+       $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
+       $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
diff --git a/g13/backend.c b/g13/backend.c
new file mode 100644 (file)
index 0000000..7b08cd5
--- /dev/null
@@ -0,0 +1,134 @@
+/* backend.c - Dispatcher to the various backends.
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "g13.h"
+#include "i18n.h"
+#include "keyblob.h"
+#include "backend.h"
+#include "be-encfs.h"
+#include "be-truecrypt.h"
+
+
+static gpg_error_t
+no_such_backend (int conttype)
+{
+  log_error ("invalid backend %d given - this is most likely a bug\n",
+             conttype);
+  return gpg_error (GPG_ERR_INTERNAL);
+}
+
+
+/* Return true if CONTTYPE is supported by us.  */
+int
+be_is_supported_conttype (int conttype)
+{
+  switch (conttype)
+    {
+    case CONTTYPE_ENCFS:
+      return 1;
+
+    default:
+      return 0;
+    }
+}
+
+
+
+/* If the backend requires a separate file or directory for the
+   container, return its name by computing it from FNAME which gives
+   the g13 filename.  The new file name is allocated and stored at
+   R_NAME, if this is expected to be a directory true is stored at
+   R_ISDIR.  If no detached name is expected or an error occurs NULL
+   is stored at R_NAME. The function returns 0 on success or an error
+   code.  */
+gpg_error_t
+be_get_detached_name (int conttype, const char *fname,
+                      char **r_name, int *r_isdir)
+{
+  *r_name = NULL;
+  *r_isdir = 0;
+  switch (conttype)
+    {
+    case CONTTYPE_ENCFS:
+      return be_encfs_get_detached_name (fname, r_name, r_isdir);
+
+    default:
+      return no_such_backend (conttype);
+    }
+}
+
+
+gpg_error_t
+be_create_new_keys (int conttype, membuf_t *mb)
+{
+  switch (conttype)
+    {
+    case CONTTYPE_ENCFS:
+      return be_encfs_create_new_keys (mb);
+
+    case CONTTYPE_TRUECRYPT:
+      return be_truecrypt_create_new_keys (mb);
+
+    default:
+      return no_such_backend (conttype);
+    }
+}
+
+
+/*  Dispatcher to the backend's create function.  */
+gpg_error_t
+be_create_container (ctrl_t ctrl, int conttype,
+                     const char *fname, int fd, tupledesc_t tuples,
+                     unsigned int *r_id)
+{
+  (void)fd;  /* Not yet used.  */
+
+  switch (conttype)
+    {
+    case CONTTYPE_ENCFS:
+      return be_encfs_create_container (ctrl, fname, tuples, r_id);
+
+    default:
+      return no_such_backend (conttype);
+    }
+}
+
+
+/*  Dispatcher to the backend's mount function.  */
+gpg_error_t
+be_mount_container (ctrl_t ctrl, int conttype,
+                    const char *fname,  const char *mountpoint,
+                    tupledesc_t tuples, unsigned int *r_id)
+{
+  switch (conttype)
+    {
+    case CONTTYPE_ENCFS:
+      return be_encfs_mount_container (ctrl, fname, mountpoint, tuples, r_id);
+
+    default:
+      return no_such_backend (conttype);
+    }
+}
diff --git a/g13/backend.h b/g13/backend.h
new file mode 100644 (file)
index 0000000..20d2966
--- /dev/null
@@ -0,0 +1,41 @@
+/* backend.h - Defs for the dispatcher to the various backends.
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_BACKEND_H
+#define G13_BACKEND_H
+
+#include "../common/membuf.h"
+#include "utils.h"  /* For tupledesc_t */
+
+int         be_is_supported_conttype (int conttype);
+gpg_error_t be_get_detached_name (int conttype, const char *fname,
+                                  char **r_name, int *r_isdir);
+gpg_error_t be_create_new_keys (int conttype, membuf_t *mb);
+
+gpg_error_t be_create_container (ctrl_t ctrl, int conttype,
+                                 const char *fname, int fd,
+                                 tupledesc_t tuples,
+                                 unsigned int *r_id);
+gpg_error_t be_mount_container (ctrl_t ctrl, int conttype,
+                                const char *fname, const char *mountpoint,
+                                tupledesc_t tuples,
+                                unsigned int *r_id);
+
+
+#endif /*G13_BACKEND_H*/
diff --git a/g13/be-encfs.c b/g13/be-encfs.c
new file mode 100644 (file)
index 0000000..265b4c2
--- /dev/null
@@ -0,0 +1,470 @@
+/* be-encfs.c - The EncFS based backend
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "g13.h"
+#include "i18n.h"
+#include "keyblob.h"
+#include "be-encfs.h"
+#include "runner.h"
+#include "../common/exechelp.h"
+
+
+/* Command values used to run the encfs tool.  */
+enum encfs_cmds
+  {
+    ENCFS_CMD_CREATE,
+    ENCFS_CMD_MOUNT,
+    ENCFS_CMD_UMOUNT
+  };
+
+
+/* An object to keep the private state of the encfs tool.  It is
+   released by encfs_handler_cleanup.  */
+struct encfs_parm_s
+{
+  enum encfs_cmds cmd;  /* The current command. */
+  tupledesc_t tuples;   /* NULL or the tuples object.  */
+  char *mountpoint;     /* The mountpoint.  */
+};
+typedef struct encfs_parm_s *encfs_parm_t;
+
+
+static gpg_error_t
+send_cmd_bin (runner_t runner, const void *data, size_t datalen)
+{
+  return runner_send_line (runner, data, datalen);
+}
+
+
+static gpg_error_t
+send_cmd (runner_t runner, const char *string)
+{
+  log_debug ("sending command  -->%s<--\n", string);
+  return send_cmd_bin (runner, string, strlen (string));
+}
+
+
+
+static void
+run_umount_helper (const char *mountpoint)
+{
+  gpg_error_t err;
+  const char pgmname[] = FUSERMOUNT;
+  const char *args[3];
+
+  args[0] = "-u";
+  args[1] = mountpoint;
+  args[2] = NULL;
+
+  err = gnupg_spawn_process_detached (pgmname, args, NULL);
+  if (err)
+    log_error ("failed to run '%s': %s\n",
+               pgmname, gpg_strerror (err));
+}
+
+
+/* Handle one line of the encfs tool's output.  This function is
+   allowed to modify the content of BUFFER.  */
+static gpg_error_t
+handle_status_line (runner_t runner, const char *line,
+                    enum encfs_cmds cmd, tupledesc_t tuples)
+{
+  gpg_error_t err;
+
+  /* Check that encfs understands our new options.  */
+  if (!strncmp (line, "$STATUS$", 8))
+    {
+      for (line +=8; *line && spacep (line); line++)
+        ;
+      log_info ("got status '%s'\n", line);
+      if (!strcmp (line, "fuse_main_start"))
+        {
+          /* Send a special error code back to let the caller know
+             that everything has been setup by encfs.  */
+          err = gpg_error (GPG_ERR_UNFINISHED);
+        }
+      else
+        err = 0;
+    }
+  else if (!strncmp (line, "$PROMPT$", 8))
+    {
+      for (line +=8; *line && spacep (line); line++)
+        ;
+      log_info ("got prompt '%s'\n", line);
+      if (!strcmp (line, "create_root_dir"))
+        err = send_cmd (runner, cmd == ENCFS_CMD_CREATE? "y":"n");
+      else if (!strcmp (line, "create_mount_point"))
+        err = send_cmd (runner, "y");
+      else if (!strcmp (line, "passwd")
+               || !strcmp (line, "new_passwd"))
+        {
+          if (tuples)
+            {
+              size_t n;
+              const void *value;
+
+              value = find_tuple (tuples, KEYBLOB_TAG_ENCKEY, &n);
+              if (!value)
+                err = gpg_error (GPG_ERR_INV_SESSION_KEY);
+              else if ((err = send_cmd_bin (runner, value, n)))
+                {
+                  if (gpg_err_code (err) == GPG_ERR_BUG
+                      && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
+                    err = gpg_error (GPG_ERR_INV_SESSION_KEY);
+                }
+            }
+          else
+            err = gpg_error (GPG_ERR_NO_DATA);
+        }
+      else
+        err = send_cmd (runner, ""); /* Default to send an empty line.  */
+    }
+  else if (strstr (line, "encfs: unrecognized option '"))
+    err = gpg_error (GPG_ERR_INV_ENGINE);
+  else
+    err = 0;
+
+  return err;
+}
+
+
+/* The main processing function as used by the runner.  */
+static gpg_error_t
+encfs_handler (void *opaque, runner_t runner, const char *status_line)
+{
+  encfs_parm_t parm = opaque;
+  gpg_error_t err;
+
+  if (!parm || !runner)
+    return gpg_error (GPG_ERR_BUG);
+  if (!status_line)
+    {
+      /* Runner requested internal flushing - nothing to do here. */
+      return 0;
+    }
+
+  err = handle_status_line (runner, status_line, parm->cmd, parm->tuples);
+  if (gpg_err_code (err) == GPG_ERR_UNFINISHED
+      && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
+    {
+      err = 0;
+      /* No more need for the tuples.  */
+      destroy_tupledesc (parm->tuples);
+      parm->tuples = NULL;
+
+      if (parm->cmd == ENCFS_CMD_CREATE)
+        {
+          /* The encfs tool keeps on running after creation of the
+             container.  We don't want that and thus need to stop the
+             encfs process. */
+          run_umount_helper (parm->mountpoint);
+          /* In case the umount helper does not work we try to kill
+             the engine.  FIXME: We should figure out how to make
+             fusermount work.  */
+          runner_cancel (runner);
+        }
+    }
+
+  return err;
+}
+
+
+/* Called by the runner to cleanup the private data. */
+static void
+encfs_handler_cleanup (void *opaque)
+{
+  encfs_parm_t parm = opaque;
+
+  if (!parm)
+    return;
+
+  destroy_tupledesc (parm->tuples);
+  xfree (parm->mountpoint);
+  xfree (parm);
+}
+
+
+/* Run the encfs tool.  */
+static gpg_error_t
+run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd,
+                const char *rawdir, const char *mountpoint, tupledesc_t tuples,
+                unsigned int *r_id)
+{
+  gpg_error_t err;
+  encfs_parm_t parm;
+  runner_t runner = NULL;
+  int outbound[2] = { -1, -1 };
+  int inbound[2]  = { -1, -1 };
+  const char *pgmname;
+  const char *argv[10];
+  pid_t pid = (pid_t)(-1);
+  int idx;
+
+  (void)ctrl;
+
+  parm = xtrycalloc (1, sizeof *parm);
+  if (!parm)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  parm->cmd = cmd;
+  parm->tuples = ref_tupledesc (tuples);
+  parm->mountpoint = xtrystrdup (mountpoint);
+  if (!parm->mountpoint)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  err = runner_new (&runner, "encfs");
+  if (err)
+    goto leave;
+
+  err = gnupg_create_inbound_pipe (inbound);
+  if (!err)
+    err = gnupg_create_outbound_pipe (outbound);
+  if (err)
+    {
+      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  pgmname = ENCFS;
+  idx = 0;
+  argv[idx++] = "-f";
+  if (opt.verbose)
+    argv[idx++] = "-v";
+  argv[idx++] = "--stdinpass";
+  argv[idx++] = "--annotate";
+  argv[idx++] = rawdir;
+  argv[idx++] = mountpoint;
+  argv[idx++] = NULL;
+  assert (idx <= DIM (argv));
+
+  err = gnupg_spawn_process_fd (pgmname, argv,
+                                outbound[0], -1, inbound[1], &pid);
+  if (err)
+    {
+      log_error ("error spawning '%s': %s\n", pgmname, gpg_strerror (err));
+      goto leave;
+    }
+  close (outbound[0]); outbound[0] = -1;
+  close ( inbound[1]);  inbound[1] = -1;
+
+  runner_set_fds (runner, inbound[0], outbound[1]);
+  inbound[0] = -1;  /* Now owned by RUNNER.  */
+  outbound[1] = -1; /* Now owned by RUNNER.  */
+
+  runner_set_handler (runner, encfs_handler, encfs_handler_cleanup, parm);
+  parm = NULL; /* Now owned by RUNNER.  */
+
+  runner_set_pid (runner, pid);
+  pid = (pid_t)(-1); /* The process is now owned by RUNNER.  */
+
+  err = runner_spawn (runner);
+  if (err)
+    goto leave;
+
+  *r_id = runner_get_rid (runner);
+  log_info ("running '%s' in the background\n", pgmname);
+
+ leave:
+  if (inbound[0] != -1)
+    close (inbound[0]);
+  if (inbound[1] != -1)
+    close (inbound[1]);
+  if (outbound[0] != -1)
+    close (outbound[0]);
+  if (outbound[1] != -1)
+    close (outbound[1]);
+  if (pid != (pid_t)(-1))
+    {
+      gnupg_wait_process (pgmname, pid, 1, NULL);
+      gnupg_release_process (pid);
+    }
+  runner_release (runner);
+  encfs_handler_cleanup (parm);
+  return err;
+}
+
+
+
+
+\f
+/* See be_get_detached_name for a description.  Note that the
+   dispatcher code makes sure that NULL is stored at R_NAME before
+   calling us. */
+gpg_error_t
+be_encfs_get_detached_name (const char *fname, char **r_name, int *r_isdir)
+{
+  char *result;
+
+  if (!fname || !*fname)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  result = strconcat (fname, ".d", NULL);
+  if (!result)
+    return gpg_error_from_syserror ();
+  *r_name = result;
+  *r_isdir = 1;
+  return 0;
+}
+
+
+/* Create a new session key and append it as a tuple to the memory
+   buffer MB.
+
+   The EncFS daemon takes a passphrase from stdin and internally
+   mangles it by means of some KDF from OpenSSL.  We want to store a
+   binary key but we need to make sure that certain characters are not
+   used because the EncFS utility reads it from stdin and obviously
+   acts on some of the characters.  This we replace CR (in case of an
+   MSDOS version of EncFS), LF (the delimiter used by EncFS) and Nul
+   (because it is unlikely to work).  We use 32 bytes (256 bit)
+   because that is sufficient for the largest cipher (AES-256) and in
+   addition gives enough margin for a possible entropy degradation by
+   the KDF.  */
+gpg_error_t
+be_encfs_create_new_keys (membuf_t *mb)
+{
+  char *buffer;
+  int i, j;
+
+  /* Allocate a buffer of 32 bytes plus 8 spare bytes we may need to
+     replace the unwanted values.  */
+  buffer = xtrymalloc_secure (32+8);
+  if (!buffer)
+    return gpg_error_from_syserror ();
+
+  /* Randomize the buffer.  STRONG random should be enough as it is a
+     good compromise between security and performance.  The
+     anticipated usage of this tool is the quite often creation of new
+     containers and thus this should not deplete the system's entropy
+     tool too much.  */
+  gcry_randomize (buffer, 32+8, GCRY_STRONG_RANDOM);
+  for (i=j=0; i < 32; i++)
+    {
+      if (buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == 0 )
+        {
+          /* Replace.  */
+          if (j == 8)
+            {
+              /* Need to get more random.  */
+              gcry_randomize (buffer+32, 8, GCRY_STRONG_RANDOM);
+              j = 0;
+            }
+          buffer[i] = buffer[32+j];
+          j++;
+        }
+    }
+
+  /* Store the key.  */
+  append_tuple (mb, KEYBLOB_TAG_ENCKEY, buffer, 32);
+
+  /* Free the temporary buffer.  */
+  wipememory (buffer, 32+8);  /*  A failsafe extra wiping.  */
+  xfree (buffer);
+
+  return 0;
+}
+
+
+/* Create the container described by the filename FNAME and the keyblob
+   information in TUPLES. */
+gpg_error_t
+be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples,
+                           unsigned int *r_id)
+{
+  gpg_error_t err;
+  int dummy;
+  char *containername = NULL;
+  char *mountpoint = NULL;
+
+  err = be_encfs_get_detached_name (fname, &containername, &dummy);
+  if (err)
+    goto leave;
+
+  mountpoint = xtrystrdup ("/tmp/.#g13_XXXXXX");
+  if (!mountpoint)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  if (!mkdtemp (mountpoint))
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("can't create directory '%s': %s\n"),
+                 "/tmp/.#g13_XXXXXX", gpg_strerror (err));
+      goto leave;
+    }
+
+  err = run_encfs_tool (ctrl, ENCFS_CMD_CREATE, containername, mountpoint,
+                        tuples, r_id);
+
+  /* In any case remove the temporary mount point.  */
+  if (rmdir (mountpoint))
+    log_error ("error removing temporary mount point '%s': %s\n",
+               mountpoint, gpg_strerror (gpg_error_from_syserror ()));
+
+
+ leave:
+  xfree (containername);
+  xfree (mountpoint);
+  return err;
+}
+
+
+/* Mount the container described by the filename FNAME and the keyblob
+   information in TUPLES.  On success the runner id is stored at R_ID. */
+gpg_error_t
+be_encfs_mount_container (ctrl_t ctrl,
+                          const char *fname, const char *mountpoint,
+                          tupledesc_t tuples, unsigned int *r_id)
+{
+  gpg_error_t err;
+  int dummy;
+  char *containername = NULL;
+
+  if (!mountpoint)
+    {
+      log_error ("the encfs backend requires an explicit mountpoint\n");
+      err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      goto leave;
+    }
+
+  err = be_encfs_get_detached_name (fname, &containername, &dummy);
+  if (err)
+    goto leave;
+
+  err = run_encfs_tool (ctrl, ENCFS_CMD_MOUNT, containername, mountpoint,
+                        tuples, r_id);
+
+ leave:
+  xfree (containername);
+  return err;
+}
diff --git a/g13/be-encfs.h b/g13/be-encfs.h
new file mode 100644 (file)
index 0000000..744c16a
--- /dev/null
@@ -0,0 +1,41 @@
+/* be-encfs.h - Public defs for the EncFS based backend
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_BE_ENCFS_H
+#define G13_BE_ENCFS_H
+
+#include "backend.h"
+
+gpg_error_t be_encfs_get_detached_name (const char *fname,
+                                        char **r_name, int *r_isdir);
+gpg_error_t be_encfs_create_new_keys (membuf_t *mb);
+
+gpg_error_t be_encfs_create_container (ctrl_t ctrl,
+                                       const char *fname,
+                                       tupledesc_t tuples,
+                                       unsigned int *r_id);
+
+gpg_error_t be_encfs_mount_container (ctrl_t ctrl,
+                                      const char *fname,
+                                      const char *mountpoint,
+                                      tupledesc_t tuples,
+                                      unsigned int *r_id);
+
+
+#endif /*G13_BE_ENCFS_H*/
diff --git a/g13/be-truecrypt.c b/g13/be-truecrypt.c
new file mode 100644 (file)
index 0000000..9d75bdf
--- /dev/null
@@ -0,0 +1,37 @@
+/* be-truecrypt.c - The Truecrypt based backend
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "g13.h"
+#include "i18n.h"
+#include "be-truecrypt.h"
+
+
+gpg_error_t
+be_truecrypt_create_new_keys (membuf_t *mb)
+{
+  (void)mb;
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+}
diff --git a/g13/be-truecrypt.h b/g13/be-truecrypt.h
new file mode 100644 (file)
index 0000000..e98c989
--- /dev/null
@@ -0,0 +1,28 @@
+/* be-truecrypt.h - Public defs for the Truecrypt based backend
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_BE_TRUECRYPT_H
+#define G13_BE_TRUECRYPT_H
+
+#include "backend.h"
+
+gpg_error_t be_truecrypt_create_new_keys (membuf_t *mb);
+
+
+#endif /*G13_BE_TRUECRYPT_H*/
diff --git a/g13/call-gpg.c b/g13/call-gpg.c
new file mode 100644 (file)
index 0000000..54f6056
--- /dev/null
@@ -0,0 +1,592 @@
+/* call-gpg.c - Communication with the GPG
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <assert.h>
+#include <npth.h>
+
+#include "g13.h"
+#include <assuan.h>
+#include "i18n.h"
+#include "call-gpg.h"
+#include "utils.h"
+#include "../common/exechelp.h"
+
+
+\f
+/* Fire up a new GPG.  Handle the server's initial greeting.  Returns
+   0 on success and stores the assuan context at R_CTX.  */
+static gpg_error_t
+start_gpg (ctrl_t ctrl, int input_fd, int output_fd, assuan_context_t *r_ctx)
+{
+  gpg_error_t err;
+  assuan_context_t ctx = NULL;
+  const char *pgmname;
+  const char *argv[10];
+  int no_close_list[5];
+  int i;
+  char line[ASSUAN_LINELENGTH];
+
+  (void)ctrl;
+
+  *r_ctx = NULL;
+
+  err = assuan_new (&ctx);
+  if (err)
+    {
+      log_error ("can't allocate assuan context: %s\n", gpg_strerror (err));
+      return err;
+    }
+
+  /* The first time we are used, intialize the gpg_program variable.  */
+  if ( !opt.gpg_program || !*opt.gpg_program )
+    opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG);
+
+  if (opt.verbose)
+    log_info (_("no running gpg - starting '%s'\n"), opt.gpg_program);
+
+  /* Compute argv[0].  */
+  if ( !(pgmname = strrchr (opt.gpg_program, '/')))
+    pgmname = opt.gpg_program;
+  else
+    pgmname++;
+
+  if (fflush (NULL))
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error flushing pending output: %s\n", gpg_strerror (err));
+      return err;
+    }
+
+  i = 0;
+  argv[i++] = pgmname;
+  argv[i++] = "--server";
+  if ((opt.debug & 1024))
+    argv[i++] = "--debug=1024";
+  argv[i++] = "-z";
+  argv[i++] = "0";
+  argv[i++] = "--trust-model";
+  argv[i++] = "always";
+  argv[i++] = NULL;
+
+  i = 0;
+  if (log_get_fd () != -1)
+    no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
+  no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
+  if (input_fd != -1)
+    no_close_list[i++] = assuan_fd_from_posix_fd (input_fd);
+  if (output_fd != -1)
+    no_close_list[i++] = assuan_fd_from_posix_fd (output_fd);
+  no_close_list[i] = -1;
+
+  /* Connect to GPG and perform initial handshaking.  */
+  err = assuan_pipe_connect (ctx, opt.gpg_program, argv, no_close_list,
+                            NULL, NULL, 0);
+  if (err)
+    {
+      assuan_release (ctx);
+      log_error ("can't connect to GPG: %s\n", gpg_strerror (err));
+      return gpg_error (GPG_ERR_NO_ENGINE);
+    }
+
+  if (input_fd != -1)
+    {
+      snprintf (line, sizeof line, "INPUT FD=%d", input_fd);
+      err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        {
+          assuan_release (ctx);
+          log_error ("error sending INPUT command: %s\n", gpg_strerror (err));
+          return err;
+        }
+    }
+
+  if (output_fd != -1)
+    {
+      snprintf (line, sizeof line, "OUTPUT FD=%d", output_fd);
+      err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        {
+          assuan_release (ctx);
+          log_error ("error sending OUTPUT command: %s\n", gpg_strerror (err));
+          return err;
+        }
+    }
+
+  *r_ctx = ctx;
+
+  if (DBG_ASSUAN)
+    log_debug ("connection to GPG established\n");
+  return 0;
+}
+
+
+/* Release the assuan context created by start_gpg.  */
+static void
+release_gpg (assuan_context_t ctx)
+{
+  assuan_release (ctx);
+}
+
+
+\f
+/* The data passed to the writer_thread.  */
+struct writer_thread_parms
+{
+  int fd;
+  const void *data;
+  size_t datalen;
+  gpg_error_t *err_addr;
+};
+
+
+/* The thread started by start_writer.  */
+static void *
+writer_thread_main (void *arg)
+{
+  struct writer_thread_parms *parm = arg;
+  const char *buffer = parm->data;
+  size_t length = parm->datalen;
+
+  while (length)
+    {
+      ssize_t nwritten;
+
+      nwritten = npth_write (parm->fd, buffer, length < 4096? length:4096);
+      if (nwritten < 0)
+        {
+          if (errno == EINTR)
+            continue;
+          *parm->err_addr = gpg_error_from_syserror ();
+          break; /* Write error.  */
+        }
+      length -= nwritten;
+      buffer += nwritten;
+    }
+
+  if (close (parm->fd))
+    log_error ("closing writer fd %d failed: %s\n", parm->fd, strerror (errno));
+  xfree (parm);
+  return NULL;
+}
+
+
+/* Fire up a thread to send (DATA,DATALEN) to the file descriptor FD.
+   On success the thread receives the ownership over FD.  The thread
+   ID is stored at R_TID.  WRITER_ERR is the address of an gpg_error_t
+   variable to receive a possible write error after the thread has
+   finished.  */
+static gpg_error_t
+start_writer (int fd, const void *data, size_t datalen,
+              npth_t *r_thread, gpg_error_t *err_addr)
+{
+  gpg_error_t err;
+  struct writer_thread_parms *parm;
+  npth_attr_t tattr;
+  npth_t thread;
+  int ret;
+
+  memset (r_thread, '\0', sizeof (*r_thread));
+  *err_addr = 0;
+
+  parm = xtrymalloc (sizeof *parm);
+  if (!parm)
+    return gpg_error_from_syserror ();
+  parm->fd = fd;
+  parm->data = data;
+  parm->datalen = datalen;
+  parm->err_addr = err_addr;
+
+  npth_attr_init (&tattr);
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
+
+  ret = npth_create (&thread, &tattr, writer_thread_main, parm);
+  if (ret)
+    {
+      err = gpg_error_from_errno (ret);
+      log_error ("error spawning writer thread: %s\n", gpg_strerror (err));
+    }
+  else
+    {
+      npth_setname_np (thread, "fd-writer");
+      err = 0;
+      *r_thread = thread;
+    }
+  npth_attr_destroy (&tattr);
+
+  return err;
+}
+
+
+\f
+/* The data passed to the reader_thread.  */
+struct reader_thread_parms
+{
+  int fd;
+  membuf_t *mb;
+  gpg_error_t *err_addr;
+};
+
+
+/* The thread started by start_reader.  */
+static void *
+reader_thread_main (void *arg)
+{
+  struct reader_thread_parms *parm = arg;
+  char buffer[4096];
+  int nread;
+
+  while ( (nread = npth_read (parm->fd, buffer, sizeof buffer)) )
+    {
+      if (nread < 0)
+        {
+          if (errno == EINTR)
+            continue;
+          *parm->err_addr = gpg_error_from_syserror ();
+          break;  /* Read error.  */
+        }
+
+      put_membuf (parm->mb, buffer, nread);
+    }
+
+  if (close (parm->fd))
+    log_error ("closing reader fd %d failed: %s\n", parm->fd, strerror (errno));
+  xfree (parm);
+  return NULL;
+}
+
+
+/* Fire up a thread to receive data from the file descriptor FD.  On
+   success the thread receives the ownership over FD.  The thread ID
+   is stored at R_TID.  After the thread has finished an error from
+   the thread will be stored at ERR_ADDR.  */
+static gpg_error_t
+start_reader (int fd, membuf_t *mb, npth_t *r_thread, gpg_error_t *err_addr)
+{
+  gpg_error_t err;
+  struct reader_thread_parms *parm;
+  npth_attr_t tattr;
+  npth_t thread;
+  int ret;
+
+  memset (r_thread, '\0', sizeof (*r_thread));
+  *err_addr = 0;
+
+  parm = xtrymalloc (sizeof *parm);
+  if (!parm)
+    return gpg_error_from_syserror ();
+  parm->fd = fd;
+  parm->mb = mb;
+  parm->err_addr = err_addr;
+
+  npth_attr_init (&tattr);
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
+
+  ret = npth_create (&thread, &tattr, reader_thread_main, parm);
+  if (ret)
+    {
+      err = gpg_error_from_errno (ret);
+      log_error ("error spawning reader thread: %s\n", gpg_strerror (err));
+    }
+  else
+    {
+      npth_setname_np (thread, "fd-reader");
+      err = 0;
+      *r_thread = thread;
+    }
+  npth_attr_destroy (&tattr);
+
+  return err;
+}
+
+
+
+\f
+/* Call GPG to encrypt a block of data.
+
+
+ */
+gpg_error_t
+gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
+                  strlist_t keys, void **r_ciph, size_t *r_ciphlen)
+{
+  gpg_error_t err;
+  assuan_context_t ctx = NULL;
+  int outbound_fds[2] = { -1, -1 };
+  int inbound_fds[2]  = { -1, -1 };
+  npth_t writer_thread = (npth_t)0;
+  npth_t reader_thread = (npth_t)0;
+  gpg_error_t writer_err, reader_err;
+  membuf_t reader_mb;
+  char line[ASSUAN_LINELENGTH];
+  strlist_t sl;
+  int ret;
+
+  *r_ciph = NULL;
+  *r_ciphlen = 0;
+
+  /* Init the memory buffer to receive the encrypted stuff.  */
+  init_membuf (&reader_mb, 4096);
+
+  /* Create two pipes.  */
+  err = gnupg_create_outbound_pipe (outbound_fds);
+  if (!err)
+    err = gnupg_create_inbound_pipe (inbound_fds);
+  if (err)
+    {
+      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Start GPG and send the INPUT and OUTPUT commands.  */
+  err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
+  if (err)
+    goto leave;
+  close (outbound_fds[0]); outbound_fds[0] = -1;
+  close (inbound_fds[1]); inbound_fds[1] = -1;
+
+  /* Start a writer thread to feed the INPUT command of the server.  */
+  err = start_writer (outbound_fds[1], plain, plainlen,
+                      &writer_thread, &writer_err);
+  if (err)
+    return err;
+  outbound_fds[1] = -1;  /* The thread owns the FD now.  */
+
+  /* Start a reader thread to eat from the OUTPUT command of the
+     server.  */
+  err = start_reader (inbound_fds[0], &reader_mb,
+                      &reader_thread, &reader_err);
+  if (err)
+    return err;
+  outbound_fds[0] = -1;  /* The thread owns the FD now.  */
+
+  /* Run the encryption.  */
+  for (sl = keys; sl; sl = sl->next)
+    {
+      snprintf (line, sizeof line, "RECIPIENT -- %s", sl->d);
+      err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        {
+          log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
+                 gpg_strerror (err), gpg_strsource (err));
+          goto leave;
+        }
+    }
+
+  err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    {
+      log_error ("the engine's ENCRYPT command failed: %s <%s>\n",
+                 gpg_strerror (err), gpg_strsource (err));
+      goto leave;
+    }
+
+  /* Wait for reader and return the data.  */
+  ret = npth_join (reader_thread, NULL);
+  if (ret)
+    {
+      err = gpg_error_from_errno (ret);
+      log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+  /* FIXME: Not really valid, as npth_t is an opaque type.  */
+  memset (&reader_thread, '\0', sizeof (reader_thread));
+  if (reader_err)
+    {
+      err = reader_err;
+      log_error ("read error in reader thread: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Wait for the writer to catch  a writer error.  */
+  ret = npth_join (writer_thread, NULL);
+  if (ret)
+    {
+      err = gpg_error_from_errno (ret);
+      log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+  memset (&writer_thread, '\0', sizeof (writer_thread));
+  if (writer_err)
+    {
+      err = writer_err;
+      log_error ("write error in writer thread: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Return the data.  */
+  *r_ciph = get_membuf (&reader_mb, r_ciphlen);
+  if (!*r_ciph)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error while storing the data in the reader thread: %s\n",
+                 gpg_strerror (err));
+      goto leave;
+    }
+
+ leave:
+  /* FIXME: Not valid, as npth_t is an opaque type.  */
+  if (reader_thread)
+    npth_detach (reader_thread);
+  if (writer_thread)
+    npth_detach (writer_thread);
+  if (outbound_fds[0] != -1)
+    close (outbound_fds[0]);
+  if (outbound_fds[1] != -1)
+    close (outbound_fds[1]);
+  if (inbound_fds[0] != -1)
+    close (inbound_fds[0]);
+  if (inbound_fds[1] != -1)
+    close (inbound_fds[1]);
+  release_gpg (ctx);
+  xfree (get_membuf (&reader_mb, NULL));
+  return err;
+}
+
+
+\f
+/* Call GPG to decrypt a block of data.
+
+
+ */
+gpg_error_t
+gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen,
+                  void **r_plain, size_t *r_plainlen)
+{
+  gpg_error_t err;
+  assuan_context_t ctx = NULL;
+  int outbound_fds[2] = { -1, -1 };
+  int inbound_fds[2]  = { -1, -1 };
+  npth_t writer_thread = (npth_t)0;
+  npth_t reader_thread = (npth_t)0;
+  gpg_error_t writer_err, reader_err;
+  membuf_t reader_mb;
+  int ret;
+
+  *r_plain = NULL;
+  *r_plainlen = 0;
+
+  /* Init the memory buffer to receive the encrypted stuff.  */
+  init_membuf_secure (&reader_mb, 1024);
+
+  /* Create two pipes.  */
+  err = gnupg_create_outbound_pipe (outbound_fds);
+  if (!err)
+    err = gnupg_create_inbound_pipe (inbound_fds);
+  if (err)
+    {
+      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Start GPG and send the INPUT and OUTPUT commands.  */
+  err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
+  if (err)
+    goto leave;
+  close (outbound_fds[0]); outbound_fds[0] = -1;
+  close (inbound_fds[1]); inbound_fds[1] = -1;
+
+  /* Start a writer thread to feed the INPUT command of the server.  */
+  err = start_writer (outbound_fds[1], ciph, ciphlen,
+                      &writer_thread, &writer_err);
+  if (err)
+    return err;
+  outbound_fds[1] = -1;  /* The thread owns the FD now.  */
+
+  /* Start a reader thread to eat from the OUTPUT command of the
+     server.  */
+  err = start_reader (inbound_fds[0], &reader_mb,
+                      &reader_thread, &reader_err);
+  if (err)
+    return err;
+  outbound_fds[0] = -1;  /* The thread owns the FD now.  */
+
+  /* Run the decryption.  */
+  err = assuan_transact (ctx, "DECRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    {
+      log_error ("the engine's DECRYPT command failed: %s <%s>\n",
+                 gpg_strerror (err), gpg_strsource (err));
+      goto leave;
+    }
+
+  /* Wait for reader and return the data.  */
+  ret = npth_join (reader_thread, NULL);
+  if (ret)
+    {
+      err = gpg_error_from_errno (ret);
+      log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+  memset (&reader_thread, '\0', sizeof (reader_thread));
+  if (reader_err)
+    {
+      err = reader_err;
+      log_error ("read error in reader thread: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Wait for the writer to catch a writer error.  */
+  ret = npth_join (writer_thread, NULL);
+  if (ret)
+    {
+      err = gpg_error_from_errno (ret);
+      log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+  memset (&writer_thread, '\0', sizeof (writer_thread));
+  if (writer_err)
+    {
+      err = writer_err;
+      log_error ("write error in writer thread: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Return the data.  */
+  *r_plain = get_membuf (&reader_mb, r_plainlen);
+  if (!*r_plain)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error while storing the data in the reader thread: %s\n",
+                 gpg_strerror (err));
+      goto leave;
+    }
+
+ leave:
+  if (reader_thread)
+    npth_detach (reader_thread);
+  if (writer_thread)
+    npth_detach (writer_thread);
+  if (outbound_fds[0] != -1)
+    close (outbound_fds[0]);
+  if (outbound_fds[1] != -1)
+    close (outbound_fds[1]);
+  if (inbound_fds[0] != -1)
+    close (inbound_fds[0]);
+  if (inbound_fds[1] != -1)
+    close (inbound_fds[1]);
+  release_gpg (ctx);
+  xfree (get_membuf (&reader_mb, NULL));
+  return err;
+}
diff --git a/g13/call-gpg.h b/g13/call-gpg.h
new file mode 100644 (file)
index 0000000..339544d
--- /dev/null
@@ -0,0 +1,32 @@
+/* call-gpg.h - Defs for the communication with GPG
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_CALL_GPG_H
+#define G13_CALL_GPG_H
+
+gpg_error_t gpg_encrypt_blob (ctrl_t ctrl,
+                              const void *plain, size_t plainlen,
+                              strlist_t keys,
+                              void **r_ciph, size_t *r_ciphlen);
+gpg_error_t gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen,
+                              void **r_plain, size_t *r_plainlen);
+
+
+
+#endif /*G13_CALL_GPG_H*/
diff --git a/g13/create.c b/g13/create.c
new file mode 100644 (file)
index 0000000..58ab590
--- /dev/null
@@ -0,0 +1,324 @@
+/* create.c - Create a new crypto container
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#include "g13.h"
+#include "i18n.h"
+#include "create.h"
+
+#include "keyblob.h"
+#include "backend.h"
+#include "utils.h"
+#include "call-gpg.h"
+
+/* Create a new blob with all the session keys and other meta
+   information which are to be stored encrypted in the crypto
+   container header.  On success the malloced blob is stored at R_BLOB
+   and its length at R_BLOBLEN.  On error an error code is returned
+   and (R_BLOB,R_BLOBLEN) are set to (NULL,0).
+
+   The format of this blob is a sequence of tag-length-value tuples.
+   All tuples have this format:
+
+     2 byte TAG           Big endian unsigned integer (0..65535)
+                          described by the KEYBLOB_TAG_ constants.
+     2 byte LENGTH        Big endian unsigned integer (0..65535)
+                          giving the length of the value.
+     length bytes VALUE   The value described by the tag.
+
+   The first tag in a keyblob must be a BLOBVERSION.  The other tags
+   depend on the type of the container as described by the CONTTYPE
+   tag.  See keyblob.h for details.  */
+static gpg_error_t
+create_new_keyblob (ctrl_t ctrl, int is_detached,
+                    void **r_blob, size_t *r_bloblen)
+{
+  gpg_error_t err;
+  unsigned char twobyte[2];
+  membuf_t mb;
+
+  *r_blob = NULL;
+  *r_bloblen = 0;
+
+  init_membuf_secure (&mb, 512);
+
+  append_tuple (&mb, KEYBLOB_TAG_BLOBVERSION, "\x01", 1);
+
+  twobyte[0] = (ctrl->conttype >> 8);
+  twobyte[1] = (ctrl->conttype);
+  append_tuple (&mb, KEYBLOB_TAG_CONTTYPE, twobyte, 2);
+  if (is_detached)
+    append_tuple (&mb, KEYBLOB_TAG_DETACHED, NULL, 0);
+
+  err = be_create_new_keys (ctrl->conttype, &mb);
+  if (err)
+    goto leave;
+
+  /* Just for testing.  */
+  append_tuple (&mb, KEYBLOB_TAG_FILLER, "filler", 6);
+
+  *r_blob = get_membuf (&mb, r_bloblen);
+  if (!*r_blob)
+    {
+      err = gpg_error_from_syserror ();
+      *r_bloblen = 0;
+    }
+  else
+    log_debug ("used keyblob size is %zu\n", *r_bloblen);
+
+ leave:
+  xfree (get_membuf (&mb, NULL));
+  return err;
+}
+
+
+
+/* Encrypt the keyblob (KEYBLOB,KEYBLOBLEN) and store the result at
+   (R_ENCBLOB, R_ENCBLOBLEN).  Returns 0 on success or an error code.
+   On error R_EKYBLOB is set to NULL.  Depending on the keys set in
+   CTRL the result is a single OpenPGP binary message, a single
+   special OpenPGP packet encapsulating a CMS message or a
+   concatenation of both with the CMS packet being the last.  */
+static gpg_error_t
+encrypt_keyblob (ctrl_t ctrl, void *keyblob, size_t keybloblen,
+                 strlist_t keys,
+                 void **r_encblob, size_t *r_encbloblen)
+{
+  gpg_error_t err;
+
+  /* FIXME:  For now we only implement OpenPGP.  */
+  err = gpg_encrypt_blob (ctrl, keyblob, keybloblen, keys,
+                          r_encblob, r_encbloblen);
+
+  return err;
+}
+
+
+/* Write a new file under the name FILENAME with the keyblob and an
+   appropriate header.  This fucntion is called with a lock file in
+   place and after checking that the filename does not exists.  */
+static gpg_error_t
+write_keyblob (const char *filename,
+               const void *keyblob, size_t keybloblen)
+{
+  gpg_error_t err;
+  estream_t fp;
+  unsigned char packet[32];
+  size_t headerlen, paddinglen;
+
+  fp = es_fopen (filename, "wbx");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error creating new container '%s': %s\n",
+                 filename, gpg_strerror (err));
+      return err;
+    }
+
+  /* Allow for an least 8 times larger keyblob to accommodate for
+     future key changes.  Round it up to 4096 byte. */
+  headerlen = ((32 + 8 * keybloblen + 16) + 4095) / 4096 * 4096;
+  paddinglen = headerlen - 32 - keybloblen;
+  assert (paddinglen >= 16);
+
+  packet[0] = (0xc0|61); /* CTB for the private packet type 0x61.  */
+  packet[1] = 0xff;      /* 5 byte length packet, value 20.  */
+  packet[2] = 0;
+  packet[3] = 0;
+  packet[4] = 0;
+  packet[5] = 26;
+  memcpy (packet+6, "GnuPG/G13", 10); /* Packet subtype.  */
+  packet[16] = 1;   /* G13 packet format version.  */
+  packet[17] = 0;   /* Reserved.  */
+  packet[18] = 0;   /* Reserved.  */
+  packet[19] = 0;   /* OS Flag.  */
+  packet[20] = (headerlen >> 24);  /* Total length of header.  */
+  packet[21] = (headerlen >> 16);
+  packet[22] = (headerlen >> 8);
+  packet[23] = (headerlen);
+  packet[24] = 1;   /* Number of header copies.  */
+  packet[25] = 0;   /* Number of header copies at the end.  */
+  packet[26] = 0;   /* Reserved.  */
+  packet[27] = 0;   /* Reserved.  */
+  packet[28] = 0;   /* Reserved.  */
+  packet[29] = 0;   /* Reserved.  */
+  packet[30] = 0;   /* Reserved.  */
+  packet[31] = 0;   /* Reserved.  */
+
+  if (es_fwrite (packet, 32, 1, fp) != 1)
+    goto writeerr;
+
+  if (es_fwrite (keyblob, keybloblen, 1, fp) != 1)
+    goto writeerr;
+
+  /* Write the padding.  */
+  packet[0] = (0xc0|61); /* CTB for Private packet type 0x61.  */
+  packet[1] = 0xff;      /* 5 byte length packet, value 20.  */
+  packet[2] = (paddinglen-6) >> 24;
+  packet[3] = (paddinglen-6) >> 16;
+  packet[4] = (paddinglen-6) >> 8;
+  packet[5] = (paddinglen-6);
+  memcpy (packet+6, "GnuPG/PAD", 10); /* Packet subtype.  */
+  if (es_fwrite (packet, 16, 1, fp) != 1)
+    goto writeerr;
+  memset (packet, 0, 32);
+  for (paddinglen-=16; paddinglen >= 32; paddinglen -= 32)
+    if (es_fwrite (packet, 32, 1, fp) != 1)
+      goto writeerr;
+  if (paddinglen)
+    if (es_fwrite (packet, paddinglen, 1, fp) != 1)
+      goto writeerr;
+
+  if (es_fclose (fp))
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error closing '%s': %s\n",
+                 filename, gpg_strerror (err));
+      remove (filename);
+      return err;
+    }
+
+  return 0;
+
+
+ writeerr:
+  err = gpg_error_from_syserror ();
+  log_error ("error writing header to '%s': %s\n",
+             filename, gpg_strerror (err));
+  es_fclose (fp);
+  remove (filename);
+  return err;
+}
+
+
+
+/* Create a new container under the name FILENAME and intialize it
+   using the current settings.  KEYS is a list of public keys to which
+   the container will be encrypted.  If the file already exists an
+   error is returned.  */
+gpg_error_t
+g13_create_container (ctrl_t ctrl, const char *filename, strlist_t keys)
+{
+  gpg_error_t err;
+  dotlock_t lock;
+  void *keyblob = NULL;
+  size_t keybloblen;
+  void *enckeyblob = NULL;
+  size_t enckeybloblen;
+  char *detachedname = NULL;
+  int detachedisdir;
+  tupledesc_t tuples = NULL;
+  unsigned int dummy_rid;
+
+  if (!keys)
+    return gpg_error (GPG_ERR_NO_PUBKEY);
+
+  /* A quick check to see that no container with that name already
+     exists.  */
+  if (!access (filename, F_OK))
+    return gpg_error (GPG_ERR_EEXIST);
+
+  /* Take a lock and proceed with the creation.  If there is a lock we
+     immediately return an error because for creation it does not make
+     sense to wait.  */
+  lock = dotlock_create (filename, 0);
+  if (!lock)
+    return gpg_error_from_syserror ();
+  if (dotlock_take (lock, 0))
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  else
+    err = 0;
+
+  /* Check again that the file does not exist.  */
+  {
+      struct stat sb;
+
+      if (!stat (filename, &sb))
+        {
+          err = gpg_error (GPG_ERR_EEXIST);
+          goto leave;
+        }
+  }
+  /* And a possible detached file or directory may not exist either.  */
+  err = be_get_detached_name (ctrl->conttype, filename,
+                              &detachedname, &detachedisdir);
+  if (err)
+    goto leave;
+  if (detachedname)
+    {
+      struct stat sb;
+
+      if (!stat (detachedname, &sb))
+        {
+          err = gpg_error (GPG_ERR_EEXIST);
+          goto leave;
+        }
+    }
+
+  /* Create a new keyblob.  */
+  err = create_new_keyblob (ctrl, !!detachedname, &keyblob, &keybloblen);
+  if (err)
+    goto leave;
+
+  /* Encrypt that keyblob.  */
+  err = encrypt_keyblob (ctrl, keyblob, keybloblen, keys,
+                         &enckeyblob, &enckeybloblen);
+  if (err)
+    goto leave;
+
+  /* Put a copy of the keyblob into a tuple structure.  */
+  err = create_tupledesc (&tuples, keyblob, keybloblen);
+  if (err)
+    goto leave;
+  keyblob = NULL;
+  /* if (opt.verbose) */
+  /*   dump_keyblob (tuples); */
+
+  /* Write out the header, the encrypted keyblob and some padding. */
+  err = write_keyblob (filename, enckeyblob, enckeybloblen);
+  if (err)
+    goto leave;
+
+  /* Create and append the container.  FIXME: We should pass the
+     estream object in addition to the filename, so that the backend
+     can append the container to the g13 file.  */
+  err = be_create_container (ctrl, ctrl->conttype, filename, -1, tuples,
+                             &dummy_rid);
+
+
+ leave:
+  destroy_tupledesc (tuples);
+  xfree (detachedname);
+  xfree (enckeyblob);
+  xfree (keyblob);
+  dotlock_destroy (lock);
+
+  return err;
+}
diff --git a/g13/create.h b/g13/create.h
new file mode 100644 (file)
index 0000000..cc4ddfd
--- /dev/null
@@ -0,0 +1,27 @@
+/* create.h - Defs to create a new crypto container
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_CREATE_H
+#define G13_CREATE_H
+
+gpg_error_t g13_create_container (ctrl_t ctrl, const char *filename,
+                                  strlist_t keys);
+
+
+#endif /*G13_CREATE_H*/
diff --git a/g13/encfs-1.5_annotate.diff b/g13/encfs-1.5_annotate.diff
new file mode 100644 (file)
index 0000000..031147d
--- /dev/null
@@ -0,0 +1,293 @@
+2009-10-14  Werner Koch  <wk@gnupg.org>
+
+       * encfs/main.cpp (processArgs): Add option --annotate.
+       (EncFS_Args, processArgs): Support annotate option.
+       (main): Print status messages.
+       * encfs/FileUtils.h (EncFS_Opts): Add field ANNOTATE.
+       * encfs/FileUtils.cpp (userAllowMkdir): Add arg PROMPTNO.
+       (createV6Config): Add arg ANNOTATE.
+       (initFS): Pass it down.
+       * encfs/encfsctl.cpp (cmd_export): Adjust call to userAllowMkdir.
+       (do_chpasswd): Add arg ANNOTATE.
+       (chpasswd, chpasswdAutomaticly): Pass false for ANNOTATE.
+
+       * encfs/SSL_Cipher.cpp (TimedPBKDF2, newKey): Solve build
+       problems by using const_cast for SALT.  Suggested by Valient.
+
+
+diff -urp encfs-1.5.2.orig/encfs/FileUtils.cpp encfs-1.5.2/encfs/FileUtils.cpp
+--- encfs-1.5.2.orig/encfs/FileUtils.cpp       2008-09-10 07:53:58.000000000 +0200
++++ encfs-1.5.2/encfs/FileUtils.cpp    2009-10-12 19:29:12.000000000 +0200
+@@ -280,13 +280,24 @@ std::string parentDirectory( const std::
+       return path.substr(0, last);
+ }
+-bool userAllowMkdir( const char *path, mode_t mode )
++bool userAllowMkdir(int promptno, const char *path, mode_t mode )
+ {
+     // TODO: can we internationalize the y/n names?  Seems strange to prompt in
+     // their own language but then have to respond 'y' or 'n'.
+     // xgroup(setup)
+     cerr << autosprintf( _("The directory \"%s\" does not exist. Should it be created? (y,n) "), path );
+     char answer[10];
++    switch (promptno)
++    {
++      case 1:
++        cerr << endl << "$PROMPT$ create_root_dir" << endl;
++        break;
++      case 2:
++        cerr << endl << "$PROMPT$ create_mount_point" << endl;
++        break;
++      default:
++        break;
++    }
+     fgets( answer, sizeof(answer), stdin );
+     if(toupper(answer[0]) == 'Y')
+@@ -934,7 +945,7 @@ bool selectZeroBlockPassThrough()
+ RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir, 
+       bool enableIdleTracking, bool forceDecode,
+       const std::string &passwordProgram,
+-      bool useStdin, bool reverseEncryption )
++        bool useStdin, bool annotate, bool reverseEncryption )
+ {
+     RootPtr rootInfo;
+@@ -949,7 +960,10 @@ RootPtr createV6Config( EncFS_Context *c
+               " enter \"p\" for pre-configured paranoia mode,\n"
+               " anything else, or an empty line will select standard mode.\n"
+               "?> ");
+-    
++
++    if (annotate)
++      cerr << "$PROMPT$ config_option" << endl;
++
+     char answer[10] = {0};
+     fgets( answer, sizeof(answer), stdin );
+     cout << "\n";
+@@ -1135,7 +1149,11 @@ RootPtr createV6Config( EncFS_Context *c
+     CipherKey userKey;
+     rDebug( "useStdin: %i", useStdin );
+     if(useStdin)
++    {
++        if (annotate)
++          cerr << "$PROMPT$ new_passwd" << endl;
+       userKey = config.getUserKey( useStdin );
++    }
+     else if(!passwordProgram.empty())
+       userKey = config.getUserKey( passwordProgram, rootDir );
+     else
+@@ -1585,6 +1603,8 @@ RootPtr initFS( EncFS_Context *ctx, cons
+         if(opts->passwordProgram.empty())
+         {
+             rDebug( "useStdin: %i", opts->useStdin );
++            if (opts->annotate)
++              cerr << "$PROMPT$ passwd" << endl;
+             userKey = config.getUserKey( opts->useStdin );
+         } else
+             userKey = config.getUserKey( opts->passwordProgram, opts->rootDir );
+@@ -1649,7 +1669,7 @@ RootPtr initFS( EncFS_Context *ctx, cons
+           // creating a new encrypted filesystem
+           rootInfo = createV6Config( ctx, opts->rootDir, opts->idleTracking,
+                   opts->forceDecode, opts->passwordProgram, opts->useStdin,
+-                  opts->reverseEncryption );
++                    opts->annotate, opts->reverseEncryption );
+       }
+     }
+       
+diff -urp encfs-1.5.2.orig/encfs/FileUtils.h encfs-1.5.2/encfs/FileUtils.h
+--- encfs-1.5.2.orig/encfs/FileUtils.h 2008-08-23 23:48:12.000000000 +0200
++++ encfs-1.5.2/encfs/FileUtils.h      2009-10-12 19:29:55.000000000 +0200
+@@ -35,8 +35,9 @@ const char *lastPathElement( const char 
+ std::string parentDirectory( const std::string &path );
+ // ask the user for permission to create the directory.  If they say ok, then
+-// do it and return true.
+-bool userAllowMkdir( const char *dirPath, mode_t mode );
++// do it and return true.  If PROMPTNO is 1 show a prompt asking for
++// the root directory, if 2 ask for the mount point.
++bool userAllowMkdir(int promptno, const char *dirPath, mode_t mode );
+ enum ConfigType
+ {
+@@ -155,6 +156,7 @@ struct EncFS_Opts
+     std::string passwordProgram; // path to password program (or empty)
+     bool useStdin; // read password from stdin rather then prompting
++    bool annotate; // print annotation lines prompt to stderr.
+     bool ownerCreate; // set owner of new files to caller
+@@ -167,6 +169,7 @@ struct EncFS_Opts
+       checkKey = true;
+       forceDecode = false;
+       useStdin = false;
++        annotate = false;
+       ownerCreate = false;
+       reverseEncryption = false;
+     }
+diff -urp encfs-1.5.2.orig/encfs/SSL_Cipher.cpp encfs-1.5.2/encfs/SSL_Cipher.cpp
+--- encfs-1.5.2.orig/encfs/SSL_Cipher.cpp      2008-08-23 23:48:12.000000000 +0200
++++ encfs-1.5.2/encfs/SSL_Cipher.cpp   2009-10-12 11:23:25.000000000 +0200
+@@ -144,8 +144,10 @@ int TimedPBKDF2(const char *pass, int pa
+     for(;;)
+     {
+         gettimeofday( &start, 0 );
+-        int res = PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, 
+-                                    iter, keylen, out);
++        int res = PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, 
++                                         const_cast<unsigned char*>(salt), 
++                                         saltlen, 
++                                         iter, keylen, out);
+         if(res != 1)
+             return -1;
+@@ -423,9 +425,10 @@ CipherKey SSL_Cipher::newKey(const char 
+     } else
+     {
+         // known iteration length
+-        if(PKCS5_PBKDF2_HMAC_SHA1(password, passwdLength, salt, saltLen, 
+-                    iterationCount, _keySize + _ivLength, 
+-                    KeyData(key)) != 1)
++        if(PKCS5_PBKDF2_HMAC_SHA1(password, passwdLength,
++                                  const_cast<unsigned char*>(salt), saltLen, 
++                                  iterationCount, _keySize + _ivLength, 
++                                  KeyData(key)) != 1)
+         {
+             rWarning("openssl error, PBKDF2 failed");
+             return CipherKey();
+
+
+diff -urp encfs-1.5.2.orig/encfs/encfsctl.cpp encfs-1.5.2/encfs/encfsctl.cpp
+--- encfs-1.5.2.orig/encfs/encfsctl.cpp        2008-08-23 23:48:12.000000000 +0200
++++ encfs-1.5.2/encfs/encfsctl.cpp     2009-10-12 19:29:11.000000000 +0200
+@@ -564,7 +564,7 @@ static int cmd_export( int argc, char **
+     string destDir = argv[2];
+     // if the dir doesn't exist, then create it (with user permission)
+-    if(!checkDir(destDir) && !userAllowMkdir(destDir.c_str(), 0700))
++    if(!checkDir(destDir) && !userAllowMkdir(0, destDir.c_str(), 0700))
+       return EXIT_FAILURE;
+     return traverseDirs(rootInfo, "/", destDir);
+@@ -641,7 +641,7 @@ static int cmd_showcruft( int argc, char
+     return EXIT_SUCCESS;
+ }
+-static int do_chpasswd( bool useStdin, int argc, char **argv )
++static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
+ {
+     (void)argc;
+     string rootDir = argv[1];
+@@ -669,6 +669,8 @@ static int do_chpasswd( bool useStdin, i
+     // ask for existing password
+     cout << _("Enter current Encfs password\n");
++    if (annotate)
++      cerr << "$PROMPT$ passwd" << endl;
+     CipherKey userKey = config.getUserKey( useStdin );
+     if(!userKey)
+       return EXIT_FAILURE;
+@@ -690,7 +692,11 @@ static int do_chpasswd( bool useStdin, i
+     config.kdfIterations = 0; // generate new
+     if( useStdin )
++    {
++        if (annotate)
++            cerr << "$PROMPT$ new_passwd" << endl;
+       userKey = config.getUserKey( true );
++    }
+     else
+       userKey = config.getNewUserKey();
+@@ -729,12 +735,12 @@ static int do_chpasswd( bool useStdin, i
+ static int chpasswd( int argc, char **argv )
+ {
+-    return do_chpasswd( false, argc, argv );
++    return do_chpasswd( false, false, argc, argv );
+ }
+ static int chpasswdAutomaticly( int argc, char **argv )
+ {
+-    return do_chpasswd( true, argc, argv );
++    return do_chpasswd( true, false, argc, argv );
+ }
+diff -urp encfs-1.5.2.orig/encfs/main.cpp encfs-1.5.2/encfs/main.cpp
+--- encfs-1.5.2.orig/encfs/main.cpp    2008-08-06 08:36:13.000000000 +0200
++++ encfs-1.5.2/encfs/main.cpp 2009-10-14 14:19:09.000000000 +0200
+@@ -104,6 +104,7 @@ struct EncFS_Args
+       if(opts->forceDecode) ss << "(forceDecode) ";
+       if(opts->ownerCreate) ss << "(ownerCreate) ";
+       if(opts->useStdin) ss << "(useStdin) ";
++      if(opts->annotate) ss << "(annotate) ";
+       if(opts->reverseEncryption) ss << "(reverseEncryption) ";
+       if(opts->mountOnDemand) ss << "(mountOnDemand) ";
+       for(int i=0; i<fuseArgc; ++i)
+@@ -196,6 +197,7 @@ bool processArgs(int argc, char *argv[],
+     out->opts->forceDecode = false;
+     out->opts->ownerCreate = false;
+     out->opts->useStdin = false;
++    out->opts->annotate = false;
+     out->opts->reverseEncryption = false;
+  
+     bool useDefaultFlags = true;
+@@ -223,6 +225,7 @@ bool processArgs(int argc, char *argv[],
+       {"extpass", 1, 0, 'p'}, // external password program
+       // {"single-thread", 0, 0, 's'}, // single-threaded mode
+       {"stdinpass", 0, 0, 'S'}, // read password from stdin
++      {"annotate", 0, 0, 513}, // Print annotation lines to stderr
+       {"verbose", 0, 0, 'v'}, // verbose mode
+       {"version", 0, 0, 'V'}, //version
+       {"reverse", 0, 0, 'r'}, // reverse encryption
+@@ -255,6 +258,9 @@ bool processArgs(int argc, char *argv[],
+       case 'S':
+           out->opts->useStdin = true;
+           break;
++        case 513:
++            out->opts->annotate = true;
++            break;
+       case 'f':
+           out->isDaemon = false;
+           // this option was added in fuse 2.x
+@@ -403,13 +409,15 @@ bool processArgs(int argc, char *argv[],
+     // check that the directories exist, or that we can create them..
+     if(!isDirectory( out->opts->rootDir.c_str() ) && 
+-          !userAllowMkdir( out->opts->rootDir.c_str() ,0700))
++       !userAllowMkdir(out->opts->annotate? 1:0,
++                       out->opts->rootDir.c_str() ,0700))
+     {
+       rWarning(_("Unable to locate root directory, aborting."));
+       return false;
+     }
+     if(!isDirectory( out->mountPoint.c_str() ) && 
+-          !userAllowMkdir( out->mountPoint.c_str(),0700))
++       !userAllowMkdir(out->opts->annotate? 2:0,
++                       out->mountPoint.c_str(), 0700))
+     {
+       rWarning(_("Unable to locate mount point, aborting."));
+       return false;
+@@ -610,6 +618,9 @@ int main(int argc, char *argv[])
+       {
+           time_t startTime, endTime;
+          
++            if (encfsArgs->opts->annotate)
++              cerr << "$STATUS$ fuse_main_start" << endl;
++
+           // FIXME: workaround for fuse_main returning an error on normal
+           // exit.  Only print information if fuse_main returned
+           // immediately..
+@@ -622,6 +633,9 @@ int main(int argc, char *argv[])
+           
+           time( &endTime );
++            if (encfsArgs->opts->annotate)
++              cerr << "$STATUS$ fuse_main_end" << endl;
++
+           if(res == 0)
+               returnCode = EXIT_SUCCESS;
+
diff --git a/g13/encfs-1.7.3_annotate.diff b/g13/encfs-1.7.3_annotate.diff
new file mode 100644 (file)
index 0000000..0239538
--- /dev/null
@@ -0,0 +1,249 @@
+2010-11-10  Werner Koch  <wk@gnupg.org>
+
+        Port my patch for 1.5 dated 2009-10-14 to 1.7.3.
+
+       * encfs/main.cpp (processArgs): Add option --annotate.
+       (EncFS_Args, processArgs): Support annotate option.
+       (main): Print status messages.
+       * encfs/FileUtils.h (EncFS_Opts): Add field ANNOTATE.
+       * encfs/FileUtils.cpp (userAllowMkdir): Add arg PROMPTNO.
+       (createV6Config): Make use of ANNOTATE option.
+       (initFS): Ditto.
+       * encfs/encfsctl.cpp (cmd_export): Adjust call to userAllowMkdir.
+       (do_chpasswd): Add arg ANNOTATE.
+       (chpasswd, chpasswdAutomaticly): Pass false for ANNOTATE.
+
+
+diff -urpN orig/encfs-1.7.3/encfs/FileUtils.cpp encfs-1.7.3/encfs/FileUtils.cpp
+--- orig/encfs-1.7.3/encfs/FileUtils.cpp       2010-11-04 04:28:54.000000000 +0100
++++ encfs-1.7.3/encfs/FileUtils.cpp    2010-11-10 11:43:32.000000000 +0100
+@@ -314,14 +314,27 @@ std::string parentDirectory( const std::
+       return path.substr(0, last);
+ }
+-bool userAllowMkdir( const char *path, mode_t mode )
++bool userAllowMkdir(int promptno, const char *path, mode_t mode )
+ {
+     // TODO: can we internationalize the y/n names?  Seems strange to prompt in
+     // their own language but then have to respond 'y' or 'n'.
+     // xgroup(setup)
+     cerr << autosprintf( _("The directory \"%s\" does not exist. Should it be created? (y,n) "), path );
+     char answer[10];
+-    char *res = fgets( answer, sizeof(answer), stdin );
++    char *res;
++
++    switch (promptno)
++    {
++      case 1:
++        cerr << endl << "$PROMPT$ create_root_dir" << endl;
++        break;
++      case 2:
++        cerr << endl << "$PROMPT$ create_mount_point" << endl;
++        break;
++      default:
++        break;
++    }
++    res = fgets( answer, sizeof(answer), stdin );
+     if(res != 0 && toupper(answer[0]) == 'Y')
+     {
+@@ -976,6 +989,7 @@ RootPtr createV6Config( EncFS_Context *c
+     bool useStdin = opts->useStdin;
+     bool reverseEncryption = opts->reverseEncryption;
+     ConfigMode configMode = opts->configMode;
++    bool annotate = opts->annotate;
+     
+     RootPtr rootInfo;
+@@ -994,6 +1008,9 @@ RootPtr createV6Config( EncFS_Context *c
+                 " anything else, or an empty line will select standard mode.\n"
+                 "?> ");
+     
++        if (annotate)
++            cerr << "$PROMPT$ config_option" << endl;
++
+         char *res = fgets( answer, sizeof(answer), stdin );
+       (void)res;
+         cout << "\n";
+@@ -1179,7 +1196,11 @@ RootPtr createV6Config( EncFS_Context *c
+     CipherKey userKey;
+     rDebug( "useStdin: %i", useStdin );
+     if(useStdin)
++    {
++        if (annotate)
++            cerr << "$PROMPT$ new_passwd" << endl;
+         userKey = config->getUserKey( useStdin );
++    }
+     else if(!passwordProgram.empty())
+         userKey = config->getUserKey( passwordProgram, rootDir );
+     else
+@@ -1618,6 +1639,8 @@ RootPtr initFS( EncFS_Context *ctx, cons
+         if(opts->passwordProgram.empty())
+         {
+             rDebug( "useStdin: %i", opts->useStdin );
++            if (opts->annotate)
++                cerr << "$PROMPT$ passwd" << endl;
+             userKey = config->getUserKey( opts->useStdin );
+         } else
+             userKey = config->getUserKey( opts->passwordProgram, opts->rootDir );
+diff -urpN orig/encfs-1.7.3/encfs/FileUtils.h encfs-1.7.3/encfs/FileUtils.h
+--- orig/encfs-1.7.3/encfs/FileUtils.h 2010-09-05 22:47:01.000000000 +0200
++++ encfs-1.7.3/encfs/FileUtils.h      2010-11-10 11:45:16.000000000 +0100
+@@ -36,7 +36,7 @@ std::string parentDirectory( const std::
+ // ask the user for permission to create the directory.  If they say ok, then
+ // do it and return true.
+-bool userAllowMkdir( const char *dirPath, mode_t mode );
++bool userAllowMkdir(int promptno, const char *dirPath, mode_t mode );
+ class Cipher;
+ class DirNode;
+@@ -72,6 +72,7 @@ struct EncFS_Opts
+     std::string passwordProgram; // path to password program (or empty)
+     bool useStdin; // read password from stdin rather then prompting
++    bool annotate; // print annotation line prompt to stderr.
+     bool ownerCreate; // set owner of new files to caller
+@@ -87,6 +88,7 @@ struct EncFS_Opts
+         checkKey = true;
+         forceDecode = false;
+         useStdin = false;
++        annotate = false;
+         ownerCreate = false;
+         reverseEncryption = false;
+         configMode = Config_Prompt;
+diff -urpN orig/encfs-1.7.3/encfs/encfsctl.cpp encfs-1.7.3/encfs/encfsctl.cpp
+--- orig/encfs-1.7.3/encfs/encfsctl.cpp        2010-08-30 08:27:49.000000000 +0200
++++ encfs-1.7.3/encfs/encfsctl.cpp     2010-11-10 11:53:36.000000000 +0100
+@@ -616,7 +616,7 @@ static int cmd_export( int argc, char **
+     string destDir = argv[2];
+     // if the dir doesn't exist, then create it (with user permission)
+-    if(!checkDir(destDir) && !userAllowMkdir(destDir.c_str(), 0700))
++    if(!checkDir(destDir) && !userAllowMkdir(0, destDir.c_str(), 0700))
+       return EXIT_FAILURE;
+     return traverseDirs(rootInfo, "/", destDir);
+@@ -693,7 +693,7 @@ static int cmd_showcruft( int argc, char
+     return EXIT_SUCCESS;
+ }
+-static int do_chpasswd( bool useStdin, int argc, char **argv )
++static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
+ {
+     (void)argc;
+     string rootDir = argv[1];
+@@ -721,6 +721,8 @@ static int do_chpasswd( bool useStdin, i
+     // ask for existing password
+     cout << _("Enter current Encfs password\n");
++    if (annotate)
++        cerr << "$PROMPT$ passwd" << endl;
+     CipherKey userKey = config->getUserKey( useStdin );
+     if(!userKey)
+       return EXIT_FAILURE;
+@@ -742,7 +744,11 @@ static int do_chpasswd( bool useStdin, i
+     config->kdfIterations = 0; // generate new
+     if( useStdin )
++    {
++        if (annotate)
++            cerr << "$PROMPT$ new_passwd" << endl;
+         userKey = config->getUserKey( true );
++    }
+     else
+         userKey = config->getNewUserKey();
+@@ -781,12 +787,12 @@ static int do_chpasswd( bool useStdin, i
+ static int chpasswd( int argc, char **argv )
+ {
+-    return do_chpasswd( false, argc, argv );
++    return do_chpasswd( false, false, argc, argv );
+ }
+ static int chpasswdAutomaticly( int argc, char **argv )
+ {
+-    return do_chpasswd( true, argc, argv );
++    return do_chpasswd( true, false, argc, argv );
+ }
+diff -urpN orig/encfs-1.7.3/encfs/main.cpp encfs-1.7.3/encfs/main.cpp
+--- orig/encfs-1.7.3/encfs/main.cpp    2009-11-29 23:04:12.000000000 +0100
++++ encfs-1.7.3/encfs/main.cpp 2010-11-10 11:58:59.000000000 +0100
+@@ -104,6 +104,7 @@ struct EncFS_Args
+       if(opts->forceDecode) ss << "(forceDecode) ";
+       if(opts->ownerCreate) ss << "(ownerCreate) ";
+       if(opts->useStdin) ss << "(useStdin) ";
++        if(opts->annotate) ss << "(annotate) ";
+       if(opts->reverseEncryption) ss << "(reverseEncryption) ";
+       if(opts->mountOnDemand) ss << "(mountOnDemand) ";
+       for(int i=0; i<fuseArgc; ++i)
+@@ -196,6 +197,7 @@ bool processArgs(int argc, char *argv[],
+     out->opts->forceDecode = false;
+     out->opts->ownerCreate = false;
+     out->opts->useStdin = false;
++    out->opts->annotate = false;
+     out->opts->reverseEncryption = false;
+  
+     bool useDefaultFlags = true;
+@@ -223,6 +225,7 @@ bool processArgs(int argc, char *argv[],
+       {"extpass", 1, 0, 'p'}, // external password program
+       // {"single-thread", 0, 0, 's'}, // single-threaded mode
+       {"stdinpass", 0, 0, 'S'}, // read password from stdin
++        {"annotate", 0, 0, 513}, // Print annotation lines to stderr
+       {"verbose", 0, 0, 'v'}, // verbose mode
+       {"version", 0, 0, 'V'}, //version
+       {"reverse", 0, 0, 'r'}, // reverse encryption
+@@ -263,6 +266,9 @@ bool processArgs(int argc, char *argv[],
+       case 'S':
+           out->opts->useStdin = true;
+           break;
++        case 513:
++            out->opts->annotate = true;
++            break;
+       case 'f':
+           out->isDaemon = false;
+           // this option was added in fuse 2.x
+@@ -411,13 +417,15 @@ bool processArgs(int argc, char *argv[],
+     // check that the directories exist, or that we can create them..
+     if(!isDirectory( out->opts->rootDir.c_str() ) && 
+-          !userAllowMkdir( out->opts->rootDir.c_str() ,0700))
++       !userAllowMkdir(out->opts->annotate? 1:0,
++                       out->opts->rootDir.c_str() ,0700))
+     {
+       rWarning(_("Unable to locate root directory, aborting."));
+       return false;
+     }
+     if(!isDirectory( out->mountPoint.c_str() ) && 
+-          !userAllowMkdir( out->mountPoint.c_str(),0700))
++       !userAllowMkdir(out->opts->annotate? 2:0,
++                       out->mountPoint.c_str(),0700))
+     {
+       rWarning(_("Unable to locate mount point, aborting."));
+       return false;
+@@ -631,6 +639,9 @@ int main(int argc, char *argv[])
+       {
+           time_t startTime, endTime;
+          
++            if (encfsArgs->opts->annotate)
++                cerr << "$STATUS$ fuse_main_start" << endl;
++
+           // FIXME: workaround for fuse_main returning an error on normal
+           // exit.  Only print information if fuse_main returned
+           // immediately..
+@@ -643,6 +654,9 @@ int main(int argc, char *argv[])
+           
+           time( &endTime );
++            if (encfsArgs->opts->annotate)
++                cerr << "$STATUS$ fuse_main_end" << endl;
++
+           if(res == 0)
+               returnCode = EXIT_SUCCESS;
+
diff --git a/g13/g13.c b/g13/g13.c
new file mode 100644 (file)
index 0000000..8682114
--- /dev/null
+++ b/g13/g13.c
@@ -0,0 +1,979 @@
+/* g13.c - Disk Key management with GnuPG
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <npth.h>
+
+#include "g13.h"
+
+#include <gcrypt.h>
+#include <assuan.h>
+
+#include "i18n.h"
+#include "sysutils.h"
+#include "gc-opt-flags.h"
+#include "asshelp.h"
+#include "../common/init.h"
+#include "keyblob.h"
+#include "server.h"
+#include "runner.h"
+#include "create.h"
+#include "mount.h"
+#include "mountinfo.h"
+
+
+enum cmd_and_opt_values {
+  aNull = 0,
+  oQuiet       = 'q',
+  oVerbose     = 'v',
+  oRecipient   = 'r',
+
+  aGPGConfList  = 500,
+  aGPGConfTest,
+  aCreate,
+  aMount,
+  aUmount,
+  aServer,
+
+  oOptions,
+  oDebug,
+  oDebugLevel,
+  oDebugAll,
+  oDebugNone,
+  oDebugWait,
+  oDebugAllowCoreDump,
+  oLogFile,
+  oNoLogFile,
+  oAuditLog,
+
+  oOutput,
+
+  oAgentProgram,
+  oGpgProgram,
+
+  oDisplay,
+  oTTYname,
+  oTTYtype,
+  oLCctype,
+  oLCmessages,
+  oXauthority,
+
+  oStatusFD,
+  oLoggerFD,
+
+  oNoVerbose,
+  oNoSecmemWarn,
+  oNoGreeting,
+  oNoTTY,
+  oNoOptions,
+  oHomedir,
+  oWithColons,
+  oDryRun,
+  oNoDetach,
+
+  oNoRandomSeedFile,
+  oFakedSystemTime
+ };
+
+
+static ARGPARSE_OPTS opts[] = {
+
+  ARGPARSE_group (300, N_("@Commands:\n ")),
+
+  ARGPARSE_c (aCreate, "create", N_("Create a new file system container")),
+  ARGPARSE_c (aMount,  "mount",  N_("Mount a file system container") ),
+  ARGPARSE_c (aUmount, "umount", N_("Unmount a file system container") ),
+  ARGPARSE_c (aServer, "server", N_("Run in server mode")),
+
+  ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
+  ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
+
+  ARGPARSE_group (301, N_("@\nOptions:\n ")),
+
+  ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
+
+  ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
+  ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
+  ARGPARSE_s_n (oQuiet,        "quiet",  N_("be somewhat more quiet")),
+  ARGPARSE_s_n (oNoTTY, "no-tty", N_("don't use the terminal at all")),
+  ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
+  ARGPARSE_s_s (oLogFile, "log-file",  N_("|FILE|write log output to FILE")),
+  ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"),
+  ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"),
+
+  ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
+
+  ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")),
+
+  ARGPARSE_p_u (oDebug, "debug", "@"),
+  ARGPARSE_s_s (oDebugLevel, "debug-level",
+                N_("|LEVEL|set the debugging level to LEVEL")),
+  ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
+  ARGPARSE_s_n (oDebugNone, "debug-none", "@"),
+  ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
+  ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"),
+
+  ARGPARSE_s_i (oStatusFD, "status-fd",
+                N_("|FD|write status info to this FD")),
+
+  ARGPARSE_group (302, N_(
+  "@\n(See the man page for a complete listing of all commands and options)\n"
+  )),
+
+  ARGPARSE_group (303, N_("@\nExamples:\n\n"
+    " blurb\n"
+                          " blurb\n")),
+
+  /* Hidden options. */
+  ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
+  ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
+  ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
+  ARGPARSE_s_n (oNoOptions, "no-options", "@"),
+  ARGPARSE_s_s (oHomedir, "homedir", "@"),
+  ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
+  ARGPARSE_s_s (oGpgProgram, "gpg-program", "@"),
+  ARGPARSE_s_s (oDisplay,    "display", "@"),
+  ARGPARSE_s_s (oTTYname,    "ttyname", "@"),
+  ARGPARSE_s_s (oTTYtype,    "ttytype", "@"),
+  ARGPARSE_s_s (oLCctype,    "lc-ctype", "@"),
+  ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
+  ARGPARSE_s_s (oXauthority, "xauthority", "@"),
+  ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
+  ARGPARSE_s_n (oWithColons, "with-colons", "@"),
+  ARGPARSE_s_n (oNoRandomSeedFile,  "no-random-seed-file", "@"),
+
+  /* Command aliases.  */
+
+  ARGPARSE_end ()
+};
+
+
+/* The timer tick interval used by the idle task.  */
+#define TIMERTICK_INTERVAL_SEC     (1)
+
+
+/* Global variable to keep an error count. */
+int g13_errors_seen = 0;
+
+/* It is possible that we are currently running under setuid permissions.  */
+static int maybe_setuid = 1;
+
+/* Helper to implement --debug-level and --debug.  */
+static const char *debug_level;
+static unsigned int debug_value;
+
+/* Flag to indicate that a shutdown was requested.  */
+static int shutdown_pending;
+
+/* The thread id of the idle task.  */
+static npth_t idle_task_thread;
+
+
+\f
+static void set_cmd (enum cmd_and_opt_values *ret_cmd,
+                     enum cmd_and_opt_values new_cmd );
+
+static void emergency_cleanup (void);
+static void start_idle_task (void);
+static void join_idle_task (void);
+
+\f
+/* Begin NPth wrapper functions. */
+ASSUAN_SYSTEM_NPTH_IMPL;
+
+\f
+static const char *
+my_strusage( int level )
+{
+  const char *p;
+
+  switch (level)
+    {
+    case 11: p = "@G13@ (@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: @G13@ [options] [files] (-h for help)");
+      break;
+    case 41:
+      p = _("Syntax: @G13@ [options] [files]\n"
+            "Create, mount or unmount an encrypted file system container\n");
+      break;
+
+    case 31: p = "\nHome: "; break;
+    case 32: p = opt.homedir; break;
+
+    default: p = NULL; break;
+    }
+  return p;
+}
+
+
+static void
+wrong_args (const char *text)
+{
+  fprintf (stderr, _("usage: %s [options] "), G13_NAME);
+  fputs (text, stderr);
+  putc ('\n', stderr);
+  g13_exit (2);
+}
+
+
+/* Setup the debugging.  With a DEBUG_LEVEL of NULL only the active
+   debug flags are propagated to the subsystems.  With DEBUG_LEVEL
+   set, a specific set of debug flags is set; and individual debugging
+   flags will be added on top.  */
+static void
+set_debug (void)
+{
+  int numok = (debug_level && digitp (debug_level));
+  int numlvl = numok? atoi (debug_level) : 0;
+
+  if (!debug_level)
+    ;
+  else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
+    opt.debug = 0;
+  else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
+    opt.debug = DBG_ASSUAN_VALUE|DBG_MOUNT_VALUE;
+  else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
+    opt.debug = DBG_ASSUAN_VALUE|DBG_MOUNT_VALUE;
+  else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
+    opt.debug = (DBG_ASSUAN_VALUE|DBG_MOUNT_VALUE|DBG_CRYPTO_VALUE);
+  else if (!strcmp (debug_level, "guru") || numok)
+    {
+      opt.debug = ~0;
+      /* if (numok) */
+      /*   opt.debug &= ~(DBG_HASHING_VALUE); */
+    }
+  else
+    {
+      log_error (_("invalid debug-level '%s' given\n"), debug_level);
+      g13_exit(2);
+    }
+
+  opt.debug |= debug_value;
+
+  if (opt.debug && !opt.verbose)
+    opt.verbose = 1;
+  if (opt.debug)
+    opt.quiet = 0;
+
+  if (opt.debug & DBG_CRYPTO_VALUE )
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
+  gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
+
+  if (opt.debug)
+    log_info ("enabled debug flags:%s%s%s%s%s\n",
+              (opt.debug & DBG_MOUNT_VALUE  )? " mount":"",
+              (opt.debug & DBG_CRYPTO_VALUE )? " crypto":"",
+              (opt.debug & DBG_MEMORY_VALUE )? " memory":"",
+              (opt.debug & DBG_MEMSTAT_VALUE)? " memstat":"",
+              (opt.debug & DBG_ASSUAN_VALUE )? " assuan":"");
+}
+
+
+
+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
+    {
+      log_error (_("conflicting commands\n"));
+      g13_exit (2);
+    }
+
+  *ret_cmd = cmd;
+}
+
+
+int
+main ( int argc, char **argv)
+{
+  ARGPARSE_ARGS pargs;
+  int orig_argc;
+  char **orig_argv;
+  gpg_error_t err = 0;
+  /* const char *fname; */
+  int may_coredump;
+  FILE *configfp = NULL;
+  char *configname = NULL;
+  unsigned configlineno;
+  int parse_debug = 0;
+  int no_more_options = 0;
+  int default_config =1;
+  char *logfile = NULL;
+  int greeting = 0;
+  int nogreeting = 0;
+  /* int debug_wait = 0; */
+  int use_random_seed = 1;
+  /* int nodetach = 0; */
+  /* int nokeysetup = 0; */
+  enum cmd_and_opt_values cmd = 0;
+  struct server_control_s ctrl;
+  strlist_t recipients = NULL;
+
+  /*mtrace();*/
+
+  gnupg_reopen_std (G13_NAME);
+  set_strusage (my_strusage);
+  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+  log_set_prefix (G13_NAME, 1);
+
+  /* Make sure that our subsystems are ready.  */
+  i18n_init ();
+  init_common_subsystems (&argc, &argv);
+
+  npth_init ();
+
+  /* Check that the Libgcrypt is suitable.  */
+  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
+    log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
+               NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
+
+  /* Take extra care of the random pool.  */
+  gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
+
+  may_coredump = disable_core_dumps ();
+
+  gnupg_init_signals (0, emergency_cleanup);
+
+  dotlock_create (NULL, 0); /* Register locking cleanup.  */
+
+  opt.session_env = session_env_new ();
+  if (!opt.session_env)
+    log_fatal ("error allocating session environment block: %s\n",
+               strerror (errno));
+
+  opt.homedir = 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;
+    }
+
+  /* Initialize the secure memory. */
+  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+  maybe_setuid = 0;
+
+  /*
+     Now we are now working under our real uid
+  */
+
+  /* Setup malloc hooks. */
+  {
+    struct assuan_malloc_hooks malloc_hooks;
+
+    malloc_hooks.malloc = gcry_malloc;
+    malloc_hooks.realloc = gcry_realloc;
+    malloc_hooks.free = gcry_free;
+    assuan_set_malloc_hooks (&malloc_hooks);
+  }
+
+  /* Prepare libassuan.  */
+  assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
+  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
+  setup_libassuan_logging (&opt.debug);
+
+  /* Setup a default control structure for command line mode.  */
+  memset (&ctrl, 0, sizeof ctrl);
+  g13_init_default_ctrl (&ctrl);
+  ctrl.no_server = 1;
+  ctrl.status_fd = -1; /* No status output. */
+
+  /* Set the default option file */
+  if (default_config )
+    configname = make_filename (opt.homedir, G13_NAME".conf", 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));
+              g13_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:
+       case aGPGConfTest:
+          set_cmd (&cmd, pargs.r_opt);
+          nogreeting = 1;
+          /* nokeysetup = 1; */
+          break;
+
+        case aServer:
+        case aMount:
+        case aUmount:
+          /* nokeysetup = 1; */
+        case aCreate:
+          set_cmd (&cmd, pargs.r_opt);
+          break;
+
+        case oOutput: opt.outfile = pargs.r.ret_str; break;
+
+        case oQuiet: opt.quiet = 1; break;
+        case oNoGreeting: nogreeting = 1; break;
+        case oNoTTY:  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 oNoLogFile: logfile = NULL; break;
+
+        case oNoDetach: /*nodetach = 1; */break;
+
+        case oDebug: debug_value |= pargs.r.ret_ulong; break;
+        case oDebugAll: debug_value = ~0; break;
+        case oDebugNone: debug_value = 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 oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
+        case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
+
+        case oNoOptions: break; /* no-options */
+        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 oHomedir: opt.homedir = pargs.r.ret_str; break;
+
+        case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
+        case oGpgProgram: opt.gpg_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 oXauthority: opt.xauthority = xstrdup (pargs.r.ret_str); break;
+
+        case oFakedSystemTime:
+          {
+            time_t faked_time = isotime2epoch (pargs.r.ret_str);
+            if (faked_time == (time_t)(-1))
+              faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
+            gnupg_set_time (faked_time, 0);
+          }
+          break;
+
+        case oNoSecmemWarn: gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); break;
+
+        case oNoRandomSeedFile: use_random_seed = 0; break;
+
+        case oRecipient: /* Store the encryption key.  */
+          add_to_strlist (&recipients, pargs.r.ret_str);
+          break;
+
+
+        default:
+          pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
+          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, G13_NAME".conf", NULL);
+
+  if (log_get_errorcount(0))
+    g13_exit(2);
+
+  /* Now that we have the options parsed we need to update the default
+     control structure.  */
+  g13_init_default_ctrl (&ctrl);
+
+  if (nogreeting)
+    greeting = 0;
+
+  if (greeting)
+    {
+      fprintf (stderr, "%s %s; %s\n",
+               strusage(11), strusage(13), strusage(14) );
+      fprintf (stderr, "%s\n", strusage(15) );
+    }
+
+  if (may_coredump && !opt.quiet)
+    log_info (_("WARNING: program may create a core file!\n"));
+
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+    {
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
+    }
+
+
+  if (logfile)
+    {
+      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);
+      dump_isotime (tbuf);
+      log_printf ("\n");
+    }
+
+  /* Print any pending secure memory warnings.  */
+  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+  /* Setup the debug flags for all subsystems.  */
+  set_debug ();
+
+  /* Install a regular exit handler to make real sure that the secure
+     memory gets wiped out.  */
+  if (atexit (emergency_cleanup))
+    {
+      log_error ("atexit failed\n");
+      g13_exit (2);
+    }
+
+  /* Terminate if we found any error until now.  */
+  if (log_get_errorcount(0))
+    g13_exit (2);
+
+  /* Set the standard GnuPG 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);
+    }
+
+  /* Store given filename into FNAME. */
+  /* fname = argc? *argv : NULL; */
+
+  /* Parse all given encryption keys.  This does a lookup of the keys
+     and stops if any of the given keys was not found. */
+#if 0 /* Currently not implemented.  */
+  if (!nokeysetup)
+    {
+      strlist_t sl;
+      int failed = 0;
+
+      for (sl = recipients; sl; sl = sl->next)
+        if (check_encryption_key ())
+          failed = 1;
+      if (failed)
+        g13_exit (1);
+    }
+#endif /*0*/
+
+  /* Dispatch command.  */
+  err = 0;
+  switch (cmd)
+    {
+    case aGPGConfList:
+      { /* List options and default values in the GPG Conf format.  */
+       char *config_filename_esc = percent_escape (opt.config_filename, NULL);
+
+        printf ("gpgconf-g13.conf:%lu:\"%s\n",
+                GC_OPT_FLAG_DEFAULT, config_filename_esc);
+        xfree (config_filename_esc);
+
+        printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
+       printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE);
+       printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
+       printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
+      }
+      break;
+    case aGPGConfTest:
+      /* This is merely a dummy command to test whether the
+         configuration file is valid.  */
+      break;
+
+    case aServer:
+      {
+        start_idle_task ();
+        ctrl.no_server = 0;
+        err = g13_server (&ctrl);
+        if (err)
+          log_error ("server exited with error: %s <%s>\n",
+                     gpg_strerror (err), gpg_strsource (err));
+        else
+          shutdown_pending++;
+      }
+      break;
+
+    case aCreate: /* Create a new container. */
+      {
+        if (argc != 1)
+          wrong_args ("--create filename");
+        start_idle_task ();
+        err = g13_create_container (&ctrl, argv[0], recipients);
+        if (err)
+          log_error ("error creating a new container: %s <%s>\n",
+                     gpg_strerror (err), gpg_strsource (err));
+        else
+          shutdown_pending++;
+      }
+      break;
+
+    case aMount: /* Mount a container. */
+      {
+        if (argc != 1 && argc != 2 )
+          wrong_args ("--mount filename [mountpoint]");
+        start_idle_task ();
+        err = g13_mount_container (&ctrl, argv[0], argc == 2?argv[1]:NULL);
+        if (err)
+          log_error ("error mounting container '%s': %s <%s>\n",
+                     *argv, gpg_strerror (err), gpg_strsource (err));
+      }
+      break;
+
+    default:
+      log_error (_("invalid command (there is no implicit command)\n"));
+      break;
+    }
+
+  if (!err)
+    join_idle_task ();
+
+  /* Cleanup.  */
+  g13_exit (0);
+  return 8; /*NOTREACHED*/
+}
+
+
+/* Note: This function is used by signal handlers!. */
+static void
+emergency_cleanup (void)
+{
+  gcry_control (GCRYCTL_TERM_SECMEM );
+}
+
+
+void
+g13_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 : g13_errors_seen? 1 : 0;
+  exit (rc);
+}
+
+
+/* Store defaults into the per-connection CTRL object.  */
+void
+g13_init_default_ctrl (struct server_control_s *ctrl)
+{
+  ctrl->conttype = CONTTYPE_ENCFS;
+}
+
+
+/* This function is called for each signal we catch.  It is run in the
+   main context or the one of a NPth thread and thus it is not
+   restricted in what it may do.  */
+static void
+handle_signal (int signo)
+{
+  switch (signo)
+    {
+#ifndef HAVE_W32_SYSTEM
+    case SIGHUP:
+      log_info ("SIGHUP received - re-reading configuration\n");
+      /* Fixme:  Not yet implemented.  */
+      break;
+
+    case SIGUSR1:
+      log_info ("SIGUSR1 received - printing internal information:\n");
+      /* Fixme: We need to see how to integrate pth dumping into our
+         logging system.  */
+      /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
+      mountinfo_dump_all ();
+      break;
+
+    case SIGUSR2:
+      log_info ("SIGUSR2 received - no action defined\n");
+      break;
+
+    case SIGTERM:
+      if (!shutdown_pending)
+        log_info ("SIGTERM received - shutting down ...\n");
+      else
+        log_info ("SIGTERM received - still %u runners active\n",
+                  runner_get_threads ());
+      shutdown_pending++;
+      if (shutdown_pending > 2)
+        {
+          log_info ("shutdown forced\n");
+          log_info ("%s %s stopped\n", strusage(11), strusage(13) );
+          g13_exit (0);
+       }
+      break;
+
+    case SIGINT:
+      log_info ("SIGINT received - immediate shutdown\n");
+      log_info( "%s %s stopped\n", strusage(11), strusage(13));
+      g13_exit (0);
+      break;
+#endif /*!HAVE_W32_SYSTEM*/
+
+    default:
+      log_info ("signal %d received - no action defined\n", signo);
+    }
+}
+
+
+/* This ticker function is called about every TIMERTICK_INTERVAL_SEC
+   seconds. */
+static void
+handle_tick (void)
+{
+  /* log_debug ("TICK\n"); */
+}
+
+
+/* The idle task.  We use a separate thread to do idle stuff and to
+   catch signals.  */
+static void *
+idle_task (void *dummy_arg)
+{
+  int signo;           /* The number of a raised signal is stored here.  */
+  int saved_errno;
+  struct timespec abstime;
+  struct timespec curtime;
+  struct timespec timeout;
+  int ret;
+
+  (void)dummy_arg;
+
+  /* Create the event to catch the signals. */
+#ifndef HAVE_W32_SYSTEM
+  npth_sigev_init ();
+  npth_sigev_add (SIGHUP);
+  npth_sigev_add (SIGUSR1);
+  npth_sigev_add (SIGUSR2);
+  npth_sigev_add (SIGINT);
+  npth_sigev_add (SIGTERM);
+  npth_sigev_fini ();
+#endif
+
+  npth_clock_gettime (&abstime);
+  abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
+
+  for (;;)
+    {
+      /* The shutdown flag allows us to terminate the idle task.  */
+      if (shutdown_pending)
+        {
+          runner_cancel_all ();
+
+          if (!runner_get_threads ())
+            break; /* ready */
+       }
+
+      npth_clock_gettime (&curtime);
+      if (!(npth_timercmp (&curtime, &abstime, <)))
+       {
+         /* Timeout.  */
+         handle_tick ();
+         npth_clock_gettime (&abstime);
+         abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
+       }
+      npth_timersub (&abstime, &curtime, &timeout);
+
+#ifndef HAVE_W32_SYSTEM
+      ret = npth_pselect (0, NULL, NULL, NULL, &timeout, npth_sigev_sigmask());
+      saved_errno = errno;
+
+      while (npth_sigev_get_pending(&signo))
+       handle_signal (signo);
+#else
+      ret = npth_eselect (0, NULL, NULL, NULL, &timeout, NULL, NULL);
+      saved_errno = errno;
+#endif
+
+      if (ret == -1 && saved_errno != EINTR)
+       {
+          log_error (_("npth_pselect failed: %s - waiting 1s\n"),
+                     strerror (saved_errno));
+          npth_sleep (1);
+          continue;
+       }
+
+      if (ret <= 0)
+       /* Interrupt or timeout.  Will be handled when calculating the
+          next timeout.  */
+       continue;
+
+      /* Here one would add processing of file descriptors.  */
+    }
+
+  log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
+  return NULL;
+}
+
+
+/* Start the idle task.   */
+static void
+start_idle_task (void)
+{
+  npth_attr_t tattr;
+  npth_t thread;
+  sigset_t sigs;       /* The set of signals we want to catch.  */
+  int err;
+
+#ifndef HAVE_W32_SYSTEM
+  /* These signals should always go to the idle task, so they need to
+     be blocked everywhere else.  We assume start_idle_task is called
+     from the main thread before any other threads are created.  */
+  sigemptyset (&sigs);
+  sigaddset (&sigs, SIGHUP);
+  sigaddset (&sigs, SIGUSR1);
+  sigaddset (&sigs, SIGUSR2);
+  sigaddset (&sigs, SIGINT);
+  sigaddset (&sigs, SIGTERM);
+  npth_sigmask (SIG_BLOCK, &sigs, NULL);
+#endif
+
+  npth_attr_init (&tattr);
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
+
+  err = npth_create (&thread, &tattr, idle_task, NULL);
+  if (err)
+    {
+      log_fatal ("error starting idle task: %s\n", strerror (err));
+      return; /*NOTREACHED*/
+    }
+  npth_setname_np (thread, "idle-task");
+  idle_task_thread = thread;
+  npth_attr_destroy (&tattr);
+}
+
+
+/* Wait for the idle task to finish.  */
+static void
+join_idle_task (void)
+{
+  int err;
+
+  /* FIXME: This assumes that a valid pthread_t is non-null.  That is
+     not guaranteed.  */
+  if (idle_task_thread)
+    {
+      err = npth_join (idle_task_thread, NULL);
+      if (err)
+        log_error ("waiting for idle task thread failed: %s\n",
+                   strerror (err));
+    }
+}
diff --git a/g13/g13.h b/g13/g13.h
new file mode 100644 (file)
index 0000000..bdcc02a
--- /dev/null
+++ b/g13/g13.h
@@ -0,0 +1,112 @@
+/* g13.h - Global definitions for G13.
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_H
+#define G13_H
+
+#ifdef GPG_ERR_SOURCE_DEFAULT
+#error GPG_ERR_SOURCE_DEFAULT already defined
+#endif
+#define GPG_ERR_SOURCE_DEFAULT  GPG_ERR_SOURCE_G13
+#include <gpg-error.h>
+
+#include "../common/util.h"
+#include "../common/status.h"
+#include "../common/session-env.h"
+
+/* 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 dry_run;        /* Don't change any persistent data.  */
+
+  const char *homedir;         /* Configuration directory name.  */
+  const char *config_filename; /* Name of the used config file.  */
+
+  /* Filename of the AGENT program.  */
+  const char *agent_program;
+
+  /* Filename of the GPG program.  Unless set via an program option it
+     is initialzed at the first engine startup to the standard gpg
+     filename.  */
+  const char *gpg_program;
+
+  /* Environment variables passed along to the engine.  */
+  char *display;
+  char *ttyname;
+  char *ttytype;
+  char *lc_ctype;
+  char *lc_messages;
+  char *xauthority;
+  char *pinentry_user_data;
+  session_env_t session_env;
+
+  /* Name of the output file - FIXME: what is this?  */
+  const char *outfile;
+
+} opt;
+
+
+/* Debug values and macros.  */
+#define DBG_MOUNT_VALUE     1  /* Debug mount or device stuff. */
+#define DBG_CRYPTO_VALUE    4  /* Debug low level crypto.  */
+#define DBG_MEMORY_VALUE   32  /* Debug memory allocation stuff.  */
+#define DBG_MEMSTAT_VALUE 128  /* Show memory statistics.  */
+#define DBG_ASSUAN_VALUE  1024  /* Debug assuan communication.  */
+
+#define DBG_MOUNT    (opt.debug & DBG_MOUNT_VALUE)
+#define DBG_CRYPTO   (opt.debug & DBG_CRYPTO_VALUE)
+#define DBG_MEMORY   (opt.debug & DBG_MEMORY_VALUE)
+#define DBG_ASSUAN   (opt.debug & DBG_ASSUAN_VALUE)
+
+/* Forward declaration for an object defined in server.c.  */
+struct server_local_s;
+
+/* Session control object.  This object is passed down to most
+   functions.  The default values for it are set by
+   g13_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 agent_seen;     /* Flag indicating that the gpg-agent has been
+                         accessed.  */
+
+  int with_colons;    /* Use column delimited output format */
+
+  /* Type of the current container.  See the CONTTYPE_ constants.  */
+  int conttype;
+
+};
+
+
+\f
+/*-- g13.c --*/
+void g13_exit (int rc);
+void g13_init_default_ctrl (struct server_control_s *ctrl);
+
+/*-- server.c (commonly used, thus declared here) --*/
+gpg_error_t g13_status (ctrl_t ctrl, int no, ...) GNUPG_GCC_A_SENTINEL(0);
+
+
+#endif /*G13_H*/
diff --git a/g13/keyblob.h b/g13/keyblob.h
new file mode 100644 (file)
index 0000000..99d239f
--- /dev/null
@@ -0,0 +1,127 @@
+/* keyblob.h - Defs to describe a keyblob
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_KEYBLOB_H
+#define G13_KEYBLOB_H
+
+/* The header block is the actual core of G13.  Here is the format:
+
+   u8   Packet type.  Value is 61 (0x3d).
+   u8   Constant value 255 (0xff).
+   u32  Length of the following structure
+          b10  Value: "GnuPG/G13\x00".
+          u8   Version.  Value is 1.
+          u8   reserved
+          u8   reserved
+          u8   OS Flag:  reserved, should be 0.
+          u32  Length of the entire header.  This includes all bytes
+               starting at the packet type and ending with the last
+               padding byte of the header.
+          u8   Number of copies of this header (1..255).
+          u8   Number of copies of this header at the end of the
+               container (usually 0).
+          b6   reserved
+   n bytes: OpenPGP encrypted and optionally signed message.
+   n bytes: CMS encrypted and optionally signed packet.  Such a CMS
+            packet will be enclosed in a a private flagged OpenPGP
+            packet.  Either the OpenPGP encrypted packet as described
+            above, the CMS encrypted or both packets must exist.  The
+            encapsulation packet has this structure:
+                u8   Packet type.  Value is 61 (0x3d).
+                u8   Constant value 255 (0xff).
+                u32  Length of the following structure
+                b10  Value: "GnuPG/CMS\x00".
+                b(n) Regular CMS structure.
+   n bytes: Padding. The structure resembles an OpenPGP packet.
+                u8   Packet type.  Value is 61 (0x3d).
+                u8   Constant value 255 (0xff).
+                u32  Length of the following structure
+                b10  Value: "GnuPG/PAD\x00".
+                b(n) Padding stuff.
+            Given this structure the minimum padding is 16 bytes.
+
+   n bytes: File system container.
+   (optionally followed by copies on the header).
+*/
+
+\f
+#define KEYBLOB_TAG_BLOBVERSION 0
+/* This tag is used to describe the version of the keyblob.  It must
+   be the first tag in a keyblob and may only occur once.  Its value
+   is a single byte giving the blob version.  The only defined version
+   is 1.  */
+
+#define KEYBLOB_TAG_CONTTYPE 1
+/* This tag gives the type of the container.  The value is a two byte
+   big endian integer giving the type of the container as described by
+   the CONTTYPE_ constants.  */
+
+#define KEYBLOB_TAG_DETACHED 2
+/* Indicates that the actual storage is not in the same file as the
+   keyblob.  If a value is given it is expected to be the GUID of the
+   partition.  */
+
+#define KEYBLOB_TAG_KEYNO  16
+/* This tag indicates a new key.  The value is a 4 byte big endian
+   integer giving the key number.  If the container type does only
+   need one key this key number should be 0.  */
+
+#define KEYBLOB_TAG_ENCALGO  17
+/* Describes the algorithm of the key.  It must follow a KEYNO tag.
+   The value is a 2 byte big endian algorithm number.  The algorithm
+   numbers used are those from Libgcrypt (e.g. AES 128 is described by
+   the value 7).  This tag is optional.  */
+
+#define KEYBLOB_TAG_ENCKEY  18
+/* This tag gives the actual encryption key.  It must follow a KEYNO
+   tag.  The value is the plain key.  */
+
+#define KEYBLOB_TAG_MACALGO  19
+/* Describes the MAC algorithm.  It must follow a KEYNO tag.  The
+   value is a 2 byte big endian algorithm number describing the MAC
+   algorithm with a value of 1 indicating HMAC.  It is followed by
+   data specific to the MAC algorithm.  In case of HMAC this data is a
+   2 byte big endian integer with the Libgcrypt algorithm id of the
+   hash algorithm.  */
+
+#define KEYBLOB_TAG_MACKEY  20
+/* This tag gives the actual MACing key.  It must follow a KEYNO tag.
+   The value is the key used for MACing.  */
+
+
+#define KEYBLOB_TAG_FILLER   0xffff
+/* This tag may be used for alignment and padding porposes.  The value
+   has no meaning.  */
+
+
+\f
+#define CONTTYPE_ENCFS      1
+/* A EncFS based backend.  This requires a whole directory which
+   includes the encrypted files.  Metadata is not encrypted.  */
+
+
+#define CONTTYPE_TRUECRYPT  21571
+/* A Truecrypt (www.truecrypt.org) based container.  Due to the design
+   of truecrypt this requires a second datafile because it is not
+   possible to to prepend a truecrypt container with our keyblob.  */
+
+
+
+
+#endif /*G13_KEYBLOB_H*/
diff --git a/g13/mount.c b/g13/mount.c
new file mode 100644 (file)
index 0000000..512e29d
--- /dev/null
@@ -0,0 +1,415 @@
+/* mount.c - Mount a crypto container
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#include "g13.h"
+#include "i18n.h"
+#include "mount.h"
+
+#include "keyblob.h"
+#include "backend.h"
+#include "utils.h"
+#include "call-gpg.h"
+#include "mountinfo.h"
+#include "runner.h"
+
+
+/* Parse the header prefix and return the length of the entire header.  */
+static gpg_error_t
+parse_header (const char *filename,
+              const unsigned char *packet, size_t packetlen,
+              size_t *r_headerlen)
+{
+  unsigned int len;
+
+  if (packetlen != 32)
+    return gpg_error (GPG_ERR_BUG);
+
+  len = ((packet[2] << 24) | (packet[3] << 16)
+         | (packet[4] << 8) | packet[5]);
+  if (packet[0] != (0xc0|61) || len < 26
+      || memcmp (packet+6, "GnuPG/G13", 10))
+    {
+      log_error ("file '%s' is not valid container\n", filename);
+      return gpg_error (GPG_ERR_INV_OBJ);
+    }
+  if (packet[16] != 1)
+    {
+      log_error ("unknown version %u of container '%s'\n",
+                 (unsigned int)packet[16], filename);
+      return gpg_error (GPG_ERR_INV_OBJ);
+    }
+  if (packet[17] || packet[18]
+      || packet[26] || packet[27] || packet[28] || packet[29]
+      || packet[30] || packet[31])
+    log_info ("WARNING: unknown meta information in '%s'\n", filename);
+  if (packet[19])
+    log_info ("WARNING: OS flag is not supported in '%s'\n", filename);
+  if (packet[24] != 1 || packet[25] != 0)
+    {
+      log_error ("meta data copies in '%s' are not supported\n", filename);
+      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+    }
+
+  len = ((packet[20] << 24) | (packet[21] << 16)
+         | (packet[22] << 8) | packet[23]);
+
+  /* Do a basic sanity check on the length.  */
+  if (len < 32 || len > 1024*1024)
+    {
+      log_error ("bad length given in container '%s'\n", filename);
+      return gpg_error (GPG_ERR_INV_OBJ);
+    }
+
+  *r_headerlen = len;
+  return 0;
+}
+
+
+/* Read the prefix of the keyblob and do some basic parsing.  On
+   success returns an open estream file at R_FP and the length of the
+   header at R_HEADERLEN.  */
+static gpg_error_t
+read_keyblob_prefix (const char *filename, estream_t *r_fp, size_t *r_headerlen)
+{
+  gpg_error_t err;
+  estream_t fp;
+  unsigned char packet[32];
+
+  *r_fp = NULL;
+
+  fp = es_fopen (filename, "rb");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error reading '%s': %s\n", filename, gpg_strerror (err));
+      return err;
+    }
+
+  /* Read the header.  It is defined as 32 bytes thus we read it in one go.  */
+  if (es_fread (packet, 32, 1, fp) != 1)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error reading the header of '%s': %s\n",
+                 filename, gpg_strerror (err));
+      es_fclose (fp);
+      return err;
+    }
+
+  err = parse_header (filename, packet, 32, r_headerlen);
+  if (err)
+    es_fclose (fp);
+  else
+    *r_fp = fp;
+
+  return err;
+}
+
+
+/* Read the keyblob at FILENAME.  The caller should have acquired a
+   lockfile and checked that the file exists.  */
+static gpg_error_t
+read_keyblob (const char *filename,
+              void **r_enckeyblob, size_t *r_enckeybloblen)
+{
+  gpg_error_t err;
+  estream_t fp = NULL;
+  size_t headerlen, msglen;
+  void *msg = NULL;
+
+  *r_enckeyblob = NULL;
+  *r_enckeybloblen = 0;
+
+  err = read_keyblob_prefix (filename, &fp, &headerlen);
+  if (err)
+    goto leave;
+
+  if (opt.verbose)
+    log_info ("header length of '%s' is %zu\n", filename, headerlen);
+
+  /* Read everything including the padding.  We should eventually do a
+     regular OpenPGP parsing to detect the padding packet and pass
+     only the actual used OpenPGP data to the engine.  This is in
+     particular required when supporting CMS which will be
+     encapsulated in an OpenPGP packet.  */
+  assert (headerlen >= 32);
+  msglen = headerlen - 32;
+  if (!msglen)
+    {
+      err = gpg_error (GPG_ERR_NO_DATA);
+      goto leave;
+    }
+  msg = xtrymalloc (msglen);
+  if (!msglen)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  if (es_fread (msg, msglen, 1, fp) != 1)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error reading keyblob of '%s': %s\n",
+                 filename, gpg_strerror (err));
+      goto leave;
+    }
+
+  *r_enckeyblob = msg;
+  msg = NULL;
+  *r_enckeybloblen = msglen;
+
+ leave:
+  xfree (msg);
+  es_fclose (fp);
+
+  return err;
+}
+
+
+
+
+/* Decrypt the keyblob (ENCKEYBLOB,ENCKEYBLOBLEN) and store the result at
+   (R_KEYBLOB, R_KEYBLOBLEN).  Returns 0 on success or an error code.
+   On error R_KEYBLOB is set to NULL.  */
+static gpg_error_t
+decrypt_keyblob (ctrl_t ctrl, const void *enckeyblob, size_t enckeybloblen,
+                 void **r_keyblob, size_t *r_keybloblen)
+{
+  gpg_error_t err;
+
+  /* FIXME:  For now we only implement OpenPGP.  */
+  err = gpg_decrypt_blob (ctrl, enckeyblob, enckeybloblen,
+                          r_keyblob, r_keybloblen);
+
+  return err;
+}
+
+
+static void
+dump_keyblob (tupledesc_t tuples)
+{
+  size_t n;
+  unsigned int tag;
+  const void *value;
+
+  log_info ("keyblob dump:\n");
+  tag = KEYBLOB_TAG_BLOBVERSION;
+  value = find_tuple (tuples, tag, &n);
+  while (value)
+    {
+      log_info ("   tag: %-5u len: %-2u value: ", tag, (unsigned int)n);
+      if (tag == KEYBLOB_TAG_ENCKEY
+          ||  tag == KEYBLOB_TAG_MACKEY)
+        log_printf ("[confidential]\n");
+      else if (!n)
+        log_printf ("[none]\n");
+      else
+        log_printhex ("", value, n);
+      value = next_tuple (tuples, &tag, &n);
+    }
+}
+
+
+
+/* Mount the container with name FILENAME at MOUNTPOINT.  */
+gpg_error_t
+g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
+{
+  gpg_error_t err;
+  dotlock_t lock;
+  void *enckeyblob = NULL;
+  size_t enckeybloblen;
+  void *keyblob = NULL;
+  size_t keybloblen;
+  tupledesc_t tuples = NULL;
+  size_t n;
+  const unsigned char *value;
+  int conttype;
+  unsigned int rid;
+  char *mountpoint_buffer = NULL;
+
+  /* A quick check to see whether the container exists.  */
+  if (access (filename, R_OK))
+    return gpg_error_from_syserror ();
+
+  if (!mountpoint)
+    {
+      mountpoint_buffer = xtrystrdup ("/tmp/g13-XXXXXX");
+      if (!mountpoint_buffer)
+        return gpg_error_from_syserror ();
+      if (!mkdtemp (mountpoint_buffer))
+        {
+          err = gpg_error_from_syserror ();
+          log_error (_("can't create directory '%s': %s\n"),
+                     "/tmp/g13-XXXXXX", gpg_strerror (err));
+          xfree (mountpoint_buffer);
+          return err;
+        }
+      mountpoint = mountpoint_buffer;
+    }
+
+  /* Try to take a lock.  */
+  lock = dotlock_create (filename, 0);
+  if (!lock)
+    {
+      xfree (mountpoint_buffer);
+      return gpg_error_from_syserror ();
+    }
+
+  if (dotlock_take (lock, 0))
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  else
+    err = 0;
+
+  /* Check again that the file exists.  */
+  {
+    struct stat sb;
+
+    if (stat (filename, &sb))
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+  }
+
+  /* Read the encrypted keyblob.  */
+  err = read_keyblob (filename, &enckeyblob, &enckeybloblen);
+  if (err)
+    goto leave;
+
+  /* Decrypt that keyblob and store it in a tuple descriptor.  */
+  err = decrypt_keyblob (ctrl, enckeyblob, enckeybloblen,
+                         &keyblob, &keybloblen);
+  if (err)
+    goto leave;
+  xfree (enckeyblob);
+  enckeyblob = NULL;
+
+  err = create_tupledesc (&tuples, keyblob, keybloblen);
+  if (!err)
+    keyblob = NULL;
+  else
+    {
+      if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
+        log_error ("unknown keyblob version\n");
+      goto leave;
+    }
+  if (opt.verbose)
+    dump_keyblob (tuples);
+
+  value = find_tuple (tuples, KEYBLOB_TAG_CONTTYPE, &n);
+  if (!value || n != 2)
+    conttype = 0;
+  else
+    conttype = (value[0] << 8 | value[1]);
+  if (!be_is_supported_conttype (conttype))
+    {
+      log_error ("content type %d is not supported\n", conttype);
+      err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      goto leave;
+    }
+  err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples, &rid);
+  if (!err)
+    {
+      err = mountinfo_add_mount (filename, mountpoint, conttype, rid,
+                                 !!mountpoint_buffer);
+      /* Fixme: What shall we do if this fails?  Add a provisional
+         mountinfo entry first and remove it on error? */
+      if (!err)
+        {
+          char *tmp = percent_plus_escape (mountpoint);
+          if (!tmp)
+            err = gpg_error_from_syserror ();
+          else
+            {
+              g13_status (ctrl, STATUS_MOUNTPOINT, tmp, NULL);
+              xfree (tmp);
+            }
+        }
+    }
+
+ leave:
+  destroy_tupledesc (tuples);
+  xfree (keyblob);
+  xfree (enckeyblob);
+  dotlock_destroy (lock);
+  xfree (mountpoint_buffer);
+  return err;
+}
+
+
+/* Unmount the container with name FILENAME or the one mounted at
+   MOUNTPOINT.  If both are given the FILENAME takes precedence.  */
+gpg_error_t
+g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
+{
+  gpg_error_t err;
+  unsigned int rid;
+  runner_t runner;
+
+  (void)ctrl;
+
+  if (!filename && !mountpoint)
+    return gpg_error (GPG_ERR_ENOENT);
+  err = mountinfo_find_mount (filename, mountpoint, &rid);
+  if (err)
+    return err;
+
+  runner = runner_find_by_rid (rid);
+  if (!runner)
+    {
+      log_error ("runner %u not found\n", rid);
+      return gpg_error (GPG_ERR_NOT_FOUND);
+    }
+
+  runner_cancel (runner);
+  runner_release (runner);
+
+  return 0;
+}
+
+
+/* Test whether the container with name FILENAME is a suitable G13
+   container.  This function may even be called on a mounted
+   container.  */
+gpg_error_t
+g13_is_container (ctrl_t ctrl, const char *filename)
+{
+  gpg_error_t err;
+  estream_t fp = NULL;
+  size_t dummy;
+
+  (void)ctrl;
+
+  /* Read just the prefix of the header.  */
+  err = read_keyblob_prefix (filename, &fp, &dummy);
+  if (!err)
+    es_fclose (fp);
+  return err;
+}
diff --git a/g13/mount.h b/g13/mount.h
new file mode 100644 (file)
index 0000000..b2fe99e
--- /dev/null
@@ -0,0 +1,33 @@
+/* mount.h - Defs to mount a crypto container
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_MOUNT_H
+#define G13_MOUNT_H
+
+gpg_error_t g13_mount_container (ctrl_t ctrl,
+                                 const char *filename,
+                                 const char *mountpoint);
+gpg_error_t g13_umount_container (ctrl_t ctrl,
+                                  const char *filename,
+                                  const char *mountpoint);
+
+gpg_error_t g13_is_container (ctrl_t ctrl, const char *filename);
+
+
+#endif /*G13_MOUNT_H*/
diff --git a/g13/mountinfo.c b/g13/mountinfo.c
new file mode 100644 (file)
index 0000000..e2de8d9
--- /dev/null
@@ -0,0 +1,198 @@
+/* mountinfo.c - Track infos about mounts
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#include "g13.h"
+#include "i18n.h"
+#include "mountinfo.h"
+
+#include "keyblob.h"
+#include "utils.h"
+
+
+
+/* The object to keep track of mount information.  */
+struct mounttable_s
+{
+  int in_use;        /* The slot is in use.  */
+  char *container;   /* Name of the container.  */
+  char *mountpoint;  /* Name of the mounttype.  */
+  int conttype;      /* Type of the container.  */
+  unsigned int rid;  /* Identifier of the runner task.  */
+  struct {
+    unsigned int remove:1;  /* True if the mountpoint shall be removed
+                               on umount.  */
+  } flags;
+};
+
+
+/* The allocated table of mounts and its size.  */
+static mtab_t mounttable;
+size_t mounttable_size;
+
+
+\f
+/* Add CONTAINER,MOUNTPOINT,CONTTYPE,RID to the mounttable.  */
+gpg_error_t
+mountinfo_add_mount (const char *container, const char *mountpoint,
+                     int conttype, unsigned int rid, int remove_flag)
+{
+  size_t idx;
+  mtab_t m;
+
+  for (idx=0; idx < mounttable_size; idx++)
+    if (!mounttable[idx].in_use)
+      break;
+  if (!(idx < mounttable_size))
+    {
+      size_t nslots = mounttable_size;
+
+      mounttable_size += 10;
+      m = xtrycalloc (mounttable_size, sizeof *mounttable);
+      if (!m)
+        return gpg_error_from_syserror ();
+      if (mounttable)
+        {
+          for (idx=0; idx < nslots; idx++)
+            m[idx] = mounttable[idx];
+          xfree (mounttable);
+        }
+      mounttable = m;
+      m = mounttable + nslots;
+      assert (!m->in_use);
+    }
+  else
+    m = mounttable + idx;
+
+  m->container = xtrystrdup (container);
+  if (!m->container)
+    return gpg_error_from_syserror ();
+  m->mountpoint = xtrystrdup (mountpoint);
+  if (!m->mountpoint)
+    {
+      xfree (m->container);
+      m->container = NULL;
+      return gpg_error_from_syserror ();
+    }
+  m->conttype = conttype;
+  m->rid = rid;
+  m->flags.remove = !!remove_flag;
+  m->in_use = 1;
+
+  return 0;
+}
+
+
+/* Remove a mount info.  Either the CONTAINER, the MOUNTPOINT or the
+   RID must be given.  The first argument given is used.  */
+gpg_error_t
+mountinfo_del_mount (const char *container, const char *mountpoint,
+                     unsigned int rid)
+{
+  gpg_error_t err;
+  size_t idx;
+  mtab_t m;
+
+  /* If a container or mountpint is givem search the RID via the
+     standard find fucntion.  */
+  if (container || mountpoint)
+    {
+      err = mountinfo_find_mount (container, mountpoint, &rid);
+      if (err)
+        return err;
+    }
+
+  /* Find via RID and delete. */
+  for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
+    if (m->in_use && m->rid == rid)
+      {
+        if (m->flags.remove && m->mountpoint)
+          {
+            /* FIXME: This does not always work because the umount may
+               not have completed yet.  We should add the mountpoints
+               to an idle queue and retry a remove.  */
+            if (rmdir (m->mountpoint))
+              log_error ("error removing mount point '%s': %s\n",
+                         m->mountpoint,
+                         gpg_strerror (gpg_error_from_syserror ()));
+          }
+        m->in_use = 0;
+        xfree (m->container);
+        m->container = NULL;
+        xfree (m->mountpoint);
+        m->mountpoint = NULL;
+        return 0;
+      }
+  return gpg_error (GPG_ERR_NOT_FOUND);
+}
+
+
+/* Find a mount and return its rid at R_RID.  If CONTAINER is given,
+   the search is done by the container name, if it is not given the
+   search is done by MOUNTPOINT.  */
+gpg_error_t
+mountinfo_find_mount (const char *container, const char *mountpoint,
+                      unsigned int *r_rid)
+{
+  size_t idx;
+  mtab_t m;
+
+  if (container)
+    {
+      for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
+        if (m->in_use && !strcmp (m->container, container))
+          break;
+    }
+  else if (mountpoint)
+    {
+      for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
+        if (m->in_use && !strcmp (m->mountpoint, mountpoint))
+          break;
+    }
+  else
+    idx = mounttable_size;
+  if (!(idx < mounttable_size))
+    return gpg_error (GPG_ERR_NOT_FOUND);
+
+  *r_rid = m->rid;
+  return 0;
+}
+
+
+/* Dump all info to the log stream.  */
+void
+mountinfo_dump_all (void)
+{
+  size_t idx;
+  mtab_t m;
+
+  for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++)
+    if (m->in_use)
+      log_info ("mtab[%d] %s on %s type %d rid %u%s\n",
+                (int)idx, m->container, m->mountpoint, m->conttype, m->rid,
+                m->flags.remove?" [remove]":"");
+}
diff --git a/g13/mountinfo.h b/g13/mountinfo.h
new file mode 100644 (file)
index 0000000..95e95f5
--- /dev/null
@@ -0,0 +1,40 @@
+/* mountinfo.h - Track infos about mounts
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_MOUNTINFO_H
+#define G13_MOUNTINFO_H
+
+struct mounttable_s;
+typedef struct mounttable_s *mtab_t;
+
+gpg_error_t mountinfo_add_mount (const char *container,
+                                 const char *mountpoint,
+                                 int conttype, unsigned int rid,
+                                 int remove_flag);
+gpg_error_t mountinfo_del_mount (const char *container,
+                                 const char *mountpoint,
+                                 unsigned int rid);
+gpg_error_t mountinfo_find_mount (const char *container,
+                                  const char *mountpoint,
+                                  unsigned int *r_rid);
+
+void mountinfo_dump_all (void);
+
+
+#endif /*G13_MOUNTINFO_H*/
diff --git a/g13/runner.c b/g13/runner.c
new file mode 100644 (file)
index 0000000..905a0d1
--- /dev/null
@@ -0,0 +1,539 @@
+/* runner.c - Run and watch the backend engines
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <npth.h>
+
+#include "g13.h"
+#include "i18n.h"
+#include "keyblob.h"
+#include "runner.h"
+#include "../common/exechelp.h"
+#include "mountinfo.h"
+
+/* The runner object.  */
+struct runner_s
+{
+  char *name;              /* The name of this runner.  */
+  unsigned int identifier; /* The runner identifier.  */
+
+  int spawned;  /* True if runner_spawn has been called.  */
+  npth_t thread; /* The TID of the runner thread.  */
+  runner_t next_running; /* Builds a list of all running threads.  */
+  int canceled;     /* Set if a cancel has already been send once.  */
+
+  int cancel_flag;  /* If set the thread should terminate itself.  */
+
+
+  /* We use a reference counter to know when it is safe to remove the
+     object.  Lacking an explicit ref function this counter will take
+     only these two values:
+
+     1 = Thread not running or only the thread is still running.
+     2 = Thread is running and someone is holding a reference.  */
+  int refcount;
+
+  pid_t pid;  /* PID of the backend's process (the engine).  */
+  int in_fd;  /* File descriptors to read from the engine.  */
+  int out_fd; /* File descriptors to write to the engine.  */
+  engine_handler_fnc_t handler;  /* The handler functions.  */
+  engine_handler_cleanup_fnc_t handler_cleanup;
+  void *handler_data;  /* Private data of HANDLER and HANDLER_CLEANUP.  */
+
+  /* Instead of IN_FD we use an estream.  Note that the runner thread
+     may close the stream and set status_fp to NULL at any time.  Thus
+     it won't be a good idea to use it while the runner thread is
+     running.  */
+  estream_t status_fp;
+};
+
+
+/* The head of the list of all running threads.  */
+static runner_t running_threads;
+
+
+
+\f
+/* Write NBYTES of BUF to file descriptor FD. */
+static int
+writen (int fd, const void *buf, size_t nbytes)
+{
+  size_t nleft = nbytes;
+  int nwritten;
+
+  while (nleft > 0)
+    {
+      nwritten = npth_write (fd, buf, nleft);
+      if (nwritten < 0)
+        {
+          if (errno == EINTR)
+            nwritten = 0;
+          else
+            return -1;
+        }
+      nleft -= nwritten;
+      buf = (const char*)buf + nwritten;
+    }
+
+  return 0;
+}
+
+
+static int
+check_already_spawned (runner_t runner, const char *funcname)
+{
+  if (runner->spawned)
+    {
+      log_error ("BUG: runner already spawned - ignoring call to %s\n",
+                 funcname);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+
+/* Return the number of active threads.  */
+unsigned int
+runner_get_threads (void)
+{
+  unsigned int n = 0;
+  runner_t r;
+
+  for (r = running_threads; r; r = r->next_running)
+    n++;
+  return n;
+}
+
+
+/* The public release function. */
+void
+runner_release (runner_t runner)
+{
+  gpg_error_t err;
+
+  if (!runner)
+    return;
+
+  if (!--runner->refcount)
+    return;
+
+  err = mountinfo_del_mount (NULL, NULL, runner->identifier);
+  if (err)
+    log_error ("failed to remove mount with rid %u from mtab: %s\n",
+               runner->identifier, gpg_strerror (err));
+
+  es_fclose (runner->status_fp);
+  if (runner->in_fd != -1)
+    close (runner->in_fd);
+  if (runner->out_fd != -1)
+    close (runner->out_fd);
+
+  /* Fixme: close the process. */
+
+  /* Tell the engine to release its data.  */
+  if (runner->handler_cleanup)
+    runner->handler_cleanup (runner->handler_data);
+
+  if (runner->pid != (pid_t)(-1))
+    {
+      /* The process has not been cleaned up - do it now.  */
+      gnupg_kill_process (runner->pid);
+      /* (Actually we should use the program name and not the
+          arbitrary NAME of the runner object.  However it does not
+          matter because that information is only used for
+          diagnostics.)  */
+      gnupg_wait_process (runner->name, runner->pid, 1, NULL);
+      gnupg_release_process (runner->pid);
+    }
+
+  xfree (runner->name);
+  xfree (runner);
+}
+
+
+/* Create a new runner context.  On success a new runner object is
+   stored at R_RUNNER.  On failure NULL is stored at this address and
+   an error code returned.  */
+gpg_error_t
+runner_new (runner_t *r_runner, const char *name)
+{
+  static unsigned int namecounter; /* Global name counter.  */
+  char *namebuffer;
+  runner_t runner, r;
+
+  *r_runner = NULL;
+
+  runner = xtrycalloc (1, sizeof *runner);
+  if (!runner)
+    return gpg_error_from_syserror ();
+
+  /* Bump up the namecounter.  In case we ever had an overflow we
+     check that this number is currently not in use.  The algorithm is
+     a bit lame but should be sufficient because such an wrap is not
+     very likely: Assuming that we do a mount 10 times a second, then
+     we would overwrap on a 32 bit system after 13 years.  */
+  do
+    {
+      namecounter++;
+      for (r = running_threads; r; r = r->next_running)
+        if (r->identifier == namecounter)
+          break;
+    }
+  while (r);
+
+  runner->identifier = namecounter;
+  runner->name = namebuffer = xtryasprintf ("%s-%d", name, namecounter);
+  if (!runner->name)
+    {
+      xfree (runner);
+      return gpg_error_from_syserror ();
+    }
+  runner->refcount = 1;
+  runner->pid = (pid_t)(-1);
+  runner->in_fd = -1;
+  runner->out_fd = -1;
+
+  *r_runner = runner;
+  return 0;
+}
+
+
+/* Return the identifier of RUNNER.  */
+unsigned int
+runner_get_rid (runner_t runner)
+{
+  return runner->identifier;
+}
+
+
+/* Find a runner by its rid.  Returns the runner object.  The caller
+   must release the runner object.  */
+runner_t
+runner_find_by_rid (unsigned int rid)
+{
+  runner_t r;
+
+  for (r = running_threads; r; r = r->next_running)
+    if (r->identifier == rid)
+      {
+        r->refcount++;
+        return r;
+      }
+  return NULL;
+}
+
+
+/* A runner usually maintains two file descriptors to control the
+   backend engine.  This function is used to set these file
+   descriptors.  The function takes ownership of these file
+   descriptors.  IN_FD will be used to read from engine and OUT_FD to
+   send data to the engine. */
+void
+runner_set_fds (runner_t runner, int in_fd, int out_fd)
+{
+  if (check_already_spawned (runner, "runner_set_fds"))
+    return;
+
+  if (runner->in_fd != -1)
+    close (runner->in_fd);
+  if (runner->out_fd != -1)
+    close (runner->out_fd);
+  runner->in_fd = in_fd;
+  runner->out_fd = out_fd;
+}
+
+
+/* Set the PID of the backend engine.  After this call the engine is
+   owned by the runner object.  */
+void
+runner_set_pid (runner_t runner, pid_t pid)
+{
+  if (check_already_spawned (runner, "runner_set_fds"))
+    return;
+
+  runner->pid = pid;
+}
+
+
+/* Register the engine handler fucntions HANDLER and HANDLER_CLEANUP
+   and its private HANDLER_DATA with RUNNER.  */
+void
+runner_set_handler (runner_t runner,
+                    engine_handler_fnc_t handler,
+                    engine_handler_cleanup_fnc_t handler_cleanup,
+                    void *handler_data)
+{
+  if (check_already_spawned (runner, "runner_set_handler"))
+    return;
+
+  runner->handler = handler;
+  runner->handler_cleanup = handler_cleanup;
+  runner->handler_data = handler_data;
+}
+
+
+/* The thread spawned by runner_spawn.  */
+static void *
+runner_thread (void *arg)
+{
+  runner_t runner = arg;
+  gpg_error_t err = 0;
+
+  log_debug ("starting runner thread\n");
+  /* If a status_fp is available, the thread's main task is to read
+     from that stream and invoke the backend's handler function.  This
+     is done on a line by line base and the line length is limited to
+     a reasonable value (about 1000 characters). Other work will
+     continue either due to an EOF of the stream or by demand of the
+     engine.  */
+  if (runner->status_fp)
+    {
+      int c, cont_line;
+      unsigned int pos;
+      char buffer[1024];
+      estream_t fp = runner->status_fp;
+
+      pos = 0;
+      cont_line = 0;
+      while (!err && !runner->cancel_flag && (c=es_getc (fp)) != EOF)
+        {
+          buffer[pos++] = c;
+          if (pos >= sizeof buffer - 5 || c == '\n')
+            {
+              buffer[pos - (c == '\n')] = 0;
+              if (opt.verbose)
+                log_info ("%s%s: %s\n",
+                          runner->name, cont_line? "(cont)":"", buffer);
+              /* We handle only complete lines and ignore any stuff we
+                 possibly had to truncate.  That is - at least for the
+                 encfs engine - not an issue because our changes to
+                 the tool make sure that only relatively short prompt
+                 lines are of interest.  */
+              if (!cont_line && runner->handler)
+                err = runner->handler (runner->handler_data,
+                                       runner, buffer);
+              pos = 0;
+              cont_line = (c != '\n');
+            }
+        }
+      if (!err && runner->cancel_flag)
+        log_debug ("runner thread noticed cancel flag\n");
+      else
+        log_debug ("runner thread saw EOF\n");
+      if (pos)
+        {
+          buffer[pos] = 0;
+          if (opt.verbose)
+            log_info ("%s%s: %s\n",
+                      runner->name, cont_line? "(cont)":"", buffer);
+          if (!cont_line && !err && runner->handler)
+            err = runner->handler (runner->handler_data,
+                                          runner, buffer);
+        }
+      if (!err && es_ferror (fp))
+        {
+          err = gpg_error_from_syserror ();
+          log_error ("error reading from %s: %s\n",
+                     runner->name, gpg_strerror (err));
+        }
+
+      runner->status_fp = NULL;
+      es_fclose (fp);
+      log_debug ("runner thread closed status fp\n");
+    }
+
+  /* Now wait for the process to finish.  */
+  if (!err && runner->pid != (pid_t)(-1))
+    {
+      int exitcode;
+
+      log_debug ("runner thread waiting ...\n");
+      err = gnupg_wait_process (runner->name, runner->pid, 1, &exitcode);
+      gnupg_release_process (runner->pid);
+      runner->pid = (pid_t)(-1);
+      if (err)
+        log_error ("running '%s' failed (exitcode=%d): %s\n",
+                   runner->name, exitcode, gpg_strerror (err));
+      log_debug ("runner thread waiting finished\n");
+    }
+
+  /* Get rid of the runner object (note: it is refcounted).  */
+  log_debug ("runner thread releasing runner ...\n");
+  {
+    runner_t r, rprev;
+
+    for (r = running_threads, rprev = NULL; r; rprev = r, r = r->next_running)
+      if (r == runner)
+        {
+          if (!rprev)
+            running_threads = r->next_running;
+          else
+            rprev->next_running = r->next_running;
+          r->next_running = NULL;
+          break;
+        }
+  }
+  runner_release (runner);
+  log_debug ("runner thread runner released\n");
+
+  return NULL;
+}
+
+
+/* Spawn a new thread to let RUNNER work as a coprocess.  */
+gpg_error_t
+runner_spawn (runner_t runner)
+{
+  gpg_error_t err;
+  npth_attr_t tattr;
+  npth_t thread;
+  int ret;
+
+  if (check_already_spawned (runner, "runner_spawn"))
+    return gpg_error (GPG_ERR_BUG);
+
+  /* In case we have an input fd, open it as an estream so that the
+     Pth scheduling will work.  The stdio functions don't work with
+     Pth because they don't call the pth counterparts of read and
+     write unless linker tricks are used.  */
+  if (runner->in_fd != -1)
+    {
+      estream_t fp;
+
+      fp = es_fdopen (runner->in_fd, "r");
+      if (!fp)
+        {
+          err = gpg_error_from_syserror ();
+          log_error ("can't fdopen pipe for reading: %s\n", gpg_strerror (err));
+          return err;
+        }
+      runner->status_fp = fp;
+      runner->in_fd = -1;  /* Now owned by status_fp.  */
+    }
+
+  npth_attr_init (&tattr);
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+
+  ret = npth_create (&thread, &tattr, runner_thread, runner);
+  if (ret)
+    {
+      err = gpg_error_from_errno (ret);
+      log_error ("error spawning runner thread: %s\n", gpg_strerror (err));
+      return err;
+    }
+  npth_setname_np (thread, runner->name);
+
+  /* The scheduler has not yet kicked in, thus we can safely set the
+     spawned flag and the tid.  */
+  runner->spawned = 1;
+  runner->thread = thread;
+  runner->next_running = running_threads;
+  running_threads = runner;
+
+  npth_attr_destroy (&tattr);
+
+  /* The runner thread is now runnable.  */
+
+  return 0;
+}
+
+
+/* Cancel a running thread.  */
+void
+runner_cancel (runner_t runner)
+{
+  /* Warning: runner_cancel_all has knowledge of this code.  */
+  if (runner->spawned)
+    {
+      runner->canceled = 1;  /* Mark that we canceled this one already.  */
+      /* FIXME: This does only work if the thread emits status lines.  We
+         need to change the trhead to wait on an event.  */
+      runner->cancel_flag = 1;
+      /* For now we use the brutal way and kill the process. */
+      gnupg_kill_process (runner->pid);
+    }
+}
+
+
+/* Cancel all runner threads.  */
+void
+runner_cancel_all (void)
+{
+  runner_t r;
+
+  do
+    {
+      for (r = running_threads; r; r = r->next_running)
+        if (r->spawned && !r->canceled)
+          {
+            runner_cancel (r);
+            break;
+          }
+    }
+  while (r);
+}
+
+
+/* Send a line of data down to the engine.  This line may not contain
+   a binary Nul or a LF character.  This function is used by the
+   engine's handler.  */
+gpg_error_t
+runner_send_line (runner_t runner, const void *data, size_t datalen)
+{
+  gpg_error_t err = 0;
+
+  if (!runner->spawned)
+    {
+      log_error ("BUG: runner for %s not spawned\n", runner->name);
+      err = gpg_error (GPG_ERR_INTERNAL);
+    }
+  else if (runner->out_fd == -1)
+    {
+      log_error ("no output file descriptor for runner %s\n", runner->name);
+      err = gpg_error (GPG_ERR_EBADF);
+    }
+  else if (data && datalen)
+    {
+      if (memchr (data, '\n', datalen))
+        {
+          log_error ("LF detected in response data\n");
+          err = gpg_error (GPG_ERR_BUG);
+        }
+      else if (memchr (data, 0, datalen))
+        {
+          log_error ("Nul detected in response data\n");
+          err = gpg_error (GPG_ERR_BUG);
+        }
+      else if (writen (runner->out_fd, data, datalen))
+        err = gpg_error_from_syserror ();
+    }
+
+  if (!err)
+    if (writen (runner->out_fd, "\n", 1))
+      err = gpg_error_from_syserror ();
+
+  return err;
+}
diff --git a/g13/runner.h b/g13/runner.h
new file mode 100644 (file)
index 0000000..3c82143
--- /dev/null
@@ -0,0 +1,76 @@
+/* runner.h - Run and watch the backend engines
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_RUNNER_H
+#define G13_RUNNER_H
+
+/* The runner object.  */
+struct runner_s;
+typedef struct runner_s *runner_t;
+
+/* Prototypes for the handler functions provided by the engine.  */
+typedef gpg_error_t (*engine_handler_fnc_t) (void *opaque,
+                                             runner_t runner,
+                                             const char *statusline);
+typedef void (*engine_handler_cleanup_fnc_t) (void *opaque);
+
+
+/* Return the number of active threads.  */
+unsigned int runner_get_threads (void);
+
+/* Create a new runner object.  */
+gpg_error_t runner_new (runner_t *r_runner, const char *name);
+
+/* Free a runner object.  */
+void runner_release (runner_t runner);
+
+/* Return the identifier of RUNNER.  */
+unsigned int runner_get_rid (runner_t runner);
+
+/* Find a runner by its rid.  */
+runner_t runner_find_by_rid (unsigned int rid);
+
+/* Functions to set properties of the runner.  */
+void runner_set_fds (runner_t runner, int in_fd, int out_fd);
+
+void runner_set_pid (runner_t runner, pid_t pid);
+
+/* Register the handler functions with a runner.  */
+void runner_set_handler (runner_t runner,
+                         engine_handler_fnc_t handler,
+                         engine_handler_cleanup_fnc_t handler_cleanup,
+                         void *handler_data);
+
+/* Start the runner.  */
+gpg_error_t runner_spawn (runner_t runner);
+
+/* Cancel a runner.  */
+void runner_cancel (runner_t runner);
+
+/* Cancel all runner.  */
+void runner_cancel_all (void);
+
+/* Send data back to the engine.  This function is used by the
+   engine's handler.  */
+gpg_error_t runner_send_line (runner_t runner,
+                              const void *data, size_t datalen);
+
+
+
+#endif /*G13_RUNNER_H*/
diff --git a/g13/server.c b/g13/server.c
new file mode 100644 (file)
index 0000000..07b74f8
--- /dev/null
@@ -0,0 +1,751 @@
+/* server.c - The G13 Assuan server
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "g13.h"
+#include <assuan.h>
+#include "i18n.h"
+#include "keyblob.h"
+#include "server.h"
+#include "mount.h"
+#include "create.h"
+
+
+/* The filepointer for status message used in non-server mode */
+static FILE *statusfp;
+
+/* Local data for this server module.  A pointer to this is stored in
+   the CTRL object of each connection.  */
+struct server_local_s
+{
+  /* The Assuan contect we are working on.  */
+  assuan_context_t assuan_ctx;
+
+  char *containername;  /* Malloced active containername.  */
+
+  strlist_t recipients; /* List of recipients.  */
+};
+
+
+
+\f
+/* Local prototypes.  */
+static int command_has_option (const char *cmd, const char *cmdopt);
+
+
+
+\f
+/*
+   Helper functions.
+ */
+
+/* Set an error and a description.  */
+#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
+
+
+/* Skip over options.  Blanks after the options are also removed.  */
+static char *
+skip_options (const char *line)
+{
+  while (spacep (line))
+    line++;
+  while ( *line == '-' && line[1] == '-' )
+    {
+      while (*line && !spacep (line))
+        line++;
+      while (spacep (line))
+        line++;
+    }
+  return (char*)line;
+}
+
+
+/* Check whether the option NAME appears in LINE.  */
+/* static int */
+/* has_option (const char *line, const char *name) */
+/* { */
+/*   const char *s; */
+/*   int n = strlen (name); */
+
+/*   s = strstr (line, name); */
+/*   if (s && s >= skip_options (line)) */
+/*     return 0; */
+/*   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */
+/* } */
+
+
+/* Helper to print a message while leaving a command.  */
+static gpg_error_t
+leave_cmd (assuan_context_t ctx, gpg_error_t err)
+{
+  if (err)
+    {
+      const char *name = assuan_get_command_name (ctx);
+      if (!name)
+        name = "?";
+      if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
+        log_error ("command '%s' failed: %s\n", name,
+                   gpg_strerror (err));
+      else
+        log_error ("command '%s' failed: %s <%s>\n", name,
+                   gpg_strerror (err), gpg_strsource (err));
+    }
+  return err;
+}
+
+
+
+\f
+/* The handler for Assuan OPTION commands.  */
+static gpg_error_t
+option_handler (assuan_context_t ctx, const char *key, const char *value)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+
+  (void)ctrl;
+
+  if (!strcmp (key, "putenv"))
+    {
+      /* Change the session's environment to be used for the
+         Pinentry.  Valid values are:
+          <NAME>            Delete envvar NAME
+          <KEY>=            Set envvar NAME to the empty string
+          <KEY>=<VALUE>     Set envvar NAME to VALUE
+      */
+      err = session_env_putenv (opt.session_env, value);
+    }
+  else if (!strcmp (key, "display"))
+    {
+      err = session_env_setenv (opt.session_env, "DISPLAY", value);
+    }
+  else if (!strcmp (key, "ttyname"))
+    {
+      err = session_env_setenv (opt.session_env, "GPG_TTY", value);
+    }
+  else if (!strcmp (key, "ttytype"))
+    {
+      err = session_env_setenv (opt.session_env, "TERM", value);
+    }
+  else if (!strcmp (key, "lc-ctype"))
+    {
+      xfree (opt.lc_ctype);
+      opt.lc_ctype = xtrystrdup (value);
+      if (!opt.lc_ctype)
+        err = gpg_error_from_syserror ();
+    }
+  else if (!strcmp (key, "lc-messages"))
+    {
+      xfree (opt.lc_messages);
+      opt.lc_messages = xtrystrdup (value);
+      if (!opt.lc_messages)
+        err = gpg_error_from_syserror ();
+    }
+  else if (!strcmp (key, "xauthority"))
+    {
+      err = session_env_setenv (opt.session_env, "XAUTHORITY", value);
+    }
+  else if (!strcmp (key, "pinentry-user-data"))
+    {
+      err = session_env_setenv (opt.session_env, "PINENTRY_USER_DATA", value);
+    }
+  else if (!strcmp (key, "allow-pinentry-notify"))
+    {
+      ; /* We always allow it.  */
+    }
+  else
+    err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
+
+  return err;
+}
+
+
+/* The handler for an Assuan RESET command.  */
+static gpg_error_t
+reset_notify (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+
+  (void)line;
+
+  xfree (ctrl->server_local->containername);
+  ctrl->server_local->containername = NULL;
+
+  FREE_STRLIST (ctrl->server_local->recipients);
+
+  assuan_close_input_fd (ctx);
+  assuan_close_output_fd (ctx);
+  return 0;
+}
+
+
+static const char hlp_open[] =
+  "OPEN [<options>] <filename>\n"
+  "\n"
+  "Open the container FILENAME.  FILENAME must be percent-plus\n"
+  "escaped.  A quick check to see whether this is a suitable G13\n"
+  "container file is done.  However no cryptographic check or any\n"
+  "other check is done.  This command is used to define the target for\n"
+  "further commands.  The filename is reset with the RESET command,\n"
+  "another OPEN or the CREATE command.";
+static gpg_error_t
+cmd_open (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+  char *p, *pend;
+  size_t len;
+
+  /* In any case reset the active container.  */
+  xfree (ctrl->server_local->containername);
+  ctrl->server_local->containername = NULL;
+
+  /* Parse the line.  */
+  line = skip_options (line);
+  for (p=line; *p && !spacep (p); p++)
+    ;
+  pend = p;
+  while (spacep(p))
+    p++;
+  if (*p || pend == line)
+    {
+      err = gpg_error (GPG_ERR_ASS_SYNTAX);
+      goto leave;
+    }
+  *pend = 0;
+
+  /* Unescape the line and check for embedded Nul bytes.  */
+  len = percent_plus_unescape_inplace (line, 0);
+  line[len] = 0;
+  if (!len || memchr (line, 0, len))
+    {
+      err = gpg_error (GPG_ERR_INV_NAME);
+      goto leave;
+    }
+
+  /* Do a basic check.  */
+  err = g13_is_container (ctrl, line);
+  if (err)
+    goto leave;
+
+  /* Store the filename.  */
+  ctrl->server_local->containername = xtrystrdup (line);
+  if (!ctrl->server_local->containername)
+    err = gpg_error_from_syserror ();
+
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_mount[] =
+  "MOUNT [options] [<mountpoint>]\n"
+  "\n"
+  "Mount the currently open file onto MOUNTPOINT.  If MOUNTPOINT is not\n"
+  "given the system picks an unused mountpoint.  MOUNTPOINT must\n"
+  "be percent-plus escaped to allow for arbitrary names.";
+static gpg_error_t
+cmd_mount (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+  char *p, *pend;
+  size_t len;
+
+  line = skip_options (line);
+  for (p=line; *p && !spacep (p); p++)
+    ;
+  pend = p;
+  while (spacep(p))
+    p++;
+  if (*p)
+    {
+      err = gpg_error (GPG_ERR_ASS_SYNTAX);
+      goto leave;
+    }
+  *pend = 0;
+
+  /* Unescape the line and check for embedded Nul bytes.  */
+  len = percent_plus_unescape_inplace (line, 0);
+  line[len] = 0;
+  if (memchr (line, 0, len))
+    {
+      err = gpg_error (GPG_ERR_INV_NAME);
+      goto leave;
+    }
+
+  if (!ctrl->server_local->containername)
+    {
+      err = gpg_error (GPG_ERR_MISSING_ACTION);
+      goto leave;
+    }
+
+  /* Perform the mount.  */
+  err = g13_mount_container (ctrl, ctrl->server_local->containername,
+                             *line? line : NULL);
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_umount[] =
+  "UMOUNT [options] [<mountpoint>]\n"
+  "\n"
+  "Unmount the currently open file or the one opened at MOUNTPOINT.\n"
+  "MOUNTPOINT must be percent-plus escaped.  On success the mountpoint\n"
+  "is returned via a \"MOUNTPOINT\" status line.";
+static gpg_error_t
+cmd_umount (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+  char *p, *pend;
+  size_t len;
+
+  line = skip_options (line);
+  for (p=line; *p && !spacep (p); p++)
+    ;
+  pend = p;
+  while (spacep(p))
+    p++;
+  if (*p)
+    {
+      err = gpg_error (GPG_ERR_ASS_SYNTAX);
+      goto leave;
+    }
+  *pend = 0;
+
+  /* Unescape the line and check for embedded Nul bytes.  */
+  len = percent_plus_unescape_inplace (line, 0);
+  line[len] = 0;
+  if (memchr (line, 0, len))
+    {
+      err = gpg_error (GPG_ERR_INV_NAME);
+      goto leave;
+    }
+
+  /* Perform the unmount.  */
+  err = g13_umount_container (ctrl, ctrl->server_local->containername,
+                              *line? line : NULL);
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_recipient[] =
+  "RECIPIENT <userID>\n"
+  "\n"
+  "Add USERID to the list of recipients to be used for the next CREATE\n"
+  "command.  All recipient commands are cumulative until a RESET or an\n"
+  "successful create command.";
+static gpg_error_t
+cmd_recipient (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err = 0;
+
+  line = skip_options (line);
+
+  if (!add_to_strlist_try (&ctrl->server_local->recipients, line))
+    err = gpg_error_from_syserror ();
+
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_signer[] =
+  "SIGNER <userID>\n"
+  "\n"
+  "Not yet implemented.";
+static gpg_error_t
+cmd_signer (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+
+  (void)ctrl;
+  (void)line;
+
+  err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_create[] =
+  "CREATE [options] <filename>\n"
+  "\n"
+  "Create a new container.  On success the OPEN command is \n"
+  "implictly done for the new container.";
+static gpg_error_t
+cmd_create (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  char *p, *pend;
+  size_t len;
+
+  /* First we close the active container.  */
+  xfree (ctrl->server_local->containername);
+  ctrl->server_local->containername = NULL;
+
+  /* Parse the line.  */
+  line = skip_options (line);
+  for (p=line; *p && !spacep (p); p++)
+    ;
+  pend = p;
+  while (spacep(p))
+    p++;
+  if (*p || pend == line)
+    {
+      err = gpg_error (GPG_ERR_ASS_SYNTAX);
+      goto leave;
+    }
+  *pend = 0;
+
+  /* Unescape the line and check for embedded Nul bytes.  */
+  len = percent_plus_unescape_inplace (line, 0);
+  line[len] = 0;
+  if (!len || memchr (line, 0, len))
+    {
+      err = gpg_error (GPG_ERR_INV_NAME);
+      goto leave;
+    }
+
+  /* Create container.  */
+  err = g13_create_container (ctrl, line, ctrl->server_local->recipients);
+
+  if (!err)
+    {
+      FREE_STRLIST (ctrl->server_local->recipients);
+
+      /* Store the filename.  */
+      ctrl->server_local->containername = xtrystrdup (line);
+      if (!ctrl->server_local->containername)
+        err = gpg_error_from_syserror ();
+
+    }
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_getinfo[] =
+  "GETINFO <what>\n"
+  "\n"
+  "Multipurpose function to return a variety of information.\n"
+  "Supported values for WHAT are:\n"
+  "\n"
+  "  version     - Return the version of the program.\n"
+  "  pid         - Return the process id of the server.\n"
+  "  cmd_has_option CMD OPT\n"
+  "              - Return OK if the command CMD implements the option OPT.";
+static gpg_error_t
+cmd_getinfo (assuan_context_t ctx, char *line)
+{
+  gpg_error_t err = 0;
+
+  if (!strcmp (line, "version"))
+    {
+      const char *s = PACKAGE_VERSION;
+      err = assuan_send_data (ctx, s, strlen (s));
+    }
+  else if (!strcmp (line, "pid"))
+    {
+      char numbuf[50];
+
+      snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
+      err = assuan_send_data (ctx, numbuf, strlen (numbuf));
+    }
+  else if (!strncmp (line, "cmd_has_option", 14)
+           && (line[14] == ' ' || line[14] == '\t' || !line[14]))
+    {
+      char *cmd, *cmdopt;
+      line += 14;
+      while (*line == ' ' || *line == '\t')
+        line++;
+      if (!*line)
+        err = gpg_error (GPG_ERR_MISSING_VALUE);
+      else
+        {
+          cmd = line;
+          while (*line && (*line != ' ' && *line != '\t'))
+            line++;
+          if (!*line)
+            err = gpg_error (GPG_ERR_MISSING_VALUE);
+          else
+            {
+              *line++ = 0;
+              while (*line == ' ' || *line == '\t')
+                line++;
+              if (!*line)
+                err = gpg_error (GPG_ERR_MISSING_VALUE);
+              else
+                {
+                  cmdopt = line;
+                  if (!command_has_option (cmd, cmdopt))
+                    err = gpg_error (GPG_ERR_GENERAL);
+                }
+            }
+        }
+    }
+  else
+    err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
+
+  return leave_cmd (ctx, err);
+}
+
+
+\f
+/* Return true if the command CMD implements the option CMDOPT.  */
+static int
+command_has_option (const char *cmd, const char *cmdopt)
+{
+  (void)cmd;
+  (void)cmdopt;
+
+  return 0;
+}
+
+
+/* Tell the Assuan library about our commands.  */
+static int
+register_commands (assuan_context_t ctx)
+{
+  static struct {
+    const char *name;
+    assuan_handler_t handler;
+    const char * const help;
+  } table[] =  {
+    { "OPEN",          cmd_open,   hlp_open },
+    { "MOUNT",         cmd_mount,  hlp_mount},
+    { "UMOUNT",        cmd_umount, hlp_umount },
+    { "RECIPIENT",     cmd_recipient, hlp_recipient },
+    { "SIGNER",        cmd_signer, hlp_signer },
+    { "CREATE",        cmd_create, hlp_create },
+    { "INPUT",         NULL },
+    { "OUTPUT",        NULL },
+    { "GETINFO",       cmd_getinfo,hlp_getinfo },
+    { NULL }
+  };
+  gpg_error_t err;
+  int i;
+
+  for (i=0; table[i].name; i++)
+    {
+      err = assuan_register_command (ctx, table[i].name, table[i].handler,
+                                     table[i].help);
+      if (err)
+        return err;
+    }
+  return 0;
+}
+
+
+/* Startup the server. DEFAULT_RECPLIST is the list of recipients as
+   set from the command line or config file.  We only require those
+   marked as encrypt-to. */
+gpg_error_t
+g13_server (ctrl_t ctrl)
+{
+  gpg_error_t err;
+  assuan_fd_t filedes[2];
+  assuan_context_t ctx = NULL;
+  static const char hello[] = ("GNU Privacy Guard's G13 server "
+                               PACKAGE_VERSION " ready");
+
+  /* We use a pipe based server so that we can work from scripts.
+     assuan_init_pipe_server will automagically detect when we are
+     called with a socketpair and ignore FIELDES in this case. */
+  filedes[0] = assuan_fdopen (0);
+  filedes[1] = assuan_fdopen (1);
+  err = assuan_new (&ctx);
+  if (err)
+    {
+      log_error ("failed to allocate an Assuan context: %s\n",
+                 gpg_strerror (err));
+      goto leave;
+    }
+
+  err = assuan_init_pipe_server (ctx, filedes);
+  if (err)
+    {
+      log_error ("failed to initialize the server: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  err = register_commands (ctx);
+  if (err)
+    {
+      log_error ("failed to the register commands with Assuan: %s\n",
+                 gpg_strerror (err));
+      goto leave;
+    }
+
+  assuan_set_pointer (ctx, ctrl);
+
+  if (opt.verbose || opt.debug)
+    {
+      char *tmp = NULL;
+
+      tmp = xtryasprintf ("Home: %s\n"
+                          "Config: %s\n"
+                          "%s",
+                          opt.homedir,
+                          opt.config_filename,
+                          hello);
+      if (tmp)
+        {
+          assuan_set_hello_line (ctx, tmp);
+          xfree (tmp);
+        }
+    }
+  else
+    assuan_set_hello_line (ctx, hello);
+
+  assuan_register_reset_notify (ctx, reset_notify);
+  assuan_register_option_handler (ctx, option_handler);
+
+  ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
+  if (!ctrl->server_local)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  ctrl->server_local->assuan_ctx = ctx;
+
+  while ( !(err = assuan_accept (ctx)) )
+    {
+      err = assuan_process (ctx);
+      if (err)
+        log_info ("Assuan processing failed: %s\n", gpg_strerror (err));
+    }
+  if (err == -1)
+    err = 0;
+  else
+    log_info ("Assuan accept problem: %s\n", gpg_strerror (err));
+
+ leave:
+  reset_notify (ctx, NULL);  /* Release all items hold by SERVER_LOCAL.  */
+  if (ctrl->server_local)
+    {
+      xfree (ctrl->server_local);
+      ctrl->server_local = NULL;
+    }
+
+  assuan_release (ctx);
+  return err;
+}
+
+
+/* Send a status line with status ID NO.  The arguments are a list of
+   strings terminated by a NULL argument.  */
+gpg_error_t
+g13_status (ctrl_t ctrl, int no, ...)
+{
+  gpg_error_t err = 0;
+  va_list arg_ptr;
+  const char *text;
+
+  va_start (arg_ptr, no);
+
+  if (ctrl->no_server && ctrl->status_fd == -1)
+    ; /* No status wanted. */
+  else if (ctrl->no_server)
+    {
+      if (!statusfp)
+        {
+          if (ctrl->status_fd == 1)
+            statusfp = stdout;
+          else if (ctrl->status_fd == 2)
+            statusfp = stderr;
+          else
+            statusfp = fdopen (ctrl->status_fd, "w");
+
+          if (!statusfp)
+            {
+              log_fatal ("can't open fd %d for status output: %s\n",
+                         ctrl->status_fd, strerror(errno));
+            }
+        }
+
+      fputs ("[GNUPG:] ", statusfp);
+      fputs (get_status_string (no), statusfp);
+
+      while ( (text = va_arg (arg_ptr, const char*) ))
+        {
+          putc ( ' ', statusfp );
+          for (; *text; text++)
+            {
+              if (*text == '\n')
+                fputs ( "\\n", statusfp );
+              else if (*text == '\r')
+                fputs ( "\\r", statusfp );
+              else
+                putc ( *(const byte *)text,  statusfp );
+            }
+        }
+      putc ('\n', statusfp);
+      fflush (statusfp);
+    }
+  else
+    {
+      assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+      char buf[950], *p;
+      size_t n;
+
+      p = buf;
+      n = 0;
+      while ( (text = va_arg (arg_ptr, const char *)) )
+        {
+          if (n)
+            {
+              *p++ = ' ';
+              n++;
+            }
+          for ( ; *text && n < DIM (buf)-2; n++)
+            *p++ = *text++;
+        }
+      *p = 0;
+      err = assuan_write_status (ctx, get_status_string (no), buf);
+    }
+
+  va_end (arg_ptr);
+  return err;
+}
+
+
+/* Helper to notify the client about Pinentry events.  Returns an gpg
+   error code. */
+gpg_error_t
+g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
+{
+  if (!ctrl || !ctrl->server_local)
+    return 0;
+  return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
+}
diff --git a/g13/server.h b/g13/server.h
new file mode 100644 (file)
index 0000000..af8494a
--- /dev/null
@@ -0,0 +1,28 @@
+/* server.h - The G13 Assuan server
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_SERVER_H
+#define G13_SERVER_H
+
+
+gpg_error_t g13_server (ctrl_t ctrl);
+
+gpg_error_t g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line);
+
+#endif /*G13_SERVER_H*/
diff --git a/g13/utils.c b/g13/utils.c
new file mode 100644 (file)
index 0000000..6fe3e5a
--- /dev/null
@@ -0,0 +1,179 @@
+/* utils.c - Utility functions
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "g13.h"
+#include "utils.h"
+
+
+/* Definition of the tuple descriptor object.  */
+struct tupledesc_s
+{
+  unsigned char *data; /* The tuple data.  */
+  size_t datalen;      /* The length of the data.  */
+  size_t pos;          /* The current position as used by next_tuple.  */
+  int refcount;        /* Number of references hold. */
+};
+
+
+
+/* Append the TAG and the VALUE to the MEMBUF.  There is no error
+   checking here; this is instead done while getting the value back
+   from the membuf. */
+void
+append_tuple (membuf_t *membuf, int tag, const void *value, size_t length)
+{
+  unsigned char buf[2];
+
+  assert (tag >= 0 && tag <= 0xffff);
+  assert (length <= 0xffff);
+
+  buf[0] = tag >> 8;
+  buf[1] = tag;
+  put_membuf (membuf, buf, 2);
+  buf[0] = length >> 8;
+  buf[1] = length;
+  put_membuf (membuf, buf, 2);
+  if (length)
+    put_membuf (membuf, value, length);
+}
+
+
+/* Create a tuple object by moving the ownership of (DATA,DATALEN) to
+   a new object.  Returns 0 on success and stores the new object at
+   R_TUPLEHD.  The return object must be released using
+   destroy_tuples().  */
+gpg_error_t
+create_tupledesc (tupledesc_t *r_desc, void *data, size_t datalen)
+{
+  if (datalen < 5 || memcmp (data, "\x00\x00\x00\x01\x01", 5))
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  *r_desc = xtrymalloc (sizeof **r_desc);
+  if (!*r_desc)
+    return gpg_error_from_syserror ();
+  (*r_desc)->data = data;
+  (*r_desc)->datalen = datalen;
+  (*r_desc)->pos = 0;
+  (*r_desc)->refcount++;
+  return 0;
+}
+
+/* Unref a tuple descriptor and if the refcount is down to 0 release
+   its allocated storage.  */
+void
+destroy_tupledesc (tupledesc_t tupledesc)
+{
+  if (!tupledesc)
+    return;
+
+  if (!--tupledesc->refcount)
+    {
+      xfree (tupledesc->data);
+      xfree (tupledesc);
+    }
+}
+
+
+tupledesc_t
+ref_tupledesc (tupledesc_t tupledesc)
+{
+  if (tupledesc)
+    tupledesc->refcount++;
+  return tupledesc;
+}
+
+
+/* Find the first tuple with tag TAG.  On success return a pointer to
+   its value and store the length of the value at R_LENGTH.  If no
+   tuple was return NULL.  For future use by next_tupe, the last
+   position is stored in the descriptor.  */
+const void *
+find_tuple (tupledesc_t tupledesc, unsigned int tag, size_t *r_length)
+{
+  const unsigned char *s;
+  const unsigned char *s_end; /* Points right behind the data. */
+  unsigned int t;
+  size_t n;
+
+  s = tupledesc->data;
+  if (!s)
+    return NULL;
+  s_end = s + tupledesc->datalen;
+  while (s < s_end)
+    {
+      if (s+3 >= s_end || s + 3 < s)
+        break;
+      t  = s[0] << 8;
+      t |= s[1];
+      n  = s[2] << 8;
+      n |= s[3];
+      s += 4;
+      if (s + n > s_end || s + n < s)
+        break;
+      if (t == tag)
+        {
+          tupledesc->pos = (s + n) - tupledesc->data;
+          *r_length = n;
+          return s;
+        }
+      s += n;
+    }
+  return NULL;
+}
+
+
+const void *
+next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length)
+{
+  const unsigned char *s;
+  const unsigned char *s_end; /* Points right behind the data.  */
+  unsigned int t;
+  size_t n;
+
+  s = tupledesc->data;
+  if (!s)
+    return NULL;
+  s_end = s + tupledesc->datalen;
+  s += tupledesc->pos;
+  if (s < s_end
+      && !(s+3 >= s_end || s + 3 < s))
+    {
+      t  = s[0] << 8;
+      t |= s[1];
+      n  = s[2] << 8;
+      n |= s[3];
+      s += 4;
+      if (!(s + n > s_end || s + n < s))
+        {
+          tupledesc->pos = (s + n) - tupledesc->data;
+          *r_tag = t;
+          *r_length = n;
+          return s;
+        }
+    }
+
+  return NULL;
+}
diff --git a/g13/utils.h b/g13/utils.h
new file mode 100644 (file)
index 0000000..914b2cf
--- /dev/null
@@ -0,0 +1,43 @@
+/* utils.h - Defs for utility fucthe dispatcher to the various backends.ntions
+ * Copyright (C) 2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G13_UTILS_H
+#define G13_UTILS_H
+
+#include "../common/membuf.h"
+
+/* Append a new tuple to a memory buffer.  */
+void append_tuple (membuf_t *membuf,
+                   int tag, const void *value, size_t length);
+
+/* The tuple descriptor object. */
+struct tupledesc_s;
+typedef struct tupledesc_s *tupledesc_t;
+
+gpg_error_t create_tupledesc (tupledesc_t *r_tupledesc,
+                              void *data, size_t datalen);
+void destroy_tupledesc (tupledesc_t tupledesc);
+tupledesc_t ref_tupledesc (tupledesc_t tupledesc);
+const void *find_tuple (tupledesc_t tupledesc,
+                        unsigned int tag, size_t *r_length);
+const void *next_tuple (tupledesc_t tupledesc,
+                        unsigned int *r_tag, size_t *r_length);
+
+
+#endif /*G13_UTILS_H*/
index 59667db..5c1d7c4 100644 (file)
@@ -29,6 +29,10 @@ MAINTAINERCLEANFILES =
 
 AM_CPPFLAGS =
 
+if HAVE_W32CE_SYSTEM
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+endif
+
 ## begin gnulib module alloca-opt
 
 BUILT_SOURCES += $(ALLOCA_H)
index 4cf86a0..e8db739 100644 (file)
 
 #include <errno.h>
 #ifndef __set_errno
-# define __set_errno(Val) errno = (Val)
+# ifdef HAVE_W32CE_SYSTEM
+#  include <gpg-error.h>
+#  define __set_errno(Val) gpg_err_set_errno ((Val))
+# else
+#  define __set_errno(Val) errno = (Val)
+# endif
 #endif
 
 #include <stddef.h>
 # include <io.h>
 #endif
 
+#ifdef HAVE_W32CE_SYSTEM
+#include <windows.h>
+#define getpid() GetCurrentProcessId ()
+#endif
+
 #if !_LIBC
 # define __getpid getpid
 # define __gettimeofday gettimeofday
index 7c03d62..775d29c 100644 (file)
 
 #include <errno.h>
 #ifndef __set_errno
-# define __set_errno(ev) ((errno) = (ev))
+# ifdef HAVE_W32CE_SYSTEM
+#  include <gpg-error.h>
+#  define __set_errno(ev) gpg_err_set_errno ((ev))
+# else
+#  define __set_errno(ev) ((errno) = (ev))
+# endif
 #endif
 
 #include <stdlib.h>
@@ -42,7 +47,7 @@ extern char **environ;
 #endif
 
 #if _LIBC
-/* This lock protects against simultaneous modifications of `environ'.  */
+/* This lock protects against simultaneous modifications of 'environ'.  */
 # include <bits/libc-lock.h>
 __libc_lock_define_initialized (static, envlock)
 # define LOCK  __libc_lock_lock (envlock)
@@ -76,8 +81,8 @@ static void *known_values;
 
 # define KNOWN_VALUE(Str) \
   ({                                                                         \
-    void *value = tfind (Str, &known_values, (compar_fn_t) strcmp);          \
-    value != NULL ? *(char **) value : NULL;                                 \
+    void *_v = tfind (Str, &known_values, (compar_fn_t) strcmp);             \
+    _v != NULL ? *(char **) _v : NULL;                               \
   })
 # define STORE_VALUE(Str) \
   tsearch (Str, &known_values, (compar_fn_t) strcmp)
@@ -96,11 +101,11 @@ static void *known_values;
 static char **last_environ;
 
 
-/* This function is used by `setenv' and `putenv'.  The difference between
+/* This function is used by 'setenv' and 'putenv'.  The difference between
    the two functions is that for the former must create a new string which
-   is then placed in the environment, while the argument of `putenv'
+   is then placed in the environment, while the argument of 'putenv'
    must be used directly.  This is all complicated by the fact that we try
-   to reuse values once generated for a `setenv' call since we can never
+   to reuse values once generated for a 'setenv' call since we can never
    free the strings.  */
 int
 __add_to_environ (const char *name, const char *value, const char *combined,
@@ -283,7 +288,7 @@ setenv (const char *name, const char *value, int replace)
   return __add_to_environ (name, value, NULL, replace);
 }
 
-/* The `clearenv' was planned to be added to POSIX.1 but probably
+/* The 'clearenv' was planned to be added to POSIX.1 but probably
    never made it.  Nevertheless the POSIX.9 standard (POSIX bindings
    for Fortran 77) requires this function.  */
 int
index bc27595..1118e8d 100644 (file)
  * <http://www.opengroup.org/susv3xbd/stdint.h.html>
  */
 
+/* On Android (Bionic libc), <sys/types.h> includes this file before
+   having defined 'time_t'.  Therefore in this case avoid including
+   other system header files; just include the system's <stdint.h>.
+   Ideally we should test __BIONIC__ here, but it is only defined after
+   <sys/cdefs.h> has been included; hence test __ANDROID__ instead.  */
+#if defined __ANDROID__ \
+    && defined _SYS_TYPES_H_ && !defined _SSIZE_T_DEFINED_
+# include_next <stdint.h>
+#else
+
 /* Get those types that are already defined in other system include
    files, so that we can "#define int8_t signed char" below without
    worrying about a later system include file containing a "typedef
 # include @ABSOLUTE_STDINT_H@
 #endif
 
+#ifdef __APPLE__
+  /* Apple's implementation of <stdint.h> is bugy; we therefore use
+     the source definitions.  */
+# include <_types/_intmax_t.h>
+# include <_types/_uintmax_t.h>
+#endif
+
 /* <sys/types.h> defines some of the stdint.h types as well, on glibc,
    IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>).
    MacOS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but
 /* Here we assume a standard architecture where the hardware integer
    types have 8, 16, 32, optionally 64 bits.  */
 
-#undef INT8_MIN
-#undef INT8_MAX
-#undef UINT8_MAX
-#define INT8_MIN  (~ INT8_MAX)
-#define INT8_MAX  127
-#define UINT8_MAX  255
-
-#undef INT16_MIN
-#undef INT16_MAX
-#undef UINT16_MAX
-#define INT16_MIN  (~ INT16_MAX)
-#define INT16_MAX  32767
-#define UINT16_MAX  65535
-
-#undef INT32_MIN
-#undef INT32_MAX
-#undef UINT32_MAX
-#define INT32_MIN  (~ INT32_MAX)
-#define INT32_MAX  2147483647
-#define UINT32_MAX  4294967295U
-
-#undef INT64_MIN
-#undef INT64_MAX
-#ifdef int64_t
-# define INT64_MIN  (~ INT64_MAX)
-# define INT64_MAX  INTMAX_C (9223372036854775807)
-#endif
+# undef INT8_MIN
+# undef INT8_MAX
+# undef UINT8_MAX
+# define INT8_MIN  (~ INT8_MAX)
+# define INT8_MAX  127
+# define UINT8_MAX  255
+
+# undef INT16_MIN
+# undef INT16_MAX
+# undef UINT16_MAX
+# define INT16_MIN  (~ INT16_MAX)
+# define INT16_MAX  32767
+# define UINT16_MAX  65535
+
+# undef INT32_MIN
+# undef INT32_MAX
+# undef UINT32_MAX
+# define INT32_MIN  (~ INT32_MAX)
+# define INT32_MAX  2147483647
+# define UINT32_MAX  4294967295U
+
+# undef INT64_MIN
+# undef INT64_MAX
+# ifdef int64_t
+#  define INT64_MIN  (~ INT64_MAX)
+#  define INT64_MAX  INTMAX_C (9223372036854775807)
+# endif
 
-#undef UINT64_MAX
-#ifdef uint64_t
-# define UINT64_MAX  UINTMAX_C (18446744073709551615)
-#endif
+# undef UINT64_MAX
+# ifdef uint64_t
+#  define UINT64_MAX  UINTMAX_C (18446744073709551615)
+# endif
 
 /* 7.18.2.2. Limits of minimum-width integer types */
 
    types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
    are the same as the corresponding N_t types.  */
 
-#undef INT_LEAST8_MIN
-#undef INT_LEAST8_MAX
-#undef UINT_LEAST8_MAX
-#define INT_LEAST8_MIN  INT8_MIN
-#define INT_LEAST8_MAX  INT8_MAX
-#define UINT_LEAST8_MAX  UINT8_MAX
-
-#undef INT_LEAST16_MIN
-#undef INT_LEAST16_MAX
-#undef UINT_LEAST16_MAX
-#define INT_LEAST16_MIN  INT16_MIN
-#define INT_LEAST16_MAX  INT16_MAX
-#define UINT_LEAST16_MAX  UINT16_MAX
-
-#undef INT_LEAST32_MIN
-#undef INT_LEAST32_MAX
-#undef UINT_LEAST32_MAX
-#define INT_LEAST32_MIN  INT32_MIN
-#define INT_LEAST32_MAX  INT32_MAX
-#define UINT_LEAST32_MAX  UINT32_MAX
-
-#undef INT_LEAST64_MIN
-#undef INT_LEAST64_MAX
-#ifdef int64_t
-# define INT_LEAST64_MIN  INT64_MIN
-# define INT_LEAST64_MAX  INT64_MAX
-#endif
+# undef INT_LEAST8_MIN
+# undef INT_LEAST8_MAX
+# undef UINT_LEAST8_MAX
+# define INT_LEAST8_MIN  INT8_MIN
+# define INT_LEAST8_MAX  INT8_MAX
+# define UINT_LEAST8_MAX  UINT8_MAX
+
+# undef INT_LEAST16_MIN
+# undef INT_LEAST16_MAX
+# undef UINT_LEAST16_MAX
+# define INT_LEAST16_MIN  INT16_MIN
+# define INT_LEAST16_MAX  INT16_MAX
+# define UINT_LEAST16_MAX  UINT16_MAX
+
+# undef INT_LEAST32_MIN
+# undef INT_LEAST32_MAX
+# undef UINT_LEAST32_MAX
+# define INT_LEAST32_MIN  INT32_MIN
+# define INT_LEAST32_MAX  INT32_MAX
+# define UINT_LEAST32_MAX  UINT32_MAX
+
+# undef INT_LEAST64_MIN
+# undef INT_LEAST64_MAX
+# ifdef int64_t
+#  define INT_LEAST64_MIN  INT64_MIN
+#  define INT_LEAST64_MAX  INT64_MAX
+# endif
 
-#undef UINT_LEAST64_MAX
-#ifdef uint64_t
-# define UINT_LEAST64_MAX  UINT64_MAX
-#endif
+# undef UINT_LEAST64_MAX
+# ifdef uint64_t
+#  define UINT_LEAST64_MAX  UINT64_MAX
+# endif
 
 /* 7.18.2.3. Limits of fastest minimum-width integer types */
 
    types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
    are taken from the same list of types.  */
 
-#undef INT_FAST8_MIN
-#undef INT_FAST8_MAX
-#undef UINT_FAST8_MAX
-#define INT_FAST8_MIN  LONG_MIN
-#define INT_FAST8_MAX  LONG_MAX
-#define UINT_FAST8_MAX  ULONG_MAX
-
-#undef INT_FAST16_MIN
-#undef INT_FAST16_MAX
-#undef UINT_FAST16_MAX
-#define INT_FAST16_MIN  LONG_MIN
-#define INT_FAST16_MAX  LONG_MAX
-#define UINT_FAST16_MAX  ULONG_MAX
-
-#undef INT_FAST32_MIN
-#undef INT_FAST32_MAX
-#undef UINT_FAST32_MAX
-#define INT_FAST32_MIN  LONG_MIN
-#define INT_FAST32_MAX  LONG_MAX
-#define UINT_FAST32_MAX  ULONG_MAX
-
-#undef INT_FAST64_MIN
-#undef INT_FAST64_MAX
-#ifdef int64_t
-# define INT_FAST64_MIN  INT64_MIN
-# define INT_FAST64_MAX  INT64_MAX
-#endif
+# undef INT_FAST8_MIN
+# undef INT_FAST8_MAX
+# undef UINT_FAST8_MAX
+# define INT_FAST8_MIN  LONG_MIN
+# define INT_FAST8_MAX  LONG_MAX
+# define UINT_FAST8_MAX  ULONG_MAX
+
+# undef INT_FAST16_MIN
+# undef INT_FAST16_MAX
+# undef UINT_FAST16_MAX
+# define INT_FAST16_MIN  LONG_MIN
+# define INT_FAST16_MAX  LONG_MAX
+# define UINT_FAST16_MAX  ULONG_MAX
+
+# undef INT_FAST32_MIN
+# undef INT_FAST32_MAX
+# undef UINT_FAST32_MAX
+# define INT_FAST32_MIN  LONG_MIN
+# define INT_FAST32_MAX  LONG_MAX
+# define UINT_FAST32_MAX  ULONG_MAX
+
+# undef INT_FAST64_MIN
+# undef INT_FAST64_MAX
+# ifdef int64_t
+#  define INT_FAST64_MIN  INT64_MIN
+#  define INT_FAST64_MAX  INT64_MAX
+# endif
 
-#undef UINT_FAST64_MAX
-#ifdef uint64_t
-# define UINT_FAST64_MAX  UINT64_MAX
-#endif
+# undef UINT_FAST64_MAX
+# ifdef uint64_t
+#  define UINT_FAST64_MAX  UINT64_MAX
+# endif
 
 /* 7.18.2.4. Limits of integer types capable of holding object pointers */
 
-#undef INTPTR_MIN
-#undef INTPTR_MAX
-#undef UINTPTR_MAX
-#define INTPTR_MIN  LONG_MIN
-#define INTPTR_MAX  LONG_MAX
-#define UINTPTR_MAX  ULONG_MAX
+# undef INTPTR_MIN
+# undef INTPTR_MAX
+# undef UINTPTR_MAX
+# define INTPTR_MIN  LONG_MIN
+# define INTPTR_MAX  LONG_MAX
+# define UINTPTR_MAX  ULONG_MAX
 
 /* 7.18.2.5. Limits of greatest-width integer types */
 
-#undef INTMAX_MIN
-#undef INTMAX_MAX
-#define INTMAX_MIN  (~ INTMAX_MAX)
-#ifdef INT64_MAX
-# define INTMAX_MAX  INT64_MAX
-#else
-# define INTMAX_MAX  INT32_MAX
-#endif
+# undef INTMAX_MIN
+# undef INTMAX_MAX
+# define INTMAX_MIN  (~ INTMAX_MAX)
+# ifdef INT64_MAX
+#  define INTMAX_MAX  INT64_MAX
+# else
+#  define INTMAX_MAX  INT32_MAX
+# endif
 
-#undef UINTMAX_MAX
-#ifdef UINT64_MAX
-# define UINTMAX_MAX  UINT64_MAX
-#else
-# define UINTMAX_MAX  UINT32_MAX
-#endif
+# undef UINTMAX_MAX
+# ifdef UINT64_MAX
+#  define UINTMAX_MAX  UINT64_MAX
+# else
+#  define UINTMAX_MAX  UINT32_MAX
+# endif
 
 /* 7.18.3. Limits of other integer types */
 
 /* ptrdiff_t limits */
-#undef PTRDIFF_MIN
-#undef PTRDIFF_MAX
-#define PTRDIFF_MIN  \
+# undef PTRDIFF_MIN
+# undef PTRDIFF_MAX
+# define PTRDIFF_MIN  \
    _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)
-#define PTRDIFF_MAX  \
+# define PTRDIFF_MAX  \
    _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)
 
 /* sig_atomic_t limits */
-#undef SIG_ATOMIC_MIN
-#undef SIG_ATOMIC_MAX
-#define SIG_ATOMIC_MIN  \
+# undef SIG_ATOMIC_MIN
+# undef SIG_ATOMIC_MAX
+# define SIG_ATOMIC_MIN  \
    _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
                0@SIG_ATOMIC_T_SUFFIX@)
-#define SIG_ATOMIC_MAX  \
+# define SIG_ATOMIC_MAX  \
    _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
                0@SIG_ATOMIC_T_SUFFIX@)
 
 
 /* size_t limit */
-#undef SIZE_MAX
-#define SIZE_MAX  _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@)
+# undef SIZE_MAX
+# define SIZE_MAX  _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@)
 
 /* wchar_t limits */
-#undef WCHAR_MIN
-#undef WCHAR_MAX
-#define WCHAR_MIN  \
+# undef WCHAR_MIN
+# undef WCHAR_MAX
+# define WCHAR_MIN  \
    _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
-#define WCHAR_MAX  \
+# define WCHAR_MAX  \
    _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
 
 /* wint_t limits */
-#undef WINT_MIN
-#undef WINT_MAX
-#define WINT_MIN  \
+# undef WINT_MIN
+# undef WINT_MAX
+# define WINT_MIN  \
    _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
-#define WINT_MAX  \
+# define WINT_MAX  \
    _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
 
 #endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */
 /* Here we assume a standard architecture where the hardware integer
    types have 8, 16, 32, optionally 64 bits, and int is 32 bits.  */
 
-#undef INT8_C
-#undef UINT8_C
-#define INT8_C(x) x
-#define UINT8_C(x) x
-
-#undef INT16_C
-#undef UINT16_C
-#define INT16_C(x) x
-#define UINT16_C(x) x
-
-#undef INT32_C
-#undef UINT32_C
-#define INT32_C(x) x
-#define UINT32_C(x) x ## U
-
-#undef INT64_C
-#undef UINT64_C
-#if LONG_MAX >> 31 >> 31 == 1
-# define INT64_C(x) x##L
-#elif defined _MSC_VER
-# define INT64_C(x) x##i64
-#elif @HAVE_LONG_LONG_INT@
-# define INT64_C(x) x##LL
-#endif
-#if ULONG_MAX >> 31 >> 31 >> 1 == 1
-# define UINT64_C(x) x##UL
-#elif defined _MSC_VER
-# define UINT64_C(x) x##ui64
-#elif @HAVE_UNSIGNED_LONG_LONG_INT@
-# define UINT64_C(x) x##ULL
-#endif
+# undef INT8_C
+# undef UINT8_C
+# define INT8_C(x) x
+# define UINT8_C(x) x
+
+# undef INT16_C
+# undef UINT16_C
+# define INT16_C(x) x
+# define UINT16_C(x) x
+
+# undef INT32_C
+# undef UINT32_C
+# define INT32_C(x) x
+# define UINT32_C(x) x ## U
+
+# undef INT64_C
+# undef UINT64_C
+# if LONG_MAX >> 31 >> 31 == 1
+#  define INT64_C(x) x##L
+# elif defined _MSC_VER
+#  define INT64_C(x) x##i64
+# elif @HAVE_LONG_LONG_INT@
+#  define INT64_C(x) x##LL
+# endif
+# if ULONG_MAX >> 31 >> 31 >> 1 == 1
+#  define UINT64_C(x) x##UL
+# elif defined _MSC_VER
+#  define UINT64_C(x) x##ui64
+# elif @HAVE_UNSIGNED_LONG_LONG_INT@
+#  define UINT64_C(x) x##ULL
+# endif
 
 /* 7.18.4.2. Macros for greatest-width integer constants */
 
-#undef INTMAX_C
-#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
-# define INTMAX_C(x)   x##LL
-#elif defined int64_t
-# define INTMAX_C(x)   INT64_C(x)
-#else
-# define INTMAX_C(x)   x##L
-#endif
+# undef INTMAX_C
+# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
+#  define INTMAX_C(x)   x##LL
+# elif defined int64_t
+#  define INTMAX_C(x)   INT64_C(x)
+# else
+#  define INTMAX_C(x)   x##L
+# endif
 
-#undef UINTMAX_C
-#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
-# define UINTMAX_C(x)  x##ULL
-#elif defined uint64_t
-# define UINTMAX_C(x)  UINT64_C(x)
-#else
-# define UINTMAX_C(x)  x##UL
-#endif
+# undef UINTMAX_C
+# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
+#  define UINTMAX_C(x)  x##ULL
+# elif defined uint64_t
+#  define UINTMAX_C(x)  UINT64_C(x)
+# else
+#  define UINTMAX_C(x)  x##UL
+# endif
 
+#endif /* !(defined __ANDROID__ && ...) */
 #endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */
-
 #endif /* _GL_STDINT_H */
index 76b707c..8a025d4 100644 (file)
 
 #include <errno.h>
 #if !_LIBC
-# define __set_errno(ev) ((errno) = (ev))
+# ifdef HAVE_W32CE_SYSTEM
+#  include <gpg-error.h>
+#  define __set_errno(ev) gpg_err_set_errno ((ev))
+# else
+#  define __set_errno(ev) ((errno) = (ev))
+# endif
 #endif
 
 #include <stdlib.h>
@@ -33,7 +38,7 @@ extern char **environ;
 #endif
 
 #if _LIBC
-/* This lock protects against simultaneous modifications of `environ'.  */
+/* This lock protects against simultaneous modifications of 'environ'.  */
 # include <bits/libc-lock.h>
 __libc_lock_define_initialized (static, envlock)
 # define LOCK  __libc_lock_lock (envlock)
diff --git a/include/Makefile.am b/include/Makefile.am
deleted file mode 100644 (file)
index 4d733ba..0000000
+++ /dev/null
@@ -1 +0,0 @@
-EXTRA_DIST = cipher.h types.h host2net.h _regex.h ChangeLog-2011
diff --git a/include/_regex.h b/include/_regex.h
deleted file mode 100644 (file)
index ddd0024..0000000
+++ /dev/null
@@ -1,574 +0,0 @@
-/* Definitions for data structures and routines for the regular
-   expression library.
-   Copyright (C) 1985,1989-93,1995-98,2000,2001,2002
-   Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-   MA 02110-1301, USA. */
-
-#ifndef _REGEX_H
-#define _REGEX_H 1
-
-/* Allow the use in C++ code.  */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* POSIX says that <sys/types.h> must be included (by the caller) before
-   <regex.h>.  */
-
-#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS
-/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
-   should be there.  */
-# include <stddef.h>
-#endif
-
-/* The following two types have to be signed and unsigned integer type
-   wide enough to hold a value of a pointer.  For most ANSI compilers
-   ptrdiff_t and size_t should be likely OK.  Still size of these two
-   types is 2 for Microsoft C.  Ugh... */
-typedef long int s_reg_t;
-typedef unsigned long int active_reg_t;
-
-/* The following bits are used to determine the regexp syntax we
-   recognize.  The set/not-set meanings are chosen so that Emacs syntax
-   remains the value 0.  The bits are given in alphabetical order, and
-   the definitions shifted by one from the previous bit; thus, when we
-   add or remove a bit, only one other definition need change.  */
-typedef unsigned long int reg_syntax_t;
-
-/* If this bit is not set, then \ inside a bracket expression is literal.
-   If set, then such a \ quotes the following character.  */
-#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
-
-/* If this bit is not set, then + and ? are operators, and \+ and \? are
-     literals.
-   If set, then \+ and \? are operators and + and ? are literals.  */
-#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
-
-/* If this bit is set, then character classes are supported.  They are:
-     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
-     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
-   If not set, then character classes are not supported.  */
-#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
-
-/* If this bit is set, then ^ and $ are always anchors (outside bracket
-     expressions, of course).
-   If this bit is not set, then it depends:
-        ^  is an anchor if it is at the beginning of a regular
-           expression or after an open-group or an alternation operator;
-        $  is an anchor if it is at the end of a regular expression, or
-           before a close-group or an alternation operator.
-
-   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
-   POSIX draft 11.2 says that * etc. in leading positions is undefined.
-   We already implemented a previous draft which made those constructs
-   invalid, though, so we haven't changed the code back.  */
-#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
-
-/* If this bit is set, then special characters are always special
-     regardless of where they are in the pattern.
-   If this bit is not set, then special characters are special only in
-     some contexts; otherwise they are ordinary.  Specifically,
-     * + ? and intervals are only special when not after the beginning,
-     open-group, or alternation operator.  */
-#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
-
-/* If this bit is set, then *, +, ?, and { cannot be first in an re or
-     immediately after an alternation or begin-group operator.  */
-#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
-
-/* If this bit is set, then . matches newline.
-   If not set, then it doesn't.  */
-#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
-
-/* If this bit is set, then . doesn't match NUL.
-   If not set, then it does.  */
-#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
-
-/* If this bit is set, nonmatching lists [^...] do not match newline.
-   If not set, they do.  */
-#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
-
-/* If this bit is set, either \{...\} or {...} defines an
-     interval, depending on RE_NO_BK_BRACES.
-   If not set, \{, \}, {, and } are literals.  */
-#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
-
-/* If this bit is set, +, ? and | aren't recognized as operators.
-   If not set, they are.  */
-#define RE_LIMITED_OPS (RE_INTERVALS << 1)
-
-/* If this bit is set, newline is an alternation operator.
-   If not set, newline is literal.  */
-#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
-
-/* If this bit is set, then `{...}' defines an interval, and \{ and \}
-     are literals.
-  If not set, then `\{...\}' defines an interval.  */
-#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
-
-/* If this bit is set, (...) defines a group, and \( and \) are literals.
-   If not set, \(...\) defines a group, and ( and ) are literals.  */
-#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
-
-/* If this bit is set, then \<digit> matches <digit>.
-   If not set, then \<digit> is a back-reference.  */
-#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
-
-/* If this bit is set, then | is an alternation operator, and \| is literal.
-   If not set, then \| is an alternation operator, and | is literal.  */
-#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
-
-/* If this bit is set, then an ending range point collating higher
-     than the starting range point, as in [z-a], is invalid.
-   If not set, then when ending range point collates higher than the
-     starting range point, the range is ignored.  */
-#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
-
-/* If this bit is set, then an unmatched ) is ordinary.
-   If not set, then an unmatched ) is invalid.  */
-#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
-
-/* If this bit is set, succeed as soon as we match the whole pattern,
-   without further backtracking.  */
-#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
-
-/* If this bit is set, do not process the GNU regex operators.
-   If not set, then the GNU regex operators are recognized. */
-#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
-
-/* If this bit is set, turn on internal regex debugging.
-   If not set, and debugging was on, turn it off.
-   This only works if regex.c is compiled -DDEBUG.
-   We define this bit always, so that all that's needed to turn on
-   debugging is to recompile regex.c; the calling code can always have
-   this bit set, and it won't affect anything in the normal case. */
-#define RE_DEBUG (RE_NO_GNU_OPS << 1)
-
-/* If this bit is set, a syntactically invalid interval is treated as
-   a string of ordinary characters.  For example, the ERE 'a{1' is
-   treated as 'a\{1'.  */
-#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
-
-/* If this bit is set, then ignore case when matching.
-   If not set, then case is significant.  */
-#define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
-
-/* This global variable defines the particular regexp syntax to use (for
-   some interfaces).  When a regexp is compiled, the syntax used is
-   stored in the pattern buffer, so changing this does not affect
-   already-compiled regexps.  */
-extern reg_syntax_t re_syntax_options;
-\f
-/* Define combinations of the above bits for the standard possibilities.
-   (The [[[ comments delimit what gets put into the Texinfo file, so
-   don't delete them!)  */
-/* [[[begin syntaxes]]] */
-#define RE_SYNTAX_EMACS 0
-
-#define RE_SYNTAX_AWK                                                  \
-  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL                    \
-   | RE_NO_BK_PARENS              | RE_NO_BK_REFS                      \
-   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES                 \
-   | RE_DOT_NEWLINE              | RE_CONTEXT_INDEP_ANCHORS            \
-   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
-
-#define RE_SYNTAX_GNU_AWK                                              \
-  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG)        \
-   & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS           \
-       | RE_CONTEXT_INVALID_OPS ))
-
-#define RE_SYNTAX_POSIX_AWK                                            \
-  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS             \
-   | RE_INTERVALS          | RE_NO_GNU_OPS)
-
-#define RE_SYNTAX_GREP                                                 \
-  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES                                \
-   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS                           \
-   | RE_NEWLINE_ALT)
-
-#define RE_SYNTAX_EGREP                                                        \
-  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS                   \
-   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE                   \
-   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS                            \
-   | RE_NO_BK_VBAR)
-
-#define RE_SYNTAX_POSIX_EGREP                                          \
-  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES                    \
-   | RE_INVALID_INTERVAL_ORD)
-
-/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
-#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
-
-#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
-
-/* Syntax bits common to both basic and extended POSIX regex syntax.  */
-#define _RE_SYNTAX_POSIX_COMMON                                                \
-  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL             \
-   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
-
-#define RE_SYNTAX_POSIX_BASIC                                          \
-  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
-
-/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
-   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
-   isn't minimal, since other operators, such as \`, aren't disabled.  */
-#define RE_SYNTAX_POSIX_MINIMAL_BASIC                                  \
-  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
-
-#define RE_SYNTAX_POSIX_EXTENDED                                       \
-  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
-   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES                          \
-   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR                            \
-   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
-
-/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
-   removed and RE_NO_BK_REFS is added.  */
-#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED                               \
-  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
-   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES                          \
-   | RE_NO_BK_PARENS        | RE_NO_BK_REFS                            \
-   | RE_NO_BK_VBAR         | RE_UNMATCHED_RIGHT_PAREN_ORD)
-/* [[[end syntaxes]]] */
-\f
-/* Maximum number of duplicates an interval can allow.  Some systems
-   (erroneously) define this in other header files, but we want our
-   value, so remove any previous define.  */
-#ifdef RE_DUP_MAX
-# undef RE_DUP_MAX
-#endif
-/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows.  */
-#define RE_DUP_MAX (0x7fff)
-
-
-/* POSIX `cflags' bits (i.e., information for `regcomp').  */
-
-/* If this bit is set, then use extended regular expression syntax.
-   If not set, then use basic regular expression syntax.  */
-#define REG_EXTENDED 1
-
-/* If this bit is set, then ignore case when matching.
-   If not set, then case is significant.  */
-#define REG_ICASE (REG_EXTENDED << 1)
-
-/* If this bit is set, then anchors do not match at newline
-     characters in the string.
-   If not set, then anchors do match at newlines.  */
-#define REG_NEWLINE (REG_ICASE << 1)
-
-/* If this bit is set, then report only success or fail in regexec.
-   If not set, then returns differ between not matching and errors.  */
-#define REG_NOSUB (REG_NEWLINE << 1)
-
-
-/* POSIX `eflags' bits (i.e., information for regexec).  */
-
-/* If this bit is set, then the beginning-of-line operator doesn't match
-     the beginning of the string (presumably because it's not the
-     beginning of a line).
-   If not set, then the beginning-of-line operator does match the
-     beginning of the string.  */
-#define REG_NOTBOL 1
-
-/* Like REG_NOTBOL, except for the end-of-line.  */
-#define REG_NOTEOL (1 << 1)
-
-
-/* If any error codes are removed, changed, or added, update the
-   `re_error_msg' table in regex.c.  */
-typedef enum
-{
-#ifdef _XOPEN_SOURCE
-  REG_ENOSYS = -1,     /* This will never happen for this implementation.  */
-#endif
-
-  REG_NOERROR = 0,     /* Success.  */
-  REG_NOMATCH,         /* Didn't find a match (for regexec).  */
-
-  /* POSIX regcomp return error codes.  (In the order listed in the
-     standard.)  */
-  REG_BADPAT,          /* Invalid pattern.  */
-  REG_ECOLLATE,                /* Not implemented.  */
-  REG_ECTYPE,          /* Invalid character class name.  */
-  REG_EESCAPE,         /* Trailing backslash.  */
-  REG_ESUBREG,         /* Invalid back reference.  */
-  REG_EBRACK,          /* Unmatched left bracket.  */
-  REG_EPAREN,          /* Parenthesis imbalance.  */
-  REG_EBRACE,          /* Unmatched \{.  */
-  REG_BADBR,           /* Invalid contents of \{\}.  */
-  REG_ERANGE,          /* Invalid range end.  */
-  REG_ESPACE,          /* Ran out of memory.  */
-  REG_BADRPT,          /* No preceding re for repetition op.  */
-
-  /* Error codes we've added.  */
-  REG_EEND,            /* Premature end.  */
-  REG_ESIZE,           /* Compiled pattern bigger than 2^16 bytes.  */
-  REG_ERPAREN          /* Unmatched ) or \); not returned from regcomp.  */
-} reg_errcode_t;
-\f
-/* This data structure represents a compiled pattern.  Before calling
-   the pattern compiler, the fields `buffer', `allocated', `fastmap',
-   `translate', and `no_sub' can be set.  After the pattern has been
-   compiled, the `re_nsub' field is available.  All other fields are
-   private to the regex routines.  */
-
-#ifndef RE_TRANSLATE_TYPE
-# define RE_TRANSLATE_TYPE char *
-#endif
-
-struct re_pattern_buffer
-{
-/* [[[begin pattern_buffer]]] */
-       /* Space that holds the compiled pattern.  It is declared as
-          `unsigned char *' because its elements are
-           sometimes used as array indexes.  */
-  unsigned char *buffer;
-
-       /* Number of bytes to which `buffer' points.  */
-  unsigned long int allocated;
-
-       /* Number of bytes actually used in `buffer'.  */
-  unsigned long int used;
-
-        /* Syntax setting with which the pattern was compiled.  */
-  reg_syntax_t syntax;
-
-        /* Pointer to a fastmap, if any, otherwise zero.  re_search uses
-           the fastmap, if there is one, to skip over impossible
-           starting points for matches.  */
-  char *fastmap;
-
-        /* Either a translate table to apply to all characters before
-           comparing them, or zero for no translation.  The translation
-           is applied to a pattern when it is compiled and to a string
-           when it is matched.  */
-  RE_TRANSLATE_TYPE translate;
-
-       /* Number of subexpressions found by the compiler.  */
-  size_t re_nsub;
-
-        /* Zero if this pattern cannot match the empty string, one else.
-           Well, in truth it's used only in `re_search_2', to see
-           whether or not we should use the fastmap, so we don't set
-           this absolutely perfectly; see `re_compile_fastmap' (the
-           `duplicate' case).  */
-  unsigned can_be_null : 1;
-
-        /* If REGS_UNALLOCATED, allocate space in the `regs' structure
-             for `max (RE_NREGS, re_nsub + 1)' groups.
-           If REGS_REALLOCATE, reallocate space if necessary.
-           If REGS_FIXED, use what's there.  */
-#define REGS_UNALLOCATED 0
-#define REGS_REALLOCATE 1
-#define REGS_FIXED 2
-  unsigned regs_allocated : 2;
-
-        /* Set to zero when `regex_compile' compiles a pattern; set to one
-           by `re_compile_fastmap' if it updates the fastmap.  */
-  unsigned fastmap_accurate : 1;
-
-        /* If set, `re_match_2' does not return information about
-           subexpressions.  */
-  unsigned no_sub : 1;
-
-        /* If set, a beginning-of-line anchor doesn't match at the
-           beginning of the string.  */
-  unsigned not_bol : 1;
-
-        /* Similarly for an end-of-line anchor.  */
-  unsigned not_eol : 1;
-
-        /* If true, an anchor at a newline matches.  */
-  unsigned newline_anchor : 1;
-
-/* [[[end pattern_buffer]]] */
-};
-
-typedef struct re_pattern_buffer regex_t;
-\f
-/* Type for byte offsets within the string.  POSIX mandates this.  */
-typedef int regoff_t;
-
-
-/* This is the structure we store register match data in.  See
-   regex.texinfo for a full description of what registers match.  */
-struct re_registers
-{
-  unsigned num_regs;
-  regoff_t *start;
-  regoff_t *end;
-};
-
-
-/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
-   `re_match_2' returns information about at least this many registers
-   the first time a `regs' structure is passed.  */
-#ifndef RE_NREGS
-# define RE_NREGS 30
-#endif
-
-
-/* POSIX specification for registers.  Aside from the different names than
-   `re_registers', POSIX uses an array of structures, instead of a
-   structure of arrays.  */
-typedef struct
-{
-  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
-  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
-} regmatch_t;
-\f
-/* Declarations for routines.  */
-
-/* To avoid duplicating every routine declaration -- once with a
-   prototype (if we are ANSI), and once without (if we aren't) -- we
-   use the following macro to declare argument types.  This
-   unfortunately clutters up the declarations a bit, but I think it's
-   worth it.  */
-
-#if __STDC__
-
-# define _RE_ARGS(args) args
-
-#else /* not __STDC__ */
-
-# define _RE_ARGS(args) ()
-
-#endif /* not __STDC__ */
-
-/* Sets the current default syntax to SYNTAX, and return the old syntax.
-   You can also simply assign to the `re_syntax_options' variable.  */
-extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
-
-/* Compile the regular expression PATTERN, with length LENGTH
-   and syntax given by the global `re_syntax_options', into the buffer
-   BUFFER.  Return NULL if successful, and an error string if not.  */
-extern const char *re_compile_pattern
-  _RE_ARGS ((const char *pattern, size_t length,
-             struct re_pattern_buffer *buffer));
-
-
-/* Compile a fastmap for the compiled pattern in BUFFER; used to
-   accelerate searches.  Return 0 if successful and -2 if was an
-   internal error.  */
-extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
-
-
-/* Search in the string STRING (with length LENGTH) for the pattern
-   compiled into BUFFER.  Start searching at position START, for RANGE
-   characters.  Return the starting position of the match, -1 for no
-   match, or -2 for an internal error.  Also return register
-   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
-extern int re_search
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
-            int length, int start, int range, struct re_registers *regs));
-
-
-/* Like `re_search', but search in the concatenation of STRING1 and
-   STRING2.  Also, stop searching at index START + STOP.  */
-extern int re_search_2
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
-             int length1, const char *string2, int length2,
-             int start, int range, struct re_registers *regs, int stop));
-
-
-/* Like `re_search', but return how many characters in STRING the regexp
-   in BUFFER matched, starting at position START.  */
-extern int re_match
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
-             int length, int start, struct re_registers *regs));
-
-
-/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
-extern int re_match_2
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
-             int length1, const char *string2, int length2,
-             int start, struct re_registers *regs, int stop));
-
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
-   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
-   for recording register information.  STARTS and ENDS must be
-   allocated with malloc, and must each be at least `NUM_REGS * sizeof
-   (regoff_t)' bytes long.
-
-   If NUM_REGS == 0, then subsequent matches should allocate their own
-   register data.
-
-   Unless this function is called, the first search or match using
-   PATTERN_BUFFER will allocate its own register data, without
-   freeing the old data.  */
-extern void re_set_registers
-  _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
-             unsigned num_regs, regoff_t *starts, regoff_t *ends));
-
-#if defined _REGEX_RE_COMP || defined _LIBC
-# ifndef _CRAY
-/* 4.2 bsd compatibility.  */
-extern char *re_comp _RE_ARGS ((const char *));
-extern int re_exec _RE_ARGS ((const char *));
-# endif
-#endif
-
-/* GCC 2.95 and later have "__restrict"; C99 compilers have
-   "restrict", and "configure" may have defined "restrict".  */
-#ifndef __restrict
-# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
-#  if defined restrict || 199901L <= __STDC_VERSION__
-#   define __restrict restrict
-#  else
-#   define __restrict
-#  endif
-# endif
-#endif
-/* gcc 3.1 and up support the [restrict] syntax.  */
-#ifndef __restrict_arr
-# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-#  define __restrict_arr __restrict
-# else
-#  define __restrict_arr
-# endif
-#endif
-
-/* POSIX compatibility.  */
-extern int regcomp _RE_ARGS ((regex_t *__restrict __preg,
-                             const char *__restrict __pattern,
-                             int __cflags));
-
-extern int regexec _RE_ARGS ((const regex_t *__restrict __preg,
-                             const char *__restrict __string, size_t __nmatch,
-                             regmatch_t __pmatch[__restrict_arr],
-                             int __eflags));
-
-extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
-                                 char *__errbuf, size_t __errbuf_size));
-
-extern void regfree _RE_ARGS ((regex_t *__preg));
-
-
-#ifdef __cplusplus
-}
-#endif /* C++ */
-
-#endif /* regex.h */
-\f
-/*
-Local variables:
-make-backup-files: t
-version-control: t
-trim-versions-without-asking: nil
-End:
-*/
diff --git a/include/cipher.h b/include/cipher.h
deleted file mode 100644 (file)
index 1b7e69b..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* cipher.h - Definitions for OpenPGP
- * Copyright (C) 1998, 1999, 2000, 2001, 2006,
- *               2007  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 3 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, see <http://www.gnu.org/licenses/>.
- */
-#ifndef G10_CIPHER_H
-#define G10_CIPHER_H
-
-#include <gcrypt.h>
-
-/* Macros for compatibility with older libgcrypt versions. */
-#ifndef GCRY_PK_USAGE_CERT
-# define GCRY_PK_USAGE_CERT 4
-# define GCRY_PK_USAGE_AUTH 8
-# define GCRY_PK_USAGE_UNKN 128
-#endif
-
-
-/* Constants for OpenPGP. */
-
-#define CIPHER_ALGO_NONE        /*  0 */  GCRY_CIPHER_NONE
-#define CIPHER_ALGO_IDEA        /*  1 */  GCRY_CIPHER_IDEA
-#define CIPHER_ALGO_3DES        /*  2 */  GCRY_CIPHER_3DES
-#define CIPHER_ALGO_CAST5       /*  3 */  GCRY_CIPHER_CAST5
-#define CIPHER_ALGO_BLOWFISH    /*  4 */  GCRY_CIPHER_BLOWFISH /* 128 bit */
-/* 5 & 6 are reserved */
-#define CIPHER_ALGO_AES          /*  7 */  GCRY_CIPHER_AES
-#define CIPHER_ALGO_AES192       /*  8 */  GCRY_CIPHER_AES192
-#define CIPHER_ALGO_AES256       /*  9 */  GCRY_CIPHER_AES256
-#define CIPHER_ALGO_RIJNDAEL     CIPHER_ALGO_AES
-#define CIPHER_ALGO_RIJNDAEL192  CIPHER_ALGO_AES192
-#define CIPHER_ALGO_RIJNDAEL256  CIPHER_ALGO_AES256
-#define CIPHER_ALGO_TWOFISH     /* 10 */  GCRY_CIPHER_TWOFISH  /* 256 bit */
-/* Note: Camellia ids don't match those used by libgcrypt. */
-#define CIPHER_ALGO_CAMELLIA128     11
-#define CIPHER_ALGO_CAMELLIA192     12
-#define CIPHER_ALGO_CAMELLIA256     13
-#define CIPHER_ALGO_DUMMY          110    /* No encryption at all. */
-
-#define PUBKEY_ALGO_RSA              1
-#define PUBKEY_ALGO_RSA_E            2 /* RSA encrypt only. */
-#define PUBKEY_ALGO_RSA_S            3 /* RSA sign only.    */
-#define PUBKEY_ALGO_ELGAMAL_E       16 /* Elgamal encr only */
-#define PUBKEY_ALGO_DSA             17
-#define PUBKEY_ALGO_ECDH            18
-#define PUBKEY_ALGO_ECDSA           19
-#define PUBKEY_ALGO_ELGAMAL         20 /* Elgamal encr+sign */
-
-#define PUBKEY_USAGE_SIG     GCRY_PK_USAGE_SIGN  /* Good for signatures. */
-#define PUBKEY_USAGE_ENC     GCRY_PK_USAGE_ENCR  /* Good for encryption. */
-#define PUBKEY_USAGE_CERT    GCRY_PK_USAGE_CERT  /* Also good to certify keys.*/
-#define PUBKEY_USAGE_AUTH    GCRY_PK_USAGE_AUTH  /* Good for authentication. */
-#define PUBKEY_USAGE_UNKNOWN GCRY_PK_USAGE_UNKN  /* Unknown usage flag. */
-#define PUBKEY_USAGE_NONE    256                 /* No usage given. */
-#if  (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR | GCRY_PK_USAGE_CERT \
-      | GCRY_PK_USAGE_AUTH | GCRY_PK_USAGE_UNKN) >= 256
-# error Please choose another value for PUBKEY_USAGE_NONE
-#endif
-
-#define DIGEST_ALGO_MD5       /*  1 */ GCRY_MD_MD5
-#define DIGEST_ALGO_SHA1      /*  2 */ GCRY_MD_SHA1
-#define DIGEST_ALGO_RMD160    /*  3 */ GCRY_MD_RMD160
-/* 4, 5, 6, and 7 are reserved */
-#define DIGEST_ALGO_SHA256    /*  8 */ GCRY_MD_SHA256
-#define DIGEST_ALGO_SHA384    /*  9 */ GCRY_MD_SHA384
-#define DIGEST_ALGO_SHA512    /* 10 */ GCRY_MD_SHA512
-/* SHA224 is only available in libgcrypt 1.4.0; thus we
-   can't use the GCRY macro here.  */
-#define DIGEST_ALGO_SHA224    /* 11 */ 11 /* GCRY_MD_SHA224 */
-
-#define COMPRESS_ALGO_NONE 0
-#define COMPRESS_ALGO_ZIP  1
-#define COMPRESS_ALGO_ZLIB 2
-#define COMPRESS_ALGO_BZIP2  3
-
-#define is_RSA(a)     ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
-                      || (a)==PUBKEY_ALGO_RSA_S )
-#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL_E)
-#define is_DSA(a)     ((a)==PUBKEY_ALGO_DSA)
-
-/* The data encryption key object. */
-typedef struct
-{
-  int algo;
-  int keylen;
-  int algo_info_printed;
-  int use_mdc;
-  int symmetric;
-  byte key[32]; /* This is the largest used keylen (256 bit). */
-  char s2k_cacheid[1+16+1];
-} DEK;
-
-
-
-/* Constants to allocate static MPI arrays. */
-#define PUBKEY_MAX_NPKEY  4
-#define PUBKEY_MAX_NSKEY  6
-#define PUBKEY_MAX_NSIG   2
-#define PUBKEY_MAX_NENC   2
-
-#endif /*G10_CIPHER_H*/
diff --git a/include/types.h b/include/types.h
deleted file mode 100644 (file)
index 8a861bc..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/* types.h - some common typedefs
- *     Copyright (C) 1998, 1999, 2000, 2001 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef G10_TYPES_H
-#define G10_TYPES_H
-
-#ifdef HAVE_INTTYPES_H
-/* For uint64_t */
-#include <inttypes.h>
-#endif
-
-/* The AC_CHECK_SIZEOF() in configure fails for some machines.
- * we provide some fallback values here */
-#if !SIZEOF_UNSIGNED_SHORT
-#undef SIZEOF_UNSIGNED_SHORT
-#define SIZEOF_UNSIGNED_SHORT 2
-#endif
-#if !SIZEOF_UNSIGNED_INT
-#undef SIZEOF_UNSIGNED_INT
-#define SIZEOF_UNSIGNED_INT 4
-#endif
-#if !SIZEOF_UNSIGNED_LONG
-#undef SIZEOF_UNSIGNED_LONG
-#define SIZEOF_UNSIGNED_LONG 4
-#endif
-
-
-#include <sys/types.h>
-
-
-#ifndef HAVE_BYTE_TYPEDEF
-#undef byte        /* maybe there is a macro with this name */
-#ifndef __riscos__
-typedef unsigned char byte;
-#else 
-/* Norcroft treats char  = unsigned char  as legal assignment
-               but char* = unsigned char* as illegal assignment
-   and the same applies to the signed variants as well  */
-typedef char byte;
-#endif
-#define HAVE_BYTE_TYPEDEF
-#endif
-
-#ifndef HAVE_USHORT_TYPEDEF
-#undef ushort     /* maybe there is a macro with this name */
-typedef unsigned short ushort;
-#define HAVE_USHORT_TYPEDEF
-#endif
-
-#ifndef HAVE_ULONG_TYPEDEF
-#undef ulong       /* maybe there is a macro with this name */
-typedef unsigned long ulong;
-#define HAVE_ULONG_TYPEDEF
-#endif
-
-#ifndef HAVE_U16_TYPEDEF
-#undef u16         /* maybe there is a macro with this name */
-#if SIZEOF_UNSIGNED_INT == 2
-typedef unsigned int   u16;
-#elif SIZEOF_UNSIGNED_SHORT == 2
-typedef unsigned short u16;
-#else
-#error no typedef for u16
-#endif
-#define HAVE_U16_TYPEDEF
-#endif
-
-#ifndef HAVE_U32_TYPEDEF
-#undef u32         /* maybe there is a macro with this name */
-#if SIZEOF_UNSIGNED_INT == 4
-typedef unsigned int u32;
-#elif SIZEOF_UNSIGNED_LONG == 4
-typedef unsigned long u32;
-#else
-#error no typedef for u32
-#endif
-#define HAVE_U32_TYPEDEF
-#endif
-
-/****************
- * Warning: Some systems segfault when this u64 typedef and
- * the dummy code in cipher/md.c is not available.  Examples are
- * Solaris and IRIX.
- */
-#ifndef HAVE_U64_TYPEDEF
-#undef u64         /* maybe there is a macro with this name */
-#if SIZEOF_UINT64_T == 8
-typedef uint64_t u64;
-#define U64_C(c) (UINT64_C(c))
-#define HAVE_U64_TYPEDEF
-#elif SIZEOF_UNSIGNED_INT == 8
-typedef unsigned int u64;
-#define U64_C(c) (c ## U)
-#define HAVE_U64_TYPEDEF
-#elif SIZEOF_UNSIGNED_LONG == 8
-typedef unsigned long u64;
-#define U64_C(c) (c ## UL)
-#define HAVE_U64_TYPEDEF
-#elif SIZEOF_UNSIGNED_LONG_LONG == 8
-typedef unsigned long long u64;
-#define U64_C(c) (c ## ULL)
-#define HAVE_U64_TYPEDEF
-#endif
-#endif
-
-typedef union {
-    int a;
-    short b;
-    char c[1];
-    long d;
-#ifdef HAVE_U64_TYPEDEF
-    u64 e;
-#endif
-    float f;
-    double g;
-} PROPERLY_ALIGNED_TYPE;
-
-#endif /*G10_TYPES_H*/
diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am
deleted file mode 100644 (file)
index 2ba2fbf..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# Makefile for the JNLIB part of GnuPG
-# Copyright (C) 1999, 2000, 2001, 2004,
-#               2006 Feee Software Soundation, Inc.
-#
-# This file is part of JNLIB.
-#
-# JNLIB is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 3 of
-# the License, or (at your option) any later version.
-#
-# JNLIB 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-
-## Process this file with automake to produce Makefile.in
-
-EXTRA_DIST = README ChangeLog-2011
-noinst_PROGRAMS = $(module_tests)
-TESTS = $(module_tests)
-
-AM_CPPFLAGS = -I$(top_srcdir)/intl
-
-# We need libgcrypt because libjnlib-config includes gcrypt.h
-AM_CFLAGS = -DJNLIB_IN_JNLIB $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS)
-
-noinst_LIBRARIES = libjnlib.a
-
-
-#libjnlib_a_LDFLAGS =
-libjnlib_a_SOURCES = \
-       libjnlib-config.h \
-       stringhelp.c stringhelp.h \
-       strlist.c strlist.h \
-       utf8conv.c utf8conv.h \
-       argparse.c argparse.h \
-       logging.c logging.h  \
-       dotlock.c dotlock.h  \
-       types.h mischelp.c mischelp.h dynload.h w32help.h
-
-if HAVE_W32_SYSTEM
-libjnlib_a_SOURCES += w32-reg.c w32-afunix.c w32-afunix.h w32-gettext.c
-endif
-
-
-# For GnuPG we don't need the xmalloc stuff.
-#       xmalloc.c xmalloc.h
-
-
-#
-# Module tests.
-#
-# These tests should only be used at the canonical location of jnlib
-# which is the GnuPG package.  The reason for this is that t-support.c
-# defines replacements for the actual used memory allocation functions
-# so that there is no dependency on libgcrypt.
-#
-module_tests = t-stringhelp
-
-t_jnlib_src = t-support.c t-support.h
-t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV)
-
-t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src)
-t_stringhelp_LDADD = $(t_jnlib_ldadd)
-
diff --git a/jnlib/README b/jnlib/README
deleted file mode 100644 (file)
index 5536e1a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-JNLIB - This is a collection of utility function which are too small
-to put into a library.  The code here is licensed under the LGPL.
-
-libjnlib-config.h should be be modified for each project to make these
-functions fit into the software. Mainly these are memory functions in
-case you need another allocator.
-
-
diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c
deleted file mode 100644 (file)
index 2578658..0000000
+++ /dev/null
@@ -1,703 +0,0 @@
-/* dotlock.c - dotfile locking
- * Copyright (C) 1998, 2000, 2001, 2003, 2004,
- *               2005, 2006, 2008 Free Software Foundation, Inc.
- *
- * This file is part of JNLIB.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * JNLIB 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#ifdef  HAVE_DOSISH_SYSTEM
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#else
-# include <sys/utsname.h>
-#endif
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include "libjnlib-config.h"
-#include "stringhelp.h"
-#include "dotlock.h"
-
-#if !defined(DIRSEP_C) && !defined(EXTSEP_C) \
-    && !defined(DIRSEP_S) && !defined(EXTSEP_S)
-#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
-#endif
-
-
-/* The object describing a lock.  */
-struct dotlock_handle
-{
-  struct dotlock_handle *next;
-  char *lockname;      /* Name of the actual lockfile.          */
-  int locked;          /* Lock status.                          */
-  int disable;         /* If true, locking is disabled.         */
-
-#ifdef HAVE_DOSISH_SYSTEM
-  HANDLE lockhd;       /* The W32 handle of the lock file.      */
-#else
-  char *tname;         /* Name of the lockfile template.        */
-  size_t nodename_off; /* Offset in TNAME of the nodename part. */
-  size_t nodename_len; /* Length of the nodename part.          */
-#endif /* HAVE_DOSISH_SYSTEM */
-};
-
-
-/* A list of of all lock handles. */
-static volatile DOTLOCK all_lockfiles;
-
-/* If this has the value true all locking is disabled.  */
-static int never_lock;
-
-
-/* Local protototypes.  */
-#ifndef HAVE_DOSISH_SYSTEM
-static int read_lockfile (DOTLOCK h, int *same_node);
-#endif /*!HAVE_DOSISH_SYSTEM*/
-
-
-
-\f
-/* Entirely disable all locking.  This function should be called
-   before any locking is done.  It may be called right at startup of
-   the process as it only sets a global value.  */
-void
-disable_dotlock(void)
-{
-  never_lock = 1;
-}
-
-
-
-/* Create a lockfile for a file name FILE_TO_LOCK and returns an
-   object of type DOTLOCK which may be used later to actually acquire
-   the lock.  A cleanup routine gets installed to cleanup left over
-   locks or other files used internally by the lock mechanism.
-
-   Calling this function with NULL does only install the atexit
-   handler and may thus be used to assure that the cleanup is called
-   after all other atexit handlers.
-
-   This function creates a lock file in the same directory as
-   FILE_TO_LOCK using that name and a suffix of ".lock".  Note that on
-   POSIX systems a temporary file ".#lk.<hostname>.pid[.threadid] is
-   used.
-
-   The function returns an new handle which needs to be released using
-   destroy_dotlock but gets also released at the termination of the
-   process.  On error NULL is returned.
- */
-DOTLOCK
-create_dotlock (const char *file_to_lock)
-{
-  static int initialized;
-  DOTLOCK h;
-#ifndef  HAVE_DOSISH_SYSTEM
-  int  fd = -1;
-  char pidstr[16];
-  const char *nodename;
-  const char *dirpart;
-  int dirpartlen;
-  struct utsname utsbuf;
-  size_t tnamelen;
-#endif
-
-  if ( !initialized )
-    {
-      atexit (dotlock_remove_lockfiles);
-      initialized = 1;
-    }
-
-  if ( !file_to_lock )
-    return NULL;  /* Only initialization was requested.  */
-
-  h = jnlib_calloc (1, sizeof *h);
-  if (!h)
-    return NULL;
-
-  if (never_lock)
-    {
-      h->disable = 1;
-#ifdef _REENTRANT
-      /* fixme: aquire mutex on all_lockfiles */
-#endif
-      h->next = all_lockfiles;
-      all_lockfiles = h;
-      return h;
-    }
-
-#ifndef HAVE_DOSISH_SYSTEM
-  /*
-     This is the POSIX version which uses a temporary file and the
-     link system call to make locking an atomic operation.
-   */
-
-  snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );
-
-  /* Create a temporary file. */
-  if ( uname ( &utsbuf ) )
-    nodename = "unknown";
-  else
-    nodename = utsbuf.nodename;
-
-#ifdef __riscos__
-  {
-    char *iter = (char *) nodename;
-    for (; iter[0]; iter++)
-      if (iter[0] == '.')
-        iter[0] = '/';
-  }
-#endif /* __riscos__ */
-
-  if ( !(dirpart = strrchr (file_to_lock, DIRSEP_C)) )
-    {
-      dirpart = EXTSEP_S;
-      dirpartlen = 1;
-    }
-  else
-    {
-      dirpartlen = dirpart - file_to_lock;
-      dirpart = file_to_lock;
-    }
-
-#ifdef _REENTRANT
-    /* fixme: aquire mutex on all_lockfiles */
-#endif
-  h->next = all_lockfiles;
-  all_lockfiles = h;
-
-  tnamelen = dirpartlen + 6 + 30 + strlen(nodename) + 10;
-  h->tname = jnlib_malloc (tnamelen + 1);
-  if (!h->tname)
-    {
-      all_lockfiles = h->next;
-      jnlib_free (h);
-      return NULL;
-    }
-  h->nodename_len = strlen (nodename);
-
-#ifndef __riscos__
-  snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h );
-  h->nodename_off = strlen (h->tname);
-  snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off,
-           "%s.%d", nodename, (int)getpid ());
-#else /* __riscos__ */
-  snprintf (h->tname, tnamelen, "%.*s.lk%p/", dirpartlen, dirpart, h );
-  h->nodename_off = strlen (h->tname);
-  snprintf (h->tname+h->nodename_off, tnamelen - h->modename_off,
-            "%s/%d", nodename, (int)getpid () );
-#endif /* __riscos__ */
-
-  do
-    {
-      errno = 0;
-      fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
-                 S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
-    }
-  while (fd == -1 && errno == EINTR);
-
-  if ( fd == -1 )
-    {
-      all_lockfiles = h->next;
-      log_error (_("failed to create temporary file `%s': %s\n"),
-                  h->tname, strerror(errno));
-      jnlib_free (h->tname);
-      jnlib_free (h);
-      return NULL;
-    }
-  if ( write (fd, pidstr, 11 ) != 11 )
-    goto write_failed;
-  if ( write (fd, nodename, strlen (nodename) ) != strlen (nodename) )
-    goto write_failed;
-  if ( write (fd, "\n", 1 ) != 1 )
-    goto write_failed;
-  if ( close (fd) )
-    {
-      if ( errno == EINTR )
-        fd = -1;
-      goto write_failed;
-    }
-  fd = -1;
-
-# ifdef _REENTRANT
-  /* release mutex */
-# endif
-  h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 );
-  if (!h->lockname)
-    {
-      all_lockfiles = h->next;
-      unlink (h->tname);
-      jnlib_free (h->tname);
-      jnlib_free (h);
-      return NULL;
-    }
-  strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
-  return h;
-
- write_failed:
-  all_lockfiles = h->next;
-# ifdef _REENTRANT
-  /* fixme: release mutex */
-# endif
-  log_error ( _("error writing to `%s': %s\n"), h->tname, strerror(errno) );
-  if (fd != -1)
-    close (fd);
-  unlink (h->tname);
-  jnlib_free (h->tname);
-  jnlib_free (h);
-  return NULL;
-
-#else /* HAVE_DOSISH_SYSTEM */
-
-  /* The Windows version does not need a temporary file but uses the
-     plain lock file along with record locking.  We create this file
-     here so that we later do only need to do the file locking.  For
-     error reporting it is useful to keep the name of the file in the
-     handle.  */
-  h->next = all_lockfiles;
-  all_lockfiles = h;
-
-  h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 );
-  if (!h->lockname)
-    {
-      all_lockfiles = h->next;
-      jnlib_free (h);
-      return NULL;
-    }
-  strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
-
-  /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
-     along with FILE_SHARE_DELETE but that does not work due to a race
-     condition: Despite the OPEN_ALWAYS flag CreateFile may return an
-     error and we can't reliable create/open the lock file unless we
-     would wait here until it works - however there are other valid
-     reasons why a lock file can't be created and thus the process
-     would not stop as expected but spin til until Windows crashes.
-     Our solution is to keep the lock file open; that does not
-     harm. */
-  h->lockhd = CreateFile (h->lockname,
-                          GENERIC_READ|GENERIC_WRITE,
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL, OPEN_ALWAYS, 0, NULL);
-  if (h->lockhd == INVALID_HANDLE_VALUE)
-    {
-      log_error (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1));
-      all_lockfiles = h->next;
-      jnlib_free (h->lockname);
-      jnlib_free (h);
-      return NULL;
-    }
-  return h;
-
-#endif /* HAVE_DOSISH_SYSTEM */
-}
-
-
-/* Destroy the local handle H and release the lock. */
-void
-destroy_dotlock ( DOTLOCK h )
-{
-  DOTLOCK hprev, htmp;
-
-  if ( !h )
-    return;
-
-  /* First remove the handle from our global list of all locks. */
-  for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next)
-    if (htmp == h)
-      {
-        if (hprev)
-          hprev->next = htmp->next;
-        else
-          all_lockfiles = htmp->next;
-        h->next = NULL;
-        break;
-      }
-
-  /* Then destroy the lock. */
-  if (!h->disable)
-    {
-#ifdef HAVE_DOSISH_SYSTEM
-      if (h->locked)
-        {
-          UnlockFile (h->lockhd, 0, 0, 1, 0);
-        }
-      CloseHandle (h->lockhd);
-#else /* !HAVE_DOSISH_SYSTEM */
-      if (h->locked && h->lockname)
-        unlink (h->lockname);
-      if (h->tname)
-        unlink (h->tname);
-      jnlib_free (h->tname);
-#endif /* HAVE_DOSISH_SYSTEM */
-      jnlib_free (h->lockname);
-    }
-  jnlib_free(h);
-}
-
-
-#ifndef HAVE_DOSISH_SYSTEM
-static int
-maybe_deadlock( DOTLOCK h )
-{
-  DOTLOCK r;
-
-  for ( r=all_lockfiles; r; r = r->next )
-    {
-      if ( r != h && r->locked )
-        return 1;
-    }
-  return 0;
-}
-#endif /*!HAVE_DOSISH_SYSTEM*/
-
-
-
-/* Do a lock on H. A TIMEOUT of 0 returns immediately, -1 waits
-   forever (hopefully not), other values are reserved (should then be
-   timeouts in milliseconds).  Returns: 0 on success  */
-int
-make_dotlock ( DOTLOCK h, long timeout )
-{
-  int backoff = 0;
-#ifndef HAVE_DOSISH_SYSTEM
-  int  pid;
-  const char *maybe_dead="";
-  int same_node;
-#endif /*!HAVE_DOSISH_SYSTEM*/
-
-  if ( h->disable )
-    return 0; /* Locks are completely disabled.  Return success. */
-
-  if ( h->locked )
-    {
-#ifndef __riscos__
-      log_debug ("Oops, `%s' is already locked\n", h->lockname);
-#endif /* !__riscos__ */
-      return 0;
-    }
-
-  for (;;)
-    {
-#ifndef HAVE_DOSISH_SYSTEM
-# ifndef __riscos__
-      if ( !link(h->tname, h->lockname) )
-        {
-          /* fixme: better use stat to check the link count */
-          h->locked = 1;
-          return 0; /* okay */
-       }
-      if ( errno != EEXIST )
-        {
-          log_error ( "lock not made: link() failed: %s\n", strerror(errno) );
-          return -1;
-       }
-# else /* __riscos__ */
-      if ( !renamefile(h->tname, h->lockname) )
-        {
-          h->locked = 1;
-          return 0; /* okay */
-        }
-      if ( errno != EEXIST )
-        {
-          log_error( "lock not made: rename() failed: %s\n", strerror(errno) );
-          return -1;
-        }
-# endif /* __riscos__ */
-
-      if ( (pid = read_lockfile (h, &same_node)) == -1 )
-        {
-          if ( errno != ENOENT )
-            {
-              log_info ("cannot read lockfile\n");
-              return -1;
-           }
-          log_info( "lockfile disappeared\n");
-          continue;
-       }
-      else if ( pid == getpid() && same_node )
-        {
-          log_info( "Oops: lock already held by us\n");
-          h->locked = 1;
-          return 0; /* okay */
-       }
-      else if ( same_node && kill (pid, 0) && errno == ESRCH )
-        {
-# ifndef __riscos__
-          log_info (_("removing stale lockfile (created by %d)\n"), pid );
-          unlink (h->lockname);
-          continue;
-# else /* __riscos__ */
-          /* Under RISCOS we are *pretty* sure that the other task
-             is dead and therefore we remove the stale lock file. */
-          maybe_dead = _(" - probably dead - removing lock");
-          unlink(h->lockname);
-# endif /* __riscos__ */
-       }
-
-      if ( timeout == -1 )
-        {
-          /* Wait until lock has been released. */
-          struct timeval tv;
-
-          log_info (_("waiting for lock (held by %d%s) %s...\n"),
-                    pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
-
-
-          /* We can't use sleep, cause signals may be blocked. */
-          tv.tv_sec = 1 + backoff;
-          tv.tv_usec = 0;
-          select(0, NULL, NULL, NULL, &tv);
-          if ( backoff < 10 )
-            backoff++ ;
-       }
-      else
-        return -1;
-#else /*HAVE_DOSISH_SYSTEM*/
-      int w32err;
-
-      if (LockFile (h->lockhd, 0, 0, 1, 0))
-        {
-          h->locked = 1;
-          return 0; /* okay */
-        }
-      w32err = GetLastError ();
-      if (w32err != ERROR_LOCK_VIOLATION)
-        {
-          log_error (_("lock `%s' not made: %s\n"),
-                     h->lockname, w32_strerror (w32err));
-          return -1;
-        }
-
-      if ( timeout == -1 )
-        {
-          /* Wait until lock has been released. */
-          log_info (_("waiting for lock %s...\n"), h->lockname);
-          Sleep ((1 + backoff)*1000);
-          if ( backoff < 10 )
-            backoff++ ;
-       }
-      else
-        return -1;
-#endif /*HAVE_DOSISH_SYSTEM*/
-    }
-  /*NOTREACHED*/
-}
-
-
-/* Release a lock.  Returns 0 on success.  */
-int
-release_dotlock( DOTLOCK h )
-{
-#ifndef HAVE_DOSISH_SYSTEM
-  int pid, same_node;
-#endif
-
-  /* To avoid atexit race conditions we first check whether there are
-     any locks left.  It might happen that another atexit handler
-     tries to release the lock while the atexit handler of this module
-     already ran and thus H is undefined.  */
-  if (!all_lockfiles)
-    return 0;
-
-  if ( h->disable )
-    return 0;
-
-  if ( !h->locked )
-    {
-      log_debug("Oops, `%s' is not locked\n", h->lockname);
-      return 0;
-    }
-
-#ifdef HAVE_DOSISH_SYSTEM
-  if (!UnlockFile (h->lockhd, 0, 0, 1, 0))
-    {
-      log_error ("release_dotlock: error removing lockfile `%s': %s\n",
-                 h->lockname, w32_strerror (-1));
-      return -1;
-    }
-#else
-
-  pid = read_lockfile (h, &same_node);
-  if ( pid == -1 )
-    {
-      log_error( "release_dotlock: lockfile error\n");
-      return -1;
-    }
-  if ( pid != getpid() || !same_node )
-    {
-      log_error( "release_dotlock: not our lock (pid=%d)\n", pid);
-      return -1;
-    }
-
-#ifndef __riscos__
-  if ( unlink( h->lockname ) )
-    {
-      log_error ("release_dotlock: error removing lockfile `%s'\n",
-                 h->lockname);
-      return -1;
-    }
-  /* Fixme: As an extra check we could check whether the link count is
-     now really at 1. */
-#else /* __riscos__ */
-  if ( renamefile (h->lockname, h->tname) )
-    {
-      log_error ("release_dotlock: error renaming lockfile `%s' to `%s'\n",
-                 h->lockname, h->tname);
-      return -1;
-    }
-#endif /* __riscos__ */
-
-#endif /* !HAVE_DOSISH_SYSTEM */
-  h->locked = 0;
-  return 0;
-}
-
-
-/* Read the lock file and return the pid, returns -1 on error.  True
-   will be stored in the integer at address SAME_NODE if the lock file
-   has been created on the same node. */
-#ifndef HAVE_DOSISH_SYSTEM
-static int
-read_lockfile (DOTLOCK h, int *same_node )
-{
-  char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node
-                                   name are usually shorter. */
-  int fd;
-  int pid = -1;
-  char *buffer, *p;
-  size_t expected_len;
-  int res, nread;
-
-  *same_node = 0;
-  expected_len = 10 + 1 + h->nodename_len + 1;
-  if ( expected_len >= sizeof buffer_space)
-    {
-      buffer = jnlib_malloc (expected_len);
-      if (!buffer)
-        return -1;
-    }
-  else
-    buffer = buffer_space;
-
-  if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
-    {
-      int e = errno;
-      log_info ("error opening lockfile `%s': %s\n",
-                h->lockname, strerror(errno) );
-      if (buffer != buffer_space)
-        jnlib_free (buffer);
-      errno = e; /* Need to return ERRNO here. */
-      return -1;
-    }
-
-  p = buffer;
-  nread = 0;
-  do
-    {
-      res = read (fd, p, expected_len - nread);
-      if (res == -1 && errno == EINTR)
-        continue;
-      if (res < 0)
-        {
-          log_info ("error reading lockfile `%s'", h->lockname );
-          close (fd);
-          if (buffer != buffer_space)
-            jnlib_free (buffer);
-          errno = 0; /* Do not return an inappropriate ERRNO. */
-          return -1;
-        }
-      p += res;
-      nread += res;
-    }
-  while (res && nread != expected_len);
-  close(fd);
-
-  if (nread < 11)
-    {
-      log_info ("invalid size of lockfile `%s'", h->lockname );
-      if (buffer != buffer_space)
-        jnlib_free (buffer);
-      errno = 0; /* Better don't return an inappropriate ERRNO. */
-      return -1;
-    }
-
-  if (buffer[10] != '\n'
-      || (buffer[10] = 0, pid = atoi (buffer)) == -1
-#ifndef __riscos__
-      || !pid
-#else /* __riscos__ */
-      || (!pid && riscos_getpid())
-#endif /* __riscos__ */
-      )
-    {
-      log_error ("invalid pid %d in lockfile `%s'", pid, h->lockname );
-      if (buffer != buffer_space)
-        jnlib_free (buffer);
-      errno = 0;
-      return -1;
-    }
-
-  if (nread == expected_len
-      && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
-      && buffer[11+h->nodename_len] == '\n')
-    *same_node = 1;
-
-  if (buffer != buffer_space)
-    jnlib_free (buffer);
-  return pid;
-}
-#endif /* !HAVE_DOSISH_SYSTEM */
-
-
-/* Remove all lockfiles.  This is usually called by the atexit handler
-   installed by this module but may also be called by other
-   termination handlers.  */
-void
-dotlock_remove_lockfiles()
-{
-  DOTLOCK h, h2;
-
-  h = all_lockfiles;
-  all_lockfiles = NULL;
-
-  while ( h )
-    {
-      h2 = h->next;
-      destroy_dotlock (h);
-      h = h2;
-    }
-}
-
diff --git a/jnlib/dotlock.h b/jnlib/dotlock.h
deleted file mode 100644 (file)
index b2a0190..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* dotlock.h
- *     Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
- *
- * This file is part of JNLIB.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * JNLIB 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LIBJNLIB_DOTLOCK_H
-#define LIBJNLIB_DOTLOCK_H
-
-struct dotlock_handle;
-typedef struct dotlock_handle *DOTLOCK;
-
-void disable_dotlock (void);
-DOTLOCK create_dotlock(const char *file_to_lock);
-void destroy_dotlock ( DOTLOCK h );
-int make_dotlock (DOTLOCK h, long timeout);
-int release_dotlock (DOTLOCK h);
-void dotlock_remove_lockfiles (void);
-
-#endif /*LIBJNLIB_DOTLOCK_H*/
diff --git a/jnlib/dynload.h b/jnlib/dynload.h
deleted file mode 100644 (file)
index 5477465..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* dynload.h - Wrapper functions for run-time dynamic loading
- *      Copyright (C) 2003 Free Software Foundation, Inc.
- *
- * This file is part of JNLIB.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * JNLIB 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LIBJNLIB_DYNLOAD_H
-#define LIBJNLIB_DYNLOAD_H
-
-#ifndef __MINGW32__
-# include <dlfcn.h>
-#else
-# include <windows.h>
-
-# define RTLD_LAZY 0
-
-static inline void *
-dlopen (const char * name, int flag)
-{
-  void * hd = LoadLibrary (name);
-  (void)flag;
-  return hd;
-}
-
-static inline void *
-dlsym (void *hd, const char *sym)
-{
-  if (hd && sym)
-    {
-      void * fnc = GetProcAddress (hd, sym);
-      if (!fnc)
-        return NULL;
-      return fnc;
-    }
-  return NULL;
-}
-
-
-static inline const char *
-dlerror (void)
-{
-  static char buf[32];
-  sprintf (buf, "ec=%lu", GetLastError ());
-  return buf;
-}
-
-
-static inline int
-dlclose (void * hd)
-{
-  if (hd)
-    {
-      CloseHandle (hd);
-      return 0;
-    }
-  return -1;
-}  
-# endif /*__MINGW32__*/
-#endif /*LIBJNLIB_DYNLOAD_H*/
diff --git a/jnlib/logging.c b/jnlib/logging.c
deleted file mode 100644 (file)
index 028697b..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-/* logging.c - Useful logging functions
- * Copyright (C) 1998, 1999, 2000, 2001, 2003,
- *               2004, 2005, 2006, 2009 Free Software Foundation, Inc.
- *
- * This file is part of JNLIB.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * JNLIB 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include <config.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifndef HAVE_W32_SYSTEM
-#include <sys/socket.h>
-#include <sys/un.h>
-#endif /*!HAVE_W32_SYSTEM*/
-#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-
-
-#define JNLIB_NEED_LOG_LOGV 1
-#define JNLIB_NEED_AFLOCAL 1
-#include "libjnlib-config.h"
-#include "logging.h"
-
-#if defined (HAVE_FOPENCOOKIE) ||  defined (HAVE_FUNOPEN)
-#define USE_FUNWRITER 1
-#endif
-
-#ifdef HAVE_FOPENCOOKIE
-typedef ssize_t my_funopen_hook_ret_t;
-typedef size_t  my_funopen_hook_size_t;
-#else
-typedef int     my_funopen_hook_ret_t;
-typedef int     my_funopen_hook_size_t;
-#endif
-
-
-static FILE *logstream;
-static int log_socket = -1;
-static char prefix_buffer[80];
-static int with_time;
-static int with_prefix;
-static int with_pid;
-static unsigned long (*get_tid_callback)(void);
-static int running_detached;
-static int force_prefixes;
-
-static int missing_lf;
-static int errorcount;
-
-
-int
-log_get_errorcount (int clear)
-{
-    int n = errorcount;
-    if( clear )
-       errorcount = 0;
-    return n;
-}
-
-void
-log_inc_errorcount (void)
-{
-   errorcount++;
-}
-
-
-/* The follwing 3 functions are used by funopen to write logs to a
-   socket. */
-#ifdef USE_FUNWRITER
-struct fun_cookie_s {
-  int fd;
-  int quiet;
-  int want_socket;
-  int is_socket;
-  char name[1];
-};
-
-/* Write NBYTES of BUFFER to file descriptor FD. */
-static int
-writen (int fd, const void *buffer, size_t nbytes)
-{
-  const char *buf = buffer;
-  size_t nleft = nbytes;
-  int nwritten;
-  
-  while (nleft > 0)
-    {
-      nwritten = write (fd, buf, nleft);
-      if (nwritten < 0 && errno == EINTR)
-        continue;
-      if (nwritten < 0)
-        return -1;
-      nleft -= nwritten;
-      buf = buf + nwritten;
-    }
-  
-  return 0;
-}
-
-
-static my_funopen_hook_ret_t 
-fun_writer (void *cookie_arg, const char *buffer, my_funopen_hook_size_t size)
-{
-  struct fun_cookie_s *cookie = cookie_arg;
-
-  /* Note that we always try to reconnect to the socket but print
-     error messages only the first time an error occured.  If
-     RUNNING_DETACHED is set we don't fall back to stderr and even do
-     not print any error messages.  This is needed because detached
-     processes often close stderr and by writing to file descriptor 2
-     we might send the log message to a file not intended for logging
-     (e.g. a pipe or network connection). */
-  if (cookie->want_socket && cookie->fd == -1)
-    {
-      /* Not yet open or meanwhile closed due to an error. */
-      cookie->is_socket = 0;
-      cookie->fd = socket (PF_LOCAL, SOCK_STREAM, 0);
-      if (cookie->fd == -1)
-        {
-          if (!cookie->quiet && !running_detached
-              && isatty (fileno (stderr)))
-            fprintf (stderr, "failed to create socket for logging: %s\n",
-                     strerror(errno));
-        }
-      else
-        {
-          struct sockaddr_un addr;
-          size_t addrlen;
-          
-          memset (&addr, 0, sizeof addr);
-          addr.sun_family = PF_LOCAL;
-          strncpy (addr.sun_path, cookie->name, sizeof (addr.sun_path)-1);
-          addr.sun_path[sizeof (addr.sun_path)-1] = 0;
-          addrlen = SUN_LEN (&addr);
-      
-          if (connect (cookie->fd, (struct sockaddr *) &addr, addrlen) == -1)
-            {
-              if (!cookie->quiet && !running_detached
-                  && isatty (fileno (stderr)))
-                fprintf (stderr, "can't connect to `%s': %s\n",
-                         cookie->name, strerror(errno));
-              close (cookie->fd);
-              cookie->fd = -1;
-            }
-        }
-      
-      if (cookie->fd == -1)
-        {
-          if (!running_detached)
-            {
-              /* Due to all the problems with apps not running
-                 detached but being called with stderr closed or
-                 used for a different purposes, it does not make
-                 sense to switch to stderr.  We therefore disable it. */
-              if (!cookie->quiet)
-                {
-                  /* fputs ("switching logging to stderr\n", stderr);*/
-                  cookie->quiet = 1;
-                }
-              cookie->fd = -1; /*fileno (stderr);*/
-            }
-        }
-      else /* Connection has been established. */
-        {
-          cookie->quiet = 0;
-          cookie->is_socket = 1;
-        }
-    }
-
-  log_socket = cookie->fd;
-  if (cookie->fd != -1 && !writen (cookie->fd, buffer, size))
-    return (my_funopen_hook_ret_t)size; /* Okay. */ 
-
-  if (!running_detached && cookie->fd != -1
-      && isatty (fileno (stderr)))
-    {
-      if (*cookie->name)
-        fprintf (stderr, "error writing to `%s': %s\n",
-                 cookie->name, strerror(errno));
-      else
-        fprintf (stderr, "error writing to file descriptor %d: %s\n",
-                 cookie->fd, strerror(errno));
-    }
-  if (cookie->is_socket && cookie->fd != -1)
-    {
-      close (cookie->fd);
-      cookie->fd = -1;
-      log_socket = -1;
-    }
-
-  return (my_funopen_hook_ret_t)size;
-}
-
-static int
-fun_closer (void *cookie_arg)
-{
-  struct fun_cookie_s *cookie = cookie_arg;
-
-  if (cookie->fd != -1 && cookie->fd != 2)
-    close (cookie->fd);
-  jnlib_free (cookie);
-  log_socket = -1;
-  return 0;
-}
-#endif /*USE_FUNWRITER*/
-
-
-
-/* Common function to either set the logging to a file or a file
-   descriptor. */
-static void
-set_file_fd (const char *name, int fd) 
-{
-  FILE *fp;
-  int want_socket;
-#ifdef USE_FUNWRITER
-  struct fun_cookie_s *cookie;
-#endif
-
-  /* Close an open log stream.  */
-  if (logstream)
-    {
-      if (logstream != stderr && logstream != stdout)
-        fclose (logstream);
-      logstream = NULL;
-    }
-
-  /* Figure out what kind of logging we want.  */
-  if (name && !strcmp (name, "-"))
-    {
-      name = NULL;
-      fd = fileno (stderr);
-    }
-
-  if (name)
-    {
-      want_socket = (!strncmp (name, "socket://", 9) && name[9]);
-      if (want_socket)
-        name += 9;
-    }
-  else
-    {
-      want_socket = 0;
-    }
-
-  /* Setup a new stream.  */
-#ifdef USE_FUNWRITER
-  /* The xmalloc below is justified because we can expect that this
-     function is called only during initialization and there is no
-     easy way out of this error condition.  */
-  cookie = jnlib_xmalloc (sizeof *cookie + (name? strlen (name):0));
-  strcpy (cookie->name, name? name:"");
-  cookie->quiet = 0;
-  cookie->is_socket = 0;
-  cookie->want_socket = want_socket;
-  if (!name)
-    cookie->fd = fd;
-  else if (want_socket)
-    cookie->fd = -1;
-  else
-    {
-      do
-        cookie->fd = open (name, O_WRONLY|O_APPEND|O_CREAT,
-                           (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH));
-      while (cookie->fd == -1 && errno == EINTR);
-    }
-  log_socket = cookie->fd;
-
-#ifdef HAVE_FOPENCOOKIE
-  {
-    cookie_io_functions_t io = { NULL };
-    io.write = fun_writer;
-    io.close = fun_closer;
-    
-    fp = fopencookie (cookie, "w", io);
-  }
-#else /*!HAVE_FOPENCOOKIE*/
-  fp = funopen (cookie, NULL, fun_writer, NULL, fun_closer);
-#endif /*!HAVE_FOPENCOOKIE*/
-
-#else /*!USE_FUNWRITER*/
-
-  /* The system does not feature custom streams.  Thus fallback to
-     plain stdio. */
-  if (want_socket)
-    {
-      fprintf (stderr, "system does not support logging to a socket - "
-               "using stderr\n");
-      fp = stderr;
-    }
-  else if (name)
-    fp = fopen (name, "a");
-  else if (fd == 1)
-    fp = stdout;
-  else if (fd == 2)
-    fp = stderr;
-  else
-    fp = fdopen (fd, "a");
-
-  log_socket = -1; 
-
-#endif /*!USE_FUNWRITER*/
-
-  /* On error default to stderr.  */
-  if (!fp)
-    {
-      if (name)
-        fprintf (stderr, "failed to open log file `%s': %s\n",
-                 name, strerror(errno));
-      else
-        fprintf (stderr, "failed to fdopen file descriptor %d: %s\n",
-                 fd, strerror(errno));
-      /* We need to make sure that there is a log stream.  We use stderr. */
-      fp = stderr;
-    }
-  else
-    setvbuf (fp, NULL, _IOLBF, 0);
-  
-  logstream = fp;
-
-  /* We always need to print the prefix and the pid for socket mode,
-     so that the server reading the socket can do something
-     meaningful. */
-  force_prefixes = want_socket;
-
-  missing_lf = 0;
-}
-
-
-/* Set the file to write log to.  The special names NULL and "-" may
-   be used to select stderr and names formatted like
-   "socket:///home/foo/mylogs" may be used to write the logging to the
-   socket "/home/foo/mylogs".  If the connection to the socket fails
-   or a write error is detected, the function writes to stderr and
-   tries the next time again to connect the socket.
-  */
-void
-log_set_file (const char *name) 
-{
-  set_file_fd (name? name: "-", -1);
-}
-
-void
-log_set_fd (int fd)
-{
-  set_file_fd (NULL, fd);
-}
-
-
-void
-log_set_get_tid_callback (unsigned long (*cb)(void))
-{
-  get_tid_callback = cb;
-}
-
-
-void
-log_set_prefix (const char *text, unsigned int flags)
-{
-  if (text)
-    {
-      strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1);
-      prefix_buffer[sizeof (prefix_buffer)-1] = 0;
-    }
-  
-  with_prefix = (flags & JNLIB_LOG_WITH_PREFIX);
-  with_time = (flags & JNLIB_LOG_WITH_TIME);
-  with_pid  = (flags & JNLIB_LOG_WITH_PID);
-  running_detached = (flags & JNLIB_LOG_RUN_DETACHED);
-}
-
-
-const char *
-log_get_prefix (unsigned int *flags)
-{
-  if (flags)
-    {
-      *flags = 0;
-      if (with_prefix)
-        *flags |= JNLIB_LOG_WITH_PREFIX;
-      if (with_time)
-        *flags |= JNLIB_LOG_WITH_TIME;
-      if (with_pid)
-        *flags |= JNLIB_LOG_WITH_PID;
-      if (running_detached)
-        *flags |= JNLIB_LOG_RUN_DETACHED;
-    }
-  return prefix_buffer;
-}
-
-/* This function returns true if the file descriptor FD is in use for
-   logging.  This is preferable over a test using log_get_fd in that
-   it allows the logging code to use more then one file descriptor. */
-int
-log_test_fd (int fd)
-{
-  if (logstream)
-    {
-      int tmp = fileno (logstream);
-      if ( tmp != -1 && tmp == fd)
-        return 1;
-    }
-  if (log_socket != -1 && log_socket == fd)
-    return 1;
-  return 0;
-}
-
-int
-log_get_fd ()
-{
-  return fileno(logstream?logstream:stderr);
-}
-
-FILE *
-log_get_stream ()
-{
-  /* FIXME: We should not return stderr here but initialize the log
-     stream properly.  This might break more things than using stderr,
-     though */
-  return logstream?logstream:stderr;
-}
-
-static void
-do_logv (int level, const char *fmt, va_list arg_ptr)
-{
-  if (!logstream)
-    {
-      log_set_file (NULL); /* Make sure a log stream has been set.  */
-      assert (logstream);
-    }
-
-  if (missing_lf && level != JNLIB_LOG_CONT)
-    putc('\n', logstream );
-  missing_lf = 0;
-
-  if (level != JNLIB_LOG_CONT)
-    { /* Note this does not work for multiple line logging as we would
-       * need to print to a buffer first */
-      if (with_time && !force_prefixes)
-        {
-          struct tm *tp;
-          time_t atime = time (NULL);
-          
-          tp = localtime (&atime);
-          fprintf (logstream, "%04d-%02d-%02d %02d:%02d:%02d ",
-                   1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
-                   tp->tm_hour, tp->tm_min, tp->tm_sec );
-        }
-      if (with_prefix || force_prefixes)
-        fputs (prefix_buffer, logstream);
-      if (with_pid || force_prefixes)
-        {
-          if (get_tid_callback)
-            fprintf (logstream, "[%u.%lx]", 
-                     (unsigned int)getpid (), get_tid_callback ());
-          else
-            fprintf (logstream, "[%u]", (unsigned int)getpid ());
-        }
-      if (!with_time || force_prefixes)
-        putc (':', logstream);
-      /* A leading backspace suppresses the extra space so that we can
-         correctly output, programname, filename and linenumber. */
-      if (fmt && *fmt == '\b')
-        fmt++;
-      else
-        putc (' ', logstream);
-    }
-
-  switch (level)
-    {
-    case JNLIB_LOG_BEGIN: break;
-    case JNLIB_LOG_CONT: break;
-    case JNLIB_LOG_INFO: break;
-    case JNLIB_LOG_WARN: break;
-    case JNLIB_LOG_ERROR: break;
-    case JNLIB_LOG_FATAL: fputs("Fatal: ",logstream ); break;
-    case JNLIB_LOG_BUG: fputs("Ohhhh jeeee: ", logstream); break;
-    case JNLIB_LOG_DEBUG: fputs("DBG: ", logstream ); break;
-    default: fprintf(logstream,"[Unknown log level %d]: ", level ); break;
-    }
-
-
-  if (fmt)
-    {
-      vfprintf(logstream,fmt,arg_ptr) ;
-      if (*fmt && fmt[strlen(fmt)-1] != '\n')
-        missing_lf = 1;
-#ifdef HAVE_W32_SYSTEM
-      else
-        fflush (logstream);
-#endif
-    }
-
-  if (level == JNLIB_LOG_FATAL)
-    {
-      if (missing_lf)
-        putc('\n', logstream );
-      exit(2);
-    }
-  if (level == JNLIB_LOG_BUG)
-    {
-      if (missing_lf)
-        putc('\n', logstream );
-      abort();
-    }
-}
-
-static void
-do_log( int level, const char *fmt, ... )
-{
-    va_list arg_ptr ;
-
-    va_start( arg_ptr, fmt ) ;
-    do_logv( level, fmt, arg_ptr );
-    va_end(arg_ptr);
-}
-
-
-void
-log_logv (int level, const char *fmt, va_list arg_ptr)
-{
-  do_logv (level, fmt, arg_ptr);
-}
-
-void
-log_info( const char *fmt, ... )
-{
-    va_list arg_ptr ;
-
-    va_start( arg_ptr, fmt ) ;
-    do_logv( JNLIB_LOG_INFO, fmt, arg_ptr );
-    va_end(arg_ptr);
-}
-
-void
-log_error( const char *fmt, ... )
-{
-    va_list arg_ptr ;
-
-    va_start( arg_ptr, fmt ) ;
-    do_logv( JNLIB_LOG_ERROR, fmt, arg_ptr );
-    va_end(arg_ptr);
-    /* protect against counter overflow */
-    if( errorcount < 30000 )
-       errorcount++;
-}
-
-
-void
-log_fatal( const char *fmt, ... )
-{
-    va_list arg_ptr ;
-
-    va_start( arg_ptr, fmt ) ;
-    do_logv( JNLIB_LOG_FATAL, fmt, arg_ptr );
-    va_end(arg_ptr);
-    abort(); /* never called, but it makes the compiler happy */
-}
-
-void
-log_bug( const char *fmt, ... )
-{
-    va_list arg_ptr ;
-
-    va_start( arg_ptr, fmt ) ;
-    do_logv( JNLIB_LOG_BUG, fmt, arg_ptr );
-    va_end(arg_ptr);
-    abort(); /* never called, but it makes the compiler happy */
-}
-
-void
-log_debug( const char *fmt, ... )
-{
-    va_list arg_ptr ;
-
-    va_start( arg_ptr, fmt ) ;
-    do_logv( JNLIB_LOG_DEBUG, fmt, arg_ptr );
-    va_end(arg_ptr);
-}
-
-
-void
-log_printf (const char *fmt, ...)
-{
-  va_list arg_ptr;
-
-  va_start (arg_ptr, fmt);
-  do_logv (fmt ? JNLIB_LOG_CONT : JNLIB_LOG_BEGIN, fmt, arg_ptr);
-  va_end (arg_ptr);
-}
-
-/* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
-   dump, with TEXT just an empty string, print a trailing linefeed,
-   otherwise print an entire debug line. */
-void
-log_printhex (const char *text, const void *buffer, size_t length)
-{
-  if (text && *text)
-    log_debug ("%s ", text);
-  if (length)
-    {
-      const unsigned char *p = buffer;
-      log_printf ("%02X", *p);
-      for (length--, p++; length--; p++)
-        log_printf (" %02X", *p);
-    }
-  if (text)
-    log_printf ("\n");
-}
-
-
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
-void
-bug_at( const char *file, int line, const char *func )
-{
-    do_log( JNLIB_LOG_BUG,
-            ("... this is a bug (%s:%d:%s)\n"), file, line, func );
-    abort(); /* never called, but it makes the compiler happy */
-}
-#else
-void
-bug_at( const char *file, int line )
-{
-    do_log( JNLIB_LOG_BUG,
-            _("you found a bug ... (%s:%d)\n"), file, line);
-    abort(); /* never called, but it makes the compiler happy */
-}
-#endif
-
diff --git a/jnlib/w32-gettext.c b/jnlib/w32-gettext.c
deleted file mode 100644 (file)
index 14cb1e1..0000000
+++ /dev/null
@@ -1,1706 +0,0 @@
-/* w32-gettext.h - A simple gettext implementation for Windows targets.
-   Copyright (C) 1995, 1996, 1997, 1999, 2005, 2007,
-                 2008 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License
-   as published by the Free Software Foundation; either version 2.1 of
-   the License, or (at your option) any later version.
-
-   This program 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#if !defined (_WIN32) && !defined (__CYGWIN32__)
-#  error This module may only be build for Windows or Cygwin32
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <locale.h>
-#ifdef HAVE_WINSOCK2_H
-# include <winsock2.h>
-#endif
-#include <windows.h>
-
-#ifdef JNLIB_IN_JNLIB
-#include "libjnlib-config.h"
-#endif
-
-#ifndef jnlib_malloc
-# define jnlib_malloc(a)    malloc ((a))
-# define jnlib_calloc(a,b)  calloc ((a), (b))
-# define jnlib_free(a)      free ((a))
-# define jnlib_xstrdup(a)   my_xstrdup(a)
-#endif /*!jnlib_malloc*/
-
-
-\f
-/* localname.c from gettext BEGIN.  */
-
-/* Determine the current selected locale.
-   Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU Library General Public License as published
-   by the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library 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.  */
-
-/* Written by Ulrich Drepper <drepper@gnu.org>, 1995.  */
-/* Win32 code written by Tor Lillqvist <tml@iki.fi>.  */
-/* Renamed _nl_locale_name, removed unsed args, removed include files,
-   non-W32 code and changed comments <wk@gnupg.org>.  */
-
-/* Mingw headers don't have latest language and sublanguage codes.  */
-#ifndef LANG_AFRIKAANS
-#define LANG_AFRIKAANS 0x36
-#endif
-#ifndef LANG_ALBANIAN
-#define LANG_ALBANIAN 0x1c
-#endif
-#ifndef LANG_AMHARIC
-#define LANG_AMHARIC 0x5e
-#endif
-#ifndef LANG_ARABIC
-#define LANG_ARABIC 0x01
-#endif
-#ifndef LANG_ARMENIAN
-#define LANG_ARMENIAN 0x2b
-#endif
-#ifndef LANG_ASSAMESE
-#define LANG_ASSAMESE 0x4d
-#endif
-#ifndef LANG_AZERI
-#define LANG_AZERI 0x2c
-#endif
-#ifndef LANG_BASQUE
-#define LANG_BASQUE 0x2d
-#endif
-#ifndef LANG_BELARUSIAN
-#define LANG_BELARUSIAN 0x23
-#endif
-#ifndef LANG_BENGALI
-#define LANG_BENGALI 0x45
-#endif
-#ifndef LANG_BURMESE
-#define LANG_BURMESE 0x55
-#endif
-#ifndef LANG_CAMBODIAN
-#define LANG_CAMBODIAN 0x53
-#endif
-#ifndef LANG_CATALAN
-#define LANG_CATALAN 0x03
-#endif
-#ifndef LANG_CHEROKEE
-#define LANG_CHEROKEE 0x5c
-#endif
-#ifndef LANG_DIVEHI
-#define LANG_DIVEHI 0x65
-#endif
-#ifndef LANG_EDO
-#define LANG_EDO 0x66
-#endif
-#ifndef LANG_ESTONIAN
-#define LANG_ESTONIAN 0x25
-#endif
-#ifndef LANG_FAEROESE
-#define LANG_FAEROESE 0x38
-#endif
-#ifndef LANG_FARSI
-#define LANG_FARSI 0x29
-#endif
-#ifndef LANG_FRISIAN
-#define LANG_FRISIAN 0x62
-#endif
-#ifndef LANG_FULFULDE
-#define LANG_FULFULDE 0x67
-#endif
-#ifndef LANG_GAELIC
-#define LANG_GAELIC 0x3c
-#endif
-#ifndef LANG_GALICIAN
-#define LANG_GALICIAN 0x56
-#endif
-#ifndef LANG_GEORGIAN
-#define LANG_GEORGIAN 0x37
-#endif
-#ifndef LANG_GUARANI
-#define LANG_GUARANI 0x74
-#endif
-#ifndef LANG_GUJARATI
-#define LANG_GUJARATI 0x47
-#endif
-#ifndef LANG_HAUSA
-#define LANG_HAUSA 0x68
-#endif
-#ifndef LANG_HAWAIIAN
-#define LANG_HAWAIIAN 0x75
-#endif
-#ifndef LANG_HEBREW
-#define LANG_HEBREW 0x0d
-#endif
-#ifndef LANG_HINDI
-#define LANG_HINDI 0x39
-#endif
-#ifndef LANG_IBIBIO
-#define LANG_IBIBIO 0x69
-#endif
-#ifndef LANG_IGBO
-#define LANG_IGBO 0x70
-#endif
-#ifndef LANG_INDONESIAN
-#define LANG_INDONESIAN 0x21
-#endif
-#ifndef LANG_INUKTITUT
-#define LANG_INUKTITUT 0x5d
-#endif
-#ifndef LANG_KANNADA
-#define LANG_KANNADA 0x4b
-#endif
-#ifndef LANG_KANURI
-#define LANG_KANURI 0x71
-#endif
-#ifndef LANG_KASHMIRI
-#define LANG_KASHMIRI 0x60
-#endif
-#ifndef LANG_KAZAK
-#define LANG_KAZAK 0x3f
-#endif
-#ifndef LANG_KONKANI
-#define LANG_KONKANI 0x57
-#endif
-#ifndef LANG_KYRGYZ
-#define LANG_KYRGYZ 0x40
-#endif
-#ifndef LANG_LAO
-#define LANG_LAO 0x54
-#endif
-#ifndef LANG_LATIN
-#define LANG_LATIN 0x76
-#endif
-#ifndef LANG_LATVIAN
-#define LANG_LATVIAN 0x26
-#endif
-#ifndef LANG_LITHUANIAN
-#define LANG_LITHUANIAN 0x27
-#endif
-#ifndef LANG_MACEDONIAN
-#define LANG_MACEDONIAN 0x2f
-#endif
-#ifndef LANG_MALAY
-#define LANG_MALAY 0x3e
-#endif
-#ifndef LANG_MALAYALAM
-#define LANG_MALAYALAM 0x4c
-#endif
-#ifndef LANG_MALTESE
-#define LANG_MALTESE 0x3a
-#endif
-#ifndef LANG_MANIPURI
-#define LANG_MANIPURI 0x58
-#endif
-#ifndef LANG_MARATHI
-#define LANG_MARATHI 0x4e
-#endif
-#ifndef LANG_MONGOLIAN
-#define LANG_MONGOLIAN 0x50
-#endif
-#ifndef LANG_NEPALI
-#define LANG_NEPALI 0x61
-#endif
-#ifndef LANG_ORIYA
-#define LANG_ORIYA 0x48
-#endif
-#ifndef LANG_OROMO
-#define LANG_OROMO 0x72
-#endif
-#ifndef LANG_PAPIAMENTU
-#define LANG_PAPIAMENTU 0x79
-#endif
-#ifndef LANG_PASHTO
-#define LANG_PASHTO 0x63
-#endif
-#ifndef LANG_PUNJABI
-#define LANG_PUNJABI 0x46
-#endif
-#ifndef LANG_RHAETO_ROMANCE
-#define LANG_RHAETO_ROMANCE 0x17
-#endif
-#ifndef LANG_SAAMI
-#define LANG_SAAMI 0x3b
-#endif
-#ifndef LANG_SANSKRIT
-#define LANG_SANSKRIT 0x4f
-#endif
-#ifndef LANG_SERBIAN
-#define LANG_SERBIAN 0x1a
-#endif
-#ifndef LANG_SINDHI
-#define LANG_SINDHI 0x59
-#endif
-#ifndef LANG_SINHALESE
-#define LANG_SINHALESE 0x5b
-#endif
-#ifndef LANG_SLOVAK
-#define LANG_SLOVAK 0x1b
-#endif
-#ifndef LANG_SOMALI
-#define LANG_SOMALI 0x77
-#endif
-#ifndef LANG_SORBIAN
-#define LANG_SORBIAN 0x2e
-#endif
-#ifndef LANG_SUTU
-#define LANG_SUTU 0x30
-#endif
-#ifndef LANG_SWAHILI
-#define LANG_SWAHILI 0x41
-#endif
-#ifndef LANG_SYRIAC
-#define LANG_SYRIAC 0x5a
-#endif
-#ifndef LANG_TAGALOG
-#define LANG_TAGALOG 0x64
-#endif
-#ifndef LANG_TAJIK
-#define LANG_TAJIK 0x28
-#endif
-#ifndef LANG_TAMAZIGHT
-#define LANG_TAMAZIGHT 0x5f
-#endif
-#ifndef LANG_TAMIL
-#define LANG_TAMIL 0x49
-#endif
-#ifndef LANG_TATAR
-#define LANG_TATAR 0x44
-#endif
-#ifndef LANG_TELUGU
-#define LANG_TELUGU 0x4a
-#endif
-#ifndef LANG_THAI
-#define LANG_THAI 0x1e
-#endif
-#ifndef LANG_TIBETAN
-#define LANG_TIBETAN 0x51
-#endif
-#ifndef LANG_TIGRINYA
-#define LANG_TIGRINYA 0x73
-#endif
-#ifndef LANG_TSONGA
-#define LANG_TSONGA 0x31
-#endif
-#ifndef LANG_TSWANA
-#define LANG_TSWANA 0x32
-#endif
-#ifndef LANG_TURKMEN
-#define LANG_TURKMEN 0x42
-#endif
-#ifndef LANG_UKRAINIAN
-#define LANG_UKRAINIAN 0x22
-#endif
-#ifndef LANG_URDU
-#define LANG_URDU 0x20
-#endif
-#ifndef LANG_UZBEK
-#define LANG_UZBEK 0x43
-#endif
-#ifndef LANG_VENDA
-#define LANG_VENDA 0x33
-#endif
-#ifndef LANG_VIETNAMESE
-#define LANG_VIETNAMESE 0x2a
-#endif
-#ifndef LANG_WELSH
-#define LANG_WELSH 0x52
-#endif
-#ifndef LANG_XHOSA
-#define LANG_XHOSA 0x34
-#endif
-#ifndef LANG_YI
-#define LANG_YI 0x78
-#endif
-#ifndef LANG_YIDDISH
-#define LANG_YIDDISH 0x3d
-#endif
-#ifndef LANG_YORUBA
-#define LANG_YORUBA 0x6a
-#endif
-#ifndef LANG_ZULU
-#define LANG_ZULU 0x35
-#endif
-#ifndef SUBLANG_ARABIC_SAUDI_ARABIA
-#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
-#endif
-#ifndef SUBLANG_ARABIC_IRAQ
-#define SUBLANG_ARABIC_IRAQ 0x02
-#endif
-#ifndef SUBLANG_ARABIC_EGYPT
-#define SUBLANG_ARABIC_EGYPT 0x03
-#endif
-#ifndef SUBLANG_ARABIC_LIBYA
-#define SUBLANG_ARABIC_LIBYA 0x04
-#endif
-#ifndef SUBLANG_ARABIC_ALGERIA
-#define SUBLANG_ARABIC_ALGERIA 0x05
-#endif
-#ifndef SUBLANG_ARABIC_MOROCCO
-#define SUBLANG_ARABIC_MOROCCO 0x06
-#endif
-#ifndef SUBLANG_ARABIC_TUNISIA
-#define SUBLANG_ARABIC_TUNISIA 0x07
-#endif
-#ifndef SUBLANG_ARABIC_OMAN
-#define SUBLANG_ARABIC_OMAN 0x08
-#endif
-#ifndef SUBLANG_ARABIC_YEMEN
-#define SUBLANG_ARABIC_YEMEN 0x09
-#endif
-#ifndef SUBLANG_ARABIC_SYRIA
-#define SUBLANG_ARABIC_SYRIA 0x0a
-#endif
-#ifndef SUBLANG_ARABIC_JORDAN
-#define SUBLANG_ARABIC_JORDAN 0x0b
-#endif
-#ifndef SUBLANG_ARABIC_LEBANON
-#define SUBLANG_ARABIC_LEBANON 0x0c
-#endif
-#ifndef SUBLANG_ARABIC_KUWAIT
-#define SUBLANG_ARABIC_KUWAIT 0x0d
-#endif
-#ifndef SUBLANG_ARABIC_UAE
-#define SUBLANG_ARABIC_UAE 0x0e
-#endif
-#ifndef SUBLANG_ARABIC_BAHRAIN
-#define SUBLANG_ARABIC_BAHRAIN 0x0f
-#endif
-#ifndef SUBLANG_ARABIC_QATAR
-#define SUBLANG_ARABIC_QATAR 0x10
-#endif
-#ifndef SUBLANG_AZERI_LATIN
-#define SUBLANG_AZERI_LATIN 0x01
-#endif
-#ifndef SUBLANG_AZERI_CYRILLIC
-#define SUBLANG_AZERI_CYRILLIC 0x02
-#endif
-#ifndef SUBLANG_BENGALI_INDIA
-#define SUBLANG_BENGALI_INDIA 0x01
-#endif
-#ifndef SUBLANG_BENGALI_BANGLADESH
-#define SUBLANG_BENGALI_BANGLADESH 0x02
-#endif
-#ifndef SUBLANG_CHINESE_MACAU
-#define SUBLANG_CHINESE_MACAU 0x05
-#endif
-#ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
-#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
-#endif
-#ifndef SUBLANG_ENGLISH_JAMAICA
-#define SUBLANG_ENGLISH_JAMAICA 0x08
-#endif
-#ifndef SUBLANG_ENGLISH_CARIBBEAN
-#define SUBLANG_ENGLISH_CARIBBEAN 0x09
-#endif
-#ifndef SUBLANG_ENGLISH_BELIZE
-#define SUBLANG_ENGLISH_BELIZE 0x0a
-#endif
-#ifndef SUBLANG_ENGLISH_TRINIDAD
-#define SUBLANG_ENGLISH_TRINIDAD 0x0b
-#endif
-#ifndef SUBLANG_ENGLISH_ZIMBABWE
-#define SUBLANG_ENGLISH_ZIMBABWE 0x0c
-#endif
-#ifndef SUBLANG_ENGLISH_PHILIPPINES
-#define SUBLANG_ENGLISH_PHILIPPINES 0x0d
-#endif
-#ifndef SUBLANG_ENGLISH_INDONESIA
-#define SUBLANG_ENGLISH_INDONESIA 0x0e
-#endif
-#ifndef SUBLANG_ENGLISH_HONGKONG
-#define SUBLANG_ENGLISH_HONGKONG 0x0f
-#endif
-#ifndef SUBLANG_ENGLISH_INDIA
-#define SUBLANG_ENGLISH_INDIA 0x10
-#endif
-#ifndef SUBLANG_ENGLISH_MALAYSIA
-#define SUBLANG_ENGLISH_MALAYSIA 0x11
-#endif
-#ifndef SUBLANG_ENGLISH_SINGAPORE
-#define SUBLANG_ENGLISH_SINGAPORE 0x12
-#endif
-#ifndef SUBLANG_FRENCH_LUXEMBOURG
-#define SUBLANG_FRENCH_LUXEMBOURG 0x05
-#endif
-#ifndef SUBLANG_FRENCH_MONACO
-#define SUBLANG_FRENCH_MONACO 0x06
-#endif
-#ifndef SUBLANG_FRENCH_WESTINDIES
-#define SUBLANG_FRENCH_WESTINDIES 0x07
-#endif
-#ifndef SUBLANG_FRENCH_REUNION
-#define SUBLANG_FRENCH_REUNION 0x08
-#endif
-#ifndef SUBLANG_FRENCH_CONGO
-#define SUBLANG_FRENCH_CONGO 0x09
-#endif
-#ifndef SUBLANG_FRENCH_SENEGAL
-#define SUBLANG_FRENCH_SENEGAL 0x0a
-#endif
-#ifndef SUBLANG_FRENCH_CAMEROON
-#define SUBLANG_FRENCH_CAMEROON 0x0b
-#endif
-#ifndef SUBLANG_FRENCH_COTEDIVOIRE
-#define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
-#endif
-#ifndef SUBLANG_FRENCH_MALI
-#define SUBLANG_FRENCH_MALI 0x0d
-#endif
-#ifndef SUBLANG_FRENCH_MOROCCO
-#define SUBLANG_FRENCH_MOROCCO 0x0e
-#endif
-#ifndef SUBLANG_FRENCH_HAITI
-#define SUBLANG_FRENCH_HAITI 0x0f
-#endif
-#ifndef SUBLANG_GERMAN_LUXEMBOURG
-#define SUBLANG_GERMAN_LUXEMBOURG 0x04
-#endif
-#ifndef SUBLANG_GERMAN_LIECHTENSTEIN
-#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
-#endif
-#ifndef SUBLANG_KASHMIRI_INDIA
-#define SUBLANG_KASHMIRI_INDIA 0x02
-#endif
-#ifndef SUBLANG_MALAY_MALAYSIA
-#define SUBLANG_MALAY_MALAYSIA 0x01
-#endif
-#ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
-#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
-#endif
-#ifndef SUBLANG_NEPALI_INDIA
-#define SUBLANG_NEPALI_INDIA 0x02
-#endif
-#ifndef SUBLANG_PUNJABI_INDIA
-#define SUBLANG_PUNJABI_INDIA 0x01
-#endif
-#ifndef SUBLANG_ROMANIAN_ROMANIA
-#define SUBLANG_ROMANIAN_ROMANIA 0x01
-#endif
-#ifndef SUBLANG_SERBIAN_LATIN
-#define SUBLANG_SERBIAN_LATIN 0x02
-#endif
-#ifndef SUBLANG_SERBIAN_CYRILLIC
-#define SUBLANG_SERBIAN_CYRILLIC 0x03
-#endif
-#ifndef SUBLANG_SINDHI_INDIA
-#define SUBLANG_SINDHI_INDIA 0x00
-#endif
-#ifndef SUBLANG_SINDHI_PAKISTAN
-#define SUBLANG_SINDHI_PAKISTAN 0x01
-#endif
-#ifndef SUBLANG_SPANISH_GUATEMALA
-#define SUBLANG_SPANISH_GUATEMALA 0x04
-#endif
-#ifndef SUBLANG_SPANISH_COSTA_RICA
-#define SUBLANG_SPANISH_COSTA_RICA 0x05
-#endif
-#ifndef SUBLANG_SPANISH_PANAMA
-#define SUBLANG_SPANISH_PANAMA 0x06
-#endif
-#ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
-#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
-#endif
-#ifndef SUBLANG_SPANISH_VENEZUELA
-#define SUBLANG_SPANISH_VENEZUELA 0x08
-#endif
-#ifndef SUBLANG_SPANISH_COLOMBIA
-#define SUBLANG_SPANISH_COLOMBIA 0x09
-#endif
-#ifndef SUBLANG_SPANISH_PERU
-#define SUBLANG_SPANISH_PERU 0x0a
-#endif
-#ifndef SUBLANG_SPANISH_ARGENTINA
-#define SUBLANG_SPANISH_ARGENTINA 0x0b
-#endif
-#ifndef SUBLANG_SPANISH_ECUADOR
-#define SUBLANG_SPANISH_ECUADOR 0x0c
-#endif
-#ifndef SUBLANG_SPANISH_CHILE
-#define SUBLANG_SPANISH_CHILE 0x0d
-#endif
-#ifndef SUBLANG_SPANISH_URUGUAY
-#define SUBLANG_SPANISH_URUGUAY 0x0e
-#endif
-#ifndef SUBLANG_SPANISH_PARAGUAY
-#define SUBLANG_SPANISH_PARAGUAY 0x0f
-#endif
-#ifndef SUBLANG_SPANISH_BOLIVIA
-#define SUBLANG_SPANISH_BOLIVIA 0x10
-#endif
-#ifndef SUBLANG_SPANISH_EL_SALVADOR
-#define SUBLANG_SPANISH_EL_SALVADOR 0x11
-#endif
-#ifndef SUBLANG_SPANISH_HONDURAS
-#define SUBLANG_SPANISH_HONDURAS 0x12
-#endif
-#ifndef SUBLANG_SPANISH_NICARAGUA
-#define SUBLANG_SPANISH_NICARAGUA 0x13
-#endif
-#ifndef SUBLANG_SPANISH_PUERTO_RICO
-#define SUBLANG_SPANISH_PUERTO_RICO 0x14
-#endif
-#ifndef SUBLANG_SWEDISH_FINLAND
-#define SUBLANG_SWEDISH_FINLAND 0x02
-#endif
-#ifndef SUBLANG_TAMAZIGHT_ARABIC
-#define SUBLANG_TAMAZIGHT_ARABIC 0x01
-#endif
-#ifndef SUBLANG_TAMAZIGHT_LATIN
-#define SUBLANG_TAMAZIGHT_LATIN 0x02
-#endif
-#ifndef SUBLANG_TIGRINYA_ETHIOPIA
-#define SUBLANG_TIGRINYA_ETHIOPIA 0x00
-#endif
-#ifndef SUBLANG_TIGRINYA_ERITREA
-#define SUBLANG_TIGRINYA_ERITREA 0x01
-#endif
-#ifndef SUBLANG_URDU_PAKISTAN
-#define SUBLANG_URDU_PAKISTAN 0x01
-#endif
-#ifndef SUBLANG_URDU_INDIA
-#define SUBLANG_URDU_INDIA 0x02
-#endif
-#ifndef SUBLANG_UZBEK_LATIN
-#define SUBLANG_UZBEK_LATIN 0x01
-#endif
-#ifndef SUBLANG_UZBEK_CYRILLIC
-#define SUBLANG_UZBEK_CYRILLIC 0x02
-#endif
-
-/* Return an XPG style locale name
-     language[_territory[.codeset]][@modifier].
-   Don't even bother determining the codeset; it's not useful in this
-   context, because message catalogs are not specific to a single
-   codeset.  The result must not be freed; it is statically
-   allocated.  */
-static const char *
-my_nl_locale_name (const char *categoryname)
-{
-  const char *retval;
-  LCID lcid;
-  LANGID langid;
-  int primary, sub;
-
-  /* Let the user override the system settings through environment
-     variables, as on POSIX systems.  */
-  retval = getenv ("LC_ALL");
-  if (retval != NULL && retval[0] != '\0')
-    return retval;
-  retval = getenv (categoryname);
-  if (retval != NULL && retval[0] != '\0')
-    return retval;
-  retval = getenv ("LANG");
-  if (retval != NULL && retval[0] != '\0')
-    return retval;
-
-  /* Use native Win32 API locale ID.  */
-  lcid = GetThreadLocale ();
-
-  /* Strip off the sorting rules, keep only the language part.  */
-  langid = LANGIDFROMLCID (lcid);
-
-  /* Split into language and territory part.  */
-  primary = PRIMARYLANGID (langid);
-  sub = SUBLANGID (langid);
-
-  /* Dispatch on language.
-     See also http://www.unicode.org/unicode/onlinedat/languages.html .
-     For details about languages, see http://www.ethnologue.com/ .  */
-  switch (primary)
-    {
-    case LANG_AFRIKAANS: return "af_ZA";
-    case LANG_ALBANIAN: return "sq_AL";
-    case LANG_AMHARIC: return "am_ET";
-    case LANG_ARABIC:
-      switch (sub)
-       {
-       case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
-       case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
-       case SUBLANG_ARABIC_EGYPT: return "ar_EG";
-       case SUBLANG_ARABIC_LIBYA: return "ar_LY";
-       case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
-       case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
-       case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
-       case SUBLANG_ARABIC_OMAN: return "ar_OM";
-       case SUBLANG_ARABIC_YEMEN: return "ar_YE";
-       case SUBLANG_ARABIC_SYRIA: return "ar_SY";
-       case SUBLANG_ARABIC_JORDAN: return "ar_JO";
-       case SUBLANG_ARABIC_LEBANON: return "ar_LB";
-       case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
-       case SUBLANG_ARABIC_UAE: return "ar_AE";
-       case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
-       case SUBLANG_ARABIC_QATAR: return "ar_QA";
-       }
-      return "ar";
-    case LANG_ARMENIAN: return "hy_AM";
-    case LANG_ASSAMESE: return "as_IN";
-    case LANG_AZERI:
-      switch (sub)
-       {
-       /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
-       case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
-       case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
-       }
-      return "az";
-    case LANG_BASQUE:
-      return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
-    case LANG_BELARUSIAN: return "be_BY";
-    case LANG_BENGALI:
-      switch (sub)
-       {
-       case SUBLANG_BENGALI_INDIA: return "bn_IN";
-       case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
-       }
-      return "bn";
-    case LANG_BULGARIAN: return "bg_BG";
-    case LANG_BURMESE: return "my_MM";
-    case LANG_CAMBODIAN: return "km_KH";
-    case LANG_CATALAN: return "ca_ES";
-    case LANG_CHEROKEE: return "chr_US";
-    case LANG_CHINESE:
-      switch (sub)
-       {
-       case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
-       case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
-       case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
-       case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
-       case SUBLANG_CHINESE_MACAU: return "zh_MO";
-       }
-      return "zh";
-    case LANG_CROATIAN:                /* LANG_CROATIAN == LANG_SERBIAN
-                                * What used to be called Serbo-Croatian
-                                * should really now be two separate
-                                * languages because of political reasons.
-                                * (Says tml, who knows nothing about Serbian
-                                * or Croatian.)
-                                * (I can feel those flames coming already.)
-                                */
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "hr_HR";
-       case SUBLANG_SERBIAN_LATIN: return "sr_CS";
-       case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
-       }
-      return "hr";
-    case LANG_CZECH: return "cs_CZ";
-    case LANG_DANISH: return "da_DK";
-    case LANG_DIVEHI: return "div_MV";
-    case LANG_DUTCH:
-      switch (sub)
-       {
-       case SUBLANG_DUTCH: return "nl_NL";
-       case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
-       }
-      return "nl";
-    case LANG_EDO: return "bin_NG";
-    case LANG_ENGLISH:
-      switch (sub)
-       {
-       /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
-        * English was the language spoken in England.
-        * Oh well.
-        */
-       case SUBLANG_ENGLISH_US: return "en_US";
-       case SUBLANG_ENGLISH_UK: return "en_GB";
-       case SUBLANG_ENGLISH_AUS: return "en_AU";
-       case SUBLANG_ENGLISH_CAN: return "en_CA";
-       case SUBLANG_ENGLISH_NZ: return "en_NZ";
-       case SUBLANG_ENGLISH_EIRE: return "en_IE";
-       case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
-       case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
-       case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
-       case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
-       case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
-       case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
-       case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
-       case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
-       case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
-       case SUBLANG_ENGLISH_INDIA: return "en_IN";
-       case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
-       case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
-       }
-      return "en";
-    case LANG_ESTONIAN: return "et_EE";
-    case LANG_FAEROESE: return "fo_FO";
-    case LANG_FARSI: return "fa_IR";
-    case LANG_FINNISH: return "fi_FI";
-    case LANG_FRENCH:
-      switch (sub)
-       {
-       case SUBLANG_FRENCH: return "fr_FR";
-       case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
-       case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
-       case SUBLANG_FRENCH_SWISS: return "fr_CH";
-       case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
-       case SUBLANG_FRENCH_MONACO: return "fr_MC";
-       case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
-       case SUBLANG_FRENCH_REUNION: return "fr_RE";
-       case SUBLANG_FRENCH_CONGO: return "fr_CG";
-       case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
-       case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
-       case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
-       case SUBLANG_FRENCH_MALI: return "fr_ML";
-       case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
-       case SUBLANG_FRENCH_HAITI: return "fr_HT";
-       }
-      return "fr";
-    case LANG_FRISIAN: return "fy_NL";
-    case LANG_FULFULDE: return "ful_NG";
-    case LANG_GAELIC:
-      switch (sub)
-       {
-       case 0x01: /* SCOTTISH */ return "gd_GB";
-       case 0x02: /* IRISH */ return "ga_IE";
-       }
-      return "C";
-    case LANG_GALICIAN: return "gl_ES";
-    case LANG_GEORGIAN: return "ka_GE";
-    case LANG_GERMAN:
-      switch (sub)
-       {
-       case SUBLANG_GERMAN: return "de_DE";
-       case SUBLANG_GERMAN_SWISS: return "de_CH";
-       case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
-       case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
-       case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
-       }
-      return "de";
-    case LANG_GREEK: return "el_GR";
-    case LANG_GUARANI: return "gn_PY";
-    case LANG_GUJARATI: return "gu_IN";
-    case LANG_HAUSA: return "ha_NG";
-    case LANG_HAWAIIAN:
-      /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
-        or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
-      return "cpe_US";
-    case LANG_HEBREW: return "he_IL";
-    case LANG_HINDI: return "hi_IN";
-    case LANG_HUNGARIAN: return "hu_HU";
-    case LANG_IBIBIO: return "nic_NG";
-    case LANG_ICELANDIC: return "is_IS";
-    case LANG_IGBO: return "ibo_NG";
-    case LANG_INDONESIAN: return "id_ID";
-    case LANG_INUKTITUT: return "iu_CA";
-    case LANG_ITALIAN:
-      switch (sub)
-       {
-       case SUBLANG_ITALIAN: return "it_IT";
-       case SUBLANG_ITALIAN_SWISS: return "it_CH";
-       }
-      return "it";
-    case LANG_JAPANESE: return "ja_JP";
-    case LANG_KANNADA: return "kn_IN";
-    case LANG_KANURI: return "kau_NG";
-    case LANG_KASHMIRI:
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "ks_PK";
-       case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
-       }
-      return "ks";
-    case LANG_KAZAK: return "kk_KZ";
-    case LANG_KONKANI:
-      /* FIXME: Adjust this when such locales appear on Unix.  */
-      return "kok_IN";
-    case LANG_KOREAN: return "ko_KR";
-    case LANG_KYRGYZ: return "ky_KG";
-    case LANG_LAO: return "lo_LA";
-    case LANG_LATIN: return "la_VA";
-    case LANG_LATVIAN: return "lv_LV";
-    case LANG_LITHUANIAN: return "lt_LT";
-    case LANG_MACEDONIAN: return "mk_MK";
-    case LANG_MALAY:
-      switch (sub)
-       {
-       case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
-       case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
-       }
-      return "ms";
-    case LANG_MALAYALAM: return "ml_IN";
-    case LANG_MALTESE: return "mt_MT";
-    case LANG_MANIPURI:
-      /* FIXME: Adjust this when such locales appear on Unix.  */
-      return "mni_IN";
-    case LANG_MARATHI: return "mr_IN";
-    case LANG_MONGOLIAN:
-      return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
-    case LANG_NEPALI:
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "ne_NP";
-       case SUBLANG_NEPALI_INDIA: return "ne_IN";
-       }
-      return "ne";
-    case LANG_NORWEGIAN:
-      switch (sub)
-       {
-       case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO";
-       case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
-       }
-      return "no";
-    case LANG_ORIYA: return "or_IN";
-    case LANG_OROMO: return "om_ET";
-    case LANG_PAPIAMENTU: return "pap_AN";
-    case LANG_PASHTO:
-      return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
-    case LANG_POLISH: return "pl_PL";
-    case LANG_PORTUGUESE:
-      switch (sub)
-       {
-       case SUBLANG_PORTUGUESE: return "pt_PT";
-       /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
-          Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
-       case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
-       }
-      return "pt";
-    case LANG_PUNJABI:
-      switch (sub)
-       {
-       case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
-       }
-      return "pa";
-    case LANG_RHAETO_ROMANCE: return "rm_CH";
-    case LANG_ROMANIAN:
-      switch (sub)
-       {
-       case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
-       }
-      return "ro";
-    case LANG_RUSSIAN:
-      return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
-    case LANG_SAAMI: /* actually Northern Sami */ return "se_NO";
-    case LANG_SANSKRIT: return "sa_IN";
-    case LANG_SINDHI:
-      switch (sub)
-       {
-       case SUBLANG_SINDHI_INDIA: return "sd_IN";
-       case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
-       }
-      return "sd";
-    case LANG_SINHALESE: return "si_LK";
-    case LANG_SLOVAK: return "sk_SK";
-    case LANG_SLOVENIAN: return "sl_SI";
-    case LANG_SOMALI: return "so_SO";
-    case LANG_SORBIAN:
-      /* FIXME: Adjust this when such locales appear on Unix.  */
-      return "wen_DE";
-    case LANG_SPANISH:
-      switch (sub)
-       {
-       case SUBLANG_SPANISH: return "es_ES";
-       case SUBLANG_SPANISH_MEXICAN: return "es_MX";
-       case SUBLANG_SPANISH_MODERN:
-         return "es_ES@modern";        /* not seen on Unix */
-       case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
-       case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
-       case SUBLANG_SPANISH_PANAMA: return "es_PA";
-       case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
-       case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
-       case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
-       case SUBLANG_SPANISH_PERU: return "es_PE";
-       case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
-       case SUBLANG_SPANISH_ECUADOR: return "es_EC";
-       case SUBLANG_SPANISH_CHILE: return "es_CL";
-       case SUBLANG_SPANISH_URUGUAY: return "es_UY";
-       case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
-       case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
-       case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
-       case SUBLANG_SPANISH_HONDURAS: return "es_HN";
-       case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
-       case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
-       }
-      return "es";
-    case LANG_SUTU: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
-    case LANG_SWAHILI: return "sw_KE";
-    case LANG_SWEDISH:
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "sv_SE";
-       case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
-       }
-      return "sv";
-    case LANG_SYRIAC: return "syr_TR"; /* An extinct language.  */
-    case LANG_TAGALOG: return "tl_PH";
-    case LANG_TAJIK: return "tg_TJ";
-    case LANG_TAMAZIGHT:
-      switch (sub)
-       {
-       /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
-       case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
-       case SUBLANG_TAMAZIGHT_LATIN: return "ber_MA@latin";
-       }
-      return "ber_MA";
-    case LANG_TAMIL:
-      return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
-    case LANG_TATAR: return "tt_RU";
-    case LANG_TELUGU: return "te_IN";
-    case LANG_THAI: return "th_TH";
-    case LANG_TIBETAN: return "bo_CN";
-    case LANG_TIGRINYA:
-      switch (sub)
-       {
-       case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
-       case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
-       }
-      return "ti";
-    case LANG_TSONGA: return "ts_ZA";
-    case LANG_TSWANA: return "tn_BW";
-    case LANG_TURKISH: return "tr_TR";
-    case LANG_TURKMEN: return "tk_TM";
-    case LANG_UKRAINIAN: return "uk_UA";
-    case LANG_URDU:
-      switch (sub)
-       {
-       case SUBLANG_URDU_PAKISTAN: return "ur_PK";
-       case SUBLANG_URDU_INDIA: return "ur_IN";
-       }
-      return "ur";
-    case LANG_UZBEK:
-      switch (sub)
-       {
-       case SUBLANG_UZBEK_LATIN: return "uz_UZ";
-       case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
-       }
-      return "uz";
-    case LANG_VENDA:
-      /* FIXME: It's not clear whether Venda has the ISO 639-2 two-letter code
-        "ve" or not.
-        http://www.loc.gov/standards/iso639-2/englangn.html has it, but
-        http://lcweb.loc.gov/standards/iso639-2/codechanges.html doesn't,  */
-      return "ven_ZA"; /* or "ve_ZA"? */
-    case LANG_VIETNAMESE: return "vi_VN";
-    case LANG_WELSH: return "cy_GB";
-    case LANG_XHOSA: return "xh_ZA";
-    case LANG_YI: return "sit_CN";
-    case LANG_YIDDISH: return "yi_IL";
-    case LANG_YORUBA: return "yo_NG";
-    case LANG_ZULU: return "zu_ZA";
-    default: return "C";
-    }
-}
-
-/* localname.c from gettext END.  */
-
-
-\f
-/* Support functions.  */
-
-static __inline__ uint32_t
-do_swap_u32 (uint32_t i)
-{
-  return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
-}
-
-#define SWAPIT(flag, data) ((flag) ? do_swap_u32(data) : (data))
-
-
-/* We assume to have `unsigned long int' value with at least 32 bits.  */
-#define HASHWORDBITS 32
-
-/* The so called `hashpjw' function by P.J. Weinberger
-   [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
-   1986, 1987 Bell Telephone Laboratories, Inc.]  */
-static __inline__ unsigned long
-hash_string( const char *str_param )
-{
-  unsigned long int hval, g;
-  const char *str = str_param;
-
-  hval = 0;
-  while (*str != '\0')
-    {
-      hval <<= 4;
-      hval += (unsigned long int) *str++;
-      g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
-      if (g != 0)
-       {
-         hval ^= g >> (HASHWORDBITS - 8);
-         hval ^= g;
-       }
-    }
-  return hval;
-}
-
-/* static char * */
-/* my_xstrdup (const char *s) */
-/* { */
-/*   size_t n = strlen (s) + 1; */
-/*   char *p = jnlib_malloc (n); */
-/*   if (!p) */
-/*     abort (); */
-/*   strcpy (p, s); */
-/*   return p; */
-/* } */
-
-
-\f
-/* Generic message catalog and gettext stuff.  */
-
-/* The magic number of the GNU message catalog format. */
-#define MAGIC        0x950412de
-#define MAGIC_SWAPPED 0xde120495
-
-/* Revision number of the currently used .mo (binary) file format.  */
-#define MO_REVISION_NUMBER 0
-
-
-/* Header for binary .mo file format.  */
-struct mo_file_header
-{
-  /* The magic number. */
-  uint32_t magic;
-  /* The revision number of the file format.  */
-  uint32_t revision;
-  /* The number of strings pairs.  */
-  uint32_t nstrings;
-  /* Offset of table with start offsets of original strings.  */
-  uint32_t orig_tab_offset;
-  /* Offset of table with start offsets of translation strings.  */
-  uint32_t trans_tab_offset;
-  /* Size of hashing table.  */
-  uint32_t hash_tab_size;
-  /* Offset of first hashing entry.  */
-  uint32_t hash_tab_offset;
-};
-
-
-struct string_desc
-{
-  /* Length of addressed string.  */
-  uint32_t length;
-  /* Offset of string in file. */
-  uint32_t offset;
-};
-
-
-struct overflow_space_s
-{
-  struct overflow_space_s *next;
-  uint32_t idx;
-  uint32_t length;
-  char d[1];
-};
-
-struct loaded_domain
-{
-  char *data;
-  char *data_native; /* Data mapped to the native version of the
-                        string.  (Allocated along with DATA). */
-  int must_swap;
-  uint32_t nstrings;
-  uint32_t *mapped;  /* 0   := Not mapped (original utf8).
-                        1   := Mapped to native encoding in overflow space.
-                        >=2 := Mapped to native encoding. The values
-                               gives the length of the mapped string.
-                               becuase the 0 is included and an empty
-                               string is not allowed we will enver get
-                               values 0 and 1.  */
-  struct overflow_space_s *overflow_space;
-  struct string_desc *orig_tab;
-  struct string_desc *trans_tab;
-  uint32_t hash_size;
-  uint32_t *hash_tab;
-};
-
-
-/* The domain we use.  We only support one domain at this point.  This
-   is why this implementation can not be shared.  Bindtextdomain and
-   dgettext will simply cheat and always use this one domain.  */
-static struct loaded_domain *the_domain;
-
-/* Global flag to switch gettext into an utf8 mode.  */
-static int want_utf8;
-
-
-\f
-/* Free the domain data.  */
-static void
-free_domain (struct loaded_domain *domain)
-{
-  struct overflow_space_s *os, *os2;
-
-  jnlib_free (domain->data);
-  jnlib_free (domain->mapped);
-  for (os = domain->overflow_space; os; os = os2)
-    {
-      os2 = os->next;
-      jnlib_free (os);
-    }
-  jnlib_free (domain);
-}
-
-
-static struct loaded_domain *
-load_domain (const char *filename)
-{
-  FILE *fp;
-  size_t size;
-  struct stat st;
-  struct mo_file_header *data = NULL;
-  struct loaded_domain *domain = NULL;
-  size_t to_read;
-  char *read_ptr;
-
-  fp = fopen (filename, "rb");
-  if (!fp)
-    return NULL;
-
-  /* Determine the file size.  */
-  if (fstat (fileno (fp), &st)
-      || (size = (size_t) st.st_size) != st.st_size
-      || size < sizeof (struct mo_file_header))
-    {
-      fclose (fp);
-      return NULL;
-    }
-
-  data = (2*size <= size)? NULL : jnlib_malloc (2*size);
-  if (!data)
-    {
-      fclose (fp);
-      return NULL;
-    }
-
-  to_read = size;
-  read_ptr = (char *) data;
-  do
-    {
-      long int nb = fread (read_ptr, 1, to_read, fp);
-      if (nb < to_read)
-       {
-         fclose (fp);
-         jnlib_free (data);
-         return NULL;
-       }
-      read_ptr += nb;
-      to_read -= nb;
-    }
-  while (to_read > 0);
-  fclose (fp);
-
-  /* Using the magic number we can test whether it really is a message
-     catalog file.  */
-  if (data->magic != MAGIC && data->magic != MAGIC_SWAPPED)
-    {
-      /* The magic number is wrong: not a message catalog file.  */
-      jnlib_free (data);
-      return NULL;
-    }
-
-  domain = jnlib_calloc (1, sizeof *domain);
-  if (!domain)
-    {
-      jnlib_free (data);
-      return NULL;
-    }
-  domain->data = (char *) data;
-  domain->data_native = (char *) data + size;
-  domain->must_swap = data->magic != MAGIC;
-
-  /* Fill in the information about the available tables.  */
-  switch (SWAPIT (domain->must_swap, data->revision))
-    {
-    case MO_REVISION_NUMBER:
-      domain->nstrings = SWAPIT (domain->must_swap, data->nstrings);
-      domain->orig_tab = (struct string_desc *)
-       ((char *) data + SWAPIT (domain->must_swap, data->orig_tab_offset));
-      domain->trans_tab = (struct string_desc *)
-       ((char *) data + SWAPIT (domain->must_swap, data->trans_tab_offset));
-      domain->hash_size = SWAPIT (domain->must_swap, data->hash_tab_size);
-      domain->hash_tab = (uint32_t *)
-       ((char *) data + SWAPIT (domain->must_swap, data->hash_tab_offset));
-      break;
-
-    default:
-      /* This is an invalid revision.  */
-      jnlib_free (data);
-      jnlib_free (domain);
-      return NULL;
-    }
-
-  /* Allocate an array to keep track of code page mappings.  */
-  domain->mapped = jnlib_calloc (domain->nstrings, sizeof *domain->mapped);
-  if (!domain->mapped)
-    {
-      jnlib_free (data);
-      jnlib_free (domain);
-      return NULL;
-    }
-
-  return domain;
-}
-
-
-/* Return a malloced wide char string from an UTF-8 encoded input
-   string STRING.  Caller must free this value. On failure returns
-   NULL.  The result of calling this function with STRING set to NULL
-   is not defined. */
-static wchar_t *
-utf8_to_wchar (const char *string, size_t length, size_t *retlen)
-{
-  int n;
-  wchar_t *result;
-  size_t nbytes;
-
-  n = MultiByteToWideChar (CP_UTF8, 0, string, length, NULL, 0);
-  if (n < 0 || (n+1) <= 0)
-    return NULL;
-
-  nbytes = (size_t)(n+1) * sizeof(*result);
-  if (nbytes / sizeof(*result) != (n+1))
-    {
-      errno = ENOMEM;
-      return NULL;
-    }
-  result = jnlib_malloc (nbytes);
-  if (!result)
-    return NULL;
-
-  n = MultiByteToWideChar (CP_UTF8, 0, string, length, result, n);
-  if (n < 0)
-    {
-      jnlib_free (result);
-      return NULL;
-    }
-  *retlen = n;
-  return result;
-}
-
-
-/* Return a malloced string encoded in UTF-8 from the wide char input
-   string STRING.  Caller must free this value. On failure returns
-   NULL.  The result of calling this function with STRING set to NULL
-   is not defined. */
-static char *
-wchar_to_native (const wchar_t *string, size_t length, size_t *retlen)
-{
-  int n;
-  char *result;
-
-  n = WideCharToMultiByte (CP_ACP, 0, string, length, NULL, 0, NULL, NULL);
-  if (n < 0 || (n+1) <= 0)
-    return NULL;
-
-  result = jnlib_malloc (n+1);
-  if (!result)
-    return NULL;
-
-  n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL);
-  if (n < 0)
-    {
-      jnlib_free (result);
-      return NULL;
-    }
-  *retlen = n;
-  return result;
-}
-
-
-/* Convert UTF8 to the native codepage.  Caller must free the return value. */
-static char *
-utf8_to_native (const char *string, size_t length, size_t *retlen)
-{
-  wchar_t *wstring;
-  char *result;
-  size_t newlen;
-
-  wstring = utf8_to_wchar (string, length, &newlen);
-  if (wstring)
-    {
-      result = wchar_to_native (wstring, newlen, &newlen);
-      jnlib_free (wstring);
-    }
-  else
-    result = NULL;
-  *retlen = result? newlen : 0;
-  return result;
-}
-
-
-
-\f
-/* Specify that the DOMAINNAME message catalog will be found
-   in DIRNAME rather than in the system locale data base.  */
-char *
-bindtextdomain (const char *domainname, const char *dirname)
-{
-  struct loaded_domain *domain = NULL;
-  const char *catval_full;
-  char *catval;
-  char *fname;
-
-  /* DOMAINNAME is ignored.  We only support one domain.  */
-
-  /* DIRNAME is "$INSTALLDIR\share\locale".  */
-
-  /* First find out the category value.  */
-  catval = NULL;
-  catval_full = my_nl_locale_name ("LC_MESSAGES");
-
-  /* Normally, we would have to loop over all returned locales, and
-     search for the right file.  See gettext intl/dcigettext.c for all
-     the gory details.  Here, we only support the basic category, and
-     ignore everything else.  */
-  if (catval_full)
-    {
-      char *p;
-
-      catval = jnlib_malloc (strlen (catval_full) + 1);
-      if (catval)
-       {
-         strcpy (catval, catval_full);
-         p = strchr (catval, '_');
-         if (p)
-           *p = '\0';
-       }
-    }
-  if (!catval)
-    return NULL;
-
-  /* Now build the filename string.  The complete filename is this:
-     DIRNAME + \ + CATVAL + \LC_MESSAGES\ + DOMAINNAME + .mo  */
-  {
-    int len = strlen (dirname) + 1 + strlen (catval) + 13
-      + strlen (domainname) + 3 + 1;
-    char *p;
-
-    fname = jnlib_malloc (len);
-    if (!fname)
-      {
-       jnlib_free (catval);
-       return NULL;
-      }
-
-    p = fname;
-    strcpy (p, dirname);
-    p += strlen (dirname);
-    *(p++) = '\\';
-    strcpy (p, catval);
-    p += strlen (catval);
-    strcpy (p, "\\LC_MESSAGES\\");
-    p += 13;
-    strcpy (p, domainname);
-    p += strlen (domainname);
-    strcpy (p, ".mo");
-  }
-
-  domain = load_domain (fname);
-  jnlib_free (catval);
-  jnlib_free (fname);
-
-  /* We should not be invoked twice, but this is how you would do
-     it if it happened.  */
-  if (the_domain)
-    free_domain (the_domain);
-  the_domain = domain;
-
-  /* For historic reasons we are not allowed to return a const char*. */
-  return (char*)dirname;
-}
-
-
-
-\f
-static const char *
-get_plural (const char *data, size_t datalen, unsigned long nplural)
-{
-  const char *p;
-  int idx;
-
-  /* We only support the Germanic rule.  */
-  idx = (nplural == 1? 0 : 1);
-
-  for (; idx; idx--)
-    {
-      p = strchr (data, 0) + 1;
-      if (p >= data+datalen)
-        return "ERROR in GETTEXT (bad plural entry)";
-      datalen -= (p-data);
-      data = p;
-    }
-  return data;
-}
-
-
-static const char*
-get_string (struct loaded_domain *domain, uint32_t idx,
-            int use_plural, unsigned long nplural)
-{
-  struct overflow_space_s *os;
-  const char *trans;  /* Pointer to the translated entry.  */
-  size_t translen;    /* Length of that entry.  */
-
-  if (want_utf8)
-    {
-      trans = (domain->data
-               + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-      translen = SWAPIT(domain->must_swap, domain->trans_tab[idx].length);
-    }
-  else if (!domain->mapped[idx])
-    {
-      /* Not yet mapped.  Map from utf-8 to native encoding now.  */
-      const char *p_utf8;
-      size_t plen_utf8, buflen;
-      char *buf;
-
-      p_utf8 = (domain->data
-                + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-      plen_utf8 = SWAPIT(domain->must_swap, domain->trans_tab[idx].length);
-
-      buf = utf8_to_native (p_utf8, plen_utf8, &buflen);
-      if (!buf)
-        {
-          trans = "ERROR in GETTEXT MALLOC";
-          translen = 0;
-        }
-      else if (buflen <= plen_utf8 && buflen > 1)
-        {
-          /* Copy into the DATA_NATIVE area. */
-          char *p_tmp;
-
-          p_tmp = (domain->data_native
-                   + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-          memcpy (p_tmp, buf, buflen);
-          domain->mapped[idx] = buflen;
-          trans = p_tmp;
-          translen = buflen;
-        }
-      else
-        {
-          /* There is not enough space for the translation (or for
-             whatever reason an empry string is used): Store it in the
-             overflow_space and mark that in the mapped array.
-             Because UTF-8 strings are in general longer than the
-             Windows 2 byte encodings, we expect that this won't
-             happen too often (if at all) and thus we use a linked
-             list to manage this space. */
-          os = jnlib_malloc (sizeof *os + buflen);
-          if (os)
-            {
-              os->idx = idx;
-              memcpy (os->d, buf, buflen);
-              os->length = buflen;
-              os->next = domain->overflow_space;
-              domain->overflow_space = os;
-              domain->mapped[idx] = 1;
-              trans = os->d;
-              translen = os->length;
-            }
-          else
-            {
-              trans = "ERROR in GETTEXT MALLOC";
-              translen = 0;
-            }
-        }
-      jnlib_free (buf);
-    }
-  else if (domain->mapped[idx] == 1)
-    {
-      /* The translated string is in the overflow_space. */
-      for (os=domain->overflow_space; os; os = os->next)
-        if (os->idx == idx)
-          break;
-      if (os)
-        {
-          trans = os->d;
-          translen = os->length;
-        }
-      else
-        {
-          trans = "ERROR in GETTEXT (overflow space)\n";
-          translen = 0;
-        }
-    }
-  else
-    {
-      trans = (domain->data_native
-               + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-      translen = domain->mapped[idx];
-    }
-
-  if (use_plural && translen)
-    return get_plural (trans, translen, nplural);
-  else
-    return trans;
-}
-
-
-static const char *
-do_gettext (const char *msgid, const char *msgid2, unsigned long nplural)
-{
-  struct loaded_domain *domain;
-  uint32_t top, bottom, nstr;
-
-  if (!(domain = the_domain))
-    goto not_found;
-
-  /* First try to use the hash table.  */
-  if (domain->hash_size > 2 && domain->hash_tab)
-    {
-      /* Use the hashing table.  */
-      uint32_t len = strlen (msgid);
-      uint32_t hash_val = hash_string (msgid);
-      uint32_t idx = hash_val % domain->hash_size;
-      uint32_t incr = 1 + (hash_val % (domain->hash_size - 2));
-
-      while ( (nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx])) )
-        {
-          nstr--;
-          if (nstr < domain->nstrings
-              && SWAPIT(domain->must_swap,
-                        domain->orig_tab[nstr].length) >= len
-              && !strcmp (msgid, (domain->data
-                                  + SWAPIT(domain->must_swap,
-                                           domain->orig_tab[nstr].offset))))
-            {
-              return get_string (domain, nstr, !!msgid2, nplural);
-            }
-
-          if (idx >= domain->hash_size - incr)
-            idx -= domain->hash_size - incr;
-          else
-            idx += incr;
-       }
-    }
-
-  /* Now we try the default method: binary search in the sorted array
-     of messages.  */
-  bottom = 0;
-  top = domain->nstrings;
-  while (bottom < top)
-    {
-      int cmp_val;
-
-      nstr = (bottom + top) / 2;
-      cmp_val = strcmp (msgid, (domain->data
-                                + SWAPIT(domain->must_swap,
-                                         domain->orig_tab[nstr].offset)));
-      if (cmp_val < 0)
-        top = nstr;
-      else if (cmp_val > 0)
-        bottom = nstr + 1;
-      else
-        return get_string (domain, nstr, !!msgid2, nplural);
-    }
-
- not_found:
-  /* We use the standard Germanic rule if plural has been requested.  */
-  return msgid2? (nplural == 1? msgid : msgid2) : msgid;
-}
-
-
-char *
-textdomain (const char *domainname)
-{
-  /* For now, support only one domain.  */
-  return (char*)domainname;
-}
-
-
-const char *
-gettext (const char *msgid)
-{
-  return do_gettext (msgid, NULL, 0);
-}
-
-char *
-dgettext (const char *domainname, const char *msgid)
-{
-  (void)domainname;
-
-  /* For now, support only one domain.  */
-  return (char*)do_gettext (msgid, NULL, 0);
-}
-
-const char *
-ngettext (const char *msgid1, const char *msgid2, unsigned long int n)
-{
-  /* We use the simple Germanic plural rule.  */
-  return do_gettext (msgid1, msgid2, n);
-}
-
-
-/* Return the locale name as used by gettext.  The return value will
-   never be NULL. */
-const char *
-gettext_localename (void)
-{
-  const char *s;
-
-  s = my_nl_locale_name ("LC_MESSAGES");
-  return s? s:"";
-}
-
-void
-gettext_select_utf8 (int value)
-{
-  want_utf8 = value;
-}
-
-
-#ifdef TEST
-int
-main (int argc, char **argv)
-{
-  const char atext1[] =
-    "Warning: You have entered an insecure passphrase.%%0A"
-    "A passphrase should be at least %u character long.";
-  const char atext2[] =
-    "Warning: You have entered an insecure passphrase.%%0A"
-    "A passphrase should be at least %u characters long.";
-
-  if (argc)
-    {
-      argc--;
-      argv++;
-    }
-
-  bindtextdomain ("gnupg2", "c:/programme/gnu/gnupg/share/locale");
-
-  printf ("locale is `%s'\n", gettext_localename ());
-  fputs ("text with N=1:\n", stdout);
-  fputs (ngettext (atext1, atext2, 1), stdout);
-  fputs ("\n\ntext with N=2:\n", stdout);
-  fputs (ngettext (atext1, atext2, 2), stdout);
-  fputs ("\nready\n", stdout);
-
-  return 0;
-}
-/*
- * Local Variables:
- *  compile-command: "i586-mingw32msvc-gcc -DTEST -Wall -g w32-gettext.c"
- * End:
- */
-#endif /*TEST*/
diff --git a/jnlib/w32help.h b/jnlib/w32help.h
deleted file mode 100644 (file)
index c7aa5cb..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* w32help.h - W32 speicif functions
- * Copyright (C) 2007  Free Software Foundation, Inc.
- *
- * This file is part of JNLIB.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * JNLIB 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LIBJNLIB_W32HELP_H
-#define LIBJNLIB_W32HELP_H
-#ifdef HAVE_W32_SYSTEM
-
-/*-- w32-reg.c --*/
-char *read_w32_registry_string (const char *root,
-                               const char *dir, const char *name );
-
-#ifdef USE_SIMPLE_GETTEXT
-char *bindtextdomain (const char *domainname, const char *dirname);
-const char *gettext (const char *msgid );
-const char *ngettext (const char *msgid1, const char *msgid2,
-                      unsigned long int n);
-const char *gettext_localename (void);
-void gettext_select_utf8 (int value);
-#endif /*USE_SIMPLE_GETTEXT*/
-
-
-#endif /*HAVE_W32_SYSTEM*/
-#endif /*LIBJNLIB_MISCHELP_H*/
diff --git a/jnlib/xmalloc.h b/jnlib/xmalloc.h
deleted file mode 100644 (file)
index 8c9c529..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* xmalloc.h
- *     Copyright (C) 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
- *
- * This file is part of JNLIB.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * JNLIB 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LIBJNLIB_XMALLOC_H
-#define LIBJNLIB_XMALLOC_H
-
-void *xmalloc( size_t n );
-void *xrealloc( void *a, size_t n );
-void *xcalloc( size_t n, size_t m );
-char *xstrdup( const char *string );
-char *xstrcat2( const char *a, const char *b );
-
-
-#endif /*LIBJNLIB_XMALLOC_H*/
index ed3aa41..7641f53 100644 (file)
@@ -1,19 +1,62 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-04-28  Werner Koch  <wk@g10code.com>
 
-       * keybox-openpgp.c (parse_key): Remove set but unused vars
-       EXPIREDATE and NDAYS.
+       * keybox-openpgp.c: Include ../common/openpgpdefs.h.
+       (enum packet_types): Remove.
+       (_keybox_parse_openpgp): Update NPARSED also on errors.
+       (parse_key): Take care of ecc algorithms.
+       * kbxutil.c (import_openpgp): Do not print an error for non-RSA v3
+       packets.
 
 2010-07-23  Werner Koch  <wk@g10code.com>
 
        * keybox-blob.c (_keybox_create_x509_blob): Fix reallocation bug.
 
+2010-04-20  Marcus Brinkmann  <marcus@g10code.de>
+
+       * keybox-update.c [!HAVE_DOSISH_SYSTEM]: Include
+       ../common/sysutils.h even then to silence gcc warning about
+       missing declaration of gnupg_remove.
+
+2010-04-15  Werner Koch  <wk@g10code.com>
+
+       * keybox-blob.c: Include gettime.h
+       (make_timestamp): Remove.
+
+2010-03-23  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (extra_libs): New.
+       (kbxutil_LDADD): Use it.
+
+       * keybox-update.c: [HAVE_DOSISH_SYSTEM]: Include sysutils.h.
+       (keybox_compress): Replace rewind by fseek+clearerr.
+       (rename_tmp_file, keybox_compress): s/remove/gnupg_remove/.
+
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (kbxutil_LDADD, $(PROGRAMS)): Remove libjnlib.a.
+
+       * keybox-search.c, keybox-init.c, keybox-defs.h, kbxutil.c:
+       Replace "jnlib" include file part by "common".
+
+2010-03-08  Werner Koch  <wk@g10code.com>
+
+       Use macros for iobuf_ioctl commands.
+
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * keybox-search-desc.h (keydb_search_desc): Use u32 type for
+       KID. Extend the skip function ptr.
+       (gpg_pkt_user_id_t): New.
+       * keybox-search.c (has_short_kid, has_long_kid): Change to use u32
+       args for KID.
+
 2008-12-09  Werner Koch  <wk@g10code.com>
 
        * kbxutil.c (main): Call i18n_init before init_common_subsystems.
 
 
  Copyright 2001, 2002, 2003, 2004, 2005, 2006,
-          2007, 2008 Free Software Foundation, Inc.
+          2007, 2008, 2011 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
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 65c0af2..d7edb25 100644 (file)
 
 ## Process this file with automake to produce Makefile.in
 
+EXTRA_DIST = mkerrors
+
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common \
+             -I$(top_srcdir)/intl
 
-EXTRA_DIST = mkerrors ChangeLog-2011
-AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl \
-              $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS)
 include $(top_srcdir)/am/cmacros.am
 
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS)
+
 noinst_LIBRARIES = libkeybox.a
 bin_PROGRAMS = kbxutil
 
+if HAVE_W32CE_SYSTEM
+extra_libs =  $(LIBASSUAN_LIBS)
+else
+extra_libs =
+endif
+
 common_sources = \
        keybox.h keybox-defs.h keybox-search-desc.h \
        keybox-util.c \
@@ -45,8 +54,8 @@ libkeybox_a_SOURCES = $(common_sources)
 # requires it - although we don't actually need it.  It is easier
 # to do it this way.
 kbxutil_SOURCES = kbxutil.c $(common_sources)
-kbxutil_LDADD   = ../common/libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \
-                  $(KSBA_LIBS) $(LIBGCRYPT_LIBS) \
+kbxutil_LDADD   = ../common/libcommon.a ../gl/libgnu.a \
+                  $(KSBA_LIBS) $(LIBGCRYPT_LIBS) $(extra_libs) \
                   $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS)
 
-$(PROGRAMS) : ../common/libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a
+$(PROGRAMS) : ../common/libcommon.a ../gl/libgnu.a
index f0921b7..34cbc53 100644 (file)
@@ -1,5 +1,5 @@
 /* kbxutil.c - The Keybox utility
- * Copyright (C) 2000, 2001, 2004, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2000, 2001, 2004, 2007, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <assert.h>
 
 #define JNLIB_NEED_LOG_LOGV
-#include "../jnlib/logging.h"
-#include "../jnlib/argparse.h"
-#include "../jnlib/stringhelp.h"
-#include "../jnlib/utf8conv.h"
+#include <gpg-error.h>
+#include "../common/logging.h"
+#include "../common/argparse.h"
+#include "../common/stringhelp.h"
+#include "../common/utf8conv.h"
 #include "i18n.h"
-#include "init.h"
 #include "keybox-defs.h"
-
+#include "../common/init.h"
 #include <gcrypt.h>
 
+
 enum cmd_and_opt_values {
   aNull = 0,
   oArmor         = 'a',
@@ -46,7 +47,7 @@ enum cmd_and_opt_values {
   oOutput        = 'o',
   oQuiet         = 'q',
   oVerbose       = 'v',
-  
+
   aNoSuchCmd    = 500,   /* force other values not to be a letter */
   aFindByFpr,
   aFindByKid,
@@ -73,13 +74,13 @@ static ARGPARSE_OPTS opts[] = {
 /*   { aFindByFpr,  "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, */
 /*   { aFindByKid,  "find-by-kid", 0, "|KID| find key using it's keyid" }, */
 /*   { aFindByUid,  "find-by-uid", 0, "|NAME| find key by user name" }, */
-  { aStats,      "stats",       0, "show key statistics" }, 
+  { aStats,      "stats",       0, "show key statistics" },
   { aImportOpenPGP, "import-openpgp", 0, "import OpenPGP keyblocks"},
   { aFindDups,    "find-dups",   0, "find duplicates" },
   { aCut,         "cut",         0, "export records" },
-  
+
   { 301, NULL, 0, N_("@\nOptions:\n ") },
-  
+
   { oFrom, "from", 4, "|N|first record to export" },
   { oTo,   "to",   4, "|N|last record to export" },
 /*   { oArmor, "armor",     0, N_("create ascii armored output")}, */
@@ -88,7 +89,7 @@ static ARGPARSE_OPTS opts[] = {
   { oVerbose, "verbose",   0, N_("verbose") },
   { oQuiet,    "quiet",   0, N_("be somewhat more quiet") },
   { oDryRun, "dry-run",   0, N_("do not make any changes") },
-  
+
   { oDebug, "debug"     ,4|16, N_("set debugging flags")},
   { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
 
@@ -106,7 +107,7 @@ my_strusage( int level )
 {
     const char *p;
     switch( level ) {
-      case 11: p = "kbxutil (GnuPG)";
+      case 11: p = "kbxutil (@GNUPG@)";
        break;
       case 13: p = VERSION; break;
       case 17: p = PRINTABLE_OS_NAME; break;
@@ -144,7 +145,7 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
     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;  
+    default:            level = JNLIB_LOG_ERROR; break;
     }
   log_logv (level, fmt, arg_ptr);
 }
@@ -236,7 +237,7 @@ read_file (const char *fname, size_t *r_length)
   FILE *fp;
   char *buf;
   size_t buflen;
-  
+
   if (!strcmp (fname, "-"))
     {
       size_t nread, bufsize = 0;
@@ -245,7 +246,7 @@ read_file (const char *fname, size_t *r_length)
       buf = NULL;
       buflen = 0;
 #define NCHUNK 8192
-      do 
+      do
         {
           bufsize += NCHUNK;
           if (!buf)
@@ -258,7 +259,7 @@ read_file (const char *fname, size_t *r_length)
           nread = fread (buf+buflen, 1, NCHUNK, fp);
           if (nread < NCHUNK && ferror (fp))
             {
-              log_error ("error reading `[stdin]': %s\n", strerror (errno));
+              log_error ("error reading '[stdin]': %s\n", strerror (errno));
               xfree (buf);
               return NULL;
             }
@@ -275,24 +276,24 @@ read_file (const char *fname, size_t *r_length)
       fp = fopen (fname, "rb");
       if (!fp)
         {
-          log_error ("can't open `%s': %s\n", fname, strerror (errno));
+          log_error ("can't open '%s': %s\n", fname, strerror (errno));
           return NULL;
         }
-  
+
       if (fstat (fileno(fp), &st))
         {
-          log_error ("can't stat `%s': %s\n", fname, strerror (errno));
+          log_error ("can't stat '%s': %s\n", fname, strerror (errno));
           fclose (fp);
           return NULL;
         }
-      
+
       buflen = st.st_size;
       buf = xtrymalloc (buflen+1);
       if (!buf)
         log_fatal ("can't allocate buffer: %s\n", strerror (errno));
       if (fread (buf, buflen, 1, fp) != 1)
         {
-          log_error ("error reading `%s': %s\n", fname, strerror (errno));
+          log_error ("error reading '%s': %s\n", fname, strerror (errno));
           fclose (fp);
           xfree (buf);
           return NULL;
@@ -332,7 +333,8 @@ dump_fpr (const unsigned char *buffer, size_t len)
 static void
 dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image)
 {
-  printf ("pub %02X%02X%02X%02X",
+  printf ("pub %2d %02X%02X%02X%02X",
+          info->primary.algo,
           info->primary.keyid[4], info->primary.keyid[5],
           info->primary.keyid[6], info->primary.keyid[7] );
   dump_fpr (info->primary.fpr, info->primary.fprlen);
@@ -342,9 +344,10 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image)
       struct _keybox_openpgp_key_info *k;
 
       k = &info->subkeys;
-      do 
+      do
         {
-          printf ("sub %02X%02X%02X%02X",
+          printf ("sub %2d %02X%02X%02X%02X",
+                  k->algo,
                   k->keyid[4], k->keyid[5],
                   k->keyid[6], k->keyid[7] );
           dump_fpr (k->fpr, k->fprlen);
@@ -358,7 +361,7 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image)
       struct _keybox_openpgp_uid_info *u;
 
       u = &info->uids;
-      do 
+      do
         {
           printf ("uid\t\t%.*s\n", (int)u->len, image + u->off);
           u = u->next;
@@ -369,13 +372,14 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image)
 
 
 static void
-import_openpgp (const char *filename)
+import_openpgp (const char *filename, int dryrun)
 {
   gpg_error_t err;
   char *buffer;
   size_t buflen, nparsed;
   unsigned char *p;
   struct _keybox_openpgp_info info;
+  KEYBOXBLOB blob;
 
   buffer = read_file (filename, &buflen);
   if (!buffer)
@@ -389,12 +393,46 @@ import_openpgp (const char *filename)
         {
           if (gpg_err_code (err) == GPG_ERR_NO_DATA)
             break;
-          log_info ("%s: failed to parse OpenPGP keyblock: %s\n",
-                    filename, gpg_strerror (err));
+          if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
+            {
+              /* This is likely a v3 key packet with a non-RSA
+                 algorithm.  These are keys from very early versions
+                 of GnuPG (pre-OpenPGP).  */
+            }
+          else
+            {
+              fflush (stdout);
+              log_info ("%s: failed to parse OpenPGP keyblock: %s\n",
+                        filename, gpg_strerror (err));
+            }
         }
       else
         {
-          dump_openpgp_key (&info, p);
+          if (dryrun)
+            dump_openpgp_key (&info, p);
+          else
+            {
+              err = _keybox_create_openpgp_blob (&blob, &info, p, nparsed,
+                                                 NULL, 0);
+              if (err)
+                {
+                  fflush (stdout);
+                  log_error ("%s: failed to create OpenPGP keyblock: %s\n",
+                             filename, gpg_strerror (err));
+                }
+              else
+                {
+                  err = _keybox_write_blob (blob, stdout);
+                  _keybox_release_blob (blob);
+                  if (err)
+                    {
+                      fflush (stdout);
+                      log_error ("%s: failed to write OpenPGP keyblock: %s\n",
+                                 filename, gpg_strerror (err));
+                    }
+                }
+            }
+
           _keybox_destroy_openpgp_info (&info);
         }
       p += nparsed;
@@ -412,14 +450,15 @@ main( int argc, char **argv )
   ARGPARSE_ARGS pargs;
   enum cmd_and_opt_values cmd = 0;
   unsigned long from = 0, to = ULONG_MAX;
-  
+  int dry_run = 0;
+
   set_strusage( my_strusage );
   gcry_control (GCRYCTL_DISABLE_SECMEM);
-  log_set_prefix ("kbxutil", 1); 
+  log_set_prefix ("kbxutil", 1);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   /* Check that the libraries are suitable.  Do it here because
      the option parsing may need services of the library.  */
@@ -433,7 +472,7 @@ main( int argc, char **argv )
 
   /*create_dotlock(NULL); register locking cleanup */
 
-  /* We need to use the gcry malloc function because jnlib does use them */
+  /* We need to use the gcry malloc function because jnlib uses them.  */
   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
 
@@ -469,71 +508,73 @@ main( int argc, char **argv )
         case oFrom: from = pargs.r.ret_ulong; break;
         case oTo: to = pargs.r.ret_ulong; break;
 
+        case oDryRun: dry_run = 1; break;
+
         default:
           pargs.err = 2;
           break;
        }
     }
-  
+
   if (to < from)
     log_error ("record number of \"--to\" is lower than \"--from\" one\n");
 
 
   if (log_get_errorcount(0) )
     myexit(2);
-  
+
   if (!cmd)
     { /* Default is to list a KBX file */
-      if (!argc) 
+      if (!argc)
         _keybox_dump_file (NULL, 0, stdout);
       else
         {
-          for (; argc; argc--, argv++) 
+          for (; argc; argc--, argv++)
             _keybox_dump_file (*argv, 0, stdout);
         }
     }
   else if (cmd == aStats )
     {
-      if (!argc) 
+      if (!argc)
         _keybox_dump_file (NULL, 1, stdout);
       else
         {
-          for (; argc; argc--, argv++) 
+          for (; argc; argc--, argv++)
             _keybox_dump_file (*argv, 1, stdout);
         }
     }
   else if (cmd == aFindDups )
     {
-      if (!argc) 
+      if (!argc)
         _keybox_dump_find_dups (NULL, 0, stdout);
       else
         {
-          for (; argc; argc--, argv++) 
+          for (; argc; argc--, argv++)
             _keybox_dump_find_dups (*argv, 0, stdout);
         }
     }
   else if (cmd == aCut )
     {
-      if (!argc) 
+      if (!argc)
         _keybox_dump_cut_records (NULL, from, to, stdout);
       else
         {
-          for (; argc; argc--, argv++) 
+          for (; argc; argc--, argv++)
             _keybox_dump_cut_records (*argv, from, to, stdout);
         }
     }
   else if (cmd == aImportOpenPGP)
     {
       if (!argc)
-        import_openpgp ("-");
+        import_openpgp ("-", dry_run);
       else
         {
-          for (; argc; argc--, argv++) 
-            import_openpgp (*argv);
+          for (; argc; argc--, argv++)
+            import_openpgp (*argv, dry_run);
         }
     }
 #if 0
-  else if ( cmd == aFindByFpr ) 
+  else if ( cmd == aFindByFpr )
     {
       char *fpr;
       if ( argc != 2 )
@@ -541,17 +582,17 @@ main( int argc, char **argv )
       fpr = format_fingerprint ( argv[1] );
       if ( !fpr )
         log_error ("invalid formatted fingerprint\n");
-      else 
+      else
         {
           kbxfile_search_by_fpr ( argv[0], fpr );
           gcry_free ( fpr );
         }
     }
-  else if ( cmd == aFindByKid ) 
+  else if ( cmd == aFindByKid )
     {
       u32 kid[2];
       int mode;
-      
+
       if ( argc != 2 )
         wrong_args ("kbxfile short-or-long-keyid");
       mode = format_keyid ( argv[1], kid );
@@ -562,7 +603,7 @@ main( int argc, char **argv )
           kbxfile_search_by_kid ( argv[0], kid, mode );
        }
     }
-  else if ( cmd == aFindByUid ) 
+  else if ( cmd == aFindByUid )
     {
       if ( argc != 2 )
         wrong_args ("kbxfile userID");
@@ -571,7 +612,7 @@ main( int argc, char **argv )
 #endif
   else
       log_error ("unsupported action\n");
-  
+
   myexit(0);
   return 8; /*NEVER REACHED*/
 }
@@ -590,5 +631,3 @@ myexit( int rc )
                        keybox_errors_seen? 1 : 0;
     exit(rc );
 }
-
-
index 01d4ba2..ef72148 100644 (file)
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+/*
+* The keybox data format
+
+   The KeyBox uses an augmented OpenPGP/X.509 key format.  This makes
+   random access to a keyblock/certificate easier and also gives the
+   opportunity to store additional information (e.g. the fingerprint)
+   along with the key.  All integers are stored in network byte order,
+   offsets are counted from the beginning of the Blob.
+
+** Overview of blob types
+
+   | Byte 4 | Blob type    |
+   |--------+--------------|
+   |      0 | Empty blob   |
+   |      1 | First blob   |
+   |      2 | OpenPGP blob |
+   |      3 | X.509 blob   |
+
+** The First blob
+
+   The first blob of a plain KBX file has a special format:
+
+   - u32  Length of this blob
+   - byte Blob type (1)
+   - byte Version number (1)
+   - u16  Header flags
+          bit 0 - RFU
+          bit 1 - Is being or has been used for OpenPGP blobs
+   - b4   Magic 'KBXf'
+   - u32  RFU
+   - u32  file_created_at
+   - u32  last_maintenance_run
+   - u32  RFU
+   - u32  RFU
+
+** The OpenPGP and X.509 blobs
+
+   The OpenPGP and X.509 blobs are very similiar, things which are
+   X.509 specific are noted like [X.509: xxx]
+
+   - u32  Length of this blob (including these 4 bytes)
+   - byte Blob type
+           2 = OpenPGP
+           3 = X509
+   - byte Version number of this blob type
+           1 = The only defined value
+   - u16  Blob flags
+          bit 0 = contains secret key material (not used)
+          bit 1 = ephemeral blob (e.g. used while quering external resources)
+   - u32  Offset to the OpenPGP keyblock or the X.509 DER encoded
+          certificate
+   - u32  The length of the keyblock or certificate
+   - u16  [NKEYS] Number of keys (at least 1!) [X509: always 1]
+   - u16  Size of the key information structure (at least 28).
+   - NKEYS times:
+      - b20  The fingerprint of the key.
+             Fingerprints are always 20 bytes, MD5 left padded with zeroes.
+      - u32  Offset to the n-th key's keyID (a keyID is always 8 byte)
+             or 0 if not known which is the case only for X.509.
+      - u16  Key flags
+             bit 0 = qualified signature (not yet implemented}
+      - u16  RFU
+      - bN   Optional filler up to the specified length of this
+             structure.
+   - u16  Size of the serial number (may be zero)
+      -  bN  The serial number. N as giiven above.
+   - u16  Number of user IDs
+   - u16  [NUIDS] Size of user ID information structure
+   - NUIDS times:
+
+      For X509, the first user ID is the Issuer, the second the
+      Subject and the others are subjectAltNames.  For OpenPGP we only
+      store the information from UserID packets here.
+
+      - u32  Blob offset to the n-th user ID
+      - u32  Length of this user ID.
+      - u16  User ID flags.
+             (not yet used)
+      - byte Validity
+      - byte RFU
+
+   - u16  [NSIGS] Number of signatures
+   - u16  Size of signature information (4)
+   - NSIGS times:
+      - u32  Expiration time of signature with some special values:
+             - 0x00000000 = not checked
+             - 0x00000001 = missing key
+             - 0x00000002 = bad signature
+             - 0x10000000 = valid and expires at some date in 1978.
+             - 0xffffffff = valid and does not expire
+   - u8        Assigned ownertrust [X509: not used]
+   - u8        All_Validity
+        OpenPGP: See ../g10/trustdb/TRUST_* [not yet used]
+        X509: Bit 4 set := key has been revoked.
+                           Note that this value matches TRUST_FLAG_REVOKED
+   - u16  RFU
+   - u32  Recheck_after
+   - u32  Latest timestamp in the keyblock (useful for KS syncronsiation?)
+   - u32  Blob created at
+   - u32  [NRES] Size of reserved space (not including this field)
+   - bN   Reserved space of size NRES for future use.
+   - bN   Arbitrary space for example used to store data which is not
+          part of the keyblock or certificate.  For example the v3 key
+          IDs go here.
+   - bN   Space for the keyblock or certificate.
+   - bN   RFU.  This is the remaining space after keyblock and before
+          the checksum.  Is is not covered by the checksum.
+   - b20  SHA-1 checksum (useful for KS syncronisation?)
+          Note, that KBX versions before GnuPG 2.1 used an MD5
+          checksum.  However it was only created but never checked.
+          Thus we do not expect problems if we switch to SHA-1.  If
+          the checksum fails and the first 4 bytes are zero, we can
+          try again with MD5.  SHA-1 has the advantage that it is
+          faster on CPUs with dedicated SHA-1 support.
 
-/* The keybox data formats
-
-The KeyBox uses an augmented OpenPGP/X.509 key format.  This makes
-random access to a keyblock/certificate easier and also gives the
-opportunity to store additional information (e.g. the fingerprint)
-along with the key.  All integers are stored in network byte order,
-offsets are counted from the beginning of the Blob.
-
-The first record of a plain KBX file has a special format:
-
- u32  length of the first record
- byte Blob type (1)
- byte version number (1)
- byte reserved
- byte reserved
- u32  magic 'KBXf'
- u32  reserved
- u32  file_created_at
- u32  last_maintenance_run
- u32  reserved
- u32  reserved
-
-The OpenPGP and X.509 blob are very similiar, things which are
-X.509 specific are noted like [X.509: xxx]
-
- u32  length of this blob (including these 4 bytes)
- byte Blob type (2) [X509: 3]
- byte version number of this blob type (1)
- u16  Blob flags
-       bit 0 = contains secret key material
-        bit 1 = ephemeral blob (e.g. used while quering external resources)
-
- u32  offset to the OpenPGP keyblock or X509 DER encoded certificate
- u32  and its length
- u16  number of keys (at least 1!) [X509: always 1]
- u16  size of additional key information
- n times:
-   b20 The keys fingerprint
-       (fingerprints are always 20 bytes, MD5 left padded with zeroes)
-   u32 offset to the n-th key's keyID (a keyID is always 8 byte)
-        or 0 if not known which is the case only for X509.
-   u16 special key flags
-        bit 0 = qualified signature (not yet implemented}
-   u16 reserved
- u16  size of serialnumber(may be zero) 
-   n  u16 (see above) bytes of serial number
- u16  number of user IDs
- u16  size of additional user ID information
- n times:
-   u32 offset to the n-th user ID
-   u32 length of this user ID.
-   u16 special user ID flags.
-        bit 0 =
-   byte validity
-   byte reserved
-   [For X509, the first user ID is the Issuer, the second the Subject
-   and the others are subjectAltNames]
- u16  number of signatures
- u16  size of signature information (4)
-   u32 expiration time of signature with some special values:
-       0x00000000 = not checked
-       0x00000001 = missing key
-       0x00000002 = bad signature
-       0x10000000 = valid and expires at some date in 1978.
-       0xffffffff = valid and does not expire
- u8    assigned ownertrust [X509: not used]
- u8    all_validity 
-           OpenPGP:  see ../g10/trustdb/TRUST_* [not yet used]
-           X509: Bit 4 set := key has been revoked.  Note that this value
-                              matches TRUST_FLAG_REVOKED
- u16   reserved
- u32   recheck_after
- u32   Newest timestamp in the keyblock (useful for KS syncronsiation?)
- u32   Blob created at
- u32   size of reserved space (not including this field)
-      reserved space
-
-    Here we might want to put other data
-
-    Here comes the keyblock
-
-    maybe we put a signature here later.
-
- b16   MD5 checksum  (useful for KS syncronisation), we might also want to use
-    a mac here.
- b4    reserved
 
 */
 
@@ -119,14 +147,13 @@ X.509 specific are noted like [X.509: xxx]
 #include "keybox-defs.h"
 #include <gcrypt.h>
 
-#ifdef KEYBOX_WITH_OPENPGP
-/* include stuff to parse the packets */
-#endif
 #ifdef KEYBOX_WITH_X509
 #include <ksba.h>
 #endif
 
 
+#include "../common/gettime.h"
+
 
 /* special values of the signature status */
 #define SF_NONE(a)  ( !(a) )
@@ -154,6 +181,7 @@ struct keyboxblob_key {
   u16    flags;
 };
 struct keyboxblob_uid {
+  u32    off;
   ulong  off_addr;
   char   *name;     /* used only with x509 */
   u32    len;
@@ -178,7 +206,7 @@ struct keyboxblob {
   byte *blob;
   size_t bloblen;
   off_t fileoffset;
-  
+
   /* stuff used only by keybox_create_blob */
   unsigned char *serialbuf;
   const unsigned char *serial;
@@ -191,10 +219,10 @@ struct keyboxblob {
   u32  *sigs;
   struct fixup_list *fixups;
   int fixup_out_of_core;
-  
+
   struct keyid_list *temp_kids;
   struct membuf bufbuf; /* temporary store for the blob */
-  struct membuf *buf; 
+  struct membuf *buf;
 };
 
 
@@ -225,7 +253,7 @@ put_membuf (struct membuf *mb, const void *buf, size_t len)
   if (mb->len + len >= mb->size)
     {
       char *p;
-      
+
       mb->size += len + 1024;
       p = xtryrealloc (mb->buf, mb->size);
       if (!p)
@@ -235,7 +263,10 @@ put_membuf (struct membuf *mb, const void *buf, size_t len)
         }
       mb->buf = p;
     }
-  memcpy (mb->buf + mb->len, buf, len);
+  if (buf)
+    memcpy (mb->buf + mb->len, buf, len);
+  else
+    memset (mb->buf + mb->len, 0, len);
   mb->len += len;
 }
 
@@ -285,20 +316,21 @@ put32 (struct membuf *mb, u32 a )
   put_membuf (mb, tmp, 4);
 }
 
+
 \f
 /* Store a value in the fixup list */
 static void
 add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
 {
   struct fixup_list *fl;
-  
+
   if (blob->fixup_out_of_core)
     return;
 
   fl = xtrycalloc(1, sizeof *fl);
   if (!fl)
     blob->fixup_out_of_core = 1;
-  else 
+  else
     {
       fl->off = off;
       fl->val = val;
@@ -307,177 +339,141 @@ add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
     }
 }
 
-\f
-/*
- Some wrappers
-*/
-
-static u32
-make_timestamp (void)
-{
-  return time(NULL);
-}
-
 
 \f
-#ifdef KEYBOX_WITH_OPENPGP
 /*
-  OpenPGP specific stuff 
+  OpenPGP specific stuff
 */
 
 
-/*
-  We must store the keyid at some place because we can't calculate the
-  offset yet. This is only used for v3 keyIDs.  Function returns an
-  index value for later fixup or -1 for out of core. The value must be
-  a non-zero value */
+/* We must store the keyid at some place because we can't calculate
+   the offset yet. This is only used for v3 keyIDs.  Function returns
+   an index value for later fixup or -1 for out of core.  The value
+   must be a non-zero value. */
 static int
-pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
+pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo)
 {
   struct keyid_list *k, *r;
-  
-  k = xtrymalloc (sizeof *k); 
+
+  k = xtrymalloc (sizeof *k);
   if (!k)
     return -1;
-  k->kid[0] = pk->keyid[0] >> 24 ;
-  k->kid[1] = pk->keyid[0] >> 16 ;
-  k->kid[2] = pk->keyid[0] >>  8 ;
-  k->kid[3] = pk->keyid[0]        ;
-  k->kid[4] = pk->keyid[0] >> 24 ;
-  k->kid[5] = pk->keyid[0] >> 16 ;
-  k->kid[6] = pk->keyid[0] >>  8 ;
-  k->kid[7] = pk->keyid[0]        ;
+  memcpy (k->kid, kinfo->keyid, 8);
   k->seqno = 0;
   k->next = blob->temp_kids;
   blob->temp_kids = k;
-  for (r=k; r; r = r->next) 
+  for (r=k; r; r = r->next)
     k->seqno++;
-  
+
   return k->seqno;
 }
 
-static int
-pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
+
+/* Helper for pgp_create_key_part.  */
+static gpg_error_t
+pgp_create_key_part_single (KEYBOXBLOB blob, int n,
+                            struct _keybox_openpgp_key_info *kinfo)
 {
-  KBNODE node;
   size_t fprlen;
-  int n;
+  int off;
 
-  for (n=0, node = keyblock; node; node = node->next)
+  fprlen = kinfo->fprlen;
+  if (fprlen > 20)
+    fprlen = 20;
+  memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
+  if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */
     {
-      if ( node->pkt->pkttype == PKT_PUBLIC_KEY
-           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) 
-        {
-          PKT_public_key *pk = node->pkt->pkt.public_key;
-          char tmp[20];
-
-          fingerprint_from_pk (pk, tmp , &fprlen);
-          memcpy (blob->keys[n].fpr, tmp, 20);
-          if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
-            {
-              assert (fprlen == 16);
-              memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
-              memset (blob->keys[n].fpr, 0, 4);
-              blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
-           }
-          else
-            {
-              blob->keys[n].off_kid = 0; /* will be fixed up later */
-           }
-          blob->keys[n].flags = 0;
-          n++;
-       }
-      else if ( node->pkt->pkttype == PKT_SECRET_KEY
-                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) 
-        {
-          never_reached (); /* actually not yet implemented */
-       }
+      memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen);
+      memset (blob->keys[n].fpr, 0, 20 - fprlen);
+      off = pgp_temp_store_kid (blob, kinfo);
+      if (off == -1)
+        return gpg_error_from_syserror ();
+      blob->keys[n].off_kid = off;
     }
+  else
+    blob->keys[n].off_kid = 0; /* Will be fixed up later */
+  blob->keys[n].flags = 0;
+  return 0;
+}
+
+
+static gpg_error_t
+pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
+{
+  gpg_error_t err;
+  int n = 0;
+  struct _keybox_openpgp_key_info *kinfo;
+
+  err = pgp_create_key_part_single (blob, n++, &info->primary);
+  if (err)
+    return err;
+  if (info->nsubkeys)
+    for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
+      if ((err=pgp_create_key_part_single (blob, n++, kinfo)))
+        return err;
+
   assert (n == blob->nkeys);
   return 0;
 }
 
-static int
-pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
+
+static void
+pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
 {
-  KBNODE node;
-  int n;
+  int n = 0;
+  struct _keybox_openpgp_uid_info *u;
 
-  for (n=0, node = keyblock; node; node = node->next)
+  if (info->nuids)
     {
-      if (node->pkt->pkttype == PKT_USER_ID)
+      for (u = &info->uids; u; u = u->next)
         {
-          PKT_user_id *u = node->pkt->pkt.user_id;
-          
+          blob->uids[n].off = u->off;
           blob->uids[n].len = u->len;
           blob->uids[n].flags = 0;
           blob->uids[n].validity = 0;
           n++;
-       }
+        }
     }
+
   assert (n == blob->nuids);
-  return 0;
 }
 
-static int
-pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
+
+static void
+pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus)
 {
-  KBNODE node;
   int n;
-  
-  for (n=0, node = keyblock; node; node = node->next)
+
+  for (n=0; n < blob->nsigs; n++)
     {
-      if (node->pkt->pkttype == PKT_SIGNATURE)
-        {
-          PKT_signature *sig = node->pkt->pkt.signature;
-          
-          blob->sigs[n] = 0;   /* FIXME: check the signature here */
-          n++;
-       }
+      blob->sigs[n] = sigstatus? sigstatus[n+1] : 0;
     }
-  assert( n == blob->nsigs );
-  return 0;
 }
 
+
 static int
-pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
+pgp_create_blob_keyblock (KEYBOXBLOB blob,
+                          const unsigned char *image, size_t imagelen)
 {
   struct membuf *a = blob->buf;
-  KBNODE node;
-  int rc;
   int n;
   u32 kbstart = a->len;
 
-  add_fixup (blob, kbstart);
+  add_fixup (blob, 8, kbstart);
 
-  for (n = 0, node = keyblock; node; node = node->next)
-    {
-      rc = build_packet ( a, node->pkt );
-      if ( rc ) {
-        gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
-                      node->pkt->pkttype, gpg_errstr(rc) );
-        return GPGERR_WRITE_FILE;
-      }
-      if ( node->pkt->pkttype == PKT_USER_ID ) 
-        {
-          PKT_user_id *u = node->pkt->pkt.user_id;
-          /* build_packet has set the offset of the name into u ;
-           * now we can do the fixup */
-          add_fixup (blob, blob->uids[n].off_addr, u->stored_at);
-          n++;
-       }
-    }
-  assert (n == blob->nuids);
+  for (n = 0; n < blob->nuids; n++)
+    add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off);
+
+  put_membuf (a, image, imagelen);
 
-  add_fixup (blob, a->len - kbstart);
+  add_fixup (blob, 12, a->len - kbstart);
   return 0;
 }
-#endif /*KEYBOX_WITH_OPENPGP*/
+
 
 \f
 #ifdef KEYBOX_WITH_X509
-/* 
+/*
    X.509 specific stuff
  */
 
@@ -501,7 +497,7 @@ x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
   add_fixup (blob, 12, a->len - kbstart);
   return 0;
 }
+
 #endif /*KEYBOX_WITH_X509*/
 
 /* Write a stored keyID out to the buffer */
@@ -509,8 +505,8 @@ static void
 write_stored_kid (KEYBOXBLOB blob, int seqno)
 {
   struct keyid_list *r;
-  
-  for ( r = blob->temp_kids; r; r = r->next ) 
+
+  for ( r = blob->temp_kids; r; r = r->next )
     {
       if (r->seqno == seqno )
         {
@@ -526,8 +522,8 @@ static void
 release_kid_list (struct keyid_list *kl)
 {
   struct keyid_list *r, *r2;
-  
-  for ( r = kl; r; r = r2 ) 
+
+  for ( r = kl; r; r = r2 )
     {
       r2 = r->next;
       xfree (r);
@@ -543,7 +539,7 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
   int i;
 
   put32 ( a, 0 ); /* blob length, needs fixup */
-  put8 ( a, blobtype);  
+  put8 ( a, blobtype);
   put8 ( a, 1 );  /* blob type version */
   put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
 
@@ -595,14 +591,14 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
 
   /* space where we write keyIDs and and other stuff so that the
      pointers can actually point to somewhere */
-  if (blobtype == BLOBTYPE_PGP)
+  if (blobtype == KEYBOX_BLOBTYPE_PGP)
     {
       /* We need to store the keyids for all pgp v3 keys because those key
          IDs are not part of the fingerprint.  While we are doing that, we
          fixup all the keyID offsets */
       for (i=0; i < blob->nkeys; i++ )
         {
-          if (blob->keys[i].off_kid) 
+          if (blob->keys[i].off_kid)
             { /* this is a v3 one */
               add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
               write_stored_kid (blob, blob->keys[i].off_kid);
@@ -610,18 +606,18 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
           else
             { /* the better v4 key IDs - just store an offset 8 bytes back */
               add_fixup (blob, blob->keys[i].off_kid_addr,
-                         blob->keys[i].off_kid_addr - 8); 
+                         blob->keys[i].off_kid_addr - 8);
             }
         }
     }
-  
-  if (blobtype == BLOBTYPE_X509)
+
+  if (blobtype == KEYBOX_BLOBTYPE_X509)
     {
       /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
          the utf-8 string represenation of them */
       for (i=0; i < blob->nuids; i++ )
         {
-          if (blob->uids[i].name) 
+          if (blob->uids[i].name)
             { /* this is a v3 one */
               add_fixup (blob, blob->uids[i].off_addr, a->len);
               put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
@@ -648,13 +644,11 @@ create_blob_finish (KEYBOXBLOB blob)
   struct membuf *a = blob->buf;
   unsigned char *p;
   unsigned char *pp;
-  int i;
   size_t n;
 
-  /* write a placeholder for the checksum */
-  for (i = 0; i < 16; i++ )
-    put32 (a, 0);  /* Hmmm: why put32() ?? */
-  
+  /* Write a placeholder for the checksum */
+  put_membuf (a, NULL, 20);
+
   /* get the memory area */
   n = 0; /* (Just to avoid compiler warning.) */
   p = get_membuf (a, &n);
@@ -681,8 +675,8 @@ create_blob_finish (KEYBOXBLOB blob)
       }
   }
 
-  /* calculate and store the MD5 checksum */
-  gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
+  /* Compute and store the SHA-1 checksum. */
+  gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20);
 
   pp = xtrymalloc (n);
   if ( !pp )
@@ -690,92 +684,95 @@ create_blob_finish (KEYBOXBLOB blob)
   memcpy (pp , p, n);
   blob->blob = pp;
   blob->bloblen = n;
-  
+
   return 0;
 }
 
-\f
-#ifdef KEYBOX_WITH_OPENPGP
 
-int
-_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral)
+\f
+gpg_error_t
+_keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
+                             keybox_openpgp_info_t info,
+                             const unsigned char *image,
+                             size_t imagelen,
+                             u32 *sigstatus,
+                             int as_ephemeral)
 {
-  int rc = 0;
-  KBNODE node;
+  gpg_error_t err;
   KEYBOXBLOB blob;
 
   *r_blob = NULL;
+
+  /* If we have a signature status vector, check that the number of
+     elements matches the actual number of signatures.  */
+  if (sigstatus && sigstatus[0] != info->nsigs)
+    return gpg_error (GPG_ERR_INTERNAL);
+
   blob = xtrycalloc (1, sizeof *blob);
   if (!blob)
     return gpg_error_from_syserror ();
 
-  /* fixme: Do some sanity checks on the keyblock */
+  blob->nkeys = 1 + info->nsubkeys;
+  blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
+  if (!blob->keys)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
 
-  /* count userids and keys so that we can allocate the arrays */
-  for (node = keyblock; node; node = node->next) 
+  blob->nuids = info->nuids;
+  if (blob->nuids)
     {
-      switch (node->pkt->pkttype)
+      blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
+      if (!blob->uids)
         {
-        case PKT_PUBLIC_KEY:
-        case PKT_SECRET_KEY:
-        case PKT_PUBLIC_SUBKEY:
-        case PKT_SECRET_SUBKEY: blob->nkeys++; break;
-        case PKT_USER_ID:  blob->nuids++; break;
-        case PKT_SIGNATURE: blob->nsigs++; break;
-        default: break;
-       }
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
 
-  blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
-  blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
-  blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
-  if (!blob->keys || !blob->uids || !blob->sigs)
+  blob->nsigs = info->nsigs;
+  if (blob->nsigs)
     {
-      rc = gpg_error (GPG_ERR_ENOMEM);
-      goto leave;
+      blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
+      if (!blob->sigs)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
 
-  rc = pgp_create_key_part ( blob, keyblock );
-  if (rc)
-    goto leave;
-  rc = pgp_create_uid_part ( blob, keyblock );
-  if (rc)
-    goto leave;
-  rc = pgp_create_sig_part ( blob, keyblock );
-  if (rc)
+  err = pgp_create_key_part (blob, info);
+  if (err)
     goto leave;
-  
+  pgp_create_uid_part (blob, info);
+  pgp_create_sig_part (blob, sigstatus);
+
   init_membuf (&blob->bufbuf, 1024);
   blob->buf = &blob->bufbuf;
-  rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral);
-  if (rc)
+  err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral);
+  if (err)
     goto leave;
-  rc = pgp_create_blob_keyblock (blob, keyblock);
-  if (rc)
+  err = pgp_create_blob_keyblock (blob, image, imagelen);
+  if (err)
     goto leave;
-  rc = create_blob_trailer (blob);
-  if (rc)
+  err = create_blob_trailer (blob);
+  if (err)
     goto leave;
-  rc = create_blob_finish ( blob );
-  if (rc)
+  err = create_blob_finish (blob);
+  if (err)
     goto leave;
 
-  
  leave:
   release_kid_list (blob->temp_kids);
   blob->temp_kids = NULL;
-  if (rc)
-    {
-      keybox_release_blob (blob);
-      *r_blob = NULL;
-    }
+  if (err)
+    _keybox_release_blob (blob);
   else
-    {
-      *r_blob = blob;
-    }
-  return rc;
+    *r_blob = blob;
+  return err;
 }
-#endif /*KEYBOX_WITH_OPENPGP*/
+
 
 #ifdef KEYBOX_WITH_X509
 
@@ -877,7 +874,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
       rc = gpg_error_from_syserror ();
       goto leave;
     }
-  
+
   p = ksba_cert_get_issuer (cert, 0);
   if (!p)
     {
@@ -890,7 +887,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
       if (blob->nuids >= max_names)
         {
           char **tmp;
-          
+
           max_names += 100;
           tmp = xtryrealloc (names, max_names * sizeof *names);
           if (!tmp)
@@ -904,9 +901,9 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
       if (!i && (p=x509_email_kludge (p)))
         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
     }
-  
+
   /* space for signature information */
-  blob->nsigs = 1; 
+  blob->nsigs = 1;
 
   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
@@ -940,7 +937,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
   init_membuf (&blob->bufbuf, 1024);
   blob->buf = &blob->bufbuf;
   /* write out what we already have */
-  rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
+  rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral);
   if (rc)
     goto leave;
   rc = x509_create_blob_cert (blob, cert);
@@ -953,16 +950,16 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
   if (rc)
     goto leave;
 
-  
+
  leave:
   release_kid_list (blob->temp_kids);
   blob->temp_kids = NULL;
-  if (blob && names)
+  if (names)
     {
       for (i=0; i < blob->nuids; i++)
-        xfree (names[i]); 
+        xfree (names[i]);
+      xfree (names);
     }
-  xfree (names);
   if (rc)
     {
       _keybox_release_blob (blob);
@@ -983,7 +980,7 @@ _keybox_new_blob (KEYBOXBLOB *r_blob,
                   unsigned char *image, size_t imagelen, off_t off)
 {
   KEYBOXBLOB blob;
-  
+
   *r_blob = NULL;
   blob = xtrycalloc (1, sizeof *blob);
   if (!blob)
@@ -1032,9 +1029,9 @@ _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
 
 
 void
-_keybox_update_header_blob (KEYBOXBLOB blob)
+_keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp)
 {
-  if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
+  if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER)
     {
       u32 val = make_timestamp ();
 
@@ -1043,5 +1040,8 @@ _keybox_update_header_blob (KEYBOXBLOB blob)
       blob->blob[20+1] = (val >> 16);
       blob->blob[20+2] = (val >>  8);
       blob->blob[20+3] = (val      );
+
+      if (for_openpgp)
+        blob->blob[7] |= 0x02;  /* OpenPGP data may be available.  */
     }
 }
index 728168d..8d795ab 100644 (file)
@@ -1,4 +1,4 @@
-/* keybox-defs.h - interal Keybox defintions
+/* keybox-defs.h - internal Keybox definitions
  *     Copyright (C) 2001, 2004 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
 #define KEYBOX_DEFS_H 1
 
 #ifdef GPG_ERR_SOURCE_DEFAULT
-#error GPG_ERR_SOURCE_DEFAULT already defined
+# if GPG_ERR_SOURCE_DEFAULT != GPG_ERR_SOURCE_KEYBOX
+#  error GPG_ERR_SOURCE_DEFAULT already defined
+# endif
+#else
+# define GPG_ERR_SOURCE_DEFAULT  GPG_ERR_SOURCE_KEYBOX
 #endif
-#define GPG_ERR_SOURCE_DEFAULT  GPG_ERR_SOURCE_KEYBOX
 #include <gpg-error.h>
 #define map_assuan_err(a) \
         map_assuan_err_with_source (GPG_ERR_SOURCE_DEFAULT, (a))
    owns here.  This will not allow us build KBX in a standalone way
    but there is currently no need for it anyway.  Same goes for
    stringhelp.h which for example provides a replacement for stpcpy -
-   fixme: Better the LIBOBJ mechnism. */
-#include "../jnlib/types.h"
-#include "../jnlib/stringhelp.h"
+   fixme: Better use the LIBOBJ mechnism. */
+#include "../common/types.h"
+#include "../common/stringhelp.h"
 
 #include "keybox.h"
 
 
-enum {
-  BLOBTYPE_EMPTY = 0,
-  BLOBTYPE_HEADER = 1,
-  BLOBTYPE_PGP = 2,
-  BLOBTYPE_X509 = 3
-};
-
-
 typedef struct keyboxblob *KEYBOXBLOB;
 
 
@@ -98,6 +93,7 @@ struct keybox_handle {
   int eof;
   int error;
   int ephemeral;
+  int for_openpgp;        /* Used by gpg.  */
   struct keybox_found_s found;
   struct keybox_found_s saved_found;
   struct {
@@ -111,6 +107,7 @@ struct keybox_handle {
 struct _keybox_openpgp_key_info
 {
   struct _keybox_openpgp_key_info *next;
+  int algo;
   unsigned char keyid[8];
   int fprlen;  /* Either 16 or 20 */
   unsigned char fpr[20];
@@ -155,9 +152,12 @@ void _keybox_close_file (KEYBOX_HANDLE hd);
 
 
 /*-- keybox-blob.c --*/
-#ifdef KEYBOX_WITH_OPENPGP
-  /* fixme */
-#endif /*KEYBOX_WITH_OPENPGP*/
+gpg_error_t _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
+                                         keybox_openpgp_info_t info,
+                                         const unsigned char *image,
+                                         size_t imagelen,
+                                         u32 *sigstatus,
+                                         int as_ephemeral);
 #ifdef KEYBOX_WITH_X509
 int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
                               unsigned char *sha1_digest, int as_ephemeral);
@@ -169,7 +169,7 @@ int  _keybox_new_blob (KEYBOXBLOB *r_blob,
 void _keybox_release_blob (KEYBOXBLOB blob);
 const unsigned char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n);
 off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob);
-void _keybox_update_header_blob (KEYBOXBLOB blob);
+void _keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp);
 
 /*-- keybox-openpgp.c --*/
 gpg_error_t _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
@@ -182,7 +182,6 @@ void _keybox_destroy_openpgp_info (keybox_openpgp_info_t info);
 int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp);
 int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted);
 int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp);
-int _keybox_write_header_blob (FILE *fp);
 
 /*-- keybox-search.c --*/
 gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer,
@@ -190,6 +189,20 @@ gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer,
                                           int what,
                                           size_t *flag_off, size_t *flag_size);
 
+static inline int
+blob_get_type (KEYBOXBLOB blob)
+{
+  const unsigned char *buffer;
+  size_t length;
+
+  buffer = _keybox_get_blob_image (blob, &length);
+  if (length < 32)
+    return -1; /* blob too short */
+
+  return buffer[4];
+}
+
+
 /*-- keybox-dump.c --*/
 int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp);
 int _keybox_dump_file (const char *filename, int stats_only, FILE *outfp);
@@ -223,19 +236,19 @@ void  _keybox_free (void *p);
 
 #define return_if_fail(expr) do {                        \
     if (!(expr)) {                                       \
-        fprintf (stderr, "%s:%d: assertion `%s' failed\n", \
+        fprintf (stderr, "%s:%d: assertion '%s' failed\n", \
                  __FILE__, __LINE__, #expr );            \
         return;                                                 \
     } } while (0)
 #define return_null_if_fail(expr) do {                   \
     if (!(expr)) {                                       \
-        fprintf (stderr, "%s:%d: assertion `%s' failed\n", \
+        fprintf (stderr, "%s:%d: assertion '%s' failed\n", \
                  __FILE__, __LINE__, #expr );            \
         return NULL;                                    \
     } } while (0)
 #define return_val_if_fail(expr,val) do {                \
     if (!(expr)) {                                       \
-        fprintf (stderr, "%s:%d: assertion `%s' failed\n", \
+        fprintf (stderr, "%s:%d: assertion '%s' failed\n", \
                  __FILE__, __LINE__, #expr );            \
         return (val);                                   \
     } } while (0)
@@ -260,5 +273,3 @@ void  _keybox_free (void *p);
 
 
 #endif /*KEYBOX_DEFS_H*/
-
-
index da716f3..5315e84 100644 (file)
@@ -25,7 +25,6 @@
 
 #include "keybox-defs.h"
 #include <gcrypt.h>
-#include "../include/host2net.h"
 
 /* Argg, we can't include ../common/util.h */
 char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
@@ -34,13 +33,21 @@ char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
 static ulong
 get32 (const byte *buffer)
 {
-  return buf32_to_ulong (buffer);
+  ulong a;
+  a =  *buffer << 24;
+  a |= buffer[1] << 16;
+  a |= buffer[2] << 8;
+  a |= buffer[3];
+  return a;
 }
 
 static ulong
 get16 (const byte *buffer)
 {
-  return buf16_to_ulong (buffer);
+  ulong a;
+  a =  *buffer << 8;
+  a |= buffer[1];
+  return a;
 }
 
 void
@@ -73,6 +80,57 @@ print_string (FILE *fp, const byte *p, size_t n, int delim)
 
 
 static int
+print_checksum (const byte *buffer, size_t length, size_t unhashed, FILE *fp)
+{
+  const byte *p;
+  int i;
+  int hashlen;
+  unsigned char digest[20];
+
+  fprintf (fp, "Checksum: ");
+  if (unhashed && unhashed < 20)
+    {
+      fputs ("[specified unhashed sized too short]\n", fp);
+      return 0;
+    }
+  if (!unhashed)
+    {
+      unhashed = 16;
+      hashlen = 16;
+    }
+  else
+    hashlen = 20;
+  if (length < 5+unhashed)
+    {
+      fputs ("[blob too short for a checksum]\n", fp);
+      return 0;
+    }
+
+  p = buffer + length - hashlen;
+  for (i=0; i < hashlen; p++, i++)
+    fprintf (fp, "%02x", *p);
+
+  if (hashlen == 16) /* Compatibility method.  */
+    {
+      gcry_md_hash_buffer (GCRY_MD_MD5, digest, buffer, length - 16);
+      if (!memcmp (buffer + length - 16, digest, 16))
+        fputs (" [valid]\n", fp);
+      else
+        fputs (" [bad]\n", fp);
+    }
+  else
+    {
+      gcry_md_hash_buffer (GCRY_MD_SHA1, digest, buffer, length - unhashed);
+      if (!memcmp (buffer + length - hashlen, digest, hashlen))
+        fputs (" [valid]\n", fp);
+      else
+        fputs (" [bad]\n", fp);
+    }
+  return 0;
+}
+
+
+static int
 dump_header_blob (const byte *buffer, size_t length, FILE *fp)
 {
   unsigned long n;
@@ -83,6 +141,25 @@ dump_header_blob (const byte *buffer, size_t length, FILE *fp)
       return -1;
     }
   fprintf (fp, "Version: %d\n", buffer[5]);
+
+  n = get16 (buffer + 6);
+  fprintf( fp, "Flags:   %04lX", n);
+  if (n)
+    {
+      int any = 0;
+
+      fputs (" (", fp);
+      if ((n & 2))
+        {
+          if (any)
+            putc (',', fp);
+          fputs ("openpgp", fp);
+          any++;
+        }
+      putc (')', fp);
+    }
+  putc ('\n', fp);
+
   if ( memcmp (buffer+8, "KBXf", 4))
     fprintf (fp, "[Error: invalid magic number]\n");
 
@@ -101,12 +178,13 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
 {
   const byte *buffer;
   size_t length;
-  int type;
+  int type, i;
   ulong n, nkeys, keyinfolen;
   ulong nuids, uidinfolen;
   ulong nsigs, siginfolen;
   ulong rawdata_off, rawdata_len;
   ulong nserial;
+  ulong unhashed;
   const byte *p;
 
   buffer = _keybox_get_blob_image (blob, &length);
@@ -127,17 +205,17 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
   type = buffer[4];
   switch (type)
     {
-    case BLOBTYPE_EMPTY:
+    case KEYBOX_BLOBTYPE_EMPTY:
       fprintf (fp, "Type:   Empty\n");
       return 0;
 
-    case BLOBTYPE_HEADER:
+    case KEYBOX_BLOBTYPE_HEADER:
       fprintf (fp, "Type:   Header\n");
       return dump_header_blob (buffer, length, fp);
-    case BLOBTYPE_PGP:
+    case KEYBOX_BLOBTYPE_PGP:
       fprintf (fp, "Type:   OpenPGP\n");
       break;
-    case BLOBTYPE_X509:
+    case KEYBOX_BLOBTYPE_X509:
       fprintf (fp, "Type:   X.509\n");
       break;
     default:
@@ -182,14 +260,18 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
   fprintf( fp, "Data-Offset: %lu\n", rawdata_off );
   fprintf( fp, "Data-Length: %lu\n", rawdata_len );
   if (rawdata_off > length || rawdata_len > length
-      || rawdata_off+rawdata_off > length)
+      || rawdata_off+rawdata_len > length
+      || rawdata_len + 4 > length
+      || rawdata_off+rawdata_len + 4 > length)
     fprintf (fp, "[Error: raw data larger than blob]\n");
+  unhashed = length - rawdata_off - rawdata_len;
+  fprintf (fp, "Unhashed: %lu\n", unhashed);
 
   nkeys = get16 (buffer + 16);
   fprintf (fp, "Key-Count: %lu\n", nkeys );
   if (!nkeys)
     fprintf (fp, "[Error: no keys]\n");
-  if (nkeys > 1 && type == BLOBTYPE_X509)
+  if (nkeys > 1 && type == KEYBOX_BLOBTYPE_X509)
     fprintf (fp, "[Error: only one key allowed for X509]\n");
 
   keyinfolen = get16 (buffer + 18 );
@@ -198,7 +280,6 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
   p = buffer + 20;
   for (n=0; n < nkeys; n++, p += keyinfolen)
     {
-      int i;
       ulong kidoff, kflags;
 
       fprintf (fp, "Key-Fpr[%lu]: ", n );
@@ -240,13 +321,13 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
 
       uidoff = get32( p );
       uidlen = get32( p+4 );
-      if (type == BLOBTYPE_X509 && !n)
+      if (type == KEYBOX_BLOBTYPE_X509 && !n)
         {
           fprintf (fp, "Issuer-Off: %lu\n", uidoff );
           fprintf (fp, "Issuer-Len: %lu\n", uidlen );
           fprintf (fp, "Issuer: \"");
         }
-      else if (type == BLOBTYPE_X509 && n == 1)
+      else if (type == KEYBOX_BLOBTYPE_X509 && n == 1)
         {
           fprintf (fp, "Subject-Off: %lu\n", uidoff );
           fprintf (fp, "Subject-Len: %lu\n", uidlen );
@@ -261,12 +342,12 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
       print_string (fp, buffer+uidoff, uidlen, '\"');
       fputs ("\"\n", fp);
       uflags = get16 (p + 8);
-      if (type == BLOBTYPE_X509 && !n)
+      if (type == KEYBOX_BLOBTYPE_X509 && !n)
         {
           fprintf (fp, "Issuer-Flags: %04lX\n", uflags );
           fprintf (fp, "Issuer-Validity: %d\n", p[10] );
         }
-      else if (type == BLOBTYPE_X509 && n == 1)
+      else if (type == KEYBOX_BLOBTYPE_X509 && n == 1)
         {
           fprintf (fp, "Subject-Flags: %04lX\n", uflags );
           fprintf (fp, "Subject-Validity: %d\n", p[10] );
@@ -284,27 +365,50 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
   fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen );
   /* fixme: check bounds  */
   p += 4;
-  for (n=0; n < nsigs; n++, p += siginfolen)
-    {
-      ulong sflags;
-
-      sflags = get32 (p);
-      fprintf (fp, "Sig-Expire[%lu]: ", n );
-      if (!sflags)
-        fputs ("[not checked]", fp);
-      else if (sflags == 1 )
-        fputs ("[missing key]", fp);
-      else if (sflags == 2 )
-        fputs ("[bad signature]", fp);
-      else if (sflags < 0x10000000)
-        fprintf (fp, "[bad flag %0lx]", sflags);
-      else if (sflags == 0xffffffff)
-        fputs ("0", fp );
-      else
-        fputs ("a time"/*strtimestamp( sflags )*/, fp );
-      putc ('\n', fp );
-    }
-
+  {
+    int in_range = 0;
+    ulong first = 0;
+
+    for (n=0; n < nsigs; n++, p += siginfolen)
+      {
+        ulong sflags;
+
+        sflags = get32 (p);
+        if (!in_range && !sflags)
+          {
+            in_range = 1;
+            first = n;
+            continue;
+          }
+        if (in_range && !sflags)
+          continue;
+        if (in_range)
+          {
+            fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1);
+            in_range = 0;
+          }
+
+        fprintf (fp, "Sig-Expire[%lu]: ", n );
+        if (!sflags)
+          fputs ("[not checked]", fp);
+        else if (sflags == 1 )
+          fputs ("[missing key]", fp);
+        else if (sflags == 2 )
+          fputs ("[bad signature]", fp);
+        else if (sflags < 0x10000000)
+          fprintf (fp, "[bad flag %0lx]", sflags);
+        else if (sflags == (ulong)(-1))
+          fputs ("[good - does not expire]", fp );
+        else
+          fprintf (fp, "[good - expires at %lu]", sflags);
+        putc ('\n', fp );
+      }
+    if (in_range)
+      {
+        fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1);
+        in_range = 0;
+      }
+  }
   fprintf (fp, "Ownertrust: %d\n", p[0] );
   fprintf (fp, "All-Validity: %d\n", p[1] );
   p += 4;
@@ -317,13 +421,17 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
   n = get32 (p ); p += 4;
   fprintf (fp, "Reserved-Space: %lu\n", n );
 
-  /* check that the keyblock is at the correct offset and other bounds */
-  /*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/
+  if (n >= 4 && unhashed >= 24)
+    {
+      n = get32 ( buffer + length - unhashed);
+      fprintf (fp, "Storage-Flags: %08lx\n", n );
+    }
+  print_checksum (buffer, length, unhashed, fp);
   return 0;
 }
 
 
-/* Compute the SHA_1 checksum of teh rawdata in BLOB and aput it into
+/* Compute the SHA-1 checksum of the rawdata in BLOB and put it into
    DIGEST. */
 static int
 hash_blob_rawdata (KEYBOXBLOB blob, unsigned char *digest)
@@ -344,12 +452,12 @@ hash_blob_rawdata (KEYBOXBLOB blob, unsigned char *digest)
   type = buffer[4];
   switch (type)
     {
-    case BLOBTYPE_PGP:
-    case BLOBTYPE_X509:
+    case KEYBOX_BLOBTYPE_PGP:
+    case KEYBOX_BLOBTYPE_X509:
       break;
 
-    case BLOBTYPE_EMPTY:
-    case BLOBTYPE_HEADER:
+    case KEYBOX_BLOBTYPE_EMPTY:
+    case KEYBOX_BLOBTYPE_HEADER:
     default:
       memset (digest, 0, 20);
       return 0;
@@ -383,6 +491,7 @@ struct file_stats_s
   unsigned long non_flagged;
   unsigned long secret_flagged;
   unsigned long ephemeral_flagged;
+  unsigned long skipped_long_blobs;
 };
 
 static int
@@ -410,16 +519,16 @@ update_stats (KEYBOXBLOB blob, struct file_stats_s *s)
   type = buffer[4];
   switch (type)
     {
-    case BLOBTYPE_EMPTY:
+    case KEYBOX_BLOBTYPE_EMPTY:
       s->empty_blob_count++;
       return 0;
-    case BLOBTYPE_HEADER:
+    case KEYBOX_BLOBTYPE_HEADER:
       s->header_blob_count++;
       return 0;
-    case BLOBTYPE_PGP:
+    case KEYBOX_BLOBTYPE_PGP:
       s->pgp_blob_count++;
       break;
-    case BLOBTYPE_X509:
+    case KEYBOX_BLOBTYPE_X509:
       s->x509_blob_count++;
       break;
     default:
@@ -464,8 +573,8 @@ open_file (const char **filename, FILE *outfp)
   if (!fp)
     {
       int save_errno = errno;
-      fprintf (outfp, "can't open `%s': %s\n", *filename, strerror(errno));
-      errno = save_errno;
+      fprintf (outfp, "can't open '%s': %s\n", *filename, strerror(errno));
+      gpg_err_set_errno (save_errno);
     }
   return fp;
 }
@@ -486,8 +595,25 @@ _keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
   if (!(fp = open_file (&filename, outfp)))
     return gpg_error_from_syserror ();
 
-  while ( !(rc = _keybox_read_blob (&blob, fp)) )
+  for (;;)
     {
+      rc = _keybox_read_blob (&blob, fp);
+      if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
+          && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
+        {
+          if (stats_only)
+            stats.skipped_long_blobs++;
+          else
+            {
+              fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
+              fprintf (outfp, "# Record too large\nEND-RECORD\n");
+            }
+          count++;
+          continue;
+        }
+      if (rc)
+        break;
+
       if (stats_only)
         {
           update_stats (blob, &stats);
@@ -504,7 +630,7 @@ _keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
   if (rc == -1)
     rc = 0;
   if (rc)
-    fprintf (outfp, "error reading `%s': %s\n", filename, gpg_strerror (rc));
+    fprintf (outfp, "# error reading '%s': %s\n", filename, gpg_strerror (rc));
 
   if (fp != stdin)
     fclose (fp);
@@ -528,14 +654,17 @@ _keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
                stats.non_flagged,
                stats.secret_flagged,
                stats.ephemeral_flagged);
+        if (stats.skipped_long_blobs)
+          fprintf (outfp, "   skipped long blobs: %8lu\n",
+                   stats.skipped_long_blobs);
         if (stats.unknown_blob_count)
           fprintf (outfp, "   unknown blob types: %8lu\n",
                    stats.unknown_blob_count);
         if (stats.too_short_blobs)
-          fprintf (outfp, "      too short blobs: %8lu\n",
+          fprintf (outfp, "      too short blobs: %8lu (error)\n",
                    stats.too_short_blobs);
         if (stats.too_large_blobs)
-          fprintf (outfp, "      too large blobs: %8lu\n",
+          fprintf (outfp, "      too large blobs: %8lu (error)\n",
                    stats.too_large_blobs);
     }
 
@@ -585,7 +714,7 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
   if (!dupitems)
     {
       gpg_error_t tmperr = gpg_error_from_syserror ();
-      fprintf (outfp, "error allocating array for `%s': %s\n",
+      fprintf (outfp, "error allocating array for '%s': %s\n",
                filename, strerror(errno));
       return tmperr;
     }
@@ -596,7 +725,7 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
       unsigned char digest[20];
 
       if (hash_blob_rawdata (blob, digest))
-        fprintf (outfp, "error in blob %ld of `%s'\n", recno, filename);
+        fprintf (outfp, "error in blob %ld of '%s'\n", recno, filename);
       else if (memcmp (digest, zerodigest, 20))
         {
           if (dupitems_count >= dupitems_size)
@@ -608,7 +737,7 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
               if (!tmp)
                 {
                   gpg_error_t tmperr = gpg_error_from_syserror ();
-                  fprintf (outfp, "error reallocating array for `%s': %s\n",
+                  fprintf (outfp, "error reallocating array for '%s': %s\n",
                            filename, strerror(errno));
                   free (dupitems);
                   return tmperr;
@@ -625,7 +754,7 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
   if (rc == -1)
     rc = 0;
   if (rc)
-    fprintf (outfp, "error reading `%s': %s\n", filename, gpg_strerror (rc));
+    fprintf (outfp, "error reading '%s': %s\n", filename, gpg_strerror (rc));
   if (fp != stdin)
     fclose (fp);
 
@@ -684,7 +813,7 @@ _keybox_dump_cut_records (const char *filename, unsigned long from,
   if (rc == -1)
     rc = 0;
   if (rc)
-    fprintf (stderr, "error reading `%s': %s\n", filename, gpg_strerror (rc));
+    fprintf (stderr, "error reading '%s': %s\n", filename, gpg_strerror (rc));
  leave:
   if (fp != stdin)
     fclose (fp);
index e11efc1..ce2b498 100644 (file)
@@ -6,12 +6,12 @@
 
 /**
  * keybox_strerror:
- * @err:  Error code 
- * 
+ * @err:  Error code
+ *
  * This function returns a textual representaion of the given
  * errorcode. If this is an unknown value, a string with the value
  * is returned (Beware: it is hold in a static buffer).
- * 
+ *
  * Return value: String with the error description.
  **/
 const char *
@@ -44,4 +44,3 @@ keybox_strerror (KeyboxError err)
 
   return s;
 }
-
index e3c22bd..98808ed 100644 (file)
@@ -27,6 +27,9 @@
 #include "keybox-defs.h"
 
 
+#define IMAGELEN_LIMIT (2*1024*1024)
+
+
 #if !defined(HAVE_FTELLO) && !defined(ftello)
 static off_t
 ftello (FILE *stream)
@@ -43,7 +46,7 @@ ftello (FILE *stream)
 
 
 /* Read a block at the current postion and return it in r_blob.
-   r_blob may be NULL to simply skip the current block */
+   r_blob may be NULL to simply skip the current block */
 int
 _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
 {
@@ -55,7 +58,8 @@ _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
 
   *skipped_deleted = 0;
  again:
-  *r_blob = NULL;
+  if (r_blob)
+    *r_blob = NULL;
   off = ftello (fp);
   if (off == (off_t)-1)
     return gpg_error_from_syserror ();
@@ -74,10 +78,7 @@ _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
     }
 
   imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4;
-  if (imagelen > 500000) /* Sanity check. */
-    return gpg_error (GPG_ERR_TOO_LARGE);
-  
-  if (imagelen < 5) 
+  if (imagelen < 5)
     return gpg_error (GPG_ERR_TOO_SHORT);
 
   if (!type)
@@ -89,8 +90,17 @@ _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
       goto again;
     }
 
+  if (imagelen > IMAGELEN_LIMIT) /* Sanity check. */
+    {
+      /* Seek forward so that the caller may choose to ignore this
+         record.  */
+      if (fseek (fp, imagelen-5, SEEK_CUR))
+        return gpg_error_from_syserror ();
+      return gpg_error (GPG_ERR_TOO_LARGE);
+    }
+
   image = xtrymalloc (imagelen);
-  if (!image) 
+  if (!image)
     return gpg_error_from_syserror ();
 
   image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4; image[4] = type;
@@ -100,7 +110,7 @@ _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
       xfree (image);
       return tmperr;
     }
-  
+
   rc = r_blob? _keybox_new_blob (r_blob, image, imagelen, off) : 0;
   if (rc || !r_blob)
     xfree (image);
@@ -123,6 +133,10 @@ _keybox_write_blob (KEYBOXBLOB blob, FILE *fp)
   size_t length;
 
   image = _keybox_get_blob_image (blob, &length);
+
+  if (length > IMAGELEN_LIMIT)
+    return gpg_error (GPG_ERR_TOO_LARGE);
+
   if (fwrite (image, length, 1, fp) != 1)
     return gpg_error_from_syserror ();
   return 0;
@@ -131,7 +145,7 @@ _keybox_write_blob (KEYBOXBLOB blob, FILE *fp)
 
 /* Write a fresh header type blob. */
 int
-_keybox_write_header_blob (FILE *fp)
+_keybox_write_header_blob (FILE *fp, int for_openpgp)
 {
   unsigned char image[32];
   u32 val;
@@ -140,9 +154,11 @@ _keybox_write_header_blob (FILE *fp)
   /* Length of this blob. */
   image[3] = 32;
 
-  image[4] = BLOBTYPE_HEADER;
+  image[4] = KEYBOX_BLOBTYPE_HEADER;
   image[5] = 1; /* Version */
-  
+  if (for_openpgp)
+    image[7] = 0x02; /* OpenPGP data may be available.  */
+
   memcpy (image+8, "KBXf", 4);
   val = time (NULL);
   /* created_at and last maintenance run. */
@@ -159,5 +175,3 @@ _keybox_write_header_blob (FILE *fp)
     return gpg_error_from_syserror ();
   return 0;
 }
-
-
index 53c1c50..0d4800e 100644 (file)
@@ -1,4 +1,4 @@
-/* keybox-init.c - Initalization of the library 
+/* keybox-init.c - Initalization of the library
  *     Copyright (C) 2001 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
@@ -24,7 +24,7 @@
 #include <unistd.h>
 #include <assert.h>
 
-#include "../jnlib/mischelp.h"
+#include "../common/mischelp.h"
 #include "keybox-defs.h"
 
 static KB_NAME kb_names;
@@ -59,7 +59,7 @@ keybox_register_file (const char *fname, int secret)
   /* keep a list of all issued pointers */
   kr->next = kb_names;
   kb_names = kr;
-  
+
   /* create the offset table the first time a function here is used */
 /*      if (!kb_offtbl) */
 /*        kb_offtbl = new_offset_hash_table (); */
@@ -75,17 +75,12 @@ keybox_is_writable (void *token)
   return r? !access (r->fname, W_OK) : 0;
 }
 
-    
 
-/* Create a new handle for the resource associated with TOKEN.  SECRET
-   is just a cross-check.
-   
-   The returned handle must be released using keybox_release (). */
-KEYBOX_HANDLE
-keybox_new (void *token, int secret)
+
+static KEYBOX_HANDLE
+do_keybox_new (KB_NAME resource, int secret, int for_openpgp)
 {
   KEYBOX_HANDLE hd;
-  KB_NAME resource = token;
   int idx;
 
   assert (resource && !resource->secret == !secret);
@@ -94,6 +89,7 @@ keybox_new (void *token, int secret)
     {
       hd->kb = resource;
       hd->secret = !!secret;
+      hd->for_openpgp = for_openpgp;
       if (!resource->handle_table)
         {
           resource->handle_table_size = 3;
@@ -118,7 +114,7 @@ keybox_new (void *token, int secret)
           size_t newsize;
 
           newsize = resource->handle_table_size + 5;
-          tmptbl = xtryrealloc (resource->handle_table, 
+          tmptbl = xtryrealloc (resource->handle_table,
                                 newsize * sizeof (*tmptbl));
           if (!tmptbl)
             {
@@ -135,7 +131,31 @@ keybox_new (void *token, int secret)
   return hd;
 }
 
-void 
+
+/* Create a new handle for the resource associated with TOKEN.  SECRET
+   is just a cross-check.  This is the OpenPGP version.  The returned
+   handle must be released using keybox_release.  */
+KEYBOX_HANDLE
+keybox_new_openpgp (void *token, int secret)
+{
+  KB_NAME resource = token;
+
+  return do_keybox_new (resource, secret, 1);
+}
+
+/* Create a new handle for the resource associated with TOKEN.  SECRET
+   is just a cross-check.  This is the X.509 version.  The returned
+   handle must be released using keybox_release.  */
+KEYBOX_HANDLE
+keybox_new_x509 (void *token, int secret)
+{
+  KB_NAME resource = token;
+
+  return do_keybox_new (resource, secret, 0);
+}
+
+
+void
 keybox_release (KEYBOX_HANDLE hd)
 {
   if (!hd)
@@ -201,7 +221,7 @@ int
 keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes)
 {
   if (!hd)
-    return gpg_error (GPG_ERR_INV_HANDLE); 
+    return gpg_error (GPG_ERR_INV_HANDLE);
   hd->ephemeral = yes;
   return 0;
 }
@@ -210,7 +230,7 @@ keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes)
 /* Close the file of the resource identified by HD.  For consistent
    results this fucntion closes the files of all handles pointing to
    the resource identified by HD.  */
-void 
+void
 _keybox_close_file (KEYBOX_HANDLE hd)
 {
   int idx;
@@ -230,3 +250,20 @@ _keybox_close_file (KEYBOX_HANDLE hd)
       }
   assert (!hd->fp);
 }
+
+
+/*
+ * Lock the keybox at handle HD, or unlock if YES is false.  Note that
+ * we currently ignore the handle and lock all registered keyboxes.
+ */
+int
+keybox_lock (KEYBOX_HANDLE hd, int yes)
+{
+  /* FIXME: We need to implement it before we can use it with gpg.
+     gpgsm does the locking in its local keydb.c driver; this should
+     be changed as well.  */
+
+  (void)hd;
+  (void)yes;
+  return 0;
+}
index ebeef51..6ae6c44 100644 (file)
@@ -1,5 +1,5 @@
 /* keybox-openpgp.c - OpenPGP key parsing
- *     Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include "keybox-defs.h"
 
 #include <gcrypt.h>
-#include "../include/host2net.h"
-
-
-enum packet_types
-  {
-    PKT_NONE              =0,
-    PKT_PUBKEY_ENC        =1, /* public key encrypted packet */
-    PKT_SIGNATURE         =2, /* secret key encrypted packet */
-    PKT_SYMKEY_ENC        =3, /* session key packet (OpenPGP)*/
-    PKT_ONEPASS_SIG        =4, /* one pass sig packet (OpenPGP)*/
-    PKT_SECRET_KEY        =5, /* secret key */
-    PKT_PUBLIC_KEY        =6, /* public key */
-    PKT_SECRET_SUBKEY      =7, /* secret subkey (OpenPGP) */
-    PKT_COMPRESSED        =8, /* compressed data packet */
-    PKT_ENCRYPTED         =9, /* conventional encrypted data */
-    PKT_MARKER           =10, /* marker packet (OpenPGP) */
-    PKT_PLAINTEXT        =11, /* plaintext data with filename and mode */
-    PKT_RING_TRUST       =12, /* keyring trust packet */
-    PKT_USER_ID                  =13, /* user id packet */
-    PKT_PUBLIC_SUBKEY     =14, /* public subkey (OpenPGP) */
-    PKT_OLD_COMMENT       =16, /* comment packet from an OpenPGP draft */
-    PKT_ATTRIBUTE         =17, /* PGP's attribute packet */
-    PKT_ENCRYPTED_MDC     =18, /* integrity protected encrypted data */
-    PKT_MDC              =19, /* manipulation detection code packet */
-    PKT_COMMENT                  =61, /* new comment packet (private) */
-    PKT_GPG_CONTROL       =63  /* internal control packet */
-  };
 
+#include "../common/openpgpdefs.h"
 
 
 /* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
-   which is of amaximum length as stored at BUFLEN.  Return the header
+   which has a maximum length as stored at BUFLEN.  Return the header
    information of that packet and advance the pointer stored at BUFPTR
    to the next packet; also adjust the length stored at BUFLEN to
    match the remaining bytes. If there are no more packets, store NULL
    at BUFPTR.  Return an non-zero error code on failure or the
-   follwing data on success:
+   following data on success:
 
    R_DATAPKT = Pointer to the begin of the packet data.
    R_DATALEN = Length of this data.  This has already been checked to fit
@@ -120,8 +94,10 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
         {
           if (len <4 )
             return gpg_error (GPG_ERR_INV_PACKET); /* No length bytes. */
-          pktlen = buf32_to_ulong (buf);
-          buf += 4;
+          pktlen  = (*buf++) << 24;
+          pktlen |= (*buf++) << 16;
+          pktlen |= (*buf++) << 8;
+          pktlen |= (*buf++);
           len -= 4;
       }
       else /* Partial length encoding is not allowed for key packets. */
@@ -165,8 +141,8 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
       return gpg_error (GPG_ERR_UNEXPECTED);
     }
 
-  if (pktlen == 0xffffffff)
-      return gpg_error (GPG_ERR_INV_PACKET);
+  if (pktlen == (unsigned long)(-1))
+    return gpg_error (GPG_ERR_INV_PACKET);
 
   if (pktlen > len)
     return gpg_error (GPG_ERR_INV_PACKET); /* Packet length header too long. */
@@ -185,7 +161,7 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
 }
 
 
-/* Parse a key packet and store the ionformation in KI. */
+/* Parse a key packet and store the information in KI. */
 static gpg_error_t
 parse_key (const unsigned char *data, size_t datalen,
            struct _keybox_openpgp_key_info *ki)
@@ -194,12 +170,12 @@ parse_key (const unsigned char *data, size_t datalen,
   const unsigned char *data_start = data;
   int i, version, algorithm;
   size_t n;
-  /*unsigned long timestamp;*/
   int npkey;
   unsigned char hashbuffer[768];
   const unsigned char *mpi_n = NULL;
   size_t mpi_n_len = 0, mpi_e_len = 0;
   gcry_md_hd_t md;
+  int is_ecc = 0;
 
   if (datalen < 5)
     return gpg_error (GPG_ERR_INV_PACKET);
@@ -214,7 +190,7 @@ parse_key (const unsigned char *data, size_t datalen,
     {
       if (datalen < 2)
         return gpg_error (GPG_ERR_INV_PACKET);
-      data += 2; datalen -= 2;
+      data +=2; datalen -= 2;
     }
 
   if (!datalen)
@@ -223,42 +199,67 @@ parse_key (const unsigned char *data, size_t datalen,
 
   switch (algorithm)
     {
-    case 1:
-    case 2:
-    case 3: /* RSA */
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:
       npkey = 2;
       break;
-    case 16:
-    case 20: /* Elgamal */
+    case PUBKEY_ALGO_ELGAMAL_E:
+    case PUBKEY_ALGO_ELGAMAL:
       npkey = 3;
       break;
-    case 17: /* DSA */
+    case PUBKEY_ALGO_DSA:
       npkey = 4;
       break;
+    case PUBKEY_ALGO_ECDH:
+      npkey = 3;
+      is_ecc = 1;
+      break;
+    case PUBKEY_ALGO_ECDSA:
+    case PUBKEY_ALGO_EDDSA:
+      npkey = 2;
+      is_ecc = 1;
+      break;
     default: /* Unknown algorithm. */
       return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
     }
 
+  ki->algo = algorithm;
+
   for (i=0; i < npkey; i++ )
     {
       unsigned int nbits, nbytes;
 
       if (datalen < 2)
         return gpg_error (GPG_ERR_INV_PACKET);
-      nbits = ((data[0]<<8)|(data[1]));
-      data += 2; datalen -=2;
-      nbytes = (nbits+7) / 8;
-      if (datalen < nbytes)
-        return gpg_error (GPG_ERR_INV_PACKET);
-      /* For use by v3 fingerprint calculation we need to know the RSA
-         modulus and exponent. */
-      if (i==0)
+
+      if (is_ecc && (i == 0 || i == 2))
         {
-          mpi_n = data;
-          mpi_n_len = nbytes;
+          nbytes = data[0];
+          if (nbytes < 2 || nbytes > 254)
+            return gpg_error (GPG_ERR_INV_PACKET);
+          nbytes++; /* The size byte itself.  */
+          if (datalen < nbytes)
+            return gpg_error (GPG_ERR_INV_PACKET);
+        }
+      else
+        {
+          nbits = ((data[0]<<8)|(data[1]));
+          data += 2;
+          datalen -= 2;
+          nbytes = (nbits+7) / 8;
+          if (datalen < nbytes)
+            return gpg_error (GPG_ERR_INV_PACKET);
+          /* For use by v3 fingerprint calculation we need to know the RSA
+             modulus and exponent. */
+          if (i==0)
+            {
+              mpi_n = data;
+              mpi_n_len = nbytes;
+            }
+          else if (i==1)
+            mpi_e_len = nbytes;
         }
-      else if (i==1)
-        mpi_e_len = nbytes;
 
       data += nbytes; datalen -= nbytes;
     }
@@ -283,7 +284,7 @@ parse_key (const unsigned char *data, size_t datalen,
       if (mpi_n_len < 8)
         {
           /* Moduli less than 64 bit are out of the specs scope.  Zero
-             them out becuase this is what gpg does too. */
+             them out because this is what gpg does too. */
           memset (ki->keyid, 0, 8);
         }
       else
@@ -293,10 +294,10 @@ parse_key (const unsigned char *data, size_t datalen,
     {
       /* Its a pitty that we need to prefix the buffer with the tag
          and a length header: We can't simply pass it to the fast
-         hashing fucntion for that reason.  It might be a good idea to
+         hashing function for that reason.  It might be a good idea to
          have a scatter-gather enabled hash function. What we do here
          is to use a static buffer if this one is large enough and
-         only use the regular hash fucntions if this buffer is not
+         only use the regular hash functions if this buffer is not
          large enough. */
       if ( 3 + n < sizeof hashbuffer )
         {
@@ -330,19 +331,19 @@ parse_key (const unsigned char *data, size_t datalen,
 /* The caller must pass the address of an INFO structure which will
    get filled on success with information pertaining to the OpenPGP
    keyblock IMAGE of length IMAGELEN.  Note that a caller does only
-   need to release this INFO structure when the function returns
+   need to release this INFO structure if the function returns
    success.  If NPARSED is not NULL the actual number of bytes parsed
    will be stored at this address.  */
 gpg_error_t
 _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
-                       size_t *nparsed,
-                       keybox_openpgp_info_t info)
+                       size_t *nparsed, keybox_openpgp_info_t info)
 {
   gpg_error_t err = 0;
   const unsigned char *image_start, *data;
   size_t n, datalen;
   int pkttype;
   int first = 1;
+  int read_error = 0;
   struct _keybox_openpgp_key_info *k, **ktail = NULL;
   struct _keybox_openpgp_uid_info *u, **utail = NULL;
 
@@ -355,7 +356,10 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
     {
       err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n);
       if (err)
-        break;
+        {
+          read_error = 1;
+          break;
+        }
 
       if (first)
         {
@@ -366,6 +370,8 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
           else
             {
               err = gpg_error (GPG_ERR_UNEXPECTED);
+              if (nparsed)
+                *nparsed += n;
               break;
             }
           first = 0;
@@ -425,9 +431,12 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
               if (err)
                 {
                   info->nsubkeys--;
-                  if (gpg_err_code (err) != GPG_ERR_UNKNOWN_ALGORITHM)
-                    break;
                   /* We ignore subkeys with unknown algorithms. */
+                  if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
+                      || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
+                    err = 0;
+                  if (err)
+                    break;
                 }
               else
                 ktail = &info->subkeys.next;
@@ -445,9 +454,12 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
                 {
                   xfree (k);
                   info->nsubkeys--;
-                  if (gpg_err_code (err) != GPG_ERR_UNKNOWN_ALGORITHM)
-                    break;
                   /* We ignore subkeys with unknown algorithms. */
+                  if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
+                      || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
+                    err = 0;
+                  if (err)
+                    break;
                 }
               else
                 {
@@ -461,11 +473,10 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
   if (err)
     {
       _keybox_destroy_openpgp_info (info);
-      if (!first
-          && (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
-              || gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM))
+      if (!read_error)
         {
-          /* We are able to skip to the end of this keyblock. */
+          /* Packet parsing worked, thus we should be able to skip the
+             rest of the keyblock.  */
           while (image)
             {
               if (next_packet (&image, &imagelen,
index 98d8135..ec7a3c1 100644 (file)
@@ -17,7 +17,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-/* 
+/*
    This file is a temporary kludge until we can come up with solution
    to share this description between keybox and the application
    specific keydb
@@ -48,24 +48,31 @@ typedef enum {
   KEYDB_SEARCH_MODE_NEXT
 } KeydbSearchMode;
 
-struct keydb_search_desc {
+
+/* Forwward declaration.  See g10/packet.h.  */
+struct gpg_pkt_user_id_s;
+typedef struct gpg_pkt_user_id_s *gpg_pkt_user_id_t;
+
+/* A search descriptor.  */
+struct keydb_search_desc
+{
   KeydbSearchMode mode;
-  int (*skipfnc)(void *,void*); /* used to be: void*, u32* */
+  int (*skipfnc)(void *, u32 *, gpg_pkt_user_id_t);
   void *skipfncvalue;
-  const unsigned char *sn; 
+  const unsigned char *sn;
   int snlen;  /* -1 := sn is a hex string */
   union {
     const char *name;
     unsigned char fpr[24];
-    unsigned char kid[8]; 
+    u32 kid[2]; /* Note that this is in native endianess.  */
     unsigned char grip[20];
   } u;
+  int exact;    /* Use exactly this key ('!' suffix in gpg).  */
 };
 
 
 struct keydb_search_desc;
 typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
-
 typedef struct keydb_search_desc KEYBOX_SEARCH_DESC;
 
 
index 4b013ce..10a71c4 100644 (file)
@@ -1,5 +1,6 @@
 /* keybox-search.c - Search operations
- * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2004, 2012,
+ *               2013 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -24,8 +25,7 @@
 #include <assert.h>
 #include <errno.h>
 
-#include "../jnlib/stringhelp.h" /* ascii_xxxx() */
-#include "../include/host2net.h"
+#include "../common/stringhelp.h" /* ascii_xxxx() */
 
 #include "keybox-defs.h"
 #include <gcrypt.h>
@@ -46,30 +46,25 @@ struct sn_array_s {
 static inline ulong
 get32 (const byte *buffer)
 {
-  return buf32_to_ulong (buffer);
+  ulong a;
+  a =  *buffer << 24;
+  a |= buffer[1] << 16;
+  a |= buffer[2] << 8;
+  a |= buffer[3];
+  return a;
 }
 
 static inline ulong
 get16 (const byte *buffer)
 {
-  return buf16_to_ulong (buffer);
+  ulong a;
+  a =  *buffer << 8;
+  a |= buffer[1];
+  return a;
 }
 
 
 
-static inline int
-blob_get_type (KEYBOXBLOB blob)
-{
-  const unsigned char *buffer;
-  size_t length;
-
-  buffer = _keybox_get_blob_image (blob, &length);
-  if (length < 32)
-    return -1; /* blob too short */
-
-  return buffer[4];
-}
-
 static inline unsigned int
 blob_get_blob_flags (KEYBOXBLOB blob)
 {
@@ -95,7 +90,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length,
   size_t nkeys, keyinfolen;
   size_t nuids, uidinfolen;
   size_t nserial;
-  size_t nsigs, siginfolen;
+  size_t nsigs, siginfolen, siginfooff;
 
   switch (what)
     {
@@ -109,6 +104,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length,
     case KEYBOX_FLAG_OWNERTRUST:
     case KEYBOX_FLAG_VALIDITY:
     case KEYBOX_FLAG_CREATED_AT:
+    case KEYBOX_FLAG_SIG_INFO:
       if (length < 20)
         return GPG_ERR_INV_OBJ;
       /* Key info. */
@@ -133,6 +129,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length,
       if (pos+4 > length)
         return GPG_ERR_INV_OBJ ; /* Out of bounds. */
       /* Signature info. */
+      siginfooff = pos;
       nsigs = get16 (buffer + pos); pos += 2;
       siginfolen = get16 (buffer + pos); pos += 2;
       if (siginfolen < 4 )
@@ -151,6 +148,10 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length,
           *flag_size = 4;
           *flag_off += 1+2+4+4+4;
           break;
+        case KEYBOX_FLAG_SIG_INFO:
+          *flag_size = siginfolen * nsigs;
+          *flag_off = siginfooff;
+          break;
         default:
           break;
         }
@@ -220,6 +221,9 @@ blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
 }
 
 
+/* Returns 0 if not found or the number of the key which was found.
+   For X.509 this is always 1, for OpenPGP this is 1 for the primary
+   key and 2 and more for the subkeys.  */
 static int
 blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
 {
@@ -246,7 +250,7 @@ blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
     {
       off = pos + idx*keyinfolen;
       if (!memcmp (buffer + off, fpr, 20))
-        return 1; /* found */
+        return idx+1; /* found */
     }
   return 0; /* not found */
 }
@@ -278,7 +282,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
     {
       off = pos + idx*keyinfolen;
       if (!memcmp (buffer + off + fproff, fpr, fprlen))
-        return 1; /* found */
+        return idx+1; /* found */
     }
   return 0; /* not found */
 }
@@ -286,7 +290,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
 
 static int
 blob_cmp_name (KEYBOXBLOB blob, int idx,
-               const char *name, size_t namelen, int substr)
+               const char *name, size_t namelen, int substr, int x509)
 {
   const unsigned char *buffer;
   size_t length;
@@ -323,10 +327,9 @@ blob_cmp_name (KEYBOXBLOB blob, int idx,
     return 0; /* out of bounds */
 
   if (idx < 0)
-    { /* compare all names starting with that (negated) index */
-      idx = -idx;
-
-      for ( ;idx < nuids; idx++)
+    { /* Compare all names.  Note that for X.509 we start with index 1
+         so to skip the issuer at index 0.  */
+      for (idx = !!x509; idx < nuids; idx++)
         {
           size_t mypos = pos;
 
@@ -340,15 +343,14 @@ blob_cmp_name (KEYBOXBLOB blob, int idx,
           if (substr)
             {
               if (ascii_memcasemem (buffer+off, len, name, namelen))
-                return 1; /* found */
+                return idx+1; /* found */
             }
           else
             {
               if (len == namelen && !memcmp (buffer+off, name, len))
-                return 1; /* found */
+                return idx+1; /* found */
             }
         }
-      return 0; /* not found */
     }
   else
     {
@@ -364,20 +366,25 @@ blob_cmp_name (KEYBOXBLOB blob, int idx,
 
       if (substr)
         {
-          return !!ascii_memcasemem (buffer+off, len, name, namelen);
+          if (ascii_memcasemem (buffer+off, len, name, namelen))
+            return idx+1; /* found */
         }
       else
         {
-          return len == namelen && !memcmp (buffer+off, name, len);
+          if (len == namelen && !memcmp (buffer+off, name, len))
+            return idx+1; /* found */
         }
     }
+  return 0; /* not found */
 }
 
 
-/* compare all email addresses of the subject.  With SUBSTR given as
-   True a substring search is done in the mail address */
+/* Compare all email addresses of the subject.  With SUBSTR given as
+   True a substring search is done in the mail address.  If X509
+   states whether thr search is done on an X.509 blob.  */
 static int
-blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr)
+blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr,
+               int x509)
 {
   const unsigned char *buffer;
   size_t length;
@@ -418,7 +425,9 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr)
   if (namelen < 1)
     return 0;
 
-  for (idx=1 ;idx < nuids; idx++)
+  /* Note that for X.509 we start at index 1 becuase index 0 is used
+     for the issuer name.  */
+  for (idx=!!x509 ;idx < nuids; idx++)
     {
       size_t mypos = pos;
 
@@ -427,6 +436,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr)
       len = get32 (buffer+mypos+4);
       if (off+len > length)
         return 0; /* error: better stop here out of bounds */
+      if (!x509)
+        {
+          /* For OpenPGP we need to forward to the mailbox part.  */
+          for ( ;len && buffer[off] != '<'; len--, off++)
+            ;
+        }
       if (len < 2 || buffer[off] != '<')
         continue; /* empty name or trailing 0 not stored */
       len--; /* one back */
@@ -436,12 +451,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr)
       if (substr)
         {
           if (ascii_memcasemem (buffer+off+1, len, name, namelen))
-            return 1; /* found */
+            return idx+1; /* found */
         }
       else
         {
           if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len))
-            return 1; /* found */
+            return idx+1; /* found */
         }
     }
   return 0; /* not found */
@@ -523,15 +538,29 @@ blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
   The has_foo functions are used as helpers for search
 */
 static inline int
-has_short_kid (KEYBOXBLOB blob, const unsigned char *kid)
+has_short_kid (KEYBOXBLOB blob, u32 lkid)
 {
-  return blob_cmp_fpr_part (blob, kid+4, 16, 4);
+  unsigned char buf[4];
+  buf[0] = lkid >> 24;
+  buf[1] = lkid >> 16;
+  buf[2] = lkid >> 8;
+  buf[3] = lkid;
+  return blob_cmp_fpr_part (blob, buf, 16, 4);
 }
 
 static inline int
-has_long_kid (KEYBOXBLOB blob, const unsigned char *kid)
+has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid)
 {
-  return blob_cmp_fpr_part (blob, kid, 12, 8);
+  unsigned char buf[8];
+  buf[0] = mkid >> 24;
+  buf[1] = mkid >> 16;
+  buf[2] = mkid >> 8;
+  buf[3] = mkid;
+  buf[4] = lkid >> 24;
+  buf[5] = lkid >> 16;
+  buf[6] = lkid >> 8;
+  buf[7] = lkid;
+  return blob_cmp_fpr_part (blob, buf, 12, 8);
 }
 
 static inline int
@@ -544,7 +573,7 @@ static inline int
 has_keygrip (KEYBOXBLOB blob, const unsigned char *grip)
 {
 #ifdef KEYBOX_WITH_X509
-  if (blob_get_type (blob) == BLOBTYPE_X509)
+  if (blob_get_type (blob) == KEYBOX_BLOBTYPE_X509)
     return blob_x509_has_grip (blob, grip);
 #endif
   return 0;
@@ -558,11 +587,11 @@ has_issuer (KEYBOXBLOB blob, const char *name)
 
   return_val_if_fail (name, 0);
 
-  if (blob_get_type (blob) != BLOBTYPE_X509)
+  if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
     return 0;
 
   namelen = strlen (name);
-  return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0);
+  return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1);
 }
 
 static inline int
@@ -574,13 +603,13 @@ has_issuer_sn (KEYBOXBLOB blob, const char *name,
   return_val_if_fail (name, 0);
   return_val_if_fail (sn, 0);
 
-  if (blob_get_type (blob) != BLOBTYPE_X509)
+  if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
     return 0;
 
   namelen = strlen (name);
 
   return (blob_cmp_sn (blob, sn, snlen)
-          && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0));
+          && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1));
 }
 
 static inline int
@@ -588,7 +617,7 @@ has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
 {
   return_val_if_fail (sn, 0);
 
-  if (blob_get_type (blob) != BLOBTYPE_X509)
+  if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
     return 0;
   return blob_cmp_sn (blob, sn, snlen);
 }
@@ -600,26 +629,29 @@ has_subject (KEYBOXBLOB blob, const char *name)
 
   return_val_if_fail (name, 0);
 
-  if (blob_get_type (blob) != BLOBTYPE_X509)
+  if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
     return 0;
 
   namelen = strlen (name);
-  return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0);
+  return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1);
 }
 
+
 static inline int
-has_subject_or_alt (KEYBOXBLOB blob, const char *name, int substr)
+has_username (KEYBOXBLOB blob, const char *name, int substr)
 {
   size_t namelen;
+  int btype;
 
   return_val_if_fail (name, 0);
 
-  if (blob_get_type (blob) != BLOBTYPE_X509)
+  btype = blob_get_type (blob);
+  if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
     return 0;
 
   namelen = strlen (name);
-  return blob_cmp_name (blob, -1 /* all subject names*/, name,
-                        namelen, substr);
+  return blob_cmp_name (blob, -1 /* all subject/user names */, name,
+                        namelen, substr, (btype == KEYBOX_BLOBTYPE_X509));
 }
 
 
@@ -627,16 +659,22 @@ static inline int
 has_mail (KEYBOXBLOB blob, const char *name, int substr)
 {
   size_t namelen;
+  int btype;
 
   return_val_if_fail (name, 0);
 
-  if (blob_get_type (blob) != BLOBTYPE_X509)
+  btype = blob_get_type (blob);
+  if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
     return 0;
 
+  if (btype == KEYBOX_BLOBTYPE_PGP && *name == '<')
+    name++; /* Hack to remove the leading '<' for gpg.  */
+
   namelen = strlen (name);
   if (namelen && name[namelen-1] == '>')
     namelen--;
-  return blob_cmp_mail (blob, name, namelen, substr);
+  return blob_cmp_mail (blob, name, namelen, substr,
+                        (btype == KEYBOX_BLOBTYPE_X509));
 }
 
 
@@ -681,15 +719,21 @@ keybox_search_reset (KEYBOX_HANDLE hd)
 
 
 /* Note: When in ephemeral mode the search function does visit all
-   blobs but in standard mode, blobs flagged as ephemeral are ignored.  */
+   blobs but in standard mode, blobs flagged as ephemeral are ignored.
+   If WANT_BLOBTYPE is not 0 only blobs of this type are considered.
+   The value at R_SKIPPED is updated by the number of skipped long
+   records (counts PGP and X.509). */
 int
-keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
+keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
+               keybox_blobtype_t want_blobtype,
+               size_t *r_descindex, unsigned long *r_skipped)
 {
   int rc;
   size_t n;
   int need_words, any_skip;
   KEYBOXBLOB blob = NULL;
   struct sn_array_s *sn_array = NULL;
+  int pk_no, uid_no;
 
   if (!hd)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -806,18 +850,29 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
     }
 
 
+  pk_no = uid_no = 0;
   for (;;)
     {
       unsigned int blobflags;
+      int blobtype;
 
       _keybox_release_blob (blob); blob = NULL;
       rc = _keybox_read_blob (&blob, hd->fp);
+      if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
+          && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
+        {
+          ++*r_skipped;
+          continue; /* Skip too large records.  */
+        }
+
       if (rc)
         break;
 
-      if (blob_get_type (blob) == BLOBTYPE_HEADER)
+      blobtype = blob_get_type (blob);
+      if (blobtype == KEYBOX_BLOBTYPE_HEADER)
+        continue;
+      if (want_blobtype && blobtype != want_blobtype)
         continue;
-
 
       blobflags = blob_get_blob_flags (blob);
       if (!hd->ephemeral && (blobflags & 2))
@@ -831,19 +886,23 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
               never_reached ();
               break;
             case KEYDB_SEARCH_MODE_EXACT:
-              if (has_subject_or_alt (blob, desc[n].u.name, 0))
+              uid_no = has_username (blob, desc[n].u.name, 0);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_MAIL:
-              if (has_mail (blob, desc[n].u.name, 0))
+              uid_no = has_mail (blob, desc[n].u.name, 0);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_MAILSUB:
-              if (has_mail (blob, desc[n].u.name, 1))
+              uid_no = has_mail (blob, desc[n].u.name, 1);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_SUBSTR:
-              if (has_subject_or_alt (blob, desc[n].u.name, 1))
+              uid_no =  has_username (blob, desc[n].u.name, 1);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_MAILEND:
@@ -870,16 +929,19 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_SHORT_KID:
-              if (has_short_kid (blob, desc[n].u.kid))
+              pk_no = has_short_kid (blob, desc[n].u.kid[1]);
+              if (pk_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_LONG_KID:
-              if (has_long_kid (blob, desc[n].u.kid))
+              pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]);
+              if (pk_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_FPR:
             case KEYDB_SEARCH_MODE_FPR20:
-              if (has_fingerprint (blob, desc[n].u.fpr))
+              pk_no = has_fingerprint (blob, desc[n].u.fpr);
+              if (pk_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_KEYGRIP:
@@ -899,10 +961,14 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
        }
       continue;
     found:
+      /* Record which DESC we matched on.  Note this value is only
+        meaningful if this function returns with no errors. */
+      if(r_descindex)
+       *r_descindex = n;
       for (n=any_skip?0:ndesc; n < ndesc; n++)
         {
 /*            if (desc[n].skipfnc */
-/*                && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */
+/*                && desc[n].skipfnc (desc[n].skipfncvalue, aki, NULL)) */
 /*              break; */
         }
       if (n == ndesc)
@@ -912,6 +978,8 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
   if (!rc)
     {
       hd->found.blob = blob;
+      hd->found.pk_no = pk_no;
+      hd->found.uid_no = uid_no;
     }
   else if (rc == -1)
     {
@@ -937,6 +1005,65 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
    Functions to return a certificate or a keyblock.  To be used after
    a successful search operation.
 */
+
+
+/* Return the last found keyblock.  Returns 0 on success and stores a
+   new iobuf at R_IOBUF and a signature status vector at R_SIGSTATUS
+   in that case.  R_UID_NO and R_PK_NO are used to retun the number of
+   the key or user id which was matched the search criteria; if not
+   known they are set to 0. */
+gpg_error_t
+keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
+                     int *r_pk_no, int *r_uid_no, u32 **r_sigstatus)
+{
+  gpg_error_t err;
+  const unsigned char *buffer, *p;
+  size_t length;
+  size_t image_off, image_len;
+  size_t siginfo_off, siginfo_len;
+  u32 *sigstatus, n, n_sigs, sigilen;
+
+  *r_iobuf = NULL;
+  *r_sigstatus = NULL;
+
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!hd->found.blob)
+    return gpg_error (GPG_ERR_NOTHING_FOUND);
+
+  if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP)
+    return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
+
+  buffer = _keybox_get_blob_image (hd->found.blob, &length);
+  if (length < 40)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+  image_off = get32 (buffer+8);
+  image_len = get32 (buffer+12);
+  if (image_off+image_len > length)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+
+  err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO,
+                                   &siginfo_off, &siginfo_len);
+  if (err)
+    return err;
+  n_sigs  = get16 (buffer + siginfo_off);
+  sigilen = get16 (buffer + siginfo_off + 2);
+  p = buffer + siginfo_off + 4;
+  sigstatus = xtrymalloc ((1+n_sigs) * sizeof *sigstatus);
+  if (!sigstatus)
+    return gpg_error_from_syserror ();
+  sigstatus[0] = n_sigs;
+  for (n=1; n <= n_sigs; n++, p += sigilen)
+    sigstatus[n] = get32 (p);
+
+  *r_pk_no  = hd->found.pk_no;
+  *r_uid_no = hd->found.uid_no;
+  *r_sigstatus = sigstatus;
+  *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len);
+  return 0;
+}
+
+
 #ifdef KEYBOX_WITH_X509
 /*
   Return the last found cert.  Caller must free it.
@@ -956,7 +1083,7 @@ keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert)
   if (!hd->found.blob)
     return gpg_error (GPG_ERR_NOTHING_FOUND);
 
-  if (blob_get_type (hd->found.blob) != BLOBTYPE_X509)
+  if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_X509)
     return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
 
   buffer = _keybox_get_blob_image (hd->found.blob, &length);
@@ -1021,4 +1148,3 @@ keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value)
   ec = get_flag_from_image (buffer, length, what, value);
   return ec? gpg_error (ec):0;
 }
-
index 75464cf..11861ac 100644 (file)
@@ -1,5 +1,5 @@
 /* keybox-update.c - keybox update operations
- *     Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2012 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <errno.h>
 #include <time.h>
 #include <unistd.h>
+#include <assert.h>
 
 #include "keybox-defs.h"
-#include "../include/host2net.h"
+#include "../common/sysutils.h"
 
 #define EXTSEP_S "."
 
+#define FILECOPY_INSERT 1
+#define FILECOPY_DELETE 2
+#define FILECOPY_UPDATE 3
+
 
 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
 
@@ -159,7 +164,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
 /*      { */
 /*        if (chmod (tmpfname, S_IRUSR | S_IWUSR) )  */
 /*          { */
-/*            log_debug ("chmod of `%s' failed: %s\n", */
+/*            log_debug ("chmod of '%s' failed: %s\n", */
 /*                       tmpfname, strerror(errno) ); */
 /*            return KEYBOX_Write_File; */
 /*     } */
@@ -167,15 +172,15 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
 #endif
 
   /* fixme: invalidate close caches (not used with stdio)*/
-/*    iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); */
-/*    iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); */
-/*    iobuf_ioctl (NULL, 2, 0, (char*)fname ); */
+/*    iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)tmpfname ); */
+/*    iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)bakfname ); */
+/*    iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname ); */
 
   /* First make a backup file except for secret keyboxes. */
   if (!secret)
     {
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-      remove (bakfname);
+      gnupg_remove (bakfname);
 #endif
       if (rename (fname, bakfname) )
         {
@@ -185,7 +190,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
 
   /* Then rename the file. */
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-  remove (fname);
+  gnupg_remove (fname);
 #endif
   if (rename (tmpfname, fname) )
     {
@@ -206,20 +211,18 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
 
 
 
-/* Perform insert/delete/update operation.
-    mode 1 = insert
-        2 = delete
-        3 = update
-*/
+/* Perform insert/delete/update operation.  MODE is one of
+   FILECOPY_INSERT, FILECOPY_DELETE, FILECOPY_UPDATE.  FOR_OPENPGP
+   indicates that this is called due to an OpenPGP keyblock change.  */
 static int
 blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
-               int secret, off_t start_offset)
+               int secret, int for_openpgp, off_t start_offset)
 {
   FILE *fp, *newfp;
   int rc=0;
   char *bakfname = NULL;
   char *tmpfname = NULL;
-  char buffer[4096];
+  char buffer[4096];  /* (Must be at least 32 bytes) */
   int nread, nbytes;
 
   /* Open the source file. Because we do a rename, we have to check the
@@ -228,7 +231,7 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
     return gpg_error_from_syserror ();
 
   fp = fopen (fname, "rb");
-  if (mode == 1 && !fp && errno == ENOENT)
+  if (mode == FILECOPY_INSERT && !fp && errno == ENOENT)
     {
       /* Insert mode but file does not exist:
          Create a new keybox file. */
@@ -236,19 +239,13 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
       if (!newfp )
         return gpg_error_from_syserror ();
 
-      rc = _keybox_write_header_blob (newfp);
+      rc = _keybox_write_header_blob (newfp, for_openpgp);
       if (rc)
-        {
-          fclose (newfp);
-          return rc;
-        }
+        return rc;
 
       rc = _keybox_write_blob (blob, newfp);
       if (rc)
-        {
-          fclose (newfp);
-          return rc;
-        }
+        return rc;
 
       if ( fclose (newfp) )
         return gpg_error_from_syserror ();
@@ -271,36 +268,42 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
   rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
   if (rc)
     {
-      fclose (fp);
-      fclose (newfp);
+      fclose(fp);
       goto leave;
     }
 
   /* prepare for insert */
-  if (mode == 1)
+  if (mode == FILECOPY_INSERT)
     {
-      /* Copy everything to the new file. */
+      int first_record = 1;
+
+      /* Copy everything to the new file.  If this is for OpenPGP, we
+         make sure that the openpgp flag is set in the header.  (We
+         failsafe the blob type.) */
       while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 )
         {
+          if (first_record && for_openpgp
+              && buffer[4] == KEYBOX_BLOBTYPE_HEADER)
+            {
+              first_record = 0;
+              buffer[7] |= 0x02; /* OpenPGP data may be available.  */
+            }
+
           if (fwrite (buffer, nread, 1, newfp) != 1)
             {
               rc = gpg_error_from_syserror ();
-              fclose (fp);
-              fclose (newfp);
               goto leave;
             }
         }
       if (ferror (fp))
         {
           rc = gpg_error_from_syserror ();
-          fclose (fp);
-          fclose (newfp);
           goto leave;
         }
     }
 
   /* Prepare for delete or update. */
-  if ( mode == 2 || mode == 3 )
+  if ( mode == FILECOPY_DELETE || mode == FILECOPY_UPDATE )
     {
       off_t current = 0;
 
@@ -318,59 +321,43 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
           if (fwrite (buffer, nread, 1, newfp) != 1)
             {
               rc = gpg_error_from_syserror ();
-              fclose (fp);
-              fclose (newfp);
               goto leave;
             }
         }
       if (ferror (fp))
         {
           rc = gpg_error_from_syserror ();
-          fclose (fp);
-          fclose (newfp);
           goto leave;
         }
 
       /* Skip this blob. */
       rc = _keybox_read_blob (NULL, fp);
       if (rc)
-        {
-          fclose (fp);
-          fclose (newfp);
-          return rc;
-        }
+        return rc;
     }
 
   /* Do an insert or update. */
-  if ( mode == 1 || mode == 3 )
+  if ( mode == FILECOPY_INSERT || mode == FILECOPY_UPDATE )
     {
       rc = _keybox_write_blob (blob, newfp);
       if (rc)
-        {
-          fclose (fp);
-          fclose (newfp);
           return rc;
-        }
     }
 
   /* Copy the rest of the packet for an delete or update. */
-  if (mode == 2 || mode == 3)
+  if (mode == FILECOPY_DELETE || mode == FILECOPY_UPDATE)
     {
       while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 )
         {
           if (fwrite (buffer, nread, 1, newfp) != 1)
             {
               rc = gpg_error_from_syserror ();
-              fclose (fp);
-              fclose (newfp);
               goto leave;
             }
         }
       if (ferror (fp))
         {
           rc = gpg_error_from_syserror ();
-          fclose (fp);
-          fclose (newfp);
           goto leave;
         }
     }
@@ -397,6 +384,102 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
 }
 
 
+/* Insert the OpenPGP keyblock {IMAGE,IMAGELEN} into HD.  SIGSTATUS is
+   a vector describing the status of the signatures; its first element
+   gives the number of following elements.  */
+gpg_error_t
+keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen,
+                        u32 *sigstatus)
+{
+  gpg_error_t err;
+  const char *fname;
+  KEYBOXBLOB blob;
+  size_t nparsed;
+  struct _keybox_openpgp_info info;
+
+  if (!hd)
+    return gpg_error (GPG_ERR_INV_HANDLE);
+  if (!hd->kb)
+    return gpg_error (GPG_ERR_INV_HANDLE);
+  fname = hd->kb->fname;
+  if (!fname)
+    return gpg_error (GPG_ERR_INV_HANDLE);
+
+
+  /* Close this one otherwise we will mess up the position for a next
+     search.  Fixme: it would be better to adjust the position after
+     the write operation.  */
+  _keybox_close_file (hd);
+
+  err = _keybox_parse_openpgp (image, imagelen, &nparsed, &info);
+  if (err)
+    return err;
+  assert (nparsed <= imagelen);
+  err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen,
+                                     sigstatus, hd->ephemeral);
+  _keybox_destroy_openpgp_info (&info);
+  if (!err)
+    {
+      err = blob_filecopy (FILECOPY_INSERT, fname, blob, hd->secret, 1, 0);
+      _keybox_release_blob (blob);
+      /*    if (!rc && !hd->secret && kb_offtbl) */
+      /*      { */
+      /*        update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */
+      /*      } */
+    }
+  return err;
+}
+
+
+/* Update the current key at HD with the given OpenPGP keyblock in
+   {IMAGE,IMAGELEN}.  */
+gpg_error_t
+keybox_update_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen)
+{
+  gpg_error_t err;
+  const char *fname;
+  off_t off;
+  KEYBOXBLOB blob;
+  size_t nparsed;
+  struct _keybox_openpgp_info info;
+
+  if (!hd || !image || !imagelen)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!hd->found.blob)
+    return gpg_error (GPG_ERR_NOTHING_FOUND);
+  if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP)
+    return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
+  fname = hd->kb->fname;
+  if (!fname)
+    return gpg_error (GPG_ERR_INV_HANDLE);
+
+  off = _keybox_get_blob_fileoffset (hd->found.blob);
+  if (off == (off_t)-1)
+    return gpg_error (GPG_ERR_GENERAL);
+
+  /* Close this the file so that we do no mess up the position for a
+     next search.  */
+  _keybox_close_file (hd);
+
+  /* Build a new blob.  */
+  err = _keybox_parse_openpgp (image, imagelen, &nparsed, &info);
+  if (err)
+    return err;
+  assert (nparsed <= imagelen);
+  err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen,
+                                     NULL, hd->ephemeral);
+  _keybox_destroy_openpgp_info (&info);
+
+  /* Update the keyblock.  */
+  if (!err)
+    {
+      err = blob_filecopy (FILECOPY_UPDATE, fname, blob, hd->secret, 1, off);
+      _keybox_release_blob (blob);
+    }
+  return err;
+}
+
+
 
 #ifdef KEYBOX_WITH_X509
 int
@@ -423,7 +506,7 @@ keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
   rc = _keybox_create_x509_blob (&blob, cert, sha1_digest, hd->ephemeral);
   if (!rc)
     {
-      rc = blob_filecopy (1, fname, blob, hd->secret, 0);
+      rc = blob_filecopy (FILECOPY_INSERT, fname, blob, hd->secret, 0, 0);
       _keybox_release_blob (blob);
       /*    if (!rc && !hd->secret && kb_offtbl) */
       /*      { */
@@ -622,9 +705,10 @@ keybox_compress (KEYBOX_HANDLE hd)
       size_t length;
 
       buffer = _keybox_get_blob_image (blob, &length);
-      if (length > 4 && buffer[4] == BLOBTYPE_HEADER)
+      if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER)
         {
-          u32 last_maint = buf32_to_u32 (buffer+20);
+          u32 last_maint = ((buffer[20] << 24) | (buffer[20+1] << 16)
+                            | (buffer[20+2] << 8) | (buffer[20+3]));
 
           if ( (last_maint + 3*3600) > time (NULL) )
             {
@@ -634,14 +718,15 @@ keybox_compress (KEYBOX_HANDLE hd)
             }
         }
       _keybox_release_blob (blob);
-      rewind (fp);
+      fseek (fp, 0, SEEK_SET);
+      clearerr (fp);
     }
 
   /* Create the new file. */
   rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
   if (rc)
     {
-      fclose (fp);
+      fclose(fp);
       return rc;;
     }
 
@@ -667,10 +752,12 @@ keybox_compress (KEYBOX_HANDLE hd)
       if (first_blob)
         {
           first_blob = 0;
-          if (length > 4 && buffer[4] == BLOBTYPE_HEADER)
+          if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER)
             {
-              /* Write out the blob with an updated maintenance time stamp. */
-              _keybox_update_header_blob (blob);
+              /* Write out the blob with an updated maintenance time
+                 stamp and if needed (ie. used by gpg) set the openpgp
+                 flag.  */
+              _keybox_update_header_blob (blob, hd->for_openpgp);
               rc = _keybox_write_blob (blob, newfp);
               if (rc)
                 break;
@@ -678,12 +765,12 @@ keybox_compress (KEYBOX_HANDLE hd)
             }
 
           /* The header blob is missing.  Insert it.  */
-          rc = _keybox_write_header_blob (newfp);
+          rc = _keybox_write_header_blob (newfp, hd->for_openpgp);
           if (rc)
             break;
           any_changes = 1;
         }
-      else if (length > 4 && buffer[4] == BLOBTYPE_HEADER)
+      else if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER)
         {
           /* Oops: There is another header record - remove it. */
           any_changes = 1;
@@ -697,7 +784,7 @@ keybox_compress (KEYBOX_HANDLE hd)
           rc = gpg_error (GPG_ERR_BUG);
           break;
         }
-      blobflags = buf16_to_uint (buffer+pos);
+      blobflags = ((buffer[pos] << 8) | (buffer[pos+1]));
       if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
         {
           /* This is an ephemeral blob. */
@@ -706,7 +793,8 @@ keybox_compress (KEYBOX_HANDLE hd)
               || size != 4)
             created_at = 0; /* oops. */
           else
-            created_at = buf32_to_u32 (buffer+pos);
+            created_at = ((buffer[pos] << 24) | (buffer[pos+1] << 16)
+                          | (buffer[pos+2] << 8) | (buffer[pos+3]));
 
           if (created_at && created_at < cut_time)
             {
@@ -735,7 +823,7 @@ keybox_compress (KEYBOX_HANDLE hd)
 
   /* Rename or remove the temporary file. */
   if (rc || !any_changes)
-    remove (tmpfname);
+    gnupg_remove (tmpfname);
   else
     rc = rename_tmp_file (bakfname, tmpfname, fname, hd->secret);
 
@@ -743,4 +831,3 @@ keybox_compress (KEYBOX_HANDLE hd)
   xfree(tmpfname);
   return rc;
 }
-
index 84de504..9fe9290 100644 (file)
@@ -1,4 +1,4 @@
-/* keybox-util.c - Utility functions for Keybox 
+/* keybox-util.c - Utility functions for Keybox
  *     Copyright (C) 2001 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
@@ -68,4 +68,3 @@ _keybox_free (void *p)
   if (p)
     free_func (p);
 }
-
index e0d8c53..386fff1 100644 (file)
@@ -1,5 +1,5 @@
 /* keybox.h - Keybox operations
- *     Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2012 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #ifndef KEYBOX_H
 #define KEYBOX_H 1
 #ifdef __cplusplus
-extern "C" { 
+extern "C" {
 #if 0
  }
 #endif
 #endif
 
+#include "../common/iobuf.h"
 #include "keybox-search-desc.h"
 
-#define KEYBOX_WITH_OPENPGP 1 
 #define KEYBOX_WITH_X509 1
 
 
-#ifdef KEYBOX_WITH_OPENPGP
-#  undef KEYBOX_WITH_OPENPGP
-/*#include <lib-to-handle-gpg-data-structs.h>*/
-#endif
-
 #ifdef KEYBOX_WITH_X509
 # include <ksba.h>
 #endif
@@ -53,39 +48,65 @@ typedef enum
     KEYBOX_FLAG_UID,        /* The user ID flags; requires an uid index. */
     KEYBOX_FLAG_UID_VALIDITY,/* The validity of a specific uid, requires
                                an uid index. */
-    KEYBOX_FLAG_CREATED_AT  /* The date the block was created. */
+    KEYBOX_FLAG_CREATED_AT, /* The date the block was created. */
+    KEYBOX_FLAG_SIG_INFO,   /* The signature info block.  */
   } keybox_flag_t;
 
 /* Flag values used with KEYBOX_FLAG_BLOB.  */
 #define KEYBOX_FLAG_BLOB_SECRET     1
 #define KEYBOX_FLAG_BLOB_EPHEMERAL  2
 
+/* The keybox blob types.  */
+typedef enum
+  {
+    KEYBOX_BLOBTYPE_EMPTY  = 0,
+    KEYBOX_BLOBTYPE_HEADER = 1,
+    KEYBOX_BLOBTYPE_PGP    = 2,
+    KEYBOX_BLOBTYPE_X509   = 3
+  } keybox_blobtype_t;
 
 
 /*-- keybox-init.c --*/
 void *keybox_register_file (const char *fname, int secret);
 int keybox_is_writable (void *token);
 
-KEYBOX_HANDLE keybox_new (void *token, int secret);
+KEYBOX_HANDLE keybox_new_openpgp (void *token, int secret);
+KEYBOX_HANDLE keybox_new_x509 (void *token, int secret);
 void keybox_release (KEYBOX_HANDLE hd);
 void keybox_push_found_state (KEYBOX_HANDLE hd);
 void keybox_pop_found_state (KEYBOX_HANDLE hd);
 const char *keybox_get_resource_name (KEYBOX_HANDLE hd);
 int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
 
+int keybox_lock (KEYBOX_HANDLE hd, int yes);
+
+/*-- keybox-file.c --*/
+/* Fixme: This function does not belong here: Provide a better
+   interface to create a new keybox file.  */
+int _keybox_write_header_blob (FILE *fp, int openpgp_flag);
 
 /*-- keybox-search.c --*/
-#ifdef KEYBOX_WITH_X509 
+gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
+                                 int *r_uid_no, int *r_pk_no, u32 **sigstatus);
+#ifdef KEYBOX_WITH_X509
 int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert);
 #endif /*KEYBOX_WITH_X509*/
 int keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value);
 
 int keybox_search_reset (KEYBOX_HANDLE hd);
-int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc);
+int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
+                   keybox_blobtype_t want_blobtype,
+                   size_t *r_descindex, unsigned long *r_skipped);
 
 
 /*-- keybox-update.c --*/
-#ifdef KEYBOX_WITH_X509 
+gpg_error_t keybox_insert_keyblock (KEYBOX_HANDLE hd,
+                                    const void *image, size_t imagelen,
+                                    u32 *sigstatus);
+gpg_error_t keybox_update_keyblock (KEYBOX_HANDLE hd,
+                                    const void *image, size_t imagelen);
+
+#ifdef KEYBOX_WITH_X509
 int keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
                         unsigned char *sha1_digest);
 int keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
@@ -100,11 +121,7 @@ int keybox_compress (KEYBOX_HANDLE hd);
 /*--  --*/
 
 #if 0
-int keybox_lock (KEYBOX_HANDLE hd, int yes);
-int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb);
 int keybox_locate_writable (KEYBOX_HANDLE hd);
-int keybox_search_reset (KEYBOX_HANDLE hd);
-int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc);
 int keybox_rebuild_cache (void *);
 #endif
 
index cd49d4d..629485a 100755 (executable)
@@ -27,12 +27,12 @@ cat <<EOF
 
 /**
  * keybox_strerror:
- * @err:  Error code 
- * 
+ * @err:  Error code
+ *
  * This function returns a textual representaion of the given
  * errorcode. If this is an unknown value, a string with the value
  * is returned (Beware: it is hold in a static buffer).
- * 
+ *
  * Return value: String with the error description.
  **/
 const char *
index b3f96a4..01cca41 100644 (file)
@@ -1,10 +1,16 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
+2011-01-20  Werner Koch  <wk@g10code.com>
+
+       * gpgkeys_hkp.c (get_name): Remove test for KS_GETNAME.  It is
+       always true.
+       (search_key): Remove test for KS_GETNAME.  It is always false.
+
 2009-08-26  Werner Koch  <wk@g10code.com>
 
        * gpgkeys_hkp.c: Include util.h.
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/keyserver/Makefile.am b/keyserver/Makefile.am
deleted file mode 100644 (file)
index e625127..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-# Makefile.am - Makefile for keyservers
-# Copyright (C) 2001, 2002, 2004, 2005, 2006,
-#               2009 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 3 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, see <http://www.gnu.org/licenses/>.
-## Process this file with automake to produce Makefile.in
-
-# Note that we have renamed the resulting binaries to from gpgkeys_foo
-# to gpg2keys_foo to allow for a non-conflicting installation of
-# gnupg1 and gnupg2.  Having the same names for the helpers would
-# otherwise lead to trouble when to uninstall one of them.
-EXTRA_PROGRAMS = gpg2keys_ldap gpg2keys_hkp gpg2keys_finger gpg2keys_curl \
-                gpg2keys_kdns
-EXTRA_SCRIPTS = gpg2keys_mailto
-
-EXTRA_DIST = ChangeLog-2011
-
-AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl
-
-AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
-
-include $(top_srcdir)/am/cmacros.am
-
-libexec_PROGRAMS = $(GPGKEYS_LDAP) $(GPGKEYS_HKP) $(GPGKEYS_FINGER) \
-                   $(GPGKEYS_CURL) $(GPGKEYS_KDNS)
-libexec_SCRIPTS = $(GPGKEYS_MAILTO)
-noinst_SCRIPTS = gpg2keys_test
-
-common_libs = ../gl/libgnu.a  ../common/libcommon.a ../jnlib/libjnlib.a
-other_libs = $(LIBICONV) $(LIBINTL) $(CAPLIBS)
-
-gpg2keys_ldap_SOURCES = gpgkeys_ldap.c ksutil.c ksutil.h no-libgcrypt.c
-gpg2keys_ldap_CPPFLAGS = $(LDAP_CPPFLAGS) $(AM_CPPFLAGS)
-gpg2keys_ldap_LDADD = ../jnlib/libjnlib.a $(LDAPLIBS) $(GPG_ERROR_LIBS) \
-                      $(NETLIBS) $(other_libs)
-
-gpg2keys_finger_SOURCES = gpgkeys_finger.c ksutil.c ksutil.h no-libgcrypt.c
-gpg2keys_finger_CPPFLAGS = $(AM_CPPFLAGS)
-gpg2keys_finger_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
-                        $(NETLIBS) $(other_libs)
-
-gpg2keys_kdns_SOURCES = gpgkeys_kdns.c ksutil.c ksutil.h no-libgcrypt.c
-gpg2keys_kdns_CPPFLAGS = $(AM_CPPFLAGS)
-gpg2keys_kdns_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
-                      $(ADNSLIBS) $(NETLIBS) $(other_libs)
-
-
-gpg2keys_curl_SOURCES = gpgkeys_curl.c ksutil.c ksutil.h no-libgcrypt.c
-gpg2keys_hkp_SOURCES  = gpgkeys_hkp.c ksutil.c ksutil.h no-libgcrypt.c
-if FAKE_CURL
-gpg2keys_curl_SOURCES += curl-shim.c curl-shim.h
-gpg2keys_curl_CPPFLAGS = $(AM_CPPFLAGS)
-gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
-                     $(other_libs)
-gpg2keys_hkp_SOURCES += curl-shim.c curl-shim.h
-gpg2keys_hkp_CPPFLAGS = $(AM_CPPFLAGS)
-gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
-                    $(other_libs)
-else
-# Note that we need to include all other libs here as well because
-# some compilers don't care about inline functions and insert
-# references to symbols used in unused inline functions.
-gpg2keys_curl_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS)
-gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
-                      $(other_libs) $(LIBCURL) $(GETOPT)
-gpg2keys_hkp_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS)
-gpg2keys_hkp_LDADD =  $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
-                      $(other_libs) $(LIBCURL) $(GETOPT)
-endif
-
-# Make sure that all libs are build before we use them.  This is
-# important for things like make -j2.
-$(PROGRAMS): $(common_libs)
index 93d05b0..696efe2 100644 (file)
@@ -1,8 +1,7 @@
 /* curl-shim.c - Implement a small subset of the curl API in terms of
  * the iobuf HTTP API
  *
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2012,
- *               2013 Free Software Foundation, Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -165,8 +164,6 @@ curl_easy_setopt(CURL *curl,CURLoption option,...)
       break;
     }
 
-  va_end(ap);
-
   return handle_error(curl,CURLE_OK,NULL);
 }
 
@@ -177,9 +174,6 @@ curl_easy_perform(CURL *curl)
   CURLcode err=CURLE_OK;
   const char *errstr=NULL;
   char *proxy=NULL;
-  struct http_srv srv;
-
-  memset(&srv,0,sizeof(srv));
 
   /* Emulate the libcurl proxy behavior.  If the calling program set a
      proxy, use it.  If it didn't set a proxy or set it to NULL, check
@@ -192,17 +186,10 @@ curl_easy_perform(CURL *curl)
   else
     proxy=getenv(HTTP_PROXY_ENV);
 
-  if(curl->srvtag)
-    srv.srvtag=curl->srvtag;
-
   if(curl->flags.verbose)
     {
       fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null");
       fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url);
-      if(srv.srvtag)
-       fprintf(curl->errors,
-               "* SRV tag is \"%s\": host and port may be overridden\n",
-               srv.srvtag);
       fprintf(curl->errors,"* HTTP auth is \"%s\"\n",
              curl->auth?curl->auth:"null");
       fprintf(curl->errors,"* HTTP method is %s\n",
@@ -211,17 +198,13 @@ curl_easy_perform(CURL *curl)
 
   if(curl->flags.post)
     {
-      rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth,
-                      0, proxy, NULL, &srv,
+      rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, NULL, curl->auth,
+                      0, proxy, NULL, curl->srvtag,
                      curl->headers?curl->headers->list:NULL);
       if (!rc)
        {
          unsigned int post_len = strlen(curl->postfields);
 
-         if(curl->flags.verbose && srv.used_server && srv.used_port)
-           fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
-                    srv.used_server, srv.used_port);
-
          es_fprintf (http_get_write_ptr (curl->hd),
                       "Content-Type: application/x-www-form-urlencoded\r\n"
                       "Content-Length: %u\r\n", post_len);
@@ -239,15 +222,11 @@ curl_easy_perform(CURL *curl)
     }
   else
     {
-      rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth,
-                      0, proxy, NULL, &srv,
+      rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, NULL, curl->auth,
+                      0, proxy, NULL, curl->srvtag,
                      curl->headers?curl->headers->list:NULL);
       if (!rc)
        {
-         if(curl->flags.verbose && srv.used_server && srv.used_port)
-           fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
-                    srv.used_server, srv.used_port);
-
          rc = http_wait_response (curl->hd);
           curl->status = http_get_status_code (curl->hd);
          if (!rc)
@@ -289,8 +268,6 @@ curl_easy_perform(CURL *curl)
        }
     }
 
-  xfree(srv.used_server);
-
   switch(gpg_err_code (rc))
     {
     case 0:
@@ -305,29 +282,8 @@ curl_easy_perform(CURL *curl)
       err=CURLE_COULDNT_CONNECT;
       break;
     }
-      
-  return handle_error(curl,err,errstr);
-}
 
-CURLcode
-curl_easy_getinfo(CURL *curl, CURLINFO info, ... )
-{
-  va_list ap;
-  long *var;
-
-  va_start(ap,info);
-
-  switch(info)
-    {
-    case CURLINFO_RESPONSE_CODE:
-      var=va_arg(ap,long *);
-      *var=curl->status;
-      break;
-    default:
-      break;
-    }
-
-  return handle_error(curl,CURLE_OK,NULL);
+  return handle_error(curl,err,errstr);
 }
 
 /* This is not the same exact set that is allowed according to
index df28fcc..0a11e7c 100644 (file)
@@ -1,6 +1,5 @@
 /* curl-shim.h
- * Copyright (C) 2005, 2006, 2007, 2008, 2009,
- *               2013 Free Software Foundation, Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GNUPG.
  *
@@ -55,11 +54,6 @@ typedef enum
     CURLOPT_SRVTAG_GPG_HACK
   } CURLoption;
 
-typedef enum
-  {
-    CURLINFO_RESPONSE_CODE
-  } CURLINFO;
-
 typedef size_t (*write_func)(char *buffer,size_t size,
                             size_t nitems,void *outstream);
 
@@ -88,7 +82,7 @@ typedef struct
 typedef struct
 {
   const char **protocols;
-} curl_version_info_data; 
+} curl_version_info_data;
 
 #define CURL_ERROR_SIZE 256
 #define CURL_GLOBAL_DEFAULT 0
@@ -99,11 +93,10 @@ void curl_global_cleanup(void);
 CURL *curl_easy_init(void);
 CURLcode curl_easy_setopt(CURL *curl,CURLoption option,...);
 CURLcode curl_easy_perform(CURL *curl);
-CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );
 void curl_easy_cleanup(CURL *curl);
 char *curl_escape(char *str,int len);
 #define curl_free(x) free(x)
-#define curl_version() "GnuPG curl-shim"
+#define curl_version() GNUPG_NAME" curl-shim"
 curl_version_info_data *curl_version_info(int type);
 
 struct curl_slist
index f0f5744..fc4c6f3 100644 (file)
@@ -124,7 +124,7 @@ main(int argc,char *argv[])
   /* Kludge to implement standard GNU options.  */
   if (argc > 1 && !strcmp (argv[1], "--version"))
     {
-      printf ("gpgkeys_curl (GnuPG) %s\n", VERSION);
+      printf ("gpgkeys_curl (%s) %s\n", GNUPG_NAME, VERSION);
       printf ("Uses: %s\n", curl_version());
       return 0;
     }
@@ -150,7 +150,7 @@ main(int argc,char *argv[])
        output=fopen(optarg,"wb");
        if(output==NULL)
          {
-           fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+           fprintf(console,"gpgkeys: Cannot open output file '%s': %s\n",
                    optarg,strerror(errno));
            return KEYSERVER_INTERNAL_ERROR;
          }
@@ -163,7 +163,7 @@ main(int argc,char *argv[])
       input=fopen(argv[optind],"r");
       if(input==NULL)
        {
-         fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+         fprintf(console,"gpgkeys: Cannot open input file '%s': %s\n",
                  argv[optind],strerror(errno));
          return KEYSERVER_INTERNAL_ERROR;
        }
@@ -281,7 +281,7 @@ main(int argc,char *argv[])
 
   if(curldata->protocols[i]==NULL)
     {
-      fprintf(console,"gpgkeys: protocol `%s' not supported\n",opt->scheme);
+      fprintf(console,"gpgkeys: protocol '%s' not supported\n",opt->scheme);
       ret=KEYSERVER_SCHEME_NOT_FOUND;
       goto fail;
     }
@@ -304,8 +304,7 @@ main(int argc,char *argv[])
     }
 
   curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert);
-  if (opt->ca_cert_file)
-    curl_easy_setopt (curl, CURLOPT_CAINFO, opt->ca_cert_file);
+  curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file);
 
   /* Avoid caches to get the most recent copy of the key.  This is bug
      #1061.  In pre-curl versions of the code, we didn't do it.  Then
index a599e4d..673e956 100644 (file)
 #endif
 
 #ifdef HAVE_W32_SYSTEM
-# ifdef HAVE_WINSOCK2_H
-#  include <winsock2.h>
-# endif
-# include <windows.h>
+#include <windows.h>
 #else
 #include <unistd.h>
 #include <sys/types.h>
@@ -88,13 +85,13 @@ connect_server (const char *server, unsigned short port)
     {
       if (hp->h_addrtype != AF_INET)
         {
-          fprintf (console, "gpgkeys: unknown address family for `%s'\n",
+          fprintf (console, "gpgkeys: unknown address family for '%s'\n",
                    server);
           return -1;
         }
       if (hp->h_length != 4)
         {
-          fprintf (console, "gpgkeys: illegal address length for `%s'\n",
+          fprintf (console, "gpgkeys: illegal address length for '%s'\n",
                    server);
           return -1;
         }
@@ -102,7 +99,7 @@ connect_server (const char *server, unsigned short port)
     }
   else
     {
-      fprintf (console, "gpgkeys: host `%s' not found: ec=%d\n",
+      fprintf (console, "gpgkeys: host '%s' not found: ec=%d\n",
                server, (int)WSAGetLastError ());
       return -1;
     }
@@ -117,7 +114,7 @@ connect_server (const char *server, unsigned short port)
 
   if (connect (sock, (struct sockaddr *)&addr, sizeof addr))
     {
-      fprintf (console, "gpgkeys: error connecting `%s': ec=%d\n",
+      fprintf (console, "gpgkeys: error connecting '%s': ec=%d\n",
                server, (int)WSAGetLastError ());
       sock_close (sock);
       return -1;
@@ -133,7 +130,7 @@ connect_server (const char *server, unsigned short port)
   host = gethostbyname ((char*)server);
   if (!host)
     {
-      fprintf (console, "gpgkeys: host `%s' not found: %s\n",
+      fprintf (console, "gpgkeys: host '%s' not found: %s\n",
                server, strerror (errno));
       return -1;
     }
@@ -150,7 +147,7 @@ connect_server (const char *server, unsigned short port)
 
   if (connect (sock, (struct sockaddr *)&addr, sizeof addr) == -1)
     {
-      fprintf (console, "gpgkeys: error connecting `%s': %s\n",
+      fprintf (console, "gpgkeys: error connecting '%s': %s\n",
                server, strerror (errno));
       close (sock);
       return -1;
@@ -340,7 +337,7 @@ main(int argc,char *argv[])
   /* Kludge to implement standard GNU options.  */
   if (argc > 1 && !strcmp (argv[1], "--version"))
     {
-      fputs ("gpgkeys_finger (GnuPG) " VERSION"\n", stdout);
+      fputs ("gpgkeys_finger ("GNUPG_NAME") " VERSION"\n", stdout);
       return 0;
     }
   else if (argc > 1 && !strcmp (argv[1], "--help"))
@@ -365,7 +362,7 @@ main(int argc,char *argv[])
        output=fopen(optarg,"w");
        if(output==NULL)
          {
-           fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+           fprintf(console,"gpgkeys: Cannot open output file '%s': %s\n",
                    optarg,strerror(errno));
            return KEYSERVER_INTERNAL_ERROR;
          }
@@ -378,7 +375,7 @@ main(int argc,char *argv[])
       input=fopen(argv[optind],"r");
       if(input==NULL)
        {
-         fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+         fprintf(console,"gpgkeys: Cannot open input file '%s': %s\n",
                  argv[optind],strerror(errno));
          return KEYSERVER_INTERNAL_ERROR;
        }
index 36a44ef..6ecc8bb 100644 (file)
@@ -1,6 +1,6 @@
 /* gpgkeys_hkp.c - talk to an HKP keyserver
  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- *               2009, 2012, 2013 Free Software Foundation, Inc.
+ *               2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <errno.h>
 #include <unistd.h>
 #ifdef HAVE_GETOPT_H
-# include <getopt.h>
+#include <getopt.h>
 #endif
 #ifdef HAVE_LIBCURL
-# include <curl/curl.h>
-/* This #define rigamarole is to enable a hack to fake DNS SRV using
-   libcurl.  It only works if we have getaddrinfo(), inet_ntop(), and
-   a modern enough version of libcurl (7.21.3) so we can use
-   CURLOPT_RESOLVE to feed the resolver from the outside to force
-   libcurl to pass the right SNI. */
-# if (defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP) \
-      && LIBCURL_VERNUM >= 0x071503)
-#  include <sys/types.h>
-#  include <sys/socket.h>
-#  include <netdb.h>
-#  include <arpa/inet.h>
-# else
-#  undef USE_DNS_SRV
-# endif
+#include <curl/curl.h>
 #else
-#  include "curl-shim.h"
+#include "curl-shim.h"
 #endif
 #include "util.h"
 #ifdef USE_DNS_SRV
-# include "srv.h"
+#include "srv.h"
 #endif
 #include "keyserver.h"
 #include "ksutil.h"
@@ -74,10 +60,9 @@ static char errorbuffer[CURL_ERROR_SIZE];
 static char *proto,*port;
 
 static size_t
-curl_mrindex_writer (const void *ptr,size_t size,size_t nmemb,void *stream)
+curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream)
 {
-  static int checked = 0;
-  static int swallow = 0;
+  static int checked=0,swallow=0;
 
   if(!checked)
     {
@@ -223,7 +208,7 @@ send_key(int *r_eof)
   append_path(request,"/pks/add");
 
   if(opt->verbose>2)
-    fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+    fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request);
 
   curl_easy_setopt(curl,CURLOPT_URL,request);
   curl_easy_setopt(curl,CURLOPT_POST,1L);
@@ -304,7 +289,7 @@ get_key(char *getkey)
   strcat(request,offset);
 
   if(opt->verbose>2)
-    fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+    fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request);
 
   curl_easy_setopt(curl,CURLOPT_URL,request);
   curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer);
@@ -319,49 +304,15 @@ get_key(char *getkey)
     }
   else
     {
-      long status = 0;
-
       curl_writer_finalize(&ctx);
-
-      curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &status);
-
-      if (opt->verbose > 2)
-       fprintf (console, "gpgkeys: HTTP response code is %ld\n", status);
-
-      if (status == 200)
+      if(!ctx.flags.done)
        {
-         if (!ctx.flags.done)
-           {
-             if (ctx.flags.begun)
-               {
-                 fprintf (console, "gpgkeys: key %s partially retrieved"
-                          " (probably corrupt)\n", getkey);
-                 fprintf (output, "\nKEY 0x%s FAILED %d\n",
-                          getkey, KEYSERVER_KEY_INCOMPLETE);
-               }
-             else
-               {
-                 fprintf (console, "gpgkeys: key %s can't be retrieved\n",
-                          getkey);
-                 fprintf (output, "\nKEY 0x%s FAILED %d\n",
-                          getkey, KEYSERVER_GENERAL_ERROR);
-               }
-           }
-         else
-           fprintf (output, "\nKEY 0x%s END\n", getkey);
-       }
-      else if (status == 404)
-       {
-         fprintf (console, "gpgkeys: key %s not found on keyserver\n", getkey);
-         fprintf (output, "\nKEY 0x%s FAILED %d\n",
-                 getkey, KEYSERVER_KEY_NOT_FOUND);
+         fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
+         fprintf(output,"\nKEY 0x%s FAILED %d\n",
+                 getkey,KEYSERVER_KEY_NOT_FOUND);
        }
       else
-       {
-         fprintf (console, "gpgkeys: key %s can't be retrieved\n", getkey);
-         fprintf (output, "\nKEY 0x%s FAILED %d\n",
-                 getkey, KEYSERVER_GENERAL_ERROR);
-       }
+       fprintf(output,"\nKEY 0x%s END\n",getkey);
     }
 
   return KEYSERVER_OK;
@@ -395,7 +346,7 @@ get_name(const char *getkey)
      opt->path,
      appendable_path (opt->path,"/pks/lookup?op=get&options=mr&search="),
      searchkey_encoded,
-     opt->action == KS_GETNAME? "&exact=on":"",
+     "&exact=on",
      NULL);
   if(!request)
     {
@@ -407,7 +358,7 @@ get_name(const char *getkey)
   fprintf(output,"NAME %s BEGIN\n",getkey);
 
   if(opt->verbose>2)
-    fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+    fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request);
 
   curl_easy_setopt(curl,CURLOPT_URL,request);
   curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer);
@@ -422,47 +373,16 @@ get_name(const char *getkey)
     }
   else
     {
-      long status = 0;
-
       curl_writer_finalize(&ctx);
-
-      curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &status);
-
-      if (opt->verbose > 2)
-       fprintf (console, "gpgkeys: HTTP response code is %ld\n", status);
-
-      if (status == 200)
+      if(!ctx.flags.done)
        {
-         if (!ctx.flags.done)
-           {
-             if (ctx.flags.begun)
-               {
-                 fprintf (console, "gpgkeys: key %s partially retrieved"
-                          " (probably corrupt)\n", getkey);
-                 ret = KEYSERVER_KEY_INCOMPLETE;
-               }
-             else
-               {
-                 fprintf (console, "gpgkeys: key %s can't be retrieved\n",
-                          getkey);
-                 ret = KEYSERVER_GENERAL_ERROR;
-               }
-           }
-         else
-           {
-             fprintf (output, "\nNAME %s END\n", getkey);
-             ret = KEYSERVER_OK;
-           }
-       }
-      else if (status == 404)
-       {
-         fprintf (console, "gpgkeys: key %s not found on keyserver\n", getkey);
-         ret = KEYSERVER_KEY_NOT_FOUND;
+         fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
+         ret=KEYSERVER_KEY_NOT_FOUND;
        }
       else
        {
-         fprintf (console, "gpgkeys: key %s can't be retrieved\n", getkey);
-         ret = KEYSERVER_GENERAL_ERROR;
+         fprintf(output,"\nNAME %s END\n",getkey);
+         ret=KEYSERVER_OK;
        }
     }
 
@@ -515,7 +435,6 @@ search_key(const char *searchkey)
      appendable_path (opt->path, "/pks/lookup?op=index&options=mr&search="),
      hexprefix,
      searchkey_encoded,
-     opt->action == KS_GETNAME? "&exact=on":"",
      NULL);
   if(!request)
     {
@@ -527,7 +446,7 @@ search_key(const char *searchkey)
   fprintf(output,"SEARCH %s BEGIN\n",searchkey);
 
   if(opt->verbose>2)
-    fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+    fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request);
 
   curl_easy_setopt(curl,CURLOPT_URL,request);
   curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_mrindex_writer);
@@ -579,29 +498,19 @@ fail_all(struct keylist *keylist,int err)
       }
 }
 
-#if defined(HAVE_LIBCURL) && defined(USE_DNS_SRV)
+#ifdef HAVE_LIBCURL
 /* If there is a SRV record, take the highest ranked possibility.
-   This is a hack, as we don't proceed downwards if we can't
-   connect(), but only if we can't getaddinfo().  All this should
-   ideally be replaced by actual SRV support in libcurl someday! */
-
-#define HOST_HEADER "Host:"
-
+   This is a hack, as we don't proceed downwards. */
 static void
-srv_replace(const char *srvtag,
-           struct curl_slist **headers,struct curl_slist **resolve)
+srv_replace(const char *srvtag)
 {
+#ifdef USE_DNS_SRV
   struct srventry *srvlist=NULL;
-  int srvcount, srvindex;
-  char *portstr;
+  int srvcount;
 
   if(!srvtag)
     return;
 
-  portstr=malloc (MAX_PORT);
-  if(!portstr)
-    return;
-
   if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME)
     {
       char srvname[MAXDNAME];
@@ -612,77 +521,28 @@ srv_replace(const char *srvtag,
       strcat(srvname,opt->host);
       srvcount=getsrv(srvname,&srvlist);
     }
-  else
-    srvcount = 0;
 
-  for(srvindex=0 ; srvindex<srvcount && portstr ; srvindex++)
+  if(srvlist)
     {
-      struct addrinfo hints, *res;
+      char *newname,*newport;
 
-      sprintf (portstr, "%hu", srvlist[srvindex].port);
-      memset (&hints, 0, sizeof (hints));
-      hints.ai_socktype = SOCK_STREAM;
-
-      if (getaddrinfo (srvlist[srvindex].target, portstr, &hints, &res) == 0)
+      newname=strdup(srvlist->target);
+      newport=malloc(MAX_PORT);
+      if(newname && newport)
        {
-         /* Very safe */
-         char ipaddr[INET_ADDRSTRLEN+INET6_ADDRSTRLEN];
-
-         if((res->ai_family==AF_INET
-             && inet_ntop (res->ai_family,
-                           &((struct sockaddr_in *)res->ai_addr)->sin_addr,
-                           ipaddr,sizeof(ipaddr)))
-            || (res->ai_family==AF_INET6
-                && inet_ntop (res->ai_family,
-                              &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
-                              ipaddr,sizeof(ipaddr))))
-           {
-             char *entry,*host;
-
-             entry=malloc (strlen(opt->host)+1
-                           +strlen(portstr)+1+strlen(ipaddr)+1);
-
-             host=malloc (strlen(HOST_HEADER)+1+strlen(opt->host)+1);
-
-             if(entry && host)
-               {
-                 sprintf (entry, "%s:%s:%s", opt->host, portstr, ipaddr);
-                 sprintf (host, "%s %s", HOST_HEADER, opt->host);
-
-                 *resolve=curl_slist_append (*resolve,entry);
-                 *headers=curl_slist_append (*headers,host);
-
-                 if(*resolve && *headers)
-                   {
-                     if(curl_easy_setopt (curl,
-                                          CURLOPT_RESOLVE,*resolve)==CURLE_OK)
-                       {
-                         if(opt->debug)
-                           fprintf (console, "gpgkeys: Faking %s SRV from"
-                                    " %s to %s:%u\n",
-                                    srvtag, opt->host,
-                                    srvlist[srvindex].target,
-                                    srvlist[srvindex].port);
-
-                         free (opt->port);
-                         opt->port=portstr;
-                         portstr=NULL;
-                       }
-                   }
-               }
-
-             free (entry);
-             free (host);
-           }
-
-         freeaddrinfo (res);
+         free(opt->host);
+         free(opt->port);
+         opt->host=newname;
+         snprintf(newport,MAX_PORT,"%u",srvlist->port);
+         opt->port=newport;
        }
       else
-       continue; /* Not found */
+       {
+         free(newname);
+         free(newport);
+       }
     }
-
-  free (srvlist);
-  free (portstr);
+#endif
 }
 #endif
 
@@ -698,26 +558,19 @@ show_help (FILE *fp)
 int
 main(int argc,char *argv[])
 {
-  int arg,ret=KEYSERVER_INTERNAL_ERROR;
+  int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1;
   char line[MAX_LINE];
   int failed=0;
   struct keylist *keylist=NULL,*keyptr=NULL;
   char *proxy=NULL;
-  struct curl_slist *headers=NULL,*resolve=NULL;
-
-  /* Only default this to on if we have SRV support */
-#ifdef USE_DNS_SRV
-  int try_srv = 1;
-#else
-  int try_srv = 0;
-#endif
+  struct curl_slist *headers=NULL;
 
   console=stderr;
 
   /* Kludge to implement standard GNU options.  */
   if (argc > 1 && !strcmp (argv[1], "--version"))
     {
-      printf ("gpgkeys_hkp (GnuPG) %s\n", VERSION);
+      printf ("gpgkeys_hkp (%s) %s\n", GNUPG_NAME, VERSION);
       printf ("Uses: %s\n", curl_version());
       return 0;
     }
@@ -743,7 +596,7 @@ main(int argc,char *argv[])
        output=fopen(optarg,"w");
        if(output==NULL)
          {
-           fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+           fprintf(console,"gpgkeys: Cannot open output file '%s': %s\n",
                    optarg,strerror(errno));
            return KEYSERVER_INTERNAL_ERROR;
          }
@@ -756,7 +609,7 @@ main(int argc,char *argv[])
       input=fopen(argv[optind],"r");
       if(input==NULL)
        {
-         fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+         fprintf(console,"gpgkeys: Cannot open input file '%s': %s\n",
                  argv[optind],strerror(errno));
          return KEYSERVER_INTERNAL_ERROR;
        }
@@ -839,8 +692,7 @@ main(int argc,char *argv[])
       goto fail;
     }
 
-  /* Defaults */
-  if(ks_strcasecmp(opt->scheme,"hkps")==0)
+  if(ascii_strcasecmp(opt->scheme,"hkps")==0)
     {
       proto="https";
       port="443";
@@ -872,16 +724,11 @@ main(int argc,char *argv[])
       goto fail;
     }
 
-  if(opt->debug)
-    {
-      fprintf(console,"gpgkeys: curl version = %s\n",curl_version());
-      curl_easy_setopt(curl,CURLOPT_STDERR,console);
-      curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
-    }
-
-  /* Only use SRV if the user does not provide a :port.  The semantics
-     of a specified port and SRV do not play well together. */
-  if(!opt->port && try_srv)
+  /* If the user gives a :port, then disable SRV.  The semantics of a
+     specified port and SRV do not play well together. */
+  if(opt->port)
+    port=opt->port;
+  else if(try_srv)
     {
       char *srvtag;
 
@@ -897,12 +744,8 @@ main(int argc,char *argv[])
         This isn't as good as true SRV support, as we do not try all
         possible targets at one particular level and work our way
         down the list, but it's better than nothing. */
-#ifdef USE_DNS_SRV
-      srv_replace(srvtag,&headers,&resolve);
+      srv_replace(srvtag);
 #else
-      fprintf(console,"gpgkeys: try-dns-srv was requested, but not SRV capable\n");
-#endif
-#else /* !HAVE_LIBCURL */
       /* We're using our internal curl shim, so we can use its (true)
         SRV support.  Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real
         libcurl option.  It's specific to our shim. */
@@ -910,19 +753,20 @@ main(int argc,char *argv[])
 #endif
     }
 
-  /* If the user provided a port (or it came in via SRV, above),
-     replace the default. */
-  if(opt->port)
-    port=opt->port;
-
   curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer);
 
   if(opt->auth)
     curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth);
 
+  if(opt->debug)
+    {
+      fprintf(console,"gpgkeys: curl version = %s\n",curl_version());
+      curl_easy_setopt(curl,CURLOPT_STDERR,console);
+      curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
+    }
+
   curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert);
-  if (opt->ca_cert_file)
-    curl_easy_setopt (curl, CURLOPT_CAINFO, opt->ca_cert_file);
+  curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file);
 
   /* Avoid caches to get the most recent copy of the key.  This is bug
      #1061.  In pre-curl versions of the code, we didn't do it.  Then
@@ -1122,7 +966,6 @@ main(int argc,char *argv[])
   free_ks_options(opt);
 
   curl_slist_free_all(headers);
-  curl_slist_free_all(resolve);
 
   if(curl)
     curl_easy_cleanup(curl);
index 5979b06..14651f9 100644 (file)
@@ -66,7 +66,7 @@ static const char *kdns_root;
 /* The replacement string for the at sign.  */
 static const char *kdns_at_repl;
 
-/* Flag indicating that a TCP conenction should be used.  */
+/* Flag indicating that a TCP connection should be used.  */
 static int kdns_usevc;
 
 
@@ -87,7 +87,7 @@ get_key (adns_state adns_ctx, char *address)
   domain = strrchr (address, '@');
   if (!domain || domain == address || !domain[1])
     {
-      fprintf (console, PGM": invalid mail address `%s'\n", address);
+      fprintf (console, PGM": invalid mail address '%s'\n", address);
       ret = KEYSERVER_GENERAL_ERROR;
       goto leave;
     }
@@ -105,7 +105,7 @@ get_key (adns_state adns_ctx, char *address)
 
   fprintf (output,"NAME %s BEGIN\n", address);
   if (opt->verbose > 2)
-    fprintf(console, PGM": looking up `%s'\n", name);
+    fprintf(console, PGM": looking up '%s'\n", name);
 
   if ( adns_synchronous (adns_ctx, name, (adns_r_unknown | my_adns_r_cert),
                          adns_qf_quoteok_query|(kdns_usevc?adns_qf_usevc:0),
@@ -115,9 +115,9 @@ get_key (adns_state adns_ctx, char *address)
       ret = KEYSERVER_KEY_NOT_FOUND;
       goto leave;
     }
-  if (answer->status != adns_s_ok) 
+  if (answer->status != adns_s_ok)
     {
-      fprintf (console, PGM": DNS query returned: %s (%s)\n", 
+      fprintf (console, PGM": DNS query returned: %s (%s)\n",
                adns_strerror (answer->status),
                adns_errabbrev (answer->status));
       ret = KEYSERVER_KEY_NOT_FOUND;
@@ -141,7 +141,7 @@ get_key (adns_state adns_ctx, char *address)
     }
   if ( datalen < 5 )
     {
-      fprintf (console, PGM": error: truncated CERT record\n"); 
+      fprintf (console, PGM": error: truncated CERT record\n");
       ret = KEYSERVER_KEY_NOT_FOUND;
       goto leave;
     }
@@ -155,7 +155,7 @@ get_key (adns_state adns_ctx, char *address)
       if ( datalen < 11 )
         {
           /* Gpg checks for a minium length of 11, thus we do the same.  */
-          fprintf (console, PGM": error: OpenPGP data to short\n"); 
+          fprintf (console, PGM": error: OpenPGP data to short\n");
           ret = KEYSERVER_KEY_NOT_FOUND;
           goto leave;
         }
@@ -166,11 +166,11 @@ get_key (adns_state adns_ctx, char *address)
       break;
 
     default:
-      fprintf (console, PGM": CERT type %d ignored\n", (data[0] <<8|data[1])); 
+      fprintf (console, PGM": CERT type %d ignored\n", (data[0] <<8|data[1]));
       ret = KEYSERVER_KEY_NOT_FOUND;
       goto leave;
     }
-  
+
   ret = 0; /* All fine.  */
 
  leave:
@@ -178,17 +178,17 @@ get_key (adns_state adns_ctx, char *address)
     fprintf (output, "\nNAME %s FAILED %d\n", address, ret);
   else
     fprintf (output, "\nNAME %s END\n", address);
-  adns_free (answer); 
+  adns_free (answer);
   xfree (name);
   return ret;
 }
 
 
 /* Print some help.  */
-static void 
+static void
 show_help (FILE *fp)
 {
-  fputs (PGM" (GnuPG) " VERSION"\n\n", fp);
+  fputs (PGM" ("GNUPG_NAME") " VERSION"\n\n", fp);
   fputs (" -h\thelp\n"
          " -V\tversion\n"
          " -o\toutput to this file\n"
@@ -233,7 +233,7 @@ main (int argc, char *argv[])
   /* Kludge to implement standard GNU options.  */
   if (argc > 1 && !strcmp (argv[1], "--version"))
     {
-      fputs (PGM" (GnuPG) " VERSION"\n", stdout);
+      fputs (PGM" ("GNUPG_NAME") " VERSION"\n", stdout);
       return 0;
     }
   else if (argc > 1 && !strcmp (argv[1], "--help"))
@@ -254,7 +254,7 @@ main (int argc, char *argv[])
           output = fopen (optarg,"w");
           if (!output)
             {
-              fprintf (console, PGM": cannot open output file `%s': %s\n",
+              fprintf (console, PGM": cannot open output file '%s': %s\n",
                        optarg, strerror(errno) );
               return KEYSERVER_INTERNAL_ERROR;
             }
@@ -272,7 +272,7 @@ main (int argc, char *argv[])
       input = fopen (argv[optind], "r");
       if (!input)
        {
-         fprintf (console, PGM": cannot open input file `%s': %s\n",
+         fprintf (console, PGM": cannot open input file '%s': %s\n",
                    argv[optind], strerror(errno) );
          return KEYSERVER_INTERNAL_ERROR;
        }
@@ -283,7 +283,7 @@ main (int argc, char *argv[])
 
   if (!output)
     output = stdout;
-  
+
   opt = init_ks_options();
   if(!opt)
     return KEYSERVER_NO_MEMORY;
@@ -292,10 +292,10 @@ main (int argc, char *argv[])
   while ( fgets(line,MAX_LINE,input) )
     {
       int err;
-      
+
       if(line[0]=='\n')
        break;
-      
+
       err = parse_ks_options (line, opt);
       if (err > 0)
        {
@@ -326,7 +326,7 @@ main (int argc, char *argv[])
       if (p)
         {
           *p++ = 0;
-          do 
+          do
             {
               pend = strchr (p, '&');
               if (pend)
@@ -371,7 +371,7 @@ main (int argc, char *argv[])
                strerror (errno));
       goto leave;
     }
-  
+
   if (opt->action == KS_GETNAME)
     {
       while ( fgets (line,MAX_LINE,input) )
@@ -379,11 +379,11 @@ main (int argc, char *argv[])
           if (line[0]=='\n' || !line[0] )
             break;
           line[strlen(line)-1] = 0;  /* Trim the trailing LF. */
-          
+
           akey = xtrymalloc (sizeof *akey);
           if (!akey)
             {
-              fprintf (console, 
+              fprintf (console,
                        PGM": out of memory while building key list\n");
               ret = KEYSERVER_NO_MEMORY;
               goto leave;
@@ -402,7 +402,7 @@ main (int argc, char *argv[])
                "key retrieval by name\n");
       goto leave;
     }
-  
+
   /* Send the response */
   fprintf (output, "VERSION %d\n", KEYSERVER_PROTO_VERSION);
   fprintf (output, "PROGRAM %s\n\n", VERSION);
@@ -413,13 +413,13 @@ main (int argc, char *argv[])
         fprintf (console, "User:\t\t%s\n", opt->opaque);
       fprintf (console, "Command:\tGET\n");
     }
-  
+
   for (akey = keylist; akey; akey = akey->next)
     {
       set_timeout (opt->timeout);
       if ( get_key (adns_ctx, akey->str) )
         failed++;
-    }      
+    }
   if (!failed)
     ret = KEYSERVER_OK;
 
index 9f99b28..f24a571 100644 (file)
 #include "util.h"
 #endif
 
-
-#if HAVE_W32_SYSTEM
-# if !defined(__MINGW64_VERSION_MAJOR) || !defined(__MINGW32_MAJOR_VERSION)
-   /* This is mingw32 with bogus ldap definitions; i.e. Unix style
-      LDAP definitions.  */
-#  define my_ldap_start_tls_s(a,b,c) ldap_start_tls_sA ((a),(b),(c))
-# else
-   /* Standard Microsoft or mingw64.  */
-#  define my_ldap_start_tls_s(a,b,c) ldap_start_tls_sA ((a),NULL,NULL,(b),(c))
-# endif
-#else /*!W32*/
-# define my_ldap_start_tls_s(a,b,c) ldap_start_tls_s ((a),(b),(c))
-#endif /*!W32*/
-
-
 extern char *optarg;
 extern int optind;
 
@@ -470,7 +455,7 @@ build_attrs(LDAPMod ***modlist,char *line)
          case 'R':
            revoked=1;
            break;
-           
+
          case 'd':
          case 'D':
            disabled=1;
@@ -1052,7 +1037,7 @@ get_key(char *getkey)
   else
     {
       /* short key id */
-    
+
       sprintf(search,"(pgpkeyid=%.8s)",getkey);
     }
 
@@ -1782,12 +1767,12 @@ find_basekeyspacedn(void)
        }
 
       ldap_msgfree(si_res);
-    }   
+    }
 
   return LDAP_SUCCESS;
 }
 
-static void 
+static void
 show_help (FILE *fp)
 {
   fprintf (fp,"-h, --help\thelp\n");
@@ -1809,7 +1794,7 @@ main(int argc,char *argv[])
   /* Kludge to implement standard GNU options.  */
   if (argc > 1 && !strcmp (argv[1], "--version"))
     {
-      fputs ("gpgkeys_ldap (GnuPG) " VERSION"\n", stdout);
+      fputs ("gpgkeys_ldap ("GNUPG_NAME") " VERSION"\n", stdout);
       return 0;
     }
   else if (argc > 1 && !strcmp (argv[1], "--help"))
@@ -1834,7 +1819,7 @@ main(int argc,char *argv[])
        output=fopen(optarg,"w");
        if(output==NULL)
          {
-           fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+           fprintf(console,"gpgkeys: Cannot open output file '%s': %s\n",
                    optarg,strerror(errno));
            return KEYSERVER_INTERNAL_ERROR;
          }
@@ -1847,7 +1832,7 @@ main(int argc,char *argv[])
       input=fopen(argv[optind],"r");
       if(input==NULL)
        {
-         fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+         fprintf(console,"gpgkeys: Cannot open input file '%s': %s\n",
                  argv[optind],strerror(errno));
          return KEYSERVER_INTERNAL_ERROR;
        }
@@ -2204,7 +2189,7 @@ main(int argc,char *argv[])
 #endif
 
          if(err==LDAP_SUCCESS)
-           err = my_ldap_start_tls_s (ldap, NULL, NULL);
+           err=ldap_start_tls_s(ldap,NULL,NULL);
 
          if(err!=LDAP_SUCCESS)
            {
index 0ba09cd..1f85f16 100644 (file)
  */
 
 #include <config.h>
-#include <signal.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
 #ifdef HAVE_W32_SYSTEM
-# ifdef HAVE_WINSOCK2_H
-#  include <winsock2.h>
-# endif
-# include <windows.h>
+#include <windows.h>
 #endif
 
 #ifdef HAVE_LIBCURL
@@ -81,7 +80,7 @@ register_timeout(void)
   sigemptyset(&act.sa_mask);
   act.sa_flags=0;
   return sigaction(SIGALRM,&act,NULL);
-#else
+#else 
   if(signal(SIGALRM,catch_alarm)==SIG_ERR)
     return -1;
   else
@@ -112,12 +111,6 @@ init_ks_options(void)
 {
   struct ks_options *opt;
 
-#ifndef HAVE_LIBCURL
-  /* Without cURL we use our own HTTP module which uses our logging
-     subsystem.  Thus we need to init that.  */
-  log_set_prefix ("gpgkeys", JNLIB_LOG_WITH_PREFIX);
-#endif /*!HAVE_LIBCURL*/
-
   opt=calloc(1,sizeof(struct ks_options));
 
   if(opt)
@@ -606,7 +599,7 @@ ks_hextobyte (const char *s)
 
 
 /* Non localized version of toupper.  */
-int
+int 
 ks_toupper (int c)
 {
   if (c >= 'a' && c <= 'z')
index 218bc86..d466275 100644 (file)
@@ -1,4 +1,4 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        * libcurl.m4: Fix lost hash sign introduced by previous change.
        Reported by John Marshall.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-08-10  Werner Koch  <wk@g10code.com>
 
        * readline.m4, libcurl.m4: Fix use of AC_LANG_PROGRAM.
        * libcurl.m4: s/ifelse/m4_if/.
 
+2011-02-25  Werner Koch  <wk@g10code.com>
+
+       * ksba.m4: Update from git master.
+
+2011-02-23  Werner Koch  <wk@g10code.com>
+
+       * libgcrypt.m4, gpg-error.m4: Update from their GIT masters.
+
+2010-06-08  Werner Koch  <wk@g10code.com>
+
+       * ldap.m4 (gnupg_have_ldap): Set variable.
+
 2009-09-03  Werner Koch  <wk@g10code.com>
 
        * estream.m4: Update for libestream.
        * uintmax_t.m4: New file, from gettext-0.11.5.
        * ulonglong.m4: New file, from gettext-0.11.5.
        * Makefile.am: New file.
+
+Local Variables:
+buffer-read-only: t
+End:
index c5ac24f..f1b8df9 100644 (file)
@@ -4,17 +4,10 @@ EXTRA_DIST += ldap.m4 libcurl.m4 libusb.m4 tar-ustar.m4 readline.m4
 
 EXTRA_DIST += gnupg-pth.m4
 
-EXTRA_DIST += gpg-error.m4 libgcrypt.m4 libassuan.m4 ksba.m4
+EXTRA_DIST += gpg-error.m4 libgcrypt.m4 libassuan.m4 ksba.m4 ntbtls.m4
 
 EXTRA_DIST += autobuild.m4
 
-EXTRA_DIST += estream.m4
-
 EXTRA_DIST += sys_socket_h.m4 socklen.m4
 
 EXTRA_DIST += ChangeLog-2011
-
-
-
-
-
diff --git a/m4/estream.m4 b/m4/estream.m4
deleted file mode 100644 (file)
index b61059a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-dnl Autoconf macros for libestream
-dnl       Copyright (C) 2007 g10 Code GmbH
-dnl
-dnl This file is free software; as a special exception the author gives
-dnl unlimited permission to copy and/or distribute it, with or without
-dnl modifications, as long as this notice is preserved.
-dnl
-dnl This file is distributed in the hope that it will be useful, but
-dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-
-dnl estream_PRINTF_INIT
-dnl Prepare build of source included estream-printf.c
-dnl
-AC_DEFUN([estream_PRINTF_INIT],
-[ 
-  AC_MSG_NOTICE([checking system features for estream-printf])
-  AC_CHECK_HEADERS(stdint.h)
-  AC_TYPE_LONG_LONG_INT  
-  AC_TYPE_LONG_DOUBLE  
-  AC_TYPE_INTMAX_T
-  AC_TYPE_UINTMAX_T
-  AC_CHECK_TYPES([ptrdiff_t])
-  AC_CHECK_SIZEOF([unsigned long])
-  AC_CHECK_SIZEOF([void *])
-  AC_CACHE_CHECK([for nl_langinfo and THOUSANDS_SEP],
-                  estream_cv_langinfo_thousands_sep,
-      [AC_TRY_LINK([#include <langinfo.h>],
-        [char* cs = nl_langinfo(THOUSANDS_SEP); return !cs;],
-        estream_cv_langinfo_thousands_sep=yes,
-        estream_cv_langinfo_thousands_sep=no)
-      ])
-  if test $estream_cv_langinfo_thousands_sep = yes; then
-    AC_DEFINE(HAVE_LANGINFO_THOUSANDS_SEP, 1,
-      [Define if you have <langinfo.h> and nl_langinfo(THOUSANDS_SEP).])
-  fi
-])
-
-
-dnl estream_INIT
-dnl Prepare build of source included estream.c
-dnl
-AC_DEFUN([estream_INIT],
-[ 
-  AC_REQUIRE([estream_PRINTF_INIT])
-  AC_MSG_NOTICE([checking system features for estream])
-
-])
index be247bf..c9ae1f7 100644 (file)
@@ -1,5 +1,5 @@
-# gettext.m4 serial 66 (gettext-0.18.2)
-dnl Copyright (C) 1995-2014 Free Software Foundation, Inc.
+# gettext.m4 serial 60 (gettext-0.17)
+dnl Copyright (C) 1995-2007 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -15,7 +15,7 @@ dnl They are *not* in the public domain.
 
 dnl Authors:
 dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2006.
 
 dnl Macro to add for using GNU gettext.
 
@@ -35,7 +35,7 @@ dnl    will be ignored.  If NEEDSYMBOL is specified and is
 dnl    'need-formatstring-macros', then GNU gettext implementations that don't
 dnl    support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
 dnl INTLDIR is used to find the intl libraries.  If empty,
-dnl    the value '$(top_builddir)/intl/' is used.
+dnl    the value `$(top_builddir)/intl/' is used.
 dnl
 dnl The result of the configuration is one of three cases:
 dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
@@ -60,8 +60,6 @@ AC_DEFUN([AM_GNU_GETTEXT],
   ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
     [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
 ])])])])])
-  ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
-    [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
   ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
     [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
 ])])])])
@@ -97,7 +95,7 @@ AC_DEFUN([AM_GNU_GETTEXT],
     AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
   ])
 
-  dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation.
+  dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
   gt_INTL_MACOSX
 
   dnl Set USE_NLS.
@@ -125,11 +123,11 @@ AC_DEFUN([AM_GNU_GETTEXT],
     gt_use_preinstalled_gnugettext=no
     ifelse(gt_included_intl, yes, [
       AC_MSG_CHECKING([whether included gettext is requested])
-      AC_ARG_WITH([included-gettext],
+      AC_ARG_WITH(included-gettext,
         [  --with-included-gettext use the GNU gettext library included here],
         nls_cv_force_use_gnu_gettext=$withval,
         nls_cv_force_use_gnu_gettext=no)
-      AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
+      AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
 
       nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
       if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
@@ -157,18 +155,12 @@ changequote([,])dnl
         fi
 
         AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
-         [AC_LINK_IFELSE(
-            [AC_LANG_PROGRAM(
-               [[
-#include <libintl.h>
+         [AC_TRY_LINK([#include <libintl.h>
 $gt_revision_test_code
 extern int _nl_msg_cat_cntr;
-extern int *_nl_domain_bindings;
-               ]],
-               [[
-bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
-               ]])],
+extern int *_nl_domain_bindings;],
+            [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
             [eval "$gt_func_gnugettext_libc=yes"],
             [eval "$gt_func_gnugettext_libc=no"])])
 
@@ -189,47 +181,35 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_b
             gt_save_LIBS="$LIBS"
             LIBS="$LIBS $LIBINTL"
             dnl Now see whether libintl exists and does not depend on libiconv.
-            AC_LINK_IFELSE(
-              [AC_LANG_PROGRAM(
-                 [[
-#include <libintl.h>
+            AC_TRY_LINK([#include <libintl.h>
 $gt_revision_test_code
 extern int _nl_msg_cat_cntr;
 extern
 #ifdef __cplusplus
 "C"
 #endif
-const char *_nl_expand_alias (const char *);
-                 ]],
-                 [[
-bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
-                 ]])],
+const char *_nl_expand_alias (const char *);],
+              [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
               [eval "$gt_func_gnugettext_libintl=yes"],
               [eval "$gt_func_gnugettext_libintl=no"])
             dnl Now see whether libintl exists and depends on libiconv.
             if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
               LIBS="$LIBS $LIBICONV"
-              AC_LINK_IFELSE(
-                [AC_LANG_PROGRAM(
-                   [[
-#include <libintl.h>
+              AC_TRY_LINK([#include <libintl.h>
 $gt_revision_test_code
 extern int _nl_msg_cat_cntr;
 extern
 #ifdef __cplusplus
 "C"
 #endif
-const char *_nl_expand_alias (const char *);
-                   ]],
-                   [[
-bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
-                   ]])],
-                [LIBINTL="$LIBINTL $LIBICONV"
-                 LTLIBINTL="$LTLIBINTL $LTLIBICONV"
-                 eval "$gt_func_gnugettext_libintl=yes"
-                ])
+const char *_nl_expand_alias (const char *);],
+                [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+               [LIBINTL="$LIBINTL $LIBICONV"
+                LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+                eval "$gt_func_gnugettext_libintl=yes"
+               ])
             fi
             CPPFLAGS="$gt_save_CPPFLAGS"
             LIBS="$gt_save_LIBS"])
@@ -287,7 +267,7 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a
 
     if test "$gt_use_preinstalled_gnugettext" = "yes" \
        || test "$nls_cv_use_gnu_gettext" = "yes"; then
-      AC_DEFINE([ENABLE_NLS], [1],
+      AC_DEFINE(ENABLE_NLS, 1,
         [Define to 1 if translation of program messages to the user's native language
    is requested.])
     else
@@ -321,9 +301,9 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a
       fi
 
       dnl For backward compatibility. Some packages may be using this.
-      AC_DEFINE([HAVE_GETTEXT], [1],
+      AC_DEFINE(HAVE_GETTEXT, 1,
        [Define if the GNU gettext() function is already present or preinstalled.])
-      AC_DEFINE([HAVE_DCGETTEXT], [1],
+      AC_DEFINE(HAVE_DCGETTEXT, 1,
        [Define if the GNU dcgettext() function is already present or preinstalled.])
     fi
 
@@ -339,9 +319,9 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a
     fi
 
     dnl Make all variables we use known to autoconf.
-    AC_SUBST([BUILD_INCLUDED_LIBINTL])
-    AC_SUBST([USE_INCLUDED_LIBINTL])
-    AC_SUBST([CATOBJEXT])
+    AC_SUBST(BUILD_INCLUDED_LIBINTL)
+    AC_SUBST(USE_INCLUDED_LIBINTL)
+    AC_SUBST(CATOBJEXT)
 
     dnl For backward compatibility. Some configure.ins may be using this.
     nls_cv_header_intl=
@@ -349,36 +329,36 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a
 
     dnl For backward compatibility. Some Makefiles may be using this.
     DATADIRNAME=share
-    AC_SUBST([DATADIRNAME])
+    AC_SUBST(DATADIRNAME)
 
     dnl For backward compatibility. Some Makefiles may be using this.
     INSTOBJEXT=.mo
-    AC_SUBST([INSTOBJEXT])
+    AC_SUBST(INSTOBJEXT)
 
     dnl For backward compatibility. Some Makefiles may be using this.
     GENCAT=gencat
-    AC_SUBST([GENCAT])
+    AC_SUBST(GENCAT)
 
     dnl For backward compatibility. Some Makefiles may be using this.
     INTLOBJS=
     if test "$USE_INCLUDED_LIBINTL" = yes; then
       INTLOBJS="\$(GETTOBJS)"
     fi
-    AC_SUBST([INTLOBJS])
+    AC_SUBST(INTLOBJS)
 
     dnl Enable libtool support if the surrounding package wishes it.
     INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
-    AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
+    AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX)
   ])
 
   dnl For backward compatibility. Some Makefiles may be using this.
   INTLLIBS="$LIBINTL"
-  AC_SUBST([INTLLIBS])
+  AC_SUBST(INTLLIBS)
 
   dnl Make all documented variables known to autoconf.
-  AC_SUBST([LIBINTL])
-  AC_SUBST([LTLIBINTL])
-  AC_SUBST([POSUB])
+  AC_SUBST(LIBINTL)
+  AC_SUBST(LTLIBINTL)
+  AC_SUBST(POSUB)
 ])
 
 
index 712d6e8..6dc9e0e 100644 (file)
@@ -11,7 +11,7 @@ dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 
 # GNUPG_PTH_VERSION_CHECK(REQUIRED)
-#
+# 
 # If the version is sufficient, HAVE_PTH will be set to yes.
 #
 # Taken and modified from the m4 macros which come with Pth.
@@ -69,7 +69,7 @@ AC_DEFUN([GNUPG_PTH_VERSION_CHECK],
        AC_MSG_RESULT($gnupg_cv_pth_is_sane)
     else
        AC_MSG_RESULT(no)
-    fi
+    fi    
   ])
 
 
@@ -82,7 +82,7 @@ AC_DEFUN([GNUPG_PTH_VERSION_CHECK],
 AC_DEFUN([GNUPG_PATH_PTH],
 [ AC_ARG_WITH(pth-prefix,
              AC_HELP_STRING([--with-pth-prefix=PFX],
-                           [prefix where GNU Pth is installed]),
+                           [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"
@@ -91,7 +91,7 @@ AC_DEFUN([GNUPG_PATH_PTH],
   tmp=ifelse([$1], ,1.3.7,$1)
   if test "$PTH_CONFIG" != "no"; then
     GNUPG_PTH_VERSION_CHECK($tmp)
-    if test $have_pth = yes; then
+    if test $have_pth = yes; then      
        PTH_CFLAGS=`$PTH_CONFIG --cflags`
        PTH_LIBS=`$PTH_CONFIG --ldflags`
        PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs --all`"
index 1661204..1362709 100644 (file)
@@ -26,20 +26,19 @@ dnl is added to the gpg_config_script_warn variable.
 dnl
 AC_DEFUN([AM_PATH_GPG_ERROR],
 [ AC_REQUIRE([AC_CANONICAL_HOST])
-  gpg_error_config_prefix=""
   dnl --with-libgpg-error-prefix=PFX is the preferred name for this option,
   dnl since that is consistent with how our three siblings use the directory/
   dnl package name in --with-$dir_name-prefix=PFX.
   AC_ARG_WITH(libgpg-error-prefix,
-              AC_HELP_STRING([--with-libgpg-error-prefix=PFX],
-                             [prefix where GPG Error is installed (optional)]),
-              [gpg_error_config_prefix="$withval"])
+            AC_HELP_STRING([--with-libgpg-error-prefix=PFX],
+                           [prefix where GPG Error is installed (optional)]),
+     gpg_error_config_prefix="$withval", gpg_error_config_prefix="")
 
   dnl Accept --with-gpg-error-prefix and make it work the same as
   dnl --with-libgpg-error-prefix above, for backwards compatibility,
   dnl but do not document this old, inconsistently-named option.
   AC_ARG_WITH(gpg-error-prefix,,
-              [gpg_error_config_prefix="$withval"])
+     gpg_error_config_prefix="$withval", gpg_error_config_prefix="")
 
   if test x"${GPG_ERROR_CONFIG}" = x ; then
      if test x"${gpg_error_config_prefix}" != x ; then
@@ -64,8 +63,7 @@ AC_DEFUN([AM_PATH_GPG_ERROR],
   min_gpg_error_version=ifelse([$1], ,0.0,$1)
   AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version)
   ok=no
-  if test "$GPG_ERROR_CONFIG" != "no" \
-     && test -f "$GPG_ERROR_CONFIG" ; then
+  if test "$GPG_ERROR_CONFIG" != "no" ; then
     req_major=`echo $min_gpg_error_version | \
                sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
     req_minor=`echo $min_gpg_error_version | \
index 4b29c5f..66bc76f 100644 (file)
@@ -1,5 +1,5 @@
-# iconv.m4 serial 18 (gettext-0.18.2)
-dnl Copyright (C) 2000-2002, 2007-2014 Free Software Foundation, Inc.
+# iconv.m4 serial AM6 (gettext-0.17)
+dnl Copyright (C) 2000-2002, 2007 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -30,55 +30,44 @@ AC_DEFUN([AM_ICONV_LINK],
   dnl Add $INCICONV to CPPFLAGS before performing the following checks,
   dnl because if the user has installed libiconv and not disabled its use
   dnl via --without-libiconv-prefix, he wants to use it. The first
-  dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
+  dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
   am_save_CPPFLAGS="$CPPFLAGS"
   AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
 
-  AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
+  AC_CACHE_CHECK([for iconv], am_cv_func_iconv, [
     am_cv_func_iconv="no, consider installing GNU libiconv"
     am_cv_lib_iconv=no
-    AC_LINK_IFELSE(
-      [AC_LANG_PROGRAM(
-         [[
-#include <stdlib.h>
-#include <iconv.h>
-         ]],
-         [[iconv_t cd = iconv_open("","");
-           iconv(cd,NULL,NULL,NULL,NULL);
-           iconv_close(cd);]])],
-      [am_cv_func_iconv=yes])
+    AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+      [iconv_t cd = iconv_open("","");
+       iconv(cd,NULL,NULL,NULL,NULL);
+       iconv_close(cd);],
+      am_cv_func_iconv=yes)
     if test "$am_cv_func_iconv" != yes; then
       am_save_LIBS="$LIBS"
       LIBS="$LIBS $LIBICONV"
-      AC_LINK_IFELSE(
-        [AC_LANG_PROGRAM(
-           [[
-#include <stdlib.h>
-#include <iconv.h>
-           ]],
-           [[iconv_t cd = iconv_open("","");
-             iconv(cd,NULL,NULL,NULL,NULL);
-             iconv_close(cd);]])],
-        [am_cv_lib_iconv=yes]
-        [am_cv_func_iconv=yes])
+      AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+        [iconv_t cd = iconv_open("","");
+         iconv(cd,NULL,NULL,NULL,NULL);
+         iconv_close(cd);],
+        am_cv_lib_iconv=yes
+        am_cv_func_iconv=yes)
       LIBS="$am_save_LIBS"
     fi
   ])
   if test "$am_cv_func_iconv" = yes; then
-    AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
-      dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
-      dnl Solaris 10.
+    AC_CACHE_CHECK([for working iconv], am_cv_func_iconv_works, [
+      dnl This tests against bugs in AIX 5.1 and HP-UX 11.11.
       am_save_LIBS="$LIBS"
       if test $am_cv_lib_iconv = yes; then
         LIBS="$LIBS $LIBICONV"
       fi
-      AC_RUN_IFELSE(
-        [AC_LANG_SOURCE([[
+      AC_TRY_RUN([
 #include <iconv.h>
 #include <string.h>
 int main ()
 {
-  int result = 0;
   /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
      returns.  */
   {
@@ -95,47 +84,7 @@ int main ()
                             (char **) &inptr, &inbytesleft,
                             &outptr, &outbytesleft);
         if (res == 0)
-          result |= 1;
-        iconv_close (cd_utf8_to_88591);
-      }
-  }
-  /* Test against Solaris 10 bug: Failures are not distinguishable from
-     successful returns.  */
-  {
-    iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
-    if (cd_ascii_to_88591 != (iconv_t)(-1))
-      {
-        static const char input[] = "\263";
-        char buf[10];
-        const char *inptr = input;
-        size_t inbytesleft = strlen (input);
-        char *outptr = buf;
-        size_t outbytesleft = sizeof (buf);
-        size_t res = iconv (cd_ascii_to_88591,
-                            (char **) &inptr, &inbytesleft,
-                            &outptr, &outbytesleft);
-        if (res == 0)
-          result |= 2;
-        iconv_close (cd_ascii_to_88591);
-      }
-  }
-  /* Test against AIX 6.1..7.1 bug: Buffer overrun.  */
-  {
-    iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
-    if (cd_88591_to_utf8 != (iconv_t)(-1))
-      {
-        static const char input[] = "\304";
-        static char buf[2] = { (char)0xDE, (char)0xAD };
-        const char *inptr = input;
-        size_t inbytesleft = 1;
-        char *outptr = buf;
-        size_t outbytesleft = 1;
-        size_t res = iconv (cd_88591_to_utf8,
-                            (char **) &inptr, &inbytesleft,
-                            &outptr, &outbytesleft);
-        if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
-          result |= 4;
-        iconv_close (cd_88591_to_utf8);
+          return 1;
       }
   }
 #if 0 /* This bug could be worked around by the caller.  */
@@ -154,8 +103,7 @@ int main ()
                             (char **) &inptr, &inbytesleft,
                             &outptr, &outbytesleft);
         if ((int)res > 0)
-          result |= 8;
-        iconv_close (cd_88591_to_utf8);
+          return 1;
       }
   }
 #endif
@@ -169,19 +117,13 @@ int main ()
       && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
       /* Try HP-UX names.  */
       && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
-    result |= 16;
-  return result;
-}]])],
-        [am_cv_func_iconv_works=yes],
-        [am_cv_func_iconv_works=no],
-        [
-changequote(,)dnl
-         case "$host_os" in
+    return 1;
+  return 0;
+}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
+        [case "$host_os" in
            aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
            *)            am_cv_func_iconv_works="guessing yes" ;;
-         esac
-changequote([,])dnl
-        ])
+         esac])
       LIBS="$am_save_LIBS"
     ])
     case "$am_cv_func_iconv_works" in
@@ -192,7 +134,7 @@ changequote([,])dnl
     am_func_iconv=no am_cv_lib_iconv=no
   fi
   if test "$am_func_iconv" = yes; then
-    AC_DEFINE([HAVE_ICONV], [1],
+    AC_DEFINE(HAVE_ICONV, 1,
       [Define if you have the iconv() function and it works.])
   fi
   if test "$am_cv_lib_iconv" = yes; then
@@ -205,64 +147,34 @@ changequote([,])dnl
     LIBICONV=
     LTLIBICONV=
   fi
-  AC_SUBST([LIBICONV])
-  AC_SUBST([LTLIBICONV])
+  AC_SUBST(LIBICONV)
+  AC_SUBST(LTLIBICONV)
 ])
 
-dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
-dnl avoid warnings like
-dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
-dnl This is tricky because of the way 'aclocal' is implemented:
-dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
-dnl   Otherwise aclocal's initial scan pass would miss the macro definition.
-dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
-dnl   Otherwise aclocal would emit many "Use of uninitialized value $1"
-dnl   warnings.
-m4_define([gl_iconv_AC_DEFUN],
-  m4_version_prereq([2.64],
-    [[AC_DEFUN_ONCE(
-        [$1], [$2])]],
-    [m4_ifdef([gl_00GNULIB],
-       [[AC_DEFUN_ONCE(
-           [$1], [$2])]],
-       [[AC_DEFUN(
-           [$1], [$2])]])]))
-gl_iconv_AC_DEFUN([AM_ICONV],
+AC_DEFUN([AM_ICONV],
 [
   AM_ICONV_LINK
   if test "$am_cv_func_iconv" = yes; then
     AC_MSG_CHECKING([for iconv declaration])
-    AC_CACHE_VAL([am_cv_proto_iconv], [
-      AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM(
-           [[
+    AC_CACHE_VAL(am_cv_proto_iconv, [
+      AC_TRY_COMPILE([
 #include <stdlib.h>
 #include <iconv.h>
 extern
 #ifdef __cplusplus
 "C"
 #endif
-#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
+#if defined(__STDC__) || defined(__cplusplus)
 size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
 #else
 size_t iconv();
 #endif
-           ]],
-           [[]])],
-        [am_cv_proto_iconv_arg1=""],
-        [am_cv_proto_iconv_arg1="const"])
+], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
       am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
     am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
-    AC_MSG_RESULT([
-         $am_cv_proto_iconv])
-    AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+    AC_MSG_RESULT([$]{ac_t:-
+         }[$]am_cv_proto_iconv)
+    AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
       [Define as const if the declaration of iconv() needs const.])
-    dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
-    m4_ifdef([gl_ICONV_H_DEFAULTS],
-      [AC_REQUIRE([gl_ICONV_H_DEFAULTS])
-       if test -n "$am_cv_proto_iconv_arg1"; then
-         ICONV_CONST="const"
-       fi
-      ])
   fi
 ])
index f4462ca..954f88a 100644 (file)
@@ -17,7 +17,7 @@ AC_DEFUN([GNUPG_CHECK_LDAP],
 # OpenLDAP, circa 1999, was terrible with creating weird dependencies.
 # If all else fails, the user can play guess-the-dependency by using
 # something like ./configure LDAPLIBS="-Lfoo -lbar"
-
+gnupg_have_ldap=no
 AC_ARG_WITH(ldap,
   AC_HELP_STRING([--with-ldap=DIR],[look for the LDAP library in DIR]),
   [_ldap_with=$withval])
@@ -66,6 +66,7 @@ if test x$_ldap_with != xno ; then
         test "$gnupg_cv_func_ldaplber_init" = yes ; then
        LDAPLIBS="$LDAP_LDFLAGS $MY_LDAPLIBS"
        GPGKEYS_LDAP="gpg2keys_ldap$EXEEXT"
+       gnupg_have_ldap=yes
 
        AC_CHECK_FUNCS(ldap_get_option ldap_set_option)
        # The extra test for ldap_start_tls_sA is for W32 because 
index ddc569f..96c4e2c 100644 (file)
@@ -1,56 +1,50 @@
-# lib-ld.m4 serial 6
-dnl Copyright (C) 1996-2003, 2009-2014 Free Software Foundation, Inc.
+# lib-ld.m4 serial 3 (gettext-0.13)
+dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 dnl Subroutines of libtool.m4,
-dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid
-dnl collision with libtool.m4.
+dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
+dnl with libtool.m4.
 
-dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no.
+dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
 AC_DEFUN([AC_LIB_PROG_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
-[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
 case `$LD -v 2>&1 </dev/null` in
 *GNU* | *'with BFD'*)
-  acl_cv_prog_gnu_ld=yes
-  ;;
+  acl_cv_prog_gnu_ld=yes ;;
 *)
-  acl_cv_prog_gnu_ld=no
-  ;;
+  acl_cv_prog_gnu_ld=no ;;
 esac])
 with_gnu_ld=$acl_cv_prog_gnu_ld
 ])
 
-dnl From libtool-2.4. Sets the variable LD.
+dnl From libtool-1.4. Sets the variable LD.
 AC_DEFUN([AC_LIB_PROG_LD],
-[AC_REQUIRE([AC_PROG_CC])dnl
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
 AC_REQUIRE([AC_CANONICAL_HOST])dnl
-
-AC_ARG_WITH([gnu-ld],
-    [AS_HELP_STRING([--with-gnu-ld],
-        [assume the C compiler uses GNU ld [default=no]])],
-    [test "$withval" = no || with_gnu_ld=yes],
-    [with_gnu_ld=no])dnl
-
 # Prepare PATH_SEPARATOR.
 # The user is always right.
 if test "${PATH_SEPARATOR+set}" != set; then
-  # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
-  # contains only /bin. Note that ksh looks also at the FPATH variable,
-  # so we have to set that as well for the test.
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
-    && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
-           || PATH_SEPARATOR=';'
-       }
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
 fi
-
 ac_prog=ld
 if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
-  AC_MSG_CHECKING([for ld used by $CC])
+  AC_MSG_CHECKING([for ld used by GCC])
   case $host in
   *-*-mingw*)
     # gcc leaves a trailing carriage return which upsets mingw
@@ -60,12 +54,12 @@ if test "$GCC" = yes; then
   esac
   case $ac_prog in
     # Accept absolute paths.
-    [[\\/]]* | ?:[[\\/]]*)
-      re_direlt='/[[^/]][[^/]]*/\.\./'
-      # Canonicalize the pathname of ld
-      ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'`
-      while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do
-        ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+    [[\\/]* | [A-Za-z]:[\\/]*)]
+      [re_direlt='/[^/][^/]*/\.\./']
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
       done
       test -z "$LD" && LD="$ac_prog"
       ;;
@@ -83,36 +77,33 @@ elif test "$with_gnu_ld" = yes; then
 else
   AC_MSG_CHECKING([for non-GNU ld])
 fi
-AC_CACHE_VAL([acl_cv_path_LD],
+AC_CACHE_VAL(acl_cv_path_LD,
 [if test -z "$LD"; then
-  acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
   for ac_dir in $PATH; do
-    IFS="$acl_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
       acl_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some variants of GNU ld only accept -v.
+      # but apparently some GNU ld's only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
-      case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in
+      case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
       *GNU* | *'with BFD'*)
-        test "$with_gnu_ld" != no && break
-        ;;
+       test "$with_gnu_ld" != no && break ;;
       *)
-        test "$with_gnu_ld" != yes && break
-        ;;
+       test "$with_gnu_ld" != yes && break ;;
       esac
     fi
   done
-  IFS="$acl_save_ifs"
+  IFS="$ac_save_ifs"
 else
   acl_cv_path_LD="$LD" # Let the user override the test with a path.
 fi])
 LD="$acl_cv_path_LD"
 if test -n "$LD"; then
-  AC_MSG_RESULT([$LD])
+  AC_MSG_RESULT($LD)
 else
-  AC_MSG_RESULT([no])
+  AC_MSG_RESULT(no)
 fi
 test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
 AC_LIB_PROG_LD_GNU
index 3522d99..e3d26fc 100644 (file)
@@ -1,12 +1,12 @@
-# lib-link.m4 serial 26 (gettext-0.18.2)
-dnl Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# lib-link.m4 serial 13 (gettext-0.17)
+dnl Copyright (C) 2001-2007 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 dnl From Bruno Haible.
 
-AC_PREREQ([2.54])
+AC_PREREQ(2.54)
 
 dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
 dnl the libraries corresponding to explicit and implicit dependencies.
@@ -18,9 +18,9 @@ AC_DEFUN([AC_LIB_LINKFLAGS],
 [
   AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
   AC_REQUIRE([AC_LIB_RPATH])
-  pushdef([Name],[m4_translit([$1],[./+-], [____])])
-  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
-                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  define([Name],[translit([$1],[./-], [___])])
+  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
   AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
     AC_LIB_LINKFLAGS_BODY([$1], [$2])
     ac_cv_lib[]Name[]_libs="$LIB[]NAME"
@@ -39,17 +39,16 @@ AC_DEFUN([AC_LIB_LINKFLAGS],
   dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
   dnl results of this search when this library appears as a dependency.
   HAVE_LIB[]NAME=yes
-  popdef([NAME])
-  popdef([Name])
+  undefine([Name])
+  undefine([NAME])
 ])
 
-dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
 dnl searches for libname and the libraries corresponding to explicit and
 dnl implicit dependencies, together with the specified include files and
-dnl the ability to compile and link the specified testcode. The missing-message
-dnl defaults to 'no' and may contain additional hints for the user.
-dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
-dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl the ability to compile and link the specified testcode. If found, it
+dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
+dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
 dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
 dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
 dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
@@ -58,9 +57,9 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
 [
   AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
   AC_REQUIRE([AC_LIB_RPATH])
-  pushdef([Name],[m4_translit([$1],[./+-], [____])])
-  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
-                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  define([Name],[translit([$1],[./-], [___])])
+  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
 
   dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
   dnl accordingly.
@@ -74,26 +73,13 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
 
   AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
     ac_save_LIBS="$LIBS"
-    dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
-    dnl because these -l options might require -L options that are present in
-    dnl LIBS. -l options benefit only from the -L options listed before it.
-    dnl Otherwise, add it to the front of LIBS, because it may be a static
-    dnl library that depends on another static library that is present in LIBS.
-    dnl Static libraries benefit only from the static libraries listed after
-    dnl it.
-    case " $LIB[]NAME" in
-      *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
-      *)       LIBS="$LIB[]NAME $LIBS" ;;
-    esac
-    AC_LINK_IFELSE(
-      [AC_LANG_PROGRAM([[$3]], [[$4]])],
-      [ac_cv_lib[]Name=yes],
-      [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
+    LIBS="$LIBS $LIB[]NAME"
+    AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
     LIBS="$ac_save_LIBS"
   ])
   if test "$ac_cv_lib[]Name" = yes; then
     HAVE_LIB[]NAME=yes
-    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
+    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
     AC_MSG_CHECKING([how to link with lib[]$1])
     AC_MSG_RESULT([$LIB[]NAME])
   else
@@ -109,15 +95,13 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
   AC_SUBST([LIB]NAME)
   AC_SUBST([LTLIB]NAME)
   AC_SUBST([LIB]NAME[_PREFIX])
-  popdef([NAME])
-  popdef([Name])
+  undefine([Name])
+  undefine([NAME])
 ])
 
 dnl Determine the platform dependent parameters needed to use rpath:
 dnl   acl_libext,
 dnl   acl_shlibext,
-dnl   acl_libname_spec,
-dnl   acl_library_names_spec,
 dnl   acl_hardcode_libdir_flag_spec,
 dnl   acl_hardcode_libdir_separator,
 dnl   acl_hardcode_direct,
@@ -130,7 +114,7 @@ AC_DEFUN([AC_LIB_RPATH],
   AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld
   AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
   AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
-  AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
+  AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
     CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
     ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
     . ./conftest.sh
@@ -147,32 +131,11 @@ AC_DEFUN([AC_LIB_RPATH],
   acl_hardcode_direct="$acl_cv_hardcode_direct"
   acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
   dnl Determine whether the user wants rpath handling at all.
-  AC_ARG_ENABLE([rpath],
+  AC_ARG_ENABLE(rpath,
     [  --disable-rpath         do not hardcode runtime library paths],
     :, enable_rpath=yes)
 ])
 
-dnl AC_LIB_FROMPACKAGE(name, package)
-dnl declares that libname comes from the given package. The configure file
-dnl will then not have a --with-libname-prefix option but a
-dnl --with-package-prefix option. Several libraries can come from the same
-dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
-dnl macro call that searches for libname.
-AC_DEFUN([AC_LIB_FROMPACKAGE],
-[
-  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
-                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
-  define([acl_frompackage_]NAME, [$2])
-  popdef([NAME])
-  pushdef([PACK],[$2])
-  pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
-                                     [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
-  define([acl_libsinpackage_]PACKUP,
-    m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1])
-  popdef([PACKUP])
-  popdef([PACK])
-])
-
 dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
 dnl the libraries corresponding to explicit and implicit dependencies.
 dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
@@ -181,23 +144,19 @@ dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
 AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
 [
   AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
-  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
-                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
-  pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
-  pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
-                                     [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
-  pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
+  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
   dnl Autoconf >= 2.61 supports dots in --with options.
-  pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
+  define([N_A_M_E],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit([$1],[.],[_])],[$1])])
   dnl By default, look in $includedir and $libdir.
   use_additional=yes
   AC_LIB_WITH_FINAL_PREFIX([
     eval additional_includedir=\"$includedir\"
     eval additional_libdir=\"$libdir\"
   ])
-  AC_ARG_WITH(P_A_C_K[-prefix],
-[[  --with-]]P_A_C_K[[-prefix[=DIR]  search for ]PACKLIBS[ in DIR/include and DIR/lib
-  --without-]]P_A_C_K[[-prefix     don't search for ]PACKLIBS[ in includedir and libdir]],
+  AC_LIB_ARG_WITH([lib]N_A_M_E[-prefix],
+[  --with-lib]N_A_M_E[-prefix[=DIR]  search for lib$1 in DIR/include and DIR/lib
+  --without-lib]N_A_M_E[-prefix     don't search for lib$1 in includedir and libdir],
 [
     if test "X$withval" = "Xno"; then
       use_additional=no
@@ -210,10 +169,6 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
       else
         additional_includedir="$withval/include"
         additional_libdir="$withval/$acl_libdirstem"
-        if test "$acl_libdirstem2" != "$acl_libdirstem" \
-           && ! test -d "$withval/$acl_libdirstem"; then
-          additional_libdir="$withval/$acl_libdirstem2"
-        fi
       fi
     fi
 ])
@@ -223,9 +178,6 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
   LTLIB[]NAME=
   INC[]NAME=
   LIB[]NAME[]_PREFIX=
-  dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
-  dnl computed. So it has to be reset here.
-  HAVE_LIB[]NAME=
   rpathdirs=
   ltrpathdirs=
   names_already_handled=
@@ -245,7 +197,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
         names_already_handled="$names_already_handled $name"
         dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
         dnl or AC_LIB_HAVE_LINKFLAGS call.
-        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
+        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
         eval value=\"\$HAVE_LIB$uppername\"
         if test -n "$value"; then
           if test "$value" = yes; then
@@ -375,9 +327,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
               dnl Linking with a shared library. We attempt to hardcode its
               dnl directory into the executable's runpath, unless it's the
               dnl standard /usr/lib.
-              if test "$enable_rpath" = no \
-                 || test "X$found_dir" = "X/usr/$acl_libdirstem" \
-                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+              if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then
                 dnl No hardcoding is needed.
                 LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
               else
@@ -465,16 +415,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
             case "$found_dir" in
               */$acl_libdirstem | */$acl_libdirstem/)
                 basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
-                if test "$name" = '$1'; then
-                  LIB[]NAME[]_PREFIX="$basedir"
-                fi
-                additional_includedir="$basedir/include"
-                ;;
-              */$acl_libdirstem2 | */$acl_libdirstem2/)
-                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
-                if test "$name" = '$1'; then
-                  LIB[]NAME[]_PREFIX="$basedir"
-                fi
+                LIB[]NAME[]_PREFIX="$basedir"
                 additional_includedir="$basedir/include"
                 ;;
             esac
@@ -535,11 +476,9 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
                     dnl   3. if it's already present in $LDFLAGS or the already
                     dnl      constructed $LIBNAME,
                     dnl   4. if it doesn't exist as a directory.
-                    if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
-                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+                    if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
                       haveit=
-                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
-                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
                         if test -n "$GCC"; then
                           case $host_os in
                             linux* | gnu* | k*bsd*-gnu) haveit=yes;;
@@ -670,11 +609,6 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
       LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
     done
   fi
-  popdef([P_A_C_K])
-  popdef([PACKLIBS])
-  popdef([PACKUP])
-  popdef([PACK])
-  popdef([NAME])
 ])
 
 dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
@@ -720,8 +654,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
         if test -n "$next"; then
           dir="$next"
           dnl No need to hardcode the standard /usr/lib.
-          if test "X$dir" != "X/usr/$acl_libdirstem" \
-             && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+          if test "X$dir" != "X/usr/$acl_libdirstem"; then
             rpathdirs="$rpathdirs $dir"
           fi
           next=
@@ -730,8 +663,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
             -L) next=yes ;;
             -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
                  dnl No need to hardcode the standard /usr/lib.
-                 if test "X$dir" != "X/usr/$acl_libdirstem" \
-                    && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+                 if test "X$dir" != "X/usr/$acl_libdirstem"; then
                    rpathdirs="$rpathdirs $dir"
                  fi
                  next= ;;
index 31f49e4..a8684e1 100644 (file)
@@ -1,5 +1,5 @@
-# lib-prefix.m4 serial 7 (gettext-0.18)
-dnl Copyright (C) 2001-2005, 2008-2014 Free Software Foundation, Inc.
+# lib-prefix.m4 serial 5 (gettext-0.15)
+dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -153,72 +153,33 @@ AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
   prefix="$acl_save_prefix"
 ])
 
-dnl AC_LIB_PREPARE_MULTILIB creates
-dnl - a variable acl_libdirstem, containing the basename of the libdir, either
-dnl   "lib" or "lib64" or "lib/64",
-dnl - a variable acl_libdirstem2, as a secondary possible value for
-dnl   acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
-dnl   "lib/amd64".
+dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing
+dnl the basename of the libdir, either "lib" or "lib64".
 AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
 [
-  dnl There is no formal standard regarding lib and lib64.
-  dnl On glibc systems, the current practice is that on a system supporting
-  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
-  dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
-  dnl the compiler's default mode by looking at the compiler's library search
-  dnl path. If at least one of its elements ends in /lib64 or points to a
-  dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
-  dnl Otherwise we use the default, namely "lib".
-  dnl On Solaris systems, the current practice is that on a system supporting
-  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
-  dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
-  dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
-  AC_REQUIRE([AC_CANONICAL_HOST])
+  dnl There is no formal standard regarding lib and lib64. The current
+  dnl practice is that on a system supporting 32-bit and 64-bit instruction
+  dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit
+  dnl libraries go under $prefix/lib. We determine the compiler's default
+  dnl mode by looking at the compiler's library search path. If at least
+  dnl of its elements ends in /lib64 or points to a directory whose absolute
+  dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the
+  dnl default, namely "lib".
   acl_libdirstem=lib
-  acl_libdirstem2=
-  case "$host_os" in
-    solaris*)
-      dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
-      dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
-      dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
-      dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
-      dnl symlink is missing, so we set acl_libdirstem2 too.
-      AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
-        [AC_EGREP_CPP([sixtyfour bits], [
-#ifdef _LP64
-sixtyfour bits
-#endif
-           ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
-        ])
-      if test $gl_cv_solaris_64bit = yes; then
-        acl_libdirstem=lib/64
-        case "$host_cpu" in
-          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
-          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+  searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+  if test -n "$searchpath"; then
+    acl_save_IFS="${IFS=       }"; IFS=":"
+    for searchdir in $searchpath; do
+      if test -d "$searchdir"; then
+        case "$searchdir" in
+          */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+          *) searchdir=`cd "$searchdir" && pwd`
+             case "$searchdir" in
+               */lib64 ) acl_libdirstem=lib64 ;;
+             esac ;;
         esac
       fi
-      ;;
-    *)
-      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
-      if test -n "$searchpath"; then
-        acl_save_IFS="${IFS=   }"; IFS=":"
-        for searchdir in $searchpath; do
-          if test -d "$searchdir"; then
-            case "$searchdir" in
-              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
-              */../ | */.. )
-                # Better ignore directories of this form. They are misleading.
-                ;;
-              *) searchdir=`cd "$searchdir" && pwd`
-                 case "$searchdir" in
-                   */lib64 ) acl_libdirstem=lib64 ;;
-                 esac ;;
-            esac
-          fi
-        done
-        IFS="$acl_save_IFS"
-      fi
-      ;;
-  esac
-  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+    done
+    IFS="$acl_save_IFS"
+  fi
 ])
index 6299501..49caecc 100644 (file)
@@ -192,9 +192,10 @@ x=CURLOPT_VERBOSE;
            AC_SUBST(LIBCURL_CPPFLAGS)
            AC_SUBST(LIBCURL)
 
-          _libcurl_vernum=`echo $_libcurl_version | $_libcurl_vernum_parse`
+           _libcurl_vernum=`echo $_libcurl_version | $_libcurl_vernum_parse`
 
-          AC_DEFINE_UNQUOTED(LIBCURL_VERNUM,$_libcurl_vernum,[The version of the libcurl library in packed hex form])
+           AC_DEFINE_UNQUOTED(LIBCURL_VERNUM, $_libcurl_vernum,
+                  [The version of the libcurl library in packed hex form])
 
            for _libcurl_feature in $_libcurl_features ; do
              AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
index 53cdc8b..7967cc2 100644 (file)
--- a/m4/nls.m4
+++ b/m4/nls.m4
@@ -1,6 +1,5 @@
-# nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014 Free Software Foundation,
-dnl Inc.
+# nls.m4 serial 3 (gettext-0.15)
+dnl Copyright (C) 1995-2003, 2005-2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -18,15 +17,15 @@ dnl Authors:
 dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
 dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
 
-AC_PREREQ([2.50])
+AC_PREREQ(2.50)
 
 AC_DEFUN([AM_NLS],
 [
   AC_MSG_CHECKING([whether NLS is requested])
   dnl Default is enabled NLS
-  AC_ARG_ENABLE([nls],
+  AC_ARG_ENABLE(nls,
     [  --disable-nls           do not use Native Language Support],
     USE_NLS=$enableval, USE_NLS=yes)
-  AC_MSG_RESULT([$USE_NLS])
-  AC_SUBST([USE_NLS])
+  AC_MSG_RESULT($USE_NLS)
+  AC_SUBST(USE_NLS)
 ])
diff --git a/m4/npth.m4 b/m4/npth.m4
new file mode 100644 (file)
index 0000000..17c2644
--- /dev/null
@@ -0,0 +1,112 @@
+# npth.m4 - autoconf macro to detect NPTH.
+# Copyright (C) 2002, 2003, 2004, 2011 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This 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.
+
+AC_DEFUN([_AM_PATH_NPTH_CONFIG],
+[ AC_ARG_WITH(npth-prefix,
+            AC_HELP_STRING([--with-npth-prefix=PFX],
+                           [prefix where NPTH is installed (optional)]),
+     npth_config_prefix="$withval", npth_config_prefix="")
+  if test "x$npth_config_prefix" != x ; then
+      NPTH_CONFIG="$npth_config_prefix/bin/npth-config"
+  fi
+  AC_PATH_PROG(NPTH_CONFIG, npth-config, no)
+
+  if test "$NPTH_CONFIG" != "no" ; then
+    npth_version=`$NPTH_CONFIG --version`
+  fi
+  npth_version_major=`echo $npth_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+  npth_version_minor=`echo $npth_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+])
+
+dnl AM_PATH_NPTH([MINIMUM-VERSION,
+dnl               [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libnpth and define NPTH_CFLAGS and NPTH_LIBS.
+dnl
+AC_DEFUN([AM_PATH_NPTH],
+[ AC_REQUIRE([_AM_PATH_NPTH_CONFIG])dnl
+  tmp=ifelse([$1], ,1:0.91,$1)
+  if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+     req_npth_api=`echo "$tmp"     | sed 's/\(.*\):\(.*\)/\1/'`
+     min_npth_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+  else
+     req_npth_api=1
+     min_npth_version="$tmp"
+  fi
+
+  AC_MSG_CHECKING(for NPTH - version >= $min_npth_version)
+  ok=no
+  if test "$NPTH_CONFIG" != "no" ; then
+    req_major=`echo $min_npth_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+    req_minor=`echo $min_npth_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+    if test "$npth_version_major" -gt "$req_major"; then
+        ok=yes
+    else
+        if test "$npth_version_major" -eq "$req_major"; then
+            if test "$npth_version_minor" -gt "$req_minor"; then
+               ok=yes
+            else
+               if test "$npth_version_minor" -eq "$req_minor"; then
+                  ok=yes
+               fi
+            fi
+        fi
+    fi
+  fi
+  if test $ok = yes; then
+    AC_MSG_RESULT([yes ($npth_version)])
+  else
+    AC_MSG_RESULT(no)
+  fi
+  if test $ok = yes; then
+     # If we have a recent NPTH, we should also check that the
+     # API is compatible.
+     if test "$req_npth_api" -gt 0 ; then
+        tmp=`$NPTH_CONFIG --api-version 2>/dev/null || echo 0`
+        if test "$tmp" -gt 0 ; then
+           AC_MSG_CHECKING([NPTH API version])
+           if test "$req_npth_api" -eq "$tmp" ; then
+             AC_MSG_RESULT([okay])
+           else
+             ok=no
+             AC_MSG_RESULT([does not match. want=$req_npth_api got=$tmp])
+           fi
+        fi
+     fi
+  fi
+  if test $ok = yes; then
+    NPTH_CFLAGS=`$NPTH_CONFIG --cflags`
+    NPTH_LIBS=`$NPTH_CONFIG --libs`
+    ifelse([$2], , :, [$2])
+    npth_config_host=`$NPTH_CONFIG --host 2>/dev/null || echo none`
+    if test x"$npth_config_host" != xnone ; then
+      if test x"$npth_config_host" != x"$host" ; then
+        AC_MSG_WARN([[
+***
+*** The config script $NPTH_CONFIG was
+*** built for $npth_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-npth-prefix
+*** to specify a matching config script.
+***]])
+      fi
+    fi
+  else
+    NPTH_CFLAGS=""
+    NPTH_LIBS=""
+    ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(NPTH_CFLAGS)
+  AC_SUBST(NPTH_LIBS)
+])
diff --git a/m4/ntbtls.m4 b/m4/ntbtls.m4
new file mode 100644 (file)
index 0000000..85c8ee9
--- /dev/null
@@ -0,0 +1,137 @@
+dnl Autoconf macros for NTBTLS
+dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; as a special exception the author gives
+dnl unlimited permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+dnl This file is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+dnl AM_PATH_NTBTLS([MINIMUM-VERSION,
+dnl                   [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl
+dnl Test for NTBTLS and define NTBTLS_CFLAGS and NTBTLS_LIBS.
+dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
+dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1.  Using
+dnl this features allows to prevent build against newer versions of libgcrypt
+dnl with a changed API.
+dnl
+AC_DEFUN([AM_PATH_NTBTLS],
+[ AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_ARG_WITH(ntbtls-prefix,
+            AC_HELP_STRING([--with-ntbtls-prefix=PFX],
+                           [prefix where NTBTLS is installed (optional)]),
+     ntbtls_config_prefix="$withval", ntbtls_config_prefix="")
+  if test x"${NTBTLS_CONFIG}" = x ; then
+     if test x"${ntbtls_config_prefix}" != x ; then
+        NTBTLS_CONFIG="${ntbtls_config_prefix}/bin/ntbtls-config"
+     else
+       case "${SYSROOT}" in
+         /*)
+           if test -x "${SYSROOT}/bin/ntbtls-config" ; then
+             NTBTLS_CONFIG="${SYSROOT}/bin/ntbtls-config"
+           fi
+           ;;
+         '')
+           ;;
+          *)
+           AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
+           ;;
+       esac
+     fi
+  fi
+
+  AC_PATH_PROG(NTBTLS_CONFIG, ntbtls-config, no)
+  tmp=ifelse([$1], ,1:1.0.0,$1)
+  if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+     req_ntbtls_api=`echo "$tmp"     | sed 's/\(.*\):\(.*\)/\1/'`
+     min_ntbtls_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+  else
+     req_ntbtls_api=0
+     min_ntbtls_version="$tmp"
+  fi
+
+  AC_MSG_CHECKING(for NTBTLS - version >= $min_ntbtls_version)
+  ok=no
+  if test "$NTBTLS_CONFIG" != "no" ; then
+    req_major=`echo $min_ntbtls_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+    req_minor=`echo $min_ntbtls_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+    req_micro=`echo $min_ntbtls_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+    ntbtls_config_version=`$NTBTLS_CONFIG --version`
+    major=`echo $ntbtls_config_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+    minor=`echo $ntbtls_config_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+    micro=`echo $ntbtls_config_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
+    if test "$major" -gt "$req_major"; then
+        ok=yes
+    else
+        if test "$major" -eq "$req_major"; then
+            if test "$minor" -gt "$req_minor"; then
+               ok=yes
+            else
+               if test "$minor" -eq "$req_minor"; then
+                   if test "$micro" -ge "$req_micro"; then
+                     ok=yes
+                   fi
+               fi
+            fi
+        fi
+    fi
+  fi
+  if test $ok = yes; then
+    AC_MSG_RESULT([yes ($ntbtls_config_version)])
+  else
+    AC_MSG_RESULT(no)
+  fi
+  if test $ok = yes; then
+     # If we have a recent ntbtls, we should also check that the
+     # API is compatible
+     if test "$req_ntbtls_api" -gt 0 ; then
+        tmp=`$NTBTLS_CONFIG --api-version 2>/dev/null || echo 0`
+        if test "$tmp" -gt 0 ; then
+           AC_MSG_CHECKING([NTBTLS API version])
+           if test "$req_ntbtls_api" -eq "$tmp" ; then
+             AC_MSG_RESULT([okay])
+           else
+             ok=no
+             AC_MSG_RESULT([does not match. want=$req_ntbtls_api got=$tmp])
+           fi
+        fi
+     fi
+  fi
+  if test $ok = yes; then
+    NTBTLS_CFLAGS=`$NTBTLS_CONFIG --cflags`
+    NTBTLS_LIBS=`$NTBTLS_CONFIG --libs`
+    ifelse([$2], , :, [$2])
+    ntbtls_config_host=`$NTBTLS_CONFIG --host 2>/dev/null || echo none`
+    if test x"$ntbtls_config_host" != xnone ; then
+      if test x"$ntbtls_config_host" != x"$host" ; then
+  AC_MSG_WARN([[
+***
+*** The config script $NTBTLS_CONFIG was
+*** built for $ntbtls_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-ntbtls-prefix
+*** to specify a matching config script or use \$SYSROOT.
+***]])
+        gpg_config_script_warn="$gpg_config_script_warn ntbtls"
+      fi
+    fi
+  else
+    NTBTLS_CFLAGS=""
+    NTBTLS_LIBS=""
+    ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(NTBTLS_CFLAGS)
+  AC_SUBST(NTBTLS_LIBS)
+])
index 84659ea..0734762 100644 (file)
--- a/m4/po.m4
+++ b/m4/po.m4
@@ -1,5 +1,5 @@
-# po.m4 serial 22 (gettext-0.19)
-dnl Copyright (C) 1995-2014 Free Software Foundation, Inc.
+# po.m4 serial 15 (gettext-0.17)
+dnl Copyright (C) 1995-2007 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -17,20 +17,19 @@ dnl Authors:
 dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
 dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
 
-AC_PREREQ([2.60])
+AC_PREREQ(2.50)
 
 dnl Checks for all prerequisites of the po subdirectory.
 AC_DEFUN([AM_PO_SUBDIRS],
 [
   AC_REQUIRE([AC_PROG_MAKE_SET])dnl
   AC_REQUIRE([AC_PROG_INSTALL])dnl
-  AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-  AC_REQUIRE([AC_PROG_SED])dnl
+  AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
   AC_REQUIRE([AM_NLS])dnl
 
   dnl Release version of the gettext macros. This is used to ensure that
   dnl the gettext macros and po/Makefile.in.in are in sync.
-  AC_SUBST([GETTEXT_MACRO_VERSION], [0.19])
+  AC_SUBST([GETTEXT_MACRO_VERSION], [0.17])
 
   dnl Perform the following tests also if --disable-nls has been given,
   dnl because they are needed for "make dist" to work.
@@ -42,7 +41,7 @@ AC_DEFUN([AM_PO_SUBDIRS],
     [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
      (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
     :)
-  AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
+  AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
 
   dnl Test whether it is GNU msgfmt >= 0.15.
 changequote(,)dnl
@@ -103,7 +102,7 @@ changequote([,])dnl
       case "$ac_file" in */Makefile.in)
         # Adjust a relative srcdir.
         ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
-        ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'`
+        ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
         ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
         # In autoconf-2.13 it is called $ac_given_srcdir.
         # In autoconf-2.50 it is called $srcdir.
@@ -119,8 +118,7 @@ changequote([,])dnl
         if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
           rm -f "$ac_dir/POTFILES"
           test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
-          gt_tab=`printf '\t'`
-          cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+          cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[  ]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
           POMAKEFILEDEPS="POTFILES.in"
           # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
           # on $ac_dir but don't depend on user-specified configuration
@@ -131,12 +129,12 @@ changequote([,])dnl
               test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
             fi
             ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
-            # Hide the ALL_LINGUAS assignment from automake < 1.5.
+            # Hide the ALL_LINGUAS assigment from automake < 1.5.
             eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
             POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
           else
             # The set of available languages was given in configure.in.
-            # Hide the ALL_LINGUAS assignment from automake < 1.5.
+            # Hide the ALL_LINGUAS assigment from automake < 1.5.
             eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
           fi
           # Compute POFILES
@@ -228,7 +226,7 @@ AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
 changequote(,)dnl
   # Adjust a relative srcdir.
   ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
-  ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'`
+  ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
   ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
   # In autoconf-2.13 it is called $ac_given_srcdir.
   # In autoconf-2.50 it is called $srcdir.
@@ -256,7 +254,6 @@ EOT
   fi
 
   # A sed script that extracts the value of VARIABLE from a Makefile.
-  tab=`printf '\t'`
   sed_x_variable='
 # Test if the hold space is empty.
 x
@@ -264,9 +261,9 @@ s/P/P/
 x
 ta
 # Yes it was empty. Look if we have the expected variable definition.
-/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=/{
+/^[     ]*VARIABLE[     ]*=/{
   # Seen the first line of the variable definition.
-  s/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=//
+  s/^[  ]*VARIABLE[     ]*=//
   ba
 }
 bd
@@ -318,7 +315,7 @@ changequote([,])dnl
     sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
     ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
   fi
-  # Hide the ALL_LINGUAS assignment from automake < 1.5.
+  # Hide the ALL_LINGUAS assigment from automake < 1.5.
   eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
   # Compute POFILES
   # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
@@ -408,15 +405,14 @@ changequote([,])dnl
   fi
 
   sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
-  tab=`printf '\t'`
   if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
     # Add dependencies that cannot be formulated as a simple suffix rule.
     for lang in $ALL_LINGUAS; do
       frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
       cat >> "$ac_file.tmp" <<EOF
 $frobbedlang.msg: $lang.po
-${tab}@echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
-${tab}\$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+       @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+       \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
 EOF
     done
   fi
@@ -426,8 +422,8 @@ EOF
       frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
       cat >> "$ac_file.tmp" <<EOF
 $frobbedlang/\$(DOMAIN).resources.dll: $lang.po
-${tab}@echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
-${tab}\$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+       @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
+       \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
 EOF
     done
   fi
index b499f79..a56365c 100644 (file)
@@ -1,5 +1,5 @@
-# progtest.m4 serial 7 (gettext-0.18.2)
-dnl Copyright (C) 1996-2003, 2005, 2008-2014 Free Software Foundation, Inc.
+# progtest.m4 serial 4 (gettext-0.14.2)
+dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -16,7 +16,7 @@ dnl They are *not* in the public domain.
 dnl Authors:
 dnl   Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-AC_PREREQ([2.50])
+AC_PREREQ(2.50)
 
 # Search path for a program which passes the given test.
 
@@ -27,14 +27,15 @@ AC_DEFUN([AM_PATH_PROG_WITH_TEST],
 # Prepare PATH_SEPARATOR.
 # The user is always right.
 if test "${PATH_SEPARATOR+set}" != set; then
-  # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
-  # contains only /bin. Note that ksh looks also at the FPATH variable,
-  # so we have to set that as well for the test.
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
-    && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
-           || PATH_SEPARATOR=';'
-       }
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
 fi
 
 # Find out how to test for executable files. Don't use a zero-byte file,
@@ -54,7 +55,7 @@ rm -f conf$$.file
 # Extract the first word of "$2", so it can be a program name with args.
 set dummy $2; ac_word=[$]2
 AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL([ac_cv_path_$1],
+AC_CACHE_VAL(ac_cv_path_$1,
 [case "[$]$1" in
   [[\\/]]* | ?:[[\\/]]*)
     ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
@@ -83,9 +84,9 @@ ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
 esac])dnl
 $1="$ac_cv_path_$1"
 if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
-  AC_MSG_RESULT([$][$1])
+  AC_MSG_RESULT([$]$1)
 else
-  AC_MSG_RESULT([no])
+  AC_MSG_RESULT(no)
 fi
-AC_SUBST([$1])dnl
+AC_SUBST($1)dnl
 ])
index 783f401..0c9619d 100644 (file)
@@ -10,6 +10,7 @@ dnl
 dnl Defines HAVE_LIBREADLINE to 1 if a working readline setup is
 dnl found, and sets @LIBREADLINE@ to the necessary libraries.
 
+
 AC_DEFUN([GNUPG_CHECK_READLINE],
 [
   AC_ARG_WITH(readline,
@@ -17,6 +18,7 @@ AC_DEFUN([GNUPG_CHECK_READLINE],
        [look for the readline library in DIR]),
      [_do_readline=$withval],[_do_readline=yes])
 
+  gnupg_cv_have_readline=no
   if test "$_do_readline" != "no" ; then
      if test -d "$withval" ; then
         CPPFLAGS="${CPPFLAGS} -I$withval/include"
@@ -51,6 +53,7 @@ rl_completion_matches(NULL,NULL);
            AC_DEFINE(HAVE_LIBREADLINE,1,
              [Define to 1 if you have a fully functional readline library.])
            AC_SUBST(LIBREADLINE,$_combo)
+           gnupg_cv_have_readline=yes
            break
         fi
      done
index 6c1d897..3615b74 100644 (file)
@@ -1,50 +1,41 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-01-12  Jakub Bogusz <qboosh@pld-linux.org>  (wk)
+2011-05-12  Marcus Brinkmann  <marcus@g10code.com>
 
-       * pl.po: Update.
+       * cs.po: Merge in dirmngr cs.po.  Hope I got that right.
 
-2011-01-12  Petr Pisar  <petr.pisar@atlas.cz>  (wk)
+2011-01-20  Werner Koch  <wk@g10code.com>
 
-       * cs.po: Update.
+       * de.po: Fix two fuzzies.
 
-2011-01-12  Jedi  <JediLin@Gmail.com>  (wk)
+2010-10-21  Werner Koch  <wk@g10code.com>
 
-       * zh_TW.po: Update.
-
-2011-01-12  Daniel Nylander  <po@danielnylander.se>  (wk)
-
-       * sv.po: Update.
-
-2010-09-03  Werner Koch  <wk@g10code.com>
-
-       * de.po: Insert missing spaces.  Fixes Debian-Bug#594489.
+       * POTFILES.in: Add files in dirmngr/.
+       * de.po: Translate the dirmngr strings.
 
-2010-07-19  Jedi  <JediLin@Gmail.com>  (wk)
+2010-10-18  Werner Koch  <wk@g10code.com>
 
-       * zh_TW.po: Update.
-
-2010-05-12  Jedi  <JediLin@Gmail.com>  (wk)
-
-       * zh_TW.po: Update (dated 2010-03-10).
+       * de.po: Update.
 
-2010-02-17  Werner Koch  <wk@g10code.com>
+       * POTFILES.in: Add cvt-openpgp.c
 
-       * de.po: Replace "Unterschrift" by "Signatur".
-       (keygen.c): Use Abbrechen instead of Quit.
+       * LINGUAS: Re-enable de.po.
 
-2009-12-21  Jedi Lin  <Jedi@Jedi.org>  (wk)
+2010-04-13  Marcus Brinkmann  <marcus@g10code.de>
 
-       * zh_TW.po: Update (dated 2009-09-05).
+       * POTFILES.in: Replace common/exechelp.c by
+       common/exechelp-posix.c, common/exechelp-w32.c and
+       common/exechelp-w32ce.c.
 
-2009-12-04  Petr Pisar <petr.pisar@atlas.cz>  (wk)
+2009-10-16  Marcus Brinkmann  <marcus@g10code.com>
 
-       * cs.po: Update.
+       * POTFILES.in: g10/encode.c was renamed to g10/encrypt.c, and
+       encr-data.c was renamed to decrypt-data.c
 
 2009-09-03  Werner Koch  <wk@g10code.com>
 
        * POTFILES.in: New.
        * de.po: New.
 
-
  Copyright 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 9d22331..686d277 100644 (file)
@@ -1,31 +1,30 @@
-en@quot
-en@boldquot
-be
-ca
-cs
-da
+#en@quot
+#en@boldquot
+#be
+#ca
+#cs
+#da
 de
-eo
-el
-es
-et
-fi
+#eo
+#el
+#es
+#et
+#fi
 fr
-gl
-hu
-id
-it
+#gl
+#hu
+#id
+#it
 ja
-nb
-nl
-pl
-pt_BR
-pt
-ro
-ru
-sk
-sv
-tr
+#nb
+#pl
+#pt_BR
+#pt
+#ro
+#ru
+#sk
+#sv
+#tr
 uk
-zh_TW
-zh_CN
+#zh_TW
+#zh_CN
index 65184f6..eb68ea2 100644 (file)
@@ -1,5 +1,5 @@
 # Makefile for PO directory in any package using GNU gettext.
-# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+# Copyright (C) 1995-1997, 2000-2007 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
 #
 # This file can be copied and used freely without restrictions.  It can
 # be used in projects which are not available under the GNU General Public
@@ -8,14 +8,13 @@
 # Please note that the actual code of GNU gettext is covered by the GNU
 # General Public License and is *not* in the public domain.
 #
-# Origin: gettext-0.19
-GETTEXT_MACRO_VERSION = 0.19
+# Origin: gettext-0.17
+GETTEXT_MACRO_VERSION = 0.17
 
 PACKAGE = @PACKAGE@
 VERSION = @VERSION@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 
-SED = @SED@
 SHELL = /bin/sh
 @SET_MAKE@
 
@@ -57,8 +56,8 @@ XGETTEXT_ = @XGETTEXT@
 XGETTEXT_no = @XGETTEXT@
 XGETTEXT_yes = @XGETTEXT_015@
 XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-MSGMERGE = msgmerge
-MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGMERGE = msgmerge --previous
+MSGMERGE_UPDATE = @MSGMERGE@ --previous --update
 MSGINIT = msginit
 MSGCONV = msgconv
 MSGFILTER = msgfilter
@@ -77,16 +76,6 @@ POTFILES = \
 
 CATALOGS = @CATALOGS@
 
-POFILESDEPS_ = $(srcdir)/$(DOMAIN).pot
-POFILESDEPS_yes = $(POFILESDEPS_)
-POFILESDEPS_no =
-POFILESDEPS = $(POFILESDEPS_$(PO_DEPENDS_ON_POT))
-
-DISTFILESDEPS_ = update-po
-DISTFILESDEPS_yes = $(DISTFILESDEPS_)
-DISTFILESDEPS_no =
-DISTFILESDEPS = $(DISTFILESDEPS_$(DIST_DEPENDS_ON_UPDATE_PO))
-
 # Makevars gets inserted here. (Don't remove this line!)
 
 .SUFFIXES:
@@ -99,22 +88,22 @@ DISTFILESDEPS = $(DISTFILESDEPS_$(DIST_DEPENDS_ON_UPDATE_PO))
 .po.gmo:
        @lang=`echo $* | sed -e 's,.*/,,'`; \
        test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
-       echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
-       cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+       echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \
+       cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
 
 .sin.sed:
        sed -e '/^#/d' $< > t-$@
        mv t-$@ $@
 
 
-all: all-@USE_NLS@
+all: check-macro-version all-@USE_NLS@
 
 all-yes: stamp-po
 all-no:
 
 # Ensure that the gettext macros and this Makefile.in.in are in sync.
-CHECK_MACRO_VERSION = \
-       test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
+check-macro-version:
+       @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
          || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
               exit 1; \
             }
@@ -134,7 +123,6 @@ CHECK_MACRO_VERSION = \
 # $(POFILES) has been designed to not touch files that don't need to be
 # changed.
 stamp-po: $(srcdir)/$(DOMAIN).pot
-       @$(CHECK_MACRO_VERSION)
        test ! -f $(srcdir)/$(DOMAIN).pot || \
          test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
        @test ! -f $(srcdir)/$(DOMAIN).pot || { \
@@ -149,29 +137,11 @@ stamp-po: $(srcdir)/$(DOMAIN).pot
 
 # This target rebuilds $(DOMAIN).pot; it is an expensive operation.
 # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
-# The determination of whether the package xyz is a GNU one is based on the
-# heuristic whether some file in the top level directory mentions "GNU xyz".
-# If GNU 'find' is available, we avoid grepping through monster files.
 $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
-       package_gnu="$(PACKAGE_GNU)"; \
-       test -n "$$package_gnu" || { \
-         if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \
-                LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f \
-                              -size -10000000c -exec grep 'GNU @PACKAGE@' \
-                              /dev/null '{}' ';' 2>/dev/null; \
-              else \
-                LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \
-              fi; \
-            } | grep -v 'libtool:' >/dev/null; then \
-            package_gnu=yes; \
-          else \
-            package_gnu=no; \
-          fi; \
-       }; \
-       if test "$$package_gnu" = "yes"; then \
-         package_prefix='GNU '; \
+       if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \
+         package_gnu='GNU '; \
        else \
-         package_prefix=''; \
+         package_gnu=''; \
        fi; \
        if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
          msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
@@ -191,7 +161,7 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
              --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
              --files-from=$(srcdir)/POTFILES.in \
              --copyright-holder='$(COPYRIGHT_HOLDER)' \
-             --package-name="$${package_prefix}@PACKAGE@" \
+             --package-name="$${package_gnu}@PACKAGE@" \
              --package-version='@VERSION@' \
              --msgid-bugs-address="$$msgid_bugs_address" \
            ;; \
@@ -219,20 +189,12 @@ $(srcdir)/$(DOMAIN).pot:
 
 # This target rebuilds a PO file if $(DOMAIN).pot has changed.
 # Note that a PO file is not touched if it doesn't need to be changed.
-$(POFILES): $(POFILESDEPS)
+$(POFILES): $(srcdir)/$(DOMAIN).pot
        @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
        if test -f "$(srcdir)/$${lang}.po"; then \
-         test -f $(srcdir)/$(DOMAIN).pot || $(MAKE) $(srcdir)/$(DOMAIN).pot; \
          test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
-         echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
-         cd $(srcdir) \
-           && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
-                  '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
-                    $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
-                  *) \
-                    $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
-                esac; \
-              }; \
+         echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \
+         cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \
        else \
          $(MAKE) $${lang}.po-create; \
        fi
@@ -255,6 +217,7 @@ install-data: install-data-@USE_NLS@
        fi
 install-data-no: all
 install-data-yes: all
+       $(mkdir_p) $(DESTDIR)$(datadir)
        @catalogs='$(CATALOGS)'; \
        for cat in $$catalogs; do \
          cat=`basename $$cat`; \
@@ -306,6 +269,7 @@ installdirs-data: installdirs-data-@USE_NLS@
        fi
 installdirs-data-no:
 installdirs-data-yes:
+       $(mkdir_p) $(DESTDIR)$(datadir)
        @catalogs='$(CATALOGS)'; \
        for cat in $$catalogs; do \
          cat=`basename $$cat`; \
@@ -383,7 +347,7 @@ maintainer-clean: distclean
 
 distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 dist distdir:
-       test -z "$(DISTFILESDEPS)" || $(MAKE) $(DISTFILESDEPS)
+       $(MAKE) update-po
        @$(MAKE) dist2
 # This is a separate target because 'update-po' must be executed before.
 dist2: stamp-po $(DISTFILES)
@@ -431,15 +395,9 @@ update-po: Makefile
        tmpdir=`pwd`; \
        echo "$$lang:"; \
        test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
-       echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
+       echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
        cd $(srcdir); \
-       if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
-              '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
-                $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
-              *) \
-                $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
-            esac; \
-          }; then \
+       if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \
          if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
            rm -f $$tmpdir/$$lang.new.po; \
          else \
@@ -460,13 +418,9 @@ $(DUMMYPOFILES):
 update-gmo: Makefile $(GMOFILES)
        @:
 
-# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
-# because execution permission bits may not work on the current file system.
-# Use @SHELL@, which is the shell determined by autoconf for the use by its
-# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
 Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
        cd $(top_builddir) \
-         && @SHELL@ ./config.status $(subdir)/$@.in po-directories
+         && $(SHELL) ./config.status $(subdir)/$@.in po-directories
 
 force:
 
index 5baaf5a..b99cd46 100644 (file)
@@ -20,14 +20,6 @@ XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
 # their copyright.
 COPYRIGHT_HOLDER = Free Software Foundation, Inc.
 
-# This tells whether or not to prepend "GNU " prefix to the package
-# name that gets inserted into the header of the $(DOMAIN).pot file.
-# Possible values are "yes", "no", or empty.  If it is empty, try to
-# detect it automatically by scanning the files in $(top_srcdir) for
-# "GNU packagename" string.
-PACKAGE_GNU = no
-
-
 # This is the email address or URL to which the translators shall report
 # bugs in the untranslated strings:
 # - Strings which are not entire sentences, see the maintainer guidelines
@@ -47,33 +39,3 @@ MSGID_BUGS_ADDRESS = translations@gnupg.org
 # This is the list of locale categories, beyond LC_MESSAGES, for which the
 # message catalogs shall be used.  It is usually empty.
 EXTRA_LOCALE_CATEGORIES =
-
-# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'
-# context.  Possible values are "yes" and "no".  Set this to yes if the
-# package uses functions taking also a message context, like pgettext(), or
-# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.
-USE_MSGCTXT = no
-
-# These options get passed to msgmerge.
-# Useful options are in particular:
-#   --previous            to keep previous msgids of translated messages,
-#   --quiet               to reduce the verbosity.
-MSGMERGE_OPTIONS = --previous
-
-# These options get passed to msginit.
-# If you want to disable line wrapping when writing PO files, add
-# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and
-# MSGINIT_OPTIONS.
-MSGINIT_OPTIONS =
-
-# This tells whether or not to regenerate a PO file when $(DOMAIN).pot
-# has changed.  Possible values are "yes" and "no".  Set this to no if
-# the POT file is checked in the repository and the version control
-# program ignores timestamps.
-PO_DEPENDS_ON_POT = yes
-
-# This tells whether or not to forcibly update $(DOMAIN).pot and
-# regenerate PO files on "make dist".  Possible values are "yes" and
-# "no".  Set this to no if the POT file and PO files are maintained
-# externally.
-DIST_DEPENDS_ON_UPDATE_PO = yes
diff --git a/po/Makevars.template b/po/Makevars.template
new file mode 100644 (file)
index 0000000..32692ab
--- /dev/null
@@ -0,0 +1,41 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = $(PACKAGE)
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding
+# package.  (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.)  Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright.  The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER = Free Software Foundation, Inc.
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+#   in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+#   understood.
+# - Strings which make invalid assumptions about notation of date, time or
+#   money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS =
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used.  It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
index 40ae4c9..6050b1b 100644 (file)
@@ -9,9 +9,12 @@ agent/preset-passphrase.c
 agent/protect-tool.c
 agent/trustlist.c
 agent/findkey.c
-agent/call-pinentry.c
+agent/pksign.c
+agent/cvt-openpgp.c
 
-common/exechelp.c
+common/exechelp-posix.c
+common/exechelp-w32.c
+common/exechelp-w32ce.c
 common/http.c
 common/simple-pwquery.c
 common/sysutils.c
@@ -22,6 +25,12 @@ common/audit.c
 common/helpfile.c
 common/gettime.c
 
+common/argparse.c
+common/logging.c
+common/utf8conv.c
+common/dotlock.c
+
+
 g10/armor.c
 g10/build-packet.c
 g10/call-agent.c
@@ -29,8 +38,8 @@ g10/card-util.c
 g10/dearmor.c
 g10/decrypt.c
 g10/delkey.c
-g10/encode.c
-g10/encr-data.c
+g10/encrypt.c
+g10/decrypt-data.c
 g10/exec.c
 g10/export.c
 g10/getkey.c
@@ -55,7 +64,6 @@ g10/pkclist.c
 g10/plaintext.c
 g10/pubkey-enc.c
 g10/revoke.c
-g10/seckey-cert.c
 g10/seskey.c
 g10/sig-check.c
 g10/sign.c
@@ -66,11 +74,6 @@ g10/textfilter.c
 g10/trustdb.c
 g10/verify.c
 
-jnlib/argparse.c
-jnlib/logging.c
-jnlib/utf8conv.c
-jnlib/dotlock.c
-
 kbx/kbxutil.c
 
 scd/app-nks.c
@@ -100,6 +103,21 @@ sm/qualified.c
 sm/sign.c
 sm/verify.c
 
+dirmngr/certcache.c
+dirmngr/crlcache.c
+dirmngr/crlfetch.c
+dirmngr/dirmngr-client.c
+dirmngr/dirmngr.c
+dirmngr/dirmngr_ldap.c
+dirmngr/ldap-wrapper-ce.c
+dirmngr/ldap-wrapper.c
+dirmngr/ldap.c
+dirmngr/ldapserver.c
+dirmngr/misc.c
+dirmngr/ocsp.c
+dirmngr/server.c
+dirmngr/validate.c
+
 tools/gpg-connect-agent.c
 tools/gpgconf-comp.c
 tools/gpgconf.c
index 9dc9630..9c2a995 100644 (file)
@@ -1,4 +1,3 @@
-# This file, Rules-quot, can be copied and used freely without restrictions.
 # Special Makefile rules for English message catalogs with quotation marks.
 
 DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot
@@ -15,23 +14,13 @@ en@boldquot.po-update: en@boldquot.po-update-en
 
 .insert-header.po-update-en:
        @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \
-       if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
+       if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
        tmpdir=`pwd`; \
        echo "$$lang:"; \
        ll=`echo $$lang | sed -e 's/@.*//'`; \
        LC_ALL=C; export LC_ALL; \
        cd $(srcdir); \
-       if $(MSGINIT) $(MSGINIT_OPTIONS) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null \
-          | $(SED) -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | \
-          { case `$(MSGFILTER) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
-            '' | 0.[0-9] | 0.[0-9].* | 0.1[0-8] | 0.1[0-8].*) \
-              $(MSGFILTER) $(SED) -f `echo $$lang | sed -e 's/.*@//'`.sed \
-              ;; \
-            *) \
-              $(MSGFILTER) `echo $$lang | sed -e 's/.*@//'` \
-              ;; \
-            esac } 2>/dev/null > $$tmpdir/$$lang.new.po \
-            ; then \
+       if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \
          if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
            rm -f $$tmpdir/$$lang.new.po; \
          else \
index d79654f..a9a5e74 100644 (file)
--- a/po/be.po
+++ b/po/be.po
@@ -9,7 +9,6 @@ msgstr ""
 "PO-Revision-Date: 2003-10-30 16:35+0200\n"
 "Last-Translator: Ales Nyakhaychyk <nab@mail.by>\n"
 "Language-Team: Belarusian <i18n@mova.org>\n"
-"Language: be\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -19,41 +18,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "%s: немагчыма стварыць хэш-табліцу: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "паказаць сьпіс ключоў і ID карыстальнікаў"
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "нерэчаісны пароль"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -78,9 +42,6 @@ msgid ""
 "this session"
 msgstr ""
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -116,11 +77,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr ""
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr ""
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -147,20 +108,8 @@ msgstr "грамадскі ключ ня знойдзены"
 msgid "error writing key: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr ""
 "Увядзіце новы пароль для гэтага сакрэтнага ключа.\n"
 "\n"
@@ -169,13 +118,11 @@ msgstr ""
 msgid "Please re-enter this passphrase"
 msgstr "Увядзіце пароль\n"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
-"Увядзіце новы пароль для гэтага сакрэтнага ключа.\n"
-"\n"
 
 msgid "does not match - try again"
 msgstr ""
@@ -202,7 +149,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -286,7 +233,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Увядзіце новы пароль для гэтага сакрэтнага ключа.\n"
 "\n"
@@ -304,10 +251,10 @@ msgstr ""
 "Выбары:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -359,23 +306,16 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "Паўтарыце пароль\n"
 
-msgid "enable ssh support"
-msgstr ""
-
-msgid "enable putty support"
+msgid "enable ssh-agent emulation"
 msgstr ""
 
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "Паўтарыце пароль\n"
-
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
 
@@ -396,7 +336,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -404,23 +344,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr ""
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
 msgid "name of socket too long\n"
@@ -431,7 +371,7 @@ msgid "can't create socket: %s\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -442,7 +382,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
@@ -450,19 +390,19 @@ msgid "listen() failed: %s\n"
 msgstr "збой падпісаньня: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "запіс у stdout\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: тэчка створана\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
 #, fuzzy, c-format
@@ -566,31 +506,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "сакрэтны ключ недаступны"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "памылка чытаньня файла"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -678,15 +618,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
@@ -701,7 +641,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr ""
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr ""
 
 msgid "communication problem with gpg-agent\n"
@@ -776,10 +716,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -806,22 +742,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "дрэнны сэртыфікат"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "дрэнны сэртыфікат"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "дрэнны сэртыфікат"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "дрэнны сэртыфікат"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "дрэнны сэртыфікат"
 
@@ -863,24 +783,9 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Подпіс створаны ў %.*s з выкарыстаньнем %s ID ключа %08lX\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
-msgid "Encryption algorithm supported"
-msgstr ""
-
 msgid "Data verification succeeded"
 msgstr ""
 
@@ -889,11 +794,11 @@ msgid "Signature available"
 msgstr "Подпіс створаны ў %.*s з выкарыстаньнем %s ID ключа %08lX\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
 
 #, fuzzy, c-format
@@ -938,7 +843,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Для \"%s\" даведка адсутнічае"
 
 msgid "ignoring garbage line"
@@ -1098,11 +1003,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 msgid "Login data (account name): "
@@ -1299,8 +1204,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Загад> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1321,7 +1226,7 @@ msgid "--output doesn't work for this command\n"
 msgstr ""
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "немагчыма адкрыць \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1371,18 +1276,18 @@ msgid "using cipher %s\n"
 msgstr "збой падпісаньня: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr ""
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr ""
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr ""
 
 msgid ""
@@ -1438,11 +1343,11 @@ msgid "this platform requires temporary files when calling external programs\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, c-format
@@ -1460,11 +1365,11 @@ msgid "unable to read external program response: %s\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr ""
 
 msgid "export signatures that are marked as local-only"
@@ -1528,15 +1433,11 @@ msgid "[User ID not found]"
 msgstr ""
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr ""
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy
@@ -1555,6 +1456,10 @@ msgstr ""
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr ""
+
 #, fuzzy
 msgid "make a signature"
 msgstr "зрабіць адчэплены подпіс"
@@ -1597,9 +1502,6 @@ msgstr "паказаць сакрэтныя ключы"
 msgid "generate a new key pair"
 msgstr "стварыць новую пару ключоў"
 
-msgid "generate a revocation certificate"
-msgstr ""
-
 msgid "remove keys from the public keyring"
 msgstr "выдаліць ключы са зьвязку грамадскіх ключоў"
 
@@ -1615,9 +1517,8 @@ msgstr "падпісаць ключ толькі мясцова"
 msgid "sign or edit a key"
 msgstr "падпісаць ці рэдагаваць ключ"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "дрэнны пароль"
+msgid "generate a revocation certificate"
+msgstr ""
 
 msgid "export keys"
 msgstr "экспарт ключоў"
@@ -1712,15 +1613,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Выкарыстаньне: gpg [выбары] [файлы] (-h для даведкі)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Сынтаксіс: gpg [выбары] [файлы]\n"
 "sign, check, encrypt ці decrypt\n"
@@ -1752,35 +1648,35 @@ msgid "conflicting commands\n"
 msgstr "несумяшчальныя загады\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
 
 #, c-format
@@ -1789,11 +1685,11 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 
 #, c-format
@@ -1802,11 +1698,11 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "невядомая вэрсыя"
 
 msgid "display photo IDs during key listings"
@@ -1843,7 +1739,7 @@ msgid "show expiration dates during signature listings"
 msgstr ""
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr ""
 
 #, c-format
@@ -1855,11 +1751,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s - гэта недапушчальнае мноства знакаў\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s - гэта недапушчальнае мноства знакаў\n"
 
 msgid "could not parse keyserver URL\n"
@@ -2031,15 +1927,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s ня мае сэнсу разам з %s!\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr ""
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr ""
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr ""
 
 #, c-format
@@ -2056,7 +1952,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [назва_файла]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "збой падпісаньня: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2108,10 +2004,6 @@ msgstr "--lsign-key user-id"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key user-id [загады]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key user-id"
-
 #, fuzzy, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "збой падпісаньня: %s\n"
@@ -2141,7 +2033,7 @@ msgid "enarmoring failed: %s\n"
 msgstr ""
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
 
 msgid "[filename]"
@@ -2182,7 +2074,7 @@ msgid "No help available"
 msgstr "Даведка адсутнічае"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Для \"%s\" даведка адсутнічае"
 
 msgid "import signatures that are marked as local-only"
@@ -2191,9 +2083,6 @@ msgstr ""
 msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
-msgid "do not clear the ownertrust values during import"
-msgstr ""
-
 msgid "do not update the trustdb after import"
 msgstr ""
 
@@ -2309,13 +2198,6 @@ msgstr ""
 msgid "key %s: no user ID\n"
 msgstr "паказаць сьпіс ключоў і ID карыстальнікаў"
 
-#, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "грамадскі ключ ня знойдзены"
-
-msgid "rejected by import filter"
-msgstr ""
-
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr ""
@@ -2344,11 +2226,11 @@ msgid "no writable keyring found: %s\n"
 msgstr ""
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr ""
 
 #, c-format
@@ -2411,19 +2293,15 @@ msgstr "паказаць сьпіс ключоў і подпісаў"
 msgid "key %s: \"%s\" not changed\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "грамадскі ключ ня знойдзены"
+#, c-format
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr ""
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "сакрэтны ключ недаступны"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr ""
-
-#, c-format
 msgid "no default secret keyring: %s\n"
 msgstr ""
 
@@ -2464,15 +2342,11 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "паказаць сьпіс ключоў і ID карыстальнікаў"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
+msgid "key %s: no subkey for key binding\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "%s: тэчка створана\n"
-
 #, c-format
-msgid "key %s: no subkey for key binding\n"
+msgid "key %s: unsupported public key algorithm\n"
 msgstr ""
 
 #, c-format
@@ -2553,15 +2427,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr ""
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr ""
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, c-format
@@ -2734,7 +2608,7 @@ msgstr ""
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr ""
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr ""
 
 #, c-format
@@ -2970,7 +2844,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "падпісаць ключ толькі мясцова"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "невядомая вэрсыя"
 
 #, c-format
@@ -3001,11 +2875,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3089,7 +2963,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr ""
 
 #, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr ""
 
 #, c-format
@@ -3149,12 +3023,6 @@ msgid ""
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-msgid "You may want to change its expiration date too.\n"
-msgstr ""
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3368,7 +3236,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr ""
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr ""
 
 #, fuzzy
@@ -3384,7 +3252,7 @@ msgid "too many compression preferences\n"
 msgstr "за шмат пераваг для \"%c\"\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "недапушчальныя дапомныя перавагі\n"
 
 msgid "writing direct signature\n"
@@ -3602,7 +3470,7 @@ msgid "Invalid character in comment\n"
 msgstr ""
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr ""
 
 #, c-format
@@ -3676,15 +3544,15 @@ msgid "Key generation canceled.\n"
 msgstr ""
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "запіс у stdout\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr ""
 
 #, c-format
@@ -3696,11 +3564,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr ""
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr ""
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr ""
 
 msgid "public and secret key created and signed.\n"
@@ -3736,11 +3604,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "збой падпісаньня: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr ""
 
 msgid "never     "
@@ -3782,15 +3650,11 @@ msgstr ""
 msgid "      Key fingerprint ="
 msgstr "паказаць ключы й адбіткі пальцаў"
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "збой падпісаньня: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -3808,7 +3672,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "немагчыма адкрыць \"%s\"\n"
 
 #, fuzzy, c-format
@@ -3845,7 +3709,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 
 msgid "disabled"
@@ -3909,10 +3773,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "збой падпісаньня: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -3920,11 +3780,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -3939,6 +3799,10 @@ msgstr "збой падпісаньня: %s\n"
 msgid "keyserver internal error\n"
 msgstr "агульная памылка"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "збой падпісаньня: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4112,10 +3976,6 @@ msgid "unknown"
 msgstr "невядомая вэрсыя"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr ""
 
@@ -4137,7 +3997,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, c-format
@@ -4163,10 +4023,6 @@ msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr ""
 
@@ -4199,15 +4055,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr ""
 
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr ""
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr ""
-
 msgid "Uncompressed"
 msgstr ""
 
@@ -4220,15 +4067,15 @@ msgid "this message may not be usable by %s\n"
 msgstr ""
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "невядомая вэрсыя"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Файл \"%s\" ужо йснуе. "
 
 #, fuzzy
@@ -4245,16 +4092,16 @@ msgstr "Увядзіце новае ймя файла"
 msgid "writing to stdout\n"
 msgstr "запіс у stdout\n"
 
-#, fuzzy, c-format
+#, c-format
 msgid "assuming signed data in '%s'\n"
-msgstr "немагчыма адкрыць %s: %s\n"
+msgstr ""
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 
 #, c-format
@@ -4269,10 +4116,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr ""
 
 #, c-format
-msgid "problem with the agent: %s\n"
-msgstr ""
-
-#, c-format
 msgid " (main key ID %s)"
 msgstr ""
 
@@ -4294,6 +4137,10 @@ msgstr "Увядзіце пароль\n"
 msgid "cancelled by user\n"
 msgstr "скасавана карыстальнікам\n"
 
+#, c-format
+msgid "problem with the agent: %s\n"
+msgstr ""
+
 #, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
@@ -4323,7 +4170,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, c-format
@@ -4334,7 +4181,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr ""
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr ""
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4364,16 +4211,6 @@ msgstr ""
 msgid "revocation comment: "
 msgstr ""
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr ""
 
@@ -4470,11 +4307,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4572,7 +4409,7 @@ msgid "no signed data\n"
 msgstr ""
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -4851,7 +4688,7 @@ msgid ""
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy
@@ -4869,25 +4706,17 @@ msgid "ownertrust value missing"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "памылка чытаньня файла"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "%s: немагчыма стварыць тэчку: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "немагчыма адкрыць \"%s\"\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr ""
@@ -4899,13 +4728,21 @@ msgstr ""
 msgid "trustdb transaction too large\n"
 msgstr ""
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "немагчыма адкрыць %s: %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "немагчыма адкрыць %s: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "%s: немагчыма стварыць тэчку: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "немагчыма адкрыць \"%s\"\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -4990,7 +4827,7 @@ msgid "input line longer than %d characters\n"
 msgstr ""
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr ""
 
 #, c-format
@@ -5031,14 +4868,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5089,11 +4918,11 @@ msgid "next trustdb check due at %s\n"
 msgstr ""
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr ""
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5160,10 +4989,6 @@ msgid "missing argument"
 msgstr ""
 
 #, fuzzy
-msgid "invalid argument"
-msgstr "паказаць ключы й адбіткі пальцаў"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "несумяшчальныя загады\n"
 
@@ -5183,10 +5008,6 @@ msgstr "недапушчальныя выбары імпартаваньня\n"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "недапушчальныя выбары імпартаваньня\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5215,8 +5036,12 @@ msgstr "недапушчальныя выбары імпартаваньня\n"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr ""
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "памылка стварэньня \"%s\": %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5224,15 +5049,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "збой падпісаньня: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, c-format
@@ -5250,7 +5075,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "грамадскі ключ ня знойдзены"
 
 #, fuzzy, c-format
@@ -5267,11 +5092,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Выкарыстаньне: gpg [выбары] [файлы] (-h для даведкі)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Выкарыстаньне: gpg [выбары] [файлы] (-h для даведкі)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5400,9 +5224,6 @@ msgstr "Калі ласка, абярыце від ключа, які Вам п
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5412,14 +5233,6 @@ msgstr ""
 msgid "|N|New PIN"
 msgstr ""
 
-#, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "Паўтарыце пароль\n"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "Паўтарыце пароль\n"
-
 msgid "error reading application data\n"
 msgstr ""
 
@@ -5486,9 +5299,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr ""
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "Паўтарыце пароль\n"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5522,16 +5334,13 @@ msgstr ""
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "несумяшчальныя загады\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Выкарыстаньне: gpg [выбары] [файлы] (-h для даведкі)"
@@ -5541,7 +5350,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5561,7 +5370,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
@@ -5596,7 +5405,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5625,7 +5434,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "грамадскі ключ ня знойдзены"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "%s: немагчыма стварыць хэш-табліцу: %s\n"
 
 msgid "certificate has been revoked"
@@ -5812,16 +5621,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -5843,11 +5652,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, c-format
@@ -5855,11 +5664,11 @@ msgid "line %d: not a valid email address\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, fuzzy, c-format
@@ -5928,7 +5737,7 @@ msgid "No subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -5937,7 +5746,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "нерэчаісны хэш-альгарытм \"%s\"\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -5978,7 +5787,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "грамадскі ключ ня знойдзены"
 
 #, fuzzy, c-format
@@ -5986,11 +5795,11 @@ msgid "error locking keybox: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr ""
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6025,6 +5834,10 @@ msgstr ""
 msgid "invoke gpg-protect-tool"
 msgstr ""
 
+#, fuzzy
+msgid "change a passphrase"
+msgstr "дрэнны пароль"
+
 msgid "create base-64 encoded output"
 msgstr ""
 
@@ -6103,8 +5916,8 @@ msgstr "Выкарыстаньне: gpg [выбары] [файлы] (-h для 
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Сынтаксіс: gpg [выбары] [файлы]\n"
 "sign, check, encrypt ці decrypt\n"
@@ -6115,11 +5928,11 @@ msgid "usage: gpgsm [options] "
 msgstr "Выкарыстаньне: gpg [выбары] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "невядомая вэрсыя"
 
 #, c-format
@@ -6142,11 +5955,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6162,6 +5975,10 @@ msgstr ""
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "%s: немагчыма стварыць хэш-табліцу: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
@@ -6175,11 +5992,14 @@ msgid "error reading input: %s\n"
 msgstr "паказаць ключы й адбіткі пальцаў"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "памылка стварэньня \"%s\": %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "%s: тэчка створана\n"
 
 #, fuzzy
@@ -6213,11 +6033,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "паказаць ключы й адбіткі пальцаў"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6334,7 +6154,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "невядомая вэрсыя"
 
 #, fuzzy, c-format
@@ -6564,7 +6384,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "немагчыма адкрыць %s: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "%s: немагчыма стварыць тэчку: %s\n"
 
 #, c-format
@@ -6659,17 +6479,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "памылка стварэньня \"%s\": %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "%s: немагчыма стварыць хэш-табліцу: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Загад> "
-
 #~ msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
 #~ msgstr "Калі ласка, паведамляйце пра памылкі на <gnupg-bugs@gnu.org>.\n"
 
@@ -6774,6 +6583,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "памылка стварэньня файла"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "нерэчаісны пароль"
+
 #~ msgid "file close error"
 #~ msgstr "памылка зачыненьня файла"
 
index 23ad588..51abe68 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -30,7 +30,6 @@ msgstr ""
 "PO-Revision-Date: 2005-02-04 02:04+0100\n"
 "Last-Translator: Jordi Mallach <jordi@gnu.org>\n"
 "Language-Team: Catalan <ca@dodds.net>\n"
-"Language: ca\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -39,42 +38,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "no s'ha pogut emmagatzemar l'empremta digital: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to create a sign and encrypt key? "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Segur que voleu crear una clau de signatura i xifratge? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "la contrasenya és invàlida"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -100,9 +63,6 @@ msgid ""
 "this session"
 msgstr "Introduïu la contrasenya; aquesta ha de ser una frase secreta \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -139,11 +99,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "l'algoritme de protecció %d%s no està suportat\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "no s'ha pogut crear «%s»: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "no s'ha pogut obrir «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -172,31 +132,19 @@ msgstr "no s'ha pogut eliminar el bloc de claus: %s\n"
 msgid "error writing key: %s\n"
 msgstr "error mentre s'escrivia l'anell «%s»: %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Introduïu la contrasenya; aquesta ha de ser una frase secreta \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "canvia la contrasenya"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Introduïu la contrasenya; aquesta ha de ser una frase secreta \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -224,7 +172,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -312,7 +260,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Cal una contrasenya per a protegir la clau secreta.\n"
 "\n"
@@ -330,10 +278,10 @@ msgstr ""
 "Opcions:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 # Un dels dos és en la llista d'opcions amb --help. Urgh. jm
@@ -390,32 +338,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "error en la creació de la contrasenya: %s\n"
 
-# Gènere?  Nombre?  ivb
-# Werner FIXME: please add translator comment saying *what* is
-# uncompressed so we know the gender. jm
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "no és suportat"
-
-# Gènere?  Nombre?  ivb
-# Werner FIXME: please add translator comment saying *what* is
-# uncompressed so we know the gender. jm
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "no és suportat"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "error en la creació de la contrasenya: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -437,7 +368,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -445,23 +376,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTA: no existeix el fitxer d'opcions predeterminades «%s»\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "fitxer d'opcions «%s»: %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "s'estan llegint opcions de «%s»\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "error en crear «%s»: %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "no es pot crear el directori «%s»: %s\n"
 
 msgid "name of socket too long\n"
@@ -472,7 +403,7 @@ msgid "can't create socket: %s\n"
 msgstr "no s'ha pogut crear «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "Certificat de revocació vàlid"
 
 #, fuzzy
@@ -484,7 +415,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "error en crear «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "error mentre s'enviava a «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -492,19 +423,19 @@ msgid "listen() failed: %s\n"
 msgstr "ha fallat l'actualització: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "s'està escrivint la clau secreta a «%s»\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: s'ha creat el directori\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "base de dades de confiança: ha fallat la lectura (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: no s'ha pogut crear el directori: %s\n"
 
 #, fuzzy, c-format
@@ -612,32 +543,32 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "error en la creació de la contrasenya: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "error en la lectura de «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "fitxer d'opcions «%s»: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 # Parts?  Peces?  ivb
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "parts de la clau secreta no estan disponbles\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "error de lectura: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "error en la lectura de «%s»: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -725,15 +656,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "s'ha produït un error mentre s'escrivia l'anell secret «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "error en la lectura de «%s»: %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "error en la lectura de «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -748,7 +679,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent no està disponible en aquesta sessió\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "no s'ha pogut connectar amb «%s»: %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -828,10 +759,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -858,22 +785,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "Certificat correcte"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "Certificat correcte"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "Certificat correcte"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "Certificat correcte"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "Certificat de revocació vàlid"
 
@@ -928,26 +839,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "l'algoritme de dispersió és invàlid «%s»\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Aquesta signatura va caducar el %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "l'algoritme de dispersió és invàlid «%s»\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "l'algoritme de protecció %d%s no està suportat\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "s'ha eliminat la verificació de signatura\n"
 
@@ -956,11 +851,11 @@ msgid "Signature available"
 msgstr "Aquesta signatura va caducar el %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Signatura correcta de \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "l'algoritme de dispersió és invàlid «%s»\n"
 
 #, fuzzy, c-format
@@ -1007,7 +902,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "No hi ha ajuda disponible per a `%s'"
 
 #, fuzzy
@@ -1188,11 +1083,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "error en crear l'anell «%s»: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "error en la lectura de «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "error mentre s'escrivia l'anell «%s»: %s\n"
 
 msgid "Login data (account name): "
@@ -1395,8 +1290,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Ordre> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1415,7 +1310,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output no funciona per a aquesta ordre\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "no s'ha pogut obrir «%s»\n"
 
 #, fuzzy, c-format
@@ -1469,11 +1364,11 @@ msgid "using cipher %s\n"
 msgstr "Ha fallat el procés de signatura: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "«%s» ja està comprimida\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "AVÍS: «%s» és un fitxer buit\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1481,7 +1376,7 @@ msgstr ""
 "només podeu xifrar a claus RSA de 2048 bits o menys en el mode --pgp2\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "s'està llegint des de «%s»\n"
 
 msgid ""
@@ -1553,11 +1448,11 @@ msgstr ""
 "externs\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "no s'ha pogut executar %s «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "no s'ha pogut executar %s «%s»: %s\n"
 
 #, c-format
@@ -1575,11 +1470,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "no s'ha pogut llegir la resposta del programa extern: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "AVÍS: no s'ha pogut eliminar el fitxer temporal (%s) «%s»: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "AVÍS: no s'ha pogut eliminar el directori temporal «%s»: %s\n"
 
 #, fuzzy
@@ -1649,16 +1544,12 @@ msgstr ""
 msgid "[User ID not found]"
 msgstr "[No s'ha trobat l'id d'usuari]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "clau %08lX: clau secreta sense clau pública - es descarta\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "error en crear «%s»: %s\n"
 
 #, fuzzy
@@ -1679,6 +1570,10 @@ msgstr ""
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "s'usarà la clau secundària %08lX en lloc de la primària %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "clau %08lX: clau secreta sense clau pública - es descarta\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "|[fitxer]|crea una signatura"
@@ -1723,9 +1618,6 @@ msgstr "llista claus secretes"
 msgid "generate a new key pair"
 msgstr "genera un nou parell de claus"
 
-msgid "generate a revocation certificate"
-msgstr "genera un certificat de revocació"
-
 msgid "remove keys from the public keyring"
 msgstr "elimina claus de l'anell públic"
 
@@ -1741,9 +1633,8 @@ msgstr "signa una clau localment"
 msgid "sign or edit a key"
 msgstr "signa o edita una clau"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "canvia la contrasenya"
+msgid "generate a revocation certificate"
+msgstr "genera un certificat de revocació"
 
 msgid "export keys"
 msgstr "exporta claus"
@@ -1845,15 +1736,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Forma d'ús: gpg [opcions] [fitxers] (-h per a veure l'ajuda)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxi: gpg [opcions] [fitxers]\n"
 "signa, comprova, xifra o desxifra\n"
@@ -1890,38 +1776,38 @@ msgid "conflicting commands\n"
 msgstr "les ordres entren en conflicte\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "no s'ha trobat cap signe = a la definició de grup «%s»\n"
 
 # Indi. ivb
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "AVÍS: el propietari és insegur en %s «%s»\n"
 
 # Indi. ivb
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "AVÍS: el propietari és insegur en %s «%s»\n"
 
 # Indi. ivb
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "AVÍS: el propietari és insegur en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "AVÍS: els permissos són insegurs en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "AVÍS: els permissos són insegurs en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "AVÍS: els permissos són insegurs en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "AVÍS: el propietari del directori envoltant és insegur en %s «%s»\n"
 
 #, fuzzy, c-format
@@ -1930,11 +1816,11 @@ msgid ""
 msgstr "AVÍS: el propietari del directori envoltant és insegur en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "AVÍS: el propietari del directori envoltant és insegur en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "AVÍS: els permissos del directori envoltant són insegurs en %s «%s»\n"
 
 #, fuzzy, c-format
@@ -1943,11 +1829,11 @@ msgid ""
 msgstr "AVÍS: els permissos del directori envoltant són insegurs en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "AVÍS: els permissos del directori envoltant són insegurs en %s «%s»\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "s'ha creat el nou fitxer d'opcions «%s»\n"
 
 msgid "display photo IDs during key listings"
@@ -1988,7 +1874,7 @@ msgid "show expiration dates during signature listings"
 msgstr "No hi ha cap signatura corresponent en l'anell secret\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "NOTA: es descarta el fitxer d'opcions predeterminades antic «%s»\n"
 
 #, c-format
@@ -2000,11 +1886,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "NOTA: %s no és per a ús normal!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s no és un joc de caràcters vàlid\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s no és un joc de caràcters vàlid\n"
 
 #, fuzzy
@@ -2187,15 +2073,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s encara no funciona amb %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "no podeu usar l'algorisme de xifratge «%s» mentre esteu en mode %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "no podeu usar l'algorisme de resum %s mentre esteu en mode %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "no podeu usar l'algorisme de compressió %s mentre esteu en mode %s\n"
 
 #, c-format
@@ -2213,7 +2099,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [nom_del_fitxer]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "ha fallat el desxifratge: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2265,10 +2151,6 @@ msgstr "--lsign-key user-id"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key user-id [ordres]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key user-id"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "l'enviament al servidor de claus ha fallat: %s\n"
@@ -2298,7 +2180,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "no s'ha pogut crear l'armadura: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "l'algoritme de dispersió és invàlid «%s»\n"
 
 msgid "[filename]"
@@ -2343,7 +2225,7 @@ msgid "No help available"
 msgstr "No hi ha ajuda disponible"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "No hi ha ajuda disponible per a `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2353,10 +2235,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "actualitza la base de dades de confiança"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "actualitza la base de dades de confiança"
 
@@ -2475,13 +2353,6 @@ msgid "key %s: no user ID\n"
 msgstr "clau %08lX: sense ID\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "es descarta «%s»: %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "clau %08lX: corrupció de la subclau HKP reparada\n"
 
@@ -2509,11 +2380,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "no s'ha trobat cap anell escrivible: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "s'està escrivint en «%s»\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "error mentre s'escrivia l'anell «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -2577,17 +2448,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "clau %08lX: «%s» no ha estat modificada\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "no s'ha trobat la clau secreta «%s»: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "clau %08lX: clau secreta amb xifrat %d no vàlid - es descarta\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "s'està escrivint la clau secreta a «%s»\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "clau %08lX: clau secreta amb xifrat %d no vàlid - es descarta\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "no hi ha anell secret predeterminat: %s\n"
@@ -2628,8 +2495,8 @@ msgstr "clau %08lX: no hi ha ID per a la signatura\n"
 #, fuzzy, c-format
 msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
 msgstr ""
-"clau %08lX: l'algoritme de clau pública no es suporta sobre l'id d'usuari "
-"«%s»\n"
+"clau %08lX: l'algoritme de clau pública no es suporta sobre l'id d'usuari «%"
+"s»\n"
 "\n"
 
 #, fuzzy, c-format
@@ -2637,18 +2504,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "clau %08lX: l'autosignatura no és vàlida en l'id d'usuari «%s»\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "clau %08lX: l'algoritme de clau pública no és suportat\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "clau %08lX: s'ha afegit la signatura de clau directa\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "clau %08lX: no hi ha una subclau per a l'enllaç de la clau\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "clau %08lX: l'algoritme de clau pública no és suportat\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "clau %08lX: l'enllaç de subclau és invàlid\n"
 
@@ -2708,8 +2571,8 @@ msgstr "clau %08lX: s'ha detectat un ID d'usuari duplicat - es fusiona\n"
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
 msgstr ""
-"AVÍS: la clau %08lX pot estar revocada: s'adquireix la clau de revocació "
-"%08lX\n"
+"AVÍS: la clau %08lX pot estar revocada: s'adquireix la clau de revocació %"
+"08lX\n"
 
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
@@ -2738,15 +2601,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "es descarta: la clau secreta ja és present\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "error en crear l'anell «%s»: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "s'ha creat l'anell «%s»\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "error en crear «%s»: %s\n"
 
 #, c-format
@@ -2936,7 +2799,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) He fet comprovacions molt acurades.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Seleccioneu una opció (introduïu «?» per obtindre més informació):"
 
 #, fuzzy, c-format
@@ -3227,7 +3090,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Pista: Trieu els ID d'usuari que voleu signar\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "la classe de signatura és desconeguda"
 
 #, c-format
@@ -3262,11 +3125,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "no s'ha pogut obrir «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "error en crear l'anell «%s»: %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3357,7 +3220,7 @@ msgstr "No hi ha preferències en un ID d'usuari d'estil PGP 2.x.\n"
 # Potser %s haja d'anar darrere de «clau».  ivb
 # És cert. Nova funcionalitat de 1.2.0, IIRC. jm
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Aquesta clau pot ser revocada per la clau %s "
 
 # Potser %s haja d'anar darrere de «clau».  ivb
@@ -3427,14 +3290,6 @@ msgstr ""
 "      causar que una ID d'usuari diferent esdevinga en la primària "
 "assumida.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "No podeu canviar la data de caducitat de les claus v3\n"
-
 # Photo ID com abans.  ivb
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
@@ -3674,7 +3529,7 @@ msgstr ""
 "S'està mostrant el photo ID %s de mida %ld per a la clau 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "la preferència %c%lu és duplicada\n"
 
 #, fuzzy
@@ -3690,7 +3545,7 @@ msgid "too many compression preferences\n"
 msgstr "hi ha massa preferències «%c»\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "hi ha un caràcter invàlid en la cadena de preferència\n"
 
 msgid "writing direct signature\n"
@@ -3935,7 +3790,7 @@ msgid "Invalid character in comment\n"
 msgstr "Hi ha un caràcter invàlid en el camp *comentari*\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Esteu usant el joc de caràcters `%s'.\n"
 
 #, c-format
@@ -4022,15 +3877,15 @@ msgid "Key generation canceled.\n"
 msgstr "La generació de claus ha estat cancel·lada.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "s'està escrivint la clau pública a «%s»\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "s'està escrivint la clau secreta a «%s»\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "s'està escrivint la clau secreta a «%s»\n"
 
 # Potser no hi haja cap anell! ivb
@@ -4045,11 +3900,11 @@ msgstr ""
 "\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "s'ha produït un error mentre s'escrivia l'anell públic «%s»: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "s'ha produït un error mentre s'escrivia l'anell secret «%s»: %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -4095,11 +3950,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "no s'ha pogut eliminar el bloc de claus: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "no s'ha pogut crear «%s»: %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr ""
 
 msgid "never     "
@@ -4141,15 +3996,11 @@ msgstr "      Empremta digital de la subclau:"
 msgid "      Key fingerprint ="
 msgstr "     Empremta digital ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "signatura %s, algorisme de resum %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "no s'ha pogut crear l'armadura: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4167,7 +4018,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Per favor, solucioneu aquest possible problema de seguretat\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "s'està comprovant l'anell «%s»\n"
 
 #, fuzzy, c-format
@@ -4207,7 +4058,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "AVÍS: les opcions en «%s» encara no estan actives durant aquesta execució\n"
 
@@ -4274,10 +4125,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "la recepció des del servidor de claus ha fallat: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "no es coneix cap servidor de claus (useu l'opció \"--keyserver\")\n"
 
@@ -4285,11 +4132,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4307,6 +4154,10 @@ msgid "keyserver internal error\n"
 msgstr "error de servidor de claus"
 
 #, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "la recepció des del servidor de claus ha fallat: %s\n"
+
+#, fuzzy, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "%s: no és un ID vàlid\n"
 
@@ -4484,10 +4335,6 @@ msgid "unknown"
 msgstr "desconeguda"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "No s'ha pogut comprovar la signatura: %s\n"
 
@@ -4510,7 +4357,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "s'ha detectat un paquet arrel invàlid en proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "ha fallat l'actualització de la base de dades de confiança: %s\n"
 
 #, fuzzy, c-format
@@ -4537,11 +4384,6 @@ msgstr "signatura %s, algorisme de resum %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "AVÍS: %s és una opció desaconsellada.\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "signatura %s, algorisme de resum %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "el mòdul de xifratge IDEA no està present\n"
 
@@ -4573,15 +4415,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "AVÍS: %s és una opció desaconsellada.\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "AVÍS: %s és una opció desaconsellada.\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "AVÍS: %s és una opció desaconsellada.\n"
-
 # Gènere?  Nombre?  Passat, futur?  ivb
 # Werner FIXME: please add translator comment saying *what* is
 # uncompressed so we know the gender. jm
@@ -4601,15 +4434,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "aquest missatge pot no ser usable per %s\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "s'estan llegint opcions de «%s»\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "el destinatari predeterminat és desconegut «%s»\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "El fitxer «%s» existeix. "
 
 #, fuzzy
@@ -4627,17 +4460,16 @@ msgstr "Introduïu el nou nom del fitxer"
 msgid "writing to stdout\n"
 msgstr "s'està escrivint en stdout\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "s'asumeix que hi ha dades signades en «%s»\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "s'ha creat el nou fitxer d'opcions «%s»\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "AVÍS: les opcions en «%s» encara no estan actives durant aquesta execució\n"
 
@@ -4654,10 +4486,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "el subpaquet de tipus %d té el bit crític activat\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "hi ha un problema amb l'agent: l'agent ha tornat 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (ID de la clau principal %08lX)"
 
@@ -4691,6 +4519,10 @@ msgid "cancelled by user\n"
 msgstr "s'ha cancel·lat per l'usuari\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "hi ha un problema amb l'agent: l'agent ha tornat 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4725,7 +4557,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Introduïu el nom del fitxer JPEG per al photo ID: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "No s'ha pogut obrir la foto «%s»: %s\n"
 
 #, c-format
@@ -4737,7 +4569,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Esteu segur que encara voleu utilitzarla (s/N)? "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "«%s» no és un fitxer JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4767,16 +4599,6 @@ msgstr "raó de la revocació: "
 msgid "revocation comment: "
 msgstr "comentari de la revocació: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMxXoO"
 
@@ -4895,11 +4717,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Nota: Aquesta clau ha estat desactivada.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -5002,7 +4824,7 @@ msgid "no signed data\n"
 msgstr "no hi ha dades signades\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "no s'han pogut obrir les dades signades `%s'\n"
 
 #, fuzzy, c-format
@@ -5311,8 +5133,8 @@ msgstr "es descarta: la clau secreta ja és present\n"
 #, fuzzy
 msgid "this is a PGP generated Elgamal key which is not secure for signatures!"
 msgstr ""
-"es descarta «%s»: és una clau ElGamal generada per PGP que no és segura per "
-"signatures!\n"
+"es descarta «%s»: és una clau ElGamal generada per PGP que no és segura per "
+"signatures!\n"
 
 #, c-format
 msgid "trust record %lu, type %d: write failed: %s\n"
@@ -5327,7 +5149,7 @@ msgstr ""
 "# (Utilitzeu «gpg --import-ownertrust» per a restaurar-les)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "error en la lectura de «%s»: %s\n"
 
 #, fuzzy
@@ -5346,25 +5168,17 @@ msgid "ownertrust value missing"
 msgstr "importa els valors de confiança"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "error en trobar el registre de confiança: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "error de lectura: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "base de dades de confiança: no s'ha pogut sincronitzar: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "no es pot crear el directori «%s»: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "no s'ha pogut obrir «%s»\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "reg de la base de dades de confiança %lu: ha fallat lseek: %s\n"
@@ -5372,20 +5186,28 @@ msgstr "reg de la base de dades de confiança %lu: ha fallat lseek: %s\n"
 #, c-format
 msgid "trustdb rec %lu: write failed (n=%d): %s\n"
 msgstr ""
-"reg de la base de dades de confiança %lu: ha fallat la escriptura (n=%d): "
-"%s\n"
+"reg de la base de dades de confiança %lu: ha fallat la escriptura (n=%d): %"
+"s\n"
 
 msgid "trustdb transaction too large\n"
 msgstr "la transacció de la base de dades de confiança és massa gran\n"
 
+# No em passe! ;)  ivb
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "no s'ha pogut tancar «%s»: %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: el directori no existeix!\n"
 
-# No em passe! ;)  ivb
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "no s'ha pogut tancar «%s»: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "no es pot crear el directori «%s»: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "no s'ha pogut obrir «%s»\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5471,7 +5293,7 @@ msgid "input line longer than %d characters\n"
 msgstr "la línia d'entrada és superior a %d caràcters\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "«%s» no és un ID de clau llarg vàlid\n"
 
 #, fuzzy, c-format
@@ -5514,14 +5336,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5575,13 +5389,13 @@ msgid "next trustdb check due at %s\n"
 msgstr "la pròxima comprovació de la base de dades de confiança serà el %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr ""
 "no és necessària una comprovació de la base de dades de confiança\n"
 "\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr ""
 "no és necessària una comprovació de la base de dades de confiança\n"
 "\n"
@@ -5655,11 +5469,6 @@ msgid "missing argument"
 msgstr "l'argument és invàlid"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "l'armadura és invàlida"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "les ordres entren en conflicte\n"
 
@@ -5683,10 +5492,6 @@ msgstr "opcions d'importació no vàlides\n"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "opcions d'importació no vàlides\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5719,8 +5524,12 @@ msgstr "opcions d'importació no vàlides\n"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "heu trobat un bug... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "error en la lectura de «%s»: %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5728,15 +5537,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "no es pot obrir el fitxer: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "no s'ha pogut crear l'armadura: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "no es pot crear el directori «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "error mentre s'escrivia l'anell «%s»: %s\n"
 
 #, c-format
@@ -5754,7 +5563,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "no s'ha trobat la clau pública %08lX: %s\n"
 
 #, fuzzy, c-format
@@ -5771,11 +5580,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Forma d'ús: gpg [opcions] [fitxers] (-h per a veure l'ajuda)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Forma d'ús: gpg [opcions] [fitxers] (-h per a veure l'ajuda)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5904,9 +5712,6 @@ msgstr "Seleccioneu la raó de la revocació:\n"
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5917,14 +5722,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "canvia la contrasenya"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "canvia la contrasenya"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "s'ha produït un error en llegir el bloc de claus: %s\n"
 
@@ -5991,9 +5788,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr ""
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "canvia la contrasenya"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -6030,16 +5826,13 @@ msgstr "no usa el terminal en absolut"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "les ordres entren en conflicte\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Forma d'ús: gpg [opcions] [fitxers] (-h per a veure l'ajuda)"
@@ -6049,7 +5842,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -6069,7 +5862,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr "no s'ha pogut posar «%s» en la base de dades de confiança - %s\n"
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -6105,7 +5898,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "no s'ha pogut obrir «%s»: %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -6134,7 +5927,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "no s'ha pogut eliminar el bloc de claus: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "no s'ha pogut inicialitzar la base de dades de confiança: %s\n"
 
 #, fuzzy
@@ -6346,16 +6139,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "s'ha produït un error mentre s'escrivia l'anell secret «%s»: %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6377,11 +6170,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6389,11 +6182,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "No és una adreça vàlida\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "error en crear l'anell «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "error en crear l'anell «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -6464,7 +6257,7 @@ msgid "No subject name given\n"
 msgstr "(No es va donar una descripció)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6473,7 +6266,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "l'algoritme de dispersió és invàlid «%s»\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6521,7 +6314,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "no s'ha trobat la clau secreta «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -6529,11 +6322,11 @@ msgid "error locking keybox: %s\n"
 msgstr "s'ha produït un error en llegir el bloc de claus: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "certificat duplicat: esborrat"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "certificat duplicat: esborrat"
 
 #, fuzzy, c-format
@@ -6570,6 +6363,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "canvia la contrasenya"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "crea eixida amb armadura ascii"
 
@@ -6648,8 +6445,8 @@ msgstr "Forma d'ús: gpg [opcions] [fitxers] (-h per a veure l'ajuda)"
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxi: gpg [opcions] [fitxers]\n"
 "signa, comprova, xifra o desxifra\n"
@@ -6660,11 +6457,11 @@ msgid "usage: gpgsm [options] "
 msgstr "forma d'ús: gpg [opcions] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "no s'ha pogut connectar amb «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "el destinatari predeterminat és desconegut «%s»\n"
 
 #, fuzzy, c-format
@@ -6687,12 +6484,12 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr ""
 
 # No em passe! ;)  ivb
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "no s'ha pogut tancar «%s»: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6709,6 +6506,10 @@ msgstr "Certificat correcte"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "no s'ha pogut inicialitzar la base de dades de confiança: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "error en crear «%s»: %s\n"
@@ -6722,11 +6523,14 @@ msgid "error reading input: %s\n"
 msgstr "error en la lectura de «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "error en crear l'anell «%s»: %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "s'ha creat l'anell «%s»\n"
 
 #, fuzzy
@@ -6760,11 +6564,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "error: l'empremta digital és invàlida\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6885,7 +6689,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "el destinatari predeterminat és desconegut «%s»\n"
 
 #, fuzzy, c-format
@@ -7115,7 +6919,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "ha fallat l'actualització de la base de dades de confiança: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "no es pot crear el directori «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -7212,17 +7016,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "error en la lectura de «%s»: %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "no s'ha pogut inicialitzar la base de dades de confiança: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Ordre> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "la base de dades de confiança està corrompuda; per favor, executeu «gpg --"
@@ -7303,8 +7096,7 @@ msgstr ""
 #~ "claus\n"
 #~ "tenen confiança absoluta - aquestes són normalment les claus per a les "
 #~ "que\n"
-#~ "teniu accés a la clau secreta.  Contesteu «sí» per a donar a aquesta "
-#~ "clau\n"
+#~ "teniu accés a la clau secreta.  Contesteu «sí» per a donar a aquesta clau\n"
 #~ "confiança absoluta\n"
 
 # "clau no confiable"? jm
@@ -7426,8 +7218,7 @@ msgstr ""
 #~ "«1» significa que creieu que la clau és de la persona que diu que és la\n"
 #~ "    propietària, però no heu pogut, o no heu verificat la clau de cap "
 #~ "manera.\n"
-#~ "    Açò és útil per a la verificació d'un «rol», quan signeu la clau "
-#~ "d'un\n"
+#~ "    Açò és útil per a la verificació d'un «rol», quan signeu la clau d'un\n"
 #~ "    usuari amb pseudònim.\n"
 #~ "\n"
 #~ "«2» significa que heu fet algunes comprovacions de la clau. Per exemple, "
@@ -7621,8 +7412,7 @@ msgstr ""
 #, fuzzy
 #~ msgid "cipher extension `%s' not loaded due to unsafe permissions\n"
 #~ msgstr ""
-#~ "la extensió de xifrat «%s» no s'ha carregat per tindre permissos "
-#~ "insegurs\n"
+#~ "la extensió de xifrat «%s» no s'ha carregat per tindre permissos insegurs\n"
 
 #~ msgid "DSA requires the use of a 160 bit hash algorithm\n"
 #~ msgstr "DSA requereix l'ús d'un algoritme de dispersió de 160 bits\n"
@@ -7765,6 +7555,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "el paquet és invàlid"
 
+#~ msgid "invalid armor"
+#~ msgstr "l'armadura és invàlida"
+
 #~ msgid "no such user id"
 #~ msgstr "no s'ha trobat l'id de l'usuari"
 
@@ -7774,6 +7567,12 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "s'ha utilitzat una clau secreta incorrecta"
 
+# Gènere?  Nombre?  ivb
+# Werner FIXME: please add translator comment saying *what* is
+# uncompressed so we know the gender. jm
+#~ msgid "not supported"
+#~ msgstr "no és suportat"
+
 #~ msgid "bad key"
 #~ msgstr "la clau és incorrecta"
 
@@ -7789,6 +7588,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "error en la creació del fitxer"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "la contrasenya és invàlida"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "l'algoritme de clau pública no és implementat"
 
@@ -8553,6 +8355,9 @@ msgstr ""
 #~ msgid "%s: error checking key: %s\n"
 #~ msgstr "%s: error en la comprovació de la clau: %s\n"
 
+#~ msgid "Do you really want to create a sign and encrypt key? "
+#~ msgstr "Segur que voleu crear una clau de signatura i xifratge? "
+
 #~ msgid "Do you really need such a large keysize? "
 #~ msgstr "Realment necessiteu una clau tan llarga? "
 
index e2bba98..417e4c3 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -3,90 +3,35 @@
 #               2005 Free Software Foundation, Inc.
 # Magda Procházková <magda@math.muni.cz> 2001,
 # Roman Pavlik <rp@tns.cz> 2001, 2002, 2003, 2004, 2005.
-# Petr Pisar <petr.pisar@atlas.cz>, 2009, 2010, 2011, 2013.
+# Petr Pisar <petr.pisar@atlas.cz>, 2009.
 #
-# A "%%0A" is used by Pinentry to insert a line break. The double percent
-# sign is actually needed because it is also a printf format string. If you
-# need to insert a plain % sign, you need to encode it as "%%25".
-#
-# „armor“ překládat jako „ASCII“
-# (reader's) pinpad → klávesnice čtečky
-#
-# „keybox“ je jednotné úložiště pro X.509 a PGP certifikáty/klíče
-# <http://www.gnupg.org/documentation/manuals/gnupg/kbxutil.html>
-# Občas je třeba rozlišovat mezi keybox (překládám jako schránka) a keyring
-# (překládám jako klíčenka nebo soubor klíčů).
-#
-# Některé pojmy ohledně GnuPG jsou vysvětleny na
-# <http://www.gnupg.org/documentation/manuals/gnupg/Glossary.html>
-#
-# Některé pojmy by měly být překládány v souladu se zákonem 227/2000 Sb.,
-# zákon o elektronickém podpisu, <http://portal.gov.cz/zakon/227/2000>:
-# kvalifikovaný certifikát/podpis
+# cache → keš
+# distribution point → místo distribuce
+# DP (distribution point (of CRL)) → DP
+# load → zavést
+# OCSP request → OCSP dotaz
+# validate → ověřit (platnost)
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg2 2.0.21\n"
+"Project-Id-Version: gnupg-1.3.92\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2013-09-01 11:14+0200\n"
-"Last-Translator: Petr Pisar <petr.pisar@atlas.cz>\n"
+"PO-Revision-Date: 2004-11-26 09:12+0200\n"
+"Last-Translator: Roman Pavlik <rp@tns.cz>\n"
 "Language-Team: Czech <translations.cs@gnupg.cz>\n"
-"Language: cs\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "failed to acquire the pinentry lock: %s\n"
-msgstr "získání zámku pinetry se nezdařilo: %s\n"
-
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|_Cancel"
-msgstr "|pinentry-label|_Zrušit"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_OK"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|PIN:"
-msgstr "|pinentry-label|PIN:"
-
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|_Zrušit"
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Opravdu chcete revokovat vybrané podklíče? (a/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "nesprávné heslo"
+msgstr "uložení fingerprintu se nezdařilo: %s\n"
 
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
+#, fuzzy
 msgid "Quality:"
-msgstr "Kvalita:"
+msgstr "platnost: %s"
 
 #. TRANSLATORS: This string is a tooltip, shown by pinentry when
 #. hovering over the quality bar.  Please use an appropriate
@@ -96,179 +41,177 @@ msgstr "Kvalita:"
 #. will be used.
 msgid "pinentry.qualitybar.tooltip"
 msgstr ""
-"Kvalita textu zde zadaného.\n"
-"Na podrobnosti ohledně kritérií se zeptejte svého správce."
 
 msgid ""
 "Please enter your PIN, so that the secret key can be unlocked for this "
 "session"
 msgstr ""
-"Prosím, zadejte váš PIN, aby pro tuto relaci mohl být odemknut tajný klíč"
 
+#, fuzzy
 msgid ""
 "Please enter your passphrase, so that the secret key can be unlocked for "
 "this session"
-msgstr ""
-"Prosím, zadejte vaše heslo, aby pro tuto relaci mohl být odemknut tajný klíč"
+msgstr "Prosím, vložte heslo; toto je tajná věta \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
-msgstr "SETERROR %s (pokus %d z %d)"
+msgstr ""
 
+#, fuzzy
 msgid "PIN too long"
-msgstr "PIN je příliš dlouhý"
+msgstr "řádek je příliš dlouhý"
 
+#, fuzzy
 msgid "Passphrase too long"
-msgstr "Heslo je příliš dlouhé"
+msgstr "řádek je příliš dlouhý"
 
+#, fuzzy
 msgid "Invalid characters in PIN"
-msgstr "Neplatný znak v PINu"
+msgstr "Neplatný znak ve jméně\n"
 
 msgid "PIN too short"
-msgstr "PIN je příliš krátký"
+msgstr ""
 
+#, fuzzy
 msgid "Bad PIN"
-msgstr "Å patný PIN"
+msgstr "Å¡patné MPI"
 
+#, fuzzy
 msgid "Bad Passphrase"
-msgstr "Å patné heslo"
+msgstr "Å¡patné heslo"
 
+#, fuzzy
 msgid "Passphrase"
-msgstr "Heslo"
+msgstr "špatné heslo"
 
-#, c-format
+#, fuzzy, c-format
 msgid "ssh keys greater than %d bits are not supported\n"
-msgstr "SSH klíče delší než %d bitů nejsou podporovány\n"
+msgstr "ochranný algoritmus %d není podporován\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
-msgstr "nemohu vytvořit „%s“: %s\n"
+msgid "can't create '%s': %s\n"
+msgstr "nemohu vytvořit `%s': %s\n"
 
-#, c-format
-msgid "can't open `%s': %s\n"
-msgstr "nemohu otevřít „%s“: %s\n"
+#, fuzzy, c-format
+msgid "can't open '%s': %s\n"
+msgstr ""
+"nemohu otevřít `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting serial number of card: %s\n"
-msgstr "chyba při získání sériového čísla karty: %s\n"
+msgstr "chyba při získání nového PINu: %s\n"
 
 #, c-format
 msgid "detected card with S/N: %s\n"
-msgstr "nalezena karta se sériovým číslem: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting default authentication keyID of card: %s\n"
-msgstr ""
-"chyba při získání identifikátoru implicitního autentizačního klíče karty: "
-"%s\n"
+msgstr "chyba při získání informací o aktuálním klíči: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "no suitable card key found: %s\n"
-msgstr "nenalezen žádný vhodný klíč karty: %s\n"
+msgstr "nenalezen zapisovatelný soubor tajných klíčů (secring): %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "shadowing the key failed: %s\n"
-msgstr "výroba stínového klíče se nezdařila: %s\n"
+msgstr "čtení veřejného klíče se nezdařilo: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key: %s\n"
-msgstr "chyba při zápisu klíče: %s\n"
-
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-"Proces SSH si vyžádal použití klíče%%0A  %s%%0A  (%s)%%0APřejete si to "
-"povolit?"
-
-msgid "Allow"
-msgstr "Povolit"
+msgstr "chyba při zápisu souboru klíčů (keyring)  `%s': %s\n"
 
-msgid "Deny"
-msgstr "Zakázat"
-
-#, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
-msgstr "Prosím, vložte heslo pro SSH klíč%%0A  %F%%0A  (%c)"
+#, fuzzy, c-format
+msgid "Please enter the passphrase for the ssh key%0A  %c"
+msgstr "Prosím, vložte heslo; toto je tajná věta \n"
 
+#, fuzzy
 msgid "Please re-enter this passphrase"
-msgstr "Prosím, vložte toto heslo znovu"
+msgstr "změnit heslo"
 
 #, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s"
+"%%0Awithin gpg-agent's key storage"
 msgstr ""
-"Prosím, vložte heslo, abyste ochránil(a) přijatý tajný klíč%%0A   %s%%0A   %s"
-"%%0Auvnitř úložiště klíčů gpg-agenta"
 
 msgid "does not match - try again"
-msgstr "neshodují se – zkuste to znovu"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "failed to create stream from socket: %s\n"
-msgstr "ze socketu se nepodařilo se vytvořit proud (stream): %s\n"
+msgstr "%s: nepodařilo se vytvořit hashovací tabulku: %s\n"
 
+#, fuzzy
 msgid "Please insert the card with serial number"
-msgstr "Prosím, vložte kartu se sériovým číslem"
+msgstr ""
+"Prosím vyjměte kartu a vložte jinou se seriovým číslem:\n"
+"   %.*s\n"
 
+#, fuzzy
 msgid "Please remove the current card and insert the one with serial number"
-msgstr "Prosím, vyjměte kartu a vložte jinou se sériovým číslem"
+msgstr ""
+"Prosím vyjměte kartu a vložte jinou se seriovým číslem:\n"
+"   %.*s\n"
 
+#, fuzzy
 msgid "Admin PIN"
-msgstr "PIN správce"
+msgstr "|A|PIN administrátora"
 
 #. TRANSLATORS: A PUK is the Personal Unblocking Code
 #. used to unblock a PIN.
 msgid "PUK"
-msgstr "PUK"
+msgstr ""
 
 msgid "Reset Code"
-msgstr "Resetační kód"
+msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
-msgstr "%s%%0A%%0APro vstup použijte klávesnici čtečky."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
+msgstr ""
 
+#, fuzzy
 msgid "Repeat this Reset Code"
-msgstr "Zopakujte resetační kód"
+msgstr "Opakujte tento PIN: "
 
+#, fuzzy
 msgid "Repeat this PUK"
-msgstr "Zopakujte tento PUK"
+msgstr "Opakujte tento PIN: "
 
+#, fuzzy
 msgid "Repeat this PIN"
-msgstr "Zopakujte tento PIN"
+msgstr "Opakujte tento PIN: "
 
+#, fuzzy
 msgid "Reset Code not correctly repeated; try again"
-msgstr "Resetační kód nebyl správně zopakován; zkuste to znovu"
+msgstr "PIN není zopakován správně; zkuste to znovu"
 
+#, fuzzy
 msgid "PUK not correctly repeated; try again"
-msgstr "PUK nebyl zopakován správně; zkuste to znovu"
+msgstr "PIN není zopakován správně; zkuste to znovu"
 
 msgid "PIN not correctly repeated; try again"
-msgstr "PIN nebyl zopakován správně; zkuste to znovu"
+msgstr "PIN ne zopakován správně; zkuste to znovu"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Please enter the PIN%s%s%s to unlock the card"
-msgstr "Prosím, vložte PIN%s%s%s, abyste odemkl(a) kartu"
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error creating temporary file: %s\n"
-msgstr "chyba při vytváření dočasného souboru: %s\n"
+msgstr "chyba při vytváření hesla: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing to temporary file: %s\n"
-msgstr "chyba při zápisu do dočasného souboru: %s\n"
+msgstr "%s: chyba při zápisu adresářového záznamu: %s\n"
 
+#, fuzzy
 msgid "Enter new passphrase"
-msgstr "Vložte nové heslo"
+msgstr "Vložit heslo\n"
 
+#, fuzzy
 msgid "Take this one anyway"
-msgstr "Použít přesto tento klíč"
+msgstr "Použít přesto tento klíč? (a/N) "
 
 #, c-format
 msgid ""
@@ -278,14 +221,7 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
 "at least %u characters long."
 msgstr[0] ""
-"Varování: Zadali jste nebezpečné heslo.%%0AHeslo by mělo být alespoň %u znak "
-"dlouhé."
 msgstr[1] ""
-"Varování: Zadali jste nebezpečné heslo.%%0AHeslo by mělo být alespoň %u "
-"znaky dlouhé."
-msgstr[2] ""
-"Varování: Zadali jste nebezpečné heslo.%%0AHeslo by mělo být alespoň %u "
-"znaků dlouhé."
 
 #, c-format
 msgid ""
@@ -295,244 +231,243 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
 "contain at least %u digits or%%0Aspecial characters."
 msgstr[0] ""
-"Varování: Zadali jste nebezpečné heslo.%%0AHeslo by mělo obsahovat alespoň "
-"%u číslici nebo %%0Azvláštní znak."
 msgstr[1] ""
-"Varování: Zadali jste nebezpečné heslo.%%0AHeslo by mělo obsahovat alespoň "
-"%u číslice nebo %%0Azvláštní znaky."
-msgstr[2] ""
-"Varování: Zadali jste nebezpečné heslo.%%0AHeslo by mělo obsahovat alespoň "
-"%u číslic nebo %%0Azvláštních znaků."
 
 #, c-format
 msgid ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
 "a known term or match%%0Acertain pattern."
 msgstr ""
-"Varování: Zadali jste nebezpečné heslo.%%0AHeslo by nemělo být známým slovem "
-"nebo se shodovat%%0As určitým vzorem."
 
 #, c-format
 msgid ""
 "You have not entered a passphrase!%0AAn empty passphrase is not allowed."
-msgstr "Nezadali jste heslo!%0APrázdné heslo není dovoleno."
+msgstr ""
 
 #, c-format
 msgid ""
 "You have not entered a passphrase - this is in general a bad idea!%0APlease "
 "confirm that you do not want to have any protection on your key."
 msgstr ""
-"Nezadali jste heslo – toto je obecně špatný nápad!%0AProsím, potvrďte, že si "
-"žádnou ochranu svého klíče nepřejete."
 
 msgid "Yes, protection is not needed"
-msgstr "Ano, ochrana není třeba"
+msgstr ""
 
-#, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
-msgstr "Pro ochranu svého nového klíče,%0Aprosím, zadejte heslo"
+#, fuzzy, c-format
+msgid "Please enter the passphrase to%0Ato protect your new key"
+msgstr ""
+"Pro ochranu Vašeho tajného klíče musíte zadat heslo.\n"
+"\n"
 
+#, fuzzy
 msgid "Please enter the new passphrase"
-msgstr "Prosím, zadejte nové heslo"
+msgstr "změnit heslo"
 
+#, fuzzy
 msgid ""
 "@Options:\n"
 " "
 msgstr ""
-"@Volby:\n"
+"@\n"
+"Možnosti:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "běžet v režimu démona (na pozadí)"
-
 msgid "run in server mode (foreground)"
-msgstr "běžet v režimu serveru (na popředí)"
+msgstr "poběží v režimu serveru (na popředí)"
 
+msgid "run in daemon mode (background)"
+msgstr "poběží v režimu démona (na pozadí)"
+
+#, fuzzy
 msgid "verbose"
-msgstr "s dodatečnými informacemi"
+msgstr ""
+"s dodatečnými informacemi\n"
 
+#, fuzzy
 msgid "be somewhat more quiet"
-msgstr "být o trochu víc tichý"
+msgstr ""
+"být o trochu víc tichý\n"
 
 msgid "sh-style command output"
-msgstr "vypisovat příkazy ve stylu sh"
+msgstr "výstup příkazů ve stylu sh"
 
 msgid "csh-style command output"
-msgstr "vypisovat příkazy ve stylu csh"
+msgstr "výstup příkazů ve stylu csh"
 
 msgid "|FILE|read options from FILE"
-msgstr "|SOUBOR|načíst volby ze SOUBORU"
+msgstr "|SOUBOR|načte volby ze SOUBORU"
 
 msgid "do not detach from the console"
-msgstr "neodpojovat se od konzole"
+msgstr "neodpojí se od konzole"
 
 msgid "do not grab keyboard and mouse"
-msgstr "neuzurpovat si klávesnici a myš"
+msgstr ""
 
+#, fuzzy
 msgid "use a log file for the server"
-msgstr "použít pro server soubor s protokolem"
+msgstr "vyhledat klíče na serveru klíčů"
 
+#, fuzzy
 msgid "use a standard location for the socket"
-msgstr "použít standardní umístění socketu"
+msgstr "nastavit sadu preferencí pro vybrané uživatelské ID"
 
 msgid "|PGM|use PGM as the PIN-Entry program"
-msgstr "|PROGRAM|použít PROGRAM jako PIN-Entry program"
+msgstr ""
 
 msgid "|PGM|use PGM as the SCdaemon program"
-msgstr "|PROGRAM|použít PROGRAM jako SCdaemon program"
+msgstr ""
 
+#, fuzzy
 msgid "do not use the SCdaemon"
-msgstr "nepoužívat SCdémona"
+msgstr "aktualizovat databázi důvěry"
 
 msgid "ignore requests to change the TTY"
-msgstr "ignorovat požadavky na změnu TTY"
+msgstr ""
 
 msgid "ignore requests to change the X display"
-msgstr "ignorovat požadavky na změnu X displeje"
+msgstr ""
 
 msgid "|N|expire cached PINs after N seconds"
-msgstr "|N|zahodit zapamatované PINy po N sekundách"
+msgstr ""
 
 msgid "do not use the PIN cache when signing"
-msgstr "nepoužívat paměť PINů na podepisování"
+msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
-msgstr "nedovolit klientům označovat klíče za „důvěryhodné“"
+msgid "allow clients to mark keys as \"trusted\""
+msgstr ""
 
+#, fuzzy
 msgid "allow presetting passphrase"
-msgstr "umožnit přednastavení hesla"
-
-msgid "enable ssh support"
-msgstr "zapnout podporu pro OpenSSH"
-
-msgid "enable putty support"
-msgstr "zapnout podporu pro PuTTY"
+msgstr "chyba při vytváření hesla: %s\n"
 
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "nedovolit opakovat stará hesla"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
-msgstr "|SOUBOR|zapsat nastavení prostředí též do SOUBORU"
+msgstr ""
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
 msgid "Please report bugs to <@EMAIL@>.\n"
 msgstr ""
-"Chyby v programu, prosím, oznamujte (anglicky) na <@EMAIL@>,\n"
-"připomínky k překladu hlaste (česky) na <translations.cs@gnupg.cz>.\n"
+"Prosím, chyby v programu hlaste (anglicky) na <@EMAIL@>,\n"
+"chyby v překladu (česky) na <translations.cs@gnupg.cz>.\n"
 
+#, fuzzy
 msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Použití: gpg-agent [VOLBY] (-h pro nápovědu)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: gpg-agent [options] [command [args]]\n"
 "Secret key management for GnuPG\n"
 msgstr ""
-"Syntaxe: gpg-agent [VOLBY] [PŘÍKAZ [ARGUMENTY]]\n"
-"Správa tajných klíčů pro GnuPG\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr "zadána neplatná úroveň ladění „%s“\n"
 
+# První argument je název knihovny
 #, c-format
 msgid "%s is too old (need %s, have %s)\n"
-msgstr "%s je příliš stará (potřebuji %s, mám %s)\n"
+msgstr "%s je příliš stará (potřeba %s, přítomna %s)\n"
 
-#, c-format
-msgid "NOTE: no default option file `%s'\n"
-msgstr "POZNÁMKA: neexistuje implicitní soubor s možnostmi „%s“\n"
+#, fuzzy, c-format
+msgid "NOTE: no default option file '%s'\n"
+msgstr ""
+"POZNÁMKA: neexistuje implicitní soubor s možnostmi `%s'\n"
 
-#, c-format
-msgid "option file `%s': %s\n"
-msgstr "soubor s možnostmi „%s“: %s\n"
+#, fuzzy, c-format
+msgid "option file '%s': %s\n"
+msgstr ""
+"soubor s možnostmi `%s': %s\n"
 
-#, c-format
-msgid "reading options from `%s'\n"
-msgstr "čtu možnosti z „%s“\n"
+#, fuzzy, c-format
+msgid "reading options from '%s'\n"
+msgstr ""
+"čtu možnosti z `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
-msgstr "chyba při vytváření „%s“: %s\n"
+msgid "error creating '%s': %s\n"
+msgstr "chyba při vytváření `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "nemohu vytvořit adresář „%s“: %s\n"
+msgid "can't create directory '%s': %s\n"
+msgstr "nemohu vytvořit adresář `%s': %s\n"
 
 msgid "name of socket too long\n"
 msgstr "název socketu je příliš dlouhý\n"
 
 #, c-format
 msgid "can't create socket: %s\n"
-msgstr "nemohu vytvořit socket: %s\n"
+msgstr "socket nelze vytvořit: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
-msgstr "název socketu „%s“ je příliš dlouhý\n"
+msgid "socket name '%s' is too long\n"
+msgstr ""
 
+#, fuzzy
 msgid "a gpg-agent is already running - not starting a new one\n"
-msgstr "gpg-agent již běží – nový nebude spuštěn\n"
+msgstr "gpg-agent není v tomto sezení dostupný\n"
 
 msgid "error getting nonce for the socket\n"
-msgstr "chyba při získání náhodného řetězce pro socket\n"
+msgstr "chyba při získávání soli pro socket\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
-msgstr "chyba při přilepování socketu na „%s“: %s\n"
+msgid "error binding socket to '%s': %s\n"
+msgstr "chyba při přilepování socketu ne „%s“: %s\n"
 
 #, c-format
 msgid "listen() failed: %s\n"
-msgstr "služba listen() selhala: %s\n"
+msgstr "volání listen() selhalo: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
-msgstr "naslouchám na socketu „%s“\n"
+msgid "listening on socket '%s'\n"
+msgstr "naslouchá se na socketu „%s“\n"
 
 #, c-format
-msgid "directory `%s' created\n"
-msgstr "adresář „%s“ vytvořen\n"
+msgid "directory '%s' created\n"
+msgstr "adresář `%s' vytvořen\n"
 
-#, c-format
-msgid "stat() failed for `%s': %s\n"
-msgstr "stat() na „%s“ selhal: %s\n"
+#, fuzzy, c-format
+msgid "stat() failed for '%s': %s\n"
+msgstr "fstat(%d) selhal v %s: %s\n"
 
-#, c-format
-msgid "can't use `%s' as home directory\n"
-msgstr "„%s“ nelze použít jako domovský adresář\n"
+#, fuzzy, c-format
+msgid "can't use '%s' as home directory\n"
+msgstr "nemohu vytvořit adresář `%s': %s\n"
 
 #, c-format
 msgid "error reading nonce on fd %d: %s\n"
-msgstr "chyba při čtení náhodného řetězce z fd %d: %s\n"
+msgstr "chyba při čtení soli z deskriptoru %d: %s\n"
 
 #, c-format
 msgid "handler 0x%lx for fd %d started\n"
-msgstr "obsluha 0x%lx pro fd %d spuštěna\n"
+msgstr ""
 
 #, c-format
 msgid "handler 0x%lx for fd %d terminated\n"
-msgstr "obsluha 0x%lx pro fd %d ukončena\n"
+msgstr ""
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d started\n"
-msgstr "SSH obsluha 0x%lx pro fd %d spuštěna\n"
+msgstr ""
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d terminated\n"
-msgstr "SSH obsluha 0x%lx pro fd %d ukončena\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "pth_select selhala: %s – čekám 1 s\n"
+msgstr "aktualizace tajného klíče selhala: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s %s stopped\n"
-msgstr "%s %s pozastaveno\n"
+msgstr "%s: přeskočeno: %s\n"
 
+#, fuzzy
 msgid "no gpg-agent running in this session\n"
-msgstr "v této relaci neběží žádný gpg-agent\n"
+msgstr "gpg-agent není v tomto sezení dostupný\n"
 
 msgid "malformed GPG_AGENT_INFO environment variable\n"
 msgstr "špatný formát proměnné prostředí GPG_AGENT_INFO\n"
@@ -541,15 +476,14 @@ msgstr "špatný formát proměnné prostředí GPG_AGENT_INFO\n"
 msgid "gpg-agent protocol version %d is not supported\n"
 msgstr "gpg-agent protokol verze %d není podporován\n"
 
+#, fuzzy
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
-msgstr "Použití: gpg-preset-passphrase [VOLBY] KEYGRIP (-h pro nápovědu)\n"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
 "Password cache maintenance\n"
 msgstr ""
-"Syntaxe: gpg-preset-passphrase [VOLBY] KEYGRIP\n"
-"Správa dočasné paměti pro hesla\n"
 
 msgid ""
 "@Commands:\n"
@@ -558,85 +492,86 @@ msgstr ""
 "@Příkazy:\n"
 " "
 
+#, fuzzy
 msgid ""
 "@\n"
 "Options:\n"
 " "
 msgstr ""
 "@\n"
-"Volby:\n"
-" "
+"Možnosti:\n"
+" \n"
 
+#, fuzzy
 msgid "Usage: gpg-protect-tool [options] (-h for help)\n"
-msgstr "Použití: gpg-protect-tool [VOLBY] (-h pro nápovědu)\n"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: gpg-protect-tool [options] [args]\n"
 "Secret key maintenance tool\n"
 msgstr ""
-"Syntaxe: gpg-protect-tool [VOLBY] [ARGUMENTY]nNástroj na správu tajných "
-"klíčů\n"
 
+#, fuzzy
 msgid "Please enter the passphrase to unprotect the PKCS#12 object."
-msgstr "Prosím, vložte heslo, abyste zpřístupnili objekt PKCS#12."
+msgstr "Prosím, vložte heslo; toto je tajná věta \n"
 
+#, fuzzy
 msgid "Please enter the passphrase to protect the new PKCS#12 object."
-msgstr "Prosím, vložte heslo, abyste ochránili nový objekt PKCS#12."
+msgstr "Prosím, vložte heslo; toto je tajná věta \n"
 
 msgid ""
 "Please enter the passphrase to protect the imported object within the GnuPG "
 "system."
 msgstr ""
-"Prosím, zadejte heslo, abyste ochránili importovaný objekt uvnitř systému "
-"GnuPG."
 
+#, fuzzy
 msgid ""
 "Please enter the passphrase or the PIN\n"
 "needed to complete this operation."
-msgstr ""
-"Prosím, vložte heslo nebo PIN\n"
-"potřebný pro dokončení této operace."
+msgstr "Prosím, vložte heslo; toto je tajná věta \n"
 
+#, fuzzy
 msgid "Passphrase:"
-msgstr "Heslo:"
+msgstr "špatné heslo"
 
+#, fuzzy
 msgid "cancelled\n"
-msgstr "zrušeno\n"
+msgstr "zrušeno"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error while asking for the passphrase: %s\n"
-msgstr "chyba při ptaní se na heslo: %s\n"
+msgstr "chyba při vytváření hesla: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "chyba při otevírání „%s“: %s\n"
 
-#, c-format
-msgid "file `%s', line %d: %s\n"
-msgstr "soubor „%s“, řádek %d: %s\n"
+#, fuzzy, c-format
+msgid "file '%s', line %d: %s\n"
+msgstr "soubor s možnostmi `%s': %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
-msgstr "ignorováno sdělení „%s“ z „%s“, řádku %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
+msgstr ""
 
-#, c-format
-msgid "system trustlist `%s' not available\n"
-msgstr "systémový důvěryhodný seznam „%s“ není dostupný\n"
+#, fuzzy, c-format
+msgid "system trustlist '%s' not available\n"
+msgstr "tajné části klíče nejsou dostupné\n"
 
-#, c-format
-msgid "bad fingerprint in `%s', line %d\n"
-msgstr "chybný otisk v „%s“, řádek %d\n"
+#, fuzzy, c-format
+msgid "bad fingerprint in '%s', line %d\n"
+msgstr "chyba při čtení v `%s': %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
-msgstr "neplatný příznak klíče v „%s“, řádek %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
+msgstr ""
 
-#, c-format
-msgid "error reading `%s', line %d: %s\n"
-msgstr "chyba při čtení „%s“, řádek %d: %s\n"
+#, fuzzy, c-format
+msgid "error reading '%s', line %d: %s\n"
+msgstr "chyba při čtení `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
-msgstr "chyba při čtení seznamu důvěryhodných kořenových certifikátů\n"
+msgstr ""
 
 #. TRANSLATORS: This prompt is shown by the Pinentry
 #. and has one special property: A "%%0A" is used by
@@ -651,14 +586,13 @@ msgid ""
 "Do you ultimately trust%%0A  \"%s\"%%0Ato correctly certify user "
 "certificates?"
 msgstr ""
-"Věříte bezmezně, že%%0A  „%s“%%0Ařádně ověřuje identitu uživatele při "
-"vydávání certifikátu?"
 
+#, fuzzy
 msgid "Yes"
-msgstr "Ano"
+msgstr "ano"
 
 msgid "No"
-msgstr "Ne"
+msgstr ""
 
 #. TRANSLATORS: This prompt is shown by the Pinentry and has
 #. one special property: A "%%0A" is used by Pinentry to
@@ -673,68 +607,68 @@ msgid ""
 "Please verify that the certificate identified as:%%0A  \"%s\"%%0Ahas the "
 "fingerprint:%%0A  %s"
 msgstr ""
-"Prosím ověřte, že certifikát rozpoznaný jako:%%0A  „%s“%%0Amá otisk:%%0A  %s"
 
 #. TRANSLATORS: "Correct" is the label of a button and intended
 #. to be hit if the fingerprint matches the one of the CA.  The
 #. other button is "the default "Cancel" of the Pinentry.
 msgid "Correct"
-msgstr "V pořádku"
+msgstr ""
 
 msgid "Wrong"
-msgstr "Špatně"
+msgstr ""
 
 #, c-format
 msgid "Note: This passphrase has never been changed.%0APlease change it now."
-msgstr "Poznámka: Toto heslo nikdy nebylo změněno.%0AProsím, nyní jej změňte."
+msgstr ""
 
 #, c-format
 msgid ""
 "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s.  Please change "
 "it now."
-msgstr "Toto heslo se nezměnilo%%0Aod %.4s-%.2s-%.2s. Prosím, nyní jej změňte."
+msgstr ""
 
+#, fuzzy
 msgid "Change passphrase"
-msgstr "Změnit heslo"
+msgstr "změnit heslo"
 
 msgid "I'll change it later"
-msgstr "Změním jej později"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error creating a pipe: %s\n"
-msgstr "chyba při vytváření roury: %s\n"
+msgstr "chyba při vytváření hesla: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't fdopen pipe for reading: %s\n"
-msgstr "nemohu otevřít (fdopen) rouru pro čtení: %s\n"
+msgstr "nemohu otevřít podepsaná data '%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error forking process: %s\n"
-msgstr "chyba při rozdvojování procesu: %s\n"
+msgstr "chyba při čtení `%s': %s\n"
 
 #, c-format
 msgid "waiting for process %d to terminate failed: %s\n"
-msgstr "čekání na konec procesu %d se nezdařilo: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting exit code of process %d: %s\n"
-msgstr "chyba při získání návratového kódu procesu %d: %s\n"
+msgstr "chyba při získání informací o aktuálním klíči: %s\n"
 
-#, c-format
-msgid "error running `%s': exit status %d\n"
-msgstr "chyba v běhu „%s“: návratový kód %d\n"
+#, fuzzy, c-format
+msgid "error running '%s': exit status %d\n"
+msgstr "chyba při čtení `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "chyba při spouštění „%s“: pravděpodobně není nainstalován\n"
+msgid "error running '%s': probably not installed\n"
+msgstr ""
 
-#, c-format
-msgid "error running `%s': terminated\n"
-msgstr "chyba v běhu „%s“: násilně ukončeno\n"
+#, fuzzy, c-format
+msgid "error running '%s': terminated\n"
+msgstr "chyba při čtení `%s': %s\n"
 
 #, c-format
 msgid "error creating socket: %s\n"
-msgstr "chyba při vytváření socketu: %s\n"
+msgstr "chyba při tvorbě socketu: %s\n"
 
 msgid "host not found"
 msgstr "stroj nenalezen"
@@ -743,34 +677,35 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent není v tomto sezení dostupný\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
-msgstr "nemohu se připojit k „%s“: %s\n"
+msgid "can't connect to '%s': %s\n"
+msgstr "nemohu se připojit k `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
-msgstr "problémy v komunikaci s gpg-agentem\n"
+msgstr ""
 
 msgid "problem setting the gpg-agent options\n"
-msgstr "problém v nastavování voleb gpg-agenta\n"
+msgstr ""
 
+#, fuzzy
 msgid "canceled by user\n"
 msgstr "zrušeno uživatelem\n"
 
+#, fuzzy
 msgid "problem with the agent\n"
-msgstr "problém s agentem\n"
+msgstr "problém s agentem - používání agenta vypnuto\n"
 
 #, c-format
 msgid "can't disable core dumps: %s\n"
 msgstr "nemohu vypnout vytváření core souborů: %s\n"
 
-# TODO: i18n of first %s
-#, c-format
+#, fuzzy, c-format
 msgid "Warning: unsafe ownership on %s \"%s\"\n"
-msgstr "Varování: vlastnictví %s „%s“ není nastaveno bezpečně\n"
+msgstr ""
+"VAROVÁNÍ: vlastnictví rozšiřujícího modulu není nastaveno bezpečně `%s'\n"
 
-# TODO: i18n of first %s
-#, c-format
+#, fuzzy, c-format
 msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgstr "Varování: přístupová práva %s „%s“ nejsou bezpečná\n"
+msgstr "VAROVÁNÍ: přístupová práva rozšiřujícímu modulu nejsou bezpečná `%s'\n"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "yes"
@@ -809,165 +744,155 @@ msgstr "zZ"
 
 #, c-format
 msgid "out of core in secure memory while allocating %lu bytes"
-msgstr "při pokusu alokovat %lu bajtů došla bezpečná paměť"
+msgstr ""
 
 #, c-format
 msgid "out of core while allocating %lu bytes"
-msgstr "při pokusu alokovat %lu bajtů došla paměť"
+msgstr ""
 
 msgid "no running gpg-agent - starting one\n"
-msgstr "gpg-agent neběží – spouští se\n"
-
-# TODO: Plural
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "čeká se %d s, než se objeví agent\n"
+msgstr ""
 
 msgid "can't connect to the agent - trying fall back\n"
-msgstr "k agentu se nelze připojit – zkouším náhradní způsob\n"
+msgstr ""
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
 msgid "|audit-log-result|Good"
-msgstr "|audit-log-result|V pořádku"
+msgstr ""
 
 msgid "|audit-log-result|Bad"
-msgstr "|audit-log-result|Špatný"
+msgstr ""
 
 msgid "|audit-log-result|Not supported"
-msgstr "|audit-log-result|Není podporováno"
+msgstr ""
 
+#, fuzzy
 msgid "|audit-log-result|No certificate"
-msgstr "|audit-log-result|Žádný certifikát"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|Není zapnuto"
+msgstr "špatný certifikát"
 
 msgid "|audit-log-result|Error"
-msgstr "|audit-log-result|Chyba"
-
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|Není použito"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|V pořádku"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|Přeskočeno"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|Některý"
+msgstr ""
 
+#, fuzzy
 msgid "Certificate chain available"
-msgstr "Je k dispozici řetěz certifikátů"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "root certificate missing"
-msgstr "chybí kořenový certifikát"
+msgstr "špatný certifikát"
 
 msgid "Data encryption succeeded"
-msgstr "Šifrování dat uspělo"
+msgstr ""
 
+#, fuzzy
 msgid "Data available"
-msgstr "Data k dispozici"
+msgstr "vypiš všechna dostupná data"
 
+#, fuzzy
 msgid "Session key created"
-msgstr "Vytvořen klíč relace"
+msgstr "%s: soubor klíčů (keyring) vytvořen\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "algorithm: %s"
-msgstr "algoritmus: %s"
+msgstr "platnost: %s"
 
-#, c-format
+#, fuzzy, c-format
 msgid "unsupported algorithm: %s"
-msgstr "nepodporovaný algoritmus: %s"
+msgstr ""
+"\n"
+"Podporované algoritmy:\n"
 
+#, fuzzy
 msgid "seems to be not encrypted"
-msgstr "zdá se nebýt zašifrováno"
+msgstr "nezašifrováno"
 
+#, fuzzy
 msgid "Number of recipients"
-msgstr "Počet příjemců"
+msgstr "Aktuální příjemci:\n"
 
 #, c-format
 msgid "Recipient %d"
-msgstr "Příjemce %d"
+msgstr ""
 
 msgid "Data signing succeeded"
-msgstr "Podepisování dat uspělo"
-
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "hashovací algoritmus dat: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "Podepisovatel %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "hashovací algoritmus atributu: %s"
+msgstr ""
 
 msgid "Data decryption succeeded"
-msgstr "Dešifrování dat uspělo"
-
-msgid "Encryption algorithm supported"
-msgstr "Šifrovací algoritmus podporován"
+msgstr ""
 
+#, fuzzy
 msgid "Data verification succeeded"
-msgstr "Ověření dat uspělo"
+msgstr "verifikace podpisu potlačena\n"
 
+#, fuzzy
 msgid "Signature available"
-msgstr "Podpis je k dispozici"
+msgstr "Podpis vytvořen %s\n"
 
-msgid "Parsing data succeeded"
-msgstr "Rozebírání dat uspělo"
+#, fuzzy
+msgid "Parsing signature succeeded"
+msgstr "Dobrý podpis od \"%s\""
 
-#, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "chybný hashovací algoritmus dat: %s"
+#, fuzzy, c-format
+msgid "Bad hash algorithm: %s"
+msgstr "neplatný hashovací algoritmus `%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature %d"
-msgstr "Podpis %d"
+msgstr "Podpis vytvořen %s\n"
 
+#, fuzzy
 msgid "Certificate chain valid"
-msgstr "Řetěz certifikátů je platný"
+msgstr "Platnost klíče vypršela!"
 
+#, fuzzy
 msgid "Root certificate trustworthy"
-msgstr "Kořenový certifikát je důvěryhodný"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "no CRL found for certificate"
-msgstr "pro certifikát nebyl nalezen žádný CRL"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "the available CRL is too old"
-msgstr "dostupný CRL je příliš starý"
+msgstr "Klíč k dispozici na: "
 
+#, fuzzy
 msgid "CRL/OCSP check of certificates"
-msgstr "Kontrola certifikátů proti CRL/OCSP"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "Included certificates"
-msgstr "Zahrnuté certifikáty"
+msgstr "špatný certifikát"
 
 msgid "No audit log entries."
-msgstr "Žádné položky auditního protokolu."
+msgstr ""
 
+#, fuzzy
 msgid "Unknown operation"
-msgstr "Neznámá operace"
+msgstr "neznámá verze"
 
 msgid "Gpg-Agent usable"
-msgstr "Gpg-Agent je použitelný"
+msgstr ""
 
 msgid "Dirmngr usable"
-msgstr "Dirmngr je použitelný"
+msgstr ""
 
-#, c-format
-msgid "No help available for `%s'."
-msgstr "Nápověda pro „%s“ není dostupná.'"
+#, fuzzy, c-format
+msgid "No help available for '%s'."
+msgstr "Pomoc není dostupná pro '%s'"
 
+#, fuzzy
 msgid "ignoring garbage line"
-msgstr "ignoruji řádek s nepořádkem"
+msgstr "chyba v patičce\n"
 
+# Čas ve formátu ISO
 msgid "[none]"
-msgstr "[není nastaveno]"
+msgstr "[neuvedeno]"
 
 #, c-format
 msgid "armor: %s\n"
@@ -982,8 +907,9 @@ msgstr "ASCII hlavička: "
 msgid "invalid clearsig header\n"
 msgstr "neplatná hlavička podpisu v čitelném formátu\n"
 
+#, fuzzy
 msgid "unknown armor header: "
-msgstr "neznámá ASCII hlavička: "
+msgstr "ASCII hlavička: "
 
 msgid "nested clear text signatures\n"
 msgstr "vnořené podpisy v čitelném formátu\n"
@@ -1027,7 +953,7 @@ msgstr "neplatné kódování ASCII: řádek je delší než %d znaků\n"
 msgid ""
 "quoted printable character in armor - probably a buggy MTA has been used\n"
 msgstr ""
-"neplatný znak (quoted-printable) v ASCII kódování – pravděpodobně byl použit "
+"neplatný znak (quoted-printable) v ASCII kódování - pravděpodobně byl použit "
 "špatný MTA\n"
 
 msgid ""
@@ -1035,13 +961,13 @@ msgid ""
 "an '='\n"
 msgstr ""
 "symbolické jméno smí obsahovat pouze písmena, číslice, tečky nebo podtržítka "
-"a musí končit znakem „=“\n"
+"a musí končit znakem '='\n"
 
 msgid "a user notation name must contain the '@' character\n"
-msgstr "zápis jména uživatele musí obsahovat znak „@“\n"
+msgstr "jméno uživatele musí obsahovat znakt '@' \n"
 
 msgid "a notation name must not contain more than one '@' character\n"
-msgstr "jméno uživatele nesmí obsahovat více než jeden znak „@“\n"
+msgstr "jméno uživatele nesmí obsahovat více než jeden znak '@' \n"
 
 msgid "a notation value must not use any control characters\n"
 msgstr "hodnota nemůže obsahovat žádné kontrolní znaky\n"
@@ -1054,7 +980,7 @@ msgstr "není v přímo čitelném formátu"
 
 #, c-format
 msgid "OpenPGP card not available: %s\n"
-msgstr "OpenPGP karta není dostupná: %s\n"
+msgstr "OpenPGp karta není dostupná: %s\n"
 
 #, c-format
 msgid "OpenPGP card no. %s detected\n"
@@ -1063,11 +989,13 @@ msgstr "Nalezena OpenPGP karta číslo %s\n"
 msgid "can't do this in batch mode\n"
 msgstr "nelze provést v dávkovém módu\n"
 
+#, fuzzy
 msgid "This command is only available for version 2 cards\n"
-msgstr "Tento příkaz je dostupný pouze pro karty verze 2\n"
+msgstr "Tento příkaz není v módů %s dovolený.\n"
 
+#, fuzzy
 msgid "Reset Code not or not anymore available\n"
-msgstr "Resetační kód není nebo už není dostupný\n"
+msgstr "tajné části klíče nejsou dostupné\n"
 
 msgid "Your selection? "
 msgstr "Váš výběr? "
@@ -1094,7 +1022,7 @@ msgid "Error: Only plain ASCII is currently allowed.\n"
 msgstr "Chyba: V současné verzi je povolenou pouze plain ASCII.\n"
 
 msgid "Error: The \"<\" character may not be used.\n"
-msgstr "Chyba: Znak „<“ nelze použít.\n"
+msgstr "Chyba: Znak \"<\" nelze použít.\n"
 
 msgid "Error: Double spaces are not allowed.\n"
 msgstr "Chyba: Více mezer není povoleno.\n"
@@ -1118,15 +1046,16 @@ msgstr "Chyba: URL je příliš dlouhé (limit je %d znaků).\n"
 
 #, c-format
 msgid "error allocating enough memory: %s\n"
-msgstr "chyba při alokování paměti: %s\n"
+msgstr "chyba při alokování dostatečného množství paměti: %s\n"
 
-#, c-format
-msgid "error reading `%s': %s\n"
-msgstr "chyba při čtení „%s“: %s\n"
+#, fuzzy, c-format
+msgid "error reading '%s': %s\n"
+msgstr ""
+"chyba při čtení `%s': %s\n"
 
 #, c-format
-msgid "error writing `%s': %s\n"
-msgstr "chyba při zápisu do „%s“: %s\n"
+msgid "error writing '%s': %s\n"
+msgstr "chyba při zapisování do „%s“: %s\n"
 
 msgid "Login data (account name): "
 msgstr "Login (jménu účtu): "
@@ -1146,22 +1075,22 @@ msgid "Language preferences: "
 msgstr "Jazykové předvolby: "
 
 msgid "Error: invalid length of preference string.\n"
-msgstr "Chyba: neplatná délka řetězce s předvolbami.\n"
+msgstr "Chyba: neplatná délka řetezce s předvolbami.\n"
 
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Chyba: neplatný znak v řetězci s předvolbami\n"
 
 msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Zadejte pohlaví: M – mužské, F – ženské, nebo stiskněte mezerník: "
+msgstr "Zadejte pohlaví: M - mužské, F - ženské nebo stisněte mezerník: "
 
 msgid "Error: invalid response.\n"
 msgstr "Chyba: neplatná odpověď.\n"
 
 msgid "CA fingerprint: "
-msgstr "Otisk CA: "
+msgstr "CA fingerprint: "
 
 msgid "Error: invalid formatted fingerprint.\n"
-msgstr "Chyba: chybně utvořené otisk.\n"
+msgstr "Chyba: nesprávně naformátovaný fingerprint.\n"
 
 #, c-format
 msgid "key operation not possible: %s\n"
@@ -1182,22 +1111,18 @@ msgid ""
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
-"POZNÁMKA: Nelze zaručit, že karta podporuje požadovanou velikost.\n"
-"          Pokud generování klíče neuspěje, prosím, nahlédněte do "
-"dokumentace\n"
-"          své karty, kde se dozvíte, jaké velikosti jsou dovoleny.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "Jakou délku klíče pro podepisování si přejete? (%u) "
+msgstr "Jakou délku klíče si přejete? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "Jakou délku klíče pro šifrování si přejete? (%u) "
+msgstr "Jakou délku klíče si přejete? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "Jakou délku klíče pro autentizaci si přejete? (%u) "
+msgstr "Jakou délku klíče si přejete? (%u) "
 
 #, c-format
 msgid "rounded up to %u bits\n"
@@ -1209,17 +1134,18 @@ msgstr "velikost klíče %s musí být v intervalu %u-%u\n"
 
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
-msgstr "Karta bude nyní přenastavena na generování klíče dlouhého %u bitů\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
-msgstr "chyba při změně velikosti klíče %d na %u bitů: %s\n"
+msgstr "chyba při hledání záznamu důvěryhodnosti v `%s': %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr "Vytvořit zálohu šifrovacího klíče mimo kartu? (A/n) "
 
+#, fuzzy
 msgid "NOTE: keys are already stored on the card!\n"
-msgstr "POZNÁMKA: na kartě jsou již klíče uloženy!\n"
+msgstr "tajný klíč je na kartě uložen\n"
 
 msgid "Replace existing keys? (y/N) "
 msgstr "Přepsat existující klíče? (a/N) "
@@ -1231,7 +1157,7 @@ msgid ""
 "You should change them using the command --change-pin\n"
 msgstr ""
 "Prosím nezapomeňte, že tovární nastavení PINu je\n"
-"   PIN = „%s“     PIN administrátora = „%s“\n"
+"   PIN = `%s'     PIN administrátora = `%s'\n"
 "Toto nastavení můžete změnit příkazem --change-pin\n"
 
 msgid "Please select the type of key to generate:\n"
@@ -1256,14 +1182,14 @@ msgid "unknown key protection algorithm\n"
 msgstr "neznámý algoritmus pro ochranu klíče\n"
 
 msgid "secret parts of key are not available\n"
-msgstr "tajné části klíče nejsou dostupné\n"
+msgstr "tajné části klče nejsou dostupné\n"
 
 msgid "secret key already stored on a card\n"
 msgstr "tajný klíč je na kartě uložen\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key to card: %s\n"
-msgstr "chyba při zápisu klíče na kartu: %s\n"
+msgstr "chyba při zápisu souboru klíčů (keyring)  `%s': %s\n"
 
 msgid "quit this menu"
 msgstr "ukončit toto menu"
@@ -1281,7 +1207,7 @@ msgid "change card holder's name"
 msgstr "změní jméno majitele karty"
 
 msgid "change URL to retrieve key"
-msgstr "zmÄ\9bní URL pro získání klíče"
+msgstr "zmÄ\9bní URL pro záskání klíče"
 
 msgid "fetch the key specified in the card URL"
 msgstr "získá klíč specifikovaný v URL karty"
@@ -1296,7 +1222,7 @@ msgid "change card holder's sex"
 msgstr "změní pohlaví držitele karty"
 
 msgid "change a CA fingerprint"
-msgstr "vypsat otisk certifikační autority"
+msgstr "vypsat fingerprint certifikační autority"
 
 msgid "toggle the signature force PIN flag"
 msgstr "zapnout/vypnout požadování PINu při každé self-sign operaci"
@@ -1311,10 +1237,10 @@ msgid "verify the PIN and list all data"
 msgstr "ověř PIN a vypiš všechna data"
 
 msgid "unblock the PIN using a Reset Code"
-msgstr "odblokovat PIN pomocí resetačního kódu"
+msgstr ""
 
-msgid "gpg/card> "
-msgstr "gpg/karta> "
+msgid "Command> "
+msgstr "Příkaz> "
 
 msgid "Admin-only command\n"
 msgstr "pouze administrátorské příkazy\n"
@@ -1326,28 +1252,28 @@ msgid "Admin commands are not allowed\n"
 msgstr "administrátorské příkazy nejsou povoleny\n"
 
 msgid "Invalid command  (try \"help\")\n"
-msgstr "Neplatný příkaz (zkuste „help“)\n"
+msgstr "Neplatný příkaz (zkuste \"help\")\n"
 
 msgid "--output doesn't work for this command\n"
 msgstr "--output pro tento příkaz není platný\n"
 
 #, c-format
-msgid "can't open `%s'\n"
-msgstr "nelze otevřít „%s“\n"
+msgid "can't open '%s'\n"
+msgstr "nelze otevřít `%s'\n"
 
 #, c-format
 msgid "key \"%s\" not found: %s\n"
-msgstr "klíč „%s“ nenalezen: %s\n"
+msgstr "klíč \"%s\" nenalezen: %s\n"
 
 #, c-format
 msgid "error reading keyblock: %s\n"
 msgstr "chyba při čtení bloku klíče: %s\n"
 
 msgid "(unless you specify the key by fingerprint)\n"
-msgstr "(dokud neurčíte klíč jeho otiskem)\n"
+msgstr "(dokud neurčíte klíč jeho fingerprintem)\n"
 
 msgid "can't do this in batch mode without \"--yes\"\n"
-msgstr "bez parametru „--yes“ to nemohu v dávkovém módu provést\n"
+msgstr "bez parametru \"--yes\" to nemohu v dávkovém módu provést\n"
 
 msgid "Delete this key from the keyring? (y/N) "
 msgstr "Smazat tento klíč ze souboru klíčů? (a/N) "
@@ -1357,18 +1283,18 @@ msgstr "Toto je tajný klíč! - opravdu smazat? (a/N) "
 
 #, c-format
 msgid "deleting keyblock failed: %s\n"
-msgstr "smazání bloku klíče se nezdařilo: %s\n"
+msgstr "smazání bloku klíče se nezdařilo:  %s\n"
 
 msgid "ownertrust information cleared\n"
 msgstr "informace o důvěryhodnosti vlastníka klíče vymazány\n"
 
 #, c-format
 msgid "there is a secret key for public key \"%s\"!\n"
-msgstr "tajný klíč pro veřejný klíč „%s“ existuje!\n"
+msgstr "existuje tajný klíč pro tento veřejný klíč \"%s\"!\n"
 
 msgid "use option \"--delete-secret-keys\" to delete it first.\n"
 msgstr ""
-"abyste ho smazal(a), použijte nejprve parametr „--delete-secret-key“.\n"
+"abyste ho smazal(a), použijte nejprve parametr \"--delete-secret-key\".\n"
 
 #, c-format
 msgid "error creating passphrase: %s\n"
@@ -1382,20 +1308,20 @@ msgid "using cipher %s\n"
 msgstr "použití šifry: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
-msgstr "„%s“ je již zkomprimován\n"
+msgid "'%s' already compressed\n"
+msgstr "`%s' je již zkomprimován\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
-msgstr "VAROVÁNÍ: soubor „%s“ je prázdný\n"
+msgid "WARNING: '%s' is an empty file\n"
+msgstr "VAROVÁNÍ: soubor `%s' je prázdný\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr ""
 "v módu --pgp2 můžete šifrovat pouze RSA klíčem o délce 2048 bitů a méně\n"
 
 #, c-format
-msgid "reading from `%s'\n"
-msgstr "čtu z „%s“\n"
+msgid "reading from '%s'\n"
+msgstr "čtu z `%s'\n"
 
 msgid ""
 "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
@@ -1425,7 +1351,7 @@ msgstr "použití %s není v módu %s dovoleno\n"
 
 #, c-format
 msgid "%s/%s encrypted for: \"%s\"\n"
-msgstr "%s/%s zašifrovaný pro: „%s“\n"
+msgstr "%s/%s zašifrovaný pro: %s\n"
 
 #, c-format
 msgid "%s encrypted data\n"
@@ -1457,12 +1383,12 @@ msgstr ""
 "dočasné soubory (temp files)\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
-msgstr "nelze spustit program „%s“: %s\n"
+msgid "unable to execute program '%s': %s\n"
+msgstr "nelze spustit program `%s': %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
-msgstr "nelze spustit shell „%s“: %s\n"
+msgid "unable to execute shell '%s': %s\n"
+msgstr "nelze spustit shell `%s': %s\n"
 
 #, c-format
 msgid "system error while calling external program: %s\n"
@@ -1479,55 +1405,59 @@ msgid "unable to read external program response: %s\n"
 msgstr "nelze přečíst odpověď externího programu: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
-msgstr "VAROVÁNÍ: nelze smazat dočasný soubor (%s) „%s“: %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
+msgstr "VAROVÁNÍ: nelze smazat dočasný soubor (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
-msgstr "VAROVÁNÍ: nelze smazat dočasný adresář „%s“: %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
+msgstr "VAROVÁNÍ: nelze smazat dočasný adresář `%s': %s\n"
 
+#, fuzzy
 msgid "export signatures that are marked as local-only"
-msgstr "exportovat podpisy, které jsou označeny jako jen místní (local-only)"
+msgstr "Podpis bude označen jako neodvolatelný (non-revocable).\n"
 
 msgid "export attribute user IDs (generally photo IDs)"
-msgstr "exportovat atributy uživatelských ID (obecně ID fotografií)"
+msgstr ""
 
+#, fuzzy
 msgid "export revocation keys marked as \"sensitive\""
-msgstr "exportovat revokační klíče označené jako „citlivé“"
+msgstr "pro \"%s\" nebyl nalezen žádný revokační klíč\n"
 
+#, fuzzy
 msgid "remove the passphrase from exported subkeys"
-msgstr "odstranit ochranu heslem z exportovaných podklíčů"
+msgstr "revokovat klíč nebo vybrané podklíče"
 
+#, fuzzy
 msgid "remove unusable parts from key during export"
-msgstr "odstranit nepoužitelné části z klíče při exportu"
+msgstr "odstranit nepoužitelné části z klíče"
 
 msgid "remove as much as possible from key during export"
-msgstr "odstranit při exportu z klíče vše, co lze"
+msgstr ""
 
 msgid "export keys in an S-expression based format"
-msgstr "exportovat klíče ve formátu postaveném na S-výrazech"
+msgstr ""
 
 msgid "exporting secret keys not allowed\n"
 msgstr "exportování tajného klíče není povoleno\n"
 
 #, c-format
 msgid "key %s: not protected - skipped\n"
-msgstr "klíč %s: není chráněný – přeskočeno\n"
+msgstr "klíč %s: není chráněný - přeskočeno\n"
 
 #, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
-msgstr "klíč %s: PGP 2.x klíč – přeskočeno\n"
+msgstr "klíč %s: PGP 2.x klíč - přeskočeno\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: key material on-card - skipped\n"
-msgstr "klíč %s: tělo klíče je na kartě – přeskočeno\n"
+msgstr "klíč %s: podpis podklíče na špatném místě - přeskočeno \n"
 
 msgid "about to export an unprotected subkey\n"
-msgstr "exportovat nechráněné podklíče\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "failed to unprotect the subkey: %s\n"
-msgstr "odemknutí podklíče selhalo: %s\n"
+msgstr "nelze uložit klíč: %s\n"
 
 #, c-format
 msgid "WARNING: secret key %s does not have a simple SK checksum\n"
@@ -1537,25 +1467,22 @@ msgid "WARNING: nothing exported\n"
 msgstr "VAROVÁNÍ: nebylo nic vyexportováno\n"
 
 msgid "too many entries in pk cache - disabled\n"
-msgstr "příliš mnoho položek v bufferu veřejných klíčů – vypnuto\n"
+msgstr "příliš mnoho položek v bufferu veřejných klíčů - vypnuto\n"
 
 msgid "[User ID not found]"
 msgstr "[ID uživatele nenalezeno]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "klíč %s: tajný klíč bez klíče veřejného – přeskočeno\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
-msgstr "„%s“ automaticky získáno přes %s\n"
+msgid "automatically retrieved '%s' via %s\n"
+msgstr ""
 
-#, c-format
-msgid "error retrieving `%s' via %s: %s\n"
-msgstr "chyba při získávání „%s“ přes %s: %s\n"
+#, fuzzy, c-format
+msgid "error retrieving '%s' via %s: %s\n"
+msgstr "chyba při vytváření `%s': %s\n"
 
+#, fuzzy
 msgid "No fingerprint"
-msgstr "Chybí otisk"
+msgstr "CA fingerprint: "
 
 # c-format
 #, c-format
@@ -1564,17 +1491,23 @@ msgstr "Neplatný klíč %s změněn na platný pomocí --always-non-selfsigned-
 
 #, c-format
 msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "neexistuje tajný podklíč pro veřejný klíč %s – ignorováno\n"
+msgstr "neexistuje tajný podklíč pro veřejný klíč %s - ignorováno\n"
 
 #, c-format
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "používám podklíč %s místo primárního klíče %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "klíč %s: tajný klíč bez klíče veřejného - přeskočeno\n"
+
+#, fuzzy
 msgid "make a signature"
-msgstr "vytvořit podpis"
+msgstr "|[soubor]|vytvořit podpis"
 
+#, fuzzy
 msgid "make a clear text signature"
-msgstr "vytvořit podpis v čitelném dokumentu"
+msgstr "|[soubor]|vytvořit podpis v čitelném dokumentu"
 
 msgid "make a detached signature"
 msgstr "vytvořit podpis oddělený od dokumentu"
@@ -1601,7 +1534,7 @@ msgid "list and check key signatures"
 msgstr "vypsat a zkontrolovat podpisy klíčů"
 
 msgid "list keys and fingerprints"
-msgstr "vypsat seznam klíčů a otisků"
+msgstr "vypsat seznam klíčů a fingerprintů"
 
 msgid "list secret keys"
 msgstr "vypsat seznam tajných klíčů"
@@ -1609,9 +1542,6 @@ msgstr "vypsat seznam tajných klíčů"
 msgid "generate a new key pair"
 msgstr "vytvořit nový pár klíčů"
 
-msgid "generate a revocation certificate"
-msgstr "vytvořit revokační certifikát"
-
 msgid "remove keys from the public keyring"
 msgstr "odstranit klíč ze souboru veřejných klíčů"
 
@@ -1627,8 +1557,8 @@ msgstr "podepsat klíč lokálně"
 msgid "sign or edit a key"
 msgstr "podepsat nebo modifikovat klíč"
 
-msgid "change a passphrase"
-msgstr "změnit heslo"
+msgid "generate a revocation certificate"
+msgstr "vytvořit revokační certifikát"
 
 msgid "export keys"
 msgstr "exportovat klíče"
@@ -1660,29 +1590,38 @@ msgstr "změnit PIN karty"
 msgid "update the trust database"
 msgstr "aktualizovat databázi důvěry"
 
+#, fuzzy
 msgid "print message digests"
-msgstr "vypsat hash zprávy"
+msgstr "|algo [soubory]  vypiš hash"
 
 msgid "run in server mode"
-msgstr "pracovat v režimu serveru"
+msgstr ""
 
 msgid "create ascii armored output"
 msgstr "vytvoř výstup zakódovaný pomocí ASCII"
 
+#, fuzzy
 msgid "|USER-ID|encrypt for USER-ID"
-msgstr "|ID_UŽIVATELE|šifrovat pro ID_UŽIVATELE"
+msgstr "|JMÉNO|šifrovat pro JMÉNO"
 
+#, fuzzy
 msgid "|USER-ID|use USER-ID to sign or decrypt"
-msgstr "|ID_UŽIVATELE|použít toto ID_UŽIVATELE pro podepsání nebo dešifrování"
+msgstr ""
+"použít tento id uživatele pro podepsání\n"
+" nebo dešifrování"
 
+#, fuzzy
 msgid "|N|set compress level to N (0 disables)"
-msgstr "|N|nastavit úroveň komprese na N (0 – žádná)"
+msgstr ""
+"|N|nastavit úrověň komprimace N (0 - žádná\n"
+" komprimace)"
 
 msgid "use canonical text mode"
 msgstr "použít kanonický textový mód"
 
+#, fuzzy
 msgid "|FILE|write output to FILE"
-msgstr "|SOUBOR|zapsat výstup do SOUBORU"
+msgstr "čtu možnosti z `%s'\n"
 
 msgid "do not make any changes"
 msgstr "neprovádět žádné změny"
@@ -1698,7 +1637,7 @@ msgid ""
 "(See the man page for a complete listing of all commands and options)\n"
 msgstr ""
 "@\n"
-"(Pro kompletní seznam všech příkazů a možností použijte manuálové stránky.)\n"
+"(Použijte manuálové stránky pro kompletní seznam všech příkazů a možností)\n"
 
 msgid ""
 "@\n"
@@ -1715,19 +1654,19 @@ msgstr ""
 " --clearsign [soubor]       vytvořit podpis čitelného dokumentu\n"
 " --detach-sign [soubor]     vytvořit podpis oddělený od dokumentu\n"
 " --list-keys [jména]        vypsat klíče\n"
-" --fingerprint [jména]      vypsat otisky\n"
+" --fingerprint [jména]      vypsat fingerprinty \n"
 
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Syntaxe: gpg [možnosti] [soubory]\n"
-"Podepisuje, ověřuje, šifruje nebo dešifruje.\n"
-"Výchozí operace závisí na vstupních datech.\n"
+"podepsat, ověřit, šifrovat nebo dešifrovat\n"
+"implicitní operace závisí na vstupních datech\n"
 
 msgid ""
 "\n"
@@ -1755,133 +1694,138 @@ msgid "conflicting commands\n"
 msgstr "konfliktní příkazy\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
-msgstr "no = podpis nalezen v definici skupiny „%s“\n"
+msgid "no = sign found in group definition '%s'\n"
+msgstr "no = podpis nalezen v definici skupiny `%s'\n"
 
+# g10/g10.c:1179#, c-format
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr ""
-"VAROVÁNÍ: vlastnictví domovského adresáře není nastaveno bezpečně „%s“\n"
+"VAROVÁNÍ: vlastnictví domovského adresáře není nastaveno bezpečně `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr ""
-"VAROVÁNÍ: vlastnictví konfiguračního souboru není nastaveno bezpečně „%s“\n"
+"VAROVÁNÍ: vlastnictví konfiguračního souboru není nastaveno bezpečně `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr ""
-"VAROVÁNÍ: vlastnictví rozšiřujícího modulu není nastaveno bezpečně „%s“\n"
+"VAROVÁNÍ: vlastnictví rozšiřujícího modulu není nastaveno bezpečně `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr ""
-"VAROVÁNÍ: přístupová práva pro domovský adresáře nejsou bezpečná „%s“\n"
+"VAROVÁNÍ: přístupová práva pro domovský adresáře nejsou bezpečná `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr ""
-"VAROVÁNÍ: přístupová práva pro konfigurační soubor nejsou bezpečná „%s“\n"
+"VAROVÁNÍ: přístupová práva pro konfigurační soubor nejsou bezpečná `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
-msgstr "VAROVÁNÍ: přístupová práva rozšiřujícímu modulu nejsou bezpečná „%s“\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
+msgstr "VAROVÁNÍ: přístupová práva rozšiřujícímu modulu nejsou bezpečná `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
-"VAROVÁNÍ: vlastnictví adresáře s domovským adresářem není nastaveno "
-"nebezpečně „%s“\n"
+"VAROVÁNÍ: vlastnictví adresáře s domovkým adresářem není nastaveno "
+"nebezpečně `%s'\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
 msgstr ""
 "VAROVÁNÍ: vlastnictví adresáře s konfiguračním souborem není nastaveno "
-"nebezpečně „%s“\n"
+"nebezpečně `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "VAROVÁNÍ: vlastnictví adresáře s rozšiřujícím modulem není nastaveno "
-"nebezpečně „%s“\n"
+"nebezpečně `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 "VAROVÁNÍ: přístupová práva k adresáři s domovským adresářem nejsou nastavena "
-"bezpečně „%s“\n"
+"bezpečně `%s'\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
 msgstr ""
-"VAROVÁNÍ: přístupová práva k adresáři s konfiguračním souborem nejsou "
-"nastavena bezpečně „%s“\n"
+"VAROVÁNÍ: přístupová práva k adersáři s konfiguračním souborem nejsou "
+"nastavena bezpečně `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "VAROVÁNÍ: přístupová práva k adresáři s rozšiřujícím modulem nejsou "
-"nastavena bezpečně „%s“\n"
+"nastavena bezpečně `%s'\n"
 
 # c-format
 #, c-format
-msgid "unknown configuration item `%s'\n"
-msgstr "neznámá konfigurační položka „%s“\n"
+msgid "unknown configuration item '%s'\n"
+msgstr "neznámá konfigurační položka \"%s\"\n"
 
 msgid "display photo IDs during key listings"
-msgstr "zobrazovat ID fotografií během výpisu klíčů"
+msgstr ""
 
 msgid "show policy URLs during signature listings"
-msgstr "ukazovat URL politik během výpisu podpisů"
+msgstr ""
 
+#, fuzzy
 msgid "show all notations during signature listings"
-msgstr "ukazovat všechny poznámky během výpisu podpisů"
+msgstr "V souboru tajných klíčů chybí odpovídající podpis\n"
 
 msgid "show IETF standard notations during signature listings"
-msgstr "ukazovat poznámky IETF standardu během vypisování podpisů"
+msgstr ""
 
 msgid "show user-supplied notations during signature listings"
-msgstr "ukazovat uživatelské poznámky během výpisu podpisů"
+msgstr ""
 
+#, fuzzy
 msgid "show preferred keyserver URLs during signature listings"
-msgstr "ukazovat URL upřednostňovaného serveru klíčů při výpisu podpisů"
+msgstr "zadané URL preferovaného serveru klíčů je neplaté\n"
 
 msgid "show user ID validity during key listings"
-msgstr "ukazovat platnost ID uživatelů při výpisu klíčů"
+msgstr ""
 
 msgid "show revoked and expired user IDs in key listings"
-msgstr "ukazovat odvolané a prošlé ID uživatelů při výpisu klíčů"
+msgstr ""
 
 msgid "show revoked and expired subkeys in key listings"
-msgstr "ukazovat odvolané a prošlé podklíče při výpisu klíčů"
+msgstr ""
 
+#, fuzzy
 msgid "show the keyring name in key listings"
-msgstr "ukazovat název souboru s klíči při výpisu klíčů"
+msgstr "přepnout mezi vypisem seznamu tajných a veřejných klíčů"
 
+#, fuzzy
 msgid "show expiration dates during signature listings"
-msgstr "ukazovat data expirace během výpisu podpisů"
+msgstr "V souboru tajných klíčů chybí odpovídající podpis\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
-msgstr "POZNÁMKA: starý implicitní soubor s možnostmi „%s“ ignorován\n"
+msgid "NOTE: old default options file '%s' ignored\n"
+msgstr "POZNÁMKA: starý implicitní soubor s možnostmi `%s ignorován'\n"
 
 #, c-format
 msgid "libgcrypt is too old (need %s, have %s)\n"
-msgstr "libgcrypt je příliš stará (potřebuji %s, mám %s)\n"
+msgstr ""
 
 #, c-format
 msgid "NOTE: %s is not for normal use!\n"
 msgstr "POZNÁMKA: %s není pro normální použití!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
-msgstr "„%s“ není platná doba expirace podpisu\n"
+msgid "'%s' is not a valid signature expiration\n"
+msgstr "`%s' není platná doba expirace podpisu\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
-msgstr "„%s“ není platná znaková sada\n"
+msgid "'%s' is not a valid character set\n"
+msgstr "`%s' není platná znaková sada\n"
 
 msgid "could not parse keyserver URL\n"
 msgstr "nelze zpracovat URL serveru klíčů\n"
@@ -1915,37 +1859,41 @@ msgid "invalid list options\n"
 msgstr "neplatný parametr pro výpis\n"
 
 msgid "display photo IDs during signature verification"
-msgstr "zobrazovat ID fotografií při ověřování podpisu"
+msgstr ""
 
 msgid "show policy URLs during signature verification"
-msgstr "ukazovat URL politik při ověřování podpisu"
+msgstr ""
 
+#, fuzzy
 msgid "show all notations during signature verification"
-msgstr "ukazovat všechny poznámky při ověřování podpisu"
+msgstr "`%s' není platná doba expirace podpisu\n"
 
 msgid "show IETF standard notations during signature verification"
-msgstr "ukazovat poznámky IETF standardu při ověřování podpisu"
+msgstr ""
 
 msgid "show user-supplied notations during signature verification"
-msgstr "ukazovat uživatelské poznámky při ověřování podpisu"
+msgstr ""
 
+#, fuzzy
 msgid "show preferred keyserver URLs during signature verification"
-msgstr "ukazovat URL upřednostňovaného serveru klíčů při ověřování podpisu"
+msgstr "zadané URL preferovaného serveru klíčů je neplaté\n"
 
+#, fuzzy
 msgid "show user ID validity during signature verification"
-msgstr "ukazovat platnost ID uživatele při ověřování podpisu"
+msgstr "`%s' není platná doba expirace podpisu\n"
 
 msgid "show revoked and expired user IDs in signature verification"
-msgstr "ukazovat odvolané a prošlé ID uživatelů při ověřování podpisů"
+msgstr ""
 
+#, fuzzy
 msgid "show only the primary user ID in signature verification"
-msgstr "ukazovat jen primární ID uživatele při ověřování podpisu"
+msgstr "`%s' není platná doba expirace podpisu\n"
 
 msgid "validate signatures with PKA data"
-msgstr "ověřovat podpisy s daty PKA"
+msgstr ""
 
 msgid "elevate the trust of signatures with valid PKA data"
-msgstr "vyzvednout důvěru podpisů s platnými daty PKA"
+msgstr ""
 
 #, c-format
 msgid "%s:%d: invalid verify options\n"
@@ -1958,12 +1906,12 @@ msgstr "neplatný parametr pro ověření\n"
 msgid "unable to set exec-path to %s\n"
 msgstr "nelze nastavit exec-path na %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: invalid auto-key-locate list\n"
-msgstr "%s:%d: neplatný seznam auto-key-locate\n"
+msgstr "%s:%d: neplatný parametr pro ověření\n"
 
 msgid "invalid auto-key-locate list\n"
-msgstr "neplatný seznam auto-key-locate\n"
+msgstr ""
 
 msgid "WARNING: program may create a core file!\n"
 msgstr "VAROVÁNÍ: program může vytvořit soubor core!\n"
@@ -2005,7 +1953,7 @@ msgid "selected digest algorithm is invalid\n"
 msgstr "vybraný hashovací algoritmus je neplatný\n"
 
 msgid "selected compression algorithm is invalid\n"
-msgstr "vybraný kompresní algoritmus je neplatný\n"
+msgstr "vybraný komprimovací algoritmus je neplatný\n"
 
 msgid "selected certification digest algorithm is invalid\n"
 msgstr "vybraný hashovací algoritmus je neplatný\n"
@@ -2036,7 +1984,7 @@ msgid "invalid S2K mode; must be 0, 1 or 3\n"
 msgstr "neplatný mód S2K; musí být 0, 1 nebo 3\n"
 
 msgid "invalid default preferences\n"
-msgstr "neplatné implicitní předvolby\n"
+msgstr "neplatné defaultní předvolby\n"
 
 msgid "invalid personal cipher preferences\n"
 msgstr "neplatné uživatelské předvolby pro šifrování\n"
@@ -2052,16 +2000,16 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s dosud není funkční s %s\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
-msgstr "použití šifrovacího algoritmu „%s“ v módu %s dovoleno\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgstr "použití šifrovacího algoritmu `%s' v módu %s dovoleno\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
-msgstr "použití hashovacího algoritmu „%s“ v módu %s dovoleno\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgstr "použití hashovacího algoritmu `%s' v módu %s dovoleno\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
-msgstr "použití komprimačního algoritmu „%s“ v módu %s dovoleno\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgstr "použití komprimačního algoritmu `%s' v módu %s dovoleno\n"
 
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
@@ -2078,8 +2026,8 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [jméno souboru]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
-msgstr "symetrické šifrování „%s“ se nepovedlo: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
+msgstr "symetrické šifrování `%s' se nepovedlo: %s\n"
 
 msgid "--encrypt [filename]"
 msgstr "--encrypt [jméno souboru]"
@@ -2128,16 +2076,13 @@ msgstr "--lsign-key id uživatele"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key id uživatele [příkazy]"
 
-msgid "--passwd <user-id>"
-msgstr "--passwd <id-uživatele>"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "odeslání na keyserver se nezdařilo: %s\n"
 
 #, c-format
 msgid "keyserver receive failed: %s\n"
-msgstr "získání dat z serveru klíčů se nezdařilo: %s\n"
+msgstr "získání dat z keyserveru se nezdařilo: %s\n"
 
 #, c-format
 msgid "key export failed: %s\n"
@@ -2145,11 +2090,11 @@ msgstr "export klíče se nepodařil: %s\n"
 
 #, c-format
 msgid "keyserver search failed: %s\n"
-msgstr "hledání na serveru klíčů se nezdařilo: %s\n"
+msgstr "hledání na keyserveru se nezdařilo: %s\n"
 
 #, c-format
 msgid "keyserver refresh failed: %s\n"
-msgstr "obnovení dat na serveru klíčů se nezdařilo: %s\n"
+msgstr "refresh dat na keyserveru se nezdařil: %s\n"
 
 #, c-format
 msgid "dearmoring failed: %s\n"
@@ -2160,8 +2105,8 @@ msgid "enarmoring failed: %s\n"
 msgstr "kódování do ASCII formátu selhalo: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
-msgstr "neplatný hashovací algoritmus „%s“\n"
+msgid "invalid hash algorithm '%s'\n"
+msgstr "neplatný hashovací algoritmus `%s'\n"
 
 msgid "[filename]"
 msgstr "[jméno souboru]"
@@ -2176,10 +2121,11 @@ msgid "the given signature policy URL is invalid\n"
 msgstr "zadané URL pro podepisovací politiku je neplatné\n"
 
 msgid "the given preferred keyserver URL is invalid\n"
-msgstr "zadané URL preferovaného serveru klíčů je neplatné\n"
+msgstr "zadané URL preferovaného serveru klíčů je neplaté\n"
 
+#, fuzzy
 msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|SOUBOR|brát klíče z klíčenky (keyringu) SOUBOR"
+msgstr "ber klíče z této klíčenky (keyringu)"
 
 msgid "make timestamp conflicts only a warning"
 msgstr "pouze varování při konfliktu časového razítka"
@@ -2188,47 +2134,46 @@ msgid "|FD|write status info to this FD"
 msgstr "|FD|zapsat informace o stavu do tohoto FD"
 
 msgid "Usage: gpgv [options] [files] (-h for help)"
-msgstr "Použití: gpg [volby] [soubory] (-h pro pomoc)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
+#, fuzzy
 msgid ""
 "Syntax: gpgv [options] [files]\n"
 "Check signatures against known trusted keys\n"
 msgstr ""
-"Syntaxe: gpgv [volby] [soubory]\n"
-"Ověří podpisy proti známým důvěryhodným klíčům\n"
+"Syntaxe: gpg [volby] [souboru]\n"
+"Ověří podpisy proti známým, důvěryhodným klíčům\n"
 
 msgid "No help available"
-msgstr "Nápověda není k dispozici"
+msgstr "Pomoc není k dispozici"
 
 #, c-format
-msgid "No help available for `%s'"
-msgstr "Pro „%s“ není dostupná žádná nápověda"
+msgid "No help available for '%s'"
+msgstr "Pomoc není dostupná pro '%s'"
 
 msgid "import signatures that are marked as local-only"
-msgstr "importovat podpisy, které jsou označeny jen jako místní"
+msgstr ""
 
 msgid "repair damage from the pks keyserver during import"
-msgstr "opravit poškození vzniklá při importu z PKS serveru"
+msgstr ""
 
 #, fuzzy
-#| msgid "do not update the trustdb after import"
-msgid "do not clear the ownertrust values during import"
-msgstr "neaktualizovat databázi důvěry po importu"
-
 msgid "do not update the trustdb after import"
-msgstr "neaktualizovat databázi důvěry po importu"
+msgstr "aktualizovat databázi důvěry"
 
+#, fuzzy
 msgid "create a public key when importing a secret key"
-msgstr "vytvořit veřejný klíč při importu tajného klíče"
+msgstr "veřejný klíč neodpovídá tajnému klíči!\n"
 
 msgid "only accept updates to existing keys"
-msgstr "přijímat aktualizace pouze u existujících klíčů"
+msgstr ""
 
+#, fuzzy
 msgid "remove unusable parts from key after import"
-msgstr "odstranit z klíče po importu nepoužitelné části"
+msgstr "odstranit nepoužitelné části z klíče"
 
 msgid "remove as much as possible from key after import"
-msgstr "odstranit po importu z klíče vše, co lze"
+msgstr ""
 
 #, c-format
 msgid "skipping block of type %d\n"
@@ -2298,28 +2243,26 @@ msgstr "         odstraněné podpisy: %lu\n"
 msgid "      user IDs cleaned: %lu\n"
 msgstr " odstraněné uživatelské ID: %lu\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "WARNING: key %s contains preferences for unavailable\n"
 "algorithms on these user IDs:\n"
-msgstr ""
-"VAROVÁNÍ: klíč %s obsahuje předvolby pro nedostupné\n"
-"algoritmy na těchto ID uživatelů:\n"
+msgstr "VAROVÁNÍ: klíč %s obsahuje preference pro algoritmy,\n"
 
 #, c-format
 msgid "         \"%s\": preference for cipher algorithm %s\n"
-msgstr "         \"%s\": předvolby pro šifrovací algoritmus %s\n"
+msgstr "         \"%s\": preference pro šifrovací algortimus %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for digest algorithm %s\n"
-msgstr "         \"%s\": předvolby pro podepisovací algoritmus %s\n"
+msgstr "         \"%s\": preference pro podepisovací algoritmus %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for compression algorithm %s\n"
-msgstr "         \"%s\": předvolby pro komprimační algoritmus %s\n"
+msgstr "         \"%s\": preference pro komprimační algoritmus %s\n"
 
 msgid "it is strongly suggested that you update your preferences and\n"
-msgstr "velmi doporučujeme aktualizaci nastavení vašich preferencí a\n"
+msgstr "velmi doporučujeme aktualiaci nastavení vašich preferencí a\n"
 
 msgid "re-distribute this key to avoid potential algorithm mismatch problems\n"
 msgstr ""
@@ -2327,20 +2270,12 @@ msgstr ""
 
 #, c-format
 msgid "you can update your preferences with: gpg --edit-key %s updpref save\n"
-msgstr "nelze aktualizovat předvolby s: gpg --edit-key %s updpref save\n"
+msgstr "nelze aktualizovat preference s: gpg --edit-key %s updpref save\n"
 
 #, c-format
 msgid "key %s: no user ID\n"
 msgstr "klíč %s: chybí identifikátor uživatele\n"
 
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s: %s\n"
-msgstr "přeskočen „%s“: %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "klíč %s: PKS poškození podklíče opraveno\n"
@@ -2371,16 +2306,16 @@ msgstr "nenalezen zapisovatelný soubor klíčů (keyring): %s\n"
 
 # g10/import.c:766 g10/openfile.c:261#, c-format
 #, c-format
-msgid "writing to `%s'\n"
-msgstr "zapisuji do „%s“\n"
+msgid "writing to '%s'\n"
+msgstr "zapisuji do '%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
-msgstr "chyba při zápisu souboru klíčů (keyring) „%s“: %s\n"
+msgid "error writing keyring '%s': %s\n"
+msgstr "chyba při zápisu souboru klíčů (keyring)  `%s': %s\n"
 
 #, c-format
 msgid "key %s: public key \"%s\" imported\n"
-msgstr "klíč %s: veřejný klíč „%s“ importován\n"
+msgstr "klíč %s: veřejný klíč \"%s\" importován\n"
 
 #, c-format
 msgid "key %s: doesn't match our copy\n"
@@ -2396,61 +2331,56 @@ msgstr "klíč %s: nemohu číst originální blok klíče: %s\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new user ID\n"
-msgstr "klíč %s: „%s“ 1 nový identifikátor uživatele\n"
+msgstr "klíč %s: \"%s\" 1 nový identifikátor uživatele\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d new user IDs\n"
-msgstr "klíč %s: „%s“ %d nových identifikátorů uživatele\n"
+msgstr "klíč %s: \"%s\" %d nových identifikátorů uživatele\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new signature\n"
-msgstr "klíč %s: „%s“ 1 nový podpis\n"
+msgstr "klíč %s: \"%s\" 1 nový podpis\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d new signatures\n"
-msgstr "klíč %s: „%s“ %d nových podpisů\n"
+msgstr "klíč %s: \"%s\" %d nových podpisů\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new subkey\n"
-msgstr "klíč %s: „%s“ 1 nový podklíč\n"
+msgstr "klíč %s: \"%s\" 1 nový podklíč\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d new subkeys\n"
-msgstr "klíč %s: „%s“ %d nových podklíčů\n"
+msgstr "klíč %s: \"%s\" %d nových podklíčů\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d signature cleaned\n"
-msgstr "klíč %s: „%s“ %d podpisů odstraněno\n"
+msgstr "klíč %s: \"%s\" %d podpisů odstraněno\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d signatures cleaned\n"
-msgstr "klíč %s: „%s“ %d podpisů odstraněno\n"
+msgstr "klíč %s: \"%s\" %d podpisů odstraněno\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d user ID cleaned\n"
-msgstr "klíč %s: „%s“ %d ID uživatele odstraněno\n"
+msgstr "klíč %s: \"%s\" %d ID uživatele odstraněno\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d user IDs cleaned\n"
-msgstr "klíč %s: „%s“ %d ID uživatele odstraněno\n"
+msgstr "klíč %s: \"%s\" %d ID uživatele odstraněno\n"
 
 #, c-format
 msgid "key %s: \"%s\" not changed\n"
-msgstr "klíč %s: „%s“ beze změn\n"
+msgstr "klíč %s: \"%s\" beze změn\n"
 
-#, fuzzy, c-format
-#| msgid "secret key \"%s\" not found: %s\n"
-msgid "secret key %s: %s\n"
-msgstr "tajný klíč „%s“ nenalezen: %s\n"
+#, c-format
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "klíč %s: tajný klíč s neplatnou šifrou %d - přeskočeno\n"
 
 msgid "importing secret keys not allowed\n"
 msgstr "import tajných klíčů není povolen\n"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "klíč %s: tajný klíč s neplatnou šifrou %d – přeskočeno\n"
-
-#, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "není nastaven implicitní soubor tajných klíčů %s\n"
 
@@ -2468,15 +2398,15 @@ msgstr "klíč %s: nenalezen tajný klíč: %s\n"
 
 #, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
-msgstr "klíč %s: chybí veřejný klíč – nemohu aplikovat revokační certifikát\n"
+msgstr "klíč %s: chybí veřejný klíč - nemohu aplikovat revokační certifikát\n"
 
 #, c-format
 msgid "key %s: invalid revocation certificate: %s - rejected\n"
-msgstr "klíč %s: neplatný revokační certifikát: %s – zamítnuto\n"
+msgstr "klíč %s: neplatný revokační certifikát: %s - zamítnuto\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate imported\n"
-msgstr "klíč %s: „%s“ revokační certifikát importován\n"
+msgstr "klíč %s: \"%s\" revokační certifikát importován\n"
 
 #, c-format
 msgid "key %s: no user ID for signature\n"
@@ -2485,25 +2415,22 @@ msgstr "klíč %s: neexistuje id uživatele pro podpis\n"
 #, c-format
 msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
 msgstr ""
-"klíč %s: nepodporovaný algoritmus veřejného klíče u uživatelského ID „%s“\n"
+"klíč %s: nepodporovaný algoritmus veřejného klíče u uživatelského id  \"%s"
+"\"\n"
 
 #, c-format
 msgid "key %s: invalid self-signature on user ID \"%s\"\n"
-msgstr "klíč %s neplatný podpis klíče jím samým u uživatelského ID „%s“\n"
-
-#, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "klíč %s: nepodporovaný algoritmus veřejného klíče\n"
-
-#, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "klíč %s: neplatný podpis klíče jím samým (direct key signature)\n"
+msgstr "klíč %s neplatný podpis klíče jím samým u uživatelského id \"%s\"\n"
 
 #, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "klíč %s: neexistuje podklíč pro vázání klíčů\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "klíč %s: nepodporovaný algoritmus veřejného klíče\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "klíč %s: neplatná vazba podklíče\n"
 
@@ -2525,7 +2452,7 @@ msgstr "klíč %s: smazána vícenásobná revokace podklíče\n"
 
 #, c-format
 msgid "key %s: skipped user ID \"%s\"\n"
-msgstr "klíč %s: přeskočen identifikátor uživatele „%s“\n"
+msgstr "klíč %s: přeskočen identifikátor uživatele \"%s\"\n"
 
 #, c-format
 msgid "key %s: skipped subkey\n"
@@ -2566,14 +2493,14 @@ msgstr "VAROVÁNÍ: klíč %s může být revokován: revokační klíč %s nena
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate added\n"
-msgstr "klíč %s: „%s“ přidán revokační certifikát\n"
+msgstr "klíč %s: \"%s\" přidán revokační certifikát\n"
 
 #, c-format
 msgid "key %s: direct key signature added\n"
 msgstr "klíč %s: podpis klíče jím samým (direct key signature) přidán\n"
 
 msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr "POZNÁMKA: sériové číslo klíče neodpovídá číslu karty\n"
+msgstr "POZNÁMKA: S/N klíče neodpovídá S/N karty\n"
 
 msgid "NOTE: primary key is online and stored on card\n"
 msgstr "POZNÁMKA: primární klíč je online a je uložen na kartě\n"
@@ -2582,16 +2509,16 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "POZNÁMKA: sekundární klíč je online a je uložen na kartě\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
-msgstr "chyba při vytváření souboru klíčů (keyring) „%s“: %s\n"
+msgid "error creating keyring '%s': %s\n"
+msgstr "chyba při vytváření souboru klíčů (keyring)`%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
-msgstr "soubor klíčů (keyring) „%s“ vytvořen\n"
+msgid "keyring '%s' created\n"
+msgstr "soubor klíčů (keyring) `%s' vytvořen\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
-msgstr "zdroj bloku klíče „%s“: %s\n"
+msgid "keyblock resource '%s': %s\n"
+msgstr "zdroj bloku klíče `%s': %s\n"
 
 #, c-format
 msgid "failed to rebuild keyring cache: %s\n"
@@ -2637,18 +2564,18 @@ msgid ""
 "(by looking at passports, checking fingerprints from different sources, "
 "etc.)\n"
 msgstr ""
-"Prosím rozhodněte, nakolik důvěřujete tomuto uživateli, že správně\n"
+"Prosím rozhodněte, nakolik důvěřete tomuto uživateli, že správně\n"
 "verifikuje klíče jiných uživatelů (prohlédnutím cestovních pasů,\n"
-"kontrolou otisků z různých zdrojů...)?\n"
+"kontrolou fingerprintů z různých zdrojů...)?\n"
 "\n"
 
 #, c-format
 msgid "  %d = I trust marginally\n"
-msgstr "  %d = Důvěřuji částečně\n"
+msgstr " %d = Důvěřuji částečně\n"
 
 #, c-format
 msgid "  %d = I trust fully\n"
-msgstr "  %d = Důvěřuji úplně\n"
+msgstr " %d = Důvěřuji úplně\n"
 
 msgid ""
 "Please enter the depth of this trust signature.\n"
@@ -2666,7 +2593,7 @@ msgstr ""
 
 #, c-format
 msgid "User ID \"%s\" is revoked."
-msgstr "Uživatelské ID „%s“ je revokováno."
+msgstr "Uživatelské ID \"%s\" je revokováno."
 
 msgid "Are you sure you still want to sign it? (y/N) "
 msgstr "Jste si jistý(á), že stále chcete podepsat tento klíč? (a/N) "
@@ -2676,15 +2603,15 @@ msgstr "  Nelze podepsat.\n"
 
 #, c-format
 msgid "User ID \"%s\" is expired."
-msgstr "Vypršela platnost uživatelského ID „%s“."
+msgstr "Vypršela platnost uživatelského ID \"%s\"."
 
 #, c-format
 msgid "User ID \"%s\" is not self-signed."
-msgstr "ID uživatele „%s“ není podepsáno jím samým."
+msgstr "ID uživatele \"%s\" není podepsáno jím samým."
 
 #, c-format
 msgid "User ID \"%s\" is signable.  "
-msgstr "ID uživatele „%s“ je připraveno k podpisu."
+msgstr "ID uživatele \"%s\" je připraveno k podpisu."
 
 msgid "Sign it? (y/N) "
 msgstr "Podepsat? (a/N) "
@@ -2694,7 +2621,7 @@ msgid ""
 "The self-signature on \"%s\"\n"
 "is a PGP 2.x-style signature.\n"
 msgstr ""
-"Podpis klíče „%s“ jím samým je\n"
+"Podpis klíče \"%s\" jím samým je\n"
 "podpis formátu PGP 2.x.\n"
 
 msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) "
@@ -2705,8 +2632,9 @@ msgid ""
 "Your current signature on \"%s\"\n"
 "has expired.\n"
 msgstr ""
-"Platnost vašeho podpisu na „%s“\n"
+"Platnost Vašeho podpisu na \"%s\"\n"
 "vypršela.\n"
+"\n"
 
 msgid "Do you want to issue a new signature to replace the expired one? (y/N) "
 msgstr ""
@@ -2718,19 +2646,20 @@ msgid ""
 "Your current signature on \"%s\"\n"
 "is a local signature.\n"
 msgstr ""
-"Váš současný podpis na „%s“\n"
+"Vaš současný podpis na \"%s\"\n"
 "je pouze lokální.\n"
+"\n"
 
 msgid "Do you want to promote it to a full exportable signature? (y/N) "
 msgstr "Přejete si jej změnit na plně exportovatelný podpise? (a/N) "
 
 #, c-format
 msgid "\"%s\" was already locally signed by key %s\n"
-msgstr "„%s“ je již lokálně podepsán klíčem %s\n"
+msgstr "\"%s\" je již lokálně podepsán klíčem %s\n"
 
 #, c-format
 msgid "\"%s\" was already signed by key %s\n"
-msgstr "„%s“ je již podepsán klíčem %s\n"
+msgstr "\"%s\" je již podepsán klíčem %s\n"
 
 msgid "Do you want to sign it again anyway? (y/N) "
 msgstr "Chcete klíč přesto znova podepsat? (a/N) "
@@ -2765,7 +2694,7 @@ msgid ""
 msgstr ""
 "S jakou jistotou jste prověřili, že klíč, který chcete podepsat\n"
 "patří výše uvedené osobě.\n"
-"Pokud neznáte odpověď, zadejte „0“.\n"
+"Pokud neznáte odpověď, zadejte \"0\".\n"
 
 #, c-format
 msgid "   (0) I will not answer.%s\n"
@@ -2783,8 +2712,8 @@ msgstr "   (2) Částečně jsem to ověřil(a).%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Velmi pečlivě jsem to ověřil(a).%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
-msgstr "Váš výběr? (pro více informací vložte „?“): "
+msgid "Your selection? (enter '?' for more information): "
+msgstr "Vaš výběr? (pro více informací vložte '?'): "
 
 #, c-format
 msgid ""
@@ -2792,7 +2721,7 @@ msgid ""
 "key \"%s\" (%s)\n"
 msgstr ""
 "Jste si jistý(á), že chcete podepsat tento klíč\n"
-"svým klíčem „%s“ (%s)\n"
+"svým klíčem \"%s\" (%s)\n"
 
 msgid "This will be a self-signature.\n"
 msgstr "Jedná se o podpis klíče jím samým.\n"
@@ -2873,7 +2802,7 @@ msgid "save and quit"
 msgstr "uložit a ukončit"
 
 msgid "show key fingerprint"
-msgstr "vypsat otisk klíče"
+msgstr "vypsat fingerprint klíče"
 
 msgid "list key and user IDs"
 msgstr "vypsat seznam klíčů a id uživatelů"
@@ -2897,7 +2826,7 @@ msgid "sign selected user IDs with a trust signature"
 msgstr "podepsat vybrané uživatelské ID důvěryhodným podpisem"
 
 msgid "sign selected user IDs with a non-revocable signature"
-msgstr "podepsat vybraná uživatelská ID neodvolatelným podpisem"
+msgstr "podepsat vybrané uživatelské ID nerevokovatelným podpisem"
 
 msgid "add a user ID"
 msgstr "přidat identifikátor uživatele"
@@ -2909,7 +2838,7 @@ msgid "delete selected user IDs"
 msgstr "smazat vybrané ID uživatele"
 
 msgid "add a subkey"
-msgstr "přidat podklíč"
+msgstr "přidat podklíčy"
 
 msgid "add a key to a smartcard"
 msgstr "přidat klíč na kartu"
@@ -2936,7 +2865,7 @@ msgid "flag the selected user ID as primary"
 msgstr "označit vybrané uživatelské ID jako primární"
 
 msgid "toggle between the secret and public key listings"
-msgstr "přepnout mezi výpisem seznamu tajných a veřejných klíčů"
+msgstr "přepnout mezi vypisem seznamu tajných a veřejných klíčů"
 
 msgid "list preferences (expert)"
 msgstr "vypsat seznam předvoleb (pro experty)"
@@ -2947,11 +2876,13 @@ msgstr "vypsat seznam předvoleb (podrobně)"
 msgid "set preference list for the selected user IDs"
 msgstr "nastavit sadu preferencí pro vybrané uživatelské ID"
 
+#, fuzzy
 msgid "set the preferred keyserver URL for the selected user IDs"
-msgstr "nastavit URL preferovaného serveru klíčů pro vybraná uživatelská ID"
+msgstr "nastavit URL preferovaného server klíčů pro vybrané uživatelské ID"
 
+#, fuzzy
 msgid "set a notation for the selected user IDs"
-msgstr "zadat poznámku pro vybraná uživatelská ID"
+msgstr "nastavit sadu preferencí pro vybrané uživatelské ID"
 
 msgid "change the passphrase"
 msgstr "změnit heslo"
@@ -2979,14 +2910,13 @@ msgstr "ukázat vybrané fotografické ID"
 
 msgid "compact unusable user IDs and remove unusable signatures from key"
 msgstr ""
-"směstnat nepoužitelná ID uživatelů a odstranit z klíče nepoužitelné podpisy"
 
 msgid "compact unusable user IDs and remove all signatures from key"
-msgstr "směstnat nepoužitelná ID uživatelů a odstranit z klíče všechny podpisy"
+msgstr ""
 
 #, c-format
 msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "chyba při čtení bloku tajného klíče „%s“: %s\n"
+msgstr "chyba při čtení bloku tajného klíče \"%s\": %s\n"
 
 msgid "Secret key is available.\n"
 msgstr "Tajný klíč je dostupný.\n"
@@ -2995,7 +2925,7 @@ msgid "Need the secret key to do this.\n"
 msgstr "Pro provedení této operace je potřeba tajný klíč.\n"
 
 msgid "Please use the command \"toggle\" first.\n"
-msgstr "Prosím, nejdříve použijte příkaz „toggle“ (přepnout).\n"
+msgstr "Prosím, nejdříve použijte příkaz \"toggle\" (přepnout).\n"
 
 msgid ""
 "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -3003,9 +2933,10 @@ msgid ""
 "  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
-"* Příkaz „sign“ může být použit s prefixem „l“ pro lokální podpis (lsign),\n"
-"  s prefixem „t“ pro důvěryhodný podpis (tsign) nebo „nr“ pro neodvolatelný\n"
-"  podpis (nrsign) nebo libovolnou jejich kombinací (ltsign, tnrsign, atd.).\n"
+"* Příkaz `sign' může být použit s prefixem `l' pro lokální podpis (lsign),\n"
+"  s prefixem `t' pro důvěryhodný podpis (tsign) nebo `nr' pro neodvolatený "
+"podpis\n"
+"  (nrsign) nebo libovolnou jejich kombinací  (ltsign, tnrsign, atd.).\n"
 
 msgid "Key is revoked."
 msgstr "Klíč revokován."
@@ -3017,8 +2948,8 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Nápověda: Vyberte id uživatele k podepsání\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
-msgstr "Neznámý typ podpisu „%s“\n"
+msgid "Unknown signature type '%s'\n"
+msgstr "Neznámý typ podpisu `%s'\n"
 
 #, c-format
 msgid "This command is not allowed while in %s mode.\n"
@@ -3048,12 +2979,12 @@ msgid "Command expects a filename argument\n"
 msgstr "Příkaz očekává jméno souboru jako argument\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
-msgstr "Nemohu otevřít „%s“: %s\n"
+msgid "Can't open '%s': %s\n"
+msgstr "Nemohu otevřít `%s': %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
-msgstr "Chyba při čtení záložního klíče z „%s“: %s\n"
+msgid "Error reading backup key from '%s': %s\n"
+msgstr "Chyba při čtení záložního klíče z `%s': %s\n"
 
 msgid "You must select at least one key.\n"
 msgstr "Musíte vybrat alespoň jeden klíč.\n"
@@ -3122,15 +3053,19 @@ msgstr "Keyserver bez modifikace"
 msgid "Preferred keyserver: "
 msgstr "Preferovaný keyserver: "
 
+#, fuzzy
 msgid "Notations: "
-msgstr "Poznámky: "
+msgstr ""
+"@\n"
+"Možnosti:\n"
+" "
 
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Uživatelský ID formátu PGP 2.x nemá žádné předvolby\n"
 
 #, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "V %s byl následující klíč revokován %s klíčem %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
+msgstr "V %s tento klíč revokoval %s klíčem %s\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
@@ -3180,8 +3115,11 @@ msgstr ""
 "Prosím nezapomeňte, že zobrazované údaje o platnosti klíčů nemusí\n"
 "být nutně správné, dokud znova nespustíte program.\n"
 
+# status
+#, fuzzy
 msgid "revoked"
-msgstr "revokován"
+msgstr ""
+"revokován\n"
 
 msgid "expired"
 msgstr "platnost skončila"
@@ -3193,14 +3131,6 @@ msgstr ""
 "VAROVÁNÍ: žádné uživatelské ID nebylo označeno jako primární.  Tento příkaz\n"
 "              může způsobit, že za primární bude považováno jiné user ID.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Nemůžete změnit dobu platnosti klíče verze 3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3241,25 +3171,25 @@ msgstr "Nic nebylo smazáno.\n"
 msgid "invalid"
 msgstr "neplatný"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\" compacted: %s\n"
-msgstr "Uživatelské ID „%s“ směstnáno: %s\n"
+msgstr "Uživatelské ID \"%s\": je již odstraněno.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": %d signature removed\n"
-msgstr "Uživatelské ID „%s“: %d podpisů odstraněno\n"
+msgstr "klíč %s: \"%s\" %d podpisů odstraněno\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": %d signatures removed\n"
-msgstr "Uživatelské ID „%s“: %d podpisů odstraněno\n"
+msgstr "klíč %s: \"%s\" %d podpisů odstraněno\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": already minimized\n"
-msgstr "Uživatelské ID „%s“: je již minimalizované\n"
+msgstr "Uživatelské ID \"%s\": je již odstraněno.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": already clean\n"
-msgstr "Uživatelské ID „%s“: je již odstraněné\n"
+msgstr "Uživatelské ID \"%s\": je již odstraněno.\n"
 
 msgid ""
 "WARNING: This is a PGP 2.x-style key.  Adding a designated revoker may "
@@ -3282,11 +3212,11 @@ msgid "you cannot appoint a key as its own designated revoker\n"
 msgstr "klíč nelze pověřit revokací jím samým\n"
 
 msgid "this key has already been designated as a revoker\n"
-msgstr "tento klíč již byl pověřen revokací\n"
+msgstr "tento klíč již bykl pověřen revokací\n"
 
 msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n"
 msgstr ""
-"VAROVÁNÍ: ustanovení klíče „pověřeným odvolatelem“ je nevratná operace!\n"
+"VAROVÁNÍ: ustanovení klíče 'povřeným revokátorem' je nevratná operace!\n"
 
 msgid ""
 "Are you sure you want to appoint this key as a designated revoker? (y/N) "
@@ -3310,23 +3240,23 @@ msgstr "Nemůžete změnit dobu platnosti klíče verze 3\n"
 msgid "No corresponding signature in secret ring\n"
 msgstr "V souboru tajných klíčů chybí odpovídající podpis\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "signing subkey %s is already cross-certified\n"
-msgstr "podepisovací podklíč %s je již křížově certifikován\n"
+msgstr "VAROVÁNÍ: podepisovací podklíč %s není křížově certifikován\n"
 
 #, c-format
 msgid "subkey %s does not sign and so does not need to be cross-certified\n"
-msgstr "podklíč %s nepodepisuje, a tak není třeba jej křížově certifikovat\n"
+msgstr ""
 
 msgid "Please select exactly one user ID.\n"
 msgstr "Prosím, vyberte právě jeden id uživatele .\n"
 
 #, c-format
 msgid "skipping v3 self-signature on user ID \"%s\"\n"
-msgstr "přeskočen v3 podpis klíče jím samým u uživatelského id „%s“\n"
+msgstr "přeskočen v3 podpis klíče jím samým u uživatelského id \"%s\"\n"
 
 msgid "Enter your preferred keyserver URL: "
-msgstr "Vložte URL preferovaného serveru klíčů: "
+msgstr "Vložte URL preferovaného keyserveru: "
 
 msgid "Are you sure you want to replace it? (y/N) "
 msgstr "Jste si jistý(á), že jej chcete přepsat? (a/N) "
@@ -3334,11 +3264,13 @@ msgstr "Jste si jistý(á), že jej chcete přepsat? (a/N) "
 msgid "Are you sure you want to delete it? (y/N) "
 msgstr "Jste si jistý(á), že jej chcete smazat? (a/N) "
 
+#, fuzzy
 msgid "Enter the notation: "
-msgstr "Vložte poznámku: "
+msgstr "Podepisovací notace: "
 
+#, fuzzy
 msgid "Proceed? (y/N) "
-msgstr "Pokračovat (a/N)? "
+msgstr "Přepsat (a/N)? "
 
 #, c-format
 msgid "No user ID with index %d\n"
@@ -3354,7 +3286,7 @@ msgstr "Neexistuje podklíč s indexem %d\n"
 
 #, c-format
 msgid "user ID: \"%s\"\n"
-msgstr "ID uživatele: „%s“\n"
+msgstr "id uživatele:\"%s\"\n"
 
 #, c-format
 msgid "signed by your key %s on %s%s%s\n"
@@ -3374,14 +3306,14 @@ msgid "Create a revocation certificate for this signature? (y/N) "
 msgstr "Vytvořit pro tento podpis revokační certifikát? (a/N)"
 
 msgid "Not signed by you.\n"
-msgstr "Nepodepsáno vámi.\n"
+msgstr ""
 
 #, c-format
 msgid "You have signed these user IDs on key %s:\n"
 msgstr "Podepsal(a) jste následující identifikátory uživatele: %s:\n"
 
 msgid " (non-revocable)"
-msgstr " (neodvolatelné)"
+msgstr " (nerevokovatelné)"
 
 #, c-format
 msgid "revoked by your key %s on %s\n"
@@ -3398,7 +3330,7 @@ msgstr "neexistuje tajný klíč\n"
 
 #, c-format
 msgid "user ID \"%s\" is already revoked\n"
-msgstr "uživatelské ID „%s“ je již revokováno\n"
+msgstr "Uživatelské ID \"%s\" je již revokováno.\n"
 
 #, c-format
 msgid "WARNING: a user ID signature is dated %d seconds in the future\n"
@@ -3417,8 +3349,8 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Zobrazuji %s fotografický ID o velikosti %ld pro klíč %s (uid %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
-msgstr "duplicita předvolby „%s“\n"
+msgid "preference '%s' duplicated\n"
+msgstr "duplicita předvolby `%s'\n"
 
 msgid "too many cipher preferences\n"
 msgstr "příliš mnoho předvoleb pro šifrování\n"
@@ -3430,8 +3362,8 @@ msgid "too many compression preferences\n"
 msgstr "příliš mnoho předvoleb pro komprimaci\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
-msgstr "neplatná položka „%s“ v řetězci s předvolbami\n"
+msgid "invalid item '%s' in preference string\n"
+msgstr "neplatná položka `%s' v řetězci s předvolbami\n"
 
 msgid "writing direct signature\n"
 msgstr "zapisuji podpis klíče jím samým (direct signature)\n"
@@ -3440,7 +3372,7 @@ msgid "writing self signature\n"
 msgstr "zapisuji podpis klíče sebou samým\n"
 
 msgid "writing key binding signature\n"
-msgstr "zapisuji „key-binding“ podpis\n"
+msgstr "zapisuji \"key-binding\" podpis\n"
 
 #, c-format
 msgid "keysize invalid; using %u bits\n"
@@ -3453,14 +3385,12 @@ msgstr "délka klíče zaokrouhlena na %u bitů\n"
 msgid ""
 "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n"
 msgstr ""
-"VAROVÁNÍ: některé OpenPGP programy nedokáží zacházet s DSA klíčem s takto "
-"dlouhým hashem\n"
 
 msgid "Sign"
 msgstr "Podepisování"
 
 msgid "Certify"
-msgstr "Certifikování"
+msgstr ""
 
 msgid "Encrypt"
 msgstr "Šifrování"
@@ -3507,13 +3437,13 @@ msgstr "   (%c) Konec\n"
 msgid "Please select what kind of key you want:\n"
 msgstr "Prosím, vyberte druh klíče, který chcete:\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA and RSA (default)\n"
-msgstr "   (%d) RSA a RSA (implicitní)\n"
+msgstr "   (%d) DSA a ElGamal (implicitní)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) DSA and Elgamal\n"
-msgstr "   (%d) DSA a Elgamal\n"
+msgstr "   (%d) DSA a ElGamal (implicitní)\n"
 
 #, c-format
 msgid "   (%d) DSA (sign only)\n"
@@ -3525,7 +3455,7 @@ msgstr "   (%d) RSA (pouze pro podpis)\n"
 
 #, c-format
 msgid "   (%d) Elgamal (encrypt only)\n"
-msgstr "   (%d) Elgamal (pouze pro šifrování)\n"
+msgstr "   (%d) ElGamal (pouze pro šifrování)\n"
 
 #, c-format
 msgid "   (%d) RSA (encrypt only)\n"
@@ -3543,9 +3473,9 @@ msgstr "   (%d) RSA (nastavit si vlastní použití)\n"
 msgid "%s keys may be between %u and %u bits long.\n"
 msgstr "klíč %s může mít délku v intervalu %u až %u bitů.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the subkey? (%u) "
-msgstr "Jakou délku podklíče si přejete? (%u) "
+msgstr "Jakou délku klíče si přejete? (%u) "
 
 #, c-format
 msgid "What keysize do you want? (%u) "
@@ -3624,10 +3554,6 @@ msgid ""
 "GnuPG needs to construct a user ID to identify your key.\n"
 "\n"
 msgstr ""
-"\n"
-"GnuPG potřebuje sestrojit uživatelské ID, aby bylo možné rozpoznat\n"
-"váš klíč.\n"
-"\n"
 
 #. TRANSLATORS: This string is in general not anymore used
 #. but you should keep your existing translation.  In case
@@ -3642,10 +3568,10 @@ msgid ""
 "\n"
 msgstr ""
 "\n"
-"Aby bylo možné rozpoznat váš klíč, musíte znát identifikátor uživatele;\n"
-"program jej složí z vašeho jména a příjmení, komentáře e-mailové adresy\n"
+"Aby bylo možné rozpoznat Váš klíč, musíte znát identifikátor uživatele;\n"
+"program jej složí z Vašeho jména a příjmení, komentáře a e-mailu\n"
 "v tomto tvaru:\n"
-"    „Magda Prochazkova (student) <magda@domena.cz>“\n"
+"    \"Magda Prochazkova (student) <magda@domena.cz>\"\n"
 "\n"
 
 msgid "Real name: "
@@ -3673,8 +3599,8 @@ msgid "Invalid character in comment\n"
 msgstr "Neplatný znak v komentáři\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
-msgstr "Používáte znakovou sadu „%s“.\n"
+msgid "You are using the '%s' character set.\n"
+msgstr "Používáte znakovou sadu `%s'.\n"
 
 #, c-format
 msgid ""
@@ -3683,14 +3609,14 @@ msgid ""
 "\n"
 msgstr ""
 "Zvolil(a) jste tento identifikátor uživatele:\n"
-"    „%s“\n"
+"    \"%s\"\n"
 "\n"
 
 msgid "Please don't put the email address into the real name or the comment\n"
 msgstr "Do pole jméno nebo komentář nepište, prosím, e-mailovou adresu.\n"
 
 msgid "Such a user ID already exists on this key!\n"
-msgstr "Takový identifikátor uživatele již u tohoto klíče existuje!\n"
+msgstr ""
 
 #. TRANSLATORS: These are the allowed answers in
 #. lower and uppercase.  Below you will find the matching
@@ -3724,12 +3650,11 @@ msgstr ""
 "Pro ochranu Vašeho tajného klíče musíte zadat heslo.\n"
 "\n"
 
+#, fuzzy
 msgid ""
 "Please enter a passphrase to protect the off-card backup of the new "
 "encryption key."
-msgstr ""
-"Prosím, zadejte heslo, kterým ochráníte zálohu mimo kartu nového šifrovacího "
-"klíče."
+msgstr "Prosím, vložte heslo; toto je tajná věta \n"
 
 #, c-format
 msgid "%s.\n"
@@ -3741,9 +3666,9 @@ msgid ""
 "using this program with the option \"--edit-key\".\n"
 "\n"
 msgstr ""
-"Nechcete heslo – to *není* dobrý nápad!\n"
+"Nechcete heslo - to *není* dobrý nápad!\n"
 "Dobře, budu pokračovat bez hesla. Kdykoliv můžete heslo změnit použitím\n"
-"tohoto programu s parametrem „--edit-key“.\n"
+"tohoto programu s parametrem \"--edit-key\".\n"
 "\n"
 
 msgid ""
@@ -3762,16 +3687,16 @@ msgid "Key generation canceled.\n"
 msgstr "Vytváření klíče bylo zrušeno.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
-msgstr "zapisuji veřejný klíč do „%s“\n"
+msgid "writing public key to '%s'\n"
+msgstr "zapisuji veřejný klíč do `%s'\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "zapisuji tajný klíč do „%s“\n"
+msgid "writing secret key stub to '%s'\n"
+msgstr "zapisuji tajný klíč do `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "zapisuji tajný klíč do „%s“\n"
+msgid "writing secret key to '%s'\n"
+msgstr "zapisuji tajný klíč do `%s'\n"
 
 #, c-format
 msgid "no writable public keyring found: %s\n"
@@ -3782,12 +3707,12 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "nenalezen zapisovatelný soubor tajných klíčů (secring): %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "chyba při zápisu do souboru veřejných klíčů „%s“: %s\n"
+msgid "error writing public keyring '%s': %s\n"
+msgstr "chyba při zápisu do souboru veřejných klíčů `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "chyba při zápisu do souboru tajných klíčů „%s“: %s\n"
+msgid "error writing secret keyring '%s': %s\n"
+msgstr "chyba při zápisu do souboru tajných klíčů `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
 msgstr "veřejný a tajný klíč byly vytvořeny a podepsány.\n"
@@ -3797,7 +3722,7 @@ msgid ""
 "the command \"--edit-key\" to generate a subkey for this purpose.\n"
 msgstr ""
 "Tento klíč nemůže být použitý pro šifrování. K vytvoření\n"
-"sekundárního klíče pro tento účel můžete použít příkaz „--edit-key“.\n"
+"sekundárního klíče pro tento účel můžete použít příkaz \"--edit-key\".\n"
 
 #, c-format
 msgid "Key generation failed: %s\n"
@@ -3828,12 +3753,12 @@ msgid "storing key onto card failed: %s\n"
 msgstr "uložení klíče na kartu se nezdařilo: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
-msgstr "nemohu vytvořit zálohu souboru „%s“: %s\n"
+msgid "can't create backup file '%s': %s\n"
+msgstr "nemohu vytvořit zálohu souboru `%s': %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
-msgstr "POZNÁMKA: záloha klíče z karty uložena do „%s“\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
+msgstr "POZNÁMKA: záloha klíče z karty uložena do `%s'\n"
 
 msgid "never     "
 msgstr "nikdy     "
@@ -3857,33 +3782,28 @@ msgid "Keyring"
 msgstr "soubor klíčů (keyring)"
 
 msgid "Primary key fingerprint:"
-msgstr "Otisk primárního klíče:"
+msgstr "Primární fingerprint klíče:"
 
 msgid "     Subkey fingerprint:"
-msgstr "         Otisk podklíče:"
+msgstr "     Fingerprint podklíče:"
 
 #. TRANSLATORS: this should fit into 24 bytes to that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
-msgstr "  Otisk primárního klíče:"
+msgstr " Primární fingerprint klíče:"
 
 msgid "      Subkey fingerprint:"
-msgstr "          Otisk podklíče:"
+msgstr "      Fingerprint podklíče:"
 
 msgid "      Key fingerprint ="
-msgstr "          Otisk klíče ="
-
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "VAROVÁNÍ: používám experimentální hashovací algoritmus %s\n"
+msgstr "      Fingerprint klíče ="
 
 msgid "      Card serial no. ="
-msgstr "  riové číslo karty ="
+msgstr "      Seriové číslo karty ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
-msgstr "přejmenování „%s“ na „%s“ se nezdařilo: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
+msgstr "přejmenování `%s' na `%s' se nezdařilo: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
 msgstr "VAROVÁNÍ: Existují dva soubory s tajnými informacemi.\n"
@@ -3900,8 +3820,8 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Prosím, opravte tento možný bezpečnostní problém\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
-msgstr "cache souboru klíčů „%s“\n"
+msgid "caching keyring '%s'\n"
+msgstr "cache souboru klíčů `%s'\n"
 
 #, c-format
 msgid "%lu keys cached so far (%lu signatures)\n"
@@ -3916,43 +3836,44 @@ msgid "%s: keyring created\n"
 msgstr "%s: soubor klíčů (keyring) vytvořen\n"
 
 msgid "include revoked keys in search results"
-msgstr "zahrnout do výsledku hledání odvolané klíče"
+msgstr ""
 
 msgid "include subkeys when searching by key ID"
-msgstr "zahrnout podklíče, když se hledá podle ID klíče"
+msgstr ""
 
 msgid "use temporary files to pass data to keyserver helpers"
-msgstr "používat dočasné soubory na přenos dat k modulům pro servery klíčů"
+msgstr ""
 
 msgid "do not delete temporary files after using them"
-msgstr "nemazat dočasné soubory po jejich použití"
+msgstr ""
 
 msgid "automatically retrieve keys when verifying signatures"
-msgstr "automaticky získávat klíče při ověřování podpisů"
+msgstr ""
 
+#, fuzzy
 msgid "honor the preferred keyserver URL set on the key"
-msgstr "respektovat URL upřednostňovaných serverů klíčů daného klíče"
+msgstr "Vložte URL preferovaného keyserveru: "
 
 msgid "honor the PKA record set on a key when retrieving keys"
-msgstr "respektovat PKA záznamy klíče při získávání klíčů"
+msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
-msgstr "VAROVÁNÍ: volba „%s“ pro server klíčů není na této platformě účinná\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
+msgstr "VAROVÁNÍ: volba `%s' pro server klíčů není na této platformě účinná\n"
 
 msgid "disabled"
-msgstr "zneplatněn"
+msgstr "disabled"
 
 msgid "Enter number(s), N)ext, or Q)uit > "
-msgstr "Vložte číslo (čísla), „N“ pro další, nebo „Q“ pro konec > "
+msgstr "Vložte číslo (čísla), 'N' pro další nebo 'Q' pro konec> "
 
 #, c-format
 msgid "invalid keyserver protocol (us %d!=handler %d)\n"
-msgstr "neplatný protokol serveru klíčů (naše %d!=obsluha %d)\n"
+msgstr "neplatný protokol serveru klíčů (us %d!=handler %d)\n"
 
 #, c-format
 msgid "key \"%s\" not found on keyserver\n"
-msgstr "klíč „%s“ nebyl na serveru klíčů nalezen\n"
+msgstr "klíč \"%s\" nebyl na serveru klíčů nalezen\n"
 
 msgid "key not found on keyserver\n"
 msgstr "klíč nebyl na serveru klíčů nalezen\n"
@@ -3965,13 +3886,13 @@ msgstr "požaduji klíč %s ze %s server %s\n"
 msgid "requesting key %s from %s\n"
 msgstr "požaduji klíč %s z %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "searching for names from %s server %s\n"
-msgstr "vyhledávám jména na %s serveru %s\n"
+msgstr "vyhledávám \"%s\" na %s serveru %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "searching for names from %s\n"
-msgstr "vyhledávám jména na serveru %s\n"
+msgstr "vyhledávám \"%s\" na serveru %s\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
@@ -3983,39 +3904,35 @@ msgstr "posílám klíč %s na %s\n"
 
 #, c-format
 msgid "searching for \"%s\" from %s server %s\n"
-msgstr "vyhledávám „%s“ na %s serveru %s\n"
+msgstr "vyhledávám \"%s\" na %s serveru %s\n"
 
 #, c-format
 msgid "searching for \"%s\" from %s\n"
-msgstr "vyhledávám „%s“ na serveru %s\n"
+msgstr "vyhledávám \"%s\" na serveru %s\n"
 
 msgid "no keyserver action!\n"
 msgstr "žádná operace se serverem klíčů!\n"
 
 #, c-format
 msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr "VAROVÁNÍ: obsluha serveru klíčů z jiné verze GnuPG (%s)\n"
+msgstr "VAROVÁNÍ: keyserver handler z jiné verze GnuPG (%s)\n"
 
 msgid "keyserver did not send VERSION\n"
 msgstr "server klíčů neposlal VERSION\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "chyba komunikace se serverem klíčů: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
-msgstr "žádný server klíčů není znám (použijte volbu --keyserver)\n"
+msgstr "žadný server klíčů není znám (použíjte volbu --keyserver)\n"
 
 msgid "external keyserver calls are not supported in this build\n"
 msgstr "volání externího keyserver není v této verzi podporováno\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "protokol serveru klíčů „%s“ není podporován\n"
+msgid "no handler for keyserver scheme '%s'\n"
+msgstr "protokol serveru klíčů `%s' není podporován\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
-msgstr "akce „%s“ není podporována v protokolu „%s“ serveru klíčů\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
+msgstr "akce `%s' není podporována v protokolu `%s' serveru klíčů\n"
 
 #, c-format
 msgid "%s does not support handler version %d\n"
@@ -4028,8 +3945,12 @@ msgid "keyserver internal error\n"
 msgstr "interní chyba serveru klíčů\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "chyba komunikace se serverem klíčů: %s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
-msgstr "„%s“ není ID klíče: přeskočeno\n"
+msgstr "\"%s\" není ID klíče: přeskočeno\n"
 
 #, c-format
 msgid "WARNING: unable to refresh key %s via %s: %s\n"
@@ -4043,13 +3964,13 @@ msgstr "aktualizuji 1 klíč z %s\n"
 msgid "refreshing %d keys from %s\n"
 msgstr "aktualizuji %d klíčů z %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
-msgstr "VAROVÁNÍ: URI %s nelze získat: %s\n"
+msgstr "VAROVÁNÍ: nelze aktualizovat klíč %s prostřednictvím %s: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: unable to parse URI %s\n"
-msgstr "VAROVÁNÍ: URI %s nelze rozebrat\n"
+msgstr "VAROVÁNÍ: nelze aktualizovat klíč %s prostřednictvím %s: %s\n"
 
 #, c-format
 msgid "weird size for an encrypted session key (%d)\n"
@@ -4061,7 +3982,7 @@ msgstr "%s zašifrovaný klíč sezení\n"
 
 #, c-format
 msgid "passphrase generated with unknown digest algorithm %d\n"
-msgstr "heslo (passphrase) generováno s použitím neznámého algoritmu %d\n"
+msgstr "heslo (passphraze) generováno s použitím neznámého algoritmu %d\n"
 
 #, c-format
 msgid "public key is %s\n"
@@ -4076,7 +3997,7 @@ msgstr "zašifrována %u-bitovým %s klíčem, ID %s, vytvořeným %s\n"
 
 #, c-format
 msgid "      \"%s\"\n"
-msgstr "      „%s“\n"
+msgstr "      \"%s\"\n"
 
 # Scripte scannen lt. dl1bke auf "ID (0-9A-F)+" deswegen muß "ID" rein :-(
 # [kw]
@@ -4116,35 +4037,37 @@ msgstr "VAROVÁNÍ: se zašifrovanou zprávou bylo manipulováno!\n"
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
-msgstr "vymazané heslo zapamatované pro ID: %s\n"
+msgstr ""
 
 #, c-format
 msgid "decryption failed: %s\n"
 msgstr "dešifrování selhalo: %s\n"
 
 msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
-msgstr "POZNÁMKA: odesílatel požadoval („for-your-eyes-only“)\n"
+msgstr "POZNÁMKA: odesílatel požadoval (\"for-your-eyes-only\")\n"
 
 #, c-format
 msgid "original file name='%.*s'\n"
 msgstr "původní jméno souboru='%.*s'\n"
 
 msgid "WARNING: multiple plaintexts seen\n"
-msgstr "VAROVÁNÍ: zachyceno více prostých textů\n"
+msgstr ""
 
 msgid "standalone revocation - use \"gpg --import\" to apply\n"
 msgstr ""
-"samostatný revokační certifikát – použijte „gpg --import“, chcete-li jej "
+"samostatný revokační certifikát -  použijte \"gpg --import\", chcete-li jej "
 "užít\n"
 
+#, fuzzy
 msgid "no signature found\n"
-msgstr "nenalezen žádná podpis\n"
+msgstr "Dobrý podpis od \"%s\""
 
 msgid "signature verification suppressed\n"
 msgstr "verifikace podpisu potlačena\n"
 
+#, fuzzy
 msgid "can't handle this ambiguous signature data\n"
-msgstr "neumím pracovat s těmito nejednoznačnými daty\n"
+msgstr "neumím pracovat s těmito násobnými podpisy\n"
 
 #, c-format
 msgid "Signature made %s\n"
@@ -4164,22 +4087,22 @@ msgstr "Klíč k dispozici na: "
 
 #, c-format
 msgid "BAD signature from \"%s\""
-msgstr "ŠPATNÝ podpis od „%s“"
+msgstr "ŠPATNÝ podpis od \"%s\""
 
 #, c-format
 msgid "Expired signature from \"%s\""
-msgstr "Podpis s vypršenou platností od „%s“"
+msgstr "Podpis s vypršenou platností od \"%s\""
 
 #, c-format
 msgid "Good signature from \"%s\""
-msgstr "Dobrý podpis od „%s“"
+msgstr "Dobrý podpis od \"%s\""
 
 msgid "[uncertain]"
 msgstr "[nejistý]"
 
 #, c-format
 msgid "                aka \"%s\""
-msgstr "                alias „%s“"
+msgstr "                alias \"%s\""
 
 #, c-format
 msgid "Signature expired %s\n"
@@ -4199,12 +4122,11 @@ msgstr "binární formát"
 msgid "textmode"
 msgstr "textový formát"
 
+# status
+#, fuzzy
 msgid "unknown"
-msgstr "neznámý formát"
-
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
 msgstr ""
+"neznámý formát\n"
 
 #, c-format
 msgid "Can't check signature: %s\n"
@@ -4228,8 +4150,8 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "nalezen neplatný kořenový paket v proc_tree()\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
-msgstr "fstat „%s“ selhal na %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
+msgstr "fstat `%s' selhal na %s: %s\n"
 
 #, c-format
 msgid "fstat(%d) failed in %s: %s\n"
@@ -4239,8 +4161,9 @@ msgstr "fstat(%d) selhal v %s: %s\n"
 msgid "WARNING: using experimental public key algorithm %s\n"
 msgstr "VAROVÁNÍ: používám experimentální algoritmus veřejného klíče %s\n"
 
+#, fuzzy
 msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n"
-msgstr "VAROVÁNÍ: Podepisovací a šifrovací klíče Elgamal se nedoporučují\n"
+msgstr "VAROVÁNÍ: vyžádaný algoritmus %s není doporučen\n"
 
 #, c-format
 msgid "WARNING: using experimental cipher algorithm %s\n"
@@ -4254,75 +4177,59 @@ msgstr "VAROVÁNÍ: používám experimentální hashovací algoritmus %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "VAROVÁNÍ: vyžádaný algoritmus %s není doporučen\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "podpis %s, hashovací algoritmus %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "IDEA modul pro GnuPG nenalezen\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "please see %s for more information\n"
-msgstr "více informací naleznete na adrese %s\n"
+msgstr "Více informací naleznete na adrese http://www.gnupg.cz/faq.html\n"
 
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
-msgstr "%s:%d: použití parametru „%s“ se nedoporučuje\n"
+msgstr "%s:%d: použití parametru \"%s\" se nedoporučuje\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated option\n"
-msgstr "VAROVÁNÍ: používání parametru „%s“ se nedoporučuje\n"
+msgstr "VAROVÁNÍ: používání parametru \"%s\" se nedoporučuje\n"
 
 #, c-format
 msgid "please use \"%s%s\" instead\n"
-msgstr "použijte místo něj „%s%s“ \n"
+msgstr "použijte místo něj \"%s%s\" \n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated command - do not use it\n"
-msgstr "VAROVÁNÍ: používání příkaz „%s“ se nedoporučuje - nepoužívejte jej\n"
+msgstr "VAROVÁNÍ: používání příkaz \"%s\" se nedoporučuje - nepoužívejte jej\n"
 
 #, c-format
 msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgstr "%s:%u: zastaralý parametr „%s“ – neúčinkuje\n"
-
-#, c-format
-msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr "VAROVÁNÍ: „%s“ je zastaralý parametr – neúčinkuje\n"
-
-#, fuzzy, c-format
-#| msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: zastaralý parametr „%s“ – neúčinkuje\n"
+msgstr ""
 
 #, fuzzy, c-format
-#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "VAROVÁNÍ: „%s“ je zastaralý parametr – neúčinkuje\n"
+msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgstr "VAROVÁNÍ: používání parametru \"%s\" se nedoporučuje\n"
 
 msgid "Uncompressed"
-msgstr "Nezkomprimováno"
+msgstr "Nezakomprimováno"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "uncompressed|none"
-msgstr "nezkomprimováno|nic"
+msgstr "nezakomprimováno|nic"
 
 #, c-format
 msgid "this message may not be usable by %s\n"
 msgstr "tato zpráva nemusí být s %s použitelná\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
-msgstr "nejednoznačné volby „%s“\n"
+msgid "ambiguous option '%s'\n"
+msgstr "nejednoznačné volby `%s'\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
-msgstr "neznámá volba „%s“\n"
+msgid "unknown option '%s'\n"
+msgstr "neznámá volba `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
-msgstr "Soubor „%s“ existuje. "
+msgid "File '%s' exists. "
+msgstr "Soubor `%s' existuje. "
 
 msgid "Overwrite? (y/N) "
 msgstr "Přepsat (a/N)? "
@@ -4337,18 +4244,17 @@ msgstr "Vložte nový název souboru"
 msgid "writing to stdout\n"
 msgstr "zapisuji do standardního výstupu\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
-msgstr "předpokládám podepsaná data v „%s“\n"
+msgstr "předpokládám podepsaná data v `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
-msgstr "vytvořen nový konfigurační soubor „%s“\n"
+msgid "new configuration file '%s' created\n"
+msgstr "vytvořen nový konfigurační soubor `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
-msgstr "VAROVÁNÍ: nastavení z „%s“ nejsou při tomto spuštění zatím aktivní\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
+msgstr "VAROVÁNÍ: nastavení z `%s' nejsou při tomto spuštění zatím aktivní\n"
 
 #, c-format
 msgid "can't handle public key algorithm %d\n"
@@ -4359,17 +4265,13 @@ msgstr "VAROVÁNÍ: potencionálně nebezpečně symetricky zašifrován klíč
 
 #, c-format
 msgid "subpacket of type %d has critical bit set\n"
-msgstr "podpacket typu %d má nastavený kritický bit\n"
-
-#, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problém s agentem: %s\n"
+msgstr "podpaket typu %d má nastavený kritický bit\n"
 
 #, c-format
 msgid " (main key ID %s)"
-msgstr " (hlavní ID klíče %s)"
+msgstr "(hlavní ID klíče %s)"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Please enter the passphrase to unlock the secret key for the OpenPGP "
 "certificate:\n"
@@ -4377,11 +4279,9 @@ msgid ""
 "%u-bit %s key, ID %s,\n"
 "created %s%s.\n"
 msgstr ""
-"Prosím, zadejte heslo, abyste odemkl(a) tajný klíč příslušející OpenPGP "
-"certifikátu:\n"
-"„%.*s“\n"
-"Klíč o délce %u bitů, typ %s, ID %s\n"
-"vytvořený %s%s.\n"
+"Potřebujete heslo, abyste odemknul(a) tajný klíč pro uživatele:\n"
+"\"%.*s\"\n"
+"Klíč o délce %u bitů, typ %s, ID %s, vytvořený %s%s\n"
 
 msgid "Enter passphrase\n"
 msgstr "Vložit heslo\n"
@@ -4389,13 +4289,17 @@ msgstr "Vložit heslo\n"
 msgid "cancelled by user\n"
 msgstr "zrušeno uživatelem\n"
 
+#, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problém s agentem - používání agenta vypnuto\n"
+
 #, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
 msgstr ""
-"Musíte znát heslo, abyste odemkl(a) tajný klíč pro\n"
-"uživatele: „%s“\n"
+"Musíte znát heslo, abyste odemknul(a) tajný klíč pro\n"
+"uživatele: \"%s\"\n"
 
 #, c-format
 msgid "%u-bit %s key, ID %s, created %s"
@@ -4413,8 +4317,8 @@ msgid ""
 "Keeping the image close to 240x288 is a good size to use.\n"
 msgstr ""
 "\n"
-"Vyberte obrázek, který bude použit jako Vaše fotografické ID. Obrázek musí\n"
-"být ve formátu JPEG. Nezapomeňte, že obrázek bude uložen ve Vašem veřejném\n"
+"Vyberte obrázek, který bude použit jako Vaše fotografické ID.  Obrázek musí\n"
+"být ve formátu JPEG. Nezapomeňtě, že obrázek bude uložen ve Vašem veřejném\n"
 "klíči - velký obrázek bude mít za následek velmi velký veřejný klíč !\n"
 "Vhodná velikost obrázku je asi 240x288.\n"
 
@@ -4422,8 +4326,8 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Vložte jméno JPEG souboru s fotografickým ID: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
-msgstr "nelze otevřít JPEG soubor „%s“: %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
+msgstr "nelze otevřít JPEG soubor `%s': %s\n"
 
 #, c-format
 msgid "This JPEG is really large (%d bytes) !\n"
@@ -4433,8 +4337,8 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Jste si jistý(á), že jej chcete použít? (a/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
-msgstr "„%s“ není soubor ve formátu JPEG\n"
+msgid "'%s' is not a JPEG file\n"
+msgstr "`%s' není soubor ve formátu JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
 msgstr "Je tato fotografie správná (a/N/u)? "
@@ -4463,16 +4367,6 @@ msgstr "důvod pro revokaci: "
 msgid "revocation comment: "
 msgstr "revokační poznámka: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMuUsS"
 
@@ -4481,7 +4375,7 @@ msgstr "Není přiřazena žádná hodnota důvěry:\n"
 
 #, c-format
 msgid "  aka \"%s\"\n"
-msgstr "  alias „%s“\n"
+msgstr "  alias \"%s\"\n"
 
 msgid ""
 "How much do you trust that this key actually belongs to the named user?\n"
@@ -4489,24 +4383,24 @@ msgstr "Nakolik důvěřujete tvrzení, že tento klíč patří uvedenému uži
 
 #, c-format
 msgid "  %d = I don't know or won't say\n"
-msgstr "  %d = Nevím nebo neřeknu\n"
+msgstr " %d = Nevím nebo neřeknu\n"
 
 #, c-format
 msgid "  %d = I do NOT trust\n"
-msgstr "  %d = Nedůvěřuji\n"
+msgstr " %d = Nedůvěřuji\n"
 
 #, c-format
 msgid "  %d = I trust ultimately\n"
-msgstr "  %d = Důvěřuji absolutně\n"
+msgstr " %d = Důvěřuji absolutně\n"
 
 msgid "  m = back to the main menu\n"
-msgstr "  m = zpět do hlavního menu\n"
+msgstr " m = zpět do hlavního menu\n"
 
 msgid "  s = skip this key\n"
-msgstr "  s = přeskočit tento klíč\n"
+msgstr " s = přeskočit tento klíč\n"
 
 msgid "  q = quit\n"
-msgstr "  u = ukončit\n"
+msgstr " u = ukončit\n"
 
 #, c-format
 msgid ""
@@ -4531,7 +4425,7 @@ msgstr "%s: Nic nenaznačuje tomu, že tento klíč patří uvedenému uživatel
 
 #, c-format
 msgid "%s: There is limited assurance this key belongs to the named user\n"
-msgstr "%s: Je zde částečná důvěra, že tento klíč patří uvedenému uživateli\n"
+msgstr "%s: Je zde částečná důvěra, že tento klíč patří uvedenému uvživateli\n"
 
 msgid "This key probably belongs to the named user\n"
 msgstr "Tento klíč pravděpodobně náleží uvedenému uživateli\n"
@@ -4574,18 +4468,18 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Poznámka: Tento klíč byl označen jako neplatný (disabled).\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
-msgstr "Poznámka: Podepisovatelova ověřená adresa je „%s“\n"
+msgid "Note: Verified signer's address is '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr "Poznámka: Podepisovatelova adresa „%s“ se neshoduje s DNS záznamem\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
+msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
-msgstr "úroveň důvěry opravena na PLNOU, kvůli platné PKA informaci\n"
+msgstr ""
 
 msgid "trustlevel adjusted to NEVER due to bad PKA info\n"
-msgstr "úroveň důvěry opravena na ŽÁDNOU, kvůli špatné PKA informaci\n"
+msgstr ""
 
 msgid "Note: This key has expired!\n"
 msgstr "Poznámka: Skončila platnost tohoto klíče!\n"
@@ -4599,7 +4493,7 @@ msgstr ""
 "         Nic nenaznačuje tomu, že tento podpis patří vlastníkovi klíče.\n"
 
 msgid "WARNING: We do NOT trust this key!\n"
-msgstr "VAROVÁNÍ: NEDŮVĚŘUJEME tomuto klíči!\n"
+msgstr "VAROVÁNÍ: NEdůvěřujeme tomuto klíči!\n"
 
 msgid "         The signature is probably a FORGERY.\n"
 msgstr "         Tento podpis je pravděpodobně PADĚLANÝ.\n"
@@ -4648,7 +4542,7 @@ msgstr "přeskočeno: veřejný klíč je již nastaven\n"
 
 #, c-format
 msgid "unknown default recipient \"%s\"\n"
-msgstr "neznámý implicitní adresát „%s“\n"
+msgstr "neznámý implicitní adresát \"%s\"\n"
 
 #, c-format
 msgid "%s: skipped: public key is disabled\n"
@@ -4657,17 +4551,18 @@ msgstr "%s: přeskočeno: veřejný klíč je neplatný (disabled)\n"
 msgid "no valid addressees\n"
 msgstr "žádné platné adresy\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Note: key %s has no %s feature\n"
-msgstr "Poznámka: klíči %s chybí vlastnost %s\n"
+msgstr "klíč %s: chybí identifikátor uživatele\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Note: key %s has no preference for %s\n"
-msgstr "Poznámka: klíči %s chybí předvolby pro %s\n"
+msgstr "klíč %s: chybí identifikátor uživatele\n"
 
 msgid "data not saved; use option \"--output\" to save it\n"
 msgstr ""
-"data nebyla uložena; k jejich uložení použijte parametr příkazu „--output“\n"
+"data nebyla uložena; k jejich uložení použijte parametr příkazu \"--output"
+"\"\n"
 
 msgid "Detached signature.\n"
 msgstr "Podpis oddělený od dokumentu.\n"
@@ -4676,22 +4571,22 @@ msgid "Please enter name of data file: "
 msgstr "Prosím, vložte název datového souboru: "
 
 msgid "reading stdin ...\n"
-msgstr "čtu standardní vstup\n"
+msgstr "čtu standardní vstup ...\n"
 
 msgid "no signed data\n"
 msgstr "chybí podepsaná data\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
-msgstr "nemohu otevřít podepsaná data „%s“\n"
+msgid "can't open signed data '%s'\n"
+msgstr "nemohu otevřít podepsaná data '%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't open signed data fd=%d: %s\n"
-msgstr "nemohu otevřít podepsaná data na fd=%d: %s\n"
+msgstr "nemohu otevřít podepsaná data '%s'\n"
 
 #, c-format
 msgid "anonymous recipient; trying secret key %s ...\n"
-msgstr "anonymní adresát; zkouším tajný klíč %s\n"
+msgstr "anonymní adresát; zkouším tajný klíč %s ...\n"
 
 msgid "okay, we are the anonymous recipient.\n"
 msgstr "o.k., my jsme anonymní adresát.\n"
@@ -4743,11 +4638,11 @@ msgstr "Revokační certifikát vytvořen.\n"
 
 #, c-format
 msgid "no revocation keys found for \"%s\"\n"
-msgstr "pro „%s“ nebyl nalezen žádný revokační klíč\n"
+msgstr "pro \"%s\" nebyl nalezen žádný revokační klíč\n"
 
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
-msgstr "tajný klíč „%s“ nenalezen: %s\n"
+msgstr "tajný klíč \"%s\" nenalezen: %s\n"
 
 #, c-format
 msgid "no corresponding public key: %s\n"
@@ -4777,10 +4672,10 @@ msgstr ""
 "Revokační certifikát byl vytvořen.\n"
 "\n"
 "Prosím přeneste jej na médium, které můžete dobře schovat. Pokud se\n"
-"k tomuto certifikátu dostane nepovolaná osoba, může zneplatnit váš klíč.\n"
+"k tomuto certifikátu dostane nepovolaná osoba, může zneplatnit Váš klíč.\n"
 "Je rozumné tento certifikát vytisknout a schovat jej pro případ, že\n"
 "medium s certifikátem přestane být čitelné. Ale pozor: Tiskový subsystém\n"
-"na vašem počítači může ukládat data určená k tisku a zpřístupnit je\n"
+"na Vašem počítači může ukládat data určená k tisku a zpřístupnist je\n"
 "jiným uživatelům!\n"
 
 msgid "Please select the reason for the revocation:\n"
@@ -4822,10 +4717,10 @@ msgstr "Neplatné heslo; prosím, zkuste to znovu"
 
 #, c-format
 msgid "%s ...\n"
-msgstr "%s\n"
+msgstr "%s ...\n"
 
 msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr "VAROVÁNÍ: Objeven slabý klíč – změňte, prosím, znovu heslo.\n"
+msgstr "VAROVÁNÍ: Objeven slabý klíč - změňte, prosím, znovu heslo.\n"
 
 msgid "generating the deprecated 16-bit checksum for secret key protection\n"
 msgstr ""
@@ -4833,7 +4728,7 @@ msgstr ""
 "klíče\n"
 
 msgid "weak key created - retrying\n"
-msgstr "vytvořen slabý klíč – zkouším znovu\n"
+msgstr "vytvořen slabý klíč - zkouším znovu\n"
 
 #, c-format
 msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
@@ -4842,15 +4737,15 @@ msgstr ""
 "%d krát!\n"
 
 msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA vyžaduje, aby délka hashe byla násobkem 8 bitů\n"
+msgstr ""
 
 #, c-format
 msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "DSA klíč %s používá nebezpečný (%ubitový) hash\n"
+msgstr ""
 
 #, c-format
 msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "DSA klíč %s vyžaduje hash o délce %u nebo více bitů\n"
+msgstr ""
 
 msgid "WARNING: signature digest conflict in message\n"
 msgstr "VAROVÁNÍ: konflikt hashe podpisu ve zprávě\n"
@@ -4889,9 +4784,9 @@ msgstr ""
 msgid "NOTE: signature key %s expired %s\n"
 msgstr "POZNÁMKA: podpisovému klíči %s skončila platnost %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "NOTE: signature key %s has been revoked\n"
-msgstr "POZNÁMKA: podpisový klíč %s byl odvolán\n"
+msgstr "POZNÁMKA: klíč byl revokován"
 
 #, c-format
 msgid "assuming bad signature from key %s due to an unknown critical bit\n"
@@ -4934,7 +4829,7 @@ msgstr "kontrola vytvořeného podpisu se nepodařila: %s\n"
 
 #, c-format
 msgid "%s/%s signature from: \"%s\"\n"
-msgstr "%s/%s podpis od: „%s“\n"
+msgstr "%s/%s podpis od: \"%s\"\n"
 
 msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
 msgstr ""
@@ -4961,23 +4856,23 @@ msgstr "bude použito šifrování %s\n"
 
 msgid "key is not flagged as insecure - can't use it with the faked RNG!\n"
 msgstr ""
-"klíč není označen jako nedostatečně bezpečný – nemohu jej použít s falešným "
+"klíč není označen jako nedostatečně bezpečný - nemohu jej použít s padělaným "
 "RNG!\n"
 
 #, c-format
 msgid "skipped \"%s\": duplicated\n"
-msgstr "přeskočen „%s“: duplikován\n"
+msgstr "přeskočen \"%s\": duplikován\n"
 
 #, c-format
 msgid "skipped \"%s\": %s\n"
-msgstr "přeskočen „%s“: %s\n"
+msgstr "přeskočen \"%s\": %s\n"
 
 msgid "skipped: secret key already present\n"
 msgstr "přeskočeno: tajný klíč je už v databázi\n"
 
 msgid "this is a PGP generated Elgamal key which is not secure for signatures!"
 msgstr ""
-"toto je PGP klíč vygenerovaný podle algoritmu Elgamal,\n"
+"toto je PGP klíč vygenerovaný podle algoritmu ElGamal,\n"
 "podpisy vytvořené tímto klíčem nejsou bezpečné!"
 
 #, c-format
@@ -4990,11 +4885,11 @@ msgid ""
 "# (Use \"gpg --import-ownertrust\" to restore them)\n"
 msgstr ""
 "# Seznam přidělených hodnot důvěry, vytvořen %s\n"
-"# (Použijte „gpg --import-ownertrust“ k jeho obnově)\n"
+"# (Použijte \"gpg --import-ownertrust\" k jeho obnově)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
-msgstr "chyba v „%s“: %s\n"
+msgid "error in '%s': %s\n"
+msgstr "chyba v `%s': %s\n"
 
 msgid "line too long"
 msgstr "řádek je příliš dlouhý"
@@ -5003,32 +4898,24 @@ msgid "colon missing"
 msgstr "sloupec schází"
 
 msgid "invalid fingerprint"
-msgstr "neplatný otisk"
+msgstr "neplatný fingerprint"
 
 msgid "ownertrust value missing"
-msgstr "schází hodnota důvěryhodnosti vlastníka"
+msgstr "schází hodnota důvěryhosdnosti vlastníka"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
-msgstr "chyba při hledání záznamu důvěryhodnosti v „%s“: %s\n"
+msgid "error finding trust record in '%s': %s\n"
+msgstr "chyba při hledání záznamu důvěryhodnosti v `%s': %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
-msgstr "chyba při čtení v „%s“: %s\n"
+msgid "read error in '%s': %s\n"
+msgstr "chyba při čtení v `%s': %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "databáze důvěry: synchronizace selhala %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "nemohu vytvořit zámek pro  „%s“\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "nelze zamknout „%s“\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "záznam v databázi důvěry %lu: lseek() se nepodařil: %s\n"
 
@@ -5040,12 +4927,20 @@ msgid "trustdb transaction too large\n"
 msgstr "transakce s databází důvěry je příliš dlouhá\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "nemohu otevřít `%s': %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: adresář neexistuje!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nemohu otevřít „%s“: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "nemohu vytvořit zámek pro  `%s'\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "nelze zamčít `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5118,8 +5013,9 @@ msgstr "%s: vynulování záznamu selhalo: %s\n"
 msgid "%s: failed to append a record: %s\n"
 msgstr "%s: přidání záznamu selhalo: %s\n"
 
+#, fuzzy
 msgid "Error: The trustdb is corrupted.\n"
-msgstr "Chyba: Databáze důvěry je poškozena.\n"
+msgstr "%s: databáze důvěry vytvořena\n"
 
 #, c-format
 msgid "can't handle text lines longer than %d characters\n"
@@ -5130,8 +5026,8 @@ msgid "input line longer than %d characters\n"
 msgstr "vstupní řádek je delší než %d znaků\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
-msgstr "„%s“ není platný dlouhý keyID\n"
+msgid "'%s' is not a valid long keyID\n"
+msgstr "`%s' není platný dlouhý keyID\n"
 
 #, c-format
 msgid "key %s: accepted as trusted key\n"
@@ -5143,7 +5039,7 @@ msgstr "klíč %s se v databázi důvěry vyskytuje více než jednou\n"
 
 #, c-format
 msgid "key %s: no public key for trusted key - skipped\n"
-msgstr "klíč %s: nenalezen veřejný klíč k důvěryhodnému klíči – přeskočeno\n"
+msgstr "klíč %s: nenalezen veřejný klíč k důvěryhodnému klíči - přeskočeno\n"
 
 #, c-format
 msgid "key %s marked as ultimately trusted\n"
@@ -5158,28 +5054,20 @@ msgid "trust record %lu is not of requested type %d\n"
 msgstr "záznam důvěry %lu není požadovaného typu %d\n"
 
 msgid "You may try to re-create the trustdb using the commands:\n"
-msgstr "Databázi důvěry můžete zkusit znovu vytvořit pomocí těchto příkazů:\n"
+msgstr ""
 
 msgid "If that does not work, please consult the manual\n"
-msgstr "Pokud to nebude fungovat, prosím, nahlédněte do návodu\n"
+msgstr ""
 
 #, c-format
 msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
 msgstr ""
-"nelze použít neznámý model důvěry (%d) – předpokládáme použití modelu %s\n"
+"nelze použít neznámý model důvěry (%d) - předpokládáme použití modelu %s\n"
 
 #, c-format
 msgid "using %s trust model\n"
-msgstr "použití modelu důvěry %s\n"
-
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
+msgstr "pouižití modelu důvěry %s\n"
+
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 "14 fixní délka na kterou se překládá see trustdb.c:uid_trust_string_fixed"
@@ -5187,9 +5075,8 @@ msgstr ""
 msgid "[ revoked]"
 msgstr "[ revokován  ]"
 
-# TODO: use context to distinguish gender
 msgid "[ expired]"
-msgstr "[ prošlý(á)  ]"
+msgstr "[ expirován  ]"
 
 msgid "[ unknown]"
 msgstr "[  neznámá   ]"
@@ -5229,12 +5116,12 @@ msgid "next trustdb check due at %s\n"
 msgstr "další kontrola databáze důvěry v %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
-msgstr "není nutné kontrolovat databázi důvěry s modelem „%s“\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
+msgstr "není nutné kontrolovat databázi důvěry s modelem `%s'\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
-msgstr "není nutné aktualizovat databázi důvěry s modelem „%s“\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
+msgstr "není nutné aktualizovat databázi důvěry s modelem `%s'\n"
 
 #, c-format
 msgid "public key %s not found: %s\n"
@@ -5285,132 +5172,134 @@ msgstr ""
 msgid "input line %u too long or missing LF\n"
 msgstr "vstupní řádek %u je příliš dlouhý nebo na konci chybí znak LF\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't open fd %d: %s\n"
-msgstr "nemohu otevřít deskriptor %d: %s\n"
+msgstr "nemohu otevřít `%s': %s\n"
 
+#, fuzzy
 msgid "argument not expected"
-msgstr "argument nebyl očekáván"
+msgstr "administrátorské příkazy nejsou povoleny\n"
 
+#, fuzzy
 msgid "read error"
-msgstr "chyba při čtení"
+msgstr "chyba při čtení souboru"
 
+#, fuzzy
 msgid "keyword too long"
-msgstr "klíčové slovo je příliš dlouhé"
+msgstr "řádek je příliš dlouhý"
 
+#, fuzzy
 msgid "missing argument"
-msgstr "postrádám argument"
+msgstr "neplatný argument"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "neplatný způsob reprezentace v ASCII"
-
 msgid "invalid command"
-msgstr "neplatný příkaz"
+msgstr "pouze administrátorské příkazy\n"
 
+#, fuzzy
 msgid "invalid alias definition"
-msgstr "neplatný definice aliasu"
+msgstr "neplatný parametr pro výpis\n"
 
+#, fuzzy
 msgid "out of core"
-msgstr "nedostatek paměti"
+msgstr "není vyžadováno"
 
+#, fuzzy
 msgid "invalid option"
-msgstr "neplatný parametr"
+msgstr "neplatný parametr pro výpis\n"
 
 #, c-format
 msgid "missing argument for option \"%.50s\"\n"
-msgstr "postrádám argument u volby „%.50s“\n"
-
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "postrádám argument u volby „%.50s“\n"
+msgstr ""
 
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "volba „%.50s“ nečeká argument\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "invalid command \"%.50s\"\n"
-msgstr "neplatný příkaz „%.50s“\n"
+msgstr "Neplatný příkaz (zkuste \"help\")\n"
 
 #, c-format
 msgid "option \"%.50s\" is ambiguous\n"
-msgstr "volba „%.50s“ není jednoznačná\n"
+msgstr ""
 
 #, c-format
 msgid "command \"%.50s\" is ambiguous\n"
-msgstr "příkaz „%.50s“ není jednoznačný\n"
+msgstr ""
 
+# Yet another expression for `not enought memory' :)
 msgid "out of core\n"
 msgstr "nedostatek paměti\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "invalid option \"%.50s\"\n"
-msgstr "neplatný parametr „%.50s“\n"
+msgstr "neplatný parametr pro výpis\n"
 
 #, c-format
 msgid "you found a bug ... (%s:%d)\n"
-msgstr "nalezena chyba v programu… (%s:%d)\n"
+msgstr "nalezena chyba v programu ... (%s:%d)\n"
 
-#, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "převod z „%s“ na „%s“ není k dispozici\n"
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "chyba při čtení `%s': %s\n"
 
 #, c-format
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr ""
+
+#, fuzzy, c-format
 msgid "iconv_open failed: %s\n"
-msgstr "iconv_open selhala: %s\n"
+msgstr "podepsání selhalo: %s\n"
 
-#, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "převod z „%s“ na „%s“ se nezdařil: %s\n"
+#, fuzzy, c-format
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "přejmenování `%s' na `%s' se nezdařilo: %s\n"
 
-#, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "nemohu vytvořit dočasný soubor „%s“: %s\n"
+#, fuzzy, c-format
+msgid "failed to create temporary file '%s': %s\n"
+msgstr "nemohu vytvořit adresář `%s': %s\n"
 
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "chyba při zápisu do „%s“: %s\n"
+#, fuzzy, c-format
+msgid "error writing to '%s': %s\n"
+msgstr "chyba při zápisu souboru klíčů (keyring)  `%s': %s\n"
 
 #, c-format
 msgid "removing stale lockfile (created by %d)\n"
-msgstr "odstraňuji starý zamykací soubor (vytvořil %d)\n"
+msgstr ""
 
 msgid " - probably dead - removing lock"
-msgstr " – asi mrtvý – odstraňuji zámek"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "čekám na zámek (drží ho %d%s) %s…\n"
+msgstr "zapisuji tajný klíč do `%s'\n"
 
 msgid "(deadlock?) "
-msgstr "(uváznutí?) "
+msgstr ""
 
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "zámek „%s“ nebyl vytvořen: %s\n"
+#, fuzzy, c-format
+msgid "lock '%s' not made: %s\n"
+msgstr "veřejný klíč %s nebyl nalezen: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "waiting for lock %s...\n"
-msgstr "čekám na zámek %s…\n"
+msgstr "zapisuji tajný klíč do `%s'\n"
 
 msgid "set debugging flags"
-msgstr "nastavit příznaky ladění"
+msgstr ""
 
 msgid "enable full debugging"
-msgstr "zapnout úplné ladění"
+msgstr ""
 
+#, fuzzy
 msgid "Usage: kbxutil [options] [files] (-h for help)"
-msgstr "Použití: kbxutil [VOLBY] [SOUBORY] (-h pro nápovědu)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
-"Syntaxe: kbxutil [VOLBY] [SOUBORY]\n"
-"Vypisuje, exportuje, importuje schránku na klíče (keybox).\n"
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5422,46 +5311,42 @@ msgstr "schází veřejný RSA exponent nebo je delší než %d bitů\n"
 
 #, c-format
 msgid "PIN callback returned error: %s\n"
-msgstr "funkce PIN callback skončila chybou: %s\n"
+msgstr "funkce PIN callback zkončila chybou: %s\n"
 
 msgid "the NullPIN has not yet been changed\n"
-msgstr "NullPIN ještě nebyl změněn\n"
+msgstr ""
 
-# TRANSLATORS: Do not translate the "|*|" prefixes but keep
-# them verbatim at the start of the string.  */
+#, fuzzy
 msgid "|N|Please enter a new PIN for the standard keys."
-msgstr "|N|Prosím, zadejte nový PIN pro standardní klíče."
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
+#, fuzzy
 msgid "||Please enter the PIN for the standard keys."
-msgstr "||Prosím, zadejte PIN pro standardní klíče."
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
+#, fuzzy
 msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|NP|Prosím, zadejte nový kód pro odblokování (PUK) standardních klíčů."
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
+#, fuzzy
 msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|P|Prosím, zadejte kód pro odblokování (PUK) standardních klíčů."
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
 msgid "|N|Please enter a new PIN for the key to create qualified signatures."
 msgstr ""
-"|N|Prosím, zadejte nový PIN klíče určeného na tvorbu kvalifikovaných podpisů."
 
 msgid "||Please enter the PIN for the key to create qualified signatures."
 msgstr ""
-"||Prosím, zadejte PIN klíče určeného na tvorbu kvalifikovaných podpisů."
 
 msgid ""
 "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Prosím, zadejte nový kód pro odblokování (PUK) klíče určeného na tvorbu "
-"kvalifikovaných podpisů."
 
 msgid ""
 "|P|Please enter the PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Prosím, zadejte kód pro odblokování (PUK) klíče určeného na tvorbu "
-"kvalifikovaných podpisů."
 
 #, c-format
 msgid "error getting new PIN: %s\n"
@@ -5469,11 +5354,11 @@ msgstr "chyba při získání nového PINu: %s\n"
 
 #, c-format
 msgid "failed to store the fingerprint: %s\n"
-msgstr "uložení otisku se nezdařilo: %s\n"
+msgstr "uložení fingerprintu se nezdařilo: %s\n"
 
 #, c-format
 msgid "failed to store the creation date: %s\n"
-msgstr "uložení data vytvoření se nezdařilo: %s\n"
+msgstr "uložení datumu vytvoření se nezdařilo: %s\n"
 
 #, c-format
 msgid "reading public key failed: %s\n"
@@ -5490,20 +5375,19 @@ msgstr "odpověď neobsahuje veřejný RSA exponent\n"
 
 #, c-format
 msgid "using default PIN as %s\n"
-msgstr "používám implicitní PIN jako %s\n"
+msgstr ""
 
 #, c-format
 msgid "failed to use default PIN as %s: %s - disabling further default use\n"
 msgstr ""
-"použití implicitního PINu jako %s selhalo: %s – vypínám jeho budoucí "
-"použití\n"
 
 #, c-format
 msgid "||Please enter the PIN%%0A[sigs done: %lu]"
 msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
+#, fuzzy
 msgid "||Please enter the PIN"
-msgstr "||Prosím vložte PIN"
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
 #, c-format
 msgid "PIN for CHV%d is too short; minimum length is %d\n"
@@ -5511,7 +5395,7 @@ msgstr "PIN pro CHV%d je příliš krátký; minimální délka je %d\n"
 
 #, c-format
 msgid "verify CHV%d failed: %s\n"
-msgstr "ověření CHV%d se nezdařilo: %s\n"
+msgstr "verifikace CHV%d se nezdařila: %s\n"
 
 msgid "error retrieving CHV status from card\n"
 msgstr "chyba při získání CHV z karty\n"
@@ -5526,46 +5410,39 @@ msgstr ""
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %%0A to force a linefeed.
-#, c-format
+#, fuzzy, c-format
 msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-msgstr "|A|Prosím, zadejte PIN správce%%0A[zbývá pokusů: %d]"
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
+#, fuzzy
 msgid "|A|Please enter the Admin PIN"
-msgstr "|A|Prosím, zadejte PIN správce"
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
 msgid "access to admin commands is not configured\n"
 msgstr "přístup k administrátorským příkazům není nakonfigurován\n"
 
+#, fuzzy
 msgid "||Please enter the Reset Code for the card"
-msgstr "||Prosím, zadejte resetační kód karty"
+msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "Resetační kód je příliš krátký; minimální délka je %d\n"
+msgstr "PIN pro CHV%d je příliš krátký; minimální délka je %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
-msgstr "|RN|Nový resetační kód"
+msgstr ""
 
 msgid "|AN|New Admin PIN"
-msgstr "|AN|Nový PIN správce"
+msgstr "|AN|Nový PIN administrátora"
 
 msgid "|N|New PIN"
 msgstr "|N|Nový PIN"
 
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||Prosím, zadejte PIN správce a nový PIN správce"
-
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Prosím, zadejte PIN a nový PIN"
-
 msgid "error reading application data\n"
 msgstr "chyba při čtení aplikačních dat\n"
 
 msgid "error reading fingerprint DO\n"
-msgstr "chyba při čtení otisku DO\n"
+msgstr "chyba při čtení fingerpritnu DO\n"
 
 msgid "key already exists\n"
 msgstr "klíč již existuje\n"
@@ -5576,8 +5453,9 @@ msgstr "existující klíč bude přepsán\n"
 msgid "generating new key\n"
 msgstr "generování nového klíče\n"
 
+#, fuzzy
 msgid "writing new key\n"
-msgstr "nový klíč se zapisuje\n"
+msgstr "generování nového klíče\n"
 
 msgid "creation timestamp missing\n"
 msgstr "chybí časové razítko vytvoření\n"
@@ -5591,24 +5469,24 @@ msgid "failed to store the key: %s\n"
 msgstr "nelze uložit klíč: %s\n"
 
 msgid "please wait while key is being generated ...\n"
-msgstr "prosím počkejte než bude klíč vygenerován\n"
+msgstr "prosím počkejte než bude klíč vygenerován ...\n"
 
 msgid "generating key failed\n"
-msgstr "generování klíče se nezdařilo\n"
+msgstr "henerování klíče se nezdařilo\n"
 
 #, c-format
 msgid "key generation completed (%d seconds)\n"
 msgstr "generování klíče dokončeno (%d sekund)\n"
 
 msgid "invalid structure of OpenPGP card (DO 0x93)\n"
-msgstr "neplatná struktura OpenPGP karty (DO 0x93)\n"
+msgstr "neplatná struktura OpenPGP kraty (DO 0x93)\n"
 
 msgid "fingerprint on card does not match requested one\n"
-msgstr "otisk na kartě se neshoduje s požadovaným\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "card does not support digest algorithm %s\n"
-msgstr "karta nepodporuje hashovací algoritmus %s\n"
+msgstr "podpis %s, hashovací algoritmus %s\n"
 
 #, c-format
 msgid "signatures created so far: %lu\n"
@@ -5616,301 +5494,316 @@ msgstr "dosud vytvořené podpisy: %lu\n"
 
 msgid ""
 "verification of Admin PIN is currently prohibited through this command\n"
-msgstr "ověření PIN správce je nyní prostřednictvím tohoto příkazu zakázáno\n"
+msgstr ""
+"ověření administrátorského PIN je nyní prostřednictvím tohoto příkazu "
+"zakázáno\n"
 
 #, c-format
 msgid "can't access %s - invalid OpenPGP card?\n"
-msgstr "přístup na %s se nezdařil – vadná OpenPGP karta?\n"
+msgstr "přístup na %s se nezdařil - vadná OpenPGP karta?\n"
 
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||Prosím, zadejte svůj PIN na klávesnici čtečky"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
 #. to get some infos on the string.
+#, fuzzy
 msgid "|N|Initial New PIN"
-msgstr "|N|Prvotní nový PIN"
+msgstr "|N|Nový PIN"
 
 msgid "run in multi server mode (foreground)"
-msgstr "pracovat ve více serverové režimu (na popředí)"
+msgstr ""
 
 msgid "|LEVEL|set the debugging level to LEVEL"
-msgstr "|ÚROVEŇ|nastavit úroveň ladění na ÚROVEŇ"
+msgstr "|ÚROVEŇ|nastaví ladicí úroveň na ÚROVEŇ"
 
+#, fuzzy
 msgid "|FILE|write a log to FILE"
-msgstr "|SOUBOR|zapisovat protokol do SOUBORU"
+msgstr "čtu možnosti z `%s'\n"
 
 msgid "|N|connect to reader at port N"
-msgstr "|N|připojit se na čtečku na portu N"
+msgstr ""
 
 msgid "|NAME|use NAME as ct-API driver"
-msgstr "NÁZEV|použít NÁZEV jako ovladač ct-API"
+msgstr ""
 
 msgid "|NAME|use NAME as PC/SC driver"
-msgstr "NÁZEV|použít NÁZEV jako ovladač PC/SC"
+msgstr ""
 
 msgid "do not use the internal CCID driver"
-msgstr "nepoužívat vnitřní ovladač CCID"
+msgstr ""
 
 msgid "|N|disconnect the card after N seconds of inactivity"
-msgstr "|N|odpojovat se od karty po N sekundách nečinnosti"
+msgstr ""
 
-msgid "do not use a reader's pinpad"
-msgstr "nepoužívat klávesnici čtečky"
+msgid "do not use a reader's keypad"
+msgstr ""
 
+#, fuzzy
 msgid "deny the use of admin card commands"
-msgstr "zakázat používání správcovských příkazů karty"
-
-msgid "use variable length input for pinpad"
-msgstr "používat vstup o proměnné délce na klávesnici čtečky"
+msgstr "zobraz administrátorské příkazy"
 
+#, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Použití: scdaemon [možnosti] [SOUBORY] (-h pro nápovědu)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
 "Smartcard daemon for GnuPG\n"
 msgstr ""
-"Syntaxe: scdaemon [VOLBY] [PŘÍKAZ [ARGUMENTY]]\n"
-"Démon pro čipové karty (smartcard) pro GnuPG\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
-"prosím, použijte volbu „--daemon“, chcete-li nechat běžet program na pozadí\n"
 
 #, c-format
 msgid "handler for fd %d started\n"
-msgstr "obsluha pro deskriptor %d spuštěna\n"
+msgstr "obsluha pro deskriptor %d nastartována\n"
 
 #, c-format
 msgid "handler for fd %d terminated\n"
 msgstr "obsluha pro deskriptor %d ukončena\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "invalid radix64 character %02x skipped\n"
-msgstr "neplatný radix64 znak %02x byl přeskočen\n"
+msgstr "neplatný radix64 znak %02X byl přeskočen\n"
 
 #, c-format
 msgid "failed to proxy %s inquiry to client\n"
-msgstr "předání dotazu %s klientovi se nezdařilo\n"
+msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "žádný dirmngr neběží – spouští se „%s“\n"
+msgid "no running dirmngr - starting '%s'\n"
+msgstr ""
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "špatný formát proměnné prostředí DIRMNGR_INFO\n"
+msgstr "poškozená proměnná prostření DIRMNGR_INFO\n"
 
 #, c-format
 msgid "dirmngr protocol version %d is not supported\n"
-msgstr "protokol dirmngr verze %d není podporován\n"
+msgstr "verze %d protokolu dirmngr není podporována\n"
 
 msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr "k dirmngr se nelze připojit – zkouším náhradní způsob\n"
+msgstr "k dirmngr se nelze připojit – zkusí se náhradní postup\n"
 
 #, c-format
 msgid "validation model requested by certificate: %s"
-msgstr "certifikátem vyžadovaný ověřovací model: %s"
+msgstr ""
 
 msgid "chain"
-msgstr "řetězený"
+msgstr ""
 
 msgid "shell"
-msgstr "jednovrstvý"
+msgstr ""
 
 #, c-format
 msgid "critical certificate extension %s is not supported"
-msgstr "kritické rozšíÅ\99ení certifikát %s není podporováno"
+msgstr "kritické rozšíÅ\99ené certifikátu %s není podporováno"
 
 msgid "issuer certificate is not marked as a CA"
-msgstr "vydavatel certifikátu není označen jako CA"
+msgstr "certifikát vydavatele není označen jako CA"
 
 msgid "critical marked policy without configured policies"
-msgstr "politika označená jako kritická bez nastavených politik"
+msgstr ""
 
-#, c-format
-msgid "failed to open `%s': %s\n"
-msgstr "nemohu otevřít „%s“: %s\n"
+#, fuzzy, c-format
+msgid "failed to open '%s': %s\n"
+msgstr "Nemohu otevřít `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
-msgstr "poznámka: nekritické certifikační politiky nejsou dovoleny"
+msgstr "poznámka: nekritické certifikační politiky nejsou povoleny"
 
 msgid "certificate policy not allowed"
-msgstr "certifikační politika není dovolena"
+msgstr "certifikační politika není povolena"
 
 msgid "looking up issuer at external location\n"
-msgstr "hledám vydavatele na jiném místě\n"
+msgstr ""
 
 #, c-format
 msgid "number of issuers matching: %d\n"
-msgstr "počet odpovídajících vydavatelů: %d\n"
+msgstr ""
 
 msgid "looking up issuer from the Dirmngr cache\n"
-msgstr "hledám vydavatele ve vyrovnávací paměti Dirmngr\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "number of matching certificates: %d\n"
-msgstr "počet odpovídajících certifikátů: %d\n"
+msgstr "chyba při vytváření hesla: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "dirmngr cache-only key lookup failed: %s\n"
-msgstr "hledání klíče pouze ve vyrovnávací paměti dirmngr neuspělo: %s\n"
+msgstr "čtení veřejného klíče se nezdařilo: %s\n"
 
-msgid "failed to allocate keyDB handle\n"
-msgstr "alokace popisovače keyDB se nezdařila\n"
+#, fuzzy
+msgid "failed to allocated keyDB handle\n"
+msgstr "nelze uložit klíč: %s\n"
 
+#, fuzzy
 msgid "certificate has been revoked"
-msgstr "certifikát byl odvolán"
+msgstr "POZNÁMKA: klíč byl revokován"
 
 msgid "the status of the certificate is unknown"
-msgstr "status certifikáty není znám"
+msgstr ""
 
 msgid "please make sure that the \"dirmngr\" is properly installed\n"
-msgstr "prosím, ujistěte se, že „dirmngr“ je správně nainstalován\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "checking the CRL failed: %s"
-msgstr "kontrola CRL se nezdařila: %s"
+msgstr "kontrola vytvořeného podpisu se nepodařila: %s\n"
 
 #, c-format
 msgid "certificate with invalid validity: %s"
-msgstr "certifikát s neplatnou platností: %s"
+msgstr "certifikát s chybnou platností: %s"
 
 msgid "certificate not yet valid"
-msgstr "certifikát ještě nezačal platit"
+msgstr "certifikát ještě nenabyl platnosti"
 
+#, fuzzy
 msgid "root certificate not yet valid"
-msgstr "kořenový certifikát ještě nezačal platit"
+msgstr "exportování tajného klíče není povoleno\n"
 
 msgid "intermediate certificate not yet valid"
-msgstr "mezilehlý certifikát ještě nezačal platit"
+msgstr ""
 
 msgid "certificate has expired"
-msgstr "certifikát je prošlý"
+msgstr "certifikátu vypršela platnost"
 
+#, fuzzy
 msgid "root certificate has expired"
-msgstr "kořenový certifikát je prošlý"
+msgstr "Platnost klíče vypršela!"
 
+#, fuzzy
 msgid "intermediate certificate has expired"
-msgstr "mezilehlý certifikát je prošlý"
+msgstr "Platnost klíče vypršela!"
 
 #, c-format
 msgid "required certificate attributes missing: %s%s%s"
-msgstr "chybí povinné atributy certifikátu: %s%s%s"
+msgstr ""
 
+#, fuzzy
 msgid "certificate with invalid validity"
-msgstr "certifikát s neplatnou platností"
+msgstr "Platnost klíče vypršela!"
 
 msgid "signature not created during lifetime of certificate"
-msgstr "podpis nebyl vytvořen v době životnosti certifikátu"
+msgstr ""
 
 msgid "certificate not created during lifetime of issuer"
-msgstr "certifikát nebyl vytvořen v době životnosti vydavatele"
+msgstr ""
 
 msgid "intermediate certificate not created during lifetime of issuer"
-msgstr "mezilehlý certifikát nebyl vytvořen v době životnosti vydavatele"
+msgstr ""
 
+#, fuzzy
 msgid "  (  signature created at "
-msgstr "  (       podpis vytvořen "
+msgstr "         odstraněné podpisy: %lu\n"
 
+#, fuzzy
 msgid "  (certificate created at "
-msgstr "  (   certifikát vytvořen "
+msgstr "Revokační certifikát vytvořen.\n"
 
+#, fuzzy
 msgid "  (certificate valid from "
-msgstr "  (   certifikát planý od "
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "  (     issuer valid from "
-msgstr "  (   vydavatel platný od "
+msgstr "      Seriové číslo karty ="
 
 #, c-format
 msgid "fingerprint=%s\n"
 msgstr "otisk=%s\n"
 
 msgid "root certificate has now been marked as trusted\n"
-msgstr "kořenový certifikát byl nyní označen za důvěryhodný\n"
+msgstr ""
 
 msgid "interactive marking as trusted not enabled in gpg-agent\n"
-msgstr "v gpg-agentu není povoleno interaktivní označování za důvěryhodný\n"
+msgstr ""
 
 msgid "interactive marking as trusted disabled for this session\n"
-msgstr "interaktivní označovaní jako důvěryhodný je pro tuto relaci zakázáno\n"
+msgstr ""
 
 msgid "WARNING: creation time of signature not known - assuming current time"
-msgstr "VAROVÁNÍ: datum vytvoření podpisu není známo – předpokládám současnost"
+msgstr ""
 
+#, fuzzy
 msgid "no issuer found in certificate"
-msgstr "v certifikátu nebyl nalezen vydavatel"
+msgstr "vytvořit revokační certifikát"
 
 msgid "self-signed certificate has a BAD signature"
-msgstr "certifikát podepsaný sám sebou má ŠPATNÝ podpis"
+msgstr ""
 
 msgid "root certificate is not marked trusted"
 msgstr "kořenový certifikát není označen jako důvěryhodný"
 
-#, c-format
+#, fuzzy, c-format
 msgid "checking the trust list failed: %s\n"
-msgstr "kontrola seznamu důvěry se nepodařila: %s\n"
+msgstr "kontrola vytvořeného podpisu se nepodařila: %s\n"
 
 msgid "certificate chain too long\n"
 msgstr "řetěz certifikátů je příliš dlouhý\n"
 
 msgid "issuer certificate not found"
-msgstr "vydavatel certifikátu nebyl nalezen"
+msgstr "certifikát vydavatele nebyl nalezen"
 
 msgid "certificate has a BAD signature"
-msgstr "certifikát má ŠPATNÝ podpis"
+msgstr "certifikát má CHYBNÝ podpis"
 
 msgid "found another possible matching CA certificate - trying again"
-msgstr "nalezen další možný odpovídající certifikát CA – zkouším znovu"
+msgstr "nalezen jiný možný odpovídající certifikát autority – zkusí se znovu"
 
 #, c-format
 msgid "certificate chain longer than allowed by CA (%d)"
-msgstr "řetězec certifikátů je delší, než je dovoleno CA (%d)"
+msgstr "řetěz certifikátů je delší než dovoluje CA (%d)"
 
 msgid "certificate is good\n"
 msgstr "certifikát je v pořádku\n"
 
+#, fuzzy
 msgid "intermediate certificate is good\n"
-msgstr "mezilehlý certifikát je v pořádku\n"
+msgstr "Revokační certifikát vytvořen.\n"
 
+#, fuzzy
 msgid "root certificate is good\n"
-msgstr "kořenový certifikát je v pořádku\n"
+msgstr "špatný certifikát"
 
 msgid "switching to chain model"
-msgstr "přepínám do řetězeného modelu"
+msgstr ""
 
 #, c-format
 msgid "validation model used: %s"
-msgstr "použit ověřovací model: %s"
+msgstr ""
 
 #, c-format
 msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "%s klíč používá nebezpečný (%ubitový) hash\n"
+msgstr ""
 
 #, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
-msgstr "%ubitový hash není platná pro %ubitový %s klíč\n"
+msgstr ""
 
 msgid "(this is the MD2 algorithm)\n"
-msgstr "(toto je algoritmus MD2)\n"
+msgstr ""
 
-# none serial, none date
+# status
 msgid "none"
 msgstr "žádný"
 
+#, fuzzy
 msgid "[Error - invalid encoding]"
-msgstr "[Chyba – neplatné kódování]"
+msgstr "Chyba: neplatná odpověď.\n"
 
 msgid "[Error - out of core]"
-msgstr "[Chyba – nedostatek paměti]"
+msgstr ""
 
 msgid "[Error - No name]"
-msgstr "[Chyba – Žádné jméno]"
+msgstr ""
 
+#, fuzzy
 msgid "[Error - invalid DN]"
-msgstr "[Chyba – neplatné DN]"
+msgstr "Chyba: neplatná odpověď.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Please enter the passphrase to unlock the secret key for the X.509 "
 "certificate:\n"
@@ -5918,410 +5811,446 @@ msgid ""
 "S/N %s, ID 0x%08lX,\n"
 "created %s, expires %s.\n"
 msgstr ""
-"Potřebujete heslo, abyste odemkl(a) tajný klíč pro X.509 certifikát:\n"
-"„%s“\n"
-"sériové číslo %s, ID 0x%08lX,\n"
-"vytvořeno %s, platnost vyprší %s.\n"
+"Potřebujete heslo, abyste odemknul(a) tajný klíč pro uživatele:\n"
+"\"%.*s\"\n"
+"Klíč o délce %u bitů, typ %s, ID %s, vytvořený %s%s\n"
 
 msgid "no key usage specified - assuming all usages\n"
-msgstr "žádný způsob užití neuveden â\80\93 pÅ\99edpokládám vÅ¡echna užití\n"
+msgstr "žádné použití klíÄ\8de není urÄ\8deno â\80\93 pÅ\99edpokládají se vÅ¡echna použití\n"
 
 #, c-format
 msgid "error getting key usage information: %s\n"
-msgstr "chyba při získání informací o způsobu užití klíče: %s\n"
+msgstr "chyba při zjišťování informací o použití klíče: %s\n"
 
-msgid "certificate should not have been used for certification\n"
-msgstr "certifikát neměl být použit pro certifikování\n"
+msgid "certificate should have not been used for certification\n"
+msgstr "certifikát by neměl být použit pro certifikace\n"
 
-msgid "certificate should not have been used for OCSP response signing\n"
-msgstr "certifikát neměl být použit pro podepsání OCSP odpovědi\n"
+msgid "certificate should have not been used for OCSP response signing\n"
+msgstr "certifikát by neměl být použit pro podepisování OCSP odpovědí\n"
 
-msgid "certificate should not have been used for encryption\n"
-msgstr "certifikát neměl použit pro šifrování\n"
+msgid "certificate should have not been used for encryption\n"
+msgstr "certifikát by neměl být použit pro šifrování\n"
 
-msgid "certificate should not have been used for signing\n"
-msgstr "certifikát neměl být použit pro podepsání\n"
+msgid "certificate should have not been used for signing\n"
+msgstr "certifikát by neměl být použit pro podepisování\n"
 
 msgid "certificate is not usable for encryption\n"
-msgstr "certifikát není použitelný pro šifrování\n"
+msgstr "certifikát není pro šifrování použitelný\n"
 
 msgid "certificate is not usable for signing\n"
-msgstr "certifikát není použitelný pro podepisování\n"
+msgstr "certifikát není pro podepisování použitelný\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "line %d: invalid algorithm\n"
-msgstr "řádek %d: neplatný algoritmus\n"
+msgstr "neplatný hashovací algoritmus `%s'\n"
 
 #, c-format
 msgid "line %d: invalid key length %u (valid are %d to %d)\n"
-msgstr "řádek %d: neplatná délka klíče %u (platná je %d až %d)\n"
+msgstr ""
 
 #, c-format
 msgid "line %d: no subject name given\n"
-msgstr "řádek %d: nezadán žádný název subjektu\n"
+msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
-msgstr "řádek %d: neplatný název subjektu „%.*s“\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
+msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
-msgstr "řádek %d: neplatná název subjektu „%s“ na pozici %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "line %d: not a valid email address\n"
-msgstr "řádek %d: neplatná e-mailová adresa\n"
+msgstr "Neplatná e-mailová adresa\n"
 
-#, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
-msgstr "řádek %d: chyba při čtení klíče „%s“ z karty: %s\n"
+#, fuzzy, c-format
+msgid "line %d: error reading key '%s' from card: %s\n"
+msgstr "chyba při vytváření souboru klíčů (keyring)`%s': %s\n"
 
-#, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
-msgstr "řádek %d: chyba při získávání klíče po keygripu „%s“: %s\n"
+#, fuzzy, c-format
+msgid "line %d: error getting key by keygrip '%s': %s\n"
+msgstr "chyba při vytváření souboru klíčů (keyring)`%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "line %d: key generation failed: %s <%s>\n"
-msgstr "řádek %d: generování klíče se nepodařilo: %s <%s>\n"
+msgstr "Vytvoření klíče se nepodařilo: %s\n"
 
 msgid ""
 "To complete this certificate request please enter the passphrase for the key "
 "you just created once more.\n"
 msgstr ""
-"Žádost o certifikát dokončíte tím, že zadáte heslo pro klíč, který jste "
-"právě vytvořili, ještě jednou.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA\n"
-msgstr "   (%d) RSA\n"
+msgstr "   (%d) RSA (pouze pro podpis)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) Existing key\n"
-msgstr "   (%d) Existující klíč\n"
+msgstr "   (2) Šifrovací klíč\n"
 
 #, c-format
 msgid "   (%d) Existing key from card\n"
-msgstr "   (%d) Klíč existující na kartě\n"
+msgstr ""
 
+#, fuzzy
 msgid "Enter the keygrip: "
-msgstr "Vložte keygrip: "
+msgstr "Podepisovací notace: "
 
 msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Není platným keygripem (očekáváno 40 šestnáctkových číslic)\n"
+msgstr ""
 
+#, fuzzy
 msgid "No key with this keygrip\n"
-msgstr "Klíč s takovým keygripem neexistuje\n"
+msgstr "Neexistuje podklíč s indexem %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading the card: %s\n"
-msgstr "chyba při čtení z karty: %s\n"
+msgstr "%s: chyba při čtení volného záznamu: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Serial number of the card: %s\n"
-msgstr "Sériové číslo karty: %s\n"
+msgstr "chyba při získání nového PINu: %s\n"
 
+#, fuzzy
 msgid "Available keys:\n"
-msgstr "Dostupné klíče:\n"
+msgstr "nastavit klíč jako neplatný (disable)"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Possible actions for a %s key:\n"
-msgstr "Možné způsoby užití %s klíče:\n"
+msgstr "Pro klíč %s lze provést: "
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) sign, encrypt\n"
-msgstr "   (%d) podepisovat, šifrovat\n"
+msgstr "   (%d) DSA (pouze pro podpis)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) sign\n"
-msgstr "   (%d) podepisovat\n"
+msgstr "   (%d) DSA (pouze pro podpis)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) encrypt\n"
-msgstr "   (%d) šifrovat\n"
+msgstr "   (%d) RSA (pouze pro šifrování)\n"
 
 msgid "Enter the X.509 subject name: "
-msgstr "Zadejte X.509 jméno subjektu: "
+msgstr ""
 
+#, fuzzy
 msgid "No subject name given\n"
-msgstr "Nebylo zadáno Žádné jméno\n"
+msgstr "(Nebyl zadán Žádný popis)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
-msgstr "Neplatné jméno subjektu „%.*s“\n"
+msgid "Invalid subject name label '%.*s'\n"
+msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
 #. length of the first string up to the "%s".  Please
 #. adjust it do the length of your translation.  The
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
-#, c-format
-msgid "Invalid subject name `%s'\n"
-msgstr "Neplatné jméno subjektu „%s“\n"
+#, fuzzy, c-format
+msgid "Invalid subject name '%s'\n"
+msgstr "neplatný hashovací algoritmus `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
-msgstr "25 délka předešlého řetězce: see certreg-ui.c:gpgsm_gencertreq_tty"
+msgstr ""
 
+#, fuzzy
 msgid "Enter email addresses"
-msgstr "Zadejte e-mailovou adresu"
+msgstr "E-mailová adresa: "
 
+#, fuzzy
 msgid " (end with an empty line):\n"
-msgstr " (ukončete prázdným řádkem):\n"
+msgstr ""
+"\n"
+"Napište identifikátor uživatele (user ID). Ukončete prázdným řádkem: "
 
+#, fuzzy
 msgid "Enter DNS names"
-msgstr "Zadejte DNS jména"
+msgstr "Vložte nový název souboru"
 
+#, fuzzy
 msgid " (optional; end with an empty line):\n"
-msgstr " (volitelné; ukončete prázdným řádkem):\n"
+msgstr "Můžete vložit další popis. Ukončete prázdným řádkem:\n"
 
+#, fuzzy
 msgid "Enter URIs"
-msgstr "Zadejte (několik) URI"
+msgstr "Vložte PIN: "
 
 msgid "Parameters to be used for the certificate request:\n"
-msgstr "Parametry, které budou použity v žádosti o certifikát:\n"
+msgstr ""
 
 msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr "Nyní se vytváří žádost o certifikát. To může chvíli trvat…\n"
+msgstr ""
 
 msgid "Ready.  You should now send this request to your CA.\n"
-msgstr "Hotovo. Nyní byste měli tuto žádost poslat svojí CA.\n"
+msgstr ""
 
 msgid "resource problem: out of core\n"
-msgstr "problém se zdroji: nedostatek paměti\n"
+msgstr ""
 
 msgid "(this is the RC2 algorithm)\n"
-msgstr "(toto je algoritmus RC2)\n"
+msgstr ""
 
 msgid "(this does not seem to be an encrypted message)\n"
-msgstr "(toto nevypadá jako zašifrovaná zpráva)\n"
+msgstr ""
 
-#, c-format
-msgid "certificate `%s' not found: %s\n"
-msgstr "certifikát „%s“ nebyl nenalezen: %s\n"
+#, fuzzy, c-format
+msgid "certificate '%s' not found: %s\n"
+msgstr "tajný klíč \"%s\" nenalezen: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error locking keybox: %s\n"
-msgstr "chyba při zamykání schránky na klíče: %s\n"
+msgstr "chyba při čtení bloku klíče: %s\n"
 
-#, c-format
-msgid "duplicated certificate `%s' deleted\n"
-msgstr "smazat zdvojený certifikát „%s“\n"
+#, fuzzy, c-format
+msgid "duplicated certificate '%s' deleted\n"
+msgstr "Revokační certifikát vytvořen.\n"
 
-#, c-format
-msgid "certificate `%s' deleted\n"
-msgstr "certifikát „%s“ smazán\n"
+#, fuzzy, c-format
+msgid "certificate '%s' deleted\n"
+msgstr "duplicita předvolby `%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "deleting certificate \"%s\" failed: %s\n"
-msgstr "smazání certifikátu „%s“ se nezdařilo: %s\n"
+msgstr "smazání bloku klíče se nezdařilo:  %s\n"
 
+#, fuzzy
 msgid "no valid recipients given\n"
-msgstr "(nebyli zadáni Žádní platní příjemci)\n"
+msgstr "(Nebyl zadán Žádný popis)\n"
 
+#, fuzzy
 msgid "list external keys"
-msgstr "vypsat seznam externích klíčů"
+msgstr "vypsat seznam tajných klíčů"
 
+#, fuzzy
 msgid "list certificate chain"
-msgstr "vypsat řetěz certifikátů"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "import certificates"
-msgstr "importovat certifikáty"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "export certificates"
-msgstr "exportovat certifikáty"
+msgstr "špatný certifikát"
 
+#, fuzzy
 msgid "register a smartcard"
-msgstr "zaregistrovat čipovou kartu"
+msgstr "přidat klíč na kartu"
 
 msgid "pass a command to the dirmngr"
-msgstr "předat příkaz do dirmngr"
+msgstr ""
 
 msgid "invoke gpg-protect-tool"
-msgstr "vyvolat gpg-protect-tool"
+msgstr ""
 
+#, fuzzy
+msgid "change a passphrase"
+msgstr "změnit heslo"
+
+#, fuzzy
 msgid "create base-64 encoded output"
-msgstr "vytvářet výstup zakódovaný pomocí Base-64"
+msgstr "vytvoř výstup zakódovaný pomocí ASCII"
 
 msgid "assume input is in PEM format"
-msgstr "předpokládat vstup ve formátu PEM"
+msgstr ""
 
 msgid "assume input is in base-64 format"
-msgstr "předpokládat vstup ve formátu Base-64"
+msgstr ""
 
 msgid "assume input is in binary format"
-msgstr "předpokládat vstup v binárním formátu"
+msgstr ""
 
 msgid "use system's dirmngr if available"
-msgstr "použít systémový dirmngr, je-li dostupný"
+msgstr ""
 
 msgid "never consult a CRL"
-msgstr "nikdy nenahlížet do CRL"
+msgstr ""
 
 msgid "check validity using OCSP"
-msgstr "kontrolovat platnost pomocí OCSP"
+msgstr ""
 
 msgid "|N|number of certificates to include"
-msgstr "|N|počet certifikátů, které zahrnout"
+msgstr ""
 
 msgid "|FILE|take policy information from FILE"
-msgstr "|SOUBOR|vzít politiky ze SOUBORU"
+msgstr ""
 
 msgid "do not check certificate policies"
-msgstr "nekontrolovat politiky certifikátu"
+msgstr ""
 
 msgid "fetch missing issuer certificates"
-msgstr "stahovat chybějící certifikáty vydavatelů"
+msgstr ""
 
 msgid "don't use the terminal at all"
-msgstr "vůbec nepoužívat terminál"
+msgstr ""
 
 msgid "|FILE|write a server mode log to FILE"
-msgstr "|SOUBOR|zapisovat protokol režimu server do SOUBORU"
+msgstr ""
 
+#, fuzzy
 msgid "|FILE|write an audit log to FILE"
-msgstr "|SOUBOR|zapisovat auditní protokol do SOUBORU"
+msgstr "čtu možnosti z `%s'\n"
 
 msgid "batch mode: never ask"
-msgstr "dávkový režim: nikdy se neptat"
+msgstr ""
 
 msgid "assume yes on most questions"
-msgstr "předpokládat ano na většinu otázek"
+msgstr ""
 
 msgid "assume no on most questions"
-msgstr "předpokládat ne na většinu otázek"
+msgstr ""
 
+#, fuzzy
 msgid "|FILE|add keyring to the list of keyrings"
-msgstr "|SOUBOR|přidat klíčenku na seznam klíčenek"
+msgstr "ber klíče z této klíčenky (keyringu)"
 
 msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|ID_UŽIVATELE|použít ID_UŽIVATELE jako implicitní tajný klíč"
+msgstr ""
 
 msgid "|SPEC|use this keyserver to lookup keys"
-msgstr "|SPEC|použít tento server pro dohledávání klíčů"
+msgstr ""
 
+#, fuzzy
 msgid "|NAME|use cipher algorithm NAME"
-msgstr "|NÁZEV|použít šifrovací algoritmus NÁZEV"
+msgstr "neznámý šifrovací algoritmus"
 
+#, fuzzy
 msgid "|NAME|use message digest algorithm NAME"
-msgstr "|NÁZEV|použít hashovací algoritmus NÁZEV"
+msgstr "podpis %s, hashovací algoritmus %s\n"
 
+#, fuzzy
 msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Použití: gpgsm [VOLBY] [SOUBORY] (-h pro nápovědu)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
+#, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
-"Syntaxe: gpgsm [VOLBY] [SOUBORY]\n"
-"Podepisuje, ověřuje, šifruje nebo dešifruje pomocí protokolu S/MIME.\n"
-"Výchozí operace závisí na vstupních datech.\n"
+"Syntaxe: gpg [možnosti] [soubory]\n"
+"podepsat, ověřit, šifrovat nebo dešifrovat\n"
+"implicitní operace závisí na vstupních datech\n"
 
+#, fuzzy
 msgid "usage: gpgsm [options] "
-msgstr "užití: gpgsm [VOLBY] "
+msgstr "užití: gpg [možnosti]"
 
-#, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
-msgstr "POZNÁMKA: nebudu moci šifrovat pro „%s“: %s\n"
+#, fuzzy, c-format
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
+msgstr "nemohu se připojit k `%s': %s\n"
 
-#, c-format
-msgid "unknown validation model `%s'\n"
-msgstr "neznámý režim ovÄ\9bÅ\99ování â\80\9e%sâ\80\9c\n"
+#, fuzzy, c-format
+msgid "unknown validation model '%s'\n"
+msgstr "neznámá volba `%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%u: no hostname given\n"
-msgstr "%s:%u: nebyl zadán název stroje\n"
+msgstr "(Nebyl zadán Žádný popis)\n"
 
 #, c-format
 msgid "%s:%u: password given without user\n"
-msgstr "%s:%u: zadáno heslo bez uživatele\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%u: skipping this line\n"
-msgstr "%s:%u: přeskakuji tento řádek\n"
+msgstr " s = přeskočit tento klíč\n"
 
+#, fuzzy
 msgid "could not parse keyserver\n"
-msgstr "nelze rozebrat serveru klíčů\n"
+msgstr "nelze zpracovat URL serveru klíčů\n"
 
 msgid "WARNING: running with faked system time: "
-msgstr "VAROVÁNÍ: pracuji s podvrženým systémovým časem: "
+msgstr ""
 
 #, c-format
-msgid "importing common certificates `%s'\n"
-msgstr "importuji běžné certifikáty „%s“\n"
+msgid "importing common certificates '%s'\n"
+msgstr ""
 
-#, c-format
-msgid "can't sign using `%s': %s\n"
-msgstr "nemohu podepsat pomocí „%s“: %s\n"
+#, fuzzy, c-format
+msgid "can't sign using '%s': %s\n"
+msgstr "nemohu otevřít `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
-msgstr "neplatný příkaz (neexistuje žádný implicitní příkaz)\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "total number processed: %lu\n"
-msgstr "celkem zpracováno: %lu\n"
+msgstr "Celkový počet zpracovaných klíčů: %lu\n"
 
+#, fuzzy
 msgid "error storing certificate\n"
-msgstr "chyba při ukládání certifikátu\n"
+msgstr "vytvořit revokační certifikát"
 
 msgid "basic certificate checks failed - not imported\n"
-msgstr "základní kontrola certifikátu selhala – neimportováno\n"
+msgstr ""
 
-#, c-format
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "nelze uložit klíč: %s\n"
+
+#, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
-msgstr "chyba při získání uložených příznaků: %s\n"
+msgstr "chyba při získání nového PINu: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error importing certificate: %s\n"
-msgstr "chyba při importování certifikátu: %s\n"
+msgstr "chyba při vytváření hesla: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading input: %s\n"
-msgstr "chyba při čtení vstupu: %s\n"
+msgstr "chyba při čtení `%s': %s\n"
 
-#, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "chyba při vytváření schránky na klíče (keybox) „%s“: %s\n"
+#, fuzzy, c-format
+msgid "error creating keybox '%s': %s\n"
+msgstr "chyba při vytváření souboru klíčů (keyring)`%s': %s\n"
 
-#, c-format
-msgid "keybox `%s' created\n"
-msgstr "schránka na klíče (keybox) „%s“ vytvořena\n"
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
 
+#, fuzzy, c-format
+msgid "keybox '%s' created\n"
+msgstr "soubor klíčů (keyring) `%s' vytvořen\n"
+
+#, fuzzy
 msgid "failed to get the fingerprint\n"
-msgstr "otisk se nepodařilo získat\n"
+msgstr "uložení fingerprintu se nezdařilo: %s\n"
 
 #, c-format
 msgid "problem looking for existing certificate: %s\n"
-msgstr "problém při hledání existujícího certifikátu: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error finding writable keyDB: %s\n"
-msgstr "chyba při hledání zapisovatelné keyDB: %s\n"
+msgstr "chyba při hledání záznamu důvěryhodnosti v `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error storing certificate: %s\n"
-msgstr "chyba při ukládání certifikátu: %s\n"
+msgstr "chyba při získání informací o aktuálním klíči: %s\n"
 
 #, c-format
 msgid "problem re-searching certificate: %s\n"
-msgstr "problém při opakovaném hledání certifikátu: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error storing flags: %s\n"
-msgstr "chyba při ukládání příznaků: %s\n"
+msgstr "chyba při čtení `%s': %s\n"
 
 msgid "Error - "
-msgstr "Chyba – "
+msgstr ""
 
 msgid "GPG_TTY has not been set - using maybe bogus default\n"
-msgstr "GPG_TTY nebyla nastavena – použiji možná chybnou implicitní hodnotu\n"
+msgstr ""
 
-#, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "nesprávně formátovaný otisk v „%s“, řádek %d\n"
+#, fuzzy, c-format
+msgid "invalid formatted fingerprint in '%s', line %d\n"
+msgstr "Chyba: nesprávně naformátovaný fingerprint.\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "neplatný kód země v „%s“, řádek %d\n"
+msgid "invalid country code in '%s', line %d\n"
+msgstr ""
 
 #, c-format
 msgid ""
@@ -6332,19 +6261,11 @@ msgid ""
 "\n"
 "%s%sAre you really sure that you want to do this?"
 msgstr ""
-"Chystáte se vytvořit podpis pomocí svého certifikátu:\n"
-"„%s“\n"
-"Tímto vytvoříte kvalifikovaný podpis, který je dle zákona rovnocenný\n"
-"s podpisem vlastnoručním.\n"
-"\n"
-"%s%sJste si skutečně jistý(á), že to chcete udělat?"
 
 msgid ""
 "Note, that this software is not officially approved to create or verify such "
 "signatures.\n"
 msgstr ""
-"Vezměte na vědomí, že tento software není oficiálně schválený k vytváření "
-"nebo ověřování takových podpisů.\n"
 
 #, c-format
 msgid ""
@@ -6352,1576 +6273,1666 @@ msgid ""
 "\"%s\"\n"
 "Note, that this certificate will NOT create a qualified signature!"
 msgstr ""
-"Chystáte se vytvořit podpis pomocí svého certifikátu:\n"
-"„%s“\n"
-"Vezměte na vědomí, že tento certifikát NEVYTVOŘÍ kvalifikovaný podpis!"
 
-#, c-format
+#, fuzzy, c-format
 msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
-msgstr ""
-"hashovací algoritmus %d (%s) podepisovatele %d není podporován; použiji %s\n"
+msgstr "ochranný algoritmus %d%s není podporován\n"
 
 #, c-format
 msgid "hash algorithm used for signer %d: %s (%s)\n"
-msgstr "hashovací algoritmus použitý pro podepisovatele %d: %s (%s)\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "checking for qualified certificate failed: %s\n"
-msgstr "kontrola kvalifikovaného certifikátu selhala: %s\n"
+msgstr "kontrola vytvořeného podpisu se nepodařila: %s\n"
 
+#, fuzzy
 msgid "Signature made "
-msgstr "Podpis vytvořen "
+msgstr "Podpis vytvořen %s\n"
 
 msgid "[date not given]"
-msgstr "[datum neudáno]"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid " using certificate ID 0x%08lX\n"
-msgstr " pomocí certifikátu s ID 0x%08lX\n"
+msgstr "chyba při získání informací o aktuálním klíči: %s\n"
 
 msgid ""
 "invalid signature: message digest attribute does not match computed one\n"
 msgstr ""
-"neplatný podpis: atribut otisku zprávy se neshoduje s vypočteným otiskem\n"
 
+#, fuzzy
 msgid "Good signature from"
-msgstr "Dobrý podpis od"
+msgstr "Dobrý podpis od \"%s\""
 
+#, fuzzy
 msgid "                aka"
-msgstr "          alias"
+msgstr "                alias \"%s\""
 
+#, fuzzy
 msgid "This is a qualified signature\n"
-msgstr "Toto je kvalifikovaný podpis\n"
+msgstr "Jedná se o podpis klíče jím samým.\n"
 
+#, fuzzy
 msgid "quiet"
-msgstr "stručný výstup"
+msgstr "ukončit"
 
 msgid "print data out hex encoded"
-msgstr "vypisovat data v šestnáctkové soustavě"
+msgstr ""
 
 msgid "decode received data lines"
-msgstr "dekódovat přijaté datové řádky"
+msgstr ""
 
 msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NÁZEV|připojit se na socket Assuanu s NÁZVEM"
+msgstr ""
 
 msgid "run the Assuan server given on the command line"
-msgstr "spustit server Assuan zadaný na příkazové řádce"
+msgstr ""
 
 msgid "do not use extended connect mode"
-msgstr "nepoužívat rozšířený režim připojení"
+msgstr ""
 
+#, fuzzy
 msgid "|FILE|run commands from FILE on startup"
-msgstr "|SOUBOR|spustit příkazy ze SOUBORU při startu"
+msgstr "čtu možnosti z `%s'\n"
 
 msgid "run /subst on startup"
-msgstr "spustit /subst při startu"
+msgstr ""
 
+#, fuzzy
 msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Použití: gpg-connect-agent [VOLBY] [SOUBORY] (-h pro nápovědu)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: gpg-connect-agent [options]\n"
 "Connect to a running agent and send commands\n"
 msgstr ""
-"Syntaxe: gpg-connect-agent [VOLBY]\n"
-"Připojí se na běžícího agenta a odesílá příkazy\n"
 
 #, c-format
 msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr "volba „%s“ vyžaduje program a volitelné argumenty\n"
+msgstr ""
 
 #, c-format
 msgid "option \"%s\" ignored due to \"%s\"\n"
-msgstr "volba „%s“ ignorovaná kvůli „%s“\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "receiving line failed: %s\n"
-msgstr "přijímání řádku se nezdařilo: %s\n"
+msgstr "čtení veřejného klíče se nezdařilo: %s\n"
 
+#, fuzzy
 msgid "line too long - skipped\n"
-msgstr "řádek je příliš dlouhý – přeskočen\n"
+msgstr "řádek je příliš dlouhý"
 
 msgid "line shortened due to embedded Nul character\n"
-msgstr "řádek zkrácen, protože obsahoval znak \\0\n"
+msgstr ""
 
-#, c-format
-msgid "unknown command `%s'\n"
-msgstr "neznámý pÅ\99íkaz â\80\9e%sâ\80\9c\n"
+#, fuzzy, c-format
+msgid "unknown command '%s'\n"
+msgstr "neznámá volba `%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "sending line failed: %s\n"
-msgstr "odesílání řádku selhalo: %s\n"
+msgstr "podepsání selhalo: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error sending %s command: %s\n"
-msgstr "chyba při odesílání příkazu %s: %s\n"
+msgstr "chyba při čtení `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error sending standard options: %s\n"
-msgstr "chyba při odesílání standardního parametru: %s\n"
+msgstr "chyba při hledání záznamu důvěryhodnosti v `%s': %s\n"
 
 msgid "Options controlling the diagnostic output"
-msgstr "Volby ovlivňující diagnostický výstup"
+msgstr ""
 
 msgid "Options controlling the configuration"
-msgstr "Volby ovlivňující nastavení"
+msgstr ""
 
 msgid "Options useful for debugging"
-msgstr "Volby užitečné při ladění"
+msgstr ""
 
 msgid "|FILE|write server mode logs to FILE"
-msgstr "|SOUBOR|zapisuje protokol serverového režimu do SOUBORU"
+msgstr "|SOUBOR|protokol z režimu serveru se zapíše do SOUBORU"
 
 msgid "Options controlling the security"
-msgstr "Volby ovlivňující bezpečnost"
+msgstr ""
 
 msgid "|N|expire SSH keys after N seconds"
-msgstr "|N|zahazovat klíče SSH po N sekundách"
+msgstr ""
 
 msgid "|N|set maximum PIN cache lifetime to N seconds"
-msgstr "|N|nastavit maximální životnost dočasné paměti pro PINy na N sekund"
+msgstr ""
 
 msgid "|N|set maximum SSH key lifetime to N seconds"
-msgstr "|N| nastavit maximální životnost klíčů SSH na N sekund"
+msgstr ""
 
 msgid "Options enforcing a passphrase policy"
-msgstr "Volby vynucující politiku hesel"
+msgstr ""
 
 msgid "do not allow to bypass the passphrase policy"
-msgstr "nedovolit obejít politiku hesel"
+msgstr ""
 
 msgid "|N|set minimal required length for new passphrases to N"
-msgstr "|N|nastavit minimální vyžadovanou délku nových hesel na N"
+msgstr ""
 
 msgid "|N|require at least N non-alpha characters for a new passphrase"
-msgstr "|N|vyžaduje alespoň N nepísmenných znaků v novém hesle"
+msgstr ""
 
 msgid "|FILE|check new passphrases against pattern in FILE"
-msgstr "|SOUBOR|prověřovat nová hesla proti vzorům v SOUBORU"
+msgstr ""
 
+#, fuzzy
 msgid "|N|expire the passphrase after N days"
-msgstr "|N|omezit platnost hesla na N dnů"
+msgstr "revokovat klíč nebo vybrané podklíče"
 
+#, fuzzy
 msgid "do not allow the reuse of old passphrases"
-msgstr "nedovolit opakovat stará hesla"
+msgstr "chyba při vytváření hesla: %s\n"
 
 msgid "|NAME|use NAME as default secret key"
-msgstr "|NÁZEV|použít NÁZEV jako implicitní tajný klíč"
+msgstr ""
 
+#, fuzzy
 msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|JMÉNO|šifrovat rovněž pro uživatele s ID JMÉNO"
+msgstr "|JMÉNO|šifrovat pro JMÉNO"
 
 msgid "|SPEC|set up email aliases"
-msgstr "|SPEC|nastavit e-mailový alias"
+msgstr ""
 
 msgid "Configuration for Keyservers"
-msgstr "Nastavení serverů klíčů"
+msgstr ""
 
+#, fuzzy
 msgid "|URL|use keyserver at URL"
-msgstr "|URL|používat server klíčů na URL"
+msgstr "nelze zpracovat URL serveru klíčů\n"
 
 msgid "allow PKA lookups (DNS requests)"
-msgstr "povolit dohledávání PKA (dotazy na DNS)"
+msgstr ""
 
 msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
-msgstr "|METODA|používat METODU pro dohledávání klíčů podle e-mailové adresy"
+msgstr ""
 
 msgid "disable all access to the dirmngr"
-msgstr "zakázat veškerý přístup k dirmngr"
+msgstr ""
 
 msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr "|NÁZEV|používat kódování NÁZEV pro PKCS#12 hesla"
+msgstr ""
 
 msgid "do not check CRLs for root certificates"
-msgstr "neprověřovat kořenové certifikáty proti CRL"
+msgstr ""
 
 msgid "Options controlling the format of the output"
-msgstr "Volby ovlivňující podobu výstupu"
+msgstr ""
 
 msgid "Options controlling the interactivity and enforcement"
-msgstr "Volby ovlivňující interaktivitu a vymáhání"
+msgstr ""
 
 msgid "Configuration for HTTP servers"
-msgstr "Nastavení HTTP serverů"
+msgstr ""
 
 msgid "use system's HTTP proxy setting"
-msgstr "používat systémové nastavení HTTP proxy"
+msgstr ""
 
 msgid "Configuration of LDAP servers to use"
-msgstr "Nastavení používaných LDAP serverů"
+msgstr ""
 
 msgid "LDAP server list"
-msgstr "Seznam LDAP serverů"
+msgstr ""
 
 msgid "Configuration for OCSP"
-msgstr "Nastavení OCSP"
+msgstr ""
 
 #, c-format
 msgid "External verification of component %s failed"
-msgstr "Selhalo externí ověření komponenty %s"
+msgstr ""
 
 msgid "Note that group specifications are ignored\n"
-msgstr "Vezměte na vědomí, že určení skupiny se ignoruje\n"
+msgstr ""
 
 msgid "list all components"
-msgstr "vypsat všechny komponenty"
+msgstr ""
 
 msgid "check all programs"
-msgstr "zkontrolovat všechny programy"
+msgstr ""
 
 msgid "|COMPONENT|list options"
-msgstr "|KOMPONENTA|vypsat volby"
+msgstr ""
 
 msgid "|COMPONENT|change options"
-msgstr "|KOMPONENTA|změnit volby"
+msgstr ""
 
 msgid "|COMPONENT|check options"
-msgstr "|KOMPONENTA|zkontrolovat volby"
+msgstr ""
 
 msgid "apply global default values"
-msgstr "aplikovat globální implicitní hodnoty"
+msgstr ""
 
 msgid "get the configuration directories for gpgconf"
-msgstr "získat adresáře s nastavením gpgconfu"
+msgstr ""
 
+# c-format
+#, fuzzy
 msgid "list global configuration file"
-msgstr "vypsat globální konfigurační soubor"
+msgstr "neznámá konfigurační položka \"%s\"\n"
 
+# c-format
+#, fuzzy
 msgid "check global configuration file"
-msgstr "zkontrolovat globální konfigurační soubor"
+msgstr "neznámá konfigurační položka \"%s\"\n"
 
 msgid "use as output file"
 msgstr "použít jako výstupní soubor"
 
 msgid "activate changes at runtime, if possible"
-msgstr "provést změny za běhu, pokud to lze"
+msgstr ""
 
+#, fuzzy
 msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Použití: gpgconf [VOLBY] (-h pro nápovědu)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: gpgconf [options]\n"
 "Manage configuration options for tools of the GnuPG system\n"
 msgstr ""
-"Syntaxe: gpgconf [VOLBY]\n"
-"Spravuje konfigurační volby nástrojů, které patří do systému GnuPG\n"
 
+#, fuzzy
 msgid "usage: gpgconf [options] "
-msgstr "použití: gpgconf [VOLBY] "
+msgstr "užití: gpg [možnosti]"
 
 msgid "Need one component argument"
-msgstr "Potřebuji jeden argument určující komponentu"
+msgstr ""
 
+#, fuzzy
 msgid "Component not found"
-msgstr "Komponenta nenalezena"
+msgstr "veřejný klíč nenalezen"
 
+#, fuzzy
 msgid "No argument allowed"
-msgstr "Žádné argumenty nejsou povoleny"
+msgstr "administrátorské příkazy nejsou povoleny\n"
 
+#, fuzzy
 msgid ""
 "@\n"
 "Commands:\n"
 " "
 msgstr ""
-"@\n"
-"Příkazy:\n"
+"@Příkazy:\n"
 " "
 
+#, fuzzy
 msgid "decryption modus"
-msgstr "dešifrovací modus"
+msgstr "dešifrování o.k.\n"
 
+#, fuzzy
 msgid "encryption modus"
-msgstr "šifrovací modus"
+msgstr "dešifrování o.k.\n"
 
 msgid "tool class (confucius)"
-msgstr "třída nástrojů (Konfucius)"
+msgstr ""
 
+#, fuzzy
 msgid "program filename"
-msgstr "název souboru s programem"
+msgstr "--store [jméno souboru]"
 
 msgid "secret key file (required)"
-msgstr "soubor s tajným klíčem (nezbytné)"
+msgstr ""
 
 msgid "input file name (default stdin)"
-msgstr "název vstupního souboru (implicitně standardní vstup)"
+msgstr ""
 
+#, fuzzy
 msgid "Usage: symcryptrun [options] (-h for help)"
-msgstr "Použití: symcryptrun [VOLBY]  (-h pro nápovědu)"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE "
 "[options...] COMMAND [inputfile]\n"
 "Call a simple symmetric encryption tool\n"
 msgstr ""
-"Syntaxe: symcryptrun --class TŘÍDA --program PROGRAM --keyfile SOUBOR "
-"[VOLBY…] PŘÍKAZ [VSTUPNÍ_SOUBOR]\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s on %s aborted with status %i\n"
-msgstr "%s nad %s byl ukončen s kódem %i\n"
+msgstr "Není dovoleno používat %s s %s!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s on %s failed with status %i\n"
-msgstr "%s nad %s selhal s kódem %i\n"
+msgstr "fstat `%s' selhal na %s: %s\n"
 
-#, c-format
-msgid "can't create temporary directory `%s': %s\n"
-msgstr "nemohu vytvořit dočasný adresář „%s“: %s\n"
+#, fuzzy, c-format
+msgid "can't create temporary directory '%s': %s\n"
+msgstr "nemohu vytvořit adresář `%s': %s\n"
 
 #, c-format
 msgid "could not open %s for writing: %s\n"
-msgstr "%s nelze otevřít pro zápis: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing to %s: %s\n"
-msgstr "chyba při zápisu do %s: %s\n"
+msgstr "chyba při zápisu souboru klíčů (keyring)  `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading from %s: %s\n"
-msgstr "chyba při čtení %s': %s\n"
+msgstr "chyba při čtení `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error closing %s: %s\n"
-msgstr "chyba při zavírání chyba %s: %s\n"
+msgstr "chyba v `%s': %s\n"
 
+#, fuzzy
 msgid "no --program option provided\n"
-msgstr "nebyla zadána volba --program\n"
+msgstr "spuštění externího programu není podporováno\n"
 
 msgid "only --decrypt and --encrypt are supported\n"
-msgstr "pouze --decrypt a --encrypt jsou podporovány\n"
+msgstr ""
 
 msgid "no --keyfile option provided\n"
-msgstr "nebyla zadána volba --keyfile\n"
+msgstr ""
 
 msgid "cannot allocate args vector\n"
-msgstr "nelze alokovat pole argumentů\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "could not create pipe: %s\n"
-msgstr "nelze vytvořit rouru: %s\n"
+msgstr "nemohu vytvořit `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "could not create pty: %s\n"
-msgstr "nelze vytvořit PTY: %s\n"
+msgstr "nemohu vytvořit `%s': %s\n"
 
 #, c-format
 msgid "could not fork: %s\n"
-msgstr "nelze se rozdvojit (fork): %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "execv failed: %s\n"
-msgstr "execv selhalo: %s\n"
+msgstr "aktualizace selhala: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "select failed: %s\n"
-msgstr "služba select() selhala: %s\n"
+msgstr "smazání bloku klíče se nezdařilo:  %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "read failed: %s\n"
-msgstr "čtení selhalo: %s\n"
+msgstr "aktualizace selhala: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "pty read failed: %s\n"
-msgstr "čtení z PTY selhalo: %s\n"
+msgstr "aktualizace selhala: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "waitpid failed: %s\n"
-msgstr "služba waitpid() selhala: %s\n"
+msgstr "aktualizace selhala: %s\n"
 
 #, c-format
 msgid "child aborted with status %i\n"
-msgstr "potomek byl ukončen s kódem %i\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "cannot allocate infile string: %s\n"
-msgstr "nelze alokovat řetězec infile: %s\n"
+msgstr "nemohu vytvořit zálohu souboru `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "cannot allocate outfile string: %s\n"
-msgstr "nelze alokovat řetězec outfile: %s\n"
+msgstr "nemohu vytvořit zálohu souboru `%s': %s\n"
 
 #, c-format
 msgid "either %s or %s must be given\n"
-msgstr "musí být zadáno buď %s, nebo %s\n"
+msgstr ""
 
 msgid "no class provided\n"
-msgstr "nezadána žádná třída\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "class %s is not supported\n"
-msgstr "třída %s není podporována\n"
+msgstr "ochranný algoritmus %d není podporován\n"
 
+#, fuzzy
 msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n"
-msgstr ""
-"Použití: gpg-check-pattern [VOLBY] SOUBOR_SE_VZOREM (-h pro nápovědu)\n"
+msgstr "Použití: gpg [možnosti] [soubory] (-h pro pomoc)"
 
 msgid ""
 "Syntax: gpg-check-pattern [options] patternfile\n"
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
-"Syntaxe: gpg-check-pattern [VOLBY] SOUBOR_SE_VZOREM\n"
-"Prověří heslo zadané na vstupu proti souboru se vzory\n"
-
-#~ msgid "you may want to start the gpg-agent first\n"
-#~ msgstr "možná byste chtěl(a) nejprve spustit gpg-agenta\n"
-
-#~ msgid "enable ssh-agent emulation"
-#~ msgstr "zapnout emulaci ssh-agenta"
-
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "chyba při nahrávání „%s“: %s\n"
-
-#~ msgid "a %zu bit hash is not valid for a %u bit %s key\n"
-#~ msgstr "%zubitový hash není platný pro %ubitový %s klíč\n"
-
-#~ msgid "public key algorithm %d (%s) is not supported\n"
-#~ msgstr "algoritmus %d (%s) veřejného klíče není podporován\n"
-
-#~ msgid "protection hash algorithm %d (%s) is not supported\n"
-#~ msgstr "ochranný algoritmus %d (%s) není podporován\n"
-
-#~ msgid "error creating a stream for a pipe: %s\n"
-#~ msgstr "chyba při vytváření proudu pro rouru: %s\n"
-
-#~ msgid "connection to agent established\n"
-#~ msgstr "spojení na agenta ustanoveno\n"
-
-#~ msgid "waiting for the dirmngr to come up ... (%ds)\n"
-#~ msgstr "čeká se na dirmngr… (%d s)\n"
-
-#~ msgid "connection to the dirmngr established\n"
-#~ msgstr "spojení na dirmngr ustanoveno\n"
-
-#~ msgid "deleting secret key not implemented\n"
-#~ msgstr "smazání tajného klíče není implementováno\n"
-
-#~ msgid " - skipped"
-#~ msgstr " – přeskočeno"
-
-#~ msgid "key %s: secret key already exists\n"
-#~ msgstr "klíč %s: tajný klíč již existuje\n"
-
-#~ msgid "key %s: error sending to agent: %s\n"
-#~ msgstr "klíč %s: chyba při odesílání dat agentovi: %s\n"
-
-#~ msgid "key %s: error changing passphrase: %s\n"
-#~ msgstr "klíč %s: chyba při měnění hesla: %s\n"
-
-#~ msgid "   (%d) ECDSA and ECDH\n"
-#~ msgstr "   (%d) ECDSA a ECDH\n"
-
-#~ msgid "  (%d) ECDSA (sign only)\n"
-#~ msgstr "  (%d) ECDSA (pouze pro podpis)\n"
-
-#~ msgid "  (%d) ECDSA (set your own capabilities)\n"
-#~ msgstr "  (%d) ECDSA (nastavit si vlastní použití)\n"
-
-#~ msgid "  (%d) ECDH (encrypt only)\n"
-#~ msgstr "  (%d) ECDH (pouze pro šifrování)\n"
-
-#~ msgid "rounded to %u bits\n"
-#~ msgstr "zaokrouhleno na %u bitů\n"
-
-#~ msgid "requesting key from `%s'\n"
-#~ msgstr "požaduji klíč z „%s“\n"
-
-#~ msgid ""
-#~ "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n"
-#~ msgstr ""
-#~ "U veřejného klíče ECDSA se očekává, že v kódování SEC bude délka násobkem "
-#~ "8 bitů\n"
-
-#~ msgid ""
-#~ "Please enter the passphrase to unlock the secret key for the OpenPGP "
-#~ "certificate:"
-#~ msgstr ""
-#~ "Prosím, zadejte heslo, abyste odemkl(a) tajný klíč příslušející OpenPGP "
-#~ "certifikátu:"
-
-#~ msgid ""
-#~ "Please enter the passphrase to import the secret key for the OpenPGP "
-#~ "certificate:"
-#~ msgstr ""
-#~ "Prosím, zadejte heslo, abyste mohl(a) importovat tajný klíč příslušející "
-#~ "OpenPGP certifikátu:"
-
-#~ msgid ""
-#~ "%s\n"
-#~ "\"%.*s\"\n"
-#~ "%u-bit %s key, ID %s,\n"
-#~ "created %s%s.\n"
-#~ msgstr ""
-#~ "%s\n"
-#~ "„%.*s“\n"
-#~ "%ubitový klíč %s, ID %s,\n"
-#~ "vytvořen %s%s.\n"
-
-#~ msgid "%s key %s uses an unsafe (%zu bit) hash\n"
-#~ msgstr "%s klíč %s používá nebezpečný (%zubitový) hash\n"
-
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "alokace popisovače keyDB se nezdařila\n"
-
-#~ msgid "line %d: invalid serial number\n"
-#~ msgstr "řádek %d: neplatné sériové číslo\n"
-
-#~ msgid "line %d: invalid issuer name label `%.*s'\n"
-#~ msgstr "řádek %d: neplatný název vydavatele „%.*s“\n"
 
-#~ msgid "line %d: invalid issuer name `%s' at pos %d\n"
-#~ msgstr "řádek %d: neplatný název vydavatele „%s“ na pozici %d\n"
-
-#~ msgid "line %d: invalid date given\n"
-#~ msgstr "řádek %d: zadáno neplatné datum\n"
-
-#~ msgid "line %d: error getting signing key by keygrip `%s': %s\n"
-#~ msgstr ""
-#~ "řádek %d: chyba při získávání podpisového klíče podle keygripu „%s“: %s\n"
-
-#~ msgid "line %d: invalid hash algorithm given\n"
-#~ msgstr "řádek %d: zadán neplatný algoritmus hashe\n"
-
-#~ msgid "Create self-signed certificate? (y/N) "
-#~ msgstr "Vytvořit sám sebou podepsaný certifikát? (a/N)"
-
-#~ msgid "These parameters are used:\n"
-#~ msgstr "Budou použity tyto parametry:\n"
-
-#~ msgid "Now creating self-signed certificate.  "
-#~ msgstr "Nyní se vytváří sám sebou podepsaný certifikát. "
-
-#~ msgid "This may take a while ...\n"
-#~ msgstr "To může chvíli trvat…\n"
-
-# Ready ve významu finished po vygenerování certifikátu
-#~ msgid "Ready.\n"
-#~ msgstr "Hotovo.\n"
+#, fuzzy
+msgid "DSA requires the use of a 160 bit hash algorithm\n"
+msgstr ""
+"DSA požaduje použití 160-ti bitového hashovacího algoritmu\n"
 
-#~ msgid "can't initialize certificate cache lock: %s\n"
-#~ msgstr "zámek keše certifikát nelze inicializovat: %s\n"
+#, c-format
+msgid "can't initialize certificate cache lock: %s\n"
+msgstr "zámek keše certifikát nelze inicializovat: %s\n"
 
-#~ msgid "can't acquire read lock on the certificate cache: %s\n"
-#~ msgstr "zámek pro čtení keše certifikátů nelze získat: %s\n"
+#, c-format
+msgid "can't acquire read lock on the certificate cache: %s\n"
+msgstr "zámek pro čtení keše certifikátů nelze získat: %s\n"
 
-#~ msgid "can't acquire write lock on the certificate cache: %s\n"
-#~ msgstr "zámek pro zápis keše certifikátů nelze získat: %s\n"
+#, c-format
+msgid "can't acquire write lock on the certificate cache: %s\n"
+msgstr "zámek pro zápis keše certifikátů nelze získat: %s\n"
 
-#~ msgid "can't release lock on the certificate cache: %s\n"
-#~ msgstr "zámek keše certifikátů nelze uvolnit: %s\n"
+#, c-format
+msgid "can't release lock on the certificate cache: %s\n"
+msgstr "zámek keše certifikátů nelze uvolnit: %s\n"
 
 # TODO: plural
-#~ msgid "dropping %u certificates from the cache\n"
-#~ msgstr "%u certifikátů bude z keše vyřazeno\n"
+#, c-format
+msgid "dropping %u certificates from the cache\n"
+msgstr "%u certifikátů bude z keše vyřazeno\n"
 
-#~ msgid "can't access directory `%s': %s\n"
-#~ msgstr "k adresáři „%s“ nelze přistoupit: %s\n"
+#, c-format
+msgid "can't access directory '%s': %s\n"
+msgstr "k adresáři „%s“ nelze přistoupit: %s\n"
 
-#~ msgid "can't parse certificate `%s': %s\n"
-#~ msgstr "certifikát „%s“ nelze rozebrat: %s\n"
+#, c-format
+msgid "can't setup KSBA reader: %s\n"
+msgstr "čtečku KSBA nelze nastavit: %s\n"
 
-#~ msgid "certificate `%s' already cached\n"
-#~ msgstr "certifikát „%s“ je již v keši\n"
+#, c-format
+msgid "can't parse certificate '%s': %s\n"
+msgstr "certifikát „%s“ nelze rozebrat: %s\n"
+
+#, c-format
+msgid "certificate '%s' already cached\n"
+msgstr "certifikát „%s“ je již v keši\n"
 
-#~ msgid "trusted certificate `%s' loaded\n"
-#~ msgstr "zaveden důvěryhodný certifikát „%s“\n"
+#, c-format
+msgid "trusted certificate '%s' loaded\n"
+msgstr "zaveden důvěryhodný certifikát „%s“\n"
 
-#~ msgid "certificate `%s' loaded\n"
-#~ msgstr "certifikát „%s“ zaveden\n"
+#, c-format
+msgid "certificate '%s' loaded\n"
+msgstr "certifikát „%s“ zaveden\n"
 
-#~ msgid "  SHA1 fingerprint = %s\n"
-#~ msgstr " otisk SHA1 = %s\n"
+#, c-format
+msgid "  SHA1 fingerprint = %s\n"
+msgstr " otisk SHA1 = %s\n"
 
-#~ msgid "   issuer ="
-#~ msgstr "vydavatel ="
+msgid "   issuer ="
+msgstr "vydavatel ="
 
 # XXX: align with msgid "   issuer ="
-#~ msgid "  subject ="
-#~ msgstr "  subjekt ="
+msgid "  subject ="
+msgstr "  subjekt ="
 
-#~ msgid "error loading certificate `%s': %s\n"
-#~ msgstr "chyba při zavádění certifikátu „%s“: %s\n"
+#, c-format
+msgid "error loading certificate '%s': %s\n"
+msgstr "chyba při zavádění certifikátu „%s“: %s\n"
 
-# XXX: Align with msgid "runtime cached certificates:"
-#~ msgid "permanently loaded certificates: %u\n"
-#~ msgstr "   trvale zavedených certifikátů: %u\n"
+#, c-format
+msgid "permanently loaded certificates: %u\n"
+msgstr "trvale zavedených certifikátů: %u\n"
 
 # XXX: Align with msgid "permanently loaded certificates:"
-#~ msgid "    runtime cached certificates: %u\n"
-#~ msgstr "za běhu nakešovaných certifikátů: %u\n"
+#, c-format
+msgid "    runtime cached certificates: %u\n"
+msgstr "certifikátů po dobu běhu v keši: %u\n"
 
-#~ msgid "certificate already cached\n"
-#~ msgstr "certifikát již v keši\n"
+msgid "certificate already cached\n"
+msgstr "certifikát již v keši\n"
 
-#~ msgid "certificate cached\n"
-#~ msgstr "certifikát uložen do keše\n"
+msgid "certificate cached\n"
+msgstr "certifikát uložen do keše\n"
 
-#~ msgid "error caching certificate: %s\n"
-#~ msgstr "chyba při ukládání certifikátu do keše: %s\n"
+#, c-format
+msgid "error caching certificate: %s\n"
+msgstr "chyba při ukládání certifikátu do keše: %s\n"
 
-#~ msgid "invalid SHA1 fingerprint string `%s'\n"
-#~ msgstr "neplatný řetězec otisku SHA1 „%s“\n"
+#, c-format
+msgid "invalid SHA1 fingerprint string '%s'\n"
+msgstr "neplatný řetězec otisku SHA1 „%s“\n"
 
-#~ msgid "error fetching certificate by S/N: %s\n"
-#~ msgstr "chyba při stahování certifikátu určeného sériovým číslem: %s\n"
+#, c-format
+msgid "error fetching certificate by S/N: %s\n"
+msgstr "chyba při stahování certifikátu určeného sériovým číslem: %s\n"
 
-#~ msgid "error fetching certificate by subject: %s\n"
-#~ msgstr "chyba při stahovaní certifikátu určeného subjektem: %s\n"
+#, c-format
+msgid "error fetching certificate by subject: %s\n"
+msgstr "chyba při stahovaní certifikátu určeného subjektem: %s\n"
 
-#~ msgid "no issuer found in certificate\n"
-#~ msgstr "v certifikátu nebyl nalezen vydavatel\n"
+msgid "no issuer found in certificate\n"
+msgstr "v certifikátu nebyl nalezen vydavatel\n"
 
-#~ msgid "error getting authorityKeyIdentifier: %s\n"
-#~ msgstr "chyba při zjišťování authorityKeyIdentifier: %s\n"
+#, c-format
+msgid "error getting authorityKeyIdentifier: %s\n"
+msgstr "chyba při zjišťování authorityKeyIdentifier: %s\n"
 
-#~ msgid "creating directory `%s'\n"
-#~ msgstr "vytváří se adresář „%s“\n"
+#, c-format
+msgid "creating directory '%s'\n"
+msgstr "vytváří se adresář „%s“\n"
 
-#~ msgid "error creating directory `%s': %s\n"
-#~ msgstr "chyba při zakládání adresáře „%s“: %s\n"
+#, c-format
+msgid "error creating directory '%s': %s\n"
+msgstr "chyba při zakládání adresáře „%s“: %s\n"
 
-#~ msgid "ignoring database dir `%s'\n"
-#~ msgstr "adresář databáze „%s“ nebude brán zřetel\n"
+#, c-format
+msgid "ignoring database dir '%s'\n"
+msgstr "adresář databáze „%s“ nebude brán zřetel\n"
 
-#~ msgid "error reading directory `%s': %s\n"
-#~ msgstr "chyba při čtení adresáře „%s“: %s\n"
+#, c-format
+msgid "error reading directory '%s': %s\n"
+msgstr "chyba při čtení adresáře „%s“: %s\n"
 
-#~ msgid "removing cache file `%s'\n"
-#~ msgstr "odstraňuje se soubor keše „%s“\n"
+#, c-format
+msgid "removing cache file '%s'\n"
+msgstr "odstraňuje se soubor keše „%s“\n"
 
-#~ msgid "not removing file `%s'\n"
-#~ msgstr "soubor „%s“ nebude neodstraněn\n"
+#, c-format
+msgid "not removing file '%s'\n"
+msgstr "soubor „%s“ nebude neodstraněn\n"
 
-#~ msgid "error closing cache file: %s\n"
-#~ msgstr "chyba při zavírání souboru keše: %s\n"
+#, c-format
+msgid "error closing cache file: %s\n"
+msgstr "chyba při zavírání souboru keše: %s\n"
 
-#~ msgid "failed to open cache dir file `%s': %s\n"
-#~ msgstr "otevření kešového dir souboru „%s“ selhalo: %s\n"
+#, c-format
+msgid "failed to open cache dir file '%s': %s\n"
+msgstr "otevření kešového dir souboru „%s“ selhalo: %s\n"
 
-#~ msgid "error creating new cache dir file `%s': %s\n"
-#~ msgstr "chyba při vytváření nového kešového dir souboru „%s“: %s\n"
+#, c-format
+msgid "error creating new cache dir file '%s': %s\n"
+msgstr "chyba při vytváření nového kešového dir souboru „%s“: %s\n"
 
-#~ msgid "error writing new cache dir file `%s': %s\n"
-#~ msgstr "chyba při zápisu nového kešového dir souboru „%s: %s\n"
+#, c-format
+msgid "error writing new cache dir file '%s': %s\n"
+msgstr "chyba při zápisu nového kešového dir souboru „%s: %s\n"
 
-#~ msgid "error closing new cache dir file `%s': %s\n"
-#~ msgstr "chyba při uzavírání nového kešového dir souboru „%s“: %s\n"
+#, c-format
+msgid "error closing new cache dir file '%s': %s\n"
+msgstr "chyba při uzavírání nového kešového dir souboru „%s“: %s\n"
 
-#~ msgid "new cache dir file `%s' created\n"
-#~ msgstr "nový kešový dir soubor „%s“ vytvořen\n"
+#, c-format
+msgid "new cache dir file '%s' created\n"
+msgstr "nový kešový dir soubor „%s“ vytvořen\n"
 
-#~ msgid "failed to re-open cache dir file `%s': %s\n"
-#~ msgstr "znovu otevření kešového dir souboru „%s“ selhalo: %s\n"
+#, c-format
+msgid "failed to re-open cache dir file '%s': %s\n"
+msgstr "znovu otevření kešového dir souboru „%s“ selhalo: %s\n"
 
-#~ msgid "first record of `%s' is not the version\n"
-#~ msgstr "první záznam „%s“ není verze\n"
+#, c-format
+msgid "first record of '%s' is not the version\n"
+msgstr "první záznam „%s“ není verze\n"
 
-#~ msgid "old version of cache directory - cleaning up\n"
-#~ msgstr "stará verze adresáře s keší – bude vyčištěna\n"
+msgid "old version of cache directory - cleaning up\n"
+msgstr "stará verze adresáře s keší – bude vyčištěna\n"
 
-#~ msgid "old version of cache directory - giving up\n"
-#~ msgstr "stará verze adresáře s keší – nelze pokračovat\n"
+msgid "old version of cache directory - giving up\n"
+msgstr "stará verze adresáře s keší – nelze pokračovat\n"
 
-#~ msgid "extra field detected in crl record of `%s' line %u\n"
-#~ msgstr "nalezena nadbytečná položka v záznamu CRL „%s“ na řádku %u\n"
+#, c-format
+msgid "extra field detected in crl record of '%s' line %u\n"
+msgstr "nalezena nadbytečná položka v záznamu CRL „%s“ na řádku %u\n"
 
-#~ msgid "invalid line detected in `%s' line %u\n"
-#~ msgstr "nalezen neplatný řádek %2$u v „%1$s\n"
+#, c-format
+msgid "invalid line detected in '%s' line %u\n"
+msgstr "nalezen neplatný řádek %2$u v „%1$s\n"
 
-#~ msgid "duplicate entry detected in `%s' line %u\n"
-#~ msgstr "nalezena duplicitní položka v „%s“ na řádku %u\n"
+#, c-format
+msgid "duplicate entry detected in '%s' line %u\n"
+msgstr "nalezena duplicitní položka v „%s“ na řádku %u\n"
 
-#~ msgid "unsupported record type in `%s' line %u skipped\n"
-#~ msgstr "nepodporovaný typ záznamu v „%s“ na řádku %u přeskočen\n"
+#, c-format
+msgid "unsupported record type in '%s' line %u skipped\n"
+msgstr "nepodporovaný typ záznamu v „%s“ na řádku %u přeskočen\n"
 
-#~ msgid "invalid issuer hash in `%s' line %u\n"
-#~ msgstr "neplatný haš vydavatele v „%s“ na řádku %u\n"
+#, c-format
+msgid "invalid issuer hash in '%s' line %u\n"
+msgstr "neplatný haš vydavatele v „%s“ na řádku %u\n"
 
-#~ msgid "no issuer DN in `%s' line %u\n"
-#~ msgstr "v „%s“ na řádku %u chybí DN vydavatele\n"
+#, c-format
+msgid "no issuer DN in '%s' line %u\n"
+msgstr "v „%s“ na řádku %u chybí DN vydavatele\n"
 
-#~ msgid "invalid timestamp in `%s' line %u\n"
-#~ msgstr "neplatné časové razítko v „%s“ na řádku %u\n"
+#, c-format
+msgid "invalid timestamp in '%s' line %u\n"
+msgstr "neplatné časové razítko v „%s“ na řádku %u\n"
 
-#~ msgid "WARNING: invalid cache file hash in `%s' line %u\n"
-#~ msgstr "POZOR: neplatný haš souboru keše v „%s“ na řádku %u\n"
+#, c-format
+msgid "WARNING: invalid cache file hash in '%s' line %u\n"
+msgstr "POZOR: neplatný haš souboru keše v „%s“ na řádku %u\n"
 
-#~ msgid "detected errors in cache dir file\n"
-#~ msgstr "v kešovém dir souboru nalezeny chyby\n"
+msgid "detected errors in cache dir file\n"
+msgstr "v kešovém dir souboru nalezeny chyby\n"
 
-#~ msgid "please check the reason and manually delete that file\n"
-#~ msgstr "prosím, zjistěte příčinu a soubor ručně smažte\n"
+msgid "please check the reason and manually delete that file\n"
+msgstr "prosím, zjistěte příčinu a soubor ručně smažte\n"
 
-#~ msgid "failed to create temporary cache dir file `%s': %s\n"
-#~ msgstr "založení dočasného kešového dir souboru „%s“ selhalo: %s\n"
+#, c-format
+msgid "failed to create temporary cache dir file '%s': %s\n"
+msgstr "založení dočasného kešového dir souboru „%s“ selhalo: %s\n"
 
-#~ msgid "error closing `%s': %s\n"
-#~ msgstr "chyba při uzavírání „%s“: %s\n"
+#, c-format
+msgid "error closing '%s': %s\n"
+msgstr "chyba při uzavírání „%s“: %s\n"
 
-#~ msgid "error renaming `%s' to `%s': %s\n"
-#~ msgstr "chyba při přejmenování „%s“ na „%s“: %s\n"
+#, c-format
+msgid "error renaming '%s' to '%s': %s\n"
+msgstr "chyba při přejmenování „%s“ na „%s“: %s\n"
 
-#~ msgid "can't hash `%s': %s\n"
-#~ msgstr "nelze vypočítat haš „%s“: %s\n"
+#, c-format
+msgid "can't hash '%s': %s\n"
+msgstr "nelze vypočítat haš „%s“: %s\n"
 
-#~ msgid "error setting up MD5 hash context: %s\n"
-#~ msgstr "chyba při nastavování hašovacího kontextu MD5: %s\n"
+#, c-format
+msgid "error setting up MD5 hash context: %s\n"
+msgstr "chyba při nastavování hašovacího kontextu MD5: %s\n"
 
-#~ msgid "error hashing `%s': %s\n"
-#~ msgstr "chyba při výpočtu haše „%s“: %s\n"
+#, c-format
+msgid "error hashing '%s': %s\n"
+msgstr "chyba při výpočtu haše „%s“: %s\n"
 
-#~ msgid "invalid formatted checksum for `%s'\n"
-#~ msgstr "chybně zformátovaný kontrolní součet souboru „%s“\n"
+#, c-format
+msgid "invalid formatted checksum for '%s'\n"
+msgstr "chybně zformátovaný kontrolní součet souboru „%s“\n"
 
-#~ msgid "too many open cache files; can't open anymore\n"
-#~ msgstr "otevřeno příliš mnoho kešových souborů, další již nelze otevřít\n"
+msgid "too many open cache files; can't open anymore\n"
+msgstr "otevřeno příliš mnoho kešových souborů, další již nelze otevřít\n"
 
-#~ msgid "opening cache file `%s'\n"
-#~ msgstr "otevírá se kešový soubor „%s“\n"
+#, c-format
+msgid "opening cache file '%s'\n"
+msgstr "otevírá se kešový soubor „%s“\n"
 
-#~ msgid "error opening cache file `%s': %s\n"
-#~ msgstr "chyba při otevírání kešového souboru „%s“: %s\n"
+#, c-format
+msgid "error opening cache file '%s': %s\n"
+msgstr "chyba při otevírání kešového souboru „%s“: %s\n"
 
-#~ msgid "error initializing cache file `%s' for reading: %s\n"
-#~ msgstr "chyba při inicializaci kešového souboru „%s pro čtení: %s\n"
+#, c-format
+msgid "error initializing cache file '%s' for reading: %s\n"
+msgstr "chyba při inicializaci kešového souboru „%s pro čtení: %s\n"
 
-#~ msgid "calling unlock_db_file on a closed file\n"
-#~ msgstr "unlock_db_file zavoláno na zavřený soubor\n"
+msgid "calling unlock_db_file on a closed file\n"
+msgstr "unlock_db_file zavoláno na zavřený soubor\n"
 
-#~ msgid "calling unlock_db_file on an unlocked file\n"
-#~ msgstr "unlock_db_file zavoláno na nezamčeném souboru\n"
+msgid "calling unlock_db_file on an unlocked file\n"
+msgstr "unlock_db_file zavoláno na nezamčeném souboru\n"
 
-#~ msgid "failed to create a new cache object: %s\n"
-#~ msgstr "výroba nového objektu keše selhala: %s\n"
+#, c-format
+msgid "failed to create a new cache object: %s\n"
+msgstr "výroba nového objektu keše selhala: %s\n"
 
-#~ msgid "no CRL available for issuer id %s\n"
-#~ msgstr "pro vydavatele s ID %s není dostupný žádný CRL\n"
+#, c-format
+msgid "no CRL available for issuer id %s\n"
+msgstr "pro vydavatele s ID %s není dostupný žádný CRL\n"
 
-#~ msgid "cached CRL for issuer id %s too old; update required\n"
-#~ msgstr ""
-#~ "nakešovaný CRL pro vydavatele s ID %s příliš starý; aktualizace "
-#~ "vyžadována\n"
+#, c-format
+msgid "cached CRL for issuer id %s too old; update required\n"
+msgstr ""
+"nakešovaný CRL pro vydavatele s ID %s příliš starý; aktualizace vyžadována\n"
 
 # TODO: plural
-#~ msgid ""
-#~ "force-crl-refresh active and %d minutes passed for issuer id %s; update "
-#~ "required\n"
-#~ msgstr ""
-#~ "force-crl-refresh je aktivováno a %d minut uplynulo vydavateli s ID %s, "
-#~ "aktualizace je požadována\n"
+#, c-format
+msgid ""
+"force-crl-refresh active and %d minutes passed for issuer id %s; update "
+"required\n"
+msgstr ""
+"force-crl-refresh je aktivováno a %d minut uplynulo vydavateli s ID %s, "
+"aktualizace je požadována\n"
 
-#~ msgid "force-crl-refresh active for issuer id %s; update required\n"
-#~ msgstr ""
-#~ "force-crl-required je u vydavatele s ID %s aktivováno, aktualizace je "
-#~ "požadována\n"
+#, c-format
+msgid "force-crl-refresh active for issuer id %s; update required\n"
+msgstr ""
+"force-crl-required je u vydavatele s ID %s aktivováno, aktualizace je "
+"požadována\n"
 
 # CRL for issuer překládat jako CRL pro vydavatele, prože CRL může mít jiného
 # vydavatele než je vydavatel odvolaných certifikátů (tzv. indirect CRL)
-#~ msgid "available CRL for issuer ID %s can't be used\n"
-#~ msgstr "dostupný CRL pro vydavatele ID %s nemůže být použit\n"
+#, c-format
+msgid "available CRL for issuer ID %s can't be used\n"
+msgstr "dostupný CRL pro vydavatele ID %s nemůže být použit\n"
 
-#~ msgid "cached CRL for issuer id %s tampered; we need to update\n"
-#~ msgstr ""
-#~ "nakešovaný CRL pro vydavatele ID %s je pozměněný, je třeba jej "
-#~ "aktualizovat\n"
+#, c-format
+msgid "cached CRL for issuer id %s tampered; we need to update\n"
+msgstr ""
+"nakešovaný CRL pro vydavatele ID %s je pozměněný, je třeba jej aktualizovat\n"
 
 # XXX: The message is followed by the serial number
 # TODO: Use c-format
-#~ msgid "WARNING: invalid cache record length for S/N "
-#~ msgstr "POZOR: neplatná délka záznamu v keši pod sériovým číslem "
+msgid "WARNING: invalid cache record length for S/N "
+msgstr "POZOR: neplatná délka záznamu v keši pod sériovým číslem "
 
-#~ msgid "problem reading cache record for S/N %s: %s\n"
-#~ msgstr "problém se čtením záznamu keše pro sériové číslo %s: %s\n"
+#, c-format
+msgid "problem reading cache record for S/N %s: %s\n"
+msgstr "problém se čtením záznamu keše pro sériové číslo %s: %s\n"
 
-#~ msgid "S/N %s is not valid; reason=%02X  date=%.15s\n"
-#~ msgstr "sériové číslo %s není platné, důvod=%02X  datum=%.15s\n"
+#, c-format
+msgid "S/N %s is not valid; reason=%02X  date=%.15s\n"
+msgstr "Sériové číslo %s není platné, důvod=%02X  datum=%.15s\n"
 
-#~ msgid "S/N %s is valid, it is not listed in the CRL\n"
-#~ msgstr "sériové číslo %s je platné, není na seznamu CRL\n"
+#, c-format
+msgid "S/N %s is valid, it is not listed in the CRL\n"
+msgstr "Sériové číslo %s je platné, není na seznamu CRL\n"
 
-#~ msgid "error getting data from cache file: %s\n"
-#~ msgstr "chyba při získávání dat ze souboru keše: %s\n"
+#, c-format
+msgid "error getting data from cache file: %s\n"
+msgstr "chyba při získávání dat ze souboru keše: %s\n"
 
-#~ msgid "unknown hash algorithm `%s'\n"
-#~ msgstr "neznámý hašovací algoritmus „%s“\n"
+#, c-format
+msgid "unknown hash algorithm '%s'\n"
+msgstr "neznámý hašovací algoritmus „%s“\n"
 
-#~ msgid "gcry_md_open for algorithm %d failed: %s\n"
-#~ msgstr "gcry_md_open selhalo na algoritmu %d: %s\n"
+#, c-format
+msgid "gcry_md_open for algorithm %d failed: %s\n"
+msgstr "gcry_md_open selhalo na algoritmu %d: %s\n"
 
-#~ msgid "got an invalid S-expression from libksba\n"
-#~ msgstr "z libksba obdržen neplatný S-výraz\n"
+msgid "got an invalid S-expression from libksba\n"
+msgstr "z libksba obdržen neplatný S-výraz\n"
 
-#~ msgid "converting S-expression failed: %s\n"
-#~ msgstr "převod S-výrazu se nezdařil: %s\n"
+#, c-format
+msgid "converting S-expression failed: %s\n"
+msgstr "převod S-výrazu se nezdařil: %s\n"
 
-#~ msgid "creating S-expression failed: %s\n"
-#~ msgstr "výroba S-výrazu selhala: %s\n"
+#, c-format
+msgid "creating S-expression failed: %s\n"
+msgstr "výroba S-výrazu selhala: %s\n"
 
-#~ msgid "ksba_crl_parse failed: %s\n"
-#~ msgstr "ksba_crl_parse selhal: %s\n"
+#, c-format
+msgid "ksba_crl_parse failed: %s\n"
+msgstr "ksba_crl_parse selhal: %s\n"
 
-#~ msgid "error getting update times of CRL: %s\n"
-#~ msgstr "chyba při zjišťování časů aktualizace CRL %s\n"
+#, c-format
+msgid "error getting update times of CRL: %s\n"
+msgstr "chyba při zjišťování časů aktualizace CRL %s\n"
 
-#~ msgid "update times of this CRL: this=%s next=%s\n"
-#~ msgstr "časy aktualizace tohoto CRL: tento=%s příští=%s\n"
+#, c-format
+msgid "update times of this CRL: this=%s next=%s\n"
+msgstr "časy aktualizace tohoto CRL: tento=%s příští=%s\n"
 
-#~ msgid "nextUpdate not given; assuming a validity period of one day\n"
-#~ msgstr ""
-#~ "nextUpdate neuvedeno, předpokládaná perioda platnosti bude jeden den\n"
+msgid "nextUpdate not given; assuming a validity period of one day\n"
+msgstr "nextUpdate neuvedeno, předpokládaná perioda platnosti bude jeden den\n"
 
-#~ msgid "error getting CRL item: %s\n"
-#~ msgstr "chyba při získávání položky CRL: %s\n"
+#, c-format
+msgid "error getting CRL item: %s\n"
+msgstr "chyba při získávání položky CRL: %s\n"
 
-#~ msgid "error inserting item into temporary cache file: %s\n"
-#~ msgstr "chyba vkládání položky do dočasného souboru keše: %s\n"
+#, c-format
+msgid "error inserting item into temporary cache file: %s\n"
+msgstr "chyba vkládání položky do dočasného souboru keše: %s\n"
 
-#~ msgid "no CRL issuer found in CRL: %s\n"
-#~ msgstr "v CRL nebyl nalezen žádný vydavatel CRL: %s\n"
+#, c-format
+msgid "no CRL issuer found in CRL: %s\n"
+msgstr "v CRL nebyl nalezen žádný vydavatel CRL: %s\n"
 
-#~ msgid "locating CRL issuer certificate by authorityKeyIdentifier\n"
-#~ msgstr ""
-#~ "certifikát vydavatele CRL bude hledán podle authorityKeyIdentifier\n"
+msgid "locating CRL issuer certificate by authorityKeyIdentifier\n"
+msgstr "certifikát vydavatele CRL bude hledán podle authorityKeyIdentifier\n"
 
-#~ msgid "CRL signature verification failed: %s\n"
-#~ msgstr "ověřování podpisu CRL selhalo: %s\n"
+#, c-format
+msgid "CRL signature verification failed: %s\n"
+msgstr "ověřování podpisu CRL selhalo: %s\n"
 
-#~ msgid "error checking validity of CRL issuer certificate: %s\n"
-#~ msgstr "chyba při kontrole platnosti certifikátu vydavatele CRL: %s\n"
+#, c-format
+msgid "error checking validity of CRL issuer certificate: %s\n"
+msgstr "chyba při kontrole platnosti certifikátu vydavatele CRL: %s\n"
 
-#~ msgid "ksba_crl_new failed: %s\n"
-#~ msgstr "volání ksba_crl_new selhalo: %s\n"
+#, c-format
+msgid "ksba_crl_new failed: %s\n"
+msgstr "volání ksba_crl_new selhalo: %s\n"
 
-#~ msgid "ksba_crl_set_reader failed: %s\n"
-#~ msgstr "volání ksba_crl_set_reader selhalo: %s\n"
+#, c-format
+msgid "ksba_crl_set_reader failed: %s\n"
+msgstr "volání ksba_crl_set_reader selhalo: %s\n"
 
-#~ msgid "removed stale temporary cache file `%s'\n"
-#~ msgstr "odstraněn zastaralý dočasný soubor keše „%s“\n"
+#, c-format
+msgid "removed stale temporary cache file '%s'\n"
+msgstr "odstraněn zastaralý dočasný soubor keše „%s“\n"
 
-#~ msgid "problem removing stale temporary cache file `%s': %s\n"
-#~ msgstr ""
-#~ "problém s odstraňováním zastaralého dočasného souboru keše „%s“: %s\n"
+#, c-format
+msgid "problem removing stale temporary cache file '%s': %s\n"
+msgstr "problém s odstraňováním zastaralého dočasného souboru keše „%s“: %s\n"
 
-#~ msgid "error creating temporary cache file `%s': %s\n"
-#~ msgstr "chyba při zakládání dočasného souboru keše „%s“: %s\n"
+#, c-format
+msgid "error creating temporary cache file '%s': %s\n"
+msgstr "chyba při zakládání dočasného souboru keše „%s“: %s\n"
 
-#~ msgid "crl_parse_insert failed: %s\n"
-#~ msgstr "volání crl_parse_insert selhalo: %s\n"
+#, c-format
+msgid "crl_parse_insert failed: %s\n"
+msgstr "volání crl_parse_insert selhalo: %s\n"
 
-#~ msgid "error finishing temporary cache file `%s': %s\n"
-#~ msgstr "chyba při dokončování dočasného souboru keše „%s“: %s\n"
+#, c-format
+msgid "error finishing temporary cache file '%s': %s\n"
+msgstr "chyba při dokončování dočasného souboru keše „%s“: %s\n"
 
-#~ msgid "error closing temporary cache file `%s': %s\n"
-#~ msgstr "chyba při uzavírání dočasného souboru keše „%s“: %s\n"
+#, c-format
+msgid "error closing temporary cache file '%s': %s\n"
+msgstr "chyba při uzavírání dočasného souboru keše „%s“: %s\n"
 
-#~ msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n"
-#~ msgstr ""
-#~ "POZOR: nový CRL je stále příliš starý; jeho platnost vypršela %s – stejně "
-#~ "bude nahrán\n"
+#, c-format
+msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n"
+msgstr ""
+"POZOR: nový CRL je stále příliš starý; jeho platnost vypršela %s – stejně "
+"bude nahrán\n"
 
-#~ msgid "new CRL still too old; it expired on %s\n"
-#~ msgstr "nový CRL je stále příliš starý; jeho platnost vypršela %s\n"
+#, c-format
+msgid "new CRL still too old; it expired on %s\n"
+msgstr "nový CRL je stále příliš starý; jeho platnost vypršela %s\n"
 
-#~ msgid "unknown critical CRL extension %s\n"
-#~ msgstr "neznámé kritické rozšíření CRL %s\n"
+#, c-format
+msgid "unknown critical CRL extension %s\n"
+msgstr "neznámé kritické rozšíření CRL %s\n"
 
-#~ msgid "error reading CRL extensions: %s\n"
-#~ msgstr "chyba při čtení rozšíření CRL: %s\n"
+#, c-format
+msgid "error reading CRL extensions: %s\n"
+msgstr "chyba při čtení rozšíření CRL: %s\n"
 
-#~ msgid "creating cache file `%s'\n"
-#~ msgstr "vytváří se soubor keše „%s“\n"
+#, c-format
+msgid "creating cache file '%s'\n"
+msgstr "vytváří se soubor s keší „%s“\n"
 
-#~ msgid "problem renaming `%s' to `%s': %s\n"
-#~ msgstr "problém s přejmenováním „%s“ na „%s“: %s\n"
+#, c-format
+msgid "problem renaming '%s' to '%s': %s\n"
+msgstr "problém s přejmenováním „%s“ na „%s“: %s\n"
 
-#~ msgid ""
-#~ "updating the DIR file failed - cache entry will get lost with the next "
-#~ "program start\n"
-#~ msgstr ""
-#~ "aktualizace souboru DIR selhalo – záznam keše bude při příštím startu "
-#~ "programu ztracen\n"
+msgid ""
+"updating the DIR file failed - cache entry will get lost with the next "
+"program start\n"
+msgstr ""
+"aktualizace souboru DIR selhalo – záznam keše bude při příštím startu "
+"programu ztracen\n"
 
-#~ msgid "Begin CRL dump (retrieved via %s)\n"
-#~ msgstr "Zahajuje se výpis CRL (získán přes %s)\n"
+#, c-format
+msgid "Begin CRL dump (retrieved via %s)\n"
+msgstr "Zahajuje se výpis CRL (získán přes %s)\n"
 
-#~ msgid ""
-#~ " ERROR: The CRL will not be used because it was still too old after an "
-#~ "update!\n"
-#~ msgstr ""
-#~ " CHYBA: CRL nebude použit, protože i po aktualizaci byl příliš starý!\n"
+#, c-format
+msgid ""
+" ERROR: The CRL will not be used because it was still too old after an "
+"update!\n"
+msgstr ""
+" CHYBA: CRL nebude použit, protože i po aktualizaci byl příliš starý!\n"
 
-#~ msgid ""
-#~ " ERROR: The CRL will not be used due to an unknown critical extension!\n"
-#~ msgstr " CHYBA: CRL nebude použit kvůli neznámému kritickému rozšíření!\n"
+#, c-format
+msgid ""
+" ERROR: The CRL will not be used due to an unknown critical extension!\n"
+msgstr " CHYBA: CRL nebude použit kvůli neznámému kritickému rozšíření!\n"
+
+#, c-format
+msgid " ERROR: The CRL will not be used\n"
+msgstr " CHYBA: CRL nebude použit\n"
 
-#~ msgid " ERROR: The CRL will not be used\n"
-#~ msgstr " CHYBA: CRL nebude použit\n"
+#, c-format
+msgid " ERROR: This cached CRL may has been tampered with!\n"
+msgstr " CHYBA: Tento nakešovaný CRL byl možná pozměněn!\n"
 
-#~ msgid " ERROR: This cached CRL may has been tampered with!\n"
-#~ msgstr " CHYBA: Tento nakešovaný CRL byl možná pozměněn!\n"
+msgid " WARNING: invalid cache record length\n"
+msgstr " POZOR: neplatná délka záznamu keše\n"
 
-#~ msgid " WARNING: invalid cache record length\n"
-#~ msgstr " POZOR: neplatná délka záznamu keše\n"
+#, c-format
+msgid "problem reading cache record: %s\n"
+msgstr "problém se čtením záznamu keše: %s\n"
 
-#~ msgid "problem reading cache record: %s\n"
-#~ msgstr "problém se čtením záznamu keše: %s\n"
+#, c-format
+msgid "problem reading cache key: %s\n"
+msgstr "problém se čtením klíče keše: %s\n"
 
-#~ msgid "problem reading cache key: %s\n"
-#~ msgstr "problém se čtením klíče keše: %s\n"
+#, c-format
+msgid "error reading cache entry from db: %s\n"
+msgstr "chyba při čtení položky keše z databáze: %s\n"
 
-#~ msgid "error reading cache entry from db: %s\n"
-#~ msgstr "chyba při čtení položky keše z databáze: %s\n"
+#, c-format
+msgid "End CRL dump\n"
+msgstr "Konec výpisu CRL\n"
 
-#~ msgid "End CRL dump\n"
-#~ msgstr "Konec výpisu CRL\n"
+#, c-format
+msgid "error initializing reader object: %s\n"
+msgstr "chyba při inicializaci čtecího objektu: %s\n"
 
-#~ msgid "crl_fetch via DP failed: %s\n"
-#~ msgstr "volání crl_fetch přes DP selhalo: %s\n"
+#, c-format
+msgid "crl_fetch via DP failed: %s\n"
+msgstr "volání crl_fetch přes DP selhalo: %s\n"
 
-#~ msgid "crl_cache_insert via DP failed: %s\n"
-#~ msgstr "volání crl_cache_insert přes DP selhalo: %s\n"
+#, c-format
+msgid "crl_cache_insert via DP failed: %s\n"
+msgstr "volání crl_cache_insert přes DP selhalo: %s\n"
 
-#~ msgid "crl_cache_insert via issuer failed: %s\n"
-#~ msgstr "volání crl_cache_insert přes vydavatele selhalo: %s\n"
+#, c-format
+msgid "crl_cache_insert via issuer failed: %s\n"
+msgstr "volání crl_cache_insert přes vydavatele selhalo: %s\n"
 
-#~ msgid "reader to file mapping table full - waiting\n"
-#~ msgstr "tabulka mapování čtenáře na soubor je plná – čeká se\n"
+msgid "reader to file mapping table full - waiting\n"
+msgstr "tabulka mapování čtenáře na soubor je plná – čeká se\n"
 
-#~ msgid "using \"http\" instead of \"https\"\n"
-#~ msgstr "namísto „https“ se použije „http“\n"
+msgid "using \"http\" instead of \"https\"\n"
+msgstr "namísto „https“ se použije „http“\n"
 
 # Poslední argument je název protokolu
-#~ msgid "CRL access not possible due to disabled %s\n"
-#~ msgstr "Přístup k CRL není možný kvůli vypnutému %s\n"
+#, c-format
+msgid "CRL access not possible due to disabled %s\n"
+msgstr "Přístup k CRL není možný kvůli vypnutému %s\n"
 
-#~ msgid "error initializing reader object: %s\n"
-#~ msgstr "chyba při inicializaci čtecího objektu: %s\n"
+#, c-format
+msgid "URL '%s' redirected to '%s' (%u)\n"
+msgstr "URL „%s“ přesměrováno na „%s“ (%u)\n"
 
-#~ msgid "URL `%s' redirected to `%s' (%u)\n"
-#~ msgstr "URL „%s“ přesměrováno na „%s“ (%u)\n"
+msgid "too many redirections\n"
+msgstr "příliš mnoho přesměrování\n"
 
-#~ msgid "too many redirections\n"
-#~ msgstr "příliš mnoho přesměrování\n"
+#, c-format
+msgid "error retrieving '%s': %s\n"
+msgstr "chyba při získávání „%s“: %s\n"
 
-#~ msgid "error retrieving `%s': %s\n"
-#~ msgstr "chyba při získávání „%s“: %s\n"
+#, c-format
+msgid "error retrieving '%s': http status %u\n"
+msgstr "chyba při získávání „%s“: status HTTP je %u\n"
 
-#~ msgid "error retrieving `%s': http status %u\n"
-#~ msgstr "chyba při získávání „%s“: status HTTP je %u\n"
+#, c-format
+msgid "certificate search not possible due to disabled %s\n"
+msgstr "dohledání certifikátu nemožné kvůli vypnutému %s\n"
 
-#~ msgid "certificate search not possible due to disabled %s\n"
-#~ msgstr "dohledání certifikátu nemožné kvůli vypnutému %s\n"
+msgid "run as windows service (background)"
+msgstr "poběží jako služba Windows (na pozadí)"
 
-#~ msgid "use OCSP instead of CRLs"
-#~ msgstr "místo CRL použije OCSP"
+msgid "list the contents of the CRL cache"
+msgstr "vypíše obsah CRL keše"
 
-#~ msgid "check whether a dirmngr is running"
-#~ msgstr "zjistí, jestli dirmngr běží"
+msgid "|FILE|load CRL from FILE into cache"
+msgstr "|SOUBOR|zavede CRL ze SOUBORU do keše"
 
-#~ msgid "add a certificate to the cache"
-#~ msgstr "přidá certifikát do keše"
+msgid "|URL|fetch a CRL from URL"
+msgstr "|URL|stáhne CRL z URL"
 
-#~ msgid "validate a certificate"
-#~ msgstr "ověří platnost certifikátu"
+msgid "shutdown the dirmngr"
+msgstr "vypne dirmngr"
 
-#~ msgid "lookup a certificate"
-#~ msgstr "vyhledá certifikát"
+msgid "flush the cache"
+msgstr "vyprázdní keš"
 
-#~ msgid "lookup only locally stored certificates"
-#~ msgstr "hledá pouze mezi lokálně uloženými certifikáty"
+msgid "run without asking a user"
+msgstr "běží bez dotazování se uživatele"
 
-#~ msgid "expect an URL for --lookup"
-#~ msgstr "u --lookup očekává URL"
+msgid "force loading of outdated CRLs"
+msgstr "vynutí zavedení zastaralých CRL"
 
-#~ msgid "load a CRL into the dirmngr"
-#~ msgstr "zavede CRL do dirmngr"
+msgid "allow sending OCSP requests"
+msgstr "povolí odesílání OCSP dotazů"
 
-#~ msgid "special mode for use by Squid"
-#~ msgstr "zvláštní režim pro použití se Squidem"
+msgid "inhibit the use of HTTP"
+msgstr "zakáže použití HTTP"
 
-#~ msgid "certificates are expected in PEM format"
-#~ msgstr "certifikáty budou očekávány ve formátu PEM"
+msgid "inhibit the use of LDAP"
+msgstr "zakáže použití LDAP"
 
-#~ msgid "force the use of the default OCSP responder"
-#~ msgstr "vynutí použití výchozího OCSP odpovídače"
+msgid "ignore HTTP CRL distribution points"
+msgstr "ignoruje HTTP distribuční místa CRL "
 
-#~ msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n"
-#~ msgstr ""
-#~ "Použití: dirmngr-client [VOLBY] [CERT_SOUBOR|VZOR] (-h pro nápovědu)\n"
+msgid "ignore LDAP CRL distribution points"
+msgstr "ignoruje LDAP distribuční místa CRL"
 
-#~ msgid ""
-#~ "Syntax: dirmngr-client [options] [certfile|pattern]\n"
-#~ "Test an X.509 certificate against a CRL or do an OCSP check\n"
-#~ "The process returns 0 if the certificate is valid, 1 if it is\n"
-#~ "not valid and other error codes for general failures\n"
-#~ msgstr ""
-#~ "Syntaxe: dirmngr-client [VOLBY] [CERT_SOUBOR|VZOR]\n"
-#~ "Vyzkouší X.509 certifikát proti CRL nebo OCSP.\n"
-#~ "Proces vrátí 0, pokud je certifikát platný, 1, pokud není platný nebo "
-#~ "jiný\n"
-#~ "chybový kód značící obecné selhání.\n"
+msgid "ignore certificate contained OCSP service URLs"
+msgstr "ignoruje URL služby OCSP uvedené v certifikátu"
 
-#~ msgid "error reading certificate from stdin: %s\n"
-#~ msgstr "chyba při čtení certifikátu ze standardního vstupu: %s\n"
+msgid "|URL|redirect all HTTP requests to URL"
+msgstr "|URL|všechny HTTP požadavky přesměruje na URL"
 
-#~ msgid "error reading certificate from `%s': %s\n"
-#~ msgstr "chyba při čtení certifikátu ze „%s“: %s\n"
+msgid "|HOST|use HOST for LDAP queries"
+msgstr "|STROJ|pro LDAP dotazy použije STROJ"
 
-#~ msgid "certificate too large to make any sense\n"
-#~ msgstr "certifikát je příliš velký, než aby dával smysl\n"
+msgid "do not use fallback hosts with --ldap-proxy"
+msgstr "nepoužije náhradní stroje s --ldap-proxy"
 
-#~ msgid "lookup failed: %s\n"
-#~ msgstr "hledání selhalo: %s\n"
+msgid "|FILE|read LDAP server list from FILE"
+msgstr "|SOUBOR|načte seznam LDAP serverů ze SOUBORU"
 
-#~ msgid "loading CRL `%s' failed: %s\n"
-#~ msgstr "zavádění CRL „%s“ selhalo: %s\n"
+msgid "add new servers discovered in CRL distribution points to serverlist"
+msgstr "na seznam serverů přidá nové servery nalezené v místech distribuce CRL"
 
-#~ msgid "a dirmngr daemon is up and running\n"
-#~ msgstr "démon dirmngr běží\n"
+msgid "|N|set LDAP timeout to N seconds"
+msgstr "|N|nastaví časový limit pro LDAP na N sekund"
 
-#~ msgid "validation of certificate failed: %s\n"
-#~ msgstr "ověření platnosti certifikátu selhalo: %s\n"
+msgid "|URL|use OCSP responder at URL"
+msgstr "|URL|použije OCSP odpovídače na URL"
 
-#~ msgid "certificate is valid\n"
-#~ msgstr "certifikát je platný\n"
+msgid "|FPR|OCSP response signed by FPR"
+msgstr "|OTISK|OCSP odpovědi podepsané podle OTISKU"
 
-#~ msgid "certificate has been revoked\n"
-#~ msgstr "certifikát byl odvolán\n"
+msgid "|N|do not return more than N items in one query"
+msgstr "|N|nevrací více jak N položek na jeden dotaz"
 
-#~ msgid "certificate check failed: %s\n"
-#~ msgstr "kontrola certifikátu selhala: %s\n"
+msgid "|FILE|listen on socket FILE"
+msgstr "|SOUBOR|poslouchá ne socketu SOUBOR"
 
-#~ msgid "got status: `%s'\n"
-#~ msgstr "obdržen status: „%s“\n"
+msgid ""
+"@\n"
+"(See the \"info\" manual for a complete listing of all commands and "
+"options)\n"
+msgstr ""
+"@\n"
+"(Úplný seznam příkazů a voleb naleznete v „info“ manuálu.)\n"
 
-#~ msgid "error writing base64 encoding: %s\n"
-#~ msgstr "chyba při zápisu kódování base64: %s\n"
+msgid "Usage: dirmngr [options] (-h for help)"
+msgstr "Použití: dirmngr [VOLBY] (-h pro nápovědu)"
 
-#~ msgid "failed to allocate assuan context: %s\n"
-#~ msgstr "alokace kontextu assuan selhala: %s\n"
+msgid ""
+"Syntax: dirmngr [options] [command [args]]\n"
+"LDAP and OCSP access for GnuPG\n"
+msgstr ""
+"Syntaxe: dirmngr [VOLBY] [PŘÍKAZ [ARGUMENTY]]\n"
+"LDAP a OCSP přístup z GnuPG\n"
 
-#~ msgid "apparently no running dirmngr\n"
-#~ msgstr "dirmngr zjevně neběží\n"
+#, c-format
+msgid "valid debug levels are: %s\n"
+msgstr "platné úrovně ladění jsou: %s\n"
 
-#~ msgid "no running dirmngr - starting one\n"
-#~ msgstr "žádný dirmngr neběží – jeden bude spuštěn\n"
+msgid "usage: dirmngr [options] "
+msgstr "použití: dirmngr [VOLBY] "
 
-#~ msgid "can't connect to the dirmngr: %s\n"
-#~ msgstr "k dirmngr se nelze připojit: %s\n"
+#, c-format
+msgid "error spawning ldap wrapper reaper thread: %s\n"
+msgstr "chyba při zakládání vlákna ovládajícího obálku LDAPu: %s\n"
 
-#~ msgid "unsupported inquiry `%s'\n"
-#~ msgstr "nepodporovaný dotaz „%s“\n"
+#, c-format
+msgid "WARNING: running with faked system time %s\n"
+msgstr "POZOR: provoz s podvrženým systémovým časem %s\n"
 
-#~ msgid "absolute file name expected\n"
-#~ msgstr "očekáván absolutní název souboru\n"
+msgid "colons are not allowed in the socket name\n"
+msgstr "dvojtečky v názvu socketu jsou nepřípustné\n"
 
-#~ msgid "looking up `%s'\n"
-#~ msgstr "hledá se „%s“\n"
+#, c-format
+msgid "fork failed: %s\n"
+msgstr "volání fork() selhalo: %s\n"
 
-#~ msgid "run as windows service (background)"
-#~ msgstr "poběží jako služba Windows (na pozadí)"
+#, c-format
+msgid "setsid() failed: %s\n"
+msgstr "volání setsid() selhalo: %s\n"
 
-#~ msgid "list the contents of the CRL cache"
-#~ msgstr "vypíše obsah CRL keše"
+#, c-format
+msgid "chdir to / failed: %s\n"
+msgstr "změna pracovního adresáře na / se nezdařila: %s\n"
 
-#~ msgid "|FILE|load CRL from FILE into cache"
-#~ msgstr "|SOUBOR|zavede CRL ze SOUBORU do keše"
+#, c-format
+msgid "fetching CRL from '%s' failed: %s\n"
+msgstr "stahování CRL z „%s„ selhalo: %s\n"
 
-#~ msgid "|URL|fetch a CRL from URL"
-#~ msgstr "|URL|stáhne CRL z URL"
+#, c-format
+msgid "processing CRL from '%s' failed: %s\n"
+msgstr "zpracování CRL z „%s“ selhalo: %s\n"
 
-#~ msgid "shutdown the dirmngr"
-#~ msgstr "vypne dirmngr"
+#, c-format
+msgid "%s:%u: line too long - skipped\n"
+msgstr "%s:%u: řádek je příliš dlouhý – přeskočen\n"
 
-#~ msgid "flush the cache"
-#~ msgstr "vyprázdní keš"
+#, c-format
+msgid "%s:%u: invalid fingerprint detected\n"
+msgstr "%s:%u: zjištěn neplatný otisk\n"
 
-#~ msgid "run without asking a user"
-#~ msgstr "běží bez dotazování se uživatele"
+#, c-format
+msgid "%s:%u: read error: %s\n"
+msgstr "%s:%u: chyba čtení: %s\n"
 
-#~ msgid "force loading of outdated CRLs"
-#~ msgstr "vynutí zavedení zastaralých CRL"
+#, c-format
+msgid "%s:%u: garbage at end of line ignored\n"
+msgstr "%s:%u: nepořádek na konci řádku ignorován\n"
 
-#~ msgid "allow sending OCSP requests"
-#~ msgstr "povolí odesílání OCSP dotazů"
+msgid "SIGHUP received - re-reading configuration and flushing caches\n"
+msgstr "přijat SIGHUP – konfigurace bude znovu načtena a keš vyprázdněna\n"
 
-#~ msgid "inhibit the use of HTTP"
-#~ msgstr "zakáže použití HTTP"
+msgid "SIGUSR2 received - no action defined\n"
+msgstr "přijat SIGUSR2 – žádná akce nedefinována\n"
 
-#~ msgid "inhibit the use of LDAP"
-#~ msgstr "zakáže použití LDAP"
+msgid "SIGTERM received - shutting down ...\n"
+msgstr "přijat SIGTERM – vypíná se…\n"
 
-#~ msgid "ignore HTTP CRL distribution points"
-#~ msgstr "ignoruje HTTP distribuční místa CRL "
+# TODO: plural
+#, c-format
+msgid "SIGTERM received - still %d active connections\n"
+msgstr "přijat SIGTERM – stále aktivních spojení: %d\n"
 
-#~ msgid "ignore LDAP CRL distribution points"
-#~ msgstr "ignoruje LDAP distribuční místa CRL"
+msgid "shutdown forced\n"
+msgstr "vypnutí vynuceno\n"
 
-#~ msgid "ignore certificate contained OCSP service URLs"
-#~ msgstr "ignoruje URL služby OCSP uvedené v certifikátu"
+msgid "SIGINT received - immediate shutdown\n"
+msgstr "přijat SIGINT – okamžité vypnutí\n"
 
-#~ msgid "|URL|redirect all HTTP requests to URL"
-#~ msgstr "|URL|všechny HTTP požadavky přesměruje na URL"
+#, c-format
+msgid "signal %d received - no action defined\n"
+msgstr "přijat signál č. %d – žádná akce nedefinována\n"
 
-#~ msgid "|HOST|use HOST for LDAP queries"
-#~ msgstr "|STROJ|pro LDAP dotazy použije STROJ"
+#, c-format
+msgid "accept failed: %s - waiting 1s\n"
+msgstr "přijetí spojení selhalo: %s – čeká se 1 s\n"
 
-#~ msgid "do not use fallback hosts with --ldap-proxy"
-#~ msgstr "nepoužije náhradní stroje s --ldap-proxy"
+#, c-format
+msgid "error spawning connection handler: %s\n"
+msgstr "chyba při vytváření obsluhy spojení: %s\n"
 
-#~ msgid "|FILE|read LDAP server list from FILE"
-#~ msgstr "|SOUBOR|načte seznam LDAP serverů ze SOUBORU"
+#, c-format
+msgid "invalid char 0x%02x in host name - not added\n"
+msgstr "v názvu stroje je neplatný znak 0x%02x – nepřidáno\n"
 
-#~ msgid "add new servers discovered in CRL distribution points to serverlist"
-#~ msgstr ""
-#~ "na seznam serverů přidá nové servery nalezené v místech distribuce CRL"
+#, c-format
+msgid "adding '%s:%d' to the ldap server list\n"
+msgstr "na seznam LDAP serverů bude zařazen „%s:%d“\n"
 
-#~ msgid "|N|set LDAP timeout to N seconds"
-#~ msgstr "|N|nastaví časový limit pro LDAP na N sekund"
+#, c-format
+msgid "malloc failed: %s\n"
+msgstr "funkce malloc selhala: %s\n"
 
-#~ msgid "|URL|use OCSP responder at URL"
-#~ msgstr "|URL|použije OCSP odpovídače na URL"
+#, c-format
+msgid "error printing log line: %s\n"
+msgstr "chyba při tisknutí řádku protokolu: %s\n"
 
-#~ msgid "|FPR|OCSP response signed by FPR"
-#~ msgstr "|OTISK|OCSP odpovědi podepsané podle OTISKU"
+#, c-format
+msgid "pth_event failed: %s\n"
+msgstr "funkce pth_event selhala: %s\n"
 
-#~ msgid "|N|do not return more than N items in one query"
-#~ msgstr "|N|nevrací více jak N položek na jeden dotaz"
+#, c-format
+msgid "pth_wait failed: %s\n"
+msgstr "funkce pth_wait selhala: %s\n"
 
-#~ msgid ""
-#~ "@\n"
-#~ "(See the \"info\" manual for a complete listing of all commands and "
-#~ "options)\n"
-#~ msgstr ""
-#~ "@\n"
-#~ "(Úplný seznam příkazů a voleb naleznete v „info“ manuálu.)\n"
+#, c-format
+msgid "error reading log from ldap wrapper %d: %s\n"
+msgstr "chyba při čtení protokolu z ldapové obálky č. %d: %s\n"
 
-#~ msgid "Usage: dirmngr [options] (-h for help)"
-#~ msgstr "Použití: dirmngr [VOLBY] (-h pro nápovědu)"
+#, c-format
+msgid "ldap wrapper %d ready: timeout\n"
+msgstr "ldapová obálka %d připravena: čas vypršel\n"
 
-#~ msgid ""
-#~ "Syntax: dirmngr [options] [command [args]]\n"
-#~ "LDAP and OCSP access for GnuPG\n"
-#~ msgstr ""
-#~ "Syntaxe: dirmngr [VOLBY] [PŘÍKAZ [ARGUMENTY]]\n"
-#~ "LDAP a OCSP přístup z GnuPG\n"
+#, c-format
+msgid "ldap wrapper %d ready"
+msgstr "ldapová obálka %d připravena"
+
+#, c-format
+msgid "waiting for ldap wrapper %d failed: %s\n"
+msgstr "čekání na ldapovou obálku %d selhalo: %s\n"
 
-#~ msgid "valid debug levels are: %s\n"
-#~ msgstr "platné úrovně ladění jsou: %s\n"
+#, c-format
+msgid "ldap wrapper %d stalled - killing\n"
+msgstr "ldapová obálka %d se zasekla – bude zabita\n"
 
-#~ msgid "usage: dirmngr [options] "
-#~ msgstr "použití: dirmngr [VOLBY] "
+#, c-format
+msgid "reading from ldap wrapper %d failed: %s\n"
+msgstr "čtení z ldapové obálky %d selhalo: %s\n"
 
-#~ msgid "colons are not allowed in the socket name\n"
-#~ msgstr "dvojtečky v názvu socketu jsou nepřípustné\n"
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "chyba při alokování paměti: %s\n"
 
-#~ msgid "fetching CRL from `%s' failed: %s\n"
-#~ msgstr "stahování CRL z „%s„ selhalo: %s\n"
+#, c-format
+msgid "start_cert_fetch: invalid pattern '%s'\n"
+msgstr "start_cert_fetch: chybný vzor „%s“\n"
 
-#~ msgid "processing CRL from `%s' failed: %s\n"
-#~ msgstr "zpracování CRL z „%s“ selhalo: %s\n"
+msgid "ldap_search hit the size limit of the server\n"
+msgstr "ldap_search přesáhl omezení velikosti serveru\n"
 
-#~ msgid "%s:%u: line too long - skipped\n"
-#~ msgstr "%s:%u: řádek je příliš dlouhý – přeskočen\n"
+msgid "invalid canonical S-expression found\n"
+msgstr "nalezen neplatný kanonický S-výraz\n"
 
-#~ msgid "%s:%u: invalid fingerprint detected\n"
-#~ msgstr "%s:%u: zjištěn neplatný otisk\n"
+#, c-format
+msgid "gcry_md_open failed: %s\n"
+msgstr "gcry_md_open selhalo: %s\n"
 
-#~ msgid "%s:%u: read error: %s\n"
-#~ msgstr "%s:%u: chyba čtení: %s\n"
+#, c-format
+msgid "oops: ksba_cert_hash failed: %s\n"
+msgstr "jejda: ksba_cert_hash selhalo: %s\n"
 
-#~ msgid "%s:%u: garbage at end of line ignored\n"
-#~ msgstr "%s:%u: nepořádek na konci řádku ignorován\n"
+msgid "bad URL encoding detected\n"
+msgstr "zjištěno chybné kódování URL\n"
 
-#~ msgid "SIGHUP received - re-reading configuration and flushing caches\n"
-#~ msgstr "přijat SIGHUP – konfigurace bude znovu načtena a keš vyprázdněna\n"
+#, c-format
+msgid "error reading from responder: %s\n"
+msgstr "chyba při čtení z odpovídače: %s\n"
 
-#~ msgid "SIGUSR2 received - no action defined\n"
-#~ msgstr "přijat SIGUSR2 – žádná akce nedefinována\n"
+#, c-format
+msgid "response from server too large; limit is %d bytes\n"
+msgstr "odpověď serveru je příliš velká, limit je %d bajtů\n"
 
-#~ msgid "SIGTERM received - shutting down ...\n"
-#~ msgstr "přijat SIGTERM – vypíná se…\n"
+msgid "OCSP request not possible due to disabled HTTP\n"
+msgstr "OCSP dotaz není možný, protože HTTP je zakázáno\n"
 
-# TODO: plural
-#~ msgid "SIGTERM received - still %d active connections\n"
-#~ msgstr "přijat SIGTERM – stále aktivních spojení: %d\n"
+#, c-format
+msgid "error setting OCSP target: %s\n"
+msgstr "chyba při nastavování cíle OCSP: %s\n"
 
-#~ msgid "shutdown forced\n"
-#~ msgstr "vypnutí vynuceno\n"
+#, c-format
+msgid "error building OCSP request: %s\n"
+msgstr "chyba při sestavování OCSP dotazu: %s\n"
 
-#~ msgid "SIGINT received - immediate shutdown\n"
-#~ msgstr "přijat SIGINT – okamžité vypnutí\n"
+#, c-format
+msgid "error connecting to '%s': %s\n"
+msgstr "chyba při připojování na „%s“: %s\n"
 
-#~ msgid "signal %d received - no action defined\n"
-#~ msgstr "přijat signál č. %d – žádná akce nedefinována\n"
+#, c-format
+msgid "error reading HTTP response for '%s': %s\n"
+msgstr "chyba při čtení HTTP odpovědi od „%s“: %s\n"
 
-#~ msgid "return all values in a record oriented format"
-#~ msgstr "vrátí všechny hodnoty v záznamově orientovaném formátu"
+#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "chyba přístupu k „%s“: status HTTP %u\n"
 
-#~ msgid "|NAME|ignore host part and connect through NAME"
-#~ msgstr "|NÁZEV|ignoruje část se strojem a připojí se skrze NÁZEV"
+#, c-format
+msgid "error parsing OCSP response for '%s': %s\n"
+msgstr "chyba při rozebírání OCSP odpovědi od „%s“: %s\n"
 
-#~ msgid "|NAME|connect to host NAME"
-#~ msgstr "|NÁZEV|připojí se ke strojí NÁZEV"
+#, c-format
+msgid "OCSP responder at '%s' status: %s\n"
+msgstr "Stav odpovídače OCSP na „%s“: %s\n"
 
-#~ msgid "|N|connect to port N"
-#~ msgstr "|N|připojí se na port N"
+#, c-format
+msgid "hashing the OCSP response for '%s' failed: %s\n"
+msgstr "hašování OCSP odpovědi pro „%s“ selhalo: %s\n"
 
-#~ msgid "|NAME|use user NAME for authentication"
-#~ msgstr "|JMÉNO|pro autentizaci použije JMÉNO uživatele"
+msgid "not signed by a default OCSP signer's certificate"
+msgstr "nepodepsáno výchozím OCSP certifikátem podepisovatele"
 
-#~ msgid "|PASS|use password PASS for authentication"
-#~ msgstr "|HESLO|pro autentizaci použije HESLO"
+msgid "only SHA-1 is supported for OCSP responses\n"
+msgstr "v OCSP odpovědích je podporováno jen SHA-1\n"
 
-#~ msgid "take password from $DIRMNGR_LDAP_PASS"
-#~ msgstr "heslo získá z $DIRMNGR_LDAP_PASS"
+#, c-format
+msgid "allocating list item failed: %s\n"
+msgstr "alokování prvku seznamu selhalo: %s\n"
 
-#~ msgid "|STRING|query DN STRING"
-#~ msgstr "|ŘETĚZEC|dotáže se na DN ŘETĚZEC"
+#, c-format
+msgid "error getting responder ID: %s\n"
+msgstr "chyba při zjišťování ID odpovídače: %s\n"
 
-#~ msgid "|STRING|use STRING as filter expression"
-#~ msgstr "|ŘETĚZEC|jako filtrující výraz použije ŘETĚZEC"
+msgid "no suitable certificate found to verify the OCSP response\n"
+msgstr "žádný vhodný certifikát pro ověření OCSP odpovědi nebyl nalezen\n"
 
-#~ msgid "|STRING|return the attribute STRING"
-#~ msgstr "|ŘETĚZEC|vrátí atribut ŘETĚZEC"
+#, c-format
+msgid "issuer certificate not found: %s\n"
+msgstr "certifikát vydavatele nenalezen: %s\n"
 
-#~ msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n"
-#~ msgstr "Použití: dirmngr_ldap [VOLBY] [URL] (-h pro nápovědu)\n"
+msgid "caller did not return the target certificate\n"
+msgstr "volající nevrátil cílový certifikát\n"
 
-#~ msgid ""
-#~ "Syntax: dirmngr_ldap [options] [URL]\n"
-#~ "Internal LDAP helper for Dirmngr.\n"
-#~ "Interface and options may change without notice.\n"
-#~ msgstr ""
-#~ "Syntaxe: dirmngr_ldap [VOLBY] [URL]\n"
-#~ "Vnitřní LDAP pomůcka pro pro Dirmngr.\n"
-#~ "Rozhraní a volby se mohou bez upozornění změnit.\n"
+msgid "caller did not return the issuing certificate\n"
+msgstr "volající nevrátil vydávající certifikát\n"
 
-#~ msgid "invalid port number %d\n"
-#~ msgstr "neplatné číslo portu %d\n"
+#, c-format
+msgid "failed to allocate OCSP context: %s\n"
+msgstr "alokace OCSP kontextu selhala: %s\n"
 
-#~ msgid "scanning result for attribute `%s'\n"
-#~ msgstr "ve výsledku se hledá atribut „%s“\n"
+#, c-format
+msgid "can't get authorityInfoAccess: %s\n"
+msgstr "authorityInfoAccess nelze získat: %s\n"
 
-#~ msgid "error writing to stdout: %s\n"
-#~ msgstr "chyba při zápisu na standardní výstup: %s\n"
+msgid "no default OCSP responder defined\n"
+msgstr "žádný výchozí OCSP odpovídač nedefinován\n"
 
-#~ msgid "          available attribute `%s'\n"
-#~ msgstr "          dostupný atribut „%s“\n"
+msgid "no default OCSP signer defined\n"
+msgstr "žádný výchozí OCSP podepisovatel nedefinován\n"
 
-#~ msgid "attribute `%s' not found\n"
-#~ msgstr "atribut „%s“ nenalezen\n"
+#, c-format
+msgid "using default OCSP responder '%s'\n"
+msgstr "použije se výchozí OCSP odpovídač „%s“\n"
 
-#~ msgid "found attribute `%s'\n"
-#~ msgstr "nalezen atribut „%s“\n"
+#, c-format
+msgid "using OCSP responder '%s'\n"
+msgstr "použije se OCSP odpovídač „%s“\n"
 
-#~ msgid "processing url `%s'\n"
-#~ msgstr "zpracovává se URL „%s“\n"
+#, c-format
+msgid "failed to establish a hashing context for OCSP: %s\n"
+msgstr "nepodařilo se ustanovit hašovací kontext OCSP: %s\n"
 
-#~ msgid "          user `%s'\n"
-#~ msgstr "          uživatel „%s“\n"
+#, c-format
+msgid "error getting OCSP status for target certificate: %s\n"
+msgstr "chyba při zjišťování OCSP stavu cílového certifikátu: %s\n"
 
-#~ msgid "          pass `%s'\n"
-#~ msgstr "          heslo „%s“\n"
+#, c-format
+msgid "certificate status is: %s  (this=%s  next=%s)\n"
+msgstr "stav certifikátu je: %s (nyní=%s, příště=%s)\n"
 
-#~ msgid "          host `%s'\n"
-#~ msgstr "          stroj „%s“\n"
+# status
+msgid "good"
+msgstr "dobrý"
 
-#~ msgid "          port %d\n"
-#~ msgstr "          port %d\n"
+#, c-format
+msgid "certificate has been revoked at: %s due to: %s\n"
+msgstr "certifikát byl odvolán kdy: %s, důvod: %s\n"
 
-#~ msgid "            DN `%s'\n"
-#~ msgstr "            DN „%s“\n"
+msgid "OCSP responder returned a status in the future\n"
+msgstr "OCSP odpovídač vrátil stav v budoucnosti\n"
 
-#~ msgid "        filter `%s'\n"
-#~ msgstr "        filtr „%s“\n"
+msgid "OCSP responder returned a non-current status\n"
+msgstr "OCSP odpovídač vrátil ne současný stav\n"
 
-#~ msgid "          attr `%s'\n"
-#~ msgstr "          atribut „%s“\n"
+msgid "OCSP responder returned an too old status\n"
+msgstr "OCSP odpovídač vrátil příliš starý stav\n"
 
-#~ msgid "no host name in `%s'\n"
-#~ msgstr "v „%s“ chybí název stroje\n"
+#, c-format
+msgid "assuan_inquire(%s) failed: %s\n"
+msgstr "volání assuan_inquire(%s) selhalo: %s\n"
 
-#~ msgid "no attribute given for query `%s'\n"
-#~ msgstr "u dotazu „%s“ nezadán žádný atribut\n"
+msgid "ldapserver missing"
+msgstr "chybí ldapserver (LDAP server)"
 
-#~ msgid "WARNING: using first attribute only\n"
-#~ msgstr "POZOR: použije se pouze první atribut\n"
+msgid "serialno missing in cert ID"
+msgstr "v ID certifikátu chybí serialno (sériové číslo)"
 
-#~ msgid "LDAP init to `%s:%d' failed: %s\n"
-#~ msgstr "Inicializace LDAP u „%s:%d“ selhala: %s\n"
+#, c-format
+msgid "command %s failed: %s\n"
+msgstr "příkaz %s selhal: %s\n"
 
-#~ msgid "binding to `%s:%d' failed: %s\n"
-#~ msgstr "napojení k „%s:%d“ selhalo: %s\n"
+#, c-format
+msgid "assuan_inquire failed: %s\n"
+msgstr "volání assuan_inquire selhalo: %s\n"
 
-#~ msgid "searching `%s' failed: %s\n"
-#~ msgstr "vyhledávání „%s“ selhalo: %s\n"
+#, c-format
+msgid "fetch_cert_by_url failed: %s\n"
+msgstr "volání fetch_cert_by_url selhalo: %s\n"
 
-#~ msgid "`%s' is not an LDAP URL\n"
-#~ msgstr "„%s“ není LDAP URL\n"
+#, c-format
+msgid "error sending data: %s\n"
+msgstr "chyba při odesílání dat: %s\n"
 
-#~ msgid "`%s' is an invalid LDAP URL\n"
-#~ msgstr "„%s“ není platní LDAP URL\n"
+#, c-format
+msgid "start_cert_fetch failed: %s\n"
+msgstr "volání start_cert_fetch selhalo: %s\n"
 
-#~ msgid "error allocating memory: %s\n"
-#~ msgstr "chyba při alokování paměti: %s\n"
+#, c-format
+msgid "fetch_next_cert failed: %s\n"
+msgstr "volání fetch_next_cert selhalo: %s\n"
 
-#~ msgid "error printing log line: %s\n"
-#~ msgstr "chyba při tisknutí řádku protokolu: %s\n"
+#, c-format
+msgid "max_replies %d exceeded\n"
+msgstr "max_replies (max. odpovědí) %d překročeno\n"
 
-#~ msgid "error reading log from ldap wrapper %d: %s\n"
-#~ msgstr "chyba při čtení protokolu z ldapové obálky č. %d: %s\n"
+msgid "no data stream"
+msgstr "žádný datový proud"
 
-#~ msgid "pth_event failed: %s\n"
-#~ msgstr "funkce pth_event selhala: %s\n"
+#, c-format
+msgid "can't allocate control structure: %s\n"
+msgstr "řídící strukturu nelze alokovat: %s\n"
 
-#~ msgid "pth_wait failed: %s\n"
-#~ msgstr "funkce pth_wait selhala: %s\n"
+#, c-format
+msgid "failed to initialize the server: %s\n"
+msgstr "inicializace serveru selhala: %s\n"
 
-#~ msgid "ldap wrapper %d ready"
-#~ msgstr "ldapová obálka %d připravena"
+#, c-format
+msgid "failed to the register commands with Assuan: %s\n"
+msgstr "registrace příkazu u Assuanu selhala: %s\n"
 
-#~ msgid "ldap wrapper %d ready: timeout\n"
-#~ msgstr "ldapová obálka %d připravena: čas vypršel\n"
+#, c-format
+msgid "Assuan accept problem: %s\n"
+msgstr "problém příjmu Assuanu: %s\n"
 
-#~ msgid "ldap wrapper %d ready: exitcode=%d\n"
-#~ msgstr "ldapová obálka %d připravena: návratový kód = %d\n"
+#, c-format
+msgid "Assuan processing failed: %s\n"
+msgstr "zpracování Assuanu se nezdařilo: %s\n"
 
-#~ msgid "waiting for ldap wrapper %d failed: %s\n"
-#~ msgstr "čekání na ldapovou obálku %d selhalo: %s\n"
+msgid "accepting root CA not marked as a CA"
+msgstr "kořenová CA, která není označena jako CA, bude přijata"
 
-#~ msgid "ldap wrapper %d stalled - killing\n"
-#~ msgstr "ldapová obálka %d se zasekla – bude zabita\n"
+msgid "CRL checking too deeply nested\n"
+msgstr "kontrola CRL se zanořila příliš hluboko\n"
 
-#~ msgid "error spawning ldap wrapper reaper thread: %s\n"
-#~ msgstr "chyba při zakládání vlákna ovládajícího obálku LDAPu: %s\n"
+msgid "not checking CRL for"
+msgstr "nekontroluje se CRL pro"
 
-#~ msgid "reading from ldap wrapper %d failed: %s\n"
-#~ msgstr "čtení z ldapové obálky %d selhalo: %s\n"
+msgid "checking CRL for"
+msgstr "kontroluje se CRL pro"
 
-#~ msgid "invalid char 0x%02x in host name - not added\n"
-#~ msgstr "v názvu stroje je neplatný znak 0x%02x – nepřidáno\n"
+msgid "running in compatibility mode - certificate chain not checked!\n"
+msgstr "provoz v režimu kompatibility – řetěz certifikátů nezkontrolován!\n"
 
-#~ msgid "adding `%s:%d' to the ldap server list\n"
-#~ msgstr "na seznam LDAP serverů bude zařazen „%s:%d“\n"
+msgid "selfsigned certificate has a BAD signature"
+msgstr "sám sebou podepsaný certifikát má CHYBNÝ podpis"
 
-#~ msgid "malloc failed: %s\n"
-#~ msgstr "funkce malloc selhala: %s\n"
+#, c-format
+msgid "checking trustworthiness of root certificate failed: %s\n"
+msgstr "kontrola důvěryhodnosti kořenového certifikátu selhala: %s\n"
 
-#~ msgid "start_cert_fetch: invalid pattern `%s'\n"
-#~ msgstr "start_cert_fetch: chybný vzor „%s“\n"
+msgid "certificate chain is good\n"
+msgstr "řetěz certifikátů je v pořádku\n"
 
-#~ msgid "ldap_search hit the size limit of the server\n"
-#~ msgstr "ldap_search přesáhl omezení velikosti serveru\n"
+msgid "certificate should have not been used for CRL signing\n"
+msgstr "certifikát by neměl být použit pro podepisování CRL\n"
 
-#~ msgid "invalid canonical S-expression found\n"
-#~ msgstr "nalezen neplatný kanonický S-výraz\n"
+msgid "use OCSP instead of CRLs"
+msgstr "místo CRL použije OCSP"
 
-#~ msgid "gcry_md_open failed: %s\n"
-#~ msgstr "gcry_md_open selhalo: %s\n"
+msgid "check whether a dirmngr is running"
+msgstr "zjistí, jestli dirmngr běží"
 
-#~ msgid "oops: ksba_cert_hash failed: %s\n"
-#~ msgstr "jejda: ksba_cert_hash selhalo: %s\n"
+msgid "add a certificate to the cache"
+msgstr "přidá certifikát do keše"
 
-#~ msgid "bad URL encoding detected\n"
-#~ msgstr "zjištěno chybné kódování URL\n"
+msgid "validate a certificate"
+msgstr "ověří platnost certifikátu"
 
-#~ msgid "error reading from responder: %s\n"
-#~ msgstr "chyba při čtení z odpovídače: %s\n"
+msgid "lookup a certificate"
+msgstr "vyhledá certifikát"
 
-#~ msgid "response from server too large; limit is %d bytes\n"
-#~ msgstr "odpověď serveru je příliš velká, limit je %d bajtů\n"
+msgid "lookup only locally stored certificates"
+msgstr "hledá pouze mezi lokálně uloženými certifikáty"
 
-#~ msgid "OCSP request not possible due to disabled HTTP\n"
-#~ msgstr "OCSP dotaz není možný, protože HTTP je zakázáno\n"
+msgid "expect an URL for --lookup"
+msgstr "u --lookup očekává URL"
 
-#~ msgid "error setting OCSP target: %s\n"
-#~ msgstr "chyba při nastavování cíle OCSP: %s\n"
+msgid "load a CRL into the dirmngr"
+msgstr "zavede CRL do dirmngr"
 
-#~ msgid "error building OCSP request: %s\n"
-#~ msgstr "chyba při sestavování OCSP dotazu: %s\n"
+msgid "special mode for use by Squid"
+msgstr "zvláštní režim pro použití se Squidem"
 
-#~ msgid "error connecting to `%s': %s\n"
-#~ msgstr "chyba při připojování na „%s“: %s\n"
+msgid "certificates are expected in PEM format"
+msgstr "certifikáty budou očekávány ve formátu PEM"
 
-#~ msgid "error reading HTTP response for `%s': %s\n"
-#~ msgstr "chyba při čtení HTTP odpovědi od „%s“: %s\n"
+msgid "force the use of the default OCSP responder"
+msgstr "vynutí použití výchozího OCSP odpovídače"
 
-#~ msgid "error accessing `%s': http status %u\n"
-#~ msgstr "chyba přístupu k „%s“: status HTTP %u\n"
+msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n"
+msgstr "Použití: dirmngr-client [VOLBY] [CERT_SOUBOR|VZOR] (-h pro nápovědu)\n"
 
-#~ msgid "error parsing OCSP response for `%s': %s\n"
-#~ msgstr "chyba při rozebírání OCSP odpovědi od „%s“: %s\n"
+msgid ""
+"Syntax: dirmngr-client [options] [certfile|pattern]\n"
+"Test an X.509 certificate against a CRL or do an OCSP check\n"
+"The process returns 0 if the certificate is valid, 1 if it is\n"
+"not valid and other error codes for general failures\n"
+msgstr ""
+"Syntaxe: dirmngr-client [VOLBY] [CERT_SOUBOR|VZOR]\n"
+"Vyzkouší X.509 certifikát proti CRL nebo OCSP.\n"
+"Proces vrátí 0, pokud je certifikát platný, 1, pokud není platný nebo jiný\n"
+"chybový kód značící obecné selhání.\n"
 
-#~ msgid "OCSP responder at `%s' status: %s\n"
-#~ msgstr "Stav odpovídače OCSP na „%s“: %s\n"
+#, c-format
+msgid "error reading certificate from stdin: %s\n"
+msgstr "chyba při čtení certifikátu ze standardního vstupu: %s\n"
 
-#~ msgid "hashing the OCSP response for `%s' failed: %s\n"
-#~ msgstr "hašování OCSP odpovědi pro „%s“ selhalo: %s\n"
+#, c-format
+msgid "error reading certificate from '%s': %s\n"
+msgstr "chyba při čtení certifikátu ze „%s“: %s\n"
 
-#~ msgid "not signed by a default OCSP signer's certificate"
-#~ msgstr "nepodepsáno výchozím OCSP certifikátem podepisovatele"
+msgid "certificate too large to make any sense\n"
+msgstr "certifikát je příliš velký, než aby dával smysl\n"
 
-#~ msgid "only SHA-1 is supported for OCSP responses\n"
-#~ msgstr "v OCSP odpovědích je podporováno jen SHA-1\n"
+#, c-format
+msgid "lookup failed: %s\n"
+msgstr "hledání selhalo: %s\n"
 
-#~ msgid "allocating list item failed: %s\n"
-#~ msgstr "alokování prvku seznamu selhalo: %s\n"
+#, c-format
+msgid "loading CRL '%s' failed: %s\n"
+msgstr "zavádění CRL „%s“ selhalo: %s\n"
 
-#~ msgid "error getting responder ID: %s\n"
-#~ msgstr "chyba při zjišťování ID odpovídače: %s\n"
+msgid "a dirmngr daemon is up and running\n"
+msgstr "démon dirmngr běží\n"
 
-#~ msgid "no suitable certificate found to verify the OCSP response\n"
-#~ msgstr "žádný vhodný certifikát pro ověření OCSP odpovědi nebyl nalezen\n"
+#, c-format
+msgid "validation of certificate failed: %s\n"
+msgstr "ověření platnosti certifikátu selhalo: %s\n"
 
-#~ msgid "issuer certificate not found: %s\n"
-#~ msgstr "certifikát vydavatele nenalezen: %s\n"
+msgid "certificate is valid\n"
+msgstr "certifikát je platný\n"
 
-#~ msgid "caller did not return the target certificate\n"
-#~ msgstr "volající nevrátil cílový certifikát\n"
+msgid "certificate has been revoked\n"
+msgstr "certifikát byl odvolán\n"
 
-#~ msgid "caller did not return the issuing certificate\n"
-#~ msgstr "volající nevrátil vydávající certifikát\n"
+#, c-format
+msgid "certificate check failed: %s\n"
+msgstr "kontrola certifikátu selhala: %s\n"
 
-#~ msgid "failed to allocate OCSP context: %s\n"
-#~ msgstr "alokace OCSP kontextu selhala: %s\n"
+#, c-format
+msgid "got status: '%s'\n"
+msgstr "obdržen status: „%s“\n"
 
-#~ msgid "can't get authorityInfoAccess: %s\n"
-#~ msgstr "authorityInfoAccess nelze získat: %s\n"
+#, c-format
+msgid "error writing base64 encoding: %s\n"
+msgstr "chyba při zápisu kódování base64: %s\n"
 
-#~ msgid "no default OCSP responder defined\n"
-#~ msgstr "žádný výchozí OCSP odpovídač nedefinován\n"
+msgid "apparently no running dirmngr\n"
+msgstr "dirmngr zjevně neběží\n"
 
-#~ msgid "no default OCSP signer defined\n"
-#~ msgstr "žádný výchozí OCSP podepisovatel nedefinován\n"
+msgid "no running dirmngr - starting one\n"
+msgstr "žádný dirmngr neběží – jeden bude spuštěn\n"
 
-#~ msgid "using default OCSP responder `%s'\n"
-#~ msgstr "použije se výchozí OCSP odpovídač „%s“\n"
+#, c-format
+msgid "can't connect to the dirmngr: %s\n"
+msgstr "k dirmngr se nelze připojit: %s\n"
 
-#~ msgid "using OCSP responder `%s'\n"
-#~ msgstr "použije se OCSP odpovídač „%s“\n"
+#, c-format
+msgid "unsupported inquiry '%s'\n"
+msgstr "nepodporovaný dotaz „%s“\n"
 
-#~ msgid "failed to establish a hashing context for OCSP: %s\n"
-#~ msgstr "nepodařilo se ustanovit hašovací kontext OCSP: %s\n"
+msgid "absolute file name expected\n"
+msgstr "očekáván absolutní název souboru\n"
 
-#~ msgid "error getting OCSP status for target certificate: %s\n"
-#~ msgstr "chyba při zjišťování OCSP stavu cílového certifikátu: %s\n"
+#, c-format
+msgid "looking up '%s'\n"
+msgstr "hledá se „%s“\n"
 
-#~ msgid "certificate status is: %s  (this=%s  next=%s)\n"
-#~ msgstr "stav certifikátu je: %s (nyní=%s, příště=%s)\n"
+msgid "return all values in a record oriented format"
+msgstr "vrátí všechny hodnoty v záznamově orientovaném formátu"
 
-# status
-#~ msgid "good"
-#~ msgstr "dobrý"
+msgid "|NAME|ignore host part and connect through NAME"
+msgstr "|NÁZEV|ignoruje část se strojem a připojí se skrze NÁZEV"
 
-#~ msgid "certificate has been revoked at: %s due to: %s\n"
-#~ msgstr "certifikát byl odvolán kdy: %s, důvod: %s\n"
+msgid "|NAME|connect to host NAME"
+msgstr "|NÁZEV|připojí se ke strojí NÁZEV"
 
-#~ msgid "OCSP responder returned a status in the future\n"
-#~ msgstr "OCSP odpovídač vrátil stav v budoucnosti\n"
+msgid "|N|connect to port N"
+msgstr "|N|připojí se na port N"
 
-#~ msgid "OCSP responder returned a non-current status\n"
-#~ msgstr "OCSP odpovídač vrátil ne současný stav\n"
+msgid "|NAME|use user NAME for authentication"
+msgstr "|JMÉNO|pro autentizaci použije JMÉNO uživatele"
 
-#~ msgid "OCSP responder returned an too old status\n"
-#~ msgstr "OCSP odpovídač vrátil příliš starý stav\n"
+msgid "|PASS|use password PASS for authentication"
+msgstr "|HESLO|pro autentizaci použije HESLO"
 
-#~ msgid "assuan_inquire(%s) failed: %s\n"
-#~ msgstr "volání assuan_inquire(%s) selhalo: %s\n"
+msgid "take password from $DIRMNGR_LDAP_PASS"
+msgstr "heslo získá z $DIRMNGR_LDAP_PASS"
 
-#~ msgid "ldapserver missing"
-#~ msgstr "chybí ldapserver (LDAP server)"
+msgid "|STRING|query DN STRING"
+msgstr "|ŘETĚZEC|dotáže se na DN ŘETĚZEC"
 
-#~ msgid "serialno missing in cert ID"
-#~ msgstr "v ID certifikátu chybí serialno (sériové číslo)"
+msgid "|STRING|use STRING as filter expression"
+msgstr "|ŘETĚZEC|jako filtrující výraz použije ŘETĚZEC"
 
-#~ msgid "assuan_inquire failed: %s\n"
-#~ msgstr "volání assuan_inquire selhalo: %s\n"
+msgid "|STRING|return the attribute STRING"
+msgstr "|ŘETĚZEC|vrátí atribut ŘETĚZEC"
 
-#~ msgid "fetch_cert_by_url failed: %s\n"
-#~ msgstr "volání fetch_cert_by_url selhalo: %s\n"
+msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n"
+msgstr "Použití: dirmngr_ldap [VOLBY] [URL] (-h pro nápovědu)\n"
 
-#~ msgid "error sending data: %s\n"
-#~ msgstr "chyba při odesílání dat: %s\n"
+msgid ""
+"Syntax: dirmngr_ldap [options] [URL]\n"
+"Internal LDAP helper for Dirmngr.\n"
+"Interface and options may change without notice.\n"
+msgstr ""
+"Syntaxe: dirmngr_ldap [VOLBY] [URL]\n"
+"Vnitřní LDAP pomůcka pro pro Dirmngr.\n"
+"Rozhraní a volby se mohou bez upozornění změnit.\n"
 
-#~ msgid "start_cert_fetch failed: %s\n"
-#~ msgstr "volání start_cert_fetch selhalo: %s\n"
+#, c-format
+msgid "invalid port number %d\n"
+msgstr "neplatné číslo portu %d\n"
 
-#~ msgid "fetch_next_cert failed: %s\n"
-#~ msgstr "volání fetch_next_cert selhalo: %s\n"
+#, c-format
+msgid "scanning result for attribute '%s'\n"
+msgstr "ve výsledku se hledá atribut „%s“\n"
 
-#~ msgid "max_replies %d exceeded\n"
-#~ msgstr "max_replies (max. odpovědí) %d překročeno\n"
+#, c-format
+msgid "error writing to stdout: %s\n"
+msgstr "chyba při zápisu na standardní výstup: %s\n"
 
-#~ msgid "can't allocate control structure: %s\n"
-#~ msgstr "řídící strukturu nelze alokovat: %s\n"
+#, c-format
+msgid "          available attribute '%s'\n"
+msgstr "          dostupný atribut „%s“\n"
 
-#~ msgid "failed to initialize the server: %s\n"
-#~ msgstr "inicializace serveru selhala: %s\n"
+#, c-format
+msgid "attribute '%s' not found\n"
+msgstr "atribut „%s“ nenalezen\n"
 
-#~ msgid "failed to the register commands with Assuan: %s\n"
-#~ msgstr "registrace příkazu u Assuanu selhala: %s\n"
+#, c-format
+msgid "found attribute '%s'\n"
+msgstr "nalezen atribut „%s“\n"
 
-#~ msgid "Assuan accept problem: %s\n"
-#~ msgstr "problém příjmu Assuanu: %s\n"
+#, c-format
+msgid "processing url '%s'\n"
+msgstr "zpracovává se URL „%s“\n"
 
-#~ msgid "Assuan processing failed: %s\n"
-#~ msgstr "zpracování Assuanu se nezdařilo: %s\n"
+#, c-format
+msgid "          user '%s'\n"
+msgstr "          uživatel „%s“\n"
 
-#~ msgid "accepting root CA not marked as a CA"
-#~ msgstr "kořenová CA, která není označena jako CA, bude přijata"
+#, c-format
+msgid "          pass '%s'\n"
+msgstr "          heslo „%s“\n"
 
-#~ msgid "CRL checking too deeply nested\n"
-#~ msgstr "kontrola CRL se zanořila příliš hluboko\n"
+#, c-format
+msgid "          host '%s'\n"
+msgstr "          stroj „%s“\n"
 
-#~ msgid "not checking CRL for"
-#~ msgstr "nekontroluje se CRL pro"
+#, c-format
+msgid "          port %d\n"
+msgstr "          port %d\n"
 
-#~ msgid "checking CRL for"
-#~ msgstr "kontroluje se CRL pro"
+#, c-format
+msgid "            DN '%s'\n"
+msgstr "            DN „%s“\n"
 
-#~ msgid "running in compatibility mode - certificate chain not checked!\n"
-#~ msgstr "provoz v režimu kompatibility – řetěz certifikátů nezkontrolován!\n"
+#, c-format
+msgid "        filter '%s'\n"
+msgstr "        filtr „%s“\n"
 
-#~ msgid "selfsigned certificate has a BAD signature"
-#~ msgstr "sám sebou podepsaný certifikát má CHYBNÝ podpis"
+#, c-format
+msgid "          attr '%s'\n"
+msgstr "          atribut „%s“\n"
 
-#~ msgid "checking trustworthiness of root certificate failed: %s\n"
-#~ msgstr "kontrola důvěryhodnosti kořenového certifikátu selhala: %s\n"
+#, c-format
+msgid "no host name in '%s'\n"
+msgstr "v „%s“ chybí název stroje\n"
 
-#~ msgid "certificate chain is good\n"
-#~ msgstr "řetěz certifikátů je v pořádku\n"
+#, c-format
+msgid "no attribute given for query '%s'\n"
+msgstr "u dotazu „%s“ nezadán žádný atribut\n"
 
-#~ msgid "DSA requires the use of a 160 bit hash algorithm\n"
-#~ msgstr "DSA požaduje použití 160-ti bitového hashovacího algoritmu\n"
+msgid "WARNING: using first attribute only\n"
+msgstr "POZOR: použije se pouze první atribut\n"
 
-#~ msgid "certificate should have not been used for CRL signing\n"
-#~ msgstr "certifikát by neměl být použit pro podepisování CRL\n"
+#, c-format
+msgid "LDAP init to '%s:%d' failed: %s\n"
+msgstr "Inicializace LDAP u „%s:%d“ selhala: %s\n"
 
-#~ msgid "|ADDR|connect to Assuan server at ADDR"
-#~ msgstr "|ADRESA|připojit se na socket Assuanu na ADRESE"
+#, c-format
+msgid "binding to '%s:%d' failed: %s\n"
+msgstr "napojení k „%s:%d“ selhalo: %s\n"
 
-#~ msgid "reload all or a given component"
-#~ msgstr "znovu načíst všechny nebo zadané komponenty"
+#, c-format
+msgid "searching '%s' failed: %s\n"
+msgstr "vyhledávání „%s“ selhalo: %s\n"
 
-#~ msgid "kill a given component"
-#~ msgstr "zabít zadanou komponentu"
+#, c-format
+msgid "'%s' is not an LDAP URL\n"
+msgstr "„%s“ není LDAP URL\n"
 
-#~ msgid "Command> "
-#~ msgstr "Příkaz> "
+#, c-format
+msgid "'%s' is an invalid LDAP URL\n"
+msgstr "„%s“ není platní LDAP URL\n"
 
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
-#~ msgstr "databáze důvěry je poškozena; prosím spusťte „gpg --fix-trustdb“.\n"
+#~ msgstr ""
+#~ "databáze důvěry je poškozena; prosím spusťte \"gpg --fix-trustdb\".\n"
 
 #~ msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
 #~ msgstr ""
-#~ "Chyby oznamte (anglicky), prosím, na adresu <gnupg-bugs@gnu.org>.\n"
-#~ "Připomínky k překladu (česky) <translations.cs@gnupg.cz>.\n"
+#~ "Chyby oznamte, prosím, na adresu <gnupg-bugs@gnu.org>.\n"
+#~ "Připomínky k překladu <rp@tns.cz>.\n"
 
+#, fuzzy
 #~ msgid "Please report bugs to "
 #~ msgstr ""
-#~ "Připomínky k překladu hlaste (česky) na <translations.cs@gnupg.cz>,\n"
-#~ "chyby v programu (anglicky) na "
+#~ "Chyby oznamte, prosím, na adresu <gnupg-bugs@gnu.org>.\n"
+#~ "Připomínky k překladu <rp@tns.cz>.\n"
 
 #~ msgid "DSA keypair will have %u bits.\n"
 #~ msgstr "Pár DSA klíčů DSA dlouhý %u bitů.\n"
@@ -7929,12 +7940,52 @@ msgstr ""
 #~ msgid "Repeat passphrase\n"
 #~ msgstr "Opakovat heslo\n"
 
+#, fuzzy
 #~ msgid "||Please enter your PIN at the reader's keypad%%0A[sigs done: %lu]"
-#~ msgstr ""
-#~ "||Prosím, zadejte svůj PIN na klávesnici čtečky%%0A[podpis hotov: %lu]"
+#~ msgstr "||Prosím vložte PIN%%0A[podpis hotov: %lu]"
 
 #~ msgid "|A|Admin PIN"
-#~ msgstr "|A|PIN správce"
+#~ msgstr "|A|PIN administrátora"
+
+#, fuzzy
+#~ msgid "read options from file"
+#~ msgstr "čtu možnosti z `%s'\n"
+
+#~ msgid "generate PGP 2.x compatible messages"
+#~ msgstr "generovat zprávu komplatibilní s PGP 2.x"
+
+#, fuzzy
+#~ msgid "|[FILE]|make a signature"
+#~ msgstr "|[soubor]|vytvořit podpis"
+
+#, fuzzy
+#~ msgid "|[FILE]|make a clear text signature"
+#~ msgstr "|[soubor]|vytvořit podpis v čitelném dokumentu"
+
+#, fuzzy
+#~ msgid "use the default key as default recipient"
+#~ msgstr ""
+#~ "přeskočeno: veřejný klíč je už nastaven podle implicitního adresáta\n"
+
+#, fuzzy
+#~ msgid "force v3 signatures"
+#~ msgstr "kontrolovat podpisy"
+
+#, fuzzy
+#~ msgid "add this secret keyring to the list"
+#~ msgstr "Pro provedení této operace je potřeba tajný klíč.\n"
+
+#, fuzzy
+#~ msgid "|NAME|set terminal charset to NAME"
+#~ msgstr "|JMÉNO|šifrovat pro JMÉNO"
+
+#, fuzzy
+#~ msgid "|N|use compress algorithm N"
+#~ msgstr "neznámý komprimační algoritmus"
+
+#, fuzzy
+#~ msgid "remove key from the public keyring"
+#~ msgstr "odstranit klíč ze souboru veřejných klíčů"
 
 #~ msgid ""
 #~ "It's up to you to assign a value here; this value will never be exported\n"
@@ -8103,11 +8154,11 @@ msgstr ""
 #~ "    používají pseudonym uživatele.\n"
 #~ "\n"
 #~ "\"2\" znamená, že jste částečně ověřil pravost klíče. Např. jste ověřil\n"
-#~ "    otisk klíče a zkontroloval identifikátor uživatele\n"
+#~ "    fingerprint klíče a zkontroloval identifikátor uživatele\n"
 #~ "    uvedený na klíči s fotografickým id.\n"
 #~ "\n"
 #~ "\"3\" Znamená, že jste provedl velmi pečlivě ověření pravosti klíče.\n"
-#~ "    To může například znamenat, že jste ověřil otisk klíče \n"
+#~ "    To může například znamenat, že jste ověřil fingerprint klíče \n"
 #~ "    jeho vlastníka osobně a dále jste pomocí obtížně padělatelného \n"
 #~ "    dokumentu s fotografií (například pasu) ověřil, že jméno majitele\n"
 #~ "    klíče se shoduje se jménem uvedeným v uživatelském ID a dále jste \n"
@@ -8144,7 +8195,7 @@ msgstr ""
 #~ msgstr ""
 #~ "Toto je platný podpis klíče; normálně nechcete tento podpis smazat,\n"
 #~ "protože může být důležitý při vytváření důvěry klíče nebo jiného klíče\n"
-#~ "certifikovaného tímto klíčem."
+#~ "ceritifikovaného tímto klíčem."
 
 #~ msgid ""
 #~ "This signature can't be checked because you don't have the\n"
@@ -8155,7 +8206,7 @@ msgstr ""
 #~ "Tento podpis nemůže být ověřen, protože nemáte odpovídající veřejný "
 #~ "klíč.\n"
 #~ "Jeho smazání byste měl(a) odložit do doby, než budete znát, který klíč\n"
-#~ "byl použit, protože tento podepisovací klíč může vytvořit důvěru\n"
+#~ "byl použit, protože tento podpisovací klíč může vytvořit důvěru\n"
 #~ "prostřednictvím jiného již certifikovaného klíče."
 
 #~ msgid ""
@@ -8223,7 +8274,7 @@ msgstr ""
 #~ "Měl(a) byste specifikovat důvod certifikace. V závislosti na kontextu\n"
 #~ "máte možnost si vybrat ze seznamu:\n"
 #~ "  \"Klíč byl kompromitován\"\n"
-#~ "      Toto použijte, pokud si myslíte, že k vašemu tajnému klíči získaly\n"
+#~ "      Toto použijte, pokud si myslíte, že k Vašemu tajnému klíči získaly\n"
 #~ "       přístup neoprávněné osoby.\n"
 #~ "  \"Klíč je nahrazen\"\n"
 #~ "      Toto použijte, pokud jste tento klíč nahradil(a) novějším klíčem.\n"
@@ -8241,7 +8292,7 @@ msgstr ""
 #~ msgstr ""
 #~ "Pokud chcete, můžete vložit text popisující původ vzniku tohoto "
 #~ "revokačního\n"
-#~ "certifikátu. Prosím, stručně. \n"
+#~ "ceritifikátu. Prosím, stručně. \n"
 #~ "Text končí prázdným řádkem.\n"
 
 #~ msgid "can't put notation data into v3 (PGP 2.x style) signatures\n"
@@ -8258,13 +8309,27 @@ msgstr ""
 #~ msgid "can't put a policy URL into v3 key (PGP 2.x style) signatures\n"
 #~ msgstr "nelze uložit URL politiky do podpisu v3 klíčem (formát PGP 2.x)\n"
 
+#, fuzzy
+#~ msgid ""
+#~ "please see http://www.gnupg.org/download/iconv.html for more information\n"
+#~ msgstr "Více informací naleznete na adrese http://www.gnupg.cz/faq.html\n"
+
+#, fuzzy
+#~ msgid "key generation is not available from the commandline\n"
+#~ msgstr "gpg-agent není v tomto sezení dostupný\n"
+
+#, fuzzy
+#~ msgid "please use the script \"%s\" to generate a new key\n"
+#~ msgstr "Prosím, vyberte druh klíče, který chcete generovat:\n"
+
 #~ msgid "cipher extension `%s' not loaded due to unsafe permissions\n"
 #~ msgstr ""
-#~ "šifra „%s“ nebyla nahrána, protože přístupová práva nejsou nastavena "
+#~ "šifra `%s' nebyla nahrána, protože přístupová práva nejsou nastavena "
 #~ "bezpečně\n"
 
+#, fuzzy
 #~ msgid ".\n"
-#~ msgstr ".\n"
+#~ msgstr "%s.\n"
 
 #~ msgid "problem with the agent - disabling agent use\n"
 #~ msgstr "problém s agentem - používání agenta vypnuto\n"
@@ -8290,14 +8355,15 @@ msgstr ""
 #~ msgid "no entropy gathering module detected\n"
 #~ msgstr "nebyl detekován žádný modul pro získání entropie\n"
 
+#, fuzzy
 #~ msgid "can't lock `%s': %s\n"
-#~ msgstr "„%s“ nelze zamknout: %s\n"
+#~ msgstr "nelze zamčít `%s'\n"
 
 #~ msgid "can't stat `%s': %s\n"
-#~ msgstr "nemohu použít příkaz stat na „%s“: %s\n"
+#~ msgstr "nemohu použít příkaz stat na `%s': %s\n"
 
 #~ msgid "`%s' is not a regular file - ignored\n"
-#~ msgstr "„%s“ není normální soubor - ignoruji\n"
+#~ msgstr "`%s' není normální soubor - ignoruji\n"
 
 #~ msgid "note: random_seed file is empty\n"
 #~ msgstr "poznámka: soubor random_seed je prázdný\n"
@@ -8306,16 +8372,16 @@ msgstr ""
 #~ msgstr "VAROVÁNÍ: neplatná velikost random_seed - soubor nepoužit\n"
 
 #~ msgid "can't read `%s': %s\n"
-#~ msgstr "nemohu číst „%s“: %s\n"
+#~ msgstr "nemohu číst `%s': %s\n"
 
 #~ msgid "note: random_seed file not updated\n"
 #~ msgstr "poznámka: soubor random_seed není aktualizován\n"
 
 #~ msgid "can't write `%s': %s\n"
-#~ msgstr "nemohu zapisovat do „%s“: %s\n"
+#~ msgstr "nemohu zapisovat do `%s': %s\n"
 
 #~ msgid "can't close `%s': %s\n"
-#~ msgstr "nemohu zavřít „%s“: %s\n"
+#~ msgstr "nemohu zavřít `%s': %s\n"
 
 #~ msgid "WARNING: using insecure random number generator!!\n"
 #~ msgstr "VAROVÁNÍ: použitý generátor náhodných čísel není bezpečný!!\n"
@@ -8351,12 +8417,13 @@ msgstr ""
 #~ "abyste\n"
 #~ "mu umožnili získat více entropie (je potřeba %d bajtů).\n"
 
+#, fuzzy
 #~ msgid "card reader not available\n"
-#~ msgstr "čtečka karet není dostupná\n"
+#~ msgstr "tajný klíč není dostupný"
 
 #~ msgid "Please insert the card and hit return or enter 'c' to cancel: "
 #~ msgstr ""
-#~ "Prosím vložte kartu a stiskněte enter. Operaci zrušíte stisknutím 'z': "
+#~ "Prosím vožte kartu a stiskněte enter. Operaci zrušíte stisknutím 'z': "
 
 #~ msgid "Hit return when ready or enter 'c' to cancel: "
 #~ msgstr ""
@@ -8375,8 +8442,9 @@ msgstr ""
 #~ msgid "NOTE: %s is not available in this version\n"
 #~ msgstr "POZNÁMKA: %s není v této verzi dostupné\n"
 
+#, fuzzy
 #~ msgid "         algorithms on these user IDs:\n"
-#~ msgstr "        algoritmy těchto ID uživatelů:\n"
+#~ msgstr "které nesjou k dispozici. Táká se to těchto user ID:\n"
 
 #~ msgid "general error"
 #~ msgstr "obecná chyba"
@@ -8408,6 +8476,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "neplatný paket"
 
+#~ msgid "invalid armor"
+#~ msgstr "neplatný způsob reprezentace v ASCII"
+
 #~ msgid "no such user id"
 #~ msgstr "neexistuje uživatel s tímto id"
 
@@ -8417,6 +8488,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "je použit špatný tajný klíč"
 
+#~ msgid "not supported"
+#~ msgstr "nepodporováno"
+
 #~ msgid "bad key"
 #~ msgstr "špatný klíč"
 
@@ -8429,6 +8503,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "chyba při vytváření souboru"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "nesprávné heslo"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritmus veřejného klíče není implementován"
 
@@ -8498,8 +8575,9 @@ msgstr ""
 #~ msgid "no card"
 #~ msgstr "žádná karta"
 
+#, fuzzy
 #~ msgid "no data"
-#~ msgstr "žádná data"
+#~ msgstr "chybí podepsaná data\n"
 
 #~ msgid "ERROR: "
 #~ msgstr "CHYBA: "
@@ -8527,6 +8605,3 @@ msgstr ""
 
 #~ msgid "expired: %s)"
 #~ msgstr "platnost skončila: %s)"
-
-#~ msgid "this command has not yet been implemented\n"
-#~ msgstr "tento příkaz ještě nebyl implementován\n"
index f5a934b..5b3a05f 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -1,79 +1,29 @@
-# Dansk oversættelse af: / Danish translation of: GnuPG
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# Birger Langkjer, <birger.langkjer@image.dk>, 2000.
-# Kenneth Christiansen, kenneth@ripen.dk, 2000.
-# Joe Hansen, <joedalton2@yahoo.dk>, 2012, 2014.
-#
-# deadlock -> baglås
-# ownertrust -> ejertroværdighed (pålidelighed, tillid)
-# pinpad -> numerisk tastatur
-# record -> post
-# trust -> troværdig (pålidelig, tillid)
-# trustlist -> troværdig liste (betroet liste)
+# Dansk oversættelse af: / Danish translation of: GnuPG
+# Copyright (C) 2000 Free Software Foundation, Inc.
+# Birger Langkjer <birger.langkjer@image.dk>, 2000.
+# Kenneth Christiansen -- kenneth@ripen.dk, 2000.
+# -- puh'ha denne er lang...nå men det går da fremad ;-)
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg\n"
+"Project-Id-Version: gnupg 1.0.0h\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2014-11-16 20:27+0200\n"
-"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish@lists.debian.org>\n"
-"Language: da\n"
+"PO-Revision-Date: 2003-12-03 16:11+0100\n"
+"Last-Translator: Birger Langkjer <birger.langkjer@image.dk>\n"
+"Language-Team: Danish <dansk@klid.dk>\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#, c-format
+# er det klogt at oversætte TrustDB?
+#, fuzzy, c-format
 msgid "failed to acquire the pinentry lock: %s\n"
-msgstr "kunne ikke indhente pinentry-lås: %s\n"
-
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "_O.k."
-
-msgid "|pinentry-label|_Cancel"
-msgstr "_Afbryd"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "_O.k."
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "_O.k."
-
-msgid "|pinentry-label|PIN:"
-msgstr "PIN:"
-
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "_Afbryd"
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Vil du virkelig tilbagekalde de valgte undernøgler? (j/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "Enter new passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "Indtast ny adgangsfrase"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
-msgstr "Kvalitet:"
+msgstr ""
 
 #. TRANSLATORS: This string is a tooltip, shown by pinentry when
 #. hovering over the quality bar.  Please use an appropriate
@@ -83,182 +33,169 @@ msgstr "Kvalitet:"
 #. will be used.
 msgid "pinentry.qualitybar.tooltip"
 msgstr ""
-"Denne række indikerer kvaliteten for ovenstående angivne adgangskode.\n"
-"GnuPG anser en adgangskode for svag så længe den er rød.\n"
-"En stærk adgangskode opbygges ved at blande store bogstaver, tal og\n"
-"specialtegn. Spørg din administrator om mere præcis information om\n"
-"hvordan man anvender sikre adgangskoder."
 
 msgid ""
 "Please enter your PIN, so that the secret key can be unlocked for this "
 "session"
 msgstr ""
-"Indtast venligst din PIN, så at den hemmelige nøgle kan låses op for denne "
-"session"
 
 msgid ""
 "Please enter your passphrase, so that the secret key can be unlocked for "
 "this session"
 msgstr ""
-"Indtast din adgangsfrase, så at den hemmelige nøgle kan låses op for denne "
-"session"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
-msgstr "SETERROR %s (forsøg %d af %d)"
+msgstr ""
 
 msgid "PIN too long"
-msgstr "PIN er for lang"
+msgstr ""
 
 msgid "Passphrase too long"
-msgstr "Adgangsfrase er for lang"
+msgstr ""
 
+#, fuzzy
 msgid "Invalid characters in PIN"
-msgstr "Ugyldige tegn i PIN"
+msgstr "Ugyldige bogstaver i navn\n"
 
 msgid "PIN too short"
-msgstr "PIN er for kort"
+msgstr ""
 
+#, fuzzy
 msgid "Bad PIN"
-msgstr "Ugyldig PIN"
+msgstr "dårlig mpi"
 
+#, fuzzy
 msgid "Bad Passphrase"
-msgstr "Ugyldig adgangsfrase"
+msgstr "dårlig kodesætning"
 
+#, fuzzy
 msgid "Passphrase"
-msgstr "Adgangsfrase"
+msgstr "dårlig kodesætning"
 
-#, c-format
+#, fuzzy, c-format
 msgid "ssh keys greater than %d bits are not supported\n"
-msgstr "ssh-nøgler større end %d bit er ikke understøttet\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
-#, c-format
-msgid "can't create `%s': %s\n"
-msgstr "kan ikke oprette »%s«: %s\n"
+#, fuzzy, c-format
+msgid "can't create '%s': %s\n"
+msgstr "kan ikke oprette %s: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
-msgstr "kan ikke åbne »%s«: %s\n"
+msgid "can't open '%s': %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting serial number of card: %s\n"
-msgstr "fejl ved indhentelse af serielnummer for kort: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
 #, c-format
 msgid "detected card with S/N: %s\n"
-msgstr "detekteret kort med S/N: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting default authentication keyID of card: %s\n"
-msgstr "fejl ved indhentelse af standard-keyID for godkendelses af kort: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "no suitable card key found: %s\n"
-msgstr "ingen egnet kortnøgle fundet: %s\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "shadowing the key failed: %s\n"
-msgstr "skygge for nøgle mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key: %s\n"
-msgstr "fejl ved skrivning af nøgle: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 #, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr ""
-"En ssh-proces anmodte om brugen af nøgle%%0A  %s%%0A  (%s)%%0AØnsker du at "
-"tillade dette?"
-
-msgid "Allow"
-msgstr "Tillad"
-
-msgid "Deny"
-msgstr "Nægt"
-
-#, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
-msgstr "Indtast venligst adgangsfrasen for ssh-nøglen%%0A  %F%%0A  (%c)"
 
+#, fuzzy
 msgid "Please re-enter this passphrase"
-msgstr "Genindtast venligst denne adgangsfrase"
+msgstr "ændr kodesætningen"
 
 #, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
-"Indtast venligst en adgangsfrase for at beskytte den modtaget hemmelige nøgle"
-"%%0A   %s%%0A   %s%%0Ainden i gpg-agentens nøglelager"
 
 msgid "does not match - try again"
-msgstr "matcher ikke - prøv igen"
+msgstr ""
 
-#, c-format
+# er det klogt at oversætte TrustDB?
+#, fuzzy, c-format
 msgid "failed to create stream from socket: %s\n"
-msgstr "kunne ikke oprette strøm fra sokkel: %s\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
 msgid "Please insert the card with serial number"
-msgstr "Indsæt venligst kortet med serielnummeret"
+msgstr ""
 
 msgid "Please remove the current card and insert the one with serial number"
-msgstr "Fjern venligst det aktuelle kort og indsæt det med serielnummeret"
+msgstr ""
 
+#, fuzzy
 msgid "Admin PIN"
-msgstr "Administrator-PIN"
+msgstr "Indtast bruger-id: "
 
 #. TRANSLATORS: A PUK is the Personal Unblocking Code
 #. used to unblock a PIN.
 msgid "PUK"
-msgstr "PUK"
+msgstr ""
 
 msgid "Reset Code"
-msgstr "Nulstillingskode"
+msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
-msgstr "%s%%0A%%0ABrug læserens numeriske tastatur for indtastning."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
+msgstr ""
 
+#, fuzzy
 msgid "Repeat this Reset Code"
-msgstr "Gentag denne nulstillingskode"
+msgstr "Gentag kodesætning: "
 
+#, fuzzy
 msgid "Repeat this PUK"
-msgstr "Gentag denne PUK"
+msgstr "Gentag kodesætning: "
 
+#, fuzzy
 msgid "Repeat this PIN"
-msgstr "Gentag denne PIN"
+msgstr "Gentag kodesætning: "
 
+#, fuzzy
 msgid "Reset Code not correctly repeated; try again"
-msgstr "Nulstillingskode er ikke korrekt gentaget; prøv igen"
+msgstr "kodesætningen blev ikke ordentlig gentaget; prøv igen.\n"
 
+#, fuzzy
 msgid "PUK not correctly repeated; try again"
-msgstr "PUK er ikke korrekt gentaget; prøv igen"
+msgstr "kodesætningen blev ikke ordentlig gentaget; prøv igen.\n"
 
+#, fuzzy
 msgid "PIN not correctly repeated; try again"
-msgstr "PIN er ikke korrekt gentaget; prøv igen"
+msgstr "kodesætningen blev ikke ordentlig gentaget; prøv igen.\n"
 
 #, c-format
 msgid "Please enter the PIN%s%s%s to unlock the card"
-msgstr "Indtast venligst PIN'en%s%s%s for at låse kortet op"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error creating temporary file: %s\n"
-msgstr "fejl ved oprettelse af midlertidig fil: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing to temporary file: %s\n"
-msgstr "fejl ved skrivning til midlertidig fil: %s\n"
+msgstr "skriver til `%s'\n"
 
+#, fuzzy
 msgid "Enter new passphrase"
-msgstr "Indtast ny adgangsfrase"
+msgstr "Indtast kodesætning: "
 
+#, fuzzy
 msgid "Take this one anyway"
-msgstr "Brug denne alligevel"
+msgstr "Brug denne nøgle alligevel? "
 
 #, c-format
 msgid ""
@@ -268,11 +205,7 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
 "at least %u characters long."
 msgstr[0] ""
-"Advarsel: Du har indtastet en usikker adgangsfrase.%%0AEn adgangsfrase skal "
-"være mindst %u tegn langt."
 msgstr[1] ""
-"Advarsel: Du har indtastet en usikker adgangsfrase.%%0AEn adgangsfrase skal "
-"være mindst %u tegn langt."
 
 #, c-format
 msgid ""
@@ -282,257 +215,250 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
 "contain at least %u digits or%%0Aspecial characters."
 msgstr[0] ""
-"Advarsel: Du har indtastet en usikker adgangsfrase.%%0AEn adgangsfrase skal "
-"indeholde mindst %u ciffer eller%%0specielt tegn."
 msgstr[1] ""
-"Advarsel: Du har indtastet en usikker adgangsfrase.%%0AEn adgangsfrase skal "
-"indeholde mindst %u cifre eller%%0specielle tegn."
 
 #, c-format
 msgid ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
 "a known term or match%%0Acertain pattern."
 msgstr ""
-"Advarsel: Du har indtastet en usikker adgangsfrase.%%0AEn adgangsfrase må "
-"ikke være en kendt term eller matche%%0Aet bestemt mønster."
 
 #, c-format
 msgid ""
 "You have not entered a passphrase!%0AAn empty passphrase is not allowed."
 msgstr ""
-"Du har ikke indtastet en adgangsfrase!%0AEn tom adgangsfrase er ikke tilladt."
 
 #, c-format
 msgid ""
 "You have not entered a passphrase - this is in general a bad idea!%0APlease "
 "confirm that you do not want to have any protection on your key."
 msgstr ""
-"Du har ikke indtastet en adgangsfrase - dette er generelt en dårlig ide!"
-"%0ABekræft venligst at du ikke ønsker beskyttelse på din nøgle."
 
 msgid "Yes, protection is not needed"
-msgstr "Ja, beskyttelse er ikke krævet"
+msgstr ""
 
-#, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
-msgstr "Indtast venligst adgangsfrasen %0Afor at beskytte din nye nøgle"
+#, fuzzy, c-format
+msgid "Please enter the passphrase to%0Ato protect your new key"
+msgstr ""
+"Du skal bruge en kodesætning til at beskytte din hemmelige nøgle.\n"
+"\n"
 
+#, fuzzy
 msgid "Please enter the new passphrase"
-msgstr "Indtast venligst den nye adgangsfrase"
+msgstr "ændr kodesætningen"
 
+#, fuzzy
 msgid ""
 "@Options:\n"
 " "
 msgstr ""
-"@Indstillinger:\n"
+"@\n"
+"Indstillinger:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "kør i dæmontilstand (baggrunden)"
-
 msgid "run in server mode (foreground)"
-msgstr "kør i servertilstand (forgrunden)"
+msgstr ""
+
+msgid "run in daemon mode (background)"
+msgstr ""
 
 msgid "verbose"
-msgstr "uddybende"
+msgstr "meddelsom"
 
 msgid "be somewhat more quiet"
-msgstr "vær mindre uddybende"
+msgstr "vær mere stille"
 
 msgid "sh-style command output"
-msgstr "kommandoresultat i sh-stil"
+msgstr ""
 
 msgid "csh-style command output"
-msgstr "kommandoresultat i csh-stil"
+msgstr ""
 
+#, fuzzy
 msgid "|FILE|read options from FILE"
-msgstr "|FIL|læs tilvalg fra FIL"
+msgstr "|FILE|indlæs udvidelsesmodul FILE"
 
 msgid "do not detach from the console"
-msgstr "frakobl ikke fra konsollen"
+msgstr ""
 
 msgid "do not grab keyboard and mouse"
-msgstr "fang ikke tastatur og mus"
+msgstr ""
 
+#, fuzzy
 msgid "use a log file for the server"
-msgstr "brug en logfil for serveren"
+msgstr "eksportér nøgler til en nøgletjener"
 
+#, fuzzy
 msgid "use a standard location for the socket"
-msgstr "brug en standardplacering for soklen"
+msgstr "Generér en annullérbar certifikat"
 
 msgid "|PGM|use PGM as the PIN-Entry program"
-msgstr "|PGM|brug PGM som PIN-Entry-program"
+msgstr ""
 
 msgid "|PGM|use PGM as the SCdaemon program"
-msgstr "|PGM|brug PGM som SCdaemon-program"
+msgstr ""
 
+#, fuzzy
 msgid "do not use the SCdaemon"
-msgstr "brug ikke SCdaemon'en"
+msgstr "opdatér tillidsdatabasen"
 
 msgid "ignore requests to change the TTY"
-msgstr "ignorer forespørgsler om at ændre TTY'en"
+msgstr ""
 
 msgid "ignore requests to change the X display"
-msgstr "ignorer forespørgsler om at ændre X-skærmen"
+msgstr ""
 
 msgid "|N|expire cached PINs after N seconds"
-msgstr "|N|udløb mellemlagrede PIN'er efter N sekunder"
+msgstr ""
 
 msgid "do not use the PIN cache when signing"
-msgstr "brug ikke PIN-mellemlageret når der underskrives"
+msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
-msgstr "tillad ikke at klienter markerer nøgler som »trusted« (troværdige)"
+msgid "allow clients to mark keys as \"trusted\""
+msgstr ""
 
+#, fuzzy
 msgid "allow presetting passphrase"
-msgstr "tillad forhåndsindstilling af adgangsfrase"
-
-msgid "enable ssh support"
-msgstr "aktiver ssh-understøttelse"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-msgid "enable putty support"
-msgstr "aktiver putty-understøttelse"
-
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "tillad ikke genbrug af gamle adgangsfraser"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
-msgstr "|FIL|skriv også miljøindstillinger til FIL"
+msgstr ""
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
+#, fuzzy
 msgid "Please report bugs to <@EMAIL@>.\n"
-msgstr "Rapporter venligst fejl til <@EMAIL@>.\n"
+msgstr "Rapportér venligst fejl til <gnupg-bugs@gnu.org>.\n"
 
+#, fuzzy
 msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Brug: gpg-agent [tilvalg] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: gpg-agent [options] [command [args]]\n"
 "Secret key management for GnuPG\n"
 msgstr ""
-"Syntaks: gpg-agent [tilvalg] [kommando [parametre]]\n"
-"Hemmelig nøglehåndtering for GnuPG\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
-msgstr "ugyldigt fejlsøgningsniveau »%s« angivet\n"
+msgid "invalid debug-level '%s' given\n"
+msgstr ""
 
 #, c-format
 msgid "%s is too old (need %s, have %s)\n"
-msgstr "%s er for gammel (kræver %s, har %s)\n"
+msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
-msgstr "BEMÆRK: Ingen standardfil for tilvalg »%s«\n"
+msgid "NOTE: no default option file '%s'\n"
+msgstr "NOTITS: ingen standard alternativfil '%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
-msgstr "tilvalgsfil »%s«: %s\n"
+msgid "option file '%s': %s\n"
+msgstr "alternativfil`%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
-msgstr "læser tilvalg fra »%s«\n"
+msgid "reading options from '%s'\n"
+msgstr "læser indstillinger fra `%s'\n"
 
-#, c-format
-msgid "error creating `%s': %s\n"
-msgstr "fejl ved oprettelse af »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error creating '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "kan ikke oprette mappe »%s«: %s\n"
+#, fuzzy, c-format
+msgid "can't create directory '%s': %s\n"
+msgstr "%s: kan ikke oprette mappe: %s\n"
 
 msgid "name of socket too long\n"
-msgstr "sokkelnavnet er for langt\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't create socket: %s\n"
-msgstr "kan ikke oprette sokkel: %s\n"
+msgstr "kan ikke oprette %s: %s\n"
 
-#, c-format
-msgid "socket name `%s' is too long\n"
-msgstr "sokkelnavnet »%s« er for langt\n"
+#, fuzzy, c-format
+msgid "socket name '%s' is too long\n"
+msgstr "certifikatlæseproblem: %s\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
-msgstr "en gpg-agent kører allerede - starter ikke en ny\n"
+msgstr ""
 
+#, fuzzy
 msgid "error getting nonce for the socket\n"
-msgstr "fejl ved indhentelse af nonce for soklen\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
-msgid "error binding socket to `%s': %s\n"
-msgstr "fejl ved binding af sokkel til »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error binding socket to '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "listen() failed: %s\n"
-msgstr "listen() mislykkedes: %s\n"
+msgstr "signering fejlede: %s\n"
 
-#, c-format
-msgid "listening on socket `%s'\n"
-msgstr "lytter på sokkel »%s«\n"
+#, fuzzy, c-format
+msgid "listening on socket '%s'\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
-#, c-format
-msgid "directory `%s' created\n"
-msgstr "mappe »%s« oprettet\n"
+#, fuzzy, c-format
+msgid "directory '%s' created\n"
+msgstr "%s: mappe oprettet\n"
 
-#, c-format
-msgid "stat() failed for `%s': %s\n"
-msgstr "stat() mislykkedes for »%s«: %s\n"
+#, fuzzy, c-format
+msgid "stat() failed for '%s': %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
-#, c-format
-msgid "can't use `%s' as home directory\n"
-msgstr "kan ikke bruge »%s« som hjemmemappe\n"
+#, fuzzy, c-format
+msgid "can't use '%s' as home directory\n"
+msgstr "%s: kan ikke oprette mappe: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading nonce on fd %d: %s\n"
-msgstr "fejl ved læsning af nonce på fd %d: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 #, c-format
 msgid "handler 0x%lx for fd %d started\n"
-msgstr "håndtering 0x%lx for fd %d startet\n"
+msgstr ""
 
 #, c-format
 msgid "handler 0x%lx for fd %d terminated\n"
-msgstr "håndtering 0x%lx for fd %d termineret\n"
+msgstr ""
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d started\n"
-msgstr "ssh-håndtering 0x%lx for fd %d startet\n"
+msgstr ""
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d terminated\n"
-msgstr "ssh-håndtering 0x%lx for %d termineret\n"
+msgstr ""
 
 #, c-format
 msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "pth_select mislykkeds: %s - venter 1s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s %s stopped\n"
-msgstr "%s %s stoppet\n"
+msgstr "%s: udelod: %s\n"
 
 msgid "no gpg-agent running in this session\n"
-msgstr "ingen gpg-agent kører i denne session\n"
+msgstr ""
 
 msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "forkert udformet GPG_AGENT_INFO-miljøvariabel\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "gpg-agent-protokolversion %d er ikke understøttet\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
+#, fuzzy
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
-msgstr "Brug: gpg-preset-passphrase [tilvalg] KEYGRIP (-h for hjælp)\n"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
 "Password cache maintenance\n"
 msgstr ""
-"Syntaks: gpg-preset-passphrase [tilvalg] KEYGRIP\n"
-"Adgangskode for mellemlagervedligeholdelse\n"
 
 msgid ""
 "@Commands:\n"
@@ -547,81 +473,75 @@ msgid ""
 " "
 msgstr ""
 "@\n"
-"Tilvalg:\n"
+"Indstillinger:\n"
 " "
 
+#, fuzzy
 msgid "Usage: gpg-protect-tool [options] (-h for help)\n"
-msgstr "Brug: gpg-protect-tool [tilvalg] (-h for hjælp)\n"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: gpg-protect-tool [options] [args]\n"
 "Secret key maintenance tool\n"
 msgstr ""
-"Syntaks: gpg-protect-tool [tilvalg] [parametre]\n"
-"Vedligeholdelsesværktøj for hemmelig nøgle\n"
 
 msgid "Please enter the passphrase to unprotect the PKCS#12 object."
 msgstr ""
-"Indtast venligst adgangsfrasen for at fjerne beskyttelsen på PKCS#12-"
-"objektet."
 
 msgid "Please enter the passphrase to protect the new PKCS#12 object."
-msgstr "Indtast venligst adgangsfrasen for at beskytte det nye PKCS#12-objekt."
+msgstr ""
 
 msgid ""
 "Please enter the passphrase to protect the imported object within the GnuPG "
 "system."
 msgstr ""
-"Indtast venligst adgangsfrasen for at beskytte det importeret objekt inden i "
-"GnuPG-systemet."
 
 msgid ""
 "Please enter the passphrase or the PIN\n"
 "needed to complete this operation."
 msgstr ""
-"Indtast venligst adgangsfrasen eller PIN'en\n"
-"krævet for at færdiggøre denne handling."
 
+#, fuzzy
 msgid "Passphrase:"
-msgstr "Adgangsfrase:"
+msgstr "dårlig kodesætning"
 
 msgid "cancelled\n"
-msgstr "afbrudt\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error while asking for the passphrase: %s\n"
-msgstr "fejl ved oprettelse af adgangsfrasen: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
-msgid "error opening `%s': %s\n"
-msgstr "fejl ved åbning af »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error opening '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
-msgid "file `%s', line %d: %s\n"
-msgstr "fil »%s«, linje %d: %s\n"
+#, fuzzy, c-format
+msgid "file '%s', line %d: %s\n"
+msgstr "%s: bruger ikke fundet: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
-msgstr "udtryk »%s« ignoreret i »%s«, linje %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
+msgstr ""
 
-#, c-format
-msgid "system trustlist `%s' not available\n"
-msgstr "troværdig liste for systemet »%s« er ikke tilgængelig\n"
+#, fuzzy, c-format
+msgid "system trustlist '%s' not available\n"
+msgstr "hemmelig nøgle ikke tilgængelig"
 
-#, c-format
-msgid "bad fingerprint in `%s', line %d\n"
-msgstr "ugyldigt fingeraftryk i »%s«, linje %d\n"
+#, fuzzy, c-format
+msgid "bad fingerprint in '%s', line %d\n"
+msgstr "panser: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
-msgstr "ugyldigt nøgleflag i »%s«, linje %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
+msgstr ""
 
-#, c-format
-msgid "error reading `%s', line %d: %s\n"
-msgstr "fejl ved læsning af »%s«, linje %d: %s\n"
+#, fuzzy, c-format
+msgid "error reading '%s', line %d: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
-msgstr "fejl ved læsning af liste over betroede rodcertifikater\n"
+msgstr ""
 
 #. TRANSLATORS: This prompt is shown by the Pinentry
 #. and has one special property: A "%%0A" is used by
@@ -636,14 +556,13 @@ msgid ""
 "Do you ultimately trust%%0A  \"%s\"%%0Ato correctly certify user "
 "certificates?"
 msgstr ""
-"Stoler du fuldstændig på at%%0A  \"%s\"%%0Akorrekt certificerer "
-"brugercertifikater?"
 
+#, fuzzy
 msgid "Yes"
-msgstr "Ja"
+msgstr "ja"
 
 msgid "No"
-msgstr "Nej"
+msgstr ""
 
 #. TRANSLATORS: This prompt is shown by the Pinentry and has
 #. one special property: A "%%0A" is used by Pinentry to
@@ -658,105 +577,103 @@ msgid ""
 "Please verify that the certificate identified as:%%0A  \"%s\"%%0Ahas the "
 "fingerprint:%%0A  %s"
 msgstr ""
-"Verificer venligst at certifikatet identificeres som:%%0A  \"%s\"%%0Ahar "
-"fingeraftrykket:%%0A  %s"
 
 #. TRANSLATORS: "Correct" is the label of a button and intended
 #. to be hit if the fingerprint matches the one of the CA.  The
 #. other button is "the default "Cancel" of the Pinentry.
 msgid "Correct"
-msgstr "Korrekt"
+msgstr ""
 
 msgid "Wrong"
-msgstr "Forkert"
+msgstr ""
 
 #, c-format
 msgid "Note: This passphrase has never been changed.%0APlease change it now."
-msgstr "Bemærk: Denne adgangsfrase er aldrig blevet ændret.%0AÆndr den nu."
+msgstr ""
 
 #, c-format
 msgid ""
 "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s.  Please change "
 "it now."
 msgstr ""
-"Denne adgangsfrase er ikke blevet ændret%%0Asiden %.4s-%.2s-%.2s. Ændr den "
-"nu."
 
+#, fuzzy
 msgid "Change passphrase"
-msgstr "Ændr adgangsfrasen"
+msgstr "ændr kodesætningen"
 
 msgid "I'll change it later"
-msgstr "Jeg ændrer den senere"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error creating a pipe: %s\n"
-msgstr "fejl ved oprettelse af datakanal: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't fdopen pipe for reading: %s\n"
-msgstr "kan ikke fdopen datakanal for læsning: %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error forking process: %s\n"
-msgstr "fejl ved forgrening af proces: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 #, c-format
 msgid "waiting for process %d to terminate failed: %s\n"
-msgstr "ventning på at proces %d skulle terminere mislykkedes: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting exit code of process %d: %s\n"
-msgstr "fejl ved indhentelse af afslutningskode for proces %d: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
-msgid "error running `%s': exit status %d\n"
-msgstr "fejl ved kørsel af »%s«: afslutningsstatus %d\n"
+#, fuzzy, c-format
+msgid "error running '%s': exit status %d\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "fejl ved kørsel af »%s«: sikkert ikke installeret\n"
+msgid "error running '%s': probably not installed\n"
+msgstr ""
 
-#, c-format
-msgid "error running `%s': terminated\n"
-msgstr "fejl ved kørsel af »%s«: termineret\n"
+#, fuzzy, c-format
+msgid "error running '%s': terminated\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error creating socket: %s\n"
-msgstr "fejl ved oprettelse af sokkel: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
+#, fuzzy
 msgid "host not found"
-msgstr "vært ikke fundet"
+msgstr "%s: bruger ikke fundet\n"
 
 msgid "gpg-agent is not available in this session\n"
-msgstr "gpg-agent er ikke tilgængelig i denne session\n"
+msgstr ""
 
-#, c-format
-msgid "can't connect to `%s': %s\n"
-msgstr "kan ikke forbinde til »%s«: %s\n"
+#, fuzzy, c-format
+msgid "can't connect to '%s': %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
-msgstr "kommunikationsproblem med gpg-agent\n"
+msgstr ""
 
 msgid "problem setting the gpg-agent options\n"
-msgstr "problem ved angivelse af indstillinger for gpg-agent\n"
+msgstr ""
 
 msgid "canceled by user\n"
-msgstr "afbrudt af brugeren\n"
+msgstr ""
 
 msgid "problem with the agent\n"
-msgstr "problem med agenten\n"
+msgstr ""
 
 #, c-format
 msgid "can't disable core dumps: %s\n"
-msgstr "kan ikke slå kernedump fra: %s\n"
+msgstr "kan ikke slå core-dump fra: %s\n"
 
 #, c-format
 msgid "Warning: unsafe ownership on %s \"%s\"\n"
-msgstr "Advarsel: usikker ejerskab på %s »%s«\n"
+msgstr ""
 
 #, c-format
 msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgstr "Advarsel: usikre rettigheder på %s »%s«\n"
+msgstr ""
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "yes"
@@ -781,178 +698,167 @@ msgstr "aA"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "okay|okay"
-msgstr "okay|okay|ok"
+msgstr ""
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "cancel|cancel"
-msgstr "afbryd|stop"
+msgstr ""
 
 msgid "oO"
-msgstr "oO"
+msgstr ""
 
+#, fuzzy
 msgid "cC"
-msgstr "cC"
+msgstr "c"
 
 #, c-format
 msgid "out of core in secure memory while allocating %lu bytes"
-msgstr "ikke nok kerne i sikker hukommelse under allokering af %lu byte"
+msgstr ""
 
 #, c-format
 msgid "out of core while allocating %lu bytes"
-msgstr "ikke nok kerne under allokering af %lu byte"
+msgstr ""
 
 msgid "no running gpg-agent - starting one\n"
-msgstr "ingen kørende gpg-agent - starter en\n"
-
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "venter %d sekunder på at agenten kommer frem\n"
+msgstr ""
 
 msgid "can't connect to the agent - trying fall back\n"
-msgstr "kan ikke forbinde til agenten - forsøger med reserven\n"
+msgstr ""
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
 msgid "|audit-log-result|Good"
-msgstr "|audit-log-result|Godt"
+msgstr ""
 
 msgid "|audit-log-result|Bad"
-msgstr "|audit-log-result|Ugyldigt"
+msgstr ""
 
 msgid "|audit-log-result|Not supported"
-msgstr "|audit-log-result|Ikke understøttet"
+msgstr ""
 
+#, fuzzy
 msgid "|audit-log-result|No certificate"
-msgstr "|audit-log-result|Intet certifikat"
+msgstr "Godt certifikat"
 
+#, fuzzy
 msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|Ikke aktiveret"
+msgstr "Godt certifikat"
 
 msgid "|audit-log-result|Error"
-msgstr "|audit-log-result|Fejl"
-
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|Ikke brugt"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|Okay"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|Udeladt"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|Lidt"
+msgstr ""
 
+#, fuzzy
 msgid "Certificate chain available"
-msgstr "Certifikatkæde er tilgængelig"
+msgstr "certifikatlæseproblem: %s\n"
 
+#, fuzzy
 msgid "root certificate missing"
-msgstr "rodcertifikat mangler"
+msgstr "Godt certifikat"
 
 msgid "Data encryption succeeded"
-msgstr "Datakryptering lykkedes"
+msgstr ""
 
+#, fuzzy
 msgid "Data available"
-msgstr "Data tilgængelig"
+msgstr "Ingen hjælp tilgængelig"
 
 msgid "Session key created"
-msgstr "Sessionsnøgle oprettet"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "algorithm: %s"
-msgstr "algoritme: %s"
+msgstr "panser: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "unsupported algorithm: %s"
-msgstr "ikke understøttet algoritme: %s"
+msgstr ""
+"\n"
+"Understøttede algoritmer:\n"
 
+#, fuzzy
 msgid "seems to be not encrypted"
-msgstr "ser ikke ud til at være krypteret"
+msgstr "ikke krypteret"
 
 msgid "Number of recipients"
-msgstr "Antal modtagere"
+msgstr ""
 
 #, c-format
 msgid "Recipient %d"
-msgstr "Modtager %d"
+msgstr ""
 
 msgid "Data signing succeeded"
-msgstr "Dataunderskrivning lykkedes"
-
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "hash-algoritme for data: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "Underskriver %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "hash-algoritme for attr: %s"
+msgstr ""
 
 msgid "Data decryption succeeded"
-msgstr "Datadekryptering lykkedes"
-
-msgid "Encryption algorithm supported"
-msgstr "Krypteringsalgoritme er ikke understøttet"
+msgstr ""
 
 msgid "Data verification succeeded"
-msgstr "Dataverifikation lykkedes"
+msgstr ""
 
+#, fuzzy
 msgid "Signature available"
-msgstr "Underskrift tilgængelig"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
-msgid "Parsing data succeeded"
-msgstr "Fortolkning af data lykkedes"
+#, fuzzy
+msgid "Parsing signature succeeded"
+msgstr "God signatur fra \""
 
-#, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "ugyldig hash-algoritme for data: %s"
+#, fuzzy, c-format
+msgid "Bad hash algorithm: %s"
+msgstr "ugyldig hash-algoritme `%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature %d"
-msgstr "Underskrift %d"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
+#, fuzzy
 msgid "Certificate chain valid"
-msgstr "Certifikatkæde er gyldig"
+msgstr "certifikatlæseproblem: %s\n"
 
+#, fuzzy
 msgid "Root certificate trustworthy"
-msgstr "Rodcertifikat er troværdigt"
+msgstr "Godt certifikat"
 
+#, fuzzy
 msgid "no CRL found for certificate"
-msgstr "ingen CRL fundet for certifikat"
+msgstr "Godt certifikat"
 
+#, fuzzy
 msgid "the available CRL is too old"
-msgstr "den tilgængelige CRL er for gammel"
+msgstr "Ingen hjælp tilgængelig"
 
+#, fuzzy
 msgid "CRL/OCSP check of certificates"
-msgstr "CRL/OCSP-kontrol af certifikater"
+msgstr "Godt certifikat"
 
+#, fuzzy
 msgid "Included certificates"
-msgstr "Inkluderede certifikater"
+msgstr "Godt certifikat"
 
 msgid "No audit log entries."
-msgstr "Ingen punkter i revisionslog."
+msgstr ""
 
+#, fuzzy
 msgid "Unknown operation"
-msgstr "Ukendt handling"
+msgstr "ukendt version"
 
 msgid "Gpg-Agent usable"
-msgstr "Gpg-Agent er brugbar"
+msgstr ""
 
 msgid "Dirmngr usable"
-msgstr "Dirmngr er brugbar"
+msgstr ""
 
-#, c-format
-msgid "No help available for `%s'."
-msgstr "Ingen hjælp tilgængelig for »%s«."
+#, fuzzy, c-format
+msgid "No help available for '%s'."
+msgstr "Ingen hjælp tilgængelig for `%s'"
 
+#, fuzzy
 msgid "ignoring garbage line"
-msgstr "ignorerer affaldslinje"
+msgstr "fejl i trailerlinie\n"
 
+#, fuzzy
 msgid "[none]"
-msgstr "[ingen]"
+msgstr "ukendt version"
 
 #, c-format
 msgid "armor: %s\n"
@@ -965,23 +871,25 @@ msgid "armor header: "
 msgstr "panserhoved: "
 
 msgid "invalid clearsig header\n"
-msgstr "ugyldigt clearsig-hoved\n"
+msgstr ""
 
+#, fuzzy
 msgid "unknown armor header: "
-msgstr "ukendt panserhoved: "
+msgstr "panserhoved: "
 
 msgid "nested clear text signatures\n"
-msgstr "indlejrede underskrifter i klartekst\n"
+msgstr ""
 
+#, fuzzy
 msgid "unexpected armor: "
-msgstr "uventet panser: "
+msgstr "uforventet beskyttelse:"
 
 msgid "invalid dash escaped line: "
-msgstr "ugyldig striplet undvegen linje: "
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "invalid radix64 character %02X skipped\n"
-msgstr "ugyldigt radix64-tegn %02x udeladt\n"
+msgstr "ugyldigt radix64 tegn %02x udeladt\n"
 
 msgid "premature eof (no CRC)\n"
 msgstr "for tidlig eof (ingen CRC)\n"
@@ -990,224 +898,235 @@ msgid "premature eof (in CRC)\n"
 msgstr "for tidlig eof (i CRC)\n"
 
 msgid "malformed CRC\n"
-msgstr "ugyldig udformet CRC\n"
+msgstr "dårlig CRC\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "CRC error; %06lX - %06lX\n"
-msgstr "CRC-fejl; %06lx - %06lx\n"
+msgstr "CRC fejl; %06lx - %06lx\n"
 
+#, fuzzy
 msgid "premature eof (in trailer)\n"
 msgstr "for tidlig eof (i trailer)\n"
 
 msgid "error in trailer line\n"
-msgstr "fejl i trailerlinje\n"
+msgstr "fejl i trailerlinie\n"
 
 msgid "no valid OpenPGP data found.\n"
-msgstr "ingen gyldige OpenPGP-data fundet.\n"
+msgstr "ingen gyldig OpenPGP data fundet.\n"
 
 #, c-format
 msgid "invalid armor: line longer than %d characters\n"
-msgstr "ugyldigt panser: linje længere end %d tegn\n"
+msgstr "ugyldigt panser: linie længere end %d tegn\n"
 
 msgid ""
 "quoted printable character in armor - probably a buggy MTA has been used\n"
-msgstr ""
-"citeret udskrivingstegn i panser - måske på grund af en fejlbehæftet MTA\n"
+msgstr "quoted printable-tegn i panser - måske pga. en fejlbehæftet MTA\n"
 
 msgid ""
 "a notation name must have only printable characters or spaces, and end with "
 "an '='\n"
 msgstr ""
-"et notationsnavn må kun have udskrivningstegn eller mellemrum og skal "
-"sluttes med et »=«\n"
 
+#, fuzzy
 msgid "a user notation name must contain the '@' character\n"
-msgstr "et brugernotationsnavn skal indeholde tegnet »@«\n"
+msgstr "en notationsværdi må ikke bruge nogen kontroltegn\n"
 
+#, fuzzy
 msgid "a notation name must not contain more than one '@' character\n"
-msgstr "et notationsnavn må ikke indeholde mere end et »@«-tegn\n"
+msgstr "en notationsværdi må ikke bruge nogen kontroltegn\n"
 
 msgid "a notation value must not use any control characters\n"
-msgstr "en notationsværdi må ikke bruge nogen kontroltegn\n"
+msgstr "en notationsværdi må ikke bruge nogen kontroltegn\n"
 
+#, fuzzy
 msgid "WARNING: invalid notation data found\n"
-msgstr "ADVARSEL: Ingen notationsdata fundet\n"
+msgstr "ingen gyldig OpenPGP data fundet.\n"
 
 msgid "not human readable"
-msgstr "kan ikke læses af mennesker"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "OpenPGP card not available: %s\n"
-msgstr "OpenPGP-kort er ikke tilgængeligt: %s\n"
+msgstr "hemmelig nøgle ikke tilgængelig"
 
 #, c-format
 msgid "OpenPGP card no. %s detected\n"
-msgstr "OpenPGP-kortnr. %s detekteret\n"
+msgstr ""
 
 msgid "can't do this in batch mode\n"
-msgstr "kan ikke udføre dette i jobtilstand\n"
+msgstr ""
 
 msgid "This command is only available for version 2 cards\n"
-msgstr "Denne kommando er kun tilgængelig for version 2-kort\n"
+msgstr ""
 
+#, fuzzy
 msgid "Reset Code not or not anymore available\n"
-msgstr "Nulstillingskode er ikke eller ikke mere tilgængelig\n"
+msgstr "hemmelig nøgle ikke tilgængelig"
 
 msgid "Your selection? "
 msgstr "Dit valg? "
 
 msgid "[not set]"
-msgstr "[ikke indstillet]"
+msgstr ""
 
+#, fuzzy
 msgid "male"
-msgstr "mand"
+msgstr "slåtil"
 
+#, fuzzy
 msgid "female"
-msgstr "kvinde"
+msgstr "slåtil"
 
 msgid "unspecified"
-msgstr "ikke angivet"
+msgstr ""
 
+#, fuzzy
 msgid "not forced"
-msgstr "ikke tvunget"
+msgstr "ikke bearbejdet"
 
 msgid "forced"
-msgstr "tvunget"
+msgstr ""
 
 msgid "Error: Only plain ASCII is currently allowed.\n"
-msgstr "Fejl: Kun ren ASCII er tilladt i øjeblikket.\n"
+msgstr ""
 
 msgid "Error: The \"<\" character may not be used.\n"
-msgstr "Fejl: Tegnet »<« må ikke bruges.\n"
+msgstr ""
 
 msgid "Error: Double spaces are not allowed.\n"
-msgstr "Fejl: Dobbelt mellemrum er ikke tilladt.\n"
+msgstr ""
 
 msgid "Cardholder's surname: "
-msgstr "Kortholders efternavn: "
+msgstr ""
 
 msgid "Cardholder's given name: "
-msgstr "Kortholders fornavn: "
+msgstr ""
 
 #, c-format
 msgid "Error: Combined name too long (limit is %d characters).\n"
-msgstr "Fejl: Kombineret navn er for langt (begrænsningen er på %d tegn).\n"
+msgstr ""
 
+#, fuzzy
 msgid "URL to retrieve public key: "
-msgstr "Adresse hvor offentlig nøgle skal hentes: "
+msgstr "skriver offentligt certifikat til '%s'\n"
 
 #, c-format
 msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Fejl: Adresse er for lang (begrænsningen er %d tegn).\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error allocating enough memory: %s\n"
-msgstr "fejl ved allokering af nok hukommelse: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
-msgstr "fejl ved læsning af »%s«: %s\n"
+msgid "error reading '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
-msgid "error writing `%s': %s\n"
-msgstr "fejl ved skrivning af »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error writing '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 msgid "Login data (account name): "
-msgstr "Loginddata (kontonavn): "
+msgstr ""
 
 #, c-format
 msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Fejl: Loginddata er for lange (begrænsningen er %d tegn).\n"
+msgstr ""
 
 msgid "Private DO data: "
-msgstr "Private DO-data: "
+msgstr ""
 
 #, c-format
 msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Fejl: Privat DO er for lang (begrænsningen er %d tegn).\n"
+msgstr ""
 
+#, fuzzy
 msgid "Language preferences: "
-msgstr "Sprogpræferencer: "
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "Error: invalid length of preference string.\n"
-msgstr "Fejl: ugyldig længde for præferencestreng.\n"
+msgstr "Ugyldige bogstaver i navn\n"
 
+#, fuzzy
 msgid "Error: invalid characters in preference string.\n"
-msgstr "Fejl: ugyldige tegn i præferencestreng.\n"
+msgstr "Ugyldige bogstaver i navn\n"
 
 msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Køn ((M)and, Kvinde(F) eller mellemrum): "
+msgstr ""
 
+#, fuzzy
 msgid "Error: invalid response.\n"
-msgstr "Fejl: ugyldigt svar.\n"
+msgstr "fejl i trailerlinie\n"
 
+#, fuzzy
 msgid "CA fingerprint: "
-msgstr "CA-fingeraftryk: "
+msgstr "Fingeraftryk:"
 
+#, fuzzy
 msgid "Error: invalid formatted fingerprint.\n"
-msgstr "Fejl: Ugyldigt formateret fingeraftryk.\n"
+msgstr "fejl i trailerlinie\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key operation not possible: %s\n"
-msgstr "nøglehandling er ikke mulig: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
+#, fuzzy
 msgid "not an OpenPGP card"
-msgstr "ikke et OpenPGP-kort"
+msgstr "ingen gyldig OpenPGP data fundet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting current key info: %s\n"
-msgstr "fejl ved indhentelse af aktuel nøgleinformation: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
+#, fuzzy
 msgid "Replace existing key? (y/N) "
-msgstr "Erstat eksisterende nøgle? (j/N) "
+msgstr "Vil du gerne signere? "
 
 msgid ""
 "NOTE: There is no guarantee that the card supports the requested size.\n"
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
-"BEMÆRK: Der er ingen garanti for at kortet understøtter den ønskede\n"
-"        størrelse. Hvis nøgleoprettelsen ikke lykkes, så kontroller\n"
-"        dokumentationen for dit kort for at se hvilke størrelser, der\n"
-"        er tilladt.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "Hvilken nøglestørrelse ønsker du for underskriftsnøglen (%u) "
+msgstr "Hvilken nøglestørrelse ønsker du? (1024) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "Hvilken nøglestørrelse ønsker du for krypteringsnøglen? (%u) "
+msgstr "Hvilken nøglestørrelse ønsker du? (1024) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "Hvilken nøglestørrelse ønsker du for godkendelsesnøglen? (%u) "
+msgstr "Hvilken nøglestørrelse ønsker du? (1024) "
 
 #, c-format
 msgid "rounded up to %u bits\n"
-msgstr "afrundet op til %u bit\n"
+msgstr "rundet op til %u bit\n"
 
 #, c-format
 msgid "%s keysizes must be in the range %u-%u\n"
-msgstr "%s nøglestørrelser skal være i intervallet %u-%u\n"
+msgstr ""
 
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
-msgstr "Kortet vil nu blive omkonfigureret til at oprette en nøgle på %u bit\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
-msgstr "fejl ved ændring af størrelsen på nøglen %d til %u bit: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr ""
-"Lav sikkerhedskopi et andet sted end på kortet for krypteringsnøglen? (J/n) "
 
+#, fuzzy
 msgid "NOTE: keys are already stored on the card!\n"
-msgstr "BEMÆRK: Nøgler er allerede gemt på kortet!\n"
+msgstr "udelod: hemmelig nøgle er allerede tilstede\n"
 
+#, fuzzy
 msgid "Replace existing keys? (y/N) "
-msgstr "Erstat eksisterende nøgler (j/N) "
+msgstr "Vil du gerne signere? "
 
 #, c-format
 msgid ""
@@ -1215,477 +1134,492 @@ msgid ""
 "   PIN = `%s'     Admin PIN = `%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
-"Bemærk venligst at fabriksindstillingerne for PIN'erne er\n"
-"   PIN = »%s«     Admin-PIN = »%s«\n"
-"Du bør ændre dem med kommandoen --change-pin\n"
 
+#, fuzzy
 msgid "Please select the type of key to generate:\n"
-msgstr "Vælg venligst hvilken slags nøgle der skal oprettes:\n"
+msgstr "Vælg venligst hvilken slags nøgle du vil have:\n"
 
+#, fuzzy
 msgid "   (1) Signature key\n"
-msgstr "   (1) Underskriftsnøgle\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
+#, fuzzy
 msgid "   (2) Encryption key\n"
-msgstr "   (2) Krypteringsnøgle\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
 msgid "   (3) Authentication key\n"
-msgstr "   (3) Godkendelsesnøgle\n"
+msgstr ""
 
 msgid "Invalid selection.\n"
 msgstr "Ugyldigt valg.\n"
 
+#, fuzzy
 msgid "Please select where to store the key:\n"
-msgstr "Vælg venligst hvor nøglen skal gemmes:\n"
+msgstr "rev- forkert nøgletilbagekald\n"
 
+#, fuzzy
 msgid "unknown key protection algorithm\n"
-msgstr "ukendt nøglebeskyttelsessalgoritme\n"
+msgstr "ukendt kompressionsalgoritme"
 
+#, fuzzy
 msgid "secret parts of key are not available\n"
-msgstr "hemmelige dele af nøglen er ikke tilgængelige\n"
+msgstr "hemmelig nøgle ikke tilgængelig"
 
+#, fuzzy
 msgid "secret key already stored on a card\n"
-msgstr "hemmelig nøgle er allerede gemt på et kort\n"
+msgstr "udelod: hemmelig nøgle er allerede tilstede\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key to card: %s\n"
-msgstr "fejl ved skrivning af nøgle til kort: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 msgid "quit this menu"
 msgstr "afslut denne menu"
 
+#, fuzzy
 msgid "show admin commands"
-msgstr "vis administratorkommandoer"
+msgstr "konfliktende kommandoer\n"
 
 msgid "show this help"
-msgstr "vis denne hjælpetekst"
+msgstr "vis denne hjælp"
 
+#, fuzzy
 msgid "list all available data"
-msgstr "vis alle tilgængelige data"
+msgstr "Ingen hjælp tilgængelig"
 
 msgid "change card holder's name"
-msgstr "ændr kortholders navn"
+msgstr ""
 
 msgid "change URL to retrieve key"
-msgstr "ændr adresse for at indhente nøgle"
+msgstr ""
 
 msgid "fetch the key specified in the card URL"
-msgstr "hent nøglen angivet i kortadressen"
+msgstr ""
 
+#, fuzzy
 msgid "change the login name"
-msgstr "ændr logindnavnet"
+msgstr "ændr udløbsdatoen"
 
+#, fuzzy
 msgid "change the language preferences"
-msgstr "ændr sprogpræferencerne"
+msgstr "vis præferencer"
 
 msgid "change card holder's sex"
-msgstr "ændr kortholders køn"
+msgstr ""
 
+#, fuzzy
 msgid "change a CA fingerprint"
-msgstr "ændr et CA-fingeraftryk"
+msgstr "vis fingeraftryk"
 
 msgid "toggle the signature force PIN flag"
-msgstr "skift force PIN-flag for underskriften"
+msgstr ""
 
+#, fuzzy
 msgid "generate new keys"
-msgstr "opret nye nøgler"
+msgstr "generér et nyt nøglepar"
 
 msgid "menu to change or unblock the PIN"
-msgstr "menu til at ændre eller fjerne blokering for PIN'en"
+msgstr ""
 
 msgid "verify the PIN and list all data"
-msgstr "verificer PIN'en og vis alle data"
+msgstr ""
 
 msgid "unblock the PIN using a Reset Code"
-msgstr "fjern blokering for PIN'en med en nulstillingskode"
+msgstr ""
 
-msgid "gpg/card> "
-msgstr "gpg/card> "
+msgid "Command> "
+msgstr ""
 
+#, fuzzy
 msgid "Admin-only command\n"
-msgstr "Kommandoer kun for administratoren\n"
+msgstr "konfliktende kommandoer\n"
 
+#, fuzzy
 msgid "Admin commands are allowed\n"
-msgstr "Administratorkommandoer er tilladt\n"
+msgstr "konfliktende kommandoer\n"
 
+#, fuzzy
 msgid "Admin commands are not allowed\n"
-msgstr "Administratorkommandoer er ikke tilladt\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
 msgid "Invalid command  (try \"help\")\n"
-msgstr "Ugyldig kommando (prøv »help«)\n"
+msgstr ""
 
 msgid "--output doesn't work for this command\n"
-msgstr "--output virker ikke for denne kommando\n"
+msgstr ""
 
 #, c-format
-msgid "can't open `%s'\n"
-msgstr "kan ikke åbne »%s«\n"
+msgid "can't open '%s'\n"
+msgstr "kan ikke åbne `%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key \"%s\" not found: %s\n"
-msgstr "nøglen »%s« blev ikke fundet: %s\n"
+msgstr "%s: bruger ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading keyblock: %s\n"
-msgstr "fejl ved læsning af nøgleblok: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "(unless you specify the key by fingerprint)\n"
-msgstr "(med mindre du angiver nøglen med fingeraftryk)\n"
+msgstr ""
 
 msgid "can't do this in batch mode without \"--yes\"\n"
-msgstr "kan ikke udføre dette i jobtilstand uden »--yes«\n"
+msgstr ""
 
+#, fuzzy
 msgid "Delete this key from the keyring? (y/N) "
-msgstr "Slet denne nøgle fra nøgleringen? (j/N) "
+msgstr "Slet denne nøgle fra nøgleringen? "
 
 msgid "This is a secret key! - really delete? (y/N) "
-msgstr "Dette er en hemmelig nøgle! - Slet? (j/N) "
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "deleting keyblock failed: %s\n"
-msgstr "sletning af nøgleblok mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
 msgid "ownertrust information cleared\n"
-msgstr "information om ejertroværdighed ryddet\n"
+msgstr ""
 
 #, c-format
 msgid "there is a secret key for public key \"%s\"!\n"
-msgstr "der er en hemmelig nøgle for offentlig nøgle »%s«!\n"
+msgstr ""
 
 msgid "use option \"--delete-secret-keys\" to delete it first.\n"
-msgstr "brug tilvalget »--delete-secret-keys« for at slette den først.\n"
+msgstr ""
 
 #, c-format
 msgid "error creating passphrase: %s\n"
-msgstr "fejl ved oprettelse af adgangsfrase: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
 msgid "can't use a symmetric ESK packet due to the S2K mode\n"
-msgstr "kan ikke bruge en symmetrisk ESK-pakke på grund af S2K-tilstanden\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "using cipher %s\n"
-msgstr "bruger chiffer %s\n"
+msgstr "signering fejlede: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
-msgstr "»%s« allerede komprimeret\n"
+msgid "'%s' already compressed\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
-msgstr "ADVARSEL: »%s« er en tom fil\n"
+msgid "WARNING: '%s' is an empty file\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr ""
-"du kan kun kryptere til RSA-nøgler for 2048 bit eller mindre i tilstanden --"
-"pgp2\n"
 
 #, c-format
-msgid "reading from `%s'\n"
-msgstr "læser fra »%s«\n"
+msgid "reading from '%s'\n"
+msgstr "læser fra '%s'\n"
 
 msgid ""
 "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
-msgstr "kan ikke bruge IDEA-chifferen for alle nøglerne du krypterer til.\n"
+msgstr ""
 
 #, c-format
 msgid ""
 "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
 msgstr ""
-"ADVARSEL: Tvang for symmetrisk chiffer %s (%d) overtræder modtagerens "
-"præferencer\n"
 
 #, c-format
 msgid ""
 "WARNING: forcing compression algorithm %s (%d) violates recipient "
 "preferences\n"
 msgstr ""
-"ADVARSEL: Tvang for komprimeringsalgoritme %s (%d) overtræder modtagerens "
-"præferencer\n"
 
 #, c-format
 msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n"
 msgstr ""
-"tvang for symmetrisk chiffer %s (%d) overtræder modtagerens præferencer\n"
 
 #, c-format
 msgid "you may not use %s while in %s mode\n"
-msgstr "du kan ikke bruge %s i tilstanden %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s/%s encrypted for: \"%s\"\n"
-msgstr "%s/%s krypteret for: »%s«\n"
+msgstr "%s/%s krypteret for: %s\n"
 
 #, c-format
 msgid "%s encrypted data\n"
-msgstr "%s krypterede data\n"
+msgstr ""
 
 #, c-format
 msgid "encrypted with unknown algorithm %d\n"
-msgstr "krypteret med ukendt algoritme %d\n"
+msgstr ""
 
 msgid ""
 "WARNING: message was encrypted with a weak key in the symmetric cipher.\n"
 msgstr ""
-"ADVARSEL: Besked blev krypteret med en svag nøgle i den symmetriske "
-"chiffer.\n"
 
 msgid "problem handling encrypted packet\n"
-msgstr "problem ved håndtering af krypteret pakke\n"
+msgstr ""
 
 msgid "no remote program execution supported\n"
-msgstr "kørsel via eksternt program er ikke understøttet\n"
+msgstr ""
 
 msgid ""
 "external program calls are disabled due to unsafe options file permissions\n"
 msgstr ""
-"kald fra eksterne programmer er deaktiveret på grund af usikre rettigheder "
-"for indstillingsfil\n"
 
 msgid "this platform requires temporary files when calling external programs\n"
 msgstr ""
-"denne platform kræver midlertidige filer når der kaldes eksterne programmer\n"
 
-#, c-format
-msgid "unable to execute program `%s': %s\n"
-msgstr "kan ikke køre program »%s«: %s\n"
+#, fuzzy, c-format
+msgid "unable to execute program '%s': %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
-#, c-format
-msgid "unable to execute shell `%s': %s\n"
-msgstr "kan ikke køre skal »%s«: %s\n"
+#, fuzzy, c-format
+msgid "unable to execute shell '%s': %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
 #, c-format
 msgid "system error while calling external program: %s\n"
-msgstr "systemfejl under kald af eksternt program: %s\n"
+msgstr ""
 
 msgid "unnatural exit of external program\n"
-msgstr "unaturlig afslutning på eksternt program\n"
+msgstr ""
 
 msgid "unable to execute external program\n"
-msgstr "kan ikke køre eksternt program\n"
+msgstr ""
 
 #, c-format
 msgid "unable to read external program response: %s\n"
-msgstr "kan ikke læse svar fra eksternt program: %s\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
-msgstr "ADVARSEL: kan ikke fjerne midlertidig fil (%s) »%s«: %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
-msgstr "ADVARSEL: kan ikke fjerne midlertidig mappe »%s«: %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
+msgstr ""
 
+#, fuzzy
 msgid "export signatures that are marked as local-only"
-msgstr "eksportunderskrifter som er markeret som kun lokale"
+msgstr "signér nøglen lokalt"
 
 msgid "export attribute user IDs (generally photo IDs)"
-msgstr "bruger-id'er for eksportattributter (normalt billed-id'er)"
+msgstr ""
 
 msgid "export revocation keys marked as \"sensitive\""
-msgstr "tilbagekaldsnøgler for eksport markeret som »sensitive«"
+msgstr ""
 
 msgid "remove the passphrase from exported subkeys"
-msgstr "fjern adgangsfrasen fra eksporterede undernøgler"
+msgstr ""
 
+#, fuzzy
 msgid "remove unusable parts from key during export"
-msgstr "fjern nøgledele der ikke kan bruges under eksport"
+msgstr "dårlig hemmelig nøgle"
 
 msgid "remove as much as possible from key during export"
-msgstr "fjern så meget som muligt fra nøglen under eksport"
+msgstr ""
 
 msgid "export keys in an S-expression based format"
-msgstr "eksporter nøgler i et S-udtryksbaseret format"
+msgstr ""
 
+#, fuzzy
 msgid "exporting secret keys not allowed\n"
-msgstr "eksport af hemmelige nøgler er ikke tilladt\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: not protected - skipped\n"
-msgstr "nøgle %s: ikke beskyttet - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
-msgstr "nøgle %s: nøgle i PGP 2.x-stil - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: key material on-card - skipped\n"
-msgstr "nøgle %s: nøglemateriale på kort - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
 msgid "about to export an unprotected subkey\n"
-msgstr "eksporterer en ubeskyttet undernøgle\n"
+msgstr ""
 
-#, c-format
+# er det klogt at oversætte TrustDB?
+#, fuzzy, c-format
 msgid "failed to unprotect the subkey: %s\n"
-msgstr "kunne ikke fjerne beskyttelse på undernøgle: %s\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
 #, c-format
 msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr "ADVARSEL: hemmelig nøgle %s har ikke en simpel SK-kontrolsum\n"
+msgstr ""
 
 msgid "WARNING: nothing exported\n"
 msgstr "ADVARSEL: intet blev eksporteret\n"
 
 msgid "too many entries in pk cache - disabled\n"
-msgstr "for mange punkter i pk-mellemlager - deaktiveret\n"
+msgstr ""
 
+#, fuzzy
 msgid "[User ID not found]"
-msgstr "[Bruger-id blev ikke fundet]"
-
-#, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "nøgle %s: hemmelig nøgle uden offentlig nøgle - udeladt\n"
+msgstr "[bruger ikke fundet]"
 
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
-msgstr "hentede automatisk »%s« via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
+msgstr ""
 
-#, c-format
-msgid "error retrieving `%s' via %s: %s\n"
-msgstr "fejl ved indhentelse af »%s« via %s: %s\n"
+#, fuzzy, c-format
+msgid "error retrieving '%s' via %s: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
+#, fuzzy
 msgid "No fingerprint"
-msgstr "Ingen fingeraftryk"
+msgstr "Fingeraftryk:"
 
 #, c-format
 msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
-msgstr "Ugyldig nøgle %s gjort gyldig med --allow-non-selfsigned-uid\n"
+msgstr ""
 
 #, c-format
 msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "ingen hemmelig undernøgle for offentlig undernøgle %s - ignorerer\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "using subkey %s instead of primary key %s\n"
-msgstr "bruger undernøgle %s i stedet for primær nøgle %s\n"
+msgstr "bruger sekundær nøgle %08lX istedetfor primær nøgle %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
+
+#, fuzzy
 msgid "make a signature"
-msgstr "opret en underskrift"
+msgstr "opret en separat signatur"
 
+#, fuzzy
 msgid "make a clear text signature"
-msgstr "opret en underskrift i klartekst"
+msgstr "|[filer]|opret rentekst signatur"
 
 msgid "make a detached signature"
-msgstr "opret en separat underskrift"
+msgstr "opret en separat signatur"
 
 msgid "encrypt data"
-msgstr "krypter data"
+msgstr "kryptér data"
 
 msgid "encryption only with symmetric cipher"
-msgstr "krypter kun med symmetrisk chiffer"
+msgstr "kryptér kun med symmetriske cifre"
 
 msgid "decrypt data (default)"
-msgstr "afkrypter data (standard)"
+msgstr "afkryptér data (standard)"
 
 msgid "verify a signature"
-msgstr "godkend en underskrift"
+msgstr "godkend en signatur"
 
 msgid "list keys"
-msgstr "vis nøgler"
+msgstr "vis nøgler"
 
 msgid "list keys and signatures"
-msgstr "vis nøgler og underskrifter"
+msgstr "vis nøgler og signaturer"
 
+#, fuzzy
 msgid "list and check key signatures"
-msgstr "vis og kontroller nøgleunderskrifter"
+msgstr "tjek nøglesignaturer"
 
 msgid "list keys and fingerprints"
-msgstr "vis nøgler og fingeraftryk"
+msgstr "vis nøgle og fingeraftryk"
 
 msgid "list secret keys"
-msgstr "vis hemmelige nøgler"
+msgstr "vis hemmelige nøgler"
 
 msgid "generate a new key pair"
-msgstr "opret et nyt nøglepar"
-
-msgid "generate a revocation certificate"
-msgstr "opret et tilbagekaldscertifikat"
+msgstr "generér et nyt nøglepar"
 
+#, fuzzy
 msgid "remove keys from the public keyring"
-msgstr "fjern nøgler fra den offentlige nøglering"
+msgstr "fjern nøgle fra den offentlige nøglering"
 
+#, fuzzy
 msgid "remove keys from the secret keyring"
-msgstr "fjern nøgler fra den hemmelige nøglering"
+msgstr "fjern nøgle fra den hemmelige nøglering"
 
 msgid "sign a key"
-msgstr "underskriv en nøgle"
+msgstr "signér en nøgle"
 
 msgid "sign a key locally"
-msgstr "underskriv en nøgle lokalt"
+msgstr "signér en nøgle lokalt"
 
 msgid "sign or edit a key"
-msgstr "underskriv eller rediger en nøgle"
+msgstr "signér eller redigér en nøgle"
 
-msgid "change a passphrase"
-msgstr "ændr en adgangsfrase"
+msgid "generate a revocation certificate"
+msgstr "Generér en annullérbar certifikat"
 
 msgid "export keys"
-msgstr "eksporter nøgler"
+msgstr "eksportér nøgler"
 
 msgid "export keys to a key server"
-msgstr "eksporter nøgler til en nøgletjener"
+msgstr "eksportér nøgler til en nøgletjener"
 
 msgid "import keys from a key server"
-msgstr "importer nøgler fra en nøgleserver"
+msgstr "importér nøgler fra en nøgleserver"
 
+#, fuzzy
 msgid "search for keys on a key server"
-msgstr "søg efter nøgler på en nøgleserver"
+msgstr "eksportér nøgler til en nøgletjener"
 
+#, fuzzy
 msgid "update all keys from a keyserver"
-msgstr "opdater alle nøgler fra en nøgleserver"
+msgstr "importér nøgler fra en nøgleserver"
 
 msgid "import/merge keys"
-msgstr "importer/sammenføj nøgler"
+msgstr "importér/fusionér nøgler"
 
 msgid "print the card status"
-msgstr "udskriv kortstatus"
+msgstr ""
 
 msgid "change data on a card"
-msgstr "ændr data på et kort"
+msgstr ""
 
 msgid "change a card's PIN"
-msgstr "ændr et korts PIN"
+msgstr ""
 
 msgid "update the trust database"
-msgstr "opdater troværdighedsdatabasen"
+msgstr "opdatér tillidsdatabasen"
 
+#, fuzzy
 msgid "print message digests"
-msgstr "vis beskedsammendrag"
+msgstr "|algo [filer]|print meddelelsesresumé"
 
 msgid "run in server mode"
-msgstr "kør i servertilstand"
+msgstr ""
 
 msgid "create ascii armored output"
-msgstr "opret ascii-pansrede uddata"
+msgstr "opret ascii beskyttet uddata"
 
+#, fuzzy
 msgid "|USER-ID|encrypt for USER-ID"
-msgstr "|USER-ID|krypter for BRUGER-ID"
+msgstr "|NAME|kryptér for NAME"
 
+#, fuzzy
 msgid "|USER-ID|use USER-ID to sign or decrypt"
-msgstr "|USER-ID|brug BRUGER-ID til at underskrive eller afkryptere"
+msgstr "brug denne bruger-id til at signere eller dekryptere"
 
+#, fuzzy
 msgid "|N|set compress level to N (0 disables)"
-msgstr "|N|sæt komprimeringsniveauet til N (0 deaktiverer)"
+msgstr "|N|sæt kompresningsniveau N (0 = slået fra)"
 
 msgid "use canonical text mode"
-msgstr "brug kanonisk teksttilstand"
+msgstr "brug kanonisk tekstmodus"
 
+#, fuzzy
 msgid "|FILE|write output to FILE"
-msgstr "|FILE|skriv resultat til FIL"
+msgstr "|FILE|indlæs udvidelsesmodul FILE"
 
 msgid "do not make any changes"
-msgstr "lav ingen ændringer"
+msgstr "lav ingen ændringer"
 
 msgid "prompt before overwriting"
-msgstr "spørg før overskrivning"
+msgstr ""
 
 msgid "use strict OpenPGP behavior"
-msgstr "brug streng OpenPGP-opførsel"
+msgstr ""
 
 msgid ""
 "@\n"
 "(See the man page for a complete listing of all commands and options)\n"
 msgstr ""
-"@\n"
-"(Se manualsiden for en fuldstændig liste over alle kommandoer og tilvalg)\n"
 
 msgid ""
 "@\n"
@@ -1700,251 +1634,262 @@ msgstr ""
 "@\n"
 "Eksempler:\n"
 "\n"
-" -se -r Mikael [fil]        underskriv og krypter for bruger Mikael\n"
-" --clearsign [fil]          lav en ren tekstunderskrift\n"
-" --detach-sign [fil]        lav en separat underskrift\n"
-" --list-keys [navne]        vis nøgler\n"
+" -se -r Mikael [fil]        signér og kryptér for bruger Mikael\n"
+" --clearsign [fil]          lav en ren tekstsignatur\n"
+" --detach-sign [fil]        lav en separat signatur\n"
+" --list-keys [navne]        vis nøgler\n"
 " --fingerprint [navne]      vis fingeraftryk\n"
 
 msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
-# Skal alt dette oversættes eller er det tilvalgene?
+# Skal alt dette oversættes eller er det flagene?
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
-"Syntaks: gpg [tilvalg] [filer]\n"
-"Sign, check, encrypt eller decrypt\n"
-"standardhandling afhænger af inddata\n"
+"Syntaks: gpg [flag] [filer]\n"
+"sign, check, encrypt eller decrypt\n"
+"standard operation afhænger af inddata\n"
 
 msgid ""
 "\n"
 "Supported algorithms:\n"
 msgstr ""
 "\n"
-"Understøttede algoritmer:\n"
+"Understøttede algoritmer:\n"
 
 msgid "Pubkey: "
-msgstr "Pubkey: "
+msgstr ""
 
 msgid "Cipher: "
-msgstr "Chiffer: "
+msgstr ""
 
 msgid "Hash: "
-msgstr "Hash: "
+msgstr ""
 
+#, fuzzy
 msgid "Compression: "
-msgstr "Komprimering: "
+msgstr "Kommentar: "
 
 msgid "usage: gpg [options] "
-msgstr "brug: gpg [tilvalg] "
+msgstr "brug: gpg [flag] "
 
 msgid "conflicting commands\n"
-msgstr "kommandoer er i konflikt\n"
+msgstr "konfliktende kommandoer\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
-msgstr "ingen = tegn fundet i gruppedefinition »%s«\n"
+msgid "no = sign found in group definition '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
-msgstr "ADVARSEL: Usikker ejerskab af hjemmemappe »%s«\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
-msgstr "ADVARSEL: Usikker ejerskab på konfigurationsfil »%s«\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
-msgstr "ADVARSEL: Usikker ejerskab på udvidelse »%s«\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
-msgstr "ADVARSEL: Usikre rettigheder på hjemmemappe »%s«\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
-msgstr "ADVARSEL: Usikre rettigheder på konfigurationsfil »%s«\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
-msgstr "ADVARSEL: Usikre rettigheder på udvidelse »%s«\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
-msgstr "ADVARSEL: Usikkert indelukket mappeejerskab på hjemmemappe »%s«\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
+msgstr ""
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
 msgstr ""
-"ADVARSEL: Usikkert indelukket mappeejerskab på konfigurationsfil »%s«\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
-msgstr "ADVARSEL: Usikkert indelukket mappeejerskab på udvidelse »%s«\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
-msgstr "ADVARSEL: Usikre indelukkede mapperettigheder på hjemmemappe »%s«\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
+msgstr ""
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
 msgstr ""
-"ADVARSEL: Usikre indelukkede mapperettigheder på konfigurationsfil »%s«\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
-msgstr "ADVARSEL: Usikkert indelukket mapperettigheder på udvidelse »%s«\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
+msgstr ""
 
-#, c-format
-msgid "unknown configuration item `%s'\n"
-msgstr "ukendt konfigurationspunkt »%s«\n"
+#, fuzzy, c-format
+msgid "unknown configuration item '%s'\n"
+msgstr "ukendt standard modtager '%s'\n"
 
 msgid "display photo IDs during key listings"
-msgstr "vis billed-id'er under nøglevisninger"
+msgstr ""
 
 msgid "show policy URLs during signature listings"
-msgstr "vil politikadresser under underskriftvisninger"
+msgstr ""
 
 msgid "show all notations during signature listings"
-msgstr "vis alle notationer under underskriftvisninger"
+msgstr ""
 
 msgid "show IETF standard notations during signature listings"
-msgstr "vis IETF-standardnotationer under underskriftvisninger"
+msgstr ""
 
 msgid "show user-supplied notations during signature listings"
-msgstr "vis brugerangivne notationer under underskriftvisninger"
+msgstr ""
 
+#, fuzzy
 msgid "show preferred keyserver URLs during signature listings"
-msgstr "vis foretrukne nøgleserveradresser under underskriftvisninger"
+msgstr "den givne politik-URL er ugyldig\n"
 
 msgid "show user ID validity during key listings"
-msgstr "vis bruger-id-validitet under nøglevisninger"
+msgstr ""
 
 msgid "show revoked and expired user IDs in key listings"
-msgstr "vis tilbagekaldte og udløbne bruger-id'er i nøglevisninger"
+msgstr ""
 
 msgid "show revoked and expired subkeys in key listings"
-msgstr "vis tilbagekaldte og udløbne undernøgler i nøglevisninger"
+msgstr ""
 
+#, fuzzy
 msgid "show the keyring name in key listings"
-msgstr "vis nøgleringsnavnet i nøglevisninger"
+msgstr "skift imellem hemmelig og offentlig nøgle visning"
 
 msgid "show expiration dates during signature listings"
-msgstr "vis udløbsdatoer under underskriftvisninger"
+msgstr ""
 
-#, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
-msgstr "BEMÆRK: Gammel standardfil for tilvalg »%s« blev ignoreret\n"
+#, fuzzy, c-format
+msgid "NOTE: old default options file '%s' ignored\n"
+msgstr "NOTITS: ingen standard alternativfil '%s'\n"
 
 #, c-format
 msgid "libgcrypt is too old (need %s, have %s)\n"
-msgstr "libgcrypt er for gammel (kræver %s, har %s)\n"
+msgstr ""
 
 #, c-format
 msgid "NOTE: %s is not for normal use!\n"
-msgstr "BEMÆRK: %s er ikke til normal brug!\n"
+msgstr "NOTITS: %s er ikke til normal brug!\n"
 
-#, c-format
-msgid "`%s' is not a valid signature expiration\n"
-msgstr "»%s« er ikke et gyldigt underskriftudløb\n"
+#, fuzzy, c-format
+msgid "'%s' is not a valid signature expiration\n"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
-#, c-format
-msgid "`%s' is not a valid character set\n"
-msgstr "»%s« er ikke et gyldigt tegnsæt\n"
+#, fuzzy, c-format
+msgid "'%s' is not a valid character set\n"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
+#, fuzzy
 msgid "could not parse keyserver URL\n"
-msgstr "kunne ikke fortolke nøgleserveradresse\n"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: invalid keyserver options\n"
-msgstr "%s:%d: ugyldige indstillinger for nøgleserver\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
+#, fuzzy
 msgid "invalid keyserver options\n"
-msgstr "ugyldige indstillinger for nøgleserver\n"
+msgstr "ugyldig nøglering"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: invalid import options\n"
-msgstr "%s:%d: ugyldige importindstillinger\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
+#, fuzzy
 msgid "invalid import options\n"
-msgstr "ugyldige importindstillinger\n"
+msgstr "ugyldig rustning"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: invalid export options\n"
-msgstr "%s:%d: ugyldige eksportindstillinger\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
+#, fuzzy
 msgid "invalid export options\n"
-msgstr "ugyldige eksportindstillinger\n"
+msgstr "ugyldig nøglering"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: invalid list options\n"
-msgstr "%s:%d: ugyldige listeindstillinger\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
+#, fuzzy
 msgid "invalid list options\n"
-msgstr "ugyldige listeindstillinger\n"
+msgstr "ugyldig rustning"
 
 msgid "display photo IDs during signature verification"
-msgstr "vis billed-id'er under underskriftverificering"
+msgstr ""
 
 msgid "show policy URLs during signature verification"
-msgstr "vis politikadresser under underskriftverificering"
+msgstr ""
 
+#, fuzzy
 msgid "show all notations during signature verification"
-msgstr "vis alle notationer under underskriftverificering"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
 msgid "show IETF standard notations during signature verification"
-msgstr "vis IETF-standardnotationer under underskriftverificering"
+msgstr ""
 
 msgid "show user-supplied notations during signature verification"
-msgstr "vis brugerangivne notationer under underskriftverificering"
+msgstr ""
 
+#, fuzzy
 msgid "show preferred keyserver URLs during signature verification"
-msgstr "vis foretrukne nøgleserveradresser under underskriftverificering"
+msgstr "den givne politik-URL er ugyldig\n"
 
+#, fuzzy
 msgid "show user ID validity during signature verification"
-msgstr "vis bruger-id-validitet under underskriftverificering"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
 msgid "show revoked and expired user IDs in signature verification"
-msgstr "vis tilbagekaldte og udløbne bruger-id'er i underskriftverificering"
+msgstr ""
 
+#, fuzzy
 msgid "show only the primary user ID in signature verification"
-msgstr "vis kun den primære bruger-id i underskriftverificering"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
 msgid "validate signatures with PKA data"
-msgstr "valider underskrifter med PKA-data"
+msgstr ""
 
 msgid "elevate the trust of signatures with valid PKA data"
-msgstr "hæv troværdigheden for underskrifter med gyldige PKA-data"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: invalid verify options\n"
-msgstr "%s:%d: ugyldige verificeringsindstillinger\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
+#, fuzzy
 msgid "invalid verify options\n"
-msgstr "ugyldige verificeringsindstillinger\n"
+msgstr "ugyldig nøglering"
 
 #, c-format
 msgid "unable to set exec-path to %s\n"
-msgstr "kunne ikke angive kørselssti til %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: invalid auto-key-locate list\n"
-msgstr "%s:%d: ugyldig liste for auto-key-locate\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
 msgid "invalid auto-key-locate list\n"
-msgstr "ugyldig liste for auto-key-locate\n"
+msgstr ""
 
 msgid "WARNING: program may create a core file!\n"
-msgstr "ADVARSEL: program kan oprette en kernefil!\n"
+msgstr ""
 
 #, c-format
 msgid "WARNING: %s overrides %s\n"
-msgstr "ADVARSEL: %s overskriver %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s not allowed with %s!\n"
@@ -1952,143 +1897,151 @@ msgstr "%s ikke tilladt med %s!\n"
 
 #, c-format
 msgid "%s makes no sense with %s!\n"
-msgstr "%s er meningsløs sammen med %s!\n"
+msgstr "%s er meningsløs sammen med %s!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "will not run with insecure memory due to %s\n"
-msgstr "vil ikke køre med usikker hukommelse på grund af %s\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
 msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
 msgstr ""
-"du kan kun lave frakoblede eller rydde underskrifter i tilstanden --pgp2\n"
 
 msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr "du kan ikke underskrive og kryptere på samme tid i tilstanden --pgp2\n"
+msgstr ""
 
 msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
 msgstr ""
-"du skal bruge filer (og ikke en datakanal) når du arbejder med --pgp2 "
-"aktiveret\n"
 
 msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr "kryptering af en besked i tilstanden --pgp2 kræver IDEA-chifret\n"
+msgstr ""
 
 msgid "selected cipher algorithm is invalid\n"
-msgstr "valgt chifferalgoritme er ugyldig\n"
+msgstr "valgte cifferalgoritme er ugyldig\n"
 
 msgid "selected digest algorithm is invalid\n"
-msgstr "valgt sammendragsalgoritme er ugyldig\n"
+msgstr "valgte resuméalgoritme er ugyldig\n"
 
+#, fuzzy
 msgid "selected compression algorithm is invalid\n"
-msgstr "valgt komprimeringsalgoritme er ugyldig\n"
+msgstr "valgte cifferalgoritme er ugyldig\n"
 
+#, fuzzy
 msgid "selected certification digest algorithm is invalid\n"
-msgstr "valgt algoritme for certifikationssammendrag er ugyldig\n"
+msgstr "valgte resuméalgoritme er ugyldig\n"
 
 msgid "completes-needed must be greater than 0\n"
-msgstr "completes-needed skal være større end 0\n"
+msgstr ""
 
 msgid "marginals-needed must be greater than 1\n"
-msgstr "marginals-needed skal være større end 1\n"
+msgstr ""
 
 msgid "max-cert-depth must be in the range from 1 to 255\n"
-msgstr "max-cert-depth skal være i intervallet fra 1 til 255\n"
+msgstr ""
 
+#, fuzzy
 msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n"
-msgstr "ugyldigt default-cert-level; skal være 0, 1, 2 eller 3\n"
+msgstr "ugyldig S2K modus; skal være 0, 1 el. 3\n"
 
+#, fuzzy
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
-msgstr "ugyldigt min-cert-level; skal være 1, 2 eller 3\n"
+msgstr "ugyldig S2K modus; skal være 0, 1 el. 3\n"
 
 msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
-msgstr "BEMÆRK: simpel S2K-tilstand (0) frarådes på det skarpeste\n"
+msgstr "NOTE: simpel S2K modus (0) frarådes på det skarpeste\n"
 
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
-msgstr "ugyldig S2K-tilstand; skal være 0, 1 eller 3\n"
+msgstr "ugyldig S2K modus; skal være 0, 1 el. 3\n"
 
+#, fuzzy
 msgid "invalid default preferences\n"
-msgstr "ugyldige standardpræferencer\n"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "invalid personal cipher preferences\n"
-msgstr "ugyldige præferencer for personlig chiffer\n"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "invalid personal digest preferences\n"
-msgstr "ugyldige præferencer for personlig sammendrag\n"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "invalid personal compress preferences\n"
-msgstr "ugyldige præferencer for personlig komprimering\n"
+msgstr "vis præferencer"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s does not yet work with %s\n"
-msgstr "%s virker endnu ikke med %s\n"
+msgstr "%s er meningsløs sammen med %s!\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
-msgstr "du må ikke bruge chifferalgoritmen »%s« i tilstanden %s\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgstr ""
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
-msgstr "du må ikke bruge sammendragsalgoritmen »%s« i tilstanden %s\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgstr ""
 
-#, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
-msgstr "du må ikke bruge komprimeringsalgoritmen »%s« i tilstanden %s\n"
+#, fuzzy, c-format
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgstr "valgte cifferalgoritme er ugyldig\n"
 
+# er det klogt at oversætte TrustDB?
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
-msgstr "kunne ikke initialisere TrustDB: %s\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
 msgid "WARNING: recipients (-r) given without using public key encryption\n"
 msgstr ""
-"ADVARSEL: modtagere (-r) angivet uden brug af offentlig nøglekryptering\n"
 
 msgid "--store [filename]"
-msgstr "--store [filnavn]"
+msgstr "--store [filnavn (som gemmes)]"
 
 msgid "--symmetric [filename]"
 msgstr "--symmetric [filnavn]"
 
-#, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
-msgstr "symmetrisk kryptering af »%s« mislykkedes: %s\n"
+#, fuzzy, c-format
+msgid "symmetric encryption of '%s' failed: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
 msgid "--encrypt [filename]"
-msgstr "--encrypt [filnavn]"
+msgstr "--encrypt [filnavn (som krypteres)]"
 
+#, fuzzy
 msgid "--symmetric --encrypt [filename]"
-msgstr "--symmetric --encrypt [filnavn]"
+msgstr "--sign --encrypt [filnavn]"
 
 msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
-msgstr "du kan ikke bruge --symmetric --encrypt med --s2k-mode 0\n"
+msgstr ""
 
 #, c-format
 msgid "you cannot use --symmetric --encrypt while in %s mode\n"
-msgstr "du kan ikke bruge --symmetric --encrypt i tilstanden %s\n"
+msgstr ""
 
 msgid "--sign [filename]"
-msgstr "--sign [filnavn]"
+msgstr "--sign [filnavn (som signeres)]"
 
 msgid "--sign --encrypt [filename]"
 msgstr "--sign --encrypt [filnavn]"
 
+#, fuzzy
 msgid "--symmetric --sign --encrypt [filename]"
-msgstr "--symmetric --sign --encrypt [filnavn]"
+msgstr "--sign --encrypt [filnavn]"
 
 msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
-msgstr "du kan ikke bruge --symmetric --sign --encrypt med --s2k-mode 0\n"
+msgstr ""
 
 #, c-format
 msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
-msgstr "du kan ikke bruge --symmetric --sign --encrypt i tilstanden %s\n"
+msgstr ""
 
+#, fuzzy
 msgid "--sign --symmetric [filename]"
-msgstr "--sign --symmetric [filnavn]"
+msgstr "--symmetric [filnavn]"
 
 msgid "--clearsign [filename]"
 msgstr "--clearsign [filnavn]"
 
 msgid "--decrypt [filename]"
-msgstr "--decrypt [filnavn]"
+msgstr "--decrypt [filnavn (som dekrypteres)]"
 
 msgid "--sign-key user-id"
 msgstr "--sign-key bruger-id"
@@ -2099,125 +2052,125 @@ msgstr "--lsign-key bruger-id"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key bruger-id [kommandoer]"
 
-msgid "--passwd <user-id>"
-msgstr "--passwd <bruger-id>"
-
-#, c-format
+#, fuzzy, c-format
 msgid "keyserver send failed: %s\n"
-msgstr "nøgleserver send mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "keyserver receive failed: %s\n"
-msgstr "nøgleserver modtag mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key export failed: %s\n"
-msgstr "nøgleeksport mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "keyserver search failed: %s\n"
-msgstr "nøgleserver søg mislykkedes: %s\n"
+msgstr "signering fejlede: %s\n"
 
 #, c-format
 msgid "keyserver refresh failed: %s\n"
-msgstr "nøgleserver opdater mislykkedes: %s\n"
+msgstr ""
 
 #, c-format
 msgid "dearmoring failed: %s\n"
-msgstr "fjernelse af panser mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
 #, c-format
 msgid "enarmoring failed: %s\n"
-msgstr "påklædning af panser mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
-msgstr "ugyldig hash-algoritme »%s«\n"
+msgid "invalid hash algorithm '%s'\n"
+msgstr "ugyldig hash-algoritme `%s'\n"
 
 msgid "[filename]"
 msgstr "[filnavn]"
 
 msgid "Go ahead and type your message ...\n"
-msgstr "Gå til sagen og skriv meddelelsen ...\n"
+msgstr "Gå til sagen og skriv meddelelsen ...\n"
 
+#, fuzzy
 msgid "the given certification policy URL is invalid\n"
-msgstr "den angivne adresse for certifikatpolitik er ugyldig\n"
+msgstr "den givne politik-URL er ugyldig\n"
 
+#, fuzzy
 msgid "the given signature policy URL is invalid\n"
-msgstr "den angivne adresse for underskriftpolitik er ugyldig\n"
+msgstr "den givne politik-URL er ugyldig\n"
 
+#, fuzzy
 msgid "the given preferred keyserver URL is invalid\n"
-msgstr "den angivne adresse for foretrukken nøgleserver er ugyldig\n"
+msgstr "den givne politik-URL er ugyldig\n"
 
+#, fuzzy
 msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|FILE|tag nøglerne fra nøgleringsFILEN"
+msgstr "Slet denne nøgle fra nøgleringen? "
 
+#, fuzzy
 msgid "make timestamp conflicts only a warning"
-msgstr "giv kun tidsstempelkonflikter en advarsel"
+msgstr "tidsstempelkonflikt"
 
 msgid "|FD|write status info to this FD"
-msgstr "|FD|skriv statusinformation til denne FD"
+msgstr "|FD|skriv statusinfo til denne FD"
 
+#, fuzzy
 msgid "Usage: gpgv [options] [files] (-h for help)"
-msgstr "Brug: gpgv [tilvalg] [filer] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: gpgv [options] [files]\n"
 "Check signatures against known trusted keys\n"
 msgstr ""
-"Syntaks: gpgv [tilvalg] [filer]\n"
-"Kontroller underskrifter mod kendte troværdige nøgler\n"
 
 msgid "No help available"
-msgstr "Ingen hjælp tilgængelig"
+msgstr "Ingen hjælp tilgængelig"
 
 #, c-format
-msgid "No help available for `%s'"
-msgstr "Ingen hjælp tilgængelig for »%s«"
+msgid "No help available for '%s'"
+msgstr "Ingen hjælp tilgængelig for `%s'"
 
 msgid "import signatures that are marked as local-only"
-msgstr "importer underskrifter som er markeret som local-only"
+msgstr ""
 
 msgid "repair damage from the pks keyserver during import"
-msgstr "reparer skade fra pks-nøgleserveren under import"
-
-msgid "do not clear the ownertrust values during import"
-msgstr "ryd ikke ejerskabsværdierne under import"
+msgstr ""
 
+#, fuzzy
 msgid "do not update the trustdb after import"
-msgstr "opdater ikke trustdb efter import"
+msgstr "opdatér tillidsdatabasen"
 
 msgid "create a public key when importing a secret key"
-msgstr "opret en offentlig nøgle under import af en hemmelig nøgle"
+msgstr ""
 
 msgid "only accept updates to existing keys"
-msgstr "accepter kun opdateringer til eksisterende nøgler"
+msgstr ""
 
+#, fuzzy
 msgid "remove unusable parts from key after import"
-msgstr "fjern ubrugelige dele fra nøgle efter import"
+msgstr "dårlig hemmelig nøgle"
 
 msgid "remove as much as possible from key after import"
-msgstr "fjern så meget som muligt fra nøgle efter import"
+msgstr ""
 
 #, c-format
 msgid "skipping block of type %d\n"
-msgstr "     udelader bloktype %d\n"
+msgstr "sprang over blok af typen %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%lu keys processed so far\n"
-msgstr "     %lu-nøgler behandlet\n"
+msgstr "%lu nøgler behandlet indtil nu\n"
 
 #, c-format
 msgid "Total number processed: %lu\n"
-msgstr " Totalt antal behandl.: %lu\n"
+msgstr "Totalt antal behandlede: %lu\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "      skipped new keys: %lu\n"
-msgstr "   udeladte nye nøgler: %lu\n"
+msgstr "       nye undernøgler: %lu\n"
 
 #, c-format
 msgid "          w/o user IDs: %lu\n"
-msgstr "      w/o bruger-id'er: %lu\n"
+msgstr ""
 
 #, c-format
 msgid "              imported: %lu"
@@ -2225,380 +2178,359 @@ msgstr "           importerede: %lu"
 
 #, c-format
 msgid "             unchanged: %lu\n"
-msgstr "              uændrede: %lu\n"
+msgstr "              uændrede: %lu\n"
 
 #, c-format
 msgid "          new user IDs: %lu\n"
-msgstr "       nye bruger-id'er: %lu\n"
+msgstr "      nye bruger-id'er: %lu\n"
 
 #, c-format
 msgid "           new subkeys: %lu\n"
-msgstr "       nye undernøgler: %lu\n"
+msgstr "       nye undernøgler: %lu\n"
 
 #, c-format
 msgid "        new signatures: %lu\n"
-msgstr "     nye underskrifter: %lu\n"
+msgstr "        nye signaturer: %lu\n"
 
 #, c-format
 msgid "   new key revocations: %lu\n"
-msgstr "  nye nøgletilbagekald: %lu\n"
+msgstr "  nye nøgletilbagekald: %lu\n"
 
 #, c-format
 msgid "      secret keys read: %lu\n"
-msgstr " hemmelige nøgler læst: %lu\n"
+msgstr " hemmelige nøgler læst: %lu\n"
 
 #, c-format
 msgid "  secret keys imported: %lu\n"
-msgstr " hemmel. nøgler import: %lu\n"
+msgstr "hemmelige nøgler import: %lu\n"
 
 #, c-format
 msgid " secret keys unchanged: %lu\n"
-msgstr "hemmel. nøgler uændret: %lu\n"
+msgstr "hemmelige nøgler uændre: %lu\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "          not imported: %lu\n"
-msgstr "      ikke importerede: %lu\n"
+msgstr "           importerede: %lu"
 
-#, c-format
+#, fuzzy, c-format
 msgid "    signatures cleaned: %lu\n"
-msgstr "  underskrifter ryddet: %lu\n"
+msgstr "        nye signaturer: %lu\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "      user IDs cleaned: %lu\n"
-msgstr "   bruger-id'er ryddet: %lu\n"
+msgstr " hemmelige nøgler læst: %lu\n"
 
 #, c-format
 msgid ""
 "WARNING: key %s contains preferences for unavailable\n"
 "algorithms on these user IDs:\n"
 msgstr ""
-"ADVARSEL: nøgle %s indeholder præferencer for utilgængelige\n"
-"algoritmer på disse bruger-id'er:\n"
 
 #, c-format
 msgid "         \"%s\": preference for cipher algorithm %s\n"
-msgstr "        »%s«: præference for chifferalgoritme %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "         \"%s\": preference for digest algorithm %s\n"
-msgstr "        »%s«: præference for sammendragsalgortime %s\n"
+msgstr "%s signatur fra: %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for compression algorithm %s\n"
-msgstr "        »%s«: præference for komprimeringsalgortime %s\n"
+msgstr ""
 
 msgid "it is strongly suggested that you update your preferences and\n"
-msgstr "det anbefales på det stærkeste, at du opdaterer dine præferencer og\n"
+msgstr ""
 
 msgid "re-distribute this key to avoid potential algorithm mismatch problems\n"
 msgstr ""
-"gendistribuerer denne nøgle for at undgå potentielle problemer med rod i\n"
-"algoritmen\n"
 
 #, c-format
 msgid "you can update your preferences with: gpg --edit-key %s updpref save\n"
-msgstr "du kan opdatere dine præferencer med: gpg --edit-key %s updpref save\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no user ID\n"
-msgstr "nøgle %s: ingen bruger-id\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
-msgid "key %s: %s\n"
-msgstr "nøgle %s: %s\n"
-
-msgid "rejected by import filter"
-msgstr "afvist af importfilter"
-
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
-msgstr "nøgle %s: korruption af PKS-undernøgle er repareret!\n"
+msgstr "nøgle %08lX: undernøgle er blevet annulleret!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: accepted non self-signed user ID \"%s\"\n"
-msgstr "nøgle %s: accepteret ikke egenunderskrevet bruger-id »%s«\n"
+msgstr "nøgle %08lX: ingen gyldige bruger-id'er\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no valid user IDs\n"
-msgstr "nøgle %s: ingen gyldige bruger-id'er\n"
+msgstr "nøgle %08lX: ingen gyldige bruger-id'er\n"
 
 msgid "this may be caused by a missing self-signature\n"
-msgstr "dette kan skyldes en manglende egenunderskrift\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: public key not found: %s\n"
-msgstr "nøgle %s: offentlig nøgle blev ikke fundet: %s\n"
+msgstr "nøgle %08lX: offentlig nøgle ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: new key - skipped\n"
-msgstr "nøgle %s: ny nøgle - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "no writable keyring found: %s\n"
-msgstr "ingen skrivbar nøglering fundet: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
-msgstr "skriver til »%s«\n"
+msgid "writing to '%s'\n"
+msgstr "skriver til `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
-msgstr "fejl ved skrivning af nøglering »%s«: %s\n"
+msgid "error writing keyring '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: public key \"%s\" imported\n"
-msgstr "nøgle %s: offentlig nøgle »%s« importeret\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: doesn't match our copy\n"
-msgstr "nøgle %s: stemmer ikke med vores kopi\n"
+msgstr "nøgle %08lX: stemmer ikke med vores kopi\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: can't locate original keyblock: %s\n"
-msgstr "nøgle %s: kan ikke lokalisere original nøgleblok: %s\n"
+msgstr "nøgle %08lX: kan ikke lokalisere original nøgleblok: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: can't read original keyblock: %s\n"
-msgstr "nøgle %s: kan ikke læse original nøgleblok: %s\n"
+msgstr "nøgle %08lX: kan ikke læse original nøgleblok: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" 1 new user ID\n"
-msgstr "nøgle %s: »%s« 1 ny bruger-id\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" %d new user IDs\n"
-msgstr "nøgle %s: »%s« %d nye bruger-id'er\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" 1 new signature\n"
-msgstr "nøgle %s: »%s« 1 ny underskrift\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" %d new signatures\n"
-msgstr "nøgle %s: »%s« %d nye underskrifter\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" 1 new subkey\n"
-msgstr "nøgle %s: »%s« 1 ny undernøgle\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" %d new subkeys\n"
-msgstr "nøgle %s: »%s« %d nye undernøgler\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" %d signature cleaned\n"
-msgstr "nøgle %s: »%s« %d underskrift renset\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" %d signatures cleaned\n"
-msgstr "nøgle %s: »%s« %d underskrifter renset\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" %d user ID cleaned\n"
-msgstr "nøgle %s: »%s« %d bruger-id renset\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" %d user IDs cleaned\n"
-msgstr "nøgle %s: »%s« %d bruger-id'er renset\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" not changed\n"
-msgstr "nøgle %s: »%s« ikke ændret\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
-msgid "secret key %s: %s\n"
-msgstr "hemmelig nøgle %s: %s\n"
+#, fuzzy, c-format
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
+#, fuzzy
 msgid "importing secret keys not allowed\n"
-msgstr "import af hemmelige nøgler er ikke tilladt\n"
-
-#, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "nøgle %s: hemmelig nøgle med ugyldig chiffer %d - udeladt\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "no default secret keyring: %s\n"
-msgstr "ingen hemmelig standardnøglering: %s\n"
+msgstr "ingen standard offentlig nøglering\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: secret key imported\n"
-msgstr "nøgle %s: hemmelig nøgle importeret\n"
+msgstr "hemmelige nøgler import: %lu\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: already in secret keyring\n"
-msgstr "nøgle %s: allerede i hemmelig nøglering\n"
+msgstr "fjern nøgle fra den hemmelige nøglering"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: secret key not found: %s\n"
-msgstr "nøgle %s: hemmelig nøgle blev ikke fundet: %s\n"
+msgstr "%s: bruger ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
-msgstr ""
-"nøgle %s: ingen offentlig nøgle - kan ikke anvende tilbagekaldscertifikat\n"
+msgstr "Generér en annullérbar certifikat"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: invalid revocation certificate: %s - rejected\n"
-msgstr "nøgle %s: ugyldigt tilbagekaldscertifikat: %s - afvist\n"
+msgstr "Generér en annullérbar certifikat"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" revocation certificate imported\n"
-msgstr "nøgle %s: »%s« tilbagekaldscertifikat importeret\n"
+msgstr "Generér en annullérbar certifikat"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no user ID for signature\n"
-msgstr "nøgle %s: ingen bruger-id for underskrift\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
-msgstr ""
-"nøgle %s: ikke understøttet offentlig nøglealgoritme på bruger-id »%s«\n"
+msgstr "nøgle %08lX: offentlig nøgle ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: invalid self-signature on user ID \"%s\"\n"
-msgstr "nøgle %s: ugyldig egenunderskrift på bruger-id »%s«\n"
-
-#, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "nøgle %s: ikke understøttet offentlig nøglealgoritme\n"
-
-#, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "nøgle %s: ugyldig direkte nøgleunderskrift\n"
+msgstr "nøgle %08lX: ingen gyldige bruger-id'er\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
-msgstr "nøgle %s: ingen undernøgle for nøglebinding\n"
+msgstr "nøgle %08lX: undernøgle er blevet annulleret!\n"
 
-#, c-format
+#, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "nøgle %08lX: offentlig nøgle ikke fundet: %s\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
-msgstr "nøgle %s: ugyldig undernøglebinding\n"
+msgstr "nøgle %08lX: ingen gyldige bruger-id'er\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: removed multiple subkey binding\n"
-msgstr "nøgle %s: fjernet flerundernøglebinding\n"
+msgstr "nøgle %08lX: undernøgle er blevet annulleret!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no subkey for key revocation\n"
-msgstr "nøgle %s: ingen undernøgle for nøgletilbagekald\n"
+msgstr "nøgle %08lX: undernøgle er blevet annulleret!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: invalid subkey revocation\n"
-msgstr "nøgle %s: ugyldig undernøgletilbagekald\n"
+msgstr "nøgle %08lX: ingen gyldige bruger-id'er\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: removed multiple subkey revocation\n"
-msgstr "nøgle %s: fjernet flerundernøgletilbagekald\n"
+msgstr "nøgle %08lX: ingen gyldige bruger-id'er\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: skipped user ID \"%s\"\n"
-msgstr "nøgle %s: udeladt bruger-id »%s«\n"
+msgstr "%s: udelod: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: skipped subkey\n"
-msgstr "nøgle %s: udeladt undernøgle\n"
+msgstr "%s: udelod: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: non exportable signature (class 0x%02X) - skipped\n"
-msgstr ""
-"nøgle %s: underskrift der ikke kan eksporteres (klasse 0x%02X) - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: revocation certificate at wrong place - skipped\n"
-msgstr "nøgle %s: tilbagekaldscertifikat på forkert sted - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: invalid revocation certificate: %s - skipped\n"
-msgstr "nøgle %s: ugyldigt tilbagekaldscertifikat: %s - udeladt\n"
+msgstr "Generér en annullérbar certifikat"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: subkey signature in wrong place - skipped\n"
-msgstr "nøgle %s: undernøgleunderskrift på forkert sted - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: unexpected signature class (0x%02X) - skipped\n"
-msgstr "nøgle %s: uventet underskriftklasse (0x%02X) - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
 #, c-format
 msgid "key %s: duplicated user ID detected - merged\n"
-msgstr "nøgle %s: duplikeret bruger-id detekteret - sammenføjet\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
-msgstr "ADVARSEL: nøgle %s kan tilbagekaldes: henter tilbagekaldsnøgle %s\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
-msgstr ""
-"ADVARSEL: nøgle %s kan tilbagekaldes: tilbagekaldsnøgle %s er ikke til "
-"stede.\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: \"%s\" revocation certificate added\n"
-msgstr "nøgle %s: »%s« tilbagekaldscertifikat tilføjet\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: direct key signature added\n"
-msgstr "nøgle %s: direkte nøgleunderskrift tilføjet\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
 msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr "BEMÆRK: en nøgles S/N matcher ikke kortets\n"
+msgstr ""
 
+#, fuzzy
 msgid "NOTE: primary key is online and stored on card\n"
-msgstr "BEMÆRK: primær nøgle er på nettet og lagret på kort\n"
+msgstr "udelod: hemmelig nøgle er allerede tilstede\n"
 
+#, fuzzy
 msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "BEMÆRK: sekundær nøgle er på nettet og lagret på kort\n"
+msgstr "udelod: hemmelig nøgle er allerede tilstede\n"
 
-#, c-format
-msgid "error creating keyring `%s': %s\n"
-msgstr "fejl ved oprettelse af nøglering »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error creating keyring '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
-msgstr "nøglering »%s« oprettet\n"
+msgid "keyring '%s' created\n"
+msgstr ""
 
-#, c-format
-msgid "keyblock resource `%s': %s\n"
-msgstr "nøgleblokressource »%s«: %s\n"
+#, fuzzy, c-format
+msgid "keyblock resource '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "failed to rebuild keyring cache: %s\n"
-msgstr "kunne ikke genbygge nøgleringsmellemlager: %s\n"
+msgstr "ingen standard offentlig nøglering\n"
 
 msgid "[revocation]"
-msgstr "[tilbagekald]"
+msgstr ""
 
 msgid "[self-signature]"
-msgstr "[egenunderskrift]"
+msgstr "[selv-signatur]"
 
 msgid "1 bad signature\n"
-msgstr "1 ugyldig underskrift\n"
+msgstr "1 dårlig signature\n"
 
 #, c-format
 msgid "%d bad signatures\n"
-msgstr "%d ugyldige underskrifter\n"
+msgstr "%d dårlige signaturer\n"
 
 msgid "1 signature not checked due to a missing key\n"
-msgstr "1 underskrift er ikke kontrolleret på grund af en manglende nøgle\n"
+msgstr ""
 
 #, c-format
 msgid "%d signatures not checked due to missing keys\n"
-msgstr "%d underskrifter er ikke kontrolleret på grund af manglende nøgler\n"
+msgstr ""
 
 msgid "1 signature not checked due to an error\n"
-msgstr "1 underskrift er ikke kontrolleret på grund af en fejl\n"
+msgstr ""
 
 #, c-format
 msgid "%d signatures not checked due to errors\n"
-msgstr "%d underskrifter er ikke kontrolleret på grund af fejl\n"
+msgstr ""
 
 msgid "1 user ID without valid self-signature detected\n"
-msgstr "1 bruger-id uden gyldig egenunderskrift detekteret\n"
+msgstr ""
 
 #, c-format
 msgid "%d user IDs without valid self-signatures detected\n"
-msgstr "%d bruger-id'er uden gyldige egenunderskrifter detekteret\n"
+msgstr ""
 
 msgid ""
 "Please decide how far you trust this user to correctly verify other users' "
@@ -2606,371 +2538,366 @@ msgid ""
 "(by looking at passports, checking fingerprints from different sources, "
 "etc.)\n"
 msgstr ""
-"Beslut dig for hvor meget du stoler på at denne bruger korrekt verificerer "
-"andre brugers nøgler\n"
-"(ved at kigge på pas, kontrollere fingeraftryk fra andre kilder etc.)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "  %d = I trust marginally\n"
-msgstr "  %d = Marginal troværdighed\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "  %d = I trust fully\n"
-msgstr "  %d = Fuld troværdighed\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
 msgid ""
 "Please enter the depth of this trust signature.\n"
 "A depth greater than 1 allows the key you are signing to make\n"
 "trust signatures on your behalf.\n"
 msgstr ""
-"Indtast venligst dybden på denne troværdighedsunderskrift.\n"
-"En dybde større end 1 giver nøglen du underskriver mulighed for\n"
-"at lavet troværdighedsunderskrifter på dine vegne.\n"
 
 msgid "Please enter a domain to restrict this signature, or enter for none.\n"
 msgstr ""
-"Indtast venligst et domæne for at begrænse denne underskrift, eller retur "
-"for ingen.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\" is revoked."
-msgstr "Bruger-id »%s« er tilbagekaldt."
+msgstr "Nøglen er beskyttet.\n"
 
+#, fuzzy
 msgid "Are you sure you still want to sign it? (y/N) "
-msgstr "Er du sikker på, at du stadig vil underskrive (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
 msgid "  Unable to sign.\n"
-msgstr "  Kunne ikke underskrive.\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\" is expired."
-msgstr "Bruger-id »%s« er udløbet."
+msgstr "Nøglen er beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\" is not self-signed."
-msgstr "Bruger-id »%s« er ikke egenunderskrevet."
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\" is signable.  "
-msgstr "Bruger-id »%s« kan underskrives.  "
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
+#, fuzzy
 msgid "Sign it? (y/N) "
-msgstr "Underskriv? (j/N) "
+msgstr "Vil du gerne signere? "
 
 #, c-format
 msgid ""
 "The self-signature on \"%s\"\n"
 "is a PGP 2.x-style signature.\n"
 msgstr ""
-"Egenunderskriften på »%s«\n"
-"er en underskrift i PGP 2.x-stil.\n"
 
 msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) "
-msgstr "Ønsker du at forfremme den til en OpenPGP-egenunderskrift? (j/N) "
+msgstr ""
 
 #, c-format
 msgid ""
 "Your current signature on \"%s\"\n"
 "has expired.\n"
 msgstr ""
-"Din aktuelle underskrift på »%s«\n"
-"er udløbet.\n"
 
 msgid "Do you want to issue a new signature to replace the expired one? (y/N) "
 msgstr ""
-"Ønsker du at udstede en ny underskrift for at erstatte den udløbne? (j/N) "
 
 #, c-format
 msgid ""
 "Your current signature on \"%s\"\n"
 "is a local signature.\n"
 msgstr ""
-"Din aktuelle underskrift på »%s«\n"
-"er en lokal underskrift.\n"
 
 msgid "Do you want to promote it to a full exportable signature? (y/N) "
 msgstr ""
-"Ønsker du at forfremme den til en fuld underskrift, der kan eksporteres (j/"
-"N) "
 
 #, c-format
 msgid "\"%s\" was already locally signed by key %s\n"
-msgstr "»%s« var allerede underskrevet lokalt af nøgle %s\n"
+msgstr ""
 
 #, c-format
 msgid "\"%s\" was already signed by key %s\n"
-msgstr "»%s« var allerede underskrevet af nøgle %s\n"
+msgstr ""
 
+#, fuzzy
 msgid "Do you want to sign it again anyway? (y/N) "
-msgstr "Ønsker du at underskrive den igen alligevel? (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
 #, c-format
 msgid "Nothing to sign with key %s\n"
-msgstr "Intet at underskrive med nøgle %s\n"
+msgstr ""
 
+#, fuzzy
 msgid "This key has expired!"
-msgstr "Denne nøgle er udløbet!"
+msgstr "Bemærk: Denne nøgle er forældet!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "This key is due to expire on %s.\n"
-msgstr "Denne nøgle er ved at udløbe på %s.\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
 msgid "Do you want your signature to expire at the same time? (Y/n) "
-msgstr "Ønsker du at dine underskrifter skal udløbe på samme tidspunkt? (J/n) "
+msgstr ""
 
 msgid ""
 "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
 "mode.\n"
 msgstr ""
-"Du kan ikke lave en OpenPGP-underskrift på en PGP 2.x-nøgle i tilstanden --"
-"pgp2.\n"
 
 msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "Dette vil gøre nøglen ubrugelig i PGP 2.x.\n"
+msgstr ""
 
 msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
 msgstr ""
-"Hvor omhyggeligt har du verificeret, at nøglen du er ved at underskrive "
-"rent\n"
-"faktisk tilhører personen navngivet ovenfor? Hvis du ikke kender svaret, så "
-"indtast »0«.\n"
 
 #, c-format
 msgid "   (0) I will not answer.%s\n"
-msgstr "   (0) Jeg vil ikke svare.%s\n"
+msgstr ""
 
 #, c-format
 msgid "   (1) I have not checked at all.%s\n"
-msgstr "   (1) Jeg har ingen kontrol udført.%s\n"
+msgstr ""
 
 #, c-format
 msgid "   (2) I have done casual checking.%s\n"
-msgstr "   (2) Jeg har udført en overfladisk kontrol.%s\n"
+msgstr ""
 
 #, c-format
 msgid "   (3) I have done very careful checking.%s\n"
-msgstr "   (3) Jeg har foretaget en meget omhyggelig kontrol.%s\n"
+msgstr ""
 
-msgid "Your selection? (enter `?' for more information): "
-msgstr "Dit valg? (indtast »?« for yderligere information): "
+msgid "Your selection? (enter '?' for more information): "
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Are you sure that you want to sign this key with your\n"
 "key \"%s\" (%s)\n"
-msgstr ""
-"Er du sikker på, at du ønsker at underskrive denne nøgle\n"
-"med din nøgle »%s« (%s)\n"
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
+#, fuzzy
 msgid "This will be a self-signature.\n"
-msgstr "Dette vil være en egenunderskrift.\n"
+msgstr "skriver selvsignatur\n"
 
 msgid "WARNING: the signature will not be marked as non-exportable.\n"
 msgstr ""
-"ADVARSEL: Underskriften vil ikke blive markeret som ikke at kunne "
-"eksporteres.\n"
 
 msgid "WARNING: the signature will not be marked as non-revocable.\n"
 msgstr ""
-"ADVARSEL: Underskriften vil ikke blive markereret som ikke at kunne "
-"tilbagekaldes.\n"
 
 msgid "The signature will be marked as non-exportable.\n"
-msgstr "Underskriften vil blive markeret som ikke at kunne eksporteres.\n"
+msgstr ""
 
+#, fuzzy
 msgid "The signature will be marked as non-revocable.\n"
-msgstr "Underskriften vil blive markeret som ikke at kunne tilbagekaldes.\n"
+msgstr "signér nøglen lokalt"
 
 msgid "I have not checked this key at all.\n"
-msgstr "Jeg har overhovedet ikke kontrolleret denne nøgle.\n"
+msgstr ""
 
 msgid "I have checked this key casually.\n"
-msgstr "Jeg har overfladisk kontrolleret denne nøgle.\n"
+msgstr ""
 
 msgid "I have checked this key very carefully.\n"
-msgstr "Jeg har omhyggeligt kontrolleret denne nøgle.\n"
+msgstr ""
 
+#, fuzzy
 msgid "Really sign? (y/N) "
-msgstr "Underskriv? (j/N) "
+msgstr "Vil du gerne signere? "
 
 #, c-format
 msgid "signing failed: %s\n"
-msgstr "underskrift mislykkedes: %s\n"
+msgstr "signering fejlede: %s\n"
 
 msgid "Key has only stub or on-card key items - no passphrase to change.\n"
 msgstr ""
-"Nøgle har kun stump eller ikkekort nøgleposter - ingen adgangsfrase at "
-"ændre.\n"
 
 msgid "This key is not protected.\n"
-msgstr "Denne nøgle er ikke beskyttet.\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
+#, fuzzy
 msgid "Secret parts of primary key are not available.\n"
-msgstr "Hemmelige dele for primær nøgle er ikke tilgængelige.\n"
+msgstr "hemmelig nøgle ikke tilgængelig"
 
+#, fuzzy
 msgid "Secret parts of primary key are stored on-card.\n"
-msgstr "Hemmelige dele for primær nøgle gemmes på kortet.\n"
+msgstr "hemmelig nøgle ikke tilgængelig"
 
 msgid "Key is protected.\n"
-msgstr "Nøglen er beskyttet.\n"
+msgstr "Nøglen er beskyttet.\n"
 
 #, c-format
 msgid "Can't edit this key: %s\n"
-msgstr "Kan ikke redigere denne nøgle: %s\n"
+msgstr "Kan ikke redigere denne nøgle: %s\n"
 
 msgid ""
 "Enter the new passphrase for this secret key.\n"
 "\n"
-msgstr "Indtast den nye adgangsfrase for denne hemmelige nøgle.\n"
+msgstr ""
 
+#, fuzzy
 msgid "passphrase not correctly repeated; try again"
-msgstr "adgangsfrasen er ikke korrekt gentaget; prøv igen"
+msgstr "kodesætningen blev ikke ordentlig gentaget; prøv igen.\n"
 
 msgid ""
 "You don't want a passphrase - this is probably a *bad* idea!\n"
 "\n"
 msgstr ""
-"Du ønsker ikke en adgangsfrase - dette er en *dårlig* ide!\n"
-"\n"
 
+#, fuzzy
 msgid "Do you really want to do this? (y/N) "
-msgstr "Vil du virkelig gerne gøre dette? (j/N) "
+msgstr "Vil du virkelig gerne gøre dette?"
 
 msgid "moving a key signature to the correct place\n"
-msgstr "flytter en nøgleunderskrift til det korrekte sted\n"
+msgstr ""
 
 msgid "save and quit"
 msgstr "gem og afslut"
 
+#, fuzzy
 msgid "show key fingerprint"
-msgstr "vis nøglefingeraftryk"
+msgstr "vis fingeraftryk"
 
 msgid "list key and user IDs"
-msgstr "vis nøgle og bruger-id'er"
+msgstr "vis nøgler og bruger-id'er"
 
 msgid "select user ID N"
-msgstr "vælg bruger-id N"
+msgstr ""
 
+#, fuzzy
 msgid "select subkey N"
-msgstr "vælg undernøgle N"
+msgstr "vælg sekundær nøgle N"
 
+#, fuzzy
 msgid "check signatures"
-msgstr "kontroller underskrifter"
+msgstr "Kan ikke tjekke signatur: %s\n"
 
 msgid "sign selected user IDs [* see below for related commands]"
 msgstr ""
-"underskriv valgte bruger-id'er [* se nedenfor for relaterede kommandoer]"
 
+#, fuzzy
 msgid "sign selected user IDs locally"
-msgstr "underskriv valgte bruger-id'er lokalt"
+msgstr "signér nøglen lokalt"
 
 msgid "sign selected user IDs with a trust signature"
-msgstr "underskriv valgte bruger-id'er med en troværdighedsunderskrift"
+msgstr ""
 
 msgid "sign selected user IDs with a non-revocable signature"
-msgstr "underskriv bruger-id'er md en underskrift der ikke kan kaldes tilbage"
+msgstr ""
 
 msgid "add a user ID"
-msgstr "tilføj bruger-id"
+msgstr "tilføj bruger-id"
 
+#, fuzzy
 msgid "add a photo ID"
-msgstr "tilføj billed-id"
+msgstr "tilføj bruger-id"
 
+#, fuzzy
 msgid "delete selected user IDs"
-msgstr "slet valgte bruger-id'er"
+msgstr "slet bruger id"
 
+#, fuzzy
 msgid "add a subkey"
-msgstr "tilføj en undernøgle"
+msgstr "tilføj nøgle"
 
 msgid "add a key to a smartcard"
-msgstr "tilføj en nøgle til et smartkort"
+msgstr ""
 
 msgid "move a key to a smartcard"
-msgstr "flyt en nøgle til et smartkort"
+msgstr ""
 
 msgid "move a backup key to a smartcard"
-msgstr "flyt en sikkerhedskopinøgle til et smartkort"
+msgstr ""
 
+#, fuzzy
 msgid "delete selected subkeys"
-msgstr "slet valgte undernøgler"
+msgstr "slet sekundær nøgle"
 
+#, fuzzy
 msgid "add a revocation key"
-msgstr "tilføj en tilbagekaldsnøgle"
+msgstr "tilføj sekundær nøgle"
 
+#, fuzzy
 msgid "delete signatures from the selected user IDs"
-msgstr "slet underskrifter fra de valgte bruger-id'er"
+msgstr "Generér en annullérbar certifikat"
 
 msgid "change the expiration date for the key or selected subkeys"
-msgstr "ændr udløbsdatoen for nøglen eller valgte undernøgler"
+msgstr ""
 
 msgid "flag the selected user ID as primary"
-msgstr "marker den valgte bruger-id som primær"
+msgstr ""
 
+#, fuzzy
 msgid "toggle between the secret and public key listings"
-msgstr "skift mellem hemmelig og offentlig nøglevisning"
+msgstr "skift imellem hemmelig og offentlig nøgle visning"
 
+#, fuzzy
 msgid "list preferences (expert)"
-msgstr "vis præferencer (ekspert)"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "list preferences (verbose)"
-msgstr "vis præferencer (uddybende)"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "set preference list for the selected user IDs"
-msgstr "angiv præferenceliste for de valgte bruger-id'er"
+msgstr "Generér en annullérbar certifikat"
 
+#, fuzzy
 msgid "set the preferred keyserver URL for the selected user IDs"
-msgstr "angiv den foretrukne nøgleserveradresse for de valgte bruger-id'er"
+msgstr "Generér en annullérbar certifikat"
 
+#, fuzzy
 msgid "set a notation for the selected user IDs"
-msgstr "angiv en notation for de valgte bruger-id'er"
+msgstr "Generér en annullérbar certifikat"
 
 msgid "change the passphrase"
-msgstr "ændr adgangsfrasen"
+msgstr "ændr kodesætningen"
 
 msgid "change the ownertrust"
-msgstr "ændr ejertroværdigheden"
+msgstr ""
 
+#, fuzzy
 msgid "revoke signatures on the selected user IDs"
-msgstr "tilbagekald underskrifter på de valgte bruger-id'er"
+msgstr "Vil du virkelig oprette?"
 
+#, fuzzy
 msgid "revoke selected user IDs"
-msgstr "tilbagekald valgte bruger-id'er"
+msgstr "tilføj bruger-id"
 
 msgid "revoke key or selected subkeys"
-msgstr "tilbagekald nøgle eller valgte undernøgler"
+msgstr ""
 
+#, fuzzy
 msgid "enable key"
-msgstr "aktiver nøgle"
+msgstr "slå nøgle til"
 
+#, fuzzy
 msgid "disable key"
-msgstr "deaktiver nøgle"
+msgstr "slå nøgle fra"
 
 msgid "show selected photo IDs"
-msgstr "vis valgte billed-id'er"
+msgstr ""
 
 msgid "compact unusable user IDs and remove unusable signatures from key"
 msgstr ""
-"komprimer ubrugelige bruger-id'er og fjern ubrugelige underskrifter fra nøgle"
 
 msgid "compact unusable user IDs and remove all signatures from key"
 msgstr ""
-"komprimer ubrugelige bruger-id'er og fjern alle underskrifter fra nøgle"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "fejl ved læsning af hemmelig nøgleblok »%s«: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "Secret key is available.\n"
-msgstr "Hemmelig nøgle er tilgængelig.\n"
+msgstr ""
 
 msgid "Need the secret key to do this.\n"
-msgstr "Har brug for den hemmelige nøgle for dette.\n"
+msgstr ""
 
 msgid "Please use the command \"toggle\" first.\n"
-msgstr "Brug venligst kommandoen »toggle« først.\n"
+msgstr ""
 
 msgid ""
 "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -2978,481 +2905,490 @@ msgid ""
 "  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
-"* Kommandoen »sign« kan have præfikset »l« for lokale underskrifter "
-"(lsign),\n"
-"  et »t« for troværdighedsunderskrifter (tsign), et »nr« for underskrifter\n"
-"  der ikke kan tilbagekaldes (nrsign), eller en kombination (ltsign, "
-"tnrsign\n"
-"  etc.).\n"
 
+#, fuzzy
 msgid "Key is revoked."
-msgstr "Nøglen er tilbagekaldt."
+msgstr "Nøglen er beskyttet.\n"
 
+#, fuzzy
 msgid "Really sign all user IDs? (y/N) "
-msgstr "Vil du gerne underskrive alle bruger-id'er (j/N) "
+msgstr "Vil du gerne signere? "
 
+#, fuzzy
 msgid "Hint: Select the user IDs to sign\n"
-msgstr "Fif: Vælg bruger-id'erne at underskrive\n"
+msgstr "signér nøglen lokalt"
 
-#, c-format
-msgid "Unknown signature type `%s'\n"
-msgstr "Ukendt underskrifttype »%s«\n"
+#, fuzzy, c-format
+msgid "Unknown signature type '%s'\n"
+msgstr "ukendt signaturklasse"
 
 #, c-format
 msgid "This command is not allowed while in %s mode.\n"
-msgstr "Denne kommando er ikke tilladt i tilstanden %s.\n"
+msgstr ""
 
 msgid "You must select at least one user ID.\n"
-msgstr "Du skal vælge mindst en bruger-id.\n"
+msgstr ""
 
 msgid "You can't delete the last user ID!\n"
-msgstr "Du kan ikke slette den sidste bruger-id!\n"
+msgstr ""
 
+#, fuzzy
 msgid "Really remove all selected user IDs? (y/N) "
-msgstr "Vil du virkelig fjerne alle valgte bruger-id'er? (j/N) "
+msgstr "Vil du virkelig oprette?"
 
+#, fuzzy
 msgid "Really remove this user ID? (y/N) "
-msgstr "Vil du virkelig fjerne denne bruger-id? (j/N) "
+msgstr "Vil du virkelig oprette?"
 
 #. TRANSLATORS: Please take care: This is about
 #. moving the key and not about removing it.
 msgid "Really move the primary key? (y/N) "
-msgstr "Vil du virkelig flytte den primære nøgle? (j/N) "
+msgstr ""
 
+#, fuzzy
 msgid "You must select exactly one key.\n"
-msgstr "Du skal vælge præcis en nøgle.\n"
+msgstr "Vælg venligst hvilken slags nøgle du vil have:\n"
 
 msgid "Command expects a filename argument\n"
-msgstr "Kommando forventer en filnavnsparameter\n"
+msgstr ""
 
-#, c-format
-msgid "Can't open `%s': %s\n"
-msgstr "Kan ikke åbne »%s«: %s\n"
+#, fuzzy, c-format
+msgid "Can't open '%s': %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
-#, c-format
-msgid "Error reading backup key from `%s': %s\n"
-msgstr "Fejl ved læsning af sikkerhedskopinøgle fra »%s«: %s\n"
+#, fuzzy, c-format
+msgid "Error reading backup key from '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 msgid "You must select at least one key.\n"
-msgstr "Du skal vælge mindst en nøgle.\n"
+msgstr ""
 
+#, fuzzy
 msgid "Do you really want to delete the selected keys? (y/N) "
-msgstr "Vil du virkelig slette de valgte nøgler? (j/N) "
+msgstr "Vil du gerne oprette en underskrivnings- og krypteringsnøgle? "
 
+#, fuzzy
 msgid "Do you really want to delete this key? (y/N) "
-msgstr "Vil du virkelig slette denne nøgle? (j/N) "
+msgstr "Vil du virkelig gerne gøre dette?"
 
+#, fuzzy
 msgid "Really revoke all selected user IDs? (y/N) "
-msgstr "Vil du virkelig tilbagekalde alle valgte bruger-id'er? (j/N) "
+msgstr "Vil du virkelig oprette?"
 
+#, fuzzy
 msgid "Really revoke this user ID? (y/N) "
-msgstr "Vil du virkelig tilbagekalde dette bruger-id? (j/N) "
+msgstr "Vil du virkelig oprette?"
 
+#, fuzzy
 msgid "Do you really want to revoke the entire key? (y/N) "
-msgstr "Vil du virkelig tilbagekalde hele nøglen? (j/N) "
+msgstr "Vil du virkelig gerne gøre dette?"
 
+#, fuzzy
 msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgstr "Vil du virkelig tilbagekalde de valgte undernøgler? (j/N) "
+msgstr "Vil du gerne oprette en underskrivnings- og krypteringsnøgle? "
 
+#, fuzzy
 msgid "Do you really want to revoke this subkey? (y/N) "
-msgstr "Vil du virkelig tilbagekalde denne undernøgle? (j/N) "
+msgstr "Vil du virkelig gerne gøre dette?"
 
 msgid "Owner trust may not be set while using a user provided trust database\n"
 msgstr ""
-"Ejertroværdighed kan ikke indstilles, når der bruges en brugerleveret "
-"troværdighedsdatabase\n"
 
+#, fuzzy
 msgid "Set preference list to:\n"
-msgstr "Angiv præferenceliste til:\n"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "Really update the preferences for the selected user IDs? (y/N) "
-msgstr "Opdater præferencerne for de valgte bruger-id'er (j/N) "
+msgstr "Generér en annullérbar certifikat"
 
+#, fuzzy
 msgid "Really update the preferences? (y/N) "
-msgstr "Opdater præferencerne? (j/N) "
+msgstr "Generér en annullérbar certifikat"
 
+#, fuzzy
 msgid "Save changes? (y/N) "
-msgstr "Gem ændringer? (j/N) "
+msgstr "Gem ændringer? "
 
+#, fuzzy
 msgid "Quit without saving? (y/N) "
-msgstr "Afslut uden at gemme? (j/N) "
+msgstr "Afslut uden at gemme? "
 
 #, c-format
 msgid "update failed: %s\n"
-msgstr "opdatering mislykkedes: %s\n"
+msgstr ""
 
 #, c-format
 msgid "update secret failed: %s\n"
-msgstr "opdatering af hemmelighed mislykkedes: %s\n"
+msgstr ""
 
 msgid "Key not changed so no update needed.\n"
-msgstr "Nøgle ikke ændret så ingen opdatering krævet.\n"
+msgstr ""
 
 msgid "Digest: "
-msgstr "Sammendrag: "
+msgstr ""
 
 msgid "Features: "
-msgstr "Funktioner: "
+msgstr ""
 
 msgid "Keyserver no-modify"
-msgstr "Nøgleserver no-modify"
+msgstr ""
 
 msgid "Preferred keyserver: "
-msgstr "Fortrukken nøgleserver: "
+msgstr ""
 
+#, fuzzy
 msgid "Notations: "
-msgstr "Notationer: "
+msgstr ""
+"@\n"
+"Indstillinger:\n"
+" "
 
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
-msgstr "Der er ingen præferencer på en bruger-id i PGP 2.x-stil.\n"
+msgstr ""
 
-#, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "Den følgende nøgle blev tilbagekaldt den %s af %s nøgle %s\n"
+#, fuzzy, c-format
+msgid "This key was revoked on %s by %s key %s\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "This key may be revoked by %s key %s"
-msgstr "Denne nøgle er tilbagekaldt af %s nøgle %s"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
 msgid "(sensitive)"
-msgstr "(sensitiv)"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "created: %s"
-msgstr "oprettet: %s"
+msgstr "kan ikke oprette %s: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "revoked: %s"
-msgstr "tilbagekaldt: %s"
+msgstr "tilføj nøgle"
 
-#, c-format
+#, fuzzy, c-format
 msgid "expired: %s"
-msgstr "udløbet: %s"
+msgstr "Nøgle udløber d. %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "expires: %s"
-msgstr "udløber: %s"
+msgstr "Nøgle udløber d. %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "usage: %s"
-msgstr "brug: %s"
+msgstr "betro"
 
-#, c-format
+#, fuzzy, c-format
 msgid "trust: %s"
-msgstr "troværdighed: %s"
+msgstr "betro"
 
 #, c-format
 msgid "validity: %s"
-msgstr "validitet: %s"
+msgstr ""
 
 msgid "This key has been disabled"
-msgstr "Denne nøgle er blevet deaktiveret"
+msgstr ""
 
 msgid "card-no: "
-msgstr "kortnr.: "
+msgstr ""
 
 msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
 msgstr ""
-"Bemærk venligst at den viste nøglevaliditet ikke nødvendigvis er\n"
-"korrekt med mindre du genstarter programmet.\n"
 
+#, fuzzy
 msgid "revoked"
-msgstr "tilbagekaldt"
+msgstr "tilføj nøgle"
 
+#, fuzzy
 msgid "expired"
-msgstr "udløbet"
+msgstr "udløb"
 
 msgid ""
 "WARNING: no user ID has been marked as primary.  This command may\n"
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
-"ADVARSEL: Intet bruger-id er blevet markeret som primær. Denne kommando\n"
-"        kan medføre at et anden bruger-id bliver den formodede primære.\n"
-
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Du kan ikke ændre udløbsdatoen for en v3-nøgle\n"
 
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
 "         of PGP to reject this key.\n"
 msgstr ""
-"ADVARSEL: Dette er en nøgle i PGP2-stil. Tilføjelse af et billed-id kan "
-"medføre at\n"
-"          nogle version af PGP afviser denne nøgle.\n"
 
+#, fuzzy
 msgid "Are you sure you still want to add it? (y/N) "
-msgstr "Er du sikker på, at du stadig ønsker at tilføje den? (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
 msgid "You may not add a photo ID to a PGP2-style key.\n"
-msgstr "Du må ikke tilføje et billed-id til en nøgle i PGP2-stil.\n"
+msgstr ""
 
 msgid "Delete this good signature? (y/N/q)"
-msgstr "Slet denne gode underskrift? (j/N/a)"
+msgstr ""
 
 msgid "Delete this invalid signature? (y/N/q)"
-msgstr "Slet denne ugyldige underskrift? (j/N/a)"
+msgstr ""
 
 msgid "Delete this unknown signature? (y/N/q)"
-msgstr "Slet denne ukendte underskrift? (j/n/a)"
+msgstr ""
 
 msgid "Really delete this self-signature? (y/N)"
-msgstr "Virkelig slette denne egenunderskrift? (j/N)"
+msgstr ""
 
 #, c-format
 msgid "Deleted %d signature.\n"
-msgstr "Slettede %d underskrift.\n"
+msgstr "Slettede %d signatur.\n"
 
 #, c-format
 msgid "Deleted %d signatures.\n"
-msgstr "Slettede %d underskrifter.\n"
+msgstr ""
 
 msgid "Nothing deleted.\n"
-msgstr "Intet slettet.\n"
+msgstr ""
 
+#, fuzzy
 msgid "invalid"
-msgstr "ugyldig"
+msgstr "ugyldig rustning"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\" compacted: %s\n"
-msgstr "Bruger-id »%s« komprimeret: %s\n"
+msgstr "Nøglen er beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": %d signature removed\n"
-msgstr "Bruger-id »%s«: %d underskrift fjernet\n"
+msgstr "Nøglen er beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": %d signatures removed\n"
-msgstr "Bruger-id »%s«: %d underskrifter fjernet\n"
+msgstr "Nøglen er beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": already minimized\n"
-msgstr "Bruger-id »%s«: allerede minimeret\n"
+msgstr "Nøglen er beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "User ID \"%s\": already clean\n"
-msgstr "Bruger-id »%s«: allerede ryddet\n"
+msgstr "Nøglen er beskyttet.\n"
 
 msgid ""
 "WARNING: This is a PGP 2.x-style key.  Adding a designated revoker may "
 "cause\n"
 "         some versions of PGP to reject this key.\n"
 msgstr ""
-"ADVARSEL: Dette er en nøgle i PGP 2.x-stil. Tilføjelse af en dedikeret "
-"tilbagekalder\n"
-"          kan medføre at nogle versioner af PGP afviser denne nøgle.\n"
 
 msgid "You may not add a designated revoker to a PGP 2.x-style key.\n"
 msgstr ""
-"Du må ikke tilføje en dedikeret tilbagekalder til en nøgle i PGP 2.x-stil.\n"
 
+#, fuzzy
 msgid "Enter the user ID of the designated revoker: "
-msgstr "Indtast bruger'id for den dedikerede tilbagekalder: "
+msgstr "Indtast nøglens størrelse"
 
 msgid "cannot appoint a PGP 2.x style key as a designated revoker\n"
-msgstr "kan ikke udpege en nøgle i PGP 2.x-stil som dedikeret tilbagekalder\n"
+msgstr ""
 
 msgid "you cannot appoint a key as its own designated revoker\n"
-msgstr "du kan ikke udpege en nøgle som dets egen dedikerede tilbagekalder\n"
+msgstr ""
 
+#, fuzzy
 msgid "this key has already been designated as a revoker\n"
-msgstr "denne nøgle er allerede blevet dedikeret som en tilbagekalder\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
 msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n"
 msgstr ""
-"ADVARSEL: Udpegning af en nøgle som en dedikeret tilbagekalder kan ikke "
-"fortrydes!\n"
 
+#, fuzzy
 msgid ""
 "Are you sure you want to appoint this key as a designated revoker? (y/N) "
-msgstr ""
-"Er du sikker på, at du ønsker at udpege denne nøgle som en dedikeret "
-"tilbagekalder? (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
 msgid "Please remove selections from the secret keys.\n"
-msgstr "Fjern venligst markeringer fra de hemmelige nøgler.\n"
+msgstr ""
 
+#, fuzzy
 msgid "Please select at most one subkey.\n"
-msgstr "Vælg venligst højst en undernøgle.\n"
+msgstr "Vælg venligst hvilken slags nøgle du vil have:\n"
 
 msgid "Changing expiration time for a subkey.\n"
-msgstr "Ændrer udløbstidspunkt for en undernøgle.\n"
+msgstr ""
 
 msgid "Changing expiration time for the primary key.\n"
-msgstr "Ændrer udløbstidspunkt for den primære nøgle.\n"
+msgstr ""
 
 msgid "You can't change the expiration date of a v3 key\n"
-msgstr "Du kan ikke ændre udløbsdatoen for en v3-nøgle\n"
+msgstr ""
 
 msgid "No corresponding signature in secret ring\n"
-msgstr "Ingen tilsvarende underskrift i hemmelig ring\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "signing subkey %s is already cross-certified\n"
-msgstr "underskriftsundernøgle %s er allerede krydscertificeret\n"
+msgstr "Nøglen er beskyttet.\n"
 
 #, c-format
 msgid "subkey %s does not sign and so does not need to be cross-certified\n"
 msgstr ""
-"undernøgle %s underskriver ikke og skal derfor ikke være krydscertificeret\n"
 
+#, fuzzy
 msgid "Please select exactly one user ID.\n"
-msgstr "Vælg venligst præcis en bruger-id.\n"
+msgstr "Vælg venligst hvilken slags nøgle du vil have:\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "skipping v3 self-signature on user ID \"%s\"\n"
-msgstr "udelader v3 egenunderskrift på bruger-id »%s«\n"
+msgstr "nøgle %08lX: ingen gyldige bruger-id'er\n"
 
 msgid "Enter your preferred keyserver URL: "
-msgstr "Indtast din foretrukne nøglerserveradresse: "
+msgstr ""
 
+#, fuzzy
 msgid "Are you sure you want to replace it? (y/N) "
-msgstr "Er du sikker på, at du ønsker at erstatte den? (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
+#, fuzzy
 msgid "Are you sure you want to delete it? (y/N) "
-msgstr "Er du sikker på, at du ønsker at slette den? (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
 msgid "Enter the notation: "
-msgstr "Indtast notationen: "
+msgstr ""
 
+#, fuzzy
 msgid "Proceed? (y/N) "
-msgstr "Fortsæt? (j/N) "
+msgstr "Overskriv (j/N)? "
 
 #, c-format
 msgid "No user ID with index %d\n"
 msgstr "Ingen bruger-id med indeks %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "No user ID with hash %s\n"
-msgstr "Ingen bruger-id med hash %s\n"
+msgstr "Ingen bruger-id med indeks %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "No subkey with index %d\n"
-msgstr "Ingen undernøgle med indeks %d\n"
+msgstr "Ingen bruger-id med indeks %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "user ID: \"%s\"\n"
-msgstr "bruger-id: »%s«\n"
+msgstr "bruger-id: \""
 
 #, c-format
 msgid "signed by your key %s on %s%s%s\n"
-msgstr "underskrevet af din nøgle %s den %s%s%s\n"
+msgstr ""
 
 msgid " (non-exportable)"
-msgstr " (kan ikke eksporteres)"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "This signature expired on %s.\n"
-msgstr "Denne underskrift udløb den %s.\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
+#, fuzzy
 msgid "Are you sure you still want to revoke it? (y/N) "
-msgstr "Er du sikker på, at du ønsker at tilbagekalde den? (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
+#, fuzzy
 msgid "Create a revocation certificate for this signature? (y/N) "
-msgstr "Opret et tilbagekaldscertifikat for denne underskrift? (j/N) "
+msgstr "Generér en annullérbar certifikat"
 
 msgid "Not signed by you.\n"
-msgstr "Ikke underskrevet af dig.\n"
+msgstr ""
 
 #, c-format
 msgid "You have signed these user IDs on key %s:\n"
-msgstr "Du har underskrevet disse bruger-id'er på nøgle %s:\n"
+msgstr ""
 
+#, fuzzy
 msgid " (non-revocable)"
-msgstr " (kan ikke tilbagekaldes)"
+msgstr "signér en nøgle lokalt"
 
-#, c-format
+#, fuzzy, c-format
 msgid "revoked by your key %s on %s\n"
-msgstr "tilbagekaldt af din nøgle %s på %s\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
 msgid "You are about to revoke these signatures:\n"
-msgstr "Du er i gang med at tilbagekalde disse underskrifter:\n"
+msgstr ""
 
+#, fuzzy
 msgid "Really create the revocation certificates? (y/N) "
-msgstr "Opret tilbagekaldscertifikaterne? (j/N) "
+msgstr "Generér en annullérbar certifikat"
 
 msgid "no secret key\n"
-msgstr "ingen hemmelig nøgle\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "user ID \"%s\" is already revoked\n"
-msgstr "bruger-id »%s« er allerede tilbagekaldt\n"
+msgstr "Nøglen er beskyttet.\n"
 
 #, c-format
 msgid "WARNING: a user ID signature is dated %d seconds in the future\n"
 msgstr ""
-"ADVARSEL: En bruger-id-underskrift er dateret %d sekunder inde i fremtiden\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Key %s is already revoked.\n"
-msgstr "Nøgle %s er allerede tilbagekaldt.\n"
+msgstr "Nøglen er beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Subkey %s is already revoked.\n"
-msgstr "Undernøgle %s er allerede tilbagekaldt.\n"
+msgstr "Nøglen er beskyttet.\n"
 
 #, c-format
 msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
-msgstr "Viser %s billed'id med størrelse %ld for nøgle %s (uid %d)\n"
+msgstr ""
 
-#, c-format
-msgid "preference `%s' duplicated\n"
-msgstr "præference »%s« duplikeret\n"
+#, fuzzy, c-format
+msgid "preference '%s' duplicated\n"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "too many cipher preferences\n"
-msgstr "for mange chifferpræferencer\n"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "too many digest preferences\n"
-msgstr "for mange sammendragpræferencer\n"
+msgstr "vis præferencer"
 
+#, fuzzy
 msgid "too many compression preferences\n"
-msgstr "for mange komprimeringspræferencer\n"
+msgstr "vis præferencer"
 
-#, c-format
-msgid "invalid item `%s' in preference string\n"
-msgstr "ugyldigt punkt »%s« i præferencestreng\n"
+#, fuzzy, c-format
+msgid "invalid item '%s' in preference string\n"
+msgstr "Ugyldige bogstaver i navn\n"
 
+#, fuzzy
 msgid "writing direct signature\n"
-msgstr "skriver direkte underskrift\n"
+msgstr "skriver selvsignatur\n"
 
 msgid "writing self signature\n"
-msgstr "skriver egenunderskrift\n"
+msgstr "skriver selvsignatur\n"
 
 msgid "writing key binding signature\n"
-msgstr "skriver underskrift for nøglebinding\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "keysize invalid; using %u bits\n"
-msgstr "nøglestørrelse er ugyldig; bruger %u bit\n"
+msgstr "Ønsket nøglestørrelse er %u bit\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "keysize rounded up to %u bits\n"
-msgstr "nøglestørrelse afrundet op til %u bit\n"
+msgstr "rundet op til %u bit\n"
 
 msgid ""
 "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n"
 msgstr ""
-"ADVARSEL: Nogle OpenPGP-programmer kan ikke håndtere en DS-nøgle med denne\n"
-"sammendragsstørrelse\n"
 
+#, fuzzy
 msgid "Sign"
-msgstr "Underskriv"
+msgstr "signér"
 
 msgid "Certify"
-msgstr "Certificer"
+msgstr ""
 
+#, fuzzy
 msgid "Encrypt"
-msgstr "Krypter"
+msgstr "kryptér data"
 
 msgid "Authenticate"
-msgstr "Godkend"
+msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
 #. translation.  If this is not possible use single digits.  The
@@ -3465,81 +3401,81 @@ msgstr "Godkend"
 #. q = Finish
 #.
 msgid "SsEeAaQq"
-msgstr "UuKkGfAa"
+msgstr ""
 
 #, c-format
 msgid "Possible actions for a %s key: "
-msgstr "Mulige handligner for en %s-nøgle: "
+msgstr ""
 
 msgid "Current allowed actions: "
-msgstr "Aktuelt tilladte handlinger: "
+msgstr ""
 
 #, c-format
 msgid "   (%c) Toggle the sign capability\n"
-msgstr "   (%c) Skift evnen til at underskrive\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%c) Toggle the encrypt capability\n"
-msgstr "   (%c) Skift evnen til at kryptere\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
 #, c-format
 msgid "   (%c) Toggle the authenticate capability\n"
-msgstr "   (%c) Skift evnen til at godkende\n"
+msgstr ""
 
 #, c-format
 msgid "   (%c) Finished\n"
-msgstr "   (%c) Afsluttet\n"
+msgstr ""
 
 msgid "Please select what kind of key you want:\n"
-msgstr "Vælg venligst hvilken slags nøgle du vil have:\n"
+msgstr "Vælg venligst hvilken slags nøgle du vil have:\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA and RSA (default)\n"
-msgstr "   (%d) RSA og RSA (standard)\n"
+msgstr "   (%d) DSA og ElGamal (standard)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) DSA and Elgamal\n"
-msgstr "   (%d) DSA og Elgamal\n"
+msgstr "   (%d) DSA og ElGamal (standard)\n"
 
 #, c-format
 msgid "   (%d) DSA (sign only)\n"
-msgstr "   (%d) DSA (kun underskriv)\n"
+msgstr "   (%d) DSA (signér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA (sign only)\n"
-msgstr "   (%d) RSA (kun underskriv)\n"
+msgstr "   (%d) DSA (signér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) Elgamal (encrypt only)\n"
-msgstr "   (%d) Elgamal (kun krypter)\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA (encrypt only)\n"
-msgstr "   (%d) RSA (kun krypter)\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) DSA (set your own capabilities)\n"
-msgstr "   (%d) DSA (angiv dine egne evner)\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA (set your own capabilities)\n"
-msgstr "   (%d) RSA (angiv dine egne evner)\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
 #, c-format
 msgid "%s keys may be between %u and %u bits long.\n"
-msgstr "%s nøgler kan være mellem %u og %u bit lange.\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the subkey? (%u) "
-msgstr "Hvilken nøglestørrelse ønsker du for undernøglen? (%u) "
+msgstr "Hvilken nøglestørrelse ønsker du? (1024) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want? (%u) "
-msgstr "Hvilken nøglestørrelse ønsker du? (%u) "
+msgstr "Hvilken nøglestørrelse ønsker du? (1024) "
 
 #, c-format
 msgid "Requested keysize is %u bits\n"
-msgstr "Ønsket nøglestørrelse er %u bit\n"
+msgstr "Ønsket nøglestørrelse er %u bit\n"
 
 msgid ""
 "Please specify how long the key should be valid.\n"
@@ -3549,12 +3485,6 @@ msgid ""
 "      <n>m = key expires in n months\n"
 "      <n>y = key expires in n years\n"
 msgstr ""
-"Angiv i hvor lang tid nøglen skal være gyldig.\n"
-"         0 = nøgle udløber ikke\n"
-"      <n>  = nøgle udløber om n dage\n"
-"      <n>w = nøgle udløber om n uger\n"
-"      <n>m = nøgle udløber om n måneder\n"
-"      <n>y = nøgle udløber om n år\n"
 
 msgid ""
 "Please specify how long the signature should be valid.\n"
@@ -3564,55 +3494,48 @@ msgid ""
 "      <n>m = signature expires in n months\n"
 "      <n>y = signature expires in n years\n"
 msgstr ""
-"Angiv i hvor lang tid underskriften skal være gyldig.\n"
-"         0 = underskriften udløber ikke\n"
-"      <n>  = underskriften udløber om n dage\n"
-"      <n>w = underskriften udløber om n uger\n"
-"      <n>m = underskriften udløber om n måneder\n"
-"      <n>y = underskriften udløber om n år\n"
 
 msgid "Key is valid for? (0) "
-msgstr "Nøgle er gyldig for? (0) "
+msgstr "Nøgle er gyldig for? (0) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature is valid for? (%s) "
-msgstr "Underskrift er gyldig for? (%s) "
+msgstr "Nøgle er gyldig for? (0) "
 
 msgid "invalid value\n"
-msgstr "ugyldig værdi\n"
+msgstr "ugyldig værdi\n"
 
+#, fuzzy
 msgid "Key does not expire at all\n"
-msgstr "Nøglen udløber aldrig\n"
+msgstr "Nøglen udløber aldrig\n"
 
+#, fuzzy
 msgid "Signature does not expire at all\n"
-msgstr "Underskriften udløber aldrig\n"
+msgstr "Nøglen udløber aldrig\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Key expires at %s\n"
-msgstr "Nøglen udløber den %s\n"
+msgstr "Nøgle udløber d. %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature expires at %s\n"
-msgstr "Underskriften udløber den %s\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
 msgid ""
 "Your system can't display dates beyond 2038.\n"
 "However, it will be correctly handled up to 2106.\n"
 msgstr ""
-"Dit system kan ikke vise datoer efter 2038.\n"
-"Det vil dog blive korrekt håndteret op til 2106.\n"
 
+# virker j automatisk istedetfor y?
+#, fuzzy
 msgid "Is this correct? (y/N) "
-msgstr "Er dette korrekt? (j/N) "
+msgstr "Er dette korrekt (j/n)? "
 
 msgid ""
 "\n"
 "GnuPG needs to construct a user ID to identify your key.\n"
 "\n"
 msgstr ""
-"\n"
-"GnuPG skal konstruere et bruger-id for at identificere din nøgle.\n"
-"\n"
 
 #. TRANSLATORS: This string is in general not anymore used
 #. but you should keep your existing translation.  In case
@@ -3626,30 +3549,24 @@ msgid ""
 "    \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\n"
 "\n"
 msgstr ""
-"\n"
-"Du skal bruge en bruger-id for at identificere din nøgle; programmet "
-"konstruerer bruger-id'et\n"
-"fra fødselsnavn, kommentar og e-post-adresse i dette format:\n"
-"    »Heinrich Heine (digteren) <heinrichh@duesseldorf.de>«\n"
-"\n"
 
 msgid "Real name: "
-msgstr "Fødselsnavn: "
+msgstr "Rigtige navn: "
 
 msgid "Invalid character in name\n"
 msgstr "Ugyldige bogstaver i navn\n"
 
 msgid "Name may not start with a digit\n"
-msgstr "Navn må ikke starte med et tal\n"
+msgstr "Navn må ikke starte med et tal\n"
 
 msgid "Name must be at least 5 characters long\n"
-msgstr "Navn skal være mindst 5 bogstaver langt\n"
+msgstr "Navn skal være mindst 5 bogstaver langt\n"
 
 msgid "Email address: "
-msgstr "E-post-adresse: "
+msgstr "Epostadresse: "
 
 msgid "Not a valid email address\n"
-msgstr "Ikke en gyldig e-post-adresse\n"
+msgstr "Ikke en gyldig epostadresse\n"
 
 msgid "Comment: "
 msgstr "Kommentar: "
@@ -3658,8 +3575,8 @@ msgid "Invalid character in comment\n"
 msgstr "Ugyldigt tegn i kommentar\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
-msgstr "Du bruger tegnsættet »%s«.\n"
+msgid "You are using the '%s' character set.\n"
+msgstr "Du bruger '%s' tegnsættet.\n"
 
 #, c-format
 msgid ""
@@ -3672,10 +3589,10 @@ msgstr ""
 "\n"
 
 msgid "Please don't put the email address into the real name or the comment\n"
-msgstr "Placer ikke e-post-adressen i fødselsnavnet eller kommentaren\n"
+msgstr ""
 
 msgid "Such a user ID already exists on this key!\n"
-msgstr "Sådant et bruger-id findes allerede på denne nøgle!\n"
+msgstr ""
 
 #. TRANSLATORS: These are the allowed answers in
 #. lower and uppercase.  Below you will find the matching
@@ -3691,32 +3608,34 @@ msgstr "Sådant et bruger-id findes allerede på denne nøgle!\n"
 msgid "NnCcEeOoQq"
 msgstr "NnCcEeOoQq"
 
+#, fuzzy
 msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
-msgstr "Ændr (N)avn, (K)ommentar, (E)-post eller afslut(Q)? "
+msgstr "Ændr (N)avn, (K)ommentar, (E)post eller (O)kay/(Q)vit? "
 
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
-msgstr "Ændr (N)avn, (K)ommentar, (E)post eller (O)kay/afslut(Q)? "
+msgstr "Ændr (N)avn, (K)ommentar, (E)post eller (O)kay/(Q)vit? "
 
 msgid "Please correct the error first\n"
-msgstr "Ret venligst fejlen først\n"
+msgstr ""
 
 msgid ""
 "You need a Passphrase to protect your secret key.\n"
 "\n"
 msgstr ""
-"Du skal bruge en adgangsfrase til at beskytte din hemmelige nøgle.\n"
+"Du skal bruge en kodesætning til at beskytte din hemmelige nøgle.\n"
 "\n"
 
+#, fuzzy
 msgid ""
 "Please enter a passphrase to protect the off-card backup of the new "
 "encryption key."
 msgstr ""
-"Indtast venligst en adgangsfrase til at beskytte sikkerhedskopien fortaget "
-"uden for kortet af den nye krypteringsnøgle."
+"Du skal bruge en kodesætning til at beskytte din hemmelige nøgle.\n"
+"\n"
 
 #, c-format
 msgid "%s.\n"
-msgstr "%s.\n"
+msgstr ""
 
 msgid ""
 "You don't want a passphrase - this is probably a *bad* idea!\n"
@@ -3724,10 +3643,6 @@ msgid ""
 "using this program with the option \"--edit-key\".\n"
 "\n"
 msgstr ""
-"Du ønsker ikke en adgangsfrase - dette er en *dårlig* ide!\n"
-"Jeg giver dig en alligevel. Du kan ændre din adgangsfrase på\n"
-"ethvert tidspunkt ved at bruge dette program med tilvalget\n"
-"»--edit-key«.\n"
 
 msgid ""
 "We need to generate a lot of random bytes. It is a good idea to perform\n"
@@ -3735,575 +3650,562 @@ msgid ""
 "disks) during the prime generation; this gives the random number\n"
 "generator a better chance to gain enough entropy.\n"
 msgstr ""
-"Vi skal oprette en masse tilfældige byte. Det er en god ide at udføre\n"
-"nogle andre handlinger (tryk på tastaturet, flyt musen, brug diskene)\n"
-"under oprettelse af primtallet; dette giver det vilkårlig\n"
-"taloprettelsesprogram en bedre mulighed for at opnå nok entropi.\n"
 
 msgid "Key generation canceled.\n"
-msgstr "Nøgleoprettelse annulleret.\n"
+msgstr "Nøgleoprettelse annulleret.\n"
 
-#, c-format
-msgid "writing public key to `%s'\n"
-msgstr "skriver offentlig nøgle til »%s«\n"
+#, fuzzy, c-format
+msgid "writing public key to '%s'\n"
+msgstr "skriver offentligt certifikat til '%s'\n"
 
-#, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "skriver hemmelig nøglestump til »%s«\n"
+#, fuzzy, c-format
+msgid "writing secret key stub to '%s'\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
-#, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "skriver hemmelig nøgle til »%s«\n"
+#, fuzzy, c-format
+msgid "writing secret key to '%s'\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "no writable public keyring found: %s\n"
-msgstr "ingen skrivbar offentlig nøglering fundet: %s\n"
+msgstr "nøgle %08lX: offentlig nøgle ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "no writable secret keyring found: %s\n"
-msgstr "ingen skrivbar hemmelig nøglering fundet: %s\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
-#, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "fejl ved skrivning af offentlig nøglering »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error writing public keyring '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "fejl ved skrivning af hemmelig nøglering »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error writing secret keyring '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
-msgstr "offentlig og hemmelig nøgle oprettet og underskrevet.\n"
+msgstr "offentlig og hemmelig nøgle oprettet og signeret.\n"
 
 msgid ""
 "Note that this key cannot be used for encryption.  You may want to use\n"
 "the command \"--edit-key\" to generate a subkey for this purpose.\n"
 msgstr ""
-"Bemærk at denne nøgle ikke kan bruges til kryptering. Du kan bruge\n"
-"kommandoen »--edit-key« til at oprette en undernøgle til dette formål.\n"
 
 #, c-format
 msgid "Key generation failed: %s\n"
-msgstr "Nøgleoprettelse mislykkedes: %s\n"
+msgstr ""
 
 #, c-format
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr ""
-"nøgle er blevet oprettet %lu sekund i fremtiden (tidsforskydning eller "
-"urproblem)\n"
 
 #, c-format
 msgid ""
 "key has been created %lu seconds in future (time warp or clock problem)\n"
 msgstr ""
-"nøgle er blevet oprettet %lu sekunder i fremtiden (tidsforskydning eller "
-"urproblem)\n"
 
 msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
 msgstr ""
-"BEMÆRK: Oprettelse af undernøgler for v3-nøgler overholder ikke OpenPGP\n"
 
+#, fuzzy
 msgid "Really create? (y/N) "
-msgstr "Vil du virkelig oprette? (j/N) "
+msgstr "Vil du virkelig oprette?"
 
-#, c-format
+#, fuzzy, c-format
 msgid "storing key onto card failed: %s\n"
-msgstr "lagring af nøgle på kort mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
-#, c-format
-msgid "can't create backup file `%s': %s\n"
-msgstr "kan ikke oprette sikkerhedskopifil »%s«: %s\n"
+#, fuzzy, c-format
+msgid "can't create backup file '%s': %s\n"
+msgstr "kan ikke oprette %s: %s\n"
 
-#, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
-msgstr "BEMÆRK: sikkerhedskopi af kortnøgle gemt på »%s«\n"
+#, fuzzy, c-format
+msgid "NOTE: backup of card key saved to '%s'\n"
+msgstr "hemmelige nøgler import: %lu\n"
 
 msgid "never     "
-msgstr "aldrig    "
+msgstr ""
 
+#, fuzzy
 msgid "Critical signature policy: "
-msgstr "Kritisk underskriftspolitik: "
+msgstr "%s signatur fra: %s\n"
 
+#, fuzzy
 msgid "Signature policy: "
-msgstr "Underskriftspolitik: "
+msgstr "%s signatur fra: %s\n"
 
 msgid "Critical preferred keyserver: "
-msgstr "Kritisk foretrukken nøgleserver: "
+msgstr ""
 
 msgid "Critical signature notation: "
-msgstr "Kritisk underskriftnotation: "
+msgstr ""
 
 msgid "Signature notation: "
-msgstr "Underskriftsnotation: "
+msgstr ""
 
 msgid "Keyring"
-msgstr "Nøglering"
+msgstr ""
 
+#, fuzzy
 msgid "Primary key fingerprint:"
-msgstr "Primær nøglefingeraftryk:"
+msgstr "vis nøgle og fingeraftryk"
 
+#, fuzzy
 msgid "     Subkey fingerprint:"
-msgstr "     Undernøglefingeraftryk:"
+msgstr "             Fingeraftryk:"
 
 #. TRANSLATORS: this should fit into 24 bytes to that the
 #. * fingerprint data is properly aligned with the user ID
+#, fuzzy
 msgid " Primary key fingerprint:"
-msgstr "Primær nøglefingeraftryk:"
+msgstr "             Fingeraftryk:"
 
+#, fuzzy
 msgid "      Subkey fingerprint:"
-msgstr "  Undernøglefingeraftryk:"
+msgstr "             Fingeraftryk:"
 
+#, fuzzy
 msgid "      Key fingerprint ="
-msgstr "    Nøglefingeraftryk ="
-
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "ADVARSEL: bruger eksperimentel sammendragsalgoritme %s\n"
+msgstr "             Fingeraftryk:"
 
 msgid "      Card serial no. ="
-msgstr "   Serielnr. for kort ="
+msgstr ""
 
-#, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
-msgstr "omdøbelse af »%s« til »%s« mislykkedes: %s\n"
+#, fuzzy, c-format
+msgid "renaming '%s' to '%s' failed: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr "ADVARSEL: 2 filer med fortrolig information findes.\n"
+msgstr ""
 
 #, c-format
 msgid "%s is the unchanged one\n"
-msgstr "%s er den uændrede\n"
+msgstr ""
 
 #, c-format
 msgid "%s is the new one\n"
-msgstr "%s er den nye\n"
+msgstr ""
 
 msgid "Please fix this possible security flaw\n"
-msgstr "Ret venligst denne mulige sikkerhedsrisiko\n"
+msgstr ""
 
-#, c-format
-msgid "caching keyring `%s'\n"
-msgstr "mellemlagrer nøglering »%s«\n"
+#, fuzzy, c-format
+msgid "caching keyring '%s'\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%lu keys cached so far (%lu signatures)\n"
-msgstr "%lu nøgler mellemlagret indtil nu (%lu underskrifter)\n"
+msgstr "vis nøgler og signaturer"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%lu keys cached (%lu signatures)\n"
-msgstr "%lu nøgler mellemlagret (%lu underskrifter)\n"
+msgstr "vis nøgler og signaturer"
 
 #, c-format
 msgid "%s: keyring created\n"
-msgstr "%s: nøglering oprettet\n"
+msgstr ""
 
 msgid "include revoked keys in search results"
-msgstr "inkluder tilbagekaldte nøgler i søgeresultater"
+msgstr ""
 
 msgid "include subkeys when searching by key ID"
-msgstr "inkluder undernøgler når der søges efter nøgle-id"
+msgstr ""
 
 msgid "use temporary files to pass data to keyserver helpers"
-msgstr "brug midlertidige filer til at sende data til nøgleserverhjælpere"
+msgstr ""
 
 msgid "do not delete temporary files after using them"
-msgstr "slet ikke midlertidige filer efter at de er blevet brugt"
+msgstr ""
 
 msgid "automatically retrieve keys when verifying signatures"
-msgstr "hent automatisk nøgler når der verificeres underskrifter"
+msgstr ""
 
+#, fuzzy
 msgid "honor the preferred keyserver URL set on the key"
-msgstr "overhold den foretrukne nøglerserveradresse angivet på nøglen"
+msgstr "den givne politik-URL er ugyldig\n"
 
 msgid "honor the PKA record set on a key when retrieving keys"
-msgstr "overhold PKA-posten angivet på en nøgle når der hentes nøgler"
+msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
-msgstr "ADVARSEL: nøgleserverindstilling »%s« bruges ikke på denne platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
+msgstr ""
 
+#, fuzzy
 msgid "disabled"
-msgstr "deaktiveret"
+msgstr "slåfra"
 
 msgid "Enter number(s), N)ext, or Q)uit > "
-msgstr "Indtal tal, N)æste eller Q) for Afslut > "
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "invalid keyserver protocol (us %d!=handler %d)\n"
-msgstr "ugyldig nøgleserverprotokol (os %d!=håndtag %d)\n"
+msgstr "ugyldig nøglering"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key \"%s\" not found on keyserver\n"
-msgstr "nøgle »%s« blev ikke fundet på nøgleserver\n"
+msgstr "%s: bruger ikke fundet: %s\n"
 
+#, fuzzy
 msgid "key not found on keyserver\n"
-msgstr "nøgle blev ikke fundet på nøgleserver\n"
+msgstr "%s: bruger ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "requesting key %s from %s server %s\n"
-msgstr "anmoder om nøgle %s fra %s server %s\n"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "requesting key %s from %s\n"
-msgstr "anmoder om nøgle %s fra %s\n"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "searching for names from %s server %s\n"
-msgstr "søger efter navne fra %s server %s\n"
+msgstr "eksportér nøgler til en nøgletjener"
 
-#, c-format
+#, fuzzy, c-format
 msgid "searching for names from %s\n"
-msgstr "søger efter navne fra %s\n"
+msgstr "læser indstillinger fra `%s'\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
-msgstr "sender nøgle %s til %s server %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "sending key %s to %s\n"
-msgstr "sender nøgle %s til %s\n"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "searching for \"%s\" from %s server %s\n"
-msgstr "søger efter »%s« fra %s server %s\n"
+msgstr "eksportér nøgler til en nøgletjener"
 
-#, c-format
+#, fuzzy, c-format
 msgid "searching for \"%s\" from %s\n"
-msgstr "søger efter »%s« fra %s\n"
+msgstr "læser indstillinger fra `%s'\n"
 
+#, fuzzy
 msgid "no keyserver action!\n"
-msgstr "ingen nøgleserverhandling!\n"
+msgstr "ugyldig nøglering"
 
 #, c-format
 msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr "ADVARSEL: nøgleserverhåndtering fra en anden version af GnuPG (%s)\n"
+msgstr ""
 
 msgid "keyserver did not send VERSION\n"
-msgstr "nøgleserver sendte ikke VERSION\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "kommunikationsfejl for nøgleserver: %s\n"
+msgstr ""
 
 msgid "no keyserver known (use option --keyserver)\n"
-msgstr "ingen kendt nøgleserver (brug tilvalget --keyserver)\n"
+msgstr ""
 
 msgid "external keyserver calls are not supported in this build\n"
-msgstr "eksterne nøgleserverkald er ikke understøttet i denne bygning\n"
+msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "ingen håndtering for nøgleserverskema »%s«\n"
+msgid "no handler for keyserver scheme '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
-msgstr "handling »%s« er ikke understøttet med nøgleserverskema »%s«\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
+msgstr ""
 
 #, c-format
 msgid "%s does not support handler version %d\n"
-msgstr "%s understøtter ikke håndteringsversion %d\n"
+msgstr ""
 
+#, fuzzy
 msgid "keyserver timed out\n"
-msgstr "nøgleserver fik tidsudløb\n"
+msgstr "generel fejl"
 
+#, fuzzy
 msgid "keyserver internal error\n"
-msgstr "nøgleserver fik intern fejl\n"
+msgstr "generel fejl"
 
-#, c-format
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
+
+#, fuzzy, c-format
 msgid "\"%s\" not a key ID: skipping\n"
-msgstr "»%s« er ikke et nøgle-id: udelader\n"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
 #, c-format
 msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr "ADVARSEL: Kan ikke opdatere nøgle %s via %s: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "refreshing 1 key from %s\n"
-msgstr "opdaterer 1 nøgle fra %s\n"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "refreshing %d keys from %s\n"
-msgstr "opdaterer %d nøgler fra %s\n"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
-msgstr "ADVARSEL: kan ikke hente URI %s: %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
 #, c-format
 msgid "WARNING: unable to parse URI %s\n"
-msgstr "ADVARSEL: kan ikke fortolke URI %s\n"
+msgstr ""
 
 #, c-format
 msgid "weird size for an encrypted session key (%d)\n"
-msgstr "underlig størrelse for en krypteret sessionsnøgle (%d)\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s encrypted session key\n"
-msgstr "%s krypteret sessionsnøgle\n"
+msgstr "%s/%s krypteret for: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "passphrase generated with unknown digest algorithm %d\n"
-msgstr "adgangsfrase oprettet med ukendt sammendragsalgoritme %d\n"
+msgstr "ukendt cifferalgoritme "
 
-#, c-format
+#, fuzzy, c-format
 msgid "public key is %s\n"
-msgstr "offentlig nøgle er %s\n"
+msgstr "Offentlig nøgle er slået fra.\n"
 
 msgid "public key encrypted data: good DEK\n"
-msgstr "krypterede data for offentlig nøgle: god DEK\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "encrypted with %u-bit %s key, ID %s, created %s\n"
-msgstr "krypteret med %u-bit %s nøgle, id %s, oprettet %s\n"
+msgstr "Gentag kodesætning: "
 
-#, c-format
+#, fuzzy, c-format
 msgid "      \"%s\"\n"
-msgstr "      »%s«\n"
+msgstr "              alias \""
 
-#, c-format
+#, fuzzy, c-format
 msgid "encrypted with %s key, ID %s\n"
-msgstr "krypteret med %s nøgle, id %s\n"
+msgstr "Gentag kodesætning: "
 
 #, c-format
 msgid "public key decryption failed: %s\n"
-msgstr "afkryptering af offentlig nøgle mislykkedes: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "encrypted with %lu passphrases\n"
-msgstr "krypteret med %lu adgangsfraser\n"
+msgstr "Gentag kodesætning: "
 
+#, fuzzy
 msgid "encrypted with 1 passphrase\n"
-msgstr "krypteret med 1 adgangsfrase\n"
+msgstr "Gentag kodesætning: "
 
-#, c-format
+#, fuzzy, c-format
 msgid "assuming %s encrypted data\n"
-msgstr "antager %s krypterede data\n"
+msgstr "kryptér data"
 
 #, c-format
 msgid "IDEA cipher unavailable, optimistically attempting to use %s instead\n"
 msgstr ""
-"IDEA-chiffer utilgængelig, forsøger optimistisk at bruge %s i stedet for\n"
 
 msgid "decryption okay\n"
-msgstr "afkryptering okay\n"
+msgstr ""
 
+#, fuzzy
 msgid "WARNING: message was not integrity protected\n"
-msgstr "ADVARSEL: besked var ikke integritetsbeskyttet\n"
+msgstr "ADVARSEL: intet blev eksporteret\n"
 
 msgid "WARNING: encrypted message has been manipulated!\n"
-msgstr "ADVARSEL: krypteret besked er blevet manipuleret!\n"
+msgstr ""
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
-msgstr "ryddet adgangsfrase mellemlagret med id: %s\n"
+msgstr ""
 
 #, c-format
 msgid "decryption failed: %s\n"
-msgstr "afkryptering mislykkedes: %s\n"
+msgstr ""
 
 msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
-msgstr "BEMÆRK: afsender anmodte om »for-your-eyes-only«\n"
+msgstr ""
 
 #, c-format
 msgid "original file name='%.*s'\n"
-msgstr "oprindeligt filnavn=»%.*s«\n"
+msgstr ""
 
 msgid "WARNING: multiple plaintexts seen\n"
-msgstr "ADVARSEL: flere klartekster set\n"
+msgstr ""
 
 msgid "standalone revocation - use \"gpg --import\" to apply\n"
-msgstr "uafhængig tilbagekald - brug »gpg --import« for at anvende\n"
+msgstr ""
 
+#, fuzzy
 msgid "no signature found\n"
-msgstr "ingen underskrift fundet\n"
+msgstr "God signatur fra \""
 
 msgid "signature verification suppressed\n"
-msgstr "underskriftverificering undertrykt\n"
+msgstr ""
 
+#, fuzzy
 msgid "can't handle this ambiguous signature data\n"
-msgstr "kan ikke håndtere disse tvetydige underskriftdata\n"
+msgstr "opret en separat signatur"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature made %s\n"
-msgstr "Underskrift lavet %s\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "               using %s key %s\n"
-msgstr "               bruger %s nøgle %s\n"
+msgstr "              alias \""
 
 #, c-format
 msgid "Signature made %s using %s key ID %s\n"
-msgstr "Underskrift lavet %s med %s nøgle-id %s\n"
+msgstr ""
 
+#, fuzzy
 msgid "Key available at: "
-msgstr "Nøgle tilgængelig på: "
+msgstr "Ingen hjælp tilgængelig"
 
-#, c-format
+#, fuzzy, c-format
 msgid "BAD signature from \"%s\""
-msgstr "UGYLDIG underskrift fra »%s«"
+msgstr "DÅRLIG signatur fra \""
 
-#, c-format
+#, fuzzy, c-format
 msgid "Expired signature from \"%s\""
-msgstr "Udløbet underskrift fra »%s«"
+msgstr "God signatur fra \""
 
-#, c-format
+#, fuzzy, c-format
 msgid "Good signature from \"%s\""
-msgstr "God underskrift fra »%s«"
+msgstr "God signatur fra \""
 
 msgid "[uncertain]"
-msgstr "[usikker]"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "                aka \"%s\""
-msgstr "       også kendt som »%s«"
+msgstr "              alias \""
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature expired %s\n"
-msgstr "Underskrift udløbet %s\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature expires %s\n"
-msgstr "Underskrift udløber %s\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s signature, digest algorithm %s\n"
-msgstr "%s underskrift, sammendragsalgoritme %s\n"
+msgstr "%s signatur fra: %s\n"
 
 msgid "binary"
-msgstr "binær"
+msgstr ""
 
 msgid "textmode"
-msgstr "tekstilstand"
+msgstr ""
 
+#, fuzzy
 msgid "unknown"
-msgstr "ukendt"
-
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-"ADVARSEL: Ikke en frakoblet underskrift; filen »%s« blev IKKE verificeret!\n"
+msgstr "ukendt version"
 
 #, c-format
 msgid "Can't check signature: %s\n"
-msgstr "Kan ikke kontrollere underskrift: %s\n"
+msgstr "Kan ikke tjekke signatur: %s\n"
 
+#, fuzzy
 msgid "not a detached signature\n"
-msgstr "ikke en frakoblet underskrift\n"
+msgstr "opret en separat signatur"
 
 msgid ""
 "WARNING: multiple signatures detected.  Only the first will be checked.\n"
 msgstr ""
-"ADVARSEL: flere underskrifter detekteret. Kun den første vil blive "
-"kontrolleret.\n"
 
 #, c-format
 msgid "standalone signature of class 0x%02x\n"
-msgstr "uafhængig underskrift for klasse 0x%02x\n"
+msgstr ""
 
 msgid "old style (PGP 2.x) signature\n"
-msgstr "gammeldags (PGP 2.x) underskrift\n"
+msgstr "gammeldags (PGP 2.x) signatur\n"
 
 msgid "invalid root packet detected in proc_tree()\n"
-msgstr "ugyldig rodpakke detekteret i proc_tree()\n"
+msgstr ""
 
-#, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
-msgstr "fstat for »%s« mislykkedes i %s: %s\n"
+#, fuzzy, c-format
+msgid "fstat of '%s' failed in %s: %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
 #, c-format
 msgid "fstat(%d) failed in %s: %s\n"
-msgstr "fstat(%d) mislykkedes i %s: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: using experimental public key algorithm %s\n"
-msgstr "ADVARSEL: bruger eksperimentel offentlig nøglealgoritme %s\n"
+msgstr "nøgle %08lX: offentlig nøgle ikke fundet: %s\n"
 
+#, fuzzy
 msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n"
-msgstr "ADVARSEL: Elgamalnøgler for underskriv+krypter er forældede\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: using experimental cipher algorithm %s\n"
-msgstr "ADVARSEL: bruger eksperimentel chifferalgoritme %s\n"
+msgstr "uimplementeret cifferalgoritme"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: using experimental digest algorithm %s\n"
-msgstr "ADVARSEL: bruger eksperimentel sammendragsalgoritme %s\n"
+msgstr "%s signatur fra: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: digest algorithm %s is deprecated\n"
-msgstr "ADVARSEL: sammendragsalgoritme %s er forældet\n"
-
-#, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Bemærk: underskrifter der bruger %s-algoritmen videresendes\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
 msgid "the IDEA cipher plugin is not present\n"
-msgstr "udvidelsesmodulet for IDEA-chifret er ikke til stede\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "please see %s for more information\n"
-msgstr "se venligst %s for yderligere information\n"
+msgstr "rev- forkert nøgletilbagekald\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
-msgstr "%s:%d: forældet indstilling »%s«\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: \"%s\" is a deprecated option\n"
-msgstr "ADVARSEL: »%s« er en forældet indstilling\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
 #, c-format
 msgid "please use \"%s%s\" instead\n"
-msgstr "brug venligst »%s%s« i stedet for\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: \"%s\" is a deprecated command - do not use it\n"
-msgstr "ADVARSEL: »%s« er en forældet kommando - brug den ikke\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
 #, c-format
 msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgstr "%s:%u: forældet indstilling »%s« - den har ingen effekt\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr "ADVARSEL: »%s« er en forældet indstilling - den har ingen effekt\n"
-
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: »%s%s« er forældet i denne fil - den har kun effekt i %s\n"
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr ""
-"ADVARSEL: »%s%s« er en forældet indstilling - den har ingen effekt på %s\n"
+msgstr "ADVARSEL: '%s' er en tom fil\n"
 
+#, fuzzy
 msgid "Uncompressed"
-msgstr "Ukomprimeret"
+msgstr "ikke bearbejdet"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
+#, fuzzy
 msgid "uncompressed|none"
-msgstr "ukomprimeret|ingen"
+msgstr "ikke bearbejdet"
 
 #, c-format
 msgid "this message may not be usable by %s\n"
-msgstr "denne besked kan nok ikke bruges af %s\n"
+msgstr ""
 
-#, c-format
-msgid "ambiguous option `%s'\n"
-msgstr "tvetydigt tilvalg »%s«\n"
+#, fuzzy, c-format
+msgid "ambiguous option '%s'\n"
+msgstr "læser indstillinger fra `%s'\n"
 
-#, c-format
-msgid "unknown option `%s'\n"
-msgstr "ukendt tilvalg »%s«\n"
+#, fuzzy, c-format
+msgid "unknown option '%s'\n"
+msgstr "ukendt standard modtager '%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
-msgstr "Filen »%s« findes. "
+msgid "File '%s' exists. "
+msgstr "Fil `%s' eksisterer. "
 
+#, fuzzy
 msgid "Overwrite? (y/N) "
-msgstr "Overskriv? (j/N) "
+msgstr "Overskriv (j/N)? "
 
 #, c-format
 msgid "%s: unknown suffix\n"
@@ -4317,37 +4219,32 @@ msgstr "skriver til stdout\n"
 
 #, c-format
 msgid "assuming signed data in '%s'\n"
-msgstr "antager underskrevne data i »%s«\n"
+msgstr ""
 
 #, c-format
-msgid "new configuration file `%s' created\n"
-msgstr "ny konfigurationsfil »%s« oprettet\n"
+msgid "new configuration file '%s' created\n"
+msgstr ""
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
-"ADVARSEL: indstillinger i »%s« er endnu ikke aktive under denne kørsel\n"
 
 #, c-format
 msgid "can't handle public key algorithm %d\n"
-msgstr "kan ikke håndtere offentlig nøglealgoritme %d\n"
+msgstr ""
 
 msgid "WARNING: potentially insecure symmetrically encrypted session key\n"
-msgstr "ADVARSEL: potentiel usikker symmetrisk krypteret sessionsnøgle\n"
+msgstr ""
 
 #, c-format
 msgid "subpacket of type %d has critical bit set\n"
-msgstr "underpakke af typen %d har kritiske bitsæt\n"
-
-#, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problem med agenten: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid " (main key ID %s)"
-msgstr " (hovednøgle-id %s)"
+msgstr " (hovednøgle-ID %08lX)"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Please enter the passphrase to unlock the secret key for the OpenPGP "
 "certificate:\n"
@@ -4355,33 +4252,35 @@ msgid ""
 "%u-bit %s key, ID %s,\n"
 "created %s%s.\n"
 msgstr ""
-"Indtast venligst adgangsfrasen til at åbne den hemmelige nøgle for OpenPGP-"
-"certifikatet:\n"
-"\"%.*s\"\n"
-"%u-bit %s nøgle, id %s,\n"
-"oprettet %s%s.\n"
+"Du skal bruge en kodesætning til at beskytte din hemmelige nøgle.\n"
+"\n"
 
+#, fuzzy
 msgid "Enter passphrase\n"
-msgstr "Indtast adgangsfrase\n"
+msgstr "Indtast kodesætning: "
 
 msgid "cancelled by user\n"
-msgstr "afbrudt af bruger\n"
+msgstr ""
 
 #, c-format
+msgid "problem with the agent: %s\n"
+msgstr ""
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
 msgstr ""
-"Du skal bruge en adgangsfrase til at åbne den hemmelige\n"
-"nøgle for bruger: »%s«\n"
+"Du skal bruge en kodesætning til at beskytte din hemmelige nøgle.\n"
+"\n"
 
 #, c-format
 msgid "%u-bit %s key, ID %s, created %s"
-msgstr "%u-bit %s nøgle, id %s, oprettet %s"
+msgstr ""
 
 #, c-format
 msgid "         (subkey on main key ID %s)"
-msgstr "         (undernøgle på hovednøgle-id %s)"
+msgstr ""
 
 msgid ""
 "\n"
@@ -4390,205 +4289,192 @@ msgid ""
 "very large picture, your key will become very large as well!\n"
 "Keeping the image close to 240x288 is a good size to use.\n"
 msgstr ""
-"\n"
-"Vælg et billede til brug for dit billed-id. Billedet skal være en JPEG-fil.\n"
-"Husk at billedet gemmes i din offentlige nøgle. Hvis du bruger et meget\n"
-"stort billede, vil din nøgle også blive meget stor!\n"
-"En billede på 240x288 er en god størrelse.\n"
 
 msgid "Enter JPEG filename for photo ID: "
-msgstr "Indtast JPEG-filnavn for billed-id: "
+msgstr ""
 
-#, c-format
-msgid "unable to open JPEG file `%s': %s\n"
-msgstr "kan ikke åbne JPEG-fil »%s«: %s\n"
+#, fuzzy, c-format
+msgid "unable to open JPEG file '%s': %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
 #, c-format
 msgid "This JPEG is really large (%d bytes) !\n"
-msgstr "Denne JPEG er virkelig stor (%d byte) !\n"
+msgstr ""
 
+#, fuzzy
 msgid "Are you sure you want to use it? (y/N) "
-msgstr "Er du sikker på, at du vil benytte billedet (j/N) "
+msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
 
-#, c-format
-msgid "`%s' is not a JPEG file\n"
-msgstr "»%s« er ikke en JPEG-fil\n"
+#, fuzzy, c-format
+msgid "'%s' is not a JPEG file\n"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
+# virker j automatisk istedetfor y?
+#, fuzzy
 msgid "Is this photo correct (y/N/q)? "
-msgstr "Er dette billede korrekt (j/N/a)? "
+msgstr "Er dette korrekt (j/n)? "
 
+#, fuzzy
 msgid "unable to display photo ID!\n"
-msgstr "kan ikke vise billed-id!\n"
+msgstr "kan ikke åbne %s: %s\n"
 
 msgid "No reason specified"
-msgstr "Ingen årsag angivet"
+msgstr ""
 
+#, fuzzy
 msgid "Key is superseded"
-msgstr "Nøglen er blevet afløst"
+msgstr "Nøglen er beskyttet.\n"
 
 msgid "Key has been compromised"
-msgstr "Nøglen er blevet komprimeret"
+msgstr ""
 
 msgid "Key is no longer used"
-msgstr "Nøglen bruges ikke længere"
+msgstr ""
 
 msgid "User ID is no longer valid"
-msgstr "Bruger-id er ikke længere gyldigt"
+msgstr ""
 
+#, fuzzy
 msgid "reason for revocation: "
-msgstr "årsag for tilbagekald: "
+msgstr "rev- forkert nøgletilbagekald\n"
 
 msgid "revocation comment: "
-msgstr "tilbagekaldskommentar: "
+msgstr ""
 
-# ikke helt klart hvad de her forkortelser står for
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
-msgstr "iImMqQsS"
+msgstr ""
 
+#, fuzzy
 msgid "No trust value assigned to:\n"
-msgstr "Ingen tillidsværdi tildelt til:\n"
+msgstr ""
+"Ingen tillidsværdi tildelt til %lu:\n"
+"%4u%c/%08lX %s \""
 
-#, c-format
+#, fuzzy, c-format
 msgid "  aka \"%s\"\n"
-msgstr "  også kendt som »%s«\n"
+msgstr "              alias \""
 
+#, fuzzy
 msgid ""
 "How much do you trust that this key actually belongs to the named user?\n"
-msgstr ""
-"Hvor stor er din tillid til at denne nøgle rent faktisk tilhører den "
-"navngivne ejer?\n"
+msgstr "Denne nøgle tilhører sikkert ejeren\n"
 
 #, c-format
 msgid "  %d = I don't know or won't say\n"
-msgstr "  %d = Jeg ved det ikke eller vil ikke sige det\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "  %d = I do NOT trust\n"
-msgstr "  %d = Jeg stoler IKKE på denne nøgle\n"
+msgstr "%08lX: Vi stoler IKKE på denne nøgle\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "  %d = I trust ultimately\n"
-msgstr "  %d = Jeg stoler fuldstændig på denne nøgle\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
+#, fuzzy
 msgid "  m = back to the main menu\n"
-msgstr "  h = tilbage til hovedmenuen\n"
+msgstr " m = tilbage til hovedmenu\n"
 
+#, fuzzy
 msgid "  s = skip this key\n"
-msgstr "  s = udelad denne nøgle\n"
+msgstr "%s: udelod: %s\n"
 
+#, fuzzy
 msgid "  q = quit\n"
-msgstr "  a = afslut\n"
+msgstr " q = afslut\n"
 
 #, c-format
 msgid ""
 "The minimum trust level for this key is: %s\n"
 "\n"
 msgstr ""
-"Minimumstroværdighedsniveau for denne nøgle er: %s\n"
-"\n"
 
 msgid "Your decision? "
 msgstr "Dit valg? "
 
+#, fuzzy
 msgid "Do you really want to set this key to ultimate trust? (y/N) "
-msgstr "Vil du virkelig gerne give denne nøgle ultimativ troværdighed? (j/N) "
+msgstr "Vil du virkelig gerne gøre dette?"
 
 msgid "Certificates leading to an ultimately trusted key:\n"
-msgstr "Certifikater der fører til en ultimativ troværdig nøgle:\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s: There is no assurance this key belongs to the named user\n"
-msgstr ""
-"%s: Der er ingen garanti for, at denne nøgle tilhører den navngivne bruger\n"
+msgstr "         Intet tyder på at denne signatur tilhører ejeren.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s: There is limited assurance this key belongs to the named user\n"
-msgstr ""
-"%s: Der er begrænset garanti for, at denne nøgle tilhører den navngivne "
-"bruger\n"
+msgstr "         Intet tyder på at denne signatur tilhører ejeren.\n"
 
+#, fuzzy
 msgid "This key probably belongs to the named user\n"
-msgstr "Denne nøgle tilhører sikkert den navngivne bruger\n"
+msgstr "Denne nøgle tilhører sikkert ejeren\n"
 
 msgid "This key belongs to us\n"
-msgstr "Denne nøgle tilhører os\n"
+msgstr "Denne nøgle tilhører os\n"
 
 msgid ""
 "It is NOT certain that the key belongs to the person named\n"
 "in the user ID.  If you *really* know what you are doing,\n"
 "you may answer the next question with yes.\n"
 msgstr ""
-"Det er IKKE sikkert, at nøglen tilhører personen navngivet\n"
-"i bruger-id'et. Hvis du *virkelig* ved hvad du gør,\n"
-"så kan du besvare det næste spørgsmål med ja.\n"
 
+#, fuzzy
 msgid "Use this key anyway? (y/N) "
-msgstr "Brug denne nøgle alligevel? (j/N) "
+msgstr "Brug denne nøgle alligevel? "
 
 msgid "WARNING: Using untrusted key!\n"
-msgstr "ADVARSEL: Bruger nøgle uden troværdighed!\n"
+msgstr "ADVARSEL: Bruger nøgle uden tillid!\n"
 
+#, fuzzy
 msgid "WARNING: this key might be revoked (revocation key not present)\n"
-msgstr ""
-"ADVARSEL: Denne nøgle kan tilbagekaldes (tilbagekaldsnøgle er ikke til "
-"stede)\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
+#, fuzzy
 msgid "WARNING: This key has been revoked by its designated revoker!\n"
-msgstr ""
-"ADVARSEL: Denne nøgle er blevet tilbagekaldt af dens designmæssige "
-"tilbagekalder!\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
 msgid "WARNING: This key has been revoked by its owner!\n"
-msgstr "ADVARSEL: Denne nøgle er blevet tilbagekaldt af dets ejer!\n"
+msgstr "ADVARSEL: Denne nøgle er blevet annulleret af dets ejer!\n"
 
+#, fuzzy
 msgid "         This could mean that the signature is forged.\n"
-msgstr "         Dette kan betyde at underskriften er forfalsket.\n"
+msgstr "         Dette kan betyde at signaturen er forfalsket.\n"
 
 msgid "WARNING: This subkey has been revoked by its owner!\n"
-msgstr "ADVARSEL: Denne undernøgle er blevet tilbagekaldt af dens ejer!\n"
+msgstr "ADVARSEL: Denne undernøgle er blevet tilbagekaldt af dens ejer!\n"
 
+#, fuzzy
 msgid "Note: This key has been disabled.\n"
-msgstr "Bemærk: Denne nøgle er blevet deaktiveret.\n"
+msgstr "Bemærk: Denne nøgle er forældet!\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
-msgstr "Bemærk: Verificeret underskriftsejers adresse er »%s«\n"
+msgid "Note: Verified signer's address is '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr "Bemærk: Underskriftejers adresse »%s« matcher ikke DNS-post\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
+msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
 msgstr ""
-"troværdighedsniveau justeret til FULL på grund af gyldig PKA-information\n"
 
 msgid "trustlevel adjusted to NEVER due to bad PKA info\n"
 msgstr ""
-"troværdighedsniveau justeret til NEVER på grund af ugyldig PKA-information\n"
 
 msgid "Note: This key has expired!\n"
-msgstr "Bemærk: Denne nøgle er forældet!\n"
+msgstr "Bemærk: Denne nøgle er forældet!\n"
 
 msgid "WARNING: This key is not certified with a trusted signature!\n"
 msgstr ""
-"ADVARSEL: Denne nøgle er ikke certificeret med en troværdig underskrift!\n"
 
 msgid ""
 "         There is no indication that the signature belongs to the owner.\n"
-msgstr "         Intet tyder på at denne signatur tilhører ejeren.\n"
+msgstr "         Intet tyder på at denne signatur tilhører ejeren.\n"
 
 msgid "WARNING: We do NOT trust this key!\n"
-msgstr "ADVARSEL: Vi tror IKKE på denne nøgle!\n"
+msgstr "ADVARSEL: Vi tror IKKE på denne nøgle!\n"
 
 msgid "         The signature is probably a FORGERY.\n"
 msgstr "         Signaturen er formentlig FORFALSKET.\n"
@@ -4596,11 +4482,9 @@ msgstr "         Signaturen er formentlig FORFALSKET.\n"
 msgid ""
 "WARNING: This key is not certified with sufficiently trusted signatures!\n"
 msgstr ""
-"ADVARSEL: Denne nøgle er ikke certificeret med tilstrækkelig troværdige "
-"underskrifter!\n"
 
 msgid "         It is not certain that the signature belongs to the owner.\n"
-msgstr "         Det er ikke sikkert at signaturen tilhører ejeren.\n"
+msgstr "         Det er ikke sikkert at signaturen tilhører ejeren.\n"
 
 #, c-format
 msgid "%s: skipped: %s\n"
@@ -4608,150 +4492,158 @@ msgstr "%s: udelod: %s\n"
 
 #, c-format
 msgid "%s: skipped: public key already present\n"
-msgstr "%s: udelod: offentlig nøgle er allerede til stede\n"
+msgstr "%s: udelod: offentlig nøgle er allerede tilstede\n"
 
+#, fuzzy
 msgid "You did not specify a user ID. (you may use \"-r\")\n"
-msgstr "Du angav ikke et bruger-id. (du kan bruge »-r«)\n"
+msgstr ""
+"Du angav ikke en bruger-id. (du kan bruge \"-r\")\n"
+"\n"
 
 msgid "Current recipients:\n"
-msgstr "Aktuelle modtagere:\n"
+msgstr ""
 
 msgid ""
 "\n"
 "Enter the user ID.  End with an empty line: "
 msgstr ""
-"\n"
-"Indtast bruger-id'et. Slut med en tom linje: "
 
 msgid "No such user ID.\n"
-msgstr "Ingen sådan bruger-id.\n"
+msgstr "Ingen sådan bruger-id.\n"
 
 msgid "skipped: public key already set as default recipient\n"
-msgstr "udeladt: offentlig nøgle er allerede valgt som standardmodtager\n"
+msgstr "udeladt: offentlig nøgle er allerede valgt som standard modtager\n"
 
 msgid "Public key is disabled.\n"
-msgstr "Offentlig nøgle er slået fra.\n"
+msgstr "Offentlig nøgle er slået fra.\n"
 
+#, fuzzy
 msgid "skipped: public key already set\n"
-msgstr "udelod: offentlig nøgle er allerede angivet\n"
+msgstr "%s: udelod: offentlig nøgle er allerede tilstede\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "unknown default recipient \"%s\"\n"
-msgstr "ukendt standardmodtager »%s«\n"
+msgstr "ukendt standard modtager '%s'\n"
 
 #, c-format
 msgid "%s: skipped: public key is disabled\n"
-msgstr "%s: udelod: offentlig nøgle er slået fra\n"
+msgstr "%s: udelod: offentlignøgle er slået fra\n"
 
 msgid "no valid addressees\n"
 msgstr "ingen gyldige adresser\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Note: key %s has no %s feature\n"
-msgstr "Bemærk: nøgle %s har ingen %s-funktion\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Note: key %s has no preference for %s\n"
-msgstr "Bemærk: nøgle %s har ingen præference for %s\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
 msgid "data not saved; use option \"--output\" to save it\n"
-msgstr "data ej gemt; brug tilvalg »--output« for at gemme\n"
+msgstr ""
 
 msgid "Detached signature.\n"
-msgstr "Frakoblet underskrift.\n"
+msgstr ""
 
 msgid "Please enter name of data file: "
-msgstr "Indtast navn for datafil: "
+msgstr ""
 
 msgid "reading stdin ...\n"
-msgstr "læser stdin ...\n"
+msgstr "læser stdin ...\n"
 
 msgid "no signed data\n"
-msgstr "ingen underskrevne data\n"
+msgstr ""
 
 #, c-format
-msgid "can't open signed data `%s'\n"
-msgstr "kan ikke åbne underskrevne data »%s«\n"
+msgid "can't open signed data '%s'\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't open signed data fd=%d: %s\n"
-msgstr "kan ikke åbne underskrevne data fd=%d: %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
 #, c-format
 msgid "anonymous recipient; trying secret key %s ...\n"
-msgstr "anonym modtager; prøver hemmelig nøgle %s ...\n"
+msgstr ""
 
 msgid "okay, we are the anonymous recipient.\n"
-msgstr "okay, vi er den anonyme modtager.\n"
+msgstr ""
 
 msgid "old encoding of the DEK is not supported\n"
-msgstr "gammel kodning for DEK'en er ikke understøttet\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "cipher algorithm %d%s is unknown or disabled\n"
-msgstr "chifferalgoritme %d%s er ukendt eller deaktiveret\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
 #, c-format
 msgid "WARNING: cipher algorithm %s not found in recipient preferences\n"
-msgstr "ADVARSEL: chifferalgoritme %s ikke fundet i modtagerpræferencer\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "NOTE: secret key %s expired at %s\n"
-msgstr "BEMÆRK: hemmelig nøgle %s udløb den %s\n"
+msgstr "hemmelige nøgler import: %lu\n"
 
+#, fuzzy
 msgid "NOTE: key has been revoked"
-msgstr "BEMÆRK: nøgle er blevet tilbagekaldt"
+msgstr "nøgle %08lX: nøgle er blevet annulleret!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "build_packet failed: %s\n"
-msgstr "build_packet mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s has no user IDs\n"
-msgstr "nøgle %s har ingen bruger-id'er\n"
+msgstr "nøgle %08lX: ingen bruger-id\n"
 
 msgid "To be revoked by:\n"
-msgstr "Tilbagekaldes af:\n"
+msgstr ""
 
 msgid "(This is a sensitive revocation key)\n"
-msgstr "(Dette er en sensitiv tilbagekaldsnøgle)\n"
+msgstr ""
 
+#, fuzzy
 msgid "Create a designated revocation certificate for this key? (y/N) "
-msgstr "Opret et designet tilbagekaldscertifikat for denne nøgle? (j/N) "
+msgstr "Generér en annullérbar certifikat"
 
 msgid "ASCII armored output forced.\n"
-msgstr "ASCII-pansret resultat er tvunget.\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "make_keysig_packet failed: %s\n"
-msgstr "make_keysig_packet mislykkedes: %s\n"
+msgstr "signering fejlede: %s\n"
 
+#, fuzzy
 msgid "Revocation certificate created.\n"
-msgstr "Tilbagekaldscertifikat oprettet.\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
 #, c-format
 msgid "no revocation keys found for \"%s\"\n"
-msgstr "ingen tilbagekaldsnøgler fundet for »%s«\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "secret key \"%s\" not found: %s\n"
-msgstr "hemmelig nøgle »%s« blev ikke fundet: %s\n"
+msgstr "%s: bruger ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "no corresponding public key: %s\n"
-msgstr "ingen tilsvarende offentlig nøgle: %s\n"
+msgstr "skriver offentligt certifikat til '%s'\n"
 
 msgid "public key does not match secret key!\n"
-msgstr "offentlig nøgle matcher ikke hemmelig nøgle!\n"
+msgstr ""
 
+#, fuzzy
 msgid "Create a revocation certificate for this key? (y/N) "
-msgstr "Opret et tilbagekaldscertifikat for denne nøgle? (j/N) "
+msgstr "Generér en annullérbar certifikat"
 
+#, fuzzy
 msgid "unknown protection algorithm\n"
-msgstr "ukendt beskyttelsesalgoritme\n"
+msgstr "ukendt kompressionsalgoritme"
 
+#, fuzzy
 msgid "NOTE: This key is not protected!\n"
-msgstr "BEMÆRK: Denne nøgle er ikke beskyttet.\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
 msgid ""
 "Revocation certificate created.\n"
@@ -4762,1143 +4654,1121 @@ msgid ""
 "your media become unreadable.  But have some caution:  The print system of\n"
 "your machine might store the data and make it available to others!\n"
 msgstr ""
-"Tilbagekaldscertifikat oprettet.\n"
-"\n"
-"Flyt den venligst til et medie som du kan gemme væk; hvis Mallory får\n"
-"adgang til dette certifikat, kan han bruge den til at gøre din nøgle\n"
-"ubrugelig. Det er en god ide at udskrive dette certifikat og gemme det\n"
-"væk, i tilfælde af at dit medie pludselig ikke kan læses. Men vær\n"
-"forsigtig: Dit udskrivningssystem kan gemme dataene og gøre dem\n"
-"tilgængelige for andre!\n"
 
+#, fuzzy
 msgid "Please select the reason for the revocation:\n"
-msgstr "Vælg venligst årsagen for tilbagekaldet:\n"
+msgstr "rev- forkert nøgletilbagekald\n"
 
 msgid "Cancel"
-msgstr "Afbryd"
+msgstr ""
 
 #, c-format
 msgid "(Probably you want to select %d here)\n"
-msgstr "(Du vil sikkert vælge %d her)\n"
+msgstr ""
 
 msgid "Enter an optional description; end it with an empty line:\n"
-msgstr "Indtast en valgfri beskrivelse; afslut den med en tom linje:\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "Reason for revocation: %s\n"
-msgstr "Årsag for tilbagekald: %s\n"
+msgstr "rev- forkert nøgletilbagekald\n"
 
 msgid "(No description given)\n"
-msgstr "(Ingen beskrivelse angivet)\n"
+msgstr ""
 
+#, fuzzy
 msgid "Is this okay? (y/N) "
-msgstr "Er dette okay? (j/N) "
+msgstr "Brug denne nøgle alligevel? "
 
+#, fuzzy
 msgid "secret key parts are not available\n"
-msgstr "hemmelige nøgledele er ikke tilgængelige\n"
+msgstr "hemmelig nøgle ikke tilgængelig"
 
-#, c-format
+#, fuzzy, c-format
 msgid "protection algorithm %d%s is not supported\n"
-msgstr "beskyttelsesalgoritme %d%s er ikke understøttet\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "protection digest %d is not supported\n"
-msgstr "beskyttelsessammendrag %d er ikke understøttet\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
+#, fuzzy
 msgid "Invalid passphrase; please try again"
-msgstr "Ugyldig adgangsfrase; prøv igen"
+msgstr "ugyldig kodesætning"
 
 #, c-format
 msgid "%s ...\n"
-msgstr "%s ...\n"
+msgstr ""
 
 msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr "ADVARSEL: svag nøgle detekteret - vælg venligst adgangsfrase igen.\n"
+msgstr ""
 
 msgid "generating the deprecated 16-bit checksum for secret key protection\n"
 msgstr ""
-"opretter den forældede 16-bit-kontrolsum for beskyttelse af hemmelig nøgle\n"
 
 msgid "weak key created - retrying\n"
-msgstr "svag nøgle oprettet - prøver igen\n"
+msgstr ""
 
 #, c-format
 msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
-msgstr "kan ikke undgå svag nøgle for symmetrisk chiffer: prøvede %d gange!\n"
+msgstr ""
 
 msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA kræver at hashlængden skal gå op i 8 bit\n"
+msgstr ""
 
 #, c-format
 msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "DSA-nøgle %s bruger en usikker (%u bit) hash\n"
+msgstr ""
 
 #, c-format
 msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "DSA-nøgle %s kræver en %u bit eller større hash\n"
+msgstr ""
 
 msgid "WARNING: signature digest conflict in message\n"
-msgstr "ADVARSEL: konflikt for underskriftssammendrag i besked\n"
+msgstr ""
 
 #, c-format
 msgid "WARNING: signing subkey %s is not cross-certified\n"
-msgstr "ADVARSEL: underskriftsundernøgle %s er ikke krydscertificeret\n"
+msgstr ""
 
 #, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr ""
-"ADVARSEL: underskriftsundernøgle %s har en ugyldig krydscertificering\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "public key %s is %lu second newer than the signature\n"
-msgstr "offentlig nøgle %s er %lu sekund nyere end underskrift\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "public key %s is %lu seconds newer than the signature\n"
-msgstr "offentlig nøgle %s er %lu sekunder nyere end underskrift\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
 #, c-format
 msgid ""
 "key %s was created %lu second in the future (time warp or clock problem)\n"
 msgstr ""
-"nøgle %s blev oprettet %lu sekund inde i fremtiden (tidsforskydning eller et "
-"problem med uret)\n"
 
 #, c-format
 msgid ""
 "key %s was created %lu seconds in the future (time warp or clock problem)\n"
 msgstr ""
-"nøgle %s blev oprettet %lu sekunder inde i fremtiden (tidsforskydning eller "
-"et problem med uret)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "NOTE: signature key %s expired %s\n"
-msgstr "BEMÆRK: underskriftnøgle %s udløb %s\n"
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "NOTE: signature key %s has been revoked\n"
-msgstr "BEMÆRK: underskriftnøgle %s er blevet tilbagekaldt\n"
+msgstr "nøgle %08lX: nøgle er blevet annulleret!\n"
 
 #, c-format
 msgid "assuming bad signature from key %s due to an unknown critical bit\n"
 msgstr ""
-"antager ugyldig underskrift fra nøgle %s på grund af en ukendt kritisk del\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no subkey for subkey revocation signature\n"
-msgstr ""
-"nøgle %s: ingen undernøgle til tilbagekaldsunderskrift for undernøgle\n"
+msgstr "nøgle %08lX: undernøgle er blevet annulleret!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no subkey for subkey binding signature\n"
-msgstr "nøgle %s: ingen undernøgle til bindingsunderskrift for undernøgle\n"
+msgstr "nøgle %08lX: undernøgle er blevet annulleret!\n"
 
 #, c-format
 msgid "WARNING: unable to %%-expand notation (too large).  Using unexpanded.\n"
 msgstr ""
-"ADVARSEL: kan ikke %%-udvide notation (for stor). Bruger uden udvidelse.\n"
 
 #, c-format
 msgid ""
 "WARNING: unable to %%-expand policy URL (too large).  Using unexpanded.\n"
 msgstr ""
-"ADVARSEL: kan ikke %%-udvide politikadresse (for stor). Bruger uden "
-"udvidelse.\n"
 
 #, c-format
 msgid ""
 "WARNING: unable to %%-expand preferred keyserver URL (too large).  Using "
 "unexpanded.\n"
 msgstr ""
-"ADVARSEL: kan ikke %%-udvide foretrukken nøgleserveradresse (for stor). "
-"Bruger uden udvidelse.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "checking created signature failed: %s\n"
-msgstr "kontrol af oprettet underskrift mislykkedes: %s\n"
+msgstr "Kan ikke tjekke signatur: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s/%s signature from: \"%s\"\n"
-msgstr "%s/%s-underskrift fra: »%s«\n"
+msgstr "%s signatur fra: %s\n"
 
 msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
 msgstr ""
-"du kan kun vedhæfteunderskrive med nøgler i PGTP 2.x-stil når i tilstanden --"
-"pgp2\n"
 
 #, c-format
 msgid ""
 "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
 msgstr ""
-"ADVARSEL: tvang af sammendragsalgoritme %s (%d) overtræder "
-"modtagerpræferencer\n"
 
 msgid "signing:"
-msgstr "underskriver:"
+msgstr "signerer:"
 
 msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
 msgstr ""
-"du kan kun clearsign med nøgler i PGP 2.x-stil mens du er i tilstanden --"
-"pgp2\n"
 
 #, c-format
 msgid "%s encryption will be used\n"
-msgstr "%s-kryptering vil blive brugt\n"
+msgstr ""
 
 msgid "key is not flagged as insecure - can't use it with the faked RNG!\n"
 msgstr ""
-"nøgle er ikke markeret som usikker - kan ikke bruge den med falsk RNG!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "skipped \"%s\": duplicated\n"
-msgstr "udelod »%s«: duplikeret\n"
+msgstr "vis præferencer"
 
-#, c-format
+#, fuzzy, c-format
 msgid "skipped \"%s\": %s\n"
-msgstr "udelod »%s«: %s\n"
+msgstr "%s: udelod: %s\n"
 
+#, fuzzy
 msgid "skipped: secret key already present\n"
-msgstr "udelod: hemmelig nøgle er allerede til stede\n"
+msgstr "udelod: hemmelig nøgle er allerede tilstede\n"
 
 msgid "this is a PGP generated Elgamal key which is not secure for signatures!"
 msgstr ""
-"dette er en PGP-oprettet Elgamalnøgle som ikke er sikker for underskrifter!"
 
 #, c-format
 msgid "trust record %lu, type %d: write failed: %s\n"
-msgstr "stol på post %lu, type %d: skrivning mislykkedes: %s\n"
+msgstr ""
 
 #, c-format
 msgid ""
 "# List of assigned trustvalues, created %s\n"
 "# (Use \"gpg --import-ownertrust\" to restore them)\n"
 msgstr ""
-"# Liste over tildelte troværdige værdier, oprettede %s\n"
-"# (Brug »gpg --import-ownertrust« for at gendanne dem)\n"
 
-#, c-format
-msgid "error in `%s': %s\n"
-msgstr "fejl i »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error in '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "line too long"
-msgstr "linje for lang"
+msgstr ""
 
 msgid "colon missing"
-msgstr "kolon mangler"
+msgstr ""
 
+#, fuzzy
 msgid "invalid fingerprint"
-msgstr "ugyldig fingeraftryk"
+msgstr "fejl i trailerlinie\n"
 
+#, fuzzy
 msgid "ownertrust value missing"
-msgstr "værdi for ejertroværdighed mangler"
+msgstr "importér ejertillidsværdierne"
 
-#, c-format
-msgid "error finding trust record in `%s': %s\n"
-msgstr "fejl under forsøg på at finde troværdighedspost i »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error finding trust record in '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
-msgid "read error in `%s': %s\n"
-msgstr "læsefejl i »%s«: %s\n"
+#, fuzzy, c-format
+msgid "read error in '%s': %s\n"
+msgstr "panser: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
-msgstr "trustdb: synkronisering mislykkedes: %s\n"
-
-#, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "kan ikke oprette lås for »%s«\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "kan ikke låse »%s«\n"
+msgstr ""
 
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
-msgstr "trustdb rec %lu: lseek mislykkedes: %s\n"
+msgstr ""
 
 #, c-format
 msgid "trustdb rec %lu: write failed (n=%d): %s\n"
-msgstr "trustdb rec %lu: skrivning mislykkedes (n=%d): %s\n"
+msgstr ""
 
 msgid "trustdb transaction too large\n"
-msgstr "transaktion for trustdb er for stor\n"
+msgstr ""
+
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
 #, c-format
 msgid "%s: directory does not exist!\n"
-msgstr "%s: mappe findes ikke!\n"
+msgstr ""
 
-#, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kan ikke tilgå »%s«: %s\n"
+#, fuzzy, c-format
+msgid "can't create lock for '%s'\n"
+msgstr "kan ikke oprette %s: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "kan ikke åbne `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
-msgstr "%s: kunne ikke oprette versionspost: %s"
+msgstr ""
 
 #, c-format
 msgid "%s: invalid trustdb created\n"
-msgstr "%s: ugyldig trustdb oprettet\n"
+msgstr ""
 
 #, c-format
 msgid "%s: trustdb created\n"
-msgstr "%s: trustdb oprettet\n"
+msgstr ""
 
 msgid "NOTE: trustdb not writable\n"
-msgstr "BEMÆRK: trustdb ikke skrivbar\n"
+msgstr ""
 
 #, c-format
 msgid "%s: invalid trustdb\n"
-msgstr "%s: ugyldig trustdb\n"
+msgstr ""
 
 #, c-format
 msgid "%s: failed to create hashtable: %s\n"
-msgstr "%s: kunne ikke oprette hashtabel: %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: error updating version record: %s\n"
-msgstr "%s: fejl ved opdatering af versionspost: %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: error reading version record: %s\n"
-msgstr "%s: fejl ved læsning af versionspost: %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: error writing version record: %s\n"
-msgstr "%s: fejl ved skrivning af versionspost: %s\n"
+msgstr ""
 
 #, c-format
 msgid "trustdb: lseek failed: %s\n"
-msgstr "trustdb: lseek mislykkedes: %s\n"
+msgstr ""
 
 #, c-format
 msgid "trustdb: read failed (n=%d): %s\n"
-msgstr "trustdb: læsning mislykkedes (n=%d): %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: not a trustdb file\n"
-msgstr "%s: ikke en trustdb-fil\n"
+msgstr ""
 
 #, c-format
 msgid "%s: version record with recnum %lu\n"
-msgstr "%s: versionspost med recnum %lu\n"
+msgstr ""
 
 #, c-format
 msgid "%s: invalid file version %d\n"
-msgstr "%s: ugyldig filversion %d\n"
+msgstr ""
 
 #, c-format
 msgid "%s: error reading free record: %s\n"
-msgstr "%s: fejl ved læsning af fri post: %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: error writing dir record: %s\n"
-msgstr "%s: fejl ved skrivning af mappepost: %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: failed to zero a record: %s\n"
-msgstr "%s: mislykkedes med at nulle en post: %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: failed to append a record: %s\n"
-msgstr "%s: mislykkedes med at vedhæfte en post: %s\n"
+msgstr ""
 
 msgid "Error: The trustdb is corrupted.\n"
-msgstr "Fejl: trustdb er ødelagt.\n"
+msgstr ""
 
 #, c-format
 msgid "can't handle text lines longer than %d characters\n"
-msgstr "kan ikke håndtere tekstlinjer længere end %d tegn\n"
+msgstr ""
 
 #, c-format
 msgid "input line longer than %d characters\n"
-msgstr "inddatalinje er længere end %d tegn\n"
+msgstr ""
 
-#, c-format
-msgid "`%s' is not a valid long keyID\n"
-msgstr "»%s« er ikke et gyldigt nøgle-id\n"
+#, fuzzy, c-format
+msgid "'%s' is not a valid long keyID\n"
+msgstr "%s er ikke et gyldigt tegnsæt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: accepted as trusted key\n"
-msgstr "nøgle %s: accepteret som troværdig nøgle\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
 #, c-format
 msgid "key %s occurs more than once in the trustdb\n"
-msgstr "nøgle %s fremgår mere end en gang i trustdb\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s: no public key for trusted key - skipped\n"
-msgstr "nøgle %s: ingen offentlig nøgle for troværdig nøgle - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key %s marked as ultimately trusted\n"
-msgstr "nøgle %s markeret som ultimativ troværdig\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
 #, c-format
 msgid "trust record %lu, req type %d: read failed: %s\n"
-msgstr "troværdighedspost %lu, req-type %d: læsning mislykkedes: %s\n"
+msgstr ""
 
 #, c-format
 msgid "trust record %lu is not of requested type %d\n"
-msgstr "troværdighedspost %lu er ikke af den anmodne type %d\n"
+msgstr ""
 
 msgid "You may try to re-create the trustdb using the commands:\n"
-msgstr "Du kan forsøge at genskabe trustdb med kommandoerne:\n"
+msgstr ""
 
 msgid "If that does not work, please consult the manual\n"
-msgstr "Hvis det ikke virker, så se venligst manualen\n"
+msgstr ""
 
 #, c-format
 msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
 msgstr ""
-"kan ikke bruge ukendt troværdighedsmodel (%d) - antager %s "
-"troværdighedsmodel\n"
 
 #, c-format
 msgid "using %s trust model\n"
-msgstr "bruger %s troværdighedsmodel\n"
-
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
+msgstr ""
+
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
-msgstr "10 oversætter se trustdb.c:uid_trust_string_fixed"
+msgstr ""
 
+#, fuzzy
 msgid "[ revoked]"
-msgstr "[   tilb.]"
+msgstr "tilføj nøgle"
 
+#, fuzzy
 msgid "[ expired]"
-msgstr "[ udløbet]"
+msgstr "udløb"
 
+#, fuzzy
 msgid "[ unknown]"
-msgstr "[  ukendt]"
+msgstr "ukendt version"
 
 msgid "[  undef ]"
-msgstr "[  ej def]"
+msgstr ""
 
 msgid "[marginal]"
-msgstr "[marginal]"
+msgstr ""
 
 msgid "[  full  ]"
-msgstr "[  fuld  ]"
+msgstr ""
 
 msgid "[ultimate]"
-msgstr "[ ultim. ]"
+msgstr ""
 
 msgid "undefined"
-msgstr "ej defineret"
+msgstr ""
 
 msgid "never"
-msgstr "aldrig"
+msgstr ""
 
 msgid "marginal"
-msgstr "marginal"
+msgstr ""
 
 msgid "full"
-msgstr "fuld"
+msgstr ""
 
 msgid "ultimate"
-msgstr "ultimativ"
+msgstr ""
 
 msgid "no need for a trustdb check\n"
-msgstr "intet behov for kontrol af trustdb\n"
+msgstr ""
 
 #, c-format
 msgid "next trustdb check due at %s\n"
-msgstr "næste kontrol af trustdb sker den %s\n"
+msgstr ""
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
-msgstr "intet behov for kontrol af trustdb med troværdighedsmodellen »%s«\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
+msgstr ""
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr ""
-"intet behov for en opdatering af trustdb med troværdighedsmodellen »%s«\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "public key %s not found: %s\n"
-msgstr "offentlig nøgle %s blev ikke fundet: %s\n"
+msgstr "offentlig nøgle ikke fundet"
 
 msgid "please do a --check-trustdb\n"
-msgstr "udfør venligst en --check-trustdb\n"
+msgstr ""
 
+#, fuzzy
 msgid "checking the trustdb\n"
-msgstr "kontrollerer trustdb\n"
+msgstr "|[NAMES]|tjek tillidsdatabasen"
 
 #, c-format
 msgid "%d keys processed (%d validity counts cleared)\n"
-msgstr "%d nøgler behandlet (%d validiteter ryddet)\n"
+msgstr ""
 
 msgid "no ultimately trusted keys found\n"
-msgstr "ingen ultimativ troværdige nøgler fundet\n"
+msgstr ""
 
 #, c-format
 msgid "public key of ultimately trusted key %s not found\n"
-msgstr "offentlig nøgle for ultimativ troværdig nøgle %s blev ikke fundet\n"
+msgstr ""
 
 #, c-format
 msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
-msgstr "%d marginaler krævet, %d færdiggjorte krævet, %s troværdighedsmodel\n"
+msgstr ""
 
 #, c-format
 msgid ""
 "depth: %d  valid: %3d  signed: %3d  trust: %d-, %dq, %dn, %dm, %df, %du\n"
 msgstr ""
-"dybde: %d  gyldig: %3d  underskrevet: %3d  troværdighed: %d-, %dq, %dn, %dm, "
-"%df, %du\n"
 
 #, c-format
 msgid "unable to update trustdb version record: write failed: %s\n"
-msgstr "kan ikke opdatere trustdb-versionspost: skrivning mislykkedes: %s\n"
+msgstr ""
 
 msgid ""
 "the signature could not be verified.\n"
 "Please remember that the signature file (.sig or .asc)\n"
 "should be the first file given on the command line.\n"
 msgstr ""
-"underskriften kunne ikke verificeres.\n"
-"Husk at underskriftfilen (.sig eller .asc)\n"
-"skal være den første fil på kommandolinjen.\n"
 
 #, c-format
 msgid "input line %u too long or missing LF\n"
-msgstr "inddatalinje %u er for lang eller mangler LF\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't open fd %d: %s\n"
-msgstr "kan ikke åbne fd %d: %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
+#, fuzzy
 msgid "argument not expected"
-msgstr "parameter var ikke forventet"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
+#, fuzzy
 msgid "read error"
-msgstr "læsefejl"
+msgstr "fillæsningsfejl"
 
 msgid "keyword too long"
-msgstr "nøgleord er for langt"
+msgstr ""
 
+#, fuzzy
 msgid "missing argument"
-msgstr "manglende parameter"
+msgstr "ugyldigt argument"
 
 #, fuzzy
-#| msgid "invalid value\n"
-msgid "invalid argument"
-msgstr "ugyldig værdi\n"
-
 msgid "invalid command"
-msgstr "ugyldig kommando"
+msgstr "konfliktende kommandoer\n"
 
+#, fuzzy
 msgid "invalid alias definition"
-msgstr "ugyldig aliasdefinition"
+msgstr "ugyldig rustning"
 
+#, fuzzy
 msgid "out of core"
-msgstr "ikke nok kerne"
+msgstr "ikke bearbejdet"
 
+#, fuzzy
 msgid "invalid option"
-msgstr "ugyldig indstilling"
+msgstr "ugyldig rustning"
 
 #, c-format
 msgid "missing argument for option \"%.50s\"\n"
-msgstr "manglende parameter for indstilling »%.50s«\n"
-
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "manglende parameter for indstilling »%.50s«\n"
+msgstr ""
 
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "tilvalg »%.50s« forventer ikke et argument\n"
+msgstr ""
 
 #, c-format
 msgid "invalid command \"%.50s\"\n"
-msgstr "ugyldig kommando »%.50s«\n"
+msgstr ""
 
 #, c-format
 msgid "option \"%.50s\" is ambiguous\n"
-msgstr "tilvalg »%.50s« er tvetydigt\n"
+msgstr ""
 
 #, c-format
 msgid "command \"%.50s\" is ambiguous\n"
-msgstr "kommando »%.50s« er tvetydig\n"
+msgstr ""
 
+#, fuzzy
 msgid "out of core\n"
-msgstr "uden for kerne\n"
+msgstr "ikke bearbejdet"
 
-#, c-format
+#, fuzzy, c-format
 msgid "invalid option \"%.50s\"\n"
-msgstr "ugyldigt tilvalg »%.50s«\n"
+msgstr "ugyldig rustning"
 
 #, c-format
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "du fandt en fejl ... (%s:%d)\n"
 
-#, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "konvertering fra »%s« til »%s« er ikke tilgængelig\n"
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 #, c-format
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr ""
+
+#, fuzzy, c-format
 msgid "iconv_open failed: %s\n"
-msgstr "iconv_open mislykkedes: %s:\n"
+msgstr "kan ikke åbne %s: %s\n"
 
-#, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "konvertering fra »%s« til »%s« mislykkedes: %s\n"
+#, fuzzy, c-format
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
-#, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "kunne ikke oprette midlertidig fil »%s«: %s\n"
+#, fuzzy, c-format
+msgid "failed to create temporary file '%s': %s\n"
+msgstr "%s: kan ikke oprette mappe: %s\n"
 
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "fejl ved skrivning til »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error writing to '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
 #, c-format
 msgid "removing stale lockfile (created by %d)\n"
-msgstr "fjerner stale-låsfil (oprettet af %d)\n"
+msgstr ""
 
 msgid " - probably dead - removing lock"
-msgstr " - sikkert død - fjerner lås"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "venter på lås (holdt af %d%s) %s ...\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
 msgid "(deadlock?) "
-msgstr "(baglås?) "
+msgstr ""
 
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "lås »%s« er ikke udført: %s\n"
+#, fuzzy, c-format
+msgid "lock '%s' not made: %s\n"
+msgstr "offentlig nøgle ikke fundet"
 
-#, c-format
+#, fuzzy, c-format
 msgid "waiting for lock %s...\n"
-msgstr "venter på lås %s ...\n"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
 msgid "set debugging flags"
-msgstr "sæt aflusningstilvalg"
+msgstr "sæt aflusningsflag"
 
 msgid "enable full debugging"
-msgstr "aktiver fuld fejlsøgning"
+msgstr "slå fuld fejltjekning til"
 
+#, fuzzy
 msgid "Usage: kbxutil [options] [files] (-h for help)"
-msgstr "Brug: kbxutil [tilvalg] [filer] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
-"Syntaks: kbxutil [tilvalg] [filer]\n"
-"Vis, eksporter, importer Keybox-data\n"
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
-msgstr "RSA-modulus mangler eller har ikke størrelsen %d bit\n"
+msgstr ""
 
 #, c-format
 msgid "RSA public exponent missing or larger than %d bits\n"
-msgstr "RSA offentlig eksponent mangler eller større end %d bit\n"
+msgstr ""
 
 #, c-format
 msgid "PIN callback returned error: %s\n"
-msgstr "PIN-tilbagekald returnerede fejl: %s\n"
+msgstr ""
 
 msgid "the NullPIN has not yet been changed\n"
-msgstr "NullPIN'en er endnu ikke ændret\n"
+msgstr ""
 
+#, fuzzy
 msgid "|N|Please enter a new PIN for the standard keys."
-msgstr "|N|Indtast venligst en ny PIN for standardnøglerne."
+msgstr "ændr kodesætningen"
 
+#, fuzzy
 msgid "||Please enter the PIN for the standard keys."
-msgstr "||Indtast venligst PIn'en for standardnøglerne."
+msgstr "ændr kodesætningen"
 
+#, fuzzy
 msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys."
-msgstr ""
-"|NP|Indtast venligst en ny PIN Unblocking Code (PUK) for standardnøglerne."
+msgstr "rev- forkert nøgletilbagekald\n"
 
+#, fuzzy
 msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|P|Indtast venligst PIN Unblocking Code (PUK) for standardnøglerne."
+msgstr "rev- forkert nøgletilbagekald\n"
 
 msgid "|N|Please enter a new PIN for the key to create qualified signatures."
 msgstr ""
-"|N|Indtast venligst en ny PIN for nøglen til at oprette kvalificerede "
-"underskrifter."
 
 msgid "||Please enter the PIN for the key to create qualified signatures."
 msgstr ""
-"||Indtast venligst PIN'en for nøglen til at oprette kvalificerede "
-"underskrifter."
 
 msgid ""
 "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Indtast venligst en ny PIN Unblocking Code (PUK) for nøglen til at "
-"oprette kvalificerede underskrifter."
 
 msgid ""
 "|P|Please enter the PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|P|Indtast venligst PIN Unblocking Code (PUK) for nøglen til at oprette "
-"kvalificerede underskrifter."
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting new PIN: %s\n"
-msgstr "fejl ved indhentelse af ny PIN: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
+# er det klogt at oversætte TrustDB?
+#, fuzzy, c-format
 msgid "failed to store the fingerprint: %s\n"
-msgstr "kunne ikke gemme fingeraftrykket: %s\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "failed to store the creation date: %s\n"
-msgstr "kunne ikke gemme oprettelsesdatoen: %s\n"
+msgstr "ingen standard offentlig nøglering\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "reading public key failed: %s\n"
-msgstr "læsning af offentlig nøgle mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
 msgid "response does not contain the public key data\n"
-msgstr "svar indeholder ikke data for offentlig nøgle\n"
+msgstr ""
 
 msgid "response does not contain the RSA modulus\n"
-msgstr "svar indeholder ikke RSA modulus'erne\n"
+msgstr ""
 
 msgid "response does not contain the RSA public exponent\n"
-msgstr "svar indeholder ikke den RSA-offentlige eksponent\n"
+msgstr ""
 
 #, c-format
 msgid "using default PIN as %s\n"
-msgstr "bruger standard-PIN som %s\n"
+msgstr ""
 
 #, c-format
 msgid "failed to use default PIN as %s: %s - disabling further default use\n"
 msgstr ""
-"kunne ikke bruge standard-PIN som %s: %s - deaktiverer yderligere "
-"standardbrug\n"
 
 #, c-format
 msgid "||Please enter the PIN%%0A[sigs done: %lu]"
-msgstr "||Indtast venligst PIN%%0A[sigs færdig: %lu]"
+msgstr ""
 
+#, fuzzy
 msgid "||Please enter the PIN"
-msgstr "||Indtast venligst PIN'en"
+msgstr "ændr kodesætningen"
 
 #, c-format
 msgid "PIN for CHV%d is too short; minimum length is %d\n"
-msgstr "PIN for CHV%d er for kort; minimumlængde er %d\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "verify CHV%d failed: %s\n"
-msgstr "verificering af CHV%d mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
 msgid "error retrieving CHV status from card\n"
-msgstr "fejl ved indhentelse af CHV-status fra kort\n"
+msgstr ""
 
 msgid "card is permanently locked!\n"
-msgstr "kort er permanent låst!\n"
+msgstr ""
 
 #, c-format
 msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
-msgstr "%d PIN-forsøg for administrator før kort permanent låses\n"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %%0A to force a linefeed.
-#, c-format
+#, fuzzy, c-format
 msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-msgstr "|A|Ændr venligst administrator-PIN%%0A[tilbageværende forsøg: %d]"
+msgstr "ændr kodesætningen"
 
+#, fuzzy
 msgid "|A|Please enter the Admin PIN"
-msgstr "|A|Indtast venligst administrator-PIN'en"
+msgstr "ændr kodesætningen"
 
 msgid "access to admin commands is not configured\n"
-msgstr "adgang til administratorkommandoer er ikke konfigureret\n"
+msgstr ""
 
+#, fuzzy
 msgid "||Please enter the Reset Code for the card"
-msgstr "||Indtast venligst nulstillingskoden for kortet"
+msgstr "rev- forkert nøgletilbagekald\n"
 
 #, c-format
 msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "Nulstillingskode er for kort; minimumlængde er %d\n"
+msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
-msgstr "|RN|Ny nulstillingskode"
+msgstr ""
 
 msgid "|AN|New Admin PIN"
-msgstr "|AN|Ny administrator-PIN"
+msgstr ""
 
 msgid "|N|New PIN"
-msgstr "|N|Ny PIN"
-
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||Indtast venligst administrator-PIN'en og ny administrator-PIN"
-
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Indtast venligst PIN'en og ny PIN"
+msgstr ""
 
+#, fuzzy
 msgid "error reading application data\n"
-msgstr "fejl ved læsning af programdata\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
+#, fuzzy
 msgid "error reading fingerprint DO\n"
-msgstr "fejl ved læsning af fingeraftryk DO\n"
+msgstr "fejl i trailerlinie\n"
 
+#, fuzzy
 msgid "key already exists\n"
-msgstr "nøgle findes allerede\n"
+msgstr "fjern nøgle fra den hemmelige nøglering"
 
 msgid "existing key will be replaced\n"
-msgstr "eksisterende nøgle vil blive erstattet\n"
+msgstr ""
 
+#, fuzzy
 msgid "generating new key\n"
-msgstr "opretter ny nøgle\n"
+msgstr "generér et nyt nøglepar"
 
+#, fuzzy
 msgid "writing new key\n"
-msgstr "skriver ny nøgle\n"
+msgstr "generér et nyt nøglepar"
 
 msgid "creation timestamp missing\n"
-msgstr "oprettelsestidsstempel mangler\n"
+msgstr ""
 
 #, c-format
 msgid "RSA prime %s missing or not of size %d bits\n"
-msgstr "RSA-primtal %s mangler eller har ikke størrelsen %d bit\n"
+msgstr ""
 
-#, c-format
+# er det klogt at oversætte TrustDB?
+#, fuzzy, c-format
 msgid "failed to store the key: %s\n"
-msgstr "kunne ikke gemme nøglen: %s\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
 msgid "please wait while key is being generated ...\n"
-msgstr "vent venligst mens nøglen bliver oprettet ...\n"
+msgstr ""
 
+#, fuzzy
 msgid "generating key failed\n"
-msgstr "oprettelse af nøgle mislykkedes\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "key generation completed (%d seconds)\n"
-msgstr "nøgleoprettelse færdig (%d sekunder)\n"
+msgstr "Nøgleoprettelse annulleret.\n"
 
 msgid "invalid structure of OpenPGP card (DO 0x93)\n"
-msgstr "ugyldig struktur for OpenPGP-kort (DO 0x93)\n"
+msgstr ""
 
 msgid "fingerprint on card does not match requested one\n"
-msgstr "fingeraftryk på kort matcher ikke den anmodte\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "card does not support digest algorithm %s\n"
-msgstr "kort understøtter ikke sammendragsalgoritme %s\n"
+msgstr "%s signatur fra: %s\n"
 
 #, c-format
 msgid "signatures created so far: %lu\n"
-msgstr "underskrifter oprettet indtil videre: %lu\n"
+msgstr ""
 
 msgid ""
 "verification of Admin PIN is currently prohibited through this command\n"
 msgstr ""
-"verifikation af administrator-PIN er i øjeblikket forbudt via denne "
-"kommando\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "can't access %s - invalid OpenPGP card?\n"
-msgstr "kan ikke tilgå %s - ugyldig OpenPGP-kort?\n"
+msgstr "ingen gyldig OpenPGP data fundet.\n"
 
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||Indtast venligst din PIN på læserens numeriske tastatur"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
 #. to get some infos on the string.
+#, fuzzy
 msgid "|N|Initial New PIN"
-msgstr "|N|Oprindelig ny PIN"
+msgstr "Indtast bruger-id: "
 
 msgid "run in multi server mode (foreground)"
-msgstr "kør i flerservertilstand (forgrund)"
+msgstr ""
 
 msgid "|LEVEL|set the debugging level to LEVEL"
-msgstr "|LEVEL|angiv fejlsøgningsniveau til NIVEAU"
+msgstr ""
 
+#, fuzzy
 msgid "|FILE|write a log to FILE"
-msgstr "|FILE|skriv en log til FIL"
+msgstr "|FILE|indlæs udvidelsesmodul FILE"
 
 msgid "|N|connect to reader at port N"
-msgstr "|N|forbind til læser på port N"
+msgstr ""
 
+#, fuzzy
 msgid "|NAME|use NAME as ct-API driver"
-msgstr "|NAME|brug NAVN som ct-API-driver"
+msgstr "|NAME|brug NAME som standard modtager"
 
+#, fuzzy
 msgid "|NAME|use NAME as PC/SC driver"
-msgstr "|NAME|brug NAVN som PC/SC-driver"
+msgstr "|NAME|brug NAME som standard modtager"
 
+#, fuzzy
 msgid "do not use the internal CCID driver"
-msgstr "brug ikke den interne CCID-driver"
+msgstr "brug overhovedet ikke terminalen"
 
 msgid "|N|disconnect the card after N seconds of inactivity"
-msgstr "|N|frakobl kortet efter N sekunder inaktivitet"
+msgstr ""
 
-msgid "do not use a reader's pinpad"
-msgstr "brug ikke en læsers numeriske tastatur"
+msgid "do not use a reader's keypad"
+msgstr ""
 
+#, fuzzy
 msgid "deny the use of admin card commands"
-msgstr "nægt brugen af kommandoer for administratorkort"
-
-msgid "use variable length input for pinpad"
-msgstr "brug variabellængdeinddata for numerisk tastatur"
+msgstr "konfliktende kommandoer\n"
 
+#, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Brug: scdaemon [tilvalg] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
 "Smartcard daemon for GnuPG\n"
 msgstr ""
-"Syntaks: scdaemon [tilvalg] kommando [parametre]]\n"
-"Smartcard-dæmon for GnuPG\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
-"brug venligst tilvalget »--daemon« til at køre programmet i baggrunden\n"
 
 #, c-format
 msgid "handler for fd %d started\n"
-msgstr "håndtering for fd %d startet\n"
+msgstr ""
 
 #, c-format
 msgid "handler for fd %d terminated\n"
-msgstr "håndtering for fd %d termineret\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "invalid radix64 character %02x skipped\n"
-msgstr "ugyldigt radix64-tegn %02x udeladt\n"
+msgstr "ugyldigt radix64 tegn %02x udeladt\n"
 
 #, c-format
 msgid "failed to proxy %s inquiry to client\n"
-msgstr "kunne ikke proxy %s-forespørgsel til klient\n"
+msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "ingen kørende dirmngr - starter »%s«\n"
+msgid "no running dirmngr - starting '%s'\n"
+msgstr ""
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "forkert udformet DIRMNGR_INFO-miljøvariabel\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "dirmngr protocol version %d is not supported\n"
-msgstr "dirmngr-protokolversion %d er ikke understøttet\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
 msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr "kan ikke forbinde til dirmngr - forsøger reserve\n"
+msgstr ""
 
 #, c-format
 msgid "validation model requested by certificate: %s"
-msgstr "anmodt om valideringsmodel af certifikat: %s"
+msgstr ""
 
 msgid "chain"
-msgstr "kæde"
+msgstr ""
 
+#, fuzzy
 msgid "shell"
-msgstr "skal"
+msgstr "hjælp"
 
-#, c-format
+#, fuzzy, c-format
 msgid "critical certificate extension %s is not supported"
-msgstr "kritisk certifikatudvidelse %s er ikke understøttet"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
 msgid "issuer certificate is not marked as a CA"
-msgstr "udstedercertifikat er ikke markeret som en CA"
+msgstr ""
 
 msgid "critical marked policy without configured policies"
-msgstr "kritisk markeret politik uden konfigurerede politikker"
+msgstr ""
 
-#, c-format
-msgid "failed to open `%s': %s\n"
-msgstr "kan ikke åbne »%s«: %s\n"
+#, fuzzy, c-format
+msgid "failed to open '%s': %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
-msgstr "bemærk: ikkekritisk certifikatpolitik er ikke tilladt"
+msgstr ""
 
+#, fuzzy
 msgid "certificate policy not allowed"
-msgstr "certifikatpolitik er ikke tilladt"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
 msgid "looking up issuer at external location\n"
-msgstr "slår udsteder op på ekstern placering\n"
+msgstr ""
 
 #, c-format
 msgid "number of issuers matching: %d\n"
-msgstr "antallet af udstedere der matcher: %d\n"
+msgstr ""
 
 msgid "looking up issuer from the Dirmngr cache\n"
-msgstr "slår udsteder op fra Dirmngr-mellemlageret\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "number of matching certificates: %d\n"
-msgstr "antallet af matchende certifikater: %d\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "dirmngr cache-only key lookup failed: %s\n"
-msgstr "dirmngr cache-only-nøgleopslag mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
-msgid "failed to allocate keyDB handle\n"
-msgstr "kunne ikke allokere keyDB-håndtag\n"
+# er det klogt at oversætte TrustDB?
+#, fuzzy
+msgid "failed to allocated keyDB handle\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
+#, fuzzy
 msgid "certificate has been revoked"
-msgstr "certifikat er blevet tilbagekaldt"
+msgstr "nøgle %08lX: nøgle er blevet annulleret!\n"
 
 msgid "the status of the certificate is unknown"
-msgstr "status for certifikatet er ukendt"
+msgstr ""
 
 msgid "please make sure that the \"dirmngr\" is properly installed\n"
-msgstr "sikr dig at »dirmngr« er korrekt installeret\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "checking the CRL failed: %s"
-msgstr "kontrol af CRL'en mislykkedes: %s"
+msgstr "Kan ikke tjekke signatur: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "certificate with invalid validity: %s"
-msgstr "certifikat med ugyldig validitet: %s"
+msgstr "certifikatlæseproblem: %s\n"
 
 msgid "certificate not yet valid"
-msgstr "certifikat er endnu ikke gyldigt"
+msgstr ""
 
+#, fuzzy
 msgid "root certificate not yet valid"
-msgstr "rodcertifikat er endnu ikke gyldigt"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
 msgid "intermediate certificate not yet valid"
-msgstr "mellemliggende certifikat er endnu ikke gyldigt"
+msgstr ""
 
+#, fuzzy
 msgid "certificate has expired"
-msgstr "certifikat er udløbet"
+msgstr "certifikatlæseproblem: %s\n"
 
+#, fuzzy
 msgid "root certificate has expired"
-msgstr "rodcertifikat er udløbet"
+msgstr "certifikatlæseproblem: %s\n"
 
+#, fuzzy
 msgid "intermediate certificate has expired"
-msgstr "mellemliggende certifikat er udløbet"
+msgstr "certifikatlæseproblem: %s\n"
 
 #, c-format
 msgid "required certificate attributes missing: %s%s%s"
-msgstr "krævede certifikatattributter mangler: %s%s%s"
+msgstr ""
 
+#, fuzzy
 msgid "certificate with invalid validity"
-msgstr "certifikat med ugyldig validitet"
+msgstr "certifikatlæseproblem: %s\n"
 
 msgid "signature not created during lifetime of certificate"
-msgstr "underskrift blev ikke oprettet under certifikatets livsforløb"
+msgstr ""
 
 msgid "certificate not created during lifetime of issuer"
-msgstr "certifikat blev ikke oprettet under udsteders livsforløb"
+msgstr ""
 
 msgid "intermediate certificate not created during lifetime of issuer"
 msgstr ""
-"mellemliggende certifikat blev ikke oprettet under udsteders livsforløb"
 
+#, fuzzy
 msgid "  (  signature created at "
-msgstr "  (underskr. oprettet den "
+msgstr "        nye signaturer: %lu\n"
 
+#, fuzzy
 msgid "  (certificate created at "
-msgstr "  (certifkat oprettet den "
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
+#, fuzzy
 msgid "  (certificate valid from "
-msgstr "  (certifikat gyldigt fra "
+msgstr "certifikatlæseproblem: %s\n"
 
 msgid "  (     issuer valid from "
-msgstr "  (   udsteder gyldig fra "
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "fingerprint=%s\n"
-msgstr "fingeraftryk=%s\n"
+msgstr "Fingeraftryk:"
 
 msgid "root certificate has now been marked as trusted\n"
-msgstr "rodcertifikat er nu blevet markeret som troværdig\n"
+msgstr ""
 
 msgid "interactive marking as trusted not enabled in gpg-agent\n"
-msgstr "interaktiv markering som troværdig er ikke aktiveret i gpg-agent\n"
+msgstr ""
 
 msgid "interactive marking as trusted disabled for this session\n"
-msgstr "interaktiv markering som troværdig deaktiveret for denne session\n"
+msgstr ""
 
 msgid "WARNING: creation time of signature not known - assuming current time"
 msgstr ""
-"ADVARSEL: oprettelsestidspunkt for underskrift er ukendt - antager aktuelt "
-"tidspunkt"
 
+#, fuzzy
 msgid "no issuer found in certificate"
-msgstr "ingen udsteder fundet i certifikat"
+msgstr "Godt certifikat"
 
 msgid "self-signed certificate has a BAD signature"
-msgstr "egenunderskrevet certifikat har en UGYLDIG underskrift"
+msgstr ""
 
 msgid "root certificate is not marked trusted"
-msgstr "rodcertifikat er ikke markeret som troværdig"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "checking the trust list failed: %s\n"
-msgstr "kontrol af troværdighedslisten mislykkedes: %s\n"
+msgstr "Kan ikke tjekke signatur: %s\n"
 
+#, fuzzy
 msgid "certificate chain too long\n"
-msgstr "certifikatkæde er for lang\n"
+msgstr "certifikatlæseproblem: %s\n"
 
 msgid "issuer certificate not found"
-msgstr "udstedercertifikat blev ikke fundet"
+msgstr ""
 
+#, fuzzy
 msgid "certificate has a BAD signature"
-msgstr "certifikat har en UGYLDIG underskrift"
+msgstr "godkend en signatur"
 
 msgid "found another possible matching CA certificate - trying again"
-msgstr "fandt et andet mulig matchende CA-certifikat - prøver igen"
+msgstr ""
 
 #, c-format
 msgid "certificate chain longer than allowed by CA (%d)"
-msgstr "certifikatkæde er længere end tilladt af CA (%d)"
+msgstr ""
 
+#, fuzzy
 msgid "certificate is good\n"
-msgstr "certifikat er gyldigt\n"
+msgstr "certifikatlæseproblem: %s\n"
 
+#, fuzzy
 msgid "intermediate certificate is good\n"
-msgstr "mellemliggende certifikat er gyldigt\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
+#, fuzzy
 msgid "root certificate is good\n"
-msgstr "rodcertifikat er gyldigt\n"
+msgstr "Godt certifikat"
 
 msgid "switching to chain model"
-msgstr "skifter til kædemodel"
+msgstr ""
 
 #, c-format
 msgid "validation model used: %s"
-msgstr "valideringsmodel brugt: %s"
+msgstr ""
 
 #, c-format
 msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "%s-nøglen bruger en usikker (%u bit) hash\n"
+msgstr ""
 
 #, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
-msgstr "en %u-bit-hash er ikke gyldig for en %u-bit %s-nøgle\n"
+msgstr ""
 
 msgid "(this is the MD2 algorithm)\n"
-msgstr "(dette er MD2-algoritmen)\n"
+msgstr ""
 
+#, fuzzy
 msgid "none"
-msgstr "ingen"
+msgstr "n"
 
+#, fuzzy
 msgid "[Error - invalid encoding]"
-msgstr "[Fejl - ugyldig kodning]"
+msgstr "fejl i trailerlinie\n"
 
 msgid "[Error - out of core]"
-msgstr "[Fejl - ikke nok kerne]"
+msgstr ""
 
 msgid "[Error - No name]"
-msgstr "[Fejl - intet navn]"
+msgstr ""
 
+#, fuzzy
 msgid "[Error - invalid DN]"
-msgstr "[Fejl - ugyldig DN]"
+msgstr "fejl i trailerlinie\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Please enter the passphrase to unlock the secret key for the X.509 "
 "certificate:\n"
@@ -5906,414 +5776,442 @@ msgid ""
 "S/N %s, ID 0x%08lX,\n"
 "created %s, expires %s.\n"
 msgstr ""
-"Indtast venligst adgangsfrasen for at låse den hemmelige nøgle for X.509-"
-"certifikatet op:\n"
-"»%s«\n"
-"S/N %s, id 0x%08lX,\n"
-"oprettet %s, udløber %s.\n"
+"Du skal bruge en kodesætning til at beskytte din hemmelige nøgle.\n"
+"\n"
 
 msgid "no key usage specified - assuming all usages\n"
-msgstr "ingen nøglebrug angivet - antager alle mulige brug\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error getting key usage information: %s\n"
-msgstr "fejl ved indhentelse af nøglebrugsinformation: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
-msgstr "certifikat burde ikke være brugt for certificering\n"
+msgid "certificate should have not been used for certification\n"
+msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
-msgstr "certifikat burde ikke være brugt for OCSP-svarunderskrivning\n"
+msgid "certificate should have not been used for OCSP response signing\n"
+msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
-msgstr "certifikat burde ikke være brugt for kryptering\n"
+msgid "certificate should have not been used for encryption\n"
+msgstr ""
 
-msgid "certificate should not have been used for signing\n"
-msgstr "certifikat burde ikke være brugt for underskrift\n"
+msgid "certificate should have not been used for signing\n"
+msgstr ""
 
 msgid "certificate is not usable for encryption\n"
-msgstr "certifikat kan ikke bruges til kryptering\n"
+msgstr ""
 
 msgid "certificate is not usable for signing\n"
-msgstr "certifikat kan ikke bruges til underskrivning\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "line %d: invalid algorithm\n"
-msgstr "linje %d: ugyldig algoritme\n"
+msgstr "ugyldig hash-algoritme `%s'\n"
 
 #, c-format
 msgid "line %d: invalid key length %u (valid are %d to %d)\n"
-msgstr "linje %d: ugyldig nøglelængde %u (gyldige er %d til %d)\n"
+msgstr ""
 
 #, c-format
 msgid "line %d: no subject name given\n"
-msgstr "linje %d: intet emnenavn angivet\n"
+msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
-msgstr "linje %d: ugyldig etiket for emnenavn »%.*s«\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
+msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
-msgstr "linje %d: ugyldigt emnenavn »%s« på position %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "line %d: not a valid email address\n"
-msgstr "linje %d: ikke en gyldig e-post-adresse\n"
+msgstr "Ikke en gyldig epostadresse\n"
 
-#, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
-msgstr "linje %d: fejl ved læsning af nøgle »%s« fra kort: %s\n"
+#, fuzzy, c-format
+msgid "line %d: error reading key '%s' from card: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
-msgstr "linje %d: fejl ved indhentelse af nøgle med nøglegreb »%s«: %s\n"
+#, fuzzy, c-format
+msgid "line %d: error getting key by keygrip '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "line %d: key generation failed: %s <%s>\n"
-msgstr "linje %d: nøgleoprettelse mislykkedes: %s <%s>\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
 msgid ""
 "To complete this certificate request please enter the passphrase for the key "
 "you just created once more.\n"
 msgstr ""
-"For at færdiggøre denne certifikatanmodning så indtast venligst "
-"adgangsfrasen for nøglen du netop oprettede endnu en gang.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA\n"
-msgstr "   (%d) RSA\n"
+msgstr "   (%d) DSA (signér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) Existing key\n"
-msgstr "   (%d) Eksisterende nøgle\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
 #, c-format
 msgid "   (%d) Existing key from card\n"
-msgstr "   (%d) Eksisterende nøgle fra kort\n"
+msgstr ""
 
-# key grip
-# chiefly  ( US ) See also grip the person in charge of moving and setting up camera
-# tracks and scenery in a film or television studio
+#, fuzzy
 msgid "Enter the keygrip: "
-msgstr "Indtst nøglegrebet: "
+msgstr "kan ikke åbne nøgleringen"
 
 msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Ikke et gyldigt nøglegreb (forventer 40 hex cifre)\n"
+msgstr ""
 
+#, fuzzy
 msgid "No key with this keygrip\n"
-msgstr "Ingen nøgle med dette nøglegreb\n"
+msgstr "Ingen bruger-id med indeks %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading the card: %s\n"
-msgstr "fejl ved læsning af kort: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Serial number of the card: %s\n"
-msgstr "Serielnummer for kortet: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
+#, fuzzy
 msgid "Available keys:\n"
-msgstr "Tilgængelige nøgler:\n"
+msgstr "slå nøgle fra"
 
 #, c-format
 msgid "Possible actions for a %s key:\n"
-msgstr "Mulige handlinger for en %s-nøgle:\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) sign, encrypt\n"
-msgstr "   (%d) underskriv, krypter\n"
+msgstr "   (%d) ElGamal (signér og kryptér)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) sign\n"
-msgstr "   (%d) underskriv\n"
+msgstr "   (%d) DSA (signér kun)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) encrypt\n"
-msgstr "   (%d) krypter\n"
+msgstr "   (%d) ElGamal (kryptér kun)\n"
 
 msgid "Enter the X.509 subject name: "
-msgstr "Indtast X.509-emnenavnet: "
+msgstr ""
 
 msgid "No subject name given\n"
-msgstr "Intet emnenavn angivet\n"
+msgstr ""
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
-msgstr "Ugyldig etiket for emnenavn »%.*s«\n"
+msgid "Invalid subject name label '%.*s'\n"
+msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
 #. length of the first string up to the "%s".  Please
 #. adjust it do the length of your translation.  The
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
-#, c-format
-msgid "Invalid subject name `%s'\n"
-msgstr "Ugyldigt emnenavn »%s«\n"
+#, fuzzy, c-format
+msgid "Invalid subject name '%s'\n"
+msgstr "ugyldig hash-algoritme `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
-msgstr "19"
+msgstr ""
 
+#, fuzzy
 msgid "Enter email addresses"
-msgstr "Indtast e-post-adresse"
+msgstr "Epostadresse: "
 
 msgid " (end with an empty line):\n"
-msgstr " (slut med en tom linje):\n"
+msgstr ""
 
+#, fuzzy
 msgid "Enter DNS names"
-msgstr "Indtast DNS-navne"
+msgstr "Indtast nyt filnavn"
 
 msgid " (optional; end with an empty line):\n"
-msgstr " (valgfrit; slut med en tom linje):\n"
+msgstr ""
 
+#, fuzzy
 msgid "Enter URIs"
-msgstr "Indtast URI'er"
+msgstr "Indtast bruger-id: "
 
 msgid "Parameters to be used for the certificate request:\n"
-msgstr "Parametre for certifikatforespørgslen:\n"
+msgstr ""
 
 msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr "Opretter certifikatforespørgsel. Dette kan tage et stykke tid ...\n"
+msgstr ""
 
 msgid "Ready.  You should now send this request to your CA.\n"
-msgstr "Klar. Du skal nu sende denne forespørgsel til din CA.\n"
+msgstr ""
 
 msgid "resource problem: out of core\n"
-msgstr "ressourceproblem: ikke nok kerne\n"
+msgstr ""
 
 msgid "(this is the RC2 algorithm)\n"
-msgstr "(dette er RC2-algoritmen)\n"
+msgstr ""
 
 msgid "(this does not seem to be an encrypted message)\n"
-msgstr "(dette ser ikke ud til at være en krypteret besked)\n"
+msgstr ""
 
-#, c-format
-msgid "certificate `%s' not found: %s\n"
-msgstr "certifikat »%s« blev ikke fundet: %s\n"
+#, fuzzy, c-format
+msgid "certificate '%s' not found: %s\n"
+msgstr "%s: bruger ikke fundet: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error locking keybox: %s\n"
-msgstr "fejl ved låsning af nøgleboks: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
-msgid "duplicated certificate `%s' deleted\n"
-msgstr "duplikeret certifikat »%s« slettet\n"
+#, fuzzy, c-format
+msgid "duplicated certificate '%s' deleted\n"
+msgstr "nøgle %08lX: offentlig nøgle importeret\n"
 
-#, c-format
-msgid "certificate `%s' deleted\n"
-msgstr "certifikat »%s« slettet\n"
+#, fuzzy, c-format
+msgid "certificate '%s' deleted\n"
+msgstr "vis præferencer"
 
-#, c-format
+#, fuzzy, c-format
 msgid "deleting certificate \"%s\" failed: %s\n"
-msgstr "sletning af certifikat »%s« mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
+#, fuzzy
 msgid "no valid recipients given\n"
-msgstr "ingen gyldige modtagere angivet\n"
+msgstr "ingen gyldige adresser\n"
 
+#, fuzzy
 msgid "list external keys"
-msgstr "vis eksterne nøgler"
+msgstr "vis hemmelige nøgler"
 
+#, fuzzy
 msgid "list certificate chain"
-msgstr "vis certifikatkæde"
+msgstr "ugyldigt certifikat"
 
+#, fuzzy
 msgid "import certificates"
-msgstr "importer certifikater"
+msgstr "Godt certifikat"
 
+#, fuzzy
 msgid "export certificates"
-msgstr "eksporter certifikater"
+msgstr "Godt certifikat"
 
 msgid "register a smartcard"
-msgstr "registrer et smartkort"
+msgstr ""
 
 msgid "pass a command to the dirmngr"
-msgstr "send en kommando til dirmngr'en"
+msgstr ""
 
 msgid "invoke gpg-protect-tool"
-msgstr "opstart gpg-protect-tool"
-
-msgid "create base-64 encoded output"
-msgstr "opret base-64-kodet resultat"
+msgstr ""
+
+#, fuzzy
+msgid "change a passphrase"
+msgstr "ændr kodesætningen"
+
+#, fuzzy
+msgid "create base-64 encoded output"
+msgstr "opret ascii beskyttet uddata"
 
 msgid "assume input is in PEM format"
-msgstr "antag inddata er i PEM-format"
+msgstr ""
 
 msgid "assume input is in base-64 format"
-msgstr "antag inddata er i base-64-format"
+msgstr ""
 
 msgid "assume input is in binary format"
-msgstr "antag inddata er i binært format"
+msgstr ""
 
 msgid "use system's dirmngr if available"
-msgstr "brug systemets dirmngr hvis tilgængelig"
+msgstr ""
 
 msgid "never consult a CRL"
-msgstr "konsulter aldrig en CRL"
+msgstr ""
 
 msgid "check validity using OCSP"
-msgstr "kontroller validitet med OCSP"
+msgstr ""
 
 msgid "|N|number of certificates to include"
-msgstr "|N|antal certifikater der skal inkluderes"
+msgstr ""
 
 msgid "|FILE|take policy information from FILE"
-msgstr "|FILE|tag politikinformation fra FIL"
+msgstr ""
 
 msgid "do not check certificate policies"
-msgstr "kontroller ikke certifikatpolitikker"
+msgstr ""
 
 msgid "fetch missing issuer certificates"
-msgstr "hent manglende udstedercertifikater"
+msgstr ""
 
 msgid "don't use the terminal at all"
 msgstr "brug overhovedet ikke terminalen"
 
 msgid "|FILE|write a server mode log to FILE"
-msgstr "|FILE|skriv en servertilstandslog til FIL"
+msgstr ""
 
+#, fuzzy
 msgid "|FILE|write an audit log to FILE"
-msgstr "|FILE|skriv en revisionslog til FIL"
+msgstr "|FILE|indlæs udvidelsesmodul FILE"
 
 msgid "batch mode: never ask"
-msgstr "kørselstilstand: spørg aldrig"
+msgstr "kørselsmodus: spørg aldrig"
 
 msgid "assume yes on most questions"
-msgstr "forvent ja til de fleste spørgsmål"
+msgstr "forvent ja til de fleste sprøgsmål"
 
 msgid "assume no on most questions"
-msgstr "forvent nej til de fleste spørgsmål"
+msgstr "forvent nej til de fleste sprøgsmål"
 
+#, fuzzy
 msgid "|FILE|add keyring to the list of keyrings"
-msgstr "|FILE|tilføj nøglering til nøgleringslisten"
+msgstr "tilføj denne nøglering til nøgleringslisten"
 
+#, fuzzy
 msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|USER-ID|brug BRUGER-ID som hemmelig standardnøgle"
+msgstr "|NAME|brug NAME som standard hemmelignøgle"
 
+#, fuzzy
 msgid "|SPEC|use this keyserver to lookup keys"
-msgstr "|SPEC|brug denne nøgleserver til at slå nøgler op"
+msgstr "|HOST|brug denne nøgletjener til at slå nøgler op"
 
 msgid "|NAME|use cipher algorithm NAME"
-msgstr "|NAME|brug chifferalgoritme NAVN"
+msgstr "|NAME|brug cifferalgoritme NAME"
 
 msgid "|NAME|use message digest algorithm NAME"
-msgstr "|NAME|brug beskedsammendragsalgoritme NAVN"
+msgstr "|NAME|brug meddelelsesresumé algoritme NAME"
 
+#, fuzzy
 msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Brug: gpgsm [tilvalg] [filer] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
+# Skal alt dette oversættes eller er det flagene?
+#, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
-"Syntaks: gpgsm [tilvalg] [filer]\n"
-"Sign, check, encrypt eller decrypt med S/MIME-protokollen\n"
-"standardhandling afhænger af inddata\n"
+"Syntaks: gpg [flag] [filer]\n"
+"sign, check, encrypt eller decrypt\n"
+"standard operation afhænger af inddata\n"
 
+#, fuzzy
 msgid "usage: gpgsm [options] "
-msgstr "brug: gpgsm [tilvalg] "
+msgstr "brug: gpg [flag] "
 
-#, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
-msgstr "BEMÆRK: kan ikke kryptere til »%s«: %s\n"
+#, fuzzy, c-format
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
-#, c-format
-msgid "unknown validation model `%s'\n"
-msgstr "ukendt valideringsmodel »%s«\n"
+#, fuzzy, c-format
+msgid "unknown validation model '%s'\n"
+msgstr "ukendt standard modtager '%s'\n"
 
 #, c-format
 msgid "%s:%u: no hostname given\n"
-msgstr "%s:%u: intet værtsnavn angivet\n"
+msgstr ""
 
 #, c-format
 msgid "%s:%u: password given without user\n"
-msgstr "%s:%u: adgangskode angivet uden bruger\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%u: skipping this line\n"
-msgstr "%s:%u: udelader denne linje\n"
+msgstr "%s: udelod: %s\n"
 
+#, fuzzy
 msgid "could not parse keyserver\n"
-msgstr "kunne ikke fortolke nøgleserver\n"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
 msgid "WARNING: running with faked system time: "
-msgstr "ADVARSEL: kører med forfalsket systemtid: "
+msgstr ""
 
-#, c-format
-msgid "importing common certificates `%s'\n"
-msgstr "importerer gængse certifikater »%s«\n"
+#, fuzzy, c-format
+msgid "importing common certificates '%s'\n"
+msgstr "skriver til `%s'\n"
 
-#, c-format
-msgid "can't sign using `%s': %s\n"
-msgstr "kan ikke underskrive med »%s«: %s\n"
+#, fuzzy, c-format
+msgid "can't sign using '%s': %s\n"
+msgstr "kan ikke åbne '%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
-msgstr "ugyldig kommando (der er ingen implict kommando)\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "total number processed: %lu\n"
-msgstr "samlet antal behandlede: %lu\n"
+msgstr "Totalt antal behandlede: %lu\n"
 
+#, fuzzy
 msgid "error storing certificate\n"
-msgstr "fejl ved lagring af certifikat\n"
+msgstr "Godt certifikat"
 
 msgid "basic certificate checks failed - not imported\n"
-msgstr "grundlæggende certifikatkontroller mislykkedes - ikke importeret\n"
+msgstr ""
 
-#, c-format
+# er det klogt at oversætte TrustDB?
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
+
+#, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
-msgstr "fejl ved indhentelse af gemte flag: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error importing certificate: %s\n"
-msgstr "fejl under import af certifikat: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading input: %s\n"
-msgstr "fejl ved læsning af inddata: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "fejl ved oprettelse af nøgleboks »%s«: %s\n"
+#, fuzzy, c-format
+msgid "error creating keybox '%s': %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
-msgid "keybox `%s' created\n"
-msgstr "nøgleboks »%s« oprettet\n"
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
+#, fuzzy, c-format
+msgid "keybox '%s' created\n"
+msgstr "%s: mappe oprettet\n"
 
+# er det klogt at oversætte TrustDB?
+#, fuzzy
 msgid "failed to get the fingerprint\n"
-msgstr "kunne ikke indhente fingeraftrykket\n"
+msgstr "kunne ikke initialisere TillidsDB: %s\n"
 
 #, c-format
 msgid "problem looking for existing certificate: %s\n"
-msgstr "problem under udkig efter eksisterende certifikat: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error finding writable keyDB: %s\n"
-msgstr "fejl under søgning efter skrivbar keyDB (nøgledatabase): %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error storing certificate: %s\n"
-msgstr "fejl ved lagring af certifikat: %s\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
 #, c-format
 msgid "problem re-searching certificate: %s\n"
-msgstr "problem under gensøgning af certifikat: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error storing flags: %s\n"
-msgstr "fejl ved lagring af flag: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "Error - "
-msgstr "Fejl - "
+msgstr ""
 
 msgid "GPG_TTY has not been set - using maybe bogus default\n"
-msgstr "GPG_TTY er ikke blevet angivet - bruger måske fejlbehæftet standard\n"
+msgstr ""
 
-#, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "ugyldigt formateret fingeraftryk i »%s«, linje %d\n"
+#, fuzzy, c-format
+msgid "invalid formatted fingerprint in '%s', line %d\n"
+msgstr "fejl i trailerlinie\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "ugyldig landekode i »%s«, linje %d\n"
+msgid "invalid country code in '%s', line %d\n"
+msgstr ""
 
 #, c-format
 msgid ""
@@ -6324,19 +6222,11 @@ msgid ""
 "\n"
 "%s%sAre you really sure that you want to do this?"
 msgstr ""
-"Du er ved at opretet en underskrift med dit certifikat:\n"
-"»%s«\n"
-"Dette vil oprette en kvalificeret underskrift efter lovgivningen, der svarer "
-"til en håndskrevet underskrift.\n"
-"\n"
-"%s%sEr du sikker på, at det er hvad du ønsker?"
 
 msgid ""
 "Note, that this software is not officially approved to create or verify such "
 "signatures.\n"
 msgstr ""
-"Bemærk, at dette program ikke officielt er godkendt til at oprette eller "
-"verificere sådanne underskrifter.\n"
 
 #, c-format
 msgid ""
@@ -6344,426 +6234,1185 @@ msgid ""
 "\"%s\"\n"
 "Note, that this certificate will NOT create a qualified signature!"
 msgstr ""
-"Du er i gang med at oprette en underskrift med dit certifikat:\n"
-"»%s«\n"
-"Bemærk, at dette certifikat IKKE vil oprette en kvalificeret underskrift!"
 
-#, c-format
+#, fuzzy, c-format
 msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
-msgstr ""
-"hashalgoritme %d (%s) for underskriver %d er ikke understøttet; bruger %s\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
 #, c-format
 msgid "hash algorithm used for signer %d: %s (%s)\n"
-msgstr "hashalgoritme brugt for underskriver %d: %s (%s)\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "checking for qualified certificate failed: %s\n"
-msgstr "kontrollerer for kvalificeret certifikat mislykkedes: %s\n"
+msgstr "Kan ikke tjekke signatur: %s\n"
 
+#, fuzzy
 msgid "Signature made "
-msgstr "Underskrift lavet "
+msgstr "Denne nøgle er ikke beskyttet.\n"
 
 msgid "[date not given]"
-msgstr "[dato ikke angivet]"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid " using certificate ID 0x%08lX\n"
-msgstr " bruger certifikat-id 0x%08lX\n"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
 msgid ""
 "invalid signature: message digest attribute does not match computed one\n"
 msgstr ""
-"ugyldig underskrift: attribut for beskedsammendag matcher ikke den "
-"beregnede\n"
 
+#, fuzzy
 msgid "Good signature from"
-msgstr "God underskrift fra"
+msgstr "God signatur fra \""
 
+#, fuzzy
 msgid "                aka"
-msgstr "     også kendt som"
+msgstr "              alias \""
 
+#, fuzzy
 msgid "This is a qualified signature\n"
-msgstr "Dette er en kvalificeret underskrift\n"
+msgstr "skriver selvsignatur\n"
 
+#, fuzzy
 msgid "quiet"
-msgstr "stille"
+msgstr "afslut"
 
 msgid "print data out hex encoded"
-msgstr "vis data ud hex-kodet"
+msgstr ""
 
 msgid "decode received data lines"
-msgstr "afkod modtagne datalinjer"
+msgstr ""
 
 msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NAME|forbind til Assuansokkel NAVN"
+msgstr ""
 
 msgid "run the Assuan server given on the command line"
-msgstr "kør Assuanserveren angivet på kommandolinjen"
+msgstr ""
 
 msgid "do not use extended connect mode"
-msgstr "brug ikke udvidet forbindelsestilstand"
+msgstr ""
 
+#, fuzzy
 msgid "|FILE|run commands from FILE on startup"
-msgstr "|FILE|kør kommandoer fra FIL ved opstart"
+msgstr "|FILE|indlæs udvidelsesmodul FILE"
 
 msgid "run /subst on startup"
-msgstr "kør /subst ved opstart"
+msgstr ""
 
+#, fuzzy
 msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Brug: gpg-connect-agent [tilvalg] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: gpg-connect-agent [options]\n"
 "Connect to a running agent and send commands\n"
 msgstr ""
-"Syntaks: gpg-connect-agent [tilvalg]\n"
-"Forbind til en kørende agent og send kommandoer\n"
 
 #, c-format
 msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr "tilvalg »%s« kræver et program og valgfrie parametre\n"
+msgstr ""
 
 #, c-format
 msgid "option \"%s\" ignored due to \"%s\"\n"
-msgstr "tilvalg »%s« ignoreret på grund af »%s«\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "receiving line failed: %s\n"
-msgstr "modtagelse af linje mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
+#, fuzzy
 msgid "line too long - skipped\n"
-msgstr "linje er for lang - udeladt\n"
+msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
 
 msgid "line shortened due to embedded Nul character\n"
-msgstr "linje forkortet på grund af indlejret Nul-tegn\n"
+msgstr ""
 
-#, c-format
-msgid "unknown command `%s'\n"
-msgstr "ukendt kommando »%s«\n"
+#, fuzzy, c-format
+msgid "unknown command '%s'\n"
+msgstr "ukendt standard modtager '%s'\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "sending line failed: %s\n"
-msgstr "afsendelse af linje mislykkedes: %s\n"
+msgstr "signering fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error sending %s command: %s\n"
-msgstr "fejl under afsendelse af %s-kommando: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error sending standard options: %s\n"
-msgstr "fejl under afsendelse af standardtilvalg: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "Options controlling the diagnostic output"
-msgstr "Tilvalg der kontrollerer det diagnostiske resultat"
+msgstr ""
 
 msgid "Options controlling the configuration"
-msgstr "Tilvalg der kontrollerer konfigurationen"
+msgstr ""
 
+#, fuzzy
 msgid "Options useful for debugging"
-msgstr "Tilvalg nyttige for fejlsøgning"
+msgstr "slå fuld fejltjekning til"
 
 msgid "|FILE|write server mode logs to FILE"
-msgstr "|FILE|skriv servertilstandslogge til FIL"
+msgstr ""
 
 msgid "Options controlling the security"
-msgstr "Tilvalg der kontrollerer sikkerheden"
+msgstr ""
 
 msgid "|N|expire SSH keys after N seconds"
-msgstr "|N|udløb SSH-nøgler efter N sekunder"
+msgstr ""
 
 msgid "|N|set maximum PIN cache lifetime to N seconds"
-msgstr "|N|angive maksimal livsforløb for PIN-mellemlager til N sekunder"
+msgstr ""
 
 msgid "|N|set maximum SSH key lifetime to N seconds"
-msgstr "|N|angive maksimal livsforløb for SSH-nøgle til N sekunder"
+msgstr ""
 
 msgid "Options enforcing a passphrase policy"
-msgstr "Tilvalg der fremtvinger en adgangsfrasepolitik"
+msgstr ""
 
 msgid "do not allow to bypass the passphrase policy"
-msgstr "tillad ikke omgåelse af adgangsfrasepolitikken"
+msgstr ""
 
 msgid "|N|set minimal required length for new passphrases to N"
-msgstr "|N|angiv minimal krævet længde for nye adgangsfraser til N"
+msgstr ""
 
 msgid "|N|require at least N non-alpha characters for a new passphrase"
-msgstr "|N|kræv mindst N ikkealfanumeriske tegn for en ny adgangsfrase"
+msgstr ""
 
 msgid "|FILE|check new passphrases against pattern in FILE"
-msgstr "|FILE|kontroller nye adgangsfraser mod mønstre i FIL"
+msgstr ""
 
+#, fuzzy
 msgid "|N|expire the passphrase after N days"
-msgstr "|N|giv adgangsfrasen udløb efter N dage"
+msgstr "|N|brug pasfrasemodus N"
 
+#, fuzzy
 msgid "do not allow the reuse of old passphrases"
-msgstr "tillad ikke genbrug af gamle adgangsfraser"
+msgstr "fejl ved oprettelse af kodesætning: %s\n"
 
 msgid "|NAME|use NAME as default secret key"
-msgstr "|NAME|brug NAVN som hemmelig standardnøgle"
+msgstr "|NAME|brug NAME som standard hemmelignøgle"
 
+#, fuzzy
 msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|NAME|krypter også til bruger-id-NAVN"
+msgstr "|NAME|kryptér for NAME"
 
 msgid "|SPEC|set up email aliases"
-msgstr "|SPEC|opsæt e-post-aliasser"
+msgstr ""
 
 msgid "Configuration for Keyservers"
-msgstr "Konfiguration for nøgleservere"
+msgstr ""
 
+#, fuzzy
 msgid "|URL|use keyserver at URL"
-msgstr "|URL|brug nøgleserver på adressen"
+msgstr "importér nøgler fra en nøgleserver: %s\n"
 
 msgid "allow PKA lookups (DNS requests)"
-msgstr "tillad PKA-opslag (DNS-forespørgsler)"
+msgstr ""
 
 msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
-msgstr "|MECHANISMS|brug MEKANISMER til at finde nøgler efter postadresser"
+msgstr ""
 
 msgid "disable all access to the dirmngr"
-msgstr "deaktiver al adgang til dirmngr"
+msgstr ""
 
+#, fuzzy
 msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr "|NAME|brug kodnings-NAVN for PKCS#12-adgangsfraser"
+msgstr "|NAME|brug cifrealgoritme NAME for pasfrase"
 
 msgid "do not check CRLs for root certificates"
-msgstr "kontroller ikke CRL'er for rodcertifikater"
+msgstr ""
 
 msgid "Options controlling the format of the output"
-msgstr "Tilvalg der kontrollerer formatet for resultatet"
+msgstr ""
 
 msgid "Options controlling the interactivity and enforcement"
-msgstr "Tilvalg der kontrollerer interaktiviteten og tvang"
+msgstr ""
 
 msgid "Configuration for HTTP servers"
-msgstr "Konfiguration for HTTP-servere"
+msgstr ""
 
 msgid "use system's HTTP proxy setting"
-msgstr "brug systemets HTTP-proxyopsætning"
+msgstr ""
 
 msgid "Configuration of LDAP servers to use"
-msgstr "Konfiguraiton af LDAP-servere der skal bruges"
+msgstr ""
 
 msgid "LDAP server list"
-msgstr "LDAP-serverliste"
+msgstr ""
 
 msgid "Configuration for OCSP"
-msgstr "Konfiguration for OCSP"
+msgstr ""
 
 #, c-format
 msgid "External verification of component %s failed"
-msgstr "Ekstern verifikation af komponent %s mislykkedes"
+msgstr ""
 
 msgid "Note that group specifications are ignored\n"
-msgstr "Bemærk at gruppespecifikationer ignoreres\n"
+msgstr ""
 
 msgid "list all components"
-msgstr "vis alle komponenter"
+msgstr ""
 
 msgid "check all programs"
-msgstr "kontroller alle programmer"
+msgstr ""
 
 msgid "|COMPONENT|list options"
-msgstr "|COMPONENT|vis indstillinger"
+msgstr ""
 
 msgid "|COMPONENT|change options"
-msgstr "|COMPONENT|ændr indstillinger"
+msgstr ""
 
 msgid "|COMPONENT|check options"
-msgstr "|COMPONENT|kontroller indstillinger"
+msgstr ""
 
 msgid "apply global default values"
-msgstr "anvend globale standardværdier"
+msgstr ""
 
 msgid "get the configuration directories for gpgconf"
-msgstr "hent konfigurationsmapperne for gpgconf"
+msgstr ""
 
+#, fuzzy
 msgid "list global configuration file"
-msgstr "vis global konfigurationsfil"
+msgstr "ukendt standard modtager '%s'\n"
 
+#, fuzzy
 msgid "check global configuration file"
-msgstr "kontroller global konfigurationsfil"
+msgstr "ukendt standard modtager '%s'\n"
 
 msgid "use as output file"
 msgstr "brug som uddatafil"
 
 msgid "activate changes at runtime, if possible"
-msgstr "aktiver ændringer ved kørselstid, hvis muligt"
+msgstr ""
 
+#, fuzzy
 msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Brug: gpgconf [tilvalg] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: gpgconf [options]\n"
 "Manage configuration options for tools of the GnuPG system\n"
 msgstr ""
-"Syntaks: gpgconf [tilvalg]\n"
-"Håndter konfigurationsindstillinger for værktøjer i GnuPG-systemet\n"
 
+#, fuzzy
 msgid "usage: gpgconf [options] "
-msgstr "brug: gpgconf [tilvalg] "
+msgstr "brug: gpg [flag] "
 
 msgid "Need one component argument"
-msgstr "Kræver en kompomentparameter"
+msgstr ""
 
+#, fuzzy
 msgid "Component not found"
-msgstr "Komponent blev ikke fundet"
+msgstr "offentlig nøgle ikke fundet"
 
+#, fuzzy
 msgid "No argument allowed"
-msgstr "Ingen parameter tilladt"
+msgstr "skriver hemmeligt certifikat til '%s'\n"
 
+#, fuzzy
 msgid ""
 "@\n"
 "Commands:\n"
 " "
 msgstr ""
-"@\n"
-"Kommandoer:\n"
+"@Kommandoer:\n"
 " "
 
 msgid "decryption modus"
-msgstr "afkrypteringstilstand"
+msgstr ""
 
+#, fuzzy
 msgid "encryption modus"
-msgstr "krypteringstilstand"
+msgstr "kryptér data"
 
 msgid "tool class (confucius)"
-msgstr "værktøjsklasse (confucius)"
+msgstr ""
 
+#, fuzzy
 msgid "program filename"
-msgstr "filnavn for program"
+msgstr "--store [filnavn (som gemmes)]"
 
 msgid "secret key file (required)"
-msgstr "hemmelig nøglefil (krævet)"
+msgstr ""
 
 msgid "input file name (default stdin)"
-msgstr "filnavn for inddata (standard stdin)"
+msgstr ""
 
+#, fuzzy
 msgid "Usage: symcryptrun [options] (-h for help)"
-msgstr "Brug: symcryptrun [tilvalg] (-h for hjælp)"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE "
 "[options...] COMMAND [inputfile]\n"
 "Call a simple symmetric encryption tool\n"
 msgstr ""
-"Syntaks: symcryptrun --class CLASS --program PROGRAM --keyfile NØGLEFIL "
-"[tilvalg ...] KOMMANDO [inddatafil]\n"
-"Kald et simpelt symmetrisk krypteringsværktøj\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s on %s aborted with status %i\n"
-msgstr "%s på %s afbrudt med status %i\n"
+msgstr "%s ikke tilladt med %s!\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s on %s failed with status %i\n"
-msgstr "%s på %s mislykkedes med status %i\n"
+msgstr "kan ikke åbne %s: %s\n"
 
-#, c-format
-msgid "can't create temporary directory `%s': %s\n"
-msgstr "kan ikke oprette midlertidig mappe »%s«: %s\n"
+#, fuzzy, c-format
+msgid "can't create temporary directory '%s': %s\n"
+msgstr "%s: kan ikke oprette mappe: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "could not open %s for writing: %s\n"
-msgstr "kunne ikke åbne %s for skrivning: %s\n"
+msgstr "kan ikke åbne %s: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing to %s: %s\n"
-msgstr "fejl ved skrivning til »%s«: %s\n"
+msgstr "fejl ved skrivning af nøglering `%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading from %s: %s\n"
-msgstr "fejl ved læsning fra %s: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error closing %s: %s\n"
-msgstr "fejl ved lukning af %s: %s\n"
+msgstr "fejl ved læsning af '%s': %s\n"
 
 msgid "no --program option provided\n"
-msgstr "tilvalget --program blev ikke leveret\n"
+msgstr ""
 
 msgid "only --decrypt and --encrypt are supported\n"
-msgstr "kun --decrypt og --encrypt er understøttet\n"
+msgstr ""
 
 msgid "no --keyfile option provided\n"
-msgstr "tilvalget --keyfile blev ikke leveret\n"
+msgstr ""
 
 msgid "cannot allocate args vector\n"
-msgstr "kan ikke allokere parametervektor\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "could not create pipe: %s\n"
-msgstr "kunne ikke oprette datakanal: %s\n"
+msgstr "kan ikke oprette %s: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "could not create pty: %s\n"
-msgstr "kunne ikke oprette pty: %s\n"
+msgstr "kan ikke oprette %s: %s\n"
 
 #, c-format
 msgid "could not fork: %s\n"
-msgstr "kunne ikke forgrene: %s\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "execv failed: %s\n"
-msgstr "execv mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "select failed: %s\n"
-msgstr "select mislykkedes: %s\n"
+msgstr "fjernelse af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "read failed: %s\n"
-msgstr "læsning mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "pty read failed: %s\n"
-msgstr "pty-læsning mislykkedes: %s\n"
+msgstr "påklædning af beskyttelse fejlede: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "waitpid failed: %s\n"
-msgstr "waitpid mislykkedes: %s\n"
+msgstr "signering fejlede: %s\n"
 
 #, c-format
 msgid "child aborted with status %i\n"
-msgstr "underproces afbrudt med status %i\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "cannot allocate infile string: %s\n"
-msgstr "kan ikke allokere infile-streng: %s\n"
+msgstr "kan ikke oprette %s: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "cannot allocate outfile string: %s\n"
-msgstr "kan ikke allokere outfile-streng: %s\n"
+msgstr "kan ikke oprette %s: %s\n"
 
 #, c-format
 msgid "either %s or %s must be given\n"
-msgstr "enten %s eller %s skal være angivet\n"
+msgstr ""
 
 msgid "no class provided\n"
-msgstr "ingen klasse angivet\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "class %s is not supported\n"
-msgstr "klasse %s er ikke understøttet\n"
+msgstr "valgte cifferalgoritme %d er ugyldig\n"
 
+#, fuzzy
 msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n"
-msgstr "Brug: gpg-check-pattern [tilvalg] mønsterfil (-h for hjælp)\n"
+msgstr "Brug: gpg [flag] [filer] (-h for hjælp)"
 
 msgid ""
 "Syntax: gpg-check-pattern [options] patternfile\n"
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
-"Syntaks: gpg-check-pattern [tilvalg] mønsterfil\n"
-"Kontroller en adgangsfrase angivet på stdin mod mønsterfilen\n"
 
-#~ msgid "you may want to start the gpg-agent first\n"
-#~ msgstr "du kan eventuelt starte gpg-agenten først\n"
+#~ msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
+#~ msgstr "Rapportér venligst fejl til <gnupg-bugs@gnu.org>.\n"
+
+#, fuzzy
+#~ msgid "Please report bugs to "
+#~ msgstr "Rapportér venligst fejl til <gnupg-bugs@gnu.org>.\n"
+
+#, fuzzy
+#~ msgid "DSA keypair will have %u bits.\n"
+#~ msgstr "DSA nøglepar vil have 1024 bit.\n"
+
+#, fuzzy
+#~ msgid "Repeat passphrase\n"
+#~ msgstr "Gentag kodesætning: "
+
+#, fuzzy
+#~ msgid "read options from file"
+#~ msgstr "læser indstillinger fra `%s'\n"
+
+#~ msgid "|[file]|make a signature"
+#~ msgstr "|[filer]|opret en signatur"
+
+#, fuzzy
+#~ msgid "|[FILE]|make a signature"
+#~ msgstr "|[filer]|opret en signatur"
+
+#, fuzzy
+#~ msgid "|[FILE]|make a clear text signature"
+#~ msgstr "|[filer]|opret rentekst signatur"
+
+#~ msgid "|NAME|use NAME as default recipient"
+#~ msgstr "|NAME|brug NAME som standard modtager"
+
+#~ msgid "use the default key as default recipient"
+#~ msgstr "brug standard nøglen som standard modtager"
+
+#~ msgid "force v3 signatures"
+#~ msgstr "tving v3 signaturer"
+
+#~ msgid "always use a MDC for encryption"
+#~ msgstr "brug altid en MDC for kryptering"
+
+#~ msgid "add this secret keyring to the list"
+#~ msgstr "tilføj denne hemmeligenøglering til listen"
+
+#~ msgid "|NAME|set terminal charset to NAME"
+#~ msgstr "|NAME|sæt terminal karaktersæt til NAME"
+
+#~ msgid "|FILE|load extension module FILE"
+#~ msgstr "|FILE|indlæs udvidelsesmodul FILE"
+
+#~ msgid "|N|use compress algorithm N"
+#~ msgstr "|N|brug kompresalgoritme N"
+
+#, fuzzy
+#~ msgid "remove key from the public keyring"
+#~ msgstr "fjern nøgle fra den offentlige nøglering"
+
+#~ msgid "Enter the size of the key"
+#~ msgstr "Indtast nøglens størrelse"
+
+#~ msgid "Answer \"yes\" or \"no\""
+#~ msgstr "Svar \"ja\" eller \"nej\""
+
+#~ msgid "Answer \"yes\" if it is okay to overwrite the file"
+#~ msgstr "Svar \"ja\" hvis det er ok at overskrive filen"
+
+#~ msgid ""
+#~ "Please enter a new filename. If you just hit RETURN the default\n"
+#~ "file (which is shown in brackets) will be used."
+#~ msgstr ""
+#~ "Indtast et nyt filnavn. Hvis du bare trykker RETUR vil det\n"
+#~ "forvalgte navn (som er vist i klammer) blive brugt."
+
+#, fuzzy
+#~ msgid "shelll"
+#~ msgstr "hjælp"
+
+#, fuzzy
+#~ msgid ""
+#~ "please see http://www.gnupg.org/download/iconv.html for more information\n"
+#~ msgstr "rev- forkert nøgletilbagekald\n"
+
+#, fuzzy
+#~ msgid "please use the script \"%s\" to generate a new key\n"
+#~ msgstr "Vælg venligst hvilken slags nøgle du vil have:\n"
+
+#~ msgid "Enter passphrase: "
+#~ msgstr "Indtast kodesætning: "
+
+#~ msgid "Repeat passphrase: "
+#~ msgstr "Gentag kodesætning: "
+
+#~ msgid "-k[v][v][v][c] [user-id] [keyring]"
+#~ msgstr "-k[v][v][v][c] [bruger-id] [nøglering]"
+
+#, fuzzy
+#~ msgid "can't lock `%s': %s\n"
+#~ msgstr "kan ikke åbne `%s'\n"
+
+#, fuzzy
+#~ msgid "can't stat `%s': %s\n"
+#~ msgstr "kan ikke åbne '%s': %s\n"
+
+#, fuzzy
+#~ msgid "can't read `%s': %s\n"
+#~ msgstr "kan ikke åbne '%s': %s\n"
+
+#, fuzzy
+#~ msgid "can't write `%s': %s\n"
+#~ msgstr "kan ikke åbne '%s': %s\n"
+
+#, fuzzy
+#~ msgid "can't close `%s': %s\n"
+#~ msgstr "kan ikke åbne '%s': %s\n"
+
+#~ msgid "WARNING: using insecure random number generator!!\n"
+#~ msgstr "ADVARSEL: bruger usikker tilfældig-nummer-generator!!!\n"
+
+#~ msgid ""
+#~ "The random number generator is only a kludge to let\n"
+#~ "it run - it is in no way a strong RNG!\n"
+#~ "\n"
+#~ "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n"
+#~ "\n"
+#~ msgstr ""
+#~ "Den tilfældige nummer generator er kun en \"kludge\" for at\n"
+#~ "lade den køre - det er ikke en stærk RNG!\n"
+#~ "\n"
+#~ "BENYT IKKE DATA GENERERET AF DETTE PROGRAM!!!\n"
+#~ "\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "Not enough random bytes available.  Please do some other work to give\n"
+#~ "the OS a chance to collect more entropy! (Need %d more bytes)\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Ikke nok tilfældige byte tilgængelig.  Please do some other work to give\n"
+#~ "the OS a chance to collect more entropy! (Kræver %d byte mere)\n"
+
+#, fuzzy
+#~ msgid "card reader not available\n"
+#~ msgstr "hemmelig nøgle ikke tilgængelig"
+
+#, fuzzy
+#~ msgid "NOTE: %s is not available in this version\n"
+#~ msgstr "RSA nøgle kan ikke bruges i denne version\n"
+
+#, fuzzy
+#~ msgid "         algorithms on these user IDs:\n"
+#~ msgstr "      nye bruger-id'er: %lu\n"
+
+#~ msgid "general error"
+#~ msgstr "generel fejl"
+
+#~ msgid "unknown packet type"
+#~ msgstr "ukendt pakketype"
+
+#~ msgid "unknown pubkey algorithm"
+#~ msgstr "ukendt offentlig nøglealgoritme"
+
+#~ msgid "unknown digest algorithm"
+#~ msgstr "ukendt sammenfatningsalgoritme"
+
+#~ msgid "bad public key"
+#~ msgstr "dårlig offentlig nøgle"
+
+#~ msgid "bad secret key"
+#~ msgstr "dårlig hemmelig nøgle"
+
+#~ msgid "bad signature"
+#~ msgstr "dårlig signatur"
+
+#~ msgid "checksum error"
+#~ msgstr "tjeksumsfejl"
+
+#~ msgid "unknown cipher algorithm"
+#~ msgstr "ukendt cifferalgoritme "
+
+#~ msgid "invalid packet"
+#~ msgstr "ugyldig pakke"
+
+#~ msgid "invalid armor"
+#~ msgstr "ugyldig rustning"
+
+#~ msgid "no such user id"
+#~ msgstr "ikke-eksisterende bruger id"
+
+#~ msgid "secret key not available"
+#~ msgstr "hemmelig nøgle ikke tilgængelig"
+
+#~ msgid "wrong secret key used"
+#~ msgstr "forkert hemmelig nøgle brugt"
+
+#~ msgid "not supported"
+#~ msgstr "ikke understøttet"
+
+#~ msgid "bad key"
+#~ msgstr "dårlig nøgle"
+
+#~ msgid "file write error"
+#~ msgstr "filskrivningsfejl"
+
+#~ msgid "unknown compress algorithm"
+#~ msgstr "ukendt kompressionsalgoritme"
+
+#~ msgid "file open error"
+#~ msgstr "filåbningsfejl"
+
+#~ msgid "file create error"
+#~ msgstr "filoprettelsesfejl"
+
+#~ msgid "invalid passphrase"
+#~ msgstr "ugyldig kodesætning"
+
+#~ msgid "unimplemented pubkey algorithm"
+#~ msgstr "uimplementeret offentlig nøglealgoritme"
+
+#~ msgid "unimplemented cipher algorithm"
+#~ msgstr "uimplementeret cifferalgoritme"
+
+#~ msgid "unknown signature class"
+#~ msgstr "ukendt signaturklasse"
+
+#~ msgid "trust database error"
+#~ msgstr "tillidsdatabasefejl"
+
+#~ msgid "resource limit"
+#~ msgstr "resursegrænse"
+
+#~ msgid "invalid keyring"
+#~ msgstr "ugyldig nøglering"
+
+#~ msgid "malformed user id"
+#~ msgstr "dårlig bruger-id"
+
+#~ msgid "file close error"
+#~ msgstr "fillukningsfejl"
+
+#~ msgid "file rename error"
+#~ msgstr "filomdøbningsfejl"
+
+#~ msgid "file delete error"
+#~ msgstr "filsletningsfejl"
+
+#~ msgid "unexpected data"
+#~ msgstr "uforventet data"
+
+#~ msgid "timestamp conflict"
+#~ msgstr "tidsstempelkonflikt"
+
+#~ msgid "unusable pubkey algorithm"
+#~ msgstr "uanvendelig offentlig nøglealgoritme"
+
+#~ msgid "file exists"
+#~ msgstr "fil eksisterer"
+
+#~ msgid "weak key"
+#~ msgstr "svag nøgle"
+
+#~ msgid "bad URI"
+#~ msgstr "ugyldig URI"
+
+#~ msgid "unsupported URI"
+#~ msgstr "ikke-understøttet URI"
+
+#~ msgid "network error"
+#~ msgstr "netværksfejl"
+
+#~ msgid "not processed"
+#~ msgstr "ikke bearbejdet"
+
+#, fuzzy
+#~ msgid "unusable public key"
+#~ msgstr "dårlig offentlig nøgle"
+
+#, fuzzy
+#~ msgid "unusable secret key"
+#~ msgstr "dårlig hemmelig nøgle"
+
+#, fuzzy
+#~ msgid "keyserver error"
+#~ msgstr "generel fejl"
+
+#, fuzzy
+#~ msgid "no card"
+#~ msgstr "ikke krypteret"
+
+#, fuzzy
+#~ msgid "no data"
+#~ msgstr "kryptér data"
+
+#~ msgid "... this is a bug (%s:%d:%s)\n"
+#~ msgstr "... dette er en fejl (%s:%d:%s)\n"
+
+#, fuzzy
+#~ msgid "WARNING: using insecure memory!\n"
+#~ msgstr "Advarsel: benytter ubeskyttet hukommelse!\n"
+
+#~ msgid "operation is not possible without initialized secure memory\n"
+#~ msgstr "operation er ikke mulig uden beskyttet hukommelse indlæst\n"
+
+#~ msgid "(you may have used the wrong program for this task)\n"
+#~ msgstr "(du kan have brugt et forkert program til denne opgave)\n"
+
+#, fuzzy
+#~ msgid "all export-clean-* options from above"
+#~ msgstr "læs indstillinger fra fil"
+
+#, fuzzy
+#~ msgid "all import-clean-* options from above"
+#~ msgstr "læs indstillinger fra fil"
+
+#, fuzzy
+#~ msgid "expired: %s)"
+#~ msgstr "Nøgle udløber d. %s\n"
+
+#, fuzzy
+#~ msgid "key %s: expired signature from key %s - skipped\n"
+#~ msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
+
+#, fuzzy
+#~ msgid "Unable to clean `%s'\n"
+#~ msgstr "kan ikke åbne %s: %s\n"
+
+#, fuzzy
+#~ msgid "No user IDs are removable.\n"
+#~ msgstr "Ingen bruger-ID for nøgle\n"
+
+#, fuzzy
+#~ msgid "bad passphrase or unknown cipher algorithm (%d)\n"
+#~ msgstr "ukendt cifferalgoritme "
+
+#~ msgid "list signatures"
+#~ msgstr "vis signaturer"
+
+#~ msgid "sign the key"
+#~ msgstr "signér nøglen"
+
+#~ msgid "add a secondary key"
+#~ msgstr "tilføj sekundær nøgle"
+
+#~ msgid "delete signatures"
+#~ msgstr "slet signaturer"
+
+#~ msgid "change the expire date"
+#~ msgstr "ændr udløbsdatoen"
+
+#, fuzzy
+#~ msgid "set preference list"
+#~ msgstr "vis præferencer"
+
+#, fuzzy
+#~ msgid "updated preferences"
+#~ msgstr "vis præferencer"
+
+#~ msgid "No secondary key with index %d\n"
+#~ msgstr "Ingen sekundær nøgle med indeks %d\n"
+
+#, fuzzy
+#~ msgid "--nrsign-key user-id"
+#~ msgstr "--sign-key bruger-id"
+
+#, fuzzy
+#~ msgid "--nrlsign-key user-id"
+#~ msgstr "--sign-key bruger-id"
+
+#, fuzzy
+#~ msgid "sign the key non-revocably"
+#~ msgstr "signér nøglen lokalt"
+
+#, fuzzy
+#~ msgid "sign the key locally and non-revocably"
+#~ msgstr "signér nøglen lokalt"
+
+#~ msgid "q"
+#~ msgstr "a"
+
+#~ msgid "list"
+#~ msgstr "vis"
+
+#~ msgid "l"
+#~ msgstr "l"
+
+#~ msgid "debug"
+#~ msgstr "aflus"
+
+#, fuzzy
+#~ msgid "name"
+#~ msgstr "slåtil"
+
+#, fuzzy
+#~ msgid "login"
+#~ msgstr "lsignér"
+
+#, fuzzy
+#~ msgid "cafpr"
+#~ msgstr "fpr"
+
+#, fuzzy
+#~ msgid "generate"
+#~ msgstr "generel fejl"
+
+#~ msgid "passwd"
+#~ msgstr "kodeord"
+
+#~ msgid "save"
+#~ msgstr "gem"
+
+#~ msgid "fpr"
+#~ msgstr "fpr"
+
+#~ msgid "uid"
+#~ msgstr "uid"
+
+#~ msgid "key"
+#~ msgstr "nøgle"
+
+#~ msgid "check"
+#~ msgstr "tjek"
+
+#~ msgid "c"
+#~ msgstr "c"
+
+#~ msgid "sign"
+#~ msgstr "signér"
+
+#~ msgid "s"
+#~ msgstr "s"
+
+#, fuzzy
+#~ msgid "tsign"
+#~ msgstr "signér"
+
+#~ msgid "lsign"
+#~ msgstr "lsignér"
+
+#, fuzzy
+#~ msgid "nrsign"
+#~ msgstr "signér"
+
+#, fuzzy
+#~ msgid "nrlsign"
+#~ msgstr "signér"
+
+#~ msgid "adduid"
+#~ msgstr "tilføj-bid"
+
+#~ msgid "deluid"
+#~ msgstr "sletbid"
+
+#, fuzzy
+#~ msgid "addcardkey"
+#~ msgstr "tilføj nøgle"
+
+#~ msgid "delkey"
+#~ msgstr "sletnøgle"
+
+#, fuzzy
+#~ msgid "addrevoker"
+#~ msgstr "tilføj nøgle"
+
+#~ msgid "delsig"
+#~ msgstr "sletsig"
+
+#~ msgid "expire"
+#~ msgstr "udløb"
+
+#~ msgid "toggle"
+#~ msgstr "skift"
+
+#~ msgid "t"
+#~ msgstr "s"
+
+#~ msgid "pref"
+#~ msgstr "præf"
+
+#, fuzzy
+#~ msgid "showpref"
+#~ msgstr "vispræf"
+
+#, fuzzy
+#~ msgid "setpref"
+#~ msgstr "præf"
+
+#, fuzzy
+#~ msgid "updpref"
+#~ msgstr "præf"
+
+#, fuzzy
+#~ msgid "keyserver"
+#~ msgstr "generel fejl"
+
+#~ msgid "trust"
+#~ msgstr "betro"
+
+#, fuzzy
+#~ msgid "revuid"
+#~ msgstr "sletbid"
+
+#~ msgid "disable"
+#~ msgstr "slåfra"
+
+#~ msgid "enable"
+#~ msgstr "slåtil"
+
+#~ msgid "DSA only allows keysizes from 512 to 1024\n"
+#~ msgstr "DSA tillader kun nøglestørrelser fra 512 til 1024\n"
+
+#, fuzzy
+#~ msgid "Are you sure that you want this keysize? (y/N) "
+#~ msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
+
+#, fuzzy
+#~ msgid "          \""
+#~ msgstr "              alias \""
+
+#~ msgid "key %08lX: key has been revoked!\n"
+#~ msgstr "nøgle %08lX: nøgle er blevet annulleret!\n"
+
+#~ msgid "key %08lX: subkey has been revoked!\n"
+#~ msgstr "nøgle %08lX: undernøgle er blevet annulleret!\n"
+
+#~ msgid "%08lX: key has expired\n"
+#~ msgstr "%08lX: nøgle er udløbet\n"
+
+#~ msgid "%08lX: We do NOT trust this key\n"
+#~ msgstr "%08lX: Vi stoler IKKE på denne nøgle\n"
+
+#, fuzzy
+#~ msgid "   (%d) RSA (auth only)\n"
+#~ msgstr "   (%d) DSA (signér kun)\n"
+
+#, fuzzy
+#~ msgid "   (%d) RSA (sign and auth)\n"
+#~ msgstr "   (%d) ElGamal (signér og kryptér)\n"
+
+#, fuzzy
+#~ msgid "   (%d) RSA (encrypt and auth)\n"
+#~ msgstr "   (%d) ElGamal (kryptér kun)\n"
+
+#, fuzzy
+#~ msgid "  (%d) RSA (sign, encrypt and auth)\n"
+#~ msgstr "   (%d) ElGamal (signér og kryptér)\n"
+
+#~ msgid "%s: can't open: %s\n"
+#~ msgstr "%s: kan ikke åbne: %s\n"
+
+#~ msgid "%s: WARNING: empty file\n"
+#~ msgstr "%s: ADVARSEL: tom fil\n"
+
+#~ msgid "Really sign? "
+#~ msgstr "Vil du gerne signere? "
+
+#, fuzzy
+#~ msgid "expires"
+#~ msgstr "udløb"
+
+#, fuzzy
+#~ msgid "%s: can't make lock\n"
+#~ msgstr "%s: kan ikke åbne: %s\n"
+
+#, fuzzy
+#~ msgid "Unable to open photo \"%s\": %s\n"
+#~ msgstr "kan ikke åbne %s: %s\n"
+
+#, fuzzy
+#~ msgid "error: no ownertrust value\n"
+#~ msgstr "eksportér ejertillidsværdierne"
+
+#~ msgid " (main key ID %08lX)"
+#~ msgstr " (hovednøgle-ID %08lX)"
+
+#, fuzzy
+#~ msgid "rev! subkey has been revoked: %s\n"
+#~ msgstr "rev! undernøgle er blevet annulleret! %s\n"
+
+#, fuzzy
+#~ msgid "rev- faked revocation found\n"
+#~ msgstr "rev- forkert nøgletilbagekald\n"
+
+#, fuzzy
+#~ msgid " [expired: %s]"
+#~ msgstr "Nøgle udløber d. %s\n"
+
+#, fuzzy
+#~ msgid " [expires: %s]"
+#~ msgstr "Nøgle udløber d. %s\n"
+
+#, fuzzy
+#~ msgid " [revoked: %s]"
+#~ msgstr "tilføj nøgle"
+
+#~ msgid "store only"
+#~ msgstr "gem kun"
+
+#, fuzzy
+#~ msgid "sign a key locally and non-revocably"
+#~ msgstr "signér en nøgle lokalt"
+
+#~ msgid "list only the sequence of packets"
+#~ msgstr "vis kun pakkesekvensen"
+
+#~ msgid "export the ownertrust values"
+#~ msgstr "eksportér ejertillidsværdierne"
+
+#, fuzzy
+#~ msgid "unattended trust database update"
+#~ msgstr "opdatér tillidsdatabasen"
+
+#~ msgid "fix a corrupted trust database"
+#~ msgstr "reparér en ødelagt tillidsdatabase"
+
+#~ msgid "De-Armor a file or stdin"
+#~ msgstr "De-beskydt en fil el. stdin"
+
+#~ msgid "En-Armor a file or stdin"
+#~ msgstr "Beskydt en fil el. stdin"
+
+#, fuzzy
+#~ msgid "do not force v3 signatures"
+#~ msgstr "tving v3 signaturer"
+
+#, fuzzy
+#~ msgid "force v4 key signatures"
+#~ msgstr "tving v3 signaturer"
+
+#, fuzzy
+#~ msgid "do not force v4 key signatures"
+#~ msgstr "tving v3 signaturer"
+
+#, fuzzy
+#~ msgid "never use a MDC for encryption"
+#~ msgstr "brug altid en MDC for kryptering"
+
+#, fuzzy
+#~ msgid "|[file]|write status info to file"
+#~ msgstr "|FD|skriv statusinfo til denne FD"
+
+#~ msgid "emulate the mode described in RFC1991"
+#~ msgstr "emulér modusen beskrevet i RFC1991"
+
+#~ msgid "set all packet, cipher and digest options to OpenPGP behavior"
+#~ msgstr "sæt alle pakker, cifre og resumé flag til OpenPGP standard"
+
+#, fuzzy
+#~ msgid "set all packet, cipher and digest options to PGP 2.x behavior"
+#~ msgstr "sæt alle pakker, cifre og resumé flag til OpenPGP standard"
+
+#~ msgid "|NAME|use message digest algorithm NAME for passphrases"
+#~ msgstr "|NAME|brug meddelelses resuméalgoritme NAME for pasfrase"
+
+#~ msgid "key %08lX: not a rfc2440 key - skipped\n"
+#~ msgstr "nøgle %08lX: ikke en rfc2440 nøgle - udeladt\n"
+
+#, fuzzy
+#~ msgid " (default)"
+#~ msgstr "(standard er 1)"
+
+#~ msgid "Policy: "
+#~ msgstr "Politik: "
+
+#, fuzzy
+#~ msgid "can't get key from keyserver: %s\n"
+#~ msgstr "importér nøgler fra en nøgleserver: %s\n"
+
+#, fuzzy
+#~ msgid "%lu keys so far checked (%lu signatures)\n"
+#~ msgstr "%lu nøgler behandlet indtil nu\n"
+
+#, fuzzy
+#~ msgid "key %08lX incomplete\n"
+#~ msgstr "nøgle %08lX: ingen bruger-id\n"
+
+#, fuzzy
+#~ msgid "quit|quit"
+#~ msgstr "afslut"
+
+#~ msgid "   (%d) ElGamal (sign and encrypt)\n"
+#~ msgstr "   (%d) ElGamal (signér og kryptér)\n"
+
+#, fuzzy
+#~ msgid "Create anyway? "
+#~ msgstr "Brug denne nøgle alligevel? "
+
+#, fuzzy
+#~ msgid "invalid symkey algorithm detected (%d)\n"
+#~ msgstr "ugyldig hash-algoritme `%s'\n"
+
+#~ msgid "             Fingerprint:"
+#~ msgstr "             Fingeraftryk:"
+
+#~ msgid "|NAME=VALUE|use this notation data"
+#~ msgstr "|NAME=VALUE|brug denne notationsdata"
+
+#~ msgid ""
+#~ "the first character of a notation name must be a letter or an underscore\n"
+#~ msgstr ""
+#~ "første bogstav af en notationsnavn skal være et bogstave eller en "
+#~ "understregning\n"
+
+#, fuzzy
+#~ msgid "Are you sure you still want to sign it?\n"
+#~ msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
+
+#, fuzzy
+#~ msgid "  Are you sure you still want to sign it?\n"
+#~ msgstr "Er du sikker på at de vil benytte denne nøglestørrelse? "
+
+#~ msgid "--delete-secret-key user-id"
+#~ msgstr "--delete-secret-key bruger-id"
+
+#~ msgid "--delete-key user-id"
+#~ msgstr "--delete-key bruger-id"
+
+#, fuzzy
+#~ msgid "--delete-secret-and-public-key user-id"
+#~ msgstr "--delete-secret-and-public-key bruger-id"
+
+#~ msgid "skipped: public key already set with --encrypt-to\n"
+#~ msgstr "udeladt: offentlig nøgle er allerede valgt med --encrypt-to\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "\n"
+#~ "WARNING: This is a PGP2-style key\n"
+#~ msgstr "ADVARSEL: '%s' er en tom fil\n"
+
+#~ msgid "sSmMqQ"
+#~ msgstr "sSmMqQ"
+
+#, fuzzy
+#~ msgid "%lu key(s) to refresh\n"
+#~ msgstr "%lu nøgler behandlet indtil nu\n"
+
+#~ msgid ""
+#~ "No trust values changed.\n"
+#~ "\n"
+#~ msgstr "Ingen tillidsværdier er ændret.\n"
+
+#~ msgid "%08lX: no info to calculate a trust probability\n"
+#~ msgstr "%08lX: ignen info til at udregne en tillidssandsynlighed\n"
+
+#~ msgid "%s: error checking key: %s\n"
+#~ msgstr "%s: fejl ved undersøgelse af nøgle: %s\n"
+
+#~ msgid "can't lock keyring `%s': %s\n"
+#~ msgstr "kan ikke låse nøglering `%s': %s\n"
+
+#~ msgid "No key for user ID\n"
+#~ msgstr "Ingen nøgle for bruger-ID\n"
 
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "fejl ved læsning af »%s«: %s\n"
+#~ msgid "do not write comment packets"
+#~ msgstr "skriv ikke kommentarpakker"
 
-#~ msgid "Command> "
-#~ msgstr "Kommando> "
+#~ msgid "(default is 3)"
+#~ msgstr "(standard er 3)"
 
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "kunne ikke allokere keyDB-håndtag\n"
+#~ msgid "   (%d) ElGamal in a v3 packet\n"
+#~ msgstr "   (%d) ElGamal i en v3 pakke\n"
index 9d8c33d..5f00126 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -1,15 +1,15 @@
 # GnuPG German translation
 # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-#               2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+#               2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
 # Walter Koch <koch@u32.de>, 1998, 1999, 2000, 2001, 2002,
 #               2003, 2004, 2005, 2006
 # Merged with the gnupg 1.9.23 translation by Werner Koch on 2006-09-25.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg-2.0.18\n"
+"Project-Id-Version: gnupg-2.1.0\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-09-08 15:57+0200\n"
+"PO-Revision-Date: 2014-10-29 17:05+0100\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
@@ -33,29 +33,9 @@ msgstr "_OK"
 msgid "|pinentry-label|_Cancel"
 msgstr "_Abbrechen"
 
-msgid "|pinentry-label|_Yes"
-msgstr "_Ja"
-
-msgid "|pinentry-label|_No"
-msgstr "_Nein"
-
 msgid "|pinentry-label|PIN:"
 msgstr "PIN:"
 
-msgid "|pinentry-label|_Save in password manager"
-msgstr "Im Passwordmanager _speichern"
-
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr ""
-"Möchten Sie die eingegebene Passphrase wirklich auf dem Bildschirm sichtbar "
-"machen?"
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr "Die Passphrase sichtbar machen"
-
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "Passphrase unsichtbar machen"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -87,6 +67,9 @@ msgstr ""
 "Bitte geben Sie Ihre Passphrase ein, so daß der geheime Schlüssel benutzt "
 "werden kann."
 
+msgid "does not match - try again"
+msgstr "Keine Übereinstimmung - bitte nochmal versuchen."
+
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
@@ -94,6 +77,9 @@ msgstr ""
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (Versuch %d von %d)"
 
+msgid "Repeat:"
+msgstr "Nochmal:"
+
 msgid "PIN too long"
 msgstr "Die PIN ist zu lang"
 
@@ -120,11 +106,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "SSH Schlüssel von mehr als %d Bits werden nicht unterstützt\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "'%s' kann nicht erzeugt werden: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "'%s' kann nicht geöffnet werden: %s\n"
 
 #, c-format
@@ -136,8 +122,8 @@ msgid "detected card with S/N: %s\n"
 msgstr "Erkannte Karte hat die Seriennummer: %s\n"
 
 #, c-format
-msgid "error getting default authentication keyID of card: %s\n"
-msgstr "Fehler beim Holen der Authentisierungsschlüssel-ID der Karte: %s\n"
+msgid "no authentication key for ssh on card: %s\n"
+msgstr "Auf der Karte ist kein Authentisierungsschlüssel für SSH: %s\n"
 
 #, c-format
 msgid "no suitable card key found: %s\n"
@@ -156,8 +142,8 @@ msgid ""
 "An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
 "allow this?"
 msgstr ""
-"Ein ssh Prozess hat den Schlüssel%%0A  %s%%0A  (%s)%%0Aangefordert.  Möchten "
-"Sie dies erlauben?"
+"Ein SSH Processs möchte folgenden Schlüssel verwenden:%%0A  %s%%0A  "
+"(%s)%%0AErlauben Sie dies?"
 
 msgid "Allow"
 msgstr "Erlauben"
@@ -168,7 +154,8 @@ msgstr "Verweigern"
 #, c-format
 msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
 msgstr ""
-"Bitte geben Sie die Passphrase für den SSH-Schlüssel%%0A  %F%%0A  (%c) ein."
+"Bitte geben Sie die Passphrase für den SSH-Schlüssel%%0A  %F%%0A  "
+"(%c)%%0Aein."
 
 msgid "Please re-enter this passphrase"
 msgstr "Bitte geben Sie die Passphrase noch einmal ein:"
@@ -179,12 +166,9 @@ msgid ""
 "%s%%0Awithin gpg-agent's key storage"
 msgstr ""
 "Bitte geben Sie eine Passphrase ein, um den empfangenen geheimen\n"
-"Schlüssel%%0A   %s%%0A   %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu "
+"Schlüssel%%0A   %s%%0A  %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu "
 "schützen."
 
-msgid "does not match - try again"
-msgstr "Keine Übereinstimmung - bitte nochmal versuchen."
-
 #, c-format
 msgid "failed to create stream from socket: %s\n"
 msgstr "Das Erzeugen eines Datenstroms aus dem Socket schlug fehl: %s\n"
@@ -250,44 +234,6 @@ msgstr "Diese trotzdem benutzen"
 
 #, c-format
 msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u character long."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u characters long."
-msgstr[0] ""
-"WARNUNG:  Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben.  "
-"Eine Passphrase sollte%%0Amindestens %u Zeichen lang sein."
-msgstr[1] ""
-"WARNUNG:  Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben.  "
-"Eine Passphrase sollte%%0Amindestens %u Zeichen lang sein."
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digit or%%0Aspecial character."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digits or%%0Aspecial characters."
-msgstr[0] ""
-"WARNUNG:  Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben.  "
-"Eine Passphrase sollte%%0Amindestens %u Sonderzeichen oder eine Ziffer "
-"enthalten."
-msgstr[1] ""
-"WARNUNG:  Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben.  "
-"Eine Passphrase sollte%%0Amindestens %u Sonderzeichen oder Ziffern enthalten."
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
-"a known term or match%%0Acertain pattern."
-msgstr ""
-"WARNUNG:  Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben.  "
-"Eine Passphrase sollte kein%%0Abekanntes Wort sein oder nach bekannten "
-"Regeln aufgebaut sein."
-
-#, c-format
-msgid ""
 "You have not entered a passphrase!%0AAn empty passphrase is not allowed."
 msgstr ""
 "Sie haben keine Passphrase eingegeben!%0AEine leere Passphrase ist nicht "
@@ -306,6 +252,32 @@ msgid "Yes, protection is not needed"
 msgstr "Ja, ein Schutz ist nicht notwendig"
 
 #, c-format
+msgid "A passphrase should be at least %u character long."
+msgid_plural "A passphrase should be at least %u characters long."
+msgstr[0] "Eine Passphrase sollte mindestens %u Zeichen lang sein."
+msgstr[1] "Eine Passphrase sollte mindestens %u Zeichen lang sein."
+
+#, c-format
+msgid "A passphrase should contain at least %u digit or%%0Aspecial character."
+msgid_plural ""
+"A passphrase should contain at least %u digits or%%0Aspecial characters."
+msgstr[0] ""
+"Eine Passphrase sollte mindestens %u Sonderzeichen oder%%0Aeine Ziffer "
+"enthalten."
+msgstr[1] ""
+"Eine Passphrase sollte mindestens %u Sonderzeichen oder%%0AZiffern enthalten."
+
+#, c-format
+msgid "A passphrase may not be a known term or match%%0Acertain pattern."
+msgstr ""
+"Eine Passphrase sollte kein bekanntes Wort sein oder%%0Anach bekannten "
+"Regeln aufgebaut sein."
+
+msgid "Warning: You have entered an insecure passphrase."
+msgstr ""
+"WARNUNG:  Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben."
+
+#, c-format
 msgid "Please enter the passphrase to%0Aprotect your new key"
 msgstr "Bitte geben Sie die Passphrase ein,%0Aum Ihren Schlüssel zu schützen."
 
@@ -349,17 +321,14 @@ msgstr "Tastatur und Maus nicht \"grabben\""
 msgid "use a log file for the server"
 msgstr "Logausgaben in eine Datei umlenken"
 
-msgid "use a standard location for the socket"
-msgstr "Benutze einen Standardnamen für den Socket"
-
 msgid "|PGM|use PGM as the PIN-Entry program"
-msgstr "|PGM|benutze PGM as PIN-Entry"
+msgstr "|PGM|Benutze PGM as PIN-Entry"
 
 msgid "|PGM|use PGM as the SCdaemon program"
-msgstr "|PGM|benutze PGM als SCdaemon"
+msgstr "|PGM|Benutze PGM als SCdaemon"
 
 msgid "do not use the SCdaemon"
-msgstr "Den Scdaemon-basierten Kartenzugriff nicht nutzen"
+msgstr "Den SCdaemon-basierten Kartenzugriff nicht nutzen"
 
 msgid "ignore requests to change the TTY"
 msgstr "Ignoriere Anfragen, das TTY zu wechseln"
@@ -368,28 +337,22 @@ msgid "ignore requests to change the X display"
 msgstr "Ignoriere Anfragen, das X-Display zu wechseln"
 
 msgid "|N|expire cached PINs after N seconds"
-msgstr "|N|lasse PINs im Cache nach N Sekunden verfallen"
+msgstr "|N|Lasse PINs im Cache nach N Sekunden verfallen"
 
 msgid "do not use the PIN cache when signing"
-msgstr "benutze PINs im Cache nicht beim Signieren"
+msgstr "Benutze PINs im Cache nicht beim Signieren"
 
 msgid "disallow clients to mark keys as \"trusted\""
-msgstr "verbite Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren"
+msgstr "Verbiete Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren"
 
 msgid "allow presetting passphrase"
-msgstr "erlaube ein \"preset\" von Passphrases"
+msgstr "Erlaube ein \"preset\" von Passphrases"
 
 msgid "enable ssh support"
-msgstr "Die ssh-agent Komponente anschalten"
+msgstr "SSH Unterstützung einschalten"
 
 msgid "enable putty support"
-msgstr "Die Pageant Komponente anschalten"
-
-msgid "disallow the use of an external password cache"
-msgstr "Verbiete die Verwendung eines externen Passwordmanagers"
-
-msgid "|FILE|write environment settings also to FILE"
-msgstr "|DATEI|Schreibe die Umgebungsvariablen auf DATEI"
+msgstr "PuTTY Unterstützung einschalten"
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
@@ -399,18 +362,18 @@ msgstr ""
 "Berichte über Programmfehler bitte in englisch an <@EMAIL@>.\n"
 "Sinn- oder Schreibfehler in den deutschen Texten bitte an <de@li.org>.\n"
 
-msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Aufruf: gpg-agent [Optionen] (-h für Hilfe)"
+msgid "Usage: @GPG_AGENT@ [options] (-h for help)"
+msgstr "Gebrauch: @GPG_AGENT@ [Optionen] [Kommando [Argumente]]"
 
 msgid ""
-"Syntax: gpg-agent [options] [command [args]]\n"
-"Secret key management for GnuPG\n"
+"Syntax: @GPG_AGENT@ [options] [command [args]]\n"
+"Secret key management for @GNUPG@\n"
 msgstr ""
-"Syntax: gpg-agent [Optionen] [Befehl [Argumente]]\n"
-"Verwaltung von geheimen Schlüsseln für GnuPG\n"
+"Syntax: @GPG_AGENT@ [Optionen] [Befehl [Argumente]]\n"
+"Verwaltung von geheimen Schlüsseln für @GNUPG@\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr "ungültige Debugebene `%s' angegeben\n"
 
 #, c-format
@@ -418,24 +381,20 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr "Die Bibliothek %s ist nicht aktuell (benötige %s, habe %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "Note: no default option file '%s'\n"
 msgstr "Hinweis: Keine voreingestellte Optionendatei '%s' vorhanden\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "Optionendatei '%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "Optionen werden aus '%s' gelesen\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
-msgstr "Fehler beim Erstellen von `%s': %s\n"
-
-#, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "Verzeichnis `%s' kann nicht erzeugt werden: %s\n"
+msgid "Note: '%s' is not considered an option\n"
+msgstr "Hinweis: `%s' wird nicht als Option betrachtet\n"
 
 msgid "name of socket too long\n"
 msgstr "Der Name des Sockets ist zu lang\n"
@@ -445,7 +404,7 @@ msgid "can't create socket: %s\n"
 msgstr "Socket kann nicht erzeugt werden: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "Der Name des Sockets `%s' ist zu lang\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -455,7 +414,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "Fehler beim Ermitteln der \"Nonce\" dieses Sockets\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "Der Socket kann nicht an `%s' gebunden werden: %s\n"
 
 #, c-format
@@ -463,19 +422,23 @@ msgid "listen() failed: %s\n"
 msgstr "Der listen()-Aufruf ist fehlgeschlagen: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "Es wird auf Socket `%s' gehört\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "can't create directory '%s': %s\n"
+msgstr "Verzeichnis `%s' kann nicht erzeugt werden: %s\n"
+
+#, c-format
+msgid "directory '%s' created\n"
 msgstr "Verzeichnis `%s' erzeugt\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "stat()-Aufruf für `%s' fehlgeschlagen: %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "Die Datei `%s' kann nicht als Home-Verzeichnis benutzt werden\n"
 
 #, c-format
@@ -499,8 +462,8 @@ msgid "ssh handler 0x%lx for fd %d terminated\n"
 msgstr "SSH-Handhabungsroutine 0x%lx für fd %d beendet\n"
 
 #, c-format
-msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "pth_select()-Aufruf fehlgeschlagen: %s - warte 1s\n"
+msgid "npth_pselect failed: %s - waiting 1s\n"
+msgstr "npth_select()-Aufruf fehlgeschlagen: %s - warte 1s\n"
 
 #, c-format
 msgid "%s %s stopped\n"
@@ -509,13 +472,6 @@ msgstr "%s %s angehalten\n"
 msgid "no gpg-agent running in this session\n"
 msgstr "Der gpg-agent läuft nicht für diese Session\n"
 
-msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "fehlerhaft aufgebaute GPG_AGENT_INFO - Umgebungsvariable\n"
-
-#, c-format
-msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "GPG-Agent-Protokoll-Version %d wird nicht unterstützt\n"
-
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
 msgstr "Aufruf: gpg-preset-passphrase [Optionen] KEYGRIP (-h für Hilfe)\n"
 
@@ -584,34 +540,34 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "Fehler bei der Abfrage der Passphrase: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "Fehler beim Öffnen von `%s': %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "Datei `%s', Zeile %d: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 "Anweisung \"%s\" in `%s', Zeile %d\n"
 " ignoriert\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr ""
 "Systemliste der vertrauenswürdigen Zertifikate '%s' ist nicht vorhanden\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "fehlerhafter Fingerabdruck in `%s', Zeile %d\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr "Ungültiges Schlüsselflag in `%s', Zeile %d\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "Fehler beim Lesen von `%s', Zeile %d: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -685,13 +641,51 @@ msgstr "Die Passphrase ändern"
 msgid "I'll change it later"
 msgstr "Ich werde sie später ändern"
 
+msgid "Delete key"
+msgstr "Schlüssel löschen"
+
+msgid ""
+"Warning: This key is also listed for use with SSH!\n"
+"Deleting the key might remove your ability to access remote machines."
+msgstr ""
+"WARNUNG: Dieser Schlüssel wird auch für SSH benutzt!\n"
+"Das Löschen dieses Schlüssels kann Ihren Zugriff auf entfernte Rechner\n"
+"behindern."
+
+msgid "DSA requires the hash length to be a multiple of 8 bits\n"
+msgstr "Für DSA muß die Hashlänge ein Vielfaches von 8 Bit sein\n"
+
+#, c-format
+msgid "%s key uses an unsafe (%u bit) hash\n"
+msgstr "%s-Schlüssel verwendet ein unsicheres (%u-Bit) Hashverfahren\n"
+
+#, c-format
+msgid "a %zu bit hash is not valid for a %u bit %s key\n"
+msgstr ""
+"Ein %zu-Bit Hashverfahren ist für einen %u-Bit %s Schlüssel nicht möglich\n"
+
+msgid "secret key parts are not available\n"
+msgstr "Teile des geheimen Schlüssels sind nicht vorhanden\n"
+
+#, c-format
+msgid "public key algorithm %d (%s) is not supported\n"
+msgstr "Public-Key-Verfahren %d (%s) wird nicht unterstützt\n"
+
+#, c-format
+msgid "protection algorithm %d (%s) is not supported\n"
+msgstr "Schutzverfahren %d (%s) wird nicht unterstützt\n"
+
+#, c-format
+msgid "protection hash algorithm %d (%s) is not supported\n"
+msgstr "Schutzverfahrenshash %d (%s) wird nicht unterstützt\n"
+
 #, c-format
 msgid "error creating a pipe: %s\n"
 msgstr "Fehler beim Erzeugen einer \"Pipe\": %s\n"
 
 #, c-format
-msgid "can't fdopen pipe for reading: %s\n"
-msgstr "Pipe kann nicht zum Lesen \"fdopen\"t werden: %s\n"
+msgid "error creating a stream for a pipe: %s\n"
+msgstr "Fehler beim Erzeugen eines \"streams\" zu einer \"pipe\": %s\n"
 
 #, c-format
 msgid "error forking process: %s\n"
@@ -702,33 +696,26 @@ msgid "waiting for process %d to terminate failed: %s\n"
 msgstr "Das Warten auf die Beendigung des Prozesses %d schlug fehl: %s\n"
 
 #, c-format
-msgid "error getting exit code of process %d: %s\n"
-msgstr "Fehler beim Holen des Exitwerte des Prozesses %d: %s\n"
+msgid "error running '%s': probably not installed\n"
+msgstr "Fehler bei Ausführung von `%s': wahrscheinlich nicht installiert\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "Fehler bei Ausführung von `%s': Endestatus %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "Fehler bei Ausführung von `%s': wahrscheinlich nicht installiert\n"
-
-#, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "Fehler bei Ausführung von `%s': beendet\n"
 
 #, c-format
-msgid "error creating socket: %s\n"
-msgstr "Fehler beim Erstellen des Sockets: %s\n"
-
-msgid "host not found"
-msgstr "Host nicht gefunden"
+msgid "error getting exit code of process %d: %s\n"
+msgstr "Fehler beim Holen des Exitwerte des Prozesses %d: %s\n"
 
 msgid "gpg-agent is not available in this session\n"
 msgstr "GPG-Agent ist in dieser Sitzung nicht vorhanden\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "Verbindung zu '%s' kann nicht aufgebaut werden: %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -799,15 +786,27 @@ msgstr ""
 msgid "out of core while allocating %lu bytes"
 msgstr "Kein Speicher mehr vorhanden, als %lu Byte zugewiesen werden sollten"
 
-msgid "no running gpg-agent - starting one\n"
-msgstr "Kein aktiver gpg-agent - es wird einer gestartet\n"
+#, c-format
+msgid "no running gpg-agent - starting '%s'\n"
+msgstr "Kein aktiver gpg-agent - `%s' wird gestartet\n"
+
+#, c-format
+msgid "waiting for the agent to come up ... (%ds)\n"
+msgstr "Warte bis der gpg-agent bereit ist ... (%ds)\n"
+
+msgid "connection to agent established\n"
+msgstr "Verbindung zum gpg-agent aufgebaut\n"
+
+#, c-format
+msgid "no running Dirmngr - starting '%s'\n"
+msgstr "Kein aktiver Dirmngr - `%s' wird gestartet\n"
 
 #, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "Warte %d Sekunden bis der gpg-agent bereit ist\n"
+msgid "waiting for the dirmngr to come up ... (%ds)\n"
+msgstr "Warte bis der Dirmngr bereit ist ... (%ds)\n"
 
-msgid "can't connect to the agent - trying fall back\n"
-msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n"
+msgid "connection to the dirmngr established\n"
+msgstr "Verbindung zum Dirmngr aufgebaut\n"
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
@@ -893,7 +892,7 @@ msgid "Data decryption succeeded"
 msgstr "Entschlüsselung der Daten erfolgreich"
 
 msgid "Encryption algorithm supported"
-msgstr "Verschlüsselungsverfahren wird unterstützt"
+msgstr "Verschlüsselungsverfahren %d%s wird nicht unterstützt"
 
 msgid "Data verification succeeded"
 msgstr "Prüfung der Signatur erfolgreich"
@@ -943,7 +942,7 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr benutzbar"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Keine Hilfe für '%s' vorhanden."
 
 msgid "ignoring garbage line"
@@ -952,6 +951,107 @@ msgstr "Zeile mit nicht identifizierten Zeichen wird ignoriert"
 msgid "[none]"
 msgstr "[keine]"
 
+msgid "argument not expected"
+msgstr "Argument nicht erwartet"
+
+msgid "read error"
+msgstr "Lesefehler"
+
+msgid "keyword too long"
+msgstr "Schlüsselwort ist zu lang"
+
+msgid "missing argument"
+msgstr "Fehlendes Argument"
+
+msgid "invalid argument"
+msgstr "Ungültiges Argument"
+
+msgid "invalid command"
+msgstr "Ungültiger Befehl"
+
+msgid "invalid alias definition"
+msgstr "Ungültige Alias-Definition"
+
+msgid "out of core"
+msgstr "Nicht genügend Speicher"
+
+msgid "invalid option"
+msgstr "Ungültige Option"
+
+#, c-format
+msgid "missing argument for option \"%.50s\"\n"
+msgstr "Fehlendes Argument für Option \"%.50s\"\n"
+
+#, c-format
+msgid "invalid argument for option \"%.50s\"\n"
+msgstr "Ungültiges Argument für Option \"%.50s\"\n"
+
+#, c-format
+msgid "option \"%.50s\" does not expect an argument\n"
+msgstr "Option \"%.50s\" erwartet kein Argument\n"
+
+#, c-format
+msgid "invalid command \"%.50s\"\n"
+msgstr "Ungültiger Befehl \"%.50s\"\n"
+
+#, c-format
+msgid "option \"%.50s\" is ambiguous\n"
+msgstr "Option \"%.50s\" ist mehrdeutig\n"
+
+#, c-format
+msgid "command \"%.50s\" is ambiguous\n"
+msgstr "Befehl \"%.50s\" ist mehrdeutig\n"
+
+msgid "out of core\n"
+msgstr "Nicht genügend Speicher\n"
+
+#, c-format
+msgid "invalid option \"%.50s\"\n"
+msgstr "Ungültige Option \"%.50s\"\n"
+
+#, c-format
+msgid "you found a bug ... (%s:%d)\n"
+msgstr "Sie haben einen Bug (Programmfehler) gefunden ... (%s:%d)\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr "Umwandlung von `%s' in `%s' ist nicht verfügbar\n"
+
+#, c-format
+msgid "iconv_open failed: %s\n"
+msgstr "iconv_open fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "Umwandlung von `%s' in `%s' schlug fehl: %s\n"
+
+#, c-format
+msgid "failed to create temporary file '%s': %s\n"
+msgstr "Die temporäre Datei `%s' kann nicht erstellt werden: %s\n"
+
+#, c-format
+msgid "error writing to '%s': %s\n"
+msgstr "Fehler beim Schreiben von %s: %s\n"
+
+#, c-format
+msgid "removing stale lockfile (created by %d)\n"
+msgstr "eine übriggebliebene Sperrdatei wird entfernt (erzeugt von %d)\n"
+
+#, c-format
+msgid "waiting for lock (held by %d%s) %s...\n"
+msgstr "warte auf die Freigabe der Sperre (gehalten von %d%s) %s...\n"
+
+msgid "(deadlock?) "
+msgstr "(Deadlock?) "
+
+#, c-format
+msgid "lock '%s' not made: %s\n"
+msgstr "Dateisperre %s konnte nicht eingerichtet werden: %s\n"
+
+#, c-format
+msgid "waiting for lock %s...\n"
+msgstr "Warten auf die Freigabe der Dateisperre `%s' ...\n"
+
 #, c-format
 msgid "armor: %s\n"
 msgstr "ASCII-Hülle: %s\n"
@@ -1036,6 +1136,13 @@ msgid "not human readable"
 msgstr "nicht als Klartext darstellbar"
 
 #, c-format
+msgid "failed to proxy %s inquiry to client\n"
+msgstr "Die %s \"inquiry\" konnte nicht an den Client weitergeleitet werden\n"
+
+msgid "Enter passphrase: "
+msgstr "Geben Sie die Passphrase ein: "
+
+#, c-format
 msgid "OpenPGP card not available: %s\n"
 msgstr "OpenPGP Karte ist nicht vorhanden: %s\n"
 
@@ -1105,11 +1212,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "Fehler beim Zuteilen genügenden Speichers: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "Fehler beim Lesen von `%s': %s\n"
 
 #, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "Fehler beim Schreiben von %s: %s\n"
 
 msgid "Login data (account name): "
@@ -1162,7 +1269,7 @@ msgid "Replace existing key? (y/N) "
 msgstr "Vorhandenen Schlüssel ersetzen? (j/N) "
 
 msgid ""
-"NOTE: There is no guarantee that the card supports the requested size.\n"
+"Note: There is no guarantee that the card supports the requested size.\n"
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
@@ -1197,7 +1304,8 @@ msgstr "%s-Schlüssellängen müssen im Bereich %u-%u sein\n"
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
 msgstr ""
-"Die Karte wird nun rekonfiguriert um einen Schlüssel von %u Bit zu erzeugen\n"
+"Die Karte wird nun rekonfiguriert, um einen Schlüssel von %u Bit zu "
+"erzeugen\n"
 
 #, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
@@ -1207,8 +1315,8 @@ msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr ""
 "Sicherung des Verschlüsselungsschlüssel außerhalb der Karte erstellen? (J/n) "
 
-msgid "NOTE: keys are already stored on the card!\n"
-msgstr "ACHTUNG: Auf der Karte sind bereits Schlüssel gespeichert!\n"
+msgid "Note: keys are already stored on the card!\n"
+msgstr "Hinweis: Auf der Karte sind bereits Schlüssel gespeichert!\n"
 
 msgid "Replace existing keys? (y/N) "
 msgstr "Vorhandene Schlüssel ersetzen? (j/N) "
@@ -1216,11 +1324,11 @@ msgstr "Vorhandene Schlüssel ersetzen? (j/N) "
 #, c-format
 msgid ""
 "Please note that the factory settings of the PINs are\n"
-"   PIN = `%s'     Admin PIN = `%s'\n"
+"   PIN = '%s'     Admin PIN = '%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
 "Bitte beachten: Die Werkseinstellung der PINs sind\n"
-"   PIN = `%s'     Admin-PIN = `%s'\n"
+"   PIN = '%s'     Admin-PIN = '%s'\n"
 "Sie sollten sie mittels des Befehls --change-pin ändern\n"
 
 msgid "Please select the type of key to generate:\n"
@@ -1241,18 +1349,9 @@ msgstr "Ungültige Auswahl.\n"
 msgid "Please select where to store the key:\n"
 msgstr "Wählen Sie den Speicherort für den Schlüssel:\n"
 
-msgid "unknown key protection algorithm\n"
-msgstr "Unbekanntes Schlüssel-Schutzverfahren\n"
-
-msgid "secret parts of key are not available\n"
-msgstr "Geheime Teile des Schlüssels sind nicht vorhanden\n"
-
-msgid "secret key already stored on a card\n"
-msgstr "Geheimer Schlüssel ist bereits auf einer Karte gespeichert\n"
-
 #, c-format
-msgid "error writing key to card: %s\n"
-msgstr "Fehler beim Schreiben des Schlüssels auf die Karte: %s\n"
+msgid "KEYTOCARD failed: %s\n"
+msgstr "Das KEYTOCARD Kommando schlug fehl: %s\n"
 
 msgid "quit this menu"
 msgstr "Menü verlassen"
@@ -1321,7 +1420,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output funktioniert nicht bei diesem Befehl\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "'%s' kann nicht geöffnet werden\n"
 
 #, c-format
@@ -1345,6 +1444,16 @@ msgid "This is a secret key! - really delete? (y/N) "
 msgstr "Dies ist ein privater Schlüssel! - Wirklich löschen? (j/N) "
 
 #, c-format
+msgid "deleting secret %s failed: %s\n"
+msgstr "Fehler beim Löschen des privaten %ss: %s\n"
+
+msgid "key"
+msgstr "Schlüssel"
+
+msgid "subkey"
+msgstr "Unterschlüssel"
+
+#, c-format
 msgid "deleting keyblock failed: %s\n"
 msgstr "löschen des Schlüsselblocks fehlgeschlagen: %s\n"
 
@@ -1375,28 +1484,17 @@ msgid "using cipher %s\n"
 msgstr "benutze Cipher %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' ist bereits komprimiert\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "WARNUNG: '%s' ist eine leere Datei.\n"
 
-msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
-msgstr ""
-"Im --pgp2-Modus kann nur für RSA-Schlüssel mit maximal 2048 Bit "
-"verschlüsselt werden\n"
-
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "Lesen von '%s'\n"
 
-msgid ""
-"unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
-msgstr ""
-"Die IDEA-Verschlüsselung kann nicht mit allen Zielschlüsseln verwendet "
-"werden.\n"
-
 #, c-format
 msgid ""
 "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
@@ -1437,7 +1535,7 @@ msgstr "Mit unbekanntem Verfahren verschlüsselt %d\n"
 msgid ""
 "WARNING: message was encrypted with a weak key in the symmetric cipher.\n"
 msgstr ""
-"Warnung: Botschaft wurde mit einem unsicheren Schlüssel verschlüsselt.\n"
+"WARNUNG: Botschaft wurde mit einem unsicheren Schlüssel verschlüsselt.\n"
 
 msgid "problem handling encrypted packet\n"
 msgstr "Problem beim Bearbeiten des verschlüsselten Pakets\n"
@@ -1457,11 +1555,11 @@ msgstr ""
 "Programmen\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "Ausführen des Programms `%s' nicht möglich: %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "Ausführen der Shell `%s' nicht möglich: %s\n"
 
 #, c-format
@@ -1479,12 +1577,12 @@ msgid "unable to read external program response: %s\n"
 msgstr "Die Ausgabe des externen Programms konnte nicht gelesen werden: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr ""
 "WARNUNG: die temporäre Datei (%s) `%s' konnte nicht entfernt werden: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "WARNUNG: Temporäres Verzeichnis `%s' kann nicht entfernt werden: %s\n"
 
 msgid "export signatures that are marked as local-only"
@@ -1496,9 +1594,6 @@ msgstr "Exportiere Attribute von User-IDs (i.A. Foto-IDs)"
 msgid "export revocation keys marked as \"sensitive\""
 msgstr "Exportiere Widerrufsschlüssel die als \"sensitiv\" markiert sind"
 
-msgid "remove the passphrase from exported subkeys"
-msgstr "Die Passphrase von exportierten Unterschlüssel entfernen"
-
 msgid "remove unusable parts from key during export"
 msgstr "Unbrauchbare Teile des Schlüssel während des Exports entfernen"
 
@@ -1512,10 +1607,6 @@ msgid "exporting secret keys not allowed\n"
 msgstr "Exportieren geheimer Schlüssel ist nicht erlaubt\n"
 
 #, c-format
-msgid "key %s: not protected - skipped\n"
-msgstr "Schlüssel %s: ungeschützt - übersprungen\n"
-
-#, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
 msgstr "Schlüssel %s: PGP 2.x-artiger Schlüssel - übersprungen\n"
 
@@ -1523,38 +1614,21 @@ msgstr "Schlüssel %s: PGP 2.x-artiger Schlüssel - übersprungen\n"
 msgid "key %s: key material on-card - skipped\n"
 msgstr "Schlüssel %s: Schlüsselmaterial ist auf einer Karte - übersprungen\n"
 
-msgid "about to export an unprotected subkey\n"
-msgstr "Ein ungeschützter Unterschlüssel wird exportiert werden\n"
-
-#, c-format
-msgid "failed to unprotect the subkey: %s\n"
-msgstr "Entfernen des Schutzes für des Unterschlüssel fehlgeschlagen: %s\n"
-
-# translated by wk
-#, c-format
-msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr "WARNUNG: Der geheime Schlüssel %s hat keine einfache SK-Prüfsumme\n"
+msgid " - skipped"
+msgstr " - übersprungen"
 
 msgid "WARNING: nothing exported\n"
 msgstr "WARNUNG: Nichts exportiert\n"
 
-msgid "too many entries in pk cache - disabled\n"
-msgstr "zu viele Einträge im pk-Cache - abgeschaltet\n"
-
 msgid "[User ID not found]"
 msgstr "[User-ID nicht gefunden]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr ""
-"Schlüssel %s: geheimer Schlüssel ohne öffentlichen Schlüssel - übersprungen\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "`%s' automatisch via %s geholt\n"
 
 #, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "Fehler beim automatischen holen von `%s' über `%s': %s\n"
 
 msgid "No fingerprint"
@@ -1566,11 +1640,6 @@ msgstr ""
 "Ungültiger Schlüssel %s, gültig gemacht per --allow-non-selfsigned-uid\n"
 
 #, c-format
-msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr ""
-"Kein privater Unterschlüssel zum öffentlichen Unterschlüssel %s - ignoriert\n"
-
-#, c-format
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "der Unterschlüssel %s wird anstelle des Hauptschlüssels %s verwendet\n"
 
@@ -1613,6 +1682,12 @@ msgstr "Liste der geheimen Schlüssel"
 msgid "generate a new key pair"
 msgstr "Ein neues Schlüsselpaar erzeugen"
 
+msgid "quickly generate a new key pair"
+msgstr "Schnell ein neues Schlüsselpaar erzeugen"
+
+msgid "full featured key pair generation"
+msgstr "Ein neues Schlüsselpaar erzeugen (alle Optionen)"
+
 msgid "generate a revocation certificate"
 msgstr "Ein Schlüsselwiderruf-Zertifikat erzeugen"
 
@@ -1622,6 +1697,12 @@ msgstr "Schlüssel aus dem öff. Schlüsselbund entfernen"
 msgid "remove keys from the secret keyring"
 msgstr "Schlüssel aus dem geh. Schlüsselbund entfernen"
 
+msgid "quickly sign a key"
+msgstr "Schlüssel schnell signieren"
+
+msgid "quickly sign a key locally"
+msgstr "Schlüssel schnell nur für diesen Rechner signieren"
+
 msgid "sign a key"
 msgstr "Schlüssel signieren"
 
@@ -1724,15 +1805,15 @@ msgstr ""
 " --list-keys [Namen]        Schlüssel anzeigen\n"
 " --fingerprint [Namen]      \"Fingerabdrücke\" anzeigen\n"
 
-msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "Aufruf: gpg [Optionen] [Dateien] (-h für Hilfe)"
+msgid "Usage: @GPG@ [options] [files] (-h for help)"
+msgstr "Aufruf: @GPG@ [Optionen] [Dateien] (-h für Hilfe)"
 
 msgid ""
-"Syntax: gpg [options] [files]\n"
+"Syntax: @GPG@ [options] [files]\n"
 "Sign, check, encrypt or decrypt\n"
 "Default operation depends on the input data\n"
 msgstr ""
-"Aufruf: gpg [Optionen] [Dateien]\n"
+"Aufruf: @GPG@ [Optionen] [Dateien]\n"
 "Signieren, prüfen, verschlüsseln, entschlüsseln.\n"
 "Die voreingestellte Operation ist abhängig von den Eingabedaten\n"
 
@@ -1755,98 +1836,102 @@ msgstr "Hash: "
 msgid "Compression: "
 msgstr "Komprimierung: "
 
-msgid "usage: gpg [options] "
-msgstr "Aufruf: gpg [Optionen] "
+#, c-format
+msgid "usage: %s [options] %s\n"
+msgstr "Aufruf: %s [Optionen] %s\n"
 
 msgid "conflicting commands\n"
 msgstr "Widersprüchliche Befehle\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "Kein '='-Zeichen in der Gruppendefinition gefunden `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "WARNUNG: Unsicheres Besitzverhältnis des Home-Verzeichnis `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "WARNUNG: Unsicheres Besitzverhältnis der Konfigurationsdatei `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "WARNUNG: Unsicheres Besitzverhältnis auf die Erweiterung `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "WARNUNG: Unsichere Zugriffsrechte des Home-Verzeichnis `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "WARNUNG: Unsichere Zugriffsrechte der Konfigurationsdatei `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "WARNUNG: Unsichere Zugriffsrechte auf die Erweiterung `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
 "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses für Home-"
 "Verzeichnis `%s'\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory ownership on configuration file '%s'\n"
 msgstr ""
 "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses der "
-"Konfigurationsdatei `%s'\n"
+"Konfigurationsdatei '%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses des Home-"
 "Verzeichnisses `%s'\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory permissions on configuration file '%s'\n"
 msgstr ""
 "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses der "
-"Konfigurationsdatei `%s'\n"
+"Konfigurationsdatei '%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses auf "
 "Erweiterung `%s'\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "Unbekanntes Konfigurationselement `%s'\n"
 
 msgid "display photo IDs during key listings"
 msgstr "Anzeigen der Foto-ID in den Schlüssellisten"
 
+msgid "show key usage information during key listings"
+msgstr "Schlüsselverwendungszwecke mit den Schlüsseln anlisten"
+
 msgid "show policy URLs during signature listings"
-msgstr "Zeige Richtlinien-URL während des listens der Signaturen"
+msgstr "Richtlinien-URL mit den Signaturen anlisten"
 
 msgid "show all notations during signature listings"
 msgstr "Alle Notationen mit den Signaturen anlisten"
 
 msgid "show IETF standard notations during signature listings"
-msgstr "Zeige IETF-Standard"
+msgstr "Standard Notationen mit den Signaturen anlisten"
 
 msgid "show user-supplied notations during signature listings"
-msgstr "Zeige Benutzer-Notationen während des listens der Signaturen"
+msgstr "Benutzer-Notationen mit den Signaturen anlisten"
 
 msgid "show preferred keyserver URLs during signature listings"
-msgstr "Der bevorzugten Schlüsselserver mit den Signaturen anlisten"
+msgstr "Bevorzugten Schlüsselserver mit den Signaturen anlisten"
 
 msgid "show user ID validity during key listings"
 msgstr "Zeige Gültigkeit der User-ID in den Schlüssellisten"
@@ -1864,7 +1949,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Das Ablaufdatum mit den Signaturen anlisten"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "Note: old default options file '%s' ignored\n"
 msgstr "Hinweis: Alte voreingestellte Optionendatei '%s' wurde ignoriert\n"
 
 #, c-format
@@ -1874,15 +1959,19 @@ msgstr ""
 "%s)\n"
 
 #, c-format
-msgid "NOTE: %s is not for normal use!\n"
+msgid "Note: %s is not for normal use!\n"
 msgstr "Hinweis: %s ist nicht für den üblichen Gebrauch gedacht!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "`%s' ist kein gültiges Signaturablaufdatum\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "invalid pinentry mode '%s'\n"
+msgstr "Ungültiger Subjekt-Name '%s'\n"
+
+#, c-format
+msgid "'%s' is not a valid character set\n"
 msgstr "`%s' ist kein gültiger Zeichensatz\n"
 
 msgid "could not parse keyserver URL\n"
@@ -1978,34 +2067,19 @@ msgstr "WARNUNG: %s ersetzt %s\n"
 
 #, c-format
 msgid "%s not allowed with %s!\n"
-msgstr "%s kann nicht zusammen mit %s verwendet werden!\n"
+msgstr "%s zusammen mit %s ist nicht erlaubt!\n"
 
 #, c-format
 msgid "%s makes no sense with %s!\n"
 msgstr "%s zusammen mit %s ist nicht sinnvoll!\n"
 
+msgid "WARNING: running with faked system time: "
+msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: "
+
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
 msgstr "Startet nicht mit unsicherem Speicher, wegen Option %s\n"
 
-msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
-msgstr ""
-"Im --pgp2-Modus können Sie nur abgetrennte oder Klartextsignaturen machen\n"
-
-msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr ""
-"Im --pgp2-Modus können Sie nicht gleichzeitig signieren und verschlüsseln\n"
-
-msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr ""
-"Im --pgp2-Modus müssen Sie Dateien benutzen und können keine Pipes "
-"verwenden.\n"
-
-msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr ""
-"Verschlüsseln einer Botschaft benötigt im --pgp2-Modus die IDEA-"
-"Verschlüsselung\n"
-
 msgid "selected cipher algorithm is invalid\n"
 msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n"
 
@@ -2033,7 +2107,7 @@ msgstr "ungültiger \"default-cert-level\"; Wert muß 0, 1, 2 oder 3 sein\n"
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
 msgstr "ungültiger \"min-cert-level\"; Wert muß 0, 1, 2 oder 3 sein\n"
 
-msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
+msgid "Note: simple S2K mode (0) is strongly discouraged\n"
 msgstr "Hinweis: Vom \"simple S2K\"-Modus (0) ist strikt abzuraten\n"
 
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
@@ -2056,17 +2130,17 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s arbeitet noch nicht mit %s zusammen\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr ""
 "Die Benutzung des Verschlüsselungsverfahren %s ist im %s-Modus nicht "
 "erlaubt.\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "Die Benutzung der Hashmethode %s ist im %s-Modus nicht erlaubt.\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr ""
 "Die Benutzung des Komprimierverfahren %s ist im %s-Modus nicht erlaubt.\n"
 
@@ -2085,7 +2159,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [Dateiname]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "Symmetrische Entschlüsselung von `%s' fehlgeschlagen: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2171,7 +2245,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "Anbringen der ASCII-Hülle ist fehlgeschlagen: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "Ungültiges Hashverfahren '%s'\n"
 
 msgid "[filename]"
@@ -2212,7 +2286,7 @@ msgid "No help available"
 msgstr "Keine Hilfe vorhanden."
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Keine Hilfe für '%s' vorhanden."
 
 msgid "import signatures that are marked as local-only"
@@ -2221,16 +2295,9 @@ msgstr "Importiere Signaturen, die als nicht exportfähig markiert sind"
 msgid "repair damage from the pks keyserver during import"
 msgstr "Beseitige Beschädigung durch den Schlüsselserver während des Imports"
 
-msgid "do not clear the ownertrust values during import"
-msgstr "die \"ownertrust\" Werte bei einem Import nicht zurücksetzen"
-
 msgid "do not update the trustdb after import"
 msgstr "ändern Sie die \"Trust\"-Datenbank nach dem Import nicht"
 
-msgid "create a public key when importing a secret key"
-msgstr ""
-"beim Import eines geheimen Schlüssels einen öffentliche Schlüssel erzeugen"
-
 msgid "only accept updates to existing keys"
 msgstr "Nur Änderungen bereits existierender Schlüssel vornehmen"
 
@@ -2350,8 +2417,8 @@ msgstr "Schlüssel %s: Keine User-ID\n"
 msgid "key %s: %s\n"
 msgstr "Schlüssel %s: %s\n"
 
-msgid "rejected by import filter"
-msgstr "vom Importfilter zurückgewiesen"
+msgid "rejected by import screener"
+msgstr "vom Import-Aufpasser zurückgewiesen"
 
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
@@ -2381,11 +2448,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "kein schreibbarer Schlüsselbund gefunden: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "Schreiben nach '%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "Fehler beim Schreiben des Schlüsselbundes `%s': %s\n"
 
 #, c-format
@@ -2449,6 +2516,18 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "Schlüssel %s: \"%s\" nicht geändert\n"
 
 #, c-format
+msgid "key %s: secret key imported\n"
+msgstr "Schlüssel %s: geheimer Schlüssel importiert\n"
+
+#, c-format
+msgid "key %s: secret key already exists\n"
+msgstr "Schlüssel %s: geheimer Schlüssel bereits vorhanden\n"
+
+#, c-format
+msgid "key %s: error sending to agent: %s\n"
+msgstr "Schlüssel %s: Fehler beim Senden zum gpg-agent: %s\n"
+
+#, c-format
 msgid "secret key %s: %s\n"
 msgstr "Geheimer Schlüssel %s: %s\n"
 
@@ -2462,22 +2541,6 @@ msgstr ""
 "übersprungen\n"
 
 #, c-format
-msgid "no default secret keyring: %s\n"
-msgstr "Kein voreingestellter geheimer Schlüsselbund: %s\n"
-
-#, c-format
-msgid "key %s: secret key imported\n"
-msgstr "Schlüssel %s: geheimer Schlüssel importiert\n"
-
-#, c-format
-msgid "key %s: already in secret keyring\n"
-msgstr "Schlüssel %s: Ist bereits im geheimen Schlüsselbund\n"
-
-#, c-format
-msgid "key %s: secret key not found: %s\n"
-msgstr "Schlüssel %s: geheimer Schlüssel nicht gefunden: %s\n"
-
-#, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
 msgstr ""
 "Schlüssel %s: Kein öffentlicher Schlüssel - der Schlüsselwiderruf kann nicht "
@@ -2589,27 +2652,24 @@ msgstr "Schlüssel %s: \"%s\" Widerrufzertifikat hinzugefügt\n"
 msgid "key %s: direct key signature added\n"
 msgstr "Schlüssel %s: \"direct-key\"-Signaturen hinzugefügt\n"
 
-msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr ""
-"Hinweis: Eine Schlüsselseriennr stimmt nicht mit derjenigen der Karte "
-"überein\n"
-
-msgid "NOTE: primary key is online and stored on card\n"
-msgstr "Hinweis: Hauptschlüssel ist online und auf der Karte gespeichert\n"
-
-msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "Hinweis: Zweitschlüssel ist online und auf der Karte gespeichert\n"
+#, c-format
+msgid "error creating keybox '%s': %s\n"
+msgstr "Die \"Keybox\" `%s' konnte nicht erstellt werden: %s\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "Fehler beim Erzeugen des Schlüsselbundes `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keybox '%s' created\n"
+msgstr "Die \"Keybox\" `%s' wurde erstellt\n"
+
+#, c-format
+msgid "keyring '%s' created\n"
 msgstr "Schlüsselbund `%s' erstellt\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "Schlüsselblockhilfsmittel`%s': %s\n"
 
 #, c-format
@@ -2771,15 +2831,6 @@ msgid "Do you want your signature to expire at the same time? (Y/n) "
 msgstr "Soll Ihre Beglaubigung zur selben Zeit verfallen? (J/n) "
 
 msgid ""
-"You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
-"mode.\n"
-msgstr ""
-"Im --pgp2-Modus kann nur mit PGP-2.x-artigen Schlüsseln signiert werden\n"
-
-msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "Dies würde den Schlüssel für PGP 2.x unbrauchbar machen\n"
-
-msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
@@ -2805,7 +2856,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Ich habe es sehr sorgfältig überprüft.%s\n"
 
 # translated by wk
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Ihre Auswahl? ('?' für weitere Informationen): "
 
 #, c-format
@@ -2853,41 +2904,9 @@ msgstr ""
 "Der Schlüssel enthält nur \"stub\"- oder \"on-card\"-Schlüsselelemente- "
 "keine Passphrase ist zu ändern.\n"
 
-msgid "This key is not protected.\n"
-msgstr "Dieser Schlüssel ist nicht geschützt.\n"
-
-msgid "Secret parts of primary key are not available.\n"
-msgstr "Geheime Teile des Hauptschlüssels sind nicht vorhanden.\n"
-
-msgid "Secret parts of primary key are stored on-card.\n"
-msgstr "Geheime Teile des Hauptschlüssels sind auf der Karte gespeichert.\n"
-
-msgid "Key is protected.\n"
-msgstr "Schlüssel ist geschützt.\n"
-
 #, c-format
-msgid "Can't edit this key: %s\n"
-msgstr "Dieser Schlüssel kann nicht editiert werden: %s\n"
-
-msgid ""
-"Enter the new passphrase for this secret key.\n"
-"\n"
-msgstr ""
-"Geben Sie die neue Passphrase für diesen geheimen Schlüssel ein.\n"
-"\n"
-
-msgid "passphrase not correctly repeated; try again"
-msgstr "Passphrase wurde nicht richtig wiederholt; noch einmal versuchen"
-
-msgid ""
-"You don't want a passphrase - this is probably a *bad* idea!\n"
-"\n"
-msgstr ""
-"Sie wollen keine Passphrase - dies ist *nicht* zu empfehlen!\n"
-"\n"
-
-msgid "Do you really want to do this? (y/N) "
-msgstr "Möchten Sie dies wirklich tun? (j/N) "
+msgid "key %s: error changing passphrase: %s\n"
+msgstr "Schlüssel %s: Fehler beim Ändern der Passphrase: %s\n"
 
 msgid "moving a key signature to the correct place\n"
 msgstr "schiebe eine Beglaubigung an die richtige Stelle\n"
@@ -3012,10 +3031,6 @@ msgstr ""
 "unbrauchbare User-IDs verkleinern und alle Signaturen aus dem Schlüssel "
 "entfernen"
 
-#, c-format
-msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "Fehler beim Lesen des geheimen Schlüsselblocks \"%s\": %s\n"
-
 msgid "Secret key is available.\n"
 msgstr "Geheimer Schlüssel ist vorhanden.\n"
 
@@ -3026,14 +3041,14 @@ msgid "Please use the command \"toggle\" first.\n"
 msgstr "Bitte verwenden sie zunächst den Befehl \"toggle\"\n"
 
 msgid ""
-"* The `sign' command may be prefixed with an `l' for local signatures "
+"* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
-"  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
+"  a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
-"* Dem `sign'-Befehl darf ein `l' für nicht exportfähige Signaturen "
+"* Dem 'sign'-Befehl darf ein 'l' für nicht exportfähige Signaturen "
 "vorangestellt werden (\"lsign\"),\n"
-"  ein `t' für 'Trust'-Signatur (\"tsign\"), ein `nr' für unwiderrufbare "
+"  ein 't' für 'Trust'-Signatur (\"tsign\"), ein 'nr' für unwiderrufbare "
 "Signaturen\n"
 " (\"nrsign\"), oder jede Kombination davon (\"ltsign\", \"tnrsign\", etc.).\n"
 
@@ -3047,7 +3062,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Tip: Wählen Sie die User-IDs, die beglaubigt werden sollen\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Unbekannter Signaturtyp `%s'\n"
 
 #, c-format
@@ -3078,11 +3093,11 @@ msgid "Command expects a filename argument\n"
 msgstr "Befehl benötigt einen Dateinamen als Argument\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "'%s' kann nicht geöffnet werden: %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Fehler beim Lesen der Sicherungskopie des Schlüssels von `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3136,13 +3151,23 @@ msgstr "Beenden ohne zu speichern? (j/N) "
 msgid "update failed: %s\n"
 msgstr "Änderung fehlgeschlagen: %s\n"
 
-#, c-format
-msgid "update secret failed: %s\n"
-msgstr "Änderung des Geheimnisses fehlgeschlagen: %s\n"
-
 msgid "Key not changed so no update needed.\n"
 msgstr "Schlüssel ist nicht geändert worden, also ist kein Speichern nötig.\n"
 
+#, c-format
+msgid "\"%s\" is not a fingerprint\n"
+msgstr "\"%s\" ist kein Fingerabdruck\n"
+
+#, c-format
+msgid "\"%s\" is not the primary fingerprint\n"
+msgstr "\"%s\" ist nicht der Fingerabdruck des Hauptschlüssels\n"
+
+msgid "No matching user IDs."
+msgstr "Keine passende User-ID"
+
+msgid "Nothing to sign.\n"
+msgstr "Nichts zu beglaubigen\n"
+
 msgid "Digest: "
 msgstr "Digest: "
 
@@ -3167,7 +3192,8 @@ msgstr "Der folgende Schlüssel wurde am %s von %s Schlüssel %s widerrufen\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
-msgstr "Dieser Schlüssel kann von %s-Schlüssel %s widerrufen werden"
+msgstr ""
+"Dieser Schlüssel könnte durch %s mit Schlüssel %s  widerrufen worden sein"
 
 msgid "(sensitive)"
 msgstr "(empfindlich)"
@@ -3192,6 +3218,9 @@ msgstr "verfällt: %s"
 msgid "usage: %s"
 msgstr "Aufruf: %s"
 
+msgid "card-no: "
+msgstr "Kartennummer:"
+
 #, c-format
 msgid "trust: %s"
 msgstr "Vertrauen: %s"
@@ -3203,9 +3232,6 @@ msgstr "Gültigkeit: %s"
 msgid "This key has been disabled"
 msgstr "Hinweis: Dieser Schlüssel ist abgeschaltet"
 
-msgid "card-no: "
-msgstr "Kartennummer:"
-
 msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
@@ -3228,10 +3254,10 @@ msgstr ""
 "dazu führen, daß eine andere User-ID als primär angesehen wird.\n"
 
 msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr "WARNUNG: Ihr Verschlüsselungsunterschlüssel wird bald verfallen.\n"
+msgstr "WARNUNG: Ihr Unterschlüssel zum Verschlüsseln wird bald verfallen.\n"
 
 msgid "You may want to change its expiration date too.\n"
-msgstr "Vermutlich möchten Sie auch dessen Verfallsdatum ändern.\n"
+msgstr "Bitte erwägen Sie, dessen Verfallsdatum auch zu ändern.\n"
 
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
@@ -3333,9 +3359,6 @@ msgstr ""
 "Möchten Sie diesen Schlüssel wirklich als vorgesehenen Widerrufer festlegen? "
 "(j/N): "
 
-msgid "Please remove selections from the secret keys.\n"
-msgstr "Bitte entfernen Sie die Auswahl von den geheimen Schlüsseln.\n"
-
 msgid "Please select at most one subkey.\n"
 msgstr "Bitte wählen Sie höchstens einen Unterschlüssel aus.\n"
 
@@ -3348,9 +3371,6 @@ msgstr "Ändern des Verfallsdatums des Hauptschlüssels.\n"
 msgid "You can't change the expiration date of a v3 key\n"
 msgstr "Sie können das Verfallsdatum eines v3-Schlüssels nicht ändern\n"
 
-msgid "No corresponding signature in secret ring\n"
-msgstr "Keine entsprechende Signatur im geheimen Schlüsselbund\n"
-
 #, c-format
 msgid "signing subkey %s is already cross-certified\n"
 msgstr "Signaturunterschlüssel %s ist bereits rücksigniert\n"
@@ -3461,7 +3481,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Anzeigen einer %s Foto-ID (Größe %ld) für Schlüssel %s (User-ID %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "Voreinstellung `%s' ist doppelt\n"
 
 msgid "too many cipher preferences\n"
@@ -3474,7 +3494,7 @@ msgid "too many compression preferences\n"
 msgstr "zu viele Komprimierungsvoreinstellungen\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "Ungültiges Feld `%s' in der Voreinstellungszeichenkette\n"
 
 msgid "writing direct signature\n"
@@ -3584,6 +3604,35 @@ msgid "   (%d) RSA (set your own capabilities)\n"
 msgstr "   (%d) RSA (Leistungsfähigkeit selber einstellbar)\n"
 
 #, c-format
+msgid "   (%d) ECC and ECC\n"
+msgstr "  (%d) ECC und ECC\n"
+
+#, c-format
+msgid "  (%d) ECC (sign only)\n"
+msgstr "  (%d) ECC (nur signieren)\n"
+
+#, c-format
+msgid "  (%d) ECC (set your own capabilities)\n"
+msgstr "  (%d) ECC (Leistungsfähigkeit selber einstellbar)\n"
+
+#, c-format
+msgid "  (%d) ECC (encrypt only)\n"
+msgstr "  (%d) ECC (nur verschlüsseln)\n"
+
+#, c-format
+msgid "  (%d) Existing key\n"
+msgstr "   (%d) Vorhandener Schlüssel\n"
+
+msgid "Enter the keygrip: "
+msgstr "Geben Sie den \"Keygrip\" ein: "
+
+msgid "Not a valid keygrip (expecting 40 hex digits)\n"
+msgstr "Kein gültiger \"Keygrip\" (40 Hex-Ziffern werden erwartet)\n"
+
+msgid "No key with this keygrip\n"
+msgstr "Kein Schlüssel mit diesem \"Keygrip\"\n"
+
+#, c-format
 msgid "%s keys may be between %u and %u bits long.\n"
 msgstr "%s-Schlüssel können zwischen %u und %u Bit lang sein.\n"
 
@@ -3599,6 +3648,13 @@ msgstr "Welche Schlüssellänge wünschen Sie? (%u) "
 msgid "Requested keysize is %u bits\n"
 msgstr "Die verlangte Schlüssellänge beträgt %u Bit\n"
 
+#, c-format
+msgid "rounded to %u bits\n"
+msgstr "gerundet auf %u Bit\n"
+
+msgid "Please select which elliptic curve you want:\n"
+msgstr "Bitte wählen Sie, welche elliptische Kurve Sie möchten:\n"
+
 msgid ""
 "Please specify how long the key should be valid.\n"
 "         0 = key does not expire\n"
@@ -3669,7 +3725,7 @@ msgid ""
 "\n"
 msgstr ""
 "\n"
-"GnuPG erstellt eine User-ID um Ihren Schlüssel identifizierbar zu machen.\n"
+"GnuPG erstellt eine User-ID, um Ihren Schlüssel identifizierbar zu machen.\n"
 "\n"
 
 #. TRANSLATORS: This string is in general not anymore used
@@ -3716,7 +3772,7 @@ msgid "Invalid character in comment\n"
 msgstr "Ungültiges Zeichen im Kommentar.\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Sie benutzen den Zeichensatz `%s'\n"
 
 #, c-format
@@ -3755,6 +3811,12 @@ msgstr "Ändern: (N)ame, (K)ommentar, (E)-Mail oder (A)bbrechen? "
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
 msgstr "Ändern: (N)ame, (K)ommentar, (E)-Mail oder (F)ertig/(A)bbrechen? "
 
+msgid "Change (N)ame, (E)mail, or (Q)uit? "
+msgstr "Ändern: (N)ame, (E)-Mail oder (A)bbrechen? "
+
+msgid "Change (N)ame, (E)mail, or (O)kay/(Q)uit? "
+msgstr "Ändern: (N)ame, (E)-Mail oder (F)ertig/(A)bbrechen? "
+
 msgid "Please correct the error first\n"
 msgstr "Bitte beseitigen Sie zuerst den Fehler\n"
 
@@ -3772,6 +3834,9 @@ msgstr ""
 "Bitte geben Sie die Passphrase ein, um die Sicherheitskopie des neuen "
 "Verschlüsselungsschlüssel der Karte zu schützen."
 
+msgid "passphrase not correctly repeated; try again"
+msgstr "Passphrase wurde nicht richtig wiederholt; noch einmal versuchen"
+
 #, c-format
 msgid "%s.\n"
 msgstr "%s.\n"
@@ -3798,36 +3863,51 @@ msgstr ""
 "unterstützen, indem Sie z.B. in einem anderen Fenster/Konsole irgendetwas\n"
 "tippen, die Maus verwenden oder irgendwelche anderen Programme benutzen.\n"
 
-msgid "Key generation canceled.\n"
-msgstr "Schlüsselerzeugung abgebrochen.\n"
-
 #, c-format
-msgid "writing public key to `%s'\n"
-msgstr "schreiben des öffentlichen Schlüssels nach '%s'\n"
+msgid "Key generation failed: %s\n"
+msgstr "Schlüsselerzeugung fehlgeschlagen: %s\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "schreiben des geheimen Schlüssel-\"stub\"s nach `%s'\n"
+msgid ""
+"About to create a key for:\n"
+"    \"%s\"\n"
+"\n"
+msgstr ""
+"Erzeugung eines Schlüssels für:\n"
+"    \"%s\"\n"
+"\n"
+
+msgid "Continue? (Y/n) "
+msgstr "Fortsetzen? (J/n) "
 
 #, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "schreiben des geheimen Schlüssels nach '%s'\n"
+msgid "A key for \"%s\" already exists\n"
+msgstr "Ein Schlüssel für \"%s\" existiert bereits\n"
+
+msgid "Create anyway? (y/N) "
+msgstr "Trotzdem erzeugen? (j/N) "
+
+msgid "creating anyway\n"
+msgstr "wird trotzdem erzeugt\n"
 
 #, c-format
-msgid "no writable public keyring found: %s\n"
-msgstr "kein schreibbarer öffentlicher Schlüsselbund gefunden: %s\n"
+msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n"
+msgstr "Hinweis: \"%s %s\" ruft den erweiterten Dialog auf.\n"
+
+msgid "Key generation canceled.\n"
+msgstr "Schlüsselerzeugung abgebrochen.\n"
 
 #, c-format
-msgid "no writable secret keyring found: %s\n"
-msgstr "kein schreibbarer geheimer Schlüsselbund gefunden: %s\n"
+msgid "writing public key to '%s'\n"
+msgstr "schreiben des öffentlichen Schlüssels nach '%s'\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "Fehler beim Schreiben des öff. Schlüsselbundes `%s': %s\n"
+msgid "no writable public keyring found: %s\n"
+msgstr "kein schreibbarer öffentlicher Schlüsselbund gefunden: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "Fehler beim Schreiben des geheimen Schlüsselbundes `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
+msgstr "Fehler beim Schreiben des öff. Schlüsselbundes `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
 msgstr "Öffentlichen und geheimen Schlüssel erzeugt und signiert.\n"
@@ -3841,10 +3921,6 @@ msgstr ""
 "Unterschlüssel für diesem Zweck erzeugen.\n"
 
 #, c-format
-msgid "Key generation failed: %s\n"
-msgstr "Schlüsselerzeugung fehlgeschlagen: %s\n"
-
-#, c-format
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr ""
@@ -3858,8 +3934,14 @@ msgstr ""
 "Der Schlüssel wurde %lu Sekunden in der Zukunft erzeugt (Zeitreise oder "
 "Uhren stimmen nicht überein)\n"
 
-msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
-msgstr "HINWEIS: Unterschlüssel für v3-Schlüssel sind nicht OpenPGP-konform\n"
+msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n"
+msgstr "Hinweis: Unterschlüssel für v3-Schlüssel sind nicht OpenPGP-konform\n"
+
+msgid "Secret parts of primary key are not available.\n"
+msgstr "Geheime Teile des Hauptschlüssels sind nicht vorhanden.\n"
+
+msgid "Secret parts of primary key are stored on-card.\n"
+msgstr "Geheime Teile des Hauptschlüssels sind auf der Karte gespeichert.\n"
 
 msgid "Really create? (y/N) "
 msgstr "Wirklich erzeugen? (j/N) "
@@ -3869,11 +3951,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "Speicher des Schlüssels auf der Karte schlug fehl: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "Sicherungsdatei '%s' kann nicht erzeugt werden: %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "Note: backup of card key saved to '%s'\n"
 msgstr "Hinweis: Sicherung des Kartenschlüssels wurde auf `%s' gespeichert\n"
 
 msgid "never     "
@@ -3894,6 +3976,10 @@ msgstr "Entscheidender Beglaubigungs-\"Notation\": "
 msgid "Signature notation: "
 msgstr "Beglaubigungs-\"Notation\": "
 
+#, c-format
+msgid "Warning: %lu key(s) skipped due to their large size\n"
+msgstr "WARNUNG: %lu Schlüssel übersprungen, da sie zu groß sind\n"
+
 msgid "Keyring"
 msgstr "Schlüsselbund"
 
@@ -3914,33 +4000,15 @@ msgstr " Unter-Fingerabdruck  ="
 msgid "      Key fingerprint ="
 msgstr "  Schl.-Fingerabdruck ="
 
-#, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "WARNUNG: Ein PGP-2 Fingerabdruck ist unsicher\n"
-
 msgid "      Card serial no. ="
 msgstr "      Kartenseriennr. ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "umbenennen von `%s' nach `%s' schlug fehl: %s\n"
 
-msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr "Warnung: Zwei Dateien mit vertraulichem Inhalt vorhanden.\n"
-
-#, c-format
-msgid "%s is the unchanged one\n"
-msgstr "%s ist der Unveränderte\n"
-
-#, c-format
-msgid "%s is the new one\n"
-msgstr "%s ist der Neue\n"
-
-msgid "Please fix this possible security flaw\n"
-msgstr "Bitte diesen potentiellen Sicherheitsmangel beseitigen\n"
-
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "Puffern des Schlüsselbundes `%s'\n"
 
 #, c-format
@@ -3980,7 +4048,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "Die im Schlüssel enthaltenen PKA-Daten beim Schlüsselholen beachten"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "WARNUNG: Schlüsselserver-Option `%s' wird auf dieser Plattform nicht "
 "verwendet\n"
@@ -3996,6 +4064,25 @@ msgid "invalid keyserver protocol (us %d!=handler %d)\n"
 msgstr "Ungültiges Schlüsselserverprotokoll (wir %d!=Handhabungsroutine %d)\n"
 
 #, c-format
+msgid "\"%s\" not a key ID: skipping\n"
+msgstr "\"%s\" ist keine Schlüssel-ID: überspringe\n"
+
+#, c-format
+msgid "WARNING: unable to refresh key %s via %s: %s\n"
+msgstr "WARNUNG: Schlüssel %s kann per %s nicht aktualisiert werden: %s\n"
+
+#, c-format
+msgid "refreshing 1 key from %s\n"
+msgstr "ein Schlüssel wird per %s aktualisiert\n"
+
+#, c-format
+msgid "refreshing %d keys from %s\n"
+msgstr "%d Schlüssel werden per %s aktualisiert\n"
+
+msgid "no keyserver known (use option --keyserver)\n"
+msgstr "Kein Schlüsselserver bekannt (Option --keyserver verwenden)\n"
+
+#, c-format
 msgid "key \"%s\" not found on keyserver\n"
 msgstr "Schlüssel \"%s\" wurde auf dem Schlüsselserver nicht gefunden\n"
 
@@ -4011,12 +4098,8 @@ msgid "requesting key %s from %s\n"
 msgstr "fordere Schlüssel %s von %s an\n"
 
 #, c-format
-msgid "searching for names from %s server %s\n"
-msgstr "suche Namen auf %s-Server %s\n"
-
-#, c-format
-msgid "searching for names from %s\n"
-msgstr "suche Namen auf %s\n"
+msgid "skipped \"%s\": %s\n"
+msgstr "übersprungen \"%s\": %s\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
@@ -4027,79 +4110,14 @@ msgid "sending key %s to %s\n"
 msgstr "sende Schlüssel %s auf %s\n"
 
 #, c-format
-msgid "searching for \"%s\" from %s server %s\n"
-msgstr "suche nach \"%s\" auf %s-Server %s\n"
-
-#, c-format
-msgid "searching for \"%s\" from %s\n"
-msgstr "suche nach \"%s\" auf %s\n"
-
-msgid "no keyserver action!\n"
-msgstr "Kein Schlüsselserver-Vorgang\n"
-
-#, c-format
-msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr ""
-"WARNUNG: Die Schlüsselserver-Handhabungsroutine stammt von einer anderen "
-"GnuPG-Version (%s)\n"
-
-msgid "keyserver did not send VERSION\n"
-msgstr "Schlüsselserver sendete VERSION nicht\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "Schlüsselserver-Datenübertragunsfehler: %s\n"
-
-msgid "no keyserver known (use option --keyserver)\n"
-msgstr "Kein Schlüsselserver bekannt (Option --keyserver verwenden)\n"
-
-msgid "external keyserver calls are not supported in this build\n"
-msgstr ""
-"Externe Schlüsselserveraufrufe werden in diesem \"Build\" nicht unterstützt\n"
-
-#, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "Keine Handhabungsroutine für Schlüsselserverschema `%s'\n"
-
-#, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
-msgstr "Vorgang `%s' wird vom Schlüsselserverschema `%s' nicht unterstützt\n"
-
-#, c-format
-msgid "%s does not support handler version %d\n"
-msgstr "%s unterstützt Hilfsroutinenversion %d nicht\n"
-
-msgid "keyserver timed out\n"
-msgstr "Schlüsselserver-Zeitüberschreitung\n"
-
-msgid "keyserver internal error\n"
-msgstr "interner Fehler Schlüsselserver\n"
-
-#, c-format
-msgid "\"%s\" not a key ID: skipping\n"
-msgstr "\"%s\" ist keine Schlüssel-ID: überspringe\n"
-
-#, c-format
-msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr "WARNUNG: Schlüssel %s kann per %s nicht aktualisiert werden: %s\n"
-
-#, c-format
-msgid "refreshing 1 key from %s\n"
-msgstr "ein Schlüssel wird per %s aktualisiert\n"
-
-#, c-format
-msgid "refreshing %d keys from %s\n"
-msgstr "%d Schlüssel werden per %s aktualisiert\n"
+msgid "requesting key from '%s'\n"
+msgstr "fordere Schlüssel von %s an\n"
 
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
 msgstr "WARNUNG: die URI %s kann nicht geholt werden: %s\n"
 
 #, c-format
-msgid "WARNING: unable to parse URI %s\n"
-msgstr "WARNUNG: die URI %s kann nicht analysiert werden\n"
-
-#, c-format
 msgid "weird size for an encrypted session key (%d)\n"
 msgstr "Seltsame Länge für einen verschlüsselten Sitzungsschlüssel (%d)\n"
 
@@ -4159,7 +4177,7 @@ msgstr ""
 "WARNUNG: Botschaft wurde nicht integritätsgeschützt (integrity protected)\n"
 
 msgid "WARNING: encrypted message has been manipulated!\n"
-msgstr "Warnung: Verschlüsselte Botschaft ist manipuliert worden!\n"
+msgstr "WARNUNG: Verschlüsselte Botschaft ist manipuliert worden!\n"
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
@@ -4169,7 +4187,7 @@ msgstr "Passphrase aus dem Cache gelöscht.  Cache ID: %s\n"
 msgid "decryption failed: %s\n"
 msgstr "Entschlüsselung fehlgeschlagen: %s\n"
 
-msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
+msgid "Note: sender requested \"for-your-eyes-only\"\n"
 msgstr ""
 "Hinweis: Der Absender verlangte Vertraulichkeit(\"for-your-eyes-only\")\n"
 
@@ -4187,6 +4205,18 @@ msgstr ""
 msgid "no signature found\n"
 msgstr "Keine Signatur gefunden\n"
 
+#, c-format
+msgid "BAD signature from \"%s\""
+msgstr "FALSCHE Signatur von \"%s\""
+
+#, c-format
+msgid "Expired signature from \"%s\""
+msgstr "Verfallene Signatur von \"%s\""
+
+#, c-format
+msgid "Good signature from \"%s\""
+msgstr "Korrekte Signatur von \"%s\""
+
 msgid "signature verification suppressed\n"
 msgstr "Signaturüberprüfung unterdrückt\n"
 
@@ -4209,18 +4239,6 @@ msgstr "Signatur vom %s mittels %s-Schlüssel ID %s\n"
 msgid "Key available at: "
 msgstr "Schlüssel erhältlich bei: "
 
-#, c-format
-msgid "BAD signature from \"%s\""
-msgstr "FALSCHE Signatur von \"%s\""
-
-#, c-format
-msgid "Expired signature from \"%s\""
-msgstr "Verfallene Signatur von \"%s\""
-
-#, c-format
-msgid "Good signature from \"%s\""
-msgstr "Korrekte Signatur von \"%s\""
-
 msgid "[uncertain]"
 msgstr "[ungewiß]  "
 
@@ -4237,8 +4255,8 @@ msgid "Signature expires %s\n"
 msgstr "Diese Signatur verfällt am %s.\n"
 
 #, c-format
-msgid "%s signature, digest algorithm %s\n"
-msgstr "%s Signatur, Hashmethode \"%s\"\n"
+msgid "%s signature, digest algorithm %s%s%s\n"
+msgstr "%s Signatur, Hashmethode %s%s%s\n"
 
 msgid "binary"
 msgstr "Binäre"
@@ -4249,11 +4267,8 @@ msgstr "Textmodus"
 msgid "unknown"
 msgstr "unbekannt"
 
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-"WARNING: Dies ist keine abgetrennte Signatur; die Datei '%s' wurde NICHT "
-"geprüft!\n"
+msgid ", key algorithm "
+msgstr ", Schlüsselverfahren "
 
 #, c-format
 msgid "Can't check signature: %s\n"
@@ -4278,7 +4293,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "ungültiges root-Paket in proc_tree() entdeckt\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "fstat von `%s' schlug fehl in %s: %s\n"
 
 #, c-format
@@ -4308,14 +4323,7 @@ msgstr "WARNUNG: Die Verwendung des Hashverfahrens %s ist nicht ratsam\n"
 
 #, c-format
 msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Hinweis: Signaturen mit dem %s Hashverfahren werden zurückgewiesen.\n"
-
-msgid "the IDEA cipher plugin is not present\n"
-msgstr "das IDEA-Verschlüsselungs-Plugin ist nicht vorhanden\n"
-
-#, c-format
-msgid "please see %s for more information\n"
-msgstr "Siehe %s für weitere Infos\n"
+msgstr "Hinweis: %s basierte Signaturen werden zurückgewiesen.\n"
 
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
@@ -4339,21 +4347,20 @@ msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
 msgstr "%s:%u: Die Option \"%s\" is veraltet - sie hat keine Wirkung\n"
 
 #, c-format
-msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr "WARNUNG: \"%s\" ist eine veraltete Option - sie hat keine Wirkung.\n"
+msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgstr "WARNUNG: \"%s%s\" ist eine veraltete Option - sie hat keine Wirkung.\n"
 
 #, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
+msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n"
 msgstr ""
-"%s:%u: Die Option \"%s%s\" ist in dieser Datei sinnlos - sie hat lediglich "
-"Wirkung in %s\n"
+"%s:%u: Die Option \"%s\" is veraltet - sie hat eine Wirkung nur in %s.\n"
 
 #, c-format
 msgid ""
 "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
 msgstr ""
-"WARNUNG: \"%s%s\" ist eine veraltete Option - sie hat eine Wirkung lediglich "
-"in %s\n"
+"WARNUNG: \"%s%s\" ist eine veraltete Option - sie hat eine Wirkung nur\n"
+"in %s.\n"
 
 msgid "Uncompressed"
 msgstr "nicht komprimiert"
@@ -4367,15 +4374,20 @@ msgid "this message may not be usable by %s\n"
 msgstr "Diese Botschaft könnte für %s unbrauchbar sein\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "Mehrdeutige Option '%s'\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "Unbekannte Option '%s'\n"
 
+msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n"
+msgstr ""
+"Der öffentliche ECDSA Schlüssel muß ein Vielfaches von 8 Bit als Länge "
+"haben\n"
+
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Datei '%s' existiert bereits. "
 
 msgid "Overwrite? (y/N) "
@@ -4396,11 +4408,11 @@ msgid "assuming signed data in '%s'\n"
 msgstr "die unterzeichneten Daten sind wohl in '%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "Neue Konfigurationsdatei `%s' erstellt\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "WARNUNG: Optionen in `%s' sind während dieses Laufes noch nicht wirksam\n"
 
@@ -4460,6 +4472,50 @@ msgstr "%u-Bit %s Schlüssel, ID %s, erzeugt %s"
 msgid "         (subkey on main key ID %s)"
 msgstr "         (Unterschlüssel aus Hauptschlüssel-ID %s)"
 
+msgid "Please enter the passphrase to unlock the OpenPGP secret key:"
+msgstr ""
+"Sie benötigen eine Passphrase, um den geheimen OpenPGP Schlüssel zu "
+"entsperren:"
+
+msgid "Please enter the passphrase to import the OpenPGP secret key:"
+msgstr ""
+"Sie benötigen eine Passphrase, um den geheimen OpenPGP Schlüssel zu "
+"importieren:"
+
+msgid "Please enter the passphrase to export the OpenPGP secret subkey:"
+msgstr ""
+"Sie benötigen eine Passphrase, um den geheimen OpenPGP Unterschlüssel zu "
+"exportieren:"
+
+msgid "Please enter the passphrase to export the OpenPGP secret key:"
+msgstr ""
+"Sie benötigen eine Passphrase, um den geheimen OpenPGP Schlüssel zu "
+"exportieren:"
+
+msgid "Do you really want to permanently delete the OpenPGP secret subkey key:"
+msgstr ""
+"Möchten Sie den ausgewählten geheimen OpenPGP Unterschlüssel wirklich "
+"dauerhaft entfernen? (j/N) "
+
+msgid "Do you really want to permanently delete the OpenPGP secret key:"
+msgstr ""
+"Möchten Sie den ausgewählten geheimen OpenPGP Schlüssel wirklich dauerhaft "
+"entfernen? (j/N) "
+
+#, c-format
+msgid ""
+"%s\n"
+"\"%.*s\"\n"
+"%u-bit %s key, ID %s,\n"
+"created %s%s.\n"
+"%s"
+msgstr ""
+"%s\n"
+"\"%.*s\"\n"
+"%u-Bit %s Schlüssel, ID %s,\n"
+"erzeugt %s%s.\n"
+"%s"
+
 # translated by wk
 msgid ""
 "\n"
@@ -4479,7 +4535,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Dateiname mit JPEG für die Foto-ID eingeben: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "JPEG-Datei `%s' kann nicht geöffnet werden: %s\n"
 
 #, c-format
@@ -4490,7 +4546,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Wollen Sie es wirklich benutzen? (j/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "`%s' ist keine JPEG-Datei\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4639,13 +4695,12 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Hinweis: Dieser Schlüssel wurde abgeschaltet.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr "Hinweis: Überprüfte Adresse des Unterzeichners ist `%s'\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr ""
-"Hinweise: Adresse des Unterzeichners `%s' passt nicht zum DNS-Eintrag\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
+msgstr "Hinweis: Adresse des Unterzeichners `%s' passt nicht zum DNS-Eintrag\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
 msgstr "\"Trust\"-Ebene auf VOLLSTÄNDIG geändert (wg. gültiger PKA-Info)\n"
@@ -4687,6 +4742,10 @@ msgid "%s: skipped: %s\n"
 msgstr "%s: übersprungen: %s\n"
 
 #, c-format
+msgid "%s: skipped: public key is disabled\n"
+msgstr "%s: übersprungen: öffentlicher Schlüssel ist abgeschaltet\n"
+
+#, c-format
 msgid "%s: skipped: public key already present\n"
 msgstr "%s: übersprungen: öffentlicher Schlüssel bereits vorhanden\n"
 
@@ -4721,10 +4780,6 @@ msgstr "übersprungen: öffentlicher Schlüssel bereits gesetzt\n"
 msgid "unknown default recipient \"%s\"\n"
 msgstr "Unbekannter voreingestellter Empfänger \"%s\"\n"
 
-#, c-format
-msgid "%s: skipped: public key is disabled\n"
-msgstr "%s: übersprungen: öffentlicher Schlüssel ist abgeschaltet\n"
-
 msgid "no valid addressees\n"
 msgstr "Keine gültigen Adressaten\n"
 
@@ -4740,6 +4795,10 @@ msgid "data not saved; use option \"--output\" to save it\n"
 msgstr ""
 "Daten wurden nicht gespeichert; verwenden Sie dafür die Option \"--output\"\n"
 
+#, c-format
+msgid "error creating '%s': %s\n"
+msgstr "Fehler beim Erstellen von `%s': %s\n"
+
 msgid "Detached signature.\n"
 msgstr "Abgetrennte Beglaubigungen.\n"
 
@@ -4753,7 +4812,7 @@ msgid "no signed data\n"
 msgstr "keine signierten Daten\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "kann signierte Datei '%s' nicht öffnen.\n"
 
 #, c-format
@@ -4781,10 +4840,10 @@ msgstr ""
 "Empfängereinstellungen gefunden\n"
 
 #, c-format
-msgid "NOTE: secret key %s expired at %s\n"
+msgid "Note: secret key %s expired at %s\n"
 msgstr "Hinweis: geheimer Schlüssel %s verfällt am %s\n"
 
-msgid "NOTE: key has been revoked"
+msgid "Note: key has been revoked"
 msgstr "Hinweis: Schlüssel wurde widerrufen"
 
 #, c-format
@@ -4819,26 +4878,38 @@ msgstr "Widerrufzertifikat erzeugt.\n"
 msgid "no revocation keys found for \"%s\"\n"
 msgstr "keine Widerrufsschlüssel für \"%s\" gefunden\n"
 
+msgid "This is a revocation certificate for the OpenPGP key:"
+msgstr "Dies ist ein Widerrufszertifikat für den OpenPGP Schlüssel:"
+
+msgid ""
+"Use it to revoke this key in case of a compromise or loss of\n"
+"the secret key.  However, if the secret key is still accessible,\n"
+"it is better to generate a new revocation certificate and give\n"
+"a reason for the revocation."
+msgstr ""
+"Benutzen Sie es, um einen Schlüssel zu widerrufen, falls der private\n"
+"Schlüssel verloren wurde oder kompromittiert ist.  Falls jedoch auf\n"
+"den privaten Schlüssel noch zugegriffen werden kann, so ist es besser,\n"
+"ein neues Widerrufszertifikat zu erzeugen, um den Grund des Widerrufs\n"
+"mit angeben zu können."
+
+msgid ""
+"To avoid an accidental use of this file, a colon has been inserted\n"
+"before the 5 dashes below.  Remove this colon with a text editor\n"
+"before making use of this revocation certificate."
+msgstr ""
+"Um eine versehentliche Aktivierung des Widerrufszertifikats zu\n"
+"vermeiden, wurde ein Doppelpunkt direkt vor den 5 Spiegelstrichen\n"
+"unten eingefügt.  Vor dem Import dieses Widerrufszertifikats\n"
+"entfernen Sie bitte dieses Doppelpunkt mittels eines Texteditors."
+
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
 msgstr "Geheimer Schlüssel \"%s\" nicht gefunden: %s\n"
 
-#, c-format
-msgid "no corresponding public key: %s\n"
-msgstr "kein zugehöriger öffentlicher Schlüssel: %s\n"
-
-msgid "public key does not match secret key!\n"
-msgstr "Öffentlicher Schlüssel paßt nicht zum geheimen Schlüssel!\n"
-
 msgid "Create a revocation certificate for this key? (y/N) "
 msgstr "Ein Widerrufszertifikat für diesen Schlüssel erzeugen? (j/N) "
 
-msgid "unknown protection algorithm\n"
-msgstr "Unbekanntes Schutzverfahren\n"
-
-msgid "NOTE: This key is not protected!\n"
-msgstr "Dieser Schlüssel ist nicht geschützt.\n"
-
 # translated by wk
 msgid ""
 "Revocation certificate created.\n"
@@ -4851,12 +4922,12 @@ msgid ""
 msgstr ""
 "Widerrufszertifikat wurde erzeugt.\n"
 "\n"
-"Bitte speichern Sie es auf einem Medium, welches Sie wegschließen\n"
+"Bitte speichern Sie es auf einem Medium welches Sie wegschließen\n"
 "können; falls Mallory (ein Angreifer) Zugang zu diesem Zertifikat\n"
 "erhält, kann er Ihren Schlüssel unbrauchbar machen.  Es wäre klug,\n"
 "dieses Widerrufszertifikat auch auszudrucken und sicher aufzubewahren,\n"
-"falls das ursprüngliche Medium nicht mehr lesbar ist.  Aber Obacht: Das\n"
-"Drucksystem kann unter Umständen anderen Nutzern eine Kopie zugänglich\n"
+"falls das ursprüngliche Medium nicht mehr lesbar ist. Aber Obacht: Das\n"
+"Drucksystem kann unter Umständen eine Kopie anderen Nutzern zugänglich\n"
 "machen.\n"
 
 msgid "Please select the reason for the revocation:\n"
@@ -4883,34 +4954,6 @@ msgstr "(Keine Beschreibung angegeben)\n"
 msgid "Is this okay? (y/N) "
 msgstr "Ist das OK? (j/N) "
 
-msgid "secret key parts are not available\n"
-msgstr "Teile des geheimen Schlüssels sind nicht vorhanden\n"
-
-#, c-format
-msgid "protection algorithm %d%s is not supported\n"
-msgstr "Schutzverfahren %d%s wird nicht unterstützt\n"
-
-#, c-format
-msgid "protection digest %d is not supported\n"
-msgstr "Hashschutzverfahren %d wird nicht unterstützt\n"
-
-msgid "Invalid passphrase; please try again"
-msgstr "Ungültige Passphrase; versuchen Sie es bitte noch einmal"
-
-#, c-format
-msgid "%s ...\n"
-msgstr "%s ...\n"
-
-msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr ""
-"WARNUNG: Unsicherer Schlüssel entdeckt -\n"
-"         bitte Passphrase nochmals wechseln.\n"
-
-msgid "generating the deprecated 16-bit checksum for secret key protection\n"
-msgstr ""
-"Die mißbilligte 16-bit Prüfsumme wird zum Schutz des geheimen Schlüssels "
-"benutzt\n"
-
 msgid "weak key created - retrying\n"
 msgstr "Unsicherer Schlüssel erzeugt - neuer Versuch\n"
 
@@ -4920,16 +4963,14 @@ msgstr ""
 "Trotz %d-fachen Versuches konnte die Erzeugung eines unsicheren Schlüssels "
 "für sym. Verschlüsselung nicht vermieden werden!\n"
 
-msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "Für DSA muß die Hashlänge ein Vielfaches von 8 Bit sein\n"
-
 #, c-format
-msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "DSA-Schlüssel %s verwendet einen unsicheren (%u Bit-) Hash\n"
+msgid "%s key %s uses an unsafe (%zu bit) hash\n"
+msgstr "%s-Schlüssel %s verwendet ein unsicheres (%zu-Bit) Hashverfahren\n"
 
 #, c-format
-msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "DSA-Schlüssel %s benötigt einen mindestens %u Bit langen Hash\n"
+msgid "%s key %s requires a %zu bit or larger hash (hash is %s)\n"
+msgstr ""
+"%s-Schlüssel %s benötigt einen mindestens %zu Bit langen Hash (Hash ist %s)\n"
 
 msgid "WARNING: signature digest conflict in message\n"
 msgstr "WARNUNG: Widersprechende Hashverfahren in der signierten Nachricht\n"
@@ -4939,6 +4980,10 @@ msgid "WARNING: signing subkey %s is not cross-certified\n"
 msgstr "WARNUNG: Signaturunterschlüssel %s hat keine Rücksignatur\n"
 
 #, c-format
+msgid "please see %s for more information\n"
+msgstr "Siehe %s für weitere Infos\n"
+
+#, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr "WARNUNG: Signaturunterschlüssel %s hat eine ungültige Rücksignatur\n"
 
@@ -4965,11 +5010,11 @@ msgstr ""
 "Uhrenproblem)\n"
 
 #, c-format
-msgid "NOTE: signature key %s expired %s\n"
+msgid "Note: signature key %s expired %s\n"
 msgstr "Hinweis: Signaturschlüssel %s ist am %s verfallen\n"
 
 #, c-format
-msgid "NOTE: signature key %s has been revoked\n"
+msgid "Note: signature key %s has been revoked\n"
 msgstr "Hinweis: Signaturschlüssel %s wurde widerrufen\n"
 
 #, c-format
@@ -5019,11 +5064,6 @@ msgstr "Prüfung der erstellten Signatur ist fehlgeschlagen: %s\n"
 msgid "%s/%s signature from: \"%s\"\n"
 msgstr "%s/%s Signatur von: \"%s\"\n"
 
-msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"Im --pgp2-Modus kann nur mit PGP-2.x-artigen Schlüsseln eine abgetrennte "
-"Signatur erzeugt werden\n"
-
 #, c-format
 msgid ""
 "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
@@ -5034,11 +5074,6 @@ msgstr ""
 msgid "signing:"
 msgstr "signiere:"
 
-msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"Im --pgp2-Modus können Sie Klartextsignaturen nur mit PGP-2.x-artigen "
-"Schlüssel machen\n"
-
 #, c-format
 msgid "%s encryption will be used\n"
 msgstr "%s Verschlüsselung wird verwendet\n"
@@ -5052,10 +5087,6 @@ msgstr ""
 msgid "skipped \"%s\": duplicated\n"
 msgstr "übersprungen \"%s\": doppelt\n"
 
-#, c-format
-msgid "skipped \"%s\": %s\n"
-msgstr "übersprungen \"%s\": %s\n"
-
 msgid "skipped: secret key already present\n"
 msgstr "übersprungen: geheimer Schlüssel bereits vorhanden\n"
 
@@ -5077,7 +5108,7 @@ msgstr ""
 "# (\"gpg --import-ownertrust\" um sie zu restaurieren)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "Fehler in `%s': %s\n"
 
 msgid "line too long"
@@ -5093,11 +5124,11 @@ msgid "ownertrust value missing"
 msgstr "\"Owner trust\"-Wert fehlt"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "Fehler beim Suchen des \"Trust records\" in `%s': %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "Lesefehler in `%s': %s\n"
 
 #, c-format
@@ -5105,14 +5136,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "\"Trust-DB\": sync fehlgeschlagen: %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "Datei `%s' konnte nicht gesperrt werden\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "'%s' kann nicht gesperrt werden\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb Satz %lu: lseek fehlgeschlagen: %s\n"
 
@@ -5124,12 +5147,20 @@ msgid "trustdb transaction too large\n"
 msgstr "trustdb Transaktion zu groß\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "kann aus `%s' nicht zugreifen: %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: Verzeichnis existiert nicht!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kann aus `%s' nicht zugreifen: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "Datei `%s' konnte nicht gesperrt werden\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "'%s' kann nicht gesperrt werden\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5143,8 +5174,8 @@ msgstr "%s: ungültige trust-db erzeugt\n"
 msgid "%s: trustdb created\n"
 msgstr "%s: trust-db erzeugt\n"
 
-msgid "NOTE: trustdb not writable\n"
-msgstr "Notiz: Die \"trustdb\" ist nicht schreibbar\n"
+msgid "Note: trustdb not writable\n"
+msgstr "Hinweis: Die \"trustdb\" ist nicht schreibbar\n"
 
 #, c-format
 msgid "%s: invalid trustdb\n"
@@ -5214,7 +5245,7 @@ msgid "input line longer than %d characters\n"
 msgstr "Eingabezeile ist länger als %d Zeichen\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "'%s' ist keine gültige lange Schlüssel-ID\n"
 
 #, c-format
@@ -5261,53 +5292,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr "verwende Vertrauensmodell %s\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
-msgid "10 translator see trustdb.c:uid_trust_string_fixed"
-msgstr "10"
-
-msgid "[ revoked]"
-msgstr "[widerrufen]"
-
-msgid "[ expired]"
-msgstr "[verfall.]"
-
-msgid "[ unknown]"
-msgstr "[  unbek.]"
-
-msgid "[  undef ]"
-msgstr "[  undef.]"
-
-msgid "[marginal]"
-msgstr "[marginal]"
-
-msgid "[  full  ]"
-msgstr "[ vollst.]"
-
-msgid "[ultimate]"
-msgstr "[ uneing.]"
-
-msgid "undefined"
-msgstr "unbestimmt"
-
-msgid "never"
-msgstr "niemals"
-
-msgid "marginal"
-msgstr "marginal"
-
-msgid "full"
-msgstr "vollständig"
-
-msgid "ultimate"
-msgstr "uneingeschränkt"
-
 msgid "no need for a trustdb check\n"
 msgstr "\"Trust-DB\"-Überprüfung nicht nötig\n"
 
@@ -5316,11 +5300,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "nächste \"Trust-DB\"-Pflichtüberprüfung am %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "\"Trust-DB\"-Überprüfung ist beim `%s'-Vertrauensmodell nicht nötig\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "\"Trust-DB\"-Änderung ist beim `%s'-Vertrauensmodell nicht nötig\n"
 
 #, c-format
@@ -5380,110 +5364,6 @@ msgstr "Eingabezeile %u ist zu lang oder es fehlt ein LF\n"
 msgid "can't open fd %d: %s\n"
 msgstr "fd=%d kann nicht geöffnet werden: %s\n"
 
-msgid "argument not expected"
-msgstr "Argument nicht erwartet"
-
-msgid "read error"
-msgstr "Lesefehler"
-
-msgid "keyword too long"
-msgstr "Schlüsselwort ist zu lang"
-
-msgid "missing argument"
-msgstr "Fehlendes Argument"
-
-msgid "invalid argument"
-msgstr "Ungültiges Argument"
-
-msgid "invalid command"
-msgstr "Ungültiger Befehl"
-
-msgid "invalid alias definition"
-msgstr "Ungültige Alias-Definition"
-
-msgid "out of core"
-msgstr "Nicht genügend Speicher"
-
-msgid "invalid option"
-msgstr "Ungültige Option"
-
-#, c-format
-msgid "missing argument for option \"%.50s\"\n"
-msgstr "Fehlendes Argument für Option \"%.50s\"\n"
-
-#, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "Ungültiges Argument für Option \"%.50s\"\n"
-
-#, c-format
-msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "Option \"%.50s\" erwartet kein Argument\n"
-
-#, c-format
-msgid "invalid command \"%.50s\"\n"
-msgstr "Ungültiger Befehl \"%.50s\"\n"
-
-#, c-format
-msgid "option \"%.50s\" is ambiguous\n"
-msgstr "Option \"%.50s\" ist mehrdeutig\n"
-
-#, c-format
-msgid "command \"%.50s\" is ambiguous\n"
-msgstr "Befehl \"%.50s\" ist mehrdeutig\n"
-
-msgid "out of core\n"
-msgstr "Nicht genügend Speicher\n"
-
-#, c-format
-msgid "invalid option \"%.50s\"\n"
-msgstr "Ungültige Option \"%.50s\"\n"
-
-#, c-format
-msgid "you found a bug ... (%s:%d)\n"
-msgstr "Sie haben einen Bug (Programmfehler) gefunden ... (%s:%d)\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "Umwandlung von `%s' in `%s' ist nicht verfügbar\n"
-
-#, c-format
-msgid "iconv_open failed: %s\n"
-msgstr "iconv_open fehlgeschlagen: %s\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "Umwandlung von `%s' in `%s' schlug fehl: %s\n"
-
-#, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "Die temporäre Datei `%s' kann nicht erstellt werden: %s\n"
-
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "Fehler beim Schreiben von %s: %s\n"
-
-#, c-format
-msgid "removing stale lockfile (created by %d)\n"
-msgstr "eine übriggebliebene Sperrdatei wird entfernt (erzeugt von %d)\n"
-
-msgid " - probably dead - removing lock"
-msgstr " - existiert wahrscheinlich nicht mehr - entferne Sperre"
-
-#, c-format
-msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "warte auf die Freigabe der Sperre (gehalten von %d%s) %s...\n"
-
-msgid "(deadlock?) "
-msgstr "(Deadlock?) "
-
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "Dateisperre %s konnte nicht eingerichtet werden: %s\n"
-
-#, c-format
-msgid "waiting for lock %s...\n"
-msgstr "Warten auf die Freigabe der Dateisperre `%s' ...\n"
-
 msgid "set debugging flags"
 msgstr "Debug Flags setzen"
 
@@ -5579,6 +5459,9 @@ msgstr "Die Antwort enthält das RSA-Modulus nicht\n"
 msgid "response does not contain the RSA public exponent\n"
 msgstr "Antwort enthält den öffentlichen RSA-Exponenten nicht\n"
 
+msgid "response does not contain the EC public point\n"
+msgstr "Der öffentlichen EC Punkt fehlt in der Antwort\n"
+
 #, c-format
 msgid "using default PIN as %s\n"
 msgstr "Die Standard PIN wird für %s benutzt\n"
@@ -5646,10 +5529,10 @@ msgid "|N|New PIN"
 msgstr "|N|Neue PIN"
 
 msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "|A|Bitte die Admin-PIN und dann die neue Admin PIN eingeben."
+msgstr "|A|Bitte die Admin-PIN sowie die neue Admin-PIN eingeben."
 
 msgid "||Please enter the PIN and New PIN"
-msgstr "||Bitte die PIN und dann die neue PIN eingeben"
+msgstr "||Bitte die PIN sowie die neue PIN eingeben"
 
 msgid "error reading application data\n"
 msgstr "Fehler beim Lesen der Anwendungsdaten\n"
@@ -5754,19 +5637,19 @@ msgid "deny the use of admin card commands"
 msgstr "Verweigere die Benutzung von \"Admin\"-Befehlen"
 
 msgid "use variable length input for pinpad"
-msgstr "Tastatur des Kartenlesers hat variierbare Längen"
+msgstr "Variable Längeneingabe für die Kartenlesertastatur benutzen"
 
-msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Aufruf: scdaemon [Optionen] (-h für Hilfe)"
+msgid "Usage: @SCDAEMON@ [options] (-h for help)"
+msgstr "Gebrauch: @SCDAEMON@ [Optionen] (-h für Hilfe)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
-"Smartcard daemon for GnuPG\n"
+"Smartcard daemon for @GNUPG@\n"
 msgstr ""
-"Syntax: scdaemon [Optionen] [Befehl [Argumente]]\n"
-"Smartcard Daemon für GnuPG\n"
+"Syntax: @SCDAEMON@ [Optionen] [Befehl [Argumente]]\n"
+"Smartcard Daemon für @GNUPG@\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+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"
@@ -5784,26 +5667,6 @@ msgid "invalid radix64 character %02x skipped\n"
 msgstr "Ungültiges Basis-64 Zeichen %02X wurde übersprungen\n"
 
 #, c-format
-msgid "failed to proxy %s inquiry to client\n"
-msgstr "Die %s \"inquiry\" konnte nicht an den Client weitergeleitet werden\n"
-
-#, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "Kein aktiver Dirmngr - `%s' wird einer gestartet\n"
-
-msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "Die Variable DIRMNGR_INFO ist fehlerhaft\n"
-
-#, c-format
-msgid "dirmngr protocol version %d is not supported\n"
-msgstr "Die Dirmngr Protokollversion %d wird nicht unterstützt\n"
-
-msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr ""
-"Verbindung zum Dirmngr kann nicht aufgebaut werden - Ersatzmethode wird "
-"versucht\n"
-
-#, c-format
 msgid "validation model requested by certificate: %s"
 msgstr "Durch Zertifikat angefordertes Gültigkeitsmodell: %s"
 
@@ -5824,11 +5687,11 @@ msgid "critical marked policy without configured policies"
 msgstr "entscheidende Richtlinie ohne konfigurierte Richtlinien"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "Datei `%s' kann nicht geöffnet werden: %s\n"
 
-msgid "note: non-critical certificate policy not allowed"
-msgstr "Notiz: Die unkritische Zertifikatsrichtlinie ist nicht erlaubt"
+msgid "Note: non-critical certificate policy not allowed"
+msgstr "Hinweis: Die unkritische Zertifikatsrichtlinie ist nicht erlaubt"
 
 msgid "certificate policy not allowed"
 msgstr "Die Zertifikatsrichtlinie ist nicht erlaubt"
@@ -5990,10 +5853,6 @@ msgid "validation model used: %s"
 msgstr "Benutztes Gültigkeitsmodell: %s"
 
 #, c-format
-msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "%s-Schlüssel verwendet ein unsicheres (%u-Bit) Hashverfahren\n"
-
-#, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
 msgstr ""
 "Ein %u-Bit Hashverfahren ist für einen %u-Bit %s Schlüssel nicht möglich\n"
@@ -6072,11 +5931,11 @@ msgid "line %d: no subject name given\n"
 msgstr "Zeile %d: Kein Subjekt-Name angegeben\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr "Zeile %d: ungültiger Subjekt-Name-Label `%.*s'\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr "Zeile %d: ungültige Betreffbezeichnung `%s' in Spalte %d\n"
 
 #, c-format
@@ -6084,11 +5943,48 @@ msgid "line %d: not a valid email address\n"
 msgstr "Zeile %d: Keine gültige E-Mailadresse\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: invalid serial number\n"
+msgstr "Zeile %d: Ungültige Seriennummer\n"
+
+#, c-format
+msgid "line %d: invalid issuer name label '%.*s'\n"
+msgstr "Zeile %d: ungültiger Issuer-Name-Label `%.*s'\n"
+
+#, c-format
+msgid "line %d: invalid issuer name '%s' at pos %d\n"
+msgstr "Zeile %d: ungültiger Herausgeber `%s' in Spalte %d\n"
+
+#, c-format
+msgid "line %d: invalid date given\n"
+msgstr "Zeile %d: Ungültiges Datum\n"
+
+#, c-format
+msgid "line %d: error getting signing key by keygrip '%s': %s\n"
+msgstr ""
+"Zeile %d: Fehler beim Holen des Signaturschlüssels per \"Keygrip\" `%s': %s\n"
+
+#, c-format
+msgid "line %d: invalid hash algorithm given\n"
+msgstr "Zeile %d: Ungültiges Hashverfahren\n"
+
+#, c-format
+msgid "line %d: invalid authority-key-id\n"
+msgstr "Zeile %d: Ungültige Authentisierungsschlüssel-ID\n"
+
+#, c-format
+msgid "line %d: invalid subject-key-id\n"
+msgstr "Zeile %d: ungültige \"Subject-Key-Id\"\n"
+
+#, c-format
+msgid "line %d: invalid extension syntax\n"
+msgstr "Zeile %d: Ungültiger Syntax der Extension\n"
+
+#, c-format
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "Zeile %d: Fehler beim Lesen des Schlüssels `%s' von der Karte: %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "Zeile %d: Fehler beim Holen des Schlüssels per \"Keygrip\" `%s': %s\n"
 
 #, c-format
@@ -6114,15 +6010,6 @@ msgstr "   (%d) Vorhandener Schlüssel\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Vorhandener Schlüssel auf der Karte\n"
 
-msgid "Enter the keygrip: "
-msgstr "Geben Sie den \"Keygrip\" ein: "
-
-msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Kein gültiger \"Keygrip\" (40 Hex-Ziffern werden erwartet)\n"
-
-msgid "No key with this keygrip\n"
-msgstr "Kein Schlüssel mit diesem \"Keygrip\"\n"
-
 #, c-format
 msgid "error reading the card: %s\n"
 msgstr "Fehler beim Lesen von der Karte: %s\n"
@@ -6157,7 +6044,7 @@ msgid "No subject name given\n"
 msgstr "Kein Subjekt-Name angegeben\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr "Ungültiger Subjekt-Name-Label `%.*s'\n"
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6166,7 +6053,7 @@ msgstr "Ungültiger Subjekt-Name-Label `%.*s'\n"
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "Ungültiger Subjekt-Name `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6187,12 +6074,23 @@ msgstr " (Optional. Beenden mit einer leeren Zeile):\n"
 msgid "Enter URIs"
 msgstr "Bitte geben Sie die URIs ein"
 
-msgid "Parameters to be used for the certificate request:\n"
-msgstr "Parameter die für die Zertifikatsanforderung benutzt werden sollen:\n"
+msgid "Create self-signed certificate? (y/N) "
+msgstr "Ein eigenbeglaubigtes Zertifikat erzeugen? (j/N) "
 
-msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr ""
-"Die Zertifikatsanforderung wird erzeugt.  Dies kann einen Moment dauern ...\n"
+msgid "These parameters are used:\n"
+msgstr "Verwendete Parameter:\n"
+
+msgid "Now creating self-signed certificate.  "
+msgstr "Das eigenbeglaubigte Zertifikat wird erzeugt.  "
+
+msgid "Now creating certificate request.  "
+msgstr "Die Zertifikatsanforderung wird erzeugt.  "
+
+msgid "This may take a while ...\n"
+msgstr "Dies kann einen Moment dauern ...\n"
+
+msgid "Ready.\n"
+msgstr "Fertig.\n"
 
 msgid "Ready.  You should now send this request to your CA.\n"
 msgstr "Fertig.  Sie sollten nun diese Anforderung an die CA senden.\n"
@@ -6207,7 +6105,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(dies ist wahrscheinlich keine verschlüsselte Nachricht)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "Zertifikat `%s' nicht gefunden: %s\n"
 
 #, c-format
@@ -6215,11 +6113,11 @@ msgid "error locking keybox: %s\n"
 msgstr "Fehler beim Sperren der Keybox: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Doppeltes Zertifikat `%s' gelöscht\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "Zertifikat `%s' gelöscht\n"
 
 #, c-format
@@ -6262,9 +6160,6 @@ msgstr "Eingabedaten sind im Basis-64 Format"
 msgid "assume input is in binary format"
 msgstr "Eingabedaten sind im Binärformat"
 
-msgid "use system's dirmngr if available"
-msgstr "Benutze den System Dirmngr falls verfügbar"
-
 msgid "never consult a CRL"
 msgstr "Niemals eine CRL konsultieren"
 
@@ -6316,26 +6211,23 @@ msgstr "|NAME|Verschlüsselungsverfahren NAME benutzen"
 msgid "|NAME|use message digest algorithm NAME"
 msgstr "|NAME|Hashverfahren NAME benutzen"
 
-msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Aufruf: gpgsm [Optionen] [Dateien] (-h für Hilfe)"
+msgid "Usage: @GPGSM@ [options] [files] (-h for help)"
+msgstr "Aufruf: @GPGSM@ [Optionen] [Dateien] (-h für Hilfe)"
 
 msgid ""
-"Syntax: gpgsm [options] [files]\n"
+"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 ""
-"Syntax: gpgsm [Optionen] [Dateien]\n"
+"Syntax: @GPGSM@ [Optionen] [Dateien]\n"
 "Signieren, prüfen, ver- und entschlüsseln mittels S/MIME Protokoll\n"
 
-msgid "usage: gpgsm [options] "
-msgstr "Aufruf: gpgsm [Optionen] "
-
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "Note: won't be able to encrypt to '%s': %s\n"
 msgstr "Hinweis: Verschlüsselung für `%s' wird nicht möglich sein: %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "Unbekanntes Gültigkeitsmodell '%s'\n"
 
 #, c-format
@@ -6353,15 +6245,12 @@ msgstr "%s:%u: Zeile wird übersprungen\n"
 msgid "could not parse keyserver\n"
 msgstr "Schlüsselserver-URL konnte nicht analysiert werden\n"
 
-msgid "WARNING: running with faked system time: "
-msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: "
-
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "Importiere allgemeine Zertifikate: %s\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "Signieren mit `%s' nicht möglich: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6389,14 +6278,6 @@ msgstr "Fehler beim Importieren des Zertifikats: %s\n"
 msgid "error reading input: %s\n"
 msgstr "Fehler beim Lesen der Eingabe: %s\n"
 
-#, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "Die \"Keybox\" `%s' konnte nicht erstellt werden: %s\n"
-
-#, c-format
-msgid "keybox `%s' created\n"
-msgstr "Die \"Keybox\" `%s' wurde erstellt\n"
-
 msgid "failed to get the fingerprint\n"
 msgstr "Kann den Fingerprint nicht ermitteln\n"
 
@@ -6429,11 +6310,11 @@ msgstr ""
 "wird deshalb verwendet\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "Der Fingerabdruck in `%s', Zeile %d is fehlerhaft formatiert\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr "Ungültiger Landescode in `%s', Zeile %d\n"
 
 #, c-format
@@ -6509,17 +6390,1249 @@ msgstr "                alias"
 msgid "This is a qualified signature\n"
 msgstr "Dies ist eine qualifizierte Signatur.\n"
 
-msgid "quiet"
-msgstr "Reduzierte Informationen"
-
-msgid "print data out hex encoded"
-msgstr "Druckdaten hexkodiert ausgeben"
+#, c-format
+msgid "can't initialize certificate cache lock: %s\n"
+msgstr ""
+"Sperre für den Zertifikatzwischenspeicher kann nicht initialisiert werden: "
+"%s\n"
 
-msgid "decode received data lines"
-msgstr "Dekodiere empfangene Datenzeilen"
+#, c-format
+msgid "can't acquire read lock on the certificate cache: %s\n"
+msgstr ""
+"Lesesperre für den Zertifikatzwischenspeicher kann nicht gesetzt werden: %s\n"
 
-msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NAME|Verbinde mit dem Assuan-Socket NAME"
+#, c-format
+msgid "can't acquire write lock on the certificate cache: %s\n"
+msgstr ""
+"Schreibsperre für den Zertifikatzwischenspeicher kann nicht gesetzt werden: "
+"%s\n"
+
+#, c-format
+msgid "can't release lock on the certificate cache: %s\n"
+msgstr ""
+"Sperre für den Zertifikatzwischenspeicher kann nicht freigegeben werden: %s\n"
+
+#, c-format
+msgid "dropping %u certificates from the cache\n"
+msgstr "%u Zertifikate werden aus dem Zertifikatzwischenspeicher entfernt\n"
+
+#, c-format
+msgid "can't access directory '%s': %s\n"
+msgstr "Fehler beim Zugriff auf das Verzeichnis `%s': %s\n"
+
+#, c-format
+msgid "can't parse certificate '%s': %s\n"
+msgstr "Zertifikat `%s' kann nicht zerlegt werden: %s\n"
+
+#, c-format
+msgid "certificate '%s' already cached\n"
+msgstr "Zertifikat `%s' ist bereits im Zwischenspeicher\n"
+
+#, c-format
+msgid "trusted certificate '%s' loaded\n"
+msgstr "Vertrauenswürdiges Zertifikat `%s' wurde geladen\n"
+
+#, c-format
+msgid "certificate '%s' loaded\n"
+msgstr "Zertifikat `%s' wurde geladen\n"
+
+#, c-format
+msgid "  SHA1 fingerprint = %s\n"
+msgstr "  SHA1 Fingerabdruck=%s\n"
+
+msgid "   issuer ="
+msgstr "   Issuer ="
+
+msgid "  subject ="
+msgstr "  Subjekt ="
+
+#, c-format
+msgid "error loading certificate '%s': %s\n"
+msgstr "Fehler beim Laden des Zertifikats `%s': %s\n"
+
+#, c-format
+msgid "permanently loaded certificates: %u\n"
+msgstr "   dauerhaft geladene Zertifikate: %u\n"
+
+#, c-format
+msgid "    runtime cached certificates: %u\n"
+msgstr "zur Laufzeit zwischengespeicherte Zertifikate: %u\n"
+
+msgid "certificate already cached\n"
+msgstr "Zertifikat ist bereits im Zwischenspeicher\n"
+
+msgid "certificate cached\n"
+msgstr "Zertifikat wurde zwischengespeichert\n"
+
+#, c-format
+msgid "error caching certificate: %s\n"
+msgstr "Fehler beim Zwischenspeichern des Zertifikats: %s\n"
+
+#, c-format
+msgid "invalid SHA1 fingerprint string '%s'\n"
+msgstr "ungültiger SHA1 Fingerabdruck `%s'\n"
+
+#, c-format
+msgid "error fetching certificate by S/N: %s\n"
+msgstr "Fehler beim Holen des Zertifikats mittels Seriennummer: %s\n"
+
+#, c-format
+msgid "error fetching certificate by subject: %s\n"
+msgstr "Fehler beim Holen des Zertifikats mittels Subject: %s\n"
+
+msgid "no issuer found in certificate\n"
+msgstr "Im Zertifikat ist kein Herausgeber enthalten\n"
+
+#, c-format
+msgid "error getting authorityKeyIdentifier: %s\n"
+msgstr "Fehler beim Holen des \"authorityKeyIdentifier\": %s\n"
+
+#, c-format
+msgid "creating directory '%s'\n"
+msgstr "Das Verzeichnis `%s' wird erzeugt\n"
+
+#, c-format
+msgid "error creating directory '%s': %s\n"
+msgstr "Fehler beim Erzeugen des Verzeichnis '%s': %s\n"
+
+#, c-format
+msgid "ignoring database dir '%s'\n"
+msgstr "Das DB-Verzeichnis `%s' wird ignoriert\n"
+
+#, c-format
+msgid "error reading directory '%s': %s\n"
+msgstr "Fehler beim Lesen des Verzeichnis `%s': %s\n"
+
+#, c-format
+msgid "removing cache file '%s'\n"
+msgstr "Die Zwischenspeicherdatei `%s' wird entfernt\n"
+
+#, c-format
+msgid "not removing file '%s'\n"
+msgstr "Die Datei `%s' wird nicht gelöscht\n"
+
+#, c-format
+msgid "error closing cache file: %s\n"
+msgstr "Fehler beim Schließen der Zwischenspeicherdatei: %s\n"
+
+#, c-format
+msgid "failed to open cache dir file '%s': %s\n"
+msgstr ""
+"Die Zwischenspeicherverzeichnisdatei `%s' konnte nicht geöffnet werden: %s\n"
+
+#, c-format
+msgid "error creating new cache dir file '%s': %s\n"
+msgstr ""
+"Fehler beim Erzeugen der neuen Zwischenspeicherverzeichnisdatei `%s': %s\n"
+
+#, c-format
+msgid "error writing new cache dir file '%s': %s\n"
+msgstr ""
+"Fehler beim Schreiben der neuen Zwischenspeicherverzeichnisdatei `%s': %s\n"
+
+#, c-format
+msgid "error closing new cache dir file '%s': %s\n"
+msgstr ""
+"Fehler beim Schließen der neuen Zwischenspeicherverzeichnisdatei `%s': %s\n"
+
+#, c-format
+msgid "new cache dir file '%s' created\n"
+msgstr "Neue Zwischenspeicherverzeichnisdatei `%s' wurde erzeugt\n"
+
+#, c-format
+msgid "failed to re-open cache dir file '%s': %s\n"
+msgstr ""
+"Fehler beim Wiederöffnen der Zwischenspeicherverzeichnisdatei `%s': %s\n"
+
+#, c-format
+msgid "first record of '%s' is not the version\n"
+msgstr "Der erste Datensatz von `%s' enthält nicht die Version\n"
+
+msgid "old version of cache directory - cleaning up\n"
+msgstr "Alte Version des Zwischenspeicherverzeichnisses - räume auf\n"
+
+msgid "old version of cache directory - giving up\n"
+msgstr "Alte Version des Zwischenspeicherverzeichnisses - gebe auf\n"
+
+#, c-format
+msgid "extra field detected in crl record of '%s' line %u\n"
+msgstr "Weiteres Feld im CRL Datensatz von `%s', Zeile %u festgestellt\n"
+
+#, c-format
+msgid "invalid line detected in '%s' line %u\n"
+msgstr "Ungültige Zeile in `%s', Zeile %u\n"
+
+#, c-format
+msgid "duplicate entry detected in '%s' line %u\n"
+msgstr "Doppelter Eintrag in `%s', Zeile %u festgestellt\n"
+
+#, c-format
+msgid "unsupported record type in '%s' line %u skipped\n"
+msgstr "Nicht unterstützter Datensatztyp in `%s', Zeile %u übergangen\n"
+
+#, c-format
+msgid "invalid issuer hash in '%s' line %u\n"
+msgstr "Ungültiger Issuer Hashwert in `%s', Zeile %u\n"
+
+#, c-format
+msgid "no issuer DN in '%s' line %u\n"
+msgstr "Kein Issuer DN in `%s', Zeile %u\n"
+
+#, c-format
+msgid "invalid timestamp in '%s' line %u\n"
+msgstr "Ungültiger Zeitstempel in `%s', Zeile %u\n"
+
+#, c-format
+msgid "WARNING: invalid cache file hash in '%s' line %u\n"
+msgstr "WARNUNG: Ungültiger Zwischenspeicherdatei Hashwert in `%s', Zeile %u\n"
+
+msgid "detected errors in cache dir file\n"
+msgstr "Id der Zwischenspeicherverzeichnisdatei wurden Fehler erkannt\n"
+
+msgid "please check the reason and manually delete that file\n"
+msgstr ""
+"Bitte ermitteln sie die Ursache und löschen sie die Datei dann manuell\n"
+
+#, c-format
+msgid "failed to create temporary cache dir file '%s': %s\n"
+msgstr ""
+"Die temporäre Zwischenspeicherverzeichnisdatei `%s' konnte nicht erzeugt "
+"werden: %s\n"
+
+#, c-format
+msgid "error closing '%s': %s\n"
+msgstr "Fehler beim Schließen von `%s': %s\n"
+
+#, c-format
+msgid "error renaming '%s' to '%s': %s\n"
+msgstr "Fehler beim Umbenennen von `%s` nach `%s': %s\n"
+
+#, c-format
+msgid "can't hash '%s': %s\n"
+msgstr "Hashwert von `%s' kann nicht gebildet werden: %s\n"
+
+#, c-format
+msgid "error setting up MD5 hash context: %s\n"
+msgstr "Fehler beim Vorbereiten des MD5 Hashkontext: %s\n"
+
+#, c-format
+msgid "error hashing '%s': %s\n"
+msgstr "Fehler beim Hashen von `%s': %s\n"
+
+#, c-format
+msgid "invalid formatted checksum for '%s'\n"
+msgstr "Ungültig formatierte Prüfsumme für `%s'\n"
+
+msgid "too many open cache files; can't open anymore\n"
+msgstr ""
+"Zu viele geöffnete Zwischenspeicherdateien; weitere kann nicht geöffnet "
+"werden\n"
+
+#, c-format
+msgid "opening cache file '%s'\n"
+msgstr "Die Zwischenspeicherdatei `%s' wird geöffnet\n"
+
+#, c-format
+msgid "error opening cache file '%s': %s\n"
+msgstr "Fehler beim Öffnen der Zwischenspeicherdatei `%s': %s\n"
+
+#, c-format
+msgid "error initializing cache file '%s' for reading: %s\n"
+msgstr ""
+"Fehler beim Initialisieren der Zwischenspeicherdatei `%s' zum Lesen: %s\n"
+
+msgid "calling unlock_db_file on a closed file\n"
+msgstr "unlock_db_file wird für eine geschlossene Datei aufgerufen\n"
+
+msgid "calling unlock_db_file on an unlocked file\n"
+msgstr "unlock_db_file wird für eine nicht gesperrte Datei aufgerufen\n"
+
+#, c-format
+msgid "failed to create a new cache object: %s\n"
+msgstr "Ein neues Zwischenspeicherobjekt konnte nicht erzeugt werden: %s\n"
+
+#, c-format
+msgid "no CRL available for issuer id %s\n"
+msgstr "Es ist keine CRL für den Issuer mit der ID %s vorhanden\n"
+
+#, c-format
+msgid "cached CRL for issuer id %s too old; update required\n"
+msgstr ""
+"Die zwischengespeicherte CRL für den Issuer mit der ID %s ist zu alt; ein "
+"Update wird benötigt\n"
+
+#, c-format
+msgid ""
+"force-crl-refresh active and %d minutes passed for issuer id %s; update "
+"required\n"
+msgstr ""
+"\"force-crl-refresh\" ist aktiviert und %d Minuten für den Issuer mit Id %s "
+"sind vorbei; Update wird benötigt\n"
+
+#, c-format
+msgid "force-crl-refresh active for issuer id %s; update required\n"
+msgstr ""
+"\"force-crl-refresh\" ist für den Issuer mit der Id %s aktiviert; Update "
+"wird benötigt\n"
+
+#, c-format
+msgid "available CRL for issuer ID %s can't be used\n"
+msgstr ""
+"Die vorhandene CRL für den Issuer mit der ID %s kann nicht benutzt werden\n"
+
+#, c-format
+msgid "cached CRL for issuer id %s tampered; we need to update\n"
+msgstr ""
+"Die zwischengespeicherte CRL für den Issuer mit der ID %s wurde verändert; "
+"eine Update wird benötigt\n"
+
+msgid "WARNING: invalid cache record length for S/N "
+msgstr "WARNUNG: Ungültige Länge des Zwischenspeicherdateisatzes für S/N "
+
+#, c-format
+msgid "problem reading cache record for S/N %s: %s\n"
+msgstr "Problem beim Lesen des Zwischenspeicherdatensatzes für S/N %s: %s\n"
+
+#, c-format
+msgid "S/N %s is not valid; reason=%02X  date=%.15s\n"
+msgstr "S/N %s ist nicht gültig; Grund=%02X  Datum=%.15s\n"
+
+#, c-format
+msgid "S/N %s is valid, it is not listed in the CRL\n"
+msgstr "S/N %s ist gültig; sie ist nicht in der CRL enthalten\n"
+
+#, c-format
+msgid "error getting data from cache file: %s\n"
+msgstr "Fehler beim Holen der Daten aus der Zwischenspeicherdatei: %s\n"
+
+#, c-format
+msgid "unknown hash algorithm '%s'\n"
+msgstr "Ungültige Hashmethode `%s'\n"
+
+#, c-format
+msgid "gcry_md_open for algorithm %d failed: %s\n"
+msgstr "gcry_md_open für Methode %d fehlgeschlagen: %s\n"
+
+msgid "got an invalid S-expression from libksba\n"
+msgstr "Ungültige S-Expression von Libksba erhalten\n"
+
+#, c-format
+msgid "converting S-expression failed: %s\n"
+msgstr "Konvertierung der S-Expression fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "creating S-expression failed: %s\n"
+msgstr "Erzeugen der S-Expression fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "ksba_crl_parse failed: %s\n"
+msgstr "ksba_crl_parse fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "error getting update times of CRL: %s\n"
+msgstr "Die \"Update Times\" konnte nicht aus der CRL bestimmt werden: %s\n"
+
+#, c-format
+msgid "update times of this CRL: this=%s next=%s\n"
+msgstr "Die \"Update Times\" dieser CRL sind: this=%s next=%s\n"
+
+msgid "nextUpdate not given; assuming a validity period of one day\n"
+msgstr "\"nextUpdate\" fehlt; wir nehmen eine Gültigkeit von einem Tag an\n"
+
+#, c-format
+msgid "error getting CRL item: %s\n"
+msgstr "Fehler beim Holen eines CRL Items: %s\n"
+
+#, c-format
+msgid "error inserting item into temporary cache file: %s\n"
+msgstr ""
+"Fehler beim Einfügen eines Items in die temporäre Zwischenspeicherdatei: %s\n"
+
+#, c-format
+msgid "no CRL issuer found in CRL: %s\n"
+msgstr "In der CRL wurde kein CRL Herausgeber gefunden: %s\n"
+
+msgid "locating CRL issuer certificate by authorityKeyIdentifier\n"
+msgstr ""
+"CRL Herausgeberzertifikat wird über \"authorityKeyIdentifier\" geholt\n"
+
+#, c-format
+msgid "CRL signature verification failed: %s\n"
+msgstr "Signaturprüfung der CRL ist fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "error checking validity of CRL issuer certificate: %s\n"
+msgstr "Fehler beim Püfen des CRL Herausgeberzertifikats: %s\n"
+
+#, c-format
+msgid "ksba_crl_new failed: %s\n"
+msgstr "ksba_crl_new fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "ksba_crl_set_reader failed: %s\n"
+msgstr "ksba_crl_set_reader fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "removed stale temporary cache file '%s'\n"
+msgstr "Die alte temporäre Zwischenspeicherdatei `%s' wurde entfernt\n"
+
+#, c-format
+msgid "problem removing stale temporary cache file '%s': %s\n"
+msgstr ""
+"Problem beim Löschen der alten temporären Zwischenspeicherdatei `%s': %s\n"
+
+#, c-format
+msgid "error creating temporary cache file '%s': %s\n"
+msgstr "Fehler beim Erzeugen der temporären Zwischenspeicherdatei `%s': %s\n"
+
+#, c-format
+msgid "crl_parse_insert failed: %s\n"
+msgstr "crl_parse_insert fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "error finishing temporary cache file '%s': %s\n"
+msgstr ""
+"Fehler beim Fertigstellen der temporären Zwischenspeicherdatei `%s': %s\n"
+
+#, c-format
+msgid "error closing temporary cache file '%s': %s\n"
+msgstr "Fehler beim Schließen der temporären Zwischenspeicherdatei `%s': %s\n"
+
+#, c-format
+msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n"
+msgstr ""
+"WARNUNG: Neue CRL ist immer noch zu alt; sie verfiel am %s - wird trotzdem "
+"geladen\n"
+
+#, c-format
+msgid "new CRL still too old; it expired on %s\n"
+msgstr "Neue CRL ist immer noch zu alt; sie verviel am %s\n"
+
+#, c-format
+msgid "unknown critical CRL extension %s\n"
+msgstr "Unbekannte kritische CRL Erweiterung %s\n"
+
+#, c-format
+msgid "error reading CRL extensions: %s\n"
+msgstr "Fehler beim Lesen einer CRL Erweiterung: %s\n"
+
+#, c-format
+msgid "creating cache file '%s'\n"
+msgstr "Zwischenspeicherdatei `%s' wird erzeugt\n"
+
+#, c-format
+msgid "problem renaming '%s' to '%s': %s\n"
+msgstr "Problem beim Umbenennen von `%s' nach `%s': %s\n"
+
+msgid ""
+"updating the DIR file failed - cache entry will get lost with the next "
+"program start\n"
+msgstr ""
+"Update der Zwischenspeicherverzeichnisdatei fehlgeschlagen - "
+"Zwischenspeichereintrag wird mit dem nächste Programmstart verloren gehen\n"
+
+#, c-format
+msgid "Begin CRL dump (retrieved via %s)\n"
+msgstr "Anfang CRL Ausgabe (geholt via %s)\n"
+
+msgid ""
+" ERROR: The CRL will not be used because it was still too old after an "
+"update!\n"
+msgstr ""
+" FEHLER: Die CRL wird nicht benutzt, da sie trotz eines Updates zu alt war!\n"
+
+msgid ""
+" ERROR: The CRL will not be used due to an unknown critical extension!\n"
+msgstr ""
+" FEHLER: Die CRL wird nicht benutzt, da sie eine unbekannte kritische CRL "
+"Erweiterung trägt!\n"
+
+msgid " ERROR: The CRL will not be used\n"
+msgstr " FEHLER: Die CRL wird nicht benutzt\n"
+
+msgid " ERROR: This cached CRL may have been tampered with!\n"
+msgstr ""
+" FEHLER: Diese zwischengespeicherte CRL ist möglicherweise abgeändert "
+"worden!\n"
+
+msgid " WARNING: invalid cache record length\n"
+msgstr " WARNUNG: Ungültige Länge eines Zwischenspeicherdatensatzes\n"
+
+#, c-format
+msgid "problem reading cache record: %s\n"
+msgstr "Problem beim Lesen eines Zwischenspeicherdatensatzes: %s\n"
+
+#, c-format
+msgid "problem reading cache key: %s\n"
+msgstr "Problem beim Lesen eines Zwischenspeicherschlüssels: %s\n"
+
+#, c-format
+msgid "error reading cache entry from db: %s\n"
+msgstr "Fehler beim Lesen eine Zwischenspeichereintrags aus der DB: %s\n"
+
+msgid "End CRL dump\n"
+msgstr "Ende CRL Ausgabe\n"
+
+#, c-format
+msgid "crl_fetch via DP failed: %s\n"
+msgstr "crl_fetch über den DP fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "crl_cache_insert via DP failed: %s\n"
+msgstr "crl_cache_insert über den DP fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "crl_cache_insert via issuer failed: %s\n"
+msgstr "crl_cache_insert über den Issuer fehlgeschlagen: %s\n"
+
+msgid "reader to file mapping table full - waiting\n"
+msgstr "\"reader to file\" Zuordnungstabelle ist voll - warte\n"
+
+msgid "using \"http\" instead of \"https\"\n"
+msgstr "Es wird \"HTTP\" anstatt \"HTTPS\" verwendet\n"
+
+#, c-format
+msgid "CRL access not possible due to disabled %s\n"
+msgstr "CRL Zugriff nicht möglich da %s abgeschaltet ist\n"
+
+#, c-format
+msgid "error initializing reader object: %s\n"
+msgstr "Fehler beim Initialisieren des \"reader\" Objekts: %s\n"
+
+#, c-format
+msgid "URL '%s' redirected to '%s' (%u)\n"
+msgstr "URL `%s' nach `%s' umgeleitet (%u)\n"
+
+msgid "too many redirections\n"
+msgstr "zu viele verschachtelte Umleitungen\n"
+
+#, c-format
+msgid "error retrieving '%s': %s\n"
+msgstr "Fehler beim Holen von `%s': %s\n"
+
+#, c-format
+msgid "error retrieving '%s': http status %u\n"
+msgstr "Fehler beim Holen von `%s': HTTP Status %u\n"
+
+#, c-format
+msgid "certificate search not possible due to disabled %s\n"
+msgstr "Zertifikatsuche ist nicht möglich da %s abgeschaltet ist\n"
+
+msgid "use OCSP instead of CRLs"
+msgstr "OCSP anstatt CRL benutzen"
+
+msgid "check whether a dirmngr is running"
+msgstr "Teste ob der dirmngr noch läuft"
+
+msgid "add a certificate to the cache"
+msgstr "Ein Zertifikat dem Zwischenspeicher zufügen"
+
+msgid "validate a certificate"
+msgstr "Zertifikat prüfen"
+
+msgid "lookup a certificate"
+msgstr "Zertifikat auffinden"
+
+msgid "lookup only locally stored certificates"
+msgstr "Nur lokal gespeicherte Zertifikate auffinden"
+
+msgid "expect an URL for --lookup"
+msgstr "Eine URL wird für --lookup erwartet"
+
+msgid "load a CRL into the dirmngr"
+msgstr "CRL in den Dirmngr laden"
+
+msgid "special mode for use by Squid"
+msgstr "Sondermodus für Squid"
+
+msgid "expect certificates in PEM format"
+msgstr "Zertifikate werden im PEM Format erwartet"
+
+msgid "force the use of the default OCSP responder"
+msgstr "Die Nutzung des voreingestellten OCSP Responder erzwingen"
+
+msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n"
+msgstr ""
+"Gebrauch: dirmngr-client [Optionen] [Zertdatei|Muster] (-h für Hilfe)\n"
+
+msgid ""
+"Syntax: dirmngr-client [options] [certfile|pattern]\n"
+"Test an X.509 certificate against a CRL or do an OCSP check\n"
+"The process returns 0 if the certificate is valid, 1 if it is\n"
+"not valid and other error codes for general failures\n"
+msgstr ""
+"Gebrauch: dirmngr-client [Optionen]  [Zertdatei|Muster]\n"
+"Teste ein X.509 Zertifikat gegen eine CRL oder führe eine OCSP Prüfung "
+"durch\n"
+"The Prozess gibt 0 zurück wenn das Zertifikat gültig ist, 1 wenn es nicht\n"
+"gültig ist und weitere Werte bei anderen Fehlern.\n"
+
+#, c-format
+msgid "error reading certificate from stdin: %s\n"
+msgstr "Fehler beim Lesen des Zertifikats von der Standardeingabe: %s\n"
+
+#, c-format
+msgid "error reading certificate from '%s': %s\n"
+msgstr "Fehler beim Lesen des Zertifikats von `%s': %s\n"
+
+msgid "certificate too large to make any sense\n"
+msgstr "Zertifikat ist zu groß um Sinnvoll zu sein\n"
+
+#, c-format
+msgid "lookup failed: %s\n"
+msgstr "Aufsuchen fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "loading CRL '%s' failed: %s\n"
+msgstr "Laden der CRL von `%s' fehlgeschlagen: %s\n"
+
+msgid "a dirmngr daemon is up and running\n"
+msgstr "Ein dirmngr ist vorhanden und aktiv\n"
+
+#, c-format
+msgid "validation of certificate failed: %s\n"
+msgstr "Prüfung des Zertifikats fehlgeschlagen: %s\n"
+
+msgid "certificate is valid\n"
+msgstr "Zertifikat ist gültig\n"
+
+msgid "certificate has been revoked\n"
+msgstr "Zertifikat wurde widerrufen\n"
+
+#, c-format
+msgid "certificate check failed: %s\n"
+msgstr "Zertifikatprüfung fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "got status: '%s'\n"
+msgstr "Erhielt Status: `%s'\n"
+
+#, c-format
+msgid "error writing base64 encoding: %s\n"
+msgstr "Fehler beim Schreiben der Base-64 Darstellung: %s\n"
+
+#, c-format
+msgid "failed to allocate assuan context: %s\n"
+msgstr "Fehler beim Bereitstellen eines Assuan Kontext: %s\n"
+
+msgid "apparently no running dirmngr\n"
+msgstr "Offensichtlich ist kein Dirmngr vorhanden\n"
+
+msgid "no running dirmngr - starting one\n"
+msgstr "Dirmngr läuft nicht - ein neuer wird gestartet\n"
+
+#, c-format
+msgid "malformed %s environment variable\n"
+msgstr "Fehlerhafte %s Variable\n"
+
+#, c-format
+msgid "dirmngr protocol version %d is not supported\n"
+msgstr "Dirmngr Protocol Version %d wird nicht unterstützt\n"
+
+msgid "can't connect to the dirmngr - trying fall back\n"
+msgstr "Verbindung zum Dirmngr nicht möglich - Rückfallmethode wird versucht\n"
+
+#, c-format
+msgid "can't connect to the dirmngr: %s\n"
+msgstr "Verbindung zum Dirmngr nicht möglich: %s\n"
+
+#, c-format
+msgid "unsupported inquiry '%s'\n"
+msgstr "Nicht unterstützte INQUIRY `%s'\n"
+
+msgid "absolute file name expected\n"
+msgstr "Absoluter Dateiname erwartet\n"
+
+#, c-format
+msgid "looking up '%s'\n"
+msgstr "Auffinden von `%s'\n"
+
+msgid "run as windows service (background)"
+msgstr "Als Windows-Service ausführen (Hintergrund)"
+
+msgid "list the contents of the CRL cache"
+msgstr "Den Inhalt des CRL Zwischenspeichers anzeigen"
+
+msgid "|FILE|load CRL from FILE into cache"
+msgstr "|DATEI|Lade die CRL aus der DATEI in den Zwischenspeicher"
+
+msgid "|URL|fetch a CRL from URL"
+msgstr "|URL|Hole eine CRL von dieser URL"
+
+msgid "shutdown the dirmngr"
+msgstr "Den Dirmngr herunterfahren"
+
+msgid "flush the cache"
+msgstr "Den Zwischenspeicher löschen"
+
+msgid "|FILE|write server mode logs to FILE"
+msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI"
+
+msgid "run without asking a user"
+msgstr "Ausführung ohne Benutzernachfrage"
+
+msgid "force loading of outdated CRLs"
+msgstr "Laden von abgelaufenen CRLs erzwingen"
+
+msgid "allow sending OCSP requests"
+msgstr "OCSP Anfragen erlauben"
+
+msgid "inhibit the use of HTTP"
+msgstr "Sperre die Benutzung von HTTP"
+
+msgid "inhibit the use of LDAP"
+msgstr "Sperre die Benutzung von LDAP"
+
+msgid "ignore HTTP CRL distribution points"
+msgstr "Übergehe HTTP CRL Distribution Points"
+
+msgid "ignore LDAP CRL distribution points"
+msgstr "Übergehe LDAP CRL Distribution Points"
+
+msgid "ignore certificate contained OCSP service URLs"
+msgstr "Übergehe im Zertifikat enthaltene OCSP Service URLs"
+
+msgid "|URL|redirect all HTTP requests to URL"
+msgstr "|URL|Leite alle HTTP Anfragen über URL"
+
+msgid "|HOST|use HOST for LDAP queries"
+msgstr "|HOST|Benutze HOST für LDAP Anfragen"
+
+msgid "do not use fallback hosts with --ldap-proxy"
+msgstr "Keine Benutzung der Rückgriffshosts mit --ldap-proxy"
+
+msgid "|FILE|read LDAP server list from FILE"
+msgstr "|DATEI|Lese die LDAP Serverliste aus DATEI"
+
+msgid "add new servers discovered in CRL distribution points to serverlist"
+msgstr "Füge neue Server aus den CRL Distribution Points der Serverliste hinzu"
+
+msgid "|N|set LDAP timeout to N seconds"
+msgstr "|N|Setze das LDAP Timeout auf N Sekunden"
+
+msgid "|URL|use OCSP responder at URL"
+msgstr "|URL|Benutze den OCSP Responder mit dieser URL"
+
+msgid "|FPR|OCSP response signed by FPR"
+msgstr "|FPR|OCSP Antwort ist durch FPR signiert"
+
+msgid "|N|do not return more than N items in one query"
+msgstr "|N|Nicht mehr als N Angaben in einer Anfrage zurückgeben"
+
+msgid "|FILE|use the CA certificates in FILE for HKP over TLS"
+msgstr "|DATEI|Benutze die CA Zertifikate in DATEI für HKP über TLS"
+
+msgid ""
+"@\n"
+"(See the \"info\" manual for a complete listing of all commands and "
+"options)\n"
+msgstr ""
+"@\n"
+"(Im \"info\"-Handbuch findet sich eine vollständige Liste aller Kommandos "
+"und Optionen)\n"
+
+msgid "Usage: @DIRMNGR@ [options] (-h for help)"
+msgstr "Gebrauch: @DIRMNGR@ [Optionen]"
+
+msgid ""
+"Syntax: @DIRMNGR@ [options] [command [args]]\n"
+"Keyserver, CRL, and OCSP access for @GNUPG@\n"
+msgstr ""
+"Syntax: @DIRMNGR@ [Optionen] [Kommando [Argumente]]\n"
+"Keyserver, CRL und OCSP Zugriff für @GNUPG@\n"
+
+#, c-format
+msgid "valid debug levels are: %s\n"
+msgstr "Gültige Debugebenen sind: %s\n"
+
+#, c-format
+msgid "usage: %s [options] "
+msgstr "Aufruf: %s [Optionen] "
+
+msgid "colons are not allowed in the socket name\n"
+msgstr "Doppelpunkte sind im Namen des Sockets nicht erlaubt\n"
+
+#, c-format
+msgid "fetching CRL from '%s' failed: %s\n"
+msgstr "Holen der CRL von `%s' fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "processing CRL from '%s' failed: %s\n"
+msgstr "Verarbeitung der CRL von `%s' fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "%s:%u: line too long - skipped\n"
+msgstr "%s:%u: Zeile ist zu lang - übergangen\n"
+
+#, c-format
+msgid "%s:%u: invalid fingerprint detected\n"
+msgstr "%s:%u: ungültiger Fingerabdruck erkannt\n"
+
+#, c-format
+msgid "%s:%u: read error: %s\n"
+msgstr "%s:%u: Lesefehler: %s\n"
+
+#, c-format
+msgid "%s:%u: garbage at end of line ignored\n"
+msgstr "%s:%u: Müll am Ende der Zeile wird ignoriert\n"
+
+msgid "SIGHUP received - re-reading configuration and flushing caches\n"
+msgstr ""
+"SIGHUP empfangen - lese die Konfiguration erneut und lösche die "
+"Zwischenspeicher\n"
+
+msgid "SIGUSR2 received - no action defined\n"
+msgstr "SIGUSR2 empfangen - keine Aktion definiert\n"
+
+msgid "SIGTERM received - shutting down ...\n"
+msgstr "SIGTERM empfangen - wird heruntergefahren ...\n"
+
+#, c-format
+msgid "SIGTERM received - still %d active connections\n"
+msgstr "SIGTERM empfangen - immer noch %d Verbindungen aktiv\n"
+
+msgid "shutdown forced\n"
+msgstr "Herunterfahren wurde erzwungen\n"
+
+msgid "SIGINT received - immediate shutdown\n"
+msgstr "SIGINT empfangen - wird sofort heruntergefahren\n"
+
+#, c-format
+msgid "signal %d received - no action defined\n"
+msgstr "Signal %d empfangen - keine Aktion definiert\n"
+
+msgid "return all values in a record oriented format"
+msgstr "Alle Werte in einem Record Format zurückgeben"
+
+msgid "|NAME|ignore host part and connect through NAME"
+msgstr "|NAME|Host Teil ignorieren und über NAME verbinden"
+
+msgid "|NAME|connect to host NAME"
+msgstr "|NAME|Verbinde mit dem Host NAME"
+
+msgid "|N|connect to port N"
+msgstr "|N|Verbinde mit dem Port N"
+
+msgid "|NAME|use user NAME for authentication"
+msgstr "|NAME|Benutze NAME zur Authentifizierung"
+
+msgid "|PASS|use password PASS for authentication"
+msgstr "Benutze Passwort PASS zur Authentifizierung"
+
+msgid "take password from $DIRMNGR_LDAP_PASS"
+msgstr "Nimm das Passwort von $DIRMNGR_LDAP_PASS"
+
+msgid "|STRING|query DN STRING"
+msgstr "|STRING|Frage den DN STRING ab"
+
+msgid "|STRING|use STRING as filter expression"
+msgstr "|STRING|Benutze STRING als Filterausdruck"
+
+msgid "|STRING|return the attribute STRING"
+msgstr "|STRING|Gib das Attribut STRING zurück"
+
+msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n"
+msgstr "Gebrauch: dirmngr_ldap [Optionen] [URL] (-h für Hilfe)\n"
+
+msgid ""
+"Syntax: dirmngr_ldap [options] [URL]\n"
+"Internal LDAP helper for Dirmngr\n"
+"Interface and options may change without notice\n"
+msgstr ""
+"Gebrauch: dirmngr_ldap [Optionen] [URL] (-h für Hilfe)\n"
+"Internes LDAP-Hilfsprogramm für Dirmngr.\n"
+"Interface und Optionen können sich mit jedem Release ändern.\n"
+
+#, c-format
+msgid "invalid port number %d\n"
+msgstr "Ungültige Portnummer %d\n"
+
+#, c-format
+msgid "scanning result for attribute '%s'\n"
+msgstr "Absuchen des Ergebnisses nach Attribut `%s'\n"
+
+#, c-format
+msgid "error writing to stdout: %s\n"
+msgstr "Fehler beim Schreiben auf Standardausgabe: %s\n"
+
+#, c-format
+msgid "          available attribute '%s'\n"
+msgstr "        verfügbare Attribute `%s'\n"
+
+#, c-format
+msgid "attribute '%s' not found\n"
+msgstr "Attribut `%s' nicht gefunden\n"
+
+#, c-format
+msgid "found attribute '%s'\n"
+msgstr "Attribut `%s' gefunden\n"
+
+#, c-format
+msgid "processing url '%s'\n"
+msgstr "Verarbeiten der URL `%s'\n"
+
+#, c-format
+msgid "          user '%s'\n"
+msgstr "           Benutzer `%s'\n"
+
+#, c-format
+msgid "          pass '%s'\n"
+msgstr "           Passwort `%s'\n"
+
+#, c-format
+msgid "          host '%s'\n"
+msgstr "               Host `%s'\n"
+
+#, c-format
+msgid "          port %d\n"
+msgstr "               Port %d\n"
+
+#, c-format
+msgid "            DN '%s'\n"
+msgstr "                 DN `%s'\n"
+
+#, c-format
+msgid "        filter '%s'\n"
+msgstr "             Filter `%s'\n"
+
+#, c-format
+msgid "          attr '%s'\n"
+msgstr "           Attribut `%s'\n"
+
+#, c-format
+msgid "no host name in '%s'\n"
+msgstr "Kein Hostname in `%s'\n"
+
+#, c-format
+msgid "no attribute given for query '%s'\n"
+msgstr "Kein Attribut für Abfrage `%s' angegeben\n"
+
+msgid "WARNING: using first attribute only\n"
+msgstr "WARNUNG: Es wird nur das erste Attribut benutzt\n"
+
+#, c-format
+msgid "LDAP init to '%s:%d' failed: %s\n"
+msgstr "LDAP Initialisierung von `%s:%d' fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "binding to '%s:%d' failed: %s\n"
+msgstr "Anbindung an `%s:%d' fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "searching '%s' failed: %s\n"
+msgstr "Suche mit `%s' fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "'%s' is not an LDAP URL\n"
+msgstr "`%s' ist kein LDAP URL\n"
+
+#, c-format
+msgid "'%s' is an invalid LDAP URL\n"
+msgstr "`%s' ist ein ungültiger LDAP URL\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "Fehler beim Allozieren von Speicher: %s\n"
+
+#, c-format
+msgid "error printing log line: %s\n"
+msgstr "Fehler beim Schreiben einer Logzeile: %s\n"
+
+#, c-format
+msgid "error reading log from ldap wrapper %d: %s\n"
+msgstr "Fehler beim Lesen des Logs vom LDAP Wrapper %d: %s\n"
+
+#, c-format
+msgid "npth_select failed: %s - waiting 1s\n"
+msgstr "npth_select()-Aufruf fehlgeschlagen: %s - warte 1s\n"
+
+#, c-format
+msgid "ldap wrapper %d ready"
+msgstr "LDAP Wrapper %d fertig"
+
+#, c-format
+msgid "ldap wrapper %d ready: timeout\n"
+msgstr "LDAP Wrapper %d fertig: Zeitüberschreitung\n"
+
+#, c-format
+msgid "ldap wrapper %d ready: exitcode=%d\n"
+msgstr "LDAP Wrapper %d fertig: Exitcode=%d\n"
+
+#, c-format
+msgid "waiting for ldap wrapper %d failed: %s\n"
+msgstr "Warten auf den LDAP Wrapper %d fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "ldap wrapper %d stalled - killing\n"
+msgstr "LDAP Wrapper %d versackt - abgeschossen\n"
+
+#, c-format
+msgid "error spawning ldap wrapper reaper thread: %s\n"
+msgstr "Fehler beim Starten des LDAP Wrapper Kontrollthreads: %s\n"
+
+#, c-format
+msgid "reading from ldap wrapper %d failed: %s\n"
+msgstr "Lesen vom LDAP Wrapper %d fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "invalid char 0x%02x in host name - not added\n"
+msgstr "Ungültiges Zeichen 0x%02X im Hostnamen - nicht hinzugefügt\n"
+
+#, c-format
+msgid "adding '%s:%d' to the ldap server list\n"
+msgstr "`%s:%d' wird der LDAP Serverliste hinzugefügt\n"
+
+#, c-format
+msgid "malloc failed: %s\n"
+msgstr "malloc() fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "start_cert_fetch: invalid pattern '%s'\n"
+msgstr "start_cert_fetch: Ungültiges Muster `%s'\n"
+
+msgid "ldap_search hit the size limit of the server\n"
+msgstr "ldap_search erreichte die Größengrenze des Servers\n"
+
+msgid "invalid canonical S-expression found\n"
+msgstr "Ungültige kanonische S-Expression gefunden\n"
+
+#, c-format
+msgid "gcry_md_open failed: %s\n"
+msgstr "gcry_md_open fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "oops: ksba_cert_hash failed: %s\n"
+msgstr "Nanu: ksba_cert_hash fehlgeschlagen: %s\n"
+
+msgid "bad URL encoding detected\n"
+msgstr "Fehlerhafte URL Kodierung erkannt\n"
+
+#, c-format
+msgid "error reading from responder: %s\n"
+msgstr "Fehler beim Lesen vom Responder: %s\n"
+
+#, c-format
+msgid "response from server too large; limit is %d bytes\n"
+msgstr "Antwort vom Server zu lang; die Grenze sind %d Bytes\n"
+
+msgid "OCSP request not possible due to disabled HTTP\n"
+msgstr "OCSP Anfrage nicht möglich da HTTP abgeschaltet ist\n"
+
+#, c-format
+msgid "error setting OCSP target: %s\n"
+msgstr "Fehler beim Setzen des OCSP Ziels: %s\n"
+
+#, c-format
+msgid "error building OCSP request: %s\n"
+msgstr "Fehler beim Aufbauen der OCSP Anfrage: %s\n"
+
+#, c-format
+msgid "error connecting to '%s': %s\n"
+msgstr "Fehler beim Verbinden mit '%s': %s\n"
+
+#, c-format
+msgid "error reading HTTP response for '%s': %s\n"
+msgstr "Fehler beim Lesen der HTTP Antwort von `%s': %s\n"
+
+#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "Fehler beim Zugreifen auf `%s': HTTP Status %u\n"
+
+#, c-format
+msgid "error parsing OCSP response for '%s': %s\n"
+msgstr "Fehler beim Zerlegen der OCSP Antwort für `%s': %s\n"
+
+#, c-format
+msgid "OCSP responder at '%s' status: %s\n"
+msgstr "OCSP Responder `%s' Status: %s\n"
+
+#, c-format
+msgid "hashing the OCSP response for '%s' failed: %s\n"
+msgstr "Hashen der OCSP Antwort für `%s' fehlgeschlagen: %s\n"
+
+msgid "not signed by a default OCSP signer's certificate"
+msgstr "Nicht durch voreingestelltes OCSP \"Signer-Zertifikat\" signiert"
+
+msgid "only SHA-1 is supported for OCSP responses\n"
+msgstr "Lediglich SHA-1 wird bei OCSP Antworten unterstützt\n"
+
+#, c-format
+msgid "allocating list item failed: %s\n"
+msgstr "malloc() fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "error getting responder ID: %s\n"
+msgstr "Fehler beim Holen der Responder-ID: %s\n"
+
+msgid "no suitable certificate found to verify the OCSP response\n"
+msgstr ""
+"Kein benutzbares Zertifikat zur Überprüfung der OCSP Antwort gefunden\n"
+
+#, c-format
+msgid "issuer certificate not found: %s\n"
+msgstr "Herausgeberzertifikat nicht gefunden: %s\n"
+
+msgid "caller did not return the target certificate\n"
+msgstr "Aufrufer gab das Ziel Zertifikat nicht zurück\n"
+
+msgid "caller did not return the issuing certificate\n"
+msgstr "Aufrufer gab das Issuer Zertifikat nicht zurück\n"
+
+#, c-format
+msgid "failed to allocate OCSP context: %s\n"
+msgstr "Fehler beim Bereitstellen eines OCSP Kontext: %s\n"
+
+#, c-format
+msgid "can't get authorityInfoAccess: %s\n"
+msgstr "authorityInfoAccess kann nicht geholt werden: %s\n"
+
+msgid "no default OCSP responder defined\n"
+msgstr "Kein  voreingestellter OCSP Responder definiert\n"
+
+msgid "no default OCSP signer defined\n"
+msgstr "Kein voreingestellter OCSP \"Signer\" definiert\n"
+
+#, c-format
+msgid "using default OCSP responder '%s'\n"
+msgstr "Der voreingestellte OCSP Responder `%s' wird benutzt\n"
+
+#, c-format
+msgid "using OCSP responder '%s'\n"
+msgstr "Der OCSP Responder `%s' wird benutzt\n"
+
+#, c-format
+msgid "failed to establish a hashing context for OCSP: %s\n"
+msgstr "Kontext zum Hashen von OCSP kann nicht erzeugt werden: %s\n"
+
+#, c-format
+msgid "error getting OCSP status for target certificate: %s\n"
+msgstr "Fehler beim Holen des OCSP Status für das Zielzertifikat: %s\n"
+
+#, c-format
+msgid "certificate status is: %s  (this=%s  next=%s)\n"
+msgstr "Zertifikatstatus ist: %s  (this=%s  next=%s)\n"
+
+msgid "good"
+msgstr "Gut"
+
+#, c-format
+msgid "certificate has been revoked at: %s due to: %s\n"
+msgstr "Zertifikat wurde widerrufen am: %s wegen: %s\n"
+
+msgid "OCSP responder returned a status in the future\n"
+msgstr "OCSP Responder gab einen Status in der Zukunft zurück\n"
+
+msgid "OCSP responder returned a non-current status\n"
+msgstr "OCSP Responder gab einen nicht aktuellen Status zurück\n"
+
+msgid "OCSP responder returned an too old status\n"
+msgstr "OCSP Responder gab einen zu alten Status zurück\n"
+
+#, c-format
+msgid "assuan_inquire(%s) failed: %s\n"
+msgstr "assuan_inquire(%s) fehlgeschlagen: %s\n"
+
+msgid "ldapserver missing"
+msgstr "LDAP Server fehlt"
+
+msgid "serialno missing in cert ID"
+msgstr "Seriennummer fehlt in der Cert-ID"
+
+#, c-format
+msgid "assuan_inquire failed: %s\n"
+msgstr "assuan_inquire fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "fetch_cert_by_url failed: %s\n"
+msgstr "fetch_cert_by_url() fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "error sending data: %s\n"
+msgstr "Fehler beim Senden der Daten: %s\n"
+
+#, c-format
+msgid "start_cert_fetch failed: %s\n"
+msgstr "start_cert_fetch fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "fetch_next_cert failed: %s\n"
+msgstr "fetch_next_cert fehlgeschlagen: %s\n"
+
+#, c-format
+msgid "max_replies %d exceeded\n"
+msgstr "max_replies %d überschritten\n"
+
+#, c-format
+msgid "can't allocate control structure: %s\n"
+msgstr "Fehler beim Erzeugen der Kontrollstruktur: %s\n"
+
+#, c-format
+msgid "failed to initialize the server: %s\n"
+msgstr "Fehler beim Initialisieren des Servers: %s\n"
+
+#, c-format
+msgid "failed to the register commands with Assuan: %s\n"
+msgstr "Fehler beim Registrieren der Kommandos gegen Assuan: %s\n"
+
+#, c-format
+msgid "Assuan accept problem: %s\n"
+msgstr "Assuan accept Problem: %s\n"
+
+#, c-format
+msgid "Assuan processing failed: %s\n"
+msgstr "Assuan Verarbeitung fehlgeschlagen: %s\n"
+
+msgid "accepting root CA not marked as a CA"
+msgstr ""
+"Herausgeberzertifikat akzeptiert obgleich nicht für eine CA gekennzeichnet"
+
+msgid "CRL checking too deeply nested\n"
+msgstr "CRL Überprüfung ist zu tief geschachtelt\n"
+
+msgid "not checking CRL for"
+msgstr "keine Prüfung der CRL für"
+
+msgid "checking CRL for"
+msgstr "Prüfen der CRL für"
+
+msgid "running in compatibility mode - certificate chain not checked!\n"
+msgstr "Kompatibilitätsmodus - Zertifikatkette nicht geprüft!\n"
+
+msgid "selfsigned certificate has a BAD signature"
+msgstr "Das eigenbeglaubigte Zertifikat hat eine FALSCHE Signatur"
+
+#, c-format
+msgid "checking trustworthiness of root certificate failed: %s\n"
+msgstr ""
+"Prüfung der Vertrauenswürdigkeit des Wurzelzertifikats fehlgeschlagen: %s\n"
+
+msgid "certificate chain is good\n"
+msgstr "Der Zertifikatkette ist gültig\n"
+
+msgid "DSA requires the use of a 160 bit hash algorithm\n"
+msgstr "DSA benötigt eine 160 Bit Hashmethode\n"
+
+msgid "certificate should not have been used for CRL signing\n"
+msgstr ""
+"Das Zertifikat hätte nicht zum Signieren einer CRL benutzt werden sollen\n"
+
+msgid "quiet"
+msgstr "Reduzierte Informationen"
+
+msgid "print data out hex encoded"
+msgstr "Druckdaten hexkodiert ausgeben"
+
+msgid "decode received data lines"
+msgstr "Dekodiere empfangene Datenzeilen"
+
+msgid "connect to the dirmngr"
+msgstr "Mit dem Dirmngr verbinden"
+
+msgid "|NAME|connect to Assuan socket NAME"
+msgstr "|NAME|Verbinde mit dem Assuan-Socket NAME"
+
+msgid "|ADDR|connect to Assuan server at ADDR"
+msgstr "|ADDR|Verbinde mit dem Assuan-Server an Adresse ADDR"
 
 msgid "run the Assuan server given on the command line"
 msgstr "Starten des auf der Kommandozeile angegebenen Assuan-Server"
@@ -6533,14 +7646,14 @@ msgstr "|DATEI|Beim Starten Kommandos aus DATEI lesen"
 msgid "run /subst on startup"
 msgstr "Nach dem Starten \"/subst\" ausführen"
 
-msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Aufruf: gpg-connect-agent [Optionen] (-h für Hilfe)"
+msgid "Usage: @GPG@-connect-agent [options] (-h for help)"
+msgstr "Aufruf: @GPG@-connect-agent [Optionen] (-h für Hilfe)"
 
 msgid ""
-"Syntax: gpg-connect-agent [options]\n"
+"Syntax: @GPG@-connect-agent [options]\n"
 "Connect to a running agent and send commands\n"
 msgstr ""
-"Syntax: gpg-connect-agent [Optionen]\n"
+"Syntax: @GPG@-connect-agent [Optionen]\n"
 "Mit einem laufenden Agenten verbinden und Befehle senden\n"
 
 #, c-format
@@ -6562,7 +7675,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr "Zeile wegen enthaltenem Nul-Zeichen gekürzt\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "unbekannter Befehl `%s'\n"
 
 #, c-format
@@ -6570,10 +7683,6 @@ msgid "sending line failed: %s\n"
 msgstr "Senden der Zeile schlug fehl: %s\n"
 
 #, c-format
-msgid "error sending %s command: %s\n"
-msgstr "Fehler beim Senden des %s-Befehls: %s\n"
-
-#, c-format
 msgid "error sending standard options: %s\n"
 msgstr "Fehler beim Senden der Standardoptionen: %s\n"
 
@@ -6586,9 +7695,6 @@ msgstr "Optionen zur Einstellung der Konfiguration"
 msgid "Options useful for debugging"
 msgstr "Nützliche Optionen zur Fehlersuche"
 
-msgid "|FILE|write server mode logs to FILE"
-msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI"
-
 msgid "Options controlling the security"
 msgstr "Optionen zur Einstellung der Sicherheit"
 
@@ -6675,6 +7781,27 @@ msgstr "Liste der LDAP Server"
 msgid "Configuration for OCSP"
 msgstr "Konfiguration zu OCSP"
 
+msgid "GPG for OpenPGP"
+msgstr "GPG für OpenPGP"
+
+msgid "GPG Agent"
+msgstr "GPG Agent"
+
+msgid "Smartcard Daemon"
+msgstr "Smartcard Daemon"
+
+msgid "GPG for S/MIME"
+msgstr "GPG für S/MIME"
+
+msgid "Directory Manager"
+msgstr "Directory Manager"
+
+msgid "PIN and Passphrase Entry"
+msgstr "PIN und Passphrase Eingabe"
+
+msgid "Component not suitable for launching"
+msgstr "Komponente unterstützt kein direktes starten"
+
 #, c-format
 msgid "External verification of component %s failed"
 msgstr "Die externe Überprüfung der Komponente %s war nicht erfolgreich"
@@ -6700,8 +7827,8 @@ msgstr "|KOMPONENTE|Prüfe die Optionen"
 msgid "apply global default values"
 msgstr "Wende die gobalen Voreinstellungen an"
 
-msgid "get the configuration directories for gpgconf"
-msgstr "Hole die Einstelungsverzeichnisse von gpgconf"
+msgid "get the configuration directories for @GPGCONF@"
+msgstr "Hole die Einstellungsverzeichnisse von @GPGCONF@"
 
 msgid "list global configuration file"
 msgstr "Zeige die globale Konfigurationsdatei an"
@@ -6709,24 +7836,30 @@ msgstr "Zeige die globale Konfigurationsdatei an"
 msgid "check global configuration file"
 msgstr "Prüfe die globale Konfigurationsdatei"
 
+msgid "reload all or a given component"
+msgstr "\"reload\" an alle oder eine Komponente senden"
+
+msgid "launch a given component"
+msgstr "Die angegebene Komponente starten"
+
+msgid "kill a given component"
+msgstr "\"kill\" an eine Komponente senden"
+
 msgid "use as output file"
 msgstr "Als Ausgabedatei benutzen"
 
 msgid "activate changes at runtime, if possible"
 msgstr "Aktiviere Änderungen zur Laufzeit; falls möglich"
 
-msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Aufruf: gpgconf [Optionen] (-h für Hilfe)"
+msgid "Usage: @GPGCONF@ [options] (-h for help)"
+msgstr "Gebrauch: @GPGCONF@ [Optionen] (-h für Hilfe)"
 
 msgid ""
-"Syntax: gpgconf [options]\n"
-"Manage configuration options for tools of the GnuPG system\n"
+"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"
-
-msgid "usage: gpgconf [options] "
-msgstr "Aufruf: gpgconf [Optionen] "
+"Syntax: @GPGCONF@ {Optionen]\n"
+"Verwalte Konfigurationsoptionen für Programme des @GNUPG@ Systems\n"
 
 msgid "Need one component argument"
 msgstr "Benötige ein Komponentenargument"
@@ -6785,7 +7918,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "%s auf %s schlug mit Status %i fehl\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "Das temporäre Verzeichnis `%s' kann nicht erstellt werden: %s\n"
 
 #, c-format
@@ -6881,15 +8014,437 @@ msgstr ""
 "Syntax: gpg-check-pattern [optionen] Musterdatei\n"
 "Die von stdin gelesene Passphrase gegen die Musterdatei prüfen\n"
 
+#~ msgid "no secret subkey for public subkey %s - ignoring\n"
+#~ msgstr ""
+#~ "Kein privater Unterschlüssel zum öffentlichen Unterschlüssel %s - "
+#~ "ignoriert\n"
+
+#~ msgid "use a standard location for the socket"
+#~ msgstr "Benutze einen Standardnamen für den Socket"
+
+#~ msgid "|FILE|write environment settings also to FILE"
+#~ msgstr "|DATEI|Schreibe die Umgebungsvariablen auf DATEI"
+
+#~ msgid "gpg-agent protocol version %d is not supported\n"
+#~ msgstr "GPG-Agent-Protokoll-Version %d wird nicht unterstützt\n"
+
+#~ msgid "can't connect to the agent - trying fall back\n"
+#~ msgstr ""
+#~ "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n"
+
+#~ msgid "   (%d) ECC\n"
+#~ msgstr "   (%d) ECC\n"
+
+#~ msgid "can't create directory `%s': %s\n"
+#~ msgstr " git describe --match gnupg-2.1.*[0-9] --long"
+
 #~ msgid "you may want to start the gpg-agent first\n"
 #~ msgstr "Sie sollten zuerst den gpg-agent starten\n"
 
-#~ msgid "error loading `%s': %s\n"
+#~ msgid ""
+#~ "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
+#~ msgstr ""
+#~ "Im --pgp2-Modus kann nur für RSA-Schlüssel mit maximal 2048 Bit "
+#~ "verschlüsselt werden\n"
+
+#~ msgid ""
+#~ "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
+#~ msgstr ""
+#~ "Die IDEA-Verschlüsselung kann nicht mit allen Zielschlüsseln verwendet "
+#~ "werden.\n"
+
+#~ msgid ""
+#~ "you can only make detached or clear signatures while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "Im --pgp2-Modus können Sie nur abgetrennte oder Klartextsignaturen "
+#~ "machen\n"
+
+#~ msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "Im --pgp2-Modus können Sie nicht gleichzeitig signieren und "
+#~ "verschlüsseln\n"
+
+#~ msgid ""
+#~ "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
+#~ msgstr ""
+#~ "Im --pgp2-Modus müssen Sie Dateien benutzen und können keine Pipes "
+#~ "verwenden.\n"
+
+#~ msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
+#~ msgstr ""
+#~ "Verschlüsseln einer Botschaft benötigt im --pgp2-Modus die IDEA-"
+#~ "Verschlüsselung\n"
+
+#~ msgid ""
+#~ "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
+#~ "mode.\n"
+#~ msgstr ""
+#~ "Im --pgp2-Modus kann nur mit PGP-2.x-artigen Schlüsseln signiert werden\n"
+
+#~ msgid "This would make the key unusable in PGP 2.x.\n"
+#~ msgstr "Dies würde den Schlüssel für PGP 2.x unbrauchbar machen\n"
+
+#~ msgid ""
+#~ "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "Im --pgp2-Modus kann nur mit PGP-2.x-artigen Schlüsseln eine abgetrennte "
+#~ "Signatur erzeugt werden\n"
+
+#~ msgid ""
+#~ "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "Im --pgp2-Modus können Sie Klartextsignaturen nur mit PGP-2.x-artigen "
+#~ "Schlüssel machen\n"
+
+#~ msgid "usage: gpg [options] "
+#~ msgstr "Aufruf: gpg [Optionen] "
+
+#~ msgid "usage: gpgsm [options] "
+#~ msgstr "Aufruf: gpgsm [Optionen] "
+
+#~ msgid "enable ssh-agent emulation"
+#~ msgstr "Die ssh-agent-Emulation anschalten"
+
+#~ msgid "error creating socket: %s\n"
+#~ msgstr "Fehler beim Erstellen des Sockets: %s\n"
+
+#~ msgid "host not found"
+#~ msgstr "Host nicht gefunden"
+
+#~ msgid "error loading '%s': %s\n"
 #~ msgstr "Fehler beim Laden von `%s': %s\n"
 
+#~ msgid "deleting secret key not implemented\n"
+#~ msgstr "Löschen des geheimen Schlüssel ist nicht implementiert\n"
+
+#~ msgid "10 translator see trustdb.c:uid_trust_string_fixed"
+#~ msgstr "10"
+
+#~ msgid "[ revoked]"
+#~ msgstr "[widerrufen]"
+
+#~ msgid "[ expired]"
+#~ msgstr "[verfall.]"
+
+#~ msgid "[ unknown]"
+#~ msgstr "[  unbek.]"
+
+#~ msgid "[  undef ]"
+#~ msgstr "[  undef.]"
+
+#~ msgid "[marginal]"
+#~ msgstr "[marginal]"
+
+#~ msgid "[  full  ]"
+#~ msgstr "[ vollst.]"
+
+#~ msgid "[ultimate]"
+#~ msgstr "[ uneing.]"
+
+#~ msgid "undefined"
+#~ msgstr "unbestimmt"
+
+#~ msgid "never"
+#~ msgstr "niemals"
+
+#~ msgid "marginal"
+#~ msgstr "marginal"
+
+#~ msgid "full"
+#~ msgstr "vollständig"
+
+#~ msgid "ultimate"
+#~ msgstr "uneingeschränkt"
+
+#~ msgid "usage: gpgconf [options] "
+#~ msgstr "Aufruf: gpgconf [Optionen] "
+
+#~ msgid "Usage: scdaemon [options] (-h for help)"
+#~ msgstr "Aufruf: scdaemon [Optionen] (-h für Hilfe)"
+
+#~ msgid "malformed GPG_AGENT_INFO environment variable\n"
+#~ msgstr "fehlerhaft aufgebaute GPG_AGENT_INFO - Umgebungsvariable\n"
+
+#~ msgid "Usage: gpgsm [options] [files] (-h for help)"
+#~ msgstr "Aufruf: gpgsm [Optionen] [Dateien] (-h für Hilfe)"
+
+#~ msgid "Usage: dirmngr [options] (-h for help)"
+#~ msgstr "Gebrauch: dirmnr [Optionen] [Kommando [Argumente]]"
+
+#~ msgid "usage: dirmngr [options] "
+#~ msgstr "Gebrauch: dirmngr [Optionen] "
+
+#~ msgid "Usage: gpgconf [options] (-h for help)"
+#~ msgstr "Aufruf: gpgconf [Optionen] (-h für Hilfe)"
+
+#~ msgid "Usage: gpg-agent [options] (-h for help)"
+#~ msgstr "Aufruf: gpg-agent [Optionen] (-h für Hilfe)"
+
 #~ msgid "failed to allocated keyDB handle\n"
 #~ msgstr "Ein keyDB Handle konnte nicht bereitgestellt werden\n"
 
+#~ msgid "the IDEA cipher plugin is not present\n"
+#~ msgstr "das IDEA-Verschlüsselungs-Plugin ist nicht vorhanden\n"
+
+#~ msgid "pth_event failed: %s\n"
+#~ msgstr "pth_event() fehlgeschlagen: %s\n"
+
+#~ msgid "pth_wait failed: %s\n"
+#~ msgstr "pth_wait() fehlgeschlagen: %s\n"
+
+#~ msgid " - probably dead - removing lock"
+#~ msgstr " - existiert wahrscheinlich nicht mehr - entferne Sperre"
+
+#~ msgid "key %s: secret key part already available\n"
+#~ msgstr "Schlüssel %s: Die geheimen Teile sind bereits vorhanden\n"
+
+#~ msgid "self-signed certificate"
+#~ msgstr "eigenbeglaubigtes Zertifikat"
+
+#~ msgid "Parameters to be used for the certificate request:\n"
+#~ msgstr ""
+#~ "Parameter die für die Zertifikatsanforderung benutzt werden sollen:\n"
+
+#~ msgid "WARNING: unable to parse URI %s\n"
+#~ msgstr "WARNUNG: die URI %s kann nicht analysiert werden\n"
+
+#~ msgid "DSA key %s uses an unsafe (%zu bit) hash\n"
+#~ msgstr "DSA-Schlüssel %s verwendet einen unsicheren (%zu Bit-) Hash\n"
+
+#~ msgid "accept failed: %s - waiting 1s\n"
+#~ msgstr "accept() fehlgeschlagen: %s - warte 1s\n"
+
+#~ msgid "error spawning connection handler: %s\n"
+#~ msgstr "Fehler beim Starten des Verbindungshandler: %s\n"
+
+#~ msgid "searching for names from %s server %s\n"
+#~ msgstr "suche Namen auf %s-Server %s\n"
+
+#~ msgid "searching for names from %s\n"
+#~ msgstr "suche Namen auf %s\n"
+
+#~ msgid "searching for \"%s\" from %s server %s\n"
+#~ msgstr "suche nach \"%s\" auf %s-Server %s\n"
+
+#~ msgid "searching for \"%s\" from %s\n"
+#~ msgstr "suche nach \"%s\" auf %s\n"
+
+#~ msgid "no keyserver action!\n"
+#~ msgstr "Kein Schlüsselserver-Vorgang\n"
+
+#~ msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
+#~ msgstr ""
+#~ "WARNUNG: Die Schlüsselserver-Handhabungsroutine stammt von einer anderen "
+#~ "GnuPG-Version (%s)\n"
+
+#~ msgid "keyserver did not send VERSION\n"
+#~ msgstr "Schlüsselserver sendete VERSION nicht\n"
+
+#~ msgid "no handler for keyserver scheme `%s'\n"
+#~ msgstr "Keine Handhabungsroutine für Schlüsselserverschema `%s'\n"
+
+#~ msgid "action `%s' not supported with keyserver scheme `%s'\n"
+#~ msgstr ""
+#~ "Vorgang `%s' wird vom Schlüsselserverschema `%s' nicht unterstützt\n"
+
+#~ msgid "%s does not support handler version %d\n"
+#~ msgstr "%s unterstützt Hilfsroutinenversion %d nicht\n"
+
+#~ msgid "keyserver timed out\n"
+#~ msgstr "Schlüsselserver-Zeitüberschreitung\n"
+
+#~ msgid "keyserver internal error\n"
+#~ msgstr "interner Fehler Schlüsselserver\n"
+
+#~ msgid "keyserver communications error: %s\n"
+#~ msgstr "Schlüsselserver-Datenübertragunsfehler: %s\n"
+
+#~ msgid "connection to agent established (%ds)\n"
+#~ msgstr "Verbindung zum gpg-agent aufgebaut (%ds)\n"
+
+#~ msgid "connection to the dirmngr established (%ds)\n"
+#~ msgstr "Verbindung zum Dirmngr aufgebaut (%ds)\n"
+
+#~ msgid "external keyserver calls are not supported in this build\n"
+#~ msgstr ""
+#~ "Externe Schlüsselserveraufrufe werden in diesem \"Build\" nicht "
+#~ "unterstützt\n"
+
+#~ msgid "This key is not protected.\n"
+#~ msgstr "Dieser Schlüssel ist nicht geschützt.\n"
+
+#~ msgid "unknown key protection algorithm\n"
+#~ msgstr "Unbekanntes Schlüssel-Schutzverfahren\n"
+
+#~ msgid "Secret parts of key are not available.\n"
+#~ msgstr "Geheime Teile des Schlüssels sind nicht vorhanden\n"
+
+#~ msgid "Secret parts of key are stored on-card.\n"
+#~ msgstr "Geheime Teile des Schlüssels sind auf einer Karte gespeichert.\n"
+
+#~ msgid "protection algorithm %d%s is not supported\n"
+#~ msgstr "Schutzverfahren %d%s wird nicht unterstützt\n"
+
+#~ msgid "protection digest %d is not supported\n"
+#~ msgstr "Hashschutzverfahren %d wird nicht unterstützt\n"
+
+#~ msgid "Can't edit this key: %s\n"
+#~ msgstr "Dieser Schlüssel kann nicht editiert werden: %s\n"
+
+#~ msgid ""
+#~ "Enter the new passphrase for this secret key.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "Geben Sie die neue Passphrase für diesen geheimen Schlüssel ein.\n"
+#~ "\n"
+
+#~ msgid ""
+#~ "You don't want a passphrase - this is probably a *bad* idea!\n"
+#~ "\n"
+#~ msgstr ""
+#~ "Sie wollen keine Passphrase - dies ist *nicht* zu empfehlen!\n"
+#~ "\n"
+
+#~ msgid "Do you really want to do this? (y/N) "
+#~ msgstr "Möchten Sie dies wirklich tun? (j/N) "
+
+#~ msgid "update secret failed: %s\n"
+#~ msgstr "Änderung des Geheimnisses fehlgeschlagen: %s\n"
+
+#~ msgid "can't setup KSBA reader: %s\n"
+#~ msgstr "KSAB Reader Objekt kann nicht erstellt werden: %s\n"
+
+#~ msgid "|FILE|listen on socket FILE"
+#~ msgstr "|DATEI|Anfragen auf Socket DATEI annehmen"
+
+#~ msgid "command %s failed: %s\n"
+#~ msgstr "Kommando %s fehlgeschlagen: %s\n"
+
+#~ msgid "no data stream"
+#~ msgstr "Kein Datenstrom"
+
+#~ msgid "can't fdopen pipe for reading: %s\n"
+#~ msgstr "Pipe kann nicht zum Lesen \"fdopen\"t werden: %s\n"
+
+#~ msgid "secret key already stored on a card\n"
+#~ msgstr "Geheimer Schlüssel ist bereits auf einer Karte gespeichert\n"
+
+#~ msgid "error writing key to card: %s\n"
+#~ msgstr "Fehler beim Schreiben des Schlüssels auf die Karte: %s\n"
+
+#~ msgid "remove the passphrase from exported subkeys"
+#~ msgstr "Die Passphrase von exportierten Unterschlüssel entfernen"
+
+#~ msgid "key %s: not protected - skipped\n"
+#~ msgstr "Schlüssel %s: ungeschützt - übersprungen\n"
+
+#~ msgid "about to export an unprotected subkey\n"
+#~ msgstr "Ein ungeschützter Unterschlüssel wird exportiert werden\n"
+
+#~ msgid "failed to unprotect the subkey: %s\n"
+#~ msgstr "Entfernen des Schutzes für des Unterschlüssel fehlgeschlagen: %s\n"
+
+# translated by wk
+#~ msgid "WARNING: secret key %s does not have a simple SK checksum\n"
+#~ msgstr "WARNUNG: Der geheime Schlüssel %s hat keine einfache SK-Prüfsumme\n"
+
+#~ msgid "key %s: secret key without public key - skipped\n"
+#~ msgstr ""
+#~ "Schlüssel %s: geheimer Schlüssel ohne öffentlichen Schlüssel - "
+#~ "übersprungen\n"
+
+#~ msgid "create a public key when importing a secret key"
+#~ msgstr ""
+#~ "beim Import eines geheimen Schlüssels einen öffentliche Schlüssel erzeugen"
+
+#~ msgid "no default secret keyring: %s\n"
+#~ msgstr "Kein voreingestellter geheimer Schlüsselbund: %s\n"
+
+#~ msgid "key %s: already in secret keyring\n"
+#~ msgstr "Schlüssel %s: Ist bereits im geheimen Schlüsselbund\n"
+
+#~ msgid "key %s: secret key not found: %s\n"
+#~ msgstr "Schlüssel %s: geheimer Schlüssel nicht gefunden: %s\n"
+
+#~ msgid "Note: a key's S/N does not match the card's one\n"
+#~ msgstr ""
+#~ "Hinweis: Eine Schlüsselseriennr stimmt nicht mit derjenigen der Karte "
+#~ "überein\n"
+
+#~ msgid "Note: primary key is online and stored on card\n"
+#~ msgstr "Hinweis: Hauptschlüssel ist online und auf der Karte gespeichert\n"
+
+#~ msgid "Note: secondary key is online and stored on card\n"
+#~ msgstr "Hinweis: Zweitschlüssel ist online und auf der Karte gespeichert\n"
+
+#~ msgid "Key is protected.\n"
+#~ msgstr "Schlüssel ist geschützt.\n"
+
+#~ msgid "error reading secret keyblock \"%s\": %s\n"
+#~ msgstr "Fehler beim Lesen des geheimen Schlüsselblocks \"%s\": %s\n"
+
+#~ msgid "Please remove selections from the secret keys.\n"
+#~ msgstr "Bitte entfernen Sie die Auswahl von den geheimen Schlüsseln.\n"
+
+#~ msgid "No corresponding signature in secret ring\n"
+#~ msgstr "Keine entsprechende Signatur im geheimen Schlüsselbund\n"
+
+#~ msgid "writing secret key stub to `%s'\n"
+#~ msgstr "schreiben des geheimen Schlüssel-\"stub\"s nach `%s'\n"
+
+#~ msgid "writing secret key to `%s'\n"
+#~ msgstr "schreiben des geheimen Schlüssels nach '%s'\n"
+
+#~ msgid "no writable secret keyring found: %s\n"
+#~ msgstr "kein schreibbarer geheimer Schlüsselbund gefunden: %s\n"
+
+#~ msgid "error writing secret keyring `%s': %s\n"
+#~ msgstr "Fehler beim Schreiben des geheimen Schlüsselbundes `%s': %s\n"
+
+#~ msgid "WARNING: 2 files with confidential information exists.\n"
+#~ msgstr "WARNUNG: Zwei Dateien mit vertraulichem Inhalt vorhanden.\n"
+
+#~ msgid "%s is the unchanged one\n"
+#~ msgstr "%s ist der Unveränderte\n"
+
+#~ msgid "%s is the new one\n"
+#~ msgstr "%s ist der Neue\n"
+
+#~ msgid "Please fix this possible security flaw\n"
+#~ msgstr "Bitte diesen potentiellen Sicherheitsmangel beseitigen\n"
+
+#~ msgid "no corresponding public key: %s\n"
+#~ msgstr "kein zugehöriger öffentlicher Schlüssel: %s\n"
+
+#~ msgid "public key does not match secret key!\n"
+#~ msgstr "Öffentlicher Schlüssel paßt nicht zum geheimen Schlüssel!\n"
+
+#~ msgid "unknown protection algorithm\n"
+#~ msgstr "Unbekanntes Schutzverfahren\n"
+
+#~ msgid "Note: This key is not protected!\n"
+#~ msgstr "Dieser Schlüssel ist nicht geschützt.\n"
+
+#~ msgid "Invalid passphrase; please try again"
+#~ msgstr "Ungültige Passphrase; versuchen Sie es bitte noch einmal"
+
+#~ msgid "%s ...\n"
+#~ msgstr "%s ...\n"
+
+#~ msgid "WARNING: Weak key detected - please change passphrase again.\n"
+#~ msgstr ""
+#~ "WARNUNG: Unsicherer Schlüssel entdeckt -\n"
+#~ "         bitte Passphrase nochmals wechseln.\n"
+
+#~ msgid ""
+#~ "generating the deprecated 16-bit checksum for secret key protection\n"
+#~ msgstr ""
+#~ "Die mißbilligte 16-bit Prüfsumme wird zum Schutz des geheimen Schlüssels "
+#~ "benutzt\n"
+
+#~ msgid "use system's dirmngr if available"
+#~ msgstr "Benutze den System Dirmngr falls verfügbar"
+
 #~ msgid "Command> "
 #~ msgstr "Befehl> "
 
@@ -7339,6 +8894,3 @@ msgstr ""
 #~ msgstr ""
 #~ "Verschlüsselungserweiterung `%s' wurde wegen unsicherer Zugriffsrechte "
 #~ "nicht geladen\n"
-
-#~ msgid "DSA requires the use of a 160 bit hash algorithm\n"
-#~ msgstr "DSA benötigt einen 160-bit Hash Algorithmus\n"
index 92ee086..6f62bb2 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -1,8 +1,6 @@
 # Greek Translation of GnuPG.
 # Copyright (C) 2002 Free Software Foundation, Inc.
 # Dokianakis Theofanis <madf@hellug.gr>, 2002.
-#                      !-- psbl.surriel.com rejected (2011-01-11)
-# Designated-Translator: none
 #
 msgid ""
 msgstr ""
@@ -11,7 +9,6 @@ msgstr ""
 "PO-Revision-Date: 2003-06-27 12:00+0200\n"
 "Last-Translator: Dokianakis Theofanis <madf@hellug.gr>\n"
 "Language-Team: Greek <nls@tux.hellug.gr>\n"
-"Language: el\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-7\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -20,41 +17,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "áðïôõ÷ßá áñ÷éêïðïßçóçò ôçò TrustDB: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Óßãïõñá èÝëåôå íá áíáêëçèïýí ôá åðéëåãìÝíá êëåéäéÜ; "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "ìç Ýãêõñç öñÜóç êëåéäß"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -80,9 +42,6 @@ msgid ""
 "this session"
 msgstr "ÐëçêôñïëïãÞóôå ôç öñÜóç êëåéäß· áõôÞ åßíáé ìéá ìõóôéêÞ ðñüôáóç \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -119,11 +78,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "äåí õðïóôçñßæåôáé ï áëãüñéèìïò ðñïóôáóßáò %d%s\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôïõ `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "áäõíáìßá ðñüóâáóçò óôï `%s': %s\n"
 
 #, fuzzy, c-format
@@ -150,31 +109,19 @@ msgstr "
 msgid "error writing key: %s\n"
 msgstr "áäõíáìßá åããñáöÞò ôçò êëåéäïèÞêçò `%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "ÐëçêôñïëïãÞóôå ôç öñÜóç êëåéäß· áõôÞ åßíáé ìéá ìõóôéêÞ ðñüôáóç \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "áëëáãÞ ôçò öñÜóçò êëåéäß"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "ÐëçêôñïëïãÞóôå ôç öñÜóç êëåéäß· áõôÞ åßíáé ìéá ìõóôéêÞ ðñüôáóç \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -201,7 +148,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -289,7 +236,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "×ñåéÜæåóôå ìéá ÖñÜóç êëåéäß ãéá íá ðñïóôáôåýóåôå ôï ìõóôéêü êëåéäß.\n"
 "\n"
@@ -307,10 +254,10 @@ msgstr ""
 "ÅðéëïãÝò:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -366,26 +313,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "óöÜëìá óôç äçìéïõñãßá ôçò öñÜóçò êëåéäß: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "äåí õðïóôçñßæåôáé"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "äåí õðïóôçñßæåôáé"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "óöÜëìá óôç äçìéïõñãßá ôçò öñÜóçò êëåéäß: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -407,7 +343,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -415,23 +351,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "ÓÇÌÅÉÙÓÇ: ìç ðñïêáèïñéóìÝíï áñ÷åßï åðéëïãþí `%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "áñ÷åßï åðéëïãþí `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "áíÜãíùóç åðéëïãþí áðü `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "óöÜëìá êáôÜ ôç äçìéïõñãßá ôïõ `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò êáôáëüãïõ `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -442,7 +378,7 @@ msgid "can't create socket: %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôïõ %s: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -454,7 +390,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "óöÜëìá óôç äçìéïõñãßá ôçò öñÜóçò êëåéäß: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "óöÜëìá óôç áðïóôïëÞ ðñïò ôï `%s': %s\n"
 
 #, fuzzy, c-format
@@ -462,19 +398,19 @@ msgid "listen() failed: %s\n"
 msgstr "ç åíçìÝñùóç áðÝôõ÷å: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "åããñáöÞ ôïõ ìõóôéêïý êëåéäéïý óôï `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: êáôÜëïãïò äçìéïõñãÞèçêå\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "trustdb: read áðÝôõ÷å (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: áäõíáìßá äçìéïõñãßáò êáôáëüãïõ: %s\n"
 
 #, fuzzy, c-format
@@ -582,31 +518,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "óöÜëìá óôç äçìéïõñãßá ôçò öñÜóçò êëåéäß: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "ôï êëåéäß '%s' äå âñÝèçêå: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "ôìÞìáôá ôïõ ìõóôéêïý êëåéäéïý äåí åßíáé äéáèÝóéìá\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "óöÜëìá áíÜãíùóçò: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -694,15 +630,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "áäõíáìßá åããñáöÞò ìõóôéêÞò êëåéäïèÞêçò `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
 
 #, fuzzy, c-format
@@ -717,7 +653,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "ï gpg-agent äåí åßíáé äéáèÝóéìïò óå áõôÞ ôç óõíåäñßá\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "áäõíáìßá óýíäåóçò óôï `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -794,10 +730,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -824,22 +756,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "êáêü ðéóôïðïéçôéêü"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "êáêü ðéóôïðïéçôéêü"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "êáêü ðéóôïðïéçôéêü"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "êáêü ðéóôïðïéçôéêü"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "êáêü ðéóôïðïéçôéêü"
 
@@ -882,26 +798,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "ìç Ýãêõñïò áëãüñéèìïò  hash `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "ÕðïãñáöÞ Ýëçîå óôéò %s.\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "ìç Ýãêõñïò áëãüñéèìïò  hash `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "äåí õðïóôçñßæåôáé ï áëãüñéèìïò ðñïóôáóßáò %d%s\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "êáôáóôïëÞ áíÜêëçóçò õðïãñáöÞò\n"
 
@@ -910,11 +810,11 @@ msgid "Signature available"
 msgstr "ÕðïãñáöÞ Ýëçîå óôéò %s.\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "ÊáëÞ õðïãñáöÞ áðü \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "ìç Ýãêõñïò áëãüñéèìïò  hash `%s'\n"
 
 #, fuzzy, c-format
@@ -959,7 +859,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Äåí õðÜñ÷åé äéáèÝóéìç âïÞèåéá ãéá `%s'"
 
 #, fuzzy
@@ -1134,11 +1034,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "áäõíáìßá åããñáöÞò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1340,8 +1240,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "ÅíôïëÞ> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1362,7 +1262,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output äåí ëåéôïõñãåß ãéá áõôÞ ôçí åíôïëÞ\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "áäõíáìßá ðñüóâáóçò ôïõ `%s'\n"
 
 #, fuzzy, c-format
@@ -1415,11 +1315,11 @@ msgid "using cipher %s\n"
 msgstr "÷ñÞóç ôïõ êñõðôáëãüñéèìïõ: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' Þäç óõìðéÝóôçêå\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: `%s' åßíáé Ýíá Üäåéï áñ÷åßï\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1428,7 +1328,7 @@ msgstr ""
 "pgp2\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "áíÜãíùóç áðü `%s'\n"
 
 msgid ""
@@ -1498,11 +1398,11 @@ msgstr ""
 "áõôÞ ç ðëáôöüñìá áðáéôåß ðñïóùñ. áñ÷åßá óôçí êëÞóç åîùôåñéêþí ðñïãñáììÜôùí\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "áäõíáìßá åêôÝëåóçò ôïõ %s \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "áäõíáìßá åêôÝëåóçò ôïõ %s \"%s\": %s\n"
 
 #, c-format
@@ -1520,11 +1420,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "áäõíáìßá áíÜãíùóçò ôçò áðÜíôçóçò ôïõ åîùôåñéêïý ðñïãñÜììáôïò: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: áäõíáìßá äéáãñáöÞò tempfile (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: áäõíáìßá äéáãñáöÞò ðñïóùñéíïý öáêÝëïõ `%s': %s\n"
 
 #, fuzzy
@@ -1593,16 +1493,12 @@ msgstr "
 msgid "[User ID not found]"
 msgstr "[User id äåí âñÝèçêå]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "êëåéäß %08lX: ìõóôéêü êëåéäß ÷ùñßò äçìüóéï - ðáñáëåßöèçêå\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "óöÜëìá êáôÜ ôç äçìéïõñãßá ôïõ `%s': %s\n"
 
 #, fuzzy
@@ -1622,6 +1518,10 @@ msgstr "
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "÷ñÞóç ôïõ äåõôåñåýïíôïò êëåéäéïý %08lX áíôß ôïõ ðñùôåýïíôïò %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "êëåéäß %08lX: ìõóôéêü êëåéäß ÷ùñßò äçìüóéï - ðáñáëåßöèçêå\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "äçìéïõñãßá ìéáò ìç ðñïóáñôçìÝíçò õðïãñáöÞò"
@@ -1664,9 +1564,6 @@ msgstr "
 msgid "generate a new key pair"
 msgstr "äçìéïõñãßá åíüò íÝïõ æåýãïõò êëåéäéþí"
 
-msgid "generate a revocation certificate"
-msgstr "äçìéïõñãßá åíüò ðéóôïðïéçôéêïý áíÜêëçóçò"
-
 msgid "remove keys from the public keyring"
 msgstr "áöáßñåóç ôùí êëåéäéþí áðü ôç äçìüóéá êëåéäïèÞêç"
 
@@ -1682,9 +1579,8 @@ msgstr "
 msgid "sign or edit a key"
 msgstr "õðïãñáöÞ Þ åðåîåñãáóßá åíüò êëåéäéïý"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "áëëáãÞ ôçò öñÜóçò êëåéäß"
+msgid "generate a revocation certificate"
+msgstr "äçìéïõñãßá åíüò ðéóôïðïéçôéêïý áíÜêëçóçò"
 
 msgid "export keys"
 msgstr "åîáãùãÞ êëåéäéþí"
@@ -1783,15 +1679,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "×ñÞóç: gpg [åðéëïãÝò] [áñ÷åßá] (-h ãéá âïÞèåéá)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Óýíôáîç: gpg [åðéëïãÝò] [áñ÷åßá]\n"
 "õðïãñáöÞ, Ýëåã÷ïò, êñõðôïãñÜöçóç Þ áðïêñõðôïãñÜöçóç\n"
@@ -1823,35 +1714,35 @@ msgid "conflicting commands\n"
 msgstr "óõãêñïõüìåíåò åíôïëÝò\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "äåí âñÝèçêå ôï óýìâïëï = óôïí ïñéóìü ôçò ïìÜäáò \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëÞò éäéïêôçóßá óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëÞò éäéïêôçóßá óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëÞò éäéïêôçóßá óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
 "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëÞò éäéïêôçóßáåóþêëåéóôïõ öáêÝëïõ óôï %s \"%s\"\n"
 
@@ -1862,12 +1753,12 @@ msgstr ""
 "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëÞò éäéïêôçóßáåóþêëåéóôïõ öáêÝëïõ óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëÞò éäéïêôçóßáåóþêëåéóôïõ öáêÝëïõ óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò åóþêëåéóôïõ öáêÝëïõ óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1876,11 +1767,11 @@ msgid ""
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò åóþêëåéóôïõ öáêÝëïõ óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ìç áóöáëåßò Üäåéåò åóþêëåéóôïõ öáêÝëïõ óôï %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "Üãíùóôï áíôéêåßìåíï ñõèìßóåùò \"%s\"\n"
 
 msgid "display photo IDs during key listings"
@@ -1921,7 +1812,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Äåí âñÝèçêå áíôßóôïé÷ç õðïãñáöÞ óôç ìõóôéêÞ êëåéäïèÞêç\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "ÓÇÌÅÉÙÓÇ: áãíïÞèçêå ôï ðáëéü áñ÷åßï ðñïêáèïñéóìÝíùí åðéëïãþí `%s'\n"
 
 #, c-format
@@ -1933,11 +1824,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "ÓÇÌÅÉÙÓÇ: ôï %s äåí åßíáé ãéá êáíïíéêÞ ÷ñÞóç!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "ôï %s äåí åßíáé Ýãêõñï óåô ÷áñáêôÞñùí\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "ôï %s äåí åßíáé Ýãêõñï óåô ÷áñáêôÞñùí\n"
 
 #, fuzzy
@@ -2119,16 +2010,16 @@ msgid "%s does not yet work with %s\n"
 msgstr "ôï %s áêüìá äå ëåéôïõñãåß ìáæß ìå ôï %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "áðáãïñåýåôå ç ÷ñÞóç ôïõ êñõðôáëãüñéèìïõ \"%s\" óôçí êáôÜóôáóç %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr ""
 "áðáãïñåýåôå ç ÷ñÞóç ôïõ áëãüñéèìïõ ðåñßëçøçò \"%s\" óôçí êáôÜóôáóç %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr ""
 "áðáãïñåýåôå ç ÷ñÞóç ôïõ áëãüñéèìïõ óõìðßåóçò \"%s\" óôçí êáôÜóôáóç %s\n"
 
@@ -2148,7 +2039,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [üíïìá áñ÷åßïõ]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "áðïêñõðôïãñÜöçóç áðÝôõ÷å: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2200,10 +2091,6 @@ msgstr "--lsign-key user-id"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key user-id [åíôïëÝò]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key user-id"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "keyserver áðïóôïëÞ áðÝôõ÷å: %s\n"
@@ -2233,7 +2120,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "èùñÜêéóç áðÝôõ÷å: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "ìç Ýãêõñïò áëãüñéèìïò  hash `%s'\n"
 
 msgid "[filename]"
@@ -2277,7 +2164,7 @@ msgid "No help available"
 msgstr "Äåí õðÜñ÷åé äéáèÝóéìç âïÞèåéá"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Äåí õðÜñ÷åé äéáèÝóéìç âïÞèåéá ãéá `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2287,10 +2174,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "áíáíÝùóç ôçò âÜóçò äåäïìÝíùí åìðéóôïóýíçò"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "áíáíÝùóç ôçò âÜóçò äåäïìÝíùí åìðéóôïóýíçò"
 
@@ -2409,13 +2292,6 @@ msgid "key %s: no user ID\n"
 msgstr "êëåéäß %08lX: äåí õðÜñ÷åé áõôü ôï user ID\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "ðáñáëåßöèçêå `%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "êëåéäß %08lX: åðéäéüñèùóç öèáñìÝíïõ õðïêëåéäéïý HKP\n"
 
@@ -2443,11 +2319,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "äåí âñåèçêå åããñÜøéìç êëåéäïèÞêç: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "åããñáöÞ óôï  `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "áäõíáìßá åããñáöÞò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 #, fuzzy, c-format
@@ -2511,17 +2387,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "êëåéäß %08lX: \"%s\" áìåôÜâëçôï\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "ôï ìõóôéêü êëåéäß `%s' äå âñÝèçêå: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "êëåéäß %08lX: ìõóôéêü êëåéäß ìå Üêõñï êñõðôáëã. %d - ðáñáëåßöèçêå\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "åããñáöÞ ôïõ ìõóôéêïý êëåéäéïý óôï `%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "êëåéäß %08lX: ìõóôéêü êëåéäß ìå Üêõñï êñõðôáëã. %d - ðáñáëåßöèçêå\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "äåí õðÜñ÷åé ðñïêáèïñéóìÝíç êëåéäïèÞêç: %s\n"
@@ -2559,26 +2431,22 @@ msgstr "
 #, fuzzy, c-format
 msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
 msgstr ""
-"êëåéäß %08lX: ìç õðïóôçñéæüìåíïò áëãüñéèìïò äçìïóßïõ êëåéäéïý óôï user id "
-"\"%s\"\n"
+"êëåéäß %08lX: ìç õðïóôçñéæüìåíïò áëãüñéèìïò äçìïóßïõ êëåéäéïý óôï user id \"%"
+"s\"\n"
 
 #, fuzzy, c-format
 msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "êëåéäß %08lX: ìç Ýãêõñç éäéï-õðïãñáöÞ óôï user id \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "êëåéäß %08lX: ìç õðïóôçñéæüìåíïò áëãüñéèìïò äçìïóßïõ êëåéäéïý\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "êëåéäß %08lX: Üìåóç õðïãñáöÞ êëåéäéïý ðñïóôÝèçêå\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "êëåéäß %08lX: äåí õðÜñ÷åé õðïêëåéäß ãéá ôç äÝóìåõóç êëåéäéïý\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "êëåéäß %08lX: ìç õðïóôçñéæüìåíïò áëãüñéèìïò äçìïóßïõ êëåéäéïý\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "êëåéäß %08lX: ìç Ýãêõñç äÝóìåõóç õðïêëåéäéïý\n"
 
@@ -2635,8 +2503,8 @@ msgstr "
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
 msgstr ""
-"ÐÑÏÅÉÄÏÐÏÉÇÓÇ: êëåéäß %08lX ìðïñåß íá áíáêëçèåß: ëÞøç êëåéäéïý áíÜêëçóçò "
-"%08lX\n"
+"ÐÑÏÅÉÄÏÐÏÉÇÓÇ: êëåéäß %08lX ìðïñåß íá áíáêëçèåß: ëÞøç êëåéäéïý áíÜêëçóçò %"
+"08lX\n"
 
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
@@ -2665,15 +2533,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "ðáñáëåßöèçêå: ìõóôéêü êëåéäß Þäç ðáñþí\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "êëåéäïèÞêç `%s' äçìéïõñãÞèçêå\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "óöÜëìá êáôÜ ôç äçìéïõñãßá ôïõ `%s': %s\n"
 
 #, c-format
@@ -2864,7 +2732,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) ¸÷ù êÜíåé åêôåôáìÝíï Ýëåã÷ï.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Ç åðéëïãÞ óáò; (ðëçêôñïëïãÞóôå ? ãéá ðëçñïöïñßåò): "
 
 #, fuzzy, c-format
@@ -3144,7 +3012,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "ÓõìâïõëÞ: ÅðéëÝîôå ôï user ID ãéá õðïãñáöÞ\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Üãíùóôç êëÜóç õðïãñáöÞò"
 
 #, c-format
@@ -3179,11 +3047,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "áäõíáìßá ðñüóâáóçò óôï `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3272,7 +3140,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Äåí õðÜñ÷ïõí ðñïåðéëïãÝò óå Ýíá user ID ôýðïõ PGP 2.x.\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Áõôü ôï êëåéäß ìðïñåß íá áíáêëçèåß áðü %s êëåéäß "
 
 #, fuzzy, c-format
@@ -3339,14 +3207,6 @@ msgstr ""
 "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: äåí Ý÷åé óçìåéùèåß ID ÷ñÞóôç óáí ðñùôåýùí.  ÁõôÞ ç åíôïëÞ\n"
 "              ìðïñåß íá êÜíåé Ýíá Üëëï ID ÷ñÞóôç íá ãßíåé ôï ðñùôåýùí.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Äåí ìðïñåßôå íá áëëÜîåôå ôçí çìåñïìçíßá ëÞîçò óå Ýíá v3 êëåéäß\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3585,7 +3445,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Áðåéêüíéóç %s photo ID ìåãÝèïõò %ld ãéá ôï êëåéäß 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "ç ðñïåðéëïãÞ %c%lu áíôéãñÜöôçêå\n"
 
 #, fuzzy
@@ -3601,7 +3461,7 @@ msgid "too many compression preferences\n"
 msgstr "ðÜñá ðïëëÝò `%c' ðñïåðéëïãÝò\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "ìç Ýãêõñïò ÷áñáêôÞñáò óôï \"êïñäüíé\" ôçò åðéëïãÞò\n"
 
 msgid "writing direct signature\n"
@@ -3844,7 +3704,7 @@ msgid "Invalid character in comment\n"
 msgstr "Ìç Ýãêõñïò ÷áñáêôÞñáò óôï ó÷üëéï\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "×ñçóéìïðïéåßôå ôï `%s' óåô ÷áñáêôÞñùí.\n"
 
 #, c-format
@@ -3929,15 +3789,15 @@ msgid "Key generation canceled.\n"
 msgstr "Ç äçìéïõñãßá êëåéäéïý áíáâëÞèçêå.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "åããñáöÞ ôïõ äçìïóßïõ êëåéäéïý óôï `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "åããñáöÞ ôïõ ìõóôéêïý êëåéäéïý óôï `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "åããñáöÞ ôïõ ìõóôéêïý êëåéäéïý óôï `%s'\n"
 
 #, c-format
@@ -3949,11 +3809,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "äå âñÝèçêå åããñÜøéìç ìõóôéêÞ êëåéäïèÞêç: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "áäõíáìßá åããñáöÞò äçìüóéáò êëåéäïèÞêçò `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "áäõíáìßá åããñáöÞò ìõóôéêÞò êëåéäïèÞêçò `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -4001,11 +3861,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "äéáãñáöÞ block êëåéäéþí áðÝôõ÷å: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôïõ `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "ÓÇÌÅÉÙÓÇ: ôï ìõóôéêü êëåéäß %08lX Ýëçîå óôéò %s\n"
 
 msgid "never     "
@@ -4047,15 +3907,11 @@ msgstr "      
 msgid "      Key fingerprint ="
 msgstr "     Áðïôýðùìá êëåéäéïý ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "%s õðïãñáöÞ, áëãüñéèìïò ðåñßëçøçò %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "èùñÜêéóç áðÝôõ÷å: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4073,7 +3929,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Ðáñáêáëþ äéïñèþóôå áõôÞ ôçí ðéèáíÞ \"ôñýðá\" áóöáëåßáò\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "Ýëåã÷ïò êëåéäïèÞêçò `%s'\n"
 
 #, fuzzy, c-format
@@ -4111,7 +3967,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ïé åðéëïãåò óôï `%s' äåí åßíáé åíåñãÝò óå áõôÞ ôçí åêôÝëåóç\n"
 
@@ -4179,10 +4035,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "keyserver ëÞøç áðÝôõ÷å: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4190,11 +4042,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4209,6 +4061,10 @@ msgstr "
 msgid "keyserver internal error\n"
 msgstr "óöÜëìá äéáêïìéóôÞ êëåéäéþí"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "keyserver ëÞøç áðÝôõ÷å: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4382,10 +4238,6 @@ msgid "unknown"
 msgstr "Üãíùóôï"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Áäõíáìßá åëÝã÷ïõ ôçò õðïãñáöÞò: %s\n"
 
@@ -4408,7 +4260,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "ìç Ýãêõñï ñéæéêü(root) ðáêÝôï áíé÷íåýôçêå óôï proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "áäõíáìßá ðñüóâáóçò ôïõ áñ÷åßïõ: %s\n"
 
 #, fuzzy, c-format
@@ -4439,11 +4291,6 @@ msgstr ""
 "ï åîáíáãêáóìüò ôïõ áëãüñéèìïõ ðåñßëçøçò %s (%d) ðáñáâéÜæåé ôéò\n"
 "ðñïåðéëïãÝò ôïõ ðáñáëÞðôç\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s õðïãñáöÞ, áëãüñéèìïò ðåñßëçøçò %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "ôï âýóìá ôïõ êñõðôáëãüñéèìïõ IDEA äåí õðÜñ÷åé\n"
 
@@ -4475,15 +4322,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: \"%s\" åßíáé ìéá ìç óõíåéóôþìåíç åðéëïãÞ\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: \"%s\" åßíáé ìéá ìç óõíåéóôþìåíç åðéëïãÞ\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: \"%s\" åßíáé ìéá ìç óõíåéóôþìåíç åðéëïãÞ\n"
-
 msgid "Uncompressed"
 msgstr "Áóõìðßåóôï"
 
@@ -4497,15 +4335,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "áõôü ôï ìÞíõìá ßóùò äåí ìðïñåß íá ÷ñçóéìïðïéçèåß áðü %s\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "áíÜãíùóç åðéëïãþí áðü `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "Üãíùóôïò ðñïêáèïñéóìÝíïò ðáñáëÞðôçò `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Ôï áñ÷åßï `%s' õðÜñ÷åé Þäç. "
 
 #, fuzzy
@@ -4522,17 +4360,16 @@ msgstr "
 msgid "writing to stdout\n"
 msgstr "åããñáöÞ óôçí stdout\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "õðüèåóç õðïãåãñáììÝíùí äåäïìÝíùí óôï `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "äçìéïõñãÞèçêå íÝï áñ÷åßï åðéëïãþí `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "ÐÑÏÅÉÄÏÐÏÉÇÓÇ: ïé åðéëïãåò óôï `%s' äåí åßíáé åíåñãÝò óå áõôÞ ôçí åêôÝëåóç\n"
 
@@ -4548,10 +4385,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "õðïðáêÝôï ôýðïõ %d Ý÷åé ïñéóìÝíï ôï êñéôéêü bit\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "ðñüâëçìá ìå ôïí agent: agent åðéóôñÝöåé 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (êýñéï êëåéäß, ID %08lX)"
 
@@ -4575,6 +4408,10 @@ msgid "cancelled by user\n"
 msgstr "áêõñþèçêå áðü ôï ÷ñÞóôç\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "ðñüâëçìá ìå ôïí agent: agent åðéóôñÝöåé 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4608,7 +4445,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "ÐëçêôñïëïãÞóôå Ýíá üíïìá áñ÷åßïõ ãéá ôï photo ID: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "áäõíáìßá ðñüóâáóçò ôïõ áñ÷åßïõ: %s\n"
 
 #, c-format
@@ -4620,7 +4457,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Óßãïõñá èÝëåôå áêüìá íá ôï ÷ñçóéìïðïéÞóåôå; (y/N) "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\" äåí åßíáé JPEG áñ÷åßï\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4650,16 +4487,6 @@ msgstr "
 msgid "revocation comment: "
 msgstr "ó÷üëéï áíÜêëçóçò:"
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4777,11 +4604,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Óçìåßùóç: Áõôü ôï êëåéäß Ý÷åé áðåíåñãïðïéçèåß.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4886,7 +4713,7 @@ msgid "no signed data\n"
 msgstr "äåí õðÜñ÷ïõí õðïãåãñáììÝíá äåäïìÝíá\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "áäõíáìßá ðñüóâáóçò õðïãåãñáììÝíùí äåäïìÝíùí `%s'\n"
 
 #, fuzzy, c-format
@@ -5205,7 +5032,7 @@ msgstr ""
 "# (×ñÞóç ôïõ \"gpg --import-ownertrust\" ãéá åðáíáöïñÜ ôïõò)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
 
 #, fuzzy
@@ -5224,25 +5051,17 @@ msgid "ownertrust value missing"
 msgstr "åéóáãùãÞ ôùí ôéìþí åìðéóôïóýíçò"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "óöÜëìá óôçí åýñåóç ôçò åããñáöÞò åìðéóôïóýíçò: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "óöÜëìá áíÜãíùóçò: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "trustdb: sync áðÝôõ÷å: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "áäõíáìßá äçìéïõñãßáò ôïõ `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "áäõíáìßá ðñüóâáóçò ôïõ `%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb rec %lu: áðïôõ÷ßá lseek: %s\n"
@@ -5254,13 +5073,21 @@ msgstr "trustdb rec %lu: 
 msgid "trustdb transaction too large\n"
 msgstr "ðïëý ìåãÜëç óõíáëëáãÞ trustdb\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "áäõíáìßá êëåéóßìáôïò ôïõ `%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: ï öÜêåëïò äåí õðÜñ÷åé!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "áäõíáìßá êëåéóßìáôïò ôïõ `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "áäõíáìßá äçìéïõñãßáò ôïõ `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "áäõíáìßá ðñüóâáóçò ôïõ `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5346,7 +5173,7 @@ msgid "input line longer than %d characters\n"
 msgstr "ãñáììÞ åéóüäïõ ìåãáëýôåñç áðü %d ÷áñáêôÞñåò\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' äåí åßíáé Ýãêõñï ìáêñý keyID\n"
 
 #, fuzzy, c-format
@@ -5389,14 +5216,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5448,11 +5267,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "åðüìåíïò Ýëåã÷ïò ôçò trustdb èá ãßíåé óôéò %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "äåí õðÜñ÷åé áíÜãêç ãéá Ýëåã÷ï ôçò trustdb\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "äåí õðÜñ÷åé áíÜãêç ãéá Ýëåã÷ï ôçò trustdb\n"
 
 #, fuzzy, c-format
@@ -5524,11 +5343,6 @@ msgid "missing argument"
 msgstr "ìç Ýãêõñï üñéóìá"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "ìç Ýãêõñç èùñÜêéóç"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "óõãêñïõüìåíåò åíôïëÝò\n"
 
@@ -5548,10 +5362,6 @@ msgstr "
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "ìç Ýãêõñåò åðéëïãÝò åéãáãùãÞò\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5580,8 +5390,12 @@ msgstr "
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "âñÞêáôå Ýíá bug ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5589,15 +5403,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "áäõíáìßá ðñüóâáóçò ôïõ áñ÷åßïõ: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "èùñÜêéóç áðÝôõ÷å: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò êáôáëüãïõ `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "áäõíáìßá åããñáöÞò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 #, c-format
@@ -5615,7 +5429,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "ôï äçìüóéï êëåéäß %08lX äåí âñÝèçêå: %s\n"
 
 #, fuzzy, c-format
@@ -5632,11 +5446,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "×ñÞóç: gpg [åðéëïãÝò] [áñ÷åßá] (-h ãéá âïÞèåéá)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "×ñÞóç: gpg [åðéëïãÝò] [áñ÷åßá] (-h ãéá âïÞèåéá)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5765,9 +5578,6 @@ msgstr "
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5778,14 +5588,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "áëëáãÞ ôçò öñÜóçò êëåéäß"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "áëëáãÞ ôçò öñÜóçò êëåéäß"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ ìðëïê êëåéäéþí: %s\n"
 
@@ -5852,9 +5654,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "äå âñÝèçêáí Ýãêõñá OpenPGP äåäïìÝíá.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "áëëáãÞ ôçò öñÜóçò êëåéäß"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5890,16 +5691,13 @@ msgstr "
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "óõãêñïõüìåíåò åíôïëÝò\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "×ñÞóç: gpg [åðéëïãÝò] [áñ÷åßá] (-h ãéá âïÞèåéá)"
@@ -5909,7 +5707,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5929,7 +5727,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5965,7 +5763,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "áäõíáìßá ðñüóâáóçò óôï `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5994,7 +5792,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "äéáãñáöÞ block êëåéäéþí áðÝôõ÷å: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "áðïôõ÷ßá áñ÷éêïðïßçóçò ôçò TrustDB: %s\n"
 
 #, fuzzy
@@ -6184,16 +5982,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "áäõíáìßá åããñáöÞò ìõóôéêÞò êëåéäïèÞêçò `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6215,11 +6013,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6227,11 +6025,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Ìç Ýãêõñç äéåýèõíóç Email\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôçò êëåéäïèÞêçò `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6302,7 +6100,7 @@ msgid "No subject name given\n"
 msgstr "(Äåí äþèçêå ðåñéãñáöÞ)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6311,7 +6109,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "ìç Ýãêõñïò áëãüñéèìïò  hash `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6357,7 +6155,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "ôï êëåéäß '%s' äå âñÝèçêå: %s\n"
 
 #, fuzzy, c-format
@@ -6365,11 +6163,11 @@ msgid "error locking keybox: %s\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ ìðëïê êëåéäéþí: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Ðéóôïðïéçôéêü áíÜêëçóçò äçìéïõñãÞèçêå.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "ç ðñïåðéëïãÞ %c%lu áíôéãñÜöôçêå\n"
 
 #, fuzzy, c-format
@@ -6406,6 +6204,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "áëëáãÞ ôçò öñÜóçò êëåéäß"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "äçìéïõñãßá ascii èùñáêéóìÝíçò åîüäïõ"
 
@@ -6483,8 +6285,8 @@ msgstr "
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Óýíôáîç: gpg [åðéëïãÝò] [áñ÷åßá]\n"
 "õðïãñáöÞ, Ýëåã÷ïò, êñõðôïãñÜöçóç Þ áðïêñõðôïãñÜöçóç\n"
@@ -6495,11 +6297,11 @@ msgid "usage: gpgsm [options] "
 msgstr "÷ñÞóç: gpg [åðéëïãÝò] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "áäõíáìßá óýíäåóçò óôï `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "Üãíùóôïò ðñïêáèïñéóìÝíïò ðáñáëÞðôçò `%s'\n"
 
 #, fuzzy, c-format
@@ -6522,11 +6324,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "åããñáöÞ óôï  `%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "áäõíáìßá êëåéóßìáôïò ôïõ `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6543,6 +6345,10 @@ msgstr "
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "áðïôõ÷ßá áñ÷éêïðïßçóçò ôçò TrustDB: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "óöÜëìá óôç äçìéïõñãßá ôçò öñÜóçò êëåéäß: %s\n"
@@ -6556,11 +6362,14 @@ msgid "error reading input: %s\n"
 msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò ôçò êëåéäïèÞêçò `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "êëåéäïèÞêç `%s' äçìéïõñãÞèçêå\n"
 
 #, fuzzy
@@ -6594,11 +6403,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "óöÜëìá: ìç Ýãêõñï áðïôýðùìá\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6719,7 +6528,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "Üãíùóôïò ðñïêáèïñéóìÝíïò ðáñáëÞðôçò `%s'\n"
 
 #, fuzzy, c-format
@@ -6950,7 +6759,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "áäõíáìßá ðñüóâáóçò ôïõ áñ÷åßïõ: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "áäõíáìßá äçìéïõñãßáò êáôáëüãïõ `%s': %s\n"
 
 #, fuzzy, c-format
@@ -7046,17 +6855,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "óöÜëìá êáôÜ ôçí áíÜãíùóç ôïõ `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "áðïôõ÷ßá áñ÷éêïðïßçóçò ôçò TrustDB: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "ÅíôïëÞ> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "ç trustdb åßíáé öèáñìÝíç - ÷ñçóéìïðïéåßóôå ôï \"gpg --fix-trustdb\".\n"
@@ -7592,6 +7390,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "ìç Ýãêõñï ðáêÝôï"
 
+#~ msgid "invalid armor"
+#~ msgstr "ìç Ýãêõñç èùñÜêéóç"
+
 #~ msgid "no such user id"
 #~ msgstr "Üãíùóôç ôáõôüôçôá ÷ñÞóôç (user id)"
 
@@ -7601,6 +7402,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "÷ñÞóç ëÜèïò ìõóôéêïý êëåéäéïý"
 
+#~ msgid "not supported"
+#~ msgstr "äåí õðïóôçñßæåôáé"
+
 #~ msgid "bad key"
 #~ msgstr "êáêü êëåéäß"
 
@@ -7616,6 +7420,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "óöÜëìá äçìéïõñãßáò áñ÷åßïõ"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "ìç Ýãêõñç öñÜóç êëåéäß"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "ìç õëïðïéçìÝíïò áëãüñéèìïò äçìïóßïõ êëåéäéïý"
 
index 911274d..07c1497 100644 (file)
--- a/po/eo.po
+++ b/po/eo.po
@@ -1,8 +1,6 @@
 # Mesaøoj por la programo GnuPG
 # Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 # Edmund GRIMLEY EVANS <edmundo@rano.org>, 2000-2002.
-#                      !--- psbl.surriel.com rejected (2011-01-11)
-# Designated-Translator: none
 #
 msgid ""
 msgstr ""
@@ -11,7 +9,6 @@ msgstr ""
 "PO-Revision-Date: 2002-04-14 14:33+0100\n"
 "Last-Translator: Edmund GRIMLEY EVANS <edmundo@rano.org>\n"
 "Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
-"Language: eo\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-3\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -20,42 +17,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "malsukcesis doni komencajn valorojn al fido-datenaro: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to create a sign and encrypt key? "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Æu vi vere volas krei subskriban kaj æifran þlosilon? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "nevalida pasfrazo"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -81,9 +42,6 @@ msgid ""
 "this session"
 msgstr "Bonvolu doni la pasfrazon; tio estas sekreta frazo \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -120,11 +78,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "protekto-metodo %d%s ne estas realigita\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "ne povas krei '%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "ne povas malfermi '%s': %s\n"
 
 #, fuzzy, c-format
@@ -151,31 +109,19 @@ msgstr "forvi
 msgid "error writing key: %s\n"
 msgstr "eraro dum skribado de þlosilaro '%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Bonvolu doni la pasfrazon; tio estas sekreta frazo \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "þanøi la pasfrazon"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Bonvolu doni la pasfrazon; tio estas sekreta frazo \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -203,7 +149,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -291,7 +237,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Vi bezonas pasfrazon por protekti vian sekretan þlosilon.\n"
 "\n"
@@ -309,10 +255,10 @@ msgstr ""
 "Opcioj:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -367,26 +313,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "eraro dum kreado de pasfrazo: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "ne realigita"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "ne realigita"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "eraro dum kreado de pasfrazo: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -408,7 +343,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -416,23 +351,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTO: mankas implicita opcio-dosiero '%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "opcio-dosiero '%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "legas opciojn el '%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "eraro dum kreado de '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "%s: ne povas krei dosierujon: %s\n"
 
 msgid "name of socket too long\n"
@@ -443,7 +378,7 @@ msgid "can't create socket: %s\n"
 msgstr "ne povas krei %s: %s\n"
 
 #, fuzzy, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "Valida atestilrevoko"
 
 #, fuzzy
@@ -455,7 +390,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "eraro dum kreado de pasfrazo: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "eraro dum sendo al '%s': %s\n"
 
 #, fuzzy, c-format
@@ -463,19 +398,19 @@ msgid "listen() failed: %s\n"
 msgstr "aktualigo malsukcesis: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "skribas sekretan þlosilon al '%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: dosierujo kreita\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "fido-datenaro: lego malsukcesis (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: ne povas krei dosierujon: %s\n"
 
 #, fuzzy, c-format
@@ -583,31 +518,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "eraro dum kreado de pasfrazo: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "eraro dum legado de '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "þlosilo '%s' ne trovita: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "sekretaj þlosilpartoj ne estas disponataj\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "kiraso: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "eraro dum legado de '%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -695,15 +630,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "eraro dum skribado de sekreta þlosilaro '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "eraro dum legado de '%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "eraro dum legado de '%s': %s\n"
 
 #, fuzzy, c-format
@@ -718,7 +653,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent ne estas disponata en æi tiu sesio\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "ne povas konektiøi al '%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -796,10 +731,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -826,22 +757,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "Bona atestilo"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "Bona atestilo"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "Bona atestilo"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "Bona atestilo"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "Valida atestilrevoko"
 
@@ -886,26 +801,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "nevalida kompendi-metodo '%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Æi tiu þlosilo eksvalidiøos je %s.\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "nevalida kompendi-metodo '%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "protekto-metodo %d%s ne estas realigita\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "kontrolo de subskribo estas malþaltita\n"
 
@@ -914,11 +813,11 @@ msgid "Signature available"
 msgstr "Æi tiu þlosilo eksvalidiøos je %s.\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Bona subskribo de \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "nevalida kompendi-metodo '%s'\n"
 
 #, fuzzy, c-format
@@ -965,7 +864,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Nenia helpo disponata por '%s'"
 
 #, fuzzy
@@ -1142,11 +1041,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "eraro dum kreado de þlosilaro '%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "eraro dum legado de '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "eraro dum skribado de þlosilaro '%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1348,8 +1247,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Komando> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1370,7 +1269,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output ne funkcias por æi tiu komando\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "ne povas malfermi '%s'\n"
 
 #, fuzzy, c-format
@@ -1422,18 +1321,18 @@ msgid "using cipher %s\n"
 msgstr "subskribado malsukcesis: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "'%s' jam densigita\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "AVERTO: '%s' estas malplena dosiero\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr "eblas æifri nur per RSA-þlosiloj de maksimume 2048 bitoj kun --pgp2\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "legas el '%s'\n"
 
 msgid ""
@@ -1491,11 +1390,11 @@ msgid "this platform requires temporary files when calling external programs\n"
 msgstr "%s: eraro dum legado de versiregistro: %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "ne povas malfermi %s: %s\n"
 
 #, fuzzy, c-format
@@ -1513,11 +1412,11 @@ msgid "unable to read external program response: %s\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy
@@ -1583,16 +1482,12 @@ msgstr "tro da registroj en pk-staplo - mal
 msgid "[User ID not found]"
 msgstr "[Uzantidentigilo ne trovita]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "þlosilo %08lX: sekreta þlosilo sen publika þlosilo - ignorita\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "eraro dum kreado de '%s': %s\n"
 
 #, fuzzy
@@ -1611,6 +1506,10 @@ msgstr "estas sekreta 
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "uzas flankan þlosilon %08lX anstataý la æefa þlosilo %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "þlosilo %08lX: sekreta þlosilo sen publika þlosilo - ignorita\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "fari apartan subskribon"
@@ -1653,9 +1552,6 @@ msgstr "listigi sekretajn 
 msgid "generate a new key pair"
 msgstr "krei novan þlosilparon"
 
-msgid "generate a revocation certificate"
-msgstr "krei revokatestilon"
-
 msgid "remove keys from the public keyring"
 msgstr "forigi þlosilojn de la publika þlosilaro"
 
@@ -1671,9 +1567,8 @@ msgstr "subskribi 
 msgid "sign or edit a key"
 msgstr "subskribi aý redakti þlosilon"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "þanøi la pasfrazon"
+msgid "generate a revocation certificate"
+msgstr "krei revokatestilon"
 
 msgid "export keys"
 msgstr "eksporti þlosilojn"
@@ -1772,15 +1667,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Uzado: gpg [opcioj] [dosieroj] (-h por helpo)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintakso: gpg [opcioj] [dosieroj]\n"
 "subskribi, kontroli, æifri aý malæifri\n"
@@ -1813,35 +1703,35 @@ msgid "conflicting commands\n"
 msgstr "malkongruaj komandoj\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1850,11 +1740,11 @@ msgid ""
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "Averto: malsekura posedeco sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1863,11 +1753,11 @@ msgid ""
 msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "Averto: malsekuraj permesoj sur %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "%s: nova opcio-dosiero kreita\n"
 
 msgid "display photo IDs during key listings"
@@ -1908,7 +1798,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Mankas responda subskribo en sekreta þlosilaro\n"
 
 #, fuzzy, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "NOTO: mankas implicita opcio-dosiero '%s'\n"
 
 #, c-format
@@ -1920,11 +1810,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "NOTO: %s ne estas por normala uzado!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s ne estas valida signaro\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s ne estas valida signaro\n"
 
 #, fuzzy
@@ -2109,15 +1999,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s ne havas sencon kun %s!\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "Tiu komando ne eblas en la reøimo %s.\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "Tiu komando ne eblas en la reøimo %s.\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "Tiu komando ne eblas en la reøimo %s.\n"
 
 #, c-format
@@ -2134,7 +2024,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [dosiero]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "malæifrado malsukcesis: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2186,10 +2076,6 @@ msgstr "--lsign-key uzantidentigilo"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key uzantidentigilo [komandoj]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key uzantidentigilo"
-
 #, fuzzy, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "Kreado de þlosiloj malsukcesis: %s\n"
@@ -2219,7 +2105,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "enkirasigo malsukcesis: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "nevalida kompendi-metodo '%s'\n"
 
 msgid "[filename]"
@@ -2262,7 +2148,7 @@ msgid "No help available"
 msgstr "Nenia helpo disponata"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Nenia helpo disponata por '%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2272,10 +2158,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "aktualigi la fido-datenaron"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "aktualigi la fido-datenaron"
 
@@ -2393,13 +2275,6 @@ msgid "key %s: no user ID\n"
 msgstr "þlosilo %08lX: mankas uzantidentigilo\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "ignoris '%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "þlosilo %08lX: mankas subþlosilo por þlosilbindado\n"
 
@@ -2427,11 +2302,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "neniu skribebla þlosilaro trovita: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "skribas al '%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "eraro dum skribado de þlosilaro '%s': %s\n"
 
 #, fuzzy, c-format
@@ -2495,17 +2370,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "þlosilo %08lX: ne þanøita\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "þlosilo '%s' ne trovita: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "þlosilo %08lX: sekreta þlosilo sen publika þlosilo - ignorita\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "skribas sekretan þlosilon al '%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "þlosilo %08lX: sekreta þlosilo sen publika þlosilo - ignorita\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "mankas implicita sekreta þlosilaro: %s\n"
@@ -2548,18 +2419,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "þlosilo %08lX: nevalida mem-subskribo\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "þlosilo %08lX: nerealigita publikþlosila metodo\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "þlosilo %08lX: rekta þlosilsubskribo aldonita\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "þlosilo %08lX: mankas subþlosilo por þlosilbindado\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "þlosilo %08lX: nerealigita publikþlosila metodo\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "þlosilo %08lX: nevalida subþlosila bindado\n"
 
@@ -2639,15 +2506,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "ignorita: sekreta þlosilo jam æeestas\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "eraro dum kreado de þlosilaro '%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "þlosilaro '%s' kreita\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "eraro dum kreado de '%s': %s\n"
 
 #, c-format
@@ -2855,7 +2722,7 @@ msgstr "   (2) Mi malzorge kontrolis.%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Mi tre zorge kontrolis.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr ""
 
 #, fuzzy, c-format
@@ -3132,7 +2999,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Sugesto: Elekti la uzantidentigilojn por subskribi\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "nekonata klaso de subskribo"
 
 #, c-format
@@ -3167,11 +3034,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "ne povas malfermi '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "eraro dum kreado de þlosilaro '%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3259,7 +3126,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Æi tiu þlosilo estas revokebla per %s þlosilo %s%s\n"
 
 #, fuzzy, c-format
@@ -3322,14 +3189,6 @@ msgid ""
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Vi ne povas þanøi la daton de eksvalidiøo de v3-þlosilo\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3562,7 +3421,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "prefero %c%lu ripetita\n"
 
 #, fuzzy
@@ -3578,7 +3437,7 @@ msgid "too many compression preferences\n"
 msgstr "tro da '%c'-preferoj\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "nevalida signo en signoæeno\n"
 
 #, fuzzy
@@ -3821,7 +3680,7 @@ msgid "Invalid character in comment\n"
 msgstr "Nevalida signo en komento\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Vi uzas la signaron '%s'.\n"
 
 #, c-format
@@ -3906,15 +3765,15 @@ msgid "Key generation canceled.\n"
 msgstr "Kreado de þlosiloj nuligita.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "skribas publikan þlosilon al '%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "skribas sekretan þlosilon al '%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "skribas sekretan þlosilon al '%s'\n"
 
 #, c-format
@@ -3926,11 +3785,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "neniu skribebla sekreta þlosilaro trovita: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "eraro dum skribado de publika þlosilaro '%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "eraro dum skribado de sekreta þlosilaro '%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3974,11 +3833,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "forviþo de þlosilbloko malsukcesis: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "ne povas krei '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "NOTO: sekreta þlosilo %08lX eksvalidiøis je %s\n"
 
 msgid "never     "
@@ -4026,15 +3885,11 @@ msgstr "     
 msgid "      Key fingerprint ="
 msgstr "     Þlosilo-fingrospuro ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "%s-subskribo de: %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "enkirasigo malsukcesis: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4052,7 +3907,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Bonvolu ripari æi tiun eblan sekurecproblemon\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "kontrolas þlosilaron '%s'\n"
 
 #, fuzzy, c-format
@@ -4090,7 +3945,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 
 #, fuzzy
@@ -4157,10 +4012,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "listigo de sekretaj þlosiloj malsukcesis: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "neniu þlosilservilo konata (uzu la opcion --keyserver)\n"
 
@@ -4168,11 +4019,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4188,6 +4039,10 @@ msgid "keyserver internal error\n"
 msgstr "þlosilservila eraro"
 
 #, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "listigo de sekretaj þlosiloj malsukcesis: %s\n"
+
+#, fuzzy, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "%s: ne valida þlosilidentigilo\n"
 
@@ -4363,10 +4218,6 @@ msgid "unknown"
 msgstr "nekonata versio"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Ne povas kontroli subskribon: %s\n"
 
@@ -4388,7 +4239,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "nevalida radikpaketo trovita en proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "aktualigo de fido-datenaro malsukcesis: %s\n"
 
 #, fuzzy, c-format
@@ -4415,10 +4266,6 @@ msgstr "%s-subskribo de: %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "NOTO: æifrad-metodo %d ne trovita en preferoj\n"
 
-#, fuzzy, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s-subskribo de: %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "la aldona¼o por la æifro IDEA en æeestas\n"
 
@@ -4450,15 +4297,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "AVERTO: '%s' estas malplena dosiero\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "AVERTO: '%s' estas malplena dosiero\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "AVERTO: '%s' estas malplena dosiero\n"
-
 #, fuzzy
 msgid "Uncompressed"
 msgstr "ne traktita"
@@ -4473,15 +4311,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "æi tiu mesaøo povas ne esti uzebla de PGP 2.x\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "legas opciojn el '%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "nekonata implicita ricevonto '%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Dosiero '%s' ekzistas. "
 
 #, fuzzy
@@ -4498,17 +4336,16 @@ msgstr "Donu novan dosiernomon"
 msgid "writing to stdout\n"
 msgstr "skribas al la normala eligo\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "supozas subskribitajn datenojn en '%s'\n"
 
 #, fuzzy, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "%s: nova opcio-dosiero kreita\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 
 #, c-format
@@ -4523,10 +4360,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "subpaketo de speco %d havas þaltitan \"critical bit\"\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problemo kun agento: agento redonas 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (æefþlosilo %08lX)"
 
@@ -4549,6 +4382,10 @@ msgid "cancelled by user\n"
 msgstr "nuligita de uzanto\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problemo kun agento: agento redonas 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4577,7 +4414,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "ne povas malfermi %s: %s\n"
 
 #, c-format
@@ -4589,7 +4426,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Æu vi estas certa, ke vi ankoraý volas subskribi øin?\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "%s: ne estas fido-datenaro\n"
 
 #, fuzzy
@@ -4623,16 +4460,6 @@ msgstr "Kialo por revoko: "
 msgid "revocation comment: "
 msgstr "Komento pri revoko: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMfFsS"
 
@@ -4748,11 +4575,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Noto: Æi tiu þlosilo estas malþaltita.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4854,7 +4681,7 @@ msgid "no signed data\n"
 msgstr "mankas subskribitaj datenoj\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "ne povas malfermi subskribitan dosieron '%s'\n"
 
 #, fuzzy, c-format
@@ -5160,7 +4987,7 @@ msgid ""
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "eraro dum legado de '%s': %s\n"
 
 #, fuzzy
@@ -5179,25 +5006,17 @@ msgid "ownertrust value missing"
 msgstr "importi posedantofido-valorojn"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "eraro dum legado de dosieruja registro: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "kiraso: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "fido-datenaro: sync malsukcesis: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "ne povas krei '%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "ne povas malfermi '%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "fido-datenaro loko %lu: lseek malsukcesis: %s\n"
@@ -5209,13 +5028,21 @@ msgstr "fido-datenaro loko %lu: skribo malsukcesis (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "fido-datenaro-transakcio tro granda\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "ne povas fermi '%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: dosierujo ne ekzistas!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "ne povas fermi '%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "ne povas krei '%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "ne povas malfermi '%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5301,7 +5128,7 @@ msgid "input line longer than %d characters\n"
 msgstr "enigata linio pli longa ol %d signojn\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "'%s' ne estas valida longa þlosilidentigilo\n"
 
 #, fuzzy, c-format
@@ -5342,14 +5169,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5400,11 +5219,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "sekva kontrolo de fido-datenaro je %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "kontrolo de fido-datenaro ne estas bezonata\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "kontrolo de fido-datenaro ne estas bezonata\n"
 
 #, fuzzy, c-format
@@ -5476,11 +5295,6 @@ msgid "missing argument"
 msgstr "nevalida argumento"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "nevalida kiraso"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "malkongruaj komandoj\n"
 
@@ -5500,10 +5314,6 @@ msgstr "nevalida kiraso"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "nevalida kiraso"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5532,8 +5342,12 @@ msgstr "nevalida kiraso"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "vi trovis cimon ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "eraro dum legado de '%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5541,15 +5355,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "ne povas malfermi %s: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "enkirasigo malsukcesis: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "%s: ne povas krei dosierujon: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "eraro dum skribado de þlosilaro '%s': %s\n"
 
 #, c-format
@@ -5567,7 +5381,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "publika þlosilo %08lX ne trovita: %s\n"
 
 #, fuzzy, c-format
@@ -5584,11 +5398,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Uzado: gpg [opcioj] [dosieroj] (-h por helpo)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Uzado: gpg [opcioj] [dosieroj] (-h por helpo)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5717,9 +5530,6 @@ msgstr "Kialo por revoko: "
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5730,14 +5540,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "þanøi la pasfrazon"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "þanøi la pasfrazon"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "eraro dum legado de þlosilbloko: %s\n"
 
@@ -5804,9 +5606,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "validaj OpenPGP-datenoj ne trovitaj.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "þanøi la pasfrazon"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5843,16 +5644,13 @@ msgstr "tute ne uzi la terminalon"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "malkongruaj komandoj\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Uzado: gpg [opcioj] [dosieroj] (-h por helpo)"
@@ -5862,7 +5660,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5882,7 +5680,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr "malsukcesis meti '%s' en fido-datenaron: %s\n"
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5918,7 +5716,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "ne povas malfermi '%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5947,7 +5745,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "forviþo de þlosilbloko malsukcesis: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "malsukcesis doni komencajn valorojn al fido-datenaro: %s\n"
 
 #, fuzzy
@@ -6148,16 +5946,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "eraro dum skribado de sekreta þlosilaro '%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6179,11 +5977,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6191,11 +5989,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Nevalida retadreso\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "eraro dum kreado de þlosilaro '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "eraro dum kreado de þlosilaro '%s': %s\n"
 
 #, fuzzy, c-format
@@ -6265,7 +6063,7 @@ msgid "No subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6274,7 +6072,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "nevalida kompendi-metodo '%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6323,7 +6121,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "þlosilo '%s' ne trovita: %s\n"
 
 #, fuzzy, c-format
@@ -6331,11 +6129,11 @@ msgid "error locking keybox: %s\n"
 msgstr "eraro dum legado de þlosilbloko: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "ripetita atestilo - forviþita"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "ripetita atestilo - forviþita"
 
 #, fuzzy, c-format
@@ -6372,6 +6170,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "þanøi la pasfrazon"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "krei eligon en askia kiraso"
 
@@ -6449,8 +6251,8 @@ msgstr "Uzado: gpg [opcioj] [dosieroj] (-h por helpo)"
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintakso: gpg [opcioj] [dosieroj]\n"
 "subskribi, kontroli, æifri aý malæifri\n"
@@ -6461,11 +6263,11 @@ msgid "usage: gpgsm [options] "
 msgstr "uzado: gpg [opcioj] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "ne povas konektiøi al '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "nekonata implicita ricevonto '%s'\n"
 
 #, c-format
@@ -6488,11 +6290,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "skribas al '%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "ne povas fermi '%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6509,6 +6311,10 @@ msgstr "Bona atestilo"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "malsukcesis doni komencajn valorojn al fido-datenaro: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "eraro dum kreado de pasfrazo: %s\n"
@@ -6522,11 +6328,14 @@ msgid "error reading input: %s\n"
 msgstr "eraro dum legado de '%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "eraro dum kreado de þlosilaro '%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "þlosilaro '%s' kreita\n"
 
 #, fuzzy
@@ -6560,11 +6369,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "%s: nevalida dosiero-versio %d\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6683,7 +6492,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "nekonata implicita ricevonto '%s'\n"
 
 #, fuzzy, c-format
@@ -6914,7 +6723,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "aktualigo de fido-datenaro malsukcesis: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "%s: ne povas krei dosierujon: %s\n"
 
 #, fuzzy, c-format
@@ -7009,17 +6818,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "eraro dum legado de '%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "malsukcesis doni komencajn valorojn al fido-datenaro: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Komando> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "la fido-datenaro estas fuþita; bonvolu ruli \"gpg --fix-trustdb\".\n"
@@ -7487,6 +7285,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "nevalida paketo"
 
+#~ msgid "invalid armor"
+#~ msgstr "nevalida kiraso"
+
 #~ msgid "no such user id"
 #~ msgstr "uzantidentigilo ne ekzistas"
 
@@ -7496,6 +7297,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "maløusta sekreta þlosilo uzata"
 
+#~ msgid "not supported"
+#~ msgstr "ne realigita"
+
 #~ msgid "bad key"
 #~ msgstr "malbona þlosilo"
 
@@ -7511,6 +7315,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "eraro æe kreo de dosiero"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "nevalida pasfrazo"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "nerealigita publikþlosila metodo"
 
@@ -8136,8 +7943,8 @@ msgstr ""
 
 #~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"
 #~ msgstr ""
-#~ "kontrolas æe profundo %d subskribita=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/"
-#~ "%d\n"
+#~ "kontrolas æe profundo %d subskribita=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%"
+#~ "d\n"
 
 #~ msgid ""
 #~ "Select the algorithm to use.\n"
@@ -8428,6 +8235,9 @@ msgstr ""
 #~ msgid "For info see http://www.gnupg.org"
 #~ msgstr "Por informoj vidu http://www.gnupg.org"
 
+#~ msgid "Do you really want to create a sign and encrypt key? "
+#~ msgstr "Æu vi vere volas krei subskriban kaj æifran þlosilon? "
+
 #~ msgid "can't lock keyring `%s': %s\n"
 #~ msgstr "ne povas þlosi la þlosilaron '%s': %s\n"
 
index a5278bd..0381b6c 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -1,72 +1,27 @@
-# Mensajes en español para GnuPG.
+# Mensajes en español para GnuPG.
 # Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
 # Urko Lusa <ulusa@euskalnet.net>, 1998, 1999.
 #  I've tried to mantain the terminology used by Armando Ramos
 #  <armando@clerval.org> in his PGP 2.3.6i translation.
 #  I also got inspiration from it.po by Marco d'Itri <md@linux.it>
-# Manuel "Venturi" Porras Peralta <venturi@openmailbox.org>, 2014.
+#
+# Jaime Suárez <jsuarez@mundocripto.com>, 2001-2008.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: gnupg 2.0.9\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2014-11-20 11:43+0100\n"
-"Last-Translator: Manuel \"Venturi\" Porras Peralta <venturi@openmailbox."
-"org>\n"
-"Language-Team: Español; Castellano <debian-l10n-spanish@lists.debian.org>\n"
-"Language: es\n"
+"PO-Revision-Date: 2008-12-14 19:34+0100\n"
+"Last-Translator: Jaime Suárez <jaime@mundocripto.com>\n"
+"Language-Team: Spanish <es@li.org>\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 "plural: Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 2.91.6\n"
 
 #, c-format
 msgid "failed to acquire the pinentry lock: %s\n"
-msgstr "fallo al conseguir el bloqueo de entrada de pin: %s\n"
-
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|_Cancel"
-msgstr "|pinentry-label|_Cancelar"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_OK"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|PIN:"
-msgstr "|pinentry-label|PIN:"
-
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|_Cancelar"
-
-#, fuzzy
-#| msgid "Do you really want to create a sign and encrypt key? "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "¿De verdad quiere crear una clave de firma y cifrado? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "frase contraseña incorrecta"
+msgstr "no pude conseguir el bloqueo de entrada de pin: %s\n"
 
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
@@ -80,24 +35,21 @@ msgstr "Calidad:"
 #. translate this entry, a default english text (see source)
 #. will be used.
 msgid "pinentry.qualitybar.tooltip"
-msgstr "pinentry.qualitybar.tooltip"
+msgstr "barra de calidad, entrada de pin"
 
 msgid ""
 "Please enter your PIN, so that the secret key can be unlocked for this "
 "session"
 msgstr ""
-"Introduzca su PIN para desbloquear la clave secreta durante esta sesión"
+"Por favor introduzca su PIN para desbloquear la clave secreta de esta sesión"
 
 msgid ""
 "Please enter your passphrase, so that the secret key can be unlocked for "
 "this session"
 msgstr ""
-"Introduzca la contraseña para desbloquear la clave secreta durante esta "
-"sesión"
+"Por favor introduzca la frase contraseña para desbloquear la clave secreta "
+"de esta sesión"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (intento %d de %d)"
@@ -106,10 +58,10 @@ msgid "PIN too long"
 msgstr "PIN demasiado largo"
 
 msgid "Passphrase too long"
-msgstr "Contraseña demasiado larga"
+msgstr "Frase contraseña demasiado larga"
 
 msgid "Invalid characters in PIN"
-msgstr "Caracteres inválidos en el PIN"
+msgstr "Caracteres inválidos en el PIN"
 
 msgid "PIN too short"
 msgstr "PIN demasiado corto"
@@ -117,45 +69,45 @@ msgstr "PIN demasiado corto"
 msgid "Bad PIN"
 msgstr "PIN incorrecto"
 
-# ¿Por qué no frase de paso?
-# Porque todo el mundo sabe lo que es una contraseña
+# ¿Por qué no frase de paso?
+# Porque todo el mundo sabe lo que es una contraseña
 # y una "frase de paso" no. Soy consciente de que se
 # traduce igual password y passphrase pero el contexto
-# permite saber de lo que se está hablando.
-# No sé, no sé.
-# ¿Por qué los ingleses entonces sí que saben lo que es un "passphrase"?
-# ¿Es que son más listos? :-)
+# permite saber de lo que se está hablando.
+# No sé, no sé.
+# ¿Por qué los ingleses entonces sí que saben lo que es un "passphrase"?
+# ¿Es que son más listos? :-)
 #
 msgid "Bad Passphrase"
-msgstr "Contraseña errónea"
+msgstr "Frase contraseña errónea"
 
-# ¿Por qué no frase de paso?
-# Porque todo el mundo sabe lo que es una contraseña
+# ¿Por qué no frase de paso?
+# Porque todo el mundo sabe lo que es una contraseña
 # y una "frase de paso" no. Soy consciente de que se
 # traduce igual password y passphrase pero el contexto
-# permite saber de lo que se está hablando.
-# No sé, no sé.
-# ¿Por qué los ingleses entonces sí que saben lo que es un "passphrase"?
-# ¿Es que son más listos? :-)
+# permite saber de lo que se está hablando.
+# No sé, no sé.
+# ¿Por qué los ingleses entonces sí que saben lo que es un "passphrase"?
+# ¿Es que son más listos? :-)
 #
 msgid "Passphrase"
-msgstr "Contraseña"
+msgstr "Frase contraseña"
 
 #, c-format
 msgid "ssh keys greater than %d bits are not supported\n"
-msgstr "no pueden usarse claves ssh de más de %d bits\n"
+msgstr "no pueden usarse claves ssh de más de %d bits\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
-msgstr "no se puede crear `%s': %s\n"
+msgid "can't create '%s': %s\n"
+msgstr "no se puede crear %s: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "no se puede abrir `%s': %s\n"
 
 #, c-format
 msgid "error getting serial number of card: %s\n"
-msgstr "error obteniendo el número de serie de la tarjeta: %s\n"
+msgstr "error obteniendo el número de serie de la tarjeta: %s\n"
 
 #, c-format
 msgid "detected card with S/N: %s\n"
@@ -164,8 +116,8 @@ msgstr "detectada tarjeta con S/N: %s\n"
 #, c-format
 msgid "error getting default authentication keyID of card: %s\n"
 msgstr ""
-"error obteniendo identificador de la clave de autenticación predeterminado "
-"de la tarjeta: %s\n"
+"error obteniendo ID de la clave por defecto para autenticaren la tarjeta: %"
+"s\n"
 
 #, c-format
 msgid "no suitable card key found: %s\n"
@@ -173,53 +125,45 @@ msgstr "no se encuentra una clave de tarjeta adecuada: %s\n"
 
 #, c-format
 msgid "shadowing the key failed: %s\n"
-msgstr "el cifrado de la clave falló: %s\n"
+msgstr "el sombreado de la clave falló: %s\n"
 
 #, c-format
 msgid "error writing key: %s\n"
 msgstr "error escribiendo clave: %s\n"
 
 #, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-"Un proceso ssh solicitó utilizar la clave%%0A  %s%%0A  (%s)%%0A¿Desea "
-"permitirlo?"
-
-msgid "Allow"
-msgstr "Permitir"
-
-msgid "Deny"
-msgstr "No permitir"
-
-#, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
-msgstr "Introduzca la contraseña para la clave ssh%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
+msgstr "Por favor introduzca la frase contraseña para la clave ssh%0A %c"
 
 msgid "Please re-enter this passphrase"
-msgstr "Vuelva a introducir contraseña"
+msgstr "Por favor vuelva a introducir frase contraseña"
 
 #, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
-"Introduzca una contraseña para proteger la clave secreta recibida%%0A   %s"
-"%%0A   %s%%0Aen el almacén de claves del agente gpg"
+"Por favor introduzca una frase contraseña para proteger la clave "
+"secretarecibida%%0A  %s%%0Aen el almacen de claves del agente gpg"
 
 msgid "does not match - try again"
-msgstr "no coincide - inténtelo de nuevo"
+msgstr "no coincide - reinténtelo"
 
 #, c-format
 msgid "failed to create stream from socket: %s\n"
 msgstr "fallo al crear un flujo desde el socket: %s\n"
 
+#, fuzzy
 msgid "Please insert the card with serial number"
-msgstr "Inserte la tarjeta con número de serie"
+msgstr ""
+"Por favor retire la tarjeta actual e inserte la de número de serie:\n"
+"   %.*s\n"
 
+#, fuzzy
 msgid "Please remove the current card and insert the one with serial number"
-msgstr "Retire tarjeta actual e inserte la que tiene número de serie"
+msgstr ""
+"Por favor retire la tarjeta actual e inserte la de número de serie:\n"
+"   %.*s\n"
 
 msgid "Admin PIN"
 msgstr "PIN del Administrador"
@@ -227,36 +171,38 @@ msgstr "PIN del Administrador"
 #. TRANSLATORS: A PUK is the Personal Unblocking Code
 #. used to unblock a PIN.
 msgid "PUK"
-msgstr "PUK"
+msgstr ""
 
 msgid "Reset Code"
-msgstr "Código de Reinicio"
+msgstr "Código de Reinicio"
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
-msgstr "%s%%0A%%0AUse el teclado del lector como entrada."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
+msgstr ""
 
 msgid "Repeat this Reset Code"
-msgstr "Repita este Código de Reinicio"
+msgstr "Repita este Código de Reinicio"
 
+#, fuzzy
 msgid "Repeat this PUK"
-msgstr "Repita este PUK"
+msgstr "Repita este PIN"
 
 msgid "Repeat this PIN"
 msgstr "Repita este PIN"
 
 msgid "Reset Code not correctly repeated; try again"
-msgstr "Código de Reinicio repetido incorrectamente; inténtelo de nuevo"
+msgstr "Código de Reinicio repetido incorrectamente; inténtelo de nuevo"
 
+#, fuzzy
 msgid "PUK not correctly repeated; try again"
-msgstr "PUK repetido incorrectamente; inténtelo de nuevo"
+msgstr "PIN repetido incorrectamente; inténtelo de nuevo"
 
 msgid "PIN not correctly repeated; try again"
-msgstr "PIN repetido incorrectamente; inténtelo de nuevo"
+msgstr "PIN repetido incorrectamente; inténtelo de nuevo"
 
 #, c-format
 msgid "Please enter the PIN%s%s%s to unlock the card"
-msgstr "Introduzca el PIN%s%s%s para desbloquear la tarjeta"
+msgstr "Por favor introduzca el PIN%s%s%s para desbloquear la tarjeta"
 
 #, c-format
 msgid "error creating temporary file: %s\n"
@@ -267,7 +213,7 @@ msgid "error writing to temporary file: %s\n"
 msgstr "error escribiendo en el fichero temporal: %s\n"
 
 msgid "Enter new passphrase"
-msgstr "Introduzca nueva contraseña"
+msgstr "Introduzca nueva frase contraseña"
 
 msgid "Take this one anyway"
 msgstr "Tomar esta de todas formas"
@@ -280,11 +226,11 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
 "at least %u characters long."
 msgstr[0] ""
-"Aviso: ha introducido una contraseña insegura.%%0AUna contraseña debe tener "
-"al menos %u carácter."
+"Aviso: ha introducido una frase contraseña insegura.%%0AUna frase contraseña "
+"debe tener al menos %u carácter."
 msgstr[1] ""
-"Aviso: ha introducido una contraseña insegura.%%0AUna contraseña debe tener "
-"al menos %u caracteres."
+"Aviso: ha introducido una frase contraseña insegura.%%0AUna frase contraseña "
+"debe tener al menos %u caracteres."
 
 #, c-format
 msgid ""
@@ -294,44 +240,44 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
 "contain at least %u digits or%%0Aspecial characters."
 msgstr[0] ""
-"Aviso: Ha introducido una contraseña insegura.%%0AUna frasecontraseña debe "
-"tener al menos %u digito o%%0Acarácter especial."
+"Aviso: Ha introducido una frase contraseña insegura.%%0AUna frasecontraseña "
+"debe tener al menos %u digito o%%0Acarácter especial."
 msgstr[1] ""
-"Aviso: Ha introducido una contraseña insegura.%%0AUna frasecontraseña debe "
-"tener al menos %u digitos o%%0Acaracteres especiales."
+"Aviso: Ha introducido una frase contraseña insegura.%%0AUna frasecontraseña "
+"debe tener al menos %u digitos o%%0Acaracteres especiales."
 
 #, c-format
 msgid ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
 "a known term or match%%0Acertain pattern."
 msgstr ""
-"Aviso: ha introducido una contraseña insegura.%%0AUna contraseña no puede "
-"ser un término conocido%%0Ao ajustarse a cierto patrón."
+"Aviso: ha introducido una frase contraseña insegura.%%0AUna frase contraseña "
+"no puede ser un término conocido%%0Ao ajustarse a cierto patrón."
 
 #, c-format
 msgid ""
 "You have not entered a passphrase!%0AAn empty passphrase is not allowed."
 msgstr ""
-"¡No ha introducido una contraseña!%0AnNo se permiten frases contraseña en "
-"blanco."
+"¡No ha introducido una frase contraseña!%0AnNo se permiten frases contraseña "
+"en blanco."
 
 #, c-format
 msgid ""
 "You have not entered a passphrase - this is in general a bad idea!%0APlease "
 "confirm that you do not want to have any protection on your key."
 msgstr ""
-"No ha introducido una contraseña -¡esto suele ser una mala idea!%0AConfirme "
-"que no desea ninguna protección para su clave."
+"No ha introducido una frase contraseña -¡esto es en general una mala idea!%"
+"0Apor favor confirme que no quiere ninguna protección para su clave."
 
 msgid "Yes, protection is not needed"
-msgstr "Sí, no se necesita protección"
+msgstr "Sí, no se necesita protección"
 
 #, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
-msgstr "Introduzca contraseña para%0Aproteger su nueva clave"
+msgid "Please enter the passphrase to%0Ato protect your new key"
+msgstr "Por favor introduzca frase contraseña para%0Aproteger su nueva clave"
 
 msgid "Please enter the new passphrase"
-msgstr "Escriba la nueva contraseña"
+msgstr "Por favor escriba la nueva frase contraseña"
 
 msgid ""
 "@Options:\n"
@@ -340,17 +286,17 @@ msgstr ""
 "@Opciones:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "ejecutar en modo demonio (segundo plano)"
-
 msgid "run in server mode (foreground)"
 msgstr "ejecutar en modo servidor (primer plano)"
 
+msgid "run in daemon mode (background)"
+msgstr "ejecutar en modo demonio (segundo plano)"
+
 msgid "verbose"
-msgstr "detallado"
+msgstr "prolijo"
 
 msgid "be somewhat more quiet"
-msgstr "algo más discreto"
+msgstr "algo más discreto"
 
 msgid "sh-style command output"
 msgstr "salida de datos estilo sh"
@@ -365,13 +311,13 @@ msgid "do not detach from the console"
 msgstr "no independizarse de la consola"
 
 msgid "do not grab keyboard and mouse"
-msgstr "no acaparar teclado y ratón"
+msgstr "no acaparar teclado y ratón"
 
 msgid "use a log file for the server"
 msgstr "usar un fichero log para el servidor"
 
 msgid "use a standard location for the socket"
-msgstr "usar una localización estándar para el socket"
+msgstr "usar una localización estándar para el socket"
 
 msgid "|PGM|use PGM as the PIN-Entry program"
 msgstr "|PGM|usar PGM como el programa para entrada de PIN"
@@ -389,36 +335,29 @@ msgid "ignore requests to change the X display"
 msgstr "ignorar peticiones de cambiar el display X"
 
 msgid "|N|expire cached PINs after N seconds"
-msgstr "|N|los PINs en la caché expiran en N segundos"
+msgstr "|N|los PINs en la caché expiran en N segundos"
 
 msgid "do not use the PIN cache when signing"
-msgstr "no usar el caché de PINs al firmar"
+msgstr "no usar el caché de PINs al firmar"
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr "permitir que los clientes marquen claves como \"fiables\""
 
 msgid "allow presetting passphrase"
-msgstr "permitir preestablecer contraseña"
-
-msgid "enable ssh support"
-msgstr "permitir emulación de ssh-agent"
+msgstr "permitir preestablecer frase contraseña"
 
-msgid "enable putty support"
-msgstr "no disponible"
-
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "no permite reusar antiguas frases contraseña"
+msgid "enable ssh-agent emulation"
+msgstr "permitir emulación de ssh-agent"
 
 msgid "|FILE|write environment settings also to FILE"
-msgstr "|FICHERO|escribir variables de entorno también en FICHERO"
+msgstr "|FICHERO|escribir variables de entorno también en FICHERO"
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
+#, fuzzy
 msgid "Please report bugs to <@EMAIL@>.\n"
-msgstr "Informe de posibles fallos del programa a <@EMAIL@>.\n"
+msgstr "Por favor, informe de posibles \"bugs\" a <"
 
 msgid "Usage: gpg-agent [options] (-h for help)"
 msgstr "Uso: gpg-agent [opciones] (-h para ayuda)"
@@ -431,31 +370,31 @@ msgstr ""
 "Manejo de claves privadas por GnuPG\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
-msgstr "el nivel de depuración `%s` no es válido\n"
+msgid "invalid debug-level '%s' given\n"
+msgstr "el nivel de depuración `%s` no es válido\n"
 
 #, c-format
 msgid "%s is too old (need %s, have %s)\n"
 msgstr "%s es demasiado antiguo (necesita %s, tiene %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTA: no existe el fichero de opciones predefinido `%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "fichero de opciones `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "leyendo opciones desde `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "error creando `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "no se puede crear el directorio `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -466,42 +405,42 @@ msgid "can't create socket: %s\n"
 msgstr "no se puede crear el socket: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "el nombre de socket `%s' es demasiado largo\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
-msgstr "ya hay un agente gpg ejecutándose - no se inicia otro\n"
+msgstr "ya hay un agente gpg ejecutándose - no se inicia otro\n"
 
 msgid "error getting nonce for the socket\n"
-msgstr "error obteniendo valor único para el socket\n"
+msgstr "error obteniendo valor único para el socket\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "error enlazando el socket con `%s': %s\n"
 
 #, c-format
 msgid "listen() failed: %s\n"
-msgstr "listen() falló: %s\n"
+msgstr "listen() falló: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "escuchando el socket `%s'\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "directorio `%s' creado\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
-msgstr "stat() falló para `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
+msgstr "stat() falló para `%s': %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "no puede usar `%s' como directorio personal\n"
 
 #, c-format
 msgid "error reading nonce on fd %d: %s\n"
-msgstr "error leyendo valor único en el descriptor %d: %s\n"
+msgstr "error leyendo valor único en el descriptor %d: %s\n"
 
 #, c-format
 msgid "handler 0x%lx for fd %d started\n"
@@ -521,7 +460,7 @@ msgstr "manejador ssh 0x%lx para el descriptor %d finalizado\n"
 
 #, c-format
 msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "pth_select falló: %s - espero 1s\n"
+msgstr "pth_select falló: %s - espero 1s\n"
 
 # msgstr "clave %08lX: %d nuevas subclaves\n"
 #, c-format
@@ -529,14 +468,14 @@ msgid "%s %s stopped\n"
 msgstr "%s %s detenido\n"
 
 msgid "no gpg-agent running in this session\n"
-msgstr "no hay un agente gpg ejecutándose en esta sesión\n"
+msgstr "no hay un agente gpg ejecutándose en esta sesión\n"
 
 msgid "malformed GPG_AGENT_INFO environment variable\n"
 msgstr "variable de entorno GPG_AGENT_INFO malformada\n"
 
 #, c-format
 msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "el programa no permite usar el protocolo agente gpg versión %d\n"
+msgstr "el programa no permite usar el protocolo agente gpg versión %d\n"
 
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
 msgstr "Uso: gpg-preset-passphrase [opciones] KEYGRIP (-h para ayuda)\n"
@@ -546,17 +485,17 @@ msgid ""
 "Password cache maintenance\n"
 msgstr ""
 "Sintaxis: gpg-preset-passphrase [opciones] KEYGRIP\n"
-"Mantenimiento de la caché de contraseñas\n"
+"Mantenimiento de la caché de contraseñas\n"
 
-# Órdenes, please...
-# Sí, este no he podido ser yo :-) Por cierto, ¿por qué la O no se
-# puede acentuar? Â¿demasiado alta?
-# ¿Quién dice que no se puede? :-)
+# Órdenes, please...
+# Sí, este no he podido ser yo :-) Por cierto, ¿por qué la O no se
+# puede acentuar? ¿demasiado alta?
+# ¿Quién dice que no se puede? :-)
 msgid ""
 "@Commands:\n"
 " "
 msgstr ""
-"@Órdenes:\n"
+"@Órdenes:\n"
 " "
 
 msgid ""
@@ -579,72 +518,73 @@ msgstr ""
 "Herramienta para el mantenimiento de claves secretas\n"
 
 msgid "Please enter the passphrase to unprotect the PKCS#12 object."
-msgstr "Introduzca contraseña para desproteger el objeto PKCS#12."
+msgstr "Introduzca frase contraseña para desproteger el objeto PKCS#12."
 
 msgid "Please enter the passphrase to protect the new PKCS#12 object."
-msgstr "Introduzca contraseña para proteger el nuevo objeto PKCS#12."
+msgstr "Introduzca frase contraseña para proteger el nuevo objeto PKCS#12."
 
 msgid ""
 "Please enter the passphrase to protect the imported object within the GnuPG "
 "system."
-msgstr "Introduzca la contraseña para proteger el objeto importado en GnuPG"
+msgstr ""
+"Introduzca la frase contraseña para proteger el objeto importado en GnuPG"
 
 msgid ""
 "Please enter the passphrase or the PIN\n"
 "needed to complete this operation."
 msgstr ""
-"Introduzca la contraseña o PIN\n"
-"necesarios para completar esta operación."
+"Por favor introduzca la frase contraseña o PIN\n"
+"necesarios para completar esta operación."
 
-# ¿Por qué no frase de paso?
-# Porque todo el mundo sabe lo que es una contraseña
+# ¿Por qué no frase de paso?
+# Porque todo el mundo sabe lo que es una contraseña
 # y una "frase de paso" no. Soy consciente de que se
 # traduce igual password y passphrase pero el contexto
-# permite saber de lo que se está hablando.
-# No sé, no sé.
-# ¿Por qué los ingleses entonces sí que saben lo que es un "passphrase"?
-# ¿Es que son más listos? :-)
+# permite saber de lo que se está hablando.
+# No sé, no sé.
+# ¿Por qué los ingleses entonces sí que saben lo que es un "passphrase"?
+# ¿Es que son más listos? :-)
 #
 msgid "Passphrase:"
-msgstr "contraseña:"
+msgstr "Frase contraseña:"
 
 msgid "cancelled\n"
 msgstr "cancelado\n"
 
 #, c-format
 msgid "error while asking for the passphrase: %s\n"
-msgstr "error pidiendo la contraseña: %s\n"
+msgstr "error pidiendo la frase contraseña: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "error abriendo `%s': %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
-msgstr "fichero `%s', línea %d: %s\n"
+msgid "file '%s', line %d: %s\n"
+msgstr "fichero `%s', línea %d: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
-msgstr "declaración \"%s\" ignorada en `%s', línea %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
+msgstr "declaración \"%s\" ignorada en `%s', línea %d\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
-msgstr "la lista de confianza `%s' del sistema no está disponible\n"
+msgid "system trustlist '%s' not available\n"
+msgstr "la lista de confianza `%s' del sistema no está disponible\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
-msgstr "huella digital incorrecta en `%s', línea %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
+msgstr "huella digital incorrecta en `%s', línea %d\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
-msgstr "opción de clave inválida en `%s', línea %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
+msgstr "opción de clave inválida en `%s', línea %d\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
-msgstr "error leyendo `%s', línea %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
+msgstr "error leyendo `%s', línea %d: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
-msgstr "error leyendo la lista de certificados raíz fiables\n"
+msgstr "error leyendo la lista de certificados raíz fiables\n"
 
 #. TRANSLATORS: This prompt is shown by the Pinentry
 #. and has one special property: A "%%0A" is used by
@@ -659,11 +599,11 @@ msgid ""
 "Do you ultimately trust%%0A  \"%s\"%%0Ato correctly certify user "
 "certificates?"
 msgstr ""
-"¿Confía absolutamente en%%0A  \"%s\"%%0A para certificar correctamentelos "
+"¿Confía absolutamente en%%0A  \"%s\"%%0A para certificar correctamentelos "
 "certificados de otros usuarios?"
 
 msgid "Yes"
-msgstr "Sí"
+msgstr "Sí"
 
 msgid "No"
 msgstr "No"
@@ -681,8 +621,8 @@ msgid ""
 "Please verify that the certificate identified as:%%0A  \"%s\"%%0Ahas the "
 "fingerprint:%%0A  %s"
 msgstr ""
-"Verifique que el certificado identificado como:%%0A \"%s\"%%0Atiene la "
-"huella digital:%%0A  %s"
+"Por favor verifique que el certificado identificado como:%%0A \"%s\"%%"
+"0Atiene la huella digital:%%0A  %s"
 
 #. TRANSLATORS: "Correct" is the label of a button and intended
 #. to be hit if the fingerprint matches the one of the CA.  The
@@ -691,32 +631,34 @@ msgid "Correct"
 msgstr "Correcto"
 
 msgid "Wrong"
-msgstr "Incorrecto"
+msgstr ""
 
 #, c-format
 msgid "Note: This passphrase has never been changed.%0APlease change it now."
-msgstr "Nota: Esta contraseña nunca ha sido cambiada.%0AHágalo ahora."
+msgstr ""
+"Nota: Esta frase contraseña nunca ha sido cambiada.%0APor favor hágalo ahora."
 
 #, c-format
 msgid ""
 "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s.  Please change "
 "it now."
 msgstr ""
-"Esta contraseña no se ha cambiado%%0Adesde %.4s-%.2s-%.2s. Cámbiela ahora."
+"Esta frase contraseña no se ha cambiado%%0Adesde %.4s-%.2s-%.2s.Por favor "
+"cámbiela ahora."
 
 msgid "Change passphrase"
-msgstr "Cambia la contraseña"
+msgstr "Cambia la frase contraseña"
 
 msgid "I'll change it later"
-msgstr "La cambiaré más tarde"
+msgstr "La cambiaré más tarde"
 
 #, c-format
 msgid "error creating a pipe: %s\n"
-msgstr "error creando tubería: %s\n"
+msgstr "error creando tubería: %s\n"
 
 #, c-format
 msgid "can't fdopen pipe for reading: %s\n"
-msgstr "no puede abrirse tubería para leer: %s\n"
+msgstr "no puede abrirse tubería para leer: %s\n"
 
 #, c-format
 msgid "error forking process: %s\n"
@@ -728,18 +670,18 @@ msgstr "fallo esperando que el proceso %d terminara: %s\n"
 
 #, c-format
 msgid "error getting exit code of process %d: %s\n"
-msgstr "error obteniendo código de finalización del proceso: %d %s\n"
+msgstr "error obteniendo código de finalización del proceso: %d %s\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
-msgstr "error ejecutando `%s': código de finalización %d\n"
+msgid "error running '%s': exit status %d\n"
+msgstr "error ejecutando `%s': código de finalización %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "error ejecutando `%s': probablemente no está instalado\n"
+msgid "error running '%s': probably not installed\n"
+msgstr "error ejecutando `%s': probablemente no está instalado\n"
 
 #, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "error ejecutando `%s': terminado\n"
 
 #, c-format
@@ -750,14 +692,14 @@ msgid "host not found"
 msgstr "host no encontrado"
 
 msgid "gpg-agent is not available in this session\n"
-msgstr "el agente gpg no esta disponible en esta sesión\n"
+msgstr "el agente gpg no esta disponible en esta sesión\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "no se puede conectar con `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
-msgstr "problema de comunicación con el agente gpg\n"
+msgstr "problema de comunicación con el agente gpg\n"
 
 msgid "problem setting the gpg-agent options\n"
 msgstr "problema estableciendo opciones de gpg-agent\n"
@@ -782,7 +724,7 @@ msgstr "Aviso: permisos inseguros en %s \"%s\"\n"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "yes"
-msgstr "sí|si"
+msgstr "sí|si"
 
 msgid "yY"
 msgstr "sS"
@@ -824,11 +766,7 @@ msgid "out of core while allocating %lu bytes"
 msgstr "error de memoria reservando %lu bytes"
 
 msgid "no running gpg-agent - starting one\n"
-msgstr "no hay gpg-agent en ejecución - inicando uno\n"
-
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "esperando %d segundos para que el agente arranque\n"
+msgstr "no hay gpg-agent en ejecución - inicando uno\n"
 
 msgid "can't connect to the agent - trying fall back\n"
 msgstr "no puedo conectar con el agente - intentando retirada\n"
@@ -836,40 +774,30 @@ msgstr "no puedo conectar con el agente - intentando retirada\n"
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
 msgid "|audit-log-result|Good"
-msgstr "|audit-log-result|Bien"
+msgstr ""
 
 msgid "|audit-log-result|Bad"
-msgstr "|audit-log-result|Mal"
+msgstr ""
 
 msgid "|audit-log-result|Not supported"
-msgstr "|audit-log-result|No disponible"
+msgstr ""
 
+#, fuzzy
 msgid "|audit-log-result|No certificate"
-msgstr "|audit-log-result|Sin certificado"
+msgstr "importa certificado"
 
+#, fuzzy
 msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|No habilitado"
+msgstr "importa certificado"
 
 msgid "|audit-log-result|Error"
-msgstr "|audit-log-result|Error"
-
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|No usado"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|Correcto"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|Omitido"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|Algún"
+msgstr ""
 
 msgid "Certificate chain available"
 msgstr "Cadena de certificados disponible"
 
 msgid "root certificate missing"
-msgstr "falta el certificado raíz"
+msgstr "falta el certificado raíz"
 
 msgid "Data encryption succeeded"
 msgstr "Datos cifrados correctamente"
@@ -878,7 +806,7 @@ msgid "Data available"
 msgstr "Hay datos disponibles"
 
 msgid "Session key created"
-msgstr "Creada clave de sesión"
+msgstr "Creada clave de sesión"
 
 #, c-format
 msgid "algorithm: %s"
@@ -889,10 +817,10 @@ msgid "unsupported algorithm: %s"
 msgstr "algoritmo no disponible: %s"
 
 msgid "seems to be not encrypted"
-msgstr "no parece que esté cifrado"
+msgstr "no parece que esté cifrado"
 
 msgid "Number of recipients"
-msgstr "Número de destinatarios"
+msgstr "Número de destinatarios"
 
 #, c-format
 msgid "Recipient %d"
@@ -901,46 +829,31 @@ msgstr "Destinatario %d"
 msgid "Data signing succeeded"
 msgstr "Datos firmados correctamente"
 
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritmmo de resumen de datos: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "Firmante %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritmmo de resumen de atributos: %s"
-
 msgid "Data decryption succeeded"
 msgstr "Datos descifrados correctamente"
 
-msgid "Encryption algorithm supported"
-msgstr "Algoritmo de cifrado disponible"
-
 msgid "Data verification succeeded"
 msgstr "Datos verificados correctamente"
 
 msgid "Signature available"
 msgstr "Firma disponible"
 
-msgid "Parsing data succeeded"
-msgstr "Interpretación de datos correcta"
+msgid "Parsing signature succeeded"
+msgstr "Firma interpretada correctamente"
 
 #, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "algoritmo de resumen de datos erróneo: %s"
+msgid "Bad hash algorithm: %s"
+msgstr "Algoritmmo de resumen erróneo: %s"
 
 #, c-format
 msgid "Signature %d"
 msgstr "Firma %d"
 
 msgid "Certificate chain valid"
-msgstr "Cadena de certificados válida"
+msgstr "Cadena de certificados válida"
 
 msgid "Root certificate trustworthy"
-msgstr "Certificado raíz fiable"
+msgstr "Certificado raíz fiable"
 
 msgid "no CRL found for certificate"
 msgstr "no se encuentra CRL para el certificado"
@@ -949,7 +862,7 @@ msgid "the available CRL is too old"
 msgstr "el CRL disponible es demasiado antiguo"
 
 msgid "CRL/OCSP check of certificates"
-msgstr "Comprobación CRL/OCSP de certificados"
+msgstr "Comprobación CRL/OCSP de certificados"
 
 msgid "Included certificates"
 msgstr "Certificados incluidos"
@@ -958,7 +871,7 @@ msgid "No audit log entries."
 msgstr "No auditar entradas de los logs"
 
 msgid "Unknown operation"
-msgstr "Operación desconocida"
+msgstr "Operación desconocida"
 
 msgid "Gpg-Agent usable"
 msgstr "Gpg-Agent utilizable"
@@ -967,11 +880,11 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr utilizable"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "No hay ayuda disponible para `%s'."
 
 msgid "ignoring garbage line"
-msgstr "ignorando línea con basura"
+msgstr "ignorando línea con basura"
 
 msgid "[none]"
 msgstr "[ninguno]"
@@ -981,13 +894,13 @@ msgid "armor: %s\n"
 msgstr "armadura: %s\n"
 
 msgid "invalid armor header: "
-msgstr "cabecera de armadura inválida: "
+msgstr "cabecera de armadura inválida: "
 
 msgid "armor header: "
 msgstr "cabecera de armadura: "
 
 msgid "invalid clearsig header\n"
-msgstr "cabecera de firma clara inválida\n"
+msgstr "cabecera de firma clara inválida\n"
 
 msgid "unknown armor header: "
 msgstr "cabecera de armadura desconocida: "
@@ -999,62 +912,62 @@ msgid "unexpected armor: "
 msgstr "armadura inesperada: "
 
 msgid "invalid dash escaped line: "
-msgstr "Línea con guiones inválida: "
+msgstr "Línea con guiones inválida: "
 
 #, c-format
 msgid "invalid radix64 character %02X skipped\n"
-msgstr "caracter inválido radix64 %02X omitido\n"
+msgstr "caracter inválido radix64 %02X omitido\n"
 
 msgid "premature eof (no CRC)\n"
-msgstr "Fin de fichero prematuro (falta suma de comprobación)\n"
+msgstr "Fin de fichero prematuro (falta suma de comprobación)\n"
 
 msgid "premature eof (in CRC)\n"
-msgstr "Fin de suma de comprobación prematuro\n"
+msgstr "Fin de suma de comprobación prematuro\n"
 
 msgid "malformed CRC\n"
-msgstr "Suma de comprobación mal creada\n"
+msgstr "Suma de comprobación mal creada\n"
 
 #, c-format
 msgid "CRC error; %06lX - %06lX\n"
-msgstr "Error en suma de comprobación: %06lX - %06lX\n"
+msgstr "Error en suma de comprobación: %06lX - %06lX\n"
 
 msgid "premature eof (in trailer)\n"
 msgstr "fin de fichero prematuro (en el cierre)\n"
 
 msgid "error in trailer line\n"
-msgstr "error en la línea de cierre\n"
+msgstr "error en la línea de cierre\n"
 
 msgid "no valid OpenPGP data found.\n"
-msgstr "no se han encontrados datos OpenPGP válidos\n"
+msgstr "no se han encontrados datos OpenPGP válidos\n"
 
 #, c-format
 msgid "invalid armor: line longer than %d characters\n"
-msgstr "armadura incorrecta: línea más larga de %d caracteres\n"
+msgstr "armadura incorrecta: línea más larga de %d caracteres\n"
 
 msgid ""
 "quoted printable character in armor - probably a buggy MTA has been used\n"
 msgstr ""
-"caracter \"quoted printable\" en la armadura - probablemente se usó\n"
+"caracter \"quoted printable\" en la armadura - probablemente se usó\n"
 "un MTA defectuoso\n"
 
 msgid ""
 "a notation name must have only printable characters or spaces, and end with "
 "an '='\n"
 msgstr ""
-"un nombre de notación debe tener sólo caracteres imprimibles o espacios, y "
+"un nombre de notación debe tener sólo caracteres imprimibles o espacios, y "
 "acabar con un '='\n"
 
 msgid "a user notation name must contain the '@' character\n"
-msgstr "un nombre de notación de usuario debe contener el caracter '@'\n"
+msgstr "un nombre de notación de usuario debe contener el caracter '@'\n"
 
 msgid "a notation name must not contain more than one '@' character\n"
-msgstr "un nombre de notación no debe contener más de un caracter '@'\n"
+msgstr "un nombre de notación no debe contener más de un caracter '@'\n"
 
 msgid "a notation value must not use any control characters\n"
-msgstr "un valor de notación no debe usar ningún caracter de control\n"
+msgstr "un valor de notación no debe usar ningún caracter de control\n"
 
 msgid "WARNING: invalid notation data found\n"
-msgstr "ATENCIÓN: encontrados datos de notación inválidos\n"
+msgstr "ATENCIÓN: encontrados datos de notación inválidos\n"
 
 msgid "not human readable"
 msgstr "ilegible"
@@ -1071,13 +984,13 @@ msgid "can't do this in batch mode\n"
 msgstr "imposible hacer esto en modo de proceso por lotes\n"
 
 msgid "This command is only available for version 2 cards\n"
-msgstr "Esta orden solo está disponible en tarjetas versión 2\n"
+msgstr "Esta orden solo está disponible en tarjetas versión 2\n"
 
 msgid "Reset Code not or not anymore available\n"
-msgstr "No hay Código de Reinicio o ya no está disponible\n"
+msgstr "No hay Código de Reinicio o ya no está disponible\n"
 
 msgid "Your selection? "
-msgstr "Su elección: "
+msgstr "Su elección: "
 
 msgid "[not set]"
 msgstr "[no establecido]"
@@ -1098,7 +1011,7 @@ msgid "forced"
 msgstr "forzado"
 
 msgid "Error: Only plain ASCII is currently allowed.\n"
-msgstr "Error: sólo se permite ASCII sin formato actualmente.\n"
+msgstr "Error: sólo se permite ASCII sin formato actualmente.\n"
 
 msgid "Error: The \"<\" character may not be used.\n"
 msgstr "Error: El caracter \"<\" no puede usarse.\n"
@@ -1114,33 +1027,33 @@ msgstr "Nombre del titular de la tarjeta: "
 
 #, c-format
 msgid "Error: Combined name too long (limit is %d characters).\n"
-msgstr "Error: nombre combinado demasiado largo (máximo %d caracteres).\n"
+msgstr "Error: nombre combinado demasiado largo (máximo %d caracteres).\n"
 
 msgid "URL to retrieve public key: "
-msgstr "URL de donde recuperar la clave pública: "
+msgstr "URL de donde recuperar la clave pública: "
 
 #, c-format
 msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Error: URL demasiado larga (el máximo son %d caracteres).\n"
+msgstr "Error: URL demasiado larga (el máximo son %d caracteres).\n"
 
 #, c-format
 msgid "error allocating enough memory: %s\n"
 msgstr "error reservando memoria: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "error leyendo `%s': %s\n"
 
-#, c-format
-msgid "error writing `%s': %s\n"
-msgstr "error escribiendo `%s': %s\n"
+#, fuzzy, c-format
+msgid "error writing '%s': %s\n"
+msgstr "error escribiendo en `%s': %s\n"
 
 msgid "Login data (account name): "
 msgstr "Datos de login (nombre de la cuenta): "
 
 #, c-format
 msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Error: el login es demasiado largo (límite de %d caracteres).\n"
+msgstr "Error: el login es demasiado largo (límite de %d caracteres).\n"
 
 msgid "Private DO data: "
 msgstr "Datos privados: "
@@ -1148,63 +1061,60 @@ msgstr "Datos privados: "
 #, c-format
 msgid "Error: Private DO too long (limit is %d characters).\n"
 msgstr ""
-"Error: los datos privados son demasiado largos (límite de %d caracteres).\n"
+"Error: los datos privados son demasiado largos (límite de %d caracteres).\n"
 
 msgid "Language preferences: "
 msgstr "Preferencias de idioma: "
 
 msgid "Error: invalid length of preference string.\n"
-msgstr "Error: longitud de la cadena de preferencias inválida.\n"
+msgstr "Error: longitud de la cadena de preferencias inválida.\n"
 
 msgid "Error: invalid characters in preference string.\n"
-msgstr "Error: caracteres inválidos en cadena de preferencias.\n"
+msgstr "Error: caracteres inválidos en cadena de preferencias.\n"
 
 msgid "Sex ((M)ale, (F)emale or space): "
 msgstr "Sexo ((H)ombre, (M)mujer o espacio): "
 
 msgid "Error: invalid response.\n"
-msgstr "Error: respuesta no válida.\n"
+msgstr "Error: respuesta no válida.\n"
 
 msgid "CA fingerprint: "
 msgstr "Huella dactilar CA:"
 
 msgid "Error: invalid formatted fingerprint.\n"
-msgstr "Error: formato inválido de huella dactilar.\n"
+msgstr "Error: formato inválido de huella dactilar.\n"
 
 #, c-format
 msgid "key operation not possible: %s\n"
-msgstr "la operación con la clave no es posible: %s\n"
+msgstr "la operación con la clave no es posible: %s\n"
 
 msgid "not an OpenPGP card"
 msgstr "no es una tarjeta OpenPGP"
 
 #, c-format
 msgid "error getting current key info: %s\n"
-msgstr "error obteniendo la información actual de la clave: %s\n"
+msgstr "error obteniendo la información actual de la clave: %s\n"
 
 msgid "Replace existing key? (y/N) "
-msgstr "¿Reemplazar la clave existente? (s/N) "
+msgstr "¿Reemplazar la clave existente? (s/N) "
 
 msgid ""
 "NOTE: There is no guarantee that the card supports the requested size.\n"
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
-"NOTA: No hay garantía de que la tarjeta permita el uso del tamaño\n"
-"      requerido. Si la generación de clave fracasa, compruebe\n"
-"      la documentación de su tarjeta para ver los tamaños posibles.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "¿De qué tamaño quiere la clave de Firmado? (%u) "
+msgstr "¿De qué tamaño quiere la clave? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "¿De qué tamaño quiere la clave de Cifrado? (%u) "
+msgstr "¿De qué tamaño quiere la clave? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "¿De qué tamaño quiere la clave de Autenticación? (%u) "
+msgstr "¿De qué tamaño quiere la clave? (%u) "
 
 #, c-format
 msgid "rounded up to %u bits\n"
@@ -1212,25 +1122,26 @@ msgstr "redondeados a %u bits\n"
 
 #, c-format
 msgid "%s keysizes must be in the range %u-%u\n"
-msgstr "los tamaños de claves %s deben estar en el rango %u-%u\n"
+msgstr "los tamaños de claves %s deben estar en el rango %u-%u\n"
 
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
-msgstr "Ahora la tarjeta se reconfigurará para generar una clave de %u bits\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
-msgstr "error cambiando el tamaño de la clave %d a %u bits: %s\n"
+msgstr "error enlazando el socket con `%s': %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr ""
-"¿Hacer copia de seguridad externa a la tarjeta de clave de cifrado? (S/n)"
+"¿Hacer copia de seguridad externa a la tarjeta de clave de cifrado? (S/n)"
 
+#, fuzzy
 msgid "NOTE: keys are already stored on the card!\n"
-msgstr "NOTA: ¡claves ya almacenadas en la tarjeta!\n"
+msgstr "clave secreta ya almacenada en una tarjeta\n"
 
 msgid "Replace existing keys? (y/N) "
-msgstr "¿Reemplazar las claves existentes? (s/N) "
+msgstr "¿Reemplazar las claves existentes? (s/N) "
 
 #, c-format
 msgid ""
@@ -1238,12 +1149,12 @@ msgid ""
 "   PIN = `%s'     Admin PIN = `%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
-"Observe que los valores de fábrica del PIN son\n"
+"Por favor observe que los valores de fábrica del PIN son\n"
 "   PIN = `%s'     PIN Administrador = `%s'\n"
-"Debería cambiarlos usando la orden --change-pin\n"
+"Debería cambiarlos usando la orden --change-pin\n"
 
 msgid "Please select the type of key to generate:\n"
-msgstr "Seleccione tipo de clave que generar:\n"
+msgstr "Por favor seleccione tipo de clave que generar:\n"
 
 msgid "   (1) Signature key\n"
 msgstr "    (1) Clave de firmado\n"
@@ -1252,32 +1163,32 @@ msgid "   (2) Encryption key\n"
 msgstr "   (2) Clave de cifrado\n"
 
 msgid "   (3) Authentication key\n"
-msgstr "   (3) Clave de autentificación\n"
+msgstr "   (3) Clave de autentificación\n"
 
 msgid "Invalid selection.\n"
-msgstr "Elección inválida.\n"
+msgstr "Elección inválida.\n"
 
 msgid "Please select where to store the key:\n"
-msgstr "Elija donde guardar la clave:\n"
+msgstr "Por favor elija donde guardar la clave:\n"
 
 msgid "unknown key protection algorithm\n"
-msgstr "algoritmo de protección de clave desconocido\n"
+msgstr "algoritmo de protección de clave desconocido\n"
 
 msgid "secret parts of key are not available\n"
-msgstr "las partes secretas de la clave no están disponibles\n"
+msgstr "las partes secretas de la clave no están disponibles\n"
 
 msgid "secret key already stored on a card\n"
 msgstr "clave secreta ya almacenada en una tarjeta\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key to card: %s\n"
-msgstr "error escribiendo clave en la tarjeta: %s\n"
+msgstr "error escribiendo clave: %s\n"
 
 msgid "quit this menu"
-msgstr "sale de este menú"
+msgstr "sale de este menú"
 
 msgid "show admin commands"
-msgstr "ver órdenes de administrador"
+msgstr "ver órdenes de administrador"
 
 msgid "show this help"
 msgstr "muestra esta ayuda"
@@ -1307,40 +1218,40 @@ msgid "change a CA fingerprint"
 msgstr "cambiar huella dactilar de una CA"
 
 msgid "toggle the signature force PIN flag"
-msgstr "cambiar estado de la opción forzar firma del PIN"
+msgstr "cambiar estado de la opción forzar firma del PIN"
 
 msgid "generate new keys"
 msgstr "generar nuevas claves"
 
 msgid "menu to change or unblock the PIN"
-msgstr "menú para cambiar o desbloquear el PIN"
+msgstr "menú para cambiar o desbloquear el PIN"
 
 msgid "verify the PIN and list all data"
 msgstr "verificar PIN y listar todos los datos"
 
 msgid "unblock the PIN using a Reset Code"
-msgstr "desbloquear PIN usando Código de Reinicio"
+msgstr "desbloquear PIN usando Código de Reinicio"
 
-msgid "gpg/card> "
-msgstr "gpg/tarjeta> "
+msgid "Command> "
+msgstr "Orden> "
 
 msgid "Admin-only command\n"
-msgstr "Órdenes sólo de administrador\n"
+msgstr "Órdenes sólo de administrador\n"
 
 msgid "Admin commands are allowed\n"
-msgstr "Se permiten órdenes de administrador\n"
+msgstr "Se permiten órdenes de administrador\n"
 
 msgid "Admin commands are not allowed\n"
-msgstr "No se permiten órdenes de administrador\n"
+msgstr "No se permiten órdenes de administrador\n"
 
 msgid "Invalid command  (try \"help\")\n"
-msgstr "Orden inválida (pruebe \"help\")\n"
+msgstr "Orden inválida (pruebe \"help\")\n"
 
 msgid "--output doesn't work for this command\n"
 msgstr "--output no funciona con esta orden\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "no se puede abrir `%s'\n"
 
 #, c-format
@@ -1358,49 +1269,49 @@ msgid "can't do this in batch mode without \"--yes\"\n"
 msgstr "imposible hacer esto en modo de proceso por lotes sin \"--yes\"\n"
 
 msgid "Delete this key from the keyring? (y/N) "
-msgstr "¿Desea eliminar esta clave del almacén? (s/N) "
+msgstr "¿Eliminar esta clave del anillo? (s/N) "
 
 msgid "This is a secret key! - really delete? (y/N) "
-msgstr "¡Es una clave secreta! Â¿Eliminar realmente? (s/N) "
+msgstr "¡Es una clave secreta! ¿Eliminar realmente? (s/N) "
 
 #, c-format
 msgid "deleting keyblock failed: %s\n"
-msgstr "fallo al eliminar el bloque de almacén de claves: %s\n"
+msgstr "borrado de bloque de anillo de claves fallido: %s\n"
 
 msgid "ownertrust information cleared\n"
-msgstr "borrada información de propietarios\n"
+msgstr "borrada información de propietarios\n"
 
 #, c-format
 msgid "there is a secret key for public key \"%s\"!\n"
-msgstr "¡hay una clave secreta para esta clave pública! \"%s\"!\n"
+msgstr "¡hay una clave secreta para esta clave pública! \"%s\"!\n"
 
 msgid "use option \"--delete-secret-keys\" to delete it first.\n"
-msgstr "use antes la opción \"--delete-secret-key\" para borrarla.\n"
+msgstr "use antes la opción \"--delete-secret-key\" para borrarla.\n"
 
 #, c-format
 msgid "error creating passphrase: %s\n"
-msgstr "error creando contraseña: %s\n"
+msgstr "error creando frase contraseña: %s\n"
 
 msgid "can't use a symmetric ESK packet due to the S2K mode\n"
-msgstr "no puede usar un paquete simétrico ESK debido al modo S2K\n"
+msgstr "no puede usar un paquete simétrico ESK debido al modo S2K\n"
 
 #, c-format
 msgid "using cipher %s\n"
 msgstr "usando cifrado %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
-msgstr "`%s' ya está comprimido\n"
+msgid "'%s' already compressed\n"
+msgstr "`%s' ya está comprimido\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
-msgstr "ATENCIÓN `%s' es un fichero vacío\n"
+msgid "WARNING: '%s' is an empty file\n"
+msgstr "ATENCIÓN `%s' es un fichero vacío\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr "solo puede cifrar a claves RSA de 2048 bits o menos en modo --pgp2\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "leyendo desde `%s'\n"
 
 msgid ""
@@ -1412,7 +1323,7 @@ msgstr ""
 msgid ""
 "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
 msgstr ""
-"ATENCIÓN: forzar el cifrado simétrico %s (%d) viola las preferencias\n"
+"AVISO: forzar el cifrado simétrico %s (%d) viola las preferencias\n"
 "del destinatario\n"
 
 #, c-format
@@ -1420,13 +1331,13 @@ msgid ""
 "WARNING: forcing compression algorithm %s (%d) violates recipient "
 "preferences\n"
 msgstr ""
-"ATENCIÓN: forzar el algoritmo de compresión %s (%d) va en contra\n"
+"AVISO: forzar el algoritmo de compresión %s (%d) va en contra\n"
 "de las preferencias del receptor\n"
 
 #, c-format
 msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n"
 msgstr ""
-"forzar el cifrado simétrico %s (%d) viola las preferencias\n"
+"forzar el cifrado simétrico %s (%d) viola las preferencias\n"
 "del destinatario\n"
 
 #, c-format
@@ -1448,7 +1359,7 @@ msgstr "cifrado con algoritmo desconocido %d\n"
 msgid ""
 "WARNING: message was encrypted with a weak key in the symmetric cipher.\n"
 msgstr ""
-"ATENCIÓN: mensaje cifrado con una clave débil en el cifrado simétrico.\n"
+"ATENCIÓN: mensaje cifrado con una clave débil en el cifrado simétrico.\n"
 
 msgid "problem handling encrypted packet\n"
 msgstr "problema trabajando con un paquete cifrado\n"
@@ -1468,19 +1379,19 @@ msgstr ""
 "externos\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "no se puede ejecutar el programa `%s': %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
-msgstr "no se puede ejecutar el intérprete de órdenes `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
+msgstr "no se puede ejecutar el intérprete de órdenes `%s': %s\n"
 
 #, c-format
 msgid "system error while calling external program: %s\n"
 msgstr "error del sistema llamando al programa externo: %s\n"
 
 msgid "unnatural exit of external program\n"
-msgstr "el programa externo finalizó anormalmente\n"
+msgstr "el programa externo finalizó anormalmente\n"
 
 msgid "unable to execute external program\n"
 msgstr "no se puede ejecutar el programa externo\n"
@@ -1490,24 +1401,24 @@ msgid "unable to read external program response: %s\n"
 msgstr "no se puede leer la respuesta del programa externo: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
-msgstr "ATENCIÓN: no se puede borrar fichero temporal (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
+msgstr "AVISO: no se puede borrar fichero temporal (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
-msgstr "ATENCIÓN: no se puede borrar el fichero temporal `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
+msgstr "AVISO: no se puede borrar el fichero temporal `%s': %s\n"
 
 msgid "export signatures that are marked as local-only"
-msgstr "exportar firmas marcadas como sólo locales"
+msgstr "exportar firmas marcadas como sólo locales"
 
 msgid "export attribute user IDs (generally photo IDs)"
-msgstr "exportar el atributo ID de usuario (generalmente fotográfico)"
+msgstr "exportar el atributo ID de usuario (generalmente fotográfico)"
 
 msgid "export revocation keys marked as \"sensitive\""
-msgstr "exportar claves de revocación marcadas como \"confidenciales\""
+msgstr "exportar claves de revocación marcadas como \"confidenciales\""
 
 msgid "remove the passphrase from exported subkeys"
-msgstr "borrar contraseña de las subclaves exportadas"
+msgstr "borrar frase contraseña de las subclaves exportadas"
 
 msgid "remove unusable parts from key during export"
 msgstr "borrar partes inutilizables de la clave al exportar"
@@ -1516,7 +1427,7 @@ msgid "remove as much as possible from key during export"
 msgstr "borrar tanto como sea posible de la clave al exportar"
 
 msgid "export keys in an S-expression based format"
-msgstr "exportar claves en formato basado en una expresión S"
+msgstr "exportar claves en formato basado en una expresión S"
 
 msgid "exporting secret keys not allowed\n"
 msgstr "no se permite exportar claves secretas\n"
@@ -1542,11 +1453,10 @@ msgstr "fallo al desproteger la subclave: %s\n"
 
 #, c-format
 msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr ""
-"ATENCIÓN: la clave secreta %s no tiene suma de comprobación simple SK\n"
+msgstr "AVISO: la clave secreta %s no tiene suma de comprobación simple SK\n"
 
 msgid "WARNING: nothing exported\n"
-msgstr "ATENCIÓN: no se ha exportado nada\n"
+msgstr "ATENCIÓN: no se ha exportado nada\n"
 
 msgid "too many entries in pk cache - disabled\n"
 msgstr "demasiados registros en la cache pk - anulada\n"
@@ -1555,32 +1465,32 @@ msgid "[User ID not found]"
 msgstr "[ID de usuario no encontrado]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "clave %s: clave secreta sin clave pública - omitida\n"
+msgid "automatically retrieved '%s' via %s\n"
+msgstr "recuperado automáticamente `%s' vía %s\n"
 
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
-msgstr "recuperado automáticamente `%s' vía %s\n"
-
-#, c-format
-msgid "error retrieving `%s' via %s: %s\n"
-msgstr "error recuperando `%s' vía %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
+msgstr "error recuperando `%s' vía %s: %s\n"
 
 msgid "No fingerprint"
 msgstr "No hay huella dactilar"
 
 #, c-format
 msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
-msgstr "Clave %s inválida hecha válida mediante --allow-non-selfsigned-uid\n"
+msgstr "Clave %s inválida hecha válida mediante --allow-non-selfsigned-uid\n"
 
 #, c-format
 msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "no hay subclave secreta para la subclave pública %s - ignorada\n"
+msgstr "no hay subclave secreta para la subclave pública %s - ignorada\n"
 
 #, c-format
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "usando subclave %s en vez de clave primaria %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "clave %s: clave secreta sin clave pública - omitida\n"
+
 msgid "make a signature"
 msgstr "crea una firma"
 
@@ -1594,7 +1504,7 @@ msgid "encrypt data"
 msgstr "cifra datos"
 
 msgid "encryption only with symmetric cipher"
-msgstr "cifra sólo con un cifrado simétrico"
+msgstr "cifra sólo con un cifrado simétrico"
 
 msgid "decrypt data (default)"
 msgstr "descifra datos (predefinido)"
@@ -1620,14 +1530,11 @@ msgstr "lista claves secretas"
 msgid "generate a new key pair"
 msgstr "genera un nuevo par de claves"
 
-msgid "generate a revocation certificate"
-msgstr "genera un certificado de revocación"
-
 msgid "remove keys from the public keyring"
-msgstr "elimina claves del almacén público"
+msgstr "elimina claves del anillo público"
 
 msgid "remove keys from the secret keyring"
-msgstr "elimina claves del almacén privado"
+msgstr "elimina claves del anillo privado"
 
 msgid "sign a key"
 msgstr "firma la clave"
@@ -1638,8 +1545,8 @@ msgstr "firma la clave localmente"
 msgid "sign or edit a key"
 msgstr "firma o modifica una clave"
 
-msgid "change a passphrase"
-msgstr "cambia una contraseña"
+msgid "generate a revocation certificate"
+msgstr "genera un certificado de revocación"
 
 msgid "export keys"
 msgstr "exporta claves"
@@ -1672,7 +1579,7 @@ msgid "update the trust database"
 msgstr "actualiza la base de datos de confianza"
 
 msgid "print message digests"
-msgstr "imprime resúmenes de mensaje"
+msgstr "imprime resúmenes de mensaje"
 
 msgid "run in server mode"
 msgstr "ejecutar en modo servidor"
@@ -1687,16 +1594,16 @@ msgid "|USER-ID|use USER-ID to sign or decrypt"
 msgstr "|ID-USUARIO|usa este identificador para firmar o descifrar"
 
 msgid "|N|set compress level to N (0 disables)"
-msgstr "|N|nivel de compresión N (0 desactiva)"
+msgstr "|N|nivel de compresión N (0 desactiva)"
 
 msgid "use canonical text mode"
-msgstr "usa modo de texto canónico"
+msgstr "usa modo de texto canónico"
 
 msgid "|FILE|write output to FILE"
 msgstr "|FICHERO|volcar salida en FICHERO"
 
 msgid "do not make any changes"
-msgstr "no hacer ningún cambio"
+msgstr "no hace ningún cambio"
 
 msgid "prompt before overwriting"
 msgstr "preguntar antes de sobreescribir"
@@ -1704,16 +1611,16 @@ msgstr "preguntar antes de sobreescribir"
 msgid "use strict OpenPGP behavior"
 msgstr "usar estilo OpenPGP estricto"
 
-# ordenes -> órdenes
-# página man -> página de manual
-# Vale. Â¿del manual mejor?
-# Hmm, no sé, en man-db se usa "de". La verdad es que no lo he pensado.
+# ordenes -> órdenes
+# página man -> página de manual
+# Vale. ¿del manual mejor?
+# Hmm, no sé, en man-db se usa "de". La verdad es que no lo he pensado.
 msgid ""
 "@\n"
 "(See the man page for a complete listing of all commands and options)\n"
 msgstr ""
 "@\n"
-"(Revise la lista completa de órdenes y opciones en las páginas de manual)\n"
+"(Véase en la página del manual la lista completo de órdenes y opciones)\n"
 
 msgid ""
 "@\n"
@@ -1739,12 +1646,12 @@ msgstr "Uso: gpg [opciones] [ficheros] (-h para ayuda)"
 
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxis: gpg [opciones] [ficheros]\n"
-"Firma, comprueba, cifra o descifra\n"
-"La operación predeterminada depende de los datos de entrada\n"
+"firma, comprueba, cifra o descifra\n"
+"la operación por defecto depende de los datos de entrada\n"
 
 msgid ""
 "\n"
@@ -1754,7 +1661,7 @@ msgstr ""
 "Algoritmos disponibles:\n"
 
 msgid "Pubkey: "
-msgstr "Clave pública: "
+msgstr "Clave pública: "
 
 msgid "Cipher: "
 msgstr "Cifrado: "
@@ -1763,89 +1670,89 @@ msgid "Hash: "
 msgstr "Resumen: "
 
 msgid "Compression: "
-msgstr "Compresión: "
+msgstr "Compresión: "
 
 msgid "usage: gpg [options] "
 msgstr "uso: gpg [opciones] "
 
 msgid "conflicting commands\n"
-msgstr "órdenes incompatibles\n"
+msgstr "órdenes incompatibles\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
-msgstr "no se encontró el signo = en la definición de grupo `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
+msgstr "no se encontró el signo = en la definición de grupo `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
-msgstr "ATENCIÓN: propiedad insegura del directorio personal `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
+msgstr "AVISO: propiedad insegura del directorio personal `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
-msgstr "ATENCIÓN: propiedad insegura del fichero de configuración `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
+msgstr "AVISO: propiedad insegura del fichero de configuración `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
-msgstr "ATENCIÓN: propiedad insegura de la extensión `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
+msgstr "AVISO: propiedad insegura de la extensión `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
-msgstr "ATENCIÓN: permisos inseguros del directorio personal `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
+msgstr "AVISO: permisos inseguros del directorio personal `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
-msgstr "ATENCIÓN: permisos inseguros del fichero de configuración `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
+msgstr "AVISO: permisos inseguros del fichero de configuración `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
-msgstr "ATENCIÓN: permisos inseguros de la extensión `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
+msgstr "AVISO: permisos inseguros de la extensión `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
-msgstr "ATENCIÓN: propiedad insegura del directorio contenedor de `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
+msgstr "AVISO: propiedad insegura del directorio contenedor de `%s'\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
 msgstr ""
-"ATENCIÓN: propiedad insegura del directorio contenedor del fichero de\n"
-"configuración `%s'\n"
+"AVISO: propiedad insegura del directorio contenedor del fichero de\n"
+"configuración `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
-"ATENCIÓN: propiedad insegura del directorio contenedor de la extensión `%s'\n"
+"AVISO: propiedad insegura del directorio contenedor de la extensión `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
-msgstr "ATENCIÓN: permisos inseguros del directorio contenedor de `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
+msgstr "AVISO: permisos inseguros del directorio contenedor de `%s'\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
 msgstr ""
-"ATENCIÓN: permisos inseguros del directorio contenedor del fichero de\n"
-"configuración `%s'\n"
+"AVISO: permisos inseguros del directorio contenedor del fichero de\n"
+"configuración `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
-"ATENCIÓN: permisos inseguros del directorio contenedor de la extensión `%s'\n"
+"AVISO: permisos inseguros del directorio contenedor de la extensión `%s'\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
-msgstr "artículo de configuración desconocido `%s'\n"
+msgid "unknown configuration item '%s'\n"
+msgstr "artículo de configuración desconocido `%s'\n"
 
 msgid "display photo IDs during key listings"
 msgstr "mostrar foto IDs al listar claves"
 
 msgid "show policy URLs during signature listings"
-msgstr "mostrar URLS de política al listar firmas"
+msgstr "mostrar URLS de política al listar firmas"
 
 msgid "show all notations during signature listings"
 msgstr "mostrar todas las notaciones al listar firmas"
 
 msgid "show IETF standard notations during signature listings"
-msgstr "mostrar notaciones estándar IETF al listar firmas"
+msgstr "mostrar notaciones estándar IETF al listar firmas"
 
 msgid "show user-supplied notations during signature listings"
 msgstr "mostrar notaciones personalizadas al listar firmas"
@@ -1863,13 +1770,13 @@ msgid "show revoked and expired subkeys in key listings"
 msgstr "mostrar subclaves revocadas y expiradas al listar claves"
 
 msgid "show the keyring name in key listings"
-msgstr "mostrar nombre de los almacenes de claves al listar claves"
+msgstr "mostrar nombre de los anillos de claves al listar claves"
 
 msgid "show expiration dates during signature listings"
 msgstr "mostrar fechas de caducidad al listar firmas"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "NOTA: se ignora el antiguo fichero de opciones predefinidas `%s'\n"
 
 #, c-format
@@ -1878,58 +1785,58 @@ msgstr "libgcrypt demasiado antigua (necesito %s, tengo %s)\n"
 
 #, c-format
 msgid "NOTE: %s is not for normal use!\n"
-msgstr "NOTA: Â¡%s no es para uso normal!\n"
+msgstr "NOTA: ¡%s no es para uso normal!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
-msgstr "`%s' no es una fecha de caducidad válida\n"
+msgid "'%s' is not a valid signature expiration\n"
+msgstr "`%s' no es una fecha de caducidad válida\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
-msgstr "`%s' no es un juego de caracteres válido\n"
+msgid "'%s' is not a valid character set\n"
+msgstr "`%s' no es un juego de caracteres válido\n"
 
 msgid "could not parse keyserver URL\n"
 msgstr "no se puede interpretar la URL del servidor de claves\n"
 
 #, c-format
 msgid "%s:%d: invalid keyserver options\n"
-msgstr "%s:%d: opciones del servidor de claves inválidas\n"
+msgstr "%s:%d: opciones del servidor de claves inválidas\n"
 
 msgid "invalid keyserver options\n"
-msgstr "opciones del servidor de claves inválidas\n"
+msgstr "opciones del servidor de claves inválidas\n"
 
 #, c-format
 msgid "%s:%d: invalid import options\n"
-msgstr "%s:%d: opciones de importación inválidas\n"
+msgstr "%s:%d: opciones de importación inválidas\n"
 
 msgid "invalid import options\n"
-msgstr "opciones de importación inválidas\n"
+msgstr "opciones de importación inválidas\n"
 
 #, c-format
 msgid "%s:%d: invalid export options\n"
-msgstr "%s:%d: opciones de exportación inválidas\n"
+msgstr "%s:%d: opciones de exportación inválidas\n"
 
 msgid "invalid export options\n"
-msgstr "opciones de exportación inválidas\n"
+msgstr "opciones de exportación inválidas\n"
 
 #, c-format
 msgid "%s:%d: invalid list options\n"
-msgstr "%s:%d: lista de opciones inválida\n"
+msgstr "%s:%d: lista de opciones inválida\n"
 
 msgid "invalid list options\n"
-msgstr "lista de opciones inválida\n"
+msgstr "lista de opciones inválida\n"
 
 msgid "display photo IDs during signature verification"
 msgstr "mostrar foto IDs al verificar firmas"
 
 msgid "show policy URLs during signature verification"
-msgstr "mostrar URLs de política al verificar firmas"
+msgstr "mostrar URLs de política al verificar firmas"
 
 msgid "show all notations during signature verification"
 msgstr "mostrar todas las notaciones al verificar firmas"
 
 msgid "show IETF standard notations during signature verification"
-msgstr "mostrar notaciones estándar IETF al verificar firmas"
+msgstr "mostrar notaciones estándar IETF al verificar firmas"
 
 msgid "show user-supplied notations during signature verification"
 msgstr "mostrar notaciones personalizadas al verificar firmas"
@@ -1950,14 +1857,14 @@ msgid "validate signatures with PKA data"
 msgstr "validar firmas con datos PKA"
 
 msgid "elevate the trust of signatures with valid PKA data"
-msgstr "aumentar confianza en las firmas con datos válidos PKA"
+msgstr "aumentar confianza en las firmas con datos válidos PKA"
 
 #, c-format
 msgid "%s:%d: invalid verify options\n"
-msgstr "%s:%d: opciones de verificación inválidas\n"
+msgstr "%s:%d: opciones de verificación inválidas\n"
 
 msgid "invalid verify options\n"
-msgstr "opciones de verificación inválidas\n"
+msgstr "opciones de verificación inválidas\n"
 
 #, c-format
 msgid "unable to set exec-path to %s\n"
@@ -1965,53 +1872,53 @@ msgstr "imposible establecer camino de ejecutables %s\n"
 
 #, c-format
 msgid "%s:%d: invalid auto-key-locate list\n"
-msgstr "%s:%d: lista de auto-localización de claves inválida\n"
+msgstr "%s:%d: lista de auto-localización de claves inválida\n"
 
 msgid "invalid auto-key-locate list\n"
-msgstr "lista de auto-localización de claves inválida\n"
+msgstr "lista de auto-localización de claves inválida\n"
 
 msgid "WARNING: program may create a core file!\n"
-msgstr "ATENCIÓN: ¡el programa podría volcar un fichero core!\n"
+msgstr "ATENCIÓN: ¡el programa podría volcar un fichero core!\n"
 
 #, c-format
 msgid "WARNING: %s overrides %s\n"
-msgstr "ATENCIÓN: %s sustituye a %s\n"
+msgstr "AVISO: %s sustituye a %s\n"
 
 #, c-format
 msgid "%s not allowed with %s!\n"
-msgstr "¡%s no permitido con %s!\n"
+msgstr "¡%s no permitido con %s!\n"
 
 #, c-format
 msgid "%s makes no sense with %s!\n"
-msgstr "¡%s no tiene sentido con %s!\n"
+msgstr "¡%s no tiene sentido con %s!\n"
 
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
-msgstr "no se ejecutará en memoria insegura por %s\n"
+msgstr "no se ejecutará en memoria insegura por %s\n"
 
 msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
-msgstr "sólo puede hacer firmas separadas o en claro en modo --pgp2\n"
+msgstr "sólo puede hacer firmas separadas o en claro en modo --pgp2\n"
 
 msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
 msgstr "no puede firmar y cifrar a la vez en modo --pgp2\n"
 
 msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr "debe usar ficheros (no tuberías) si trabaja con --pgp2 activo.\n"
+msgstr "debe usar ficheros (no tuberías) si trabaja con --pgp2 activo.\n"
 
 msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
 msgstr "cifrar un mensaje en modo --pgp2 requiere el algoritmo IDEA\n"
 
 msgid "selected cipher algorithm is invalid\n"
-msgstr "el algoritmo de cifrado seleccionado es inválido\n"
+msgstr "el algoritmo de cifrado seleccionado es inválido\n"
 
 msgid "selected digest algorithm is invalid\n"
-msgstr "el algoritmo de resumen seleccionado no inválido\n"
+msgstr "el algoritmo de resumen seleccionado no inválido\n"
 
 msgid "selected compression algorithm is invalid\n"
-msgstr "el algoritmo de compresión seleccionado es inválido\n"
+msgstr "el algoritmo de compresión seleccionado es inválido\n"
 
 msgid "selected certification digest algorithm is invalid\n"
-msgstr "el algoritmo de certificación por resumen elegido es inválido\n"
+msgstr "el algoritmo de certificación por resumen elegido es inválido\n"
 
 msgid "completes-needed must be greater than 0\n"
 msgstr "completes-needed debe ser mayor que 0\n"
@@ -2023,10 +1930,10 @@ msgid "max-cert-depth must be in the range from 1 to 255\n"
 msgstr "max-cert-depth debe estar en el rango de 1 a 255\n"
 
 msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n"
-msgstr "default-cert-level inválido; debe ser 0, 1, 2, ó 3\n"
+msgstr "default-cert-level inválido; debe ser 0, 1, 2, ó 3\n"
 
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
-msgstr "min-cert-level inválido; debe ser 0, 1, 2, ó 3\n"
+msgstr "min-cert-level inválido; debe ser 0, 1, 2, ó 3\n"
 
 msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
 msgstr "NOTA: el modo S2K simple (0) no es nada recomendable\n"
@@ -2035,39 +1942,39 @@ msgid "invalid S2K mode; must be 0, 1 or 3\n"
 msgstr "modo S2K incorrecto; debe ser 0, 1 o 3\n"
 
 msgid "invalid default preferences\n"
-msgstr "preferencias predeterminadas inválidas\n"
+msgstr "preferencias por defecto inválidas\n"
 
 msgid "invalid personal cipher preferences\n"
-msgstr "preferencias personales de cifrado inválidas\n"
+msgstr "preferencias personales de cifrado inválidas\n"
 
 msgid "invalid personal digest preferences\n"
-msgstr "preferencias personales de algoritmo de resumen inválidas\n"
+msgstr "preferencias personales de algoritmo de resumen inválidas\n"
 
 msgid "invalid personal compress preferences\n"
-msgstr "preferencias personales de compresión inválidas\n"
+msgstr "preferencias personales de compresión inválidas\n"
 
 #, c-format
 msgid "%s does not yet work with %s\n"
-msgstr "%s aún no funciona con %s\n"
+msgstr "%s aún no funciona con %s\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "no puede usar el cifrado `%s' en modo %s\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "no puede usar el resumen `%s' en modo %s\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
-msgstr "no puede usar la compresión `%s' en modo %s\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgstr "no puede usar la compresión `%s' en modo %s\n"
 
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
-msgstr "inicialización de la base de datos de confianza fallida: %s\n"
+msgstr "inicialización de la base de datos de confianza fallida: %s\n"
 
 msgid "WARNING: recipients (-r) given without using public key encryption\n"
-msgstr "ATENCIÓN: se indicaron receptores (-r) sin clave pública de cifrado\n"
+msgstr "AVISO: se indicaron receptores (-r) sin clave pública de cifrado\n"
 
 msgid "--store [filename]"
 msgstr "--store [nombre_fichero]"
@@ -2076,8 +1983,8 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [nombre_fichero]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
-msgstr "el cifrado simétrico de `%s' falló: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
+msgstr "el cifrado simétrico de `%s' falló: %s\n"
 
 msgid "--encrypt [filename]"
 msgstr "--encrypt [nombre_fichero]"
@@ -2124,108 +2031,107 @@ msgid "--lsign-key user-id"
 msgstr "--lsign-key id-usuario"
 
 msgid "--edit-key user-id [commands]"
-msgstr "--edit-key id-usuario [órdenes]"
-
-msgid "--passwd <user-id>"
-msgstr "--passwd <id-usuario>"
+msgstr "--edit-key id-usuario [órdenes]"
 
 #, c-format
 msgid "keyserver send failed: %s\n"
-msgstr "envío al servidor de claves fallido: %s\n"
+msgstr "envío al servidor de claves fallido: %s\n"
 
 #, c-format
 msgid "keyserver receive failed: %s\n"
-msgstr "recepción del servidor de claves fallida: %s\n"
+msgstr "recepción del servidor de claves fallida: %s\n"
 
 #, c-format
 msgid "key export failed: %s\n"
-msgstr "exportación de clave fallida: %s\n"
+msgstr "exportación de clave fallida: %s\n"
 
 #, c-format
 msgid "keyserver search failed: %s\n"
-msgstr "búsqueda del servidor de claves fallida: %s\n"
+msgstr "búsqueda del servidor de claves fallida: %s\n"
 
 #, c-format
 msgid "keyserver refresh failed: %s\n"
-msgstr "renovación al servidor de claves fallida: %s\n"
+msgstr "renovación al servidor de claves fallida: %s\n"
 
 #, c-format
 msgid "dearmoring failed: %s\n"
-msgstr "eliminación de armadura fallida: %s\n"
+msgstr "eliminación de armadura fallida: %s\n"
 
 #, c-format
 msgid "enarmoring failed: %s\n"
-msgstr "creación de armadura fallida: %s\n"
+msgstr "creación de armadura fallida: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
-msgstr "algoritmo de distribución inválido `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
+msgstr "algoritmo de distribución inválido `%s'\n"
 
 msgid "[filename]"
 msgstr "[nombre_fichero]"
 
 # Falta un espacio.
-# En español no se deja espacio antes de los puntos suspensivos
+# En español no se deja espacio antes de los puntos suspensivos
 # (Real Academia dixit) :)
-# Tomo nota :-). Este comentario déjalo siempre.
+# Tomo nota :-). Este comentario déjalo siempre.
 msgid "Go ahead and type your message ...\n"
 msgstr "Adelante, teclee su mensaje...\n"
 
 msgid "the given certification policy URL is invalid\n"
-msgstr "URL de política de certificado inválida\n"
+msgstr "URL de política de certificado inválida\n"
 
 msgid "the given signature policy URL is invalid\n"
-msgstr "URL de política inválida\n"
+msgstr "URL de política inválida\n"
 
 msgid "the given preferred keyserver URL is invalid\n"
-msgstr "la URL del servidor de claves preferido no es válida\n"
+msgstr "la URL del servidor de claves preferido no es válida\n"
 
 msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|FICHERO|tomar las claves del almacén FILE"
+msgstr "|FICHERO|tomar las claves del anillo FILE"
 
+# o tal vez "en el sello..."
+# Creo que es mejor "con el sello de fecha", no es un conflicto
+# del sello en si mismo sino en relación con el mensaje.
+# Ok.
 msgid "make timestamp conflicts only a warning"
-msgstr "hacer que los conflictos de fecha-hora sean sólo un aviso"
+msgstr "hacer que los conflictos de fecha-hora sean sólo un aviso"
 
 msgid "|FD|write status info to this FD"
-msgstr "|DF|escribe información de estado en este descriptor de fichero"
+msgstr "|DF|escribe información de estado en este descriptor de fichero"
 
 msgid "Usage: gpgv [options] [files] (-h for help)"
 msgstr "Uso: gpgv [opciones] [ficheros] (-h para ayuda)"
 
+#, fuzzy
 msgid ""
 "Syntax: gpgv [options] [files]\n"
 "Check signatures against known trusted keys\n"
 msgstr ""
-"Sintaxis: gpgv [opciones] [ficheros]\n"
-"Confrontar las firmas frente a claves fiables conocidas\n"
+"Sintaxis: gpg [opciones] [ficheros]\n"
+"Confrontar las firmas contra claves conocidas\n"
 
 msgid "No help available"
 msgstr "Ayuda no disponible"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "No hay ayuda disponible para `%s'"
 
 msgid "import signatures that are marked as local-only"
-msgstr "importar firmas marcadas como sólo locales"
+msgstr "importar firmas marcadas como sólo locales"
 
 msgid "repair damage from the pks keyserver during import"
-msgstr "reparar daño del servidor de claves públicas al importar"
-
-msgid "do not clear the ownertrust values during import"
-msgstr "no actualiza la base de datos de confianza después de importar"
+msgstr "reparar daño del servidor de claves públicas al importar"
 
 msgid "do not update the trustdb after import"
-msgstr "no actualiza la base de datos de confianza después de importar"
+msgstr "no actualiza la base de datos de confianza después de importar"
 
 msgid "create a public key when importing a secret key"
-msgstr "crear una clave pública al importar una clave secreta"
+msgstr "crear una clave pública al importar una clave secreta"
 
 msgid "only accept updates to existing keys"
-msgstr "sólo aceptar actualizaciones de claves ya existentes"
+msgstr "sólo aceptar actualizaciones de claves ya existentes"
 
 msgid "remove unusable parts from key after import"
-msgstr "borrar partes inútiles de la clave después de importar"
+msgstr "borrar partes inútiles de la clave después de importar"
 
 msgid "remove as much as possible from key after import"
 msgstr "borrar tanto como sea posible de la clave tras importar"
@@ -2276,7 +2182,7 @@ msgstr "        nuevas revocaciones de claves: %lu\n"
 
 #, c-format
 msgid "      secret keys read: %lu\n"
-msgstr "     claves secretas leídas: %lu\n"
+msgstr "     claves secretas leídas: %lu\n"
 
 #, c-format
 msgid "  secret keys imported: %lu\n"
@@ -2303,7 +2209,7 @@ msgid ""
 "WARNING: key %s contains preferences for unavailable\n"
 "algorithms on these user IDs:\n"
 msgstr ""
-"ATENCIÓN: la clave %s contiene preferencias para algoritmos\n"
+"AVISO: la clave %s contiene preferencias para algoritmos\n"
 "no disponibles en estos IDs de usuario:\n"
 
 #, c-format
@@ -2316,7 +2222,7 @@ msgstr "         \"%s\": algoritmo de resumen preferido %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for compression algorithm %s\n"
-msgstr "         \"%s\": algoritmo de compresión preferido %s\n"
+msgstr "         \"%s\": algoritmo de compresión preferido %s\n"
 
 msgid "it is strongly suggested that you update your preferences and\n"
 msgstr "se recomienda encarecidamente que actualice sus preferencias y\n"
@@ -2336,15 +2242,8 @@ msgid "key %s: no user ID\n"
 msgstr "clave %s: sin identificador de usuario\n"
 
 #, c-format
-msgid "key %s: %s\n"
-msgstr "omitido \"%s\": %s\n"
-
-msgid "rejected by import filter"
-msgstr "rechazado por el filtro de importación"
-
-#, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
-msgstr "clave %s: se ha reparado la corrupción en la subclave PKS\n"
+msgstr "clave %s: reparada la subclave PKS corrompida\n"
 
 #, c-format
 msgid "key %s: accepted non self-signed user ID \"%s\"\n"
@@ -2352,14 +2251,14 @@ msgstr "clave %s: aceptado ID de usuario sin autofirma \"%s\"\n"
 
 #, c-format
 msgid "key %s: no valid user IDs\n"
-msgstr "clave %s: sin identificadores de usuario válidos\n"
+msgstr "clave %s: sin identificadores de usuario válidos\n"
 
 msgid "this may be caused by a missing self-signature\n"
 msgstr "esto puede ser debido a la ausencia de autofirma\n"
 
 #, c-format
 msgid "key %s: public key not found: %s\n"
-msgstr "clave %s: clave pública no encontrada: %s\n"
+msgstr "clave %s: clave pública no encontrada: %s\n"
 
 #, c-format
 msgid "key %s: new key - skipped\n"
@@ -2367,19 +2266,19 @@ msgstr "clave %s: clave nueva - omitida\n"
 
 #, c-format
 msgid "no writable keyring found: %s\n"
-msgstr "almacén de claves no modificable encontrado: %s\n"
+msgstr "anillo de claves no escribible encontrado: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "escribiendo en `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
-msgstr "error escribiendo almacén `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
+msgstr "error escribiendo anillo `%s': %s\n"
 
 #, c-format
 msgid "key %s: public key \"%s\" imported\n"
-msgstr "clave %s: clave pública \"%s\" importada\n"
+msgstr "clave %s: clave pública \"%s\" importada\n"
 
 #, c-format
 msgid "key %s: doesn't match our copy\n"
@@ -2438,19 +2337,15 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "clave %s: \"%s\" sin cambios\n"
 
 #, c-format
-msgid "secret key %s: %s\n"
-msgstr "clave secreta \"%s\" no encontrada: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "clave %s: clave secreta con cifrado inválido %d - omitida\n"
 
 msgid "importing secret keys not allowed\n"
 msgstr "no se permite importar claves secretas\n"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "clave %s: clave secreta con cifrado inválido %d - omitida\n"
-
-#, c-format
 msgid "no default secret keyring: %s\n"
-msgstr "no hay almacén secreto de claves predeterminado: %s\n"
+msgstr "no hay anillo secreto de claves por defecto: %s\n"
 
 #, c-format
 msgid "key %s: secret key imported\n"
@@ -2458,7 +2353,7 @@ msgstr "clave %s: clave secreta importada\n"
 
 #, c-format
 msgid "key %s: already in secret keyring\n"
-msgstr "clave %s: ya estaba en el almacén secreto\n"
+msgstr "clave %s: ya estaba en el anillo secreto\n"
 
 #, c-format
 msgid "key %s: secret key not found: %s\n"
@@ -2467,16 +2362,16 @@ msgstr "clave %s: clave secreta no encontrada: %s\n"
 #, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
 msgstr ""
-"clave %s: falta la clave pública - imposible emplear el\n"
-"certificado de revocación\n"
+"clave %s: falta la clave pública - imposible emplear el\n"
+"certificado de revocación\n"
 
 #, c-format
 msgid "key %s: invalid revocation certificate: %s - rejected\n"
-msgstr "clave %s: certificado de revocación inválido: %s - rechazado\n"
+msgstr "clave %s: certificado de revocación inválido: %s - rechazado\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate imported\n"
-msgstr "clave %s: \"%s\" certificado de revocación importado\n"
+msgstr "clave %s: \"%s\" certificado de revocación importado\n"
 
 #, c-format
 msgid "key %s: no user ID for signature\n"
@@ -2484,43 +2379,39 @@ msgstr "clave %s: no hay identificador de usuario para la firma\n"
 
 #, c-format
 msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
-msgstr "clave %s: algoritmo de clave pública no disponible para ID \"%s\"\n"
+msgstr "clave %s: algoritmo de clave pública no disponible para ID \"%s\"\n"
 
 #, c-format
 msgid "key %s: invalid self-signature on user ID \"%s\"\n"
-msgstr "clave %s: autofirma inválida para el id \"%s\"\n"
-
-#, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "clave %s: algoritmo de clave pública no disponible\n"
-
-#, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "clave %s: firma directa de clave inválida\n"
+msgstr "clave %s: autofirma inválida para el id \"%s\"\n"
 
 #, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "clave %s: no hay subclave que unir a la clave\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "clave %s: algoritmo de clave pública no disponible\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
-msgstr "clave %s: unión de subclave inválida\n"
+msgstr "clave %s: unión de subclave inválida\n"
 
 #, c-format
 msgid "key %s: removed multiple subkey binding\n"
-msgstr "clave %s: borrado enlace de subclaves múltiples\n"
+msgstr "clave %s: borrado enlace de subclaves múltiples\n"
 
 #, c-format
 msgid "key %s: no subkey for key revocation\n"
-msgstr "clave %s: no hay subclave para la revocación de clave\n"
+msgstr "clave %s: no hay subclave para la revocación de clave\n"
 
 #, c-format
 msgid "key %s: invalid subkey revocation\n"
-msgstr "clave %s: revocación de subclave inválida\n"
+msgstr "clave %s: revocación de subclave inválida\n"
 
 #, c-format
 msgid "key %s: removed multiple subkey revocation\n"
-msgstr "clave %s: borrada revocación de subclave múltiple\n"
+msgstr "clave %s: borrada revocación de subclave múltiple\n"
 
 #, c-format
 msgid "key %s: skipped user ID \"%s\"\n"
@@ -2536,11 +2427,11 @@ msgstr "clave %s: firma no exportable (clase 0x%02x) - omitida\n"
 
 #, c-format
 msgid "key %s: revocation certificate at wrong place - skipped\n"
-msgstr "clave %s: certificado de revocación en lugar equivocado - omitido\n"
+msgstr "clave %s: certificado de revocación en lugar equivocado - omitido\n"
 
 #, c-format
 msgid "key %s: invalid revocation certificate: %s - skipped\n"
-msgstr "clave %s: certificado de revocación no valido: %s - omitido\n"
+msgstr "clave %s: certificado de revocación no valido: %s - omitido\n"
 
 #, c-format
 msgid "key %s: subkey signature in wrong place - skipped\n"
@@ -2557,49 +2448,48 @@ msgstr "clave %s: detectado usuario duplicado - fusionada\n"
 #, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
 msgstr ""
-"ATENCIÓN: la clave %s puede estar revocada: recuperando clave de revocación "
-"%s\n"
+"AVISO: la clave %s puede estar revocada: recuperando clave de revocación %s\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
 msgstr ""
-"ATENCIÓN: la clave %s puede estar revocada: falta clave de revocación %s.\n"
+"AVISO: la clave %s puede estar revocada: falta clave de revocación %s.\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate added\n"
-msgstr "clave %s: \"%s\" certificado de revocación añadido\n"
+msgstr "clave %s: \"%s\" certificado de revocación añadido\n"
 
 #, c-format
 msgid "key %s: direct key signature added\n"
-msgstr "clave %s: firma directa de clave añadida\n"
+msgstr "clave %s: firma directa de clave añadida\n"
 
 msgid "NOTE: a key's S/N does not match the card's one\n"
 msgstr "NOTA: un S/N de la clave no coincide con la de la tarjeta\n"
 
 msgid "NOTE: primary key is online and stored on card\n"
-msgstr "NOTA: clave primaria en línea y almacenada en la tarjeta\n"
+msgstr "NOTA: clave primaria en línea y almacenada en la tarjeta\n"
 
 msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "NOTA: clave secundaria en línea y almacenada en la tarjeta\n"
+msgstr "NOTA: clave secundaria en línea y almacenada en la tarjeta\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
-msgstr "error escribiendo almacén `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
+msgstr "error escribiendo anillo `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
-msgstr "almacén `%s' creado\n"
+msgid "keyring '%s' created\n"
+msgstr "anillo `%s' creado\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "recurso de bloque de claves: `%s': %s\n"
 
 #, c-format
 msgid "failed to rebuild keyring cache: %s\n"
-msgstr "fallo reconstruyendo caché del almacén de claves: %s\n"
+msgstr "fallo reconstruyendo caché del anillo de claves: %s\n"
 
 msgid "[revocation]"
-msgstr "[revocación]"
+msgstr "[revocación]"
 
 msgid "[self-signature]"
 msgstr "[autofirma]"
@@ -2626,11 +2516,11 @@ msgid "%d signatures not checked due to errors\n"
 msgstr "%d firmas no comprobadas por errores\n"
 
 msgid "1 user ID without valid self-signature detected\n"
-msgstr "Detectado 1 identificador de usuario sin autofirma válida\n"
+msgstr "Detectado 1 identificador de usuario sin autofirma válida\n"
 
 #, c-format
 msgid "%d user IDs without valid self-signatures detected\n"
-msgstr "Detectados %d identificadores de usuario sin autofirma válida\n"
+msgstr "Detectados %d identificadores de usuario sin autofirma válida\n"
 
 msgid ""
 "Please decide how far you trust this user to correctly verify other users' "
@@ -2638,26 +2528,26 @@ msgid ""
 "(by looking at passports, checking fingerprints from different sources, "
 "etc.)\n"
 msgstr ""
-"Decida su nivel de confianza en que este usuario\n"
+"Por favor, decida su nivel de confianza en que este usuario\n"
 "verifique correctamente las claves de otros usuarios (mirando\n"
 "pasaportes, comprobando huellas dactilares en diferentes fuentes...)\n"
 "\n"
 
 #, c-format
 msgid "  %d = I trust marginally\n"
-msgstr " %d = Confío un poco\n"
+msgstr " %d = Confío un poco\n"
 
 #, c-format
 msgid "  %d = I trust fully\n"
-msgstr " %d = Confío totalmente\n"
+msgstr " %d = Confío totalmente\n"
 
 msgid ""
 "Please enter the depth of this trust signature.\n"
 "A depth greater than 1 allows the key you are signing to make\n"
 "trust signatures on your behalf.\n"
 msgstr ""
-"Introduzca el nivel de esta firma de confianza.\n"
-"Un nivel mayor que 1 permite que la clave que está firmando pueda\n"
+"Por favor, introduzca el nivel de esta firma de confianza.\n"
+"Un nivel mayor que 1 permite que la clave que está firmando pueda\n"
 "hacer firmas de confianza en su nombre.\n"
 
 msgid "Please enter a domain to restrict this signature, or enter for none.\n"
@@ -2668,7 +2558,7 @@ msgid "User ID \"%s\" is revoked."
 msgstr "ID de usuario \"%s\" revocado."
 
 msgid "Are you sure you still want to sign it? (y/N) "
-msgstr "¿Seguro que todavía quiere firmarlo? (s/N) "
+msgstr "¿Seguro que todavía quiere firmarlo? (s/N) "
 
 msgid "  Unable to sign.\n"
 msgstr "  Imposible firmar.\n"
@@ -2686,7 +2576,7 @@ msgid "User ID \"%s\" is signable.  "
 msgstr "ID de usuario \"%s\" puede firmarse."
 
 msgid "Sign it? (y/N) "
-msgstr "¿Firmarlo? (s/N) "
+msgstr "¿Firmarlo? (s/N) "
 
 #, c-format
 msgid ""
@@ -2708,7 +2598,7 @@ msgstr ""
 "ha expirado.\n"
 
 msgid "Do you want to issue a new signature to replace the expired one? (y/N) "
-msgstr "¿Quiere producir una nueva firma que reemplace a la expirada? (s/N) "
+msgstr "¿Quiere producir una nueva firma que reemplace a la expirada? (s/N) "
 
 #, c-format
 msgid ""
@@ -2730,21 +2620,21 @@ msgid "\"%s\" was already signed by key %s\n"
 msgstr "\"%s\" ya estaba firmada por la clave %s\n"
 
 msgid "Do you want to sign it again anyway? (y/N) "
-msgstr "¿Quiere firmarlo aún así? (s/N) "
+msgstr "¿Quiere firmarlo aún así? (s/N) "
 
 #, c-format
 msgid "Nothing to sign with key %s\n"
 msgstr "Nada que firmar con la clave %s\n"
 
 msgid "This key has expired!"
-msgstr "¡Esta clave ha caducado!"
+msgstr "¡Esta clave ha caducado!"
 
 #, c-format
 msgid "This key is due to expire on %s.\n"
-msgstr "Esta clave expirará el %s.\n"
+msgstr "Esta clave expirará el %s.\n"
 
 msgid "Do you want your signature to expire at the same time? (Y/n) "
-msgstr "¿Quiere que su firma caduque al mismo tiempo? (S/n) "
+msgstr "¿Quiere que su firma caduque al mismo tiempo? (S/n) "
 
 msgid ""
 "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
@@ -2754,14 +2644,14 @@ msgstr ""
 "pgp2.\n"
 
 msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "Esto inutilizaría la clave en PGP 2.x.\n"
+msgstr "Esto inutilizaría la clave en PGP 2.x.\n"
 
 msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
 msgstr ""
-"¿Cómo de cuidadosamente ha verificado que la clave que está a punto de\n"
+"¿Cómo de cuidadosamente ha verificado que la clave que está a punto de\n"
 "firmar pertenece realmente a la persona arriba nombrada? Si no sabe que\n"
 "contestar, introduzca \"0\".\n"
 
@@ -2775,37 +2665,37 @@ msgstr "   (1) No lo he comprobado en absoluto.%s\n"
 
 #, c-format
 msgid "   (2) I have done casual checking.%s\n"
-msgstr "   (2) He hecho una comprobación informal.%s\n"
+msgstr "   (2) He hecho una comprobación informal.%s\n"
 
 #, c-format
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Lo he comprobado meticulosamente.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
-msgstr "¿Su elección? (escriba '?' si desea más información): "
+msgid "Your selection? (enter '?' for more information): "
+msgstr "¿Su elección? (escriba '?' si desea más información): "
 
 #, c-format
 msgid ""
 "Are you sure that you want to sign this key with your\n"
 "key \"%s\" (%s)\n"
 msgstr ""
-"¿Está realmente seguro de querer firmar esta clave\n"
+"¿Está realmente seguro de querer firmar esta clave\n"
 "con su clave: \"%s\" (%s)?\n"
 
 msgid "This will be a self-signature.\n"
-msgstr "Esto será una autofirma.\n"
+msgstr "Esto será una autofirma.\n"
 
 msgid "WARNING: the signature will not be marked as non-exportable.\n"
-msgstr "ATENCION: la firma no se marcará como no exportable.\n"
+msgstr "ATENCION: la firma no se marcará como no exportable.\n"
 
 msgid "WARNING: the signature will not be marked as non-revocable.\n"
-msgstr "ATENCIÓN: la firma no se marcará como no revocable.\n"
+msgstr "AVISO: la firma no se marcará como no revocable.\n"
 
 msgid "The signature will be marked as non-exportable.\n"
-msgstr "La firma se marcará como no exportable.\n"
+msgstr "La firma se marcará como no exportable.\n"
 
 msgid "The signature will be marked as non-revocable.\n"
-msgstr "La firma se marcará como no revocable.\n"
+msgstr "La firma se marcará como no revocable.\n"
 
 msgid "I have not checked this key at all.\n"
 msgstr "No he comprobado esta clave en absoluto.\n"
@@ -2817,7 +2707,7 @@ msgid "I have checked this key very carefully.\n"
 msgstr "He comprobado esta clave meticulosamente.\n"
 
 msgid "Really sign? (y/N) "
-msgstr "¿Firmar de verdad? (s/N) "
+msgstr "¿Firmar de verdad? (s/N) "
 
 #, c-format
 msgid "signing failed: %s\n"
@@ -2825,20 +2715,20 @@ msgstr "firma fallida: %s\n"
 
 msgid "Key has only stub or on-card key items - no passphrase to change.\n"
 msgstr ""
-"La clave tiene sólo un apuntador u objetos de clave en la propia tarjeta\n"
-"- no hay contraseña que cambiar.\n"
+"La clave tiene sólo un apuntador u objetos de clave en la propia tarjeta\n"
+"- no hay frase contraseña que cambiar.\n"
 
 msgid "This key is not protected.\n"
-msgstr "Esta clave no está protegida.\n"
+msgstr "Esta clave no está protegida.\n"
 
 msgid "Secret parts of primary key are not available.\n"
-msgstr "Las partes secretas de la clave primaria no están disponibles.\n"
+msgstr "Las partes secretas de la clave primaria no están disponibles.\n"
 
 msgid "Secret parts of primary key are stored on-card.\n"
 msgstr "Las partes secretas de la clave primaria se guardan en la tarjeta.\n"
 
 msgid "Key is protected.\n"
-msgstr "La clave está protegida.\n"
+msgstr "La clave está protegida.\n"
 
 #, c-format
 msgid "Can't edit this key: %s\n"
@@ -2848,21 +2738,21 @@ msgid ""
 "Enter the new passphrase for this secret key.\n"
 "\n"
 msgstr ""
-"Introduzca la nueva contraseña para esta clave secreta.\n"
+"Introduzca la nueva frase contraseña para esta clave secreta.\n"
 "\n"
 
 msgid "passphrase not correctly repeated; try again"
-msgstr "contraseña repetida incorrectamente; inténtelo de nuevo"
+msgstr "frase contraseña repetida incorrectamente; inténtelo de nuevo"
 
 msgid ""
 "You don't want a passphrase - this is probably a *bad* idea!\n"
 "\n"
 msgstr ""
-"No ha especificado contraseña. Esto es probablemente una *mala* idea.\n"
+"No ha especificado frase contraseña. Esto es probablemente una *mala* idea.\n"
 "\n"
 
 msgid "Do you really want to do this? (y/N) "
-msgstr "¿Realmente quiere hacer esto? (s/N) "
+msgstr "¿Realmente quiere hacer esto? (s/N) "
 
 msgid "moving a key signature to the correct place\n"
 msgstr "moviendo la firma de la clave al lugar correcto\n"
@@ -2886,7 +2776,7 @@ msgid "check signatures"
 msgstr "comprueba firmas"
 
 msgid "sign selected user IDs [* see below for related commands]"
-msgstr "firmar IDs seleccionadas [* ver debajo órdenes relacionadas]"
+msgstr "firmar IDs seleccionadas [* ver debajo órdenes relacionadas]"
 
 msgid "sign selected user IDs locally"
 msgstr "firma localmente los IDs de usuarios elegidos"
@@ -2898,19 +2788,19 @@ msgid "sign selected user IDs with a non-revocable signature"
 msgstr "firmar IDs seleccionados con firma no revocable"
 
 msgid "add a user ID"
-msgstr "añadir un identificador de usuario"
+msgstr "añadir un identificador de usuario"
 
 msgid "add a photo ID"
-msgstr "añadir un ID fotográfico"
+msgstr "añadir un ID fotográfico"
 
 msgid "delete selected user IDs"
 msgstr "borrar identificadores de usuario seleccionados"
 
 msgid "add a subkey"
-msgstr "añadir una subclave"
+msgstr "añadir una subclave"
 
 msgid "add a key to a smartcard"
-msgstr "añadir clave a tarjeta"
+msgstr "añadir clave a tarjeta"
 
 msgid "move a key to a smartcard"
 msgstr "mover una clave a la tarjeta"
@@ -2922,7 +2812,7 @@ msgid "delete selected subkeys"
 msgstr "borrar clave secundaria"
 
 msgid "add a revocation key"
-msgstr "añadir una clave de revocación"
+msgstr "añadir una clave de revocación"
 
 msgid "delete signatures from the selected user IDs"
 msgstr "borrar firmas de los ID seleccionados"
@@ -2934,7 +2824,7 @@ msgid "flag the selected user ID as primary"
 msgstr "marcar ID de usuario seleccionado como primario"
 
 msgid "toggle between the secret and public key listings"
-msgstr "cambiar entre lista de claves secretas y públicas"
+msgstr "cambiar entre lista de claves secretas y públicas"
 
 msgid "list preferences (expert)"
 msgstr "mostrar preferencias (experto)"
@@ -2949,10 +2839,10 @@ msgid "set the preferred keyserver URL for the selected user IDs"
 msgstr "establecer URL del servidor de claves preferido por los IDs elegidos"
 
 msgid "set a notation for the selected user IDs"
-msgstr "establecer notación para los IDs de usuario seleccionados"
+msgstr "establecer notación para los IDs de usuario seleccionados"
 
 msgid "change the passphrase"
-msgstr "cambia la contraseña"
+msgstr "cambia la frase contraseña"
 
 msgid "change the ownertrust"
 msgstr "cambia valores de confianza"
@@ -2992,7 +2882,7 @@ msgid "Need the secret key to do this.\n"
 msgstr "Se necesita la clave secreta para hacer esto.\n"
 
 msgid "Please use the command \"toggle\" first.\n"
-msgstr "Utilice primero la orden \"cambia\".\n"
+msgstr "Por favor use la orden \"cambia\" primero.\n"
 
 msgid ""
 "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -3002,19 +2892,19 @@ msgid ""
 msgstr ""
 "* La orden `sign' (firmar) puede estar precedida por una 'l' para firmas\n"
 "locales (lsign), una 't' para firmas fiables (tsign), `nr' para firmas no\n"
-"revocables (nrsign) o cualquier combinación de ellas (ltsign, tnrsign, etc)\n"
+"revocables (nrsign) o cualquier combinación de ellas (ltsign, tnrsign, etc)\n"
 
 msgid "Key is revoked."
-msgstr "La clave está revocada."
+msgstr "La clave está revocada."
 
 msgid "Really sign all user IDs? (y/N) "
-msgstr "¿Firmar realmente todos los IDs de usuario? (s/N) "
+msgstr "¿Firmar realmente todos los IDs de usuario? (s/N) "
 
 msgid "Hint: Select the user IDs to sign\n"
 msgstr "Sugerencia: seleccione los identificadores de usuario que firmar\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Clase de firma desconocida `%s'\n"
 
 #, c-format
@@ -3025,18 +2915,19 @@ msgid "You must select at least one user ID.\n"
 msgstr "Debe seleccionar por lo menos un identificador de usuario.\n"
 
 msgid "You can't delete the last user ID!\n"
-msgstr "¡No puede borrar el último identificador de usuario!\n"
+msgstr "¡No puede borrar el último identificador de usuario!\n"
 
 msgid "Really remove all selected user IDs? (y/N) "
-msgstr "¿Borrar realmente todos los identificadores seleccionados? (s/N) "
+msgstr "¿Borrar realmente todos los identificadores seleccionados? (s/N) "
 
 msgid "Really remove this user ID? (y/N) "
-msgstr "¿Borrar realmente este identificador de usuario? (s/N) "
+msgstr "¿Borrar realmente este identificador de usuario? (s/N) "
 
 #. TRANSLATORS: Please take care: This is about
 #. moving the key and not about removing it.
+#, fuzzy
 msgid "Really move the primary key? (y/N) "
-msgstr "¿Realmente cambiar de sitio la clave primaria? (s/N)"
+msgstr "¿Borrar FIXME la clave primaria? (s/N)"
 
 msgid "You must select exactly one key.\n"
 msgstr "Debe seleccionar exactamente una clave.\n"
@@ -3045,40 +2936,40 @@ msgid "Command expects a filename argument\n"
 msgstr "La orden espera un nombre de fichero como argumento\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "No se puede abrir `%s': %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Error leyendo clave de respaldo desde `%s': %s\n"
 
 msgid "You must select at least one key.\n"
 msgstr "Debe seleccionar por lo menos una clave.\n"
 
 msgid "Do you really want to delete the selected keys? (y/N) "
-msgstr "¿De verdad quiere borrar las claves seleccionadas? (s/N) "
+msgstr "¿De verdad quiere borrar las claves seleccionadas? (s/N) "
 
 msgid "Do you really want to delete this key? (y/N) "
-msgstr "¿De verdad quiere borrar esta clave? (s/N) "
+msgstr "¿De verdad quiere borrar esta clave? (s/N) "
 
 msgid "Really revoke all selected user IDs? (y/N) "
-msgstr "¿Revocar realmente todos los identificadores seleccionados? (s/N) "
+msgstr "¿Revocar realmente todos los identificadores seleccionados? (s/N) "
 
 msgid "Really revoke this user ID? (y/N) "
-msgstr "¿Revocar realmente este identificador de usuario? (s/N) "
+msgstr "¿Revocar realmente este identificador de usuario? (s/N) "
 
 msgid "Do you really want to revoke the entire key? (y/N) "
-msgstr "¿De verdad quiere revocar la clave completa? (s/N) "
+msgstr "¿De verdad quiere revocar la clave completa? (s/N) "
 
 msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgstr "¿De verdad quiere revocar las subclaves seleccionadas? (s/N)"
+msgstr "¿De verdad quiere revocar las subclaves seleccionadas? (s/N)"
 
 msgid "Do you really want to revoke this subkey? (y/N) "
-msgstr "¿De verdad quiere revocar esta subclave? (s/N) "
+msgstr "¿De verdad quiere revocar esta subclave? (s/N) "
 
 msgid "Owner trust may not be set while using a user provided trust database\n"
 msgstr ""
-"La confianza del propietario no puede establecerse si se está usando\n"
+"La confianza del propietario no puede establecerse si se está usando\n"
 "una base de datos de confianza propocionada por el usuario\n"
 
 msgid "Set preference list to:\n"
@@ -3086,33 +2977,33 @@ msgstr "Establecer lista de preferencias a:\n"
 
 msgid "Really update the preferences for the selected user IDs? (y/N) "
 msgstr ""
-"¿Actualizar realmente las preferencias para los ID seleccionados? (s/N) "
+"¿Actualizar realmente las preferencias para los ID seleccionados? (s/N) "
 
 msgid "Really update the preferences? (y/N) "
-msgstr "¿Actualizar realmente las preferencias? (s/N) "
+msgstr "¿Actualizar realmente las preferencias? (s/N) "
 
 msgid "Save changes? (y/N) "
-msgstr "¿Grabar cambios? (s/N) "
+msgstr "¿Grabar cambios? (s/N) "
 
 msgid "Quit without saving? (y/N) "
-msgstr "¿Salir sin grabar? (s/N) "
+msgstr "¿Salir sin grabar? (s/N) "
 
 #, c-format
 msgid "update failed: %s\n"
-msgstr "actualización fallida: %s\n"
+msgstr "actualización fallida: %s\n"
 
 #, c-format
 msgid "update secret failed: %s\n"
-msgstr "actualización de la clave secreta fallida: %s\n"
+msgstr "actualización de la clave secreta fallida: %s\n"
 
 msgid "Key not changed so no update needed.\n"
-msgstr "Clave sin cambios, no se necesita actualización.\n"
+msgstr "Clave sin cambios, no se necesita actualización.\n"
 
 msgid "Digest: "
 msgstr "Resumen: "
 
 msgid "Features: "
-msgstr "Características: "
+msgstr "Características: "
 
 msgid "Keyserver no-modify"
 msgstr "Sevidor de claves no-modificar"
@@ -3127,8 +3018,8 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "No hay preferencias en un identificador de usuario estilo PGP 2.x\n"
 
 #, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "La siguiente clave fue revocada en %s por %s clave %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
+msgstr "Esta clave fue revocada en %s por %s clave %s\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
@@ -3147,7 +3038,7 @@ msgstr "revocada: %s"
 
 #, c-format
 msgid "expired: %s"
-msgstr "caducó: %s"
+msgstr "caducó: %s"
 
 #, c-format
 msgid "expires: %s"
@@ -3166,7 +3057,7 @@ msgid "validity: %s"
 msgstr "validez: %s"
 
 msgid "This key has been disabled"
-msgstr "Esta clave está deshabilitada"
+msgstr "Esta clave está deshabilitada"
 
 msgid "card-no: "
 msgstr "num. tarjeta: "
@@ -3175,7 +3066,7 @@ msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
 msgstr ""
-"Advierta que la validez de clave mostrada no es necesariamente\n"
+"Por favor, advierta que la validez de clave mostrada no es necesariamente\n"
 "correcta a menos de que reinicie el programa.\n"
 
 msgid "revoked"
@@ -3188,44 +3079,34 @@ msgid ""
 "WARNING: no user ID has been marked as primary.  This command may\n"
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
-"ATENCIÓN: ningún ID de usuario está marcado como principal. Esta orden "
-"puede\n"
-"       causar que se tome como identificador principal otro identificador de "
-"usuario distinto.\n"
-
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "No puede cambiar la fecha de caducidad de una clave v3\n"
+"AVISO: ningún ID de usuario está marcado como principal. Esta orden puede\n"
+"       causar que se tome como principal por defecto otro ID de usuario.\n"
 
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
 "         of PGP to reject this key.\n"
 msgstr ""
-"ATENCIÓN: esta es una clave de tipo PGP2. Añadir un ID fotográfico puede\n"
+"AVISO: esta es una clave de tipo PGP2. Añadir un ID fotográfico puede\n"
 "hacer que algunas versiones de PGP rechacen esta clave.\n"
 
 msgid "Are you sure you still want to add it? (y/N) "
-msgstr "¿Está seguro de querer añadirla? (s/N) "
+msgstr "¿Está seguro de querer añadirla? (s/N) "
 
 msgid "You may not add a photo ID to a PGP2-style key.\n"
-msgstr "No puede añadir un ID fotográfico a una clave tipo PGP2.\n"
+msgstr "No puede añadir un ID fotográfico a una clave tipo PGP2.\n"
 
 msgid "Delete this good signature? (y/N/q)"
-msgstr "¿Borrar esta firma correcta? (s/N/q)"
+msgstr "¿Borrar esta firma correcta? (s/N/q)"
 
 msgid "Delete this invalid signature? (y/N/q)"
-msgstr "¿Borrar esta firma inválida? (s/N/q)"
+msgstr "¿Borrar esta firma inválida? (s/N/q)"
 
 msgid "Delete this unknown signature? (y/N/q)"
-msgstr "¿Borrar esta firma desconocida? (s/N/q)"
+msgstr "¿Borrar esta firma desconocida? (s/N/q)"
 
 msgid "Really delete this self-signature? (y/N)"
-msgstr "¿Borrar realmente esta autofirma? (s/N)"
+msgstr "¿Borrar realmente esta autofirma? (s/N)"
 
 #, c-format
 msgid "Deleted %d signature.\n"
@@ -3236,10 +3117,10 @@ msgid "Deleted %d signatures.\n"
 msgstr "%d firmas borradas\n"
 
 msgid "Nothing deleted.\n"
-msgstr "No se borró nada\n"
+msgstr "No se borró nada\n"
 
 msgid "invalid"
-msgstr "inválida"
+msgstr "inválida"
 
 #, c-format
 msgid "User ID \"%s\" compacted: %s\n"
@@ -3266,11 +3147,11 @@ msgid ""
 "cause\n"
 "         some versions of PGP to reject this key.\n"
 msgstr ""
-"ATENCIÓN: esta es una clave tipo PGP2. Añadir un revocador designado puede\n"
+"AVISO: esta es una clave tipo PGP2. Añadir un revocador designado puede\n"
 "       hacer que algunas versiones de PGP rechacen esta clave.\n"
 
 msgid "You may not add a designated revoker to a PGP 2.x-style key.\n"
-msgstr "No puede añadir un revocador designado a una clave tipo PGP2.\n"
+msgstr "No puede añadir un revocador designado a una clave tipo PGP2.\n"
 
 msgid "Enter the user ID of the designated revoker: "
 msgstr "Introduzca el ID de usuario del revocador designado: "
@@ -3286,18 +3167,18 @@ msgstr "esta clave ya ha sido designada como revocadora\n"
 
 msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n"
 msgstr ""
-"¡ATENCIÓN: no podrá deshacer la elección de clave como revocador designado!\n"
+"¡AVISO: no podrá deshacer la elección de clave como revocador designado!\n"
 
 msgid ""
 "Are you sure you want to appoint this key as a designated revoker? (y/N) "
 msgstr ""
-"¿Está seguro de querer elegir esta clave como revocador designado? (s/N) "
+"¿Está seguro de querer elegir esta clave como revocador designado? (s/N) "
 
 msgid "Please remove selections from the secret keys.\n"
-msgstr "Quite las selecciones de las claves secretas.\n"
+msgstr "Por favor, quite las selecciones de las claves secretas.\n"
 
 msgid "Please select at most one subkey.\n"
-msgstr "Seleccione como máximo una clave secundaria.\n"
+msgstr "Por favor, seleccione como máximo una clave secundaria.\n"
 
 msgid "Changing expiration time for a subkey.\n"
 msgstr "Cambiando fecha de caducidad de subclave.\n"
@@ -3309,18 +3190,18 @@ msgid "You can't change the expiration date of a v3 key\n"
 msgstr "No puede cambiar la fecha de caducidad de una clave v3\n"
 
 msgid "No corresponding signature in secret ring\n"
-msgstr "No existe la firma correspondiente en el almacén secreto\n"
+msgstr "No existe la firma correspondiente en el anillo secreto\n"
 
 #, c-format
 msgid "signing subkey %s is already cross-certified\n"
-msgstr "la subclave de firmado %s ya está certificada en cruz\n"
+msgstr "la subclave de firmado %s ya está certificada en cruz\n"
 
 #, c-format
 msgid "subkey %s does not sign and so does not need to be cross-certified\n"
-msgstr "la subclave %s no firma y así no necesita ser certificada en cruz\n"
+msgstr "la subclave %s no firma y así no necesita ser certificada en cruz\n"
 
 msgid "Please select exactly one user ID.\n"
-msgstr "Seleccione exactamente un identificador de usuario.\n"
+msgstr "Por favor seleccione exactamente un identificador de usuario.\n"
 
 #, c-format
 msgid "skipping v3 self-signature on user ID \"%s\"\n"
@@ -3330,20 +3211,20 @@ msgid "Enter your preferred keyserver URL: "
 msgstr "Introduzca la URL de su servidor de claves preferido: "
 
 msgid "Are you sure you want to replace it? (y/N) "
-msgstr "¿Seguro que quiere reemplazarlo? (s/N) "
+msgstr "¿Seguro que quiere reemplazarlo? (s/N) "
 
 msgid "Are you sure you want to delete it? (y/N) "
-msgstr "¿Seguro que quiere borrarlo? (s/N) "
+msgstr "¿Seguro que quiere borrarlo? (s/N) "
 
 msgid "Enter the notation: "
-msgstr "Introduzca la notación: "
+msgstr "Introduzca la notación: "
 
 msgid "Proceed? (y/N) "
-msgstr "¿Continuar? (s/N) "
+msgstr "¿Continuar? (s/N) "
 
 #, c-format
 msgid "No user ID with index %d\n"
-msgstr "No hay ningún identificador de usuario con el índice %d\n"
+msgstr "No hay ningún identificador de usuario con el índice %d\n"
 
 #, c-format
 msgid "No user ID with hash %s\n"
@@ -3351,7 +3232,7 @@ msgstr "No hay ID de usuario con hash %s\n"
 
 #, c-format
 msgid "No subkey with index %d\n"
-msgstr "No existe una subclave con índice %d\n"
+msgstr "No existe una subclave con índice %d\n"
 
 #, c-format
 msgid "user ID: \"%s\"\n"
@@ -3366,16 +3247,16 @@ msgstr " (no exportable)"
 
 #, c-format
 msgid "This signature expired on %s.\n"
-msgstr "Esta firma caducó el %s.\n"
+msgstr "Esta firma caducó el %s.\n"
 
 msgid "Are you sure you still want to revoke it? (y/N) "
-msgstr "¿De verdad quiere revocarla? (s/N) "
+msgstr "¿De verdad quiere revocarla? (s/N) "
 
 msgid "Create a revocation certificate for this signature? (y/N) "
-msgstr "¿Crear un certificado de revocación para esta clave? (s/N)"
+msgstr "¿Crear un certificado de revocación para esta clave? (s/N)"
 
 msgid "Not signed by you.\n"
-msgstr "No está firmado por usted.\n"
+msgstr ""
 
 #, c-format
 msgid "You have signed these user IDs on key %s:\n"
@@ -3392,7 +3273,7 @@ msgid "You are about to revoke these signatures:\n"
 msgstr "Va a revocar las siguientes firmas:\n"
 
 msgid "Really create the revocation certificates? (y/N) "
-msgstr "¿Crear los certificados de revocación realmente? (s/N) "
+msgstr "¿Crear los certificados de revocación realmente? (s/N) "
 
 msgid "no secret key\n"
 msgstr "no hay clave secreta\n"
@@ -3403,7 +3284,7 @@ msgstr "ID de usuario \"%s\" ya ha sido revocado\n"
 
 #, c-format
 msgid "WARNING: a user ID signature is dated %d seconds in the future\n"
-msgstr "ATENCIÓN: un ID de usuario tiene fecha %d segundos en el futuro\n"
+msgstr "AVISO: un ID de usuario tiene fecha %d segundos en el futuro\n"
 
 #, c-format
 msgid "Key %s is already revoked.\n"
@@ -3415,10 +3296,10 @@ msgstr "La subclave %s ya ha sido revocada.\n"
 
 #, c-format
 msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
-msgstr "Mostrando ID fotográfico %s de tamaño %ld para la clave %s (uid %d)\n"
+msgstr "Mostrando ID fotográfico %s de tamaño %ld para la clave %s (uid %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "preferencia `%s' duplicada\n"
 
 msgid "too many cipher preferences\n"
@@ -3428,11 +3309,11 @@ msgid "too many digest preferences\n"
 msgstr "demasiadas preferencias de resumen\n"
 
 msgid "too many compression preferences\n"
-msgstr "demasiadas preferencias de compresión\n"
+msgstr "demasiadas preferencias de compresión\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
-msgstr "caracter inválido `%s' en cadena de preferencias\n"
+msgid "invalid item '%s' in preference string\n"
+msgstr "caracter inválido `%s' en cadena de preferencias\n"
 
 msgid "writing direct signature\n"
 msgstr "escribiendo firma directa\n"
@@ -3441,21 +3322,21 @@ msgid "writing self signature\n"
 msgstr "escribiendo autofirma\n"
 
 msgid "writing key binding signature\n"
-msgstr "escribiendo la firma de comprobación de clave\n"
+msgstr "escribiendo la firma de comprobación de clave\n"
 
 #, c-format
 msgid "keysize invalid; using %u bits\n"
-msgstr "tamaño de clave incorrecto; se usarán %u bits\n"
+msgstr "tamaño de clave incorrecto; se usarán %u bits\n"
 
 #, c-format
 msgid "keysize rounded up to %u bits\n"
-msgstr "tamaño de clave redondeado a %u bits\n"
+msgstr "tamaño de clave redondeado a %u bits\n"
 
 msgid ""
 "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n"
 msgstr ""
-"ATENCIÓN: ciertos programas OpenPGP no usan claves DSAcon resúmenes de este "
-"tamaño\n"
+"AVISO: ciertos programas OpenPGP no usan claves DSAcon resúmenes de este "
+"tamaño\n"
 
 msgid "Sign"
 msgstr "Firma"
@@ -3467,7 +3348,7 @@ msgid "Encrypt"
 msgstr "Cifrado"
 
 msgid "Authenticate"
-msgstr "Autentificación"
+msgstr "Autentificación"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
 #. translation.  If this is not possible use single digits.  The
@@ -3499,38 +3380,38 @@ msgstr "   (%c) Conmutar la capacidad de cifrado\n"
 
 #, c-format
 msgid "   (%c) Toggle the authenticate capability\n"
-msgstr "   (%c) Conmutar la capacidad de autenticación\n"
+msgstr "   (%c) Conmutar la capacidad de autentificación\n"
 
 #, c-format
 msgid "   (%c) Finished\n"
 msgstr "   (%c) Acabado\n"
 
 msgid "Please select what kind of key you want:\n"
-msgstr "Seleccione tipo de clave deseado:\n"
+msgstr "Por favor seleccione tipo de clave deseado:\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA and RSA (default)\n"
-msgstr "   (%d) RSA y RSA (predeterminada)\n"
+msgstr "   (%d) DSA y ElGamal (por defecto)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) DSA and Elgamal\n"
-msgstr "   (%d) DSA y ElGamal\n"
+msgstr "   (%d) DSA y ElGamal (por defecto)\n"
 
 #, c-format
 msgid "   (%d) DSA (sign only)\n"
-msgstr "   (%d) DSA (sólo firmar)\n"
+msgstr "   (%d) DSA (sólo firmar)\n"
 
 #, c-format
 msgid "   (%d) RSA (sign only)\n"
-msgstr "   (%d) RSA (sólo firmar)\n"
+msgstr "   (%d) RSA (sólo firmar)\n"
 
 #, c-format
 msgid "   (%d) Elgamal (encrypt only)\n"
-msgstr "   (%d) ElGamal (sólo cifrar)\n"
+msgstr "   (%d) ElGamal (sólo cifrar)\n"
 
 #, c-format
 msgid "   (%d) RSA (encrypt only)\n"
-msgstr "   (%d) RSA (sólo cifrar)\n"
+msgstr "   (%d) RSA (sólo cifrar)\n"
 
 #, c-format
 msgid "   (%d) DSA (set your own capabilities)\n"
@@ -3544,17 +3425,17 @@ msgstr "   (%d) RSA (permite elegir capacidades)\n"
 msgid "%s keys may be between %u and %u bits long.\n"
 msgstr "las claves %s pueden tener entre %u y %u bits de longitud.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the subkey? (%u) "
-msgstr "¿De qué tamaño quiere la subclave? (%u) "
+msgstr "¿De qué tamaño quiere la clave? (%u) "
 
 #, c-format
 msgid "What keysize do you want? (%u) "
-msgstr "¿De qué tamaño quiere la clave? (%u) "
+msgstr "¿De qué tamaño quiere la clave? (%u) "
 
 #, c-format
 msgid "Requested keysize is %u bits\n"
-msgstr "El tamaño requerido es de %u bits\n"
+msgstr "El tamaño requerido es de %u bits\n"
 
 msgid ""
 "Please specify how long the key should be valid.\n"
@@ -3564,12 +3445,12 @@ msgid ""
 "      <n>m = key expires in n months\n"
 "      <n>y = key expires in n years\n"
 msgstr ""
-"Especifique el período de validez de la clave.\n"
+"Por favor, especifique el período de validez de la clave.\n"
 "         0 = la clave nunca caduca\n"
-"      <n>  = la clave caduca en n días\n"
+"      <n>  = la clave caduca en n días\n"
 "      <n>w = la clave caduca en n semanas\n"
 "      <n>m = la clave caduca en n meses\n"
-"      <n>y = la clave caduca en n años\n"
+"      <n>y = la clave caduca en n años\n"
 
 msgid ""
 "Please specify how long the signature should be valid.\n"
@@ -3579,22 +3460,22 @@ msgid ""
 "      <n>m = signature expires in n months\n"
 "      <n>y = signature expires in n years\n"
 msgstr ""
-"Especifique el período de validez de la clave.\n"
+"Por favor, especifique el período de validez de la clave.\n"
 "         0 = la clave nunca caduca\n"
-"      <n>  = la clave caduca en n días\n"
+"      <n>  = la clave caduca en n días\n"
 "      <n>w = la clave caduca en n semanas\n"
 "      <n>m = la clave caduca en n meses\n"
-"      <n>y = la clave caduca en n años\n"
+"      <n>y = la clave caduca en n años\n"
 
 msgid "Key is valid for? (0) "
-msgstr "¿Validez de la clave (0)? "
+msgstr "¿Validez de la clave (0)? "
 
 #, c-format
 msgid "Signature is valid for? (%s) "
-msgstr "Clave válida Â¿durante? (%s) "
+msgstr "Clave válida ¿durante? (%s) "
 
 msgid "invalid value\n"
-msgstr "valor inválido\n"
+msgstr "valor inválido\n"
 
 msgid "Key does not expire at all\n"
 msgstr "La clave nunca caduca\n"
@@ -3614,11 +3495,11 @@ msgid ""
 "Your system can't display dates beyond 2038.\n"
 "However, it will be correctly handled up to 2106.\n"
 msgstr ""
-"Su sistema no puede mostrar fechas más allá del 2038.\n"
-"Sin embargo funcionará correctamente hasta el 2106.\n"
+"Su sistema no puede mostrar fechas más allá del 2038.\n"
+"Sin embargo funcionará correctamente hasta el 2106.\n"
 
 msgid "Is this correct? (y/N) "
-msgstr "¿Es correcto? (s/n) "
+msgstr "¿Es correcto? (s/n) "
 
 msgid ""
 "\n"
@@ -3643,8 +3524,8 @@ msgid ""
 msgstr ""
 "\n"
 "Necesita un identificador de usuario para identificar su clave. El programa\n"
-"construye el identificador a partir del Nombre Real, Comentario y Dirección\n"
-"de Correo Electrónico de esta forma:\n"
+"construye el identificador a partir del Nombre Real, Comentario y Dirección\n"
+"de Correo Electrónico de esta forma:\n"
 "    \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\n"
 "\n"
 
@@ -3652,29 +3533,29 @@ msgid "Real name: "
 msgstr "Nombre y apellidos: "
 
 msgid "Invalid character in name\n"
-msgstr "Caracter inválido en el nombre\n"
+msgstr "Caracter inválido en el nombre\n"
 
 msgid "Name may not start with a digit\n"
-msgstr "El nombre no puede empezar con un número\n"
+msgstr "El nombre no puede empezar con un número\n"
 
 msgid "Name must be at least 5 characters long\n"
 msgstr "El nombre debe tener al menos 5 caracteres\n"
 
 msgid "Email address: "
-msgstr "Dirección de correo electrónico: "
+msgstr "Dirección de correo electrónico: "
 
 msgid "Not a valid email address\n"
-msgstr "Dirección inválida\n"
+msgstr "Dirección inválida\n"
 
 msgid "Comment: "
 msgstr "Comentario: "
 
 msgid "Invalid character in comment\n"
-msgstr "Caracter inválido en el comentario\n"
+msgstr "Caracter inválido en el comentario\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
-msgstr "Está usando el juego de caracteres `%s'.\n"
+msgid "You are using the '%s' character set.\n"
+msgstr "Está usando el juego de caracteres `%s'.\n"
 
 #, c-format
 msgid ""
@@ -3688,11 +3569,11 @@ msgstr ""
 
 msgid "Please don't put the email address into the real name or the comment\n"
 msgstr ""
-"No ponga la dirección de correo electrónico en el nombre real o en el "
+"Por favor no ponga la dirección de correo-e en el nombre real o en el "
 "comentario\n"
 
 msgid "Such a user ID already exists on this key!\n"
-msgstr "¡Ese ID de usuario ya existe en esta clave!\n"
+msgstr ""
 
 #. TRANSLATORS: These are the allowed answers in
 #. lower and uppercase.  Below you will find the matching
@@ -3709,27 +3590,27 @@ msgid "NnCcEeOoQq"
 msgstr "NnCcDdVvSs"
 
 msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
-msgstr "¿Cambia (N)ombre, (C)omentario, (D)irección o (S)alir? "
+msgstr "¿Cambia (N)ombre, (C)omentario, (D)irección o (S)alir? "
 
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
-msgstr "¿Cambia (N)ombre, (C)omentario, (D)irección o (V)ale/(S)alir? "
+msgstr "¿Cambia (N)ombre, (C)omentario, (D)irección o (V)ale/(S)alir? "
 
 msgid "Please correct the error first\n"
-msgstr "Corrija primero el error.\n"
+msgstr "Por favor corrija primero el error.\n"
 
 msgid ""
 "You need a Passphrase to protect your secret key.\n"
 "\n"
 msgstr ""
-"Necesita una contraseña para proteger su clave secreta.\n"
+"Necesita una frase contraseña para proteger su clave secreta.\n"
 "\n"
 
+#, fuzzy
 msgid ""
 "Please enter a passphrase to protect the off-card backup of the new "
 "encryption key."
 msgstr ""
-"Introduzca la contraseña para proteger la copia de seguridadde la clave "
-"externamente a la tarjeta."
+"Introduzca la frase contraseña para proteger el objeto importado en GnuPG"
 
 #, c-format
 msgid "%s.\n"
@@ -3741,9 +3622,9 @@ msgid ""
 "using this program with the option \"--edit-key\".\n"
 "\n"
 msgstr ""
-"No ha especificado contraseña. Esto es probablemente una *mala* idea.\n"
-"Si más tarde quiere añadir una, puede hacerlo usando este programa con\n"
-"la opción \"--edit-key\".\n"
+"No ha especificado contraseña. Esto es probablemente una *mala* idea.\n"
+"Si más tarde quiere añadir una, puede hacerlo usando este programa con\n"
+"la opción \"--edit-key\".\n"
 "\n"
 
 msgid ""
@@ -3753,108 +3634,108 @@ msgid ""
 "generator a better chance to gain enough entropy.\n"
 msgstr ""
 "Es necesario generar muchos bytes aleatorios. Es una buena idea realizar\n"
-"alguna otra tarea (trabajar en otra ventana/consola, mover el ratón, usar\n"
-"la red y los discos) durante la generación de números primos. Esto da al\n"
-"generador de números aleatorios mayor oportunidad de recoger suficiente\n"
-"entropía.\n"
+"alguna otra tarea (trabajar en otra ventana/consola, mover el ratón, usar\n"
+"la red y los discos) durante la generación de números primos. Esto da al\n"
+"generador de números aleatorios mayor oportunidad de recoger suficiente\n"
+"entropía.\n"
 
 msgid "Key generation canceled.\n"
-msgstr "Creación de claves cancelada.\n"
+msgstr "Creación de claves cancelada.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
-msgstr "escribiendo clave pública en `%s'\n"
+msgid "writing public key to '%s'\n"
+msgstr "escribiendo clave pública en `%s'\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "escribiendo apuntador de la clave privada en `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "escribiendo clave privada en `%s'\n"
 
 #, c-format
 msgid "no writable public keyring found: %s\n"
-msgstr "almacén público de claves no modificable encontrado: %s\n"
+msgstr "anillo público de claves no escribible encontrado: %s\n"
 
 #, c-format
 msgid "no writable secret keyring found: %s\n"
-msgstr "almacén privado de claves no modificable encontrado: %s\n"
+msgstr "anillo privado de claves no escribible encontrado: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "error escribiendo almacén público `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
+msgstr "error escribiendo anillo público `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "error escribiendo almacén privado `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
+msgstr "error escribiendo anillo privado `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
-msgstr "claves pública y secreta creadas y firmadas.\n"
+msgstr "claves pública y secreta creadas y firmadas.\n"
 
 msgid ""
 "Note that this key cannot be used for encryption.  You may want to use\n"
 "the command \"--edit-key\" to generate a subkey for this purpose.\n"
 msgstr ""
 "Tenga en cuenta que esta clave no puede ser usada para cifrar. Puede usar\n"
-"la orden \"--edit-key\" para crear una subclave con este propósito.\n"
+"la orden \"--edit-key\" para crear una subclave con este propósito.\n"
 
 #, c-format
 msgid "Key generation failed: %s\n"
-msgstr "Creación de la clave fallida: %s\n"
+msgstr "Creación de la clave fallida: %s\n"
 
 #, c-format
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr ""
-"clave pública creada %lu segundos en el futuro (salto en el tiempo o\n"
+"clave pública creada %lu segundos en el futuro (salto en el tiempo o\n"
 "problemas con el reloj)\n"
 
 #, c-format
 msgid ""
 "key has been created %lu seconds in future (time warp or clock problem)\n"
 msgstr ""
-"clave pública creada %lu segundos en el futuro (salto en el tiempo o\n"
+"clave pública creada %lu segundos en el futuro (salto en el tiempo o\n"
 "problemas con el reloj)\n"
 
 msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
-msgstr "NOTA: crear subclaves para claves V3 no sigue el estándar OpenPGP\n"
+msgstr "NOTA: crear subclaves para claves V3 no sigue el estándar OpenPGP\n"
 
 msgid "Really create? (y/N) "
-msgstr "¿Crear de verdad? (s/N) "
+msgstr "¿Crear de verdad? (s/N) "
 
 #, c-format
 msgid "storing key onto card failed: %s\n"
 msgstr "almacenado de clave en la tarjeta fallido: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "no se puede crear fichero de respaldo `%s': %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "NOTA: copia de seguridad de la clave guardada en `%s'\n"
 
 msgid "never     "
 msgstr "nunca     "
 
 msgid "Critical signature policy: "
-msgstr "Política de firmas críticas: "
+msgstr "Política de firmas críticas: "
 
 msgid "Signature policy: "
-msgstr "Política de firmas: "
+msgstr "Política de firmas: "
 
 msgid "Critical preferred keyserver: "
-msgstr "Servidor de claves crítico preferido: "
+msgstr "Servidor de claves crítico preferido: "
 
 msgid "Critical signature notation: "
-msgstr "Notación de firmas críticas: "
+msgstr "Notación de firmas críticas: "
 
 msgid "Signature notation: "
-msgstr "Notación de firma: "
+msgstr "Notación de firma: "
 
 msgid "Keyring"
-msgstr "Almacén de claves"
+msgstr "Anillo de claves"
 
 msgid "Primary key fingerprint:"
 msgstr "Huellas dactilares de la clave primaria:"
@@ -3865,7 +3746,7 @@ msgstr "     Huella de subclave:"
 #. TRANSLATORS: this should fit into 24 bytes to that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
-msgstr " Huella clave primaria:"
+msgstr " Huella de clave primaria:"
 
 msgid "      Subkey fingerprint:"
 msgstr "      Huella de subclave:"
@@ -3873,20 +3754,15 @@ msgstr "      Huella de subclave:"
 msgid "      Key fingerprint ="
 msgstr "      Huella de clave ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "ATENCIÓN: usando algoritmo de resumen experimental %s\n"
-
 msgid "      Card serial no. ="
-msgstr "      Número de serie de la tarjeta ="
+msgstr "      Número de serie de la tarjeta ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "renombrando `%s' en `%s' fallo: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr "ATENCIÓN: existen 2 ficheros con información confidencial.\n"
+msgstr "ATENCIÓN: existen 2 ficheros con información confidencial.\n"
 
 #, c-format
 msgid "%s is the unchanged one\n"
@@ -3897,11 +3773,11 @@ msgid "%s is the new one\n"
 msgstr "%s es el nuevo\n"
 
 msgid "Please fix this possible security flaw\n"
-msgstr "Arregle este posible fallo de seguridad\n"
+msgstr "Por favor arregle este posible fallo de seguridad\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
-msgstr "memorizando almacén `%s'\n"
+msgid "caching keyring '%s'\n"
+msgstr "memorizando anillo `%s'\n"
 
 #, c-format
 msgid "%lu keys cached so far (%lu signatures)\n"
@@ -3913,10 +3789,10 @@ msgstr "%lu claves memorizadas (%lu firmas)\n"
 
 #, c-format
 msgid "%s: keyring created\n"
-msgstr "%s: almacén creado\n"
+msgstr "%s: anillo creado\n"
 
 msgid "include revoked keys in search results"
-msgstr "incluir claves revocadas en resultados de la búsqueda"
+msgstr "incluir claves revocadas en resultados de la búsqueda"
 
 msgid "include subkeys when searching by key ID"
 msgstr "incluir subclaves al buscar por ID de clave"
@@ -3930,7 +3806,7 @@ msgid "do not delete temporary files after using them"
 msgstr "no borrar ficheros temporales tras usarlos"
 
 msgid "automatically retrieve keys when verifying signatures"
-msgstr "recuperar automáticamente claves al verificar firmas"
+msgstr "recuperar automáticamente claves al verificar firmas"
 
 msgid "honor the preferred keyserver URL set on the key"
 msgstr "usar la URL de servidor de claves preferido presente en la clave"
@@ -3939,20 +3815,20 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "usar el registro PKA presente en una clave al recuperar claves"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
-"ATENCIÓN: las opciones de servidor de claves `%s' no se usan en esta "
+"AVISO: las opciones de servidor de claves `%s' no se usan en esta "
 "plataforma\n"
 
 msgid "disabled"
 msgstr "deshabilitado"
 
 msgid "Enter number(s), N)ext, or Q)uit > "
-msgstr "Introduzca número(s), O)tro, o F)in >"
+msgstr "Introduzca número(s), O)tro, o F)in >"
 
 #, c-format
 msgid "invalid keyserver protocol (us %d!=handler %d)\n"
-msgstr "protocolo del servidor de claves inválido (us %d!=handler %d)\n"
+msgstr "protocolo del servidor de claves inválido (us %d!=handler %d)\n"
 
 #, c-format
 msgid "key \"%s\" not found on keyserver\n"
@@ -3994,41 +3870,36 @@ msgid "searching for \"%s\" from %s\n"
 msgstr "buscando \"%s\" de %s\n"
 
 msgid "no keyserver action!\n"
-msgstr "¡no se solicita ninguna acción al servidor de claves!\n"
+msgstr "¡no se solicita ninguna acción al servidor de claves!\n"
 
 #, c-format
 msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
 msgstr ""
-"ATENCIÓN: el manejo de claves procede de una versión diferente de GnuPG "
-"(%s)\n"
+"AVISO: el manejo de claves procede de una versión diferente de GnuPG (%s)\n"
 
 msgid "keyserver did not send VERSION\n"
-msgstr "el servidor de claves no envió VERSION\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "error de comunicación con el servidor de claves: %s\n"
+msgstr "el servidor de claves no envió VERSION\n"
 
 msgid "no keyserver known (use option --keyserver)\n"
-msgstr "no hay servidores de claves conocidos (use opción --keyserver)\n"
+msgstr "no hay servidores de claves conocidos (use opción --keyserver)\n"
 
 msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 "no se pueden realizar llamadas a un servidor externo de claves tal y\n"
-"como está compilado el programa\n"
+"como está compilado el programa\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr "no hay un manejador para ese esquema de servidor de claves `%s'\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
-"la acción `%s' no es posible con este esquema de servidor de claves `%s'\n"
+"la acción `%s' no es posible con este esquema de servidor de claves `%s'\n"
 
 #, c-format
 msgid "%s does not support handler version %d\n"
-msgstr "%s no permite usar la versión %d del manejador\n"
+msgstr "%s no permite usar la versión %d del manejador\n"
 
 msgid "keyserver timed out\n"
 msgstr "agotado el tiempo de espera para el servidor de claves\n"
@@ -4037,12 +3908,16 @@ msgid "keyserver internal error\n"
 msgstr "error interno del servidor de claves\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "error de comunicación con el servidor de claves: %s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
-msgstr "\"%s\" no es un identificador de clave válido: omitido\n"
+msgstr "\"%s\" no es un identificador de clave válido: omitido\n"
 
 #, c-format
 msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr "ATENCIÓN: no se puede renovar la clave %s a traves de %s: %s\n"
+msgstr "AVISO: no se puede renovar la clave %s a traves de %s: %s\n"
 
 #, c-format
 msgid "refreshing 1 key from %s\n"
@@ -4054,30 +3929,30 @@ msgstr "renovando %d claves desde %s\n"
 
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
-msgstr "ATENCIÓN: imposible recuperar URI %s: %s\n"
+msgstr "AVISO: imposible recuperar URI %s: %s\n"
 
 #, c-format
 msgid "WARNING: unable to parse URI %s\n"
-msgstr "ATENCIÓN: imposible interpretar URI %s\n"
+msgstr "AVISO: imposible interpretar URI %s\n"
 
 #, c-format
 msgid "weird size for an encrypted session key (%d)\n"
-msgstr "tamaño anormal para una clave de sesión cifrada (%d)\n"
+msgstr "tamaño anormal para una clave de sesión cifrada (%d)\n"
 
 #, c-format
 msgid "%s encrypted session key\n"
-msgstr "%s clave de sesión cifrada\n"
+msgstr "%s clave de sesión cifrada\n"
 
 #, c-format
 msgid "passphrase generated with unknown digest algorithm %d\n"
-msgstr "contraseña generada con algoritmo de resumen desconocido %d\n"
+msgstr "frase contraseña generada con algoritmo de resumen desconocido %d\n"
 
 #, c-format
 msgid "public key is %s\n"
-msgstr "la clave pública es %s\n"
+msgstr "la clave pública es %s\n"
 
 msgid "public key encrypted data: good DEK\n"
-msgstr "datos cifrados con la clave pública: DEK correcta\n"
+msgstr "datos cifrados con la clave pública: DEK correcta\n"
 
 #, c-format
 msgid "encrypted with %u-bit %s key, ID %s, created %s\n"
@@ -4093,14 +3968,14 @@ msgstr "cifrado con clave %s, ID %s\n"
 
 #, c-format
 msgid "public key decryption failed: %s\n"
-msgstr "descifrado de la clave pública fallido: %s\n"
+msgstr "descifrado de la clave pública fallido: %s\n"
 
 #, c-format
 msgid "encrypted with %lu passphrases\n"
-msgstr "cifrado con %lu frases contraseña\n"
+msgstr "cifrado con %lu frases contraseña\n"
 
 msgid "encrypted with 1 passphrase\n"
-msgstr "cifrado con 1 contraseña\n"
+msgstr "cifrado con 1 frase contraseña\n"
 
 #, c-format
 msgid "assuming %s encrypted data\n"
@@ -4115,37 +3990,37 @@ msgid "decryption okay\n"
 msgstr "descifrado correcto\n"
 
 msgid "WARNING: message was not integrity protected\n"
-msgstr "ATENCIÓN: la intgridad del mensaje no está protegida\n"
+msgstr "ATENCIÓN: la intgridad del mensaje no está protegida\n"
 
 msgid "WARNING: encrypted message has been manipulated!\n"
-msgstr "ATENCIÃ\93N: Â¡el mensaje cifrado ha sido manipulado!\n"
+msgstr "ATENCIÓN: ¡el mensaje cifrado ha sido manipulado!\n"
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
-msgstr "borrada frase de paso en caché con ID: %s\n"
+msgstr ""
 
 #, c-format
 msgid "decryption failed: %s\n"
 msgstr "descifrado fallido: %s\n"
 
 msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
-msgstr "NOTA: el remitente solicitó \"sólo-para-tus-ojos\"\n"
+msgstr "NOTA: el remitente solicitó \"sólo-para-tus-ojos\"\n"
 
 #, c-format
 msgid "original file name='%.*s'\n"
 msgstr "nombre fichero original='%.*s'\n"
 
 msgid "WARNING: multiple plaintexts seen\n"
-msgstr "ATENCIÓN: se observan varios textos en claro\n"
+msgstr "AVISO: se observan varios textos en claro\n"
 
 msgid "standalone revocation - use \"gpg --import\" to apply\n"
-msgstr "revocación independiente - use \"gpg --import\" para aplicarla\n"
+msgstr "revocación independiente - use \"gpg --import\" para aplicarla\n"
 
 msgid "no signature found\n"
-msgstr "no se encontró firma\n"
+msgstr "no se encontró firma\n"
 
 msgid "signature verification suppressed\n"
-msgstr "suprimida la verificación de la firma\n"
+msgstr "suprimida la verificación de la firma\n"
 
 msgid "can't handle this ambiguous signature data\n"
 msgstr "no puedo manejar estos datos ambiguos en la firma\n"
@@ -4206,10 +4081,6 @@ msgid "unknown"
 msgstr "desconocido"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr "ATENCIÓN: ¡no es una firma separada, no se verificó el fichero «%s»!\n"
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Imposible comprobar la firma: %s\n"
 
@@ -4218,7 +4089,7 @@ msgstr "no es una firma separada\n"
 
 msgid ""
 "WARNING: multiple signatures detected.  Only the first will be checked.\n"
-msgstr "ATENCIÓN: detectadas múltiples firmas. Sólo la primera se comprueba.\n"
+msgstr "AVISO: detectadas múltiples firmas. Sólo la primera se comprueba.\n"
 
 #, c-format
 msgid "standalone signature of class 0x%02x\n"
@@ -4228,79 +4099,65 @@ msgid "old style (PGP 2.x) signature\n"
 msgstr "firma al viejo estilo (PGP 2.x)\n"
 
 msgid "invalid root packet detected in proc_tree()\n"
-msgstr "paquete raíz inválido detectado en proc_tree()\n"
+msgstr "paquete raíz inválido detectado en proc_tree()\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
-msgstr "fstat de `%s' falló en %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
+msgstr "fstat de `%s' falló en %s: %s\n"
 
 #, c-format
 msgid "fstat(%d) failed in %s: %s\n"
-msgstr "fstat(%d) falló en %s: %s\n"
+msgstr "fstat(%d) falló en %s: %s\n"
 
 #, c-format
 msgid "WARNING: using experimental public key algorithm %s\n"
-msgstr "ATENCIÓN: usando un algoritmo de clave pública experimental %s\n"
+msgstr "AVISO: usando un algoritmo de clave pública experimental %s\n"
 
 msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n"
-msgstr "ATENCIÓN: las firmas Elgamal para firmar y cifrar están obsoletas\n"
+msgstr "AVISO: las firmas Elgamal para firmar y cifrar están obsoletas\n"
 
 #, c-format
 msgid "WARNING: using experimental cipher algorithm %s\n"
-msgstr "ATENCIÓN: usando algoritmo de cifrado experimental %s\n"
+msgstr "AVISO: usando algoritmo de cifrado experimental %s\n"
 
 #, c-format
 msgid "WARNING: using experimental digest algorithm %s\n"
-msgstr "ATENCIÓN: usando algoritmo de resumen experimental %s\n"
+msgstr "AVISO: usando algoritmo de resumen experimental %s\n"
 
 #, c-format
 msgid "WARNING: digest algorithm %s is deprecated\n"
-msgstr "ATENCIÓN: el algoritmo de resumen %s está obsoleto\n"
-
-#, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Nota: se rechazarán las firmas que usen el algoritmo %s\n"
+msgstr "AVISO: el algoritmo de resumen %s está obsoleto\n"
 
 msgid "the IDEA cipher plugin is not present\n"
-msgstr "el plugin para el cifrado IDEA no está presente\n"
+msgstr "el plugin para el cifrado IDEA no está presente\n"
 
 #, c-format
 msgid "please see %s for more information\n"
-msgstr "vea %s para más información\n"
+msgstr "por favor vea %s para más información\n"
 
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
-msgstr "%s:%d: opción obsoleta \"%s\"\n"
+msgstr "%s:%d: opción obsoleta \"%s\"\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated option\n"
-msgstr "ATENCIÓN: \"%s\" es una opción obsoleta\n"
+msgstr "ATENCIÓN: \"%s\" es una opción obsoleta\n"
 
 #, c-format
 msgid "please use \"%s%s\" instead\n"
-msgstr "use \"%s%s\" en su lugar\n"
+msgstr "por favor use \"%s%s\" en su lugar\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated command - do not use it\n"
-msgstr "ATENCIÓN: \"%s\" es una orden obsoleta - no la use\n"
+msgstr "ATENCIÓN: \"%s\" es una orden obsoleta - no la use\n"
 
 #, c-format
 msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgstr "%s:%u: opción obsoleta \"%s\" - no tiene efecto\n"
+msgstr "%s:%u: opción obsoleta \"%s\" - no tiene efecto\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr "ATENCIÓN: \"%s\" es una opción obsoleta - no tiene efecto\n"
-
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: \"%s%s\" está obsoleta en este fichero - solo afecta en %s\n"
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr ""
-"ATENCIÓN: \"%s%s\" es una opción obsoleta - no tiene efecto excepto en %s\n"
+msgstr "ATENCIÓN: \"%s\" es una opción obsoleta - no tiene efecto\n"
 
 msgid "Uncompressed"
 msgstr "Sin comprimir"
@@ -4311,22 +4168,22 @@ msgstr "sin_comprimir|ninguno"
 
 #, c-format
 msgid "this message may not be usable by %s\n"
-msgstr "este mensaje podría no ser utilizable por %s\n"
+msgstr "este mensaje podría no ser utilizable por %s\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
-msgstr "opción ambigua `%s'\n"
+msgid "ambiguous option '%s'\n"
+msgstr "opción ambigua `%s'\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
-msgstr "opción desconocida `%s'\n"
+msgid "unknown option '%s'\n"
+msgstr "opción desconocida `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "El fichero `%s' ya existe. "
 
 msgid "Overwrite? (y/N) "
-msgstr "¿Sobreescribir? (s/N) "
+msgstr "¿Sobreescribir? (s/N) "
 
 #, c-format
 msgid "%s: unknown suffix\n"
@@ -4343,29 +4200,24 @@ msgid "assuming signed data in '%s'\n"
 msgstr "asumiendo que hay datos firmados en `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
-msgstr "creado un nuevo fichero de configuración `%s'\n"
+msgid "new configuration file '%s' created\n"
+msgstr "creado un nuevo fichero de configuración `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
-msgstr ""
-"ATENCIÓN: las opciones en `%s' no están aún activas en esta ejecución\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
+msgstr "AVISO: las opciones en `%s' no están aún activas en esta ejecución\n"
 
 #, c-format
 msgid "can't handle public key algorithm %d\n"
-msgstr "no puedo manejar el algoritmo de clave pública %d\n"
+msgstr "no puedo manejar el algoritmo de clave pública %d\n"
 
 msgid "WARNING: potentially insecure symmetrically encrypted session key\n"
 msgstr ""
-"ATENCIÓN: clave de sesión cifrada simétricamente potencialmente insegura\n"
+"AVISO: clave de sesión cifrada simétricamente potencialmente insegura\n"
 
 #, c-format
 msgid "subpacket of type %d has critical bit set\n"
-msgstr "el subpaquete de tipo %d tiene el bit crítico activado\n"
-
-#, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problema con el agente: %s\n"
+msgstr "el subpaquete de tipo %d tiene el bit crítico activado\n"
 
 #, c-format
 msgid " (main key ID %s)"
@@ -4379,24 +4231,28 @@ msgid ""
 "%u-bit %s key, ID %s,\n"
 "created %s%s.\n"
 msgstr ""
-"Introduzca contraseña para desbloquear la clave secreta del certificado "
-"OpenPGP:\n"
+"Introduzca frase contraseña para desbloquear la clave secreta del "
+"certificado OpenPGP:\n"
 "\"%.*s\"\n"
 "con %u bits clave %s, ID %s,\n"
 "creada el %s%s.\n"
 
 msgid "Enter passphrase\n"
-msgstr "Introduzca contraseña\n"
+msgstr "Introduzca frase contraseña\n"
 
 msgid "cancelled by user\n"
 msgstr "cancelado por el usuario\n"
 
 #, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problema con el agente: %s\n"
+
+#, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
 msgstr ""
-"Necesita una contraseña para desbloquear la clave secreta\n"
+"Necesita una frase contraseña para desbloquear la clave secreta\n"
 "del usuario: \"%s\"\n"
 
 #, c-format
@@ -4415,37 +4271,37 @@ msgid ""
 "Keeping the image close to 240x288 is a good size to use.\n"
 msgstr ""
 "\n"
-"Escoja una imagen para usar en su ID fotográfico. La imagen debe ser un\n"
-"fichero JPEG. Recuerde que la imágen se almacena en su clave pública.\n"
-"Si usa una foto muy grande, ¡su clave será también muy grande!\n"
-"Una imagen cercana a 240x288 tiene un tamaño adecuado.\n"
+"Escoja una imagen para usar en su ID fotográfico. La imagen debe ser un\n"
+"fichero JPEG. Recuerde que la imágen se almacena en su clave pública.\n"
+"Si usa una foto muy grande, ¡su clave será también muy grande!\n"
+"Una imagen cercana a 240x288 tiene un tamaño adecuado.\n"
 
 msgid "Enter JPEG filename for photo ID: "
-msgstr "Introduzca nombre del fichero JPEG para ID fotográfico: "
+msgstr "Introduzca nombre del fichero JPEG para ID fotográfico: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "Imposible abrir fichero JPEG `%s': %s\n"
 
 #, c-format
 msgid "This JPEG is really large (%d bytes) !\n"
-msgstr "¡Este JPEG es realmente grande (%d bytes)!\n"
+msgstr "¡Este JPEG es realmente grande (%d bytes)!\n"
 
 msgid "Are you sure you want to use it? (y/N) "
-msgstr "¿Seguro que quiere usarlo? (s/N) "
+msgstr "¿Seguro que quiere usarlo? (s/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "`%s' no es un fichero JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
-msgstr "¿Es correcta la foto? (s/n) "
+msgstr "¿Es correcta la foto? (s/n) "
 
 msgid "unable to display photo ID!\n"
-msgstr "¡no puedo mostrar ID fotográfico!\n"
+msgstr "¡no puedo mostrar ID fotográfico!\n"
 
 msgid "No reason specified"
-msgstr "No se dio ninguna razón"
+msgstr "No se dio ninguna razón"
 
 msgid "Key is superseded"
 msgstr "La clave ha sido reemplazada."
@@ -4454,27 +4310,17 @@ msgid "Key has been compromised"
 msgstr "La clave ha sido comprometida"
 
 msgid "Key is no longer used"
-msgstr "La clave ya no está en uso"
+msgstr "La clave ya no está en uso"
 
 msgid "User ID is no longer valid"
-msgstr "El identificador de usuario ya no es válido"
+msgstr "El identificador de usuario ya no es válido"
 
 msgid "reason for revocation: "
-msgstr "razón para la revocación: "
+msgstr "razón para la revocación: "
 
 msgid "revocation comment: "
-msgstr "comentario a la revocación: "
+msgstr "comentario a la revocación: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4488,12 +4334,12 @@ msgstr "  alias \"%s\"\n"
 msgid ""
 "How much do you trust that this key actually belongs to the named user?\n"
 msgstr ""
-"¿Qué seguridad tiene de que esta clave pertenece realmente al usuario\n"
+"¿Qué seguridad tiene de que esta clave pertenece realmente al usuario\n"
 "que se nombra?\n"
 
 #, c-format
 msgid "  %d = I don't know or won't say\n"
-msgstr " %d = No lo sé o prefiero no decirlo\n"
+msgstr " %d = No lo sé o prefiero no decirlo\n"
 
 #, c-format
 msgid "  %d = I do NOT trust\n"
@@ -4501,10 +4347,10 @@ msgstr " %d = NO tengo confianza\n"
 
 #, c-format
 msgid "  %d = I trust ultimately\n"
-msgstr " %d = confío absolutamente\n"
+msgstr " %d = confío absolutamente\n"
 
 msgid "  m = back to the main menu\n"
-msgstr "  m = volver al menú principal\n"
+msgstr "  m = volver al menú principal\n"
 
 msgid "  s = skip this key\n"
 msgstr "  s = saltar esta clave\n"
@@ -4517,14 +4363,14 @@ msgid ""
 "The minimum trust level for this key is: %s\n"
 "\n"
 msgstr ""
-"El mínimo nivel de confianza para esta clave es: %s\n"
+"El mínimo nivel de confianza para esta clave es: %s\n"
 "\n"
 
 msgid "Your decision? "
-msgstr "¿Su decisión? "
+msgstr "¿Su decisión? "
 
 msgid "Do you really want to set this key to ultimate trust? (y/N) "
-msgstr "¿De verdad quiere asignar absoluta confianza a esta clave? (s/N) "
+msgstr "¿De verdad quiere asignar absoluta confianza a esta clave? (s/N) "
 
 msgid "Certificates leading to an ultimately trusted key:\n"
 msgstr "Certificados que llevan a una clave de confianza absoluta:\n"
@@ -4553,70 +4399,70 @@ msgid ""
 "you may answer the next question with yes.\n"
 msgstr ""
 "No es seguro que la clave pertenezca a la persona que se nombra en el\n"
-"identificador de usuario. Si *realmente* sabe lo que está haciendo,\n"
-"puede contestar sí a la siguiente pregunta.\n"
+"identificador de usuario. Si *realmente* sabe lo que está haciendo,\n"
+"puede contestar sí a la siguiente pregunta.\n"
 
 msgid "Use this key anyway? (y/N) "
-msgstr "¿Usar esta clave de todas formas? (s/N) "
+msgstr "¿Usar esta clave de todas formas? (s/N) "
 
 msgid "WARNING: Using untrusted key!\n"
-msgstr "ATENCIÃ\93N: Â¡Usando una clave no fiable!\n"
+msgstr "ATENCIÓN: ¡Usando una clave no fiable!\n"
 
 msgid "WARNING: this key might be revoked (revocation key not present)\n"
-msgstr "ATENCIÓN: la clave puede estar revocada (falta clave de revocación)\n"
+msgstr "AVISO: la clave puede estar revocada (falta clave de revocación)\n"
 
 msgid "WARNING: This key has been revoked by its designated revoker!\n"
 msgstr ""
-"ATENCIÃ\93N: Â¡Esta clave ha sido revocada por la persona designada\n"
+"ATENCIÓN: ¡Esta clave ha sido revocada por la persona designada\n"
 "como revocador!\n"
 
 msgid "WARNING: This key has been revoked by its owner!\n"
-msgstr "ATENCIÃ\93N: Â¡Esta clave ha sido revocada por su propietario!\n"
+msgstr "ATENCIÓN: ¡Esta clave ha sido revocada por su propietario!\n"
 
 msgid "         This could mean that the signature is forged.\n"
-msgstr "         Esto puede significar que la firma está falsificada.\n"
+msgstr "         Esto puede significar que la firma está falsificada.\n"
 
 msgid "WARNING: This subkey has been revoked by its owner!\n"
-msgstr "ATENCIÃ\93N: Â¡Esta clave ha sido revocada por su propietario!\n"
+msgstr "ATENCIÓN: ¡Esta clave ha sido revocada por su propietario!\n"
 
 msgid "Note: This key has been disabled.\n"
-msgstr "Nota: Esta clave está deshabilitada.\n"
+msgstr "Nota: Esta clave está deshabilitada.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
-msgstr "Nota: la dirección del firmante verificado es `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
+msgstr "Nota: la dirección del firmante verificado es `%s'\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr "Nota: la dirección del firmante `%s' no coincide con la entrada DNS\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
+msgstr "Nota: la dirección del firmante `%s' no coincide con la entrada DNS\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
-msgstr "nivel de confianza puesto a TOTAL (información PKA válida)\n"
+msgstr "nivel de confianza puesto a TOTAL (información PKA válida)\n"
 
 msgid "trustlevel adjusted to NEVER due to bad PKA info\n"
-msgstr "nivel de confianza puesto a NUNCA (información PKA inválida)\n"
+msgstr "nivel de confianza puesto a NUNCA (información PKA inválida)\n"
 
 msgid "Note: This key has expired!\n"
-msgstr "Nota: Â¡Esta clave ha caducado!\n"
+msgstr "Nota: ¡Esta clave ha caducado!\n"
 
 msgid "WARNING: This key is not certified with a trusted signature!\n"
 msgstr ""
-"ATENCIÓN: ¡Esta clave no está certificada por una firma de confianza!\n"
+"ATENCIÓN: ¡Esta clave no está certificada por una firma de confianza!\n"
 
 msgid ""
 "         There is no indication that the signature belongs to the owner.\n"
 msgstr "          No hay indicios de que la firma pertenezca al propietario.\n"
 
 msgid "WARNING: We do NOT trust this key!\n"
-msgstr "ATENCIÃ\93N: Â¡Esta clave NO es de confianza!\n"
+msgstr "ATENCIÓN: ¡Esta clave NO es de confianza!\n"
 
 msgid "         The signature is probably a FORGERY.\n"
-msgstr "          La firma es probablemente una FALSIFICACIÓN.\n"
+msgstr "          La firma es probablemente una FALSIFICACIÓN.\n"
 
 msgid ""
 "WARNING: This key is not certified with sufficiently trusted signatures!\n"
 msgstr ""
-"ATENCIÓN: ¡Esta clave no está certificada con firmas de suficiente "
+"ATENCIÓN: ¡Esta clave no está certificada con firmas de suficiente "
 "confianza!\n"
 
 msgid "         It is not certain that the signature belongs to the owner.\n"
@@ -4628,7 +4474,7 @@ msgstr "%s: omitido: %s\n"
 
 #, c-format
 msgid "%s: skipped: public key already present\n"
-msgstr "%s: omitida: clave pública ya presente\n"
+msgstr "%s: omitida: clave pública ya presente\n"
 
 msgid "You did not specify a user ID. (you may use \"-r\")\n"
 msgstr "No ha especificado un ID de usuario (puede usar \"-r\")\n"
@@ -4641,19 +4487,19 @@ msgid ""
 "Enter the user ID.  End with an empty line: "
 msgstr ""
 "\n"
-"Introduzca ID de usuario. Acabe con una línea vacía: "
+"Introduzca ID de usuario. Acabe con una línea vacía: "
 
 msgid "No such user ID.\n"
 msgstr "ID de usuario inexistente.\n"
 
 msgid "skipped: public key already set as default recipient\n"
-msgstr "omitida: clave pública ya designada como destinataria predeterminada\n"
+msgstr "omitida: clave pública ya designada como destinataria por defecto\n"
 
 msgid "Public key is disabled.\n"
-msgstr "Clave pública deshabilitada.\n"
+msgstr "Clave pública deshabilitada.\n"
 
 msgid "skipped: public key already set\n"
-msgstr "omitida: clave pública ya establecida\n"
+msgstr "omitida: clave pública ya establecida\n"
 
 #, c-format
 msgid "unknown default recipient \"%s\"\n"
@@ -4661,10 +4507,10 @@ msgstr "desconocido el destinatario predefinido \"%s\"\n"
 
 #, c-format
 msgid "%s: skipped: public key is disabled\n"
-msgstr "%s: omitida: clave pública deshabilitada\n"
+msgstr "%s: omitida: clave pública deshabilitada\n"
 
 msgid "no valid addressees\n"
-msgstr "no hay direcciones válidas\n"
+msgstr "no hay direcciones válidas\n"
 
 #, c-format
 msgid "Note: key %s has no %s feature\n"
@@ -4675,7 +4521,7 @@ msgid "Note: key %s has no preference for %s\n"
 msgstr "Nota: clave %s no tiene preferencias para %s\n"
 
 msgid "data not saved; use option \"--output\" to save it\n"
-msgstr "datos no grabados; use la opción \"--output\" para grabarlos\n"
+msgstr "datos no grabados; use la opción \"--output\" para grabarlos\n"
 
 msgid "Detached signature.\n"
 msgstr "Firma separada.\n"
@@ -4690,7 +4536,7 @@ msgid "no signed data\n"
 msgstr "no hay datos firmados\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "imposible abrir datos firmados `%s'\n"
 
 #, c-format
@@ -4699,13 +4545,13 @@ msgstr "imposible abrir datos firmados fd=%d: %s\n"
 
 #, c-format
 msgid "anonymous recipient; trying secret key %s ...\n"
-msgstr "destinatario anónimo; probando clave secreta %s ...\n"
+msgstr "destinatario anónimo; probando clave secreta %s ...\n"
 
 msgid "okay, we are the anonymous recipient.\n"
-msgstr "de acuerdo, somos el destinatario anónimo.\n"
+msgstr "de acuerdo, somos el destinatario anónimo.\n"
 
 msgid "old encoding of the DEK is not supported\n"
-msgstr "la antigua codificación de la DEK no puede usarse\n"
+msgstr "la antigua codificación de la DEK no puede usarse\n"
 
 #, c-format
 msgid "cipher algorithm %d%s is unknown or disabled\n"
@@ -4717,41 +4563,41 @@ msgstr "NOTA: el cifrado %s no aparece en las preferencias del receptor\n"
 
 #, c-format
 msgid "NOTE: secret key %s expired at %s\n"
-msgstr "NOTA: clave secreta %s caducó el %s\n"
+msgstr "NOTA: clave secreta %s caducó el %s\n"
 
 msgid "NOTE: key has been revoked"
 msgstr "NOTA: la clave ha sido revocada"
 
 #, c-format
 msgid "build_packet failed: %s\n"
-msgstr "construcción del paquete fallida: %s\n"
+msgstr "construcción del paquete fallida: %s\n"
 
 #, c-format
 msgid "key %s has no user IDs\n"
 msgstr "clave %s: sin identificador de usuario\n"
 
 msgid "To be revoked by:\n"
-msgstr "Será revocado por:\n"
+msgstr "Será revocado por:\n"
 
 msgid "(This is a sensitive revocation key)\n"
-msgstr "(Este es una clave de revocación confidencial)\n"
+msgstr "(Este es una clave de revocación confidencial)\n"
 
 msgid "Create a designated revocation certificate for this key? (y/N) "
-msgstr "¿Crear un certificado de revocación para esta clave? (s/N)"
+msgstr "¿Crear un certificado de revocación para esta clave? (s/N)"
 
 msgid "ASCII armored output forced.\n"
 msgstr "se fuerza salida con armadura ASCII.\n"
 
 #, c-format
 msgid "make_keysig_packet failed: %s\n"
-msgstr "make_keysig_packet falló: %s\n"
+msgstr "make_keysig_packet falló: %s\n"
 
 msgid "Revocation certificate created.\n"
-msgstr "Certificado de revocación creado.\n"
+msgstr "Certificado de revocación creado.\n"
 
 #, c-format
 msgid "no revocation keys found for \"%s\"\n"
-msgstr "no se encuetran claves de revocación para \"%s\"\n"
+msgstr "no se encuetran claves de revocación para \"%s\"\n"
 
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
@@ -4759,19 +4605,19 @@ msgstr "clave secreta \"%s\" no encontrada: %s\n"
 
 #, c-format
 msgid "no corresponding public key: %s\n"
-msgstr "no existe la clave pública correspondiente: %s\n"
+msgstr "no existe la clave pública correspondiente: %s\n"
 
 msgid "public key does not match secret key!\n"
-msgstr "¡la clave pública y la privada no se corresponden!\n"
+msgstr "¡la clave pública y la privada no se corresponden!\n"
 
 msgid "Create a revocation certificate for this key? (y/N) "
-msgstr "¿Crear un certificado de revocación para esta clave? (s/N) "
+msgstr "¿Crear un certificado de revocación para esta clave? (s/N) "
 
 msgid "unknown protection algorithm\n"
-msgstr "algoritmo de protección desconocido\n"
+msgstr "algoritmo de protección desconocido\n"
 
 msgid "NOTE: This key is not protected!\n"
-msgstr "NOTA: ¡Esta clave no está protegida!\n"
+msgstr "NOTA: ¡Esta clave no está protegida!\n"
 
 msgid ""
 "Revocation certificate created.\n"
@@ -4782,75 +4628,76 @@ msgid ""
 "your media become unreadable.  But have some caution:  The print system of\n"
 "your machine might store the data and make it available to others!\n"
 msgstr ""
-"Certificado de revocación creado.\n"
+"Certificado de revocación creado.\n"
 "\n"
-"Consérvelo en un medio que pueda esconder; si alguien consigue\n"
+"Por favor consérvelo en un medio que pueda esconder; si alguien consigue\n"
 "acceso a este certificado puede usarlo para inutilizar su clave.\n"
 "Es inteligente imprimir este certificado y guardarlo en otro lugar, por\n"
-"si acaso su medio resulta imposible de leer. Pero precaución: Â¡el sistema\n"
-"de impresión de su máquina podría almacenar los datos y hacerlos accesibles\n"
+"si acaso su medio resulta imposible de leer. Pero precaución: ¡el sistema\n"
+"de impresión de su máquina podría almacenar los datos y hacerlos accesibles\n"
 "a otras personas!\n"
 
 msgid "Please select the reason for the revocation:\n"
-msgstr "Elija una razón para la revocación:\n"
+msgstr "Por favor elija una razón para la revocación:\n"
 
 msgid "Cancel"
 msgstr "Cancelar"
 
 #, c-format
 msgid "(Probably you want to select %d here)\n"
-msgstr "(Probablemente quería seleccionar %d aquí)\n"
+msgstr "(Probablemente quería seleccionar %d aquí)\n"
 
 msgid "Enter an optional description; end it with an empty line:\n"
-msgstr "Introduzca una descripción opcional; acábela con una línea vacía:\n"
+msgstr "Introduzca una descripción opcional; acábela con una línea vacía:\n"
 
 #, c-format
 msgid "Reason for revocation: %s\n"
-msgstr "Razón para la revocación: %s\n"
+msgstr "Razón para la revocación: %s\n"
 
 msgid "(No description given)\n"
-msgstr "(No se dió descripción)\n"
+msgstr "(No se dió descripción)\n"
 
 msgid "Is this okay? (y/N) "
-msgstr "¿Es correcto? (s/N) "
+msgstr "¿Es correcto? (s/N) "
 
 msgid "secret key parts are not available\n"
-msgstr "las partes de la clave privada no están disponibles\n"
+msgstr "las partes de la clave privada no están disponibles\n"
 
 #, c-format
 msgid "protection algorithm %d%s is not supported\n"
-msgstr "el algoritmo de protección %d%s no puede ser utilizado\n"
+msgstr "el algoritmo de protección %d%s no puede ser utilizado\n"
 
 #, c-format
 msgid "protection digest %d is not supported\n"
 msgstr "el resumen protector %d no puede ser utilizado\n"
 
 msgid "Invalid passphrase; please try again"
-msgstr "contraseña incorrecta; inténtelo de nuevo."
+msgstr "Frase contraseña incorrecta; inténtelo de nuevo."
 
 #, c-format
 msgid "%s ...\n"
 msgstr "%s ... \n"
 
 msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr "ATENCIÓN: detectada clave débil - cambie la contraseña.\n"
+msgstr ""
+"ATENCIÓN: detectada clave débil - por favor cambie la frase contraseña.\n"
 
 msgid "generating the deprecated 16-bit checksum for secret key protection\n"
 msgstr ""
-"generando la suma de comprobación de 16 bits (obsoleta) para \n"
+"generando la suma de comprobación de 16 bits (obsoleta) para \n"
 "proteger la clave secreta.\n"
 
 msgid "weak key created - retrying\n"
-msgstr "creada clave débil - reintentando\n"
+msgstr "creada clave débil - reintentando\n"
 
 #, c-format
 msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
 msgstr ""
-"¡imposible evitar clave débil para cifrado simétrico después de %d "
+"¡imposible evitar clave débil para cifrado simétrico después de %d "
 "intentos!\n"
 
 msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA necesita un resumen cuya longitud sea múltiplo de 8 bits\n"
+msgstr "DSA necesita un resumen cuya longitud sea múltiplo de 8 bits\n"
 
 #, c-format
 msgid "DSA key %s uses an unsafe (%u bit) hash\n"
@@ -4861,24 +4708,24 @@ msgid "DSA key %s requires a %u bit or larger hash\n"
 msgstr "la clave DSA %s requiere un resumen de %u bits al menos\n"
 
 msgid "WARNING: signature digest conflict in message\n"
-msgstr "ATENCIÓN: conflicto con el resumen de la firma del mensaje\n"
+msgstr "AVISO: conflicto con el resumen de la firma del mensaje\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s is not cross-certified\n"
-msgstr "ATENCIÓN: la subclave de firmado %s no tiene certificado cruzado\n"
+msgstr "AVISO: la subclave de firmado %s no tiene certificado cruzado\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr ""
-"ATENCIÓN: la subclave de cifrado %s tiene un certificado cruzado inválido\n"
+"AVISO: la subclave de cifrado %s tiene un certificado cruzado inválido\n"
 
 #, c-format
 msgid "public key %s is %lu second newer than the signature\n"
-msgstr "la clave pública %s es %lu segundos más nueva que la firma\n"
+msgstr "la clave pública %s es %lu segundos más nueva que la firma\n"
 
 #, c-format
 msgid "public key %s is %lu seconds newer than the signature\n"
-msgstr "la clave pública %s es %lu segundos más nueva que la firma\n"
+msgstr "la clave pública %s es %lu segundos más nueva que la firma\n"
 
 #, c-format
 msgid ""
@@ -4905,11 +4752,11 @@ msgstr "NOTA: la clave de firmado %s ha sido revocada\n"
 #, c-format
 msgid "assuming bad signature from key %s due to an unknown critical bit\n"
 msgstr ""
-"asumiendo firma incorrecta de la clave %s por un bit crítico desconocido\n"
+"asumiendo firma incorrecta de la clave %s por un bit crítico desconocido\n"
 
 #, c-format
 msgid "key %s: no subkey for subkey revocation signature\n"
-msgstr "clave %s: no hay subclave para la firma de revocación de subclave\n"
+msgstr "clave %s: no hay subclave para la firma de revocación de subclave\n"
 
 #, c-format
 msgid "key %s: no subkey for subkey binding signature\n"
@@ -4918,14 +4765,13 @@ msgstr "clave %s: no hay subclave para firma de subclave de enlace\n"
 #, c-format
 msgid "WARNING: unable to %%-expand notation (too large).  Using unexpanded.\n"
 msgstr ""
-"ATENCIÓN: no puedo expandir el %% de la url de política . Se usa sin "
-"expandir.\n"
+"AVISO: no puedo expandir el %% de la url de política . Se usa sin expandir.\n"
 
 #, c-format
 msgid ""
 "WARNING: unable to %%-expand policy URL (too large).  Using unexpanded.\n"
 msgstr ""
-"ATENCIÓN: no puedo expandir el %% de la url de política (demasiado larga).\n"
+"AVISO: no puedo expandir el %% de la url de política (demasiado larga).\n"
 "Se usa sin expandir.\n"
 
 #, c-format
@@ -4933,12 +4779,12 @@ msgid ""
 "WARNING: unable to %%-expand preferred keyserver URL (too large).  Using "
 "unexpanded.\n"
 msgstr ""
-"ATENCIÓN: no puedo expandir el %% de la URL del servidor de claves\n"
+"AVISO: no puedo expandir el %% de la URL del servidor de claves\n"
 "preferido. Se usa sin expandir.\n"
 
 #, c-format
 msgid "checking created signature failed: %s\n"
-msgstr "la comprobación de la firma creada falló: %s\n"
+msgstr "la comprobación de la firma creada falló: %s\n"
 
 #, c-format
 msgid "%s/%s signature from: \"%s\"\n"
@@ -4946,25 +4792,25 @@ msgstr "%s/%s firma de: \"%s\"\n"
 
 msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
 msgstr ""
-"sólo puede hacer firmas separadas con claves tipo PGP 2.x estando enmodo --"
+"sólo puede hacer firmas separadas con claves tipo PGP 2.x estando enmodo --"
 "pgp2\n"
 
 #, c-format
 msgid ""
 "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
 msgstr ""
-"ATENCIÓN: forzar el algoritmo de resumen %s (%d) va en contra de las\n"
+"AVISO: forzar el algoritmo de resumen %s (%d) va en contra de las\n"
 "preferencias del destinatario\n"
 
 msgid "signing:"
 msgstr "firmando:"
 
 msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr "sólo puede firmar en claro con claves PGP 2.x estando en modo --pgp2\n"
+msgstr "sólo puede firmar en claro con claves PGP 2.x estando en modo --pgp2\n"
 
 #, c-format
 msgid "%s encryption will be used\n"
-msgstr "se usará un cifrado %s\n"
+msgstr "se usará un cifrado %s\n"
 
 msgid "key is not flagged as insecure - can't use it with the faked RNG!\n"
 msgstr "clave no marcada como insegura - no puede usarse con el pseudo RNG\n"
@@ -4982,7 +4828,7 @@ msgstr "omitido: clave secreta ya presente\n"
 
 msgid "this is a PGP generated Elgamal key which is not secure for signatures!"
 msgstr ""
-"¡esta es una clave ElGamal generada por PGP que NO es segura para firmar!"
+"¡esta es una clave ElGamal generada por PGP que NO es segura para firmar!"
 
 #, c-format
 msgid "trust record %lu, type %d: write failed: %s\n"
@@ -4997,40 +4843,32 @@ msgstr ""
 "# (Use \"gpg --import-ownertrust\" para restablecerlos)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "error en `%s': %s\n"
 
 msgid "line too long"
-msgstr "línea demasiado larga"
+msgstr "línea demasiado larga"
 
 msgid "colon missing"
 msgstr "falta una coma"
 
 msgid "invalid fingerprint"
-msgstr "huella dactilar no válida"
+msgstr "huella dactilar no válida"
 
 msgid "ownertrust value missing"
 msgstr "falta el valor de confianza"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "error econtrando registro de confianza en `%s': %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "error de lectura `%s': %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
-msgstr "base de datos de confianza: fallo sincronización: %s\n"
-
-#, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "no se puede crear el bloqueo para `%s'\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "no se puede bloquear `%s'\n"
+msgstr "base de datos de confianza: fallo sincronización: %s\n"
 
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
@@ -5042,23 +4880,31 @@ msgstr ""
 "registro base de datos de confianza %lu: escritura fallida (n=%d): %s\n"
 
 msgid "trustdb transaction too large\n"
-msgstr "transacción en la base de datos de confianza demasiado grande\n"
+msgstr "transacción en la base de datos de confianza demasiado grande\n"
+
+#, c-format
+msgid "can't access '%s': %s\n"
+msgstr "no se puede acceder a `%s': %s\n"
 
 #, c-format
 msgid "%s: directory does not exist!\n"
-msgstr "%s: Â¡el directorio no existe!\n"
+msgstr "%s: ¡el directorio no existe!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "no se puede acceder a `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "no se puede crear el bloqueo para `%s'\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "no se puede bloquear `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
-msgstr "%s: fallo en la creación del registro de versión: %s"
+msgstr "%s: fallo en la creación del registro de versión: %s"
 
 #, c-format
 msgid "%s: invalid trustdb created\n"
-msgstr "%s: se ha creado base de datos de confianza inválida\n"
+msgstr "%s: se ha creado base de datos de confianza inválida\n"
 
 #, c-format
 msgid "%s: trustdb created\n"
@@ -5069,23 +4915,23 @@ msgstr "NOTA: no se puede escribir base de datos de confianza\n"
 
 #, c-format
 msgid "%s: invalid trustdb\n"
-msgstr "%s: base de datos de confianza inválida\n"
+msgstr "%s: base de datos de confianza inválida\n"
 
 #, c-format
 msgid "%s: failed to create hashtable: %s\n"
-msgstr "%s: fallo en la creación de la tabla hash: %s\n"
+msgstr "%s: fallo en la creación de la tabla hash: %s\n"
 
 #, c-format
 msgid "%s: error updating version record: %s\n"
-msgstr "%s: error actualizando el registro de versión: %s\n"
+msgstr "%s: error actualizando el registro de versión: %s\n"
 
 #, c-format
 msgid "%s: error reading version record: %s\n"
-msgstr "%s: error leyendo registro de versión: %s\n"
+msgstr "%s: error leyendo registro de versión: %s\n"
 
 #, c-format
 msgid "%s: error writing version record: %s\n"
-msgstr "%s: error escribiendo registro de versión: %s\n"
+msgstr "%s: error escribiendo registro de versión: %s\n"
 
 #, c-format
 msgid "trustdb: lseek failed: %s\n"
@@ -5101,11 +4947,11 @@ msgstr "%s: no es una base de datos de confianza\n"
 
 #, c-format
 msgid "%s: version record with recnum %lu\n"
-msgstr "%s: registro de versión con número de registro %lu\n"
+msgstr "%s: registro de versión con número de registro %lu\n"
 
 #, c-format
 msgid "%s: invalid file version %d\n"
-msgstr "%s: versión del fichero %d inválida\n"
+msgstr "%s: versión del fichero %d inválida\n"
 
 #, c-format
 msgid "%s: error reading free record: %s\n"
@@ -5121,22 +4967,23 @@ msgstr "%s: fallo en poner a cero un registro: %s\n"
 
 #, c-format
 msgid "%s: failed to append a record: %s\n"
-msgstr "%s: fallo al añadir un registro: %s\n"
+msgstr "%s: fallo al añadir un registro: %s\n"
 
+#, fuzzy
 msgid "Error: The trustdb is corrupted.\n"
-msgstr "Error: base de datos de confianza corrupta.\n"
+msgstr "%s: se ha creado base de datos de confianza\n"
 
 #, c-format
 msgid "can't handle text lines longer than %d characters\n"
-msgstr "no se pueden manejar líneas de texto de más de %d caracteres\n"
+msgstr "no se pueden manejar líneas de texto de más de %d caracteres\n"
 
 #, c-format
 msgid "input line longer than %d characters\n"
-msgstr "línea de longitud superior a %d caracteres\n"
+msgstr "línea de longitud superior a %d caracteres\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
-msgstr "'%s' no es un identificador largo de clave válido\n"
+msgid "'%s' is not a valid long keyID\n"
+msgstr "'%s' no es un identificador largo de clave válido\n"
 
 #, c-format
 msgid "key %s: accepted as trusted key\n"
@@ -5144,11 +4991,11 @@ msgstr "clave %s: aceptada como clave fiable\n"
 
 #, c-format
 msgid "key %s occurs more than once in the trustdb\n"
-msgstr "la clave %s aparece más de una vez en la base de datos de confianza\n"
+msgstr "la clave %s aparece más de una vez en la base de datos de confianza\n"
 
 #, c-format
 msgid "key %s: no public key for trusted key - skipped\n"
-msgstr "clave %s: clave fiable sin clave pública - omitida\n"
+msgstr "clave %s: clave fiable sin clave pública - omitida\n"
 
 #, c-format
 msgid "key %s marked as ultimately trusted\n"
@@ -5156,7 +5003,7 @@ msgstr "clave %s marcada como de confianza absoluta\n"
 
 #, c-format
 msgid "trust record %lu, req type %d: read failed: %s\n"
-msgstr "registro de confianza %lu, petición tipo %d: fallo lectura: %s\n"
+msgstr "registro de confianza %lu, petición tipo %d: fallo lectura: %s\n"
 
 #, c-format
 msgid "trust record %lu is not of requested type %d\n"
@@ -5164,10 +5011,9 @@ msgstr "registro de confianza %lu no es del tipo requerido %d\n"
 
 msgid "You may try to re-create the trustdb using the commands:\n"
 msgstr ""
-"Puede intentar recrear la base de datos de confianza usando las órdenes:\n"
 
 msgid "If that does not work, please consult the manual\n"
-msgstr "Si eso no funciona, consulte el manual\n"
+msgstr ""
 
 #, c-format
 msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
@@ -5177,14 +5023,6 @@ msgstr "imposible usar modelo de confianza (%d) - asumiendo el modelo %s\n"
 msgid "using %s trust model\n"
 msgstr "usando %s como modelo de confianza\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr "13 no apto para supersticiosos"
 
@@ -5225,30 +5063,30 @@ msgid "ultimate"
 msgstr "absoluta"
 
 msgid "no need for a trustdb check\n"
-msgstr "no es necesaria una comprobación de la base de datos de confianza\n"
+msgstr "no es necesaria una comprobación de la base de datos de confianza\n"
 
 #, c-format
 msgid "next trustdb check due at %s\n"
-msgstr "siguiente comprobación de base de datos de confianza el: %s\n"
+msgstr "siguiente comprobación de base de datos de confianza el: %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr ""
-"no es necesaria una comprobación de la base de datos de confianza\n"
+"no es necesaria una comprobación de la base de datos de confianza\n"
 "con el modelo de confianza `%s'\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr ""
 "no es necesario comprobar la base de datos de confianza\n"
 "con el modelo `%s'\n"
 
 #, c-format
 msgid "public key %s not found: %s\n"
-msgstr "clave pública %s no encontrada: %s\n"
+msgstr "clave pública %s no encontrada: %s\n"
 
 msgid "please do a --check-trustdb\n"
-msgstr "haga un --check-trustdb\n"
+msgstr "por favor haga un --check-trustdb\n"
 
 msgid "checking the trustdb\n"
 msgstr "comprobando base de datos de confianza\n"
@@ -5262,7 +5100,7 @@ msgstr "no se encuentran claves absolutamente fiables\n"
 
 #, c-format
 msgid "public key of ultimately trusted key %s not found\n"
-msgstr "clave pública de la clave absolutamente fiable %s no encontrada\n"
+msgstr "clave pública de la clave absolutamente fiable %s no encontrada\n"
 
 #, c-format
 msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
@@ -5274,13 +5112,13 @@ msgstr ""
 msgid ""
 "depth: %d  valid: %3d  signed: %3d  trust: %d-, %dq, %dn, %dm, %df, %du\n"
 msgstr ""
-"nivel: %d  validez: %3d  firmada: %3d  confianza: %d-, %dq, %dn, %dm, %df, "
-"%du\n"
+"nivel: %d  validez: %3d  firmada: %3d  confianza: %d-, %dq, %dn, %dm, %df, %"
+"du\n"
 
 #, c-format
 msgid "unable to update trustdb version record: write failed: %s\n"
 msgstr ""
-"no se puede actualizar el registro de la versión de la base de datos\n"
+"no se puede actualizar el registro de la versión de la base de datos\n"
 "de confianza: fallo de escritura: %s\n"
 
 msgid ""
@@ -5289,19 +5127,19 @@ msgid ""
 "should be the first file given on the command line.\n"
 msgstr ""
 "la firma no se pudo verificar.\n"
-"Recuerde que el fichero de firma (.sig o .asc)\n"
-"debería ser el primero que se da en la línea de órdenes.\n"
+"Por favor recuerde que el fichero de firma (.sig o .asc)\n"
+"debería ser el primero que se da en la línea de órdenes.\n"
 
 #, c-format
 msgid "input line %u too long or missing LF\n"
-msgstr "la línea %u es demasiado larga o no tiene avance de línea (LF)\n"
+msgstr "la línea %u es demasiado larga o no tiene avance de línea (LF)\n"
 
 #, c-format
 msgid "can't open fd %d: %s\n"
 msgstr "no se puede abrir fd %d: %s\n"
 
 msgid "argument not expected"
-msgstr "parámetro inesperado"
+msgstr "parámetro inesperado"
 
 msgid "read error"
 msgstr "error de lectura"
@@ -5310,45 +5148,35 @@ msgid "keyword too long"
 msgstr "palabra clave demasiado larga"
 
 msgid "missing argument"
-msgstr "falta el parámetro"
-
-#, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armadura inválida"
+msgstr "falta el parámetro"
 
 msgid "invalid command"
-msgstr "orden inválida"
+msgstr "orden inválida"
 
 msgid "invalid alias definition"
-msgstr "definición de alias inválida"
+msgstr "definición de alias inválida"
 
 msgid "out of core"
 msgstr "memoria desbordada"
 
 msgid "invalid option"
-msgstr "opción inválida"
+msgstr "opción inválida"
 
 #, c-format
 msgid "missing argument for option \"%.50s\"\n"
-msgstr "falta parámetro para la opción \"%.50s\"\n"
-
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "falta parámetro para la opción \"%.50s\"\n"
+msgstr "falta parámetro para la opción \"%.50s\"\n"
 
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "la opción \"%.50s\" no necesita parámetros\n"
+msgstr "la opción \"%.50s\" no necesita parámetros\n"
 
 #, c-format
 msgid "invalid command \"%.50s\"\n"
-msgstr "orden inválida \"%.50s\"\n"
+msgstr "orden inválida \"%.50s\"\n"
 
 #, c-format
 msgid "option \"%.50s\" is ambiguous\n"
-msgstr "la opción \"%.50s\" es ambigua\n"
+msgstr "la opción \"%.50s\" es ambigua\n"
 
 #, c-format
 msgid "command \"%.50s\" is ambiguous\n"
@@ -5359,30 +5187,34 @@ msgstr "memoria desbordada\n"
 
 #, c-format
 msgid "invalid option \"%.50s\"\n"
-msgstr "opción inválida \"%.50s\"\n"
+msgstr "opción inválida \"%.50s\"\n"
 
 #, c-format
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "ha encontrado un error... (%s:%d)\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "la conversión de `%s' en `%s' no está disponible\n"
+msgid "error loading '%s': %s\n"
+msgstr "error cargando `%s': %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr "la conversión de `%s' en `%s' no está disponible\n"
 
 #, c-format
 msgid "iconv_open failed: %s\n"
-msgstr "iconv_open falló: %s\n"
+msgstr "iconv_open falló: %s\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "la conversión de `%s' en `%s' falló: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "la conversión de `%s' en `%s' falló: %s\n"
 
 #, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "no se puede crear el fichero temporal `%s': %s\n"
 
 #, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "error escribiendo en `%s': %s\n"
 
 #, c-format
@@ -5397,10 +5229,10 @@ msgid "waiting for lock (held by %d%s) %s...\n"
 msgstr "esperando al bloqueo (que mantiene %d%s) %s...\n"
 
 msgid "(deadlock?) "
-msgstr "(¿bloqueo mutuo?)"
+msgstr "(¿bloqueo mutuo?)"
 
 #, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "bloqueo `%s' no hecho: %s\n"
 
 #, c-format
@@ -5408,67 +5240,67 @@ msgid "waiting for lock %s...\n"
 msgstr "esperando al bloqueo %s...\n"
 
 msgid "set debugging flags"
-msgstr "establece los parámetros de depuración"
+msgstr "establece los parámetros de depuración"
 
 msgid "enable full debugging"
-msgstr "habilita depuración completa"
+msgstr "habilita depuración completa"
 
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Uso: kbxutil [opciones] [ficheros] (-h para ayuda)"
 
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
 "Sintaxis: kbxutil [opciones] [ficheros]\n"
 "listar, exportar, importar datos Keybox\n"
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
-msgstr "falta el módulo RSA o no es de %d bits\n"
+msgstr "falta el módulo RSA o no es de %d bits\n"
 
 #, c-format
 msgid "RSA public exponent missing or larger than %d bits\n"
-msgstr "falta el exponente público RSA o es mayor de %d bits\n"
+msgstr "falta el exponente público RSA o es mayor de %d bits\n"
 
 #, c-format
 msgid "PIN callback returned error: %s\n"
-msgstr "la función de manejo del PIN devolvió un error: %s\n"
+msgstr "la función de manejo del PIN devolvió un error: %s\n"
 
 msgid "the NullPIN has not yet been changed\n"
 msgstr "el PIN-Nulo no ha sido cambiado\n"
 
+#, fuzzy
 msgid "|N|Please enter a new PIN for the standard keys."
-msgstr "|N|Introduzca un nuevo PIN para las claves estándar."
+msgstr "||Por favor inntroduzca su PIN en el teclado del lector"
 
+#, fuzzy
 msgid "||Please enter the PIN for the standard keys."
-msgstr "||Introduzca PIN para claves estándar."
+msgstr "|A|Introduzca PIN de Administrador en el teclado del lector"
 
+#, fuzzy
 msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|NP|Introduzca nuevo PIN Unblocking Code (PUK) para claves estándar."
+msgstr "||Por favor introduzca Código de Reinicio de la tarjeta"
 
+#, fuzzy
 msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|P|Introduzca PIN Unblocking Code (PUK) para claves estándar."
+msgstr "||Por favor introduzca Código de Reinicio de la tarjeta"
 
 msgid "|N|Please enter a new PIN for the key to create qualified signatures."
-msgstr "|N|Entre un nuevo PIN para la clave que crea firmas cualificadas."
+msgstr ""
 
 msgid "||Please enter the PIN for the key to create qualified signatures."
-msgstr "||Introduzca un PIN para la clave que crea firmas cualificadas."
+msgstr ""
 
 msgid ""
 "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Introduzca un nuevo PIN Unblocking Code (PUK) para la clave que crea "
-"firmas cualificadas."
 
 msgid ""
 "|P|Please enter the PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Introduzca el PIN Unblocking Code (PUK) para la clave que crea firmas "
-"cualificadas."
 
 #, c-format
 msgid "error getting new PIN: %s\n"
@@ -5480,50 +5312,49 @@ msgstr "fallo al almacenar la huella digital: %s\n"
 
 #, c-format
 msgid "failed to store the creation date: %s\n"
-msgstr "fallo guardando la fecha de creación: %s\n"
+msgstr "fallo guardando la fecha de creación: %s\n"
 
 #, c-format
 msgid "reading public key failed: %s\n"
-msgstr "fallo leyendo clave pública: %s\n"
+msgstr "fallo leyendo clave pública: %s\n"
 
 msgid "response does not contain the public key data\n"
-msgstr "la respuesta no incluye la clave pública\n"
+msgstr "la respuesta no incluye la clave pública\n"
 
 msgid "response does not contain the RSA modulus\n"
-msgstr "la respuesta no incluye el módulo RSA\n"
+msgstr "la respuesta no incluye el módulo RSA\n"
 
 msgid "response does not contain the RSA public exponent\n"
-msgstr "la respuesta no incluye el exponente público RSA\n"
+msgstr "la respuesta no incluye el exponente público RSA\n"
 
 #, c-format
 msgid "using default PIN as %s\n"
-msgstr "usando %s como PIN predeterminado\n"
+msgstr "usando PIN por defecto %s\n"
 
 #, c-format
 msgid "failed to use default PIN as %s: %s - disabling further default use\n"
-msgstr ""
-"fallo al usar %s como PIN predeterminado: %s - en adelante desactivado\n"
+msgstr "fallo al usar el PIN por defecto %s: %s - en adelante deshabilitado\n"
 
 #, c-format
 msgid "||Please enter the PIN%%0A[sigs done: %lu]"
-msgstr "||Introduzca PIN%%0A[firmas hechas: %lu]"
+msgstr "||Por favor introduzca PIN%%0A[firmas hechas: %lu]"
 
 msgid "||Please enter the PIN"
-msgstr "||Introduzca PIN"
+msgstr "||Por favor introduzca PIN"
 
 #, c-format
 msgid "PIN for CHV%d is too short; minimum length is %d\n"
-msgstr "El PIN para CHV%d es demasiado corto; longitud mínima %d\n"
+msgstr "El PIN para CHV%d es demasiado corto; longitud mínima %d\n"
 
 #, c-format
 msgid "verify CHV%d failed: %s\n"
-msgstr "la verificación CHV%d falló: %s\n"
+msgstr "la verificación CHV%d falló: %s\n"
 
 msgid "error retrieving CHV status from card\n"
 msgstr "error recuperando el estatus CHV de la tarjeta\n"
 
 msgid "card is permanently locked!\n"
-msgstr "¡la tarjeta está bloqueada permanentemente!\n"
+msgstr "¡la tarjeta está bloqueada permanentemente!\n"
 
 #, c-format
 msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
@@ -5533,28 +5364,28 @@ msgstr ""
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %%0A to force a linefeed.
-#, c-format
+#, fuzzy, c-format
 msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-msgstr "|A|Introduzca PIN de Administrador%%0A[intentos restantes: %d]"
+msgstr ""
+"|A|Introduzca PIN de Administrador en el teclado del lector%%0A[intentos "
+"restantes %d]"
 
+#, fuzzy
 msgid "|A|Please enter the Admin PIN"
-msgstr "|A|Introduzca PIN de Administrador"
+msgstr "||Por favor introduzca PIN"
 
 msgid "access to admin commands is not configured\n"
-msgstr "el acceso a órdenes de administrador no está configurado\n"
+msgstr "el acceso a órdenes de administrador no está configurado\n"
 
 msgid "||Please enter the Reset Code for the card"
-msgstr "||Introduzca Código de Reinicio de la tarjeta"
+msgstr "||Por favor introduzca Código de Reinicio de la tarjeta"
 
 #, c-format
 msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "Código de Reinicio demasiado corto; longitud mínima %d\n"
+msgstr "Código de Reinicio demasiado corto; longitud mínima %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
-msgstr "|CR|Nuevo Código de Reinicio"
+msgstr "|CR|Nuevo Código de Reinicio"
 
 msgid "|AN|New Admin PIN"
 msgstr "|AN|Nuevo PIN Administrador"
@@ -5562,14 +5393,8 @@ msgstr "|AN|Nuevo PIN Administrador"
 msgid "|N|New PIN"
 msgstr "|N|Nuevo PIN"
 
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "|A|Introduzca PIN de Administrador"
-
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Introduzca PIN"
-
 msgid "error reading application data\n"
-msgstr "error leyendo datos de la aplicación\n"
+msgstr "error leyendo datos de la aplicación\n"
 
 msgid "error reading fingerprint DO\n"
 msgstr "error leyendo huella digital DO\n"
@@ -5578,16 +5403,17 @@ msgid "key already exists\n"
 msgstr "la clave ya existe\n"
 
 msgid "existing key will be replaced\n"
-msgstr "la clave existente será reemplazada\n"
+msgstr "la clave existente será reemplazada\n"
 
 msgid "generating new key\n"
 msgstr "generando nueva clave\n"
 
+#, fuzzy
 msgid "writing new key\n"
-msgstr "escribiendo clave nueva\n"
+msgstr "generando nueva clave\n"
 
 msgid "creation timestamp missing\n"
-msgstr "falta fecha de creación\n"
+msgstr "falta fecha de creación\n"
 
 #, c-format
 msgid "RSA prime %s missing or not of size %d bits\n"
@@ -5598,17 +5424,17 @@ msgid "failed to store the key: %s\n"
 msgstr "fallo al almacenar la clave: %s\n"
 
 msgid "please wait while key is being generated ...\n"
-msgstr "espere mientras se genera la clave ...\n"
+msgstr "por favor, espere mientras se genera la clave ...\n"
 
 msgid "generating key failed\n"
-msgstr "la generación de la clave falló\n"
+msgstr "la generación de la clave falló\n"
 
 #, c-format
 msgid "key generation completed (%d seconds)\n"
-msgstr "generación de clave completada (%d segundos)\n"
+msgstr "generación de clave completada (%d segundos)\n"
 
 msgid "invalid structure of OpenPGP card (DO 0x93)\n"
-msgstr "estructura de la tarjeta OpenPGP inválida (DO 0x93)\n"
+msgstr "estructura de la tarjeta OpenPGP inválida (DO 0x93)\n"
 
 msgid "fingerprint on card does not match requested one\n"
 msgstr "la huella digital en la tarjeta no coincide con la solicitada\n"
@@ -5628,10 +5454,10 @@ msgstr ""
 
 #, c-format
 msgid "can't access %s - invalid OpenPGP card?\n"
-msgstr "no se puede acceder a %s - ¿tarjeta OpenPGP inválida?\n"
+msgstr "no se puede acceder a %s - ¿tarjeta OpenPGP inválida?\n"
 
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||Inntroduzca su PIN en el teclado del lector"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr "||Por favor inntroduzca su PIN en el teclado del lector"
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5661,16 +5487,14 @@ msgid "do not use the internal CCID driver"
 msgstr "no usa el driverd del CCID interno"
 
 msgid "|N|disconnect the card after N seconds of inactivity"
-msgstr "|N|desconectar la tarjeta después de N segundos de inactividad"
+msgstr "|N|desconectar la tarjeta después de N segundos de inactividad"
 
-msgid "do not use a reader's pinpad"
-msgstr "no usar el teclado del lector"
+msgid "do not use a reader's keypad"
+msgstr "no usa el teclado del lector"
 
+#, fuzzy
 msgid "deny the use of admin card commands"
-msgstr "rechazar el uso de órdenes de administración de la tarjeta"
-
-msgid "use variable length input for pinpad"
-msgstr "usar longitud variable para la entrada del teclado"
+msgstr "permitir órdenes de administrador en la tarjeta"
 
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Uso: scdaemon [opciones] [ficheros] (-h para ayuda)"
@@ -5682,8 +5506,8 @@ msgstr ""
 "Sintaxis: scdaemon [opciones] [orden [args]]\n"
 "Demonio de la tarjeta inteligente para GnuPG\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
-msgstr "use la opción `--daemon' para ejectuar el programa en segundo plano\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
+msgstr "use la opción `--daemon' para ejectuar el programa en segundo plano\n"
 
 #, c-format
 msgid "handler for fd %d started\n"
@@ -5695,29 +5519,29 @@ msgstr "manejador del descriptor %d terminado\n"
 
 #, c-format
 msgid "invalid radix64 character %02x skipped\n"
-msgstr "caracter inválido radix64 %02x omitido\n"
+msgstr "caracter inválido radix64 %02x omitido\n"
 
 #, c-format
 msgid "failed to proxy %s inquiry to client\n"
-msgstr "fallo al hacer la petición proxy %s al cliente\n"
+msgstr "fallo al hacer la petición proxy %s al cliente\n"
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "no hay dirmngr en ejecución - iniciando `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
+msgstr "no hay dirmngr en ejecución - iniciando `%s'\n"
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
 msgstr "variable de entorno DIRMNGR_INFO malformada\n"
 
 #, c-format
 msgid "dirmngr protocol version %d is not supported\n"
-msgstr "la versión del protocolo dirmngr %d no puede usarse\n"
+msgstr "la versión del protocolo dirmngr %d no puede usarse\n"
 
 msgid "can't connect to the dirmngr - trying fall back\n"
 msgstr "no puedo conectar con el dirmngr - intentando retirada\n"
 
 #, c-format
 msgid "validation model requested by certificate: %s"
-msgstr "el certificado: %s requiere un modelo de validación"
+msgstr "el certificado: %s requiere un modelo de validación"
 
 msgid "chain"
 msgstr "cadena"
@@ -5727,44 +5551,44 @@ msgstr "shell"
 
 #, c-format
 msgid "critical certificate extension %s is not supported"
-msgstr "la extensión crítica de certificado %s no puede usarse"
+msgstr "la extensión crítica de certificado %s no puede usarse"
 
 msgid "issuer certificate is not marked as a CA"
-msgstr "el certificado del emisor no está marcado como CA"
+msgstr "el certificado del emisor no está marcado como CA"
 
 msgid "critical marked policy without configured policies"
-msgstr "política marcada como crítica sin políticas configuradas"
+msgstr "política marcada como crítica sin políticas configuradas"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "fallo abriendo `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
-msgstr "nota: no se permiten políticas no críticas de certificados"
+msgstr "nota: no se permiten políticas no críticas de certificados"
 
 msgid "certificate policy not allowed"
-msgstr "no se permite política de certificado"
+msgstr "no se permite política de certificado"
 
 msgid "looking up issuer at external location\n"
-msgstr "buscando al emisor en una localización externa\n"
+msgstr "buscando al emisor en una localización externa\n"
 
 #, c-format
 msgid "number of issuers matching: %d\n"
 msgstr "numero de emisores coincidentes: %d\n"
 
 msgid "looking up issuer from the Dirmngr cache\n"
-msgstr "buscando emisor en el caché de Dirmngr\n"
+msgstr "buscando emisor en el caché de Dirmngr\n"
 
 #, c-format
 msgid "number of matching certificates: %d\n"
-msgstr "número de certificados coincidentes: %d\n"
+msgstr "número de certificados coincidentes: %d\n"
 
 #, c-format
 msgid "dirmngr cache-only key lookup failed: %s\n"
-msgstr "fallo buscando la clave sólo caché de dirmngr: %s\n"
+msgstr "fallo buscando la clave sólo caché de dirmngr: %s\n"
 
-msgid "failed to allocate keyDB handle\n"
-msgstr "fallo al reservar handle de keyDB\n"
+msgid "failed to allocated keyDB handle\n"
+msgstr "fallo al colocar handle de keyDB\n"
 
 msgid "certificate has been revoked"
 msgstr "el certificado ha sido revocado"
@@ -5773,30 +5597,30 @@ msgid "the status of the certificate is unknown"
 msgstr "el estado del certificado es desconocido"
 
 msgid "please make sure that the \"dirmngr\" is properly installed\n"
-msgstr "asegúrese de que \"dirmngr\" está bien instalado\n"
+msgstr "por favor asegúrese de que \"dirmngr\" está bien instalado\n"
 
 #, c-format
 msgid "checking the CRL failed: %s"
-msgstr "la comprobación de CRL falló: %s"
+msgstr "la comprobación de CRL falló: %s"
 
 #, c-format
 msgid "certificate with invalid validity: %s"
 msgstr "validez del certificado incorrecta: %s"
 
 msgid "certificate not yet valid"
-msgstr "el certificado aún no es válido"
+msgstr "el certificado aún no es válido"
 
 msgid "root certificate not yet valid"
-msgstr "el certificado raíz no es válido aún"
+msgstr "el certificado raíz no es válido aún"
 
 msgid "intermediate certificate not yet valid"
-msgstr "el certificado intermedio aún no es válido"
+msgstr "el certificado intermedio aún no es válido"
 
 msgid "certificate has expired"
 msgstr "certificado caducado"
 
 msgid "root certificate has expired"
-msgstr "el certificado raíz ha caducado"
+msgstr "el certificado raíz ha caducado"
 
 msgid "intermediate certificate has expired"
 msgstr "el certificado intermedio ha caducado"
@@ -5825,27 +5649,26 @@ msgid "  (certificate created at "
 msgstr "  (certificado creado en "
 
 msgid "  (certificate valid from "
-msgstr "  (certificado válido desde "
+msgstr "  (certificado válido desde "
 
 msgid "  (     issuer valid from "
-msgstr "  (     emisor válido desde "
+msgstr "  (     emisor válido desde "
 
 #, c-format
 msgid "fingerprint=%s\n"
 msgstr "huella dactilar=%s\n"
 
 msgid "root certificate has now been marked as trusted\n"
-msgstr "certificado raíz marcado ahora como fiable\n"
+msgstr "certificado raíz marcado ahora como fiable\n"
 
 msgid "interactive marking as trusted not enabled in gpg-agent\n"
-msgstr "marcar interactivamente como fiable no está activado en gpg-agent\n"
+msgstr "marcar interactivamente como fiable no está activado en gpg-agent\n"
 
 msgid "interactive marking as trusted disabled for this session\n"
-msgstr "marcar interactivamente como fíable desactivado en esta sesión\n"
+msgstr "marcar interactivamente como fíable desactivado en esta sesión\n"
 
 msgid "WARNING: creation time of signature not known - assuming current time"
-msgstr ""
-"ATENCIÓN: fecha de creación de firma desconocida - asumo momento actual"
+msgstr "AVISO: fecha de creación de firma desconocida - asumo momento actual"
 
 msgid "no issuer found in certificate"
 msgstr "no se encuentra el emisor de este certificado"
@@ -5854,11 +5677,11 @@ msgid "self-signed certificate has a BAD signature"
 msgstr "certificado auto firmado con firma INCORRECTA"
 
 msgid "root certificate is not marked trusted"
-msgstr "el certificado raíz no está marcado como fiable"
+msgstr "el certificado raíz no está marcado como fiable"
 
 #, c-format
 msgid "checking the trust list failed: %s\n"
-msgstr "la comprobación de la lista de confianza falló: %s\n"
+msgstr "la comprobación de la lista de confianza falló: %s\n"
 
 msgid "certificate chain too long\n"
 msgstr "cadena de certificados demasiado larga\n"
@@ -5874,7 +5697,7 @@ msgstr "encontrado otro posible certificado de CA coincidente - reintentando"
 
 #, c-format
 msgid "certificate chain longer than allowed by CA (%d)"
-msgstr "cadena de certificados más larga de lo que permite la CA (%d)"
+msgstr "cadena de certificados más larga de lo que permite la CA (%d)"
 
 msgid "certificate is good\n"
 msgstr "certificado correcto\n"
@@ -5883,14 +5706,14 @@ msgid "intermediate certificate is good\n"
 msgstr "certificado intermedio correcto\n"
 
 msgid "root certificate is good\n"
-msgstr "certificado raíz correcto\n"
+msgstr "certificado raíz correcto\n"
 
 msgid "switching to chain model"
 msgstr "cambiando al modelo en cadena"
 
 #, c-format
 msgid "validation model used: %s"
-msgstr "modelo de validación usado: %s"
+msgstr "modelo de validación usado: %s"
 
 #, c-format
 msgid "%s key uses an unsafe (%u bit) hash\n"
@@ -5907,7 +5730,7 @@ msgid "none"
 msgstr "ninguno"
 
 msgid "[Error - invalid encoding]"
-msgstr "[Error - codificación inválida]"
+msgstr "[Error - codificación inválida]"
 
 msgid "[Error - out of core]"
 msgstr "[Error - core]"
@@ -5916,7 +5739,7 @@ msgid "[Error - No name]"
 msgstr "[Error - Sin nombre]"
 
 msgid "[Error - invalid DN]"
-msgstr "[Error - DN inválido]"
+msgstr "[Error - DN inválido]"
 
 #, c-format
 msgid ""
@@ -5926,8 +5749,8 @@ msgid ""
 "S/N %s, ID 0x%08lX,\n"
 "created %s, expires %s.\n"
 msgstr ""
-"Introduzca la frase de paso para desbloquear la clave secretadel certificado "
-"X.509\n"
+"Por favor introduzca la frase de paso para desbloquear la clave secretadel "
+"certificado X.509\n"
 "\"%s\"\n"
 "S/N %s, ID 0x%08lX,\n"
 "created %s, expires %s.\n"
@@ -5937,19 +5760,19 @@ msgstr "no se especifica uso de la clave - asumiendo todos los usos\n"
 
 #, c-format
 msgid "error getting key usage information: %s\n"
-msgstr "error obteniendo información sobre uso de la clave: %s\n"
+msgstr "error obteniendo información sobre uso de la clave: %s\n"
 
-msgid "certificate should not have been used for certification\n"
-msgstr "el certificado no debería haberse usado para certificar\n"
+msgid "certificate should have not been used for certification\n"
+msgstr "el certificado no debería haberse usado para certificar\n"
 
-msgid "certificate should not have been used for OCSP response signing\n"
-msgstr "el certificado no debería haberse usado para firma en respuesta OCSP\n"
+msgid "certificate should have not been used for OCSP response signing\n"
+msgstr "el certificado no debería haberse usado para firma en respuesta OCSP\n"
 
-msgid "certificate should not have been used for encryption\n"
-msgstr "el certificado no debería haberse usado para cifrar\n"
+msgid "certificate should have not been used for encryption\n"
+msgstr "el certificado no debería haberse usado para cifrar\n"
 
-msgid "certificate should not have been used for signing\n"
-msgstr "el certificado no debería haberse usado para firmar\n"
+msgid "certificate should have not been used for signing\n"
+msgstr "el certificado no debería haberse usado para firmar\n"
 
 msgid "certificate is not usable for encryption\n"
 msgstr "el certificado no es utilizable para cifrar\n"
@@ -5959,46 +5782,46 @@ msgstr "el certificado no es utilizable para firmar\n"
 
 #, c-format
 msgid "line %d: invalid algorithm\n"
-msgstr "línea %d: algoritmo inválido\n"
+msgstr "línea %d: algoritmo inválido\n"
 
 #, c-format
 msgid "line %d: invalid key length %u (valid are %d to %d)\n"
-msgstr "línea %d: longitud de clave inválida %u (válidas de %d a %d)\n"
+msgstr "línea %d: longitud de clave inválida %u (válidas de %d a %d)\n"
 
 #, c-format
 msgid "line %d: no subject name given\n"
-msgstr "línea %d: falta nombre de entidad\n"
+msgstr "línea %d: falta nombre de entidad\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
-msgstr "línea %d: etiqueta con nombre de entidad inválida `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
+msgstr "línea %d: etiqueta con nombre de entidad inválida `%.*s'\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
-msgstr "línea %d: nombre de entidad inválida `%s' posición %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
+msgstr "línea %d: nombre de entidad inválida `%s' posición %d\n"
 
 #, c-format
 msgid "line %d: not a valid email address\n"
-msgstr "línea %d: no es una dirección de email válida\n"
+msgstr "línea %d: no es una dirección de email válida\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
-msgstr "línea %d: error leyendo clave `%s' de la tarjeta: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
+msgstr "línea %d: error leyendo clave `%s' de la tarjeta: %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
-msgstr "línea %d: error obteniendo clave con keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
+msgstr "línea %d: error obteniendo clave con keygrip `%s': %s\n"
 
 #, c-format
 msgid "line %d: key generation failed: %s <%s>\n"
-msgstr "línea %d: generación de clave fallida: %s <%s>\n"
+msgstr "línea %d: generación de clave fallida: %s <%s>\n"
 
 msgid ""
 "To complete this certificate request please enter the passphrase for the key "
 "you just created once more.\n"
 msgstr ""
-"Para completar este certificado introduzca la contraseñapara la clave que "
-"acaba de crear una vez más.\n"
+"Para completar este certificado introduzca por favor la frase contraseñapara "
+"la clave que acaba de crear una vez más.\n"
 
 #, c-format
 msgid "   (%d) RSA\n"
@@ -6012,25 +5835,28 @@ msgstr "   (%d) Clave existente\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Clave existente de la tarjeta\n"
 
+#, fuzzy
 msgid "Enter the keygrip: "
-msgstr "Introduzca keygrip: "
+msgstr "Introduzca la notación: "
 
 msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "No es un keygrip válido (se esperaban 40 dígitos hex)\n"
+msgstr ""
 
+#, fuzzy
 msgid "No key with this keygrip\n"
-msgstr "No hay claves con ese keygrip\n"
+msgstr "No existe una subclave con índice %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading the card: %s\n"
-msgstr "error leyendo la tarjeta: %s\n"
+msgstr "%s: error leyendo registro libre: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Serial number of the card: %s\n"
-msgstr "mero de serie de la tarjeta: %s\n"
+msgstr "error obteniendo el número de serie de la tarjeta: %s\n"
 
+#, fuzzy
 msgid "Available keys:\n"
-msgstr "Claves disponibles:\n"
+msgstr "deshabilita clave"
 
 #, c-format
 msgid "Possible actions for a %s key:\n"
@@ -6052,11 +5878,11 @@ msgid "Enter the X.509 subject name: "
 msgstr "Introduzca nombre de entidad para X.509"
 
 msgid "No subject name given\n"
-msgstr "No se dió nombre de entidad\n"
+msgstr "No se dió nombre de entidad\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
-msgstr "Etiqueta de nombre de entidad inválida `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
+msgstr "Etiqueta de nombre de entidad inválida `%.*s'\n"
 
 #. TRANSLATORS: The 22 in the second string is the
 #. length of the first string up to the "%s".  Please
@@ -6064,35 +5890,35 @@ msgstr "Etiqueta de nombre de entidad inválida `%.*s'\n"
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
-msgstr "Nombre de entidad inválido `%s'\n"
+msgid "Invalid subject name '%s'\n"
+msgstr "Nombre de entidad inválido `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
 msgstr "28 visto por el traductor hasta la comilla inclusive"
 
 msgid "Enter email addresses"
-msgstr "Dirección de correo electrónico: "
+msgstr "Dirección de correo electrónico: "
 
 msgid " (end with an empty line):\n"
-msgstr " (termine con una línea en blanco):\n"
+msgstr " (termine con una línea en blanco):\n"
 
 msgid "Enter DNS names"
 msgstr "Introduzca nombres de DNS"
 
 msgid " (optional; end with an empty line):\n"
-msgstr " (opcional; acabe con una línea en blanco):\n"
+msgstr " (opcional; acabe con una línea en blanco):\n"
 
 msgid "Enter URIs"
 msgstr "Introduzca URIs"
 
 msgid "Parameters to be used for the certificate request:\n"
-msgstr "Parámetros que se usarán para pedir certificados:\n"
+msgstr "Parámetros que se usarán para pedir certificados:\n"
 
 msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr "Creando una petición de certificado.  Puede llevar un rato ...\n"
+msgstr "Creando una petición de certificado.  Puede llevar un rato ...\n"
 
 msgid "Ready.  You should now send this request to your CA.\n"
-msgstr "Acabado. Debería mandar esta petición a su CA.\n"
+msgstr "Acabado. Debería mandar esta petición a su CA.\n"
 
 msgid "resource problem: out of core\n"
 msgstr "problema de recursos: memoria desbordada\n"
@@ -6104,7 +5930,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(no parece un mensaje cifrado)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "certificado `%s' no encontrado: %s\n"
 
 #, c-format
@@ -6112,11 +5938,11 @@ msgid "error locking keybox: %s\n"
 msgstr "error bloqueando keybox: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "certificado duplicado `%s' borrado\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "certificado `%s' borrado\n"
 
 #, c-format
@@ -6124,7 +5950,7 @@ msgid "deleting certificate \"%s\" failed: %s\n"
 msgstr "borrado del certificado \"%s\" fallido: %s\n"
 
 msgid "no valid recipients given\n"
-msgstr "no se dieron receptores válidos\n"
+msgstr "no se dieron receptores válidos\n"
 
 msgid "list external keys"
 msgstr "lista claves externas"
@@ -6147,6 +5973,9 @@ msgstr "pasar una orden a dirmngr"
 msgid "invoke gpg-protect-tool"
 msgstr "invocar gpg-protect-tool"
 
+msgid "change a passphrase"
+msgstr "cambia una frase contraseña"
+
 msgid "create base-64 encoded output"
 msgstr "crea una salida en base-64"
 
@@ -6160,7 +5989,7 @@ msgid "assume input is in binary format"
 msgstr "asumir entrada en formato binario"
 
 msgid "use system's dirmngr if available"
-msgstr "usar el dirmngr del sistema si está disponible"
+msgstr "usar el dirmngr del sistema si está disponible"
 
 msgid "never consult a CRL"
 msgstr "nunca consultar una CRL"
@@ -6169,13 +5998,13 @@ msgid "check validity using OCSP"
 msgstr "comprabar validez usando OCSP"
 
 msgid "|N|number of certificates to include"
-msgstr "|N|número de certificados que incluir"
+msgstr "|N|número de certificados que incluir"
 
 msgid "|FILE|take policy information from FILE"
-msgstr "|FICHERO|tomar política de información de FICHERO"
+msgstr "|FICHERO|tomar política de información de FICHERO"
 
 msgid "do not check certificate policies"
-msgstr "no comprobar políticas de certificados"
+msgstr "no comprobar políticas de certificados"
 
 msgid "fetch missing issuer certificates"
 msgstr "recuperar certificados de emisor perdidos"
@@ -6187,28 +6016,28 @@ msgid "|FILE|write a server mode log to FILE"
 msgstr "|FICHERO|escribir un log en modo servidor en FICHERO"
 
 msgid "|FILE|write an audit log to FILE"
-msgstr "|FICHERO|escribir inform de auditoría a FICHERO"
+msgstr "|FICHERO|escribir inform de auditoría a FICHERO"
 
 msgid "batch mode: never ask"
 msgstr "proceso por lotes: nunca preguntar"
 
 # assume -> suponer, no asumir
-# No estoy seguro. El diccionario Collins en la acepción b) de asumir
+# No estoy seguro. El diccionario Collins en la acepción b) de asumir
 # dice "b) (suponer) to assume, suppose..."
-# Además una de las acepciones de asumir es "aceptar algo" y suponer
-# viene a ser asumir una idea como propia. Suponer "sí" en casi todas las
+# Además una de las acepciones de asumir es "aceptar algo" y suponer
+# viene a ser asumir una idea como propia. Suponer "sí" en casi todas las
 # preguntas no me acaba de gustar.
 msgid "assume yes on most questions"
-msgstr "asume \"sí\" en casi todas las preguntas"
+msgstr "asume \"sí\" en casi todas las preguntas"
 
 msgid "assume no on most questions"
 msgstr "asume \"no\" en casi todas las preguntas"
 
 msgid "|FILE|add keyring to the list of keyrings"
-msgstr "|FICHERO|añade este almacén a la lista de almacenes"
+msgstr "|FICHERO|añade este anillo a la lista de anillos"
 
 msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|ID-USUARIO|utiliza ID-USUARIO como clave secreta predeterminada"
+msgstr "|ID-USUARIO|usa ID-USUARIO como clave secreta por defecto"
 
 msgid "|SPEC|use this keyserver to lookup keys"
 msgstr "|ESPEC|usa este servidor para buscar claves"
@@ -6224,23 +6053,23 @@ msgstr "Uso: gpgsm [opciones] [ficheros] (-h para ayuda)"
 
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxis: gpgsm [opciones] [ficheros]\n"
 "firma, comprueba, cifra o descifra usando protocolo S/MIME\n"
-"la operación predeterminada depende de los datos de entrada\n"
+"la operación por defecto depende de los datos de entrada\n"
 
 msgid "usage: gpgsm [options] "
 msgstr "uso: gpgsm [opciones] "
 
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
-msgstr "NOTA: no se podrá cifrar a `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
+msgstr "NOTA: no se podrá cifrar a `%s': %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
-msgstr "modelo de validación desconocido `%s'\n"
+msgid "unknown validation model '%s'\n"
+msgstr "modelo de validación desconocido `%s'\n"
 
 #, c-format
 msgid "%s:%u: no hostname given\n"
@@ -6248,28 +6077,28 @@ msgstr "%s:%u: falta el nombre del host\n"
 
 #, c-format
 msgid "%s:%u: password given without user\n"
-msgstr "%s:%u: se dio contraseña sin usuario\n"
+msgstr "%s:%u: se dio contraseña sin usuario\n"
 
 #, c-format
 msgid "%s:%u: skipping this line\n"
-msgstr "%s:%u: omitir esta línea\n"
+msgstr "%s:%u: omitir esta línea\n"
 
 msgid "could not parse keyserver\n"
 msgstr "no se puede interpretar el servidor de claves\n"
 
 msgid "WARNING: running with faked system time: "
-msgstr "ATENCIÓN: ejecutándose con hora del sistema falsificada"
+msgstr "AVISO: ejecutándose con hora del sistema falsificada"
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "importando certificados comunes `%s'\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "no puedo firmar usando `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
-msgstr "orden inválida (no hay orden implícita)\n"
+msgstr "orden inválida (no hay orden implícita)\n"
 
 #, c-format
 msgid "total number processed: %lu\n"
@@ -6279,11 +6108,14 @@ msgid "error storing certificate\n"
 msgstr "error almacenando certificado\n"
 
 msgid "basic certificate checks failed - not imported\n"
-msgstr "fallaron comprobaciones básicas sobre el certificado - no importado\n"
+msgstr "fallaron comprobaciones básicas sobre el certificado - no importado\n"
+
+msgid "failed to allocate keyDB handle\n"
+msgstr "fallo al reservar handle de keyDB\n"
 
 #, c-format
 msgid "error getting stored flags: %s\n"
-msgstr "error obteniendo parámetros almacenados: %s\n"
+msgstr "error obteniendo parámetros almacenados: %s\n"
 
 #, c-format
 msgid "error importing certificate: %s\n"
@@ -6294,11 +6126,14 @@ msgid "error reading input: %s\n"
 msgstr "error leyendo entrada: %s\n"
 
 #, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "error creando caja de claves `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr "puede que quiera ejecutar gpg-agent antes\n"
+
 #, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "caja de claves `%s' creada\n"
 
 msgid "failed to get the fingerprint\n"
@@ -6322,23 +6157,21 @@ msgstr "problema re-buscando el certificado: %s\n"
 
 #, c-format
 msgid "error storing flags: %s\n"
-msgstr "error almacenando parámetros: %s\n"
+msgstr "error almacenando parámetros: %s\n"
 
 msgid "Error - "
 msgstr "Error - "
 
 msgid "GPG_TTY has not been set - using maybe bogus default\n"
-msgstr ""
-"«GPG_TTY» no tiene valor - utilizar el valor predeterminado puede ser "
-"absurdo\n"
+msgstr "GPG_TTY no tiene valor - usando valor por defecto quizá absurdo\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "formato inválido de huella dactilar en `%s', línea %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
+msgstr "formato inválido de huella dactilar en `%s', línea %d\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "código de país inválido en `%s', línea %d\n"
+msgid "invalid country code in '%s', line %d\n"
+msgstr "código de país inválido en `%s', línea %d\n"
 
 #, c-format
 msgid ""
@@ -6349,17 +6182,17 @@ msgid ""
 "\n"
 "%s%sAre you really sure that you want to do this?"
 msgstr ""
-"Está a punto de crear una firma usando su certificado:\n"
+"Está a punto de crear una firma usando su certificado:\n"
 "\"%s\"\n"
-"Esto creará una firma válida ante la ley e igual a una firma manuscrita\n"
+"Esto creará una firma válida ante la ley e igual a una firma manuscrita\n"
 "\n"
-"%s%sEstá realmente seguro de querer hacer esto?"
+"%s%sEstá realmente seguro de querer hacer esto?"
 
 msgid ""
 "Note, that this software is not officially approved to create or verify such "
 "signatures.\n"
 msgstr ""
-"Observe que este programa no está oficialmente aprobado para crear "
+"Observe que este programa no está oficialmente aprobado para crear "
 "overificar tales firmas.\n"
 
 #, c-format
@@ -6368,9 +6201,9 @@ msgid ""
 "\"%s\"\n"
 "Note, that this certificate will NOT create a qualified signature!"
 msgstr ""
-"Está a punto de crear una firma usando su certificado:\n"
+"Está a punto de crear una firma usando su certificado:\n"
 "\"%s\"\n"
-"¡Observe que este certificado NO creará una firma cualificada!"
+"¡Observe que este certificado NO creará una firma cualificada!"
 
 #, c-format
 msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
@@ -6382,7 +6215,7 @@ msgstr "algoritmo de hash usado para el firmante %d: %s (%s)\n"
 
 #, c-format
 msgid "checking for qualified certificate failed: %s\n"
-msgstr "la comprobación de la firma cualificada falló: %s\n"
+msgstr "la comprobación de la firma cualificada falló: %s\n"
 
 msgid "Signature made "
 msgstr "Firmado el "
@@ -6396,7 +6229,7 @@ msgstr "usando el certificado ID 0x%08lX\n"
 
 msgid ""
 "invalid signature: message digest attribute does not match computed one\n"
-msgstr "firma inválida: el resumen del mensaje no coincide con el calculado\n"
+msgstr "firma inválida: el resumen del mensaje no coincide con el calculado\n"
 
 msgid "Good signature from"
 msgstr "Firma correcta de"
@@ -6414,19 +6247,19 @@ msgid "print data out hex encoded"
 msgstr "escribir datos de salida en hexadecimal"
 
 msgid "decode received data lines"
-msgstr "decodificar líneas de datos recibidos"
+msgstr "decodificar líneas de datos recibidos"
 
 msgid "|NAME|connect to Assuan socket NAME"
 msgstr "|NOMBRE|conectar al socket Assuan NOMBRE"
 
 msgid "run the Assuan server given on the command line"
-msgstr "ejecutar el servidor Assuan indicando en línea de órdenes"
+msgstr "ejecutar el servidor Assuan indicando en línea de órdenes"
 
 msgid "do not use extended connect mode"
-msgstr "no usar el modo de conexión extendido"
+msgstr "no usar el modo de conexión extendido"
 
 msgid "|FILE|run commands from FILE on startup"
-msgstr "|FICHERO|ejecuta órdenes de FICHERO al empezar"
+msgstr "|FICHERO|ejecuta órdenes de FICHERO al empezar"
 
 msgid "run /subst on startup"
 msgstr "ejecutar /subst al empezar"
@@ -6439,33 +6272,33 @@ msgid ""
 "Connect to a running agent and send commands\n"
 msgstr ""
 "Sintaxis: gpg-connect-agent [opciones]\n"
-"Conectar a un agente que se está ejecutando y mandar órdenes\n"
+"Conectar a un agente que se está ejecutando y mandar órdenes\n"
 
 #, c-format
 msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr "la opción \"%s\" necesita un programa y parámetros opcionales\n"
+msgstr "la opción \"%s\" necesita un programa y parámetros opcionales\n"
 
 #, c-format
 msgid "option \"%s\" ignored due to \"%s\"\n"
-msgstr "la opción \"%s\" se ignora por \"%s\"\n"
+msgstr "la opción \"%s\" se ignora por \"%s\"\n"
 
 #, c-format
 msgid "receiving line failed: %s\n"
-msgstr "fallo recibiendo la línea: %s\n"
+msgstr "fallo recibiendo la línea: %s\n"
 
 msgid "line too long - skipped\n"
-msgstr "línea demasiado larga -omitida\n"
+msgstr "línea demasiado larga -omitida\n"
 
 msgid "line shortened due to embedded Nul character\n"
-msgstr "línea acortada por culpa del caracter Nul incluído\n"
+msgstr "línea acortada por culpa del caracter Nul incluído\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "orden desconocida `%s'\n"
 
 #, c-format
 msgid "sending line failed: %s\n"
-msgstr "fallo mandando la línea: %s\n"
+msgstr "fallo mandando la línea: %s\n"
 
 #, c-format
 msgid "error sending %s command: %s\n"
@@ -6473,16 +6306,16 @@ msgstr "error enviando orden %s: %s\n"
 
 #, c-format
 msgid "error sending standard options: %s\n"
-msgstr "error enviando opciones estándar: %s\n"
+msgstr "error enviando opciones estándar: %s\n"
 
 msgid "Options controlling the diagnostic output"
-msgstr "Opciones que controlan la salida de diagnósticos"
+msgstr "Opciones que controlan la salida de diagnósticos"
 
 msgid "Options controlling the configuration"
-msgstr "Opciones que controlan la configuración"
+msgstr "Opciones que controlan la configuración"
 
 msgid "Options useful for debugging"
-msgstr "Opciones útiles para el depurado"
+msgstr "Opciones útiles para el depurado"
 
 msgid "|FILE|write server mode logs to FILE"
 msgstr "|FICHERO|escribir logs en modo servidor en FICHERO"
@@ -6494,49 +6327,49 @@ msgid "|N|expire SSH keys after N seconds"
 msgstr "|N|las claves SSH caducan en N segundos"
 
 msgid "|N|set maximum PIN cache lifetime to N seconds"
-msgstr "|N|establecer vida máxima del caché de PIN en N segundos"
+msgstr "|N|establecer vida máxima del caché de PIN en N segundos"
 
 msgid "|N|set maximum SSH key lifetime to N seconds"
-msgstr "|N|establecer vida máxima de la clave SSH en N segundos"
+msgstr "|N|establecer vida máxima de la clave SSH en N segundos"
 
 msgid "Options enforcing a passphrase policy"
-msgstr "Opciones que fuerzan una política de frases contraseña"
+msgstr "Opciones que fuerzan una política de frases contraseña"
 
 msgid "do not allow to bypass the passphrase policy"
-msgstr "no permitir evitar la política de frases contraseña"
+msgstr "no permitir evitar la política de frases contraseña"
 
 msgid "|N|set minimal required length for new passphrases to N"
-msgstr "|N|establecer longitud mínima para nuevas frases contraseña en N"
+msgstr "|N|establecer longitud mínima para nuevas frases contraseña en N"
 
 msgid "|N|require at least N non-alpha characters for a new passphrase"
-msgstr "|N|pedir al menos N caracteres no alfabéticos para nuevas contraseñas"
+msgstr "|N|pedir al menos N caracteres no alfabéticos para nuevas contraseñas"
 
 msgid "|FILE|check new passphrases against pattern in FILE"
-msgstr "|FICHERO|comprobar nuevas frases contraseña con el patrón en FICHERO"
+msgstr "|FICHERO|comprobar nuevas frases contraseña con el patrón en FICHERO"
 
 msgid "|N|expire the passphrase after N days"
-msgstr "|N|contraseña caduca tras N días"
+msgstr "|N|frase contraseña caduca tras N días"
 
 msgid "do not allow the reuse of old passphrases"
-msgstr "no permite reusar antiguas frases contraseña"
+msgstr "no permite reusar antiguas frases contraseña"
 
 msgid "|NAME|use NAME as default secret key"
-msgstr "|NOMBRE|usa NOMBRE como clave secreta predeterminada"
+msgstr "|NOMBRE|usa NOMBRE como clave secreta por defecto"
 
 msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|NOMBRE|cifra para el ususario NOMBRE también"
+msgstr "|NOMBRE|cifra para el ususario NOMBRE también"
 
 msgid "|SPEC|set up email aliases"
 msgstr "|ESPEC|establecer alias de email"
 
 msgid "Configuration for Keyservers"
-msgstr "Configuración para servidores de claves"
+msgstr "Configuración para servidores de claves"
 
 msgid "|URL|use keyserver at URL"
 msgstr "|URL|usar servidor de claves en URL"
 
 msgid "allow PKA lookups (DNS requests)"
-msgstr "permitir búsquedas PKA (peticiones DNS)"
+msgstr "permitir búsquedas PKA (peticiones DNS)"
 
 msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
 msgstr "|MECANISMOS|usa MECANISMOS para encontrar claves por emails"
@@ -6545,38 +6378,38 @@ msgid "disable all access to the dirmngr"
 msgstr "prohibir todo acceso al dirmngr"
 
 msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr "|NOMBRE|usa la codificación NOMBRE para frases contraseña PKCS#12"
+msgstr "|NOMBRE|usa la codificación NOMBRE para frases contraseña PKCS#12"
 
 msgid "do not check CRLs for root certificates"
-msgstr "no comprobar CRLs para certificados raíz"
+msgstr "no comprobar CRLs para certificados raíz"
 
 msgid "Options controlling the format of the output"
 msgstr "Opciones que controlan el formato de la salida"
 
 msgid "Options controlling the interactivity and enforcement"
-msgstr "Opciones que controlan la interactividad y obligación"
+msgstr "Opciones que controlan la interactividad y obligación"
 
 msgid "Configuration for HTTP servers"
-msgstr "Configuración de servidores HTTP"
+msgstr "Configuración de servidores HTTP"
 
 msgid "use system's HTTP proxy setting"
-msgstr "usar configuración del proxy HTTP del sistema"
+msgstr "usar configuración del proxy HTTP del sistema"
 
 msgid "Configuration of LDAP servers to use"
-msgstr "Configuración de servidores LDAP que se usará"
+msgstr "Configuración de servidores LDAP que se usará"
 
 msgid "LDAP server list"
 msgstr "lista de servidores LDAP"
 
 msgid "Configuration for OCSP"
-msgstr "Configuración de OCSP"
+msgstr "Configuración de OCSP"
 
 #, c-format
 msgid "External verification of component %s failed"
-msgstr "Verificación externa del componente %s fallida"
+msgstr "Verificación externa del componente %s fallida"
 
 msgid "Note that group specifications are ignored\n"
-msgstr "Note que las especificación de grupo se ignoran\n"
+msgstr "Note que las especificación de grupo se ignoran\n"
 
 msgid "list all components"
 msgstr "listar todos los componentes"
@@ -6594,22 +6427,22 @@ msgid "|COMPONENT|check options"
 msgstr "|COMPONENTE|comprobar opciones"
 
 msgid "apply global default values"
-msgstr "aplicar valores globales predeterminados"
+msgstr "aplicar valores globales por defecto"
 
 msgid "get the configuration directories for gpgconf"
-msgstr "obtener directorios de configuración para gpgconf"
+msgstr "obtener directorios de configuración para gpgconf"
 
 msgid "list global configuration file"
-msgstr "listar fichero de configuración global"
+msgstr "listar fichero de configuración global"
 
 msgid "check global configuration file"
-msgstr "comprobar fichero global de configuración"
+msgstr "comprobar fichero global de configuración"
 
 msgid "use as output file"
 msgstr "usa como fichero de salida"
 
 msgid "activate changes at runtime, if possible"
-msgstr "activar cambios en tiempo de ejecución, si es posible"
+msgstr "activar cambios en tiempo de ejecución, si es posible"
 
 msgid "Usage: gpgconf [options] (-h for help)"
 msgstr "Uso: gpgconf [opciones] (-h para ayuda)"
@@ -6619,7 +6452,7 @@ msgid ""
 "Manage configuration options for tools of the GnuPG system\n"
 msgstr ""
 "Sintaxis: gpgconf [opciones]\n"
-"Administrar opciones de configuración de las herramientas GnuPG\n"
+"Administrar opciones de configuración de las herramientas GnuPG\n"
 
 msgid "usage: gpgconf [options] "
 msgstr "uso: gpgconf [opciones] "
@@ -6631,19 +6464,19 @@ msgid "Component not found"
 msgstr "Componente no encontrado"
 
 msgid "No argument allowed"
-msgstr "No se permiten parámetros"
+msgstr "No se permiten parámetros"
 
-# Órdenes, please...
-# Sí, este no he podido ser yo :-) Por cierto, ¿por qué la O no se
-# puede acentuar? Â¿demasiado alta?
-# ¿Quién dice que no se puede? :-)
+# Órdenes, please...
+# Sí, este no he podido ser yo :-) Por cierto, ¿por qué la O no se
+# puede acentuar? ¿demasiado alta?
+# ¿Quién dice que no se puede? :-)
 msgid ""
 "@\n"
 "Commands:\n"
 " "
 msgstr ""
 "@\n"
-"Órdenes:\n"
+"Órdenes:\n"
 " "
 
 msgid "decryption modus"
@@ -6662,7 +6495,7 @@ msgid "secret key file (required)"
 msgstr "fichero de clave secreta (requerido)"
 
 msgid "input file name (default stdin)"
-msgstr "nombre del fichero de entrada (predeterminado stdin)"
+msgstr "nombre del fichero de entrada (por defecto stdin)"
 
 msgid "Usage: symcryptrun [options] (-h for help)"
 msgstr "Uso: symcryptrun [opciones] (-h para ayuda)"
@@ -6674,18 +6507,18 @@ msgid ""
 msgstr ""
 "Sintaxis: symcryptrun --class CLASE --program PROGRAMA --keyfile FICHERO "
 "[opciones...] ORDEN [fichero entrada]\n"
-"Invocar una herramienta simple de cifrado simétrico\n"
+"Invocar una herramienta simple de cifrado simétrico\n"
 
 #, c-format
 msgid "%s on %s aborted with status %i\n"
-msgstr "%s en %s abortó con estado %i\n"
+msgstr "%s en %s abortó con estado %i\n"
 
 #, c-format
 msgid "%s on %s failed with status %i\n"
-msgstr "%s en %s falló con estado %i\n"
+msgstr "%s en %s falló con estado %i\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "no se puede crear el directorio temporal `%s': %s\n"
 
 #, c-format
@@ -6705,20 +6538,20 @@ msgid "error closing %s: %s\n"
 msgstr "error cerrando %s: %s\n"
 
 msgid "no --program option provided\n"
-msgstr "falta la opción --program\n"
+msgstr "falta la opción --program\n"
 
 msgid "only --decrypt and --encrypt are supported\n"
-msgstr "sólo pueden usarse --decrypt y --encrypt\n"
+msgstr "sólo pueden usarse --decrypt y --encrypt\n"
 
 msgid "no --keyfile option provided\n"
-msgstr "falta la opción --keyfile\n"
+msgstr "falta la opción --keyfile\n"
 
 msgid "cannot allocate args vector\n"
-msgstr "no puedo reservar espacio para el vector de parámetros\n"
+msgstr "no puedo reservar espacio para el vector de parámetros\n"
 
 #, c-format
 msgid "could not create pipe: %s\n"
-msgstr "no se pudo crear la tubería: %s\n"
+msgstr "no se pudo crear la tubería: %s\n"
 
 #, c-format
 msgid "could not create pty: %s\n"
@@ -6780,23 +6613,12 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 "Sintaxis: gpg-check-pattern [opciones] fichero_de_patrones\n"
-"Compara contraseña dada en entrada estándar con un fichero de patrones\n"
-
-#~ msgid "you may want to start the gpg-agent first\n"
-#~ msgstr "puede que quiera ejecutar gpg-agent antes\n"
-
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "error cargando `%s': %s\n"
-
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "fallo al colocar handle de keyDB\n"
-
-#~ msgid "Command> "
-#~ msgstr "Orden> "
+"Compara frase contraseña dada en entrada estándar con un fichero de "
+"patrones\n"
 
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
-#~ "La base de datos de confianza está dañada. Por favor, ejecute\n"
+#~ "La base de datos de confianza está dañada. Por favor, ejecute\n"
 #~ "\"gpg --fix-trust-db\".\n"
 
 #~ msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
@@ -6806,13 +6628,13 @@ msgstr ""
 #~ msgstr "Por favor, informe de \"bugs\" a "
 
 #~ msgid "DSA keypair will have %u bits.\n"
-#~ msgstr "El par de claves DSA tendrá %u bits.\n"
+#~ msgstr "El par de claves DSA tendrá %u bits.\n"
 
 #~ msgid "this command has not yet been implemented\n"
-#~ msgstr "esta orden no está aún implementada\n"
+#~ msgstr "esta orden no está aún implementada\n"
 
 #~ msgid "Repeat passphrase\n"
-#~ msgstr "Repita frase contraseña\n"
+#~ msgstr "Repita frase contraseña\n"
 
 #~ msgid "||Please enter your PIN at the reader's keypad%%0A[sigs done: %lu]"
 #~ msgstr ""
@@ -6828,7 +6650,7 @@ msgstr ""
 #~ msgstr "Bibliotecas utilizadas:"
 
 #~ msgid "|algo [files]|print message digests"
-#~ msgstr "|algo [ficheros]|imprime resúmenes de mensaje"
+#~ msgstr "|algo [ficheros]|imprime resúmenes de mensaje"
 
 #~ msgid "generate PGP 2.x compatible messages"
 #~ msgstr "generar mensajes compatibles con PGP 2.x"
@@ -6852,19 +6674,19 @@ msgstr ""
 #~ msgstr "siempre usa un MDC para cifrar"
 
 #~ msgid "add this secret keyring to the list"
-#~ msgstr "añade este anillo secreto a la lista"
+#~ msgstr "añade este anillo secreto a la lista"
 
 #~ msgid "|NAME|set terminal charset to NAME"
 #~ msgstr "|NOMBRE|usa el juego de caracteres NOMBRE"
 
 #~ msgid "|FILE|load extension module FILE"
-#~ msgstr "|FICHERO|carga módulo de extensiones FICHERO"
+#~ msgstr "|FICHERO|carga módulo de extensiones FICHERO"
 
 #~ msgid "|N|use compress algorithm N"
-#~ msgstr "|N|usa el algoritmo de compresión N"
+#~ msgstr "|N|usa el algoritmo de compresión N"
 
 #~ msgid "remove key from the public keyring"
-#~ msgstr "elimina clave del anillo público"
+#~ msgstr "elimina clave del anillo público"
 
 #~ msgid ""
 #~ "It's up to you to assign a value here; this value will never be exported\n"
@@ -6872,11 +6694,11 @@ msgstr ""
 #~ "nothing\n"
 #~ "to do with the (implicitly created) web-of-certificates."
 #~ msgstr ""
-#~ "Está en su mano asignar un valor aquí. Dicho valor nunca será exportado "
+#~ "Está en su mano asignar un valor aquí. Dicho valor nunca será exportado "
 #~ "a\n"
 #~ "terceros. Es necesario para implementar la red de confianza, no tiene "
 #~ "nada\n"
-#~ "que ver con la red de certificados (implícitamente creada)."
+#~ "que ver con la red de certificados (implícitamente creada)."
 
 #~ msgid ""
 #~ "To build the Web-of-Trust, GnuPG needs to know which keys are\n"
@@ -6884,15 +6706,15 @@ msgstr ""
 #~ "access to the secret key.  Answer \"yes\" to set this key to\n"
 #~ "ultimately trusted\n"
 #~ msgstr ""
-#~ "Para construir la Red-de-Confianza, GnuPG necesita saber qué claves\n"
+#~ "Para construir la Red-de-Confianza, GnuPG necesita saber qué claves\n"
 #~ "tienen confianza absoluta - normalmente son las claves para las que "
 #~ "usted\n"
-#~ "puede acceder a la clave secreta. Conteste \"sí\" para hacer que esta\n"
+#~ "puede acceder a la clave secreta. Conteste \"sí\" para hacer que esta\n"
 #~ "clave se considere como de total confianza\n"
 
 #~ msgid "If you want to use this untrusted key anyway, answer \"yes\"."
 #~ msgstr ""
-#~ "Si quiere usar esta clave no fiable de todos modos, conteste \"sí\"."
+#~ "Si quiere usar esta clave no fiable de todos modos, conteste \"sí\"."
 
 #~ msgid ""
 #~ "Enter the user ID of the addressee to whom you want to send the message."
@@ -6912,10 +6734,10 @@ msgstr ""
 #~ msgstr ""
 #~ "Seleccione el algoritmo que usar.\n"
 #~ "\n"
-#~ "DSA (alias DSS) es el Algoritmo de Firma Digital y sólo se usa para "
+#~ "DSA (alias DSS) es el Algoritmo de Firma Digital y sólo se usa para "
 #~ "firmas.\n"
 #~ "\n"
-#~ "Elgamal es un algoritmo sólo para cifrar.\n"
+#~ "Elgamal es un algoritmo sólo para cifrar.\n"
 #~ "\n"
 #~ "RSA sirve tanto para firmar como para cifrar.\n"
 #~ "\n"
@@ -6928,14 +6750,14 @@ msgstr ""
 #~ "Please consult your security expert first."
 #~ msgstr ""
 #~ "En general no es una buena idea usar la misma clave para firmar y\n"
-#~ "cifrar. Este algoritmo debéria usarse solo en ciertos contextos.\n"
+#~ "cifrar. Este algoritmo debéria usarse solo en ciertos contextos.\n"
 #~ "Por favor consulte primero a un experto en seguridad."
 
 #~ msgid "Enter the size of the key"
 #~ msgstr "Introduzca la longitud de la clave"
 
 #~ msgid "Answer \"yes\" or \"no\""
-#~ msgstr "Responda \"sí\" o \"no\""
+#~ msgstr "Responda \"sí\" o \"no\""
 
 #~ msgid ""
 #~ "Enter the required value as shown in the prompt.\n"
@@ -6944,17 +6766,17 @@ msgstr ""
 #~ "the given value as an interval."
 #~ msgstr ""
 #~ "Introduzca el valor requerido conforme se muestra.\n"
-#~ "Es posible introducir una fecha ISO (AAAA-MM-DD), pero no se obtendrá "
+#~ "Es posible introducir una fecha ISO (AAAA-MM-DD), pero no se obtendrá "
 #~ "una\n"
-#~ "buena respuesta a los errores; el sistema intentará interpretar el valor\n"
+#~ "buena respuesta a los errores; el sistema intentará interpretar el valor\n"
 #~ "introducido como un intervalo."
 
 #~ msgid "Enter the name of the key holder"
-#~ msgstr "Introduzca el nombre del dueño de la clave"
+#~ msgstr "Introduzca el nombre del dueño de la clave"
 
 #~ msgid "please enter an optional but highly suggested email address"
 #~ msgstr ""
-#~ "Introduzca una dirección de correo electrónico (opcional pero muy\n"
+#~ "Introduzca una dirección de correo electrónico (opcional pero muy\n"
 #~ "recomendable)"
 
 #~ msgid "Please enter an optional comment"
@@ -6969,13 +6791,13 @@ msgstr ""
 #~ msgstr ""
 #~ "N  para cambiar el nombre.\n"
 #~ "C  para cambiar el comentario.\n"
-#~ "E  para cambiar la dirección.\n"
-#~ "O  para continuar con la generación de clave.\n"
-#~ "S  para interrumpir la generación de clave."
+#~ "E  para cambiar la dirección.\n"
+#~ "O  para continuar con la generación de clave.\n"
+#~ "S  para interrumpir la generación de clave."
 
 #~ msgid ""
 #~ "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key."
-#~ msgstr "Responda \"sí\" (o sólo \"s\") para generar la subclave."
+#~ msgstr "Responda \"sí\" (o sólo \"s\") para generar la subclave."
 
 #~ msgid ""
 #~ "When you sign a user ID on a key, you should first verify that the key\n"
@@ -7020,36 +6842,36 @@ msgstr ""
 #~ "\n"
 #~ "If you don't know what the right answer is, answer \"0\"."
 #~ msgstr ""
-#~ "Cuando firme un ID de usuario en una clave, debería verificar que la "
+#~ "Cuando firme un ID de usuario en una clave, debería verificar que la "
 #~ "clave\n"
-#~ "pertenece a la persona que se nombra en el ID de usuario. Es útil para\n"
-#~ "otros saber cómo de cuidadosamente lo ha verificado.\n"
+#~ "pertenece a la persona que se nombra en el ID de usuario. Es útil para\n"
+#~ "otros saber cómo de cuidadosamente lo ha verificado.\n"
 #~ "\n"
-#~ "\"0\" significa que no hace ninguna declaración concreta sobre como ha\n"
+#~ "\"0\" significa que no hace ninguna declaración concreta sobre como ha\n"
 #~ "      comprobado la validez de la clave.\n"
 #~ "\n"
 #~ "\"1\" significa que cree que la clave pertenece a la persona que declara\n"
-#~ "      poseerla pero no pudo o no verificó la clave en absoluto. Esto es "
-#~ "útil\n"
-#~ "      para una verificación en persona cuando firmas la clave de un "
+#~ "      poseerla pero no pudo o no verificó la clave en absoluto. Esto es "
+#~ "útil\n"
+#~ "      para una verificación en persona cuando firmas la clave de un "
 #~ "usuario\n"
-#~ "      pseudoanónimo.\n"
+#~ "      pseudoanónimo.\n"
 #~ "\n"
-#~ "\"2\" significa que hizo una comprobación informal de la clave. Por "
+#~ "\"2\" significa que hizo una comprobación informal de la clave. Por "
 #~ "ejemplo\n"
-#~ "      podría querer decir que comprobó la huella dactilar de la clave y\n"
-#~ "      comprobó el ID de usuario en la clave con un ID fotográfico.\n"
+#~ "      podría querer decir que comprobó la huella dactilar de la clave y\n"
+#~ "      comprobó el ID de usuario en la clave con un ID fotográfico.\n"
 #~ "\n"
-#~ "\"3\" significa que hizo una comprobación exhaustiva de la clave. Por\n"
+#~ "\"3\" significa que hizo una comprobación exhaustiva de la clave. Por\n"
 #~ "      ejemplo verificando la huella dactilar de la clave con el "
 #~ "propietario\n"
-#~ "      de la clave, y que comprobó, mediante un documento difícil de "
+#~ "      de la clave, y que comprobó, mediante un documento difícil de "
 #~ "falsificar\n"
-#~ "      con ID fotográfico (como un pasaporte) que el nombre del poseedor "
+#~ "      con ID fotográfico (como un pasaporte) que el nombre del poseedor "
 #~ "de la\n"
 #~ "      clave coincide con el ID de usuario en la clave y finalmente que "
-#~ "verificó\n"
-#~ "      (intercambiando email) que la dirección de email de la clave "
+#~ "verificó\n"
+#~ "      (intercambiando email) que la dirección de email de la clave "
 #~ "pertenece\n"
 #~ "      al poseedor de la clave.\n"
 #~ "\n"
@@ -7058,30 +6880,30 @@ msgstr ""
 #~ "\"\n"
 #~ "para usted cuando firma las claves de otros.\n"
 #~ "\n"
-#~ "Si no sabe qué contestar, conteste \"0\"."
+#~ "Si no sabe qué contestar, conteste \"0\"."
 
 #~ msgid "Answer \"yes\" if you want to sign ALL the user IDs"
-#~ msgstr "Responda \"sí\" si quiere firmar TODOS los IDs de usuario"
+#~ msgstr "Responda \"sí\" si quiere firmar TODOS los IDs de usuario"
 
 #~ msgid ""
 #~ "Answer \"yes\" if you really want to delete this user ID.\n"
 #~ "All certificates are then also lost!"
 #~ msgstr ""
-#~ "Responda \"sí\" si realmente quiere borrar este ID de usuario.\n"
-#~ "¡También se perderán todos los certificados!"
+#~ "Responda \"sí\" si realmente quiere borrar este ID de usuario.\n"
+#~ "¡También se perderán todos los certificados!"
 
 #~ msgid "Answer \"yes\" if it is okay to delete the subkey"
-#~ msgstr "Responda \"sí\" si quiere borrar esta subclave"
+#~ msgstr "Responda \"sí\" si quiere borrar esta subclave"
 
 #~ msgid ""
 #~ "This is a valid signature on the key; you normally don't want\n"
 #~ "to delete this signature because it may be important to establish a\n"
 #~ "trust connection to the key or another key certified by this key."
 #~ msgstr ""
-#~ "Esta es una firma válida de esta clave. Normalmente no será deseable\n"
+#~ "Esta es una firma válida de esta clave. Normalmente no será deseable\n"
 #~ "borrar esta firma ya que puede ser importante para establecer una "
-#~ "conexión\n"
-#~ "de confianza con la clave o con otra clave certificada por ésta."
+#~ "conexión\n"
+#~ "de confianza con la clave o con otra clave certificada por ésta."
 
 #~ msgid ""
 #~ "This signature can't be checked because you don't have the\n"
@@ -7090,14 +6912,14 @@ msgstr ""
 #~ "a trust connection through another already certified key."
 #~ msgstr ""
 #~ "Esta firma no puede ser comprobada porque no tiene Vd. la clave\n"
-#~ "correspondiente. Debería posponer su borrado hasta conocer qué clave\n"
-#~ "se usó, ya que dicha clave podría establecer una conexión de confianza\n"
-#~ "a través de otra clave certificada."
+#~ "correspondiente. Debería posponer su borrado hasta conocer qué clave\n"
+#~ "se usó, ya que dicha clave podría establecer una conexión de confianza\n"
+#~ "a través de otra clave certificada."
 
 #~ msgid ""
 #~ "The signature is not valid.  It does make sense to remove it from\n"
 #~ "your keyring."
-#~ msgstr "Esta firma no es válida. Tiene sentido borrarla de su anillo."
+#~ msgstr "Esta firma no es válida. Tiene sentido borrarla de su anillo."
 
 #~ msgid ""
 #~ "This is a signature which binds the user ID to the key. It is\n"
@@ -7107,31 +6929,31 @@ msgstr ""
 #~ "a second one is available."
 #~ msgstr ""
 #~ "Esta es una firma que une el ID de usuario a la clave. No suele ser una\n"
-#~ "buena idea borrar dichas firmas. De hecho, GnuPG podría no ser capaz de\n"
-#~ "volver a usar esta clave. Así que bórrela tan sólo si esta autofirma no\n"
-#~ "es válida por alguna razón y hay otra disponible."
+#~ "buena idea borrar dichas firmas. De hecho, GnuPG podría no ser capaz de\n"
+#~ "volver a usar esta clave. Así que bórrela tan sólo si esta autofirma no\n"
+#~ "es válida por alguna razón y hay otra disponible."
 
 #~ msgid ""
 #~ "Change the preferences of all user IDs (or just of the selected ones)\n"
 #~ "to the current list of preferences.  The timestamp of all affected\n"
 #~ "self-signatures will be advanced by one second.\n"
 #~ msgstr ""
-#~ "Cambiar las preferencias de todos los IDs de usuario (o sólo los \n"
+#~ "Cambiar las preferencias de todos los IDs de usuario (o sólo los \n"
 #~ "seleccionados) a la lista actual de preferencias. El sello de tiempo\n"
-#~ "de todas las autofirmas afectadas se avanzará en un segundo.\n"
+#~ "de todas las autofirmas afectadas se avanzará en un segundo.\n"
 
 #~ msgid "Please enter the passhrase; this is a secret sentence \n"
-#~ msgstr "Por favor introduzca la contraseña: una frase secreta \n"
+#~ msgstr "Por favor introduzca la contraseña: una frase secreta \n"
 
 #~ msgid ""
 #~ "Please repeat the last passphrase, so you are sure what you typed in."
-#~ msgstr "Repita la última frase contraseña para asegurarse de lo que tecleó."
+#~ msgstr "Repita la última frase contraseña para asegurarse de lo que tecleó."
 
 #~ msgid "Give the name of the file to which the signature applies"
 #~ msgstr "Introduzca el nombre del fichero al que corresponde la firma"
 
 #~ msgid "Answer \"yes\" if it is okay to overwrite the file"
-#~ msgstr "Responda \"sí\" para sobreescribir el fichero"
+#~ msgstr "Responda \"sí\" para sobreescribir el fichero"
 
 # Sugerencia: ENTER -> INTRO.
 # Aceptada.
@@ -7139,9 +6961,9 @@ msgstr ""
 #~ "Please enter a new filename. If you just hit RETURN the default\n"
 #~ "file (which is shown in brackets) will be used."
 #~ msgstr ""
-#~ "Introduzca un nuevo nombre de fichero. Si pulsa INTRO se usará el "
+#~ "Introduzca un nuevo nombre de fichero. Si pulsa INTRO se usará el "
 #~ "fichero\n"
-#~ "por omisión (mostrado entre corchetes)."
+#~ "por omisión (mostrado entre corchetes)."
 
 #~ msgid ""
 #~ "You should specify a reason for the certification.  Depending on the\n"
@@ -7157,42 +6979,42 @@ msgstr ""
 #~ "      Use this to state that the user ID should not longer be used;\n"
 #~ "      this is normally used to mark an email address invalid.\n"
 #~ msgstr ""
-#~ "Debería especificar un motivo para la certificación. Dependiendo del\n"
-#~ "contexto puede elegir una opción de esta lista:\n"
+#~ "Debería especificar un motivo para la certificación. Dependiendo del\n"
+#~ "contexto puede elegir una opción de esta lista:\n"
 #~ "  \"La clave ha sido comprometida\"\n"
 #~ "      Use esto si tiene razones para pensar que personas no autorizadas\n"
 #~ "      tuvieron acceso a su clave secreta.\n"
 #~ "  \"La clave ha sido sustituida\"\n"
-#~ "      Use esto si ha reemplazado la clave por otra más nueva.\n"
-#~ "  \"La clave ya no está en uso\"\n"
+#~ "      Use esto si ha reemplazado la clave por otra más nueva.\n"
+#~ "  \"La clave ya no está en uso\"\n"
 #~ "      Use esto si ha dejado de usar esta clave.\n"
-#~ "  \"La identificación de usuario ya no es válida\"\n"
-#~ "      Use esto para señalar que la identificación de usuario no debería\n"
+#~ "  \"La identificación de usuario ya no es válida\"\n"
+#~ "      Use esto para señalar que la identificación de usuario no debería\n"
 #~ "      seguir siendo usada; esto se utiliza normalmente para marcar una\n"
-#~ "      dirección de correo-e como inválida.\n"
+#~ "      dirección de correo-e como inválida.\n"
 
 #~ msgid ""
 #~ "If you like, you can enter a text describing why you issue this\n"
 #~ "revocation certificate.  Please keep this text concise.\n"
 #~ "An empty line ends the text.\n"
 #~ msgstr ""
-#~ "Si lo desea puede introducir un texto explicando por qué emite\n"
-#~ "este certificado de revocación. Por favor, que el texto sea breve.\n"
-#~ "Una línea vacía pone fin al texto.\n"
+#~ "Si lo desea puede introducir un texto explicando por qué emite\n"
+#~ "este certificado de revocación. Por favor, que el texto sea breve.\n"
+#~ "Una línea vacía pone fin al texto.\n"
 
 #~ msgid "can't put notation data into v3 (PGP 2.x style) signatures\n"
-#~ msgstr "no uede poner datos de notación en claves v3 (estilo PGP 2.x)\n"
+#~ msgstr "no uede poner datos de notación en claves v3 (estilo PGP 2.x)\n"
 
 #~ msgid "can't put notation data into v3 (PGP 2.x style) key signatures\n"
 #~ msgstr ""
 #~ "no se puede elegir una clave tipo PGP 2.x como revocador designado\n"
 
 #~ msgid "can't put a policy URL into v3 (PGP 2.x style) signatures\n"
-#~ msgstr "no puede poner URL de política en firmas v3 (estilo PGP 2.x)\n"
+#~ msgstr "no puede poner URL de política en firmas v3 (estilo PGP 2.x)\n"
 
 #~ msgid "can't put a policy URL into v3 key (PGP 2.x style) signatures\n"
 #~ msgstr ""
-#~ "no puede poner URL de política en firmas de claves v3 (estilo PGP 2.x)\n"
+#~ "no puede poner URL de política en firmas de claves v3 (estilo PGP 2.x)\n"
 
 #, fuzzy
 #~ msgid "shelll"
@@ -7201,18 +7023,18 @@ msgstr ""
 #, fuzzy
 #~ msgid ""
 #~ "please see http://www.gnupg.org/download/iconv.html for more information\n"
-#~ msgstr "por favor, vea http://www.gnupg.org/faq.html para más información\n"
+#~ msgstr "por favor, vea http://www.gnupg.org/faq.html para más información\n"
 
 #, fuzzy
 #~ msgid "key generation is not available from the commandline\n"
-#~ msgstr "el agente gpg no esta disponible en esta sesión\n"
+#~ msgstr "el agente gpg no esta disponible en esta sesión\n"
 
 #, fuzzy
 #~ msgid "please use the script \"%s\" to generate a new key\n"
 #~ msgstr "Por favor seleccione tipo de clave que generar:\n"
 
 #~ msgid "cipher extension `%s' not loaded due to unsafe permissions\n"
-#~ msgstr "no se carga el cifrado de ampliación `%s' por permisos inseguros\n"
+#~ msgstr "no se carga el cifrado de ampliación `%s' por permisos inseguros\n"
 
 #~ msgid "DSA requires the use of a 160 bit hash algorithm\n"
 #~ msgstr "DSA necesita un algoritmo de hash de 160 bits.\n"
@@ -7225,13 +7047,13 @@ msgstr ""
 #~ msgstr "problema con el agente - inhabilitando el uso del agente\n"
 
 #~ msgid "can't query passphrase in batch mode\n"
-#~ msgstr "imposible pedir frase contraseña en modo de proceso por lotes\n"
+#~ msgstr "imposible pedir frase contraseña en modo de proceso por lotes\n"
 
 #~ msgid "Enter passphrase: "
-#~ msgstr "Introduzca frase contraseña: "
+#~ msgstr "Introduzca frase contraseña: "
 
 #~ msgid "Repeat passphrase: "
-#~ msgstr "Repita frase contraseña: "
+#~ msgstr "Repita frase contraseña: "
 
 #~ msgid "-k[v][v][v][c] [user-id] [keyring]"
 #~ msgstr "-k[v][v][v][c] [id-usuario] [anillo]"
@@ -7243,29 +7065,29 @@ msgstr ""
 #~ msgstr "no se puede generar un primo con menos de %d bits\n"
 
 #~ msgid "no entropy gathering module detected\n"
-#~ msgstr "no se ha detectado módulo acumulador de entropía\n"
+#~ msgstr "no se ha detectado módulo acumulador de entropía\n"
 
 #, fuzzy
 #~ msgid "can't lock `%s': %s\n"
 #~ msgstr "no se puede bloquear `%s'\n"
 
 #~ msgid "can't stat `%s': %s\n"
-#~ msgstr "no se puede obtener información de `%s': %s\n"
+#~ msgstr "no se puede obtener información de `%s': %s\n"
 
 # ignore no es ignorar, es no tener en cuenta, ignorar es not to know.
 # Sugerencia: descartar.
-# Sugerencia a la sugerencia: ¿qué tal omitido? (pasar en silencio una
+# Sugerencia a la sugerencia: ¿qué tal omitido? (pasar en silencio una
 # cosa; excluirla de lo que se habla o escribe) dice el diccionario.
-# Bien. También se puede poner "descartado".
+# Bien. También se puede poner "descartado".
 #~ msgid "`%s' is not a regular file - ignored\n"
 #~ msgstr "`%s` no es un fichero regular - descartado\n"
 
 #~ msgid "note: random_seed file is empty\n"
-#~ msgstr "nota: el fichero de semillas aleatorias está vacío\n"
+#~ msgstr "nota: el fichero de semillas aleatorias está vacío\n"
 
 #~ msgid "WARNING: invalid size of random_seed file - not used\n"
 #~ msgstr ""
-#~ "ATENCIÓN: tamaño incorrecto del fichero de semillas aleatorias - no se "
+#~ "ATENCIÓN: tamaño incorrecto del fichero de semillas aleatorias - no se "
 #~ "usa\n"
 
 #~ msgid "can't read `%s': %s\n"
@@ -7281,7 +7103,7 @@ msgstr ""
 #~ msgstr "no se puede cerrar `%s': %s\n"
 
 #~ msgid "WARNING: using insecure random number generator!!\n"
-#~ msgstr "ATENCIÓN: ¡usando un generador de números aleatorios inseguro!\n"
+#~ msgstr "ATENCIÓN: ¡usando un generador de números aleatorios inseguro!\n"
 
 #~ msgid ""
 #~ "The random number generator is only a kludge to let\n"
@@ -7290,10 +7112,10 @@ msgstr ""
 #~ "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n"
 #~ "\n"
 #~ msgstr ""
-#~ "El generador de números aleatorios es sólo un apaño\n"
-#~ "para poder compilar. Â¡No es en absoluto un generador seguro!\n"
+#~ "El generador de números aleatorios es sólo un apaño\n"
+#~ "para poder compilar. ¡No es en absoluto un generador seguro!\n"
 #~ "\n"
-#~ "¡NO USE DATOS GENERADOS POR ESTE PROGRAMA!\n"
+#~ "¡NO USE DATOS GENERADOS POR ESTE PROGRAMA!\n"
 #~ "\n"
 
 #~ msgid ""
@@ -7301,9 +7123,9 @@ msgstr ""
 #~ "keep you from getting bored, because it will improve the quality\n"
 #~ "of the entropy.\n"
 #~ msgstr ""
-#~ "Por favor espere, se está reuniendo entropía. Haga alguna otra cosa con\n"
+#~ "Por favor espere, se está reuniendo entropía. Haga alguna otra cosa con\n"
 #~ "el ordenador mientras tanto si eso hace que no se aburra, porque eso\n"
-#~ "mejorará la calidad de la entropía.\n"
+#~ "mejorará la calidad de la entropía.\n"
 
 #~ msgid ""
 #~ "\n"
@@ -7311,9 +7133,9 @@ msgstr ""
 #~ "the OS a chance to collect more entropy! (Need %d more bytes)\n"
 #~ msgstr ""
 #~ "\n"
-#~ "No hay suficientes bytes aleatorios disponibles. Por favor, haga algún\n"
-#~ "otro trabajo para que el sistema pueda recolectar más entropía\n"
-#~ "(se necesitan %d bytes más).\n"
+#~ "No hay suficientes bytes aleatorios disponibles. Por favor, haga algún\n"
+#~ "otro trabajo para que el sistema pueda recolectar más entropía\n"
+#~ "(se necesitan %d bytes más).\n"
 
 #, fuzzy
 #~ msgid "card reader not available\n"
@@ -7323,7 +7145,7 @@ msgstr ""
 #~ msgstr "Inserte la tarjeta y pulse Intro o escriba 'c' para cancelar: "
 
 #~ msgid "Hit return when ready or enter 'c' to cancel: "
-#~ msgstr "Pulse Intro cuando esté listo"
+#~ msgstr "Pulse Intro cuando esté listo"
 
 #~ msgid "Enter New Admin PIN: "
 #~ msgstr "Introduzca nuevo PIN de administrador: "
@@ -7336,7 +7158,7 @@ msgstr ""
 
 #, fuzzy
 #~ msgid "NOTE: %s is not available in this version\n"
-#~ msgstr "el agente gpg no esta disponible en esta sesión\n"
+#~ msgstr "el agente gpg no esta disponible en esta sesión\n"
 
 #, fuzzy
 #~ msgid "         algorithms on these user IDs:\n"
@@ -7349,13 +7171,13 @@ msgstr ""
 #~ msgstr "Formato desconocido"
 
 #~ msgid "unknown pubkey algorithm"
-#~ msgstr "Algoritmo de clave pública desconocido"
+#~ msgstr "Algoritmo de clave pública desconocido"
 
 #~ msgid "unknown digest algorithm"
 #~ msgstr "Algoritmo desconocido de resumen de mensaje"
 
 #~ msgid "bad public key"
-#~ msgstr "Clave pública incorrecta"
+#~ msgstr "Clave pública incorrecta"
 
 #~ msgid "bad secret key"
 #~ msgstr "Clave secreta incorrecta"
@@ -7364,26 +7186,29 @@ msgstr ""
 #~ msgstr "Firma incorrecta"
 
 #~ msgid "checksum error"
-#~ msgstr "Error en la suma de comprobación"
+#~ msgstr "Error en la suma de comprobación"
 
 #~ msgid "unknown cipher algorithm"
 #~ msgstr "Algoritmo de cifrado desconocido"
 
-# Â¿y llavero?
+# ¿y llavero?
 # Hombre... las claves son parecidas a las llaves pero no lo mismo
 # toda la literatura en castellano usa "anillos de claves" si un
-# programa nos habla del llavero Â¿no puedo abrir el llavero? nos
+# programa nos habla del llavero ¿no puedo abrir el llavero? nos
 # miraremos en el bolsillo bastante desconcertados. No creo que se
 # trate de establecer una nomenclatura propia.
-# A lo mejor toda esa literatura está producida por gente que no sabía
-# cómo se dice llavero en inglés...
-# Si los ingleses dicen llavero en su idioma ¿por qué no vamos a poder
+# A lo mejor toda esa literatura está producida por gente que no sabía
+# cómo se dice llavero en inglés...
+# Si los ingleses dicen llavero en su idioma ¿por qué no vamos a poder
 # nosotros decir lo mismo en el nuestro?
 #~ msgid "can't open the keyring"
 #~ msgstr "No se puede abrir el anillo de claves"
 
 #~ msgid "invalid packet"
-#~ msgstr "paquete inválido"
+#~ msgstr "paquete inválido"
+
+#~ msgid "invalid armor"
+#~ msgstr "armadura inválida"
 
 #~ msgid "no such user id"
 #~ msgstr "no existe el ID de usuario"
@@ -7394,6 +7219,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "clave secreta incorrecta"
 
+#~ msgid "not supported"
+#~ msgstr "no disponible"
+
 #~ msgid "bad key"
 #~ msgstr "clave incorrecta"
 
@@ -7401,7 +7229,7 @@ msgstr ""
 #~ msgstr "error de escritura"
 
 #~ msgid "unknown compress algorithm"
-#~ msgstr "algoritmo de compresión desconocido"
+#~ msgstr "algoritmo de compresión desconocido"
 
 #~ msgid "file open error"
 #~ msgstr "error al abrir fichero"
@@ -7409,8 +7237,11 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "error al crear fichero"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "frase contraseña incorrecta"
+
 #~ msgid "unimplemented pubkey algorithm"
-#~ msgstr "algoritmo de clave pública no implementado"
+#~ msgstr "algoritmo de clave pública no implementado"
 
 #~ msgid "unimplemented cipher algorithm"
 #~ msgstr "algoritmo de cifrado no implementado"
@@ -7422,10 +7253,10 @@ msgstr ""
 #~ msgstr "error en la base de datos de confianza"
 
 #~ msgid "resource limit"
-#~ msgstr "límite de recurso"
+#~ msgstr "límite de recurso"
 
 #~ msgid "invalid keyring"
-#~ msgstr "anillo inválido"
+#~ msgstr "anillo inválido"
 
 #~ msgid "bad certificate"
 #~ msgstr "certificado incorrecto"
@@ -7447,19 +7278,19 @@ msgstr ""
 
 # o tal vez "en el sello..."
 # Creo que es mejor "con el sello de fecha", no es un conflicto
-# del sello en si mismo sino en relación con el mensaje.
+# del sello en si mismo sino en relación con el mensaje.
 # Ok.
 #~ msgid "timestamp conflict"
 #~ msgstr "conflicto con el sello de fecha"
 
 #~ msgid "unusable pubkey algorithm"
-#~ msgstr "algoritmo de clave pública no utilizable"
+#~ msgstr "algoritmo de clave pública no utilizable"
 
 #~ msgid "file exists"
 #~ msgstr "el fichero existe"
 
 #~ msgid "weak key"
-#~ msgstr "clave débil"
+#~ msgstr "clave débil"
 
 #~ msgid "bad URI"
 #~ msgstr "URI incorrecto"
@@ -7474,7 +7305,7 @@ msgstr ""
 #~ msgstr "no procesado"
 
 #~ msgid "unusable public key"
-#~ msgstr "clave pública inutilizable"
+#~ msgstr "clave pública inutilizable"
 
 #~ msgid "unusable secret key"
 #~ msgstr "clave secreta inutilizable"
@@ -7496,16 +7327,16 @@ msgstr ""
 #~ msgstr "ATENCION: "
 
 # bicho :-)
-# Â¿Error simplemente?
-# Uf, preferiría bug, si leo "error" voy a pensar en otra cosa distinta...
+# ¿Error simplemente?
+# Uf, preferiría bug, si leo "error" voy a pensar en otra cosa distinta...
 #~ msgid "... this is a bug (%s:%d:%s)\n"
 #~ msgstr "... esto es un bug (%s:%d:%s)\n"
 
 #~ msgid "WARNING: using insecure memory!\n"
-#~ msgstr "ATENCIÓN: ¡se está usando memoria insegura!\n"
+#~ msgstr "ATENCIÓN: ¡se está usando memoria insegura!\n"
 
 #~ msgid "operation is not possible without initialized secure memory\n"
-#~ msgstr "operación imposible sin memoria segura inicializada\n"
+#~ msgstr "operación imposible sin memoria segura inicializada\n"
 
 #~ msgid "(you may have used the wrong program for this task)\n"
 #~ msgstr ""
@@ -7514,8 +7345,8 @@ msgstr ""
 #~ msgid ""
 #~ "please see http://www.gnupg.org/why-not-idea.html for more information\n"
 #~ msgstr ""
-#~ "por favor vea http://www.gnupg.org/why-not-idea.html para más "
-#~ "información\n"
+#~ "por favor vea http://www.gnupg.org/why-not-idea.html para más "
+#~ "información\n"
 
 #, fuzzy
 #~ msgid "all export-clean-* options from above"
@@ -7526,7 +7357,7 @@ msgstr ""
 #~ msgstr "lee opciones del fichero"
 
 #~ msgid "expired: %s)"
-#~ msgstr "caducó: %s)"
+#~ msgstr "caducó: %s)"
 
 #~ msgid "key %s: expired signature from key %s - skipped\n"
 #~ msgstr "clave %s: firma caducada con la clave %s - omitida\n"
@@ -7540,7 +7371,7 @@ msgstr ""
 #~ msgstr "No hay clave secreta para tal usuario\n"
 
 #~ msgid "length of RSA modulus is not %d\n"
-#~ msgstr "la longitud del módulo RSA no es %d\n"
+#~ msgstr "la longitud del módulo RSA no es %d\n"
 
 #~ msgid "length of an RSA prime is not %d\n"
 #~ msgstr "la longitud del primo RSA no es %d\n"
@@ -7558,22 +7389,22 @@ msgstr ""
 #~ msgstr "no puedo conseguir el FD de escritura para el agente\n"
 
 #~ msgid "invalid response from agent\n"
-#~ msgstr "respuesta del agente inválida\n"
+#~ msgstr "respuesta del agente inválida\n"
 
 #~ msgid "digest algorithm `%s' is read-only in this release\n"
-#~ msgstr "el algoritmo de resumen `%s' es de sólo lectura en esta versión\n"
+#~ msgstr "el algoritmo de resumen `%s' es de sólo lectura en esta versión\n"
 
 #~ msgid ""
 #~ "WARNING: digest `%s' is not part of OpenPGP.  Use at your own risk!\n"
 #~ msgstr ""
-#~ "AVISO: el resumen `%s' no es parte de OpenPGP. ¡Úselo bajo su "
+#~ "AVISO: el resumen `%s' no es parte de OpenPGP. ¡Úselo bajo su "
 #~ "responsabilidad!\n"
 
 #~ msgid "|[files]|encrypt files"
 #~ msgstr "|[ficheros]|cifra ficheros"
 
 #~ msgid "store only"
-#~ msgstr "sólo almacenar"
+#~ msgstr "sólo almacenar"
 
 #~ msgid "|[files]|decrypt files"
 #~ msgstr "|[ficheros]|descifra ficheros"
@@ -7585,7 +7416,7 @@ msgstr ""
 #~ msgstr "firma la clave localmente y no revocablemente"
 
 #~ msgid "list only the sequence of packets"
-#~ msgstr "lista sólo la secuencia de paquetes"
+#~ msgstr "lista sólo la secuencia de paquetes"
 
 #~ msgid "export the ownertrust values"
 #~ msgstr "exporta los valores de confianza"
@@ -7594,13 +7425,13 @@ msgstr ""
 #~ msgstr "actualiza la base de datos de confianza"
 
 #~ msgid "fix a corrupted trust database"
-#~ msgstr "arregla una base de datos de confianza dañada"
+#~ msgstr "arregla una base de datos de confianza dañada"
 
 #~ msgid "De-Armor a file or stdin"
-#~ msgstr "quita la armadura de un fichero o de la entrada estándar"
+#~ msgstr "quita la armadura de un fichero o de la entrada estándar"
 
 #~ msgid "En-Armor a file or stdin"
-#~ msgstr "crea la armadura a un fichero o a la entrada estándar"
+#~ msgstr "crea la armadura a un fichero o a la entrada estándar"
 
 #~ msgid "do not force v3 signatures"
 #~ msgstr "no fuerza firmas v3"
@@ -7620,10 +7451,10 @@ msgstr ""
 #~ msgstr "usa el agente gpg"
 
 #~ msgid "|[file]|write status info to file"
-#~ msgstr "|[fichero]|escribe información de estado en el fichero"
+#~ msgstr "|[fichero]|escribe información de estado en el fichero"
 
 #~ msgid "|KEYID|ultimately trust this key"
-#~ msgstr "|ID-CLAVE|confía plenamente en esta clave"
+#~ msgstr "|ID-CLAVE|confía plenamente en esta clave"
 
 #~ msgid "emulate the mode described in RFC1991"
 #~ msgstr "emula el modo descrito en la RFC1991"
@@ -7636,26 +7467,26 @@ msgstr ""
 
 #~ msgid "|NAME|use message digest algorithm NAME for passphrases"
 #~ msgstr ""
-#~ "|NOMBRE|usa algoritmo de resumen de mensaje NOMBRE para las contraseñas"
+#~ "|NOMBRE|usa algoritmo de resumen de mensaje NOMBRE para las contraseñas"
 
 #~ msgid "throw keyid field of encrypted packets"
 #~ msgstr "elimina campo keyid de los paquetes cifrados"
 
 #~ msgid "Show Photo IDs"
-#~ msgstr "Muestra IDs fotográficos"
+#~ msgstr "Muestra IDs fotográficos"
 
 #~ msgid "Don't show Photo IDs"
-#~ msgstr "No muestra IDs fotográficos"
+#~ msgstr "No muestra IDs fotográficos"
 
 #~ msgid "Set command line to view Photo IDs"
-#~ msgstr "Ajusta linea de comandos para ver IDs fotográficos"
+#~ msgstr "Ajusta linea de comandos para ver IDs fotográficos"
 
 #~ msgid "compress algorithm `%s' is read-only in this release\n"
 #~ msgstr ""
-#~ "el algoritmo de compresión `%s' es de sólo lectura en esta versión\n"
+#~ "el algoritmo de compresión `%s' es de sólo lectura en esta versión\n"
 
 #~ msgid "compress algorithm must be in range %d..%d\n"
-#~ msgstr "el algoritmo de compresión debe estar en el rango %d-%d\n"
+#~ msgstr "el algoritmo de compresión debe estar en el rango %d-%d\n"
 
 #~ msgid "--nrsign-key user-id"
 #~ msgstr "--nrsign-key id-usuario"
@@ -7664,16 +7495,16 @@ msgstr ""
 #~ msgstr "--nrlsign-key id-usuario"
 
 #~ msgid "key %08lX: key has been revoked!\n"
-#~ msgstr "clave %08lX: Â¡esta clave ha sido revocada!\n"
+#~ msgstr "clave %08lX: ¡esta clave ha sido revocada!\n"
 
 #~ msgid "key %08lX: subkey has been revoked!\n"
-#~ msgstr "clave %08lX: Â¡esta subclave ha sido revocada!\n"
+#~ msgstr "clave %08lX: ¡esta subclave ha sido revocada!\n"
 
 #~ msgid "%08lX: key has expired\n"
 #~ msgstr "%08lX: clave caducada\n"
 
 #~ msgid "%08lX: We do NOT trust this key\n"
-#~ msgstr "%08lX: Â¡Esta clave NO es de confianza!\n"
+#~ msgstr "%08lX: ¡Esta clave NO es de confianza!\n"
 
 #~ msgid ""
 #~ "%08lX: It is not sure that this key really belongs to the owner\n"
@@ -7683,7 +7514,7 @@ msgstr ""
 #~ "proprietario pero se acepta igualmente\n"
 
 #~ msgid "preference %c%lu is not valid\n"
-#~ msgstr "la preferencia %c%lu no es válida\n"
+#~ msgstr "la preferencia %c%lu no es válida\n"
 
 #~ msgid ""
 #~ "About to generate a new %s keypair.\n"
@@ -7692,45 +7523,45 @@ msgstr ""
 #~ "    highest suggested keysize is 2048 bits\n"
 #~ msgstr ""
 #~ "Listo para generar un nuevo par de claves %s.\n"
-#~ "              el tamaño mínimo es 768 bits\n"
-#~ "        el tamaño por defecto es 1024 bits\n"
-#~ " el tamaño máximo recomendado es 2048 bits\n"
+#~ "              el tamaño mínimo es 768 bits\n"
+#~ "        el tamaño por defecto es 1024 bits\n"
+#~ " el tamaño máximo recomendado es 2048 bits\n"
 
 #~ msgid "DSA only allows keysizes from 512 to 1024\n"
-#~ msgstr "DSA sólo permite tamaños desde 512 a 1024\n"
+#~ msgstr "DSA sólo permite tamaños desde 512 a 1024\n"
 
 #~ msgid "keysize too small; 1024 is smallest value allowed for RSA.\n"
 #~ msgstr ""
-#~ "tamaño de clave insuficiente; 1024 es el mínimo permitido para RSA.\n"
+#~ "tamaño de clave insuficiente; 1024 es el mínimo permitido para RSA.\n"
 
 #~ msgid "keysize too small; 768 is smallest value allowed.\n"
-#~ msgstr "tamaño insuficiente; 768 es el valor mínimo permitido\n"
+#~ msgstr "tamaño insuficiente; 768 es el valor mínimo permitido\n"
 
 #~ msgid "keysize too large; %d is largest value allowed.\n"
-#~ msgstr "tamaño excesivo; %d es el máximo valor permitido.\n"
+#~ msgstr "tamaño excesivo; %d es el máximo valor permitido.\n"
 
 #~ msgid ""
 #~ "Keysizes larger than 2048 are not suggested because\n"
 #~ "computations take REALLY long!\n"
 #~ msgstr ""
-#~ "No se recomiendan claves de más de 2048 bits porque\n"
-#~ "¡el tiempo de cálculo es REALMENTE largo!\n"
+#~ "No se recomiendan claves de más de 2048 bits porque\n"
+#~ "¡el tiempo de cálculo es REALMENTE largo!\n"
 
 #~ msgid "Are you sure that you want this keysize? "
-#~ msgstr "¿Seguro que quiere una clave de este tamaño? "
+#~ msgstr "¿Seguro que quiere una clave de este tamaño? "
 
 #~ msgid ""
 #~ "Okay, but keep in mind that your monitor and keyboard radiation is also "
 #~ "very vulnerable to attacks!\n"
 #~ msgstr ""
-#~ "De acuerdo, Â¡pero tenga en cuenta que las radiaciones de su monitor y\n"
-#~ "teclado también son vulnerables a un ataque!\n"
+#~ "De acuerdo, ¡pero tenga en cuenta que las radiaciones de su monitor y\n"
+#~ "teclado también son vulnerables a un ataque!\n"
 
 #~ msgid "%s: can't open: %s\n"
 #~ msgstr "%s: no se puede abrir: %s\n"
 
 #~ msgid "%s: WARNING: empty file\n"
-#~ msgstr "%s: ATENCIÓN: fichero vacío\n"
+#~ msgstr "%s: ATENCIÓN: fichero vacío\n"
 
 #~ msgid "key %08lX: not a rfc2440 key - skipped\n"
 #~ msgstr "clave %08lX: no es conforme a rfc2440 - omitida\n"
@@ -7745,7 +7576,7 @@ msgstr ""
 #~ msgstr "(por defecto)"
 
 #~ msgid "Really sign? "
-#~ msgstr "¿Firmar de verdad? "
+#~ msgstr "¿Firmar de verdad? "
 
 #~ msgid "q"
 #~ msgstr "s"
@@ -7802,10 +7633,10 @@ msgstr ""
 #~ msgstr "depura"
 
 #~ msgid "adduid"
-#~ msgstr "añaidu"
+#~ msgstr "añaidu"
 
 #~ msgid "addphoto"
-#~ msgstr "añadirfoto"
+#~ msgstr "añadirfoto"
 
 #~ msgid "deluid"
 #~ msgstr "borridu"
@@ -7814,13 +7645,13 @@ msgstr ""
 #~ msgstr "borfoto"
 
 #~ msgid "add a secondary key"
-#~ msgstr "añade una clave secundaria"
+#~ msgstr "añade una clave secundaria"
 
 #~ msgid "delkey"
 #~ msgstr "borrcla"
 
 #~ msgid "addrevoker"
-#~ msgstr "añarevoc"
+#~ msgstr "añarevoc"
 
 #~ msgid "delsig"
 #~ msgstr "borrfir"
@@ -7877,10 +7708,10 @@ msgstr ""
 #~ msgstr "%s%c %4u%c/%08lX  creada: %s expira: %s"
 
 #~ msgid "rev! subkey has been revoked: %s\n"
-#~ msgstr "rev! Â¡esta subclave ha sido revocada! %s\n"
+#~ msgstr "rev! ¡esta subclave ha sido revocada! %s\n"
 
 #~ msgid "rev- faked revocation found\n"
-#~ msgstr "rev-  se encontró una revocación falsificada\n"
+#~ msgstr "rev-  se encontró una revocación falsificada\n"
 
 #~ msgid ""
 #~ "\"\n"
@@ -7896,25 +7727,25 @@ msgstr ""
 #~ msgstr "   firmada por %08lX el %s%s\n"
 
 #~ msgid "Policy: "
-#~ msgstr "Política: "
+#~ msgstr "Política: "
 
 #~ msgid "Experimental algorithms should not be used!\n"
-#~ msgstr "¡No se deberían usar algoritmos experimentales!\n"
+#~ msgstr "¡No se deberían usar algoritmos experimentales!\n"
 
 #~ msgid ""
 #~ "this cipher algorithm is deprecated; please use a more standard one!\n"
 #~ msgstr ""
-#~ "ese algoritmo de cifrado está desacreditado;¡por favor use uno más "
-#~ "estándar!\n"
+#~ "ese algoritmo de cifrado está desacreditado;¡por favor use uno más "
+#~ "estándar!\n"
 
 #~ msgid "can't get key from keyserver: %s\n"
 #~ msgstr "no puede obtenerse la clave en el servidor: %s\n"
 
 #~ msgid "success sending to `%s' (status=%u)\n"
-#~ msgstr "envió correcto a `%s` (estado=%u)\n"
+#~ msgstr "envió correcto a `%s` (estado=%u)\n"
 
 #~ msgid "failed sending to `%s': status=%u\n"
-#~ msgstr "falló el envio a `%s': status=%u\n"
+#~ msgstr "falló el envio a `%s': status=%u\n"
 
 #~ msgid "this keyserver does not support --search-keys\n"
 #~ msgstr "este servidor de clave no proporciona --search-keys\n"
@@ -7966,11 +7797,11 @@ msgstr ""
 
 #~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"
 #~ msgstr ""
-#~ "comprobando en profundidad %d firmado=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/"
-#~ "%d\n"
+#~ "comprobando en profundidad %d firmado=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%"
+#~ "d\n"
 
 #~ msgid "If you want to use this revoked key anyway, answer \"yes\"."
-#~ msgstr "Si quiere usar esta clave revocada de todos modos, conteste \"sí\"."
+#~ msgstr "Si quiere usar esta clave revocada de todos modos, conteste \"sí\"."
 
 #~ msgid ""
 #~ "Select the algorithm to use.\n"
@@ -7995,34 +7826,34 @@ msgstr ""
 #~ "in\n"
 #~ "this menu."
 #~ msgstr ""
-#~ "Seleccione el algoritmo que usará.\n"
+#~ "Seleccione el algoritmo que usará.\n"
 #~ "\n"
-#~ "DSA (también conocido como DSS) es un algoritmo de firma digital que "
-#~ "sólo\n"
+#~ "DSA (también conocido como DSS) es un algoritmo de firma digital que "
+#~ "sólo\n"
 #~ "puede usarse para firmas. Es el algoritmo sugerido porque la "
-#~ "verificación\n"
-#~ "de firmas DSA es mucho más rápida que la de firmas ElGamal.\n"
+#~ "verificación\n"
+#~ "de firmas DSA es mucho más rápida que la de firmas ElGamal.\n"
 #~ "\n"
 #~ "ElGamal es un algoritmo que puede ser usado para firma y cifrado. "
 #~ "OpenPGP\n"
-#~ "distingue entre dos tipos de estos algoritmos: sólo para cifrado y para\n"
+#~ "distingue entre dos tipos de estos algoritmos: sólo para cifrado y para\n"
 #~ "firma y cifrado. En realidad es lo mismo, pero se deben seleccionar "
 #~ "ciertos\n"
-#~ "parámetros de una forma particular para crear una clave segura para "
+#~ "parámetros de una forma particular para crear una clave segura para "
 #~ "firmas:\n"
-#~ "este programa lo hace así, pero otras implementaciones de OpenPGP no "
+#~ "este programa lo hace así, pero otras implementaciones de OpenPGP no "
 #~ "tienen\n"
-#~ "por qué entender el tipo de firma y cifrado.\n"
+#~ "por qué entender el tipo de firma y cifrado.\n"
 #~ "\n"
 #~ "La clave primaria debe ser una clave capaz de firmar, es por ello que la\n"
-#~ "opción de clave ElGamal sólo para cifrado no está disponible en este menú."
+#~ "opción de clave ElGamal sólo para cifrado no está disponible en este menú."
 
 #~ msgid ""
 #~ "Although these keys are defined in RFC2440 they are not suggested\n"
 #~ "because they are not supported by all programs and signatures created\n"
 #~ "with them are quite large and very slow to verify."
 #~ msgstr ""
-#~ "Aunque estas claves están definidas en RFC2440, no se aconseja su uso,\n"
+#~ "Aunque estas claves están definidas en RFC2440, no se aconseja su uso,\n"
 #~ "ya que no todos los programas pueden utilizarlas y las firmas creadas\n"
 #~ "con ellas son bastante grandes y lentas de verificar."
 
@@ -8057,44 +7888,44 @@ msgstr ""
 #~ "also\n"
 #~ "very slow, and may not be as secure as the other choices.\n"
 #~ msgstr ""
-#~ "El uso de este algoritmo sólo es posible con GnuPG. No será posible\n"
+#~ "El uso de este algoritmo sólo es posible con GnuPG. No será posible\n"
 #~ "comunicarse mediante esta clave con usuarios de PGP. Este algoritmo\n"
-#~ "es además muy lento, y podría no ser tan seguro como otros.\n"
+#~ "es además muy lento, y podría no ser tan seguro como otros.\n"
 
 #~ msgid "Create anyway? "
-#~ msgstr "¿Crear de todas formas?"
+#~ msgstr "¿Crear de todas formas?"
 
 #~ msgid "invalid symkey algorithm detected (%d)\n"
-#~ msgstr "detectado algoritmo simétrico inválido (%d)\n"
+#~ msgstr "detectado algoritmo simétrico inválido (%d)\n"
 
 #~ msgid "this keyserver is not fully HKP compatible\n"
 #~ msgstr "este servidor de claves no es totalmente compatible con HKP\n"
 
 #~ msgid "The use of this algorithm is deprecated - create anyway? "
 #~ msgstr ""
-#~ "El uso de este algoritmo está desaconsejado - Â¿crear de todas formas?"
+#~ "El uso de este algoritmo está desaconsejado - ¿crear de todas formas?"
 
 #~ msgid "|NAME=VALUE|use this notation data"
-#~ msgstr "|NOMBRE=VALOR|usa estos datos de notación"
+#~ msgstr "|NOMBRE=VALOR|usa estos datos de notación"
 
 #~ msgid ""
 #~ "the first character of a notation name must be a letter or an underscore\n"
 #~ msgstr ""
-#~ "El primer carácter de una notación debe ser una letra o un subrayado\n"
+#~ "El primer carácter de una notación debe ser una letra o un subrayado\n"
 
 #~ msgid "dots in a notation name must be surrounded by other characters\n"
 #~ msgstr ""
-#~ "los puntos en una notación deben estar rodeados por otros caracteres\n"
+#~ "los puntos en una notación deben estar rodeados por otros caracteres\n"
 
 #~ msgid ""
 #~ "WARNING: This key already has a photo ID.\n"
 #~ "         Adding another photo ID may confuse some versions of PGP.\n"
 #~ msgstr ""
-#~ "AVISO: Esta clave ya tiene identificador fotográfico.\n"
-#~ "       Añadir otro ID puede confundir a algunas versiones de PGP.\n"
+#~ "AVISO: Esta clave ya tiene identificador fotográfico.\n"
+#~ "       Añadir otro ID puede confundir a algunas versiones de PGP.\n"
 
 #~ msgid "You may only have one photo ID on a key.\n"
-#~ msgstr "Solo puede tener un ID fotográfico en una clave.\n"
+#~ msgstr "Solo puede tener un ID fotográfico en una clave.\n"
 
 #~ msgid "             Fingerprint:"
 #~ msgstr "         Huella dactilar:"
@@ -8103,18 +7934,18 @@ msgstr ""
 #~ msgstr "reinicie GnuPG otra vez para que lea el nuevo fichero de opciones\n"
 
 #~ msgid "changing permission of  `%s' failed: %s\n"
-#~ msgstr "al cambiar permisos de `%s' ocurrió el fallo: %s\n"
+#~ msgstr "al cambiar permisos de `%s' ocurrió el fallo: %s\n"
 
 #, fuzzy
 #~ msgid "Are you sure you still want to sign it?\n"
-#~ msgstr "¿Seguro que quiere una clave de este tamaño? "
+#~ msgstr "¿Seguro que quiere una clave de este tamaño? "
 
 #, fuzzy
 #~ msgid "  Are you sure you still want to sign it?\n"
-#~ msgstr "¿Seguro que quiere una clave de este tamaño? "
+#~ msgstr "¿Seguro que quiere una clave de este tamaño? "
 
 #~ msgid "too many random bits requested; the limit is %d\n"
-#~ msgstr "se solicitan demasiados bits aleatorios; el límite es %d\n"
+#~ msgstr "se solicitan demasiados bits aleatorios; el límite es %d\n"
 
 #~ msgid "|[NAMES]|check the trust database"
 #~ msgstr "|[NOMBRES]|comprueba la base de datos de confianza"
@@ -8129,7 +7960,7 @@ msgstr ""
 #~ msgstr "--delete-secret-and-public-key id-usuario"
 
 #~ msgid "For info see http://www.gnupg.org"
-#~ msgstr "Información en http://www.gnupg.org"
+#~ msgstr "Información en http://www.gnupg.org"
 
 #~ msgid "sSmMqQ"
 #~ msgstr "iImMqQ"
@@ -8139,7 +7970,7 @@ msgstr ""
 #~ "can assign some missing owner trust values.\n"
 #~ "\n"
 #~ msgstr ""
-#~ "No puede encontrarse una ruta de confianza válida para esta clave. "
+#~ "No puede encontrarse una ruta de confianza válida para esta clave. "
 #~ "Veamos\n"
 #~ "si es posible asignar algunos valores de confianza perdidos.\n"
 #~ "\n"
@@ -8155,27 +7986,30 @@ msgstr ""
 #~ "No trust values changed.\n"
 #~ "\n"
 #~ msgstr ""
-#~ "No se cambió ningún valor de confianza.\n"
+#~ "No se cambió ningún valor de confianza.\n"
 #~ "\n"
 
 #~ msgid "%08lX: no info to calculate a trust probability\n"
 #~ msgstr ""
-#~ "%08lX: no hay información para calcular la probabilidad de confianza\n"
+#~ "%08lX: no hay información para calcular la probabilidad de confianza\n"
 
 #~ msgid "skipped: public key already set with --encrypt-to\n"
-#~ msgstr "omitida: clave pública ya designada con --encrypt-to\n"
+#~ msgstr "omitida: clave pública ya designada con --encrypt-to\n"
 
 #~ msgid "%s: error checking key: %s\n"
 #~ msgstr "%s: error comprobando la clave: %s\n"
 
+#~ msgid "Do you really want to create a sign and encrypt key? "
+#~ msgstr "¿De verdad quiere crear una clave de firma y cifrado? "
+
 #~ msgid "Do you really need such a large keysize? "
-#~ msgstr "¿De verdad necesita una clave tan grande? "
+#~ msgstr "¿De verdad necesita una clave tan grande? "
 
 #~ msgid "too many entries in unk cache - disabled\n"
 #~ msgstr "demasiados registros en la cache unk - anulada\n"
 
 #~ msgid "no default public keyring\n"
-#~ msgstr "no hay anillo público por defecto\n"
+#~ msgstr "no hay anillo público por defecto\n"
 
 #~ msgid "secret key %08lX not imported (use %s to allow for it)\n"
 #~ msgstr "clave secreta %08lX no importada (use %s para permitirlo)\n"
@@ -8184,7 +8018,7 @@ msgstr ""
 #~ msgstr "clave %08lX: nuestra copia no tiene autofirma\n"
 
 #~ msgid "assuming bad MDC due to an unknown critical bit\n"
-#~ msgstr "asumiendo MDC incorrecto debido a un bit crítico desconocido\n"
+#~ msgstr "asumiendo MDC incorrecto debido a un bit crítico desconocido\n"
 
 #~ msgid "error reading dir record for LID %lu: %s\n"
 #~ msgstr "error leyendo registro de directorio del LID %lu: %s\n"
@@ -8199,47 +8033,47 @@ msgstr ""
 #~ msgstr "error leyendo clave primaria para el LID %lu: %s\n"
 
 #~ msgid "key %08lX: query record failed\n"
-#~ msgstr "clave %08lX: petición de registro fallida\n"
+#~ msgstr "clave %08lX: petición de registro fallida\n"
 
 #~ msgid "key %08lX: already in trusted key table\n"
-#~ msgstr "clave %08lX: ya está en la tabla de confianza\n"
+#~ msgstr "clave %08lX: ya está en la tabla de confianza\n"
 
 #~ msgid "NOTE: secret key %08lX is NOT protected.\n"
-#~ msgstr "NOTA: la clave secreta %08lX NO está protegida.\n"
+#~ msgstr "NOTA: la clave secreta %08lX NO está protegida.\n"
 
 #~ msgid "key %08lX: secret and public key don't match\n"
-#~ msgstr "clave %08lX: las claves pública y secreta no se corresponden\n"
+#~ msgstr "clave %08lX: las claves pública y secreta no se corresponden\n"
 
 #~ msgid "key %08lX.%lu: Good subkey binding\n"
-#~ msgstr "clave %08lX.%lu: unión de subclave válida\n"
+#~ msgstr "clave %08lX.%lu: unión de subclave válida\n"
 
 #~ msgid "key %08lX.%lu: Invalid subkey binding: %s\n"
-#~ msgstr "clave %08lX.%lu: unión de subclave inválida: %s\n"
+#~ msgstr "clave %08lX.%lu: unión de subclave inválida: %s\n"
 
 #~ msgid "key %08lX.%lu: Valid key revocation\n"
-#~ msgstr "clave %08lX.%lu: revocación de clave válida\n"
+#~ msgstr "clave %08lX.%lu: revocación de clave válida\n"
 
 #~ msgid "key %08lX.%lu: Invalid key revocation: %s\n"
-#~ msgstr "clave %08lX.%lu: revocación de clave inválida: %s\n"
+#~ msgstr "clave %08lX.%lu: revocación de clave inválida: %s\n"
 
 #~ msgid "Good self-signature"
-#~ msgstr "Autofirma válida"
+#~ msgstr "Autofirma válida"
 
 #~ msgid "Invalid self-signature"
-#~ msgstr "Autofirma inválida"
+#~ msgstr "Autofirma inválida"
 
 #~ msgid "Valid user ID revocation skipped due to a newer self signature"
 #~ msgstr ""
-#~ "Revocación válida de ID de usuario omitida, existe autofirma más reciente"
+#~ "Revocación válida de ID de usuario omitida, existe autofirma más reciente"
 
 #~ msgid "Valid user ID revocation"
-#~ msgstr "Revocación de ID de usuario válida"
+#~ msgstr "Revocación de ID de usuario válida"
 
 #~ msgid "Invalid user ID revocation"
-#~ msgstr "Revocación de ID de usuario inválida."
+#~ msgstr "Revocación de ID de usuario inválida."
 
 #~ msgid "Invalid certificate revocation"
-#~ msgstr "Certificado de revocación incorrecto"
+#~ msgstr "Certificado de revocación incorrecto"
 
 #~ msgid "sig record %lu[%d] points to wrong record.\n"
 #~ msgstr "registro de firma %lu[%d] apunta al registro equivocado.\n"
@@ -8248,10 +8082,10 @@ msgstr ""
 #~ msgstr "tdbio_search_dir fallida: %s\n"
 
 #~ msgid "lid ?: insert failed: %s\n"
-#~ msgstr "lid ?: inserción fallida: %s\n"
+#~ msgstr "lid ?: inserción fallida: %s\n"
 
 #~ msgid "lid %lu: insert failed: %s\n"
-#~ msgstr "lid %lu: inserción fallida: %s\n"
+#~ msgstr "lid %lu: inserción fallida: %s\n"
 
 #~ msgid "lid %lu: inserted\n"
 #~ msgstr "lid %lu: insertada\n"
@@ -8266,7 +8100,7 @@ msgstr ""
 #~ msgstr "lid %lu: registro de directiorio sin clave - omitido\n"
 
 #~ msgid "\t%lu due to new pubkeys\n"
-#~ msgstr "\t%lu debido a las nuevas claves públicas\n"
+#~ msgstr "\t%lu debido a las nuevas claves públicas\n"
 
 #~ msgid "\t%lu keys updated\n"
 #~ msgstr "\t%lu claves actualizadas\n"
@@ -8275,13 +8109,13 @@ msgstr ""
 #~ msgstr "Oh oh, no hay claves\n"
 
 #~ msgid "Ooops, no user IDs\n"
-#~ msgstr "Oh oh, no hay ningún ID de usuario\n"
+#~ msgstr "Oh oh, no hay ningún ID de usuario\n"
 
 #~ msgid "check_trust: search dir record failed: %s\n"
-#~ msgstr "check_trust: búsqueda registro directorio fallida: %s\n"
+#~ msgstr "check_trust: búsqueda registro directorio fallida: %s\n"
 
 #~ msgid "key %08lX: insert trust record failed: %s\n"
-#~ msgstr "clave %08lX: inserción del registro de confianza fallida: %s\n"
+#~ msgstr "clave %08lX: inserción del registro de confianza fallida: %s\n"
 
 #~ msgid "key %08lX.%lu: inserted into trustdb\n"
 #~ msgstr "clave %08lX.%lu: incluida en la base de datos de confianza\n"
@@ -8295,20 +8129,20 @@ msgstr ""
 #~ msgstr "clave %08lX.%lu: caducada el %s\n"
 
 #~ msgid "key %08lX.%lu: trust check failed: %s\n"
-#~ msgstr "clave %08lX.%lu: comprobación de confianza fallida: %s\n"
+#~ msgstr "clave %08lX.%lu: comprobación de confianza fallida: %s\n"
 
 #~ msgid "problem finding '%s' in trustdb: %s\n"
 #~ msgstr "problema buscando '%s' en la tabla de confianza: %s\n"
 
 #~ msgid "user '%s' not in trustdb - inserting\n"
-#~ msgstr "usuario '%s' no está en la tabla de confianza - insertando\n"
+#~ msgstr "usuario '%s' no está en la tabla de confianza - insertando\n"
 
 #~ msgid "WARNING: can't yet handle long pref records\n"
 #~ msgstr ""
-#~ "ATENCÍON: todavía no puedo tratar registros de preferencias largos\n"
+#~ "ATENCÍON: todavía no puedo tratar registros de preferencias largos\n"
 
 #~ msgid "RSA key cannot be used in this version\n"
-#~ msgstr "No puede usarse clave RSA en esta versión\n"
+#~ msgstr "No puede usarse clave RSA en esta versión\n"
 
 #~ msgid "No key for user ID\n"
 #~ msgstr "No hay clave para tal usuario\n"
@@ -8320,7 +8154,7 @@ msgstr ""
 #~ "RSA keys are deprecated; please consider creating a new key and use this "
 #~ "key in the future\n"
 #~ msgstr ""
-#~ "Las claves RSA están en desuso, considere la creación de una nueva clave "
+#~ "Las claves RSA están en desuso, considere la creación de una nueva clave "
 #~ "para futuros usos\n"
 
 #~ msgid "do not write comment packets"
@@ -8333,7 +8167,7 @@ msgstr ""
 #~ msgstr "   (%d) ElGamal en un paquete v3\n"
 
 #~ msgid "Key generation can only be used in interactive mode\n"
-#~ msgstr "La creación de claves sólo es posible en modo interactivo\n"
+#~ msgstr "La creación de claves sólo es posible en modo interactivo\n"
 
 #, fuzzy
 #~ msgid "tdbio_search_sdir failed: %s\n"
@@ -8341,17 +8175,17 @@ msgstr ""
 
 #~ msgid "NOTE: sig rec %lu[%d] in hintlist of %lu but marked as checked\n"
 #~ msgstr ""
-#~ "NOTA: el registro de firma %lu[%d] está en la lista\n"
-#~ "de búsqueda de %lu pero está marcado como comprobado\n"
+#~ "NOTA: el registro de firma %lu[%d] está en la lista\n"
+#~ "de búsqueda de %lu pero está marcado como comprobado\n"
 
 #~ msgid "NOTE: sig rec %lu[%d] in hintlist of %lu but not marked\n"
 #~ msgstr ""
-#~ "NOTA: el registro de firma %lu[%d] está en la lista\n"
-#~ "de búsqueda de %lu pero no está marcado\n"
+#~ "NOTA: el registro de firma %lu[%d] está en la lista\n"
+#~ "de búsqueda de %lu pero no está marcado\n"
 
 #~ msgid "sig rec %lu[%d] in hintlist of %lu does not point to a dir record\n"
 #~ msgstr ""
-#~ "El registro de firma %lu[%d] en la lista de búsqueda de %lu\n"
+#~ "El registro de firma %lu[%d] en la lista de búsqueda de %lu\n"
 #~ "no apunta a un registro de directorio\n"
 
 #~ msgid "lid %lu: no primary key\n"
@@ -8363,27 +8197,27 @@ msgstr ""
 #~ "en el bloque de clave\n"
 
 #~ msgid "lid %lu: self-signature in hintlist\n"
-#~ msgstr "lid %lu: autofirma en lista de búsqueda\n"
+#~ msgstr "lid %lu: autofirma en lista de búsqueda\n"
 
 #~ msgid "very strange: no public key\n"
-#~ msgstr "muy raro: no hay clave pública\n"
+#~ msgstr "muy raro: no hay clave pública\n"
 
 #~ msgid "hintlist %lu[%d] of %lu does not point to a dir record\n"
 #~ msgstr ""
-#~ "la lista de búsqueda %lu[%d] de %lu no apunta a\n"
+#~ "la lista de búsqueda %lu[%d] de %lu no apunta a\n"
 #~ "un registro de directorio\n"
 
 #~ msgid "lid %lu: can't get keyblock: %s\n"
 #~ msgstr "lid %lu: no puedo obtener el bloque de clave: %s\n"
 
 #~ msgid "Too many preference items"
-#~ msgstr "Demasiados ítems de preferencias"
+#~ msgstr "Demasiados ítems de preferencias"
 
 #~ msgid "insert_trust_record: keyblock not found: %s\n"
 #~ msgstr "insert_trust_record: bloque de clave no encontrado: %s\n"
 
 #~ msgid "lid %lu: update failed: %s\n"
-#~ msgstr "lid %lu: actualización fallida: %s\n"
+#~ msgstr "lid %lu: actualización fallida: %s\n"
 
 #~ msgid "lid %lu: updated\n"
 #~ msgstr "lid %lu: actualizado\n"
@@ -8392,7 +8226,7 @@ msgstr ""
 #~ msgstr "lid %lu: bien\n"
 
 #~ msgid "%s: update failed: %s\n"
-#~ msgstr "%s: actualización fallida: %s\n"
+#~ msgstr "%s: actualización fallida: %s\n"
 
 #~ msgid "%s: updated\n"
 #~ msgstr "%s: actualizada\n"
@@ -8404,7 +8238,7 @@ msgstr ""
 #~ msgstr "lid %lu: bloque de clave no encontrado: %s\n"
 
 #~ msgid "can't lock keyring `%': %s\n"
-#~ msgstr "no puede bloquearse el anillo público `%s': %s\n"
+#~ msgstr "no puede bloquearse el anillo público `%s': %s\n"
 
 #~ msgid "writing keyblock\n"
 #~ msgstr "escribiendo bloque de claves\n"
@@ -8414,7 +8248,7 @@ msgstr ""
 
 #, fuzzy
 #~ msgid "encrypted message is valid\n"
-#~ msgstr "el algoritmo de resumen seleccionado no es válido\n"
+#~ msgstr "el algoritmo de resumen seleccionado no es válido\n"
 
 #, fuzzy
 #~ msgid "Can't check MDC: %s\n"
@@ -8442,25 +8276,25 @@ msgstr ""
 #~ msgstr "problema lista usuario '%s': %s\n"
 
 #~ msgid "user '%s' not in trustdb\n"
-#~ msgstr "usuario '%s' no está en la tabla de confianza\n"
+#~ msgstr "usuario '%s' no está en la tabla de confianza\n"
 
 #~ msgid "directory record w/o primary key\n"
 #~ msgstr "registro de directorio sin clave primaria\n"
 
 #~ msgid "key not in trustdb, searching ring.\n"
-#~ msgstr "la clave no está en tabla de confianza, buscando en el anillo.\n"
+#~ msgstr "la clave no está en tabla de confianza, buscando en el anillo.\n"
 
 #~ msgid "key not in ring: %s\n"
-#~ msgstr "la clave no está en el anillo: %s\n"
+#~ msgstr "la clave no está en el anillo: %s\n"
 
 #~ msgid "Oops: key is now in trustdb???\n"
-#~ msgstr "Oh oh: la clave ahora está en la tabla de confianza???\n"
+#~ msgstr "Oh oh: la clave ahora está en la tabla de confianza???\n"
 
 #~ msgid "Hmmm, public key lost?"
-#~ msgstr "Oh oh, ¿se ha perdido la clave pública?"
+#~ msgstr "Oh oh, ¿se ha perdido la clave pública?"
 
 #~ msgid "did not use primary key for insert_trust_record()\n"
-#~ msgstr "no se usó clave primaria para insert_trust_record()\n"
+#~ msgstr "no se usó clave primaria para insert_trust_record()\n"
 
 #~ msgid "second"
 #~ msgstr "segundo"
index 1aaeebe..6a0d25c 100644 (file)
--- a/po/et.po
+++ b/po/et.po
@@ -9,7 +9,6 @@ msgstr ""
 "PO-Revision-Date: 2004-06-17 11:04+0300\n"
 "Last-Translator: Toomas Soome <Toomas.Soome@microlink.ee>\n"
 "Language-Team: Estonian <et@li.org>\n"
-"Language: et\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8-bit\n"
@@ -18,41 +17,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "TrustDB initsialiseerimine ebaõnnestus: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Kas te tõesti soovite valitud võtmeid tühistada? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "vigane parool"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -78,9 +42,6 @@ msgid ""
 "this session"
 msgstr "Palun sisestage parool; see on salajane tekst \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -117,11 +78,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "kaitse algoritm %d%s ei ole toetatud\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "`%s' ei õnnestu luua: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "`%s' ei õnnestu avada: %s\n"
 
 #, fuzzy, c-format
@@ -148,31 +109,19 @@ msgstr "v
 msgid "error writing key: %s\n"
 msgstr "viga võtmehoidlasse `%s' kirjutamisel: %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Palun sisestage parool; see on salajane tekst \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "muuda parooli"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Palun sisestage parool; see on salajane tekst \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -199,7 +148,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -287,7 +236,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Te vajate oma salajase võtme kaitsmiseks parooli.\n"
 "\n"
@@ -305,10 +254,10 @@ msgstr ""
 "Võtmed:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -363,26 +312,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "viga parooli loomisel: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "ei ole toetatud"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "ei ole toetatud"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "viga parooli loomisel: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -404,7 +342,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -412,23 +350,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "MÄRKUS: vaikimisi võtmete fail `%s' puudub\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "võtmete fail `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "loen võtmeid failist `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "viga `%s' loomisel: %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "kataloogi `%s' ei õnnestu luua: %s\n"
 
 msgid "name of socket too long\n"
@@ -439,7 +377,7 @@ msgid "can't create socket: %s\n"
 msgstr "%s ei õnnestu luua: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -451,7 +389,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "viga parooli loomisel: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "viga teate saatmisel serverile `%s': %s\n"
 
 #, fuzzy, c-format
@@ -459,19 +397,19 @@ msgid "listen() failed: %s\n"
 msgstr "uuendamine ebaõnnestus: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "kirjutan salajase võtme faili `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: kataloog on loodud\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "trustdb: lugemine ebaõnnestus (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: kataloogi ei õnnestu luua: %s\n"
 
 #, fuzzy, c-format
@@ -579,31 +517,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "viga parooli loomisel: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "viga `%s' lugemisel: %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "võtit '%s' ei leitud: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "salajase võtme komponendid ei ole kättesaadavad\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "viga lugemisel: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "viga `%s' lugemisel: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -691,15 +629,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "viga salajase võtme võtmehoidlasse `%s' kirjutamisel: %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "viga `%s' lugemisel: %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "viga `%s' lugemisel: %s\n"
 
 #, fuzzy, c-format
@@ -714,7 +652,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent ei ole sesses sessioonis kasutatav\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "ei õnnestu luua ühendust serveriga `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -791,10 +729,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -821,22 +755,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "halb sertifikaat"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "halb sertifikaat"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "halb sertifikaat"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "halb sertifikaat"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "halb sertifikaat"
 
@@ -879,26 +797,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "vigane räsialgoritm `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Allkiri aegus %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "vigane räsialgoritm `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "kaitse algoritm %d%s ei ole toetatud\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "allkirja kontroll jäeti ära\n"
 
@@ -907,11 +809,11 @@ msgid "Signature available"
 msgstr "Allkiri aegus %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Korrektne allkiri kasutajalt \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "vigane räsialgoritm `%s'\n"
 
 #, fuzzy, c-format
@@ -956,7 +858,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "`%s' kohta abiinfo puudub"
 
 #, fuzzy
@@ -1130,11 +1032,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "viga võtmehoidla `%s' loomisel: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "viga `%s' lugemisel: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "viga võtmehoidlasse `%s' kirjutamisel: %s\n"
 
 msgid "Login data (account name): "
@@ -1336,8 +1238,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Käsklus> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1358,7 +1260,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "võti --output ei tööta selle käsuga\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "`%s' ei õnnestu avada\n"
 
 #, fuzzy, c-format
@@ -1410,11 +1312,11 @@ msgid "using cipher %s\n"
 msgstr "kasutan ¨iffrit %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' on juba pakitud\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "HOIATUS: `%s' on tühi fail\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1422,7 +1324,7 @@ msgstr ""
 "RSA võtmeid pikkusega kuni 2048 bitti saab krüpteerida ainult --pgp2 moodis\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "loen failist `%s'\n"
 
 msgid ""
@@ -1486,11 +1388,11 @@ msgstr ""
 "kasutamist\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "ei Õnnestu käivitada %s \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "ei Õnnestu käivitada %s \"%s\": %s\n"
 
 #, c-format
@@ -1508,11 +1410,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "ei õnnestu lugeda välise programmi vastust: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "HOIATUS: ei saa kustutada ajutist faili (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "HOIATUS: ei õnnestu eemaldada ajutist kataloogi `%s': %s\n"
 
 #, fuzzy
@@ -1581,16 +1483,12 @@ msgstr "avalike v
 msgid "[User ID not found]"
 msgstr "[Kasutaja id puudub]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "võti %08lX: salajane võti avaliku võtmeta - jätsin vahele\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "viga `%s' loomisel: %s\n"
 
 #, fuzzy
@@ -1611,6 +1509,10 @@ msgstr "avalikul alamv
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "kasutan sekundaarset võtit %08lX primaarse võtme %08lX asemel\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "võti %08lX: salajane võti avaliku võtmeta - jätsin vahele\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "loo eraldiseisev allkiri"
@@ -1653,9 +1555,6 @@ msgstr "n
 msgid "generate a new key pair"
 msgstr "genereeri uus võtmepaar"
 
-msgid "generate a revocation certificate"
-msgstr "genereeri tühistamise sertifikaat"
-
 msgid "remove keys from the public keyring"
 msgstr "eemalda võtmed avalike võtmete hoidlast"
 
@@ -1671,9 +1570,8 @@ msgstr "allkirjasta v
 msgid "sign or edit a key"
 msgstr "allkirjasta või toimeta võtit"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "muuda parooli"
+msgid "generate a revocation certificate"
+msgstr "genereeri tühistamise sertifikaat"
 
 msgid "export keys"
 msgstr "ekspordi võtmed"
@@ -1772,15 +1670,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Kasuta: gpg [võtmed] [failid] (-h näitab abiinfot)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Süntaks: gpg [võtmed] [failid]\n"
 "allkirjasta, kontrolli, krüpti ja dekrüpti\n"
@@ -1812,35 +1705,35 @@ msgid "conflicting commands\n"
 msgstr "vastuolulised käsud\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "grupi definitsioonis \"%s\" puudub sümbol =\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "HOIATUS: ebaturvaline omanik %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "HOIATUS: ebaturvaline omanik %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "HOIATUS: ebaturvaline omanik %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "HOIATUS: ebaturvalised õigused %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "HOIATUS: ebaturvalised õigused %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "HOIATUS: ebaturvalised õigused %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "HOIATUS: ebaturvaline kataloogi omanik %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1849,11 +1742,11 @@ msgid ""
 msgstr "HOIATUS: ebaturvaline kataloogi omanik %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "HOIATUS: ebaturvaline kataloogi omanik %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "Hoiatus: ebaturvalised kataloogi õigused %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1862,11 +1755,11 @@ msgid ""
 msgstr "Hoiatus: ebaturvalised kataloogi õigused %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "Hoiatus: ebaturvalised kataloogi õigused %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "tundmatu seade \"%s\"\n"
 
 msgid "display photo IDs during key listings"
@@ -1907,7 +1800,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Vastavat allkirja salajaste võtmete hoidlas pole\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "MÄRKUS: ignoreerin vana vaikimisi võtmete faili `%s'\n"
 
 #, c-format
@@ -1919,11 +1812,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "MÄRKUS: %s ei ole tavapäraseks kasutamiseks!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s ei ole lubatud kooditabel\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s ei ole lubatud kooditabel\n"
 
 #, fuzzy
@@ -2100,15 +1993,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s ei tööta veel koos %s-ga\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "¨ifri algoritm \"%s\" ei ole moodis %s lubatud\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "sõnumilühendi algoritm \"%s\" ei ole moodis %s lubatud\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "pakkimise algoritm \"%s\" ei ole moodis %s lubatud\n"
 
 #, c-format
@@ -2126,7 +2019,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [failinimi]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "lahtikrüpteerimine ebaõnnestus: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2178,10 +2071,6 @@ msgstr "--lsign-key kasutaja-id"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key kasutaja-id [käsud]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key kasutaja-id"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "võtmeserverile saatmine ebaõnnestus: %s\n"
@@ -2211,7 +2100,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "pakendamine ebaõnnestus: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "vigane räsialgoritm `%s'\n"
 
 msgid "[filename]"
@@ -2255,7 +2144,7 @@ msgid "No help available"
 msgstr "Abiinfo puudub"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "`%s' kohta abiinfo puudub"
 
 msgid "import signatures that are marked as local-only"
@@ -2265,10 +2154,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "uuenda usalduse andmebaasi"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "uuenda usalduse andmebaasi"
 
@@ -2387,13 +2272,6 @@ msgid "key %s: no user ID\n"
 msgstr "võti %08lX: kasutaja ID puudub\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "`%s' jätsin vahele: %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "võti %08lX: HKP alamvõtme rike parandatud\n"
 
@@ -2422,11 +2300,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "ei leia kirjutatavat võtmehoidlat: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "kirjutan faili `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "viga võtmehoidlasse `%s' kirjutamisel: %s\n"
 
 #, fuzzy, c-format
@@ -2490,17 +2368,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "võti %08lX: \"%s\" ei muudetud\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "salajast võtit `%s' ei leitud: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "võti %08lX: salajane võti vigase ¨ifriga %d - jätsin vahele\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "kirjutan salajase võtme faili `%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "võti %08lX: salajane võti vigase ¨ifriga %d - jätsin vahele\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "puudub salajaste võtmete vaikimisi võtmehoidla: %s\n"
@@ -2543,18 +2417,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "võti %08lX: kasutajal \"%s\" on vigane iseenda allkiri\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "võti %08lX: mittetoetatud avaliku võtme algoritm\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "võti %08lX: lisatud vahetu võtme allkiri\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "võti %08lX: võtmeseosel puudub alamvõti\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "võti %08lX: mittetoetatud avaliku võtme algoritm\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "võti %08lX: vigane alamvõtme seos\n"
 
@@ -2637,15 +2507,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "jätsin vahele: avalik võti on juba olemas\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "viga võtmehoidla `%s' loomisel: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "võtmehoidla `%s' on loodud\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "viga `%s' loomisel: %s\n"
 
 #, c-format
@@ -2834,7 +2704,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Ma olen kontrollinud väga hoolikalt.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Teie valik? (lisainfo saamiseks vajutage '?'): "
 
 #, fuzzy, c-format
@@ -3111,7 +2981,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Vihje: Valige allkirjastamiseks kasutaja\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "tundmatu allkirja klass"
 
 #, c-format
@@ -3146,11 +3016,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "`%s' ei õnnestu avada: %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "viga võtmehoidla `%s' loomisel: %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3238,7 +3108,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "PGP 2.x stiilis kasutaja ID ei oma seadeid.\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Selle võtme võib olla tühistanud %s võti "
 
 #, fuzzy, c-format
@@ -3305,14 +3175,6 @@ msgstr ""
 "HOIATUS: ühtegi kasutaja ID pole märgitud primaarseks.  See käsklus võib\n"
 "              põhjustada muu kasutaja ID primaarseks määramist.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "v3 võtme aegumise aega ei saa muuta.\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3540,7 +3402,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Näitan %s foto IDd suurusega %ld, võti 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "eelistus %c%lu on duplikaat\n"
 
 #, fuzzy
@@ -3556,7 +3418,7 @@ msgid "too many compression preferences\n"
 msgstr "liiga palju `%c' eelistusi\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "lubamatu sümbol eelistuste sõnes\n"
 
 msgid "writing direct signature\n"
@@ -3798,7 +3660,7 @@ msgid "Invalid character in comment\n"
 msgstr "Lubamatu sümbol kommentaaris\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Te kasutate kooditabelit `%s'.\n"
 
 #, c-format
@@ -3883,15 +3745,15 @@ msgid "Key generation canceled.\n"
 msgstr "Võtme genereerimine katkestati.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "kirjutan avaliku võtme faili `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "kirjutan salajase võtme faili `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "kirjutan salajase võtme faili `%s'\n"
 
 #, c-format
@@ -3903,11 +3765,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "kirjutatavat salajaste võtmete hoidlat pole: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "viga avaliku võtme võtmehoidlasse `%s' kirjutamisel: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "viga salajase võtme võtmehoidlasse `%s' kirjutamisel: %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3948,11 +3810,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "võtmebloki kustutamine ebaõnnestus: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "`%s' ei õnnestu luua: %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "MÄRKUS: salajane võti %08lX aegus %s\n"
 
 msgid "never     "
@@ -3994,15 +3856,11 @@ msgstr "     Alamv
 msgid "      Key fingerprint ="
 msgstr "     Võtme sõrmejälg ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "%s allkiri, sõnumilühendi algoritm %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "pakendamine ebaõnnestus: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4020,7 +3878,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Palun parandage see võimalik turvaprobleem\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "kontrollin võtmehoidlat `%s'\n"
 
 #, fuzzy, c-format
@@ -4058,7 +3916,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "HOIATUS: seaded failis `%s' pole seekord veel aktiivsed\n"
 
 #, fuzzy
@@ -4125,10 +3983,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "võtmeserverilt lugemine ebaõnnestus: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4136,11 +3990,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4155,6 +4009,10 @@ msgstr "v
 msgid "keyserver internal error\n"
 msgstr "võtmeserveri viga"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "võtmeserverilt lugemine ebaõnnestus: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4326,10 +4184,6 @@ msgid "unknown"
 msgstr "tundmatu"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Allkirja ei saa kontrollida: %s\n"
 
@@ -4351,7 +4205,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "proc_tree() tuvastas vigase juurmise paketi\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "faili ei õnnestu avada: %s\n"
 
 #, fuzzy, c-format
@@ -4380,11 +4234,6 @@ msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr ""
 "sõnumilühendi algoritmi %s (%d) kasutamine on vastuolus saaja eelistustega\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s allkiri, sõnumilühendi algoritm %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "IDEA ¨ifri lisandprogrammi pole\n"
 
@@ -4416,15 +4265,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "HOIATUS: võtit \"%s\" ei soovitata kasutada.\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "HOIATUS: võtit \"%s\" ei soovitata kasutada.\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "HOIATUS: võtit \"%s\" ei soovitata kasutada.\n"
-
 msgid "Uncompressed"
 msgstr "Pakkimata"
 
@@ -4438,15 +4278,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "see teade ei pruugi olla programmiga %s kasutatav\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "loen võtmeid failist `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "tundmatu vaikimisi saaja `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Fail `%s' on olemas. "
 
 #, fuzzy
@@ -4463,17 +4303,16 @@ msgstr "Sisestage uus failinimi"
 msgid "writing to stdout\n"
 msgstr "kirjutan standardväljundisse\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "eeldan allkirjastatud andmeid failis `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "uus omaduste fail `%s' on loodud\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "HOIATUS: seaded failis `%s' pole seekord veel aktiivsed\n"
 
 #, c-format
@@ -4490,10 +4329,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "alampaketil tüübiga %d on kriitiline bitt seatud\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "probleem agendiga: agent tagastas 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (peamise võtme ID %08lX)"
 
@@ -4516,6 +4351,10 @@ msgid "cancelled by user\n"
 msgstr "katkestatud kasutaja poolt\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "probleem agendiga: agent tagastas 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4549,7 +4388,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Sisestage foto ID jaoks JPEG faili nimi: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "faili ei õnnestu avada: %s\n"
 
 #, c-format
@@ -4561,7 +4400,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Olete kindel, et soovite seda kasutada (j/E)? "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\": ei ole JPEG fail\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4591,16 +4430,6 @@ msgstr "t
 msgid "revocation comment: "
 msgstr "tühistamise kommentaar: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iItTvVjJ"
 
@@ -4712,11 +4541,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Märkus: See võti on blokeeritud.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4818,7 +4647,7 @@ msgid "no signed data\n"
 msgstr "allkirjastatud andmeid pole\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "allkirjastatud andmete avamine ebaõnnestus `%s'\n"
 
 #, fuzzy, c-format
@@ -4980,8 +4809,8 @@ msgstr "loodi n
 #, c-format
 msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
 msgstr ""
-"sümmeetrilises ¨ifris ei õnnestu vältida nõrga võtme kasutamist; proovisin "
-"%d korda!\n"
+"sümmeetrilises ¨ifris ei õnnestu vältida nõrga võtme kasutamist; proovisin %"
+"d korda!\n"
 
 msgid "DSA requires the hash length to be a multiple of 8 bits\n"
 msgstr ""
@@ -5127,7 +4956,7 @@ msgstr ""
 "# (Taastamiseks kasutage \"gpg --import-ownertrust\")\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "viga `%s' lugemisel: %s\n"
 
 #, fuzzy
@@ -5146,25 +4975,17 @@ msgid "ownertrust value missing"
 msgstr "impordi usalduse väärtused"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "viga usalduse kirje otsimisel: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "viga lugemisel: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "trustdb: sync ebaõnnestus: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "`%s' ei õnnestu luua: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "`%s' ei õnnestu avada\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb kirje %lu: lseek ebaõnnestus: %s\n"
@@ -5176,13 +4997,21 @@ msgstr "trustdb rec %lu: write failed (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "trustdb transaktsioon on liiga suur\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "`%s' ei õnnestu sulgeda: %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: kataloogi ei ole!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "`%s' ei õnnestu sulgeda: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "`%s' ei õnnestu luua: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "`%s' ei õnnestu avada\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5268,7 +5097,7 @@ msgid "input line longer than %d characters\n"
 msgstr "sisendrida on pikem, kui %d sümbolit\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' ei ole kehtiv pikk võtmeID\n"
 
 #, fuzzy, c-format
@@ -5309,14 +5138,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5368,11 +5189,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "trustdb järgmine kontroll %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "trustdb kontrolliks puudub vajadus\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "trustdb kontrolliks puudub vajadus\n"
 
 #, fuzzy, c-format
@@ -5443,11 +5264,6 @@ msgid "missing argument"
 msgstr "vigane argument"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "vigane pakend"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "vastuolulised käsud\n"
 
@@ -5467,10 +5283,6 @@ msgstr "vigased impordi v
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "vigased impordi võtmed\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5499,8 +5311,12 @@ msgstr "vigased impordi v
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "te leidsite vea ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "viga `%s' lugemisel: %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5508,15 +5324,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "faili ei õnnestu avada: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "pakendamine ebaõnnestus: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "kataloogi `%s' ei õnnestu luua: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "viga võtmehoidlasse `%s' kirjutamisel: %s\n"
 
 #, c-format
@@ -5534,7 +5350,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "ei leia avalikku võtit %08lX: %s\n"
 
 #, fuzzy, c-format
@@ -5551,11 +5367,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Kasuta: gpg [võtmed] [failid] (-h näitab abiinfot)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Kasuta: gpg [võtmed] [failid] (-h näitab abiinfot)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5684,9 +5499,6 @@ msgstr "Palun valige t
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5697,14 +5509,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "muuda parooli"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "muuda parooli"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "viga võtmebloki lugemisel: %s\n"
 
@@ -5771,9 +5575,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "ei leia OpenPGP andmeid.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "muuda parooli"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5809,16 +5612,13 @@ msgstr "
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "vastuolulised käsud\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Kasuta: gpg [võtmed] [failid] (-h näitab abiinfot)"
@@ -5828,7 +5628,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5848,7 +5648,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5884,7 +5684,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "`%s' ei õnnestu avada: %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5913,7 +5713,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "võtmebloki kustutamine ebaõnnestus: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "TrustDB initsialiseerimine ebaõnnestus: %s\n"
 
 #, fuzzy
@@ -6102,16 +5902,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "viga salajase võtme võtmehoidlasse `%s' kirjutamisel: %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6133,11 +5933,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6145,11 +5945,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Selline e-posti aadress ei ole lubatud\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "viga võtmehoidla `%s' loomisel: %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "viga võtmehoidla `%s' loomisel: %s\n"
 
 #, fuzzy, c-format
@@ -6220,7 +6020,7 @@ msgid "No subject name given\n"
 msgstr "(Kirjeldust ei antud)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6229,7 +6029,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "vigane räsialgoritm `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6275,7 +6075,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "võtit '%s' ei leitud: %s\n"
 
 #, fuzzy, c-format
@@ -6283,11 +6083,11 @@ msgid "error locking keybox: %s\n"
 msgstr "viga võtmebloki lugemisel: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Tühistamise sertifikaat on loodud.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "eelistus %c%lu on duplikaat\n"
 
 #, fuzzy, c-format
@@ -6324,6 +6124,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "muuda parooli"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "loo ascii pakendis väljund"
 
@@ -6401,8 +6205,8 @@ msgstr "Kasuta: gpg [v
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Süntaks: gpg [võtmed] [failid]\n"
 "allkirjasta, kontrolli, krüpti ja dekrüpti\n"
@@ -6413,11 +6217,11 @@ msgid "usage: gpgsm [options] "
 msgstr "kasuta: gpg [võtmed] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "ei õnnestu luua ühendust serveriga `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "tundmatu vaikimisi saaja `%s'\n"
 
 #, fuzzy, c-format
@@ -6440,11 +6244,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "kirjutan faili `%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "`%s' ei õnnestu sulgeda: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6461,6 +6265,10 @@ msgstr "genereeri t
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "TrustDB initsialiseerimine ebaõnnestus: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "viga parooli loomisel: %s\n"
@@ -6474,11 +6282,14 @@ msgid "error reading input: %s\n"
 msgstr "viga `%s' lugemisel: %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "viga võtmehoidla `%s' loomisel: %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "võtmehoidla `%s' on loodud\n"
 
 #, fuzzy
@@ -6512,11 +6323,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "viga: vigane sõrmejälg\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6637,7 +6448,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "tundmatu vaikimisi saaja `%s'\n"
 
 #, fuzzy, c-format
@@ -6868,7 +6679,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "faili ei õnnestu avada: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "kataloogi `%s' ei õnnestu luua: %s\n"
 
 #, fuzzy, c-format
@@ -6964,17 +6775,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "viga `%s' lugemisel: %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "TrustDB initsialiseerimine ebaõnnestus: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Käsklus> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "trustdb on vigane; palun käivitage \"gpg --fix-trustdb\".\n"
 
@@ -7489,6 +7289,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "vigane pakett"
 
+#~ msgid "invalid armor"
+#~ msgstr "vigane pakend"
+
 #~ msgid "no such user id"
 #~ msgstr "sellist kasutaja id pole"
 
@@ -7498,6 +7301,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "kasutati valet salajast võtit"
 
+#~ msgid "not supported"
+#~ msgstr "ei ole toetatud"
+
 #~ msgid "bad key"
 #~ msgstr "halb võti"
 
@@ -7513,6 +7319,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "viga faili loomisel"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "vigane parool"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "realiseerimata avaliku võtme algoritm"
 
@@ -8155,8 +7964,8 @@ msgstr ""
 
 #~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"
 #~ msgstr ""
-#~ "kontrollin sügavusel %d allkirjastatud=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/"
-#~ "%d\n"
+#~ "kontrollin sügavusel %d allkirjastatud=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%"
+#~ "d\n"
 
 #~ msgid ""
 #~ "Select the algorithm to use.\n"
index d3f5d42..b0d9b61 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -25,7 +25,6 @@ msgstr ""
 "PO-Revision-Date: 2004-06-16 22:40+0300\n"
 "Last-Translator: Tommi Vainikainen <Tommi.Vainikainen@iki.fi>\n"
 "Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
-"Language: fi\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -34,41 +33,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "TrustDB:n alustaminen ei onnistu: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Haluatko varmasti mitätöidä valitut avaimet? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "väärä salasana"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -94,9 +58,6 @@ msgid ""
 "this session"
 msgstr "Ole hyvä ja syötä salasana, tämän on salainen lause \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -133,11 +94,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "suojausalgoritmi %d%s ei ole käytettävissä\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "tiedostoa \"%s\" ei voi luoda: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "tiedostoa \"%s\" ei voi avata: %s\n"
 
 #, fuzzy, c-format
@@ -164,31 +125,19 @@ msgstr "avainlohkojen poisto epäonnistui: %s\n"
 msgid "error writing key: %s\n"
 msgstr "virhe kirjoitettaessa avainrenkaaseen \"%s\": %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Ole hyvä ja syötä salasana, tämän on salainen lause \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "muuta salasanaa"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Ole hyvä ja syötä salasana, tämän on salainen lause \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -215,7 +164,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -303,7 +252,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Tarvitset salasanan suojaamaan salaista avaintasi.\n"
 "\n"
@@ -321,10 +270,10 @@ msgstr ""
 "Valitsimet:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -379,26 +328,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "virhe luotaessa salasanaa: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "ei tuettu"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "ei tuettu"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "virhe luotaessa salasanaa: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -421,7 +359,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -429,23 +367,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "HUOM: Ei oletusasetustiedostoa \"%s\"\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "asetustiedosto \"%s\": %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "luetaan asetukset tiedostosta \"%s\"\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "virhe luotaessa \"%s\": %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "hakemiston \"%s\" luominen ei onnistu: %s\n"
 
 msgid "name of socket too long\n"
@@ -456,7 +394,7 @@ msgid "can't create socket: %s\n"
 msgstr "ei voida luoda kohdetta %s: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -468,7 +406,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "virhe luotaessa salasanaa: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "virhe lähettäessä kohteeseen \"%s\": %s\n"
 
 #, fuzzy, c-format
@@ -476,19 +414,19 @@ msgid "listen() failed: %s\n"
 msgstr "päivitys epäonnistui: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "kirjoitan salaisen avaimen kohteeseen \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: hakemisto luotu\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "trustdb: luku epäonnistui (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: hakemistoa ei voi luoda: %s\n"
 
 #, fuzzy, c-format
@@ -596,31 +534,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "virhe luotaessa salasanaa: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "avainta \"%s\" ei löydy: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "salaisen avaimen osat eivät ole käytettävissä\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "lukuvirhe: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -708,15 +646,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "virhe kirjoitettaessa salaiseen avainrenkaaseen \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
 
 #, fuzzy, c-format
@@ -731,7 +669,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent ei ole käytettävissä tässä istunnossa\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "yhteys kohteeseen \"%s\" ei onnistu: %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -808,10 +746,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -838,22 +772,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "virheellinen varmenne"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "virheellinen varmenne"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "virheellinen varmenne"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "virheellinen varmenne"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "virheellinen varmenne"
 
@@ -896,26 +814,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "virheellinen tiivistealgoritmi \"%s\"\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Allekirjoitus vanheni %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "virheellinen tiivistealgoritmi \"%s\"\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "suojausalgoritmi %d%s ei ole käytettävissä\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "allekirjoituksen varmistus vaiennetaan\n"
 
@@ -924,11 +826,11 @@ msgid "Signature available"
 msgstr "Allekirjoitus vanheni %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Allekirjoitus täsmää lähettäjään \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "virheellinen tiivistealgoritmi \"%s\"\n"
 
 #, fuzzy, c-format
@@ -973,7 +875,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Ei ohjetta aiheesta \"%s\""
 
 #, fuzzy
@@ -1149,11 +1051,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "virhe kirjoitettaessa avainrenkaaseen \"%s\": %s\n"
 
 msgid "Login data (account name): "
@@ -1355,8 +1257,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Komento> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1377,7 +1279,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output ei toimi yhdessä tämän komennon kanssa\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "tiedostoa \"%s\" ei voi avata\n"
 
 #, fuzzy, c-format
@@ -1429,11 +1331,11 @@ msgid "using cipher %s\n"
 msgstr "käytetään salakirjoitusalgoritmia %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "\"%s\" on jo pakattu\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "VAROITUS: \"%s\" on tyhjä tiedosto\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1441,7 +1343,7 @@ msgstr ""
 "--pgp2-tilassa voidaan salata korkeintaan 2048-bittisillä RSA-avaimilla\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "luetaan kohteesta \"%s\"\n"
 
 msgid ""
@@ -1503,11 +1405,11 @@ msgstr ""
 "tämä ympäristö vaatii väliaikaistiedoston kutsuttaessa ulkoisia ohjelmia\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "komentoa %s \"%s\" ei voi suorittaa: %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "komentoa %s \"%s\" ei voi suorittaa: %s\n"
 
 #, c-format
@@ -1525,11 +1427,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "ulkoisen ohjelman vastausta ei voi lukea: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "VAROITUS: tilapäistiedostoa (%s) \"%s\" ei voi poistaa: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "VAROITUS: väliaikaishakemistoa \"%s\" ei voi poistaa: %s\n"
 
 #, fuzzy
@@ -1598,18 +1500,12 @@ msgstr "pk-välimuistissa on liian monta kohdetta - poistettu käytöstä\n"
 msgid "[User ID not found]"
 msgstr "[Käyttäjätunnusta ei löytynyt]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr ""
-"avain %08lX: salaisella avaimella ei ole vastaavaa \n"
-"julkista avainta - ohitetaan\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "virhe luotaessa \"%s\": %s\n"
 
 #, fuzzy
@@ -1630,6 +1526,12 @@ msgid "using subkey %s instead of primary key %s\n"
 msgstr ""
 "käytetään toissijaista avainta %08lX ensisijaisen avaimen %08lX sijasta\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr ""
+"avain %08lX: salaisella avaimella ei ole vastaavaa \n"
+"julkista avainta - ohitetaan\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "tee erillinen allekirjoitus"
@@ -1672,9 +1574,6 @@ msgstr "näytä salaiset avaimet"
 msgid "generate a new key pair"
 msgstr "luo uusi avainpari"
 
-msgid "generate a revocation certificate"
-msgstr "luo mitätöintivarmenne"
-
 msgid "remove keys from the public keyring"
 msgstr "poista avaimet julkisten avainten renkaasta"
 
@@ -1690,9 +1589,8 @@ msgstr "allekirjoita avain paikallisesti"
 msgid "sign or edit a key"
 msgstr "allekirjoita tai muokkaa avainta"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "muuta salasanaa"
+msgid "generate a revocation certificate"
+msgstr "luo mitätöintivarmenne"
 
 msgid "export keys"
 msgstr "vie avaimia"
@@ -1791,15 +1689,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Käyttö: gpg [valitsimet] [tiedostot] (-h näyttää ohjeen)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Syntaksi: gpg [valitsimet] [tiedostot]\n"
 "allekirjoita, tarkista, salaa tai avaa\n"
@@ -1831,35 +1724,35 @@ msgid "conflicting commands\n"
 msgstr "ristiriitainen komento\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "=-merkkiä ei löytynyt ryhmämäärityksessä \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "VAROITUS: omistussuhde kohteessa %s \"%s\" ei ole turvallinen\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "VAROITUS: omistussuhde kohteessa %s \"%s\" ei ole turvallinen\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "VAROITUS: omistussuhde kohteessa %s \"%s\" ei ole turvallinen\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "VAROITUS: oikeudet kohteessa %s \"%s\" eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "VAROITUS: oikeudet kohteessa %s \"%s\" eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "VAROITUS: oikeudet kohteessa %s \"%s\" eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "VAROITUS: %s \"%s\" hakemiston oikeudet eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
@@ -1868,11 +1761,11 @@ msgid ""
 msgstr "VAROITUS: %s \"%s\" hakemiston oikeudet eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "VAROITUS: %s \"%s\" hakemiston oikeudet eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "VAROITUS: Hakemiston %s \"%s\" oikeudet eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
@@ -1881,11 +1774,11 @@ msgid ""
 msgstr "VAROITUS: Hakemiston %s \"%s\" oikeudet eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "VAROITUS: Hakemiston %s \"%s\" oikeudet eivät ole turvallisia\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "tuntematon asetus \"%s\"\n"
 
 msgid "display photo IDs during key listings"
@@ -1926,7 +1819,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Salaisesta avainrenkaasta ei löydy vastaavaa allekirjoitusta\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "HUOM: Vanhat oletusarvoiset asetukset löytyvät tiedostosta \"%s\"\n"
 
 #, c-format
@@ -1938,11 +1831,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "HUOM: %s ei ole normaaliin käyttöön!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s ei kelpaa merkistöksi\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s ei kelpaa merkistöksi\n"
 
 #, fuzzy
@@ -2120,15 +2013,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s ja %s eivät vielä toimi yhdessä\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "salausalgoritmia \"%s\" ei voi käyttää %s-tilassa\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "tiivistealgoritmia \"%s\" ei voi käyttää %s-tilassa\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "pakkausalgoritmia \"%s\" ei voi käyttää %s-tilassa\n"
 
 #, c-format
@@ -2146,7 +2039,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [tiedostonimi]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "avaus epäonnistui: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2198,10 +2091,6 @@ msgstr "--lsign-key käyttäjätunnus"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key käyttäjätunnus [komennot]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key käyttäjätunnus"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "avainpalvelimelle lähettäminen epäonnistui: %s\n"
@@ -2231,7 +2120,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "ascii-koodaaminen epäonnistui: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "virheellinen tiivistealgoritmi \"%s\"\n"
 
 msgid "[filename]"
@@ -2275,7 +2164,7 @@ msgid "No help available"
 msgstr "Ei ohjeita saatavilla"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Ei ohjetta aiheesta \"%s\""
 
 msgid "import signatures that are marked as local-only"
@@ -2285,10 +2174,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "päivitä luottamustietokanta"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "päivitä luottamustietokanta"
 
@@ -2408,13 +2293,6 @@ msgid "key %s: no user ID\n"
 msgstr "avain %08lX: ei käyttäjätunnusta\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "ohitetaan \"%s\": %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "avain %08lX: HKP-aliavainvirhe korjattu\n"
 
@@ -2443,11 +2321,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "kirjoitettavissa olevaa avainrengasta ei löydy: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "kirjoitetaan kohteeseen \"%s\"\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "virhe kirjoitettaessa avainrenkaaseen \"%s\": %s\n"
 
 #, fuzzy, c-format
@@ -2511,17 +2389,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "avain %08lX: \"%s\" ei muutoksia\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "salaista avainta \"%s\" ei löydy: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "avain %08lX: avaimella on epäkelpo salain %d - ohitetaan\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "kirjoitan salaisen avaimen kohteeseen \"%s\"\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "avain %08lX: avaimella on epäkelpo salain %d - ohitetaan\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "salaiselle avainrenkaalle ei ole asetettu oletusarvoa: %s\n"
@@ -2564,18 +2438,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "avain %08lX: epäkelpo oma-allekirjoitus käyttäjätunnuksella \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "avain %08lX: julkisen avaimen algoritmia ei tueta\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "avain %08lX: lisättiin suora avainallekirjoitus\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "avain %08lX: ei aliavainta avainten riippuvuuksiin\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "avain %08lX: julkisen avaimen algoritmia ei tueta\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "avain %08lX: pätemätön aliavainriippuvuus\n"
 
@@ -2660,15 +2530,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "ohitetaan: salainen avain on jo paikalla\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "avainrengas \"%s\" luotu\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "virhe luotaessa \"%s\": %s\n"
 
 #, c-format
@@ -2860,7 +2730,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Olen suorittanut huolellisen tarkistuksen.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Valintasi? (syöttämällä \"?\" saat lisätietoja): "
 
 #, fuzzy, c-format
@@ -3137,7 +3007,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Vihje: Valitse allekirjoitettavat käyttäjätunnukset\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "tuntematon allekirjoitusluokka"
 
 #, c-format
@@ -3172,11 +3042,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "tiedostoa \"%s\" ei voi avata: %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3264,7 +3134,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "PGP 2.x -muodon käyttäjätunnukselle ei ole valintoja.\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Tämä avain voidaan mitätöidä %s-avaimella "
 
 #, fuzzy, c-format
@@ -3331,14 +3201,6 @@ msgstr ""
 "VAROITUS: mitään käyttäjätunnusta ei ole merkitty ensisijaiseksi.  Tämän \n"
 "komennon johdosta eri käyttäjätunnus voi tulla oletetuksi ensisijaiseksi.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Et voi muuttaa v3-avainten vanhentumispäivää\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3571,7 +3433,7 @@ msgstr ""
 "(käyttäjätunnus %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "valinta %c%lu on kopio\n"
 
 #, fuzzy
@@ -3587,7 +3449,7 @@ msgid "too many compression preferences\n"
 msgstr "liian monta \"%c\" valintaa\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "Valinnassa on luvaton merkki\n"
 
 msgid "writing direct signature\n"
@@ -3831,7 +3693,7 @@ msgid "Invalid character in comment\n"
 msgstr "Huomautuksessa on epäkelpo merkki\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Käytät merkistöä \"%s\".\n"
 
 #, c-format
@@ -3916,15 +3778,15 @@ msgid "Key generation canceled.\n"
 msgstr "Avaimen luonti keskeytetty.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "kirjoitan julkisen avaimen kohteeseen \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "kirjoitan salaisen avaimen kohteeseen \"%s\"\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "kirjoitan salaisen avaimen kohteeseen \"%s\"\n"
 
 #, c-format
@@ -3936,11 +3798,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "kirjoitettavissa olevaa salaista avainrengasta ei löydy: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "virhe kirjoitettaessa julkiseen avainrenkaaseen \"%s\": %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "virhe kirjoitettaessa salaiseen avainrenkaaseen \"%s\": %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3984,11 +3846,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "avainlohkojen poisto epäonnistui: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "tiedostoa \"%s\" ei voi luoda: %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "HUOM: salainen avain %08lX vanheni %s\n"
 
 msgid "never     "
@@ -4030,16 +3892,11 @@ msgstr "      Aliavaimen sormenjälki:"
 msgid "      Key fingerprint ="
 msgstr "     Avaimen sormenjälki ="
 
-# Ensimmäinen %s on binary, textmode tai unknown, ks. alla
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "%sallekirjoitus, tiivistealgoritmi %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "ascii-koodaaminen epäonnistui: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4057,7 +3914,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Ole hyvä ja korjaa tämä mahdollinen tietoturvareikä\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "tarkistetaan avainrengasta \"%s\"\n"
 
 #, fuzzy, c-format
@@ -4095,7 +3952,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "VAROITUS: asetukset tiedostossa \"%s\" eivät ole käytössä vielä tässä "
 "ajossa\n"
@@ -4164,10 +4021,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "avainpalvelimelta vastaanotto epäonnistui: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4175,11 +4028,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4194,6 +4047,10 @@ msgstr "avainpalvelinvirhe"
 msgid "keyserver internal error\n"
 msgstr "avainpalvelinvirhe"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "avainpalvelimelta vastaanotto epäonnistui: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4369,10 +4226,6 @@ msgid "unknown"
 msgstr "tuntematon "
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Allekirjoitusta ei voi tarkistaa: %s\n"
 
@@ -4396,7 +4249,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "epäkelpo juuripaketti havaittu proc_tree():ssä\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "ei voi avata tiedostoa: %s\n"
 
 #, fuzzy, c-format
@@ -4426,12 +4279,6 @@ msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr ""
 "valittua tiivistesalgoritmia %s (%d) ei löydy vastaanottajan valinnoista\n"
 
-# Ensimmäinen %s on binary, textmode tai unknown, ks. alla
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%sallekirjoitus, tiivistealgoritmi %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "IDEA-salaimen liitännäinen ei käytettävissä\n"
 
@@ -4463,15 +4310,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "VAROITUS: \"%s\" on paheksuttu valitsin\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "VAROITUS: \"%s\" on paheksuttu valitsin\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "VAROITUS: \"%s\" on paheksuttu valitsin\n"
-
 msgid "Uncompressed"
 msgstr "pakkaamaton"
 
@@ -4485,15 +4323,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "%s ei kenties voi käsitellä tätä viestiä\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "luetaan asetukset tiedostosta \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "tuntematon oletusvastaanottaja \"%s\"\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Tiedosto \"%s\" on olemassa."
 
 #, fuzzy
@@ -4510,17 +4348,16 @@ msgstr "Syötä uusi tiedostonimi"
 msgid "writing to stdout\n"
 msgstr "kirjoitetaan vakiotulosteeseen\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "data kohteessa \"%s\" oletetaan allekirjoitetuksi\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "uusi asetustiedosto \"%s\" luotu\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "VAROITUS: asetukset tiedostossa \"%s\" eivät ole käytössä vielä tässä "
 "ajossa\n"
@@ -4537,10 +4374,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "tyypin %d alipaketilla on kriittinen bitti asetettuna\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "agentin käytössä on ongelmia: agentti vastaa 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (pääavaimen tunnus %08lX)"
 
@@ -4563,6 +4396,10 @@ msgid "cancelled by user\n"
 msgstr "käyttäjän peruma\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "agentin käytössä on ongelmia: agentti vastaa 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4596,7 +4433,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Syötä JPEG-tiedostonimi valokuvatunnisteelle: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "ei voi avata tiedostoa: %s\n"
 
 #, c-format
@@ -4608,7 +4445,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Haluatko varmasti käyttää sitä (k/E)? "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\" ei ole JPEG-tiedosto\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4638,16 +4475,6 @@ msgstr "mitätöinnin syy: "
 msgid "revocation comment: "
 msgstr "mitätöintikommentti: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMlLoO"
 
@@ -4765,11 +4592,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Huom: Tämä avain on poistettu käytöstä\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4875,7 +4702,7 @@ msgid "no signed data\n"
 msgstr "ei allekirjoitettua dataa\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "allekirjoitetun datan \"%s\" avaaminen ei onnistu\n"
 
 #, fuzzy, c-format
@@ -5191,7 +5018,7 @@ msgstr ""
 "# (Käytä \"gpg --import-ownertrust\" palauttaaksesi ne)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
 
 #, fuzzy
@@ -5210,25 +5037,17 @@ msgid "ownertrust value missing"
 msgstr "tuo luottamusasteet"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "virhe etsittäessä luottamustietuetta: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "lukuvirhe: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "trustdb: synkronointi epäonnistui: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "tiedostoa \"%s\" ei voi luoda: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "tiedostoa \"%s\" ei voi avata\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb rec %lu: lseek epäonnistui: %s\n"
@@ -5240,13 +5059,21 @@ msgstr "trustdb rec %lu: kirjoittaminen epäonnistuin (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "trustdb-tapahtuma on liian suuri\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: hakemistoa ei ole olemassa!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "tiedostoa \"%s\" ei voi luoda: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "tiedostoa \"%s\" ei voi avata\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5332,7 +5159,7 @@ msgid "input line longer than %d characters\n"
 msgstr "syöterivi on yli %d merkkiä pitkä\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "\"%s\" ei kelpaa pitkänä avaintunnuksena\n"
 
 #, fuzzy, c-format
@@ -5374,14 +5201,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5433,11 +5252,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "seuraava trustdb tarkistus %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "trustdb:n tarkistusta ei tarvita\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "trustdb:n tarkistusta ei tarvita\n"
 
 #, fuzzy, c-format
@@ -5508,11 +5327,6 @@ msgid "missing argument"
 msgstr "virheellinen argumentti"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "virheellinen ascii-koodaus"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "ristiriitainen komento\n"
 
@@ -5532,10 +5346,6 @@ msgstr "virheelliset tuontivalitsimet\n"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "virheelliset tuontivalitsimet\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5564,8 +5374,12 @@ msgstr "virheelliset tuontivalitsimet\n"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "olet löytänyt ohjelmistovian ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5573,15 +5387,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "ei voi avata tiedostoa: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "ascii-koodaaminen epäonnistui: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "hakemiston \"%s\" luominen ei onnistu: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "virhe kirjoitettaessa avainrenkaaseen \"%s\": %s\n"
 
 #, c-format
@@ -5599,7 +5413,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "julkista avainta %08lX ei löydy: %s\n"
 
 #, fuzzy, c-format
@@ -5616,11 +5430,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Käyttö: gpg [valitsimet] [tiedostot] (-h näyttää ohjeen)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Käyttö: gpg [valitsimet] [tiedostot] (-h näyttää ohjeen)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5749,9 +5562,6 @@ msgstr "Valitse mitätöinnin syy:\n"
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5762,14 +5572,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "muuta salasanaa"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "muuta salasanaa"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "virhe luettaessa avainlohkoa: %s\n"
 
@@ -5837,9 +5639,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "kelvollista OpenPGP-dataa ei löytynyt.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "muuta salasanaa"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5875,16 +5676,13 @@ msgstr "älä käytä lainkaan päätettä"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "ristiriitainen komento\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Käyttö: gpg [valitsimet] [tiedostot] (-h näyttää ohjeen)"
@@ -5894,7 +5692,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5914,7 +5712,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5950,7 +5748,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "tiedostoa \"%s\" ei voi avata: %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5979,7 +5777,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "avainlohkojen poisto epäonnistui: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "TrustDB:n alustaminen ei onnistu: %s\n"
 
 #, fuzzy
@@ -6168,16 +5966,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "virhe kirjoitettaessa salaiseen avainrenkaaseen \"%s\": %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6199,11 +5997,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6211,11 +6009,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Sähköpostiosoite ei kelpaa\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
 
 #, fuzzy, c-format
@@ -6286,7 +6084,7 @@ msgid "No subject name given\n"
 msgstr "(Kuvausta ei annettu)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6295,7 +6093,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "virheellinen tiivistealgoritmi \"%s\"\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6341,7 +6139,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "avainta \"%s\" ei löydy: %s\n"
 
 #, fuzzy, c-format
@@ -6349,11 +6147,11 @@ msgid "error locking keybox: %s\n"
 msgstr "virhe luettaessa avainlohkoa: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Mitätöintivarmenne luotu.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "valinta %c%lu on kopio\n"
 
 #, fuzzy, c-format
@@ -6390,6 +6188,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "muuta salasanaa"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "tuota ascii-koodattu tuloste"
 
@@ -6467,8 +6269,8 @@ msgstr "Käyttö: gpg [valitsimet] [tiedostot] (-h näyttää ohjeen)"
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Syntaksi: gpg [valitsimet] [tiedostot]\n"
 "allekirjoita, tarkista, salaa tai avaa\n"
@@ -6479,11 +6281,11 @@ msgid "usage: gpgsm [options] "
 msgstr "käyttö: gpg [valitsimet] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "yhteys kohteeseen \"%s\" ei onnistu: %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "tuntematon oletusvastaanottaja \"%s\"\n"
 
 #, fuzzy, c-format
@@ -6506,11 +6308,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "kirjoitetaan kohteeseen \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6527,6 +6329,10 @@ msgstr "luo mitätöintivarmenne"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "TrustDB:n alustaminen ei onnistu: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "virhe luotaessa salasanaa: %s\n"
@@ -6540,11 +6346,14 @@ msgid "error reading input: %s\n"
 msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "avainrengas \"%s\" luotu\n"
 
 #, fuzzy
@@ -6578,11 +6387,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "virhe: sormenjälki on väärä\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6703,7 +6512,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "tuntematon oletusvastaanottaja \"%s\"\n"
 
 #, fuzzy, c-format
@@ -6934,7 +6743,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "ei voi avata tiedostoa: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "hakemiston \"%s\" luominen ei onnistu: %s\n"
 
 #, fuzzy, c-format
@@ -7030,17 +6839,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "TrustDB:n alustaminen ei onnistu: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Komento> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "trustdb on turmeltunut; suorita \"gpg --fix-trustdb\"\n"
 
@@ -7576,6 +7374,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "virheellinen paketti"
 
+#~ msgid "invalid armor"
+#~ msgstr "virheellinen ascii-koodaus"
+
 #~ msgid "no such user id"
 #~ msgstr "käyttäjätunnusta ei löydy"
 
@@ -7585,6 +7386,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "käytetty salainen avain on väärä"
 
+#~ msgid "not supported"
+#~ msgstr "ei tuettu"
+
 #~ msgid "bad key"
 #~ msgstr "avain ei kelpaa"
 
@@ -7600,6 +7404,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "virhe tiedostoa luotaessa"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "väärä salasana"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "julkisen avaimen algoritmi ei ole käytössä"
 
@@ -8255,8 +8062,8 @@ msgstr ""
 
 #~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"
 #~ msgstr ""
-#~ "tarkistetaan syvyyteen %d allekirjoitettu=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/"
-#~ "%d/%d\n"
+#~ "tarkistetaan syvyyteen %d allekirjoitettu=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%"
+#~ "d/%d\n"
 
 #~ msgid ""
 #~ "Select the algorithm to use.\n"
index 88ac4ac..abec34a 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -5,9 +5,9 @@
 # David Prévot <david@tilapin.org>, 2012, 2014.
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg 2.0.26\n"
+"Project-Id-Version: gnupg 2.1\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2014-11-01 19:43-0400\n"
+"PO-Revision-Date: 2014-11-01 19:04-0400\n"
 "Last-Translator: David Prévot <david@tilapin.org>\n"
 "Language-Team: French <traduc@traduc.org>\n"
 "Language: fr\n"
@@ -32,37 +32,9 @@ msgstr "|pinentry-label|_OK"
 msgid "|pinentry-label|_Cancel"
 msgstr "|pinentry-label|_Annuler"
 
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_OK"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_OK"
-
 msgid "|pinentry-label|PIN:"
 msgstr "|pinentry-label|Code personnel :"
 
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|_Annuler"
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Voulez-vous vraiment révoquer les sous-clefs sélectionnées ? (o/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "phrase de passe incorrecte"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -93,6 +65,9 @@ msgstr ""
 "Veuillez entrer votre phrase secrète, afin de débloquer la clef secrète "
 "pendant cette session"
 
+msgid "does not match - try again"
+msgstr "ne correspond pas — veuillez réessayer"
+
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
@@ -100,6 +75,9 @@ msgstr ""
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (essai %d sur %d)"
 
+msgid "Repeat:"
+msgstr "Répéter :"
+
 msgid "PIN too long"
 msgstr "Code personnel trop long"
 
@@ -126,11 +104,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "les clefs SSH plus grandes que %d bits ne sont pas prises en charge\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "impossible de créer « %s » : %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "impossible d'ouvrir « %s » : %s\n"
 
 #, c-format
@@ -142,10 +120,8 @@ msgid "detected card with S/N: %s\n"
 msgstr "carte détectée avec le numéro de série : %s\n"
 
 #, c-format
-msgid "error getting default authentication keyID of card: %s\n"
-msgstr ""
-"erreur de lecture de l'identifiant de clef d'authentification par défaut de "
-"la carte : %s\n"
+msgid "no authentication key for ssh on card: %s\n"
+msgstr "aucune clef d'authentification pour SSH sur la carte : %s\n"
 
 #, c-format
 msgid "no suitable card key found: %s\n"
@@ -188,9 +164,6 @@ msgstr ""
 "Veuillez entrer une phrase secrète pour protéger la clef secrète%%0A   %s"
 "%%0A   %s%%0Areçue dans l'espace de stockage de clefs de gpg-agent"
 
-msgid "does not match - try again"
-msgstr "ne correspond pas — veuillez réessayer"
-
 #, c-format
 msgid "failed to create stream from socket: %s\n"
 msgstr "échec de création du flux à partir de cette socket : %s\n"
@@ -256,43 +229,6 @@ msgstr "La prendre quand même"
 
 #, c-format
 msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u character long."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u characters long."
-msgstr[0] ""
-"Avertissement : une phrase secrète non sécurisée a été entrée.%%0AUne phrase "
-"secrète devrait contenir au moins %u caractère."
-msgstr[1] ""
-"Avertissement : une phrase secrète sécurisée a été entrée.%%0AUne phrase "
-"secrète devrait contenir au moins %u caractères."
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digit or%%0Aspecial character."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digits or%%0Aspecial characters."
-msgstr[0] ""
-"Avertissement : une phrase secrète non sécurisée a été entrée.%%0AUne phrase "
-"secrète devrait contenir au moins %u chiffre%%0Aou caractère spécial."
-msgstr[1] ""
-"Avertissement : une phrase secrète non sécurisée a été entrée.%%0AUne phrase "
-"secrète devrait contenir au moins %u chiffres%%0Aou caractères spéciaux."
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
-"a known term or match%%0Acertain pattern."
-msgstr ""
-"Avertissement : une phrase secrète non sécurisée a été entrée.%%0AUne phrase "
-"secrète ne devrait ni être un mot commun,%%0Ani correspondre à un certain "
-"schéma."
-
-#, c-format
-msgid ""
 "You have not entered a passphrase!%0AAn empty passphrase is not allowed."
 msgstr ""
 "Aucune phrase secrète n'a été entrée.%0AUne phrase secrète vide n'est pas "
@@ -310,6 +246,32 @@ msgid "Yes, protection is not needed"
 msgstr "Oui, aucune protection n'est nécessaire"
 
 #, c-format
+msgid "A passphrase should be at least %u character long."
+msgid_plural "A passphrase should be at least %u characters long."
+msgstr[0] "Une phrase secrète devrait contenir au moins %u caractère."
+msgstr[1] "Une phrase secrète devrait contenir au moins %u caractères."
+
+#, c-format
+msgid "A passphrase should contain at least %u digit or%%0Aspecial character."
+msgid_plural ""
+"A passphrase should contain at least %u digits or%%0Aspecial characters."
+msgstr[0] ""
+"Une phrase secrète devrait contenir au moins %u chiffre%%0Aou caractère "
+"spécial."
+msgstr[1] ""
+"Une phrase secrète devrait contenir au moins %u chiffres%%0Aou caractères "
+"spéciaux."
+
+#, c-format
+msgid "A passphrase may not be a known term or match%%0Acertain pattern."
+msgstr ""
+"Une phrase secrète ne devrait ni être un mot commun,%%0Ani correspondre à un "
+"certain schéma."
+
+msgid "Warning: You have entered an insecure passphrase."
+msgstr "Avertissement : une phrase secrète non sécurisée a été entrée."
+
+#, c-format
 msgid "Please enter the passphrase to%0Aprotect your new key"
 msgstr "Veuillez entrer la phrase secrète%0Apour protéger la nouvelle clef"
 
@@ -353,9 +315,6 @@ msgstr "ne pas capturer le clavier et la souris"
 msgid "use a log file for the server"
 msgstr "utiliser un fichier journal pour le serveur"
 
-msgid "use a standard location for the socket"
-msgstr "utiliser un emplacement de socket standard"
-
 msgid "|PGM|use PGM as the PIN-Entry program"
 msgstr "|PROG|utiliser PROG pour entrer le code personnel"
 
@@ -389,14 +348,6 @@ msgstr "activer la prise en charge de SSH"
 msgid "enable putty support"
 msgstr "activer la prise en charge de putty"
 
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "ne pas autoriser la réutilisation d'anciennes phrases secrètes"
-
-msgid "|FILE|write environment settings also to FILE"
-msgstr "|FICHIER|écrire aussi les réglages d'env. dans FICHIER"
-
 # @EMAIL@ is currently an URL
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
@@ -406,18 +357,18 @@ msgstr ""
 "Veuillez signaler toutes anomalies sur <@EMAIL@> (en anglais)\n"
 "et tout problème de traduction à <traduc@traduc.org>.\n"
 
-msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Utilisation : gpg-agent [options] (-h pour l'aide)"
+msgid "Usage: @GPG_AGENT@ [options] (-h for help)"
+msgstr "Utilisation : dirmngr @GPG_AGENT@ (-h pour l'aide)"
 
 msgid ""
-"Syntax: gpg-agent [options] [command [args]]\n"
-"Secret key management for GnuPG\n"
+"Syntax: @GPG_AGENT@ [options] [command [args]]\n"
+"Secret key management for @GNUPG@\n"
 msgstr ""
-"Syntaxe : gpg-agent [options] [commande [arguments]]\n"
-"Gestionnaire de clefs secrètes pour GnuPG\n"
+"Syntaxe : @GPG_AGENT@ [options] [commande [arguments]]\n"
+"Gestionnaire de clefs secrètes pour @GNUPG@\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr "niveau de débogage « %s » incorrect\n"
 
 #, c-format
@@ -425,24 +376,20 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr "%s est trop ancien (nécessaire : %s, utilisé : %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "Note: no default option file '%s'\n"
 msgstr "Remarque : pas de fichier d'options par défaut « %s »\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "fichier d'options « %s » : %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "lecture des options de « %s »\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
-msgstr "erreur de création de « %s » : %s\n"
-
-#, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "impossible de créer le répertoire « %s » : %s\n"
+msgid "Note: '%s' is not considered an option\n"
+msgstr "Remarque : « %s » n'est pas considéré comme une option\n"
 
 msgid "name of socket too long\n"
 msgstr "nom de socket trop long\n"
@@ -452,7 +399,7 @@ msgid "can't create socket: %s\n"
 msgstr "impossible de créer la socket : %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "le nom de la socket « %s » est trop long\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -464,7 +411,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "erreur de lecture du « nonce » de la socket\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "erreur de lien de la socket à « %s » : %s\n"
 
 #, c-format
@@ -472,19 +419,23 @@ msgid "listen() failed: %s\n"
 msgstr "échec de listen() : %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "écoute sur la socket « %s »\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "can't create directory '%s': %s\n"
+msgstr "impossible de créer le répertoire « %s » : %s\n"
+
+#, c-format
+msgid "directory '%s' created\n"
 msgstr "répertoire « %s » créé\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "échec de stat() pour « %s » : %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "impossible d'utiliser « %s » comme répertoire personnel\n"
 
 #, c-format
@@ -508,8 +459,8 @@ msgid "ssh handler 0x%lx for fd %d terminated\n"
 msgstr "gestionnaire SSH 0x%lx pour le descripteur %d terminé\n"
 
 #, c-format
-msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "échec de pth_select : %s — attente 1 s\n"
+msgid "npth_pselect failed: %s - waiting 1s\n"
+msgstr "échec de npth_pselect : %s — attente 1 s\n"
 
 #, c-format
 msgid "%s %s stopped\n"
@@ -519,13 +470,6 @@ msgid "no gpg-agent running in this session\n"
 msgstr ""
 "aucune instance de gpg-agent n'est en cours d'exécution dans cette session\n"
 
-msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "la variable d'environnement GPG_AGENT_INFO est mal définie\n"
-
-#, c-format
-msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "le protocole gpg-agent version %d n'est pas pris en charge\n"
-
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
 msgstr ""
 "Utilisation : gpg-preset-passphrase [options] KEYGRIP (-h pour l'aide)\n"
@@ -595,31 +539,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "erreur de demande de la phrase secrète : %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "erreur d'ouverture de « %s » : %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "fichier « %s », ligne %d : %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr "déclaration « %s » ignorée dans « %s », ligne %d\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "le système de liste de confiance « %s » n'est pas disponible\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "mauvaise empreinte dans « %s », ligne %d\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr "option de clef incorrecte dans « %s », ligne %d\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "erreur de lecture de « %s », ligne %d : %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -692,13 +636,53 @@ msgstr "Modifier la phrase secrète"
 msgid "I'll change it later"
 msgstr "Je la modifierai plus tard"
 
+msgid "Delete key"
+msgstr "Supprimer la clef"
+
+msgid ""
+"Warning: This key is also listed for use with SSH!\n"
+"Deleting the key might remove your ability to access remote machines."
+msgstr ""
+"Avertissement : cette clef fait aussi partie de la liste pour utiliser avec "
+"SSH.\n"
+"Supprimer cette clef pourrait vous empêcher d’accéder à des machines "
+"distantes."
+
+msgid "DSA requires the hash length to be a multiple of 8 bits\n"
+msgstr "DSA nécessite que la taille du hachage soit un multiple de 8 bits\n"
+
+#, c-format
+msgid "%s key uses an unsafe (%u bit) hash\n"
+msgstr "la clef %s utilise un hachage non sûr (%u bits)\n"
+
+#, c-format
+msgid "a %zu bit hash is not valid for a %u bit %s key\n"
+msgstr ""
+"un hachage de %1$zu bits n'est pas valable pour une clef %3$s de %2$u bits\n"
+
+msgid "secret key parts are not available\n"
+msgstr "des parties de la clef secrète ne sont pas disponibles\n"
+
+#, c-format
+msgid "public key algorithm %d (%s) is not supported\n"
+msgstr "l'algorithme de clef publique %d (%s) n'est pas pris en charge\n"
+
+#, c-format
+msgid "protection algorithm %d (%s) is not supported\n"
+msgstr "l'algorithme de protection %d (%s) n'est pas pris en charge\n"
+
+#, c-format
+msgid "protection hash algorithm %d (%s) is not supported\n"
+msgstr ""
+"l'algorithme de protection de hachage %d (%s) n'est pas pris en charge\n"
+
 #, c-format
 msgid "error creating a pipe: %s\n"
 msgstr "erreur de création d'un tube : %s\n"
 
 #, c-format
-msgid "can't fdopen pipe for reading: %s\n"
-msgstr "impossible d'ouvrir un tube en lecture avec fdopen : %s\n"
+msgid "error creating a stream for a pipe: %s\n"
+msgstr "erreur de création d'un flux pour un tube : %s\n"
 
 #, c-format
 msgid "error forking process: %s\n"
@@ -709,33 +693,26 @@ msgid "waiting for process %d to terminate failed: %s\n"
 msgstr "échec d'attente de fin du processus %d : %s\n"
 
 #, c-format
-msgid "error getting exit code of process %d: %s\n"
-msgstr "erreur de lecture du code de retour du processus %d : %s\n"
+msgid "error running '%s': probably not installed\n"
+msgstr "erreur d'exécution de « %s » : il n'est sans doute pas installé\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "erreur d'exécution de « %s » : code de retour %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "erreur d'exécution de « %s » : il n'est sans doute pas installé\n"
-
-#, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "erreur d'exécution de « %s » : terminé\n"
 
 #, c-format
-msgid "error creating socket: %s\n"
-msgstr "erreur de création de socket : %s\n"
-
-msgid "host not found"
-msgstr "hôte introuvable"
+msgid "error getting exit code of process %d: %s\n"
+msgstr "erreur de lecture du code de retour du processus %d : %s\n"
 
 msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent n'est pas disponible dans cette session\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "impossible de se connecter à « %s » : %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -805,18 +782,28 @@ msgstr "hors limite de la mémoire sécurisée lors de l'allocation de %lu octe
 msgid "out of core while allocating %lu bytes"
 msgstr "hors limite lors de l'allocation de %lu octets"
 
-msgid "no running gpg-agent - starting one\n"
+#, c-format
+msgid "no running gpg-agent - starting '%s'\n"
 msgstr ""
-"pas d'instance de gpg-agent en cours d'exécution —\n"
-"démarrage d'une nouvelle instance\n"
+"pas d'instance de gpg-agent en cours d'exécution — démarrage de « %s »\n"
 
 #, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "%d secondes d'attente pour permettre à l'agent d'arriver\n"
+msgid "waiting for the agent to come up ... (%ds)\n"
+msgstr "attente pour permettre à l'agent d'arriver… (%d s)\n"
 
-msgid "can't connect to the agent - trying fall back\n"
-msgstr ""
-"impossible de se connecter à l'agent — essai avec la solution de repli\n"
+msgid "connection to agent established\n"
+msgstr "connexion à l'agent établie\n"
+
+#, c-format
+msgid "no running Dirmngr - starting '%s'\n"
+msgstr "pas d'instance de Dirmngr en cours d'exécution — démarrage de « %s »\n"
+
+#, c-format
+msgid "waiting for the dirmngr to come up ... (%ds)\n"
+msgstr "attente pour permettre au dirmngr d'arriver… (%d s)\n"
+
+msgid "connection to the dirmngr established\n"
+msgstr "connexion au dirmngr établie\n"
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
@@ -952,7 +939,7 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr utilisable"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Pas d'aide disponible pour « %s »."
 
 msgid "ignoring garbage line"
@@ -961,6 +948,107 @@ msgstr "ligne inutile ignorée"
 msgid "[none]"
 msgstr "[aucun]"
 
+msgid "argument not expected"
+msgstr "argument inattendu"
+
+msgid "read error"
+msgstr "erreur de lecture"
+
+msgid "keyword too long"
+msgstr "mot-clef trop long"
+
+msgid "missing argument"
+msgstr "argument manquant"
+
+msgid "invalid argument"
+msgstr "argument incorrect"
+
+msgid "invalid command"
+msgstr "commande incorrecte"
+
+msgid "invalid alias definition"
+msgstr "définition d'alias incorrecte"
+
+msgid "out of core"
+msgstr "hors limite"
+
+msgid "invalid option"
+msgstr "option incorrecte"
+
+#, c-format
+msgid "missing argument for option \"%.50s\"\n"
+msgstr "argument manquant pour l'option « %.50s »\n"
+
+#, c-format
+msgid "invalid argument for option \"%.50s\"\n"
+msgstr "argument incorrect pour l'option « %.50s »\n"
+
+#, c-format
+msgid "option \"%.50s\" does not expect an argument\n"
+msgstr "l'option « %.50s » n'attend pas d'argument\n"
+
+#, c-format
+msgid "invalid command \"%.50s\"\n"
+msgstr "commande « %.50s » incorrecte\n"
+
+#, c-format
+msgid "option \"%.50s\" is ambiguous\n"
+msgstr "l'option « %.50s » est ambiguë\n"
+
+#, c-format
+msgid "command \"%.50s\" is ambiguous\n"
+msgstr "la commande « %.50s » est ambiguë\n"
+
+msgid "out of core\n"
+msgstr "hors limite\n"
+
+#, c-format
+msgid "invalid option \"%.50s\"\n"
+msgstr "option « %.50s » incorrecte\n"
+
+#, c-format
+msgid "you found a bug ... (%s:%d)\n"
+msgstr "vous avez trouvé un bogue… (%s : %d)\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr "conversion de « %s » vers « %s » non disponible\n"
+
+#, c-format
+msgid "iconv_open failed: %s\n"
+msgstr "échec de iconv_open : %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "impossible de convertir « %s » en « %s » : %s\n"
+
+#, c-format
+msgid "failed to create temporary file '%s': %s\n"
+msgstr "impossible de créer le fichier temporaire « %s » : %s\n"
+
+#, c-format
+msgid "error writing to '%s': %s\n"
+msgstr "erreur d'écriture sur « %s » : %s\n"
+
+#, c-format
+msgid "removing stale lockfile (created by %d)\n"
+msgstr "suppression du vieux fichier verrou (créé par %d)\n"
+
+#, c-format
+msgid "waiting for lock (held by %d%s) %s...\n"
+msgstr "attente du verrou (appartenant à %d%s) %s…\n"
+
+msgid "(deadlock?) "
+msgstr "(peut-être un verrou mort) "
+
+#, c-format
+msgid "lock '%s' not made: %s\n"
+msgstr "verrou « %s » non effectif : %s\n"
+
+#, c-format
+msgid "waiting for lock %s...\n"
+msgstr "attente du verrou %s…\n"
+
 #, c-format
 msgid "armor: %s\n"
 msgstr "armure : %s\n"
@@ -1045,6 +1133,13 @@ msgid "not human readable"
 msgstr "non lisible par l'utilisateur"
 
 #, c-format
+msgid "failed to proxy %s inquiry to client\n"
+msgstr "échec de transfert de la demande %s au client\n"
+
+msgid "Enter passphrase: "
+msgstr "Entrez la phrase secrète : "
+
+#, c-format
 msgid "OpenPGP card not available: %s\n"
 msgstr "la carte OpenPGP n'est pas disponible : %s\n"
 
@@ -1113,11 +1208,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "erreur d'allocation de suffisamment de mémoire : %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "erreur de lecture de « %s » : %s\n"
 
 #, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "erreur d'écriture de « %s » : %s\n"
 
 msgid "Login data (account name): "
@@ -1174,7 +1269,7 @@ msgid "Replace existing key? (y/N) "
 msgstr "Faut-il remplacer la clef existante ? (o/N) "
 
 msgid ""
-"NOTE: There is no guarantee that the card supports the requested size.\n"
+"Note: There is no guarantee that the card supports the requested size.\n"
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
@@ -1216,7 +1311,7 @@ msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr ""
 "Faut-il faire une sauvegarde hors carte de la clef de chiffrement ? (O/n) "
 
-msgid "NOTE: keys are already stored on the card!\n"
+msgid "Note: keys are already stored on the card!\n"
 msgstr "Remarque : les clefs sont déjà stockées sur la carte.\n"
 
 msgid "Replace existing keys? (y/N) "
@@ -1225,7 +1320,7 @@ msgstr "Faut-il remplacer les clefs existantes ? (o/N) "
 #, c-format
 msgid ""
 "Please note that the factory settings of the PINs are\n"
-"   PIN = `%s'     Admin PIN = `%s'\n"
+"   PIN = '%s'     Admin PIN = '%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
 "Veuillez noter que les configurations d'usine des codes personnels sont\n"
@@ -1250,18 +1345,9 @@ msgstr "Choix incorrect.\n"
 msgid "Please select where to store the key:\n"
 msgstr "Veuillez sélectionner l'endroit où stocker la clef :\n"
 
-msgid "unknown key protection algorithm\n"
-msgstr "algorithme de protection de clef inconnu\n"
-
-msgid "secret parts of key are not available\n"
-msgstr "Les parties secrètes de la clef ne sont pas disponibles.\n"
-
-msgid "secret key already stored on a card\n"
-msgstr "la clef secrète est déjà stockée sur une carte\n"
-
 #, c-format
-msgid "error writing key to card: %s\n"
-msgstr "erreur d'écriture la clef sur la carte : %s\n"
+msgid "KEYTOCARD failed: %s\n"
+msgstr "échec de KEYTOCARD : %s\n"
 
 msgid "quit this menu"
 msgstr "quitter ce menu"
@@ -1332,7 +1418,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output n'est pas compatible avec cette commande\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "impossible d'ouvrir « %s »\n"
 
 #, c-format
@@ -1356,6 +1442,16 @@ msgid "This is a secret key! - really delete? (y/N) "
 msgstr "C'est une clef secrète — faut-il vraiment la supprimer ? (o/N) "
 
 #, c-format
+msgid "deleting secret %s failed: %s\n"
+msgstr "échec de suppression de %s secrète : %s\n"
+
+msgid "key"
+msgstr "clef"
+
+msgid "subkey"
+msgstr "sous-clef"
+
+#, c-format
 msgid "deleting keyblock failed: %s\n"
 msgstr "échec de suppression du bloc de clef : %s\n"
 
@@ -1382,28 +1478,17 @@ msgid "using cipher %s\n"
 msgstr "utilisation de l'algorithme de chiffrement %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "« %s » est déjà compressé\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "Attention : « %s » est un fichier vide\n"
 
-msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
-msgstr ""
-"le chiffrement RSA n'est possible qu'avec des clefs d'au plus 2048 bits\n"
-"en mode --pgp2\n"
-
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "lecture de « %s »\n"
 
-msgid ""
-"unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
-msgstr ""
-"impossible d'utiliser le chiffrement IDEA avec toutes les clefs\n"
-"utilisés pour chiffrer.\n"
-
 #, c-format
 msgid ""
 "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
@@ -1465,11 +1550,11 @@ msgstr ""
 "programmes externes\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "impossible d'exécuter le programme « %s » : %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "impossible d'exécuter l'interpréteur de commandes « %s » : %s\n"
 
 #, c-format
@@ -1487,13 +1572,13 @@ msgid "unable to read external program response: %s\n"
 msgstr "impossible de lire la réponse du programme externe : %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr ""
 "Attention : impossible de supprimer le fichier temporaire\n"
 "            (%s) « %s » : %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr ""
 "Attention : impossible de supprimer le répertoire temporaire « %s » :\n"
 "            %s\n"
@@ -1507,9 +1592,6 @@ msgstr "exporter les attributs d'identité (en général les photos d'identité)
 msgid "export revocation keys marked as \"sensitive\""
 msgstr "exporter les clefs de révocation marquées comme « sensibles »"
 
-msgid "remove the passphrase from exported subkeys"
-msgstr "supprimer la phrase secrète des sous-clefs exportées"
-
 msgid "remove unusable parts from key during export"
 msgstr "supprimer les parties inutilisables de la clef pendant l'exportation"
 
@@ -1523,10 +1605,6 @@ msgid "exporting secret keys not allowed\n"
 msgstr "il est interdit d'exporter les clefs secrètes\n"
 
 #, c-format
-msgid "key %s: not protected - skipped\n"
-msgstr "clef %s : non protégée — ignorée\n"
-
-#, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
 msgstr "clef %s : clef de type PGP 2.x — ignorée\n"
 
@@ -1534,37 +1612,21 @@ msgstr "clef %s : clef de type PGP 2.x — ignorée\n"
 msgid "key %s: key material on-card - skipped\n"
 msgstr "clef %s : matériel de clef sur la carte — ignorée\n"
 
-msgid "about to export an unprotected subkey\n"
-msgstr "sur le point d'exporter une sous-clef non protégée\n"
-
-#, c-format
-msgid "failed to unprotect the subkey: %s\n"
-msgstr "échec de déprotection de la sous-clef : %s\n"
-
-#, c-format
-msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr ""
-"Attention : la clef secrète %s n'a pas de somme de contrôle SK simple\n"
+msgid " - skipped"
+msgstr " — ignoré"
 
 msgid "WARNING: nothing exported\n"
 msgstr "Attention : rien n'a été exporté\n"
 
-msgid "too many entries in pk cache - disabled\n"
-msgstr "trop d'entrées dans le cache de clefs publiques — désactivé\n"
-
 msgid "[User ID not found]"
 msgstr "[identité introuvable]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "clef %s : clef secrète sans clef publique — ignorée\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "« %s » automatiquement récupéré par %s\n"
 
 #, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "erreur de récupération de « %s » avec %s : %s\n"
 
 msgid "No fingerprint"
@@ -1577,10 +1639,6 @@ msgstr ""
 "--allow-non-selfsigned-uid\n"
 
 #, c-format
-msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "pas de sous-clef secrète pour la sous-clef publique %s — ignorée\n"
-
-#, c-format
 msgid "using subkey %s instead of primary key %s\n"
 msgstr ""
 "utilisation de la sous-clef %s à la place de la clef\n"
@@ -1625,6 +1683,12 @@ msgstr "afficher les clefs secrètes"
 msgid "generate a new key pair"
 msgstr "générer une nouvelle paire de clefs"
 
+msgid "quickly generate a new key pair"
+msgstr "générer rapidement une nouvelle paire de clefs"
+
+msgid "full featured key pair generation"
+msgstr "générer une paire de clefs complètes"
+
 msgid "generate a revocation certificate"
 msgstr "générer un certificat de révocation"
 
@@ -1634,6 +1698,12 @@ msgstr "supprimer les clefs du porte-clefs public"
 msgid "remove keys from the secret keyring"
 msgstr "supprimer les clefs du porte-clefs secret"
 
+msgid "quickly sign a key"
+msgstr "signer rapidement une clef"
+
+msgid "quickly sign a key locally"
+msgstr "signer rapidement une clef localement"
+
 msgid "sign a key"
 msgstr "signer une clef"
 
@@ -1685,6 +1755,7 @@ msgstr "exécuter en mode serveur"
 msgid "create ascii armored output"
 msgstr "créer une sortie ASCII avec armure"
 
+# NOTE: Extra initial space to realign the output (maybe wchar issue)
 msgid "|USER-ID|encrypt for USER-ID"
 msgstr "|IDENTITÉ| chiffrer pour l'IDENTITÉ"
 
@@ -1736,15 +1807,15 @@ msgstr ""
 " --list-keys [noms]         montrer les clefs\n"
 " --fingerprint [noms]       montrer les empreintes\n"
 
-msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "Utilisation : gpg [options] [fichiers] (-h pour l'aide)"
+msgid "Usage: @GPG@ [options] [files] (-h for help)"
+msgstr "Utilisation : @GPG@ [options] [fichiers] (-h pour l'aide)"
 
 msgid ""
-"Syntax: gpg [options] [files]\n"
+"Syntax: @GPG@ [options] [files]\n"
 "Sign, check, encrypt or decrypt\n"
 "Default operation depends on the input data\n"
 msgstr ""
-"Syntaxe : gpg [options] [fichiers]\n"
+"Syntaxe : @GPG@ [options] [fichiers]\n"
 "Signer, vérifier, chiffrer ou déchiffrer\n"
 "L'opération par défaut dépend des données entrées\n"
 
@@ -1767,97 +1838,101 @@ msgstr "Hachage : "
 msgid "Compression: "
 msgstr "Compression : "
 
-msgid "usage: gpg [options] "
-msgstr "utilisation : gpg [options] "
+#, c-format
+msgid "usage: %s [options] %s\n"
+msgstr "utilisation : %s [options] %s\n"
 
 msgid "conflicting commands\n"
 msgstr "commandes en conflit\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "aucun signe = trouvé dans la définition du groupe « %s »\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr ""
 "Attention : le propriétaire du répertoire personnel « %s »\n"
 "            n'est pas sûr\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr ""
 "Attention : le propriétaire du fichier de configuration « %s »\n"
 "            n'est pas sûr\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr ""
 "Attention : le propriétaire de l'extension « %s »\n"
 "            n'est pas sûr\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr ""
 "Attention : les droits du répertoire personnel « %s »\n"
 "            ne sont pas sûrs\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr ""
 "Attention : les droits du fichier de configuration « %s »\n"
 "            ne sont pas sûrs\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr ""
 "Attention : les droits de l'extension « %s »\n"
 "            ne sont pas sûrs\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
 "Attention : le propriétaire du répertoire contenant le répertoire personnel\n"
 "            « %s » n'est pas sûr\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory ownership on configuration file '%s'\n"
 msgstr ""
 "Attention : le propriétaire du répertoire contenant le fichier de\n"
 "            configuration « %s » n'est pas sûr\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "Attention : le propriétaire du répertoire contenant l'extension\n"
 "            « %s » n'est pas sûr\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 "Attention : les droits du répertoire contenant le répertoire personnel\n"
 "            « %s » ne sont pas sûrs\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory permissions on configuration file '%s'\n"
 msgstr ""
 "Attention : les droits du répertoire contenant le fichier de configuration\n"
 "            « %s » ne sont pas sûrs\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "Attention : les droits du répertoire contenant l'extension\n"
 "            « %s » ne sont pas sûrs\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "élément de configuration « %s » inconnu\n"
 
 msgid "display photo IDs during key listings"
 msgstr "montrer les photos d'identité en affichant les clefs"
 
+msgid "show key usage information during key listings"
+msgstr "indiquer les informations sur l'utilisation en affichant les clefs"
+
 msgid "show policy URLs during signature listings"
 msgstr "montrer les URL de politique en affichant les signatures"
 
@@ -1891,7 +1966,7 @@ msgid "show expiration dates during signature listings"
 msgstr "montrer les dates d'expiration en affichant les signatures"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "Note: old default options file '%s' ignored\n"
 msgstr "Remarque : l'ancien fichier d'options par défaut « %s » a été ignoré\n"
 
 #, c-format
@@ -1899,15 +1974,19 @@ msgid "libgcrypt is too old (need %s, have %s)\n"
 msgstr "libgcrypt est trop ancienne (nécessaire : %s, utilisé : %s)\n"
 
 #, c-format
-msgid "NOTE: %s is not for normal use!\n"
+msgid "Note: %s is not for normal use!\n"
 msgstr "Remarque : %s n'est pas pour une utilisation normale.\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "« %s » n'est pas une date d'expiration de signature valable\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "invalid pinentry mode '%s'\n"
+msgstr "mode pinentry « %s » incorrect\n"
+
+#, c-format
+msgid "'%s' is not a valid character set\n"
 msgstr "« %s » n'est pas un jeu de caractères valable\n"
 
 msgid "could not parse keyserver URL\n"
@@ -2010,27 +2089,13 @@ msgstr "%s n'est pas permis avec %s.\n"
 msgid "%s makes no sense with %s!\n"
 msgstr "%s n'a aucun sens avec %s.\n"
 
+msgid "WARNING: running with faked system time: "
+msgstr "Attention : exécution avec un système de temps contrefait : "
+
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
 msgstr "ne sera pas exécuté avec une mémoire non sécurisée à cause de %s\n"
 
-msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
-msgstr ""
-"une signature détachée ou en texte clair n'est possible qu'en mode --pgp2\n"
-
-msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr "signer et chiffrer en même temps n'est possible qu'en mode --pgp2\n"
-
-msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr ""
-"des fichiers (et pas un tube) doivent être utilisés lorsque --pgp2\n"
-"est activé.\n"
-
-msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr ""
-"chiffrer un message en mode --pgp2 nécessite l'algorithme de chiffrement "
-"IDEA\n"
-
 msgid "selected cipher algorithm is invalid\n"
 msgstr "l'algorithme de chiffrement sélectionné est incorrect\n"
 
@@ -2058,7 +2123,7 @@ msgstr "« default-cert-level » incorrect ; doit être 0, 1, 2 ou 3\n"
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
 msgstr "« min-cert-level » incorrect ; doit être , 1, 2 ou 3\n"
 
-msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
+msgid "Note: simple S2K mode (0) is strongly discouraged\n"
 msgstr "Remarque : le mode S2K simple (0) est fortement déconseillé\n"
 
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
@@ -2081,15 +2146,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s ne fonctionne pas encore avec %s\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "impossible d'utiliser l'algorithme de chiffrement « %s » en mode %s.\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "impossible d'utiliser l'algorithme de hachage « %s » en mode %s.\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "impossible d'utiliser l'algorithme de compression « %s » en mode %s.\n"
 
 #, c-format
@@ -2108,7 +2173,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [fichier]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "échec du chiffrement symétrique de « %s » : %s\n"
 
 msgid "--encrypt [filename]"
@@ -2190,7 +2255,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "échec de construction d'une armure : %s \n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "algorithme de hachage « %s » incorrect\n"
 
 msgid "[filename]"
@@ -2231,7 +2296,7 @@ msgid "No help available"
 msgstr "Pas d'aide disponible"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Pas d'aide disponible pour « %s »"
 
 msgid "import signatures that are marked as local-only"
@@ -2240,17 +2305,9 @@ msgstr "importer des signatures marquées comme locales seulement"
 msgid "repair damage from the pks keyserver during import"
 msgstr "réparer les données endommagées du serveur pks pendant l'importation"
 
-#, fuzzy
-#| msgid "do not update the trustdb after import"
-msgid "do not clear the ownertrust values during import"
-msgstr "ne pas mettre à jour la base de confiance après l'importation"
-
 msgid "do not update the trustdb after import"
 msgstr "ne pas mettre à jour la base de confiance après l'importation"
 
-msgid "create a public key when importing a secret key"
-msgstr "créer une clef publique en important une clef secrète"
-
 msgid "only accept updates to existing keys"
 msgstr "n'accepter que les mises à jour des clefs existantes"
 
@@ -2368,7 +2425,7 @@ msgstr "clef %s : pas d'identité\n"
 msgid "key %s: %s\n"
 msgstr "clef %s : %s\n"
 
-msgid "rejected by import filter"
+msgid "rejected by import screener"
 msgstr "rejetée par le filtre d’importation"
 
 #, c-format
@@ -2399,11 +2456,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "aucun porte-clefs accessible en écriture n'a été trouvé : %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "écriture de « %s »\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "erreur d'écriture du porte-clefs « %s » : %s\n"
 
 #, c-format
@@ -2467,31 +2524,27 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "clef %s : « %s » n'est pas modifiée\n"
 
 #, c-format
-msgid "secret key %s: %s\n"
-msgstr "clef secrète %s : %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "impossible d'importer des clefs secrètes\n"
+msgid "key %s: secret key imported\n"
+msgstr "clef %s : clef secrète importée\n"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "clef %s : clef secrète avec chiffrement %d incorrect — ignorée\n"
+msgid "key %s: secret key already exists\n"
+msgstr "clef %s : la clef secrète clef existe déjà\n"
 
 #, c-format
-msgid "no default secret keyring: %s\n"
-msgstr "pas de porte-clefs par défaut : %s\n"
+msgid "key %s: error sending to agent: %s\n"
+msgstr "clef %s : erreur d'envoi à l'agent : %s\n"
 
 #, c-format
-msgid "key %s: secret key imported\n"
-msgstr "clef %s : clef secrète importée\n"
+msgid "secret key %s: %s\n"
+msgstr "clef secrète %s : %s\n"
 
-#, c-format
-msgid "key %s: already in secret keyring\n"
-msgstr "clef %s : déjà dans le porte-clefs secret\n"
+msgid "importing secret keys not allowed\n"
+msgstr "impossible d'importer des clefs secrètes\n"
 
 #, c-format
-msgid "key %s: secret key not found: %s\n"
-msgstr "clef %s : clef secrète introuvable : %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "clef %s : clef secrète avec chiffrement %d incorrect — ignorée\n"
 
 #, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
@@ -2603,27 +2656,24 @@ msgstr "clef %s : ajout du certificat de révocation « %s »\n"
 msgid "key %s: direct key signature added\n"
 msgstr "clef %s : ajout de la signature directe de clef\n"
 
-msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr ""
-"Remarque : le numéro de série d'une clef ne correspond pas à celui de la "
-"carte\n"
-
-msgid "NOTE: primary key is online and stored on card\n"
-msgstr "Remarque : la clef principale est en ligne et stockée sur la carte\n"
-
-msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "Remarque : la clef secondaire est en ligne et stockée sur la carte\n"
+#, c-format
+msgid "error creating keybox '%s': %s\n"
+msgstr "erreur de création du trousseau local « %s » : %s\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "erreur de création du porte-clefs « %s » : %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keybox '%s' created\n"
+msgstr "le trousseau local « %s » a été créé\n"
+
+#, c-format
+msgid "keyring '%s' created\n"
 msgstr "le porte-clefs « %s » a été créé\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "ressource de bloc de clef « %s » : %s\n"
 
 #, c-format
@@ -2782,16 +2832,6 @@ msgid "Do you want your signature to expire at the same time? (Y/n) "
 msgstr "Voulez-vous que votre signature expire en même temps ? (O/n) "
 
 msgid ""
-"You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
-"mode.\n"
-msgstr ""
-"Impossible de faire une signature OpenPGP d'une clef PGP 2.x en mode --"
-"pgp2.\n"
-
-msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "Cela rendrait la clef inutilisable par PGP 2.x.\n"
-
-msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
@@ -2815,7 +2855,7 @@ msgstr "   (2) J'ai partiellement vérifié.%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) J'ai complètement vérifié.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Quel est votre choix ? (Entrez « ? » pour plus de renseignements) : "
 
 #, c-format
@@ -2862,44 +2902,9 @@ msgstr ""
 "La clef ne possède que des éléments partiels ou stockés sur carte\n"
 "— pas de phrase secrète à modifier.\n"
 
-msgid "This key is not protected.\n"
-msgstr "Cette clef n'est pas protégée.\n"
-
-msgid "Secret parts of primary key are not available.\n"
-msgstr "Les parties secrètes de la clef principale ne sont pas disponibles.\n"
-
-msgid "Secret parts of primary key are stored on-card.\n"
-msgstr ""
-"Les parties secrètes de la clef principale sont stockées sur la carte.\n"
-
-msgid "Key is protected.\n"
-msgstr "La clef est protégée.\n"
-
 #, c-format
-msgid "Can't edit this key: %s\n"
-msgstr "Impossible d'éditer cette clef : %s\n"
-
-msgid ""
-"Enter the new passphrase for this secret key.\n"
-"\n"
-msgstr ""
-"Entrez la nouvelle phrase secrète pour cette clef secrète.\n"
-"\n"
-
-msgid "passphrase not correctly repeated; try again"
-msgstr ""
-"la phrase secrète n'a pas été correctement répétée ; veuillez réessayer"
-
-msgid ""
-"You don't want a passphrase - this is probably a *bad* idea!\n"
-"\n"
-msgstr ""
-"Vous ne voulez pas de phrase secrète — c'est sans doute une *mauvaise* "
-"idée.\n"
-"\n"
-
-msgid "Do you really want to do this? (y/N) "
-msgstr "Voulez-vous vraiment faire cela ? (o/N) "
+msgid "key %s: error changing passphrase: %s\n"
+msgstr "clef %s : erreur de modification de la phrase secrète : %s\n"
 
 msgid "moving a key signature to the correct place\n"
 msgstr "déplacement d'une signature de clef au bon endroit\n"
@@ -3026,10 +3031,6 @@ msgstr ""
 "compacter les identités inutilisables et supprimer toutes\n"
 "            les signatures de la clef"
 
-#, c-format
-msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "erreur de lecture du bloc de clef secrète « %s » : %s\n"
-
 msgid "Secret key is available.\n"
 msgstr "La clef secrète est disponible.\n"
 
@@ -3040,9 +3041,9 @@ msgid "Please use the command \"toggle\" first.\n"
 msgstr "Veuillez d'abord utiliser la commande « toggle ».\n"
 
 msgid ""
-"* The `sign' command may be prefixed with an `l' for local signatures "
+"* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
-"  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
+"  a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
 "* La commande « sign » peut être précédée du caractère « l » pour\n"
@@ -3060,7 +3061,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Conseil : sélectionner les identités à signer\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Type de signature « %s » inconnu\n"
 
 #, c-format
@@ -3091,11 +3092,11 @@ msgid "Command expects a filename argument\n"
 msgstr "La commande attend un nom de fichier comme argument\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "Impossible d'ouvrir « %s » : %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Erreur de lecture de la clef de sauvegarde sur « %s » : %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3149,13 +3150,23 @@ msgstr "Faut-il quitter sans enregistrer ? (o/N) "
 msgid "update failed: %s\n"
 msgstr "échec de la mise à jour : %s\n"
 
-#, c-format
-msgid "update secret failed: %s\n"
-msgstr "échec de la mise à jour de la clef secrète : %s\n"
-
 msgid "Key not changed so no update needed.\n"
 msgstr "La clef n'a pas été modifiée donc la mise à jour est inutile.\n"
 
+#, c-format
+msgid "\"%s\" is not a fingerprint\n"
+msgstr "« %s » n’est pas une empreinte\n"
+
+#, c-format
+msgid "\"%s\" is not the primary fingerprint\n"
+msgstr "« %s » n’est pas l’empreinte principale\n"
+
+msgid "No matching user IDs."
+msgstr "Pas d’identités correspondantes."
+
+msgid "Nothing to sign.\n"
+msgstr "Rien à signer.\n"
+
 msgid "Digest: "
 msgstr "Hachage : "
 
@@ -3205,6 +3216,9 @@ msgstr "expire : %s"
 msgid "usage: %s"
 msgstr "utilisation : %s"
 
+msgid "card-no: "
+msgstr "nº de carte : "
+
 #, c-format
 msgid "trust: %s"
 msgstr "confiance : %s"
@@ -3216,9 +3230,6 @@ msgstr "validité : %s"
 msgid "This key has been disabled"
 msgstr "Cette clef a été désactivée"
 
-msgid "card-no: "
-msgstr "nº de carte : "
-
 msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
@@ -3241,12 +3252,10 @@ msgstr ""
 "            risque de rendre une autre identité principale par défaut.\n"
 
 msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
+msgstr "Attention : votre sous-clef de chiffrement expire bientôt.\n"
 
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
 msgid "You may want to change its expiration date too.\n"
-msgstr "Vous ne pouvez pas modifier la date d'expiration d'une clef v3\n"
+msgstr "Vous pourriez modifier aussi sa date d’expiration.\n"
 
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
@@ -3264,13 +3273,13 @@ msgstr ""
 "Vous ne devriez pas ajouter de photo d'identité à une clef de type PGP 2.\n"
 
 msgid "Delete this good signature? (y/N/q)"
-msgstr "Faut-il supprimer cette bonne signature ? (o/N/q)"
+msgstr "Supprimer cette bonne signature ? (o/N/q)"
 
 msgid "Delete this invalid signature? (y/N/q)"
-msgstr "Faut-il supprimer cette signature incorrecte ? (o/N/q)"
+msgstr "Supprimer cette signature incorrecte ? (o/N/q)"
 
 msgid "Delete this unknown signature? (y/N/q)"
-msgstr "Faut-il supprimer cette signature inconnue ? (o/N/q)"
+msgstr "Supprimer cette signature inconnue ? (o/N/q)"
 
 msgid "Really delete this self-signature? (y/N)"
 msgstr "Faut-il vraiment supprimer cette autosignature ? (o/N)"
@@ -3346,9 +3355,6 @@ msgid ""
 msgstr ""
 "Voulez-vous vraiment rendre cette clef comme révocateur désigné ? (o/N) "
 
-msgid "Please remove selections from the secret keys.\n"
-msgstr "Veuillez supprimer les sélections des clefs secrètes.\n"
-
 msgid "Please select at most one subkey.\n"
 msgstr "Veuillez sélectionner au plus une sous-clef.\n"
 
@@ -3361,9 +3367,6 @@ msgstr "Modification de la date d'expiration de la clef principale.\n"
 msgid "You can't change the expiration date of a v3 key\n"
 msgstr "Vous ne pouvez pas modifier la date d'expiration d'une clef v3\n"
 
-msgid "No corresponding signature in secret ring\n"
-msgstr "Pas de signature correspondante dans le porte-clefs secret\n"
-
 #, c-format
 msgid "signing subkey %s is already cross-certified\n"
 msgstr "la sous-clef de signature %s a déjà une certification croisée\n"
@@ -3477,7 +3480,7 @@ msgstr ""
 "%s (uid %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "préférence « %s » en double\n"
 
 msgid "too many cipher preferences\n"
@@ -3490,7 +3493,7 @@ msgid "too many compression preferences\n"
 msgstr "trop de préférences de compression\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "élément « %s » incorrect dans la chaîne de préférences\n"
 
 # g10/keygen.c:123 ???
@@ -3603,6 +3606,35 @@ msgid "   (%d) RSA (set your own capabilities)\n"
 msgstr "   (%d) RSA (indiquez vous-même les capacités)\n"
 
 #, c-format
+msgid "   (%d) ECC and ECC\n"
+msgstr "   (%d) ECC et ECC\n"
+
+#, c-format
+msgid "  (%d) ECC (sign only)\n"
+msgstr "  (%d) ECC (signature seule)\n"
+
+#, c-format
+msgid "  (%d) ECC (set your own capabilities)\n"
+msgstr "  (%d) ECC (indiquez vous-même les capacités)\n"
+
+#, c-format
+msgid "  (%d) ECC (encrypt only)\n"
+msgstr "  (%d) ECC (chiffrement seul)\n"
+
+#, c-format
+msgid "  (%d) Existing key\n"
+msgstr "  (%d) Clef existante\n"
+
+msgid "Enter the keygrip: "
+msgstr "Entrez le keygrip : "
+
+msgid "Not a valid keygrip (expecting 40 hex digits)\n"
+msgstr "Ce n'est pas un keygrip valable (40 chiffres hexadécimaux attendus)\n"
+
+msgid "No key with this keygrip\n"
+msgstr "Pas de clef avec ce keygrip\n"
+
+#, c-format
 msgid "%s keys may be between %u and %u bits long.\n"
 msgstr "les clefs %s peuvent faire une taille comprise entre %u et %u bits.\n"
 
@@ -3618,6 +3650,13 @@ msgstr "Quelle taille de clef désirez-vous ? (%u) "
 msgid "Requested keysize is %u bits\n"
 msgstr "La taille demandée est %u bits\n"
 
+#, c-format
+msgid "rounded to %u bits\n"
+msgstr "arrondie à %u bits\n"
+
+msgid "Please select which elliptic curve you want:\n"
+msgstr "Sélectionnez le type de courbe elliptique désiré :\n"
+
 msgid ""
 "Please specify how long the key should be valid.\n"
 "         0 = key does not expire\n"
@@ -3736,7 +3775,7 @@ msgid "Invalid character in comment\n"
 msgstr "Caractère incorrect dans le commentaire\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Vous utilisez le jeu de caractères « %s ».\n"
 
 #, c-format
@@ -3773,14 +3812,19 @@ msgstr "NnCcAaOoQq"
 
 msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
 msgstr ""
-"Faut-il modifier le (N)om, le (C)ommentaire, l'(A)dresse électronique\n"
-"ou (Q)uitter ? "
+"Changer le (N)om, le (C)ommentaire, l'(A)dresse électronique ou (Q)uitter ? "
 
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
 msgstr ""
-"Faut-il modifier le (N)om, le (C)ommentaire, l'(A)dresse électronique\n"
+"Changer le (N)om, le (C)ommentaire, l'(A)dresse électronique\n"
 "ou (O)ui/(Q)uitter ? "
 
+msgid "Change (N)ame, (E)mail, or (Q)uit? "
+msgstr "Changer le (N)om, l’(A)dresse électronique ou (Q)uitter ? "
+
+msgid "Change (N)ame, (E)mail, or (O)kay/(Q)uit? "
+msgstr "Changer le (N)om, l'(A)dresse électronique ou (O)ui/(Q)uitter ? "
+
 msgid "Please correct the error first\n"
 msgstr "Veuillez d'abord corriger l'erreur\n"
 
@@ -3798,6 +3842,10 @@ msgstr ""
 "Veuillez entrer une phrase secrète pour protéger la sauvegarde hors carte de "
 "la nouvelle clef de chiffrement."
 
+msgid "passphrase not correctly repeated; try again"
+msgstr ""
+"la phrase secrète n'a pas été correctement répétée ; veuillez réessayer"
+
 #, c-format
 msgid "%s.\n"
 msgstr "%s.\n"
@@ -3824,36 +3872,53 @@ msgstr ""
 "pendant la génération de nombres premiers ; cela donne au générateur de\n"
 "nombres aléatoires une meilleure chance d'obtenir suffisamment d'entropie.\n"
 
-msgid "Key generation canceled.\n"
-msgstr "La génération de clef a été annulée.\n"
-
 #, c-format
-msgid "writing public key to `%s'\n"
-msgstr "écriture de la clef publique dans Â«Â %s »\n"
+msgid "Key generation failed: %s\n"
+msgstr "Ã\89chec de génération de la clef : %s\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "écriture de la clef secrète partielle dans « %s »\n"
+msgid ""
+"About to create a key for:\n"
+"    \"%s\"\n"
+"\n"
+msgstr ""
+"Sur le point de créer une clef pour :\n"
+"   « %s »\n"
+"\n"
+
+msgid "Continue? (Y/n) "
+msgstr "Faut-il continuer ? (O/n) "
 
 #, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "écriture de la clef secrète dans « %s »\n"
+msgid "A key for \"%s\" already exists\n"
+msgstr "Une clef pour « %s » existe déjà\n"
+
+msgid "Create anyway? (y/N) "
+msgstr "Faut-il quand même créer ? (o/N) "
+
+msgid "creating anyway\n"
+msgstr "création quand même\n"
 
 #, c-format
-msgid "no writable public keyring found: %s\n"
-msgstr "aucun porte-clefs public accessible en écriture n'a été trouvé : %s\n"
+msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n"
+msgstr ""
+"Remarque : Utilisez « %s %s » pour une fenêtre de dialogue de génération de "
+"clef complète.\n"
+
+msgid "Key generation canceled.\n"
+msgstr "La génération de clef a été annulée.\n"
 
 #, c-format
-msgid "no writable secret keyring found: %s\n"
-msgstr "aucun porte-clefs secret accessible en écriture n'a été trouvé : %s\n"
+msgid "writing public key to '%s'\n"
+msgstr "écriture de la clef publique dans « %s »\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "erreur d'écriture du porte-clefs public « %s » : %s\n"
+msgid "no writable public keyring found: %s\n"
+msgstr "aucun porte-clefs public accessible en écriture n'a été trouvé : %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "erreur d'écriture du porte-clefs secret « %s » : %s\n"
+msgid "error writing public keyring '%s': %s\n"
+msgstr "erreur d'écriture du porte-clefs public « %s » : %s\n"
 
 msgid "public and secret key created and signed.\n"
 msgstr "les clefs publique et secrète ont été créées et signées.\n"
@@ -3867,10 +3932,6 @@ msgstr ""
 "utiliser la commande « --edit-key » pour générer une sous-clef à cette fin.\n"
 
 #, c-format
-msgid "Key generation failed: %s\n"
-msgstr "Échec de génération de la clef : %s\n"
-
-#, c-format
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr ""
@@ -3884,11 +3945,18 @@ msgstr ""
 "la clef a été créée %lu secondes dans le futur (faille temporelle ou\n"
 "problème d'horloge)\n"
 
-msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
+msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n"
 msgstr ""
 "Remarque : la création de sous-clefs pour des clefs v3 n'est pas compatible\n"
 "           avec OpenPGP\n"
 
+msgid "Secret parts of primary key are not available.\n"
+msgstr "Les parties secrètes de la clef principale ne sont pas disponibles.\n"
+
+msgid "Secret parts of primary key are stored on-card.\n"
+msgstr ""
+"Les parties secrètes de la clef principale sont stockées sur la carte.\n"
+
 msgid "Really create? (y/N) "
 msgstr "Faut-il vraiment la créer ? (o/N) "
 
@@ -3897,11 +3965,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "impossible de stocker la clef sur la carte : %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "impossible de créer le fichier de sauvegarde « %s » : %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "Note: backup of card key saved to '%s'\n"
 msgstr "Remarque : sauvegarde de la clef de la carte dans « %s »\n"
 
 msgid "never     "
@@ -3922,6 +3990,10 @@ msgstr "Notation de signature critique : "
 msgid "Signature notation: "
 msgstr "Notation de signature : "
 
+#, c-format
+msgid "Warning: %lu key(s) skipped due to their large size\n"
+msgstr "Attention : %lu clefs ignorées en raison de leur grande taille\n"
+
 msgid "Keyring"
 msgstr "Porte-clefs"
 
@@ -3942,35 +4014,15 @@ msgstr " Empreinte de sous-clef :"
 msgid "      Key fingerprint ="
 msgstr " Empreinte de la clef ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "Attention : utilisation de l'algorithme expérimental de hachage %s\n"
-
 msgid "      Card serial no. ="
 msgstr " Nº de série de carte ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "impossible de renommer « %s » en « %s » : %s\n"
 
-msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr ""
-"Attention : deux fichiers existent avec des informations confidentielles.\n"
-
 #, c-format
-msgid "%s is the unchanged one\n"
-msgstr "%s est le fichier d'origine\n"
-
-#, c-format
-msgid "%s is the new one\n"
-msgstr "%s est le nouveau\n"
-
-msgid "Please fix this possible security flaw\n"
-msgstr "Veuillez corriger cet éventuel problème de sécurité\n"
-
-#, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "mise en cache du porte-clefs « %s »\n"
 
 #, c-format
@@ -4011,7 +4063,7 @@ msgstr ""
 "clefs"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "Attention : l'option de serveur de clefs « %s » n'est pas\n"
 "            utilisée sur cette plateforme\n"
@@ -4027,6 +4079,27 @@ msgid "invalid keyserver protocol (us %d!=handler %d)\n"
 msgstr "protocole de serveur de clefs incorrect (nous %d!=gestionnaire %d)\n"
 
 #, c-format
+msgid "\"%s\" not a key ID: skipping\n"
+msgstr "« %s » n'est pas un identifiant de clef : ignoré\n"
+
+#, c-format
+msgid "WARNING: unable to refresh key %s via %s: %s\n"
+msgstr ""
+"Attention : impossible de rafraîchir la clef %s\n"
+"            avec %s : %s\n"
+
+#, c-format
+msgid "refreshing 1 key from %s\n"
+msgstr "rafraîchissement d'une clef à partir de %s\n"
+
+#, c-format
+msgid "refreshing %d keys from %s\n"
+msgstr "rafraîchissement de %d clefs à partir de %s\n"
+
+msgid "no keyserver known (use option --keyserver)\n"
+msgstr "pas de serveur de clefs connu (utilisez l'option --keyserver)\n"
+
+#, c-format
 msgid "key \"%s\" not found on keyserver\n"
 msgstr "clef « %s » introuvable sur le serveur de clefs\n"
 
@@ -4042,12 +4115,8 @@ msgid "requesting key %s from %s\n"
 msgstr "requête de la clef %s sur %s\n"
 
 #, c-format
-msgid "searching for names from %s server %s\n"
-msgstr "recherche de noms sur le serveur %s %s\n"
-
-#, c-format
-msgid "searching for names from %s\n"
-msgstr "recherche de noms sur %s\n"
+msgid "skipped \"%s\": %s\n"
+msgstr "« %s » a été ignorée : %s\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
@@ -4058,84 +4127,14 @@ msgid "sending key %s to %s\n"
 msgstr "envoi de la clef %s à %s\n"
 
 #, c-format
-msgid "searching for \"%s\" from %s server %s\n"
-msgstr "recherche de « %s » sur le serveur %s %s\n"
-
-#, c-format
-msgid "searching for \"%s\" from %s\n"
-msgstr "recherche de « %s » sur %s\n"
-
-msgid "no keyserver action!\n"
-msgstr "pas d'action pour le serveur de clefs.\n"
-
-#, c-format
-msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr ""
-"Attention : le gestionnaire de serveurs de clefs provient d'une\n"
-"            version différente de GnuPG (%s)\n"
-
-msgid "keyserver did not send VERSION\n"
-msgstr "le serveurs de clefs n'a pas envoyé sa VERSION\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "erreur de communication avec le serveur de clefs : %s\n"
-
-msgid "no keyserver known (use option --keyserver)\n"
-msgstr "pas de serveur de clefs connu (utilisez l'option --keyserver)\n"
-
-msgid "external keyserver calls are not supported in this build\n"
-msgstr ""
-"les appels externes à un serveur de clef ne sont pas pris en charge dans\n"
-"cette compilation\n"
-
-#, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "pas de gestionnaire pour le type de serveurs de clefs « %s »\n"
-
-#, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
-msgstr ""
-"l'action « %s » n'est pas prise en charge avec le type de serveurs\n"
-"de clefs « %s »\n"
-
-#, c-format
-msgid "%s does not support handler version %d\n"
-msgstr "%s ne prend pas en charge pas le gestionnaire de version %d\n"
-
-msgid "keyserver timed out\n"
-msgstr "le délai d'attente du serveur de clefs a expiré\n"
-
-msgid "keyserver internal error\n"
-msgstr "erreur interne du serveur de clefs\n"
-
-#, c-format
-msgid "\"%s\" not a key ID: skipping\n"
-msgstr "« %s » n'est pas un identifiant de clef : ignoré\n"
-
-#, c-format
-msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr ""
-"Attention : impossible de rafraîchir la clef %s\n"
-"            avec %s : %s\n"
-
-#, c-format
-msgid "refreshing 1 key from %s\n"
-msgstr "rafraîchissement d'une clef à partir de %s\n"
-
-#, c-format
-msgid "refreshing %d keys from %s\n"
-msgstr "rafraîchissement de %d clefs à partir de %s\n"
+msgid "requesting key from '%s'\n"
+msgstr "requête de la clef sur « %s »\n"
 
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
 msgstr "Attention : impossible de récupérer l'URI %s : %s\n"
 
 #, c-format
-msgid "WARNING: unable to parse URI %s\n"
-msgstr "Attention : impossible d'analyser l'URI %s\n"
-
-#, c-format
 msgid "weird size for an encrypted session key (%d)\n"
 msgstr "taille étonnante pour une clef de session chiffrée (%d)\n"
 
@@ -4206,7 +4205,7 @@ msgstr "phrase secrète effacée mise en cache avec l'identifiant : %s\n"
 msgid "decryption failed: %s\n"
 msgstr "échec du déchiffrement : %s\n"
 
-msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
+msgid "Note: sender requested \"for-your-eyes-only\"\n"
 msgstr "Remarque : l'expéditeur a demandé « à votre seule attention »\n"
 
 #, c-format
@@ -4222,6 +4221,18 @@ msgstr "révocation autonome — utilisez « gpg --import » pour l'appliquer
 msgid "no signature found\n"
 msgstr "aucune signature trouvée\n"
 
+#, c-format
+msgid "BAD signature from \"%s\""
+msgstr "MAUVAISE signature de « %s »"
+
+#, c-format
+msgid "Expired signature from \"%s\""
+msgstr "Signature expirée de « %s »"
+
+#, c-format
+msgid "Good signature from \"%s\""
+msgstr "Bonne signature de « %s »"
+
 msgid "signature verification suppressed\n"
 msgstr "vérification de signature supprimée\n"
 
@@ -4243,18 +4254,6 @@ msgstr "Signature faite le %s avec la clef %s d'identifiant %s\n"
 msgid "Key available at: "
 msgstr "Clef disponible sur : "
 
-#, c-format
-msgid "BAD signature from \"%s\""
-msgstr "MAUVAISE signature de « %s »"
-
-#, c-format
-msgid "Expired signature from \"%s\""
-msgstr "Signature expirée de « %s »"
-
-#, c-format
-msgid "Good signature from \"%s\""
-msgstr "Bonne signature de « %s »"
-
 msgid "[uncertain]"
 msgstr "[doute]"
 
@@ -4271,8 +4270,8 @@ msgid "Signature expires %s\n"
 msgstr "La signature expire le %s\n"
 
 #, c-format
-msgid "%s signature, digest algorithm %s\n"
-msgstr "signature %s, algorithme de hachage %s\n"
+msgid "%s signature, digest algorithm %s%s%s\n"
+msgstr "signature %s, algorithme de hachage %s%s%s\n"
 
 msgid "binary"
 msgstr "binaire"
@@ -4283,9 +4282,8 @@ msgstr "mode texte"
 msgid "unknown"
 msgstr "inconnu"
 
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
+msgid ", key algorithm "
+msgstr ", algorithme de clef "
 
 #, c-format
 msgid "Can't check signature: %s\n"
@@ -4311,7 +4309,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "paquet racine incorrect détecté dans proc_tree()\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "échec du fstat de « %s » dans %s : %s\n"
 
 #, c-format
@@ -4345,13 +4343,6 @@ msgstr "Attention : l'algorithme de hachage %s est déconseillé\n"
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Remarque : les signatures utilisant l’algorithme %s sont rejetées\n"
 
-msgid "the IDEA cipher plugin is not present\n"
-msgstr "le module de chiffrement IDEA n'est pas présent\n"
-
-#, c-format
-msgid "please see %s for more information\n"
-msgstr "veuillez consulter %s pour plus de renseignements\n"
-
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
 msgstr "%s : %d : option « %s » déconseillée\n"
@@ -4373,13 +4364,13 @@ msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
 msgstr "%s : %u : option « %s » obsolète — non prise en compte\n"
 
 #, c-format
-msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr "Attention : « %s » est une option obsolète — non prise en compte\n"
+msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgstr "Attention : « %s%s » est une option obsolète — non prise en compte\n"
 
 #, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
+msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n"
 msgstr ""
-"%s : %u : « %s%s » est obsolète dans ce fichier — n’est prise en compte que "
+"%s : %u : « %s » est obsolète dans ce fichier — n’est prise en compte que "
 "dans %s\n"
 
 #, c-format
@@ -4401,15 +4392,20 @@ msgid "this message may not be usable by %s\n"
 msgstr "ce message ne sera pas utilisable par %s\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "option « %s » ambiguë\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "option « %s » inconnue\n"
 
+msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n"
+msgstr ""
+"une clef publique ECDSA est censée être dans un encodage SEC multiple de "
+"8 bits\n"
+
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Le fichier « %s » existe. "
 
 msgid "Overwrite? (y/N) "
@@ -4425,17 +4421,16 @@ msgstr "Entrez le nouveau nom de fichier"
 msgid "writing to stdout\n"
 msgstr "écriture vers la sortie standard\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "les données signées sont supposées être dans « %s »\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "nouveau fichier de configuration « %s » créé\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "Attention : les options de « %s » ne sont pas encore actives cette fois\n"
 
@@ -4497,11 +4492,53 @@ msgstr "clef %2$s de %1$u bits, identifiant %3$s, créée le %4$s"
 msgid "         (subkey on main key ID %s)"
 msgstr "        (sous-clef de la clef principale d'identifiant %s)"
 
-msgid ""
-"\n"
-"Pick an image to use for your photo ID.  The image must be a JPEG file.\n"
-"Remember that the image is stored within your public key.  If you use a\n"
-"very large picture, your key will become very large as well!\n"
+msgid "Please enter the passphrase to unlock the OpenPGP secret key:"
+msgstr ""
+"Veuillez entrer la phrase secrète pour déverrouiller la clef secrète "
+"OpenPGP :"
+
+msgid "Please enter the passphrase to import the OpenPGP secret key:"
+msgstr ""
+"Veuillez entrer la phrase secrète pour importer la clef secrète OpenPGP :"
+
+msgid "Please enter the passphrase to export the OpenPGP secret subkey:"
+msgstr ""
+"Veuillez entrer la phrase secrète pour exporter la sous-clef secrète "
+"OpenPGP :"
+
+msgid "Please enter the passphrase to export the OpenPGP secret key:"
+msgstr ""
+"Veuillez entrer la phrase secrète pour exporter la clef secrète OpenPGP :"
+
+# NOTE:  s/subkey key/subkey/
+msgid "Do you really want to permanently delete the OpenPGP secret subkey key:"
+msgstr ""
+"Voulez-vous vraiment supprimer de façon permanente la sous-clef secrète "
+"OpenPGP :"
+
+msgid "Do you really want to permanently delete the OpenPGP secret key:"
+msgstr ""
+"Voulez-vous vraiment supprimer de façon permanente la clef secrète OpenPGP :"
+
+#, c-format
+msgid ""
+"%s\n"
+"\"%.*s\"\n"
+"%u-bit %s key, ID %s,\n"
+"created %s%s.\n"
+"%s"
+msgstr ""
+"%1$s\n"
+"« %3$.*2$s »\n"
+"clef %5$s de %4$u bits, identifiant %6$s,\n"
+"créée le %7$s%8$s.\n"
+"%9$s"
+
+msgid ""
+"\n"
+"Pick an image to use for your photo ID.  The image must be a JPEG file.\n"
+"Remember that the image is stored within your public key.  If you use a\n"
+"very large picture, your key will become very large as well!\n"
 "Keeping the image close to 240x288 is a good size to use.\n"
 msgstr ""
 "\n"
@@ -4514,7 +4551,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Entrez le nom du fichier JPEG pour la photo d'identité : "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "impossible d'ouvrir le fichier JPEG « %s » : %s\n"
 
 #, c-format
@@ -4525,7 +4562,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Voulez-vous vraiment l'utiliser ? (o/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "« %s » n'est pas un fichier JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4535,7 +4572,7 @@ msgid "unable to display photo ID!\n"
 msgstr "impossible d'afficher la photo d'identité.\n"
 
 msgid "No reason specified"
-msgstr "Aucune raison indiquée"
+msgstr "Aucune cause indiquée"
 
 msgid "Key is superseded"
 msgstr "La clef a été remplacée"
@@ -4675,11 +4712,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Remarque : cette clef a été désactivée.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr "Remarque : l'adresse vérifiée du signataire est « %s »\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 "Remarque : l'adresse du signataire « %s » ne correspond pas à l'entrée DNS\n"
 
@@ -4722,6 +4759,10 @@ msgid "%s: skipped: %s\n"
 msgstr "%s : ignoré : %s\n"
 
 #, c-format
+msgid "%s: skipped: public key is disabled\n"
+msgstr "%s : ignoré : la clef publique est désactivée\n"
+
+#, c-format
 msgid "%s: skipped: public key already present\n"
 msgstr "%s : ignoré : clef publique déjà présente\n"
 
@@ -4755,10 +4796,6 @@ msgstr "ignoré : clef publique déjà activée\n"
 msgid "unknown default recipient \"%s\"\n"
 msgstr "destinataire par défaut « %s » inconnu\n"
 
-#, c-format
-msgid "%s: skipped: public key is disabled\n"
-msgstr "%s : ignoré : la clef publique est désactivée\n"
-
 msgid "no valid addressees\n"
 msgstr "pas de destinataire valable\n"
 
@@ -4775,6 +4812,10 @@ msgstr ""
 "les données ne sont pas enregistrées ; utilisez l'option « --output » pour\n"
 "les enregistrer\n"
 
+#, c-format
+msgid "error creating '%s': %s\n"
+msgstr "erreur de création de « %s » : %s\n"
+
 msgid "Detached signature.\n"
 msgstr "Signature détachée.\n"
 
@@ -4788,7 +4829,7 @@ msgid "no signed data\n"
 msgstr "pas de données signées\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "impossible d'ouvrir les données signées « %s »\n"
 
 #, c-format
@@ -4817,10 +4858,10 @@ msgstr ""
 "            dans les préférences du destinataire\n"
 
 #, c-format
-msgid "NOTE: secret key %s expired at %s\n"
+msgid "Note: secret key %s expired at %s\n"
 msgstr "Remarque : la clef secrète %s a expiré le %s\n"
 
-msgid "NOTE: key has been revoked"
+msgid "Note: key has been revoked"
 msgstr "Remarque : la clef a été révoquée"
 
 #, c-format
@@ -4855,26 +4896,37 @@ msgstr "Certificat de révocation créé.\n"
 msgid "no revocation keys found for \"%s\"\n"
 msgstr "aucune clef de révocation trouvée pour « %s »\n"
 
+msgid "This is a revocation certificate for the OpenPGP key:"
+msgstr "Ceci est un certificat de révocation pour la clef OpenPGP :"
+
+msgid ""
+"Use it to revoke this key in case of a compromise or loss of\n"
+"the secret key.  However, if the secret key is still accessible,\n"
+"it is better to generate a new revocation certificate and give\n"
+"a reason for the revocation."
+msgstr ""
+"Utilisez-le pour révoquer cette clef en cas de compromis ou de\n"
+"perte de la clef secrète. Cependant, si la clef secrète est\n"
+"encore accessible, créer un nouveau certificat de révocation\n"
+"est préférable afin d’indiquer la cause de révocation."
+
+msgid ""
+"To avoid an accidental use of this file, a colon has been inserted\n"
+"before the 5 dashes below.  Remove this colon with a text editor\n"
+"before making use of this revocation certificate."
+msgstr ""
+"Pour éviter une utilisation accidentelle de ce fichier, un\n"
+"deux-points a été inséré avant les cinq tirets suivants.\n"
+"Supprimez ce deux-points avec un éditeur de texte avant\n"
+"d’utiliser ce certificat de révocation."
+
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
 msgstr "clef secrète « %s » introuvable : %s\n"
 
-#, c-format
-msgid "no corresponding public key: %s\n"
-msgstr "pas de clef publique correspondante : %s\n"
-
-msgid "public key does not match secret key!\n"
-msgstr "la clef publique ne correspond pas à la clef secrète.\n"
-
 msgid "Create a revocation certificate for this key? (y/N) "
 msgstr "Faut-il créer un certificat de révocation pour cette clef ? (o/N) "
 
-msgid "unknown protection algorithm\n"
-msgstr "algorithme de protection inconnu\n"
-
-msgid "NOTE: This key is not protected!\n"
-msgstr "Remarque : cette clef n'est pas protégée.\n"
-
 msgid ""
 "Revocation certificate created.\n"
 "\n"
@@ -4891,7 +4943,8 @@ msgstr ""
 "inutilisable.\n"
 "Imprimer ce certificat et le stocker ailleurs est une bonne idée, au cas où "
 "le\n"
-"support devienne illisible. Attention quand même : le système d'impression\n"
+"support devienne illisible. Attention tout de même : le système "
+"d'impression\n"
 "utilisé pourrait stocker ces données et les rendre accessibles à d'autres.\n"
 
 msgid "Please select the reason for the revocation:\n"
@@ -4918,33 +4971,6 @@ msgstr "(Aucune description donnée)\n"
 msgid "Is this okay? (y/N) "
 msgstr "Est-ce d'accord ? (o/N) "
 
-msgid "secret key parts are not available\n"
-msgstr "des parties de la clef secrète ne sont pas disponibles\n"
-
-#, c-format
-msgid "protection algorithm %d%s is not supported\n"
-msgstr "l'algorithme de protection %d%s n'est pas pris en charge\n"
-
-#, c-format
-msgid "protection digest %d is not supported\n"
-msgstr "le hachage de protection %d n'est pas pris en charge\n"
-
-msgid "Invalid passphrase; please try again"
-msgstr "Phrase secrète incorrecte ; veuillez réessayer"
-
-#, c-format
-msgid "%s ...\n"
-msgstr "%s…\n"
-
-msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr ""
-"Attention : clef faible détectée — modifiez encore la phrase secrète.\n"
-
-msgid "generating the deprecated 16-bit checksum for secret key protection\n"
-msgstr ""
-"génération de la somme de contrôle de 16 bits (obsolète) pour protéger\n"
-"la clef secrète\n"
-
 msgid "weak key created - retrying\n"
 msgstr "clef faible générée — nouvel essai\n"
 
@@ -4954,16 +4980,14 @@ msgstr ""
 "impossible d'éviter une clef faible pour le chiffrement symétrique :\n"
 "%d essais ont eu lieu.\n"
 
-msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA nécessite que la taille du hachage soit un multiple de 8 bits\n"
-
 #, c-format
-msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "la clef DSA %s utilise un hachage non sûr (%u bits)\n"
+msgid "%s key %s uses an unsafe (%zu bit) hash\n"
+msgstr "la clef %s %s utilise un hachage non sûr (%zu bits)\n"
 
 #, c-format
-msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "la clef DSA %s nécessite un hachage d'au moins %u bits\n"
+msgid "%s key %s requires a %zu bit or larger hash (hash is %s)\n"
+msgstr ""
+"la clef %s %s nécessite un hachage d'au moins %zu bits (le hachage est %s)\n"
 
 msgid "WARNING: signature digest conflict in message\n"
 msgstr "Attention : conflit de hachage de signature dans le message\n"
@@ -4974,6 +4998,10 @@ msgstr ""
 "Attention : la sous-clef de signature %s n'a pas de certificat croisé\n"
 
 #, c-format
+msgid "please see %s for more information\n"
+msgstr "veuillez consulter %s pour plus de renseignements\n"
+
+#, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr ""
 "Attention : la sous-clef de signature %s a un certificat croisé incorrect\n"
@@ -5002,11 +5030,11 @@ msgstr ""
 "(faille temporelle ou problème d'horloge)\n"
 
 #, c-format
-msgid "NOTE: signature key %s expired %s\n"
+msgid "Note: signature key %s expired %s\n"
 msgstr "Remarque : la clef de signature %s a expiré le %s\n"
 
 #, c-format
-msgid "NOTE: signature key %s has been revoked\n"
+msgid "Note: signature key %s has been revoked\n"
 msgstr "Remarque : la clef de signature %s a été révoquée\n"
 
 #, c-format
@@ -5056,11 +5084,6 @@ msgstr "échec de vérification de la signature créée : %s\n"
 msgid "%s/%s signature from: \"%s\"\n"
 msgstr "%s/%s signature de : « %s »\n"
 
-msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"une signature détachée avec des clefs de type\n"
-"PGP 2.x n'est possible qu'en mode --pgp2\n"
-
 #, c-format
 msgid ""
 "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
@@ -5071,11 +5094,6 @@ msgstr ""
 msgid "signing:"
 msgstr "signature :"
 
-msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"une signature en texte clair avec des clefs de type\n"
-"PGP 2.x n'est possible qu'en mode --pgp2\n"
-
 #, c-format
 msgid "%s encryption will be used\n"
 msgstr "le chiffrement %s sera utilisé\n"
@@ -5089,10 +5107,6 @@ msgstr ""
 msgid "skipped \"%s\": duplicated\n"
 msgstr "« %s » a été ignorée : en double\n"
 
-#, c-format
-msgid "skipped \"%s\": %s\n"
-msgstr "« %s » a été ignorée : %s\n"
-
 msgid "skipped: secret key already present\n"
 msgstr "ignoré : clef secrète déjà présente\n"
 
@@ -5114,7 +5128,7 @@ msgstr ""
 "# (utilisez « gpg --import-ownertrust » pour les restaurer)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "erreur dans « %s » : %s\n"
 
 msgid "line too long"
@@ -5130,11 +5144,11 @@ msgid "ownertrust value missing"
 msgstr "valeur de confiance au propriétaire manquante"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "impossible de trouver l'enregistrement de confiance dans « %s » : %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "erreur de lecture dans « %s » : %s\n"
 
 #, c-format
@@ -5142,14 +5156,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "base de confiance : échec de synchronisation : %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "impossible de créer un verrou pour « %s »\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "impossible de verrouiller « %s »\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "enregistrement de base de confiance %lu : échec de lseek : %s\n"
 
@@ -5162,12 +5168,20 @@ msgid "trustdb transaction too large\n"
 msgstr "transaction de base de confiance trop grande\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "impossible d'accéder à « %s » : %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s : le répertoire n'existe pas.\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossible d'accéder à « %s » : %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "impossible de créer un verrou pour « %s »\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "impossible de verrouiller « %s »\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5181,7 +5195,7 @@ msgstr "%s : base de confiance incorrecte créée\n"
 msgid "%s: trustdb created\n"
 msgstr "%s : base de confiance créée\n"
 
-msgid "NOTE: trustdb not writable\n"
+msgid "Note: trustdb not writable\n"
 msgstr "Remarque : la base de confiance n'est pas accessible en écriture\n"
 
 #, c-format
@@ -5252,7 +5266,7 @@ msgid "input line longer than %d characters\n"
 msgstr "la ligne d'entrée est plus longue que %d caractères\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "« %s » n'est pas un identifiant valable de clef longue\n"
 
 #, c-format
@@ -5297,53 +5311,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr "utilisation du modèle de confiance %s\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
-msgid "10 translator see trustdb.c:uid_trust_string_fixed"
-msgstr "11 le traducteur a bien lu ce qu'il fallait :)"
-
-msgid "[ revoked]"
-msgstr "[ révoquée]"
-
-msgid "[ expired]"
-msgstr "[ expirée ]"
-
-msgid "[ unknown]"
-msgstr "[ inconnue]"
-
-msgid "[  undef ]"
-msgstr "[indéfinie]"
-
-msgid "[marginal]"
-msgstr "[marginale]"
-
-msgid "[  full  ]"
-msgstr "[  totale ]"
-
-msgid "[ultimate]"
-msgstr "[  ultime ]"
-
-msgid "undefined"
-msgstr "indéfinie"
-
-msgid "never"
-msgstr "jamais"
-
-msgid "marginal"
-msgstr "marginale"
-
-msgid "full"
-msgstr "totale"
-
-msgid "ultimate"
-msgstr "ultime"
-
 msgid "no need for a trustdb check\n"
 msgstr "inutile de vérifier la base de confiance\n"
 
@@ -5352,13 +5319,13 @@ msgid "next trustdb check due at %s\n"
 msgstr "la prochaine vérification de la base de confiance aura lieu le %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr ""
 "inutile de vérifier la base de confiance avec le modèle de\n"
 "     confiance « %s »\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr ""
 "inutile de mettre à jour la base de confiance avec le modèle de\n"
 "     confiance « %s »\n"
@@ -5422,113 +5389,6 @@ msgstr ""
 msgid "can't open fd %d: %s\n"
 msgstr "impossible d'ouvrir le descripteur %d : %s\n"
 
-msgid "argument not expected"
-msgstr "argument inattendu"
-
-msgid "read error"
-msgstr "erreur de lecture"
-
-msgid "keyword too long"
-msgstr "mot-clef trop long"
-
-msgid "missing argument"
-msgstr "argument manquant"
-
-#, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armure incorrecte"
-
-msgid "invalid command"
-msgstr "commande incorrecte"
-
-msgid "invalid alias definition"
-msgstr "définition d'alias incorrecte"
-
-msgid "out of core"
-msgstr "hors limite"
-
-msgid "invalid option"
-msgstr "option incorrecte"
-
-#, c-format
-msgid "missing argument for option \"%.50s\"\n"
-msgstr "argument manquant pour l'option « %.50s »\n"
-
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "argument manquant pour l'option « %.50s »\n"
-
-#, c-format
-msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "l'option « %.50s » n'attend pas d'argument\n"
-
-#, c-format
-msgid "invalid command \"%.50s\"\n"
-msgstr "commande « %.50s » incorrecte\n"
-
-#, c-format
-msgid "option \"%.50s\" is ambiguous\n"
-msgstr "l'option « %.50s » est ambiguë\n"
-
-#, c-format
-msgid "command \"%.50s\" is ambiguous\n"
-msgstr "la commande « %.50s » est ambiguë\n"
-
-msgid "out of core\n"
-msgstr "hors limite\n"
-
-#, c-format
-msgid "invalid option \"%.50s\"\n"
-msgstr "option « %.50s » incorrecte\n"
-
-#, c-format
-msgid "you found a bug ... (%s:%d)\n"
-msgstr "vous avez trouvé un bogue… (%s : %d)\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "conversion de « %s » vers « %s » non disponible\n"
-
-#, c-format
-msgid "iconv_open failed: %s\n"
-msgstr "échec de iconv_open : %s\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "impossible de convertir « %s » en « %s » : %s\n"
-
-#, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "impossible de créer le fichier temporaire « %s » : %s\n"
-
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "erreur d'écriture sur « %s » : %s\n"
-
-#, c-format
-msgid "removing stale lockfile (created by %d)\n"
-msgstr "suppression du vieux fichier verrou (créé par %d)\n"
-
-msgid " - probably dead - removing lock"
-msgstr " — sans doute mort — suppression du verrou"
-
-#, c-format
-msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "attente du verrou (appartenant à %d%s) %s…\n"
-
-msgid "(deadlock?) "
-msgstr "(peut-être un verrou mort) "
-
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "verrou « %s » non effectif : %s\n"
-
-#, c-format
-msgid "waiting for lock %s...\n"
-msgstr "attente du verrou %s…\n"
-
 msgid "set debugging flags"
 msgstr "activer les options de débogage"
 
@@ -5625,6 +5485,9 @@ msgstr "la réponse ne contient pas le module RSA\n"
 msgid "response does not contain the RSA public exponent\n"
 msgstr "la réponse ne contient pas l'exposant public RSA\n"
 
+msgid "response does not contain the EC public point\n"
+msgstr "la réponse ne contient pas le point public EC\n"
+
 #, c-format
 msgid "using default PIN as %s\n"
 msgstr "utilisation du code personnel par défaut en tant que %s\n"
@@ -5816,17 +5679,17 @@ msgstr "refus d'utiliser les commandes d'administration de la carte"
 msgid "use variable length input for pinpad"
 msgstr "utiliser une entrée de taille variable pour le pavé numérique"
 
-msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Utilisation : scdaemon [options] (-h pour l'aide)"
+msgid "Usage: @SCDAEMON@ [options] (-h for help)"
+msgstr "Utilisation : @SCDAEMON@ [options] (-h pour l'aide)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
-"Smartcard daemon for GnuPG\n"
+"Smartcard daemon for @GNUPG@\n"
 msgstr ""
 "Syntaxe : scdaemon [options] [commande [arguments]]\n"
-"Démon de carte à puce pour GnuPG\n"
+"Démon de carte à puce pour @GNUPG@\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 "veuillez utiliser l'option « --daemon » pour exécuter le programme\n"
 "en arrière-plan\n"
@@ -5844,25 +5707,6 @@ msgid "invalid radix64 character %02x skipped\n"
 msgstr "caractère %02x incorrect en radix64, ignoré\n"
 
 #, c-format
-msgid "failed to proxy %s inquiry to client\n"
-msgstr "échec de transfert de la demande %s au client\n"
-
-#, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "pas d'instance de dirmngr en cours d'exécution — démarrage de « %s »\n"
-
-msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "la variable d'environnement DIRMNGR_INFO est mal définie\n"
-
-#, c-format
-msgid "dirmngr protocol version %d is not supported\n"
-msgstr "le protocole dirmngr version %d n'est pas pris en charge\n"
-
-msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr ""
-"impossible de se connecter au dirmngr — essai avec la solution de repli\n"
-
-#, c-format
 msgid "validation model requested by certificate: %s"
 msgstr "modèle de validation demandé par le certificat : %s"
 
@@ -5884,11 +5728,11 @@ msgid "critical marked policy without configured policies"
 msgstr "politique de signature marquée critique sans politiques configurées"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "échec d'ouverture de « %s » : %s\n"
 
-msgid "note: non-critical certificate policy not allowed"
-msgstr "remarque : politique de certificat non critique non autorisée"
+msgid "Note: non-critical certificate policy not allowed"
+msgstr "Remarque : politique de certificat non critique non autorisée"
 
 msgid "certificate policy not allowed"
 msgstr "politique de certificat non autorisée"
@@ -6046,10 +5890,6 @@ msgid "validation model used: %s"
 msgstr "modèle de validation utilisé : %s"
 
 #, c-format
-msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "la clef %s utilise un hachage non sûr (%u bits)\n"
-
-#, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
 msgstr ""
 "un hachage de %1$u bits n'est pas valable pour une clef %3$s de %2$u bits\n"
@@ -6061,7 +5901,7 @@ msgid "none"
 msgstr "aucun"
 
 msgid "[Error - invalid encoding]"
-msgstr "[Erreur — encodage incorrecte]"
+msgstr "[Erreur — encodage incorrect]"
 
 msgid "[Error - out of core]"
 msgstr "[Erreur — hors limite]"
@@ -6129,11 +5969,11 @@ msgid "line %d: no subject name given\n"
 msgstr "ligne %d : aucun nom de sujet donné\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr "ligne %d : étiquette de nom de sujet « %.*s » incorrecte\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr "ligne %d : nom de sujet « %s » incorrect à la position %d\n"
 
 #, c-format
@@ -6141,11 +5981,48 @@ msgid "line %d: not a valid email address\n"
 msgstr "ligne %d : ce n'est pas une adresse électronique valable\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: invalid serial number\n"
+msgstr "ligne %d : numéro de série incorrect\n"
+
+#, c-format
+msgid "line %d: invalid issuer name label '%.*s'\n"
+msgstr "ligne %d : étiquette de nom d'émetteur « %.*s » incorrecte\n"
+
+#, c-format
+msgid "line %d: invalid issuer name '%s' at pos %d\n"
+msgstr "ligne %d : nom d'émetteur « %s » incorrect à la position %d\n"
+
+#, c-format
+msgid "line %d: invalid date given\n"
+msgstr "ligne %d : date donnée incorrect\n"
+
+#, c-format
+msgid "line %d: error getting signing key by keygrip '%s': %s\n"
+msgstr ""
+"ligne %d : erreur de lecture de clef de signature par keygrip « %s » : %s\n"
+
+#, c-format
+msgid "line %d: invalid hash algorithm given\n"
+msgstr "ligne %d : algorithme de hachage donné incorrect\n"
+
+#, c-format
+msgid "line %d: invalid authority-key-id\n"
+msgstr "ligne %d : authority-key-id incorrect\n"
+
+#, c-format
+msgid "line %d: invalid subject-key-id\n"
+msgstr "ligne %d : subject-key-id incorrect\n"
+
+#, c-format
+msgid "line %d: invalid extension syntax\n"
+msgstr "ligne %d : syntaxe d'extension incorrecte\n"
+
+#, c-format
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "ligne %d : erreur de lecture de la clef « %s » sur la carte : %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "ligne %d : erreur de lecture de clef par keygrip « %s » : %s\n"
 
 #, c-format
@@ -6171,15 +6048,6 @@ msgstr "   (%d) Clef existante\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Clef existante sur la carte\n"
 
-msgid "Enter the keygrip: "
-msgstr "Entrez le keygrip : "
-
-msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Ce n'est pas un keygrip valable (40 chiffres hexadécimaux attendus)\n"
-
-msgid "No key with this keygrip\n"
-msgstr "Pas de clef avec ce keygrip\n"
-
 #, c-format
 msgid "error reading the card: %s\n"
 msgstr "erreur de lecture de la carte : %s\n"
@@ -6214,7 +6082,7 @@ msgid "No subject name given\n"
 msgstr "Aucun nom de sujet donné\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr "Étiquette de nom de sujet « %.*s » incorrecte\n"
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6223,7 +6091,7 @@ msgstr "Étiquette de nom de sujet « %.*s » incorrecte\n"
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "Nom de sujet « %s » incorrect\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6244,13 +6112,23 @@ msgstr " (facultatif, terminez par une ligne vide) :\n"
 msgid "Enter URIs"
 msgstr "Entrez les URI"
 
-msgid "Parameters to be used for the certificate request:\n"
-msgstr "Paramètres à utiliser pour la demande de certificat :\n"
+msgid "Create self-signed certificate? (y/N) "
+msgstr "Faut-il créer un certificat autosigné ? (o/N) "
 
-msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr ""
-"Création de la demande de certificat. Cela risque de prendre un peu de "
-"temps…\n"
+msgid "These parameters are used:\n"
+msgstr "Ces paramètres seront utilisés :\n"
+
+msgid "Now creating self-signed certificate.  "
+msgstr "Création de certificat autosigné. "
+
+msgid "Now creating certificate request.  "
+msgstr "Création de la demande de certificat. "
+
+msgid "This may take a while ...\n"
+msgstr "Cela risque de prendre un peu de temps…\n"
+
+msgid "Ready.\n"
+msgstr "Prêt.\n"
 
 msgid "Ready.  You should now send this request to your CA.\n"
 msgstr ""
@@ -6267,7 +6145,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(ça ne ressemble pas à un message chiffré)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "certificat « %s » introuvable : %s\n"
 
 #, c-format
@@ -6275,11 +6153,11 @@ msgid "error locking keybox: %s\n"
 msgstr "erreur de verrouillage du trousseau local : %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "certificat en double « %s » supprimé\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "certificat « %s » supprimé\n"
 
 #, c-format
@@ -6322,9 +6200,6 @@ msgstr "entrée supposée au format base-64"
 msgid "assume input is in binary format"
 msgstr "entrée supposée au format binaire"
 
-msgid "use system's dirmngr if available"
-msgstr "utiliser le dirmngr du système si disponible"
-
 msgid "never consult a CRL"
 msgstr "ne pas consulter liste de révocations de cert."
 
@@ -6376,27 +6251,24 @@ msgstr "|NOM|utiliser l'algorithme de chiffrement NOM"
 msgid "|NAME|use message digest algorithm NAME"
 msgstr "|NOM|utiliser l'algorithme de hachage NOM"
 
-msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Utilisation : gpgsm [options] [fichiers] (-h pour l'aide)"
+msgid "Usage: @GPGSM@ [options] [files] (-h for help)"
+msgstr "Utilisation : @GPGSM@ [options] [fichiers] (-h pour l'aide)"
 
 msgid ""
-"Syntax: gpgsm [options] [files]\n"
+"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 ""
-"Syntaxe : gpgsm [options] [fichiers]\n"
+"Syntaxe : @GPGSM@ [options] [fichiers]\n"
 "Signer, vérifier, chiffrer ou déchiffrer en utilisant le protocole S/MIME\n"
 "L'opération par défaut dépend des données entrées\n"
 
-msgid "usage: gpgsm [options] "
-msgstr "utilisation : gpgsm [options] "
-
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "Note: won't be able to encrypt to '%s': %s\n"
 msgstr "Remarque : ne sera pas capable de chiffrer à « %s » : %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "modèle de validation « %s » inconnu\n"
 
 #, c-format
@@ -6414,15 +6286,12 @@ msgstr "%s : %u : ignorer cette ligne\n"
 msgid "could not parse keyserver\n"
 msgstr "impossible d'analyser le serveur de clefs\n"
 
-msgid "WARNING: running with faked system time: "
-msgstr "Attention : exécution avec un système de temps contrefait : "
-
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "importation des certificats commun « %s »\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "impossible de signer en utilisant « %s » : %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6450,14 +6319,6 @@ msgstr "erreur d'importation du certificat : %s\n"
 msgid "error reading input: %s\n"
 msgstr "erreur de lecture de l'entrée : %s\n"
 
-#, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "erreur de création du trousseau local « %s » : %s\n"
-
-#, c-format
-msgid "keybox `%s' created\n"
-msgstr "le trousseau local « %s » a été créé\n"
-
 msgid "failed to get the fingerprint\n"
 msgstr "impossible d'obtenir l'empreinte\n"
 
@@ -6474,101 +6335,1363 @@ msgid "error storing certificate: %s\n"
 msgstr "erreur de stockage du certificat : %s\n"
 
 #, c-format
-msgid "problem re-searching certificate: %s\n"
-msgstr "problème de nouvelle recherche de certificat : %s\n"
+msgid "problem re-searching certificate: %s\n"
+msgstr "problème de nouvelle recherche de certificat : %s\n"
+
+#, c-format
+msgid "error storing flags: %s\n"
+msgstr "erreur de stockage des options : %s\n"
+
+msgid "Error - "
+msgstr "Erreur — "
+
+msgid "GPG_TTY has not been set - using maybe bogus default\n"
+msgstr ""
+"GPG_TTY n'a pas été définie — utilisation de valeurs par défaut "
+"potentiellement inappropriées\n"
+
+#, c-format
+msgid "invalid formatted fingerprint in '%s', line %d\n"
+msgstr "formatage incorrect de l'empreinte dans « %s », ligne %d\n"
+
+#, c-format
+msgid "invalid country code in '%s', line %d\n"
+msgstr "code de pays incorrect dans « %s », ligne %d\n"
+
+#, c-format
+msgid ""
+"You are about to create a signature using your certificate:\n"
+"\"%s\"\n"
+"This will create a qualified signature by law equated to a handwritten "
+"signature.\n"
+"\n"
+"%s%sAre you really sure that you want to do this?"
+msgstr ""
+"Vous êtes sur le point de créer une signature en utilisant votre "
+"certificat :\n"
+"« %s »\n"
+"Cela va créer une signature qualifiée équivalente légalement à une signature "
+"à la main.\n"
+"\n"
+"%s%sVoulez-vous vraiment faire cela ?"
+
+msgid ""
+"Note, that this software is not officially approved to create or verify such "
+"signatures.\n"
+msgstr ""
+"Remarquez que ce programme n'est pas officiellement approuvé pour créer ou "
+"vérifier de telles signatures.\n"
+
+#, c-format
+msgid ""
+"You are about to create a signature using your certificate:\n"
+"\"%s\"\n"
+"Note, that this certificate will NOT create a qualified signature!"
+msgstr ""
+"Vous êtes sur le point de créer une signature en utilisant votre "
+"certificat :\n"
+"« %s »\n"
+"Remarquez que ce certificat ne va pas créer de signature qualifiée."
+
+#, c-format
+msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
+msgstr ""
+"l'algorithme de hachage %d (%s) pour le signataire %d n'est pas pris en "
+"charge ; utilisation de %s\n"
+
+#, c-format
+msgid "hash algorithm used for signer %d: %s (%s)\n"
+msgstr "algorithme de hachage utilisé pour le signataire %d : %s (%s)\n"
+
+#, c-format
+msgid "checking for qualified certificate failed: %s\n"
+msgstr "échec de vérification de certificat qualifié : %s\n"
+
+msgid "Signature made "
+msgstr "Signature faite le "
+
+msgid "[date not given]"
+msgstr "[date non donnée]"
+
+#, c-format
+msgid " using certificate ID 0x%08lX\n"
+msgstr " en utilisant le certificat d'identifiant 0x%08lX\n"
+
+msgid ""
+"invalid signature: message digest attribute does not match computed one\n"
+msgstr ""
+"signature incorrecte : l'attribut de hachage du message ne correspond pas à "
+"celui calculé\n"
+
+msgid "Good signature from"
+msgstr "Bonne signature de"
+
+msgid "                aka"
+msgstr "                alias"
+
+msgid "This is a qualified signature\n"
+msgstr "C'est une signature qualifiée\n"
+
+#, c-format
+msgid "can't initialize certificate cache lock: %s\n"
+msgstr "impossible d'initialiser le verrou du cache de certificat : %s\n"
+
+#, c-format
+msgid "can't acquire read lock on the certificate cache: %s\n"
+msgstr ""
+"impossible d'obtenir le verrou de lecture du cache de certificat : %s\n"
+
+#, c-format
+msgid "can't acquire write lock on the certificate cache: %s\n"
+msgstr ""
+"impossible d'obtenir le verrou d'écriture du cache de certificat : %s\n"
+
+#, c-format
+msgid "can't release lock on the certificate cache: %s\n"
+msgstr "impossible de libérer le verrou du cache de certificat : %s\n"
+
+#, c-format
+msgid "dropping %u certificates from the cache\n"
+msgstr "abandon de %u certificats du cache\n"
+
+#, c-format
+msgid "can't access directory '%s': %s\n"
+msgstr "impossible d'accéder au répertoire « %s » : %s\n"
+
+#, c-format
+msgid "can't parse certificate '%s': %s\n"
+msgstr "impossible d'analyser le certificat « %s » : %s\n"
+
+#, c-format
+msgid "certificate '%s' already cached\n"
+msgstr "certificat « %s » déjà en cache\n"
+
+#, c-format
+msgid "trusted certificate '%s' loaded\n"
+msgstr "certificat de confiance « %s » chargé\n"
+
+#, c-format
+msgid "certificate '%s' loaded\n"
+msgstr "certificat « %s » chargé\n"
+
+#, c-format
+msgid "  SHA1 fingerprint = %s\n"
+msgstr "  empreinte SHA1 = %s\n"
+
+msgid "   issuer ="
+msgstr " émetteur ="
+
+msgid "  subject ="
+msgstr "    sujet ="
+
+#, c-format
+msgid "error loading certificate '%s': %s\n"
+msgstr "erreur de chargement du certificat « %s » : %s\n"
+
+#, c-format
+msgid "permanently loaded certificates: %u\n"
+msgstr "certificats chargés de façon permanente : %u\n"
+
+#, c-format
+msgid "    runtime cached certificates: %u\n"
+msgstr "      certificats actuellement en cache : %u\n"
+
+msgid "certificate already cached\n"
+msgstr "certificat déjà en cache\n"
+
+msgid "certificate cached\n"
+msgstr "certificat en cache\n"
+
+#, c-format
+msgid "error caching certificate: %s\n"
+msgstr "erreur de mise en cache du certificat : %s\n"
+
+#, c-format
+msgid "invalid SHA1 fingerprint string '%s'\n"
+msgstr "chaîne « %s » d'empreinte SHA1 incorrecte\n"
+
+#, c-format
+msgid "error fetching certificate by S/N: %s\n"
+msgstr "erreur de récupération du certificat par numéro de série : %s\n"
+
+#, c-format
+msgid "error fetching certificate by subject: %s\n"
+msgstr "erreur de récupération du certificat par sujet : %s\n"
+
+msgid "no issuer found in certificate\n"
+msgstr "aucun émetteur trouvé dans le certificat\n"
+
+#, c-format
+msgid "error getting authorityKeyIdentifier: %s\n"
+msgstr "erreur de lecture d'authorityKeyIdentifier : %s\n"
+
+#, c-format
+msgid "creating directory '%s'\n"
+msgstr "création du répertoire « %s »\n"
+
+#, c-format
+msgid "error creating directory '%s': %s\n"
+msgstr "erreur de création du répertoire « %s » : %s\n"
+
+#, c-format
+msgid "ignoring database dir '%s'\n"
+msgstr "répertoire de base de données « %s » ignoré\n"
+
+#, c-format
+msgid "error reading directory '%s': %s\n"
+msgstr "erreur de lecture du répertoire « %s » : %s\n"
+
+#, c-format
+msgid "removing cache file '%s'\n"
+msgstr "suppression du fichier de cache « %s »\n"
+
+#, c-format
+msgid "not removing file '%s'\n"
+msgstr "pas de suppression du fichier « %s »\n"
+
+#, c-format
+msgid "error closing cache file: %s\n"
+msgstr "erreur de fermeture du fichier de cache : %s\n"
+
+#, c-format
+msgid "failed to open cache dir file '%s': %s\n"
+msgstr "échec d'ouverture du répertoire de cache « %s » : %s\n"
+
+#, c-format
+msgid "error creating new cache dir file '%s': %s\n"
+msgstr "erreur de création du nouveau répertoire de cache « %s » : %s\n"
+
+#, c-format
+msgid "error writing new cache dir file '%s': %s\n"
+msgstr "erreur d'écriture du nouveau répertoire de cache « %s » : %s\n"
+
+#, c-format
+msgid "error closing new cache dir file '%s': %s\n"
+msgstr "erreur de fermeture du nouveau répertoire de cache « %s » : %s\n"
+
+#, c-format
+msgid "new cache dir file '%s' created\n"
+msgstr "nouveau répertoire de cache « %s » créé\n"
+
+#, c-format
+msgid "failed to re-open cache dir file '%s': %s\n"
+msgstr "échec de réouverture du répertoire de cache « %s » : %s\n"
+
+#, c-format
+msgid "first record of '%s' is not the version\n"
+msgstr "le premier enregistrement de « %s » n'est pas la version\n"
+
+msgid "old version of cache directory - cleaning up\n"
+msgstr "ancienne version du répertoire de cache — nettoyage\n"
+
+msgid "old version of cache directory - giving up\n"
+msgstr "ancienne version du répertoire de cache — abandon\n"
+
+#, c-format
+msgid "extra field detected in crl record of '%s' line %u\n"
+msgstr ""
+"champ supplémentaire détecté dans l'enregistrement de liste de révocations "
+"de certificat de « %s » ligne %u\n"
+
+#, c-format
+msgid "invalid line detected in '%s' line %u\n"
+msgstr "ligne incorrecte détectée dans « %s » ligne %u\n"
+
+#, c-format
+msgid "duplicate entry detected in '%s' line %u\n"
+msgstr "entrée en double détectée dans « %s » ligne %u\n"
+
+#, c-format
+msgid "unsupported record type in '%s' line %u skipped\n"
+msgstr "type d'enregistrement non pris en charge dans « %s » ligne %u ignoré\n"
+
+#, c-format
+msgid "invalid issuer hash in '%s' line %u\n"
+msgstr "hachage d'émetteur incorrect dans « %s » ligne %u\n"
+
+#, c-format
+msgid "no issuer DN in '%s' line %u\n"
+msgstr "aucun DN d'émetteur dans « %s » ligne %u\n"
+
+#, c-format
+msgid "invalid timestamp in '%s' line %u\n"
+msgstr "date incorrecte dans « %s » ligne %u\n"
+
+#, c-format
+msgid "WARNING: invalid cache file hash in '%s' line %u\n"
+msgstr ""
+"Attention : hachage de fichier de cache incorrect dans « %s » ligne %u\n"
+
+msgid "detected errors in cache dir file\n"
+msgstr "erreurs détectées dans le répertoire de cache\n"
+
+msgid "please check the reason and manually delete that file\n"
+msgstr "veuillez vérifier la raison et effacer vous-même ce fichier\n"
+
+#, c-format
+msgid "failed to create temporary cache dir file '%s': %s\n"
+msgstr "impossible de créer le répertoire de cache temporaire « %s » : %s\n"
+
+#, c-format
+msgid "error closing '%s': %s\n"
+msgstr "erreur de fermeture de « %s » : %s\n"
+
+#, c-format
+msgid "error renaming '%s' to '%s': %s\n"
+msgstr "erreur en renommant « %s » en « %s » : %s\n"
+
+#, c-format
+msgid "can't hash '%s': %s\n"
+msgstr "impossible de hacher « %s » : %s\n"
+
+#, c-format
+msgid "error setting up MD5 hash context: %s\n"
+msgstr "erreur de configuration du contexte de hachage MD5 : %s\n"
+
+#, c-format
+msgid "error hashing '%s': %s\n"
+msgstr "erreur du hachage de « %s » : %s\n"
+
+#, c-format
+msgid "invalid formatted checksum for '%s'\n"
+msgstr "formatage incorrect de la somme de contrôle pour « %s »\n"
+
+msgid "too many open cache files; can't open anymore\n"
+msgstr "trop de fichiers de cache ouverts ; impossible d'en ouvrir plus\n"
+
+#, c-format
+msgid "opening cache file '%s'\n"
+msgstr "ouverture du fichier de cache « %s »\n"
+
+#, c-format
+msgid "error opening cache file '%s': %s\n"
+msgstr "erreur d'ouverture du fichier de cache « %s » : %s\n"
+
+#, c-format
+msgid "error initializing cache file '%s' for reading: %s\n"
+msgstr "erreur d'initialisation du fichier de cache « %s » en lecture : %s\n"
+
+msgid "calling unlock_db_file on a closed file\n"
+msgstr "appel d'unlock_db_file sur un fichier fermé\n"
+
+msgid "calling unlock_db_file on an unlocked file\n"
+msgstr "appel d'unlock_db_file sur un fichier déverrouillé\n"
+
+#, c-format
+msgid "failed to create a new cache object: %s\n"
+msgstr "échec de création d'un nouvel objet de cache : %s\n"
+
+#, c-format
+msgid "no CRL available for issuer id %s\n"
+msgstr ""
+"pas de liste de révocations de certificat disponible pour l'identifiant "
+"d'émetteur %s\n"
+
+#, c-format
+msgid "cached CRL for issuer id %s too old; update required\n"
+msgstr ""
+"la liste de révocations de certificat en cache pour l'identifiant d'émetteur "
+"%s est trop ancienne ; mise à jour nécessaire\n"
+
+#, c-format
+msgid ""
+"force-crl-refresh active and %d minutes passed for issuer id %s; update "
+"required\n"
+msgstr ""
+"force-crl-refresh activé et %d minutes se sont écoulées pour l'identifiant "
+"d'émetteur %s ; mise à jour nécessaire\n"
+
+#, c-format
+msgid "force-crl-refresh active for issuer id %s; update required\n"
+msgstr ""
+"force-crl-refresh activé pour l'identifiant d'émetteur %s ; mise à jour "
+"nécessaire\n"
+
+#, c-format
+msgid "available CRL for issuer ID %s can't be used\n"
+msgstr ""
+"la liste de révocations de certificat pour l'identifiant d'émetteur %s ne "
+"peut pas être utilisée\n"
+
+#, c-format
+msgid "cached CRL for issuer id %s tampered; we need to update\n"
+msgstr ""
+"la liste de révocations de certificat en cache pour l'identifiant d'émetteur "
+"%s a été modifiée ; mise à jour nécessaire\n"
+
+msgid "WARNING: invalid cache record length for S/N "
+msgstr ""
+"Attention : taille d'enregistrement de cache incorrecte pour le numéro de "
+"série "
+
+#, c-format
+msgid "problem reading cache record for S/N %s: %s\n"
+msgstr ""
+"problème de lecture d'enregistrement de cache pour le numéro de série %s : "
+"%s\n"
+
+#, c-format
+msgid "S/N %s is not valid; reason=%02X  date=%.15s\n"
+msgstr "le numéro de série %s est incorrect ; raison=%02X  date=%.15s\n"
+
+#, c-format
+msgid "S/N %s is valid, it is not listed in the CRL\n"
+msgstr ""
+"le numéro de série %s est valable, il ne fait pas partie de la liste de "
+"révocation de certificats\n"
+
+#, c-format
+msgid "error getting data from cache file: %s\n"
+msgstr "erreur de lecture des données du fichier de cache : %s\n"
+
+#, c-format
+msgid "unknown hash algorithm '%s'\n"
+msgstr "algorithme de hachage « %s » inconnu\n"
+
+#, c-format
+msgid "gcry_md_open for algorithm %d failed: %s\n"
+msgstr "échec de gcry_md_open pour l'algorithme %d : %s\n"
+
+msgid "got an invalid S-expression from libksba\n"
+msgstr "expression symbolique incorrecte obtenue de libksba\n"
+
+#, c-format
+msgid "converting S-expression failed: %s\n"
+msgstr "échec de conversion d'expression symbolique : %s\n"
+
+#, c-format
+msgid "creating S-expression failed: %s\n"
+msgstr "échec de création d'expression symbolique : %s\n"
+
+#, c-format
+msgid "ksba_crl_parse failed: %s\n"
+msgstr "échec de ksba_crl_parse : %s\n"
+
+#, c-format
+msgid "error getting update times of CRL: %s\n"
+msgstr ""
+"erreur de lecture des dates de mises à jour de la liste de révocations de "
+"certificat : %s\n"
+
+#, c-format
+msgid "update times of this CRL: this=%s next=%s\n"
+msgstr ""
+"dates de mises à jour de la liste de révocations de certificat : celle-ci=%s "
+"prochaine=%s\n"
+
+msgid "nextUpdate not given; assuming a validity period of one day\n"
+msgstr "nextUpdate non donné ; période de validité supposée d'un jour\n"
+
+#, c-format
+msgid "error getting CRL item: %s\n"
+msgstr ""
+"erreur de lecture de l'élément de liste de révocations de certificat : %s\n"
+
+#, c-format
+msgid "error inserting item into temporary cache file: %s\n"
+msgstr "erreur d'insertion d'élément dans le fichier cache temporaire : %s\n"
+
+#, c-format
+msgid "no CRL issuer found in CRL: %s\n"
+msgstr ""
+"aucun émetteur de liste de révocations de certificat trouvé dans la liste : "
+"%s\n"
+
+msgid "locating CRL issuer certificate by authorityKeyIdentifier\n"
+msgstr ""
+"localisation du certificat d'émetteur de liste de révocations par "
+"authorityKeyIdentifier\n"
+
+#, c-format
+msgid "CRL signature verification failed: %s\n"
+msgstr ""
+"échec de vérification de signature de liste de révocations de certificat : "
+"%s\n"
+
+#, c-format
+msgid "error checking validity of CRL issuer certificate: %s\n"
+msgstr ""
+"erreur de vérification de la validité du certificat d'émetteur de liste de "
+"révocations : %s\n"
+
+#, c-format
+msgid "ksba_crl_new failed: %s\n"
+msgstr "échec de ksba_crl_new : %s\n"
+
+#, c-format
+msgid "ksba_crl_set_reader failed: %s\n"
+msgstr "échec de ksba_crl_set_reader : %s\n"
+
+#, c-format
+msgid "removed stale temporary cache file '%s'\n"
+msgstr "vieux fichier de cache temporaire « %s » supprimé\n"
+
+#, c-format
+msgid "problem removing stale temporary cache file '%s': %s\n"
+msgstr ""
+"problème de suppression du vieux fichier de cache temporaire « %s » : %s\n"
+
+#, c-format
+msgid "error creating temporary cache file '%s': %s\n"
+msgstr "erreur de création du fichier de cache temporaire « %s » : %s\n"
+
+#, c-format
+msgid "crl_parse_insert failed: %s\n"
+msgstr "échec de crl_parse_insert : %s\n"
+
+#, c-format
+msgid "error finishing temporary cache file '%s': %s\n"
+msgstr "erreur de finalisation du fichier de cache temporaire « %s » : %s\n"
+
+#, c-format
+msgid "error closing temporary cache file '%s': %s\n"
+msgstr "erreur de fermeture du fichier de cache temporaire « %s » : %s\n"
+
+#, c-format
+msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n"
+msgstr ""
+"Attention : la nouvelle liste de révocations de certificat est trop "
+"ancienne ; elle a expiré le %s — chargement quand même\n"
+
+#, c-format
+msgid "new CRL still too old; it expired on %s\n"
+msgstr ""
+"la nouvelle liste de révocations de certificat est trop ancienne ; elle a "
+"expiré le %s\n"
+
+#, c-format
+msgid "unknown critical CRL extension %s\n"
+msgstr "extension %s de liste de révocations de certificat critique inconnue\n"
+
+#, c-format
+msgid "error reading CRL extensions: %s\n"
+msgstr ""
+"erreur de lecture des extensions de liste de révocations de certificat : %s\n"
+
+#, c-format
+msgid "creating cache file '%s'\n"
+msgstr "création du fichier de cache « %s »\n"
+
+#, c-format
+msgid "problem renaming '%s' to '%s': %s\n"
+msgstr "problème en renommant « %s » en « %s » : %s\n"
+
+msgid ""
+"updating the DIR file failed - cache entry will get lost with the next "
+"program start\n"
+msgstr ""
+"échec de mise à jour du fichier DIR — l'entrée de cache sera perdue avec le "
+"prochain démarrage du programme\n"
+
+#, c-format
+msgid "Begin CRL dump (retrieved via %s)\n"
+msgstr ""
+"Démarrage du vidage de liste de révocations de certificat (récupérée par "
+"%s)\n"
+
+msgid ""
+" ERROR: The CRL will not be used because it was still too old after an "
+"update!\n"
+msgstr ""
+" Erreur : la liste de révocations de certificat ne sera pas utilisée car "
+"elle était encore trop ancienne après une mise à jour.\n"
+
+msgid ""
+" ERROR: The CRL will not be used due to an unknown critical extension!\n"
+msgstr ""
+" Erreur : la liste de révocations de certificat ne sera pas utilisée à cause "
+"d'une extension critique inconnue.\n"
+
+msgid " ERROR: The CRL will not be used\n"
+msgstr ""
+" Erreur : la liste de révocations de certificat ne sera pas utilisée.\n"
+
+msgid " ERROR: This cached CRL may have been tampered with!\n"
+msgstr ""
+" Erreur : cette liste de révocations de certificat en cache a pu être "
+"modifiée.\n"
+
+msgid " WARNING: invalid cache record length\n"
+msgstr " Attention : taille d'enregistrement de cache incorrecte\n"
+
+#, c-format
+msgid "problem reading cache record: %s\n"
+msgstr "problème de lecture d'enregistrement de cache : %s\n"
+
+#, c-format
+msgid "problem reading cache key: %s\n"
+msgstr "problème de lecture d'enregistrement de clef : %s\n"
+
+#, c-format
+msgid "error reading cache entry from db: %s\n"
+msgstr "erreur de lecture de l'entrée de cache dans la base de données : %s\n"
+
+msgid "End CRL dump\n"
+msgstr "Fin du vidage de liste de révocations de certificat\n"
+
+#, c-format
+msgid "crl_fetch via DP failed: %s\n"
+msgstr "échec de crl_fetch par points de distribution : %s\n"
+
+#, c-format
+msgid "crl_cache_insert via DP failed: %s\n"
+msgstr "échec de crl_cache_insert par points de distribution : %s\n"
+
+#, c-format
+msgid "crl_cache_insert via issuer failed: %s\n"
+msgstr "échec de crl_cache_insert par émetteur : %s\n"
+
+msgid "reader to file mapping table full - waiting\n"
+msgstr "table de projection de lecteur vers fichier pleine — attente\n"
+
+msgid "using \"http\" instead of \"https\"\n"
+msgstr "utilisation d'« http » au lieu d'« https »\n"
+
+#, c-format
+msgid "CRL access not possible due to disabled %s\n"
+msgstr ""
+"accès à la liste de révocations de certificat impossible car %s est "
+"désactivé\n"
+
+#, c-format
+msgid "error initializing reader object: %s\n"
+msgstr "erreur d'initialisation de l'objet lecteur : %s\n"
+
+#, c-format
+msgid "URL '%s' redirected to '%s' (%u)\n"
+msgstr "URL « %s » redirigée vers « %s » (%u)\n"
+
+msgid "too many redirections\n"
+msgstr "trop de redirections\n"
+
+#, c-format
+msgid "error retrieving '%s': %s\n"
+msgstr "erreur de récupération de « %s » : %s\n"
+
+#, c-format
+msgid "error retrieving '%s': http status %u\n"
+msgstr "erreur de récupération de « %s » : état HTTP %u\n"
+
+#, c-format
+msgid "certificate search not possible due to disabled %s\n"
+msgstr "recherche de certificats impossible car %s est désactivé\n"
+
+msgid "use OCSP instead of CRLs"
+msgstr "utiliser OCSP au lieu des listes de révocations de certificat"
+
+msgid "check whether a dirmngr is running"
+msgstr "vérifier si une instance de dirmngr fonctionne"
+
+msgid "add a certificate to the cache"
+msgstr "ajouter un certificat au cache"
+
+msgid "validate a certificate"
+msgstr "valider un certificat"
+
+msgid "lookup a certificate"
+msgstr "rechercher un certificat"
+
+msgid "lookup only locally stored certificates"
+msgstr "rechercher seulement les certificats localement"
+
+msgid "expect an URL for --lookup"
+msgstr "exiger une URL pour --lookup"
+
+msgid "load a CRL into the dirmngr"
+msgstr "charger une liste de rév. de cert. dans dirmngr"
+
+msgid "special mode for use by Squid"
+msgstr "mode spécial pour être utilisé par Squid"
+
+msgid "expect certificates in PEM format"
+msgstr "attendre les certificats au format PEM"
+
+msgid "force the use of the default OCSP responder"
+msgstr "forcer utilisation du répondeur OCSP par défaut"
+
+msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n"
+msgstr ""
+"Utilisation : dirmngr-client [options] [fic_cert|motif] (-h pour l'aide)\n"
+
+msgid ""
+"Syntax: dirmngr-client [options] [certfile|pattern]\n"
+"Test an X.509 certificate against a CRL or do an OCSP check\n"
+"The process returns 0 if the certificate is valid, 1 if it is\n"
+"not valid and other error codes for general failures\n"
+msgstr ""
+"Syntaxe : dirmngr-client [options] [fic_cert|motif]\n"
+"Vérifier un certificat X.509 par rapport à une liste de\n"
+"révocations de certificat ou faire une vérification OCSP\n"
+"Le processus renvoie 0 si le certificat est valable, 1 s'il est\n"
+"incorrect et d'autres codes d'erreurs pour les problèmes globaux\n"
+
+#, c-format
+msgid "error reading certificate from stdin: %s\n"
+msgstr "erreur de lecture du certificat sur l'entrée standard : %s\n"
+
+#, c-format
+msgid "error reading certificate from '%s': %s\n"
+msgstr "erreur de lecture du certificat sur « %s » : %s\n"
+
+msgid "certificate too large to make any sense\n"
+msgstr "certificat trop grand pour être possible\n"
+
+#, c-format
+msgid "lookup failed: %s\n"
+msgstr "échec de la recherche : %s\n"
+
+#, c-format
+msgid "loading CRL '%s' failed: %s\n"
+msgstr ""
+"échec de chargement de la liste de révocations de certificat « %s » : %s\n"
+
+msgid "a dirmngr daemon is up and running\n"
+msgstr "un démon dirmngr fonctionne et est disponible\n"
+
+#, c-format
+msgid "validation of certificate failed: %s\n"
+msgstr "échec de validation du certificat : %s\n"
+
+msgid "certificate is valid\n"
+msgstr "le certificat est valable\n"
+
+msgid "certificate has been revoked\n"
+msgstr "le certificat a été révoquée\n"
+
+#, c-format
+msgid "certificate check failed: %s\n"
+msgstr "échec de vérification du certificat : %s\n"
+
+#, c-format
+msgid "got status: '%s'\n"
+msgstr "état obtenu : « %s »\n"
+
+#, c-format
+msgid "error writing base64 encoding: %s\n"
+msgstr "erreur d'écriture en encodage base64 : %s\n"
+
+#, c-format
+msgid "failed to allocate assuan context: %s\n"
+msgstr "échec d'allocation du contexte Assuan : %s\n"
+
+msgid "apparently no running dirmngr\n"
+msgstr "pas d'instance de dirmngr en cours d'exécution apparemment\n"
+
+msgid "no running dirmngr - starting one\n"
+msgstr ""
+"pas d'instance de dirmngr en cours d'exécution —\n"
+"démarrage d'une nouvelle instance\n"
+
+#, c-format
+msgid "malformed %s environment variable\n"
+msgstr "la variable d'environnement %s est mal définie\n"
+
+#, c-format
+msgid "dirmngr protocol version %d is not supported\n"
+msgstr "le protocole dirmngr version %d n'est pas pris en charge\n"
+
+msgid "can't connect to the dirmngr - trying fall back\n"
+msgstr ""
+"impossible de se connecter au dirmngr — essai avec la solution de repli\n"
+
+#, c-format
+msgid "can't connect to the dirmngr: %s\n"
+msgstr "impossible de se connecter au dirmngr : %s\n"
+
+#, c-format
+msgid "unsupported inquiry '%s'\n"
+msgstr "demande « %s » non prise en charge\n"
+
+msgid "absolute file name expected\n"
+msgstr "nom de fichier absolu attendu\n"
+
+#, c-format
+msgid "looking up '%s'\n"
+msgstr "recherche de « %s »\n"
+
+msgid "run as windows service (background)"
+msgstr "exécuter en service Windows (arrière-plan)"
+
+msgid "list the contents of the CRL cache"
+msgstr "afficher le contenu du cache de la liste de révocations de certificat"
+
+msgid "|FILE|load CRL from FILE into cache"
+msgstr ""
+"|FICHIER|charger la liste de révocations de certificat du FICHIER dans le "
+"cache"
+
+msgid "|URL|fetch a CRL from URL"
+msgstr "|URL|récupérer une liste de révocations de certificat d'une URL"
+
+msgid "shutdown the dirmngr"
+msgstr "arrêter le dirmngr"
+
+msgid "flush the cache"
+msgstr "vider le cache"
+
+msgid "|FILE|write server mode logs to FILE"
+msgstr "|FICHIER|écrire les journaux serveur dans le FICHIER"
+
+msgid "run without asking a user"
+msgstr "exécuter sans demander à l'utilisateur"
+
+msgid "force loading of outdated CRLs"
+msgstr "forcer le chargement des listes de révocations de certificat obsolètes"
+
+msgid "allow sending OCSP requests"
+msgstr "permettre l'envoi de requêtes OCSP"
+
+msgid "inhibit the use of HTTP"
+msgstr "interdire l'utilisation d'HTTP"
+
+msgid "inhibit the use of LDAP"
+msgstr "interdire l'utilisation de LDAP"
+
+msgid "ignore HTTP CRL distribution points"
+msgstr ""
+"ignorer les points de distribution de liste de révocations de certificat en "
+"HTTP"
+
+msgid "ignore LDAP CRL distribution points"
+msgstr ""
+"ignorer les points de distribution de liste de révocations de certificat en "
+"LDAP"
+
+msgid "ignore certificate contained OCSP service URLs"
+msgstr "ignorer les URL de service OCSP contenues dans le certificat"
+
+msgid "|URL|redirect all HTTP requests to URL"
+msgstr "|URL|rediriger toutes les requêtes HTTP vers l'URL"
+
+msgid "|HOST|use HOST for LDAP queries"
+msgstr "|HÔTE|utiliser l'HÔTE pour les requêtes LDAP"
+
+msgid "do not use fallback hosts with --ldap-proxy"
+msgstr "ne pas utiliser d'hôtes de repli avec --ldap-proxy"
+
+msgid "|FILE|read LDAP server list from FILE"
+msgstr "|FICHIER|lire la liste de serveurs LDAP depuis le FICHIER"
+
+msgid "add new servers discovered in CRL distribution points to serverlist"
+msgstr ""
+"ajouter les nouveaux serveurs découverts dans les points de distribution de "
+"liste de révocations de certificat à la liste de serveurs"
+
+msgid "|N|set LDAP timeout to N seconds"
+msgstr "|N|définir le temps d'expiration de LDAP à N secondes"
+
+msgid "|URL|use OCSP responder at URL"
+msgstr "|URL|utiliser le répondeur OCSP à l'URL"
+
+msgid "|FPR|OCSP response signed by FPR"
+msgstr "|EMPR|réponse OCSP signée par EMPR"
+
+msgid "|N|do not return more than N items in one query"
+msgstr "|N|ne pas renvoyer plus de N éléments dans une requête"
+
+msgid "|FILE|use the CA certificates in FILE for HKP over TLS"
+msgstr "|FICHIER|utiliser les certificats de CA dans FICHIER pour HKP par TLS"
+
+msgid ""
+"@\n"
+"(See the \"info\" manual for a complete listing of all commands and "
+"options)\n"
+msgstr ""
+"@\n"
+"(Consultez le manuel « info » pour obtenir une liste complète des commandes\n"
+"et options)\n"
+
+msgid "Usage: @DIRMNGR@ [options] (-h for help)"
+msgstr "Utilisation : @DIRMNGR@ [options] (-h pour l'aide)"
+
+msgid ""
+"Syntax: @DIRMNGR@ [options] [command [args]]\n"
+"Keyserver, CRL, and OCSP access for @GNUPG@\n"
+msgstr ""
+"Syntaxe : @DIRMNGR@ [options] [commande [arguments]]\n"
+"Serveur de clefs, liste de révocations de certificat et accès OCSP pour "
+"@GNUPG@\n"
+
+#, c-format
+msgid "valid debug levels are: %s\n"
+msgstr "les niveaux de débogage possibles sont : %s\n"
+
+#, c-format
+msgid "usage: %s [options] "
+msgstr "utilisation : %s [options] "
+
+msgid "colons are not allowed in the socket name\n"
+msgstr "les deux-points ne sont pas permis dans le nom de socket\n"
+
+#, c-format
+msgid "fetching CRL from '%s' failed: %s\n"
+msgstr ""
+"échec de récupération de liste de révocations de certificat sur « %s » : %s\n"
+
+#, c-format
+msgid "processing CRL from '%s' failed: %s\n"
+msgstr ""
+"échec du traitement de liste de révocations de certificat sur « %s » : %s\n"
+
+#, c-format
+msgid "%s:%u: line too long - skipped\n"
+msgstr "%s : %u : ligne trop longue — ignorée\n"
+
+#, c-format
+msgid "%s:%u: invalid fingerprint detected\n"
+msgstr "%s : %u : empreinte incorrecte détectée\n"
+
+#, c-format
+msgid "%s:%u: read error: %s\n"
+msgstr "%s : %u : erreur de lecture : %s\n"
+
+#, c-format
+msgid "%s:%u: garbage at end of line ignored\n"
+msgstr "%s : %u : fin de ligne inutile ignorée\n"
+
+msgid "SIGHUP received - re-reading configuration and flushing caches\n"
+msgstr "SIGHUP reçu — relecture de la configuration et vidage des caches\n"
+
+msgid "SIGUSR2 received - no action defined\n"
+msgstr "SIGUSR2 reçu — aucune action définie\n"
+
+msgid "SIGTERM received - shutting down ...\n"
+msgstr "SIGTERM reçu — arrêt…\n"
+
+#, c-format
+msgid "SIGTERM received - still %d active connections\n"
+msgstr "SIGTERM reçu — encore %d connexions actives\n"
+
+msgid "shutdown forced\n"
+msgstr "arrêt forcé\n"
+
+msgid "SIGINT received - immediate shutdown\n"
+msgstr "SIGINT reçu — arrêt immédiat\n"
+
+#, c-format
+msgid "signal %d received - no action defined\n"
+msgstr "signal %d reçu — aucune action définie\n"
+
+msgid "return all values in a record oriented format"
+msgstr "renvoyer toutes les valeurs au format enreg."
+
+msgid "|NAME|ignore host part and connect through NAME"
+msgstr "|NOM|ignorer l'hôte et se connecter par NOM"
+
+msgid "|NAME|connect to host NAME"
+msgstr "|NOM|se connecter à l'hôte NOM"
+
+msgid "|N|connect to port N"
+msgstr "|N|se connecter au port N"
+
+msgid "|NAME|use user NAME for authentication"
+msgstr "|NOM|utiliser le NOM d'utilisateur pour authentif."
+
+msgid "|PASS|use password PASS for authentication"
+msgstr "|MDP|utiliser le mot de passe MDP pour authentif."
+
+msgid "take password from $DIRMNGR_LDAP_PASS"
+msgstr "prendre le mot de passe de $DIRMNGR_LDAP_PASS"
+
+msgid "|STRING|query DN STRING"
+msgstr "|CHAÎNE|demander la CHAÎNE DN"
+
+msgid "|STRING|use STRING as filter expression"
+msgstr "|CHAÎNE|utiliser la CHAÎNE comme expression de filtre"
+
+msgid "|STRING|return the attribute STRING"
+msgstr "|CHAÎNE|renvoyer l'attribut CHAÎNE"
+
+msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n"
+msgstr "Utilisation : dirmngr_ldap [options] [URL] (-h pour l'aide)\n"
+
+msgid ""
+"Syntax: dirmngr_ldap [options] [URL]\n"
+"Internal LDAP helper for Dirmngr\n"
+"Interface and options may change without notice\n"
+msgstr ""
+"Syntaxe : dirmngr_ldap [options] [URL]\n"
+"Assistant LDAP interne pour Dirmngr\n"
+"L'interface et les options pourraient changer sans prévenir\n"
+
+#, c-format
+msgid "invalid port number %d\n"
+msgstr "numéro de port %d incorrect\n"
+
+#, c-format
+msgid "scanning result for attribute '%s'\n"
+msgstr "examen de résultat pour l'attribut « %s »\n"
+
+#, c-format
+msgid "error writing to stdout: %s\n"
+msgstr "erreur d'écriture sur la sortie standard : %s\n"
+
+#, c-format
+msgid "          available attribute '%s'\n"
+msgstr "          attribut « %s » disponible\n"
+
+#, c-format
+msgid "attribute '%s' not found\n"
+msgstr "attribut « %s » introuvable\n"
+
+#, c-format
+msgid "found attribute '%s'\n"
+msgstr "attribut « %s » trouvé\n"
+
+#, c-format
+msgid "processing url '%s'\n"
+msgstr "traitement de l'URL « %s »\n"
+
+#, c-format
+msgid "          user '%s'\n"
+msgstr "  utilisateur « %s »\n"
+
+#, c-format
+msgid "          pass '%s'\n"
+msgstr " mot de passe « %s »\n"
+
+#, c-format
+msgid "          host '%s'\n"
+msgstr "         hôte « %s »\n"
+
+#, c-format
+msgid "          port %d\n"
+msgstr "         port %d\n"
+
+#, c-format
+msgid "            DN '%s'\n"
+msgstr "           DN « %s »\n"
+
+#, c-format
+msgid "        filter '%s'\n"
+msgstr "       filtre « %s »\n"
+
+#, c-format
+msgid "          attr '%s'\n"
+msgstr "     attribut « %s »\n"
+
+#, c-format
+msgid "no host name in '%s'\n"
+msgstr "aucun nom d'hôte donné dans « %s »\n"
+
+#, c-format
+msgid "no attribute given for query '%s'\n"
+msgstr "pas d'attribut donné pour la requête « %s »\n"
+
+msgid "WARNING: using first attribute only\n"
+msgstr "Attention : utilisation du premier attribut seulement\n"
+
+#, c-format
+msgid "LDAP init to '%s:%d' failed: %s\n"
+msgstr "échec d'initialisation de LDAP à « %s : %d » : %s\n"
+
+#, c-format
+msgid "binding to '%s:%d' failed: %s\n"
+msgstr "échec du lien de « %s : %d » : %s\n"
+
+#, c-format
+msgid "searching '%s' failed: %s\n"
+msgstr "échec de recherche de « %s » : %s\n"
+
+#, c-format
+msgid "'%s' is not an LDAP URL\n"
+msgstr "« %s » n'est pas une URL LDAP\n"
+
+#, c-format
+msgid "'%s' is an invalid LDAP URL\n"
+msgstr "« %s » est une URL LDAP incorrecte\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "erreur d'allocation de mémoire : %s\n"
+
+#, c-format
+msgid "error printing log line: %s\n"
+msgstr "erreur d'affichage de ligne du journal : %s\n"
+
+#, c-format
+msgid "error reading log from ldap wrapper %d: %s\n"
+msgstr "erreur de lecture du journal par l'enveloppe LDAP %d : %s\n"
+
+#, c-format
+msgid "npth_select failed: %s - waiting 1s\n"
+msgstr "échec de npth_select : %s — attente 1 s\n"
+
+#, c-format
+msgid "ldap wrapper %d ready"
+msgstr "enveloppe LDAP %d prête"
+
+#, c-format
+msgid "ldap wrapper %d ready: timeout\n"
+msgstr "enveloppe LDAP %d prête : temps expiré\n"
+
+#, c-format
+msgid "ldap wrapper %d ready: exitcode=%d\n"
+msgstr "enveloppe LDAP %d prête : exitcode=%d\n"
+
+#, c-format
+msgid "waiting for ldap wrapper %d failed: %s\n"
+msgstr "échec d'attente de l'enveloppe LDAP %d : %s\n"
+
+#, c-format
+msgid "ldap wrapper %d stalled - killing\n"
+msgstr "enveloppe LDAP %d à l'arrêt — le processus va être tué\n"
+
+# NOTE: Incorrectly set as translatable?
+#, c-format
+msgid "error spawning ldap wrapper reaper thread: %s\n"
+msgstr "error spawning ldap wrapper reaper thread: %s\n"
+
+#, c-format
+msgid "reading from ldap wrapper %d failed: %s\n"
+msgstr "échec de lecture par l'enveloppe LDAP %d : %s\n"
+
+#, c-format
+msgid "invalid char 0x%02x in host name - not added\n"
+msgstr "caractère 0x%02x incorrect dans le nom d'hôte — non ajouté\n"
+
+#, c-format
+msgid "adding '%s:%d' to the ldap server list\n"
+msgstr "ajout de « %s : %d » à la liste de serveurs LDAP\n"
+
+#, c-format
+msgid "malloc failed: %s\n"
+msgstr "échec de malloc : %s\n"
+
+#, c-format
+msgid "start_cert_fetch: invalid pattern '%s'\n"
+msgstr "start_cert_fetch : motif « %s » incorrect\n"
+
+msgid "ldap_search hit the size limit of the server\n"
+msgstr "ldap_search a atteint la taille limite du serveur\n"
+
+msgid "invalid canonical S-expression found\n"
+msgstr "expression symbolique canonique incorrecte trouvée\n"
+
+#, c-format
+msgid "gcry_md_open failed: %s\n"
+msgstr "échec de gcry_md_open : %s\n"
+
+#, c-format
+msgid "oops: ksba_cert_hash failed: %s\n"
+msgstr "erreur : échec de ksba_cert_hash : %s\n"
+
+msgid "bad URL encoding detected\n"
+msgstr "mauvais encodage d'URL détecté\n"
+
+#, c-format
+msgid "error reading from responder: %s\n"
+msgstr "erreur de lecture du répondeur : %s\n"
+
+#, c-format
+msgid "response from server too large; limit is %d bytes\n"
+msgstr "réponse trop grande du serveur ; limitée à %d octets.\n"
+
+msgid "OCSP request not possible due to disabled HTTP\n"
+msgstr "requête OCSP impossible car HTTP est désactivé\n"
+
+#, c-format
+msgid "error setting OCSP target: %s\n"
+msgstr "erreur de configuration de la cible OCSP : %s\n"
+
+#, c-format
+msgid "error building OCSP request: %s\n"
+msgstr "erreur de construction de la requête OCSP : %s\n"
+
+#, c-format
+msgid "error connecting to '%s': %s\n"
+msgstr "erreur de connexion à « %s » : %s\n"
+
+#, c-format
+msgid "error reading HTTP response for '%s': %s\n"
+msgstr "erreur de lecture de réponse HTTP pour « %s » : %s\n"
+
+#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "erreur d'accès à « %s » : état HTTP %u\n"
+
+#, c-format
+msgid "error parsing OCSP response for '%s': %s\n"
+msgstr "erreur d'analyse de réponse OCSP pour « %s » : %s\n"
+
+#, c-format
+msgid "OCSP responder at '%s' status: %s\n"
+msgstr "répondeur OCSP à l'état « %s » : %s\n"
+
+#, c-format
+msgid "hashing the OCSP response for '%s' failed: %s\n"
+msgstr "échec de hachage de la réponse OCSP pour « %s » : %s\n"
+
+msgid "not signed by a default OCSP signer's certificate"
+msgstr "non signée par un certificat de signataire OCSP par défaut"
+
+msgid "only SHA-1 is supported for OCSP responses\n"
+msgstr "seul SHA-1 est pris en charge pour les réponses\n"
+
+#, c-format
+msgid "allocating list item failed: %s\n"
+msgstr "erreur d'allocation d'élément de liste : %s\n"
+
+#, c-format
+msgid "error getting responder ID: %s\n"
+msgstr "erreur de lecture de l'identifiant de répondeur : %s\n"
+
+msgid "no suitable certificate found to verify the OCSP response\n"
+msgstr ""
+"aucun certificat convenable n'a été trouvée pour vérifier la réponse OCSP\n"
+
+#, c-format
+msgid "issuer certificate not found: %s\n"
+msgstr "certificat d'émetteur introuvable : %s\n"
+
+msgid "caller did not return the target certificate\n"
+msgstr "l'appelant n'a pas renvoyé le certificat cible\n"
+
+msgid "caller did not return the issuing certificate\n"
+msgstr "l'appelant n'a pas renvoyé le certificat émetteur\n"
+
+#, c-format
+msgid "failed to allocate OCSP context: %s\n"
+msgstr "échec d'allocation du contexte OCSP : %s\n"
+
+#, c-format
+msgid "can't get authorityInfoAccess: %s\n"
+msgstr "impossible d'obtenir authorityInfoAccess : %s\n"
+
+msgid "no default OCSP responder defined\n"
+msgstr "aucun répondeur OCSP par défaut défini\n"
+
+msgid "no default OCSP signer defined\n"
+msgstr "aucun signataire OCSP par défaut défini\n"
+
+#, c-format
+msgid "using default OCSP responder '%s'\n"
+msgstr "utilisation du répondeur OCSP « %s » par défaut\n"
+
+#, c-format
+msgid "using OCSP responder '%s'\n"
+msgstr "utilisation du répondeur OCSP « %s »\n"
+
+#, c-format
+msgid "failed to establish a hashing context for OCSP: %s\n"
+msgstr "échec d'établissement d'un contexte de hachage pour OCSP : %s\n"
+
+#, c-format
+msgid "error getting OCSP status for target certificate: %s\n"
+msgstr "erreur de lecture de l'état OCSP pour le certificat cible : %s\n"
+
+#, c-format
+msgid "certificate status is: %s  (this=%s  next=%s)\n"
+msgstr "l'état du certificat est : %s  (celui-ci=%s  prochain=%s)\n"
+
+msgid "good"
+msgstr "correct"
+
+#, c-format
+msgid "certificate has been revoked at: %s due to: %s\n"
+msgstr "le certificat a été révoquée le : %s à cause de : %s\n"
+
+msgid "OCSP responder returned a status in the future\n"
+msgstr "le répondeur OCSP a renvoyé un état dans le futur\n"
+
+msgid "OCSP responder returned a non-current status\n"
+msgstr "le répondeur OCSP a renvoyé un état non actuel\n"
+
+msgid "OCSP responder returned an too old status\n"
+msgstr "le répondeur OCSP a renvoyé un trop vieil état\n"
+
+#, c-format
+msgid "assuan_inquire(%s) failed: %s\n"
+msgstr "échec d'assuan_inquire(%s) : %s\n"
+
+msgid "ldapserver missing"
+msgstr "ldapserver manquant"
+
+msgid "serialno missing in cert ID"
+msgstr "serialno manquant dans l'identifiant de certificat"
+
+#, c-format
+msgid "assuan_inquire failed: %s\n"
+msgstr "échec d'assuan_inquire : %s\n"
+
+#, c-format
+msgid "fetch_cert_by_url failed: %s\n"
+msgstr "échec de fetch_cert_by_url : %s\n"
+
+#, c-format
+msgid "error sending data: %s\n"
+msgstr "erreur d'envoi de données : %s\n"
 
 #, c-format
-msgid "error storing flags: %s\n"
-msgstr "erreur de stockage des options : %s\n"
+msgid "start_cert_fetch failed: %s\n"
+msgstr "échec de start_cert_fetch : %s\n"
 
-msgid "Error - "
-msgstr "Erreur — "
+#, c-format
+msgid "fetch_next_cert failed: %s\n"
+msgstr "échec de fetch_next_cert : %s\n"
 
-msgid "GPG_TTY has not been set - using maybe bogus default\n"
-msgstr ""
-"GPG_TTY n'a pas été définie — utilisation de défauts peut-être défectueux\n"
+#, c-format
+msgid "max_replies %d exceeded\n"
+msgstr "max_replies %d dépassé\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "formatage incorrect de l'empreinte dans « %s », ligne %d\n"
+msgid "can't allocate control structure: %s\n"
+msgstr "impossible d'allouer une structure de contrôle : %s\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "code de pays incorrect dans « %s », ligne %d\n"
+msgid "failed to initialize the server: %s\n"
+msgstr "impossible d'initialiser le serveur : %s\n"
 
 #, c-format
-msgid ""
-"You are about to create a signature using your certificate:\n"
-"\"%s\"\n"
-"This will create a qualified signature by law equated to a handwritten "
-"signature.\n"
-"\n"
-"%s%sAre you really sure that you want to do this?"
-msgstr ""
-"Vous êtes sur le point de créer une signature en utilisant votre "
-"certificat :\n"
-"« %s »\n"
-"Cela va créer une signature qualifiée équivalente légalement à une signature "
-"à la main.\n"
-"\n"
-"%s%sVoulez-vous vraiment faire cela ?"
+msgid "failed to the register commands with Assuan: %s\n"
+msgstr "impossible d'enregistrer les commandes avec Assuan : %s\n"
 
-msgid ""
-"Note, that this software is not officially approved to create or verify such "
-"signatures.\n"
-msgstr ""
-"Remarquez que ce programme n'est pas officiellement approuvé pour créer ou "
-"vérifier de telles signatures.\n"
+#, c-format
+msgid "Assuan accept problem: %s\n"
+msgstr "problème d'accept_assuan : %s\n"
 
 #, c-format
-msgid ""
-"You are about to create a signature using your certificate:\n"
-"\"%s\"\n"
-"Note, that this certificate will NOT create a qualified signature!"
+msgid "Assuan processing failed: %s\n"
+msgstr "problème de traitement Assuan : %s\n"
+
+msgid "accepting root CA not marked as a CA"
 msgstr ""
-"Vous êtes sur le point de créer une signature en utilisant votre "
-"certificat :\n"
-"« %s »\n"
-"Remarquez que ce certificat ne va pas créer de signature qualifiée."
+"acceptation de l'autorité de certification racine non marquée comme une "
+"autorité de certification"
 
-#, c-format
-msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
+msgid "CRL checking too deeply nested\n"
 msgstr ""
-"l'algorithme de hachage %d (%s) pour le signataire %d n'est pas pris en "
-"charge ; utilisation de %s\n"
+"vérification de liste de révocations de certificat imbriquée trop "
+"profondément\n"
 
-#, c-format
-msgid "hash algorithm used for signer %d: %s (%s)\n"
-msgstr "algorithme de hachage utilisé pour le signataire %d : %s (%s)\n"
+msgid "not checking CRL for"
+msgstr "pas de vérification de liste de révocations de certificat pour"
 
-#, c-format
-msgid "checking for qualified certificate failed: %s\n"
-msgstr "échec de vérification de certificat qualifié : %s\n"
+msgid "checking CRL for"
+msgstr "vérification de liste de révocations de certificat pour"
 
-msgid "Signature made "
-msgstr "Signature faite le "
+msgid "running in compatibility mode - certificate chain not checked!\n"
+msgstr ""
+"exécution en mode de compatibilité — chaîne de certificats non vérifiée\n"
 
-msgid "[date not given]"
-msgstr "[date non donnée]"
+msgid "selfsigned certificate has a BAD signature"
+msgstr "certificat autosigné avec une mauvaise signature"
 
 #, c-format
-msgid " using certificate ID 0x%08lX\n"
-msgstr " en utilisant le certificat d'identifiant 0x%08lX\n"
-
-msgid ""
-"invalid signature: message digest attribute does not match computed one\n"
+msgid "checking trustworthiness of root certificate failed: %s\n"
 msgstr ""
-"signature incorrecte : l'attribut de hachage du message ne correspond pas à "
-"celui calculé\n"
+"échec de vérification du niveau de confiance du certificat racine : %s\n"
 
-msgid "Good signature from"
-msgstr "Bonne signature de"
+msgid "certificate chain is good\n"
+msgstr "la chaîne de certificats est correcte\n"
 
-msgid "                aka"
-msgstr "                alias"
+msgid "DSA requires the use of a 160 bit hash algorithm\n"
+msgstr "DSA nécessite l'utilisation d'un algorithme de hachage de 160 bits\n"
 
-msgid "This is a qualified signature\n"
-msgstr "C'est une signature qualifiée\n"
+msgid "certificate should not have been used for CRL signing\n"
+msgstr ""
+"le certificat n'aurait pas dû être utilisé pour signer une liste de "
+"révocations de certificat\n"
 
 msgid "quiet"
 msgstr "silencieux"
@@ -6579,9 +7702,15 @@ msgstr "afficher les données encodées au format hexadécimal"
 msgid "decode received data lines"
 msgstr "décoder les lignes de données reçues"
 
+msgid "connect to the dirmngr"
+msgstr "se connecter au dirmngr"
+
 msgid "|NAME|connect to Assuan socket NAME"
 msgstr "|NOM|se connecter à la socket Assuan NOM"
 
+msgid "|ADDR|connect to Assuan server at ADDR"
+msgstr "|ADR|se connecter au serveur Assuan à ADR"
+
 msgid "run the Assuan server given on the command line"
 msgstr "exécuter le serveur Assuan donné en ligne de commande"
 
@@ -6594,14 +7723,14 @@ msgstr "|FICHIER|exécuter les commandes du FICHIER au démarrage"
 msgid "run /subst on startup"
 msgstr "exécuter /subst au démarrage"
 
-msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Utilisation : gpg-connect-agent [options] (-h pour l'aide)"
+msgid "Usage: @GPG@-connect-agent [options] (-h for help)"
+msgstr "Utilisation : @GPG@-connect-agent [options] (-h pour l'aide)"
 
 msgid ""
-"Syntax: gpg-connect-agent [options]\n"
+"Syntax: @GPG@-connect-agent [options]\n"
 "Connect to a running agent and send commands\n"
 msgstr ""
-"Syntaxe : gpg-connect-agent [options]\n"
+"Syntaxe : @GPG@-connect-agent [options]\n"
 "Se connecter à un agent en fonctionnement et envoyer des commandes\n"
 
 #, c-format
@@ -6623,7 +7752,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr "ligne raccourcie à cause de caractère NULL inclus\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "commande « %s » inconnue\n"
 
 #, c-format
@@ -6631,10 +7760,6 @@ msgid "sending line failed: %s\n"
 msgstr "échec d'envoi de ligne : %s\n"
 
 #, c-format
-msgid "error sending %s command: %s\n"
-msgstr "erreur d'envoi de commande %s : %s\n"
-
-#, c-format
 msgid "error sending standard options: %s\n"
 msgstr "erreur d'envoi d'options standards : %s\n"
 
@@ -6647,9 +7772,6 @@ msgstr "Options contrôlant la configuration"
 msgid "Options useful for debugging"
 msgstr "Options pratiques pour le débogage"
 
-msgid "|FILE|write server mode logs to FILE"
-msgstr "|FICHIER|écrire les journaux serveur dans le FICHIER"
-
 msgid "Options controlling the security"
 msgstr "Options contrôlant la sécurité"
 
@@ -6738,6 +7860,27 @@ msgstr "liste de serveurs LDAP"
 msgid "Configuration for OCSP"
 msgstr "Configuration pour OCSP"
 
+msgid "GPG for OpenPGP"
+msgstr "GPG pour OpenPGP"
+
+msgid "GPG Agent"
+msgstr "Agent GPG"
+
+msgid "Smartcard Daemon"
+msgstr "Démon de carte à puce"
+
+msgid "GPG for S/MIME"
+msgstr "GPG pour S/MIME"
+
+msgid "Directory Manager"
+msgstr "Gestionnaire de répertoires"
+
+msgid "PIN and Passphrase Entry"
+msgstr "Entrée de code personnel et de phrase secrète"
+
+msgid "Component not suitable for launching"
+msgstr "Composant non convenable pour le lancement"
+
 #, c-format
 msgid "External verification of component %s failed"
 msgstr "Échec de vérification externe du composant %s"
@@ -6763,8 +7906,8 @@ msgstr "|COMPOSANT|vérifier les options"
 msgid "apply global default values"
 msgstr "appliquer les valeurs par défaut globales"
 
-msgid "get the configuration directories for gpgconf"
-msgstr "aff. répertoires de configuration pour gpgconf"
+msgid "get the configuration directories for @GPGCONF@"
+msgstr "aff. répertoires de configuration pour @GPGCONF@"
 
 msgid "list global configuration file"
 msgstr "afficher le fichier de configuration globale"
@@ -6772,24 +7915,30 @@ msgstr "afficher le fichier de configuration globale"
 msgid "check global configuration file"
 msgstr "vérifier le fichier de configuration globale"
 
+msgid "reload all or a given component"
+msgstr "recharger tous les composants ou celui donné"
+
+msgid "launch a given component"
+msgstr "lancer un composant donné"
+
+msgid "kill a given component"
+msgstr "tuer un composant donné"
+
 msgid "use as output file"
 msgstr "utiliser comme fichier de sortie"
 
 msgid "activate changes at runtime, if possible"
 msgstr "activer modif. pendant l'exécution si possible"
 
-msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Utilisation : gpgconf [options] (-h pour l'aide)"
+msgid "Usage: @GPGCONF@ [options] (-h for help)"
+msgstr "Utilisation : @GPGCONF@ [options] (-h pour l'aide)"
 
 msgid ""
-"Syntax: gpgconf [options]\n"
-"Manage configuration options for tools of the GnuPG system\n"
+"Syntax: @GPGCONF@ [options]\n"
+"Manage configuration options for tools of the @GNUPG@ system\n"
 msgstr ""
-"Syntaxe : gpgconf [options]\n"
-"Gérer les options de configuration pour les outils du système GnuPG\n"
-
-msgid "usage: gpgconf [options] "
-msgstr "utilisation : gpgconf [options] "
+"Syntaxe : @GPGCONF@ [options]\n"
+"Gérer les options de configuration pour les outils du système @GNUPG@\n"
 
 msgid "Need one component argument"
 msgstr "Un argument de composant nécessaire"
@@ -6848,7 +7997,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "échec de %s sur %s avec l'état %i\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "impossible de créer le répertoire temporaire « %s » : %s\n"
 
 #, c-format
@@ -6945,15 +8094,417 @@ msgstr ""
 "Vérifier une phrase secrète donnée sur l'entrée standard par rapport à "
 "ficmotif\n"
 
+#~ msgid "use a standard location for the socket"
+#~ msgstr "utiliser un emplacement de socket standard"
+
+#~ msgid "|FILE|write environment settings also to FILE"
+#~ msgstr "|FICHIER|écrire aussi les réglages d'env. dans FICHIER"
+
+#~ msgid "gpg-agent protocol version %d is not supported\n"
+#~ msgstr "le protocole gpg-agent version %d n'est pas pris en charge\n"
+
+#~ msgid "can't connect to the agent - trying fall back\n"
+#~ msgstr ""
+#~ "impossible de se connecter à l'agent — essai avec la solution de repli\n"
+
+#~ msgid "no secret subkey for public subkey %s - ignoring\n"
+#~ msgstr "pas de sous-clef secrète pour la sous-clef publique %s — ignorée\n"
+
+#~ msgid "   (%d) ECC\n"
+#~ msgstr "   (%d) ECC\n"
+
+#, fuzzy
+#~| msgid "can't create directory '%s': %s\n"
+#~ msgid "can't create directory `%s': %s\n"
+#~ msgstr "impossible de créer le répertoire « %s » : %s\n"
+
+#, fuzzy
+#~| msgid "directory '%s' created\n"
+#~ msgid "directory `%s' created\n"
+#~ msgstr "répertoire « %s » créé\n"
+
+#, fuzzy
+#~| msgid "error creating keybox '%s': %s\n"
+#~ msgid "error creating keybox `%s': %s\n"
+#~ msgstr "erreur de création du trousseau local « %s » : %s\n"
+
+#, fuzzy
+#~| msgid "keybox '%s' created\n"
+#~ msgid "keybox `%s' created\n"
+#~ msgstr "le trousseau local « %s » a été créé\n"
+
+#, fuzzy
+#~| msgid "can't create lock for '%s'\n"
+#~ msgid "can't create lock for `%s'\n"
+#~ msgstr "impossible de créer un verrou pour « %s »\n"
+
+#~ msgid ""
+#~ "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
+#~ msgstr ""
+#~ "le chiffrement RSA n'est possible qu'avec des clefs d'au plus 2048 bits\n"
+#~ "en mode --pgp2\n"
+
+#~ msgid ""
+#~ "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
+#~ msgstr ""
+#~ "impossible d'utiliser le chiffrement IDEA avec toutes les clefs\n"
+#~ "utilisés pour chiffrer.\n"
+
+#~ msgid ""
+#~ "you can only make detached or clear signatures while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "une signature détachée ou en texte clair n'est possible qu'en mode --"
+#~ "pgp2\n"
+
+#~ msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
+#~ msgstr "signer et chiffrer en même temps n'est possible qu'en mode --pgp2\n"
+
+#~ msgid ""
+#~ "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
+#~ msgstr ""
+#~ "des fichiers (et pas un tube) doivent être utilisés lorsque --pgp2\n"
+#~ "est activé.\n"
+
+#~ msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
+#~ msgstr ""
+#~ "chiffrer un message en mode --pgp2 nécessite l'algorithme de chiffrement "
+#~ "IDEA\n"
+
+#~ msgid ""
+#~ "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
+#~ "mode.\n"
+#~ msgstr ""
+#~ "Impossible de faire une signature OpenPGP d'une clef PGP 2.x en mode --"
+#~ "pgp2.\n"
+
+#~ msgid "This would make the key unusable in PGP 2.x.\n"
+#~ msgstr "Cela rendrait la clef inutilisable par PGP 2.x.\n"
+
+#~ msgid ""
+#~ "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "une signature détachée avec des clefs de type\n"
+#~ "PGP 2.x n'est possible qu'en mode --pgp2\n"
+
+#~ msgid ""
+#~ "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "une signature en texte clair avec des clefs de type\n"
+#~ "PGP 2.x n'est possible qu'en mode --pgp2\n"
+
 #~ msgid "you may want to start the gpg-agent first\n"
 #~ msgstr "vous pourriez d'abord démarrer l'agent GPG\n"
 
-#~ msgid "error loading `%s': %s\n"
+#~ msgid "usage: gpg [options] "
+#~ msgstr "utilisation : gpg [options] "
+
+#~ msgid "usage: gpgsm [options] "
+#~ msgstr "utilisation : gpgsm [options] "
+
+#, fuzzy
+#~| msgid "can't create '%s': %s\n"
+#~ msgid "can't create `%s': %s\n"
+#~ msgstr "impossible de créer « %s » : %s\n"
+
+#, fuzzy
+#~| msgid "can't open '%s': %s\n"
+#~ msgid "can't open `%s': %s\n"
+#~ msgstr "impossible d'ouvrir « %s » : %s\n"
+
+#~ msgid "enable ssh-agent emulation"
+#~ msgstr "activer l'émulation de ssh-agent"
+
+#~ msgid "Usage: gpg-agent [options] (-h for help)"
+#~ msgstr "Utilisation : gpg-agent [options] (-h pour l'aide)"
+
+#~ msgid "malformed GPG_AGENT_INFO environment variable\n"
+#~ msgstr "la variable d'environnement GPG_AGENT_INFO est mal définie\n"
+
+#~ msgid "error creating socket: %s\n"
+#~ msgstr "erreur de création de socket : %s\n"
+
+#~ msgid "host not found"
+#~ msgstr "hôte introuvable"
+
+#~ msgid "error loading '%s': %s\n"
 #~ msgstr "erreur de chargement de « %s » : %s\n"
 
+#~ msgid "deleting secret key not implemented\n"
+#~ msgstr "la suppression de clef secrète n'est pas implémentée\n"
+
+#~ msgid "10 translator see trustdb.c:uid_trust_string_fixed"
+#~ msgstr "11 le traducteur a bien lu ce qu'il fallait :)"
+
+#~ msgid "[ revoked]"
+#~ msgstr "[ révoquée]"
+
+#~ msgid "[ expired]"
+#~ msgstr "[ expirée ]"
+
+#~ msgid "[ unknown]"
+#~ msgstr "[ inconnue]"
+
+#~ msgid "[  undef ]"
+#~ msgstr "[indéfinie]"
+
+#~ msgid "[marginal]"
+#~ msgstr "[marginale]"
+
+#~ msgid "[  full  ]"
+#~ msgstr "[  totale ]"
+
+#~ msgid "[ultimate]"
+#~ msgstr "[  ultime ]"
+
+#~ msgid "undefined"
+#~ msgstr "indéfinie"
+
+#~ msgid "never"
+#~ msgstr "jamais"
+
+#~ msgid "marginal"
+#~ msgstr "marginale"
+
+#~ msgid "full"
+#~ msgstr "totale"
+
+#~ msgid "ultimate"
+#~ msgstr "ultime"
+
+#~ msgid "Usage: scdaemon [options] (-h for help)"
+#~ msgstr "Utilisation : scdaemon [options] (-h pour l'aide)"
+
+#~ msgid "Usage: gpgsm [options] [files] (-h for help)"
+#~ msgstr "Utilisation : gpgsm [options] [fichiers] (-h pour l'aide)"
+
+#~ msgid "usage: dirmngr [options] "
+#~ msgstr "utilisation : dirmngr [options] "
+
+#~ msgid "Usage: gpgconf [options] (-h for help)"
+#~ msgstr "Utilisation : gpgconf [options] (-h pour l'aide)"
+
+#~ msgid "usage: gpgconf [options] "
+#~ msgstr "utilisation : gpgconf [options] "
+
+#~ msgid "too many entries in pk cache - disabled\n"
+#~ msgstr "trop d'entrées dans le cache de clefs publiques — désactivé\n"
+
 #~ msgid "failed to allocated keyDB handle\n"
 #~ msgstr "impossible d'allouer la gestion de base de clefs\n"
 
+#~ msgid "can't fdopen pipe for reading: %s\n"
+#~ msgstr "impossible d'ouvrir un tube en lecture avec fdopen : %s\n"
+
+#~ msgid "unknown key protection algorithm\n"
+#~ msgstr "algorithme de protection de clef inconnu\n"
+
+#~ msgid "secret parts of key are not available\n"
+#~ msgstr "Les parties secrètes de la clef ne sont pas disponibles.\n"
+
+#~ msgid "secret key already stored on a card\n"
+#~ msgstr "la clef secrète est déjà stockée sur une carte\n"
+
+#~ msgid "error writing key to card: %s\n"
+#~ msgstr "erreur d'écriture la clef sur la carte : %s\n"
+
+#~ msgid "remove the passphrase from exported subkeys"
+#~ msgstr "supprimer la phrase de passe des sous-clefs exportées"
+
+#~ msgid "key %s: not protected - skipped\n"
+#~ msgstr "clef %s : non protégée — ignorée\n"
+
+#~ msgid "about to export an unprotected subkey\n"
+#~ msgstr "sur le point d'exporter une sous-clef non protégée\n"
+
+#~ msgid "failed to unprotect the subkey: %s\n"
+#~ msgstr "échec de déprotection de la sous-clef : %s\n"
+
+#~ msgid "WARNING: secret key %s does not have a simple SK checksum\n"
+#~ msgstr ""
+#~ "Attention : la clef secrète %s n'a pas de somme de contrôle SK simple\n"
+
+#~ msgid "key %s: secret key without public key - skipped\n"
+#~ msgstr "clef %s : clef secrète sans clef publique — ignorée\n"
+
+#~ msgid "create a public key when importing a secret key"
+#~ msgstr "créer une clef publique en important une clef secrète"
+
+#~ msgid "key %s: already in secret keyring\n"
+#~ msgstr "clef %s : déjà dans le porte-clefs secret\n"
+
+#~ msgid "key %s: secret key not found: %s\n"
+#~ msgstr "clef %s : clef secrète introuvable : %s\n"
+
+#~ msgid "NOTE: a key's S/N does not match the card's one\n"
+#~ msgstr ""
+#~ "Remarque : le numéro de série d'une clef ne correspond pas à celui de la "
+#~ "carte\n"
+
+#~ msgid "NOTE: primary key is online and stored on card\n"
+#~ msgstr ""
+#~ "Remarque : la clef principale est en ligne et stockée sur la carte\n"
+
+#~ msgid "NOTE: secondary key is online and stored on card\n"
+#~ msgstr ""
+#~ "Remarque : la clef secondaire est en ligne et stockée sur la carte\n"
+
+#~ msgid "This key is not protected.\n"
+#~ msgstr "Cette clef n'est pas protégée.\n"
+
+#~ msgid "Key is protected.\n"
+#~ msgstr "La clef est protégée.\n"
+
+#~ msgid "Can't edit this key: %s\n"
+#~ msgstr "Impossible d'éditer cette clef : %s\n"
+
+#~ msgid ""
+#~ "Enter the new passphrase for this secret key.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "Entrez la nouvelle phrase de passe pour cette clef secrète.\n"
+#~ "\n"
+
+#~ msgid ""
+#~ "You don't want a passphrase - this is probably a *bad* idea!\n"
+#~ "\n"
+#~ msgstr ""
+#~ "Vous ne voulez pas de phrase de passe — c'est sans doute une *mauvaise* "
+#~ "idée.\n"
+#~ "\n"
+
+#~ msgid "Do you really want to do this? (y/N) "
+#~ msgstr "Voulez-vous vraiment faire cela ? (o/N) "
+
+#~ msgid "error reading secret keyblock \"%s\": %s\n"
+#~ msgstr "erreur de lecture du bloc de clef secrète « %s » : %s\n"
+
+#~ msgid "Please remove selections from the secret keys.\n"
+#~ msgstr "Veuillez supprimer les sélections des clefs secrètes.\n"
+
+#~ msgid "No corresponding signature in secret ring\n"
+#~ msgstr "Pas de signature correspondante dans le porte-clefs secret\n"
+
+#~ msgid "writing secret key stub to '%s'\n"
+#~ msgstr "écriture de la clef secrète partielle dans « %s »\n"
+
+#~ msgid "writing secret key to '%s'\n"
+#~ msgstr "écriture de la clef secrète dans « %s »\n"
+
+#~ msgid "no writable secret keyring found: %s\n"
+#~ msgstr ""
+#~ "aucun porte-clefs secret accessible en écriture n'a été trouvé : %s\n"
+
+#~ msgid "WARNING: 2 files with confidential information exists.\n"
+#~ msgstr ""
+#~ "Attention : deux fichiers existent avec des informations "
+#~ "confidentielles.\n"
+
+#~ msgid "%s is the unchanged one\n"
+#~ msgstr "%s est le fichier d'origine\n"
+
+#~ msgid "%s is the new one\n"
+#~ msgstr "%s est le nouveau\n"
+
+#~ msgid "Please fix this possible security flaw\n"
+#~ msgstr "Veuillez corriger cet éventuel problème de sécurité\n"
+
+#~ msgid "searching for names from %s server %s\n"
+#~ msgstr "recherche de noms sur le serveur %s %s\n"
+
+#~ msgid "searching for names from %s\n"
+#~ msgstr "recherche de noms sur %s\n"
+
+#~ msgid "searching for \"%s\" from %s server %s\n"
+#~ msgstr "recherche de « %s » sur le serveur %s %s\n"
+
+#~ msgid "searching for \"%s\" from %s\n"
+#~ msgstr "recherche de « %s » sur %s\n"
+
+#~ msgid "no keyserver action!\n"
+#~ msgstr "pas d'action pour le serveur de clefs.\n"
+
+#~ msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
+#~ msgstr ""
+#~ "Attention : le gestionnaire de serveurs de clefs provient d'une\n"
+#~ "            version différente de GnuPG (%s)\n"
+
+#~ msgid "keyserver did not send VERSION\n"
+#~ msgstr "le serveurs de clefs n'a pas envoyé sa VERSION\n"
+
+#~ msgid "external keyserver calls are not supported in this build\n"
+#~ msgstr ""
+#~ "les appels externes à un serveur de clef ne sont pas pris en charge dans\n"
+#~ "cette compilation\n"
+
+#~ msgid "no handler for keyserver scheme '%s'\n"
+#~ msgstr "pas de gestionnaire pour le type de serveurs de clefs « %s »\n"
+
+#~ msgid "action '%s' not supported with keyserver scheme '%s'\n"
+#~ msgstr ""
+#~ "l'action « %s » n'est pas prise en charge avec le type de serveurs\n"
+#~ "de clefs « %s »\n"
+
+#~ msgid "%s does not support handler version %d\n"
+#~ msgstr "%s ne prend pas en charge pas le gestionnaire de version %d\n"
+
+#~ msgid "keyserver timed out\n"
+#~ msgstr "le délai d'attente du serveur de clefs a expiré\n"
+
+#~ msgid "keyserver internal error\n"
+#~ msgstr "erreur interne du serveur de clefs\n"
+
+#~ msgid "keyserver communications error: %s\n"
+#~ msgstr "erreur de communication avec le serveur de clefs : %s\n"
+
+#~ msgid "WARNING: unable to parse URI %s\n"
+#~ msgstr "Attention : impossible d'analyser l'URI %s\n"
+
+#~ msgid "the IDEA cipher plugin is not present\n"
+#~ msgstr "le module de chiffrement IDEA n'est pas présent\n"
+
+#~ msgid "no corresponding public key: %s\n"
+#~ msgstr "pas de clef publique correspondante : %s\n"
+
+#~ msgid "public key does not match secret key!\n"
+#~ msgstr "la clef publique ne correspond pas à la clef secrète.\n"
+
+#~ msgid "unknown protection algorithm\n"
+#~ msgstr "algorithme de protection inconnu\n"
+
+#~ msgid "NOTE: This key is not protected!\n"
+#~ msgstr "Remarque : cette clef n'est pas protégée.\n"
+
+#~ msgid "protection digest %d is not supported\n"
+#~ msgstr "le hachage de protection %d n'est pas pris en charge\n"
+
+#~ msgid "Invalid passphrase; please try again"
+#~ msgstr "Phrase de passe incorrecte ; veuillez réessayer"
+
+#~ msgid "%s ...\n"
+#~ msgstr "%s…\n"
+
+#~ msgid "WARNING: Weak key detected - please change passphrase again.\n"
+#~ msgstr ""
+#~ "Attention : clef faible détectée — modifiez encore la phrase de passe.\n"
+
+#~ msgid ""
+#~ "generating the deprecated 16-bit checksum for secret key protection\n"
+#~ msgstr ""
+#~ "génération de la somme de contrôle de 16 bits (obsolète) pour protéger\n"
+#~ "la clef secrète\n"
+
+#~ msgid "DSA key %s uses an unsafe (%u bit) hash\n"
+#~ msgstr "la clef DSA %s utilise un hachage non sûr (%u bits)\n"
+
+#~ msgid " - probably dead - removing lock"
+#~ msgstr " — sans doute mort — suppression du verrou"
+
+#~ msgid "Parameters to be used for the certificate request:\n"
+#~ msgstr "Paramètres à utiliser pour la demande de certificat :\n"
+
+#~ msgid "use system's dirmngr if available"
+#~ msgstr "utiliser le dirmngr du système si disponible"
+
 #~ msgid "can't gen prime with pbits=%u qbits=%u\n"
 #~ msgstr "impossible de générer un nombre premier avec pbits=%u qbits=%u\n"
 
@@ -6963,33 +8514,25 @@ msgstr ""
 #~ msgid "no entropy gathering module detected\n"
 #~ msgstr "aucun module de récupération d'entropie n'a été trouvé\n"
 
-#~ msgid "can't lock `%s': %s\n"
+#~ msgid "can't lock '%s': %s\n"
 #~ msgstr "impossible de verrouiller « %s » : %s\n"
 
-#~ msgid "can't stat `%s': %s\n"
-#~ msgstr "impossible d'accéder à « %s » : %s\n"
-
-#~ msgid "`%s' is not a regular file - ignored\n"
+#~ msgid "'%s' is not a regular file - ignored\n"
 #~ msgstr "« %s » n'est pas un fichier régulier — ignoré\n"
 
 #~ msgid "note: random_seed file is empty\n"
 #~ msgstr "remarque : le fichier random_seed est vide\n"
 
-#~ msgid "WARNING: invalid size of random_seed file - not used\n"
-#~ msgstr ""
-#~ "Attention : la taille du fichier random_seed est incorrecte.\n"
-#~ "            Il ne sera pas utilisé.\n"
-
-#~ msgid "can't read `%s': %s\n"
+#~ msgid "can't read '%s': %s\n"
 #~ msgstr "impossible de lire « %s » : %s\n"
 
 #~ msgid "note: random_seed file not updated\n"
 #~ msgstr "remarque : le fichier random_seed n'a pas été mis à jour\n"
 
-#~ msgid "can't write `%s': %s\n"
+#~ msgid "can't write '%s': %s\n"
 #~ msgstr "impossible d'écrire « %s » : %s\n"
 
-#~ msgid "can't close `%s': %s\n"
+#~ msgid "can't close '%s': %s\n"
 #~ msgstr "impossible de fermer « %s » : %s\n"
 
 #~ msgid "WARNING: using insecure random number generator!!\n"
@@ -7053,14 +8596,11 @@ msgstr ""
 #~ msgid "generate PGP 2.x compatible messages"
 #~ msgstr "générer des messages compatibles avec PGP 2.x"
 
-#~ msgid "cipher extension `%s' not loaded due to unsafe permissions\n"
+#~ msgid "cipher extension '%s' not loaded due to unsafe permissions\n"
 #~ msgstr ""
 #~ "l'extension de chiffrement « %s » n'a pas été chargée car ses\n"
 #~ "droits ne sont pas sûrs\n"
 
-#~ msgid "NOTE: %s is not available in this version\n"
-#~ msgstr "Remarque : %s n'est pas disponible dans cette version\n"
-
 #~ msgid "-k[v][v][v][c] [user-id] [keyring]"
 #~ msgstr "-k[v][v][v][c] [identité] [porte-clefs]"
 
@@ -7390,9 +8930,6 @@ msgstr ""
 #~ msgid "can't query passphrase in batch mode\n"
 #~ msgstr "impossible de demander la phrase de passe en mode automatique\n"
 
-#~ msgid "Enter passphrase: "
-#~ msgstr "Entrez la phrase de passe : "
-
 #~ msgid "Repeat passphrase: "
 #~ msgstr "Répétez la phrase de passe : "
 
@@ -7405,9 +8942,6 @@ msgstr ""
 #~ msgid "unknown packet type"
 #~ msgstr "type de paquet inconnu"
 
-#~ msgid "unknown pubkey algorithm"
-#~ msgstr "algorithme de clef publique inconnu"
-
 #~ msgid "unknown digest algorithm"
 #~ msgstr "algorithme de hachage inconnu"
 
@@ -7435,9 +8969,6 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "mauvaise clef secrète utilisée"
 
-#~ msgid "bad key"
-#~ msgstr "mauvaise clef"
-
 #~ msgid "file write error"
 #~ msgstr "erreur d'écriture de fichier"
 
@@ -7450,6 +8981,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "erreur de création de fichier"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "phrase de passe incorrecte"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algorithme de clef publique non implémenté"
 
@@ -7534,9 +9068,6 @@ msgstr ""
 #~ msgid "... this is a bug (%s:%d:%s)\n"
 #~ msgstr "… c'est un bogue (%s : %d : %s)\n"
 
-#~ msgid "WARNING: using insecure memory!\n"
-#~ msgstr "Attention : utilisation de mémoire non sécurisée.\n"
-
 # FIXME: s#http://www.gnupg.org/faq.html#http://www.gnupg.org/documentation/faqs.html#
 #~ msgid "please see http://www.gnupg.org/faq.html for more information\n"
 #~ msgstr ""
index 40ac351..b3137a5 100644 (file)
--- a/po/gl.po
+++ b/po/gl.po
@@ -9,7 +9,6 @@ msgstr ""
 "PO-Revision-Date: 2003-12-04 11:39+0100\n"
 "Last-Translator: Jacobo Tarrio <jtarrio@trasno.net>\n"
 "Language-Team: Galician <gpul-traduccion@ceu.fi.udc.es>\n"
-"Language: gl\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -18,42 +17,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "non se puido inicializa-la base de datos de confianzas: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to create a sign and encrypt key? "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "¿Seguro que quere crear unha chave para asinar e cifrar? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "contrasinal incorrecto"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -79,9 +42,6 @@ msgid ""
 "this session"
 msgstr "Por favor, introduza o contrasinal; esta é unha frase secreta \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -118,11 +78,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "o algoritmo de protección %d%s non está soportado\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "non se pode crear `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "non se puido abrir `%s': %s\n"
 
 #, fuzzy, c-format
@@ -149,31 +109,19 @@ msgstr "fallou o borrado do bloque de chaves: %s\n"
 msgid "error writing key: %s\n"
 msgstr "erro escribindo no chaveiro `%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Por favor, introduza o contrasinal; esta é unha frase secreta \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "cambia-lo contrasinal"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Por favor, introduza o contrasinal; esta é unha frase secreta \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -201,7 +149,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -289,7 +237,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Necesita un contrasinal para protexe-la súa chave secreta.\n"
 "\n"
@@ -307,10 +255,10 @@ msgstr ""
 "Opcións:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -367,26 +315,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "erro ao crea-lo contrasinal: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "non está soportado"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "non está soportado"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "erro ao crea-lo contrasinal: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -410,7 +347,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -418,23 +355,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTA: non existe o ficheiro de opcións por defecto `%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "ficheiro de opcións `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "lendo as opcións de `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "erro ao crear `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "non se pode crea-lo directorio `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -445,7 +382,7 @@ msgid "can't create socket: %s\n"
 msgstr "non foi posible crear %s: %s\n"
 
 #, fuzzy, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "Revocación de certificado válida"
 
 #, fuzzy
@@ -457,7 +394,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "erro ao crea-lo contrasinal: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "erro ao enviar a `%s': %s\n"
 
 #, fuzzy, c-format
@@ -465,19 +402,19 @@ msgid "listen() failed: %s\n"
 msgstr "a actualización fallou: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "gravando a chave secreta en `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: directorio creado\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "base de datos de confianza: fallou a lectura (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: non foi posible crear un directorio: %s\n"
 
 #, fuzzy, c-format
@@ -585,31 +522,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "erro ao crea-lo contrasinal: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "erro lendo `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "non se atopou a chave `%s': %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "hai partes da chave secreta non dispoñibles\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "erro de lectura: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "erro lendo `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -697,15 +634,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "erro escribindo no chaveiro secreto `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "erro lendo `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "erro lendo `%s': %s\n"
 
 #, fuzzy, c-format
@@ -720,7 +657,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent non está dispoñible nesta sesión\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "non se puido conectar a `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -797,10 +734,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -827,22 +760,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "Certificado correcto"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "Certificado correcto"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "Certificado correcto"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "Certificado correcto"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "Revocación de certificado válida"
 
@@ -887,26 +804,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritmo de hash non válido `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "A sinatura caducou o %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritmo de hash non válido `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "o algoritmo de protección %d%s non está soportado\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "verificación de sinatura suprimida\n"
 
@@ -915,11 +816,11 @@ msgid "Signature available"
 msgstr "A sinatura caducou o %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Sinatura correcta de \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "algoritmo de hash non válido `%s'\n"
 
 #, fuzzy, c-format
@@ -966,7 +867,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Non hai axuda dispoñible para `%s'"
 
 #, fuzzy
@@ -1141,11 +1042,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "erro ao crea-lo chaveiro `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "erro lendo `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "erro escribindo no chaveiro `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1347,8 +1248,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Comando> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1369,7 +1270,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output non traballa con este comando\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "non se puido abrir `%s'\n"
 
 #, fuzzy, c-format
@@ -1422,18 +1323,18 @@ msgid "using cipher %s\n"
 msgstr "fallou a sinatura: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' xa está comprimido\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "AVISO: `%s' é un ficheiro baleiro\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr "só pode cifrar a chaves RSA de 2048 bits ou menos en modo --pgp2\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "lendo de `%s'\n"
 
 msgid ""
@@ -1500,11 +1401,11 @@ msgstr ""
 "externos\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "non se puido executar %s \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "non se puido executar %s \"%s\": %s\n"
 
 #, c-format
@@ -1522,11 +1423,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "non se puido le-la resposta do programa externo: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "AVISO: non se puido borra-lo ficheiro temporal (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "AVISO: non se puido elimina-lo directorio temporal `%s': %s\n"
 
 #, fuzzy
@@ -1594,16 +1495,12 @@ msgstr "demasiadas entradas na cach
 msgid "[User ID not found]"
 msgstr "[Non se atopou o id de usuario]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "chave %08lX: chave secreta sen chave pública - omitida\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "erro ao crear `%s': %s\n"
 
 #, fuzzy
@@ -1624,6 +1521,10 @@ msgstr ""
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "emprégase a chave secundaria %08lX no canto da primaria %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "chave %08lX: chave secreta sen chave pública - omitida\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "facer unha sinatura separada"
@@ -1666,9 +1567,6 @@ msgstr "ve-la lista de chaves secretas"
 msgid "generate a new key pair"
 msgstr "xerar un novo par de chaves"
 
-msgid "generate a revocation certificate"
-msgstr "xerar un certificado de revocación"
-
 msgid "remove keys from the public keyring"
 msgstr "borrar chaves do chaveiro público"
 
@@ -1684,9 +1582,8 @@ msgstr "asinar unha chave localmente"
 msgid "sign or edit a key"
 msgstr "asinar ou editar unha chave"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "cambia-lo contrasinal"
+msgid "generate a revocation certificate"
+msgstr "xerar un certificado de revocación"
 
 msgid "export keys"
 msgstr "exportar chaves"
@@ -1785,15 +1682,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Uso: gpg [opcións] [ficheiros] (-h para ve-la axuda)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxe: gpg [opcións] [ficheiros]\n"
 "asinar, verificar, cifrar ou descifrar\n"
@@ -1825,35 +1717,35 @@ msgid "conflicting commands\n"
 msgstr "comandos conflictivos\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "non se atopou un signo = na definición do grupo \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "AVISO: propiedade insegura en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "AVISO: propiedade insegura en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "AVISO: propiedade insegura en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "AVISO: permisos inseguros en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "AVISO: permisos inseguros en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "AVISO: permisos inseguros en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "AVISO: propiedade do directorio contedor insegura en %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1862,11 +1754,11 @@ msgid ""
 msgstr "AVISO: propiedade do directorio contedor insegura en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "AVISO: propiedade do directorio contedor insegura en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "AVISO: permisos do directorio contedor inseguros en %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1875,11 +1767,11 @@ msgid ""
 msgstr "AVISO: permisos do directorio contedor inseguros en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "AVISO: permisos do directorio contedor inseguros en %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr " creouse un novo ficheiro de configuración `%s'\n"
 
 msgid "display photo IDs during key listings"
@@ -1920,7 +1812,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Non hai unha sinatura correspondiente no chaveiro secreto\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "NOTA: ignórase o antigo ficheiro de opcións por defecto `%s'\n"
 
 #, c-format
@@ -1932,11 +1824,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "NOTA: ¡%s non é para uso normal!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s non é un xogo de caracteres válido\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s non é un xogo de caracteres válido\n"
 
 #, fuzzy
@@ -2116,15 +2008,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "¡%s aínda non traballa con %s!\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "non se pode empregar o algoritmo de cifrado \"%s\" no modo %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "non se pode empregar o algoritmo de resumo \"%s\" no modo %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "non se pode empregar o algoritmo de compresión \"%s\" no modo %s\n"
 
 #, c-format
@@ -2142,7 +2034,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [ficheiro]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "o descifrado fallou: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2194,10 +2086,6 @@ msgstr "--lsign-key id-de-usuario"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key id-de-usuario [comandos]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key id-de-usuario"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "o envío ao servidor de chaves fallou: %s\n"
@@ -2227,7 +2115,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "non se puido poñe-la armadura: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "algoritmo de hash non válido `%s'\n"
 
 msgid "[filename]"
@@ -2271,7 +2159,7 @@ msgid "No help available"
 msgstr "Non hai axuda dispoñible"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Non hai axuda dispoñible para `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2281,10 +2169,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "actualiza-la base de datos de confianza"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "actualiza-la base de datos de confianza"
 
@@ -2403,13 +2287,6 @@ msgid "key %s: no user ID\n"
 msgstr "chave %08lX: non hai ID de usuario\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "omítese `%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "chave %08lX: arranxouse a corrupción da sub-chave HKP\n"
 
@@ -2437,11 +2314,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "non se atopou un chaveiro no que se poida escribir: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "escribindo a `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "erro escribindo no chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
@@ -2509,17 +2386,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "chave %08lX: \"%s\" sen cambios\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "non se atopou a chave secreta `%s': %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "chave %08lX: chave secreta cunha cifra %d non válida - omitida\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "gravando a chave secreta en `%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "chave %08lX: chave secreta cunha cifra %d non válida - omitida\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "non hai un chaveiro privado por defecto: %s\n"
@@ -2568,18 +2441,14 @@ msgstr ""
 "chave %08lX: auto-sinatura non válida no identificadr de usuario \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "chave %08lX: algoritmo de chave pública non soportado\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "chave %08lX: engadiuse unha sinatura de chave directa\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "chave %08lX: non hai sub-chave para a ligazón da chave\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "chave %08lX: algoritmo de chave pública non soportado\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "chave %08lX: ligazón de sub-chave incorrecta\n"
 
@@ -2634,8 +2503,8 @@ msgstr "chave %08lX: ID de usuario duplicado detectado - mesturado\n"
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
 msgstr ""
-"AVISO: a chave %08lX pode estar revocada: obtendo a chave de revocación "
-"%08lX\n"
+"AVISO: a chave %08lX pode estar revocada: obtendo a chave de revocación %"
+"08lX\n"
 
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
@@ -2664,15 +2533,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "omítese: a chave secreta xa está presente\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "erro ao crea-lo chaveiro `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "chaveiro `%s' creado\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "erro ao crear `%s': %s\n"
 
 #, c-format
@@ -2859,7 +2728,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Fixen comprobacións moi exhaustivas.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "¿A súa elección? (introduza '?' para ter máis información): "
 
 #, fuzzy, c-format
@@ -3142,7 +3011,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Pista: seleccione os IDs de usuario que desexa asinar\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "clase de sinatura descoñecida"
 
 #, c-format
@@ -3177,11 +3046,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "non se puido abrir `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "erro ao crea-lo chaveiro `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3271,7 +3140,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Non hai preferencias nun ID de usuario estilo PGP 2.x.\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Esta chave pode estar revocada por %s chave "
 
 #, fuzzy, c-format
@@ -3338,14 +3207,6 @@ msgstr ""
 "AVISO: non se marcou ningún ID de usuario coma primario. Esta orde pode\n"
 "              facer que un ID de usuario diferente se converta no primario.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Non pode cambia-la data de expiración dunha chave v3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3584,7 +3445,7 @@ msgstr ""
 "Amosando a id. fotográfica %s de tamaño %ld da chave 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "preferencia %c%lu duplicada\n"
 
 #, fuzzy
@@ -3600,7 +3461,7 @@ msgid "too many compression preferences\n"
 msgstr "demasiadas preferencias `%c'\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "caracter non válido na cadea de preferencias\n"
 
 msgid "writing direct signature\n"
@@ -3843,7 +3704,7 @@ msgid "Invalid character in comment\n"
 msgstr "Carácter non válido no comentario\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Está a usa-lo xogo de caracteres `%s'.\n"
 
 #, c-format
@@ -3929,15 +3790,15 @@ msgid "Key generation canceled.\n"
 msgstr "Cancelouse a xeración de chaves.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "gravando a chave pública en `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "gravando a chave secreta en `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "gravando a chave secreta en `%s'\n"
 
 #, c-format
@@ -3949,11 +3810,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "non se atopou un chaveiro privado no que se poida escribir: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "erro escribindo no chaveiro público `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "erro escribindo no chaveiro secreto `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3998,11 +3859,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "fallou o borrado do bloque de chaves: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "non se pode crear `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "NOTA: a chave secreta %08lX caducou o %s\n"
 
 msgid "never     "
@@ -4044,15 +3905,11 @@ msgstr "     Pegada dactilar da sub-chave:"
 msgid "      Key fingerprint ="
 msgstr "     Pegada dactilar ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "Sinatura %s, algoritmo de resumo %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "non se puido poñe-la armadura: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4070,7 +3927,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Por favor, amañe este posible fallo de seguridade\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "comprobando o chaveiro `%s'\n"
 
 #, fuzzy, c-format
@@ -4108,7 +3965,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "AVISO: as opcións de `%s' aínda non están activas nesta execución\n"
 
 #, fuzzy
@@ -4175,10 +4032,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "a recepción do servidor de chaves fallou: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 "non hai un servidor de chaves coñecido (empregue a opción --keyserver)\n"
@@ -4187,11 +4040,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4207,6 +4060,10 @@ msgid "keyserver internal error\n"
 msgstr "erro do servidor de chaves"
 
 #, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "a recepción do servidor de chaves fallou: %s\n"
+
+#, fuzzy, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "%s: non é un ID de chave válido\n"
 
@@ -4377,10 +4234,6 @@ msgid "unknown"
 msgstr "descoñecido"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Non foi posible verifica-la sinatura: %s\n"
 
@@ -4403,7 +4256,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "paquete raíz incorrecto detectado en proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr ""
 "a actualización da base de datos de confianza fallou:\n"
 "%s\n"
@@ -4434,11 +4287,6 @@ msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr ""
 "forza-lo algoritmo de resumo %s (%d) viola as preferencias do destinatario\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Sinatura %s, algoritmo de resumo %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "o plugin de cifra IDEA non está presente\n"
 
@@ -4470,15 +4318,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "AVISO: \"%s\" é unha opción a extinguir\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "AVISO: \"%s\" é unha opción a extinguir\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "AVISO: \"%s\" é unha opción a extinguir\n"
-
 msgid "Uncompressed"
 msgstr "Sen comprimir"
 
@@ -4492,15 +4331,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "esta mensaxe pode non ser utilizable por %s\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "lendo as opcións de `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "destinatario por defecto `%s' descoñecido\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "O ficheiro `%s' xa existe. "
 
 #, fuzzy
@@ -4517,17 +4356,16 @@ msgstr "Introduza o novo nome de ficheiro"
 msgid "writing to stdout\n"
 msgstr "escribindo na saída estándar\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "suponse que hai datos asinados en `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr " creouse un novo ficheiro de configuración `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "AVISO: as opcións de `%s' aínda non están activas nesta execución\n"
 
 #, c-format
@@ -4543,10 +4381,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "un subpaquete de tipo %d ten o bit crítico posto\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problema co axente: o axente voltou coa resposta 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (ID principal da chave %08lX)"
 
@@ -4569,6 +4403,10 @@ msgid "cancelled by user\n"
 msgstr "cancelado polo usuario\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problema co axente: o axente voltou coa resposta 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4602,7 +4440,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Introduza o nome do ficheiro JPEG: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "non se puido abrir un ficheiro: %s\n"
 
 #, c-format
@@ -4614,7 +4452,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "¿Está seguro de que quere empregala (s/N)? "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\" non é un ficheiro JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4644,16 +4482,6 @@ msgstr "motivo para a revocaci
 msgid "revocation comment: "
 msgstr "comentario de revocación: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMsSoO"
 
@@ -4771,11 +4599,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Nota: Esta chave está desactivada.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4879,7 +4707,7 @@ msgid "no signed data\n"
 msgstr "non hai datos asinados\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "non foi posible abri-los datos asinados `%s'\n"
 
 #, fuzzy, c-format
@@ -5193,7 +5021,7 @@ msgstr ""
 "# (Empregue \"gpg --import-ownertrust\" para restauralos)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "erro lendo `%s': %s\n"
 
 #, fuzzy
@@ -5212,25 +5040,17 @@ msgid "ownertrust value missing"
 msgstr "importa-los valores de confianza no propietario"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "erro ao buscar un rexistro de confianza: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "erro de lectura: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "base de datos de confianza: fallou a sincronización: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "non se pode crear `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "non se puido abrir `%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "rexistro da base de datos de confianza %lu: lseek fallou: %s\n"
@@ -5243,13 +5063,21 @@ msgstr ""
 msgid "trustdb transaction too large\n"
 msgstr "transacción da base de datos de confianza demasiado grande\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "non se pode pechar `%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: ¡o directorio non existe!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "non se pode pechar `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "non se pode crear `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "non se puido abrir `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5335,7 +5163,7 @@ msgid "input line longer than %d characters\n"
 msgstr "a liña de entrada contén máis de %d caracteres\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' non é un ID longo de chave válido\n"
 
 #, fuzzy, c-format
@@ -5377,14 +5205,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5436,11 +5256,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "hase comproba-la base de datos de confianza o %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "non se precisa comproba-la base de datos de confianza\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "non se precisa comproba-la base de datos de confianza\n"
 
 #, fuzzy, c-format
@@ -5512,11 +5332,6 @@ msgid "missing argument"
 msgstr "argumento non válido"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armadura non válida"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "comandos conflictivos\n"
 
@@ -5536,10 +5351,6 @@ msgstr "opci
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "opcións de importación non válidas\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5568,8 +5379,12 @@ msgstr "opci
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "atopou un erro ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "erro lendo `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5577,15 +5392,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "non se puido abrir un ficheiro: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "non se puido poñe-la armadura: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "non se pode crea-lo directorio `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "erro escribindo no chaveiro `%s': %s\n"
 
 #, c-format
@@ -5603,7 +5418,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "non se atopou a chave pública %08lX: %s\n"
 
 #, fuzzy, c-format
@@ -5620,11 +5435,10 @@ msgstr "habilitar depuraci
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Uso: gpg [opcións] [ficheiros] (-h para ve-la axuda)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Uso: gpg [opcións] [ficheiros] (-h para ve-la axuda)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5753,9 +5567,6 @@ msgstr "Por favor, escolla o motivo da revocaci
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5766,14 +5577,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "cambia-lo contrasinal"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "cambia-lo contrasinal"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "erro ao le-lo bloque de chaves: %s\n"
 
@@ -5840,9 +5643,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "non se atoparon datos OpenPGP válidos.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "cambia-lo contrasinal"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5879,16 +5681,13 @@ msgstr "non usa-la terminal en absoluto"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "comandos conflictivos\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Uso: gpg [opcións] [ficheiros] (-h para ve-la axuda)"
@@ -5898,7 +5697,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5918,7 +5717,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr "erro ao pór '%s' na base de datos de confianza: %s\n"
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5954,7 +5753,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "non se puido abrir `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5983,7 +5782,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "fallou o borrado do bloque de chaves: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "non se puido inicializa-la base de datos de confianzas: %s\n"
 
 #, fuzzy
@@ -6184,16 +5983,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "erro escribindo no chaveiro secreto `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6215,11 +6014,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6227,11 +6026,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Non é un enderezo de e-mail válido\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "erro ao crea-lo chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "erro ao crea-lo chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6302,7 +6101,7 @@ msgid "No subject name given\n"
 msgstr "(Non se deu unha descrición)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6311,7 +6110,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "algoritmo de hash non válido `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6358,7 +6157,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "non se atopou a chave `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6366,11 +6165,11 @@ msgid "error locking keybox: %s\n"
 msgstr "erro ao le-lo bloque de chaves: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "certificado duplicado - borrado"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "certificado duplicado - borrado"
 
 #, fuzzy, c-format
@@ -6407,6 +6206,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "cambia-lo contrasinal"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "crear saída con armadura en ascii"
 
@@ -6484,8 +6287,8 @@ msgstr "Uso: gpg [opci
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxe: gpg [opcións] [ficheiros]\n"
 "asinar, verificar, cifrar ou descifrar\n"
@@ -6496,11 +6299,11 @@ msgid "usage: gpgsm [options] "
 msgstr "uso: gpg [opcións] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "non se puido conectar a `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "destinatario por defecto `%s' descoñecido\n"
 
 #, fuzzy, c-format
@@ -6523,11 +6326,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "escribindo a `%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "non se pode pechar `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6544,6 +6347,10 @@ msgstr "Certificado correcto"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "non se puido inicializa-la base de datos de confianzas: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "erro ao crea-lo contrasinal: %s\n"
@@ -6557,11 +6364,14 @@ msgid "error reading input: %s\n"
 msgstr "erro lendo `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "erro ao crea-lo chaveiro `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "chaveiro `%s' creado\n"
 
 #, fuzzy
@@ -6595,11 +6405,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "erro: pegada dactilar non válida\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6720,7 +6530,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "destinatario por defecto `%s' descoñecido\n"
 
 #, fuzzy, c-format
@@ -6954,7 +6764,7 @@ msgstr ""
 "%s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "non se pode crea-lo directorio `%s': %s\n"
 
 #, fuzzy, c-format
@@ -7050,17 +6860,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "erro lendo `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "non se puido inicializa-la base de datos de confianzas: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Comando> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "a base de datos de confianza está corrompida; execute \"gpg --fix-trustdb"
@@ -7599,6 +7398,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "paquete non válido"
 
+#~ msgid "invalid armor"
+#~ msgstr "armadura non válida"
+
 #~ msgid "no such user id"
 #~ msgstr "non hai tal id de usuario"
 
@@ -7608,6 +7410,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "empregouse unha chave secreta errónea"
 
+#~ msgid "not supported"
+#~ msgstr "non está soportado"
+
 #~ msgid "bad key"
 #~ msgstr "chave incorrecta"
 
@@ -7623,6 +7428,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "erro de creación de ficheiro"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "contrasinal incorrecto"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritmo de chave pública non implementado"
 
@@ -8277,8 +8085,8 @@ msgstr ""
 
 #~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"
 #~ msgstr ""
-#~ "comprobando con profundidade %d asinadas=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/"
-#~ "%d/%d\n"
+#~ "comprobando con profundidade %d asinadas=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%"
+#~ "d/%d\n"
 
 #~ msgid ""
 #~ "Select the algorithm to use.\n"
@@ -8465,6 +8273,9 @@ msgstr ""
 #~ msgid "%s: error checking key: %s\n"
 #~ msgstr "%s: erro ao verifica-la chave: %s\n"
 
+#~ msgid "Do you really want to create a sign and encrypt key? "
+#~ msgstr "¿Seguro que quere crear unha chave para asinar e cifrar? "
+
 #~ msgid "Do you really need such a large keysize? "
 #~ msgstr "¿Está seguro de precisar un tamaño de chave tan grande? "
 
index 6469bf3..54fd98b 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -9,7 +9,6 @@ msgstr ""
 "PO-Revision-Date: 2004-06-19 21:53+0200\n"
 "Last-Translator: Nagy Ferenc László <nfl@nfllab.com>\n"
 "Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
-"Language: hu\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -18,41 +17,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "Bizalmi adatbázis (%s) inicializálása sikertelen!\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Valóban visszavonja a kijelölt kulcsokat? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "érvénytelen jelszó"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -78,9 +42,6 @@ msgid ""
 "this session"
 msgstr "Kérem, adja meg a jelszót! Ezt egy titkos mondat. \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -117,11 +78,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "%d%s védõ algoritmus nem támogatott.\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "Nem tudom létrehozni a(z) \"%s\" állományt: %s.\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "Nem tudom megnyitni a(z) \"%s\" állományt: %s.\n"
 
 #, fuzzy, c-format
@@ -148,31 +109,19 @@ msgstr "A kulcsblokk t
 msgid "error writing key: %s\n"
 msgstr "Hiba a \"%s\" kulcskarika írásakor: %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Kérem, adja meg a jelszót! Ezt egy titkos mondat. \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "jelszóváltoztatás"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Kérem, adja meg a jelszót! Ezt egy titkos mondat. \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -199,7 +148,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -287,7 +236,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Most szükség van egy jelszóra (vagy mondatra), amely a titkos kulcsát védi.\n"
 "\n"
@@ -305,10 +254,10 @@ msgstr ""
 "Opciók:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -363,26 +312,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "Hiba a jelszó létrehozásakor: %s.\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "nem támogatott"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "nem támogatott"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "Hiba a jelszó létrehozásakor: %s.\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -404,7 +342,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -412,23 +350,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "MEGJEGYZÉS: Nincs alapértelmezett opciós fájl (%s).\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "\"%s\" opciós fájl: %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "Az opciókat a \"%s\" állományból olvasom.\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "Hiba \"%s\" létrehozásakor: %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "Nem tudom a \"%s\" könyvtárat létrehozni: %s.\n"
 
 msgid "name of socket too long\n"
@@ -439,7 +377,7 @@ msgid "can't create socket: %s\n"
 msgstr "%s nem hozható létre: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -451,7 +389,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "Hiba a jelszó létrehozásakor: %s.\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "Hiba %s-ra/-re küldéskor: %s\n"
 
 #, fuzzy, c-format
@@ -459,19 +397,19 @@ msgid "listen() failed: %s\n"
 msgstr "Frissítés sikertelen: %s.\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "Írom a titkos kulcsot a %s állományba.\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: Könyvtárat létrehoztam.\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "Bizalmi adatbázis: olvasás sikertelen (n=%d): %s.\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: Nem tudom a könyvtárat létrehozni: %s.\n"
 
 #, fuzzy, c-format
@@ -579,31 +517,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "Hiba a jelszó létrehozásakor: %s.\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "Hiba \"%s\" olvasásakor: %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "\"%s\" kulcs nem található: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "Titkos kulcsrészek nem állnak rendelkezésre.\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "Olvasási hiba: %s.\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "Hiba \"%s\" olvasásakor: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -691,15 +629,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "Hiba a(z) \"%s\" titkoskulcs-karika írásakor: %s.\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "Hiba \"%s\" olvasásakor: %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "Hiba \"%s\" olvasásakor: %s\n"
 
 #, fuzzy, c-format
@@ -714,7 +652,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "GPG ügynök nem elérhetõ ebben a munkafolyamatban.\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "Nem tudok kapcsolódni \"%s\" objektumhoz: %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -791,10 +729,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -821,22 +755,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "rossz igazolás"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "rossz igazolás"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "rossz igazolás"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "rossz igazolás"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "rossz igazolás"
 
@@ -879,26 +797,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "Érvénytelen kivonatoló algoritmus: %s\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Az aláírás lejárt: %s.\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "Érvénytelen kivonatoló algoritmus: %s\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "%d%s védõ algoritmus nem támogatott.\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "Aláírás-ellenõrzés elnyomva.\n"
 
@@ -907,11 +809,11 @@ msgid "Signature available"
 msgstr "Az aláírás lejárt: %s.\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Jó aláírás a következõtõl: \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "Érvénytelen kivonatoló algoritmus: %s\n"
 
 #, fuzzy, c-format
@@ -956,7 +858,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Nem áll rendelkezésre segítség \"%s\" témához."
 
 #, fuzzy
@@ -1130,11 +1032,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "Hiba \"%s\" olvasásakor: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "Hiba a \"%s\" kulcskarika írásakor: %s\n"
 
 msgid "Login data (account name): "
@@ -1336,8 +1238,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Parancs> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1358,7 +1260,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "Az --output opció nem mûködik ehhez a parancshoz.\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "Nem tudom megnyitni %s-t!\n"
 
 #, fuzzy, c-format
@@ -1410,11 +1312,11 @@ msgid "using cipher %s\n"
 msgstr "%s rejtjelezést használok.\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "\"%s\" már tömörített.\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "FIGYELEM: A(z) \"%s\" állomány üres.\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1422,7 +1324,7 @@ msgstr ""
 "Csak 2048 bites, vagy rövidebb RSA kulcsokkal titkosíthat --pgp2 módban!\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "Olvasok a \"%s\" állományból.\n"
 
 msgid ""
@@ -1483,11 +1385,11 @@ msgstr ""
 "Ez a platform átmeneti állományokat igényel külsõ programok hívásához.\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "Nem tudom végrehajtani a következõ \"%s\"-t: \"%s\": %s.\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "Nem tudom végrehajtani a következõ \"%s\"-t: \"%s\": %s.\n"
 
 #, c-format
@@ -1505,12 +1407,12 @@ msgid "unable to read external program response: %s\n"
 msgstr "Nem tudom beolvasni a külsõ program válaszát: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr ""
 "FIGYELEM: Nem tudom törölni az (\"%s\") átmeneti állományt: \"%s\": %s.\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "FIGYELEM: nem tudom törölni a \"%s\" átmeneti könyvtárat: %s\n"
 
 #, fuzzy
@@ -1577,16 +1479,12 @@ msgstr "T
 msgid "[User ID not found]"
 msgstr "[ismeretlen kulcs]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "%08lX kulcs: titkos kulcs nyilvános kulcs nélkül - kihagytam.\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "Hiba \"%s\" létrehozásakor: %s\n"
 
 #, fuzzy
@@ -1608,6 +1506,10 @@ msgstr ""
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "A %08lX másodlagos kulcsot használjuk a %08lX elsõdleges helyett.\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "%08lX kulcs: titkos kulcs nyilvános kulcs nélkül - kihagytam.\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "különálló aláírás készítése"
@@ -1650,9 +1552,6 @@ msgstr "titkos kulcsok list
 msgid "generate a new key pair"
 msgstr "új kulcspár létrehozása"
 
-msgid "generate a revocation certificate"
-msgstr "visszavonási igazolás készítése"
-
 msgid "remove keys from the public keyring"
 msgstr "kulcsok eltávolítása a nyilvánoskulcs-karikáról"
 
@@ -1668,9 +1567,8 @@ msgstr "kulcs al
 msgid "sign or edit a key"
 msgstr "kulcs aláírása vagy szerkesztése"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "jelszóváltoztatás"
+msgid "generate a revocation certificate"
+msgstr "visszavonási igazolás készítése"
 
 msgid "export keys"
 msgstr "kulcsok exportálása"
@@ -1769,15 +1667,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Használat: gpg [opciók] [fájlok] (-h a súgóhoz)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Szintaxis: gpg [opciók] [fájlok]\n"
 "Aláírás, ellenõrzés, titkosítás vagy visszafejtés.\n"
@@ -1809,35 +1702,35 @@ msgid "conflicting commands\n"
 msgstr "Egymásnak ellentmondó parancsok!\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "Nem találtam = jelet a \"%s\" csoportdefinícióban!\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "FIGYELEM: Nem biztonságos tulajdonos: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "FIGYELEM: Nem biztonságos tulajdonos: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "FIGYELEM: Nem biztonságos tulajdonos: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "FIGYELEM: nem biztonságos engedélyek: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "FIGYELEM: nem biztonságos engedélyek: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "FIGYELEM: nem biztonságos engedélyek: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "FIGYELEM: nem biztonságos könyvtártulajdonos: %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1846,11 +1739,11 @@ msgid ""
 msgstr "FIGYELEM: nem biztonságos könyvtártulajdonos: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "FIGYELEM: nem biztonságos könyvtártulajdonos: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "FIGYELEM: nem biztonságos könyvtárengedélyek: %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1859,11 +1752,11 @@ msgid ""
 msgstr "FIGYELEM: nem biztonságos könyvtárengedélyek: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "FIGYELEM: nem biztonságos könyvtárengedélyek: %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "\"%s\": ismeretlen konfigurációs elem.\n"
 
 msgid "display photo IDs during key listings"
@@ -1904,7 +1797,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Nincs megfelelõ aláírás a titkoskulcs-karikán.\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "MEGJEGYZÉS: Figyelmen kívül hagytam a régi opciókat (%s).\n"
 
 #, c-format
@@ -1916,11 +1809,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "MEGJEGYZÉS: %s nem normál használatra van!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s nem érvényes karakterkiosztás!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s nem érvényes karakterkiosztás!\n"
 
 #, fuzzy
@@ -2096,17 +1989,17 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s és %s egyelõre nem használható együtt!\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr ""
 "Lehet, hogy nem használhatja \"%s\" rejtjelezõ algoritmust %s módban!\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr ""
 "Lehet, hogy nem használhatja \"%s\" kivonatoló algoritmust %s módban!\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "Lehet, hogy nem használhatja \"%s\" tömörítõ algoritmust %s módban!\n"
 
 #, c-format
@@ -2124,7 +2017,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [fájlnév]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "Visszafejtés sikertelen: %s.\n"
 
 msgid "--encrypt [filename]"
@@ -2176,10 +2069,6 @@ msgstr "--lsign-key felh-azonos
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key felh-azonosító [parancsok]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key felh-azonosító"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "Küldés a kulcsszerverre sikertelen: %s\n"
@@ -2209,7 +2098,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "Páncélozás nem sikerült: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "Érvénytelen kivonatoló algoritmus: %s\n"
 
 msgid "[filename]"
@@ -2253,7 +2142,7 @@ msgid "No help available"
 msgstr "Nem áll rendelkezésre segítség."
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Nem áll rendelkezésre segítség \"%s\" témához."
 
 msgid "import signatures that are marked as local-only"
@@ -2263,10 +2152,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "bizalmi adatbázis frissítése"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "bizalmi adatbázis frissítése"
 
@@ -2385,13 +2270,6 @@ msgid "key %s: no user ID\n"
 msgstr "%08lX kulcs: Nincs felhasználói azonosító.\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "Kihagytam \"%s\"-t: %s.\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "%08lX kulcs: HKP alkulcssérülés kijavítva.\n"
 
@@ -2419,11 +2297,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "Nem írható kulcskarikát találtam: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "Írok a \"%s\" állományba.\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "Hiba a \"%s\" kulcskarika írásakor: %s\n"
 
 #, fuzzy, c-format
@@ -2487,18 +2365,14 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "%08lX kulcs: \"%s\" nem változott.\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "\"%s\" titkos kulcs nem található: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr ""
+"%08lX kulcs: Titkos kulcs érvénytelen (%d) rejtjelezõvel - kihagytam.\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "Írom a titkos kulcsot a %s állományba.\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr ""
-"%08lX kulcs: Titkos kulcs érvénytelen (%d) rejtjelezõvel - kihagytam.\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "Nincs alapértelmezett titkoskulcs-karika: %s\n"
@@ -2542,18 +2416,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "%08lX kulcs: Érvénytelen önaláírás a \"%s\" felh. azonosítón!\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "%08lX kulcs: Nem támogatott nyilvános kulcsú algoritmus!\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "%08lX kulcs: Kulcsaláírást hozzáadtam.\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "%08lX kulcs: Nincs alkulcs a kulcskötéshez!\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "%08lX kulcs: Nem támogatott nyilvános kulcsú algoritmus!\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "%08lX kulcs: Érvénytelen alkulcskötés!\n"
 
@@ -2638,15 +2508,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "Kihagytam: titkos kulcs már jelen van.\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "\"%s\" kulcskarikát létrehoztam.\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "Hiba \"%s\" létrehozásakor: %s\n"
 
 #, c-format
@@ -2834,7 +2704,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Nagyon alaposan ellenõriztem.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Mi a válasza? (Adjon meg \"?\"-et magyarázathoz!): "
 
 #, fuzzy, c-format
@@ -3111,7 +2981,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Javaslat: Válassza ki az aláírni kívánt felhasználóazonosítókat!\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "ismeretlen aláírásosztály"
 
 #, c-format
@@ -3146,11 +3016,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "Nem tudom megnyitni a(z) \"%s\" állományt: %s.\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3238,7 +3108,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Nincsenek preferenciák egy PGP 2.x felhasználóazonosítón!\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Ezt a kulcsot a következõ %s kulcs visszavonhatja: "
 
 #, fuzzy, c-format
@@ -3305,14 +3175,6 @@ msgstr ""
 "FIGYELEM: Nincs kijelölt elsõdleges felhasználóazonosító. Ez a parancs\n"
 " azt okozhatja, hogy egy másik azonosító lesz elsõdlegesként használva.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Nem változtathatja meg egy v3 kulcs lejárati dátumát!\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3544,7 +3406,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "%s fotóazonosító (méret: %ld, kulcs: 0x%08lX, felh: %d) mutatása.\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "%c%lu preferencia kétszer szerepel!\n"
 
 #, fuzzy
@@ -3560,7 +3422,7 @@ msgid "too many compression preferences\n"
 msgstr "Túl sok \"%c\" preferencia.\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "Érvénytelen karakter a preferenciák között!\n"
 
 msgid "writing direct signature\n"
@@ -3803,7 +3665,7 @@ msgid "Invalid character in comment\n"
 msgstr "Érvénytelen karakter a megjegyzésben!\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Ön a(z) %s karakterkódolást használja.\n"
 
 #, c-format
@@ -3889,15 +3751,15 @@ msgid "Key generation canceled.\n"
 msgstr "Kulcs létrehozása megszakítva.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "Írom a kulcsot a %s állományba.\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "Írom a titkos kulcsot a %s állományba.\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "Írom a titkos kulcsot a %s állományba.\n"
 
 #, c-format
@@ -3909,11 +3771,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "Nem írható titkoskulcs-karikát találtam: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "Hiba a(z) \"%s\" nyilvánoskulcs-karika írásakor: %s.\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "Hiba a(z) \"%s\" titkoskulcs-karika írásakor: %s.\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3957,11 +3819,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "A kulcsblokk törlése sikertelen: %s.\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "Nem tudom létrehozni a(z) \"%s\" állományt: %s.\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "MEGJEGYZÉS: %08lX titkos kulcs %s-kor lejárt.\n"
 
 msgid "never     "
@@ -4003,15 +3865,11 @@ msgstr "         Alkulcsujjlenyomat:"
 msgid "      Key fingerprint ="
 msgstr " Kulcs ujjlenyomata ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "%s aláírás, %s kivonatoló algoritmus.\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "Páncélozás nem sikerült: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4029,7 +3887,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Kérem, oldja meg ezt a lehetséges biztonsági problémát!\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "Ellenõrzöm a(z) \"%s\" kulcskarikát.\n"
 
 #, fuzzy, c-format
@@ -4067,7 +3925,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "FIGYELEM: \"%s\" opciói csak a következõ futáskor lesznek érvényesek!\n"
 
@@ -4135,10 +3993,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "Vétel a kulcsszerverrõl sikertelen: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4146,11 +4000,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4165,6 +4019,10 @@ msgstr "kulcsszerverhiba"
 msgid "keyserver internal error\n"
 msgstr "kulcsszerverhiba"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "Vétel a kulcsszerverrõl sikertelen: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4342,10 +4200,6 @@ msgid "unknown"
 msgstr "Ismeretlen módú"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Nem tudom ellenõrizni az aláírást: %s.\n"
 
@@ -4367,7 +4221,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "Érvénytelen gyökércsomagot találtam a proc_tree() függvényben!\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "Nem tudom megnyitni az állományt: %s.\n"
 
 #, fuzzy, c-format
@@ -4398,11 +4252,6 @@ msgstr ""
 "%s (%d) kivonatoló algoritmus használatának erõltetése ellentétes\n"
 "a címzett preferenciáival.\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s aláírás, %s kivonatoló algoritmus.\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "Az IDEA rejtjelezõ bõvítés nincs jelen!\n"
 
@@ -4434,15 +4283,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "FIGYELEM: \"%s\" elavult opció!\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "FIGYELEM: \"%s\" elavult opció!\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "FIGYELEM: \"%s\" elavult opció!\n"
-
 msgid "Uncompressed"
 msgstr "tömörítetlen"
 
@@ -4456,15 +4296,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "Lehet, hogy ez az üzenet használhatatlan a %s számára!\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "Az opciókat a \"%s\" állományból olvasom.\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "Ismeretlen alapértelmezett címzett: \"%s\"\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "\"%s\" állomány létezik. "
 
 #, fuzzy
@@ -4481,17 +4321,16 @@ msgstr "
 msgid "writing to stdout\n"
 msgstr "Írok a szabványos kimenetre.\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "Azt feltételezem, hogy az aláírt adat a %s állományban van.\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "\"%s\" új konfigurációs állományt létrehoztam.\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "FIGYELEM: \"%s\" opciói csak a következõ futáskor lesznek érvényesek!\n"
 
@@ -4508,10 +4347,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "A %d típusú alcsomag kritikus bitje beállított.\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "Probléma az ügynökkel: ügynök válasza: 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr ""
 " \n"
@@ -4537,6 +4372,10 @@ msgid "cancelled by user\n"
 msgstr "A felhasználó megszakította a mûveletet.\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "Probléma az ügynökkel: ügynök válasza: 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4571,7 +4410,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Adja meg egy JPEG fájl nevét a fotóazonosítóhoz: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "Nem tudom megnyitni az állományt: %s.\n"
 
 #, c-format
@@ -4583,7 +4422,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Biztos abban, hogy használni akarja (i/N)? "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\" nem JPEG állomány.\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4613,16 +4452,6 @@ msgstr "Visszavon
 msgid "revocation comment: "
 msgstr "Megjegyzés a visszavonáshoz: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iIfFkKhH"
 
@@ -4736,11 +4565,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Megjegyzés: Ez a kulcs le lett tiltva.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4845,7 +4674,7 @@ msgid "no signed data\n"
 msgstr "Nincs aláírt adat.\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "Nem tudom megnyitni a(z) \"%s\" aláírt adatot!\n"
 
 #, fuzzy, c-format
@@ -5158,7 +4987,7 @@ msgstr ""
 "# (Használja a \"gpg --import-ownertrust\" parancsot a visszaállításhoz!)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "Hiba \"%s\" olvasásakor: %s\n"
 
 #, fuzzy
@@ -5177,25 +5006,17 @@ msgid "ownertrust value missing"
 msgstr "bizalmi értékek importja"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "Hiba bizalmi rekord keresésekor: %s.\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "Olvasási hiba: %s.\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "Bizalmi adatbázis: szinkronizáció sikertelen: %s.\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "Nem tudom létrehozni a(z) \"%s\" állományt: %s.\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "Nem tudom megnyitni %s-t!\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "Bizalmi adatbázis %lu. rekord: lseek sikertelen: %s.\n"
@@ -5207,13 +5028,21 @@ msgstr "Bizalmi adatb
 msgid "trustdb transaction too large\n"
 msgstr "Bizalmi adatbázis tranzakciója túl nagy.\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "Nem tudom bezárni a(z) \"%s\" állományt: %s.\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: Könyvtár nem létezik!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "Nem tudom bezárni a(z) \"%s\" állományt: %s.\n"
+msgid "can't create lock for '%s'\n"
+msgstr "Nem tudom létrehozni a(z) \"%s\" állományt: %s.\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "Nem tudom megnyitni %s-t!\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5299,7 +5128,7 @@ msgid "input line longer than %d characters\n"
 msgstr "A bemeneti sor hosszabb, mint %d karakter.\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "\"%s\" nem egy érvényes hosszú kulcsazonosító.\n"
 
 #, fuzzy, c-format
@@ -5341,14 +5170,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5400,11 +5221,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "A bizalmi adatbázis következõ ellenõrzése: %s.\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "Nincs szükség a bizalmi adatbázis ellenõrzésére.\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "Nincs szükség a bizalmi adatbázis ellenõrzésére.\n"
 
 #, fuzzy, c-format
@@ -5475,11 +5296,6 @@ msgid "missing argument"
 msgstr "érvénytelen argumentum"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "érvénytelen páncél"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "Egymásnak ellentmondó parancsok!\n"
 
@@ -5499,10 +5315,6 @@ msgstr "
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "Érvénytelen import opciók!\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5531,8 +5343,12 @@ msgstr "
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "Talált egy programhibát... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "Hiba \"%s\" olvasásakor: %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5540,15 +5356,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "Nem tudom megnyitni az állományt: %s.\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "Páncélozás nem sikerült: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "Nem tudom a \"%s\" könyvtárat létrehozni: %s.\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "Hiba a \"%s\" kulcskarika írásakor: %s\n"
 
 #, c-format
@@ -5566,7 +5382,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "A(z) %08lX nyilvános kulcsot nem találom: %s.\n"
 
 #, fuzzy, c-format
@@ -5583,11 +5399,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Használat: gpg [opciók] [fájlok] (-h a súgóhoz)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Használat: gpg [opciók] [fájlok] (-h a súgóhoz)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5716,9 +5531,6 @@ msgstr "K
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5729,14 +5541,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "jelszóváltoztatás"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "jelszóváltoztatás"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "Hiba a kulcsblokk olvasásakor: %s\n"
 
@@ -5803,9 +5607,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "Nem találtam érvényes OpenPGP adatot.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "jelszóváltoztatás"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5841,16 +5644,13 @@ msgstr "ne haszn
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "Egymásnak ellentmondó parancsok!\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Használat: gpg [opciók] [fájlok] (-h a súgóhoz)"
@@ -5860,7 +5660,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5880,7 +5680,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5916,7 +5716,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "Nem tudom megnyitni a(z) \"%s\" állományt: %s.\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5945,7 +5745,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "A kulcsblokk törlése sikertelen: %s.\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "Bizalmi adatbázis (%s) inicializálása sikertelen!\n"
 
 #, fuzzy
@@ -6135,16 +5935,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "Hiba a(z) \"%s\" titkoskulcs-karika írásakor: %s.\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6166,11 +5966,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6178,11 +5978,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Ez nem érvényes e-mail cím.\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
 
 #, fuzzy, c-format
@@ -6253,7 +6053,7 @@ msgid "No subject name given\n"
 msgstr "(Nincs leírás.)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6262,7 +6062,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "Érvénytelen kivonatoló algoritmus: %s\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6308,7 +6108,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "\"%s\" kulcs nem található: %s\n"
 
 #, fuzzy, c-format
@@ -6316,11 +6116,11 @@ msgid "error locking keybox: %s\n"
 msgstr "Hiba a kulcsblokk olvasásakor: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Visszavonó igazolás létrehozva.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "%c%lu preferencia kétszer szerepel!\n"
 
 #, fuzzy, c-format
@@ -6357,6 +6157,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "jelszóváltoztatás"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "ascii páncélozott kimenet létrehozása"
 
@@ -6434,8 +6238,8 @@ msgstr "Haszn
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Szintaxis: gpg [opciók] [fájlok]\n"
 "Aláírás, ellenõrzés, titkosítás vagy visszafejtés.\n"
@@ -6446,11 +6250,11 @@ msgid "usage: gpgsm [options] "
 msgstr "Használat: gpg [opciók] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "Nem tudok kapcsolódni \"%s\" objektumhoz: %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "Ismeretlen alapértelmezett címzett: \"%s\"\n"
 
 #, fuzzy, c-format
@@ -6473,11 +6277,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "Írok a \"%s\" állományba.\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "Nem tudom bezárni a(z) \"%s\" állományt: %s.\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6494,6 +6298,10 @@ msgstr "visszavon
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "Bizalmi adatbázis (%s) inicializálása sikertelen!\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "Hiba a jelszó létrehozásakor: %s.\n"
@@ -6507,11 +6315,14 @@ msgid "error reading input: %s\n"
 msgstr "Hiba \"%s\" olvasásakor: %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "\"%s\" kulcskarikát létrehoztam.\n"
 
 #, fuzzy
@@ -6545,11 +6356,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "Hiba: Érvénytelen ujjlenyomat.\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6670,7 +6481,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "Ismeretlen alapértelmezett címzett: \"%s\"\n"
 
 #, fuzzy, c-format
@@ -6901,7 +6712,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "Nem tudom megnyitni az állományt: %s.\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "Nem tudom a \"%s\" könyvtárat létrehozni: %s.\n"
 
 #, fuzzy, c-format
@@ -6997,17 +6808,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "Hiba \"%s\" olvasásakor: %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "Bizalmi adatbázis (%s) inicializálása sikertelen!\n"
-
-#~ msgid "Command> "
-#~ msgstr "Parancs> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "Bizalmi adatbázis sérült. Kérem, futtassa: \"gpg --fix-trustdb\".\n"
 
@@ -7535,6 +7335,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "érvénytelen csomag"
 
+#~ msgid "invalid armor"
+#~ msgstr "érvénytelen páncél"
+
 #~ msgid "no such user id"
 #~ msgstr "nincs ilyen felhasználói azonosító"
 
@@ -7544,6 +7347,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "rossz titkos kulcs használata"
 
+#~ msgid "not supported"
+#~ msgstr "nem támogatott"
+
 #~ msgid "bad key"
 #~ msgstr "rossz kulcs"
 
@@ -7559,6 +7365,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "állománylétrehozási hiba"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "érvénytelen jelszó"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "nem megvalósított nyilvános kulcsú algoritmus"
 
index f3ba6b5..7a6c024 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -2,9 +2,6 @@
 # gnupg 1.2.4 (Indonesian)
 # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 # Tedi Heriyanto <tedi_h@gmx.net>, 1999, 2000, 2001, 2002, 2003, 2004.
-#                !-- user is unknown (2011-01-11)
-#
-# Designated-Translator: none
 #
 msgid ""
 msgstr ""
@@ -13,7 +10,6 @@ msgstr ""
 "PO-Revision-Date: 2004-06-17 16:32+0700\n"
 "Last-Translator: Tedi Heriyanto <tedi_h@gmx.net>\n"
 "Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
-"Language: id\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -23,41 +19,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "gagal inisialisasi TrustDB: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Anda ingin membatalkan kunci terpilih ini? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "passphrase tidak valid"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -83,9 +44,6 @@ msgid ""
 "this session"
 msgstr "Silakan masukkan passphrase; ini kalimat rahasia\n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -122,11 +80,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "algoritma proteksi %d%s tidak didukung\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "tidak dapat membuat %s: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "tidak dapat membuka `%s': %s\n"
 
 #, fuzzy, c-format
@@ -153,31 +111,19 @@ msgstr "gagal menghapus keyblok: %s\n"
 msgid "error writing key: %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Silakan masukkan passphrase; ini kalimat rahasia\n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "ubah passphrase"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Silakan masukkan passphrase; ini kalimat rahasia\n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -204,7 +150,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -292,7 +238,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Anda perlu sebuah passphrase untuk melindungi kunci rahasia anda.\n"
 "\n"
@@ -310,10 +256,10 @@ msgstr ""
 "Pilihan:\n"
 "  "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -368,26 +314,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "kesalahan penciptaan passphrase: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "tidak didukung"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "tidak didukung"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "kesalahan penciptaan passphrase: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -409,7 +344,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -417,23 +352,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "CATATAN: tidak ada file pilihan baku `%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "file pilihan `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "membaca pilihan dari `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "kesalahan penciptaan : `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "tidak dapat membuat direktori `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -444,7 +379,7 @@ msgid "can't create socket: %s\n"
 msgstr "tidak dapat membuat %s: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -456,7 +391,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "kesalahan penciptaan passphrase: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "kesalahan mengirim ke `%s': %s\n"
 
 #, fuzzy, c-format
@@ -464,19 +399,19 @@ msgid "listen() failed: %s\n"
 msgstr "gagal memperbarui: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "menulis kunci rahasia ke `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: direktori tercipta\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "trustdb: read failed (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: tidak dapat membuat direktori: %s\n"
 
 #, fuzzy, c-format
@@ -584,31 +519,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "kesalahan penciptaan passphrase: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "kesalahan membaca `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "kunci '%s' tidak ditemukan: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "bagian kunci rahasia tidak tersedia\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "kesalahan pembacaan: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "kesalahan membaca `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -696,15 +631,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "kesalahan menulis keyring rahasia `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "kesalahan membaca `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "kesalahan membaca `%s': %s\n"
 
 #, fuzzy, c-format
@@ -719,7 +654,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent tidak tersedia untuk sesi ini\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "tidak dapat terkoneksi ke `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -796,10 +731,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -826,22 +757,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "sertifikat yang buruk"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "sertifikat yang buruk"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "sertifikat yang buruk"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "sertifikat yang buruk"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "sertifikat yang buruk"
 
@@ -884,26 +799,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritma hash tidak valid `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Signature kadaluwarsa %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritma hash tidak valid `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "algoritma proteksi %d%s tidak didukung\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "verifikasi signature tidak diabaikan\n"
 
@@ -912,11 +811,11 @@ msgid "Signature available"
 msgstr "Signature kadaluwarsa %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Signature baik dari \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "algoritma hash tidak valid `%s'\n"
 
 #, fuzzy, c-format
@@ -961,7 +860,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Tidak tersedia bantuan untuk `%s'"
 
 #, fuzzy
@@ -1136,11 +1035,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "kesalahan membaca `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1342,8 +1241,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Perintah> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1364,7 +1263,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output tidak berfungsi untuk perintah ini\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "tidak dapat membuka `%s'\n"
 
 #, fuzzy, c-format
@@ -1416,11 +1315,11 @@ msgid "using cipher %s\n"
 msgstr "menggunakan cipher %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' sudah dikompresi\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "PERINGATAN: `%s' adalah file kosong\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1429,7 +1328,7 @@ msgstr ""
 "pgp2\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "Membaca dari `%s'\n"
 
 msgid ""
@@ -1491,11 +1390,11 @@ msgstr ""
 "platform ini membutuhkan file temp ketika memanggil program eksternal\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "tidak dapat mengeksekusi %s \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "tidak dapat mengeksekusi %s \"%s\": %s\n"
 
 #, c-format
@@ -1513,11 +1412,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "tidak dapat membaca tanggapan program eksternal: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "PERINGATAN: tidak dapat menghapus file temp (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "PERINGATAN: tidak dapat menghapus direktori temp `%s': %s\n"
 
 #, fuzzy
@@ -1585,16 +1484,12 @@ msgstr "terlalu banyak masukan dalam pk cache - ditiadakan\n"
 msgid "[User ID not found]"
 msgstr "[User id tidak ditemukan]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "kunci %08lX: kunci rahasia tanpa kunci publik - dilewati\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "kesalahan penciptaan : `%s': %s\n"
 
 #, fuzzy
@@ -1613,6 +1508,10 @@ msgstr "tidak ada subkey rahasia untuk subkey publik %08lX. diabaikan\n"
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "menggunakan kunci sekunder %08lX bukannya kunci primer %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "kunci %08lX: kunci rahasia tanpa kunci publik - dilewati\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "buat detached signature"
@@ -1655,9 +1554,6 @@ msgstr "tampilkan kunci rahasia"
 msgid "generate a new key pair"
 msgstr "buat sepasang kunci baru"
 
-msgid "generate a revocation certificate"
-msgstr "buat sertifikat revokasi"
-
 msgid "remove keys from the public keyring"
 msgstr "hapus kunci dari keyring publik"
 
@@ -1673,9 +1569,8 @@ msgstr "tandai kunci secara lokal"
 msgid "sign or edit a key"
 msgstr "tandai atau edit kunci"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "ubah passphrase"
+msgid "generate a revocation certificate"
+msgstr "buat sertifikat revokasi"
 
 msgid "export keys"
 msgstr "ekspor kunci"
@@ -1774,15 +1669,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Pemakaian: gpg [pilihan] [file] (-h untuk bantuan)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaks: gpg [pilihan] [file]\n"
 "tandai, cek, enkripsi atau dekripsi\n"
@@ -1814,35 +1704,35 @@ msgid "conflicting commands\n"
 msgstr "perintah saling konflik\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "tanda = tidak ditemukan dalam definisi grup \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "Peringatan: kepemilikan tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "Peringatan: kepemilikan tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "Peringatan: kepemilikan tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "Peringatan: permisi tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "Peringatan: permisi tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "Peringatan: permisi tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "Peringatan: kepemilikan direktori tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1851,11 +1741,11 @@ msgid ""
 msgstr "Peringatan: kepemilikan direktori tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "Peringatan: kepemilikan direktori tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "Peringatan: permisi direktori tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1864,11 +1754,11 @@ msgid ""
 msgstr "Peringatan: permisi direktori tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "Peringatan: permisi direktori tidak aman pada %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "Item Konfigurasi tidak dikenal \"%s\"\n"
 
 msgid "display photo IDs during key listings"
@@ -1909,7 +1799,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Tidak ada signature koresponden di ring rahasia\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "CATATAN: file pilihan baku lama `%s' diabaikan\n"
 
 #, c-format
@@ -1921,11 +1811,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "CATATAN: %s tidak untuk pemakaian normal!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s bukanlah set karakter yang valid\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s bukanlah set karakter yang valid\n"
 
 #, fuzzy
@@ -2107,17 +1997,17 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s belum dapat dipakai dengan %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr ""
 "anda tidak boleh menggunakan algoritma cipher \"%s\" saat dalam mode %s.\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr ""
 "anda tidak boleh menggunakan algoritma digest \"%s\" saat dalam mode %s.\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr ""
 "anda tidak boleh menggunakan algoritma kompresi \"%s\" saat dalam mode %s.\n"
 
@@ -2137,7 +2027,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [namafile]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "dekripsi gagal: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2189,10 +2079,6 @@ msgstr "--lsign-key id-user"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key id-user [perintah]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key id-user"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "Pengiriman keyserver gagal: %s\n"
@@ -2222,7 +2108,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "gagal enarmoring: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "algoritma hash tidak valid `%s'\n"
 
 msgid "[filename]"
@@ -2266,7 +2152,7 @@ msgid "No help available"
 msgstr "Tidak tersedia bantuan"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Tidak tersedia bantuan untuk `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2276,10 +2162,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "perbarui database trust"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "perbarui database trust"
 
@@ -2398,13 +2280,6 @@ msgid "key %s: no user ID\n"
 msgstr "kunci %08lX: tidak ada ID user\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "melewati `%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "kunci %08lX: subkey HKP yang rusak diperbaiki\n"
 
@@ -2432,11 +2307,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "tidak ditemukan keyring yang dapat ditulisi: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "menulis ke `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 #, fuzzy, c-format
@@ -2500,17 +2375,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "kunci %08lX: \"%s\" tidak berubah\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "kunci rahasia `%s' tidak ditemukan: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "kunci %08lX: kunci rahasia dengan cipher tidak valid %d - dilewati\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "menulis kunci rahasia ke `%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "kunci %08lX: kunci rahasia dengan cipher tidak valid %d - dilewati\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "tidak ada keyring rahasia baku: %s\n"
@@ -2554,18 +2425,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "kunci %08lX: self-signature tidak valid pada user id \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "kunci %08lX: algoritma publik key tidak didukung\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "kunci %08lX: signature kunci langsung ditambahkan\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "kunci %08lX: tidak ada subkey untuk key binding\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "kunci %08lX: algoritma publik key tidak didukung\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "kunci %08lX: subkey binding tidak valid\n"
 
@@ -2648,15 +2515,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "dilewati: kunci pribadi telah ada\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "%s: keyring tercipta\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "kesalahan penciptaan : `%s': %s\n"
 
 #, c-format
@@ -2848,7 +2715,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Saya telah melakukan pemeriksaan hati-hati.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Pilihan Anda? (berikan '?' untuk informasi lebih lanjut):"
 
 #, fuzzy, c-format
@@ -3125,7 +2992,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Petunjuk: Pilih ID user untuk ditandai\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "kelas signature tidak dikenal"
 
 #, c-format
@@ -3160,11 +3027,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "tidak dapat membuka `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3252,7 +3119,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Tidak ada preferensi pada user ID bergaya PGP 2.x.\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Kunci ini dapat dibatalkan oleh kunci %s"
 
 #, fuzzy, c-format
@@ -3319,14 +3186,6 @@ msgstr ""
 "WARNING: no user ID has been marked as primary.  This command may\n"
 "              cause a different user ID to become the assumed primary.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Anda tidak dapat merubah batas waktu kunci v3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3561,7 +3420,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Menampilkan photo ID %s berukuran %ld untuk kunci 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "preferensi %c%lu ganda \n"
 
 #, fuzzy
@@ -3577,7 +3436,7 @@ msgid "too many compression preferences\n"
 msgstr "terlalu banyak preferensi `%c'\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "Karakter tidak valid dalam string preferensi\n"
 
 msgid "writing direct signature\n"
@@ -3819,7 +3678,7 @@ msgid "Invalid character in comment\n"
 msgstr "Karakter tidak valid dalam komentar\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Anda menggunakan set karakter `%s'.\n"
 
 #, c-format
@@ -3904,15 +3763,15 @@ msgid "Key generation canceled.\n"
 msgstr "Pembuatan kunci dibatalkan.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "menulis kunci publik ke `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "menulis kunci rahasia ke `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "menulis kunci rahasia ke `%s'\n"
 
 #, c-format
@@ -3924,11 +3783,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "tidak ditemukan keyring rahasia yang dapat ditulisi: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "kesalahan menulis keyring publik `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "kesalahan menulis keyring rahasia `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3971,11 +3830,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "gagal menghapus keyblok: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "tidak dapat membuat %s: %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "CATATAN: kunci pribadi %08lX berakhir pada %s\n"
 
 msgid "never     "
@@ -4017,15 +3876,11 @@ msgstr "     Fingerprint subkunci ="
 msgid "      Key fingerprint ="
 msgstr "     Fingerprint kunci ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "%s signature, algoritma digest %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "gagal enarmoring: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4043,7 +3898,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Silakan perbaiki kemungkinan lubang keamanan ini\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "memeriksa keyring `%s'\n"
 
 #, fuzzy, c-format
@@ -4081,7 +3936,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "PERINGATAN: opsi dalam `%s' belum aktif selama pelaksanaan ini\n"
 
 #, fuzzy
@@ -4148,10 +4003,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "Penerimaan keyserver gagal: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4159,11 +4010,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4178,6 +4029,10 @@ msgstr "kesalahan keyserver"
 msgid "keyserver internal error\n"
 msgstr "kesalahan keyserver"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "Penerimaan keyserver gagal: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4349,10 +4204,6 @@ msgid "unknown"
 msgstr "tidak dikenal"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Tidak dapat memeriksa signature: %s\n"
 
@@ -4375,7 +4226,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "terdeteksi root paket tidak valid dalam proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "tidak dapat membuka file: %s\n"
 
 #, fuzzy, c-format
@@ -4402,11 +4253,6 @@ msgstr "%s signature, algoritma digest %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "memaksa algoritma digest %s (%d) melanggar preferensi penerima\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s signature, algoritma digest %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "plugin cipher IDEA tidak tersedia\n"
 
@@ -4438,15 +4284,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "WARNING: \"%s\" adalah opsi terdepresiasi\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "WARNING: \"%s\" adalah opsi terdepresiasi\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "WARNING: \"%s\" adalah opsi terdepresiasi\n"
-
 msgid "Uncompressed"
 msgstr "Tidak dikompresi"
 
@@ -4460,15 +4297,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "pesan ini mungkin tidak dapat digunakan oleh %s\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "membaca pilihan dari `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "penerima baku tidak dikenal `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "File `%s' ada. "
 
 #, fuzzy
@@ -4485,17 +4322,16 @@ msgstr "Masukkan nama file baru"
 msgid "writing to stdout\n"
 msgstr "menulis ke stdout\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "mengasumsikan data bertanda dalam `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "file konfigurasi baru `%s' tercipta\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "PERINGATAN: opsi dalam `%s' belum aktif selama pelaksanaan ini\n"
 
 #, c-format
@@ -4510,10 +4346,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "subpaket tipe %d memiliki bit kritis terset\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "masalah dengan agen: agen mengembalikan 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (ID kunci utama %08lX)"
 
@@ -4536,6 +4368,10 @@ msgid "cancelled by user\n"
 msgstr "dibatalkan oleh user\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "masalah dengan agen: agen mengembalikan 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4571,7 +4407,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Masukkan nama file JPEG sebagai ID foto: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "tidak dapat membuka file: %s\n"
 
 #, c-format
@@ -4583,7 +4419,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Apakah anda yakin ingin menggunakannya? (y/N) "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\" bukan sebuah file JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4613,16 +4449,6 @@ msgstr "Alasan pembatalan:"
 msgid "revocation comment: "
 msgstr "Komentar pembatalan:"
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4737,11 +4563,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Catatan: Kunci ini telah ditiadakan\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4843,7 +4669,7 @@ msgid "no signed data\n"
 msgstr "tidak ada data tertandai\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "tidak dapat membuka data tertandai `%s'\n"
 
 #, fuzzy, c-format
@@ -5156,7 +4982,7 @@ msgstr ""
 "# (Use \"gpg --import-ownertrust\" to restore them)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "kesalahan membaca `%s': %s\n"
 
 #, fuzzy
@@ -5175,25 +5001,17 @@ msgid "ownertrust value missing"
 msgstr "impor nilai ownertrust"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "kesalahan: gagal menemukan catatan trust: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "kesalahan pembacaan: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "trustdb: gagal sync: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "tidak dapat membuat %s: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "tidak dapat membuka `%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb rec %lu: lseek gagal: %s\n"
@@ -5205,13 +5023,21 @@ msgstr "trustdb rec %lu: write failed (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "transaksi trustdb terlalu besar\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "tidak dapat menutup `%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: direktori tidak ada!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "tidak dapat menutup `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "tidak dapat membuat %s: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "tidak dapat membuka `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5297,7 +5123,7 @@ msgid "input line longer than %d characters\n"
 msgstr "baris input lebih dari %d karakter\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "'%s' bukanlah keyID panjang yang valid\n"
 
 #, fuzzy, c-format
@@ -5338,14 +5164,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5397,11 +5215,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "pemeriksaan trustdb berikutnya pada %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "tidak perlu memeriksa trustdb\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "tidak perlu memeriksa trustdb\n"
 
 #, fuzzy, c-format
@@ -5472,11 +5290,6 @@ msgid "missing argument"
 msgstr "argumen tidak valid"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armor tidak valid"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "perintah saling konflik\n"
 
@@ -5496,10 +5309,6 @@ msgstr "opsi impor tidak valid\n"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "opsi impor tidak valid\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5528,8 +5337,12 @@ msgstr "opsi impor tidak valid\n"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "anda menemukan kesalahan ...(%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "kesalahan membaca `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5537,15 +5350,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "tidak dapat membuka file: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "gagal enarmoring: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "tidak dapat membuat direktori `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 #, c-format
@@ -5563,7 +5376,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "kunci publik %08lX tidak ditemukan: %s\n"
 
 #, fuzzy, c-format
@@ -5580,11 +5393,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Pemakaian: gpg [pilihan] [file] (-h untuk bantuan)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Pemakaian: gpg [pilihan] [file] (-h untuk bantuan)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5713,9 +5525,6 @@ msgstr "Silakan pilih alasan untuk pembatalan:\n"
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5726,14 +5535,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "ubah passphrase"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "ubah passphrase"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "gagal membaca keyblock: %s\n"
 
@@ -5800,9 +5601,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "tidak ditemukan data OpenPGP yang valid.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "ubah passphrase"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5838,16 +5638,13 @@ msgstr "jangan menggunakan terminal"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "perintah saling konflik\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Pemakaian: gpg [pilihan] [file] (-h untuk bantuan)"
@@ -5857,7 +5654,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5877,7 +5674,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5913,7 +5710,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "tidak dapat membuka `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5942,7 +5739,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "gagal menghapus keyblok: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "gagal inisialisasi TrustDB: %s\n"
 
 #, fuzzy
@@ -6131,16 +5928,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "kesalahan menulis keyring rahasia `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6162,11 +5959,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6174,11 +5971,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Bukan alamat email yang valid\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6249,7 +6046,7 @@ msgid "No subject name given\n"
 msgstr "(Tidak diberikan deskripsi)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6258,7 +6055,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "algoritma hash tidak valid `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6305,7 +6102,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "kunci '%s' tidak ditemukan: %s\n"
 
 #, fuzzy, c-format
@@ -6313,11 +6110,11 @@ msgid "error locking keybox: %s\n"
 msgstr "gagal membaca keyblock: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Sertifikat pembatalan tercipta.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "preferensi %c%lu ganda \n"
 
 #, fuzzy, c-format
@@ -6354,6 +6151,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "ubah passphrase"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "ciptakan output ascii"
 
@@ -6431,8 +6232,8 @@ msgstr "Pemakaian: gpg [pilihan] [file] (-h untuk bantuan)"
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaks: gpg [pilihan] [file]\n"
 "tandai, cek, enkripsi atau dekripsi\n"
@@ -6443,11 +6244,11 @@ msgid "usage: gpgsm [options] "
 msgstr "pemakaian: gpg [pilihan] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "tidak dapat terkoneksi ke `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "penerima baku tidak dikenal `%s'\n"
 
 #, fuzzy, c-format
@@ -6470,11 +6271,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "menulis ke `%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "tidak dapat menutup `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6491,6 +6292,10 @@ msgstr "buat sertifikat revokasi"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "gagal inisialisasi TrustDB: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "kesalahan penciptaan passphrase: %s\n"
@@ -6504,11 +6309,14 @@ msgid "error reading input: %s\n"
 msgstr "kesalahan membaca `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "kesalahan menulis keyring `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "%s: keyring tercipta\n"
 
 #, fuzzy
@@ -6542,11 +6350,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "kesalahan: fingerprint tidak valid\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6667,7 +6475,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "penerima baku tidak dikenal `%s'\n"
 
 #, fuzzy, c-format
@@ -6898,7 +6706,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "tidak dapat membuka file: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "tidak dapat membuat direktori `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6994,17 +6802,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "kesalahan membaca `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "gagal inisialisasi TrustDB: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Perintah> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "trustdb terkorupsi; silakan jalankan \"gpg --fix-trustdb\".\n"
 
@@ -7536,6 +7333,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "paket tidak valid"
 
+#~ msgid "invalid armor"
+#~ msgstr "armor tidak valid"
+
 #~ msgid "no such user id"
 #~ msgstr "tidak ada user id tsb"
 
@@ -7545,6 +7345,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "digunakan kunci rahasia yang salah"
 
+#~ msgid "not supported"
+#~ msgstr "tidak didukung"
+
 #~ msgid "bad key"
 #~ msgstr "kunci yang buruk"
 
@@ -7560,6 +7363,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "kesalahan buat file"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "passphrase tidak valid"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritma pubkey belum diimplementasikan"
 
index a1728a4..54e414e 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -9,7 +9,6 @@ msgstr ""
 "PO-Revision-Date: 2008-05-26 12:02+0200\n"
 "Last-Translator: Marco d'Itri <md@linux.it>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
-"Language: it\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -18,41 +17,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "inizializzazione del trustdb fallita: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Vuoi davvero revocare le chiavi selezionate? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "passphrase non valida"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -78,9 +42,6 @@ msgid ""
 "this session"
 msgstr "Inserisci la passphrase, cioè una frase segreta \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -117,11 +78,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "l'algoritmo di protezione %d%s non è gestito\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "impossibile creare `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "impossibile aprire `%s': %s\n"
 
 #, fuzzy, c-format
@@ -148,31 +109,19 @@ msgstr "cancellazione del keyblock fallita: %s\n"
 msgid "error writing key: %s\n"
 msgstr "errore scrivendo il portachiavi `%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Inserisci la passphrase, cioè una frase segreta \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "cambia la passphrase"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Inserisci la passphrase, cioè una frase segreta \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -199,7 +148,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -287,7 +236,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Ti serve una passphrase per proteggere la tua chiave segreta.\n"
 "\n"
@@ -305,10 +254,10 @@ msgstr ""
 "Opzioni:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -363,26 +312,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "errore nella creazione della passhprase: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "non gestito"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "non gestito"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "errore nella creazione della passhprase: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -404,7 +342,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -412,23 +350,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTA: manca il file `%s' con le opzioni predefinite\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "file con le opzioni `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "lettura delle opzioni da `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "errore creando `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "impossibile creare la directory `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -439,7 +377,7 @@ msgid "can't create socket: %s\n"
 msgstr "impossibile creare %s: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -451,7 +389,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "errore nella creazione della passhprase: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "errore leggendo `%s': %s\n"
 
 #, fuzzy, c-format
@@ -459,19 +397,19 @@ msgid "listen() failed: %s\n"
 msgstr "aggiornamento fallito: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "scrittura della chiave segreta in `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: directory creata\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "trustdb: read fallita (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: impossibile creare la directory: %s\n"
 
 #, fuzzy, c-format
@@ -579,31 +517,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "errore nella creazione della passhprase: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "errore leggendo `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "chiave `%s' non trovata: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "parti della chiave segreta non sono disponibili\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "errore di lettura: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "errore leggendo `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -691,15 +629,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "errore scrivendo il portachiavi segreto `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "errore leggendo `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "errore leggendo `%s': %s\n"
 
 #, fuzzy, c-format
@@ -714,7 +652,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent non è disponibile in questa sessione\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "impossibile connettersi a `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -791,10 +729,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -821,22 +755,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "certificato danneggiato"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "certificato danneggiato"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "certificato danneggiato"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "certificato danneggiato"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "certificato danneggiato"
 
@@ -879,26 +797,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritmo di hash non valido `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Firma scaduta il %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritmo di hash non valido `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "l'algoritmo di protezione %d%s non è gestito\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "verifica della firma soppressa\n"
 
@@ -907,11 +809,11 @@ msgid "Signature available"
 msgstr "Firma scaduta il %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Firma valida da \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "algoritmo di hash non valido `%s'\n"
 
 #, fuzzy, c-format
@@ -956,7 +858,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Non è disponibile un aiuto per `%s'"
 
 #, fuzzy
@@ -1132,11 +1034,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "errore creando il portachiavi `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "errore leggendo `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "errore scrivendo il portachiavi `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1338,8 +1240,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Comando> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1360,7 +1262,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output non funziona con questo comando\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "impossibile aprire `%s'\n"
 
 #, fuzzy, c-format
@@ -1413,11 +1315,11 @@ msgid "using cipher %s\n"
 msgstr "uso il cifrario %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' è già compresso\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "ATTENZIONE: `%s' è un file vuoto\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1426,7 +1328,7 @@ msgstr ""
 "bit\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "lettura da `%s'\n"
 
 msgid ""
@@ -1497,11 +1399,11 @@ msgstr ""
 "esterni\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "impossibile eseguire %s \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "impossibile eseguire %s \"%s\": %s\n"
 
 #, c-format
@@ -1519,11 +1421,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "impossibile leggere la risposta del programma esterno: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "ATTENZIONE: impossibile cancellare il file temporaneo (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "ATTENZIONE: impossibile rimuovere la directory temporanea `%s': %s\n"
 
 #, fuzzy
@@ -1590,16 +1492,12 @@ msgstr "troppe voci nella pk cache - disabilitata\n"
 msgid "[User ID not found]"
 msgstr "[User ID non trovato]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "chiave %08lX: chiave segreta senza chiave pubblica - saltata\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "errore creando `%s': %s\n"
 
 #, fuzzy
@@ -1619,6 +1517,10 @@ msgstr ""
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "uso la chiave secondaria %08lX invece della chiave primaria %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "chiave %08lX: chiave segreta senza chiave pubblica - saltata\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "fai una firma separata"
@@ -1661,9 +1563,6 @@ msgstr "elenca le chiavi segrete"
 msgid "generate a new key pair"
 msgstr "genera una nuova coppia di chiavi"
 
-msgid "generate a revocation certificate"
-msgstr "genera un certificato di revoca"
-
 msgid "remove keys from the public keyring"
 msgstr "rimuove le chiavi dal portachiavi pubblico"
 
@@ -1679,9 +1578,8 @@ msgstr "firma una chiave localmente"
 msgid "sign or edit a key"
 msgstr "firma o modifica una chiave"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "cambia la passphrase"
+msgid "generate a revocation certificate"
+msgstr "genera un certificato di revoca"
 
 msgid "export keys"
 msgstr "esporta delle chiavi"
@@ -1780,15 +1678,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Uso: gpg [opzioni] [files] (-h per l'aiuto)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintassi: gpg [opzioni] [files]\n"
 "firma, controlla, cifra o decifra\n"
@@ -1820,35 +1713,35 @@ msgid "conflicting commands\n"
 msgstr "comandi in conflitto\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "non è stato trovato il segno = nella definizione del gruppo \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "ATTENZIONE: il proprietario \"%s\" di %s è insicuro\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "ATTENZIONE: il proprietario \"%s\" di %s è insicuro\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "ATTENZIONE: il proprietario \"%s\" di %s è insicuro\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "ATTENZIONE: il proprietario \"%s\" di %s è insicuro\n"
 
 #, fuzzy, c-format
@@ -1857,11 +1750,11 @@ msgid ""
 msgstr "ATTENZIONE: il proprietario \"%s\" di %s è insicuro\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "ATTENZIONE: il proprietario \"%s\" di %s è insicuro\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
 
 #, fuzzy, c-format
@@ -1870,11 +1763,11 @@ msgid ""
 msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "ATTENZIONE: i permessi \"%s\" di %s sono insicuri\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "elemento della configurazione sconosciuto \"%s\"\n"
 
 msgid "display photo IDs during key listings"
@@ -1915,7 +1808,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Manca la firma corrispondente nel portachiavi segreto\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr ""
 "NOTA: il vecchio file `%s' con le opzioni predefinite è stato ignorato\n"
 
@@ -1928,11 +1821,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "NOTA: %s normalmente non deve essere usato!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s non è un set di caratteri valido\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s non è un set di caratteri valido\n"
 
 #, fuzzy
@@ -2110,15 +2003,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s non funziona ancora con %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "non è possibile usare l'algoritmo di cifratura \"%s\" in modalità %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "non è possibile usare l'algoritmo di digest \"%s\" in modalità %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr ""
 "non è possibile usare l'algoritmo di compressione \"%s\" in modalità %s\n"
 
@@ -2138,7 +2031,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [nomefile]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "decifratura fallita: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2190,10 +2083,6 @@ msgstr "--lsign-key user-id"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key user-id [comandi]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key user-id"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "invio al keyserver fallito: %s\n"
@@ -2223,7 +2112,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "creazione dell'armatura fallita: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "algoritmo di hash non valido `%s'\n"
 
 msgid "[filename]"
@@ -2267,7 +2156,7 @@ msgid "No help available"
 msgstr "Non è disponibile un aiuto"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Non è disponibile un aiuto per `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2277,10 +2166,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "aggiorna il database della fiducia"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "aggiorna il database della fiducia"
 
@@ -2399,13 +2284,6 @@ msgid "key %s: no user ID\n"
 msgstr "chiave %08lX: nessun user ID\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "saltata `%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "chiave %08lX: riparati i danni di HKP alla subchiave\n"
 
@@ -2433,11 +2311,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "non è stato trovato un portachiavi scrivibile: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "scrittura in `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "errore scrivendo il portachiavi `%s': %s\n"
 
 #, fuzzy, c-format
@@ -2501,17 +2379,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "chiave %08lX: \"%s\" non cambiata\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "chiave segreta `%s' non trovata: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "chiave %08lX: chiave segreta con cifrario %d non valido - saltata\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "scrittura della chiave segreta in `%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "chiave %08lX: chiave segreta con cifrario %d non valido - saltata\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "nessun portachiavi segreto predefinito: %s\n"
@@ -2556,18 +2430,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "chiave %08lX: autofirma non valida sull'user ID \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "chiave %08lX: algoritmo a chiave pubblica non gestito\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "chiave %08lX: aggiunta una firma alla chiave diretta\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "chiave %08lX: non ci sono subchiavi per il legame con la chiave\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "chiave %08lX: algoritmo a chiave pubblica non gestito\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "chiave %08lX: legame con la subchiave non valido:\n"
 
@@ -2652,15 +2522,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "saltata: chiave pubblica già presente\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "errore creando il portachiavi `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "portachiavi `%s' creato\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "errore creando `%s': %s\n"
 
 #, c-format
@@ -2850,7 +2720,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) L'ho controllata molto attentamente.%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Cosa scegli? (inserisci '?' per ulteriori informazioni): "
 
 #, fuzzy, c-format
@@ -3127,7 +2997,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Suggerimento: seleziona gli user ID da firmare\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "classe della firma sconosciuta"
 
 #, c-format
@@ -3162,11 +3032,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "impossibile aprire `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "errore creando il portachiavi `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3254,7 +3124,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Non esistono preferense su un user ID in stile PGP 2.x\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Questa chiave può essere revocata dalla chiave %s "
 
 #, fuzzy, c-format
@@ -3323,14 +3193,6 @@ msgstr ""
 "            potrebbe fare diventare un altro user ID il primario "
 "predefinito.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Non è possibile cambiare la data di scadenza di una chiave v3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3571,7 +3433,7 @@ msgstr ""
 "Mostro %s ID fotografici di dimensioni %ld per la chaive 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "la preferenza %c%lu è doppia\n"
 
 #, fuzzy
@@ -3587,7 +3449,7 @@ msgid "too many compression preferences\n"
 msgstr "ci sono troppe preferenze `%c'\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "carattere non valido nella stringa delle preferenze\n"
 
 msgid "writing direct signature\n"
@@ -3830,7 +3692,7 @@ msgid "Invalid character in comment\n"
 msgstr "Carattere non valido nel commento\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Stai usando il set di caratteri `%s'.\n"
 
 #, c-format
@@ -3915,15 +3777,15 @@ msgid "Key generation canceled.\n"
 msgstr "Generazione della chiave annullata.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "scrittura della chiave pubblica in `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "scrittura della chiave segreta in `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "scrittura della chiave segreta in `%s'\n"
 
 #, c-format
@@ -3935,11 +3797,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "non è stato trovato un portachiavi segreto scrivibile: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "errore scrivendo il portachiavi pubblico `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "errore scrivendo il portachiavi segreto `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3984,11 +3846,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "cancellazione del keyblock fallita: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "impossibile creare `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "NOTA: chiave %08lX scaduta il %s\n"
 
 msgid "never     "
@@ -4030,15 +3892,11 @@ msgstr "     Impronta digitale della subchiave:"
 msgid "      Key fingerprint ="
 msgstr "     Impronta digitale ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "Firma %s, algoritmo di digest %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "creazione dell'armatura fallita: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4056,7 +3914,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Per favore risolvete questo possibile problema di sicurezza\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "controllo il portachiavi `%s'\n"
 
 #, fuzzy, c-format
@@ -4094,7 +3952,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "ATTENZIONE: le opzioni in `%s' non sono ancora attive durante questa\n"
 "esecuzione del programma\n"
@@ -4164,10 +4022,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "ricezione dal keyserver fallita: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4175,11 +4029,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4194,6 +4048,10 @@ msgstr "errore del keyserver"
 msgid "keyserver internal error\n"
 msgstr "errore del keyserver"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "ricezione dal keyserver fallita: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4365,10 +4223,6 @@ msgid "unknown"
 msgstr "sconosciuto"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Impossibile controllare la firma: %s\n"
 
@@ -4390,7 +4244,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "individuato un pacchetto radice non valido in proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "impossibile aprire il file: %s\n"
 
 #, fuzzy, c-format
@@ -4419,11 +4273,6 @@ msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr ""
 "forzare l'algoritmo di digest %s (%d) viola le preferenze del destinatario\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Firma %s, algoritmo di digest %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "il plugin per il cifrario IDEA non è presente\n"
 
@@ -4455,15 +4304,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "ATTENZIONE: \"%s\" è una opzione deprecata\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "ATTENZIONE: \"%s\" è una opzione deprecata\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "ATTENZIONE: \"%s\" è una opzione deprecata\n"
-
 msgid "Uncompressed"
 msgstr "Non compresso"
 
@@ -4477,15 +4317,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "questo messaggio può non essere utilizzabile da %s\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "lettura delle opzioni da `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "destinatario predefinito `%s' sconosciuto\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Il file `%s' esiste. "
 
 #, fuzzy
@@ -4502,17 +4342,16 @@ msgstr "Inserire il nuovo nome del file"
 msgid "writing to stdout\n"
 msgstr "scrivo su stdout\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "suppongo che i dati firmati siano in `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "creato un nuovo file di configurazione `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "ATTENZIONE: le opzioni in `%s' non sono ancora attive durante questa\n"
 "esecuzione del programma\n"
@@ -4531,10 +4370,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "il sottopacchetto di tipo %d ha un bit critico impostato\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problema con l'agent: ha restituito 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (key ID principale %08lX)"
 
@@ -4557,6 +4392,10 @@ msgid "cancelled by user\n"
 msgstr "interrotto dall'utente\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problema con l'agent: ha restituito 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4593,7 +4432,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Inserisci il nome del file JPEG per l'ID fotografico: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "impossibile aprire il file: %s\n"
 
 #, c-format
@@ -4605,7 +4444,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Sei sicuro di volerla usare? (s/N) "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\": non è un file JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4635,16 +4474,6 @@ msgstr "ragione della revoca: "
 msgid "revocation comment: "
 msgstr "commento alla revoca: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4761,11 +4590,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Nota: questa chiave è stata disabilitata.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4868,7 +4697,7 @@ msgid "no signed data\n"
 msgstr "non ci sono dati firmati\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "impossibile aprire i dati firmati `%s'\n"
 
 #, fuzzy, c-format
@@ -5196,7 +5025,7 @@ msgstr ""
 "# (Usa \"gpg --import-ownertrust\" per ripristinarli)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "errore leggendo `%s': %s\n"
 
 #, fuzzy
@@ -5215,25 +5044,17 @@ msgid "ownertrust value missing"
 msgstr "importa i valori di fiducia"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "errore cercando il record della fiducia: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "errore di lettura: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "trustdb: sync fallita: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "impossibile creare `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "impossibile aprire `%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb rec %lu: lseek fallita: %s\n"
@@ -5245,13 +5066,21 @@ msgstr "trustdb rec %lu: scrittura fallita (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "transazione del trustdb troppo grande\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "impossibile chiudere `%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: la directory non esiste!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossibile chiudere `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "impossibile creare `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "impossibile aprire `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5337,7 +5166,7 @@ msgid "input line longer than %d characters\n"
 msgstr "linea di input più lunga di %d caratteri\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' non è un key ID lungo valido\n"
 
 #, fuzzy, c-format
@@ -5379,14 +5208,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5438,11 +5259,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "il prossimo controllo del trustdb sarà fatto il %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "non è necessario un controllo del trustdb\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "non è necessario un controllo del trustdb\n"
 
 #, fuzzy, c-format
@@ -5513,11 +5334,6 @@ msgid "missing argument"
 msgstr "argomento non valido"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armatura non valida"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "comandi in conflitto\n"
 
@@ -5538,10 +5354,6 @@ msgstr "opzioni di importazione non valide\n"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "opzioni di importazione non valide\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5571,8 +5383,12 @@ msgstr "opzioni di importazione non valide\n"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "hai trovato un bug... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "errore leggendo `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5580,15 +5396,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "impossibile aprire il file: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "creazione dell'armatura fallita: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "impossibile creare la directory `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "errore scrivendo il portachiavi `%s': %s\n"
 
 #, c-format
@@ -5606,7 +5422,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "chiave pubblica %08lX non trovata: %s\n"
 
 #, fuzzy, c-format
@@ -5623,11 +5439,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Uso: gpg [opzioni] [files] (-h per l'aiuto)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Uso: gpg [opzioni] [files] (-h per l'aiuto)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5756,9 +5571,6 @@ msgstr "Per favore scegli il motivo della revoca:\n"
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5769,14 +5581,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "cambia la passphrase"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "cambia la passphrase"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "errore leggendo il keyblock: %s\n"
 
@@ -5843,9 +5647,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "Non sono stati trovati dati OpenPGP validi.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "cambia la passphrase"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5881,16 +5684,13 @@ msgstr "non usa per niente il terminale"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "comandi in conflitto\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Uso: gpg [opzioni] [files] (-h per l'aiuto)"
@@ -5900,7 +5700,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5920,7 +5720,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5956,7 +5756,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "impossibile aprire `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5985,7 +5785,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "cancellazione del keyblock fallita: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "inizializzazione del trustdb fallita: %s\n"
 
 #, fuzzy
@@ -6174,16 +5974,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "errore scrivendo il portachiavi segreto `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6205,11 +6005,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6217,11 +6017,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "L'indirizzo di email non è valido\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "errore creando il portachiavi `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "errore creando il portachiavi `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6292,7 +6092,7 @@ msgid "No subject name given\n"
 msgstr "(Non è stata data una descrizione)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6301,7 +6101,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "algoritmo di hash non valido `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6347,7 +6147,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "chiave `%s' non trovata: %s\n"
 
 #, fuzzy, c-format
@@ -6355,11 +6155,11 @@ msgid "error locking keybox: %s\n"
 msgstr "errore leggendo il keyblock: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Certificato di revoca creato.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "la preferenza %c%lu è doppia\n"
 
 #, fuzzy, c-format
@@ -6396,6 +6196,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "cambia la passphrase"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "crea un output ascii con armatura"
 
@@ -6473,8 +6277,8 @@ msgstr "Uso: gpg [opzioni] [files] (-h per l'aiuto)"
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintassi: gpg [opzioni] [files]\n"
 "firma, controlla, cifra o decifra\n"
@@ -6485,11 +6289,11 @@ msgid "usage: gpgsm [options] "
 msgstr "uso: gpg [opzioni] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "impossibile connettersi a `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "destinatario predefinito `%s' sconosciuto\n"
 
 #, fuzzy, c-format
@@ -6512,11 +6316,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "scrittura in `%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "impossibile chiudere `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6533,6 +6337,10 @@ msgstr "genera un certificato di revoca"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "inizializzazione del trustdb fallita: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "errore nella creazione della passhprase: %s\n"
@@ -6546,11 +6354,14 @@ msgid "error reading input: %s\n"
 msgstr "errore leggendo `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "errore creando il portachiavi `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "portachiavi `%s' creato\n"
 
 #, fuzzy
@@ -6584,11 +6395,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "errore: impronta digitale non valida\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6709,7 +6520,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "destinatario predefinito `%s' sconosciuto\n"
 
 #, fuzzy, c-format
@@ -6940,7 +6751,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "impossibile aprire il file: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "impossibile creare la directory `%s': %s\n"
 
 #, fuzzy, c-format
@@ -7036,17 +6847,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "errore leggendo `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "inizializzazione del trustdb fallita: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Comando> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "Il trustdb è danneggiato; eseguire \"gpg --fix-trust-db\".\n"
 
@@ -7593,6 +7393,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "pacchetto non valido"
 
+#~ msgid "invalid armor"
+#~ msgstr "armatura non valida"
+
 #~ msgid "no such user id"
 #~ msgstr "l'user id non esiste"
 
@@ -7602,6 +7405,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "è stata usata la chiave segreta sbagliata"
 
+#~ msgid "not supported"
+#~ msgstr "non gestito"
+
 #~ msgid "bad key"
 #~ msgstr "chiave sbagliata"
 
@@ -7617,6 +7423,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "errore durante la creazione del file"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "passphrase non valida"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritmo della chiave pubblica non implementato"
 
index 23176f9..db6258e 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -7,11 +7,11 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: GNU gnupg 2.0.30\n"
+"Project-Id-Version: gnupg 2.1\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-12-18 14:34+0900\n"
+"PO-Revision-Date: 2014-08-12 16:21+0200\n"
 "Last-Translator: NIIBE Yutaka <gniibe@fsij.org>\n"
-"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
+"Language-Team: none\n"
 "Language: ja\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -31,33 +31,15 @@ msgid "|pinentry-label|_OK"
 msgstr "|pinentry-label|_OK"
 
 msgid "|pinentry-label|_Cancel"
-msgstr "|pinentry-label|キャンセル(_C)"
-
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_Yes"
-
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_No"
+msgstr "|pinentry-label|_キャンセル"
 
 msgid "|pinentry-label|PIN:"
 msgstr "|pinentry-label|PIN:"
 
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|パスワードマネージャに保存する(_S)"
-
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "本当に画面にパスフレーズを見えるようにしますか?"
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr "|pinentry-tt|パスフレーズを見えるようにする"
-
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "|pinentry-tt|パスフレーズを隠す"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
-msgstr "品質:"
+msgstr "品質: %s"
 
 #. TRANSLATORS: This string is a tooltip, shown by pinentry when
 #. hovering over the quality bar.  Please use an appropriate
@@ -82,6 +64,9 @@ msgstr ""
 "あなたのパスフレーズを入力してください(このセッションで秘密鍵のロックを解除す"
 "るために使われます)"
 
+msgid "does not match - try again"
+msgstr "一致しません - もう一度"
+
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
@@ -89,6 +74,9 @@ msgstr ""
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (現在 %d / 最大 %d)"
 
+msgid "Repeat:"
+msgstr ""
+
 msgid "PIN too long"
 msgstr "PINが長すぎます"
 
@@ -115,12 +103,12 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "ssh鍵で%dビットより大きいものはサポートされません\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
-msgstr "「%s」が作成できません: %s\n"
+msgid "can't create '%s': %s\n"
+msgstr "'%s'が作成できません: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
-msgstr "「%s」が開けません: %s\n"
+msgid "can't open '%s': %s\n"
+msgstr "'%s'が開けません: %s\n"
 
 #, c-format
 msgid "error getting serial number of card: %s\n"
@@ -131,8 +119,8 @@ msgid "detected card with S/N: %s\n"
 msgstr "カードを検出しました。シリアル番号: %s\n"
 
 #, c-format
-msgid "error getting default authentication keyID of card: %s\n"
-msgstr "ã\82«ã\83¼ã\83\89ã\81®ã\83\87ã\83\95ã\82©ã\83«ã\83\88èª\8d証keyIDã\81®å\8f\96å¾\97ã\82¨ã\83©ã\83¼: %s\n"
+msgid "no authentication key for ssh on card: %s\n"
+msgstr "ã\82«ã\83¼ã\83\89ã\81«sshã\81®èª\8d証é\8dµã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93: %s\n"
 
 #, c-format
 msgid "no suitable card key found: %s\n"
@@ -175,9 +163,6 @@ msgstr ""
 "パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A   %s"
 "%%0A   %s%%0Aを保護します。"
 
-msgid "does not match - try again"
-msgstr "一致しません - もう一度"
-
 #, c-format
 msgid "failed to create stream from socket: %s\n"
 msgstr "ソケットからストリームを作成するのに失敗しました: %s\n"
@@ -197,14 +182,14 @@ msgid "PUK"
 msgstr "PUK"
 
 msgid "Reset Code"
-msgstr "リセット・コード"
+msgstr "Reset Code"
 
 #, c-format
 msgid "%s%%0A%%0AUse the reader's pinpad for input."
 msgstr "%s%%0A%%0Aリーダーのピンパッドを入力に使ってください。"
 
 msgid "Repeat this Reset Code"
-msgstr "このリセット・コードをもう一度入力してください"
+msgstr "このReset Codeをもう一度入力してください"
 
 msgid "Repeat this PUK"
 msgstr "このPUKをもう一度入力してください"
@@ -213,7 +198,7 @@ msgid "Repeat this PIN"
 msgstr "このPINをもう一度入力してください"
 
 msgid "Reset Code not correctly repeated; try again"
-msgstr "リセット・コードが正しく繰り返されていません。もう一度"
+msgstr "Reset Codeが正しく繰り返されていません。もう一度"
 
 msgid "PUK not correctly repeated; try again"
 msgstr "PUKが正しく繰り返されていません。もう一度"
@@ -241,36 +226,6 @@ msgstr "それでもこれを使います"
 
 #, c-format
 msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u character long."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u characters long."
-msgstr[0] ""
-"警告: 安全とは言えないパスフレーズが入力されました。%%0Aパスフレーズは最低%u"
-"文字であるべきです。"
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digit or%%0Aspecial character."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digits or%%0Aspecial characters."
-msgstr[0] ""
-"警告: 安全とは言えないパスフレーズが入力されました。%%0Aパスフレーズは最低%u"
-"文字の数字もしくは%%0A特殊文字を含むべきです。"
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
-"a known term or match%%0Acertain pattern."
-msgstr ""
-"警告: 安全とは言えないパスフレーズが入力されました。%%0Aパスフレーズには、よ"
-"く知られている用語や%%0A特定のパターンにマッチするものは避けましょう。"
-
-#, c-format
-msgid ""
 "You have not entered a passphrase!%0AAn empty passphrase is not allowed."
 msgstr ""
 "パスフレーズが入力されませんでした!%0A空のパスフレーズは認められません。"
@@ -286,6 +241,47 @@ msgstr ""
 msgid "Yes, protection is not needed"
 msgstr "はい、保護は必要ありません"
 
+#, fuzzy, c-format
+#| msgid "Name must be at least 5 characters long\n"
+msgid "A passphrase should be at least %u character long."
+msgid_plural "A passphrase should be at least %u characters long."
+msgstr[0] "名前は5文字以上でなければなりません\n"
+
+#, fuzzy, c-format
+#| msgid ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "contain at least %u digit or%%0Aspecial character."
+#| msgid_plural ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "contain at least %u digits or%%0Aspecial characters."
+msgid "A passphrase should contain at least %u digit or%%0Aspecial character."
+msgid_plural ""
+"A passphrase should contain at least %u digits or%%0Aspecial characters."
+msgstr[0] ""
+"警告: 安全とは言えないパスフレーズが入力されました。%%0Aパスフレーズは最低%u"
+"文字の数字もしくは%%0A特殊文字を含むべきです。"
+
+#, fuzzy, c-format
+#| msgid ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase may not "
+#| "be a known term or match%%0Acertain pattern."
+msgid "A passphrase may not be a known term or match%%0Acertain pattern."
+msgstr ""
+"警告: 安全とは言えないパスフレーズが入力されました。%%0Aパスフレーズには、よ"
+"く知られている用語や%%0A特定のパターンにマッチするものは避けましょう。"
+
+#, fuzzy
+#| msgid ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "be at least %u character long."
+#| msgid_plural ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "be at least %u characters long."
+msgid "Warning: You have entered an insecure passphrase."
+msgstr ""
+"警告: 安全とは言えないパスフレーズが入力されました。%%0Aパスフレーズは最低%u"
+"文字であるべきです。"
+
 #, c-format
 msgid "Please enter the passphrase to%0Aprotect your new key"
 msgstr "新しい鍵を保護するために、%0Aパスフレーズを入力してください。"
@@ -330,9 +326,6 @@ msgstr "キーボードとマウスを占有しない"
 msgid "use a log file for the server"
 msgstr "サーバのログ・ファイルを使う"
 
-msgid "use a standard location for the socket"
-msgstr "ソケットに標準の場所を使う"
-
 msgid "|PGM|use PGM as the PIN-Entry program"
 msgstr "|PGM|PGMをPIN入力プログラムとして使う"
 
@@ -361,16 +354,10 @@ msgid "allow presetting passphrase"
 msgstr "パスフレーズの事前設定を認める"
 
 msgid "enable ssh support"
-msgstr "sshã\82µã\83\9dã\83¼ã\83\88ã\82\92æ\9c\89å\8a¹にする"
+msgstr "sshã\82µã\83\9dã\83¼ã\83\88ã\82\92æ\9c\89å\8a\9fにする"
 
 msgid "enable putty support"
-msgstr "puttyサポートを有効にする"
-
-msgid "disallow the use of an external password cache"
-msgstr "外部のパスワードキャッシュの使用を認めない"
-
-msgid "|FILE|write environment settings also to FILE"
-msgstr "|FILE|FILEに環境変数の設定も書き出す"
+msgstr "puttyサポートを有功にする"
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
@@ -378,43 +365,39 @@ msgstr "|FILE|FILEに環境変数の設定も書き出す"
 msgid "Please report bugs to <@EMAIL@>.\n"
 msgstr "バグは <@EMAIL@> までご報告ください。\n"
 
-msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "使い方: gpg-agent [オプション] (ヘルプは -h)"
+msgid "Usage: @GPG_AGENT@ [options] (-h for help)"
+msgstr "使い方: @GPG_AGENT@ [オプション] (ヘルプは -h)"
 
 msgid ""
-"Syntax: gpg-agent [options] [command [args]]\n"
-"Secret key management for GnuPG\n"
+"Syntax: @GPG_AGENT@ [options] [command [args]]\n"
+"Secret key management for @GNUPG@\n"
 msgstr ""
-"形式: gpg-agent [オプション] [コマンド [引数]]\n"
-"GnuPGの秘密鍵の管理\n"
+"形式: @GPG_AGENT@ [オプション] [コマンド [引数]]\n"
+"@GnuPG@の秘密鍵の管理\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
-msgstr "無効なdebug-level「%s」が与えられました\n"
+msgid "invalid debug-level '%s' given\n"
+msgstr "無効なdebug-level '%s'が与えられました\n"
 
 #, c-format
 msgid "%s is too old (need %s, have %s)\n"
 msgstr "%s が古すぎます (%s が必要、現在 %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
-msgstr "*注意*: デフォルトのオプション・ファイル「%s」がありません\n"
-
-#, c-format
-msgid "option file `%s': %s\n"
-msgstr "オプション・ファイル「%s」: %s\n"
+msgid "Note: no default option file '%s'\n"
+msgstr "*注意*: デフォルトのオプション・ファイル '%s' がありません\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
-msgstr "ã\80\8c%sã\80\8dã\81\8bã\82\89ã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\92読ã\81¿è¾¼ã\81¿ã\81¾ã\81\99\n"
+msgid "option file '%s': %s\n"
+msgstr "ã\82ªã\83\97ã\82·ã\83§ã\83³ã\83»ã\83\95ã\82¡ã\82¤ã\83« '%s': %s\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
-msgstr "「%s」の作成エラー: %s\n"
+msgid "reading options from '%s'\n"
+msgstr "'%s' からオプションを読み込みます\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "ディレクトリ「%s」が作成できません: %s\n"
+msgid "Note: '%s' is not considered an option\n"
+msgstr "*注意*: '%s'はオプションとは考えられません\n"
 
 msgid "name of socket too long\n"
 msgstr "ソケット名が長すぎます\n"
@@ -424,8 +407,8 @@ msgid "can't create socket: %s\n"
 msgstr "ソケットが作成できません: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
-msgstr "ソケット名「%s」は長すぎます\n"
+msgid "socket name '%s' is too long\n"
+msgstr "ソケット名'%s'は長すぎます\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
 msgstr "gpg-agentは既に実行されています - 新しいものをスタートさせません\n"
@@ -434,28 +417,32 @@ msgid "error getting nonce for the socket\n"
 msgstr "ソケットのナンス取得エラー\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
-msgstr "ソケットの「%s」へのバインドのエラー: %s\n"
+msgid "error binding socket to '%s': %s\n"
+msgstr "'%s'でソケットのバインドのエラー: %s\n"
 
 #, c-format
 msgid "listen() failed: %s\n"
 msgstr "listen() に失敗しました: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
-msgstr "ソケット「%s」でlisten\n"
+msgid "listening on socket '%s'\n"
+msgstr "ソケット'%s'でlisten\n"
 
 #, c-format
-msgid "directory `%s' created\n"
-msgstr "ディレクトリ「%s」が作成されました\n"
+msgid "can't create directory '%s': %s\n"
+msgstr "ディレクトリ'%s'が作成できません: %s\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
-msgstr "ã\80\8c%sã\80\8dã\81§stat()ã\81\8c失æ\95\97ã\81\97ã\81¾ã\81\97ã\81\9f: %s\n"
+msgid "directory '%s' created\n"
+msgstr "ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ª'%s'ã\81\8cä½\9cæ\88\90ã\81\95ã\82\8cã\81¾ã\81\97ã\81\9f\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
-msgstr "「%s」をホーム・ディレクトリに使えません\n"
+msgid "stat() failed for '%s': %s\n"
+msgstr "'%s'でstat()が失敗しました: %s\n"
+
+#, c-format
+msgid "can't use '%s' as home directory\n"
+msgstr "'%s'をホーム・ディレクトリに使えません\n"
 
 #, c-format
 msgid "error reading nonce on fd %d: %s\n"
@@ -478,8 +465,8 @@ msgid "ssh handler 0x%lx for fd %d terminated\n"
 msgstr "ssh ハンドラ0x%lx (fd %d に対する)が終了\n"
 
 #, c-format
-msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "pth_selectに失敗しました: %s - 一秒待ちます\n"
+msgid "npth_pselect failed: %s - waiting 1s\n"
+msgstr "npth_pselectに失敗しました: %s - 一秒待ちます\n"
 
 #, c-format
 msgid "%s %s stopped\n"
@@ -488,13 +475,6 @@ msgstr "%s %s 停止しました\n"
 msgid "no gpg-agent running in this session\n"
 msgstr "このセッションでgpg-agentは実行されていません\n"
 
-msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "GPG_AGENT_INFO環境変数が壊れています\n"
-
-#, c-format
-msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "gpg-agentプロトコル・バージョン%dはサポートされていません\n"
-
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
 msgstr "使い方: gpg-preset-passphrase [オプション] KEYGRIP (ヘルプは -h)\n"
 
@@ -563,32 +543,32 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "パスフレーズを問い合わせする際、エラー: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
-msgstr "「%s」を開く際、エラー: %s\n"
+msgid "error opening '%s': %s\n"
+msgstr "'%s'を開く際、エラー: %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
-msgstr "ファイル「%s」(行 %d): %s\n"
+msgid "file '%s', line %d: %s\n"
+msgstr "ファイル'%s'(行 %d): %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
-msgstr "ステートメント \"%s\" は「%s」で無視されました(行 %d)\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
+msgstr "ステートメント \"%s\" は'%s'で無視されました(行 %d)\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
-msgstr "システム信用リスト「%s」が得られません\n"
+msgid "system trustlist '%s' not available\n"
+msgstr "システム信用リスト'%s'が得られません\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
-msgstr "「%s」の不正なフィンガープリント (行 %d)\n"
+msgid "bad fingerprint in '%s', line %d\n"
+msgstr "'%s'の不正なフィンガープリント (行 %d)\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
-msgstr "「%s」の無効な鍵フラグ(行 %d)\n"
+msgid "invalid keyflag in '%s', line %d\n"
+msgstr "'%s'の無効な鍵フラグ(行 %d)\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
-msgstr "「%s」の読み込みエラー(行 %d): %s\n"
+msgid "error reading '%s', line %d: %s\n"
+msgstr "'%s'の読み込みエラー(行 %d): %s\n"
 
 msgid "error reading list of trusted root certificates\n"
 msgstr "信用されたルート証明書のリストの読み込みエラ−\n"
@@ -626,7 +606,7 @@ msgid ""
 "Please verify that the certificate identified as:%%0A  \"%s\"%%0Ahas the "
 "fingerprint:%%0A  %s"
 msgstr ""
-"確èª\8dã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82証æ\98\8eæ\9b¸:%%0A  \"%s\"%%0Aã\81¯ä¸\8bè¨\98ã\81®ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\82\92æ\8c\81ã\81¤:"
+"確認してください。証明書:%%0A  \"%s\"%%0Aは下記のフィンガープリントを持つ:"
 "%%0A  %s"
 
 #. TRANSLATORS: "Correct" is the label of a button and intended
@@ -656,13 +636,49 @@ msgstr "パスフレーズを変更する"
 msgid "I'll change it later"
 msgstr "後で変更する"
 
+msgid "Delete key"
+msgstr "鍵を削除する"
+
+msgid ""
+"Warning: This key is also listed for use with SSH!\n"
+"Deleting the key might remove your ability to access remote machines."
+msgstr ""
+"警告: この鍵はSSHの使用にもリストされています!\n"
+"この鍵を削除するとリモート・マシンのアクセスの能力を失うかもしれません。"
+
+msgid "DSA requires the hash length to be a multiple of 8 bits\n"
+msgstr "DSAは8ビットの倍数のハッシュ長を必要とします\n"
+
+#, c-format
+msgid "%s key uses an unsafe (%u bit) hash\n"
+msgstr "%s 鍵は安全でない(%uビット)ハッシュを使用しています\n"
+
+#, c-format
+msgid "a %zu bit hash is not valid for a %u bit %s key\n"
+msgstr "%zuビットのハッシュは%uビットの%s鍵には無効です\n"
+
+msgid "secret key parts are not available\n"
+msgstr "秘密部分が得られません\n"
+
+#, c-format
+msgid "public key algorithm %d (%s) is not supported\n"
+msgstr "公開鍵アルゴリズム%d (%s)はサポートされていません\n"
+
+#, c-format
+msgid "protection algorithm %d (%s) is not supported\n"
+msgstr "保護アルゴリズム%d (%s)はサポートされていません\n"
+
+#, c-format
+msgid "protection hash algorithm %d (%s) is not supported\n"
+msgstr "保護ハッシュ・アルゴリズム%d (%s)はサポートされていません\n"
+
 #, c-format
 msgid "error creating a pipe: %s\n"
 msgstr "パイプの作成エラー: %s\n"
 
 #, c-format
-msgid "can't fdopen pipe for reading: %s\n"
-msgstr "ã\83\91ã\82¤ã\83\97ã\82\92読ã\81¿è¾¼ã\81¿ã\81®ã\81\9fã\82\81ã\81«fdopenã\81§ã\81\8dã\81¾ã\81\9bã\82\93: %s\n"
+msgid "error creating a stream for a pipe: %s\n"
+msgstr "ã\83\91ã\82¤ã\83\97ã\81®ã\82¹ã\83\88ã\83ªã\83¼ã\83 ä½\9cæ\88\90ã\82¨ã\83©ã\83¼: %s\n"
 
 #, c-format
 msgid "error forking process: %s\n"
@@ -673,34 +689,27 @@ msgid "waiting for process %d to terminate failed: %s\n"
 msgstr "プロセス%dの終了待ちが失敗: %s\n"
 
 #, c-format
-msgid "error getting exit code of process %d: %s\n"
-msgstr "プロセス %d のexitコード取得エラー: %s\n"
-
-#, c-format
-msgid "error running `%s': exit status %d\n"
-msgstr "「%s」の実行エラー: exitステイタス %d\n"
+msgid "error running '%s': probably not installed\n"
+msgstr "'%s'の実行エラー: おそらくインストールされていません\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "「%s」の実行エラー: おそらくインストールされていません\n"
+msgid "error running '%s': exit status %d\n"
+msgstr "'%s'の実行エラー: exitステイタス %d\n"
 
 #, c-format
-msgid "error running `%s': terminated\n"
-msgstr "「%s」の実行エラー: 終了しました\n"
+msgid "error running '%s': terminated\n"
+msgstr "'%s'の実行エラー: 終了しました\n"
 
 #, c-format
-msgid "error creating socket: %s\n"
-msgstr "ソケット作成エラー: %s\n"
-
-msgid "host not found"
-msgstr "ホストが見つかりません"
+msgid "error getting exit code of process %d: %s\n"
+msgstr "プロセス %d のexitコード取得エラー: %s\n"
 
 msgid "gpg-agent is not available in this session\n"
-msgstr "ã\81\93ã\81®ã\82»ã\83\83ã\82·ã\83§ã\83³ã\81§gpg-agentã\81\8cå\88©ç\94¨ã\81§ã\81\8dã\81¾ã\81\9bã\82\93\n"
+msgstr "ã\81\93ã\81®ã\82»ã\83\83ã\82·ã\83§ã\83³ã\81§gpg-agentã\81¯ç\84¡å\8a¹ã\81§ã\81\99\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
-msgstr "「%s」へ接続できません: %s\n"
+msgid "can't connect to '%s': %s\n"
+msgstr "'%s'へ接続できません: %s\n"
 
 msgid "communication problem with gpg-agent\n"
 msgstr "gpg-agentとの通信障害\n"
@@ -720,11 +729,11 @@ msgstr "コア・ダンプを無効にできません: %s\n"
 
 #, c-format
 msgid "Warning: unsafe ownership on %s \"%s\"\n"
-msgstr "警告: 「%s」の安全でない所有 \"%s\"\n"
+msgstr "警告: '%s'の安全でない所有者 \"%s\"\n"
 
 #, c-format
 msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgstr "警告: 「%s」の安全でない許可 \"%s\"\n"
+msgstr "警告: '%s'の安全でない許可 \"%s\"\n"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "yes"
@@ -769,15 +778,27 @@ msgstr "%luバイトの確保においてセキュア・メモリが足りませ
 msgid "out of core while allocating %lu bytes"
 msgstr "%luバイトの確保においてメモリが足りません"
 
-msgid "no running gpg-agent - starting one\n"
-msgstr "gpg-agentが動いていません - 開始します\n"
+#, c-format
+msgid "no running gpg-agent - starting '%s'\n"
+msgstr "gpg-agentが実行されていません - '%s'を開始します\n"
 
 #, c-format
-msgid "waiting %d seconds for the agent to come up\n"
+msgid "waiting for the agent to come up ... (%ds)\n"
 msgstr "agentの起動のため、%d秒待ちます\n"
 
-msgid "can't connect to the agent - trying fall back\n"
-msgstr "agentに接続できません - フォールバックしてみます\n"
+msgid "connection to agent established\n"
+msgstr "エージェントへの接続が確立しました。\n"
+
+#, c-format
+msgid "no running Dirmngr - starting '%s'\n"
+msgstr "dirmngrが動いていません - 開始します'%s'\n"
+
+#, c-format
+msgid "waiting for the dirmngr to come up ... (%ds)\n"
+msgstr "dirmngrの起動のため、%d秒待ちます\n"
+
+msgid "connection to the dirmngr established\n"
+msgstr "dirmngrへの接続が確立しました\n"
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
@@ -913,8 +934,8 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr利用可能"
 
 #, c-format
-msgid "No help available for `%s'."
-msgstr "「%s」のヘルプはありません。"
+msgid "No help available for '%s'."
+msgstr "'%s'のヘルプはありません。"
 
 msgid "ignoring garbage line"
 msgstr "ガベージ行を無視します"
@@ -922,6 +943,110 @@ msgstr "ガベージ行を無視します"
 msgid "[none]"
 msgstr "[未設定]"
 
+msgid "argument not expected"
+msgstr "引数は期待されていません"
+
+msgid "read error"
+msgstr "読み込みエラー"
+
+msgid "keyword too long"
+msgstr "キーワードが長すぎます"
+
+msgid "missing argument"
+msgstr "引数ありません"
+
+#, fuzzy
+#| msgid "invalid value\n"
+msgid "invalid argument"
+msgstr "無効な値\n"
+
+msgid "invalid command"
+msgstr "無効なコマンド"
+
+msgid "invalid alias definition"
+msgstr "無効なエイリアス定義です"
+
+msgid "out of core"
+msgstr "メモリがありません"
+
+msgid "invalid option"
+msgstr "無効なオプション"
+
+#, c-format
+msgid "missing argument for option \"%.50s\"\n"
+msgstr "オプション\"%.50s\"に引数がありません\n"
+
+#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "invalid argument for option \"%.50s\"\n"
+msgstr "オプション\"%.50s\"に引数がありません\n"
+
+#, c-format
+msgid "option \"%.50s\" does not expect an argument\n"
+msgstr "オプション\"%.50s\"は引数をとりません\n"
+
+#, c-format
+msgid "invalid command \"%.50s\"\n"
+msgstr "無効なコマンド \"%.50s\"\n"
+
+#, c-format
+msgid "option \"%.50s\" is ambiguous\n"
+msgstr "オプション\"%.50s\"はあいまいです\n"
+
+#, c-format
+msgid "command \"%.50s\" is ambiguous\n"
+msgstr "コマンド\"%.50s\"はあいまいです\n"
+
+msgid "out of core\n"
+msgstr "メモリがありません\n"
+
+#, c-format
+msgid "invalid option \"%.50s\"\n"
+msgstr "無効なオプション \"%.50s\"\n"
+
+#, c-format
+msgid "you found a bug ... (%s:%d)\n"
+msgstr "あなたはバグを発見しました ... (%s:%d)\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr "'%s'から'%s'への変換は利用できません\n"
+
+#, c-format
+msgid "iconv_open failed: %s\n"
+msgstr "iconv_openに失敗しました: %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "'%s'から'%s'への変換に失敗: %s\n"
+
+#, c-format
+msgid "failed to create temporary file '%s': %s\n"
+msgstr "一時ファイル'%s'が作成できません: %s\n"
+
+#, c-format
+msgid "error writing to '%s': %s\n"
+msgstr "'%s'の書き込みエラー: %s\n"
+
+#, c-format
+msgid "removing stale lockfile (created by %d)\n"
+msgstr "古い lockfile (%d により作成)を除去します\n"
+
+#, c-format
+msgid "waiting for lock (held by %d%s) %s...\n"
+msgstr "lockを待ちます (%d%s により保持) %s...\n"
+
+msgid "(deadlock?) "
+msgstr "(デッドロック?) "
+
+#, c-format
+msgid "lock '%s' not made: %s\n"
+msgstr "lock '%s' は作成されませんでした: %s\n"
+
+#, c-format
+msgid "waiting for lock %s...\n"
+msgstr "lock %s を待ちます...\n"
+
 #, c-format
 msgid "armor: %s\n"
 msgstr "外装: %s\n"
@@ -1005,6 +1130,13 @@ msgid "not human readable"
 msgstr "人には読めません"
 
 #, c-format
+msgid "failed to proxy %s inquiry to client\n"
+msgstr "プロキシ%sのクライアントへの問い合わせが失敗しました\n"
+
+msgid "Enter passphrase: "
+msgstr "パスフレーズを入力: "
+
+#, c-format
 msgid "OpenPGP card not available: %s\n"
 msgstr "OpenPGPカードが利用できません: %s\n"
 
@@ -1013,13 +1145,13 @@ msgid "OpenPGP card no. %s detected\n"
 msgstr "OpenPGPカードno. %sを検出\n"
 
 msgid "can't do this in batch mode\n"
-msgstr "ã\81\93れはバッチ・モードではできません\n"
+msgstr "ã\81\9dれはバッチ・モードではできません\n"
 
 msgid "This command is only available for version 2 cards\n"
 msgstr "このコマンドが使えるのはバージョン2のカードだけです\n"
 
 msgid "Reset Code not or not anymore available\n"
-msgstr "リセット・コードが(もはや)利用可能ではありません\n"
+msgstr "Reset Codeが(もはや)利用可能ではありません\n"
 
 msgid "Your selection? "
 msgstr "あなたの選択は? "
@@ -1073,12 +1205,12 @@ msgid "error allocating enough memory: %s\n"
 msgstr "十分なメモリの確保のエラー: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
-msgstr "「%s」の読み込みエラー: %s\n"
+msgid "error reading '%s': %s\n"
+msgstr "'%s'の読み込みエラー: %s\n"
 
 #, c-format
-msgid "error writing `%s': %s\n"
-msgstr "「%s」の書き込みエラー: %s\n"
+msgid "error writing '%s': %s\n"
+msgstr "'%s'の書き込みエラー: %s\n"
 
 msgid "Login data (account name): "
 msgstr "ログイン・データ (アカウント名): "
@@ -1104,16 +1236,16 @@ msgid "Error: invalid characters in preference string.\n"
 msgstr "エラー: 優先指定の文字列に無効な文字があります。\n"
 
 msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "性別 ((M)男、(F)女、または空白): "
+msgstr "性別 ((M)男、(F)女、空白): "
 
 msgid "Error: invalid response.\n"
 msgstr "エラー: 無効な応答。\n"
 
 msgid "CA fingerprint: "
-msgstr "CAã\81®ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88: "
+msgstr "CAのフィンガープリント: "
 
 msgid "Error: invalid formatted fingerprint.\n"
-msgstr "ã\82¨ã\83©ã\83¼: ç\84¡å\8a¹ã\81ªå½¢å¼\8fã\81®ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\80\82\n"
+msgstr "エラー: 無効な形式のフィンガープリント。\n"
 
 #, c-format
 msgid "key operation not possible: %s\n"
@@ -1127,16 +1259,16 @@ msgid "error getting current key info: %s\n"
 msgstr "現行鍵情報の取得エラー: %s\n"
 
 msgid "Replace existing key? (y/N) "
-msgstr "既存の鍵を置き換えしますか? (y/N) "
+msgstr "既存の鍵を交換しますか? (y/N) "
 
 msgid ""
-"NOTE: There is no guarantee that the card supports the requested size.\n"
+"Note: There is no guarantee that the card supports the requested size.\n"
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
 "*注意*: カードが要求された鍵長をサポートしているという保証はありません。\n"
 "        鍵生成が成功しない場合、あなたのカードに関する技術文書を確認し、\n"
-"        利用できる鍵長について確認ください。\n"
+"        利用できる鍵長についてみてください。\n"
 
 #, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
@@ -1144,7 +1276,7 @@ msgstr "署名鍵の鍵長は? (%u) "
 
 #, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "暗号鍵の鍵長は? (%u) "
+msgstr "暗号鍵の鍵長は? (%u) "
 
 #, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
@@ -1167,9 +1299,9 @@ msgid "error changing size of key %d to %u bits: %s\n"
 msgstr "鍵%dの長さを%u bit に変更する際にエラー: %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
-msgstr "暗号鍵のカード外バックアップを作成しますか? (Y/n) "
+msgstr "暗号鍵のカード外バックアップを作成しますか? (Y/n) "
 
-msgid "NOTE: keys are already stored on the card!\n"
+msgid "Note: keys are already stored on the card!\n"
 msgstr "*注意*: 秘密鍵はもうカードに保管してあります!\n"
 
 msgid "Replace existing keys? (y/N) "
@@ -1178,11 +1310,11 @@ msgstr "既存の鍵を置き換えますか? (y/N) "
 #, c-format
 msgid ""
 "Please note that the factory settings of the PINs are\n"
-"   PIN = `%s'     Admin PIN = `%s'\n"
+"   PIN = '%s'     Admin PIN = '%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
 "工場設定のPINは下記のとおり\n"
-"   PIN = `%s'     管理者PIN = `%s'\n"
+"   PIN = '%s'     Admin PIN = '%s'\n"
 "次のコマンドを使って変更すべきです --change-pin\n"
 
 msgid "Please select the type of key to generate:\n"
@@ -1201,20 +1333,11 @@ msgid "Invalid selection.\n"
 msgstr "無効な選択です。\n"
 
 msgid "Please select where to store the key:\n"
-msgstr "鍵の保管場所を選択してください:\n"
-
-msgid "unknown key protection algorithm\n"
-msgstr "不明の鍵保護アルゴリズムです\n"
-
-msgid "secret parts of key are not available\n"
-msgstr "鍵の秘密部分が利用できません\n"
-
-msgid "secret key already stored on a card\n"
-msgstr "秘密鍵はもうカードに保管してあります\n"
+msgstr "鍵を保管する場所を選択してください:\n"
 
 #, c-format
-msgid "error writing key to card: %s\n"
-msgstr "鍵のカード書き込みエラー: %s\n"
+msgid "KEYTOCARD failed: %s\n"
+msgstr "KEYTOCARDが失敗しました: %s\n"
 
 msgid "quit this menu"
 msgstr "このメニューを終了"
@@ -1235,7 +1358,7 @@ msgid "change URL to retrieve key"
 msgstr "鍵を取得するURLの変更"
 
 msgid "fetch the key specified in the card URL"
-msgstr "ã\82«ã\83¼ã\83\89URLã\81§æ\8c\87å®\9aã\81\95ã\82\8cã\81\9fé\8dµã\81®å\8f\96å¾\97"
+msgstr "ã\82«ã\83¼ã\83\89URLã\81§æ\8c\87å®\9aã\81\95ã\82\8cã\81\9fé\8dµã\81®å¼\95ã\81\8då\87ºã\81\97"
 
 msgid "change the login name"
 msgstr "ログイン名の変更"
@@ -1247,7 +1370,7 @@ msgid "change card holder's sex"
 msgstr "カード所有者の性別の変更"
 
 msgid "change a CA fingerprint"
-msgstr "CAã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\81®å¤\89æ\9b´"
+msgstr "CAフィンガープリントの変更"
 
 msgid "toggle the signature force PIN flag"
 msgstr "署名強制PINフラグを反転"
@@ -1262,19 +1385,19 @@ msgid "verify the PIN and list all data"
 msgstr "PINを確認しすべてのデータを表示する"
 
 msgid "unblock the PIN using a Reset Code"
-msgstr "PINをリセット・コードでブロックを解除する"
+msgstr "PINをReset Codeで再設定する"
 
 msgid "gpg/card> "
 msgstr "gpg/card> "
 
 msgid "Admin-only command\n"
-msgstr "管理専用コマンド\n"
+msgstr "管理専用コマンド\n"
 
 msgid "Admin commands are allowed\n"
-msgstr "管理コマンドが許可されています\n"
+msgstr "管理コマンドが許可されています\n"
 
 msgid "Admin commands are not allowed\n"
-msgstr "管理コマンドは禁止されています\n"
+msgstr "管理コマンドは禁止されています\n"
 
 msgid "Invalid command  (try \"help\")\n"
 msgstr "無効なコマンド (\"help\"を参照)\n"
@@ -1283,8 +1406,8 @@ msgid "--output doesn't work for this command\n"
 msgstr "このコマンドで--outputは機能しません\n"
 
 #, c-format
-msgid "can't open `%s'\n"
-msgstr "「%s」が開けません\n"
+msgid "can't open '%s'\n"
+msgstr "'%s'が開けません\n"
 
 #, c-format
 msgid "key \"%s\" not found: %s\n"
@@ -1295,7 +1418,7 @@ msgid "error reading keyblock: %s\n"
 msgstr "鍵ブロックの読み込みエラー: %s\n"
 
 msgid "(unless you specify the key by fingerprint)\n"
-msgstr "(ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\81§é\8dµã\82\92æ\8c\87å®\9aã\81\97ã\81¦ã\81ªã\81\84é\99\90ã\82\8a)\n"
+msgstr "(ã\81\82ã\82\8bã\81\84ã\81¯ã\80\81ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83\97ã\83ªã\83³ã\83\88ã\81§é\8dµã\82\92æ\8c\87å®\9a)\n"
 
 msgid "can't do this in batch mode without \"--yes\"\n"
 msgstr "\"--yes\"なしでバッチ・モードではできません\n"
@@ -1307,6 +1430,16 @@ msgid "This is a secret key! - really delete? (y/N) "
 msgstr "これは秘密鍵です! 本当に削除しますか? (y/N) "
 
 #, c-format
+msgid "deleting secret %s failed: %s\n"
+msgstr "秘密%sの削除に失敗しました: %s\n"
+
+msgid "key"
+msgstr "鍵"
+
+msgid "subkey"
+msgstr "サブ鍵: "
+
+#, c-format
 msgid "deleting keyblock failed: %s\n"
 msgstr "鍵ブロックの削除に失敗しました: %s\n"
 
@@ -1332,23 +1465,16 @@ msgid "using cipher %s\n"
 msgstr "暗号方式 %s を使います\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
-msgstr "「%s」はもう圧縮済みです\n"
+msgid "'%s' already compressed\n"
+msgstr "'%s'はもう圧縮済みです\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
-msgstr "*警告*: 「%s」は空のファイルです\n"
-
-msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
-msgstr "--pgp2モードでは2048ビット以下のRSA鍵で暗号化しかできません\n"
+msgid "WARNING: '%s' is an empty file\n"
+msgstr "*警告*: '%s'は空のファイルです\n"
 
 #, c-format
-msgid "reading from `%s'\n"
-msgstr "「%s」から読み込み\n"
-
-msgid ""
-"unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
-msgstr "暗号化しようとしている鍵は全部IDEA暗号を使えません。\n"
+msgid "reading from '%s'\n"
+msgstr "'%s'から読み込み\n"
 
 #, c-format
 msgid ""
@@ -1396,20 +1522,20 @@ msgstr "遠隔プログラムの実行は、サポートしていません\n"
 msgid ""
 "external program calls are disabled due to unsafe options file permissions\n"
 msgstr ""
-"オプション・ファイルの許可モードが安全ではないので、外部プログラムの呼出しは"
-"禁止となります。\n"
+"オプション・ファイルの許可モードが、安全ではないので、\n"
+"外部プログラムの呼出しは、使用禁止です。\n"
 
 msgid "this platform requires temporary files when calling external programs\n"
 msgstr ""
 "このプラットホームだと、外部プログラムの呼出しには、一時ファイルが必要です\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
-msgstr "プログラム「%s」を実行できません: %s\n"
+msgid "unable to execute program '%s': %s\n"
+msgstr "'%s'を実行できません: %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
-msgstr "シェル「%s」を実行できません: %s\n"
+msgid "unable to execute shell '%s': %s\n"
+msgstr "シェル'%s'を実行できません: %s\n"
 
 #, c-format
 msgid "system error while calling external program: %s\n"
@@ -1426,12 +1552,12 @@ msgid "unable to read external program response: %s\n"
 msgstr "外部プログラムの応答を読み込めません: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
-msgstr "*警告*: 一時ファイルを削除できません (%s) 「%s」: %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
+msgstr "*警告*: 一時ファイルを削除できません (%s) '%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
-msgstr "*警告*: 一時ディレクトリ「%s」を削除できません: %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
+msgstr "*警告*: 一時ディレクトリ'%s'を削除できません: %s\n"
 
 msgid "export signatures that are marked as local-only"
 msgstr "ローカルのみと指定された署名をエクスポートします"
@@ -1442,9 +1568,6 @@ msgstr "ユーザIDの属性(通常フォトID)をエクスポートします"
 msgid "export revocation keys marked as \"sensitive\""
 msgstr "\"sensitive\"(機密)と指定された失効鍵をエクスポートします"
 
-msgid "remove the passphrase from exported subkeys"
-msgstr "エクスポートされた副鍵のパスフレーズを除去する"
-
 msgid "remove unusable parts from key during export"
 msgstr "エクスポートの際、利用できない部分を除去する"
 
@@ -1458,10 +1581,6 @@ msgid "exporting secret keys not allowed\n"
 msgstr "秘密鍵のエクスポートは認められません\n"
 
 #, c-format
-msgid "key %s: not protected - skipped\n"
-msgstr "鍵%s: 保護されていません - スキップします\n"
-
-#, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
 msgstr "鍵%s: PGP 2.x形式の鍵です - スキップします\n"
 
@@ -1469,50 +1588,31 @@ msgstr "鍵%s: PGP 2.x形式の鍵です - スキップします\n"
 msgid "key %s: key material on-card - skipped\n"
 msgstr "鍵%s: 鍵はカード上にあります - スキップします\n"
 
-msgid "about to export an unprotected subkey\n"
-msgstr "保護されていない副鍵を、エクスポートしようとしています\n"
-
-#, c-format
-msgid "failed to unprotect the subkey: %s\n"
-msgstr "副鍵の保護を解除するのに失敗しました: %s\n"
-
-#, c-format
-msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr "*警告*: 秘密鍵%sには、単純なSKチェックサムがありません\n"
+msgid " - skipped"
+msgstr " - スキップされました"
 
 msgid "WARNING: nothing exported\n"
-msgstr "*警告*: 何もエクスポートされていません\n"
-
-msgid "too many entries in pk cache - disabled\n"
-msgstr "pkキャッシュのエントリーが多すぎます - 使用禁止\n"
+msgstr "*警告*: 何もエクスポートしていません\n"
 
 msgid "[User ID not found]"
 msgstr "[ユーザIDが見つかりません]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "鍵%s: 公開鍵のない秘密鍵です - スキップします\n"
+msgid "automatically retrieved '%s' via %s\n"
+msgstr "'%s'を %s から自動取得\n"
 
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
-msgstr "「%s」を %s から自動取得\n"
-
-#, c-format
-msgid "error retrieving `%s' via %s: %s\n"
-msgstr "「%s」を %s から取得する際のエラー: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
+msgstr "'%s'を %s から取得する際のエラー: %s\n"
 
 msgid "No fingerprint"
-msgstr "ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93"
+msgstr "フィンガープリントがありません"
 
 #, c-format
 msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
 msgstr "--allow-non-selfsigned-uidで有効にされた無効な鍵%sです\n"
 
 #, c-format
-msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "公開副鍵%sに対する秘密副鍵がありません - 無視\n"
-
-#, c-format
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "副鍵%s(主鍵%sではなく)を用います\n"
 
@@ -1523,7 +1623,7 @@ msgid "make a clear text signature"
 msgstr "クリア・テクスト署名を作成"
 
 msgid "make a detached signature"
-msgstr "å\88\86é\81£署名を作成"
+msgstr "å\88\86é\9b¢署名を作成"
 
 msgid "encrypt data"
 msgstr "データを暗号化"
@@ -1547,7 +1647,7 @@ msgid "list and check key signatures"
 msgstr "鍵署名の検査と一覧"
 
 msgid "list keys and fingerprints"
-msgstr "é\8dµã\81¨ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\81®ä¸\80覧"
+msgstr "鍵とフィンガープリントの一覧"
 
 msgid "list secret keys"
 msgstr "秘密鍵の一覧"
@@ -1555,6 +1655,14 @@ msgstr "秘密鍵の一覧"
 msgid "generate a new key pair"
 msgstr "新しい鍵対を生成"
 
+#, fuzzy
+#| msgid "generate a new key pair"
+msgid "quickly generate a new key pair"
+msgstr "新しい鍵対を生成"
+
+msgid "full featured key pair generation"
+msgstr ""
+
 msgid "generate a revocation certificate"
 msgstr "失効証明書を生成"
 
@@ -1564,6 +1672,12 @@ msgstr "公開鍵リングから鍵を削除"
 msgid "remove keys from the secret keyring"
 msgstr "秘密鍵リングから鍵を削除"
 
+msgid "quickly sign a key"
+msgstr "鍵にすばやく署名"
+
+msgid "quickly sign a key locally"
+msgstr "鍵へすばやくローカルに署名"
+
 msgid "sign a key"
 msgstr "鍵に署名"
 
@@ -1661,20 +1775,20 @@ msgstr ""
 "\n"
 " -se -r Bob [ファイル]      ユーザBobへ署名と暗号化\n"
 " --clearsign [ファイル]     クリア・テクスト署名を作成\n"
-" --detach-sign [ã\83\95ã\82¡ã\82¤ã\83«]   å\88\86é\81£署名を作成\n"
+" --detach-sign [ã\83\95ã\82¡ã\82¤ã\83«]   å\88\86é\9b¢署名を作成\n"
 " --list-keys [名前]         鍵を表示\n"
-" --fingerprint [å\90\8då\89\8d]       ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\82\92表示\n"
+" --fingerprint [名前]       フィンガープリントを表示\n"
 
-msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "使い方: gpg [オプション] [ファイル] (ヘルプは -h)"
+msgid "Usage: @GPG@ [options] [files] (-h for help)"
+msgstr "使い方: @GPG@ [オプション] [ファイル] (ヘルプは -h)"
 
 msgid ""
-"Syntax: gpg [options] [files]\n"
+"Syntax: @GPG@ [options] [files]\n"
 "Sign, check, encrypt or decrypt\n"
 "Default operation depends on the input data\n"
 msgstr ""
-"形式: gpg [オプション] [ファイル]\n"
-"ç½²å\90\8dã\80\81æ¤\9cæ\9f»ã\80\81æ\9a\97å\8f·å\8c\96ã\82\84復号\n"
+"形式: @GPG@ [オプション] [ファイル]\n"
+"ç½²å\90\8dã\80\81æ¤\9cæ\9f»ã\80\81æ\9a\97å\8f·å\8c\96ã\81¾ã\81\9fã\81¯復号\n"
 "デフォルトの操作は、入力データに依存\n"
 
 msgid ""
@@ -1696,94 +1810,99 @@ msgstr "ハッシュ: "
 msgid "Compression: "
 msgstr "圧縮: "
 
-msgid "usage: gpg [options] "
-msgstr "使い方: gpg [オプション] "
+#, c-format
+msgid "usage: %s [options] %s\n"
+msgstr "使い方: %s [オプション] %s\n"
 
 msgid "conflicting commands\n"
 msgstr "対立するコマンド\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
-msgstr "=記号が、グループ定義「%s」内に見つかりません\n"
+msgid "no = sign found in group definition '%s'\n"
+msgstr "=記号が、グループ定義'%s'内に見つかりません\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
-msgstr "*警告*: homedir 「%s」の安全でない所有\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
+msgstr "*警告*: homedir '%s'の安全でない所有者\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
-msgstr "*警告*: コンフィグレーション・ファイル「%s」の安全でない所有\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
+msgstr "*警告*: コンフィグレーション・ファイル'%s'の安全でない所有者\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
-msgstr "*警告*: 拡張「%s」の安全でない所有\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
+msgstr "*警告*: 拡張'%s'の安全でない所有者\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
-msgstr "*警告*: homedir 「%s」の安全でない許可\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
+msgstr "*警告*: homedir '%s'の安全でない許可\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
-msgstr "*警告*: コンフィグレーション・ファイル「%s」の安全でない許可\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
+msgstr "*警告*: コンフィグレーション・ファイル'%s'の安全でない許可\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
-msgstr "*警告*: 拡張「%s」の安全でない許可\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
+msgstr "*警告*: 拡張'%s'の安全でない許可\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
-msgstr "*警告*: homedir 「%s」の安全でない上位ディレクトリ所有\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
+msgstr "*警告*: homedir '%s'の安全でない上位ディレクトリ所有者\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory ownership on configuration file '%s'\n"
 msgstr ""
-"*警告*: コンフィグレーション・ファイル「%s」の安全でない上位ディレクトリ所"
-"\n"
+"*警告*: コンフィグレーション・ファイル'%s'の安全でない上位ディレクトリ所有"
+"\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
-msgstr "*警告*: 拡張「%s」の安全でない上位ディレクトリ所有\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
+msgstr "*警告*: 拡張'%s'の安全でない上位ディレクトリ所有者\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
-msgstr "*警告*: homedir 「%s」の安全でない上位ディレクトリ許可\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
+msgstr "*警告*: homedir '%s'の安全でない上位ディレクトリ許可\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory permissions on configuration file '%s'\n"
 msgstr ""
-"*警告*: コンフィグレーション・ファイル「%s」の安全でない上位ディレクトリ許"
-"可\n"
+"*警告*: コンフィグレーション・ファイル'%s'の安全でない上位ディレクトリ許可\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
-msgstr "*警告*: 拡張「%s」の安全でない上位ディレクトリ許可\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
+msgstr "*警告*: 拡張'%s'の安全でない上位ディレクトリ許可\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
-msgstr "不明のコンフィグレーション項目「%s」\n"
+msgid "unknown configuration item '%s'\n"
+msgstr "不明のコンフィグレーション項目'%s'\n"
 
 msgid "display photo IDs during key listings"
-msgstr "鍵の一覧時にフォトIDを表示する"
+msgstr "鍵の一覧にフォトIDを表示する"
+
+#, fuzzy
+#| msgid "show user ID validity during key listings"
+msgid "show key usage information during key listings"
+msgstr "鍵の一覧にユーザIDの有効性を表示する"
 
 msgid "show policy URLs during signature listings"
-msgstr "署名の一覧時にポリシーURLを表示する"
+msgstr "署名の一覧にポリシURLを表示する"
 
 msgid "show all notations during signature listings"
-msgstr "署名の一覧にすべての注釈を表示する"
+msgstr "署名の一覧にすべての注釈を表示する"
 
 msgid "show IETF standard notations during signature listings"
-msgstr "署名の一覧にIETF標準注釈を表示する"
+msgstr "署名の一覧にIETF標準注釈を表示する"
 
 msgid "show user-supplied notations during signature listings"
-msgstr "署名の一覧にユーザの注釈を表示する"
+msgstr "署名の一覧にユーザの注釈を表示する"
 
 msgid "show preferred keyserver URLs during signature listings"
-msgstr "署名の一覧に優先鍵サーバURLを表示する"
+msgstr "署名の一覧に優先鍵サーバURLを表示する"
 
 msgid "show user ID validity during key listings"
-msgstr "鍵の一覧にユーザIDの有効性を表示する"
+msgstr "鍵の一覧にユーザIDの有効性を表示する"
 
 msgid "show revoked and expired user IDs in key listings"
 msgstr "鍵の一覧に失効したユーザID、期限切れとなったユーザIDを表示する"
@@ -1795,28 +1914,31 @@ msgid "show the keyring name in key listings"
 msgstr "鍵の一覧に鍵リングの名前を表示する"
 
 msgid "show expiration dates during signature listings"
-msgstr "署名の一覧に有効期限の日付を表示する"
+msgstr "署名の一覧に有効期限の日付を表示する"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
-msgstr ""
-"*注意*: 以前デフォルトだったオプション・ファイル「%s」は、無視されます\n"
+msgid "Note: old default options file '%s' ignored\n"
+msgstr "*注意*: 以前デフォルトだったオプション・ファイル'%s'は、無視されます\n"
 
 #, c-format
 msgid "libgcrypt is too old (need %s, have %s)\n"
-msgstr "libgcrypt ã\81\8c古すぎます (必要 %s, 現在 %s)\n"
+msgstr "libgcrypt ã\81¯古すぎます (必要 %s, 現在 %s)\n"
 
 #, c-format
-msgid "NOTE: %s is not for normal use!\n"
+msgid "Note: %s is not for normal use!\n"
 msgstr "*注意*: 普通%sは使いません!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
-msgstr "「%s」は、有効な署名期限ではありません\n"
+msgid "'%s' is not a valid signature expiration\n"
+msgstr "'%s'は、有効な署名表現ではありません\n"
+
+#, c-format
+msgid "invalid pinentry mode '%s'\n"
+msgstr "無効な pinentry mode '%s'です\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
-msgstr "「%s」は、有効な文字集合ではありません\n"
+msgid "'%s' is not a valid character set\n"
+msgstr "'%s'は、有効な文字集合ではありません\n"
 
 msgid "could not parse keyserver URL\n"
 msgstr "鍵サーバのURLを解析不能\n"
@@ -1853,7 +1975,7 @@ msgid "display photo IDs during signature verification"
 msgstr "署名の検証時にフォトIDを表示する"
 
 msgid "show policy URLs during signature verification"
-msgstr "署名の検証時にポリシURLを表示する"
+msgstr "署名の検証時にポリシURLを表示する"
 
 msgid "show all notations during signature verification"
 msgstr "署名の検証時にすべての注釈を表示する"
@@ -1901,7 +2023,7 @@ msgid "invalid auto-key-locate list\n"
 msgstr "無効な auto-key-locate リストです\n"
 
 msgid "WARNING: program may create a core file!\n"
-msgstr "*è­¦å\91\8a*: ã\83\97ã\83­ã\82°ã\83©ã\83 ã\81¯coreã\83\95ã\82¡ã\82¤ã\83«ã\82\92ä½\9cæ\88\90ã\81\99ることがあります!\n"
+msgstr "*è­¦å\91\8a*: ã\83\97ã\83­ã\82°ã\83©ã\83 ã\81®ã\82³ã\82¢ã\83»ã\83\95ã\82¡ã\82¤ã\83«ã\81\8cã\81§ã\81\8dることがあります!\n"
 
 #, c-format
 msgid "WARNING: %s overrides %s\n"
@@ -1915,22 +2037,13 @@ msgstr "%sは%sとともに使うことはできません!\n"
 msgid "%s makes no sense with %s!\n"
 msgstr "%sは%sとともに使っても無意味です!\n"
 
+msgid "WARNING: running with faked system time: "
+msgstr "*警告*: ニセモノのシステム時刻で実行しています: "
+
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
 msgstr "%s のため、セキュアでないメモリで実行しません\n"
 
-msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
-msgstr "--pgp2モードでは分遣署名かクリア・テクスト署名だけしかできません\n"
-
-msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr "--pgp2モードでは署名と暗号化を同時にできません\n"
-
-msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr "--pgp2を指定したら、(パイプでなく) ファイルを指定せねばなりません。\n"
-
-msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr "--pgp2モードのメッセージ暗号化では、IDEA暗号方式が必要です\n"
-
 msgid "selected cipher algorithm is invalid\n"
 msgstr "選択された暗号アルゴリズムは、無効です\n"
 
@@ -1958,7 +2071,7 @@ msgstr "無効なdefault-cert-level。0か1か2か3でなければなりませ
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
 msgstr "無効なmin-cert-level。0か1か2か3でなければなりません\n"
 
-msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
+msgid "Note: simple S2K mode (0) is strongly discouraged\n"
 msgstr "*注意*: 単純なS2Kモード(0)の使用には強く反対します\n"
 
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
@@ -1981,16 +2094,16 @@ msgid "%s does not yet work with %s\n"
 msgstr "%sは%sではまだ機能しません\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
-msgstr "暗号アルゴリズム「%s」を%sモードで使うことはできません\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgstr "暗号アルゴリズム'%s'を%sモードで使うことはできません\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
-msgstr "ダイジェスト・アルゴリズム「%s」を%sモードで使うことはできません\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgstr "ダイジェスト・アルゴリズム'%s'を%sモードで使うことはできません\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
-msgstr "圧縮アルゴリズム「%s」を%sモードで使うことはできません\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgstr "圧縮アルゴリズム'%s'を%sモードで使うことはできません\n"
 
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
@@ -2006,8 +2119,8 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [ファイル名]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
-msgstr "「%s」の共通鍵暗号に失敗しました: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
+msgstr "'%s'の共通鍵暗号に失敗しました: %s\n"
 
 msgid "--encrypt [filename]"
 msgstr "--encrypt [ファイル名]"
@@ -2077,7 +2190,7 @@ msgstr "鍵サーバの検索に失敗しました: %s\n"
 
 #, c-format
 msgid "keyserver refresh failed: %s\n"
-msgstr "鍵サーバの更新に失敗しました: %s\n"
+msgstr "鍵サーバの回復に失敗しました: %s\n"
 
 #, c-format
 msgid "dearmoring failed: %s\n"
@@ -2088,8 +2201,8 @@ msgid "enarmoring failed: %s\n"
 msgstr "外装に失敗しました: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
-msgstr "無効なハッシュ・アルゴリズム「%s」です\n"
+msgid "invalid hash algorithm '%s'\n"
+msgstr "無効なハッシュ・アルゴリズム'%s'です\n"
 
 msgid "[filename]"
 msgstr "[ファイル名]"
@@ -2098,10 +2211,10 @@ msgid "Go ahead and type your message ...\n"
 msgstr "開始します。メッセージを打ってください ...\n"
 
 msgid "the given certification policy URL is invalid\n"
-msgstr "あたえられた証明書ポリシURLは無効です\n"
+msgstr "あたえられた証明書ポリシURLは無効です\n"
 
 msgid "the given signature policy URL is invalid\n"
-msgstr "あたえられた署名ポリシURLは無効です\n"
+msgstr "あたえられた署名ポリシURLは無効です\n"
 
 msgid "the given preferred keyserver URL is invalid\n"
 msgstr "指定された優先鍵サーバURLは無効です\n"
@@ -2129,23 +2242,17 @@ msgid "No help available"
 msgstr "ヘルプはありません"
 
 #, c-format
-msgid "No help available for `%s'"
-msgstr "「%s」のヘルプはありません"
+msgid "No help available for '%s'"
+msgstr "'%s'のヘルプはありません"
 
 msgid "import signatures that are marked as local-only"
 msgstr "ローカルだけとマークされた署名をインポートします"
 
 msgid "repair damage from the pks keyserver during import"
-msgstr "インポートの際、にpksキーサーバからのダメージを修正します"
-
-msgid "do not clear the ownertrust values during import"
-msgstr "インポートの際、所有者信用の値をクリアしない"
+msgstr "インポート時にpksキーサーバからのダメージを修正します"
 
 msgid "do not update the trustdb after import"
-msgstr "インポート後、信用データベースを更新しない"
-
-msgid "create a public key when importing a secret key"
-msgstr "秘密鍵をインポートしたときに公開鍵を作成します"
+msgstr "インポートの際、信用データベースを更新しない"
 
 msgid "only accept updates to existing keys"
 msgstr "既存の鍵に対する更新のみ認めます"
@@ -2154,7 +2261,7 @@ msgid "remove unusable parts from key after import"
 msgstr "インポート後、利用できない部分を鍵から除去します"
 
 msgid "remove as much as possible from key after import"
-msgstr "インポート後、できるだけ除去します"
+msgstr "インポート後、できるだけ除去します"
 
 #, c-format
 msgid "skipping block of type %d\n"
@@ -2162,11 +2269,11 @@ msgstr "型%dのブロックをスキップします\n"
 
 #, c-format
 msgid "%lu keys processed so far\n"
-msgstr "これまで%lu個の鍵を処理\n"
+msgstr "%lu鍵まで処理\n"
 
 #, c-format
 msgid "Total number processed: %lu\n"
-msgstr "          処理数の合計: %lu\n"
+msgstr "        処理数の合計: %lu\n"
 
 #, c-format
 msgid "      skipped new keys: %lu\n"
@@ -2258,12 +2365,13 @@ msgstr "以下で、優先指定を更新できます: gpg --edit-key %s updpref
 msgid "key %s: no user ID\n"
 msgstr "鍵%s: ユーザIDがありません\n"
 
-#, c-format
+#, fuzzy, c-format
+#| msgid "skipped \"%s\": %s\n"
 msgid "key %s: %s\n"
-msgstr "鍵%s: %s\n"
+msgstr "\"%s\"をスキップしました: %s\n"
 
-msgid "rejected by import filter"
-msgstr "インポート・フィルタにより拒否されました"
+msgid "rejected by import screener"
+msgstr ""
 
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
@@ -2293,12 +2401,12 @@ msgid "no writable keyring found: %s\n"
 msgstr "書き込み可能な鍵リングが見つかりません: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
-msgstr "「%s」への書き込み\n"
+msgid "writing to '%s'\n"
+msgstr "'%s'への書き込み\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
-msgstr "鍵リング「%s」の書き込みエラー: %s\n"
+msgid "error writing keyring '%s': %s\n"
+msgstr "鍵リング'%s'の書き込みエラー: %s\n"
 
 #, c-format
 msgid "key %s: public key \"%s\" imported\n"
@@ -2361,31 +2469,28 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "鍵%s:\"%s\"変更なし\n"
 
 #, c-format
-msgid "secret key %s: %s\n"
-msgstr "秘密鍵 %s: %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "秘密鍵のインポートは禁止です\n"
+msgid "key %s: secret key imported\n"
+msgstr "鍵%s: 秘密鍵をインポートしました\n"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "鍵%s: 無効な暗号方式%dの秘密鍵です - スキップします\n"
+msgid "key %s: secret key already exists\n"
+msgstr "鍵 %s: 秘密鍵はもうあります\n"
 
 #, c-format
-msgid "no default secret keyring: %s\n"
-msgstr "デフォルトの秘密鍵リングがありません: %s\n"
+msgid "key %s: error sending to agent: %s\n"
+msgstr "鍵 %s: エージェントへの送信エラー: %s\n"
 
-#, c-format
-msgid "key %s: secret key imported\n"
-msgstr "鍵%s: 秘密鍵をインポートしました\n"
+#, fuzzy, c-format
+#| msgid "secret key \"%s\" not found: %s\n"
+msgid "secret key %s: %s\n"
+msgstr "秘密鍵\"%s\"が見つかりません: %s\n"
 
-#, c-format
-msgid "key %s: already in secret keyring\n"
-msgstr "鍵%s: 既に秘密鍵リングにあります\n"
+msgid "importing secret keys not allowed\n"
+msgstr "秘密鍵のインポートは禁止です\n"
 
 #, c-format
-msgid "key %s: secret key not found: %s\n"
-msgstr "é\8dµ%s: ç§\98å¯\86é\8dµã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "é\8dµ%s: ç\84¡å\8a¹ã\81ªæ\9a\97å\8f·æ\96¹å¼\8f%dã\81®ç§\98å¯\86é\8dµã\81§ã\81\99 - ã\82¹ã\82­ã\83\83ã\83\97ã\81\97ã\81¾ã\81\99\n"
 
 #, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
@@ -2477,11 +2582,11 @@ msgstr "鍵%s: 重複したユーザIDの検出 - マージ\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
-msgstr "*警告*: 鍵%sは失効されたかもしれません: 失効鍵%sを取ってきます\n"
+msgstr "*警告*: 鍵%sは失効可能です: 失効鍵%sを取ってきます\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
-msgstr "*警告*: 鍵%sは失効されたかもしれません: 失効鍵%sが存在しません。\n"
+msgstr "*警告*: 鍵%sは失効可能です: 失効鍵%sが存在しません。\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate added\n"
@@ -2491,26 +2596,25 @@ msgstr "鍵%s:\"%s\"失効証明書の追加\n"
 msgid "key %s: direct key signature added\n"
 msgstr "鍵%s: 直接鍵署名を追加\n"
 
-msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr "*注意*: 鍵のシリアル番号がカードのものと一致しません\n"
-
-msgid "NOTE: primary key is online and stored on card\n"
-msgstr "*注意*: 主鍵はもうカードに保管してあります\n"
+#, c-format
+msgid "error creating keybox '%s': %s\n"
+msgstr "keybox'%s'の作成エラー: %s\n"
 
-msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "*注意*: 二次鍵はもうカードに保管してあります\n"
+#, c-format
+msgid "error creating keyring '%s': %s\n"
+msgstr "鍵リング'%s'の作成エラー: %s\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
-msgstr "鍵リング「%s」の作成エラー: %s\n"
+msgid "keybox '%s' created\n"
+msgstr "keybox'%s'が作成されました\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
-msgstr "鍵リング「%s」を作成しました\n"
+msgid "keyring '%s' created\n"
+msgstr "鍵リング'%s'ができました\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
-msgstr "keyblock リソース「%s」: %s\n"
+msgid "keyblock resource '%s': %s\n"
+msgstr "keyblock リソース'%s': %s\n"
 
 #, c-format
 msgid "failed to rebuild keyring cache: %s\n"
@@ -2557,8 +2661,8 @@ msgid ""
 "etc.)\n"
 msgstr ""
 "他のユーザの鍵を正しく検証するために、このユーザの信用度を決めてください\n"
-"(ã\83\91ã\82¹ã\83\9dã\83¼ã\83\88ã\82\92è¦\8bã\81\9bã\81¦ã\82\82ã\82\89ã\81£ã\81\9fã\82\8aã\80\81ä»\96ã\81\8bã\82\89å¾\97ã\81\9fã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\82\92æ¤\9cæ\9f»ã\81\97ã\81\9fã\82\8aã\80\81ã\81ª"
-"ã\81©ã\81ªã\81©)\n"
+"(ã\83\91ã\82¹ã\83\9dã\83¼ã\83\88ã\82\92è¦\8bã\81\9bã\81¦ã\82\82ã\82\89ã\81£ã\81\9fã\82\8aã\80\81ä»\96ã\81\8bã\82\89å¾\97ã\81\9fã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83\97ã\83ªã\83³ã\83\88ã\82\92æ¤\9cæ\9f»ã\81\97ã\81\9fã\82\8aã\80\81ã\81ªã\81©"
+"など)\n"
 
 #, c-format
 msgid "  %d = I trust marginally\n"
@@ -2632,14 +2736,14 @@ msgid ""
 "is a local signature.\n"
 msgstr ""
 "\"%s\"にたいするあなたの今の署名\n"
-"はローカルな署名です。\n"
+"は内部署名です。\n"
 
 msgid "Do you want to promote it to a full exportable signature? (y/N) "
 msgstr "エクスポート可能な署名に格上げしたいですか? (y/N) "
 
 #, c-format
 msgid "\"%s\" was already locally signed by key %s\n"
-msgstr "\"%s\"は鍵%sでもうローカルに署名してあります\n"
+msgstr "\"%s\"は鍵%sでもう内部署名してあります\n"
 
 #, c-format
 msgid "\"%s\" was already signed by key %s\n"
@@ -2663,14 +2767,6 @@ msgid "Do you want your signature to expire at the same time? (Y/n) "
 msgstr "同時に署名も期限切れとしたいですか? (Y/n) "
 
 msgid ""
-"You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
-"mode.\n"
-msgstr "--pgp2モードではPGP 2.x鍵でOpenPGP署名ができません。\n"
-
-msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "この鍵はPGP 2.xで使用できなくなります。\n"
-
-msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
@@ -2694,8 +2790,8 @@ msgstr "   (2) 一応、検査しました。%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) かなり注意して検査しました。%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
-msgstr "選択は? (詳細は '?' で): "
+msgid "Your selection? (enter '?' for more information): "
+msgstr "選択は? (詳細は '?'): "
 
 #, c-format
 msgid ""
@@ -2741,41 +2837,9 @@ msgstr ""
 "鍵にはスタブあるいはカード上の項目しかありません - パスフレーズは変更されませ"
 "ん。\n"
 
-msgid "This key is not protected.\n"
-msgstr "この鍵は保護されていません。\n"
-
-msgid "Secret parts of primary key are not available.\n"
-msgstr "主鍵の秘密部分が利用できません。\n"
-
-msgid "Secret parts of primary key are stored on-card.\n"
-msgstr "主鍵の秘密部分はカード上に保存されています。\n"
-
-msgid "Key is protected.\n"
-msgstr "鍵は保護されています。\n"
-
-#, c-format
-msgid "Can't edit this key: %s\n"
-msgstr "この鍵は編集できません: %s\n"
-
-msgid ""
-"Enter the new passphrase for this secret key.\n"
-"\n"
-msgstr ""
-"この秘密鍵の新しいパスフレーズを入力してください。\n"
-"\n"
-
-msgid "passphrase not correctly repeated; try again"
-msgstr "パスフレーズをちゃんと繰り返していません。再入力してください"
-
-msgid ""
-"You don't want a passphrase - this is probably a *bad* idea!\n"
-"\n"
-msgstr ""
-"パスフレーズが不必要なようですが、おそらくそれは良くない考えです!\n"
-"\n"
-
-msgid "Do you really want to do this? (y/N) "
-msgstr "本当に実行しますか? (y/N) "
+#, c-format
+msgid "key %s: error changing passphrase: %s\n"
+msgstr "鍵 %s: パスフレーズの変更エラー: %s\n"
 
 msgid "moving a key signature to the correct place\n"
 msgstr "鍵の署名を正しい場所に移動します\n"
@@ -2784,7 +2848,7 @@ msgid "save and quit"
 msgstr "保存して終了"
 
 msgid "show key fingerprint"
-msgstr "é\8dµã\81®ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\82\92表示"
+msgstr "鍵のフィンガープリントを表示"
 
 msgid "list key and user IDs"
 msgstr "鍵とユーザIDの一覧"
@@ -2793,7 +2857,7 @@ msgid "select user ID N"
 msgstr "ユーザID Nの選択"
 
 msgid "select subkey N"
-msgstr "副鍵Nの選択"
+msgstr "subkey Nの選択"
 
 msgid "check signatures"
 msgstr "署名の確認"
@@ -2823,13 +2887,13 @@ msgid "add a subkey"
 msgstr "副鍵を追加"
 
 msgid "add a key to a smartcard"
-msgstr "スマートカードへ鍵の追加"
+msgstr "ICカードへ鍵の追加"
 
 msgid "move a key to a smartcard"
-msgstr "鍵をスマートカードへ移動"
+msgstr "鍵をICカードへ移動"
 
 msgid "move a backup key to a smartcard"
-msgstr "バックアップ鍵をスマートカードへ移動"
+msgstr "バックアップ鍵をICカードへ移動"
 
 msgid "delete selected subkeys"
 msgstr "選択した副鍵の削除"
@@ -2859,7 +2923,7 @@ msgid "set preference list for the selected user IDs"
 msgstr "選択したユーザIDに優先指定リストを設定"
 
 msgid "set the preferred keyserver URL for the selected user IDs"
-msgstr "選択したユーザIDに優先鍵サーバのURLを設定"
+msgstr "選択したユーザIDに優先鍵サーバのURIを設定"
 
 msgid "set a notation for the selected user IDs"
 msgstr "選択したユーザIDに注釈を設定する"
@@ -2874,7 +2938,7 @@ msgid "revoke signatures on the selected user IDs"
 msgstr "選択したユーザIDの署名を失効"
 
 msgid "revoke selected user IDs"
-msgstr "選択したユーザIDの失効"
+msgstr "ユーザIDの失効"
 
 msgid "revoke key or selected subkeys"
 msgstr "鍵の失効または選択した副鍵の失効"
@@ -2894,10 +2958,6 @@ msgstr "使えないユーザIDをコンパクトにし、使えない署名を
 msgid "compact unusable user IDs and remove all signatures from key"
 msgstr "使えないユーザIDをコンパクトにし、すべての署名を鍵から除去"
 
-#, c-format
-msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "秘密鍵ブロック\"%s\"の読み込みエラー: %s\n"
-
 msgid "Secret key is available.\n"
 msgstr "秘密鍵が使用できます。\n"
 
@@ -2908,13 +2968,13 @@ msgid "Please use the command \"toggle\" first.\n"
 msgstr "まず\"toggle\"コマンドを使ってください。\n"
 
 msgid ""
-"* The `sign' command may be prefixed with an `l' for local signatures "
+"* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
-"  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
+"  a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
-"* `sign' コマンドは `l' で始まると、ローカルの署名で (lsign)、\n"
-"  `t' で始まると信用署名 (tsign)、`nr' で始まると失効不可署名\n"
+"* 'sign' コマンドは 'l' で始まると、ローカルの署名で (lsign)、\n"
+"  't' で始まると信用署名 (tsign)、'nr' で始まると失効不可署名\n"
 "  (nrsign)、もしくはこれらの組み合わせ (ltsign, tnrsign, など)となります。\n"
 
 msgid "Key is revoked."
@@ -2927,8 +2987,8 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "ヒント: まず署名するユーザIDを選択します\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
-msgstr "不明の署名タイプ「%s」\n"
+msgid "Unknown signature type '%s'\n"
+msgstr "不明の署名タイプ'%s'\n"
 
 #, c-format
 msgid "This command is not allowed while in %s mode.\n"
@@ -2958,12 +3018,12 @@ msgid "Command expects a filename argument\n"
 msgstr "コマンドはファイル名の引数を期待します\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
-msgstr "「%s」が開けません: %s\n"
+msgid "Can't open '%s': %s\n"
+msgstr "'%s'が開けません: %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
-msgstr "バックアップ鍵を「%s」から読み込みする際のエラー: %s\n"
+msgid "Error reading backup key from '%s': %s\n"
+msgstr "バックアップ鍵を'%s'から読み込みする際のエラー: %s\n"
 
 msgid "You must select at least one key.\n"
 msgstr "鍵を少なくとも1本選択してください。\n"
@@ -2981,7 +3041,7 @@ msgid "Really revoke this user ID? (y/N) "
 msgstr "このユーザIDを本当に失効しますか? (y/N) "
 
 msgid "Do you really want to revoke the entire key? (y/N) "
-msgstr "この鍵全体を本当に失効しますか? (y/N) "
+msgstr "鍵全体を本当に失効しますか? (y/N) "
 
 msgid "Do you really want to revoke the selected subkeys? (y/N) "
 msgstr "選択した副鍵を本当に失効しますか? (y/N) "
@@ -3012,13 +3072,23 @@ msgstr "保存せずに終了しますか? (y/N) "
 msgid "update failed: %s\n"
 msgstr "更新に失敗しました: %s\n"
 
-#, c-format
-msgid "update secret failed: %s\n"
-msgstr "秘密の更新に失敗しました: %s\n"
-
 msgid "Key not changed so no update needed.\n"
 msgstr "鍵は無変更なので更新は不要です。\n"
 
+#, c-format
+msgid "\"%s\" is not a fingerprint\n"
+msgstr "\"%s\"はフィンガープリントではありません\n"
+
+#, c-format
+msgid "\"%s\" is not the primary fingerprint\n"
+msgstr "\"%s\" はプライマリ・フィンガープリントではありません\n"
+
+msgid "No matching user IDs."
+msgstr "マッチするユーザIDはありません。"
+
+msgid "Nothing to sign.\n"
+msgstr "署名するものがありません。\n"
+
 msgid "Digest: "
 msgstr "ダイジェスト: "
 
@@ -3039,7 +3109,7 @@ msgstr "PGP 2.x形式ユーザIDの優先指定が、ありません。\n"
 
 #, c-format
 msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "%sで%s鍵%sによって以下の鍵は、失効されました\n"
+msgstr "%s で %s 鍵によってこの鍵は、失効されました: %s\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
@@ -3068,6 +3138,9 @@ msgstr "有効期限: %s"
 msgid "usage: %s"
 msgstr "利用法: %s"
 
+msgid "card-no: "
+msgstr "カード番号: "
+
 #, c-format
 msgid "trust: %s"
 msgstr "信用: %s"
@@ -3079,9 +3152,6 @@ msgstr "有効性: %s"
 msgid "This key has been disabled"
 msgstr "この鍵は使用禁止に設定されています"
 
-msgid "card-no: "
-msgstr "カード番号: "
-
 msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
@@ -3103,10 +3173,12 @@ msgstr ""
 "              ユーザIDが主になると仮定する場合があります。\n"
 
 msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr "*警告*: 暗号副鍵がもうすぐ期限切れとなります。\n"
+msgstr ""
 
+#, fuzzy
+#| msgid "You can't change the expiration date of a v3 key\n"
 msgid "You may want to change its expiration date too.\n"
-msgstr "有効期限の変更も検討ください。\n"
+msgstr "v3鍵の有効期限は変更できません\n"
 
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
@@ -3115,7 +3187,7 @@ msgid ""
 msgstr ""
 "*警告*: これはPGP2形式の鍵です。フォトIDの追加で、一部のバージョンのPGPで"
 "は、\n"
-"        この鍵を拒否するかもしれません。\n"
+"      この鍵を拒否するかもしれません。\n"
 
 msgid "Are you sure you still want to add it? (y/N) "
 msgstr "それでも追加したいですか? (y/N) "
@@ -3176,7 +3248,7 @@ msgid ""
 msgstr ""
 "*警告*: これはPGP 2.x形式の鍵です。指名失効者の追加で、一部のバージョンのPGP"
 "では、\n"
-"        この鍵を拒否するかもしれません。\n"
+"      この鍵を拒否するかもしれません。\n"
 
 msgid "You may not add a designated revoker to a PGP 2.x-style key.\n"
 msgstr "PGP 2.x形式の鍵には指名失効者を追加できません。\n"
@@ -3200,9 +3272,6 @@ msgid ""
 "Are you sure you want to appoint this key as a designated revoker? (y/N) "
 msgstr "本当にこの鍵を指名失効者に任命しますか? (y/N) "
 
-msgid "Please remove selections from the secret keys.\n"
-msgstr "秘密鍵の選択をといてください。\n"
-
 msgid "Please select at most one subkey.\n"
 msgstr "高々1個の副鍵を選択してください。\n"
 
@@ -3215,9 +3284,6 @@ msgstr "主鍵の有効期限を変更します。\n"
 msgid "You can't change the expiration date of a v3 key\n"
 msgstr "v3鍵の有効期限は変更できません\n"
 
-msgid "No corresponding signature in secret ring\n"
-msgstr "秘密鍵リングに対応する署名がありません\n"
-
 #, c-format
 msgid "signing subkey %s is already cross-certified\n"
 msgstr "署名する副鍵%sはすでに相互証明されています\n"
@@ -3279,7 +3345,7 @@ msgid "Are you sure you still want to revoke it? (y/N) "
 msgstr "それでも本当に失効したいですか? (y/N) "
 
 msgid "Create a revocation certificate for this signature? (y/N) "
-msgstr "この署名にたいする失効証明書を作成しますか? (y/N) "
+msgstr "この署名にする失効証明書を作成しますか? (y/N) "
 
 msgid "Not signed by you.\n"
 msgstr "あなたによって署名されていません。\n"
@@ -3325,8 +3391,8 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "%s (大きさ%ld) の鍵%s (uid %d) のフォトIDとして表示\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
-msgstr "優先指定「%s」の重複\n"
+msgid "preference '%s' duplicated\n"
+msgstr "優先指定'%s'の重複\n"
 
 msgid "too many cipher preferences\n"
 msgstr "暗号方式の優先指定が多すぎます\n"
@@ -3338,8 +3404,8 @@ msgid "too many compression preferences\n"
 msgstr "圧縮の優先指定が多すぎます\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
-msgstr "優先指定の文字列に無効な項目「%s」があります\n"
+msgid "invalid item '%s' in preference string\n"
+msgstr "優先指定の文字列に無効な項目'%s'があります\n"
 
 msgid "writing direct signature\n"
 msgstr "直接署名を書き込みます\n"
@@ -3398,15 +3464,15 @@ msgstr "現在の認められた操作: "
 
 #, c-format
 msgid "   (%c) Toggle the sign capability\n"
-msgstr "   (%c) 署名機能を反転する\n"
+msgstr "   (%c) 署名特性を反転する\n"
 
 #, c-format
 msgid "   (%c) Toggle the encrypt capability\n"
-msgstr "   (%c) 暗号機能を反転する\n"
+msgstr "   (%c) 暗号特性を反転する\n"
 
 #, c-format
 msgid "   (%c) Toggle the authenticate capability\n"
-msgstr "   (%c) 認証機能を反転する\n"
+msgstr "   (%c) 認証特性を反転する\n"
 
 #, c-format
 msgid "   (%c) Finished\n"
@@ -3441,11 +3507,41 @@ msgstr "   (%d) RSA (暗号化のみ)\n"
 
 #, c-format
 msgid "   (%d) DSA (set your own capabilities)\n"
-msgstr "   (%d) DSA (機能をあなた自身で設定)\n"
+msgstr "   (%d) DSA (特性をあなた自身で設定)\n"
 
 #, c-format
 msgid "   (%d) RSA (set your own capabilities)\n"
-msgstr "   (%d) RSA (機能をあなた自身で設定)\n"
+msgstr "   (%d) RSA (特性をあなた自身で設定)\n"
+
+#, fuzzy, c-format
+#| msgid "   (%d) ECC\n"
+msgid "   (%d) ECC and ECC\n"
+msgstr "   (%d) ECC\n"
+
+#, c-format
+msgid "  (%d) ECC (sign only)\n"
+msgstr "  (%d) ECC (署名のみ)\n"
+
+#, c-format
+msgid "  (%d) ECC (set your own capabilities)\n"
+msgstr "  (%d) ECC (特性をあなた自身で設定)\n"
+
+#, c-format
+msgid "  (%d) ECC (encrypt only)\n"
+msgstr "  (%d) ECC (暗号化のみ)\n"
+
+#, c-format
+msgid "  (%d) Existing key\n"
+msgstr "  (%d) 既存の鍵\n"
+
+msgid "Enter the keygrip: "
+msgstr "keygripを入力: "
+
+msgid "Not a valid keygrip (expecting 40 hex digits)\n"
+msgstr "有効なkeygrip (40桁の16進数字)ではありません\n"
+
+msgid "No key with this keygrip\n"
+msgstr "このkeygripの鍵はありません\n"
 
 #, c-format
 msgid "%s keys may be between %u and %u bits long.\n"
@@ -3463,6 +3559,13 @@ msgstr "鍵長は? (%u) "
 msgid "Requested keysize is %u bits\n"
 msgstr "要求された鍵長は%uビット\n"
 
+#, c-format
+msgid "rounded to %u bits\n"
+msgstr "%uビットに切り上げます\n"
+
+msgid "Please select which elliptic curve you want:\n"
+msgstr "ご希望の楕円曲線を選択してください:\n"
+
 msgid ""
 "Please specify how long the key should be valid.\n"
 "         0 = key does not expire\n"
@@ -3504,10 +3607,10 @@ msgid "invalid value\n"
 msgstr "無効な値\n"
 
 msgid "Key does not expire at all\n"
-msgstr "は無期限です\n"
+msgstr "%sは無期限です\n"
 
 msgid "Signature does not expire at all\n"
-msgstr "署名は無期限です\n"
+msgstr "%署名は無期限です\n"
 
 #, c-format
 msgid "Key expires at %s\n"
@@ -3580,8 +3683,8 @@ msgid "Invalid character in comment\n"
 msgstr "コメントに無効な文字があります\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
-msgstr "あなたは文字集合「%s」を使っています。\n"
+msgid "You are using the '%s' character set.\n"
+msgstr "あなたは文字集合'%s'を使っています。\n"
 
 #, c-format
 msgid ""
@@ -3619,6 +3722,16 @@ msgstr "名前(N)、コメント(C)、電子メール(E)の変更、または終
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
 msgstr "名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? "
 
+#, fuzzy
+#| msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
+msgid "Change (N)ame, (E)mail, or (Q)uit? "
+msgstr "名前(N)、コメント(C)、電子メール(E)の変更、または終了(Q)? "
+
+#, fuzzy
+#| msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
+msgid "Change (N)ame, (E)mail, or (O)kay/(Q)uit? "
+msgstr "名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? "
+
 msgid "Please correct the error first\n"
 msgstr "まずエラーを修正してください\n"
 
@@ -3633,8 +3746,11 @@ msgid ""
 "Please enter a passphrase to protect the off-card backup of the new "
 "encryption key."
 msgstr ""
-"パスフレーズを入力してください。これは新しく作られる暗号化鍵のカード外のバッ"
-"クアップを保護するものです。"
+"パスフレーズを入力してください。これは新しく作られる暗号鍵のカード外のバック"
+"アップを保護するものです。"
+
+msgid "passphrase not correctly repeated; try again"
+msgstr "パスフレーズをちゃんと繰り返していません。再入力してください"
 
 #, c-format
 msgid "%s.\n"
@@ -3657,40 +3773,59 @@ msgid ""
 "disks) during the prime generation; this gives the random number\n"
 "generator a better chance to gain enough entropy.\n"
 msgstr ""
-"たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か\n"
-"す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生\n"
-"成器に十分なエントロピーを供給する機会を与えることができます。\n"
-
-msgid "Key generation canceled.\n"
-msgstr "鍵の生成が取り消されました。\n"
+"たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か"
+"す、\n"
+"ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生成器"
+"に\n"
+"十分なエントロピーを供給する機会を与えることができます。\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
-msgstr "「%s」へ公開鍵を書き込みます\n"
+msgid "Key generation failed: %s\n"
+msgstr "鍵の生成に失敗しました: %s\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "「%s」へ秘密鍵スタブを書き込みます\n"
+msgid ""
+"About to create a key for:\n"
+"    \"%s\"\n"
+"\n"
+msgstr ""
 
-#, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "「%s」へ秘密鍵を書き込みます\n"
+msgid "Continue? (Y/n) "
+msgstr ""
+
+#, fuzzy, c-format
+#| msgid "key already exists\n"
+msgid "A key for \"%s\" already exists\n"
+msgstr "鍵はもうあります\n"
+
+#, fuzzy
+#| msgid "Use this key anyway? (y/N) "
+msgid "Create anyway? (y/N) "
+msgstr "それでもこの鍵を使いますか? (y/N) "
+
+#, fuzzy
+#| msgid "generating new key\n"
+msgid "creating anyway\n"
+msgstr "新しい鍵を生成\n"
 
 #, c-format
-msgid "no writable public keyring found: %s\n"
-msgstr "書き込み可能な公開鍵リングが見つかりません: %s\n"
+msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n"
+msgstr ""
+
+msgid "Key generation canceled.\n"
+msgstr "鍵の生成が取り消されました。\n"
 
 #, c-format
-msgid "no writable secret keyring found: %s\n"
-msgstr "書き込み可能な秘密鍵リングが見つかりません: %s\n"
+msgid "writing public key to '%s'\n"
+msgstr "'%s'へ公開鍵を書き込みます\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "公開鍵リング「%s」の書き込みエラー: %s\n"
+msgid "no writable public keyring found: %s\n"
+msgstr "書き込み可能な公開鍵リングが見つかりません: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "秘密鍵リング「%s」の書き込みエラー: %s\n"
+msgid "error writing public keyring '%s': %s\n"
+msgstr "公開鍵リング'%s'の書き込みエラー: %s\n"
 
 msgid "public and secret key created and signed.\n"
 msgstr "公開鍵と秘密鍵を作成し、署名しました。\n"
@@ -3703,10 +3838,6 @@ msgstr ""
 "\"--edit-key\"コマンドを使って副鍵を生成してください。\n"
 
 #, c-format
-msgid "Key generation failed: %s\n"
-msgstr "鍵の生成に失敗しました: %s\n"
-
-#, c-format
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr "鍵は%lu秒未来にできました (時間歪曲か時計の障害でしょう)\n"
@@ -3716,9 +3847,15 @@ msgid ""
 "key has been created %lu seconds in future (time warp or clock problem)\n"
 msgstr "鍵は%lu秒未来にできました (時間歪曲か時計の障害でしょう)\n"
 
-msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
+msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n"
 msgstr "*注意*: v3鍵に対する副鍵の作成は、OpenPGPに適合しません\n"
 
+msgid "Secret parts of primary key are not available.\n"
+msgstr "主鍵の秘密部分が得られません。\n"
+
+msgid "Secret parts of primary key are stored on-card.\n"
+msgstr "主鍵の秘密部分は科議場に保存されています。\n"
+
 msgid "Really create? (y/N) "
 msgstr "本当に作成しますか? (y/N) "
 
@@ -3727,21 +3864,21 @@ msgid "storing key onto card failed: %s\n"
 msgstr "カードへの鍵の保管に失敗しました: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
-msgstr "バックアップ・ファイル「%s」が作成できません: %s\n"
+msgid "can't create backup file '%s': %s\n"
+msgstr "バックアップ・ファイル'%s'が作成できません: %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
-msgstr "*注意*: カード鍵のバックアップが「%s」へ保存されます\n"
+msgid "Note: backup of card key saved to '%s'\n"
+msgstr "*注意*: カード鍵のバックアップが'%s'へ保存されます\n"
 
 msgid "never     "
 msgstr "無期限    "
 
 msgid "Critical signature policy: "
-msgstr "クリティカルな署名ポリシ: "
+msgstr "クリティカルな署名ポリシ: "
 
 msgid "Signature policy: "
-msgstr "署名ポリシ: "
+msgstr "署名ポリシ: "
 
 msgid "Critical preferred keyserver: "
 msgstr "クリティカルな優先鍵サーバ: "
@@ -3752,54 +3889,40 @@ msgstr "クリティカルな署名注釈: "
 msgid "Signature notation: "
 msgstr "署名注釈: "
 
+#, c-format
+msgid "Warning: %lu key(s) skipped due to their large size\n"
+msgstr ""
+
 msgid "Keyring"
 msgstr "鍵リング"
 
 msgid "Primary key fingerprint:"
-msgstr "主é\8dµã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»プリント:"
+msgstr "主é\8dµã\81®ã\83\95ã\82£ã\83³ã\82¬ã\83¼プリント:"
 
 msgid "     Subkey fingerprint:"
-msgstr "å\89¯é\8dµã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»プリント:"
+msgstr "å\89¯é\8dµã\81®ã\83\95ã\82£ã\83³ã\82¬ã\83¼プリント:"
 
 #. TRANSLATORS: this should fit into 24 bytes to that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
-msgstr "主é\8dµã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88:"
+msgstr "主鍵フィンガープリント:"
 
 msgid "      Subkey fingerprint:"
-msgstr "å\89¯é\8dµã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88:"
+msgstr "副鍵フィンガープリント:"
 
 msgid "      Key fingerprint ="
-msgstr " フィンガー・プリント ="
-
-#, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "*警告*: PGP-2のフィンガー・プリントは安全ではありません\n"
+msgstr "   フィンガープリント ="
 
 msgid "      Card serial no. ="
-msgstr " カード・シリアル番号 ="
-
-#, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
-msgstr "「%s」から「%s」へ名前変更に失敗: %s\n"
-
-msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr "*警告*: 機密情報をもったファイルが2つ存在します。\n"
+msgstr "   カード・シリアル番号 ="
 
 #, c-format
-msgid "%s is the unchanged one\n"
-msgstr "%sは変更のない方です\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
+msgstr "'%s'から'%s'へ名前変更に失敗: %s\n"
 
 #, c-format
-msgid "%s is the new one\n"
-msgstr "%sは新しい方です\n"
-
-msgid "Please fix this possible security flaw\n"
-msgstr "この安全上の欠陥の可能性を直してください\n"
-
-#, c-format
-msgid "caching keyring `%s'\n"
-msgstr "鍵リング「%s」をキャッシュします\n"
+msgid "caching keyring '%s'\n"
+msgstr "鍵リング'%s'をキャッシュします\n"
 
 #, c-format
 msgid "%lu keys cached so far (%lu signatures)\n"
@@ -3835,9 +3958,9 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "鍵に設定されたPKAレコードを鍵の取得時に与える"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
-"*警告*: 鍵サーバのオプション「%s」は、このプラットホームでは使われません\n"
+"*警告*: 鍵サーバのオプション'%s'は、このプラットホームでは使われません\n"
 
 msgid "disabled"
 msgstr "使用禁止"
@@ -3850,6 +3973,25 @@ msgid "invalid keyserver protocol (us %d!=handler %d)\n"
 msgstr "無効な鍵サーバ・プロトコルです (us %d!=handler %d)\n"
 
 #, c-format
+msgid "\"%s\" not a key ID: skipping\n"
+msgstr "\"%s\"鍵IDではありません: スキップします\n"
+
+#, c-format
+msgid "WARNING: unable to refresh key %s via %s: %s\n"
+msgstr "*警告*: 鍵%sを%s経由で回復できません: %s\n"
+
+#, c-format
+msgid "refreshing 1 key from %s\n"
+msgstr "1本の鍵を%sから回復\n"
+
+#, c-format
+msgid "refreshing %d keys from %s\n"
+msgstr "%d本の鍵を%sから回復\n"
+
+msgid "no keyserver known (use option --keyserver)\n"
+msgstr "既知の鍵サーバがありません (オプション--keyserverを使いましょう)\n"
+
+#, c-format
 msgid "key \"%s\" not found on keyserver\n"
 msgstr "鍵\"%s\"が鍵サーバに見つかりません\n"
 
@@ -3865,12 +4007,8 @@ msgid "requesting key %s from %s\n"
 msgstr "鍵%sを%sに要求\n"
 
 #, c-format
-msgid "searching for names from %s server %s\n"
-msgstr "%sからサーバ%sで名前を検索\n"
-
-#, c-format
-msgid "searching for names from %s\n"
-msgstr "%sから名前を検索\n"
+msgid "skipped \"%s\": %s\n"
+msgstr "\"%s\"をスキップしました: %s\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
@@ -3881,76 +4019,14 @@ msgid "sending key %s to %s\n"
 msgstr "鍵%sを%sへ送信\n"
 
 #, c-format
-msgid "searching for \"%s\" from %s server %s\n"
-msgstr "\"%s\"を%sサーバ%sから検索\n"
-
-#, c-format
-msgid "searching for \"%s\" from %s\n"
-msgstr "\"%s\"をサーバ%sから検索\n"
-
-msgid "no keyserver action!\n"
-msgstr "鍵サーバ・アクションがありません!\n"
-
-#, c-format
-msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr "*警告*: 別のバージョンのGnuPGの鍵サーバ・ハンドラ (%s)\n"
-
-msgid "keyserver did not send VERSION\n"
-msgstr "鍵サーバはVERSIONを送信しませんでした\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "鍵サーバ通信エラー: %s\n"
-
-msgid "no keyserver known (use option --keyserver)\n"
-msgstr "既知の鍵サーバがありません (オプション--keyserverを使いましょう)\n"
-
-msgid "external keyserver calls are not supported in this build\n"
-msgstr "このビルドでは、外部鍵サーバの呼出しはサポートしていません\n"
-
-#, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "鍵サーバ・スキーム「%s」用のハンドラがありません\n"
-
-#, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
-msgstr "操作「%s」は、鍵サーバ・スキーム「%s」でサポートされていません\n"
-
-#, c-format
-msgid "%s does not support handler version %d\n"
-msgstr "%sはハンドラ・バージョン%dをサポートしません\n"
-
-msgid "keyserver timed out\n"
-msgstr "鍵サーバのタイムアウト\n"
-
-msgid "keyserver internal error\n"
-msgstr "鍵サーバの内部エラー\n"
-
-#, c-format
-msgid "\"%s\" not a key ID: skipping\n"
-msgstr "\"%s\"鍵IDではありません: スキップします\n"
-
-#, c-format
-msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr "*警告*: 鍵%sを%s経由で更新できません: %s\n"
-
-#, c-format
-msgid "refreshing 1 key from %s\n"
-msgstr "1本の鍵を%sから更新\n"
-
-#, c-format
-msgid "refreshing %d keys from %s\n"
-msgstr "%d本の鍵を%sから更新\n"
+msgid "requesting key from '%s'\n"
+msgstr "鍵を'%s'から要求\n"
 
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
 msgstr "*警告*: URI %s からデータを取れません: %s\n"
 
 #, c-format
-msgid "WARNING: unable to parse URI %s\n"
-msgstr "*警告*: URI %s を解析できません\n"
-
-#, c-format
 msgid "weird size for an encrypted session key (%d)\n"
 msgstr "変な長さの暗号化済みセッション鍵 (%d)\n"
 
@@ -4017,7 +4093,7 @@ msgstr "保持したパスフレーズをクリアしました ID: %s\n"
 msgid "decryption failed: %s\n"
 msgstr "復号に失敗しました: %s\n"
 
-msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
+msgid "Note: sender requested \"for-your-eyes-only\"\n"
 msgstr "*注意*: 送信者は\"極秘とする\"ように求めています\n"
 
 #, c-format
@@ -4033,6 +4109,18 @@ msgstr "スタンドアロン失効 - \"gpg --import\"を使って適用して
 msgid "no signature found\n"
 msgstr "署名が見つかりません\n"
 
+#, c-format
+msgid "BAD signature from \"%s\""
+msgstr "\"%s\"からの*不正な*署名"
+
+#, c-format
+msgid "Expired signature from \"%s\""
+msgstr "\"%s\"からの期限切れの署名"
+
+#, c-format
+msgid "Good signature from \"%s\""
+msgstr "\"%s\"からの正しい署名"
+
 msgid "signature verification suppressed\n"
 msgstr "署名の検証を省略\n"
 
@@ -4054,18 +4142,6 @@ msgstr "%sに%s鍵ID %sで施された署名\n"
 msgid "Key available at: "
 msgstr "以下に鍵があります: "
 
-#, c-format
-msgid "BAD signature from \"%s\""
-msgstr "\"%s\"からの*不正な*署名"
-
-#, c-format
-msgid "Expired signature from \"%s\""
-msgstr "\"%s\"からの期限切れの署名"
-
-#, c-format
-msgid "Good signature from \"%s\""
-msgstr "\"%s\"からの正しい署名"
-
 msgid "[uncertain]"
 msgstr "[不確定]"
 
@@ -4082,8 +4158,8 @@ msgid "Signature expires %s\n"
 msgstr "この署名は%sで期限切れとなります\n"
 
 #, c-format
-msgid "%s signature, digest algorithm %s\n"
-msgstr "%s署名、ダイジェスト・アルゴリズム %s\n"
+msgid "%s signature, digest algorithm %s%s%s\n"
+msgstr "%s署名、ダイジェスト・アルゴリズム %s%s%s\n"
 
 msgid "binary"
 msgstr "バイナリ"
@@ -4094,17 +4170,15 @@ msgstr "テキストモード"
 msgid "unknown"
 msgstr "不明の"
 
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-"*警告*: 分遣署名ではありません。ファイル「%s」は検証されて*いませんでした*!\n"
+msgid ", key algorithm "
+msgstr "、鍵アルゴリズム "
 
 #, c-format
 msgid "Can't check signature: %s\n"
 msgstr "署名を検査できません: %s\n"
 
 msgid "not a detached signature\n"
-msgstr "å\88\86é\81£ç½²å\90\8dã\81§ã\81¯ありません\n"
+msgstr "å\88\86é\9b¢ç½²å\90\8dã\81§ありません\n"
 
 msgid ""
 "WARNING: multiple signatures detected.  Only the first will be checked.\n"
@@ -4121,8 +4195,8 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "proc_tree() の中に無効なルート・パケットを検出しました\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
-msgstr "「%s」のfstatが%sで失敗しました: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
+msgstr "'%s'のfstatが%sで失敗しました: %s\n"
 
 #, c-format
 msgid "fstat(%d) failed in %s: %s\n"
@@ -4149,14 +4223,7 @@ msgstr "*警告*: ダイジェスト・アルゴリズム %s は廃止されて
 
 #, c-format
 msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "注意: %s のアルゴリズムを使った署名は拒否されます\n"
-
-msgid "the IDEA cipher plugin is not present\n"
-msgstr "IDEA暗号方式のプラグインがありません\n"
-
-#, c-format
-msgid "please see %s for more information\n"
-msgstr "詳細は%sをご覧ください\n"
+msgstr "注意: アルゴリズム %s を用いた署名は拒否されました\n"
 
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
@@ -4179,23 +4246,24 @@ msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
 msgstr ""
 "%s:%u: \"%s\"は、使われなくなったオプションです - なんの効果もありません\n"
 
-#, c-format
-msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
 msgstr ""
 "*警告*: \"%s\"は、使われなくなったオプションです - なんの効果もありません\n"
 
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
+#, fuzzy, c-format
+#| msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
+msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n"
 msgstr ""
-"%s:%u: \"%s%s\"は、使われなくなったオプションです - %sになんの効果もありませ"
-"ん\n"
+"%s:%u: \"%s\"は、使われなくなったオプションです - なんの効果もありません\n"
 
-#, c-format
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgid ""
 "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
 msgstr ""
-"*警告*: \"%s%s\"は、使われなくなったオプションです - %s以外になんの効果もあり"
-"ません\n"
+"*警告*: \"%s\"は、使われなくなったオプションです - なんの効果もありません\n"
 
 msgid "Uncompressed"
 msgstr "無圧縮"
@@ -4209,16 +4277,19 @@ msgid "this message may not be usable by %s\n"
 msgstr "このメッセージは、%sでは使用できません\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
-msgstr "あいまいなオプション「%s」\n"
+msgid "ambiguous option '%s'\n"
+msgstr "あいまいなオプション'%s'\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
-msgstr "不明のオプション「%s」\n"
+msgid "unknown option '%s'\n"
+msgstr "不明のオプション'%s'\n"
+
+msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n"
+msgstr "ECDSAの公開鍵は8ビットの倍数のSECエンコーディングを期待します\n"
 
 #, c-format
-msgid "File `%s' exists. "
-msgstr "ファイル「%s」は存在します。"
+msgid "File '%s' exists. "
+msgstr "ファイル'%s'は既に存在します。"
 
 msgid "Overwrite? (y/N) "
 msgstr "上書きしますか? (y/N) "
@@ -4235,15 +4306,15 @@ msgstr "標準出力に書き込みます\n"
 
 #, c-format
 msgid "assuming signed data in '%s'\n"
-msgstr "署名されたデータが「%s」にあると想定します\n"
+msgstr "署名されたデータが'%s'にあると想定します\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
-msgstr "新しいコンフィグレーション・ファイル「%s」を作成しました\n"
+msgid "new configuration file '%s' created\n"
+msgstr "新しいコンフィグレーション・ファイル'%s'ができました\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
-msgstr "*警告*: 「%s」のオプションはこの実行では、まだ有効になりません\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
+msgstr "*警告*: '%s'のオプションはこの実行では、まだ有効になりません\n"
 
 #, c-format
 msgid "can't handle public key algorithm %d\n"
@@ -4300,6 +4371,39 @@ msgstr "%uビット%s鍵, ID %s作成日付は%s"
 msgid "         (subkey on main key ID %s)"
 msgstr "         (主鍵ID %s の副鍵)"
 
+msgid "Please enter the passphrase to unlock the OpenPGP secret key:"
+msgstr "OpenPGPの秘密鍵のロックを解除するためにパスフレーズを入力してください:"
+
+msgid "Please enter the passphrase to import the OpenPGP secret key:"
+msgstr "OpenPGPの秘密鍵をインポートするためにパスフレーズを入力してください:"
+
+msgid "Please enter the passphrase to export the OpenPGP secret subkey:"
+msgstr ""
+"OpenPGPの秘密サブ鍵をエクスポートするためにパスフレーズを入力してください:"
+
+msgid "Please enter the passphrase to export the OpenPGP secret key:"
+msgstr "OpenPGPの秘密鍵をエクスポートするためにパスフレーズを入力してください:"
+
+msgid "Do you really want to permanently delete the OpenPGP secret subkey key:"
+msgstr "選択したOpenPGPサブ鍵を本当に永久に削除しますか? (y/N) "
+
+msgid "Do you really want to permanently delete the OpenPGP secret key:"
+msgstr "選択したOpenPGP秘密鍵を本当に永久に削除しますか? (y/N) "
+
+#, c-format
+msgid ""
+"%s\n"
+"\"%.*s\"\n"
+"%u-bit %s key, ID %s,\n"
+"created %s%s.\n"
+"%s"
+msgstr ""
+"%s\n"
+"\"%.*s\"\n"
+"%uビット%s鍵, ID %s,\n"
+"作成日付 %s%s.\n"
+"%s"
+
 msgid ""
 "\n"
 "Pick an image to use for your photo ID.  The image must be a JPEG file.\n"
@@ -4317,8 +4421,8 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "フォトID用のJPEGファイル名を入力してください: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
-msgstr "JPEGファイル「%s」が開けません: %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
+msgstr "JPEGファイル'%s'が開けません: %s\n"
 
 #, c-format
 msgid "This JPEG is really large (%d bytes) !\n"
@@ -4328,8 +4432,8 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "本当に使いたいですか? (y/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
-msgstr "「%s」は、JPEGファイルではありません\n"
+msgid "'%s' is not a JPEG file\n"
+msgstr "'%s'は、JPEGファイルではありません\n"
 
 msgid "Is this photo correct (y/N/q)? "
 msgstr "この写真は正しいですか (y/N/q)? "
@@ -4393,7 +4497,7 @@ msgstr "  %d = 信用し ない\n"
 
 #, c-format
 msgid "  %d = I trust ultimately\n"
-msgstr "  %d = ç©¶æ¥µ的に信用する\n"
+msgstr "  %d = çµ¶å¯¾的に信用する\n"
 
 msgid "  m = back to the main menu\n"
 msgstr "  m = メーン・メニューに戻る\n"
@@ -4414,10 +4518,10 @@ msgid "Your decision? "
 msgstr "あなたの決定は? "
 
 msgid "Do you really want to set this key to ultimate trust? (y/N) "
-msgstr "æ\9c¬å½\93ã\81«ã\81\93ã\81®é\8dµã\82\92究極的に信用しますか? (y/N) "
+msgstr "æ\9c¬å½\93ã\81«ã\81\93ã\81®é\8dµã\82\92絶対的に信用しますか? (y/N) "
 
 msgid "Certificates leading to an ultimately trusted key:\n"
-msgstr "究極的に信用した鍵への証明書:\n"
+msgstr "絶対的に信用した鍵への証明書:\n"
 
 #, c-format
 msgid "%s: There is no assurance this key belongs to the named user\n"
@@ -4467,12 +4571,12 @@ msgid "Note: This key has been disabled.\n"
 msgstr "注意: この鍵は使用禁止に設定されています。\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
-msgstr "注意: 確認された署名者のアドレスは「%s」です\n"
+msgid "Note: Verified signer's address is '%s'\n"
+msgstr "注意: 確認された署名者のアドレスは'%s'です\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr "注意: 署名者のアドレス「%s」がDNSのエントリと一致しません\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
+msgstr "注意: 署名者のアドレス'%s'がDNSのエントリと一致しません\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
 msgstr "PKA情報が有効のため、信用レベルがFULLに調整されました\n"
@@ -4508,6 +4612,10 @@ msgid "%s: skipped: %s\n"
 msgstr "%s: スキップ: %s\n"
 
 #, c-format
+msgid "%s: skipped: public key is disabled\n"
+msgstr "%s: スキップ: 公開鍵は使用禁止です\n"
+
+#, c-format
 msgid "%s: skipped: public key already present\n"
 msgstr "%s: スキップ: 公開鍵はもうあります\n"
 
@@ -4540,10 +4648,6 @@ msgstr "スキップ: 公開鍵はもう設定済みです\n"
 msgid "unknown default recipient \"%s\"\n"
 msgstr "デフォルトの受取人\"%s\"が不明です\n"
 
-#, c-format
-msgid "%s: skipped: public key is disabled\n"
-msgstr "%s: スキップ: 公開鍵は使用禁止です\n"
-
 msgid "no valid addressees\n"
 msgstr "有効な宛先がありません\n"
 
@@ -4559,8 +4663,12 @@ msgid "data not saved; use option \"--output\" to save it\n"
 msgstr ""
 "データは保存されていません。保存には\"--output\"オプションを使ってください\n"
 
+#, c-format
+msgid "error creating '%s': %s\n"
+msgstr "'%s'の作成エラー: %s\n"
+
 msgid "Detached signature.\n"
-msgstr "å\88\86é\81£署名。\n"
+msgstr "å\88\86é\9b¢署名。\n"
 
 msgid "Please enter name of data file: "
 msgstr "データ・ファイルの名前を入力: "
@@ -4572,8 +4680,8 @@ msgid "no signed data\n"
 msgstr "署名されたデータがありません\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
-msgstr "署名されたデータ「%s」が開けません\n"
+msgid "can't open signed data '%s'\n"
+msgstr "署名されたデータ'%s'が開けません\n"
 
 #, c-format
 msgid "can't open signed data fd=%d: %s\n"
@@ -4598,10 +4706,10 @@ msgid "WARNING: cipher algorithm %s not found in recipient preferences\n"
 msgstr "*警告*: 暗号アルゴリズム%sは受取人の優先指定に入っていません\n"
 
 #, c-format
-msgid "NOTE: secret key %s expired at %s\n"
+msgid "Note: secret key %s expired at %s\n"
 msgstr "*注意*: 秘密鍵%sは%sで期限切れとなります\n"
 
-msgid "NOTE: key has been revoked"
+msgid "Note: key has been revoked"
 msgstr "*注意*: 鍵は失効済みです"
 
 #, c-format
@@ -4619,7 +4727,7 @@ msgid "(This is a sensitive revocation key)\n"
 msgstr "(これは、機密指定の失効鍵です)\n"
 
 msgid "Create a designated revocation certificate for this key? (y/N) "
-msgstr "この鍵にたいする指名失効証明書を作成しますか? (y/N) "
+msgstr "この鍵にする指名失効証明書を作成しますか? (y/N) "
 
 msgid "ASCII armored output forced.\n"
 msgstr "ASCII外装出力を強制します。\n"
@@ -4635,25 +4743,34 @@ msgstr "失効証明書を作成。\n"
 msgid "no revocation keys found for \"%s\"\n"
 msgstr "\"%s\"用の失効鍵が見つかりません\n"
 
+msgid "This is a revocation certificate for the OpenPGP key:"
+msgstr "これは失効証明書でこちらのOpenPGP鍵に対するものです:"
+
+msgid ""
+"Use it to revoke this key in case of a compromise or loss of\n"
+"the secret key.  However, if the secret key is still accessible,\n"
+"it is better to generate a new revocation certificate and give\n"
+"a reason for the revocation."
+msgstr ""
+"秘密鍵のコンプロマイズや紛失の場合、これを使ってこの鍵を失効させます。\n"
+"しかし、秘密鍵がまだアクセス可能である場合、新しい失効証明書を生成し、\n"
+"失効の理由をつける方がよいでしょう。"
+
+msgid ""
+"To avoid an accidental use of this file, a colon has been inserted\n"
+"before the 5 dashes below.  Remove this colon with a text editor\n"
+"before making use of this revocation certificate."
+msgstr ""
+"このファイルを誤って使うのを避けるため、以下ではコロンが5つのダッシュの前に挿"
+"入されます。\n"
+"この失効証明書を使う前にはテクスト・エディタでこのコロンを削除してください。"
+
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
 msgstr "秘密鍵\"%s\"が見つかりません: %s\n"
 
-#, c-format
-msgid "no corresponding public key: %s\n"
-msgstr "対応する公開鍵がありません: %s\n"
-
-msgid "public key does not match secret key!\n"
-msgstr "公開鍵と秘密鍵が照合しません!\n"
-
 msgid "Create a revocation certificate for this key? (y/N) "
-msgstr "この鍵にたいする失効証明書を作成しますか? (y/N) "
-
-msgid "unknown protection algorithm\n"
-msgstr "不明の保護アルゴリズムです\n"
-
-msgid "NOTE: This key is not protected!\n"
-msgstr "*注意*: この鍵は保護されていません!\n"
+msgstr "この鍵に対する失効証明書を作成しますか? (y/N) "
 
 msgid ""
 "Revocation certificate created.\n"
@@ -4698,56 +4815,34 @@ msgstr "(説明はありません)\n"
 msgid "Is this okay? (y/N) "
 msgstr "よろしいですか? (y/N) "
 
-msgid "secret key parts are not available\n"
-msgstr "秘密部分が得られません\n"
+msgid "weak key created - retrying\n"
+msgstr "弱い鍵ができました - 再実行\n"
 
 #, c-format
-msgid "protection algorithm %d%s is not supported\n"
-msgstr "保護アルゴリズム%d%sはサポートされていません\n"
+msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
+msgstr "共通鍵暗号方式の弱い鍵を回避することができません。%d回試みました!\n"
 
 #, c-format
-msgid "protection digest %d is not supported\n"
-msgstr "保護ダイジェスト%dはサポートしていません\n"
-
-msgid "Invalid passphrase; please try again"
-msgstr "無効なパスフレーズです。再入力してください"
+msgid "%s key %s uses an unsafe (%zu bit) hash\n"
+msgstr "%s 鍵 %s は安全でない(%zuビット)ハッシュを使用しています\n"
 
 #, c-format
-msgid "%s ...\n"
-msgstr "%s ...\n"
-
-msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr "*警告*: 弱い鍵を検出しました。パスフレーズを変更してください。\n"
+msgid "%s key %s requires a %zu bit or larger hash (hash is %s)\n"
+msgstr ""
+"%s鍵%sは%zuビットあるいはより大きいハッシュを必要とします(今のハッシュは%s)\n"
 
-msgid "generating the deprecated 16-bit checksum for secret key protection\n"
-msgstr "廃止された16ビットのチェックサムを秘密鍵の保護に生成\n"
-
-msgid "weak key created - retrying\n"
-msgstr "弱い鍵ができました - 再実行\n"
-
-#, c-format
-msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
-msgstr "共通鍵暗号方式の弱い鍵を回避することができません。%d回試みました!\n"
-
-msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSAは8ビットの倍数のハッシュ長を必要とします\n"
-
-#, c-format
-msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "DSA鍵 %sは安全でない(%uビット)ハッシュを用います\n"
-
-#, c-format
-msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "DSA鍵 %s は%u ビット以上のハッシュを必要とします\n"
-
-msgid "WARNING: signature digest conflict in message\n"
-msgstr "*警告*: 署名のダイジェストが、メッセージと衝突します\n"
+msgid "WARNING: signature digest conflict in message\n"
+msgstr "*警告*: 署名のダイジェストが、メッセージと衝突します\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s is not cross-certified\n"
 msgstr "*警告*: 署名副鍵%sは、相互証明されてません\n"
 
 #, c-format
+msgid "please see %s for more information\n"
+msgstr "詳細は%sをご覧ください\n"
+
+#, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr "*警告*: 無効な相互証明が、署名副鍵%sにあります\n"
 
@@ -4770,11 +4865,11 @@ msgid ""
 msgstr "鍵%sは%lu秒未来にできました (時間歪曲か時計の障害でしょう)\n"
 
 #, c-format
-msgid "NOTE: signature key %s expired %s\n"
+msgid "Note: signature key %s expired %s\n"
 msgstr "*注意*: 署名鍵%sは%sに期限切れとなります\n"
 
 #, c-format
-msgid "NOTE: signature key %s has been revoked\n"
+msgid "Note: signature key %s has been revoked\n"
 msgstr "*注意*: 鍵 %s は失効済みです\n"
 
 #, c-format
@@ -4796,7 +4891,7 @@ msgstr "*警告*: 表記を%%拡張不能 (大きすぎ)。拡張せずに使用
 #, c-format
 msgid ""
 "WARNING: unable to %%-expand policy URL (too large).  Using unexpanded.\n"
-msgstr "*警告*: ポリシURLを%%拡張不能 (大きすぎ)。拡張せずに使用。\n"
+msgstr "*警告*: ポリシURLを%%拡張不能 (大きすぎ)。拡張せずに使用。\n"
 
 #, c-format
 msgid ""
@@ -4812,9 +4907,6 @@ msgstr "作成された署名の検査に失敗しました: %s\n"
 msgid "%s/%s signature from: \"%s\"\n"
 msgstr "%s/%s署名。署名者:\"%s\"\n"
 
-msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr "--pgp2モードでは、PGP 2.x形式の鍵で分遣署名できるだけです\n"
-
 #, c-format
 msgid ""
 "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
@@ -4825,9 +4917,6 @@ msgstr ""
 msgid "signing:"
 msgstr "署名:"
 
-msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr "--pgp2モードではPGP 2.x形式の鍵でクリア・テクスト署名しかできません\n"
-
 #, c-format
 msgid "%s encryption will be used\n"
 msgstr "%s暗号化を使用します\n"
@@ -4841,10 +4930,6 @@ msgstr ""
 msgid "skipped \"%s\": duplicated\n"
 msgstr "\"%s\"をスキップします: 重複\n"
 
-#, c-format
-msgid "skipped \"%s\": %s\n"
-msgstr "\"%s\"をスキップしました: %s\n"
-
 msgid "skipped: secret key already present\n"
 msgstr "スキップ: 秘密鍵はもうあります\n"
 
@@ -4860,12 +4945,12 @@ msgid ""
 "# List of assigned trustvalues, created %s\n"
 "# (Use \"gpg --import-ownertrust\" to restore them)\n"
 msgstr ""
-"# 指定された信度の一覧です 作成日時: %s\n"
+"# 指定された信度の一覧です 作成日時: %s\n"
 "# (\"gpg --import-ownertrust\" で復旧することができます)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
-msgstr "「%s」でエラー: %s\n"
+msgid "error in '%s': %s\n"
+msgstr "'%s'でエラー: %s\n"
 
 msgid "line too long"
 msgstr "行が長すぎます"
@@ -4874,32 +4959,24 @@ msgid "colon missing"
 msgstr "コロンがありません"
 
 msgid "invalid fingerprint"
-msgstr "ç\84¡å\8a¹ã\81ªã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88"
+msgstr "無効なフィンガープリント"
 
 msgid "ownertrust value missing"
 msgstr "所有者信用度がありません"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
-msgstr "「%s」で信用レコードの検索エラー: %s\n"
+msgid "error finding trust record in '%s': %s\n"
+msgstr "'%s'で信用レコードの検索エラー: %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
-msgstr "「%s」で読み込みエラー: %s\n"
+msgid "read error in '%s': %s\n"
+msgstr "'%s'で読み込みエラー: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "信用データベース: 同期に失敗しました: %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "「%s」のロックを作成できません\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "「%s」がロックできません\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "信用データベース レコード%lu: シークに失敗しました: %s\n"
 
@@ -4911,12 +4988,20 @@ msgid "trustdb transaction too large\n"
 msgstr "信用データベースのトランザクションが大きすぎます\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "'%s'にアクセスできません: %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: ディレクトリがありません!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "「%s」にアクセスできません: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "'%s'のロックを作成できません\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "'%s'がロックできません\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -4930,7 +5015,7 @@ msgstr "%s: 無効な信用データベースを作成\n"
 msgid "%s: trustdb created\n"
 msgstr "%s: 信用データベースができました\n"
 
-msgid "NOTE: trustdb not writable\n"
+msgid "Note: trustdb not writable\n"
 msgstr "*注意*: 信用データベースが、書き込み不能です\n"
 
 #, c-format
@@ -4979,7 +5064,7 @@ msgstr "%s: 空きレコードの読み込みエラー: %s\n"
 
 #, c-format
 msgid "%s: error writing dir record: %s\n"
-msgstr "%s: ディレクトリ・レコードの書き込みエラー: %s\n"
+msgstr "%s: ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ªã\83¼ã\83»ã\83¬ã\82³ã\83¼ã\83\89ã\81®æ\9b¸ã\81\8dè¾¼ã\81¿ã\82¨ã\83©ã\83¼: %s\n"
 
 #, c-format
 msgid "%s: failed to zero a record: %s\n"
@@ -5001,8 +5086,8 @@ msgid "input line longer than %d characters\n"
 msgstr "入力行の長さが%d文字を超えています\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
-msgstr "「%s」は、有効な大型鍵IDでありません\n"
+msgid "'%s' is not a valid long keyID\n"
+msgstr "'%s'は、有効な大型鍵IDでありません\n"
 
 #, c-format
 msgid "key %s: accepted as trusted key\n"
@@ -5018,7 +5103,7 @@ msgstr "鍵%s: 信用される鍵の公開鍵がありません - スキップ
 
 #, c-format
 msgid "key %s marked as ultimately trusted\n"
-msgstr "é\8dµ%sã\82\92究極的に信用するよう記録しました\n"
+msgstr "é\8dµ%sã\82\92絶対的に信用するよう記録しました\n"
 
 #, c-format
 msgid "trust record %lu, req type %d: read failed: %s\n"
@@ -5042,53 +5127,6 @@ msgstr "不明の信用モデル (%d) は使えません - %s信用モデルを
 msgid "using %s trust model\n"
 msgstr "%s信用モデルを使用\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
-msgid "10 translator see trustdb.c:uid_trust_string_fixed"
-msgstr "10"
-
-msgid "[ revoked]"
-msgstr "[  失効  ]"
-
-msgid "[ expired]"
-msgstr "[期限切れ]"
-
-msgid "[ unknown]"
-msgstr "[  不明  ]"
-
-msgid "[  undef ]"
-msgstr "[ 未定義 ]"
-
-msgid "[marginal]"
-msgstr "[まぁまぁ]"
-
-msgid "[  full  ]"
-msgstr "[  充分  ]"
-
-msgid "[ultimate]"
-msgstr "[  究極  ]"
-
-msgid "undefined"
-msgstr "未定義"
-
-msgid "never"
-msgstr "断じてなし"
-
-msgid "marginal"
-msgstr "まぁまぁ"
-
-msgid "full"
-msgstr "充分"
-
-msgid "ultimate"
-msgstr "究極"
-
 msgid "no need for a trustdb check\n"
 msgstr "信用データベースの検査は、不要です\n"
 
@@ -5097,12 +5135,12 @@ msgid "next trustdb check due at %s\n"
 msgstr "次回の信用データベース検査は、%sです\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
-msgstr "信用モデル「%s」で信用データベースの検査は、不要です\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
+msgstr "信用モデル'%s'で信用データベースの検査は、不要です\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
-msgstr "信用モデル「%s」で信用データベースの更新は、不要です\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
+msgstr "信用モデル'%s'で信用データベースの更新は、不要です\n"
 
 #, c-format
 msgid "public key %s not found: %s\n"
@@ -5119,15 +5157,15 @@ msgid "%d keys processed (%d validity counts cleared)\n"
 msgstr "%d本の鍵を処理 (うち%d本の有効性数をクリア)\n"
 
 msgid "no ultimately trusted keys found\n"
-msgstr "究極的に信用する鍵が見つかりません\n"
+msgstr "絶対的に信用する鍵が見つかりません\n"
 
 #, c-format
 msgid "public key of ultimately trusted key %s not found\n"
-msgstr "究極的に信用する鍵%sの公開鍵が見つかりません\n"
+msgstr "絶対的に信用する鍵%sの公開鍵が見つかりません\n"
 
 #, c-format
 msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
-msgstr "「まぁまぁの信用」%d、「全面的信用」%d、%s信用モデル\n"
+msgstr "'まぁまぁの信用'%d、'全面的信用'%d、%s信用モデル\n"
 
 #, c-format
 msgid ""
@@ -5157,110 +5195,6 @@ msgstr "入力の%u行目が長すぎるか、LFがないようです\n"
 msgid "can't open fd %d: %s\n"
 msgstr "fd %dが開けません: %s\n"
 
-msgid "argument not expected"
-msgstr "引数は期待されていません"
-
-msgid "read error"
-msgstr "読み込みエラー"
-
-msgid "keyword too long"
-msgstr "キーワードが長すぎます"
-
-msgid "missing argument"
-msgstr "引数がありません"
-
-msgid "invalid argument"
-msgstr "無効な引数"
-
-msgid "invalid command"
-msgstr "無効なコマンド"
-
-msgid "invalid alias definition"
-msgstr "無効なエイリアス定義です"
-
-msgid "out of core"
-msgstr "メモリがありません"
-
-msgid "invalid option"
-msgstr "無効なオプション"
-
-#, c-format
-msgid "missing argument for option \"%.50s\"\n"
-msgstr "オプション\"%.50s\"に引数がありません\n"
-
-#, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "オプション\"%.50s\"に無効な引数です\n"
-
-#, c-format
-msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "オプション\"%.50s\"は引数をとりません\n"
-
-#, c-format
-msgid "invalid command \"%.50s\"\n"
-msgstr "無効なコマンド \"%.50s\"\n"
-
-#, c-format
-msgid "option \"%.50s\" is ambiguous\n"
-msgstr "オプション\"%.50s\"はあいまいです\n"
-
-#, c-format
-msgid "command \"%.50s\" is ambiguous\n"
-msgstr "コマンド\"%.50s\"はあいまいです\n"
-
-msgid "out of core\n"
-msgstr "メモリがありません\n"
-
-#, c-format
-msgid "invalid option \"%.50s\"\n"
-msgstr "無効なオプション \"%.50s\"\n"
-
-#, c-format
-msgid "you found a bug ... (%s:%d)\n"
-msgstr "あなたはバグを発見しました ... (%s:%d)\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "「%s」から「%s」への変換は利用できません\n"
-
-#, c-format
-msgid "iconv_open failed: %s\n"
-msgstr "iconv_openに失敗しました: %s\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "「%s」から「%s」への変換に失敗しました: %s\n"
-
-#, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "一時ファイル「%s」の作成に失敗しました: %s\n"
-
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "「%s」の書き込みエラー: %s\n"
-
-#, c-format
-msgid "removing stale lockfile (created by %d)\n"
-msgstr "古い lockfile (%d により作成)を除去します\n"
-
-msgid " - probably dead - removing lock"
-msgstr " - おそらく死んでます - ロックを除去"
-
-#, c-format
-msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "lockを待ちます (%d%s により保持) %s...\n"
-
-msgid "(deadlock?) "
-msgstr "(デッドロック?) "
-
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "lock 「%s」 は作成されませんでした: %s\n"
-
-#, c-format
-msgid "waiting for lock %s...\n"
-msgstr "lock %s を待ちます...\n"
-
 msgid "set debugging flags"
 msgstr "デバッグ・フラグを設定"
 
@@ -5279,15 +5213,15 @@ msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
-msgstr "RSAのモジュラスがないか、%dビットのものではありません\n"
+msgstr "RSAの法(modulus)がないか、%dビットのものではありません\n"
 
 #, c-format
 msgid "RSA public exponent missing or larger than %d bits\n"
-msgstr "RSA公開指数がないか %d ビットより大きすぎます\n"
+msgstr "RSA公開指数が指定されていないか %d ビットより大きすぎます\n"
 
 #, c-format
 msgid "PIN callback returned error: %s\n"
-msgstr "PINコールバックがエラーをしました: %s\n"
+msgstr "PINコールバックがエラーをしました: %s\n"
 
 msgid "the NullPIN has not yet been changed\n"
 msgstr "NullPINが変更されていません\n"
@@ -5342,11 +5276,14 @@ msgid "response does not contain the public key data\n"
 msgstr "応答に公開鍵データが含まれていません\n"
 
 msgid "response does not contain the RSA modulus\n"
-msgstr "応答にRSAのモジュラスが含まれていません\n"
+msgstr "応答にRSAの法(modulus)が含まれていません\n"
 
 msgid "response does not contain the RSA public exponent\n"
 msgstr "応答にRSA公開指数が含まれていません\n"
 
+msgid "response does not contain the EC public point\n"
+msgstr "応答に楕円曲線の公開点が含まれていません\n"
+
 #, c-format
 msgid "using default PIN as %s\n"
 msgstr "デフォルトPINを%sとして使います\n"
@@ -5373,14 +5310,14 @@ msgid "verify CHV%d failed: %s\n"
 msgstr "CHV%dの認証に失敗しました: %s\n"
 
 msgid "error retrieving CHV status from card\n"
-msgstr "カードからCHVステイタスの取得でエラー\n"
+msgstr "カードからのCHVステイタス取得でエラー\n"
 
 msgid "card is permanently locked!\n"
-msgstr "ã\82«ã\83¼ã\83\89ã\81\8cæ°¸ä¹\85ã\81«ã\83­ã\83\83ã\82¯ã\81\95ã\82\8cã\81¦ã\81¾ã\81\99!\n"
+msgstr "カードが永久にロックされます!\n"
 
 #, c-format
 msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
-msgstr "カードの永久ロック前に%d回の管理者PINの試行が残っています\n"
+msgstr "カードの永久ロック前に%dのAdmin PINが試されています\n"
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %%0A to force a linefeed.
@@ -5395,17 +5332,17 @@ msgid "access to admin commands is not configured\n"
 msgstr "管理コマンドへのアクセスが設定されていません\n"
 
 msgid "||Please enter the Reset Code for the card"
-msgstr "||カードのリセット・コードを入力してください"
+msgstr "||カードのReset Codeを入力してください"
 
 #, c-format
 msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "リセット・コードが短すぎます。最短の長さは%dです。\n"
+msgstr "Reset Codeが短すぎます。最短の長さは%dです。\n"
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
 #. to get some infos on the string.
 msgid "|RN|New Reset Code"
-msgstr "|RN|新しいリセット・コード"
+msgstr "|RN|新しいReset Code"
 
 msgid "|AN|New Admin PIN"
 msgstr "|AN|新しい管理者PIN"
@@ -5423,7 +5360,7 @@ msgid "error reading application data\n"
 msgstr "アプリケーション・データの読み込みエラー\n"
 
 msgid "error reading fingerprint DO\n"
-msgstr "ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\81®ã\83\87ã\83¼ã\82¿ã\83»ã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88ã\81®èª­ã\81¿è¾¼ã\81¿ã\82¨ã\83©ã\83¼\n"
+msgstr "フィンガープリントのデータ・オブジェクトの読み込みエラー\n"
 
 msgid "key already exists\n"
 msgstr "鍵はもうあります\n"
@@ -5462,7 +5399,7 @@ msgid "invalid structure of OpenPGP card (DO 0x93)\n"
 msgstr "OpenPGPカードに無効な構造 (データ・オブジェクト 0x93)\n"
 
 msgid "fingerprint on card does not match requested one\n"
-msgstr "ã\82«ã\83¼ã\83\89ã\81®ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\81\8cè¦\81æ±\82ã\81\95ã\82\8cã\81\9fã\82\82ã\81®ã\81¨ä¸\80è\87´ã\81\97ã\81¾ã\81\9bã\82\93\n"
+msgstr "カードのフィンガープリントが要求されたものと一致しません\n"
 
 #, c-format
 msgid "card does not support digest algorithm %s\n"
@@ -5520,21 +5457,21 @@ msgid "deny the use of admin card commands"
 msgstr "管理カード・コマンドの使用を拒否"
 
 msgid "use variable length input for pinpad"
-msgstr "PINPADで可変長入力を使う"
+msgstr "ピンパッドの可変長入力を使う"
 
-msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "使い方: scdaemon [オプション] (ヘルプは -h)"
+msgid "Usage: @SCDAEMON@ [options] (-h for help)"
+msgstr "使い方: @SCDAEMON@ [オプション] (ヘルプは -h)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
-"Smartcard daemon for GnuPG\n"
+"Smartcard daemon for @GNUPG@\n"
 msgstr ""
 "形式: scdaemon [オプション] [コマンド [引数]]\n"
-"GnuPGのSmartcardデーモン\n"
+"@GNUPG@のSmartcardデーモン\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
-"\"--daemon\"オプションを使って、プログラムをバックグラウンドで実行してくださ"
+"'--daemon'オプションを使って、プログラムをバックグラウンドで実行してくださ"
 "い\n"
 
 #, c-format
@@ -5550,24 +5487,6 @@ msgid "invalid radix64 character %02x skipped\n"
 msgstr "無効な64進文字%02Xをスキップしました\n"
 
 #, c-format
-msgid "failed to proxy %s inquiry to client\n"
-msgstr "プロキシ%sのクライアントへの問い合わせが失敗しました\n"
-
-#, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "Dirmngrが動いていません - 開始します「%s」\n"
-
-msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "DIRMNGR_INFO環境変数が破壊されています\n"
-
-#, c-format
-msgid "dirmngr protocol version %d is not supported\n"
-msgstr "dirmngrプロトコル・バージョン%dはサポートされていません\n"
-
-msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr "dirmngrに接続できません - フォールバックを試します\n"
-
-#, c-format
 msgid "validation model requested by certificate: %s"
 msgstr "証明書から以下の検証モデルが要求されました: %s"
 
@@ -5585,17 +5504,19 @@ msgid "issuer certificate is not marked as a CA"
 msgstr "発行者の証明書がCAとしてマークされていません"
 
 msgid "critical marked policy without configured policies"
-msgstr "ã\82³ã\83³ã\83\95ã\82£ã\82°ã\81\95ã\82\8cã\81\9fã\83\9dã\83ªã\82·ã\83¼ã\81ªã\81\97ã\81«ã\82¯ã\83ªã\83\86ã\82£ã\82«ã\83«ã\81«ã\83\9eã\83¼ã\82¯ã\81\95ã\82\8cã\81\9fã\83\9dã\83ªã\82·ã\83¼"
+msgstr "ã\82³ã\83³ã\83\95ã\82£ã\82°ã\81\95ã\82\8cã\81\9fã\83\9dã\83ªã\82·ã\81ªã\81\97ã\81«ã\82¯ã\83ªã\83\86ã\82£ã\82«ã\83«ã\81«ã\83\9eã\83¼ã\82¯ã\81\95ã\82\8cã\81\9fã\83\9dã\83ªã\82·"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
-msgstr "「%s」が開けません: %s\n"
+msgid "failed to open '%s': %s\n"
+msgstr "'%s'が開けません: %s\n"
 
-msgid "note: non-critical certificate policy not allowed"
-msgstr "注意: クリティカルでない証明書ポリシーは認められません"
+#, fuzzy
+#| msgid "note: non-critical certificate policy not allowed"
+msgid "Note: non-critical certificate policy not allowed"
+msgstr "注意: クリティカルでない証明書ポリシは認められません"
 
 msgid "certificate policy not allowed"
-msgstr "証æ\98\8eæ\9b¸ã\83\9dã\83ªã\82·ã\83¼ã\81¯èª\8dã\82\81ã\82\89ã\82\8cã\81¾ã\81\9bã\82\93"
+msgstr "証明書ポリシは認められません"
 
 msgid "looking up issuer at external location\n"
 msgstr "発行者の外部ロケーションを調べています\n"
@@ -5683,7 +5604,7 @@ msgstr "  (     発行者、有効"
 
 #, c-format
 msgid "fingerprint=%s\n"
-msgstr "ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88=%s\n"
+msgstr "フィンガープリント=%s\n"
 
 msgid "root certificate has now been marked as trusted\n"
 msgstr "ルート証明書は信用すると今、マークされました\n"
@@ -5746,10 +5667,6 @@ msgid "validation model used: %s"
 msgstr "使用した検証モデル: %s"
 
 #, c-format
-msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "%s 鍵は安全でない(%uビット)ハッシュを使用しています\n"
-
-#, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
 msgstr "%uビットハッシュは%uビットの%s鍵には無効です\n"
 
@@ -5823,24 +5740,60 @@ msgid "line %d: no subject name given\n"
 msgstr "行 %d: サブジェクト名がありません\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
-msgstr "行 %d: 無効なサブジェクト名ラベル「%.*s」です\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
+msgstr "行 %d: 無効なサブジェクト名ラベル'%.*s'です\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
-msgstr "行 %d: 無効なサブジェクト名「%s」(位置: %d)です\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
+msgstr "行 %d: 無効なサブジェクト名'%s'(位置: %d)です\n"
 
 #, c-format
 msgid "line %d: not a valid email address\n"
 msgstr "行 %d: 有効な電子メール・アドレスではありません\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
-msgstr "行 %d: カードから鍵「%s」の読み込みエラー: %s\n"
+msgid "line %d: invalid serial number\n"
+msgstr "行 %d: 無効なシリアル番号です\n"
+
+#, c-format
+msgid "line %d: invalid issuer name label '%.*s'\n"
+msgstr "行 %d: 無効なサブジェクト名ラベル'%.*s'です\n"
+
+#, c-format
+msgid "line %d: invalid issuer name '%s' at pos %d\n"
+msgstr "行 %d: 無効なサブジェクト名'%s'(位置: %d)です\n"
+
+#, c-format
+msgid "line %d: invalid date given\n"
+msgstr "行 %d: 無効な日付が与えられました\n"
+
+#, c-format
+msgid "line %d: error getting signing key by keygrip '%s': %s\n"
+msgstr "行 %d: keygrip'%s'から鍵の取得エラー: %s\n"
+
+#, c-format
+msgid "line %d: invalid hash algorithm given\n"
+msgstr "行 %d: 無効なハッシュ・アルゴリズムです\n"
+
+#, c-format
+msgid "line %d: invalid authority-key-id\n"
+msgstr "行 %d: 無効なauthority-key-idです\n"
+
+#, c-format
+msgid "line %d: invalid subject-key-id\n"
+msgstr "行 %d: 無効なsubject-key-idです\n"
+
+#, c-format
+msgid "line %d: invalid extension syntax\n"
+msgstr "行 %d: 無効な拡張構文です\n"
+
+#, c-format
+msgid "line %d: error reading key '%s' from card: %s\n"
+msgstr "行 %d: カードから鍵'%s'の読み込みエラー: %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
-msgstr "行 %d: keygrip「%s」から鍵の取得エラー: %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
+msgstr "行 %d: keygrip'%s'から鍵の取得エラー: %s\n"
 
 #, c-format
 msgid "line %d: key generation failed: %s <%s>\n"
@@ -5865,15 +5818,6 @@ msgstr "   (%d) 既存の鍵\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) カードに存在する鍵\n"
 
-msgid "Enter the keygrip: "
-msgstr "keygripを入力: "
-
-msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "有効なkeygrip (40桁の16進数字)ではありません\n"
-
-msgid "No key with this keygrip\n"
-msgstr "このkeygripの鍵はありません\n"
-
 #, c-format
 msgid "error reading the card: %s\n"
 msgstr "カードの読み込みエラー: %s\n"
@@ -5908,8 +5852,8 @@ msgid "No subject name given\n"
 msgstr "サブジェクト名がありません\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
-msgstr "無効なサブジェクト名ラベル「%.*s」です\n"
+msgid "Invalid subject name label '%.*s'\n"
+msgstr "無効なサブジェクト名ラベル'%.*s'です\n"
 
 #. TRANSLATORS: The 22 in the second string is the
 #. length of the first string up to the "%s".  Please
@@ -5917,8 +5861,8 @@ msgstr "無効なサブジェクト名ラベル「%.*s」です\n"
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
-msgstr "無効なサブジェクト名「%s」です\n"
+msgid "Invalid subject name '%s'\n"
+msgstr "無効なサブジェクト名'%s'です\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
 msgstr "33"
@@ -5938,11 +5882,23 @@ msgstr " (オプションです。空行で終了):\n"
 msgid "Enter URIs"
 msgstr "URIを入力"
 
-msgid "Parameters to be used for the certificate request:\n"
-msgstr "証明書要求に使われるパラメータ:\n"
+msgid "Create self-signed certificate? (y/N) "
+msgstr "自己署名証明書を作成しますか? (y/N) "
+
+msgid "These parameters are used:\n"
+msgstr "下記のパラメータが使われます:\n"
+
+msgid "Now creating self-signed certificate.  "
+msgstr "今、自己署名証明書を作成しています。  "
 
-msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr "証明書要求を作成しています。しばらく時間がかかります ...\n"
+msgid "Now creating certificate request.  "
+msgstr "今、証明書要求を作成しています。  "
+
+msgid "This may take a while ...\n"
+msgstr "しばらくかかります...\n"
+
+msgid "Ready.\n"
+msgstr "準備完了。\n"
 
 msgid "Ready.  You should now send this request to your CA.\n"
 msgstr "準備ができました。今、この要求をあなたのCAに送るべきです。\n"
@@ -5957,24 +5913,24 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(暗号化されたメッセージではないようです)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
-msgstr "証明書「%s」が見つかりません: %s\n"
+msgid "certificate '%s' not found: %s\n"
+msgstr "証明書'%s'が見つかりません: %s\n"
 
 #, c-format
 msgid "error locking keybox: %s\n"
 msgstr "keyboxのロックのエラー: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
-msgstr "重複した証明書「%s」を削除しました\n"
+msgid "duplicated certificate '%s' deleted\n"
+msgstr "重複した証明書'%s'を削除しました\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
-msgstr "証明書「%s」を削除しました\n"
+msgid "certificate '%s' deleted\n"
+msgstr "証明書'%s'を削除しました\n"
 
 #, c-format
 msgid "deleting certificate \"%s\" failed: %s\n"
-msgstr "証明書「%s」の削除に失敗しました: %s\n"
+msgstr "証明書'%s'の削除に失敗しました: %s\n"
 
 msgid "no valid recipients given\n"
 msgstr "有効な受け取り手が指定されていません\n"
@@ -5992,7 +5948,7 @@ msgid "export certificates"
 msgstr "証明書をエクスポートする"
 
 msgid "register a smartcard"
-msgstr "スマートカードを登録する"
+msgstr "ICカードを登録する"
 
 msgid "pass a command to the dirmngr"
 msgstr "dirmngrにコマンドを渡す"
@@ -6012,9 +5968,6 @@ msgstr "base-64フォーマットの入力を仮定する"
 msgid "assume input is in binary format"
 msgstr "バイナリ・フォーマットの入力を仮定する"
 
-msgid "use system's dirmngr if available"
-msgstr "もしあれば、システムのdirmngrを使用する"
-
 msgid "never consult a CRL"
 msgstr "決してCRLを調べない"
 
@@ -6025,10 +5978,10 @@ msgid "|N|number of certificates to include"
 msgstr "|N|インクルードする証明書の数"
 
 msgid "|FILE|take policy information from FILE"
-msgstr "|FILE|ポリシ情報をFILEから取得する"
+msgstr "|FILE|ポリシ情報をFILEから取得する"
 
 msgid "do not check certificate policies"
-msgstr "証æ\98\8eæ\9b¸ã\83\9dã\83ªã\82·ã\83¼ã\82\92ã\83\81ã\82§ã\83\83ã\82¯ã\81\97ã\81ªã\81\84"
+msgstr "証明書ポリシをチェックしない"
 
 msgid "fetch missing issuer certificates"
 msgstr "紛失している発行者証明書を取得する"
@@ -6066,28 +6019,25 @@ msgstr "|NAME|暗号アルゴリズムにNAMEを使用"
 msgid "|NAME|use message digest algorithm NAME"
 msgstr "|NAME|ダイジェスト・アルゴリズムにNAMEを使用"
 
-msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "使い方: gpgsm [オプション] [ファイル] (ヘルプは -h)"
+msgid "Usage: @GPGSM@ [options] [files] (-h for help)"
+msgstr "使い方: @GPGSM@ [オプション] [ファイル] (ヘルプは -h)"
 
 msgid ""
-"Syntax: gpgsm [options] [files]\n"
+"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 ""
-"形式: gpgsm [オプション] [ファイル]\n"
+"形式: @GPGSM@ [オプション] [ファイル]\n"
 "S/MIMEプロトコルを用いて、署名、検査、暗号化や復号を行います\n"
 "デフォルトの操作は、入力データに依存します\n"
 
-msgid "usage: gpgsm [options] "
-msgstr "使い方: gpgsm [オプション] "
-
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
-msgstr "*注意*:「%s」に対して暗号化できません: %s\n"
+msgid "Note: won't be able to encrypt to '%s': %s\n"
+msgstr "*注意*:'%s'に対して暗号化できません: %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
-msgstr "不明の検証モデル 「%s」\n"
+msgid "unknown validation model '%s'\n"
+msgstr "不明の検証モデル '%s'\n"
 
 #, c-format
 msgid "%s:%u: no hostname given\n"
@@ -6104,16 +6054,13 @@ msgstr "%s:%u: この行はスキップ\n"
 msgid "could not parse keyserver\n"
 msgstr "鍵サーバのURLを解析不能\n"
 
-msgid "WARNING: running with faked system time: "
-msgstr "*警告*: ニセモノのシステム時刻で実行しています: "
-
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "共通証明書のインポート・エラー: %s\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
-msgstr "「%s」を用いて署名できません: %s\n"
+msgid "can't sign using '%s': %s\n"
+msgstr "'%s'を用いて署名できません: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
 msgstr "無効なコマンド (暗黙のコマンドはありません)\n"
@@ -6140,16 +6087,8 @@ msgstr "証明書のインポート・エラー: %s\n"
 msgid "error reading input: %s\n"
 msgstr "入力読み込みエラー: %s\n"
 
-#, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "keybox「%s」の作成エラー: %s\n"
-
-#, c-format
-msgid "keybox `%s' created\n"
-msgstr "keybox「%s」が作成されました\n"
-
 msgid "failed to get the fingerprint\n"
-msgstr "ã\83\95ã\82£ã\83³ã\82¬ã\83¼ã\83»ã\83\97ã\83ªã\83³ã\83\88ã\81®å\8f\96å¾\97ã\81«å¤±æ\95\97ã\81\97ã\81¾ã\81\97ã\81\9f\n"
+msgstr "フィンガープリントの取得に失敗しました\n"
 
 #, c-format
 msgid "problem looking for existing certificate: %s\n"
@@ -6178,12 +6117,12 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr "GPG_TTY が設定されていません - 少々疑問のデフォルトを使います\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "「%s」(行 %d) 無効な形式のフィンガー・プリント\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
+msgstr "'%s'(行 %d) 無効な形式のフィンガープリント\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "「%s」 (行 %d)で無効な国識別コード\n"
+msgid "invalid country code in '%s', line %d\n"
+msgstr "'%s' (行 %d)で無効な国識別コード\n"
 
 #, c-format
 msgid ""
@@ -6256,88 +6195,1277 @@ msgstr "      別名"
 msgid "This is a qualified signature\n"
 msgstr "これは認定署名です\n"
 
-msgid "quiet"
-msgstr "おとなしく"
+#, c-format
+msgid "can't initialize certificate cache lock: %s\n"
+msgstr "証明書キャッシュのロックが初期化できません: %s\n"
 
-msgid "print data out hex encoded"
-msgstr "16進でエンコードしてデータ出力を表示する"
+#, c-format
+msgid "can't acquire read lock on the certificate cache: %s\n"
+msgstr "証明書キャッシュの読み出しロックが取得できません: %s\n"
 
-msgid "decode received data lines"
-msgstr "受信したデータ行をデコードする"
+#, c-format
+msgid "can't acquire write lock on the certificate cache: %s\n"
+msgstr "証明書キャッシュの書き込みロックが取得できません: %s\n"
 
-msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NAME|Assuanのソケット名NAMEに接続する"
+#, c-format
+msgid "can't release lock on the certificate cache: %s\n"
+msgstr "証明書キャッシュのロックが解除できません: %s\n"
 
-msgid "run the Assuan server given on the command line"
-msgstr "コマンド・ラインで与えられたAssuanサーバを実行する"
+#, c-format
+msgid "dropping %u certificates from the cache\n"
+msgstr "%uの証明書をキャッシュからはずします\n"
 
-msgid "do not use extended connect mode"
-msgstr "拡張接続モードを使わない"
+#, c-format
+msgid "can't access directory '%s': %s\n"
+msgstr "ディレクトリ'%s'が作成できません: %s\n"
 
-msgid "|FILE|run commands from FILE on startup"
-msgstr "|FILE|起動時にFILEからコマンドを実行する"
+#, c-format
+msgid "can't parse certificate '%s': %s\n"
+msgstr "証明書'%s'が解析できません: %s\n"
 
-msgid "run /subst on startup"
-msgstr "起動時に /subst を実行する"
+#, c-format
+msgid "certificate '%s' already cached\n"
+msgstr "証明書'%s'はすでにキャッシュされています\n"
 
-msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "使い方: gpg-connect-agent [オプション] (ヘルプは -h)"
+#, c-format
+msgid "trusted certificate '%s' loaded\n"
+msgstr "信用される証明書'%s'をロードしました\n"
 
-msgid ""
-"Syntax: gpg-connect-agent [options]\n"
-"Connect to a running agent and send commands\n"
-msgstr ""
-"形式: gpg-connect-agent [オプション]\n"
-"実行中のagentに接続し、コマンドを送る\n"
+#, c-format
+msgid "certificate '%s' loaded\n"
+msgstr "証明書'%s'をロードしました\n"
 
 #, c-format
-msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr "オプション\"%s\"はプログラムとオプショナルの引数を要します\n"
+msgid "  SHA1 fingerprint = %s\n"
+msgstr "  SHA1フィンガープリント = %s\n"
+
+msgid "   issuer ="
+msgstr "   発行者 ="
+
+msgid "  subject ="
+msgstr "サブジェクト ="
 
 #, c-format
-msgid "option \"%s\" ignored due to \"%s\"\n"
-msgstr "オプション\"%s\"は\"%s\"のため無視されました\n"
+msgid "error loading certificate '%s': %s\n"
+msgstr "証明書'%s'の読み込みエラー: %s\n"
 
 #, c-format
-msgid "receiving line failed: %s\n"
-msgstr "行の受信に失敗しました: %s\n"
+msgid "permanently loaded certificates: %u\n"
+msgstr "永続的にロードされる証明書: %u\n"
 
-msgid "line too long - skipped\n"
-msgstr "行が長すぎます - スキップされました\n"
+#, c-format
+msgid "    runtime cached certificates: %u\n"
+msgstr "実行時キャッシュ証明書の数: %u\n"
 
-msgid "line shortened due to embedded Nul character\n"
-msgstr "組込みのNulキャラクタのため行は短くされました\n"
+msgid "certificate already cached\n"
+msgstr "   すでにキャッシュされた証明書\n"
+
+msgid "certificate cached\n"
+msgstr "キャッシュされた証明書\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
-msgstr "不明のコマンド「%s」\n"
+msgid "error caching certificate: %s\n"
+msgstr "証明書のキャッシュのエラー: %s\n"
 
 #, c-format
-msgid "sending line failed: %s\n"
-msgstr "行の送信に失敗しました: %s\n"
+msgid "invalid SHA1 fingerprint string '%s'\n"
+msgstr "無効なSHA1フィンガープリント文字列'%s'\n"
 
 #, c-format
-msgid "error sending %s command: %s\n"
-msgstr "「%s」コマンドの送信エラー: %s\n"
+msgid "error fetching certificate by S/N: %s\n"
+msgstr "S/Nでの証明書取得エラー : %s\n"
 
 #, c-format
-msgid "error sending standard options: %s\n"
-msgstr "標準オプションを送信エラー: %s\n"
+msgid "error fetching certificate by subject: %s\n"
+msgstr "サブジェクトでの証明書取得エラー: %s\n"
 
-msgid "Options controlling the diagnostic output"
-msgstr "診æ\96­å\87ºå\8a\9bã\82\92å\88¶å¾¡ã\81\99ã\82\8bã\82ªã\83\97ã\82·ã\83§ã\83³"
+msgid "no issuer found in certificate\n"
+msgstr "証æ\98\8eæ\9b¸ã\81«ç\99ºè¡\8cè\80\85ã\81\8cã\81¿ã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93\n"
 
-msgid "Options controlling the configuration"
-msgstr "コンフィグレーションを制御するオプション"
+#, c-format
+msgid "error getting authorityKeyIdentifier: %s\n"
+msgstr "authorityKeyIdentifierの取得エラー: %s\n"
 
-msgid "Options useful for debugging"
-msgstr "デバッグのために有用なオプション"
+#, c-format
+msgid "creating directory '%s'\n"
+msgstr "ディレクトリ'%s'の作成\n"
 
-msgid "|FILE|write server mode logs to FILE"
-msgstr "|FILE|FILEにサーバ・モードのログを書き出す"
+#, c-format
+msgid "error creating directory '%s': %s\n"
+msgstr "ディレクトリ'%s'の作成エラー: %s\n"
 
-msgid "Options controlling the security"
-msgstr "セキュリティを制御するオプション"
+#, c-format
+msgid "ignoring database dir '%s'\n"
+msgstr "データベース・ディレクトリ'%s'を無視します\n"
+
+#, c-format
+msgid "error reading directory '%s': %s\n"
+msgstr "ディレクトリ'%s'の読み込みエラー: %s\n"
+
+#, c-format
+msgid "removing cache file '%s'\n"
+msgstr "キャッシュ・ファイル' %s'の削除\n"
+
+#, c-format
+msgid "not removing file '%s'\n"
+msgstr "ファイル'%s'を削除しません\n"
+
+#, c-format
+msgid "error closing cache file: %s\n"
+msgstr "キャッシュ・ファイルでクローズのエラー: %s\n"
+
+#, c-format
+msgid "failed to open cache dir file '%s': %s\n"
+msgstr "キャッシュ・ディレクトリ・ファイル'%s'が開けません: %s\n"
+
+#, c-format
+msgid "error creating new cache dir file '%s': %s\n"
+msgstr "新しいキャッシュ・ディレクトリ・ファイル'%s'の作成エラー: %s\n"
+
+#, c-format
+msgid "error writing new cache dir file '%s': %s\n"
+msgstr "新しいキャッシュ・ディレクトリ・ファイル'%s'の書き込みエラー: %s\n"
+
+#, c-format
+msgid "error closing new cache dir file '%s': %s\n"
+msgstr "新しいキャッシュ・ディレクトリ・ファイル'%s'でクローズのエラー: %s\n"
+
+#, c-format
+msgid "new cache dir file '%s' created\n"
+msgstr "新しいキャッシュ・ディレクトリ・ファイル'%s'ができました\n"
+
+#, c-format
+msgid "failed to re-open cache dir file '%s': %s\n"
+msgstr "キャッシュ・ディレクトリ・ファイル'%s'が再オープンできません: %s\n"
+
+#, c-format
+msgid "first record of '%s' is not the version\n"
+msgstr "最初のレコード'%s'はそのバージョンではありません。\n"
+
+msgid "old version of cache directory - cleaning up\n"
+msgstr "古いバージョンのキャッシュ・ディレクトリ - きれいにします\n"
+
+msgid "old version of cache directory - giving up\n"
+msgstr "古いバージョンのキャッシュ・ディレクトリ - あきらめます\n"
+
+#, c-format
+msgid "extra field detected in crl record of '%s' line %u\n"
+msgstr "crlレコードの'%s'に行 %u で余分なフィールドが検出されました\n"
+
+#, c-format
+msgid "invalid line detected in '%s' line %u\n"
+msgstr "'%s' (行 %u)で無効な行\n"
+
+#, c-format
+msgid "duplicate entry detected in '%s' line %u\n"
+msgstr "'%s' (行 %u)で重複したエントリ\n"
+
+#, c-format
+msgid "unsupported record type in '%s' line %u skipped\n"
+msgstr "サポートしていないレコード型 '%s' を行 %u でスキップしました\n"
+
+#, c-format
+msgid "invalid issuer hash in '%s' line %u\n"
+msgstr "'%s'の無効な発行者ハッシュ(行 %u)\n"
+
+#, c-format
+msgid "no issuer DN in '%s' line %u\n"
+msgstr "'%s'で発行者DNがありません(行 %u)\n"
+
+#, c-format
+msgid "invalid timestamp in '%s' line %u\n"
+msgstr "'%s'の無効なタイムスタンプ(行 %u)\n"
+
+#, c-format
+msgid "WARNING: invalid cache file hash in '%s' line %u\n"
+msgstr "*警告*: '%s'で無効なキャッシュ・ファイル・ハッシュ(行 %u)\n"
+
+msgid "detected errors in cache dir file\n"
+msgstr "キャッシュ・ディレクトリ・ファイルの検出エラー\n"
+
+msgid "please check the reason and manually delete that file\n"
+msgstr "理由を確認し、手動でそのファイルを削除してください\n"
+
+#, c-format
+msgid "failed to create temporary cache dir file '%s': %s\n"
+msgstr "一時キャッシュ・ディレクトリ・ファイル'%s'が作成できません: %s\n"
+
+#, c-format
+msgid "error closing '%s': %s\n"
+msgstr "'%s'でクローズのエラー: %s\n"
+
+#, c-format
+msgid "error renaming '%s' to '%s': %s\n"
+msgstr "'%s'から'%s'へ名前変更のエラー: %s\n"
+
+#, c-format
+msgid "can't hash '%s': %s\n"
+msgstr "'%s'をハッシュできません: %s\n"
+
+#, c-format
+msgid "error setting up MD5 hash context: %s\n"
+msgstr "MD5ハッシュ・コンテクストの設定エラー: %s\n"
+
+#, c-format
+msgid "error hashing '%s': %s\n"
+msgstr "'%s'でハッシュのエラー: %s\n"
+
+#, c-format
+msgid "invalid formatted checksum for '%s'\n"
+msgstr "'%s'に対する無効な形式のチェックサム\n"
+
+msgid "too many open cache files; can't open anymore\n"
+msgstr ""
+"キャッシュ・ファイルを多くオープンしすぎです。これ以上オープンできません\n"
+
+#, c-format
+msgid "opening cache file '%s'\n"
+msgstr "キャッシュ・ファイル'%s'を開く\n"
+
+#, c-format
+msgid "error opening cache file '%s': %s\n"
+msgstr "キャッシュ・ファイル'%s'を開く際、エラー: %s\n"
+
+#, c-format
+msgid "error initializing cache file '%s' for reading: %s\n"
+msgstr "キャッシュ・ファイル '%s' の初期化エラー、読み込み: %s\n"
+
+msgid "calling unlock_db_file on a closed file\n"
+msgstr "unlock_db_file のクローズしたファイルへの呼び出し\n"
+
+msgid "calling unlock_db_file on an unlocked file\n"
+msgstr "unlock_db_fileのロックしてないファイルへの呼び出し\n"
+
+#, c-format
+msgid "failed to create a new cache object: %s\n"
+msgstr "新しいキャッシュ・オブジェクトを作成するのに失敗しました: %s\n"
+
+#, c-format
+msgid "no CRL available for issuer id %s\n"
+msgstr "発行者ID%sに対してCRLはありません\n"
+
+#, c-format
+msgid "cached CRL for issuer id %s too old; update required\n"
+msgstr "キャッシュされたCRLの発行者ID %s が古すぎます。更新が必要です\n"
+
+#, c-format
+msgid ""
+"force-crl-refresh active and %d minutes passed for issuer id %s; update "
+"required\n"
+msgstr ""
+"force-crl-refreshが有効で%d分が発行者ID%sに経過しました。更新が必要です\n"
+
+#, c-format
+msgid "force-crl-refresh active for issuer id %s; update required\n"
+msgstr "force-crl-refreshが発行者ID%sに対し有効です。更新が必要です\n"
+
+#, c-format
+msgid "available CRL for issuer ID %s can't be used\n"
+msgstr "発行者ID%sに対する利用可能なCRLが使用できません\n"
+
+#, c-format
+msgid "cached CRL for issuer id %s tampered; we need to update\n"
+msgstr ""
+"発行者ID%sに対するキャッシュされたCRLが変更されています。更新が必要です\n"
+
+msgid "WARNING: invalid cache record length for S/N "
+msgstr "**警告**: S/Nに対する無効なキャッシュ・レコード長"
+
+#, c-format
+msgid "problem reading cache record for S/N %s: %s\n"
+msgstr "S/N %sに対するキャッシュ・レコードを読み込む際の問題: %s\n"
+
+#, c-format
+msgid "S/N %s is not valid; reason=%02X  date=%.15s\n"
+msgstr "S/N %s は無効です。理由=%02X 日付=%.15s\n"
+
+#, c-format
+msgid "S/N %s is valid, it is not listed in the CRL\n"
+msgstr "S/N %sは有効です。CRLに載っていません\n"
+
+#, c-format
+msgid "error getting data from cache file: %s\n"
+msgstr "キャッシュ・ファイルからデータの取得エラー: %s\n"
+
+#, c-format
+msgid "unknown hash algorithm '%s'\n"
+msgstr "不明なハッシュ・アルゴリズム'%s'\n"
+
+#, c-format
+msgid "gcry_md_open for algorithm %d failed: %s\n"
+msgstr "アルゴリズム%dのgcry_md_openが失敗: %s\n"
+
+msgid "got an invalid S-expression from libksba\n"
+msgstr "libksbaから無効なS-式を取得しました\n"
+
+#, c-format
+msgid "converting S-expression failed: %s\n"
+msgstr "S式の変換に失敗しました: %s\n"
+
+#, c-format
+msgid "creating S-expression failed: %s\n"
+msgstr "S式の作成に失敗しました: %s\n"
+
+#, c-format
+msgid "ksba_crl_parse failed: %s\n"
+msgstr "ksba_crl_parse に失敗しました: %s\n"
+
+#, c-format
+msgid "error getting update times of CRL: %s\n"
+msgstr "CRLの更新時刻の取得エラー: %s\n"
+
+#, c-format
+msgid "update times of this CRL: this=%s next=%s\n"
+msgstr "このCRLの更新時刻: これ=%s 次=%s\n"
+
+msgid "nextUpdate not given; assuming a validity period of one day\n"
+msgstr "nextUpdateが与えられていません。一日の有効期間を仮定します\n"
+
+#, c-format
+msgid "error getting CRL item: %s\n"
+msgstr "CRL項目の取得エラー: %s\n"
+
+#, c-format
+msgid "error inserting item into temporary cache file: %s\n"
+msgstr "一時キャッシュ・ファイルに項目の挿入エラー: %s\n"
+
+#, c-format
+msgid "no CRL issuer found in CRL: %s\n"
+msgstr "CRLに発行者がありません: %s\n"
+
+msgid "locating CRL issuer certificate by authorityKeyIdentifier\n"
+msgstr "CRL発行証明書をauthorityKeyIdentifierで見つけます\n"
+
+#, c-format
+msgid "CRL signature verification failed: %s\n"
+msgstr "CRL署名の検証に失敗しました: %s\n"
+
+#, c-format
+msgid "error checking validity of CRL issuer certificate: %s\n"
+msgstr "CRL発行者証明書の検証検査エラ−: %s\n"
+
+#, c-format
+msgid "ksba_crl_new failed: %s\n"
+msgstr "ksba_crl_new が失敗しました: %s\n"
+
+#, c-format
+msgid "ksba_crl_set_reader failed: %s\n"
+msgstr "ksba_crl_set_reader が失敗しました: %s\n"
+
+#, c-format
+msgid "removed stale temporary cache file '%s'\n"
+msgstr "古い一時キャッシュ・ファイル'%s'を削除しました\n"
+
+#, c-format
+msgid "problem removing stale temporary cache file '%s': %s\n"
+msgstr "古い一時キャッシュ・ファイル'%s'が削除の問題: %s\n"
+
+#, c-format
+msgid "error creating temporary cache file '%s': %s\n"
+msgstr "一時キャッシュ・ファイル'%s'の作成エラー: %s\n"
+
+#, c-format
+msgid "crl_parse_insert failed: %s\n"
+msgstr "crl_parse_insert が失敗しました: %s\n"
+
+#, c-format
+msgid "error finishing temporary cache file '%s': %s\n"
+msgstr "一時キャッシュ・ファイル'%s'の終了エラー: %s\n"
+
+#, c-format
+msgid "error closing temporary cache file '%s': %s\n"
+msgstr "一時キャッシュ・ファイル'%s'のクローズ・エラー: %s\n"
+
+#, c-format
+msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n"
+msgstr ""
+"**警告**: 新しいCRLはまだ古すぎます。%sに期限がきています - それでも読み込み"
+"ます\n"
+
+#, c-format
+msgid "new CRL still too old; it expired on %s\n"
+msgstr "新しいCRLはまだ古すぎます。%sに期限がきています\n"
+
+#, c-format
+msgid "unknown critical CRL extension %s\n"
+msgstr "不明のクリティカルCRLの拡張 %s\n"
+
+#, c-format
+msgid "error reading CRL extensions: %s\n"
+msgstr "CRL拡張の読み込みエラー: %s\n"
+
+#, c-format
+msgid "creating cache file '%s'\n"
+msgstr "キャッシュ・ファイル'%s'の作成\n"
+
+#, c-format
+msgid "problem renaming '%s' to '%s': %s\n"
+msgstr "'%s'から'%s'へ名前変更の問題: %s\n"
+
+msgid ""
+"updating the DIR file failed - cache entry will get lost with the next "
+"program start\n"
+msgstr ""
+"DIRファイルの更新の失敗 - キャッシュ・エントリは次のプログラムの開始で失われ"
+"ます\n"
+
+#, c-format
+msgid "Begin CRL dump (retrieved via %s)\n"
+msgstr "CRLダンプの開始 (%s から取得)\n"
+
+msgid ""
+" ERROR: The CRL will not be used because it was still too old after an "
+"update!\n"
+msgstr "*エラー*: CRLは使用されません。更新後でも、古すぎるからです!\n"
+
+msgid ""
+" ERROR: The CRL will not be used due to an unknown critical extension!\n"
+msgstr "*エラー*: CRLは不明なクリティカル拡張のため使用されません!\n"
+
+msgid " ERROR: The CRL will not be used\n"
+msgstr "*エラー*: CRLは使用されません\n"
+
+msgid " ERROR: This cached CRL may have been tampered with!\n"
+msgstr "*エラー*: このキャッシュされたCRLは変更されているかもしれません!\n"
+
+msgid " WARNING: invalid cache record length\n"
+msgstr "*警告*: 無効なキャッシュ・レコード長\n"
+
+#, c-format
+msgid "problem reading cache record: %s\n"
+msgstr "キャッシュ・レコードの読み込みの問題: %s\n"
+
+#, c-format
+msgid "problem reading cache key: %s\n"
+msgstr "キャッシュ鍵の再読み込みの問題: %s\n"
+
+#, c-format
+msgid "error reading cache entry from db: %s\n"
+msgstr "dbからキャッシュ・エントリの読み込みエラー: %s\n"
+
+msgid "End CRL dump\n"
+msgstr "CRLダンプの終了\n"
+
+#, c-format
+msgid "crl_fetch via DP failed: %s\n"
+msgstr "DPからcrl_fetchが失敗しました: %s\n"
+
+#, c-format
+msgid "crl_cache_insert via DP failed: %s\n"
+msgstr "DPからcrl_cache_insertが失敗しました: %s\n"
+
+#, c-format
+msgid "crl_cache_insert via issuer failed: %s\n"
+msgstr "発行者からcrl_cache_insertが失敗しました: %s\n"
+
+msgid "reader to file mapping table full - waiting\n"
+msgstr "readerからファイル・マッピングのテーブルがいっぱいです - 待ちます\n"
+
+msgid "using \"http\" instead of \"https\"\n"
+msgstr "\"http\" を \"https\" の代わりに使います\n"
+
+#, c-format
+msgid "CRL access not possible due to disabled %s\n"
+msgstr "CRLアクセスは停止された%sのため不可能です\n"
+
+#, c-format
+msgid "error initializing reader object: %s\n"
+msgstr "リーダ・オブジェクトの初期化エラー: %s\n"
+
+#, c-format
+msgid "URL '%s' redirected to '%s' (%u)\n"
+msgstr "URL'%s' は '%s' (%u) へリダイレクトされました\n"
+
+msgid "too many redirections\n"
+msgstr "リダイレクトが多すぎます\n"
+
+#, c-format
+msgid "error retrieving '%s': %s\n"
+msgstr "'%s'を取得する際のエラー: %s\n"
+
+#, c-format
+msgid "error retrieving '%s': http status %u\n"
+msgstr "'%s'の取得エラー: httpステイタス %u\n"
+
+#, c-format
+msgid "certificate search not possible due to disabled %s\n"
+msgstr "禁止されているため、証明書の探索ができません: %s\n"
+
+msgid "use OCSP instead of CRLs"
+msgstr "OCSPをCRLの代わりに使います"
+
+msgid "check whether a dirmngr is running"
+msgstr "dirmngrが動いているかどうか確認します"
+
+msgid "add a certificate to the cache"
+msgstr "証明書をキャッシュに追加します"
+
+msgid "validate a certificate"
+msgstr "証明書を検証する"
+
+msgid "lookup a certificate"
+msgstr "証明書を探索する"
+
+msgid "lookup only locally stored certificates"
+msgstr "ローカルに保持された証明書だけを探索します"
+
+msgid "expect an URL for --lookup"
+msgstr "--lookupにはURLがきます"
+
+msgid "load a CRL into the dirmngr"
+msgstr "dirmngrにCRLをロードする"
+
+msgid "special mode for use by Squid"
+msgstr "Squidのための特別なモード"
+
+msgid "expect certificates in PEM format"
+msgstr "証明書はPEM形式を期待します"
+
+msgid "force the use of the default OCSP responder"
+msgstr "デフォルトOCSP応答の使用を強制します"
+
+msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n"
+msgstr ""
+"使い方: dirmngr-client [オプション] [証明書ファイル|パターン] (ヘルプは -h)\n"
+
+msgid ""
+"Syntax: dirmngr-client [options] [certfile|pattern]\n"
+"Test an X.509 certificate against a CRL or do an OCSP check\n"
+"The process returns 0 if the certificate is valid, 1 if it is\n"
+"not valid and other error codes for general failures\n"
+msgstr ""
+"形式: dirmngr-client [オプション] [証明書ファイル|パターン]\n"
+"X.509証明書をCRLに対してテストする、あるいはOCSPチェックを行う\n"
+"プロセスは証明書が有効の場合、0を返し、有効でない場合、1 を返す。\n"
+"一般の失敗の場合、そのほかのエラーコードを返す\n"
+
+#, c-format
+msgid "error reading certificate from stdin: %s\n"
+msgstr "stdinから証明書読み込みエラー: %s\n"
+
+#, c-format
+msgid "error reading certificate from '%s': %s\n"
+msgstr "'%s'から証明書の読み込みエラー: %s\n"
+
+msgid "certificate too large to make any sense\n"
+msgstr "証明書は意味のあるものとしては大きすぎます\n"
+
+#, c-format
+msgid "lookup failed: %s\n"
+msgstr "検索に失敗しました: %s\n"
+
+#, c-format
+msgid "loading CRL '%s' failed: %s\n"
+msgstr "CRL'%s'の読み込みが失敗しました: %s\n"
+
+msgid "a dirmngr daemon is up and running\n"
+msgstr "dirmngr daemonが起動され動いています\n"
+
+#, c-format
+msgid "validation of certificate failed: %s\n"
+msgstr "証明書の検証に失敗しました: %s\n"
+
+msgid "certificate is valid\n"
+msgstr "証明書は正しいです\n"
+
+msgid "certificate has been revoked\n"
+msgstr "証明書は失効済みです\n"
+
+#, c-format
+msgid "certificate check failed: %s\n"
+msgstr "証明書の検査に失敗しました: %s\n"
+
+#, c-format
+msgid "got status: '%s'\n"
+msgstr "ステイタス'%s'を取得しました\n"
+
+#, c-format
+msgid "error writing base64 encoding: %s\n"
+msgstr "base64エンコーディングの書き込みエラー: %s\n"
+
+#, c-format
+msgid "failed to allocate assuan context: %s\n"
+msgstr "assuanコンテクストの確保に失敗しました: %s\n"
+
+msgid "apparently no running dirmngr\n"
+msgstr "あきらかにdirmngrが動いていません\n"
+
+msgid "no running dirmngr - starting one\n"
+msgstr "dirmngrが動いていません - 開始します\n"
+
+#, c-format
+msgid "malformed %s environment variable\n"
+msgstr "環境変数%sが破壊されています\n"
+
+#, c-format
+msgid "dirmngr protocol version %d is not supported\n"
+msgstr "dirmngrプロトコル・バージョン%dはサポートされていません\n"
+
+msgid "can't connect to the dirmngr - trying fall back\n"
+msgstr "dirmngrに接続できません - フォールバックを試します\n"
+
+#, c-format
+msgid "can't connect to the dirmngr: %s\n"
+msgstr "dirmngrへ接続できません: %s\n"
+
+#, c-format
+msgid "unsupported inquiry '%s'\n"
+msgstr "サポートされていない問い合わせ: '%s'\n"
+
+msgid "absolute file name expected\n"
+msgstr "絶対ファイル名がきます\n"
+
+#, c-format
+msgid "looking up '%s'\n"
+msgstr "'%s'を検索します\n"
+
+msgid "run as windows service (background)"
+msgstr "ウィンドウズ・サービスとして実行 (バックグラウンド)"
+
+msgid "list the contents of the CRL cache"
+msgstr "CRLキャッシュの内容をリストします"
+
+msgid "|FILE|load CRL from FILE into cache"
+msgstr "|FILE|FILEからCRLをキャッシュにロードする"
+
+msgid "|URL|fetch a CRL from URL"
+msgstr "|URL|URLからCRLを取得します"
+
+msgid "shutdown the dirmngr"
+msgstr "dirmngrをシャットダウンする"
+
+msgid "flush the cache"
+msgstr "キャッシュをフラッシュします"
+
+msgid "|FILE|write server mode logs to FILE"
+msgstr "|FILE|FILEにサーバ・モードのログを書き出す"
+
+msgid "run without asking a user"
+msgstr "ユーザに問い合わせせずに実行"
+
+msgid "force loading of outdated CRLs"
+msgstr "期日の過ぎたCRLのロードを強制する"
+
+msgid "allow sending OCSP requests"
+msgstr "OCSP要求の送信を認める"
+
+msgid "inhibit the use of HTTP"
+msgstr "HTTPの使用を禁止する"
+
+msgid "inhibit the use of LDAP"
+msgstr "LDAPの使用を禁止する"
+
+msgid "ignore HTTP CRL distribution points"
+msgstr "HTTP CRL配布ポイントを無視する"
+
+msgid "ignore LDAP CRL distribution points"
+msgstr "LDAP CRL配布ポイントを無視する"
+
+msgid "ignore certificate contained OCSP service URLs"
+msgstr "OCSPサービスURLに入っている証明書を無視する"
+
+msgid "|URL|redirect all HTTP requests to URL"
+msgstr "|URL|すべてのHTTPリクエストをURLにリダイレクトする"
+
+msgid "|HOST|use HOST for LDAP queries"
+msgstr "|HOST|LDAPの問い合わせにHOSTを使う"
+
+msgid "do not use fallback hosts with --ldap-proxy"
+msgstr "--ldap-proxy にフォールバック・ホストを使わない"
+
+msgid "|FILE|read LDAP server list from FILE"
+msgstr "|FILE|FILEからLDAPサーバリストを読み込みます"
+
+msgid "add new servers discovered in CRL distribution points to serverlist"
+msgstr "CRL配布ポイントに発見された新しいサーバを serverlist に追加する"
+
+msgid "|N|set LDAP timeout to N seconds"
+msgstr "|N|LDAPのタイムアウトをN秒とする"
+
+msgid "|URL|use OCSP responder at URL"
+msgstr "|URL|OCSP応答としてURLを使用"
+
+msgid "|FPR|OCSP response signed by FPR"
+msgstr "|FPR|FPRで署名されたOCSPレスポンス"
+
+msgid "|N|do not return more than N items in one query"
+msgstr "|N|一つのクエリでNを越えるのアイテムを返さない"
+
+msgid "|FILE|use the CA certificates in FILE for HKP over TLS"
+msgstr "|FILE|FILEにあるCA証明書をTLSでのHKPに使う"
+
+msgid ""
+"@\n"
+"(See the \"info\" manual for a complete listing of all commands and "
+"options)\n"
+msgstr ""
+"@\n"
+"(コマンドとオプション全部の一覧は、\"info\" マニュアルをご覧ください)\n"
+
+msgid "Usage: @DIRMNGR@ [options] (-h for help)"
+msgstr "使い方: @DIRMNGR@ [オプション] (ヘルプは -h)"
+
+#, fuzzy
+#| msgid ""
+#| "Syntax: @DIRMNGR@ [options] [command [args]]\n"
+#| "LDAP and OCSP access for @GNUPG@\n"
+msgid ""
+"Syntax: @DIRMNGR@ [options] [command [args]]\n"
+"Keyserver, CRL, and OCSP access for @GNUPG@\n"
+msgstr ""
+"形式: @DIRMNGR@ [オプション] [コマンド [引数]]\n"
+"@GnuPG@のLDAPとOCSPアクセス\n"
+
+#, c-format
+msgid "valid debug levels are: %s\n"
+msgstr "有効なdebugレベルは: %s\n"
+
+#, c-format
+msgid "usage: %s [options] "
+msgstr "使い方: %s [オプション] "
+
+msgid "colons are not allowed in the socket name\n"
+msgstr "コロンはソケット名に許されません\n"
+
+#, c-format
+msgid "fetching CRL from '%s' failed: %s\n"
+msgstr "'%s'からCRLの取得の失敗: %s\n"
+
+#, c-format
+msgid "processing CRL from '%s' failed: %s\n"
+msgstr "'%s'からCRLの処理に失敗: %s\n"
+
+#, c-format
+msgid "%s:%u: line too long - skipped\n"
+msgstr "%s:%u: 行が長すぎます - スキップされました\n"
+
+#, c-format
+msgid "%s:%u: invalid fingerprint detected\n"
+msgstr "%s:%u: 無効なフィンガープリントが検出されました\n"
+
+#, c-format
+msgid "%s:%u: read error: %s\n"
+msgstr "%s:%u: 読み込みエラー: %s\n"
+
+#, c-format
+msgid "%s:%u: garbage at end of line ignored\n"
+msgstr "%s:%u: 行末のゴミを無視\n"
+
+msgid "SIGHUP received - re-reading configuration and flushing caches\n"
+msgstr "SIGHUPを受け取り - 設定を読み直し、キャッシュをフラッシュ\n"
+
+msgid "SIGUSR2 received - no action defined\n"
+msgstr "SIGUSR2を受け取り - 動作は定義されない\n"
+
+msgid "SIGTERM received - shutting down ...\n"
+msgstr "SIGTERMを受け取り - シャットダウン...\n"
+
+#, c-format
+msgid "SIGTERM received - still %d active connections\n"
+msgstr "SIGTERMを受け取り - %d本のアクティブな接続がまだあります\n"
+
+msgid "shutdown forced\n"
+msgstr "強制的にシャットダウンする\n"
+
+msgid "SIGINT received - immediate shutdown\n"
+msgstr "SIGINTを受け取り - すぐにシャットダウン\n"
+
+#, c-format
+msgid "signal %d received - no action defined\n"
+msgstr "シグナル%dを受け取り - アクションは定義されない\n"
+
+msgid "return all values in a record oriented format"
+msgstr "レコード形式ですべての値を返す"
+
+msgid "|NAME|ignore host part and connect through NAME"
+msgstr "|NAME|host部分を無視してNAMEをとおして接続する"
+
+msgid "|NAME|connect to host NAME"
+msgstr "|NAME|ホストNAMEに接続する"
+
+msgid "|N|connect to port N"
+msgstr "|N|ポートNに接続します"
+
+msgid "|NAME|use user NAME for authentication"
+msgstr "|NAME|ユーザNAMEを認証に使う"
+
+msgid "|PASS|use password PASS for authentication"
+msgstr "|PASS|パスワードPASSを認証に使う"
+
+msgid "take password from $DIRMNGR_LDAP_PASS"
+msgstr "パスワードを$DIRMNGR_LDAP_PASSから取ってくる"
+
+msgid "|STRING|query DN STRING"
+msgstr "|STRING|DN STRINGをクエリする"
+
+msgid "|STRING|use STRING as filter expression"
+msgstr "|STRING|STRINGをフィルタ式に使う"
+
+msgid "|STRING|return the attribute STRING"
+msgstr "|STRING|STRINGの属性を返す"
+
+msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n"
+msgstr "使い方: dirmngr_ldap [オプション] [URL] (ヘルプは -h)\n"
+
+msgid ""
+"Syntax: dirmngr_ldap [options] [URL]\n"
+"Internal LDAP helper for Dirmngr\n"
+"Interface and options may change without notice\n"
+msgstr ""
+"形式: dirmngr_ldap [オプション] [URL]\n"
+"Dirmngrの内部LDAPヘルパー\n"
+"インタフェースとオプションは事前の通知なく変更されることがあります\n"
+
+#, c-format
+msgid "invalid port number %d\n"
+msgstr "無効なポート番号 %d\n"
+
+#, c-format
+msgid "scanning result for attribute '%s'\n"
+msgstr "属性'%s'のスキャン結果\n"
+
+#, c-format
+msgid "error writing to stdout: %s\n"
+msgstr "stdoutへの書き込みエラー: %s\n"
+
+#, c-format
+msgid "          available attribute '%s'\n"
+msgstr "          利用可能な属性'%s'\n"
+
+#, c-format
+msgid "attribute '%s' not found\n"
+msgstr "属性'%s'が見つかりません\n"
+
+#, c-format
+msgid "found attribute '%s'\n"
+msgstr "属性'%s'が見つかりました\n"
+
+#, c-format
+msgid "processing url '%s'\n"
+msgstr "url'%s'を処理\n"
+
+#, c-format
+msgid "          user '%s'\n"
+msgstr "        ユーザ '%s'\n"
+
+#, c-format
+msgid "          pass '%s'\n"
+msgstr "                パスワード '%s'\n"
+
+#, c-format
+msgid "          host '%s'\n"
+msgstr "        ホスト '%s'\n"
+
+#, c-format
+msgid "          port %d\n"
+msgstr "        ポート %d\n"
+
+#, c-format
+msgid "            DN '%s'\n"
+msgstr "                DN '%s'\n"
+
+#, c-format
+msgid "        filter '%s'\n"
+msgstr "        フィルタ '%s'\n"
+
+#, c-format
+msgid "          attr '%s'\n"
+msgstr "         属性 '%s'\n"
+
+#, c-format
+msgid "no host name in '%s'\n"
+msgstr "'%s'にホスト名がありません\n"
+
+#, c-format
+msgid "no attribute given for query '%s'\n"
+msgstr "クエリ '%s' に属性が指定されていません\n"
+
+msgid "WARNING: using first attribute only\n"
+msgstr "*警告*: 最初の属性だけを使っています\n"
+
+#, c-format
+msgid "LDAP init to '%s:%d' failed: %s\n"
+msgstr "'%s:%d'のLDAP初期化に失敗: %s\n"
+
+#, c-format
+msgid "binding to '%s:%d' failed: %s\n"
+msgstr "'%s:%d'のバインドに失敗: %s\n"
+
+#, c-format
+msgid "searching '%s' failed: %s\n"
+msgstr "'%s'の探索に失敗しました: %s\n"
+
+#, c-format
+msgid "'%s' is not an LDAP URL\n"
+msgstr "'%s'は、LDAP URLではありません\n"
+
+#, c-format
+msgid "'%s' is an invalid LDAP URL\n"
+msgstr "'%s' は無効なLDAP URLです\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "メモリの確保のエラー: %s\n"
+
+#, c-format
+msgid "error printing log line: %s\n"
+msgstr "log出力エラー: %s\n"
+
+#, c-format
+msgid "error reading log from ldap wrapper %d: %s\n"
+msgstr "ldap wrapper %dからのログの読み込みエラー: %s\n"
+
+#, c-format
+msgid "npth_select failed: %s - waiting 1s\n"
+msgstr "npth_selectに失敗しました: %s - 一秒待ちます\n"
+
+#, c-format
+msgid "ldap wrapper %d ready"
+msgstr "ldap wrapper %d が準備完了"
+
+#, c-format
+msgid "ldap wrapper %d ready: timeout\n"
+msgstr "ldap wrapper %d が準備完了: タイムアウト\n"
+
+#, c-format
+msgid "ldap wrapper %d ready: exitcode=%d\n"
+msgstr "ldap wrapper %d が準備完了: exitcode=%d\n"
+
+#, c-format
+msgid "waiting for ldap wrapper %d failed: %s\n"
+msgstr "ldap wrapper %dの待ちが失敗: %s\n"
+
+#, c-format
+msgid "ldap wrapper %d stalled - killing\n"
+msgstr "ldap wrapper %d が止まりました - killしています\n"
+
+#, c-format
+msgid "error spawning ldap wrapper reaper thread: %s\n"
+msgstr "ldap wrapperのスレッドの起動でエラー: %s\n"
+
+#, c-format
+msgid "reading from ldap wrapper %d failed: %s\n"
+msgstr "ldap wrapper %d からの読み込みに失敗しました: %s\n"
+
+#, c-format
+msgid "invalid char 0x%02x in host name - not added\n"
+msgstr "ホスト名に無効な文字 0x%02x - 加えません\n"
+
+#, c-format
+msgid "adding '%s:%d' to the ldap server list\n"
+msgstr "'%s:%d'をLDAPサーバ・リストに追加\n"
+
+#, c-format
+msgid "malloc failed: %s\n"
+msgstr "mallocが失敗しました: %s\n"
+
+#, c-format
+msgid "start_cert_fetch: invalid pattern '%s'\n"
+msgstr "start_cert_fetch: 無効なパターン '%s'\n"
+
+msgid "ldap_search hit the size limit of the server\n"
+msgstr "ldap_search がサーバのサイズ限界を越えました\n"
+
+msgid "invalid canonical S-expression found\n"
+msgstr "無効な正規S式が見つかりました\n"
+
+#, c-format
+msgid "gcry_md_open failed: %s\n"
+msgstr "gcry_md_openに失敗しました: %s\n"
+
+#, c-format
+msgid "oops: ksba_cert_hash failed: %s\n"
+msgstr "おっと: ksba_cert_hashが失敗しました: %s\n"
+
+msgid "bad URL encoding detected\n"
+msgstr "不正なURLエンコーディングが検出されました\n"
+
+#, c-format
+msgid "error reading from responder: %s\n"
+msgstr "応答からの読み込みエラー: %s\n"
+
+#, c-format
+msgid "response from server too large; limit is %d bytes\n"
+msgstr "サーバからの応答がが長すぎます (上限%dバイト)。\n"
+
+msgid "OCSP request not possible due to disabled HTTP\n"
+msgstr "HTTPが停止されているためOCSPリクエストが不可能です\n"
+
+#, c-format
+msgid "error setting OCSP target: %s\n"
+msgstr "OCSPターゲットの設定エラー: %s\n"
+
+#, c-format
+msgid "error building OCSP request: %s\n"
+msgstr "OCSP要求のビルド・エラー: %s\n"
+
+#, c-format
+msgid "error connecting to '%s': %s\n"
+msgstr "'%s'の接続エラー: %s\n"
+
+#, c-format
+msgid "error reading HTTP response for '%s': %s\n"
+msgstr "'%s'のHTTP応答の読み込みエラー: %s\n"
+
+#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "'%s'へアクセスのエラー: httpステイタス %u\n"
+
+#, c-format
+msgid "error parsing OCSP response for '%s': %s\n"
+msgstr "'%s'に対するOCSP応答解析エラー: %s\n"
+
+#, c-format
+msgid "OCSP responder at '%s' status: %s\n"
+msgstr "OSCP応答が '%s' でステイタス: %s\n"
+
+#, c-format
+msgid "hashing the OCSP response for '%s' failed: %s\n"
+msgstr "'%s'に対するOCSP応答のハッシングに失敗しました: %s\n"
+
+msgid "not signed by a default OCSP signer's certificate"
+msgstr "デフォルトOCSP署名者の証明で署名されていません"
+
+msgid "only SHA-1 is supported for OCSP responses\n"
+msgstr "SHA-1だけがOCSPレスポンスとしてサポートされています\n"
+
+#, c-format
+msgid "allocating list item failed: %s\n"
+msgstr "リスト項目の確保に失敗しました: %s\n"
+
+#, c-format
+msgid "error getting responder ID: %s\n"
+msgstr "応答IDの取得エラー: %s\n"
+
+msgid "no suitable certificate found to verify the OCSP response\n"
+msgstr "OCSP応答を検証する適切な証明書がありませんでした\n"
+
+#, c-format
+msgid "issuer certificate not found: %s\n"
+msgstr "発行者証明書が見つかりません: %s\n"
+
+msgid "caller did not return the target certificate\n"
+msgstr "呼出側が対象の証明書を返しませんでした\n"
+
+msgid "caller did not return the issuing certificate\n"
+msgstr "呼出側が発行される証明書を返しませんでした\n"
+
+#, c-format
+msgid "failed to allocate OCSP context: %s\n"
+msgstr "OCSPコンテクストの確保に失敗しました: %s\n"
+
+#, c-format
+msgid "can't get authorityInfoAccess: %s\n"
+msgstr "authorityInfoAccessを取得できません: %s\n"
+
+msgid "no default OCSP responder defined\n"
+msgstr "デフォルトOCSPレスポンダが定義されていません\n"
+
+msgid "no default OCSP signer defined\n"
+msgstr "デフォルトのOCSP署名者が定義されていません\n"
+
+#, c-format
+msgid "using default OCSP responder '%s'\n"
+msgstr "デフォルトOCSP応答'%s'を使います\n"
+
+#, c-format
+msgid "using OCSP responder '%s'\n"
+msgstr "OCSP応答'%s'を使います\n"
+
+#, c-format
+msgid "failed to establish a hashing context for OCSP: %s\n"
+msgstr "OCSPのハッシュ・コンテクストを確立するのに失敗しました: %s\n"
+
+#, c-format
+msgid "error getting OCSP status for target certificate: %s\n"
+msgstr "対象の証明書のOCSPステイタスの取得エラー: %s\n"
+
+#, c-format
+msgid "certificate status is: %s  (this=%s  next=%s)\n"
+msgstr "証明書ステイタスは: %s (これ=%s 次=%s)\n"
+
+msgid "good"
+msgstr "良好"
+
+#, c-format
+msgid "certificate has been revoked at: %s due to: %s\n"
+msgstr "証明書は失効済みです: %s (理由: %s)\n"
+
+msgid "OCSP responder returned a status in the future\n"
+msgstr "OSCPレスポンダは未来のステイタスを返しました\n"
+
+msgid "OCSP responder returned a non-current status\n"
+msgstr "OSCPレスポンダは現在でないステイタスを返しました\n"
+
+msgid "OCSP responder returned an too old status\n"
+msgstr "OSCPレスポンダは古すぎるステイタスを返しました\n"
+
+#, c-format
+msgid "assuan_inquire(%s) failed: %s\n"
+msgstr "assuan_inquire(%s)が失敗しました: %s\n"
+
+msgid "ldapserver missing"
+msgstr "ldapserverがありません"
+
+msgid "serialno missing in cert ID"
+msgstr "serialnoがcert IDにありません"
+
+#, c-format
+msgid "assuan_inquire failed: %s\n"
+msgstr "assuan_inquireに失敗しました: %s\n"
+
+#, c-format
+msgid "fetch_cert_by_url failed: %s\n"
+msgstr "fetch_cert_by_url が失敗しました: %s\n"
+
+#, c-format
+msgid "error sending data: %s\n"
+msgstr "データ送信エラー: %s\n"
+
+#, c-format
+msgid "start_cert_fetch failed: %s\n"
+msgstr "start_cert_fetch が失敗しました: %s\n"
+
+#, c-format
+msgid "fetch_next_cert failed: %s\n"
+msgstr "fetch_next_cert が失敗しました: %s\n"
+
+#, c-format
+msgid "max_replies %d exceeded\n"
+msgstr "max_replies %d を越えました\n"
+
+#, c-format
+msgid "can't allocate control structure: %s\n"
+msgstr "制御構造を確保できません: %s\n"
+
+#, c-format
+msgid "failed to initialize the server: %s\n"
+msgstr "サーバの初期化に失敗しました: %s\n"
+
+#, c-format
+msgid "failed to the register commands with Assuan: %s\n"
+msgstr "Assuanで登録コマンドに失敗しました: %s\n"
+
+#, c-format
+msgid "Assuan accept problem: %s\n"
+msgstr "Assuan accept の問題: %s\n"
+
+#, c-format
+msgid "Assuan processing failed: %s\n"
+msgstr "Assuanの処理が失敗しました: %s\n"
+
+msgid "accepting root CA not marked as a CA"
+msgstr "CAとしてマークされていないルートCAを受領します"
+
+msgid "CRL checking too deeply nested\n"
+msgstr "CRL検査のネストが深すぎです\n"
+
+msgid "not checking CRL for"
+msgstr "CRL を確認しません"
+
+msgid "checking CRL for"
+msgstr "CRLの検査をしています"
+
+msgid "running in compatibility mode - certificate chain not checked!\n"
+msgstr "コンパチ・モードで実行します - 証明書チェインは確認しません!\n"
+
+msgid "selfsigned certificate has a BAD signature"
+msgstr "自己署名証明書に*不正な*署名があります"
+
+#, c-format
+msgid "checking trustworthiness of root certificate failed: %s\n"
+msgstr "ルート証明書の信用検査に失敗しました: %s\n"
+
+msgid "certificate chain is good\n"
+msgstr "証明書チェインは正しいです\n"
+
+msgid "DSA requires the use of a 160 bit hash algorithm\n"
+msgstr "DSAは160ビットののハッシュアルゴリズムの使用を必要とします\n"
+
+msgid "certificate should not have been used for CRL signing\n"
+msgstr "証明書はCRL署名のために使われるべきではありませんでした\n"
+
+msgid "quiet"
+msgstr "おとなしく"
+
+msgid "print data out hex encoded"
+msgstr "16進でエンコードしてデータ出力を表示する"
+
+msgid "decode received data lines"
+msgstr "受信したデータ行をデコードする"
+
+msgid "connect to the dirmngr"
+msgstr "dirmngrへ接続"
+
+msgid "|NAME|connect to Assuan socket NAME"
+msgstr "|NAME|Assuanのソケット名NAMEに接続する"
+
+msgid "|ADDR|connect to Assuan server at ADDR"
+msgstr "|ADDR|ADDRのAssuanサーバに接続する"
+
+msgid "run the Assuan server given on the command line"
+msgstr "コマンド・ラインで与えられたAssuanサーバを実行する"
+
+msgid "do not use extended connect mode"
+msgstr "拡張接続モードを使わない"
+
+msgid "|FILE|run commands from FILE on startup"
+msgstr "|FILE|起動時にFILEからコマンドを実行する"
+
+msgid "run /subst on startup"
+msgstr "起動時に /subst を実行する"
+
+msgid "Usage: @GPG@-connect-agent [options] (-h for help)"
+msgstr "使い方: @GPG@-connect-agent [オプション] (ヘルプは -h)"
+
+msgid ""
+"Syntax: @GPG@-connect-agent [options]\n"
+"Connect to a running agent and send commands\n"
+msgstr ""
+"形式: @GPG@-connect-agent [オプション]\n"
+"実行中のagentに接続し、コマンドを送る\n"
+
+#, c-format
+msgid "option \"%s\" requires a program and optional arguments\n"
+msgstr "オプション\"%s\"はプログラムとオプショナルの引数を要します\n"
+
+#, c-format
+msgid "option \"%s\" ignored due to \"%s\"\n"
+msgstr "オプション\"%s\"は\"%s\"のため無視されました\n"
+
+#, c-format
+msgid "receiving line failed: %s\n"
+msgstr "行の受信に失敗しました: %s\n"
+
+msgid "line too long - skipped\n"
+msgstr "行が長すぎます - スキップされました\n"
+
+msgid "line shortened due to embedded Nul character\n"
+msgstr "組込みのNulキャラクタのため行は短くされました\n"
+
+#, c-format
+msgid "unknown command '%s'\n"
+msgstr "不明のコマンド'%s'\n"
+
+#, c-format
+msgid "sending line failed: %s\n"
+msgstr "行の送信に失敗しました: %s\n"
+
+#, c-format
+msgid "error sending standard options: %s\n"
+msgstr "標準オプションを送信エラー: %s\n"
+
+msgid "Options controlling the diagnostic output"
+msgstr "診断出力を制御するオプション"
+
+msgid "Options controlling the configuration"
+msgstr "コンフィグレーションを制御するオプション"
+
+msgid "Options useful for debugging"
+msgstr "デバッグのために有用なオプション"
+
+msgid "Options controlling the security"
+msgstr "セキュリティを制御するオプション"
 
 msgid "|N|expire SSH keys after N seconds"
 msgstr "|N|N秒後にSSH鍵を無効とする"
@@ -6349,10 +7477,10 @@ msgid "|N|set maximum SSH key lifetime to N seconds"
 msgstr "|N|最大SSH鍵存続時間をN秒とする"
 
 msgid "Options enforcing a passphrase policy"
-msgstr "ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\83»ã\83\9dã\83ªã\82·ã\83¼ã\81®å¼·å\88¶ã\82ªã\83\97ã\82·ã\83§ã\83³"
+msgstr "パスワード・ポリシの強制オプション"
 
 msgid "do not allow to bypass the passphrase policy"
-msgstr "ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\83»ã\83\9dã\83ªã\82·ã\83¼ã\82\92è¿\82å\9b\9eã\81\99ã\82\8bã\81\93ã\81¨ã\82\92èª\8dã\82\81ã\81ªã\81\84"
+msgstr "パスワード・ポリシを迂回することを認めない"
 
 msgid "|N|set minimal required length for new passphrases to N"
 msgstr "|N|新しいパスフレーズの必要とする最低長をNとする"
@@ -6421,6 +7549,27 @@ msgstr "LDAPサーバ・リスト"
 msgid "Configuration for OCSP"
 msgstr "OCSPのコンフィグレーション"
 
+msgid "GPG for OpenPGP"
+msgstr "OpenPGPのためのGPG"
+
+msgid "GPG Agent"
+msgstr "GPG Agent"
+
+msgid "Smartcard Daemon"
+msgstr "スマートカード・デーモン"
+
+msgid "GPG for S/MIME"
+msgstr "S/MIME のためのGPG"
+
+msgid "Directory Manager"
+msgstr "ディレクトリ・マネージャ"
+
+msgid "PIN and Passphrase Entry"
+msgstr "PINとパスフレーズの入力"
+
+msgid "Component not suitable for launching"
+msgstr "コンポーネントが起動するために適切ではありません"
+
 #, c-format
 msgid "External verification of component %s failed"
 msgstr "コンポーネント%sの外部の検証が失敗しました"
@@ -6446,8 +7595,8 @@ msgstr "|COMPONENT|オプションをチェックする"
 msgid "apply global default values"
 msgstr "グローバル・デフォルト値を適用する"
 
-msgid "get the configuration directories for gpgconf"
-msgstr "gpgconfのためにコンフィグレーション・ディレクトリを取得する"
+msgid "get the configuration directories for @GPGCONF@"
+msgstr "@GPGCONF@のためにコンフィグレーション・ディレクトリを取得する"
 
 msgid "list global configuration file"
 msgstr "グローバルのコンフィグレーション・ファイルをリストする"
@@ -6455,24 +7604,30 @@ msgstr "グローバルのコンフィグレーション・ファイルをリス
 msgid "check global configuration file"
 msgstr "グローバルのコンフィグレーション・ファイルをチェックする"
 
+msgid "reload all or a given component"
+msgstr "すべて、あるいは指定されたコンポーネントをリロードする"
+
+msgid "launch a given component"
+msgstr "指定されたコンポーネントを起動する"
+
+msgid "kill a given component"
+msgstr "指定されたコンポーネントをkillする"
+
 msgid "use as output file"
 msgstr "出力ファイルとして使用"
 
 msgid "activate changes at runtime, if possible"
 msgstr "可能な場合、実行時に変更を有効とする"
 
-msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "使い方: gpgconf [オプション] (ヘルプは -h)"
+msgid "Usage: @GPGCONF@ [options] (-h for help)"
+msgstr "使い方: @GPGCONF@ [オプション] (ヘルプは -h)"
 
 msgid ""
-"Syntax: gpgconf [options]\n"
-"Manage configuration options for tools of the GnuPG system\n"
+"Syntax: @GPGCONF@ [options]\n"
+"Manage configuration options for tools of the @GNUPG@ system\n"
 msgstr ""
-"形式: gpgconf [オプション]\n"
-"GnuPGシステムのツールに対しコンフィグレーション・オプションを管理する\n"
-
-msgid "usage: gpgconf [options] "
-msgstr "使い方: gpgconf [オプション] "
+"形式: @GPGCONF@ [オプション]\n"
+"@GNUPG@システムのツールに対しコンフィグレーション・オプションを管理する\n"
 
 msgid "Need one component argument"
 msgstr "一つコンポーネント引数が必要です"
@@ -6531,8 +7686,8 @@ msgid "%s on %s failed with status %i\n"
 msgstr "%s (%s の)がステイタス%iで失敗しました\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
-msgstr "一時ディレクトリ「%s」が作成できません: %s\n"
+msgid "can't create temporary directory '%s': %s\n"
+msgstr "一時ディレクトリ'%s'が作成できません: %s\n"
 
 #, c-format
 msgid "could not open %s for writing: %s\n"
@@ -6540,15 +7695,15 @@ msgstr "%sを書き込みでオープンできませんでした: %s\n"
 
 #, c-format
 msgid "error writing to %s: %s\n"
-msgstr "「%s」の書き込みエラー: %s\n"
+msgstr "'%s'の書き込みエラー: %s\n"
 
 #, c-format
 msgid "error reading from %s: %s\n"
-msgstr "「%s」の読み込みエラー: %s\n"
+msgstr "'%s'の読み込みエラー: %s\n"
 
 #, c-format
 msgid "error closing %s: %s\n"
-msgstr "「%s」でクローズのエラー: %s\n"
+msgstr "'%s'でクローズのエラー: %s\n"
 
 msgid "no --program option provided\n"
 msgstr "--programオプションが指定されていません\n"
@@ -6626,3 +7781,140 @@ msgid ""
 msgstr ""
 "形式: gpg-check-pattern [オプション] パターンファイル\n"
 "パターンファイルに対して標準入力のパスフレーズを確認する\n"
+
+#~ msgid "no secret subkey for public subkey %s - ignoring\n"
+#~ msgstr "公開副鍵%sにたいする秘密副鍵がありません - 無視\n"
+
+#, fuzzy
+#~| msgid "Note: no default option file '%s'\n"
+#~ msgid "NOTE: no default option file '%s'\n"
+#~ msgstr "*注意*: デフォルトのオプション・ファイル '%s' がありません\n"
+
+#, fuzzy
+#~| msgid "Note: %s is not for normal use!\n"
+#~ msgid "NOTE: %s is not for normal use!\n"
+#~ msgstr "*注意*: 普通%sは使いません!\n"
+
+#, fuzzy
+#~| msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n"
+#~ msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
+#~ msgstr "*注意*: v3鍵に対する副鍵の作成は、OpenPGPに適合しません\n"
+
+#~ msgid "note: non-critical certificate policy not allowed"
+#~ msgstr "注意: クリティカルでない証明書ポリシは認められません"
+
+#~ msgid "use a standard location for the socket"
+#~ msgstr "ソケットに標準の場所を使う"
+
+#~ msgid "|FILE|write environment settings also to FILE"
+#~ msgstr "|FILE|FILEに環境変数の設定も書き出す"
+
+#~ msgid "gpg-agent protocol version %d is not supported\n"
+#~ msgstr "gpg-agentプロトコル・バージョン%dはサポートされていません\n"
+
+#~ msgid "can't connect to the agent - trying fall back\n"
+#~ msgstr "agentに接続できません - フォールバックしてみます\n"
+
+#, fuzzy
+#~| msgid "can't create directory '%s': %s\n"
+#~ msgid "can't create directory `%s': %s\n"
+#~ msgstr "ディレクトリ'%s'が作成できません: %s\n"
+
+#, fuzzy
+#~| msgid "directory '%s' created\n"
+#~ msgid "directory `%s' created\n"
+#~ msgstr "ディレクトリ'%s'が作成されました\n"
+
+#, fuzzy
+#~| msgid "error creating keybox '%s': %s\n"
+#~ msgid "error creating keybox `%s': %s\n"
+#~ msgstr "keybox'%s'の作成エラー: %s\n"
+
+#, fuzzy
+#~| msgid "keybox '%s' created\n"
+#~ msgid "keybox `%s' created\n"
+#~ msgstr "keybox'%s'が作成されました\n"
+
+#, fuzzy
+#~| msgid "can't create lock for '%s'\n"
+#~ msgid "can't create lock for `%s'\n"
+#~ msgstr "'%s'のロックを作成できません\n"
+
+#~ msgid ""
+#~ "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
+#~ msgstr "--pgp2モードでは2048ビット以下のRSA鍵で暗号化しかできません\n"
+
+#~ msgid ""
+#~ "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
+#~ msgstr "暗号化しようとしている鍵は全部IDEA暗号を使えません。\n"
+
+#~ msgid ""
+#~ "you can only make detached or clear signatures while in --pgp2 mode\n"
+#~ msgstr "--pgp2モードでは分離署名かクリア・テクスト署名だけしかできません\n"
+
+#~ msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
+#~ msgstr "--pgp2モードでは署名と暗号化を同時にできません\n"
+
+#~ msgid ""
+#~ "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
+#~ msgstr ""
+#~ "--pgp2を指定したら、(パイプでなく) ファイルを指定せねばなりません。\n"
+
+#~ msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
+#~ msgstr "--pgp2モードのメッセージ暗号化では、IDEA暗号方式が必要です\n"
+
+#~ msgid ""
+#~ "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
+#~ "mode.\n"
+#~ msgstr "--pgp2モードではPGP 2.x鍵でOpenPGP署名ができません。\n"
+
+#~ msgid "This would make the key unusable in PGP 2.x.\n"
+#~ msgstr "この鍵はPGP 2.xで使用できなくなります。\n"
+
+#~ msgid ""
+#~ "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr "--pgp2モードでは、PGP 2.x形式の鍵で分離署名できるだけです\n"
+
+#~ msgid ""
+#~ "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "--pgp2モードではPGP 2.x形式の鍵でクリア・テクスト署名しかできません\n"
+
+#~ msgid "you may want to start the gpg-agent first\n"
+#~ msgstr "まず gpg-agent を開始したいでしょう\n"
+
+#~ msgid "[ revoked]"
+#~ msgstr "[  失効  ]"
+
+#~ msgid "[ expired]"
+#~ msgstr "[期限切れ]"
+
+#~ msgid "[ unknown]"
+#~ msgstr "[  不明  ]"
+
+#~ msgid "[  undef ]"
+#~ msgstr "[ 未定義 ]"
+
+#~ msgid "[marginal]"
+#~ msgstr "[まぁまぁ]"
+
+#~ msgid "[  full  ]"
+#~ msgstr "[  充分  ]"
+
+#~ msgid "[ultimate]"
+#~ msgstr "[  究極  ]"
+
+#~ msgid "undefined"
+#~ msgstr "未定義"
+
+#~ msgid "never"
+#~ msgstr "無期限"
+
+#~ msgid "marginal"
+#~ msgstr "まぁまぁ"
+
+#~ msgid "full"
+#~ msgstr "充分"
+
+#~ msgid "ultimate"
+#~ msgstr "究極"
index a25f25e..73ec6e3 100644 (file)
--- a/po/nb.po
+++ b/po/nb.po
@@ -13,7 +13,6 @@ msgstr ""
 "PO-Revision-Date: 2006-06-13 20:31+0200\n"
 "Last-Translator: Trond Endrestøl <Trond.Endrestol@fagskolen.gjovik.no>\n"
 "Language-Team: Norwegian Bokmål <i18n-nb@lister.ping.uio.no>\n"
-"Language: nb\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -22,42 +21,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "klarte ikke å lagre fingeravtrykket: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Vil du virkelig oppheve de valgte undernøklene? (j/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "ugyldig passfrase"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 #, fuzzy
@@ -83,9 +46,6 @@ msgid ""
 "this session"
 msgstr ""
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -122,11 +82,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr ""
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "kan ikke opprette «%s»: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "kan ikke åpne «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -153,33 +113,19 @@ msgstr "lesing av offentlig n
 msgid "error writing key: %s\n"
 msgstr "feil ved skriving av nøkkelknippet «%s»: %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Tast inn den nye passfrasen for denne hemmelige nøkklen.\n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "endre passfrasen"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
-"Du trenger en passfrase for å beskytte din hemmelige nøkkel.\n"
-"\n"
 
 msgid "does not match - try again"
 msgstr ""
@@ -213,7 +159,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -300,7 +246,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Du trenger en passfrase for å beskytte din hemmelige nøkkel.\n"
 "\n"
@@ -318,10 +264,10 @@ msgstr ""
 "Valg:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -376,23 +322,16 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "feil ved opprettelse av passfrase: %s\n"
 
-msgid "enable ssh support"
-msgstr ""
-
-msgid "enable putty support"
+msgid "enable ssh-agent emulation"
 msgstr ""
 
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "feil ved opprettelse av passfrase: %s\n"
-
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
 
@@ -413,7 +352,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -421,23 +360,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "MERK: ingen standard valgfil «%s»\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "valgfil «%s»: %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "leser valg fra «%s»\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr ""
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "kan ikke opprette katalogen «%s»: %s\n"
 
 msgid "name of socket too long\n"
@@ -448,7 +387,7 @@ msgid "can't create socket: %s\n"
 msgstr "kan ikke opprette «%s»: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -459,7 +398,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "feil ved henting av ny PIN: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "feil ved søking etter tillitspost i «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -467,19 +406,19 @@ msgid "listen() failed: %s\n"
 msgstr "oppdatering mislyktes: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "skriver hemmelig nøkkel til «%s»\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "katalogen «%s» ble opprettet\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "fstat(%d) mislyktes in %s: %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "kan ikke opprette katalogen «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -583,31 +522,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "feil ved opprettelse av passfrase: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "feil med «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "valgfil «%s»: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "hemmelig nøkkel er ikke tilgjengelig"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "lesefeil ved «%s»: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "feil ved lesing av «%s»: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -695,15 +634,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "feil ved henting av nåværende nøkkelinfo: %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "feil ved lesing av «%s»: %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "feil ved lesing av «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -718,7 +657,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr ""
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr ""
 
 msgid "communication problem with gpg-agent\n"
@@ -791,10 +730,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -821,22 +756,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "ugyldig sertifikat"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "ugyldig sertifikat"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "ugyldig sertifikat"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "ugyldig sertifikat"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "ugyldig sertifikat"
 
@@ -879,25 +798,9 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "ugyldig hashalgoritme «%s»\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Signatur opprettet %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "ugyldig hashalgoritme «%s»\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
-#, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "kryptert med en ukjent algoritme %d\n"
-
 msgid "Data verification succeeded"
 msgstr ""
 
@@ -906,11 +809,11 @@ msgid "Signature available"
 msgstr "Signatur opprettet %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "ingen signatur ble funnet\n"
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "ugyldig hashalgoritme «%s»\n"
 
 #, fuzzy, c-format
@@ -955,7 +858,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr ""
 
 #, fuzzy
@@ -1118,11 +1021,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "feil ved opprettelse av nøkkelknippet «%s»: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "feil ved lesing av «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "feil ved skriving av nøkkelknippet «%s»: %s\n"
 
 msgid "Login data (account name): "
@@ -1307,8 +1210,8 @@ msgstr "bekrefte PIN og vise alle data"
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Kommando> "
 
 msgid "Admin-only command\n"
 msgstr "Admin-reservert kommando\n"
@@ -1326,7 +1229,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output virker ikke for denne kommandoen\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "kan ikke åpne «%s»\n"
 
 #, c-format
@@ -1375,11 +1278,11 @@ msgid "using cipher %s\n"
 msgstr "bruker cipher %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "«%s» er allerede komprimert\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "ADVARSEL: «%s» er en tom fil\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1388,7 +1291,7 @@ msgstr ""
 "--pgp2-modus\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "leser fra «%s»\n"
 
 msgid ""
@@ -1455,11 +1358,11 @@ msgstr ""
 "denne plattformen krever midlertidige filer ved kall på eksterne programmer\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "kunne ikke utføre program «%s»: %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "kunne ikke utføre skallet «%s»: %s\n"
 
 #, c-format
@@ -1477,11 +1380,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "klarte ikke å lese reponsen fra eksternt program: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "ADVARSEL: klarte ikke å fjerne midlertidig fil (%s) «%s»: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "ADVARSEL: klarte ikke å fjerne midlertidig katalog «%s»: %s\n"
 
 msgid "export signatures that are marked as local-only"
@@ -1541,15 +1444,11 @@ msgid "[User ID not found]"
 msgstr "[Brukerid ikke funnet]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "nøkkel %s: hemmelig nøkkel uten offentlig nøkkel - hoppet over\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "feil ved lesing av «%s»: %s\n"
 
 #, fuzzy
@@ -1568,6 +1467,10 @@ msgstr "ingen hemmelig undern
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "bruker undernøkkel %s i stedet for primærnøkkel %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "nøkkel %s: hemmelig nøkkel uten offentlig nøkkel - hoppet over\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "|[fil]|lage en signatur"
@@ -1609,9 +1512,6 @@ msgstr "liste hemmelige n
 msgid "generate a new key pair"
 msgstr "generere et nytt nøkkelpar"
 
-msgid "generate a revocation certificate"
-msgstr "generere et opphevingssertifikat"
-
 msgid "remove keys from the public keyring"
 msgstr "fjerne nøkler fra det offentlige nøkkelknippet"
 
@@ -1627,9 +1527,8 @@ msgstr "signere en n
 msgid "sign or edit a key"
 msgstr "signere eller redigere en nøkkel"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "endre passfrasen"
+msgid "generate a revocation certificate"
+msgstr "generere et opphevingssertifikat"
 
 msgid "export keys"
 msgstr "eksportere nøkler"
@@ -1728,15 +1627,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Bruksmåte: gpg [valg] [filer] (-h for hjelp)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Bruksmåte: gpg [valg] [filer]\n"
 "signere, sjekke, kryptere eller dekryptere\n"
@@ -1768,56 +1662,55 @@ msgid "conflicting commands\n"
 msgstr "motstridende kommandoer\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "fant ingen «=»-tegn i gruppedefinisjonen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "ADVARSEL: utrygt eierskap på hjemmekatalogen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "ADVARSEL: utrygt eierskap på konfigurasjonsfilen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "ADVARSEL: utrygt eierskap på utvidelsen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "ADVARSEL: utrygge rettigheter på hjemmekatalogen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "ADVARSEL: utrygge rettigheter på konfigurasjonsfilen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "ADVARSEL: utrygge rettigheter på utvidelsen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
-"ADVARSEL: utrygt eierskap på katalogene på nivåene over hjemmekatalogen "
-"«%s»\n"
+"ADVARSEL: utrygt eierskap på katalogene på nivåene over hjemmekatalogen «%s»\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
 msgstr ""
-"ADVARSEL: utrygt eierskap på katalogene på nivåene over konfigurasjonsfilen "
-"«%s»\n"
+"ADVARSEL: utrygt eierskap på katalogene på nivåene over konfigurasjonsfilen «%"
+"s»\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "ADVARSEL: utrygt eierskap på katalogene på nivåene over utvidelsen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
-"ADVARSEL: utrygge rettigheter på katalogene på nivåene over hjemmekatalogen "
-"«%s»\n"
+"ADVARSEL: utrygge rettigheter på katalogene på nivåene over hjemmekatalogen «%"
+"s»\n"
 
 #, c-format
 msgid ""
@@ -1827,12 +1720,12 @@ msgstr ""
 "konfigurasjonsfilen «%s»\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "ADVARSEL: utrygge rettigheter på katalogene på nivåene over utvidelsen «%s»\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "ukjent konfigurasjonspunkt «%s»\n"
 
 msgid "display photo IDs during key listings"
@@ -1869,7 +1762,7 @@ msgid "show expiration dates during signature listings"
 msgstr ""
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "MERK: den gamle valgfila «%s» ble ignorert\n"
 
 #, c-format
@@ -1882,11 +1775,11 @@ msgstr "MERK: %s er ikke for vanlig bruk!\n"
 
 # Tenk litt på denne du, Trond.
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "«%s» er ikke en gyldig signaturutgåelse\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "«%s» er ikke et gyldig tegnsett\n"
 
 msgid "could not parse keyserver URL\n"
@@ -2052,15 +1945,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s virker ikke ennå med %s\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "du kan ikke bruke cipheralgoritmen «%s» i %s-modus\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "du kan ikke bruke digestalgoritmen «%s» i %s-modus\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "du kan ikke bruke kompresjonsalgoritmen «%s» i %s-modus\n"
 
 #, c-format
@@ -2078,7 +1971,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [filnavn]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "symmetrisk kryptering av «%s» mislyktes: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2128,10 +2021,6 @@ msgstr "--lsign-key brukerid"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key brukerid [kommandoer]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key brukerid"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "sending til nøkkelserver mislyktes: %s\n"
@@ -2161,7 +2050,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "enarmoring failed: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "ugyldig hashalgoritme «%s»\n"
 
 msgid "[filename]"
@@ -2204,7 +2093,7 @@ msgid "No help available"
 msgstr ""
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr ""
 
 msgid "import signatures that are marked as local-only"
@@ -2213,11 +2102,6 @@ msgstr ""
 msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
-#, fuzzy
-#| msgid "do not update the trustdb after import"
-msgid "do not clear the ownertrust values during import"
-msgstr "ikke oppdatér tillitsdatabasen etter import"
-
 msgid "do not update the trustdb after import"
 msgstr "ikke oppdatér tillitsdatabasen etter import"
 
@@ -2333,14 +2217,6 @@ msgstr ""
 msgid "key %s: no user ID\n"
 msgstr "nøkkel %s: ingen brukerid\n"
 
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s: %s\n"
-msgstr "hoppet over «%s»: %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "nøkkel %s: PKS-undernøkkel reparert\n"
@@ -2369,11 +2245,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "ingen skrivbart nøkkelknippe funnet: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "skriver til «%s»\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "feil ved skriving av nøkkelknippet «%s»: %s\n"
 
 #, c-format
@@ -2436,18 +2312,13 @@ msgstr "n
 msgid "key %s: \"%s\" not changed\n"
 msgstr "nøkkel %s: «%s» ikke endret\n"
 
-#, fuzzy, c-format
-#| msgid "secret key \"%s\" not found: %s\n"
-msgid "secret key %s: %s\n"
-msgstr "hemmelig nøkkel «%s» ble ikke funnet: %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "import av hemmelig nøkkel er ikke tillatt\n"
-
 #, c-format
 msgid "key %s: secret key with invalid cipher %d - skipped\n"
 msgstr "nøkkel %s: hemmelig nøkkel med ugyldig cipher %d - hoppet over\n"
 
+msgid "importing secret keys not allowed\n"
+msgstr "import av hemmelig nøkkel er ikke tillatt\n"
+
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "ingen standard hemmelig nøkkelknippe: %s\n"
@@ -2490,18 +2361,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "nøkkel %s: ugyldig selvsignatur for brukerid «%s»\n"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "nøkkel %s: ustøttet offentlig nøkkelalgoritme\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "nøkkel %s: direkte nøkkelsignatur lagt til\n"
-
-#, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "nøkkel %s: ingen undernøkkel for nøkkelbinding\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "nøkkel %s: ustøttet offentlig nøkkelalgoritme\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "nøkkel %s: ugyldig undernøkkelbinding\n"
 
@@ -2580,15 +2447,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr ""
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "feil ved opprettelse av nøkkelknippet «%s»: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "nøkkelknippet «%s» ble opprettet\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "nøkkelblokkressurs «%s»: %s\n"
 
 #, c-format
@@ -2773,7 +2640,7 @@ msgstr "   (2) Jeg har gjort en vanlig sjekk.%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Jeg har sjekket veldig nøye.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Ditt valg? (angi «?» for mer informasjon): "
 
 #, c-format
@@ -2997,7 +2864,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Tips: Velg brukeriden som skal signeres\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Ukjent signaturtype «%s»\n"
 
 #, c-format
@@ -3028,11 +2895,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "Kan ikke åpne «%s»: %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Feil ved lesing av sikkerhetskopiert nøkkel «%s»: %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3106,8 +2973,8 @@ msgstr "Notasjoner: "
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Det er ingen preferanser for en PGP 2.x-aktig brukerid.\n"
 
-#, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+#, c-format
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Denne nøkkelen ble opphevet den %s av %s med nøkkelen %s\n"
 
 #, c-format
@@ -3167,12 +3034,6 @@ msgid ""
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-msgid "You may want to change its expiration date too.\n"
-msgstr ""
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3386,7 +3247,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr ""
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "preferansen %s er duplisert\n"
 
 msgid "too many cipher preferences\n"
@@ -3399,7 +3260,7 @@ msgid "too many compression preferences\n"
 msgstr "for mange kompresjons-preferanser\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "ugyldig oppføring «%s» i preferansestreng\n"
 
 msgid "writing direct signature\n"
@@ -3640,7 +3501,7 @@ msgid "Invalid character in comment\n"
 msgstr "Ugyldig tegn i kommentar\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Du bruker tegnsettet «%s».\n"
 
 #, c-format
@@ -3728,15 +3589,15 @@ msgid "Key generation canceled.\n"
 msgstr "Nøkkelgenereringen ble avbrutt.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "skriver offentlig nøkkel til «%s»\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "skriver foreløpig hemmelig nøkkel til «%s»\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "skriver hemmelig nøkkel til «%s»\n"
 
 #, c-format
@@ -3748,11 +3609,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "ingen skrivbart hemmelig nøkkelknippe ble funnet: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "feil ved skriving av offentlig nøkkelknippe «%s»: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "feil ved skriving av hemmelig nøkkelknippe «%s»: %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3799,11 +3660,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "lagring av nøkkel på kort mislyktes: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "kan ikke opprette sikkerhetskopifil «%s»: %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr ""
 
 msgid "never     "
@@ -3844,16 +3705,11 @@ msgstr "      Fingeravstrykk for undern
 msgid "      Key fingerprint ="
 msgstr " Nøkkelfingeravtrykk ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "ADVARSEL: bruker eksperimentell digest-algoritme %s\n"
-
 msgid "      Card serial no. ="
 msgstr "      Serienummer for kort ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "omdøping fra «%s» til «%s» mislyktes: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -3871,7 +3727,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr ""
 
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "cacher nøkkelknippet «%s»\n"
 
 #, c-format
@@ -3908,7 +3764,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "ADVARSEL: nøkkelserver-valget «%s» er ikke i bruk på denne plattformen\n"
 
@@ -3971,10 +3827,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr "nøkkelserver sendte ikke VERSION\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "kommunikasjonsfeil med nøkkelserver: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -3982,11 +3834,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4000,6 +3852,10 @@ msgid "keyserver internal error\n"
 msgstr "intern feil ved nøkkelserver\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "kommunikasjonsfeil med nøkkelserver: %s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
 
@@ -4170,10 +4026,6 @@ msgid "unknown"
 msgstr "ukjent"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr ""
 
@@ -4195,7 +4047,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr ""
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr ""
 
 #, c-format
@@ -4222,11 +4074,6 @@ msgstr "ADVARSEL: bruker eksperimentell digest-algoritme %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "ADVARSEL: digestalgoritmen «%s» er avlegs\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s signatur, digestalgoritme %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr ""
 
@@ -4258,15 +4105,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr ""
 
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr ""
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr ""
-
 msgid "Uncompressed"
 msgstr ""
 
@@ -4279,15 +4117,15 @@ msgid "this message may not be usable by %s\n"
 msgstr ""
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "flertydig valg «%s»\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "ukjent valg «%s»\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Fila «%s» finnes. "
 
 msgid "Overwrite? (y/N) "
@@ -4303,17 +4141,16 @@ msgstr "Tast inn nytt filnavn"
 msgid "writing to stdout\n"
 msgstr "skriver til stdout\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "antar at signert data er i «%s»\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "ny konfigurasjonsfil «%s» ble opprettet\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "ADVARSEL: valgene i «%s» er ikke aktive under denne kjøringen\n"
 
 #, c-format
@@ -4328,10 +4165,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr ""
 
 #, c-format
-msgid "problem with the agent: %s\n"
-msgstr ""
-
-#, c-format
 msgid " (main key ID %s)"
 msgstr " (hovednøkkelid %s)"
 
@@ -4354,6 +4187,10 @@ msgid "cancelled by user\n"
 msgstr ""
 
 #, c-format
+msgid "problem with the agent: %s\n"
+msgstr ""
+
+#, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4381,7 +4218,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr ""
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "kan ikke åpne JPEG-fil «%s»: %s\n"
 
 #, c-format
@@ -4392,7 +4229,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Er du sikker på at du vil bruke den? (j/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "«%s» er ikke et JPEG-fil\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4422,16 +4259,6 @@ msgstr "grunnen for opphevelse: "
 msgid "revocation comment: "
 msgstr "kommentar til opphevelse: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4538,11 +4365,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Merk: Denne nøkkelen har blitt utkoblet.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4645,7 +4472,7 @@ msgid "no signed data\n"
 msgstr ""
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -4932,7 +4759,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "feil med «%s»: %s\n"
 
 msgid "line too long"
@@ -4948,11 +4775,11 @@ msgid "ownertrust value missing"
 msgstr "verdi for eiertillit mangler"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "feil ved søking etter tillitspost i «%s»: %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "lesefeil ved «%s»: %s\n"
 
 #, c-format
@@ -4960,14 +4787,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr ""
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "kan ikke opprette lås for «%s»\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "kan ikke låse «%s»\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr ""
 
@@ -4979,12 +4798,20 @@ msgid "trustdb transaction too large\n"
 msgstr ""
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "kan ikke aksere «%s»: %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr ""
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kan ikke aksere «%s»: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "kan ikke opprette lås for «%s»\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "kan ikke låse «%s»\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5069,7 +4896,7 @@ msgid "input line longer than %d characters\n"
 msgstr ""
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr ""
 
 #, c-format
@@ -5110,14 +4937,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5165,11 +4984,11 @@ msgid "next trustdb check due at %s\n"
 msgstr ""
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr ""
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr ""
 
 #, c-format
@@ -5237,11 +5056,6 @@ msgid "missing argument"
 msgstr "ugydig argument"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "ugyldig beskyttelse"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "Admin-reservert kommando\n"
 
@@ -5261,10 +5075,6 @@ msgstr "ugyldige listevalg\n"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "ugyldige listevalg\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5293,8 +5103,12 @@ msgstr "ugyldige listevalg\n"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "du fant en feil ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "feil ved lesing av «%s»: %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5302,15 +5116,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "signering mislyktes: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "omdøping fra «%s» til «%s» mislyktes: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "kan ikke opprette katalogen «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "feil ved skriving av nøkkelknippet «%s»: %s\n"
 
 #, c-format
@@ -5328,7 +5142,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "fant ikke offentlig nøkkel %s: %s\n"
 
 #, fuzzy, c-format
@@ -5345,11 +5159,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Bruksmåte: gpg [valg] [filer] (-h for hjelp)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Bruksmåte: gpg [valg] [filer] (-h for hjelp)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5478,9 +5291,6 @@ msgstr "||Vennligst tast inn PIN%%0A[signaturer utf
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr "PIN for CHV%d er for kort; minum lengde er %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5490,14 +5300,6 @@ msgstr "|AN|Ny Admin PIN"
 msgid "|N|New PIN"
 msgstr "|N|Ny PIN"
 
-#, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||Vennligst tast inn PIN%%0A[signaturer utført: %lu]"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Vennligst tast inn PIN%%0A[signaturer utført: %lu]"
-
 msgid "error reading application data\n"
 msgstr "feil ved lesing av applikasjonsdata\n"
 
@@ -5560,9 +5362,8 @@ msgstr "bekrefting av Admin PIN er forel
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "kan ikke aksere %s - ugyldig OpenPGP-kort?\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||Vennligst tast inn PIN%%0A[signaturer utført: %lu]"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5596,16 +5397,13 @@ msgstr ""
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "vise admin-kommandoer"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Bruksmåte: gpg [valg] [filer] (-h for hjelp)"
@@ -5615,7 +5413,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5635,7 +5433,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
@@ -5669,7 +5467,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "Kan ikke åpne «%s»: %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5698,7 +5496,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "lesing av offentlig nøkkel mislyktes: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "klarte ikke å lagre nøkkelen: %s\n"
 
 msgid "certificate has been revoked"
@@ -5887,16 +5685,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "feil ved henting av nåværende nøkkelinfo: %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -5918,11 +5716,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5930,11 +5728,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Ikke en gyldig epostadresse\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "feil ved opprettelse av nøkkelknippet «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "feil ved opprettelse av nøkkelknippet «%s»: %s\n"
 
 #, fuzzy, c-format
@@ -6002,7 +5800,7 @@ msgid "No subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6011,7 +5809,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "ugyldig hashalgoritme «%s»\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6060,7 +5858,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "hemmelig nøkkel «%s» ble ikke funnet: %s\n"
 
 #, fuzzy, c-format
@@ -6068,11 +5866,11 @@ msgid "error locking keybox: %s\n"
 msgstr "feil ved lesing av nøkkelblokk: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "nøkkel %s: ugyldig opphevingssertifikat: %s - avvist\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "preferansen %s er duplisert\n"
 
 #, fuzzy, c-format
@@ -6109,6 +5907,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "endre passfrasen"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "lage ASCII-beskyttet output"
 
@@ -6186,8 +5988,8 @@ msgstr "Bruksm
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Bruksmåte: gpg [valg] [filer]\n"
 "signere, sjekke, kryptere eller dekryptere\n"
@@ -6198,11 +6000,11 @@ msgid "usage: gpgsm [options] "
 msgstr "bruksmåte: gpg [valg] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "kan ikke opprette «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "ukjent valg «%s»\n"
 
 #, c-format
@@ -6225,11 +6027,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "kan ikke aksere «%s»: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6246,6 +6048,10 @@ msgstr "generere et opphevingssertifikat"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "klarte ikke å lagre nøkkelen: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "feil ved henting av ny PIN: %s\n"
@@ -6259,11 +6065,14 @@ msgid "error reading input: %s\n"
 msgstr "feil ved lesing av «%s»: %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "feil ved opprettelse av nøkkelknippet «%s»: %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "nøkkelknippet «%s» ble opprettet\n"
 
 #, fuzzy
@@ -6297,11 +6106,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "Feil: ugyldig formattert fingeravtrykk.\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6420,7 +6229,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "ukjent valg «%s»\n"
 
 #, fuzzy, c-format
@@ -6649,7 +6458,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "%s er ikke tillatt sammen med %s!\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "kan ikke opprette katalogen «%s»: %s\n"
 
 #, c-format
@@ -6745,17 +6554,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "feil ved lesing av «%s»: %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "klarte ikke å lagre nøkkelen: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Kommando> "
-
 #~ msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
 #~ msgstr "Vennligst rapporter feil til <gnupg-bugs@gnu.org>.\n"
 
@@ -6769,6 +6567,10 @@ msgstr ""
 #~ msgid "Repeat passphrase\n"
 #~ msgstr "Gjenta passfrase\n"
 
+#, fuzzy
+#~ msgid "||Please enter your PIN at the reader's keypad%%0A[sigs done: %lu]"
+#~ msgstr "||Vennligst tast inn PIN%%0A[signaturer utført: %lu]"
+
 #~ msgid "|A|Admin PIN"
 #~ msgstr "|A|Admin PIN"
 
@@ -7038,6 +6840,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "ugyldig pakke"
 
+#~ msgid "invalid armor"
+#~ msgstr "ugyldig beskyttelse"
+
 #~ msgid "no such user id"
 #~ msgstr "det finnes ingen slik brukerid"
 
@@ -7056,6 +6861,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "feil ved opprettelse av fil"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "ugyldig passfrase"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "uimplementert pubkey-algoritme"
 
diff --git a/po/nl.po b/po/nl.po
deleted file mode 100644 (file)
index 03fdaf1..0000000
--- a/po/nl.po
+++ /dev/null
@@ -1,7647 +0,0 @@
-# Dutch translations for package gnupg2.
-# Copyright (C) 2006 Free Software Foundation, Inc.
-# This file is distributed under the same license as the gnupg package.
-# Automatically generated, 2006.
-#
-# All this catalog "translates" are quotation characters.
-# The msgids must be ASCII and therefore cannot contain real quotation
-# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
-# and double quote (0x22). These substitutes look strange; see
-# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
-#
-# This catalog translates grave accent (0x60) and apostrophe (0x27) to
-# left single quotation mark (U+2018) and right single quotation mark (U+2019).
-# It also translates pairs of apostrophe (0x27) to
-# left single quotation mark (U+2018) and right single quotation mark (U+2019)
-# and pairs of quotation mark (0x22) to
-# left double quotation mark (U+201C) and right double quotation mark (U+201D).
-#
-# When output to an UTF-8 terminal, the quotation characters appear perfectly.
-# When output to an ISO-8859-1 terminal, the single quotation marks are
-# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
-# grave/acute accent (by libiconv), and the double quotation marks are
-# transliterated to 0x22.
-# When output to an ASCII terminal, the single quotation marks are
-# transliterated to apostrophes, and the double quotation marks are
-# transliterated to 0x22.
-# Frans Spiesschaert <Frans.Spiesschaert@yucom.be>, 2014, 2015.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: gnupg 2.0.28\n"
-"Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-12-19 12:28+0100\n"
-"Last-Translator: Frans Spiesschaert <Frans.Spiesschaert@yucom.be>\n"
-"Language-Team: Debian Dutch l10n Team <debian-l10n-dutch@lists.debian.org>\n"
-"Language: nl\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 2.91.6\n"
-
-#, c-format
-msgid "failed to acquire the pinentry lock: %s\n"
-msgstr "verwerven van de pinentry-vergrendeling is mislukt: %s\n"
-
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|_Cancel"
-msgstr "|pinentry-label|_Annuleren"
-
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_Ja"
-
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_Nee"
-
-msgid "|pinentry-label|PIN:"
-msgstr "|pinentry-label|Pincode:"
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|_Bewaren in de wachtwoordmanager"
-
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Wilt U uw wachtwoordzin echt zichtbaar maken op het scherm?"
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr "|pinentry-tt|Wachtwoordzin zichtbaar maken"
-
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "|pinentry-tt|Wachtwoordzin verbergen"
-
-#. TRANSLATORS: This string is displayed by Pinentry as the label
-#. for the quality bar.
-msgid "Quality:"
-msgstr "Kwaliteit:"
-
-#. TRANSLATORS: This string is a tooltip, shown by pinentry when
-#. hovering over the quality bar.  Please use an appropriate
-#. string to describe what this is about.  The length of the
-#. tooltip is limited to about 900 characters.  If you do not
-#. translate this entry, a default english text (see source)
-#. will be used.
-msgid "pinentry.qualitybar.tooltip"
-msgstr ""
-"De kwaliteit van de hierboven ingevoerde wachtwoordzin.\n"
-"Vraag aan uw systeembeheerder nadere toelichting bij\n"
-"de gehanteerde criteria voor het meten van de kwaliteit."
-
-msgid ""
-"Please enter your PIN, so that the secret key can be unlocked for this "
-"session"
-msgstr ""
-"Voer uw pincode in, zodat de geheime sleutel voor deze sessie ontgrendeld "
-"kan worden"
-
-msgid ""
-"Please enter your passphrase, so that the secret key can be unlocked for "
-"this session"
-msgstr ""
-"Voer uw wachtwoordzin in, zodat de geheime sleutel voor deze sessie "
-"ontgrendeld kan worden"
-
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
-#, c-format
-msgid "SETERROR %s (try %d of %d)"
-msgstr "SETERROR %s (poging %d van %d)"
-
-msgid "PIN too long"
-msgstr "Pincode is te lang"
-
-msgid "Passphrase too long"
-msgstr "Wachtwoordzin is te lang"
-
-msgid "Invalid characters in PIN"
-msgstr "Ongeldige tekens in de pincode"
-
-msgid "PIN too short"
-msgstr "Pincode is te kort"
-
-msgid "Bad PIN"
-msgstr "Slechte pincode"
-
-msgid "Bad Passphrase"
-msgstr "Slechte wachtwoordzin"
-
-msgid "Passphrase"
-msgstr "Wachtwoordzin"
-
-#, c-format
-msgid "ssh keys greater than %d bits are not supported\n"
-msgstr "ssh-sleutels groter dan %d bits worden niet ondersteund\n"
-
-#, c-format
-msgid "can't create `%s': %s\n"
-msgstr "kan `%s' niet aanmaken: %s\n"
-
-#, c-format
-msgid "can't open `%s': %s\n"
-msgstr "kan `%s' niet openen: %s\n"
-
-#, c-format
-msgid "error getting serial number of card: %s\n"
-msgstr "fout bij het opvragen van het serienummer van de kaart: %s\n"
-
-#, c-format
-msgid "detected card with S/N: %s\n"
-msgstr "kaart gevonden met serienummer: %s\n"
-
-#, c-format
-msgid "error getting default authentication keyID of card: %s\n"
-msgstr ""
-"fout bij het ophalen van de kaart van de ID van de standaard "
-"authenticatiesleutel: %s\n"
-
-#, c-format
-msgid "no suitable card key found: %s\n"
-msgstr "geen bruikbare kaartsleutel gevonden: %s\n"
-
-#, c-format
-msgid "shadowing the key failed: %s\n"
-msgstr "verheimelijken van de sleutel is mislukt: %s\n"
-
-#, c-format
-msgid "error writing key: %s\n"
-msgstr "fout bij het wegschrijven van de sleutel: %s\n"
-
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-"Een ssh-proces vroeg om het gebruik van sleutel%%0A  %s%%0A  (%s)%%0AWilt u "
-"dit toestaan?"
-
-msgid "Allow"
-msgstr "Toestaan"
-
-msgid "Deny"
-msgstr "Verbieden"
-
-#, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
-msgstr "Voer de wachtwoordzin in voor de ssh-sleutel%%0A  %F%%0A  (%c)"
-
-msgid "Please re-enter this passphrase"
-msgstr "Gelieve deze wachtwoordzin nogmaals in te voeren"
-
-#, c-format
-msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr ""
-"Gelieve een wachtwoordzin in te voeren ter beveiliging van de verkregen "
-"geheime sleutel%%0A   %s%%0A   %s%%0Abinnen de sleutelopslagplaats van de "
-"gpg-agent"
-
-msgid "does not match - try again"
-msgstr "komt niet overeen - probeer opnieuw"
-
-#, c-format
-msgid "failed to create stream from socket: %s\n"
-msgstr "een gegevensstroom vanuit de socket doen ontstaan is mislukt: %s\n"
-
-msgid "Please insert the card with serial number"
-msgstr "Plaats de kaart met serienummer"
-
-msgid "Please remove the current card and insert the one with serial number"
-msgstr "Verwijder de huidige kaart en plaats die met serienummer"
-
-msgid "Admin PIN"
-msgstr "Pincode van de beheerder"
-
-#. TRANSLATORS: A PUK is the Personal Unblocking Code
-#. used to unblock a PIN.
-msgid "PUK"
-msgstr "PUK-code"
-
-msgid "Reset Code"
-msgstr "Reset-Code"
-
-#, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
-msgstr "%s%%0A%%0AGebruik het numeriek pad van de kaartlezer als input."
-
-msgid "Repeat this Reset Code"
-msgstr "Herhaal deze Reset-Code"
-
-msgid "Repeat this PUK"
-msgstr "Herhaal deze PUK-code"
-
-msgid "Repeat this PIN"
-msgstr "Herhaal deze pincode"
-
-msgid "Reset Code not correctly repeated; try again"
-msgstr "Reset-Code was niet tweemaal hetzelfde; probeer opnieuw"
-
-msgid "PUK not correctly repeated; try again"
-msgstr "PUK-code was niet tweemaal hetzelfde; probeer opnieuw"
-
-msgid "PIN not correctly repeated; try again"
-msgstr "Pincode was niet tweemaal hetzelfde; probeer opnieuw"
-
-#, c-format
-msgid "Please enter the PIN%s%s%s to unlock the card"
-msgstr "Gelieve de pincode%s%s%s in te voeren om de kaart te ontgrendelen"
-
-#, c-format
-msgid "error creating temporary file: %s\n"
-msgstr "fout bij het maken van een tijdelijk bestand: %s\n"
-
-#, c-format
-msgid "error writing to temporary file: %s\n"
-msgstr "fout bij het schrijven naar het tijdelijk bestand: %s\n"
-
-msgid "Enter new passphrase"
-msgstr "Voer nieuwe wachtwoordzin in"
-
-msgid "Take this one anyway"
-msgstr "Die toch gebruiken"
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u character long."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u characters long."
-msgstr[0] ""
-"Waarschuwing: u heeft een onveilige wachtwoordzin ingevoerd.%%0AEen "
-"wachtwoordzin moet minstens %u teken lang zijn."
-msgstr[1] ""
-"Waarschuwing: u heeft een onveilige wachtwoordzin ingevoerd.%%0AEen "
-"wachtwoordzin moet minstens %u tekens lang zijn."
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digit or%%0Aspecial character."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digits or%%0Aspecial characters."
-msgstr[0] ""
-"Waarschuwing: u heeft een onveilige wachtwoordzin ingevoerd.%%0AEen "
-"wachtwoordzin moet minstens %u cijfer of%%0A speciaal teken bevatten."
-msgstr[1] ""
-"Waarschuwing: u heeft een onveilige wachtwoordzin ingevoerd.%%0AEen "
-"wachtwoordzin moet minstens %u cijfers of%%0A speciale tekens bevatten."
-
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
-"a known term or match%%0Acertain pattern."
-msgstr ""
-"Waarschuwing: u heeft een onveilige wachtwoordzin ingevoerd.%%0AEen "
-"wachtwoordzin mag geen bekende term zijn of overeenkomen met%%0A een bepaald "
-"patroon."
-
-#, c-format
-msgid ""
-"You have not entered a passphrase!%0AAn empty passphrase is not allowed."
-msgstr ""
-"U heeft geen wachtwoordzin ingevoerd!!%0AEen lege wachtwoordzin is niet "
-"toegestaan."
-
-#, c-format
-msgid ""
-"You have not entered a passphrase - this is in general a bad idea!%0APlease "
-"confirm that you do not want to have any protection on your key."
-msgstr ""
-"U heeft geen wachtwoordzin ingevoerd - dit is meestal en slecht idee!"
-"%0AGelieve te bevestigen dat u uw sleutel op geen enkele manier wenst te "
-"beveiligen."
-
-msgid "Yes, protection is not needed"
-msgstr "Ja, een beveiliging is onnodig"
-
-#, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
-msgstr ""
-"Gelieve de wachtwoordzin in te voeren ter%0Abeveiliging van uw nieuwe sleutel"
-
-msgid "Please enter the new passphrase"
-msgstr "Gelieve de nieuwe wachtwoordzin in te voeren"
-
-msgid ""
-"@Options:\n"
-" "
-msgstr ""
-"@Opties:\n"
-" "
-
-msgid "run in daemon mode (background)"
-msgstr "uitvoeren als achtergronddienst (daemon-modus)"
-
-msgid "run in server mode (foreground)"
-msgstr "uitvoeren in servermodus (voorgronddienst)"
-
-msgid "verbose"
-msgstr "gedetailleerd"
-
-msgid "be somewhat more quiet"
-msgstr "wees wat stiller"
-
-msgid "sh-style command output"
-msgstr "commando-uitvoer in sh-formaat"
-
-msgid "csh-style command output"
-msgstr "commando-uitvoer in csh-formaat"
-
-msgid "|FILE|read options from FILE"
-msgstr "|BESTAND|de opties inlezen vanuit BESTAND"
-
-msgid "do not detach from the console"
-msgstr "niet van de console loskoppelen"
-
-msgid "do not grab keyboard and mouse"
-msgstr "het toetsenbord en de muis niet kapen"
-
-msgid "use a log file for the server"
-msgstr "gebruik een logboekbestand voor de server"
-
-msgid "use a standard location for the socket"
-msgstr "gebruik een standaardlocatie voor de socket"
-
-msgid "|PGM|use PGM as the PIN-Entry program"
-msgstr "|PROG|PROG gebruiken als programma voor het invoeren van de pincode"
-
-msgid "|PGM|use PGM as the SCdaemon program"
-msgstr "|PROG|PROG gebruiken als het programma voor de SC-achtergronddienst"
-
-msgid "do not use the SCdaemon"
-msgstr "gebruik de SC-achtergronddienst niet"
-
-msgid "ignore requests to change the TTY"
-msgstr "verzoeken om de TTY te wijzigen negeren"
-
-msgid "ignore requests to change the X display"
-msgstr "verzoeken om het grafisch beeldscherm te wijzigen negeren"
-
-msgid "|N|expire cached PINs after N seconds"
-msgstr "|N|in de cache geladen pincodes laten verlopen na N seconden"
-
-msgid "do not use the PIN cache when signing"
-msgstr ""
-"maak bij het ondertekenen geen gebruik van het cachegeheugen met de pincodes"
-
-msgid "disallow clients to mark keys as \"trusted\""
-msgstr "clients niet toestaan om sleutels als \"betrouwbaar\" te markeren"
-
-msgid "allow presetting passphrase"
-msgstr "het vooraf instellen van de wachtwoordzin toestaan"
-
-msgid "enable ssh support"
-msgstr "ssh-ondersteuning mogelijk maken"
-
-msgid "enable putty support"
-msgstr "putty-ondersteuning mogelijk maken"
-
-msgid "disallow the use of an external password cache"
-msgstr "het gebruik van een externe wachtwoordcache niet toestaan"
-
-msgid "|FILE|write environment settings also to FILE"
-msgstr "|BESTAND|schrijf omgevingsinstellingen ook weg naar BESTAND"
-
-#. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
-#. reporting address.  This is so that we can change the
-#. reporting address without breaking the translations.
-msgid "Please report bugs to <@EMAIL@>.\n"
-msgstr "Gelieve fouten te signaleren aan <@EMAIL@>.\n"
-
-msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Gebruik: gpg-agent [opties] (-h voor hulp)"
-
-msgid ""
-"Syntax: gpg-agent [options] [command [args]]\n"
-"Secret key management for GnuPG\n"
-msgstr ""
-"Syntaxis:  gpg-agent [opties] [opdracht [argumenten]]\n"
-"Beheer van geheime sleutels van GnuPG\n"
-
-#, c-format
-msgid "invalid debug-level `%s' given\n"
-msgstr "ongeldig debug-niveau `%s' opgegeven\n"
-
-#, c-format
-msgid "%s is too old (need %s, have %s)\n"
-msgstr "%s is te oud (heb %s nodig, heb %s)\n"
-
-#, c-format
-msgid "NOTE: no default option file `%s'\n"
-msgstr "NOOT: geen bestand `%s' met standaardopties\n"
-
-#, c-format
-msgid "option file `%s': %s\n"
-msgstr "optiebestand `%s': %s\n"
-
-#, c-format
-msgid "reading options from `%s'\n"
-msgstr "inlezen van opties uit `%s'\n"
-
-#, c-format
-msgid "error creating `%s': %s\n"
-msgstr "fout bij het aanmaken van `%s': %s\n"
-
-#, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "kan map `%s' niet maken: %s\n"
-
-msgid "name of socket too long\n"
-msgstr "socketnaam is te lang\n"
-
-#, c-format
-msgid "can't create socket: %s\n"
-msgstr "kan socket niet aanmaken: %s\n"
-
-#, c-format
-msgid "socket name `%s' is too long\n"
-msgstr "socketnaam `%s' is te lang\n"
-
-msgid "a gpg-agent is already running - not starting a new one\n"
-msgstr ""
-"er is al een instantie van gpg-agent actief - er wordt geen nieuwe "
-"opgestart\n"
-
-msgid "error getting nonce for the socket\n"
-msgstr "fout bij het verkrijgen van nonce voor de socket\n"
-
-#, c-format
-msgid "error binding socket to `%s': %s\n"
-msgstr "fout bij de het verbinden van de socket met `%s': %s\n"
-
-#, c-format
-msgid "listen() failed: %s\n"
-msgstr "listen() is mislukt: %s\n"
-
-#, c-format
-msgid "listening on socket `%s'\n"
-msgstr "er wordt geluisterd op socket `%s'\n"
-
-#, c-format
-msgid "directory `%s' created\n"
-msgstr "map `%s' aangemaakt\n"
-
-#, c-format
-msgid "stat() failed for `%s': %s\n"
-msgstr "opvragen van status van `%s' mislukte: %s\n"
-
-#, c-format
-msgid "can't use `%s' as home directory\n"
-msgstr "kan map `%s' niet gebruiken als thuismap\n"
-
-#, c-format
-msgid "error reading nonce on fd %d: %s\n"
-msgstr "fout bij het lezen van nonce op bestandsindicator %d: %s\n"
-
-#, c-format
-msgid "handler 0x%lx for fd %d started\n"
-msgstr "verwerker 0x%lx voor bestandsindicator %d werd gestart\n"
-
-#, c-format
-msgid "handler 0x%lx for fd %d terminated\n"
-msgstr "verwerker 0x%lx voor bestandsindicator %d werd beëindigd\n"
-
-#, c-format
-msgid "ssh handler 0x%lx for fd %d started\n"
-msgstr "ssh-verwerker 0x%lx voor bestandsindicator %d werd gestart\n"
-
-#, c-format
-msgid "ssh handler 0x%lx for fd %d terminated\n"
-msgstr "ssh-verwerker 0x%lx voor bestandsindicator %d werd beëindigd\n"
-
-#, c-format
-msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "pth_select mislukte: %s - er wordt 1s gewacht\n"
-
-#, c-format
-msgid "%s %s stopped\n"
-msgstr "%s %s gestopt\n"
-
-msgid "no gpg-agent running in this session\n"
-msgstr "er is geen instantie van gpg-agent actief tijdens deze sessie\n"
-
-msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "ongeldig formaat van de omgevingsvariabele GPG_AGENT_INFO\n"
-
-#, c-format
-msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "protocolversie %d van gpg-agent wordt niet ondersteund\n"
-
-msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
-msgstr "Gebruik: gpg-preset-passphrase [opties] SLEUTELHENDEL (-h voor hulp)\n"
-
-msgid ""
-"Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
-"Password cache maintenance\n"
-msgstr ""
-"Syntaxis: gpg-preset-passphrase [opties] SLEUTELHENDEL\n"
-"Onderhoud van de wachtwoordcache\n"
-
-msgid ""
-"@Commands:\n"
-" "
-msgstr ""
-"@Commando's:\n"
-" "
-
-msgid ""
-"@\n"
-"Options:\n"
-" "
-msgstr ""
-"@\n"
-"Opties:\n"
-" "
-
-msgid "Usage: gpg-protect-tool [options] (-h for help)\n"
-msgstr "Gebruik: gpg-protect-tool [opties] (-h voor hulp)\n"
-
-msgid ""
-"Syntax: gpg-protect-tool [options] [args]\n"
-"Secret key maintenance tool\n"
-msgstr ""
-"Syntaxis: gpg-protect-tool [opties] [argumenten]\n"
-"Hulpmiddel voor het onderhoud van de geheime sleutels\n"
-
-msgid "Please enter the passphrase to unprotect the PKCS#12 object."
-msgstr ""
-"Voer de wachtwoordzin in om de beveiliging van het PKCS#12-object op te "
-"heffen."
-
-msgid "Please enter the passphrase to protect the new PKCS#12 object."
-msgstr "Voer de wachtwoordzin in om het nieuwe PKCS#12-object te beveiligen."
-
-msgid ""
-"Please enter the passphrase to protect the imported object within the GnuPG "
-"system."
-msgstr ""
-"Voer de wachtwoordzin in om het in het GnuPG-systeem geïmporteerde object te "
-"beveiligen."
-
-msgid ""
-"Please enter the passphrase or the PIN\n"
-"needed to complete this operation."
-msgstr ""
-"Gelieve de wachtwoordzin of de pincode in te voeren\n"
-"dit is nodig om deze bewerking te voltooien."
-
-msgid "Passphrase:"
-msgstr "Wachtwoordzin:"
-
-msgid "cancelled\n"
-msgstr "geannuleerd\n"
-
-#, c-format
-msgid "error while asking for the passphrase: %s\n"
-msgstr "fout bij het opvragen van de wachtwoordzin: %s\n"
-
-#, c-format
-msgid "error opening `%s': %s\n"
-msgstr "fout bij het openen van `%s': %s\n"
-
-#, c-format
-msgid "file `%s', line %d: %s\n"
-msgstr "bestand `%s', regel %d: %s\n"
-
-#, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
-msgstr "instructie \"%s\" genegeerd in `%s', regel %d\n"
-
-#, c-format
-msgid "system trustlist `%s' not available\n"
-msgstr "de lijst `%s' over systeembetrouwbaarheid is niet beschikbaar\n"
-
-#, c-format
-msgid "bad fingerprint in `%s', line %d\n"
-msgstr "slechte vingerafdruk in `%s', regel %d\n"
-
-#, c-format
-msgid "invalid keyflag in `%s', line %d\n"
-msgstr "ongeldige sleutelparameter in `%s', regel %d\n"
-
-#, c-format
-msgid "error reading `%s', line %d: %s\n"
-msgstr "fout bij het lezen van `%s', regel %d: %s\n"
-
-msgid "error reading list of trusted root certificates\n"
-msgstr "fout bij het lezen van de lijst van vertrouwde stamcertificaten\n"
-
-#. TRANSLATORS: This prompt is shown by the Pinentry
-#. and has one special property: A "%%0A" is used by
-#. Pinentry to insert a line break.  The double
-#. percent sign is actually needed because it is also
-#. a printf format string.  If you need to insert a
-#. plain % sign, you need to encode it as "%%25".  The
-#. "%s" gets replaced by the name as stored in the
-#. certificate.
-#, c-format
-msgid ""
-"Do you ultimately trust%%0A  \"%s\"%%0Ato correctly certify user "
-"certificates?"
-msgstr ""
-"Vertrouwt u er uiterst sterk op dat%%0A  \"%s\"%%0Aop een correcte wijze "
-"gebruikerscertificaten certificeert?"
-
-msgid "Yes"
-msgstr "Ja"
-
-msgid "No"
-msgstr "Nee"
-
-#. TRANSLATORS: This prompt is shown by the Pinentry and has
-#. one special property: A "%%0A" is used by Pinentry to
-#. insert a line break.  The double percent sign is actually
-#. needed because it is also a printf format string.  If you
-#. need to insert a plain % sign, you need to encode it as
-#. "%%25".  The second "%s" gets replaced by a hexdecimal
-#. fingerprint string whereas the first one receives the name
-#. as stored in the certificate.
-#, c-format
-msgid ""
-"Please verify that the certificate identified as:%%0A  \"%s\"%%0Ahas the "
-"fingerprint:%%0A  %s"
-msgstr ""
-"Gelieve te verifiëren of het certificaat dat geïdentificeerd werd als:%%0A  "
-"\"%s\"%%0Avolgende vingerafdruk heeft:%%0A  %s"
-
-#. TRANSLATORS: "Correct" is the label of a button and intended
-#. to be hit if the fingerprint matches the one of the CA.  The
-#. other button is "the default "Cancel" of the Pinentry.
-msgid "Correct"
-msgstr "Juist"
-
-msgid "Wrong"
-msgstr "Fout"
-
-#, c-format
-msgid "Note: This passphrase has never been changed.%0APlease change it now."
-msgstr ""
-"Noot: Deze wachtwoordzin werd nog nooit gewijzigd.%0AGelieve hem nu te "
-"wijzigen."
-
-#, c-format
-msgid ""
-"This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s.  Please change "
-"it now."
-msgstr ""
-"Deze wachtwoordzin werd niet meer gewijzigd%%0Asinds %.4s-%.2s-%.2s. Gelieve "
-"hem nu te wijzigen."
-
-msgid "Change passphrase"
-msgstr "Wijzig de wachtwoordzin"
-
-msgid "I'll change it later"
-msgstr "Ik zal hem later wijzigen"
-
-#, c-format
-msgid "error creating a pipe: %s\n"
-msgstr "fout bij het maken van een pijp: %s\n"
-
-#, c-format
-msgid "can't fdopen pipe for reading: %s\n"
-msgstr "kan de pijp met fdopen niet openen om eruit te lezen: %s\n"
-
-#, c-format
-msgid "error forking process: %s\n"
-msgstr "fout bij het starten van een nieuw proces (fork): %s\n"
-
-#, c-format
-msgid "waiting for process %d to terminate failed: %s\n"
-msgstr "wachten op het einde van proces %d is mislukt: %s\n"
-
-#, c-format
-msgid "error getting exit code of process %d: %s\n"
-msgstr "fout bij het opvragen van de afsluitcode van proces %d: %s\n"
-
-#, c-format
-msgid "error running `%s': exit status %d\n"
-msgstr "fout bij het uitvoeren van `%s': afsluitstatus %d\n"
-
-#, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "fout bij het uitvoeren van `%s': wellicht niet geïnstalleerd\n"
-
-#, c-format
-msgid "error running `%s': terminated\n"
-msgstr "fout bij het uitvoeren van `%s': gestopt\n"
-
-#, c-format
-msgid "error creating socket: %s\n"
-msgstr "fout bij het maken van een socket: %s\n"
-
-msgid "host not found"
-msgstr "computer niet gevonden"
-
-msgid "gpg-agent is not available in this session\n"
-msgstr "gpg-agent is niet beschikbaar tijdens deze sessie\n"
-
-#, c-format
-msgid "can't connect to `%s': %s\n"
-msgstr "kan geen verbinding maken met `%s': %s\n"
-
-msgid "communication problem with gpg-agent\n"
-msgstr "probleem in de communicatie met gpg-agent\n"
-
-msgid "problem setting the gpg-agent options\n"
-msgstr "problemen bij het instellen van de opties voor gpg-agent\n"
-
-msgid "canceled by user\n"
-msgstr "afgebroken door de gebruiker\n"
-
-msgid "problem with the agent\n"
-msgstr "probleem met de agent\n"
-
-#, c-format
-msgid "can't disable core dumps: %s\n"
-msgstr "het is niet mogelijk om core-dumps uit te schakelen: %s\n"
-
-#, c-format
-msgid "Warning: unsafe ownership on %s \"%s\"\n"
-msgstr "Waarschuwing: onveilige eigendomsinstellingen op %s \"%s\"\n"
-
-#, c-format
-msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgstr "Waarschuwing: onveilige toegangsrechten op %s \"%s\"\n"
-
-#. TRANSLATORS: See doc/TRANSLATE about this string.
-msgid "yes"
-msgstr "yes|ja"
-
-msgid "yY"
-msgstr "yYjJ"
-
-#. TRANSLATORS: See doc/TRANSLATE about this string.
-msgid "no"
-msgstr "no|nee"
-
-msgid "nN"
-msgstr "nN"
-
-#. TRANSLATORS: See doc/TRANSLATE about this string.
-msgid "quit"
-msgstr "quit|stoppen"
-
-msgid "qQ"
-msgstr "qQsS"
-
-#. TRANSLATORS: See doc/TRANSLATE about this string.
-msgid "okay|okay"
-msgstr "okay|oké|ok|OK"
-
-#. TRANSLATORS: See doc/TRANSLATE about this string.
-msgid "cancel|cancel"
-msgstr "cancel|cancelen|annuleren"
-
-msgid "oO"
-msgstr "oO"
-
-msgid "cC"
-msgstr "cCaA"
-
-#, c-format
-msgid "out of core in secure memory while allocating %lu bytes"
-msgstr ""
-"over de limiet van het beveiligde geheugen bij het reserveren van %lu bytes"
-
-#, c-format
-msgid "out of core while allocating %lu bytes"
-msgstr "over de geheugenlimiet bij het reserveren van %lu bytes"
-
-msgid "no running gpg-agent - starting one\n"
-msgstr "er is geen instantie van gpg-agent actief - er wordt een gestart\n"
-
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "er wordt %d seconden gewacht terwijl de agent opstart\n"
-
-msgid "can't connect to the agent - trying fall back\n"
-msgstr ""
-"kan geen verbinding krijgen met de agent - er wordt een noodoplossing "
-"geprobeerd\n"
-
-#. TRANSLATORS: Copy the prefix between the vertical bars
-#. verbatim.  It will not be printed.
-msgid "|audit-log-result|Good"
-msgstr "|audit-log-result|Goed"
-
-msgid "|audit-log-result|Bad"
-msgstr "|audit-log-result|Slecht"
-
-msgid "|audit-log-result|Not supported"
-msgstr "|audit-log-result|Niet ondersteund"
-
-msgid "|audit-log-result|No certificate"
-msgstr "|audit-log-result|Geen certificaat"
-
-msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|Niet geactiveerd"
-
-msgid "|audit-log-result|Error"
-msgstr "|audit-log-result|Fout"
-
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|Niet gebruikt"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|Oké"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|Overgeslagen"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|Sommige"
-
-msgid "Certificate chain available"
-msgstr "Ketting van certificaten is beschikbaar"
-
-msgid "root certificate missing"
-msgstr "stamcertificaat ontbreekt"
-
-msgid "Data encryption succeeded"
-msgstr "Versleutelen van gegevens is geslaagd"
-
-msgid "Data available"
-msgstr "Er zijn gegevens beschikbaar"
-
-msgid "Session key created"
-msgstr "Sessiesleutel aangemaakt"
-
-#, c-format
-msgid "algorithm: %s"
-msgstr "algoritme: %s"
-
-#, c-format
-msgid "unsupported algorithm: %s"
-msgstr "niet ondersteund algoritme: %s"
-
-msgid "seems to be not encrypted"
-msgstr "lijkt niet versleuteld te zijn"
-
-msgid "Number of recipients"
-msgstr "Aantal ontvangers"
-
-#, c-format
-msgid "Recipient %d"
-msgstr "Ontvanger %d"
-
-msgid "Data signing succeeded"
-msgstr "Gegevens ondertekenen is gelukt"
-
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritme voor het hashen van gegevens: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "Ondertekenaar %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritme voor het hashen van attributen: %s"
-
-msgid "Data decryption succeeded"
-msgstr "Gegevens versleutelen is gelukt"
-
-msgid "Encryption algorithm supported"
-msgstr "Versleutelingsalgoritme wordt ondersteund"
-
-msgid "Data verification succeeded"
-msgstr "Verificatie van gegevens is gelukt"
-
-msgid "Signature available"
-msgstr "Ondertekening is beschikbaar"
-
-msgid "Parsing data succeeded"
-msgstr "Gegevens ontleden is gelukt"
-
-#, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "slecht algoritme voor het hashen van gegevens: %s"
-
-#, c-format
-msgid "Signature %d"
-msgstr "Handtekening %d"
-
-msgid "Certificate chain valid"
-msgstr "Ketting van certificaten is geldig"
-
-msgid "Root certificate trustworthy"
-msgstr "Stamcertificaat is betrouwbaar"
-
-msgid "no CRL found for certificate"
-msgstr "geen enkele lijst van intrekkingen gevonden voor het certificaat"
-
-msgid "the available CRL is too old"
-msgstr "de beschikbare lijst van intrekkingen is te oud"
-
-msgid "CRL/OCSP check of certificates"
-msgstr ""
-"Verificatie van de certificaten met de lijst van intrekkingen en met OCSP"
-
-msgid "Included certificates"
-msgstr "Ingesloten certificaten"
-
-msgid "No audit log entries."
-msgstr "Geen invoer in het auditlogboek."
-
-msgid "Unknown operation"
-msgstr "Onbekende bewerking"
-
-msgid "Gpg-Agent usable"
-msgstr "Gpg-Agent kan gebruikt worden"
-
-msgid "Dirmngr usable"
-msgstr "Dirmngr kan gebruikt worden"
-
-#, c-format
-msgid "No help available for `%s'."
-msgstr "Geen hulp beschikbaar voor `%s'."
-
-msgid "ignoring garbage line"
-msgstr "regel met rommel wordt genegeerd"
-
-msgid "[none]"
-msgstr "[geen]"
-
-#, c-format
-msgid "armor: %s\n"
-msgstr "harnas: %s\n"
-
-msgid "invalid armor header: "
-msgstr "ongeldige harnas-intro: "
-
-msgid "armor header: "
-msgstr "harnas-intro: "
-
-msgid "invalid clearsig header\n"
-msgstr "ongeldige intro van de handtekening in klare tekst\n"
-
-msgid "unknown armor header: "
-msgstr "onbekende harnas-intro: "
-
-msgid "nested clear text signatures\n"
-msgstr "geneste ondertekeningen in klare tekst\n"
-
-msgid "unexpected armor: "
-msgstr "onverwacht harnas: "
-
-msgid "invalid dash escaped line: "
-msgstr "door liggend streepje afgeschermde regel is ongeldig: "
-
-#, c-format
-msgid "invalid radix64 character %02X skipped\n"
-msgstr "ongeldig radix64-teken %02X overgeslagen\n"
-
-msgid "premature eof (no CRC)\n"
-msgstr "voortijdig bestandseinde (eof) (geen CRC)\n"
-
-msgid "premature eof (in CRC)\n"
-msgstr "voortijdig bestandseinde (eof) (in CRC)\n"
-
-msgid "malformed CRC\n"
-msgstr "ongeldige CRC\n"
-
-#, c-format
-msgid "CRC error; %06lX - %06lX\n"
-msgstr "CRC-fout; %06lX - %06lX\n"
-
-msgid "premature eof (in trailer)\n"
-msgstr "voortijdig bestandseinde (eof) (in de epiloog)\n"
-
-msgid "error in trailer line\n"
-msgstr "fout in epiloogregel\n"
-
-msgid "no valid OpenPGP data found.\n"
-msgstr "geen geldige OpenPGP-gegevens gevonden.\n"
-
-#, c-format
-msgid "invalid armor: line longer than %d characters\n"
-msgstr "ongeldig harnas: de regel is langer dan %d tekens\n"
-
-msgid ""
-"quoted printable character in armor - probably a buggy MTA has been used\n"
-msgstr ""
-"harnas bevat een 'quoted printable'-teken - wellicht werd een defecte MTA "
-"(mail-server) gebruikt\n"
-
-msgid ""
-"a notation name must have only printable characters or spaces, and end with "
-"an '='\n"
-msgstr ""
-"een notatiebenaming mag enkel afdrukbare tekens of spaties bevatten, en moet "
-"eindigen met een '='-teken\n"
-
-msgid "a user notation name must contain the '@' character\n"
-msgstr "een notatiebenaming voor een gebruiker moet het teken '@' bevatten\n"
-
-msgid "a notation name must not contain more than one '@' character\n"
-msgstr ""
-"een notatiebenaming mag niet meer dan een keer het teken '@' bevatten\n"
-
-msgid "a notation value must not use any control characters\n"
-msgstr "een notatiewaarde mag geen enkel controleteken bevatten\n"
-
-msgid "WARNING: invalid notation data found\n"
-msgstr "WAARSCHUWING: ongeldige notatiegegevens gevonden\n"
-
-msgid "not human readable"
-msgstr "niet leesbaar door de gebruiker"
-
-#, c-format
-msgid "OpenPGP card not available: %s\n"
-msgstr "OpenPGP-kaart is niet beschikbaar: %s\n"
-
-#, c-format
-msgid "OpenPGP card no. %s detected\n"
-msgstr "OpenPGP-kaartnummer %s gevonden\n"
-
-msgid "can't do this in batch mode\n"
-msgstr "dit is niet mogelijk in automatische modus\n"
-
-msgid "This command is only available for version 2 cards\n"
-msgstr "Dit commando is enkel beschikbaar voor kaarten van versie 2\n"
-
-msgid "Reset Code not or not anymore available\n"
-msgstr "Reset-Code niet of niet langer beschikbaar\n"
-
-msgid "Your selection? "
-msgstr "Uw keuze? "
-
-msgid "[not set]"
-msgstr "[niet ingesteld]"
-
-msgid "male"
-msgstr "man"
-
-msgid "female"
-msgstr "vrouw"
-
-msgid "unspecified"
-msgstr "niet gespecificeerd"
-
-msgid "not forced"
-msgstr "niet geforceerd"
-
-msgid "forced"
-msgstr "geforceerd"
-
-msgid "Error: Only plain ASCII is currently allowed.\n"
-msgstr "Fout: Alleen platte ASCII is momenteel toegestaan.\n"
-
-msgid "Error: The \"<\" character may not be used.\n"
-msgstr "Fout: U mag het teken \"<\" niet gebruiken.\n"
-
-msgid "Error: Double spaces are not allowed.\n"
-msgstr "Fout: Dubbele spaties gebruiken is niet toegestaan.\n"
-
-msgid "Cardholder's surname: "
-msgstr "Achternaam van de kaarthouder: "
-
-msgid "Cardholder's given name: "
-msgstr "Voornaam van de kaarthouder: "
-
-#, c-format
-msgid "Error: Combined name too long (limit is %d characters).\n"
-msgstr "Fout: Volledige naam is te lang (de limiet is %d tekens).\n"
-
-msgid "URL to retrieve public key: "
-msgstr "URL voor het ophalen van de publieke sleutel: "
-
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Fout: URL is te lang (de limiet is %d tekens).\n"
-
-#, c-format
-msgid "error allocating enough memory: %s\n"
-msgstr "fout bij het reserveren van voldoende geheugen: %s\n"
-
-#, c-format
-msgid "error reading `%s': %s\n"
-msgstr "fout bij het lezen van `%s': %s\n"
-
-#, c-format
-msgid "error writing `%s': %s\n"
-msgstr "fout bij het wegschrijven van `%s': %s\n"
-
-msgid "Login data (account name): "
-msgstr "Aanmeldgegevens (accountnaam): "
-
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Fout: Aanmeldgegevens zijn te lang (de limiet is %d tekens).\n"
-
-msgid "Private DO data: "
-msgstr "Geheime DO-gegevens: "
-
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Fout: Geheime DO is te lang (de limiet is %d tekens).\n"
-
-msgid "Language preferences: "
-msgstr "Taalvoorkeuren: "
-
-msgid "Error: invalid length of preference string.\n"
-msgstr "Fout: ongeldige lengte van de voorkeursinformatie.\n"
-
-msgid "Error: invalid characters in preference string.\n"
-msgstr "Fout: ongeldige tekens in voorkeursinformatie.\n"
-
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Geslacht ((M)Man, (F)Vrouw of spatie): "
-
-msgid "Error: invalid response.\n"
-msgstr "Fout: ongeldig antwoord.\n"
-
-msgid "CA fingerprint: "
-msgstr "CA-vingerafdruk: "
-
-msgid "Error: invalid formatted fingerprint.\n"
-msgstr "Fout: ongeldig opgemaakte vingerafdruk.\n"
-
-#, c-format
-msgid "key operation not possible: %s\n"
-msgstr "sleutelbewerking is niet mogelijk: %s\n"
-
-msgid "not an OpenPGP card"
-msgstr "geen OpenPGP-kaart"
-
-#, c-format
-msgid "error getting current key info: %s\n"
-msgstr "fout bij het ophalen van de gegevens van de huidige sleutel: %s\n"
-
-msgid "Replace existing key? (y/N) "
-msgstr "Bestaande sleutel vervangen? (j/N) "
-
-msgid ""
-"NOTE: There is no guarantee that the card supports the requested size.\n"
-"      If the key generation does not succeed, please check the\n"
-"      documentation of your card to see what sizes are allowed.\n"
-msgstr ""
-"NOOT: Het kan niet gegarandeerd worden dat de kaart\n"
-"      de gevraagde grootte ondersteunt.\n"
-"      Indien het aanmaken van de sleutel niet lukt, moet u de documentatie\n"
-"      bij uw kaart raadplegen om na te gaan welke groottes toegelaten zijn.\n"
-
-#, c-format
-msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "Welke sleutelgrootte wilt u voor de Ondertekeningssleutel? (%u) "
-
-#, c-format
-msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "Welke sleutelgrootte wilt u voor de Encryptiesleutel? (%u) "
-
-#, c-format
-msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "Welke sleutelgrootte wilt u voor de Authenticatiesleutel? (%u) "
-
-#, c-format
-msgid "rounded up to %u bits\n"
-msgstr "afgerond naar %u bits\n"
-
-#, c-format
-msgid "%s keysizes must be in the range %u-%u\n"
-msgstr "%s sleutelgrootte moet vallen binnen het bereik %u-%u\n"
-
-#, c-format
-msgid "The card will now be re-configured to generate a key of %u bits\n"
-msgstr ""
-"De kaart zal nu opnieuw ingesteld worden om een sleutel van %u bits aan te "
-"maken\n"
-
-#, c-format
-msgid "error changing size of key %d to %u bits: %s\n"
-msgstr ""
-"fout bij het veranderen van de grootte van sleutel %d naar %u bits: %s\n"
-
-msgid "Make off-card backup of encryption key? (Y/n) "
-msgstr "Een externe reservekopie maken van de encryptiesleutel? (J/n) "
-
-msgid "NOTE: keys are already stored on the card!\n"
-msgstr "NOOT: sleutels worden al op de kaart bewaard!\n"
-
-msgid "Replace existing keys? (y/N) "
-msgstr "Bestaande sleutels vervangen? (j/N) "
-
-#, c-format
-msgid ""
-"Please note that the factory settings of the PINs are\n"
-"   PIN = `%s'     Admin PIN = `%s'\n"
-"You should change them using the command --change-pin\n"
-msgstr ""
-"Gelieve te noteren dat de fabrieksinstellingen voor de pincodes de volgende "
-"zijn:\n"
-"   pincode = `%s'     Beheerderspincode = `%s'\n"
-"U wordt aangeraden deze te wijzigen met het commando --change-pin\n"
-
-msgid "Please select the type of key to generate:\n"
-msgstr "Selecteer het type sleutel dat aangemaakt moet worden:\n"
-
-msgid "   (1) Signature key\n"
-msgstr "   (1) Ondertekeningssleutel\n"
-
-msgid "   (2) Encryption key\n"
-msgstr "   (2) Encryptiesleutel\n"
-
-msgid "   (3) Authentication key\n"
-msgstr "   (3) Authenticatiesleutel\n"
-
-msgid "Invalid selection.\n"
-msgstr "Ongeldige keuze.\n"
-
-msgid "Please select where to store the key:\n"
-msgstr "Geef aan waar de sleutel moet opgeslagen worden:\n"
-
-msgid "unknown key protection algorithm\n"
-msgstr "onbekend sleutelbeveiligingsalgoritme\n"
-
-msgid "secret parts of key are not available\n"
-msgstr "geheime delen van de sleutel zijn niet beschikbaar\n"
-
-msgid "secret key already stored on a card\n"
-msgstr "geheime sleutel staat reeds op de kaart\n"
-
-#, c-format
-msgid "error writing key to card: %s\n"
-msgstr "fout bij het wegschrijven van de sleutel naar de kaart: %s\n"
-
-msgid "quit this menu"
-msgstr "dit menu verlaten"
-
-msgid "show admin commands"
-msgstr "toon beheerderscommando's"
-
-msgid "show this help"
-msgstr "toon deze hulp"
-
-msgid "list all available data"
-msgstr "toon alle beschikbare gegevens"
-
-msgid "change card holder's name"
-msgstr "verander de naam van de kaarthouder"
-
-msgid "change URL to retrieve key"
-msgstr "verander de URL waarvan de sleutel opgehaald moet worden"
-
-msgid "fetch the key specified in the card URL"
-msgstr "haal de sleutel op van de URL die op de kaart vermeld staat"
-
-msgid "change the login name"
-msgstr "verander de aanmeldnaam"
-
-msgid "change the language preferences"
-msgstr "verander de taalvoorkeuren"
-
-msgid "change card holder's sex"
-msgstr "verander het geslacht van de kaarthouder"
-
-msgid "change a CA fingerprint"
-msgstr "verander een CA-vingerafdruk"
-
-msgid "toggle the signature force PIN flag"
-msgstr ""
-"schakel de parameter die om een pincode vraagt bij het ondertekenen aan/uit"
-
-msgid "generate new keys"
-msgstr "maak nieuwe sleutels aan"
-
-msgid "menu to change or unblock the PIN"
-msgstr "menu voor het wijzigen of ontgrendelen van de pincode"
-
-msgid "verify the PIN and list all data"
-msgstr "controleer de pincode en toon alle gegevens"
-
-msgid "unblock the PIN using a Reset Code"
-msgstr "ontgrendel de pincode met behulp van een Reset-Code"
-
-msgid "gpg/card> "
-msgstr "gpg/kaart> "
-
-msgid "Admin-only command\n"
-msgstr "Enkel de beheerder kan dit commando uitvoeren\n"
-
-msgid "Admin commands are allowed\n"
-msgstr "Beheerderscommando's zijn toegestaan\n"
-
-msgid "Admin commands are not allowed\n"
-msgstr "Beheerderscommando's zijn niet toegestaan\n"
-
-msgid "Invalid command  (try \"help\")\n"
-msgstr "Ongeldig commando  (probeer \"help\")\n"
-
-msgid "--output doesn't work for this command\n"
-msgstr "--output werkt niet voor dit commando\n"
-
-#, c-format
-msgid "can't open `%s'\n"
-msgstr "kan `%s' niet openen\n"
-
-#, c-format
-msgid "key \"%s\" not found: %s\n"
-msgstr "sleutel \"%s\" niet gevonden: %s\n"
-
-#, c-format
-msgid "error reading keyblock: %s\n"
-msgstr "fout tijdens het lezen van sleutelblok: %s\n"
-
-msgid "(unless you specify the key by fingerprint)\n"
-msgstr "(tenzij u de sleutel via de vingerafdruk specificeert)\n"
-
-msgid "can't do this in batch mode without \"--yes\"\n"
-msgstr ""
-"dit is onmogelijk in automatische modus zonder de parameter \"--yes\"\n"
-
-msgid "Delete this key from the keyring? (y/N) "
-msgstr "Deze sleutel uit de sleutelring verwijderen? (j/N) "
-
-msgid "This is a secret key! - really delete? (y/N) "
-msgstr "Dit is een geheime sleutel! - echt verwijderen? (j/N) "
-
-#, c-format
-msgid "deleting keyblock failed: %s\n"
-msgstr "verwijderen van sleutelblok is mislukt: %s\n"
-
-msgid "ownertrust information cleared\n"
-msgstr "de betrouwbaarheidsgegevens werden gewist\n"
-
-#, c-format
-msgid "there is a secret key for public key \"%s\"!\n"
-msgstr "een geheime sleutel fungeert als publieke sleutel \"%s\"!\n"
-
-msgid "use option \"--delete-secret-keys\" to delete it first.\n"
-msgstr ""
-"gebruik de optie \"--delete-secret-keys\" om hem eerst te verwijderen.\n"
-
-#, c-format
-msgid "error creating passphrase: %s\n"
-msgstr "fout bij het maken van de wachtwoordzin: %s\n"
-
-msgid "can't use a symmetric ESK packet due to the S2K mode\n"
-msgstr "kan geen symmetrisch ESK-pakket gebruiken omwille van de S2K-modus\n"
-
-#, c-format
-msgid "using cipher %s\n"
-msgstr "versleutelingsalgoritme %s wordt gebruikt\n"
-
-#, c-format
-msgid "`%s' already compressed\n"
-msgstr "`%s' is reeds gecomprimeerd\n"
-
-#, c-format
-msgid "WARNING: `%s' is an empty file\n"
-msgstr "WAARSCHUWING: `%s' is een leeg bestand\n"
-
-msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
-msgstr ""
-"U kunt enkel versleutelen naar RSA-sleutels van 2048 bits of minder in de "
-"modus --pgp2\n"
-
-#, c-format
-msgid "reading from `%s'\n"
-msgstr "lezen van `%s'\n"
-
-msgid ""
-"unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
-msgstr ""
-"het is onmogelijk om het IDEA-versleutelingsalgoritme te gebruiken voor al "
-"de sleutels waarnaar u versleutelt.\n"
-
-#, c-format
-msgid ""
-"WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
-msgstr ""
-"WAARSCHUWING: het dwingend opleggen van het symmetrisch "
-"versleutelingsalgoritme %s (%d) gaat in tegen de voorkeuren van de "
-"ontvanger\n"
-
-#, c-format
-msgid ""
-"WARNING: forcing compression algorithm %s (%d) violates recipient "
-"preferences\n"
-msgstr ""
-"WAARSCHUWING: het dwingend opleggen van het compressiealgoritme %s (%d) gaat "
-"in tegen de voorkeuren van de ontvanger\n"
-
-#, c-format
-msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n"
-msgstr ""
-"het dwingend opleggen van het symmetrisch versleutelingsalgoritme %s (%d) "
-"gaat in tegen de voorkeuren van de ontvanger\n"
-
-#, c-format
-msgid "you may not use %s while in %s mode\n"
-msgstr "u mag %s niet gebruiken in de %s-modus\n"
-
-#, c-format
-msgid "%s/%s encrypted for: \"%s\"\n"
-msgstr "%s/%s versleuteld voor: \"%s\"\n"
-
-#, c-format
-msgid "%s encrypted data\n"
-msgstr "%s versleutelde gegevens\n"
-
-#, c-format
-msgid "encrypted with unknown algorithm %d\n"
-msgstr "versleuteld met onbekend algoritme %d\n"
-
-msgid ""
-"WARNING: message was encrypted with a weak key in the symmetric cipher.\n"
-msgstr ""
-"WAARSCHUWING: het bericht is versleuteld met een zwakke sleutel in het "
-"symmetrische versleutelingsalgoritme.\n"
-
-msgid "problem handling encrypted packet\n"
-msgstr "probleem met het verwerken van het versleutelde pakket\n"
-
-msgid "no remote program execution supported\n"
-msgstr "het uitvoeren van externe programma's wordt niet ondersteund\n"
-
-msgid ""
-"external program calls are disabled due to unsafe options file permissions\n"
-msgstr ""
-"het aanroepen van externe programma's is uitgeschakeld omdat de "
-"toegangsrechten van het optiebestand onveilig zijn\n"
-
-msgid "this platform requires temporary files when calling external programs\n"
-msgstr ""
-"dit platform heeft tijdelijke bestanden nodig bij het aanroepen van externe "
-"programma's\n"
-
-#, c-format
-msgid "unable to execute program `%s': %s\n"
-msgstr "kan programma `%s' niet uitvoeren: %s\n"
-
-#, c-format
-msgid "unable to execute shell `%s': %s\n"
-msgstr "kan shell `%s' niet uitvoeren: %s\n"
-
-#, c-format
-msgid "system error while calling external program: %s\n"
-msgstr "systeemfout bij het aanroepen van een extern programma: %s\n"
-
-msgid "unnatural exit of external program\n"
-msgstr "onnatuurlijk einde van het externe programma\n"
-
-msgid "unable to execute external program\n"
-msgstr "niet in staat om het externe programma uit te voeren\n"
-
-#, c-format
-msgid "unable to read external program response: %s\n"
-msgstr "niet in staat om het antwoord van het externe programma te lezen: %s\n"
-
-#, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
-msgstr ""
-"WAARSCHUWING: tijdelijk bestand (%s) `%s' kan niet verwijderd worden: %s\n"
-
-#, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
-msgstr "WAARSCHUWING: tijdelijke map `%s' kan niet verwijderd worden: %s\n"
-
-msgid "export signatures that are marked as local-only"
-msgstr "exporteer handtekeningen die gemarkeerd staan als uitsluitend lokaal"
-
-msgid "export attribute user IDs (generally photo IDs)"
-msgstr ""
-"exporteer identiteitsattributen van gebruikers (meestal identiteitsfoto's)"
-
-msgid "export revocation keys marked as \"sensitive\""
-msgstr "exporteer intrekkingssleutels die als \"gevoelig\" gemarkeerd zijn"
-
-msgid "remove the passphrase from exported subkeys"
-msgstr "verwijder de wachtwoordzin van de geëxporteerde subsleutels"
-
-msgid "remove unusable parts from key during export"
-msgstr "verwijder de onbruikbare delen van de sleutel tijdens het exporteren"
-
-msgid "remove as much as possible from key during export"
-msgstr "verwijder zo veel mogelijk van de sleutel tijdens het exporteren"
-
-msgid "export keys in an S-expression based format"
-msgstr "exporteer sleutels in een formaat gebaseerd op een S-expressie"
-
-msgid "exporting secret keys not allowed\n"
-msgstr "het exporteren van geheime sleutels is niet toegestaan\n"
-
-#, c-format
-msgid "key %s: not protected - skipped\n"
-msgstr "sleutel %s: niet beveiligd - overgeslagen\n"
-
-#, c-format
-msgid "key %s: PGP 2.x style key - skipped\n"
-msgstr "sleutel %s: sleutel van het type PGP 2.x - overgeslagen\n"
-
-#, c-format
-msgid "key %s: key material on-card - skipped\n"
-msgstr "sleutel %s: sleutelmateriaal op kaart - overgeslagen\n"
-
-msgid "about to export an unprotected subkey\n"
-msgstr "sta op het punt om een onbeveiligde subsleutel te exporteren\n"
-
-#, c-format
-msgid "failed to unprotect the subkey: %s\n"
-msgstr "wegnemen van de beveiliging van de subsleutel is mislukt: %s\n"
-
-#, c-format
-msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr ""
-"WAARSCHUWING: geheime sleutel %s heeft geen eenvoudige SK-controlesom\n"
-
-msgid "WARNING: nothing exported\n"
-msgstr "WAARSCHUWING: er werd niets geëxporteerd\n"
-
-msgid "too many entries in pk cache - disabled\n"
-msgstr "te veel regels in de pk-cache - gedeactiveerd\n"
-
-msgid "[User ID not found]"
-msgstr "[Gebruikers-ID niet gevonden]"
-
-#, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "sleutel %s: geheime sleutel zonder publieke sleutel - overgeslagen\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
-msgstr "`%s' automatisch opgehaald via %s\n"
-
-#, c-format
-msgid "error retrieving `%s' via %s: %s\n"
-msgstr "fout bij het ophalen van `%s' via %s: %s\n"
-
-msgid "No fingerprint"
-msgstr "Geen vingerafdruk"
-
-#, c-format
-msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
-msgstr ""
-"Ongeldige sleutel %s is geldig gemaakt met --allow-non-selfsigned-uid\n"
-
-#, c-format
-msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "geen geheime subsleutel voor publieke subsleutel %s - overgeslagen\n"
-
-#, c-format
-msgid "using subkey %s instead of primary key %s\n"
-msgstr "subsleutel %s wordt gebruikt in plaats van primaire sleutel %s\n"
-
-msgid "make a signature"
-msgstr "maak een ondertekening"
-
-msgid "make a clear text signature"
-msgstr "maak een ondertekening in klare tekst"
-
-msgid "make a detached signature"
-msgstr "maak een ontkoppelde ondertekening"
-
-msgid "encrypt data"
-msgstr "versleutel gegevens"
-
-msgid "encryption only with symmetric cipher"
-msgstr "enkel versleutelen met het symmetrisch versleutelingsalgoritme"
-
-msgid "decrypt data (default)"
-msgstr "ontcijfer gegevens (standaard)"
-
-msgid "verify a signature"
-msgstr "controleer een ondertekening"
-
-msgid "list keys"
-msgstr "toon sleutels"
-
-msgid "list keys and signatures"
-msgstr "toon sleutels en ondertekeningen"
-
-msgid "list and check key signatures"
-msgstr "toon en controleer sleutelondertekeningen"
-
-msgid "list keys and fingerprints"
-msgstr "toon sleutels en vingerafdrukken"
-
-msgid "list secret keys"
-msgstr "toon geheime sleutels"
-
-msgid "generate a new key pair"
-msgstr "maak een nieuw sleutelpaar aan"
-
-msgid "generate a revocation certificate"
-msgstr "maak een intrekkingscertificaat aan"
-
-msgid "remove keys from the public keyring"
-msgstr "verwijder sleutels uit de publieke sleutelring"
-
-msgid "remove keys from the secret keyring"
-msgstr "verwijder sleutels uit de geheime sleutelring"
-
-msgid "sign a key"
-msgstr "onderteken een sleutel"
-
-msgid "sign a key locally"
-msgstr "onderteken een sleutel lokaal"
-
-msgid "sign or edit a key"
-msgstr "onderteken of bewerk een sleutel"
-
-msgid "change a passphrase"
-msgstr "wijzig een wachtwoordzin"
-
-msgid "export keys"
-msgstr "exporteer sleutels"
-
-msgid "export keys to a key server"
-msgstr "exporteer sleutels naar een sleutelserver"
-
-msgid "import keys from a key server"
-msgstr "importeer sleutels van een sleutelserver"
-
-msgid "search for keys on a key server"
-msgstr "zoek naar sleutels op een sleutelserver"
-
-msgid "update all keys from a keyserver"
-msgstr "alle sleutels bijwerken vanaf een sleutelserver"
-
-msgid "import/merge keys"
-msgstr "sleutels importeren/samenvoegen"
-
-msgid "print the card status"
-msgstr "toon de kaartstatus"
-
-msgid "change data on a card"
-msgstr "wijzig gegevens op een kaart"
-
-msgid "change a card's PIN"
-msgstr "wijzig de pincode van een kaart"
-
-msgid "update the trust database"
-msgstr "werk de database met betrouwbaarheidsinformatie bij"
-
-msgid "print message digests"
-msgstr "toon de hash-waarden van het bericht"
-
-msgid "run in server mode"
-msgstr "in servermodus uitvoeren"
-
-msgid "create ascii armored output"
-msgstr "creëer uitvoer in ascii-harnas"
-
-msgid "|USER-ID|encrypt for USER-ID"
-msgstr "|GEBRUIKERS-ID|versleutel voor GEBRUIKERS-ID"
-
-msgid "|USER-ID|use USER-ID to sign or decrypt"
-msgstr ""
-"|GEBRUIKERS-ID|gebruik deze GEBRUIKERS-ID om te ondertekenen of te "
-"ontcijferen"
-
-msgid "|N|set compress level to N (0 disables)"
-msgstr "|N|stel compressieniveau N in (0 voor geen)"
-
-msgid "use canonical text mode"
-msgstr "gebruik de gebruikelijke tekstmodus"
-
-msgid "|FILE|write output to FILE"
-msgstr "|BESTAND|schrijf uitvoer weg naar BESTAND"
-
-msgid "do not make any changes"
-msgstr "maak geen wijzigingen"
-
-msgid "prompt before overwriting"
-msgstr "niet overschrijven zonder te vragen"
-
-msgid "use strict OpenPGP behavior"
-msgstr "strikt OpenPGP-gedrag toepassen"
-
-msgid ""
-"@\n"
-"(See the man page for a complete listing of all commands and options)\n"
-msgstr ""
-"@\n"
-"(zie de man-pagina voor een complete lijst van alle commando's en opties)\n"
-
-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"
-"Voorbeelden:\n"
-"\n"
-" -se -r Bob [bestand]       onderteken en versleutel voor gebruiker Bob\n"
-" --clearsign [bestand]      maak een ondertekening in klare tekst\n"
-" --detach-sign [bestand]    maak een ontkoppelde ondertekening\n"
-" --list-keys [namen]        toon sleutels\n"
-" --fingerprint [namen]      toon vingerafdrukken\n"
-
-msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "Gebruik: gpg [opties] [bestanden] (-h voor hulp)"
-
-msgid ""
-"Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
-msgstr ""
-"Syntaxis: gpg [opties] [bestanden]\n"
-"Onderteken, controleer, versleutel of ontcijfer\n"
-"Standaardactie is afhankelijk van de gegevensinvoer\n"
-
-msgid ""
-"\n"
-"Supported algorithms:\n"
-msgstr ""
-"\n"
-"Ondersteunde algoritmes:\n"
-
-msgid "Pubkey: "
-msgstr "Publieke sleutel: "
-
-msgid "Cipher: "
-msgstr "Versleutelingsalgoritme: "
-
-msgid "Hash: "
-msgstr "Hashalgoritme: "
-
-msgid "Compression: "
-msgstr "Compressiealgoritme: "
-
-msgid "usage: gpg [options] "
-msgstr "gebruik: gpg [opties] "
-
-msgid "conflicting commands\n"
-msgstr "conflicterende commando's\n"
-
-#, c-format
-msgid "no = sign found in group definition `%s'\n"
-msgstr "geen '='-teken gevonden in de groepsdefinitie `%s'\n"
-
-#, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
-msgstr "WAARSCHUWING: onveilige eigendomsinstellingen van thuismap `%s'\n"
-
-#, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
-msgstr ""
-"WAARSCHUWING: onveilige eigendomsinstellingen van configuratiebestand `%s'\n"
-
-#, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
-msgstr "WAARSCHUWING: onveilige eigendomsinstellingen van uitbreiding ‘%s’\n"
-
-#, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
-msgstr "WAARSCHUWING: toegangsrechten van thuismap `%s' zijn onveilig\n"
-
-#, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
-msgstr ""
-"WAARSCHUWING: toegangsrechten van configuratiebestand `%s' zijn onveilig\n"
-
-#, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
-msgstr "WAARSCHUWING: toegangsrechten van uitbreiding ‘%s’ zijn onveilig\n"
-
-#, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
-msgstr ""
-"WAARSCHUWING: de eigendomsinstellingen van de map waarin de thuismap `%s' "
-"zich bevindt, zijn onveilig\n"
-
-#, c-format
-msgid ""
-"WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
-msgstr ""
-"WAARSCHUWING: de eigendomsinstellingen van de map waarin configuratiebestand "
-"`%s' zich bevindt, zijn onveilig\n"
-
-#, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
-msgstr ""
-"WAARSCHUWING: de eigendomsinstellingen van de map waarin uitbreiding `%s' "
-"zich bevindt, zijn onveilig\n"
-
-#, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
-msgstr ""
-"WAARSCHUWING: de toegangsrechten van de map waarin de thuismap `%s' zich "
-"bevindt, zijn onveilig\n"
-
-#, c-format
-msgid ""
-"WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
-msgstr ""
-"WAARSCHUWING: de toegangsrechten van de map waarin configuratiebestand `%s' "
-"zich bevindt, zijn onveilig\n"
-
-#, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
-msgstr ""
-"WAARSCHUWING: de toegangsrechten van de map waarin uitbreiding `%s' zich "
-"bevindt, zijn onveilig\n"
-
-#, c-format
-msgid "unknown configuration item `%s'\n"
-msgstr "onbekend configuratie-item `%s'\n"
-
-msgid "display photo IDs during key listings"
-msgstr "toon identiteitsfoto's bij de lijst van sleutels"
-
-msgid "show policy URLs during signature listings"
-msgstr "toon richtlijn-URL's bij de lijst van handtekeningen"
-
-msgid "show all notations during signature listings"
-msgstr "toon alle notaties bij het weergeven van de lijst van handtekeningen"
-
-msgid "show IETF standard notations during signature listings"
-msgstr ""
-"toon IETF-standaardnotaties bij het weergeven van de lijst van handtekeningen"
-
-msgid "show user-supplied notations during signature listings"
-msgstr ""
-"toon door de gebruiker gemaakte notaties bij het weergeven van de lijst van "
-"handtekeningen"
-
-msgid "show preferred keyserver URLs during signature listings"
-msgstr ""
-"toon de URL van de voorkeurssleutelserver bij de lijst van handtekeningen"
-
-msgid "show user ID validity during key listings"
-msgstr "toon de geldigheid van de gebruikers-ID bij de lijst van sleutels"
-
-msgid "show revoked and expired user IDs in key listings"
-msgstr ""
-"toon de ingetrokken en verlopen gebruikers-ID's bij de lijst van sleutels"
-
-msgid "show revoked and expired subkeys in key listings"
-msgstr "toon de ingetrokken en vervallen subsleutels bij de lijst van sleutels"
-
-msgid "show the keyring name in key listings"
-msgstr "toon de naam van de sleutelring bij de lijst van sleutels"
-
-msgid "show expiration dates during signature listings"
-msgstr "toon de vervaldata bij de lijst van handtekeningen"
-
-#, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
-msgstr "NOOT: oud bestand `%s' met standaardopties werd genegeerd\n"
-
-#, c-format
-msgid "libgcrypt is too old (need %s, have %s)\n"
-msgstr "libgcrypt is te oud (heb %s nodig, heb %s)\n"
-
-#, c-format
-msgid "NOTE: %s is not for normal use!\n"
-msgstr "NOOT: %s is niet bedoeld voor normaal gebruik!\n"
-
-#, c-format
-msgid "`%s' is not a valid signature expiration\n"
-msgstr "`%s' is geen geldige vervaldatum voor handtekeningen\n"
-
-#, c-format
-msgid "`%s' is not a valid character set\n"
-msgstr "`%s' is geen geldige tekenset\n"
-
-msgid "could not parse keyserver URL\n"
-msgstr "kon de URL van de sleutelserver niet ontleden\n"
-
-#, c-format
-msgid "%s:%d: invalid keyserver options\n"
-msgstr "%s:%d: ongeldige sleutelserveropties\n"
-
-msgid "invalid keyserver options\n"
-msgstr "ongeldige sleutelserveropties\n"
-
-#, c-format
-msgid "%s:%d: invalid import options\n"
-msgstr "%s:%d: ongeldige importopties\n"
-
-msgid "invalid import options\n"
-msgstr "ongeldige importopties\n"
-
-#, c-format
-msgid "%s:%d: invalid export options\n"
-msgstr "%s:%d: ongeldige exportopties\n"
-
-msgid "invalid export options\n"
-msgstr "ongeldige exportopties\n"
-
-#, c-format
-msgid "%s:%d: invalid list options\n"
-msgstr "%s:%d: ongeldige lijstopties\n"
-
-msgid "invalid list options\n"
-msgstr "ongeldige lijstopties\n"
-
-msgid "display photo IDs during signature verification"
-msgstr "toon identiteitsfoto's bij het controleren van de handtekening"
-
-msgid "show policy URLs during signature verification"
-msgstr "toon richtlijn-URL's bij het controleren van de handtekening"
-
-msgid "show all notations during signature verification"
-msgstr "toon alle notaties bij het controleren van de handtekening"
-
-msgid "show IETF standard notations during signature verification"
-msgstr "toon IETF-standaardnotaties bij het controleren van de handtekening"
-
-msgid "show user-supplied notations during signature verification"
-msgstr ""
-"toon door de gebruiker gemaakte notaties bij het controleren van de "
-"handtekening"
-
-msgid "show preferred keyserver URLs during signature verification"
-msgstr ""
-"toon de URL van de voorkeurssleutelserver bij het controleren van de "
-"handtekening"
-
-msgid "show user ID validity during signature verification"
-msgstr ""
-"toon de geldigheid van de gebruikers-ID bij het controleren van de "
-"handtekening"
-
-msgid "show revoked and expired user IDs in signature verification"
-msgstr ""
-"toon de ingetrokken en vervallen gebruikers-ID's bij het controleren van de "
-"handtekening"
-
-msgid "show only the primary user ID in signature verification"
-msgstr ""
-"toon enkel de primaire gebruikers-ID bij het controleren van de handtekening"
-
-msgid "validate signatures with PKA data"
-msgstr "valideer ondertekeningen met PKA-gegevens"
-
-msgid "elevate the trust of signatures with valid PKA data"
-msgstr ""
-"verhoog de betrouwbaarheid van ondertekeningen met geldige PKA-gegevens"
-
-#, c-format
-msgid "%s:%d: invalid verify options\n"
-msgstr "%s:%d: ongeldige verificatieopties\n"
-
-msgid "invalid verify options\n"
-msgstr "ongeldige verificatieopties\n"
-
-#, c-format
-msgid "unable to set exec-path to %s\n"
-msgstr "kon het pad naar het programma %s niet instellen\n"
-
-#, c-format
-msgid "%s:%d: invalid auto-key-locate list\n"
-msgstr "%s:%d: lijst voor het automatisch opzoeken van sleutels is ongeldig\n"
-
-msgid "invalid auto-key-locate list\n"
-msgstr "lijst voor het automatisch opzoeken van sleutels is ongeldig\n"
-
-msgid "WARNING: program may create a core file!\n"
-msgstr "WAARSCHUWING: het programma zou een core-dump-bestand kunnen maken!\n"
-
-#, c-format
-msgid "WARNING: %s overrides %s\n"
-msgstr "WAARSCHUWING: %s heeft voorrang op %s\n"
-
-#, c-format
-msgid "%s not allowed with %s!\n"
-msgstr "%s mag niet gebruikt worden met %s!\n"
-
-#, c-format
-msgid "%s makes no sense with %s!\n"
-msgstr "%s is zinloos in combinatie met %s!\n"
-
-#, c-format
-msgid "will not run with insecure memory due to %s\n"
-msgstr "zal met onveilig geheugen niet werken wegens %s\n"
-
-msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
-msgstr ""
-"enkel ontkoppelde ondertekeningen of handtekeningen in klare tekst zijn "
-"mogelijk in de modus --pgp2\n"
-
-msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr "u kunt miet tegelijk ondertekenen en versleutelen in de modus --pgp2\n"
-
-msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr "u moet bestanden (en geen pipe) gebruiken in de modus --pgp2.\n"
-
-msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr ""
-"om een bericht te versleutelen in de modus --pgp2 is het IDEA-"
-"versleutelingsalgoritme nodig\n"
-
-msgid "selected cipher algorithm is invalid\n"
-msgstr "ongeldig versleutelingsalgoritme gekozen\n"
-
-msgid "selected digest algorithm is invalid\n"
-msgstr "ongeldig hashalgoritme gekozen\n"
-
-msgid "selected compression algorithm is invalid\n"
-msgstr "ongeldig compressiealgoritme gekozen\n"
-
-msgid "selected certification digest algorithm is invalid\n"
-msgstr "het gekozen hashalgoritme voor certificatie is ongeldig\n"
-
-msgid "completes-needed must be greater than 0\n"
-msgstr "completes-needed moet groter zijn dan 0\n"
-
-msgid "marginals-needed must be greater than 1\n"
-msgstr "marginals-needed moet groter zijn dan 1\n"
-
-msgid "max-cert-depth must be in the range from 1 to 255\n"
-msgstr "max-cert-depth moet liggen tussen 1 en 255\n"
-
-msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n"
-msgstr "ongeldig default-cert-level; moet 0, 1, 2 of 3 zijn\n"
-
-msgid "invalid min-cert-level; must be 1, 2, or 3\n"
-msgstr "ongeldig min-cert-level; moet 1, 2 of 3 zijn\n"
-
-msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
-msgstr "NOOT: eenvoudige S2K-modus (0) wordt sterk afgeraden\n"
-
-msgid "invalid S2K mode; must be 0, 1 or 3\n"
-msgstr "ongeldige S2K-modus; moet 0, 1 of 3 zijn\n"
-
-msgid "invalid default preferences\n"
-msgstr "ongeldige standaardvoorkeuren\n"
-
-msgid "invalid personal cipher preferences\n"
-msgstr "ongeldige voorkeuren in het persoonlijk versleutelingsalgoritme\n"
-
-msgid "invalid personal digest preferences\n"
-msgstr "ongeldige voorkeuren in het persoonlijk hashalgoritme\n"
-
-msgid "invalid personal compress preferences\n"
-msgstr "ongeldige voorkeuren in het persoonlijk compressiealgoritme\n"
-
-#, c-format
-msgid "%s does not yet work with %s\n"
-msgstr "%s werkt nog niet met %s\n"
-
-#, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
-msgstr "u mag versleutelingsalgoritme `%s' niet gebruiken in %s-modus\n"
-
-#, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
-msgstr "u mag hashalgoritme `%s' niet gebruiken in %s-modus\n"
-
-#, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
-msgstr "u mag compressiealgoritme `%s' niet gebruiken in %s-modus\n"
-
-#, c-format
-msgid "failed to initialize the TrustDB: %s\n"
-msgstr ""
-"initialiseren van de TrustDB (database van vertrouwen) is mislukt: %s\n"
-
-msgid "WARNING: recipients (-r) given without using public key encryption\n"
-msgstr ""
-"WAARSCHUWING: er werden ontvangers (-r) opgegeven zonder dat versleuteling "
-"met een publieke sleutel toegepast wordt\n"
-
-msgid "--store [filename]"
-msgstr "--store [bestandsnaam]"
-
-msgid "--symmetric [filename]"
-msgstr "--symmetric [bestandsnaam]"
-
-#, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
-msgstr "symmetrische versleuteling van `%s' is mislukt: %s\n"
-
-msgid "--encrypt [filename]"
-msgstr "--encrypt [bestandsnaam]"
-
-msgid "--symmetric --encrypt [filename]"
-msgstr "--symmetric --encrypt [bestandsnaam]"
-
-msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
-msgstr "u kunt --symmetric --encrypt niet gebruiken samen met --s2k-mode 0\n"
-
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
-msgstr "u kunt --symmetric --encrypt niet in %s-modus gebruiken\n"
-
-msgid "--sign [filename]"
-msgstr "--sign [bestandsnaam]"
-
-msgid "--sign --encrypt [filename]"
-msgstr "--sign --encrypt [bestandsnaam]"
-
-msgid "--symmetric --sign --encrypt [filename]"
-msgstr "--symmetric --sign --encrypt [bestandsnaam]"
-
-msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
-msgstr ""
-"u kunt --symmetric --sign --encrypt niet gebruiken samen met --s2k-mode 0\n"
-
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
-msgstr "u kunt --symmetric --sign --encrypt niet in %s-modus gebruiken\n"
-
-msgid "--sign --symmetric [filename]"
-msgstr "--sign --symmetric [bestandsnaam]"
-
-msgid "--clearsign [filename]"
-msgstr "--clearsign [bestandsnaam]"
-
-msgid "--decrypt [filename]"
-msgstr "--decrypt [bestandsnaam]"
-
-msgid "--sign-key user-id"
-msgstr "--sign-key gebruikers-id"
-
-msgid "--lsign-key user-id"
-msgstr "--lsign-key gebruikers-id"
-
-msgid "--edit-key user-id [commands]"
-msgstr "--edit-key gebruikers-id [commando's]"
-
-msgid "--passwd <user-id>"
-msgstr "--passwd <gebruikers-id>"
-
-#, c-format
-msgid "keyserver send failed: %s\n"
-msgstr "verzenden naar sleutelserver is mislukt: %s\n"
-
-#, c-format
-msgid "keyserver receive failed: %s\n"
-msgstr "opvragen vanaf sleutelserver is mislukt: %s\n"
-
-#, c-format
-msgid "key export failed: %s\n"
-msgstr "sleutel exporteren is mislukt: %s\n"
-
-#, c-format
-msgid "keyserver search failed: %s\n"
-msgstr "opzoeking op sleutelserver is mislukt: %s\n"
-
-#, c-format
-msgid "keyserver refresh failed: %s\n"
-msgstr "verversen vanaf sleutelserver is mislukt: %s\n"
-
-#, c-format
-msgid "dearmoring failed: %s\n"
-msgstr "ontmantelen van harnas is mislukt: %s\n"
-
-#, c-format
-msgid "enarmoring failed: %s\n"
-msgstr "opbouwen van harnas is mislukt: %s\n"
-
-#, c-format
-msgid "invalid hash algorithm `%s'\n"
-msgstr "ongeldig hashalgoritme `%s'\n"
-
-msgid "[filename]"
-msgstr "[bestandsnaam]"
-
-msgid "Go ahead and type your message ...\n"
-msgstr "U kunt uw bericht typen ...\n"
-
-msgid "the given certification policy URL is invalid\n"
-msgstr "de opgegeven URL voor certificeringsrichtlijnen is ongeldig\n"
-
-msgid "the given signature policy URL is invalid\n"
-msgstr "de opgegeven URL voor ondertekeningsrichtlijnen is ongeldig\n"
-
-msgid "the given preferred keyserver URL is invalid\n"
-msgstr "de opgegeven URL voor de voorkeurssleutelserver is ongeldig\n"
-
-msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|BESTAND|gebruik de sleutels van de sleutelring BESTAND"
-
-msgid "make timestamp conflicts only a warning"
-msgstr "maak dateringsconflicten slechts een waarschuwing waard"
-
-msgid "|FD|write status info to this FD"
-msgstr "|FD|schrijf statusinformatie naar deze bestandsindicator (FD)"
-
-msgid "Usage: gpgv [options] [files] (-h for help)"
-msgstr "Gebruik: gpgv [opties] [bestanden] (-h voor hulp)"
-
-msgid ""
-"Syntax: gpgv [options] [files]\n"
-"Check signatures against known trusted keys\n"
-msgstr ""
-"Syntaxis: gpg [opties] [bestanden]\n"
-"Controleer ondertekeningen via gekende en vertrouwde sleutels\n"
-
-msgid "No help available"
-msgstr "Geen hulp beschikbaar"
-
-#, c-format
-msgid "No help available for `%s'"
-msgstr "Geen hulp beschikbaar voor `%s'"
-
-msgid "import signatures that are marked as local-only"
-msgstr "importeer handtekeningen die als uitsluitend lokaal zijn gemarkeerd"
-
-msgid "repair damage from the pks keyserver during import"
-msgstr ""
-"herstel beschadigingen die ontstaan zijn bij het importeren vanuit de pks-"
-"sleutelserver"
-
-msgid "do not clear the ownertrust values during import"
-msgstr ""
-"zet de waarden in verband met betrouwbaarheid bij het importeren niet op nul"
-
-msgid "do not update the trustdb after import"
-msgstr "werk de betrouwbaarheidsdatabank (trustdb) niet bij na het importeren"
-
-msgid "create a public key when importing a secret key"
-msgstr ""
-"maak een publieke sleutel aan bij het importeren van een geheime sleutel"
-
-msgid "only accept updates to existing keys"
-msgstr "accepteer alleen het bijwerken van bestaande sleutels"
-
-msgid "remove unusable parts from key after import"
-msgstr "verwijder onbruikbare delen van de sleutel na het importeren"
-
-msgid "remove as much as possible from key after import"
-msgstr "verwijder zo veel mogelijk van de sleutel na het importeren"
-
-#, c-format
-msgid "skipping block of type %d\n"
-msgstr "blok van het type %d wordt overgeslagen\n"
-
-#, c-format
-msgid "%lu keys processed so far\n"
-msgstr "%lu sleutels verwerkt tot dusver\n"
-
-#, c-format
-msgid "Total number processed: %lu\n"
-msgstr "          Totaal aantal verwerkt: %lu\n"
-
-#, c-format
-msgid "      skipped new keys: %lu\n"
-msgstr "    overgeslagen nieuwe sleutels: %lu\n"
-
-#, c-format
-msgid "          w/o user IDs: %lu\n"
-msgstr "            zonder gebruikers-ID: %lu\n"
-
-#, c-format
-msgid "              imported: %lu"
-msgstr "                    geïmporteerd: %lu"
-
-#, c-format
-msgid "             unchanged: %lu\n"
-msgstr "                     onveranderd: %lu\n"
-
-#, c-format
-msgid "          new user IDs: %lu\n"
-msgstr "          nieuwe gebruikers-ID's: %lu\n"
-
-#, c-format
-msgid "           new subkeys: %lu\n"
-msgstr "              nieuwe subsleutels: %lu\n"
-
-#, c-format
-msgid "        new signatures: %lu\n"
-msgstr "           nieuwe handtekeningen: %lu\n"
-
-#, c-format
-msgid "   new key revocations: %lu\n"
-msgstr "nieuwe intrekkingen van sleutels: %lu\n"
-
-#, c-format
-msgid "      secret keys read: %lu\n"
-msgstr "        gelezen geheime sleutels: %lu\n"
-
-#, c-format
-msgid "  secret keys imported: %lu\n"
-msgstr "  geïmporteerde geheime sleutels: %lu\n"
-
-#, c-format
-msgid " secret keys unchanged: %lu\n"
-msgstr "   ongewijzigde geheime sleutels: %lu\n"
-
-#, c-format
-msgid "          not imported: %lu\n"
-msgstr "               niet geïmporteerd: %lu\n"
-
-#, c-format
-msgid "    signatures cleaned: %lu\n"
-msgstr "     opgeschoonde handtekeningen: %lu\n"
-
-#, c-format
-msgid "      user IDs cleaned: %lu\n"
-msgstr "    opgeschoonde gebruikers-ID's: %lu\n"
-
-#, c-format
-msgid ""
-"WARNING: key %s contains preferences for unavailable\n"
-"algorithms on these user IDs:\n"
-msgstr ""
-"WAARSCHUWING: sleutel %s bevat voorkeuren voor niet-beschikbare\n"
-"algoritmes bij deze gebruikers-ID's:\n"
-
-#, c-format
-msgid "         \"%s\": preference for cipher algorithm %s\n"
-msgstr "         \"%s\": voorkeur voor versleutelingsalgoritme %s\n"
-
-#, c-format
-msgid "         \"%s\": preference for digest algorithm %s\n"
-msgstr "         \"%s\": voorkeur voor hashalgoritme %s\n"
-
-#, c-format
-msgid "         \"%s\": preference for compression algorithm %s\n"
-msgstr "         \"%s\": voorkeur voor compressiealgoritme %s\n"
-
-msgid "it is strongly suggested that you update your preferences and\n"
-msgstr "we raden u sterk aan om uw voorkeuren aan te passen en\n"
-
-msgid "re-distribute this key to avoid potential algorithm mismatch problems\n"
-msgstr ""
-"om deze sleutel opnieuw te distribueren om mogelijke problemen met niet-"
-"overeenstemmende algoritmes te voorkomen\n"
-
-#, c-format
-msgid "you can update your preferences with: gpg --edit-key %s updpref save\n"
-msgstr "u kunt uw voorkeuren bijwerken met: gpg --edit-key %s updpref save\n"
-
-#, c-format
-msgid "key %s: no user ID\n"
-msgstr "sleutel %s: geen gebruikers-ID\n"
-
-#, c-format
-msgid "key %s: %s\n"
-msgstr "sleutel %s: %s\n"
-
-msgid "rejected by import filter"
-msgstr "verworpen door de importfilter"
-
-#, c-format
-msgid "key %s: PKS subkey corruption repaired\n"
-msgstr "sleutel %s: beschadigingen in PKS-subsleutel hersteld\n"
-
-#, c-format
-msgid "key %s: accepted non self-signed user ID \"%s\"\n"
-msgstr "sleutel %s: niet auto-gesigneerde gebruikers-ID \"%s\" aanvaard\n"
-
-#, c-format
-msgid "key %s: no valid user IDs\n"
-msgstr "sleutel %s: geen geldige gebruikers-ID's\n"
-
-msgid "this may be caused by a missing self-signature\n"
-msgstr ""
-"dit kan veroorzaakt worden door het ontbreken van een eigen ondertekening\n"
-
-#, c-format
-msgid "key %s: public key not found: %s\n"
-msgstr "sleutel %s: publieke sleutel niet gevonden: %s\n"
-
-#, c-format
-msgid "key %s: new key - skipped\n"
-msgstr "sleutel %s: nieuwe sleutel - overgeslagen\n"
-
-#, c-format
-msgid "no writable keyring found: %s\n"
-msgstr "geen sleutelring gevonden waarnaartoe geschreven kan worden: %s\n"
-
-#, c-format
-msgid "writing to `%s'\n"
-msgstr "aan het schrijven naar `%s'\n"
-
-#, c-format
-msgid "error writing keyring `%s': %s\n"
-msgstr "fout bij het schrijven naar sleutelring `%s': %s\n"
-
-#, c-format
-msgid "key %s: public key \"%s\" imported\n"
-msgstr "sleutel %s: publieke sleutel \"%s\" geïmporteerd\n"
-
-#, c-format
-msgid "key %s: doesn't match our copy\n"
-msgstr "sleutel %s: stemt niet overeen met onze kopie\n"
-
-#, c-format
-msgid "key %s: can't locate original keyblock: %s\n"
-msgstr "sleutel %s: kan het originele sleutelblok niet vinden: %s\n"
-
-#, c-format
-msgid "key %s: can't read original keyblock: %s\n"
-msgstr "sleutel %s: kan het originele sleutelblok niet lezen: %s\n"
-
-#, c-format
-msgid "key %s: \"%s\" 1 new user ID\n"
-msgstr "sleutel %s: \"%s\" 1 nieuwe gebruikers-ID\n"
-
-#, c-format
-msgid "key %s: \"%s\" %d new user IDs\n"
-msgstr "sleutel %s: \"%s\" %d nieuwe gebruikers-ID's\n"
-
-#, c-format
-msgid "key %s: \"%s\" 1 new signature\n"
-msgstr "sleutel %s: \"%s\" 1 nieuwe ondertekening\n"
-
-#, c-format
-msgid "key %s: \"%s\" %d new signatures\n"
-msgstr "sleutel %s: \"%s\" %d nieuwe ondertekeningen\n"
-
-#, c-format
-msgid "key %s: \"%s\" 1 new subkey\n"
-msgstr "sleutel %s: \"%s\" 1 nieuwe subsleutel\n"
-
-#, c-format
-msgid "key %s: \"%s\" %d new subkeys\n"
-msgstr "sleutel %s: \"%s\" %d nieuwe subsleutels\n"
-
-#, c-format
-msgid "key %s: \"%s\" %d signature cleaned\n"
-msgstr "sleutel %s: \"%s\" %d ondertekening opgeschoond\n"
-
-#, c-format
-msgid "key %s: \"%s\" %d signatures cleaned\n"
-msgstr "sleutel %s: \"%s\" %d ondertekeningen opgeschoond\n"
-
-#, c-format
-msgid "key %s: \"%s\" %d user ID cleaned\n"
-msgstr "sleutel %s: \"%s\" %d gebruikers-ID opgeschoond\n"
-
-#, c-format
-msgid "key %s: \"%s\" %d user IDs cleaned\n"
-msgstr "sleutel %s: \"%s\" %d gebruikers-ID's opgeschoond\n"
-
-#, c-format
-msgid "key %s: \"%s\" not changed\n"
-msgstr "sleutel %s: \"%s\" niet veranderd\n"
-
-#, c-format
-msgid "secret key %s: %s\n"
-msgstr "geheime sleutel %s: %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "importeren van geheime sleutels is niet toegestaan\n"
-
-#, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr ""
-"sleutel %s: geheime sleutel met ongeldig versleutelingsalgoritme %d - "
-"overgeslagen\n"
-
-#, c-format
-msgid "no default secret keyring: %s\n"
-msgstr "geen standaardsleutelring voor geheime sleutels: %s\n"
-
-#, c-format
-msgid "key %s: secret key imported\n"
-msgstr "sleutel %s: geheime sleutel geïmporteerd\n"
-
-#, c-format
-msgid "key %s: already in secret keyring\n"
-msgstr "sleutel %s: reeds in sleutelring van geheime sleutels\n"
-
-#, c-format
-msgid "key %s: secret key not found: %s\n"
-msgstr "sleutel %s: geheime sleutel niet gevonden: %s\n"
-
-#, c-format
-msgid "key %s: no public key - can't apply revocation certificate\n"
-msgstr ""
-"sleutel %s: geen publieke sleutel - kan intrekkingscertificaat niet "
-"toepassen\n"
-
-#, c-format
-msgid "key %s: invalid revocation certificate: %s - rejected\n"
-msgstr "sleutel %s: ongeldig intrekkingscertificaat: %s - afgewezen\n"
-
-#, c-format
-msgid "key %s: \"%s\" revocation certificate imported\n"
-msgstr "sleutel %s: \"%s\" intrekkingscertificaat geïmporteerd\n"
-
-#, c-format
-msgid "key %s: no user ID for signature\n"
-msgstr "sleutel %s: geen gebruikers-ID voor ondertekening\n"
-
-#, c-format
-msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
-msgstr ""
-"sleutel %s: niet ondersteund publieke-sleutelalgoritme voor gebruikers-ID "
-"\"%s\"\n"
-
-#, c-format
-msgid "key %s: invalid self-signature on user ID \"%s\"\n"
-msgstr "sleutel %s: ongeldige eigen ondertekening bij gebruikers-ID \"%s\"\n"
-
-#, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "sleutel %s: niet ondersteund publieke-sleutelalgoritme\n"
-
-#, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "sleutel %s: ongeldige rechtstreekse ondertekening van de sleutel\n"
-
-#, c-format
-msgid "key %s: no subkey for key binding\n"
-msgstr "sleutel %s: geen subsleutel voor de koppeling met de sleutel\n"
-
-#, c-format
-msgid "key %s: invalid subkey binding\n"
-msgstr "sleutel %s: ongeldige koppeling met de subsleutel\n"
-
-#, c-format
-msgid "key %s: removed multiple subkey binding\n"
-msgstr "sleutel %s: meervoudige koppeling met de subsleutel verwijderd\n"
-
-#, c-format
-msgid "key %s: no subkey for key revocation\n"
-msgstr "sleutel %s: geen subsleutel voor het intrekken van de sleutel\n"
-
-#, c-format
-msgid "key %s: invalid subkey revocation\n"
-msgstr "sleutel %s: ongeldige intrekking van subsleutel\n"
-
-#, c-format
-msgid "key %s: removed multiple subkey revocation\n"
-msgstr "sleutel %s: meervoudige intrekking van de subsleutel verwijderd\n"
-
-#, c-format
-msgid "key %s: skipped user ID \"%s\"\n"
-msgstr "sleutel %s: gebruikers-ID \"%s\" overgeslagen\n"
-
-#, c-format
-msgid "key %s: skipped subkey\n"
-msgstr "sleutel %s: subsleutel overgeslagen\n"
-
-#, c-format
-msgid "key %s: non exportable signature (class 0x%02X) - skipped\n"
-msgstr ""
-"sleutel %s: ondertekening (klasse 0x%02X) kan niet geëxporteerd worden - "
-"overgeslagen\n"
-
-#, c-format
-msgid "key %s: revocation certificate at wrong place - skipped\n"
-msgstr "sleutel %s: intrekkingscertificaat op verkeerde plek - overgeslagen\n"
-
-#, c-format
-msgid "key %s: invalid revocation certificate: %s - skipped\n"
-msgstr "sleutel %s: ongeldig intrekkingscertificaat: %s - overgeslagen\n"
-
-#, c-format
-msgid "key %s: subkey signature in wrong place - skipped\n"
-msgstr ""
-"sleutel %s: ondertekening van subsleutel op de verkeerde plek - "
-"overgeslagen\n"
-
-#, c-format
-msgid "key %s: unexpected signature class (0x%02X) - skipped\n"
-msgstr "sleutel %s: onverwachte ondertekening klasse (0x%02X) - overgeslagen\n"
-
-#, c-format
-msgid "key %s: duplicated user ID detected - merged\n"
-msgstr "sleutel %s: duplicaat van gebruikers-ID gevonden - samengevoegd\n"
-
-#, c-format
-msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
-msgstr ""
-"WAARSCHUWING: sleutel %s kan ingetrokken zijn: ophalen intrekkingssleutel "
-"%s\n"
-
-#, c-format
-msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
-msgstr ""
-"WAARSCHUWING: sleutel %s kan ingetrokken zijn: intrekkingssleutel %s niet "
-"aanwezig.\n"
-
-#, c-format
-msgid "key %s: \"%s\" revocation certificate added\n"
-msgstr "sleutel %s: \"%s\" intrekkingscertificaat toegevoegd\n"
-
-#, c-format
-msgid "key %s: direct key signature added\n"
-msgstr "sleutel %s: directe ondertekening van de sleutel toegevoegd\n"
-
-msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr ""
-"NOOT: een serienummer van een sleutel stemt niet overeen met die van de "
-"kaart\n"
-
-msgid "NOTE: primary key is online and stored on card\n"
-msgstr "NOOT: primaire sleutel is online en opgeslagen op de kaart\n"
-
-msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "NOOT: secundaire sleutel is online en opgeslagen op de kaart\n"
-
-#, c-format
-msgid "error creating keyring `%s': %s\n"
-msgstr "fout bij het aanmaken van de sleutelring `%s': %s\n"
-
-#, c-format
-msgid "keyring `%s' created\n"
-msgstr "sleutelring `%s' is aangemaakt\n"
-
-#, c-format
-msgid "keyblock resource `%s': %s\n"
-msgstr "bron van de sleutelblok `%s': %s\n"
-
-#, c-format
-msgid "failed to rebuild keyring cache: %s\n"
-msgstr "de cache van de sleutelring opnieuw bouwen is mislukt: %s\n"
-
-msgid "[revocation]"
-msgstr "[intrekking]"
-
-msgid "[self-signature]"
-msgstr "[eigen ondertekening]"
-
-msgid "1 bad signature\n"
-msgstr "1 slechte ondertekening\n"
-
-#, c-format
-msgid "%d bad signatures\n"
-msgstr "%d slechte ondertekeningen\n"
-
-msgid "1 signature not checked due to a missing key\n"
-msgstr ""
-"1 ondertekening werd niet gecontroleerd wegens een ontbrekende sleutel\n"
-
-#, c-format
-msgid "%d signatures not checked due to missing keys\n"
-msgstr ""
-"%d ondertekeningen werden niet gecontroleerd wegens ontbrekende sleutels\n"
-
-msgid "1 signature not checked due to an error\n"
-msgstr "1 ondertekening werd niet gecontroleerd wegens een fout\n"
-
-#, c-format
-msgid "%d signatures not checked due to errors\n"
-msgstr "%d ondertekeningen werden niet gecontroleerd wegens fouten\n"
-
-msgid "1 user ID without valid self-signature detected\n"
-msgstr "1 gebruikers-ID gevonden zonder geldige eigen handtekening\n"
-
-#, c-format
-msgid "%d user IDs without valid self-signatures detected\n"
-msgstr "%d gebruikers-ID's gevonden zonder geldige eigen handtekening\n"
-
-msgid ""
-"Please decide how far you trust this user to correctly verify other users' "
-"keys\n"
-"(by looking at passports, checking fingerprints from different sources, "
-"etc.)\n"
-msgstr ""
-"Geef aan in welke mate u er op vertrouwt dat deze gebruiker de sleutels van "
-"andere gebruikers op correcte wijze controleert\n"
-"(door het paspoort te bekijken, vingerafdrukken uit verschillende bronnen te "
-"checken, enz.)\n"
-
-#, c-format
-msgid "  %d = I trust marginally\n"
-msgstr "  %d = Ik vertrouw het maar marginaal\n"
-
-#, c-format
-msgid "  %d = I trust fully\n"
-msgstr "  %d = Ik vertrouw het volledig\n"
-
-msgid ""
-"Please enter the depth of this trust signature.\n"
-"A depth greater than 1 allows the key you are signing to make\n"
-"trust signatures on your behalf.\n"
-msgstr ""
-"Geef aan hoe groot het vertrouwen mag zijn in deze betrouwbare "
-"handtekening.\n"
-"Als de waarde groter dan 1 is, stelt u de sleutel die u ondertekent, in de\n"
-"mogelijkheid om in uw plaats handtekeningen van vertrouwen te plaatsen.\n"
-
-msgid "Please enter a domain to restrict this signature, or enter for none.\n"
-msgstr ""
-"Voer een domein in als u de geldigheid van de handtekening daartoe wilt "
-"beperken, laat leeg voor geen beperking.\n"
-
-#, c-format
-msgid "User ID \"%s\" is revoked."
-msgstr "Gebruikers-ID \"%s\" is ingetrokken."
-
-msgid "Are you sure you still want to sign it? (y/N) "
-msgstr "Weet U zeker dat U die nog steeds wilt ondertekenen? (j/N) "
-
-msgid "  Unable to sign.\n"
-msgstr "  Ondertekenen is niet mogelijk.\n"
-
-#, c-format
-msgid "User ID \"%s\" is expired."
-msgstr "Gebruikers-ID \"%s\" is vervallen."
-
-#, c-format
-msgid "User ID \"%s\" is not self-signed."
-msgstr "Gebruikers-ID \"%s\" is niet auto-gesigneerd."
-
-#, c-format
-msgid "User ID \"%s\" is signable.  "
-msgstr "Gebruikers-ID \"%s\" kan ondertekend worden.  "
-
-msgid "Sign it? (y/N) "
-msgstr "Ondertekenen? (j/N) "
-
-#, c-format
-msgid ""
-"The self-signature on \"%s\"\n"
-"is a PGP 2.x-style signature.\n"
-msgstr ""
-"De eigen ondertekening van \"%s\"\n"
-"is een ondertekening van het type PGP 2.x.\n"
-
-msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) "
-msgstr ""
-"Wilt u ze opwaarderen tot een eigen ondertekening van het type OpenPGP? (j/"
-"N) "
-
-#, c-format
-msgid ""
-"Your current signature on \"%s\"\n"
-"has expired.\n"
-msgstr ""
-"Uw huidige ondertekening op \"%s\"\n"
-"is verlopen.\n"
-
-msgid "Do you want to issue a new signature to replace the expired one? (y/N) "
-msgstr ""
-"Wilt U een nieuwe ondertekening uitgeven om de vervallen te vervangen ? (j/"
-"N) "
-
-#, c-format
-msgid ""
-"Your current signature on \"%s\"\n"
-"is a local signature.\n"
-msgstr ""
-"Uw huidige ondertekening op \"%s\"\n"
-"is een lokale ondertekening.\n"
-
-msgid "Do you want to promote it to a full exportable signature? (y/N) "
-msgstr ""
-"Wilt u ze opwaarderen naar een ondertekening die volledig exporteerbaar is? "
-"(j/N) "
-
-#, c-format
-msgid "\"%s\" was already locally signed by key %s\n"
-msgstr "\"%s\" was reeds lokaal ondertekend met sleutel %s\n"
-
-#, c-format
-msgid "\"%s\" was already signed by key %s\n"
-msgstr "\"%s\" was reeds ondertekend met sleutel %s\n"
-
-msgid "Do you want to sign it again anyway? (y/N) "
-msgstr "Wilt u die toch opnieuw ondertekenen? (j/N) "
-
-#, c-format
-msgid "Nothing to sign with key %s\n"
-msgstr "Er valt niets te ondertekenen met sleutel %s\n"
-
-msgid "This key has expired!"
-msgstr "Deze sleutel is verlopen!"
-
-#, c-format
-msgid "This key is due to expire on %s.\n"
-msgstr "Deze sleutel zal vervallen op %s.\n"
-
-msgid "Do you want your signature to expire at the same time? (Y/n) "
-msgstr "Wilt u uw handtekening op hetzelfde moment laten vervallen? (J/n) "
-
-msgid ""
-"You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
-"mode.\n"
-msgstr ""
-"U mag geen OpenPGP-ondertekening zetten bij een sleutel van het type PGP 2.x "
-"als u de modus --pgp2 gebruikt.\n"
-
-msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "Dit zou de sleutel onbruikbaar maken met PGP 2.x.\n"
-
-msgid ""
-"How carefully have you verified the key you are about to sign actually "
-"belongs\n"
-"to the person named above?  If you don't know what to answer, enter \"0\".\n"
-msgstr ""
-"Hoe zorgvuldig heeft u gecontroleerd dat de sleutel die u gaat ondertekenen\n"
-"werkelijk van de hiervoor genoemde persoon is? Indien u niet goed weet wat\n"
-"te antwoorden, geef dan \"0\" op\n"
-
-#, c-format
-msgid "   (0) I will not answer.%s\n"
-msgstr "   (0) Hierop geef ik geen antwoord.%s\n"
-
-#, c-format
-msgid "   (1) I have not checked at all.%s\n"
-msgstr "   (1) Ik heb dit helemaal niet gecontroleerd.%s\n"
-
-#, c-format
-msgid "   (2) I have done casual checking.%s\n"
-msgstr "   (2) Ik heb een oppervlakkige controle uitgevoerd.%s\n"
-
-#, c-format
-msgid "   (3) I have done very careful checking.%s\n"
-msgstr "   (3) Ik heb dit zeer zorgvuldig gecontroleerd.%s\n"
-
-msgid "Your selection? (enter `?' for more information): "
-msgstr "Uw keuze? (type `?' voor meer informatie): "
-
-#, c-format
-msgid ""
-"Are you sure that you want to sign this key with your\n"
-"key \"%s\" (%s)\n"
-msgstr ""
-"Weet u zeker dat u deze sleutel wilt ondertekenen met uw\n"
-"sleutel \"%s\" (%s)\n"
-
-msgid "This will be a self-signature.\n"
-msgstr "Dit zal een eigen ondertekening zijn.\n"
-
-msgid "WARNING: the signature will not be marked as non-exportable.\n"
-msgstr ""
-"WAARSCHUWING: de ondertekening zal niet als niet-exporteerbaar\n"
-"              worden gemarkeerd.\n"
-
-msgid "WARNING: the signature will not be marked as non-revocable.\n"
-msgstr ""
-"WAARSCHUWING: de ondertekening zal niet als niet in te trekken\n"
-"              worden gemarkeerd.\n"
-
-msgid "The signature will be marked as non-exportable.\n"
-msgstr "De ondertekening zal als niet-exporteerbaar gemarkeerd worden.\n"
-
-msgid "The signature will be marked as non-revocable.\n"
-msgstr "De ondertekening zal als niet in te trekken gemarkeerd worden.\n"
-
-msgid "I have not checked this key at all.\n"
-msgstr "Ik heb deze sleutel helemaal niet gecontroleerd.\n"
-
-msgid "I have checked this key casually.\n"
-msgstr "Ik heb deze sleutel oppervlakkig gecontroleerd.\n"
-
-msgid "I have checked this key very carefully.\n"
-msgstr "Ik heb deze sleutel zeer zorgvuldig gecontroleerd.\n"
-
-msgid "Really sign? (y/N) "
-msgstr "Echt ondertekenen? (j/N) "
-
-#, c-format
-msgid "signing failed: %s\n"
-msgstr "ondertekenen is mislukt: %s\n"
-
-msgid "Key has only stub or on-card key items - no passphrase to change.\n"
-msgstr ""
-"Deze sleutel bevat slechts partiële of op de kaart opgeslagen elementen - er "
-"is geen wachtwoordzin die veranderd kan worden.\n"
-
-msgid "This key is not protected.\n"
-msgstr "Deze sleutel is niet beveiligd.\n"
-
-msgid "Secret parts of primary key are not available.\n"
-msgstr "Geheime delen van de primaire sleutel zijn niet beschikbaar.\n"
-
-msgid "Secret parts of primary key are stored on-card.\n"
-msgstr "Geheime delen van de primaire sleutel staan opgeslagen op de kaart.\n"
-
-msgid "Key is protected.\n"
-msgstr "Sleutel is beveiligd.\n"
-
-#, c-format
-msgid "Can't edit this key: %s\n"
-msgstr "Deze sleutel kan niet bewerkt worden: %s\n"
-
-msgid ""
-"Enter the new passphrase for this secret key.\n"
-"\n"
-msgstr ""
-"Voer de nieuwe wachtwoordzin voor deze geheime sleutel in.\n"
-"\n"
-
-msgid "passphrase not correctly repeated; try again"
-msgstr "de wachtwoordzin is niet twee keer dezelfde; probeer opnieuw"
-
-msgid ""
-"You don't want a passphrase - this is probably a *bad* idea!\n"
-"\n"
-msgstr ""
-"U wilt geen wachtwoordzin - Dit is wellicht een *slecht* idee!\n"
-"\n"
-
-msgid "Do you really want to do this? (y/N) "
-msgstr "Wilt u dit echt doen? (j/N) "
-
-msgid "moving a key signature to the correct place\n"
-msgstr ""
-"de ondertekening van de sleutel wordt naar de juiste plaats verplaatst\n"
-
-msgid "save and quit"
-msgstr "opslaan en stoppen"
-
-msgid "show key fingerprint"
-msgstr "toon de vingerafdruk van de sleutel"
-
-msgid "list key and user IDs"
-msgstr "toon sleutel en gebruikers-ID's"
-
-msgid "select user ID N"
-msgstr "selecteer gebruikers-ID N"
-
-msgid "select subkey N"
-msgstr "selecteer subsleutel N"
-
-msgid "check signatures"
-msgstr "controleer handtekeningen"
-
-msgid "sign selected user IDs [* see below for related commands]"
-msgstr ""
-"onderteken geselecteerde gebruikers-ID's [* zie hieronder voor gerelateerde "
-"commando's]"
-
-msgid "sign selected user IDs locally"
-msgstr "onderteken geselecteerde gebruikers-ID's lokaal"
-
-msgid "sign selected user IDs with a trust signature"
-msgstr ""
-"onderteken geselecteerde gebruikers-ID's met een handtekening van vertrouwen"
-
-msgid "sign selected user IDs with a non-revocable signature"
-msgstr ""
-"onderteken geselecteerde gebruikers-ID's met een handtekening die niet "
-"ingetrokken kan worden"
-
-msgid "add a user ID"
-msgstr "voeg een gebruikers-ID toe"
-
-msgid "add a photo ID"
-msgstr "voeg een identiteitsfoto toe"
-
-msgid "delete selected user IDs"
-msgstr "verwijder geselecteerde gebruikers-ID's"
-
-msgid "add a subkey"
-msgstr "voeg een subsleutel toe"
-
-msgid "add a key to a smartcard"
-msgstr "voeg een sleutel toe op een chipkaart"
-
-msgid "move a key to a smartcard"
-msgstr "verplaats een sleutel naar een chipkaart"
-
-msgid "move a backup key to a smartcard"
-msgstr "verplaats een reservesleutel naar een chipkaart"
-
-msgid "delete selected subkeys"
-msgstr "verwijder de geselecteerde subsleutels"
-
-msgid "add a revocation key"
-msgstr "voeg een intrekkingssleutel toe"
-
-msgid "delete signatures from the selected user IDs"
-msgstr "verwijder ondertekeningen van de geselecteerde gebruikers-ID's"
-
-msgid "change the expiration date for the key or selected subkeys"
-msgstr "verander de vervaldatum van de sleutel of de geselecteerde subsleutels"
-
-msgid "flag the selected user ID as primary"
-msgstr "markeer de geselecteerde gebruikers-ID als primair"
-
-msgid "toggle between the secret and public key listings"
-msgstr "wissel tussen de lijst met geheime en die met publieke sleutels"
-
-msgid "list preferences (expert)"
-msgstr "toon voorkeuren (expert)"
-
-msgid "list preferences (verbose)"
-msgstr "toon voorkeuren (uitvoerig)"
-
-msgid "set preference list for the selected user IDs"
-msgstr "stel de lijst met voorkeuren in voor de geselecteerde gebruikers-ID's"
-
-msgid "set the preferred keyserver URL for the selected user IDs"
-msgstr ""
-"stel de URL in van de voorkeurssleutelserver voor de geselecteerde "
-"gebruikers-ID's"
-
-msgid "set a notation for the selected user IDs"
-msgstr "stel een notatie in voor de geselecteerde gebruikers-ID's"
-
-msgid "change the passphrase"
-msgstr "wijzig de wachtwoordzin"
-
-msgid "change the ownertrust"
-msgstr "wijzig de betrouwbaarheidsinformatie"
-
-msgid "revoke signatures on the selected user IDs"
-msgstr "trek de handtekeningen op de geselecteerde gebruikers-ID's in"
-
-msgid "revoke selected user IDs"
-msgstr "trek de geselecteerde gebruikers-ID's in"
-
-msgid "revoke key or selected subkeys"
-msgstr "trek de sleutel of de geselecteerde subsleutels in"
-
-msgid "enable key"
-msgstr "activeer de sleutel"
-
-msgid "disable key"
-msgstr "deactiveer de sleutel"
-
-msgid "show selected photo IDs"
-msgstr "toon de geselecteerde identiteitsfoto's"
-
-msgid "compact unusable user IDs and remove unusable signatures from key"
-msgstr ""
-"comprimeer onbruikbare gebruikers-ID's en verwijder onbruikbare "
-"handtekeningen van de sleutel"
-
-msgid "compact unusable user IDs and remove all signatures from key"
-msgstr ""
-"comprimeer onbruikbare gebruikers-ID's en verwijder alle handtekeningen van "
-"de sleutel"
-
-#, c-format
-msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "fout bij het lezen van het geheime sleutelblok \"%s\": %s\n"
-
-msgid "Secret key is available.\n"
-msgstr "Geheime sleutel is beschikbaar.\n"
-
-msgid "Need the secret key to do this.\n"
-msgstr "Hiervoor is de geheime sleutel nodig.\n"
-
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Gebruik eerst het commando \"toggle\" (wisselen).\n"
-
-msgid ""
-"* The `sign' command may be prefixed with an `l' for local signatures "
-"(lsign),\n"
-"  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
-"  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
-msgstr ""
-"* Het commando `sign' (ondertekenen) kan worden voorafgegaan door een\n"
-"  `l' (lsign) om een lokale ondertekening te maken, een `t' (tsign) om een\n"
-"  handtekening van vertrouwen te plaatsen, een `nr' (nrsign) om een\n"
-"  niet-intrekbare handtekening te zetten, of om het even welke combinatie\n"
-"  hiervan (ltsign, tnrsign, enz.).\n"
-
-msgid "Key is revoked."
-msgstr "Sleutel werd ingetrokken."
-
-msgid "Really sign all user IDs? (y/N) "
-msgstr "Echt alle gebruikers-ID's ondertekenen? (j/N) "
-
-msgid "Hint: Select the user IDs to sign\n"
-msgstr "Hint: Selecteer de gebruikers-ID's die U wilt ondertekenen\n"
-
-#, c-format
-msgid "Unknown signature type `%s'\n"
-msgstr "Onbekend ondertekeningstype ‘%s’\n"
-
-#, c-format
-msgid "This command is not allowed while in %s mode.\n"
-msgstr "Dit commando is niet toegestaan in %s-modus.\n"
-
-msgid "You must select at least one user ID.\n"
-msgstr "U moet minimaal één gebruikers-ID selecteren.\n"
-
-msgid "You can't delete the last user ID!\n"
-msgstr "U kunt de laatste gebruikers-ID niet verwijderen!\n"
-
-msgid "Really remove all selected user IDs? (y/N) "
-msgstr "Werkelijk alle geselecteerde gebruikers-ID's verwijderen? (j/N) "
-
-msgid "Really remove this user ID? (y/N) "
-msgstr "Wilt u deze gebruikers-ID echt verwijderen? (j/N) "
-
-#. TRANSLATORS: Please take care: This is about
-#. moving the key and not about removing it.
-msgid "Really move the primary key? (y/N) "
-msgstr "Wilt u echt de primaire sleutel verplaatsen? (j/N) "
-
-msgid "You must select exactly one key.\n"
-msgstr "U moet exact één sleutel selecteren.\n"
-
-msgid "Command expects a filename argument\n"
-msgstr "Commando verwacht een bestandsnaam als argument\n"
-
-#, c-format
-msgid "Can't open `%s': %s\n"
-msgstr "Kan `%s' niet openen: %s\n"
-
-#, c-format
-msgid "Error reading backup key from `%s': %s\n"
-msgstr "Fout bij het lezen van reservesleutel van `%s': %s\n"
-
-msgid "You must select at least one key.\n"
-msgstr "U moet minimaal één sleutel selecteren.\n"
-
-msgid "Do you really want to delete the selected keys? (y/N) "
-msgstr "Wilt u de geselecteerde sleutels echt wissen? (j/N) "
-
-msgid "Do you really want to delete this key? (y/N) "
-msgstr "Wilt u deze sleutel echt wissen? (j/N) "
-
-msgid "Really revoke all selected user IDs? (y/N) "
-msgstr "Wilt u alle geselecteerde gebruikers-ID's echt intrekken? (j/N) "
-
-msgid "Really revoke this user ID? (y/N) "
-msgstr "Wilt u deze gebruikers-ID echt intrekken? (j/N) "
-
-msgid "Do you really want to revoke the entire key? (y/N) "
-msgstr "Wilt u echt de volledige sleutel intrekken? (j/N) "
-
-msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgstr "Wilt U de geselecteerde subsleutels echt intrekken? (j/N) "
-
-msgid "Do you really want to revoke this subkey? (y/N) "
-msgstr "Wilt U deze subsleutel echt intrekken? (j/N) "
-
-msgid "Owner trust may not be set while using a user provided trust database\n"
-msgstr ""
-"Betrouwbaarheidsinformatie kan niet ingesteld worden wanneer gebruik\n"
-"gemaakt wordt van een door een gebruiker zelf verstrekte vertrouwenslijst\n"
-
-msgid "Set preference list to:\n"
-msgstr "Stel voorkeurenlijst in op:\n"
-
-msgid "Really update the preferences for the selected user IDs? (y/N) "
-msgstr ""
-"De voorkeuren voor de geselecteerde gebruikers-ID's echt aanpassen? (j/N) "
-
-msgid "Really update the preferences? (y/N) "
-msgstr "De voorkeuren echt aanpassen? (j/N) "
-
-msgid "Save changes? (y/N) "
-msgstr "Aanpassingen opslaan? (j/N) "
-
-msgid "Quit without saving? (y/N) "
-msgstr "Stoppen zonder opslaan? (j/N) "
-
-#, c-format
-msgid "update failed: %s\n"
-msgstr "aanpassen is mislukt: %s\n"
-
-#, c-format
-msgid "update secret failed: %s\n"
-msgstr "aanpassen van geheime gedeelte is mislukt: %s\n"
-
-msgid "Key not changed so no update needed.\n"
-msgstr "Sleutel is niet veranderd, dus er is geen aanpassing nodig.\n"
-
-msgid "Digest: "
-msgstr "Hashing: "
-
-msgid "Features: "
-msgstr "Functies: "
-
-msgid "Keyserver no-modify"
-msgstr "Sleutelserver zonder wijziging"
-
-msgid "Preferred keyserver: "
-msgstr "Voorkeurssleutelserver: "
-
-msgid "Notations: "
-msgstr "Notaties: "
-
-msgid "There are no preferences on a PGP 2.x-style user ID.\n"
-msgstr "Een gebruikers-ID in een formaat PGP 2.x kent geen voorkeuren.\n"
-
-#, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "De volgende sleutel werd ingetrokken op %s door %s sleutel %s\n"
-
-#, c-format
-msgid "This key may be revoked by %s key %s"
-msgstr "Deze sleutel kan ingetrokken zijn door %s sleutel %s"
-
-msgid "(sensitive)"
-msgstr "(gevoelig)"
-
-#, c-format
-msgid "created: %s"
-msgstr "aangemaakt op: %s"
-
-#, c-format
-msgid "revoked: %s"
-msgstr "ingetrokken op: %s"
-
-#, c-format
-msgid "expired: %s"
-msgstr "verlopen op: %s"
-
-#, c-format
-msgid "expires: %s"
-msgstr "vervaldatum: %s"
-
-#, c-format
-msgid "usage: %s"
-msgstr "gebruik: %s"
-
-#, c-format
-msgid "trust: %s"
-msgstr "betrouwbaarheid: %s"
-
-#, c-format
-msgid "validity: %s"
-msgstr "geldigheid: %s"
-
-msgid "This key has been disabled"
-msgstr "Deze sleutel werd uitgeschakeld"
-
-msgid "card-no: "
-msgstr "kaartnummer: "
-
-msgid ""
-"Please note that the shown key validity is not necessarily correct\n"
-"unless you restart the program.\n"
-msgstr ""
-"Houd er rekening mee dat de getoonde geldigheid van de sleutel niet\n"
-"noodzakelijk correct is, tenzij u de applicatie herstart.\n"
-
-msgid "revoked"
-msgstr "ingetrokken"
-
-msgid "expired"
-msgstr "verlopen"
-
-msgid ""
-"WARNING: no user ID has been marked as primary.  This command may\n"
-"              cause a different user ID to become the assumed primary.\n"
-msgstr ""
-"WAARSCHUWING: Er werd geen gebruikers-ID als primair gemarkeerd. Door dit\n"
-"              programma te gebruiken kan er een andere gebruikers-ID de\n"
-"              veronderstelde primaire ID worden.\n"
-
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr "Waarschuwing: Uw subsleutel voor versleutelen vervalt weldra.\n"
-
-msgid "You may want to change its expiration date too.\n"
-msgstr "Misschien wilt u ook zijn vervaldatum wijzigen.\n"
-
-msgid ""
-"WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
-"versions\n"
-"         of PGP to reject this key.\n"
-msgstr ""
-"WAARSCHUWING: Dit is een sleutel in PGP2-formaat. Het toevoegen van een\n"
-"              identiteitsfoto kan er voor zorgen dat sommige versies van "
-"PGP\n"
-"              deze sleutel zullen verwerpen.\n"
-
-msgid "Are you sure you still want to add it? (y/N) "
-msgstr "Weet U zeker dat u die nog steeds wilt toevoegen? (j/N) "
-
-msgid "You may not add a photo ID to a PGP2-style key.\n"
-msgstr ""
-"U kunt geen identiteitsfoto toevoegen aan een sleutel in PGP2-formaat.\n"
-
-msgid "Delete this good signature? (y/N/q)"
-msgstr "Deze goede handtekening verwijderen? (j/N/s)"
-
-msgid "Delete this invalid signature? (y/N/q)"
-msgstr "Deze ongeldige handtekening verwijderen? (j/N/s)"
-
-msgid "Delete this unknown signature? (y/N/q)"
-msgstr "Deze onbekende handtekening verwijderen? (j/N/s)"
-
-msgid "Really delete this self-signature? (y/N)"
-msgstr "Deze eigen handtekening echt verwijderen? (j/N)"
-
-#, c-format
-msgid "Deleted %d signature.\n"
-msgstr "%d handtekening verwijderd.\n"
-
-#, c-format
-msgid "Deleted %d signatures.\n"
-msgstr "%d handtekeningen verwijderd.\n"
-
-msgid "Nothing deleted.\n"
-msgstr "Niets verwijderd.\n"
-
-msgid "invalid"
-msgstr "ongeldig"
-
-#, c-format
-msgid "User ID \"%s\" compacted: %s\n"
-msgstr "Gebruikers-ID \"%s\" is gecomprimeerd: %s\n"
-
-#, c-format
-msgid "User ID \"%s\": %d signature removed\n"
-msgstr "Gebruikers-ID \"%s\": %d handtekening verwijderd\n"
-
-#, c-format
-msgid "User ID \"%s\": %d signatures removed\n"
-msgstr "Gebruikers-ID \"%s\": %d handtekeningen verwijderd\n"
-
-#, c-format
-msgid "User ID \"%s\": already minimized\n"
-msgstr "Gebruikers-ID \"%s\": reeds geminimaliseerd\n"
-
-#, c-format
-msgid "User ID \"%s\": already clean\n"
-msgstr "Gebruikers-ID \"%s\": reeds opgeschoond\n"
-
-msgid ""
-"WARNING: This is a PGP 2.x-style key.  Adding a designated revoker may "
-"cause\n"
-"         some versions of PGP to reject this key.\n"
-msgstr ""
-"WAARSCHUWING: Dit is een sleutel van het type PGP 2.x. Het toevoegen van "
-"een\n"
-"              bevoegde intrekker kan er voor zorgen dat sommige PGP-versies\n"
-"              deze sleutel zullen verwerpen.\n"
-
-msgid "You may not add a designated revoker to a PGP 2.x-style key.\n"
-msgstr ""
-"U mag geen bevoegde intrekker toevoegen aan een sleutel van het type PGP 2."
-"x.\n"
-
-msgid "Enter the user ID of the designated revoker: "
-msgstr "Geef de gebruikers-ID van de bevoegde intrekker: "
-
-msgid "cannot appoint a PGP 2.x style key as a designated revoker\n"
-msgstr ""
-"kan geen sleutel van het type PGP 2.x aanstellen als bevoegde intrekker\n"
-
-msgid "you cannot appoint a key as its own designated revoker\n"
-msgstr "u kunt een sleutel niet aanstellen als zijn eigen bevoegde intrekker\n"
-
-msgid "this key has already been designated as a revoker\n"
-msgstr "deze sleutel is al aangesteld als bevoegde intrekker\n"
-
-msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n"
-msgstr ""
-"WAARSCHUWING: een sleutel aanstellen als bevoegde intrekker kan niet "
-"ongedaan\n"
-"              gemaakt worden!\n"
-
-msgid ""
-"Are you sure you want to appoint this key as a designated revoker? (y/N) "
-msgstr ""
-"Weet u zeker dat u deze sleutel wilt aanstellen als bevoegde intrekker? (j/"
-"N) "
-
-msgid "Please remove selections from the secret keys.\n"
-msgstr "Haal de gekozen onderdelen uit de geheime sleutels.\n"
-
-msgid "Please select at most one subkey.\n"
-msgstr "Selecteer hoogstens één subsleutel.\n"
-
-msgid "Changing expiration time for a subkey.\n"
-msgstr "De vervaldatum van een subsleutel wordt veranderd.\n"
-
-msgid "Changing expiration time for the primary key.\n"
-msgstr "De vervaldatum van de primaire sleutel wordt veranderd.\n"
-
-msgid "You can't change the expiration date of a v3 key\n"
-msgstr "U kunt de vervaldatum van een v3-sleutel niet veranderen\n"
-
-msgid "No corresponding signature in secret ring\n"
-msgstr "Er is geen overeenkomstige ondertekening in de geheime sleutelring\n"
-
-#, c-format
-msgid "signing subkey %s is already cross-certified\n"
-msgstr ""
-"er gebeurde reeds een kruiscertificering van de ondertekening van subsleutel "
-"%s\n"
-
-#, c-format
-msgid "subkey %s does not sign and so does not need to be cross-certified\n"
-msgstr ""
-"subsleutel %s ondertekent niet en heeft dus geen kruiscertificering nodig\n"
-
-msgid "Please select exactly one user ID.\n"
-msgstr "Selecteer exact één gebruikers-ID.\n"
-
-#, c-format
-msgid "skipping v3 self-signature on user ID \"%s\"\n"
-msgstr ""
-"de eigen ondertekening in v3-stijl van gebruikers-ID \"%s\" wordt "
-"overgeslagen\n"
-
-msgid "Enter your preferred keyserver URL: "
-msgstr "Geef de URL van de sleutelserver van uw voorkeur: "
-
-msgid "Are you sure you want to replace it? (y/N) "
-msgstr "Weet u zeker dat u die wilt vervangen? (j/N) "
-
-msgid "Are you sure you want to delete it? (y/N) "
-msgstr "Weet u zeker dat u die wilt verwijderen? (j/N) "
-
-msgid "Enter the notation: "
-msgstr "Voer de notatie in: "
-
-msgid "Proceed? (y/N) "
-msgstr "Doorgaan? (j/N) "
-
-#, c-format
-msgid "No user ID with index %d\n"
-msgstr "Er is geen gebruikers-ID met index %d\n"
-
-#, c-format
-msgid "No user ID with hash %s\n"
-msgstr "Er is geen gebruikers-ID met hash %s\n"
-
-#, c-format
-msgid "No subkey with index %d\n"
-msgstr "Er is geen subsleutel met index %d\n"
-
-#, c-format
-msgid "user ID: \"%s\"\n"
-msgstr "gebruikers-ID: \"%s\"\n"
-
-#, c-format
-msgid "signed by your key %s on %s%s%s\n"
-msgstr "ondertekend met uw sleutel %s op %s%s%s\n"
-
-msgid " (non-exportable)"
-msgstr " (niet exporteerbaar)"
-
-#, c-format
-msgid "This signature expired on %s.\n"
-msgstr "Deze ondertekening is verlopen op %s.\n"
-
-msgid "Are you sure you still want to revoke it? (y/N) "
-msgstr "Weet u zeker dat u die nog altijd wilt intrekken? (j/N) "
-
-msgid "Create a revocation certificate for this signature? (y/N) "
-msgstr "Een intrekkingscertificaat voor deze ondertekening aanmaken? (j/N) "
-
-msgid "Not signed by you.\n"
-msgstr "Niet door u ondertekend.\n"
-
-#, c-format
-msgid "You have signed these user IDs on key %s:\n"
-msgstr "U heeft deze gebruikers-ID's op sleutel %s ondertekend:\n"
-
-msgid " (non-revocable)"
-msgstr " (niet intrekbaar)"
-
-#, c-format
-msgid "revoked by your key %s on %s\n"
-msgstr "ingetrokken door uw sleutel %s op %s\n"
-
-msgid "You are about to revoke these signatures:\n"
-msgstr "U staat op het punt deze ondertekeningen in te trekken:\n"
-
-msgid "Really create the revocation certificates? (y/N) "
-msgstr "Wilt u deze intrekkingscertificaten echt aanmaken? (j/N) "
-
-msgid "no secret key\n"
-msgstr "geen geheime sleutel\n"
-
-#, c-format
-msgid "user ID \"%s\" is already revoked\n"
-msgstr "gebruikers-ID \"%s\" is reeds ingetrokken\n"
-
-#, c-format
-msgid "WARNING: a user ID signature is dated %d seconds in the future\n"
-msgstr ""
-"WAARSCHUWING: de ondertekening van een gebruikers-ID\n"
-"              is %d seconden in de toekomst gedateerd\n"
-
-#, c-format
-msgid "Key %s is already revoked.\n"
-msgstr "Sleutel %s is reeds ingetrokken.\n"
-
-#, c-format
-msgid "Subkey %s is already revoked.\n"
-msgstr "Subsleutel %s is reeds ingetrokken.\n"
-
-#, c-format
-msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
-msgstr ""
-"%s identiteitsfoto van formaat %ld voor sleutel %s (gebruikers-ID %d) wordt "
-"getoond\n"
-
-#, c-format
-msgid "preference `%s' duplicated\n"
-msgstr "voorkeur `%s' heeft duplicaat\n"
-
-msgid "too many cipher preferences\n"
-msgstr "te veel voorkeursinstellingen voor versleuteling\n"
-
-msgid "too many digest preferences\n"
-msgstr "te veel voorkeursinstellingen voor hashing\n"
-
-msgid "too many compression preferences\n"
-msgstr "te veel voorkeursinstellingen voor compressie\n"
-
-#, c-format
-msgid "invalid item `%s' in preference string\n"
-msgstr "ongeldig item `%s' in voorkeursinstellingen\n"
-
-msgid "writing direct signature\n"
-msgstr "directe ondertekening wordt weggeschreven\n"
-
-msgid "writing self signature\n"
-msgstr "eigen handtekening wordt weggeschreven\n"
-
-msgid "writing key binding signature\n"
-msgstr "de ondertekening van de koppeling met de sleutel wordt weggeschreven\n"
-
-#, c-format
-msgid "keysize invalid; using %u bits\n"
-msgstr "sleutelgrootte is ongeldig; %u bit wordt gebruikt\n"
-
-#, c-format
-msgid "keysize rounded up to %u bits\n"
-msgstr "sleutelgrootte afgerond op %u bits\n"
-
-msgid ""
-"WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n"
-msgstr ""
-"WAARSCHUWING: sommige OpenPGP-programma's kunnen niet overweg met een\n"
-"              DSA-sleutel van deze hashgrootte\n"
-
-msgid "Sign"
-msgstr "Ondertekenen"
-
-msgid "Certify"
-msgstr "Certificeren"
-
-msgid "Encrypt"
-msgstr "Versleutelen"
-
-msgid "Authenticate"
-msgstr "Authenticeren"
-
-#. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
-#.
-msgid "SsEeAaQq"
-msgstr "OoVvAaSs"
-
-#, c-format
-msgid "Possible actions for a %s key: "
-msgstr "Mogelijke acties voor een %s-sleutel: "
-
-msgid "Current allowed actions: "
-msgstr "Momenteel toegestane acties: "
-
-#, c-format
-msgid "   (%c) Toggle the sign capability\n"
-msgstr "   (%c) De bekwaamheid om te onderteken activeren/deactiveren\n"
-
-#, c-format
-msgid "   (%c) Toggle the encrypt capability\n"
-msgstr "   (%c) De bekwaamheid om te versleutelen activeren/deactiveren\n"
-
-#, c-format
-msgid "   (%c) Toggle the authenticate capability\n"
-msgstr "   (%c) De bekwaamheid om te authenticeren activeren/deactiveren\n"
-
-#, c-format
-msgid "   (%c) Finished\n"
-msgstr "   (%c) Klaar\n"
-
-msgid "Please select what kind of key you want:\n"
-msgstr "Selecteer het soort sleutel dat u wilt:\n"
-
-#, c-format
-msgid "   (%d) RSA and RSA (default)\n"
-msgstr "   (%d) RSA en RSA (standaard)\n"
-
-#, c-format
-msgid "   (%d) DSA and Elgamal\n"
-msgstr "   (%d) DSA en Elgamal\n"
-
-#, c-format
-msgid "   (%d) DSA (sign only)\n"
-msgstr "   (%d) DSA (alleen ondertekenen)\n"
-
-#, c-format
-msgid "   (%d) RSA (sign only)\n"
-msgstr "   (%d) RSA (alleen ondertekenen)\n"
-
-#, c-format
-msgid "   (%d) Elgamal (encrypt only)\n"
-msgstr "   (%d) Elgamal (alleen versleutelen)\n"
-
-#, c-format
-msgid "   (%d) RSA (encrypt only)\n"
-msgstr "   (%d) RSA (alleen versleutelen)\n"
-
-#, c-format
-msgid "   (%d) DSA (set your own capabilities)\n"
-msgstr "   (%d) DSA (eigen bekwaamheden instellen)\n"
-
-#, c-format
-msgid "   (%d) RSA (set your own capabilities)\n"
-msgstr "   (%d) RSA (eigen bekwaamheden instellen)\n"
-
-#, c-format
-msgid "%s keys may be between %u and %u bits long.\n"
-msgstr "%s-sleutels moeten tussen %u en %u bits lang zijn.\n"
-
-#, c-format
-msgid "What keysize do you want for the subkey? (%u) "
-msgstr "Welke sleutellengte wilt u voor de subsleutel? (%u) "
-
-#, c-format
-msgid "What keysize do you want? (%u) "
-msgstr "Welke sleutellengte wilt u? (%u) "
-
-#, c-format
-msgid "Requested keysize is %u bits\n"
-msgstr "Gevraagde sleutellengte is %u bits\n"
-
-msgid ""
-"Please specify how long the key should be valid.\n"
-"         0 = key does not expire\n"
-"      <n>  = key expires in n days\n"
-"      <n>w = key expires in n weeks\n"
-"      <n>m = key expires in n months\n"
-"      <n>y = key expires in n years\n"
-msgstr ""
-"Geef aan hoe lang de sleutel geldig moet zijn.\n"
-"         0 = sleutel verloopt nooit\n"
-"      <n>  = sleutel verloopt na n dagen\n"
-"      <n>w = sleutel verloopt na n weken\n"
-"      <n>m = sleutel verloopt na n maanden\n"
-"      <n>y = sleutel verloopt na n jaar\n"
-
-msgid ""
-"Please specify how long the signature should be valid.\n"
-"         0 = signature does not expire\n"
-"      <n>  = signature expires in n days\n"
-"      <n>w = signature expires in n weeks\n"
-"      <n>m = signature expires in n months\n"
-"      <n>y = signature expires in n years\n"
-msgstr ""
-"Geef aan hoe lang de ondertekening geldig moet zijn.\n"
-"         0 = ondertekening verloopt nooit\n"
-"      <n>  = ondertekening verloopt na n dagen\n"
-"      <n>w = ondertekening verloopt na n weken\n"
-"      <n>m = ondertekening verloopt na n maanden\n"
-"      <n>y = ondertekening verloopt na n jaar\n"
-
-msgid "Key is valid for? (0) "
-msgstr "Hoe lang moet de sleutel geldig zijn? (0) "
-
-#, c-format
-msgid "Signature is valid for? (%s) "
-msgstr "Hoe lang moet de ondertekening geldig zijn? (%s) "
-
-msgid "invalid value\n"
-msgstr "ongeldige waarde\n"
-
-msgid "Key does not expire at all\n"
-msgstr "Sleutel verloopt helemaal niet\n"
-
-msgid "Signature does not expire at all\n"
-msgstr "Ondertekening verloopt helemaal niet\n"
-
-#, c-format
-msgid "Key expires at %s\n"
-msgstr "Sleutel vervalt op %s\n"
-
-#, c-format
-msgid "Signature expires at %s\n"
-msgstr "Ondertekening vervalt op %s\n"
-
-msgid ""
-"Your system can't display dates beyond 2038.\n"
-"However, it will be correctly handled up to 2106.\n"
-msgstr ""
-"Uw systeem kan geen datum weergeven na 2038.\n"
-"Data worden echter wel juist verwerkt tot 2106.\n"
-
-msgid "Is this correct? (y/N) "
-msgstr "Is dit correct? (j/N) "
-
-msgid ""
-"\n"
-"GnuPG needs to construct a user ID to identify your key.\n"
-"\n"
-msgstr ""
-"\n"
-"GnuPG moet een gebruikers-ID bouwen ter identificatie van uw sleutel.\n"
-"\n"
-
-#. TRANSLATORS: This string is in general not anymore used
-#. but you should keep your existing translation.  In case
-#. the new string is not translated this old string will
-#. be used.
-msgid ""
-"\n"
-"You need a user ID to identify your key; the software constructs the user "
-"ID\n"
-"from the Real Name, Comment and Email Address in this form:\n"
-"    \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\n"
-"\n"
-msgstr ""
-"\n"
-"U heeft een gebruikers-ID nodig om uw sleutel te identificeren; de software\n"
-"construeert de gebruikers-ID aan de hand van de werkelijke naam, de\n"
-"toelichting en het e-mailadres in het volgende formaat:\n"
-"    \"Heinrich Heine (De dichter) <heinrichh@duesseldorf.de>\"\n"
-"\n"
-
-msgid "Real name: "
-msgstr "Werkelijke naam: "
-
-msgid "Invalid character in name\n"
-msgstr "Ongeldig teken in de naam\n"
-
-msgid "Name may not start with a digit\n"
-msgstr "Een naam mag niet met een cijfer beginnen\n"
-
-msgid "Name must be at least 5 characters long\n"
-msgstr "Een naam moet minimaal 5 tekens lang zijn\n"
-
-msgid "Email address: "
-msgstr "E-mailadres: "
-
-msgid "Not a valid email address\n"
-msgstr "Geen geldig e-mailadres\n"
-
-msgid "Comment: "
-msgstr "Toelichting: "
-
-msgid "Invalid character in comment\n"
-msgstr "Ongeldig teken in de toelichting\n"
-
-#, c-format
-msgid "You are using the `%s' character set.\n"
-msgstr "U gebruikt tekenset `%s'.\n"
-
-#, c-format
-msgid ""
-"You selected this USER-ID:\n"
-"    \"%s\"\n"
-"\n"
-msgstr ""
-"U heeft de volgende GEBRUIKERS-ID gekozen:\n"
-"    \"%s\"\n"
-"\n"
-
-msgid "Please don't put the email address into the real name or the comment\n"
-msgstr ""
-"Plaats het e-mailadres alstublieft niet bij de werkelijke naam of de "
-"toelichting\n"
-
-msgid "Such a user ID already exists on this key!\n"
-msgstr "Een dergelijke gebruikers-ID bestaat reeds voor deze sleutel!\n"
-
-#. TRANSLATORS: These are the allowed answers in
-#. lower and uppercase.  Below you will find the matching
-#. string which should be translated accordingly and the
-#. letter changed to match the one in the answer string.
-#.
-#. n = Change name
-#. c = Change comment
-#. e = Change email
-#. o = Okay (ready, continue)
-#. q = Quit
-#.
-msgid "NnCcEeOoQq"
-msgstr "NnTtEeOoSs"
-
-msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
-msgstr "Wijzig (N)aam, (T)oelichting, (E)-mailadres of (S)toppen? "
-
-msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
-msgstr "Wijzig (N)aam, (T)oelichting, (E)-mailadres of (O)ké/(S)toppen? "
-
-msgid "Please correct the error first\n"
-msgstr "Verbeter eerst de fout\n"
-
-msgid ""
-"You need a Passphrase to protect your secret key.\n"
-"\n"
-msgstr ""
-"U heeft een wachtwoordzin nodig om uw geheime sleutel te beveiligen.\n"
-"\n"
-
-msgid ""
-"Please enter a passphrase to protect the off-card backup of the new "
-"encryption key."
-msgstr ""
-"Voer een wachtwoordzin in om de externe veiligheidskopie van de nieuwe "
-"encryptiesleutel te beveiligen."
-
-#, c-format
-msgid "%s.\n"
-msgstr "%s.\n"
-
-msgid ""
-"You don't want a passphrase - this is probably a *bad* idea!\n"
-"I will do it anyway.  You can change your passphrase at any time,\n"
-"using this program with the option \"--edit-key\".\n"
-"\n"
-msgstr ""
-"U wilt geen wachtwoordzin - dit is waarschijnlijk een *slecht* idee!\n"
-"Ik ga het toch doen. U kunt uw wachtwoordzin op elk moment wijzigen\n"
-"met behulp van dit programma en de optie \"--edit-key\".\n"
-"\n"
-
-msgid ""
-"We need to generate a lot of random bytes. It is a good idea to perform\n"
-"some other action (type on the keyboard, move the mouse, utilize the\n"
-"disks) during the prime generation; this gives the random number\n"
-"generator a better chance to gain enough entropy.\n"
-msgstr ""
-"We moeten een hele hoop willekeurige bytes genereren. U doet er goed aan om\n"
-"een andere activiteit te ondernemen (tikken op het toetsenbord, de muis\n"
-"bewegen, de schijven gebruiken) tijdens het genereren van het priemgetal.\n"
-"Dit geeft het programma dat het willekeurig getal genereert, meer kans om\n"
-"voldoende entropie te verzamelen.\n"
-
-msgid "Key generation canceled.\n"
-msgstr "Het aanmaken van de sleutel is geannuleerd.\n"
-
-#, c-format
-msgid "writing public key to `%s'\n"
-msgstr "publieke sleutel wordt weggeschreven naar `%s'\n"
-
-#, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "een stukje van de geheime sleutel wordt weggeschreven naar `%s'\n"
-
-#, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "geheime sleutel wordt weggeschreven naar `%s'\n"
-
-#, c-format
-msgid "no writable public keyring found: %s\n"
-msgstr ""
-"geen publieke sleutelring gevonden waarnaar geschreven kan worden: %s\n"
-
-#, c-format
-msgid "no writable secret keyring found: %s\n"
-msgstr "geen geheime sleutelring gevonden waarnaar geschreven kan worden: %s\n"
-
-#, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "fout bij het schrijven naar de publieke sleutelring `%s': %s\n"
-
-#, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "fout bij het schrijven naar de geheime sleutelring `%s': %s\n"
-
-msgid "public and secret key created and signed.\n"
-msgstr "publieke en geheime sleutel zijn aangemaakt en ondertekend.\n"
-
-msgid ""
-"Note that this key cannot be used for encryption.  You may want to use\n"
-"the command \"--edit-key\" to generate a subkey for this purpose.\n"
-msgstr ""
-"Noteer dat deze sleutel niet gebruikt kan worden voor versleuteling. U zou\n"
-"het commando \"--edit-key\" kunnen gebruiken om voor dit doel een "
-"subsleutel\n"
-"aan te maken.\n"
-
-#, c-format
-msgid "Key generation failed: %s\n"
-msgstr "Sleutel aanmaken is mislukt: %s\n"
-
-#, c-format
-msgid ""
-"key has been created %lu second in future (time warp or clock problem)\n"
-msgstr ""
-"de sleutel werd %lu seconde in de toekomst aangemaakt (afwijkende tijd of er "
-"is een probleem met de klok)\n"
-
-#, c-format
-msgid ""
-"key has been created %lu seconds in future (time warp or clock problem)\n"
-msgstr ""
-"de sleutel werd %lu seconden in de toekomst aangemaakt (afwijkende tijd of "
-"er is een probleem met de klok)\n"
-
-msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
-msgstr ""
-"NOOT: subsleutels aanmaken voor v3-sleutels is niet compatibel met OpenPGP\n"
-
-msgid "Really create? (y/N) "
-msgstr "Werkelijk aanmaken? (j/N) "
-
-#, c-format
-msgid "storing key onto card failed: %s\n"
-msgstr "sleutel opslaan op kaart is niet gelukt: %s\n"
-
-#, c-format
-msgid "can't create backup file `%s': %s\n"
-msgstr "kan reservebestand `%s' niet aanmaken: %s\n"
-
-#, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
-msgstr "NOOT: reservebestand van de kaartsleutel opgeslagen als `%s'\n"
-
-msgid "never     "
-msgstr "nooit     "
-
-msgid "Critical signature policy: "
-msgstr "Kritieke ondertekeningsrichtlijnen: "
-
-msgid "Signature policy: "
-msgstr "Ondertekeningsrichtlijnen: "
-
-msgid "Critical preferred keyserver: "
-msgstr "Kritieke voorkeurssleutelserver: "
-
-msgid "Critical signature notation: "
-msgstr "Kritieke notatie van de handtekening: "
-
-msgid "Signature notation: "
-msgstr "Notatie van de handtekening: "
-
-msgid "Keyring"
-msgstr "Sleutelring"
-
-msgid "Primary key fingerprint:"
-msgstr "Vingerafdruk van de primaire sleutel:"
-
-msgid "     Subkey fingerprint:"
-msgstr "      Vingerafdruk van de subsleutel:"
-
-#. TRANSLATORS: this should fit into 24 bytes to that the
-#. * fingerprint data is properly aligned with the user ID
-msgid " Primary key fingerprint:"
-msgstr " Vingerafdruk van de primaire sleutel:"
-
-msgid "      Subkey fingerprint:"
-msgstr "       Vingerafdruk van de subsleutel:"
-
-msgid "      Key fingerprint ="
-msgstr "      Vingerafdruk van de sleutel ="
-
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "WAARSCHUWING: er wordt een experimenteel hashalgoritme %s gebruikt\n"
-
-msgid "      Card serial no. ="
-msgstr "         Serienummer van de kaart ="
-
-#, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
-msgstr "het hernoemen van `%s' naar `%s' is mislukt: %s\n"
-
-msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr ""
-"WAARSCHUWING: er bestaan twee bestanden met vertrouwelijke informatie.\n"
-
-#, c-format
-msgid "%s is the unchanged one\n"
-msgstr "%s is het ongewijzigde\n"
-
-#, c-format
-msgid "%s is the new one\n"
-msgstr "%s is het nieuwe\n"
-
-msgid "Please fix this possible security flaw\n"
-msgstr "Los dit mogelijk veiligheidseuvel alstublieft op\n"
-
-#, c-format
-msgid "caching keyring `%s'\n"
-msgstr "sleutelring `%s' wordt in de cache geladen\n"
-
-#, c-format
-msgid "%lu keys cached so far (%lu signatures)\n"
-msgstr "%lu sleutels tot dusver in de cache geladen (%lu ondertekeningen)\n"
-
-#, c-format
-msgid "%lu keys cached (%lu signatures)\n"
-msgstr "%lu sleutels in de cache geladen (%lu ondertekeningen)\n"
-
-#, c-format
-msgid "%s: keyring created\n"
-msgstr "%s: sleutelring aangemaakt\n"
-
-msgid "include revoked keys in search results"
-msgstr "ingetrokken sleutels ook weergeven bij de zoekresultaten"
-
-msgid "include subkeys when searching by key ID"
-msgstr "ook zoeken op subsleutels als gezocht wordt op sleutel-ID"
-
-msgid "use temporary files to pass data to keyserver helpers"
-msgstr ""
-"gebruik tijdelijke bestanden om gegevens door te geven aan de "
-"sleutelserverhelpers"
-
-msgid "do not delete temporary files after using them"
-msgstr "tijdelijke bestanden na gebruik niet verwijderen"
-
-msgid "automatically retrieve keys when verifying signatures"
-msgstr "sleutels automatisch ophalen bij het controleren van ondertekeningen"
-
-msgid "honor the preferred keyserver URL set on the key"
-msgstr ""
-"honoreer de URL van de voorkeurssleutelserver zoals die in de sleutel "
-"vermeld staat"
-
-msgid "honor the PKA record set on a key when retrieving keys"
-msgstr ""
-"honoreer bij het ophalen van de sleutel de PKA-staat die in de sleutel "
-"vervat zit"
-
-#, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
-msgstr ""
-"WAARSCHUWING: sleutelserveroptie `%s' wordt niet gebruikt op dit platform\n"
-
-msgid "disabled"
-msgstr "uitgeschakeld"
-
-msgid "Enter number(s), N)ext, or Q)uit > "
-msgstr "Voer (een) getal(len) in, V)olgende , of S)toppen > "
-
-#, c-format
-msgid "invalid keyserver protocol (us %d!=handler %d)\n"
-msgstr "ongeldig sleutelserverprotocol (wij %d!=verwerkingsroutine %d)\n"
-
-#, c-format
-msgid "key \"%s\" not found on keyserver\n"
-msgstr "sleutel \"%s\" niet gevonden op de sleutelserver\n"
-
-msgid "key not found on keyserver\n"
-msgstr "sleutel niet gevonden op de sleutelserver\n"
-
-#, c-format
-msgid "requesting key %s from %s server %s\n"
-msgstr "opvragen sleutel %s van %s server %s\n"
-
-#, c-format
-msgid "requesting key %s from %s\n"
-msgstr "opvragen sleutel %s van %s\n"
-
-#, c-format
-msgid "searching for names from %s server %s\n"
-msgstr "namen zoeken van %s server %s\n"
-
-#, c-format
-msgid "searching for names from %s\n"
-msgstr "namen zoeken van %s\n"
-
-#, c-format
-msgid "sending key %s to %s server %s\n"
-msgstr "versturen van sleutel %s naar %s server %s\n"
-
-#, c-format
-msgid "sending key %s to %s\n"
-msgstr "versturen van sleutel %s naar %s\n"
-
-#, c-format
-msgid "searching for \"%s\" from %s server %s\n"
-msgstr "zoeken naar \"%s\" van %s server %s\n"
-
-#, c-format
-msgid "searching for \"%s\" from %s\n"
-msgstr "zoeken naar \"%s\" van %s\n"
-
-msgid "no keyserver action!\n"
-msgstr "geen sleutelserveractiviteit!\n"
-
-#, c-format
-msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr ""
-"WAARSCHUWING: verwerkingsroutine van sleutelserver heeft een andere GnuPG-"
-"versie (%s)\n"
-
-msgid "keyserver did not send VERSION\n"
-msgstr "sleutelserver verstuurde geen versie-informatie\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "fout in de communicatie met de sleutelserver: %s\n"
-
-msgid "no keyserver known (use option --keyserver)\n"
-msgstr "er is geen sleutelserver bekend (gebruik optie --keyserver)\n"
-
-msgid "external keyserver calls are not supported in this build\n"
-msgstr ""
-"het aanroepen van externe sleutelservers wordt in deze versie niet "
-"ondersteund\n"
-
-#, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "geen verwerkingsroutine voor sleutelserverstelsel `%s'\n"
-
-#, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
-msgstr "de actie `%s' wordt niet ondersteund door sleutelserverstelsel `%s'\n"
-
-#, c-format
-msgid "%s does not support handler version %d\n"
-msgstr "%s ondersteunt verwerkingsroutine met versie %d niet\n"
-
-msgid "keyserver timed out\n"
-msgstr "sleutelserver reageert te langzaam\n"
-
-msgid "keyserver internal error\n"
-msgstr "sleutelserver geeft een interne fout\n"
-
-#, c-format
-msgid "\"%s\" not a key ID: skipping\n"
-msgstr "\"%s\" is geen sleutel-ID: overgeslagen\n"
-
-#, c-format
-msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr ""
-"WAARSCHUWING: het is niet mogelijk sleutel %s via %s te verversen: %s\n"
-
-#, c-format
-msgid "refreshing 1 key from %s\n"
-msgstr "verversen van 1 sleutel vanuit %s\n"
-
-#, c-format
-msgid "refreshing %d keys from %s\n"
-msgstr "verversen van %d sleutels vanuit %s\n"
-
-#, c-format
-msgid "WARNING: unable to fetch URI %s: %s\n"
-msgstr "WAARSCHUWING: het is niet mogelijk om URI %s op te halen: %s\n"
-
-#, c-format
-msgid "WARNING: unable to parse URI %s\n"
-msgstr "WAARSCHUWING: het is niet mogelijk om URI %s te ontleden\n"
-
-#, c-format
-msgid "weird size for an encrypted session key (%d)\n"
-msgstr "vreemde lengte voor een versleutelde sessiesleutel (%d)\n"
-
-#, c-format
-msgid "%s encrypted session key\n"
-msgstr "%s versleutelde sessiesleutel\n"
-
-#, c-format
-msgid "passphrase generated with unknown digest algorithm %d\n"
-msgstr "wachtwoordzin is gemaakt met onbekend hashalgoritme %d\n"
-
-#, c-format
-msgid "public key is %s\n"
-msgstr "publieke sleutel is %s\n"
-
-msgid "public key encrypted data: good DEK\n"
-msgstr "met de publieke sleutel versleutelde gegevens: goede DEK\n"
-
-#, c-format
-msgid "encrypted with %u-bit %s key, ID %s, created %s\n"
-msgstr "versleuteld met %u bit %s-sleutel, ID %s, gemaakt op %s\n"
-
-#, c-format
-msgid "      \"%s\"\n"
-msgstr "      \"%s\"\n"
-
-#, c-format
-msgid "encrypted with %s key, ID %s\n"
-msgstr "versleuteld met %s-sleutel, ID %s\n"
-
-#, c-format
-msgid "public key decryption failed: %s\n"
-msgstr "ontcijferen van publieke sleutel is mislukt : %s\n"
-
-#, c-format
-msgid "encrypted with %lu passphrases\n"
-msgstr "versleuteld met %lu wachtwoordzinnen\n"
-
-msgid "encrypted with 1 passphrase\n"
-msgstr "versleuteld met 1 wachtwoordzin\n"
-
-#, c-format
-msgid "assuming %s encrypted data\n"
-msgstr "gegevens waarschijnlijk versleuteld met %s\n"
-
-#, c-format
-msgid "IDEA cipher unavailable, optimistically attempting to use %s instead\n"
-msgstr ""
-"IDEA-versleutelingsalgoritme is niet beschikbaar, maar we gaan in plaats "
-"daarvan met goede moed %s proberen\n"
-
-msgid "decryption okay\n"
-msgstr "ontcijfering oké\n"
-
-msgid "WARNING: message was not integrity protected\n"
-msgstr "WAARSCHUWING: de integriteit van het bericht was niet beveiligd\n"
-
-msgid "WARNING: encrypted message has been manipulated!\n"
-msgstr "WAARSCHUWING: versleuteld bericht werd gemanipuleerd!\n"
-
-#, c-format
-msgid "cleared passphrase cached with ID: %s\n"
-msgstr "gewiste wachtwoordzin in de cache geplaatst met ID: %s\n"
-
-#, c-format
-msgid "decryption failed: %s\n"
-msgstr "ontcijferen mislukt: %s\n"
-
-msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
-msgstr ""
-"NOOT: afzender heeft het volgende verzocht: \"alleen-voor-u-persoonlijk\"\n"
-
-#, c-format
-msgid "original file name='%.*s'\n"
-msgstr "originele bestandsnaam='%.*s'\n"
-
-msgid "WARNING: multiple plaintexts seen\n"
-msgstr "WAARSCHUWING: er werd meerdere keren een klare tekst gezien\n"
-
-msgid "standalone revocation - use \"gpg --import\" to apply\n"
-msgstr "autonome intrekking - gebruik \"gpg --import\" om ze toe te passen\n"
-
-msgid "no signature found\n"
-msgstr "geen ondertekening gevonden\n"
-
-msgid "signature verification suppressed\n"
-msgstr "controle van de ondertekening onderdrukt\n"
-
-msgid "can't handle this ambiguous signature data\n"
-msgstr "kan deze ambigue ondertekeningsgegevens niet verwerken\n"
-
-#, c-format
-msgid "Signature made %s\n"
-msgstr "Ondertekening gemaakt op %s\n"
-
-#, c-format
-msgid "               using %s key %s\n"
-msgstr "               met %s sleutel %s\n"
-
-#, c-format
-msgid "Signature made %s using %s key ID %s\n"
-msgstr "Ondertekening gemaakt op %s met %s sleutel-ID %s\n"
-
-msgid "Key available at: "
-msgstr "Sleutel beschikbaar op: "
-
-#, c-format
-msgid "BAD signature from \"%s\""
-msgstr "SLECHTE handtekening van \"%s\""
-
-#, c-format
-msgid "Expired signature from \"%s\""
-msgstr "Vervallen handtekening van \"%s\""
-
-#, c-format
-msgid "Good signature from \"%s\""
-msgstr "Goede handtekening van \"%s\""
-
-msgid "[uncertain]"
-msgstr "[onzeker]"
-
-#, c-format
-msgid "                aka \"%s\""
-msgstr "                ook bekend als \"%s\""
-
-#, c-format
-msgid "Signature expired %s\n"
-msgstr "Ondertekening vervallen op %s\n"
-
-#, c-format
-msgid "Signature expires %s\n"
-msgstr "Ondertekening verloopt op %s\n"
-
-#, c-format
-msgid "%s signature, digest algorithm %s\n"
-msgstr "%s handtekening, hashalgoritme %s\n"
-
-msgid "binary"
-msgstr "binair"
-
-msgid "textmode"
-msgstr "tekstmodus"
-
-msgid "unknown"
-msgstr "onbekend"
-
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-"WAARSCHUWING: geen ontkoppelde handtekening; bestand '%s' werd NIET "
-"geverifieerd!\n"
-
-#, c-format
-msgid "Can't check signature: %s\n"
-msgstr "Kan ondertekening niet controleren: %s\n"
-
-msgid "not a detached signature\n"
-msgstr "geen ontkoppelde ondertekening\n"
-
-msgid ""
-"WARNING: multiple signatures detected.  Only the first will be checked.\n"
-msgstr ""
-"WAARSCHUWING: meerdere ondertekeningen gevonden.\n"
-"              Alleen de eerste zal gecontroleerd worden.\n"
-
-#, c-format
-msgid "standalone signature of class 0x%02x\n"
-msgstr "autonome ondertekening van klasse 0x%02x\n"
-
-msgid "old style (PGP 2.x) signature\n"
-msgstr "ondertekening in oude stijl (PGP 2.x)\n"
-
-msgid "invalid root packet detected in proc_tree()\n"
-msgstr "ongeldig stampakket gevonden in proc_tree()\n"
-
-#, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
-msgstr "opvragen van status (fstat) van `%s' mislukte in %s: %s\n"
-
-#, c-format
-msgid "fstat(%d) failed in %s: %s\n"
-msgstr "opvragen van status (fstat(%d)) mislukte in %s: %s\n"
-
-#, c-format
-msgid "WARNING: using experimental public key algorithm %s\n"
-msgstr ""
-"WAARSCHUWING: er wordt een experimenteel algoritme %s\n"
-"              gebruikt voor de publieke sleutel\n"
-
-msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n"
-msgstr ""
-"WAARSCHUWING: Elgamal-sleutels die ondertekenen + versleutelen zijn "
-"verouderd\n"
-
-#, c-format
-msgid "WARNING: using experimental cipher algorithm %s\n"
-msgstr ""
-"WAARSCHUWING: er wordt een experimenteel versleutelingsalgoritme %s "
-"gebruikt\n"
-
-#, c-format
-msgid "WARNING: using experimental digest algorithm %s\n"
-msgstr "WAARSCHUWING: er wordt een experimenteel hashalgoritme %s gebruikt\n"
-
-#, c-format
-msgid "WARNING: digest algorithm %s is deprecated\n"
-msgstr "WAARSCHUWING: hashalgoritme %s is verouderd\n"
-
-#, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Noot: handtekeningen die het %s-algoritme gebruiken worden verworpen\n"
-
-msgid "the IDEA cipher plugin is not present\n"
-msgstr "het IDEA versleutelingsalgoritme is niet beschikbaar\n"
-
-#, c-format
-msgid "please see %s for more information\n"
-msgstr "lees %s voor meer informatie\n"
-
-#, c-format
-msgid "%s:%d: deprecated option \"%s\"\n"
-msgstr "%s:%d: verouderde optie \"%s\"\n"
-
-#, c-format
-msgid "WARNING: \"%s\" is a deprecated option\n"
-msgstr "WAARSCHUWING: \"%s\" is een verouderde optie\n"
-
-#, c-format
-msgid "please use \"%s%s\" instead\n"
-msgstr "gelieve in de plaats \"%s%s\" te gebruiken\n"
-
-#, c-format
-msgid "WARNING: \"%s\" is a deprecated command - do not use it\n"
-msgstr "WAARSCHUWING: \"%s\" is een verouderd commando - gebruik het niet\n"
-
-#, c-format
-msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgstr "%s:%u: verouderde optie \"%s\" - ze heeft geen enkel effect\n"
-
-#, c-format
-msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr ""
-"WAARSCHUWING: \"%s\" is een verouderde optie - ze heeft geen enkel effect\n"
-
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr ""
-"%s:%u: \"%s%s\" is in dit bestand verouderd - ze heeft enkel effect in %s\n"
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr ""
-"WAARSCHUWING: \"%s%s\" is een verouderde optie - ze heeft geen effect tenzij "
-"op %s\n"
-
-msgid "Uncompressed"
-msgstr "Niet gecomprimeerd"
-
-#. TRANSLATORS: See doc/TRANSLATE about this string.
-msgid "uncompressed|none"
-msgstr "niet gecomprimeerd|geen"
-
-#, c-format
-msgid "this message may not be usable by %s\n"
-msgstr "dit bericht kan mogelijk niet gebruikt worden door %s\n"
-
-#, c-format
-msgid "ambiguous option `%s'\n"
-msgstr "dubbelzinnige optie `%s'\n"
-
-#, c-format
-msgid "unknown option `%s'\n"
-msgstr "onbekende optie `%s'\n"
-
-#, c-format
-msgid "File `%s' exists. "
-msgstr "Bestand `%s' bestaat. "
-
-msgid "Overwrite? (y/N) "
-msgstr "Overschrijven? (j/N) "
-
-#, c-format
-msgid "%s: unknown suffix\n"
-msgstr "%s: onbekend achtervoegsel\n"
-
-msgid "Enter new filename"
-msgstr "Voer een nieuwe bestandsnaam in"
-
-msgid "writing to stdout\n"
-msgstr "schrijven naar standaarduitvoer\n"
-
-#, c-format
-msgid "assuming signed data in '%s'\n"
-msgstr "gegevens in `%s' worden verondersteld ondertekend te zijn\n"
-
-#, c-format
-msgid "new configuration file `%s' created\n"
-msgstr "nieuw configuratiebestand `%s' aangemaakt\n"
-
-#, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
-msgstr ""
-"WAARSCHUWING: opties in `%s' zijn tijdens deze doorloop nog niet actief\n"
-
-#, c-format
-msgid "can't handle public key algorithm %d\n"
-msgstr "kan het algoritme %d van de publieke sleutel niet verwerken\n"
-
-msgid "WARNING: potentially insecure symmetrically encrypted session key\n"
-msgstr ""
-"WAARSCHUWING: mogelijk onveilige symmetrisch versleutelde sessiesleutel\n"
-
-#, c-format
-msgid "subpacket of type %d has critical bit set\n"
-msgstr "de kritieke bit is gezet voor het subpakket van type %d\n"
-
-#, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problemen met de agent: %s\n"
-
-#, c-format
-msgid " (main key ID %s)"
-msgstr " (hoofdsleutel-ID %s)"
-
-#, c-format
-msgid ""
-"Please enter the passphrase to unlock the secret key for the OpenPGP "
-"certificate:\n"
-"\"%.*s\"\n"
-"%u-bit %s key, ID %s,\n"
-"created %s%s.\n"
-msgstr ""
-"Voer de wachtwoordzin in om de geheime sleutel te ontgrendelen\n"
-"van het volgende OpenPGP-certificaat:\n"
-"\"%.*s\"\n"
-"%u-bit %s-sleutel, ID %s,\n"
-"gemaakt op %s%s.\n"
-
-msgid "Enter passphrase\n"
-msgstr "Voer de wachtwoordzin in\n"
-
-msgid "cancelled by user\n"
-msgstr "geannuleerd door de gebruiker\n"
-
-#, c-format
-msgid ""
-"You need a passphrase to unlock the secret key for\n"
-"user: \"%s\"\n"
-msgstr ""
-"U heeft een wachtwoordzin nodig om de geheime sleutel te ontgrendelen\n"
-"van gebruiker: \"%s\"\n"
-
-#, c-format
-msgid "%u-bit %s key, ID %s, created %s"
-msgstr "%u-bit %s-sleutel, ID %s, aangemaakt op %s"
-
-#, c-format
-msgid "         (subkey on main key ID %s)"
-msgstr "         (subsleutel bij hoofdsleutel-ID %s)"
-
-msgid ""
-"\n"
-"Pick an image to use for your photo ID.  The image must be a JPEG file.\n"
-"Remember that the image is stored within your public key.  If you use a\n"
-"very large picture, your key will become very large as well!\n"
-"Keeping the image close to 240x288 is a good size to use.\n"
-msgstr ""
-"\n"
-"Kies een afbeelding om als uw identiteitsfoto te gebruiken. De afbeelding\n"
-"moet een bestand in JPEG-formaat zijn. Onthoud dat de afbeelding opgeslagen\n"
-"wordt in uw publieke sleutel. Als u een erg grote afbeelding gebruikt, zal\n"
-"uw publieke sleutel ook erg groot worden! Een goed formaat voor de "
-"afbeelding\n"
-"is ongeveer 240x288.\n"
-
-msgid "Enter JPEG filename for photo ID: "
-msgstr "Geef de naam van het JPEG-bestand voor de identiteitsfoto: "
-
-#, c-format
-msgid "unable to open JPEG file `%s': %s\n"
-msgstr "kan JPEG-bestand `%s' niet openen: %s\n"
-
-#, c-format
-msgid "This JPEG is really large (%d bytes) !\n"
-msgstr "Dit JPEG-bestand is erg groot (%d bytes) !\n"
-
-msgid "Are you sure you want to use it? (y/N) "
-msgstr "Weet U zeker dat u het wilt gebruiken? (j/N) "
-
-#, c-format
-msgid "`%s' is not a JPEG file\n"
-msgstr "`%s' is geen JPEG-bestand\n"
-
-msgid "Is this photo correct (y/N/q)? "
-msgstr "Is deze foto correct (j/N/s)? "
-
-msgid "unable to display photo ID!\n"
-msgstr "het is niet mogelijk de identiteitsfoto te tonen!\n"
-
-msgid "No reason specified"
-msgstr "Geen reden opgegeven"
-
-msgid "Key is superseded"
-msgstr "Sleutel is vervangen"
-
-msgid "Key has been compromised"
-msgstr "Sleutel is gecompromitteerd"
-
-msgid "Key is no longer used"
-msgstr "Sleutel is niet meer in gebruik"
-
-msgid "User ID is no longer valid"
-msgstr "Gebruikers-ID is niet langer geldig"
-
-msgid "reason for revocation: "
-msgstr "reden van de intrekking: "
-
-msgid "revocation comment: "
-msgstr "toelichting bij de intrekking: "
-
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
-msgid "iImMqQsS"
-msgstr "iImMsSoO"
-
-msgid "No trust value assigned to:\n"
-msgstr "Er werd geen betrouwbaarheidswaarde toegekend aan:\n"
-
-#, c-format
-msgid "  aka \"%s\"\n"
-msgstr "  ook bekend als \"%s\"\n"
-
-msgid ""
-"How much do you trust that this key actually belongs to the named user?\n"
-msgstr ""
-"In hoeverre vertrouwt U erop dat deze sleutel werkelijk\n"
-"bij de genoemde gebruiker hoort?\n"
-
-#, c-format
-msgid "  %d = I don't know or won't say\n"
-msgstr "  %d = Weet ik niet of zal ik niet zeggen\n"
-
-#, c-format
-msgid "  %d = I do NOT trust\n"
-msgstr "  %d = Ik vertrouw het NIET\n"
-
-#, c-format
-msgid "  %d = I trust ultimately\n"
-msgstr "  %d = Ik heb er het uiterste vertrouwen in\n"
-
-msgid "  m = back to the main menu\n"
-msgstr "  m = terug naar het hoofdmenu\n"
-
-msgid "  s = skip this key\n"
-msgstr "  o = sla deze sleutel over\n"
-
-msgid "  q = quit\n"
-msgstr "  s = stoppen\n"
-
-#, c-format
-msgid ""
-"The minimum trust level for this key is: %s\n"
-"\n"
-msgstr ""
-"Het minimale betrouwbaarheidsniveau van deze sleutel is: %s\n"
-"\n"
-
-msgid "Your decision? "
-msgstr "Uw besluit? "
-
-msgid "Do you really want to set this key to ultimate trust? (y/N) "
-msgstr "Wilt u deze sleutel echt instellen als uiterst betrouwbaar? (j/N) "
-
-msgid "Certificates leading to an ultimately trusted key:\n"
-msgstr "Certificaten die leiden naar een uiterst betrouwbare sleutel:\n"
-
-#, c-format
-msgid "%s: There is no assurance this key belongs to the named user\n"
-msgstr "%s: Er is geen zekerheid dat deze sleutel van de genoemde persoon is\n"
-
-#, c-format
-msgid "%s: There is limited assurance this key belongs to the named user\n"
-msgstr ""
-"%s: Er is een beperkte zekerheid dat deze sleutel van de genoemde persoon "
-"is\n"
-
-msgid "This key probably belongs to the named user\n"
-msgstr "Deze sleutel is waarschijnlijk van de genoemde persoon\n"
-
-msgid "This key belongs to us\n"
-msgstr "Deze sleutel is van ons\n"
-
-msgid ""
-"It is NOT certain that the key belongs to the person named\n"
-"in the user ID.  If you *really* know what you are doing,\n"
-"you may answer the next question with yes.\n"
-msgstr ""
-"Het is NIET zeker dat deze sleutel van de persoon is die genoemd wordt\n"
-"in de gebruikers-ID. Als u echter HEEL zeker weet wat u doet,\n"
-"mag u op de volgende vraag Ja antwoorden.\n"
-
-msgid "Use this key anyway? (y/N) "
-msgstr "Deze sleutel toch gebruiken? (j/N) "
-
-msgid "WARNING: Using untrusted key!\n"
-msgstr "WAARSCHUWING: er wordt een onbetrouwbare sleutel gebruikt!\n"
-
-msgid "WARNING: this key might be revoked (revocation key not present)\n"
-msgstr ""
-"WAARSCHUWING: deze sleutel kan ingetrokken zijn\n"
-"              (maar de intrekkingssleutel is niet aanwezig)\n"
-
-msgid "WARNING: This key has been revoked by its designated revoker!\n"
-msgstr ""
-"WAARSCHUWING: Deze sleutel werd ingetrokken door zijn bevoegde intrekker!\n"
-
-msgid "WARNING: This key has been revoked by its owner!\n"
-msgstr "WAARSCHUWING: Deze sleutel werd ingetrokken door de eigenaar!\n"
-
-msgid "         This could mean that the signature is forged.\n"
-msgstr "         Dit kan betekenen dat de ondertekening vervalst is.\n"
-
-msgid "WARNING: This subkey has been revoked by its owner!\n"
-msgstr ""
-"WAARSCHUWING: Deze subsleutel werd ingetrokken door de eigenaar ervan!\n"
-
-msgid "Note: This key has been disabled.\n"
-msgstr "Noot: Deze sleutel is uitgeschakeld.\n"
-
-#, c-format
-msgid "Note: Verified signer's address is `%s'\n"
-msgstr "Noot: Het gecontroleerde adres van de ondertekenaar is `%s'\n"
-
-# TODO
-#, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr ""
-"Noot: Het adres `%s' van de ondertekenaar komt niet overeen met een DNS-"
-"registratie\n"
-
-msgid "trustlevel adjusted to FULL due to valid PKA info\n"
-msgstr ""
-"betrouwbaarheidsniveau bijgesteld naar VOLLEDIG op basis van geldige PKA-"
-"info\n"
-
-msgid "trustlevel adjusted to NEVER due to bad PKA info\n"
-msgstr ""
-"betrouwbaarheidsniveau bijgesteld naar NOOIT op basis van slechte PKA-info\n"
-
-msgid "Note: This key has expired!\n"
-msgstr "Noot: Deze sleutel is vervallen!\n"
-
-msgid "WARNING: This key is not certified with a trusted signature!\n"
-msgstr ""
-"WAARSCHUWING: Deze sleutel werd niet gecertificeerd\n"
-"              door een betrouwbare handtekening!\n"
-
-msgid ""
-"         There is no indication that the signature belongs to the owner.\n"
-msgstr ""
-"         Er is geen aanwijzing dat de handtekening van de eigenaar is.\n"
-
-msgid "WARNING: We do NOT trust this key!\n"
-msgstr "WAARSCHUWING: We vertrouwen deze sleutel NIET!\n"
-
-msgid "         The signature is probably a FORGERY.\n"
-msgstr "         De handtekening is waarschijnlijk een VERVALSING.\n"
-
-msgid ""
-"WARNING: This key is not certified with sufficiently trusted signatures!\n"
-msgstr ""
-"WAARSCHUWING: Deze sleutel werd niet met voldoende\n"
-"              betrouwbare handtekeningen gecertificeerd!\n"
-
-msgid "         It is not certain that the signature belongs to the owner.\n"
-msgstr "         Het is niet zeker dat de handtekening van de eigenaar is.\n"
-
-#, c-format
-msgid "%s: skipped: %s\n"
-msgstr "%s: overgeslagen: %s\n"
-
-#, c-format
-msgid "%s: skipped: public key already present\n"
-msgstr "%s: overgeslagen: publieke sleutel is al aanwezig\n"
-
-msgid "You did not specify a user ID. (you may use \"-r\")\n"
-msgstr ""
-"U heeft geen gebruikers-ID gespecificeerd. (u kunt de optie \"-r\" "
-"gebruiken)\n"
-
-msgid "Current recipients:\n"
-msgstr "Huidige ontvangers:\n"
-
-msgid ""
-"\n"
-"Enter the user ID.  End with an empty line: "
-msgstr ""
-"\n"
-"Voer de gebruikers-ID in. Beëindig met een lege regel: "
-
-msgid "No such user ID.\n"
-msgstr "Een dergelijke gebruikers-ID is er niet.\n"
-
-msgid "skipped: public key already set as default recipient\n"
-msgstr ""
-"overgeslagen: publieke sleutel was reeds als standaardontvanger ingesteld\n"
-
-msgid "Public key is disabled.\n"
-msgstr "Publieke sleutel werd uitgeschakeld\n"
-
-msgid "skipped: public key already set\n"
-msgstr "overgeslagen: publieke sleutel was reeds ingesteld\n"
-
-#, c-format
-msgid "unknown default recipient \"%s\"\n"
-msgstr "onbekende standaardontvanger \"%s\"\n"
-
-#, c-format
-msgid "%s: skipped: public key is disabled\n"
-msgstr "%s: overgeslagen: publieke sleutel is uitgeschakeld\n"
-
-msgid "no valid addressees\n"
-msgstr "geen geldige geadresseerden\n"
-
-#, c-format
-msgid "Note: key %s has no %s feature\n"
-msgstr "Noot: sleutel %s heeft functionaliteit %s niet\n"
-
-#, c-format
-msgid "Note: key %s has no preference for %s\n"
-msgstr "Noot: sleutel %s bevat geen voorkeur voor %s\n"
-
-msgid "data not saved; use option \"--output\" to save it\n"
-msgstr ""
-"gegevens niet bewaard; gebruik de optie \"--output\" om ze te bewaren\n"
-
-msgid "Detached signature.\n"
-msgstr "Ontkoppelde handtekening.\n"
-
-msgid "Please enter name of data file: "
-msgstr "Voer de naam in van het gegevensbestand: "
-
-msgid "reading stdin ...\n"
-msgstr "lezen van standaardinvoer (stdin) ...\n"
-
-msgid "no signed data\n"
-msgstr "geen ondertekende gegevens\n"
-
-#, c-format
-msgid "can't open signed data `%s'\n"
-msgstr "kan de ondertekende gegevens `%s' niet openen\n"
-
-#, c-format
-msgid "can't open signed data fd=%d: %s\n"
-msgstr ""
-"kan de ondertekende gegevens uit bestandsindicator=%d niet openen: %s\n"
-
-#, c-format
-msgid "anonymous recipient; trying secret key %s ...\n"
-msgstr "anonieme ontvanger; geheime sleutel %s wordt geprobeerd ...\n"
-
-msgid "okay, we are the anonymous recipient.\n"
-msgstr "oké, wij zijn de anonieme ontvanger.\n"
-
-msgid "old encoding of the DEK is not supported\n"
-msgstr "de oude codering van de encryptiesleutel DEK wordt niet ondersteund\n"
-
-#, c-format
-msgid "cipher algorithm %d%s is unknown or disabled\n"
-msgstr "versleutelingsalgoritme %d%s is onbekend of uitgeschakeld\n"
-
-#, c-format
-msgid "WARNING: cipher algorithm %s not found in recipient preferences\n"
-msgstr ""
-"WAARSCHUWING: versleutelingsalgoritme %s niet gevonden\n"
-"              in de voorkeuren van de ontvanger\n"
-
-#, c-format
-msgid "NOTE: secret key %s expired at %s\n"
-msgstr "NOOT: geheime sleutel %s verviel op %s\n"
-
-msgid "NOTE: key has been revoked"
-msgstr "NOOT: sleutel werd ingetrokken"
-
-#, c-format
-msgid "build_packet failed: %s\n"
-msgstr "build_packet is mislukt: %s\n"
-
-#, c-format
-msgid "key %s has no user IDs\n"
-msgstr "sleutel %s heeft geen gebruikers-ID's\n"
-
-msgid "To be revoked by:\n"
-msgstr "Moet worden ingetrokken door:\n"
-
-msgid "(This is a sensitive revocation key)\n"
-msgstr "(Dit is een gevoelige intekkingssleutel)\n"
-
-msgid "Create a designated revocation certificate for this key? (y/N) "
-msgstr "Een bevoegd intrekkingscertificaat aanmaken voor deze sleutel? (j/N) "
-
-msgid "ASCII armored output forced.\n"
-msgstr "gedwongen uitvoer in ASCII-harnas.\n"
-
-#, c-format
-msgid "make_keysig_packet failed: %s\n"
-msgstr "make_keysig_packet is mislukt: %s\n"
-
-msgid "Revocation certificate created.\n"
-msgstr "Intrekkingscertificaat werd aangemaakt.\n"
-
-#, c-format
-msgid "no revocation keys found for \"%s\"\n"
-msgstr "er werden geen intrekkingssleutels gevonden voor \"%s\"\n"
-
-#, c-format
-msgid "secret key \"%s\" not found: %s\n"
-msgstr "geheime sleutel \"%s\" niet gevonden: %s\n"
-
-#, c-format
-msgid "no corresponding public key: %s\n"
-msgstr "geen overeenkomstige publieke sleutel: %s\n"
-
-msgid "public key does not match secret key!\n"
-msgstr "publieke sleutel komt niet overeen met de geheime sleutel!\n"
-
-msgid "Create a revocation certificate for this key? (y/N) "
-msgstr "Een intrekkingscertificaat voor deze sleutel maken? (j/N) "
-
-msgid "unknown protection algorithm\n"
-msgstr "onbekend beveiligingsalgoritme\n"
-
-msgid "NOTE: This key is not protected!\n"
-msgstr "NOOT: Deze sleutel is niet beveiligd!\n"
-
-msgid ""
-"Revocation certificate created.\n"
-"\n"
-"Please move it to a medium which you can hide away; if Mallory gets\n"
-"access to this certificate he can use it to make your key unusable.\n"
-"It is smart to print this certificate and store it away, just in case\n"
-"your media become unreadable.  But have some caution:  The print system of\n"
-"your machine might store the data and make it available to others!\n"
-msgstr ""
-"Intrekkingscertificaat aangemaakt.\n"
-"\n"
-"Gelieve het naar een medium te verplaatsen dat u kunt wegstoppen; indien\n"
-"iemand dit certificaat in handen krijgt, kan hij het gebruiken om uw "
-"sleutel\n"
-"onbruikbaar te maken. Het is verstandig om dit certificaat af te drukken en\n"
-"het weg te bergen, voor het geval uw media onleesbaar zouden worden. Maar\n"
-"neem wat voorzichtigheid in acht: het printersysteem van uw computer kan de\n"
-"gegevens opslaan, waardoor ze voor anderen toegankelijk kunnen worden!\n"
-
-msgid "Please select the reason for the revocation:\n"
-msgstr "Gelieve een reden te kiezen voor de intrekking:\n"
-
-msgid "Cancel"
-msgstr "Annuleren"
-
-#, c-format
-msgid "(Probably you want to select %d here)\n"
-msgstr "(Wellicht wilt u hier %d kiezen)\n"
-
-msgid "Enter an optional description; end it with an empty line:\n"
-msgstr "Voer een optionele beschrijving in; beëindig met een lege regel:\n"
-
-#, c-format
-msgid "Reason for revocation: %s\n"
-msgstr "Reden van intrekking: %s\n"
-
-msgid "(No description given)\n"
-msgstr "(Geen beschrijving gegeven)\n"
-
-msgid "Is this okay? (y/N) "
-msgstr "Is dit oké? (j/N) "
-
-msgid "secret key parts are not available\n"
-msgstr "onderdelen van de geheime sleutel zijn niet beschikbaar\n"
-
-#, c-format
-msgid "protection algorithm %d%s is not supported\n"
-msgstr "beveiligingsalgoritme %d%s wordt niet ondersteund\n"
-
-#, c-format
-msgid "protection digest %d is not supported\n"
-msgstr "beveiligingshash %d wordt niet ondersteund\n"
-
-msgid "Invalid passphrase; please try again"
-msgstr "Ongeldige wachtwoordzin; probeer opnieuw"
-
-#, c-format
-msgid "%s ...\n"
-msgstr "%s ...\n"
-
-msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr ""
-"WAARSCHUWING: Een zwakke sleutel gevonden - gelieve de\n"
-"              wachtwoordzin opnieuw te wijzigen.\n"
-
-msgid "generating the deprecated 16-bit checksum for secret key protection\n"
-msgstr ""
-"de controlesom ter beveiliging van de geheime sleutel\n"
-"wordt aangemaakt in het verouderde 16-bit-formaat\n"
-
-msgid "weak key created - retrying\n"
-msgstr "er werd een zwakke sleutel aangemaakt - er wordt nogmaals geprobeerd\n"
-
-#, c-format
-msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
-msgstr ""
-"een zwakke sleutel voor het symmetrisch versleutelingsalgoritme\n"
-"kan niet vermeden worden; er werd %d maal geprobeerd!\n"
-
-msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA vereist dat de lengte van de hash een veelvoud van 8 bits is\n"
-
-#, c-format
-msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "DSA-sleutel %s gebruikt een onveilige (%u bit) hash\n"
-
-#, c-format
-msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "DSA-sleutel %s vereist een hash van %u bit of meer\n"
-
-msgid "WARNING: signature digest conflict in message\n"
-msgstr "WAARSCHUWING: conflicterende ondertekeningshash in het bericht\n"
-
-#, c-format
-msgid "WARNING: signing subkey %s is not cross-certified\n"
-msgstr ""
-"WAARSCHUWING: er is geen kruiscertificering gebeurd\n"
-"              van de ondertekenende subsleutel %s\n"
-
-#, c-format
-msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
-msgstr ""
-"WAARSCHUWING: ondertekenende subsleutel %s heeft een ongeldige "
-"kruiscertificering\n"
-
-#, c-format
-msgid "public key %s is %lu second newer than the signature\n"
-msgstr "publieke sleutel %s is %lu seconde recenter dan de handtekening\n"
-
-#, c-format
-msgid "public key %s is %lu seconds newer than the signature\n"
-msgstr "publieke sleutel %s is %lu seconden recenter dan de handtekening\n"
-
-#, c-format
-msgid ""
-"key %s was created %lu second in the future (time warp or clock problem)\n"
-msgstr ""
-"sleutel %s werd %lu seconde in de toekomst aangemaakt\n"
-"(afwijkende tijd of een probleem met de klok)\n"
-
-#, c-format
-msgid ""
-"key %s was created %lu seconds in the future (time warp or clock problem)\n"
-msgstr ""
-"sleutel %s werd %lu seconden in de toekomst aangemaakt\n"
-"(afwijkende tijd of een probleem met de klok)\n"
-
-#, c-format
-msgid "NOTE: signature key %s expired %s\n"
-msgstr "NOOT: ondertekeningssleutel %s verviel op %s\n"
-
-#, c-format
-msgid "NOTE: signature key %s has been revoked\n"
-msgstr "NOOT: ondertekeningssleutel %s werd ingetrokken\n"
-
-#, c-format
-msgid "assuming bad signature from key %s due to an unknown critical bit\n"
-msgstr ""
-"er wordt verondersteld dat de ondertekening van\n"
-"sleutel %s slecht is, omdat de kritieke bit niet gekend is\n"
-
-#, c-format
-msgid "key %s: no subkey for subkey revocation signature\n"
-msgstr ""
-"sleutel %s: geen subsleutel voor de ondertekening\n"
-"van de intrekking van de subsleutel\n"
-
-#, c-format
-msgid "key %s: no subkey for subkey binding signature\n"
-msgstr ""
-"sleutel %s: geen subsleutel voor de ondertekening van de koppeling met de "
-"subsleutel\n"
-
-#, c-format
-msgid "WARNING: unable to %%-expand notation (too large).  Using unexpanded.\n"
-msgstr ""
-"WAARSCHUWING: kan geen expansie maken op basis van %% van de notatie\n"
-"              (te groot). De niet-geëxpandeerde versie wordt gebruikt.\n"
-
-#, c-format
-msgid ""
-"WARNING: unable to %%-expand policy URL (too large).  Using unexpanded.\n"
-msgstr ""
-"WAARSCHUWING: kan geen expansie maken op basis van %% van de richtlijn-URL\n"
-"              (te groot). De niet-geëxpandeerde versie wordt gebruikt.\n"
-
-#, c-format
-msgid ""
-"WARNING: unable to %%-expand preferred keyserver URL (too large).  Using "
-"unexpanded.\n"
-msgstr ""
-"WAARSCHUWING: kan geen expansie maken op basis van %% van de\n"
-"              URL van de voorkeurssleutelsserver (te groot).\n"
-"              De niet-geëxpandeerde versie wordt gebruikt.\n"
-
-#, c-format
-msgid "checking created signature failed: %s\n"
-msgstr "controle van de aangemaakte ondertekening is mislukt: %s\n"
-
-#, c-format
-msgid "%s/%s signature from: \"%s\"\n"
-msgstr "%s/%s ondertekening van: \"%s\"\n"
-
-msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"u kunt enkel een ontkoppelde ondertekening maken met een\n"
-"sleutel van het type PGP 2.x als u in modus --pgp2 bent\n"
-
-#, c-format
-msgid ""
-"WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
-msgstr ""
-"WAARSCHUWING: het hashalgoritme %s (%d) dwingend opleggen is in strijd\n"
-"              met de voorkeuren van de ontvanger\n"
-
-msgid "signing:"
-msgstr "bezig met ondertekenen:"
-
-msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"u kunt enkel een ondertekening in klare tekst maken met een\n"
-"sleutel van het type PGP 2.x als u in modus --pgp2 bent\n"
-
-#, c-format
-msgid "%s encryption will be used\n"
-msgstr "%s-versleuteling zal gebruikt worden\n"
-
-msgid "key is not flagged as insecure - can't use it with the faked RNG!\n"
-msgstr ""
-"sleutel staat niet als onveilig gemarkeerd - kan hem niet gebruiken\n"
-"met de gesimuleerde generator van willekeurige getallen (RNG)!\n"
-
-#, c-format
-msgid "skipped \"%s\": duplicated\n"
-msgstr "\"%s\" overgeslagen: waren duplicaten\n"
-
-#, c-format
-msgid "skipped \"%s\": %s\n"
-msgstr "\"%s\" overgeslagen: %s\n"
-
-msgid "skipped: secret key already present\n"
-msgstr "overgeslagen: geheime sleutel is al aanwezig\n"
-
-msgid "this is a PGP generated Elgamal key which is not secure for signatures!"
-msgstr ""
-"dit is een Elgamal-sleutel aangemaakt met PGP.\n"
-"Het is niet veilig om er mee te ondertekenen!"
-
-#, c-format
-msgid "trust record %lu, type %d: write failed: %s\n"
-msgstr "staat van betrouwbaarheid %lu, type %d: registreren mislukt: %s\n"
-
-#, c-format
-msgid ""
-"# List of assigned trustvalues, created %s\n"
-"# (Use \"gpg --import-ownertrust\" to restore them)\n"
-msgstr ""
-"# Lijst van toegekende betrouwbaarheidswaarden, aangemaakt op %s\n"
-"# (Gebruik \"gpg --import-ownertrust\" om ze te repareren)\n"
-
-#, c-format
-msgid "error in `%s': %s\n"
-msgstr "fout in `%s': %s\n"
-
-msgid "line too long"
-msgstr "regel is te lang"
-
-msgid "colon missing"
-msgstr "ontbrekende dubbele punt"
-
-msgid "invalid fingerprint"
-msgstr "ongeldige vingerafdruk"
-
-msgid "ownertrust value missing"
-msgstr "ontbrekende waarde voor mate van betrouwbaarheid"
-
-#, c-format
-msgid "error finding trust record in `%s': %s\n"
-msgstr "fout bij het zoeken naar de staat van betrouwbaarheid in `%s': %s\n"
-
-#, c-format
-msgid "read error in `%s': %s\n"
-msgstr "leesfout in `%s': %s\n"
-
-#, c-format
-msgid "trustdb: sync failed: %s\n"
-msgstr "betrouwbaarheidsdatabank (trustdb): synchronisatie mislukt: %s\n"
-
-#, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "kan geen grendel maken voor `%s'\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "kan `%s' niet vergrendelen\n"
-
-#, c-format
-msgid "trustdb rec %lu: lseek failed: %s\n"
-msgstr ""
-"betrouwbaarheidsdatabank (trustdb): element %lu: lseek is mislukt: %s\n"
-
-#, c-format
-msgid "trustdb rec %lu: write failed (n=%d): %s\n"
-msgstr ""
-"betrouwbaarheidsdatabank (trustdb): element %lu: wegschrijven is mislukt (n="
-"%d): %s\n"
-
-msgid "trustdb transaction too large\n"
-msgstr "betrouwbaarheidsdatabank (trustdb): transactie is te groot\n"
-
-#, c-format
-msgid "%s: directory does not exist!\n"
-msgstr "%s: map bestaat niet!\n"
-
-#, c-format
-msgid "can't access `%s': %s\n"
-msgstr "krijg geen toegang tot `%s': %s\n"
-
-#, c-format
-msgid "%s: failed to create version record: %s"
-msgstr "%s: het registreren van de versie is mislukt: %s"
-
-#, c-format
-msgid "%s: invalid trustdb created\n"
-msgstr "%s: ongeldige betrouwbaarheidsdatabank (trustdb) aangemaakt\n"
-
-#, c-format
-msgid "%s: trustdb created\n"
-msgstr "%s: betrouwbaarheidsdatabank (trustdb) aangemaakt\n"
-
-msgid "NOTE: trustdb not writable\n"
-msgstr ""
-"NOOT: er kan niet geschreven worden in de betrouwbaarheidsdatabank "
-"(trustdb)\n"
-
-#, c-format
-msgid "%s: invalid trustdb\n"
-msgstr "%s: ongeldige betrouwbaarheidsdatabank (trustdb)\n"
-
-#, c-format
-msgid "%s: failed to create hashtable: %s\n"
-msgstr "%s: aanmaken van de hashtabel is mislukt: %s\n"
-
-#, c-format
-msgid "%s: error updating version record: %s\n"
-msgstr "%s: fout bij het bijwerken van versiegegevens: %s\n"
-
-#, c-format
-msgid "%s: error reading version record: %s\n"
-msgstr "%s: fout bij het lezen van versiegegevens: %s\n"
-
-#, c-format
-msgid "%s: error writing version record: %s\n"
-msgstr "%s: fout bij het wegschrijven van versiegegevens: %s\n"
-
-#, c-format
-msgid "trustdb: lseek failed: %s\n"
-msgstr "betrouwbaarheidsdatabank (trustdb): lseek is mislukt: %s\n"
-
-#, c-format
-msgid "trustdb: read failed (n=%d): %s\n"
-msgstr "betrouwbaarheidsdatabank (trustdb): lezen is mislukt (n=%d): %s\n"
-
-#, c-format
-msgid "%s: not a trustdb file\n"
-msgstr "%s: bestand is geen betrouwbaarheidsdatabank (trustdb)\n"
-
-#, c-format
-msgid "%s: version record with recnum %lu\n"
-msgstr "%s: versiegegevens met registratienummer %lu\n"
-
-#, c-format
-msgid "%s: invalid file version %d\n"
-msgstr "%s: ongeldige bestandsversie %d\n"
-
-#, c-format
-msgid "%s: error reading free record: %s\n"
-msgstr "%s: fout bij het lezen van vrije staat: %s\n"
-
-#, c-format
-msgid "%s: error writing dir record: %s\n"
-msgstr "%s: fout bij het wegschrijven van de staat van de map: %s\n"
-
-#, c-format
-msgid "%s: failed to zero a record: %s\n"
-msgstr "%s: fout bij het op nul zetten van een staat: %s\n"
-
-#, c-format
-msgid "%s: failed to append a record: %s\n"
-msgstr "%s: het toevoegen van een staat is mislukt: %s\n"
-
-msgid "Error: The trustdb is corrupted.\n"
-msgstr "Fout: de betrouwbaarheidsdatabank (trustdb) is beschadigd.\n"
-
-#, c-format
-msgid "can't handle text lines longer than %d characters\n"
-msgstr "kan geen tekstregels verwerken die groter zijn dan %d tekens\n"
-
-#, c-format
-msgid "input line longer than %d characters\n"
-msgstr "invoerregel groter dan %d tekens\n"
-
-#, c-format
-msgid "`%s' is not a valid long keyID\n"
-msgstr "`%s' is geen geldige ID voor een lange sleutel\n"
-
-#, c-format
-msgid "key %s: accepted as trusted key\n"
-msgstr "sleutel %s: aanvaard als betrouwbare sleutel\n"
-
-#, c-format
-msgid "key %s occurs more than once in the trustdb\n"
-msgstr ""
-"sleutel %s komt meer dan eens voor in de betrouwbaarheidsdatabank (trustdb)\n"
-
-#, c-format
-msgid "key %s: no public key for trusted key - skipped\n"
-msgstr ""
-"sleutel %s: geen publieke sleutel voor de vertrouwde sleutel - overgeslagen\n"
-
-#, c-format
-msgid "key %s marked as ultimately trusted\n"
-msgstr "sleutel %s gemarkeerd als uiterst betrouwbaar\n"
-
-#, c-format
-msgid "trust record %lu, req type %d: read failed: %s\n"
-msgstr "staat van betrouwbaarheid %lu, vereist type %d: lezen mislukt: %s\n"
-
-#, c-format
-msgid "trust record %lu is not of requested type %d\n"
-msgstr "staat van betrouwbaarheid %lu is niet van het vereiste type %d\n"
-
-msgid "You may try to re-create the trustdb using the commands:\n"
-msgstr ""
-"U kunt proberen om de betrouwbaarheidsdatabank (trustdb)\n"
-"opnieuw aan te maken met behulp van de commando's:\n"
-
-msgid "If that does not work, please consult the manual\n"
-msgstr "Indien dit niet lukt, gelieve dan de handleiding te raadplegen\n"
-
-#, c-format
-msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
-msgstr ""
-"kan onbekend betrouwbaarheidsmodel (%d) niet\n"
-"gebruiken - betrouwbaarheidsmodel %s wordt verondersteld\n"
-
-#, c-format
-msgid "using %s trust model\n"
-msgstr "betrouwbaarheidsmodel %s wordt gebruikt\n"
-
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
-msgid "10 translator see trustdb.c:uid_trust_string_fixed"
-msgstr ""
-"11 translator see trustdb.c:uid_trust_string_fixed: werd gelezen door "
-"vertaler"
-
-msgid "[ revoked]"
-msgstr "[ingetrok]"
-
-msgid "[ expired]"
-msgstr "[vervalln]"
-
-msgid "[ unknown]"
-msgstr "[onbekend]"
-
-msgid "[  undef ]"
-msgstr "[ ongedef]"
-
-msgid "[marginal]"
-msgstr "[marginal]"
-
-msgid "[  full  ]"
-msgstr "[volledig]"
-
-msgid "[ultimate]"
-msgstr "[ uiterst]"
-
-msgid "undefined"
-msgstr "niet gedefinieerd"
-
-msgid "never"
-msgstr "nooit"
-
-msgid "marginal"
-msgstr "marginaal"
-
-msgid "full"
-msgstr "volledig"
-
-msgid "ultimate"
-msgstr "uiterst"
-
-msgid "no need for a trustdb check\n"
-msgstr "een controle van de betrouwbaarheidsdatabank (trustdb) is niet nodig\n"
-
-#, c-format
-msgid "next trustdb check due at %s\n"
-msgstr "volgende controle van de betrouwbaarheidsdatabank (trustdb) is op %s\n"
-
-#, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
-msgstr ""
-"een controle van de betrouwbaarheidsdatabank (trustdb)\n"
-"is niet nodig bij het vertrouwensmodel `%s'\n"
-
-#, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
-msgstr ""
-"een bijwerking van de betrouwbaarheidsdatabank (trustdb)\n"
-"is niet nodig bij het vertrouwensmodel `%s'\n"
-
-#, c-format
-msgid "public key %s not found: %s\n"
-msgstr "publieke sleutel %s niet gevonden: %s\n"
-
-msgid "please do a --check-trustdb\n"
-msgstr "gelieve het commando --check-trustdb uit te voeren\n"
-
-msgid "checking the trustdb\n"
-msgstr "de betrouwbaarheidsdatabank (trustdb) wordt gecontroleerd\n"
-
-#, c-format
-msgid "%d keys processed (%d validity counts cleared)\n"
-msgstr "%d sleutels werden verwerkt (%d geldigheidstellers op nul gezet)\n"
-
-msgid "no ultimately trusted keys found\n"
-msgstr "geen uiterst betrouwbare sleutels gevonden\n"
-
-#, c-format
-msgid "public key of ultimately trusted key %s not found\n"
-msgstr "publieke sleutel van uiterst betrouwbare sleutel %s niet gevonden\n"
-
-#, c-format
-msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
-msgstr "%d marginale nodig, %d volledige nodig, vertrouwensmodel %s\n"
-
-#, c-format
-msgid ""
-"depth: %d  valid: %3d  signed: %3d  trust: %d-, %dq, %dn, %dm, %df, %du\n"
-msgstr ""
-"diepte: %d  geldig: %3d  ondert.: %3d  vertr.: %d-, %dq, %dn, %dm, %df, %du\n"
-
-#, c-format
-msgid "unable to update trustdb version record: write failed: %s\n"
-msgstr ""
-"bijwerken van de versiegegevens van de betrouwbaarheidsdatabank (trustdb):\n"
-"wegschrijven is mislukt: %s\n"
-
-msgid ""
-"the signature could not be verified.\n"
-"Please remember that the signature file (.sig or .asc)\n"
-"should be the first file given on the command line.\n"
-msgstr ""
-"de ondertekening kon niet geverifieerd worden.\n"
-"Denk eraan dat het bestand met handtekeningen (.sig of .asc)\n"
-"het eerste bestand moet zijn dat aan de commandolijn ingevoerd wordt.\n"
-
-#, c-format
-msgid "input line %u too long or missing LF\n"
-msgstr "invoerregel %u is te lang of LF ontbreekt\n"
-
-#, c-format
-msgid "can't open fd %d: %s\n"
-msgstr "kan bestandsindicator %d niet openen: %s\n"
-
-msgid "argument not expected"
-msgstr "onverwacht argument"
-
-msgid "read error"
-msgstr "leesfout"
-
-msgid "keyword too long"
-msgstr "sleutelwoord is te lang"
-
-msgid "missing argument"
-msgstr "ontbrekend argument"
-
-msgid "invalid argument"
-msgstr "ongeldig argument"
-
-msgid "invalid command"
-msgstr "ongeldig commando"
-
-msgid "invalid alias definition"
-msgstr "ongeldige definitie van een alias"
-
-msgid "out of core"
-msgstr "geheugenlimiet overschreden"
-
-msgid "invalid option"
-msgstr "ongeldige optie"
-
-#, c-format
-msgid "missing argument for option \"%.50s\"\n"
-msgstr "ontbrekend argument voor optie \"%.50s\"\n"
-
-#, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "ontbrekend argument voor optie \"%.50s\"\n"
-
-#, c-format
-msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "optie \"%.50s\" verwacht geen argument\n"
-
-#, c-format
-msgid "invalid command \"%.50s\"\n"
-msgstr "ongeldig commando \"%.50s\"\n"
-
-#, c-format
-msgid "option \"%.50s\" is ambiguous\n"
-msgstr "optie \"%.50s\" is ambigue\n"
-
-#, c-format
-msgid "command \"%.50s\" is ambiguous\n"
-msgstr "commando \"%.50s\" is ambigue\n"
-
-msgid "out of core\n"
-msgstr "geheugenlimiet overschreden\n"
-
-#, c-format
-msgid "invalid option \"%.50s\"\n"
-msgstr "ongeldige optie \"%.50s\"\n"
-
-#, c-format
-msgid "you found a bug ... (%s:%d)\n"
-msgstr "u vond een bug ... (%s:%d)\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "omzetting van `%s' naar `%s' is niet beschikbaar\n"
-
-#, c-format
-msgid "iconv_open failed: %s\n"
-msgstr "iconv_open is mislukt: %s\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "omzetting van `%s' naar `%s' is mislukt: %s\n"
-
-#, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "kon tijdelijk bestand `%s' niet aanmaken: %s\n"
-
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "fout bij het wegschrijven van `%s': %s\n"
-
-#, c-format
-msgid "removing stale lockfile (created by %d)\n"
-msgstr "oud grendelbestand (aangemaakt door %d) wordt verwijderd\n"
-
-msgid " - probably dead - removing lock"
-msgstr " - wellicht dood - grendel wordt verwijderd"
-
-#, c-format
-msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "wachten op de grendel (vastgehouden door %d%s) %s...\n"
-
-msgid "(deadlock?) "
-msgstr "(dode grendel?) "
-
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "grendel `%s' werd niet geplaatst: %s\n"
-
-#, c-format
-msgid "waiting for lock %s...\n"
-msgstr "wachten op grendel %s...\n"
-
-msgid "set debugging flags"
-msgstr "stel debug-opties in"
-
-msgid "enable full debugging"
-msgstr "maak debuggen ten volle mogelijk"
-
-msgid "Usage: kbxutil [options] [files] (-h for help)"
-msgstr "Gebruik: kbxutil [opties] [bestanden] (-h voor hulp)"
-
-msgid ""
-"Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr ""
-"Syntaxis: kbxutil [opties] [bestanden]\n"
-"Toon, exporteer, importeer Keybox-gegevens (sleutelkistje-data)\n"
-
-#, c-format
-msgid "RSA modulus missing or not of size %d bits\n"
-msgstr "RSA-modulus ontbreekt of heeft niet een grootte van %d bits\n"
-
-#, c-format
-msgid "RSA public exponent missing or larger than %d bits\n"
-msgstr "publieke exponent van RSA ontbreekt of is groter dan %d bits\n"
-
-#, c-format
-msgid "PIN callback returned error: %s\n"
-msgstr "Herroepen van de pincode gaf een fout: %s\n"
-
-msgid "the NullPIN has not yet been changed\n"
-msgstr "de nul-pincode werd nog niet gewijzigd\n"
-
-msgid "|N|Please enter a new PIN for the standard keys."
-msgstr "|N|Gelieve een nieuwe pincode in te voeren voor de standaardsleutels."
-
-msgid "||Please enter the PIN for the standard keys."
-msgstr "||Gelieve de pincode voor de standaardsleutels in te voeren."
-
-msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys."
-msgstr ""
-"|NP|Gelieve een nieuwe PUK-code (PIN Unblocking Code) in te voeren voor de "
-"standaardsleutels."
-
-msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys."
-msgstr ""
-"|P|Gelieve de PUK-code (PIN Unblocking Code) in te voeren voor de "
-"standaardsleutels."
-
-msgid "|N|Please enter a new PIN for the key to create qualified signatures."
-msgstr ""
-"|N|Gelieve een nieuwe pincode in te voeren voor de sleutel die bevoegde "
-"handtekeningen kan aanmaken."
-
-msgid "||Please enter the PIN for the key to create qualified signatures."
-msgstr ""
-"||Gelieve de pincode in te voeren voor de sleutel die bevoegde "
-"handtekeningen kan aanmaken."
-
-msgid ""
-"|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create "
-"qualified signatures."
-msgstr ""
-"|NP|Gelieve een nieuwe PUK-code (PIN Unblocking Code) in te voeren voor de "
-"sleutel die bevoegde handtekeningen kan aanmaken."
-
-msgid ""
-"|P|Please enter the PIN Unblocking Code (PUK) for the key to create "
-"qualified signatures."
-msgstr ""
-"|P|Gelieve de PUK-code (PIN Unblocking Code) in te voeren voor de sleutel "
-"die bevoegde handtekeningen kan aanmaken."
-
-#, c-format
-msgid "error getting new PIN: %s\n"
-msgstr "fout bij het verkrijgen van een nieuwe pincode: %s\n"
-
-#, c-format
-msgid "failed to store the fingerprint: %s\n"
-msgstr "opslaan van de vingerafdruk is mislukt: %s\n"
-
-#, c-format
-msgid "failed to store the creation date: %s\n"
-msgstr "opslaan van de aanmaakdatum is mislukt: %s\n"
-
-#, c-format
-msgid "reading public key failed: %s\n"
-msgstr "het lezen van de publieke sleutel is mislukt: %s\n"
-
-msgid "response does not contain the public key data\n"
-msgstr "antwoord bevat de gegevens van de publieke sleutel niet\n"
-
-msgid "response does not contain the RSA modulus\n"
-msgstr "antwoord bevat de RSA-modulus niet\n"
-
-msgid "response does not contain the RSA public exponent\n"
-msgstr "antwoord bevat de publieke exponent van RSA niet\n"
-
-#, c-format
-msgid "using default PIN as %s\n"
-msgstr "de standaardpincode wordt gebruikt voor %s\n"
-
-#, c-format
-msgid "failed to use default PIN as %s: %s - disabling further default use\n"
-msgstr ""
-"de standaardpincode gebruiken voor %s is mislukt: %s - standaard\n"
-"wordt in het vervolg niet meer gebruikt\n"
-
-#, c-format
-msgid "||Please enter the PIN%%0A[sigs done: %lu]"
-msgstr "||Graag invoer van de pincode%%0A[gemaakte ondertekeningen: %lu]"
-
-msgid "||Please enter the PIN"
-msgstr "||Gelieve de pincode in te voeren"
-
-#, c-format
-msgid "PIN for CHV%d is too short; minimum length is %d\n"
-msgstr "pincode voor CHV%d is te kort; die moet minimaal %d lang zijn\n"
-
-#, c-format
-msgid "verify CHV%d failed: %s\n"
-msgstr "controle van CHV%d is mislukt: %s\n"
-
-msgid "error retrieving CHV status from card\n"
-msgstr "fout bij het ophalen van de CHV-status uit de kaart\n"
-
-msgid "card is permanently locked!\n"
-msgstr "kaart is permanent vergrendeld!\n"
-
-#, c-format
-msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
-msgstr ""
-"beheerder heeft %d resterende pogingen om de pincode in te voeren\n"
-"voordat de kaart permanent vergrendeld wordt\n"
-
-#. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
-#. the start of the string.  Use %%0A to force a linefeed.
-#, c-format
-msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-msgstr "|A|Graag invoer van de beheerderspincode%%0A[resterende pogingen: %d]"
-
-msgid "|A|Please enter the Admin PIN"
-msgstr "|A|Gelieve de pincode van de beheerder in te voeren"
-
-msgid "access to admin commands is not configured\n"
-msgstr "toegang tot beheerderscommando's is niet ingesteld\n"
-
-msgid "||Please enter the Reset Code for the card"
-msgstr "||Gelieve de Reset-Code voor de kaart in te voeren"
-
-#, c-format
-msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "Reset-Code is te kort; die moet minimaal %d lang zijn\n"
-
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
-msgid "|RN|New Reset Code"
-msgstr "|RN|Nieuwe Reset-Code"
-
-msgid "|AN|New Admin PIN"
-msgstr "|AN|Nieuwe pincode voor de beheerder"
-
-msgid "|N|New PIN"
-msgstr "|N|Nieuwe pincode"
-
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr ""
-"||Gelieve de pincode van de beheerder en zijn nieuwe pincode in te voeren"
-
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Gelieve de pincode en de nieuwe pincode in te voeren"
-
-msgid "error reading application data\n"
-msgstr "fout bij het lezen van toepassingsgegevens\n"
-
-msgid "error reading fingerprint DO\n"
-msgstr "fout bij het lezen van de vingerafdruk DO\n"
-
-msgid "key already exists\n"
-msgstr "de sleutel bestaat reeds\n"
-
-msgid "existing key will be replaced\n"
-msgstr "de bestaande sleutel zal vervangen worden\n"
-
-msgid "generating new key\n"
-msgstr "aanmaken van nieuwe sleutel\n"
-
-msgid "writing new key\n"
-msgstr "wegschrijven van nieuwe sleutel\n"
-
-msgid "creation timestamp missing\n"
-msgstr "aanmaaktijdstip ontbreekt\n"
-
-#, c-format
-msgid "RSA prime %s missing or not of size %d bits\n"
-msgstr "priemgetal %s van RSA ontbreekt of heeft niet de grootte van %d bits\n"
-
-#, c-format
-msgid "failed to store the key: %s\n"
-msgstr "opslaan van de sleutel is mislukt: %s\n"
-
-msgid "please wait while key is being generated ...\n"
-msgstr "wacht terwijl de sleutel wordt aangemaakt ...\n"
-
-msgid "generating key failed\n"
-msgstr "aanmaken van de sleutel is mislukt\n"
-
-#, c-format
-msgid "key generation completed (%d seconds)\n"
-msgstr "het aanmaken van de sleutel is voltooid (in %d seconden)\n"
-
-msgid "invalid structure of OpenPGP card (DO 0x93)\n"
-msgstr "ongeldige structuur van de OpenPGP-kaart (DO 0x93)\n"
-
-msgid "fingerprint on card does not match requested one\n"
-msgstr "vingerafdruk op de kaart komt niet overeen met de gevraagde\n"
-
-#, c-format
-msgid "card does not support digest algorithm %s\n"
-msgstr "de kaart ondersteunt het hashalgoritme %s niet\n"
-
-#, c-format
-msgid "signatures created so far: %lu\n"
-msgstr "tot dusver gegenereerde handtekeningen: %lu\n"
-
-msgid ""
-"verification of Admin PIN is currently prohibited through this command\n"
-msgstr ""
-"controleren van de pincode van de beheerder wordt momenteel verboden met dit "
-"commando\n"
-
-#, c-format
-msgid "can't access %s - invalid OpenPGP card?\n"
-msgstr "kan geen toegang krijgen tot %s - ongeldige OpenPGP-kaart?\n"
-
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr ""
-"||Gelieve uw pincode in te voeren op het numeriek pad van de kaartlezer"
-
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
-msgid "|N|Initial New PIN"
-msgstr "|N|Initiële nieuwe pincode"
-
-msgid "run in multi server mode (foreground)"
-msgstr "uitvoeren in multi-servermodus (voorgrond)"
-
-msgid "|LEVEL|set the debugging level to LEVEL"
-msgstr "|NIVEAU|stel het debuggingsniveau in op NIVEAU"
-
-msgid "|FILE|write a log to FILE"
-msgstr "|BESTAND|houd een logboek bij in BESTAND"
-
-msgid "|N|connect to reader at port N"
-msgstr "|N|maak verbinding met de lezer via poort N"
-
-msgid "|NAME|use NAME as ct-API driver"
-msgstr "|NAAM|gebruik NAAM als stuurprogramma voor ct-API"
-
-msgid "|NAME|use NAME as PC/SC driver"
-msgstr "|NAAM|gebruik NAAM als stuurprogramma voor PC/SC"
-
-msgid "do not use the internal CCID driver"
-msgstr "gebruik het interne stuurprogramma CCID niet"
-
-msgid "|N|disconnect the card after N seconds of inactivity"
-msgstr ""
-"|N|verbreek de verbinding met de kaart na een inactiviteit van N seconden"
-
-msgid "do not use a reader's pinpad"
-msgstr "gebruik het numeriek pad van de kaartlezer niet"
-
-msgid "deny the use of admin card commands"
-msgstr "sta het gebruik van commando's voor het beheer van de kaart niet toe"
-
-msgid "use variable length input for pinpad"
-msgstr "maak bij het numeriek pad gebruik van een invoer van variabele lengte"
-
-msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Gebruik: scdaemon [opties] (-h voor hulp)"
-
-msgid ""
-"Syntax: scdaemon [options] [command [args]]\n"
-"Smartcard daemon for GnuPG\n"
-msgstr ""
-"Syntaxis: scdaemon [opties] [commando [parameters]]\n"
-"Chipkaart-achtergronddienst voor GnuPG\n"
-
-msgid "please use the option `--daemon' to run the program in the background\n"
-msgstr ""
-"gelieve de optie `--daemon' te gebruiken om het programma in de achtergrond "
-"uit te voeren\n"
-
-#, c-format
-msgid "handler for fd %d started\n"
-msgstr "verwerker voor bestandsindicator %d gestart\n"
-
-#, c-format
-msgid "handler for fd %d terminated\n"
-msgstr "verwerker voor bestandsindicator %d beëindigd\n"
-
-#, c-format
-msgid "invalid radix64 character %02x skipped\n"
-msgstr "ongeldig radix64-teken %02X overgeslagen\n"
-
-#, c-format
-msgid "failed to proxy %s inquiry to client\n"
-msgstr "doorspelen van aanvraag %s aan de client is mislukt\n"
-
-#, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "dirmngr wordt nog niet uitgevoerd - `%s' wordt gestart\n"
-
-msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "ongeldig formaat van de omgevingsvariabele DIRMNGR_INFO\n"
-
-#, c-format
-msgid "dirmngr protocol version %d is not supported\n"
-msgstr "protocolversie %d van dirmngr wordt niet ondersteund\n"
-
-msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr ""
-"kan geen verbinding leggen met de dirmngr - er wordt een noodoplossing "
-"geprobeerd\n"
-
-#, c-format
-msgid "validation model requested by certificate: %s"
-msgstr "door het certificaat gevraagd valideringsmodel: %s"
-
-msgid "chain"
-msgstr "ketting"
-
-msgid "shell"
-msgstr "shell"
-
-#, c-format
-msgid "critical certificate extension %s is not supported"
-msgstr "kritieke certificaatsuitbreiding %s wordt niet ondersteund"
-
-msgid "issuer certificate is not marked as a CA"
-msgstr ""
-"het certificaat van de uitgever staat niet als een certificeringsautoriteit "
-"gemarkeerd"
-
-msgid "critical marked policy without configured policies"
-msgstr ""
-"gemarkeerd als kritieke richtlijn maar instellingen voor beleidsrichtlijnen "
-"ontbreken"
-
-#, c-format
-msgid "failed to open `%s': %s\n"
-msgstr "kan `%s' niet openen: %s\n"
-
-msgid "note: non-critical certificate policy not allowed"
-msgstr "noot: niet-kritieke certificaatsrichtlijn niet toegestaan"
-
-msgid "certificate policy not allowed"
-msgstr "certificaatsrichtlijn niet toegestaan"
-
-msgid "looking up issuer at external location\n"
-msgstr "uitgever wordt op een externe locatie opgezocht\n"
-
-#, c-format
-msgid "number of issuers matching: %d\n"
-msgstr "aantal overeenstemmende uitgevers: %d\n"
-
-msgid "looking up issuer from the Dirmngr cache\n"
-msgstr "uitgever wordt opgezocht in de cache van Dirmngr\n"
-
-#, c-format
-msgid "number of matching certificates: %d\n"
-msgstr "aantal overeenstemmende certificaten: %d\n"
-
-#, c-format
-msgid "dirmngr cache-only key lookup failed: %s\n"
-msgstr ""
-"het enkel in de cache van dirmngr opzoeken van de sleutel is mislukt: %s\n"
-
-msgid "failed to allocate keyDB handle\n"
-msgstr "het reserveren van het beheer van de sleuteldatabase is mislukt\n"
-
-msgid "certificate has been revoked"
-msgstr "certificaat werd ingetrokken"
-
-msgid "the status of the certificate is unknown"
-msgstr "onbekende status van het certificaat"
-
-msgid "please make sure that the \"dirmngr\" is properly installed\n"
-msgstr ""
-"gelieve u ervan te vergewissen dat de \"dirmngr\" behoorlijk geïnstalleerd "
-"werd\n"
-
-#, c-format
-msgid "checking the CRL failed: %s"
-msgstr "controle van de lijst van ingetrokken certificaten is mislukt: %s"
-
-#, c-format
-msgid "certificate with invalid validity: %s"
-msgstr "certificaat met een ongeldige geldigheid: %s"
-
-msgid "certificate not yet valid"
-msgstr "certificaat is nog niet geldig"
-
-msgid "root certificate not yet valid"
-msgstr "stamcertificaat is nog niet geldig"
-
-msgid "intermediate certificate not yet valid"
-msgstr "het tussenliggend certificaat is nog niet geldig"
-
-msgid "certificate has expired"
-msgstr "het certificaat is verlopen"
-
-msgid "root certificate has expired"
-msgstr "het stamcertificaat is vervallen"
-
-msgid "intermediate certificate has expired"
-msgstr "het tussenliggend certificaat is vervallen"
-
-#, c-format
-msgid "required certificate attributes missing: %s%s%s"
-msgstr "de vereiste certificaatattributen ontbreken: %s%s%s"
-
-msgid "certificate with invalid validity"
-msgstr "certificaat met ongeldige geldigheid"
-
-msgid "signature not created during lifetime of certificate"
-msgstr ""
-"handtekening werd niet aangemaakt binnen de levensduur van het certificaat"
-
-msgid "certificate not created during lifetime of issuer"
-msgstr "certificaat werd niet aangemaakt binnen de levensduur van de uitgever"
-
-msgid "intermediate certificate not created during lifetime of issuer"
-msgstr ""
-"het tussenliggend certificaat werd niet aangemaakt binnen de levensduur van "
-"de uitgever"
-
-msgid "  (  signature created at "
-msgstr "  (handtekening aangemaakt op "
-
-msgid "  (certificate created at "
-msgstr "  ( certificaat aangemaakt op "
-
-msgid "  (certificate valid from "
-msgstr "  (    certificaat geldig van "
-
-msgid "  (     issuer valid from "
-msgstr "  (       uitgever geldig van "
-
-#, c-format
-msgid "fingerprint=%s\n"
-msgstr "vingerafdruk=%s\n"
-
-msgid "root certificate has now been marked as trusted\n"
-msgstr "het stamcertificaat werd nu als betrouwbaar gemarkeerd\n"
-
-msgid "interactive marking as trusted not enabled in gpg-agent\n"
-msgstr ""
-"iets interactief als betrouwbaar markeren is niet mogelijk met gpg-agent\n"
-
-msgid "interactive marking as trusted disabled for this session\n"
-msgstr ""
-"iets interactief als betrouwbaar markeren is tijdens deze sessie niet "
-"mogelijk\n"
-
-msgid "WARNING: creation time of signature not known - assuming current time"
-msgstr ""
-"WAARSCHUWING: het tijdstip waarop de handtekening aangemaakt werd is niet "
-"bekend - er wordt aangenomen dat het nu was"
-
-msgid "no issuer found in certificate"
-msgstr "geen uitgever gevonden in het certificaat"
-
-msgid "self-signed certificate has a BAD signature"
-msgstr "auto-gesigneerd certificaat heeft een SLECHTE handtekening"
-
-msgid "root certificate is not marked trusted"
-msgstr "stamcertificaat staat niet gemarkeerd als betrouwbaar"
-
-#, c-format
-msgid "checking the trust list failed: %s\n"
-msgstr "controle van de lijst van vertrouwen is mislukt: %s\n"
-
-msgid "certificate chain too long\n"
-msgstr "certificaatketting is te lang\n"
-
-msgid "issuer certificate not found"
-msgstr "certificaat van uitgever niet gevonden"
-
-msgid "certificate has a BAD signature"
-msgstr "certificaat heeft een SLECHTE ondertekening"
-
-msgid "found another possible matching CA certificate - trying again"
-msgstr ""
-"mogelijk een ander overeenstemmend CA-certificaat gevonden - er wordt "
-"opnieuw geprobeerd"
-
-#, c-format
-msgid "certificate chain longer than allowed by CA (%d)"
-msgstr ""
-"certificaatketting is langer dan toegestaan door de certificatieautoriteit "
-"(%d)"
-
-msgid "certificate is good\n"
-msgstr "certificaat is goed\n"
-
-msgid "intermediate certificate is good\n"
-msgstr "tussenliggend certificaat is goed\n"
-
-msgid "root certificate is good\n"
-msgstr "stamcertificaat is goed\n"
-
-msgid "switching to chain model"
-msgstr "er wordt overgeschakeld op het kettingmodel"
-
-#, c-format
-msgid "validation model used: %s"
-msgstr "gebruikt valideringsmodel: %s"
-
-#, c-format
-msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "%s-sleutel gebruikt een onveilige (%u bit) hash\n"
-
-#, c-format
-msgid "a %u bit hash is not valid for a %u bit %s key\n"
-msgstr "een hash van %u bit is niet geldig voor een %u bit %s-sleutel\n"
-
-msgid "(this is the MD2 algorithm)\n"
-msgstr "(dit is het MD2-algoritme)\n"
-
-msgid "none"
-msgstr "geen"
-
-msgid "[Error - invalid encoding]"
-msgstr "[Fout - ongeldige codering]"
-
-msgid "[Error - out of core]"
-msgstr "[Fout - geheugenlimiet overschreden]"
-
-msgid "[Error - No name]"
-msgstr "[Fout - Geen naam]"
-
-msgid "[Error - invalid DN]"
-msgstr "[Fout - ongeldige DN]"
-
-#, c-format
-msgid ""
-"Please enter the passphrase to unlock the secret key for the X.509 "
-"certificate:\n"
-"\"%s\"\n"
-"S/N %s, ID 0x%08lX,\n"
-"created %s, expires %s.\n"
-msgstr ""
-"Voer de wachtwoordzin in voor het ontgrendelen van de geheime sleutel van "
-"het X.509-certificaat:\n"
-"\"%s\"\n"
-"serienummer %s, ID 0x%08lX,\n"
-"aangemaakt op %s, vervalt op %s.\n"
-
-msgid "no key usage specified - assuming all usages\n"
-msgstr ""
-"geen gebruik gespecificeerd voor de sleutel - elk gebruik wordt "
-"verondersteld\n"
-
-#, c-format
-msgid "error getting key usage information: %s\n"
-msgstr ""
-"fout bij het ophalen van de informatie over het gebruik van de sleutel: %s\n"
-
-msgid "certificate should not have been used for certification\n"
-msgstr "het certificaat had niet gebruikt mogen worden om te certificeren\n"
-
-msgid "certificate should not have been used for OCSP response signing\n"
-msgstr ""
-"het certificaat had niet gebruikt mogen worden voor het ondertekenen van "
-"OCSP-antwoorden\n"
-
-msgid "certificate should not have been used for encryption\n"
-msgstr "het certificaat had niet gebruikt mogen worden om te versleutelen\n"
-
-msgid "certificate should not have been used for signing\n"
-msgstr "het certificaat had niet gebruikt mogen worden om te ondertekenen\n"
-
-msgid "certificate is not usable for encryption\n"
-msgstr "het certificaat kan niet gebruikt worden om te versleutelen\n"
-
-msgid "certificate is not usable for signing\n"
-msgstr "het certificaat kan niet gebruikt worden om te ondertekenen\n"
-
-#, c-format
-msgid "line %d: invalid algorithm\n"
-msgstr "regel %d: ongeldig algoritme\n"
-
-#, c-format
-msgid "line %d: invalid key length %u (valid are %d to %d)\n"
-msgstr "regel %d: ongeldige sleutellengte %u (geldig is van %d tot %d)\n"
-
-#, c-format
-msgid "line %d: no subject name given\n"
-msgstr "regel %d: geen naam aan het subject gegeven\n"
-
-#, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
-msgstr "regel %d: de naam van het subject heeft het ongeldige label `%.*s'\n"
-
-#, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
-msgstr "regel %d: het subject heeft de ongeldige naam `%s' op positie %d\n"
-
-#, c-format
-msgid "line %d: not a valid email address\n"
-msgstr "regel %d: geen geldig e-mailadres\n"
-
-#, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
-msgstr "regel %d: fout bij het lezen van sleutel `%s' van de kaart: %s\n"
-
-#, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
-msgstr ""
-"regel %d: fout bij het ophalen van de sleutel met sleutelhendel `%s': %s\n"
-
-#, c-format
-msgid "line %d: key generation failed: %s <%s>\n"
-msgstr "regel %d: sleutel aanmaken is mislukt: %s <%s>\n"
-
-msgid ""
-"To complete this certificate request please enter the passphrase for the key "
-"you just created once more.\n"
-msgstr ""
-"Om deze certificaataanvraag te vervolledigen moet u nogmaals de "
-"wachtwoordzin invoeren voor de sleutel die u zonet aanmaakte.\n"
-
-#, c-format
-msgid "   (%d) RSA\n"
-msgstr "   (%d) RSA\n"
-
-#, c-format
-msgid "   (%d) Existing key\n"
-msgstr "   (%d) Bestaande sleutel\n"
-
-#, c-format
-msgid "   (%d) Existing key from card\n"
-msgstr "   (%d) Bestaande sleutel op de kaart\n"
-
-msgid "Enter the keygrip: "
-msgstr "Voer de sleutelhendel in: "
-
-msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr ""
-"Geen geldige sleutelhendel (een reeks van 40 hexadecimale cijfers wordt "
-"verwacht)\n"
-
-msgid "No key with this keygrip\n"
-msgstr "Deze sleutelhendel heeft geen sleutel bij zich\n"
-
-#, c-format
-msgid "error reading the card: %s\n"
-msgstr "fout bij het lezen van de kaart: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Serienummer van de kaart: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Beschikbare sleutels:\n"
-
-#, c-format
-msgid "Possible actions for a %s key:\n"
-msgstr "Mogelijke acties voor een %s-sleutel:\n"
-
-#, c-format
-msgid "   (%d) sign, encrypt\n"
-msgstr "   (%d) ondertekenen, versleutelen\n"
-
-#, c-format
-msgid "   (%d) sign\n"
-msgstr "   (%d) ondertekenen\n"
-
-#, c-format
-msgid "   (%d) encrypt\n"
-msgstr "   (%d) versleutelen\n"
-
-msgid "Enter the X.509 subject name: "
-msgstr "Voer de naam in voor het subject in X.509-formaat: "
-
-msgid "No subject name given\n"
-msgstr "Geen naam voor het subject ingevoerd\n"
-
-#, c-format
-msgid "Invalid subject name label `%.*s'\n"
-msgstr "De naam voor het subject heeft ongeldig label `%.*s'\n"
-
-#. TRANSLATORS: The 22 in the second string is the
-#. length of the first string up to the "%s".  Please
-#. adjust it do the length of your translation.  The
-#. second string is merely passed to atoi so you can
-#. drop everything after the number.
-#, c-format
-msgid "Invalid subject name `%s'\n"
-msgstr "Subject met ongeldige naam `%s'\n"
-
-msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
-msgstr "21"
-
-msgid "Enter email addresses"
-msgstr "Voer de e-mailadressen in"
-
-msgid " (end with an empty line):\n"
-msgstr " (beëindig met een lege regel):\n"
-
-msgid "Enter DNS names"
-msgstr "Voer de DNS-namen in"
-
-msgid " (optional; end with an empty line):\n"
-msgstr " (facultatief; beëindig met een lege regel):\n"
-
-msgid "Enter URIs"
-msgstr "Voer de URI's in"
-
-msgid "Parameters to be used for the certificate request:\n"
-msgstr "Te gebruiken parameters bij het aanvragen van een certificaat:\n"
-
-msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr ""
-"Er wordt nu een aanvraag voor een certificaat gemaakt. Dit kan even "
-"duren ...\n"
-
-msgid "Ready.  You should now send this request to your CA.\n"
-msgstr ""
-"Klaar. U zou die aanvraag nu moeten sturen naar uw certificatieautoriteit.\n"
-
-msgid "resource problem: out of core\n"
-msgstr "een probleem van hulpbronnen: geheugenlimiet overschreden\n"
-
-msgid "(this is the RC2 algorithm)\n"
-msgstr "(dit is het RC2-algoritme)\n"
-
-msgid "(this does not seem to be an encrypted message)\n"
-msgstr "(dit lijkt geen versleuteld bericht te zijn)\n"
-
-#, c-format
-msgid "certificate `%s' not found: %s\n"
-msgstr "certificaat `%s' niet gevonden: %s\n"
-
-#, c-format
-msgid "error locking keybox: %s\n"
-msgstr "fout bij het vergrendelen van het sleutelkistje: %s\n"
-
-#, c-format
-msgid "duplicated certificate `%s' deleted\n"
-msgstr "duplicaat van het certificaat `%s' werd verwijderd\n"
-
-#, c-format
-msgid "certificate `%s' deleted\n"
-msgstr "certificaat `%s' werd verwijderd\n"
-
-#, c-format
-msgid "deleting certificate \"%s\" failed: %s\n"
-msgstr "verwijderen van certificaat \"%s\" is mislukt: %s\n"
-
-msgid "no valid recipients given\n"
-msgstr "geen geldige ontvangers opgegeven)\n"
-
-msgid "list external keys"
-msgstr "toon externe sleutels"
-
-msgid "list certificate chain"
-msgstr "toon de certificaatketting"
-
-msgid "import certificates"
-msgstr "importeer certificaten"
-
-msgid "export certificates"
-msgstr "exporteer certificaten"
-
-msgid "register a smartcard"
-msgstr "registreer een chipkaart"
-
-msgid "pass a command to the dirmngr"
-msgstr "geef een opdracht door aan de dirmngr"
-
-msgid "invoke gpg-protect-tool"
-msgstr "Activeer gpg-protect-tool"
-
-msgid "create base-64 encoded output"
-msgstr "creëer uitvoer in base-64-formaat"
-
-msgid "assume input is in PEM format"
-msgstr "ga er van uit dat de invoer in PEM-formaat is"
-
-msgid "assume input is in base-64 format"
-msgstr "ga er van uit dat de invoer in base-64-formaat is"
-
-msgid "assume input is in binary format"
-msgstr "ga er van uit dat de invoer in binair formaat is"
-
-msgid "use system's dirmngr if available"
-msgstr "gebruik de dirmngr van het systeem als die beschikbaar is"
-
-msgid "never consult a CRL"
-msgstr "raadpleeg nooit een CRL (lijst van ingetrokken certificaten)"
-
-msgid "check validity using OCSP"
-msgstr "controleer geldigheid met OCSP"
-
-msgid "|N|number of certificates to include"
-msgstr "|N|aantal toe te voegen certificaten"
-
-msgid "|FILE|take policy information from FILE"
-msgstr "|BESTAND|haal richtlijninformatie uit BESTAND"
-
-msgid "do not check certificate policies"
-msgstr "kijk de certificaatrichtlijnen niet na"
-
-msgid "fetch missing issuer certificates"
-msgstr "haal ontbrekende uitgeverscertificaten op"
-
-msgid "don't use the terminal at all"
-msgstr "maak helemaal geen gebruik van de terminal"
-
-msgid "|FILE|write a server mode log to FILE"
-msgstr "|BESTAND|houd een logboek bij in server-modus in BESTAND"
-
-msgid "|FILE|write an audit log to FILE"
-msgstr "|BESTAND|houd een auditlogboek bij in BESTAND"
-
-msgid "batch mode: never ask"
-msgstr "automatische modus: stel nooit vragen"
-
-msgid "assume yes on most questions"
-msgstr "ga uit van een ja-antwoord op de meeste vragen"
-
-msgid "assume no on most questions"
-msgstr "ga uit van een nee-antwoord op de meeste vragen"
-
-msgid "|FILE|add keyring to the list of keyrings"
-msgstr "|BESTAND|voeg de sleutelring toe aan de lijst van sleutelringen"
-
-msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|GEBRUIKERS-ID|gebruik GEBRUIKERS-ID als de standaard geheime sleutel"
-
-msgid "|SPEC|use this keyserver to lookup keys"
-msgstr "|SPEC|gebruik deze sleutelserver om sleutels op te zoeken"
-
-msgid "|NAME|use cipher algorithm NAME"
-msgstr "|NAAM|gebruik versleutelingsalgoritme NAAM"
-
-msgid "|NAME|use message digest algorithm NAME"
-msgstr "|NAAM|gebruik hashalgoritme NAAM"
-
-msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Gebruik: gpgsm [opties] [bestanden] (-h voor hulp)"
-
-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 ""
-"Syntaxis: gpgsm [opties] [bestanden]\n"
-"Onderteken, controleer, versleutel of ontcijfer met het S/MIME-protocol\n"
-"Standaardactie is afhankelijk van de ingevoerde gegevens\n"
-
-msgid "usage: gpgsm [options] "
-msgstr "gebruik: gpgsm [opties] "
-
-#, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
-msgstr "NOOT: zal niet in staat zijn om te versleutelen naar `%s': %s\n"
-
-#, c-format
-msgid "unknown validation model `%s'\n"
-msgstr "onbekend valideringsmodel `%s'\n"
-
-#, c-format
-msgid "%s:%u: no hostname given\n"
-msgstr "%s:%u: geen computernaam opgegeven\n"
-
-#, c-format
-msgid "%s:%u: password given without user\n"
-msgstr "%s:%u: wachtwoord zonder gebruiker gegeven\n"
-
-#, c-format
-msgid "%s:%u: skipping this line\n"
-msgstr "%s:%u: deze regel wordt overgeslagen\n"
-
-msgid "could not parse keyserver\n"
-msgstr "kon de sleutelserver niet ontleden\n"
-
-msgid "WARNING: running with faked system time: "
-msgstr "WAARSCHUWING: wordt uitgevoerd met de gesimuleerde systeemtijd: "
-
-#, c-format
-msgid "importing common certificates `%s'\n"
-msgstr "bezig met importeren van gemeenschappelijke certificaten `%s'\n"
-
-#, c-format
-msgid "can't sign using `%s': %s\n"
-msgstr "kan niet ondertekenen met `%s': %s\n"
-
-msgid "invalid command (there is no implicit command)\n"
-msgstr "ongeldig commando (er is geen impliciet commando)\n"
-
-#, c-format
-msgid "total number processed: %lu\n"
-msgstr "totaal aantal verwerkt: %lu\n"
-
-msgid "error storing certificate\n"
-msgstr "fout bij het opslaan van het certificaat\n"
-
-msgid "basic certificate checks failed - not imported\n"
-msgstr ""
-"basale controle van het certificaat mislukte - wordt niet geïmporteerd\n"
-
-#, c-format
-msgid "error getting stored flags: %s\n"
-msgstr "fout bij het inlezen van de opgeslagen opties: %s\n"
-
-#, c-format
-msgid "error importing certificate: %s\n"
-msgstr "fout bij het importeren van het certificaat: %s\n"
-
-#, c-format
-msgid "error reading input: %s\n"
-msgstr "fout bij het lezen van invoer: %s\n"
-
-#, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "fout bij het aanmaken van sleuteldoosje `%s': %s\n"
-
-#, c-format
-msgid "keybox `%s' created\n"
-msgstr "sleuteldoosje `%s' is aangemaakt\n"
-
-msgid "failed to get the fingerprint\n"
-msgstr "opvragen van de vingerafdruk is mislukt\n"
-
-#, c-format
-msgid "problem looking for existing certificate: %s\n"
-msgstr "probleem bij het opzoeken van een bestaand certificaat: %s\n"
-
-#, c-format
-msgid "error finding writable keyDB: %s\n"
-msgstr ""
-"fout bij het zoeken naar een sleuteldatabase waarin kan geschreven worden: "
-"%s\n"
-
-#, c-format
-msgid "error storing certificate: %s\n"
-msgstr "fout bij het opslaan van het certificaat: %s\n"
-
-#, c-format
-msgid "problem re-searching certificate: %s\n"
-msgstr "probleem bij het opnieuw opzoeken van het certificaat: %s\n"
-
-#, c-format
-msgid "error storing flags: %s\n"
-msgstr "fout bij het opslaan van de opties: %s\n"
-
-msgid "Error - "
-msgstr "Fout - "
-
-msgid "GPG_TTY has not been set - using maybe bogus default\n"
-msgstr ""
-"GPG_TTY werd niet ingesteld - de standaard, die misschien gebrekkig zal "
-"functioneren, wordt gebruik\n"
-
-#, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "ongeldig opgemaakte vingerafdruk in `%s', regel %d\n"
-
-#, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "ongeldige landcode in `%s', regel %d\n"
-
-#, c-format
-msgid ""
-"You are about to create a signature using your certificate:\n"
-"\"%s\"\n"
-"This will create a qualified signature by law equated to a handwritten "
-"signature.\n"
-"\n"
-"%s%sAre you really sure that you want to do this?"
-msgstr ""
-"U staat op het punt om een handtekening aan te maken met uw certificaat:\n"
-"\"%s\"\n"
-"Dit zal een bevoegde handtekening aanmaken die volgens de wet evenwaardig is "
-"aan een met de hand geplaatste handtekening.\n"
-"\n"
-"%s%sBent u er echt zeker van dat u dit wilt doen?"
-
-msgid ""
-"Note, that this software is not officially approved to create or verify such "
-"signatures.\n"
-msgstr ""
-"Noteer dat deze programmatuur niet officieel goedgekeurd is om dergelijke "
-"handtekeningen aan te maken of te verifiëren.\n"
-
-#, c-format
-msgid ""
-"You are about to create a signature using your certificate:\n"
-"\"%s\"\n"
-"Note, that this certificate will NOT create a qualified signature!"
-msgstr ""
-"U staat op het punt om een handtekening aan te maken met uw certificaat:\n"
-"\"%s\"\n"
-"Noteer dat dit certificaat GEEN bevoegde handtekening zal aanmaken!"
-
-#, c-format
-msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
-msgstr ""
-"hashalgoritme %d (%s) voor ondertekenaar %d wordt niet ondersteund; %s wordt "
-"gebruikt\n"
-
-#, c-format
-msgid "hash algorithm used for signer %d: %s (%s)\n"
-msgstr ""
-"er wordt gebruik gemaakt van het hashalgoritme voor ondertekenaar %d: %s "
-"(%s)\n"
-
-#, c-format
-msgid "checking for qualified certificate failed: %s\n"
-msgstr "nagaan of het een bevoegd certificaat betreft, is mislukt: %s\n"
-
-msgid "Signature made "
-msgstr "Handtekening geplaatst"
-
-msgid "[date not given]"
-msgstr "[datum niet vermeld]"
-
-#, c-format
-msgid " using certificate ID 0x%08lX\n"
-msgstr " er wordt gebruik gemaakt van certificaat ID 0x%08lX\n"
-
-msgid ""
-"invalid signature: message digest attribute does not match computed one\n"
-msgstr ""
-"ongeldige ondertekening: het hashattribuut van het bericht komt niet overeen "
-"met het berekende\n"
-
-msgid "Good signature from"
-msgstr "Goede handtekening van"
-
-msgid "                aka"
-msgstr "                ook bekend als"
-
-msgid "This is a qualified signature\n"
-msgstr "Dit is een bevoegde ondertekening\n"
-
-msgid "quiet"
-msgstr "stil"
-
-msgid "print data out hex encoded"
-msgstr "toon de gecodeerde gegevens in hexadecimaal formaat"
-
-msgid "decode received data lines"
-msgstr "ontcijfer de ontvangen dataregels"
-
-msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NAAM|maak verbinding met Assuan-socket NAAM"
-
-msgid "run the Assuan server given on the command line"
-msgstr "start de Assuan-server die aan de commandolijn ingevoerd werd"
-
-msgid "do not use extended connect mode"
-msgstr "maak geen gebruik van de uitvoerige verbindingsmodus"
-
-msgid "|FILE|run commands from FILE on startup"
-msgstr "|BESTAND|voer bij het opstarten de opdrachten uit BESTAND uit"
-
-msgid "run /subst on startup"
-msgstr "voer bij het opstarten /subst uit"
-
-msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Gebruik: gpg-connect-agent [opties] (-h voor hulp)"
-
-msgid ""
-"Syntax: gpg-connect-agent [options]\n"
-"Connect to a running agent and send commands\n"
-msgstr ""
-"Syntaxis: gpg-connect-agent [opties]\n"
-"Maak een verbinding met een actieve agent en stuur opdrachten\n"
-
-#, c-format
-msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr "optie \"%s\" vereist een programma en optionele argumenten\n"
-
-#, c-format
-msgid "option \"%s\" ignored due to \"%s\"\n"
-msgstr "optie \"%s\" genegeerd omwille van \"%s\"\n"
-
-#, c-format
-msgid "receiving line failed: %s\n"
-msgstr "ontvangen van regel is mislukt: %s\n"
-
-msgid "line too long - skipped\n"
-msgstr "regel is te lang - overgeslagen\n"
-
-msgid "line shortened due to embedded Nul character\n"
-msgstr "regel werd ingekort wegens een ingebed NULL-teken\n"
-
-#, c-format
-msgid "unknown command `%s'\n"
-msgstr "onbekende opdracht `%s'\n"
-
-#, c-format
-msgid "sending line failed: %s\n"
-msgstr "regel versturen is mislukt: %s\n"
-
-#, c-format
-msgid "error sending %s command: %s\n"
-msgstr "fout bij het versturen van opdracht %s: %s\n"
-
-#, c-format
-msgid "error sending standard options: %s\n"
-msgstr "fout bij het versturen van standaardopties: %s\n"
-
-msgid "Options controlling the diagnostic output"
-msgstr "Opties die de diagnostische uitvoer sturen"
-
-msgid "Options controlling the configuration"
-msgstr "Opties die de configuratie-instellingen sturen"
-
-msgid "Options useful for debugging"
-msgstr "Nuttige opties voor foutenanalyse (debugging)"
-
-msgid "|FILE|write server mode logs to FILE"
-msgstr "|BESTAND|schrijf logboekgegevens in server-modus naar BESTAND"
-
-msgid "Options controlling the security"
-msgstr "Opties die de beveiliging sturen"
-
-msgid "|N|expire SSH keys after N seconds"
-msgstr "|N|laat SSH-sleutels na N seconden verlopen"
-
-msgid "|N|set maximum PIN cache lifetime to N seconds"
-msgstr ""
-"|N|stel de maximale levensduur van de cache van de pincode in op N seconden"
-
-msgid "|N|set maximum SSH key lifetime to N seconds"
-msgstr "|N|stel de maximale levensduur van een SSH-sleutel in op N seconden"
-
-msgid "Options enforcing a passphrase policy"
-msgstr ""
-"Opties voor het toepassen van richtlijnen in verband met wachtwoordzinnen"
-
-msgid "do not allow to bypass the passphrase policy"
-msgstr "sta niet toe om de richtlijnen inzake wachtwoordzinnen te omzeilen"
-
-msgid "|N|set minimal required length for new passphrases to N"
-msgstr "|N|stel de minimale lengte voor nieuwe wachtwoordzinnen in op N"
-
-msgid "|N|require at least N non-alpha characters for a new passphrase"
-msgstr ""
-"|N|stel als vereiste dat een nieuwe wachtwoordzin minstens N niet-alfa "
-"tekens moet bevatten"
-
-msgid "|FILE|check new passphrases against pattern in FILE"
-msgstr "|BESTAND|toets nieuwe wachtwoordzinnen af aan het patroon in BESTAND"
-
-msgid "|N|expire the passphrase after N days"
-msgstr "|N|laat de wachtwoordzin na N dagen vervallen"
-
-msgid "do not allow the reuse of old passphrases"
-msgstr "laat het opnieuw gebruiken van oude wachtwoordzinnen niet toe"
-
-msgid "|NAME|use NAME as default secret key"
-msgstr "|NAAM|gebruik NAAM als standaard geheime sleutel"
-
-msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|NAAM|versleutel ook naar gebruikers-ID NAAM"
-
-msgid "|SPEC|set up email aliases"
-msgstr "|SPEC|stel e-mail aliassen in"
-
-msgid "Configuration for Keyservers"
-msgstr "Instellingen voor Sleutelservers"
-
-msgid "|URL|use keyserver at URL"
-msgstr "|URL|gebruik de sleutelserver op URL"
-
-msgid "allow PKA lookups (DNS requests)"
-msgstr "sta PKA-opzoekingen toe (DNS-verzoeken)"
-
-msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
-msgstr ""
-"|MECHANISME|gebruik MECHANISME om sleutels via e-mailadressen te localiseren"
-
-msgid "disable all access to the dirmngr"
-msgstr "deactiveer alle toegang tot de dirmngr"
-
-msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr ""
-"|NAAM|gebruik codering NAAM voor wachtwoordzinnen van het formaat PKCS#12"
-
-msgid "do not check CRLs for root certificates"
-msgstr ""
-"voer voor stamcertificaten geen controle uit bij de lijst van ingetrokken "
-"certificaten"
-
-msgid "Options controlling the format of the output"
-msgstr "Opties om het formaat van de uitvoer te sturen"
-
-msgid "Options controlling the interactivity and enforcement"
-msgstr "Opties die een invloed hebben op de interactiviteit en de uitvoering"
-
-msgid "Configuration for HTTP servers"
-msgstr "Configuratie van de HTTP-servers"
-
-msgid "use system's HTTP proxy setting"
-msgstr "gebruik de instellingen van het systeem met betrekking tot HTTP proxy"
-
-msgid "Configuration of LDAP servers to use"
-msgstr "Te gebruiken configuratie voor de LDAP-servers"
-
-msgid "LDAP server list"
-msgstr "Lijst van LDAP-servers"
-
-msgid "Configuration for OCSP"
-msgstr "Configuratie van OCSP"
-
-#, c-format
-msgid "External verification of component %s failed"
-msgstr "Externe verificatie van component %s is mislukt"
-
-msgid "Note that group specifications are ignored\n"
-msgstr "Noteer dat groepsspecificaties genegeerd worden\n"
-
-msgid "list all components"
-msgstr "toon alle componenten"
-
-msgid "check all programs"
-msgstr "controleer alle programma's"
-
-msgid "|COMPONENT|list options"
-msgstr "|COMPONENT|toon opties"
-
-msgid "|COMPONENT|change options"
-msgstr "|COMPONENT|wijzig opties"
-
-msgid "|COMPONENT|check options"
-msgstr "|COMPONENT|controleer opties"
-
-msgid "apply global default values"
-msgstr "pas de globale standaardwaarden toe"
-
-msgid "get the configuration directories for gpgconf"
-msgstr "haal de mappen op met de configuratie-instellingen van gpgconf"
-
-msgid "list global configuration file"
-msgstr "toon het bestand met de globale configuratie-instellingen"
-
-msgid "check global configuration file"
-msgstr "controleer het bestand met de globale configuratie-instellingen"
-
-msgid "use as output file"
-msgstr "gebruik als uitvoerbestand"
-
-msgid "activate changes at runtime, if possible"
-msgstr ""
-"pas indien mogelijk wijzigingen nog toe tijdens de uitvoering van het "
-"programma"
-
-msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Gebruik: gpgconf [opties] (-h voor hulp)"
-
-msgid ""
-"Syntax: gpgconf [options]\n"
-"Manage configuration options for tools of the GnuPG system\n"
-msgstr ""
-"Syntaxis: gpgconf [opties]\n"
-"Beheer de configuratieopties van de instrumenten van het GnuPG-systeem\n"
-
-msgid "usage: gpgconf [options] "
-msgstr "gebruik: gpgconf [opties] "
-
-msgid "Need one component argument"
-msgstr "Een component als argument is vereist"
-
-msgid "Component not found"
-msgstr "Component niet gevonden"
-
-msgid "No argument allowed"
-msgstr "Een argument is niet toegelaten"
-
-msgid ""
-"@\n"
-"Commands:\n"
-" "
-msgstr ""
-"@\n"
-"Commando's:\n"
-" "
-
-msgid "decryption modus"
-msgstr "ontcijferingsmodus"
-
-msgid "encryption modus"
-msgstr "encryptiemodus"
-
-msgid "tool class (confucius)"
-msgstr "klasse van instrumenten (confucius)"
-
-msgid "program filename"
-msgstr "bestandsnaam van het programma"
-
-msgid "secret key file (required)"
-msgstr "geheime-sleutelbestand (verplicht)"
-
-msgid "input file name (default stdin)"
-msgstr "bestandsnaam voor de invoer (standaard is stdin)"
-
-msgid "Usage: symcryptrun [options] (-h for help)"
-msgstr "Gebruik: symcryptrun [opties] (-h voor hulp)"
-
-msgid ""
-"Syntax: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE "
-"[options...] COMMAND [inputfile]\n"
-"Call a simple symmetric encryption tool\n"
-msgstr ""
-"Syntaxis: symcryptrun --class KLASSE --program PROGRAMMA --keyfile "
-"SLEUTELBESTAND [opties...] COMMANDO [invoerbestand]\n"
-"Uitvoeren van een eenvoudig hulpmiddel voor symmetrische versleuteling\n"
-
-#, c-format
-msgid "%s on %s aborted with status %i\n"
-msgstr "%s op %s afgebroken met status %i\n"
-
-#, c-format
-msgid "%s on %s failed with status %i\n"
-msgstr "%s op %s mislukte met status %i\n"
-
-#, c-format
-msgid "can't create temporary directory `%s': %s\n"
-msgstr "kan tijdelijke map `%s' niet maken: %s\n"
-
-#, c-format
-msgid "could not open %s for writing: %s\n"
-msgstr "kon %s niet openen om er naar te schrijven: %s\n"
-
-#, c-format
-msgid "error writing to %s: %s\n"
-msgstr "fout bij het schrijven naar %s: %s\n"
-
-#, c-format
-msgid "error reading from %s: %s\n"
-msgstr "fout bij het lezen uit %s: %s\n"
-
-#, c-format
-msgid "error closing %s: %s\n"
-msgstr "fout bij het sluiten van %s: %s\n"
-
-msgid "no --program option provided\n"
-msgstr "geen optie --program meegegeven\n"
-
-msgid "only --decrypt and --encrypt are supported\n"
-msgstr "enkel --decrypt en --encrypt worden ondersteund\n"
-
-msgid "no --keyfile option provided\n"
-msgstr "geen optie --keyfile meegegeven\n"
-
-msgid "cannot allocate args vector\n"
-msgstr "kan de parametervector niet reserveren\n"
-
-#, c-format
-msgid "could not create pipe: %s\n"
-msgstr "kon pijp niet aanmaken: %s\n"
-
-#, c-format
-msgid "could not create pty: %s\n"
-msgstr "kon pty niet aanmaken: %s\n"
-
-#, c-format
-msgid "could not fork: %s\n"
-msgstr "kon geen nieuw programma (fork) starten: %s\n"
-
-#, c-format
-msgid "execv failed: %s\n"
-msgstr "execv is mislukt: %s\n"
-
-#, c-format
-msgid "select failed: %s\n"
-msgstr "selecteren is mislukt: %s\n"
-
-#, c-format
-msgid "read failed: %s\n"
-msgstr "lezen is mislukt: %s\n"
-
-#, c-format
-msgid "pty read failed: %s\n"
-msgstr "lezen van pty is mislukt: %s\n"
-
-#, c-format
-msgid "waitpid failed: %s\n"
-msgstr "waitpid is mislukt: %s\n"
-
-#, c-format
-msgid "child aborted with status %i\n"
-msgstr "kindproces werd afgebroken met status %i\n"
-
-#, c-format
-msgid "cannot allocate infile string: %s\n"
-msgstr "kan de tekenreeks infile niet reserveren: %s\n"
-
-#, c-format
-msgid "cannot allocate outfile string: %s\n"
-msgstr "kan de tekenreeks outfile niet reserveren: %s\n"
-
-#, c-format
-msgid "either %s or %s must be given\n"
-msgstr "ofwel %s of %s moet opgegeven worden\n"
-
-msgid "no class provided\n"
-msgstr "geen klasse opgegeven\n"
-
-#, c-format
-msgid "class %s is not supported\n"
-msgstr "klasse %s wordt niet ondersteund\n"
-
-msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n"
-msgstr "Gebruik: gpg-check-pattern [opties] patroonbestand (-h voor hulp)\n"
-
-msgid ""
-"Syntax: gpg-check-pattern [options] patternfile\n"
-"Check a passphrase given on stdin against the patternfile\n"
-msgstr ""
-"Syntaxis: gpg-check-pattern [opties] patroonbestand\n"
-"Toets een wachtwoordzin die op stdin ingevoerd werd, aan een patroonbestand\n"
-
-#~ msgid "can't gen prime with pbits=%u qbits=%u\n"
-#~ msgstr "kan geen priemgetal genereren met pbits=%u qbits=%u\n"
-
-#~ msgid "can't generate a prime with less than %d bits\n"
-#~ msgstr "kan geen priemgetal genereren van minder dan %d bits\n"
-
-#~ msgid "no entropy gathering module detected\n"
-#~ msgstr "geen module gevonden om entropie te verzamelen\n"
-
-#~ msgid "can't lock `%s': %s\n"
-#~ msgstr "kan `%s' niet vergrendelen: %s\n"
-
-#~ msgid "can't stat `%s': %s\n"
-#~ msgstr "kan status van `%s' niet vaststellen: %s\n"
-
-#~ msgid "`%s' is not a regular file - ignored\n"
-#~ msgstr "`%s' is geen gewoon bestand - wordt genegeerd\n"
-
-#~ msgid "note: random_seed file is empty\n"
-#~ msgstr "noot: bestand random_seed is leeg\n"
-
-#~ msgid "WARNING: invalid size of random_seed file - not used\n"
-#~ msgstr ""
-#~ "WAARSCHUWING: ongeldige grootte van het bestand random_seed - wordt niet "
-#~ "gebruikt\n"
-
-#~ msgid "can't read `%s': %s\n"
-#~ msgstr "kan `%s' niet lezen: %s\n"
-
-#~ msgid "note: random_seed file not updated\n"
-#~ msgstr "noot: bestand random_seed wordt niet bijgewerkt\n"
-
-#~ msgid "can't write `%s': %s\n"
-#~ msgstr "kan `%s' niet wegschrijven: %s\n"
-
-#~ msgid "can't close `%s': %s\n"
-#~ msgstr "kan `%s' niet afsluiten: %s\n"
-
-#~ msgid "WARNING: using insecure random number generator!!\n"
-#~ msgstr ""
-#~ "WAARSCHUWING: er wordt een onveilige generator van willekeurige getallen "
-#~ "gebruikt!!\n"
-
-#~ msgid ""
-#~ "The random number generator is only a kludge to let\n"
-#~ "it run - it is in no way a strong RNG!\n"
-#~ "\n"
-#~ "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n"
-#~ "\n"
-#~ msgstr ""
-#~ "De generator van willekeurige getallen is alleen maar een zootje "
-#~ "ongeregeld\n"
-#~ "om iets te hebben dat werkt - het is niet echt een sterk programma!\n"
-#~ "\n"
-#~ "GEBRUIK DE DOOR DIT PROGRAMMA GEGENEREERDE GEGEVENS NIET!!\n"
-#~ "\n"
-
-#~ msgid ""
-#~ "Please wait, entropy is being gathered. Do some work if it would\n"
-#~ "keep you from getting bored, because it will improve the quality\n"
-#~ "of the entropy.\n"
-#~ msgstr ""
-#~ "Ogenblik geduld, entropie wordt verzameld. Werk intussen wat.\n"
-#~ "Het zal er niet enkel voor zorgen dat u zich niet gaat vervelen, het\n"
-#~ "zal tegelijk de kwaliteit van de entropie verbeteren.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Not enough random bytes available.  Please do some other work to give\n"
-#~ "the OS a chance to collect more entropy! (Need %d more bytes)\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Er zijn niet genoeg willekeurige bytes beschikbaar. Doe wat ander werk om "
-#~ "het OS\n"
-#~ "de gelegenheid te geven meer entropie te verzamelen! (heb nog %d bytes "
-#~ "nodig)\n"
-
-#~ msgid "card reader not available\n"
-#~ msgstr "kaartlezer is niet beschikbaar\n"
-
-#~ msgid "Please insert the card and hit return or enter 'c' to cancel: "
-#~ msgstr "Plaats de kaart en druk op enter of op 'c' om te cancelen: "
-
-#~ msgid "Hit return when ready or enter 'c' to cancel: "
-#~ msgstr "Druk op enter als u klaar bent of op 'c' om te cancelen: "
-
-#~ msgid "Enter New Admin PIN: "
-#~ msgstr "Voer de nieuwe pincode voor de beheerder in: "
-
-#~ msgid "Enter New PIN: "
-#~ msgstr "Voer nieuwe pincode in: "
-
-#~ msgid "Enter Admin PIN: "
-#~ msgstr "Voer de pincode voor de beheerder in: "
-
-#~ msgid "generate PGP 2.x compatible messages"
-#~ msgstr "berichten aanmaken die compatibel zijn met PGP 2.x"
-
-#~ msgid "NOTE: %s is not available in this version\n"
-#~ msgstr "NOOT: %s is niet beschikbaar in deze versie\n"
-
-#~ msgid "-k[v][v][v][c] [user-id] [keyring]"
-#~ msgstr "-k[v][v][v][c] [gebruikers-id] [sleutelring]"
-
-#~ msgid ""
-#~ "It's up to you to assign a value here; this value will never be exported\n"
-#~ "to any 3rd party.  We need it to implement the web-of-trust; it has "
-#~ "nothing\n"
-#~ "to do with the (implicitly created) web-of-certificates."
-#~ msgstr ""
-#~ "Het is aan u om hier een waarde toe te kennen; deze waarde zal nooit naar "
-#~ "een\n"
-#~ "derde partij geëxporteerd worden. We hebben ze nodig om het netwerk-van-"
-#~ "vertrouwen\n"
-#~ "(web-of-trust) te implementeren. Dit heeft niets te maken met het "
-#~ "(impliciet\n"
-#~ "aangemaakte) netwerk-van-certificaten (web-of-certificates)."
-
-#~ msgid ""
-#~ "To build the Web-of-Trust, GnuPG needs to know which keys are\n"
-#~ "ultimately trusted - those are usually the keys for which you have\n"
-#~ "access to the secret key.  Answer \"yes\" to set this key to\n"
-#~ "ultimately trusted\n"
-#~ msgstr ""
-#~ "Om het netwerk-van-vertrouwen op te bouwen, moet GnuPG weten welke "
-#~ "sleutels\n"
-#~ "volledig vertrouwd worden. Dit zijn gewoonlijk de sleutels waarvoor u ook "
-#~ "toegang\n"
-#~ "tot de geheime sleutel heeft. Antwoord \"yes\" om deze sleutel in te\n"
-#~ "stellen als volledig te vertrouwen.\n"
-
-#~ msgid "If you want to use this untrusted key anyway, answer \"yes\"."
-#~ msgstr ""
-#~ "Als u deze niet-vertrouwde sleutel toch wilt gebruiken, antwoord dan \"yes"
-#~ "\"."
-
-#~ msgid ""
-#~ "Enter the user ID of the addressee to whom you want to send the message."
-#~ msgstr "Voer het gebruikers-ID in van de ontvanger van dit bericht."
-
-#~ msgid ""
-#~ "Select the algorithm to use.\n"
-#~ "\n"
-#~ "DSA (aka DSS) is the Digital Signature Algorithm and can only be used\n"
-#~ "for signatures.\n"
-#~ "\n"
-#~ "Elgamal is an encrypt-only algorithm.\n"
-#~ "\n"
-#~ "RSA may be used for signatures or encryption.\n"
-#~ "\n"
-#~ "The first (primary) key must always be a key which is capable of signing."
-#~ msgstr ""
-#~ "Selecteer het te gebruiken algoritme.\n"
-#~ "\n"
-#~ "DSA (ook bekend als DSS) is het algoritme voor digitale handtekeningen\n"
-#~ "(Digital Signature Algorithm) dat enkel voor ondertekeningen kan gebruikt "
-#~ "worden.\n"
-#~ "\n"
-#~ "Elgamal is een algoritme enkel bedoeld voor versleuteling.\n"
-#~ "\n"
-#~ "RSA kan gebruikt worden voor ondertekeningen en versleuteling.\n"
-#~ "\n"
-#~ "De eerste (primaire) sleutel moet altijd een sleutel zijn waarmee "
-#~ "ondertekend\n"
-#~ "kan worden."
-
-#~ msgid ""
-#~ "In general it is not a good idea to use the same key for signing and\n"
-#~ "encryption.  This algorithm should only be used in certain domains.\n"
-#~ "Please consult your security expert first."
-#~ msgstr ""
-#~ "In het algemeen is het geen goed idee om dezelfde sleutel te gebruiken "
-#~ "om\n"
-#~ "te ondertekenen en te versleutelen. Dit algoritme zou enkel in bepaalde "
-#~ "domeinen\n"
-#~ "gebruikt mogen worden. Vraag eerst een beveiligingsspecialist om advies."
-
-#~ msgid "Enter the size of the key"
-#~ msgstr "Voer de lengte van de sleutel in"
-
-#~ msgid "Answer \"yes\" or \"no\""
-#~ msgstr "Antwoord \"yes\" (Ja) of \"no\" (nee)"
-
-#~ msgid ""
-#~ "Enter the required value as shown in the prompt.\n"
-#~ "It is possible to enter a ISO date (YYYY-MM-DD) but you won't\n"
-#~ "get a good error response - instead the system tries to interpret\n"
-#~ "the given value as an interval."
-#~ msgstr ""
-#~ "Geef de vereiste waarde op, zoals getoond in de vraag.\n"
-#~ "Het is mogelijk om een datum in ISO-formaat (JJJJ-MM-DD) in te voeren, "
-#~ "maar u\n"
-#~ "zult geen passende foutmelding krijgen - het systeem zal daarentegen "
-#~ "proberen\n"
-#~ "om de ingevoerde waarde te interpreteren als een interval."
-
-#~ msgid "Enter the name of the key holder"
-#~ msgstr "Geef de naam van de sleutelhouder"
-
-#~ msgid "please enter an optional but highly suggested email address"
-#~ msgstr ""
-#~ "geef alstublieft een e-mailadres, dit is niet verplicht maar wel sterk "
-#~ "aangeraden"
-
-#~ msgid "Please enter an optional comment"
-#~ msgstr "Geef eventueel een toelichting. Dit is facultatief"
-
-#~ msgid ""
-#~ "N  to change the name.\n"
-#~ "C  to change the comment.\n"
-#~ "E  to change the email address.\n"
-#~ "O  to continue with key generation.\n"
-#~ "Q  to quit the key generation."
-#~ msgstr ""
-#~ "N  om de de naam te veranderen.\n"
-#~ "C  om de toelichting te veranderen.\n"
-#~ "E  om het e-mailadres te veranderen.\n"
-#~ "O  om door te gaan met het aanmaken van de sleutel.\n"
-#~ "Q  om het aanmaken van de sleutel af te breken."
-
-#~ msgid ""
-#~ "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key."
-#~ msgstr ""
-#~ "Antwoord \"yes\" (of alleen \"y\") als het oké is om de subsleutel te "
-#~ "maken."
-
-#~ msgid ""
-#~ "When you sign a user ID on a key, you should first verify that the key\n"
-#~ "belongs to the person named in the user ID.  It is useful for others to\n"
-#~ "know how carefully you verified this.\n"
-#~ "\n"
-#~ "\"0\" means you make no particular claim as to how carefully you verified "
-#~ "the\n"
-#~ "    key.\n"
-#~ "\n"
-#~ "\"1\" means you believe the key is owned by the person who claims to own "
-#~ "it\n"
-#~ "    but you could not, or did not verify the key at all.  This is useful "
-#~ "for\n"
-#~ "    a \"persona\" verification, where you sign the key of a pseudonymous "
-#~ "user.\n"
-#~ "\n"
-#~ "\"2\" means you did casual verification of the key.  For example, this "
-#~ "could\n"
-#~ "    mean that you verified the key fingerprint and checked the user ID on "
-#~ "the\n"
-#~ "    key against a photo ID.\n"
-#~ "\n"
-#~ "\"3\" means you did extensive verification of the key.  For example, this "
-#~ "could\n"
-#~ "    mean that you verified the key fingerprint with the owner of the key "
-#~ "in\n"
-#~ "    person, and that you checked, by means of a hard to forge document "
-#~ "with a\n"
-#~ "    photo ID (such as a passport) that the name of the key owner matches "
-#~ "the\n"
-#~ "    name in the user ID on the key, and finally that you verified (by "
-#~ "exchange\n"
-#~ "    of email) that the email address on the key belongs to the key "
-#~ "owner.\n"
-#~ "\n"
-#~ "Note that the examples given above for levels 2 and 3 are *only* "
-#~ "examples.\n"
-#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive"
-#~ "\"\n"
-#~ "mean to you when you sign other keys.\n"
-#~ "\n"
-#~ "If you don't know what the right answer is, answer \"0\"."
-#~ msgstr ""
-#~ "Als U een gebruikers-ID koppelt aan een sleutel, moet U eerst nagaan of "
-#~ "de\n"
-#~ "sleutel echt van de persoon is die in het gebruikers-ID genoemd wordt.\n"
-#~ "Voor anderen is het van belang te weten dat U dit grondig gecontroleerd "
-#~ "heeft.\n"
-#~ "\n"
-#~ "\"0\" betekent dat U zich niet uitspreekt over hoe grondig U deze "
-#~ "sleutel\n"
-#~ "    heeft gecontroleerd\n"
-#~ "\n"
-#~ "\"1\" betekent dat U gelooft dat de sleutel eigendom is van de persoon "
-#~ "die beweert\n"
-#~ "    er eigenaar van te zijn, maar dat u de sleutel niet controleerde of "
-#~ "dit\n"
-#~ "    niet kon doen. Dit is zinvol in geval van een \"persona\"-verificatie "
-#~ "bij\n"
-#~ "    het ondertekenen van de sleutel van het pseudoniem van een "
-#~ "gebruiker.\n"
-#~ "\n"
-#~ "\"2\" betekent dat U de sleutel vluchtig gecontroleerd heeft. Dit kan "
-#~ "bijvoorbeeld\n"
-#~ "    betekenen dat u de vingerafdruk van de sleutel gecontroleerd heeft en "
-#~ "de\n"
-#~ "    gebruikers-ID getoetst heeft aan een identiteitsfoto.\n"
-#~ "\n"
-#~ "\"3\" betekent dat u de sleutel uitvoerig heeft gecontroleerd. Dit kan "
-#~ "bijvoorbeeld\n"
-#~ "    betekenen dat U de vingerafdruk van de sleutel persoonlijk "
-#~ "gecontroleerd\n"
-#~ "    heeft bij de eigenaar van de sleutel, en dat u gecontroleerd heeft "
-#~ "aan de hand\n"
-#~ "    van een foto op een moeilijk te vervalsen document (zoals een "
-#~ "paspoort)\n"
-#~ "    dat de naam van de eigenaar van de sleutel overeenkomt met de naam in "
-#~ "de\n"
-#~ "    gebruikers-ID op de sleutel, en dat u tenslotte gecontroleerd heeft "
-#~ "(via het\n"
-#~ "    uitwisselen van e-mail) dat het e-mailadres op de sleutel effectief "
-#~ "van\n"
-#~ "    de eigenaar van de sleutel is.\n"
-#~ "\n"
-#~ "Noteer dat de gegeven voorbeelden voor de niveaus 2 en 3 *slechts* "
-#~ "voorbeelden\n"
-#~ "zijn. Uiteindelijk moet U zelf uitmaken wat voor u de betekenis is van "
-#~ "\"vluchtig\"\n"
-#~ "en \"uitvoerig\" bij het ondertekenen van sleutels van anderen.\n"
-#~ "\n"
-#~ "Indien u twijfelt over wat het correcte antwoord is, antwoord dan \"0\"."
-
-#~ msgid "Answer \"yes\" if you want to sign ALL the user IDs"
-#~ msgstr "Antwoord \"yes\" als U ALLE gebruikers-ID's wilt tekenen."
-
-#~ msgid ""
-#~ "Answer \"yes\" if you really want to delete this user ID.\n"
-#~ "All certificates are then also lost!"
-#~ msgstr ""
-#~ "Antwoord \"yes\" als u werkelijk deze gebruikers-ID wilt wissen.\n"
-#~ "Alle bijbehorende certificaten worden ook gewist!"
-
-#~ msgid "Answer \"yes\" if it is okay to delete the subkey"
-#~ msgstr "Antwoord \"yes\" als het oké is om de subsleutel te wissen"
-
-#~ msgid ""
-#~ "This is a valid signature on the key; you normally don't want\n"
-#~ "to delete this signature because it may be important to establish a\n"
-#~ "trust connection to the key or another key certified by this key."
-#~ msgstr ""
-#~ "Dit is een geldige ondertekening van de sleutel; normaal gezien wilt U "
-#~ "deze\n"
-#~ "ondertekening niet wissen. omdat ze belangrijk kan zijn voor het opzetten "
-#~ "van een\n"
-#~ "betrouwbare relatie met behulp van deze sleutel of met een andere sleutel "
-#~ "die met\n"
-#~ "deze sleutel gecertificeerd werd."
-
-#~ msgid ""
-#~ "This signature can't be checked because you don't have the\n"
-#~ "corresponding key.  You should postpone its deletion until you\n"
-#~ "know which key was used because this signing key might establish\n"
-#~ "a trust connection through another already certified key."
-#~ msgstr ""
-#~ "Deze ondertekening kan niet worden gecontroleerd omdat u de bijbehorende\n"
-#~ "sleutel niet heeft. U wordt aangeraden om het verwijderen ervan uit te "
-#~ "stellen\n"
-#~ "totdat u weet welke sleutel gebruikt geweest is, omdat deze "
-#~ "ondertekenende\n"
-#~ "sleutel misschien een betrouwbare relatie tot stand brengt via\n"
-#~ "een andere reeds gecertificeerde sleutel."
-
-#~ msgid ""
-#~ "The signature is not valid.  It does make sense to remove it from\n"
-#~ "your keyring."
-#~ msgstr ""
-#~ "De ondertekening is niet geldig. Het is een goed idee om ze van uw "
-#~ "sleutelring\n"
-#~ "af te halen."
-
-#~ msgid ""
-#~ "This is a signature which binds the user ID to the key. It is\n"
-#~ "usually not a good idea to remove such a signature.  Actually\n"
-#~ "GnuPG might not be able to use this key anymore.  So do this\n"
-#~ "only if this self-signature is for some reason not valid and\n"
-#~ "a second one is available."
-#~ msgstr ""
-#~ "Dit is een ondertekening die de gebruikers-ID aan de sleutel koppelt. "
-#~ "Het\n"
-#~ "is meestal niet goed om een dergelijke handtekening te verwijderen. "
-#~ "Waarschijnlijk\n"
-#~ "zal GnuPG deze sleutel dan niet meer kunnen gebruiken. Doe dit dus alleen "
-#~ "als deze\n"
-#~ "zelf geplaatste handtekening om een of andere reden niet geldig is en er\n"
-#~ "een andere beschikbaar is."
-
-#~ msgid ""
-#~ "Change the preferences of all user IDs (or just of the selected ones)\n"
-#~ "to the current list of preferences.  The timestamp of all affected\n"
-#~ "self-signatures will be advanced by one second.\n"
-#~ msgstr ""
-#~ "Vervang de voorkeuren van alle (of alleen de gekozen) gebruikers-ID's\n"
-#~ "door de huidige lijst van voorkeuren. De tijdsindicatie van alle "
-#~ "betrokken\n"
-#~ "zelf geplaatste handtekeningen zal met een seconde worden verhoogd.\n"
-
-#~ msgid ""
-#~ "Please repeat the last passphrase, so you are sure what you typed in."
-#~ msgstr ""
-#~ "Herhaal de laatste wachtwoordzin, om zeker te zijn dat u die juist "
-#~ "intypte."
-
-#~ msgid "Give the name of the file to which the signature applies"
-#~ msgstr ""
-#~ "Geef de naam van het bestand waarop deze handtekening van toepassing is"
-
-#~ msgid "Answer \"yes\" if it is okay to overwrite the file"
-#~ msgstr "Antwoord \"yes\" als het oké is om bestand te overschrijven"
-
-#~ msgid ""
-#~ "Please enter a new filename. If you just hit RETURN the default\n"
-#~ "file (which is shown in brackets) will be used."
-#~ msgstr ""
-#~ "Geef alstublieft een nieuwe bestandsnaam. Als U gewoon op Enter drukt zal "
-#~ "het\n"
-#~ "standaardbestand (u ziet zijn naam tussen de blokhaken) gebruikt worden."
-
-#~ msgid ""
-#~ "You should specify a reason for the certification.  Depending on the\n"
-#~ "context you have the ability to choose from this list:\n"
-#~ "  \"Key has been compromised\"\n"
-#~ "      Use this if you have a reason to believe that unauthorized persons\n"
-#~ "      got access to your secret key.\n"
-#~ "  \"Key is superseded\"\n"
-#~ "      Use this if you have replaced this key with a newer one.\n"
-#~ "  \"Key is no longer used\"\n"
-#~ "      Use this if you have retired this key.\n"
-#~ "  \"User ID is no longer valid\"\n"
-#~ "      Use this to state that the user ID should not longer be used;\n"
-#~ "      this is normally used to mark an email address invalid.\n"
-#~ msgstr ""
-#~ "Geef hier een reden voor de certificering. Afhankelijk van de context "
-#~ "kunt U\n"
-#~ "een omschrijving kiezen uit deze lijst:\n"
-#~ "  \"Sleutel is gecompromitteerd\"\n"
-#~ "      Gebruik dit indien u redenen heeft om aan te nemen dat onbevoegde\n"
-#~ "      personen uw geheime sleutel in handen gekregen hebben.\n"
-#~ "  \"Sleutel is vervangen\"\n"
-#~ "      Gebruik dit als u deze sleutel door een nieuwe vervangen heeft.\n"
-#~ "  \"Sleutel wordt niet langer gebruikt\"\n"
-#~ "      Gebruik dit indien u deze sleutel ingetrokken heeft.\n"
-#~ "  \"Gebruikers-ID is niet langer geldig\"\n"
-#~ "      Gebruik dit om te stellen dat deze gebruikers-ID niet langer "
-#~ "gebruikt\n"
-#~ "      zou moeten worden. Gewoonlijk gebruikt men dit om een e-mailadres "
-#~ "als\n"
-#~ "      niet langer geldig te markeren.\n"
-
-#~ msgid ""
-#~ "If you like, you can enter a text describing why you issue this\n"
-#~ "revocation certificate.  Please keep this text concise.\n"
-#~ "An empty line ends the text.\n"
-#~ msgstr ""
-#~ "Als U wilt kunt U een tekst intypen met uitleg waarom u dit\n"
-#~ "certificaat van intrekking maakt. Hou deze tekst beknopt.\n"
-#~ "Beëindig de tekst met een lege regel.\n"
-
-#~ msgid "         algorithms on these user IDs:\n"
-#~ msgstr "         algoritmes bij deze gebruikers-ID's:\n"
-
-#~ msgid "NOTE: This feature is not available in %s\n"
-#~ msgstr "NOOT: Deze functionaliteit is niet beschikbaar in %s\n"
-
-#~ msgid "Repeat passphrase\n"
-#~ msgstr "Herhaal wachtwoordzin\n"
-
-#~ msgid "can't query passphrase in batch mode\n"
-#~ msgstr "kan geen wachtwoordzin vragen in automatische modus\n"
-
-#~ msgid "Enter passphrase: "
-#~ msgstr "Voer wachtwoordzin in: "
-
-#~ msgid "Repeat passphrase: "
-#~ msgstr "Herhaal wachtwoordzin: "
-
-#~ msgid "no photo viewer set\n"
-#~ msgstr "geen programma ingesteld om de foto te bekijken\n"
-
-#~ msgid "general error"
-#~ msgstr "algemene fout"
-
-#~ msgid "unknown packet type"
-#~ msgstr "onbekend pakkettype"
-
-#~ msgid "unknown pubkey algorithm"
-#~ msgstr "onbekend algoritme van de publieke sleutel"
-
-#~ msgid "unknown digest algorithm"
-#~ msgstr "onbekend hashalgoritme"
-
-#~ msgid "bad public key"
-#~ msgstr "slechte publieke sleutel"
-
-#~ msgid "bad secret key"
-#~ msgstr "slechte geheime sleutel"
-
-#~ msgid "bad signature"
-#~ msgstr "slechte handtekening"
-
-#~ msgid "checksum error"
-#~ msgstr "fout in de controlesom"
-
-#~ msgid "can't open the keyring"
-#~ msgstr "kan de sleutelring niet openen"
-
-#~ msgid "invalid packet"
-#~ msgstr "ongeldig pakket"
-
-#~ msgid "no such user id"
-#~ msgstr "een dergelijk gebruikers-id bestaat niet"
-
-#~ msgid "wrong secret key used"
-#~ msgstr "er werd een verkeerde geheime sleutel gebruikt"
-
-#~ msgid "bad key"
-#~ msgstr "slechte sleutel"
-
-#~ msgid "file write error"
-#~ msgstr "fout bij het wegschrijven naar het bestand"
-
-#~ msgid "unknown compress algorithm"
-#~ msgstr "onbekend compressiealgoritme"
-
-#~ msgid "file open error"
-#~ msgstr "fout bij het openen van het bestand"
-
-#~ msgid "file create error"
-#~ msgstr "fout bij het aanmaken van het bestand"
-
-#~ msgid "unimplemented pubkey algorithm"
-#~ msgstr "niet geïmplementeerd algoritme voor de publieke sleutel"
-
-#~ msgid "unimplemented cipher algorithm"
-#~ msgstr "niet geïmplementeerd versleutelingsalgoritme"
-
-#~ msgid "unknown signature class"
-#~ msgstr "onbekende handtekeningenklasse"
-
-#~ msgid "trust database error"
-#~ msgstr "fout in de betrouwbaarheidsdatabank (trustdb)"
-
-#~ msgid "bad MPI"
-#~ msgstr "slecht MPI (geheel getal van multipele precisie)"
-
-#~ msgid "resource limit"
-#~ msgstr "bronlimiet"
-
-#~ msgid "invalid keyring"
-#~ msgstr "ongeldige sleutelring"
-
-#~ msgid "malformed user id"
-#~ msgstr "ongeldige gebruikers-id"
-
-#~ msgid "file close error"
-#~ msgstr "fout bij het sluiten van het bestand"
-
-#~ msgid "file rename error"
-#~ msgstr "fout bij het hernoemen van het bestand"
-
-#~ msgid "file delete error"
-#~ msgstr "fout bij het verwijderen van het bestand"
-
-#~ msgid "unexpected data"
-#~ msgstr "onverwachte gegevens"
-
-#~ msgid "timestamp conflict"
-#~ msgstr "dateringsconflict"
-
-#~ msgid "unusable pubkey algorithm"
-#~ msgstr "onbruikbaar algoritme van de publieke sleutel"
-
-#~ msgid "file exists"
-#~ msgstr "bestand bestaat"
-
-#~ msgid "weak key"
-#~ msgstr "zwakke sleutel"
-
-#~ msgid "bad URI"
-#~ msgstr "slechte URI"
-
-#~ msgid "unsupported URI"
-#~ msgstr "niet ondersteunde URI"
-
-#~ msgid "network error"
-#~ msgstr "netwerkfout"
-
-#~ msgid "not processed"
-#~ msgstr "niet verwerkt"
-
-#~ msgid "unusable public key"
-#~ msgstr "onbruikbare publieke sleutel"
-
-#~ msgid "unusable secret key"
-#~ msgstr "onbruikbare geheime sleutel"
-
-#~ msgid "keyserver error"
-#~ msgstr "fout van de sleutelserver"
-
-#~ msgid "no card"
-#~ msgstr "geen kaart"
-
-#~ msgid "no data"
-#~ msgstr "geen gegevens"
-
-#~ msgid "ERROR: "
-#~ msgstr "FOUT: "
-
-#~ msgid "WARNING: "
-#~ msgstr "WAARSCHUWING: "
-
-#~ msgid "... this is a bug (%s:%d:%s)\n"
-#~ msgstr "... dit is een bug (%s:%d:%s)\n"
-
-#~ msgid "WARNING: using insecure memory!\n"
-#~ msgstr "WAARSCHUWING: er wordt onveilig geheugen gebruikt!\n"
-
-#~ msgid ""
-#~ "please see http://www.gnupg.org/documentation/faqs.html for more "
-#~ "information\n"
-#~ msgstr ""
-#~ "zie http://www.gnupg.org/documentation/faqs.html voor meer informatie\n"
-
-#~ msgid "operation is not possible without initialized secure memory\n"
-#~ msgstr "bewerking is niet mogelijk zonder geïnitialiseerd veilig geheugen\n"
-
-#~ msgid "(you may have used the wrong program for this task)\n"
-#~ msgstr ""
-#~ "(misschien heeft u voor deze taak het verkeerde programma gebruikt)\n"
-
-#~ msgid "cipher extension `%s' not loaded due to unsafe permissions\n"
-#~ msgstr ""
-#~ "versleutelalgoritme uitbreiding ‘%s’ is niet geladen door onveilige\n"
-#~ "instellingen\n"
-
-#~ msgid "Command> "
-#~ msgstr "Commando> "
-
-#~ msgid "DSA keypair will have %u bits.\n"
-#~ msgstr "DSA sleutelpaar krijgt %u bits.\n"
-
-#~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
-#~ msgstr "the trustdb is corrupted; please run “gpg --fix-trustdb”.\n"
-
-#~ msgid "can't put notation data into v3 (PGP 2.x style) signatures\n"
-#~ msgstr "can't put notation data into v3 (PGP 2.x style) signatures\n"
-
-#~ msgid "can't put notation data into v3 (PGP 2.x style) key signatures\n"
-#~ msgstr "can't put notation data into v3 (PGP 2.x style) key signatures\n"
-
-#~ msgid "can't put a policy URL into v3 (PGP 2.x style) signatures\n"
-#~ msgstr "can't put a policy URL into v3 (PGP 2.x style) signatures\n"
-
-#~ msgid "can't put a policy URL into v3 key (PGP 2.x style) signatures\n"
-#~ msgstr "can't put a policy URL into v3 key (PGP 2.x style) signatures\n"
index 5198a7c..8cec82b 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -1,73 +1,32 @@
 # Gnu Privacy Guard.
-# Copyright (C) 1998, 1999, 2000, 2001, 2002,
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 
 #               2007 Free Software Foundation, Inc.
-# Janusz A. Urbanowicz <alex@bofh.net.pl>, 1999, 2000, 2001, 2002, 2003-2004
-# Jakub Bogusz <qboosh@pld-linux.org>, 2003-2014.
+# Janusz A. Urbanowicz <alex@bofh.net.pl>, 1999, 2000, 2001, 2002, 
+#                                           2003-2004(?).
+# fixes and updates by Jakub Bogusz <qboosh@pld-linux.org>, 2003-2007.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg-2.0.24\n"
+"Project-Id-Version: gnupg-2.0.7\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2014-11-21 20:42+0100\n"
+"PO-Revision-Date: 2007-11-26 19:01+0100\n"
 "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
 "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
-"Language: pl\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
 "|| n%100>=20) ? 1 : 2);\n"
 
 #, c-format
 msgid "failed to acquire the pinentry lock: %s\n"
-msgstr "nie udało się uzyskać blokady pinentry: %s\n"
-
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|_Cancel"
-msgstr "|pinentry-label|_Anuluj"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_OK"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|PIN:"
-msgstr "|pinentry-label|PIN:"
-
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|_Anuluj"
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Czy na pewno chcesz unieważnić wybrane podklucze? (t/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "Enter new passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "Wprowadź nowe hasło"
+msgstr "nie uda³o siê uzyskaæ blokady pinentry: %s\n"
 
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
+#, fuzzy
 msgid "Quality:"
-msgstr "Jakość:"
+msgstr "poprawno¶æ: %s"
 
 #. TRANSLATORS: This string is a tooltip, shown by pinentry when
 #. hovering over the quality bar.  Please use an appropriate
@@ -77,177 +36,163 @@ msgstr "Jakość:"
 #. will be used.
 msgid "pinentry.qualitybar.tooltip"
 msgstr ""
-"Jakość wpisanego wyżej tekstu.\n"
-"Kryteria jakości można uzyskać od administratora."
 
 msgid ""
 "Please enter your PIN, so that the secret key can be unlocked for this "
 "session"
-msgstr "Proszę wprowadzić swój PIN, żeby odblokować klucz tajny dla tej sesji"
+msgstr "Proszê wprowadziæ swój PIN, ¿eby odblokowaæ klucz tajny dla tej sesji"
 
 msgid ""
 "Please enter your passphrase, so that the secret key can be unlocked for "
 "this session"
 msgstr ""
-"Proszę wprowadzić swoje hasło, żeby odblokować klucz tajny dla tej sesji"
+"Proszê wprowadziæ swoje has³o, ¿eby odblokowaæ klucz tajny dla tej sesji"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
-msgstr "SETERROR %s (próba %d z %d)"
+msgstr "SETERROR %s (próba %d z %d)"
 
 msgid "PIN too long"
-msgstr "PIN zbyt długi"
+msgstr "PIN zbyt d³ugi"
 
 msgid "Passphrase too long"
-msgstr "Hasło zbyt długie"
+msgstr "Has³o zbyt d³ugie"
 
 msgid "Invalid characters in PIN"
-msgstr "Niewłaściwy znak w PIN-ie"
+msgstr "Niew³a¶ciwy znak w PIN-ie"
 
 msgid "PIN too short"
-msgstr "PIN zbyt krótki"
+msgstr "PIN zbyt krótki"
 
 msgid "Bad PIN"
 msgstr "Niepoprawny PIN"
 
 msgid "Bad Passphrase"
-msgstr "Niepoprawne hasło"
+msgstr "Niepoprawne has³o"
 
 msgid "Passphrase"
-msgstr "Hasło"
+msgstr "Has³o"
 
 #, c-format
 msgid "ssh keys greater than %d bits are not supported\n"
-msgstr "klucze ssh większe niż %d bitów nie są obsługiwane\n"
+msgstr "klucze ssh wiêksze ni¿ %d bitów nie s± obs³ugiwane\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
-msgstr "nie można utworzyć ,,%s'': %s\n"
+msgid "can't create '%s': %s\n"
+msgstr "nie mo¿na utworzyæ ,,%s'': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
-msgstr "nie można otworzyć ,,%s'': %s\n"
+msgid "can't open '%s': %s\n"
+msgstr "nie mo¿na otworzyæ ,,%s'': %s\n"
 
 #, c-format
 msgid "error getting serial number of card: %s\n"
-msgstr "błąd pobierania numeru seryjnego karty: %s\n"
+msgstr "b³±d pobierania numeru seryjnego karty: %s\n"
 
 #, c-format
 msgid "detected card with S/N: %s\n"
-msgstr "wykryto kartę o numerze seryjnym: %s\n"
+msgstr "wykryto kartê o numerze seryjnym: %s\n"
 
 #, c-format
 msgid "error getting default authentication keyID of card: %s\n"
-msgstr "błąd pobierania domyślnego keyID uwierzytelnienia karty: %s\n"
+msgstr "b³±d pobierania domy¶lnego keyID uwierzytelnienia karty: %s\n"
 
 #, c-format
 msgid "no suitable card key found: %s\n"
-msgstr "nie znaleziono pasującego klucza karty: %s\n"
+msgstr "nie znaleziono pasuj±cego klucza karty: %s\n"
 
 #, c-format
 msgid "shadowing the key failed: %s\n"
-msgstr "zaciemnienie klucza nie powiodło się: %s\n"
+msgstr "zaciemnienie klucza nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "error writing key: %s\n"
-msgstr "błąd zapisu klucza: %s\n"
-
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-"Proces ssh zarządał użycia klucza%%0a  %s%%0A  (%s)%%0ACzy zezwolić na to?"
-
-msgid "Allow"
-msgstr "Zgoda"
-
-msgid "Deny"
-msgstr "Odmowa"
+msgstr "b³±d zapisu klucza: %s\n"
 
 #, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
-msgstr "Proszę wprowadzić hasło dla klucza ssh%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
+msgstr "Proszê wprowadziæ has³o dla klucza ssh%0A  %c"
 
 msgid "Please re-enter this passphrase"
-msgstr "Proszę ponownie wprowadzić to hasło"
+msgstr "Proszê ponownie wprowadziæ to has³o"
 
 #, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
-"Proszę wprowadzić hasło do zabezpieczenia odebranego klucza tajnego%%0A   %s"
-"%%0A   %s%%0Aw miejscu przechowywania kluczy gpg-agenta"
+"Proszê wprowadziæ has³o do zabezpieczenia odebranego klucza tajnego%%0A   %s%"
+"%0A w miejscu przechowywania kluczy gpg-agenta"
 
 msgid "does not match - try again"
-msgstr "nie pasują - proszę spróbować jeszcze raz"
+msgstr "nie pasuj± - proszê spróbowaæ jeszcze raz"
 
 #, c-format
 msgid "failed to create stream from socket: %s\n"
-msgstr "nie udało się utworzyć strumienia z gniazda: %s\n"
+msgstr "nie uda³o siê utworzyæ strumienia z gniazda: %s\n"
 
 msgid "Please insert the card with serial number"
-msgstr "Proszę włożyć kartę z numerem seryjnym"
+msgstr ""
 
 msgid "Please remove the current card and insert the one with serial number"
-msgstr "Proszę wyjąć obecną kartę i włożyć kartę z numerem seryjnym"
+msgstr ""
 
 msgid "Admin PIN"
-msgstr "PIN administracyjny"
+msgstr "PIN administratora"
 
 #. TRANSLATORS: A PUK is the Personal Unblocking Code
 #. used to unblock a PIN.
 msgid "PUK"
-msgstr "PUK"
+msgstr ""
 
 msgid "Reset Code"
-msgstr "Kod resetujący"
+msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
-msgstr "%s%%0A%%0ADo wpisywania należy użyć klawiatury czytnika."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
+msgstr ""
 
+#, fuzzy
 msgid "Repeat this Reset Code"
-msgstr "Powtórz ten kod resetujący"
+msgstr "Powtórz ten PIN"
 
+#, fuzzy
 msgid "Repeat this PUK"
-msgstr "Powtórz ten PUK"
+msgstr "Powtórz ten PIN"
 
 msgid "Repeat this PIN"
-msgstr "Powtórz ten PIN"
+msgstr "Powtórz ten PIN"
 
+#, fuzzy
 msgid "Reset Code not correctly repeated; try again"
-msgstr "Kod resetujący nie powtórzony poprawnie; spróbuj jeszcze raz"
+msgstr "PIN nie powtórzony poprawnie; spróbuj jeszcze raz"
 
+#, fuzzy
 msgid "PUK not correctly repeated; try again"
-msgstr "PUK nie powtórzony poprawnie; spróbuj jeszcze raz"
+msgstr "PIN nie powtórzony poprawnie; spróbuj jeszcze raz"
 
 msgid "PIN not correctly repeated; try again"
-msgstr "PIN nie powtórzony poprawnie; spróbuj jeszcze raz"
+msgstr "PIN nie powtórzony poprawnie; spróbuj jeszcze raz"
 
 #, c-format
 msgid "Please enter the PIN%s%s%s to unlock the card"
-msgstr "Proszę wprowadzić PIN%s%s%s aby odblokować kartę"
+msgstr "Proszê wprowadziæ PIN%s%s%s aby odblokowaæ kartê"
 
 #, c-format
 msgid "error creating temporary file: %s\n"
-msgstr "błąd tworzenia pliku tymczasowego: %s\n"
+msgstr "b³±d tworzenia pliku tymczasowego: %s\n"
 
 #, c-format
 msgid "error writing to temporary file: %s\n"
-msgstr "błąd zapisu do pliku tymczasowego: %s\n"
+msgstr "b³±d zapisu do pliku tymczasowego: %s\n"
 
 msgid "Enter new passphrase"
-msgstr "Wprowadź nowe hasło"
+msgstr "Wprowad¼ nowe has³o"
 
 msgid "Take this one anyway"
 msgstr "Przyjmij je mimo to"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
 "at least %u character long."
@@ -255,16 +200,16 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
 "at least %u characters long."
 msgstr[0] ""
-"Uwaga: Wprowadzono hasło, które nie jest bezpieczne.%%0AHasło powinno mieć "
-"przynajmniej %u znak długości."
+"Uwaga: Wprowadzono has³o, które na pewno nie jest%%0Abezpieczne. Has³o "
+"powinno mieæ przynajmniej%%0A%u znak d³ugo¶ci."
 msgstr[1] ""
-"Uwaga: Wprowadzono hasło, które nie jest bezpieczne.%%0AHasło powinno mieć "
-"przynajmniej %u znaki długości."
+"Uwaga: Wprowadzono has³o, które na pewno nie jest%%0Abezpieczne. Has³o "
+"powinno mieæ przynajmniej%%0A%u znaki d³ugo¶ci."
 msgstr[2] ""
-"Uwaga: Wprowadzono hasło, które nie jest bezpieczne.%%0AHasło powinno mieć "
-"przynajmniej %u znaków długości."
+"Uwaga: Wprowadzono has³o, które na pewno nie jest%%0Abezpieczne. Has³o "
+"powinno mieæ przynajmniej%%0A%u znaków d³ugo¶ci."
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
 "contain at least %u digit or%%0Aspecial character."
@@ -272,45 +217,45 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
 "contain at least %u digits or%%0Aspecial characters."
 msgstr[0] ""
-"Uwaga: Wprowadzono hasło, które nie jest bezpieczne.%%0AHasło powinno mieć "
-"przynajmniej %u cyfrę lub%%0Aznak specjalny."
+"Uwaga: Wprowadzono has³o, które na pewno nie jest%%0Abezpieczne. Has³o "
+"powinno mieæ przynajmniej%%0A%u cyfrê lub znak specjalny."
 msgstr[1] ""
-"Uwaga: Wprowadzono hasło, które nie jest bezpieczne.%%0AHasło powinno mieć "
-"przynajmniej %u cyfry lub%%0Aznaki specjalne."
+"Uwaga: Wprowadzono has³o, które na pewno nie jest%%0Abezpieczne. Has³o "
+"powinno mieæ przynajmniej%%0A%u cyfry lub znaki specjalne."
 msgstr[2] ""
-"Uwaga: Wprowadzono hasło, które nie jest bezpieczne.%%0AHasło powinno mieć "
-"przynajmniej %u cyfr lub%%0Aznaków specjalnych."
+"Uwaga: Wprowadzono has³o, które na pewno nie jest%%0Abezpieczne. Has³o "
+"powinno mieæ przynajmniej%%0A%u cyfr lub znaków specjalnych."
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
 "a known term or match%%0Acertain pattern."
 msgstr ""
-"Uwaga: Wprowadzono hasło, które nie jest bezpieczne.%%0AHasło nie może być "
-"znanym słowem ani pasować%%0Ado określonego wzorca."
+"Uwaga: Wprowadzono has³o, które na pewno nie jest%0Abezpieczne. Has³o nie "
+"mo¿e byæ znanym s³owem%0Aani pasowaæ do okre¶lonego wzorca."
 
 #, c-format
 msgid ""
 "You have not entered a passphrase!%0AAn empty passphrase is not allowed."
-msgstr "Nie wprowadzono hasła!%0APuste hasło nie jest dozwolone."
+msgstr "Nie wprowadzono has³a!%0APuste has³o nie jest dozwolone."
 
 #, c-format
 msgid ""
 "You have not entered a passphrase - this is in general a bad idea!%0APlease "
 "confirm that you do not want to have any protection on your key."
 msgstr ""
-"Nie wprowadzono hasła - to jest ogólnie zły pomysł!%0AProszę potwierdzić, że "
-"naprawdę ma nie być żadnej ochrony tego klucza."
+"Nie wprowadzono has³a - to jest ogólnie z³y pomys³!%0AProszê potwierdziæ, ¿e "
+"naprawdê ma nie byæ ¿adnej ochrony tego klucza."
 
 msgid "Yes, protection is not needed"
 msgstr "Tak, ochrona nie jest potrzebna"
 
 #, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
-msgstr "Proszę wprowadzić hasło do%0Azabezpieczenia swojego nowego klucza"
+msgid "Please enter the passphrase to%0Ato protect your new key"
+msgstr "Proszê wprowadziæ has³o do%0Azabezpieczenia swojego nowego klucza"
 
 msgid "Please enter the new passphrase"
-msgstr "Proszę wprowadzić nowe hasło"
+msgstr "Proszê wprowadziæ nowe has³o"
 
 msgid ""
 "@Options:\n"
@@ -319,23 +264,23 @@ msgstr ""
 "@Opcje:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "uruchomienie w trybie demona (w tle)"
-
 msgid "run in server mode (foreground)"
 msgstr "uruchomienie w trybie serwera (pierwszoplanowo)"
 
+msgid "run in daemon mode (background)"
+msgstr "uruchomienie w trybie demona (w tle)"
+
 msgid "verbose"
 msgstr "z dodatkowymi informacjami"
 
 msgid "be somewhat more quiet"
-msgstr "mniej komunikatów"
+msgstr "mniej komunikatów"
 
 msgid "sh-style command output"
-msgstr "wyjście poleceń w stylu sh"
+msgstr "wyj¶cie poleceñ w stylu sh"
 
 msgid "csh-style command output"
-msgstr "wyjście poleceń w stylu csh"
+msgstr "wyj¶cie poleceñ w stylu csh"
 
 msgid "|FILE|read options from FILE"
 msgstr "|PLIK|odczyt opcji z PLIKU"
@@ -347,185 +292,179 @@ msgid "do not grab keyboard and mouse"
 msgstr "nie przechwytywanie klawiatury i myszy"
 
 msgid "use a log file for the server"
-msgstr "użycie pliku loga dla serwera"
+msgstr "u¿ycie pliku loga dla serwera"
 
 msgid "use a standard location for the socket"
-msgstr "użycie standardowego położenia gniazda"
+msgstr "u¿ycie standardowego po³o¿enia gniazda"
 
 msgid "|PGM|use PGM as the PIN-Entry program"
-msgstr "|PGM|użycie PGM jako programu do wprowadzania PIN-u"
+msgstr "|PGM|u¿ycie PGM jako programu do wprowadzania PIN-u"
 
 msgid "|PGM|use PGM as the SCdaemon program"
-msgstr "|PGM|użycie PGM jako programu SCdaemon"
+msgstr "|PGM|u¿ycie PGM jako programu SCdaemon"
 
 msgid "do not use the SCdaemon"
-msgstr "nie używanie SCdaemona"
+msgstr "nie u¿ywanie SCdaemona"
 
 msgid "ignore requests to change the TTY"
-msgstr "ignorowanie żądań zmiany TTY"
+msgstr "ignorowanie ¿±dañ zmiany TTY"
 
 msgid "ignore requests to change the X display"
-msgstr "ignorowanie żądań zmiany ekranu X"
+msgstr "ignorowanie ¿±dañ zmiany ekranu X"
 
 msgid "|N|expire cached PINs after N seconds"
-msgstr "|N|przedawnienie pamiętanych PIN-ów po N sekundach"
+msgstr "|N|przedawnienie pamiêtanych PIN-ów po N sekundach"
 
 msgid "do not use the PIN cache when signing"
-msgstr "nie używanie pamięci PIN-ów przy podpisywaniu"
+msgstr "nie u¿ywanie pamiêci PIN-ów przy podpisywaniu"
 
-msgid "disallow clients to mark keys as \"trusted\""
-msgstr "brak zezwolenia dla klientów na oznaczanie kluczy jako ,,zaufanych''"
+msgid "allow clients to mark keys as \"trusted\""
+msgstr "zezwolenie klientom na oznaczanie kluczy jako \"zaufanych\""
 
 msgid "allow presetting passphrase"
-msgstr "zezwolenie na predefiniowane hasło"
+msgstr "zezwolenie na predefiniowane has³o"
 
-msgid "enable ssh support"
-msgstr "włączenie obsługi ssh"
-
-msgid "enable putty support"
-msgstr "włączenie obsługi putty"
-
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "nie zezwalanie na ponowne użycie starych haseł"
+msgid "enable ssh-agent emulation"
+msgstr "w³±czenie emulacji ssh-agenta"
 
 msgid "|FILE|write environment settings also to FILE"
-msgstr "|PLIK|zapis ustawień środowiska także do PLIKU"
+msgstr "|PLIK|zapis ustawieñ ¶rodowiska tak¿e do PLIKU"
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
+#, fuzzy
 msgid "Please report bugs to <@EMAIL@>.\n"
-msgstr "Błędy prosimy zgłaszać na adres <@EMAIL@>.\n"
+msgstr "B³êdy prosimy zg³aszaæ na adres <"
 
 msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Wywołanie: gpg-agent [opcje] (-h podaje pomoc)"
+msgstr "Wywo³anie: gpg-agent [opcje] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: gpg-agent [options] [command [args]]\n"
 "Secret key management for GnuPG\n"
 msgstr ""
-"Składnia: gpg-agent [opcje] [polecenie [argumenty]]\n"
-"Zarządzanie kluczem tajnym dla GnuPG\n"
+"Sk³adnia: gpg-agent [opcje] [polecenie [argumenty]]\n"
+"Zarz±dzanie kluczem tajnym dla GnuPG\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
-msgstr "podano błędny poziom diagnostyki ,,%s''\n"
+msgid "invalid debug-level '%s' given\n"
+msgstr "podano b³êdny poziom diagnostyki ,,%s''\n"
 
 #, c-format
 msgid "%s is too old (need %s, have %s)\n"
 msgstr "biblioteka %s jest zbyt stara (potrzebna %s, zainstalowana %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
-msgstr "UWAGA: brak domyślnego pliku opcji ,,%s''\n"
+msgid "NOTE: no default option file '%s'\n"
+msgstr "UWAGA: brak domylnego pliku opcji ,,%s''\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "plik opcji ,,%s'': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "odczyt opcji z ,,%s''\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
-msgstr "błąd tworzenia ,,%s'': %s\n"
+msgid "error creating '%s': %s\n"
+msgstr "b³±d tworzenia ,,%s'': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "nie można utworzyć katalogu ,,%s'': %s\n"
+msgid "can't create directory '%s': %s\n"
+msgstr "nie mo¿na utworzyæ katalogu ,,%s'': %s\n"
 
 msgid "name of socket too long\n"
-msgstr "nazwa gniazda zbyt długa\n"
+msgstr "nazwa gniazda zbyt d³uga\n"
 
 #, c-format
 msgid "can't create socket: %s\n"
-msgstr "nie można utworzyć gniazda: %s\n"
+msgstr "nie mo¿na utworzyæ gniazda: %s\n"
 
-#, c-format
-msgid "socket name `%s' is too long\n"
-msgstr "nazwa gniazda `%s' zbyt długa\n"
+#, fuzzy, c-format
+msgid "socket name '%s' is too long\n"
+msgstr "nazwa gniazda zbyt d³uga\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
-msgstr "gpg-agent już działa - nie uruchamianie nowego\n"
+msgstr "gpg-agent ju¿ dzia³a - nie uruchamianie nowego\n"
 
+#, fuzzy
 msgid "error getting nonce for the socket\n"
-msgstr "błąd podczas pobierania nonce z gniazda\n"
+msgstr "b³±d podczas odczytu nowego PIN-u: %s\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
-msgstr "błąd podczas przypisywania gniazda do ,,%s'': %s\n"
+msgid "error binding socket to '%s': %s\n"
+msgstr "b³±d podczas przypisywania gniazda do ,,%s'': %s\n"
 
 #, c-format
 msgid "listen() failed: %s\n"
-msgstr "listen() nie powiodło się: %s\n"
+msgstr "listen() nie powiod³o siê: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
-msgstr "nasłuchiwanie na gnieździe ,,%s''\n"
+msgid "listening on socket '%s'\n"
+msgstr "nas³uchiwanie na gnie¼dzie ,,%s''\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "katalog ,,%s'' utworzony\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
-msgstr "stat() nie powiodło się dla ,,%s'': %s\n"
+msgid "stat() failed for '%s': %s\n"
+msgstr "stat() nie powiod³o siê dla ,,%s'': %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
-msgstr "nie można użyć ,,%s'' jako katalogu domowego\n"
+msgid "can't use '%s' as home directory\n"
+msgstr "nie mo¿na u¿yæ ,,%s'' jako katalogu domowego\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading nonce on fd %d: %s\n"
-msgstr "błąd odczytu nonce z fd %d: %s\n"
+msgstr "b³±d odczytu z %s: %s\n"
 
 #, c-format
 msgid "handler 0x%lx for fd %d started\n"
-msgstr "obsługa 0x%lx dla fd %d uruchomiona\n"
+msgstr "obs³uga 0x%lx dla fd %d uruchomiona\n"
 
 #, c-format
 msgid "handler 0x%lx for fd %d terminated\n"
-msgstr "obsługa 0x%lx dla fd %d zakończona\n"
+msgstr "obs³uga 0x%lx dla fd %d zakoñczona\n"
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d started\n"
-msgstr "obsługa ssh 0x%lx dla fd %d uruchomiona\n"
+msgstr "obs³uga ssh 0x%lx dla fd %d uruchomiona\n"
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d terminated\n"
-msgstr "obsługa ssh 0x%lx dla fd %d zakończona\n"
+msgstr "obs³uga ssh 0x%lx dla fd %d zakoñczona\n"
 
 #, c-format
 msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "pth_select nie powiodło się: %s - czekanie 1s\n"
+msgstr "pth_select nie powiod³o siê: %s - czekanie 1s\n"
 
 #, c-format
 msgid "%s %s stopped\n"
 msgstr "%s %s zatrzymany\n"
 
 msgid "no gpg-agent running in this session\n"
-msgstr "brak działającego gpg-agenta w tej sesji\n"
+msgstr "brak dzia³aj±cego gpg-agenta w tej sesji\n"
 
 msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "zły format zmiennej środowiskowej GPG_AGENT_INFO\n"
+msgstr "z³y format zmiennej ¶rodowiskowej GPG_AGENT_INFO\n"
 
 #, c-format
 msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "wersja %d protokołu agenta nie jest obsługiwana\n"
+msgstr "wersja %d protoko³u agenta nie jest obs³ugiwana\n"
 
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
 msgstr ""
-"Wywołanie: gpg-preset-passphrase [opcje] UCHWYT_KLUCZA (-h podaje pomoc)\n"
+"Wywo³anie: gpg-preset-passphrase [opcje] UCHWYT_KLUCZA (-h podaje pomoc)\n"
 
 msgid ""
 "Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
 "Password cache maintenance\n"
 msgstr ""
-"Składnia: gpg-preset-passphrase [opcje] UCHWYT_KLUCZA\n"
-"Utrzymuwanie pamięci haseł\n"
+"Sk³adnia: gpg-preset-passphrase [opcje] UCHWYT_KLUCZA\n"
+"Utrzymuwanie pamiêci hase³\n"
 
 msgid ""
 "@Commands:\n"
@@ -544,74 +483,74 @@ msgstr ""
 " "
 
 msgid "Usage: gpg-protect-tool [options] (-h for help)\n"
-msgstr "Wywołanie: gpg-protect-tool [opcje] (-h podaje pomoc)\n"
+msgstr "Wywo³anie: gpg-protect-tool [opcje] (-h podaje pomoc)\n"
 
 msgid ""
 "Syntax: gpg-protect-tool [options] [args]\n"
 "Secret key maintenance tool\n"
 msgstr ""
-"Składnia: gpg-protect-tool [opcje] [argumenty]\n"
-"Narzędzie do utrzymywania kluczy tajnych\n"
+"Sk³adnia: gpg-protect-tool [opcje] [argumenty]\n"
+"Narzêdzie do utrzymywania kluczy tajnych\n"
 
 msgid "Please enter the passphrase to unprotect the PKCS#12 object."
-msgstr "Proszę wprowadzić hasło do odbezpieczenia obiektu PKCS#12."
+msgstr "Proszê wprowadziæ has³o do odbezpieczenia obiektu PKCS#12."
 
 msgid "Please enter the passphrase to protect the new PKCS#12 object."
-msgstr "Proszę wprowadzić hasło do zabezpieczenia obiektu PKCS#12."
+msgstr "Proszê wprowadziæ has³o do zabezpieczenia obiektu PKCS#12."
 
 msgid ""
 "Please enter the passphrase to protect the imported object within the GnuPG "
 "system."
 msgstr ""
-"Proszę wprowadzić hasło do zabezpieczenia ważnego obiektu w systemie GnuPG."
+"Proszê wprowadziæ has³o do zabezpieczenia wa¿nego obiektu w systemie GnuPG."
 
 msgid ""
 "Please enter the passphrase or the PIN\n"
 "needed to complete this operation."
 msgstr ""
-"Proszę wprowadzić hasło lub PIN\n"
-"Potrzebny do zakończenia tej operacji."
+"Proszê wprowadziæ has³o lub PIN\n"
+"Potrzebny do zakoñczenia tej operacji."
 
 msgid "Passphrase:"
-msgstr "Hasło:"
+msgstr "Has³o:"
 
 msgid "cancelled\n"
 msgstr "anulowano\n"
 
 #, c-format
 msgid "error while asking for the passphrase: %s\n"
-msgstr "błąd podczas pytania o hasło: %s\n"
+msgstr "b³±d podczas pytania o has³o: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
-msgstr "błąd podczas otwierania ,,%s'': %s\n"
+msgid "error opening '%s': %s\n"
+msgstr "b³±d podczas otwierania ,,%s'': %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "plik ,,%s'', linia %d: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr "instrukcja \"%s\" zignorowana w ,,%s'', w linii %d\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
-msgstr "systemowa lista zaufania ,,%s'' niedostępna\n"
+msgid "system trustlist '%s' not available\n"
+msgstr "systemowa lista zaufania ,,%s'' niedostêpna\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
-msgstr "błędny odcisk w ,,%s'', w linii %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
+msgstr "b³êdny odcisk w ,,%s'', w linii %d\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
-msgstr "nieprawidłowa flaga klucza w ,,%s'', w linii %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
+msgstr "nieprawid³owa flaga klucza w ,,%s'', w linii %d\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
-msgstr "błąd odczytu ,,%s'', w linii %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
+msgstr "b³±d odczytu ,,%s'', w linii %d: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
-msgstr "błąd odczytu listy zaufanych certyfikatów głównych\n"
+msgstr "b³±d odczytu listy zaufanych certyfikatów g³ównych\n"
 
 #. TRANSLATORS: This prompt is shown by the Pinentry
 #. and has one special property: A "%%0A" is used by
@@ -626,8 +565,8 @@ msgid ""
 "Do you ultimately trust%%0A  \"%s\"%%0Ato correctly certify user "
 "certificates?"
 msgstr ""
-"Czy absolutnie ufasz, że%%0A  ,,%s''%%0Apoprawnie poświadcza certyfikaty "
-"użytkowników?"
+"Czy absolutnie ufasz, ¿e%%0A  ,,%s''%%0Apoprawnie po¶wiadcza certyfikaty "
+"u¿ytkowników?"
 
 msgid "Yes"
 msgstr "Tak"
@@ -648,7 +587,7 @@ msgid ""
 "Please verify that the certificate identified as:%%0A  \"%s\"%%0Ahas the "
 "fingerprint:%%0A  %s"
 msgstr ""
-"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a  ,,%s''%%0Ama "
+"Proszê sprawdziæ, ¿e certyfikat zidentyfikowany jako:%%0a  ,,%s''%%0Ama "
 "odcisk:%%0A  %s"
 
 #. TRANSLATORS: "Correct" is the label of a button and intended
@@ -658,94 +597,94 @@ msgid "Correct"
 msgstr "Akceptuj"
 
 msgid "Wrong"
-msgstr "Odrzuć"
+msgstr ""
 
 #, c-format
 msgid "Note: This passphrase has never been changed.%0APlease change it now."
-msgstr "Uwaga: To hasło nie było nigdy zmieniane.%0AProszę zmienić je teraz."
+msgstr "Uwaga: To has³o nie by³o nigdy zmieniane.%0AProszê zmieniæ je teraz."
 
 #, c-format
 msgid ""
 "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s.  Please change "
 "it now."
 msgstr ""
-"To hasło nie zostało zmienione%%0Aod %.4s-%.2s-%.2s. Proszę zmienić je teraz."
+"To has³o nie zosta³o zmienione%%0Aod %.4s-%.2s-%.2s. Proszê zmieniæ je teraz."
 
 msgid "Change passphrase"
-msgstr "Zmiana hasła"
+msgstr "Zmiana has³a"
 
 msgid "I'll change it later"
-msgstr "Zmienię je później"
+msgstr "Zmieniê je pó¼niej"
 
 #, c-format
 msgid "error creating a pipe: %s\n"
-msgstr "błąd tworzenia potoku: %s\n"
+msgstr "b³±d tworzenia potoku: %s\n"
 
 #, c-format
 msgid "can't fdopen pipe for reading: %s\n"
-msgstr "nie można wykonać fdopen do odczytu na potoku: %s\n"
+msgstr "nie mo¿na wykonaæ fdopen do odczytu na potoku: %s\n"
 
 #, c-format
 msgid "error forking process: %s\n"
-msgstr "błąd podczas tworzenia procesu: %s\n"
+msgstr "b³±d podczas tworzenia procesu: %s\n"
 
 #, c-format
 msgid "waiting for process %d to terminate failed: %s\n"
-msgstr "oczekiwanie na zakończenie procesu %d nie powiodło się: %s\n"
+msgstr "oczekiwanie na zakoñczenie procesu %d nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "error getting exit code of process %d: %s\n"
-msgstr "błąd odczytu kodu zakończenia procesu %d: %s\n"
+msgstr "b³±d odczytu kodu zakoñczenia procesu %d: %s\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
-msgstr "błąd uruchamiania ,,%s'': kod wyjścia %d\n"
+msgid "error running '%s': exit status %d\n"
+msgstr "b³±d uruchamiania ,,%s'': kod wyj¶cia %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "błąd uruchamiania ,,%s'': prawdopodobnie nie zainstalowany\n"
+msgid "error running '%s': probably not installed\n"
+msgstr "b³±d uruchamiania ,,%s'': prawdopodobnie nie zainstalowany\n"
 
 #, c-format
-msgid "error running `%s': terminated\n"
-msgstr "błąd uruchamiania ,,%s'': zakończono\n"
+msgid "error running '%s': terminated\n"
+msgstr "b³±d uruchamiania ,,%s'': zakoñczono\n"
 
 #, c-format
 msgid "error creating socket: %s\n"
-msgstr "błąd tworzenia gniazda: %s\n"
+msgstr "b³±d tworzenia gniazda: %s\n"
 
 msgid "host not found"
 msgstr "nie znaleziono hosta"
 
 msgid "gpg-agent is not available in this session\n"
-msgstr "gpg-agent nie jest dostępny w tej sesji\n"
+msgstr "gpg-agent nie jest dostêpny w tej sesji\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
-msgstr "nie można się połączyć z ,,%s'': %s\n"
+msgid "can't connect to '%s': %s\n"
+msgstr "nie mo¿na siê po³±czyæ z ,,%s'': %s\n"
 
 msgid "communication problem with gpg-agent\n"
-msgstr "problem z komunikacją z gpg-agentem\n"
+msgstr "problem z komunikacj± z gpg-agentem\n"
 
 msgid "problem setting the gpg-agent options\n"
 msgstr "problem z ustawieniem opcji gpg-agenta\n"
 
 msgid "canceled by user\n"
-msgstr "anulowano przez użytkownika\n"
+msgstr "anulowano przez u¿ytkownika\n"
 
 msgid "problem with the agent\n"
 msgstr "problem z agentem\n"
 
 #, c-format
 msgid "can't disable core dumps: %s\n"
-msgstr "nie można wyłączyć zrzutów pamięci: %s\n"
+msgstr "nie mo¿na wy³±czyæ zrzutów pamiêci: %s\n"
 
 #, c-format
 msgid "Warning: unsafe ownership on %s \"%s\"\n"
-msgstr "Ostrzeżenie: niebezpieczne prawa własności do %s ,,%s''\n"
+msgstr "Ostrze¿enie: niebezpieczne prawa w³asno¶ci do %s ,,%s''\n"
 
 #, c-format
 msgid "Warning: unsafe permissions on %s \"%s\"\n"
-msgstr "Ostrzeżenie: niebezpieczne prawa dostępu do %s ,,%s''\n"
+msgstr "Ostrze¿enie: niebezpieczne prawa dostêpu do %s ,,%s''\n"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "yes"
@@ -763,7 +702,7 @@ msgstr "nN"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "quit"
-msgstr "wyjście"
+msgstr "wyjcie"
 
 msgid "qQ"
 msgstr "wW"
@@ -784,161 +723,151 @@ msgstr "aA"
 
 #, c-format
 msgid "out of core in secure memory while allocating %lu bytes"
-msgstr "brak miejsca w bezpiecznej pamięci podczas przydzielania %lu bajtów"
+msgstr "brak miejsca w bezpiecznej pamiêci podczas przydzielania %lu bajtów"
 
 #, c-format
 msgid "out of core while allocating %lu bytes"
-msgstr "brak miejsca podczas przydzielania %lu bajtów"
+msgstr "brak miejsca podczas przydzielania %lu bajtów"
 
+#, fuzzy
 msgid "no running gpg-agent - starting one\n"
-msgstr "gpg-agent nie działa - uruchamianie\n"
-
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "oczekiwanie (%d s) na uruchomienie agenta\n"
+msgstr "dirmngr nie dzia³a - uruchamianie ,,%s''\n"
 
+#, fuzzy
 msgid "can't connect to the agent - trying fall back\n"
-msgstr "nie można połączyć się z agentem - próba fallbacku\n"
+msgstr "nie mo¿na po³±czyæ siê z dirmngr - próba fallbacku\n"
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
 msgid "|audit-log-result|Good"
-msgstr "|audit-log-result|Dobry"
+msgstr ""
 
 msgid "|audit-log-result|Bad"
-msgstr "|audit-log-result|Zły"
+msgstr ""
 
 msgid "|audit-log-result|Not supported"
-msgstr "|audit-log-result|Nieobsługiwany"
+msgstr ""
 
+#, fuzzy
 msgid "|audit-log-result|No certificate"
-msgstr "|audit-log-result|Brak certyfikatu"
+msgstr "import certyfikatów"
 
+#, fuzzy
 msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|Nie włączony"
+msgstr "import certyfikatów"
 
 msgid "|audit-log-result|Error"
-msgstr "|audit-log-result|Błąd"
-
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|Nie używany"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|OK"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|Pominięto"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|Częściowo"
+msgstr ""
 
+#, fuzzy
 msgid "Certificate chain available"
-msgstr "Łańcuch certyfikatów dostępny"
+msgstr "³añcuch certyfikatów zbyt d³ugi\n"
 
+#, fuzzy
 msgid "root certificate missing"
-msgstr "brak certyfikatu głównego"
+msgstr "certyfikat g³ówny jest dobry\n"
 
 msgid "Data encryption succeeded"
-msgstr "Szyfrowanie danych zakończone"
+msgstr ""
 
+#, fuzzy
 msgid "Data available"
-msgstr "Dane dostępne"
+msgstr "wypisanie wszystkich dostêpnych danych"
 
+#, fuzzy
 msgid "Session key created"
-msgstr "Klucz sesji utworzony"
+msgstr "%s: zbiór kluczy utworzony\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "algorithm: %s"
-msgstr "algorytm: %s"
+msgstr "poprawno¶æ: %s"
 
-#, c-format
+#, fuzzy, c-format
 msgid "unsupported algorithm: %s"
-msgstr "nieobsługiwany algorytm: %s"
+msgstr ""
+"\n"
+"Obs³ugiwane algorytmy:\n"
 
+#, fuzzy
 msgid "seems to be not encrypted"
-msgstr "nie wygląda na zaszyfrowaną wiadomość"
+msgstr "(to nie wygl±da na zaszyfrowan± wiadomo¶æ)\n"
 
+#, fuzzy
 msgid "Number of recipients"
-msgstr "Liczba odbiorców"
+msgstr "Aktualni odbiorcy:\n"
 
 #, c-format
 msgid "Recipient %d"
-msgstr "Odbiorca %d"
+msgstr ""
 
 msgid "Data signing succeeded"
-msgstr "Podpisywanie danych zakończone"
-
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "algorytm skrótu danych: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "Podpisujący %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algorytm skrótu atrybutów: %s"
+msgstr ""
 
 msgid "Data decryption succeeded"
-msgstr "Odszyfrowywanie danych zakończone"
-
-msgid "Encryption algorithm supported"
-msgstr "Algorytm szyfrowania obsługiwany"
+msgstr ""
 
+#, fuzzy
 msgid "Data verification succeeded"
-msgstr "Weryfikacja danych zakończona"
+msgstr "wymuszono pominiêcie sprawdzenia podpisu\n"
 
+#, fuzzy
 msgid "Signature available"
-msgstr "Podpis dostępny"
+msgstr "Podpisano w "
 
-msgid "Parsing data succeeded"
-msgstr "Analiza danych zakończona"
+#, fuzzy
+msgid "Parsing signature succeeded"
+msgstr "nie znaleziono podpisu\n"
 
-#, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "niewłaściwy algorytm skrótu danych: %s"
+#, fuzzy, c-format
+msgid "Bad hash algorithm: %s"
+msgstr "niew³a¶ciwy algorytm skrótu ,,%s''\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Signature %d"
-msgstr "Podpis %d"
+msgstr "Podpisano w "
 
+#, fuzzy
 msgid "Certificate chain valid"
-msgstr "Łańcuch certyfikatów poprawny"
+msgstr "certyfikat jeszcze nie jest wa¿ny"
 
+#, fuzzy
 msgid "Root certificate trustworthy"
-msgstr "Certyfikat główny jest zaufany"
+msgstr "certyfikat g³ówny jest dobry\n"
 
 msgid "no CRL found for certificate"
 msgstr "nie znaleziono CRL dla certyfikatu"
 
 msgid "the available CRL is too old"
-msgstr "dostępny CRL jest zbyt stary"
+msgstr "dostêpny CRL jest zbyt stary"
 
+#, fuzzy
 msgid "CRL/OCSP check of certificates"
-msgstr "weryfikacja CRL/OCSP certyfikatów"
+msgstr "nie znaleziono CRL dla certyfikatu"
 
+#, fuzzy
 msgid "Included certificates"
-msgstr "Dołączone certyfikaty"
+msgstr "eksport certyfikatów"
 
 msgid "No audit log entries."
-msgstr "Brak wpisów w logu."
+msgstr ""
 
+#, fuzzy
 msgid "Unknown operation"
-msgstr "Nieznana operacja"
+msgstr "nieznana opcja ,,%s''\n"
 
 msgid "Gpg-Agent usable"
-msgstr "Gpg-Agent sprawny"
+msgstr ""
 
 msgid "Dirmngr usable"
-msgstr "Dirmngr sprawny"
+msgstr ""
 
-#, c-format
-msgid "No help available for `%s'."
-msgstr "Brak pomocy dla ,,%s''."
+#, fuzzy, c-format
+msgid "No help available for '%s'."
+msgstr "Brak pomocy o ,,%s''"
 
+#, fuzzy
 msgid "ignoring garbage line"
-msgstr "zignorowano błędną linię"
+msgstr "b³±d w linii koñcz±cej\n"
 
 msgid "[none]"
 msgstr "[brak]"
@@ -948,19 +877,20 @@ msgid "armor: %s\n"
 msgstr "opakowanie: %s\n"
 
 msgid "invalid armor header: "
-msgstr "niepoprawny nagłówek opakowania: "
+msgstr "niepoprawny nag³ówek opakowania: "
 
 msgid "armor header: "
-msgstr "nagłówek opakowania: "
+msgstr "nag³ówek opakowania: "
 
 msgid "invalid clearsig header\n"
-msgstr "niewłaściwy nagłówek dokumentu z podpisem na końcu\n"
+msgstr "niew³a¶ciwy nag³ówek dokumentu z podpisem na koñcu\n"
 
+#, fuzzy
 msgid "unknown armor header: "
-msgstr "nieznany nagłówek opakowania: "
+msgstr "nag³ówek opakowania: "
 
 msgid "nested clear text signatures\n"
-msgstr "zagnieżdżone podpisy na końcu dokumentu\n"
+msgstr "zagnie¿d¿one podpisy na koñcu dokumentu\n"
 
 msgid "unexpected armor: "
 msgstr "nieoczekiwane opakowanie: "
@@ -970,7 +900,7 @@ msgstr "niepoprawne oznaczenie linii minusami: "
 
 #, c-format
 msgid "invalid radix64 character %02X skipped\n"
-msgstr "niewłaściwy znak formatu radix64 ,,%02X'' został pominięty\n"
+msgstr "niew³a¶ciwy znak formatu radix64 ,,%02X'' zosta³ pominiêty\n"
 
 msgid "premature eof (no CRC)\n"
 msgstr "przedwczesny koniec pliku (brak CRC)\n"
@@ -979,78 +909,80 @@ msgid "premature eof (in CRC)\n"
 msgstr "przedwczesny koniec pliku (w CRC)\n"
 
 msgid "malformed CRC\n"
-msgstr "błąd formatu CRC\n"
+msgstr "b³±d formatu CRC\n"
 
 #, c-format
 msgid "CRC error; %06lX - %06lX\n"
-msgstr "Błąd sumy CRC; %06lX - %06lX\n"
+msgstr "B³±d sumy CRC; %06lX - %06lX\n"
 
 msgid "premature eof (in trailer)\n"
-msgstr "przedwczesny koniec pliku (w linii kończącej)\n"
+msgstr "przedwczesny koniec pliku (w linii koñcz±cej)\n"
 
 msgid "error in trailer line\n"
-msgstr "błąd w linii kończącej\n"
+msgstr "b³±d w linii koñcz±cej\n"
 
 msgid "no valid OpenPGP data found.\n"
 msgstr "nie odnaleziono poprawnych danych w formacie OpenPGP.\n"
 
 #, c-format
 msgid "invalid armor: line longer than %d characters\n"
-msgstr "błąd opakowania: linia dłuższa niż %d znaków\n"
+msgstr "b³±d opakowania: linia d³u¿sza ni¿ %d znaków\n"
 
 msgid ""
 "quoted printable character in armor - probably a buggy MTA has been used\n"
 msgstr ""
 "znak kodowania quoted-printable w opakowaniu ASCII - prawdopodobnie\n"
-"przekłamanie wprowadzone przez serwer pocztowy\n"
+"przek³amanie wprowadzone przez serwer pocztowy\n"
 
 msgid ""
 "a notation name must have only printable characters or spaces, and end with "
 "an '='\n"
 msgstr ""
-"nazwa adnotacji musi zawierać tylko znaki drukowalne lub spacje i kończyć "
-"się znakiem ,,=''\n"
+"nazwa adnotacji musi zawieraæ tylko znaki drukowalne lub spacje i koñczyæ "
+"siê znakiem ,,=''\n"
 
 msgid "a user notation name must contain the '@' character\n"
-msgstr "nazwa adnotacji użytkownika musi zawierać znak ,,@''\n"
+msgstr "nazwa adnotacji u¿ytkownika musi zawieraæ znak ,,@''\n"
 
 msgid "a notation name must not contain more than one '@' character\n"
-msgstr "nazwa adnotacjinie może zawierać więcej niż jednego znaku ,,@''\n"
+msgstr "nazwa adnotacjinie mo¿e zawieraæ wiêcej ni¿ jednego znaku ,,@''\n"
 
 msgid "a notation value must not use any control characters\n"
-msgstr "wartość adnotacji nie może zawierać żadnych znaków sterujących\n"
+msgstr "warto¶æ adnotacji nie mo¿e zawieraæ ¿adnych znaków steruj±cych\n"
 
 msgid "WARNING: invalid notation data found\n"
-msgstr "OSTRZEŻENIE: napotkano błędne dane adnotacji\n"
+msgstr "OSTRZE¯ENIE: napotkano b³êdne dane adnotacji\n"
 
 msgid "not human readable"
-msgstr "nieczytelne dla człowieka"
+msgstr "nieczytelne dla cz³owieka"
 
 #, c-format
 msgid "OpenPGP card not available: %s\n"
-msgstr "Karta OpenPGP niedostępna: %s\n"
+msgstr "Karta OpenPGP niedostêpna: %s\n"
 
 #, c-format
 msgid "OpenPGP card no. %s detected\n"
-msgstr "Wykryto kartę OpenPGP nr %s\n"
+msgstr "Wykryto kartê OpenPGP nr %s\n"
 
 msgid "can't do this in batch mode\n"
-msgstr "nie działa w trybie wsadowym\n"
+msgstr "nie dzia³a w trybie wsadowym\n"
 
+#, fuzzy
 msgid "This command is only available for version 2 cards\n"
-msgstr "To polecenie jest dostępne tylko dla kart w wersji 2\n"
+msgstr "To polecenie nie jest dostêpne w trybie %s.\n"
 
+#, fuzzy
 msgid "Reset Code not or not anymore available\n"
-msgstr "Kod resetujący nie jest (już lub w ogóle) dostępny\n"
+msgstr "tajne czê¶ci klucza s± niedostêpne\n"
 
 msgid "Your selection? "
-msgstr "Twój wybór? "
+msgstr "Twój wybór? "
 
 msgid "[not set]"
 msgstr "[nie ustawiono]"
 
 msgid "male"
-msgstr "mężczyzna"
+msgstr "mê¿czyzna"
 
 msgid "female"
 msgstr "kobieta"
@@ -1065,77 +997,77 @@ msgid "forced"
 msgstr "wymuszono"
 
 msgid "Error: Only plain ASCII is currently allowed.\n"
-msgstr "Błąd: aktualnie dopuszczalne jest tylko czyste ASCII.\n"
+msgstr "B³±d: aktualnie dopuszczalne jest tylko czyste ASCII.\n"
 
 msgid "Error: The \"<\" character may not be used.\n"
-msgstr "Błąd: znak ,,<'' nie może być użyty.\n"
+msgstr "B³±d: znak ,,<'' nie mo¿e byæ u¿yty.\n"
 
 msgid "Error: Double spaces are not allowed.\n"
-msgstr "Błąd: podwójne spacje nie są dopuszczalne.\n"
+msgstr "B³±d: podwójne spacje nie s± dopuszczalne.\n"
 
 msgid "Cardholder's surname: "
 msgstr "Nazwisko posiadacza karty: "
 
 msgid "Cardholder's given name: "
-msgstr "Imię posiadacza karty: "
+msgstr "Imiê posiadacza karty: "
 
 #, c-format
 msgid "Error: Combined name too long (limit is %d characters).\n"
-msgstr "Błąd: pełne personalia zbyt długie (limit to %d znaków).\n"
+msgstr "B³±d: pe³ne personalia zbyt d³ugie (limit to %d znaków).\n"
 
 msgid "URL to retrieve public key: "
 msgstr "URL do odczytania klucza publicznego: "
 
 #, c-format
 msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Błąd: URL zbyt długi (limit to %d znaków).\n"
+msgstr "B³±d: URL zbyt d³ugi (limit to %d znaków).\n"
 
 #, c-format
 msgid "error allocating enough memory: %s\n"
-msgstr "błąd przydzielania wystarczającej ilości pamięci: %s\n"
+msgstr "b³±d przydzielania wystarczaj±cej ilo¶ci pamiêci: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
-msgstr "błąd odczytu ,,%s'': %s\n"
+msgid "error reading '%s': %s\n"
+msgstr "b³±d odczytu ,,%s'': %s\n"
 
-#, c-format
-msgid "error writing `%s': %s\n"
-msgstr "błąd zapisu ,,%s'': %s\n"
+#, fuzzy, c-format
+msgid "error writing '%s': %s\n"
+msgstr "b³±d zapisu do %s: %s\n"
 
 msgid "Login data (account name): "
 msgstr "Dane logowania (nazwa konta): "
 
 #, c-format
 msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Błąd: dane logowania zbyt długie (limit to %d znaków).\n"
+msgstr "B³±d: dane logowania zbyt d³ugie (limit to %d znaków).\n"
 
 msgid "Private DO data: "
 msgstr "Prywatne dane DO: "
 
 #, c-format
 msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Błąd: prywatne DO zbyt długie (limit to %d znaków).\n"
+msgstr "B³±d: prywatne DO zbyt d³ugie (limit to %d znaków).\n"
 
 msgid "Language preferences: "
-msgstr "Preferowane języki: "
+msgstr "Preferowane jêzyki: "
 
 msgid "Error: invalid length of preference string.\n"
-msgstr "Błąd: niewłaściwa długość tekstu preferencji.\n"
+msgstr "B³±d: niew³a¶ciwa d³ugo¶æ tekstu preferencji.\n"
 
 msgid "Error: invalid characters in preference string.\n"
-msgstr "Błąd: niewłaściwe znaki w tekście preferencji.\n"
+msgstr "B³±d: niew³a¶ciwe znaki w tek¶cie preferencji.\n"
 
 msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Płeć (M - mężczyzna, F - kobieta lub spacja): "
+msgstr "P³eæ (M - mê¿czyzna, F - kobieta lub spacja): "
 
 msgid "Error: invalid response.\n"
-msgstr "Błąd: niewłaściwa odpowiedź.\n"
+msgstr "B³±d: niew³a¶ciwa odpowied¼.\n"
 
 msgid "CA fingerprint: "
 msgstr "Odcisk CA:"
 
 msgid "Error: invalid formatted fingerprint.\n"
-msgstr "Błąd: niewłaściwie sformatowany odcisk.\n"
+msgstr "B³±d: niew³a¶ciwie sformatowany odcisk.\n"
 
 #, c-format
 msgid "key operation not possible: %s\n"
@@ -1146,56 +1078,54 @@ msgstr "to nie jest karta OpenPGP"
 
 #, c-format
 msgid "error getting current key info: %s\n"
-msgstr "błąd podczas odczytu aktualnych informacji o kluczu: %s\n"
+msgstr "b³±d podczas odczytu aktualnych informacji o kluczu: %s\n"
 
 msgid "Replace existing key? (y/N) "
-msgstr "Zastąpić istniejący klucz? (t/N) "
+msgstr "Zast±piæ istniej±cy klucz? (t/N) "
 
 msgid ""
 "NOTE: There is no guarantee that the card supports the requested size.\n"
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
-"UWAGA: Nie ma gwarancji, że karta obsługuje żądany rozmiar.\n"
-"       Jeśli tworzenie klucza nie powiedzie się, proszę sprawdzić\n"
-"       dokumentację karty, aby poznać dozwolone rozmiary.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "Jakiej długości klucz do podpisywania wygenerować? (%u) "
+msgstr "Jakiej d³ugo¶ci klucz wygenerowaæ? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "Jakiej długości klucz do szyfrowania wygenerować? (%u) "
+msgstr "Jakiej d³ugo¶ci klucz wygenerowaæ? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "Jakiej długości klucz do uwierzytelniania wygenerować? (%u) "
+msgstr "Jakiej d³ugo¶ci klucz wygenerowaæ? (%u) "
 
 #, c-format
 msgid "rounded up to %u bits\n"
-msgstr "zaokrąglono do %u bitów\n"
+msgstr "zaokr±glono do %u bitów\n"
 
 #, c-format
 msgid "%s keysizes must be in the range %u-%u\n"
-msgstr "Rozmiary kluczy %s muszą być z przedziału %u-%u\n"
+msgstr "Rozmiary kluczy %s musz± byæ z przedzia³u %u-%u\n"
 
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
-msgstr "Karta zostanie przekonfigurowana do tworzenia klucza %u-bitowego\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
-msgstr "błąd podczas zmiany rozmiaru klucza %d na %u bitów: %s\n"
+msgstr "b³±d podczas przypisywania gniazda do ,,%s'': %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
-msgstr "Stworzyć poza kartą kopię zapasową klucza szyfrującego? (T/n) "
+msgstr "Stworzyæ poza kart± kopiê zapasow± klucza szyfruj±cego? (T/n) "
 
+#, fuzzy
 msgid "NOTE: keys are already stored on the card!\n"
-msgstr "UWAGA: klucze są już zapisane na karcie!\n"
+msgstr "klucz prywatny jest ju¿ zapisany na karcie\n"
 
 msgid "Replace existing keys? (y/N) "
-msgstr "Zastąpić istniejące klucze? (t/N) "
+msgstr "Zast±piæ istniej±ce klucze? (t/N) "
 
 #, c-format
 msgid ""
@@ -1203,15 +1133,15 @@ msgid ""
 "   PIN = `%s'     Admin PIN = `%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
-"Fabryczne ustawienia PIN-ów to\n"
-"   PIN = ,,%s''   PIN administracyjny = ,,%s''\n"
-"Należy je zmienić przy użyciu polecenia --change-pin\n"
+"Fabryczne ustawienia PIN-ów to\n"
+"   PIN = ,,%s''   PIN administratora = ,,%s''\n"
+"Nale¿y je zmieniæ przy u¿yciu polecenia --change-pin\n"
 
 msgid "Please select the type of key to generate:\n"
-msgstr "Proszę wybrać rodzaj klucza do wygenerowania:\n"
+msgstr "Proszê wybraæ rodzaj klucza do wygenerowania:\n"
 
 msgid "   (1) Signature key\n"
-msgstr "   (1) Klucz do podpisów\n"
+msgstr "   (1) Klucz do podpisów\n"
 
 msgid "   (2) Encryption key\n"
 msgstr "   (2) Klucz do szyfrowania\n"
@@ -1220,35 +1150,35 @@ msgid "   (3) Authentication key\n"
 msgstr "   (3) Klucz do uwierzytelniania\n"
 
 msgid "Invalid selection.\n"
-msgstr "Niewłaściwy wybór.\n"
+msgstr "Niew³a¶ciwy wybór.\n"
 
 msgid "Please select where to store the key:\n"
-msgstr "Proszę wybrać gdzie zapisać klucz:\n"
+msgstr "Proszê wybraæ gdzie zapisaæ klucz:\n"
 
 msgid "unknown key protection algorithm\n"
 msgstr "nieznany algorytm ochrony klucza\n"
 
 msgid "secret parts of key are not available\n"
-msgstr "części tajne klucza są niedostępne\n"
+msgstr "czê¶ci tajne klucza s± niedostêpne\n"
 
 msgid "secret key already stored on a card\n"
-msgstr "klucz prywatny jest już zapisany na karcie\n"
+msgstr "klucz prywatny jest ju¿ zapisany na karcie\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key to card: %s\n"
-msgstr "błąd zapisu klucza na karcie: %s\n"
+msgstr "b³±d zapisu klucza: %s\n"
 
 msgid "quit this menu"
-msgstr "wyjście z tego menu"
+msgstr "wyjcie z tego menu"
 
 msgid "show admin commands"
-msgstr "pokazanie poleceń administratora"
+msgstr "pokazanie poleceñ administratora"
 
 msgid "show this help"
 msgstr "ten tekst pomocy"
 
 msgid "list all available data"
-msgstr "wypisanie wszystkich dostępnych danych"
+msgstr "wypisanie wszystkich dostêpnych danych"
 
 msgid "change card holder's name"
 msgstr "zmiana nazwy posiadacza karty"
@@ -1257,16 +1187,16 @@ msgid "change URL to retrieve key"
 msgstr "zmiana URL-a do odczytu klucza"
 
 msgid "fetch the key specified in the card URL"
-msgstr "pobranie klucza określonego w URL-u karty"
+msgstr "pobranie klucza okrelonego w URL-u karty"
 
 msgid "change the login name"
 msgstr "zmiana nazwy logowania"
 
 msgid "change the language preferences"
-msgstr "zmiana preferowanych języków"
+msgstr "zmiana preferowanych jêzyków"
 
 msgid "change card holder's sex"
-msgstr "zmiana płci posiadacza karty"
+msgstr "zmiana p³ci posiadacza karty"
 
 msgid "change a CA fingerprint"
 msgstr "zmiana odcisku CA"
@@ -1284,102 +1214,102 @@ msgid "verify the PIN and list all data"
 msgstr "sprawdzenie PIN-u i wypisanie wszystkich danych"
 
 msgid "unblock the PIN using a Reset Code"
-msgstr "odblokowanie PIN-u przy użyciu kodu resetującego"
+msgstr ""
 
-msgid "gpg/card> "
-msgstr "gpg/karta> "
+msgid "Command> "
+msgstr "Polecenie> "
 
 msgid "Admin-only command\n"
 msgstr "Polecenie tylko dla administratora\n"
 
 msgid "Admin commands are allowed\n"
-msgstr "Polecenia dla administratora są dozwolone\n"
+msgstr "Polecenia dla administratora s± dozwolone\n"
 
 msgid "Admin commands are not allowed\n"
-msgstr "Polecenia dla administratora nie są dozwolone\n"
+msgstr "Polecenia dla administratora nie s± dozwolone\n"
 
 msgid "Invalid command  (try \"help\")\n"
-msgstr "Niepoprawne polecenie  (spróbuj ,,help'')\n"
+msgstr "Niepoprawne polecenie  (spróbuj ,,help'')\n"
 
 msgid "--output doesn't work for this command\n"
-msgstr "opcja --output nie działa z tym poleceniem\n"
+msgstr "opcja --output nie dzia³a z tym poleceniem\n"
 
 #, c-format
-msgid "can't open `%s'\n"
-msgstr "nie można otworzyć ,,%s''\n"
+msgid "can't open '%s'\n"
+msgstr "nie mo¿na otworzyæ ,,%s''\n"
 
 #, c-format
 msgid "key \"%s\" not found: %s\n"
-msgstr "klucz ,,%s'' nie został odnaleziony: %s\n"
+msgstr "klucz ,,%s'' nie zosta³ odnaleziony: %s\n"
 
 #, c-format
 msgid "error reading keyblock: %s\n"
-msgstr "błąd odczytu bloku kluczy: %s\n"
+msgstr "b³±d odczytu bloku kluczy: %s\n"
 
 msgid "(unless you specify the key by fingerprint)\n"
-msgstr "(chyba, że klucz zostaje wybrany przez podanie odcisku)\n"
+msgstr "(chyba, ¿e klucz zostaje wybrany przez podanie odcisku)\n"
 
 msgid "can't do this in batch mode without \"--yes\"\n"
-msgstr "bez opcji ,,--yes'' nie działa w trybie wsadowym\n"
+msgstr "bez opcji ,,--yes'' nie dzia³a w trybie wsadowym\n"
 
 msgid "Delete this key from the keyring? (y/N) "
-msgstr "Usunąć ten klucz ze zbioru? (t/N) "
+msgstr "Usun±æ ten klucz ze zbioru? (t/N) "
 
 msgid "This is a secret key! - really delete? (y/N) "
-msgstr "To jest klucz tajny! - czy na pewno go usunąć? (t/N) "
+msgstr "To jest klucz tajny! - czy na pewno go usun±æ? (t/N) "
 
 #, c-format
 msgid "deleting keyblock failed: %s\n"
-msgstr "usunięcie bloku klucza nie powiodło się: %s\n"
+msgstr "usuniêcie bloku klucza nie powiod³o siê: %s\n"
 
 msgid "ownertrust information cleared\n"
-msgstr "informacja o zaufaniu dla właściciela klucza została wymazana\n"
+msgstr "informacja o zaufaniu dla w³a¶ciciela klucza zosta³a wymazana\n"
 
 #, c-format
 msgid "there is a secret key for public key \"%s\"!\n"
 msgstr "dla klucza publicznego ,,%s'' istnieje klucz prywatny!\n"
 
 msgid "use option \"--delete-secret-keys\" to delete it first.\n"
-msgstr "aby go usunąć należy najpierw użyć opcji \"--delete-secret-key\".\n"
+msgstr "aby go usun±æ nale¿y najpierw u¿yæ opcji \"--delete-secret-key\".\n"
 
 #, c-format
 msgid "error creating passphrase: %s\n"
-msgstr "błąd podczas tworzenia hasła: %s\n"
+msgstr "b³±d podczas tworzenia has³a: %s\n"
 
 msgid "can't use a symmetric ESK packet due to the S2K mode\n"
 msgstr ""
-"ustawiony tryb S2K nie pozwala użyć pakietu ESK dla szyfru symetrycznego\n"
+"ustawiony tryb S2K nie pozwala u¿yæ pakietu ESK dla szyfru symetrycznego\n"
 
 #, c-format
 msgid "using cipher %s\n"
 msgstr "szyfrem %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
-msgstr ",,%s'' już jest skompresowany\n"
+msgid "'%s' already compressed\n"
+msgstr ",,%s'' ju¿ jest skompresowany\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
-msgstr "OSTRZEŻENIE: plik ,,%s'' jest pusty\n"
+msgid "WARNING: '%s' is an empty file\n"
+msgstr "OSTRZE¯ENIE: plik ,,%s'' jest pusty\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr ""
-"w trybie --pgp2 można szyfrować dla kluczy RSA krótszych od 2048 bitów\n"
+"w trybie --pgp2 mo¿na szyfrowaæ dla kluczy RSA krótszych od 2048 bitów\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "odczyt z ,,%s''\n"
 
 msgid ""
 "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
 msgstr ""
-"nie można użyć szyfru IDEA z wszystkimi kluczami dla których szyfrujesz.\n"
+"nie mo¿na u¿yæ szyfru IDEA z wszystkimi kluczami dla których szyfrujesz.\n"
 
 #, c-format
 msgid ""
 "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
 msgstr ""
-"OSTRZEŻENIE: wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami "
+"OSTRZE¯ENIE: wymuszone u¿ycie szyfru %s (%d) k³óci siê z ustawieniami "
 "adresata\n"
 
 #, c-format
@@ -1387,16 +1317,16 @@ msgid ""
 "WARNING: forcing compression algorithm %s (%d) violates recipient "
 "preferences\n"
 msgstr ""
-"OSTRZEŻENIE: wymuszone użycie kompresji %s (%d) kłóci się z ustawieniami "
+"OSTRZE¯ENIE: wymuszone u¿ycie kompresji %s (%d) k³óci siê z ustawieniami "
 "adresata\n"
 
 #, c-format
 msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n"
-msgstr "wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami adresata\n"
+msgstr "wymuszone u¿ycie szyfru %s (%d) k³óci siê z ustawieniami adresata\n"
 
 #, c-format
 msgid "you may not use %s while in %s mode\n"
-msgstr "%s nie jest dostępne w trybie %s\n"
+msgstr "%s nie jest dostêpne w trybie %s\n"
 
 #, c-format
 msgid "%s/%s encrypted for: \"%s\"\n"
@@ -1404,7 +1334,7 @@ msgstr "%s/%s zaszyfrowany dla: ,,%s''\n"
 
 #, c-format
 msgid "%s encrypted data\n"
-msgstr "dane zaszyfrowano za pomocą %s\n"
+msgstr "dane zaszyfrowano za pomoc± %s\n"
 
 #, c-format
 msgid "encrypted with unknown algorithm %d\n"
@@ -1413,146 +1343,149 @@ msgstr "dane zaszyfrowano nieznanym algorytmem numer %d\n"
 msgid ""
 "WARNING: message was encrypted with a weak key in the symmetric cipher.\n"
 msgstr ""
-"OSTRZEŻENIE: wiadomość była szyfrowana kluczem słabym szyfru symetrycznego.\n"
+"OSTRZE¯ENIE: wiadomo¶æ by³a szyfrowana kluczem s³abym szyfru symetrycznego.\n"
 
 msgid "problem handling encrypted packet\n"
-msgstr "problem podczas obróbki pakietu szyfrowego\n"
+msgstr "problem podczas obróbki pakietu szyfrowego\n"
 
 msgid "no remote program execution supported\n"
-msgstr "odwołania do zewnętrznych programów są wyłączone\n"
+msgstr "odwo³ania do zewnêtrznych programów s± wy³±czone\n"
 
 msgid ""
 "external program calls are disabled due to unsafe options file permissions\n"
 msgstr ""
-"nieszczelne uprawnienia ustawień - wołanie zewnętrznych programów wyłączone\n"
+"nieszczelne uprawnienia ustawieñ - wo³anie zewnêtrznych programów wy³±czone\n"
 
 msgid "this platform requires temporary files when calling external programs\n"
 msgstr ""
-"platforma wymaga użycia plików tymczasowych do wołania zewnętrznych "
-"programów\n"
+"platforma wymaga u¿ycia plików tymczasowych do wo³ania zewnêtrznych "
+"programów\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
-msgstr "nie można uruchomić programu ,,%s'': %s\n"
+msgid "unable to execute program '%s': %s\n"
+msgstr "nie mo¿na uruchomiæ programu ,,%s'': %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
-msgstr "nie można uruchomić powłoki ,,%s'': %s\n"
+msgid "unable to execute shell '%s': %s\n"
+msgstr "nie mo¿na uruchomiæ pow³oki ,,%s'': %s\n"
 
 #, c-format
 msgid "system error while calling external program: %s\n"
-msgstr "błąd systemu podczas wołania programu zewnętrznego: %s\n"
+msgstr "b³±d systemu podczas wo³ania programu zewnêtrznego: %s\n"
 
 msgid "unnatural exit of external program\n"
-msgstr "nienaturalne zakończenie pracy zewnętrznego programu\n"
+msgstr "nienaturalne zakoñczenie pracy zewnêtrznego programu\n"
 
 msgid "unable to execute external program\n"
-msgstr "nie można uruchomić zewnętrznego programu\n"
+msgstr "nie mo¿na uruchomiæ zewnêtrznego programu\n"
 
 #, c-format
 msgid "unable to read external program response: %s\n"
-msgstr "nie można odczytać odpowiedzi programu zewnętrznego: %s\n"
+msgstr "nie mo¿na odczytaæ odpowiedzi programu zewnêtrznego: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
-msgstr "OSTRZEŻENIE: nie można skasować pliku tymczasowego (%s) ,,%s'': %s.\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
+msgstr "OSTRZE¯ENIE: nie mo¿na skasowaæ pliku tymczasowego (%s) ,,%s'': %s.\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
-msgstr "OSTRZEŻENIE: nie można skasować tymczasowego katalogu ,,%s'': %s.\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
+msgstr "OSTRZE¯ENIE: nie mo¿na skasowaæ tymczasowego katalogu ,,%s'': %s.\n"
 
 msgid "export signatures that are marked as local-only"
-msgstr "eksport podpisów oznaczonych jako tylko lokalne"
+msgstr "eksport podpisów oznaczonych jako tylko lokalne"
 
 msgid "export attribute user IDs (generally photo IDs)"
-msgstr "eksport atrybutów ID użytkownika (ogólnie ID zdjęć)"
+msgstr "eksport atrybutów ID u¿ytkownika (ogólnie ID zdjêæ)"
 
 msgid "export revocation keys marked as \"sensitive\""
-msgstr "eksport kluczy unieważniających oznaczonych jako ,,poufne''"
+msgstr "eksport kluczy uniewa¿niaj±cych oznaczonych jako ,,poufne''"
 
 msgid "remove the passphrase from exported subkeys"
-msgstr "usunięcie hasła z wyeksportowanych podkluczy"
+msgstr "usuniêcie has³a z wyeksportowanych podkluczy"
 
 msgid "remove unusable parts from key during export"
-msgstr "usunięcie bezużytecznych części z klucza przy eksporcie"
+msgstr "usuniêcie bezu¿ytecznych czê¶ci z klucza przy eksporcie"
 
 msgid "remove as much as possible from key during export"
-msgstr "usunięcie jak największej części klucza przy eksporcie"
+msgstr "usuniêcie jak najwiêkszej czê¶ci klucza przy eksporcie"
 
 msgid "export keys in an S-expression based format"
-msgstr "eksport kluczy w formacie opartym na S-wyrażeniach"
+msgstr "eksport kluczy w formacie opartym na S-wyra¿eniach"
 
 msgid "exporting secret keys not allowed\n"
 msgstr "eksport kluczy tajnych nie jest dozwolony\n"
 
 #, c-format
 msgid "key %s: not protected - skipped\n"
-msgstr "klucz %s: nie jest chroniony - pominięty\n"
+msgstr "klucz %s: nie jest chroniony - pominiêty\n"
 
 #, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
-msgstr "klucz %s: klucz PGP 2.x - pominięty\n"
+msgstr "klucz %s: klucz PGP 2.x - pominiêty\n"
 
 #, c-format
 msgid "key %s: key material on-card - skipped\n"
-msgstr "klucz %s: zawartość klucza na karcie - pominięto\n"
+msgstr "klucz %s: zawarto¶æ klucza na karcie - pominiêto\n"
 
 msgid "about to export an unprotected subkey\n"
-msgstr "ma być wyeksportowany niezabezpieczony podklucz\n"
+msgstr "ma byæ wyeksportowany niezabezpieczony podklucz\n"
 
 #, c-format
 msgid "failed to unprotect the subkey: %s\n"
-msgstr "nie powiodło się odbezpieczanie podklucza: %s\n"
+msgstr "nie powiod³o siê odbezpieczanie podklucza: %s\n"
 
 #, c-format
 msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr "OSTRZEŻENIE: klucz prywatny %s nie ma prostej sumy kontrolnej SK.\n"
+msgstr "OSTRZE¯ENIE: klucz prywatny %s nie ma prostej sumy kontrolnej SK.\n"
 
 msgid "WARNING: nothing exported\n"
-msgstr "OSTRZEŻENIE: nic nie zostało wyeksportowane!\n"
+msgstr "OSTRZE¯ENIE: nic nie zosta³o wyeksportowane!\n"
 
 msgid "too many entries in pk cache - disabled\n"
-msgstr "zbyt wiele wpisów w buforze kluczy publicznych - wyłączony\n"
+msgstr "zbyt wiele wpisów w buforze kluczy publicznych - wy³±czony\n"
 
 msgid "[User ID not found]"
-msgstr "[brak identyfikatora użytkownika]"
-
-#, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "klucz %s: klucz tajny bez klucza jawnego - pominięty\n"
+msgstr "[brak identyfikatora u¿ytkownika]"
 
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "automatycznie pobrano `%s' poprzez %s\n"
 
-#, c-format
-msgid "error retrieving `%s' via %s: %s\n"
-msgstr "błąd odtwarzania ,,%s'' poprzez %s: %s\n"
+#, fuzzy, c-format
+msgid "error retrieving '%s' via %s: %s\n"
+msgstr "b³±d tworzenia ,,%s'': %s\n"
 
+#, fuzzy
 msgid "No fingerprint"
-msgstr "Brak odcisku"
+msgstr "Odcisk CA:"
 
 #, c-format
 msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
 msgstr ""
-"Opcja --allow-non-selfsigned-uid wymusiła uznanie za poprawny klucza %s.\n"
+"Opcja --allow-non-selfsigned-uid wymusi³a uznanie za poprawny klucza %s.\n"
 
 #, c-format
 msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "brak prywatnego odpowiednika podklucza publicznego %s - pominięty\n"
+msgstr "brak prywatnego odpowiednika podklucza publicznego %s - pominiêty\n"
 
 #, c-format
 msgid "using subkey %s instead of primary key %s\n"
-msgstr "używany jest podklucz %s zamiast klucza głównego %s\n"
+msgstr "u¿ywany jest podklucz %s zamiast klucza g³ównego %s\n"
+
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "klucz %s: klucz tajny bez klucza jawnego - pominiêty\n"
 
+#, fuzzy
 msgid "make a signature"
-msgstr "złożenie podpisu"
+msgstr "|[plik]|z³o¿enie podpisu"
 
+#, fuzzy
 msgid "make a clear text signature"
-msgstr "złożenie podpisu pod dokumentem"
+msgstr "|[plik]|z³o¿enie podpisu pod dokumentem"
 
 msgid "make a detached signature"
-msgstr "złożenie podpisu oddzielonego od dokumentu"
+msgstr "z³o¿enie podpisu oddzielonego od dokumentu"
 
 msgid "encrypt data"
 msgstr "szyfrowanie danych"
@@ -1561,7 +1494,7 @@ msgid "encryption only with symmetric cipher"
 msgstr "szyfrowanie tylko szyfrem symetrycznym"
 
 msgid "decrypt data (default)"
-msgstr "odszyfrowywanie danych (domyślne)"
+msgstr "odszyfrowywanie danych (domylne)"
 
 msgid "verify a signature"
 msgstr "sprawdzenie podpisu"
@@ -1570,13 +1503,13 @@ msgid "list keys"
 msgstr "lista kluczy"
 
 msgid "list keys and signatures"
-msgstr "lista kluczy i podpisów"
+msgstr "lista kluczy i podpisów"
 
 msgid "list and check key signatures"
-msgstr "wypisanie i sprawdzenie podpisów kluczy"
+msgstr "wypisanie i sprawdzenie podpisów kluczy"
 
 msgid "list keys and fingerprints"
-msgstr "lista kluczy i ich odcisków"
+msgstr "lista kluczy i ich odcisków"
 
 msgid "list secret keys"
 msgstr "lista kluczy prywatnych"
@@ -1584,26 +1517,23 @@ msgstr "lista kluczy prywatnych"
 msgid "generate a new key pair"
 msgstr "generacja nowej pary kluczy"
 
-msgid "generate a revocation certificate"
-msgstr "tworzenie certyfikatu unieważnienia klucza"
-
 msgid "remove keys from the public keyring"
-msgstr "usunięcie klucza ze zbioru kluczy publicznych"
+msgstr "usuniêcie klucza ze zbioru kluczy publicznych"
 
 msgid "remove keys from the secret keyring"
-msgstr "usunięcie klucza ze zbioru kluczy prywatnych"
+msgstr "usuniêcie klucza ze zbioru kluczy prywatnych"
 
 msgid "sign a key"
-msgstr "złożenie podpisu na kluczu"
+msgstr "z³o¿enie podpisu na kluczu"
 
 msgid "sign a key locally"
-msgstr "złożenie prywatnego podpisu na kluczu"
+msgstr "z³o¿enie prywatnego podpisu na kluczu"
 
 msgid "sign or edit a key"
 msgstr "podpisanie lub modyfikacja klucza"
 
-msgid "change a passphrase"
-msgstr "zmiana hasła"
+msgid "generate a revocation certificate"
+msgstr "tworzenie certyfikatu uniewa¿nienia klucza"
 
 msgid "export keys"
 msgstr "eksport kluczy do pliku"
@@ -1618,13 +1548,13 @@ msgid "search for keys on a key server"
 msgstr "szukanie kluczy na serwerze"
 
 msgid "update all keys from a keyserver"
-msgstr "odświeżenie wszystkich kluczy z serwera"
+msgstr "od¶wie¿enie wszystkich kluczy z serwera"
 
 msgid "import/merge keys"
-msgstr "import/dołączenie kluczy"
+msgstr "import/do³±czenie kluczy"
 
 msgid "print the card status"
-msgstr "wyświetlenie stanu karty"
+msgstr "wywietlenie stanu karty"
 
 msgid "change data on a card"
 msgstr "zmiana danych na karcie"
@@ -1635,8 +1565,9 @@ msgstr "zmiana PIN-u karty"
 msgid "update the trust database"
 msgstr "uaktualnienie bazy zaufania"
 
+#, fuzzy
 msgid "print message digests"
-msgstr "wypisanie skrótów wiadomości"
+msgstr "|algo [pliki]|skróty wiadomo¶ci"
 
 msgid "run in server mode"
 msgstr "uruchomienie w trybie serwera"
@@ -1644,38 +1575,40 @@ msgstr "uruchomienie w trybie serwera"
 msgid "create ascii armored output"
 msgstr "opakowanie ASCII pliku wynikowego"
 
+#, fuzzy
 msgid "|USER-ID|encrypt for USER-ID"
-msgstr "|UŻYTKOWNIK|szyfrowanie dla odbiorcy o tym identyfikatorze"
+msgstr "|NAZWA|szyfrowanie dla odbiorcy NAZWA"
 
+#, fuzzy
 msgid "|USER-ID|use USER-ID to sign or decrypt"
-msgstr ""
-"|UŻYTKOWNIK|użycie tego identyfikatora użytkownika do podpisania lub "
-"odszyfrowania"
+msgstr "identyfikator do podpisania lub odszyfrowania"
 
+#, fuzzy
 msgid "|N|set compress level to N (0 disables)"
-msgstr "|N|ustawienie poziomu kompresji N (0 - bez)"
+msgstr "|N|poziom kompresji N (0 - bez)"
 
 msgid "use canonical text mode"
 msgstr "kanoniczny format tekstowy"
 
+#, fuzzy
 msgid "|FILE|write output to FILE"
-msgstr "|PLIK|zapis wyjścia do PLIKU"
+msgstr "|PLIK|odczyt opcji z PLIKU"
 
 msgid "do not make any changes"
 msgstr "pozostawienie bez zmian"
 
 msgid "prompt before overwriting"
-msgstr "pytanie przed nadpisaniem plików"
+msgstr "pytanie przed nadpisaniem plików"
 
 msgid "use strict OpenPGP behavior"
-msgstr "ścisłe zachowanie OpenPGP"
+msgstr "¶cis³e zachowanie OpenPGP"
 
 msgid ""
 "@\n"
 "(See the man page for a complete listing of all commands and options)\n"
 msgstr ""
 "@\n"
-"(Pełną listę poleceń i opcji można znaleźć w podręczniku systemowym.)\n"
+"(Pe³n± listê poleceñ i opcji mo¿na znale¼æ w podrêczniku systemowym.)\n"
 
 msgid ""
 "@\n"
@@ -1688,34 +1621,34 @@ msgid ""
 " --fingerprint [names]      show fingerprints\n"
 msgstr ""
 "@\n"
-"Przykłady:\n"
+"Przyk³ady:\n"
 "\n"
 " -se -r Bob [plik]          podpisanie i zaszyfrowanie kluczem Boba\n"
-" --clearsign [plik]         podpisanie z pozostawieniem czytelności "
+" --clearsign [plik]         podpisanie z pozostawieniem czytelnoci "
 "dokumentu\n"
 " --detach-sign [plik]       podpisanie z umieszczeniem podpisu w osobnym "
 "pliku\n"
 " --list-keys [nazwy]        pokazanie klucze\n"
-" --fingerprint [nazwy]      pokazanie odcisków kluczy\n"
+" --fingerprint [nazwy]      pokazanie odcisków kluczy\n"
 
 msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "Wywołanie: gpg [opcje] [pliki] (-h podaje pomoc)"
+msgstr "Wywo³anie: gpg [opcje] [pliki] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
-"Składnia: gpg [opcje] [pliki]\n"
-"Podpisywanie, sprawdzanie podpisów, szyfrowanie, rozszyfrowywanie\n"
-"Domyślnie wykonywana operacja zależy od danych wejściowych\n"
+"Sk³adnia: gpg [opcje] [pliki]\n"
+"podpisywanie, sprawdzanie podpisów, szyfrowanie, deszyfrowanie\n"
+"domy¶lnie wykonywana operacja zale¿y od danych wej¶ciowych\n"
 
 msgid ""
 "\n"
 "Supported algorithms:\n"
 msgstr ""
 "\n"
-"Obsługiwane algorytmy:\n"
+"Obs³ugiwane algorytmy:\n"
 
 msgid "Pubkey: "
 msgstr "Asymetryczne: "
@@ -1724,128 +1657,128 @@ msgid "Cipher: "
 msgstr "Symetryczne: "
 
 msgid "Hash: "
-msgstr "Skrótów: "
+msgstr "Skrótów: "
 
 msgid "Compression: "
 msgstr "Kompresji: "
 
 msgid "usage: gpg [options] "
-msgstr "wywołanie: gpg [opcje]"
+msgstr "wywo³anie: gpg [opcje]"
 
 msgid "conflicting commands\n"
 msgstr "sprzeczne polecenia\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "w definicji grupy ,,%s'' brak znaku ,,=''\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego ,,%s''\n"
+"OSTRZE¯ENIE: niebezpieczne prawa w³asno¶ci do katalogu domowego ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa własności do pliku konfiguracyjnego ,,%s''\n"
+"OSTRZE¯ENIE: niebezpieczne prawa w³asno¶ci do pliku konfiguracyjnego ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
-msgstr "OSTRZEŻENIE: niebezpieczne prawa własności do rozszerzenia ,,%s''\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
+msgstr "OSTRZE¯ENIE: niebezpieczne prawa w³asno¶ci do rozszerzenia ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
-msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu domowego ,,%s''\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
+msgstr "OSTRZE¯ENIE: niebezpieczne prawa dostêpu do katalogu domowego ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa dostępu do pliku konfiguracyjnego ,,%s''\n"
+"OSTRZE¯ENIE: niebezpieczne prawa dostêpu do pliku konfiguracyjnego ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
-msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do rozszerzenia ,,%s''\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
+msgstr "OSTRZE¯ENIE: niebezpieczne prawa dostêpu do rozszerzenia ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego katalog "
+"OSTRZE¯ENIE: niebezpieczne prawa w³asno¶ci do katalogu zawieraj±cego katalog "
 "domowy ,,%s''\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego plik "
+"OSTRZE¯ENIE: niebezpieczne prawa w³asno¶ci do katalogu zawieraj±cego plik "
 "konfiguracyjny ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego "
+"OSTRZE¯ENIE: niebezpieczne prawa w³asno¶ci do katalogu zawieraj±cego "
 "rozszerzenie ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego katalog "
+"OSTRZE¯ENIE: niebezpieczne prawa dostêpu do katalogu zawieraj±cego katalog "
 "domowy ,,%s''\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego plik "
+"OSTRZE¯ENIE: niebezpieczne prawa dostêpu do katalogu zawieraj±cego plik "
 "konfiguracyjny ,,%s''\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
-"OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego "
+"OSTRZE¯ENIE: niebezpieczne prawa dostêpu do katalogu zawieraj±cego "
 "rozszerzenie ,,%s''\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "nieznana opcja konfiguracyjna ,,%s''\n"
 
 msgid "display photo IDs during key listings"
-msgstr "wyświetlenie ID zdjęć przy wypisywaniu kluczy"
+msgstr "wy¶wietlenie ID zdjêæ przy wypisywaniu kluczy"
 
 msgid "show policy URLs during signature listings"
-msgstr "pokazywanie URL-i polityk przy wypisywaniu podpisów"
+msgstr "pokazywanie URL-i polityk przy wypisywaniu podpisów"
 
 msgid "show all notations during signature listings"
-msgstr "pokazywanie wszystkich adnotacji przy wypisywaniu podpisów"
+msgstr "pokazywanie wszystkich adnotacji przy wypisywaniu podpisów"
 
 msgid "show IETF standard notations during signature listings"
-msgstr "pokazywanie standardowych adnotacji IETF przy wypisywaniu podpisów"
+msgstr "pokazywanie standardowych adnotacji IETF przy wypisywaniu podpisów"
 
 msgid "show user-supplied notations during signature listings"
-msgstr "pokazywanie adnotacji użytkownika przy wypisywaniu podpisów"
+msgstr "pokazywanie adnotacji u¿ytkownika przy wypisywaniu podpisów"
 
 msgid "show preferred keyserver URLs during signature listings"
 msgstr ""
-"pokazywanie URL-i preferowanych serwerów kluczy przy wypisywaniu podpisów"
+"pokazywanie URL-i preferowanych serwerów kluczy przy wypisywaniu podpisów"
 
 msgid "show user ID validity during key listings"
-msgstr "pokazywanie poprawności ID użytkownika przy wypisywaniu kluczy"
+msgstr "pokazywanie poprawno¶ci ID u¿ytkownika przy wypisywaniu kluczy"
 
 msgid "show revoked and expired user IDs in key listings"
 msgstr ""
-"pokazywanie unieważnionych i wygasłych ID użytkownika na listach kluczy"
+"pokazywanie uniewa¿nionych i wygas³ych ID u¿ytkownika na listach kluczy"
 
 msgid "show revoked and expired subkeys in key listings"
-msgstr "pokazywanie unieważnionych i wygasłych podkluczy na listach kluczy"
+msgstr "pokazywanie uniewa¿nionych i wygas³ych podkluczy na listach kluczy"
 
 msgid "show the keyring name in key listings"
 msgstr "pokazywanie nazwy zbioru kluczy na listach kluczy"
 
 msgid "show expiration dates during signature listings"
-msgstr "pokazywanie dat wygaśnięcia przy wypisywaniu podpisów"
+msgstr "pokazywanie dat wyga¶niêcia przy wypisywaniu podpisów"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
-msgstr "UWAGA: stary domyślny plik opcji ,,%s'' został zignorowany\n"
+msgid "NOTE: old default options file '%s' ignored\n"
+msgstr "UWAGA: stary domy¶lny plik opcji ,,%s'' zosta³ zignorowany\n"
 
 #, c-format
 msgid "libgcrypt is too old (need %s, have %s)\n"
@@ -1854,18 +1787,18 @@ msgstr ""
 
 #, c-format
 msgid "NOTE: %s is not for normal use!\n"
-msgstr "UWAGA: %s nie jest do normalnego użytku!\n"
+msgstr "UWAGA: %s nie jest do normalnego u¿ytku!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
-msgstr ",,%s'' nie jest poprawnym czasem wygaśnięcia podpisu\n"
+msgid "'%s' is not a valid signature expiration\n"
+msgstr ",,%s'' nie jest poprawnym czasem wyga¶niêcia podpisu\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
-msgstr ",,%s'' nie jest poprawną nazwą zestawu znaków\n"
+msgid "'%s' is not a valid character set\n"
+msgstr ",,%s'' nie jest poprawn± nazw± zestawu znaków\n"
 
 msgid "could not parse keyserver URL\n"
-msgstr "niezrozumiały URL serwera kluczy\n"
+msgstr "niezrozumia³y URL serwera kluczy\n"
 
 #, c-format
 msgid "%s:%d: invalid keyserver options\n"
@@ -1896,40 +1829,40 @@ msgid "invalid list options\n"
 msgstr "niepoprawne opcje wypisywania\n"
 
 msgid "display photo IDs during signature verification"
-msgstr "wyświetlanie ID zdjęć przy sprawdzaniu podpisów"
+msgstr "wy¶wietlanie ID zdjêæ przy sprawdzaniu podpisów"
 
 msgid "show policy URLs during signature verification"
-msgstr "pokazywanie URL-i polityk przy sprawdzaniu podpisów"
+msgstr "pokazywanie URL-i polityk przy sprawdzaniu podpisów"
 
 msgid "show all notations during signature verification"
-msgstr "pokazywanie wszystkich adnotacji przy sprawdzaniu podpisów"
+msgstr "pokazywanie wszystkich adnotacji przy sprawdzaniu podpisów"
 
 msgid "show IETF standard notations during signature verification"
-msgstr "pokazywanie standardowych adnotacji IETF przy sprawdzaniu podpisów"
+msgstr "pokazywanie standardowych adnotacji IETF przy sprawdzaniu podpisów"
 
 msgid "show user-supplied notations during signature verification"
-msgstr "pokazywanie adnotacji użytkownika przy sprawdzaniu podpisów"
+msgstr "pokazywanie adnotacji u¿ytkownika przy sprawdzaniu podpisów"
 
 msgid "show preferred keyserver URLs during signature verification"
 msgstr ""
-"pokazywanie URL-i preferowanych serwerów kluczy przy sprawdzaniu podpisów"
+"pokazywanie URL-i preferowanych serwerów kluczy przy sprawdzaniu podpisów"
 
 msgid "show user ID validity during signature verification"
-msgstr "pokazywanie poprawności ID użytkownika przy sprawdzaniu podpisów"
+msgstr "pokazywanie poprawno¶ci ID u¿ytkownika przy sprawdzaniu podpisów"
 
 msgid "show revoked and expired user IDs in signature verification"
 msgstr ""
-"pokazywanie unieważnionych i wygasłych ID użytkownika przy sprawdzaniu "
-"podpisów"
+"pokazywanie uniewa¿nionych i wygas³ych ID u¿ytkownika przy sprawdzaniu "
+"podpisów"
 
 msgid "show only the primary user ID in signature verification"
-msgstr "pokazywanie tylko głównego ID użytkownika przy sprawdzaniu podpisu"
+msgstr "pokazywanie tylko g³ównego ID u¿ytkownika przy sprawdzaniu podpisu"
 
 msgid "validate signatures with PKA data"
-msgstr "sprawdzanie podpisów z danymi PKA"
+msgstr "sprawdzanie podpisów z danymi PKA"
 
 msgid "elevate the trust of signatures with valid PKA data"
-msgstr "zwiększenie zaufania podpisów z poprawnymi danymi PKA"
+msgstr "zwiêkszenie zaufania podpisów z poprawnymi danymi PKA"
 
 #, c-format
 msgid "%s:%d: invalid verify options\n"
@@ -1940,7 +1873,7 @@ msgstr "niepoprawne opcje sprawdzania\n"
 
 #, c-format
 msgid "unable to set exec-path to %s\n"
-msgstr "nie można ustawić ścieżki programów wykonywalnych na %s\n"
+msgstr "nie mo¿na ustawiæ ¶cie¿ki programów wykonywalnych na %s\n"
 
 #, c-format
 msgid "%s:%d: invalid auto-key-locate list\n"
@@ -1950,107 +1883,107 @@ msgid "invalid auto-key-locate list\n"
 msgstr "Niepoprawna lista auto-key-locate\n"
 
 msgid "WARNING: program may create a core file!\n"
-msgstr "OSTRZEŻENIE: program może stworzyć plik zrzutu pamięci!\n"
+msgstr "OSTRZE¯ENIE: program mo¿e stworzyæ plik zrzutu pamiêci!\n"
 
 #, c-format
 msgid "WARNING: %s overrides %s\n"
-msgstr "OSTRZEŻENIE: %s powoduje obejście %s\n"
+msgstr "OSTRZE¯ENIE: %s powoduje obej¶cie %s\n"
 
 #, c-format
 msgid "%s not allowed with %s!\n"
-msgstr "Nie wolno używać %s z %s!\n"
+msgstr "Nie wolno u¿ywaæ %s z %s!\n"
 
 #, c-format
 msgid "%s makes no sense with %s!\n"
-msgstr "%s nie ma sensu w połączeniu z %s!\n"
+msgstr "%s nie ma sensu w po³±czeniu z %s!\n"
 
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
-msgstr "nie zadziała z niebezpieczną pamięcią z powodu %s\n"
+msgstr "nie zadzia³a z niebezpieczn± pamiêci± z powodu %s\n"
 
 msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
 msgstr ""
-"w trybie --pgp2 można składać tylko podpisy oddzielne lub dołączone do "
+"w trybie --pgp2 mo¿na sk³adaæ tylko podpisy oddzielne lub do³±czone do "
 "tekstu\n"
 
 msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr "w trybie --pgp2 nie można jednocześnie szyfrować i podpisywać\n"
+msgstr "w trybie --pgp2 nie mo¿na jednocze¶nie szyfrowaæ i podpisywaæ\n"
 
 msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr "w trybie --pgp2 trzeba używać plików a nie potoków.\n"
+msgstr "w trybie --pgp2 trzeba u¿ywaæ plików a nie potoków.\n"
 
 msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr "szyfrowanie wiadomości w trybie --pgp2 wymaga modułu szyfru IDEA\n"
+msgstr "szyfrowanie wiadomo¶ci w trybie --pgp2 wymaga modu³u szyfru IDEA\n"
 
 msgid "selected cipher algorithm is invalid\n"
-msgstr "wybrany algorytm szyfrujący jest niepoprawny\n"
+msgstr "wybrany algorytm szyfruj±cy jest niepoprawny\n"
 
 msgid "selected digest algorithm is invalid\n"
-msgstr "wybrany algorytm skrótów wiadomości jest niepoprawny\n"
+msgstr "wybrany algorytm skrótów wiadomo¶ci jest niepoprawny\n"
 
 msgid "selected compression algorithm is invalid\n"
 msgstr "wybrany algorytm kompresji jest niepoprawny\n"
 
 msgid "selected certification digest algorithm is invalid\n"
-msgstr "wybrany algorytm skrótów poświadczeń jest niepoprawny\n"
+msgstr "wybrany algorytm skrótów po¶wiadczeñ jest niepoprawny\n"
 
 msgid "completes-needed must be greater than 0\n"
-msgstr "wartość completes-needed musi być większa od 0\n"
+msgstr "warto¶æ completes-needed musi byæ wiêksza od 0\n"
 
 msgid "marginals-needed must be greater than 1\n"
-msgstr "wartość marginals-needed musi być większa od 1\n"
+msgstr "warto¶æ marginals-needed musi byæ wiêksza od 1\n"
 
 msgid "max-cert-depth must be in the range from 1 to 255\n"
-msgstr "wartość max-cert-depth musi mieścić się w zakresie od 1 do 255\n"
+msgstr "warto¶æ max-cert-depth musi mie¶ciæ siê w zakresie od 1 do 255\n"
 
 msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n"
 msgstr ""
-"niewłaściwy domyślny poziom sprawdzania; musi mieć wartość 0, 1, 2 lub 3\n"
+"niew³a¶ciwy domy¶lny poziom sprawdzania; musi mieæ warto¶æ 0, 1, 2 lub 3\n"
 
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
 msgstr ""
-"niewłaściwy minimalny poziom sprawdzania; musi mieć wartość 0, 1, 2 lub 3\n"
+"niew³a¶ciwy minimalny poziom sprawdzania; musi mieæ warto¶æ 0, 1, 2 lub 3\n"
 
 msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
 msgstr "UWAGA: prosty tryb S2K (0) jest stanowczo odradzany\n"
 
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
-msgstr "niepoprawny tryb S2K; musi mieć wartość 0, 1 lub 3\n"
+msgstr "niepoprawny tryb S2K; musi mieæ warto¶æ 0, 1 lub 3\n"
 
 msgid "invalid default preferences\n"
-msgstr "niewłaściwe domyślne ustawienia\n"
+msgstr "niew³a¶ciwe domy¶lne ustawienia\n"
 
 msgid "invalid personal cipher preferences\n"
-msgstr "niewłaściwe ustawienia szyfrów\n"
+msgstr "niew³a¶ciwe ustawienia szyfrów\n"
 
 msgid "invalid personal digest preferences\n"
-msgstr "niewłaściwe ustawienia skrótów\n"
+msgstr "niew³a¶ciwe ustawienia skrótów\n"
 
 msgid "invalid personal compress preferences\n"
-msgstr "niewłaściwe ustawienia algorytmów kompresji\n"
+msgstr "niew³a¶ciwe ustawienia algorytmów kompresji\n"
 
 #, c-format
 msgid "%s does not yet work with %s\n"
-msgstr "%s jeszcze nie działa z %s!\n"
+msgstr "%s jeszcze nie dzia³a z %s!\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
-msgstr "szyfr ,,%s'' nie jest dostępny w trybie %s\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgstr "szyfr ,,%s'' nie jest dostêpny w trybie %s\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
-msgstr "skrót ,,%s'' nie jest dostępny w trybie %s\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgstr "skrót ,,%s'' nie jest dostêpny w trybie %s\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
-msgstr "kompresja ,,%s'' nie jest dostępna w trybie %s\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgstr "kompresja ,,%s'' nie jest dostêpna w trybie %s\n"
 
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
-msgstr "inicjowanie Bazy Zaufania nie powiodło się: %s\n"
+msgstr "inicjowanie Bazy Zaufania nie powiod³o siê: %s\n"
 
 msgid "WARNING: recipients (-r) given without using public key encryption\n"
-msgstr "OSTRZEŻENIE: podano adresatów (-r) w działaniu które ich nie dotyczy\n"
+msgstr "OSTRZE¯ENIE: podano adresatów (-r) w dzia³aniu które ich nie dotyczy\n"
 
 msgid "--store [filename]"
 msgstr "--store [plik]"
@@ -2059,8 +1992,8 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [plik]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
-msgstr "szyfrowanie symetryczne ,,%s'' nie powiodło się: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
+msgstr "szyfrowanie symetryczne ,,%s'' nie powiod³o siê: %s\n"
 
 msgid "--encrypt [filename]"
 msgstr "--encrypt [plik]"
@@ -2069,11 +2002,11 @@ msgid "--symmetric --encrypt [filename]"
 msgstr "--symmetric --encrypt [plik]"
 
 msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
-msgstr "nie można użyć --symmetric --encrypt wraz z --s2k-mode 0\n"
+msgstr "nie mo¿na u¿yæ --symmetric --encrypt wraz z --s2k-mode 0\n"
 
 #, c-format
 msgid "you cannot use --symmetric --encrypt while in %s mode\n"
-msgstr "nie można użyć --symmetric --encrypt w trybie %s\n"
+msgstr "nie mo¿na u¿yæ --symmetric --encrypt w trybie %s\n"
 
 msgid "--sign [filename]"
 msgstr "--sign [plik]"
@@ -2085,11 +2018,11 @@ msgid "--symmetric --sign --encrypt [filename]"
 msgstr "--symmetric --sign --encrypt [plik]"
 
 msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
-msgstr "nie można użyć --symmetric --sign --encrypt wraz z --s2k-mode 0\n"
+msgstr "nie mo¿na u¿yæ --symmetric --sign --encrypt wraz z --s2k-mode 0\n"
 
 #, c-format
 msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
-msgstr "nie można użyć --symmetric --sign --encrypt w trybie %s\n"
+msgstr "nie mo¿na u¿yæ --symmetric --sign --encrypt w trybie %s\n"
 
 msgid "--sign --symmetric [filename]"
 msgstr "--sign --symmetric [plik]"
@@ -2101,98 +2034,94 @@ msgid "--decrypt [filename]"
 msgstr "--decrypt [plik]"
 
 msgid "--sign-key user-id"
-msgstr "--sign-key nazwa użytkownika"
+msgstr "--sign-key nazwa u¿ytkownika"
 
 msgid "--lsign-key user-id"
-msgstr "--lsign-key nazwa użytkownika"
+msgstr "--lsign-key nazwa u¿ytkownika"
 
 msgid "--edit-key user-id [commands]"
-msgstr "--edit-key nazwa użytkownika [polecenia]"
-
-msgid "--passwd <user-id>"
-msgstr "--passwd <id-użytkownika>"
+msgstr "--edit-key nazwa u¿ytkownika [polecenia]"
 
 #, c-format
 msgid "keyserver send failed: %s\n"
-msgstr "wysyłka do serwera kluczy nie powiodła się: %s\n"
+msgstr "wysy³ka do serwera kluczy nie powiod³a siê: %s\n"
 
 #, c-format
 msgid "keyserver receive failed: %s\n"
-msgstr "odbiór z serwera kluczy nie powiódł się: %s\n"
+msgstr "odbiór z serwera kluczy nie powiód³ siê: %s\n"
 
 #, c-format
 msgid "key export failed: %s\n"
-msgstr "eksport kluczy nie powiódł się: %s\n"
+msgstr "eksport kluczy nie powiód³ siê: %s\n"
 
 #, c-format
 msgid "keyserver search failed: %s\n"
-msgstr "szukanie w serwerze kluczy nie powiodło się: %s\n"
+msgstr "szukanie w serwerze kluczy nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "keyserver refresh failed: %s\n"
-msgstr "odświeżenie kluczy z serwera nie powiodło się: %s\n"
+msgstr "od¶wie¿enie kluczy z serwera nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "dearmoring failed: %s\n"
-msgstr "zdjęcie opakowania ASCII nie powiodło się: %s\n"
+msgstr "zdjêcie opakowania ASCII nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "enarmoring failed: %s\n"
-msgstr "opakowywanie ASCII nie powiodło się: %s\n"
+msgstr "opakowywanie ASCII nie powiod³o siê: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
-msgstr "niewłaściwy algorytm skrótu ,,%s''\n"
+msgid "invalid hash algorithm '%s'\n"
+msgstr "niew³a¶ciwy algorytm skrótu ,,%s''\n"
 
 msgid "[filename]"
 msgstr "[nazwa pliku]"
 
 msgid "Go ahead and type your message ...\n"
-msgstr "Wpisz tutaj swoją wiadomość ...\n"
+msgstr "Wpisz tutaj swoj± wiadomo¶æ ...\n"
 
 msgid "the given certification policy URL is invalid\n"
-msgstr "podany URL regulaminu poświadczania jest niepoprawny\n"
+msgstr "podany URL regulaminu powiadczania jest niepoprawny\n"
 
 msgid "the given signature policy URL is invalid\n"
-msgstr "podany URL regulaminu podpisów jest niepoprawny\n"
+msgstr "podany URL regulaminu podpisów jest niepoprawny\n"
 
 msgid "the given preferred keyserver URL is invalid\n"
 msgstr "podany preferowany URL serwera kluczy jest niepoprawny\n"
 
+#, fuzzy
 msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|PLIK|pobieranie kluczy ze zbioru PLIK"
+msgstr "pobieranie kluczy z tego zbioru"
 
 msgid "make timestamp conflicts only a warning"
-msgstr "nie traktować konfliktu datowników jako błędu"
+msgstr "nie traktowaæ konfliktu datowników jako b³êdu"
 
 msgid "|FD|write status info to this FD"
 msgstr "|FD|pisanie opisu stanu do deskryptora FD"
 
 msgid "Usage: gpgv [options] [files] (-h for help)"
-msgstr "Wywołanie: gpgv [opcje] [pliki] (-h podaje pomoc)"
+msgstr "Wywo³anie: gpgv [opcje] [pliki] (-h podaje pomoc)"
 
+#, fuzzy
 msgid ""
 "Syntax: gpgv [options] [files]\n"
 "Check signatures against known trusted keys\n"
 msgstr ""
-"Składnia: gpgv [opcje] [pliki]\n"
-"Sprawdzanie podpisów ze znanych zaufanych kluczy\n"
+"Sk³adnia: gpg [opcje] [pliki]\n"
+"Sprawdzanie podpisów ze znanych zaufanych kluczy\n"
 
 msgid "No help available"
-msgstr "Pomoc niedostępna"
+msgstr "Pomoc niedostêpna"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Brak pomocy o ,,%s''"
 
 msgid "import signatures that are marked as local-only"
-msgstr "import podpisów oznaczonych jako tylko lokalne"
+msgstr "import podpisów oznaczonych jako tylko lokalne"
 
 msgid "repair damage from the pks keyserver during import"
-msgstr "naprawienie uszkodzeń z serwera pks przy imporcie"
-
-msgid "do not clear the ownertrust values during import"
-msgstr "bez czyszczenia wartości zaufania właściciela przy imporcie"
+msgstr "naprawienie uszkodzeñ z serwera pks przy imporcie"
 
 msgid "do not update the trustdb after import"
 msgstr "nie uaktualnianie bazy zaufania po imporcie"
@@ -2201,17 +2130,17 @@ msgid "create a public key when importing a secret key"
 msgstr "tworzenie kluczy publicznych przy imporcie kluczy tajnych"
 
 msgid "only accept updates to existing keys"
-msgstr "przyjmowanie tylko uaktualnień istniejących kluczy"
+msgstr "przyjmowanie tylko uaktualnieñ istniej±cych kluczy"
 
 msgid "remove unusable parts from key after import"
-msgstr "usuwanie bezużytecznych części kluczy po imporcie"
+msgstr "usuwanie bezu¿ytecznych czê¶ci kluczy po imporcie"
 
 msgid "remove as much as possible from key after import"
-msgstr "usuwanie jak największej części kluczy po imporcie"
+msgstr "usuwanie jak najwiêkszej czê¶ci kluczy po imporcie"
 
 #, c-format
 msgid "skipping block of type %d\n"
-msgstr "blok typu %d zostaje pominięty\n"
+msgstr "blok typu %d zostaje pominiêty\n"
 
 #, c-format
 msgid "%lu keys processed so far\n"
@@ -2219,11 +2148,11 @@ msgstr "%lu kluczy przetworzonych do tej chwili\n"
 
 #, c-format
 msgid "Total number processed: %lu\n"
-msgstr "Ogółem przetworzonych kluczy: %lu\n"
+msgstr "Ogó³em przetworzonych kluczy: %lu\n"
 
 #, c-format
 msgid "      skipped new keys: %lu\n"
-msgstr "   pominiętych nowych kluczy: %lu\n"
+msgstr "   pominiêtych nowych kluczy: %lu\n"
 
 #, c-format
 msgid "          w/o user IDs: %lu\n"
@@ -2231,7 +2160,7 @@ msgstr "          bez identyfikatora: %lu\n"
 
 #, c-format
 msgid "              imported: %lu"
-msgstr "         dołączono do zbioru: %lu"
+msgstr "         do³±czono do zbioru: %lu"
 
 #, c-format
 msgid "             unchanged: %lu\n"
@@ -2239,7 +2168,7 @@ msgstr "                   bez zmian: %lu\n"
 
 #, c-format
 msgid "          new user IDs: %lu\n"
-msgstr "      nowych identyfikatorów: %lu\n"
+msgstr "      nowych identyfikatorów: %lu\n"
 
 #, c-format
 msgid "           new subkeys: %lu\n"
@@ -2247,11 +2176,11 @@ msgstr "            nowych podkluczy: %lu\n"
 
 #, c-format
 msgid "        new signatures: %lu\n"
-msgstr "             nowych podpisów: %lu\n"
+msgstr "             nowych podpisów: %lu\n"
 
 #, c-format
 msgid "   new key revocations: %lu\n"
-msgstr "   nowych unieważnień kluczy: %lu\n"
+msgstr "   nowych uniewa¿nieñ kluczy: %lu\n"
 
 #, c-format
 msgid "      secret keys read: %lu\n"
@@ -2267,23 +2196,23 @@ msgstr "    tajnych kluczy bez zmian: %lu\n"
 
 #, c-format
 msgid "          not imported: %lu\n"
-msgstr "      nie włączono do zbioru: %lu\n"
+msgstr "      nie w³±czono do zbioru: %lu\n"
 
 #, c-format
 msgid "    signatures cleaned: %lu\n"
-msgstr "     podpisów wyczyszczonych: %lu\n"
+msgstr "     podpisów wyczyszczonych: %lu\n"
 
 #, c-format
 msgid "      user IDs cleaned: %lu\n"
-msgstr "ID użytkownika wyczyszczonych: %lu\n"
+msgstr "ID u¿ytkownika wyczyszczonych: %lu\n"
 
 #, c-format
 msgid ""
 "WARNING: key %s contains preferences for unavailable\n"
 "algorithms on these user IDs:\n"
 msgstr ""
-"OSTRZEŻENIE: klucz %s zawiera preferencje dla niedostępnych\n"
-"algorytmów dla tych ID użytkownika:\n"
+"OSTRZE¯ENIE: klucz %s zawiera preferencje dla niedostêpnych\n"
+"algorytmów dla tych ID u¿ytkownika:\n"
 
 #, c-format
 msgid "         \"%s\": preference for cipher algorithm %s\n"
@@ -2291,48 +2220,41 @@ msgstr "         ,,%s'': preferowany szyfr %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for digest algorithm %s\n"
-msgstr "         ,,%s'': preferowany algorytm skrótu %s\n"
+msgstr "         ,,%s'': preferowany algorytm skrótu %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for compression algorithm %s\n"
 msgstr "         ,,%s'': preferowany algorytm kompresji %s\n"
 
 msgid "it is strongly suggested that you update your preferences and\n"
-msgstr "zdecydowanie sugerowane jest uaktualnienie ustawień i ponowne\n"
+msgstr "zdecydowanie sugerowane jest uaktualnienie ustawieñ i ponowne\n"
 
 msgid "re-distribute this key to avoid potential algorithm mismatch problems\n"
-msgstr "rozesłanie tego klucza w celu uniknięcia niezgodności algorytmów\n"
+msgstr "rozes³anie tego klucza w celu unikniêcia niezgodno¶ci algorytmów\n"
 
 #, c-format
 msgid "you can update your preferences with: gpg --edit-key %s updpref save\n"
 msgstr ""
-"można uaktualnić swoje ustawienia poprzez: gpg --edit-key %s updpref save\n"
+"mo¿na uaktualniæ swoje ustawienia poprzez: gpg --edit-key %s updpref save\n"
 
 #, c-format
 msgid "key %s: no user ID\n"
-msgstr "klucz %s: brak identyfikatora użytkownika\n"
-
-#, c-format
-msgid "key %s: %s\n"
-msgstr "klucz %s: %s\n"
-
-msgid "rejected by import filter"
-msgstr "odrzucony przez filtr importu"
+msgstr "klucz %s: brak identyfikatora u¿ytkownika\n"
 
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
-msgstr "klucz %s: podklucz uszkodzony przez serwer został naprawiony\n"
+msgstr "klucz %s: podklucz uszkodzony przez serwer zosta³ naprawiony\n"
 
 #, c-format
 msgid "key %s: accepted non self-signed user ID \"%s\"\n"
-msgstr "klucz %s: przyjęto identyfikator nie podpisany nim samym ,,%s''\n"
+msgstr "klucz %s: przyjêto identyfikator nie podpisany nim samym ,,%s''\n"
 
 #, c-format
 msgid "key %s: no valid user IDs\n"
-msgstr "klucz %s: brak poprawnych identyfikatorów użytkownika\n"
+msgstr "klucz %s: brak poprawnych identyfikatorów u¿ytkownika\n"
 
 msgid "this may be caused by a missing self-signature\n"
-msgstr "to może być spowodowane brakiem podpisu klucza nim samym\n"
+msgstr "to mo¿e byæ spowodowane brakiem podpisu klucza nim samym\n"
 
 #, c-format
 msgid "key %s: public key not found: %s\n"
@@ -2340,19 +2262,19 @@ msgstr "klucz %s: brak klucza publicznego: %s\n"
 
 #, c-format
 msgid "key %s: new key - skipped\n"
-msgstr "klucz %s: nowy klucz - pominięty\n"
+msgstr "klucz %s: nowy klucz - pominiêty\n"
 
 #, c-format
 msgid "no writable keyring found: %s\n"
 msgstr "brak zapisywalnego zbioru kluczy: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "zapis do ,,%s''\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
-msgstr "błąd zapisu zbioru kluczy ,,%s'': %s\n"
+msgid "error writing keyring '%s': %s\n"
+msgstr "b³±d zapisu zbioru kluczy ,,%s'': %s\n"
 
 #, c-format
 msgid "key %s: public key \"%s\" imported\n"
@@ -2360,7 +2282,7 @@ msgstr "klucz %s: klucz publiczny ,,%s'' wczytano do zbioru\n"
 
 #, c-format
 msgid "key %s: doesn't match our copy\n"
-msgstr "klucz %s: nie zgadza się z lokalną kopią\n"
+msgstr "klucz %s: nie zgadza siê z lokaln± kopi±\n"
 
 #, c-format
 msgid "key %s: can't locate original keyblock: %s\n"
@@ -2368,15 +2290,15 @@ msgstr "klucz %s: brak oryginalnego bloku klucza; %s\n"
 
 #, c-format
 msgid "key %s: can't read original keyblock: %s\n"
-msgstr "klucz %s: nie można odczytać oryginalnego bloku klucza: %s\n"
+msgstr "klucz %s: nie mo¿na odczytaæ oryginalnego bloku klucza: %s\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new user ID\n"
-msgstr "klucz %s: ,,%s'' 1 nowy identyfikator użytkownika\n"
+msgstr "klucz %s: ,,%s'' 1 nowy identyfikator u¿ytkownika\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d new user IDs\n"
-msgstr "klucz %s: ,,%s'' %d nowych identyfikatorów użytkownika\n"
+msgstr "klucz %s: ,,%s'' %d nowych identyfikatorów u¿ytkownika\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new signature\n"
@@ -2384,7 +2306,7 @@ msgstr "klucz %s: ,,%s'' 1 nowy podpis\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d new signatures\n"
-msgstr "klucz %s: ,,%s'' %d nowych podpisów\n"
+msgstr "klucz %s: ,,%s'' %d nowych podpisów\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new subkey\n"
@@ -2400,34 +2322,30 @@ msgstr "klucz %s: ,,%s'' %d podpis wyczyszczony\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d signatures cleaned\n"
-msgstr "klucz %s: ,,%s'' %d podpisów wyczyszczonych\n"
+msgstr "klucz %s: ,,%s'' %d podpisów wyczyszczonych\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d user ID cleaned\n"
-msgstr "klucz %s: ,,%s'' %d identyfikator użytkownika wyczyszczony\n"
+msgstr "klucz %s: ,,%s'' %d identyfikator u¿ytkownika wyczyszczony\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d user IDs cleaned\n"
-msgstr "klucz %s: ,,%s'' %d identyfikatorów użytkownika wyczyszczonych\n"
+msgstr "klucz %s: ,,%s'' %d identyfikatorów u¿ytkownika wyczyszczonych\n"
 
 #, c-format
 msgid "key %s: \"%s\" not changed\n"
 msgstr "klucz %s: ,,%s'' bez zmian\n"
 
 #, c-format
-msgid "secret key %s: %s\n"
-msgstr "klucz prywatny %s: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "klucz %s: klucz tajny z b³êdnym szyfrem %d - pominiêty\n"
 
 msgid "importing secret keys not allowed\n"
 msgstr "wczytywanie kluczy tajnych nie jest dozwolone\n"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "klucz %s: klucz tajny z błędnym szyfrem %d - pominięty\n"
-
-#, c-format
 msgid "no default secret keyring: %s\n"
-msgstr "brak domyślnego zbioru kluczy tajnych: %s\n"
+msgstr "brak domylnego zbioru kluczy tajnych: %s\n"
 
 #, c-format
 msgid "key %s: secret key imported\n"
@@ -2435,7 +2353,7 @@ msgstr "klucz %s: klucz tajny wczytany do zbioru\n"
 
 #, c-format
 msgid "key %s: already in secret keyring\n"
-msgstr "klucz %s: ten klucz tajny już znajduje się w zbiorze\n"
+msgstr "klucz %s: ten klucz tajny ju¿ znajduje siê w zbiorze\n"
 
 #, c-format
 msgid "key %s: secret key not found: %s\n"
@@ -2444,142 +2362,138 @@ msgstr "klucz %s: brak klucza tajnego: %s\n"
 #, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
 msgstr ""
-"klucz %s: brak klucza publicznego którego dotyczy wczytany certyfikat\n"
-"              unieważnienia\n"
+"klucz %s: brak klucza publicznego którego dotyczy wczytany certyfikat\n"
+"              uniewa¿nienia\n"
 
 #, c-format
 msgid "key %s: invalid revocation certificate: %s - rejected\n"
-msgstr "klucz %s: niepoprawny certyfikat unieważnienia: %s - odrzucony\n"
+msgstr "klucz %s: niepoprawny certyfikat uniewa¿nienia: %s - odrzucony\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate imported\n"
-msgstr "klucz %s: ,,%s'' certyfikat unieważnienia został już wczytany\n"
+msgstr "klucz %s: ,,%s'' certyfikat uniewa¿nienia zosta³ ju¿ wczytany\n"
 
 #, c-format
 msgid "key %s: no user ID for signature\n"
-msgstr "klucz %s: brak identyfikatora użytkownika do podpisu\n"
+msgstr "klucz %s: brak identyfikatora u¿ytkownika do podpisu\n"
 
 #, c-format
 msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
-msgstr "klucz %s: algorytm asymetryczny dla id ,,%s'' nie jest obsługiwany\n"
+msgstr "klucz %s: algorytm asymetryczny dla id ,,%s'' nie jest obs³ugiwany\n"
 
 #, c-format
 msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "klucz %s: niepoprawny podpis na identyfikatorze ,,%s''\n"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "klucz %s: nieobsługiwany algorytm asymetryczny\n"
-
-#, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "klucz %s: nieprawidłowy bezpośredni podpis\n"
+msgid "key %s: no subkey for key binding\n"
+msgstr "klucz %s: brak podklucza do dowi±zania\n"
 
 #, c-format
-msgid "key %s: no subkey for key binding\n"
-msgstr "klucz %s: brak podklucza do dowiązania\n"
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "klucz %s: nieobs³ugiwany algorytm asymetryczny\n"
 
 #, c-format
 msgid "key %s: invalid subkey binding\n"
-msgstr "klucz %s: niepoprawne dowiązanie podklucza\n"
+msgstr "klucz %s: niepoprawne dowi±zanie podklucza\n"
 
 #, c-format
 msgid "key %s: removed multiple subkey binding\n"
-msgstr "klucz %s: usunięto wielokrotne dowiązanie podklucza\n"
+msgstr "klucz %s: usuniêto wielokrotne dowi±zanie podklucza\n"
 
 #, c-format
 msgid "key %s: no subkey for key revocation\n"
-msgstr "klucz %s: brak podklucza, którego dotyczy unieważnienie\n"
+msgstr "klucz %s: brak podklucza, którego dotyczy uniewa¿nienie\n"
 
 #, c-format
 msgid "key %s: invalid subkey revocation\n"
-msgstr "klucz %s: niepoprawne unieważnienie podklucza\n"
+msgstr "klucz %s: niepoprawne uniewa¿nienie podklucza\n"
 
 #, c-format
 msgid "key %s: removed multiple subkey revocation\n"
-msgstr "klucz %s: usunięto wielokrotne unieważnienie podklucza\n"
+msgstr "klucz %s: usuniêto wielokrotne uniewa¿nienie podklucza\n"
 
 #, c-format
 msgid "key %s: skipped user ID \"%s\"\n"
-msgstr "klucz %s: pominięto identyfikator użytkownika ,,%s''\n"
+msgstr "klucz %s: pominiêto identyfikator u¿ytkownika ,,%s''\n"
 
 #, c-format
 msgid "key %s: skipped subkey\n"
-msgstr "klucz %s: podklucz pominięty\n"
+msgstr "klucz %s: podklucz pominiêty\n"
 
 #, c-format
 msgid "key %s: non exportable signature (class 0x%02X) - skipped\n"
-msgstr "klucz %s: podpis nieeksportowalny (klasy 0x%02X) - pominięty\n"
+msgstr "klucz %s: podpis nieeksportowalny (klasy 0x%02X) - pominiêty\n"
 
 #, c-format
 msgid "key %s: revocation certificate at wrong place - skipped\n"
 msgstr ""
-"klucz %s: pominięto certyfikat unieważnienia umieszczony\n"
-"              w niewłaściwym miejscu\n"
+"klucz %s: pominiêto certyfikat uniewa¿nienia umieszczony\n"
+"              w niew³a¶ciwym miejscu\n"
 
 #, c-format
 msgid "key %s: invalid revocation certificate: %s - skipped\n"
-msgstr "klucz %s: pominięto -  niepoprawny certyfikat unieważnienia: %s\n"
+msgstr "klucz %s: pominiêto -  niepoprawny certyfikat uniewa¿nienia: %s\n"
 
 #, c-format
 msgid "key %s: subkey signature in wrong place - skipped\n"
-msgstr "klucz %s: pominięto - podpis na podkluczu w niewłaściwym miejscu\n"
+msgstr "klucz %s: pominiêto - podpis na podkluczu w niew³a¶ciwym miejscu\n"
 
 #, c-format
 msgid "key %s: unexpected signature class (0x%02X) - skipped\n"
-msgstr "klucz %s: pominięto - nieoczekiwana klasa podpisu (0x%02X)\n"
+msgstr "klucz %s: pominiêto - nieoczekiwana klasa podpisu (0x%02X)\n"
 
 #, c-format
 msgid "key %s: duplicated user ID detected - merged\n"
-msgstr "key %s: dołączono powtórzony identyfikator użytkownika\n"
+msgstr "key %s: do³±czono powtórzony identyfikator u¿ytkownika\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
 msgstr ""
-"OSTRZEŻENIE: klucz %s mógł zostać unieważniony:\n"
-"             zapytanie o unieważniający klucz %s w serwerze kluczy\n"
+"OSTRZE¯ENIE: klucz %s móg³ zostaæ uniewa¿niony:\n"
+"             zapytanie o uniewa¿niaj±cy klucz %s w serwerze kluczy\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
 msgstr ""
-"OSTRZEŻENIE: klucz %s mógł zostać unieważniony:\n"
-"             brak unieważniającego klucza %s.\n"
+"OSTRZE¯ENIE: klucz %s móg³ zostaæ uniewa¿niony:\n"
+"             brak uniewa¿niaj±cego klucza %s.\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate added\n"
-msgstr "klucz %s: ,,%s'' dodany certyfikat unieważnienia\n"
+msgstr "klucz %s: ,,%s'' dodany certyfikat uniewa¿nienia\n"
 
 #, c-format
 msgid "key %s: direct key signature added\n"
-msgstr "klucz %s: dodano bezpośredni podpis\n"
+msgstr "klucz %s: dodano bezporedni podpis\n"
 
 msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr "UWAGA: numer seryjny klucza nie zgadza się z numerem karty\n"
+msgstr "UWAGA: numer seryjny klucza nie zgadza siê z numerem karty\n"
 
 msgid "NOTE: primary key is online and stored on card\n"
-msgstr "UWAGA: klucz główny jest aktywny i zapisany na karcie\n"
+msgstr "UWAGA: klucz g³ówny jest aktywny i zapisany na karcie\n"
 
 msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "UWAGA: klucz dodatkowy jest aktywny i zapisany na karcie\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
-msgstr "błąd tworzenia zbioru kluczy `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
+msgstr "b³±d tworzenia zbioru kluczy `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
-msgstr "zbiór kluczy ,,%s'' został utworzony\n"
+msgid "keyring '%s' created\n"
+msgstr "zbiór kluczy ,,%s'' zosta³ utworzony\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
-msgstr "zasób bloku klucza `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
+msgstr "zasób bloku klucza `%s': %s\n"
 
 #, c-format
 msgid "failed to rebuild keyring cache: %s\n"
-msgstr "nie powiodła się odbudowa bufora bazy: %s\n"
+msgstr "nie powiod³a siê odbudowa bufora bazy: %s\n"
 
 msgid "[revocation]"
-msgstr "[unieważnienie]"
+msgstr "[uniewa¿nienie]"
 
 msgid "[self-signature]"
 msgstr "[podpis klucza nim samym]"
@@ -2589,29 +2503,29 @@ msgstr "1 niepoprawny podpis\n"
 
 #, c-format
 msgid "%d bad signatures\n"
-msgstr "%d niepoprawnych podpisów\n"
+msgstr "%d niepoprawnych podpisów\n"
 
 msgid "1 signature not checked due to a missing key\n"
-msgstr "1 podpis nie został sprawdzony z powodu braku klucza\n"
+msgstr "1 podpis nie zosta³ sprawdzony z powodu braku klucza\n"
 
 #, c-format
 msgid "%d signatures not checked due to missing keys\n"
-msgstr "%d podpisów nie zostało sprawdzonych z powodu braku kluczy\n"
+msgstr "%d podpisów nie zosta³o sprawdzonych z powodu braku kluczy\n"
 
 msgid "1 signature not checked due to an error\n"
-msgstr "1 podpis nie został sprawdzony z powodu błędu\n"
+msgstr "1 podpis nie zosta³ sprawdzony z powodu b³êdu\n"
 
 #, c-format
 msgid "%d signatures not checked due to errors\n"
-msgstr "%d podpisów nie sprawdzonych z powodu błędów\n"
+msgstr "%d podpisów nie sprawdzonych z powodu b³êdów\n"
 
 msgid "1 user ID without valid self-signature detected\n"
-msgstr "wykryto 1 identyfikator użytkownika niepodpisany tym samym kluczem\n"
+msgstr "wykryto 1 identyfikator u¿ytkownika niepodpisany tym samym kluczem\n"
 
 #, c-format
 msgid "%d user IDs without valid self-signatures detected\n"
 msgstr ""
-"wykryto %d identyfikatorów użytkownika niepodpisanych tym samym kluczem\n"
+"wykryto %d identyfikatorów u¿ytkownika niepodpisanych tym samym kluczem\n"
 
 msgid ""
 "Please decide how far you trust this user to correctly verify other users' "
@@ -2619,9 +2533,9 @@ msgid ""
 "(by looking at passports, checking fingerprints from different sources, "
 "etc.)\n"
 msgstr ""
-"Zastanów się jak bardzo ufasz temu użytkownikowi w kwestii sprawdzania\n"
-"tożsamości innych użytkowników (czy sprawdzi on odciski kluczy pobrane\n"
-"z różnych źródeł, dokumenty potwierdzające tożsamość, itd.).\n"
+"Zastanów siê jak bardzo ufasz temu u¿ytkownikowi w kwestii sprawdzania\n"
+"to¿samo¶ci innych u¿ytkowników (czy sprawdzi on odciski kluczy pobrane\n"
+"z ró¿nych ¼róde³, dokumenty potwierdzaj±ce to¿samo¶æ, itd.).\n"
 
 #, c-format
 msgid "  %d = I trust marginally\n"
@@ -2629,33 +2543,33 @@ msgstr "  %d = mam ograniczone zaufanie\n"
 
 #, c-format
 msgid "  %d = I trust fully\n"
-msgstr "  %d = mam pełne zaufanie\n"
+msgstr "  %d = mam pe³ne zaufanie\n"
 
 msgid ""
 "Please enter the depth of this trust signature.\n"
 "A depth greater than 1 allows the key you are signing to make\n"
 "trust signatures on your behalf.\n"
 msgstr ""
-"Proszę wpisać poziom tego podpisu zaufania.\n"
-"Poziom wyższy niż 1 umożliwia używanie podpisywanego właśnie klucza\n"
-"do wykonywania zaufanych podpisów w twoim imieniu.\n"
+"Proszê wpisaæ poziom tego podpisu zaufania.\n"
+"Poziom wy¿szy ni¿ 1 umo¿liwia u¿ywanie podpisywanego w³a¶nie klucza\n"
+"do wykonywania zaufanych podpisów w twoim imieniu.\n"
 
 msgid "Please enter a domain to restrict this signature, or enter for none.\n"
-msgstr "Proszę wpisać domenę ograniczającą ten podpis lub Enter dla żadnej.\n"
+msgstr "Proszê wpisaæ domenê ograniczaj±c± ten podpis lub Enter dla ¿adnej.\n"
 
 #, c-format
 msgid "User ID \"%s\" is revoked."
-msgstr "Identyfikator użytkownika ,,%s'' został unieważniony."
+msgstr "Identyfikator u¿ytkownika ,,%s'' zosta³ uniewa¿niony."
 
 msgid "Are you sure you still want to sign it? (y/N) "
-msgstr "Czy na pewno chcesz podpisać? (t/N) "
+msgstr "Czy na pewno chcesz podpisaæ? (t/N) "
 
 msgid "  Unable to sign.\n"
-msgstr " Nie da się złożyć podpisu.\n"
+msgstr " Nie da siê z³o¿yæ podpisu.\n"
 
 #, c-format
 msgid "User ID \"%s\" is expired."
-msgstr "Identyfikator użytkownika ,,%s'' przekroczył swój termin ważności."
+msgstr "Identyfikator u¿ytkownika ,,%s'' przekroczy³ swój termin wa¿no¶ci."
 
 #, c-format
 msgid "User ID \"%s\" is not self-signed."
@@ -2663,10 +2577,10 @@ msgstr "Identyfikator ,,%s'' nie jest podpisany swoim kluczem."
 
 #, c-format
 msgid "User ID \"%s\" is signable.  "
-msgstr "Identyfikator użytkownika ,,%s'' jest podpisywalny. "
+msgstr "Identyfikator u¿ytkownika ,,%s'' jest podpisywalny. "
 
 msgid "Sign it? (y/N) "
-msgstr "Podpisać go? (t/N) "
+msgstr "Podpisaæ go? (t/N) "
 
 #, c-format
 msgid ""
@@ -2674,76 +2588,76 @@ msgid ""
 "is a PGP 2.x-style signature.\n"
 msgstr ""
 "Podpis klucza nim samym na ,,%s''\n"
-"jest podpisem złożonym przez PGP 2.x.\n"
+"jest podpisem z³o¿onym przez PGP 2.x.\n"
 
 msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) "
-msgstr "Czy chcesz zamienić go na podpis OpenPGP? (t/N) "
+msgstr "Czy chcesz zamieniæ go na podpis OpenPGP? (t/N) "
 
 #, c-format
 msgid ""
 "Your current signature on \"%s\"\n"
 "has expired.\n"
 msgstr ""
-"Twój podpis na ,,%s''\n"
-"przekroczył datę ważności.\n"
+"Twój podpis na ,,%s''\n"
+"przekroczy³ datê wa¿no¶ci.\n"
 
 msgid "Do you want to issue a new signature to replace the expired one? (y/N) "
-msgstr "Czy chcesz zastąpić przeterminowany podpis nowym? (t/N) "
+msgstr "Czy chcesz zast±piæ przeterminowany podpis nowym? (t/N) "
 
 #, c-format
 msgid ""
 "Your current signature on \"%s\"\n"
 "is a local signature.\n"
 msgstr ""
-"Twój podpis na ,,%s''\n"
+"Twój podpis na ,,%s''\n"
 "jest podpisem prywatnym (lokalnym).\n"
 
 msgid "Do you want to promote it to a full exportable signature? (y/N) "
 msgstr ""
-"Czy chcesz zamienić go na pełny, publiczny, eksportowalny podpis? (t/N) "
+"Czy chcesz zamieniæ go na pe³ny, publiczny, eksportowalny podpis? (t/N) "
 
 #, c-format
 msgid "\"%s\" was already locally signed by key %s\n"
-msgstr ",,%s'' jest już lokalnie podpisany kluczem %s\n"
+msgstr ",,%s'' jest ju¿ lokalnie podpisany kluczem %s\n"
 
 #, c-format
 msgid "\"%s\" was already signed by key %s\n"
-msgstr ",,%s'' jest już podpisany kluczem %s\n"
+msgstr ",,%s'' jest ju¿ podpisany kluczem %s\n"
 
 msgid "Do you want to sign it again anyway? (y/N) "
-msgstr "Czy na pewno chcesz to podpisać jeszcze raz? (t/N) "
+msgstr "Czy na pewno chcesz to podpisaæ jeszcze raz? (t/N) "
 
 #, c-format
 msgid "Nothing to sign with key %s\n"
 msgstr "Nie ma nic do podpisania kluczem %s\n"
 
 msgid "This key has expired!"
-msgstr "Data ważności tego klucza upłynęła!"
+msgstr "Data wa¿no¶ci tego klucza up³ynê³a!"
 
 #, c-format
 msgid "This key is due to expire on %s.\n"
-msgstr "Ważność tego klucza wygasa %s.\n"
+msgstr "Wa¿no¶æ tego klucza wygasa %s.\n"
 
 msgid "Do you want your signature to expire at the same time? (Y/n) "
 msgstr ""
-"Czy chcesz żeby ważność Twojego podpisu wygasała w tej samej chwili? (T/n) "
+"Czy chcesz ¿eby wa¿no¶æ Twojego podpisu wygasa³a w tej samej chwili? (T/n) "
 
 msgid ""
 "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
 "mode.\n"
 msgstr ""
-"W trybie --pgp2 nie można podpisywać kluczy PGP 2.x podpisami OpenPGP.\n"
+"W trybie --pgp2 nie mo¿na podpisywaæ kluczy PGP 2.x podpisami OpenPGP.\n"
 
 msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "To uczyni ten klucz nieużytecznym dla PGP 2.x.\n"
+msgstr "To uczyni ten klucz nieu¿ytecznym dla PGP 2.x.\n"
 
 msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
 msgstr ""
-"Jak dokładnie została przez Ciebie sprawdzona tożsamość tej osoby?\n"
-"Jeśli nie wiesz co odpowiedzieć, podaj ,,0''.\n"
+"Jak dok³adnie zosta³a przez Ciebie sprawdzona to¿samo¶æ tej osoby?\n"
+"Je¶li nie wiesz co odpowiedzieæ, podaj ,,0''.\n"
 
 #, c-format
 msgid "   (0) I will not answer.%s\n"
@@ -2751,149 +2665,149 @@ msgstr "   (0) Nie odpowiem na to pytanie. %s\n"
 
 #, c-format
 msgid "   (1) I have not checked at all.%s\n"
-msgstr "   (1) W ogóle nie.%s\n"
+msgstr "   (1) W ogóle nie.%s\n"
 
 #, c-format
 msgid "   (2) I have done casual checking.%s\n"
-msgstr "   (2) Pobieżnie.%s\n"
+msgstr "   (2) Pobie¿nie.%s\n"
 
 #, c-format
 msgid "   (3) I have done very careful checking.%s\n"
-msgstr "   (3) Bardzo dokładnie.%s\n"
+msgstr "   (3) Bardzo dok³adnie.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
-msgstr "Twój wybór (,,?'' podaje więcej informacji): "
+msgid "Your selection? (enter '?' for more information): "
+msgstr "Twój wybór (,,?'' podaje wiêcej informacji): "
 
 #, c-format
 msgid ""
 "Are you sure that you want to sign this key with your\n"
 "key \"%s\" (%s)\n"
 msgstr ""
-"Czy jesteś naprawdę pewien, że chcesz podpisać ten klucz\n"
+"Czy jeste¶ naprawdê pewien, ¿e chcesz podpisaæ ten klucz\n"
 "swoim kluczem ,,%s'' (%s)\n"
 
 msgid "This will be a self-signature.\n"
-msgstr "To będzie podpis klucza nim samym.\n"
+msgstr "To bêdzie podpis klucza nim samym.\n"
 
 msgid "WARNING: the signature will not be marked as non-exportable.\n"
 msgstr ""
-"OSTRZEŻENIE: podpis nie zostanie oznaczony jako prywatny "
+"OSTRZE¯ENIE: podpis nie zostanie oznaczony jako prywatny "
 "(nieeksportowalny).\n"
 
 msgid "WARNING: the signature will not be marked as non-revocable.\n"
 msgstr ""
-"OSTRZEŻENIE: podpis nie zostanie oznaczony jako nie podlegający "
-"unieważnieniu.\n"
+"OSTRZE¯ENIE: podpis nie zostanie oznaczony jako nie podlegaj±cy "
+"uniewa¿nieniu.\n"
 
 msgid "The signature will be marked as non-exportable.\n"
 msgstr "Podpis zostanie oznaczony jako prywatny (nieeksportowalny).\n"
 
 msgid "The signature will be marked as non-revocable.\n"
-msgstr "Podpis zostanie oznaczony jako nie podlegający unieważnieniu.\n"
+msgstr "Podpis zostanie oznaczony jako nie podlegaj±cy uniewa¿nieniu.\n"
 
 msgid "I have not checked this key at all.\n"
-msgstr "Tożsamość użytkownika nie została w ogóle sprawdzona.\n"
+msgstr "To¿samo¶æ u¿ytkownika nie zosta³a w ogóle sprawdzona.\n"
 
 msgid "I have checked this key casually.\n"
-msgstr "Tożsamość użytkownika została sprawdzona pobieżnie.\n"
+msgstr "To¿samo¶æ u¿ytkownika zosta³a sprawdzona pobie¿nie.\n"
 
 msgid "I have checked this key very carefully.\n"
-msgstr "Tożsamość użytkownika została dokładnie sprawdzona.\n"
+msgstr "To¿samo¶æ u¿ytkownika zosta³a dok³adnie sprawdzona.\n"
 
 msgid "Really sign? (y/N) "
-msgstr "Czy na pewno podpisać? (t/N) "
+msgstr "Czy na pewno podpisaæ? (t/N) "
 
 #, c-format
 msgid "signing failed: %s\n"
-msgstr "złożenie podpisu nie powiodło się: %s\n"
+msgstr "z³o¿enie podpisu nie powiod³o siê: %s\n"
 
 msgid "Key has only stub or on-card key items - no passphrase to change.\n"
 msgstr ""
-"Klucz ma tylko zaślepkę albo elementy na karcie - nie ma hasła do zmiany.\n"
+"Klucz ma tylko za¶lepkê albo elementy na karcie - nie ma has³a do zmiany.\n"
 
 msgid "This key is not protected.\n"
 msgstr "Ten klucz nie jest chroniony.\n"
 
 msgid "Secret parts of primary key are not available.\n"
-msgstr "Część tajna głównego klucza jest niedostępna.\n"
+msgstr "Czê¶æ tajna g³ównego klucza jest niedostêpna.\n"
 
 msgid "Secret parts of primary key are stored on-card.\n"
-msgstr "Część tajna głównego klucza jest zapisana na karcie.\n"
+msgstr "Czê¶æ tajna g³ównego klucza jest zapisana na karcie.\n"
 
 msgid "Key is protected.\n"
 msgstr "Klucz jest chroniony.\n"
 
 #, c-format
 msgid "Can't edit this key: %s\n"
-msgstr "Tego klucza nie można modyfikować: %s.\n"
+msgstr "Tego klucza nie mo¿na modyfikowaæ: %s.\n"
 
 msgid ""
 "Enter the new passphrase for this secret key.\n"
 "\n"
 msgstr ""
-"Wprowadź nowe długie, skomplikowane hasło dla tego klucza tajnego.\n"
+"Wprowad¼ nowe d³ugie, skomplikowane has³o dla tego klucza tajnego.\n"
 "\n"
 
 msgid "passphrase not correctly repeated; try again"
-msgstr "hasło nie zostało poprawnie powtórzone; jeszcze jedna próba"
+msgstr "has³o nie zosta³o poprawnie powtórzone; jeszcze jedna próba"
 
 msgid ""
 "You don't want a passphrase - this is probably a *bad* idea!\n"
 "\n"
 msgstr ""
-"Nie chcesz hasła - to *zły* pomysł!\n"
+"Nie chcesz has³a - to *z³y* pomys³!\n"
 "\n"
 
 msgid "Do you really want to do this? (y/N) "
-msgstr "Czy na pewno chcesz to zrobić? (t/N) "
+msgstr "Czy na pewno chcesz to zrobiæ? (t/N) "
 
 msgid "moving a key signature to the correct place\n"
-msgstr "przenoszę podpis klucza na właściwe miejsce\n"
+msgstr "przenoszê podpis klucza na w³a¶ciwe miejsce\n"
 
 msgid "save and quit"
-msgstr "zapis zmian i wyjście"
+msgstr "zapis zmian i wyjcie"
 
 msgid "show key fingerprint"
 msgstr "okazanie odcisku klucza"
 
 msgid "list key and user IDs"
-msgstr "lista kluczy i identyfikatorów użytkownika"
+msgstr "lista kluczy i identyfikatorów u¿ytkownika"
 
 msgid "select user ID N"
-msgstr "wybór identyfikatora użytkownika N"
+msgstr "wybór identyfikatora u¿ytkownika N"
 
 msgid "select subkey N"
-msgstr "wybór podklucza N"
+msgstr "wybór podklucza N"
 
 msgid "check signatures"
-msgstr "sprawdzenie podpisów"
+msgstr "sprawdzenie podpisów"
 
 msgid "sign selected user IDs [* see below for related commands]"
 msgstr ""
-"złożenie podpisu na wybranych identyfikatorach użytkownika [* poniżej "
-"powiązane polecenia]"
+"z³o¿enie podpisu na wybranych identyfikatorach u¿ytkownika [* poni¿ej "
+"powi±zane polecenia]"
 
 msgid "sign selected user IDs locally"
 msgstr ""
-"złożenie prywatnego (lokalnego) podpisu na wybranych identyfikatorach "
-"użytkownika"
+"z³o¿enie prywatnego (lokalnego) podpisu na wybranych identyfikatorach "
+"u¿ytkownika"
 
 msgid "sign selected user IDs with a trust signature"
-msgstr "podpisanie wybranych identyfikatorów użytkownika sygnaturą zaufania"
+msgstr "podpisanie wybranych identyfikatorów u¿ytkownika sygnatur± zaufania"
 
 msgid "sign selected user IDs with a non-revocable signature"
 msgstr ""
-"podpisanie wybranych identyfikatorów użytkownika sygnaturą nie podlegającą "
-"unieważnieniu"
+"podpisanie wybranych identyfikatorów u¿ytkownika sygnatur± nie podlegaj±c± "
+"uniewa¿nieniu"
 
 msgid "add a user ID"
-msgstr "dodanie nowego identyfikatora użytkownika do klucza"
+msgstr "dodanie nowego identyfikatora u¿ytkownika do klucza"
 
 msgid "add a photo ID"
-msgstr "dodanie zdjęcia użytkownika do klucza"
+msgstr "dodanie zdjêcia u¿ytkownika do klucza"
 
 msgid "delete selected user IDs"
-msgstr "usunięcie wybranych identyfikatorów użytkownika z klucza"
+msgstr "usuniêcie wybranych identyfikatorów u¿ytkownika z klucza"
 
 msgid "add a subkey"
 msgstr "dodanie podklucza"
@@ -2902,92 +2816,92 @@ msgid "add a key to a smartcard"
 msgstr "dodanie klucza do karty procesorowej"
 
 msgid "move a key to a smartcard"
-msgstr "przeniesienie klucza na kartę procesorową"
+msgstr "przeniesienie klucza na kartê procesorow±"
 
 msgid "move a backup key to a smartcard"
-msgstr "przeniesienie klucza zapasowego na kartę procesorową"
+msgstr "przeniesienie klucza zapasowego na kartê procesorow±"
 
 msgid "delete selected subkeys"
-msgstr "usunięcie wybranych podkluczy"
+msgstr "usuniêcie wybranych podkluczy"
 
 msgid "add a revocation key"
-msgstr "dodanie klucza unieważniającego"
+msgstr "dodanie klucza uniewa¿niaj±cego"
 
 msgid "delete signatures from the selected user IDs"
-msgstr "usunięcie podpisów z wybranych identyfikatorów użytkownika"
+msgstr "usuniêcie podpisów z wybranych identyfikatorów u¿ytkownika"
 
 msgid "change the expiration date for the key or selected subkeys"
-msgstr "zmiana daty wygaśnięcia dla klucza lub wybranych podkluczy"
+msgstr "zmiana daty wyga¶niêcia dla klucza lub wybranych podkluczy"
 
 msgid "flag the selected user ID as primary"
-msgstr "oznaczenie wybranego identyfikatora użytkownika jako głównego"
+msgstr "oznaczenie wybranego identyfikatora u¿ytkownika jako g³ównego"
 
 msgid "toggle between the secret and public key listings"
-msgstr "przełączenie pomiędzy listami kluczy tajnych i publicznych"
+msgstr "prze³±czenie pomiêdzy listami kluczy tajnych i publicznych"
 
 msgid "list preferences (expert)"
 msgstr "ustawienia (zaawansowane)"
 
 msgid "list preferences (verbose)"
-msgstr "rozbudowana lista ustawień"
+msgstr "rozbudowana lista ustawieñ"
 
 msgid "set preference list for the selected user IDs"
-msgstr "ustawienie listy preferencji dla wybranych identyfikatorów użytkownika"
+msgstr "ustawienie listy preferencji dla wybranych identyfikatorów u¿ytkownika"
 
 msgid "set the preferred keyserver URL for the selected user IDs"
 msgstr ""
-"ustawienie URL-a preferowanego serwera kluczy dla wybranych identyfikatorów "
-"użytkownika"
+"ustawienie URL-a preferowanego serwera kluczy dla wybranych identyfikatorów "
+"u¿ytkownika"
 
 msgid "set a notation for the selected user IDs"
-msgstr "ustawienie adnotacji dla wybranych identyfikatorów użytkownika"
+msgstr "ustawienie adnotacji dla wybranych identyfikatorów u¿ytkownika"
 
 msgid "change the passphrase"
-msgstr "zmiana hasła klucza"
+msgstr "zmiana has³a klucza"
 
 msgid "change the ownertrust"
-msgstr "zmiana zaufania właściciela"
+msgstr "zmiana zaufania w³a¶ciciela"
 
 msgid "revoke signatures on the selected user IDs"
-msgstr "unieważnienie podpisów na wybranych identyfikatorach użytkownika"
+msgstr "uniewa¿nienie podpisów na wybranych identyfikatorach u¿ytkownika"
 
 msgid "revoke selected user IDs"
-msgstr "unieważnienie wybranych identyfikatorów użytkownika"
+msgstr "uniewa¿nienie wybranych identyfikatorów u¿ytkownika"
 
 msgid "revoke key or selected subkeys"
-msgstr "unieważnienie klucza lub wybranych podkluczy"
+msgstr "uniewa¿nienie klucza lub wybranych podkluczy"
 
 msgid "enable key"
-msgstr "włączenie klucza do użycia"
+msgstr "w³±czenie klucza do u¿ycia"
 
 msgid "disable key"
-msgstr "wyłączenie klucza z użycia"
+msgstr "wy³±czenie klucza z u¿ycia"
 
 msgid "show selected photo IDs"
-msgstr "okazanie wybranych identyfikatorów - zdjęć"
+msgstr "okazanie wybranych identyfikatorów - zdjêæ"
 
 msgid "compact unusable user IDs and remove unusable signatures from key"
 msgstr ""
-"zagęszczanie bezużytecznych ID użytkowników i usuwanie bezużytecznych "
-"podpisów z kluczy"
+"zagêszczanie bezu¿ytecznych ID u¿ytkowników i usuwanie bezu¿ytecznych "
+"podpisów z kluczy"
 
 msgid "compact unusable user IDs and remove all signatures from key"
 msgstr ""
-"zagęszczanie bezużytecznych ID użytkowników i usuwanie wszystkich podpisów z "
+"zagêszczanie bezu¿ytecznych ID u¿ytkowników i usuwanie wszystkich podpisów z "
 "kluczy"
 
 #, c-format
 msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "błąd odczytu bloku klucza tajnego ,,%s'': %s\n"
+msgstr "b³±d odczytu bloku klucza tajnego ,,%s'': %s\n"
 
 msgid "Secret key is available.\n"
-msgstr "Dostępny jest klucz tajny.\n"
+msgstr "Dostêpny jest klucz tajny.\n"
 
 msgid "Need the secret key to do this.\n"
 msgstr "Do wykonania tej operacji potrzebny jest klucz tajny.\n"
 
 msgid "Please use the command \"toggle\" first.\n"
-msgstr "Najpierw trzeba użyć polecenia \"przeł\".\n"
+msgstr "Najpierw trzeba u¿yæ polecenia \"prze³\".\n"
 
 msgid ""
 "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -2995,120 +2909,122 @@ msgid ""
 "  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
-"* Polecenie `sign' można poprzedzić ,,l'' dla lokalnych sygnatur (lsign),\n"
+"* Polecenie `sign' mo¿na poprzedziæ ,,l'' dla lokalnych sygnatur (lsign),\n"
 "  ,,t'' dla sygnatur zaufania (tsign) albo ,,nr'' dla sygnatur nie\n"
-"  podlegających unieważnieniu (nrsign), albo dowolną ich kombinacją "
+"  podlegaj±cych uniewa¿nieniu (nrsign), albo dowoln± ich kombinacj± "
 "(ltsign,\n"
 "  tnrsign itd.).\n"
 
 msgid "Key is revoked."
-msgstr "Klucz unieważniony."
+msgstr "Klucz uniewa¿niony."
 
 msgid "Really sign all user IDs? (y/N) "
-msgstr "Czy na pewno podpisać wszystkie identyfikatory użytkownika? (t/N) "
+msgstr "Czy na pewno podpisaæ wszystkie identyfikatory u¿ytkownika? (t/N) "
 
 msgid "Hint: Select the user IDs to sign\n"
-msgstr "Podpowiedź: wybierz identyfikatory użytkownika do podpisania.\n"
+msgstr "Podpowied¼: wybierz identyfikatory u¿ytkownika do podpisania.\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Nieznany rodzaj podpisu ,,%s''\n"
 
 #, c-format
 msgid "This command is not allowed while in %s mode.\n"
-msgstr "To polecenie nie jest dostępne w trybie %s.\n"
+msgstr "To polecenie nie jest dostêpne w trybie %s.\n"
 
 msgid "You must select at least one user ID.\n"
-msgstr "Musisz wybrać co najmniej jeden identyfikator użytkownika.\n"
+msgstr "Musisz wybraæ co najmniej jeden identyfikator u¿ytkownika.\n"
 
 msgid "You can't delete the last user ID!\n"
-msgstr "Nie możesz usunąć ostatniego identyfikatora użytkownika!\n"
+msgstr "Nie mo¿esz usun±æ ostatniego identyfikatora u¿ytkownika!\n"
 
 msgid "Really remove all selected user IDs? (y/N) "
 msgstr ""
-"Czy na pewno usunąć wszystkie wybrane identyfikatory użytkownika? (t/N) "
+"Czy na pewno usun±æ wszystkie wybrane identyfikatory u¿ytkownika? (t/N) "
 
 msgid "Really remove this user ID? (y/N) "
-msgstr "Czy na pewno usunąć ten identyfikator użytkownika? (t/N) "
+msgstr "Czy na pewno usun±æ ten identyfikator u¿ytkownika? (t/N) "
 
 #. TRANSLATORS: Please take care: This is about
 #. moving the key and not about removing it.
 msgid "Really move the primary key? (y/N) "
-msgstr "Czy na pewno przenieść główny klucz (t/N) "
+msgstr "Czy na pewno przenie¶æ g³ówny klucz (t/N) "
 
 msgid "You must select exactly one key.\n"
-msgstr "Musisz wybrać dokładnie jeden klucz.\n"
+msgstr "Musisz wybraæ dok³adnie jeden klucz.\n"
 
 msgid "Command expects a filename argument\n"
-msgstr "Polecenie oczekuje argumentu będącego nazwą pliku\n"
+msgstr "Polecenie oczekuje argumentu bêd±cego nazw± pliku\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
-msgstr "Nie można otworzyć ,,%s'': %s\n"
+msgid "Can't open '%s': %s\n"
+msgstr "Nie mo¿na otworzyæ ,,%s'': %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
-msgstr "Błąd podczas odczytu klucza zapasowego z `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
+msgstr "B³±d podczas odczytu klucza zapasowego z `%s': %s\n"
 
 msgid "You must select at least one key.\n"
-msgstr "Musisz wybrać co najmniej jeden klucz.\n"
+msgstr "Musisz wybraæ co najmniej jeden klucz.\n"
 
 msgid "Do you really want to delete the selected keys? (y/N) "
-msgstr "Czy na pewno chcesz usunąć wybrane klucze? (t/N) "
+msgstr "Czy na pewno chcesz usun±æ wybrane klucze? (t/N) "
 
 msgid "Do you really want to delete this key? (y/N) "
-msgstr "Czy na pewno chcesz usunąć ten klucz? (t/N) "
+msgstr "Czy na pewno chcesz usun±æ ten klucz? (t/N) "
 
 msgid "Really revoke all selected user IDs? (y/N) "
 msgstr ""
-"Czy na pewno unieważnić wszystkie wybrane identyfikatory użytkownika? (t/N) "
+"Czy na pewno uniewa¿niæ wszystkie wybrane identyfikatory u¿ytkownika? (t/N) "
 
 msgid "Really revoke this user ID? (y/N) "
-msgstr "Czy na pewno unieważnić ten identyfikator użytkownika? (t/N) "
+msgstr "Czy na pewno uniewa¿niæ ten identyfikator u¿ytkownika? (t/N) "
 
 msgid "Do you really want to revoke the entire key? (y/N) "
-msgstr "Czy na pewno chcesz unieważnić cały klucz? (t/N) "
+msgstr "Czy na pewno chcesz uniewa¿niæ ca³y klucz? (t/N) "
 
 msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgstr "Czy na pewno chcesz unieważnić wybrane podklucze? (t/N) "
+msgstr "Czy na pewno chcesz uniewa¿niæ wybrane podklucze? (t/N) "
 
 msgid "Do you really want to revoke this subkey? (y/N) "
-msgstr "Czy na pewno chcesz unieważnić ten podklucz? (t/N) "
+msgstr "Czy na pewno chcesz uniewa¿niæ ten podklucz? (t/N) "
 
+#, fuzzy
 msgid "Owner trust may not be set while using a user provided trust database\n"
 msgstr ""
-"Zaufanie użytkownika nie może być ustawione podczas używania bazy zaufania\n"
-"dostarczonej przez użytkownika\n"
+"Zaufanie u¿ytkownika nie mo¿e byæ ustawione podczas u¿ywania bazy "
+"dostarczonej\n"
+"przez u¿ytkownika\n"
 
 msgid "Set preference list to:\n"
-msgstr "Ustawienie listy ustawień na:\n"
+msgstr "Ustawienie listy ustawieñ na:\n"
 
 msgid "Really update the preferences for the selected user IDs? (y/N) "
 msgstr ""
-"Czy na pewno uaktualnić ustawienia dla wybranych identyfikatorów? (t/N) "
+"Czy na pewno uaktualniæ ustawienia dla wybranych identyfikatorów? (t/N) "
 
 msgid "Really update the preferences? (y/N) "
-msgstr "Czy na pewno uaktualnić ustawienia? (t/N) "
+msgstr "Czy na pewno uaktualniæ ustawienia? (t/N) "
 
 msgid "Save changes? (y/N) "
-msgstr "Zapisać zmiany? (t/N) "
+msgstr "Zapisaæ zmiany? (t/N) "
 
 msgid "Quit without saving? (y/N) "
-msgstr "Wyjść bez zapisania zmian? (t/N) "
+msgstr "Wyj¶æ bez zapisania zmian? (t/N) "
 
 #, c-format
 msgid "update failed: %s\n"
-msgstr "zapis zmian nie powiódł się: %s\n"
+msgstr "zapis zmian nie powiód³ siê: %s\n"
 
 #, c-format
 msgid "update secret failed: %s\n"
-msgstr "zapis zmian na kluczu prywatnym nie powiódł się: %s\n"
+msgstr "zapis zmian na kluczu prywatnym nie powiód³ siê: %s\n"
 
 msgid "Key not changed so no update needed.\n"
-msgstr "Klucz nie został zmieniony więc zapis zmian nie jest konieczny.\n"
+msgstr "Klucz nie zosta³ zmieniony wiêc zapis zmian nie jest konieczny.\n"
 
 msgid "Digest: "
-msgstr "Skrót: "
+msgstr "Skrót: "
 
 msgid "Features: "
 msgstr "Ustawienia: "
@@ -3123,15 +3039,15 @@ msgid "Notations: "
 msgstr "Adnotacje: "
 
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
-msgstr "Klucze PGP 2.x nie zawierają opisu ustawień.\n"
+msgstr "Klucze PGP 2.x nie zawieraj± opisu ustawieñ.\n"
 
 #, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "Ten klucz został unieważniony %s przez klucz użytkownika %s %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
+msgstr "Ten klucz zosta³ uniewa¿niony %s przez klucz %s u¿ytkownika %s\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
-msgstr "Klucz może zostać unieważniony przez klucz %s użytkownika %s"
+msgstr "Klucz mo¿e zostaæ uniewa¿niony przez klucz %s u¿ytkownika %s"
 
 msgid "(sensitive)"
 msgstr "(poufne)"
@@ -3142,11 +3058,11 @@ msgstr "utworzono: %s"
 
 #, c-format
 msgid "revoked: %s"
-msgstr "unieważniono: %s"
+msgstr "uniewa¿niono: %s"
 
 #, c-format
 msgid "expired: %s"
-msgstr "wygasł: %s"
+msgstr "wygas³: %s"
 
 #, c-format
 msgid "expires: %s"
@@ -3154,7 +3070,7 @@ msgstr "wygasa: %s"
 
 #, c-format
 msgid "usage: %s"
-msgstr "użycie: %s"
+msgstr "u¿ycie: %s"
 
 #, c-format
 msgid "trust: %s"
@@ -3162,10 +3078,10 @@ msgstr "zaufanie: %s"
 
 #, c-format
 msgid "validity: %s"
-msgstr "poprawność: %s"
+msgstr "poprawno¶æ: %s"
 
 msgid "This key has been disabled"
-msgstr "Ten klucz został wyłączony z użytku"
+msgstr "Ten klucz zosta³ wy³±czony z u¿ytku"
 
 msgid "card-no: "
 msgstr "nr-karty: "
@@ -3174,179 +3090,171 @@ msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
 msgstr ""
-"Pokazana wartość wiarygodności klucza może być niepoprawna,\n"
-"dopóki program nie zostanie uruchomiony ponownie.\n"
+"Pokazana warto¶æ wiarygodno¶ci klucza mo¿e byæ niepoprawna,\n"
+"dopóki program nie zostanie uruchomiony ponownie.\n"
 
 msgid "revoked"
-msgstr "unieważniony"
+msgstr "uniewa¿niony"
 
 msgid "expired"
-msgstr "wygasł"
+msgstr "wygas³"
 
 msgid ""
 "WARNING: no user ID has been marked as primary.  This command may\n"
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
-"OSTRZEŻENIE: żaden identyfikator użytkownika nie został oznaczony explicite\n"
-"             jako główny. Wykonanie tego polecenie może więc spowodować\n"
-"             wyświetlanie innego identyfikatora jako domyślnego głównego.\n"
-
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Nie można zmienić daty ważności klucza w wersji 3.\n"
+"OSTRZE¯ENIE: ¿aden identyfikator u¿ytkownika nie zosta³ oznaczony explicite\n"
+"             jako g³ówny. Wykonanie tego polecenie mo¿e wiêc spowodowaæ\n"
+"             wy¶wietlanie innego identyfikatora jako domy¶lnego g³ównego.\n"
 
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
 "         of PGP to reject this key.\n"
 msgstr ""
-"OSTRZEŻENIE: To jest klucz PGP wersji 2. Dodanie zdjęcia spowoduje, że\n"
-"             niektóre wersje przestaną go rozumieć.\n"
+"OSTRZE¯ENIE: To jest klucz PGP wersji 2. Dodanie zdjêcia spowoduje, ¿e\n"
+"             niektóre wersje przestan± go rozumieæ.\n"
 
 msgid "Are you sure you still want to add it? (y/N) "
-msgstr "Czy dalej chcesz je dodać? (t/N) "
+msgstr "Czy dalej chcesz je dodaæ? (t/N) "
 
 msgid "You may not add a photo ID to a PGP2-style key.\n"
-msgstr "Do klucza dla PGP 2.x nie można dodać zdjęcia.\n"
+msgstr "Do klucza dla PGP 2.x nie mo¿na dodaæ zdjêcia.\n"
 
 msgid "Delete this good signature? (y/N/q)"
-msgstr "Usunąć ten poprawny podpis? (t/N/w) "
+msgstr "Usun±æ ten poprawny podpis? (t/N/w) "
 
 msgid "Delete this invalid signature? (y/N/q)"
-msgstr "Usunąć ten niepoprawny podpis? (t/N/w) "
+msgstr "Usun±æ ten niepoprawny podpis? (t/N/w) "
 
 msgid "Delete this unknown signature? (y/N/q)"
-msgstr "Usunąć ten nieznany podpis? (t/N/w) "
+msgstr "Usun±æ ten nieznany podpis? (t/N/w) "
 
 msgid "Really delete this self-signature? (y/N)"
-msgstr "Na pewno usunąć ten podpis klucza nim samym? (t/N) "
+msgstr "Na pewno usun±æ ten podpis klucza nim samym? (t/N) "
 
 #, c-format
 msgid "Deleted %d signature.\n"
-msgstr "%d podpis usunięty.\n"
+msgstr "%d podpis usuniêty.\n"
 
 #, c-format
 msgid "Deleted %d signatures.\n"
-msgstr "%d podpisów usuniętych.\n"
+msgstr "%d podpisów usuniêtych.\n"
 
 msgid "Nothing deleted.\n"
-msgstr "Nic nie zostało usunięte.\n"
+msgstr "Nic nie zosta³o usuniête.\n"
 
 msgid "invalid"
 msgstr "niepoprawny"
 
 #, c-format
 msgid "User ID \"%s\" compacted: %s\n"
-msgstr "Identyfikator użytkownika ,,%s'' upakowany: %s\n"
+msgstr "Identyfikator u¿ytkownika ,,%s'' upakowany: %s\n"
 
 #, c-format
 msgid "User ID \"%s\": %d signature removed\n"
-msgstr "Identyfikator użytkownika ,,%s'': %d podpis wyczyszczony\n"
+msgstr "Identyfikator u¿ytkownika ,,%s'': %d podpis wyczyszczony\n"
 
 #, c-format
 msgid "User ID \"%s\": %d signatures removed\n"
-msgstr "Identyfikator użytkownika ,,%s'': %d podpisów wyczyszczonych\n"
+msgstr "Identyfikator u¿ytkownika ,,%s'': %d podpisów wyczyszczonych\n"
 
 #, c-format
 msgid "User ID \"%s\": already minimized\n"
-msgstr "Identyfikator użytkownika ,,%s'': już zmniejszony.\n"
+msgstr "Identyfikator u¿ytkownika ,,%s'': ju¿ zmniejszony.\n"
 
 #, c-format
 msgid "User ID \"%s\": already clean\n"
-msgstr "Identyfikator użytkownika ,,%s'': już czysty.\n"
+msgstr "Identyfikator u¿ytkownika ,,%s'': ju¿ czysty.\n"
 
 msgid ""
 "WARNING: This is a PGP 2.x-style key.  Adding a designated revoker may "
 "cause\n"
 "         some versions of PGP to reject this key.\n"
 msgstr ""
-"OSTRZEŻENIE: To jest klucz PGP wersji 2.x. Wyznaczenie mu klucza\n"
-"             unieważniającego spowoduje, że niektóre wersje PGP przestaną\n"
-"             go rozumieć.\n"
+"OSTRZE¯ENIE: To jest klucz PGP wersji 2.x. Wyznaczenie mu klucza\n"
+"             uniewa¿niaj±cego spowoduje, ¿e niektóre wersje PGP przestan±\n"
+"             go rozumieæ.\n"
 
 msgid "You may not add a designated revoker to a PGP 2.x-style key.\n"
-msgstr "Do klucza dla PGP 2.x nie można wyznaczyć klucza unieważniającego.\n"
+msgstr "Do klucza dla PGP 2.x nie mo¿na wyznaczyæ klucza uniewa¿niaj±cego.\n"
 
 msgid "Enter the user ID of the designated revoker: "
-msgstr "Podaj identyfikator klucza unieważniającego: "
+msgstr "Podaj identyfikator klucza uniewa¿niaj±cego: "
 
 msgid "cannot appoint a PGP 2.x style key as a designated revoker\n"
-msgstr "klucza PGP 2.x nie można wyznaczyć jako unieważniającego\n"
+msgstr "klucza PGP 2.x nie mo¿na wyznaczyæ jako uniewa¿niaj±cego\n"
 
 msgid "you cannot appoint a key as its own designated revoker\n"
-msgstr "nie można wyznaczyć klucza do unieważniania jego samego\n"
+msgstr "nie mo¿na wyznaczyæ klucza do uniewa¿niania jego samego\n"
 
 msgid "this key has already been designated as a revoker\n"
-msgstr "ten klucz został już uznany kluczem unieważniającym\n"
+msgstr "ten klucz zosta³ ju¿ uznany kluczem uniewa¿niaj±cym\n"
 
 msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n"
 msgstr ""
-"OSTRZEŻENIE: nie można cofnąć wyznaczenia klucza jako unieważniającego!\n"
+"OSTRZE¯ENIE: nie mo¿na cofn±æ wyznaczenia klucza jako uniewa¿niaj±cego!\n"
 
 msgid ""
 "Are you sure you want to appoint this key as a designated revoker? (y/N) "
-msgstr "Czy na pewno chcesz wyznaczyć ten klucz jako unieważniający? (t/N) "
+msgstr "Czy na pewno chcesz wyznaczyæ ten klucz jako uniewa¿niaj±cy? (t/N) "
 
 msgid "Please remove selections from the secret keys.\n"
-msgstr "Proszę usunąć znacznik wyboru z kluczy prywatnych.\n"
+msgstr "Proszê usun±æ znacznik wyboru z kluczy prywatnych.\n"
 
 msgid "Please select at most one subkey.\n"
-msgstr "Proszę wybrać najwyżej jeden podklucz.\n"
+msgstr "Proszê wybraæ najwy¿ej jeden podklucz.\n"
 
 msgid "Changing expiration time for a subkey.\n"
-msgstr "Zmiana daty ważności podklucza.\n"
+msgstr "Zmiana daty wa¿no¶ci podklucza.\n"
 
 msgid "Changing expiration time for the primary key.\n"
-msgstr "Zmiana daty ważności głównego klucza.\n"
+msgstr "Zmiana daty wa¿no¶ci g³ównego klucza.\n"
 
 msgid "You can't change the expiration date of a v3 key\n"
-msgstr "Nie można zmienić daty ważności klucza w wersji 3.\n"
+msgstr "Nie mo¿na zmieniæ daty wa¿no¶ci klucza w wersji 3.\n"
 
 msgid "No corresponding signature in secret ring\n"
-msgstr "Brak odpowiadającego podpisu w zbiorze kluczy prywatnych\n"
+msgstr "Brak odpowiadaj±cego podpisu w zbiorze kluczy prywatnych\n"
 
 #, c-format
 msgid "signing subkey %s is already cross-certified\n"
-msgstr "podklucz podpisujący %s jest już skrośnie podpisany\n"
+msgstr "podklucz podpisuj±cy %s jest ju¿ skro¶nie podpisany\n"
 
 #, c-format
 msgid "subkey %s does not sign and so does not need to be cross-certified\n"
 msgstr ""
-"podklucz %s nie jest podpisujący, więc nie musi być skrośnie podpisany\n"
+"podklucz %s nie jest podpisuj±cy, wiêc nie musi byæ skro¶nie podpisany\n"
 
 msgid "Please select exactly one user ID.\n"
-msgstr "Proszę wybrać dokładnie jeden identyfikator użytkownika.\n"
+msgstr "Proszê wybraæ dok³adnie jeden identyfikator u¿ytkownika.\n"
 
 #, c-format
 msgid "skipping v3 self-signature on user ID \"%s\"\n"
-msgstr "podpis w wersji 3 na identyfikatorze ,,%s'' zostaje pominięty\n"
+msgstr "podpis w wersji 3 na identyfikatorze ,,%s'' zostaje pominiêty\n"
 
 msgid "Enter your preferred keyserver URL: "
 msgstr "Podaj preferowany URL serwera kluczy: "
 
 msgid "Are you sure you want to replace it? (y/N) "
-msgstr "Czy na pewno chcesz go zastąpić? (t/N) "
+msgstr "Czy na pewno chcesz go zast±piæ? (t/N) "
 
 msgid "Are you sure you want to delete it? (y/N) "
-msgstr "Czy na pewno chcesz go usunąć? (t/N) "
+msgstr "Czy na pewno chcesz go usun±æ? (t/N) "
 
 msgid "Enter the notation: "
 msgstr "Adnotacje: "
 
 msgid "Proceed? (y/N) "
-msgstr "Kontynuować? (t/N) "
+msgstr "Kontynuowaæ? (t/N) "
 
 #, c-format
 msgid "No user ID with index %d\n"
-msgstr "Brak identyfikatora użytkownika o numerze %d.\n"
+msgstr "Brak identyfikatora u¿ytkownika o numerze %d.\n"
 
 #, c-format
 msgid "No user ID with hash %s\n"
-msgstr "Brak identyfikatora użytkownika o skrócie %s\n"
+msgstr "Brak identyfikatora u¿ytkownika o skrócie %s\n"
 
 #, c-format
 msgid "No subkey with index %d\n"
@@ -3354,7 +3262,7 @@ msgstr "Brak podklucza o numerze %d.\n"
 
 #, c-format
 msgid "user ID: \"%s\"\n"
-msgstr "identyfikator użytkownika: ,,%s''\n"
+msgstr "identyfikator u¿ytkownika: ,,%s''\n"
 
 #, c-format
 msgid "signed by your key %s on %s%s%s\n"
@@ -3365,100 +3273,100 @@ msgstr " (podpis nieeksportowalny) "
 
 #, c-format
 msgid "This signature expired on %s.\n"
-msgstr "Ważność tego klucza wygasła %s.\n"
+msgstr "Wa¿no¶æ tego klucza wygas³a %s.\n"
 
 msgid "Are you sure you still want to revoke it? (y/N) "
-msgstr "Czy dalej chcesz go unieważnić? (t/N) "
+msgstr "Czy dalej chcesz go uniewa¿niæ? (t/N) "
 
 msgid "Create a revocation certificate for this signature? (y/N) "
-msgstr "Stworzyć certyfikat unieważnienia tego podpisu? (t/N) "
+msgstr "Stworzyæ certyfikat uniewa¿nienia tego podpisu? (t/N) "
 
 msgid "Not signed by you.\n"
-msgstr "Nie podpisane przez ciebie.\n"
+msgstr ""
 
 #, c-format
 msgid "You have signed these user IDs on key %s:\n"
-msgstr "Te identyfikatory na kluczu %s są podpisane przez Ciebie:\n"
+msgstr "Te identyfikatory na kluczu %s s± podpisane przez Ciebie:\n"
 
 msgid " (non-revocable)"
-msgstr " (podpis nieunieważnialny) "
+msgstr " (podpis nieuniewa¿nialny) "
 
 #, c-format
 msgid "revoked by your key %s on %s\n"
-msgstr "unieważniony przez twój klucz %s w %s\n"
+msgstr "uniewa¿niony przez twój klucz %s w %s\n"
 
 msgid "You are about to revoke these signatures:\n"
-msgstr "Czy na pewno chcesz unieważnić te podpisy:\n"
+msgstr "Czy na pewno chcesz uniewa¿niæ te podpisy:\n"
 
 msgid "Really create the revocation certificates? (y/N) "
-msgstr "Na pewno utworzyć certyfikaty unieważnienia ? (t/N) "
+msgstr "Na pewno utworzyæ certyfikaty uniewa¿nienia ? (t/N) "
 
 msgid "no secret key\n"
 msgstr "brak klucza tajnego\n"
 
 #, c-format
 msgid "user ID \"%s\" is already revoked\n"
-msgstr "identyfikator użytkownika ,,%s'' został już unieważniony\n"
+msgstr "identyfikator u¿ytkownika ,,%s'' zosta³ ju¿ uniewa¿niony\n"
 
 #, c-format
 msgid "WARNING: a user ID signature is dated %d seconds in the future\n"
 msgstr ""
-"OSTRZEŻENIE: identyfikator użytkownika podpisany za %d sekund (w "
-"przyszłości)\n"
+"OSTRZE¯ENIE: identyfikator u¿ytkownika podpisany za %d sekund (w "
+"przysz³o¶ci)\n"
 
 #, c-format
 msgid "Key %s is already revoked.\n"
-msgstr "Klucz %s jest już unieważniony.\n"
+msgstr "Klucz %s jest ju¿ uniewa¿niony.\n"
 
 #, c-format
 msgid "Subkey %s is already revoked.\n"
-msgstr "Podklucz %s jest już unieważniony.\n"
+msgstr "Podklucz %s jest ju¿ uniewa¿niony.\n"
 
 #, c-format
 msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr ""
-"Wyświetlanie zdjęcia w formacie %s o rozmiarze %ld bajtów dla klucza %s (id "
-"%d).\n"
+"Wy¶wietlanie zdjêcia w formacie %s o rozmiarze %ld bajtów dla klucza %s (id %"
+"d).\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
-msgstr "ustawienie ,,%s'' powtarza się\n"
+msgid "preference '%s' duplicated\n"
+msgstr "ustawienie ,,%s'' powtarza siê\n"
 
 msgid "too many cipher preferences\n"
-msgstr "zbyt wiele ustawień szyfru\n"
+msgstr "zbyt wiele ustawieñ szyfru\n"
 
 msgid "too many digest preferences\n"
-msgstr "zbyt wiele ustawień funkcji skrótu\n"
+msgstr "zbyt wiele ustawieñ funkcji skrótu\n"
 
 msgid "too many compression preferences\n"
-msgstr "zbyt wiele ustawień kompresji\n"
+msgstr "zbyt wiele ustawieñ kompresji\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
-msgstr "niewłaściwy element `%s' w tekście ustawień\n"
+msgid "invalid item '%s' in preference string\n"
+msgstr "niew³a¶ciwy element `%s' w tek¶cie ustawieñ\n"
 
 msgid "writing direct signature\n"
-msgstr "zapis podpisu bezpośredniego\n"
+msgstr "zapis podpisu bezporedniego\n"
 
 msgid "writing self signature\n"
 msgstr "zapis podpisu klucza nim samym\n"
 
 msgid "writing key binding signature\n"
-msgstr "zapis podpisu wiążącego klucz\n"
+msgstr "zapis podpisu wi±¿±cego klucz\n"
 
 #, c-format
 msgid "keysize invalid; using %u bits\n"
-msgstr "niewłaściwa długość klucza; wykorzystano %u bitów\n"
+msgstr "niew³a¶ciwa d³ugo¶æ klucza; wykorzystano %u bitów\n"
 
 #, c-format
 msgid "keysize rounded up to %u bits\n"
-msgstr "rozmiar klucza zaokrąglony w górę do %u bitów\n"
+msgstr "rozmiar klucza zaokr±glony w górê do %u bitów\n"
 
 msgid ""
 "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n"
 msgstr ""
-"OSTRZEŻENIE: niektóre programy OpenPGP nie potrafią obsłużyć klucza RSA o "
-"tej długości skrótu\n"
+"OSTRZE¯ENIE: niektóre programy OpenPGP nie potrafi± obs³u¿yæ klucza RSA o "
+"tej d³ugo¶ci skrótu\n"
 
 msgid "Sign"
 msgstr "Podpisywanie"
@@ -3487,37 +3395,37 @@ msgstr "PpSsUuZz"
 
 #, c-format
 msgid "Possible actions for a %s key: "
-msgstr "Możliwe akcje dla klucza %s: "
+msgstr "Mo¿liwe akcje dla klucza %s: "
 
 msgid "Current allowed actions: "
 msgstr "Aktualnie dopuszczalne akcje: "
 
 #, c-format
 msgid "   (%c) Toggle the sign capability\n"
-msgstr "   (%c) Przełączenie możliwości podpisywania\n"
+msgstr "   (%c) Prze³±czenie mo¿liwo¶ci podpisywania\n"
 
 #, c-format
 msgid "   (%c) Toggle the encrypt capability\n"
-msgstr "   (%c) Przełączenie możliwości szyfrowania\n"
+msgstr "   (%c) Prze³±czenie mo¿liwo¶ci szyfrowania\n"
 
 #, c-format
 msgid "   (%c) Toggle the authenticate capability\n"
-msgstr "   (%c) Przełączenie możliwości uwierzytelniania\n"
+msgstr "   (%c) Prze³±czenie mo¿liwo¶ci uwierzytelniania\n"
 
 #, c-format
 msgid "   (%c) Finished\n"
-msgstr "   (%c) Zakończenie\n"
+msgstr "   (%c) Zakoñczenie\n"
 
 msgid "Please select what kind of key you want:\n"
-msgstr "Proszę wybrać rodzaj klucza:\n"
+msgstr "Proszê wybraæ rodzaj klucza:\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA and RSA (default)\n"
-msgstr "   (%d) RSA i RSA (domyślne)\n"
+msgstr "   (%d) Para kluczy dla algorytmów DSA i Elgamala (domy¶lne)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) DSA and Elgamal\n"
-msgstr "   (%d) DSA i Elgamala\n"
+msgstr "   (%d) Para kluczy dla algorytmów DSA i Elgamala (domy¶lne)\n"
 
 #, c-format
 msgid "   (%d) DSA (sign only)\n"
@@ -3529,7 +3437,7 @@ msgstr "   (%d) RSA (tylko do podpisywania)\n"
 
 #, c-format
 msgid "   (%d) Elgamal (encrypt only)\n"
-msgstr "   (%d) Elgamala (tylko do szyfrowania)\n"
+msgstr "   (%d) Klucz dla algorytmu Elgamala (tylko do szyfrowania)\n"
 
 #, c-format
 msgid "   (%d) RSA (encrypt only)\n"
@@ -3537,27 +3445,27 @@ msgstr "   (%d) RSA (tylko do szyfrowania)\n"
 
 #, c-format
 msgid "   (%d) DSA (set your own capabilities)\n"
-msgstr "   (%d) DSA (możliwości do ustawienia)\n"
+msgstr "   (%d) DSA (mo¿liwo¶ci do ustawienia)\n"
 
 #, c-format
 msgid "   (%d) RSA (set your own capabilities)\n"
-msgstr "   (%d) RSA (możliwości do ustawienia)\n"
+msgstr "   (%d) RSA (mo¿liwo¶ci do ustawienia)\n"
 
 #, c-format
 msgid "%s keys may be between %u and %u bits long.\n"
-msgstr "Klucze %s będą miały od %u do %u bitów długości.\n"
+msgstr "Klucze %s bêd± mia³y od %u do %u bitów d³ugo¶ci.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the subkey? (%u) "
-msgstr "Jakiej długości podklucz wygenerować? (%u) "
+msgstr "Jakiej d³ugo¶ci klucz wygenerowaæ? (%u) "
 
 #, c-format
 msgid "What keysize do you want? (%u) "
-msgstr "Jakiej długości klucz wygenerować? (%u) "
+msgstr "Jakiej d³ugo¶ci klucz wygenerowaæ? (%u) "
 
 #, c-format
 msgid "Requested keysize is %u bits\n"
-msgstr "Żądana długość klucza to %u bitów.\n"
+msgstr "¯±dana d³ugo¶æ klucza to %u bitów.\n"
 
 msgid ""
 "Please specify how long the key should be valid.\n"
@@ -3567,12 +3475,12 @@ msgid ""
 "      <n>m = key expires in n months\n"
 "      <n>y = key expires in n years\n"
 msgstr ""
-"Okres ważności klucza.\n"
-"         0 = klucz nie ma określonego terminu ważności\n"
-"      <n>  = termin ważności klucza upływa za n dni\n"
-"      <n>w = termin ważności klucza upływa za n tygodni\n"
-"      <n>m = termin ważności klucza upływa za n miesięcy\n"
-"      <n>y = termin ważności klucza upływa za n lat\n"
+"Okres wa¿no¶ci klucza.\n"
+"         0 = klucz nie ma okre¶lonego terminu wa¿no¶ci\n"
+"      <n>  = termin wa¿no¶ci klucza up³ywa za n dni\n"
+"      <n>w = termin wa¿no¶ci klucza up³ywa za n tygodni\n"
+"      <n>m = termin wa¿no¶ci klucza up³ywa za n miesiêcy\n"
+"      <n>y = termin wa¿no¶ci klucza up³ywa za n lat\n"
 
 msgid ""
 "Please specify how long the signature should be valid.\n"
@@ -3582,55 +3490,52 @@ msgid ""
 "      <n>m = signature expires in n months\n"
 "      <n>y = signature expires in n years\n"
 msgstr ""
-"Okres ważności podpisu.\n"
-"         0 = klucz nie ma określonego terminu ważności\n"
-"      <n>  = termin ważności podpisu upływa za n dni\n"
-"      <n>w = termin ważności podpisu upływa za n tygodni\n"
-"      <n>m = termin ważności podpisu upływa za n miesięcy\n"
-"      <n>y = termin ważności podpisu upływa za n lat\n"
+"Okres wa¿no¶ci podpisu.\n"
+"         0 = klucz nie ma okre¶lonego terminu wa¿no¶ci\n"
+"      <n>  = termin wa¿no¶ci podpisu up³ywa za n dni\n"
+"      <n>w = termin wa¿no¶ci podpisu up³ywa za n tygodni\n"
+"      <n>m = termin wa¿no¶ci podpisu up³ywa za n miesiêcy\n"
+"      <n>y = termin wa¿no¶ci podpisu up³ywa za n lat\n"
 
 msgid "Key is valid for? (0) "
-msgstr "Okres ważności klucza? (0) "
+msgstr "Okres wa¿no¶ci klucza? (0) "
 
 #, c-format
 msgid "Signature is valid for? (%s) "
-msgstr "Okres ważności podpisu? (%s) "
+msgstr "Okres wa¿no¶ci podpisu? (%s) "
 
 msgid "invalid value\n"
-msgstr "niepoprawna wartość\n"
+msgstr "niepoprawna warto¶æ\n"
 
 msgid "Key does not expire at all\n"
-msgstr "Klucz nie wygaśnie w ogóle\n"
+msgstr "Klucz nie wyga¶nie w ogóle\n"
 
 msgid "Signature does not expire at all\n"
-msgstr "Podpis nie wygaśnie w ogóle\n"
+msgstr "Podpis nie wyga¶nie w ogóle\n"
 
 #, c-format
 msgid "Key expires at %s\n"
-msgstr "Klucz traci ważność %s\n"
+msgstr "Klucz traci wa¿no¶æ %s\n"
 
 #, c-format
 msgid "Signature expires at %s\n"
-msgstr "Ważność podpisu wygasa %s\n"
+msgstr "Wa¿no¶æ podpisu wygasa %s\n"
 
 msgid ""
 "Your system can't display dates beyond 2038.\n"
 "However, it will be correctly handled up to 2106.\n"
 msgstr ""
-"Twój system nie potrafi pokazać daty po roku 2038.\n"
-"Niemniej daty do roku 2106 będą poprawnie obsługiwane.\n"
+"Twój system nie potrafi pokazaæ daty po roku 2038.\n"
+"Niemniej daty do roku 2106 bêd± poprawnie obs³ugiwane.\n"
 
 msgid "Is this correct? (y/N) "
-msgstr "Czy wszystko się zgadza (t/N)? "
+msgstr "Czy wszystko siê zgadza (t/N)? "
 
 msgid ""
 "\n"
 "GnuPG needs to construct a user ID to identify your key.\n"
 "\n"
 msgstr ""
-"\n"
-"GnuPG musi utworzyć identyfikator użytkownika do identyfikacji klucza.\n"
-"\n"
 
 #. TRANSLATORS: This string is in general not anymore used
 #. but you should keep your existing translation.  In case
@@ -3645,23 +3550,23 @@ msgid ""
 "\n"
 msgstr ""
 "\n"
-"Musisz podać identyfikator użytkownika aby można było rozpoznać twój klucz;\n"
-"program złoży go z twojego imienia i nazwiska, komentarza i adresu poczty\n"
-"elektronicznej. Będzie on miał, na przykład, taką postać:\n"
-"    \"Tadeusz Żeleński (Boy) <tzb@ziemianska.pl>\"\n"
+"Musisz podaæ identyfikator u¿ytkownika aby mo¿na by³o rozpoznaæ twój klucz;\n"
+"program z³o¿y go z twojego imienia i nazwiska, komentarza i adresu poczty\n"
+"elektronicznej. Bêdzie on mia³, na przyk³ad, tak± postaæ:\n"
+"    \"Tadeusz ¯eleñski (Boy) <tzb@ziemianska.pl>\"\n"
 "\n"
 
 msgid "Real name: "
-msgstr "Imię i nazwisko: "
+msgstr "Imiê i nazwisko: "
 
 msgid "Invalid character in name\n"
-msgstr "Niewłaściwy znak w imieniu lub nazwisku\n"
+msgstr "Niew³a¶ciwy znak w imieniu lub nazwisku\n"
 
 msgid "Name may not start with a digit\n"
-msgstr "Imię lub nazwisko nie może zaczynać się od cyfry\n"
+msgstr "Imiê lub nazwisko nie mo¿e zaczynaæ siê od cyfry\n"
 
 msgid "Name must be at least 5 characters long\n"
-msgstr "Imię i nazwisko muszą mieć co najmniej 5 znaków długości.\n"
+msgstr "Imiê i nazwisko musz± mieæ co najmniej 5 znaków d³ugo¶ci.\n"
 
 msgid "Email address: "
 msgstr "Adres poczty elektronicznej: "
@@ -3673,11 +3578,11 @@ msgid "Comment: "
 msgstr "Komentarz: "
 
 msgid "Invalid character in comment\n"
-msgstr "Niewłaściwy znak w komentarzu\n"
+msgstr "Niew³a¶ciwy znak w komentarzu\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
-msgstr "Używasz zestawu znaków %s.\n"
+msgid "You are using the '%s' character set.\n"
+msgstr "U¿ywasz zestawu znaków %s.\n"
 
 #, c-format
 msgid ""
@@ -3685,17 +3590,17 @@ msgid ""
 "    \"%s\"\n"
 "\n"
 msgstr ""
-"Twój identyfikator użytkownika będzie wyglądał tak:\n"
+"Twój identyfikator u¿ytkownika bêdzie wygl±da³ tak:\n"
 "    \"%s\"\n"
 "\n"
 
 msgid "Please don't put the email address into the real name or the comment\n"
 msgstr ""
-"Nie należy umieszczać adresu poczty elektronicznej w polu nazwiska czy\n"
+"Nie nale¿y umieszczaæ adresu poczty elektronicznej w polu nazwiska czy\n"
 "komentarza.\n"
 
 msgid "Such a user ID already exists on this key!\n"
-msgstr "Taki identyfikator użytkownika już istnieje na tym kluczu!\n"
+msgstr ""
 
 #. TRANSLATORS: These are the allowed answers in
 #. lower and uppercase.  Below you will find the matching
@@ -3712,29 +3617,29 @@ msgid "NnCcEeOoQq"
 msgstr "IiKkEeDdWw"
 
 msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
-msgstr "Zmienić (I)mię/nazwisko, (K)omentarz, adres (E)mail, czy (W)yjść? "
+msgstr "Zmieniæ (I)miê/nazwisko, (K)omentarz, adres (E)mail, czy (W)yj¶æ? "
 
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
 msgstr ""
-"Zmienić (I)mię/nazwisko, (K)omentarz, adres (E)mail, przejść (D)alej,\n"
-"czy (W)yjść z programu? "
+"Zmieniæ (I)miê/nazwisko, (K)omentarz, adres (E)mail, przej¶æ (D)alej,\n"
+"czy (W)yj¶æ z programu? "
 
 msgid "Please correct the error first\n"
-msgstr "Najpierw trzeba poprawić ten błąd\n"
+msgstr "Najpierw trzeba poprawiæ ten b³±d\n"
 
 msgid ""
 "You need a Passphrase to protect your secret key.\n"
 "\n"
 msgstr ""
-"Musisz podać długie, skomplikowane hasło aby ochronić swój klucz tajny.\n"
+"Musisz podaæ d³ugie, skomplikowane has³o aby ochroniæ swój klucz tajny.\n"
 "\n"
 
+#, fuzzy
 msgid ""
 "Please enter a passphrase to protect the off-card backup of the new "
 "encryption key."
 msgstr ""
-"Proszę wprowadzić hasło do zabezpieczenia kopii zapasowej poza kartą nowego "
-"klucza szyfrującego."
+"Proszê wprowadziæ has³o do zabezpieczenia wa¿nego obiektu w systemie GnuPG."
 
 #, c-format
 msgid "%s.\n"
@@ -3746,8 +3651,8 @@ msgid ""
 "using this program with the option \"--edit-key\".\n"
 "\n"
 msgstr ""
-"Nie chcesz podać hasła - to *zły* pomysł!\n"
-"W każdej chwili możesz ustawić hasło używając tego programu i opcji\n"
+"Nie chcesz podaæ has³a - to *z³y* pomys³!\n"
+"W ka¿dej chwili mo¿esz ustawiæ has³o u¿ywaj±c tego programu i opcji\n"
 "\"--edit-key\".\n"
 "\n"
 
@@ -3757,29 +3662,29 @@ msgid ""
 "disks) during the prime generation; this gives the random number\n"
 "generator a better chance to gain enough entropy.\n"
 msgstr ""
-"Musimy wygenerować dużo losowych bajtów. Dobrym pomysłem aby pomóc "
+"Musimy wygenerowaæ du¿o losowych bajtów. Dobrym pomys³em aby pomóc "
 "komputerowi\n"
 "podczas generowania liczb pierwszych jest wykonywanie w tym czasie innych\n"
-"działań (pisanie na klawiaturze, poruszanie myszką, odwołanie się do "
-"dysków);\n"
-"dzięki temu generator liczb losowych ma możliwość zebrania odpowiedniej "
-"ilości\n"
+"dzia³añ (pisanie na klawiaturze, poruszanie myszk±, odwo³anie siê do "
+"dysków);\n"
+"dziêki temu generator liczb losowych ma mo¿liwo¶æ zebrania odpowiedniej "
+"iloci\n"
 "entropii.\n"
 
 msgid "Key generation canceled.\n"
-msgstr "Procedura generacji klucza została anulowana.\n"
+msgstr "Procedura generacji klucza zosta³a anulowana.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
-msgstr "zapisuję klucz publiczny w ,,%s''\n"
+msgid "writing public key to '%s'\n"
+msgstr "zapisujê klucz publiczny w ,,%s''\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "zapisuję zaślepkę klucza tajnego w ,,%s''\n"
+msgid "writing secret key stub to '%s'\n"
+msgstr "zapisujê za¶lepkê klucza tajnego w ,,%s''\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "zapisuję klucz tajny w ,,%s''\n"
+msgid "writing secret key to '%s'\n"
+msgstr "zapisujê klucz tajny w ,,%s''\n"
 
 #, c-format
 msgid "no writable public keyring found: %s\n"
@@ -3790,58 +3695,58 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "brak zapisywalnego zbioru kluczy tajnych: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
-msgstr "błąd podczas zapisu zbioru kluczy publicznych ,,%s'': %s\n"
+msgid "error writing public keyring '%s': %s\n"
+msgstr "b³±d podczas zapisu zbioru kluczy publicznych ,,%s'': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "błąd podczas zapisu zbioru kluczy tajnych ,,%s'': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
+msgstr "b³±d podczas zapisu zbioru kluczy tajnych ,,%s'': %s\n"
 
 msgid "public and secret key created and signed.\n"
-msgstr "klucz publiczny i prywatny (tajny) zostały utworzone i podpisane.\n"
+msgstr "klucz publiczny i prywatny (tajny) zosta³y utworzone i podpisane.\n"
 
 msgid ""
 "Note that this key cannot be used for encryption.  You may want to use\n"
 "the command \"--edit-key\" to generate a subkey for this purpose.\n"
 msgstr ""
-"Ten klucz nie może być wykorzystany do szyfrowania. Komendą \"--edit-key\"\n"
-"można dodać do niego podklucz szyfrujący.\n"
+"Ten klucz nie mo¿e byæ wykorzystany do szyfrowania. Komend± \"--edit-key\"\n"
+"mo¿na dodaæ do niego podklucz szyfruj±cy.\n"
 
 #, c-format
 msgid "Key generation failed: %s\n"
-msgstr "Generacja klucza nie powiodła się: %s\n"
+msgstr "Generacja klucza nie powiod³a siê: %s\n"
 
 #, c-format
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr ""
-"klucz został stworzony %lu sekundę w przyszłości (zaburzenia\n"
-"czasoprzestrzeni, lub źle ustawiony zegar systemowy)\n"
+"klucz zosta³ stworzony %lu sekundê w przysz³o¶ci (zaburzenia\n"
+"czasoprzestrzeni, lub ¼le ustawiony zegar systemowy)\n"
 
 #, c-format
 msgid ""
 "key has been created %lu seconds in future (time warp or clock problem)\n"
 msgstr ""
-"klucz został stworzony %lu sekund w przyszłości (zaburzenia\n"
-"czasoprzestrzeni, lub źle ustawiony zegar systemowy)\n"
+"klucz zosta³ stworzony %lu sekund w przysz³o¶ci (zaburzenia\n"
+"czasoprzestrzeni, lub ¼le ustawiony zegar systemowy)\n"
 
 msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
 msgstr ""
 "UWAGA: tworzenie podkluczy dla kluczy wersji 3 jest niezgodne z OpenPGP.\n"
 
 msgid "Really create? (y/N) "
-msgstr "Czy na pewno utworzyć? (t/N) "
+msgstr "Czy na pewno utworzyæ? (t/N) "
 
 #, c-format
 msgid "storing key onto card failed: %s\n"
-msgstr "zapis klucza na karcie nie powiódł się: %s\n"
+msgstr "zapis klucza na karcie nie powiód³ siê: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
-msgstr "nie można utworzyć pliku kopii zapasowej ,,%s'': %s\n"
+msgid "can't create backup file '%s': %s\n"
+msgstr "nie mo¿na utworzyæ pliku kopii zapasowej ,,%s'': %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "UWAGA: kopia zapasowa klucza karty zapisana do ,,%s''\n"
 
 msgid "never     "
@@ -3863,10 +3768,10 @@ msgid "Signature notation: "
 msgstr "Adnotacje podpisu: "
 
 msgid "Keyring"
-msgstr "Zbiór kluczy"
+msgstr "Zbiór kluczy"
 
 msgid "Primary key fingerprint:"
-msgstr "Odcisk klucza głównego:"
+msgstr "Odcisk klucza g³ównego:"
 
 msgid "     Subkey fingerprint:"
 msgstr "      Odcisk podklucza:"
@@ -3874,7 +3779,7 @@ msgstr "      Odcisk podklucza:"
 #. TRANSLATORS: this should fit into 24 bytes to that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
-msgstr " Odcisk klucza głównego:"
+msgstr " Odcisk klucza g³ównego:"
 
 msgid "      Subkey fingerprint:"
 msgstr "       Odcisk podklucza:"
@@ -3882,64 +3787,59 @@ msgstr "       Odcisk podklucza:"
 msgid "      Key fingerprint ="
 msgstr "       Odcisk klucza ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "OSTRZEŻENIE: użycie eksperymentalnego algorytmu skrótu %s\n"
-
 msgid "      Card serial no. ="
 msgstr "    Nr seryjny karty ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
-msgstr "zmiana nazwy ,,%s'' na ,,%s'' nie powiodła się: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
+msgstr "zmiana nazwy ,,%s'' na ,,%s'' nie powiod³a siê: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr "OSTRZEŻENIE: Istnieją dwa pliki z poufnymi informacjami.\n"
+msgstr "OSTRZE¯ENIE: Istniej± dwa pliki z poufnymi informacjami.\n"
 
 #, c-format
 msgid "%s is the unchanged one\n"
-msgstr "%s pozostał bez zmian\n"
+msgstr "%s pozosta³ bez zmian\n"
 
 #, c-format
 msgid "%s is the new one\n"
-msgstr "%s został utworzony\n"
+msgstr "%s zosta³ utworzony\n"
 
 msgid "Please fix this possible security flaw\n"
-msgstr "Proszę usunąć to naruszenie zasad bezpieczeństwa\n"
+msgstr "Proszê usun±æ to naruszenie zasad bezpieczeñstwa\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "buforowanie zbioru kluczy ,,%s''\n"
 
 #, c-format
 msgid "%lu keys cached so far (%lu signatures)\n"
-msgstr "%lu kluczy zbuforowano do tej pory (%lu podpisów)\n"
+msgstr "%lu kluczy zbuforowano do tej pory (%lu podpisów)\n"
 
 #, c-format
 msgid "%lu keys cached (%lu signatures)\n"
-msgstr "%lu kluczy zbuforowano (%lu podpisów)\n"
+msgstr "%lu kluczy zbuforowano (%lu podpisów)\n"
 
 #, c-format
 msgid "%s: keyring created\n"
-msgstr "%s: zbiór kluczy utworzony\n"
+msgstr "%s: zbiór kluczy utworzony\n"
 
 msgid "include revoked keys in search results"
-msgstr "włączenie unieważnionych kluczy do wyników wyszukiwania"
+msgstr "w³±czenie uniewa¿nionych kluczy do wyników wyszukiwania"
 
 msgid "include subkeys when searching by key ID"
-msgstr "włączenie podkluczy przy poszukiwaniu po ID klucza"
+msgstr "w³±czenie podkluczy przy poszukiwaniu po ID klucza"
 
 msgid "use temporary files to pass data to keyserver helpers"
 msgstr ""
-"użycie plików tymczasowych do przekazywania danych do modułów obsługi "
+"u¿ycie plików tymczasowych do przekazywania danych do modu³ów obs³ugi "
 "serwera kluczy"
 
 msgid "do not delete temporary files after using them"
-msgstr "nie usuwanie plików tymczasowych po użyciu ich"
+msgstr "nie usuwanie plików tymczasowych po u¿yciu ich"
 
 msgid "automatically retrieve keys when verifying signatures"
-msgstr "automatyczne pobieranie kluczy przy sprawdzaniu podpisów"
+msgstr "automatyczne pobieranie kluczy przy sprawdzaniu podpisów"
 
 msgid "honor the preferred keyserver URL set on the key"
 msgstr "honorowanie URL-a preferowanego serwera kluczy ustawionego w kluczu"
@@ -3948,27 +3848,27 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "honorowanie rekordu PKA ustawionego w kluczu przy pobieraniu kluczy"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
-"OSTRZEŻENIE: opcja serwera kluczy ,,%s'' nie jest używana na tej "
+"OSTRZE¯ENIE: opcja serwera kluczy ,,%s'' nie jest u¿ywana na tej "
 "platformie.\n"
 
 msgid "disabled"
-msgstr "wyłączony"
+msgstr "wy³±czony"
 
 msgid "Enter number(s), N)ext, or Q)uit > "
-msgstr "Wprowadź numer(y), N)astępny lub Q)uit > "
+msgstr "Wprowad¼ numer(y), N)astêpny lub Q)uit > "
 
 #, c-format
 msgid "invalid keyserver protocol (us %d!=handler %d)\n"
-msgstr "niepoprawny protokół serwera kluczy (nasz %d != moduł obsługi %d)\n"
+msgstr "niepoprawny protokó³ serwera kluczy (nasz %d != modu³ obs³ugi %d)\n"
 
 #, c-format
 msgid "key \"%s\" not found on keyserver\n"
-msgstr "klucz ,,%s'' nie został odnaleziony na serwerze kluczy\n"
+msgstr "klucz ,,%s'' nie zosta³ odnaleziony na serwerze kluczy\n"
 
 msgid "key not found on keyserver\n"
-msgstr "klucz nie został odnaleziony na serwerze kluczy\n"
+msgstr "klucz nie zosta³ odnaleziony na serwerze kluczy\n"
 
 #, c-format
 msgid "requesting key %s from %s server %s\n"
@@ -3988,11 +3888,11 @@ msgstr "poszukiwanie nazw z %s\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
-msgstr "wysyłanie klucza %s na serwer %s %s\n"
+msgstr "wysy³anie klucza %s na serwer %s %s\n"
 
 #, c-format
 msgid "sending key %s to %s\n"
-msgstr "wysyłanie klucza %s na %s\n"
+msgstr "wysy³anie klucza %s na %s\n"
 
 #, c-format
 msgid "searching for \"%s\" from %s server %s\n"
@@ -4007,64 +3907,64 @@ msgstr "brak akcji serwera kluczy!\n"
 
 #, c-format
 msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr "OSTRZEŻENIE: moduł obsługi serwera kluczy z innej wersji GnuPG (%s)\n"
+msgstr "OSTRZE¯ENIE: modu³ obs³ugi serwera kluczy z innej wersji GnuPG (%s)\n"
 
 msgid "keyserver did not send VERSION\n"
-msgstr "serwer kluczy nie wysłał VERSION\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "błąd komunikacji z serwerem kluczy: %s\n"
+msgstr "serwer kluczy nie wys³a³ VERSION\n"
 
 msgid "no keyserver known (use option --keyserver)\n"
-msgstr "brak znanyk serwerów kluczy (użyj opcji --keyserver)\n"
+msgstr "brak znanyk serwerów kluczy (u¿yj opcji --keyserver)\n"
 
 msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
-"zewnętrzne wywołania serwera kluczy nie są obsługiwane w tej kompilacji\n"
+"zewnêtrzne wywo³ania serwera kluczy nie s± obs³ugiwane w tej kompilacji\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "brak modułu obsługi dla schematu serwera kluczy ,,%s''\n"
+msgid "no handler for keyserver scheme '%s'\n"
+msgstr "brak modu³u obs³ugi dla schematu serwera kluczy ,,%s''\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
-"akcja ,,%s'' nie jest obsługiwana przez schemat serwera kluczy ,,%s''\n"
+"akcja ,,%s'' nie jest obs³ugiwana przez schemat serwera kluczy ,,%s''\n"
 
 #, c-format
 msgid "%s does not support handler version %d\n"
-msgstr "%s nie obsługuje modułu obsługi w wersji %d\n"
+msgstr "%s nie obs³uguje modu³u obs³ugi w wersji %d\n"
 
 msgid "keyserver timed out\n"
-msgstr "zbyt długi czas oczekiwania na serwer kluczy\n"
+msgstr "zbyt d³ugi czas oczekiwania na serwer kluczy\n"
 
 msgid "keyserver internal error\n"
-msgstr "błąd wewnętrzny serwera kluczy\n"
+msgstr "b³±d wewnêtrzny serwera kluczy\n"
+
+#, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "b³±d komunikacji z serwerem kluczy: %s\n"
 
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
-msgstr ",,%s'' nie jest identyfikatorem klucza - pominięto\n"
+msgstr ",,%s'' nie jest identyfikatorem klucza - pominiêto\n"
 
 #, c-format
 msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr "OSTRZEŻENIE: nie można odświeżyć klucza %s przez %s: %s\n"
+msgstr "OSTRZE¯ENIE: nie mo¿na od¶wie¿yæ klucza %s przez %s: %s\n"
 
 #, c-format
 msgid "refreshing 1 key from %s\n"
-msgstr "odświeżanie 1 klucza z %s\n"
+msgstr "od¶wie¿anie 1 klucza z %s\n"
 
 #, c-format
 msgid "refreshing %d keys from %s\n"
-msgstr "odświeżanie %d kluczy z %s\n"
+msgstr "od¶wie¿anie %d kluczy z %s\n"
 
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
-msgstr "OSTRZEŻENIE: nie można pobrać URI %s: %s\n"
+msgstr "OSTRZE¯ENIE: nie mo¿na pobraæ URI %s: %s\n"
 
 #, c-format
 msgid "WARNING: unable to parse URI %s\n"
-msgstr "OSTRZEŻENIE: nie można przeanalizować URI %s\n"
+msgstr "OSTRZE¯ENIE: nie mo¿na przeanalizowaæ URI %s\n"
 
 #, c-format
 msgid "weird size for an encrypted session key (%d)\n"
@@ -4076,7 +3976,7 @@ msgstr "klucz sesyjny zaszyfrowany %s\n"
 
 #, c-format
 msgid "passphrase generated with unknown digest algorithm %d\n"
-msgstr "hasło wygenerowane nieznanym algorytmem skrótu %d\n"
+msgstr "has³o wygenerowane nieznanym algorytmem skrótu %d\n"
 
 #, c-format
 msgid "public key is %s\n"
@@ -4100,62 +4000,62 @@ msgstr "zaszyfrowano kluczem %s o identyfikatorze %s\n"
 
 #, c-format
 msgid "public key decryption failed: %s\n"
-msgstr "błąd odszyfrowywania kluczem publicznym: %s\n"
+msgstr "b³±d odszyfrowywania kluczem publicznym: %s\n"
 
 #, c-format
 msgid "encrypted with %lu passphrases\n"
-msgstr "zaszyfrowane za pomocą %lu haseł\n"
+msgstr "zaszyfrowane za pomoc± %lu hase³\n"
 
 msgid "encrypted with 1 passphrase\n"
-msgstr "zaszyfrowane jednym hasłem\n"
+msgstr "zaszyfrowane jednym has³em\n"
 
 #, c-format
 msgid "assuming %s encrypted data\n"
-msgstr "przyjmując że dane zostały zaszyfrowane za pomocą %s\n"
+msgstr "przyjmuj±c ¿e dane zosta³y zaszyfrowane za pomoc± %s\n"
 
 #, c-format
 msgid "IDEA cipher unavailable, optimistically attempting to use %s instead\n"
-msgstr "szyfr IDEA nie jest dostępny, próba użycia %s zamiast niego\n"
+msgstr "szyfr IDEA nie jest dostêpny, próba u¿ycia %s zamiast niego\n"
 
 msgid "decryption okay\n"
 msgstr "odszyfrowanie poprawne\n"
 
 msgid "WARNING: message was not integrity protected\n"
-msgstr "OSTRZEŻENIE: wiadomość nie była zabezpieczona przed manipulacją\n"
+msgstr "OSTRZE¯ENIE: wiadomo¶æ nie by³a zabezpieczona przed manipulacj±\n"
 
 msgid "WARNING: encrypted message has been manipulated!\n"
-msgstr "OSTRZEŻENIE: zaszyfrowana wiadomość była manipulowana!\n"
+msgstr "OSTRZE¯ENIE: zaszyfrowana wiadomo¶æ by³a manipulowana!\n"
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
-msgstr "wyczyszczono hasło zapamiętane z ID: %s\n"
+msgstr ""
 
 #, c-format
 msgid "decryption failed: %s\n"
-msgstr "błąd odszyfrowywania: %s\n"
+msgstr "b³±d odszyfrowywania: %s\n"
 
 msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
-msgstr "UWAGA: nadawca zaznaczył że wiadomość nie powinna być zapisywana\n"
+msgstr "UWAGA: nadawca zaznaczy³ ¿e wiadomo¶æ nie powinna byæ zapisywana\n"
 
 #, c-format
 msgid "original file name='%.*s'\n"
 msgstr "pierwotna nazwa pliku='%.*s'\n"
 
 msgid "WARNING: multiple plaintexts seen\n"
-msgstr "OSTRZEŻENIE: widziano wiele czystych tekstów\n"
+msgstr "OSTRZE¯ENIE: widziano wiele czystych tekstów\n"
 
 msgid "standalone revocation - use \"gpg --import\" to apply\n"
 msgstr ""
-"osobny certyfikat unieważnienia - użyj ,,gpg --import'' aby go wczytać\n"
+"osobny certyfikat uniewa¿nienia - u¿yj ,,gpg --import'' aby go wczytaæ\n"
 
 msgid "no signature found\n"
 msgstr "nie znaleziono podpisu\n"
 
 msgid "signature verification suppressed\n"
-msgstr "wymuszono pominięcie sprawdzenia podpisu\n"
+msgstr "wymuszono pominiêcie sprawdzenia podpisu\n"
 
 msgid "can't handle this ambiguous signature data\n"
-msgstr "nie można obsłużyć tych wieloznacznych danych podpisu\n"
+msgstr "nie mo¿na obs³u¿yæ tych wieloznacznych danych podpisu\n"
 
 #, c-format
 msgid "Signature made %s\n"
@@ -4163,26 +4063,26 @@ msgstr "Podpisano w %s\n"
 
 #, c-format
 msgid "               using %s key %s\n"
-msgstr "               przy użyciu klucza %s %s\n"
+msgstr "               przy u¿yciu klucza %s %s\n"
 
 #, c-format
 msgid "Signature made %s using %s key ID %s\n"
 msgstr "Podpisano w %s kluczem %s o numerze %s\n"
 
 msgid "Key available at: "
-msgstr "Klucz dostępny w: "
+msgstr "Klucz dostêpny w: "
 
 #, c-format
 msgid "BAD signature from \"%s\""
-msgstr "NIEPOPRAWNY podpis złożony przez ,,%s''"
+msgstr "NIEPOPRAWNY podpis z³o¿ony przez ,,%s''"
 
 #, c-format
 msgid "Expired signature from \"%s\""
-msgstr "Przeterminowany podpis złożony przez ,,%s''"
+msgstr "Przeterminowany podpis z³o¿ony przez ,,%s''"
 
 #, c-format
 msgid "Good signature from \"%s\""
-msgstr "Poprawny podpis złożony przez ,,%s''"
+msgstr "Poprawny podpis z³o¿ony przez ,,%s''"
 
 msgid "[uncertain]"
 msgstr "[niepewne]"
@@ -4193,15 +4093,15 @@ msgstr "                        alias ,,%s''"
 
 #, c-format
 msgid "Signature expired %s\n"
-msgstr "Ważność podpisu wygasła %s.\n"
+msgstr "Wa¿no¶æ podpisu wygas³a %s.\n"
 
 #, c-format
 msgid "Signature expires %s\n"
-msgstr "Ważność podpisu wygasa %s.\n"
+msgstr "Wa¿no¶æ podpisu wygasa %s.\n"
 
 #, c-format
 msgid "%s signature, digest algorithm %s\n"
-msgstr "podpis %s, skrót %s\n"
+msgstr "podpis %s, skrót %s\n"
 
 msgid "binary"
 msgstr "binarny"
@@ -4213,13 +4113,8 @@ msgid "unknown"
 msgstr "nieznany"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-"UWAGA: to nie jest podpis oddzielony; plik ,,%s'' NIE został sprawdzony!\n"
-
-#, c-format
 msgid "Can't check signature: %s\n"
-msgstr "Nie można sprawdzić podpisu: %s\n"
+msgstr "Nie mo¿na sprawdziæ podpisu: %s\n"
 
 msgid "not a detached signature\n"
 msgstr "nie jest oddzielonym podpisem.\n"
@@ -4227,7 +4122,7 @@ msgstr "nie jest oddzielonym podpisem.\n"
 msgid ""
 "WARNING: multiple signatures detected.  Only the first will be checked.\n"
 msgstr ""
-"OSTRZEŻENIE: wielokrotne podpisy. Tylko pierwszy zostanie sprawdzony.\n"
+"OSTRZE¯ENIE: wielokrotne podpisy. Tylko pierwszy zostanie sprawdzony.\n"
 
 #, c-format
 msgid "standalone signature of class 0x%02x\n"
@@ -4240,80 +4135,65 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "wykryto niepoprawny pakiet pierwotny w proc_tree()\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
-msgstr "fstat na ,,%s'' nie powiodło się w %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
+msgstr "fstat na ,,%s'' nie powiod³o siê w %s: %s\n"
 
 #, c-format
 msgid "fstat(%d) failed in %s: %s\n"
-msgstr "fstat(%d) nie powiodło się w %s: %s\n"
+msgstr "fstat(%d) nie powiod³o siê w %s: %s\n"
 
 #, c-format
 msgid "WARNING: using experimental public key algorithm %s\n"
 msgstr ""
-"OSTRZEŻENIE: użycie eksperymentalnego algorytmu klucza publicznego %s\n"
+"OSTRZE¯ENIE: u¿ycie eksperymentalnego algorytmu klucza publicznego %s\n"
 
+#, fuzzy
 msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n"
-msgstr ""
-"OSTRZEŻENIE: klucze do podpisywania i szyfrowania Elgamala są odradzane\n"
+msgstr "OSTRZE¯ENIE: algorytm skrótu %s jest odradzany\n"
 
 #, c-format
 msgid "WARNING: using experimental cipher algorithm %s\n"
-msgstr "OSTRZEŻENIE: użycie eksperymentalnego szyfru %s\n"
+msgstr "OSTRZE¯ENIE: u¿ycie eksperymentalnego szyfru %s\n"
 
 #, c-format
 msgid "WARNING: using experimental digest algorithm %s\n"
-msgstr "OSTRZEŻENIE: użycie eksperymentalnego algorytmu skrótu %s\n"
+msgstr "OSTRZE¯ENIE: u¿ycie eksperymentalnego algorytmu skrótu %s\n"
 
 #, c-format
 msgid "WARNING: digest algorithm %s is deprecated\n"
-msgstr "OSTRZEŻENIE: algorytm skrótu %s jest odradzany\n"
-
-#, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Uwaga: podpisy wykonane algorytmem %s są odrzucane\n"
+msgstr "OSTRZE¯ENIE: algorytm skrótu %s jest odradzany\n"
 
 msgid "the IDEA cipher plugin is not present\n"
-msgstr "moduł szyfru IDEA nie jest dostępny\n"
+msgstr "modu³ szyfru IDEA nie jest dostêpny\n"
 
 #, c-format
 msgid "please see %s for more information\n"
-msgstr "objaśnienie można przeczytać tutaj: %s\n"
+msgstr "obja¶nienie mo¿na przeczytaæ tutaj: %s\n"
 
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
-msgstr "%s:%d jest przestarzałą opcją ,,%s''\n"
+msgstr "%s:%d jest przestarza³± opcj± ,,%s''\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated option\n"
-msgstr "OSTRZEŻENIE: ,,%s'' jest przestarzałą opcją.\n"
+msgstr "OSTRZE¯ENIE: ,,%s'' jest przestarza³± opcj±.\n"
 
 #, c-format
 msgid "please use \"%s%s\" instead\n"
-msgstr "w jej miejsce należy użyć ,,%s%s''\n"
+msgstr "w jej miejsce nale¿y u¿yæ ,,%s%s''\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated command - do not use it\n"
 msgstr ""
-"OSTRZEŻENIE: ,,%s'' jest przestarzałym poleceniem - nie należy go używać\n"
+"OSTRZE¯ENIE: ,,%s'' jest przestarza³ym poleceniem - nie nale¿y go u¿ywaæ\n"
 
 #, c-format
 msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgstr "%s:%u: przestarzała opcja ,,%s'' - nie ma efektu\n"
+msgstr "%s:%u: przestarza³a opcja ,,%s'' - nie ma efektu\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr "OSTRZEŻENIE: ,,%s'' jest przestarzałą opcją - nie ma efektu\n"
-
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: ,,%s%s'' jest przestarzałe w tym pliku - efektywne tylko w %s\n"
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr ""
-"OSTRZEŻENIE: ,,%s%s'' jest przestarzałą opcją - nie ma efektu z wyjątkiem "
-"%s\n"
+msgstr "OSTRZE¯ENIE: ,,%s'' jest przestarza³± opcj± - nie ma efektu\n"
 
 msgid "Uncompressed"
 msgstr "Nieskompresowany"
@@ -4324,52 +4204,52 @@ msgstr "nieskompresowany|brak"
 
 #, c-format
 msgid "this message may not be usable by %s\n"
-msgstr "ta wiadomość może nie dać się odczytać za pomocą %s\n"
+msgstr "ta wiadomo¶æ mo¿e nie daæ siê odczytaæ za pomoc± %s\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "niejednoznaczna opcja ,,%s''\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "nieznana opcja ,,%s''\n"
 
 #, c-format
-msgid "File `%s' exists. "
-msgstr "Plik ,,%s'' już istnieje. "
+msgid "File '%s' exists. "
+msgstr "Plik ,,%s'' ju¿ istnieje. "
 
 msgid "Overwrite? (y/N) "
-msgstr "Nadpisać? (t/N) "
+msgstr "Nadpisaæ? (t/N) "
 
 #, c-format
 msgid "%s: unknown suffix\n"
-msgstr "%s: nieznana końcówka nazwy\n"
+msgstr "%s: nieznana koñcówka nazwy\n"
 
 msgid "Enter new filename"
 msgstr "Nazwa pliku"
 
 msgid "writing to stdout\n"
-msgstr "zapisywanie na wyjście standardowe\n"
+msgstr "zapisywanie na wyjcie standardowe\n"
 
 #, c-format
 msgid "assuming signed data in '%s'\n"
-msgstr "przyjęto obecność podpisanych danych w ,,%s''\n"
+msgstr "przyjêto obecno¶æ podpisanych danych w '%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
-msgstr "nowy plik ustawień ,,%s'' został utworzony\n"
+msgid "new configuration file '%s' created\n"
+msgstr "nowy plik ustawieñ ,,%s'' zosta³ utworzony\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
-msgstr "OSTRZEŻENIE: opcje w ,,%s'' nie są jeszcze uwzględnione.\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
+msgstr "OSTRZE¯ENIE: opcje w ,,%s'' nie s± jeszcze uwzglêdnione.\n"
 
 #, c-format
 msgid "can't handle public key algorithm %d\n"
-msgstr "nie można obsłużyć tego algorytmu klucza publicznego: %d\n"
+msgstr "nie mo¿na obs³u¿yæ tego algorytmu klucza publicznego: %d\n"
 
 msgid "WARNING: potentially insecure symmetrically encrypted session key\n"
 msgstr ""
-"OSTRZEŻENIE: symetrycznie zaszyfrowany klucz sesyjny może nie być "
+"OSTRZE¯ENIE: symetrycznie zaszyfrowany klucz sesyjny mo¿e nie byæ "
 "bezpieczny\n"
 
 #, c-format
@@ -4377,14 +4257,10 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "podpakiet typu %d ma ustawiony krytyczny bit\n"
 
 #, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problem z agentem: %s\n"
-
-#, c-format
 msgid " (main key ID %s)"
-msgstr " (ID głównego klucza %s)"
+msgstr " (ID g³ównego klucza %s)"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Please enter the passphrase to unlock the secret key for the OpenPGP "
 "certificate:\n"
@@ -4392,32 +4268,35 @@ msgid ""
 "%u-bit %s key, ID %s,\n"
 "created %s%s.\n"
 msgstr ""
-"Musisz podać hasło, aby odbezpieczyć klucz tajny certyfikatu OpenPGP:\n"
+"Musisz podaæ has³o aby odbezpieczyæ klucz tajny u¿ytkownika:\n"
 ",,%.*s''.\n"
-"Klucz o długości %u bitów, typ %s, ID %s,\n"
-"stworzony %s%s.\n"
+"Klucz o d³ugo¶ci %u bitów, typ %s, ID %s, stworzony %s%s\n"
 
 msgid "Enter passphrase\n"
-msgstr "Hasło\n"
+msgstr "Has³o\n"
 
 msgid "cancelled by user\n"
-msgstr "anulowano przez użytkownika\n"
+msgstr "anulowano przez u¿ytkownika\n"
+
+#, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problem z agentem: %s\n"
 
 #, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
 msgstr ""
-"Musisz podać hasło aby odbezpieczyć klucz prywatny użytkownika:\n"
+"Musisz podaæ has³o aby odbezpieczyæ klucz prywatny u¿ytkownika:\n"
 ",,%s''\n"
 
 #, c-format
 msgid "%u-bit %s key, ID %s, created %s"
-msgstr "długość %u bitów, typ %s, numer %s, stworzony %s"
+msgstr "d³ugo¶æ %u bitów, typ %s, numer %s, stworzony %s"
 
 #, c-format
 msgid "         (subkey on main key ID %s)"
-msgstr "         (podklucz dla głównego klucza o ID %s)"
+msgstr "         (podklucz dla g³ównego klucza o ID %s)"
 
 msgid ""
 "\n"
@@ -4427,71 +4306,61 @@ msgid ""
 "Keeping the image close to 240x288 is a good size to use.\n"
 msgstr ""
 "\n"
-"Wybierz zdjęcie które chcesz dołączyć do swojego klucza jako identyfikator.\n"
-"Musi to być plik w formacie JPEG. Zostanie on zapisany w Twoim kluczu\n"
-"publicznym. Jeśli będzie duży, powiększy to także rozmiar Twojego klucza!\n"
-"Dobry rozmiar to około 240 na 288 pikseli.\n"
+"Wybierz zdjêcie które chcesz do³±czyæ do swojego klucza jako identyfikator.\n"
+"Musi to byæ plik w formacie JPEG. Zostanie on zapisany w Twoim kluczu\n"
+"publicznym. Je¶li bêdzie du¿y, powiêkszy to tak¿e rozmiar Twojego klucza!\n"
+"Dobry rozmiar to oko³o 240 na 288 pikseli.\n"
 
 msgid "Enter JPEG filename for photo ID: "
-msgstr "Nazwa pliku ze zdjęciem w formacie JPEG: "
+msgstr "Nazwa pliku ze zdjêciem w formacie JPEG: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
-msgstr "nie można otworzyć pliku JPEG ,,%s'': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
+msgstr "nie mo¿na otworzyæ pliku JPEG ,,%s'': %s\n"
 
 #, c-format
 msgid "This JPEG is really large (%d bytes) !\n"
-msgstr "Ten JPEG jest naprawdę duży (%d bajtów)!\n"
+msgstr "Ten JPEG jest naprawdê du¿y (%d bajtów)!\n"
 
 msgid "Are you sure you want to use it? (y/N) "
-msgstr "Czy na pewno chcesz go użyć? (t/N) "
+msgstr "Czy na pewno chcesz go u¿yæ? (t/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr ",,%s'' nie jest plikiem JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
-msgstr "Czy zdjęcie jest w porządku? (t/N/w) "
+msgstr "Czy zdjêcie jest w porz±dku? (t/N/w) "
 
 msgid "unable to display photo ID!\n"
-msgstr "nie można wyświetlić zdjęcia!\n"
+msgstr "nie mo¿na wy¶wietliæ zdjêcia!\n"
 
 msgid "No reason specified"
 msgstr "nie podano przyczyny"
 
 msgid "Key is superseded"
-msgstr "klucz został zastąpiony"
+msgstr "klucz zosta³ zast±piony"
 
 msgid "Key has been compromised"
-msgstr "klucz został skompromitowany"
+msgstr "klucz zosta³ skompromitowany"
 
 msgid "Key is no longer used"
-msgstr "klucz nie jest już używany"
+msgstr "klucz nie jest ju¿ u¿ywany"
 
 msgid "User ID is no longer valid"
-msgstr "identyfikator użytkownika przestał być poprawny"
+msgstr "identyfikator u¿ytkownika przesta³ byæ poprawny"
 
 msgid "reason for revocation: "
-msgstr "powód unieważnienia: "
+msgstr "powód uniewa¿nienia: "
 
 msgid "revocation comment: "
-msgstr "komentarz do unieważnienia: "
+msgstr "komentarz do uniewa¿nienia: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMwWpP"
 
 msgid "No trust value assigned to:\n"
-msgstr "Brak wartości zaufania dla:\n"
+msgstr "Brak wartoci zaufania dla:\n"
 
 #, c-format
 msgid "  aka \"%s\"\n"
@@ -4499,7 +4368,7 @@ msgstr "  alias ,,%s''\n"
 
 msgid ""
 "How much do you trust that this key actually belongs to the named user?\n"
-msgstr "Jak bardzo ufasz, że ten klucz naprawdę należy do tej osoby?\n"
+msgstr "Jak bardzo ufasz, ¿e ten klucz naprawdê nale¿y do tej osoby?\n"
 
 #, c-format
 msgid "  %d = I don't know or won't say\n"
@@ -4514,13 +4383,13 @@ msgid "  %d = I trust ultimately\n"
 msgstr "  %d = ufam absolutnie\n"
 
 msgid "  m = back to the main menu\n"
-msgstr "  m = powrót do głównego menu\n"
+msgstr "  m = powrót do g³ównego menu\n"
 
 msgid "  s = skip this key\n"
-msgstr "  p = pominięcie tego klucza\n"
+msgstr "  p = pominiêcie tego klucza\n"
 
 msgid "  q = quit\n"
-msgstr "  w = wyjście\n"
+msgstr "  w = wyjcie\n"
 
 #, c-format
 msgid ""
@@ -4534,113 +4403,113 @@ msgid "Your decision? "
 msgstr "Twoja decyzja? "
 
 msgid "Do you really want to set this key to ultimate trust? (y/N) "
-msgstr "Czy na pewno chcesz przypisać absolutne zaufanie temu kluczowi? (t/N) "
+msgstr "Czy na pewno chcesz przypisaæ absolutne zaufanie temu kluczowi? (t/N) "
 
 msgid "Certificates leading to an ultimately trusted key:\n"
-msgstr "Certyfikaty prowadzące do ostatecznie zaufanego klucza:\n"
+msgstr "Certyfikaty prowadz±ce do ostatecznie zaufanego klucza:\n"
 
 #, c-format
 msgid "%s: There is no assurance this key belongs to the named user\n"
-msgstr "%s: Nie ma żadnej pewności, czy ten klucz należy do tej osoby\n"
+msgstr "%s: Nie ma ¿adnej pewno¶ci, czy ten klucz nale¿y do tej osoby\n"
 
 #, c-format
 msgid "%s: There is limited assurance this key belongs to the named user\n"
-msgstr "%s: Nie ma całkowitej pewności, czy ten klucz należy do tej osoby\n"
+msgstr "%s: Nie ma ca³kowitej pewno¶ci, czy ten klucz nale¿y do tej osoby\n"
 
 msgid "This key probably belongs to the named user\n"
-msgstr "Ten klucz prawdopodobnie należy do tej osoby\n"
+msgstr "Ten klucz prawdopodobnie nale¿y do tej osoby\n"
 
 msgid "This key belongs to us\n"
-msgstr "Ten klucz należy do nas\n"
+msgstr "Ten klucz nale¿y do nas\n"
 
 msgid ""
 "It is NOT certain that the key belongs to the person named\n"
 "in the user ID.  If you *really* know what you are doing,\n"
 "you may answer the next question with yes.\n"
 msgstr ""
-"NIE MA pewności, czy klucz należy do osoby wymienionej w identyfikatorze.\n"
-"Jeśli nie masz co do tego żadnych wątpliwości i *naprawdę* wiesz co robisz,\n"
-"możesz odpowiedzieć ,,tak'' na następne pytanie.\n"
+"NIE MA pewno¶ci, czy klucz nale¿y do osoby wymienionej w identyfikatorze.\n"
+"Je¶li nie masz co do tego ¿adnych w±tpliwo¶ci i *naprawdê* wiesz co robisz,\n"
+"mo¿esz odpowiedzieæ ,,tak'' na nastêpne pytanie.\n"
 
 msgid "Use this key anyway? (y/N) "
-msgstr "Użyć tego klucza pomimo to? (t/N) "
+msgstr "U¿yæ tego klucza pomimo to? (t/N) "
 
 msgid "WARNING: Using untrusted key!\n"
-msgstr "OSTRZEŻENIE: używany jest klucz nie obdarzony zaufaniem!\n"
+msgstr "OSTRZE¯ENIE: u¿ywany jest klucz nie obdarzony zaufaniem!\n"
 
 msgid "WARNING: this key might be revoked (revocation key not present)\n"
 msgstr ""
-"OSTRZEŻENIE: ten klucz mógł zostać unieważniony\n"
-"             (brak klucza unieważniającego aby to sprawdzić)\n"
+"OSTRZE¯ENIE: ten klucz móg³ zostaæ uniewa¿niony\n"
+"             (brak klucza uniewa¿niaj±cego aby to sprawdziæ)\n"
 
 msgid "WARNING: This key has been revoked by its designated revoker!\n"
-msgstr "OSTRZEŻENIE: Ten klucz został unieważniony kluczem unieważniającym!\n"
+msgstr "OSTRZE¯ENIE: Ten klucz zosta³ uniewa¿niony kluczem uniewa¿niaj±cym!\n"
 
 msgid "WARNING: This key has been revoked by its owner!\n"
-msgstr "OSTRZEŻENIE: Ten klucz został unieważniony przez właściciela!\n"
+msgstr "OSTRZE¯ENIE: Ten klucz zosta³ uniewa¿niony przez w³a¶ciciela!\n"
 
 msgid "         This could mean that the signature is forged.\n"
-msgstr "             To może oznaczać, że podpis jest fałszerstwem.\n"
+msgstr "             To mo¿e oznaczaæ, ¿e podpis jest fa³szerstwem.\n"
 
 msgid "WARNING: This subkey has been revoked by its owner!\n"
-msgstr "OSTRZEŻENIE: Ten podklucz został unieważniony przez właściciela!\n"
+msgstr "OSTRZE¯ENIE: Ten podklucz zosta³ uniewa¿niony przez w³a¶ciciela!\n"
 
 msgid "Note: This key has been disabled.\n"
-msgstr "Uwaga: Ten klucz został wyłączony z użytku.\n"
+msgstr "Uwaga: Ten klucz zosta³ wy³±czony z u¿ytku.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
-msgstr "Uwaga: Sprawdzony adres pospisującego to `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
+msgstr "Uwaga: Sprawdzony adres pospisuj±cego to `%s'\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr "Uwaga: Adres podpisującego `%s' nie pasuje do wpisu DNS\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
+msgstr "Uwaga: Adres podpisuj±cego `%s' nie pasuje do wpisu DNS\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
 msgstr ""
-"poziom zaufania poprawiony na PEŁNY ze względu na poprawne informacje PKA\n"
+"poziom zaufania poprawiony na PE£NY ze wzglêdu na poprawne informacje PKA\n"
 
 msgid "trustlevel adjusted to NEVER due to bad PKA info\n"
 msgstr ""
-"poziom zaufania poprawiony na ŻADEN ze względu na błędne informacje PKA\n"
+"poziom zaufania poprawiony na ¯ADEN ze wzglêdu na b³êdne informacje PKA\n"
 
 msgid "Note: This key has expired!\n"
-msgstr "Uwaga: Data ważności tego klucza upłynęła!\n"
+msgstr "Uwaga: Data wa¿no¶ci tego klucza up³ynê³a!\n"
 
 msgid "WARNING: This key is not certified with a trusted signature!\n"
-msgstr "OSTRZEŻENIE: Ten klucz nie jest poświadczony zaufanym podpisem!\n"
+msgstr "OSTRZE¯ENIE: Ten klucz nie jest po¶wiadczony zaufanym podpisem!\n"
 
 msgid ""
 "         There is no indication that the signature belongs to the owner.\n"
 msgstr ""
-"             Nie ma pewności co do tożsamości osoby która złożyła podpis.\n"
+"             Nie ma pewno¶ci co do to¿samo¶ci osoby która z³o¿y³a podpis.\n"
 
 msgid "WARNING: We do NOT trust this key!\n"
-msgstr "OSTRZEŻENIE: NIE UFAMY temu kluczowi!\n"
+msgstr "OSTRZE¯ENIE: NIE UFAMY temu kluczowi!\n"
 
 msgid "         The signature is probably a FORGERY.\n"
-msgstr "             Ten podpis prawdopodobnie jest FAŁSZYWY.\n"
+msgstr "             Ten podpis prawdopodobnie jest FA£SZYWY.\n"
 
 msgid ""
 "WARNING: This key is not certified with sufficiently trusted signatures!\n"
 msgstr ""
-"OSTRZEŻENIE: Tego klucza nie poświadczają wystarczająco zaufane podpisy!\n"
+"OSTRZE¯ENIE: Tego klucza nie po¶wiadczaj± wystarczaj±co zaufane podpisy!\n"
 
 msgid "         It is not certain that the signature belongs to the owner.\n"
 msgstr ""
-"             Nie ma pewności co do tożsamości osoby która złożyła ten "
+"             Nie ma pewno¶ci co do to¿samo¶ci osoby która z³o¿y³a ten "
 "podpis.\n"
 
 #, c-format
 msgid "%s: skipped: %s\n"
-msgstr "%s: pominięty: %s\n"
+msgstr "%s: pominiêty: %s\n"
 
 #, c-format
 msgid "%s: skipped: public key already present\n"
-msgstr "%s: pominięty: został już wybrany w innej opcji\n"
+msgstr "%s: pominiêty: zosta³ ju¿ wybrany w innej opcji\n"
 
 msgid "You did not specify a user ID. (you may use \"-r\")\n"
-msgstr "Nie został podany identyfikator użytkownika (np. za pomocą ,,-r'')\n"
+msgstr "Nie zosta³ podany identyfikator u¿ytkownika (np. za pomoc± ,,-r'')\n"
 
 msgid "Current recipients:\n"
 msgstr "Aktualni odbiorcy:\n"
@@ -4650,30 +4519,30 @@ msgid ""
 "Enter the user ID.  End with an empty line: "
 msgstr ""
 "\n"
-"Identyfikator użytkownika (pusta linia oznacza koniec): "
+"Identyfikator u¿ytkownika (pusta linia oznacza koniec): "
 
 msgid "No such user ID.\n"
-msgstr "Brak takiego identyfikatora użytkownika.\n"
+msgstr "Brak takiego identyfikatora u¿ytkownika.\n"
 
 msgid "skipped: public key already set as default recipient\n"
-msgstr "pominięty: klucz publiczny już jest domyślnym adresatem\n"
+msgstr "pominiêty: klucz publiczny ju¿ jest domy¶lnym adresatem\n"
 
 msgid "Public key is disabled.\n"
-msgstr "Klucz publiczny wyłączony z użycia.\n"
+msgstr "Klucz publiczny wy³±czony z u¿ycia.\n"
 
 msgid "skipped: public key already set\n"
-msgstr "pominięty: został już wybrany w innej opcji\n"
+msgstr "pominiêty: zosta³ ju¿ wybrany w innej opcji\n"
 
 #, c-format
 msgid "unknown default recipient \"%s\"\n"
-msgstr "nieznany domyślny adresat ,,%s''\n"
+msgstr "nieznany domylny adresat ,,%s''\n"
 
 #, c-format
 msgid "%s: skipped: public key is disabled\n"
-msgstr "%s: pominięty: klucz publiczny wyłączony z użytku\n"
+msgstr "%s: pominiêty: klucz publiczny wy³±czony z u¿ytku\n"
 
 msgid "no valid addressees\n"
-msgstr "brak poprawnych adresatów\n"
+msgstr "brak poprawnych adresatów\n"
 
 #, c-format
 msgid "Note: key %s has no %s feature\n"
@@ -4685,7 +4554,7 @@ msgstr "Uwaga: klucz %s nie ma preferencji dla %s\n"
 
 msgid "data not saved; use option \"--output\" to save it\n"
 msgstr ""
-"dane nie zostały zapisane; aby to zrobić, należy użyć opcji \"--output\"\n"
+"dane nie zosta³y zapisane; aby to zrobiæ, nale¿y u¿yæ opcji \"--output\"\n"
 
 msgid "Detached signature.\n"
 msgstr "Podpis oddzielony od danych.\n"
@@ -4694,88 +4563,88 @@ msgid "Please enter name of data file: "
 msgstr "Nazwa pliku danych: "
 
 msgid "reading stdin ...\n"
-msgstr "czytam strumień standardowego wejścia\n"
+msgstr "czytam strumieñ standardowego wej¶cia\n"
 
 msgid "no signed data\n"
 msgstr "brak podpisanych danych\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
-msgstr "nie można otworzyć podpisanego pliku ,,%s''\n"
+msgid "can't open signed data '%s'\n"
+msgstr "nie mo¿na otworzyæ podpisanego pliku ,,%s''\n"
 
 #, c-format
 msgid "can't open signed data fd=%d: %s\n"
-msgstr "nie można otworzyć podpisanych danych z fd=%d: %s\n"
+msgstr "nie mo¿na otworzyæ podpisanych danych z fd=%d: %s\n"
 
 #, c-format
 msgid "anonymous recipient; trying secret key %s ...\n"
 msgstr "adresat anonimowy; sprawdzanie klucza tajnego %s...\n"
 
 msgid "okay, we are the anonymous recipient.\n"
-msgstr "OK, to my jesteśmy adresatem anonimowym.\n"
+msgstr "OK, to my jestemy adresatem anonimowym.\n"
 
 msgid "old encoding of the DEK is not supported\n"
-msgstr "stary, nieobsługiwany algorytm szyfrowania klucza sesyjnego\n"
+msgstr "stary, nieobs³ugiwany algorytm szyfrowania klucza sesyjnego\n"
 
 #, c-format
 msgid "cipher algorithm %d%s is unknown or disabled\n"
-msgstr "algorytm szyfrujący %d%s jest nieznany lub został wyłączony\n"
+msgstr "algorytm szyfruj±cy %d%s jest nieznany lub zosta³ wy³±czony\n"
 
 #, c-format
 msgid "WARNING: cipher algorithm %s not found in recipient preferences\n"
-msgstr "OSTRZEŻENIE: brak algorytmu szyfrującego %s w ustawieniach odbiorcy\n"
+msgstr "OSTRZE¯ENIE: brak algorytmu szyfruj±cego %s w ustawieniach odbiorcy\n"
 
 #, c-format
 msgid "NOTE: secret key %s expired at %s\n"
-msgstr "UWAGA: ważność klucza tajnego %s wygasła %s\n"
+msgstr "UWAGA: wa¿no¶æ klucza tajnego %s wygas³a %s\n"
 
 msgid "NOTE: key has been revoked"
-msgstr "UWAGA: klucz został unieważniony"
+msgstr "UWAGA: klucz zosta³ uniewa¿niony"
 
 #, c-format
 msgid "build_packet failed: %s\n"
-msgstr "wywołanie funkcji build_packet nie powiodło się: %s\n"
+msgstr "wywo³anie funkcji build_packet nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "key %s has no user IDs\n"
-msgstr "klucz %s nie ma identyfikatorów użytkownika\n"
+msgstr "klucz %s nie ma identyfikatorów u¿ytkownika\n"
 
 msgid "To be revoked by:\n"
-msgstr "Zostanie unieważniony przez:\n"
+msgstr "Zostanie uniewa¿niony przez:\n"
 
 msgid "(This is a sensitive revocation key)\n"
-msgstr "(to jest czuły klucz unieważniający)\n"
+msgstr "(to jest czu³y klucz uniewa¿niaj±cy)\n"
 
 msgid "Create a designated revocation certificate for this key? (y/N) "
-msgstr "Stworzyć certyfikat unieważnienia tego klucza? (t/N) "
+msgstr "Stworzyæ certyfikat uniewa¿nienia tego klucza? (t/N) "
 
 msgid "ASCII armored output forced.\n"
 msgstr "wymuszono opakowanie ASCII wyniku.\n"
 
 #, c-format
 msgid "make_keysig_packet failed: %s\n"
-msgstr "wywołanie funkcji make_keysig_packet nie powiodło się: %s\n"
+msgstr "wywo³anie funkcji make_keysig_packet nie powiod³o siê: %s\n"
 
 msgid "Revocation certificate created.\n"
-msgstr "Certyfikat unieważnienia został utworzony.\n"
+msgstr "Certyfikat uniewa¿nienia zosta³ utworzony.\n"
 
 #, c-format
 msgid "no revocation keys found for \"%s\"\n"
-msgstr "brak kluczy unieważniających dla ,,%s''\n"
+msgstr "brak kluczy uniewa¿niaj±cych dla ,,%s''\n"
 
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
-msgstr "klucz prywatny ,,%s'' nie został odnaleziony: %s\n"
+msgstr "klucz prywatny ,,%s'' nie zosta³ odnaleziony: %s\n"
 
 #, c-format
 msgid "no corresponding public key: %s\n"
-msgstr "brak odpowiadającego klucza publicznego: %s\n"
+msgstr "brak odpowiadaj±cego klucza publicznego: %s\n"
 
 msgid "public key does not match secret key!\n"
 msgstr "klucz publiczny nie pasuje do klucza prywatnego!\n"
 
 msgid "Create a revocation certificate for this key? (y/N) "
-msgstr "Stworzyć certyfikat unieważnienia tego klucza? (t/N) "
+msgstr "Stworzyæ certyfikat uniewa¿nienia tego klucza? (t/N) "
 
 msgid "unknown protection algorithm\n"
 msgstr "nieznany algorytm ochrony\n"
@@ -4792,36 +4661,36 @@ msgid ""
 "your media become unreadable.  But have some caution:  The print system of\n"
 "your machine might store the data and make it available to others!\n"
 msgstr ""
-"Certyfikat unieważnienia został utworzony.\n"
+"Certyfikat uniewa¿nienia zosta³ utworzony.\n"
 "\n"
-"Należy przenieść go na nośnik który można bezpiecznie ukryć; jeśli źli "
+"Nale¿y przenie¶æ go na no¶nik który mo¿na bezpiecznie ukryæ; je¶li ¼li "
 "ludzie\n"
-"dostaną ten certyfikat w swoje ręce, mogą użyć go do uczynienia klucza\n"
-"nieużytecznym.\n"
+"dostan± ten certyfikat w swoje rêce, mog± u¿yæ go do uczynienia klucza\n"
+"nieu¿ytecznym.\n"
 "\n"
-"Niezłym pomysłem jest wydrukowanie certyfikatu unieważnienia i schowanie\n"
-"wydruku w bezpiecznym miejscu, na wypadek gdyby nośnik z certyfikatem stał "
-"się\n"
-"nieczytelny. Ale należy zachować ostrożność, systemy drukowania różnych\n"
-"komputerów mogą zachować treść wydruku i udostępnić ją osobom "
-"nieupoważnionym.\n"
+"Niez³ym pomys³em jest wydrukowanie certyfikatu uniewa¿nienia i schowanie\n"
+"wydruku w bezpiecznym miejscu, na wypadek gdyby no¶nik z certyfikatem sta³ "
+"siê\n"
+"nieczytelny. Ale nale¿y zachowaæ ostro¿no¶æ, systemy drukowania ró¿nych\n"
+"komputerów mog± zachowaæ tre¶æ wydruku i udostêpniæ j± osobom "
+"nieupowa¿nionym.\n"
 
 msgid "Please select the reason for the revocation:\n"
-msgstr "Proszę wybrać powód unieważnienia:\n"
+msgstr "Proszê wybraæ powód uniewa¿nienia:\n"
 
 msgid "Cancel"
 msgstr "Anuluj"
 
 #, c-format
 msgid "(Probably you want to select %d here)\n"
-msgstr "(Prawdopodobnie chcesz tu wybrać %d)\n"
+msgstr "(Prawdopodobnie chcesz tu wybraæ %d)\n"
 
 msgid "Enter an optional description; end it with an empty line:\n"
-msgstr "Wprowadź opis (nieobowiązkowy) i zakończ go pustą linią:\n"
+msgstr "Wprowad¼ opis (nieobowi±zkowy) i zakoñcz go pust± lini±:\n"
 
 #, c-format
 msgid "Reason for revocation: %s\n"
-msgstr "Powód unieważnienia: %s\n"
+msgstr "Powód uniewa¿nienia: %s\n"
 
 msgid "(No description given)\n"
 msgstr "(nie podano)\n"
@@ -4830,248 +4699,248 @@ msgid "Is this okay? (y/N) "
 msgstr "Informacje poprawne? (t/N) "
 
 msgid "secret key parts are not available\n"
-msgstr "tajne części klucza są niedostępne\n"
+msgstr "tajne czê¶ci klucza s± niedostêpne\n"
 
 #, c-format
 msgid "protection algorithm %d%s is not supported\n"
-msgstr "algorytm ochrony %d%s nie jest obsługiwany\n"
+msgstr "algorytm ochrony %d%s nie jest obs³ugiwany\n"
 
 #, c-format
 msgid "protection digest %d is not supported\n"
-msgstr "algorytm ochrony %d nie jest obsługiwany\n"
+msgstr "algorytm ochrony %d nie jest obs³ugiwany\n"
 
 msgid "Invalid passphrase; please try again"
-msgstr "Niepoprawne hasło; proszę spróbować ponownie"
+msgstr "Niepoprawne has³o; proszê spróbowaæ ponownie"
 
 #, c-format
 msgid "%s ...\n"
 msgstr "%s ...\n"
 
 msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr "OSTRZEŻENIE: Wykryto słaby klucz - należy ponownie zmienić hasło.\n"
+msgstr "OSTRZE¯ENIE: Wykryto s³aby klucz - nale¿y ponownie zmieniæ has³o.\n"
 
 msgid "generating the deprecated 16-bit checksum for secret key protection\n"
 msgstr ""
-"tworzenie przestarzałej 16-bitowej sumy kontrolnej dla ochrony klucza\n"
+"tworzenie przestarza³ej 16-bitowej sumy kontrolnej dla ochrony klucza\n"
 
 msgid "weak key created - retrying\n"
-msgstr "wygenerowano słaby klucz - operacja zostaje powtórzona\n"
+msgstr "wygenerowano s³aby klucz - operacja zostaje powtórzona\n"
 
 #, c-format
 msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
 msgstr ""
-"brak możliwości generacji dobrego klucza dla szyfru symetrycznego;\n"
-"operacja była powtarzana %d razy!\n"
+"brak mo¿liwo¶ci generacji dobrego klucza dla szyfru symetrycznego;\n"
+"operacja by³a powtarzana %d razy!\n"
 
 msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA wymaga długości skrótu będącego wielokrotnością 8 bitów\n"
+msgstr "DSA wymaga d³ugo¶ci skrótu bêd±cego wielokrotno¶ci± 8 bitów\n"
 
 #, c-format
 msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "Klucz DSA %s używa niebezpiecznego (%u-bitowego) skrótu\n"
+msgstr "Klucz DSA %s u¿ywa niebezpiecznego (%u-bitowego) skrótu\n"
 
 #, c-format
 msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "Klucz DSA %s wymaga %u-bitowego lub większego skrótu\n"
+msgstr "Klucz DSA %s wymaga %u-bitowego lub wiêkszego skrótu\n"
 
 msgid "WARNING: signature digest conflict in message\n"
-msgstr "OSTRZEŻENIE: konflikt skrótów podpisów w wiadomości\n"
+msgstr "OSTRZE¯ENIE: konflikt skrótów podpisów w wiadomo¶ci\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s is not cross-certified\n"
-msgstr "OSTRZEŻENIE: podklucz podpisujący %s nie jest skrośnie podpisany\n"
+msgstr "OSTRZE¯ENIE: podklucz podpisuj±cy %s nie jest skro¶nie podpisany\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr ""
-"OSTRZEŻENIE: podklucz podpisujący %s jest niepoprawnie skrośnie podpisany\n"
+"OSTRZE¯ENIE: podklucz podpisuj±cy %s jest niepoprawnie skro¶nie podpisany\n"
 
 #, c-format
 msgid "public key %s is %lu second newer than the signature\n"
-msgstr "klucz publiczny %s jest o %lu sekundę młodszy od podpisu\n"
+msgstr "klucz publiczny %s jest o %lu sekundê m³odszy od podpisu\n"
 
 #, c-format
 msgid "public key %s is %lu seconds newer than the signature\n"
-msgstr "klucz publiczny %s jest o %lu sekund(y) młodszy od podpisu\n"
+msgstr "klucz publiczny %s jest o %lu sekund(y) m³odszy od podpisu\n"
 
 #, c-format
 msgid ""
 "key %s was created %lu second in the future (time warp or clock problem)\n"
 msgstr ""
-"klucz %s został stworzony %lu sekundę w przyszłości (zaburzenia\n"
-"czasoprzestrzeni lub źle ustawiony zegar systemowy)\n"
+"klucz %s zosta³ stworzony %lu sekundê w przysz³o¶ci (zaburzenia\n"
+"czasoprzestrzeni lub ¼le ustawiony zegar systemowy)\n"
 
 #, c-format
 msgid ""
 "key %s was created %lu seconds in the future (time warp or clock problem)\n"
 msgstr ""
-"klucz %s został stworzony %lu sekund w przyszłości (zaburzenia\n"
-"czasoprzestrzeni lub źle ustawiony zegar systemowy)\n"
+"klucz %s zosta³ stworzony %lu sekund w przysz³o¶ci (zaburzenia\n"
+"czasoprzestrzeni lub ¼le ustawiony zegar systemowy)\n"
 
 #, c-format
 msgid "NOTE: signature key %s expired %s\n"
-msgstr "UWAGA: klucz podpisujący %s przekroczył datę ważności %s\n"
+msgstr "UWAGA: klucz podpisuj±cy %s przekroczy³ datê wa¿no¶ci %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "NOTE: signature key %s has been revoked\n"
-msgstr "UWAGA: klucz podpisujący %s został unieważniony\n"
+msgstr "UWAGA: klucz zosta³ uniewa¿niony"
 
 #, c-format
 msgid "assuming bad signature from key %s due to an unknown critical bit\n"
 msgstr ""
-"uznano za zły podpis utworzony kluczem %s z powodu nieznanego bitu "
+"uznano za z³y podpis utworzony kluczem %s z powodu nieznanego bitu "
 "krytycznego\n"
 
 #, c-format
 msgid "key %s: no subkey for subkey revocation signature\n"
-msgstr "klucz %s: brak podklucza dla podpisu unieważnienia podklucza\n"
+msgstr "klucz %s: brak podklucza dla podpisu uniewa¿nienia podklucza\n"
 
 #, c-format
 msgid "key %s: no subkey for subkey binding signature\n"
-msgstr "klucz %s: brak podklucza dowiązywanego podpisem\n"
+msgstr "klucz %s: brak podklucza dowi±zywanego podpisem\n"
 
 #, c-format
 msgid "WARNING: unable to %%-expand notation (too large).  Using unexpanded.\n"
 msgstr ""
-"OSTRZEŻENIE: nie można rozwinąć %% w URL adnotacji (jest zbyt długi).\n"
-"             Użyty zostanie nie rozwinięty.\n"
+"OSTRZE¯ENIE: nie mo¿na rozwin±æ %% w URL adnotacji (jest zbyt d³ugi).\n"
+"             U¿yty zostanie nie rozwiniêty.\n"
 
 #, c-format
 msgid ""
 "WARNING: unable to %%-expand policy URL (too large).  Using unexpanded.\n"
 msgstr ""
-"OSTRZEŻENIE: nie można rozwinąć znaczników %% w URL regulaminu\n"
-"           (jest zbyt długi). Użyty zostanie nie rozwinięty.\n"
+"OSTRZE¯ENIE: nie mo¿na rozwin±æ znaczników %% w URL regulaminu\n"
+"           (jest zbyt d³ugi). U¿yty zostanie nie rozwiniêty.\n"
 
 #, c-format
 msgid ""
 "WARNING: unable to %%-expand preferred keyserver URL (too large).  Using "
 "unexpanded.\n"
 msgstr ""
-"OSTRZEŻENIE: nie można rozwinąć znaczników %% w URL-u preferowanego\n"
-"           serwera kluczy (jest zbyt długi). Użyty zostanie nie rozwinięty.\n"
+"OSTRZE¯ENIE: nie mo¿na rozwin±æ znaczników %% w URL-u preferowanego\n"
+"           serwera kluczy (jest zbyt d³ugi). U¿yty zostanie nie rozwiniêty.\n"
 
 #, c-format
 msgid "checking created signature failed: %s\n"
-msgstr "sprawdzenie złożonego podpisu nie powiodło się: %s\n"
+msgstr "sprawdzenie z³o¿onego podpisu nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "%s/%s signature from: \"%s\"\n"
-msgstr "podpis %s/%s złożony przez: ,,%s''\n"
+msgstr "podpis %s/%s z³o¿ony przez: ,,%s''\n"
 
 msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
 msgstr ""
-"kluczami PGP 2 w trybie --pgp2 można podpisywać tylko do oddzielonych "
-"podpisów\n"
+"kluczami PGP 2 w trybie --pgp2 mo¿na podpisywaæ tylko do oddzielonych "
+"podpisów\n"
 
 #, c-format
 msgid ""
 "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
 msgstr ""
-"OSTRZEŻENIE: wymuszone użycie skrótu %s (%d) kłóci się z ustawieniami "
+"OSTRZE¯ENIE: wymuszone u¿ycie skrótu %s (%d) k³óci siê z ustawieniami "
 "adresata\n"
 
 msgid "signing:"
 msgstr "podpis:"
 
 msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr "w trybie --pgp2 można podpisywać tylko za pomocą kluczy z wersji 2.x\n"
+msgstr "w trybie --pgp2 mo¿na podpisywaæ tylko za pomoc± kluczy z wersji 2.x\n"
 
 #, c-format
 msgid "%s encryption will be used\n"
-msgstr "zostanie użyty szyfr %s\n"
+msgstr "zostanie u¿yty szyfr %s\n"
 
 msgid "key is not flagged as insecure - can't use it with the faked RNG!\n"
 msgstr ""
-"klucz nie jest oznaczony jako niepewny - nie można go użyć z atrapą\n"
+"klucz nie jest oznaczony jako niepewny - nie mo¿na go u¿yæ z atrap±\n"
 "generatora liczb losowych!\n"
 
 #, c-format
 msgid "skipped \"%s\": duplicated\n"
-msgstr "pominięty ,,%s'': duplikat\n"
+msgstr "pominiêty ,,%s'': duplikat\n"
 
 #, c-format
 msgid "skipped \"%s\": %s\n"
-msgstr "pominięty ,,%s'': %s\n"
+msgstr "pominiêty ,,%s'': %s\n"
 
 msgid "skipped: secret key already present\n"
-msgstr "pominięty: klucz prywatny jest już wpisany\n"
+msgstr "pominiêty: klucz prywatny jest ju¿ wpisany\n"
 
 msgid "this is a PGP generated Elgamal key which is not secure for signatures!"
 msgstr ""
-"klucz algorytmu Elgamala wygenerowany przez PGP nie zapewniający "
-"bezpiecznych podpisów!"
+"klucz algorytmu Elgamala wygenerowany przez PGP nie zapewniaj±cy "
+"bezpiecznych podpisów!"
 
 #, c-format
 msgid "trust record %lu, type %d: write failed: %s\n"
-msgstr "wpis zaufania %lu, typ zapytania %d: zapis nie powiódł się: %s\n"
+msgstr "wpis zaufania %lu, typ zapytania %d: zapis nie powiód³ siê: %s\n"
 
 #, c-format
 msgid ""
 "# List of assigned trustvalues, created %s\n"
 "# (Use \"gpg --import-ownertrust\" to restore them)\n"
 msgstr ""
-"# Lista przypisanych wartości zaufania, stworzona %s\n"
-"# (użyj \"gpg --import-ownertrust\" aby ją przywrócić)\n"
+"# Lista przypisanych wartoci zaufania, stworzona %s\n"
+"# (u¿yj \"gpg --import-ownertrust\" aby j± przywróciæ)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
-msgstr "błąd w ,,%s'': %s\n"
+msgid "error in '%s': %s\n"
+msgstr "b³±d w ,,%s'': %s\n"
 
 msgid "line too long"
-msgstr "linia zbyt długa"
+msgstr "linia zbyt d³uga"
 
 msgid "colon missing"
 msgstr "brak dwukropka"
 
 msgid "invalid fingerprint"
-msgstr "niewłaściwy odcisk"
+msgstr "niew³a¶ciwy odcisk"
 
 msgid "ownertrust value missing"
-msgstr "brak wartości zaufania właściciela"
+msgstr "brak warto¶ci zaufania w³a¶ciciela"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
-msgstr "błąd podczas szukania zapisu wartości zaufania w ,,%s'': %s\n"
+msgid "error finding trust record in '%s': %s\n"
+msgstr "b³±d podczas szukania zapisu warto¶ci zaufania w ,,%s'': %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
-msgstr "błąd odczytu w ,,%s'': %s\n"
+msgid "read error in '%s': %s\n"
+msgstr "b³±d odczytu w ,,%s'': %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
-msgstr "baza zaufania: synchronizacja nie powiodła się %s\n"
-
-#, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "nie można utworzyć blokady dla ,,%s''\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "nie można zablokować ,,%s''\n"
+msgstr "baza zaufania: synchronizacja nie powiod³a siê %s\n"
 
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
-msgstr "baza zaufania, wpis %lu: funkcja lseek() nie powiodła się: %s\n"
+msgstr "baza zaufania, wpis %lu: funkcja lseek() nie powiod³a siê: %s\n"
 
 #, c-format
 msgid "trustdb rec %lu: write failed (n=%d): %s\n"
-msgstr "baza zaufania, wpis %lu: zapis nie powiódł się (n=%d): %s\n"
+msgstr "baza zaufania, wpis %lu: zapis nie powiód³ siê (n=%d): %s\n"
 
 msgid "trustdb transaction too large\n"
-msgstr "zbyt duże zlecenie dla bazy zaufania\n"
+msgstr "zbyt du¿e zlecenie dla bazy zaufania\n"
+
+#, c-format
+msgid "can't access '%s': %s\n"
+msgstr "nie mo¿na dostaæ siê do ,,%s'': %s\n"
 
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: katalog nie istnieje!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nie można dostać się do ,,%s'': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "nie mo¿na utworzyæ blokady dla ,,%s''\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "nie mo¿na zablokowaæ ,,%s''\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
-msgstr "%s: stworzenie zapisu o wersji nie powiodło się: %s"
+msgstr "%s: stworzenie zapisu o wersji nie powiod³o siê: %s"
 
 #, c-format
 msgid "%s: invalid trustdb created\n"
@@ -5082,7 +4951,7 @@ msgid "%s: trustdb created\n"
 msgstr "%s: baza zaufania utworzona\n"
 
 msgid "NOTE: trustdb not writable\n"
-msgstr "UWAGA: nie można zapisywać bazy zaufania\n"
+msgstr "UWAGA: nie mo¿na zapisywaæ bazy zaufania\n"
 
 #, c-format
 msgid "%s: invalid trustdb\n"
@@ -5090,27 +4959,27 @@ msgstr "%s: niepoprawny plik bazy zaufania\n"
 
 #, c-format
 msgid "%s: failed to create hashtable: %s\n"
-msgstr "%s: tworzenie tablicy skrótów nie powiodło się: %s\n"
+msgstr "%s: tworzenie tablicy skrótów nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "%s: error updating version record: %s\n"
-msgstr "%s: błąd przy uaktualnianiu numeru wersji: %s\n"
+msgstr "%s: b³±d przy uaktualnianiu numeru wersji: %s\n"
 
 #, c-format
 msgid "%s: error reading version record: %s\n"
-msgstr "%s: błąd odczytu numeru wersji: %s\n"
+msgstr "%s: b³±d odczytu numeru wersji: %s\n"
 
 #, c-format
 msgid "%s: error writing version record: %s\n"
-msgstr "%s: błąd zapisu numeru wersji: %s\n"
+msgstr "%s: b³±d zapisu numeru wersji: %s\n"
 
 #, c-format
 msgid "trustdb: lseek failed: %s\n"
-msgstr "baza zaufania: funkcja lseek() zawiodła: %s\n"
+msgstr "baza zaufania: funkcja lseek() zawiod³a: %s\n"
 
 #, c-format
 msgid "trustdb: read failed (n=%d): %s\n"
-msgstr "baza zaufania: funkcja read() (n=%d) zawiodła: %s\n"
+msgstr "baza zaufania: funkcja read() (n=%d) zawiod³a: %s\n"
 
 #, c-format
 msgid "%s: not a trustdb file\n"
@@ -5122,38 +4991,39 @@ msgstr "%s: wpis wersji z numerem %lu\n"
 
 #, c-format
 msgid "%s: invalid file version %d\n"
-msgstr "%s: niewłaściwa wersja pliku %d\n"
+msgstr "%s: niew³a¶ciwa wersja pliku %d\n"
 
 #, c-format
 msgid "%s: error reading free record: %s\n"
-msgstr "%s: błąd odczytu pustego wpisu: %s\n"
+msgstr "%s: b³±d odczytu pustego wpisu: %s\n"
 
 #, c-format
 msgid "%s: error writing dir record: %s\n"
-msgstr "%s: błąd zapisu wpisu katalogowego: %s\n"
+msgstr "%s: b³±d zapisu wpisu katalogowego: %s\n"
 
 #, c-format
 msgid "%s: failed to zero a record: %s\n"
-msgstr "%s: zerowanie rekordu nie powiodło się: %s\n"
+msgstr "%s: zerowanie rekordu nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "%s: failed to append a record: %s\n"
-msgstr "%s: dopisanie rekordu nie powiodło się: %s\n"
+msgstr "%s: dopisanie rekordu nie powiod³o siê: %s\n"
 
+#, fuzzy
 msgid "Error: The trustdb is corrupted.\n"
-msgstr "Błąd: uszkodzona baza zaufania.\n"
+msgstr "%s: baza zaufania utworzona\n"
 
 #, c-format
 msgid "can't handle text lines longer than %d characters\n"
-msgstr "nie można obsłużyć linii tekstu dłuższej niż %d znaków\n"
+msgstr "nie mo¿na obs³u¿yæ linii tekstu d³u¿szej ni¿ %d znaków\n"
 
 #, c-format
 msgid "input line longer than %d characters\n"
-msgstr "linia dłuższa niż %d znaków\n"
+msgstr "linia d³u¿sza ni¿ %d znaków\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
-msgstr ",,%s'' nie jest poprawnym długim numerem klucza\n"
+msgid "'%s' is not a valid long keyID\n"
+msgstr ",,%s'' nie jest poprawnym d³ugim numerem klucza\n"
 
 #, c-format
 msgid "key %s: accepted as trusted key\n"
@@ -5161,52 +5031,44 @@ msgstr "klucz %s: zaakceptowany jako klucz zaufany\n"
 
 #, c-format
 msgid "key %s occurs more than once in the trustdb\n"
-msgstr "klucz %s jest wpisany więcej niż raz w bazie zaufania\n"
+msgstr "klucz %s jest wpisany wiêcej ni¿ raz w bazie zaufania\n"
 
 #, c-format
 msgid "key %s: no public key for trusted key - skipped\n"
-msgstr "klucz %s: brak klucza publicznego dla zaufanego klucza - pominięty\n"
+msgstr "klucz %s: brak klucza publicznego dla zaufanego klucza - pominiêty\n"
 
 #, c-format
 msgid "key %s marked as ultimately trusted\n"
-msgstr "klucz %s został oznaczony jako obdarzony absolutnym zaufaniem.\n"
+msgstr "klucz %s zosta³ oznaczony jako obdarzony absolutnym zaufaniem.\n"
 
 #, c-format
 msgid "trust record %lu, req type %d: read failed: %s\n"
-msgstr "wpis zaufania %lu, typ zapytania %d: odczyt nie powiódł się: %s\n"
+msgstr "wpis zaufania %lu, typ zapytania %d: odczyt nie powiód³ siê: %s\n"
 
 #, c-format
 msgid "trust record %lu is not of requested type %d\n"
-msgstr "wpis zaufania %lu jest typu innego niż poszukiwany %d\n"
+msgstr "wpis zaufania %lu jest typu innego ni¿ poszukiwany %d\n"
 
 msgid "You may try to re-create the trustdb using the commands:\n"
-msgstr "Można próbować odtworzyć bazę zaufania przy użyciu poleceń:\n"
+msgstr ""
 
 msgid "If that does not work, please consult the manual\n"
-msgstr "Jeśli to nie działa, należy poradzić się instrukcji\n"
+msgstr ""
 
 #, c-format
 msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
 msgstr ""
-"nie można użyć nieznanego modelu zaufania (%d) - przyjęto model zaufania %s\n"
+"nie mo¿na u¿yæ nieznanego modelu zaufania (%d) - przyjêto model zaufania %s\n"
 
 #, c-format
 msgid "using %s trust model\n"
-msgstr "użycie modelu zaufania %s\n"
-
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
+msgstr "u¿ycie modelu zaufania %s\n"
+
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr "17"
 
 msgid "[ revoked]"
-msgstr "[  unieważniony ]"
+msgstr "[  uniewa¿niony ]"
 
 msgid "[ expired]"
 msgstr "[przeterminowany]"
@@ -5215,19 +5077,19 @@ msgid "[ unknown]"
 msgstr "[    nieznane   ]"
 
 msgid "[  undef ]"
-msgstr "[  nieokreślone ]"
+msgstr "[  nieokrelone ]"
 
 msgid "[marginal]"
 msgstr "[   marginalne  ]"
 
 msgid "[  full  ]"
-msgstr "[      pełne    ]"
+msgstr "[      pe³ne    ]"
 
 msgid "[ultimate]"
 msgstr "[    absolutne   ]"
 
 msgid "undefined"
-msgstr "nieokreślone"
+msgstr "nieokrelone"
 
 msgid "never"
 msgstr "nigdy"
@@ -5236,7 +5098,7 @@ msgid "marginal"
 msgstr "marginalne"
 
 msgid "full"
-msgstr "pełne"
+msgstr "pe³ne"
 
 msgid "ultimate"
 msgstr "absolutne"
@@ -5246,14 +5108,14 @@ msgstr "sprawdzanie bazy jest niepotrzebne\n"
 
 #, c-format
 msgid "next trustdb check due at %s\n"
-msgstr "następne sprawdzanie bazy odbędzie się %s\n"
+msgstr "nastêpne sprawdzanie bazy odbêdzie siê %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "sprawdzanie bazy jest niepotrzebne przy modelu zaufania ,,%s''\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "aktualizacja bazy jest niepotrzebna przy modelu zaufania ,,%s''\n"
 
 #, c-format
@@ -5261,14 +5123,14 @@ msgid "public key %s not found: %s\n"
 msgstr "klucz publiczny %s nie odnaleziony: %s\n"
 
 msgid "please do a --check-trustdb\n"
-msgstr "należy uruchomić gpg z opcją ,,--check-trustdb''\n"
+msgstr "nale¿y uruchomiæ gpg z opcj± ,,--check-trustdb''\n"
 
 msgid "checking the trustdb\n"
 msgstr "sprawdzanie bazy zaufania\n"
 
 #, c-format
 msgid "%d keys processed (%d validity counts cleared)\n"
-msgstr "przetworzono %d kluczy (rozwiązano %d przeliczeń zaufania)\n"
+msgstr "przetworzono %d kluczy (rozwi±zano %d przeliczeñ zaufania)\n"
 
 msgid "no ultimately trusted keys found\n"
 msgstr "brak absolutnie zaufanych kluczy\n"
@@ -5279,83 +5141,74 @@ msgstr "klucz publiczny absolutnie zaufanego klucza %s nie odnaleziony\n"
 
 #, c-format
 msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
-msgstr "potrzeba %d marginalnych, %d pełnych, model zaufania %s\n"
+msgstr "potrzeba %d marginalnych, %d pe³nych, model zaufania %s\n"
 
 #, c-format
 msgid ""
 "depth: %d  valid: %3d  signed: %3d  trust: %d-, %dq, %dn, %dm, %df, %du\n"
 msgstr ""
-"poziom: %d poprawnych: %3d podpisanych: %3d zaufanie: %d-,%dq,%dn,%dm,%df,"
-"%du\n"
+"poziom: %d poprawnych: %3d podpisanych: %3d zaufanie: %d-,%dq,%dn,%dm,%df,%"
+"du\n"
 
 #, c-format
 msgid "unable to update trustdb version record: write failed: %s\n"
 msgstr ""
-"nie można uaktualnić rekordu wersji bazy zaufania: zapis nie powiódł się: "
-"%s\n"
+"nie mo¿na uaktualniæ rekordu wersji bazy zaufania: zapis nie powiód³ siê: %"
+"s\n"
 
 msgid ""
 "the signature could not be verified.\n"
 "Please remember that the signature file (.sig or .asc)\n"
 "should be the first file given on the command line.\n"
 msgstr ""
-"nie można sprawdzić podpisu.\n"
-"Należy pamiętać o podawaniu pliku podpisu (.sig lub .asc) jako pierwszego\n"
-"argumentu linii poleceń.\n"
+"nie mo¿na sprawdziæ podpisu.\n"
+"Nale¿y pamiêtaæ o podawaniu pliku podpisu (.sig lub .asc) jako pierwszego\n"
+"argumentu linii poleceñ.\n"
 
 #, c-format
 msgid "input line %u too long or missing LF\n"
-msgstr "linia wejścia %u zbyt długa lub brak znaku LF\n"
+msgstr "linia wej¶cia %u zbyt d³uga lub brak znaku LF\n"
 
 #, c-format
 msgid "can't open fd %d: %s\n"
-msgstr "nie można otworzyć fd %d: %s\n"
+msgstr "nie mo¿na otworzyæ fd %d: %s\n"
 
 msgid "argument not expected"
 msgstr "nieoczekiwany argument"
 
 msgid "read error"
-msgstr "błąd odczytu"
+msgstr "b³±d odczytu"
 
 msgid "keyword too long"
-msgstr "słowo kluczowe zbyt długie"
+msgstr "s³owo kluczowe zbyt d³ugie"
 
 msgid "missing argument"
 msgstr "brak argumentu"
 
-#, fuzzy
-#| msgid "invalid value\n"
-msgid "invalid argument"
-msgstr "niepoprawna wartość\n"
-
 msgid "invalid command"
-msgstr "błędne polecenie"
+msgstr "b³êdne polecenie"
 
 msgid "invalid alias definition"
-msgstr "błędna definicja aliasu"
+msgstr "b³êdna definicja aliasu"
 
+#, fuzzy
 msgid "out of core"
-msgstr "brak pamięci"
+msgstr "[B³±d - brak pamiêci]"
 
 msgid "invalid option"
-msgstr "błędna opcja"
+msgstr "b³êdna opcja"
 
 #, c-format
 msgid "missing argument for option \"%.50s\"\n"
 msgstr "brak argumentu dla opcji ,,%.50s''\n"
 
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "brak argumentu dla opcji ,,%.50s''\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "opcja ,,%.50s'' nie może mieć argumentów\n"
+msgstr "opcja ,,%.50s'' nie mo¿e mieæ argumentów\n"
 
 #, c-format
 msgid "invalid command \"%.50s\"\n"
-msgstr "błędne polecenie ,,%.50s''\n"
+msgstr "b³êdne polecenie ,,%.50s''\n"
 
 #, c-format
 msgid "option \"%.50s\" is ambiguous\n"
@@ -5365,295 +5218,289 @@ msgstr "opcja ,,%.50s'' jest niejednoznaczna\n"
 msgid "command \"%.50s\" is ambiguous\n"
 msgstr "polecenie ,,%.50s'' jest niejednoznaczne\n"
 
+#, fuzzy
 msgid "out of core\n"
-msgstr "brak pamięci\n"
+msgstr "[B³±d - brak pamiêci]"
 
 #, c-format
 msgid "invalid option \"%.50s\"\n"
-msgstr "błędna opcja ,,%.50s''\n"
+msgstr "b³êdna opcja ,,%.50s''\n"
 
 #, c-format
 msgid "you found a bug ... (%s:%d)\n"
-msgstr "znalazłeś(aś) błąd w programie ... (%s:%d)\n"
+msgstr "znalaz³e¶(a¶) b³±d w programie ... (%s:%d)\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "konwersja z ,,%s'' do ,,%s'' niedostępna\n"
+msgid "error loading '%s': %s\n"
+msgstr "b³±d odczytu ,,%s'': %s\n"
 
 #, c-format
-msgid "iconv_open failed: %s\n"
-msgstr "iconv_open nie powiodło się: %s\n"
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr "konwersja z ,,%s'' do ,,%s'' niedostêpna\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "konwersja z ,,%s'' do ,,%s'' nie powiodła się: %s\n"
+msgid "iconv_open failed: %s\n"
+msgstr "iconv_open nie powiod³o siê: %s\n"
 
 #, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "nie udało się utworzyć pliku tymczasowego ,,%s'': %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "konwersja z ,,%s'' do ,,%s'' nie powiod³a siê: %s\n"
 
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "błąd zapisu do ,,%s'': %s\n"
+#, fuzzy, c-format
+msgid "failed to create temporary file '%s': %s\n"
+msgstr "nie mo¿na utworzyæ katalogu tymczasowego,,%s'': %s\n"
+
+#, fuzzy, c-format
+msgid "error writing to '%s': %s\n"
+msgstr "b³±d zapisu do %s: %s\n"
 
 #, c-format
 msgid "removing stale lockfile (created by %d)\n"
-msgstr "usuwanie nieaktualnego pliku blokady (utworzonego przez %d)\n"
+msgstr ""
 
 msgid " - probably dead - removing lock"
-msgstr " - prawdopodobnie martwy - usuwanie blokady"
+msgstr ""
 
 #, c-format
 msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "oczekiwanie na blokadę (trzymaną przez %d%s) %s...\n"
+msgstr ""
 
 msgid "(deadlock?) "
-msgstr "(zakleszczenie?) "
+msgstr ""
 
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "blokada ,,%s'' nie założona: %s\n"
+#, fuzzy, c-format
+msgid "lock '%s' not made: %s\n"
+msgstr "klucz publiczny %s nie odnaleziony: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "waiting for lock %s...\n"
-msgstr "oczekiwanie na blokadę %s...\n"
+msgstr "nas³uchiwanie na gnie¼dzie ,,%s''\n"
 
 msgid "set debugging flags"
 msgstr "ustawienie flag diagnostycznych"
 
 msgid "enable full debugging"
-msgstr "włączenie pełnej diagnostyki"
+msgstr "w³±czenie pe³nej diagnostyki"
 
 msgid "Usage: kbxutil [options] [files] (-h for help)"
-msgstr "Wywołanie: kbxutil [opcje] [pliki] (-h podaje pomoc)"
+msgstr "Wywo³anie: kbxutil [opcje] [pliki] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
-"Składnia: kbxutil [opcje] [pliki]\n"
-"Wypisywanie, eksport, import danych Keybox\n"
+"Sk³adnia: kbxutil [opcje] [pliki]\n"
+"wypisywanie, eksport, import danych Keybox\n"
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
-msgstr "reszta RSA brakująca lub o rozmiarze innym niż %d bity\n"
+msgstr "reszta RSA brakuj±ca lub o rozmiarze innym ni¿ %d bity\n"
 
 #, c-format
 msgid "RSA public exponent missing or larger than %d bits\n"
-msgstr "publiczny wykładnik RSA brakujący lub większy niż %d bity\n"
+msgstr "publiczny wyk³adnik RSA brakuj±cy lub wiêkszy ni¿ %d bity\n"
 
 #, c-format
 msgid "PIN callback returned error: %s\n"
-msgstr "Zapytanie zwrotne o PIN zwróciło błąd: %s\n"
+msgstr "Zapytanie zwrotne o PIN zwróci³o b³±d: %s\n"
 
 msgid "the NullPIN has not yet been changed\n"
-msgstr "NullPIN nie został jeszcze zmieniony\n"
+msgstr "NullPIN nie zosta³ jeszcze zmieniony\n"
 
+#, fuzzy
 msgid "|N|Please enter a new PIN for the standard keys."
-msgstr "|N|Proszę wprowadzić nowy PIN dla zwykłych kluczy."
+msgstr "||Proszê wprowadziæ PIN na klawiaturze czytnika"
 
+#, fuzzy
 msgid "||Please enter the PIN for the standard keys."
-msgstr "||Proszę wprowadzić PIN dla zwykłych kluczy."
+msgstr "||Proszê wprowadziæ PIN na klawiaturze czytnika"
 
+#, fuzzy
 msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys."
-msgstr ""
-"|NP|Proszę wprowadzić nowy kod oblokowujący PIN (PUK) dla zwykłych kluczy."
+msgstr "Proszê wprowadziæ PIN%s%s%s aby odblokowaæ kartê"
 
+#, fuzzy
 msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|P|Proszę wprowadzić kod odblokowujący PIN (PUK) dla zwykłych kluczy."
+msgstr "Proszê wprowadziæ PIN%s%s%s aby odblokowaæ kartê"
 
 msgid "|N|Please enter a new PIN for the key to create qualified signatures."
 msgstr ""
-"|N|Proszę wprowadzić nowy PIN dla klucza do tworzenia podpisów "
-"kwalifikowanych."
 
 msgid "||Please enter the PIN for the key to create qualified signatures."
 msgstr ""
-"||Proszę wprowadzić PIN PIN dla klucza do tworzenia podpisów kwalifikowanych."
 
 msgid ""
 "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Proszę wprowadzić nowy kod odblokowujący PIN (PUK) dla klucza do "
-"tworzenia podpisów kwalifikowanych."
 
 msgid ""
 "|P|Please enter the PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|P|Proszę wprowadzić kod odblokowujący PIN (PUK) dla klucza do tworzenia "
-"podpisów kwalifikowanych."
 
 #, c-format
 msgid "error getting new PIN: %s\n"
-msgstr "błąd podczas odczytu nowego PIN-u: %s\n"
+msgstr "b³±d podczas odczytu nowego PIN-u: %s\n"
 
 #, c-format
 msgid "failed to store the fingerprint: %s\n"
-msgstr "nie powiódł się zapis odcisku: %s\n"
+msgstr "nie powiód³ siê zapis odcisku: %s\n"
 
 #, c-format
 msgid "failed to store the creation date: %s\n"
-msgstr "nie powiódł się zapis daty utworzenia: %s\n"
+msgstr "nie powiód³ siê zapis daty utworzenia: %s\n"
 
 #, c-format
 msgid "reading public key failed: %s\n"
-msgstr "odczyt klucza publicznego nie powiódł się: %s\n"
+msgstr "odczyt klucza publicznego nie powiód³ siê: %s\n"
 
 msgid "response does not contain the public key data\n"
-msgstr "odpowiedź nie zawiera danych klucza publicznego\n"
+msgstr "odpowied¼ nie zawiera danych klucza publicznego\n"
 
 msgid "response does not contain the RSA modulus\n"
-msgstr "odpowiedź nie zawiera współczynnika RSA\n"
+msgstr "odpowied¼ nie zawiera wspó³czynnika RSA\n"
 
 msgid "response does not contain the RSA public exponent\n"
-msgstr "odpowiedź nie zawiera publicznego wykładnika RSA\n"
+msgstr "odpowied¼ nie zawiera publicznego wyk³adnika RSA\n"
 
 #, c-format
 msgid "using default PIN as %s\n"
-msgstr "użycie domyślnego PIN-u jako %s\n"
+msgstr ""
 
 #, c-format
 msgid "failed to use default PIN as %s: %s - disabling further default use\n"
 msgstr ""
-"nie udało się użyć domyślnego PIN-u jako %s: %s - wyłączenie dalszego "
-"domyślnego użycia\n"
 
 #, c-format
 msgid "||Please enter the PIN%%0A[sigs done: %lu]"
-msgstr "||Proszę wpisać PIN%%0A[podpisów wykonanych: %lu]"
+msgstr "||Proszê wpisaæ PIN%%0A[podpisów wykonanych: %lu]"
 
+#, fuzzy
 msgid "||Please enter the PIN"
-msgstr "||Proszę wpisać PIN"
+msgstr "||Proszê wpisaæ PIN%%0A[podpisów wykonanych: %lu]"
 
 #, c-format
 msgid "PIN for CHV%d is too short; minimum length is %d\n"
-msgstr "PIN dla CHV%d jest zbyt krótki; minimalna długość to %d\n"
+msgstr "PIN dla CHV%d jest zbyt krótki; minimalna d³ugo¶æ to %d\n"
 
 #, c-format
 msgid "verify CHV%d failed: %s\n"
-msgstr "weryfikacja CHV%d nie powiodła się: %s\n"
+msgstr "weryfikacja CHV%d nie powiod³a siê: %s\n"
 
 msgid "error retrieving CHV status from card\n"
-msgstr "błąd podczas odczytu stanu CHV z karty\n"
+msgstr "b³±d podczas odczytu stanu CHV z karty\n"
 
 msgid "card is permanently locked!\n"
-msgstr "karta została trwale zablokowana!\n"
+msgstr "karta zosta³a trwale zablokowana!\n"
 
 #, c-format
 msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
-msgstr ""
-"Zostało %d prób PIN-u administracyjnego do trwałego zablokowania karty\n"
+msgstr "Zosta³o %d prób PIN-u administratora do trwa³ego zablokowania karty\n"
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %%0A to force a linefeed.
-#, c-format
+#, fuzzy, c-format
 msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-msgstr "|A|Proszę wprowadzić PIN administracyjny%%0A[pozostało prób: %d]"
+msgstr ""
+"||Proszê wprowadziæ PIN na klawiaturze czytnika%%0A[podpisów wykonanych: %lu]"
 
+#, fuzzy
 msgid "|A|Please enter the Admin PIN"
-msgstr "|A|Proszę wprowadzić PIN administracyjny"
+msgstr "||Proszê wpisaæ PIN%%0A[podpisów wykonanych: %lu]"
 
 msgid "access to admin commands is not configured\n"
-msgstr "dostęp do poleceń administratora nie został skonfigurowany\n"
+msgstr "dostêp do poleceñ administratora nie zosta³ skonfigurowany\n"
 
+#, fuzzy
 msgid "||Please enter the Reset Code for the card"
-msgstr "||Proszę wprowadzić kod resetujący dla karty"
+msgstr "Proszê wprowadziæ PIN%s%s%s aby odblokowaæ kartê"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "Kod resetujący zbyt krótki; minimalna długość to %d\n"
+msgstr "PIN dla CHV%d jest zbyt krótki; minimalna d³ugo¶æ to %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
-msgstr "|RN|Nowy kod resetujący"
+msgstr ""
 
 msgid "|AN|New Admin PIN"
-msgstr "|AN|Nowy PIN administracyjny"
+msgstr "|AN|Nowy PIN administratora"
 
 msgid "|N|New PIN"
 msgstr "|N|Nowy PIN"
 
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||Proszę wprowadzić PIN administracyjny i nowy PIN administracyjny"
-
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Proszę wprowadzić PIN i nowy PIN"
-
 msgid "error reading application data\n"
-msgstr "błąd podczas odczytu danych aplikacji\n"
+msgstr "b³±d podczas odczytu danych aplikacji\n"
 
 msgid "error reading fingerprint DO\n"
-msgstr "błąd podczas odczytu odcisku DO\n"
+msgstr "b³±d podczas odczytu odcisku DO\n"
 
 msgid "key already exists\n"
-msgstr "klucz już istnieje\n"
+msgstr "klucz ju¿ istnieje\n"
 
 msgid "existing key will be replaced\n"
-msgstr "istniejący klucz zostanie zastąpiony\n"
+msgstr "istniej±cy klucz zostanie zast±piony\n"
 
 msgid "generating new key\n"
 msgstr "generowanie nowego klucza\n"
 
+#, fuzzy
 msgid "writing new key\n"
-msgstr "zapisywanie nowego klucza\n"
+msgstr "generowanie nowego klucza\n"
 
 msgid "creation timestamp missing\n"
 msgstr "brak datownika utworzenia\n"
 
 #, c-format
 msgid "RSA prime %s missing or not of size %d bits\n"
-msgstr "liczba pierwsza %s RSA brakująca lub o rozmiarze innym niż %d bitów\n"
+msgstr "liczba pierwsza %s RSA brakuj±ca lub o rozmiarze innym ni¿ %d bitów\n"
 
 #, c-format
 msgid "failed to store the key: %s\n"
-msgstr "nie powiódł się zapis klucza: %s\n"
+msgstr "nie powiód³ siê zapis klucza: %s\n"
 
 msgid "please wait while key is being generated ...\n"
-msgstr "proszę czekać na wygenerowanie klucza...\n"
+msgstr "proszê czekaæ na wygenerowanie klucza...\n"
 
 msgid "generating key failed\n"
-msgstr "generowanie klucza nie powiodło się\n"
+msgstr "generowanie klucza nie powiod³o siê\n"
 
 #, c-format
 msgid "key generation completed (%d seconds)\n"
-msgstr "generowanie klucza zakończone (%d sekund)\n"
+msgstr "generowanie klucza zakoñczone (%d sekund)\n"
 
 msgid "invalid structure of OpenPGP card (DO 0x93)\n"
 msgstr "niepoprawna struktura karty OpenPGP (DO 0x93)\n"
 
 msgid "fingerprint on card does not match requested one\n"
-msgstr "odcisk na karcie nie zgadza się z żądanym\n"
+msgstr "odcisk na karcie nie zgadza siê z ¿±danym\n"
 
 #, c-format
 msgid "card does not support digest algorithm %s\n"
-msgstr "karta nie obsługuje algorytmu skrótu %s\n"
+msgstr "karta nie obs³uguje algorytmu skrótu %s\n"
 
 #, c-format
 msgid "signatures created so far: %lu\n"
-msgstr "dotychczas stworzono podpisów: %lu\n"
+msgstr "dotychczas stworzono podpisów: %lu\n"
 
 msgid ""
 "verification of Admin PIN is currently prohibited through this command\n"
 msgstr ""
-"weryfikacja PIN-u administracyjnego tym poleceniem jest aktualnie "
-"zabroniona\n"
+"weryfikacja PIN-u administratora tym poleceniem jest aktualnie zabroniona\n"
 
 #, c-format
 msgid "can't access %s - invalid OpenPGP card?\n"
-msgstr "nie można dostać się do %s - niepoprawna karta OpenPGP?\n"
+msgstr "nie mo¿na dostaæ siê do %s - niepoprawna karta OpenPGP?\n"
 
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||Proszę wprowadzić PIN na klawiaturze czytnika"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr "||Proszê wprowadziæ PIN na klawiaturze czytnika"
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
 #. to get some infos on the string.
+#, fuzzy
 msgid "|N|Initial New PIN"
-msgstr "|N|Początkowy nowy PIN"
+msgstr "|N|Nowy PIN"
 
 msgid "run in multi server mode (foreground)"
 msgstr "uruchomienie w trybie serwera (pierwszoplanowo)"
@@ -5661,89 +5508,88 @@ msgstr "uruchomienie w trybie serwera (pierwszoplanowo)"
 msgid "|LEVEL|set the debugging level to LEVEL"
 msgstr "|POZIOM|ustawienie POZIOMU diagnostyki"
 
+#, fuzzy
 msgid "|FILE|write a log to FILE"
-msgstr "|PLIK|zapisanie logów do PLIKu"
+msgstr "|PLIK|zapisanie logów trybu serwerowego do PLIKu"
 
 msgid "|N|connect to reader at port N"
-msgstr "|N|połączenie z czytnikiem na porcie N"
+msgstr "|N|po³±czenie z czytnikiem na porcie N"
 
 msgid "|NAME|use NAME as ct-API driver"
-msgstr "|NAZWA|użycie NAZWY jako sterownika ct-API"
+msgstr "|NAZWA|u¿ycie NAZWY jako sterownika ct-API"
 
 msgid "|NAME|use NAME as PC/SC driver"
-msgstr "|NAZWA|użycie NAZWY jako sterownika PC/SC"
+msgstr "|NAZWA|u¿ycie NAZWY jako sterownika PC/SC"
 
 msgid "do not use the internal CCID driver"
-msgstr "nie używanie wewnętrznego sterownika CCID"
+msgstr "nie u¿ywanie wewnêtrznego sterownika CCID"
 
 msgid "|N|disconnect the card after N seconds of inactivity"
-msgstr "|N|odłączenie karty po N sekundach nieaktywności"
+msgstr ""
 
-msgid "do not use a reader's pinpad"
-msgstr "nie używanie klawiatury czytnika"
+msgid "do not use a reader's keypad"
+msgstr "nie u¿ywanie klawiatury czytnika"
 
+#, fuzzy
 msgid "deny the use of admin card commands"
-msgstr "zabronienie używania poleceń karty administratora"
-
-msgid "use variable length input for pinpad"
-msgstr "użycie wejścia z klawiatury czytnika o zmiennej długości"
+msgstr "zezwolenie na u¿ycie poleceñ karty administratora"
 
 msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Wywołanie: scdaemon [opcje] (-h podaje pomoc)"
+msgstr "Wywo³anie: scdaemon [opcje] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
 "Smartcard daemon for GnuPG\n"
 msgstr ""
-"Składnia: scdaemon [opcje] [polecenie [argumenty]]\n"
+"Sk³adnia: scdaemon [opcje] [polecenie [argumenty]]\n"
 "Demon kart procesorowych dla GnuPG\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
-msgstr "proszę użyć opcji ,,--daemon'' do uruchomienia programu w tle\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
+msgstr "proszê u¿yæ opcji ,,--daemon'' do uruchomienia programu w tle\n"
 
 #, c-format
 msgid "handler for fd %d started\n"
-msgstr "obsługa fd %d uruchomiona\n"
+msgstr "obs³uga fd %d uruchomiona\n"
 
 #, c-format
 msgid "handler for fd %d terminated\n"
-msgstr "obsługa fd %d zakończona\n"
+msgstr "obs³uga fd %d zakoñczona\n"
 
 #, c-format
 msgid "invalid radix64 character %02x skipped\n"
-msgstr "niewłaściwy znak formatu radix64 %02x został pominięty\n"
+msgstr "niew³a¶ciwy znak formatu radix64 %02x zosta³ pominiêty\n"
 
 #, c-format
 msgid "failed to proxy %s inquiry to client\n"
-msgstr "nie udało się przekazać zapytania %s do klienta\n"
+msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "dirmngr nie działa - uruchamianie ,,%s''\n"
+msgid "no running dirmngr - starting '%s'\n"
+msgstr "dirmngr nie dzia³a - uruchamianie ,,%s''\n"
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "zły format zmiennej środowiskowej DIRMNGR_INFO\n"
+msgstr "z³y format zmiennej ¶rodowiskowej DIRMNGR_INFO\n"
 
 #, c-format
 msgid "dirmngr protocol version %d is not supported\n"
-msgstr "wersja %d protokołu dirmngr nie jest obsługiwana\n"
+msgstr "wersja %d protoko³u dirmngr nie jest obs³ugiwana\n"
 
 msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr "nie można połączyć się z dirmngr - próba fallbacku\n"
+msgstr "nie mo¿na po³±czyæ siê z dirmngr - próba fallbacku\n"
 
 #, c-format
 msgid "validation model requested by certificate: %s"
-msgstr "model poprawności żądany przez certyfikat: %s"
+msgstr "model poprawno¶ci ¿±dany przez certyfikat: %s"
 
 msgid "chain"
-msgstr "łańcuchowy"
+msgstr "³añcuchowy"
 
 msgid "shell"
-msgstr "powłokowy"
+msgstr "pow³okowy"
 
 #, c-format
 msgid "critical certificate extension %s is not supported"
-msgstr "krytyczne rozszerzenie certyfikatu %s nie jest obsługiwane"
+msgstr "krytyczne rozszerzenie certyfikatu %s nie jest obs³ugiwane"
 
 msgid "issuer certificate is not marked as a CA"
 msgstr "wystawca certyfikatu nie jest oznaczony jako CA"
@@ -5752,8 +5598,8 @@ msgid "critical marked policy without configured policies"
 msgstr "polityka oznaczona jako krytyczna bez skonfigurowanych polityk"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
-msgstr "nie udało się otworzyć ,,%s'': %s\n"
+msgid "failed to open '%s': %s\n"
+msgstr "nie uda³o siê otworzyæ ,,%s'': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
 msgstr "uwaga: niekrytyczna polityka certyfikatu niedozwolona"
@@ -5762,77 +5608,77 @@ msgid "certificate policy not allowed"
 msgstr "polityka certyfikatu niedozwolona"
 
 msgid "looking up issuer at external location\n"
-msgstr "poszukiwanie wystawcy na zewnątrz\n"
+msgstr "poszukiwanie wystawcy na zewn±trz\n"
 
 #, c-format
 msgid "number of issuers matching: %d\n"
-msgstr "liczba pasujących wystawców: %d\n"
+msgstr "liczba pasuj±cych wystawców: %d\n"
 
+#, fuzzy
 msgid "looking up issuer from the Dirmngr cache\n"
-msgstr "poszukiwanie wystawcy w pamięci podręcznej Dirmngr\n"
+msgstr "poszukiwanie wystawcy na zewn±trz\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "number of matching certificates: %d\n"
-msgstr "liczba pasujących certyfikatów: %d\n"
+msgstr "b³±d importu certyfikatu: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "dirmngr cache-only key lookup failed: %s\n"
-msgstr ""
-"wyszukiwanie klucza tylko w pamięci podręcznej dirmngr nie powiodło się: %s\n"
+msgstr "zaciemnienie klucza nie powiod³o siê: %s\n"
 
-msgid "failed to allocate keyDB handle\n"
-msgstr "nie udało się przydzielić uchwytu keyDB\n"
+msgid "failed to allocated keyDB handle\n"
+msgstr "nie uda³o siê przydzieliæ uchwytu keyDB\n"
 
 msgid "certificate has been revoked"
-msgstr "certyfikat został unieważniony"
+msgstr "certyfikat zosta³ uniewa¿niony"
 
 msgid "the status of the certificate is unknown"
 msgstr "status certyfikatu jest nieznany"
 
 msgid "please make sure that the \"dirmngr\" is properly installed\n"
-msgstr "proszę upewnić się, że ,,dirmngr'' jest poprawnie zainstalowany\n"
+msgstr "proszê upewniæ siê, ¿e ,,dirmngr'' jest poprawnie zainstalowany\n"
 
 #, c-format
 msgid "checking the CRL failed: %s"
-msgstr "sprawdzenie CRL nie powiodło się: %s"
+msgstr "sprawdzenie CRL nie powiod³o siê: %s"
 
 #, c-format
 msgid "certificate with invalid validity: %s"
-msgstr "certyfikat o nieważnej ważności: %s"
+msgstr "certyfikat o niewa¿nej wa¿no¶ci: %s"
 
 msgid "certificate not yet valid"
-msgstr "certyfikat jeszcze nie jest ważny"
+msgstr "certyfikat jeszcze nie jest wa¿ny"
 
 msgid "root certificate not yet valid"
-msgstr "certyfikat główny jeszcze nie jest ważny"
+msgstr "certyfikat g³ówny jeszcze nie jest wa¿ny"
 
 msgid "intermediate certificate not yet valid"
-msgstr "certyfikat pośredni jeszcze nie jest ważny"
+msgstr "certyfikat po¶redni jeszcze nie jest wa¿ny"
 
 msgid "certificate has expired"
-msgstr "certyfikat wygasł"
+msgstr "certyfikat wygas³"
 
 msgid "root certificate has expired"
-msgstr "certyfikat główny wygasł"
+msgstr "certyfikat g³ówny wygas³"
 
 msgid "intermediate certificate has expired"
-msgstr "certyfikat pośredni wygasł"
+msgstr "certyfikat po¶redni wygas³"
 
 #, c-format
 msgid "required certificate attributes missing: %s%s%s"
-msgstr "brak wymaganych atrybutów certyfikatu: %s%s%s"
+msgstr "brak wymaganych atrybutów certyfikatu: %s%s%s"
 
 msgid "certificate with invalid validity"
-msgstr "certyfikat o nieważnej ważności"
+msgstr "certyfikat o niewa¿nej wa¿no¶ci"
 
 msgid "signature not created during lifetime of certificate"
-msgstr "podpis nie utworzony w czasie życia certyfikatu"
+msgstr "podpis nie utworzony w czasie ¿ycia certyfikatu"
 
 msgid "certificate not created during lifetime of issuer"
-msgstr "certyfikat nie utworzony w czasie życia wystawcy"
+msgstr "certyfikat nie utworzony w czasie ¿ycia wystawcy"
 
 msgid "intermediate certificate not created during lifetime of issuer"
-msgstr "pośredni certyfikat nie utworzony w czasie życia wystawcy"
+msgstr "po¶redni certyfikat nie utworzony w czasie ¿ycia wystawcy"
 
 msgid "  (  signature created at "
 msgstr "  (  podpis utworzony "
@@ -5841,79 +5687,79 @@ msgid "  (certificate created at "
 msgstr "  (certyfikat utworzony "
 
 msgid "  (certificate valid from "
-msgstr "  (certyfikat ważny od "
+msgstr "  (certyfikat wa¿ny od "
 
 msgid "  (     issuer valid from "
-msgstr "  (     wystawca ważny od "
+msgstr "  (     wystawca wa¿ny od "
 
 #, c-format
 msgid "fingerprint=%s\n"
 msgstr "odcisk=%s\n"
 
 msgid "root certificate has now been marked as trusted\n"
-msgstr "główny certyfikat nie został oznaczony jako zaufany\n"
+msgstr "g³ówny certyfikat nie zosta³ oznaczony jako zaufany\n"
 
 msgid "interactive marking as trusted not enabled in gpg-agent\n"
-msgstr "interaktywne oznaczanie zaufania nie włączone w gpg-agencie\n"
+msgstr "interaktywne oznaczanie zaufania nie w³±czone w gpg-agencie\n"
 
 msgid "interactive marking as trusted disabled for this session\n"
-msgstr "interaktywne oznaczanie zaufania wyłączone dla tej sesji\n"
+msgstr "interaktywne oznaczanie zaufania wy³±czone dla tej sesji\n"
 
 msgid "WARNING: creation time of signature not known - assuming current time"
-msgstr "UWAGA: czas utworzenia podpisu nie jest znany - przyjęto czas bieżący"
+msgstr "UWAGA: czas utworzenia podpisu nie jest znany - przyjêto czas bie¿±cy"
 
 msgid "no issuer found in certificate"
 msgstr "nie znaleziono wystawcy w certyfikacie"
 
 msgid "self-signed certificate has a BAD signature"
-msgstr "własnoręcznie podpisany certyfikat ma ZŁY podpis"
+msgstr "w³asnorêcznie podpisany certyfikat ma Z£Y podpis"
 
 msgid "root certificate is not marked trusted"
-msgstr "główny certyfikat nie jest oznaczony jako zaufany"
+msgstr "g³ówny certyfikat nie jest oznaczony jako zaufany"
 
 #, c-format
 msgid "checking the trust list failed: %s\n"
-msgstr "sprawdzenie listy zaufania nie powiodło się: %s\n"
+msgstr "sprawdzenie listy zaufania nie powiod³o siê: %s\n"
 
 msgid "certificate chain too long\n"
-msgstr "łańcuch certyfikatów zbyt długi\n"
+msgstr "³añcuch certyfikatów zbyt d³ugi\n"
 
 msgid "issuer certificate not found"
 msgstr "nie znaleziono wystawcy certyfikatu"
 
 msgid "certificate has a BAD signature"
-msgstr "certyfikat ma ZŁY podpis"
+msgstr "certyfikat ma Z£Y podpis"
 
 msgid "found another possible matching CA certificate - trying again"
-msgstr "znaleziono inny być może pasujący certyfikat CA - ponawianie próby"
+msgstr "znaleziono inny byæ mo¿e pasuj±cy certyfikat CA - ponawianie próby"
 
 #, c-format
 msgid "certificate chain longer than allowed by CA (%d)"
-msgstr "łańcuch certyfikatów dłuższy niż zezwala CA (%d)"
+msgstr "³añcuch certyfikatów d³u¿szy ni¿ zezwala CA (%d)"
 
 msgid "certificate is good\n"
 msgstr "certyfikat jest dobry\n"
 
 msgid "intermediate certificate is good\n"
-msgstr "certyfikat pośredni jest dobry\n"
+msgstr "certyfikat poredni jest dobry\n"
 
 msgid "root certificate is good\n"
-msgstr "certyfikat główny jest dobry\n"
+msgstr "certyfikat g³ówny jest dobry\n"
 
 msgid "switching to chain model"
-msgstr "przełączanie do modelu łańcuchowego"
+msgstr "prze³±czanie do modelu ³añcuchowego"
 
 #, c-format
 msgid "validation model used: %s"
-msgstr "użyty model poprawności: %s"
+msgstr "u¿yty model poprawno¶ci: %s"
 
 #, c-format
 msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "Klucz %s używa niebezpiecznego (%u-bitowego) skrótu\n"
+msgstr "Klucz %s u¿ywa niebezpiecznego (%u-bitowego) skrótu\n"
 
 #, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
-msgstr "skrót %u-bitowy nie jest poprawny dla %u-bitowego klucza %s\n"
+msgstr "skrót %u-bitowy nie jest poprawny dla %u-bitowego klucza %s\n"
 
 msgid "(this is the MD2 algorithm)\n"
 msgstr "(to jest algorytm MD2)\n"
@@ -5922,18 +5768,18 @@ msgid "none"
 msgstr "brak"
 
 msgid "[Error - invalid encoding]"
-msgstr "[Błąd - niewłaściwe kodowanie]"
+msgstr "[B³±d - niew³a¶ciwe kodowanie]"
 
 msgid "[Error - out of core]"
-msgstr "[Błąd - brak pamięci]"
+msgstr "[B³±d - brak pamiêci]"
 
 msgid "[Error - No name]"
-msgstr "[Błąd - Brak nazwy]"
+msgstr "[B³±d - Brak nazwy]"
 
 msgid "[Error - invalid DN]"
-msgstr "[Błąd - niewłaściwe DN]"
+msgstr "[B³±d - niew³a¶ciwe DN]"
 
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "Please enter the passphrase to unlock the secret key for the X.509 "
 "certificate:\n"
@@ -5941,218 +5787,225 @@ msgid ""
 "S/N %s, ID 0x%08lX,\n"
 "created %s, expires %s.\n"
 msgstr ""
-"Proszę wprowadzić hasło aby odbezpieczyć klucz tajny certyfikatu X.509:\n"
+"Proszê wprowadziæ has³o aby odbezpieczyæ klucz tajny dla:\n"
 ",,%s''\n"
-"S/N %s, ID 0x%08lX,\n"
-"stworzony %s, wygasa %s.\n"
+"S/N %s, ID 0x%08lX, stworzony %s"
 
 msgid "no key usage specified - assuming all usages\n"
 msgstr ""
-"nie określono sposobu wykorzystania klucza - przyjęto wszystkie sposoby\n"
+"nie okre¶lono sposobu wykorzystania klucza - przyjêto wszystkie sposoby\n"
 
 #, c-format
 msgid "error getting key usage information: %s\n"
-msgstr "błąd podczas pobierania informacji o wykorzystaniu klucza: %s\n"
+msgstr "b³±d podczas pobierania informacji o wykorzystaniu klucza: %s\n"
 
-msgid "certificate should not have been used for certification\n"
-msgstr "certyfikat nie powinien być używany do poświadczania\n"
+msgid "certificate should have not been used for certification\n"
+msgstr "certyfikat nie powinien byæ u¿ywany do po¶wiadczania\n"
 
-msgid "certificate should not have been used for OCSP response signing\n"
-msgstr "certyfikat nie powinien być używany do podpisywania odpowiedzi OCSP\n"
+msgid "certificate should have not been used for OCSP response signing\n"
+msgstr "certyfikat nie powinien byæ u¿ywany do podpisywania odpowiedzi OCSP\n"
 
-msgid "certificate should not have been used for encryption\n"
-msgstr "certyfikat nie powinien być używany do szyfrowania\n"
+msgid "certificate should have not been used for encryption\n"
+msgstr "certyfikat nie powinien byæ u¿ywany do szyfrowania\n"
 
-msgid "certificate should not have been used for signing\n"
-msgstr "certyfikat nie powinien być używany do podpisywania\n"
+msgid "certificate should have not been used for signing\n"
+msgstr "certyfikat nie powinien byæ u¿ywany do podpisywania\n"
 
 msgid "certificate is not usable for encryption\n"
-msgstr "certyfikat nie nadaje się do szyfrowania\n"
+msgstr "certyfikat nie nadaje siê do szyfrowania\n"
 
 msgid "certificate is not usable for signing\n"
-msgstr "certyfikat nie nadaje się do podpisywania\n"
+msgstr "certyfikat nie nadaje siê do podpisywania\n"
 
 #, c-format
 msgid "line %d: invalid algorithm\n"
-msgstr "linia %d: niewłaściwy algorytm\n"
+msgstr "linia %d: niew³a¶ciwy algorytm\n"
 
 #, c-format
 msgid "line %d: invalid key length %u (valid are %d to %d)\n"
-msgstr "linia %d: niewłaściwa długość klucza %u (poprawne są od %d do %d)\n"
+msgstr "linia %d: niew³a¶ciwa d³ugo¶æ klucza %u (poprawne s± od %d do %d)\n"
 
 #, c-format
 msgid "line %d: no subject name given\n"
 msgstr "linia %d: nie podano nazwy przedmiotu\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
-msgstr "linia %d: niewłaściwa etykieta nazwy przedmiotu ,,%.*s''\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
+msgstr "linia %d: niew³a¶ciwa etykieta nazwy przedmiotu ,,%.*s''\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
-msgstr "linia %d: niewłaściwa nazwa przedmiotu ,,%s'' na pozycji %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
+msgstr "linia %d: niew³a¶ciwa nazwa przedmiotu ,,%s'' na pozycji %d\n"
 
 #, c-format
 msgid "line %d: not a valid email address\n"
 msgstr "linia %d: niepoprawny adres e-mail\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
-msgstr "linia %d: błąd odczytu klucza ,,%s'' z karty: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
+msgstr "linia %d: b³±d odczytu klucza ,,%s'' z karty: %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
-msgstr "linia %d: błąd pobierania klucza z uchwytu ,,%s'': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
+msgstr "linia %d: b³±d pobierania klucza z uchwytu ,,%s'': %s\n"
 
 #, c-format
 msgid "line %d: key generation failed: %s <%s>\n"
-msgstr "linia %d: generowanie klucza nie powiodło się: %s <%s>\n"
+msgstr "linia %d: generowanie klucza nie powiod³o siê: %s <%s>\n"
 
 msgid ""
 "To complete this certificate request please enter the passphrase for the key "
 "you just created once more.\n"
 msgstr ""
-"Aby zakończyć to żądanie certyfikatu proszę wprowadzić jeszcze raz hasło dla "
-"utworzonego klucza.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA\n"
-msgstr "   (%d) RSA\n"
+msgstr "   (%d) RSA (tylko do podpisywania)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) Existing key\n"
-msgstr "   (%d) Istniejący klucz\n"
+msgstr "   (2) Klucz do szyfrowania\n"
 
 #, c-format
 msgid "   (%d) Existing key from card\n"
-msgstr "   (%d) Istniejący klucz z karty\n"
+msgstr ""
 
+#, fuzzy
 msgid "Enter the keygrip: "
-msgstr "Uchwyt klucza: "
+msgstr "Adnotacje: "
 
 msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Nieprawidłowy uchwyt klucza (oczekiwano 40 cyfr szesnastkowych)\n"
+msgstr ""
 
+#, fuzzy
 msgid "No key with this keygrip\n"
-msgstr "Brak klucza o tym uchwycie\n"
+msgstr "Brak podklucza o numerze %d.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading the card: %s\n"
-msgstr "błąd odczytu karty: %s\n"
+msgstr "%s: b³±d odczytu pustego wpisu: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Serial number of the card: %s\n"
-msgstr "Numer seryjny karty: %s\n"
+msgstr "b³±d pobierania numeru seryjnego karty: %s\n"
 
+#, fuzzy
 msgid "Available keys:\n"
-msgstr "Dostępne klucze:\n"
+msgstr "wy³±czenie klucza z u¿ycia"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Possible actions for a %s key:\n"
-msgstr "Możliwe akcje dla klucza %s:\n"
+msgstr "Mo¿liwe akcje dla klucza %s: "
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) sign, encrypt\n"
-msgstr "   (%d) podpisywanie, szyfrowanie\n"
+msgstr "   (%d) DSA (tylko do podpisywania)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) sign\n"
-msgstr "   (%d) podpisywanie\n"
+msgstr "   (%d) DSA (tylko do podpisywania)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) encrypt\n"
-msgstr "   (%d) szyfrowanie\n"
+msgstr "   (%d) RSA (tylko do szyfrowania)\n"
 
 msgid "Enter the X.509 subject name: "
-msgstr "Nazwa przedmiotu X.509: "
+msgstr ""
 
+#, fuzzy
 msgid "No subject name given\n"
-msgstr "Nie podano nazwy przedmiotu\n"
+msgstr "linia %d: nie podano nazwy przedmiotu\n"
 
-#, c-format
-msgid "Invalid subject name label `%.*s'\n"
-msgstr "Nieprawidłowa etykieta nazwy przedmiotu ,,%.*s''\n"
+#, fuzzy, c-format
+msgid "Invalid subject name label '%.*s'\n"
+msgstr "linia %d: niew³a¶ciwa etykieta nazwy przedmiotu ,,%.*s''\n"
 
 #. TRANSLATORS: The 22 in the second string is the
 #. length of the first string up to the "%s".  Please
 #. adjust it do the length of your translation.  The
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
-#, c-format
-msgid "Invalid subject name `%s'\n"
-msgstr "Nieprawidłowa nazwa przedmiotu ,,%s''\n"
+#, fuzzy, c-format
+msgid "Invalid subject name '%s'\n"
+msgstr "linia %d: niew³a¶ciwa etykieta nazwy przedmiotu ,,%.*s''\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
-msgstr "33"
+msgstr ""
 
+#, fuzzy
 msgid "Enter email addresses"
-msgstr "Adresy poczty elektronicznej"
+msgstr "Adres poczty elektronicznej: "
 
+#, fuzzy
 msgid " (end with an empty line):\n"
-msgstr " (pusta linia oznacza koniec):\n"
+msgstr ""
+"\n"
+"Identyfikator u¿ytkownika (pusta linia oznacza koniec): "
 
+#, fuzzy
 msgid "Enter DNS names"
-msgstr "Nazwy DNS"
+msgstr "Nazwa pliku"
 
+#, fuzzy
 msgid " (optional; end with an empty line):\n"
-msgstr " (opcjonalne; pusta linia oznacza koniec):\n"
+msgstr "Wprowad¼ opis (nieobowi±zkowy) i zakoñcz go pust± lini±:\n"
 
 msgid "Enter URIs"
-msgstr "URI"
+msgstr ""
 
 msgid "Parameters to be used for the certificate request:\n"
-msgstr "Parametry, które będą użyte przy żądaniu certyfikatu:\n"
+msgstr ""
 
 msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr "Tworzenie żądania certyfikatu. Może to chwilę potrwać...\n"
+msgstr ""
 
 msgid "Ready.  You should now send this request to your CA.\n"
 msgstr ""
-"Gotowe. Teraz należy wysłać to żądanie do własnego centrum certyfikacji.\n"
 
+#, fuzzy
 msgid "resource problem: out of core\n"
-msgstr "problem z zasobami: brak pamięci\n"
+msgstr "[B³±d - brak pamiêci]"
 
 msgid "(this is the RC2 algorithm)\n"
 msgstr "(to jest algorytm RC2)\n"
 
 msgid "(this does not seem to be an encrypted message)\n"
-msgstr "(to nie wygląda na zaszyfrowaną wiadomość)\n"
+msgstr "(to nie wygl±da na zaszyfrowan± wiadomo¶æ)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "nie znaleziono certyfikatu ,,%s'': %s\n"
 
 #, c-format
 msgid "error locking keybox: %s\n"
-msgstr "błąd blokowania keyboksa: %s\n"
+msgstr "b³±d blokowania keyboksa: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
-msgstr "powtórzony certyfikat ,,%s'' usunięty\n"
+msgid "duplicated certificate '%s' deleted\n"
+msgstr "powtórzony certyfikat ,,%s'' usuniêty\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
-msgstr "certyfikat ,,%s'' usunięty\n"
+msgid "certificate '%s' deleted\n"
+msgstr "certyfikat ,,%s'' usuniêty\n"
 
 #, c-format
 msgid "deleting certificate \"%s\" failed: %s\n"
-msgstr "usunięcie certyfikatu ,,%s'' nie powiodło się: %s\n"
+msgstr "usuniêcie certyfikatu ,,%s'' nie powiod³o siê: %s\n"
 
 msgid "no valid recipients given\n"
-msgstr "nie podano poprawnych adresatów\n"
+msgstr "nie podano poprawnych adresatów\n"
 
 msgid "list external keys"
-msgstr "wypisanie kluczy zewnętrznych"
+msgstr "wypisanie kluczy zewnêtrznych"
 
 msgid "list certificate chain"
-msgstr "wypisanie łańcucha certyfikatów"
+msgstr "wypisanie ³añcucha certyfikatów"
 
 msgid "import certificates"
-msgstr "import certyfikatów"
+msgstr "import certyfikatów"
 
 msgid "export certificates"
-msgstr "eksport certyfikatów"
+msgstr "eksport certyfikatów"
 
 msgid "register a smartcard"
 msgstr "zarejestrowanie karty procesorowej"
@@ -6161,172 +6014,187 @@ msgid "pass a command to the dirmngr"
 msgstr "przekazanie polecenia do dirmngr"
 
 msgid "invoke gpg-protect-tool"
-msgstr "wywołanie gpg-protect-tool"
+msgstr "wywo³anie gpg-protect-tool"
+
+msgid "change a passphrase"
+msgstr "zmiana has³a"
 
 msgid "create base-64 encoded output"
-msgstr "tworzenie wyjścia zakodowanego base-64"
+msgstr "tworzenie wyjcia zakodowanego base-64"
 
 msgid "assume input is in PEM format"
-msgstr "przyjęcie wejścia w formacie PEM"
+msgstr "przyjêcie wej¶cia w formacie PEM"
 
 msgid "assume input is in base-64 format"
-msgstr "przyjęcie wejścia w formacie base-64"
+msgstr "przyjêcie wej¶cia w formacie base-64"
 
 msgid "assume input is in binary format"
-msgstr "przyjęcie wejścia w formacie binarnym"
+msgstr "przyjêcie wej¶cia w formacie binarnym"
 
 msgid "use system's dirmngr if available"
-msgstr "użycie systemowego dirmngr jeśli jest dostępny"
+msgstr "u¿ycie systemowego dirmngr je¶li jest dostêpny"
 
 msgid "never consult a CRL"
-msgstr "pominięcie CRL"
+msgstr "pominiêcie CRL"
 
 msgid "check validity using OCSP"
-msgstr "sprawdzenie poprawności przy użyciu OCSP"
+msgstr "sprawdzenie poprawno¶ci przy u¿yciu OCSP"
 
 msgid "|N|number of certificates to include"
-msgstr "|N|liczba certyfikatów do dołączenia"
+msgstr "|N|liczba certyfikatów do do³±czenia"
 
 msgid "|FILE|take policy information from FILE"
 msgstr "|PLIK|pobranie informacji o polityce z PLIKU"
 
 msgid "do not check certificate policies"
-msgstr "nie sprawdzanie polityk certyfikatów"
+msgstr "nie sprawdzanie polityk certyfikatów"
 
 msgid "fetch missing issuer certificates"
-msgstr "pobranie brakujących certyfikatów wystawców"
+msgstr "pobranie brakuj±cych certyfikatów wystawców"
 
 msgid "don't use the terminal at all"
-msgstr "nie używanie w ogóle terminala"
+msgstr "nie u¿ywanie w ogóle terminala"
 
+#, fuzzy
 msgid "|FILE|write a server mode log to FILE"
-msgstr "|PLIK|zapisanie logów trybu serwerowego do PLIKU"
+msgstr "|PLIK|zapisanie logów trybu serwerowego do PLIKu"
 
+#, fuzzy
 msgid "|FILE|write an audit log to FILE"
-msgstr "|PLIK|zapisanie logów audytowych do PLIKU"
+msgstr "|PLIK|zapisanie logów trybu serwerowego do PLIKu"
 
 msgid "batch mode: never ask"
-msgstr "tryb wsadowy: bez żadnych pytań"
+msgstr "tryb wsadowy: bez ¿adnych pytañ"
 
 msgid "assume yes on most questions"
-msgstr "przyjęcie odpowiedzi ,,tak'' na większość pytań"
+msgstr "przyjêcie odpowiedzi ,,tak'' na wiêkszo¶æ pytañ"
 
 msgid "assume no on most questions"
-msgstr "przyjęcie odpowiedzi ,,nie'' na większość pytań"
+msgstr "przyjêcie odpowiedzi ,,nie'' na wiêkszo¶æ pytañ"
 
+#, fuzzy
 msgid "|FILE|add keyring to the list of keyrings"
-msgstr "|PLIK|dodanie tego zbioru kluczy do listy zbiorów kluczy"
+msgstr "dodanie tego zbioru kluczy do listy zbiorów kluczy"
 
+#, fuzzy
 msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|UŻYTKOWNIK|użycie tego identyfikatora jako domyślnego klucza tajnego"
+msgstr "|NAZWA|u¿ycie NAZWY jako domy¶lnego klucza tajnego"
 
+#, fuzzy
 msgid "|SPEC|use this keyserver to lookup keys"
-msgstr "|SPEC|użycie tego serwera do wyszukiwania kluczy"
+msgstr "|HOST|u¿ycie tego serwera do wyszukiwania kluczy"
 
 msgid "|NAME|use cipher algorithm NAME"
-msgstr "|NAZWA|użycie tego algorytmu szyfrowania NAZWA"
+msgstr "|NAZWA|u¿ycie tego algorytmu szyfrowania NAZWA"
 
 msgid "|NAME|use message digest algorithm NAME"
-msgstr "|NAZWA|użycie tego algorytmu skrótu wiadomości"
+msgstr "|NAZWA|u¿ycie tego algorytmu skrótu wiadomo¶ci"
 
 msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Wywołanie: gpgsm [opcje] [pliki] (-h podaje pomoc)"
+msgstr "Wywo³anie: gpgsm [opcje] [pliki] (-h podaje pomoc)"
 
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
-"Składnia: gpgsm [opcje] [pliki]\n"
-"Podpisywanie, sprawdzanie podpisów, szyfrowanie, rozszyfrowywanie z użyciem "
-"S/MIME\n"
-"Domyślnie wykonywana operacja zależy od danych wejściowych\n"
+"Sk³adnia: gpgsm [opcje] [pliki]\n"
+"podpisywanie, sprawdzanie podpisów, szyfrowanie, deszyfrowanie z u¿yciem S/"
+"MIME\n"
+"domy¶lnie wykonywana operacja zale¿y od danych wej¶ciowych\n"
 
 msgid "usage: gpgsm [options] "
-msgstr "wywołanie: gpgsm [opcje]"
+msgstr "wywo³anie: gpgsm [opcje]"
 
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
-msgstr "UWAGA: nie można zaszyfrować do ,,%s'': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
+msgstr "UWAGA: nie mo¿na zaszyfrowaæ do ,,%s'': %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
-msgstr "nieznany model poprawności ,,%s''\n"
+msgid "unknown validation model '%s'\n"
+msgstr "nieznany model poprawnoci ,,%s''\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%u: no hostname given\n"
-msgstr "%s:%u: nie podano nazwy hosta\n"
+msgstr "linia %d: nie podano nazwy przedmiotu\n"
 
 #, c-format
 msgid "%s:%u: password given without user\n"
-msgstr "%s:%u: podano hasło bez użytkownika\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "%s:%u: skipping this line\n"
-msgstr "%s:%u: linia pominięta\n"
+msgstr "  p = pominiêcie tego klucza\n"
 
+#, fuzzy
 msgid "could not parse keyserver\n"
-msgstr "niezrozumiały adres serwera kluczy\n"
+msgstr "niezrozumia³y URL serwera kluczy\n"
 
 msgid "WARNING: running with faked system time: "
-msgstr "OSTRZEŻENIE: działanie z fałszywym czasem systemowym: "
+msgstr "OSTRZE¯ENIE: dzia³anie z fa³szywym czasem systemowym: "
 
 #, c-format
-msgid "importing common certificates `%s'\n"
-msgstr "import wspólnych certyfikatów ,,%s''\n"
+msgid "importing common certificates '%s'\n"
+msgstr "import wspólnych certyfikatów ,,%s''\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
-msgstr "nie można podpisać z użyciem ,,%s'': %s\n"
+msgid "can't sign using '%s': %s\n"
+msgstr "nie mo¿na podpisaæ z u¿yciem ,,%s'': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
-msgstr "błędne polecenie (nie ma polecenia domyślnego)\n"
+msgstr ""
 
 #, c-format
 msgid "total number processed: %lu\n"
-msgstr "całkowita liczba przetworzonych: %lu\n"
+msgstr "ca³kowita liczba przetworzonych: %lu\n"
 
 msgid "error storing certificate\n"
-msgstr "błąd zapisywania certyfikatu\n"
+msgstr "b³±d zapisywania certyfikatu\n"
 
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
-"podstawowe sprawdzenia certyikatu nie powiodły się - nie zaimportowany\n"
+"podstawowe sprawdzenia certyikatu nie powiod³y siê - nie zaimportowany\n"
+
+msgid "failed to allocate keyDB handle\n"
+msgstr "nie uda³o siê przydzieliæ uchwytu keyDB\n"
 
 #, c-format
 msgid "error getting stored flags: %s\n"
-msgstr "błąd pobierania zapisanych flag: %s\n"
+msgstr "b³±d pobierania zapisanych flag: %s\n"
 
 #, c-format
 msgid "error importing certificate: %s\n"
-msgstr "błąd importu certyfikatu: %s\n"
+msgstr "b³±d importu certyfikatu: %s\n"
 
 #, c-format
 msgid "error reading input: %s\n"
-msgstr "błąd odczytu wejścia: %s\n"
+msgstr "b³±d odczytu wej¶cia: %s\n"
 
 #, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "błąd tworzenia keyboksa ,,%s'': %s\n"
+msgid "error creating keybox '%s': %s\n"
+msgstr "b³±d tworzenia keyboksa ,,%s'': %s\n"
+
+msgid "you may want to start the gpg-agent first\n"
+msgstr "mo¿na najpierw uruchomiæ najpierw gpg-agenta\n"
 
 #, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "keybox ,,%s'' utworzony\n"
 
 msgid "failed to get the fingerprint\n"
-msgstr "nie udało się pobrać odcisku\n"
+msgstr "nie uda³o siê pobraæ odcisku\n"
 
 #, c-format
 msgid "problem looking for existing certificate: %s\n"
-msgstr "problem odszukaniem istniejącego certyfikatu: %s\n"
+msgstr "problem odszukaniem istniej±cego certyfikatu: %s\n"
 
 #, c-format
 msgid "error finding writable keyDB: %s\n"
-msgstr "błąd podczas szukania zapisywalnego keyDB: %s\n"
+msgstr "b³±d podczas szukania zapisywalnego keyDB: %s\n"
 
 #, c-format
 msgid "error storing certificate: %s\n"
-msgstr "błąd zapisywania certyfikatu: %s\n"
+msgstr "b³±d zapisywania certyfikatu: %s\n"
 
 #, c-format
 msgid "problem re-searching certificate: %s\n"
@@ -6334,22 +6202,23 @@ msgstr "problem z ponownym odszukaniem certyfikatu: %s\n"
 
 #, c-format
 msgid "error storing flags: %s\n"
-msgstr "błąd zapisywania flag: %s\n"
+msgstr "b³±d zapisywania flag: %s\n"
 
+#, fuzzy
 msgid "Error - "
-msgstr "Błąd - "
+msgstr "[B³±d - Brak nazwy]"
 
 msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
-"GPG_TTY nie zostało ustawione - użycie być może nieprawidłowego domyślnego\n"
+"GPG_TTY nie zosta³o ustawione - u¿ycie byæ mo¿e nieprawid³owego domy¶lnego\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "niewłaściwie sformatowany odcisk w ,,%s'', w linii %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
+msgstr "niew³a¶ciwie sformatowany odcisk w ,,%s'', w linii %d\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "niewłaściwy kod kraju w ,,%s'', w linii %d\n"
+msgid "invalid country code in '%s', line %d\n"
+msgstr "niew³a¶ciwy kod kraju w ,,%s'', w linii %d\n"
 
 #, c-format
 msgid ""
@@ -6360,18 +6229,18 @@ msgid ""
 "\n"
 "%s%sAre you really sure that you want to do this?"
 msgstr ""
-"Ta operacja złoży podpis przy użyciu certyfikatu:\n"
+"Ta operacja z³o¿y podpis przy u¿yciu certyfikatu:\n"
 ",,%s''\n"
-"Utworzy to kwalifikowany podpis równoważny prawnie podpisowi odręcznemu.\n"
+"Utworzy to kwalifikowany podpis równowa¿ny prawnie podpisowi odrêcznemu.\n"
 "\n"
-"%s%sNa pewno chcesz to zrobić?"
+"%s%sNa pewno chcesz to zrobiæ?"
 
 msgid ""
 "Note, that this software is not officially approved to create or verify such "
 "signatures.\n"
 msgstr ""
-"Należy zauważyć, że to oprogramowaie nie jest oficjalnie zatwierdzone do "
-"tworzenia i sprawdzania takich podpisów.\n"
+"Nale¿y zauwa¿yæ, ¿e to oprogramowaie nie jest oficjalnie zatwierdzone do "
+"tworzenia i sprawdzania takich podpisów.\n"
 
 #, c-format
 msgid ""
@@ -6379,23 +6248,21 @@ msgid ""
 "\"%s\"\n"
 "Note, that this certificate will NOT create a qualified signature!"
 msgstr ""
-"Ta operacja złoży podpis przy użyciu certyfikatu:\n"
+"Ta operacja z³o¿y podpis przy u¿yciu certyfikatu:\n"
 ",,%s''\n"
-"Należy zauważyć, że ten certyfikat NIE utworzy kwalifikowanego podpisu!"
+"Nale¿y zauwa¿yæ, ¿e ten certyfikat NIE utworzy kwalifikowanego podpisu!"
 
-#, c-format
+#, fuzzy, c-format
 msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
-msgstr ""
-"algorytm skrótu %d (%s) dla podpisującego %d nie jest obsługiwany; użycie "
-"%s\n"
+msgstr "algorytm ochrony %d%s nie jest obs³ugiwany\n"
 
 #, c-format
 msgid "hash algorithm used for signer %d: %s (%s)\n"
-msgstr "algorytm skrótu użyty dla podpisującego %d: %s (%s)\n"
+msgstr ""
 
 #, c-format
 msgid "checking for qualified certificate failed: %s\n"
-msgstr "sprawdzenie certyfikatu kwalifikowanego nie powiodło się: %s\n"
+msgstr "sprawdzenie certyfikatu kwalifikowanego nie powiod³o siê: %s\n"
 
 msgid "Signature made "
 msgstr "Podpisano w "
@@ -6405,14 +6272,14 @@ msgstr "[nie podano daty]"
 
 #, c-format
 msgid " using certificate ID 0x%08lX\n"
-msgstr " przy użyciu certyfikatu o ID 0x%08lX\n"
+msgstr " przy u¿yciu certyfikatu o ID 0x%08lX\n"
 
 msgid ""
 "invalid signature: message digest attribute does not match computed one\n"
-msgstr "błędny podpis: atrybut skrótu wiadomości nie zgadza się z obliczonym\n"
+msgstr ""
 
 msgid "Good signature from"
-msgstr "Poprawny podpis złożony przez"
+msgstr "Poprawny podpis z³o¿ony przez"
 
 msgid "                aka"
 msgstr "                        alias"
@@ -6430,33 +6297,34 @@ msgid "decode received data lines"
 msgstr "dekodowanie otrzymanych linii danych"
 
 msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NAZWA|połączenie z gniazdem Assuan o tej nazwie"
+msgstr "|NAZWA|po³±czenie z gniazdem Assuan o tej nazwie"
 
 msgid "run the Assuan server given on the command line"
-msgstr "uruchomienie serwera Assuan podanego z linii poleceń"
+msgstr "uruchomienie serwera Assuan podanego z linii poleceñ"
 
 msgid "do not use extended connect mode"
-msgstr "nie używanie rozszerzonego trybu połączenia"
+msgstr "nie u¿ywanie rozszerzonego trybu po³±czenia"
 
+#, fuzzy
 msgid "|FILE|run commands from FILE on startup"
-msgstr "|PLIK|uruchomienie poleceń z PLIKU przy starcie"
+msgstr "|PLIK|odczyt opcji z PLIKU"
 
 msgid "run /subst on startup"
-msgstr "uruchomienie /subst przy starcie"
+msgstr ""
 
 msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Wywołanie: gpg-connect-agent [opcje] (-h podaje pomoc)"
+msgstr "Wywo³anie: gpg-connect-agent [opcje] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: gpg-connect-agent [options]\n"
 "Connect to a running agent and send commands\n"
 msgstr ""
-"Składnia: gpg-connect-agent [opcje]\n"
-"Połączenie z działającym agentem i wysyłanie poleceń\n"
+"Sk³adnia: gpg-connect-agent [opcje]\n"
+"Po³±czenie z dzia³aj±cym agentem i wysy³anie poleceñ\n"
 
 #, c-format
 msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr "opcja ,,%s'' wymaga programu i opcjonalnych argumentów\n"
+msgstr "opcja ,,%s'' wymaga programu i opcjonalnych argumentów\n"
 
 #, c-format
 msgid "option \"%s\" ignored due to \"%s\"\n"
@@ -6464,141 +6332,141 @@ msgstr "opcja ,,%s'' zignorowana z powodu ,,%s''\n"
 
 #, c-format
 msgid "receiving line failed: %s\n"
-msgstr "odbieranie linii nie powiodło się: %s\n"
+msgstr "odbieranie linii nie powiod³o siê: %s\n"
 
 msgid "line too long - skipped\n"
-msgstr "linia zbyt długa - pominięta\n"
+msgstr "linia zbyt d³uga - pominiêta\n"
 
 msgid "line shortened due to embedded Nul character\n"
-msgstr "linia skrócona z powodu osadzonego znaku Nul\n"
+msgstr "linia skrócona z powodu osadzonego znaku Nul\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "nieznane polecenie ,,%s''\n"
 
 #, c-format
 msgid "sending line failed: %s\n"
-msgstr "wysyłanie linii nie powiodło się: %s\n"
+msgstr "wysy³anie linii nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "error sending %s command: %s\n"
-msgstr "błąd wysyłania polecenia %s: %s\n"
+msgstr "b³±d wysy³ania polecenia %s: %s\n"
 
 #, c-format
 msgid "error sending standard options: %s\n"
-msgstr "błąd wysyłania standardowych opcji: %s\n"
+msgstr "b³±d wysy³ania standardowych opcji: %s\n"
 
 msgid "Options controlling the diagnostic output"
-msgstr "Opcje sterujące wyjściem diagnostycznym"
+msgstr "Opcje steruj±ce wyj¶ciem diagnostycznym"
 
 msgid "Options controlling the configuration"
-msgstr "Opcje sterujące konfiguracją"
+msgstr "Opcje steruj±ce konfiguracj±"
 
 msgid "Options useful for debugging"
 msgstr "Opcje przydatne do diagnostyki"
 
 msgid "|FILE|write server mode logs to FILE"
-msgstr "|PLIK|zapisanie logów trybu serwerowego do PLIKu"
+msgstr "|PLIK|zapisanie logów trybu serwerowego do PLIKu"
 
 msgid "Options controlling the security"
-msgstr "Opcje sterujące bezpieczeństwem"
+msgstr "Opcje steruj±ce bezpieczeñstwem"
 
 msgid "|N|expire SSH keys after N seconds"
 msgstr "|N|przedawnienie kluczy SSH po N sekundach"
 
 msgid "|N|set maximum PIN cache lifetime to N seconds"
 msgstr ""
-"|N|ustawienie maksymalnego czasu życia pamięci podręcznej PIN-ów na N sekund"
+"|N|ustawienie maksymalnego czasu ¿ycia pamiêci podrêcznej PIN-ów na N sekund"
 
 msgid "|N|set maximum SSH key lifetime to N seconds"
-msgstr "|N|ustawienie maksymalnego czasu życia kluczy SSH na N sekund"
+msgstr "|N|ustawienie maksymalnego czasu ¿ycia kluczy SSH na N sekund"
 
 msgid "Options enforcing a passphrase policy"
-msgstr "Opcje wymuszające politykę haseł"
+msgstr "Opcje wymuszaj±ce politykê hase³"
 
 msgid "do not allow to bypass the passphrase policy"
-msgstr "nie zezwalanie na pominięcie polityki haseł"
+msgstr "nie zezwalanie na pominiêcie polityki hase³"
 
 msgid "|N|set minimal required length for new passphrases to N"
-msgstr "|N|ustawienie minimalnej długości nowych haseł na N"
+msgstr "|N|ustawienie minimalnej d³ugo¶ci nowych hase³ na N"
 
 msgid "|N|require at least N non-alpha characters for a new passphrase"
-msgstr "|N|wymaganie przynajmniej N znaków niealfanumerycznych w nowym haśle"
+msgstr "|N|wymaganie przynajmniej N znaków niealfanumerycznych w nowym ha¶le"
 
 msgid "|FILE|check new passphrases against pattern in FILE"
-msgstr "|PLIK|sprawdzanie nowych haseł pod kątem wzorców z PLIKU"
+msgstr "|PLIK|sprawdzanie nowych hase³ pod k±tem wzorców z PLIKU"
 
 msgid "|N|expire the passphrase after N days"
-msgstr "|N|przedawnianie haseł po N dniach"
+msgstr "|N|przedawnianie hase³ po N dniach"
 
 msgid "do not allow the reuse of old passphrases"
-msgstr "nie zezwalanie na ponowne użycie starych haseł"
+msgstr "nie zezwalanie na ponowne u¿ycie starych hase³"
 
 msgid "|NAME|use NAME as default secret key"
-msgstr "|NAZWA|użycie NAZWY jako domyślnego klucza tajnego"
+msgstr "|NAZWA|u¿ycie NAZWY jako domy¶lnego klucza tajnego"
 
 msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|NAZWA|szyfrowanie także dla odbiorcy NAZWA"
+msgstr "|NAZWA|szyfrowanie tak¿e dla odbiorcy NAZWA"
 
 msgid "|SPEC|set up email aliases"
-msgstr "|SPEC|określ adres email"
+msgstr ""
 
 msgid "Configuration for Keyservers"
-msgstr "Konfiguracja dla serwerów kluczy"
+msgstr "Konfiguracja dla serwerów kluczy"
 
+#, fuzzy
 msgid "|URL|use keyserver at URL"
-msgstr "|URL|używaj serwera kluczy URL"
+msgstr "niezrozumia³y URL serwera kluczy\n"
 
 msgid "allow PKA lookups (DNS requests)"
-msgstr "zezwolenie na wyszukiwania PKA (żądania DNS)"
+msgstr "zezwolenie na wyszukiwania PKA (¿±dania DNS)"
 
 msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
 msgstr ""
-"|MECHANIZMY|wykorzystaj MECHANIZMY do wyszukiwania kluczy na podstawie "
-"adresów e-mail"
 
+#, fuzzy
 msgid "disable all access to the dirmngr"
-msgstr "zablokuj dostęp do dirmngr"
+msgstr "przekazanie polecenia do dirmngr"
 
 msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr "|NAZWA|użycie kodowania NAZWA dla haseł PKCS#12"
+msgstr "|NAZWA|u¿ycie kodowania NAZWA dla hase³ PKCS#12"
 
 msgid "do not check CRLs for root certificates"
-msgstr "nie sprawdzanie CRL dla głównych certyfikatów"
+msgstr "nie sprawdzanie CRL dla g³ównych certyfikatów"
 
 msgid "Options controlling the format of the output"
-msgstr "Opcje sterujące formatem wyjścia"
+msgstr "Opcje steruj±ce formatem wyj¶cia"
 
 msgid "Options controlling the interactivity and enforcement"
-msgstr "Opcje sterujące interaktywnością i wymuszaniem"
+msgstr "Opcje steruj±ce interaktywno¶ci± i wymuszaniem"
 
 msgid "Configuration for HTTP servers"
-msgstr "Konfiguracja dla serwerów HTTP"
+msgstr "Konfiguracja dla serwerów HTTP"
 
 msgid "use system's HTTP proxy setting"
-msgstr "użycie systemowego ustawienia proxy HTTP"
+msgstr "u¿ycie systemowego ustawienia proxy HTTP"
 
 msgid "Configuration of LDAP servers to use"
-msgstr "Konfiguracja używanych serwerów LDAP"
+msgstr "Konfiguracja u¿ywanych serwerów LDAP"
 
 msgid "LDAP server list"
-msgstr "lista serwerów LDAP"
+msgstr ""
 
 msgid "Configuration for OCSP"
 msgstr "Konfiguracja dla OCSP"
 
 #, c-format
 msgid "External verification of component %s failed"
-msgstr "Zewnętrzna weryfikacja komponentu %s nie powiodła się"
+msgstr ""
 
 msgid "Note that group specifications are ignored\n"
-msgstr "Uwaga, określenia grup są ignorowane\n"
+msgstr "Uwaga, okre¶lenia grup s± ignorowane\n"
 
 msgid "list all components"
-msgstr "lista wszystkich komponentów"
+msgstr "lista wszystkich komponentów"
 
 msgid "check all programs"
-msgstr "sprawdzenie wszystkich programów"
+msgstr "sprawdzenie wszystkich programów"
 
 msgid "|COMPONENT|list options"
 msgstr "|KOMPONENT|wypisanie opcji"
@@ -6606,39 +6474,41 @@ msgstr "|KOMPONENT|wypisanie opcji"
 msgid "|COMPONENT|change options"
 msgstr "|KOMPONENT|zmiana opcji"
 
+#, fuzzy
 msgid "|COMPONENT|check options"
-msgstr "|KOMPONENT|zaznaczenie opcji"
+msgstr "|KOMPONENT|zmiana opcji"
 
 msgid "apply global default values"
-msgstr "zastosowanie globalnych wartości domyślnych"
+msgstr "zastosowanie globalnych warto¶ci domy¶lnych"
 
 msgid "get the configuration directories for gpgconf"
-msgstr "katalogi konfiguracyjne programu gpgconf"
+msgstr ""
 
+#, fuzzy
 msgid "list global configuration file"
-msgstr "wyświetl globalny plik konfiguracyjny"
+msgstr "sprawdzenie globalnego pliku konfiguracyjnego"
 
 msgid "check global configuration file"
 msgstr "sprawdzenie globalnego pliku konfiguracyjnego"
 
 msgid "use as output file"
-msgstr "plik wyjściowy"
+msgstr "plik wyjciowy"
 
 msgid "activate changes at runtime, if possible"
-msgstr "uaktywnienie zmian w czasie działania o ile to możliwe"
+msgstr "uaktywnienie zmian w czasie dzia³ania o ile to mo¿liwe"
 
 msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Wywołanie: gpgconf [opcje] (-h podaje pomoc)"
+msgstr "Wywo³anie: gpgconf [opcje] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: gpgconf [options]\n"
 "Manage configuration options for tools of the GnuPG system\n"
 msgstr ""
-"Składnia: gpgconf [opcje]\n"
-"Zarządzanie opcjami konfiguracji dla narzędzi z systemu GnuPG\n"
+"Sk³adnia: gpgconf [opcje]\n"
+"Zarz±dzanie opcjami konfiguracji dla narzêdzi z systemu GnuPG\n"
 
 msgid "usage: gpgconf [options] "
-msgstr "wywołanie: gpgconf [opcje]"
+msgstr "wywo³anie: gpgconf [opcje]"
 
 msgid "Need one component argument"
 msgstr "Wymagany jest jeden argument komponentu"
@@ -6659,13 +6529,13 @@ msgstr ""
 " "
 
 msgid "decryption modus"
-msgstr "tryb rozszyfrowywania"
+msgstr "tryb deszyfrowania"
 
 msgid "encryption modus"
 msgstr "tryb szyfrowania"
 
 msgid "tool class (confucius)"
-msgstr "klasa narzędzia (confucius)"
+msgstr "klasa narzêdzia (confucius)"
 
 msgid "program filename"
 msgstr "nazwa programu"
@@ -6674,19 +6544,19 @@ msgid "secret key file (required)"
 msgstr "plik klucza tajnego (wymagany)"
 
 msgid "input file name (default stdin)"
-msgstr "nazwa pliku wejściowego (domyślnie standardowe wejście)"
+msgstr "nazwa pliku wej¶ciowego (domy¶lnie standardowe wej¶cie)"
 
 msgid "Usage: symcryptrun [options] (-h for help)"
-msgstr "Wywołanie: symcryptrun [opcje] (-h podaje pomoc)"
+msgstr "Wywo³anie: symcryptrun [opcje] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE "
 "[options...] COMMAND [inputfile]\n"
 "Call a simple symmetric encryption tool\n"
 msgstr ""
-"Składnia: symcryptrun --class KLASA --program PROGRAM --keyfile PLIK_KLUCZA "
-"[opcje...] POLECENIE [plik-weściowy]\n"
-"Wywołanie prostego narzędzia do szyfrowania symetrycznego\n"
+"Sk³adnia: symcryptrun --class KLASA --program PROGRAM --keyfile PLIK_KLUCZA "
+"[opcje...] POLECENIE [plik-weciowy]\n"
+"Wywo³anie prostego narzêdzia do szyfrowania symetrycznego\n"
 
 #, c-format
 msgid "%s on %s aborted with status %i\n"
@@ -6694,101 +6564,492 @@ msgstr "%s na %s przerwany ze stanem %i\n"
 
 #, c-format
 msgid "%s on %s failed with status %i\n"
-msgstr "%s na %s nie powiódł się ze stanem %i\n"
+msgstr "%s na %s nie powiód³ siê ze stanem %i\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
-msgstr "nie można utworzyć katalogu tymczasowego,,%s'': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
+msgstr "nie mo¿na utworzyæ katalogu tymczasowego,,%s'': %s\n"
 
 #, c-format
 msgid "could not open %s for writing: %s\n"
-msgstr "nie udało się otworzyć %s do zapisu: %s\n"
+msgstr "nie uda³o siê otworzyæ %s do zapisu: %s\n"
 
 #, c-format
 msgid "error writing to %s: %s\n"
-msgstr "błąd zapisu do %s: %s\n"
+msgstr "b³±d zapisu do %s: %s\n"
 
 #, c-format
 msgid "error reading from %s: %s\n"
-msgstr "błąd odczytu z %s: %s\n"
+msgstr "b³±d odczytu z %s: %s\n"
 
 #, c-format
 msgid "error closing %s: %s\n"
-msgstr "błąd zamykania %s: %s\n"
+msgstr "b³±d zamykania %s: %s\n"
 
 msgid "no --program option provided\n"
 msgstr "nie podano opcji --program\n"
 
 msgid "only --decrypt and --encrypt are supported\n"
-msgstr "obsługiwane są tylko --decrypt i --encrypt\n"
+msgstr "obs³ugiwane s± tylko --decrypt i --encrypt\n"
 
 msgid "no --keyfile option provided\n"
 msgstr "nie podano opcji --keyfile\n"
 
 msgid "cannot allocate args vector\n"
-msgstr "nie można przydzielić wektora args\n"
+msgstr "nie mo¿na przydzieliæ wektora args\n"
 
 #, c-format
 msgid "could not create pipe: %s\n"
-msgstr "nie udało się utworzyć potoku: %s\n"
+msgstr "nie uda³o siê utworzyæ potoku: %s\n"
 
 #, c-format
 msgid "could not create pty: %s\n"
-msgstr "nie udało się utworzyć pty: %s\n"
+msgstr "nie uda³o siê utworzyæ pty: %s\n"
 
 #, c-format
 msgid "could not fork: %s\n"
-msgstr "nie udało się wykonać fork: %s\n"
+msgstr "nie uda³o siê wykonaæ fork: %s\n"
 
 #, c-format
 msgid "execv failed: %s\n"
-msgstr "execv nie powiodło się: %s\n"
+msgstr "execv nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "select failed: %s\n"
-msgstr "select nie powiodło się: %s\n"
+msgstr "select nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "read failed: %s\n"
-msgstr "odczyt nie powiódł się: %s\n"
+msgstr "odczyt nie powiód³ siê: %s\n"
 
 #, c-format
 msgid "pty read failed: %s\n"
-msgstr "odczyt pty nie powiódł się: %s\n"
+msgstr "odczyt pty nie powiód³ siê: %s\n"
 
 #, c-format
 msgid "waitpid failed: %s\n"
-msgstr "waitpid nie powiodło się: %s\n"
+msgstr "waitpid nie powiod³o siê: %s\n"
 
 #, c-format
 msgid "child aborted with status %i\n"
-msgstr "potomek został przerwany ze stanem %i\n"
+msgstr "potomek zosta³ przerwany ze stanem %i\n"
 
 #, c-format
 msgid "cannot allocate infile string: %s\n"
-msgstr "nie można przydzielić łańcucha pliku wejściowego: %s\n"
+msgstr "nie mo¿na przydzieliæ ³añcucha pliku wej¶ciowego: %s\n"
 
 #, c-format
 msgid "cannot allocate outfile string: %s\n"
-msgstr "nie można przydzielić łańcucha pliku wyjściowego: %s\n"
+msgstr "nie mo¿na przydzieliæ ³añcucha pliku wyj¶ciowego: %s\n"
 
 #, c-format
 msgid "either %s or %s must be given\n"
-msgstr "musi być podane %s lub %s\n"
+msgstr "musi byæ podane %s lub %s\n"
 
 msgid "no class provided\n"
 msgstr "nie podano klasy\n"
 
 #, c-format
 msgid "class %s is not supported\n"
-msgstr "klasa %s nie jest obsługiwana\n"
+msgstr "klasa %s nie jest obs³ugiwana\n"
 
+#, fuzzy
 msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n"
-msgstr "Wywołanie: gpg-check-pattern [opcje] plik-wzorców (-h podaje pomoc)\n"
+msgstr "Wywo³anie: gpg-connect-agent [opcje] (-h podaje pomoc)"
 
 msgid ""
 "Syntax: gpg-check-pattern [options] patternfile\n"
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
-"Składnia: gpg-check-pattern [opcje] plik-wzorców\n"
-"Sprawdzanie hasła ze standardowego wejścia względem pliku wzorców\n"
+
+#~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
+#~ msgstr ""
+#~ "Baza zaufania jest uszkodzona; proszê uruchomiæ ,,gpg --fix-trustdb''.\n"
+
+#~ msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
+#~ msgstr "B³êdy prosimy zg³aszaæ na adres <gnupg-bugs@gnu.org>.\n"
+
+#~ msgid "Please report bugs to "
+#~ msgstr "B³êdy prosimy zg³aszaæ na adres "
+
+#~ msgid "DSA keypair will have %u bits.\n"
+#~ msgstr "Para kluczy DSA bêdzie mia³a %u bitów d³ugo¶ci.\n"
+
+#~ msgid "this command has not yet been implemented\n"
+#~ msgstr "to polecenie nie zosta³o jeszcze zaimplementowane\n"
+
+#~ msgid "Repeat passphrase\n"
+#~ msgstr "Powtórzone has³o\n"
+
+#~ msgid "||Please enter your PIN at the reader's keypad%%0A[sigs done: %lu]"
+#~ msgstr ""
+#~ "||Proszê wprowadziæ PIN na klawiaturze czytnika%%0A[podpisów wykonanych: %"
+#~ "lu]"
+
+#~ msgid "|A|Admin PIN"
+#~ msgstr "|A|PIN administratora"
+
+#~ msgid "read options from file"
+#~ msgstr "odczyt opcji z pliku"
+
+#~ msgid "generate PGP 2.x compatible messages"
+#~ msgstr "generowanie wiadomo¶ci zgodnych z PGP 2.x"
+
+#~ msgid "|[FILE]|make a signature"
+#~ msgstr "|[PLIK]|z³o¿enie podpisu"
+
+#~ msgid "|[FILE]|make a clear text signature"
+#~ msgstr "|[PLIK]|z³o¿enie podpisu z zachowaniem czytelno¶ci dokumentu"
+
+#~ msgid "|NAME|use NAME as default recipient"
+#~ msgstr "|NAZWA|u¿ycie NAZWY jako domy¶lnego adresata"
+
+#~ msgid "use the default key as default recipient"
+#~ msgstr "u¿ycie domy¶lnego klucza jako domy¶lnego adresata"
+
+#~ msgid "force v3 signatures"
+#~ msgstr "wymuszenie podpisów v3"
+
+#~ msgid "always use a MDC for encryption"
+#~ msgstr "u¿ywanie zawsze MDC do szyfrowania"
+
+#~ msgid "add this secret keyring to the list"
+#~ msgstr "dodanie tego zbioru kluczy tajnych do listy"
+
+#~ msgid "|NAME|set terminal charset to NAME"
+#~ msgstr "|NAZWA|ustawienie zestawu znaków terminala"
+
+#~ msgid "|FILE|load extension module FILE"
+#~ msgstr "|PLIK|wczytanie modu³u rozszerzenia PLIK"
+
+#~ msgid "|N|use compress algorithm N"
+#~ msgstr "|N|u¿ycie algorytmu kompresji N"
+
+#~ msgid "remove key from the public keyring"
+#~ msgstr "usuniêcie klucza ze zbioru kluczy publicznych"
+
+#~ msgid ""
+#~ "It's up to you to assign a value here; this value will never be exported\n"
+#~ "to any 3rd party.  We need it to implement the web-of-trust; it has "
+#~ "nothing\n"
+#~ "to do with the (implicitly created) web-of-certificates."
+#~ msgstr ""
+#~ "Te warto¶ci u¿ytkownik przydziela wg swojego uznania; nie bêd± nigdy\n"
+#~ "eksportowane poza ten system. Potrzebne s± one do zbudowania sieci\n"
+#~ "zaufania, i nie ma to nic wspólnego z tworzon± automatycznie sieci±\n"
+#~ "certyfikatów."
+
+#~ msgid ""
+#~ "To build the Web-of-Trust, GnuPG needs to know which keys are\n"
+#~ "ultimately trusted - those are usually the keys for which you have\n"
+#~ "access to the secret key.  Answer \"yes\" to set this key to\n"
+#~ "ultimately trusted\n"
+#~ msgstr ""
+#~ "Aby zbudowaæ Sieæ Zaufania, GnuPG potrzebuje znaæ klucze do których\n"
+#~ "masz absolutne zaufanie. Zwykle s± to klucze do których masz klucze\n"
+#~ "tajne. Odpowiedz ,,tak'', je¶li chcesz okre¶liæ ten klucz jako klucz\n"
+#~ "do którego masz absolutne zaufanie.\n"
+
+#~ msgid "If you want to use this untrusted key anyway, answer \"yes\"."
+#~ msgstr ""
+#~ "Je¶li mimo wszystko chcesz u¿yæ tego klucza, klucza, co do którego nie "
+#~ "ma\n"
+#~ "¿adnej pewno¶ci do kogo nale¿y, odpowiedz ,,tak''."
+
+#~ msgid ""
+#~ "Enter the user ID of the addressee to whom you want to send the message."
+#~ msgstr "Podaj adresatów tej wiadomo¶ci."
+
+#~ msgid ""
+#~ "Select the algorithm to use.\n"
+#~ "\n"
+#~ "DSA (aka DSS) is the Digital Signature Algorithm and can only be used\n"
+#~ "for signatures.\n"
+#~ "\n"
+#~ "Elgamal is an encrypt-only algorithm.\n"
+#~ "\n"
+#~ "RSA may be used for signatures or encryption.\n"
+#~ "\n"
+#~ "The first (primary) key must always be a key which is capable of signing."
+#~ msgstr ""
+#~ "Proszê wybraæ algorytm.\n"
+#~ "\n"
+#~ "DSA (znany tak¿e jako DSS) to algorytm podpisu cyfrowego (Digital "
+#~ "Signature\n"
+#~ "Algorithm) i mo¿e byæ u¿ywany tylko do podpisów.\n"
+#~ "\n"
+#~ "Elgamal to algorytm tylko do szyfrowania.\n"
+#~ "\n"
+#~ "RSA mo¿e byæ u¿ywany do podpisów lub szyfrowania.\n"
+#~ "\n"
+#~ "Pierwszy (g³ówny) klucz zawsze musi byæ kluczem nadaj±cym siê do "
+#~ "podpisywania."
+
+#~ msgid ""
+#~ "In general it is not a good idea to use the same key for signing and\n"
+#~ "encryption.  This algorithm should only be used in certain domains.\n"
+#~ "Please consult your security expert first."
+#~ msgstr ""
+#~ "U¿ywanie tego samego klucza do podpisywania i szyfrowania nie jest "
+#~ "dobrym\n"
+#~ "pomys³em. Mo¿na tak postêpowaæ tylko w niektórych zastosowaniach. Proszê "
+#~ "siê\n"
+#~ "najpierw skonsultowaæ z ekspertem od bezpieczeñstwa. "
+
+#~ msgid "Enter the size of the key"
+#~ msgstr "Wprowad¼ rozmiar klucza"
+
+#~ msgid "Answer \"yes\" or \"no\""
+#~ msgstr "Odpowiedz \"tak\" lub \"nie\"."
+
+#~ msgid ""
+#~ "Enter the required value as shown in the prompt.\n"
+#~ "It is possible to enter a ISO date (YYYY-MM-DD) but you won't\n"
+#~ "get a good error response - instead the system tries to interpret\n"
+#~ "the given value as an interval."
+#~ msgstr ""
+#~ "Wprowad¼ ¿±dan± warto¶æ (jak w znaku zachêty).\n"
+#~ "Mo¿na tu podaæ datê w formacie ISO (RRRR-MM-DD) ale nie da to\n"
+#~ "w³a¶ciwej obs³ugi b³êdów - system próbuje interpretowaæ podan± warto¶æ\n"
+#~ "jako okres."
+
+#~ msgid "Enter the name of the key holder"
+#~ msgstr "Nazwa w³a¶ciciela klucza."
+
+#~ msgid "please enter an optional but highly suggested email address"
+#~ msgstr "proszê wprowadziæ opcjonalny ale wysoce doradzany adres e-mail"
+
+#~ msgid "Please enter an optional comment"
+#~ msgstr "Proszê wprowadziæ opcjonalny komentarz"
+
+# OSTRZE¯ENIE: nic nie zosta³o wyeksportowane!
+#~ msgid ""
+#~ "N  to change the name.\n"
+#~ "C  to change the comment.\n"
+#~ "E  to change the email address.\n"
+#~ "O  to continue with key generation.\n"
+#~ "Q  to to quit the key generation."
+#~ msgstr ""
+#~ "N aby zmieniæ nazwê (nazwisko).\n"
+#~ "C aby zmieniæ komentarz.<\n"
+#~ "E aby zmieniæ adres e-mail.\n"
+#~ "O aby kontynuowaæ tworzenie klucza.\n"
+#~ "Q aby zrezygnowaæ z tworzenia klucza."
+
+#~ msgid ""
+#~ "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key."
+#~ msgstr "Je¶li ma zostaæ wygenerowany podklucz, nale¿y odpowiedzieæ \"tak\"."
+
+#~ msgid ""
+#~ "When you sign a user ID on a key, you should first verify that the key\n"
+#~ "belongs to the person named in the user ID.  It is useful for others to\n"
+#~ "know how carefully you verified this.\n"
+#~ "\n"
+#~ "\"0\" means you make no particular claim as to how carefully you verified "
+#~ "the\n"
+#~ "    key.\n"
+#~ "\n"
+#~ "\"1\" means you believe the key is owned by the person who claims to own "
+#~ "it\n"
+#~ "    but you could not, or did not verify the key at all.  This is useful "
+#~ "for\n"
+#~ "    a \"persona\" verification, where you sign the key of a pseudonymous "
+#~ "user.\n"
+#~ "\n"
+#~ "\"2\" means you did casual verification of the key.  For example, this "
+#~ "could\n"
+#~ "    mean that you verified the key fingerprint and checked the user ID on "
+#~ "the\n"
+#~ "    key against a photo ID.\n"
+#~ "\n"
+#~ "\"3\" means you did extensive verification of the key.  For example, this "
+#~ "could\n"
+#~ "    mean that you verified the key fingerprint with the owner of the key "
+#~ "in\n"
+#~ "    person, and that you checked, by means of a hard to forge document "
+#~ "with a\n"
+#~ "    photo ID (such as a passport) that the name of the key owner matches "
+#~ "the\n"
+#~ "    name in the user ID on the key, and finally that you verified (by "
+#~ "exchange\n"
+#~ "    of email) that the email address on the key belongs to the key "
+#~ "owner.\n"
+#~ "\n"
+#~ "Note that the examples given above for levels 2 and 3 are *only* "
+#~ "examples.\n"
+#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive"
+#~ "\"\n"
+#~ "mean to you when you sign other keys.\n"
+#~ "\n"
+#~ "If you don't know what the right answer is, answer \"0\"."
+#~ msgstr ""
+#~ "Przy podpisywaniu identyfikatora u¿ytkownika na kluczu nale¿y sprawdziæ,\n"
+#~ "czy to¿samo¶æ u¿ytkownika odpowiada temu, co jest wpisane w "
+#~ "identyfikatorze.\n"
+#~ "Innym u¿ytkownikom przyda siê informacja, jak dog³êbnie zosta³o to przez\n"
+#~ "Ciebie sprawdzone.\n"
+#~ "\n"
+#~ "\"0\" oznacza, ¿e nie podajesz ¿adnych informacji na temat tego jak "
+#~ "dog³êbnie\n"
+#~ "    to¿samo¶æ u¿ytkownika zosta³a przez Ciebie potwierdzona.\n"
+#~ "\n"
+#~ "\"1\" oznacza, ¿e masz przekonanie, ¿e to¿samo¶æ u¿ytkownika odpowiada\n"
+#~ "    identyfikatorowi klucza, ale nie by³o mo¿liwo¶ci sprawdzenia tego.\n"
+#~ "    Taka sytuacja wystêpuje te¿ kiedy podpisujesz identyfikator bêd±cy\n"
+#~ "    pseudonimem.\n"
+#~ "\n"
+#~ "\"2\" oznacza, ¿e to¿samo¶æ u¿ytkownika zosta³a przez Ciebie "
+#~ "potwierdzona\n"
+#~ "    pobie¿nie - sprawdzili¶cie odcisk klucza, sprawdzi³a¶/e¶ to¿samo¶æ\n"
+#~ "    na okazanym dokumencie ze zdjêciem.\n"
+#~ "\n"
+#~ "\"3\" to dog³êbna weryfikacja to¿samo¶ci. Na przyk³ad sprawdzenie "
+#~ "odcisku\n"
+#~ "    klucza, sprawdzenie to¿samo¶ci z okazanego oficjalnego dokumentu ze\n"
+#~ "    zdjêciem (np paszportu) i weryfikacja poprawno¶ci adresu poczty\n"
+#~ "    elektronicznej przez wymianê poczty z tym adresem.\n"
+#~ "\n"
+#~ "Zauwa¿, ¿e podane powy¿ej przyk³ady dla poziomów \"2\" i \"3\" to "
+#~ "*tylko*\n"
+#~ "przyk³ady. Do Ciebie nale¿y decyzja co oznacza \"pobie¿ny\" i \"dog³êbny"
+#~ "\" w\n"
+#~ "kontek¶cie po¶wiadczania i podpisywania kluczy.\n"
+#~ "\n"
+#~ "Je¶li nie wiesz co odpowiedzieæ, podaj \"0\"."
+
+#~ msgid "Answer \"yes\" if you want to sign ALL the user IDs"
+#~ msgstr ""
+#~ "Odpowiedz \"tak\", aby podpisaæ WSZYSTKIE identyfikatory u¿ytkownika."
+
+#~ msgid ""
+#~ "Answer \"yes\" if you really want to delete this user ID.\n"
+#~ "All certificates are then also lost!"
+#~ msgstr ""
+#~ "Aby skasowaæ ten identyfikator u¿ytkownika (co wi±¿e siê ze utrat±\n"
+#~ "wszystkich jego po¶wiadczeñ!) nale¿y odpowiedzieæ ,,tak''."
+
+#~ msgid "Answer \"yes\" if it is okay to delete the subkey"
+#~ msgstr "Aby skasowaæ podklucz nale¿y odpowiedzieæ \"tak\"."
+
+#~ msgid ""
+#~ "This is a valid signature on the key; you normally don't want\n"
+#~ "to delete this signature because it may be important to establish a\n"
+#~ "trust connection to the key or another key certified by this key."
+#~ msgstr ""
+#~ "To jest poprawny podpis na tym kluczu; normalnie nie nale¿y go usuwaæ\n"
+#~ "poniewa¿ mo¿e byæ wa¿ny dla zestawienia po³±czenia zaufania do klucza\n"
+#~ "którym go z³o¿ono lub do innego klucza nim po¶wiadczonego."
+
+#~ msgid ""
+#~ "This signature can't be checked because you don't have the\n"
+#~ "corresponding key.  You should postpone its deletion until you\n"
+#~ "know which key was used because this signing key might establish\n"
+#~ "a trust connection through another already certified key."
+#~ msgstr ""
+#~ "Ten podpis nie mo¿e zostaæ potwierdzony poniewa¿ nie ma\n"
+#~ "odpowiadaj±cego mu klucza publicznego. Nale¿y od³o¿yæ usuniêcie tego\n"
+#~ "podpisu do czasu, kiedy oka¿e siê który klucz zosta³ u¿yty, poniewa¿\n"
+#~ "w momencie uzyskania tego klucza mo¿e pojawiæ siê ¶cie¿ka zaufania\n"
+#~ "pomiêdzy tym a innym, ju¿ po¶wiadczonym kluczem."
+
+#~ msgid ""
+#~ "The signature is not valid.  It does make sense to remove it from\n"
+#~ "your keyring."
+#~ msgstr "Ten podpis jest niepoprawny. Mo¿na usun±æ go ze zbioru kluczy."
+
+#~ msgid ""
+#~ "This is a signature which binds the user ID to the key. It is\n"
+#~ "usually not a good idea to remove such a signature.  Actually\n"
+#~ "GnuPG might not be able to use this key anymore.  So do this\n"
+#~ "only if this self-signature is for some reason not valid and\n"
+#~ "a second one is available."
+#~ msgstr ""
+#~ "To jest podpis wi±¿±cy identyfikator u¿ytkownika z kluczem. Nie nale¿y\n"
+#~ "go usuwaæ - GnuPG mo¿e nie móc pos³ugiwaæ siê dalej kluczem bez\n"
+#~ "takiego podpisu. Bezpiecznie mo¿na go usun±æ tylko je¶li ten podpis\n"
+#~ "klucza nim samym z jakich¶ przyczyn nie jest poprawny, i klucz jest\n"
+#~ "drugi raz podpisany w ten sam sposób."
+
+#~ msgid ""
+#~ "Change the preferences of all user IDs (or just of the selected ones)\n"
+#~ "to the current list of preferences.  The timestamp of all affected\n"
+#~ "self-signatures will be advanced by one second.\n"
+#~ msgstr ""
+#~ "Przestawienie wszystkich (lub tylko wybranych) identyfikatorów na "
+#~ "aktualne\n"
+#~ "ustawienia. Data na odpowiednich podpisach zostane przesuniêta do przodu "
+#~ "o\n"
+#~ "jedn± sekundê.\n"
+
+#~ msgid "Please enter the passhrase; this is a secret sentence \n"
+#~ msgstr "Podaj d³ugie, skomplikowane has³o, np. ca³e zdanie.\n"
+
+#~ msgid ""
+#~ "Please repeat the last passphrase, so you are sure what you typed in."
+#~ msgstr "Proszê powtórzyæ has³o, aby upewniæ siê ¿e nie by³o pomy³ki."
+
+#~ msgid "Give the name of the file to which the signature applies"
+#~ msgstr "Podaj nazwê pliku którego dotyczy ten podpis"
+
+#~ msgid "Answer \"yes\" if it is okay to overwrite the file"
+#~ msgstr "Je¶li mo¿na nadpisaæ ten plik, nale¿y odpowiedzieæ ,,tak''"
+
+#~ msgid ""
+#~ "Please enter a new filename. If you just hit RETURN the default\n"
+#~ "file (which is shown in brackets) will be used."
+#~ msgstr ""
+#~ "Nazwa pliku. Naci¶niêcie ENTER potwierdzi nazwê domy¶ln± (w nawiasach)."
+
+#~ msgid ""
+#~ "You should specify a reason for the certification.  Depending on the\n"
+#~ "context you have the ability to choose from this list:\n"
+#~ "  \"Key has been compromised\"\n"
+#~ "      Use this if you have a reason to believe that unauthorized persons\n"
+#~ "      got access to your secret key.\n"
+#~ "  \"Key is superseded\"\n"
+#~ "      Use this if you have replaced this key with a newer one.\n"
+#~ "  \"Key is no longer used\"\n"
+#~ "      Use this if you have retired this key.\n"
+#~ "  \"User ID is no longer valid\"\n"
+#~ "      Use this to state that the user ID should not longer be used;\n"
+#~ "      this is normally used to mark an email address invalid.\n"
+#~ msgstr ""
+#~ "Nalezy podaæ powód uniewa¿nienia klucza. W zale¿no¶ci od kontekstu mo¿na\n"
+#~ "go wybraæ z listy:\n"
+#~ "  \"Klucz zosta³ skompromitowany\"\n"
+#~ "      Masz powody uwa¿aæ ¿e twój klucz tajny dosta³ siê w niepowo³ane "
+#~ "rêce.\n"
+#~ "  \"Klucz zosta³ zast±piony\"\n"
+#~ "      Klucz zosta³ zast±piony nowym.\n"
+#~ "  \"Klucz nie jest ju¿ u¿ywany\"\n"
+#~ "      Klucz zosta³ wycofany z u¿ycia.\n"
+#~ "  \"Identyfikator u¿ytkownika przesta³ byæ poprawny\"\n"
+#~ "      Identyfikator u¿ytkownika (najczê¶ciej adres e-mail przesta³ byæ\n"
+#~ "      poprawny.\n"
+
+#~ msgid ""
+#~ "If you like, you can enter a text describing why you issue this\n"
+#~ "revocation certificate.  Please keep this text concise.\n"
+#~ "An empty line ends the text.\n"
+#~ msgstr ""
+#~ "Je¶li chcesz, mo¿esz podaæ opis powodu wystawienia certyfikatu\n"
+#~ "uniewa¿nienia. Opis powinien byc zwiêz³y.\n"
+#~ "Pusta linia koñczy wprowadzanie tekstu.\n"
+
+#~ msgid "can't put notation data into v3 (PGP 2.x style) signatures\n"
+#~ msgstr ""
+#~ "nie mo¿na umie¶ciæ adnotacji w podpisach sk³adanych kluczami PGP 2.x\n"
+
+#~ msgid "can't put notation data into v3 (PGP 2.x style) key signatures\n"
+#~ msgstr ""
+#~ "nie mo¿na umie¶ciæ adnotacji w podpisach kluczy sk³adanych kluczami PGP 2."
+#~ "x\n"
+
+#~ msgid "can't put a policy URL into v3 (PGP 2.x style) signatures\n"
+#~ msgstr ""
+#~ "nie mo¿na umie¶ciæ URL-a regulaminu w podpisach sk³adanych kluczami PGP 2."
+#~ "x\n"
+
+#~ msgid "can't put a policy URL into v3 key (PGP 2.x style) signatures\n"
+#~ msgstr ""
+#~ "w podpisach dla PGP 2.x nie mo¿na umie¶ciæ URL-a do regulaminu podpisu\n"
index 851d056..734605c 100644 (file)
--- a/po/pt.po
+++ b/po/pt.po
@@ -12,7 +12,6 @@ msgstr ""
 "PO-Revision-Date: 2002-09-13 18:26+0100\n"
 "Last-Translator: Pedro Morais <morais@kde.org>\n"
 "Language-Team: pt <morais@kde.org>\n"
-"Language: pt\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -21,41 +20,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "falha ao inicializar a base de dados de confiança: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Você quer realmente revogar as chaves selecionadas? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "frase-secreta inválida"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -81,9 +45,6 @@ msgid ""
 "this session"
 msgstr "Por favor digite a frase secreta \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -120,11 +81,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "algoritmo de protecção %d%s não é suportado\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "impossível criar `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 #, fuzzy, c-format
@@ -151,31 +112,19 @@ msgstr "remo
 msgid "error writing key: %s\n"
 msgstr "erro na escrita do porta-chaves `%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Por favor digite a frase secreta \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "muda a frase secreta"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Por favor digite a frase secreta \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -202,7 +151,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -290,7 +239,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Você precisa de uma frase secreta para proteger a sua chave.\n"
 "\n"
@@ -308,10 +257,10 @@ msgstr ""
 "Opções:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -367,26 +316,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "erro na criação da frase secreta: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "não suportado"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "não suportado"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "erro na criação da frase secreta: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -408,7 +346,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -416,23 +354,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTA: ficheiro de opções por omissão `%s' inexistente\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "ficheiro de opções `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "a ler opções de `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "erro ao criar `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "%s: impossível criar directoria: %s\n"
 
 msgid "name of socket too long\n"
@@ -443,7 +381,7 @@ msgid "can't create socket: %s\n"
 msgstr "impossível criar %s: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -455,7 +393,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "erro na criação da frase secreta: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "erro ao enviar para `%s': %s\n"
 
 #, fuzzy, c-format
@@ -463,19 +401,19 @@ msgid "listen() failed: %s\n"
 msgstr "actualização falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "a escrever chave privada para `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: directoria criada\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: impossível criar directoria: %s\n"
 
 #, fuzzy, c-format
@@ -583,31 +521,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "erro na criação da frase secreta: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "chave `%s' não encontrada: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "partes da chave secreta não disponíveis\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "armadura: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -695,15 +633,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
@@ -718,7 +656,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "o gpg-agent não está disponível nesta sessão\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "impossível ligar a `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -796,10 +734,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -826,22 +760,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "certificado incorrecto"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "certificado incorrecto"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "certificado incorrecto"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "certificado incorrecto"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "certificado incorrecto"
 
@@ -884,26 +802,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritmo de dispersão inválido `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Esta assinatura expirou em %s.\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritmo de dispersão inválido `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "algoritmo de protecção %d%s não é suportado\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "verificação de assinatura suprimida\n"
 
@@ -912,11 +814,11 @@ msgid "Signature available"
 msgstr "Esta assinatura expirou em %s.\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Assinatura correcta de \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "algoritmo de dispersão inválido `%s'\n"
 
 #, fuzzy, c-format
@@ -961,7 +863,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Nenhuma ajuda disponível para `%s'"
 
 #, fuzzy
@@ -1136,11 +1038,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "erro ao criar porta-chaves `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "erro na escrita do porta-chaves `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1342,8 +1244,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Comando> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1364,7 +1266,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output não funciona para este comando\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "impossível abrir `%s'\n"
 
 #, fuzzy, c-format
@@ -1416,18 +1318,18 @@ msgid "using cipher %s\n"
 msgstr "assinatura falhou: %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "%s' já comprimido\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "AVISO: `%s' é um ficheiro vazio\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr "no modo --pgp2 só pode cifrar com chaves RSA de 2048 bits ou menos\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "lendo de `%s'\n"
 
 msgid ""
@@ -1491,11 +1393,11 @@ msgid "this platform requires temporary files when calling external programs\n"
 msgstr "%s: erro ao ler registo de versão: %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "não foi possível alterar o exec-path para %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "não foi possível alterar o exec-path para %s\n"
 
 #, fuzzy, c-format
@@ -1514,11 +1416,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "não foi possível alterar o exec-path para %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "AVISO: dono pouco seguro em %s \"%s\"\n"
 
 #, fuzzy
@@ -1584,16 +1486,12 @@ msgstr "entradas demais no cache pk - desactivado\n"
 msgid "[User ID not found]"
 msgstr "[Utilizador não encontrado]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "erro ao criar `%s': %s\n"
 
 #, fuzzy
@@ -1612,6 +1510,10 @@ msgstr "h
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "usando chave secundária %08lX ao invés de chave primária %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "fazer uma assinatura separada"
@@ -1654,9 +1556,6 @@ msgstr "listar as chaves secretas"
 msgid "generate a new key pair"
 msgstr "gerar um novo par de chaves"
 
-msgid "generate a revocation certificate"
-msgstr "gerar um certificado de revogação"
-
 msgid "remove keys from the public keyring"
 msgstr "remover chaves do porta-chaves público"
 
@@ -1672,9 +1571,8 @@ msgstr "assinar uma chave localmente"
 msgid "sign or edit a key"
 msgstr "assinar ou editar uma chave"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "muda a frase secreta"
+msgid "generate a revocation certificate"
+msgstr "gerar um certificado de revogação"
 
 msgid "export keys"
 msgstr "exportar chaves"
@@ -1777,15 +1675,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxe: gpg [opções] [ficheiros]\n"
 "assina, verifica, cifra ou decifra\n"
@@ -1817,35 +1710,35 @@ msgid "conflicting commands\n"
 msgstr "comandos em conflito\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "nenhum sinal = encontrada na definição de grupo \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "AVISO: dono pouco seguro em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "AVISO: dono pouco seguro em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "AVISO: dono pouco seguro em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "AVISO: dono pouco seguro em %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1854,11 +1747,11 @@ msgid ""
 msgstr "AVISO: dono pouco seguro em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "AVISO: dono pouco seguro em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1867,11 +1760,11 @@ msgid ""
 msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "criado um novo ficheiro de configuração `%s'\n"
 
 msgid "display photo IDs during key listings"
@@ -1912,7 +1805,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "NOTA: o ficheiro antigo de opções por omissão `%s' foi ignorado\n"
 
 #, c-format
@@ -1924,11 +1817,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "NOTA: %s não é para uso normal!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s não é um conjunto de caracteres válido\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s não é um conjunto de caracteres válido\n"
 
 #, fuzzy
@@ -2107,15 +2000,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s não faz sentido com %s!\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
 
 #, c-format
@@ -2133,7 +2026,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [nome_do_ficheiro]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "decifragem falhou: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2185,10 +2078,6 @@ msgstr "--lsign-key id-utilizador"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key id-utilizador [comandos]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key id-utilizador"
-
 #, fuzzy, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "A geração de chaves falhou: %s\n"
@@ -2218,7 +2107,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "criação de armadura falhou: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "algoritmo de dispersão inválido `%s'\n"
 
 msgid "[filename]"
@@ -2263,7 +2152,7 @@ msgid "No help available"
 msgstr "Nenhuma ajuda disponível"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Nenhuma ajuda disponível para `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2273,10 +2162,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "actualizar a base de dados de confiança"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "actualizar a base de dados de confiança"
 
@@ -2394,13 +2279,6 @@ msgid "key %s: no user ID\n"
 msgstr "chave %08lX: sem ID de utilizador\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "ignorado `%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "chave %08lX: subchave HKP corrompida foi reparada\n"
 
@@ -2428,11 +2306,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "não foi encontrada nenhum porta-chaves onde escrever: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "a escrever para `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "erro na escrita do porta-chaves `%s': %s\n"
 
 #, fuzzy, c-format
@@ -2496,17 +2374,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "chave %08lX: \"%s\" não modificada\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "chave `%s' não encontrada: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "chave %08lX: chave secreta com cifra inválida %d - ignorada\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "a escrever chave privada para `%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "chave %08lX: chave secreta com cifra inválida %d - ignorada\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "sem porta-chaves público por omissão: %s\n"
@@ -2551,18 +2425,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "chave %08lX: auto-assinatura inválida do utilizador \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "chave %08lX: algoritmo de chave pública não suportado\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "chave %08lX: assinatura directa de chave adicionada\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "chave %08lX: sem subchave para ligação de chaves\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "chave %08lX: algoritmo de chave pública não suportado\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "chave %08lX: ligação de subchave inválida\n"
 
@@ -2617,8 +2487,8 @@ msgstr "chave %08lX: detectado ID de utilizador duplicado - fundido\n"
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
 msgstr ""
-"AVISO: a chave %08lX pode estar revocada: a transferir a chave de revocação "
-"%08lX\n"
+"AVISO: a chave %08lX pode estar revocada: a transferir a chave de revocação %"
+"08lX\n"
 
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
@@ -2646,15 +2516,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "ignorado: a chave secreta já está presente\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "erro ao criar porta-chaves `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "porta-chaves `%s' criado\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "erro ao criar `%s': %s\n"
 
 #, c-format
@@ -2844,7 +2714,7 @@ msgstr "   (2) Verifiquei por alto.%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Verifiquei com bastante cuidado.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr ""
 
 #, fuzzy, c-format
@@ -3124,7 +2994,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Sugestão: Selecione os IDs de utilizador para assinar\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "classe de assinatura desconhecida"
 
 #, c-format
@@ -3159,11 +3029,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "erro ao criar porta-chaves `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3252,7 +3122,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Não há preferências no ID de utilizador tipo PGP 2.x.\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Esta chave pode ser revogada pela chave %s "
 
 #, fuzzy, c-format
@@ -3317,14 +3187,6 @@ msgid ""
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Você não pode modificar a data de validade de uma chave v3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3555,7 +3417,7 @@ msgstr ""
 "A mostrar a fotografia %s com o tamanho %ld da chave 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "preferência %c%lu duplicada\n"
 
 #, fuzzy
@@ -3571,7 +3433,7 @@ msgid "too many compression preferences\n"
 msgstr "demasiadas preferências `%c'\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "caracter inválido na cadeia de caractéres da preferência\n"
 
 msgid "writing direct signature\n"
@@ -3815,7 +3677,7 @@ msgid "Invalid character in comment\n"
 msgstr "Caracter inválido no comentário\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Você está usando o conjunto de caracteres `%s'.\n"
 
 #, c-format
@@ -3902,15 +3764,15 @@ msgid "Key generation canceled.\n"
 msgstr "Geração de chave cancelada.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "a escrever chave pública para `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "a escrever chave privada para `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "a escrever chave privada para `%s'\n"
 
 #, c-format
@@ -3922,11 +3784,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "nenhum porta-chaves secreto com permissões de escrita encontrado: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "erro ao escrever no porta-chaves público `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3970,11 +3832,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "remoção do bloco de chave falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "impossível criar `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "NOTA: chave secreta %08lX expirou em %s\n"
 
 msgid "never     "
@@ -4016,15 +3878,11 @@ msgstr "      Impress
 msgid "      Key fingerprint ="
 msgstr "  Impressão da chave ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "assinatura %s de: \"%s\"\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "criação de armadura falhou: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4042,7 +3900,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Por favor conserte esta possível falha de segurança\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "a verificar o porta chaves `%s'\n"
 
 #, fuzzy, c-format
@@ -4080,7 +3938,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "AVISO: opções em `%s' ainda não estão activas nesta execução\n"
 
 #, fuzzy
@@ -4147,10 +4005,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "A geração de chaves falhou: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4158,11 +4012,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4177,6 +4031,10 @@ msgstr "erro do servidor de chaves"
 msgid "keyserver internal error\n"
 msgstr "erro do servidor de chaves"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "A geração de chaves falhou: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4352,10 +4210,6 @@ msgid "unknown"
 msgstr "versão desconhecida"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Impossível verificar assinatura: %s\n"
 
@@ -4378,7 +4232,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "pacote raiz inválido detectado em proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "impossível abrir %s: %s\n"
 
 #, fuzzy, c-format
@@ -4409,10 +4263,6 @@ msgstr ""
 "forçar o algoritmo de 'digest' %s (%d) viola as preferências do "
 "destinatário\n"
 
-#, fuzzy, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "assinatura %s de: \"%s\"\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "o 'plugin' com a cifra IDEA não está presente\n"
 
@@ -4444,15 +4294,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "AVISO: \"%s\" é uma opção depreciada\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "AVISO: \"%s\" é uma opção depreciada\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "AVISO: \"%s\" é uma opção depreciada\n"
-
 #, fuzzy
 msgid "Uncompressed"
 msgstr "não processado"
@@ -4467,15 +4308,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "esta mensagem poderá não ser utilizável pelo %s\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "a ler opções de `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "destinatário por omissão desconhecido `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Arquivo `%s' já existe. "
 
 #, fuzzy
@@ -4492,17 +4333,16 @@ msgstr "Digite novo nome de ficheiro"
 msgid "writing to stdout\n"
 msgstr "a escrever em \"stdout\"\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "a assumir dados assinados em `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "criado um novo ficheiro de configuração `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "AVISO: opções em `%s' ainda não estão activas nesta execução\n"
 
 #, c-format
@@ -4517,10 +4357,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "subpacote do tipo %d tem bit crítico ligado\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problema com o agente: o agente returnou 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (ID principal da chave %08lX)"
 
@@ -4545,6 +4381,10 @@ msgid "cancelled by user\n"
 msgstr "cancelado pelo utilizador\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problema com o agente: o agente returnou 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4573,7 +4413,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "impossível abrir %s: %s\n"
 
 #, c-format
@@ -4585,7 +4425,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "%s: não é um base de dados de confiança\n"
 
 #, fuzzy
@@ -4617,16 +4457,6 @@ msgstr "motivo da revoca
 msgid "revocation comment: "
 msgstr "comentário da revocação: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4744,11 +4574,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Nota: Esta chave foi desactivada.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4850,7 +4680,7 @@ msgid "no signed data\n"
 msgstr "não há dados assinados\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "impossível abrir dados assinados `%s'\n"
 
 #, fuzzy, c-format
@@ -5158,7 +4988,7 @@ msgid ""
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy
@@ -5177,25 +5007,17 @@ msgid "ownertrust value missing"
 msgstr "importar os valores de confiança"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "%s: erro ao escrever registo de diretório: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "armadura: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "base de dados de confiança: sincronização falhou: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "impossível criar `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "impossível abrir `%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "base de dados de confiança rec %lu: lseek falhou: %s\n"
@@ -5207,13 +5029,21 @@ msgstr "base de dados de confian
 msgid "trustdb transaction too large\n"
 msgstr "transação de base de dados de confiança muito grande\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "impossível fechar `%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: diretoria inexistente!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossível fechar `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "impossível criar `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "impossível abrir `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5299,7 +5129,7 @@ msgid "input line longer than %d characters\n"
 msgstr "linha de entrada maior que %d caracteres\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' não é um identificador longo de chave válido\n"
 
 #, fuzzy, c-format
@@ -5342,14 +5172,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5400,11 +5222,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "proxima verificação da base de dados de confiança a %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "não é necessária uma verificação da base de dados de confiança\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "não é necessária uma verificação da base de dados de confiança\n"
 
 #, fuzzy, c-format
@@ -5478,11 +5300,6 @@ msgid "missing argument"
 msgstr "argumento inválido"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armadura inválida"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "comandos em conflito\n"
 
@@ -5502,10 +5319,6 @@ msgstr "op
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "opções de importação inválidas\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5534,8 +5347,12 @@ msgstr "op
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "você encontrou um bug ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "erro na leitura de `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5543,15 +5360,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "impossível abrir %s: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "criação de armadura falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "%s: impossível criar directoria: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "erro na escrita do porta-chaves `%s': %s\n"
 
 #, c-format
@@ -5569,7 +5386,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "chave pública %08lX não encontrada: %s\n"
 
 #, fuzzy, c-format
@@ -5586,11 +5403,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5719,9 +5535,6 @@ msgstr "motivo da revoca
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5732,14 +5545,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "muda a frase secreta"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "muda a frase secreta"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "erro na leitura do bloco de chave: %s\n"
 
@@ -5806,9 +5611,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "nenhum dado OpenPGP válido encontrado.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "muda a frase secreta"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5844,16 +5648,13 @@ msgstr "nunca usar o terminal"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "comandos em conflito\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)"
@@ -5863,7 +5664,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5883,7 +5684,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5919,7 +5720,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5948,7 +5749,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "remoção do bloco de chave falhou: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "falha ao inicializar a base de dados de confiança: %s\n"
 
 #, fuzzy
@@ -6139,16 +5940,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6170,11 +5971,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6182,11 +5983,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Endereço eletrónico inválido\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "erro ao criar porta-chaves `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "erro ao criar porta-chaves `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6256,7 +6057,7 @@ msgid "No subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6265,7 +6066,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "algoritmo de dispersão inválido `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6313,7 +6114,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "chave `%s' não encontrada: %s\n"
 
 #, fuzzy, c-format
@@ -6321,11 +6122,11 @@ msgid "error locking keybox: %s\n"
 msgstr "erro na leitura do bloco de chave: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "preferência %c%lu duplicada\n"
 
 #, fuzzy, c-format
@@ -6362,6 +6163,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "muda a frase secreta"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "criar saída com armadura ascii"
 
@@ -6441,8 +6246,8 @@ msgstr "Uso: gpg [op
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxe: gpg [opções] [ficheiros]\n"
 "assina, verifica, cifra ou decifra\n"
@@ -6453,11 +6258,11 @@ msgid "usage: gpgsm [options] "
 msgstr "uso: gpg [opções] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "impossível ligar a `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "destinatário por omissão desconhecido `%s'\n"
 
 #, c-format
@@ -6480,11 +6285,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "a escrever para `%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "impossível fechar `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6501,6 +6306,10 @@ msgstr "gerar um certificado de revoga
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "falha ao inicializar a base de dados de confiança: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "erro na criação da frase secreta: %s\n"
@@ -6514,11 +6323,14 @@ msgid "error reading input: %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "erro ao criar porta-chaves `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "porta-chaves `%s' criado\n"
 
 #, fuzzy
@@ -6552,11 +6364,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "%s: versão de ficheiro inválida %d\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6677,7 +6489,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "destinatário por omissão desconhecido `%s'\n"
 
 #, fuzzy, c-format
@@ -6910,7 +6722,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "impossível abrir %s: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "%s: impossível criar directoria: %s\n"
 
 #, fuzzy, c-format
@@ -7005,17 +6817,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "erro na leitura de `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "falha ao inicializar a base de dados de confiança: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Comando> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "A base de dados de confiança está danificada; por favor execute\n"
@@ -7530,6 +7331,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "pacote inválido"
 
+#~ msgid "invalid armor"
+#~ msgstr "armadura inválida"
+
 #~ msgid "no such user id"
 #~ msgstr "identificador de utilizador inexistente"
 
@@ -7539,6 +7343,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "chave secreta incorrecta"
 
+#~ msgid "not supported"
+#~ msgstr "não suportado"
+
 #~ msgid "bad key"
 #~ msgstr "chave incorrecta"
 
@@ -7554,6 +7361,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "erro na criação do ficheiro"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "frase-secreta inválida"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritmo de chave pública não implementado"
 
@@ -8183,8 +7993,8 @@ msgstr ""
 
 #~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"
 #~ msgstr ""
-#~ "a verificar à profundidade %d assinado=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/"
-#~ "%d\n"
+#~ "a verificar à profundidade %d assinado=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%"
+#~ "d\n"
 
 #~ msgid ""
 #~ "Select the algorithm to use.\n"
index 98d43df..c63a287 100644 (file)
@@ -16,7 +16,6 @@ msgstr ""
 "PO-Revision-Date: 2007-08-16 11:35+0200\n"
 "Last-Translator:\n"
 "Language-Team: ?\n"
-"Language: pt_BR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -25,42 +24,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "falha ao inicializar o banco de dados de confiabilidade: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to create a sign and encrypt key? "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Você realmente quer criar uma chave para assinatura e criptografia? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "frase secreta inválida"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -86,9 +49,6 @@ msgid ""
 "this session"
 msgstr "Por favor digite a frase secreta"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -125,11 +85,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "algoritmo de proteção %d não é suportado\n"
 
 #, fuzzy, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "impossível criar %s: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 #, fuzzy, c-format
@@ -156,31 +116,19 @@ msgstr "enumera
 msgid "error writing key: %s\n"
 msgstr "erro na escrita do chaveiro `%': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Por favor digite a frase secreta"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "muda a frase secreta"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Por favor digite a frase secreta"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -208,7 +156,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -296,7 +244,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Você precisa de uma frase secreta para proteger sua chave.\n"
 "\n"
@@ -314,10 +262,10 @@ msgstr ""
 "Opções:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -372,28 +320,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "erro na criação da frase secreta: %s\n"
 
-# suportado ???
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "não suportado"
-
-# suportado ???
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "não suportado"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "erro na criação da frase secreta: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -415,7 +350,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -423,23 +358,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTA: arquivo de opções padrão `%s' inexistente\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "arquivo de opções `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "lendo opções de `%s'\n"
 
 #, fuzzy, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "%s: impossível criar diretório: %s\n"
 
 msgid "name of socket too long\n"
@@ -450,7 +385,7 @@ msgid "can't create socket: %s\n"
 msgstr "impossível criar %s: %s\n"
 
 #, fuzzy, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "Certificado de revogação válido"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -461,7 +396,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "erro na criação da frase secreta: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
@@ -469,19 +404,19 @@ msgid "listen() failed: %s\n"
 msgstr "atualização falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "escrevendo certificado privado para `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: diretório criado\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "banco de dados de confiabilidade: leitura falhou (n=%d): %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: impossível criar diretório: %s\n"
 
 #, fuzzy, c-format
@@ -587,31 +522,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "erro na criação da frase secreta: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "usuário `%s' não encontrado: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "chave secreta não disponível"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "erro de leitura: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -699,15 +634,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
@@ -722,7 +657,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -798,10 +733,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -828,22 +759,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "Certificado correto"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "Certificado correto"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "Certificado correto"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "Certificado correto"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "Certificado de revogação válido"
 
@@ -888,28 +803,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-# "hash" poderia ser "espalhamento", mas não fica claro
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritmo de hash inválido `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Esta chave não é protegida.\n"
-
-# "hash" poderia ser "espalhamento", mas não fica claro
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritmo de hash inválido `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "algoritmo de proteção %d não é suportado\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "verificação de assinatura suprimida\n"
 
@@ -918,12 +815,12 @@ msgid "Signature available"
 msgstr "Esta chave não é protegida.\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Assinatura correta de \""
 
 # "hash" poderia ser "espalhamento", mas não fica claro
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "algoritmo de hash inválido `%s'\n"
 
 #, fuzzy, c-format
@@ -970,7 +867,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Nenhuma ajuda disponível para `%s'"
 
 #, fuzzy
@@ -1145,11 +1042,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1353,8 +1250,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Comando> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1376,7 +1273,7 @@ msgid "--output doesn't work for this command\n"
 msgstr ""
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "impossível abrir `%s'\n"
 
 #, fuzzy, c-format
@@ -1429,18 +1326,18 @@ msgid "using cipher %s\n"
 msgstr "assinatura falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "%lu chaves processadas\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "AVISO: `%s' é um arquivo vazio\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr ""
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "lendo de `%s'\n"
 
 msgid ""
@@ -1500,11 +1397,11 @@ msgid "this platform requires temporary files when calling external programs\n"
 msgstr "%s: erro lendo registro de versão: %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "impossível abrir %s: %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "impossível abrir %s: %s\n"
 
 #, fuzzy, c-format
@@ -1522,11 +1419,11 @@ msgid "unable to read external program response: %s\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr ""
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr ""
 
 #, fuzzy
@@ -1592,16 +1489,12 @@ msgstr "entradas demais no cache pk - desativado\n"
 msgid "[User ID not found]"
 msgstr "[usuário não encontrado]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy
@@ -1620,6 +1513,10 @@ msgstr "h
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "usando chave secundária %08lX ao invés de chave primária %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "fazer uma assinatura separada"
@@ -1664,9 +1561,6 @@ msgstr "listar as chaves secretas"
 msgid "generate a new key pair"
 msgstr "gerar um novo par de chaves"
 
-msgid "generate a revocation certificate"
-msgstr "gerar um certificado de revogação"
-
 #, fuzzy
 msgid "remove keys from the public keyring"
 msgstr "remover a chave do chaveiro público"
@@ -1684,9 +1578,8 @@ msgstr "assinar uma chave localmente"
 msgid "sign or edit a key"
 msgstr "assinar ou editar uma chave"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "muda a frase secreta"
+msgid "generate a revocation certificate"
+msgstr "gerar um certificado de revogação"
 
 msgid "export keys"
 msgstr "exportar chaves"
@@ -1789,15 +1682,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Uso: gpg [opções] [arquivos] (-h para ajuda)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxe: gpg [opções] [arquivos]\n"
 "assina, verifica, criptografa ou descriptografa\n"
@@ -1830,35 +1718,35 @@ msgid "conflicting commands\n"
 msgstr "comandos conflitantes\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
@@ -1867,11 +1755,11 @@ msgid ""
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
@@ -1880,11 +1768,11 @@ msgid ""
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 msgid "display photo IDs during key listings"
@@ -1925,7 +1813,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Nenhuma assinatura correspondente no chaveiro secreto\n"
 
 #, fuzzy, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "NOTA: arquivo de opções padrão `%s' inexistente\n"
 
 #, c-format
@@ -1937,11 +1825,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "NOTA: %s não é para uso normal!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s não é um conjunto de caracteres válido\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s não é um conjunto de caracteres válido\n"
 
 #, fuzzy
@@ -2126,15 +2014,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s não faz sentido com %s!\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr ""
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "o algoritmo de criptografia selecionado não é válido\n"
 
 #, c-format
@@ -2151,7 +2039,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [nome_do_arquivo]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "descriptografia falhou: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2204,10 +2092,6 @@ msgstr "--lsign-key id-usu
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key id-usuário [comandos]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key id-usuário"
-
 #, fuzzy, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "A geração de chaves falhou: %s\n"
@@ -2238,7 +2122,7 @@ msgstr "cria
 
 # "hash" poderia ser "espalhamento", mas não fica claro
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "algoritmo de hash inválido `%s'\n"
 
 msgid "[filename]"
@@ -2288,7 +2172,7 @@ msgid "No help available"
 msgstr "Nenhuma ajuda disponível"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Nenhuma ajuda disponível para `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2298,10 +2182,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "atualizar o banco de dados de confiabilidade"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "atualizar o banco de dados de confiabilidade"
 
@@ -2420,13 +2300,6 @@ msgid "key %s: no user ID\n"
 msgstr "chave %08lX: sem ID de usuário\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "ignorado `%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "chave %08lX: sem subchave para ligação de chaves\n"
 
@@ -2454,11 +2327,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "impossível escrever chaveiro: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "escrevendo para `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
@@ -2522,18 +2395,14 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "chave %08lX: não modificada\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "usuário `%s' não encontrado: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "escrevendo certificado privado para `%s'\n"
 
 #, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n"
-
-#, fuzzy, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "impossível bloquear chaveiro secreto: %s\n"
 
@@ -2576,18 +2445,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "chave %08lX: auto-assinatura inválida\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "chave %08lX: algoritmo de chave pública não suportado\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "chave %08lX: %d novas assinaturas\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "chave %08lX: sem subchave para ligação de chaves\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "chave %08lX: algoritmo de chave pública não suportado\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "chave %08lX: ligação de subchave inválida\n"
 
@@ -2668,15 +2533,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "ignorado: a chave secreta já está presente\n"
 
 #, fuzzy, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "%s: chaveiro criado\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "%s: erro de leitura de bloco de chaves: %s\n"
 
 #, fuzzy, c-format
@@ -2863,7 +2728,7 @@ msgstr ""
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr ""
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr ""
 
 #, fuzzy, c-format
@@ -3134,7 +2999,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Sugestão: Selecione os IDs de usuário para assinar\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "classe de assinatura desconhecida"
 
 #, c-format
@@ -3169,11 +3034,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3261,7 +3126,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "AVISO: Esta chave foi revogada pelo seu dono!\n"
 
 #, fuzzy, c-format
@@ -3323,14 +3188,6 @@ msgid ""
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Você não pode modificar a data de validade de uma chave v3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3559,7 +3416,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "ignorado `%s': duplicado\n"
 
 # muitas ou demais ???
@@ -3578,7 +3435,7 @@ msgid "too many compression preferences\n"
 msgstr "Preferências demais"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "Caractere inválido no nome\n"
 
 #, fuzzy
@@ -3824,7 +3681,7 @@ msgid "Invalid character in comment\n"
 msgstr "Caractere inválido no comentário\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Você está usando o conjunto de caracteres `%s'.\n"
 
 #, c-format
@@ -3910,15 +3767,15 @@ msgid "Key generation canceled.\n"
 msgstr "Geração de chave cancelada.\n"
 
 #, fuzzy, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "escrevendo certificado público para `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "escrevendo certificado privado para `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "escrevendo certificado privado para `%s'\n"
 
 #, fuzzy, c-format
@@ -3930,11 +3787,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "impossível bloquear chaveiro secreto: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3978,11 +3835,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "enumeração de blocos de chaves falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "impossível criar %s: %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "NOTA: chave secreta %08lX expirou %s\n"
 
 msgid "never     "
@@ -4032,15 +3889,11 @@ msgstr "       Impress
 msgid "      Key fingerprint ="
 msgstr "       Impressão digital:"
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "assinatura %s de: %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "criação de armadura falhou: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4058,7 +3911,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Por favor conserte este possível furo de segurança\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
@@ -4096,7 +3949,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 
 #, fuzzy
@@ -4163,10 +4016,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "enumeração de chaves secretas falhou: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4174,11 +4023,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4194,6 +4043,10 @@ msgid "keyserver internal error\n"
 msgstr "erro geral"
 
 #, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "enumeração de chaves secretas falhou: %s\n"
+
+#, fuzzy, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "%s não é um mapa de caracteres válido\n"
 
@@ -4368,10 +4221,6 @@ msgid "unknown"
 msgstr "versão desconhecida"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Impossível verificar assinatura: %s\n"
 
@@ -4394,7 +4243,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "pacote raiz inválido detectado em proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "atualização do banco de dados de confiabilidade falhou: %s\n"
 
 #, fuzzy, c-format
@@ -4421,10 +4270,6 @@ msgstr "assinatura %s de: %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "NOTA: algoritmo de criptografia %d não encontrado nas preferências\n"
 
-#, fuzzy, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "assinatura %s de: %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr ""
 
@@ -4456,15 +4301,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "AVISO: `%s' é um arquivo vazio\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "AVISO: `%s' é um arquivo vazio\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "AVISO: `%s' é um arquivo vazio\n"
-
 #, fuzzy
 msgid "Uncompressed"
 msgstr "não processado(s)"
@@ -4479,15 +4315,15 @@ msgid "this message may not be usable by %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "lendo opções de `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "destinatário padrão desconhecido `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Arquivo `%s' já existe. "
 
 #, fuzzy
@@ -4504,17 +4340,16 @@ msgstr "Digite novo nome de arquivo"
 msgid "writing to stdout\n"
 msgstr "escrevendo em \"stdout\"\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "assumindo dados assinados em `%s'\n"
 
 #, fuzzy, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "%s: novo arquivo de opções criado\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 
 #, c-format
@@ -4528,10 +4363,6 @@ msgstr ""
 msgid "subpacket of type %d has critical bit set\n"
 msgstr "subpacote do tipo %d tem bit crítico ligado\n"
 
-#, c-format
-msgid "problem with the agent: %s\n"
-msgstr ""
-
 #, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (ID principal da chave %08lX)"
@@ -4556,6 +4387,10 @@ msgstr "Digite a frase secreta: "
 msgid "cancelled by user\n"
 msgstr ""
 
+#, c-format
+msgid "problem with the agent: %s\n"
+msgstr ""
+
 #, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
@@ -4585,7 +4420,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "impossível abrir arquivo: %s\n"
 
 #, c-format
@@ -4597,7 +4432,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Você tem certeza de que quer este tamanho de chave? "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "%s: não é um banco de dados de confiabilidade\n"
 
 #, fuzzy
@@ -4633,16 +4468,6 @@ msgstr "rev- revoga
 msgid "revocation comment: "
 msgstr "[revogação]"
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr ""
 
@@ -4757,11 +4582,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Esta chave foi desativada"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4866,7 +4691,7 @@ msgid "no signed data\n"
 msgstr "no dados assinados\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "impossível abrir dados assinados `%s'\n"
 
 #, fuzzy, c-format
@@ -5168,7 +4993,7 @@ msgstr ""
 "# (Use \"gpgm --import-ownertrust\" para restaurá-los)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy
@@ -5187,25 +5012,17 @@ msgid "ownertrust value missing"
 msgstr "importar os valores de confiança"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "erro lendo registro de diretório: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "erro de leitura: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "banco de dados de confiabilidade: sincronização falhou: %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "impossível criar %s: %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "impossível abrir `%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "banco de dados de confiabilidade rec %lu: lseek falhou: %s\n"
@@ -5217,13 +5034,21 @@ msgstr "banco de dados de confiabilidade rec %lu: escrita falhou (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "transação de banco de dados de confiabilidade muito grande\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "impossível abrir `%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: diretório inexistente!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossível abrir `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "impossível criar %s: %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "impossível abrir `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5309,7 +5134,7 @@ msgid "input line longer than %d characters\n"
 msgstr "linha de entrada maior que %d caracteres\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "%s não é um mapa de caracteres válido\n"
 
 #, fuzzy, c-format
@@ -5351,14 +5176,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5410,11 +5227,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "inserção de registro de confiança falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "%s: não é um banco de dados de confiabilidade\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "%s: não é um banco de dados de confiabilidade\n"
 
 #, fuzzy, c-format
@@ -5487,11 +5304,6 @@ msgid "missing argument"
 msgstr "argumento inválido"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armadura inválida"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "comandos conflitantes\n"
 
@@ -5511,10 +5323,6 @@ msgstr "armadura inv
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "armadura inválida"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5544,8 +5352,12 @@ msgstr "armadura inv
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "você encontrou um bug ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "erro na leitura de `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5553,15 +5365,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "impossível abrir arquivo: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "criação de armadura falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "%s: impossível criar diretório: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, c-format
@@ -5579,7 +5391,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "chave pública não encontrada"
 
 #, fuzzy, c-format
@@ -5596,11 +5408,10 @@ msgstr "habilitar depura
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Uso: gpg [opções] [arquivos] (-h para ajuda)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Uso: gpg [opções] [arquivos] (-h para ajuda)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5729,9 +5540,6 @@ msgstr "rev- revoga
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5742,14 +5550,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "muda a frase secreta"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "muda a frase secreta"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "erro na leitura de `%s': %s\n"
 
@@ -5816,9 +5616,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "nenhum dado OpenPGP válido encontrado.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "muda a frase secreta"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5855,16 +5654,13 @@ msgstr "nunca usar o terminal"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "comandos conflitantes\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Uso: gpgm [opções] [arquivos] (-h para ajuda)"
@@ -5874,7 +5670,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5894,7 +5690,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr "falha ao colocar `%s' no banco de dados de confiabilidade: %s\n"
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
@@ -5929,7 +5725,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5958,7 +5754,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "enumeração de blocos de chaves falhou: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "falha ao inicializar o banco de dados de confiabilidade: %s\n"
 
 #, fuzzy
@@ -6160,16 +5956,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6192,11 +5988,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6204,11 +6000,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Endereço eletrônico inválido\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6278,7 +6074,7 @@ msgid "No subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 # "hash" poderia ser "espalhamento", mas não fica claro
@@ -6288,7 +6084,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "algoritmo de hash inválido `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6331,7 +6127,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "usuário `%s' não encontrado: %s\n"
 
 #, fuzzy, c-format
@@ -6339,11 +6135,11 @@ msgid "error locking keybox: %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "certificado duplicado - removido"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "certificado duplicado - removido"
 
 #, fuzzy, c-format
@@ -6380,6 +6176,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "muda a frase secreta"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "criar saída com armadura ascii"
 
@@ -6457,8 +6257,8 @@ msgstr "Uso: gpgm [op
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxe: gpg [opções] [arquivos]\n"
 "assina, verifica, criptografa ou descriptografa\n"
@@ -6469,11 +6269,11 @@ msgid "usage: gpgsm [options] "
 msgstr "Uso: gpgm [opções] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "destinatário padrão desconhecido `%s'\n"
 
 #, c-format
@@ -6496,11 +6296,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "escrevendo para `%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "impossível abrir `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6517,6 +6317,10 @@ msgstr "Certificado correto"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "falha ao inicializar o banco de dados de confiabilidade: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "erro na criação da frase secreta: %s\n"
@@ -6530,11 +6334,14 @@ msgid "error reading input: %s\n"
 msgstr "erro na leitura de `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "erro na escrita do chaveiro `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "%s: chaveiro criado\n"
 
 #, fuzzy
@@ -6568,11 +6375,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "erro: impressão digital inválida\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6692,7 +6499,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "destinatário padrão desconhecido `%s'\n"
 
 #, fuzzy, c-format
@@ -6926,7 +6733,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "atualização do banco de dados de confiabilidade falhou: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "%s: impossível criar diretório: %s\n"
 
 #, fuzzy, c-format
@@ -7021,17 +6828,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "erro na leitura de `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "falha ao inicializar o banco de dados de confiabilidade: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Comando> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "O banco de dados de confiabilidade está danificado; por favor rode\n"
@@ -7363,6 +7159,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "pacote inválido"
 
+#~ msgid "invalid armor"
+#~ msgstr "armadura inválida"
+
 #~ msgid "no such user id"
 #~ msgstr "identificador de usuário inexistente"
 
@@ -7372,6 +7171,10 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "chave secreta incorreta"
 
+# suportado ???
+#~ msgid "not supported"
+#~ msgstr "não suportado"
+
 #~ msgid "bad key"
 #~ msgstr "chave incorreta"
 
@@ -7387,6 +7190,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "erro na criação de arquivo"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "frase secreta inválida"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritmo de chave pública não implementado"
 
@@ -8302,6 +8108,10 @@ msgstr ""
 #~ "usuário `%s' não encontrado no banco de dados de confiabilidade - "
 #~ "inserindo\n"
 
+#~ msgid "Do you really want to create a sign and encrypt key? "
+#~ msgstr ""
+#~ "Você realmente quer criar uma chave para assinatura e criptografia? "
+
 #~ msgid "no default public keyring\n"
 #~ msgstr "sem chaveiro público padrão\n"
 
index fb3fed7..2a1f149 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -9,10 +9,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg 1.4.2rc1\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-12-19 12:30+0100\n"
+"PO-Revision-Date: 2005-05-31 22:00-0500\n"
 "Last-Translator: Laurentiu Buzdugan <lbuz@rolix.org>\n"
 "Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
-"Language: ro\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -22,42 +21,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "am eºuat sã stochez amprenta: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Doriþi într-adevãr sã revocaþi subcheile selectate? (d/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "frazã-parolã invalidã"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 #, fuzzy
@@ -85,9 +48,6 @@ msgid ""
 msgstr ""
 "Vã rugãm introduceþi fraza-parolã; aceasta este o propoziþie secretã \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -124,11 +84,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "algoritm rezumat %d nu este suportat\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "nu pot crea `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "nu pot deschide `%s': %s\n"
 
 #, fuzzy, c-format
@@ -155,20 +115,8 @@ msgstr "citirea cheii publice a e
 msgid "error writing key: %s\n"
 msgstr "eroare la scrierea inelului de chei `%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr ""
 "Vã rugãm introduceþi fraza-parolã; aceasta este o propoziþie secretã \n"
 
@@ -176,12 +124,11 @@ msgstr ""
 msgid "Please re-enter this passphrase"
 msgstr "schimbã fraza-parolã"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
-"Vã rugãm introduceþi fraza-parolã; aceasta este o propoziþie secretã \n"
 
 msgid "does not match - try again"
 msgstr ""
@@ -215,7 +162,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -302,7 +249,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Aveþi nevoie de o frazã-parolã pentru a vã proteja cheia secretã.\n"
 "\n"
@@ -320,10 +267,10 @@ msgstr ""
 "Opþiuni:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -378,26 +325,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "eroare la crearea frazei-parolã: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "nu este suportat(ã)"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "nu este suportat(ã)"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "eroare la crearea frazei-parolã: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -419,7 +355,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -427,23 +363,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "NOTÃ: nici un fiºier opþiuni implicit `%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "fiºier opþiuni `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "citesc opþiuni din `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "eroare la creearea `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "nu pot crea directorul `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -454,7 +390,7 @@ msgid "can't create socket: %s\n"
 msgstr "nu pot crea `%s': %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -466,7 +402,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "eroare la obþinere noului PIN: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "eroare trimitere la `%s': %s\n"
 
 #, fuzzy, c-format
@@ -474,19 +410,19 @@ msgid "listen() failed: %s\n"
 msgstr "actualizarea a eºuat: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "scriu cheia secretã în `%s'\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "director `%s' creat\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "fstat(%d) a eºuat în %s: %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: nu pot crea director: %s\n"
 
 #, fuzzy, c-format
@@ -597,31 +533,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "eroare la crearea frazei-parolã: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "eroare în `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "fiºier opþiuni `%s': %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "pãrþi ale cheii secrete nu sunt disponibile\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "eroare citire în `%s': %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "eroare la citire `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -709,15 +645,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "eroare la obþinerea informaþiei pentru cheia curentã: %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "eroare la citire `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "eroare la citire `%s': %s\n"
 
 #, fuzzy, c-format
@@ -732,7 +668,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent nu este disponibil în aceastã sesiune\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "nu mã pot conecta la `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -808,10 +744,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -838,22 +770,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "certificat incorect"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "certificat incorect"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "certificat incorect"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "certificat incorect"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "certificat incorect"
 
@@ -897,26 +813,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "algoritm hash invalid `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Semnãturã fãcutã %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "algoritm hash invalid `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "algoritm de protecþie %d%s nu este suportat\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "verificare semnãturã eliminatã\n"
 
@@ -925,11 +825,11 @@ msgid "Signature available"
 msgstr "Semnãturã fãcutã %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Semnãturã bunã din \"%s\""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "algoritm hash invalid `%s'\n"
 
 #, fuzzy, c-format
@@ -974,7 +874,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Nici un disponibil disponibil pentru `%s'"
 
 #, fuzzy
@@ -1141,11 +1041,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "eroare la crearea inelului de chei `%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "eroare la citire `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "eroare la scrierea inelului de chei `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1330,8 +1230,8 @@ msgstr "verific
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Comandã> "
 
 msgid "Admin-only command\n"
 msgstr "Comandã numai-administrare\n"
@@ -1349,7 +1249,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output nu merge pentru aceastã comandã\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "nu pot deschide `%s'\n"
 
 #, c-format
@@ -1400,11 +1300,11 @@ msgid "using cipher %s\n"
 msgstr "folosesc cifrul %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' deja compresat\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "AVERTISMENT: `%s' este un fiºier gol\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1412,7 +1312,7 @@ msgstr ""
 "în modul --pgp2 puteþi cifra numai cu chei RSA de 2048 biþi sau mai puþin\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "citesc din `%s'\n"
 
 msgid ""
@@ -1478,11 +1378,11 @@ msgstr ""
 "externe\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "nu pot executa programul `%s': %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "nu pot executa shell-ul `%s': %s\n"
 
 #, c-format
@@ -1500,11 +1400,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "nu pot citi rãspunsul programului extern: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "AVERTISMENT: nu pot ºterge fiºierul temporar (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "AVERTISMENT: nu pot ºterge directorul temporar `%s': %s\n"
 
 #, fuzzy
@@ -1568,15 +1468,11 @@ msgid "[User ID not found]"
 msgstr "[ID utilizator nu a fost gãsit]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "cheia %s: cheie secretã fãrã cheie publicã - sãritã\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "eroare la creearea `%s': %s\n"
 
 #, fuzzy
@@ -1595,6 +1491,10 @@ msgstr "nici o subcheie secret
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "folosim subcheia %s în loc de cheia primarã %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "cheia %s: cheie secretã fãrã cheie publicã - sãritã\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "|[fiºier]|creazã o semnãturã"
@@ -1636,9 +1536,6 @@ msgstr "enumer
 msgid "generate a new key pair"
 msgstr "genereazã o nouã perechi de chei"
 
-msgid "generate a revocation certificate"
-msgstr "genereazã un certificat de revocare"
-
 msgid "remove keys from the public keyring"
 msgstr "ºterge chei de pe inelul de chei public"
 
@@ -1654,9 +1551,8 @@ msgstr "semneaz
 msgid "sign or edit a key"
 msgstr "semneazã sau editeazã o cheie"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "schimbã fraza-parolã"
+msgid "generate a revocation certificate"
+msgstr "genereazã un certificat de revocare"
 
 msgid "export keys"
 msgstr "exportã chei"
@@ -1755,15 +1651,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Folosire: gpg [opþiuni] [fiºiere] (-h pentru ajutor)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxã: gpg [opþiuni] [fiºiere]\n"
 "sign, check, encrypt sau decrypt\n"
@@ -1795,39 +1686,39 @@ msgid "conflicting commands\n"
 msgstr "comenzi în conflict\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "nu am gãsit nici un semn = în definiþia grupului `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr ""
 "AVERTISMENT: proprietate nesigurã (unsafe) pentru directorul home `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr ""
 "AVERTISMENT: proprietate nesigurã (unsafe) pentru fiºier configurare `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "AVERTISMENT: proprietate nesigurã (unsafe) pentru extensia `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr ""
 "AVERTISMENT: permisiuni nesigure (unsafe) pentru directorul home `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr ""
 "AVERTISMENT: permisiuni nesigure (unsafe) pentru fiºier configurare `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "AVERTISMENT: permisiuni nesigure (unsafe) pentru extensia `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
 "AVERTISMENT: proprietate director incluziuni nesigur (unsafe) pentru "
 "directorul home `%s'\n"
@@ -1840,13 +1731,13 @@ msgstr ""
 "configurare `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "AVERTISMENT: proprietate director incluziuni nesigur (unsafe) pentru "
 "extensia `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 "AVERTISMENT: permisiuni director incluziuni nesigure (unsafe) pentru "
 "directorul home `%s'\n"
@@ -1859,13 +1750,13 @@ msgstr ""
 "configurare `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "AVERTISMENT: permisiuni director incluziuni nesigure (unsafe) pentru "
 "extensia `%s'\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "articol configurare necunoscut `%s'\n"
 
 msgid "display photo IDs during key listings"
@@ -1906,7 +1797,7 @@ msgid "show expiration dates during signature listings"
 msgstr "Nici o semnãturã corespunzãtoare în inelul secret\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "NOTÃ: fisier opþiuni implicite vechi `%s' ignorat\n"
 
 #, c-format
@@ -1918,11 +1809,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "NOTÃ: %s nu este pentru o folosire normalã!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "`%s' nu este expirare de semnãturã validã\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "`%s' nu este un set de carectere valid\n"
 
 #
@@ -2098,15 +1989,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s nu merge încã cu %s!\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "nu puteþi folosi algoritmul de cifrare `%s' câtã vreme în modul %s\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "nu puteþi folosi algorimul de rezumat `%s' câtã vreme în modul %s\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "nu puteþi folosi algoritmul de compresie `%s' câtã vreme în modul %s\n"
 
 #, c-format
@@ -2125,7 +2016,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [nume_fiºier]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "cifrarea simetricã a lui `%s' a eºuat: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2175,10 +2066,6 @@ msgstr "--lsign-key id-utilizator"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key id-utilizator [comenzi]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key id-utilizator"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "trimitere server de chei eºuatã: %s\n"
@@ -2208,7 +2095,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "punerea armurii a eºuat: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "algoritm hash invalid `%s'\n"
 
 msgid "[filename]"
@@ -2251,7 +2138,7 @@ msgid "No help available"
 msgstr "Nici un ajutor disponibil"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Nici un disponibil disponibil pentru `%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2261,10 +2148,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "actualizeazã baza de date de încredere"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "actualizeazã baza de date de încredere"
 
@@ -2385,14 +2268,6 @@ msgstr "v
 msgid "key %s: no user ID\n"
 msgstr "cheia %s: nici un ID utilizator\n"
 
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s: %s\n"
-msgstr "sãritã \"%s\": %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "cheia %s: subcheia HPK coruptã a fost reparatã\n"
@@ -2421,11 +2296,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "n-am gãsit nici un inel de chei ce poate fi scris: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "scriu în `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "eroare la scrierea inelului de chei `%s': %s\n"
 
 #, c-format
@@ -2488,18 +2363,13 @@ msgstr "cheia %s: \"%s\" %d noi ID-uri utilizator\n"
 msgid "key %s: \"%s\" not changed\n"
 msgstr "cheia %s: \"%s\" nu a fost schimbatã\n"
 
-#, fuzzy, c-format
-#| msgid "secret key \"%s\" not found: %s\n"
-msgid "secret key %s: %s\n"
-msgstr "cheia secretã \"%s\" nu a fost gãsitã: %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "importul de chei secrete nu este permis\n"
-
 #, c-format
 msgid "key %s: secret key with invalid cipher %d - skipped\n"
 msgstr "cheia %s: cheie secretã cu cifru invalid %d - sãritã\n"
 
+msgid "importing secret keys not allowed\n"
+msgstr "importul de chei secrete nu este permis\n"
+
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "nici un inel de chei secrete implicit: %s\n"
@@ -2544,18 +2414,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "cheia %s: auto-semnãturã invalidã pentru ID-ul utilizator \"%s\"\n"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "cheia %s: algoritm cu cheie publicã nesuportat\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "cheia %s: am adãugat semnãtura de cheie directã\n"
-
-#, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "cheia %s: nici o subcheie pentru legarea cheii\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "cheia %s: algoritm cu cheie publicã nesuportat\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "cheia %s: legare subcheie invalidã\n"
 
@@ -2635,15 +2501,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "NOTÃ: cheia secundarã este online ºi stocatã pe card\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "eroare la crearea inelului de chei `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "inelul de chei `%s' creat\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "resursã keyblock `%s': %s\n"
 
 #, c-format
@@ -2720,7 +2586,6 @@ msgstr ""
 msgid "User ID \"%s\" is revoked."
 msgstr "ID utilizator \"%s\" a fost revocat."
 
-#, fuzzy
 msgid "Are you sure you still want to sign it? (y/N) "
 msgstr "Sunteþi sigur(ã) cã doriþi sã ºtergeþi permanent \"%s\"? (d/N)"
 
@@ -2837,7 +2702,7 @@ msgstr "   (2) Am f
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Am fãcut verificãri foarte atente.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Selecþia dvs.? (introduceþi `?' pentru informaþii suplimentare): "
 
 #, c-format
@@ -3077,7 +2942,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Sugestie: Selectaþi ID-ul utilizator de semnat\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Tip de semnãturã necunoscut `%s'\n"
 
 #, c-format
@@ -3108,11 +2973,11 @@ msgid "Command expects a filename argument\n"
 msgstr "Comanda aºteaptã un nume de fiºier ca argument\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "Nu pot deschide `%s': %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Eroare citind cheia de rezervã de pe `%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3192,8 +3057,8 @@ msgstr "Nota
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Nu existã nici o preferinþã pentru un ID utilizator stil PGP 2.x.\n"
 
-#, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+#, c-format
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Aceastã cheie a fost revocatã pe %s de %s cheia %s\n"
 
 #, c-format
@@ -3259,14 +3124,6 @@ msgstr ""
 "              Aceastã comandã poate cauza ca un alt ID utilizator\n"
 "              sã devinã ID-ul utilizator primar presupus.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Nu puteþi schimba data de expirare a unei chei v3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3492,7 +3349,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Afiºez poza ID %s de dimensiune %ld pentru cheia %s (uid %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "preferinþa `%s' duplicatã\n"
 
 msgid "too many cipher preferences\n"
@@ -3505,7 +3362,7 @@ msgid "too many compression preferences\n"
 msgstr "prea multe preferinþe de compresie\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "articol invalid `%s' în ºirul de preferinþe\n"
 
 msgid "writing direct signature\n"
@@ -3743,7 +3600,7 @@ msgid "Invalid character in comment\n"
 msgstr "Caracter invalid în comentariu\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Folosiþi setul de caractere `%s'\n"
 
 #, c-format
@@ -3828,15 +3685,15 @@ msgid "Key generation canceled.\n"
 msgstr "Generarea cheii a fost anulatã.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "scriu cheia publicã în `%s'\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "scriu talonul (stub) cheii secrete în `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "scriu cheia secretã în `%s'\n"
 
 #, c-format
@@ -3848,11 +3705,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "nu am gãsit nici un inel de chei secret de scris: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "eroare la scrierea inelului de chei public `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "eroare la scrierea inelului de chei secret `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3896,11 +3753,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "stocarea cheii pe card a eºuat: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "nu pot crea fiºier de rezervã `%s': %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "NOTÃ: copia de siguranþa a cheii cardului salvatã la `%s'\n"
 
 msgid "never     "
@@ -3941,16 +3798,11 @@ msgstr "      Amprent
 msgid "      Key fingerprint ="
 msgstr "      Amprentã cheie ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "AVERTISMENT: folosesc algoritmul rezumat experimental %s\n"
-
 msgid "      Card serial no. ="
 msgstr "      Card nr. serie ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "redenumirea `%s' ca `%s' a eºuat: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -3968,7 +3820,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Vã rugãm reparaþi aceastã deficienþã posibilã de securitate\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "pun în cache inelul de chei `%s'\n"
 
 #, c-format
@@ -4006,7 +3858,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "AVERTISMENT: opþiunile serverului de chei `%s' nu sunt folosite pe aceastã "
 "platformã\n"
@@ -4066,16 +3918,12 @@ msgstr "nici o ac
 #, c-format
 msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
 msgstr ""
-"AVERTISMENT: manipulator server de chei dintr-o versiune diferitã de GnuPG "
-"(%s)\n"
+"AVERTISMENT: manipulator server de chei dintr-o versiune diferitã de GnuPG (%"
+"s)\n"
 
 msgid "keyserver did not send VERSION\n"
 msgstr "serverul de chei nu a trimis VERSION (versiune)\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "eroare de comunicare server de chei: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "nici un server de chei cunoscut (folosiþi opþiunea --keyserver)\n"
 
@@ -4084,11 +3932,11 @@ msgstr ""
 "apeluri cãtre server de chei extern nu este suportat de acest program\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr "nici un manipulator (handler) pentru schema serverului de chei `%s'\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr "acþiunea `%s' nu este suportatã cu schema serverului de chei `%s'\n"
 
 #, c-format
@@ -4102,6 +3950,10 @@ msgid "keyserver internal error\n"
 msgstr "eroare internã server de chei\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "eroare de comunicare server de chei: %s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "\"%s\" nu este un ID de cheie: sãrit\n"
 
@@ -4272,10 +4124,6 @@ msgid "unknown"
 msgstr "necunoscut"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Nu pot verifica semnãtura: %s\n"
 
@@ -4298,7 +4146,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "pachet root invalid detectat în proc_tree()\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "fstat pentru `%s' a eºuat în %s: %s\n"
 
 #, c-format
@@ -4325,11 +4173,6 @@ msgstr "AVERTISMENT: folosesc algoritmul rezumat experimental %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "AVERTISMENT: algoritmul rezumat %s este prea vechi (deprecated)\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "semnãturã %s, algoritm rezumat %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "plugin-ul pentru cifrare IDEA nu este prezent\n"
 
@@ -4361,15 +4204,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "AVERTISMENT: \"%s\" este o opþiune învechitã\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "AVERTISMENT: \"%s\" este o opþiune învechitã\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "AVERTISMENT: \"%s\" este o opþiune învechitã\n"
-
 msgid "Uncompressed"
 msgstr "Necompresat"
 
@@ -4383,15 +4217,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "acest mesaj s-ar putea sã nu poatã fi folosit de %s\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "opþiune ambiguã `%s'\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "opþiune necunoscutã `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Fiºierul `%s' existã. "
 
 msgid "Overwrite? (y/N) "
@@ -4407,17 +4241,16 @@ msgstr "Introduce
 msgid "writing to stdout\n"
 msgstr "scriu la stdout\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "presupun date semnate în `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "fiºier de configurare nou `%s' creat\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "AVERTISMENT: opþiunile din %s nu sunt încã active în timpul acestei rulãri\n"
 
@@ -4434,10 +4267,6 @@ msgstr ""
 msgid "subpacket of type %d has critical bit set\n"
 msgstr "subpachetul de tip %d are bitul critic setat\n"
 
-#, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problemã cu agentul: agentul returneazã 0x%lx\n"
-
 #, c-format
 msgid " (main key ID %s)"
 msgstr " (ID cheie principalã %s)"
@@ -4461,6 +4290,10 @@ msgstr "Introduce
 msgid "cancelled by user\n"
 msgstr "anulatã de utilizator\n"
 
+#, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problemã cu agentul: agentul returneazã 0x%lx\n"
+
 #, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
@@ -4496,7 +4329,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Introduceþi nume-fiºier JPEG pentru pozã ID: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "nu pot deschide fiºierul JPEG `%s': %s\n"
 
 #, c-format
@@ -4507,7 +4340,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Sunteþi sigur(ã) cã doriþi sã îl folosiþi? (d/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "`%s' nu este un fiºier JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4537,16 +4370,6 @@ msgstr "motiv pentru revocare: "
 msgid "revocation comment: "
 msgstr "comentariu revocare: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMtTsS"
 
@@ -4656,11 +4479,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Notã: Aceastã cheie a fost deactivatã.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4765,7 +4588,7 @@ msgid "no signed data\n"
 msgstr "nici o datã semnatã\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "nu pot deschide date semnate `%s'\n"
 
 #, fuzzy, c-format
@@ -5073,7 +4896,7 @@ msgstr ""
 "# (Folosiþi \"gpg --import-ownertrust\" pentru a le reface)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "eroare în `%s': %s\n"
 
 msgid "line too long"
@@ -5089,11 +4912,11 @@ msgid "ownertrust value missing"
 msgstr "lipseºte valorea încrederii în proprietari (ownertrust)"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "eroare gãsire înregistrare încredere în `%s': %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "eroare citire în `%s': %s\n"
 
 #, c-format
@@ -5101,14 +4924,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "trustdb: sincronizarea a eºuat: %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "nu pot crea încuietoare (lock) pentru `%s'\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "nu pot încuia (lock) `%s'\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb rec %lu: lseek a eºuat: %s\n"
 
@@ -5120,12 +4935,20 @@ msgid "trustdb transaction too large\n"
 msgstr "tranzacþia trustdb prea mare\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "nu pot accesa `%s': %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: directorul nu existã!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nu pot accesa `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "nu pot crea încuietoare (lock) pentru `%s'\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "nu pot încuia (lock) `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5211,7 +5034,7 @@ msgid "input line longer than %d characters\n"
 msgstr "linii de intrare mai lungi de %d caractere\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' nu este un ID-cheie de lungime validã\n"
 
 #, c-format
@@ -5253,14 +5076,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr "folosesc model de încredere %s\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr "10 traducãtor vezi trustdb.c:uid_trust_string_fixed"
 
@@ -5308,11 +5123,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "urmãtoarea verificare trustdb programatã pe %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "nu e nevoie de o verificare trustdb cu modelul de încredere `%s'\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "nu e nevoie de o actualizare trustdb cu modelul de încredere `%s'\n"
 
 #, c-format
@@ -5386,11 +5201,6 @@ msgid "missing argument"
 msgstr "argument invalid"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "armurã invalidã"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "Comandã numai-administrare\n"
 
@@ -5410,10 +5220,6 @@ msgstr "op
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "opþiuni enumerare invalide\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5442,8 +5248,12 @@ msgstr "op
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "aþi gãsit un bug ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "eroare la citire `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5451,15 +5261,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "nu pot deschide fiºierul: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "redenumirea `%s' ca `%s' a eºuat: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "nu pot crea directorul `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "eroare la scrierea inelului de chei `%s': %s\n"
 
 #, c-format
@@ -5477,7 +5287,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "cheia publicã %s nu a fost gãsitã: %s\n"
 
 #, fuzzy, c-format
@@ -5494,11 +5304,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Folosire: gpg [opþiuni] [fiºiere] (-h pentru ajutor)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Folosire: gpg [opþiuni] [fiºiere] (-h pentru ajutor)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5627,9 +5436,6 @@ msgstr "||V
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr "PIN-ul pentru CHV%d este prea scurt; lungimea minimã este %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5639,14 +5445,6 @@ msgstr "|AN|PIN Admin Nou"
 msgid "|N|New PIN"
 msgstr "|N|PIN Nou"
 
-#, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||Vã rugãm introduceþi PIN%%0A[semnãturi fãcute: %lu]"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Vã rugãm introduceþi PIN%%0A[semnãturi fãcute: %lu]"
-
 msgid "error reading application data\n"
 msgstr "eroare la citirea datelor aplicaþiei\n"
 
@@ -5710,9 +5508,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "nu pot accesa %s - card OpenPGP invalid?\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||Vã rugãm introduceþi PIN%%0A[semnãturi fãcute: %lu]"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5749,16 +5546,13 @@ msgstr "nu folosi deloc terminalul"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "aratã comenzi administrare"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Folosire: gpg [opþiuni] [fiºiere] (-h pentru ajutor)"
@@ -5768,7 +5562,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5788,7 +5582,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5824,7 +5618,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "Nu pot deschide `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5853,7 +5647,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "citirea cheii publice a eºuat: %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "am eºuat sã stochez cheia: %s\n"
 
 #, fuzzy
@@ -6044,16 +5838,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "eroare la obþinerea informaþiei pentru cheia curentã: %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6075,11 +5869,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6087,11 +5881,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Nu este o adresã de email validã\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "eroare la crearea inelului de chei `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "eroare la crearea inelului de chei `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6162,7 +5956,7 @@ msgid "No subject name given\n"
 msgstr "(Nici o descriere datã)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6171,7 +5965,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "algoritm hash invalid `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6218,7 +6012,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "cheia secretã \"%s\" nu a fost gãsitã: %s\n"
 
 #, fuzzy, c-format
@@ -6226,11 +6020,11 @@ msgid "error locking keybox: %s\n"
 msgstr "eroare la citire keyblock: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Certificat de revocare creat.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "preferinþa `%s' duplicatã\n"
 
 #, fuzzy, c-format
@@ -6268,6 +6062,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "schimbã fraza-parolã"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "creazã ieºire în armurã ascii"
 
@@ -6345,8 +6143,8 @@ msgstr "Folosire: gpg [op
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sintaxã: gpg [opþiuni] [fiºiere]\n"
 "sign, check, encrypt sau decrypt\n"
@@ -6357,11 +6155,11 @@ msgid "usage: gpgsm [options] "
 msgstr "folosire: gpg [opþiuni] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "nu mã pot conecta la `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "opþiune necunoscutã `%s'\n"
 
 #, fuzzy, c-format
@@ -6385,11 +6183,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "nu pot accesa `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6406,6 +6204,10 @@ msgstr "genereaz
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "am eºuat sã stochez cheia: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "eroare la obþinere noului PIN: %s\n"
@@ -6419,11 +6221,14 @@ msgid "error reading input: %s\n"
 msgstr "eroare la citire `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "eroare la crearea inelului de chei `%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "inelul de chei `%s' creat\n"
 
 #, fuzzy
@@ -6457,11 +6262,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "Eroare: amprentã formatatã invalid.\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6580,7 +6385,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "opþiune necunoscutã `%s'\n"
 
 #, fuzzy, c-format
@@ -6812,7 +6617,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "fstat pentru `%s' a eºuat în %s: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "nu pot crea directorul `%s': %s\n"
 
 #, fuzzy, c-format
@@ -6908,17 +6713,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "eroare la citire `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "am eºuat sã stochez cheia: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Comandã> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "trustdb este coruptã; rulaþi \"gpg --fix-trustdb\".\n"
 
@@ -6935,6 +6729,10 @@ msgstr ""
 #~ msgid "Repeat passphrase\n"
 #~ msgstr "Repetaþi fraza-parolã\n"
 
+#, fuzzy
+#~ msgid "||Please enter your PIN at the reader's keypad%%0A[sigs done: %lu]"
+#~ msgstr "||Vã rugãm introduceþi PIN%%0A[semnãturi fãcute: %lu]"
+
 #~ msgid "|A|Admin PIN"
 #~ msgstr "|A|PIN Admin"
 
@@ -7490,6 +7288,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "pachet invalid"
 
+#~ msgid "invalid armor"
+#~ msgstr "armurã invalidã"
+
 #~ msgid "no such user id"
 #~ msgstr "nu existã acest id utilizator"
 
@@ -7499,6 +7300,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "a fost folositã o cheie secretã greºitã"
 
+#~ msgid "not supported"
+#~ msgstr "nu este suportat(ã)"
+
 #~ msgid "bad key"
 #~ msgstr "cheie incorectã"
 
@@ -7514,6 +7318,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "eroare creare fiºier"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "frazã-parolã invalidã"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritm pubkey neimplementat"
 
index 5f23ded..3af0277 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -1,61 +1,24 @@
 # Copyright (C)2006 Free Software Foundation, Inc.
 # This file is distributed under the same license as the GnuPG package.
 # Maxim Britov <maxim.britov@gmail.com>, 2006.
-#              !-- no such user (2011-01-11)
 # Thanks Pawel I. Shajdo <pshajdo@gmail.com>.
 # Thanks Cmecb for the inspiration.
-# Ineiev <ineiev@gnu.org>, 2014, 2015
-#
-# Designated-Translator: none
 msgid ""
 msgstr ""
 "Project-Id-Version: GnuPG 2.0.10\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-06-25 17:16+0000\n"
-"Last-Translator: Ineiev <ineiev@gnu.org>\n"
+"PO-Revision-Date: 2008-12-21 00:40+0200\n"
+"Last-Translator: Maxim Britov <maxim.britov@gmail.com>\n"
 "Language-Team: Russian <gnupg-ru@gnupg.org>\n"
-"Language: ru\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n"
 
 #, c-format
 msgid "failed to acquire the pinentry lock: %s\n"
-msgstr "сбой при блокировке для ввода PIN: %s\n"
-
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|_Cancel"
-msgstr "|pinentry-label|Отмена (_C)"
-
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|Да (_Y)"
-
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|Нет (_N)"
-
-msgid "|pinentry-label|PIN:"
-msgstr "|pinentry-label|PIN:"
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|Сохранить в диспетчере паролей (_S)"
-
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Вы действительно хотите, чтобы фраза-пароль была видна на экране?"
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr "|pinentry-tt|Показывать фразу-пароль"
-
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "|pinentry-tt|Скрывать фразу-пароль"
+msgstr ""
 
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
@@ -70,43 +33,37 @@ msgstr "Стойкость:"
 #. will be used.
 msgid "pinentry.qualitybar.tooltip"
 msgstr ""
-"СÑ\82ойкоÑ\81Ñ\82Ñ\8c Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ\8bÑ\88е Ñ\82екÑ\81Ñ\82а. Ð\9fÑ\80оконÑ\81Ñ\83лÑ\8cÑ\82иÑ\80Ñ\83йÑ\82еÑ\81Ñ\8c Ñ\83 Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80а о "
-"критериях оценки стойкости."
+"СÑ\82ойкоÑ\81Ñ\82Ñ\8c Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ\8bÑ\88е Ñ\82екÑ\81Ñ\82а. Ð\9cожеÑ\82е Ð¿Ñ\80окоÑ\81Ñ\83лÑ\8cÑ\82иÑ\80оваÑ\82Ñ\8cÑ\81Ñ\8f Ñ\83 Ð\92аÑ\88его "
+"админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80а Ð¾ ÐºÑ\80иÑ\82еÑ\80иÑ\8fÑ\85 Ð¾Ñ\86енки Ñ\81Ñ\82ойкоÑ\81Ñ\82и."
 
 msgid ""
 "Please enter your PIN, so that the secret key can be unlocked for this "
 "session"
-msgstr ""
-"Введите PIN, чтобы сделать закрытый ключ доступным на протяжении этого сеанса"
+msgstr "Введите PIN-код для получения доступа к закрытому ключу"
 
 msgid ""
 "Please enter your passphrase, so that the secret key can be unlocked for "
 "this session"
-msgstr ""
-"Введите фразу-пароль, чтобы сделать закрытый ключ доступным на протяжении "
-"этого сеанса"
+msgstr "Введите фразу-пароль для получения доступа к закрытому ключу"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (попытка %d из %d)"
 
 msgid "PIN too long"
-msgstr "Слишком длинный PIN"
+msgstr "PIN слишком длинен"
 
 msgid "Passphrase too long"
-msgstr "Слишком длинная фраза-пароль"
+msgstr "фраза-пароль слишком длинная"
 
 msgid "Invalid characters in PIN"
-msgstr "Недопустимый символ в PIN"
+msgstr "Недопустимый символ в PIN-коде"
 
 msgid "PIN too short"
-msgstr "Слишком короткий PIN"
+msgstr "PIN-код слишком короткий"
 
 msgid "Bad PIN"
-msgstr "Ð\9dевеÑ\80нÑ\8bй PIN"
+msgstr "плоÑ\85ой PIN"
 
 msgid "Bad Passphrase"
 msgstr "Неверная фраза-пароль"
@@ -116,14 +73,14 @@ msgstr "Фраза-пароль"
 
 #, c-format
 msgid "ssh keys greater than %d bits are not supported\n"
-msgstr "клÑ\8eÑ\87и ssh Ð´Ð»Ð¸Ð½Ð½ÐµÐµ %d Ð±Ð¸Ñ\82 Ð½Ðµ Ð¿Ð¾Ð´Ð´ÐµÑ\80живаÑ\8eÑ\82Ñ\81Ñ\8f\n"
+msgstr "не Ð¿Ð¾Ð´Ð´ÐµÑ\80живаÑ\8eÑ\82Ñ\81Ñ\8f ssh ÐºÐ»Ñ\8eÑ\87и Ð¿Ñ\80евÑ\8bÑ\88аÑ\8eÑ\89ие %d Ð±Ð¸Ñ\82\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "не могу создать `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "не могу открыть `%s': %s\n"
 
 #, c-format
@@ -136,48 +93,34 @@ msgstr "обнаружена карта, серийный номер: %s\n"
 
 #, c-format
 msgid "error getting default authentication keyID of card: %s\n"
-msgstr "оÑ\88ибка Ð¿Ð¾Ð»Ñ\83Ñ\87ениÑ\8f Ð¾Ñ\81новного Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ионного ID ÐºÐ»Ñ\8eÑ\87а карты: %s\n"
+msgstr "оÑ\88ибка Ð¿Ð¾Ð»Ñ\83Ñ\87ениÑ\8f Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ионного keyID Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e карты: %s\n"
 
 #, c-format
 msgid "no suitable card key found: %s\n"
-msgstr "на ÐºÐ°Ñ\80Ñ\82е Ð½Ðµ Ð½Ð°Ð¹Ð´ÐµÐ½Ð¾ Ð¿Ð¾Ð´Ñ\85одÑ\8fÑ\89его ÐºÐ»Ñ\8eÑ\87а: %s\n"
+msgstr "в ÐºÐ°Ñ\80Ñ\82е Ð½Ðµ Ð¾Ð±Ð½Ð°Ñ\80Ñ\83жен Ð¿Ñ\80игоднÑ\8bй ÐºÐ»Ñ\8eÑ\87: %s\n"
 
 #, c-format
 msgid "shadowing the key failed: %s\n"
-msgstr "сбой при затенении ключа: %s\n"
+msgstr ""
 
 #, c-format
 msgid "error writing key: %s\n"
 msgstr "сбой записи ключа: %s\n"
 
 #, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-"Процесс ssh запросил доступ к ключу%%0A  %s%%0A  (%s)%%0AВы хотите это "
-"позволить?"
-
-msgid "Allow"
-msgstr "Позволить"
-
-msgid "Deny"
-msgstr "Отказать"
-
-#, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
-msgstr "Введите фразу-пароль для ключа ssh%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
+msgstr "Введите фразу-пароль для ssh ключа%0A  %c"
 
 msgid "Please re-enter this passphrase"
 msgstr "Повторно введите фразу-пароль:"
 
 #, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
-"Введите фразу-пароль для защиты полученного закрытого ключа%%0A   %s%%0A   %s"
-"%%0Aвнутри хранилища ключей агента gpg"
+"Введите фразу-пароль для защиты принятого закрытого ключа%%0A   %s%%0Aвнутри "
+"хранилища ключей gpg-agent"
 
 msgid "does not match - try again"
 msgstr "не совпало, попробуйте еще раз"
@@ -187,43 +130,45 @@ msgid "failed to create stream from socket: %s\n"
 msgstr "сбой создания потока из сокета: %s\n"
 
 msgid "Please insert the card with serial number"
-msgstr "Вставьте карту с серийным номером"
+msgstr ""
 
 msgid "Please remove the current card and insert the one with serial number"
-msgstr "Удалите текущую карту и вставьте карту с серийным номером"
+msgstr ""
 
 msgid "Admin PIN"
-msgstr "Административный PIN"
+msgstr "Административный PID"
 
 #. TRANSLATORS: A PUK is the Personal Unblocking Code
 #. used to unblock a PIN.
 msgid "PUK"
-msgstr "Код разблокировки PIN (PUK)"
+msgstr ""
 
 msgid "Reset Code"
-msgstr "Код сброса"
+msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
-msgstr "%s%%0A%%0AВводите на клавиатуре считывателя."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
+msgstr ""
 
 msgid "Repeat this Reset Code"
-msgstr "Повторите код сброса"
+msgstr "Повторить Reset Code"
 
+#, fuzzy
 msgid "Repeat this PUK"
-msgstr "Повторите ввод PUK"
+msgstr "Повторите ввод PIN"
 
 msgid "Repeat this PIN"
 msgstr "Повторите ввод PIN"
 
 msgid "Reset Code not correctly repeated; try again"
-msgstr "Код сброса повторен неверно; попробуйте еще раз"
+msgstr "Reset Code не повторен корректно; попробуйте еще раз"
 
+#, fuzzy
 msgid "PUK not correctly repeated; try again"
-msgstr "PUK повторен неверно; попробуйте еще раз"
+msgstr "повторный PIN не совпал; попробуйте еще раз"
 
 msgid "PIN not correctly repeated; try again"
-msgstr "PIN повторен неверно; попробуйте еще раз"
+msgstr "повторный PIN не совпал; попробуйте еще раз"
 
 #, c-format
 msgid "Please enter the PIN%s%s%s to unlock the card"
@@ -241,7 +186,7 @@ msgid "Enter new passphrase"
 msgstr "Введите новую фразу-пароль"
 
 msgid "Take this one anyway"
-msgstr "Ð\92Ñ\81е Ñ\80авно Ð¿Ñ\80инÑ\8fть"
+msgstr "Ð\9fÑ\80инÑ\8fÑ\82Ñ\8c ÐºÐ°Ðº ÐµÑ\81ть"
 
 #, c-format
 msgid ""
@@ -251,13 +196,13 @@ msgid_plural ""
 "Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
 "at least %u characters long."
 msgstr[0] ""
-"Ð\92нимание: Ð\92Ñ\8b Ð²Ð²ÐµÐ»Ð¸ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\83Ñ\8e Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c.%%0AФÑ\80аза-паÑ\80олÑ\8c должна "
+"Ð\92нимание: Ð\92Ñ\8b Ð²Ð²ÐµÐ»Ð¸ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\83Ñ\8e Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c.%%0AÐ\94лина Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f должна "
 "содержать не менее %u знака."
 msgstr[1] ""
-"Ð\92нимание: Ð\92Ñ\8b Ð²Ð²ÐµÐ»Ð¸ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\83Ñ\8e Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c.%%0AФÑ\80аза-паÑ\80олÑ\8c должна "
+"Ð\92нимание: Ð\92Ñ\8b Ð²Ð²ÐµÐ»Ð¸ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\83Ñ\8e Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c.%%0AÐ\94лина Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f должна "
 "содержать не менее %u знаков."
 msgstr[2] ""
-"Ð\92нимание: Ð\92Ñ\8b Ð²Ð²ÐµÐ»Ð¸ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\83Ñ\8e Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c.%%0AФÑ\80аза-паÑ\80олÑ\8c должна "
+"Ð\92нимание: Ð\92Ñ\8b Ð²Ð²ÐµÐ»Ð¸ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\83Ñ\8e Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c.%%0AÐ\94лина Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f должна "
 "содержать не менее %u знаков."
 
 #, c-format
@@ -269,13 +214,13 @@ msgid_plural ""
 "contain at least %u digits or%%0Aspecial characters."
 msgstr[0] ""
 "Внимание: Вы ввели небезопасную фразу-пароль.%%0AФраза-пароль должна "
-"Ñ\81одеÑ\80жаÑ\82Ñ\8c Ð¿Ð¾ Ð¼ÐµÐ½Ñ\8cÑ\88ей Ð¼ÐµÑ\80е %u Ñ\86иÑ\84Ñ\80Ñ\83 Ð¸Ð»Ð¸ %%0Aспециальный символ."
+"Ñ\81одеÑ\80жаÑ\82Ñ\8c Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %u Ñ\81имвола, Ð»Ð¸Ð±Ð¾ %%0Aспециальный символ."
 msgstr[1] ""
 "Внимание: Вы ввели небезопасную фразу-пароль.%%0AФраза-пароль должна "
-"Ñ\81одеÑ\80жаÑ\82Ñ\8c Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %u Ñ\86иÑ\84Ñ\80 Ð¸Ð»Ð¸%%0AÑ\81пеÑ\86иалÑ\8cнÑ\8bÑ\85 Ñ\81имволов."
+"Ñ\81одеÑ\80жаÑ\82Ñ\8c Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %u Ñ\81имвола, Ð»Ð¸Ð±Ð¾ %%0AÑ\81пеÑ\86иалÑ\8cнÑ\8bÑ\85 Ñ\81имвола."
 msgstr[2] ""
 "Внимание: Вы ввели небезопасную фразу-пароль.%%0AФраза-пароль должна "
-"Ñ\81одеÑ\80жаÑ\82Ñ\8c Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %u Ñ\86иÑ\84Ñ\80 Ð¸Ð»Ð¸%%0AÑ\81пеÑ\86иалÑ\8cнÑ\8bÑ\85 символов."
+"Ñ\81одеÑ\80жаÑ\82Ñ\8c Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %u Ñ\81имволов, Ð»Ð¸Ð±Ð¾ %%0AÑ\81пеÑ\86иалÑ\8cнÑ\8bй символов."
 
 #, c-format
 msgid ""
@@ -295,14 +240,14 @@ msgid ""
 "You have not entered a passphrase - this is in general a bad idea!%0APlease "
 "confirm that you do not want to have any protection on your key."
 msgstr ""
-"Вы не ввели фразу-пароль - это, как правило, плохая мысль!%0A Подтвердите, "
-"что Вы действительно не хотите защитить свой ключ."
+"Вы не ввели фразу-пароль - это весьма неудачное решение!%0A Подтвердите, что "
+"Вы действительно не хотите защитить Ваш ключ."
 
 msgid "Yes, protection is not needed"
-msgstr "Да, защита не нужна"
+msgstr "Ð\94а, Ð·Ð°Ñ\89иÑ\82а Ð¼Ð½Ðµ Ð½Ðµ Ð½Ñ\83жна"
 
 #, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr "Введите фразу-пароль%0Aдля защиты нового ключа"
 
 msgid "Please enter the new passphrase"
@@ -315,32 +260,32 @@ msgstr ""
 "@Параметры:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "запуск в режиме демона (фоновый режим)"
-
 msgid "run in server mode (foreground)"
-msgstr "запуск в режиме сервера (нефоновый режим)"
+msgstr "запуск в режиме сервера (foreground)"
+
+msgid "run in daemon mode (background)"
+msgstr "запуск в режиме демона (background)"
 
 msgid "verbose"
 msgstr "подробно"
 
 msgid "be somewhat more quiet"
-msgstr "Ñ\81окÑ\80аÑ\82иÑ\82Ñ\8c Ð¿Ð¾Ð´Ñ\80обноÑ\81Ñ\82и"
+msgstr "Ñ\83менÑ\8cÑ\88иÑ\82Ñ\8c ÐºÐ¾Ð»Ð¸Ñ\87еÑ\81Ñ\82во Ð²Ñ\8bводимой Ð¸Ð½Ñ\84оÑ\80маÑ\86ии"
 
 msgid "sh-style command output"
-msgstr "вывод команды в стиле sh"
+msgstr "вывод результатов в sh-стиле"
 
 msgid "csh-style command output"
-msgstr "вывод команды в стиле csh"
+msgstr "вывод результатов в csh-стиле"
 
 msgid "|FILE|read options from FILE"
-msgstr "|FILE|взять параметры из файла FILE"
+msgstr "|FILE|взять параметры из FILE"
 
 msgid "do not detach from the console"
 msgstr "не отсоединяться от консоли"
 
 msgid "do not grab keyboard and mouse"
-msgstr "не Ð·Ð°Ñ\85ваÑ\82Ñ\8bваÑ\82Ñ\8c ÐºÐ»Ð°Ð²Ð¸Ð°Ñ\82Ñ\83Ñ\80Ñ\83 Ð¸ Ð¼Ñ\8bÑ\88Ñ\8c"
+msgstr "не Ð¿ÐµÑ\80еÑ\85ваÑ\82Ñ\8bваÑ\82Ñ\8c Ñ\81обÑ\8bÑ\82иÑ\8f Ð¼Ñ\8bÑ\88и Ð¸ ÐºÐ»Ð°Ð²Ð¸Ð°Ñ\82Ñ\83Ñ\80Ñ\8b"
 
 msgid "use a log file for the server"
 msgstr "использовать файл журнала для сервера"
@@ -349,52 +294,46 @@ msgid "use a standard location for the socket"
 msgstr "стандартное расположение сокета"
 
 msgid "|PGM|use PGM as the PIN-Entry program"
-msgstr "|PGM|использовать программу PGM для ввода паролей"
+msgstr "|PGM|использовать PGM как PIN-Entry"
 
 msgid "|PGM|use PGM as the SCdaemon program"
-msgstr "|PGM| использовать программу PGM как SCdaemon"
+msgstr "|PGM| использовать PGM как SCdaemon"
 
 msgid "do not use the SCdaemon"
 msgstr "не использовать SCdaemon"
 
 msgid "ignore requests to change the TTY"
-msgstr "игнорировать запросы смены терминала"
+msgstr "игнорировать запросы смены TTY"
 
 msgid "ignore requests to change the X display"
-msgstr "игнорировать запросы смены дисплея XWindow"
+msgstr "игнорировать запросы смены X дисплея"
 
 msgid "|N|expire cached PINs after N seconds"
-msgstr "|N|сбрасывать запомненный PIN через N секунд"
+msgstr "|N|кеш PIN просрочен после N секунд"
 
 msgid "do not use the PIN cache when signing"
-msgstr "не Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð·Ð°Ð¿Ð¾Ð¼Ð½ÐµÐ½Ð½Ñ\8bй PIN при подписывании"
+msgstr "не Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c ÐºÐµÑ\88 PIN при подписывании"
 
-msgid "disallow clients to mark keys as \"trusted\""
-msgstr "не Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñ\8fÑ\82Ñ\8c ÐºÐ»Ð¸ÐµÐ½Ñ\82ам Ð¿Ð¾Ð¼ÐµÑ\87аÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87и ÐºÐ°Ðº \"довеÑ\80енные\""
+msgid "allow clients to mark keys as \"trusted\""
+msgstr "позволиÑ\82Ñ\8c ÐºÐ»Ð¸ÐµÐ½Ñ\82ам Ð¿Ð¾Ð¼ÐµÑ\87аÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87и ÐºÐ°Ðº \"довеÑ\80Ñ\8fемые\""
 
 msgid "allow presetting passphrase"
-msgstr "разрешить предустанавливать фразу-пароль"
-
-msgid "enable ssh support"
-msgstr "включить поддержку ssh"
-
-msgid "enable putty support"
-msgstr "включить поддержку putty"
+msgstr "разрешить предустановленную фразу-пароль"
 
-msgid "disallow the use of an external password cache"
-msgstr "не позволять пользоваться внешней памятью паролей"
+msgid "enable ssh-agent emulation"
+msgstr "разрешить эмуляцию ssh-агента"
 
 msgid "|FILE|write environment settings also to FILE"
-msgstr "|FILE|сохранить состояние среды также в файл FILE"
+msgstr "|FILE|сохранить состояние окружения и в файл"
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
 msgid "Please report bugs to <@EMAIL@>.\n"
-msgstr "О найденных ошибках сообщайте по адресу <@EMAIL@>.\n"
+msgstr "О найденных ошибка сообщайте <@EMAIL@>.\n"
 
 msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: gpg-agent [параметры] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: gpg-agent [параметры] (-h для подсказки)"
 
 msgid ""
 "Syntax: gpg-agent [options] [command [args]]\n"
@@ -404,31 +343,31 @@ msgstr ""
 "Управление закрытыми ключами для GnuPG\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
-msgstr "запрошен недопустимый уровень отладки `%s'\n"
+msgid "invalid debug-level '%s' given\n"
+msgstr "запрошен недупустимый уровень отладки `%s'\n"
 
 #, c-format
 msgid "%s is too old (need %s, have %s)\n"
-msgstr "Слишком старая версия %s (нужно %s, есть %s)\n"
+msgstr "%s слишком устарело (требуется %s, имеется %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
-msgstr "ЗАМЕЧАНИЕ: основной файл параметров `%s' не обнаружен\n"
+msgid "NOTE: no default option file '%s'\n"
+msgstr "ЗАМЕЧАНИЕ: файл конфигурации `%s' не обнаружен\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
-msgstr "Ñ\84айл Ð¿Ð°Ñ\80амеÑ\82Ñ\80ов `%s': %s\n"
+msgid "option file '%s': %s\n"
+msgstr "Ñ\84айл ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80аÑ\86ии `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
-msgstr "чтение параметров из `%s'\n"
+msgid "reading options from '%s'\n"
+msgstr "параметры конфигурации из файла `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "ошибка создания `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "не могу создать каталог `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -439,87 +378,87 @@ msgid "can't create socket: %s\n"
 msgstr "не могу создать сокет: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
-msgstr "слишком дленное имя сокета `%s'\n"
+msgid "socket name '%s' is too long\n"
+msgstr "имя сокета `%s' слишком длинное\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
-msgstr "агент gpg уже запущен - еще один, новый, запущен не будет\n"
+msgstr "gpg-agent уже запущен - еще один, новый, запущен не будет\n"
 
 msgid "error getting nonce for the socket\n"
-msgstr "ошибка получения разового кода для сокета\n"
+msgstr ""
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
-msgstr "оÑ\88ибка Ñ\81вÑ\8fзÑ\8bваниÑ\8f Ñ\81океÑ\82а Ñ\81 `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
+msgstr "ошибка связывния сокета с `%s': %s\n"
 
 #, c-format
 msgid "listen() failed: %s\n"
-msgstr "сбой listen(): %s\n"
+msgstr ""
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "слушаем сокет `%s'\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "создан каталог `%s'\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
-msgstr "сбой stat() для `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
+msgstr ""
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "невозможно использовать `%s' как домашний каталог\n"
 
 #, c-format
 msgid "error reading nonce on fd %d: %s\n"
-msgstr "ошибка чтения разового кода из файлового дескриптора %d: %s\n"
+msgstr ""
 
 #, c-format
 msgid "handler 0x%lx for fd %d started\n"
-msgstr "обработчик 0x%lx для файлового дескриптора %d запущен\n"
+msgstr ""
 
 #, c-format
 msgid "handler 0x%lx for fd %d terminated\n"
-msgstr "обработчик 0x%lx для файлового дескриптора %d завершился\n"
+msgstr ""
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d started\n"
-msgstr "обработчик ssh 0x%lx для файлового дескриптора %d запущен\n"
+msgstr ""
 
 #, c-format
 msgid "ssh handler 0x%lx for fd %d terminated\n"
-msgstr "обработчик ssh 0x%lx для файлового дескриптора %d завершился\n"
+msgstr ""
 
 #, c-format
 msgid "pth_select failed: %s - waiting 1s\n"
-msgstr "сбой pth_select: %s - жду 1 секунду\n"
+msgstr ""
 
 #, c-format
 msgid "%s %s stopped\n"
 msgstr "%s %s: остановлен\n"
 
 msgid "no gpg-agent running in this session\n"
-msgstr "в Ñ\8dÑ\82ом Ñ\81еанÑ\81е Ð°Ð³ÐµÐ½Ñ\82 gpg Ð½Ðµ Ñ\80абоÑ\82аеÑ\82\n"
+msgstr "неÑ\82 gpg-agent Ð´Ð¾Ñ\81Ñ\82Ñ\83пого Ð´Ð»Ñ\8f Ð´Ð°Ð½Ð½Ð¾Ð¹ Ñ\81еÑ\81Ñ\81ии\n"
 
 msgid "malformed GPG_AGENT_INFO environment variable\n"
 msgstr "неправильная переменная окружения GPG_AGENT_INFO\n"
 
 #, c-format
 msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "протокол агента gpg версии %d не поддерживается\n"
+msgstr "протокол gpg-agent версии %d не поддерживается\n"
 
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
 msgstr ""
-"Ð\92Ñ\8bзов: gpg-preset-passphrase [паÑ\80амеÑ\82Ñ\80Ñ\8b] Ð\9aÐ\9eÐ\94\9aÐ\9bЮЧÐ\90 (-h для подсказки)\n"
+"Ð\98Ñ\81полÑ\8cзование: gpg-preset-passphrase [паÑ\80амеÑ\82Ñ\80Ñ\8b] KEYGRIP (-h для подсказки)\n"
 
 msgid ""
 "Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
 "Password cache maintenance\n"
 msgstr ""
-"Синтаксис: gpg-preset-passphrase [параметры] КОД_КЛЮЧА\n"
-"РабоÑ\82а Ñ\81 Ð±Ñ\83Ñ\84еÑ\80ом паролей\n"
+"Синтаксис: gpg-preset-passphrase [параметры] KEYGRIP\n"
+"Ð\9aеÑ\88иÑ\80ование паролей\n"
 
 msgid ""
 "@Commands:\n"
@@ -538,20 +477,20 @@ msgstr ""
 " "
 
 msgid "Usage: gpg-protect-tool [options] (-h for help)\n"
-msgstr "Ð\92Ñ\8bзов: gpg-protect-tool [параметры] (-h для подсказки)\n"
+msgstr "Ð\98Ñ\81полÑ\8cзование: gpg-protect-tool [параметры] (-h для подсказки)\n"
 
 msgid ""
 "Syntax: gpg-protect-tool [options] [args]\n"
 "Secret key maintenance tool\n"
 msgstr ""
 "Синтаксис: gpg-protect-tool [параметры] [аргументы]\n"
-"СÑ\80едÑ\81Ñ\82во работы с закрытыми ключами\n"
+"Ð\98нÑ\81Ñ\82Ñ\80Ñ\83менÑ\82 Ð´Ð»Ñ\8f работы с закрытыми ключами\n"
 
 msgid "Please enter the passphrase to unprotect the PKCS#12 object."
-msgstr "Введите фразу-пароль для снятия защиты с объекта PKCS#12."
+msgstr "Введите фразу-пароль для доступа к PKCS#12 объекту."
 
 msgid "Please enter the passphrase to protect the new PKCS#12 object."
-msgstr "Введите фразу-пароль для защиты нового объекта PKCS#12."
+msgstr "Введите фразу-пароль для защиты нового PKCS#12 объекта."
 
 msgid ""
 "Please enter the passphrase to protect the imported object within the GnuPG "
@@ -562,8 +501,8 @@ msgid ""
 "Please enter the passphrase or the PIN\n"
 "needed to complete this operation."
 msgstr ""
-"Введите фразу-пароль или PIN,\n"
-"необÑ\85одимÑ\8bе Ð´Ð»Ñ\8f Ð²Ñ\8bполнениÑ\8f Ð´Ð°Ð½Ð½Ð¾Ð¹ Ð¾Ð¿ÐµÑ\80аÑ\86ии."
+"Введите фразу-пароль или PIN\n"
+"необходимые для выполения данной операции."
 
 msgid "Passphrase:"
 msgstr "Фраза-пароль:"
@@ -576,35 +515,35 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "ошибка запроса ввода фразы-пароля: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "ошибка открытия `%s': %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "файл `%s', строка %d: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
-msgstr "выражение \"%s\" в `%s' игнорируется, строка %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
+msgstr ""
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
-msgstr "системный список доверия `%s' не доступен\n"
+msgid "system trustlist '%s' not available\n"
+msgstr "системный список доверий `%s' не доступен\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "недопустимый отпечаток в `%s', строка %d\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
-msgstr "недопустимый признак ключа в `%s', строка %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
+msgstr ""
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "ошибка чтения `%s', строка %d: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
-msgstr "ошибка чтения списка доверенных корневых сертификатов\n"
+msgstr "ошибка чтения списка доверяемых корневых сертификатов\n"
 
 #. TRANSLATORS: This prompt is shown by the Pinentry
 #. and has one special property: A "%%0A" is used by
@@ -619,8 +558,8 @@ msgid ""
 "Do you ultimately trust%%0A  \"%s\"%%0Ato correctly certify user "
 "certificates?"
 msgstr ""
-"Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ð°Ð±Ñ\81олÑ\8eÑ\82но Ð²ÐµÑ\80иÑ\82Ñ\8c, Ñ\87Ñ\82о%%0A  \"%s\"%%0AпÑ\80авилÑ\8cно Ñ\81еÑ\80Ñ\82иÑ\84иÑ\86иÑ\80Ñ\83еÑ\82 "
-"сертификаты пользователя?"
+"Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ð°Ð±Ñ\81олÑ\8eÑ\82но Ð´Ð¾Ð²ÐµÑ\80Ñ\8fÑ\82Ñ\8c%%0A  \"%s\"%%0AкоÑ\80Ñ\80екÑ\82но Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аннÑ\8bм "
+"сертификатам пользователя?"
 
 msgid "Yes"
 msgstr "Да"
@@ -641,7 +580,8 @@ msgid ""
 "Please verify that the certificate identified as:%%0A  \"%s\"%%0Ahas the "
 "fingerprint:%%0A  %s"
 msgstr ""
-"Проверьте, что отпечаток сертификата%%0A  \"%s\"%%0Aсовпадает с%%0A  %s"
+"Проверьте, что сертификат идентифицированный как:%%0A  \"%s\"%%0Aимеет "
+"отпечаток:%%0A  %s"
 
 #. TRANSLATORS: "Correct" is the label of a button and intended
 #. to be hit if the fingerprint matches the one of the CA.  The
@@ -650,77 +590,78 @@ msgid "Correct"
 msgstr "Подтверждаю"
 
 msgid "Wrong"
-msgstr "Неверно"
+msgstr ""
 
 #, c-format
 msgid "Note: This passphrase has never been changed.%0APlease change it now."
 msgstr ""
-"Замечание: Фразу-пароль никогда не меняли.%0AПожалуйста, смените ее сейчас."
+"Замечание: Фразу-пароль ни разу не сменяли.%0AПожалуйста, смените ее сейчас."
 
 #, c-format
 msgid ""
 "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s.  Please change "
 "it now."
 msgstr ""
-"Фраза-пароль не менялась%%0Aс %.4s-%.2s-%.2s. Пожалуйста, смените ее сейчас."
+"Фраза пароль не сменялась%%0Aс %.4s-%.2s-%.2s.  Пожалуйста, смените ее "
+"сейчас."
 
 msgid "Change passphrase"
-msgstr "Сменить фразу-пароль"
+msgstr "Cменить фразу-пароль"
 
 msgid "I'll change it later"
 msgstr "Сменю позже"
 
 #, c-format
 msgid "error creating a pipe: %s\n"
-msgstr "ошибка при создании канала конвейера: %s\n"
+msgstr ""
 
 #, c-format
 msgid "can't fdopen pipe for reading: %s\n"
-msgstr "отказ при вызове fdopen на чтение: %s\n"
+msgstr ""
 
 #, c-format
 msgid "error forking process: %s\n"
-msgstr "ошибка при дублировании процесса: %s\n"
+msgstr ""
 
 #, c-format
 msgid "waiting for process %d to terminate failed: %s\n"
-msgstr "сбой при ожидании завершения процесса %d: %s\n"
+msgstr ""
 
 #, c-format
 msgid "error getting exit code of process %d: %s\n"
 msgstr "ошибка получения кода возврата процесса %d: %s\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "ошибка чтения `%s': статус завершения %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr "оÑ\88ибка Ð·Ð°Ð¿Ñ\83Ñ\81ка `%s': Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾, не установлен\n"
+msgid "error running '%s': probably not installed\n"
+msgstr "оÑ\88ибка Ð·Ð°Ð¿Ñ\83Ñ\81ка `%s': Ð¿Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ не установлен\n"
 
 #, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "ошибка чтения `%s': прервано\n"
 
 #, c-format
 msgid "error creating socket: %s\n"
-msgstr "ошибка при создании сокета: %s\n"
+msgstr ""
 
 msgid "host not found"
 msgstr "хост не найден"
 
 msgid "gpg-agent is not available in this session\n"
-msgstr "в данном сеансе агент gpg недоступен\n"
+msgstr "gpg-agent недоступен в данной сессии\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "не могу подключиться к `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
-msgstr "проблема связи с агентом gpg\n"
+msgstr "проблема связи с gpg-agent\n"
 
 msgid "problem setting the gpg-agent options\n"
-msgstr "проблема задания параметров агента gpg\n"
+msgstr "проблема задания параметров gpg-agent\n"
 
 msgid "canceled by user\n"
 msgstr "прервано пользователем\n"
@@ -730,7 +671,7 @@ msgstr "проблема с агентом\n"
 
 #, c-format
 msgid "can't disable core dumps: %s\n"
-msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð¾Ñ\82клÑ\8eÑ\87иÑ\82Ñ\8c Ñ\81оздание Ñ\84айла ÐºÐ¾Ð¿Ð¸Ð¸ образа памяти: %s\n"
+msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð¾Ñ\82клÑ\8eÑ\87иÑ\82Ñ\8c Ñ\81оздание Ñ\84айла Ð´Ð°Ð¼Ð¿Ð° образа памяти: %s\n"
 
 #, c-format
 msgid "Warning: unsafe ownership on %s \"%s\"\n"
@@ -742,88 +683,74 @@ msgstr "ВНИМАНИЕ: небезопасные права доступа %s
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "yes"
-msgstr "да|yes"
+msgstr "да|Да|yes|Yes"
 
 msgid "yY"
 msgstr "yY"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "no"
-msgstr "нет|no"
+msgstr "нет|Нет|no|No"
 
 msgid "nN"
 msgstr "nN"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "quit"
-msgstr "выход|quit"
+msgstr "quit"
 
 msgid "qQ"
-msgstr "qQ"
+msgstr ""
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "okay|okay"
-msgstr "готово|okay"
+msgstr ""
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "cancel|cancel"
-msgstr "отбой|cancel"
+msgstr ""
 
 msgid "oO"
-msgstr "oO"
+msgstr ""
 
 msgid "cC"
-msgstr "cC"
+msgstr ""
 
 #, c-format
 msgid "out of core in secure memory while allocating %lu bytes"
-msgstr "вÑ\8bÑ\85од Ð·Ð° Ð¿Ñ\80едел Ð±ÐµÐ·Ð¾Ð¿Ð°Ñ\81ной памяти при распределении %lu байтов"
+msgstr "вÑ\8bÑ\85од Ð·Ð° Ð±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\8bй Ð¿Ñ\80едел памяти при распределении %lu байтов"
 
 #, c-format
 msgid "out of core while allocating %lu bytes"
 msgstr "выход за границы при распределении %lu байтов"
 
 msgid "no running gpg-agent - starting one\n"
-msgstr "агент gpg не работает - запускаем\n"
-
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "даю агенту %d секунд на подключение\n"
+msgstr "нет работающих gpg-agent - запускаем\n"
 
 msgid "can't connect to the agent - trying fall back\n"
-msgstr "невозможно подключиться к агенту - пробую более надежный вариант\n"
+msgstr "невозможно подключиться к агенту - пробуем откатиться назад\n"
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
 msgid "|audit-log-result|Good"
-msgstr "|audit-log-result|Все хорошие"
+msgstr ""
 
 msgid "|audit-log-result|Bad"
-msgstr "|audit-log-result|Все плохие"
+msgstr ""
 
 msgid "|audit-log-result|Not supported"
-msgstr "|audit-log-result|Не поддерживаются"
+msgstr ""
 
+#, fuzzy
 msgid "|audit-log-result|No certificate"
-msgstr "|audit-log-result|Нет сертификата"
+msgstr "импорт сертификатов"
 
+#, fuzzy
 msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|Отключены"
+msgstr "импорт сертификатов"
 
 msgid "|audit-log-result|Error"
-msgstr "|audit-log-result|Ошибка"
-
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|Не используются"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|В порядке"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|Игнорируется"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|Некоторые"
+msgstr ""
 
 msgid "Certificate chain available"
 msgstr "Доступна цепочка сертификатов"
@@ -832,13 +759,13 @@ msgid "root certificate missing"
 msgstr "отсутствует корневой сертификат"
 
 msgid "Data encryption succeeded"
-msgstr "Данные успешно зашифрованы"
+msgstr "Данные зашифрованы"
 
 msgid "Data available"
 msgstr "Данные доступны"
 
 msgid "Session key created"
-msgstr "Сеансовый ключ создан"
+msgstr "Сессионный ключ создан"
 
 #, c-format
 msgid "algorithm: %s"
@@ -846,10 +773,10 @@ msgstr "алгоритм: %s"
 
 #, c-format
 msgid "unsupported algorithm: %s"
-msgstr "алгоÑ\80иÑ\82м (не Ð¿Ð¾Ð´Ð´ÐµÑ\80живаеÑ\82Ñ\81Ñ\8f): %s"
+msgstr "неподдеÑ\80живаемÑ\8bй Ð°Ð»Ð³Ð¾Ñ\80иÑ\82м: %s"
 
 msgid "seems to be not encrypted"
-msgstr "кажеÑ\82Ñ\81Ñ\8f, Ð½Ðµ Ð·Ð°Ñ\88иÑ\84Ñ\80овано"
+msgstr "поÑ\85оже Ð½Ð° Ð½Ðµ Ð·Ð°Ñ\88иÑ\84Ñ\80ованное"
 
 msgid "Number of recipients"
 msgstr "Количество получателей"
@@ -859,25 +786,10 @@ msgid "Recipient %d"
 msgstr "Получатель %d"
 
 msgid "Data signing succeeded"
-msgstr "Данные успешно подписаны"
-
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "хэш-функция данных: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "Подпись %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "хэш-функция атрибутов: %s"
+msgstr "Данные подписаны"
 
 msgid "Data decryption succeeded"
-msgstr "Данные успешно расшифрованы"
-
-msgid "Encryption algorithm supported"
-msgstr "Алгоритм шифрования поддерживается"
+msgstr "Данные расшифрованы"
 
 msgid "Data verification succeeded"
 msgstr "Данные проверены"
@@ -885,31 +797,31 @@ msgstr "Данные проверены"
 msgid "Signature available"
 msgstr "Подпись доступна"
 
-msgid "Parsing data succeeded"
-msgstr "РазбоÑ\80 Ð´Ð°Ð½Ð½Ñ\8bÑ\85 завершен"
+msgid "Parsing signature succeeded"
+msgstr "РазбоÑ\80 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и завершен"
 
 #, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "недопÑ\83Ñ\81Ñ\82имаÑ\8f Ñ\85Ñ\8dÑ\88\84Ñ\83нкÑ\86иÑ\8f Ð´Ð°Ð½Ð½Ñ\8bÑ\85: %s"
+msgid "Bad hash algorithm: %s"
+msgstr "Ð\9dедопÑ\83Ñ\81Ñ\82имаÑ\8f Ñ\85Ñ\8dÑ\88\84Ñ\83нкÑ\86иÑ\8f: %s"
 
 #, c-format
 msgid "Signature %d"
 msgstr "Подпись %d"
 
 msgid "Certificate chain valid"
-msgstr "Цепочка сертификатов действительна"
+msgstr "Цепочка сертифицирования действительна"
 
 msgid "Root certificate trustworthy"
 msgstr "Корневой сертификат достоверен"
 
 msgid "no CRL found for certificate"
-msgstr "длÑ\8f Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82а Ð½Ðµ Ð½Ð°Ð¹Ð´ÐµÐ½ Ñ\81пиÑ\81ок Ð¾Ñ\82озваннÑ\8bÑ\85 Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82ов"
+msgstr "не Ð½Ð°Ð¹Ð´ÐµÐ½Ð° CRL Ð´Ð»Ñ\8f Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82а"
 
 msgid "the available CRL is too old"
-msgstr "доступный список отозванных сертификатов слишком стар"
+msgstr "достпуная CRL слишком стара"
 
 msgid "CRL/OCSP check of certificates"
-msgstr "проверка списка отозванных сертификатов/OCSP для сертификата"
+msgstr "проверка CRL/OCSP сертификата"
 
 msgid "Included certificates"
 msgstr "Задействованные сертификаты"
@@ -921,62 +833,62 @@ msgid "Unknown operation"
 msgstr "Неизвестная операция"
 
 msgid "Gpg-Agent usable"
-msgstr "Агент Gpg годен"
+msgstr "Gpg-Agent доступен"
 
 msgid "Dirmngr usable"
-msgstr "Dirmgr Ð³Ð¾Ð´ен"
+msgstr "Dirmgr Ð´Ð¾Ñ\81Ñ\82Ñ\83пен"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Нет справки для `%s'."
 
 msgid "ignoring garbage line"
 msgstr "игнорируем дефектную строку"
 
 msgid "[none]"
-msgstr "[оÑ\82Ñ\81Ñ\83Ñ\82Ñ\81Ñ\82вÑ\83ет]"
+msgstr "[нет]"
 
 #, c-format
 msgid "armor: %s\n"
-msgstr "Ñ\82екÑ\81Ñ\82овÑ\8bй Ñ\84оÑ\80маÑ\82: %s\n"
+msgstr "Ñ\84оÑ\80маÑ\82 ASCII: %s\n"
 
 msgid "invalid armor header: "
-msgstr "недопÑ\83Ñ\81Ñ\82имÑ\8bй Ñ\82екÑ\81Ñ\82овÑ\8bй Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº: "
+msgstr "непÑ\80авилÑ\8cнÑ\8bй Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº ASCII: "
 
 msgid "armor header: "
-msgstr "текстовый заголовок: "
+msgstr "заголовок ASCII: "
 
 msgid "invalid clearsig header\n"
-msgstr "недопÑ\83Ñ\81Ñ\82имÑ\8bй Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ñ\82екÑ\81Ñ\82овой подписи\n"
+msgstr "непÑ\80авилÑ\8cнÑ\8bй Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ð¿Ñ\80озÑ\80аÑ\87ной подписи\n"
 
 msgid "unknown armor header: "
-msgstr "неизвеÑ\81Ñ\82нÑ\8bй Ñ\82екÑ\81Ñ\82овÑ\8bй Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº: "
+msgstr "недопÑ\83Ñ\81Ñ\82имÑ\8bй Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº ASCII: "
 
 msgid "nested clear text signatures\n"
-msgstr "вложенные текстовые подписи\n"
+msgstr "вложенные прозрачные подписи\n"
 
 msgid "unexpected armor: "
-msgstr "неожиданнÑ\8bй Ñ\82екÑ\81Ñ\82овÑ\8bй Ñ\84оÑ\80маÑ\82"
+msgstr "неожидаемÑ\8bй Ñ\84оÑ\80маÑ\82 ASCII:"
 
 msgid "invalid dash escaped line: "
-msgstr "недопÑ\83Ñ\81Ñ\82имаÑ\8f Ñ\81Ñ\82Ñ\80ока, Ð²Ñ\8bделеннаÑ\8f Ð´ÐµÑ\84иÑ\81ами: "
+msgstr "непÑ\80авилÑ\8cнÑ\8bй Ð¾Ñ\82Ñ\81Ñ\82Ñ\83п Ð¸Ð· Ð¼Ð¸Ð½Ñ\83Ñ\81ов: "
 
 #, c-format
 msgid "invalid radix64 character %02X skipped\n"
-msgstr "недопустимый символ radix64 %02X (игнорируется)\n"
+msgstr "недопустимый символ radix64 %02X пропущен\n"
 
 msgid "premature eof (no CRC)\n"
-msgstr "преждевременный конец файла (нет контрольной суммы)\n"
+msgstr "преждевременный конец файла (нет CRC)\n"
 
 msgid "premature eof (in CRC)\n"
-msgstr "преждевременный конец файла (в контрольной сумме)\n"
+msgstr "преждевременный конец файла (в CRC)\n"
 
 msgid "malformed CRC\n"
-msgstr "поврежденная контрольная сумма\n"
+msgstr "поврежденный CRC\n"
 
 #, c-format
 msgid "CRC error; %06lX - %06lX\n"
-msgstr "ошибка контрольной суммы; %06lX - %06lX\n"
+msgstr "ошибка CRC; %06lX - %06lX\n"
 
 msgid "premature eof (in trailer)\n"
 msgstr "преждевременный конец файла (в дополнении)\n"
@@ -989,36 +901,35 @@ msgstr "не найдено данных формата OpenPGP.\n"
 
 #, c-format
 msgid "invalid armor: line longer than %d characters\n"
-msgstr "недопÑ\83Ñ\81Ñ\82имÑ\8bй Ñ\82екÑ\81Ñ\82овÑ\8bй формат: строка длиннее %d символов\n"
+msgstr "непÑ\80авилÑ\8cнÑ\8bй ASCII формат: строка длиннее %d символов\n"
 
 msgid ""
 "quoted printable character in armor - probably a buggy MTA has been used\n"
 msgstr ""
-"символ quoted printable в текстовом формате - испорчено почтовой "
-"программой?\n"
+"символы quoted printable в кодировке ASCII - вероятно использовался плохой "
+"MTA\n"
 
 msgid ""
 "a notation name must have only printable characters or spaces, and end with "
 "an '='\n"
 msgstr ""
-"имÑ\8f Ð¿Ñ\80имеÑ\87аниÑ\8f Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñ\81одеÑ\80жаÑ\82Ñ\8c Ñ\82олÑ\8cко Ð¿ÐµÑ\87аÑ\82нÑ\8bе Ñ\81имволÑ\8b Ð¸Ð»Ð¸ Ð¿Ñ\80обелÑ\8b Ð¸ "
-"заканÑ\87иваÑ\82Ñ\8cÑ\81Ñ\8f Ð·Ð½Ð°ÐºÐ¾Ð¼ '='\n"
+"имÑ\8f Ð¿Ñ\80имеÑ\87аниÑ\8f Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñ\81одеÑ\80ажаÑ\82Ñ\8c Ñ\82олÑ\8cко Ð¿ÐµÑ\87аÑ\82нÑ\8bе Ñ\81имволÑ\8b Ð¸ Ð¿Ñ\80обелÑ\8b, Ð¸ '=' Ð½Ð° "
+"конÑ\86е\n"
 
 msgid "a user notation name must contain the '@' character\n"
-msgstr "имя примечания пользователя должно содержать символ '@'\n"
+msgstr "имя пользовательского примечания должно содержать символ '@'\n"
 
 msgid "a notation name must not contain more than one '@' character\n"
-msgstr ""
-"имя примечания пользователя не должно содержать более одного символа '@'\n"
+msgstr "имя примечания должно содержать не более одного символа '@'\n"
 
 msgid "a notation value must not use any control characters\n"
-msgstr "в Ð·Ð½Ð°Ñ\87ении Ð¿Ñ\80имеÑ\87аниÑ\8f Ð½Ðµ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ð±Ñ\8bть управляющих символов\n"
+msgstr "знаÑ\87ение Ð¿Ñ\80имеÑ\87аниÑ\8f Ð½Ðµ Ð´Ð¾Ð»Ð¶Ð½Ð¾ Ñ\81одеÑ\80жать управляющих символов\n"
 
 msgid "WARNING: invalid notation data found\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½Ð°Ð¹Ð´ÐµÐ½Ð° Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имаÑ\8f Ñ\84оÑ\80ма Ð·Ð°Ð¿Ð¸Ñ\81и Ð¿Ñ\80имеÑ\87аниÑ\8f\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¾Ð±Ð½Ð°Ñ\80Ñ\83жено Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имое Ð¿Ñ\80имеÑ\87ание\n"
 
 msgid "not human readable"
-msgstr "не для чтения человеком"
+msgstr "не читаемое человеком"
 
 #, c-format
 msgid "OpenPGP card not available: %s\n"
@@ -1026,19 +937,19 @@ msgstr "Карта OpenPGP недоступна: %s\n"
 
 #, c-format
 msgid "OpenPGP card no. %s detected\n"
-msgstr "Обнаружена карта OpenPGP номер %s\n"
+msgstr "Обнаружена карта OpenPGP номер %s \n"
 
 msgid "can't do this in batch mode\n"
-msgstr "в Ð¿Ð°ÐºÐµÑ\82ном Ñ\80ежиме Ñ\8dÑ\82о Ð´ÐµÐ¹Ñ\81Ñ\82вие Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾\n"
+msgstr "невозможно Ñ\81делаÑ\82Ñ\8c Ñ\8dÑ\82о Ð² Ð¿Ð°ÐºÐµÑ\82ном Ñ\80ежиме\n"
 
 msgid "This command is only available for version 2 cards\n"
-msgstr "ЭÑ\82а ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° Ð´Ð¾Ñ\81Ñ\82Ñ\83пна Ñ\82олÑ\8cко Ð´Ð»Ñ\8f ÐºÐ°Ñ\80Ñ\82 Ð²ÐµÑ\80Ñ\81ии 2.\n"
+msgstr "Ð\94аннаÑ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° Ð´Ð¾Ð¿Ñ\83Ñ\81Ñ\82има Ñ\82олÑ\8cко Ð´Ð»Ñ\8f ÐºÐ°Ñ\80Ñ\82 Ð²ÐµÑ\80Ñ\81ии 2\n"
 
 msgid "Reset Code not or not anymore available\n"
-msgstr "Код сброса (больше) не доступен\n"
+msgstr "Reset Code не задан или недоступен\n"
 
 msgid "Your selection? "
-msgstr "Ваш выбор? "
+msgstr "Ваш выбор (?-подробнее)? "
 
 msgid "[not set]"
 msgstr "[не установлено]"
@@ -1050,69 +961,68 @@ msgid "female"
 msgstr "женский"
 
 msgid "unspecified"
-msgstr "не указан"
+msgstr "не задан"
 
 msgid "not forced"
-msgstr "не Ð¿Ñ\80инÑ\83диÑ\82елÑ\8cнÑ\8bй"
+msgstr "оÑ\82клÑ\8eÑ\87ен"
 
 msgid "forced"
-msgstr "пÑ\80инÑ\83диÑ\82елÑ\8cнÑ\8bй"
+msgstr "вклÑ\8eÑ\87ен"
 
 msgid "Error: Only plain ASCII is currently allowed.\n"
-msgstr "Ошибка: Допустим только простой текст ASCII.\n"
+msgstr "Ошибка: Допустим только чистый ASCII.\n"
 
 msgid "Error: The \"<\" character may not be used.\n"
-msgstr "Ошибка: Нельзя использовать символ \"<\"\n"
+msgstr "Ошибка: Нельзя использовать символ \"<\".\n"
 
 msgid "Error: Double spaces are not allowed.\n"
 msgstr "Ошибка: Двойные пробелы недопустимы.\n"
 
 msgid "Cardholder's surname: "
-msgstr "Фамилия владельца карты: "
+msgstr "Фамилия владельца карты:"
 
 msgid "Cardholder's given name: "
-msgstr "Имя владельца карты: "
+msgstr "Имя владельца карты:"
 
 #, c-format
 msgid "Error: Combined name too long (limit is %d characters).\n"
-msgstr "Ð\9eÑ\88ибка: Ð¡Ð»Ð¸Ñ\88ком Ð´Ð»Ð¸Ð½Ð½Ð¾Ðµ Ð¿Ð¾Ð»Ð½Ð¾Ðµ Ð¸Ð¼Ñ\8f (пÑ\80едел - %d символов).\n"
+msgstr "Ð\9eÑ\88ибка: Ð¡ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ\80ованное Ð¸Ð¼Ñ\8f Ñ\81лиÑ\88ком Ð´Ð»Ð¸Ð½Ð½Ð¾Ðµ (пÑ\80едел %d символов).\n"
 
 msgid "URL to retrieve public key: "
 msgstr "URL для получения открытого ключа: "
 
 #, c-format
 msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Ошибка: слишком длинный URL (предел - %d символов).\n"
+msgstr "Ошибка: URL слишком длинный (предел - %d символов).\n"
 
 #, c-format
 msgid "error allocating enough memory: %s\n"
-msgstr "ошибка выделения достаточной памяти: %s\n"
+msgstr "ошибка распределения памяти: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "ошибка чтения `%s': %s\n"
 
-#, c-format
-msgid "error writing `%s': %s\n"
-msgstr "ошибка записи `%s': %s\n"
+#, fuzzy, c-format
+msgid "error writing '%s': %s\n"
+msgstr "ошибка записи в `%s': %s\n"
 
 msgid "Login data (account name): "
-msgstr "Учетная запись (имя): "
+msgstr "Учетная запись (имя):"
 
 #, c-format
 msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-"Ошибка: Слишком длинные данные учетной записи (предел - %d символов).\n"
+msgstr "Ошибка: Данные учетной записи слишком длинные (предел %d символов).\n"
 
 msgid "Private DO data: "
-msgstr "Секретные данные DO:"
+msgstr "Секретные DO данные:"
 
 #, c-format
 msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Ð\9eÑ\88ибка: Ð¡Ð»Ð¸Ñ\88ком Ð¼Ð½Ð¾Ð³Ð¾ Ñ\81екÑ\80еÑ\82нÑ\8bÑ\85 Ð´Ð°Ð½Ð½Ñ\8bÑ\85 DO (пÑ\80едел - %d символов).\n"
+msgstr "Ð\9eÑ\88ибка: Ð¡ÐµÐºÑ\80еÑ\82нÑ\8bе DO Ð´Ð°Ð½Ð½Ñ\8bе Ñ\81лиÑ\88ком Ð´Ð»Ð¸Ð½Ð½Ñ\8bе (пÑ\80едел %d символов).\n"
 
 msgid "Language preferences: "
-msgstr "Предпочтительный язык: "
+msgstr "Предпочитаемый язык: "
 
 msgid "Error: invalid length of preference string.\n"
 msgstr "Ошибка: недопустимая длина строки предпочтений.\n"
@@ -1121,16 +1031,16 @@ msgid "Error: invalid characters in preference string.\n"
 msgstr "Ошибка: недопустимые символы в строке предпочтений.\n"
 
 msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Пол ((M) мужской, (F) женский или пробел): "
+msgstr "Пол ((M)Мужской, (F)Женский или пробел): "
 
 msgid "Error: invalid response.\n"
 msgstr "Ошибка: недопустимый ответ.\n"
 
 msgid "CA fingerprint: "
-msgstr "отпечаток центра сертификации: "
+msgstr "отпечаток CA: "
 
 msgid "Error: invalid formatted fingerprint.\n"
-msgstr "Ð\9eÑ\88ибка: Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имый формат отпечатка.\n"
+msgstr "Ð\9eÑ\88ибка: Ð½ÐµÐ¿Ñ\80авилÑ\8cный формат отпечатка.\n"
 
 #, c-format
 msgid "key operation not possible: %s\n"
@@ -1151,21 +1061,18 @@ msgid ""
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
-"ЗАМЕЧАНИЕ: Нет никакой гарантии, что карта поддерживает запрошенный размер.\n"
-"           Если создать ключ не удастся, сверьтесь с документацией\n"
-"           на карту и выясните, какие размеры допустимы.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "Какой Вам нужен размер ключа для подписей? (%u) "
+msgstr "Какой размер ключа необходим? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "Какой Вам нужен размер ключа для шифрования? (%u) "
+msgstr "Какой размер ключа необходим? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "Какой Вам нужен размер ключа для аутентификации? (%u) "
+msgstr "Какой размер ключа необходим? (%u) "
 
 #, c-format
 msgid "rounded up to %u bits\n"
@@ -1177,17 +1084,18 @@ msgstr "размер ключей %s должен быть в пределах %
 
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
-msgstr "Теперь карта будет перенастроена на генерацию ключа длиной %u бит\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
-msgstr "ошибка изменения размера ключа %d до %u бит: %s\n"
+msgstr "ошибка связывния сокета с `%s': %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
-msgstr "Сделать архивную копию ключа шифрования вне карты? (Y/n) "
+msgstr "Сделать резервную копию ключа шифрования вне карты? (Y/n)"
 
+#, fuzzy
 msgid "NOTE: keys are already stored on the card!\n"
-msgstr "ЗАМЕЧАНИЕ: ключи уже хранятся на карте!\n"
+msgstr "секретный ключ уже сохранен в карте\n"
 
 msgid "Replace existing keys? (y/N) "
 msgstr "Заменить существующие ключи? (y/N) "
@@ -1198,9 +1106,9 @@ msgid ""
 "   PIN = `%s'     Admin PIN = `%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
-"Ð\9eбÑ\80аÑ\82иÑ\82е Ð²Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ: Ð·Ð°Ð²Ð¾Ð´Ñ\81кие Ñ\83Ñ\81Ñ\82ановки PIN\n"
-"   PIN = `%s'    Админ. PIN = `%s'\n"
-"Ð\92ам Ñ\81ледÑ\83еÑ\82 Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ\82Ñ\8c Ð¸Ñ\85 ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ --change-pin\n"
+"УÑ\87Ñ\82иÑ\82е, Ñ\87Ñ\82о Ð·Ð°Ð²Ð¾Ð´Ñ\81кие Ñ\83Ñ\81Ñ\82ановки PIN ÐºÐ¾Ð´Ð¾Ð²\n"
+"   PIN = `%s'     Admin PIN = `%s'\n"
+"СледÑ\83еÑ\82 Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ\82Ñ\8c Ð¸Ñ\85 Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\83 --change-pin\n"
 
 msgid "Please select the type of key to generate:\n"
 msgstr "Выберите тип создаваемого ключа:\n"
@@ -1218,26 +1126,26 @@ msgid "Invalid selection.\n"
 msgstr "Неправильный выбор.\n"
 
 msgid "Please select where to store the key:\n"
-msgstr "Выберите, где хранить ключ:\n"
+msgstr "Ð\92Ñ\8bбеÑ\80иÑ\82е, Ð³Ð´Ðµ Ñ\81оÑ\85Ñ\80аниÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87:\n"
 
 msgid "unknown key protection algorithm\n"
 msgstr "неизвестный алгоритм защиты ключа\n"
 
 msgid "secret parts of key are not available\n"
-msgstr "закрытые части ключа недоступны\n"
+msgstr "секретные части ключа недоступны\n"
 
 msgid "secret key already stored on a card\n"
-msgstr "закрытый ключ уже хранится на карте\n"
+msgstr "секретный ключ уже сохранен в карте\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key to card: %s\n"
-msgstr "ошибка записи ключа на карту: %s\n"
+msgstr "сбой записи ключа: %s\n"
 
 msgid "quit this menu"
 msgstr "выйти из этого меню"
 
 msgid "show admin commands"
-msgstr "показать административные команды"
+msgstr "показать управляющие команды"
 
 msgid "show this help"
 msgstr "показать данную справку"
@@ -1252,25 +1160,25 @@ msgid "change URL to retrieve key"
 msgstr "изменить URL получения ключа"
 
 msgid "fetch the key specified in the card URL"
-msgstr "запросить ключ по заданному картой URL"
+msgstr "запросить ключ, указанный по заданному картой URL"
 
 msgid "change the login name"
-msgstr "изменить имя учетной записи"
+msgstr "изменить учетное имя"
 
 msgid "change the language preferences"
 msgstr "изменить языковые предпочтения"
 
 msgid "change card holder's sex"
-msgstr "измениÑ\82Ñ\8c Ð¿Ð¾Ð» владельца карты"
+msgstr "изменение Ð¿Ð¾Ð»Ð° владельца карты"
 
 msgid "change a CA fingerprint"
-msgstr "сменить отпечаток центра сертификации"
+msgstr "сменить отпечаток CA"
 
 msgid "toggle the signature force PIN flag"
-msgstr "переключить флаг `подпись требует PIN'"
+msgstr ""
 
 msgid "generate new keys"
-msgstr "Ñ\81оздать новые ключи"
+msgstr "Ñ\81генеÑ\80иÑ\80овать новые ключи"
 
 msgid "menu to change or unblock the PIN"
 msgstr "меню изменения или разблокировки PIN"
@@ -1279,10 +1187,10 @@ msgid "verify the PIN and list all data"
 msgstr "проверить PIN и показать все данные"
 
 msgid "unblock the PIN using a Reset Code"
-msgstr "разблокировать PIN с помощью кода сброса"
+msgstr "разблокировать PIN используя Reset Code"
 
-msgid "gpg/card> "
-msgstr "gpg/card> "
+msgid "Command> "
+msgstr "Команда> "
 
 msgid "Admin-only command\n"
 msgstr "Команды администратора\n"
@@ -1294,13 +1202,13 @@ msgid "Admin commands are not allowed\n"
 msgstr "Команды администрирования не разрешены\n"
 
 msgid "Invalid command  (try \"help\")\n"
-msgstr "Недопустимая команда (список команд: \"help\")\n"
+msgstr "Недопустимая команда  (список команд: \"help\")\n"
 
 msgid "--output doesn't work for this command\n"
-msgstr "--output Ð´Ð»Ñ\8f Ð´Ð°Ð½Ð½Ð¾Ð¹ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b Ð½Ðµ Ñ\80абоÑ\82аеÑ\82\n"
+msgstr "--output Ð½Ðµ Ñ\80абоÑ\82аеÑ\82 Ð´Ð»Ñ\8f Ð´Ð°Ð½Ð½Ð¾Ð¹ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "не могу открыть `%s'\n"
 
 #, c-format
@@ -1312,69 +1220,68 @@ msgid "error reading keyblock: %s\n"
 msgstr "ошибка чтения блока ключей: %s\n"
 
 msgid "(unless you specify the key by fingerprint)\n"
-msgstr "(еÑ\81ли Ñ\82олÑ\8cко Ð\92Ñ\8b Ð½Ðµ Ð·Ð°Ð´Ð°Ð»Ð¸ ÐºÐ»Ñ\8eÑ\87 отпечатком)\n"
+msgstr "(еÑ\81ли Ñ\82олÑ\8cко ÐºÐ»Ñ\8eÑ\87 Ð½Ðµ Ð·Ð°Ð´Ð°Ð½ отпечатком)\n"
 
 msgid "can't do this in batch mode without \"--yes\"\n"
 msgstr "не могу выполнить в пакетном режиме без \"--yes\"\n"
 
 msgid "Delete this key from the keyring? (y/N) "
-msgstr "Удалить данный ключ из таблицы? (y/N) "
+msgstr "Удалить данный ключ из таблицы ключей? (y/N)"
 
 msgid "This is a secret key! - really delete? (y/N) "
-msgstr "Это закрытый ключ! - все равно удалить? (y/N) "
+msgstr "Это секретный ключ! - действительно удалить? (y/N)"
 
 #, c-format
 msgid "deleting keyblock failed: %s\n"
 msgstr "сбой при удалении блока ключа: %s\n"
 
 msgid "ownertrust information cleared\n"
-msgstr "сведения о доверии владельцу сброшены\n"
+msgstr "информация о доверии владельцу очищена\n"
 
 #, c-format
 msgid "there is a secret key for public key \"%s\"!\n"
-msgstr "имеется закрытый ключ для открытого ключа \"%s\"!\n"
+msgstr "имеется секретный ключ для открытого ключа \"%s\"!\n"
 
 msgid "use option \"--delete-secret-keys\" to delete it first.\n"
-msgstr "сначала удалите его командой \"--delete-secret-keys\".\n"
+msgstr ""
+"сначала воспользуйтесь \"--delete-secret-keys\" для удаления закрытого "
+"ключа.\n"
 
 #, c-format
 msgid "error creating passphrase: %s\n"
-msgstr "ошибка при создании пароля: %s\n"
+msgstr "ошибка создания фразы-пароля: %s\n"
 
 msgid "can't use a symmetric ESK packet due to the S2K mode\n"
-msgstr "не могу использовать симметричный пакет ESK в режиме S2K\n"
+msgstr "не могу использовать симметричный пакет ESK в S2K режиме\n"
 
 #, c-format
 msgid "using cipher %s\n"
-msgstr "используется алгоритм шифрования %s\n"
+msgstr "использутся алгоритм шифрования %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' уже сжат\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
-msgstr "ВНИМАНИЕ: файл `%s' пуст\n"
+msgid "WARNING: '%s' is an empty file\n"
+msgstr "ВНИМАНИЕ: `%s' пустой файл\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
-msgstr ""
-"в режиме --pgp2 ключ RSA для шифрования должен быть не более 2048 бит\n"
+msgstr "в режиме --pgp2 ключ RSA для ширования должен быть не более 2048 бит\n"
 
 #, c-format
-msgid "reading from `%s'\n"
-msgstr "чтение из `%s'\n"
+msgid "reading from '%s'\n"
+msgstr "читаю из `%s'\n"
 
 msgid ""
 "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
-msgstr ""
-"не могу использовать шифр IDEA для всех ключей, которыми Вы шифруете.\n"
+msgstr "не могу использовать шифр IDEA для всех ключей.\n"
 
 #, c-format
 msgid ""
 "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
 msgstr ""
-"ВНИМАНИЕ: использование симметричного шифра %s (%d) нарушает\n"
-"          предпочтения получателя\n"
+"ВНИМАНИЕ: использование шифра %s (%d) противоречит предпочтениям получателя\n"
 
 #, c-format
 msgid ""
@@ -1384,12 +1291,11 @@ msgstr "ВНИМАНИЕ: сжатие алгоритмом %s (%d) наруша
 
 #, c-format
 msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n"
-msgstr ""
-"использование симметричного шифра %s (%d) нарушает предпочтения получателя\n"
+msgstr "использование шифра %s (%d) противоречит предпочтениям получателя\n"
 
 #, c-format
 msgid "you may not use %s while in %s mode\n"
-msgstr "нельзя использовать %s в режиме %s\n"
+msgstr "Ð\9dельзя использовать %s в режиме %s\n"
 
 #, c-format
 msgid "%s/%s encrypted for: \"%s\"\n"
@@ -1397,7 +1303,7 @@ msgstr "%s/%s зашифровано для: \"%s\"\n"
 
 #, c-format
 msgid "%s encrypted data\n"
-msgstr "данные зашифрованы алгоритмом %s\n"
+msgstr "Ð\94анные зашифрованы алгоритмом %s\n"
 
 #, c-format
 msgid "encrypted with unknown algorithm %d\n"
@@ -1416,21 +1322,20 @@ msgstr "удаленный запуск программы не поддержи
 
 msgid ""
 "external program calls are disabled due to unsafe options file permissions\n"
-msgstr ""
-"вызов внешних программ отключен из-за небезопасных прав доступа к файлу "
-"настроек\n"
+msgstr "вызов внешних программ отключен из-за небезопасных прав доступа\n"
 
 msgid "this platform requires temporary files when calling external programs\n"
 msgstr ""
-"на данной платформе при вызове внешних программ требуются временные файлы\n"
+"на данной платформе требуется использование временных файлов при вызове "
+"внешних программ\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
-msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð²Ñ\8bполнить программу `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
+msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð·Ð°Ð¿Ñ\83Ñ\81Ñ\82ить программу `%s': %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
-msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð²Ñ\8bполнить оболочку `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
+msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð·Ð°Ð¿Ñ\83Ñ\81Ñ\82ить оболочку `%s': %s\n"
 
 #, c-format
 msgid "system error while calling external program: %s\n"
@@ -1440,43 +1345,43 @@ msgid "unnatural exit of external program\n"
 msgstr "ненормальное завершение внешней программы\n"
 
 msgid "unable to execute external program\n"
-msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð²Ñ\8bполнить внешнюю программу\n"
+msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð·Ð°Ð¿Ñ\83Ñ\81Ñ\82ить внешнюю программу\n"
 
 #, c-format
 msgid "unable to read external program response: %s\n"
 msgstr "не могу прочитать ответ внешней программы: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "ВНИМАНИЕ: не могу удалить временный файл (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "ВНИМАНИЕ: не могу удалить временный каталог `%s': %s\n"
 
 msgid "export signatures that are marked as local-only"
-msgstr "экспортировать подписи, помеченные как `только локальные'"
+msgstr "экспорт подписей, помеченных как локальные"
 
 msgid "export attribute user IDs (generally photo IDs)"
-msgstr "экспортировать атрибутные ID (обычно фотоидентификаторы)"
+msgstr "экспорт атрибутов UserID (обычно PhotoID)"
 
 msgid "export revocation keys marked as \"sensitive\""
-msgstr "экспортировать ключи отзыва, помеченные как `особо важные'"
+msgstr "экспорт отзывающих ключей помеченных \"sensitive\""
 
 msgid "remove the passphrase from exported subkeys"
-msgstr "Ñ\83далиÑ\82Ñ\8c Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c Ð¸Ð· Ð²Ñ\8bбÑ\80анных подключей"
+msgstr "Ñ\83даление Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f Ð¸Ð· Ñ\8dкÑ\81поÑ\80Ñ\82иÑ\80Ñ\83емых подключей"
 
 msgid "remove unusable parts from key during export"
-msgstr "Ñ\83далиÑ\82Ñ\8c Ð¿Ñ\80и Ñ\8dкÑ\81поÑ\80Ñ\82е Ð½ÐµÐ¿Ñ\80игоднÑ\8bе Ñ\87аÑ\81Ñ\82и ÐºÐ»Ñ\8eÑ\87а"
+msgstr "Ñ\83даление Ð½ÐµÐ¸Ñ\81полÑ\8cзÑ\83емÑ\8bÑ\85 Ñ\87аÑ\81Ñ\82ей Ð¸Ð· ÐºÐ»Ñ\8eÑ\87а Ð¿Ñ\80и Ñ\8dкÑ\81поÑ\80Ñ\82е"
 
 msgid "remove as much as possible from key during export"
-msgstr "Ñ\83далиÑ\82Ñ\8c ÐºÐ°Ðº Ð¼Ð¾Ð¶Ð½Ð¾ Ð±Ð¾Ð»Ñ\8cÑ\88е Ð¸Ð· ÐºÐ»Ñ\8eÑ\87а Ð¿Ñ\80и Ñ\8dкÑ\81поÑ\80Ñ\82е"
+msgstr "Ñ\83далиÑ\82Ñ\8c Ð¼Ð°ÐºÑ\81имÑ\83м Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ð³Ð¾ Ð¸Ð· ÐºÐ»Ñ\8eÑ\87а Ð¿Ñ\80и Ñ\8dкÑ\81поÑ\80Ñ\82иÑ\80овании"
 
 msgid "export keys in an S-expression based format"
-msgstr "экспортировать ключи в формате на основе S-выражений"
+msgstr ""
 
 msgid "exporting secret keys not allowed\n"
-msgstr "экспорт закрытых ключей не разрешен\n"
+msgstr "экспорт секретных ключей не разрешен\n"
 
 #, c-format
 msgid "key %s: not protected - skipped\n"
@@ -1484,14 +1389,14 @@ msgstr "ключ %s: не защищен - пропущен\n"
 
 #, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
-msgstr "ключ %s: ключ типа PGP 2.x - пропущен\n"
+msgstr "ключ %s: стиля PGP 2.x - пропущен\n"
 
 #, c-format
 msgid "key %s: key material on-card - skipped\n"
-msgstr "клÑ\8eÑ\87 %s: Ð¼Ð°Ñ\82еÑ\80иал ÐºÐ»Ñ\8eÑ\87а на карте - пропущен\n"
+msgstr "клÑ\8eÑ\87 %s: ÐºÐ»Ñ\8eÑ\87 Ð½Ð°Ñ\85одиÑ\82Ñ\81Ñ\8f на карте - пропущен\n"
 
 msgid "about to export an unprotected subkey\n"
-msgstr "перехожу к экспорту незащищенного подключа\n"
+msgstr "экспорт незащищенного подключа\n"
 
 #, c-format
 msgid "failed to unprotect the subkey: %s\n"
@@ -1499,27 +1404,23 @@ msgstr "сбой снятия защиты с подключа: %s\n"
 
 #, c-format
 msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ñ\83 Ð·Ð°ÐºÑ\80Ñ\8bÑ\82ого ÐºÐ»Ñ\8eÑ\87а %s Ð½ет простой контрольной суммы SK\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ñ\81екÑ\80еÑ\82нÑ\8bй ÐºÐ»Ñ\8eÑ\87 %s Ð½Ðµ Ð¸Ð¼Ðµет простой контрольной суммы SK\n"
 
 msgid "WARNING: nothing exported\n"
 msgstr "ВНИМАНИЕ: нечего экспортировать\n"
 
 msgid "too many entries in pk cache - disabled\n"
-msgstr "слишком много элементов в буфере pk - отключено\n"
+msgstr "слишком много входов в pk кэше - отключено\n"
 
 msgid "[User ID not found]"
-msgstr "[ID пользователя не найден]"
+msgstr "[User ID не найден]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "клÑ\8eÑ\87 %s: Ð·Ð°ÐºÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 Ð±ÐµÐ· Ð¾Ñ\82кÑ\80Ñ\8bÑ\82ого ÐºÐ»Ñ\8eÑ\87а - Ð¿Ñ\80опÑ\83Ñ\89ен\n"
+msgid "automatically retrieved '%s' via %s\n"
+msgstr "авÑ\82омаÑ\82иÑ\87еÑ\81ки Ð¿Ð¾Ð»Ñ\83Ñ\87еннÑ\8bй `%s' via %s\n"
 
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
-msgstr "автоматически получили `%s' через %s\n"
-
-#, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "ошибка получения `%s' через %s: %s\n"
 
 msgid "No fingerprint"
@@ -1528,21 +1429,26 @@ msgstr "Нет отпечатка"
 #, c-format
 msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n"
 msgstr ""
-"Параметр --allow-non-selfsigned-uid сделал дефектный ключ %s пригодным\n"
+"Дефектный ключ %s признан пригодным согласно параметра --allow-non-"
+"selfsigned-uid\n"
 
 #, c-format
 msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "нет закрытого подключа для открытого подключа %s - игнорирую\n"
+msgstr "нет секретного подключа для открытого подключа %s - игнорируем\n"
 
 #, c-format
 msgid "using subkey %s instead of primary key %s\n"
-msgstr "использую подключ %s вместо главного ключа %s\n"
+msgstr "использую подклключ %s вместо главного ключа %s\n"
+
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "ключ %s: секретный ключ без открытого ключа - пропущен\n"
 
 msgid "make a signature"
 msgstr "создать подпись"
 
 msgid "make a clear text signature"
-msgstr "создать текстовую подпись"
+msgstr "создать прозрачную подпись"
 
 msgid "make a detached signature"
 msgstr "создать отделенную подпись"
@@ -1563,23 +1469,20 @@ msgid "list keys"
 msgstr "вывести список ключей"
 
 msgid "list keys and signatures"
-msgstr "вÑ\8bвеÑ\81Ñ\82и Ñ\81пиÑ\81ок ÐºÐ»Ñ\8eÑ\87ей Ð¸ Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
+msgstr "вÑ\8bвеÑ\81Ñ\82и Ñ\81пиÑ\81ок ÐºÐ»Ñ\8eÑ\87ей Ð¸ Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и"
 
 msgid "list and check key signatures"
-msgstr "вывести и проверить подписи ключей"
+msgstr "вывести и проверить подписи"
 
 msgid "list keys and fingerprints"
-msgstr "вывести список ключей и их отпечатков"
+msgstr "вывести список ключей c отпечатками"
 
 msgid "list secret keys"
-msgstr "вывести список закрытых ключей"
+msgstr "вывести список секретных ключей"
 
 msgid "generate a new key pair"
 msgstr "создать новую пару ключей"
 
-msgid "generate a revocation certificate"
-msgstr "создать сертификат отзыва"
-
 msgid "remove keys from the public keyring"
 msgstr "удалить ключи из таблицы открытых ключей"
 
@@ -1595,8 +1498,8 @@ msgstr "подписать ключ локально"
 msgid "sign or edit a key"
 msgstr "подписать или редактировать ключ"
 
-msgid "change a passphrase"
-msgstr "Ñ\81мениÑ\82Ñ\8c Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c"
+msgid "generate a revocation certificate"
+msgstr "Ñ\81оздаÑ\82Ñ\8c Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð¾Ñ\82зÑ\8bва"
 
 msgid "export keys"
 msgstr "экспортировать ключи"
@@ -1626,7 +1529,7 @@ msgid "change a card's PIN"
 msgstr "сменить PIN карты"
 
 msgid "update the trust database"
-msgstr "обновить таблицу доверия"
+msgstr "обновить таблицу доверий"
 
 msgid "print message digests"
 msgstr "вывести хэши файлов"
@@ -1635,22 +1538,22 @@ msgid "run in server mode"
 msgstr "запуск в режиме сервера"
 
 msgid "create ascii armored output"
-msgstr "вывод в текстовом формате ASCII"
+msgstr "вывод в ASCII формате"
 
 msgid "|USER-ID|encrypt for USER-ID"
-msgstr "|USER-ID|зашифровать для пользователя USER-ID"
+msgstr "|USER-ID|зашифровать для USER-ID"
 
 msgid "|USER-ID|use USER-ID to sign or decrypt"
-msgstr "|USER-ID|использовать ключ USER-ID для подписи и расшифровки"
+msgstr "|USER-ID|использовать USER-ID для подписывания и расшифрования"
 
 msgid "|N|set compress level to N (0 disables)"
-msgstr "|N|установить уровень сжатия N (0 без сжатия)"
+msgstr "|N|установить уровень сжатия N (0 без сжатия)"
 
 msgid "use canonical text mode"
 msgstr "использовать канонический текстовый режим"
 
 msgid "|FILE|write output to FILE"
-msgstr "|FILE|выводить данные в файл FILE"
+msgstr "|FILE|взять параметры из FILE"
 
 msgid "do not make any changes"
 msgstr "не делать никаких изменений"
@@ -1666,7 +1569,7 @@ msgid ""
 "(See the man page for a complete listing of all commands and options)\n"
 msgstr ""
 "@\n"
-"(Ð\9fолнÑ\8bй Ñ\81пиÑ\81ок ÐºÐ¾Ð¼Ð°Ð½Ð´ Ð¸ Ð¿Ð°Ñ\80амеÑ\82Ñ\80ов Ñ\81м. Ð² Ð´Ð¾ÐºÑ\83менÑ\82аÑ\86ии)\n"
+"(См. Ð´Ð¾ÐºÑ\83менÑ\82аÑ\86иÑ\8e Ð´Ð»Ñ\8f Ð±Ð¾Ð»ÐµÐµ Ð¿Ð¾Ð»Ð½Ð¾Ð³Ð¾ Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼Ð»ÐµÐ½Ð¸Ñ\8f Ñ\81 ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ð¼Ð¸ Ð¸ Ð¿Ð°Ñ\80амеÑ\82Ñ\80ами)\n"
 
 msgid ""
 "@\n"
@@ -1682,22 +1585,22 @@ msgstr ""
 "Примеры:\n"
 "\n"
 " -se -r Bob [файл]          подписать и зашифровать для получателя Bob\n"
-" --clearsign [файл]         создать текстовую подпись\n"
+" --clearsign [файл]         создать прозрачную подпись\n"
 " --detach-sign [файл]       создать отделенную подпись\n"
 " --list-keys [имена]        показать ключи\n"
 " --fingerprint [имена]      показать отпечатки\n"
 
 msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: gpg [параметры] [файлы] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: gpg [параметры] [файлы] (-h для подсказки)"
 
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Синтаксис: gpg [параметры] [файлы]\n"
-"Подписи и их проверка, шифрование и дешифровка\n"
-"Действие по умолчанию зависит от входных данных\n"
+"Подписи и их проверка, зашифрование и расшифрование.\n"
+"Действие по умолчанию зависит от входных данных.\n"
 
 msgid ""
 "\n"
@@ -1707,152 +1610,151 @@ msgstr ""
 "Поддерживаются следующие алгоритмы:\n"
 
 msgid "Pubkey: "
-msgstr "С открытым ключом: "
+msgstr "  с открытым ключом: "
 
 msgid "Cipher: "
-msgstr "Симметричные шифры: "
+msgstr "  симметричные шифры: "
 
 msgid "Hash: "
-msgstr "Хэш-функции: "
+msgstr "  хэш-функции: "
 
 msgid "Compression: "
-msgstr "Алгоритмы сжатия: "
+msgstr "  алгоритмы сжатия: "
 
 msgid "usage: gpg [options] "
-msgstr "вÑ\8bзов: gpg [параметры] "
+msgstr "иÑ\81полÑ\8cзование: gpg [параметры] "
 
 msgid "conflicting commands\n"
 msgstr "несовместимые команды\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "отсутствует знак = в определении группы `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "ВНИМАНИЕ: небезопасный владелец домашнего каталога `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\8bй Ð²Ð»Ð°Ð´ÐµÐ»ÐµÑ\86 Ñ\84айла Ð½Ð°Ñ\81Ñ\82Ñ\80оек `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\8bй Ð²Ð»Ð°Ð´ÐµÐ»ÐµÑ\86 Ñ\84айла ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80аÑ\86ии `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "ВНИМАНИЕ: небезопасный владелец файла модуля расширения `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
-msgstr "ВНИМАНИЕ: небезопасные права доступа к домашнему каталогу `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
+msgstr "ВНИМАНИЕ: небезопасные права доступа у домашнего каталога `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
-msgstr "ВНИМАНИЕ: небезопасные права доступа к файлу настроек `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
+msgstr "ВНИМАНИЕ: небезопасные права доступа у файла конфигурации `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
-msgstr "ВНИМАНИЕ: небезопасные права доступа к файлу модуля расширения `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
+msgstr "ВНИМАНИЕ: небезопасные права доступа у файла модуля расширения `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
-"ВНИМАНИЕ: небезопасный владелец каталога, содержащего домашний каталог `%s'\n"
+"ВНИМАНИЕ: небезопасный владелец каталога содержащего домашний каталог `%s'\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
 msgstr ""
-"ВНИМАНИЕ: небезопасный владелец каталога, содержащего файл настроек `%s'\n"
+"ВНИМАНИЕ: небезопасный владелец каталога содержащего файл конфигурации `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "ВНИМАНИЕ: небезопасный владелец каталога содержащего модуль расширения `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
-"ВНИМАНИЕ: небезопасные права доступа к каталогу,\n"
-"          содержащему домашний каталог `%s'\n"
+"ВНИМАНИЕ: небезопасные права доступа у каталога содержащего домашний каталог "
+"`%s'\n"
 
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
 msgstr ""
-"ВНИМАНИЕ: небезопасные права доступа к каталогу,\n"
-"          содержащему файл настроек `%s'\n"
+"ВНИМАНИЕ: небезопасные права доступа у каталога содержащего файл "
+"конфигурации `%s'\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
-"ВНИМАНИЕ: небезопасные права доступа к каталогу содержащему файл модуля "
+"ВНИМАНИЕ: небезопасные права доступа у каталогу содержащего файл модуля "
 "расширения `%s'\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
-msgstr "неизвеÑ\81Ñ\82нÑ\8bй Ð¿Ð°Ñ\80амеÑ\82Ñ\80 Ð² Ñ\84айле Ð½Ð°Ñ\81Ñ\82Ñ\80оек `%s'\n"
+msgid "unknown configuration item '%s'\n"
+msgstr "неизвеÑ\81Ñ\82нÑ\8bй Ð¿Ð°Ñ\80амеÑ\82Ñ\80 Ð² Ñ\84айле ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80аÑ\86ии `%s'\n"
 
 msgid "display photo IDs during key listings"
-msgstr "показаÑ\82Ñ\8c Ð² Ñ\81пиÑ\81ке ÐºÐ»Ñ\8eÑ\87ей Ñ\84оÑ\82оиденÑ\82иÑ\84икаÑ\82оÑ\80Ñ\8b"
+msgstr "оÑ\82обÑ\80ажаÑ\82Ñ\8c Ð¤Ð¾Ñ\82о ID Ð¿Ñ\80и Ñ\80аÑ\81пеÑ\87аÑ\82ке ÐºÐ»Ñ\8eÑ\87ей"
 
 msgid "show policy URLs during signature listings"
-msgstr "показать в списке подписей URL правил"
+msgstr "показывать ссылку на политики при распечатке подписей"
 
 msgid "show all notations during signature listings"
-msgstr "показать в списке подписей все примечания"
+msgstr "показывать все примечания при распечатке подписей"
 
 msgid "show IETF standard notations during signature listings"
-msgstr "показать в списке подписей примечания стандарта IETF"
+msgstr "показывать стандартные IETF примечания при распечатке подписей"
 
 msgid "show user-supplied notations during signature listings"
-msgstr "показать в списке подписей пользовательские примечания"
+msgstr ""
+"показывать добавленные пользователем примечания при распечатке подписей"
 
 msgid "show preferred keyserver URLs during signature listings"
-msgstr "показать в списке подписей URL предпочтительных серверов ключей"
+msgstr "показывать предпочитаемый сервер ключей при распечатке подписей"
 
 msgid "show user ID validity during key listings"
-msgstr "показать в списке ключей действительность ID пользователя"
+msgstr "показывать действительность Used ID при распечатке ключей"
 
 msgid "show revoked and expired user IDs in key listings"
-msgstr "показать в списке ключей отозванные и просроченные ID пользователей"
+msgstr "показывать отозванные и просроченные User ID при распечатке ключей"
 
 msgid "show revoked and expired subkeys in key listings"
-msgstr "показать в списке ключей отозванные и просроченные подключи"
+msgstr "показывать отозванные и просроченные ключи при распечатке ключей"
 
 msgid "show the keyring name in key listings"
-msgstr "показаÑ\82Ñ\8c Ð² Ñ\81пиÑ\81ке ÐºÐ»Ñ\8eÑ\87ей Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ Ñ\82аблиÑ\86Ñ\8b ключей"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ð¸Ð¼Ñ\8f Ñ\82аблиÑ\86 ÐºÐ»Ñ\8eÑ\87ей Ð¿Ñ\80и Ñ\80аÑ\81пеÑ\87аÑ\82ке ключей"
 
 msgid "show expiration dates during signature listings"
-msgstr "показаÑ\82Ñ\8c Ð² Ñ\81пиÑ\81ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей Ñ\81Ñ\80оки Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ð´Ð°Ñ\82Ñ\8b Ð¸Ñ\81Ñ\82еÑ\87ениÑ\8f Ð¿Ñ\80и Ñ\80аÑ\81пеÑ\87аÑ\82ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
-msgstr "ЗАМЕЧАНИЕ: старый основной файл параметров `%s' проигнорирован\n"
+msgid "NOTE: old default options file '%s' ignored\n"
+msgstr "ЗАМЕЧАНИЕ: старый файл конфигурации по умолчанию `%s' проигнорирован\n"
 
 #, c-format
 msgid "libgcrypt is too old (need %s, have %s)\n"
-msgstr "слишком старая версия libcrypt (нужно %s, есть %s)\n"
+msgstr "libcrypt слишком старой версии (требуется %s, обнаружено %s)\n"
 
 #, c-format
 msgid "NOTE: %s is not for normal use!\n"
-msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: %s Ð½Ðµ Ð¿Ñ\80едназнаÑ\87ен Ð´Ð»Ñ\8f Ð½Ð¾Ñ\80малÑ\8cного применения!\n"
+msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: %s Ð½Ðµ Ð¿Ñ\80едназнаÑ\87ен Ð´Ð»Ñ\8f Ð¾Ð±Ñ\8bÑ\87ного применения!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
-msgstr "`%s' - не допустимый срок действия подписи\n"
+msgid "'%s' is not a valid signature expiration\n"
+msgstr "`%s' недопустимый срок действия подписи\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
-msgstr "`%s' - не допустимая таблица символов\n"
+msgid "'%s' is not a valid character set\n"
+msgstr "`%s' недопустимая таблица символов\n"
 
 msgid "could not parse keyserver URL\n"
-msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð¸Ð½Ñ\82еÑ\80пÑ\80еÑ\82ировать URL сервера ключей\n"
+msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð¿Ñ\80оанализировать URL сервера ключей\n"
 
-# test it
 #, c-format
 msgid "%s:%d: invalid keyserver options\n"
 msgstr "%s:%d: недопустимые параметры для сервера ключей\n"
 
-# test it
 msgid "invalid keyserver options\n"
 msgstr "недопустимые параметры для сервера ключей\n"
 
@@ -1872,51 +1774,48 @@ msgstr "недопустимые параметры экспорта\n"
 
 #, c-format
 msgid "%s:%d: invalid list options\n"
-msgstr "%s:%d: Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имÑ\8bе Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ñ\81пиÑ\81ка\n"
+msgstr "%s:%d: Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имÑ\8bй Ñ\81пиÑ\81ок Ð¿Ð°Ñ\80амеÑ\82Ñ\80ов\n"
 
 msgid "invalid list options\n"
-msgstr "недопÑ\83Ñ\81Ñ\82имÑ\8bе Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ñ\81пиÑ\81ка\n"
+msgstr "недопÑ\83Ñ\81Ñ\82имÑ\8bй Ñ\81пиÑ\81ок Ð¿Ð°Ñ\80амеÑ\82Ñ\80ов\n"
 
 msgid "display photo IDs during signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ñ\84оÑ\82оиденÑ\82иÑ\84икаÑ\82оÑ\80Ñ\8b"
+msgstr "оÑ\82обÑ\80ажаÑ\82Ñ\8c Ð¤Ð¾Ñ\82о ID Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и"
 
 msgid "show policy URLs during signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и URL Ð¿Ñ\80авил"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ñ\81Ñ\81Ñ\8bлкÑ\83 Ð½Ð° Ð¿Ð¾Ð»Ð¸Ñ\82ики Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и"
 
 msgid "show all notations during signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей Ð²Ñ\81е Ð¿Ñ\80имеÑ\87аниÑ\8f"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ð²Ñ\81е Ð¿Ñ\80имеÑ\87аниÑ\8f Ð² Ð¿Ñ\80оÑ\86еÑ\81Ñ\81е Ð¿Ñ\80овеÑ\80ки Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
 
 msgid "show IETF standard notations during signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей Ð¿Ñ\80имеÑ\87аниÑ\8f Ñ\81Ñ\82андаÑ\80Ñ\82а IETF"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ñ\81Ñ\82андаÑ\80Ñ\82нÑ\8bе IETF Ð¿Ñ\80имеÑ\87аниÑ\8f Ð² Ð¿Ñ\80оÑ\86еÑ\81Ñ\81е Ð¿Ñ\80овеÑ\80ки Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
 
 msgid "show user-supplied notations during signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8cÑ\81кие Ð¿Ñ\80имеÑ\87аниÑ\8f"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð½Ñ\8bе Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елем Ð¿Ñ\80имеÑ\87аниÑ\8f Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
 
 msgid "show preferred keyserver URLs during signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей URL Ð¿Ñ\80едпоÑ\87Ñ\82иÑ\82елÑ\8cнÑ\8bÑ\85 Ñ\81еÑ\80веÑ\80ов ÐºÐ»Ñ\8eÑ\87ей"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ð¿Ñ\80едпоÑ\87иÑ\82аемÑ\8bе Ñ\81еÑ\80веÑ\80Ñ\8b ÐºÐ»Ñ\8eÑ\87ей Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
 
 msgid "show user ID validity during signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82Ñ\8c ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82Ñ\8c UserID Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
 
 msgid "show revoked and expired user IDs in signature verification"
-msgstr ""
-"показать при проверке подписей отозванные и просроченные ID пользователя"
+msgstr "печатать отозванные и просроченные User ID при проверке подписей"
 
 msgid "show only the primary user ID in signature verification"
-msgstr "показаÑ\82Ñ\8c Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей Ñ\82олÑ\8cко Ð³Ð»Ð°Ð²Ð½Ñ\8bй ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f"
+msgstr "пеÑ\87аÑ\82аÑ\82Ñ\8c Ñ\82олÑ\8cко Ð³Ð»Ð°Ð²Ð½Ñ\8bй User ID Ð¿Ñ\80и Ð¿Ñ\80овеÑ\80ке Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей"
 
 msgid "validate signatures with PKA data"
-msgstr "проверить подписи по данным PKA"
+msgstr ""
 
 msgid "elevate the trust of signatures with valid PKA data"
-msgstr "поднять доверие подписей с действительными данными PKA"
+msgstr ""
 
-# test it
 #, c-format
 msgid "%s:%d: invalid verify options\n"
-msgstr "%s:%d: недопустимые параметры проверки\n"
+msgstr "%s:%d: недопустимые параметры проверки \n"
 
-# test it
 msgid "invalid verify options\n"
 msgstr "недопустимые параметры проверки\n"
 
@@ -1924,7 +1823,6 @@ msgstr "недопустимые параметры проверки\n"
 msgid "unable to set exec-path to %s\n"
 msgstr "не могу определить путь запуска для %s\n"
 
-# test it
 #, c-format
 msgid "%s:%d: invalid auto-key-locate list\n"
 msgstr "%s:%d: недопустимый список auto-key-locate\n"
@@ -1933,19 +1831,19 @@ msgid "invalid auto-key-locate list\n"
 msgstr "недопустимый список auto-key-locate\n"
 
 msgid "WARNING: program may create a core file!\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ñ\81оздание Ñ\84айла Ð¾Ð±Ñ\80аза Ð¿Ð°Ð¼Ñ\8fÑ\82и!\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ñ\81оздание Ñ\84айла Ð´Ð°Ð¼Ð¿Ð° Ð¿Ð°Ð¼Ñ\8fÑ\82и Ð¿Ñ\80огÑ\80аммÑ\8b!\n"
 
 #, c-format
 msgid "WARNING: %s overrides %s\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: %s Ð¾Ñ\82менÑ\8fет %s\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: %s Ð·Ð°Ð¼ÐµÑ\81Ñ\82ит %s\n"
 
 #, c-format
 msgid "%s not allowed with %s!\n"
-msgstr "%s с %s недопустимо!\n"
+msgstr "%s не допускается использовать с %s!\n"
 
 #, c-format
 msgid "%s makes no sense with %s!\n"
-msgstr "%s с %s не имеет смысла!\n"
+msgstr "%s не имеет смысла совместно с %s!\n"
 
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
@@ -1953,29 +1851,28 @@ msgstr "не будет работать с небезопасной памят
 
 msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
 msgstr ""
-"в Ñ\80ежиме --pgp2 Ð¼Ð¾Ð¶Ð½Ð¾ Ñ\81делаÑ\82Ñ\8c Ñ\82олÑ\8cко Ð¾Ñ\82деленнÑ\83Ñ\8e Ð¸Ð»Ð¸ Ñ\82екÑ\81Ñ\82овÑ\83Ñ\8e Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c\n"
+"можно Ñ\81делаÑ\82Ñ\8c Ñ\82олÑ\8cко Ð¾Ñ\82деленнÑ\83Ñ\8e Ð¸Ð»Ð¸ Ð¿Ñ\80озÑ\80аÑ\87нÑ\83Ñ\8e Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c Ð² Ñ\80ежиме --pgp2\n"
 
 msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr "в Ñ\80ежиме --pgp2 Ð½ÐµÐ»Ñ\8cзÑ\8f Ð¾Ð´Ð½Ð¾Ð²Ñ\80еменно Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аÑ\82Ñ\8c Ð¸ Ð·Ð°Ñ\88иÑ\84Ñ\80оваÑ\82Ñ\8c\n"
+msgstr "Ð\9dелÑ\8cзÑ\8f Ð¾Ð´Ð½Ð¾Ð²Ñ\80еменно Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аÑ\82Ñ\8c Ð¸ Ð·Ð°Ñ\88иÑ\84Ñ\80оваÑ\82Ñ\8c Ð² Ñ\80ежиме --pgp2\n"
 
 msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr ""
-"в режиме --pgp2 нужно использовать файлы (а не конвейер командной строки).\n"
+msgstr "Следует использовать файлы (а не каналы (pipe)) в режиме --pgp2.\n"
 
 msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr "для шифрования сообщения в режиме --pgp2 требуется шифр IDEA\n"
+msgstr "для зашифрования сообщения в режиме --pgp2 требуется шифр IDEA\n"
 
 msgid "selected cipher algorithm is invalid\n"
-msgstr "вÑ\8bбÑ\80ан Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имый алгоритм шифрования\n"
+msgstr "вÑ\8bбÑ\80ан Ð½ÐµÐ²ÐµÑ\80ный алгоритм шифрования\n"
 
 msgid "selected digest algorithm is invalid\n"
-msgstr "вÑ\8bбÑ\80ана Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имая хэш-функция\n"
+msgstr "вÑ\8bбÑ\80ана Ð½ÐµÐ²ÐµÑ\80ная хэш-функция\n"
 
 msgid "selected compression algorithm is invalid\n"
-msgstr "вÑ\8bбÑ\80ан Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имый алгоритм сжатия\n"
+msgstr "вÑ\8bбÑ\80ан Ð½ÐµÐ²ÐµÑ\80ный алгоритм сжатия\n"
 
 msgid "selected certification digest algorithm is invalid\n"
-msgstr "вÑ\8bбÑ\80ана Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имая хэш-функция для сертификации\n"
+msgstr "вÑ\8bбÑ\80ана Ð½ÐµÐ²ÐµÑ\80ная хэш-функция для сертификации\n"
 
 msgid "completes-needed must be greater than 0\n"
 msgstr "completes-needed должен быть больше 0\n"
@@ -1993,7 +1890,7 @@ msgid "invalid min-cert-level; must be 1, 2, or 3\n"
 msgstr "недопустимый min-cert-level; должен быть 0, 1, 2 или 3\n"
 
 msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
-msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð¿Ñ\80оÑ\81Ñ\82ой Ñ\80ежим S2K (0) Ñ\81Ñ\82Ñ\80ого Ð¿Ñ\80оÑ\82ивопоказан\n"
+msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð¿Ñ\80оÑ\81Ñ\82ой Ñ\80ежим S2K (0) Ñ\81Ñ\82Ñ\80ого Ð½Ðµ Ñ\80екомендÑ\83еÑ\82Ñ\81Ñ\8f\n"
 
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
 msgstr "недопустимый режим S2K; должно быть 0, 1 или 3\n"
@@ -2012,23 +1909,23 @@ msgstr "недопустимые персональные предпочтени
 
 #, c-format
 msgid "%s does not yet work with %s\n"
-msgstr "%s пока не работает совместно с %s!\n"
+msgstr "%s пока не работает совместно с %s\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "нельзя использовать шифрование `%s' в режиме %s\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "нельзя использовать хэш-функцию `%s' в режиме %s\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "нельзя использовать сжатие `%s' в режиме %s\n"
 
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
-msgstr "сбой инициализации таблицы доверия: %s\n"
+msgstr "сбой инициализации таблицы доверий: %s\n"
 
 msgid "WARNING: recipients (-r) given without using public key encryption\n"
 msgstr ""
@@ -2042,8 +1939,8 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [файл]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
-msgstr "Ñ\81бой Ñ\81иммеÑ\82Ñ\80иÑ\87ного Ñ\88иÑ\84Ñ\80ованиÑ\8f `%s': %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
+msgstr "Ñ\81иммеÑ\82Ñ\80иÑ\87ное Ñ\88иÑ\84Ñ\80ование `%s' Ð½Ðµ Ñ\83далоÑ\81Ñ\8c: %s\n"
 
 msgid "--encrypt [filename]"
 msgstr "--encrypt [файл]"
@@ -2056,7 +1953,7 @@ msgstr "нельзя использовать --symmetric --encrypt совмес
 
 #, c-format
 msgid "you cannot use --symmetric --encrypt while in %s mode\n"
-msgstr "нелÑ\8cзÑ\8f использовать --symmetric --encrypt в режиме %s\n"
+msgstr "невозможно использовать --symmetric --encrypt в режиме %s\n"
 
 msgid "--sign [filename]"
 msgstr "--sign [файл]"
@@ -2073,7 +1970,7 @@ msgstr ""
 
 #, c-format
 msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
-msgstr "нелÑ\8cзÑ\8f использовать --symmetric --sign --encrypt в режиме %s\n"
+msgstr "невозможно использовать --symmetric --sign --encrypt в режиме %s\n"
 
 msgid "--sign --symmetric [filename]"
 msgstr "--sign --symmetric [файл]"
@@ -2085,16 +1982,13 @@ msgid "--decrypt [filename]"
 msgstr "--decrypt [файл]"
 
 msgid "--sign-key user-id"
-msgstr "--sign-key <ID пользователя>"
+msgstr "--sign-key user-id"
 
 msgid "--lsign-key user-id"
-msgstr "--lsign-key <ID пользователя>"
+msgstr "--lsign-key user-id"
 
 msgid "--edit-key user-id [commands]"
-msgstr "--edit-key <ID пользователя> [команды]"
-
-msgid "--passwd <user-id>"
-msgstr "--passwd <ID пользователя>"
+msgstr "--edit-key user-id [команды]"
 
 #, c-format
 msgid "keyserver send failed: %s\n"
@@ -2118,88 +2012,87 @@ msgstr "сбой при обновлении с сервера ключей: %s\
 
 #, c-format
 msgid "dearmoring failed: %s\n"
-msgstr "ошибка преобразования из текстового формата: %s\n"
+msgstr "ошибка преобразования из ASCII формата: %s\n"
 
 #, c-format
 msgid "enarmoring failed: %s\n"
-msgstr "ошибка преобразования в текстовый формат: %s\n"
+msgstr "ошибка преобразования в ASCII формат: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "недопустимая хэш-функция `%s'\n"
 
 msgid "[filename]"
-msgstr "[файл]"
+msgstr "[имяфайла]"
 
 msgid "Go ahead and type your message ...\n"
-msgstr "Ð\9fиÑ\88иÑ\82е сообщение ...\n"
+msgstr "Ð\9dабиÑ\80айÑ\82е Ð\92аÑ\88е сообщение ...\n"
 
 msgid "the given certification policy URL is invalid\n"
-msgstr "заданный URL правил сертификации неверен\n"
+msgstr "заданный URL политики сертификации неверен\n"
 
 msgid "the given signature policy URL is invalid\n"
-msgstr "заданный URL правил подписи неверен\n"
+msgstr "заданный URL политики подписи неверен\n"
 
 msgid "the given preferred keyserver URL is invalid\n"
-msgstr "заданный URL предпочтительного сервера ключей неверен\n"
+msgstr "заданный URL предпочитаемого сервера ключей неправилен\n"
 
 msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|FILE|взять ключи из файла связок ключей FILE"
+msgstr "|FILE|взять ключи из FILE связок ключей"
 
 msgid "make timestamp conflicts only a warning"
-msgstr "пÑ\80и Ð½ÐµÑ\81ооÑ\82веÑ\82Ñ\81Ñ\82вии Ð¼ÐµÑ\82ки Ð²Ñ\80емени - Ñ\82олÑ\8cко Ð¿Ñ\80едÑ\83пÑ\80еждение"
+msgstr "пÑ\80и Ð½ÐµÑ\81ооÑ\82веÑ\82Ñ\81Ñ\82вии Ð¾Ñ\82меÑ\82ки Ð²Ñ\80емени - Ñ\82олÑ\8cко Ð¿Ñ\80едÑ\83пÑ\80еждением"
 
 msgid "|FD|write status info to this FD"
-msgstr "|FD|выводить информацию в файл с дескриптором FD"
+msgstr "|FD|выводить инфромацию в файл с дескриптором FD"
 
 msgid "Usage: gpgv [options] [files] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: gpgv [параметры] [файлы] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзоваÑ\82Ñ\8c: gpgv [параметры] [файлы] (-h для подсказки)"
 
+#, fuzzy
 msgid ""
 "Syntax: gpgv [options] [files]\n"
 "Check signatures against known trusted keys\n"
 msgstr ""
-"Синтаксис: gpgv [параметры] [файлы]\n"
-"Проверка подписей по доверенным ключам\n"
+"Синтаксис: gpg [параметры] [файлы]\n"
+"Проверка подписей сделанных доверяемыми ключами\n"
 
 msgid "No help available"
-msgstr "СпÑ\80авки Ð½ÐµÑ\82"
+msgstr "Ð\9dеÑ\82 Ð´Ð¾Ñ\81Ñ\82Ñ\83пной Ñ\81пÑ\80авки"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Нет справки для `%s'"
 
 msgid "import signatures that are marked as local-only"
-msgstr "импортировать подписи, обозначенные как `только локальные'"
+msgstr "импорт подписи помеченной как локальная"
 
 msgid "repair damage from the pks keyserver during import"
-msgstr "устранить при импорте повреждения от сервера ключей pks"
-
-msgid "do not clear the ownertrust values during import"
-msgstr "не сбрасывать уровни доверия владельцам после импорта"
+msgstr ""
 
 msgid "do not update the trustdb after import"
-msgstr "не обновлять таблицу доверия после импорта"
+msgstr "не обновлять таблицу доверий после импорта"
 
 msgid "create a public key when importing a secret key"
-msgstr "создать открытый ключ при импорте закрытого ключа"
+msgstr "создать открытый ключ при импорте секретного ключа"
 
 msgid "only accept updates to existing keys"
-msgstr "обновлÑ\8fÑ\82Ñ\8c Ñ\82олÑ\8cко Ñ\81Ñ\83Ñ\89еÑ\81Ñ\82вÑ\83Ñ\8eÑ\89ие ÐºÐ»Ñ\8eÑ\87и"
+msgstr "пÑ\80инимаÑ\82Ñ\8c Ñ\82олÑ\8cко Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ\8f Ð¸Ð¼ÐµÑ\8eÑ\89иÑ\85Ñ\81Ñ\8f ÐºÐ»Ñ\8eÑ\87ей"
 
 msgid "remove unusable parts from key after import"
-msgstr "удалить после импорта непригодные части ключа"
+msgstr "удалять неиспользуемые части из ключа после импорта"
 
 msgid "remove as much as possible from key after import"
-msgstr "удалить после импорта из ключа как можно больше"
+msgstr "удалять всё что возможно из ключа после импорта"
 
 #, c-format
 msgid "skipping block of type %d\n"
 msgstr "пропущен блок типа %d\n"
 
+# test it
 #, c-format
 msgid "%lu keys processed so far\n"
-msgstr "обработано %lu ключей\n"
+msgstr "%lu ключей обработано\n"
 
 #, c-format
 msgid "Total number processed: %lu\n"
@@ -2211,7 +2104,7 @@ msgstr "        пропущено новых ключей: %lu\n"
 
 #, c-format
 msgid "          w/o user IDs: %lu\n"
-msgstr "           без ID пользователя: %lu\n"
+msgstr "                   без User ID: %lu\n"
 
 #, c-format
 msgid "              imported: %lu"
@@ -2223,7 +2116,7 @@ msgstr "                  неизмененных: %lu\n"
 
 #, c-format
 msgid "          new user IDs: %lu\n"
-msgstr "         новых ID пользователя: %lu\n"
+msgstr "                 новых User ID: %lu\n"
 
 #, c-format
 msgid "           new subkeys: %lu\n"
@@ -2239,27 +2132,27 @@ msgstr "          новых отзывов ключей: %lu\n"
 
 #, c-format
 msgid "      secret keys read: %lu\n"
-msgstr "    прочитано закрытых ключей: %lu\n"
+msgstr "    прочитано секретных ключей: %lu\n"
 
 #, c-format
 msgid "  secret keys imported: %lu\n"
-msgstr "импортировано закрытых ключей: %lu\n"
+msgstr "импортировано секретных ключей: %lu\n"
 
 #, c-format
 msgid " secret keys unchanged: %lu\n"
-msgstr " неизмененных закрытых ключей: %lu\n"
+msgstr " неизмененных секретных ключей: %lu\n"
 
 #, c-format
 msgid "          not imported: %lu\n"
-msgstr "             не импортировано: %lu\n"
+msgstr "              не импортировано: %lu\n"
 
 #, c-format
 msgid "    signatures cleaned: %lu\n"
-msgstr "             очищено подписей: %lu\n"
+msgstr "    подписей очищено: %lu\n"
 
 #, c-format
 msgid "      user IDs cleaned: %lu\n"
-msgstr "     очищено ID пользователей: %lu\n"
+msgstr "      очищено User ID: %lu\n"
 
 #, c-format
 msgid ""
@@ -2267,7 +2160,7 @@ msgid ""
 "algorithms on these user IDs:\n"
 msgstr ""
 "ВНИМАНИЕ: ключ %s содержит предпочтения для недоступных\n"
-"алгоритмов для следующих ID пользователей:\n"
+"алгоритмов для данных User IDs:\n"
 
 #, c-format
 msgid "         \"%s\": preference for cipher algorithm %s\n"
@@ -2275,49 +2168,44 @@ msgstr "         \"%s\": предпочитает шифр %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for digest algorithm %s\n"
-msgstr "         \"%s\": предпочитает хэш-функцию %s\n"
+msgstr "         \"%s\": предпочитает хеш-функцию %s\n"
 
 #, c-format
 msgid "         \"%s\": preference for compression algorithm %s\n"
 msgstr "         \"%s\": предпочитает сжатие %s\n"
 
 msgid "it is strongly suggested that you update your preferences and\n"
-msgstr "крайне желательно, чтобы Вы обновили свои предпочтения и\n"
+msgstr "крайне желательно, чтобы Вы обновили Ваши предпочтения и\n"
 
 msgid "re-distribute this key to avoid potential algorithm mismatch problems\n"
 msgstr ""
-"распространили этот ключ во избежание возможных нестыковок алгоритмов\n"
+"распространите данный ключ, чтобы избежать потенциальных проблем "
+"несовпадения алгоритмов\n"
 
 #, c-format
 msgid "you can update your preferences with: gpg --edit-key %s updpref save\n"
 msgstr ""
-"свои предпочтения можно обновить командой gpg --edit-key %s updpref save\n"
+"можете обновить список предпочтений используя: gpg --edit-key %s updpref "
+"save\n"
 
 #, c-format
 msgid "key %s: no user ID\n"
-msgstr "ключ %s: нет ID пользователя\n"
-
-#, c-format
-msgid "key %s: %s\n"
-msgstr "ключ %s: %s\n"
-
-msgid "rejected by import filter"
-msgstr "исключен фильтром импорта"
+msgstr "ключ %s: не имеет User ID\n"
 
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
-msgstr "ключ %s: повреждение подключа PKS исправлено\n"
+msgstr "ключ %s: PKS повреждение подключа исправлено\n"
 
 #, c-format
 msgid "key %s: accepted non self-signed user ID \"%s\"\n"
-msgstr "клÑ\8eÑ\87 %s: Ð¿Ñ\80инÑ\8fÑ\82 Ð±ÐµÐ· Ñ\81амозавеÑ\80енного ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f \"%s\"\n"
+msgstr "клÑ\8eÑ\87 %s: Ð¿Ñ\80инÑ\8fÑ\82 Ð½ÐµÑ\81амоподпиÑ\81аннÑ\8bй User ID \"%s\"\n"
 
 #, c-format
 msgid "key %s: no valid user IDs\n"
-msgstr "ключ %s: нет действительных ID пользователя\n"
+msgstr "ключ %s: нет действительных User ID\n"
 
 msgid "this may be caused by a missing self-signature\n"
-msgstr "можеÑ\82 Ð±Ñ\8bÑ\82Ñ\8c, Ð¸Ð·-за Ð¾Ñ\82Ñ\81Ñ\83Ñ\82Ñ\81Ñ\82виÑ\8f самоподписи\n"
+msgstr "пÑ\80иÑ\87иной Ñ\8dÑ\82ого Ð¼Ð¾Ð¶ÐµÑ\82 Ð±Ñ\8bÑ\82Ñ\8c Ð¾Ñ\82Ñ\81Ñ\83Ñ\82Ñ\81Ñ\82вие самоподписи\n"
 
 #, c-format
 msgid "key %s: public key not found: %s\n"
@@ -2332,36 +2220,36 @@ msgid "no writable keyring found: %s\n"
 msgstr "нет доступной для записи таблицы ключей: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "сохраняю в `%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "ошибка записи таблицы ключей `%s': %s\n"
 
 #, c-format
 msgid "key %s: public key \"%s\" imported\n"
-msgstr "клÑ\8eÑ\87 %s: Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82иÑ\80ован Ð¾Ñ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 \"%s\"\n"
+msgstr "клÑ\8eÑ\87 %s: Ð¾Ñ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 \"%s\" Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82иÑ\80ован\n"
 
 #, c-format
 msgid "key %s: doesn't match our copy\n"
-msgstr "клÑ\8eÑ\87 %s: Ð½Ðµ Ñ\81овпадаеÑ\82 Ñ\81 Ð½Ð°Ñ\88ей ÐºÐ¾Ð¿Ð¸ÐµÐ¹\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½Ðµ Ñ\81овпадаеÑ\82 Ñ\81 ÐºÐ¾Ð¿Ð¸ÐµÐ¹ Ñ\85Ñ\80анимой Ñ\83 Ð½Ð°Ñ\81\n"
 
 #, c-format
 msgid "key %s: can't locate original keyblock: %s\n"
-msgstr "клÑ\8eÑ\87 %s: Ð¾Ñ\80игиналÑ\8cнÑ\8bй Ð±Ð»Ð¾Ðº ÐºÐ»Ñ\8eÑ\87ей Ð½Ðµ Ð½Ð°Ð¹Ð´ÐµÐ½: %s\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½Ðµ Ð½Ð°Ñ\85ожÑ\83 Ð¾Ñ\80игиналÑ\8cнÑ\8bй Ð±Ð»Ð¾Ðº ÐºÐ»Ñ\8eÑ\87ей: %s\n"
 
 #, c-format
 msgid "key %s: can't read original keyblock: %s\n"
-msgstr "клÑ\8eÑ\87 %s: Ð¾Ñ\80игиналÑ\8cнÑ\8bй Ð±Ð»Ð¾Ðº ÐºÐ»Ñ\8eÑ\87ей Ð½Ðµ Ñ\87иÑ\82аеÑ\82Ñ\81Ñ\8f: %s\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½Ðµ Ð¼Ð¾Ð³Ñ\83 Ð¿Ñ\80оÑ\87иÑ\82аÑ\82Ñ\8c Ð¾Ñ\80игиналÑ\8cнÑ\8bй Ð±Ð»Ð¾Ðº ÐºÐ»Ñ\8eÑ\87ей: %s\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new user ID\n"
-msgstr "ключ %s: \"%s\" 1 новый ID пользователя\n"
+msgstr "ключ %s: \"%s\" 1 новый User ID\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d new user IDs\n"
-msgstr "ключ %s: \"%s\" %d новых ID пользователя\n"
+msgstr "ключ %s: \"%s\" %d новых User ID\n"
 
 #, c-format
 msgid "key %s: \"%s\" 1 new signature\n"
@@ -2385,46 +2273,42 @@ msgstr "ключ %s: \"%s\" %d подпись очищена\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d signatures cleaned\n"
-msgstr "клÑ\8eÑ\87 %s: \"%s\" %d Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей Ð¾Ñ\87иÑ\89ено\n"
+msgstr "клÑ\8eÑ\87 %s: \"%s\" %d Ð¾Ñ\87иÑ\89енÑ\8bÑ\85 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d user ID cleaned\n"
-msgstr "ключ %s: \"%s\" %d ID пользователя очищен\n"
+msgstr "ключ %s: \"%s\" %d User ID очищен\n"
 
 #, c-format
 msgid "key %s: \"%s\" %d user IDs cleaned\n"
-msgstr "ключ %s: \"%s\" %d ID пользователя очищено\n"
+msgstr "ключ %s: \"%s\" %d  очищенных User ID\n"
 
 #, c-format
 msgid "key %s: \"%s\" not changed\n"
 msgstr "ключ %s: \"%s\" не изменен\n"
 
 #, c-format
-msgid "secret key %s: %s\n"
-msgstr "закÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 %s: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "клÑ\8eÑ\87 %s: Ñ\81екÑ\80еÑ\82нÑ\8bй ÐºÐ»Ñ\8eÑ\87 Ñ\81 Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имÑ\8bм Ñ\88иÑ\84Ñ\80ом %d - Ð¿Ñ\80опÑ\83Ñ\89ен\n"
 
 msgid "importing secret keys not allowed\n"
-msgstr "импорт закрытого ключа не допускается\n"
-
-#, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "ключ %s: закрытый ключ с недопустимым шифром %d - пропущен\n"
+msgstr "импортирование секретного ключа не позволено\n"
 
 #, c-format
 msgid "no default secret keyring: %s\n"
-msgstr "нет основной таблицы закрытых ключей: %s\n"
+msgstr "нет основной таблицы секретных ключей: %s\n"
 
 #, c-format
 msgid "key %s: secret key imported\n"
-msgstr "ключ %s: импортирован закрытый ключ\n"
+msgstr "ключ %s: секретный ключ импортирован\n"
 
 #, c-format
 msgid "key %s: already in secret keyring\n"
-msgstr "ключ %s: уже есть в таблице закрытых ключей\n"
+msgstr "ключ %s: уже есть в таблице секретных ключей\n"
 
 #, c-format
 msgid "key %s: secret key not found: %s\n"
-msgstr "клÑ\8eÑ\87 %s: Ð·Ð°ÐºÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 Ð½Ðµ Ð½Ð°Ð¹Ð´ÐµÐ½: %s\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½Ðµ Ð½Ð°Ð¹Ð´ÐµÐ½ Ñ\81екÑ\80еÑ\82нÑ\8bй ÐºÐ»Ñ\8eÑ\87: %s\n"
 
 #, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
@@ -2436,37 +2320,32 @@ msgstr "ключ %s: неправильный сертификат отзыва:
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate imported\n"
-msgstr "ключ %s: сертификат отзыва \"%s\" импортирован\n"
+msgstr "ключ %s: \"%s\" сертификат отзыва импортирован\n"
 
 #, c-format
 msgid "key %s: no user ID for signature\n"
-msgstr "ключ %s: нет ID пользователя для подписи\n"
+msgstr "ключ %s: нет User ID для подписи\n"
 
 #, c-format
 msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n"
 msgstr ""
-"ключ %s: алгоритм с открытым ключом у ID пользователя \"%s\" не "
-"поддерживается\n"
+"ключ %s: неподдерживаемый алгоритм с открытым ключом у User ID \"%s\"\n"
 
 #, c-format
 msgid "key %s: invalid self-signature on user ID \"%s\"\n"
-msgstr "ключ %s: неправильная самоподпись на ID пользователя \"%s\"\n"
-
-#, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "ключ %s: алгоритм с открытым ключом не поддерживается\n"
+msgstr "ключ %s: неправильная самоподпись на User ID \"%s\"\n"
 
 #, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "ключ %s: неверная прямая подпись ключа\n"
+msgid "key %s: no subkey for key binding\n"
+msgstr "ключ %s: нет подключа для связывания подключей\n"
 
 #, c-format
-msgid "key %s: no subkey for key binding\n"
-msgstr "ключ %s: нет подключа для связывания ключей\n"
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "ключ %s: неподдерживаемый алгоритм с открытым ключом\n"
 
 #, c-format
 msgid "key %s: invalid subkey binding\n"
-msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имая связь подключей\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÐ¿Ñ\80авилÑ\8cная связь подключей\n"
 
 #, c-format
 msgid "key %s: removed multiple subkey binding\n"
@@ -2478,16 +2357,15 @@ msgstr "ключ %s: нет подключа для отзывающего кл
 
 #, c-format
 msgid "key %s: invalid subkey revocation\n"
-msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÐ²ÐµÑ\80ный отзыв подключа\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÐ¿Ñ\80авилÑ\8cный отзыв подключа\n"
 
-# test it
 #, c-format
 msgid "key %s: removed multiple subkey revocation\n"
-msgstr "ключ %s: удален многократный отзыв подключей\n"
+msgstr "ключ %s: удалена многожественность подключей отзыва\n"
 
 #, c-format
 msgid "key %s: skipped user ID \"%s\"\n"
-msgstr "ключ %s: пропущен ID пользователя \"%s\"\n"
+msgstr "ключ %s: пропущен User ID \"%s\"\n"
 
 #, c-format
 msgid "key %s: skipped subkey\n"
@@ -2495,7 +2373,7 @@ msgstr "ключ %s: пропущен подключ\n"
 
 #, c-format
 msgid "key %s: non exportable signature (class 0x%02X) - skipped\n"
-msgstr "ключ %s: неэкспортируемая подпись (класс 0x%02X) - пропущена\n"
+msgstr "ключ %s: не экспортируемая подпись (класс 0x%02X) - пропущена\n"
 
 #, c-format
 msgid "key %s: revocation certificate at wrong place - skipped\n"
@@ -2511,53 +2389,52 @@ msgstr "ключ %s: подпись подключа в неправильном
 
 #, c-format
 msgid "key %s: unexpected signature class (0x%02X) - skipped\n"
-msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½ный класс подписи (0x%02X) - пропущена\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÐ¸Ð·Ð²ÐµÑ\81Ñ\82ный класс подписи (0x%02X) - пропущена\n"
 
 #, c-format
 msgid "key %s: duplicated user ID detected - merged\n"
-msgstr "ключ %s: обнаружено дублирование ID пользователя - объединены\n"
+msgstr "ключ %s: обнаружено дублирование User ID - объединены\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
-msgstr "ВНИМАНИЕ: ключ %s, возможно, отозван: запрашиваю ключ отзыва %s\n"
+msgstr "ВНИМАНИЕ: ключ %s возможно отозван: запрашиваю ключ отзыва %s\n"
 
 #, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
-msgstr "ВНИМАНИЕ: ключ %s, возможно, отозван: ключ отзыва %s не получен.\n"
+msgstr "ВНИМАНИЕ: ключ %s возможно отозван: ключ отзыва %s не получен.\n"
 
 #, c-format
 msgid "key %s: \"%s\" revocation certificate added\n"
-msgstr "ключ %s: добавлен сертификат отзыва \"%s\"\n"
+msgstr "ключ %s: \"%s\" добавлен сертификат отзыва\n"
 
 #, c-format
 msgid "key %s: direct key signature added\n"
-msgstr "ключ %s: добавлена прямая подпись ключа\n"
+msgstr "ключ %s: direct key signature добавлена\n"
 
 msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr ""
-"ЗАМЕЧАНИЕ: серийный номер ключа не соответствует номеру ключа на карте\n"
+msgstr "ПРЕДУПРЕЖДАЮ: S/N ключа не соответствует S/N ключа на карте\n"
 
 msgid "NOTE: primary key is online and stored on card\n"
-msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð³Ð»Ð°Ð²Ð½Ñ\8bй ÐºÐ»Ñ\8eÑ\87 Ð³Ð¾Ñ\82ов Ð¸ Ñ\81оÑ\85Ñ\80анен Ð½Ð° карте\n"
+msgstr "Ð\9fРÐ\95Ð\94УÐ\9fРÐ\95Ð\96Ð\94Ð\90Ю: Ð³Ð»Ð°Ð²Ð½Ñ\8bй ÐºÐ»Ñ\8eÑ\87 Ð³Ð¾Ñ\82ов Ð¸ Ñ\81оÑ\85Ñ\80анен Ð² карте\n"
 
 msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð²Ñ\82оÑ\80иÑ\87нÑ\8bй ÐºÐ»Ñ\8eÑ\87 Ð³Ð¾Ñ\82ов Ð¸ Ñ\81оÑ\85Ñ\80анен Ð½Ð° карте\n"
+msgstr "Ð\9fРÐ\95Ð\94УÐ\9fРÐ\95Ð\96Ð\94Ð\90Ю: Ð²Ñ\82оÑ\80иÑ\87нÑ\8bй ÐºÐ»Ñ\8eÑ\87 Ð³Ð¾Ñ\82ов Ð¸ Ñ\81оÑ\85Ñ\80анен Ð² карте\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "ошибка создания таблицы ключей `%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "создана таблица ключей `%s'\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
-msgstr "источник блока ключей `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
+msgstr ""
 
 #, c-format
 msgid "failed to rebuild keyring cache: %s\n"
-msgstr "Ñ\81бой Ð¿ÐµÑ\80еÑ\81Ñ\82Ñ\80ойки Ð±Ñ\83Ñ\84еÑ\80а таблицы ключей: %s\n"
+msgstr "Ñ\81бой Ð¿ÐµÑ\80еÑ\81Ñ\82Ñ\80ойки ÐºÑ\8dÑ\88а таблицы ключей: %s\n"
 
 msgid "[revocation]"
 msgstr "[отозван]"
@@ -2587,11 +2464,11 @@ msgid "%d signatures not checked due to errors\n"
 msgstr "%d подписей не проверено из-за ошибок\n"
 
 msgid "1 user ID without valid self-signature detected\n"
-msgstr "обнаружен 1 ID пользователя без действительной самоподписи\n"
+msgstr "обнаружен 1 User ID без действительной самоподписи\n"
 
 #, c-format
 msgid "%d user IDs without valid self-signatures detected\n"
-msgstr "обнаружено %d ID пользователя без действительной самоподписи\n"
+msgstr "обнаружено %d User ID без действительной самоподписи\n"
 
 msgid ""
 "Please decide how far you trust this user to correctly verify other users' "
@@ -2599,9 +2476,10 @@ msgid ""
 "(by looking at passports, checking fingerprints from different sources, "
 "etc.)\n"
 msgstr ""
-"Укажите, насколько Вы доверяете данному пользователю в вопросах проверки\n"
-"достоверности ключей других пользователей (проверяет паспорт,\n"
-"сверяет отпечатки ключей из разных источников и т.п.)\n"
+"Укажите насколько Вы доверяете данному пользователю в\n"
+"вопросах проверки достоверности ключей других пользователей.\n"
+"Проверяет паспорт, сверяет отпечатки ключей и т.п.?\n"
+"\n"
 
 #, c-format
 msgid "  %d = I trust marginally\n"
@@ -2616,11 +2494,10 @@ msgid ""
 "A depth greater than 1 allows the key you are signing to make\n"
 "trust signatures on your behalf.\n"
 msgstr ""
-"Введите глубину этой подписи доверия. Глубина, большая 1,\n"
-"позволÑ\8fеÑ\82 ÐºÐ»Ñ\8eÑ\87Ñ\83, ÐºÐ¾Ñ\82оÑ\80Ñ\8bй Ð\92Ñ\8b Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8bваеÑ\82е, Ð´ÐµÐ»Ð°Ñ\82Ñ\8c Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð´Ð¾Ð²ÐµÑ\80иÑ\8f\n"
-"оÑ\82 Ð\92аÑ\88его Ð¸Ð¼ÐµÐ½Ð¸.\n"
+"Введите глубину доверий для данной подписи.\n"
+"Ð\93лÑ\83бина Ð¿Ñ\80евÑ\8bÑ\88аÑ\8eÑ\89аÑ\8f 1 Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ\82 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8bваемомÑ\83 ÐºÐ»Ñ\8eÑ\87Ñ\83 Ð´ÐµÐ»Ð°Ñ\82Ñ\8c\n"
+"довеÑ\80еннÑ\8bе Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð¾Ñ\82 Ð\92аÑ\88его Ð»Ð¸Ñ\86а.\n"
 
-# check it
 msgid "Please enter a domain to restrict this signature, or enter for none.\n"
 msgstr ""
 "Введите домен, ограничивающий использование данной подписи, или пустую "
@@ -2628,39 +2505,39 @@ msgstr ""
 
 #, c-format
 msgid "User ID \"%s\" is revoked."
-msgstr "ID пользователя \"%s\" отозван."
+msgstr "User ID \"%s\" отозван."
 
 msgid "Are you sure you still want to sign it? (y/N) "
-msgstr "Вы все равно хотите его подписать? (y/N) "
+msgstr "Вы уверены, что хотите подписать? (y/N) "
 
 msgid "  Unable to sign.\n"
 msgstr "  Не могу подписать.\n"
 
 #, c-format
 msgid "User ID \"%s\" is expired."
-msgstr "Срок действия ID пользователя \"%s\" истек."
+msgstr "User ID \"%s\" просрочен."
 
 #, c-format
 msgid "User ID \"%s\" is not self-signed."
-msgstr "ID пользователя \"%s\" не самозаверен."
+msgstr "User ID \"%s\" без самоподписи."
 
 #, c-format
 msgid "User ID \"%s\" is signable.  "
-msgstr "ID пользователя \"%s\" можно подписать."
+msgstr "User ID \"%s\" подписываем."
 
 msgid "Sign it? (y/N) "
-msgstr "Ð\9fодпиÑ\81аÑ\82Ñ\8c ÐµÐ³Ð¾? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аÑ\82Ñ\8c? (y/N)"
 
 #, c-format
 msgid ""
 "The self-signature on \"%s\"\n"
 "is a PGP 2.x-style signature.\n"
 msgstr ""
-"Самоподпись у \"%s\" -\n"
-"это подпись типа PGP 2.x.\n"
+"Самоподпись у \"%s\"\n"
+"это подпись PGP 2.x -стиля.\n"
 
 msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) "
-msgstr "Ð\92Ñ\8b Ñ\85оÑ\82иÑ\82е Ð¿Ñ\80еобÑ\80азоваÑ\82Ñ\8c ÐµÐµ Ð² Ñ\81амоподпиÑ\81Ñ\8c OpenPGP? (y/N) "
+msgstr "ХоÑ\82иÑ\82е Ñ\81делаÑ\82Ñ\8c Ñ\8dÑ\82о Ñ\81амоподпиÑ\81Ñ\8cÑ\8e OpenPGP? (y/N) "
 
 #, c-format
 msgid ""
@@ -2671,7 +2548,7 @@ msgstr ""
 "просрочена.\n"
 
 msgid "Do you want to issue a new signature to replace the expired one? (y/N) "
-msgstr "Ð\92Ñ\8b Ñ\85отите сделать новую подпись для замены просроченной? (y/N) "
+msgstr "Ð¥отите сделать новую подпись для замены просроченной? (y/N) "
 
 #, c-format
 msgid ""
@@ -2682,7 +2559,7 @@ msgstr ""
 "является локальной.\n"
 
 msgid "Do you want to promote it to a full exportable signature? (y/N) "
-msgstr "Ð\92Ñ\8b Ñ\85оÑ\82иÑ\82е Ð¿Ñ\80еобÑ\80азоваÑ\82Ñ\8c ÐµÐµ Ð² Ð¿Ð¾Ð»Ð½Ð¾Ñ\81Ñ\82Ñ\8cÑ\8e Ñ\8dкÑ\81поÑ\80Ñ\82иÑ\80Ñ\83емÑ\83Ñ\8e Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c? (y/N) "
+msgstr "ХоÑ\82иÑ\82е Ñ\81делаÑ\82Ñ\8c Ñ\8dÑ\82о Ð¿Ð¾Ð»Ð½Ð¾Ñ\81Ñ\82Ñ\8cÑ\8e Ñ\8dкÑ\81поÑ\80Ñ\82иÑ\80Ñ\83емой Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8cÑ\8e? (y/N) "
 
 #, c-format
 msgid "\"%s\" was already locally signed by key %s\n"
@@ -2693,7 +2570,7 @@ msgid "\"%s\" was already signed by key %s\n"
 msgstr "\"%s\" уже подписан ключом %s\n"
 
 msgid "Do you want to sign it again anyway? (y/N) "
-msgstr "Ð\92Ñ\8b Ð²Ñ\81е Ñ\80авно Ñ\85оÑ\82иÑ\82е Ñ\81нова Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аÑ\82Ñ\8c ÐµÐ³Ð¾? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\81нова Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аÑ\82Ñ\8c Ñ\8dÑ\82о? (y/N)"
 
 #, c-format
 msgid "Nothing to sign with key %s\n"
@@ -2704,27 +2581,27 @@ msgstr "Данный ключ просрочен!"
 
 #, c-format
 msgid "This key is due to expire on %s.\n"
-msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f данного ключа истекает %s.\n"
+msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и данного ключа истекает %s.\n"
 
 msgid "Do you want your signature to expire at the same time? (Y/n) "
-msgstr ""
-"Вы хотите, чтобы Ваша подпись была действительна до того же времени? (Y/n) "
+msgstr "Хотите чтобы Ваша подпись была действительна до того же времени?(Y/n) "
 
 msgid ""
 "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
 "mode.\n"
-msgstr "Ð\9fодпиÑ\81Ñ\8c OpenPGP Ð½Ð° ÐºÐ»Ñ\8eÑ\87е PGP 2.x Ð² Ñ\80ежиме --pgp2 Ð´ÐµÐ»Ð°Ñ\82Ñ\8c Ð½ÐµÐ»Ñ\8cзÑ\8f.\n"
+msgstr "Ð\9dелÑ\8cзÑ\8f Ñ\81делаÑ\82Ñ\8c OpenPGP Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c Ð½Ð° PGP 2.x ÐºÐ»Ñ\8eÑ\87е Ð² Ñ\80ежиме --pgp2.\n"
 
 msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "Ð\9aлÑ\8eÑ\87 Ñ\81Ñ\82ал Ð±Ñ\8b Ð½ÐµÑ\81овмеÑ\81Ñ\82им с PGP 2.x.\n"
+msgstr "ЭÑ\82о Ñ\81делаеÑ\82 ÐºÐ»Ñ\8eÑ\87 Ð½ÐµÑ\81овмеÑ\81Ñ\82имÑ\8bм с PGP 2.x.\n"
 
 msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
 msgstr ""
-"Насколько хорошо Вы проверили, что ключ действительно принадлежит\n"
-"указанному выше человеку? Если не знаете, что ответить, введите \"0\".\n"
+"Как хорошо проверено то, что ключ действительно принадлежит человеку,\n"
+"чье имя указано в User ID ключа?\n"
+"  Если не уверены как ответить, введите \"0\".\n"
 
 #, c-format
 msgid "   (0) I will not answer.%s\n"
@@ -2732,100 +2609,99 @@ msgstr "   (0) Не буду отвечать.%s\n"
 
 #, c-format
 msgid "   (1) I have not checked at all.%s\n"
-msgstr "   (1) Ð\9dикакой Ð¿Ñ\80овеÑ\80ки Ð½Ðµ Ð±Ñ\8bло.%s\n"
+msgstr "   (1) Ð¯ Ð½Ðµ Ð¿Ñ\80овеÑ\80Ñ\8fл Ñ\81овÑ\81ем.%s\n"
 
 #, c-format
 msgid "   (2) I have done casual checking.%s\n"
-msgstr "   (2) Ð\91Ñ\8bла Ñ\87аÑ\81Ñ\82иÑ\87наÑ\8f Ð¿Ñ\80овеÑ\80ка.%s\n"
+msgstr "   (2) Ð¯ Ð¿Ñ\80овеÑ\80ил Ñ\87аÑ\81Ñ\82иÑ\87но.%s\n"
 
 #, c-format
 msgid "   (3) I have done very careful checking.%s\n"
-msgstr "   (3) Ð\9fÑ\80овеÑ\80ка Ð±Ñ\8bла Ð¾Ñ\87енÑ\8c Ñ\82Ñ\89аÑ\82елÑ\8cной.%s\n"
+msgstr "   (3) Ð¯ Ð¿Ñ\80овеÑ\80ил Ð¾Ñ\87енÑ\8c Ñ\82Ñ\89аÑ\82елÑ\8cно.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
-msgstr "Ваш выбор? (введите '?' для получения информации): "
+msgid "Your selection? (enter '?' for more information): "
+msgstr "Ваше решение? (введите '?' для получения информации)"
 
 #, c-format
 msgid ""
 "Are you sure that you want to sign this key with your\n"
 "key \"%s\" (%s)\n"
 msgstr ""
-"Ð\92Ñ\8b Ñ\83веÑ\80енÑ\8b, что хотите подписать этот ключ\n"
-"своим ключом \"%s\" (%s)?\n"
+"УвеÑ\80енÑ\8b Ð² Ñ\82ом, что хотите подписать этот ключ\n"
+"своим ключом: \"%s\" (%s)\n"
 
 msgid "This will be a self-signature.\n"
 msgstr "Это будет самоподпись.\n"
 
 msgid "WARNING: the signature will not be marked as non-exportable.\n"
-msgstr "ВНИМАНИЕ: подпись не будет помечена как неэкспортируемая.\n"
+msgstr "ВНИМАНИЕ: подпись не будет помечена как не экспортируемая.\n"
 
 msgid "WARNING: the signature will not be marked as non-revocable.\n"
-msgstr "ВНИМАНИЕ: подпись не будет помечена как неотзываемая.\n"
+msgstr "ВНИМАНИЕ: подпись не будет помечена как не отзываемая.\n"
 
 msgid "The signature will be marked as non-exportable.\n"
-msgstr "Подпись будет помечена как неэкспортируемая.\n"
+msgstr "Подпись будет помечена как не экспортируемая.\n"
 
 msgid "The signature will be marked as non-revocable.\n"
-msgstr "Подпись будет помечена как неотзываемая.\n"
+msgstr "Подпись будет помечена как не отзываемая.\n"
 
 msgid "I have not checked this key at all.\n"
-msgstr "ЭÑ\82оÑ\82 ÐºÐ»Ñ\8eÑ\87 Ð¼Ð½Ð¾Ð¹ Ð½Ð¸ÐºÐ°Ðº Ð½Ðµ Ð¿Ñ\80овеÑ\80Ñ\8fлÑ\81Ñ\8f.\n"
+msgstr "Я Ñ\81овÑ\81ем Ð½Ðµ Ð¿Ñ\80овеÑ\80Ñ\8fл Ñ\8dÑ\82оÑ\82 ÐºÐ»Ñ\8eÑ\87.\n"
 
 msgid "I have checked this key casually.\n"
-msgstr "Ð\9cной Ð¿Ñ\80оведена Ð¿Ð¾Ð²ÐµÑ\80Ñ\85ноÑ\81Ñ\82наÑ\8f Ð¿Ñ\80овеÑ\80ка Ñ\8dÑ\82ого ÐºÐ»Ñ\8eÑ\87а.\n"
+msgstr "Я Ð¿Ñ\80овеÑ\80ил Ñ\8dÑ\82оÑ\82 ÐºÐ»Ñ\8eÑ\87 Ñ\82олÑ\8cко Ñ\87аÑ\81Ñ\82иÑ\87но.\n"
 
 msgid "I have checked this key very carefully.\n"
-msgstr "ЭÑ\82оÑ\82 ÐºÐ»Ñ\8eÑ\87 Ð¿Ñ\80овеÑ\80ен Ð¼Ð½Ð¾Ð¹ Ð¾Ñ\87енÑ\8c Ñ\82Ñ\89аÑ\82елÑ\8cно.\n"
+msgstr "Я Ð¾Ñ\87енÑ\8c Ñ\82Ñ\89аÑ\82елÑ\8cно Ð¿Ñ\80овеÑ\80ил Ñ\8dÑ\82оÑ\82 ÐºÐ»Ñ\8eÑ\87.\n"
 
 msgid "Really sign? (y/N) "
-msgstr "Действительно подписать? (y/N) "
+msgstr "Действительно подписать? (y/N)"
 
 #, c-format
 msgid "signing failed: %s\n"
-msgstr "подпиÑ\81аÑ\82Ñ\8c Ð½Ðµ Ñ\83далоÑ\81ь: %s\n"
+msgstr "не Ñ\83далоÑ\81Ñ\8c Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аÑ\82ь: %s\n"
 
 msgid "Key has only stub or on-card key items - no passphrase to change.\n"
 msgstr ""
-"В ключе только заготовка или элементы для карты - пароля для изменения нет.\n"
 
 msgid "This key is not protected.\n"
 msgstr "Данный ключ не защищен.\n"
 
 msgid "Secret parts of primary key are not available.\n"
-msgstr "Ð\97акÑ\80Ñ\8bÑ\82Ñ\8bе Ñ\87аÑ\81Ñ\82и Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ»Ñ\8eÑ\87а Ð¾Ñ\82Ñ\81Ñ\83Ñ\82Ñ\81Ñ\82вÑ\83Ñ\8eт.\n"
+msgstr "СекÑ\80еÑ\82наÑ\8f Ñ\87аÑ\81Ñ\82Ñ\8c Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ»Ñ\8eÑ\87а Ð¾Ñ\82Ñ\81Ñ\83Ñ\82Ñ\81Ñ\82вÑ\83ет.\n"
 
 msgid "Secret parts of primary key are stored on-card.\n"
-msgstr "Ð\97акÑ\80Ñ\8bÑ\82Ñ\8bе Ñ\87аÑ\81Ñ\82и Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ»Ñ\8eÑ\87а Ñ\81оÑ\85Ñ\80аненÑ\8b на карте.\n"
+msgstr "СекÑ\80еÑ\82наÑ\8f Ñ\87аÑ\81Ñ\82Ñ\8c Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ»Ñ\8eÑ\87а Ñ\81оÑ\85Ñ\80анена на карте.\n"
 
 msgid "Key is protected.\n"
 msgstr "Ключ защищен.\n"
 
 #, c-format
 msgid "Can't edit this key: %s\n"
-msgstr "Ð\94аннÑ\8bй ÐºÐ»Ñ\8eÑ\87 Ð½Ðµ Ñ\80едакÑ\82иÑ\80Ñ\83еÑ\82Ñ\81Ñ\8f: %s\n"
+msgstr "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ñ\80едакÑ\82иÑ\80оваÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bй ÐºÐ»Ñ\8eÑ\87: %s\n"
 
 msgid ""
 "Enter the new passphrase for this secret key.\n"
 "\n"
 msgstr ""
-"Введите новую фразу-пароль для данного закрытого ключа.\n"
+"Введите новую фразу-пароль для данного секретного ключа.\n"
 "\n"
 
 msgid "passphrase not correctly repeated; try again"
-msgstr "фраза-пароль повторена неверно; попробуйте еще раз"
+msgstr "повторный ввод фразы-пароля некорректен; попробуйте еще раз"
 
 msgid ""
 "You don't want a passphrase - this is probably a *bad* idea!\n"
 "\n"
 msgstr ""
-"ХоÑ\82иÑ\82е Ð¾Ð±Ð¾Ð¹Ñ\82иÑ\81Ñ\8c Ð±ÐµÐ· Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f? Ð¡ÐºÐ¾Ñ\80ее Ð²Ñ\81его, Ñ\8dÑ\82о Ð\9fÐ\9bÐ\9eÐ¥Ð\90Я Ð¼Ñ\8bÑ\81лÑ\8c!\n"
+"Ð\9dе Ñ\85оÑ\82иÑ\82е Ð·Ð°Ð´Ð°Ñ\82Ñ\8c Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c? Ð­Ñ\82о Ð¾Ñ\87енÑ\8c *Ð\9fÐ\9bÐ\9eÐ¥Ð\90Я* Ð¸Ð´ÐµÑ\8f!\n"
 "\n"
 
 msgid "Do you really want to do this? (y/N) "
-msgstr "Ð\92Ñ\8b Ð²Ñ\81е Ñ\80авно Ñ\85оÑ\82иÑ\82е Ñ\8dÑ\82ого? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\81делаÑ\82Ñ\8c Ñ\8dÑ\82о? (y/N)"
 
 msgid "moving a key signature to the correct place\n"
-msgstr "пеÑ\80емеÑ\89ение Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и ÐºÐ»Ñ\8eÑ\87а Ð² Ð½Ñ\83жное место\n"
+msgstr "пеÑ\80емеÑ\89ение Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и ÐºÐ»Ñ\8eÑ\87а Ð² Ð¿Ñ\80авилÑ\8cное место\n"
 
 msgid "save and quit"
 msgstr "сохранить и выйти"
@@ -2834,10 +2710,10 @@ msgid "show key fingerprint"
 msgstr "показать отпечаток ключа"
 
 msgid "list key and user IDs"
-msgstr "вывести список ключей и ID пользователя"
+msgstr "вывести список ключей и User ID"
 
 msgid "select user ID N"
-msgstr "выбрать ID пользователя N"
+msgstr "выбрать User ID N"
 
 msgid "select subkey N"
 msgstr "выбрать подключ N"
@@ -2846,25 +2722,25 @@ msgid "check signatures"
 msgstr "проверка подписей"
 
 msgid "sign selected user IDs [* see below for related commands]"
-msgstr "подписать выбранные ID пользователя [* описание команд см. ниже]"
+msgstr "подписать выбранные User ID [* описание соотв. команд см. ниже]"
 
 msgid "sign selected user IDs locally"
-msgstr "локально подписать выбранные ID пользователя"
+msgstr "локально подписать выбранные User ID"
 
 msgid "sign selected user IDs with a trust signature"
-msgstr "подписать выбранные ID пользователя подписью доверия"
+msgstr "подписать выбранные User ID - trust подписью"
 
 msgid "sign selected user IDs with a non-revocable signature"
-msgstr "подписать выбранные ID пользователя без возможности отзыва"
+msgstr "подписать выбранные User ID без возможности отзыва"
 
 msgid "add a user ID"
-msgstr "добавить ID пользователя"
+msgstr "добавить User ID"
 
 msgid "add a photo ID"
-msgstr "добавить фотоидентификатор"
+msgstr "добавить фото ID"
 
 msgid "delete selected user IDs"
-msgstr "удалить выбранные ID пользователя"
+msgstr "удалить выбранные User ID"
 
 msgid "add a subkey"
 msgstr "добавить подключ"
@@ -2876,7 +2752,7 @@ msgid "move a key to a smartcard"
 msgstr "переместить ключ на карту"
 
 msgid "move a backup key to a smartcard"
-msgstr "переместить архивный ключ на карту"
+msgstr "переместить резервную копию на смарткарту"
 
 msgid "delete selected subkeys"
 msgstr "удалить выбранные подключи"
@@ -2885,13 +2761,13 @@ msgid "add a revocation key"
 msgstr "добавить ключ отзыва"
 
 msgid "delete signatures from the selected user IDs"
-msgstr "удалить подписи у выбранных ID пользователя"
+msgstr "удалить подписи у выбранных User ID"
 
 msgid "change the expiration date for the key or selected subkeys"
-msgstr "Ñ\81мениÑ\82Ñ\8c Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f ключа или выбранных подключей"
+msgstr "Ñ\81мениÑ\82Ñ\8c Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и ключа или выбранных подключей"
 
 msgid "flag the selected user ID as primary"
-msgstr "пометить выбранный ID пользователя как главный"
+msgstr "пометить выбранный User ID как главный"
 
 msgid "toggle between the secret and public key listings"
 msgstr "переключение между просмотром открытых и закрытых ключей"
@@ -2903,14 +2779,13 @@ msgid "list preferences (verbose)"
 msgstr "список предпочтений (подробный)"
 
 msgid "set preference list for the selected user IDs"
-msgstr "установить список предпочтений для выбранных ID пользователя"
+msgstr "установить список предпочтений для выбранных User ID"
 
 msgid "set the preferred keyserver URL for the selected user IDs"
-msgstr ""
-"установить URL предпочтительного сервера ключей для выбранных ID пользователя"
+msgstr "установить URL предпочитаемого сервера ключей для выбранных User ID"
 
 msgid "set a notation for the selected user IDs"
-msgstr "установить примечание для выбранных ID пользователя"
+msgstr "установить примечание для выбранных User ID"
 
 msgid "change the passphrase"
 msgstr "сменить фразу-пароль"
@@ -2919,39 +2794,38 @@ msgid "change the ownertrust"
 msgstr "изменить уровень доверия владельцу"
 
 msgid "revoke signatures on the selected user IDs"
-msgstr "отозвать подписи у выбранных ID пользователя"
+msgstr "отозвать подписи у выбранных User ID"
 
 msgid "revoke selected user IDs"
-msgstr "оÑ\82озваÑ\82Ñ\8c Ð²Ñ\8bбÑ\80аннÑ\8bе ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f"
+msgstr "оÑ\82зÑ\8bв Ð²Ñ\8bбÑ\80аннÑ\8bÑ\85 User ID"
 
 msgid "revoke key or selected subkeys"
-msgstr "оÑ\82озваÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87 Ð¸Ð»Ð¸ Ð²Ñ\8bбÑ\80аннÑ\8bе Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87и"
+msgstr "оÑ\82зÑ\8bв ÐºÐ»Ñ\8eÑ\87а Ð¸Ð»Ð¸ Ð²Ñ\8bбÑ\80аннÑ\8bÑ\85 Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87ей"
 
 msgid "enable key"
-msgstr "подключить ключ"
+msgstr "включить ключ"
 
 msgid "disable key"
 msgstr "отключить ключ"
 
 msgid "show selected photo IDs"
-msgstr "показать выбранные фотоидентификаторы"
+msgstr "показать выбранные фото ID"
 
 msgid "compact unusable user IDs and remove unusable signatures from key"
-msgstr ""
-"сжать непригодные ID пользователей и удалить непригодные подписи из ключа"
+msgstr "сжать неиспользуемые User ID и удалить неиспользуемые подписи с ключа"
 
 msgid "compact unusable user IDs and remove all signatures from key"
-msgstr "Ñ\81жаÑ\82Ñ\8c Ð½ÐµÐ¿Ñ\80игоднÑ\8bе ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елей Ð¸ Ñ\83далиÑ\82Ñ\8c Ð²Ñ\81е Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð¸Ð· ключа"
+msgstr "Ñ\81жаÑ\82Ñ\8c Ð½ÐµÐ¸Ñ\81полÑ\8cзÑ\83емÑ\8bе User ID Ð¸ Ñ\83далиÑ\82Ñ\8c Ð²Ñ\81е Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ñ\81 ключа"
 
 #, c-format
 msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "ошибка чтения закрытого блока ключа \"%s\": %s\n"
+msgstr "ошибка чтения секретного блока ключа \"%s\": %s\n"
 
 msgid "Secret key is available.\n"
-msgstr "Ð\97акÑ\80Ñ\8bÑ\82ый ключ доступен.\n"
+msgstr "СекÑ\80еÑ\82ный ключ доступен.\n"
 
 msgid "Need the secret key to do this.\n"
-msgstr "Для данного действия нужен закрытый ключ.\n"
+msgstr "Для данного действия нужен секретный ключ.\n"
 
 msgid "Please use the command \"toggle\" first.\n"
 msgstr "Сначала воспользуйтесь командой \"toggle\".\n"
@@ -2962,102 +2836,102 @@ msgid ""
 "  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
-"* У команды `sign' может быть приставка `l' (локальные подписи, lsign),\n"
-"  `t' (подписи доверия, tsign), `nr' (неотзываемые, \n"
-"  nrsign) или любое их сочетание (ltsign, tnrsign и т.д.).\n"
+"* Команда `sign' может быть дополнена префиксом: `l' - локально подписать "
+"lsign),\n"
+"  `t' - trust подпись (tsign), `nr' - без возможности отзыва\n"
+"  (nrsign) или любым их сочетанием (ltsign, tnrsign и т.д.).\n"
 
 msgid "Key is revoked."
 msgstr "Ключ отозван."
 
 msgid "Really sign all user IDs? (y/N) "
-msgstr "Действительно подписать все ID пользователя? (y/N) "
+msgstr "Действительно хотите подписать ВСЕ User ID? (y/N)"
 
 msgid "Hint: Select the user IDs to sign\n"
-msgstr "Ð\9fодÑ\81казка: Ð\92Ñ\8bбеÑ\80иÑ\82е ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елей Ð´Ð»Ñ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и\n"
+msgstr "СовеÑ\82: Ð\92Ñ\8bбеÑ\80иÑ\82е User ID Ð´Ð»Ñ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аниÑ\8f\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Неизвестный тип подписи `%s'\n"
 
 #, c-format
 msgid "This command is not allowed while in %s mode.\n"
-msgstr "Данная команда недопустима в режиме %s.\n"
+msgstr "Данная команда не допустима в режиме %s.\n"
 
 msgid "You must select at least one user ID.\n"
-msgstr "Ð\92Ñ\8b Ð´Ð¾Ð»Ð¶Ð½Ñ\8b Ð²Ñ\8bбÑ\80аÑ\82Ñ\8c Ñ\85оÑ\82Ñ\8f Ð±Ñ\8b Ð¾Ð´Ð¸Ð½ ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f.\n"
+msgstr "СледÑ\83еÑ\82 Ð²Ñ\8bбÑ\80аÑ\82Ñ\8c Ñ\85оÑ\82Ñ\8f Ð±Ñ\8b Ð¾Ð´Ð¸Ð½ User ID.\n"
 
 msgid "You can't delete the last user ID!\n"
-msgstr "Ð\92Ñ\8b Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ\82е Ñ\83далиÑ\82Ñ\8c Ð¿Ð¾Ñ\81ледний ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f!\n"
+msgstr "Ð\9dелÑ\8cзÑ\8f Ñ\83далиÑ\82Ñ\8c Ð¿Ð¾Ñ\81ледний User ID!\n"
 
 msgid "Really remove all selected user IDs? (y/N) "
-msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\83далиÑ\82Ñ\8c Ð²Ñ\81е Ð²Ñ\8bбÑ\80аннÑ\8bе ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елей? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c Ð\92СÐ\95 Ð²Ñ\8bбÑ\80аннÑ\8bе User IDs? (y/N)"
 
 msgid "Really remove this user ID? (y/N) "
-msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\83далиÑ\82Ñ\8c Ñ\8dÑ\82оÑ\82 ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bй User ID? (y/N)"
 
 #. TRANSLATORS: Please take care: This is about
 #. moving the key and not about removing it.
 msgid "Really move the primary key? (y/N) "
-msgstr "Действительно удалить главный ключ? (y/N) "
+msgstr "Действительно удалить главный ключ? (y/N)"
 
 msgid "You must select exactly one key.\n"
-msgstr "Ð\92Ñ\8b Ð´Ð¾Ð»Ð¶Ð½Ñ\8b выбрать хотя бы один ключ.\n"
+msgstr "СледÑ\83еÑ\82 выбрать хотя бы один ключ.\n"
 
 msgid "Command expects a filename argument\n"
-msgstr "Ð\9aоманде Ð½Ñ\83жен Ð°Ñ\80гÑ\83менÑ\82-имя файла\n"
+msgstr "Ð\9aоманда Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ\82 Ð°Ñ\80гÑ\83менÑ\82имя файла\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "Не могу открыть `%s': %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
-msgstr "Ошибка чтения архивного ключа из `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
+msgstr "Ошибка чтения резервного ключа с `%s': %s\n"
 
 msgid "You must select at least one key.\n"
-msgstr "Ð\92Ñ\8b Ð´Ð¾Ð»Ð¶Ð½Ñ\8b выбрать хотя бы один ключ.\n"
+msgstr "СледÑ\83еÑ\82 выбрать хотя бы один ключ.\n"
 
 msgid "Do you really want to delete the selected keys? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c Ð²Ñ\8bбÑ\80аннÑ\8bе ÐºÐ»Ñ\8eÑ\87и? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c Ð²Ñ\8bбÑ\80аннÑ\8bе ÐºÐ»Ñ\8eÑ\87и? (y/N)"
 
 msgid "Do you really want to delete this key? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bй ÐºÐ»Ñ\8eÑ\87? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bй ÐºÐ»Ñ\8eÑ\87? (y/N)"
 
 msgid "Really revoke all selected user IDs? (y/N) "
-msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ð¾Ñ\82озваÑ\82Ñ\8c Ð²Ñ\81е Ð²Ñ\8bбÑ\80аннÑ\8bе ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елей? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ð¾Ñ\82озваÑ\82Ñ\8c Ð\92СÐ\95 Ð²Ñ\8bбÑ\80аннÑ\8bе User ID? (y/N)"
 
 msgid "Really revoke this user ID? (y/N) "
-msgstr "Действительно отозвать данный ID пользователя? (y/N) "
+msgstr "Действительно отозвать данный User ID? (y/N)"
 
 msgid "Do you really want to revoke the entire key? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¾Ñ\82озваÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87 Ñ\86еликом? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¾Ñ\82озваÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87 Ñ\86еликом? (y/N)"
 
 msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¾Ñ\82озваÑ\82Ñ\8c Ð²Ñ\8bбÑ\80аннÑ\8bе Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87и? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¾Ñ\82озваÑ\82Ñ\8c Ð²Ñ\8bбÑ\80аннÑ\8bе Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87и? (y/N)"
 
 msgid "Do you really want to revoke this subkey? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¾Ñ\82озваÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bй Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¾Ñ\82озваÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bй Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87? (y/N)"
 
 msgid "Owner trust may not be set while using a user provided trust database\n"
 msgstr ""
-"Ð\9dелÑ\8cзÑ\8f Ð¿Ñ\80иÑ\81ваиваÑ\82Ñ\8c Ñ\81Ñ\82епенÑ\8c Ð´Ð¾Ð²ÐµÑ\80иÑ\8f, ÐºÐ¾Ð³Ð´Ð° Ñ\82аблиÑ\86а Ð´Ð¾Ð²ÐµÑ\80иÑ\8f Ñ\83казана "
-"пользователем\n"
+"Ð\94овеÑ\80ие Ð²Ð»Ð°Ð´ÐµÐ»Ñ\8cÑ\86Ñ\83 Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ\82 Ð±Ñ\8bÑ\82Ñ\8c Ð½Ð°Ñ\81Ñ\82Ñ\80оено Ñ\81 Ð¿Ñ\80едоÑ\81Ñ\82авленной Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елем "
+"таблицы доверий\n"
 
 msgid "Set preference list to:\n"
 msgstr "Установить предпочтения в:\n"
 
 msgid "Really update the preferences for the selected user IDs? (y/N) "
-msgstr ""
-"Действительно обновить предпочтения для выбранных ID пользователей? (y/N) "
+msgstr "Действительно обновить предпочтения для выбранных User ID? (y/N)"
 
 msgid "Really update the preferences? (y/N) "
-msgstr "Действительно обновить предпочтения? (y/N) "
+msgstr "Действительно обновить предпочтения? (y/N)"
 
 msgid "Save changes? (y/N) "
-msgstr "Сохранить изменения? (y/N) "
+msgstr "Сохранить изменения? (y/N)"
 
 msgid "Quit without saving? (y/N) "
-msgstr "Выйти без сохранения? (y/N) "
+msgstr "Выйти без сохранения? (y/N)"
 
 #, c-format
 msgid "update failed: %s\n"
@@ -3065,7 +2939,7 @@ msgstr "сбой при обновлении: %s\n"
 
 #, c-format
 msgid "update secret failed: %s\n"
-msgstr "Ñ\81бой Ð¿Ñ\80и Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¸ Ð·Ð°ÐºÑ\80Ñ\8bÑ\82ого ключа: %s\n"
+msgstr "Ñ\81бой Ð¿Ñ\80и Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹ Ñ\81екÑ\80еÑ\82ного ключа: %s\n"
 
 msgid "Key not changed so no update needed.\n"
 msgstr "Ключ не изменялся - обновление не нужно.\n"
@@ -3074,51 +2948,50 @@ msgid "Digest: "
 msgstr "Хэш-функции: "
 
 msgid "Features: "
-msgstr "ХаÑ\80акÑ\82еÑ\80иÑ\81Ñ\82ики: "
+msgstr "Ð\9eпÑ\86ии: "
 
-# check it
 msgid "Keyserver no-modify"
-msgstr "Не изменять на сервере"
+msgstr ""
 
 msgid "Preferred keyserver: "
-msgstr "Предпочтительный сервер ключей: "
+msgstr "Предпочитаемый сервер ключей: "
 
 msgid "Notations: "
 msgstr "Примечания: "
 
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
-msgstr "Ð\92 ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f Ñ\82ипа PGP 2.x Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ\82 Ð±Ñ\8bÑ\82Ñ\8c Ð¿Ñ\80едпоÑ\87Ñ\82ений.\n"
+msgstr "Ð\9dе Ð¼Ð¾Ð¶ÐµÑ\82 Ð±Ñ\8bÑ\82Ñ\8c Ð¿Ñ\80едпоÑ\87Ñ\82ений Ð² PGP 2.x-Ñ\81Ñ\82иле User ID.\n"
 
 #, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "СледÑ\83Ñ\8eÑ\89ий ÐºÐ»Ñ\8eÑ\87 Ð±Ñ\8bл Ð¾Ñ\82озван %s Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елем %s ключом %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
+msgstr "Ð\94аннÑ\8bй ÐºÐ»Ñ\8eÑ\87 Ð±Ñ\8bл Ð¾Ñ\82озван %s - %s ключом %s\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
-msgstr "Данный ключ может быть отозван пользователем %s ключом %s"
+msgstr "Данный ключ может быть отозван %s ключом %s "
 
 msgid "(sensitive)"
-msgstr "(особо важный)"
+msgstr ""
 
 #, c-format
 msgid "created: %s"
-msgstr "      создан: %s"
+msgstr "создан: %s"
 
 #, c-format
 msgid "revoked: %s"
-msgstr "     отозван: %s"
+msgstr "отозван: %s"
 
 #, c-format
 msgid "expired: %s"
-msgstr " просрочен с: %s"
+msgstr "просрочен с: %s"
 
 #, c-format
 msgid "expires: %s"
-msgstr "    годен до: %s"
+msgstr "годен до: %s"
 
 #, c-format
 msgid "usage: %s"
-msgstr "применимость: %s"
+msgstr "применяемость: %s"
 
 #, c-format
 msgid "trust: %s"
@@ -3132,49 +3005,41 @@ msgid "This key has been disabled"
 msgstr "Данный ключ отключен"
 
 msgid "card-no: "
-msgstr "номер карты: "
+msgstr ""
 
 msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
 msgstr ""
-"Учтите, что показанная действительность ключа может быть неверной,\n"
-"пока Ð\92Ñ\8b Ð½Ðµ Ð¿ÐµÑ\80езапÑ\83Ñ\81Ñ\82иÑ\82е Ð¿Ñ\80огÑ\80аммÑ\83.\n"
+"Учтите, что показанные степени достоверности могут быть неверными,\n"
+"пока Ð¿Ñ\80огÑ\80амма Ð½Ðµ Ð±Ñ\83деÑ\82 Ð¿ÐµÑ\80езапÑ\83Ñ\89ена.\n"
 
 msgid "revoked"
 msgstr "отозван"
 
 msgid "expired"
-msgstr "просрочен"
+msgstr "просрочен с"
 
-# check it
 msgid ""
 "WARNING: no user ID has been marked as primary.  This command may\n"
 "              cause a different user ID to become the assumed primary.\n"
 msgstr ""
-"ВНИМАНИЕ: нет ID пользователя, помеченного как главный. Эта команда может\n"
-"          привести к тому, что главным станет считаться другой ID "
-"пользователя.\n"
-
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr "ВНИМАНИЕ: Срок годности Вашего подключа скоро истечет.\n"
-
-msgid "You may want to change its expiration date too.\n"
-msgstr "Возможно, надо изменить и его срок действия.\n"
+"ВНИМАНИЕ: нет User ID помеченного как главный. Данная команда может\n"
+"              воспользоваться другим user ID, используя его как главный.\n"
 
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
 "         of PGP to reject this key.\n"
 msgstr ""
-"ВНИМАНИЕ: Это ключ PGP2. Добавление фотоидентификатора может в некоторых\n"
-"          версиях PGP вызвать отбраковку ключа.\n"
+"ВНИМАНИЕ: Это ключ PGP2.  Добавление фото ID может в некоторых версиях\n"
+"         PGP вызвать выбраковку ключа.\n"
 
 msgid "Are you sure you still want to add it? (y/N) "
 msgstr "Вы уверены, что хотите добавить это? (y/N) "
 
 msgid "You may not add a photo ID to a PGP2-style key.\n"
-msgstr "Ð\9dелÑ\8cзÑ\8f Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ñ\84оÑ\82оиденÑ\82иÑ\84икаÑ\82оÑ\80 Ð² ÐºÐ»Ñ\8eÑ\87 Ñ\82ипа PGP2.\n"
+msgstr "Ð\9dелÑ\8cзÑ\8f Ð´Ð¾Ð±Ð°Ð²Ð»Ñ\8fÑ\82Ñ\8c Ñ\84оÑ\82о ID Ð² ÐºÐ»Ñ\8eÑ\87 PGP2-Ñ\82ипа.\n"
 
 msgid "Delete this good signature? (y/N/q)"
 msgstr "Удалить данную действительную подпись? (y/N/q)"
@@ -3194,7 +3059,7 @@ msgstr "Удалена %d подпись.\n"
 
 #, c-format
 msgid "Deleted %d signatures.\n"
-msgstr "Удалено %d Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей.\n"
+msgstr "Удалено %d Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и.\n"
 
 msgid "Nothing deleted.\n"
 msgstr "Ничего не удалено.\n"
@@ -3204,129 +3069,128 @@ msgstr "недопустимый"
 
 #, c-format
 msgid "User ID \"%s\" compacted: %s\n"
-msgstr "ID пользователя \"%s\" сжат: %s\n"
+msgstr "User ID \"%s\": сжат: %s\n"
 
 #, c-format
 msgid "User ID \"%s\": %d signature removed\n"
-msgstr "ID пользователя \"%s\": %d подпись удалена\n"
+msgstr "User ID \"%s\": %d подпись удалена\n"
 
 #, c-format
 msgid "User ID \"%s\": %d signatures removed\n"
-msgstr "ID пользователя \"%s\": %d подписей удалено\n"
+msgstr "User ID \"%s\": %d удалено подписей\n"
 
 #, c-format
 msgid "User ID \"%s\": already minimized\n"
-msgstr "ID пользователя \"%s\" уже минимизирован\n"
+msgstr "User ID \"%s\": уже минимизирован\n"
 
 #, c-format
 msgid "User ID \"%s\": already clean\n"
-msgstr "ID пользователя \"%s\" уже очищен\n"
+msgstr "User ID \"%s\": уже очищен\n"
 
 msgid ""
 "WARNING: This is a PGP 2.x-style key.  Adding a designated revoker may "
 "cause\n"
 "         some versions of PGP to reject this key.\n"
 msgstr ""
-"ВНИМАНИЕ: Это ключ типа PGP 2.x. Добавление особого отзывающего ключа\n"
+"ВНИМАНИЕ: Это ключ PGP 2.x. Добавление назначенного отзывающим ключа\n"
 "          может в некоторых версиях PGP вызвать выбраковку ключа.\n"
 
 msgid "You may not add a designated revoker to a PGP 2.x-style key.\n"
-msgstr "Ð\9dелÑ\8cзÑ\8f Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð¾Ñ\81обÑ\8bй Ð¾Ñ\82зÑ\8bваÑ\8eÑ\89ий ÐºÐ»Ñ\8eÑ\87 Ð² ÐºÐ»Ñ\8eÑ\87 Ñ\82ипа PGP 2.x.\n"
+msgstr "Ð\9dелÑ\8cзÑ\8f Ð´Ð¾Ð±Ð°Ð²Ð»Ñ\8fÑ\82Ñ\8c Ð½Ð°Ð·Ð½Ð°Ñ\87еннÑ\8bй Ð¾Ñ\82зÑ\8bваÑ\8eÑ\89им ÐºÐ»Ñ\8eÑ\87 Ð² PGP 2.x ÐºÐ»Ñ\8eÑ\87.\n"
 
 msgid "Enter the user ID of the designated revoker: "
-msgstr "Укажите ID пользователя ключа, назначенного отзывающим: "
+msgstr "Укажите User ID ключа, назначенного отзывающим: "
 
 msgid "cannot appoint a PGP 2.x style key as a designated revoker\n"
-msgstr "нелÑ\8cзÑ\8f Ð½Ð°Ð·Ð½Ð°Ñ\87иÑ\82Ñ\8c Ð¾Ñ\82зÑ\8bваÑ\8eÑ\89им ÐºÐ»Ñ\8eÑ\87 Ñ\82ипа PGP 2.x\n"
+msgstr "нелÑ\8cзÑ\8f Ð½Ð°Ð·Ð½Ð°Ñ\87иÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87 PGP 2.x Ð¾Ñ\82зÑ\8bваÑ\8eÑ\89им\n"
 
 msgid "you cannot appoint a key as its own designated revoker\n"
-msgstr "ключ не может быть назначен отзывающим самого себя\n"
+msgstr "ключ не может быть назначен отзывающим сам себя\n"
 
 msgid "this key has already been designated as a revoker\n"
 msgstr "этот ключ уже назначен отзывающим\n"
 
 msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n"
-msgstr "ВНИМАНИЕ: назначение ключа отзывающим невозможно отменить!\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½Ð°Ð·Ð½Ð°Ñ\87ение ÐºÐ»Ñ\8eÑ\87а Ð¾Ñ\82зÑ\8bваÑ\8eÑ\89им Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð±Ñ\83деÑ\82 Ð¾Ñ\82мениÑ\82Ñ\8c!\n"
 
 msgid ""
 "Are you sure you want to appoint this key as a designated revoker? (y/N) "
-msgstr "Вы уверены, что хотите назначить данный ключ отзывающим? (y/N) "
+msgstr "Вы уверены, что хотите назначить данный ключ отзывающим? (y/N)"
 
 msgid "Please remove selections from the secret keys.\n"
-msgstr "Снимите выделение с закрытых ключей.\n"
+msgstr "Снимите выделение с секретного ключа.\n"
 
 msgid "Please select at most one subkey.\n"
-msgstr "Ð\92Ñ\8bделиÑ\82е Ð½Ðµ Ð±Ð¾Ð»ее одного подключа.\n"
+msgstr "Ð\92Ñ\8bделиÑ\82е Ð½Ðµ Ð¼ÐµÐ½ее одного подключа.\n"
 
 msgid "Changing expiration time for a subkey.\n"
-msgstr "Смена Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f подключа.\n"
+msgstr "Смена Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и подключа.\n"
 
 msgid "Changing expiration time for the primary key.\n"
-msgstr "Смена срока действия главного ключа.\n"
+msgstr "Смена срока действия главного ключа\n"
 
 msgid "You can't change the expiration date of a v3 key\n"
-msgstr "Нельзя изменить срок действия ключа v3\n"
+msgstr "Нельзя изменять срок действия v3 ключа\n"
 
 msgid "No corresponding signature in secret ring\n"
-msgstr "Ð\9dеÑ\82 Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89ей Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð² Ñ\82аблиÑ\86е Ð·Ð°ÐºÑ\80Ñ\8bÑ\82Ñ\8bÑ\85 ÐºÐ»Ñ\8eÑ\87ей\n"
+msgstr "Ð\9dеÑ\82 Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89ей Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð² Ñ\81вÑ\8fзке Ñ\81екÑ\80еÑ\82нÑ\8bÑ\85\n"
 
 #, c-format
 msgid "signing subkey %s is already cross-certified\n"
-msgstr "подписывающий подключ %s уже перекрестно заверен\n"
+msgstr "подписываемый подключ %s уже имеет перекрестную сертификацию\n"
 
 #, c-format
 msgid "subkey %s does not sign and so does not need to be cross-certified\n"
-msgstr "подклÑ\8eÑ\87 %s Ð½Ðµ Ð´Ð»Ñ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей, Ð¾Ð½ Ð½Ðµ Ð½Ñ\83ждаеÑ\82Ñ\81Ñ\8f Ð² Ð¿ÐµÑ\80екÑ\80еÑ\81Ñ\82ном Ð·Ð°Ð²ÐµÑ\80ении\n"
+msgstr "подклÑ\8eÑ\87 %s Ð½Ðµ Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8bваÑ\8eÑ\89ий Ð¸ Ð½Ðµ Ð½Ñ\83ждаеÑ\82Ñ\81Ñ\8f Ð² Ð¿ÐµÑ\80екÑ\80еÑ\81Ñ\82ной Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и\n"
 
 msgid "Please select exactly one user ID.\n"
-msgstr "Ð\92Ñ\8bбеÑ\80иÑ\82е Ñ\80овно Ð¾Ð´Ð¸Ð½ ID Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f.\n"
+msgstr "Ð\92Ñ\8bбеÑ\80иÑ\82е Ñ\82олÑ\8cко Ð¾Ð´Ð¸Ð½ User ID.\n"
 
 #, c-format
 msgid "skipping v3 self-signature on user ID \"%s\"\n"
-msgstr "пропуск самоподписи v3 на ID пользователя \"%s\"\n"
+msgstr "пропуск v3 самоподписи на User ID \"%s\"\n"
 
 msgid "Enter your preferred keyserver URL: "
-msgstr "Ð\92ведиÑ\82е URL Ð¿Ñ\80едпоÑ\87Ñ\82иÑ\82елÑ\8cного сервера ключей: "
+msgstr "Ð\92ведиÑ\82е URL Ð¿Ñ\80едпоÑ\87Ñ\82аемого сервера ключей: "
 
 msgid "Are you sure you want to replace it? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð·Ð°Ð¼ÐµÐ½Ð¸Ñ\82Ñ\8c ÐµÐ³Ð¾? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð·Ð°Ð¼ÐµÐ½Ð¸Ñ\82Ñ\8c ÐµÐ³Ð¾? (y/N)"
 
 msgid "Are you sure you want to delete it? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c ÐµÐ³Ð¾? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ñ\83далиÑ\82Ñ\8c ÐµÐ³Ð¾? (y/N)"
 
 msgid "Enter the notation: "
-msgstr "Введите примечание: "
+msgstr "Введите примечание:"
 
 msgid "Proceed? (y/N) "
-msgstr "Ð\9fÑ\80одолжить? (y/N) "
+msgstr "Ð\9eбÑ\80абоÑ\82ать? (y/N) "
 
 #, c-format
 msgid "No user ID with index %d\n"
-msgstr "Нет ID пользователя с индексом %d\n"
+msgstr "Нет User ID с индексом %d\n"
 
 #, c-format
 msgid "No user ID with hash %s\n"
-msgstr "Нет ID пользователя с хэшем %s\n"
+msgstr "Нет User ID с хешем %s\n"
 
-# c-format
 #, c-format
 msgid "No subkey with index %d\n"
 msgstr "Нет подключа с индексом %d\n"
 
 #, c-format
 msgid "user ID: \"%s\"\n"
-msgstr "ID пользователя: \"%s\"\n"
+msgstr "User ID: \"%s\"\n"
 
 #, c-format
 msgid "signed by your key %s on %s%s%s\n"
-msgstr "подписано Вашим ключом %s %s%s%s\n"
+msgstr "подписано Вашим ключом %s от %s%s%s\n"
 
 msgid " (non-exportable)"
-msgstr " (неэкспортируемая)"
+msgstr " (не экспортируемая)"
 
 #, c-format
 msgid "This signature expired on %s.\n"
-msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð¸Ñ\81Ñ\82ек %s.\n"
+msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð·Ð°ÐºÐ¾Ð½Ñ\87илÑ\81Ñ\8f %s.\n"
 
 msgid "Are you sure you still want to revoke it? (y/N) "
 msgstr "Вы уверены, что хотите отозвать? (y/N) "
@@ -3335,18 +3199,18 @@ msgid "Create a revocation certificate for this signature? (y/N) "
 msgstr "Создать сертификат отзыва для данной подписи? (y/N) "
 
 msgid "Not signed by you.\n"
-msgstr "Вами не подписано.\n"
+msgstr ""
 
 #, c-format
 msgid "You have signed these user IDs on key %s:\n"
-msgstr "Вы подписали эти ID пользователей на ключе %s:\n"
+msgstr "Вы подписали данные User ID на ключе %s:\n"
 
 msgid " (non-revocable)"
-msgstr " (неотзываемая)"
+msgstr " (не отзываемая)"
 
 #, c-format
 msgid "revoked by your key %s on %s\n"
-msgstr "оÑ\82озвано Ð\92аÑ\88им ÐºÐ»Ñ\8eÑ\87ом %s %s\n"
+msgstr "оÑ\82зÑ\8bв Ð\92аÑ\88им ÐºÐ»Ñ\8eÑ\87ом %s Ð¾Ñ\82 %s\n"
 
 msgid "You are about to revoke these signatures:\n"
 msgstr "Вы отзываете следующие подписи:\n"
@@ -3355,34 +3219,34 @@ msgid "Really create the revocation certificates? (y/N) "
 msgstr "Действительно создать сертификат отзыва? (y/N) "
 
 msgid "no secret key\n"
-msgstr "нет закрытого ключа\n"
+msgstr "нет секретного ключа\n"
 
 #, c-format
 msgid "user ID \"%s\" is already revoked\n"
-msgstr "ID пользователя \"%s\" уже отозван\n"
+msgstr "User ID \"%s\" уже отозван\n"
 
 #, c-format
 msgid "WARNING: a user ID signature is dated %d seconds in the future\n"
-msgstr "ВНИМАНИЕ: подпись ID пользователя датирована %d секундами в будущем\n"
+msgstr "ВНИМАНИЕ: User ID подпись датирована %d секундами в будущем\n"
 
 #, c-format
 msgid "Key %s is already revoked.\n"
-msgstr "Ключ %s уже отозван.\n"
+msgstr "Ключ %s уже отозван\n"
 
 #, c-format
 msgid "Subkey %s is already revoked.\n"
-msgstr "Подключ %s уже отозван.\n"
+msgstr "Подключ %s уже отозван\n"
 
 #, c-format
 msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
-msgstr "Показ фотоидентификатора %s размера %ld для ключа %s (uid %d)\n"
+msgstr "Показ %s фото ID размера %ld для ключа %s (uid %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "предпочтение `%s' дублируется\n"
 
 msgid "too many cipher preferences\n"
-msgstr "слишком много шифровых предпочтений\n"
+msgstr "слишком много предпочтений для шифра\n"
 
 msgid "too many digest preferences\n"
 msgstr "слишком много предпочтений для хэш-функций\n"
@@ -3391,17 +3255,17 @@ msgid "too many compression preferences\n"
 msgstr "слишком много предпочтений для методов сжатия\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
-msgstr "недопустимый элемент `%s' в строке предпочтений\n"
+msgid "invalid item '%s' in preference string\n"
+msgstr "недопустимое вхождение `%s' в строке предпочтений\n"
 
 msgid "writing direct signature\n"
-msgstr "запись прямой подписи\n"
+msgstr ""
 
 msgid "writing self signature\n"
-msgstr "запись самоподписи\n"
+msgstr "сохраняем самоподпись\n"
 
 msgid "writing key binding signature\n"
-msgstr "запись объединяющей подписи\n"
+msgstr "сохраняем объединяющую подпись\n"
 
 #, c-format
 msgid "keysize invalid; using %u bits\n"
@@ -3409,13 +3273,13 @@ msgstr "неверный размер ключа; используется %u б
 
 #, c-format
 msgid "keysize rounded up to %u bits\n"
-msgstr "Ñ\80азмеÑ\80 ÐºÐ»Ñ\8eÑ\87а Ð¾ÐºÑ\80Ñ\83глен Ð²Ð²ÐµÑ\80Ñ\85 Ð´Ð¾ %u Ð±Ð¸Ñ\82\n"
+msgstr "Ñ\80азмеÑ\80 ÐºÐ»Ñ\8eÑ\87а Ð¿Ñ\80иведен Ðº %u Ð±Ð¸Ñ\82ам\n"
 
 msgid ""
 "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n"
 msgstr ""
-"ВНИМАНИЕ: некоторые реализации OpenPGP не смогут обработать ключи DSA с "
-"такой длиной хэш-функции\n"
+"ВНИМАНИЕ: некоторые реализации OpenPGP не смогут обработать DSA ключи с "
+"такой длиной хеш-функции\n"
 
 msgid "Sign"
 msgstr "Подписать"
@@ -3427,7 +3291,7 @@ msgid "Encrypt"
 msgstr "Зашифровать"
 
 msgid "Authenticate"
-msgstr "Ð\90Ñ\83Ñ\82енÑ\82иÑ\84иÑ\86иÑ\80оваÑ\82Ñ\8c"
+msgstr "Атентифицировать"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
 #. translation.  If this is not possible use single digits.  The
@@ -3440,14 +3304,14 @@ msgstr "Аутентифицировать"
 #. q = Finish
 #.
 msgid "SsEeAaQq"
-msgstr "11223300"
+msgstr ""
 
 #, c-format
 msgid "Possible actions for a %s key: "
-msgstr "Возможные действия для ключа %s: "
+msgstr "Возможные действия для ключа %s:"
 
 msgid "Current allowed actions: "
-msgstr "Допустимы действия: "
+msgstr "Допустимы действия:"
 
 #, c-format
 msgid "   (%c) Toggle the sign capability\n"
@@ -3466,15 +3330,15 @@ msgid "   (%c) Finished\n"
 msgstr "   (%c) Завершено\n"
 
 msgid "Please select what kind of key you want:\n"
-msgstr "Выберите тип ключа:\n"
+msgstr "Выберите требуемый тип ключа:\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA and RSA (default)\n"
-msgstr "   (%d) RSA и RSA (по умолчанию)\n"
+msgstr "   (%d) DSA и ElGamal (по умолчанию)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) DSA and Elgamal\n"
-msgstr "   (%d) DSA и Elgamal\n"
+msgstr "   (%d) DSA и ElGamal (по умолчанию)\n"
 
 #, c-format
 msgid "   (%d) DSA (sign only)\n"
@@ -3486,7 +3350,7 @@ msgstr "   (%d) RSA (только для подписи)\n"
 
 #, c-format
 msgid "   (%d) Elgamal (encrypt only)\n"
-msgstr "   (%d) Elgamal (только для шифрования)\n"
+msgstr "   (%d) ElGamal (только для шифрования)\n"
 
 #, c-format
 msgid "   (%d) RSA (encrypt only)\n"
@@ -3502,19 +3366,19 @@ msgstr "   (%d) RSA (с требуемыми возможностями)\n"
 
 #, c-format
 msgid "%s keys may be between %u and %u bits long.\n"
-msgstr "длина ÐºÐ»Ñ\8eÑ\87ей %s Ð¼Ð¾Ð¶ÐµÑ\82 Ð±Ñ\8bÑ\82Ñ\8c от %u до %u бит.\n"
+msgstr "клÑ\8eÑ\87и %s Ð¼Ð¾Ð³Ñ\83Ñ\82 Ð¸Ð¼ÐµÑ\82Ñ\8c Ð´Ð»Ð¸Ð½Ñ\83 от %u до %u бит.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the subkey? (%u) "
-msgstr "Ð\9aакой Ñ\80азмеÑ\80 Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87а Ð½ÐµÐ¾Ð±Ñ\85одим? (%u) "
+msgstr "Какой размер ключа необходим? (%u) "
 
 #, c-format
 msgid "What keysize do you want? (%u) "
-msgstr "Ð\9aакой Ñ\80азмеÑ\80 ÐºÐ»Ñ\8eÑ\87а Ð\92ам Ð½ÐµÐ¾Ð±Ñ\85одим? (%u) "
+msgstr "Какой размер ключа необходим? (%u) "
 
 #, c-format
 msgid "Requested keysize is %u bits\n"
-msgstr "Ð\97апÑ\80оÑ\88еннÑ\8bй Ñ\80азмеÑ\80 ÐºÐ»Ñ\8eÑ\87а - %u бит\n"
+msgstr "Ð\97апÑ\80аÑ\88иваемÑ\8bй Ñ\80азмеÑ\80 ÐºÐ»Ñ\8eÑ\87а %u бит\n"
 
 msgid ""
 "Please specify how long the key should be valid.\n"
@@ -3525,11 +3389,11 @@ msgid ""
 "      <n>y = key expires in n years\n"
 msgstr ""
 "Выберите срок действия ключа.\n"
-"         0 = Ð±ÐµÐ· Ð¾Ð³Ñ\80аниÑ\87ениÑ\8f Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f\n"
-"      <n>  = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f ÐºÐ»Ñ\8eÑ\87а - n дней\n"
-"      <n>w = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f ÐºÐ»Ñ\8eÑ\87а - n недель\n"
-"      <n>m = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f ÐºÐ»Ñ\8eÑ\87а - n месяцев\n"
-"      <n>y = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f ÐºÐ»Ñ\8eÑ\87а - n лет\n"
+"         0 = Ð±ÐµÐ· Ð¾Ð³Ñ\80аниÑ\87ениÑ\8f Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и\n"
+"      <n>  = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и n дней\n"
+"      <n>w = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и n недель\n"
+"      <n>m = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и n месяцев\n"
+"      <n>y = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и n лет\n"
 
 msgid ""
 "Please specify how long the signature should be valid.\n"
@@ -3540,42 +3404,42 @@ msgid ""
 "      <n>y = signature expires in n years\n"
 msgstr ""
 "Выберите срок действия подписи.\n"
-"         0 = Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c Ð±ÐµÐ· Ð¾Ð³Ñ\80аниÑ\87ениÑ\8f Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f\n"
-"      <n>  = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и - n дней\n"
-"      <n>w = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и - n недель\n"
-"      <n>m = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и - n месяцев\n"
-"      <n>y = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и - n лет\n"
+"         0 = Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c Ð±ÐµÐ· Ð¾Ð³Ñ\80аниÑ\87ениÑ\8f Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и\n"
+"      <n>  = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и n дней\n"
+"      <n>w = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и n недель\n"
+"      <n>m = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и n месяцев\n"
+"      <n>y = Ñ\81Ñ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и n лет\n"
 
 msgid "Key is valid for? (0) "
-msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f ÐºÐ»Ñ\8eÑ\87а? (0) "
+msgstr "Ð\9aлÑ\8eÑ\87 Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елен Ð´Ð¾? (0) "
 
 #, c-format
 msgid "Signature is valid for? (%s) "
-msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и? (%s) "
+msgstr "Ð\9fодпиÑ\81Ñ\8c Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cна Ð´Ð¾? (%s) "
 
 msgid "invalid value\n"
 msgstr "недопустимое значение\n"
 
 msgid "Key does not expire at all\n"
-msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f ÐºÐ»Ñ\8eÑ\87а Ð½Ðµ Ð¾Ð³Ñ\80аниÑ\87ен\n"
+msgstr "Ð\9aлÑ\8eÑ\87 Ð½Ðµ Ð¸Ð¼ÐµÐµÑ\82 Ð¾Ð³Ñ\80аниÑ\87ениÑ\8f Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и\n"
 
 msgid "Signature does not expire at all\n"
-msgstr "СÑ\80ок Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð½Ðµ Ð¾Ð³Ñ\80аниÑ\87ен\n"
+msgstr "Ð\9fодпиÑ\81Ñ\8c Ð½Ðµ Ð¸Ð¼ÐµÐµÑ\82 Ð¾Ð³Ñ\80аниÑ\87ениÑ\8f Ñ\81Ñ\80ока Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и\n"
 
 #, c-format
 msgid "Key expires at %s\n"
-msgstr "Ключ действителен до %s\n"
+msgstr "Ключ действителен до: %s\n"
 
 #, c-format
 msgid "Signature expires at %s\n"
-msgstr "Подпись действительна до %s\n"
+msgstr "Подпись действительна до: %s\n"
 
 msgid ""
 "Your system can't display dates beyond 2038.\n"
 "However, it will be correctly handled up to 2106.\n"
 msgstr ""
-"Ð\92аÑ\88а Ñ\81иÑ\81Ñ\82ема Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ\82 Ð¾Ñ\82обÑ\80ажаÑ\82Ñ\8c Ð´Ð°Ñ\82Ñ\8b Ð¿Ð¾Ñ\81ле 2038 Ð³Ð¾Ð´Ð°.\n"
-"Однако даты до 2106 года будут обрабатываются верно.\n"
+"Ð\92аÑ\88а Ñ\81иÑ\81Ñ\82ема Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ\82 ÐºÐ¾Ñ\80Ñ\80екÑ\82но Ð¾Ñ\82обÑ\80ажаÑ\82Ñ\8c Ð´Ð°Ñ\82Ñ\8b Ð¿Ð¾Ñ\81ле 2038.\n"
+"Однако, даты не превышающие 2106 будут обработаны корректно.\n"
 
 msgid "Is this correct? (y/N) "
 msgstr "Все верно? (y/N) "
@@ -3586,7 +3450,7 @@ msgid ""
 "\n"
 msgstr ""
 "\n"
-"GnuPG необходимо составить ID пользователя в качестве идентификатора ключа.\n"
+"GnuPG необходимо составить UserID в качестве идентификатора ключа.\n"
 "\n"
 
 #. TRANSLATORS: This string is in general not anymore used
@@ -3602,9 +3466,8 @@ msgid ""
 "\n"
 msgstr ""
 "\n"
-"Для идентификации Вашего ключа необходим ID пользователя. Программа создаст "
-"его\n"
-"из Вашего имени, комментария и адреса электронной почты в виде:\n"
+"Для идентификации Вашего ключа необходим User ID\n"
+"Программа создаст его из Вашего имени, комментария и адреса e-mail в виде:\n"
 "    \"Baba Yaga (pensioner) <yaga@deepforest.ru>\"\n"
 "\n"
 
@@ -3612,7 +3475,7 @@ msgid "Real name: "
 msgstr "Ваше настоящее имя: "
 
 msgid "Invalid character in name\n"
-msgstr "Ð\9dедопÑ\83Ñ\81Ñ\82имÑ\8bй Ñ\81имвол Ð² Ð¸мени\n"
+msgstr "Ð\9dедопÑ\83Ñ\81Ñ\82имÑ\8bй Ñ\81имвол Ð² Ð\98мени\n"
 
 msgid "Name may not start with a digit\n"
 msgstr "Имя не должно начинаться с цифры\n"
@@ -3621,10 +3484,10 @@ msgid "Name must be at least 5 characters long\n"
 msgstr "Имя не должно быть короче 5 символов\n"
 
 msgid "Email address: "
-msgstr "Адрес электронной почты: "
+msgstr "Email-адрес: "
 
 msgid "Not a valid email address\n"
-msgstr "Неправильный адрес электронной почты\n"
+msgstr "Неправильный e-mail адрес\n"
 
 msgid "Comment: "
 msgstr "Комментарий: "
@@ -3633,8 +3496,8 @@ msgid "Invalid character in comment\n"
 msgstr "Недопустимый символ в комментарии\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
-msgstr "Используется таблица символов: `%s'.\n"
+msgid "You are using the '%s' character set.\n"
+msgstr "Используемая таблица символов: `%s'.\n"
 
 #, c-format
 msgid ""
@@ -3642,16 +3505,15 @@ msgid ""
 "    \"%s\"\n"
 "\n"
 msgstr ""
-"Вы выбрали следующий ID пользователя:\n"
+"Вы выбрали следующий User ID:\n"
 "    \"%s\"\n"
 "\n"
 
 msgid "Please don't put the email address into the real name or the comment\n"
-msgstr ""
-"Не вставляйте адрес электронной почты в имя пользователя или комментарий\n"
+msgstr "Не вставляйте email-адрес в имя пользователя или комментарий\n"
 
 msgid "Such a user ID already exists on this key!\n"
-msgstr "Такой ID пользователя на этом ключе уже есть!\n"
+msgstr ""
 
 #. TRANSLATORS: These are the allowed answers in
 #. lower and uppercase.  Below you will find the matching
@@ -3665,13 +3527,14 @@ msgstr "Такой ID пользователя на этом ключе уже 
 #. q = Quit
 #.
 msgid "NnCcEeOoQq"
-msgstr "NnCcEeOoQq"
+msgstr ""
 
 msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
-msgstr "Сменить (N)Имя, (C)Комментарий, (E)Адрес или (Q)Выход? "
+msgstr "Сменить (N)Имя, (C)Комментарий, (E)email-адрес или (Q)Выход? "
 
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
-msgstr "Сменить (N)Имя, (C)Комментарий, (E)Адрес или (O)Принять/(Q)Выход? "
+msgstr ""
+"Сменить (N)Имя, (C)Комментарий, (E)email-адрес или (O)Принять/(Q)Выход? "
 
 msgid "Please correct the error first\n"
 msgstr "Сначала исправьте ошибку\n"
@@ -3680,14 +3543,14 @@ msgid ""
 "You need a Passphrase to protect your secret key.\n"
 "\n"
 msgstr ""
-"Для защиты закрытого ключа необходима фраза-пароль.\n"
+"Для защиты секретного ключа необходима фраза-пароль.\n"
 "\n"
 
+#, fuzzy
 msgid ""
 "Please enter a passphrase to protect the off-card backup of the new "
 "encryption key."
-msgstr ""
-"Введите фразу-пароль для защиты архивной копии нового ключа для шифрования."
+msgstr "Введите фразу-пароль для защиты импортированных в GnuPG объектов."
 
 #, c-format
 msgid "%s.\n"
@@ -3699,9 +3562,9 @@ msgid ""
 "using this program with the option \"--edit-key\".\n"
 "\n"
 msgstr ""
-"ХоÑ\82иÑ\82е Ð¾Ð±Ð¾Ð¹Ñ\82иÑ\81Ñ\8c Ð±ÐµÐ· Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f? Ð¡ÐºÐ¾Ñ\80ее Ð²Ñ\81его, Ñ\8dÑ\82о ПЛОХАЯ мысль!\n"
-"РабоÑ\82а Ð±Ñ\83деÑ\82 Ð¿Ñ\80одолжена. Ð\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ñ\81мениÑ\82Ñ\8c Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c в любое время,\n"
-"запÑ\83Ñ\81Ñ\82ив Ð´Ð°Ð½Ð½Ñ\83Ñ\8e Ð¿Ñ\80огÑ\80аммÑ\83 Ñ\81 Ð¿Ð°Ñ\80амеÑ\82Ñ\80ом \"--edit-key\".\n"
+"Ð\92ам Ð½Ðµ Ð½Ñ\83жна Ñ\84Ñ\80аза-паÑ\80олÑ\8c? Ð­Ñ\82о Ð\9eЧÐ\95Ð\9dЬ ПЛОХАЯ мысль!\n"
+"РабоÑ\82а Ð±Ñ\83деÑ\82 Ð¿Ñ\80одолжена. Ð¤Ñ\80азÑ\83-паÑ\80олÑ\8c Ð¼Ð¾Ð¶Ð½Ð¾ Ñ\81мениÑ\82 в любое время,\n"
+"запÑ\83Ñ\81Ñ\82ив Ð´Ð°Ð½Ð½Ñ\83Ñ\8e Ð¿Ñ\80огÑ\80аммÑ\83 Ñ\81 ÐºÐ»Ñ\8eÑ\87ом \"--edit-key\".\n"
 "\n"
 
 msgid ""
@@ -3710,26 +3573,26 @@ msgid ""
 "disks) during the prime generation; this gives the random number\n"
 "generator a better chance to gain enough entropy.\n"
 msgstr ""
-"Необходимо получить много случайных чисел. Желательно, чтобы Вы\n"
-"в процессе генерации выполняли какие-то другие действия (печать\n"
-"на ÐºÐ»Ð°Ð²Ð¸Ð°Ñ\82Ñ\83Ñ\80е, Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ñ\8f Ð¼Ñ\8bÑ\88и, Ð¾Ð±Ñ\80аÑ\89ениÑ\8f Ðº Ð´Ð¸Ñ\81кам); Ñ\8dÑ\82о Ð´Ð°Ñ\81Ñ\82 Ð³ÐµÐ½ÐµÑ\80аÑ\82оÑ\80Ñ\83\n"
-"случайных чисел больше возможностей получить достаточное количество "
-"Ñ\8dнÑ\82Ñ\80опии.\n"
+"Необходимо сгенерировать много случайных чисел. Желательно, что бы Вы\n"
+"выполняли некоторые другие активные действия (печать на клавиатуре, движения "
+"мÑ\8bÑ\88Ñ\8cÑ\8e,\n"
+"обращения к дискам) в процессе генерации; это даст генератору\n"
+"Ñ\81лÑ\83Ñ\87айнÑ\8bÑ\85 Ñ\87иÑ\81ел Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñ\81Ñ\82Ñ\8c Ð¿Ð¾Ð»Ñ\83Ñ\87иÑ\82Ñ\8c Ð»Ñ\83Ñ\87Ñ\88Ñ\83Ñ\8e Ñ\8dнÑ\82Ñ\80опиÑ\8e.\n"
 
 msgid "Key generation canceled.\n"
 msgstr "Создание ключа прервано.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "сохранение открытого ключа в `%s'\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "Ñ\81оÑ\85Ñ\80анение Ð·Ð°Ð³Ð¾Ñ\82овки Ð·Ð°ÐºÑ\80Ñ\8bÑ\82ого ключа в `%s'\n"
+msgid "writing secret key stub to '%s'\n"
+msgstr "Ñ\81оÑ\85Ñ\80анение Ð·Ð°Ð³Ð»Ñ\83Ñ\88ки Ñ\81екÑ\80еÑ\82ного ключа в `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "сохранение закрытого ключа в `%s'\n"
+msgid "writing secret key to '%s'\n"
+msgstr "сохранение секретного ключа в `%s'\n"
 
 #, c-format
 msgid "no writable public keyring found: %s\n"
@@ -3740,12 +3603,12 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "нет доступной для записи таблицы закрытых ключей: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "ошибка записи таблицы открытых ключей `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "ошибка записи таблицы закрытых ключей `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
+msgstr "ошибка записи таблицы секретных ключей `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
 msgstr "открытый и закрытый ключи созданы и подписаны.\n"
@@ -3754,7 +3617,7 @@ msgid ""
 "Note that this key cannot be used for encryption.  You may want to use\n"
 "the command \"--edit-key\" to generate a subkey for this purpose.\n"
 msgstr ""
-"Учтите, что данный ключ не может использоваться для шифрования. Вы можете\n"
+"Учтите, данный ключ не может использоваться для шифрования.  Можно\n"
 "воспользоваться командой \"--edit-key\" и создать подключ для этих целей.\n"
 
 #, c-format
@@ -3765,61 +3628,58 @@ msgstr "Сбой при создании ключа: %s\n"
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr ""
-"ключ создан на %lu секунду в будущем (петля во времени или проблемы с "
-"часами)\n"
+"ключ был создан на %lu секунд в будущем (time warp или проблемы с часами)\n"
 
 #, c-format
 msgid ""
 "key has been created %lu seconds in future (time warp or clock problem)\n"
 msgstr ""
-"ключ создан на %lu секунд в будущем (петля во времени или проблемы с "
-"часами)\n"
+"ключ был создан на %lu секунд в будущем (time warp или проблемы с часами)\n"
 
 msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
 msgstr "ЗАМЕЧАНИЕ: создание подключа для ключей v3 не совместимо с OpenPGP\n"
 
 msgid "Really create? (y/N) "
-msgstr "Действительно создать? (y/N) "
+msgstr "Действительно создать? (y/N)"
 
 #, c-format
 msgid "storing key onto card failed: %s\n"
 msgstr "сбой сохранения ключа на карту: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
-msgstr "не могу создать архивную копию, файл `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
+msgstr "не могу создать резервную копию, файл `%s': %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
-msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð°Ñ\80Ñ\85ивнаÑ\8f ÐºÐ¾Ð¿Ð¸Ñ\8f ÐºÐ»Ñ\8eÑ\87а Ð½Ð° ÐºÐ°Ñ\80Ñ\82е сохранена в `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
+msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð°Ñ\80Ñ\85ивнаÑ\8f ÐºÐ¾Ð¿Ð¸Ñ\8f ÐºÐ»Ñ\8eÑ\87а ÐºÐ°Ñ\80Ñ\82Ñ\8b сохранена в `%s'\n"
 
 msgid "never     "
 msgstr "никогда   "
 
 msgid "Critical signature policy: "
-msgstr "Ð\9aÑ\80иÑ\82иÑ\87еÑ\81кие Ð¿Ñ\80авила подписи: "
+msgstr "Ð\9aÑ\80иÑ\82иÑ\87нÑ\8bе Ð¿Ñ\80авила Ð´Ð»Ñ\8f подписи: "
 
 msgid "Signature policy: "
-msgstr "Правила подписи: "
+msgstr "Политика подписи: "
 
-# check it
 msgid "Critical preferred keyserver: "
-msgstr "Ð\9aÑ\80иÑ\82иÑ\87еÑ\81кий Ð¿Ñ\80едпоÑ\87Ñ\82иÑ\82елÑ\8cнÑ\8bй Ñ\81еÑ\80веÑ\80 ÐºÐ»Ñ\8eÑ\87ей: "
+msgstr "Ð\9aÑ\80иÑ\82иÑ\87но Ð¿Ñ\80едпоÑ\87иÑ\82аемÑ\8bе Ñ\81еÑ\80веÑ\80Ñ\8b ÐºÐ»Ñ\8eÑ\87ей:"
 
 msgid "Critical signature notation: "
-msgstr "Ð\9aÑ\80иÑ\82иÑ\87еÑ\81кое примечание к подписи: "
+msgstr "Ð\9aÑ\80иÑ\82иÑ\87ное примечание к подписи: "
 
 msgid "Signature notation: "
-msgstr "Примечание к подписи"
+msgstr "Примечание к подписи"
 
 msgid "Keyring"
 msgstr "Таблица ключей"
 
 msgid "Primary key fingerprint:"
-msgstr "Отпечаток главного ключа:"
+msgstr " Отпечаток главного ключа:"
 
 msgid "     Subkey fingerprint:"
-msgstr "      Отпечаток подключа:"
+msgstr "         Отпечаток подключа:"
 
 #. TRANSLATORS: this should fit into 24 bytes to that the
 #. * fingerprint data is properly aligned with the user ID
@@ -3827,60 +3687,56 @@ msgid " Primary key fingerprint:"
 msgstr " Отпечаток главного ключа:"
 
 msgid "      Subkey fingerprint:"
-msgstr "       Отпечаток подключа:"
+msgstr "         Отпечаток подключа:"
 
 msgid "      Key fingerprint ="
-msgstr "      Отпечаток ключа ="
-
-#, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "ВНИМАНИЕ: отпечаток PGP-2 не безопасен\n"
+msgstr "Отпечаток ключа ="
 
 msgid "      Card serial no. ="
-msgstr " серийный номер карты ="
+msgstr ""
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
-msgstr "сбой при переименовании `%s' в `%s': %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
+msgstr "при переименовании `%s' в `%s' произошел сбой: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
 msgstr "ВНИМАНИЕ: Существуют 2 файла с конфиденциальной информацией.\n"
 
 #, c-format
 msgid "%s is the unchanged one\n"
-msgstr "%s - без изменений\n"
+msgstr "%s осталось без изменений\n"
 
 #, c-format
 msgid "%s is the new one\n"
-msgstr "%s - новый\n"
+msgstr "%s новых\n"
 
 msgid "Please fix this possible security flaw\n"
-msgstr "Ð\98Ñ\81пÑ\80авÑ\8cÑ\82е Ñ\8dÑ\82Ñ\83 Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ\83Ñ\8e Ð¿Ñ\80оÑ\80еÑ\85Ñ\83 Ð±ÐµÐ·Ð¾Ð¿Ð°Ñ\81ноÑ\81Ñ\82и\n"
+msgstr "Исправьте эту прореху безопасности\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
-msgstr "бÑ\83Ñ\84еÑ\80иÑ\80ование Ñ\82аблиÑ\86Ñ\8b ключей `%s'\n"
+msgid "caching keyring '%s'\n"
+msgstr "кеÑ\88иÑ\80Ñ\83Ñ\8e Ñ\81вÑ\8fзки ключей `%s'\n"
 
 #, c-format
 msgid "%lu keys cached so far (%lu signatures)\n"
-msgstr "пока в буфер помещено %lu ключей (%lu подписей)\n"
+msgstr "%lu ключей закешировано за это время (%lu подписей)\n"
 
 #, c-format
 msgid "%lu keys cached (%lu signatures)\n"
-msgstr "%lu ÐºÐ»Ñ\8eÑ\87ей Ð¿Ð¾Ð¼ÐµÑ\89ено Ð² Ð±Ñ\83Ñ\84еÑ\80 (%lu подписей)\n"
+msgstr "%lu ÐºÐ»Ñ\8eÑ\87ей Ð·Ð°ÐºÐµÑ\88иÑ\80ованно (%lu подписей)\n"
 
 #, c-format
 msgid "%s: keyring created\n"
 msgstr "%s: таблица ключей создана\n"
 
 msgid "include revoked keys in search results"
-msgstr "вклÑ\8eÑ\87иÑ\82Ñ\8c Ð² Ñ\80езÑ\83лÑ\8cÑ\82аÑ\82Ñ\8b Ð¿Ð¾Ð¸Ñ\81ка Ð¾Ñ\82озваннÑ\8bе ÐºÐ»Ñ\8eÑ\87и"
+msgstr "вклÑ\8eÑ\87аÑ\82Ñ\8c Ð¾Ñ\82озваннÑ\8bе ÐºÐ»Ñ\8eÑ\87и Ð² Ñ\80езÑ\83Ñ\82аÑ\82аÑ\85 Ð¿Ð¾Ð¸Ñ\81ка"
 
 msgid "include subkeys when searching by key ID"
-msgstr "иÑ\81каÑ\82Ñ\8c Ð¿Ð¾ ID ÐºÐ»Ñ\8eÑ\87а, Ð²ÐºÐ»Ñ\8eÑ\87аÑ\8f Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87и"
+msgstr "вклÑ\8eÑ\87аÑ\8f Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87и Ð¿Ñ\80и Ð¿Ð¾Ð¸Ñ\81ке Ð¿Ð¾ Key ID"
 
 msgid "use temporary files to pass data to keyserver helpers"
-msgstr "передавать данные в сервер с помощью временных файлов"
+msgstr ""
 
 msgid "do not delete temporary files after using them"
 msgstr "не удалять временные файлы после использования"
@@ -3889,26 +3745,25 @@ msgid "automatically retrieve keys when verifying signatures"
 msgstr "автоматически получать ключи при проверке подписей"
 
 msgid "honor the preferred keyserver URL set on the key"
-msgstr "учитывать набор URL предпочтительных серверов ключей для этого ключа"
+msgstr "введите URL предпочтаемого сервера ключей: "
 
 msgid "honor the PKA record set on a key when retrieving keys"
-msgstr "учитывать набор записей PKA при получении ключей"
+msgstr ""
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
-"Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¿Ð°Ñ\80амеÑ\82Ñ\80 Ñ\81еÑ\80веÑ\80а ÐºÐ»Ñ\8eÑ\87ей `%s' Ð½Ð° Ð´Ð°Ð½Ð½Ð¾Ð¹ Ð¿Ð»Ð°Ñ\82Ñ\84оÑ\80ме Ð½Ðµ Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f\n"
+"Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¿Ð°Ñ\80амеÑ\82Ñ\80 Ñ\81еÑ\80веÑ\80а ÐºÐ»Ñ\8eÑ\87ей `%s' Ð½Ðµ Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f Ð½Ð° Ð´Ð°Ð½Ð½Ð¾Ð¹ Ð¿Ð»Ð°Ñ\82Ñ\84оÑ\80ме\n"
 
 msgid "disabled"
-msgstr "отключен"
+msgstr "disable"
 
 msgid "Enter number(s), N)ext, or Q)uit > "
-msgstr "Ð\92ведиÑ\82е Ñ\87иÑ\81ла, N) Ð¡Ð»ÐµÐ´Ñ\83Ñ\8eÑ\89ее или Q) Выход> "
+msgstr "Ð\92ведиÑ\82е Ñ\87иÑ\81ло(а), N) Ð¡Ð»ÐµÐ´Ñ\83Ñ\8eÑ\89ий или Q) Выход> "
 
-# test it
 #, c-format
 msgid "invalid keyserver protocol (us %d!=handler %d)\n"
-msgstr "недопустимый протокол сервера ключей (ожидается %d, получено %d)\n"
+msgstr "invalid keyserver protocol (us %d!=handler %d)\n"
 
 #, c-format
 msgid "key \"%s\" not found on keyserver\n"
@@ -3919,7 +3774,7 @@ msgstr "ключ не найден на сервере ключей\n"
 
 #, c-format
 msgid "requesting key %s from %s server %s\n"
-msgstr "запрашиваю ключ %s с сервера %s %s\n"
+msgstr "запрашиваю ключ %s с %s сервера %s\n"
 
 #, c-format
 msgid "requesting key %s from %s\n"
@@ -3927,15 +3782,15 @@ msgstr "получение ключа %s с %s\n"
 
 #, c-format
 msgid "searching for names from %s server %s\n"
-msgstr "поиÑ\81к Ð¸Ð¼ÐµÐ½ Ð½Ð° Ñ\81еÑ\80веÑ\80е %s %s\n"
+msgstr "поиÑ\81к Ð¿Ð¾ Ð¸Ð¼ÐµÐ½Ð°Ð¼ %s Ð½Ð° Ñ\81еÑ\80веÑ\80е %s\n"
 
 #, c-format
 msgid "searching for names from %s\n"
-msgstr "поиÑ\81к Ð¸Ð¼ÐµÐ½ на %s\n"
+msgstr "поиÑ\81к Ð¿Ð¾ Ð¸Ð¼ÐµÐ½Ð°Ð¼ на %s\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
-msgstr "оÑ\82пÑ\80авка ÐºÐ»Ñ\8eÑ\87а %s Ð½Ð° Ñ\81еÑ\80веÑ\80 %s %s\n"
+msgstr "оÑ\82пÑ\80авлÑ\8fÑ\8e ÐºÐ»Ñ\8eÑ\87 %s Ð½Ð° %s Ñ\81еÑ\80веÑ\80 %s\n"
 
 #, c-format
 msgid "sending key %s to %s\n"
@@ -3943,15 +3798,14 @@ msgstr "отправка ключа %s на %s\n"
 
 #, c-format
 msgid "searching for \"%s\" from %s server %s\n"
-msgstr "поиск \"%s\" на сервере %s %s\n"
+msgstr "поиск \"%s\" на %s сервере %s\n"
 
 #, c-format
 msgid "searching for \"%s\" from %s\n"
 msgstr "поиск \"%s\" на %s\n"
 
-# test it
 msgid "no keyserver action!\n"
-msgstr "неизвестное действие сервера!\n"
+msgstr ""
 
 #, c-format
 msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
@@ -3960,22 +3814,18 @@ msgstr "ВНИМАНИЕ: обработчик сервера ключей от
 msgid "keyserver did not send VERSION\n"
 msgstr "сервер ключей не прислал VERSION\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "ошибка связи с сервером ключей: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "не заданы серверы ключей (используйте --keyserver)\n"
 
 msgid "external keyserver calls are not supported in this build\n"
-msgstr "данная сборка не поддерживает внешние вызовы для сервера ключей\n"
+msgstr "данная сборка не поддерживает внешние вызовы для сервера ключей.\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr "нет обработчика для схемы сервера ключей `%s'\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr "действие `%s' не поддерживается схемой сервера ключей `%s'\n"
 
 #, c-format
@@ -3986,7 +3836,11 @@ msgid "keyserver timed out\n"
 msgstr "превышено время ожидания сервера ключей\n"
 
 msgid "keyserver internal error\n"
-msgstr "внутренняя ошибка сервера ключей\n"
+msgstr "ошибка сервера ключей\n"
+
+#, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "ошибка связи с сервером ключей: %s\n"
 
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
@@ -4006,11 +3860,11 @@ msgstr "обновление %d ключей из %s\n"
 
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð¿Ð¾Ð»Ñ\83Ñ\87иÑ\82Ñ\8c URI %s: %s\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð·Ð°Ð³Ñ\80Ñ\83зиÑ\82Ñ\8c Ñ\81Ñ\81Ñ\8bлкÑ\83 %s: %s\n"
 
 #, c-format
 msgid "WARNING: unable to parse URI %s\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð¸Ð½Ñ\82еÑ\80пÑ\80еÑ\82иÑ\80оваÑ\82Ñ\8c URI %s\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð¿Ñ\80оанализиÑ\80оваÑ\82Ñ\8c Ñ\81Ñ\81Ñ\8bлкÑ\83 %s\n"
 
 #, c-format
 msgid "weird size for an encrypted session key (%d)\n"
@@ -4018,22 +3872,22 @@ msgstr "странный размер зашифрованного сеансо
 
 #, c-format
 msgid "%s encrypted session key\n"
-msgstr "сеансовый ключ зашифрован по %s\n"
+msgstr "сеансовый ключ зашифрован %s\n"
 
 #, c-format
 msgid "passphrase generated with unknown digest algorithm %d\n"
-msgstr "фраза-пароль создана с незнакомой хэш-функцией %d\n"
+msgstr "фраза-пароль создана с незнакомой хеш-фкнкцией %d\n"
 
 #, c-format
 msgid "public key is %s\n"
 msgstr "открытый ключ %s\n"
 
 msgid "public key encrypted data: good DEK\n"
-msgstr "данные зашифрованы открытым ключом: хороший DEK\n"
+msgstr "данные зашифрованы открытым ключом: правильный DEK\n"
 
 #, c-format
 msgid "encrypted with %u-bit %s key, ID %s, created %s\n"
-msgstr "зашифровано %u-битным ключом %s с ID %s, созданным %s\n"
+msgstr "зашифровано %u-битным ключом %s, с ID %s, созданным %s\n"
 
 #, c-format
 msgid "      \"%s\"\n"
@@ -4045,22 +3899,22 @@ msgstr "зашифровано ключом %s с ID %s\n"
 
 #, c-format
 msgid "public key decryption failed: %s\n"
-msgstr "Ñ\81бой Ñ\80аÑ\81Ñ\88иÑ\84Ñ\80овки с открытым ключом: %s\n"
+msgstr "Ñ\81бой Ñ\80аÑ\81Ñ\88иÑ\84Ñ\80ованиÑ\8f с открытым ключом: %s\n"
 
 #, c-format
 msgid "encrypted with %lu passphrases\n"
-msgstr "зашифровано %lu фразами-паролями\n"
+msgstr "зашифровано с %lu фразами-паролями\n"
 
 msgid "encrypted with 1 passphrase\n"
-msgstr "зашифровано одной фразой-паролем\n"
+msgstr "зашифровано с 1 фразой-паролем\n"
 
 #, c-format
 msgid "assuming %s encrypted data\n"
-msgstr "пÑ\80едполагаÑ\8eÑ\82Ñ\81Ñ\8f Ð´Ð°Ð½Ð½Ñ\8bе, Ð·Ð°Ñ\88иÑ\84Ñ\80ованнÑ\8bе Ð¿Ð¾ %s\n"
+msgstr "пÑ\80инÑ\8fÑ\82ие %s Ð·Ð°Ñ\88иÑ\84Ñ\80ованнÑ\8bÑ\85 Ð´Ð°Ð½Ð½Ñ\8bÑ\85\n"
 
 #, c-format
 msgid "IDEA cipher unavailable, optimistically attempting to use %s instead\n"
-msgstr "шифр IDEA недоступен, попробую вместо него %s\n"
+msgstr "шифр IDEA недоступен, попробуйте использовать взамен %s\n"
 
 msgid "decryption okay\n"
 msgstr "расшифровано\n"
@@ -4073,24 +3927,24 @@ msgstr "ВНИМАНИЕ: зашифрованное сообщение было
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
-msgstr "в буфере сброшена фраза-пароль с индексом %s\n"
+msgstr ""
 
 #, c-format
 msgid "decryption failed: %s\n"
-msgstr "Ñ\81бой Ñ\80аÑ\81Ñ\88иÑ\84Ñ\80овки: %s\n"
+msgstr "Ñ\81бой Ñ\80аÑ\81Ñ\88иÑ\84Ñ\80ованиÑ\8f: %s\n"
 
 msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
-msgstr "ЗАМЕЧАНИЕ: отправитель запросил \"только между нами\"\n"
+msgstr "ЗАМЕЧАНИЕ: отправитель требует \"только для просмотра Вами\"\n"
 
 #, c-format
 msgid "original file name='%.*s'\n"
-msgstr "пеÑ\80вонаÑ\87альное имя файла='%.*s'\n"
+msgstr "оÑ\80игинальное имя файла='%.*s'\n"
 
 msgid "WARNING: multiple plaintexts seen\n"
-msgstr "ВНИМАНИЕ: наблюдается несколько текстов\n"
+msgstr ""
 
 msgid "standalone revocation - use \"gpg --import\" to apply\n"
-msgstr "отдельный сертификат отзыва: задействуется командой \"gpg --import\"\n"
+msgstr "самостоятельный сертификат отзыва: \"gpg --import\" для применения\n"
 
 msgid "no signature found\n"
 msgstr "подпись не найдена\n"
@@ -4099,7 +3953,7 @@ msgid "signature verification suppressed\n"
 msgstr "проверка подписи подавлена\n"
 
 msgid "can't handle this ambiguous signature data\n"
-msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð¾Ð±Ñ\80абоÑ\82аÑ\82Ñ\8c Ñ\8dÑ\82и Ð½ÐµÐ¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñ\87нÑ\8bе Ð´Ð°нные подписи\n"
+msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð¾Ð±Ñ\80абоÑ\82аÑ\82Ñ\8c Ñ\8dÑ\82и Ð¼Ð½Ð¾Ð¶ÐµÑ\81Ñ\82венные подписи\n"
 
 #, c-format
 msgid "Signature made %s\n"
@@ -4114,11 +3968,11 @@ msgid "Signature made %s using %s key ID %s\n"
 msgstr "Подпись создана %s ключом %s с ID %s\n"
 
 msgid "Key available at: "
-msgstr "Ключ доступен на: "
+msgstr "Ключ доступен на:"
 
 #, c-format
 msgid "BAD signature from \"%s\""
-msgstr "ПЛОХАЯ подпись от \"%s\""
+msgstr "ПЛОХАЯ подпись от  \"%s\""
 
 #, c-format
 msgid "Expired signature from \"%s\""
@@ -4133,7 +3987,7 @@ msgstr "[сомнительно]"
 
 #, c-format
 msgid "                aka \"%s\""
-msgstr "                или \"%s\""
+msgstr "                aka \"%s\""
 
 #, c-format
 msgid "Signature expired %s\n"
@@ -4145,20 +3999,16 @@ msgstr "Подпись действительна до %s\n"
 
 #, c-format
 msgid "%s signature, digest algorithm %s\n"
-msgstr "подпись в %s форме, хэш-функция %s\n"
+msgstr "%s подпись, хэш-функция %s\n"
 
 msgid "binary"
-msgstr "двоичной"
+msgstr "двоичный"
 
 msgid "textmode"
-msgstr "текстовой"
+msgstr "текстовый"
 
 msgid "unknown"
-msgstr "неизвестной"
-
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr "ВНИМАНИЕ: не отделенная подпись; файл `%s' НЕ был проверен!\n"
+msgstr "неизвестно"
 
 #, c-format
 msgid "Can't check signature: %s\n"
@@ -4170,119 +4020,107 @@ msgstr "не отделенная подпись\n"
 msgid ""
 "WARNING: multiple signatures detected.  Only the first will be checked.\n"
 msgstr ""
-"Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¾Ð±Ð½Ð°Ñ\80Ñ\83жено Ð½ÐµÑ\81колÑ\8cко Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей. Ð\9fÑ\80овеÑ\80ена Ð±Ñ\83деÑ\82 Ñ\82олÑ\8cко Ð¿ÐµÑ\80ваÑ\8f.\n"
+"Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¾Ð±Ð½Ð°Ñ\80Ñ\83жено Ð¼Ð½Ð¾Ð¶ÐµÑ\81Ñ\82во Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей.  Ð¢Ð¾Ð»Ñ\8cко Ð¿ÐµÑ\80ваÑ\8f Ð±Ñ\83деÑ\82 Ð¿Ñ\80овеÑ\80ена.\n"
 
 #, c-format
 msgid "standalone signature of class 0x%02x\n"
-msgstr "отдельная подпись класса 0x%02x\n"
+msgstr "самостоятельная подпись класса 0x%02x\n"
 
 msgid "old style (PGP 2.x) signature\n"
-msgstr "подпись старого типа (PGP 2.x)\n"
+msgstr "старый (PGP 2.x) стиль подписи\n"
 
 msgid "invalid root packet detected in proc_tree()\n"
-msgstr "обнаружен недопустимый корневой пакет в proc_tree()\n"
+msgstr ""
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
-msgstr "сбой fstat `%s' в функции %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
+msgstr ""
 
 #, c-format
 msgid "fstat(%d) failed in %s: %s\n"
-msgstr "сбой fstat(%d) в функции %s: %s\n"
+msgstr ""
 
 #, c-format
 msgid "WARNING: using experimental public key algorithm %s\n"
 msgstr ""
-"ВНИМАНИЕ: используется экспериментальный алгоритм шифрования с открытым "
-"ключом %s\n"
+"ВНИМАНИЕ: используется экспериментальный алгоритм %s шифрования с открытым "
+"ключом\n"
 
 msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n"
-msgstr "ВНИМАНИЕ: Ключи для подписи+шифрования Elgamal не рекомендуются\n"
+msgstr ""
+"ВНИМАНИЕ: Ключи Elgamal для шифрования+сжатие более не поддерживаются\n"
 
 #, c-format
 msgid "WARNING: using experimental cipher algorithm %s\n"
 msgstr ""
-"ВНИМАНИЕ: используется экспериментальный алгоритм симметричного шифрования "
-"%s\n"
+"ВНИМАНИЕ: используется экспериментальный алгоритм симметричного шифрования %"
+"s\n"
 
 #, c-format
 msgid "WARNING: using experimental digest algorithm %s\n"
-msgstr "ВНИМАНИЕ: используется экспериментальная хэш-функция %s\n"
+msgstr "ВНИМАНИЕ: используется экспериментальная хеш-функция %s\n"
 
 #, c-format
 msgid "WARNING: digest algorithm %s is deprecated\n"
-msgstr "ВНИМАНИЕ: хэш-функция %s не рекомендуется\n"
-
-#, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "Замечание: подписи с хэш-функцией %s игнорируются\n"
+msgstr "ВНИМАНИЕ: хеш-функция %s считается устаревшей\n"
 
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "модуль поддержки шифра IDEA не обнаружен\n"
 
 #, c-format
 msgid "please see %s for more information\n"
-msgstr "за Ð¿Ð¾Ð´Ñ\80обноÑ\81Ñ\82Ñ\8fми Ð¾Ð±Ñ\80аÑ\89айÑ\82еÑ\81Ñ\8c Ðº %s\n"
+msgstr "длÑ\8f Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ\82елÑ\8cной Ð¸Ð½Ñ\84оÑ\80маÑ\86ии Ñ\81м. %s\n"
 
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
-msgstr "%s:%d: Ð¿Ð°Ñ\80амеÑ\82Ñ\80 \"%s\" Ð½Ðµ Ñ\80екомендÑ\83еÑ\82Ñ\81Ñ\8f\n"
+msgstr "%s:%d: Ð½Ðµ Ñ\80екомендÑ\83емаÑ\8f Ð¾Ð¿Ñ\86иÑ\8f \"%s\"\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated option\n"
-msgstr "ВНИМАНИЕ: параметр \"%s\" не рекомендуется\n"
+msgstr "ВНИМАНИЕ: \"%s\" не рекомендуемая опция\n"
 
 #, c-format
 msgid "please use \"%s%s\" instead\n"
-msgstr "используйте вместо этого \"%s%s\"\n"
+msgstr "используйте \"%s%s\" взамен\n"
 
 #, c-format
 msgid "WARNING: \"%s\" is a deprecated command - do not use it\n"
 msgstr ""
-"ВНИМАНИЕ: команда \"%s\" не рекомендуется к употреблению - не применяйте ее\n"
+"ВНИМАНИЕ: команда \"%s\" является устаревшей - не следует применять ее\n"
 
 #, c-format
 msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgstr "%s:%u: устаревший параметр \"%s\" - игнорируется\n"
+msgstr ""
 
 #, c-format
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgstr "ВНИМАНИЕ: параметр \"%s\" устарел - он игнорируется\n"
-
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: \"%s%s\" в этом файле устарело - оно действует только в %s\n"
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "ВНИМАНИЕ: параметр \"%s%s\" устарел - он действует только для %s\n"
+msgstr "ВНИМАНИЕ: \"%s\" устаревший параметр - он не задействован\n"
 
 msgid "Uncompressed"
-msgstr "Ð\91ез сжатия"
+msgstr "без сжатия"
 
 #. TRANSLATORS: See doc/TRANSLATE about this string.
 msgid "uncompressed|none"
-msgstr "без сжатия|без|none"
+msgstr ""
 
 #, c-format
 msgid "this message may not be usable by %s\n"
-msgstr "данное сообщение может быть непригодно для %s\n"
+msgstr "данное сообщение может быть не пригодно для %s\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
-msgstr "неоднознаÑ\87ный параметр `%s'\n"
+msgid "ambiguous option '%s'\n"
+msgstr "двÑ\83Ñ\81мÑ\8bÑ\81ленный параметр `%s'\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "неизвестный параметр `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Файл `%s' существует. "
 
 msgid "Overwrite? (y/N) "
-msgstr "Ð\97апиÑ\81аÑ\82Ñ\8c Ð¿Ð¾Ð²ÐµÑ\80Ñ\85? (y/N) "
+msgstr "Ð\9fеÑ\80езапиÑ\81аÑ\82Ñ\8c (y/N)? "
 
 #, c-format
 msgid "%s: unknown suffix\n"
@@ -4292,19 +4130,19 @@ msgid "Enter new filename"
 msgstr "Введите новое имя файла"
 
 msgid "writing to stdout\n"
-msgstr "вывод в stdout\n"
+msgstr "Ð\92ывод в stdout\n"
 
 #, c-format
 msgid "assuming signed data in '%s'\n"
-msgstr "пÑ\80едполагаеÑ\82Ñ\81Ñ\8f, Ñ\87Ñ\82о Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аннÑ\8bе Ð´Ð°Ð½Ð½Ñ\8bе Ð½Ð°Ñ\85одÑ\8fÑ\82Ñ\81Ñ\8f в `%s'\n"
+msgstr "пÑ\80инÑ\8fÑ\82ие Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аннÑ\8bÑ\85 Ð´Ð°Ð½Ð½Ñ\8bÑ\85 в `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "создан новый файл настроек `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ð² `%s' Ð¿Ñ\80и Ñ\8dÑ\82ом Ð·Ð°Ð¿Ñ\83Ñ\81ке ÐµÑ\89е Ð½Ðµ Ð´ÐµÐ¹Ñ\81Ñ\82вÑ\83Ñ\8eÑ\82\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ð² `%s' ÐµÑ\89е Ð½Ðµ Ð°ÐºÑ\82ивнÑ\8b Ð¿Ñ\80и Ñ\8dÑ\82ом Ð·Ð°Ð¿Ñ\83Ñ\81ке\n"
 
 #, c-format
 msgid "can't handle public key algorithm %d\n"
@@ -4312,20 +4150,16 @@ msgstr "не могу использовать алгоритм с открыт
 
 msgid "WARNING: potentially insecure symmetrically encrypted session key\n"
 msgstr ""
-"ВНИМАНИЕ: потенциально небезопасный сеансовый ключ,\n"
-"          зашифрованный симметричным шифром\n"
+"ВНИМАНИЕ: потенциально небезопасный сеансовый ключ, зашифрованный "
+"симметричным шифром\n"
 
 #, c-format
 msgid "subpacket of type %d has critical bit set\n"
-msgstr "в подпакете типа %d установлен критический бит\n"
-
-#, c-format
-msgid "problem with the agent: %s\n"
-msgstr "проблема с агентом: %s\n"
+msgstr "подпакет типа %d имеет выставленный критический бит\n"
 
 #, c-format
 msgid " (main key ID %s)"
-msgstr " (ID главного ключа %s)"
+msgstr " (главный ключ ID %s)"
 
 #, c-format
 msgid ""
@@ -4335,7 +4169,7 @@ msgid ""
 "%u-bit %s key, ID %s,\n"
 "created %s%s.\n"
 msgstr ""
-"Необходима фраза-пароль для доступа к закрытому ключу OpenPGP сертификата:\n"
+"Необходима фраза-пароль для доступа к секретному ключу OpenPGP сертификата:\n"
 "\"%.*s\"\n"
 "%u-бит %s ключ, ID %s,\n"
 "создан %s%s.\n"
@@ -4347,15 +4181,19 @@ msgid "cancelled by user\n"
 msgstr "прервано пользователем\n"
 
 #, c-format
+msgid "problem with the agent: %s\n"
+msgstr "проблема с агентом: %s\n"
+
+#, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
 msgstr ""
-"Необходима фраза-пароль для доступа к закрытому ключу пользователя: \"%s\"\n"
+"Необходима фраза-пароль для доступа к секретному ключу пользователя: \"%s\"\n"
 
 #, c-format
 msgid "%u-bit %s key, ID %s, created %s"
-msgstr "%u-битный ключ %s, ID %s, создан %s"
+msgstr "%u-бит %s ключ, ID %s, создан %s"
 
 #, c-format
 msgid "         (subkey on main key ID %s)"
@@ -4369,81 +4207,71 @@ msgid ""
 "Keeping the image close to 240x288 is a good size to use.\n"
 msgstr ""
 "\n"
-"Ð\92Ñ\8bбеÑ\80иÑ\82е Ð¸Ð·Ð¾Ð±Ñ\80ажение Ð´Ð»Ñ\8f Ð\92аÑ\88его Ñ\84оÑ\82оиденÑ\82иÑ\84икаÑ\82оÑ\80а. Ð­Ñ\82о Ð´Ð¾Ð»Ð¶ÐµÐ½ Ð±Ñ\8bÑ\82Ñ\8c Ñ\84айл "
-"JPEG.\n"
-"Помните, что изображение будет храниться в Вашем открытом ключе и увеличит\n"
-"его Ñ\80азмеÑ\80! Ð ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ñ\83еÑ\82Ñ\81Ñ\8f размер около 240x288.\n"
+"Ð\92Ñ\8bбеÑ\80иÑ\82е Ð¸Ð·Ð¾Ð±Ñ\80ажение Ð´Ð»Ñ\8f Ð¸Ñ\81полÑ\8cзованиÑ\8f Ð² ÐºÐ°Ñ\87еÑ\81Ñ\82ве Ð\92аÑ\88его Ð¤Ð¾Ñ\82о ID.\n"
+"Изображение должно быть в формате JPEG. Помните, что оно будет храниться\n"
+"с Вашим открытым ключом и увеличит его размер, т.е. не следует брать очень\n"
+"болÑ\8cÑ\88ое Ð¸Ð·Ð¾Ð±Ñ\80ажение. Ð ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ñ\83емÑ\8bй размер около 240x288.\n"
 
 msgid "Enter JPEG filename for photo ID: "
-msgstr "Введите имя файла JPEG для фотоидентификатора: "
+msgstr "Введите имя JPEG файла для Фото ID: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
-msgstr "не Ð¼Ð¾Ð³Ñ\83 Ð¾Ñ\82кÑ\80Ñ\8bÑ\82Ñ\8c Ñ\84айл JPEG `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
+msgstr "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð¾Ñ\82кÑ\80Ñ\8bÑ\82Ñ\8c JPEG Ñ\84айл `%s': %s\n"
 
 #, c-format
 msgid "This JPEG is really large (%d bytes) !\n"
 msgstr "Этот JPEG очень велик (%d байт)!\n"
 
 msgid "Are you sure you want to use it? (y/N) "
-msgstr "Ð\92Ñ\8b Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c ÐµÐ³Ð¾? (y/N) "
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cно Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c ÐµÐ³Ð¾? (y/N)"
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
-msgstr "`%s' - не файл JPEG\n"
+msgid "'%s' is not a JPEG file\n"
+msgstr "`%s' - не JPEG файл\n"
 
 msgid "Is this photo correct (y/N/q)? "
-msgstr "ЭÑ\82о Ð¿Ñ\80авилÑ\8cнаÑ\8f Ñ\84оÑ\82огÑ\80аÑ\84иÑ\8f? (y/N/q) "
+msgstr "Ð\94анное Ñ\84оÑ\82о Ð¿Ñ\80авилÑ\8cное (y/N/q)? "
 
 msgid "unable to display photo ID!\n"
-msgstr "не могу отобразить фотоидентификатор!\n"
+msgstr "не могу отобразить Фото ID!\n"
 
 msgid "No reason specified"
-msgstr "Ð\9fÑ\80иÑ\87ина Ð½Ðµ Ñ\83казана"
+msgstr "Ð\91ез Ñ\83казаниÑ\8f Ð¿Ñ\80иÑ\87инÑ\8b"
 
 msgid "Key is superseded"
-msgstr "Ключ заменен другим"
+msgstr "Ключ заменён другим"
 
 msgid "Key has been compromised"
-msgstr "Ð\9aлÑ\8eÑ\87 Ð±Ñ\8bл Ñ\80аÑ\81кÑ\80Ñ\8bÑ\82"
+msgstr "Ð\9aлÑ\8eÑ\87 Ð±Ñ\8bл Ñ\81компÑ\80омеÑ\82иÑ\80ован"
 
 msgid "Key is no longer used"
 msgstr "Ключ больше не используется"
 
 msgid "User ID is no longer valid"
-msgstr "ID пользователя больше не действителен"
+msgstr "User ID больше не действителен"
 
 msgid "reason for revocation: "
 msgstr "причина отзыва: "
 
 msgid "revocation comment: "
-msgstr "пояснение к отзыву: "
+msgstr "прокомментируйте отзыв: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
-msgstr "iImMqQsS"
+msgstr ""
 
 msgid "No trust value assigned to:\n"
 msgstr "Не задано значение доверия для:\n"
 
 #, c-format
 msgid "  aka \"%s\"\n"
-msgstr "  или \"%s\"\n"
+msgstr "  aka \"%s\"\n"
 
-# test it
 msgid ""
 "How much do you trust that this key actually belongs to the named user?\n"
 msgstr ""
-"Насколько Вы уверены, что данный ключ принадлежит названному пользователю?\n"
+"Какова уверенность в принадлежности данного ключа лицу указанному в User ID "
+"ключа?\n"
 
 #, c-format
 msgid "  %d = I don't know or won't say\n"
@@ -4451,7 +4279,7 @@ msgstr " %d = Не знаю или не буду отвечать\n"
 
 #, c-format
 msgid "  %d = I do NOT trust\n"
-msgstr " %d = Ð\9dÐ\95 доверяю\n"
+msgstr " %d = Ð\9dе доверяю\n"
 
 #, c-format
 msgid "  %d = I trust ultimately\n"
@@ -4475,31 +4303,30 @@ msgstr ""
 "\n"
 
 msgid "Your decision? "
-msgstr "Ваше решение? "
+msgstr "Ваше решение (?-подробнее)? "
 
 msgid "Do you really want to set this key to ultimate trust? (y/N) "
-msgstr "Вы действительно хотите сделать этот ключ абсолютно доверенным? (y/N) "
+msgstr ""
+"Действительно хотите установить АБСОЛЮТНОЕ доверие к владельцу данного "
+"ключа? (y/N)"
 
 msgid "Certificates leading to an ultimately trusted key:\n"
-msgstr "СеÑ\80Ñ\82иÑ\84икаÑ\82Ñ\8b, Ð²ÐµÐ´Ñ\83Ñ\89ие Ðº Ð°Ð±Ñ\81олÑ\8eÑ\82но Ð´Ð¾Ð²ÐµÑ\80енному ключу:\n"
+msgstr "СеÑ\80Ñ\82иÑ\84икаÑ\82Ñ\8b, Ð¿Ñ\80иводÑ\8fÑ\89ие Ðº Ð°Ð±Ñ\81олÑ\8eÑ\82но Ð´Ð¾Ð²ÐµÑ\80Ñ\8fемому ключу:\n"
 
-# test it
 #, c-format
 msgid "%s: There is no assurance this key belongs to the named user\n"
 msgstr ""
-"%s: Нет свидетельств того, что данный ключ принадлежит названному "
-"полÑ\8cзоваÑ\82елÑ\8e\n"
+"%s: Нет свидетельств принадлежности данного ключа лицу указанному в User ID "
+"клÑ\8eÑ\87а\n"
 
-# test it
 #, c-format
 msgid "%s: There is limited assurance this key belongs to the named user\n"
 msgstr ""
-"%s: Мало свидетельств того, что данный ключ принадлежит названному "
-"полÑ\8cзоваÑ\82елÑ\8e\n"
+"%s: Мало свидетельств принадлежности данного ключа лицу указанному в User ID "
+"клÑ\8eÑ\87а\n"
 
-# test it
 msgid "This key probably belongs to the named user\n"
-msgstr "Этот ключ, вероятно, принадлежит названному владельцу\n"
+msgstr "Этот ключ вероятно принадлежит названному владельцу\n"
 
 msgid "This key belongs to us\n"
 msgstr "Данный ключ принадлежит нам\n"
@@ -4509,21 +4336,21 @@ msgid ""
 "in the user ID.  If you *really* know what you are doing,\n"
 "you may answer the next question with yes.\n"
 msgstr ""
-"Ð\9dеÑ\82 Ñ\83веÑ\80енноÑ\81Ñ\82и Ð² Ñ\82ом, Ñ\87Ñ\82о ÐºÐ»Ñ\8eÑ\87 Ð¿Ñ\80инадлежиÑ\82 Ñ\87еловекÑ\83, указанному\n"
-"в ID пользователя ключа. Если Вы ТОЧНО знаете, что делаете,\n"
+"Ð\9dеÑ\82 Ñ\83веÑ\80енноÑ\81Ñ\82и Ð¿Ñ\80инадлежноÑ\81Ñ\82и ÐºÐ»Ñ\8eÑ\87а Ñ\87еловекÑ\83 указанному\n"
+"в User ID ключа.  Если ТОЧНО знаете, что делаете,\n"
 "можете ответить на следующий вопрос утвердительно.\n"
 
 msgid "Use this key anyway? (y/N) "
-msgstr "Все равно использовать данный ключ? (y/N) "
+msgstr "Всё равно использовать данный ключ? (y/N)"
 
 msgid "WARNING: Using untrusted key!\n"
-msgstr "ВНИМАНИЕ: Использование недоверенного ключа!\n"
+msgstr "ВНИМАНИЕ: Использование недоверяемого ключа!\n"
 
 msgid "WARNING: this key might be revoked (revocation key not present)\n"
-msgstr "ВНИМАНИЕ: возможно, данный ключ отозван (ключ отзыва отсутствует)\n"
+msgstr "ВНИМАНИЕ: возможно данный ключ отозван (ключ отзыва отсутствует)\n"
 
 msgid "WARNING: This key has been revoked by its designated revoker!\n"
-msgstr "ВНИМАНИЕ: Данный ключ отозван ключом, назначенным отзывающим!\n"
+msgstr "ВНИМАНИЕ: Данный ключ отозван ключом назначенным отзывающим!\n"
 
 msgid "WARNING: This key has been revoked by its owner!\n"
 msgstr "ВНИМАНИЕ: Данный ключ отозван его владельцем!\n"
@@ -4538,18 +4365,18 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Замечание: Данный ключ отключен.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
-msgstr "Ð\97амеÑ\87ание: Ð\9fÑ\80овеÑ\80еннÑ\8bй Ð°Ð´Ñ\80еÑ\81 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81авÑ\88его - `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
+msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð\9fÑ\80овеÑ\80еннÑ\8bй Ð°Ð´Ñ\80еÑ\81 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81авÑ\88его `%s'\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
-msgstr "Ð\97амеÑ\87ание: Ð\90дÑ\80еÑ\81 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81авÑ\88его `%s' Ð½Ðµ Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83еÑ\82 Ð´Ð°Ð½Ð½Ñ\8bм DNS\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
+msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: Ð\90дÑ\80еÑ\81 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81авÑ\88его `%s' Ð½Ðµ Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83еÑ\82 Ñ\84оÑ\80маÑ\82Ñ\83 DNS\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
-msgstr "уровень доверия установлен в ПОЛНЫЙ по действительным данным PKA\n"
+msgstr ""
 
 msgid "trustlevel adjusted to NEVER due to bad PKA info\n"
-msgstr "уровень доверия установлен в НИКОГДА из-за непригодных данных PKA\n"
+msgstr ""
 
 msgid "Note: This key has expired!\n"
 msgstr "Замечание: Данный ключ просрочен!\n"
@@ -4559,18 +4386,18 @@ msgstr "ВНИМАНИЕ: Данный ключ не заверен довере
 
 msgid ""
 "         There is no indication that the signature belongs to the owner.\n"
-msgstr "          Нет указаний на то, что подпись принадлежит владельцу.\n"
+msgstr "         Нет указаний на то, что подпись принадлежит владельцу.\n"
 
 msgid "WARNING: We do NOT trust this key!\n"
 msgstr "ВНИМАНИЕ: НЕТ ДОВЕРИЯ данному ключу!\n"
 
 msgid "         The signature is probably a FORGERY.\n"
-msgstr "          Возможно, что подпись ПОДДЕЛАНА.\n"
+msgstr "         Возможно, что подпись ПОДДЕЛАНА.\n"
 
 msgid ""
 "WARNING: This key is not certified with sufficiently trusted signatures!\n"
 msgstr ""
-"ВНИМАНИЕ: Этот ключ не заверен достаточным количеством доверенных подписей!\n"
+"ВНИМАНИЕ: Этот ключ не заверен достаточным количеством доверяемых подписей!\n"
 
 msgid "         It is not certain that the signature belongs to the owner.\n"
 msgstr "         Нет уверенности в том, что подпись принадлежит владельцу.\n"
@@ -4581,10 +4408,10 @@ msgstr "%s: пропущено: %s\n"
 
 #, c-format
 msgid "%s: skipped: public key already present\n"
-msgstr "%s: пропущено: открытый ключ уже существует\n"
+msgstr "%s: пропущено: открытый ключ уже имеется\n"
 
 msgid "You did not specify a user ID. (you may use \"-r\")\n"
-msgstr "Не задан ID пользователя (можно использовать \"-r\").\n"
+msgstr "Не задан User ID. (можете использовать \"-r\")\n"
 
 msgid "Current recipients:\n"
 msgstr "Текущие получатели:\n"
@@ -4594,10 +4421,10 @@ msgid ""
 "Enter the user ID.  End with an empty line: "
 msgstr ""
 "\n"
-"Введите ID пользователя. Пустая строка для завершения: "
+"Введите User ID.  Пустая строка для завершения: "
 
 msgid "No such user ID.\n"
-msgstr "Нет такого ID пользователя.\n"
+msgstr "Нет такого User ID.\n"
 
 msgid "skipped: public key already set as default recipient\n"
 msgstr "пропущено: открытый ключ уже установлен для получателя по умолчанию\n"
@@ -4617,11 +4444,11 @@ msgid "%s: skipped: public key is disabled\n"
 msgstr "%s: пропущено: открытый ключ отключен\n"
 
 msgid "no valid addressees\n"
-msgstr "неÑ\82 Ð¿Ñ\80игодных адресов\n"
+msgstr "неÑ\82 Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cных адресов\n"
 
 #, c-format
 msgid "Note: key %s has no %s feature\n"
-msgstr "Замечание: у ключа %s нет функции %s\n"
+msgstr "Замечание: ключ %s не умеет %s\n"
 
 #, c-format
 msgid "Note: key %s has no preference for %s\n"
@@ -4640,10 +4467,10 @@ msgid "reading stdin ...\n"
 msgstr "читаю stdin ...\n"
 
 msgid "no signed data\n"
-msgstr "нет подписанных данных\n"
+msgstr "не подписанные данные\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "не могу открыть подписанные данные `%s'\n"
 
 #, c-format
@@ -4652,10 +4479,10 @@ msgstr "не могу открыть подписанные данные fd=%d:
 
 #, c-format
 msgid "anonymous recipient; trying secret key %s ...\n"
-msgstr "анонимный получатель; пробую закрытый ключ %s ...\n"
+msgstr "анонимный получатель; пробую секретный ключ %s ...\n"
 
 msgid "okay, we are the anonymous recipient.\n"
-msgstr "отлично, мы анонимный получатель.\n"
+msgstr "отлично, мы анонимный получатель.\n"
 
 msgid "old encoding of the DEK is not supported\n"
 msgstr "старое шифрование DEK не поддерживается\n"
@@ -4671,35 +4498,34 @@ msgstr ""
 
 #, c-format
 msgid "NOTE: secret key %s expired at %s\n"
-msgstr "ЗАМЕЧАНИЕ: закрытый ключ %s просрочен с %s\n"
+msgstr "ЗАМЕЧАНИЕ: секретный ключ %s просрочен с %s\n"
 
 msgid "NOTE: key has been revoked"
 msgstr "ЗАМЕЧАНИЕ: ключ был отозван"
 
 #, c-format
 msgid "build_packet failed: %s\n"
-msgstr "сбой build_packet: %s\n"
+msgstr ""
 
 #, c-format
 msgid "key %s has no user IDs\n"
-msgstr "у ключа %s нет ID пользователя\n"
+msgstr "ключ %s не имеет User ID\n"
 
 msgid "To be revoked by:\n"
 msgstr "Будет отозван:\n"
 
-# check it
 msgid "(This is a sensitive revocation key)\n"
-msgstr "(Это особо важный ключ отзыва)\n"
+msgstr "(Это - sensitive ключ отзыва)\n"
 
 msgid "Create a designated revocation certificate for this key? (y/N) "
-msgstr "Создать сертификат отзыва данного ключа? (y/N) "
+msgstr "Создать сертификат отзыва данного ключа? (y/N)"
 
 msgid "ASCII armored output forced.\n"
-msgstr "Для вывода использован текстовый формат ASCII.\n"
+msgstr "Для вывода использован ASCII формат.\n"
 
 #, c-format
 msgid "make_keysig_packet failed: %s\n"
-msgstr "сбой make_keysig_packet: %s\n"
+msgstr ""
 
 msgid "Revocation certificate created.\n"
 msgstr "Сертификат отзыва создан.\n"
@@ -4710,17 +4536,17 @@ msgstr "ключи отзыва для \"%s\" не найдены\n"
 
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
-msgstr "закрытый ключ \"%s\" не найден: %s\n"
+msgstr "секретный ключ \"%s\" не найден: %s\n"
 
 #, c-format
 msgid "no corresponding public key: %s\n"
-msgstr "неÑ\82 Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89его Ð¾Ñ\82кÑ\80Ñ\8bÑ\82ого ÐºÐ»Ñ\8eÑ\87а: %s\n"
+msgstr "нет соотвествующего открытого ключа: %s\n"
 
 msgid "public key does not match secret key!\n"
-msgstr "оÑ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 Ð½Ðµ Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83еÑ\82 Ð·Ð°ÐºÑ\80Ñ\8bÑ\82ому!\n"
+msgstr "оÑ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 Ð½Ðµ Ñ\81ооÑ\82веÑ\81Ñ\82вÑ\83еÑ\82 Ñ\81екÑ\80еÑ\82ному!\n"
 
 msgid "Create a revocation certificate for this key? (y/N) "
-msgstr "Создать сертификат отзыва данного ключа? (y/N) "
+msgstr "Создать сертификат отзыва данного ключа? (y/N)"
 
 msgid "unknown protection algorithm\n"
 msgstr "неизвестный алгоритм защиты\n"
@@ -4739,12 +4565,12 @@ msgid ""
 msgstr ""
 "Сертификат отзыва создан.\n"
 "\n"
-"Поместите его в надежное место; если посторонний получит доступ\n"
+"Поместите его в скрытое место;  если посторонний получит доступ\n"
 "к данному сертификату, он может использовать его, чтобы сделать\n"
 "Ваш ключ непригодным к использованию. Можно распечатать данный\n"
-"сертификат и спрятать подальше на случай, если Ваш основной\n"
+"сертификат и спрятать подальше,  на случай если Ваш основной\n"
 "носитель будет поврежден, но будьте осторожны: система печати\n"
-"Ð\92аÑ\88ей Ð¼Ð°Ñ\88инÑ\8b Ð¼Ð¾Ð¶ÐµÑ\82 Ñ\81оÑ\85Ñ\80аниÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bе Ð¸ Ñ\81делаÑ\82Ñ\8c Ð¸Ñ\85 Ð´Ð¾Ñ\81Ñ\82Ñ\83пнÑ\8bми Ð´Ð»Ñ\8f Ð´Ñ\80Ñ\83гиÑ\85!\n"
+"может сохранить данные и сделать их доступными для других!\n"
 
 msgid "Please select the reason for the revocation:\n"
 msgstr "Укажите причину отзыва:\n"
@@ -4754,7 +4580,7 @@ msgstr "Отмена"
 
 #, c-format
 msgid "(Probably you want to select %d here)\n"
-msgstr "(СкоÑ\80ее Ð²Ñ\81его, Ð\92Ñ\8b Ð·Ð´ÐµÑ\81Ñ\8c Ð²Ñ\8bбеÑ\80еÑ\82е %d)\n"
+msgstr "(Ð\92озможно Ð\92Ñ\8b Ñ\85оÑ\82иÑ\82е Ð²Ñ\8bбÑ\80аÑ\82Ñ\8c Ð·Ð´ÐµÑ\81Ñ\8c %d)\n"
 
 msgid "Enter an optional description; end it with an empty line:\n"
 msgstr "Введите необязательное пояснение; закончите пустой строкой:\n"
@@ -4770,15 +4596,15 @@ msgid "Is this okay? (y/N) "
 msgstr "Все правильно? (y/N) "
 
 msgid "secret key parts are not available\n"
-msgstr "закрытая часть ключа недоступна\n"
+msgstr "секретная часть ключ не доступна\n"
 
 #, c-format
 msgid "protection algorithm %d%s is not supported\n"
-msgstr "алгоÑ\80иÑ\82м защиты %d%s не поддерживается\n"
+msgstr "меÑ\82од защиты %d%s не поддерживается\n"
 
 #, c-format
 msgid "protection digest %d is not supported\n"
-msgstr "хэш защиты %d не поддерживается\n"
+msgstr "метод защиты %d не поддерживается\n"
 
 msgid "Invalid passphrase; please try again"
 msgstr "Неверная фраза-пароль; попробуйте еще раз"
@@ -4788,7 +4614,7 @@ msgid "%s ...\n"
 msgstr "%s ...\n"
 
 msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð\9eбнаружен слабый ключ - смените фразу-пароль еще раз.\n"
+msgstr "Ð\92Ð\9dÐ\98Ð\9cÐ\90Ð\9dÐ\98Ð\95: Ð¾бнаружен слабый ключ - смените фразу-пароль еще раз.\n"
 
 msgid "generating the deprecated 16-bit checksum for secret key protection\n"
 msgstr ""
@@ -4803,65 +4629,67 @@ msgstr ""
 "невозможно избежать слабого ключа для симметричного шифра; %d попыток!\n"
 
 msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "DSA требует длины хэша, кратной 8 битам\n"
+msgstr "DSA тебует размер хеша кратного 8 битам\n"
 
 #, c-format
 msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "Ð\9aлÑ\8eÑ\87 DSA %s Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82 Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\8bй (%u-биÑ\82нÑ\8bй) Ñ\85Ñ\8dш\n"
+msgstr "клÑ\8eÑ\87 DSA %s Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82 Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñ\81нÑ\8bй (%u Ð±Ð¸Ñ\82) Ñ\85еш\n"
 
 #, c-format
 msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "Ð\9aлÑ\8eÑ\87 DSA %s Ñ\82Ñ\80ебÑ\83еÑ\82 %u-биÑ\82ного Ð¸Ð»Ð¸ Ð±Ð¾Ð»ÐµÐµ Ð´Ð»Ð¸Ð½Ð½Ð¾Ð³Ð¾ Ñ\85Ñ\8dÑ\88а\n"
+msgstr "длÑ\8f ÐºÐ»Ñ\8eÑ\87а DSA %s Ñ\82Ñ\80ебÑ\83еÑ\82Ñ\81Ñ\8f Ñ\85еÑ\88 Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %u Ð±Ð¸Ñ\82\n"
 
 msgid "WARNING: signature digest conflict in message\n"
 msgstr "ВНИМАНИЕ: конфликт хэшей подписей в сообщении\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s is not cross-certified\n"
-msgstr "ВНИМАНИЕ: подписывающий подключ %s не был перекрестно заверен\n"
+msgstr ""
+"ВНИМАНИЕ: подписываемый подключ %s не имеет перекрестной сертификации\n"
 
 #, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
-msgstr "ВНИМАНИЕ: подписывающий подключ %s неправильно перекрестно заверен\n"
+msgstr ""
+"ВНИМАНИЕ: подписываемый подключ %s имеет недостоверную перекрестную "
+"сертификацию\n"
 
 #, c-format
 msgid "public key %s is %lu second newer than the signature\n"
-msgstr "оÑ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 %s Ð½Ð° %lu Ñ\81екÑ\83нд Ð½Ð¾Ð²Ðµе подписи\n"
+msgstr "оÑ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 %s Ð½Ð° %lu Ñ\81екÑ\83нд Ð¼Ð¾Ð»Ð¾Ð¶е подписи\n"
 
 #, c-format
 msgid "public key %s is %lu seconds newer than the signature\n"
-msgstr "оÑ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 %s Ð½Ð° %lu Ñ\81екÑ\83нд Ð½Ð¾Ð²Ðµе подписи\n"
+msgstr "оÑ\82кÑ\80Ñ\8bÑ\82Ñ\8bй ÐºÐ»Ñ\8eÑ\87 %s Ð½Ð° %lu Ñ\81екÑ\83нд Ð¼Ð¾Ð»Ð¾Ð¶е подписи\n"
 
 #, c-format
 msgid ""
 "key %s was created %lu second in the future (time warp or clock problem)\n"
 msgstr ""
-"ключ %s создан на %lu секунду в будущем (петля во времени или проблемы с "
+"ключ %s был создан на %lu секунд в будущем (time warp или проблемы с "
 "часами)\n"
 
 #, c-format
 msgid ""
 "key %s was created %lu seconds in the future (time warp or clock problem)\n"
 msgstr ""
-"ключ %s создан на %lu секунд в будущем (петля во времени или проблемы с "
+"ключ %s был создан на %lu секунд в будущем (time warp или проблемы с "
 "часами)\n"
 
 #, c-format
 msgid "NOTE: signature key %s expired %s\n"
-msgstr "ЗАМЕЧАНИЕ: срок действия подписавшего ключа %s истек %s\n"
+msgstr "ЗАМЕЧАНИЕ: подписавший ключ %s - просрочен %s\n"
 
 #, c-format
 msgid "NOTE: signature key %s has been revoked\n"
-msgstr "ЗАМЕЧАНИЕ: ключ для подписей %s отозван\n"
+msgstr "ЗАМЕЧАНИЕ: ключ %s подписи - отозван\n"
 
 #, c-format
 msgid "assuming bad signature from key %s due to an unknown critical bit\n"
-msgstr ""
-"подпись ключа %s считается плохой из-за неизвестного критического бита\n"
+msgstr "принята плохая подпись ключа %s с неизвестным критическим битом\n"
 
 #, c-format
 msgid "key %s: no subkey for subkey revocation signature\n"
-msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÑ\82 Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87а Ð´Ð»Ñ\8f Ð¾Ñ\82зÑ\8bваÑ\8eÑ\89ей Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87а\n"
+msgstr "клÑ\8eÑ\87 %s: Ð½ÐµÑ\82 Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87а Ð´Ð»Ñ\8f Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87а Ð¾Ñ\82зÑ\8bваÑ\8eÑ\89ей Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и\n"
 
 #, c-format
 msgid "key %s: no subkey for subkey binding signature\n"
@@ -4870,14 +4698,13 @@ msgstr "ключ %s: нет подключа для подписи связи п
 #, c-format
 msgid "WARNING: unable to %%-expand notation (too large).  Using unexpanded.\n"
 msgstr ""
-"ВНИМАНИЕ: не могу развернуть %% в примечании (слишком длинное).\n"
-"          Использую неразвернутым.\n"
+"ВНИМАНИЕ: не могу развернуть %% запись (длинный). Использую неразвернутым.\n"
 
 #, c-format
 msgid ""
 "WARNING: unable to %%-expand policy URL (too large).  Using unexpanded.\n"
 msgstr ""
-"ВНИМАНИЕ: не могу развернуть %% в URL правил (слишком длинный). Использую "
+"ВНИМАНИЕ: не могу развернуть %% url правил (длинный). Использую "
 "неразвернутым.\n"
 
 #, c-format
@@ -4885,7 +4712,7 @@ msgid ""
 "WARNING: unable to %%-expand preferred keyserver URL (too large).  Using "
 "unexpanded.\n"
 msgstr ""
-"ВНИМАНИЕ: невозможно развернуть %% в URL предпочтительного сервера ключей "
+"ВНИМАНИЕ: невозможно развернуть %% URL предпочитаемого сервера ключей "
 "(слишком длинно). Использую неразвернутым.\n"
 
 #, c-format
@@ -4897,8 +4724,7 @@ msgid "%s/%s signature from: \"%s\"\n"
 msgstr "%s/%s подпись от: \"%s\"\n"
 
 msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"ключом типа PGP 2.x в режиме --pgp2 можно делать только отделенные подписи\n"
+msgstr "только отделенная подпись доступна с PGP 2.x ключом в режиме --pgp2\n"
 
 #, c-format
 msgid ""
@@ -4911,17 +4737,15 @@ msgid "signing:"
 msgstr "подпись:"
 
 msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"ключом типа PGP 2.x в режиме --pgp2 можно делать только текстовые подписи\n"
+msgstr "только прозрачная подпись доступна с PGP 2.x ключом в режиме --pgp2\n"
 
 #, c-format
 msgid "%s encryption will be used\n"
-msgstr "будет использовано шифрование по %s\n"
+msgstr "будет использовано %s шифрование\n"
 
 msgid "key is not flagged as insecure - can't use it with the faked RNG!\n"
 msgstr ""
-"ключ не помечен как небезопасный - не могу использовать его с фальшивым "
-"генератором случайных чисел!\n"
+"ключ не помечен как ненадежный - не могу использовать его с ненадежным RNG!\n"
 
 #, c-format
 msgid "skipped \"%s\": duplicated\n"
@@ -4932,11 +4756,11 @@ msgid "skipped \"%s\": %s\n"
 msgstr "пропущено \"%s\": %s\n"
 
 msgid "skipped: secret key already present\n"
-msgstr "пропущено: закрытый ключ уже имеется\n"
+msgstr "пропущено: секретный ключ уже имеется\n"
 
 msgid "this is a PGP generated Elgamal key which is not secure for signatures!"
 msgstr ""
-"это ключ Elgamal, созданный PGP, он не обеспечивает безопасность подписи!"
+"это созданный PGP ElGamal ключ, не обеспечивающий безопасность подписи!"
 
 #, c-format
 msgid "trust record %lu, type %d: write failed: %s\n"
@@ -4951,11 +4775,11 @@ msgstr ""
 "# (Используйте \"gpg --import-ownertrust\" для их восстановления)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "ошибка в `%s': %s\n"
 
 msgid "line too long"
-msgstr "слишком длинная строка"
+msgstr "строка слишком длинная"
 
 msgid "colon missing"
 msgstr "пропущено двоеточие"
@@ -4967,43 +4791,43 @@ msgid "ownertrust value missing"
 msgstr "пропущено значение степени доверия владельцу"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "ошибка при поиске записи о доверии в `%s': %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "ошибка чтения в `%s': %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
-msgstr "таблица доверия: сбой синхронизации: %s\n"
-
-#, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "невозможно создать блокировку для `%s'\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "невозможно заблокировать `%s'\n"
+msgstr ""
 
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
-msgstr "таблица доверия, запись %lu: сбой lseek: %s\n"
+msgstr ""
 
 #, c-format
 msgid "trustdb rec %lu: write failed (n=%d): %s\n"
-msgstr "таблица доверия, запись %lu: сбой записи (n=%d): %s\n"
+msgstr ""
 
 msgid "trustdb transaction too large\n"
-msgstr "слишком большая транзакция таблицы доверия\n"
+msgstr "trustdb транзакция слишком длинная\n"
+
+#, c-format
+msgid "can't access '%s': %s\n"
+msgstr "нет доступа к `%s': %s\n"
 
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: каталог не существует!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "нет доступа к `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "невозможно создать блокировку для `%s'\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "невозможно заблокировать `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5011,18 +4835,18 @@ msgstr "%s: сбой создания записи о версии: %s"
 
 #, c-format
 msgid "%s: invalid trustdb created\n"
-msgstr "%s: Ñ\81оздана Ð½ÐµÐ¿Ñ\80игоднаÑ\8f Ñ\82аблиÑ\86а Ð´Ð¾Ð²ÐµÑ\80иÑ\8f\n"
+msgstr "%s: Ñ\81оздана Ð½ÐµÐ´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cнаÑ\8f Ñ\82аблиÑ\86а Ð´Ð¾Ð²ÐµÑ\80ий\n"
 
 #, c-format
 msgid "%s: trustdb created\n"
-msgstr "%s: создана таблица доверия\n"
+msgstr "%s: создана таблица доверий\n"
 
 msgid "NOTE: trustdb not writable\n"
-msgstr "ЗАМЕЧАНИЕ: таблица доверия недоступна для записи\n"
+msgstr "ЗАМЕЧАНИЕ: таблица доверий доступна только для чтения\n"
 
 #, c-format
 msgid "%s: invalid trustdb\n"
-msgstr "%s: Ð½ÐµÐ¿Ñ\80игоднаÑ\8f Ñ\82аблиÑ\86а Ð´Ð¾Ð²ÐµÑ\80иÑ\8f\n"
+msgstr "%s: Ð½ÐµÐ´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cнаÑ\8f Ñ\82аблиÑ\86а Ð´Ð¾Ð²ÐµÑ\80ий\n"
 
 #, c-format
 msgid "%s: failed to create hashtable: %s\n"
@@ -5042,15 +4866,15 @@ msgstr "%s: ошибка сохранения записи о версии: %s\n
 
 #, c-format
 msgid "trustdb: lseek failed: %s\n"
-msgstr "таблица доверия: сбой lseek: %s\n"
+msgstr ""
 
 #, c-format
 msgid "trustdb: read failed (n=%d): %s\n"
-msgstr "таблица доверия: сбой чтения (n=%d): %s\n"
+msgstr ""
 
 #, c-format
 msgid "%s: not a trustdb file\n"
-msgstr "%s: не является файлом таблицы доверия\n"
+msgstr "%s: не является файлом таблицы доверий\n"
 
 #, c-format
 msgid "%s: version record with recnum %lu\n"
@@ -5076,8 +4900,9 @@ msgstr "%s: сбой обнуления записи: %s\n"
 msgid "%s: failed to append a record: %s\n"
 msgstr "%s: сбой добавления записи: %s\n"
 
+#, fuzzy
 msgid "Error: The trustdb is corrupted.\n"
-msgstr "Ошибка: таблица доверия повреждена\n"
+msgstr "%s: создана таблица доверий\n"
 
 #, c-format
 msgid "can't handle text lines longer than %d characters\n"
@@ -5085,27 +4910,27 @@ msgstr "не могу обработать строки текста длинн
 
 #, c-format
 msgid "input line longer than %d characters\n"
-msgstr "строка ввода длиннее %d символов\n"
+msgstr "введенная строка превышает %d символов\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' не является допустимым длинным ID ключа\n"
 
 #, c-format
 msgid "key %s: accepted as trusted key\n"
-msgstr "ключ %s: принят как доверенный ключ\n"
+msgstr "ключ %s: принят как доверяемый ключ\n"
 
 #, c-format
 msgid "key %s occurs more than once in the trustdb\n"
-msgstr "клÑ\8eÑ\87 %s Ð²Ñ\81Ñ\82Ñ\80еÑ\87аеÑ\82Ñ\81Ñ\8f Ð² Ñ\82аблиÑ\86е Ð´Ð¾Ð²ÐµÑ\80иÑ\8f Ð±Ð¾Ð»ÐµÐµ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ñ\80аза\n"
+msgstr "клÑ\8eÑ\87 %s Ð²Ñ\81Ñ\82Ñ\80еÑ\87аеÑ\82Ñ\81Ñ\8f Ð±Ð¾Ð»ÐµÐµ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ñ\80аза Ð² Ñ\82аблиÑ\86е Ð´Ð¾Ð²ÐµÑ\80ий\n"
 
 #, c-format
 msgid "key %s: no public key for trusted key - skipped\n"
-msgstr "ключ %s: нет открытого ключа для доверенного ключа - пропущен\n"
+msgstr "ключ %s: нет открытого ключа для доверяемого ключа - пропущен\n"
 
 #, c-format
 msgid "key %s marked as ultimately trusted\n"
-msgstr "ключ %s помечен как абсолютно доверенный.\n"
+msgstr "ключ %s помечен как абсолютно доверяемый.\n"
 
 #, c-format
 msgid "trust record %lu, req type %d: read failed: %s\n"
@@ -5116,83 +4941,73 @@ msgid "trust record %lu is not of requested type %d\n"
 msgstr "запись о доверии %lu не запрашиваемого типа %d\n"
 
 msgid "You may try to re-create the trustdb using the commands:\n"
-msgstr "Можно попытаться пересоздать таблицу доверия командами:\n"
+msgstr ""
 
 msgid "If that does not work, please consult the manual\n"
-msgstr "Если это не выйдет, обратитесь к руководству пользователя\n"
+msgstr ""
 
-# check it
 #, c-format
 msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
 msgstr ""
-"не могу использовать неизвестную модель (%d) - использую модель доверия %s\n"
+"не могу использовать неизвестную модель (%d) - использую %s модель доверий\n"
 
-# check it
 #, c-format
 msgid "using %s trust model\n"
-msgstr "использую модель доверия %s\n"
-
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
+msgstr "использую %s модель доверий\n"
+
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
-msgstr "12 translator see trustdb.c:uid_trust_string_fixed"
+msgstr ""
 
 msgid "[ revoked]"
-msgstr "[  отозвано]"
+msgstr "[ отозван]"
 
 msgid "[ expired]"
-msgstr "[пÑ\80оÑ\81Ñ\80оÑ\87ено]"
+msgstr "[пÑ\80оÑ\81Ñ\80оÑ\87н]"
 
 msgid "[ unknown]"
-msgstr "[неизвестно]"
+msgstr "[неизвстн]"
 
 msgid "[  undef ]"
-msgstr "[ неопредел]"
+msgstr "[неопредл]"
 
 msgid "[marginal]"
-msgstr "[ ограничен]"
+msgstr "[ограничн]"
 
 msgid "[  full  ]"
-msgstr "[  полное  ]"
+msgstr "[ полное ]"
 
 msgid "[ultimate]"
-msgstr "[абсолютное]"
+msgstr "[абсолютн]"
 
 msgid "undefined"
-msgstr "неопÑ\80еделенное"
+msgstr "неопÑ\80еделено"
 
 msgid "never"
 msgstr "никогда"
 
 msgid "marginal"
-msgstr "ограниченное"
+msgstr "ограниченно"
 
 msgid "full"
 msgstr "полное"
 
 msgid "ultimate"
-msgstr "абсолютное"
+msgstr "абсолютно"
 
 msgid "no need for a trustdb check\n"
-msgstr "пÑ\80овеÑ\80ка Ñ\82аблиÑ\86Ñ\8b Ð´Ð¾Ð²ÐµÑ\80иÑ\8f Ð½Ðµ Ð½Ñ\83жна\n"
+msgstr "неÑ\82 Ð½ÐµÐ¾Ð±Ñ\85одимоÑ\81Ñ\82и Ð² Ð¿Ñ\80овеÑ\80ке Ñ\82аблиÑ\86Ñ\8b Ð´Ð¾Ð²ÐµÑ\80ий\n"
 
 #, c-format
 msgid "next trustdb check due at %s\n"
-msgstr "срок следующей проверки таблицы доверия %s\n"
+msgstr "срок следующей проверки таблицы доверий %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
-msgstr "пÑ\80овеÑ\80Ñ\8fÑ\82Ñ\8c Ñ\82аблиÑ\86Ñ\83 Ð´Ð¾Ð²ÐµÑ\80иÑ\8f Ð¿Ñ\80и Ð¼Ð¾Ð´ÐµÐ»Ð¸ Ð´Ð¾Ð²ÐµÑ\80иÑ\8f `%s' Ð½Ðµ Ð½Ñ\83жно\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
+msgstr "неÑ\82 Ð½ÐµÐ¾Ð±Ñ\85одимоÑ\81Ñ\82и Ð¿Ñ\80овеÑ\80Ñ\8fÑ\82Ñ\8c Ñ\82аблиÑ\86Ñ\83 Ð´Ð¾Ð²ÐµÑ\80ий Ð¿Ñ\80и `%s' Ð¼Ð¾Ð´ÐµÐ»Ð¸ Ð´Ð¾Ð²ÐµÑ\80ий\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
-msgstr "обновлÑ\8fÑ\82Ñ\8c Ñ\82аблиÑ\86Ñ\83 Ð´Ð¾Ð²ÐµÑ\80иÑ\8f Ð¿Ñ\80и Ð¼Ð¾Ð´ÐµÐ»Ð¸ Ð´Ð¾Ð²ÐµÑ\80иÑ\8f `%s' Ð½Ðµ Ð½Ñ\83жно\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
+msgstr "неÑ\82 Ð½ÐµÐ¾Ð±Ñ\85одимоÑ\81Ñ\82и Ð¾Ð±Ð½Ð¾Ð²Ð»Ñ\8fÑ\82Ñ\8c Ñ\82аблиÑ\86Ñ\83 Ð´Ð¾Ð²ÐµÑ\80ий Ð¿Ñ\80и '%s' Ð¼Ð¾Ð´ÐµÐ»Ð¸ Ð´Ð¾Ð²ÐµÑ\80ий\n"
 
 #, c-format
 msgid "public key %s not found: %s\n"
@@ -5202,35 +5017,35 @@ msgid "please do a --check-trustdb\n"
 msgstr "выполните --check-trustdb, пожалуйста\n"
 
 msgid "checking the trustdb\n"
-msgstr "проверка таблицы доверия\n"
+msgstr "проверка таблицы доверий\n"
 
 #, c-format
 msgid "%d keys processed (%d validity counts cleared)\n"
-msgstr "%d ключей обработано (%d счетчиков пригодности очищено)\n"
+msgstr "%d ключей обработано (%d действующих записей очищено)\n"
 
 msgid "no ultimately trusted keys found\n"
-msgstr "не найдено абсолютно доверенных ключей\n"
+msgstr "не найдено абсолютно доверяемых ключей\n"
 
 #, c-format
 msgid "public key of ultimately trusted key %s not found\n"
-msgstr "открытый ключ для абсолютно доверенного ключа %s не найден\n"
+msgstr "открытый ключ для абсолютно доверяемого ключа %s не найден\n"
 
-# check it
 #, c-format
 msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n"
-msgstr "требуется %d с ограниченным доверием, %d с полным, модель доверия %s\n"
+msgstr ""
+"%d ограниченных необходимо, %d выполненных необходимо, %s модель доверия\n"
 
 #, c-format
 msgid ""
 "depth: %d  valid: %3d  signed: %3d  trust: %d-, %dq, %dn, %dm, %df, %du\n"
 msgstr ""
-"глÑ\83бина: %d  Ð²ÐµÑ\80нÑ\8bÑ\85: %3d  Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аннÑ\8bÑ\85: %3d  Ð´Ð¾Ð²ÐµÑ\80ие: %d-, %dq, %dn, %dm, "
+"глÑ\83бина: %d  ÐºÐ¾Ñ\80Ñ\80екÑ\82нÑ\8bÑ\85: %3d  Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81аннÑ\8bÑ\85: %3d  Ð´Ð¾Ð²ÐµÑ\80иÑ\8f: %d-, %dq, %dn, %dm, "
 "%df, %du\n"
 
 #, c-format
 msgid "unable to update trustdb version record: write failed: %s\n"
 msgstr ""
-"невозможно обновить запись о версии таблицы доверия: ошибка записи: %s\n"
+"невозможно обновить запись о версии таблицы доверий: ошибка записи: %s\n"
 
 msgid ""
 "the signature could not be verified.\n"
@@ -5239,11 +5054,11 @@ msgid ""
 msgstr ""
 "Не могу проверить подпись.\n"
 "Файл подписи (.sig или .asc) должен быть\n"
-"указан в командной строке первым.\n"
+"первым из файлов в командной строке.\n"
 
 #, c-format
 msgid "input line %u too long or missing LF\n"
-msgstr "слишком длинная входная строка %u или пропущен перевод строки\n"
+msgstr "входная строка %u слишком длинная или пропущен LF\n"
 
 #, c-format
 msgid "can't open fd %d: %s\n"
@@ -5261,47 +5076,40 @@ msgstr "ключевое слово слишком длинное"
 msgid "missing argument"
 msgstr "пропущен аргумент"
 
-msgid "invalid argument"
-msgstr "недопустимый аргумент"
-
 msgid "invalid command"
 msgstr "недопустимая команда"
 
 msgid "invalid alias definition"
-msgstr "недопустимое определение синонима"
+msgstr ""
 
 msgid "out of core"
-msgstr "нехватка выделенной памяти"
+msgstr ""
 
 msgid "invalid option"
 msgstr "недопустимый параметр"
 
 #, c-format
 msgid "missing argument for option \"%.50s\"\n"
-msgstr "не хватает аргумента для параметра \"%.50s\"\n"
-
-#, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "недопустимый аргумент для параметра \"%.50s\"\n"
+msgstr ""
 
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "у параметра \"%.50s\" не должно быть аргумента\n"
+msgstr "параметр \"%.50s\" не ожидает аргумента\n"
 
 #, c-format
 msgid "invalid command \"%.50s\"\n"
-msgstr "недопустимая команда \"%.50s\"\n"
+msgstr "Ð\9dедопустимая команда \"%.50s\"\n"
 
 #, c-format
 msgid "option \"%.50s\" is ambiguous\n"
-msgstr "параметр \"%.50s\" неоднозначен\n"
+msgstr "параметр \"%.50s\" не понят\n"
 
 #, c-format
 msgid "command \"%.50s\" is ambiguous\n"
-msgstr "команда \"%.50s\" неоднозначна\n"
+msgstr "команда \"%.50s\" не понята\n"
 
 msgid "out of core\n"
-msgstr "нехватка выделенной памяти\n"
+msgstr ""
 
 #, c-format
 msgid "invalid option \"%.50s\"\n"
@@ -5309,69 +5117,73 @@ msgstr "недопустимый параметр \"%.50s\"\n"
 
 #, c-format
 msgid "you found a bug ... (%s:%d)\n"
-msgstr "Вы нашли ошибку в программе ... (%s:%d)\n"
+msgstr "Вы нашли ошибку ... (%s:%d)\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "error loading '%s': %s\n"
+msgstr "ошибка загрузки `%s': %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr "преобразование из `%s' в `%s' недоступно\n"
 
 #, c-format
 msgid "iconv_open failed: %s\n"
-msgstr "сбой в iconv_open: %s\n"
+msgstr ""
 
 #, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "сбой преобразования `%s' в `%s': %s\n"
 
 #, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "невозможно создание временного файла `%s': %s\n"
 
 #, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "ошибка записи в `%s': %s\n"
 
 #, c-format
 msgid "removing stale lockfile (created by %d)\n"
-msgstr "удаляю залипшую блокировку (созданную %d)\n"
+msgstr ""
 
 msgid " - probably dead - removing lock"
-msgstr " - вероятно, процесс мертв - снимаю блокировку"
+msgstr ""
 
 #, c-format
 msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "жду снятия блокировки (заблокировано %d%s) %s...\n"
+msgstr ""
 
 msgid "(deadlock?) "
-msgstr "(мертвая точка?) "
+msgstr ""
 
 #, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "блокировка `%s' не создана: %s\n"
+msgid "lock '%s' not made: %s\n"
+msgstr ""
 
 #, c-format
 msgid "waiting for lock %s...\n"
-msgstr "ожидаю снятия блокировки %s...\n"
+msgstr ""
 
 msgid "set debugging flags"
-msgstr "установить отладочные флаги"
+msgstr ""
 
 msgid "enable full debugging"
-msgstr "полностью включить отладку"
+msgstr ""
 
 msgid "Usage: kbxutil [options] [files] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: kbxutil [параметры] [файлы] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: kbxutil [параметры] [файлы] (-h для подсказки)"
 
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
 "Синтаксис: kbxutil [параметры] [файлы]\n"
-"Ð\9fÑ\80оÑ\81моÑ\82Ñ\80, Ñ\8dкÑ\81поÑ\80Ñ\82, Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82 Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ñ\89иÑ\82а Ñ\81 ÐºÐ»Ñ\8eÑ\87ами\n"
+"пÑ\80оÑ\81моÑ\80Ñ\82, Ñ\8dкÑ\81поÑ\80Ñ\82, Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82 Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Keybox\n"
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
-msgstr "Модули RSA пропущены, или их размер не равен %d бит\n"
+msgstr "Модули RSA пропущены или не имеют размер %d бит\n"
 
 #, c-format
 msgid "RSA public exponent missing or larger than %d bits\n"
@@ -5379,42 +5191,42 @@ msgstr "отсутствует открытая экспонента RSA или
 
 #, c-format
 msgid "PIN callback returned error: %s\n"
-msgstr "Функция обработки PIN возвратила ошибку: %s\n"
+msgstr ""
 
 msgid "the NullPIN has not yet been changed\n"
-msgstr "пустой PIN до сих пор не изменен\n"
+msgstr "NullPIN всё еще не изменен\n"
 
+#, fuzzy
 msgid "|N|Please enter a new PIN for the standard keys."
-msgstr "|A|Введите новый PIN для стандартных ключей."
+msgstr "|A|Введите Admin PIN на клавиатуре считывателя"
 
+#, fuzzy
 msgid "||Please enter the PIN for the standard keys."
-msgstr "|A|Введите PIN для стандартных ключей."
+msgstr "|A|Введите Admin PIN на клавиатуре считывателя"
 
+#, fuzzy
 msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|NP|Введите новый код разблокировки PIN (PUK) для стандартных ключей."
+msgstr "||Введите Reset Code к карте"
 
+#, fuzzy
 msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|P|Введите код разблокировки PIN (PUK) для стандартных ключей."
+msgstr "||Введите Reset Code к карте"
 
 msgid "|N|Please enter a new PIN for the key to create qualified signatures."
-msgstr "|N|Введите новый PIN ключа для создания квалифицированных подписей."
+msgstr ""
 
 msgid "||Please enter the PIN for the key to create qualified signatures."
-msgstr "||Введите PIN ключа для создания квалифицированных подписей."
+msgstr ""
 
 msgid ""
 "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Введите новый код разблокировки PIN (PUK) ключа для создания "
-"квалифицированных подписей."
 
 msgid ""
 "|P|Please enter the PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|P|Введите код разблокировки PIN (PUK) ключа для создания квалифицированных "
-"подписей."
 
 #, c-format
 msgid "error getting new PIN: %s\n"
@@ -5422,15 +5234,15 @@ msgstr "ошибка при получении нового PIN: %s\n"
 
 #, c-format
 msgid "failed to store the fingerprint: %s\n"
-msgstr "сбой при сохранении отпечатка: %s\n"
+msgstr "сбой сохранения отпечатка: %s\n"
 
 #, c-format
 msgid "failed to store the creation date: %s\n"
-msgstr "сбой при сохранении даты создания: %s\n"
+msgstr "сбой сохранения даты создания: %s\n"
 
 #, c-format
 msgid "reading public key failed: %s\n"
-msgstr "сбой при чтении ключа: %s\n"
+msgstr "сбой чтения открытого ключа: %s\n"
 
 msgid "response does not contain the public key data\n"
 msgstr "ответ не содержит данных открытого ключа\n"
@@ -5443,13 +5255,11 @@ msgstr "в ответе отсутствует открытая экспонен
 
 #, c-format
 msgid "using default PIN as %s\n"
-msgstr "основной PIN применяется как %s\n"
+msgstr ""
 
 #, c-format
 msgid "failed to use default PIN as %s: %s - disabling further default use\n"
 msgstr ""
-"не удалось применить основной PIN как %s: %s - далее применяться\n"
-"как основной не будет\n"
 
 #, c-format
 msgid "||Please enter the PIN%%0A[sigs done: %lu]"
@@ -5464,7 +5274,7 @@ msgstr "PIN для CHV%d слишком короток, минимальная 
 
 #, c-format
 msgid "verify CHV%d failed: %s\n"
-msgstr "сбой при проверке CHV%d: %s\n"
+msgstr "при проверке CHV%d сбой: %s\n"
 
 msgid "error retrieving CHV status from card\n"
 msgstr "ошибка получения статуса CHV с карты\n"
@@ -5474,33 +5284,31 @@ msgstr "карта заблокирована!\n"
 
 #, c-format
 msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
-msgstr ""
-"осталось %d попыток ввода административного PIN перед блокировкой карты\n"
+msgstr "осталось %d попыток ввода административного PIN до блокировки карты\n"
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %%0A to force a linefeed.
-#, c-format
+#, fuzzy, c-format
 msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-msgstr "|A|Введите административный PIN%%0A[осталось попыток: %d]"
+msgstr ""
+"|A|Введите Admin PID на клавиатуре считывателя%%0A[осталось попыток: %d]"
 
+#, fuzzy
 msgid "|A|Please enter the Admin PIN"
-msgstr "|A|Введите административный PIN"
+msgstr "||Введите PIN"
 
 msgid "access to admin commands is not configured\n"
 msgstr "доступ к командам управления не настроен\n"
 
 msgid "||Please enter the Reset Code for the card"
-msgstr "||Введите код сброса для карты"
+msgstr "||Введите Reset Code к карте"
 
 #, c-format
 msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "Код сброса слишком короток; минимальная длина %d\n"
+msgstr "Reset Code слишком короток, минимальная длина %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
-msgstr "|RN|Новый код сброса"
+msgstr "|RN| Новый Reset Code"
 
 msgid "|AN|New Admin PIN"
 msgstr "|AN|Новый административный PIN"
@@ -5508,12 +5316,6 @@ msgstr "|AN|Новый административный PIN"
 msgid "|N|New PIN"
 msgstr "|N|Новый PIN"
 
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "|A|Введите административный PIN и новый административный PIN"
-
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Введите PIN и новый PIN"
-
 msgid "error reading application data\n"
 msgstr "ошибка чтения данных приложения\n"
 
@@ -5529,15 +5331,16 @@ msgstr "существующий ключ будет заменен\n"
 msgid "generating new key\n"
 msgstr "генерация нового ключа\n"
 
+#, fuzzy
 msgid "writing new key\n"
-msgstr "запиÑ\81Ñ\8c нового ключа\n"
+msgstr "генеÑ\80аÑ\86иÑ\8f нового ключа\n"
 
 msgid "creation timestamp missing\n"
-msgstr "пропущена метка времени создания\n"
+msgstr "пропущен штамп создания создания\n"
 
 #, c-format
 msgid "RSA prime %s missing or not of size %d bits\n"
-msgstr "Ð\9fÑ\80оÑ\81Ñ\82ое Ñ\87иÑ\81ло RSA %s Ð¿Ñ\80опÑ\83Ñ\89ено Ð¸Ð»Ð¸ ÐµÐ³Ð¾ Ñ\80азмеÑ\80 Ð½Ðµ Ñ\80авен %d бит\n"
+msgstr "Ð\9fÑ\80оÑ\81Ñ\82ое Ñ\87иÑ\81ло RSA %s Ð¿Ñ\80опÑ\83Ñ\89ено Ð¸Ð»Ð¸ Ð½Ðµ Ð¸Ð¼ÐµÐµÑ\82 Ñ\80азмеÑ\80 %d бит\n"
 
 #, c-format
 msgid "failed to store the key: %s\n"
@@ -5551,21 +5354,21 @@ msgstr "сбой при генерации ключа\n"
 
 #, c-format
 msgid "key generation completed (%d seconds)\n"
-msgstr "создание ключа завершено (%d секунд)\n"
+msgstr "ключ сгенерирован (%d секунд)\n"
 
 msgid "invalid structure of OpenPGP card (DO 0x93)\n"
-msgstr "недопÑ\83Ñ\81Ñ\82имаÑ\8f Ñ\81Ñ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80а ÐºÐ°Ñ\80Ñ\82Ñ\8b OpenPGP (DO 0x93)\n"
+msgstr "недопÑ\83Ñ\82имаÑ\8f Ñ\81Ñ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80а OpenPGP ÐºÐ°Ñ\80Ñ\82Ñ\8b (DO 0x93)\n"
 
 msgid "fingerprint on card does not match requested one\n"
-msgstr "отпечаток на карте не совпадает с запрошенным\n"
+msgstr ""
 
 #, c-format
 msgid "card does not support digest algorithm %s\n"
-msgstr "каÑ\80Ñ\82а Ð½Ðµ Ð¿Ð¾Ð´Ð´ÐµÑ\80живаеÑ\82 Ñ\85Ñ\8dÑ\88\84Ñ\83нкÑ\86иÑ\8e %s\n"
+msgstr "каÑ\80Ñ\82а Ð½Ðµ Ð¿Ð¾Ð´Ð´ÐµÑ\80живаеÑ\82 Ñ\84Ñ\83нкÑ\86иÑ\8e Ñ\85еÑ\88иÑ\80ованиÑ\8f %s\n"
 
 #, c-format
 msgid "signatures created so far: %lu\n"
-msgstr "создано подписей: %lu\n"
+msgstr "подписей создано: %lu\n"
 
 msgid ""
 "verification of Admin PIN is currently prohibited through this command\n"
@@ -5574,52 +5377,50 @@ msgstr ""
 
 #, c-format
 msgid "can't access %s - invalid OpenPGP card?\n"
-msgstr "нет доступа %s - непригодная карта OpenPGP?\n"
+msgstr "нет доступа %s - неработоспособная карта OpenPGP?\n"
 
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||Введите PIN на клавиатуре считывателя"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
 #. to get some infos on the string.
 msgid "|N|Initial New PIN"
-msgstr "|N|Ð\9fеÑ\80вонаÑ\87алÑ\8cнÑ\8bй Ð½овый PIN"
+msgstr "|N|Ð\9dовый PIN"
 
 msgid "run in multi server mode (foreground)"
-msgstr "работать в многосерверном режиме (нефоновый режим)"
+msgstr ""
 
 msgid "|LEVEL|set the debugging level to LEVEL"
-msgstr "|LEVEL|установить уровень отладки, равный LEVEL"
+msgstr "|LEVEL|установить уровень отладки в LEVEL"
 
 msgid "|FILE|write a log to FILE"
-msgstr "|FILE|сохранять журнал в файл FILE"
+msgstr "|FILE|сохранять журнал в FILE"
 
 msgid "|N|connect to reader at port N"
-msgstr "|N|подключаться к считывателю на порту N"
+msgstr "|N|подключаться к считывателю на порт N"
 
 msgid "|NAME|use NAME as ct-API driver"
-msgstr "|NAME|использовать NAME как драйвер ct-API"
+msgstr ""
 
 msgid "|NAME|use NAME as PC/SC driver"
-msgstr "|NAME|использовать NAME как драйвер PC/SC"
+msgstr ""
 
 msgid "do not use the internal CCID driver"
-msgstr "не использовать внутренний драйвер CCID"
+msgstr "не использовать встроенный CCID драйвер"
 
 msgid "|N|disconnect the card after N seconds of inactivity"
-msgstr "|N|отключить карту после N секунд неактивности"
+msgstr "|N|отсоединить карту по истечении N секунд неактивности"
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr "не использовать клавиатуру считывателя"
 
+#, fuzzy
 msgid "deny the use of admin card commands"
-msgstr "не позволять использовать административные команды карты"
-
-msgid "use variable length input for pinpad"
-msgstr "использовать входные данные переменой длины для клавиатуры считывателя"
+msgstr "позволить использовать управляющие команды"
 
 msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: scdaemon [параметры] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: scdaemon [параметры] (-h для подсказки)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
@@ -5628,7 +5429,7 @@ msgstr ""
 "Синтаксис: scdaemon [параметры] [команда [аргументы]]\n"
 "Демон смарткарт для GnuPG\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 "Используйте параметр `--daemon' для запуска приложения в фоновом режиме\n"
 
@@ -5646,11 +5447,11 @@ msgstr "недопустимый символ radix64 %02X пропущен\n"
 
 #, c-format
 msgid "failed to proxy %s inquiry to client\n"
-msgstr "сбой при трансляции запроса %s клиенту\n"
+msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "dirmngr не выполняется - запуск `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
+msgstr "нет запущеного dirmngr - запуск `%s'\n"
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
 msgstr "неправильная переменная окружения GPG_AGENT_INFO\n"
@@ -5660,58 +5461,58 @@ msgid "dirmngr protocol version %d is not supported\n"
 msgstr "протокол dirmngr версии %d не поддерживается\n"
 
 msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr "не могу подключиться к dirmngr - пробую более надежный вариант\n"
+msgstr "не могу подсоединиться к dirmngr - пытаемся откатиться назад\n"
 
 #, c-format
 msgid "validation model requested by certificate: %s"
-msgstr "схема проверки, запрошенная сертификатом: %s"
+msgstr ""
 
 msgid "chain"
-msgstr "цепь"
+msgstr ""
 
 msgid "shell"
-msgstr "оболочка"
+msgstr ""
 
 #, c-format
 msgid "critical certificate extension %s is not supported"
-msgstr "критичное расширение сертификата %s не поддерживается"
+msgstr "критичное дополнение сертификата %s не поддерживается"
 
 msgid "issuer certificate is not marked as a CA"
-msgstr "издатель сертификата не помечен как центр сертификации"
+msgstr "издатель сертификата не помечен как CA"
 
 msgid "critical marked policy without configured policies"
-msgstr "незаданнÑ\8bе Ð¿Ñ\80авила Ð¿Ð¾Ð¼ÐµÑ\87енÑ\8b ÐºÐ°Ðº ÐºÑ\80иÑ\82иÑ\87нÑ\8bе"
+msgstr "помеÑ\87еннаÑ\8f ÐºÑ\80иÑ\82иÑ\87ной Ð¿Ð¾Ð»Ð¸Ñ\82ика Ð±ÐµÐ· Ð½Ð°Ñ\81Ñ\82Ñ\80оеннÑ\8bÑ\85 Ð¿Ð¾Ð»Ð¸Ñ\82ик"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "не могу открыть `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
-msgstr "замечание: некритичные правила сертификата недопустимы"
+msgstr "замечание: не критичные политики сертификана не позволяются"
 
 msgid "certificate policy not allowed"
-msgstr "правила сертификата недопустимы"
+msgstr "политика сертификата не дозволена"
 
 msgid "looking up issuer at external location\n"
-msgstr "внешний поиск издателя\n"
+msgstr ""
 
 #, c-format
 msgid "number of issuers matching: %d\n"
-msgstr "Ñ\87иÑ\81ло Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89их издателей: %d\n"
+msgstr "Ñ\87иÑ\81ло Ñ\81овпавÑ\88их издателей: %d\n"
 
 msgid "looking up issuer from the Dirmngr cache\n"
-msgstr "поиск издателя в буфере Dirmngr\n"
+msgstr ""
 
 #, c-format
 msgid "number of matching certificates: %d\n"
-msgstr "Ñ\87иÑ\81ло Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89иÑ\85 сертификатов: %d\n"
+msgstr "Ñ\87иÑ\81ло Ñ\81ооÑ\82веÑ\81Ñ\82вий сертификатов: %d\n"
 
 #, c-format
 msgid "dirmngr cache-only key lookup failed: %s\n"
-msgstr "ключ не найден в буфере dirmngr: %s\n"
+msgstr ""
 
-msgid "failed to allocate keyDB handle\n"
-msgstr "сбой при выделении памяти под указатель на базу данных\n"
+msgid "failed to allocated keyDB handle\n"
+msgstr ""
 
 msgid "certificate has been revoked"
 msgstr "сертификат был отозван"
@@ -5724,20 +5525,20 @@ msgstr "проверьте, что \"dirmngr\" установлен коррек
 
 #, c-format
 msgid "checking the CRL failed: %s"
-msgstr "сбой проверки списка отозванных сертификатов: %s"
+msgstr "сбой проверки CRL: %s"
 
 #, c-format
 msgid "certificate with invalid validity: %s"
-msgstr "сертификат с недействительной действительностью: %s"
+msgstr "сертификат недостоверный: %s"
 
 msgid "certificate not yet valid"
-msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 ÐµÑ\89е Ð½Ðµ Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елен"
+msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 ÐµÑ\89е Ð½Ðµ Ð´Ð¾Ñ\81Ñ\82овеÑ\80ен"
 
 msgid "root certificate not yet valid"
-msgstr "коÑ\80невой Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 ÐµÑ\89е Ð½Ðµ Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елен"
+msgstr "коÑ\80невой Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 ÐµÑ\89е Ð½Ðµ Ð´Ð¾Ñ\81Ñ\82овеÑ\80ен"
 
 msgid "intermediate certificate not yet valid"
-msgstr "пÑ\80омежÑ\83Ñ\82оÑ\87нÑ\8bй Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 ÐµÑ\89е Ð½Ðµ Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елен"
+msgstr "пÑ\80омежÑ\83Ñ\82оÑ\87нÑ\8bй Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 ÐµÑ\89е Ð½Ðµ Ð´Ð¾Ñ\81Ñ\82овеÑ\80ен"
 
 msgid "certificate has expired"
 msgstr "сертификат просрочен"
@@ -5753,62 +5554,61 @@ msgid "required certificate attributes missing: %s%s%s"
 msgstr "сертификат не имеет требуемых атрибутов: %s%s%s"
 
 msgid "certificate with invalid validity"
-msgstr "сертификат с недействительной действительностью"
+msgstr "сертификат недостоверен"
 
 msgid "signature not created during lifetime of certificate"
-msgstr "подпиÑ\81Ñ\8c Ñ\81оздана Ð²Ð½Ðµ Ð²Ñ\80емени Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f сертификата"
+msgstr "подпиÑ\81Ñ\8c Ñ\81оздана Ð²Ð½Ðµ Ð²Ñ\80емени Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и сертификата"
 
 msgid "certificate not created during lifetime of issuer"
-msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\81оздан Ð²Ð½Ðµ Ð²Ñ\80емени Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f издателя"
+msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\81оздан Ð²Ð½Ðµ Ð²Ñ\80емени Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и издателя"
 
 msgid "intermediate certificate not created during lifetime of issuer"
-msgstr "пÑ\80омежÑ\83Ñ\82оÑ\87нÑ\8bй Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\81оздан Ð²Ð½Ðµ Ð²Ñ\80емени Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\8f издателя"
+msgstr "пÑ\80омежÑ\83Ñ\82оÑ\87нÑ\8bй Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\81оздан Ð²Ð½Ðµ Ð²Ñ\80емени Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елÑ\8cноÑ\81Ñ\82и издателя"
 
 msgid "  (  signature created at "
-msgstr "  (          подпись создана "
+msgstr "  (  подписей создано "
 
 msgid "  (certificate created at "
-msgstr "  (        сертификат создан "
+msgstr "  (сертификатов создано "
 
 msgid "  (certificate valid from "
-msgstr "  (Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð´ÐµÐ¹Ñ\81Ñ\82виÑ\82елен с "
+msgstr "  (Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð´Ð¾Ñ\81Ñ\82овеÑ\80ен с "
 
 msgid "  (     issuer valid from "
-msgstr "  (  издатель действителен с "
+msgstr "  (     издатель достоверен с "
 
 #, c-format
 msgid "fingerprint=%s\n"
 msgstr "отпечаток=%s\n"
 
 msgid "root certificate has now been marked as trusted\n"
-msgstr "коÑ\80невой Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\82епеÑ\80Ñ\8c Ð¿Ð¾Ð¼ÐµÑ\87ен ÐºÐ°Ðº Ð´Ð¾Ð²ÐµÑ\80еннÑ\8bй\n"
+msgstr "коÑ\80невой Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\82епеÑ\80Ñ\8c Ð¿Ð¾Ð¼ÐµÑ\87ен Ð´Ð¾Ð²ÐµÑ\80Ñ\8fемÑ\8bм\n"
 
 msgid "interactive marking as trusted not enabled in gpg-agent\n"
-msgstr "в агенте gpg нельзя интерактивно сделать сертификат доверенным\n"
+msgstr "в gpg-agent нельзя сделать сертификат доверяемым интерактивно\n"
 
 msgid "interactive marking as trusted disabled for this session\n"
 msgstr ""
-"длÑ\8f Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñ\81еанÑ\81а Ð·Ð°Ð¿Ñ\80еÑ\89ено Ð¸Ð½Ñ\82еÑ\80акÑ\82ивно Ð´ÐµÐ»Ð°Ñ\82Ñ\8c Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð´Ð¾Ð²ÐµÑ\80еннÑ\8bм\n"
+"длÑ\8f Ð´Ð°Ð½Ð½Ð¾Ð¹ Ñ\81еÑ\81Ñ\81ии Ð·Ð°Ð¿Ñ\80еÑ\89ено Ð´ÐµÐ»Ð°Ñ\82Ñ\8c Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð´Ð¾Ð²ÐµÑ\80Ñ\8fемÑ\8bм Ð¸Ð½Ñ\82еÑ\80акÑ\82ивно\n"
 
 msgid "WARNING: creation time of signature not known - assuming current time"
 msgstr ""
-"ВНИМАНИЕ: время создания подписи неизвестно - предполагается текущий момент"
 
 msgid "no issuer found in certificate"
-msgstr "в Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82е Ð½Ðµ Ð½Ð°Ð¹Ð´ÐµÐ½ Ð¸Ð·Ð´Ð°Ñ\82елÑ\8c"
+msgstr "не Ð½Ð°Ð¹Ð´ÐµÐ½ Ð¸Ð·Ð´Ð°Ñ\82елÑ\8c Ð² Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82е"
 
 msgid "self-signed certificate has a BAD signature"
-msgstr "Ñ\83 Ñ\81амозавеÑ\80енного Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82а Ð\9fÐ\9bÐ\9eÐ¥Ð\90Я подпись"
+msgstr "Ñ\81амоподпиÑ\81аннÑ\8bй\tÑ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð¸Ð¼ÐµÐµÑ\82 Ð\9fÐ\9bÐ\9eХУЮ подпись"
 
 msgid "root certificate is not marked trusted"
-msgstr "коÑ\80невой Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð½Ðµ Ð¿Ð¾Ð¼ÐµÑ\87ен ÐºÐ°Ðº Ð´Ð¾Ð²ÐµÑ\80еннÑ\8bй"
+msgstr "коÑ\80невой Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð½Ðµ Ð¿Ð¾Ð¼ÐµÑ\87ен Ð´Ð¾Ð²ÐµÑ\80Ñ\8fемÑ\8bм"
 
 #, c-format
 msgid "checking the trust list failed: %s\n"
-msgstr "сбой проверки списка доверия: %s\n"
+msgstr "сбой проверки списка доверий: %s\n"
 
 msgid "certificate chain too long\n"
-msgstr "Ñ\81лиÑ\88ком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ\8f Ñ\86епоÑ\87ка Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82ов\n"
+msgstr "Ñ\86епоÑ\87ка Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\86ии Ñ\81лиÑ\88ком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ\8f\n"
 
 msgid "issuer certificate not found"
 msgstr "не найден издатель сертификата"
@@ -5817,39 +5617,38 @@ msgid "certificate has a BAD signature"
 msgstr "сертификат имеет ПЛОХУЮ подпись"
 
 msgid "found another possible matching CA certificate - trying again"
-msgstr ""
-"найден еще один возможный сертификат центра сертификации - повторная попытка"
+msgstr "найдено еще одно соответствие CA  сертификата - повторная попытки"
 
 #, c-format
 msgid "certificate chain longer than allowed by CA (%d)"
-msgstr "Ñ\86епоÑ\87ка Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82ов Ð´Ð»Ð¸Ð½Ð½ÐµÐµ Ð´Ð¾Ð¿Ñ\83Ñ\81каемой Ñ\86енÑ\82Ñ\80ом Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\86ии (%d)"
+msgstr "Ñ\86епоÑ\87ка Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\86ии Ð´Ð»Ð¸Ð½Ð½ÐµÐµ Ð´Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð½Ð¾Ð¹ CA (%d)"
 
 msgid "certificate is good\n"
-msgstr "хороший сертификат\n"
+msgstr ""
 
 msgid "intermediate certificate is good\n"
-msgstr "хороший промежуточный сертификат\n"
+msgstr ""
 
 msgid "root certificate is good\n"
-msgstr "хороший корневой сертификат\n"
+msgstr ""
 
 msgid "switching to chain model"
-msgstr "переключение на цепную схему"
+msgstr ""
 
 #, c-format
 msgid "validation model used: %s"
-msgstr "используется схема проверки: %s"
+msgstr ""
 
 #, c-format
 msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "%s ключ использует небезопасный (%u бит) хэш\n"
+msgstr "%s ключ использует небезопасный (%u бит) хеш\n"
 
 #, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
-msgstr "%u-битный хэш недопустим для %u-битного ключа %s\n"
+msgstr ""
 
 msgid "(this is the MD2 algorithm)\n"
-msgstr "(это алгоритм MD2)\n"
+msgstr "(это MD2 алгоритм)\n"
 
 msgid "none"
 msgstr "нет"
@@ -5858,7 +5657,7 @@ msgid "[Error - invalid encoding]"
 msgstr "[Ошибка - недопустимая кодировка]"
 
 msgid "[Error - out of core]"
-msgstr "[Ошибка - нехватка выделенной памяти]"
+msgstr ""
 
 msgid "[Error - No name]"
 msgstr "[Ошибка - Нет имени]"
@@ -5874,8 +5673,8 @@ msgid ""
 "S/N %s, ID 0x%08lX,\n"
 "created %s, expires %s.\n"
 msgstr ""
-"Введите фразу-пароль для доступа к закрытому ключу сертификата X.509:\n"
-"\"%s\"\n"
+"Введите фразу-пароль для доступа к секретному ключу к X.509 сертификату:\"%s"
+"\"\n"
 "S/N %s, ID 0x%08lX,\n"
 "создан %s, истекает %s.\n"
 
@@ -5886,23 +5685,23 @@ msgstr "не задана применимость ключа - подразум
 msgid "error getting key usage information: %s\n"
 msgstr "ошибка получения информации применимости ключа: %s\n"
 
-msgid "certificate should not have been used for certification\n"
-msgstr "сертификат не следовало использовать для сертификации\n"
+msgid "certificate should have not been used for certification\n"
+msgstr "сертификат не следует использовать для сертификации\n"
 
-msgid "certificate should not have been used for OCSP response signing\n"
-msgstr "сертификат не следовало использовать для подписывания ответа OCSP\n"
+msgid "certificate should have not been used for OCSP response signing\n"
+msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
-msgstr "сертификат не следовало использовать для шифрования\n"
+msgid "certificate should have not been used for encryption\n"
+msgstr "сертификат не следует использовать для шифрования\n"
 
-msgid "certificate should not have been used for signing\n"
-msgstr "сертификат не следовало использовать для подписей\n"
+msgid "certificate should have not been used for signing\n"
+msgstr "сертификат не следует использовать для подписывания\n"
 
 msgid "certificate is not usable for encryption\n"
-msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð½Ðµ Ð¿Ñ\80игоден для шифрования\n"
+msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð½Ðµ Ð¿Ñ\80именим для шифрования\n"
 
 msgid "certificate is not usable for signing\n"
-msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð½Ðµ Ð¿Ñ\80игоден для подписи\n"
+msgstr "Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 Ð½Ðµ Ð¿Ñ\80именим для подписи\n"
 
 #, c-format
 msgid "line %d: invalid algorithm\n"
@@ -5914,38 +5713,36 @@ msgstr "строка %d: недопустимая длина ключа %u (до
 
 #, c-format
 msgid "line %d: no subject name given\n"
-msgstr "строка %d: не задано имя субъекта\n"
+msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
-msgstr "строка %d: недопустимая метка имени субъекта `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
+msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
-msgstr "строка %d: недопустимое имя субъекта `%s' в позиции %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
+msgstr ""
 
 #, c-format
 msgid "line %d: not a valid email address\n"
-msgstr "строка %d: нет допустимого адреса электронной почты\n"
+msgstr "строка %d: нет допустимого e-mail адреса\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "строка %d: ошибка получения ключа `%s' из карты %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
-msgstr "строка %d: ошибка получения кода ключа `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
+msgstr "строка %d: ошибка получения keygrip ключа `%s': %s\n"
 
 #, c-format
 msgid "line %d: key generation failed: %s <%s>\n"
-msgstr "строка %d: сбой создания ключа: %s <%s>\n"
+msgstr "строка %d: cбой создания ключа: %s <%s>\n"
 
 msgid ""
 "To complete this certificate request please enter the passphrase for the key "
 "you just created once more.\n"
 msgstr ""
-"Чтобы завершить создание этого запроса сертификата, введите фразу-пароль для "
-"ключа, который вы только что создали, еще раз.\n"
 
 #, c-format
 msgid "   (%d) RSA\n"
@@ -5959,25 +5756,28 @@ msgstr "   (%d) Имеющийся ключ\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Имеющийся на карте ключ\n"
 
+#, fuzzy
 msgid "Enter the keygrip: "
-msgstr "Ð\92ведиÑ\82е ÐºÐ¾Ð´ ÐºÐ»Ñ\8eÑ\87а:"
+msgstr "Ð\92ведиÑ\82е Ð¿Ñ\80имеÑ\87ание:"
 
 msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Недопустимый код ключа (ожидается 40 шестнадцатеричных цифр)\n"
+msgstr ""
 
+#, fuzzy
 msgid "No key with this keygrip\n"
-msgstr "Ð\9dеÑ\82 ÐºÐ»Ñ\8eÑ\87а Ñ\81 Ñ\82аким ÐºÐ¾Ð´Ð¾Ð¼\n"
+msgstr "Ð\9dеÑ\82 Ð¿Ð¾Ð´ÐºÐ»Ñ\8eÑ\87а Ñ\81 Ð¸Ð½Ð´ÐµÐºÑ\81ом %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading the card: %s\n"
-msgstr "ошибка чтения карты: %s\n"
+msgstr "%s: ошибка чтения свободной записи: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Serial number of the card: %s\n"
-msgstr "СеÑ\80ийнÑ\8bй Ð½Ð¾Ð¼ÐµÑ\80 карты: %s\n"
+msgstr "оÑ\88ибка Ð¿Ð¾Ð»Ñ\83Ñ\87ениÑ\8f Ñ\81еÑ\80ийного Ð½Ð¾Ð¼ÐµÑ\80а карты: %s\n"
 
+#, fuzzy
 msgid "Available keys:\n"
-msgstr "Ð\94оÑ\81Ñ\82Ñ\83пнÑ\8bе ÐºÐ»Ñ\8eÑ\87и:\n"
+msgstr "оÑ\82клÑ\8eÑ\87иÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87"
 
 #, c-format
 msgid "Possible actions for a %s key:\n"
@@ -5996,14 +5796,14 @@ msgid "   (%d) encrypt\n"
 msgstr "   (%d) шифрование\n"
 
 msgid "Enter the X.509 subject name: "
-msgstr "Введите имя субъекта X.509: "
+msgstr ""
 
 msgid "No subject name given\n"
-msgstr "Не задано имя субъекта\n"
+msgstr ""
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
-msgstr "Недопустимая метка имени субъекта `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
+msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
 #. length of the first string up to the "%s".  Please
@@ -6011,64 +5811,65 @@ msgstr "Недопустимая метка имени субъекта `%.*s'\n
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
-msgstr "Недопустимое имя субъекта `%s'\n"
+msgid "Invalid subject name '%s'\n"
+msgstr ""
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
-msgstr "33"
+msgstr ""
 
 msgid "Enter email addresses"
-msgstr "Введите адреса электронной почты"
+msgstr "Введите Email-адрес: "
 
 msgid " (end with an empty line):\n"
-msgstr "(завеÑ\80Ñ\88иÑ\82е Ð¿Ñ\83Ñ\81Ñ\82ой Ñ\81Ñ\82Ñ\80окой):\n"
+msgstr "(пÑ\83Ñ\81Ñ\82аÑ\8f Ñ\81Ñ\82Ñ\80ока Ð´Ð»Ñ\8f Ð·Ð°Ð²ÐµÑ\80Ñ\88ениÑ\8f):\n"
 
 msgid "Enter DNS names"
-msgstr "Введите имена DNS"
+msgstr "Введите DNS имя"
 
 msgid " (optional; end with an empty line):\n"
-msgstr " (необÑ\8fзаÑ\82елÑ\8cно; Ð·Ð°Ð²ÐµÑ\80Ñ\88иÑ\82е Ð¿Ñ\83Ñ\81Ñ\82ой Ñ\81Ñ\82Ñ\80окой):\n"
+msgstr " (опÑ\86ионаÑ\8cно; Ð¿Ñ\83Ñ\81Ñ\82аÑ\8f Ñ\81Ñ\82Ñ\80ока Ð´Ð»Ñ\8f Ð·Ð°Ð²ÐµÑ\80Ñ\88ениÑ\8f):\n"
 
 msgid "Enter URIs"
-msgstr "Введите URI"
+msgstr "Введите URIs"
 
 msgid "Parameters to be used for the certificate request:\n"
-msgstr "Ð\9fаÑ\80амеÑ\82Ñ\80Ñ\8b Ð´Ð»Ñ\8f Ð·Ð°Ð¿Ñ\80оÑ\81а Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82а:\n"
+msgstr "Ð\9fаÑ\80амеÑ\82Ñ\80Ñ\8b Ð½ÐµÐ¾Ð±Ñ\85одимÑ\8bе Ð´Ð»Ñ\8f Ñ\81озданиÑ\8f Ð·Ð°Ð¿Ñ\80оÑ\81а Ð½Ð° Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\86иÑ\8e:\n"
 
 msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr "Создается запрос сертификата. Это может занять немного времени...\n"
+msgstr ""
+"Создается запрос на сертификацию. Это может занять немного времени...\n"
 
 msgid "Ready.  You should now send this request to your CA.\n"
-msgstr "Ð\93оÑ\82ово. Ð\94аннÑ\8bй Ð·Ð°Ð¿Ñ\80оÑ\81 Ñ\82епеÑ\80Ñ\8c Ñ\81ледÑ\83еÑ\82 Ð¿ÐµÑ\80едаÑ\82Ñ\8c Ð² Ñ\86енÑ\82Ñ\80 Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\86ии.\n"
+msgstr "Ð\93оÑ\82ово. Ð\94аннÑ\8bй Ð·Ð°Ð¿Ñ\80оÑ\81 Ñ\82епеÑ\80Ñ\8c Ñ\81ледÑ\83еÑ\82 Ð¿ÐµÑ\80едаÑ\82Ñ\8c Ð½Ð° Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81Ñ\8c Ð² CA.\n"
 
 msgid "resource problem: out of core\n"
-msgstr "проблема ресурсов: нехватка выделенной памяти\n"
+msgstr ""
 
 msgid "(this is the RC2 algorithm)\n"
-msgstr "(это алгоритм RC2)\n"
+msgstr "(это RC2 алгоритм)\n"
 
 msgid "(this does not seem to be an encrypted message)\n"
-msgstr "(Ñ\8dÑ\82о Ð½Ðµ Ð¿Ð¾Ñ\85оже Ð½Ð° зашифрованное сообщение)\n"
+msgstr "(Ñ\8dÑ\82о Ð½Ðµ Ð¿Ð¾Ñ\85оже Ð½Ðµ зашифрованное сообщение)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "сертификат `%s' не найден: %s\n"
 
 #, c-format
 msgid "error locking keybox: %s\n"
-msgstr "ошибка блокировки щита с ключами: %s\n"
+msgstr "ошибка блокировки keybox: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
-msgstr "пÑ\80одÑ\83блиÑ\80ованнÑ\8bй Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 `%s' удален\n"
+msgid "duplicated certificate '%s' deleted\n"
+msgstr "дÑ\83пликаÑ\82 Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82а `%s' удален\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "сертификат `%s' удален\n"
 
 #, c-format
 msgid "deleting certificate \"%s\" failed: %s\n"
-msgstr "Ñ\81бой Ð¿Ñ\80и Ñ\83далении Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82а \"%s\": %s\n"
+msgstr "Ñ\83даление Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82а \"%s\" Ð½ÐµÑ\83даÑ\87но: %s\n"
 
 msgid "no valid recipients given\n"
 msgstr "не заданы получатели\n"
@@ -6077,7 +5878,7 @@ msgid "list external keys"
 msgstr "вывести список внешних ключей"
 
 msgid "list certificate chain"
-msgstr "вывести список цепочек сертификатов"
+msgstr "вывести список правил сертификатов"
 
 msgid "import certificates"
 msgstr "импорт сертификатов"
@@ -6094,124 +5895,127 @@ msgstr "передать команду dirmngr"
 msgid "invoke gpg-protect-tool"
 msgstr "вызываем gpg-protect-tool"
 
+msgid "change a passphrase"
+msgstr "сменить фразу-пароль"
+
 msgid "create base-64 encoded output"
-msgstr "вывод в base-64"
+msgstr "вывод в BASE64"
 
 msgid "assume input is in PEM format"
-msgstr "предполагаю, что входные данные в формате PEM"
+msgstr "предполагаем получение в формате PEM"
 
 msgid "assume input is in base-64 format"
-msgstr "предполагаю, что входные данные в формате base-64"
+msgstr "предполагаем получение в формате BASE64"
 
 msgid "assume input is in binary format"
-msgstr "предполагаю, что входные данные в двоичном формате"
+msgstr "предполагаем получение в двоичном формате"
 
 msgid "use system's dirmngr if available"
 msgstr "используем системный dirmngr, если доступен"
 
 msgid "never consult a CRL"
-msgstr "не сверять со списком отозванных сертификатов"
+msgstr "не сверять с CRL"
 
 msgid "check validity using OCSP"
-msgstr "проверка действительности с помощью OCSP"
+msgstr "проверка действительности используя OCSP"
 
 msgid "|N|number of certificates to include"
 msgstr "|N|число включаемых сертификатов"
 
 msgid "|FILE|take policy information from FILE"
-msgstr "|FILE|взять информацию о правилах из файла FILE"
+msgstr "|FILE|взять информацию о политиках из FILE"
 
 msgid "do not check certificate policies"
-msgstr "не проверять правила сертификата"
+msgstr "не проверять политики сертификата"
 
 msgid "fetch missing issuer certificates"
-msgstr "запÑ\80оÑ\81иÑ\82Ñ\8c Ð½ÐµÐ´Ð¾Ñ\81Ñ\82аÑ\8eÑ\89иÑ\85 Ð¸Ð·Ð´Ð°Ñ\82елей сертификатов"
+msgstr "запÑ\80оÑ\81иÑ\82Ñ\8c Ð¿Ñ\80опÑ\83Ñ\89еннÑ\8bÑ\85 Ð¸Ð·Ð´Ð°Ñ\82алей сертификатов"
 
 msgid "don't use the terminal at all"
 msgstr "не использовать терминал совсем"
 
 msgid "|FILE|write a server mode log to FILE"
-msgstr "|FILE|сохранять журнал режима сервера в файле FILE"
+msgstr "|FILE|сохранять журнал режима сервера в FILE"
 
 msgid "|FILE|write an audit log to FILE"
-msgstr "|FILE|сохранять журнал аудита в файле FILE"
+msgstr "|FILE|сохранять журнал аудита в FILE"
 
 msgid "batch mode: never ask"
-msgstr "пакетный режим: ничего не спрашивать"
+msgstr "пакетный режим: ничего не запрашивать"
 
 msgid "assume yes on most questions"
-msgstr "пÑ\80инÑ\8fÑ\82Ñ\8c `да' ÐºÐ°Ðº Ð¾Ñ\82веÑ\82 на большинство вопросов"
+msgstr "пÑ\80едполагаÑ\82Ñ\8c Ð\94а на большинство вопросов"
 
 msgid "assume no on most questions"
-msgstr "пÑ\80инÑ\8fÑ\82Ñ\8c `неÑ\82' ÐºÐ°Ðº Ð¾Ñ\82вет на большинство вопросов"
+msgstr "пÑ\80едполагаÑ\82Ñ\8c Ð\9dет на большинство вопросов"
 
 msgid "|FILE|add keyring to the list of keyrings"
 msgstr "|FILE|добавить таблицу ключей в список таблиц ключей"
 
 msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|USER-ID|использовать USER-ID как основной закрытый ключ"
+msgstr "|USER-ID|использовать USER-ID как секретный ключ по умолчанию"
 
 msgid "|SPEC|use this keyserver to lookup keys"
-msgstr "|SPEC|иÑ\81каÑ\82Ñ\8c ÐºÐ»Ñ\8eÑ\87и Ð½Ð° Ð´Ð°Ð½Ð½Ð¾Ð¼ Ñ\81еÑ\80веÑ\80е ключей"
+msgstr "|SPEC|иÑ\81полÑ\8cзоваÑ\82Ñ\8c Ð´Ð°Ð½Ð½Ñ\8bй Ñ\81еÑ\80веÑ\80 ÐºÐ»Ñ\8eÑ\87ей Ð´Ð»Ñ\8f Ð¿Ð¾Ð¸Ñ\81ка ключей"
 
 msgid "|NAME|use cipher algorithm NAME"
 msgstr "|NAME|использовать алгоритм шифрования NAME"
 
 msgid "|NAME|use message digest algorithm NAME"
-msgstr "|NAME|использовать хэш-функцию NAME"
+msgstr "|NAME|использовать хеш-функцию NAME"
 
 msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: gpgsm [параметры] [файлы] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: gpgsm [параметры] [файлы] (-h для подсказки)"
 
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Синтаксис: gpgsm [параметры] [файлы]\n"
-"Ð\9fодпиÑ\81аÑ\82Ñ\8c, Ð¿Ñ\80овеÑ\80иÑ\82Ñ\8c, Ð·Ð°Ñ\88иÑ\84Ñ\80оваÑ\82Ñ\8c Ð¸Ð»Ð¸ Ñ\80аÑ\81Ñ\88иÑ\84Ñ\80оваÑ\82Ñ\8c, Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8f Ð¿Ñ\80оÑ\82окол S/"
-"MIME\n"
-"Ð\9eперация по умолчанию зависит от входных данных\n"
+"подпиÑ\81аÑ\82Ñ\8c Ð¸ Ð¿Ñ\80овеÑ\80иÑ\82Ñ\8c, Ð·Ð°Ñ\88иÑ\84Ñ\80оваÑ\82Ñ\8c Ð¸Ð»Ð¸ Ñ\80аÑ\81Ñ\88иÑ\84Ñ\80оваÑ\82Ñ\8c Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8f S/MIME "
+"протокол\n"
+"операция по умолчанию зависит от входных данных\n"
 
 msgid "usage: gpgsm [options] "
-msgstr "вÑ\8bзов: gpgsm [параметры] "
+msgstr "иÑ\81полÑ\8cзование: gpgsm [параметры] "
 
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
-msgstr "Ð\97Ð\90Ð\9cÐ\95ЧÐ\90Ð\9dÐ\98Ð\95: не могу зашифровать для `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
+msgstr "Ð\97амеÑ\87ание: не могу зашифровать для `%s': %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
-msgstr "неизвестная схема проверки `%s'\n"
+msgid "unknown validation model '%s'\n"
+msgstr ""
 
 #, c-format
 msgid "%s:%u: no hostname given\n"
-msgstr "%s:%u: не задан хост\n"
+msgstr ""
 
 #, c-format
 msgid "%s:%u: password given without user\n"
-msgstr "%s:%u: задан пароль, но не задан пользователь\n"
+msgstr ""
 
 #, c-format
 msgid "%s:%u: skipping this line\n"
-msgstr "%s:%u: Ð¿Ñ\80опÑ\83Ñ\81каÑ\8e эту строку\n"
+msgstr "%s:%u: Ð½Ðµ Ð¾Ð±Ñ\80абаÑ\82Ñ\8bваем эту строку\n"
 
 msgid "could not parse keyserver\n"
-msgstr "не удалось определить сервер ключей\n"
+msgstr ""
 
 msgid "WARNING: running with faked system time: "
-msgstr "ВНИМАНИЕ: работаем с фальшивым системным временем: "
+msgstr "ВНИМАНИЕ: выполняемся с подделанным системным временем: "
 
 #, c-format
-msgid "importing common certificates `%s'\n"
-msgstr "импорт общих сертификатов `%s'\n"
+msgid "importing common certificates '%s'\n"
+msgstr ""
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
-msgstr "невозможно подписать с помощью `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
+msgstr "невозможно подписать используя `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
-msgstr "недопустимая команда (неявной команды нет)\n"
+msgstr ""
 
 #, c-format
 msgid "total number processed: %lu\n"
@@ -6223,36 +6027,42 @@ msgstr "ошибка сохранения сертификата\n"
 msgid "basic certificate checks failed - not imported\n"
 msgstr "ошибка базовой проверки сертификата - не импортирован\n"
 
+msgid "failed to allocate keyDB handle\n"
+msgstr ""
+
 #, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "ошибка получения сохраненных флагов: %s\n"
 
 #, c-format
 msgid "error importing certificate: %s\n"
-msgstr "оÑ\88ибка Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82а сертификата: %s\n"
+msgstr "оÑ\88ибка Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82иÑ\80ованиÑ\8f сертификата: %s\n"
 
 #, c-format
 msgid "error reading input: %s\n"
 msgstr "ошибка чтения ввода: %s\n"
 
 #, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "ошибка создания щита с ключами `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
+msgstr "ошибка создания keybox `%s': %s\n"
+
+msgid "you may want to start the gpg-agent first\n"
+msgstr "возможно следует запустить gpg-agent сперва\n"
 
 #, c-format
-msgid "keybox `%s' created\n"
-msgstr "создан щит с ключами `%s'\n"
+msgid "keybox '%s' created\n"
+msgstr "создан keybox `%s'\n"
 
 msgid "failed to get the fingerprint\n"
 msgstr "сбой получения отпечатка\n"
 
 #, c-format
 msgid "problem looking for existing certificate: %s\n"
-msgstr "проблема поиска существующего сертификата: %s\n"
+msgstr ""
 
 #, c-format
 msgid "error finding writable keyDB: %s\n"
-msgstr "ошибка при поиске базы данных ключей: %s\n"
+msgstr ""
 
 #, c-format
 msgid "error storing certificate: %s\n"
@@ -6260,7 +6070,7 @@ msgstr "ошибка сохранения сертификата: %s\n"
 
 #, c-format
 msgid "problem re-searching certificate: %s\n"
-msgstr "проблема повторного поиска сертификата: %s\n"
+msgstr ""
 
 #, c-format
 msgid "error storing flags: %s\n"
@@ -6271,16 +6081,15 @@ msgstr "Ошибка - "
 
 msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
-"GPG_TTY не задан - пользуюсь установками по умолчанию (возможно, "
-"несуразными)\n"
+"GPG_TTY не установлено - возможно использование подделанного  умолчания\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
-msgstr "недопÑ\83Ñ\81Ñ\82имÑ\8bй Ñ\84оÑ\80маÑ\82 Ð¾Ñ\82пеÑ\87аÑ\82ка в `%s', строка %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
+msgstr "невеÑ\80ное Ñ\81Ñ\84оÑ\80маÑ\82иÑ\80ованнÑ\8bй Ð¾Ñ\82пеÑ\87аÑ\82ок в `%s', строка %d\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
-msgstr "недопустимый код страны в `%s', строка %d\n"
+msgid "invalid country code in '%s', line %d\n"
+msgstr "недопустисый код страны в `%s', строка %d\n"
 
 #, c-format
 msgid ""
@@ -6291,19 +6100,13 @@ msgid ""
 "\n"
 "%s%sAre you really sure that you want to do this?"
 msgstr ""
-"Вы делаете подпись с помощью своего сертификата:\n"
-"\"%s\"\n"
-"Будет создана квалифицированная подпись, по закону равнозначная "
-"собственноручной подписи.\n"
-"\n"
-"%s%sВы уверены, что хотите этого?"
 
 msgid ""
 "Note, that this software is not officially approved to create or verify such "
 "signatures.\n"
 msgstr ""
-"Учтите, что для данной программы создание и проверка подобных подписей "
-"оÑ\84иÑ\86иалÑ\8cно Ð½Ðµ Ð¾Ð´Ð¾Ð±Ñ\80енÑ\8b.\n"
+"Учтите, что для данной программы официально не одобрено создание и проверка "
+"подобнÑ\8bÑ\85 Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81ей.\n"
 
 #, c-format
 msgid ""
@@ -6311,101 +6114,98 @@ msgid ""
 "\"%s\"\n"
 "Note, that this certificate will NOT create a qualified signature!"
 msgstr ""
-"Вы делаете подпись с помощью своего сертификата:\n"
-"\"%s\"\n"
-"Обратите внимание, что этот сертификат НЕ создает квалифицированных подписей!"
 
 #, c-format
 msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n"
-msgstr "хэш-функция %d (%s) для %d не поддерживается; использую %s\n"
+msgstr "хеш-функция %d (%s) для %d не поддерживается; использую %s\n"
 
 #, c-format
 msgid "hash algorithm used for signer %d: %s (%s)\n"
-msgstr "хэш-функция для подписи %d: %s (%s)\n"
+msgstr ""
 
 #, c-format
 msgid "checking for qualified certificate failed: %s\n"
-msgstr "сбой при проверке квалифицированной подписи: %s\n"
+msgstr ""
 
 msgid "Signature made "
-msgstr "Подпись сделана "
+msgstr "Подпись сделана"
 
 msgid "[date not given]"
 msgstr "[дата не указана]"
 
 #, c-format
 msgid " using certificate ID 0x%08lX\n"
-msgstr "с использованием сертификата с ID 0x%08lX\n"
+msgstr "с использованием сертификата ID 0x%08lX\n"
 
 msgid ""
 "invalid signature: message digest attribute does not match computed one\n"
 msgstr ""
-"недопустимая подпись: атрибут хэш-функции сообщения не соответствует "
+"недопустимая подпись: атрибут дайджеста сообщения не соответствует "
 "вычисленному\n"
 
 msgid "Good signature from"
-msgstr "ХоÑ\80оÑ\88ая подпись от"
+msgstr "Ð\94ейÑ\81Ñ\82виÑ\82елÑ\8cная подпись от"
 
 msgid "                aka"
-msgstr "                или"
+msgstr "                aka"
 
 msgid "This is a qualified signature\n"
-msgstr "Это квалифицированная подпись\n"
+msgstr ""
 
 msgid "quiet"
-msgstr "менее подробно"
+msgstr ""
 
 msgid "print data out hex encoded"
-msgstr "выводить данные в шестнадцатеричном виде"
+msgstr ""
 
 msgid "decode received data lines"
-msgstr "декодировать полученные строки данных"
+msgstr ""
 
 msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NAME|подключиться к сокету Assuan NAME"
+msgstr ""
 
 msgid "run the Assuan server given on the command line"
-msgstr "запустить сервер Assuan, заданный в командной строке"
+msgstr ""
 
 msgid "do not use extended connect mode"
-msgstr "не пользоваться расширенным режимом подключения"
+msgstr ""
 
 msgid "|FILE|run commands from FILE on startup"
-msgstr "|FILE|вÑ\8bполниÑ\82Ñ\8c Ð¿Ñ\80и Ð·Ð°Ð¿Ñ\83Ñ\81ке ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b Ð¸Ð· Ñ\84айла FILE"
+msgstr "|FILE|вÑ\8bполниÑ\82Ñ\8c ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b Ð¸Ð· FILE Ð¿Ñ\80и Ð·Ð°Ð¿Ñ\83Ñ\81ке"
 
 msgid "run /subst on startup"
-msgstr "выполнить при запуске подстановку subst"
+msgstr "выполнить /substr при запуске"
 
 msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: gpg-connect-agent [параметры] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: gpg-connect-agent [параметры] (-h для подсказки)"
 
 msgid ""
 "Syntax: gpg-connect-agent [options]\n"
 "Connect to a running agent and send commands\n"
 msgstr ""
 "Синтаксис: gpg-connect-agent: [параметры]\n"
-"СвÑ\8fзÑ\8bваеÑ\82Ñ\81Ñ\8f Ñ\81 Ð·Ð°Ð¿Ñ\83Ñ\89еннÑ\8bм Ð°Ð³ÐµÐ½Ñ\82ом Ð¸ Ð¿Ð¾Ñ\81ылает команды\n"
+"СвÑ\8fзÑ\8bваеÑ\82Ñ\81Ñ\8f Ñ\81 Ð·Ð°Ð¿Ñ\83Ñ\89еннÑ\8bм Ð°Ð³ÐµÐ½Ñ\82ом Ð¸ Ð¾Ñ\82cылает команды\n"
 
 #, c-format
 msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr "паÑ\80амеÑ\82Ñ\80 \"%s\" Ñ\82Ñ\80ебÑ\83еÑ\82 Ð¿Ñ\80огÑ\80аммÑ\8b Ð¸ Ð½ÐµÐ¾Ð±Ñ\8fзаÑ\82ельных аргументов\n"
+msgstr "паÑ\80амеÑ\82Ñ\80 \"%s\" Ñ\82Ñ\80ебÑ\83еÑ\82 Ð¿Ñ\80огÑ\80аммÑ\8b Ð¸ Ð¾Ð¿Ñ\86иональных аргументов\n"
 
 #, c-format
 msgid "option \"%s\" ignored due to \"%s\"\n"
-msgstr "параметр \"%s\" игнорируется; причина - \"%s\"\n"
+msgstr "параметр \"%s\" игнорирован по причине \"%s\"\n"
 
 #, c-format
 msgid "receiving line failed: %s\n"
 msgstr "сбой получения строки: %s\n"
 
 msgid "line too long - skipped\n"
-msgstr "слишком длинная строка - пропущена\n"
+msgstr "строка слишком длинная - пропущено\n"
 
 msgid "line shortened due to embedded Nul character\n"
-msgstr "строка сокращена из-за содержащегося нулевого символа\n"
+msgstr ""
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "неизвестная команда `%s'\n"
 
 #, c-format
@@ -6414,122 +6214,120 @@ msgstr "сбой отправки строки: %s\n"
 
 #, c-format
 msgid "error sending %s command: %s\n"
-msgstr "ошибка отправки команды %s: %s\n"
+msgstr "ошибка отправки %s команды: %s\n"
 
 #, c-format
 msgid "error sending standard options: %s\n"
 msgstr "ошибка отправки стандартных параметров: %s\n"
 
 msgid "Options controlling the diagnostic output"
-msgstr "Параметры, контролирующие вывод диагностики"
+msgstr "Параметры контролирующие вывод диагностики"
 
 msgid "Options controlling the configuration"
-msgstr "Параметры, контролирующие настройки"
+msgstr "Параметры контролирующие конфигурацию"
 
 msgid "Options useful for debugging"
-msgstr "Параметры, полезные для отладки"
+msgstr "Параметры полезные для отладки"
 
 msgid "|FILE|write server mode logs to FILE"
-msgstr "|FILE|сохранять журнал режима сервера в файле FILE"
+msgstr "|FILE|сохранять журнал режима сервера в FILE"
 
 msgid "Options controlling the security"
-msgstr "Параметры, контролирующие безопасность"
+msgstr "Параметры контролирующие безопасность"
 
 msgid "|N|expire SSH keys after N seconds"
-msgstr "|N|забывать ключи SSH по истечении N секунд"
+msgstr "|N|считать ключ SSH истекшим по истечении N секунд"
 
 msgid "|N|set maximum PIN cache lifetime to N seconds"
-msgstr "|N|Ñ\83Ñ\81Ñ\82ановиÑ\82Ñ\8c Ð¼Ð°ÐºÑ\81ималÑ\8cнÑ\8bй Ñ\81Ñ\80ок Ð·Ð°Ð¿Ð¾Ð¼Ð¸Ð½Ð°Ð½Ð¸Ñ\8f PIN N секунд"
+msgstr "|N|Ñ\83Ñ\81Ñ\82ановиÑ\82Ñ\8c Ð¼Ð°ÐºÑ\81ималÑ\8cнÑ\8bй Ñ\81Ñ\80ок ÐºÐµÑ\88иÑ\80ованного PIN N секунд"
 
 msgid "|N|set maximum SSH key lifetime to N seconds"
-msgstr "|N|установить максимальный срок действия ключа SSH N секунд"
+msgstr "|N|установить максимальный срок действия SSH ключа N секунд"
 
 msgid "Options enforcing a passphrase policy"
-msgstr "Параметры, обеспечивающие правила для фраз-паролей"
+msgstr ""
 
 msgid "do not allow to bypass the passphrase policy"
-msgstr "не позволять обходить правила для фраз-паролей"
+msgstr ""
 
 msgid "|N|set minimal required length for new passphrases to N"
 msgstr "|N|установить минимальную длину фразы-пароля равной N"
 
 msgid "|N|require at least N non-alpha characters for a new passphrase"
-msgstr "|n|Ñ\82Ñ\80ебоваÑ\82Ñ\8c Ð´Ð»Ñ\8f Ð½Ð¾Ð²Ð¾Ð¹ Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ N Ð½ÐµÐ°Ð»Ñ\84авиÑ\82нÑ\8bÑ\85 Ñ\81имволов"
+msgstr "|n|Ñ\82Ñ\80ебоваÑ\82Ñ\8c Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ N Ð½Ðµ Ð°Ð»Ñ\84авиÑ\82нÑ\8bÑ\85 Ñ\81имволов Ð´Ð»Ñ\8f Ð½Ð¾Ð²Ð¾Ð¹ Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f"
 
 msgid "|FILE|check new passphrases against pattern in FILE"
 msgstr "|FILE|проверять новую фразу-пароль по файлу образцов FILE"
 
 msgid "|N|expire the passphrase after N days"
-msgstr "|N|Ñ\81Ñ\87иÑ\82аÑ\82Ñ\8c Ñ\84Ñ\80азÑ\83-паÑ\80олÑ\8c Ñ\83Ñ\81Ñ\82аÑ\80евÑ\88ей Ñ\87еÑ\80ез N дней"
+msgstr "|N|Ñ\81Ñ\80ок Ð¶Ð¸Ð·Ð½Ð¸ Ñ\84Ñ\80азÑ\8b-паÑ\80олÑ\8f N дней"
 
 msgid "do not allow the reuse of old passphrases"
 msgstr "не разрешать повторное использование старых фраз-паролей"
 
 msgid "|NAME|use NAME as default secret key"
-msgstr "|NAME|использовать NAME как основной закрытый ключ"
+msgstr "|NAME|использовать NAME как секретный ключ по умолчанию"
 
 msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|NAME|зашифровывать также для ID пользователя NAME"
+msgstr "|NAME|зашифровать для User ID: NAME"
 
 msgid "|SPEC|set up email aliases"
-msgstr "|SPEC|установить синонимы электронной почты"
+msgstr ""
 
 msgid "Configuration for Keyservers"
-msgstr "Ð\9dаÑ\81Ñ\82Ñ\80ойки серверов ключей"
+msgstr "Ð\9aонÑ\84игÑ\83Ñ\80аÑ\86иÑ\8f серверов ключей"
 
 msgid "|URL|use keyserver at URL"
 msgstr "|URL|использовать север ключей по URL"
 
 msgid "allow PKA lookups (DNS requests)"
-msgstr "разрешить поиск по PKA (запросы DNS)"
+msgstr ""
 
 msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
 msgstr ""
-"|MECHANISMS|использовать механизмы MECHANISMS для поиска ключей по адресу "
-"электронной почты"
 
 msgid "disable all access to the dirmngr"
 msgstr "полностью запретить доступ к dirmngr"
 
 msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr "|NAME|использовать кодировку NAME для фраз-паролей PKCS#12"
+msgstr "|NAME|использовать кодировку NAME для PKCS#12 фраз-паролей"
 
 msgid "do not check CRLs for root certificates"
-msgstr "не проверять списки отозванных сертификатов для корневых сертификатов"
+msgstr "не проверять CRLd для корневых сертификатов"
 
 msgid "Options controlling the format of the output"
-msgstr "Параметры, управляющие форматом вывода"
+msgstr "Параметры контрролирующие формат вывода"
 
 msgid "Options controlling the interactivity and enforcement"
-msgstr "Параметры, управляющие интерактивностью и принудительными действиями"
+msgstr ""
 
 msgid "Configuration for HTTP servers"
-msgstr "Настройки серверов HTTP"
+msgstr "Настройки HTTP серверов"
 
 msgid "use system's HTTP proxy setting"
-msgstr "использовать системные настройки промежуточного сервера HTTP"
+msgstr "использовать системные настройки HTTP проки"
 
 msgid "Configuration of LDAP servers to use"
-msgstr "Настройки серверов LDAP"
+msgstr "Настройки LDAP серверов"
 
 msgid "LDAP server list"
-msgstr "Список серверов LDAP"
+msgstr ""
 
 msgid "Configuration for OCSP"
 msgstr "Настройки OCSP"
 
 #, c-format
 msgid "External verification of component %s failed"
-msgstr "Внешняя проверка компонента %s не прошла"
+msgstr ""
 
 msgid "Note that group specifications are ignored\n"
-msgstr "Обратите внимание, что спецификации групп игнорируются\n"
+msgstr ""
 
 msgid "list all components"
 msgstr "вывод списка всех компонентов"
 
 msgid "check all programs"
-msgstr "проверить все программы"
+msgstr ""
 
 msgid "|COMPONENT|list options"
 msgstr "|COMPONENT|вывод списка параметров"
@@ -6541,16 +6339,16 @@ msgid "|COMPONENT|check options"
 msgstr "|COMPONENT|проверить параметры"
 
 msgid "apply global default values"
-msgstr "применить глобальные значения по умолчанию"
+msgstr ""
 
 msgid "get the configuration directories for gpgconf"
-msgstr "получить каталоги настроек для gpgconf"
+msgstr ""
 
 msgid "list global configuration file"
-msgstr "указать глобальный файл настроек"
+msgstr ""
 
 msgid "check global configuration file"
-msgstr "пÑ\80овеÑ\80иÑ\82Ñ\8c Ð³Ð»Ð¾Ð±Ð°Ð»Ñ\8cнÑ\8bй Ñ\84айл Ð½Ð°Ñ\81Ñ\82Ñ\80оек"
+msgstr "пÑ\80овеÑ\80иÑ\82Ñ\8c Ð³Ð»Ð¾Ð±Ð°Ð»Ñ\8cнÑ\8bй Ñ\84айл ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80аÑ\86ии"
 
 msgid "use as output file"
 msgstr "вывод в указанный файл"
@@ -6559,17 +6357,17 @@ msgid "activate changes at runtime, if possible"
 msgstr "применить изменения во время исполнения, если возможно"
 
 msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: gpgconf [параметры] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: gpgconf [параметры] (-h для подсказки)"
 
 msgid ""
 "Syntax: gpgconf [options]\n"
 "Manage configuration options for tools of the GnuPG system\n"
 msgstr ""
 "Синтаксис: gpgconf [параметры]\n"
-"УпÑ\80авлÑ\8fеÑ\82 Ð¿Ð°Ñ\80амеÑ\82Ñ\80ами Ð½Ð°Ñ\81Ñ\82Ñ\80оек инструментария GnuPG\n"
+"УпÑ\80авлÑ\8fеÑ\82 Ð¿Ð°Ñ\80амеÑ\82Ñ\80ами ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80аÑ\86ии инструментария GnuPG\n"
 
 msgid "usage: gpgconf [options] "
-msgstr "вÑ\8bзов: gpgconf [параметры] "
+msgstr "иÑ\81полÑ\8cзование: gpgconf [параметры] "
 
 msgid "Need one component argument"
 msgstr "Требуется однокомпонентный аргумент"
@@ -6590,34 +6388,34 @@ msgstr ""
 " "
 
 msgid "decryption modus"
-msgstr "режим расшифровывания"
+msgstr "режим расшифрования"
 
 msgid "encryption modus"
 msgstr "режим зашифровывания"
 
 msgid "tool class (confucius)"
-msgstr "класс средства (confucius)"
+msgstr ""
 
 msgid "program filename"
-msgstr "имя файла программы"
+msgstr ""
 
 msgid "secret key file (required)"
-msgstr "файл закрытого ключа (обязателен)"
+msgstr "файл секретного ключа (требуется)"
 
 msgid "input file name (default stdin)"
-msgstr "имÑ\8f Ð²Ñ\85одного Ñ\84айла (по Ñ\83молÑ\87аниÑ\8e stdin)"
+msgstr "ввод Ð¸Ð¼ÐµÐ½Ð¸ Ñ\84айла (stdin Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e)"
 
 msgid "Usage: symcryptrun [options] (-h for help)"
-msgstr "Ð\92Ñ\8bзов: symcryptrun [параметры] (-h для подсказки)"
+msgstr "Ð\98Ñ\81полÑ\8cзование: symcryptrun [параметры] (-h для подсказки)"
 
 msgid ""
 "Syntax: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE "
 "[options...] COMMAND [inputfile]\n"
 "Call a simple symmetric encryption tool\n"
 msgstr ""
-"Синтаксис: symcryptrun --class КЛАСС --program ПРОГРАММА --keyfile "
-"ФАЙЛ_КЛЮЧА [параметры...] КОМАНДА [входной файл]\n"
-"Ð\92Ñ\8bзÑ\8bваеÑ\82 Ð¿Ñ\80оÑ\81Ñ\82ое Ñ\81Ñ\80едÑ\81Ñ\82во шифрования\n"
+"Синтаксис: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE "
+"[параметры...] COMMAND [файл-источник]\n"
+"Ð\92Ñ\8bзÑ\8bваеÑ\82 Ð¿Ñ\80оÑ\81Ñ\82ой Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82 шифрования\n"
 
 #, c-format
 msgid "%s on %s aborted with status %i\n"
@@ -6628,12 +6426,12 @@ msgid "%s on %s failed with status %i\n"
 msgstr "сбой %s над %s, статус %i\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "невозможно создание временного каталога `%s': %s\n"
 
 #, c-format
 msgid "could not open %s for writing: %s\n"
-msgstr "невозможно открыть %s на запись: %s\n"
+msgstr "невозможно открытие %s на запись: %s\n"
 
 #, c-format
 msgid "error writing to %s: %s\n"
@@ -6657,39 +6455,39 @@ msgid "no --keyfile option provided\n"
 msgstr "не задан параметр --keyfile\n"
 
 msgid "cannot allocate args vector\n"
-msgstr "невозможно выделить память под вектор аргументов\n"
+msgstr ""
 
 #, c-format
 msgid "could not create pipe: %s\n"
-msgstr "сбой при создании канала конвейера: %s\n"
+msgstr ""
 
 #, c-format
 msgid "could not create pty: %s\n"
-msgstr "сбой при создании псевдотерминала: %s\n"
+msgstr ""
 
 #, c-format
 msgid "could not fork: %s\n"
-msgstr "сбой при дублировании процесса: %s\n"
+msgstr ""
 
 #, c-format
 msgid "execv failed: %s\n"
-msgstr "сбой execv: %s\n"
+msgstr ""
 
 #, c-format
 msgid "select failed: %s\n"
-msgstr "сбой select: %s\n"
+msgstr ""
 
 #, c-format
 msgid "read failed: %s\n"
-msgstr "сбой чтения: %s\n"
+msgstr ""
 
 #, c-format
 msgid "pty read failed: %s\n"
-msgstr "сбой чтения из псевдотерминала: %s\n"
+msgstr ""
 
 #, c-format
 msgid "waitpid failed: %s\n"
-msgstr "сбой waitpid: %s\n"
+msgstr ""
 
 #, c-format
 msgid "child aborted with status %i\n"
@@ -6697,11 +6495,11 @@ msgstr "потомок завершился, статус %i\n"
 
 #, c-format
 msgid "cannot allocate infile string: %s\n"
-msgstr "сбой при выделении памяти под имя входного файла: %s\n"
+msgstr ""
 
 #, c-format
 msgid "cannot allocate outfile string: %s\n"
-msgstr "сбой при выделении памяти под имя выходного файла: %s\n"
+msgstr ""
 
 #, c-format
 msgid "either %s or %s must be given\n"
@@ -6716,11 +6514,33 @@ msgstr "класс %s не поддерживается\n"
 
 msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n"
 msgstr ""
-"Ð\92Ñ\8bзов: gpg-check-pattern [паÑ\80амеÑ\82Ñ\80Ñ\8b] Ñ\84айл_обÑ\80азÑ\86ов (-h для подсказки)\n"
+"Ð\98Ñ\81полÑ\8cзование: gpg-check-pattern [паÑ\80амеÑ\82Ñ\80Ñ\8b] patternfile (-h для подсказки)\n"
 
 msgid ""
 "Syntax: gpg-check-pattern [options] patternfile\n"
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
-"Синтаксис: gpg-check-pattern [параметры] файл_образцов\n"
-"Проверить фразу-пароль, поступающую из stdin, по файлу образцов\n"
+
+#~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
+#~ msgstr "таблица доверий повреждена; запустите \"gpg --fix-trustdb\".\n"
+
+#~ msgid "Please report bugs to <"
+#~ msgstr "О найденных ошибках сообщайте <"
+
+#~ msgid "Please report bugs to "
+#~ msgstr "О найденных ошибка сообщайте "
+
+#~ msgid "DSA keypair will have %u bits.\n"
+#~ msgstr "Пара ключей DSA будет иметь длину %u бит.\n"
+
+#~ msgid "this command has not yet been implemented\n"
+#~ msgstr "данная команды всё еще не реализована\n"
+
+#~ msgid "Repeat passphrase\n"
+#~ msgstr "Повторите ввод фразы-пароля\n"
+
+#~ msgid "||Please enter your PIN at the reader's keypad%%0A[sigs done: %lu]"
+#~ msgstr "||Введите PIN на клавиатуре считывателя%%0A[подписей: %lu]"
+
+#~ msgid "|A|Admin PIN"
+#~ msgstr "|A|Административный PID"
index 53f88e0..85a1d54 100644 (file)
--- a/po/sk.po
+++ b/po/sk.po
@@ -1,10 +1,6 @@
 # GnuPG Slovak translation
 # Copyright (C) 1998 - 2004 Free Software Foundation, Inc.
 # Michal Majer <mmajer@econ.umb.sk>, 2002 - 2004
-#               !-- bounces (2011-01-11)
-#
-# Designated-Translator: none
-#
 msgid ""
 msgstr ""
 "Project-Id-Version: gnupg 1.2.5\n"
@@ -12,7 +8,6 @@ msgstr ""
 "PO-Revision-Date: 2004-07-20 15:52+0200\n"
 "Last-Translator: Michal Majer <mmajer@econ.umb.sk>\n"
 "Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
-"Language: sk\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -21,41 +16,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "nemô¾em inicializova» databázu dôvery: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Skutoène chcete revokova» vybrané kµúèe? "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "nesprávne heslo"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -81,9 +41,6 @@ msgid ""
 "this session"
 msgstr "Prosím, vlo¾te heslo; toto je tajná veta \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -120,11 +77,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "ochranný algoritmus %d%s nie je podporováný\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "nemô¾em vytvori» `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "nemô¾em otvori» `%s': %s\n"
 
 #, fuzzy, c-format
@@ -151,31 +108,19 @@ msgstr "zmazanie bloku k
 msgid "error writing key: %s\n"
 msgstr "chyba pri zápise súboru kµúèov (keyring)  `%s': %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Prosím, vlo¾te heslo; toto je tajná veta \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "zmeni» heslo"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "Prosím, vlo¾te heslo; toto je tajná veta \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -202,7 +147,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -290,7 +235,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "Na ochranu Vá¹ho tajného kµúèa musíte zada» heslo.\n"
 "\n"
@@ -308,10 +253,10 @@ msgstr ""
 "Mo¾nosti:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -366,26 +311,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "chyba pri vytváraní hesla: %s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "nepodporované"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "nepodporované"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "chyba pri vytváraní hesla: %s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -409,7 +343,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -417,23 +351,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "POZNÁMKA: neexistuje implicitný súbor s mo¾nos»ami `%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "súbor s mo¾nos»ami `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "èítam mo¾nosti z `%s'\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "chyba pri vytváraní `%s': %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "nemô¾em vytvori» adresár `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -444,7 +378,7 @@ msgid "can't create socket: %s\n"
 msgstr "%s: nemô¾em vytvori»: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -456,7 +390,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "chyba pri vytváraní hesla: %s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "chyba pri posielaní na `%s': %s\n"
 
 #, fuzzy, c-format
@@ -464,19 +398,19 @@ msgid "listen() failed: %s\n"
 msgstr "aktualizácia zlyhala: %s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "zapisujem tajný kµúè do `%s'\n"
 
 #, fuzzy, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "%s: adresár vytvorený\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "databáza dôvery: procedúra read() (n=%d) zlyhala: %s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "%s: nemô¾em vytvori» adresár: %s\n"
 
 #, fuzzy, c-format
@@ -584,31 +518,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "chyba pri vytváraní hesla: %s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "chyba pri èítaní `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "kµúè `%s' nebol nájdený: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "tajné èasti kµúèa nie sú dostupné\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "chyba pri èítaní: %s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "chyba pri èítaní `%s': %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -696,15 +630,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "chyba pri zápise do súboru tajných kµúèov `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "chyba pri èítaní `%s': %s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "chyba pri èítaní `%s': %s\n"
 
 #, fuzzy, c-format
@@ -719,7 +653,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent nie je v tomto sedení dostupný\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "nemô¾em sa pripoji» k `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -796,10 +730,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -826,22 +756,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "nesprávny certifikát"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "nesprávny certifikát"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "nesprávny certifikát"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "nesprávny certifikát"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "nesprávny certifikát"
 
@@ -884,26 +798,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "neplatný hashovací algoritmus `%s'\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "Platnos» podpisu vypr¹ala %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "neplatný hashovací algoritmus `%s'\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "ochranný algoritmus %d%s nie je podporováný\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "verifikácia podpisu potlaèená\n"
 
@@ -912,11 +810,11 @@ msgid "Signature available"
 msgstr "Platnos» podpisu vypr¹ala %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "Dobrý podpis od \""
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "neplatný hashovací algoritmus `%s'\n"
 
 #, fuzzy, c-format
@@ -961,7 +859,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Pomoc nie je dostupná pre '%s'"
 
 #, fuzzy
@@ -1136,11 +1034,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "chyba pri vytváraní súboru kµúèov (keyring)`%s': %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "chyba pri èítaní `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "chyba pri zápise súboru kµúèov (keyring)  `%s': %s\n"
 
 msgid "Login data (account name): "
@@ -1342,8 +1240,8 @@ msgstr ""
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Príkaz> "
 
 #, fuzzy
 msgid "Admin-only command\n"
@@ -1364,7 +1262,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output pre tento príkaz nefunguje\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "nemo¾no otvori» `%s'\n"
 
 #, fuzzy, c-format
@@ -1416,11 +1314,11 @@ msgid "using cipher %s\n"
 msgstr "pou¾itá ¹ifra %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' je u¾ skomprimovaný\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "VAROVANIE: súbor `%s' je prázdny\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1428,7 +1326,7 @@ msgstr ""
 "v móde --pgp2 mô¾ete ¹ifrova» len RSA kµúèom s då¾kou 2048 bitov a menej\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "èítam z `%s'\n"
 
 msgid ""
@@ -1492,11 +1390,11 @@ msgstr ""
 "táto platforma potrebuje doèasné súbory na spustenie externého programu\n"
 
 #, fuzzy, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "nemo¾no spusti» %s \"%s\": %s\n"
 
 #, fuzzy, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "nemo¾no spusti» %s \"%s\": %s\n"
 
 #, c-format
@@ -1514,11 +1412,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "nemo¾no cíta» odozvu externého programu: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "VAROVANIE: nemô¾em vymaza» doèasný súbor (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "VAROVANIE: nemô¾em vymaza» doèasný adresár `%s': %s\n"
 
 #, fuzzy
@@ -1585,16 +1483,12 @@ msgstr "pr
 msgid "[User ID not found]"
 msgstr "[User id not found]"
 
-#, fuzzy, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "kµúè %08lX: tajný kµúè bez verejného kµúèa - preskoèené\n"
-
 #, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "chyba pri vytváraní `%s': %s\n"
 
 #, fuzzy
@@ -1615,6 +1509,10 @@ msgstr "existuje tajn
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "pou¾ívam sekundárny kµúè %08lX namiesto primárneho kµúèa %08lX\n"
 
+#, fuzzy, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "kµúè %08lX: tajný kµúè bez verejného kµúèa - preskoèené\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "vytvori» podpis oddelený od dokumentu"
@@ -1657,9 +1555,6 @@ msgstr "vyp
 msgid "generate a new key pair"
 msgstr "vytvori» nový pár kµúèov"
 
-msgid "generate a revocation certificate"
-msgstr "vytvori» revokaèný certifikát"
-
 msgid "remove keys from the public keyring"
 msgstr "odstráni» kµúè zo súboru verejných kµúèov"
 
@@ -1675,9 +1570,8 @@ msgstr "podp
 msgid "sign or edit a key"
 msgstr "podpísa» alebo modifikova» kµúè"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "zmeni» heslo"
+msgid "generate a revocation certificate"
+msgstr "vytvori» revokaèný certifikát"
 
 msgid "export keys"
 msgstr "exportova» kµúèe"
@@ -1781,15 +1675,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Pou¾itie: gpg [mo¾nosti] [súbory] (-h pre pomoc)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Syntax: gpg [mo¾nosti] [súbory]\n"
 "podpísa», overi», ¹ifrova» alebo de¹ifrova»\n"
@@ -1821,35 +1710,35 @@ msgid "conflicting commands\n"
 msgstr "konfliktné príkazy\n"
 
 #, fuzzy, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "no = podpis nájdený v definícii skupiny \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "VAROVANIE: vlastníctvo pre %s nastavené nebezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "VAROVANIE: vlastníctvo pre %s nastavené nebezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "VAROVANIE: vlastníctvo pre %s nastavené nebezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "VAROVANIE: prístupové práva pre %s nie sú nastavené bezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "VAROVANIE: prístupové práva pre %s nie sú nastavené bezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "VAROVANIE: prístupové práva pre %s nie sú nastavené bezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "VAROVANIE: vlastníctvo adresára %s nastavené nebezpeène \"%s\"\n"
 
 #, fuzzy, c-format
@@ -1858,11 +1747,11 @@ msgid ""
 msgstr "VAROVANIE: vlastníctvo adresára %s nastavené nebezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "VAROVANIE: vlastníctvo adresára %s nastavené nebezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 "VAROVANIE: prístupové práva adresára %s nie sú nastavené bezpeène \"%s\"\n"
 
@@ -1873,12 +1762,12 @@ msgstr ""
 "VAROVANIE: prístupové práva adresára %s nie sú nastavené bezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "VAROVANIE: prístupové práva adresára %s nie sú nastavené bezpeène \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "neznáma polo¾ka konfigurácie \"%s\"\n"
 
 msgid "display photo IDs during key listings"
@@ -1919,7 +1808,7 @@ msgid "show expiration dates during signature listings"
 msgstr "V súbore tajných kµúèov chýba zodpovedajúci podpis\n"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "POZNÁMKA: starý implicitný súbor s mo¾nos»ami `%s ignorovaný'\n"
 
 #, c-format
@@ -1931,11 +1820,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "POZNÁMKA: %s nie je pre normálne pou¾itie!\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "%s nie je platná znaková sada\n"
 
 #, fuzzy, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "%s nie je platná znaková sada\n"
 
 #, fuzzy
@@ -2113,15 +2002,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s e¹te nepracuje s %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "nemô¾ete pou¾i» ¹ifrovací algoritmus \"%s\" v móde %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "nemô¾ete pou¾i» hashovací algoritmus \"%s\" v móde %s\n"
 
 #, fuzzy, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "nemô¾ete pou¾i» kompresný algoritmus \"%s\" v móde %s\n"
 
 #, c-format
@@ -2139,7 +2028,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [meno súboru]"
 
 #, fuzzy, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "de¹ifrovanie zlyhalo: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2195,10 +2084,6 @@ msgstr "--lsign-key id u
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key id u¾ívateµa [príkazy]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key id u¾ívateµa"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "nepodarilo posla» kµúè na server: %s\n"
@@ -2228,7 +2113,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "kódovanie do ASCII formátu zlyhalo: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "neplatný hashovací algoritmus `%s'\n"
 
 msgid "[filename]"
@@ -2272,7 +2157,7 @@ msgid "No help available"
 msgstr "Pomoc nie je k dispozícii"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Pomoc nie je dostupná pre '%s'"
 
 msgid "import signatures that are marked as local-only"
@@ -2282,10 +2167,6 @@ msgid "repair damage from the pks keyserver during import"
 msgstr ""
 
 #, fuzzy
-msgid "do not clear the ownertrust values during import"
-msgstr "aktualizova» databázu dôvery"
-
-#, fuzzy
 msgid "do not update the trustdb after import"
 msgstr "aktualizova» databázu dôvery"
 
@@ -2404,13 +2285,6 @@ msgid "key %s: no user ID\n"
 msgstr "kµúè %08lX: chyba identifikátor u¾ívateµa\n"
 
 #, fuzzy, c-format
-msgid "key %s: %s\n"
-msgstr "preskoèený `%s': %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
-#, fuzzy, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "kµúè %08lX: HKP po¹kodenie podkµúèa opravené\n"
 
@@ -2440,11 +2314,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "nenájdený zapisovateµný súbor kµúèov (keyring): %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "zapisujem do '%s'\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "chyba pri zápise súboru kµúèov (keyring)  `%s': %s\n"
 
 #, fuzzy, c-format
@@ -2508,17 +2382,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "kµúè %08lX: \"%s\" bez zmeny\n"
 
 #, fuzzy, c-format
-msgid "secret key %s: %s\n"
-msgstr "tajný kµúè `%s' nebol nájdený: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "kµúè %08lX: tajný kµúè bez verejného kµúèa %d - preskoèené\n"
 
 #, fuzzy
 msgid "importing secret keys not allowed\n"
 msgstr "zapisujem tajný kµúè do `%s'\n"
 
-#, fuzzy, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "kµúè %08lX: tajný kµúè bez verejného kµúèa %d - preskoèené\n"
-
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "nie je nastavený implicitný súbor tajných kµúèov %s\n"
@@ -2564,18 +2434,14 @@ msgstr ""
 "kµúè %08lX: neplatný podpis kµúèa ním samým u u¾ívateµského id \"%s\"\n"
 
 #, fuzzy, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "kµúè %08lX: nepodporovaný algoritmus verejného kµúèa\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "kµúè %08lX: podpis kµúèa ním samým (direct key signature)\n"
-
-#, fuzzy, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "kµúè %08lX: neexistuje podkµúè pre viazanie kµúèov\n"
 
 #, fuzzy, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "kµúè %08lX: nepodporovaný algoritmus verejného kµúèa\n"
+
+#, fuzzy, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "kµúè %08lX: neplatná väzba podkµúèa\n"
 
@@ -2630,8 +2496,8 @@ msgstr "k
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: fetching revocation key %s\n"
 msgstr ""
-"VAROVANIE: kµúè %08lX mô¾e by» revokovaný: skú¹am získa» revokaèný kµúè "
-"%08lX\n"
+"VAROVANIE: kµúè %08lX mô¾e by» revokovaný: skú¹am získa» revokaèný kµúè %"
+"08lX\n"
 
 #, fuzzy, c-format
 msgid "WARNING: key %s may be revoked: revocation key %s not present.\n"
@@ -2659,15 +2525,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "preskoèené: tajný kµúè je u¾ v databáze\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "chyba pri vytváraní súboru kµúèov (keyring)`%s': %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "súbor kµúèov (keyring) `%s' vytvorený\n"
 
 #, fuzzy, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "chyba pri vytváraní `%s': %s\n"
 
 #, c-format
@@ -2859,7 +2725,7 @@ msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Veµmi dôkladne som to overil(a).%s\n"
 
 #, fuzzy
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Vá¹ výber? ('?' - viac informácií): "
 
 #, fuzzy, c-format
@@ -3137,7 +3003,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Nápoveda: Vyberte id u¾ívateµa na podpísanie\n"
 
 #, fuzzy, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "neznáma trieda podpisu"
 
 #, c-format
@@ -3172,11 +3038,11 @@ msgid "Command expects a filename argument\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "nemô¾em otvori» `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "chyba pri vytváraní súboru kµúèov (keyring)`%s': %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3264,7 +3130,7 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "U¾ívateµské ID vo formáte PGP 2.x nemá ¾iadne predvoµby\n"
 
 #, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "Tento kµúè mô¾e by» revokovaný kµúèom %s "
 
 #, fuzzy, c-format
@@ -3331,14 +3197,6 @@ msgstr ""
 "VAROVANIE: ¾iadne ID u¾ívateµa nebolo oznaèené ako primárne. Tento príkaz\n"
 "spôsobí, ¾e iné ID u¾ívateµa sa bude pova¾ova» primárne.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Nemô¾ete zmeni» dobu platnosti kµúèa verzie 3\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3566,7 +3424,7 @@ msgstr ""
 "Zobrazujem %s fotografické ID s veµkos»ou %ld pre kµúè 0x%08lX (uid %d)\n"
 
 #, fuzzy, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "duplicita predvoµby %c%lu\n"
 
 #, fuzzy
@@ -3582,7 +3440,7 @@ msgid "too many compression preferences\n"
 msgstr "príli¹ veµa `%c' predvolieb\n"
 
 #, fuzzy, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "neplatný znak v re»azci s predvoµbami\n"
 
 msgid "writing direct signature\n"
@@ -3825,7 +3683,7 @@ msgid "Invalid character in comment\n"
 msgstr "Neplatný znak v komentári\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Pou¾ívate znakovú sadu `%s'.\n"
 
 #, c-format
@@ -3910,15 +3768,15 @@ msgid "Key generation canceled.\n"
 msgstr "Vytváranie kµúèa bolo zru¹ené.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "zapisujem verejný kµúè do `%s'\n"
 
 #, fuzzy, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "zapisujem tajný kµúè do `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "zapisujem tajný kµúè do `%s'\n"
 
 #, c-format
@@ -3930,11 +3788,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "nenájdený zapisovateµný súbor tajných kµúèov (secring): %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "chyba pri zápise do súboru verejných kµúèov `%s': %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "chyba pri zápise do súboru tajných kµúèov `%s': %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3978,11 +3836,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "zmazanie bloku kµúèa sa nepodarilo:  %s\n"
 
 #, fuzzy, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "nemô¾em vytvori» `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "POZNÁMKA: platnos» tajného kµúèa %08lX skonèila %s\n"
 
 msgid "never     "
@@ -4024,15 +3882,11 @@ msgstr "      Fingerprint podk
 msgid "      Key fingerprint ="
 msgstr "   Fingerprint kµúèa ="
 
-#, fuzzy, c-format
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "%s podpis, hashovací algoritmus %s\n"
-
 msgid "      Card serial no. ="
 msgstr ""
 
 #, fuzzy, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "kódovanie do ASCII formátu zlyhalo: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -4050,7 +3904,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Prosím, opravte tento mo¾ný bezpeènostný problém\n"
 
 #, fuzzy, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "kontrolujem súbor kµúèov (keyring) `%s'\n"
 
 #, fuzzy, c-format
@@ -4088,7 +3942,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "VAROVANIE: nastavenie v `%s' e¹te nie je aktívne\n"
 
 #, fuzzy
@@ -4155,10 +4009,6 @@ msgstr ""
 msgid "keyserver did not send VERSION\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "nepodarilo sa prija» kµúè zo servera: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr ""
 
@@ -4166,11 +4016,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr ""
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr ""
 
 #, c-format
@@ -4185,6 +4035,10 @@ msgstr "chyba servera k
 msgid "keyserver internal error\n"
 msgstr "chyba servera kµúèov"
 
+#, fuzzy, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "nepodarilo sa prija» kµúè zo servera: %s\n"
+
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr ""
@@ -4363,10 +4217,6 @@ msgid "unknown"
 msgstr "neznáme"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Nemô¾em overi» podpis: %s\n"
 
@@ -4388,7 +4238,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "nájdený neplatný koreòový paket v proc_tree()\n"
 
 #, fuzzy, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "nemo¾no otvori» súbor: %s\n"
 
 #, fuzzy, c-format
@@ -4417,11 +4267,6 @@ msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr ""
 "vy¾iadaný hashovací algoritmus %s (%d) nevyhovuje predvoµbám príjemcu\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s podpis, hashovací algoritmus %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "IDEA modul pre GnuPG nenájdený\n"
 
@@ -4453,15 +4298,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "VAROVÁNÍ: pou¾itie parametra \"%s\" sa neodporúèa\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "VAROVÁNÍ: pou¾itie parametra \"%s\" sa neodporúèa\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "VAROVÁNÍ: pou¾itie parametra \"%s\" sa neodporúèa\n"
-
 msgid "Uncompressed"
 msgstr "Nekomprimované"
 
@@ -4475,15 +4311,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "táto správa nemusí pou¾iteµná s %s\n"
 
 #, fuzzy, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "èítam mo¾nosti z `%s'\n"
 
 #, fuzzy, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "neznámy implicitný adresát `%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Súbor `%s' existuje. "
 
 #, fuzzy
@@ -4500,17 +4336,16 @@ msgstr "Vlo
 msgid "writing to stdout\n"
 msgstr "zapisujem na ¹tandardný výstup (stdout)\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "predpokladám podpísané dáta v `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "vytvorený nový konfiguraèný súbor `%s'\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "VAROVANIE: nastavenie v `%s' e¹te nie je aktívne\n"
 
 #, c-format
@@ -4526,10 +4361,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "podpaket typu %d má nastavený kritický bit\n"
 
 #, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problém s agentom: agent vracia 0x%lx\n"
-
-#, fuzzy, c-format
 msgid " (main key ID %s)"
 msgstr " (hlavné ID kµúèa %08lX)"
 
@@ -4552,6 +4383,10 @@ msgid "cancelled by user\n"
 msgstr "zru¹ené u¾ívateµom\n"
 
 #, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problém s agentom: agent vracia 0x%lx\n"
+
+#, fuzzy, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4586,7 +4421,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Meno súbor s fotografiou vo formáte JPEG: "
 
 #, fuzzy, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "nemo¾no otvori» súbor: %s\n"
 
 #, c-format
@@ -4598,13 +4433,12 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Ste si istý, ¾e ho chcete pou¾i»? (a/N) "
 
 #, fuzzy, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\" nie je súbor JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
 msgstr "Je táto fotografia správna (a/N/u)? "
 
-#, fuzzy
 msgid "unable to display photo ID!\n"
 msgstr "nemo¾no nastavi» exec-path na %s\n"
 
@@ -4629,16 +4463,6 @@ msgstr "d
 msgid "revocation comment: "
 msgstr "revokaèná poznámka: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMuUsS"
 
@@ -4752,11 +4576,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Poznámka: Tento kµúè bol oznaèený ako neplatný (disabled).\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr ""
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr ""
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4860,7 +4684,7 @@ msgid "no signed data\n"
 msgstr "chýbajú podpísané dáta\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "nemô¾em otvori» podpísané dáta '%s'\n"
 
 #, fuzzy, c-format
@@ -5173,7 +4997,7 @@ msgstr ""
 "# (Pou¾ite \"gpg --import-ownertrust\" na obnovenie)\n"
 
 #, fuzzy, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "chyba pri èítaní `%s': %s\n"
 
 #, fuzzy
@@ -5194,25 +5018,17 @@ msgstr ""
 " vlastníka kµúèa"
 
 #, fuzzy, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "chyba pri hµadaní záznamu dôvery: %s\n"
 
 #, fuzzy, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "chyba pri èítaní: %s\n"
 
 #, c-format
 msgid "trustdb: sync failed: %s\n"
 msgstr "databáza dôvery: synchronizácia zlyhala %s\n"
 
-#, fuzzy, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "nemô¾em vytvori» `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't lock `%s'\n"
-msgstr "nemo¾no otvori» `%s'\n"
-
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "záznam v databáze dôvery %lu: lseek() sa nepodaril: %s\n"
@@ -5224,13 +5040,21 @@ msgstr "z
 msgid "trustdb transaction too large\n"
 msgstr "transakcia s databázou dôvery je príli¹ dlhá\n"
 
+#, fuzzy, c-format
+msgid "can't access '%s': %s\n"
+msgstr "nemô¾em zavrie» `%s': %s\n"
+
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: adresár neexistuje!\n"
 
 #, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nemô¾em zavrie» `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "nemô¾em vytvori» `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "can't lock '%s'\n"
+msgstr "nemo¾no otvori» `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5316,7 +5140,7 @@ msgid "input line longer than %d characters\n"
 msgstr "vstupný riadok je dlh¹í ako %d znakov\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' nie je platné dlhé keyID\n"
 
 #, fuzzy, c-format
@@ -5358,14 +5182,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr ""
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr ""
 
@@ -5417,11 +5233,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "dal¹ia kontrola databázy dôvery %s\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "nie je nutné kontrolova» databázu dôvery\n"
 
 #, fuzzy, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "nie je nutné kontrolova» databázu dôvery\n"
 
 #, fuzzy, c-format
@@ -5492,11 +5308,6 @@ msgid "missing argument"
 msgstr "neplatný argument"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "neplatný spôsob reprezentácie v ASCII"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "konfliktné príkazy\n"
 
@@ -5516,10 +5327,6 @@ msgstr "neplatn
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "neplatný parameter pre import\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5548,8 +5355,12 @@ msgstr "neplatn
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "nájdená chyba v programe ... (%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "chyba pri èítaní `%s': %s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5557,15 +5368,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "nemo¾no otvori» súbor: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "kódovanie do ASCII formátu zlyhalo: %s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "nemô¾em vytvori» adresár `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "chyba pri zápise súboru kµúèov (keyring)  `%s': %s\n"
 
 #, c-format
@@ -5583,7 +5394,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "verejný kµúè %08lX nebol nájdený: %s\n"
 
 #, fuzzy, c-format
@@ -5600,11 +5411,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Pou¾itie: gpg [mo¾nosti] [súbory] (-h pre pomoc)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "Pou¾itie: gpg [mo¾nosti] [súbory] (-h pre pomoc)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5733,9 +5543,6 @@ msgstr "Pros
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr ""
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5746,14 +5553,6 @@ msgid "|N|New PIN"
 msgstr ""
 
 #, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "zmeni» heslo"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "zmeni» heslo"
-
-#, fuzzy
 msgid "error reading application data\n"
 msgstr "chyba pri èítaní bloku kµúèa: %s\n"
 
@@ -5820,9 +5619,8 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "nenájdené ¾iadne platné dáta vo formáte OpenPGP.\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "zmeni» heslo"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5858,16 +5656,13 @@ msgstr "v
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "konfliktné príkazy\n"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Pou¾itie: gpg [mo¾nosti] [súbory] (-h pre pomoc)"
@@ -5877,7 +5672,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5897,7 +5692,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5933,7 +5728,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "nemô¾em otvori» `%s': %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5962,7 +5757,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "zmazanie bloku kµúèa sa nepodarilo:  %s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "nemô¾em inicializova» databázu dôvery: %s\n"
 
 #, fuzzy
@@ -6151,16 +5946,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "chyba pri zápise do súboru tajných kµúèov `%s': %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -6182,11 +5977,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -6194,11 +5989,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "Neplatná e-mailová adresa\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "chyba pri vytváraní súboru kµúèov (keyring)`%s': %s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "chyba pri vytváraní súboru kµúèov (keyring)`%s': %s\n"
 
 #, fuzzy, c-format
@@ -6269,7 +6064,7 @@ msgid "No subject name given\n"
 msgstr "(®iadny popis)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6278,7 +6073,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "neplatný hashovací algoritmus `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6324,7 +6119,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "kµúè `%s' nebol nájdený: %s\n"
 
 #, fuzzy, c-format
@@ -6332,11 +6127,11 @@ msgid "error locking keybox: %s\n"
 msgstr "chyba pri èítaní bloku kµúèa: %s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "Revokaèný certifikát bol vytvorený.\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "duplicita predvoµby %c%lu\n"
 
 #, fuzzy, c-format
@@ -6373,6 +6168,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "zmeni» heslo"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "vytvor výstup zakódovaný pomocou ASCII"
 
@@ -6454,8 +6253,8 @@ msgstr "Pou
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Syntax: gpg [mo¾nosti] [súbory]\n"
 "podpísa», overi», ¹ifrova» alebo de¹ifrova»\n"
@@ -6466,11 +6265,11 @@ msgid "usage: gpgsm [options] "
 msgstr "pou¾itie: gpg [mo¾nosti] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "nemô¾em sa pripoji» k `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "neznámy implicitný adresát `%s'\n"
 
 #, fuzzy, c-format
@@ -6493,11 +6292,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "zapisujem do '%s'\n"
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "nemô¾em zavrie» `%s': %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6514,6 +6313,10 @@ msgstr "vytvori
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "nemô¾em inicializova» databázu dôvery: %s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "chyba pri vytváraní hesla: %s\n"
@@ -6527,11 +6330,14 @@ msgid "error reading input: %s\n"
 msgstr "chyba pri èítaní `%s': %s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "chyba pri vytváraní súboru kµúèov (keyring)`%s': %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "súbor kµúèov (keyring) `%s' vytvorený\n"
 
 #, fuzzy
@@ -6565,11 +6371,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "chyba: neplatný odtlaèok\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6690,7 +6496,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "neznámy implicitný adresát `%s'\n"
 
 #, fuzzy, c-format
@@ -6921,7 +6727,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "nemo¾no otvori» súbor: %s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "nemô¾em vytvori» adresár `%s': %s\n"
 
 #, fuzzy, c-format
@@ -7017,17 +6823,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "chyba pri èítaní `%s': %s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "nemô¾em inicializova» databázu dôvery: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Príkaz> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "databáza dôvery je po¹kodená; prosím spustite \"gpg --fix-trustdb\".\n"
@@ -7555,6 +7350,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "neplatný paket"
 
+#~ msgid "invalid armor"
+#~ msgstr "neplatný spôsob reprezentácie v ASCII"
+
 #~ msgid "no such user id"
 #~ msgstr "u¾ívateµ s týmto id neexistuje"
 
@@ -7564,6 +7362,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "bol pou¾itý nesprávny tajný kµúè"
 
+#~ msgid "not supported"
+#~ msgstr "nepodporované"
+
 #~ msgid "bad key"
 #~ msgstr "nesprávny kµúè"
 
@@ -7579,6 +7380,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "chyba pri vytváraní súboru"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "nesprávne heslo"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "algoritmus verejného kµúèa nie je implementovaný"
 
index 130d9ce..782bda5 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -1,8 +1,8 @@
 # Swedish messages for gnupg
-# Copyright (C) 1999-2011 Free Software Foundation, Inc.
+# Copyright (C) 1999-2008 Free Software Foundation, Inc.
+# Daniel Nylander <po@danielnylander.se>, 2006, 2007, 2008.
 # Per Tunedal <info@clipanish.com>, 2004.
 # Daniel Resare <daniel@resare.com>, 1999-2002.
-# Daniel Nylander <po@danielnylander.se>, 2006, 2007, 2008, 2011.
 #
 # ===================================================
 # This a completely revised and extended translation.
@@ -24,10 +24,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg trunk\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2011-01-12 14:53+0100\n"
+"PO-Revision-Date: 2008-07-21 09:04+0200\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
-"Language: sv\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -37,48 +36,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "misslyckades med att ta kontroll över PIN-inmatningslåset: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "_OK"
-
-msgid "|pinentry-label|_Cancel"
-msgstr "_Avbryt"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "_OK"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "_OK"
-
-msgid "|pinentry-label|PIN:"
-msgstr "PIN-kod:"
-
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "_Avbryt"
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Vill du verkligen spärra de valda undernycklarna? (j/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "Enter new passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "Ange ny lösenfras"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -111,9 +68,6 @@ msgid ""
 msgstr ""
 "Ange din lösenfras så att den hemliga nyckeln kan låsas upp för denna session"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (försök %d av %d)"
@@ -147,11 +101,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "ssh-nycklar större än %d bitar stöds inte\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "kan inte skapa \"%s\": %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "kan inte öppna \"%s\": %s\n"
 
 #, c-format
@@ -179,28 +133,16 @@ msgid "error writing key: %s\n"
 msgstr "fel vid skrivning av nyckel: %s\n"
 
 #, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
-#, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Ange lösenfrasen för ssh-nyckeln%0A  %c"
 
 msgid "Please re-enter this passphrase"
 msgstr "Ange denna lösenfras igen"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
 "Ange en lösenfras för att skydda den mottagna hemliga nyckeln%%0A   %s%%0Ai  "
 "gpg-agents nyckellager"
@@ -213,10 +155,10 @@ msgid "failed to create stream from socket: %s\n"
 msgstr "misslyckades med att skapa flöde från uttag: %s\n"
 
 msgid "Please insert the card with serial number"
-msgstr "Mata in kortet med serienummer"
+msgstr ""
 
 msgid "Please remove the current card and insert the one with serial number"
-msgstr "Ta bort det aktuella kortet och mata in det med serienummer"
+msgstr ""
 
 msgid "Admin PIN"
 msgstr "Admin PIN-kod"
@@ -224,30 +166,33 @@ msgstr "Admin PIN-kod"
 #. TRANSLATORS: A PUK is the Personal Unblocking Code
 #. used to unblock a PIN.
 msgid "PUK"
-msgstr "PUK-kod"
+msgstr ""
 
 msgid "Reset Code"
-msgstr "Nollställ kod"
+msgstr ""
 
-#, fuzzy, c-format
-#| msgid "%s%%0A%%0AUse the reader's keypad for input."
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
-msgstr "%s%%0A%%0AAnvänd läsarens knappsats för inmatning."
+#, c-format
+msgid "%s%%0A%%0AUse the reader's keypad for input."
+msgstr ""
 
+#, fuzzy
 msgid "Repeat this Reset Code"
-msgstr "Upprepa denna nollställningskod"
+msgstr "Upprepa denna PIN-kod"
 
+#, fuzzy
 msgid "Repeat this PUK"
-msgstr "Upprepa denna PUK-kod"
+msgstr "Upprepa denna PIN-kod"
 
 msgid "Repeat this PIN"
 msgstr "Upprepa denna PIN-kod"
 
+#, fuzzy
 msgid "Reset Code not correctly repeated; try again"
-msgstr "Nollställningskoden repeterades inte korrekt; försök igen"
+msgstr "PIN-kod repeterades inte korrekt; försök igen"
 
+#, fuzzy
 msgid "PUK not correctly repeated; try again"
-msgstr "PUK-koden repeterades inte korrekt; försök igen"
+msgstr "PIN-kod repeterades inte korrekt; försök igen"
 
 msgid "PIN not correctly repeated; try again"
 msgstr "PIN-kod repeterades inte korrekt; försök igen"
@@ -316,16 +261,15 @@ msgid ""
 "You have not entered a passphrase - this is in general a bad idea!%0APlease "
 "confirm that you do not want to have any protection on your key."
 msgstr ""
-"Du har inte angivet en lösenfras - det här är oftast en dålig idé!"
-"%0ABekräfta att du inte vill ha något som helst skydd för din nyckel."
+"Du har inte angivet en lösenfras - det här är oftast en dålig idé!%"
+"0ABekräfta att du inte vill ha något som helst skydd för din nyckel."
 
 msgid "Yes, protection is not needed"
 msgstr "Ja, skydd behövs inte"
 
 # fel kapitalisering i originalet?
-#, fuzzy, c-format
-#| msgid "Please enter the passphrase to%0Ato protect your new key"
-msgid "Please enter the passphrase to%0Aprotect your new key"
+#, c-format
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr "Ange lösenfrasen för%0Aför att skydda din nya nyckel"
 
 msgid "Please enter the new passphrase"
@@ -339,12 +283,12 @@ msgstr ""
 "@Flaggor:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "kör i demonläge (bakgrund)"
-
 msgid "run in server mode (foreground)"
 msgstr "kör i serverläge (förgrund)"
 
+msgid "run in daemon mode (background)"
+msgstr "kör i demonläge (bakgrund)"
+
 msgid "verbose"
 msgstr "utförlig"
 
@@ -394,37 +338,24 @@ msgid "do not use the PIN cache when signing"
 msgstr "använd inte mellanlagring av PIN-kod vid signering"
 
 # Antar att värdet inte ska översättas.
-#, fuzzy
-#| msgid "allow clients to mark keys as \"trusted\""
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr "tillåt klienter att markera nycklar som \"trusted\""
 
 msgid "allow presetting passphrase"
 msgstr "tillåt förinställning av lösenfras"
 
-#, fuzzy
-#| msgid "enable ssh-agent emulation"
-msgid "enable ssh support"
+msgid "enable ssh-agent emulation"
 msgstr "aktivera ssh-agent-emulering"
 
-msgid "enable putty support"
-msgstr ""
-
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "tillåt inte återanvändning av gamla lösenfraser"
-
 msgid "|FILE|write environment settings also to FILE"
-msgstr "|FIL|skriv även miljöinställningar till FIL"
+msgstr "|FIL|skriv miljöinställningar även till FIL"
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
+#, fuzzy
 msgid "Please report bugs to <@EMAIL@>.\n"
-msgstr ""
-"Rapportera fel till <@EMAIL@>.\n"
-"Skicka synpunkter på översättningen till <tp-sv@listor.tp-sv.se>.\n"
+msgstr "Rapportera fel till <"
 
 msgid "Usage: gpg-agent [options] (-h for help)"
 msgstr "Användning: gpg-agent [flaggor] (-h för hjälp)"
@@ -437,7 +368,7 @@ msgstr ""
 "Hantering av hemliga nycklar för GnuPG\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr "ogiltig debug-level \"%s\" angiven\n"
 
 #, c-format
@@ -445,23 +376,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr "%s är för gammal (behöver %s, har %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "OBS: inställningsfilen \"%s\" saknas\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "inställningsfil \"%s\": %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "läser inställningar från \"%s\"\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "Fel när \"%s\" skapades: %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "%s: kan inte skapa katalog: %s\n"
 
 msgid "name of socket too long\n"
@@ -472,7 +403,7 @@ msgid "can't create socket: %s\n"
 msgstr "kan inte skapa uttag: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "namnet på uttaget \"%s\" är för långt\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -483,7 +414,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "fel vid hämtning av nonce för uttaget\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "fel när \"%s\" bands till uttag: %s\n"
 
 #, c-format
@@ -491,19 +422,19 @@ msgid "listen() failed: %s\n"
 msgstr "listen() misslyckades: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "lyssnar på uttaget \"%s\"\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "katalogen \"%s\" skapades\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "stat() misslyckades för \"%s\": %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "kan inte använda \"%s\" som hemkatalog\n"
 
 #, c-format
@@ -613,31 +544,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "fel vid fråga efter lösenfrasen: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "fel vid öppnandet av \"%s\": %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "fil \"%s\", rad %d: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr "uttrycket \"%s\" ignorerat i \"%s\", rad %d\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "systemets tillitslista \"%s\" är inte tillgänglig\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "felaktigt fingeravtryck i \"%s\", rad %d\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr "ogiltig nyckelflagga i \"%s\", rad %d\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "fel vid läsning av \"%s\", rad %d: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -688,7 +619,7 @@ msgid "Correct"
 msgstr "Korrekt"
 
 msgid "Wrong"
-msgstr "Fel"
+msgstr ""
 
 #, c-format
 msgid "Note: This passphrase has never been changed.%0APlease change it now."
@@ -732,15 +663,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "fel vid hämtning av avslutskod för processen %d: %s\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "fel vid körning av \"%s\": avslutsstatus %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr "fel vid körning av \"%s\": antagligen inte installerat\n"
 
 #, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "fel vid körning av \"%s\": avslutades\n"
 
 #, c-format
@@ -754,7 +685,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "kunde inte få tillgång till GPG-Agent i denna session\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "kan inte ansluta till \"%s\": %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -828,44 +759,30 @@ msgstr "slut på kärna vid allokering av %lu byte"
 msgid "no running gpg-agent - starting one\n"
 msgstr "ingen körande gpg-agent - startar en\n"
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "väntar %d sekunder för att agenten ska komma igång\n"
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr "kan inte ansluta till agenten - försöker falla tillbaka\n"
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
 msgid "|audit-log-result|Good"
-msgstr "|audit-log-result|Bra"
+msgstr ""
 
 msgid "|audit-log-result|Bad"
-msgstr "|audit-log-result|Dålig"
+msgstr ""
 
 msgid "|audit-log-result|Not supported"
-msgstr "|audit-log-result|Stöds inte"
+msgstr ""
 
+#, fuzzy
 msgid "|audit-log-result|No certificate"
-msgstr "|audit-log-result|Inget certifikat"
+msgstr "importera certifikat"
 
+#, fuzzy
 msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|Inte aktiverat"
+msgstr "importera certifikat"
 
 msgid "|audit-log-result|Error"
-msgstr "|audit-log-result|Fel"
-
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|Används inte"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|Okej"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|Hoppades över"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|Några"
+msgstr ""
 
 msgid "Certificate chain available"
 msgstr "Certifikatkedja tillgänglig"
@@ -903,36 +820,21 @@ msgstr "Mottagare %d"
 msgid "Data signing succeeded"
 msgstr "Datasignering lyckades"
 
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "hashalgoritm för data: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "Signerare %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "hashalgoritm för attr: %s"
-
 msgid "Data decryption succeeded"
 msgstr "Datadekryptering lyckades"
 
-msgid "Encryption algorithm supported"
-msgstr "Krypteringsalgoritmen stöds"
-
 msgid "Data verification succeeded"
 msgstr "Datavalidering lyckades"
 
 msgid "Signature available"
 msgstr "Signatur tillgänglig"
 
-msgid "Parsing data succeeded"
-msgstr "Tolkning av data lyckades"
+msgid "Parsing signature succeeded"
+msgstr "Tolkning av signatur lyckades"
 
 #, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "felaktig hashalgoritm för data: %s"
+msgid "Bad hash algorithm: %s"
+msgstr "Felaktig hashalgoritm: %s"
 
 #, c-format
 msgid "Signature %d"
@@ -969,7 +871,7 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr användbar"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Det finns ingen hjälp tillgänglig för \"%s\"."
 
 msgid "ignoring garbage line"
@@ -1077,11 +979,13 @@ msgstr "OpenPGP-kort nr. %s identifierades\n"
 msgid "can't do this in batch mode\n"
 msgstr "kan inte göra detta i satsläge\n"
 
+#, fuzzy
 msgid "This command is only available for version 2 cards\n"
-msgstr "Detta kommando är endast tillgängligt för kort av version 2\n"
+msgstr "Detta kommando är inte tillåtet när du är i %s-läge.\n"
 
+#, fuzzy
 msgid "Reset Code not or not anymore available\n"
-msgstr "Återställningskoden är inte tillgänglig längre\n"
+msgstr "de hemliga nyckeldelarna är inte tillgängliga\n"
 
 msgid "Your selection? "
 msgstr "Vad väljer du? "
@@ -1135,11 +1039,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "fel vid allokering av tillräckligt mycket minne: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "fel vid läsning av \"%s\": %s\n"
 
-#, c-format
-msgid "error writing `%s': %s\n"
+#, fuzzy, c-format
+msgid "error writing '%s': %s\n"
 msgstr "fel vid skrivning till \"%s\": %s\n"
 
 msgid "Login data (account name): "
@@ -1196,22 +1100,18 @@ msgid ""
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
-"OBSERVERA: Det finns ingen garanti för att kortet har stöd för den\n"
-"      begärda storleken. Om nyckelgenereringen inte lyckas så bör du\n"
-"      kontrollera dokumentationen för ditt kort för att se vilka storlekar\n"
-"      som tillåts.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "Vilken nyckelstorlek vill du använda för signaturnyckeln? (%u) "
+msgstr "Vilken nyckelstorlek vill du ha? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "Vilken nyckelstorlek vill du använda för krypteringsnyckeln? (%u) "
+msgstr "Vilken nyckelstorlek vill du ha? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "Vilken nyckelstorlek vill du använda för autentiseringsnyckeln? (%u) "
+msgstr "Vilken nyckelstorlek vill du ha? (%u) "
 
 #, c-format
 msgid "rounded up to %u bits\n"
@@ -1224,18 +1124,17 @@ msgstr "%s nyckelstorlekar måste vara inom intervallet %u-%u\n"
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
 msgstr ""
-"Kortet kommer nu att konfigureras om för att generera en nyckel med %u "
-"bitar\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
-msgstr "fel vid ändring av storlek för nyckel %d till %u bitar: %s\n"
+msgstr "fel när \"%s\" bands till uttag: %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr "Skapa säkerhetskopia av krypteringsnyckel utanför kortet? (J/n) "
 
+#, fuzzy
 msgid "NOTE: keys are already stored on the card!\n"
-msgstr "OBSERVERA: nycklar har redan lagrats på kortet!\n"
+msgstr "hemlig nyckel redan lagrad på ett kort\n"
 
 msgid "Replace existing keys? (y/N) "
 msgstr "Ersätt existerande nycklar? (j/N) "
@@ -1277,9 +1176,9 @@ msgstr "hemliga delar av nyckeln är inte tillgängliga.\n"
 msgid "secret key already stored on a card\n"
 msgstr "hemlig nyckel redan lagrad på ett kort\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key to card: %s\n"
-msgstr "fel vid skrivning av nyckel till kort: %s\n"
+msgstr "fel vid skrivning av nyckel: %s\n"
 
 msgid "quit this menu"
 msgstr "avsluta denna meny"
@@ -1329,10 +1228,10 @@ msgid "verify the PIN and list all data"
 msgstr "validera PIN-koden och lista allt data"
 
 msgid "unblock the PIN using a Reset Code"
-msgstr "lås upp PIN-koden med en nollställningskod"
+msgstr ""
 
-msgid "gpg/card> "
-msgstr "gpg/kort> "
+msgid "Command> "
+msgstr "Kommando> "
 
 msgid "Admin-only command\n"
 msgstr "Kommandon endast för administratör\n"
@@ -1351,7 +1250,7 @@ msgstr "--output kan inte användas för detta kommando\n"
 
 # se förra kommentaren
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "kan inte öppna \"%s\"\n"
 
 #, c-format
@@ -1400,11 +1299,11 @@ msgid "using cipher %s\n"
 msgstr "använder %s-chiffer\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "\"%s\" är redan komprimerad\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "VARNING: \"%s\" är en tom fil\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1413,7 +1312,7 @@ msgstr ""
 "pgp2-läge\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "läser från \"%s\"\n"
 
 msgid ""
@@ -1480,11 +1379,11 @@ msgid "this platform requires temporary files when calling external programs\n"
 msgstr "denna plattform kräver temporärfiler vid anrop till externa program\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "kunde inte köra programmet \"%s\": %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "kunde inte köra skalet \"%s\": %s\n"
 
 #, c-format
@@ -1502,11 +1401,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "kan inte läsa svaret från det externa programmet: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "VARNING: kan inte ta bort tempfil (%s) \"%s\": %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "VARNING: kunde inte ta bort temp-katalogen \"%s\": %s\n"
 
 msgid "export signatures that are marked as local-only"
@@ -1566,15 +1465,11 @@ msgid "[User ID not found]"
 msgstr "[Användaridentiteten hittades inte]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "nyckel %s: hemlig nyckel utan publik nyckel - hoppades över\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "hämtade \"%s\" automatiskt via %s\n"
 
 #, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "fel vid hämtning av \"%s\" via %s: %s\n"
 
 msgid "No fingerprint"
@@ -1593,11 +1488,17 @@ msgstr "ingen hemlig undernyckel för publika undernyckeln %s - hoppar över\n"
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "använder undernyckeln %s istället för primära nyckeln %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "nyckel %s: hemlig nyckel utan publik nyckel - hoppades över\n"
+
+#, fuzzy
 msgid "make a signature"
-msgstr "skapa en signatur"
+msgstr "|[fil]|skapa en signatur"
 
+#, fuzzy
 msgid "make a clear text signature"
-msgstr "skapa en klartextsignatur"
+msgstr "|[fil]|skapa en klartextsignatur"
 
 msgid "make a detached signature"
 msgstr "skapa signatur i en separat fil"
@@ -1633,9 +1534,6 @@ msgstr "lista hemliga nycklar"
 msgid "generate a new key pair"
 msgstr "generera ett nytt nyckelpar"
 
-msgid "generate a revocation certificate"
-msgstr "generera ett spärrcertifikat"
-
 msgid "remove keys from the public keyring"
 msgstr "ta bort nycklar från den publika nyckelringen"
 
@@ -1651,8 +1549,8 @@ msgstr "signera en nyckel lokalt"
 msgid "sign or edit a key"
 msgstr "signera eller redigera en nyckel"
 
-msgid "change a passphrase"
-msgstr "ändra en lösenfras"
+msgid "generate a revocation certificate"
+msgstr "generera ett spärrcertifikat"
 
 msgid "export keys"
 msgstr "exportera nycklar"
@@ -1684,8 +1582,9 @@ msgstr "ändra PIN-kod för ett kort"
 msgid "update the trust database"
 msgstr "uppdatera tillitsdatabasen"
 
+#, fuzzy
 msgid "print message digests"
-msgstr "skriv ut kontrollsummor"
+msgstr "|algo [filer]|skriv ut kontrollsummor"
 
 msgid "run in server mode"
 msgstr "kör i serverläge"
@@ -1693,12 +1592,15 @@ msgstr "kör i serverläge"
 msgid "create ascii armored output"
 msgstr "skapa utdata med ett ascii-skal"
 
+#, fuzzy
 msgid "|USER-ID|encrypt for USER-ID"
-msgstr "|ANVÄNDAR-ID|kryptera för ANVÄNDAR-ID"
+msgstr "|NAMN|kryptera för NAMN"
 
+#, fuzzy
 msgid "|USER-ID|use USER-ID to sign or decrypt"
-msgstr "|ANVÄNDAR-ID|använd ANVÄNDAR-ID för att signera eller dekryptera"
+msgstr "använd denna användaridentitet för att signera eller dekryptera"
 
+#, fuzzy
 msgid "|N|set compress level to N (0 disables)"
 msgstr "|N|ställ in komprimeringsnivån till N (0 för att inaktivera)"
 
@@ -1749,15 +1651,10 @@ msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Användning: gpg [flaggor] [filer] (-h för hjälp)"
 
 # Om inget kommando anges (decrypt/encrypt etc) väljs åtgärd efter indata.
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Syntax: gpg [flaggor] [filer]\n"
 "signera, kontrollera, kryptera eller dekryptera\n"
@@ -1790,36 +1687,36 @@ msgstr "motstridiga kommandon\n"
 
 # Vad betyder detta?
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "no = signatur hittad i gruppdefinitionen \"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "VARNING: osäkert ägarskap på hemkatalogen \"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "VARNING: osäkert ägarskap på konfigurationsfilen \"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "VARNING: osäkert ägarskap på tillägget \"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "VARNING: osäkra rättigheter på hemkatalogen \"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "VARNING: osäkra rättigheter på konfigurationsfilen \"%s\"\n"
 
 # Extension är vad? FIXME
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "VARNING: osäkra rättigheter på tillägget \"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
 "VARNING: osäkert ägarskap på inneslutande katalog för hemkatalogen \"%s\"\n"
 
@@ -1827,16 +1724,16 @@ msgstr ""
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
 msgstr ""
-"VARNING: osäkert ägarskap på inneslutande katalog för konfigurationsfilen "
-"\"%s\"\n"
+"VARNING: osäkert ägarskap på inneslutande katalog för konfigurationsfilen \"%"
+"s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "VARNING: osäkert ägarskap på inneslutande katalog för tillägget \"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 "VARNING: osäkra rättigheter på inneslutande katalog för hemkatalogen \"%s\"\n"
 
@@ -1848,12 +1745,12 @@ msgstr ""
 "\"%s\"\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "VARNING: osäkra rättigheter på inneslutande katalog för tillägget \"%s\"\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "okänd konfigurationspost \"%s\"\n"
 
 msgid "display photo IDs during key listings"
@@ -1890,7 +1787,7 @@ msgid "show expiration dates during signature listings"
 msgstr "visa utgångsdatum under signaturlistningar"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "OBS: den gamla inställningsfilen \"%s\" används inte\n"
 
 #, c-format
@@ -1902,11 +1799,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "OBS: %s är inte för normal användning!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "\"%s\" är inte ett giltigt utgångsdatum för en signatur\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "\"%s\" är ingen giltig teckentabell\n"
 
 msgid "could not parse keyserver URL\n"
@@ -2084,16 +1981,16 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s fungerar ännu inte med  %s\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "du får inte använda chifferalgoritmen \"%s\" när du är i %s-läget\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr ""
 "du får inte använda sammandragsalgoritmen \"%s\" när du är i %s-läget\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr ""
 "du får inte använda komprimeringsalgoritmen \"%s\" när du är i %s-läget\n"
 
@@ -2112,7 +2009,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [filnamn]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "symmetrisk kryptering av \"%s\" misslyckades: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2163,9 +2060,6 @@ msgstr "--lsign-key användaridentitet"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key användaridentitet [kommandon]"
 
-msgid "--passwd <user-id>"
-msgstr "--passwd <användaridentitet>"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "sändning till nyckelservern misslyckades: %s\n"
@@ -2195,7 +2089,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "misslyckades med att skapa ASCII-skal: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "ogiltig kontrollsummealgoritm \"%s\"\n"
 
 msgid "[filename]"
@@ -2213,8 +2107,9 @@ msgstr "den angivna URL som beskriver signaturpolicy är ogiltig\n"
 msgid "the given preferred keyserver URL is invalid\n"
 msgstr "den angivna föredragna nyckelserver-url:n är ogiltig\n"
 
+#, fuzzy
 msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|FIL|ta nycklarna från nyckelringen FIL "
+msgstr "ta nycklarna från denna nyckelring "
 
 # Med detta kommando ger gnupg enbart en varning när ett meddelande är tidsstämplat i framtiden. Annars avslutas gnupg med ett felmeddelande.
 # Kommandot är avsett att användas i "near online system".
@@ -2228,18 +2123,19 @@ msgstr "|FD|skriv statusinformation till denna FD"
 msgid "Usage: gpgv [options] [files] (-h for help)"
 msgstr "Användning: gpgv [flaggor] [filer] (-h för hjälp)"
 
+#, fuzzy
 msgid ""
 "Syntax: gpgv [options] [files]\n"
 "Check signatures against known trusted keys\n"
 msgstr ""
-"Syntax: gpgv [flaggor] [filer]\n"
-"Kontrollera signaturer mot kända, pålitliga nycklar\n"
+"Syntax: gpg [flaggor] [filer]\n"
+"Kontrollera signaturerna mot kända nycklar\n"
 
 msgid "No help available"
 msgstr "Det finns ingen hjälp tillgänglig"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Det finns ingen hjälp tillgänglig för \"%s\""
 
 msgid "import signatures that are marked as local-only"
@@ -2248,11 +2144,6 @@ msgstr "importera signaturer som är markerade som endast lokala"
 msgid "repair damage from the pks keyserver during import"
 msgstr "reparera skada från pks-nyckelservern under importering"
 
-#, fuzzy
-#| msgid "do not update the trustdb after import"
-msgid "do not clear the ownertrust values during import"
-msgstr "uppdatera inte tillitsdatabasen efter importering"
-
 msgid "do not update the trustdb after import"
 msgstr "uppdatera inte tillitsdatabasen efter importering"
 
@@ -2373,14 +2264,6 @@ msgstr ""
 msgid "key %s: no user ID\n"
 msgstr "nyckel %s: ingen användaridentitet\n"
 
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s: %s\n"
-msgstr "hoppade över \"%s\": %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
 # Undernyckeln är skadad på HKP-servern. Vanligt fel vid många undernycklar.
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
@@ -2411,11 +2294,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "hittade ingen nyckelring som gick att skriva till: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "skriver till \"%s\"\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "fel vid skrivning av nyckelringen \"%s\": %s\n"
 
 # fixme: I appended the %s -wk
@@ -2479,18 +2362,13 @@ msgstr "nyckel %s: \"%s\" %d användaridentiteter rensade\n"
 msgid "key %s: \"%s\" not changed\n"
 msgstr "nyckel %s: \"%s\" inte ändrad\n"
 
-#, fuzzy, c-format
-#| msgid "secret key \"%s\" not found: %s\n"
-msgid "secret key %s: %s\n"
-msgstr "hemliga nyckeln \"%s\" hittades inte: %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "import av hemliga nycklar tillåts inte\n"
-
 #, c-format
 msgid "key %s: secret key with invalid cipher %d - skipped\n"
 msgstr "nyckel %s: hemlig nyckel med ogiltigt chiffer %d - hoppade över\n"
 
+msgid "importing secret keys not allowed\n"
+msgstr "import av hemliga nycklar tillåts inte\n"
+
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "ingen hemlig nyckelring angiven som standard: %s\n"
@@ -2535,18 +2413,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "nyckel %s: ogiltig självsignatur på användaridentiteten \"%s\"\n"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "nyckel %s: algoritmen för publika nycklar stöds inte\n"
-
-#, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "nyckel %s: ogiltig direkt nyckelsignatur\n"
-
-#, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "nyckel %s: ingen undernyckel för nyckelbindning\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "nyckel %s: algoritmen för publika nycklar stöds inte\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "nyckel %s: ogiltig undernyckelbindning\n"
 
@@ -2628,15 +2502,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "OBSERVERA: sekundärnyckeln är ansluten och lagrad på kort\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "fel när nyckelringen \"%s\" skapades: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "%s: nyckelring skapad\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "nyckelblockresurs \"%s\": %s\n"
 
 #, c-format
@@ -2828,7 +2702,7 @@ msgstr "   (2) Jag har gjort viss kontroll.%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Jag har gjort en noggrann kontroll.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Ditt val? (skriv \"?\" för mer information): "
 
 #, c-format
@@ -3070,7 +2944,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Tips: Välj de användaridentiteter som du vill signera\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Okänd signaturtyp \"%s\"\n"
 
 #, c-format
@@ -3101,11 +2975,11 @@ msgid "Command expects a filename argument\n"
 msgstr "Kommandot förväntar ett filnamnsargument\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "Kan inte öppna \"%s\": %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Fel vid läsning av säkerhetskopierad nyckel från \"%s\": %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3186,8 +3060,8 @@ msgstr ""
 "typ.\n"
 
 #, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "Följande nyckel blev spärrad den %s av %s nyckel %s\n"
+msgid "This key was revoked on %s by %s key %s\n"
+msgstr "Den här nyckeln blev spärrad den %s av %s nyckel %s\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
@@ -3251,14 +3125,6 @@ msgstr ""
 "Detta kommando kan göra att en annan användaridentitet antas\n"
 "vara den primära identiteten.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Du kan inte ändra giltighetsdatum för en v3-nyckel\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3439,7 +3305,7 @@ msgid "Create a revocation certificate for this signature? (y/N) "
 msgstr "Vill du skapa ett spärrcertifikat för denna signatur? (j/N)"
 
 msgid "Not signed by you.\n"
-msgstr "Inte signerad av dig.\n"
+msgstr ""
 
 #, c-format
 msgid "You have signed these user IDs on key %s:\n"
@@ -3484,7 +3350,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Visar %s foto-id med storleken %ld för nyckeln %s (uid %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "inställningen \"%s\" förekommer flera gånger\n"
 
 msgid "too many cipher preferences\n"
@@ -3497,7 +3363,7 @@ msgid "too many compression preferences\n"
 msgstr "för många komprimeringsinställningar\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "ogiltig post \"%s\" i inställningssträngen\n"
 
 msgid "writing direct signature\n"
@@ -3578,13 +3444,13 @@ msgstr "   (%c) Färdig\n"
 msgid "Please select what kind of key you want:\n"
 msgstr "Välj vilken typ av nyckel du vill ha:\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) RSA and RSA (default)\n"
-msgstr "   (%d) RSA och RSA (standard)\n"
+msgstr "   (%d) DSA och Elgamal (standard)\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "   (%d) DSA and Elgamal\n"
-msgstr "   (%d) DSA och Elgamal\n"
+msgstr "   (%d) DSA och Elgamal (standard)\n"
 
 #, c-format
 msgid "   (%d) DSA (sign only)\n"
@@ -3614,9 +3480,9 @@ msgstr "   (%d) RSA (ställ in dina egna förmågor)\n"
 msgid "%s keys may be between %u and %u bits long.\n"
 msgstr "%s-nycklar kan vara mellan %u och %u bitar långa.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the subkey? (%u) "
-msgstr "Vilken nyckelstorlek vill du använda för undernyckeln? (%u) "
+msgstr "Vilken nyckelstorlek vill du ha? (%u) "
 
 #, c-format
 msgid "What keysize do you want? (%u) "
@@ -3748,7 +3614,7 @@ msgid "Invalid character in comment\n"
 msgstr "Ogiltigt tecken i kommentaren\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Du använder teckentabellen \"%s\"\n"
 
 #, c-format
@@ -3757,7 +3623,7 @@ msgid ""
 "    \"%s\"\n"
 "\n"
 msgstr ""
-"Du valde följande ANVÄNDAR-ID:\n"
+"Du valde följande användaridentitet:\n"
 "    \"%s\"\n"
 "\n"
 
@@ -3765,7 +3631,7 @@ msgid "Please don't put the email address into the real name or the comment\n"
 msgstr "Ange inte e-postadressen som namn eller kommentar\n"
 
 msgid "Such a user ID already exists on this key!\n"
-msgstr "En sådan användaridentitet finns redan på denna nyckel!\n"
+msgstr ""
 
 # Ej solklart vad förkortningarna står för
 #. TRANSLATORS: These are the allowed answers in
@@ -3799,12 +3665,12 @@ msgstr ""
 "Du behöver en lösenfras för att skydda din hemliga nyckel\n"
 "\n"
 
+#, fuzzy
 msgid ""
 "Please enter a passphrase to protect the off-card backup of the new "
 "encryption key."
 msgstr ""
-"Ange en lösenfras för att skydda säkerhetskopian av den nya "
-"krypteringsnyckeln."
+"Ange lösenfrasen för att skydda det importerade objektet inom GnuPG-systemet."
 
 #, c-format
 msgid "%s.\n"
@@ -3836,15 +3702,15 @@ msgid "Key generation canceled.\n"
 msgstr "Skapandet av nycklar avbröts.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "skriver den publika nyckeln till \"%s\"\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "skriver hemliga nyckelstumpen till \"%s\"\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "skriver hemlig nyckel till \"%s\"\n"
 
 #, c-format
@@ -3856,11 +3722,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "ingen skrivbar hemlig nyckelring hittades: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "fel vid skrivning av publika nyckelringen \"%s\": %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "fel vid skrivning av hemliga nyckelringen \"%s\": %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3905,11 +3771,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "misslyckades med att lagra nyckeln på kortet: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "kan inte skapa säkerhetskopian \"%s\": %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "OBSERVERA: säkerhetskopia av kortnyckeln sparades i \"%s\"\n"
 
 msgid "never     "
@@ -3950,16 +3816,11 @@ msgstr "   Undernyckelns fingeravtryck:"
 msgid "      Key fingerprint ="
 msgstr "Nyckelns fingeravtryck ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "VARNING: använder experimentella sammandragsalgoritmen %s\n"
-
 msgid "      Card serial no. ="
 msgstr "       Kortets serienr ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "namnbyte från \"%s\" till \"%s\" misslyckades: %s\n"
 
 # Enligt Werner uppstår detta om något går snett när den hemliga nyckeln uppdateras.
@@ -3978,7 +3839,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Lös detta potentiella säkerhetsproblem\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "mellanlagrar nyckelringen \"%s\"\n"
 
 #, c-format
@@ -4016,7 +3877,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "respektera PKA-posten inställd på en nyckel när nycklar hämtas"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "VARNING: nyckelserverflaggan \"%s\" används inte på den här plattformen\n"
 
@@ -4079,10 +3940,6 @@ msgstr "VARNING: nyckelserverhanteraren från en annan version av GnuPG (%s)\n"
 msgid "keyserver did not send VERSION\n"
 msgstr "nyckelserver skickade inte VERSION\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "kommunikationsfel mot nyckelserver: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "ingen nyckelserver är känd (använd flaggan --keyserver)\n"
 
@@ -4090,11 +3947,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr "externa anrop till nyckelserver stöds inte i detta bygge\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr "ingen hanterare för nyckelserverschemat \"%s\"\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr "åtgärden \"%s\" stöds inte med nyckelserverschemat \"%s\"\n"
 
 #, c-format
@@ -4108,6 +3965,10 @@ msgid "keyserver internal error\n"
 msgstr "internt fel i nyckelserver\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "kommunikationsfel mot nyckelserver: %s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "\"%s\" inte ett nyckel-id: hoppar över\n"
 
@@ -4198,7 +4059,7 @@ msgstr "VARNING: det krypterade meddelandet har ändrats!\n"
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
-msgstr "tömde mellanlagrad lösenfras med ID: %s\n"
+msgstr ""
 
 #, c-format
 msgid "decryption failed: %s\n"
@@ -4286,10 +4147,6 @@ msgid "unknown"
 msgstr "okänd"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Kan inte kontrollera signaturen: %s\n"
 
@@ -4313,7 +4170,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "ogiltigt rotpaket hittades i proc_tree()\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "fstat för \"%s\" misslyckades i %s: %s\n"
 
 #, c-format
@@ -4339,11 +4196,6 @@ msgstr "VARNING: använder experimentella sammandragsalgoritmen %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "VARNING: sammandragsalgoritmen %s är föråldrad\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s signatur, sammandragsalgoritm %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "insticksmodul för IDEA-chiffer är inte installerat\n"
 
@@ -4375,17 +4227,6 @@ msgstr "%s:%u: föråldrad flagga \"%s\" - den har ingen effekt\n"
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "VARNING: \"%s\" är en föråldrad flagga - den har ingen effekt\n"
 
-#, fuzzy, c-format
-#| msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: föråldrad flagga \"%s\" - den har ingen effekt\n"
-
-#, fuzzy, c-format
-#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "VARNING: \"%s\" är en föråldrad flagga - den har ingen effekt\n"
-
 msgid "Uncompressed"
 msgstr "Okomprimerad"
 
@@ -4398,15 +4239,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "detta meddelande kanske inte kan användas av %s\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "tvetydlig flagga \"%s\"\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "okänd flagga \"%s\"\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Filen \"%s\" finns. "
 
 msgid "Overwrite? (y/N) "
@@ -4422,17 +4263,16 @@ msgstr "Ange nytt filnamn"
 msgid "writing to stdout\n"
 msgstr "skriver till standard ut\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "antar att signerad data finns i filen \"%s\"\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "ny konfigurationsfil \"%s\" skapad\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "VARNING: inställningar i \"%s\" är ännu inte aktiva under denna körning\n"
 
@@ -4448,10 +4288,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "underpaket av typen %d har den bit satt som markerar den som kritisk\n"
 
 #, c-format
-msgid "problem with the agent: %s\n"
-msgstr "problem med agenten: %s\n"
-
-#, c-format
 msgid " (main key ID %s)"
 msgstr " (primära nyckelns id %s)"
 
@@ -4476,6 +4312,10 @@ msgid "cancelled by user\n"
 msgstr "avbruten av användaren\n"
 
 #, c-format
+msgid "problem with the agent: %s\n"
+msgstr "problem med agenten: %s\n"
+
+#, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4508,7 +4348,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Skriv JPEG-filnamnet för foto-id: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "kunde inte öppna JPEG-filen \"%s\": %s\n"
 
 #, c-format
@@ -4520,7 +4360,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Vill du verkligen använda den? (j/N)? "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "\"%s\" är inte en JPEG-fil\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4553,16 +4393,6 @@ msgid "revocation comment: "
 msgstr "spärrningskommentar: "
 
 # ej kristallklart vad förkortningarna står för
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImHhAsS"
 
@@ -4667,11 +4497,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Obs: Denna nyckel har stängts av.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr "Observera: Validerad adress för signeraren är \"%s\"\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr "Observera: Signerarens adress \"%s\" matchar inte DNS-objektet\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4780,7 +4610,7 @@ msgstr "ingen signerad data\n"
 
 # se förra kommentaren
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "kan inte öppna signerat data \"%s\"\n"
 
 # se förra kommentaren
@@ -5106,7 +4936,7 @@ msgstr ""
 "# (Använd \"gpg --import-ownertrust\" för att återställa dem)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "fel i \"%s\": %s\n"
 
 msgid "line too long"
@@ -5122,11 +4952,11 @@ msgid "ownertrust value missing"
 msgstr "värde för ägartillit saknas"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "fel vid sökning av tillitsvärde i \"%s\": %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "läsfel i \"%s\":  %s\n"
 
 #, c-format
@@ -5134,15 +4964,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "tillitsdatabas: synkronisering misslyckades: %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "kan inte skapa lås för \"%s\"\n"
-
-# se förra kommentaren
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "kan inte låsa \"%s\"\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "tillitsdatabasposten %lu: lseek misslyckades: %s\n"
 
@@ -5154,12 +4975,21 @@ msgid "trustdb transaction too large\n"
 msgstr "tillitsdatabastransaktion för stor\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "kan inte komma åt \"%s\": %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: katalogen finns inte!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kan inte komma åt \"%s\": %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "kan inte skapa lås för \"%s\"\n"
+
+# se förra kommentaren
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "kan inte låsa \"%s\"\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5232,8 +5062,9 @@ msgstr "%s: misslyckades med att nollställa en post: %s\n"
 msgid "%s: failed to append a record: %s\n"
 msgstr "%s: misslyckades med att lägga till en post: %s\n"
 
+#, fuzzy
 msgid "Error: The trustdb is corrupted.\n"
-msgstr "Fel: Tillitsdatabasen är skadad.\n"
+msgstr "%s: tillitsdatabas skapad\n"
 
 #, c-format
 msgid "can't handle text lines longer than %d characters\n"
@@ -5244,7 +5075,7 @@ msgid "input line longer than %d characters\n"
 msgstr "indataraden är längre än %d tecken\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "\"%s\" är inget giltigt långt nyckel-id\n"
 
 # trusted??
@@ -5276,10 +5107,10 @@ msgid "trust record %lu is not of requested type %d\n"
 msgstr "tillitsvärdet %lu är inte av begärd typ %d\n"
 
 msgid "You may try to re-create the trustdb using the commands:\n"
-msgstr "Du kan försöka att skapa tillitsdatabasen igen med dessa kommandon:\n"
+msgstr ""
 
 msgid "If that does not work, please consult the manual\n"
-msgstr "Referera till handboken om detta inte fungerar för dig\n"
+msgstr ""
 
 #, c-format
 msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
@@ -5299,14 +5130,6 @@ msgstr "använder tillitsmodellen %s\n"
 #    It gets passed to atoi() so everything after the number is
 #    essentially a comment and need not be translated.  Either key and
 #    uid are both NULL, or neither are NULL. */
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr "15"
 
@@ -5354,12 +5177,12 @@ msgid "next trustdb check due at %s\n"
 msgstr "nästa kontroll av tillitsdatabasen kommer att äga rum %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr ""
 "det behövs ingen kontroll av tillitsdatabasen med tillitsmodellen \"%s\"\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr ""
 "det behövs ingen uppdatering av tillitsdatabasen med tillitsmodellen \"%s\"\n"
 
@@ -5431,19 +5254,15 @@ msgstr "nyckelordet är för långt"
 msgid "missing argument"
 msgstr "argument saknas"
 
-#, fuzzy
-#| msgid "invalid value\n"
-msgid "invalid argument"
-msgstr "ogiltigt värde\n"
-
 msgid "invalid command"
 msgstr "ogiltigt kommando"
 
 msgid "invalid alias definition"
 msgstr "ogiltig aliasdefinition"
 
+#, fuzzy
 msgid "out of core"
-msgstr "slut på minne"
+msgstr "[Fel - slut på kärna]"
 
 msgid "invalid option"
 msgstr "ogiltig flagga"
@@ -5452,11 +5271,6 @@ msgstr "ogiltig flagga"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr "argument för flaggan \"%.50s\" saknas\n"
 
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "argument för flaggan \"%.50s\" saknas\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr "flaggan \"%.50s\" förväntar sig inte ett argument\n"
@@ -5473,8 +5287,9 @@ msgstr "flagga \"%.50s\" är tvetydig\n"
 msgid "command \"%.50s\" is ambiguous\n"
 msgstr "kommandot \"%.50s\" är tvetydigt\n"
 
+#, fuzzy
 msgid "out of core\n"
-msgstr "slut på minne\n"
+msgstr "[Fel - slut på kärna]"
 
 #, c-format
 msgid "invalid option \"%.50s\"\n"
@@ -5485,7 +5300,11 @@ msgid "you found a bug ... (%s:%d)\n"
 msgstr "du har hittat ett fel i programmet ... (%s:%d)\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "error loading '%s': %s\n"
+msgstr "fel vid inläsning av \"%s\": %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr "konvertering från \"%s\" till \"%s\" är inte tillgänglig\n"
 
 #, c-format
@@ -5493,15 +5312,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "iconv_open misslyckades: %s\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "konvertering från \"%s\" till \"%s\" misslyckades: %s\n"
 
 #, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "misslyckades med att skapa temporärfilen \"%s\": %s\n"
 
 #, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "fel vid skrivning till \"%s\": %s\n"
 
 #, c-format
@@ -5519,7 +5338,7 @@ msgid "(deadlock?) "
 msgstr "(dödläge?) "
 
 #, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "låset \"%s\" gjordes inte: %s\n"
 
 #, c-format
@@ -5535,13 +5354,9 @@ msgstr "aktivera fullständigt felsökningsläge"
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Användning: kbxutil [flaggor] [filer] (-h för hjälp)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: kbxutil [options] [files]\n"
-#| "list, export, import Keybox data\n"
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
 "Syntax: kbxutil [flaggor] [filer]\n"
 "lista, exportera, importera nyckelskåpsdata\n"
@@ -5561,38 +5376,37 @@ msgstr "PIN-återanrop returnerade fel: %s\n"
 msgid "the NullPIN has not yet been changed\n"
 msgstr "NullPIN har ännu inte ändrats\n"
 
+#, fuzzy
 msgid "|N|Please enter a new PIN for the standard keys."
-msgstr "|N|Ange en ny PIN-kod för standardnycklarna."
+msgstr "||Knappa in din PIN-kod på läsarens knappsats"
 
+#, fuzzy
 msgid "||Please enter the PIN for the standard keys."
-msgstr "||Ange PIN-koden för standardnycklarna."
+msgstr "|A|Ange administratörens PIN-kod på läsarens knappsats"
 
+#, fuzzy
 msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|NP|Ange en ny upplåsningskod (PUK-kod) för standardnycklarna."
+msgstr "Ange PIN-koden%s%s%s för att låsa upp kortet"
 
+#, fuzzy
 msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys."
-msgstr "|P|Ange upplåsningskoden (PUK-kod) för standardnycklarna."
+msgstr "Ange PIN-koden%s%s%s för att låsa upp kortet"
 
 msgid "|N|Please enter a new PIN for the key to create qualified signatures."
 msgstr ""
-"|N|Ange en ny PIN-kod för nyckeln att skapa kvalificerade signaturer med."
 
 msgid "||Please enter the PIN for the key to create qualified signatures."
-msgstr "||Ange PIN-koden för nyckeln att skapa kvalificerade signaturer med."
+msgstr ""
 
 msgid ""
 "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|NP|Ange en ny upplåsningskod (PUK-kod) för nyckeln att skapa kvalificerade "
-"signaturer med."
 
 msgid ""
 "|P|Please enter the PIN Unblocking Code (PUK) for the key to create "
 "qualified signatures."
 msgstr ""
-"|P|Ange upplåsningskoden (PUK-koden) för nyckeln att skapa kvalificerade "
-"signaturer med."
 
 #, c-format
 msgid "error getting new PIN: %s\n"
@@ -5633,8 +5447,9 @@ msgstr ""
 msgid "||Please enter the PIN%%0A[sigs done: %lu]"
 msgstr "||Ange PIN-koden%%0A[signaturer kvar: %lu]"
 
+#, fuzzy
 msgid "||Please enter the PIN"
-msgstr "||Ange PIN-koden"
+msgstr "||Ange PIN-koden%%0A[signaturer kvar: %lu]"
 
 #, c-format
 msgid "PIN for CHV%d is too short; minimum length is %d\n"
@@ -5656,28 +5471,29 @@ msgstr "%d försök för Admin PIN-koden återstår innan kortet låses permanen
 
 #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at
 #. the start of the string.  Use %%0A to force a linefeed.
-#, c-format
+#, fuzzy, c-format
 msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
-msgstr "|A|Ange administratörens PIN-kod%%0A[återstående försök: %d]"
+msgstr ""
+"|A|Ange administratörens PIN-kod på läsarens knappsats%%0A[återstående "
+"försök: %d]"
 
+#, fuzzy
 msgid "|A|Please enter the Admin PIN"
-msgstr "|A|Ange administratörens PIN-kod"
+msgstr "||Ange PIN-koden%%0A[signaturer kvar: %lu]"
 
 msgid "access to admin commands is not configured\n"
 msgstr "åtkomst till administrationskommandon är inte konfigurerat\n"
 
+#, fuzzy
 msgid "||Please enter the Reset Code for the card"
-msgstr "||Ange nollställningskoden för kortet"
+msgstr "Ange PIN-koden%s%s%s för att låsa upp kortet"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Reset Code is too short; minimum length is %d\n"
-msgstr "Nollställningskoden är för kort; minimumlängd är %d\n"
+msgstr "PIN-kod för CHV%d är för kort; minimumlängd är %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
-msgstr "|RN|Ny nollställningskod"
+msgstr ""
 
 msgid "|AN|New Admin PIN"
 msgstr "|AN|Ny Admin PIN-kod"
@@ -5685,16 +5501,6 @@ msgstr "|AN|Ny Admin PIN-kod"
 msgid "|N|New PIN"
 msgstr "|N|Ny PIN-kod"
 
-#, fuzzy
-#| msgid "|A|Please enter the Admin PIN"
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "|A|Ange administratörens PIN-kod"
-
-#, fuzzy
-#| msgid "||Please enter the PIN"
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Ange PIN-koden"
-
 msgid "error reading application data\n"
 msgstr "fel vid läsning av programdata\n"
 
@@ -5710,8 +5516,9 @@ msgstr "befintlig nyckel kommer att ersättas\n"
 msgid "generating new key\n"
 msgstr "genererar ny nyckel\n"
 
+#, fuzzy
 msgid "writing new key\n"
-msgstr "skriver ny nyckel\n"
+msgstr "genererar ny nyckel\n"
 
 msgid "creation timestamp missing\n"
 msgstr "tidsstämpel för skapandet saknas\n"
@@ -5758,9 +5565,7 @@ msgstr ""
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "kan inte komma åt %s - ogiltigt OpenPGP-kort?\n"
 
-#, fuzzy
-#| msgid "||Please enter your PIN at the reader's keypad"
-msgid "||Please enter your PIN at the reader's pinpad"
+msgid "||Please enter your PIN at the reader's keypad"
 msgstr "||Knappa in din PIN-kod på läsarens knappsats"
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
@@ -5775,8 +5580,9 @@ msgstr "kör i multiserverläge (förgrund)"
 msgid "|LEVEL|set the debugging level to LEVEL"
 msgstr "|NIVÅ|ställ in felsökningsnivån till NIVÅ"
 
+#, fuzzy
 msgid "|FILE|write a log to FILE"
-msgstr "|FIL|skriv en logg till FIL"
+msgstr "|FIL|skriv en granskningslogg till FIL"
 
 msgid "|N|connect to reader at port N"
 msgstr "|N|anslut till läsare på port N"
@@ -5791,18 +5597,14 @@ msgid "do not use the internal CCID driver"
 msgstr "använd inte den interna CCID-drivrutinen"
 
 msgid "|N|disconnect the card after N seconds of inactivity"
-msgstr "|N|koppla från kortet efter N sekunder inaktivitet"
+msgstr ""
 
-#, fuzzy
-#| msgid "do not use a reader's keypad"
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr "använd inte läsarens knappsats"
 
+#, fuzzy
 msgid "deny the use of admin card commands"
-msgstr "neka användning av administratörskommandon för kort"
-
-msgid "use variable length input for pinpad"
-msgstr ""
+msgstr "tillåt användning av administratörskommandon för kort"
 
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Användning: scdaemon [flaggor] (-h för hjälp)"
@@ -5814,7 +5616,7 @@ msgstr ""
 "Syntax: scdaemon [flaggor] [kommando [argument]]\n"
 "Smartkortsdemon för GnuPG\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr "använd flaggan \"--daemon\" för att köra programmet i bakgrunden\n"
 
 #, c-format
@@ -5835,7 +5637,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr "misslyckades med att förmedla %s-begäran till klient\n"
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr "ingen körande dirmngr - startar \"%s\"\n"
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
@@ -5869,7 +5671,7 @@ msgid "critical marked policy without configured policies"
 msgstr "kritisk markerad policy utan konfigurerade policier"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "misslyckades med att öppna \"%s\": %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5896,7 +5698,7 @@ msgstr "antal matchande certifikat: %d\n"
 msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "uppslag av endast-mellanlagrad dirmngr-nyckel misslyckades: %s\n"
 
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "misslyckades med att allokera keyDB-hanterare\n"
 
 msgid "certificate has been revoked"
@@ -6071,24 +5873,16 @@ msgstr "ingen nyckelanvändning angiven - antar alla användningsområden\n"
 msgid "error getting key usage information: %s\n"
 msgstr "fel vid hämtning av nyckelanvändningsinformation: %s\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for certification\n"
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr "certifikatet skulle inte använts för certifiering\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for OCSP response signing\n"
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr "certifikatet skulle inte använts för signering av OCSP-svar\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for encryption\n"
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr "certifikatet skulle inte använts för kryptering\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for signing\n"
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr "certifikatet skulle inte använts för signering\n"
 
 msgid "certificate is not usable for encryption\n"
@@ -6110,11 +5904,11 @@ msgid "line %d: no subject name given\n"
 msgstr "rad %d: inget ämnesnamn angivit\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr "rad %d: ogiltig ämnesnamnsetikett \"%.*s\"\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr "rad %d: ogiltigt ämnesnamn \"%s\" på position %d\n"
 
 #, c-format
@@ -6122,13 +5916,13 @@ msgid "line %d: not a valid email address\n"
 msgstr "rad %d: inte en giltig e-postadress\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "rad %d: fel vid läsning av nyckeln \"%s\" från kortet: %s\n"
 
 # keygrip (i.e. a hash over the public key
 # parameters) formatted as a hex string.
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "rad %d: fel vid hämtning av nyckelhashen \"%s\": %s\n"
 
 #, c-format
@@ -6139,8 +5933,6 @@ msgid ""
 "To complete this certificate request please enter the passphrase for the key "
 "you just created once more.\n"
 msgstr ""
-"Ange lösenfrasen en gång till för nyckeln som du just skapade för att "
-"färdigställa denna certifikatbegäran.\n"
 
 #, c-format
 msgid "   (%d) RSA\n"
@@ -6154,25 +5946,28 @@ msgstr "   (%d) Befintlig nyckel\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Befintlig nyckel från kort\n"
 
+#, fuzzy
 msgid "Enter the keygrip: "
-msgstr "Ange nyckelhashen: "
+msgstr "Ange notationen: "
 
 msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Inte en giltig nyckelhash (förväntade 40 hexadecimala siffror)\n"
+msgstr ""
 
+#, fuzzy
 msgid "No key with this keygrip\n"
-msgstr "Ingen nyckel med denna nyckelhash\n"
+msgstr "Ingen undernyckel med indexet %d\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading the card: %s\n"
-msgstr "fel vid läsning av kortet: %s\n"
+msgstr "%s: fel vid läsning av ledig post: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Serial number of the card: %s\n"
-msgstr "Serienummer för kortet: %s\n"
+msgstr "fel när serienumret hämtades från kortet: %s\n"
 
+#, fuzzy
 msgid "Available keys:\n"
-msgstr "Tillgängliga nycklar:\n"
+msgstr "inaktivera nyckel"
 
 #, c-format
 msgid "Possible actions for a %s key:\n"
@@ -6197,7 +5992,7 @@ msgid "No subject name given\n"
 msgstr "Inget ämnesnamn angivet\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr "Ogiltig ämnesnamnsetikett \"%.*s\"\n"
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6206,7 +6001,7 @@ msgstr "Ogiltig ämnesnamnsetikett \"%.*s\"\n"
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "Ogiltigt ämnesnamn \"%s\"\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6237,8 +6032,9 @@ msgid "Ready.  You should now send this request to your CA.\n"
 msgstr ""
 "Färdig.  Du bör nu skicka denna begäran till din certifikatutfärdare.\n"
 
+#, fuzzy
 msgid "resource problem: out of core\n"
-msgstr "resursproblem: slut på minne\n"
+msgstr "resursproblem: out or core\n"
 
 msgid "(this is the RC2 algorithm)\n"
 msgstr "(det här är RC2-algoritmen)\n"
@@ -6247,7 +6043,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(det här verkar inte vara ett krypterat meddelande)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "certifikatet \"%s\" hittades inte: %s\n"
 
 #, c-format
@@ -6255,11 +6051,11 @@ msgid "error locking keybox: %s\n"
 msgstr "fel vid låsning av nyckelskåp: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "dubblett av certifikatet \"%s\" borttaget\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "certifikatet \"%s\" togs bort\n"
 
 #, c-format
@@ -6290,6 +6086,9 @@ msgstr "skicka ett kommando till dirmngr"
 msgid "invoke gpg-protect-tool"
 msgstr "starta gpg-protect-tool"
 
+msgid "change a passphrase"
+msgstr "ändra en lösenfras"
+
 msgid "create base-64 encoded output"
 msgstr "skapa base-64-kodat utdata"
 
@@ -6341,11 +6140,13 @@ msgstr "anta ja på de flesta frågorna"
 msgid "assume no on most questions"
 msgstr "anta nej på de flesta frågorna"
 
+#, fuzzy
 msgid "|FILE|add keyring to the list of keyrings"
-msgstr "|FIL|lägg till nyckelring till listan över nyckelringar"
+msgstr "lägg till denna nyckelring till listan över nyckelringar"
 
+#, fuzzy
 msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|ANVÄNDAR-ID|använd ANVÄNDAR-ID som förvald hemlig nyckel"
+msgstr "|NAMN|använd NAMN som förvald hemlig nyckel"
 
 msgid "|SPEC|use this keyserver to lookup keys"
 msgstr "|SPEC|använd denna nyckelserver för att slå upp nycklar"
@@ -6354,21 +6155,16 @@ msgid "|NAME|use cipher algorithm NAME"
 msgstr "|NAMN|använd chifferalgoritmen NAMN"
 
 msgid "|NAME|use message digest algorithm NAME"
-msgstr "|NAMN|använd algoritmen NAMN för kontrollsummor"
+msgstr "|NAMN|använd sammandragsalgoritmen NAMN"
 
 msgid "Usage: gpgsm [options] [files] (-h for help)"
 msgstr "Användning: gpgsm [flaggor] [filer] (-h för hjälp)"
 
 # Om inget kommando anges (decrypt/encrypt etc) väljs åtgärd efter indata.
-#, fuzzy
-#| 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"
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Syntax: gpgsm [flaggor] [filer]\n"
 "signera, kontrollera, kryptera eller dekryptera med S/MIME-protokollet\n"
@@ -6378,11 +6174,11 @@ msgid "usage: gpgsm [options] "
 msgstr "användning: gpgsm [flaggor] "
 
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "OBSERVERA: kommer inte att kunna kryptera till \"%s\": %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "okänd valideringsmodell \"%s\"\n"
 
 #, c-format
@@ -6404,11 +6200,11 @@ msgid "WARNING: running with faked system time: "
 msgstr "VARNING: kör med falsk systemtid: "
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "importerar vanliga certifikat \"%s\"\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "kan inte signera med \"%s\": %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6424,6 +6220,9 @@ msgstr "fel vid lagring av certifikat\n"
 msgid "basic certificate checks failed - not imported\n"
 msgstr "enkla certifikatkontroller misslyckades - importeras inte\n"
 
+msgid "failed to allocate keyDB handle\n"
+msgstr "misslyckades med att allokera keyDB-hanterare\n"
+
 #, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "fel vid hämtning av lagrade flaggor: %s\n"
@@ -6437,11 +6236,14 @@ msgid "error reading input: %s\n"
 msgstr "fel vid läsning av indata: %s\n"
 
 #, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "fel när nyckelskåpet \"%s\" skapades: %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr "du kanske vill starta gpg-agent först\n"
+
 #, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "nyckelskåpet \"%s\" skapat\n"
 
 msgid "failed to get the fingerprint\n"
@@ -6475,11 +6277,11 @@ msgstr ""
 "GPG_TTY har inte ställts in - använder kanske felaktigt standardvärde\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "ogiltigt formaterat fingeravtryck i \"%s\", rad %d\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr "ogiltig landskod i \"%s\", rad %d\n"
 
 #, c-format
@@ -6541,7 +6343,7 @@ msgstr " använder certifikat-id 0x%08lX\n"
 msgid ""
 "invalid signature: message digest attribute does not match computed one\n"
 msgstr ""
-"ogiltig signatur: attribut för kontrollsumma matchar inte den beräknade\n"
+"ogiltig signatur: meddelandesammandragsattribut matchar inte den beräknade\n"
 
 msgid "Good signature from"
 msgstr "Korrekt signatur från"
@@ -6605,7 +6407,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr "rad nerkortad på grund av inbäddat Nul-tecken\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "okänt kommando \"%s\"\n"
 
 #, c-format
@@ -6826,7 +6628,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "%s på %s misslyckades med status %i\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "kan inte skapa temporärkatalogen \"%s\": %s\n"
 
 #, c-format
@@ -6924,18 +6726,6 @@ msgstr ""
 "Syntax: gpg-check-pattern [flaggor] mönsterfil\n"
 "Kontrollera en lösenfras angiven på standard in mot mönsterfilen\n"
 
-#~ msgid "you may want to start the gpg-agent first\n"
-#~ msgstr "du kanske vill starta gpg-agent först\n"
-
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "fel vid inläsning av \"%s\": %s\n"
-
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "misslyckades med att allokera keyDB-hanterare\n"
-
-#~ msgid "Command> "
-#~ msgstr "Kommando> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "tillitsdatabasen är trasig, kör \"gpg --fix-trustdb\".\n"
 
index 61124d6..15697ca 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -10,7 +10,6 @@ msgstr ""
 "PO-Revision-Date: 2008-12-14 23:25+0200\n"
 "Last-Translator: Nilgün Belma Bugüner <nilgun@belgeler.gen.tr>\n"
 "Language-Team: Turkish\n"
-"Language: tr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -21,44 +20,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "PIN giriş kilidi edinilemedi: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr ""
-"Seçili yardımcı anahtarları gerçekten yürürlükten kaldırmak istiyor musunuz? "
-"(e/H ya da y/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "Enter new passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "Yeni anahtar parolasını giriniz"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -87,9 +48,6 @@ msgstr ""
 "Lütfen anahtar parolanızı giriniz, böylelikle bu oturumda bu gizli anahtar "
 "kilitsiz olabilecek"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (%d/%d dene)"
@@ -120,11 +78,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "%d bitlikten daha büyük SSH anahtarları desteklenmiyor\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "\"%s\" oluşturulamıyor: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "`%s' açılamıyor: %s\n"
 
 #, c-format
@@ -152,28 +110,16 @@ msgid "error writing key: %s\n"
 msgstr "anahtarı yazarken hata: %s\n"
 
 #, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
-#, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "Lütfen SSH anahtarı %0A  %c için anahtar parolasını giriniz"
 
 msgid "Please re-enter this passphrase"
 msgstr "Lütfen bu anahtar parolasını tekrar girin"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
 msgstr ""
 "gpg-agent'in anahtar deposuna korumak için alınan gizli anahtar %%0A  %s%%0A "
 "için lütfen anahtar parolası giriniz"
@@ -203,7 +149,7 @@ msgid "Reset Code"
 msgstr "Sıfırlama Kodu"
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 msgid "Repeat this Reset Code"
@@ -296,9 +242,8 @@ msgstr ""
 msgid "Yes, protection is not needed"
 msgstr "Evet, korumak gereksiz"
 
-#, fuzzy, c-format
-#| msgid "Please enter the passphrase to%0Ato protect your new key"
-msgid "Please enter the passphrase to%0Aprotect your new key"
+#, c-format
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr "Yeni anahtarınızı korumak için Lütfen%0AAnahtar Parolanızı giriniz"
 
 msgid "Please enter the new passphrase"
@@ -311,12 +256,12 @@ msgstr ""
 "@Seçenekler:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "artalan süreci olarak çalışır"
-
 msgid "run in server mode (foreground)"
 msgstr "sunucu olarak (önalanda) çalışır"
 
+msgid "run in daemon mode (background)"
+msgstr "artalan süreci olarak çalışır"
+
 msgid "verbose"
 msgstr "ayrıntılı"
 
@@ -365,27 +310,15 @@ msgstr "|N|arabellekteki PINler N saniyede zamanaşımına uğrar"
 msgid "do not use the PIN cache when signing"
 msgstr "imzalarken PIN arabelleği kullanılmaz"
 
-#, fuzzy
-#| msgid "allow clients to mark keys as \"trusted\""
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr "istemcilerin anahtarları \"güvenilir\" olarak imlemesine izin verilir"
 
 msgid "allow presetting passphrase"
 msgstr "anahtar parolasının önceden atanmasına izin verilir"
 
-#, fuzzy
-#| msgid "enable ssh-agent emulation"
-msgid "enable ssh support"
+msgid "enable ssh-agent emulation"
 msgstr "ssh-agent öykünümü etkinleşir"
 
-msgid "enable putty support"
-msgstr ""
-
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "eski anahtar parolalarının yeniden kullanılmasına izin vermez"
-
 msgid "|FILE|write environment settings also to FILE"
 msgstr "|DOSYA|ortam ayarlarını ayrıca DOSYAya da yazar"
 
@@ -407,7 +340,7 @@ msgstr ""
 "GnuPG için gizli anahtar yönetimi\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr "belirtilen hata seviyesi `%s' geçersiz\n"
 
 #, c-format
@@ -415,23 +348,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr "%s çok eski (gereken %s, sizinki %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "BİLGİ: \"%s\" öntanımlı seçenek dosyası yok\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "seçenek dosyası \"%s\": %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "\"%s\"den seçenekler okunuyor\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "`%s' oluşturulurken hata: %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "`%s' dizini oluşturulamıyor: %s\n"
 
 msgid "name of socket too long\n"
@@ -442,7 +375,7 @@ msgid "can't create socket: %s\n"
 msgstr "soket oluşturulamıyor: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "soketin ismi `%s' çok uzun\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -452,7 +385,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "soket için tuz alınırken hata\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "soket `%s'e bağlanırken hata: %s\n"
 
 #, c-format
@@ -460,19 +393,19 @@ msgid "listen() failed: %s\n"
 msgstr "soket dinleme başarısız: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "`%s' soketi dinlemede\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "dizin `%s' oluşturuldu\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "%s için stat() başarısız oldu: %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "`%s' ev dizini olarak kullanılamıyor\n"
 
 #, c-format
@@ -582,31 +515,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "anahtar parolası sorulurken hata: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "'%s' açılırken hata: %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "`%s' dosyası, %d. satır: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr "`%2$s' dosyasının %3$d. satırındaki \"%1$s\" deyimi yoksayıldı\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "sistem güvence listesi `%s' kullanım dışı\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "`%s', %d. satırda parmakizi hatalı\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr "`%s', %d. satırda anahtar bayrağı geçersiz\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "`%s' okunurken %d. satırda hata: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -699,15 +632,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "süreç %d çıkış kodu alınırken hata: %s\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "`%s' çalışırken hata: çıkış durumu: %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr "`%s' çalıştırılırken hata: muhtemelen kurulu değil\n"
 
 #, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "`%s' çalışırken hata: sonlandırıldı\n"
 
 #, c-format
@@ -721,7 +654,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent bu oturumda kullanılamaz\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "\"%s\" sunucusuna bağlanılamadı: %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -794,10 +727,6 @@ msgstr "%lu bayt ayrılırken nüve dışına çıkıldı"
 msgid "no running gpg-agent - starting one\n"
 msgstr "çalışan gpg-agent yok - bir tane başlatılıyor\n"
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr "aracıya bağlanılamıyor - son çareye başvuruluyor\n"
 
@@ -823,22 +752,6 @@ msgstr "sertifikaları ithal eder"
 msgid "|audit-log-result|Error"
 msgstr ""
 
-#, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "sertifikaları ithal eder"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "sertifikaları ithal eder"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "sertifikaları ithal eder"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "sertifikaları ithal eder"
-
 msgid "Certificate chain available"
 msgstr "Sertifika zinciri mevcut"
 
@@ -875,37 +788,20 @@ msgstr "%d. alıcı"
 msgid "Data signing succeeded"
 msgstr "Verinin imzalanması başarılı"
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "Kötü çittirim algoritması: %s"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "İmza %d"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "Kötü çittirim algoritması: %s"
-
 msgid "Data decryption succeeded"
 msgstr "Verinin şifresinin çözülmesi başarılı"
 
-#, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "koruma algoritması %d%s desteklenmiyor\n"
-
 msgid "Data verification succeeded"
 msgstr "Verinin doğrulanması başarılı"
 
 msgid "Signature available"
 msgstr "İmza kullanılabilir"
 
-#, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "İmzanın çözümlenmesi başarılı"
 
-#, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+#, c-format
+msgid "Bad hash algorithm: %s"
 msgstr "Kötü çittirim algoritması: %s"
 
 #, c-format
@@ -943,7 +839,7 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr elverişli"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "`%s' için yardım mevcut değil."
 
 msgid "ignoring garbage line"
@@ -1104,11 +1000,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "yeterli bellek ayrılırken hata: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "\"%s\" okunurken hata: %s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "`%s' yazılırken hata: %s\n"
 
 msgid "Login data (account name): "
@@ -1293,8 +1189,8 @@ msgstr "PIN'i doğrular ve tüm veriyi listeler"
 msgid "unblock the PIN using a Reset Code"
 msgstr "Bir Sıfırlama Kodu kullanarak PIN'in engelini kaldır"
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "Komut> "
 
 msgid "Admin-only command\n"
 msgstr "Yöneticiye özel komut\n"
@@ -1312,7 +1208,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output seçeneği bu komutla çalışmaz\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "`%s' açılamadı\n"
 
 #, c-format
@@ -1361,11 +1257,11 @@ msgid "using cipher %s\n"
 msgstr "%s şifrelemesi kullanılıyor\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' zaten sıkıştırılmış\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "UYARI: \"%s\" dosyası boş\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
@@ -1374,7 +1270,7 @@ msgstr ""
 "yapabilirsiniz\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "`%s'den okunuyor\n"
 
 msgid ""
@@ -1438,11 +1334,11 @@ msgstr ""
 "bu platformda, dış uygulamalar çalıştırılırken geçici dosyalar gerekiyor\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr " '%s' çalıştırılamıyor: %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "'%s' kabuğu çalıştırılamıyor: %s\n"
 
 #, c-format
@@ -1460,11 +1356,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "dış uygulamanın yanıtı okunamıyor: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "UYARI: geçici dosya silinemiyor (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "UYARI: %s geçici dizini silinemiyor: %s\n"
 
 msgid "export signatures that are marked as local-only"
@@ -1525,15 +1421,11 @@ msgid "[User ID not found]"
 msgstr "[Kullanıcı kimliği yok]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "anahtar %s: genel anahtarsız gizli anahtar - atlandı\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "`%s' %s üzerinden özdevinimli olarak alındı\n"
 
 #, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "`%s' %s üzerinden alınırken hata: %s\n"
 
 msgid "No fingerprint"
@@ -1553,6 +1445,10 @@ msgstr ""
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "yardımcı anahtar %s, asıl anahtar %s yerine kullanılıyor\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "anahtar %s: genel anahtarsız gizli anahtar - atlandı\n"
+
 msgid "make a signature"
 msgstr "bir imza yapar"
 
@@ -1592,9 +1488,6 @@ msgstr "gizli anahtarları listeler"
 msgid "generate a new key pair"
 msgstr "yeni bir anahtar çifti üretir"
 
-msgid "generate a revocation certificate"
-msgstr "bir yürürlükten kaldırma sertifikası üretir"
-
 msgid "remove keys from the public keyring"
 msgstr "anahtarları genel anahtar zincirinden siler"
 
@@ -1610,8 +1503,8 @@ msgstr "bir anahtarı yerel olarak imzalar"
 msgid "sign or edit a key"
 msgstr "bir anahtarı düzenler ve imzalar"
 
-msgid "change a passphrase"
-msgstr "anahtar parolası değiştirir"
+msgid "generate a revocation certificate"
+msgstr "bir yürürlükten kaldırma sertifikası üretir"
 
 msgid "export keys"
 msgstr "anahtarları gönderir"
@@ -1707,15 +1600,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Kullanımı: gpg [seçenekler] [dosyalar] (yardım için -h)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Yazılışı: gpg [seçenekler] [dosyalar]\n"
 "imzalama, kontrol, şifreleme veya çözme\n"
@@ -1747,35 +1635,35 @@ msgid "conflicting commands\n"
 msgstr "çelişen komutlar\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "grup tanımı '%s' içinde = işareti yok\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "UYARI: '%s' evdizininde güvensiz iyelik\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "UYARI: '%s' yapılandırma dosyasında güvensiz iyelik\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "UYARI: '%s' eklentisinde güvensiz iyelik\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "UYARI: UYARI: '%s' evdizininde güvensiz izinler\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "UYARI: '%s' yapılandırma dosyasında güvensiz izinler\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "UYARI: '%s' eklentisinde güvensiz izinler\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "UYARI: '%s' evdizinindeki ilgili dizinin iyeliği güvensiz\n"
 
 #, c-format
@@ -1784,11 +1672,11 @@ msgid ""
 msgstr "UYARI: '%s' yapılandırma dosyasını içeren dizinin iyeliği güvensiz\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "UYARI: '%s' eklentisini içeren dizinin iyeliği güvensiz\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "UYARI: '%s' evdizinindeki ilgili dizinin izinleri güvensiz\n"
 
 #, c-format
@@ -1797,11 +1685,11 @@ msgid ""
 msgstr "UYARI: '%s' yapılandırma dosyasını içeren dizinin izinleri güvensiz\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "UYARI: '%s' eklentisini içeren dizinin izinleri güvensiz\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "yapılandırma öğesi '%s' bilinmiyor\n"
 
 msgid "display photo IDs during key listings"
@@ -1843,7 +1731,7 @@ msgid "show expiration dates during signature listings"
 msgstr "imza listelemesi sırasında zamanaşımı tarihleri gösterilir"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "BİLGİ: eski öntanımlı seçenekler dosyası `%s' yoksayıldı\n"
 
 #, c-format
@@ -1855,11 +1743,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "BİLGİ: %s normal kullanım için değil!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "'%s' geçerli bir imza zamanaşımı değil\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "'%s' geçerli bir karakter kümesi değil\n"
 
 msgid "could not parse keyserver URL\n"
@@ -2029,15 +1917,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s, %s ile henüz çalışmıyor\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "%2$s kipindeyken '%1$s' şifreleme algoritması kullanılamaz\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "%2$s kipindeyken '%1$s' özet algoritması kullanılamaz\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "%2$s kipindeyken '%1$s' sıkıştırma algoritması kullanılamaz\n"
 
 #, c-format
@@ -2055,7 +1943,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [dosyaismi]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "`%s' için simetrik şifreleme başarısız: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2105,10 +1993,6 @@ msgstr "--lsign-key kullanıcı-kimliği"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key kullanıcı-kimliği [komutlar]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key kullanıcı-kimliği"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "anahtar sunucusuna gönderim başarısızlığa uğradı: %s\n"
@@ -2138,7 +2022,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "zırhlama başarısız: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "`%s' çittirim algoritması geçersiz\n"
 
 msgid "[filename]"
@@ -2180,7 +2064,7 @@ msgid "No help available"
 msgstr "yardım mevcut değil"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "\"%s\" için yardım mevcut değil"
 
 msgid "import signatures that are marked as local-only"
@@ -2189,11 +2073,6 @@ msgstr "salt-yerel olarak imlenmiş imzaları ithal eder"
 msgid "repair damage from the pks keyserver during import"
 msgstr "ithalat sırasında pks anahtar sunucusundaki bozukluğu giderir"
 
-#, fuzzy
-#| msgid "do not update the trustdb after import"
-msgid "do not clear the ownertrust values during import"
-msgstr "ithalat sonrası güvence veritabanını güncellemez"
-
 msgid "do not update the trustdb after import"
 msgstr "ithalat sonrası güvence veritabanını güncellemez"
 
@@ -2316,14 +2195,6 @@ msgstr ""
 msgid "key %s: no user ID\n"
 msgstr "anahtar %s: kullanıcı kimliği yok\n"
 
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s: %s\n"
-msgstr "\"%s\" atlandı: %s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "anahtar %s: PKS yardımcı anahtar bozulması giderildi\n"
@@ -2352,11 +2223,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "yazılabilir bir anahtar zinciri yok: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "\"%s\"e yazıyor\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "\"%s\" anahtarlığına yazarken hata oluştu: %s\n"
 
 #, c-format
@@ -2419,18 +2290,13 @@ msgstr "anahtar %s: \"%s\" %d kullanıcı kimliği temizlendi\n"
 msgid "key %s: \"%s\" not changed\n"
 msgstr "anahtar %s: \"%s\" değişmedi\n"
 
-#, fuzzy, c-format
-#| msgid "secret key \"%s\" not found: %s\n"
-msgid "secret key %s: %s\n"
-msgstr "gizli anahtar \"%s\" yok: %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "gizli anahtarı alımına izin verilmez\n"
-
 #, c-format
 msgid "key %s: secret key with invalid cipher %d - skipped\n"
 msgstr "anahtar %s: geçersiz şifreli (%d) gizli anahtar - atlandı\n"
 
+msgid "importing secret keys not allowed\n"
+msgstr "gizli anahtarı alımına izin verilmez\n"
+
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "öntanımlı gizli anahtar zinciri yok: %s\n"
@@ -2477,18 +2343,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "anahtar %s: kullanıcı kimliği \"%s\" için öz-imza geçersiz\n"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "anahtar %s: genel anahtar algoritması desteklenmiyor\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "anahtar %s: doğrudan anahtar imzası eklendi\n"
-
-#, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "anahtar %s: anahtarı garantilemek için yardımcı anahtar yok\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "anahtar %s: genel anahtar algoritması desteklenmiyor\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "anahtar %s: yardımcı anahtar garantileme geçersiz\n"
 
@@ -2571,15 +2433,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "BİLGİ: ikincil anahtar kart üzerinde saklı ve kullanılabilir\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "`%s' anahtarlığı oluşturulurken hata: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "`%s' anahtarlığı oluşturuldu\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "anahtar bloku özkaynağı `%s': %s\n"
 
 #, c-format
@@ -2773,7 +2635,7 @@ msgstr "   (2) İlişkisel denetim yaptım.%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Çok dikkatli bir denetim yaptım.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Seçiminiz? (daha fazla bilgi için: '?'): "
 
 #, c-format
@@ -3020,7 +2882,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "İpucu: İmzalamak için bir kullanıcı kimliği seçiniz\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "imza türü `%s' bilinmiyor\n"
 
 #, c-format
@@ -3052,11 +2914,11 @@ msgid "Command expects a filename argument\n"
 msgstr "Komut değiştirge olarak bir dosya ismi gerektiriyor\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "`%s' açılamıyor: %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "yedekleme anahtarı `%s' den okunurken hata oluştu: %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3143,8 +3005,8 @@ msgstr "Simgelemler: "
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "Bir PGP 2.x tarzı kullanıcı kimliğine uygun tercih yok.\n"
 
-#, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+#, c-format
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr ""
 "Bu anahtar %2$s tarafından %3$s anahtarıyla %1$s üzerinde yürürlükten "
 "kaldırılmış\n"
@@ -3212,14 +3074,6 @@ msgstr ""
 "       farklı bir kullanıcı kimliğin birincil kullanıcı kimlik olarak\n"
 "       kabul edilmesini sağlayabilirsiniz.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "Bir v3 anahtarının son kullanma tarihini değiştiremezsiniz\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3455,7 +3309,7 @@ msgstr ""
 "gösteriliyor\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "'%s' tercihi yinelendi\n"
 
 msgid "too many cipher preferences\n"
@@ -3468,7 +3322,7 @@ msgid "too many compression preferences\n"
 msgstr "çok fazla sıkıştırma tercihi\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "tercih dizgesindeki '%s' öğesi geçersiz\n"
 
 msgid "writing direct signature\n"
@@ -3711,7 +3565,7 @@ msgid "Invalid character in comment\n"
 msgstr "Önbilgi alanında geçersiz karakter var\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "`%s' karakter kümesini kullanıyorsunuz.\n"
 
 #, c-format
@@ -3801,15 +3655,15 @@ msgid "Key generation canceled.\n"
 msgstr "Anahtar üretimi durduruldu.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "genel anahtarı `%s'e yazıyor\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "gizli anahtar koçanı `%s'e yazılıyor\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "gizli anahtarı `%s'e yazıyor\n"
 
 #, c-format
@@ -3821,11 +3675,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "yazılabilir bir gizli anahtar zinciri yok: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "`%s' genel anahtarlığa yazılırken hata oluştu: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "`%s' gizli anahtarlığa yazılırken hata oluştu: %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3867,11 +3721,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "anahtarın kart üzerinde saklanması başarısız: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "'%s' yedek dosyası oluşturulamıyor: %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "BİLGİ: kart anahtarının yedeklemesi '%s' e kaydedildi\n"
 
 msgid "never     "
@@ -3912,16 +3766,11 @@ msgstr "Yardımcı anahtar parmak izi:"
 msgid "      Key fingerprint ="
 msgstr "     Anahtar parmakizi ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "UYARI: deneysel %s özet algoritması kullanılıyor\n"
-
 msgid "      Card serial no. ="
 msgstr "      Kart seri no. ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "`%s' > `%s' isim değişikliği başarısız: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -3939,7 +3788,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "Lütfen bu güvenlik çatlağını giderin\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "`%s' anahtar zinciri önbellekleniyor\n"
 
 #, c-format
@@ -3978,7 +3827,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "anahtarları alırken PKA kaydını bir anahtara atar"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "UYARI: anahtar sunucusu seçeneği `%s' bu platformda kullanımda değil\n"
 
 msgid "disabled"
@@ -4040,10 +3889,6 @@ msgstr "UYARI: GnuPG'nin başka bir sürümünün anahtar sunucusu eylemcisi (%s
 msgid "keyserver did not send VERSION\n"
 msgstr "anahtar sunucusu VERSION göndermiyor\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "anahtar sunucusuyla iletişim hatası: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "bilinen bir anahtar sunucusu yok (--keyserver seçeneğini kullanın)\n"
 
@@ -4051,11 +3896,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr "harici anahtar sunucusu çağrıları bu kurulumda desteklenmiyor\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr "`%s' anahtar sunucusu şeması için eylemci yok\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr "`%s' eylemi `%s' anahtar sunucusu şeması ile desteklenmiyor\n"
 
 #, c-format
@@ -4069,6 +3914,10 @@ msgid "keyserver internal error\n"
 msgstr "anahtar sunucusu iç hatası\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "anahtar sunucusuyla iletişim hatası: %s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "\"%s\" bir anahtar kimliği değil: atlanıyor\n"
 
@@ -4241,10 +4090,6 @@ msgid "unknown"
 msgstr "bilinmeyen"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "İmza kontrol edilemedi: %s\n"
 
@@ -4266,7 +4111,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "proc_tree() içinde geçersiz kök paket saptandı\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "`%s' için %s de durum bilgisi alınamıyor: %s\n"
 
 #, c-format
@@ -4292,11 +4137,6 @@ msgstr "UYARI: deneysel %s özet algoritması kullanılıyor\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "UYARI: %s özet algoritması artık önerilmiyor.\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s imzası, %s özet algoritması\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "IDEA şifre eklentisi yok\n"
 
@@ -4328,17 +4168,6 @@ msgstr "%s:%u: eskimiş seçenek \"%s\" - artık etkisiz\n"
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "UYARI: \"%s\" seçeneği eskidi - artık etkisiz\n"
 
-#, fuzzy, c-format
-#| msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: eskimiş seçenek \"%s\" - artık etkisiz\n"
-
-#, fuzzy, c-format
-#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "UYARI: \"%s\" seçeneği eskidi - artık etkisiz\n"
-
 msgid "Uncompressed"
 msgstr "Sıkıştırılmamış"
 
@@ -4351,15 +4180,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "bu ileti %s tarafından kullanılamayabilir\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "`%s' seçeneği belirsiz\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "`%s' seçeneği bilinmiyor\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "\"%s\" dosyası var. "
 
 msgid "Overwrite? (y/N) "
@@ -4375,17 +4204,16 @@ msgstr "Yeni dosya ismini giriniz"
 msgid "writing to stdout\n"
 msgstr "standart çıktıya yazıyor\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "\"%s\" içindeki veri imzalı kabul ediliyor\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "yeni yapılandırma dosyası `%s' oluşturuldu\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr ""
 "UYARI: `%s' deki seçenekler bu çalıştırma sırasında henüz etkin değil\n"
 
@@ -4401,10 +4229,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "%d tipi alt paket kritik bit kümesine sahip\n"
 
 #, c-format
-msgid "problem with the agent: %s\n"
-msgstr "aracı ile sorun var: %s\n"
-
-#, c-format
 msgid " (main key ID %s)"
 msgstr " (asıl anahtar kimliği %s)"
 
@@ -4428,6 +4252,10 @@ msgid "cancelled by user\n"
 msgstr "kullanıcı tarafından durduruldu\n"
 
 #, c-format
+msgid "problem with the agent: %s\n"
+msgstr "aracı ile sorun var: %s\n"
+
+#, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4460,7 +4288,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Foto kimliği için JPEG dosya ismini giriniz: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "JPEG dosyası `%s' açılamıyor: %s\n"
 
 #, c-format
@@ -4471,7 +4299,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Onu kullanmak istediğinizden emin misiniz? (e/H ya da y/N)  "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "'%s' bir JPEG dosyası değil\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4501,16 +4329,6 @@ msgstr "yürürlükten kaldırma sebebi: "
 msgid "revocation comment: "
 msgstr "yürürlükten kaldırma açıklaması: "
 
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "bBmMaAkK"
 
@@ -4621,11 +4439,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Bilgi: Bu anahtar iptal edildi.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr "Bilgi: Doğrulanmış imzacının adresi: `%s'\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr "Bilgi: İmzacının adresi `%s', DNS girdisiyle eşleşmiyor\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4727,7 +4545,7 @@ msgid "no signed data\n"
 msgstr "imzalı veri yok\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "imzalı veri '%s'  açılamadı\n"
 
 #, c-format
@@ -5042,7 +4860,7 @@ msgstr ""
 "# (Eski haline getirmek için \"gpg --import-ownertrust\" kullanın\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "'%s' de hata: %s\n"
 
 msgid "line too long"
@@ -5058,11 +4876,11 @@ msgid "ownertrust value missing"
 msgstr "sahibiningüvencesi değeri kayıp"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "`%s' deki güvence kaydını ararken hata: %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "`%s' için okuma hatası: %s\n"
 
 #, c-format
@@ -5070,14 +4888,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "güvence veritabanı: eşzamanlama başarısız: %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "`%s' için kilit oluşturulamıyor\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "`%s' kiltlenemedi\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "güvence veritabanı %lu kaydı: erişim başarısız: %s\n"
 
@@ -5089,12 +4899,20 @@ msgid "trustdb transaction too large\n"
 msgstr "güvence veritabanı işlemi çok uzun\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "'%s' erişilemiyor: %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: dizin yok!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "'%s' erişilemiyor: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "`%s' için kilit oluşturulamıyor\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "`%s' kiltlenemedi\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5180,7 +4998,7 @@ msgid "input line longer than %d characters\n"
 msgstr "girdi satırı %d karakterden daha uzun\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' geçerli bir anahtar kimliği değil\n"
 
 #, c-format
@@ -5223,14 +5041,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr "%s güvence modeli kullanılıyor\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr "20 translator seen trustdb.c:uid_trust_string_fixed"
 
@@ -5278,11 +5088,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "sonraki güvence veritabanı denetimi %s de\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "`%s' güvence modelli güvence veritabanı sınaması için gereksiz\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "`%s' güvence modelli güvence veritabanı güncellemesi için gereksiz\n"
 
 #, c-format
@@ -5351,11 +5161,6 @@ msgstr "anahtar sözcük çok uzun"
 msgid "missing argument"
 msgstr "eksik değiştirge"
 
-#, fuzzy
-#| msgid "invalid value\n"
-msgid "invalid argument"
-msgstr "değer hatalı\n"
-
 msgid "invalid command"
 msgstr "geçersiz komut"
 
@@ -5372,11 +5177,6 @@ msgstr "geçersiz seçenek"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr "\"%.50s\" seçeneği için değiştirge eksik\n"
 
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "\"%.50s\" seçeneği için değiştirge eksik\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr "\"%.50s\" seçeneğinin değiştirge ihtiyacı yok\n"
@@ -5405,7 +5205,11 @@ msgid "you found a bug ... (%s:%d)\n"
 msgstr "bir yazılım hatası buldunuz ... (%s:%d)\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "error loading '%s': %s\n"
+msgstr "`%s' yüklenirken hata: %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr "`%s' > `%s' dönüşümü elverişli değil\n"
 
 #, c-format
@@ -5413,15 +5217,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "iconv_open başarısız: %s\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "`%s' > `%s' dönüşümü başarısız: %s\n"
 
 #, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "`%s' geçici dosyası oluşturulamıyor: %s\n"
 
 #, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "`%s' yazılırken hata: %s\n"
 
 #, c-format
@@ -5439,7 +5243,7 @@ msgid "(deadlock?) "
 msgstr "(ölükilit?) "
 
 #, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "kilit `%s' yapılmadı: %s\n"
 
 #, c-format
@@ -5455,13 +5259,9 @@ msgstr "tam hata ayıklama etkin olur"
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "Kullanımı: kbxutil [seçenekler] [dosyalar] (yardım için -h)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: kbxutil [options] [files]\n"
-#| "list, export, import Keybox data\n"
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
 "Sözdizimi: kbxutil [seçenekler] [dosyalar]\n"
 "Anahtar kutusu verisini listeler, ithal ve ihraç eder\n"
@@ -5579,8 +5379,8 @@ msgstr ""
 #, fuzzy, c-format
 msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]"
 msgstr ""
-"|A|Lütfen Yönetici PIN'ini okuyucu tuştakımından giriniz%%0A[kalan deneme: "
-"%d]"
+"|A|Lütfen Yönetici PIN'ini okuyucu tuştakımından giriniz%%0A[kalan deneme: %"
+"d]"
 
 #, fuzzy
 msgid "|A|Please enter the Admin PIN"
@@ -5596,9 +5396,6 @@ msgstr "||Lütfen kart için Sıfırlama Kodunu giriniz"
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr "Sıfırlama Kodu çok kısa; asgari uzunluk: %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr "|YSK|Yeni Sıfırlama Kodu"
 
@@ -5608,15 +5405,6 @@ msgstr "|YYP|Yeni Yönetici PIN'i"
 msgid "|N|New PIN"
 msgstr "|N|Yeni PIN"
 
-#, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||Lütfen PIN'i giriniz"
-
-#, fuzzy
-#| msgid "||Please enter the PIN"
-msgid "||Please enter the PIN and New PIN"
-msgstr "||Lütfen PIN'i giriniz"
-
 msgid "error reading application data\n"
 msgstr "uygulama verisi okunurken hata\n"
 
@@ -5679,9 +5467,7 @@ msgstr "Yönetici PIN'inin doğrulanması bu komut yüzünden şimdilik yasaktı
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "%s erişilebilir değil - OpenPGP kartı geçersiz olabilir mi?\n"
 
-#, fuzzy
-#| msgid "||Please enter your PIN at the reader's keypad"
-msgid "||Please enter your PIN at the reader's pinpad"
+msgid "||Please enter your PIN at the reader's keypad"
 msgstr "||Lütfen PIN'inizi okuyucunun tuştakımından giriniz"
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
@@ -5714,18 +5500,13 @@ msgstr "dahili CCID sürücüsü kullanılmaz"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr "|N|N saniyelik durgunluktan sonra kartı ayırır"
 
-#, fuzzy
-#| msgid "do not use a reader's keypad"
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr "bir okuyucu tuştakımı kullanılmaz"
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "yönetici kartı komutları kullanımına izin verir"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "Kullanımı: scdaemon [seçenekler] (yardım için -h)"
 
@@ -5736,7 +5517,7 @@ msgstr ""
 "Sözdizimi: scdaemon [seçenekler] [komut [arg ...]]\n"
 "GnuPG için akıllı kart artalan süreci\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 "Programı artalanda çalışır bırakmak için lütfen `--daemon' seçeneğini "
 "kullanın\n"
@@ -5758,7 +5539,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr "çalışan dirmngr yok - `%s' başlatılıyor\n"
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
@@ -5792,7 +5573,7 @@ msgid "critical marked policy without configured policies"
 msgstr "yapılandırılmış poliçeler olmaksızın kritik imli poliçe"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "`%s' açılamadı: %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5819,8 +5600,8 @@ msgstr "eşleşen sertifika sayısı: %d\n"
 msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "dirmngr sadece-önbellek anahtar araması başarısızi: %s\n"
 
-msgid "failed to allocate keyDB handle\n"
-msgstr "anahtar veritabanı eylemcisine yer ayrılması başarısız oldu\n"
+msgid "failed to allocated keyDB handle\n"
+msgstr "ayrılmış anahtar veritabanı elde edilemedi: %s\n"
 
 msgid "certificate has been revoked"
 msgstr "sertifika yürürlükten kaldırılmıştı"
@@ -5994,24 +5775,16 @@ msgstr "hiç anahtar kullanımı belirtilmemiş - tüm kullanımlar var sayılı
 msgid "error getting key usage information: %s\n"
 msgstr "anahtar kullanım bilgisi alınırken hata: %s\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for certification\n"
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr "sertifika onaylama için kullanılmamalıydı\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for OCSP response signing\n"
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr "sertifika, OCSP yanıtının imzalanması için kullanılmamalıydı\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for encryption\n"
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr "sertifika şifreleme için kullanılmamalıydı\n"
 
-#, fuzzy
-#| msgid "certificate should have not been used for signing\n"
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr "sertifika imzalama için kullanılmamalıydı\n"
 
 msgid "certificate is not usable for encryption\n"
@@ -6033,11 +5806,11 @@ msgid "line %d: no subject name given\n"
 msgstr "%d. satır: konu ismi belirtilmemiş\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr "%d. satır: konu ismi yaftası `%.*s' geçersiz\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr "%1$d. satır: %3$d konumundaki konu ismi %2$s' geçersiz\n"
 
 #, c-format
@@ -6045,11 +5818,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "%d. satır: geçerli bir eposta adresi değil\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "%d. satır: `%s' anahtarı karttan okunurken hata: %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "%d. satır: `%s' anahtar maşası tarafından alınırken hata: %s\n"
 
 #, c-format
@@ -6121,7 +5894,7 @@ msgid "No subject name given\n"
 msgstr "Konu ismi belirtilmemiş\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr "Geçersiz konu ismi yaftası `%.*s'\n"
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6130,7 +5903,7 @@ msgstr "Geçersiz konu ismi yaftası `%.*s'\n"
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "Geçersiz konu ismi`%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6170,7 +5943,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(bu bir şifreli iletiymiş gibi görünmüyor)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "sertifika \"%s\" yok: %s\n"
 
 #, c-format
@@ -6178,11 +5951,11 @@ msgid "error locking keybox: %s\n"
 msgstr "anahtar bloğu kilitlenirken hata: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "yinelenmiş sertifika `%s' silindi\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "sertifika `%s' silindi\n"
 
 #, c-format
@@ -6213,6 +5986,9 @@ msgstr "dirmngr'a bir komut aktarır"
 msgid "invoke gpg-protect-tool"
 msgstr "gpg-protect-tool'u çalıştırır"
 
+msgid "change a passphrase"
+msgstr "anahtar parolası değiştirir"
+
 msgid "create base-64 encoded output"
 msgstr "base-64 kodlu çıktı oluşturur"
 
@@ -6284,15 +6060,10 @@ msgstr "|İSİM|özet algoritması olarak İSİM kullanılır"
 msgid "Usage: gpgsm [options] [files] (-h for help)"
 msgstr "Kullanımı: gpgsm [seçenekler] [dosyalar] (yardım için -h)"
 
-#, fuzzy
-#| 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"
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "Sözdizimi: gpgsm [seçenekler] [dosyalar]\n"
 "imzalama, kontrol, şifreleme veya çözme S/MIME protokolü kullanarak yapılır\n"
@@ -6302,11 +6073,11 @@ msgid "usage: gpgsm [options] "
 msgstr "kullanımı: gpgsm [seçenekler] "
 
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "BİLGİ:`%s'e şifrelenemez: %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "`%s' geçerlilik modeli bilinmiyor\n"
 
 #, c-format
@@ -6328,11 +6099,11 @@ msgid "WARNING: running with faked system time: "
 msgstr "UYARI: sahte sistem zamanıyla çalışıyor: "
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "ortak sertifikalar `%s' ithal ediliyor\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "`%s' kullanarak imzalanamıyor: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6348,6 +6119,9 @@ msgstr "sertifika saklanırken hata\n"
 msgid "basic certificate checks failed - not imported\n"
 msgstr "temel sertifika sınamaları başarısız oldu - ithal edilmedi\n"
 
+msgid "failed to allocate keyDB handle\n"
+msgstr "anahtar veritabanı eylemcisine yer ayrılması başarısız oldu\n"
+
 #, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "saklanmış bayraklar alınırken hata: %s\n"
@@ -6361,11 +6135,14 @@ msgid "error reading input: %s\n"
 msgstr "girdi okunurken hata: %s\n"
 
 #, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "anahtar bloku `%s' oluşturulurken hata: %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr "gpg-agent'ı önce başlatmak isteyebilirsiniz\n"
+
 #, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "`%s' anahtar bloğu oluşturuldu\n"
 
 msgid "failed to get the fingerprint\n"
@@ -6398,11 +6175,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr "GPG_TTY atanmamıştı - kullanımı sorunlara yolaçabilir\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "`%s', %d. satırındaki biçimli parmakizi geçersiz\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr "`%s', %d. satırındaki ülke kodu geçersiz\n"
 
 #, c-format
@@ -6526,7 +6303,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr "gömülü boş karakterden dolayı satır kısaldı\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "komut `%s' bilinmiyor\n"
 
 #, c-format
@@ -6750,7 +6527,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "%2$s üzerindeki %1$s %3$i durumuyla başarısız oldu\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "`%s' geçici dizini oluşturulamıyor: %s\n"
 
 #, c-format
@@ -6848,18 +6625,6 @@ msgstr ""
 "Standart girdiden verilen anahtar parolasını örüntü dosyasıyla "
 "karşılaştırır\n"
 
-#~ msgid "you may want to start the gpg-agent first\n"
-#~ msgstr "gpg-agent'ı önce başlatmak isteyebilirsiniz\n"
-
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "`%s' yüklenirken hata: %s\n"
-
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "ayrılmış anahtar veritabanı elde edilemedi: %s\n"
-
-#~ msgid "Command> "
-#~ msgstr "Komut> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr ""
 #~ "güvence veritabanı bozulmuş; lütfen \"gpg --fix-trustdb\" çalıştırın.\n"
index 798146b..2900ef1 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -2,20 +2,20 @@
 # Copyright (C) 2011 Free Software Foundation, Inc.
 # This file is distributed under the same license as the GnuPG package.
 #
-# Yuri Chornoivan <yurchor@ukr.net>, 2011, 2013, 2014.
+# Yuri Chornoivan <yurchor@ukr.net>, 2011, 2014.
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg2\n"
+"Project-Id-Version: GNU gnupg 2.1.0-gitfe8619d\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2014-11-15 19:07+0200\n"
+"PO-Revision-Date: 2014-06-22 17:25+0300\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
 "Language: uk\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n"
 "X-Generator: Lokalize 1.5\n"
 
 #, c-format
@@ -33,37 +33,9 @@ msgstr "_Гаразд"
 msgid "|pinentry-label|_Cancel"
 msgstr "_Скасувати"
 
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "_Гаразд"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "_Гаразд"
-
 msgid "|pinentry-label|PIN:"
 msgstr "Пінкод:"
 
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "_Скасувати"
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "Ви справді бажаєте відкликати позначені підключі? (y/N або т/Н) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "Enter new passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "Вкажіть новий пароль"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -94,6 +66,9 @@ msgstr ""
 "Будь ласка, вкажіть ваш пароль, щоб ключ можна було розблокувати для цього "
 "сеансу"
 
+msgid "does not match - try again"
+msgstr "паролі не збігаються, повторіть спробу"
+
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
@@ -101,6 +76,9 @@ msgstr ""
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (спроба %d з %d)"
 
+msgid "Repeat:"
+msgstr ""
+
 msgid "PIN too long"
 msgstr "Занадто довгий пінкод"
 
@@ -128,11 +106,11 @@ msgstr ""
 "підтримки ключів ssh, що складаються з понад %d бітів, не передбачено\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "не вдалося створити «%s»: %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "не вдалося відкрити «%s»: %s\n"
 
 #, c-format
@@ -144,9 +122,8 @@ msgid "detected card with S/N: %s\n"
 msgstr "виявлено картку з серійним номером: %s\n"
 
 #, c-format
-msgid "error getting default authentication keyID of card: %s\n"
-msgstr ""
-"помилка під час спроби отримання типового розпізнавального keyID картки: %s\n"
+msgid "no authentication key for ssh on card: %s\n"
+msgstr "на карті немає ключа розпізнавання для SSH: %s\n"
 
 #, c-format
 msgid "no suitable card key found: %s\n"
@@ -189,9 +166,6 @@ msgstr ""
 "Будь ласка, вкажіть пароль для захисту отриманого закритого ключа%%0A   %s"
 "%%0A   %s%%0Aу сховищі ключів gpg-agent"
 
-msgid "does not match - try again"
-msgstr "паролі не збігаються, повторіть спробу"
-
 #, c-format
 msgid "failed to create stream from socket: %s\n"
 msgstr "не вдалося створити потік даних з сокета: %s\n"
@@ -255,28 +229,38 @@ msgstr "Скористатися цим"
 
 #, c-format
 msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u character long."
-msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should be "
-"at least %u characters long."
-msgstr[0] ""
-"Попередження: вами введено занадто простий пароль.%%0AПароль має складатися "
-"не менше ніж з %u символу."
-msgstr[1] ""
-"Попередження: вами введено занадто простий пароль.%%0AПароль має складатися "
-"не менше ніж з %u символів."
-msgstr[2] ""
-"Попередження: вами введено занадто простий пароль.%%0AПароль має складатися "
-"не менше ніж з %u символів."
+"You have not entered a passphrase!%0AAn empty passphrase is not allowed."
+msgstr "Вами не вказано пароля!%0AВикористання порожніх паролів заборонено."
 
 #, c-format
 msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digit or%%0Aspecial character."
+"You have not entered a passphrase - this is in general a bad idea!%0APlease "
+"confirm that you do not want to have any protection on your key."
+msgstr ""
+"Вами не вказано пароля. Цього не варто робити!%0AБудь ласка, підтвердіть, що "
+"ваш ключ не слід захищати взагалі."
+
+msgid "Yes, protection is not needed"
+msgstr "Так, у захисті немає потреби"
+
+#, fuzzy, c-format
+#| msgid "Name must be at least 5 characters long\n"
+msgid "A passphrase should be at least %u character long."
+msgid_plural "A passphrase should be at least %u characters long."
+msgstr[0] "Ім’я має бути не коротшим за 5 літер\n"
+msgstr[1] "Ім’я має бути не коротшим за 5 літер\n"
+msgstr[2] "Ім’я має бути не коротшим за 5 літер\n"
+
+#, fuzzy, c-format
+#| msgid ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "contain at least %u digit or%%0Aspecial character."
+#| msgid_plural ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "contain at least %u digits or%%0Aspecial characters."
+msgid "A passphrase should contain at least %u digit or%%0Aspecial character."
 msgid_plural ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase should "
-"contain at least %u digits or%%0Aspecial characters."
+"A passphrase should contain at least %u digits or%%0Aspecial characters."
 msgstr[0] ""
 "Попередження: вами введено занадто простий пароль.%%0AПароль має містити "
 "принаймні %u цифру або%%0Aспеціальний символ."
@@ -287,29 +271,26 @@ msgstr[2] ""
 "Попередження: вами введено занадто простий пароль.%%0AПароль має містити "
 "принаймні %u цифр або%%0Aспеціальних символів."
 
-#, c-format
-msgid ""
-"Warning: You have entered an insecure passphrase.%%0AA passphrase may not be "
-"a known term or match%%0Acertain pattern."
+#, fuzzy, c-format
+#| msgid ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase may not "
+#| "be a known term or match%%0Acertain pattern."
+msgid "A passphrase may not be a known term or match%%0Acertain pattern."
 msgstr ""
 "Попередження: вами вказано занадто простий пароль.%%0AПаролем не повинно "
 "бути слово зі словника або слово%%0A, що відповідає певному зразку."
 
-#, c-format
-msgid ""
-"You have not entered a passphrase!%0AAn empty passphrase is not allowed."
-msgstr "Вами не вказано пароля!%0AВикористання порожніх паролів заборонено."
-
-#, c-format
-msgid ""
-"You have not entered a passphrase - this is in general a bad idea!%0APlease "
-"confirm that you do not want to have any protection on your key."
+#, fuzzy
+#| msgid ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "be at least %u character long."
+#| msgid_plural ""
+#| "Warning: You have entered an insecure passphrase.%%0AA passphrase should "
+#| "be at least %u characters long."
+msgid "Warning: You have entered an insecure passphrase."
 msgstr ""
-"Вами не вказано пароля. Цього не варто робити!%0AБудь ласка, підтвердіть, що "
-"ваш ключ не слід захищати взагалі."
-
-msgid "Yes, protection is not needed"
-msgstr "Так, у захисті немає потреби"
+"Попередження: вами введено занадто простий пароль.%%0AПароль має складатися "
+"не менше ніж з %u символу."
 
 #, c-format
 msgid "Please enter the passphrase to%0Aprotect your new key"
@@ -355,9 +336,6 @@ msgstr "не захоплювати керування клавіатурою і
 msgid "use a log file for the server"
 msgstr "використовувати файл журналу для сервера"
 
-msgid "use a standard location for the socket"
-msgstr "використовувати для сокета стандартне розташування"
-
 msgid "|PGM|use PGM as the PIN-Entry program"
 msgstr "використовувати вказану програму пінзаписів"
 
@@ -391,32 +369,24 @@ msgstr "увімкнути підтримку ssh"
 msgid "enable putty support"
 msgstr "увімкнути підтримку putty"
 
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "не дозволяти повторне використання старих паролів"
-
-msgid "|FILE|write environment settings also to FILE"
-msgstr "записати параметри середовища і до файла"
-
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
 msgid "Please report bugs to <@EMAIL@>.\n"
 msgstr "Будь ласка, надсилайте повідомлення про помилки на <@EMAIL@>.\n"
 
-msgid "Usage: gpg-agent [options] (-h for help)"
-msgstr "Використання: gpg-agent [параметри] (-h — довідка)"
+msgid "Usage: @GPG_AGENT@ [options] (-h for help)"
+msgstr "Використання: @GPG_AGENT@ [параметри] (-h — довідка)"
 
 msgid ""
-"Syntax: gpg-agent [options] [command [args]]\n"
-"Secret key management for GnuPG\n"
+"Syntax: @GPG_AGENT@ [options] [command [args]]\n"
+"Secret key management for @GNUPG@\n"
 msgstr ""
-"Синтаксис: gpg-agent [параметри] [команда [аргументи]]\n"
-"Керування закритими ключами у GnuPG\n"
+"Синтаксис: @GPG_AGENT@ [параметри] [команда [аргументи]]\n"
+"Керування закритими ключами у @GNUPG@\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr "вказано некоректне значення рівня діагностики «%s»\n"
 
 #, c-format
@@ -424,24 +394,20 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr "%s є занадто застарілою (потрібно %s, маємо %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "Note: no default option file '%s'\n"
 msgstr "ЗАУВАЖЕННЯ: не виявлено файла типових параметрів «%s»\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "файл параметрів «%s»: %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "прочитати параметри з «%s»\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
-msgstr "помилка створення «%s»: %s.\n"
-
-#, c-format
-msgid "can't create directory `%s': %s\n"
-msgstr "не вдалося створити каталог «%s»: %s\n"
+msgid "Note: '%s' is not considered an option\n"
+msgstr "ЗАУВАЖЕННЯ: %s не призначено для звичайного використання!\n"
 
 msgid "name of socket too long\n"
 msgstr "назва сокета є надто довгою\n"
@@ -451,7 +417,7 @@ msgid "can't create socket: %s\n"
 msgstr "не вдалося створити сокет: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "назва сокета «%s» є надто довгою\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -461,7 +427,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "помилка під час спроби отримання поточного стану сокета\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "помилка під час спроби прив’язування сокета до «%s»: %s\n"
 
 #, c-format
@@ -469,19 +435,23 @@ msgid "listen() failed: %s\n"
 msgstr "помилка listen(): %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "очікування даних на сокеті «%s»\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "can't create directory '%s': %s\n"
+msgstr "не вдалося створити каталог «%s»: %s\n"
+
+#, c-format
+msgid "directory '%s' created\n"
 msgstr "створено каталог «%s»\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "помилка stat() щодо «%s»: %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "не можна використовувати як домашній каталог «%s»\n"
 
 #, c-format
@@ -507,7 +477,7 @@ msgid "ssh handler 0x%lx for fd %d terminated\n"
 msgstr "обробник ssh 0x%lx дескриптора файла %d завершив роботу\n"
 
 #, c-format
-msgid "pth_select failed: %s - waiting 1s\n"
+msgid "npth_pselect failed: %s - waiting 1s\n"
 msgstr "помилка pth_select: %s — очікування у 1 с\n"
 
 #, c-format
@@ -517,13 +487,6 @@ msgstr "%s %s зупинено\n"
 msgid "no gpg-agent running in this session\n"
 msgstr "у цьому сеансі не запущено gpg-agent\n"
 
-msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "помилкове форматування змінної середовища GPG_AGENT_INFO\n"
-
-#, c-format
-msgid "gpg-agent protocol version %d is not supported\n"
-msgstr "підтримки версії протоколу gpg-agent %d не передбачено\n"
-
 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"
 msgstr ""
 "Використання: gpg-preset-passphrase [параметри] KEYGRIP (-h — довідка)\n"
@@ -591,31 +554,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "помилка під час спроби запиту пароля: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "помилка під час відкриття «%s»: %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "файл «%s», рядок %d: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr "проігноровано інструкцію «%s» у «%s», рядок %d\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "список довіри системи «%s» недоступний\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "помилковий відбиток у «%s», рядок %d\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr "некоректна позначка ключа у «%s», рядок %d\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "помилка під час читання «%s», рядок %d: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -687,13 +650,55 @@ msgstr "Змінити пароль"
 msgid "I'll change it later"
 msgstr "Я зміню його пізніше"
 
+msgid "Delete key"
+msgstr "Вилучити ключ"
+
+#, fuzzy
+#| msgid ""
+#| "Warning: This key is also listed for use with SSH!\n"
+#| "Deleting the key will may remove your ability to access remote machines."
+msgid ""
+"Warning: This key is also listed for use with SSH!\n"
+"Deleting the key might remove your ability to access remote machines."
+msgstr ""
+"Попередження: цей ключ є у списку використання для SSH!\n"
+"Вилучення цього ключа може призвести до неможливості отримати доступ до "
+"віддалених комп’ютерів."
+
+msgid "DSA requires the hash length to be a multiple of 8 bits\n"
+msgstr "Для DSA довжина хешу має бути кратною до 8 бітів\n"
+
+#, c-format
+msgid "%s key uses an unsafe (%u bit) hash\n"
+msgstr "Ключ %s використовує недостатньо міцний (%u-бітовий) хеш\n"
+
+#, c-format
+msgid "a %zu bit hash is not valid for a %u bit %s key\n"
+msgstr "%zu-бітовий хеш не є коректним для %u-бітового ключа %s\n"
+
+msgid "secret key parts are not available\n"
+msgstr "закриті частини ключа недоступні\n"
+
+#, c-format
+msgid "public key algorithm %d (%s) is not supported\n"
+msgstr ""
+"підтримки алгоритму роботи з відкритими ключами %d (%s) не передбачено\n"
+
+#, c-format
+msgid "protection algorithm %d (%s) is not supported\n"
+msgstr "підтримки алгоритму захисту %d (%s) не передбачено\n"
+
+#, c-format
+msgid "protection hash algorithm %d (%s) is not supported\n"
+msgstr "підтримки алгоритму захисту хешуванням %d (%s) не передбачено\n"
+
 #, c-format
 msgid "error creating a pipe: %s\n"
 msgstr "помилка під час спроби створення каналу: %s\n"
 
 #, c-format
-msgid "can't fdopen pipe for reading: %s\n"
-msgstr "не Ð²Ð´Ð°Ð»Ð¾Ñ\81Ñ\8f Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ\82и fdopen Ñ\89одо ÐºÐ°Ð½Ð°Ð»Ñ\83 Ð´Ð»Ñ\8f Ñ\87иÑ\82аннÑ\8f: %s\n"
+msgid "error creating a stream for a pipe: %s\n"
+msgstr "помилка Ð¿Ñ\96д Ñ\87аÑ\81 Ñ\81пÑ\80оби Ñ\81Ñ\82воÑ\80еннÑ\8f Ð¿Ð¾Ñ\82окÑ\83 Ð´Ð»Ñ\8f ÐºÐ°Ð½Ð°Ð»Ñ\83: %s\n"
 
 #, c-format
 msgid "error forking process: %s\n"
@@ -704,34 +709,27 @@ msgid "waiting for process %d to terminate failed: %s\n"
 msgstr "не вдалося дочекатися завершення процесу %d: %s\n"
 
 #, c-format
-msgid "error getting exit code of process %d: %s\n"
-msgstr "помилка під час спроби отримання коду виходу процесу %d: %s\n"
+msgid "error running '%s': probably not installed\n"
+msgstr ""
+"помилка під час спроби виконання «%s»: ймовірно, програму не встановлено\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "помилка під час спроби виконання «%s»: стан виходу %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
-msgstr ""
-"помилка під час спроби виконання «%s»: ймовірно, програму не встановлено\n"
-
-#, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "помилка під час спроби виконання «%s»: виконання перервано\n"
 
 #, c-format
-msgid "error creating socket: %s\n"
-msgstr "помилка під час спроби створення сокета: %s\n"
-
-msgid "host not found"
-msgstr "вузол не знайдено"
+msgid "error getting exit code of process %d: %s\n"
+msgstr "помилка під час спроби отримання коду виходу процесу %d: %s\n"
 
 msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent недоступний у цьому сеансі\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "не вдалося встановити з’єднання з «%s»: %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -802,16 +800,27 @@ msgstr ""
 msgid "out of core while allocating %lu bytes"
 msgstr "вихід за межі області під час спроби отримання %lu байтів"
 
-msgid "no running gpg-agent - starting one\n"
-msgstr "не запущено gpg-agent — запускаємо його\n"
+#, c-format
+msgid "no running gpg-agent - starting '%s'\n"
+msgstr "не запущено gpg-agent — запускаємо «%s»\n"
+
+#, c-format
+msgid "waiting for the agent to come up ... (%ds)\n"
+msgstr "очікування на працездатність агента… (%d с)\n"
+
+msgid "connection to agent established\n"
+msgstr "встановлено з’єднання з агентом\n"
 
 #, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "очікування %d на працездатність агента\n"
+msgid "no running Dirmngr - starting '%s'\n"
+msgstr "Dirmngr не запущено — запускаємо «%s»\n"
 
-msgid "can't connect to the agent - trying fall back\n"
-msgstr ""
-"не вдалося встановити з’єднання з агентом, використовуємо резервний варіант\n"
+#, c-format
+msgid "waiting for the dirmngr to come up ... (%ds)\n"
+msgstr "очікування на працездатність dirmngr… (%d с)\n"
+
+msgid "connection to the dirmngr established\n"
+msgstr "встановлено з’єднання з dirmngr\n"
 
 #. TRANSLATORS: Copy the prefix between the vertical bars
 #. verbatim.  It will not be printed.
@@ -947,7 +956,7 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr придатна до використання"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "Довідки щодо «%s» не виявлено."
 
 msgid "ignoring garbage line"
@@ -956,6 +965,110 @@ msgstr "ігноруємо беззмістовний рядок"
 msgid "[none]"
 msgstr "[немає]"
 
+msgid "argument not expected"
+msgstr "неочікуваний аргумент"
+
+msgid "read error"
+msgstr "помилка читання"
+
+msgid "keyword too long"
+msgstr "занадто довге ключове слово"
+
+msgid "missing argument"
+msgstr "не вистачає аргументу"
+
+#, fuzzy
+#| msgid "invalid value\n"
+msgid "invalid argument"
+msgstr "некоректне значення\n"
+
+msgid "invalid command"
+msgstr "некоректна команда"
+
+msgid "invalid alias definition"
+msgstr "некоректне визначення замінника"
+
+msgid "out of core"
+msgstr "вихід за межі області пам’яті"
+
+msgid "invalid option"
+msgstr "некоректний параметр"
+
+#, c-format
+msgid "missing argument for option \"%.50s\"\n"
+msgstr "не вказано аргументу до параметра «%.50s»\n"
+
+#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "invalid argument for option \"%.50s\"\n"
+msgstr "не вказано аргументу до параметра «%.50s»\n"
+
+#, c-format
+msgid "option \"%.50s\" does not expect an argument\n"
+msgstr "для параметра «%.50s» аргументи не потрібно вказувати\n"
+
+#, c-format
+msgid "invalid command \"%.50s\"\n"
+msgstr "некоректна команда «%.50s»\n"
+
+#, c-format
+msgid "option \"%.50s\" is ambiguous\n"
+msgstr "параметр «%.50s» є неоднозначним\n"
+
+#, c-format
+msgid "command \"%.50s\" is ambiguous\n"
+msgstr "команда «%.50s» є неоднозначною\n"
+
+msgid "out of core\n"
+msgstr "вихід за межі області пам’яті\n"
+
+#, c-format
+msgid "invalid option \"%.50s\"\n"
+msgstr "некоректний параметр «%.50s»\n"
+
+#, c-format
+msgid "you found a bug ... (%s:%d)\n"
+msgstr "ви виявили ваду… (%s:%d)\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
+msgstr "перетворення з «%s» у «%s» недоступне\n"
+
+#, c-format
+msgid "iconv_open failed: %s\n"
+msgstr "помилка iconv_open: %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' failed: %s\n"
+msgstr "помилка перетворення з «%s» у «%s»: %s\n"
+
+#, c-format
+msgid "failed to create temporary file '%s': %s\n"
+msgstr "не вдалося створити тимчасовий файл «%s»: %s\n"
+
+#, c-format
+msgid "error writing to '%s': %s\n"
+msgstr "помилка під час спроби запису до «%s»: %s\n"
+
+#, c-format
+msgid "removing stale lockfile (created by %d)\n"
+msgstr "вилучення застарілого файла блокування (створено %d)\n"
+
+#, c-format
+msgid "waiting for lock (held by %d%s) %s...\n"
+msgstr "очікування на блокування (зайнято %d%s) %s...\n"
+
+msgid "(deadlock?) "
+msgstr "(застаріле блокування?) "
+
+#, c-format
+msgid "lock '%s' not made: %s\n"
+msgstr "блокування «%s» не виконано: %s\n"
+
+#, c-format
+msgid "waiting for lock %s...\n"
+msgstr "очікування на блокування %s…\n"
+
 #, c-format
 msgid "armor: %s\n"
 msgstr "формат ASCII: %s\n"
@@ -1040,6 +1153,13 @@ msgid "not human readable"
 msgstr "незручне для читання"
 
 #, c-format
+msgid "failed to proxy %s inquiry to client\n"
+msgstr "не вдалося пропустити через проксі запит %s до клієнта\n"
+
+msgid "Enter passphrase: "
+msgstr "Введіть пароль: "
+
+#, c-format
 msgid "OpenPGP card not available: %s\n"
 msgstr "Не вдалося отримати доступ до картки OpenPGP: %s\n"
 
@@ -1109,11 +1229,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "помилка під час спроби розподілу пам’яті: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "помилка під час спроби читання «%s»: %s\n"
 
 #, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "помилка під час спроби читання «%s»: %s\n"
 
 msgid "Login data (account name): "
@@ -1168,7 +1288,7 @@ msgid "Replace existing key? (y/N) "
 msgstr "Замінити вже створений ключ? (y/N або т/Н) "
 
 msgid ""
-"NOTE: There is no guarantee that the card supports the requested size.\n"
+"Note: There is no guarantee that the card supports the requested size.\n"
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
@@ -1209,7 +1329,7 @@ msgstr "помилка під час спроби зміни розміру кл
 msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr "Створити резервну копію ключа шифрування поза карткою? (Y/n або Т/н) "
 
-msgid "NOTE: keys are already stored on the card!\n"
+msgid "Note: keys are already stored on the card!\n"
 msgstr "ЗАУВАЖЕННЯ: ключі вже збережено на картці!\n"
 
 msgid "Replace existing keys? (y/N) "
@@ -1218,7 +1338,7 @@ msgstr "Замірити вже створені ключі? (y/N або т/Н)
 #, c-format
 msgid ""
 "Please note that the factory settings of the PINs are\n"
-"   PIN = `%s'     Admin PIN = `%s'\n"
+"   PIN = '%s'     Admin PIN = '%s'\n"
 "You should change them using the command --change-pin\n"
 msgstr ""
 "Зауважте, що типовими параметрами пінкоду є\n"
@@ -1243,18 +1363,9 @@ msgstr "Некоректний вибір.\n"
 msgid "Please select where to store the key:\n"
 msgstr "Виберіть сховище для зберігання ключа:\n"
 
-msgid "unknown key protection algorithm\n"
-msgstr "невідомий алгоритм захисту ключа\n"
-
-msgid "secret parts of key are not available\n"
-msgstr "закриті частини ключа недоступні\n"
-
-msgid "secret key already stored on a card\n"
-msgstr "закритий ключ вже збережено на картці\n"
-
 #, c-format
-msgid "error writing key to card: %s\n"
-msgstr "помилка Ð¿Ñ\96д Ñ\87аÑ\81 Ñ\81пÑ\80оби Ð·Ð°Ð¿Ð¸Ñ\81Ñ\83 ÐºÐ»Ñ\8eÑ\87а Ð½Ð° ÐºÐ°Ñ\80Ñ\82кÑ\83: %s\n"
+msgid "KEYTOCARD failed: %s\n"
+msgstr "Ð\9fомилка KEYTOCARD: %s\n"
 
 msgid "quit this menu"
 msgstr "вийти з цього меню"
@@ -1323,7 +1434,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output не працює з цією командою\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "не вдалося відкрити «%s»\n"
 
 #, c-format
@@ -1347,6 +1458,16 @@ msgid "This is a secret key! - really delete? (y/N) "
 msgstr "Цей ключ є закритим! Вилучити його? (y/N або т/Н) "
 
 #, c-format
+msgid "deleting secret %s failed: %s\n"
+msgstr "помилка під час спроби вилучення закритого %s: %s\n"
+
+msgid "key"
+msgstr "ключ"
+
+msgid "subkey"
+msgstr "підключ"
+
+#, c-format
 msgid "deleting keyblock failed: %s\n"
 msgstr "не вдалося вилучити блокування ключа: %s\n"
 
@@ -1373,28 +1494,17 @@ msgid "using cipher %s\n"
 msgstr "використано шифр %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "«%s» вже стиснено\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "УВАГА: файл «%s» є порожнім\n"
 
-msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
-msgstr ""
-"шифрувати ключами RSA з розміром у 2048 бітів або менше лише у режимі --"
-"pgp2\n"
-
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "читання з «%s»\n"
 
-msgid ""
-"unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
-msgstr ""
-"не можна використовувати шифр IDEA для всіх ключів, якими виконується "
-"шифрування.\n"
-
 #, c-format
 msgid ""
 "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
@@ -1455,11 +1565,11 @@ msgstr ""
 "зовнішніх програм\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "не вдалося виконати програму «%s»: %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "не вдалося виконати оболонку «%s»: %s\n"
 
 #, c-format
@@ -1477,11 +1587,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "не вдалося прочитати відповідь зовнішньої програми: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "УВАГА: не вдалося вилучити тимчасовий файл (%s) «%s»: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "УВАГА: не вдалося вилучити тимчасовий каталог «%s»: %s\n"
 
 msgid "export signatures that are marked as local-only"
@@ -1496,9 +1606,6 @@ msgstr ""
 msgid "export revocation keys marked as \"sensitive\""
 msgstr "експортувати ключі відкликання, позначені як «важливі»"
 
-msgid "remove the passphrase from exported subkeys"
-msgstr "вилучити пароль з експортованих підключів"
-
 msgid "remove unusable parts from key during export"
 msgstr "вилучити невикористовувані частини ключа під час експортування"
 
@@ -1512,10 +1619,6 @@ msgid "exporting secret keys not allowed\n"
 msgstr "експортування закритих ключів заборонено\n"
 
 #, c-format
-msgid "key %s: not protected - skipped\n"
-msgstr "ключ %s: не захищено — пропущено\n"
-
-#, c-format
 msgid "key %s: PGP 2.x style key - skipped\n"
 msgstr "ключ %s: ключ у стилі PGP 2.x — пропущено\n"
 
@@ -1523,36 +1626,21 @@ msgstr "ключ %s: ключ у стилі PGP 2.x — пропущено\n"
 msgid "key %s: key material on-card - skipped\n"
 msgstr "ключ %s: матеріал ключа на карті — пропущено\n"
 
-msgid "about to export an unprotected subkey\n"
-msgstr "спроба експортування незахищеного підключа\n"
-
-#, c-format
-msgid "failed to unprotect the subkey: %s\n"
-msgstr "не вдалося зняти захист з підключа: %s\n"
-
-#, c-format
-msgid "WARNING: secret key %s does not have a simple SK checksum\n"
-msgstr "УВАГА: закритий ключ %s не має простої контрольної суми ЗК\n"
+msgid " - skipped"
+msgstr " - пропущено"
 
 msgid "WARNING: nothing exported\n"
 msgstr "УВАГА: нічого не експортовано\n"
 
-msgid "too many entries in pk cache - disabled\n"
-msgstr "занадто багато записів у кеші pk — вимкнено\n"
-
 msgid "[User ID not found]"
 msgstr "[Ідентифікатор не знайдено]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "ключ %s: закритий ключ без відкритого ключа — пропущено\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "автоматично отримано «%s» за допомогою %s\n"
 
 #, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "помилка під час спроби отримання «%s» за допомогою %s: %s\n"
 
 msgid "No fingerprint"
@@ -1565,10 +1653,6 @@ msgstr ""
 "uid\n"
 
 #, c-format
-msgid "no secret subkey for public subkey %s - ignoring\n"
-msgstr "немає закритого підключа для відкритого підключа %s — пропускаємо\n"
-
-#, c-format
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "використовуємо підключ %s замість основного ключа %s\n"
 
@@ -1611,7 +1695,15 @@ msgstr "показати список закритих ключів"
 msgid "generate a new key pair"
 msgstr "створити пару ключів"
 
-msgid "generate a revocation certificate"
+#, fuzzy
+#| msgid "generate a new key pair"
+msgid "quickly generate a new key pair"
+msgstr "створити пару ключів"
+
+msgid "full featured key pair generation"
+msgstr ""
+
+msgid "generate a revocation certificate"
 msgstr "створити сертифікат відкликання"
 
 msgid "remove keys from the public keyring"
@@ -1620,6 +1712,12 @@ msgstr "вилучити ключі з відкритого сховища кл
 msgid "remove keys from the secret keyring"
 msgstr "вилучити ключів з закритого сховища ключів"
 
+msgid "quickly sign a key"
+msgstr "швидко підписати ключ"
+
+msgid "quickly sign a key locally"
+msgstr "швидко підписати ключ локально"
+
 msgid "sign a key"
 msgstr "підписати ключ"
 
@@ -1725,15 +1823,15 @@ msgstr ""
 " --list-keys [назви]        показати ключі\n"
 " --fingerprint [назви]      показати відбитки\n"
 
-msgid "Usage: gpg [options] [files] (-h for help)"
-msgstr "Використання: gpg [параметри] [файли] (-h — довідка)"
+msgid "Usage: @GPG@ [options] [files] (-h for help)"
+msgstr "Використання: @GPG@ [параметри] [файли] (-h — довідка)"
 
 msgid ""
-"Syntax: gpg [options] [files]\n"
+"Syntax: @GPG@ [options] [files]\n"
 "Sign, check, encrypt or decrypt\n"
 "Default operation depends on the input data\n"
 msgstr ""
-"Синтаксис: gpg [параметри] [файли]\n"
+"Синтаксис: @GPG@ [параметри] [файли]\n"
 "Підписування, перевірка підписів, шифрування або розшифрування\n"
 "Типова дія залежатиме від вхідних даних\n"
 
@@ -1756,87 +1854,94 @@ msgstr "Хеш: "
 msgid "Compression: "
 msgstr "Стиснення: "
 
-msgid "usage: gpg [options] "
-msgstr "використання: gpg [параметри] "
+#, fuzzy, c-format
+#| msgid "usage: %s [options] "
+msgid "usage: %s [options] %s\n"
+msgstr "використання: %s [параметри]"
 
 msgid "conflicting commands\n"
 msgstr "несумісні команди\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "у визначенні групи «%s» немає знаку «=»\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "УВАГА: визначення власника домашнього каталогу «%s» не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "УВАГА: визначення власника у файлі налаштувань «%s» не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "УВАГА: визначення власника додатка «%s» не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr ""
 "УВАГА: визначення прав доступу до домашнього каталогу «%s» не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr ""
 "УВАГА: визначення прав доступу до файла налаштувань «%s» не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "УВАГА: визначення прав доступу до додатка «%s» не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr ""
 "УВАГА: визначення власника підлеглого каталогу домашнього каталогу «%s» не є "
 "безпечним\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory ownership on configuration file '%s'\n"
 msgstr ""
 "УВАГА: визначення власника у підлеглому каталозі, визначеному файлом "
 "налаштувань «%s», не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr ""
 "УВАГА: визначення власника підлеглого каталогу у додатку «%s» не є "
 "безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr ""
 "УВАГА: визначення прав доступу до підлеглого каталогу домашнього каталогу "
 "«%s» не є безпечним\n"
 
 #, c-format
 msgid ""
-"WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
+"WARNING: unsafe enclosing directory permissions on configuration file '%s'\n"
 msgstr ""
 "УВАГА: визначення прав доступу до підлеглого каталогу, визначеного файлом "
 "налаштувань «%s», не є безпечним\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr ""
 "УВАГА: визначення прав доступу до підлеглого каталогу у додатку «%s» не є "
 "безпечним\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "невідомий пункт налаштувань «%s»\n"
 
 msgid "display photo IDs during key listings"
 msgstr "показувати фотоідентифікатори у списках ключів"
 
+#, fuzzy
+#| msgid "show user ID validity during key listings"
+msgid "show key usage information during key listings"
+msgstr "показувати чинність ідентифікаторів користувачів у списках ключів"
+
 msgid "show policy URLs during signature listings"
 msgstr "показувати адреси правил у списках підписів"
 
@@ -1870,7 +1975,7 @@ msgid "show expiration dates during signature listings"
 msgstr "показувати дати завершення строків дії у списку підписів"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "Note: old default options file '%s' ignored\n"
 msgstr "ЗАУВАЖЕННЯ: застарілий файл типових параметрів «%s» проігноровано\n"
 
 #, c-format
@@ -1878,15 +1983,19 @@ msgid "libgcrypt is too old (need %s, have %s)\n"
 msgstr "libgcrypt занадто стара (потрібна — %s, маємо %s)\n"
 
 #, c-format
-msgid "NOTE: %s is not for normal use!\n"
+msgid "Note: %s is not for normal use!\n"
 msgstr "ЗАУВАЖЕННЯ: %s не призначено для звичайного використання!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "«%s» не є коректним записом завершення строку дії підпису\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "invalid pinentry mode '%s'\n"
+msgstr "некоректний режим введення pin «%s»\n"
+
+#, c-format
+msgid "'%s' is not a valid character set\n"
 msgstr "«%s» не є коректним набором символів\n"
 
 msgid "could not parse keyserver URL\n"
@@ -1991,25 +2100,13 @@ msgstr "%s не можна використовувати разом з %s!\n"
 msgid "%s makes no sense with %s!\n"
 msgstr "%s є зайвим, якщо використано %s!\n"
 
+msgid "WARNING: running with faked system time: "
+msgstr "УВАГА: запущено з фіктивним системним часом: "
+
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
 msgstr "не буде запущено з помилками у захисті пам’яті через %s\n"
 
-msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
-msgstr "від’єднані та текстові підписи можна створювати лише у режимі --pgp2\n"
-
-msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
-msgstr "у режимі --pgp2 не можна одночасно підписувати і зашифровувати дані\n"
-
-msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
-msgstr ""
-"вам слід використовувати файли (не канали даних) під час роботи з увімкненим "
-"--pgp2.\n"
-
-msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
-msgstr ""
-"шифрування повідомлень у режимі --pgp2 потребує використання шифру IDEA\n"
-
 msgid "selected cipher algorithm is invalid\n"
 msgstr "вибраний алгоритм шифрування є некоректним\n"
 
@@ -2038,7 +2135,7 @@ msgstr "некоректне значення default-cert-level; має бут
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
 msgstr "некоректне значення min-cert-level; має бути 1, 2 або 3\n"
 
-msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
+msgid "Note: simple S2K mode (0) is strongly discouraged\n"
 msgstr ""
 "ЗАУВАЖЕННЯ: наполегливо не рекомендуємо вам користуватися простим режимом "
 "S2K (0)\n"
@@ -2063,17 +2160,17 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s ще не може працювати разом з %s\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "не можна використовувати алгоритм шифрування «%s» у режимі %s\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr ""
 "не можна використовувати алгоритм створення контрольних сум «%s» у режимі "
 "%s\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "не можна використовувати алгоритм стискання «%s» у режимі %s\n"
 
 #, c-format
@@ -2092,7 +2189,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [назва файла]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "помилка під час спроби симетричного шифрування «%s»: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2181,7 +2278,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "помилка перетворення у формат ASCII: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "некоректний алгоритм хешування «%s»\n"
 
 msgid "[filename]"
@@ -2222,7 +2319,7 @@ msgid "No help available"
 msgstr "Довідки не передбачено"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "Довідки щодо %s не виявлено"
 
 msgid "import signatures that are marked as local-only"
@@ -2231,15 +2328,9 @@ msgstr "імпортувати підписи, позначені як лише
 msgid "repair damage from the pks keyserver during import"
 msgstr "відновлювати пошкодження сервером ключів pks під час імпортування"
 
-msgid "do not clear the ownertrust values during import"
-msgstr "не спорожняти дані щодо довіри власнику під час імпортування"
-
 msgid "do not update the trustdb after import"
 msgstr "не оновлювати базу даних довіри після імпортування"
 
-msgid "create a public key when importing a secret key"
-msgstr "створити відкритий ключ під час імпортування закритого ключа"
-
 msgid "only accept updates to existing keys"
 msgstr "приймати оновлення лише вже створених ключів"
 
@@ -2354,12 +2445,13 @@ msgstr ""
 msgid "key %s: no user ID\n"
 msgstr "ключ %s: немає ідентифікатор користувача\n"
 
-#, c-format
+#, fuzzy, c-format
+#| msgid "skipped \"%s\": %s\n"
 msgid "key %s: %s\n"
-msgstr "клÑ\8eÑ\87 %s: %s\n"
+msgstr "пÑ\80опÑ\83Ñ\89ено Â«%s»: %s\n"
 
-msgid "rejected by import filter"
-msgstr "відкинуто фільтром імпортування"
+msgid "rejected by import screener"
+msgstr ""
 
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
@@ -2389,11 +2481,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "не виявлено придатного до запису сховища ключів: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "записуємо до «%s»\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "помилка під час спроби запису сховища ключів «%s»: %s\n"
 
 #, c-format
@@ -2457,31 +2549,28 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "ключ %s: «%s» не змінено\n"
 
 #, c-format
-msgid "secret key %s: %s\n"
-msgstr "закритий ключ %s: %s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "імпортування закритих ключів заборонено\n"
+msgid "key %s: secret key imported\n"
+msgstr "ключ %s: імпортовано закритий ключ\n"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "клÑ\8eÑ\87 %s: Ð·Ð°ÐºÑ\80иÑ\82ий ÐºÐ»Ñ\8eÑ\87 Ð· Ð½ÐµÐºÐ¾Ñ\80екÑ\82ним Ñ\88иÑ\84Ñ\80ом %d â\80\94 Ð¿Ñ\80опÑ\83Ñ\89ено\n"
+msgid "key %s: secret key already exists\n"
+msgstr "клÑ\8eÑ\87 %s: Ð·Ð°ÐºÑ\80иÑ\82ий ÐºÐ»Ñ\8eÑ\87 Ð²Ð¶Ðµ Ñ\96Ñ\81нÑ\83Ñ\94\n"
 
 #, c-format
-msgid "no default secret keyring: %s\n"
-msgstr "немаÑ\94 Ñ\82ипового Ñ\81Ñ\85овиÑ\89а Ð·Ð°ÐºÑ\80иÑ\82иÑ\85 ÐºÐ»Ñ\8eÑ\87Ñ\96в: %s\n"
+msgid "key %s: error sending to agent: %s\n"
+msgstr "клÑ\8eÑ\87 %s: Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° Ð¿Ñ\96д Ñ\87аÑ\81 Ñ\81пÑ\80оби Ð½Ð°Ð´Ñ\81иланнÑ\8f Ð°Ð³ÐµÐ½Ñ\82Ñ\83: %s\n"
 
-#, c-format
-msgid "key %s: secret key imported\n"
-msgstr "ключ %s: імпортовано закритий ключ\n"
+#, fuzzy, c-format
+#| msgid "secret key \"%s\" not found: %s\n"
+msgid "secret key %s: %s\n"
+msgstr "закритий ключ «%s» не знайдено: %s\n"
 
-#, c-format
-msgid "key %s: already in secret keyring\n"
-msgstr "ключ %s: вже у сховищі закритих ключів\n"
+msgid "importing secret keys not allowed\n"
+msgstr "імпортування закритих ключів заборонено\n"
 
 #, c-format
-msgid "key %s: secret key not found: %s\n"
-msgstr "клÑ\8eÑ\87 %s: Ð·Ð°ÐºÑ\80иÑ\82ий ÐºÐ»Ñ\8eÑ\87 Ð½Ðµ Ð·Ð½Ð°Ð¹Ð´ÐµÐ½Ð¾: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "клÑ\8eÑ\87 %s: Ð·Ð°ÐºÑ\80иÑ\82ий ÐºÐ»Ñ\8eÑ\87 Ð· Ð½ÐµÐºÐ¾Ñ\80екÑ\82ним Ñ\88иÑ\84Ñ\80ом %d â\80\94 Ð¿Ñ\80опÑ\83Ñ\89ено\n"
 
 #, c-format
 msgid "key %s: no public key - can't apply revocation certificate\n"
@@ -2591,27 +2680,24 @@ msgstr "ключ %s: додано сертифікат відкликання «
 msgid "key %s: direct key signature added\n"
 msgstr "ключ %s: додано безпосередній підпис ключа\n"
 
-msgid "NOTE: a key's S/N does not match the card's one\n"
-msgstr ""
-"ЗАУВАЖЕННЯ: серійний номер ключа не збігається з серійним номером ключа на "
-"картці\n"
-
-msgid "NOTE: primary key is online and stored on card\n"
-msgstr "ЗАУВАЖЕННЯ: основний ключ використано і збережено на картці\n"
-
-msgid "NOTE: secondary key is online and stored on card\n"
-msgstr "ЗАУВАЖЕННЯ: вторинний ключ використано і збережено на картці\n"
+#, c-format
+msgid "error creating keybox '%s': %s\n"
+msgstr "помилка під час спроби створення сховища ключів «%s»: %s\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "помилка під час спроби створення сховища ключів «%s»: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keybox '%s' created\n"
+msgstr "створено сховище ключів «%s»\n"
+
+#, c-format
+msgid "keyring '%s' created\n"
 msgstr "створено сховище ключів «%s»\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "ресурс блоку ключів «%s»: %s\n"
 
 #, c-format
@@ -2771,14 +2857,6 @@ msgid "Do you want your signature to expire at the same time? (Y/n) "
 msgstr "Бажаєте, щоб строк дії вашого підпису був таким самим? (Y/n або Т/н) "
 
 msgid ""
-"You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
-"mode.\n"
-msgstr "Не можна створювати підпис OpenPGP ключа PGP 2.x у режимі --pgp2.\n"
-
-msgid "This would make the key unusable in PGP 2.x.\n"
-msgstr "Це може зробити ключ непридатним до використання у PGP 2.x.\n"
-
-msgid ""
 "How carefully have you verified the key you are about to sign actually "
 "belongs\n"
 "to the person named above?  If you don't know what to answer, enter \"0\".\n"
@@ -2804,7 +2882,7 @@ msgstr "   (2) Мною виконано часткову перевірку.%s\
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) Мною виконано ретельну перевірку.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "Ваш вибір? (введіть «?», щоб дізнатися більше): "
 
 #, c-format
@@ -2849,41 +2927,9 @@ msgstr ""
 "До ключа включено лише типовий заповнювач або записи ключа з картки — ніяких "
 "паролів не потрібно змінювати.\n"
 
-msgid "This key is not protected.\n"
-msgstr "Цей ключ не захищено.\n"
-
-msgid "Secret parts of primary key are not available.\n"
-msgstr "Закриті частини основного ключа недоступні.\n"
-
-msgid "Secret parts of primary key are stored on-card.\n"
-msgstr "Закриті частини основного ключа зберігаються на картці.\n"
-
-msgid "Key is protected.\n"
-msgstr "Ключ захищено.\n"
-
 #, c-format
-msgid "Can't edit this key: %s\n"
-msgstr "Редагування цього ключа неможливе: %s\n"
-
-msgid ""
-"Enter the new passphrase for this secret key.\n"
-"\n"
-msgstr ""
-"Вкажіть новий пароль для цього закритого ключа.\n"
-"\n"
-
-msgid "passphrase not correctly repeated; try again"
-msgstr "помилка під час повторного введення пароля, повторіть спробу"
-
-msgid ""
-"You don't want a passphrase - this is probably a *bad* idea!\n"
-"\n"
-msgstr ""
-"Ви не використовуєте пароля — дуже погана робота!\n"
-"\n"
-
-msgid "Do you really want to do this? (y/N) "
-msgstr "Ви справді цього бажаєте? (y/N або т/Н) "
+msgid "key %s: error changing passphrase: %s\n"
+msgstr "ключ %s: помилка під час спроби зміни пароля: %s\n"
 
 msgid "moving a key signature to the correct place\n"
 msgstr "пересування підпису ключа у належне місце\n"
@@ -3012,10 +3058,6 @@ msgstr ""
 "ущільнити непридатні до використання ідентифікатори користувачів і вилучити "
 "всі підписи з ключа"
 
-#, c-format
-msgid "error reading secret keyblock \"%s\": %s\n"
-msgstr "помилка під час читання блоку ключів «%s»: %s\n"
-
 msgid "Secret key is available.\n"
 msgstr "Доступний закритий ключ.\n"
 
@@ -3026,9 +3068,9 @@ msgid "Please use the command \"toggle\" first.\n"
 msgstr "Скористайтеся спочатку командою «toggle».\n"
 
 msgid ""
-"* The `sign' command may be prefixed with an `l' for local signatures "
+"* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
-"  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
+"  a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n"
 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"
 msgstr ""
 "* До команди «sign» можна додати «l» для локальних підписів (lsign),\n"
@@ -3045,7 +3087,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "Підказка: виберіть ідентифікатори користувача для підписування\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "Невідомий тип підпису «%s»\n"
 
 #, c-format
@@ -3076,11 +3118,11 @@ msgid "Command expects a filename argument\n"
 msgstr "Для команди слід вказати аргумент з назвою файла\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "Не вдалося відкрити «%s»: %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "Помилка читання резервного ключа з «%s»: %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3132,13 +3174,23 @@ msgstr "Вийти без збереження? (y/N або т/Н) "
 msgid "update failed: %s\n"
 msgstr "помилка оновлення: %s\n"
 
-#, c-format
-msgid "update secret failed: %s\n"
-msgstr "спроба оновлення пароля зазнала невдачі: %s\n"
-
 msgid "Key not changed so no update needed.\n"
 msgstr "Ключ не змінено, отже оновлення непотрібне.\n"
 
+#, c-format
+msgid "\"%s\" is not a fingerprint\n"
+msgstr "«%s» не є відбитком\n"
+
+#, c-format
+msgid "\"%s\" is not the primary fingerprint\n"
+msgstr "«%s» не є основним відбитком\n"
+
+msgid "No matching user IDs."
+msgstr "Немає відповідних ідентифікаторів користувачів."
+
+msgid "Nothing to sign.\n"
+msgstr "Нічого підписувати.\n"
+
 msgid "Digest: "
 msgstr "Контрольна сума: "
 
@@ -3189,6 +3241,9 @@ msgstr "діє до: %s"
 msgid "usage: %s"
 msgstr "використання: %s"
 
+msgid "card-no: "
+msgstr "номер картки: "
+
 #, c-format
 msgid "trust: %s"
 msgstr "надійність: %s"
@@ -3200,9 +3255,6 @@ msgstr "чинність: %s"
 msgid "This key has been disabled"
 msgstr "Цей ключ було вимкнено"
 
-msgid "card-no: "
-msgstr "номер картки: "
-
 msgid ""
 "Please note that the shown key validity is not necessarily correct\n"
 "unless you restart the program.\n"
@@ -3328,9 +3380,6 @@ msgstr ""
 "Ви справді бажаєте призначити цей ключ як підписане відкликання? (y/N або т/"
 "Н) "
 
-msgid "Please remove selections from the secret keys.\n"
-msgstr "Будь ласка, вилучіть вказане з закритих ключів.\n"
-
 msgid "Please select at most one subkey.\n"
 msgstr "Будь ласка, виберіть не більше одного ключа.\n"
 
@@ -3343,9 +3392,6 @@ msgstr "Зміна часу завершення строку дії для ос
 msgid "You can't change the expiration date of a v3 key\n"
 msgstr "Не можна змінювати дату завершення строку дії ключа v3\n"
 
-msgid "No corresponding signature in secret ring\n"
-msgstr "Немає відповідного підпису у сховищі закритих ключів\n"
-
 #, c-format
 msgid "signing subkey %s is already cross-certified\n"
 msgstr "підписування підключа %s вже перехресно сертифіковано\n"
@@ -3457,7 +3503,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "Показ фотоідентифікатора %s розміру %ld для ключа %s (uid %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "запис переваги «%s» продубльовано\n"
 
 msgid "too many cipher preferences\n"
@@ -3470,7 +3516,7 @@ msgid "too many compression preferences\n"
 msgstr "занадто багато записів переваг стискання\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "некоректний запис «%s» у рядку переваг\n"
 
 msgid "writing direct signature\n"
@@ -3580,6 +3626,36 @@ msgstr "   (%d) DSA (із визначенням можливостей влас
 msgid "   (%d) RSA (set your own capabilities)\n"
 msgstr "   (%d) RSA (із визначенням можливостей власноруч)\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) ECDSA and ECDH\n"
+msgid "   (%d) ECC and ECC\n"
+msgstr "   (%d) ECDSA і ECDH\n"
+
+#, c-format
+msgid "  (%d) ECC (sign only)\n"
+msgstr "  (%d) ECC (лише підписування)\n"
+
+#, c-format
+msgid "  (%d) ECC (set your own capabilities)\n"
+msgstr "  (%d) ECC (із визначенням можливостей власноруч)\n"
+
+#, c-format
+msgid "  (%d) ECC (encrypt only)\n"
+msgstr "  (%d) ECC (лише шифрування)\n"
+
+#, c-format
+msgid "  (%d) Existing key\n"
+msgstr "   (%d) Вже записаний ключ\n"
+
+msgid "Enter the keygrip: "
+msgstr "Вкажіть keygrip: "
+
+msgid "Not a valid keygrip (expecting 40 hex digits)\n"
+msgstr "Некоректний keygrip (мало бути вказано 40 шістнадцяткових цифр)\n"
+
+msgid "No key with this keygrip\n"
+msgstr "Немає ключів з таким значенням keygrip\n"
+
 #, c-format
 msgid "%s keys may be between %u and %u bits long.\n"
 msgstr "ключі %s можуть мати довжину від %u до %u бітів.\n"
@@ -3596,6 +3672,13 @@ msgstr "Якою має бути довжина ключа? (%u) "
 msgid "Requested keysize is %u bits\n"
 msgstr "Запитана довжина ключа — %u бітів\n"
 
+#, c-format
+msgid "rounded to %u bits\n"
+msgstr "округлено до %u бітів\n"
+
+msgid "Please select which elliptic curve you want:\n"
+msgstr "Вкажіть потрібну вам еліптичну криву:\n"
+
 msgid ""
 "Please specify how long the key should be valid.\n"
 "         0 = key does not expire\n"
@@ -3715,7 +3798,7 @@ msgid "Invalid character in comment\n"
 msgstr "Некоректний символ у коментарі\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "Вами використано таблицю символів «%s».\n"
 
 #, c-format
@@ -3757,6 +3840,17 @@ msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
 msgstr ""
 "Змінити назву (N), коментар (C), ел. пошту (E) або гаразд (O) чи вийти (Q)? "
 
+#, fuzzy
+#| msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? "
+msgid "Change (N)ame, (E)mail, or (Q)uit? "
+msgstr "Змінити назву (N), коментар (C), ел. пошту (E) або вийти (Q)? "
+
+#, fuzzy
+#| msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
+msgid "Change (N)ame, (E)mail, or (O)kay/(Q)uit? "
+msgstr ""
+"Змінити назву (N), коментар (C), ел. пошту (E) або гаразд (O) чи вийти (Q)? "
+
 msgid "Please correct the error first\n"
 msgstr "Спочатку виправте помилку\n"
 
@@ -3774,6 +3868,9 @@ msgstr ""
 "Будь ласка, вкажіть пароль для захисту позакарткової резервної копії нового "
 "ключа шифрування."
 
+msgid "passphrase not correctly repeated; try again"
+msgstr "помилка під час повторного введення пароля, повторіть спробу"
+
 #, c-format
 msgid "%s.\n"
 msgstr "%s.\n"
@@ -3800,37 +3897,54 @@ msgstr ""
 "під час створення простого числа. Це надасть змогу генератору\n"
 "псевдовипадкових чисел створити краще випадкове число.\n"
 
-msgid "Key generation canceled.\n"
-msgstr "Створення ключа скасовано.\n"
+#, c-format
+msgid "Key generation failed: %s\n"
+msgstr "Помилка під час спроби створення ключа: %s\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
-msgstr "записуємо відкритий ключ до «%s»\n"
+msgid ""
+"About to create a key for:\n"
+"    \"%s\"\n"
+"\n"
+msgstr ""
+
+msgid "Continue? (Y/n) "
+msgstr ""
+
+#, fuzzy, c-format
+#| msgid "key already exists\n"
+msgid "A key for \"%s\" already exists\n"
+msgstr "ключ вже існує\n"
+
+#, fuzzy
+#| msgid "Use this key anyway? (y/N) "
+msgid "Create anyway? (y/N) "
+msgstr "Попри все використовувати цей ключ? (y/N або т/Н) "
+
+#, fuzzy
+#| msgid "generating new key\n"
+msgid "creating anyway\n"
+msgstr "створення нового ключа\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
-msgstr "спроба запису заглушки закритого ключа до «%s»\n"
+msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n"
+msgstr ""
+
+msgid "Key generation canceled.\n"
+msgstr "Створення ключа скасовано.\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
-msgstr "спроба запису закритого ключа до «%s»\n"
+msgid "writing public key to '%s'\n"
+msgstr "записуємо відкритий ключ до «%s»\n"
 
 #, c-format
 msgid "no writable public keyring found: %s\n"
 msgstr "не знайдено придатного до запису сховища відкритих ключів: %s\n"
 
 #, c-format
-msgid "no writable secret keyring found: %s\n"
-msgstr "не виявлено придатного до запису сховища закритих ключів: %s\n"
-
-#, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "помилка під час спроби запису до сховища відкритих ключів «%s»: %s\n"
 
-#, c-format
-msgid "error writing secret keyring `%s': %s\n"
-msgstr "помилка під час спроби запису до сховища закритих ключів «%s»: %s\n"
-
 msgid "public and secret key created and signed.\n"
 msgstr "відкритий і закритий ключі створено і підписано.\n"
 
@@ -3842,10 +3956,6 @@ msgstr ""
 "скористатися командою «--edit-key» для створення підключа з цією метою.\n"
 
 #, c-format
-msgid "Key generation failed: %s\n"
-msgstr "Помилка під час спроби створення ключа: %s\n"
-
-#, c-format
 msgid ""
 "key has been created %lu second in future (time warp or clock problem)\n"
 msgstr ""
@@ -3859,9 +3969,15 @@ msgstr ""
 "ключ було створено з позначкою на %lu секунду у майбутньому (часова петля "
 "або проблема з годинником)\n"
 
-msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
+msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n"
 msgstr "ЗАУВАЖЕННЯ: створення підключів для ключів v3 несумісне з OpenPGP\n"
 
+msgid "Secret parts of primary key are not available.\n"
+msgstr "Закриті частини основного ключа недоступні.\n"
+
+msgid "Secret parts of primary key are stored on-card.\n"
+msgstr "Закриті частини основного ключа зберігаються на картці.\n"
+
 msgid "Really create? (y/N) "
 msgstr "Створити? (y/N або т/Н) "
 
@@ -3870,11 +3986,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "спроба зберігання ключа на картці зазнала невдачі: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "не вдалося створити файл резервної копії «%s»: %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "Note: backup of card key saved to '%s'\n"
 msgstr "ЗАУВАЖЕННЯ: резервну копію ключа на картці збережено до «%s»\n"
 
 msgid "never     "
@@ -3895,6 +4011,10 @@ msgstr "Критична примітка підпису: "
 msgid "Signature notation: "
 msgstr "Примітка підпису: "
 
+#, c-format
+msgid "Warning: %lu key(s) skipped due to their large size\n"
+msgstr ""
+
 msgid "Keyring"
 msgstr "Сховище ключів"
 
@@ -3915,36 +4035,15 @@ msgstr "       Відбиток підключа:"
 msgid "      Key fingerprint ="
 msgstr "      Відбиток ключа ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr ""
-"УВАГА: використовуємо експериментальний алгоритм обчислення контрольних сум "
-"%s\n"
-
 msgid "      Card serial no. ="
 msgstr "Серійний номер картки ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "спроба перейменування «%s» на «%s» зазнала невдачі: %s\n"
 
-msgid "WARNING: 2 files with confidential information exists.\n"
-msgstr "УВАГА: існує 2 файли з конфіденційними даними.\n"
-
 #, c-format
-msgid "%s is the unchanged one\n"
-msgstr "%s є незмінним\n"
-
-#, c-format
-msgid "%s is the new one\n"
-msgstr "%s є новим\n"
-
-msgid "Please fix this possible security flaw\n"
-msgstr "Будь ласка, виправте цю можливу ваду захисту\n"
-
-#, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "кешування сховища ключів «%s»\n"
 
 #, c-format
@@ -3984,7 +4083,7 @@ msgstr ""
 "брати до уваги запис PKA, встановлений у ключі під час отримання ключів"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr ""
 "УВАГА: параметр сервера ключів «%s» не використовується на цій платформі\n"
 
@@ -3999,6 +4098,26 @@ msgid "invalid keyserver protocol (us %d!=handler %d)\n"
 msgstr "некоректний протокол сервера ключів (наш %d!=%d обробника)\n"
 
 #, c-format
+msgid "\"%s\" not a key ID: skipping\n"
+msgstr "«%s» не є ідентифікатором ключа: пропускаємо\n"
+
+#, c-format
+msgid "WARNING: unable to refresh key %s via %s: %s\n"
+msgstr "УВАГА: не вдалося оновити ключ %s за допомогою %s: %s\n"
+
+#, c-format
+msgid "refreshing 1 key from %s\n"
+msgstr "оновлюємо 1 ключ з %s\n"
+
+#, c-format
+msgid "refreshing %d keys from %s\n"
+msgstr "оновлюємо %d ключів з %s\n"
+
+msgid "no keyserver known (use option --keyserver)\n"
+msgstr ""
+"не вказано жодного сервера ключів (скористайтеся параметром --keyserver)\n"
+
+#, c-format
 msgid "key \"%s\" not found on keyserver\n"
 msgstr "ключ «%s» не знайдено на сервері ключів\n"
 
@@ -4014,12 +4133,8 @@ msgid "requesting key %s from %s\n"
 msgstr "надсилаємо запит щодо ключа %s з %s\n"
 
 #, c-format
-msgid "searching for names from %s server %s\n"
-msgstr "шукаємо назви з %s сервера %s\n"
-
-#, c-format
-msgid "searching for names from %s\n"
-msgstr "шукаємо назви на %s\n"
+msgid "skipped \"%s\": %s\n"
+msgstr "пропущено «%s»: %s\n"
 
 #, c-format
 msgid "sending key %s to %s server %s\n"
@@ -4030,78 +4145,14 @@ msgid "sending key %s to %s\n"
 msgstr "надсилаємо ключ %s на %s\n"
 
 #, c-format
-msgid "searching for \"%s\" from %s server %s\n"
-msgstr "шукаємо «%s» на %s сервера %s\n"
-
-#, c-format
-msgid "searching for \"%s\" from %s\n"
-msgstr "шукаємо «%s» з %s\n"
-
-msgid "no keyserver action!\n"
-msgstr "немає дії щодо сервера ключів!\n"
-
-#, c-format
-msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
-msgstr ""
-"УВАГА: засіб обробки даних сервера ключів взято з іншої версії GnuPG (%s)\n"
-
-msgid "keyserver did not send VERSION\n"
-msgstr "сервер ключів не надіслав значення VERSION\n"
-
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "помилка під час обміну даними з сервером ключів: %s\n"
-
-msgid "no keyserver known (use option --keyserver)\n"
-msgstr ""
-"не вказано жодного сервера ключів (скористайтеся параметром --keyserver)\n"
-
-msgid "external keyserver calls are not supported in this build\n"
-msgstr "викликів зовнішнього сервера ключів у цій збірці не передбачено\n"
-
-#, c-format
-msgid "no handler for keyserver scheme `%s'\n"
-msgstr "немає обробника схеми сервера ключів «%s»\n"
-
-#, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
-msgstr "дії «%s» не передбачено для схеми сервера ключів «%s»\n"
-
-#, c-format
-msgid "%s does not support handler version %d\n"
-msgstr "у %s не передбачено підтримки обробника версії %d\n"
-
-msgid "keyserver timed out\n"
-msgstr "перевищення часу очікування даних від сервера ключів\n"
-
-msgid "keyserver internal error\n"
-msgstr "внутрішня помилка сервера ключів\n"
-
-#, c-format
-msgid "\"%s\" not a key ID: skipping\n"
-msgstr "«%s» не є ідентифікатором ключа: пропускаємо\n"
-
-#, c-format
-msgid "WARNING: unable to refresh key %s via %s: %s\n"
-msgstr "УВАГА: не вдалося оновити ключ %s за допомогою %s: %s\n"
-
-#, c-format
-msgid "refreshing 1 key from %s\n"
-msgstr "оновлюємо 1 ключ з %s\n"
-
-#, c-format
-msgid "refreshing %d keys from %s\n"
-msgstr "оновлюємо %d ключів з %s\n"
+msgid "requesting key from '%s'\n"
+msgstr "надсилаємо запит щодо ключа з «%s»\n"
 
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
 msgstr "УВАГА: не вдалося отримати адресу %s: %s\n"
 
 #, c-format
-msgid "WARNING: unable to parse URI %s\n"
-msgstr "УВАГА: не вдалося обробити адресу %s\n"
-
-#, c-format
 msgid "weird size for an encrypted session key (%d)\n"
 msgstr "дивний розмір для зашифрованого ключа сеансу (%d)\n"
 
@@ -4172,7 +4223,7 @@ msgstr "текстовий пароль кешовано з ідентифіка
 msgid "decryption failed: %s\n"
 msgstr "невдала спроба розшифрування: %s\n"
 
-msgid "NOTE: sender requested \"for-your-eyes-only\"\n"
+msgid "Note: sender requested \"for-your-eyes-only\"\n"
 msgstr "ЗАУВАЖЕННЯ: вимога відправника: «лише для Вас»\n"
 
 #, c-format
@@ -4189,9 +4240,21 @@ msgstr ""
 msgid "no signature found\n"
 msgstr "підпису не знайдено\n"
 
-msgid "signature verification suppressed\n"
-msgstr "перевірку підписів придушено\n"
-
+#, c-format
+msgid "BAD signature from \"%s\""
+msgstr "ПОМИЛКОВИЙ підпис від «%s»"
+
+#, c-format
+msgid "Expired signature from \"%s\""
+msgstr "Прострочений підпис від «%s»"
+
+#, c-format
+msgid "Good signature from \"%s\""
+msgstr "Належний підпис від «%s»"
+
+msgid "signature verification suppressed\n"
+msgstr "перевірку підписів придушено\n"
+
 msgid "can't handle this ambiguous signature data\n"
 msgstr "не вдалося обробити ці дані з неоднозначним підписом\n"
 
@@ -4210,18 +4273,6 @@ msgstr "Підпис створено %s ключем %s з ідентифіка
 msgid "Key available at: "
 msgstr "Ключ доступний на: "
 
-#, c-format
-msgid "BAD signature from \"%s\""
-msgstr "ПОМИЛКОВИЙ підпис від «%s»"
-
-#, c-format
-msgid "Expired signature from \"%s\""
-msgstr "Прострочений підпис від «%s»"
-
-#, c-format
-msgid "Good signature from \"%s\""
-msgstr "Належний підпис від «%s»"
-
 msgid "[uncertain]"
 msgstr "[непевний]"
 
@@ -4238,8 +4289,8 @@ msgid "Signature expires %s\n"
 msgstr "Підпис діє до %s\n"
 
 #, c-format
-msgid "%s signature, digest algorithm %s\n"
-msgstr "%s підпис, алгоритм контрольної суми %s\n"
+msgid "%s signature, digest algorithm %s%s%s\n"
+msgstr "%s підпис, алгоритм контрольної суми %s%s%s\n"
 
 msgid "binary"
 msgstr "двійковий"
@@ -4250,9 +4301,10 @@ msgstr "текстовий"
 msgid "unknown"
 msgstr "невідомо"
 
-#, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr "УВАГА: підпис не є від’єднаним; перевірку файла «%s» не виконано!\n"
+#, fuzzy
+#| msgid "algorithm: %s"
+msgid ", key algorithm "
+msgstr "алгоритм: %s"
 
 #, c-format
 msgid "Can't check signature: %s\n"
@@ -4276,7 +4328,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "виявлено некоректний кореневий пакет у proc_tree()\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "помилка fstat щодо «%s» у %s: %s\n"
 
 #, c-format
@@ -4311,13 +4363,6 @@ msgstr "УВАГА: алгоритм обчислення контрольних
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Зауваження: підписи за допомогою алгоритму %s відкинуто\n"
 
-msgid "the IDEA cipher plugin is not present\n"
-msgstr "не виявлено додатка шифрування IDEA\n"
-
-#, c-format
-msgid "please see %s for more information\n"
-msgstr "будь ласка, ознайомтеся з %s, щоб дізнатися більше\n"
-
 #, c-format
 msgid "%s:%d: deprecated option \"%s\"\n"
 msgstr "%s:%d: застарілий параметр «%s»\n"
@@ -4338,19 +4383,21 @@ msgstr "УВАГА: «%s» вважається застарілою коман
 msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
 msgstr "%s:%u: застарілий параметр «%s» — він не працюватиме\n"
 
-#, c-format
-msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
 msgstr "УВАГА: «%s» є застарілим параметром — він не працюватиме\n"
 
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: «%s%s» є застарілим у цьому файлі — він працює лише у %s\n"
+#, fuzzy, c-format
+#| msgid "%s:%u: obsolete option \"%s\" - it has no effect\n"
+msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n"
+msgstr "%s:%u: застарілий параметр «%s» — він не працюватиме\n"
 
-#, c-format
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgid ""
 "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr ""
-"УВАГА: «%s%s» є застарілим параметром — він не працюватиме, окрім як на %s\n"
+msgstr "УВАГА: «%s» є застарілим параметром — він не працюватиме\n"
 
 msgid "Uncompressed"
 msgstr "Нестиснений"
@@ -4364,15 +4411,19 @@ msgid "this message may not be usable by %s\n"
 msgstr "використання цього повідомлення щодо %s може бути неможливим\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "неоднозначний параметр «%s»\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "невідомий параметр «%s»\n"
 
+msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n"
+msgstr ""
+"Відкритий ключ ECDSA має зберігатися у кодуванні SEC кратному 8-бітовому\n"
+
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "Файл «%s» існує. "
 
 msgid "Overwrite? (y/N) "
@@ -4393,11 +4444,11 @@ msgid "assuming signed data in '%s'\n"
 msgstr "припускаємо підписані дані у «%s»\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "створено новий файл налаштувань «%s»\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "УВАГА: параметри у «%s» ще не є активними під час цього запуску\n"
 
 #, c-format
@@ -4456,6 +4507,38 @@ msgstr "%u-бітовий ключ %s, ідентифікатор %s, створ
 msgid "         (subkey on main key ID %s)"
 msgstr "         (підключ у ідентифікаторі основного ключа %s)"
 
+msgid "Please enter the passphrase to unlock the OpenPGP secret key:"
+msgstr "Вкажіть пароль для розблокування закритого ключа OpenPGP:"
+
+msgid "Please enter the passphrase to import the OpenPGP secret key:"
+msgstr "Вкажіть пароль для імпортування закритого ключа OpenPGP:"
+
+msgid "Please enter the passphrase to export the OpenPGP secret subkey:"
+msgstr "Вкажіть пароль для експортування закритого підключа OpenPGP:"
+
+msgid "Please enter the passphrase to export the OpenPGP secret key:"
+msgstr "Вкажіть пароль для експортування закритого ключа OpenPGP:"
+
+msgid "Do you really want to permanently delete the OpenPGP secret subkey key:"
+msgstr "Справді хочете остаточно вилучити закритий підключ OpenPGP:"
+
+msgid "Do you really want to permanently delete the OpenPGP secret key:"
+msgstr "Справді хочете остаточно вилучити закритий ключ OpenPGP:"
+
+#, c-format
+msgid ""
+"%s\n"
+"\"%.*s\"\n"
+"%u-bit %s key, ID %s,\n"
+"created %s%s.\n"
+"%s"
+msgstr ""
+"%s\n"
+"«%.*s»\n"
+"%u-бітовий ключ %s, ід. %s,\n"
+"створено %s%s.\n"
+"%s"
+
 msgid ""
 "\n"
 "Pick an image to use for your photo ID.  The image must be a JPEG file.\n"
@@ -4474,7 +4557,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "Вкажіть назву файла JPEG для фотоідентифікатора: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "не вдалося відкрити файл JPEG «%s»: %s\n"
 
 #, c-format
@@ -4485,7 +4568,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "Вам справді хочеться ним скористатися? (y/N або т/Н) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "«%s» не є файлом JPEG\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4633,11 +4716,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "Зауваження: цей ключ було вимкнено.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr "Зауваження: перевіреною адресою автора підпису є «%s»\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr "Зауваження: адреса автора підпису «%s» не збігається з записом DNS\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4674,6 +4757,10 @@ msgid "%s: skipped: %s\n"
 msgstr "%s: пропущено: %s\n"
 
 #, c-format
+msgid "%s: skipped: public key is disabled\n"
+msgstr "%s: пропущено: відкритий ключ вимкнено\n"
+
+#, c-format
 msgid "%s: skipped: public key already present\n"
 msgstr "%s: пропущено: відкритий ключ вже існує\n"
 
@@ -4707,10 +4794,6 @@ msgstr "пропущено: відкритий ключ вже встановл
 msgid "unknown default recipient \"%s\"\n"
 msgstr "невідомий типовий отримувач «%s»\n"
 
-#, c-format
-msgid "%s: skipped: public key is disabled\n"
-msgstr "%s: пропущено: відкритий ключ вимкнено\n"
-
 msgid "no valid addressees\n"
 msgstr "немає коректних адрес\n"
 
@@ -4727,6 +4810,10 @@ msgstr ""
 "дані не збережено; скористайтеся для їхнього збереження параметром «--"
 "output»\n"
 
+#, c-format
+msgid "error creating '%s': %s\n"
+msgstr "помилка створення «%s»: %s.\n"
+
 msgid "Detached signature.\n"
 msgstr "Від’єднаний підпис.\n"
 
@@ -4740,7 +4827,7 @@ msgid "no signed data\n"
 msgstr "немає підписаних даних\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "не вдалося відкрити підписані дані «%s»\n"
 
 #, c-format
@@ -4766,10 +4853,10 @@ msgid "WARNING: cipher algorithm %s not found in recipient preferences\n"
 msgstr "УВАГА: не виявлено алгоритму шифрування %s у перевагах отримувача\n"
 
 #, c-format
-msgid "NOTE: secret key %s expired at %s\n"
+msgid "Note: secret key %s expired at %s\n"
 msgstr "ЗАУВАЖЕННЯ: строк дії закритого ключа %s завершився %s\n"
 
-msgid "NOTE: key has been revoked"
+msgid "Note: key has been revoked"
 msgstr "ЗАУВАЖЕННЯ: ключ було відкликано"
 
 #, c-format
@@ -4804,26 +4891,31 @@ msgstr "Створено сертифікат відкликання.\n"
 msgid "no revocation keys found for \"%s\"\n"
 msgstr "для «%s» не знайдено ключів відкликання\n"
 
+#, fuzzy
+#| msgid "Create a revocation certificate for this key? (y/N) "
+msgid "This is a revocation certificate for the OpenPGP key:"
+msgstr "Створити сертифікат відкликання для цього ключа? (y/N або т/Н) "
+
+msgid ""
+"Use it to revoke this key in case of a compromise or loss of\n"
+"the secret key.  However, if the secret key is still accessible,\n"
+"it is better to generate a new revocation certificate and give\n"
+"a reason for the revocation."
+msgstr ""
+
+msgid ""
+"To avoid an accidental use of this file, a colon has been inserted\n"
+"before the 5 dashes below.  Remove this colon with a text editor\n"
+"before making use of this revocation certificate."
+msgstr ""
+
 #, c-format
 msgid "secret key \"%s\" not found: %s\n"
 msgstr "закритий ключ «%s» не знайдено: %s\n"
 
-#, c-format
-msgid "no corresponding public key: %s\n"
-msgstr "немає відповідного відкритого ключа: %s\n"
-
-msgid "public key does not match secret key!\n"
-msgstr "відкритий ключ не відповідає закритому ключу!\n"
-
 msgid "Create a revocation certificate for this key? (y/N) "
 msgstr "Створити сертифікат відкликання для цього ключа? (y/N або т/Н) "
 
-msgid "unknown protection algorithm\n"
-msgstr "невідомий алгоритм захисту\n"
-
-msgid "NOTE: This key is not protected!\n"
-msgstr "ЗАУВАЖЕННЯ: цей ключ не захищено!\n"
-
 msgid ""
 "Revocation certificate created.\n"
 "\n"
@@ -4866,31 +4958,6 @@ msgstr "(Опису не надано)\n"
 msgid "Is this okay? (y/N) "
 msgstr "Все правильно? (y/N або т/Н) "
 
-msgid "secret key parts are not available\n"
-msgstr "закриті частини ключа недоступні\n"
-
-#, c-format
-msgid "protection algorithm %d%s is not supported\n"
-msgstr "підтримки алгоритму захисту %d%s не передбачено\n"
-
-#, c-format
-msgid "protection digest %d is not supported\n"
-msgstr "підтримки контрольної суми захисту %d не передбачено\n"
-
-msgid "Invalid passphrase; please try again"
-msgstr "Некоректний пароль; повторіть спробу"
-
-#, c-format
-msgid "%s ...\n"
-msgstr "%s…\n"
-
-msgid "WARNING: Weak key detected - please change passphrase again.\n"
-msgstr "УВАГА: виявлено слабкий ключ — будь ласка, змініть пароль.\n"
-
-msgid "generating the deprecated 16-bit checksum for secret key protection\n"
-msgstr ""
-"створюємо застарілу 16-бітову контрольну суму для захисту закритого ключа\n"
-
 msgid "weak key created - retrying\n"
 msgstr "створено слабкий ключ — повторюємо спробу\n"
 
@@ -4900,16 +4967,15 @@ msgstr ""
 "не вдалося створити стійкий ключ для симетричного шифрування; спроба "
 "виконувалася %d разів!\n"
 
-msgid "DSA requires the hash length to be a multiple of 8 bits\n"
-msgstr "Для DSA довжина хешу має бути кратною до 8 бітів\n"
-
 #, c-format
-msgid "DSA key %s uses an unsafe (%u bit) hash\n"
-msgstr "Ключ DSA %s використовує небезпечне (%u-бітове) хешування\n"
+msgid "%s key %s uses an unsafe (%zu bit) hash\n"
+msgstr "Ключ %s використовує %s недостатньо міцний (%zu-бітовий) хеш\n"
 
 #, c-format
-msgid "DSA key %s requires a %u bit or larger hash\n"
-msgstr "Ключ DSA %s потребує хешу з %u або більшої кількості бітів\n"
+msgid "%s key %s requires a %zu bit or larger hash (hash is %s)\n"
+msgstr ""
+"Для використання %s ключа %s потрібен хеш з %zu або більше бітів (маємо хеш "
+"%s)\n"
 
 msgid "WARNING: signature digest conflict in message\n"
 msgstr "УВАГА: конфлікт контрольних сум підписів у повідомленні\n"
@@ -4919,6 +4985,10 @@ msgid "WARNING: signing subkey %s is not cross-certified\n"
 msgstr "УВАГА: підписування підключа %s не є перехресно сертифікованим\n"
 
 #, c-format
+msgid "please see %s for more information\n"
+msgstr "будь ласка, ознайомтеся з %s, щоб дізнатися більше\n"
+
+#, c-format
 msgid "WARNING: signing subkey %s has an invalid cross-certification\n"
 msgstr ""
 "УВАГА: підписування підключа %s містить некоректну перехресну сертифікацію\n"
@@ -4946,11 +5016,11 @@ msgstr ""
 "або проблема з годинником)\n"
 
 #, c-format
-msgid "NOTE: signature key %s expired %s\n"
+msgid "Note: signature key %s expired %s\n"
 msgstr "ЗАУВАЖЕННЯ: строк дії ключа підпису %s завершився %s\n"
 
 #, c-format
-msgid "NOTE: signature key %s has been revoked\n"
+msgid "Note: signature key %s has been revoked\n"
 msgstr "ЗАУВАЖЕННЯ: ключ підпису %s було відкликано\n"
 
 #, c-format
@@ -4995,11 +5065,6 @@ msgstr "невдала спроба перевірити створений пі
 msgid "%s/%s signature from: \"%s\"\n"
 msgstr "%s/%s підпис від: \"%s\"\n"
 
-msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"підписування від’єднаним ключем можливе лише за допомогою ключів у форматі "
-"PGP 2.x у режимі --pgp2\n"
-
 #, c-format
 msgid ""
 "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n"
@@ -5010,11 +5075,6 @@ msgstr ""
 msgid "signing:"
 msgstr "підписування:"
 
-msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
-msgstr ""
-"підписування текстовим ключем можливе лише за допомогою ключів у форматі PGP "
-"2.x у режимі --pgp2\n"
-
 #, c-format
 msgid "%s encryption will be used\n"
 msgstr "Буде використано шифрування %s\n"
@@ -5028,10 +5088,6 @@ msgstr ""
 msgid "skipped \"%s\": duplicated\n"
 msgstr "пропущено «%s»: дублювання\n"
 
-#, c-format
-msgid "skipped \"%s\": %s\n"
-msgstr "пропущено «%s»: %s\n"
-
 msgid "skipped: secret key already present\n"
 msgstr "пропущено: закритий ключ вже існує\n"
 
@@ -5053,7 +5109,7 @@ msgstr ""
 "# (Скористайтеся «gpg --import-ownertrust» для їхнього відновлення)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "помилка у «%s»: %s\n"
 
 msgid "line too long"
@@ -5069,11 +5125,11 @@ msgid "ownertrust value missing"
 msgstr "пропущено значення довіри до власника"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "не вдалося знайти запис довіри у «%s»: %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "помилка читання у «%s»: %s\n"
 
 #, c-format
@@ -5081,14 +5137,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "trustdb: помилка синхронізації: %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "не вдалося створити блокування для «%s»\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "не вдалося заблокувати «%s»\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "запис trustdb %lu: помилка lseek: %s\n"
 
@@ -5100,12 +5148,20 @@ msgid "trustdb transaction too large\n"
 msgstr "занадто велика операція trustdb\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "немає доступу до «%s»: %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: каталогу не існує!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "немає доступу до «%s»: %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "не вдалося створити блокування для «%s»\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "не вдалося заблокувати «%s»\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5119,7 +5175,7 @@ msgstr "%s: створено некоректну trustdb\n"
 msgid "%s: trustdb created\n"
 msgstr "%s: створено trustdb\n"
 
-msgid "NOTE: trustdb not writable\n"
+msgid "Note: trustdb not writable\n"
 msgstr "ЗАУВАЖЕННЯ: запис до trustdb заборонено\n"
 
 #, c-format
@@ -5191,7 +5247,7 @@ msgid "input line longer than %d characters\n"
 msgstr "рядок вхідних даних довший за %d символів\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "«%s» не є коректним довгим ідентифікатором ключа\n"
 
 #, c-format
@@ -5235,53 +5291,6 @@ msgstr ""
 msgid "using %s trust model\n"
 msgstr "використовуємо модель довіри %s\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
-msgid "10 translator see trustdb.c:uid_trust_string_fixed"
-msgstr "10 translator see trustdb.c:uid_trust_string_fixed"
-
-msgid "[ revoked]"
-msgstr "[відклик.]"
-
-msgid "[ expired]"
-msgstr "[застаріл]"
-
-msgid "[ unknown]"
-msgstr "[невідома]"
-
-msgid "[  undef ]"
-msgstr "[не визн.]"
-
-msgid "[marginal]"
-msgstr "[неповна ]"
-
-msgid "[  full  ]"
-msgstr "[ повна  ]"
-
-msgid "[ultimate]"
-msgstr "[безмежна]"
-
-msgid "undefined"
-msgstr "не визначено"
-
-msgid "never"
-msgstr "ніколи"
-
-msgid "marginal"
-msgstr "неповна"
-
-msgid "full"
-msgstr "повна"
-
-msgid "ultimate"
-msgstr "безмежна"
-
 msgid "no need for a trustdb check\n"
 msgstr "потреби у перевірці trustdb немає\n"
 
@@ -5290,11 +5299,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "наступну перевірку trustdb призначено на %s\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "потреби у перевірці trustdb на основі моделі довіри «%s» немає\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "потреби у оновленні trustdb на основі моделі довіри «%s» немає\n"
 
 #, c-format
@@ -5350,113 +5359,6 @@ msgstr "у рядку вхідних даних %u занадто багато 
 msgid "can't open fd %d: %s\n"
 msgstr "не вдалося відкрити fd %d: %s\n"
 
-msgid "argument not expected"
-msgstr "неочікуваний аргумент"
-
-msgid "read error"
-msgstr "помилка читання"
-
-msgid "keyword too long"
-msgstr "занадто довге ключове слово"
-
-msgid "missing argument"
-msgstr "не вистачає аргументу"
-
-#, fuzzy
-#| msgid "invalid value\n"
-msgid "invalid argument"
-msgstr "некоректне значення\n"
-
-msgid "invalid command"
-msgstr "некоректна команда"
-
-msgid "invalid alias definition"
-msgstr "некоректне визначення замінника"
-
-msgid "out of core"
-msgstr "вихід за межі області пам’яті"
-
-msgid "invalid option"
-msgstr "некоректний параметр"
-
-#, c-format
-msgid "missing argument for option \"%.50s\"\n"
-msgstr "не вказано аргументу до параметра «%.50s»\n"
-
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "не вказано аргументу до параметра «%.50s»\n"
-
-#, c-format
-msgid "option \"%.50s\" does not expect an argument\n"
-msgstr "для параметра «%.50s» аргументи не потрібно вказувати\n"
-
-#, c-format
-msgid "invalid command \"%.50s\"\n"
-msgstr "некоректна команда «%.50s»\n"
-
-#, c-format
-msgid "option \"%.50s\" is ambiguous\n"
-msgstr "параметр «%.50s» є неоднозначним\n"
-
-#, c-format
-msgid "command \"%.50s\" is ambiguous\n"
-msgstr "команда «%.50s» є неоднозначною\n"
-
-msgid "out of core\n"
-msgstr "вихід за межі області пам’яті\n"
-
-#, c-format
-msgid "invalid option \"%.50s\"\n"
-msgstr "некоректний параметр «%.50s»\n"
-
-#, c-format
-msgid "you found a bug ... (%s:%d)\n"
-msgstr "ви виявили ваду… (%s:%d)\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' not available\n"
-msgstr "перетворення з «%s» у «%s» недоступне\n"
-
-#, c-format
-msgid "iconv_open failed: %s\n"
-msgstr "помилка iconv_open: %s\n"
-
-#, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
-msgstr "помилка перетворення з «%s» у «%s»: %s\n"
-
-#, c-format
-msgid "failed to create temporary file `%s': %s\n"
-msgstr "не вдалося створити тимчасовий файл «%s»: %s\n"
-
-#, c-format
-msgid "error writing to `%s': %s\n"
-msgstr "помилка під час спроби запису до «%s»: %s\n"
-
-#, c-format
-msgid "removing stale lockfile (created by %d)\n"
-msgstr "вилучення застарілого файла блокування (створено %d)\n"
-
-msgid " - probably dead - removing lock"
-msgstr " — ймовірно, не використовується — знімаємо блокування"
-
-#, c-format
-msgid "waiting for lock (held by %d%s) %s...\n"
-msgstr "очікування на блокування (зайнято %d%s) %s...\n"
-
-msgid "(deadlock?) "
-msgstr "(застаріле блокування?) "
-
-#, c-format
-msgid "lock `%s' not made: %s\n"
-msgstr "блокування «%s» не виконано: %s\n"
-
-#, c-format
-msgid "waiting for lock %s...\n"
-msgstr "очікування на блокування %s…\n"
-
 msgid "set debugging flags"
 msgstr "встановити прапорці діагностики"
 
@@ -5557,6 +5459,9 @@ msgstr "відповідь не містить основи числення RSA
 msgid "response does not contain the RSA public exponent\n"
 msgstr "відповідь не містить відкритого показника RSA\n"
 
+msgid "response does not contain the EC public point\n"
+msgstr "відповідь не містить відкритої точки еліптичної кривої\n"
+
 #, c-format
 msgid "using default PIN as %s\n"
 msgstr "використовуємо типовий пінкод як %s\n"
@@ -5736,17 +5641,17 @@ msgstr "заборонити використання команд з адмін
 msgid "use variable length input for pinpad"
 msgstr "використовувати змінну довжину вхідних даних для зчитувача"
 
-msgid "Usage: scdaemon [options] (-h for help)"
-msgstr "Використання: scdaemon [параметри] (-h — довідка)"
+msgid "Usage: @SCDAEMON@ [options] (-h for help)"
+msgstr "Використання: @SCDAEMON@ [параметри] (-h — довідка)"
 
 msgid ""
 "Syntax: scdaemon [options] [command [args]]\n"
-"Smartcard daemon for GnuPG\n"
+"Smartcard daemon for @GNUPG@\n"
 msgstr ""
 "Синтаксис: scdaemon [параметри] [команди [аргументи]]\n"
-"Фонова служба карток пам’яті для GnuPG\n"
+"Фонова служба карток пам’яті для @GNUPG@\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 "будь ласка, скористайтеся параметром «--daemon» для запуску програми у "
 "фоновому режимі\n"
@@ -5764,34 +5669,14 @@ msgid "invalid radix64 character %02x skipped\n"
 msgstr "пропущено некоректний символ radix64 %02x\n"
 
 #, c-format
-msgid "failed to proxy %s inquiry to client\n"
-msgstr "не Ð²Ð´Ð°Ð»Ð¾Ñ\81Ñ\8f Ð¿Ñ\80опÑ\83Ñ\81Ñ\82иÑ\82и Ñ\87еÑ\80ез Ð¿Ñ\80окÑ\81Ñ\96 Ð·Ð°Ð¿Ð¸Ñ\82 %s Ð´Ð¾ ÐºÐ»Ñ\96Ñ\94нÑ\82а\n"
+msgid "validation model requested by certificate: %s"
+msgstr "моделÑ\8c Ð¿ÐµÑ\80евÑ\96Ñ\80ки, Ð·Ð°Ð¿Ð¸Ñ\82ана Ñ\81еÑ\80Ñ\82иÑ\84Ñ\96каÑ\82ом: %s"
 
-#, c-format
-msgid "no running dirmngr - starting `%s'\n"
-msgstr "dirmngr не запущено — запускаємо «%s»\n"
+msgid "chain"
+msgstr "ланцюжок"
 
-msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "помилкове форматування змінної середовища DIRMNGR_INFO\n"
-
-#, c-format
-msgid "dirmngr protocol version %d is not supported\n"
-msgstr "підтримки протоколу dirmngr версії %d не передбачено\n"
-
-msgid "can't connect to the dirmngr - trying fall back\n"
-msgstr ""
-"не вдалося встановити з’єднання з dirmngr — намагаємося скористатися "
-"резервним\n"
-
-#, c-format
-msgid "validation model requested by certificate: %s"
-msgstr "модель перевірки, запитана сертифікатом: %s"
-
-msgid "chain"
-msgstr "ланцюжок"
-
-msgid "shell"
-msgstr "оболонка"
+msgid "shell"
+msgstr "оболонка"
 
 #, c-format
 msgid "critical certificate extension %s is not supported"
@@ -5804,10 +5689,12 @@ msgid "critical marked policy without configured policies"
 msgstr "правила, позначені як критичні, без налаштування"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "не вдалося відкрити «%s»: %s\n"
 
-msgid "note: non-critical certificate policy not allowed"
+#, fuzzy
+#| msgid "note: non-critical certificate policy not allowed"
+msgid "Note: non-critical certificate policy not allowed"
 msgstr "зауваження: заборонено некритичні правила сертифікації"
 
 msgid "certificate policy not allowed"
@@ -5961,10 +5848,6 @@ msgid "validation model used: %s"
 msgstr "використана модель перевірки: %s"
 
 #, c-format
-msgid "%s key uses an unsafe (%u bit) hash\n"
-msgstr "Ключ %s використовує недостатньо міцний (%u-бітовий) хеш\n"
-
-#, c-format
 msgid "a %u bit hash is not valid for a %u bit %s key\n"
 msgstr "%u-бітовий хеш не є коректним для %u-бітового ключа %s\n"
 
@@ -6039,11 +5922,11 @@ msgid "line %d: no subject name given\n"
 msgstr "рядок %d: не вказано назви призначення\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr "рядок %d: некоректна мітка назви призначення «%.*s»\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr "рядок %d: некоректна назва призначення «%s» на позиції %d\n"
 
 #, c-format
@@ -6051,11 +5934,49 @@ msgid "line %d: not a valid email address\n"
 msgstr "рядок %d: некоректна адреса електронної пошти\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: invalid serial number\n"
+msgstr "рядок %d: некоректний серійний номер\n"
+
+#, c-format
+msgid "line %d: invalid issuer name label '%.*s'\n"
+msgstr "рядок %d: некоректна мітка назви видавця «%.*s»\n"
+
+#, c-format
+msgid "line %d: invalid issuer name '%s' at pos %d\n"
+msgstr "рядок %d: некоректна назва видавця «%s» на позиції %d\n"
+
+#, c-format
+msgid "line %d: invalid date given\n"
+msgstr "рядок %d: вказано некоректну дату\n"
+
+#, c-format
+msgid "line %d: error getting signing key by keygrip '%s': %s\n"
+msgstr ""
+"рядок %d: помилка під час спроби отримання ключа підписування за допомогою "
+"keygrip «%s»: %s\n"
+
+#, c-format
+msgid "line %d: invalid hash algorithm given\n"
+msgstr "рядок %d: вказано некоректний алгоритм хешування\n"
+
+#, c-format
+msgid "line %d: invalid authority-key-id\n"
+msgstr "рядок %d: некоректний authority-key-id\n"
+
+#, c-format
+msgid "line %d: invalid subject-key-id\n"
+msgstr "рядок %d: некоректне значення subject-key-id\n"
+
+#, c-format
+msgid "line %d: invalid extension syntax\n"
+msgstr "рядок %d: некоректний синтаксис розширення\n"
+
+#, c-format
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "рядок %d: помилка читання ключа «%s» з картки: %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr ""
 "рядок %d: помилка під час отримання ключа за допомогою keygrip «%s»: %s\n"
 
@@ -6082,15 +6003,6 @@ msgstr "   (%d) Вже записаний ключ\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Вже записаний ключ з картки\n"
 
-msgid "Enter the keygrip: "
-msgstr "Вкажіть keygrip: "
-
-msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "Некоректний keygrip (мало бути вказано 40 шістнадцяткових цифр)\n"
-
-msgid "No key with this keygrip\n"
-msgstr "Немає ключів з таким значенням keygrip\n"
-
 #, c-format
 msgid "error reading the card: %s\n"
 msgstr "помилка читання картки: %s\n"
@@ -6125,7 +6037,7 @@ msgid "No subject name given\n"
 msgstr "Не вказано назви призначення\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr "Некоректна мітка назви призначення «%.*s»\n"
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6134,7 +6046,7 @@ msgstr "Некоректна мітка назви призначення «%.*s
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "Некор. назва призн. «%s»\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6155,12 +6067,23 @@ msgstr " (необов’язковий; завершується порожні
 msgid "Enter URIs"
 msgstr "Вкажіть адреси"
 
-msgid "Parameters to be used for the certificate request:\n"
-msgstr "Ð\9fаÑ\80амеÑ\82Ñ\80и, Ñ\8fкÑ\96 Ð±Ñ\83де Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82ано Ð´Ð»Ñ\8f Ð·Ð°Ð¿Ð¸Ñ\82Ñ\83 Ñ\81еÑ\80Ñ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\97:\n"
+msgid "Create self-signed certificate? (y/N) "
+msgstr "СÑ\82воÑ\80иÑ\82и Ñ\81амопÑ\96дпиÑ\81аний Ñ\81еÑ\80Ñ\82иÑ\84Ñ\96каÑ\82? (y/N Ð°Ð±Ð¾ Ñ\82\9d"
 
-msgid "Now creating certificate request.  This may take a while ...\n"
-msgstr ""
-"Створюємо запит щодо сертифікації. Його обробка триватиме певний час…\n"
+msgid "These parameters are used:\n"
+msgstr "Використано ці параметри:\n"
+
+msgid "Now creating self-signed certificate.  "
+msgstr "Створюємо самопідписаний сертифікат.  "
+
+msgid "Now creating certificate request.  "
+msgstr "Створюємо запит щодо сертифікації.  "
+
+msgid "This may take a while ...\n"
+msgstr "Зачекайте...\n"
+
+msgid "Ready.\n"
+msgstr "Виконано.\n"
 
 msgid "Ready.  You should now send this request to your CA.\n"
 msgstr ""
@@ -6177,7 +6100,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(здається, це не зашифроване повідомлення)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "сертифіката «%s» не знайдено: %s\n"
 
 #, c-format
@@ -6185,11 +6108,11 @@ msgid "error locking keybox: %s\n"
 msgstr "помилка під час блокування сховища ключів: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "вилучено дублікат сертифіката «%s»\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "сертифікат «%s» вилучено\n"
 
 #, c-format
@@ -6232,9 +6155,6 @@ msgstr "вважати вхідні дані даними у форматі BASE
 msgid "assume input is in binary format"
 msgstr "вважати вхідні дані даними у двійковому форматі"
 
-msgid "use system's dirmngr if available"
-msgstr "використовувати доступний системний dirmngr"
-
 msgid "never consult a CRL"
 msgstr "не використовувати САС"
 
@@ -6289,28 +6209,25 @@ msgstr ""
 "|NAME|використовувати вказаний алгоритм обчислення контрольної суми "
 "повідомлення"
 
-msgid "Usage: gpgsm [options] [files] (-h for help)"
-msgstr "Використання: gpgsm [параметри] [файли] (-h — довідка)"
+msgid "Usage: @GPGSM@ [options] [files] (-h for help)"
+msgstr "Використання: @GPGSM@ [параметри] [файли] (-h — довідка)"
 
 msgid ""
-"Syntax: gpgsm [options] [files]\n"
+"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 ""
-"Синтаксис: gpgsm [параметри] [файли]\n"
+"Синтаксис: @GPGSM@ [параметри] [файли]\n"
 "Підписування, перевірка підписів, шифрування або розшифрування за допомогою "
 "протоколу S/MIME\n"
 "Типова дія залежатиме від вхідних даних\n"
 
-msgid "usage: gpgsm [options] "
-msgstr "використання: gpgsm [параметри] "
-
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "Note: won't be able to encrypt to '%s': %s\n"
 msgstr "ЗАУВАЖЕННЯ: не вдасться зашифрувати до «%s»: %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "невідома модель перевірки «%s»\n"
 
 #, c-format
@@ -6328,15 +6245,12 @@ msgstr "%s:%u: пропускаємо цей рядок\n"
 msgid "could not parse keyserver\n"
 msgstr "не вдалося обробити сервер ключів\n"
 
-msgid "WARNING: running with faked system time: "
-msgstr "УВАГА: запущено з фіктивним системним часом: "
-
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "імпортуємо загальні сертифікати «%s»\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "підписування за допомогою «%s» неможливе: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6364,14 +6278,6 @@ msgstr "помилка під час спроби імпортування се
 msgid "error reading input: %s\n"
 msgstr "помилка під час спроби читання вхідних даних: %s\n"
 
-#, c-format
-msgid "error creating keybox `%s': %s\n"
-msgstr "помилка під час спроби створення сховища ключів «%s»: %s\n"
-
-#, c-format
-msgid "keybox `%s' created\n"
-msgstr "створено сховище ключів «%s»\n"
-
 msgid "failed to get the fingerprint\n"
 msgstr "не вдалося отримати відбиток\n"
 
@@ -6403,11 +6309,11 @@ msgstr ""
 "GPG_TTY не встановлено — можливе використання підробного типового значення\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "некоректне форматування відбитка у «%s», рядок %d\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr "некоректний код країни у «%s», рядок %d\n"
 
 #, c-format
@@ -6481,234 +6387,1470 @@ msgstr "                або"
 msgid "This is a qualified signature\n"
 msgstr "Це якісний підпис\n"
 
-msgid "quiet"
-msgstr "без повідомлень"
-
-msgid "print data out hex encoded"
-msgstr "вивести дані у шістнадцятковому форматі"
-
-msgid "decode received data lines"
-msgstr "декодувати отримані рядки даних"
+#, c-format
+msgid "can't initialize certificate cache lock: %s\n"
+msgstr "не вдалося ініціалізувати блокування кешу сертифікатів: %s\n"
 
-msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|NAME|встановити з’єднання з вказаним сокетом Assuan"
+#, c-format
+msgid "can't acquire read lock on the certificate cache: %s\n"
+msgstr "не вдалося заблокувати для читання кеш сертифікатів: %s\n"
 
-msgid "run the Assuan server given on the command line"
-msgstr "запустити сервер Assuan, вказаний у командному рядку"
+#, c-format
+msgid "can't acquire write lock on the certificate cache: %s\n"
+msgstr "не вдалося заблокувати для запису кеш сертифікатів: %s\n"
 
-msgid "do not use extended connect mode"
-msgstr "не використовувати розширений режим з’єднання"
+#, c-format
+msgid "can't release lock on the certificate cache: %s\n"
+msgstr "не вдалося зняти блокування з кешу сертифікатів: %s\n"
 
-msgid "|FILE|run commands from FILE on startup"
-msgstr "|FILE|виконати команди з вказаного файла під час запуску"
+#, c-format
+msgid "dropping %u certificates from the cache\n"
+msgstr "викидання %u сертифікатів з кешу\n"
 
-msgid "run /subst on startup"
-msgstr "виконати /subst під час запуску"
+#, c-format
+msgid "can't access directory '%s': %s\n"
+msgstr "не вдалося отримати доступ до каталогу «%s»: %s\n"
 
-msgid "Usage: gpg-connect-agent [options] (-h for help)"
-msgstr "Використання: gpg-connect-agent [параметри] (-h — довідка)"
+#, c-format
+msgid "can't parse certificate '%s': %s\n"
+msgstr "не вдалося обробити сертифікат «%s»: %s\n"
 
-msgid ""
-"Syntax: gpg-connect-agent [options]\n"
-"Connect to a running agent and send commands\n"
-msgstr ""
-"Синтаксис: gpg-connect-agent [параметри]\n"
-"Встановити з’єднання з запущеним агентом і надіслати команди\n"
+#, c-format
+msgid "certificate '%s' already cached\n"
+msgstr "сертифікат «%s» вже кешовано\n"
 
 #, c-format
-msgid "option \"%s\" requires a program and optional arguments\n"
-msgstr ""
-"щоб скористатися параметром «%s», слід вказати програму та додаткові "
-"аргументи\n"
+msgid "trusted certificate '%s' loaded\n"
+msgstr "надійний сертифікат «%s» завантажено\n"
 
 #, c-format
-msgid "option \"%s\" ignored due to \"%s\"\n"
-msgstr "параметр «%s» проігноровано через «%s»\n"
+msgid "certificate '%s' loaded\n"
+msgstr "сертифікат «%s» завантажено\n"
 
 #, c-format
-msgid "receiving line failed: %s\n"
-msgstr "помилка під час спроби отримання рядка: %s\n"
+msgid "  SHA1 fingerprint = %s\n"
+msgstr "  відбиток SHA1 = %s\n"
 
-msgid "line too long - skipped\n"
-msgstr "рядок є надто довгим, його пропущено\n"
+msgid "   issuer ="
+msgstr "   видавець ="
 
-msgid "line shortened due to embedded Nul character\n"
-msgstr "рядок скорочено через вбудований символ Nul\n"
+msgid "  subject ="
+msgstr "  призначення ="
 
 #, c-format
-msgid "unknown command `%s'\n"
-msgstr "невÑ\96дома ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° Â«%s»\n"
+msgid "error loading certificate '%s': %s\n"
+msgstr "помилка Ð¿Ñ\96д Ñ\87аÑ\81 Ñ\81пÑ\80оби Ð·Ð°Ð²Ð°Ð½Ñ\82аженнÑ\8f Ñ\81еÑ\80Ñ\82иÑ\84Ñ\96каÑ\82а Â«%s»: %s\n"
 
 #, c-format
-msgid "sending line failed: %s\n"
-msgstr "помилка Ð½Ð°Ð´Ñ\81иланнÑ\8f Ñ\80Ñ\8fдка: %s\n"
+msgid "permanently loaded certificates: %u\n"
+msgstr "оÑ\81Ñ\82аÑ\82оÑ\87но Ð·Ð°Ð²Ð°Ð½Ñ\82аженÑ\96 Ñ\81еÑ\80Ñ\82иÑ\84Ñ\96каÑ\82и: %u\n"
 
 #, c-format
-msgid "error sending %s command: %s\n"
-msgstr "помилка під час спроби надсилання команди %s: %s\n"
+msgid "    runtime cached certificates: %u\n"
+msgstr "    динамічно кешовані сертифікати: %u\n"
+
+msgid "certificate already cached\n"
+msgstr "сертифікат вже кешовано\n"
+
+msgid "certificate cached\n"
+msgstr "сертифікат кешовано\n"
 
 #, c-format
-msgid "error sending standard options: %s\n"
-msgstr "помилка Ð¿Ñ\96д Ñ\87аÑ\81 Ñ\81пÑ\80оби Ð½Ð°Ð´Ñ\81иланнÑ\8f Ñ\81Ñ\82андаÑ\80Ñ\82ниÑ\85 Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\96в: %s\n"
+msgid "error caching certificate: %s\n"
+msgstr "помилка Ð¿Ñ\96д Ñ\87аÑ\81 Ñ\81пÑ\80оби ÐºÐµÑ\88Ñ\83ваннÑ\8f Ñ\81еÑ\80Ñ\82иÑ\84Ñ\96каÑ\82а: %s\n"
 
-msgid "Options controlling the diagnostic output"
-msgstr "Параметри керування діагностичним виводом"
+#, c-format
+msgid "invalid SHA1 fingerprint string '%s'\n"
+msgstr "некоректний рядок відбитка SHA1 «%s»\n"
 
-msgid "Options controlling the configuration"
-msgstr "Параметри керування налаштуваннями"
+#, c-format
+msgid "error fetching certificate by S/N: %s\n"
+msgstr "помилка під час спроби отримання сертифіката за серійним номером: %s\n"
 
-msgid "Options useful for debugging"
-msgstr "Параметри діагностики"
+#, c-format
+msgid "error fetching certificate by subject: %s\n"
+msgstr "помилка під час спроби отримання сертифіката за призначенням: %s\n"
 
-msgid "|FILE|write server mode logs to FILE"
-msgstr "|FILE|записувати журнал режиму сервера до файла"
+msgid "no issuer found in certificate\n"
+msgstr "у сертифікаті не виявлено запису видавця\n"
 
-msgid "Options controlling the security"
-msgstr "Параметри керування захистом"
+#, c-format
+msgid "error getting authorityKeyIdentifier: %s\n"
+msgstr "помилка під час спроби отримання authorityKeyIdentifier: %s\n"
 
-msgid "|N|expire SSH keys after N seconds"
-msgstr "|N|завершувати строк дії ключів SSH за N секунд"
+#, c-format
+msgid "creating directory '%s'\n"
+msgstr "створення каталогу «%s»\n"
 
-msgid "|N|set maximum PIN cache lifetime to N seconds"
-msgstr "|N|встановити максимальний строк дії кешу пінкодів у секундах"
+#, c-format
+msgid "error creating directory '%s': %s\n"
+msgstr "помилка під час спроби створення каталогу «%s»: %s\n"
 
-msgid "|N|set maximum SSH key lifetime to N seconds"
-msgstr "|N|встановити максимальний строк дії ключа SSH у секундах"
+#, c-format
+msgid "ignoring database dir '%s'\n"
+msgstr "ігноруємо каталог бази даних «%s»\n"
 
-msgid "Options enforcing a passphrase policy"
-msgstr "Параметри примусового використання правил паролів"
+#, c-format
+msgid "error reading directory '%s': %s\n"
+msgstr "помилка під час спроби читання каталогу «%s»: %s\n"
 
-msgid "do not allow to bypass the passphrase policy"
-msgstr "не дозволяти обхід правил паролів"
+#, c-format
+msgid "removing cache file '%s'\n"
+msgstr "вилучаємо файл кешу «%s»\n"
 
-msgid "|N|set minimal required length for new passphrases to N"
-msgstr "|N|встановити вказану мінімальну довжину нових паролів"
+#, c-format
+msgid "not removing file '%s'\n"
+msgstr "не вилучаємо файл «%s»\n"
 
-msgid "|N|require at least N non-alpha characters for a new passphrase"
-msgstr "|N|вимагати у нових паролях не менше вказаної кількості нелітер"
+#, c-format
+msgid "error closing cache file: %s\n"
+msgstr "помилка під час спроби закриття файла кешу: %s\n"
 
-msgid "|FILE|check new passphrases against pattern in FILE"
-msgstr "|FILE|перевіряти нові паролі за зразком з вказаного файла"
+#, c-format
+msgid "failed to open cache dir file '%s': %s\n"
+msgstr "не вдалося відкрити файл каталогу кешу «%s»: %s\n"
 
-msgid "|N|expire the passphrase after N days"
-msgstr "|N|завершувати строк дії паролів за вказану кількість днів"
+#, c-format
+msgid "error creating new cache dir file '%s': %s\n"
+msgstr "помилка під час спроби створення нового файла каталогу кешу «%s»: %s\n"
 
-msgid "do not allow the reuse of old passphrases"
-msgstr "не дозволяти повторне використання старих паролів"
+#, c-format
+msgid "error writing new cache dir file '%s': %s\n"
+msgstr "помилка під час спроби запису нового файла каталогу кешу «%s»: %s\n"
 
-msgid "|NAME|use NAME as default secret key"
-msgstr "|NAME|використовувати вказаний типовий закритий ключ"
+#, c-format
+msgid "error closing new cache dir file '%s': %s\n"
+msgstr "помилка під час спроби закриття нового файла каталогу кешу «%s»: %s\n"
 
-msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|NAME|шифрувати також до вказаного ідентифікатора користувача"
+#, c-format
+msgid "new cache dir file '%s' created\n"
+msgstr "створено новий файл каталогу кешу «%s»\n"
 
-msgid "|SPEC|set up email aliases"
-msgstr "|SPEC|встановити замінники адреси електронної пошти"
+#, c-format
+msgid "failed to re-open cache dir file '%s': %s\n"
+msgstr "не вдалося повторно відкрити файл каталогу кешу «%s»: %s\n"
 
-msgid "Configuration for Keyservers"
-msgstr "Налаштування для серверів ключів"
+#, c-format
+msgid "first record of '%s' is not the version\n"
+msgstr "першим записом «%s» не є версія\n"
 
-msgid "|URL|use keyserver at URL"
-msgstr "|URL|використовувати сервер ключів за адресою"
+msgid "old version of cache directory - cleaning up\n"
+msgstr "застаріла версія каталогу кешу — спорожнюємо\n"
 
-msgid "allow PKA lookups (DNS requests)"
-msgstr "дозволиÑ\82и Ð¿Ð¾Ñ\88Ñ\83к PKA (запиÑ\82и Ð´Ð¾ DNS)"
+msgid "old version of cache directory - giving up\n"
+msgstr "заÑ\81Ñ\82аÑ\80Ñ\96ла Ð²ÐµÑ\80Ñ\81Ñ\96Ñ\8f ÐºÐ°Ñ\82алогÑ\83 ÐºÐµÑ\88Ñ\83 â\80\94 Ð¿Ñ\80опÑ\83Ñ\81каÑ\94мо\n"
 
-msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
-msgstr ""
-"|MECHANISMS|використовувати вказаний механізм для пошуку ключів за адресою"
+#, c-format
+msgid "extra field detected in crl record of '%s' line %u\n"
+msgstr "виявлено зайве поле у записі CRL «%s», рядок %u\n"
 
-msgid "disable all access to the dirmngr"
-msgstr "заборонити доступ до dirmngr"
+#, c-format
+msgid "invalid line detected in '%s' line %u\n"
+msgstr "виявлено некоректний рядок у «%s», рядок %u\n"
 
-msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr "використовувати вказане кодування для паролів PKCS#12"
+#, c-format
+msgid "duplicate entry detected in '%s' line %u\n"
+msgstr "виявлено дублікат запису у «%s», рядок %u\n"
 
-msgid "do not check CRLs for root certificates"
-msgstr "не шукати у списках відкликаних сертифікатів кореневі сертифікати"
+#, c-format
+msgid "unsupported record type in '%s' line %u skipped\n"
+msgstr "непідтримуваний тип запису у «%s», рядок %u пропущено\n"
 
-msgid "Options controlling the format of the output"
-msgstr "Параметри керування форматом виведення"
+#, c-format
+msgid "invalid issuer hash in '%s' line %u\n"
+msgstr "некоректний хеш видавця у «%s», рядок %u\n"
 
-msgid "Options controlling the interactivity and enforcement"
-msgstr "Параметри керування інтерактивністю та примусом"
+#, c-format
+msgid "no issuer DN in '%s' line %u\n"
+msgstr "немає DN видавця «%s», рядок %u\n"
 
-msgid "Configuration for HTTP servers"
-msgstr "Налаштування для серверів HTTP"
+#, c-format
+msgid "invalid timestamp in '%s' line %u\n"
+msgstr "некоректна позначка часу у «%s», рядок %u\n"
 
-msgid "use system's HTTP proxy setting"
-msgstr "використовувати загальносистемний проксі-сервер HTTP"
+#, c-format
+msgid "WARNING: invalid cache file hash in '%s' line %u\n"
+msgstr "УВАГА: некоректний хеш файла кешу у «%s», рядок %u\n"
 
-msgid "Configuration of LDAP servers to use"
-msgstr "Ð\9dалаÑ\88Ñ\82Ñ\83ваннÑ\8f Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82аннÑ\8f Ñ\81еÑ\80веÑ\80Ñ\96в LDAP"
+msgid "detected errors in cache dir file\n"
+msgstr "виÑ\8fвлено Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ñ\83 Ñ\84айлÑ\96 ÐºÐ°Ñ\82алогÑ\83 ÐºÐµÑ\88Ñ\83\n"
 
-msgid "LDAP server list"
-msgstr "список серверів LDAP"
+msgid "please check the reason and manually delete that file\n"
+msgstr "будь ласка, перевірте причину і вилучіть цей файл вручну\n"
 
-msgid "Configuration for OCSP"
-msgstr "Налаштування OCSP"
+#, c-format
+msgid "failed to create temporary cache dir file '%s': %s\n"
+msgstr "не вдалося створити тимчасовий файл каталогу кешу «%s»: %s\n"
 
 #, c-format
-msgid "External verification of component %s failed"
-msgstr "Ð\9fомилка Ð·Ð¾Ð²Ð½Ñ\96Ñ\88нÑ\8cоÑ\97 Ð¿ÐµÑ\80евÑ\96Ñ\80ки ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ\82а %s"
+msgid "error closing '%s': %s\n"
+msgstr "помилка Ð¿Ñ\96д Ñ\87аÑ\81 Ñ\81пÑ\80оби Ð·Ð°ÐºÑ\80иÑ\82и Â«%s»: %s\n"
 
-msgid "Note that group specifications are ignored\n"
-msgstr "Зауважте, що специфікації груп буде проігноровано\n"
+#, c-format
+msgid "error renaming '%s' to '%s': %s\n"
+msgstr "помилка під час спроби перейменування «%s» на «%s»: %s\n"
 
-msgid "list all components"
-msgstr "показати список всіх компонентів"
+#, c-format
+msgid "can't hash '%s': %s\n"
+msgstr "не вдалося хешувати «%s»: %s\n"
 
-msgid "check all programs"
-msgstr "перевірити всі програми"
+#, c-format
+msgid "error setting up MD5 hash context: %s\n"
+msgstr "помилка під час спроби встановлення контексту хешування MD5: %s\n"
 
-msgid "|COMPONENT|list options"
-msgstr "|COMPONENT|показати список параметрів"
+#, c-format
+msgid "error hashing '%s': %s\n"
+msgstr "помилка під час спроби хешування «%s»: %s\n"
 
-msgid "|COMPONENT|change options"
-msgstr "|COMPONENT|змінити параметри"
+#, c-format
+msgid "invalid formatted checksum for '%s'\n"
+msgstr "некоректне форматування контрольної суми для «%s»\n"
 
-msgid "|COMPONENT|check options"
-msgstr "|COMPONENT|перевірити параметри"
+msgid "too many open cache files; can't open anymore\n"
+msgstr "забагато відкритих файлів кешу; більше файлів відкрити не можна\n"
 
-msgid "apply global default values"
-msgstr "застосувати загальні типові значення"
+#, c-format
+msgid "opening cache file '%s'\n"
+msgstr "відкриваємо файл кешу «%s»\n"
 
-msgid "get the configuration directories for gpgconf"
-msgstr "отримати назви каталогів налаштувань для gpgconf"
+#, c-format
+msgid "error opening cache file '%s': %s\n"
+msgstr "помилка під час спроби відкриття файла кешу «%s»: %s\n"
 
-msgid "list global configuration file"
-msgstr "показати загальний файл налаштувань"
+#, c-format
+msgid "error initializing cache file '%s' for reading: %s\n"
+msgstr "помилка під час спроби ініціалізації файла кешу «%s» для читання: %s\n"
 
-msgid "check global configuration file"
-msgstr "пеÑ\80евÑ\96Ñ\80иÑ\82и Ð·Ð°Ð³Ð°Ð»Ñ\8cний Ñ\84айл Ð½Ð°Ð»Ð°Ñ\88Ñ\82Ñ\83ванÑ\8c"
+msgid "calling unlock_db_file on a closed file\n"
+msgstr "виклик unlock_db_file Ð´Ð»Ñ\8f Ð·Ð°ÐºÑ\80иÑ\82ого Ñ\84айла\n"
 
-msgid "use as output file"
-msgstr "викоÑ\80иÑ\81Ñ\82аÑ\82и Ñ\84айл Ð´Ð»Ñ\8f Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ\8f Ð´Ð°Ð½Ð¸Ñ\85"
+msgid "calling unlock_db_file on an unlocked file\n"
+msgstr "виклик unlock_db_file Ð´Ð»Ñ\8f Ñ\80озблокованого Ñ\84айла\n"
 
-msgid "activate changes at runtime, if possible"
-msgstr "якщо можна, задіяти зміни у динамічному режимі"
+#, c-format
+msgid "failed to create a new cache object: %s\n"
+msgstr "не вдалося створити об’єкт кешування: %s\n"
 
-msgid "Usage: gpgconf [options] (-h for help)"
-msgstr "Використання: gpgconf [параметри] (-h — довідка)"
+#, c-format
+msgid "no CRL available for issuer id %s\n"
+msgstr "немає CRL для ідентифікатора видавця %s\n"
+
+#, c-format
+msgid "cached CRL for issuer id %s too old; update required\n"
+msgstr ""
+"кешований CRL для ідентифікатора видавця %s є занадто старим; потрібне "
+"оновлення\n"
 
+#, c-format
 msgid ""
-"Syntax: gpgconf [options]\n"
-"Manage configuration options for tools of the GnuPG system\n"
+"force-crl-refresh active and %d minutes passed for issuer id %s; update "
+"required\n"
 msgstr ""
-"СинÑ\82акÑ\81иÑ\81: gpgconf [паÑ\80амеÑ\82Ñ\80и]\n"
-"Ð\9aеÑ\80Ñ\83ваннÑ\8f Ð¿Ð°Ñ\80амеÑ\82Ñ\80ами Ð½Ð°Ð»Ð°Ñ\88Ñ\82Ñ\83ваннÑ\8f Ñ\96нÑ\81Ñ\82Ñ\80Ñ\83менÑ\82Ñ\96в Ñ\81иÑ\81Ñ\82еми GnuPG\n"
+"задÑ\96Ñ\8fно force-crl-refresh Ñ\96 %d Ñ\85вилин Ñ\82омÑ\83 Ð¿ÐµÑ\80едано Ð´Ð»Ñ\8f Ñ\96денÑ\82иÑ\84Ñ\96каÑ\82оÑ\80а "
+"видавÑ\86Ñ\8f %s; Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ\8f\n"
 
-msgid "usage: gpgconf [options] "
-msgstr "використання: gpgconf [параметри] "
+#, c-format
+msgid "force-crl-refresh active for issuer id %s; update required\n"
+msgstr ""
+"задіяно force-crl-refresh для ідентифікатора видавця %s; потрібне оновлення\n"
 
-msgid "Need one component argument"
-msgstr "Слід вказати один аргумент компонента"
+#, c-format
+msgid "available CRL for issuer ID %s can't be used\n"
+msgstr "доступний CRL для ідентифікатора видавця %s не може бути використано\n"
 
-msgid "Component not found"
-msgstr "Компонент не знайдено"
+#, c-format
+msgid "cached CRL for issuer id %s tampered; we need to update\n"
+msgstr ""
+"кешований CRL для ідентифікатора видавця %s підроблено; потрібне оновлення\n"
 
-msgid "No argument allowed"
-msgstr "Не можна вказувати аргументів"
+msgid "WARNING: invalid cache record length for S/N "
+msgstr "УВАГА: некоректна довжина запису кешу для серійного номера "
+
+#, c-format
+msgid "problem reading cache record for S/N %s: %s\n"
+msgstr ""
+"проблема під час спроби читання запису кешування для серійного номера %s: "
+"%s\n"
+
+#, c-format
+msgid "S/N %s is not valid; reason=%02X  date=%.15s\n"
+msgstr "серійний номер %s не є коректним; причина=%02X дата=%.15s\n"
+
+#, c-format
+msgid "S/N %s is valid, it is not listed in the CRL\n"
+msgstr "серійний номер %s є коректним, його немає у CRL\n"
+
+#, c-format
+msgid "error getting data from cache file: %s\n"
+msgstr "помилка під час спроби отримання даних з файла кешу: %s\n"
+
+#, c-format
+msgid "unknown hash algorithm '%s'\n"
+msgstr "невідомий алгоритм хешування «%s»\n"
+
+#, c-format
+msgid "gcry_md_open for algorithm %d failed: %s\n"
+msgstr "помилка використання gcry_md_open для алгоритму %d: %s\n"
+
+msgid "got an invalid S-expression from libksba\n"
+msgstr "отримано некоректний вираз S з libksba\n"
+
+#, c-format
+msgid "converting S-expression failed: %s\n"
+msgstr "спроба перетворення виразу S зазнала невдачі: %s\n"
+
+#, c-format
+msgid "creating S-expression failed: %s\n"
+msgstr "спроба створення виразу S зазнала невдачі: %s\n"
+
+#, c-format
+msgid "ksba_crl_parse failed: %s\n"
+msgstr "помилка ksba_crl_parse: %s\n"
+
+#, c-format
+msgid "error getting update times of CRL: %s\n"
+msgstr "помилка під час спроби отримання даних щодо часу оновлення з CRL: %s\n"
+
+#, c-format
+msgid "update times of this CRL: this=%s next=%s\n"
+msgstr "часи оновлення цього CRL: поточне=%s наступне=%s\n"
+
+msgid "nextUpdate not given; assuming a validity period of one day\n"
+msgstr "не вказано nextUpdate; вважаємо періодом чинності один день\n"
+
+#, c-format
+msgid "error getting CRL item: %s\n"
+msgstr "помилка під час спроби отримання запису CRL: %s\n"
+
+#, c-format
+msgid "error inserting item into temporary cache file: %s\n"
+msgstr ""
+"помилка під час спроби додавання пункту до файла тимчасового кешу: %s\n"
+
+#, c-format
+msgid "no CRL issuer found in CRL: %s\n"
+msgstr "не виявлено видавця CRL у CRL: %s\n"
+
+msgid "locating CRL issuer certificate by authorityKeyIdentifier\n"
+msgstr "пошук видавця CRL сертифіката за authorityKeyIdentifier\n"
+
+#, c-format
+msgid "CRL signature verification failed: %s\n"
+msgstr "помилка перевірки підпису CRL: %s\n"
+
+#, c-format
+msgid "error checking validity of CRL issuer certificate: %s\n"
+msgstr ""
+"помилка під час спроби перевірки чинності сертифіката видавця CRL: %s\n"
+
+#, c-format
+msgid "ksba_crl_new failed: %s\n"
+msgstr "помилка ksba_crl_new: %s\n"
+
+#, c-format
+msgid "ksba_crl_set_reader failed: %s\n"
+msgstr "помилка ksba_crl_set_reader: %s\n"
+
+#, c-format
+msgid "removed stale temporary cache file '%s'\n"
+msgstr "вилучено застарілий тимчасовий файл кешу «%s»\n"
+
+#, c-format
+msgid "problem removing stale temporary cache file '%s': %s\n"
+msgstr ""
+"помилка під час спроби вилучення застарілого тимчасового файла кешу «%s»: "
+"%s\n"
+
+#, c-format
+msgid "error creating temporary cache file '%s': %s\n"
+msgstr "помилка під час спроби створення тимчасового файла кешу «%s»: %s\n"
+
+#, c-format
+msgid "crl_parse_insert failed: %s\n"
+msgstr "помилка crl_parse_insert: %s\n"
+
+#, c-format
+msgid "error finishing temporary cache file '%s': %s\n"
+msgstr ""
+"помилка під час спроби завершення запису тимчасового файла кешу «%s»: %s\n"
+
+#, c-format
+msgid "error closing temporary cache file '%s': %s\n"
+msgstr "помилка під час спроби закриття тимчасового файла кешу «%s»: %s\n"
+
+#, c-format
+msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n"
+msgstr ""
+"УВАГА: новий CRL все ще занадто старий; його строк дії завершується %s — "
+"попри це завантажуємо\n"
+
+#, c-format
+msgid "new CRL still too old; it expired on %s\n"
+msgstr "новий CRL все ще занадто старий; його строк дії завершується %s\n"
+
+#, c-format
+msgid "unknown critical CRL extension %s\n"
+msgstr "невідомий критичний додаток CRL %s\n"
+
+#, c-format
+msgid "error reading CRL extensions: %s\n"
+msgstr "помилка під час читання додатків CRL: %s\n"
+
+#, c-format
+msgid "creating cache file '%s'\n"
+msgstr "створюємо файл кешу «%s»\n"
+
+#, c-format
+msgid "problem renaming '%s' to '%s': %s\n"
+msgstr "проблема під час перейменування «%s» на «%s»: %s\n"
+
+msgid ""
+"updating the DIR file failed - cache entry will get lost with the next "
+"program start\n"
+msgstr ""
+"помилка під час спроби оновлення файла каталогу — запис кешу буде втрачено "
+"під час наступного запуску програми\n"
+
+#, c-format
+msgid "Begin CRL dump (retrieved via %s)\n"
+msgstr "Початок дампу CRL (отримано за допомогою %s)\n"
+
+msgid ""
+" ERROR: The CRL will not be used because it was still too old after an "
+"update!\n"
+msgstr ""
+" ПОМИЛКА: CRL не буде використано, оскільки він все ще застарілий після "
+"оновлення!\n"
+
+msgid ""
+" ERROR: The CRL will not be used due to an unknown critical extension!\n"
+msgstr " ПОМИЛКА: CRL не буде використано через невідомий критичний додаток!\n"
+
+msgid " ERROR: The CRL will not be used\n"
+msgstr " ПОМИЛКА: CRL не буде використано\n"
+
+msgid " ERROR: This cached CRL may have been tampered with!\n"
+msgstr " ПОМИЛКА: цей кешований CRL можливо було підроблено!\n"
+
+msgid " WARNING: invalid cache record length\n"
+msgstr " УВАГА: некоректна довжина запису кешу\n"
+
+#, c-format
+msgid "problem reading cache record: %s\n"
+msgstr "проблема під час читання запису кешу: %s\n"
+
+#, c-format
+msgid "problem reading cache key: %s\n"
+msgstr "проблема під час спроби читання ключа кешу: %s\n"
+
+#, c-format
+msgid "error reading cache entry from db: %s\n"
+msgstr "помилка під час спроби читання запису кешу з бази даних: %s\n"
+
+msgid "End CRL dump\n"
+msgstr "Кінець дампу CRL\n"
+
+#, c-format
+msgid "crl_fetch via DP failed: %s\n"
+msgstr "помилка crl_fetch за DP: %s\n"
+
+#, c-format
+msgid "crl_cache_insert via DP failed: %s\n"
+msgstr "помилка crl_cache_insert за DP: %s\n"
+
+#, c-format
+msgid "crl_cache_insert via issuer failed: %s\n"
+msgstr "помилка crl_cache_insert за видавцем: %s\n"
+
+msgid "reader to file mapping table full - waiting\n"
+msgstr "засіб читання до таблиці відповідності файлів переповнено — очікуємо\n"
+
+msgid "using \"http\" instead of \"https\"\n"
+msgstr "використовуємо «http» замість «https»\n"
+
+#, c-format
+msgid "CRL access not possible due to disabled %s\n"
+msgstr "Доступ до CRL неможливий через вимкнений %s\n"
+
+#, c-format
+msgid "error initializing reader object: %s\n"
+msgstr "помилка під час спроби ініціалізації об’єкта читання: %s\n"
+
+#, c-format
+msgid "URL '%s' redirected to '%s' (%u)\n"
+msgstr "Адресу «%s» переспрямовано до «%s» (%u)\n"
+
+msgid "too many redirections\n"
+msgstr "занадто багато переспрямувань\n"
+
+#, c-format
+msgid "error retrieving '%s': %s\n"
+msgstr "помилка отримання «%s»: %s\n"
+
+#, c-format
+msgid "error retrieving '%s': http status %u\n"
+msgstr "помилка отримання «%s»: стан http %u\n"
+
+#, c-format
+msgid "certificate search not possible due to disabled %s\n"
+msgstr "пошук сертифікатів неможливий через вимкнений %s\n"
+
+msgid "use OCSP instead of CRLs"
+msgstr "використовувати OCSP замість CRL"
+
+msgid "check whether a dirmngr is running"
+msgstr "перевірити, чи запущено dirmngr"
+
+msgid "add a certificate to the cache"
+msgstr "додати сертифікат до кешу"
+
+msgid "validate a certificate"
+msgstr "перевірити сертифікат"
+
+msgid "lookup a certificate"
+msgstr "шукати сертифікат"
+
+msgid "lookup only locally stored certificates"
+msgstr "шукати лише локально збережені сертифікати"
+
+msgid "expect an URL for --lookup"
+msgstr "очікувати адресу для --lookup"
+
+msgid "load a CRL into the dirmngr"
+msgstr "завантажити CRL до dirmngr"
+
+msgid "special mode for use by Squid"
+msgstr "особливий режим для використання Squid"
+
+msgid "expect certificates in PEM format"
+msgstr "сертифікати мало бути вказано у форматі PEM"
+
+msgid "force the use of the default OCSP responder"
+msgstr "примусово використовувати типовий відповідач OCSP"
+
+msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n"
+msgstr ""
+"Використання: dirmngr-client [параметри] [файл_сертифіката|шаблон] (-h — "
+"довідка)\n"
+
+msgid ""
+"Syntax: dirmngr-client [options] [certfile|pattern]\n"
+"Test an X.509 certificate against a CRL or do an OCSP check\n"
+"The process returns 0 if the certificate is valid, 1 if it is\n"
+"not valid and other error codes for general failures\n"
+msgstr ""
+"Синтаксис: dirmngr-client [параметри] [файл_сертифіката|шаблон]\n"
+"Перевірити сертифікат X.509 за CRL або виконати перевірку OCSP.\n"
+"Процес повертає 0, якщо сертифікат є коректним, 1 якщо він не є\n"
+"коректним, інші коди для загальних помилок.\n"
+
+#, c-format
+msgid "error reading certificate from stdin: %s\n"
+msgstr "помилка під час спроби читання сертифіката з stdin: %s\n"
+
+#, c-format
+msgid "error reading certificate from '%s': %s\n"
+msgstr "помилка під час спроби читання сертифіката з «%s»: %s\n"
+
+msgid "certificate too large to make any sense\n"
+msgstr "сертифікат занадто великий для використання\n"
+
+#, c-format
+msgid "lookup failed: %s\n"
+msgstr "помилка пошуку: %s\n"
+
+#, c-format
+msgid "loading CRL '%s' failed: %s\n"
+msgstr "спроба завантаження CRL «%s» завершилася невдало: %s\n"
+
+msgid "a dirmngr daemon is up and running\n"
+msgstr "фонову службу dirmngr запущено\n"
+
+#, c-format
+msgid "validation of certificate failed: %s\n"
+msgstr "не вдалося перевірити сертифікат: %s\n"
+
+msgid "certificate is valid\n"
+msgstr "сертифікат є коректним\n"
+
+msgid "certificate has been revoked\n"
+msgstr "сертифікат відкликано\n"
+
+#, c-format
+msgid "certificate check failed: %s\n"
+msgstr "помилка під час перевірки сертифіката: %s\n"
+
+#, c-format
+msgid "got status: '%s'\n"
+msgstr "отримано стан: «%s»\n"
+
+#, c-format
+msgid "error writing base64 encoding: %s\n"
+msgstr "помилка під час спроби запису у кодуванні base64: %s\n"
+
+#, c-format
+msgid "failed to allocate assuan context: %s\n"
+msgstr "не вдалося розмістити контекст assuan: %s\n"
+
+msgid "apparently no running dirmngr\n"
+msgstr "ймовірно, dirmngr не запущено\n"
+
+msgid "no running dirmngr - starting one\n"
+msgstr "dirmngr не запущено — запускаємо\n"
+
+#, c-format
+msgid "malformed %s environment variable\n"
+msgstr "помилкове форматування змінної середовища %s\n"
+
+#, c-format
+msgid "dirmngr protocol version %d is not supported\n"
+msgstr "підтримки протоколу dirmngr версії %d не передбачено\n"
+
+msgid "can't connect to the dirmngr - trying fall back\n"
+msgstr ""
+"не вдалося встановити з’єднання з dirmngr — намагаємося скористатися "
+"резервним\n"
+
+#, c-format
+msgid "can't connect to the dirmngr: %s\n"
+msgstr "не вдалося встановити з’єднання з dirmngr: %s\n"
+
+#, c-format
+msgid "unsupported inquiry '%s'\n"
+msgstr "непідтримуваний запит «%s»\n"
+
+msgid "absolute file name expected\n"
+msgstr "мало бути вказано абсолютний шлях до файла\n"
+
+#, c-format
+msgid "looking up '%s'\n"
+msgstr "пошук «%s»\n"
+
+msgid "run as windows service (background)"
+msgstr "запустити як службу windows (у фоновому режимі)"
+
+msgid "list the contents of the CRL cache"
+msgstr "показати вміст кешу CRL"
+
+msgid "|FILE|load CRL from FILE into cache"
+msgstr "|FILE|завантажити CRL з вказаного файла до кешу"
+
+msgid "|URL|fetch a CRL from URL"
+msgstr "|URL|отримати CRL з вказаної адреси"
+
+msgid "shutdown the dirmngr"
+msgstr "завершити роботу dirmngr"
+
+msgid "flush the cache"
+msgstr "спорожнити кеш"
+
+msgid "|FILE|write server mode logs to FILE"
+msgstr "|FILE|записувати журнал режиму сервера до файла"
+
+msgid "run without asking a user"
+msgstr "запустити без запиту до користувача"
+
+msgid "force loading of outdated CRLs"
+msgstr "примусове завантаження застарілих САС"
+
+msgid "allow sending OCSP requests"
+msgstr "дозволити надсилання запитів OCSP"
+
+msgid "inhibit the use of HTTP"
+msgstr "заборонити використання HTTP"
+
+msgid "inhibit the use of LDAP"
+msgstr "заборонити використання LDAP"
+
+msgid "ignore HTTP CRL distribution points"
+msgstr "ігнорувати точки поширення САС протоколу HTTP"
+
+msgid "ignore LDAP CRL distribution points"
+msgstr "ігнорувати точки поширення САС протоколу LDAP"
+
+msgid "ignore certificate contained OCSP service URLs"
+msgstr "ігнорувати адреси служб OCSP з сертифікатами"
+
+msgid "|URL|redirect all HTTP requests to URL"
+msgstr "|URL|переспрямувати всі запити HTTP на вказану адресу"
+
+msgid "|HOST|use HOST for LDAP queries"
+msgstr "|HOST|використовувати вказаний вузол для запитів LDAP"
+
+msgid "do not use fallback hosts with --ldap-proxy"
+msgstr "не використовувати резервні вузли з --ldap-proxy"
+
+msgid "|FILE|read LDAP server list from FILE"
+msgstr "|FILE|прочитати список серверів LDAP з вказаного файла"
+
+msgid "add new servers discovered in CRL distribution points to serverlist"
+msgstr "додати виявлені у точках поширення CRL нові сервери до списку серверів"
+
+msgid "|N|set LDAP timeout to N seconds"
+msgstr "|N|встановити вказаний час очікування даних від LDAP"
+
+msgid "|URL|use OCSP responder at URL"
+msgstr "|URL|використовувати відповідач OCSP за вказаною адресою"
+
+msgid "|FPR|OCSP response signed by FPR"
+msgstr "|FPR|відповідь OCSP підписано FPR"
+
+msgid "|N|do not return more than N items in one query"
+msgstr "|N|повертати не більше за вказану кількість записів на запит"
+
+msgid "|FILE|use the CA certificates in FILE for HKP over TLS"
+msgstr "|ФАЙЛ|використовувати сертифікати CA з файла ФАЙЛ для HKP крізь TLS"
+
+msgid ""
+"@\n"
+"(See the \"info\" manual for a complete listing of all commands and "
+"options)\n"
+msgstr ""
+"@\n"
+"(Щоб ознайомитися зі списком команд і параметрів, скористайтеся сторінкою "
+"довідника (man) «info»)\n"
+
+msgid "Usage: @DIRMNGR@ [options] (-h for help)"
+msgstr "Використання: @DIRMNGR@ [параметри] (-h — довідка)"
+
+#, fuzzy
+#| msgid ""
+#| "Syntax: @DIRMNGR@ [options] [command [args]]\n"
+#| "LDAP and OCSP access for @GNUPG@\n"
+msgid ""
+"Syntax: @DIRMNGR@ [options] [command [args]]\n"
+"Keyserver, CRL, and OCSP access for @GNUPG@\n"
+msgstr ""
+"Синтаксис: @DIRMNGR@ [параметри] [команда [аргументи]]\n"
+"Доступ до LDAP і OCSP для @GNUPG@\n"
+
+#, c-format
+msgid "valid debug levels are: %s\n"
+msgstr "коректними рівнями зневаджування є: %s\n"
+
+#, c-format
+msgid "usage: %s [options] "
+msgstr "використання: %s [параметри]"
+
+msgid "colons are not allowed in the socket name\n"
+msgstr "не можна використовувати двокрапки у назві сокета\n"
+
+#, c-format
+msgid "fetching CRL from '%s' failed: %s\n"
+msgstr "помилка під час спроби отримання CRL з «%s»: %s\n"
+
+#, c-format
+msgid "processing CRL from '%s' failed: %s\n"
+msgstr "помилка під час обробки CRL з «%s»: %s\n"
+
+#, c-format
+msgid "%s:%u: line too long - skipped\n"
+msgstr "%s:%u: занадто довгий рядок — пропущено\n"
+
+#, c-format
+msgid "%s:%u: invalid fingerprint detected\n"
+msgstr "%s:%u: виявлено некоректний відбиток\n"
+
+#, c-format
+msgid "%s:%u: read error: %s\n"
+msgstr "%s:%u: помилка під час читання: %s\n"
+
+#, c-format
+msgid "%s:%u: garbage at end of line ignored\n"
+msgstr "%s:%u: беззмістовні дані наприкінці рядка проігноровано\n"
+
+msgid "SIGHUP received - re-reading configuration and flushing caches\n"
+msgstr ""
+"отримано сигнал SIGHUP — повторне читання налаштувань та спорожнення кешу\n"
+
+msgid "SIGUSR2 received - no action defined\n"
+msgstr "отримано сигнал SIGUSR2 — дій не визначено\n"
+
+msgid "SIGTERM received - shutting down ...\n"
+msgstr "отримано сигнал SIGTERM — завершуємо роботу…\n"
+
+#, c-format
+msgid "SIGTERM received - still %d active connections\n"
+msgstr "отримано сигнал SIGTERM — підтримується %d активних з’єднань\n"
+
+msgid "shutdown forced\n"
+msgstr "примусове завершення роботи\n"
+
+msgid "SIGINT received - immediate shutdown\n"
+msgstr "отримано сигнал SIGINT — негайне завершення роботи\n"
+
+#, c-format
+msgid "signal %d received - no action defined\n"
+msgstr "отримано сигнал %d — дій не визначено\n"
+
+msgid "return all values in a record oriented format"
+msgstr "повернути всі значення у форматі записів"
+
+msgid "|NAME|ignore host part and connect through NAME"
+msgstr ""
+"|NAME|ігнорувати частину вузла і встановити з’єднання за вказаною назвою"
+
+msgid "|NAME|connect to host NAME"
+msgstr "|NAME|встановити з’єднання з вузлом за вказаною назвою"
+
+msgid "|N|connect to port N"
+msgstr "|N|встановити з’єднання на вказаному порті"
+
+msgid "|NAME|use user NAME for authentication"
+msgstr "|NAME|використовувати вказаного користувача для розпізнавання"
+
+msgid "|PASS|use password PASS for authentication"
+msgstr "|PASS|використовувати вказаний пароль для розпізнавання"
+
+msgid "take password from $DIRMNGR_LDAP_PASS"
+msgstr "визначити пароль за $DIRMNGR_LDAP_PASS"
+
+msgid "|STRING|query DN STRING"
+msgstr "|STRING|надіслати запит до DN щодо вказаного рядка"
+
+msgid "|STRING|use STRING as filter expression"
+msgstr "|STRING|використовувати вказаний рядок для фільтрування"
+
+msgid "|STRING|return the attribute STRING"
+msgstr "|STRING|повернути атрибут за вказаним рядком"
+
+msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n"
+msgstr "Використання: dirmngr_ldap [параметри] [адреса] (-h — довідка)\n"
+
+msgid ""
+"Syntax: dirmngr_ldap [options] [URL]\n"
+"Internal LDAP helper for Dirmngr\n"
+"Interface and options may change without notice\n"
+msgstr ""
+"Синтаксис: dirmngr_ldap [параметри] [адреса]\n"
+"Вбудований допоміжний інструмент LDAP для Dirmngr\n"
+"Інтерфейс і параметри можуть змінюватися без додаткового оголошення\n"
+
+#, c-format
+msgid "invalid port number %d\n"
+msgstr "некоректний номер порту %d\n"
+
+#, c-format
+msgid "scanning result for attribute '%s'\n"
+msgstr "сканування результату для атрибуту «%s»\n"
+
+#, c-format
+msgid "error writing to stdout: %s\n"
+msgstr "помилка під час спроби запису до stdout: %s\n"
+
+#, c-format
+msgid "          available attribute '%s'\n"
+msgstr "          доступний атрибут «%s»\n"
+
+#, c-format
+msgid "attribute '%s' not found\n"
+msgstr "атрибут «%s» не знайдено\n"
+
+#, c-format
+msgid "found attribute '%s'\n"
+msgstr "знайдено атрибут «%s»\n"
+
+#, c-format
+msgid "processing url '%s'\n"
+msgstr "обробка адреси «%s»\n"
+
+#, c-format
+msgid "          user '%s'\n"
+msgstr "          користувач «%s»\n"
+
+#, c-format
+msgid "          pass '%s'\n"
+msgstr "          прохід «%s»\n"
+
+#, c-format
+msgid "          host '%s'\n"
+msgstr "          вузол «%s»\n"
+
+#, c-format
+msgid "          port %d\n"
+msgstr "          порт %d\n"
+
+#, c-format
+msgid "            DN '%s'\n"
+msgstr "            DN «%s»\n"
+
+#, c-format
+msgid "        filter '%s'\n"
+msgstr "        фільтр «%s»\n"
+
+#, c-format
+msgid "          attr '%s'\n"
+msgstr "          атрибут «%s»\n"
+
+#, c-format
+msgid "no host name in '%s'\n"
+msgstr "у «%s» немає назви вузла\n"
+
+#, c-format
+msgid "no attribute given for query '%s'\n"
+msgstr "не вказано атрибута для запису «%s»\n"
+
+msgid "WARNING: using first attribute only\n"
+msgstr "УВАГА: використано буде лише перший атрибут\n"
+
+#, c-format
+msgid "LDAP init to '%s:%d' failed: %s\n"
+msgstr "помилка ініціалізації LDAP «%s:%d»: %s\n"
+
+#, c-format
+msgid "binding to '%s:%d' failed: %s\n"
+msgstr "спроба прив’язування до «%s:%d» зазнала невдачі: %s\n"
+
+#, c-format
+msgid "searching '%s' failed: %s\n"
+msgstr "помилка під час спроби пошуку «%s»: %s\n"
+
+#, c-format
+msgid "'%s' is not an LDAP URL\n"
+msgstr "«%s» не є адресою LDAP\n"
+
+#, c-format
+msgid "'%s' is an invalid LDAP URL\n"
+msgstr "«%s» є некоректною адресою LDAP\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "помилка під час спроби отримання області пам’яті: %s\n"
+
+#, c-format
+msgid "error printing log line: %s\n"
+msgstr "помилка під час спроби виводу рядка журналу: %s\n"
+
+#, c-format
+msgid "error reading log from ldap wrapper %d: %s\n"
+msgstr "помилка під час спроби читання журналу з обгортки LDAP %d: %s\n"
+
+#, c-format
+msgid "npth_select failed: %s - waiting 1s\n"
+msgstr "помилка npth_select: %s — очікування у 1 с\n"
+
+#, c-format
+msgid "ldap wrapper %d ready"
+msgstr "обгортка LDAP %d готова"
+
+#, c-format
+msgid "ldap wrapper %d ready: timeout\n"
+msgstr "обгортка LDAP %d готова: перевищення часу очікування\n"
+
+#, c-format
+msgid "ldap wrapper %d ready: exitcode=%d\n"
+msgstr "обгортка LDAP %d готова: код_виходу=%d\n"
+
+#, c-format
+msgid "waiting for ldap wrapper %d failed: %s\n"
+msgstr "очікування даних з обгортки LDAP %d зазнало невдачі: %s\n"
+
+#, c-format
+msgid "ldap wrapper %d stalled - killing\n"
+msgstr "обгортка LDAP %d не відповідає — завершуємо роботу\n"
+
+#, c-format
+msgid "error spawning ldap wrapper reaper thread: %s\n"
+msgstr ""
+"помилка під час спроби породження потоку обгортки отримання даних LDAP: %s\n"
+
+#, c-format
+msgid "reading from ldap wrapper %d failed: %s\n"
+msgstr "спроба читання з обгортки LDAP %d зазнала невдачі: %s\n"
+
+#, c-format
+msgid "invalid char 0x%02x in host name - not added\n"
+msgstr "некоректний символ 0x%02x у назві вузла — не додано\n"
+
+#, c-format
+msgid "adding '%s:%d' to the ldap server list\n"
+msgstr "додавання «%s:%d» до списку сервера LDAP\n"
+
+#, c-format
+msgid "malloc failed: %s\n"
+msgstr "помилка malloc: %s\n"
+
+#, c-format
+msgid "start_cert_fetch: invalid pattern '%s'\n"
+msgstr "start_cert_fetch: некоректний шаблон «%s»\n"
+
+msgid "ldap_search hit the size limit of the server\n"
+msgstr "ldap_search перевищив обмеження розміру сервера\n"
+
+msgid "invalid canonical S-expression found\n"
+msgstr "виявлено некоректний канонічний вираз S\n"
+
+#, c-format
+msgid "gcry_md_open failed: %s\n"
+msgstr "помилка gcry_md_open: %s\n"
+
+#, c-format
+msgid "oops: ksba_cert_hash failed: %s\n"
+msgstr "ой: помилка ksba_cert_hash: %s\n"
+
+msgid "bad URL encoding detected\n"
+msgstr "виявлено помилкове кодування адреси\n"
+
+#, c-format
+msgid "error reading from responder: %s\n"
+msgstr "помилка під час спроби читання даних з відповідача: %s\n"
+
+#, c-format
+msgid "response from server too large; limit is %d bytes\n"
+msgstr "занадто об’ємна відповідь від сервера; верхня межа — %d байтів\n"
+
+msgid "OCSP request not possible due to disabled HTTP\n"
+msgstr "запит за допомогою OCSP неможливий через вимикання протоколу HTTP\n"
+
+#, c-format
+msgid "error setting OCSP target: %s\n"
+msgstr "помилка під час встановлення призначення за OCSP: %s\n"
+
+#, c-format
+msgid "error building OCSP request: %s\n"
+msgstr "помилка під час спроби побудови запиту за OCSP: %s\n"
+
+#, c-format
+msgid "error connecting to '%s': %s\n"
+msgstr "помилка під час спроби встановлення з’єднання з «%s»: %s\n"
+
+#, c-format
+msgid "error reading HTTP response for '%s': %s\n"
+msgstr "помилка під час спроби читання відповіді за HTTP для «%s»: %s\n"
+
+#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "помилка під час спроби доступу до «%s»: стан http %u\n"
+
+#, c-format
+msgid "error parsing OCSP response for '%s': %s\n"
+msgstr "помилка під час обробки відповіді за OCSP для «%s»: %s\n"
+
+#, c-format
+msgid "OCSP responder at '%s' status: %s\n"
+msgstr "Відповідач OCSP перебуває у стані «%s»: %s\n"
+
+#, c-format
+msgid "hashing the OCSP response for '%s' failed: %s\n"
+msgstr "спроба хешування відповіді OCSP для «%s» зазнала невдачі: %s\n"
+
+msgid "not signed by a default OCSP signer's certificate"
+msgstr "не підписано типовим сертифікатом підписувальника OCSP"
+
+msgid "only SHA-1 is supported for OCSP responses\n"
+msgstr "для відповідей за OCSP передбачено підтримку лише SHA-1\n"
+
+#, c-format
+msgid "allocating list item failed: %s\n"
+msgstr "спроба розміщення пункту списку у пам’яті зазнала невдачі: %s\n"
+
+#, c-format
+msgid "error getting responder ID: %s\n"
+msgstr "помилка під час спроби отримання ідентифікатора відповідача: %s\n"
+
+msgid "no suitable certificate found to verify the OCSP response\n"
+msgstr "не виявлено придатного сертифіката для перевірки відповіді за OCSP\n"
+
+#, c-format
+msgid "issuer certificate not found: %s\n"
+msgstr "не виявлено сертифіката видавця: %s\n"
+
+msgid "caller did not return the target certificate\n"
+msgstr "викликаною підпрограмою не повернуто сертифіката призначення\n"
+
+msgid "caller did not return the issuing certificate\n"
+msgstr "викликаною підпрограмою не повернуто сертифіката видавця\n"
+
+#, c-format
+msgid "failed to allocate OCSP context: %s\n"
+msgstr "не вдалося розмістити контекст OCSP: %s\n"
+
+#, c-format
+msgid "can't get authorityInfoAccess: %s\n"
+msgstr "не вдалося отримати authorityInfoAccess: %s\n"
+
+msgid "no default OCSP responder defined\n"
+msgstr "не визначено типового відповідача за OCSP\n"
+
+msgid "no default OCSP signer defined\n"
+msgstr "не визначено типового підписувача за OCSP\n"
+
+#, c-format
+msgid "using default OCSP responder '%s'\n"
+msgstr "використовуємо типовий відповідач за OCSP «%s»\n"
+
+#, c-format
+msgid "using OCSP responder '%s'\n"
+msgstr "використовуємо відповідач за OCSP «%s»\n"
+
+#, c-format
+msgid "failed to establish a hashing context for OCSP: %s\n"
+msgstr "не вдалося встановити контекст хешування для OCSP: %s\n"
+
+#, c-format
+msgid "error getting OCSP status for target certificate: %s\n"
+msgstr "помилка під час отримання стану OCSP для сертифіката призначення: %s\n"
+
+#, c-format
+msgid "certificate status is: %s  (this=%s  next=%s)\n"
+msgstr "стан сертифіката: %s  (цей=%s  наступний=%s)\n"
+
+msgid "good"
+msgstr "придатний"
+
+#, c-format
+msgid "certificate has been revoked at: %s due to: %s\n"
+msgstr "сертифікат було відкликано: %s причина: %s\n"
+
+msgid "OCSP responder returned a status in the future\n"
+msgstr "Відповідачем OCSP повернуто стан у майбутньому\n"
+
+msgid "OCSP responder returned a non-current status\n"
+msgstr "Відповідачем OCSP повернуто не поточний стан\n"
+
+msgid "OCSP responder returned an too old status\n"
+msgstr "Відповідачем OCSP повернуто занадто застарілі дані щодо стану\n"
+
+#, c-format
+msgid "assuan_inquire(%s) failed: %s\n"
+msgstr "помилка assuan_inquire(%s): %s\n"
+
+msgid "ldapserver missing"
+msgstr "не вказано ldapserver"
+
+msgid "serialno missing in cert ID"
+msgstr "у ідентифікаторі сертифіката немає серійного номера"
+
+#, c-format
+msgid "assuan_inquire failed: %s\n"
+msgstr "помилка assuan_inquire: %s\n"
+
+#, c-format
+msgid "fetch_cert_by_url failed: %s\n"
+msgstr "помилка fetch_cert_by_url: %s\n"
+
+#, c-format
+msgid "error sending data: %s\n"
+msgstr "помилка під час спроби надсилання даних: %s\n"
+
+#, c-format
+msgid "start_cert_fetch failed: %s\n"
+msgstr "помилка start_cert_fetch: %s\n"
+
+#, c-format
+msgid "fetch_next_cert failed: %s\n"
+msgstr "помилка fetch_next_cert: %s\n"
+
+#, c-format
+msgid "max_replies %d exceeded\n"
+msgstr "перевищено max_replies у %d\n"
+
+#, c-format
+msgid "can't allocate control structure: %s\n"
+msgstr "не вдалося розмістити структуру керування: %s\n"
+
+#, c-format
+msgid "failed to initialize the server: %s\n"
+msgstr "не вдалося ініціалізувати сервер: %s\n"
+
+#, c-format
+msgid "failed to the register commands with Assuan: %s\n"
+msgstr "не вдалося зареєструвати команди за допомогою Assuan: %s\n"
+
+#, c-format
+msgid "Assuan accept problem: %s\n"
+msgstr "проблема з прийняттям Assuan: %s\n"
+
+#, c-format
+msgid "Assuan processing failed: %s\n"
+msgstr "помилка обробки за допомогою Assuan: %s\n"
+
+msgid "accepting root CA not marked as a CA"
+msgstr "приймаємо кореневий сертифікат CA не позначений як CA"
+
+msgid "CRL checking too deeply nested\n"
+msgstr "занадто високий рівень вкладеності перевірки CRL\n"
+
+msgid "not checking CRL for"
+msgstr "не перевіряємо CRL щодо"
+
+msgid "checking CRL for"
+msgstr "перевіряємо CRL щодо"
+
+msgid "running in compatibility mode - certificate chain not checked!\n"
+msgstr "працюємо у режимі сумісності — ланцюжок сертифікації не перевірено!\n"
+
+msgid "selfsigned certificate has a BAD signature"
+msgstr "самопідписаний сертифікат має ПОМИЛКОВИЙ підпис"
+
+#, c-format
+msgid "checking trustworthiness of root certificate failed: %s\n"
+msgstr ""
+"спроба перевірки надійності кореневого сертифіката зазнала невдачі: %s\n"
+
+msgid "certificate chain is good\n"
+msgstr "коректний ланцюжок сертифікації\n"
+
+msgid "DSA requires the use of a 160 bit hash algorithm\n"
+msgstr "DSA потребує використання 160-бітового алгоритму хешування\n"
+
+msgid "certificate should not have been used for CRL signing\n"
+msgstr "сертифікат не мав використовуватися для підписування CRL\n"
+
+msgid "quiet"
+msgstr "без повідомлень"
+
+msgid "print data out hex encoded"
+msgstr "вивести дані у шістнадцятковому форматі"
+
+msgid "decode received data lines"
+msgstr "декодувати отримані рядки даних"
+
+msgid "connect to the dirmngr"
+msgstr "з’єднатися з dirmngr"
+
+msgid "|NAME|connect to Assuan socket NAME"
+msgstr "|NAME|встановити з’єднання з вказаним сокетом Assuan"
+
+msgid "|ADDR|connect to Assuan server at ADDR"
+msgstr "|ADDR|встановити з’єднання з сервером Assuan за вказаною адресою"
+
+msgid "run the Assuan server given on the command line"
+msgstr "запустити сервер Assuan, вказаний у командному рядку"
+
+msgid "do not use extended connect mode"
+msgstr "не використовувати розширений режим з’єднання"
+
+msgid "|FILE|run commands from FILE on startup"
+msgstr "|FILE|виконати команди з вказаного файла під час запуску"
+
+msgid "run /subst on startup"
+msgstr "виконати /subst під час запуску"
+
+msgid "Usage: @GPG@-connect-agent [options] (-h for help)"
+msgstr "Використання: @GPG@-connect-agent [параметри] (-h — довідка)"
+
+msgid ""
+"Syntax: @GPG@-connect-agent [options]\n"
+"Connect to a running agent and send commands\n"
+msgstr ""
+"Синтаксис: @GPG@-connect-agent [параметри]\n"
+"Встановити з’єднання з запущеним агентом і надіслати команди\n"
+
+#, c-format
+msgid "option \"%s\" requires a program and optional arguments\n"
+msgstr ""
+"щоб скористатися параметром «%s», слід вказати програму та додаткові "
+"аргументи\n"
+
+#, c-format
+msgid "option \"%s\" ignored due to \"%s\"\n"
+msgstr "параметр «%s» проігноровано через «%s»\n"
+
+#, c-format
+msgid "receiving line failed: %s\n"
+msgstr "помилка під час спроби отримання рядка: %s\n"
+
+msgid "line too long - skipped\n"
+msgstr "рядок є надто довгим, його пропущено\n"
+
+msgid "line shortened due to embedded Nul character\n"
+msgstr "рядок скорочено через вбудований символ Nul\n"
+
+#, c-format
+msgid "unknown command '%s'\n"
+msgstr "невідома команда «%s»\n"
+
+#, c-format
+msgid "sending line failed: %s\n"
+msgstr "помилка надсилання рядка: %s\n"
+
+#, c-format
+msgid "error sending standard options: %s\n"
+msgstr "помилка під час спроби надсилання стандартних параметрів: %s\n"
+
+msgid "Options controlling the diagnostic output"
+msgstr "Параметри керування діагностичним виводом"
+
+msgid "Options controlling the configuration"
+msgstr "Параметри керування налаштуваннями"
+
+msgid "Options useful for debugging"
+msgstr "Параметри діагностики"
+
+msgid "Options controlling the security"
+msgstr "Параметри керування захистом"
+
+msgid "|N|expire SSH keys after N seconds"
+msgstr "|N|завершувати строк дії ключів SSH за N секунд"
+
+msgid "|N|set maximum PIN cache lifetime to N seconds"
+msgstr "|N|встановити максимальний строк дії кешу пінкодів у секундах"
+
+msgid "|N|set maximum SSH key lifetime to N seconds"
+msgstr "|N|встановити максимальний строк дії ключа SSH у секундах"
+
+msgid "Options enforcing a passphrase policy"
+msgstr "Параметри примусового використання правил паролів"
+
+msgid "do not allow to bypass the passphrase policy"
+msgstr "не дозволяти обхід правил паролів"
+
+msgid "|N|set minimal required length for new passphrases to N"
+msgstr "|N|встановити вказану мінімальну довжину нових паролів"
+
+msgid "|N|require at least N non-alpha characters for a new passphrase"
+msgstr "|N|вимагати у нових паролях не менше вказаної кількості нелітер"
+
+msgid "|FILE|check new passphrases against pattern in FILE"
+msgstr "|FILE|перевіряти нові паролі за зразком з вказаного файла"
+
+msgid "|N|expire the passphrase after N days"
+msgstr "|N|завершувати строк дії паролів за вказану кількість днів"
+
+msgid "do not allow the reuse of old passphrases"
+msgstr "не дозволяти повторне використання старих паролів"
+
+msgid "|NAME|use NAME as default secret key"
+msgstr "|NAME|використовувати вказаний типовий закритий ключ"
+
+msgid "|NAME|encrypt to user ID NAME as well"
+msgstr "|NAME|шифрувати також до вказаного ідентифікатора користувача"
+
+msgid "|SPEC|set up email aliases"
+msgstr "|SPEC|встановити замінники адреси електронної пошти"
+
+msgid "Configuration for Keyservers"
+msgstr "Налаштування для серверів ключів"
+
+msgid "|URL|use keyserver at URL"
+msgstr "|URL|використовувати сервер ключів за адресою"
+
+msgid "allow PKA lookups (DNS requests)"
+msgstr "дозволити пошук PKA (запити до DNS)"
+
+msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
+msgstr ""
+"|MECHANISMS|використовувати вказаний механізм для пошуку ключів за адресою"
+
+msgid "disable all access to the dirmngr"
+msgstr "заборонити доступ до dirmngr"
+
+msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
+msgstr "використовувати вказане кодування для паролів PKCS#12"
+
+msgid "do not check CRLs for root certificates"
+msgstr "не шукати у списках відкликаних сертифікатів кореневі сертифікати"
+
+msgid "Options controlling the format of the output"
+msgstr "Параметри керування форматом виведення"
+
+msgid "Options controlling the interactivity and enforcement"
+msgstr "Параметри керування інтерактивністю та примусом"
+
+msgid "Configuration for HTTP servers"
+msgstr "Налаштування для серверів HTTP"
+
+msgid "use system's HTTP proxy setting"
+msgstr "використовувати загальносистемний проксі-сервер HTTP"
+
+msgid "Configuration of LDAP servers to use"
+msgstr "Налаштування використання серверів LDAP"
+
+msgid "LDAP server list"
+msgstr "список серверів LDAP"
+
+msgid "Configuration for OCSP"
+msgstr "Налаштування OCSP"
+
+msgid "GPG for OpenPGP"
+msgstr "GPG для OpenPGP"
+
+msgid "GPG Agent"
+msgstr "Агент GPG"
+
+msgid "Smartcard Daemon"
+msgstr "Фонова служба карток пам’яті"
+
+msgid "GPG for S/MIME"
+msgstr "GPG для S/MIME"
+
+msgid "Directory Manager"
+msgstr "Керування каталогом"
+
+msgid "PIN and Passphrase Entry"
+msgstr "Введення пінкодів і паролів"
+
+msgid "Component not suitable for launching"
+msgstr "Компонент не є придатним до запуску"
+
+#, c-format
+msgid "External verification of component %s failed"
+msgstr "Помилка зовнішньої перевірки компонента %s"
+
+msgid "Note that group specifications are ignored\n"
+msgstr "Зауважте, що специфікації груп буде проігноровано\n"
+
+msgid "list all components"
+msgstr "показати список всіх компонентів"
+
+msgid "check all programs"
+msgstr "перевірити всі програми"
+
+msgid "|COMPONENT|list options"
+msgstr "|COMPONENT|показати список параметрів"
+
+msgid "|COMPONENT|change options"
+msgstr "|COMPONENT|змінити параметри"
+
+msgid "|COMPONENT|check options"
+msgstr "|COMPONENT|перевірити параметри"
+
+msgid "apply global default values"
+msgstr "застосувати загальні типові значення"
+
+msgid "get the configuration directories for @GPGCONF@"
+msgstr "отримати назви каталогів налаштувань для @GPGCONF@"
+
+msgid "list global configuration file"
+msgstr "показати загальний файл налаштувань"
+
+msgid "check global configuration file"
+msgstr "перевірити загальний файл налаштувань"
+
+msgid "reload all or a given component"
+msgstr "перезавантажити всі або вказаний компонент"
+
+msgid "launch a given component"
+msgstr "запустити вказаний компонент"
+
+msgid "kill a given component"
+msgstr "завершити роботу вказаного компонента"
+
+msgid "use as output file"
+msgstr "використати файл для виведення даних"
+
+msgid "activate changes at runtime, if possible"
+msgstr "якщо можна, задіяти зміни у динамічному режимі"
+
+msgid "Usage: @GPGCONF@ [options] (-h for help)"
+msgstr "Використання: @GPGCONF@ [параметри] (-h — довідка)"
+
+msgid ""
+"Syntax: @GPGCONF@ [options]\n"
+"Manage configuration options for tools of the @GNUPG@ system\n"
+msgstr ""
+"Синтаксис: @GPGCONF@ [параметри]\n"
+"Керування параметрами налаштування інструментів системи @GNUPG@\n"
+
+msgid "Need one component argument"
+msgstr "Слід вказати один аргумент компонента"
+
+msgid "Component not found"
+msgstr "Компонент не знайдено"
+
+msgid "No argument allowed"
+msgstr "Не можна вказувати аргументів"
 
 msgid ""
 "@\n"
@@ -6758,7 +7900,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "невдала спроба виконання %s для %s зі станом %i\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "не вдалося створити тимчасовий каталог «%s»: %s\n"
 
 #, c-format
@@ -6855,11 +7997,218 @@ msgstr ""
 "Синтаксис: gpg-check-pattern [параметри] файл_шаблонів\n"
 "Перевірити пароль, вказаний у stdin, за допомогою файла_шаблонів\n"
 
+#~ msgid "no secret subkey for public subkey %s - ignoring\n"
+#~ msgstr "немає закритого підключа для відкритого підключа %s — пропускаємо\n"
+
+#, fuzzy
+#~| msgid "Note: no default option file '%s'\n"
+#~ msgid "NOTE: no default option file '%s'\n"
+#~ msgstr "ЗАУВАЖЕННЯ: не виявлено файла типових параметрів «%s»\n"
+
+#, fuzzy
+#~| msgid "Note: %s is not for normal use!\n"
+#~ msgid "NOTE: %s is not for normal use!\n"
+#~ msgstr "ЗАУВАЖЕННЯ: %s не призначено для звичайного використання!\n"
+
+#, fuzzy
+#~| msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n"
+#~ msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n"
+#~ msgstr "ЗАУВАЖЕННЯ: створення підключів для ключів v3 несумісне з OpenPGP\n"
+
+#~ msgid "note: non-critical certificate policy not allowed"
+#~ msgstr "зауваження: заборонено некритичні правила сертифікації"
+
+#~ msgid "use a standard location for the socket"
+#~ msgstr "використовувати для сокета стандартне розташування"
+
+#~ msgid "|FILE|write environment settings also to FILE"
+#~ msgstr "записати параметри середовища і до файла"
+
+#~ msgid "gpg-agent protocol version %d is not supported\n"
+#~ msgstr "підтримки версії протоколу gpg-agent %d не передбачено\n"
+
+#~ msgid "can't connect to the agent - trying fall back\n"
+#~ msgstr ""
+#~ "не вдалося встановити з’єднання з агентом, використовуємо резервний "
+#~ "варіант\n"
+
+#~ msgid "   (%d) ECC\n"
+#~ msgstr "   (%d) ECC\n"
+
+#, fuzzy
+#~| msgid "can't create directory '%s': %s\n"
+#~ msgid "can't create directory `%s': %s\n"
+#~ msgstr "не вдалося створити каталог «%s»: %s\n"
+
+#, fuzzy
+#~| msgid "directory '%s' created\n"
+#~ msgid "directory `%s' created\n"
+#~ msgstr "створено каталог «%s»\n"
+
+#, fuzzy
+#~| msgid "error creating keybox '%s': %s\n"
+#~ msgid "error creating keybox `%s': %s\n"
+#~ msgstr "помилка під час спроби створення сховища ключів «%s»: %s\n"
+
+#, fuzzy
+#~| msgid "keybox '%s' created\n"
+#~ msgid "keybox `%s' created\n"
+#~ msgstr "створено сховище ключів «%s»\n"
+
+#, fuzzy
+#~| msgid "can't create lock for '%s'\n"
+#~ msgid "can't create lock for `%s'\n"
+#~ msgstr "не вдалося створити блокування для «%s»\n"
+
+#~ msgid ""
+#~ "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
+#~ msgstr ""
+#~ "шифрувати ключами RSA з розміром у 2048 бітів або менше лише у режимі --"
+#~ "pgp2\n"
+
+#~ msgid ""
+#~ "unable to use the IDEA cipher for all of the keys you are encrypting to.\n"
+#~ msgstr ""
+#~ "не можна використовувати шифр IDEA для всіх ключів, якими виконується "
+#~ "шифрування.\n"
+
+#~ msgid ""
+#~ "you can only make detached or clear signatures while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "від’єднані та текстові підписи можна створювати лише у режимі --pgp2\n"
+
+#~ msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "у режимі --pgp2 не можна одночасно підписувати і зашифровувати дані\n"
+
+#~ msgid ""
+#~ "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
+#~ msgstr ""
+#~ "вам слід використовувати файли (не канали даних) під час роботи з "
+#~ "увімкненим --pgp2.\n"
+
+#~ msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
+#~ msgstr ""
+#~ "шифрування повідомлень у режимі --pgp2 потребує використання шифру IDEA\n"
+
+#~ msgid ""
+#~ "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 "
+#~ "mode.\n"
+#~ msgstr "Не можна створювати підпис OpenPGP ключа PGP 2.x у режимі --pgp2.\n"
+
+#~ msgid "This would make the key unusable in PGP 2.x.\n"
+#~ msgstr "Це може зробити ключ непридатним до використання у PGP 2.x.\n"
+
+#~ msgid ""
+#~ "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "підписування від’єднаним ключем можливе лише за допомогою ключів у "
+#~ "форматі PGP 2.x у режимі --pgp2\n"
+
+#~ msgid ""
+#~ "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n"
+#~ msgstr ""
+#~ "підписування текстовим ключем можливе лише за допомогою ключів у форматі "
+#~ "PGP 2.x у режимі --pgp2\n"
+
 #~ msgid "you may want to start the gpg-agent first\n"
 #~ msgstr "вам варто спочатку запустити gpg-agent\n"
 
-#~ msgid "error loading `%s': %s\n"
+#~ msgid "usage: gpg [options] "
+#~ msgstr "використання: gpg [параметри] "
+
+#~ msgid "usage: gpgsm [options] "
+#~ msgstr "використання: gpgsm [параметри] "
+
+#~ msgid "enable ssh-agent emulation"
+#~ msgstr "увімкнути емуляцію ssh-агента"
+
+#~ msgid "Usage: gpg-agent [options] (-h for help)"
+#~ msgstr "Використання: gpg-agent [параметри] (-h — довідка)"
+
+#~ msgid "malformed GPG_AGENT_INFO environment variable\n"
+#~ msgstr "помилкове форматування змінної середовища GPG_AGENT_INFO\n"
+
+#~ msgid "error creating socket: %s\n"
+#~ msgstr "помилка під час спроби створення сокета: %s\n"
+
+#~ msgid "host not found"
+#~ msgstr "вузол не знайдено"
+
+#~ msgid "error loading '%s': %s\n"
 #~ msgstr "помилка під час спроби завантаження «%s»: %s\n"
 
+#~ msgid " - probably dead - removing lock"
+#~ msgstr " — ймовірно, не використовується — знімаємо блокування"
+
+#~ msgid "deleting secret key not implemented\n"
+#~ msgstr "вилучення закритого ключа не реалізовано\n"
+
+#~ msgid "too many entries in pk cache - disabled\n"
+#~ msgstr "занадто багато записів у кеші pk — вимкнено\n"
+
+#~ msgid "the IDEA cipher plugin is not present\n"
+#~ msgstr "не виявлено додатка шифрування IDEA\n"
+
+#~ msgid "10 translator see trustdb.c:uid_trust_string_fixed"
+#~ msgstr "10 translator see trustdb.c:uid_trust_string_fixed"
+
+#~ msgid "[ revoked]"
+#~ msgstr "[відклик.]"
+
+#~ msgid "[ expired]"
+#~ msgstr "[застаріл]"
+
+#~ msgid "[ unknown]"
+#~ msgstr "[невідома]"
+
+#~ msgid "[  undef ]"
+#~ msgstr "[не визн.]"
+
+#~ msgid "[marginal]"
+#~ msgstr "[неповна ]"
+
+#~ msgid "[  full  ]"
+#~ msgstr "[ повна  ]"
+
+#~ msgid "[ultimate]"
+#~ msgstr "[безмежна]"
+
+#~ msgid "undefined"
+#~ msgstr "не визначено"
+
+#~ msgid "never"
+#~ msgstr "ніколи"
+
+#~ msgid "marginal"
+#~ msgstr "неповна"
+
+#~ msgid "full"
+#~ msgstr "повна"
+
+#~ msgid "ultimate"
+#~ msgstr "безмежна"
+
+#~ msgid "Usage: scdaemon [options] (-h for help)"
+#~ msgstr "Використання: scdaemon [параметри] (-h — довідка)"
+
 #~ msgid "failed to allocated keyDB handle\n"
 #~ msgstr "не вдалося розмістити обробник keyDB\n"
+
+#~ msgid "Usage: gpgsm [options] [files] (-h for help)"
+#~ msgstr "Використання: gpgsm [параметри] [файли] (-h — довідка)"
+
+#~ msgid "usage: dirmngr [options] "
+#~ msgstr "використання: dirmngr [параметри] "
+
+#~ msgid "pth_event failed: %s\n"
+#~ msgstr "помилка pth_event: %s\n"
+
+#~ msgid "pth_wait failed: %s\n"
+#~ msgstr "помилка pth_wait: %s\n"
+
+#~ msgid "Usage: gpgconf [options] (-h for help)"
+#~ msgstr "Використання: gpgconf [параметри] (-h — довідка)"
+
+#~ msgid "usage: gpgconf [options] "
+#~ msgstr "використання: gpgconf [параметри] "
index ff9f770..adcd414 100644 (file)
@@ -10,7 +10,6 @@ msgstr ""
 "PO-Revision-Date: 2009-07-09 10:03+0200\n"
 "Last-Translator: Meng Jie <zuxyhere@eastday.com>\n"
 "Language-Team: Chinese (simplified) <i18n-translation@lists.linux.net.cn>\n"
-"Language: zh_CN\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -23,42 +22,6 @@ msgstr ""
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "无法存储指纹:%s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr ""
-
-msgid "|pinentry-label|_Cancel"
-msgstr ""
-
-msgid "|pinentry-label|_Yes"
-msgstr ""
-
-msgid "|pinentry-label|_No"
-msgstr ""
-
-msgid "|pinentry-label|PIN:"
-msgstr ""
-
-msgid "|pinentry-label|_Save in password manager"
-msgstr ""
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "您真的要吊销选定的子钥吗?(y/N)"
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "无效的密码"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 #, fuzzy
@@ -85,9 +48,6 @@ msgid ""
 "this session"
 msgstr "请输入密码:这是一个秘密的句子 \n"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -124,11 +84,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "不支持保护散列 %d\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "无法建立‘%s’:%s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "无法打开‘%s’: %s\n"
 
 #, fuzzy, c-format
@@ -155,31 +115,19 @@ msgstr "无法读出公钥:%s\n"
 msgid "error writing key: %s\n"
 msgstr "写入钥匙环‘%s’时出错: %s\n"
 
-#, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-
-msgid "Allow"
-msgstr ""
-
-msgid "Deny"
-msgstr ""
-
 #, fuzzy, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
 msgstr "请输入密码:这是一个秘密的句子 \n"
 
 #, fuzzy
 msgid "Please re-enter this passphrase"
 msgstr "更改密码"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr "请输入密码:这是一个秘密的句子 \n"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr ""
 
 msgid "does not match - try again"
 msgstr ""
@@ -213,7 +161,7 @@ msgid "Reset Code"
 msgstr ""
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr ""
 
 #, fuzzy
@@ -300,7 +248,7 @@ msgid "Yes, protection is not needed"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr ""
 "您需要一个密码来保护您的私钥。\n"
 "\n"
@@ -318,10 +266,10 @@ msgstr ""
 "选项:\n"
 " "
 
-msgid "run in daemon mode (background)"
+msgid "run in server mode (foreground)"
 msgstr ""
 
-msgid "run in server mode (foreground)"
+msgid "run in daemon mode (background)"
 msgstr ""
 
 msgid "verbose"
@@ -376,26 +324,15 @@ msgstr ""
 msgid "do not use the PIN cache when signing"
 msgstr ""
 
-msgid "disallow clients to mark keys as \"trusted\""
+msgid "allow clients to mark keys as \"trusted\""
 msgstr ""
 
 #, fuzzy
 msgid "allow presetting passphrase"
 msgstr "生成密码的时候发生错误:%s\n"
 
-#, fuzzy
-#| msgid "not supported"
-msgid "enable ssh support"
-msgstr "未被支持"
-
-#, fuzzy
-#| msgid "not supported"
-msgid "enable putty support"
-msgstr "未被支持"
-
-#, fuzzy
-msgid "disallow the use of an external password cache"
-msgstr "生成密码的时候发生错误:%s\n"
+msgid "enable ssh-agent emulation"
+msgstr ""
 
 msgid "|FILE|write environment settings also to FILE"
 msgstr ""
@@ -418,7 +355,7 @@ msgid ""
 msgstr ""
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr ""
 
 #, c-format
@@ -426,23 +363,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr ""
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "注意:没有默认配置文件‘%s’\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "配置文件‘%s’:%s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "从‘%s’读取选项\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "建立‘%s’时发生错误:%s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "无法建立目录‘%s’:%s\n"
 
 msgid "name of socket too long\n"
@@ -453,7 +390,7 @@ msgid "can't create socket: %s\n"
 msgstr "无法建立‘%s’:%s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr ""
 
 #, fuzzy
@@ -465,7 +402,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "获取新 PIN 时出错:%s\n"
 
 #, fuzzy, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "在‘%s’中寻找信任度记录时出错:%s\n"
 
 #, fuzzy, c-format
@@ -473,19 +410,19 @@ msgid "listen() failed: %s\n"
 msgstr "更新失败:%s\n"
 
 #, fuzzy, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "正在将私钥写至`%s'\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "已创建目录‘%s’\n"
 
 #, fuzzy, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "fstat(%d) 在 %s 中出错:%s\n"
 
 #, fuzzy, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "无法建立目录‘%s’:%s\n"
 
 #, fuzzy, c-format
@@ -593,31 +530,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "生成密码的时候发生错误:%s\n"
 
 #, fuzzy, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "‘%s’中出错:%s\n"
 
 #, fuzzy, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "配置文件‘%s’:%s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "私钥部分不可用\n"
 
 #, fuzzy, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "读取‘%s’错误:%s\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "读取‘%s’时出错:%s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -705,15 +642,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "取得当前密钥信息时出错:%s\n"
 
 #, fuzzy, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "读取‘%s’时出错:%s\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "读取‘%s’时出错:%s\n"
 
 #, fuzzy, c-format
@@ -728,7 +665,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent 在此次舍话中无法使用\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "无法连接至‘%s’:%s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -803,10 +740,6 @@ msgstr ""
 msgid "no running gpg-agent - starting one\n"
 msgstr ""
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr ""
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr ""
 
@@ -833,22 +766,6 @@ msgid "|audit-log-result|Error"
 msgstr ""
 
 #, fuzzy
-msgid "|audit-log-result|Not used"
-msgstr "证书已损坏"
-
-#, fuzzy
-msgid "|audit-log-result|Okay"
-msgstr "证书已损坏"
-
-#, fuzzy
-msgid "|audit-log-result|Skipped"
-msgstr "证书已损坏"
-
-#, fuzzy
-msgid "|audit-log-result|Some"
-msgstr "证书已损坏"
-
-#, fuzzy
 msgid "Certificate chain available"
 msgstr "证书已损坏"
 
@@ -892,26 +809,10 @@ msgstr ""
 msgid "Data signing succeeded"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "data hash algorithm: %s"
-msgstr "无效的‘%s’散列算法\n"
-
-#, fuzzy, c-format
-msgid "Signer %d"
-msgstr "签名建立于 %s\n"
-
-#, fuzzy, c-format
-msgid "attr hash algorithm: %s"
-msgstr "无效的‘%s’散列算法\n"
-
 msgid "Data decryption succeeded"
 msgstr ""
 
 #, fuzzy
-msgid "Encryption algorithm supported"
-msgstr "保护算法 %d%s 未被支持\n"
-
-#, fuzzy
 msgid "Data verification succeeded"
 msgstr "签名验证已被抑制\n"
 
@@ -920,11 +821,11 @@ msgid "Signature available"
 msgstr "签名建立于 %s\n"
 
 #, fuzzy
-msgid "Parsing data succeeded"
+msgid "Parsing signature succeeded"
 msgstr "未找到签名\n"
 
 #, fuzzy, c-format
-msgid "bad data hash algorithm: %s"
+msgid "Bad hash algorithm: %s"
 msgstr "无效的‘%s’散列算法\n"
 
 #, fuzzy, c-format
@@ -969,7 +870,7 @@ msgid "Dirmngr usable"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "‘%s’没有可用的帮助"
 
 #, fuzzy
@@ -1132,11 +1033,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "建立钥匙环‘%s’时发生错误:%s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "读取‘%s’时出错:%s\n"
 
 #, fuzzy, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "写入钥匙环‘%s’时出错: %s\n"
 
 msgid "Login data (account name): "
@@ -1321,8 +1222,8 @@ msgstr "验证 PIN 并列出所有数据"
 msgid "unblock the PIN using a Reset Code"
 msgstr ""
 
-msgid "gpg/card> "
-msgstr ""
+msgid "Command> "
+msgstr "命令> "
 
 msgid "Admin-only command\n"
 msgstr "仅供管理员使用的命令\n"
@@ -1340,7 +1241,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output 在这个命令中不起作用\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "无法打开‘%s’\n"
 
 #, c-format
@@ -1389,18 +1290,18 @@ msgid "using cipher %s\n"
 msgstr "使用对称加密算法 %s\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "‘%s’已被压缩\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "警告:‘%s’是一个空文件\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr "在 --pgp2 模式中,您只能使用 2048 位及以下的 RSA 密钥加密\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "正在从‘%s’读取\n"
 
 msgid ""
@@ -1456,11 +1357,11 @@ msgid "this platform requires temporary files when calling external programs\n"
 msgstr "在这个操作平台上调用外部程序时需要临时文件\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "无法执行程序‘%s’:%s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "无法在命令解释环境中执行‘%s’:%s\n"
 
 #, c-format
@@ -1478,11 +1379,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "无法读取外部程序响应:%s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "警告:无法删除临时文件(%s)‘%s’:%s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "警告:无法删除临时目录‘%s’:%s\n"
 
 msgid "export signatures that are marked as local-only"
@@ -1543,15 +1444,11 @@ msgid "[User ID not found]"
 msgstr "[找不到用户标识]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "密钥 %s:无相应公钥的私钥――已跳过\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "自动获取‘%s’,通过 %s\n"
 
 #, fuzzy, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "建立‘%s’时发生错误:%s\n"
 
 #, fuzzy
@@ -1570,6 +1467,10 @@ msgstr "公钥 %s 没有相对应的私钥――忽略\n"
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "使用子钥 %s 而非主钥 %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "密钥 %s:无相应公钥的私钥――已跳过\n"
+
 #, fuzzy
 msgid "make a signature"
 msgstr "|[文件名]|生成一份签名"
@@ -1611,9 +1512,6 @@ msgstr "列出私钥"
 msgid "generate a new key pair"
 msgstr "生成一副新的密钥对"
 
-msgid "generate a revocation certificate"
-msgstr "生成一份吊销证书"
-
 msgid "remove keys from the public keyring"
 msgstr "从公钥钥匙环里删除密钥"
 
@@ -1629,9 +1527,8 @@ msgstr "为某把密钥添加本地签名"
 msgid "sign or edit a key"
 msgstr "编辑某把密钥或为其添加签名"
 
-#, fuzzy
-msgid "change a passphrase"
-msgstr "更改密码"
+msgid "generate a revocation certificate"
+msgstr "生成一份吊销证书"
 
 msgid "export keys"
 msgstr "导出密钥"
@@ -1730,15 +1627,10 @@ msgstr ""
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "用法: gpg [选项] [文件] (用 -h 求助)"
 
-#, fuzzy
-#| msgid ""
-#| "Syntax: gpg [options] [files]\n"
-#| "sign, check, encrypt or decrypt\n"
-#| "default operation depends on the input data\n"
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "语法:gpg [选项] [文件名]\n"
 "签名、检查、加密或解密\n"
@@ -1770,35 +1662,35 @@ msgid "conflicting commands\n"
 msgstr "冲突的指令\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "在‘%s’组定义里找不到等号(=)\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "警告:用户目录‘%s’所有权不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "警告:配置文件‘%s’所有权不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "警告:扩展模块‘%s’所有权不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "警告:用户目录‘%s’权限不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "警告:配置文件‘%s’权限不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "警告:扩展模块‘%s’权限不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "警告:用户目录‘%s’的关闭目录所有权不安全\n"
 
 #, c-format
@@ -1807,11 +1699,11 @@ msgid ""
 msgstr "警告:配置文件‘%s’的关闭目录所有权不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "警告:扩展模块‘%s’的关闭目录所有权不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "警告:用户目录‘%s’的关闭目录权限不安全\n"
 
 #, c-format
@@ -1820,11 +1712,11 @@ msgid ""
 msgstr "警告:配置文件‘%s’的关闭目录权限不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "警告:扩展模块‘%s’的关闭目录权限不安全\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "未知的配置项‘%s’\n"
 
 msgid "display photo IDs during key listings"
@@ -1861,7 +1753,7 @@ msgid "show expiration dates during signature listings"
 msgstr "列出签名时显示过期日期"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "注意:旧式的默认配置文件‘%s’已被忽略\n"
 
 #, c-format
@@ -1873,11 +1765,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "注意:一般情况下不会用到 %s!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "‘%s’不是一个有效的签名过期日期\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "‘%s’不是一个有效的字符集\n"
 
 msgid "could not parse keyserver URL\n"
@@ -2044,15 +1936,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s 尚不能和 %s 并用\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "您不能在 %s 模式下使用‘%s’对称加密算法\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "您不能在 %s 模式下使用‘%s’散列算法\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "您不能在 %s 模式下使用‘%s’压缩算法\n"
 
 #, c-format
@@ -2069,7 +1961,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [文件名]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "对称加密‘%s’失败:%s\n"
 
 msgid "--encrypt [filename]"
@@ -2119,10 +2011,6 @@ msgstr "--lsign-key 用户标识"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key 用户标识 [指令]"
 
-#, fuzzy
-msgid "--passwd <user-id>"
-msgstr "--sign-key 用户标识"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "上传至公钥服务器失败:%s\n"
@@ -2152,7 +2040,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "进行 ASCII 封装失败:%s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "无效的‘%s’散列算法\n"
 
 msgid "[filename]"
@@ -2195,7 +2083,7 @@ msgid "No help available"
 msgstr "没有可用的帮助"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "‘%s’没有可用的帮助"
 
 msgid "import signatures that are marked as local-only"
@@ -2204,11 +2092,6 @@ msgstr "导入被标记为局部的签名"
 msgid "repair damage from the pks keyserver during import"
 msgstr "导入时修复 PKS 公钥服务器导致的损坏"
 
-#, fuzzy
-#| msgid "do not update the trustdb after import"
-msgid "do not clear the ownertrust values during import"
-msgstr "导入后不更新信任度数据库"
-
 msgid "do not update the trustdb after import"
 msgstr "导入后不更新信任度数据库"
 
@@ -2324,14 +2207,6 @@ msgstr "您可以这样更新您的首选项:gpg --edit-key %s updpref save\n"
 msgid "key %s: no user ID\n"
 msgstr "密钥 %s:没有用户标识\n"
 
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s: %s\n"
-msgstr "“%s”已跳过:%s\n"
-
-msgid "rejected by import filter"
-msgstr ""
-
 #, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "密钥 %s:PKS 子钥破损已修复\n"
@@ -2360,11 +2235,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "找不到可写的钥匙环:%s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "正在写入‘%s’\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "写入钥匙环‘%s’时出错: %s\n"
 
 #, c-format
@@ -2427,18 +2302,13 @@ msgstr "密钥 %s:“%s”%d 个用户标识被清除\n"
 msgid "key %s: \"%s\" not changed\n"
 msgstr "密钥 %s:“%s”未改变\n"
 
-#, fuzzy, c-format
-#| msgid "secret key \"%s\" not found: %s\n"
-msgid "secret key %s: %s\n"
-msgstr "找不到私钥“%s”:%s\n"
-
-msgid "importing secret keys not allowed\n"
-msgstr "不允许导入私钥\n"
-
 #, c-format
 msgid "key %s: secret key with invalid cipher %d - skipped\n"
 msgstr "密钥 %s:私钥使用了无效的加密算法 %d――已跳过\n"
 
+msgid "importing secret keys not allowed\n"
+msgstr "不允许导入私钥\n"
+
 #, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "没有默认的私钥钥匙环: %s\n"
@@ -2480,18 +2350,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "密钥 %s:用户标识“%s”自身签名无效\n"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "密钥 %s:不支持的公钥算法\n"
-
-#, fuzzy, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "密钥 %s:已新增直接密钥签名\n"
-
-#, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "密钥 %s:没有可供绑定的子钥\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "密钥 %s:不支持的公钥算法\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "密钥 %s:无效的子钥绑定\n"
 
@@ -2573,15 +2439,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "注意:子钥在线,存储在卡上\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "建立钥匙环‘%s’时发生错误:%s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "钥匙环‘%s’已建立\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "密钥块资源‘%s’:%s\n"
 
 #, c-format
@@ -2762,7 +2628,7 @@ msgstr "   (2) 我随意检查过。 %s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) 我非常小心地检查过。 %s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "您的选择?(输入‘?’以获得更多的信息):"
 
 #, c-format
@@ -2993,7 +2859,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "提示:选择要添加签名的用户标识\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "未知的签名类型‘%s’\n"
 
 #, c-format
@@ -3025,11 +2891,11 @@ msgid "Command expects a filename argument\n"
 msgstr "命令需要一个文件名作为参数\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "无法打开‘%s’:%s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "从‘%s’读取备份密钥时出错:%s\n"
 
 msgid "You must select at least one key.\n"
@@ -3103,8 +2969,8 @@ msgstr "注记:"
 msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "PGP 2.x 样式的用户标识没有首选项。\n"
 
-#, fuzzy, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
+#, c-format
+msgid "This key was revoked on %s by %s key %s\n"
 msgstr "此密钥已于 %s 被 %s 密钥 %s 所吊销\n"
 
 #, c-format
@@ -3165,14 +3031,6 @@ msgid ""
 msgstr ""
 "警告:没有首选用户标识。此指令可能假定一个不同的用户标识为首选用户标识。\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "您不能变更 v3 密钥的使用期限\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3394,7 +3252,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "正在显示 %s 照片标识(大小为 %ld,属于密钥 %s,用户标识 %d)\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "首选项‘%s’重复\n"
 
 msgid "too many cipher preferences\n"
@@ -3407,7 +3265,7 @@ msgid "too many compression preferences\n"
 msgstr "太多首选压缩算法\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "首选项字符串里有无效项‘%s’\n"
 
 msgid "writing direct signature\n"
@@ -3644,7 +3502,7 @@ msgid "Invalid character in comment\n"
 msgstr "注释含有无效的字符\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "您正在使用‘%s’字符集。\n"
 
 #, c-format
@@ -3727,15 +3585,15 @@ msgid "Key generation canceled.\n"
 msgstr "密钥生成已取消。\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "正在将公钥写至`%s'\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "向‘%s’写入私钥占位符\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "正在将私钥写至`%s'\n"
 
 #, c-format
@@ -3747,11 +3605,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "找不到可写的私钥钥匙环:%s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "写入公钥钥匙环‘%s’时发生错误: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "写入私钥钥匙环‘%s’时发生错误: %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3789,11 +3647,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "向卡上存储密钥时失败:%s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "不能创建备份文件‘%s’:%s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "注意:卡密钥的备份已保存到‘%s’\n"
 
 msgid "never     "
@@ -3835,16 +3693,11 @@ msgstr " 子钥指纹:"
 msgid "      Key fingerprint ="
 msgstr "密钥指纹 ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "警告:使用试验性质的散列算法 %s\n"
-
 msgid "      Card serial no. ="
 msgstr "卡序列号 ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "将‘%s’重命名为‘%s’时失败:%s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -3862,7 +3715,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "请修补这个可能的安全性漏洞\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "缓存钥匙环‘%s’\n"
 
 #, c-format
@@ -3899,7 +3752,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "获取密钥时使用密钥上的 PKA 记录"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "警告:公钥服务器选项‘%s’在此平台上没有被使用\n"
 
 msgid "disabled"
@@ -3961,10 +3814,6 @@ msgstr "警告:处理公钥服务器的程序来自不同版本的 GnuPG (%s)\
 msgid "keyserver did not send VERSION\n"
 msgstr "公钥服务器未发送 VERSION\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "公钥服务器通讯错误:%s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "未给出公钥服务器(使用 --keyserver 选项)\n"
 
@@ -3972,11 +3821,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr "这一编译版本不支持外部调用公钥服务器\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr "没有处理‘%s’公钥服务器的程序\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr "‘%s’操作不为‘%s’公钥服务器所支持\n"
 
 #, c-format
@@ -3990,6 +3839,10 @@ msgid "keyserver internal error\n"
 msgstr "公钥服务器内部错误\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "公钥服务器通讯错误:%s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "“%s”不是一个用户标识:跳过\n"
 
@@ -4158,10 +4011,6 @@ msgid "unknown"
 msgstr "未知"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr ""
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "无法检查签名:%s\n"
 
@@ -4183,7 +4032,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "在 proc_tree() 中检测到无效的根包\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "‘%s’的 fstat 在 %s 中出错:%s\n"
 
 #, c-format
@@ -4210,11 +4059,6 @@ msgstr "警告:使用试验性质的散列算法 %s\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "警告:不建议使用散列算法 %s\n"
 
-#, fuzzy, c-format
-#| msgid "%s signature, digest algorithm %s\n"
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "%s 签名,散列算法 %s\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "IDEA 算法插件不存在\n"
 
@@ -4246,15 +4090,6 @@ msgstr ""
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "警告:“%s”选项已不建议使用\n"
 
-#, fuzzy, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "警告:“%s”选项已不建议使用\n"
-
-#, fuzzy, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "警告:“%s”选项已不建议使用\n"
-
 msgid "Uncompressed"
 msgstr "不压缩"
 
@@ -4267,15 +4102,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "%s 也许不能使用这个报文\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "有歧义的选项‘%s’\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "未知的选项 '%s'\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "文件‘%s’已存在。 "
 
 msgid "Overwrite? (y/N) "
@@ -4291,17 +4126,16 @@ msgstr "请输入新的文件名"
 msgid "writing to stdout\n"
 msgstr "正在写入到标准输出\n"
 
-#, fuzzy, c-format
-#| msgid "assuming signed data in `%s'\n"
+#, c-format
 msgid "assuming signed data in '%s'\n"
 msgstr "假定被签名的数据是‘%s’\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "新的配置文件‘%s’已建立\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "警告:在‘%s’里的选项于此次运行期间未被使用\n"
 
 #, c-format
@@ -4315,10 +4149,6 @@ msgstr "警告:潜在不安全的对称加密会话密钥\n"
 msgid "subpacket of type %d has critical bit set\n"
 msgstr "%d 类别的子包设定了关键位\n"
 
-#, fuzzy, c-format
-msgid "problem with the agent: %s\n"
-msgstr "代理程序有问题――正在停用代理程序\n"
-
 #, c-format
 msgid " (main key ID %s)"
 msgstr " (主钥匙号 %s)"
@@ -4341,6 +4171,10 @@ msgstr "请输入密码\n"
 msgid "cancelled by user\n"
 msgstr "用户取消\n"
 
+#, fuzzy, c-format
+msgid "problem with the agent: %s\n"
+msgstr "代理程序有问题――正在停用代理程序\n"
+
 #, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
@@ -4371,7 +4205,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "输入要当作相片标识的JPEG文件名: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "无法打开 JPEG 文件‘%s’:%s\n"
 
 #, c-format
@@ -4382,7 +4216,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "您确定要用它吗?(y/N)"
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "“%s”不是一个 JPEG 文件\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4413,16 +4247,6 @@ msgid "revocation comment: "
 msgstr "吊销注释:"
 
 #  a string with valid answers
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4522,11 +4346,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "注意:这把密钥已经被禁用了。\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr "注意:验证过的签名者的地址是‘%s’\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr "注意:签名者的地址‘%s’不匹配任何 DNS 记录\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4626,7 +4450,7 @@ msgid "no signed data\n"
 msgstr "不含签名的数据\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "无法打开有签名的数据‘%s’\n"
 
 #, fuzzy, c-format
@@ -4911,7 +4735,7 @@ msgstr ""
 "# (请用“gpg --import-ownertrust”导入这些信任度)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "‘%s’中出错:%s\n"
 
 msgid "line too long"
@@ -4927,11 +4751,11 @@ msgid "ownertrust value missing"
 msgstr "没有信任度"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "在‘%s’中寻找信任度记录时出错:%s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "读取‘%s’错误:%s\n"
 
 #, c-format
@@ -4939,14 +4763,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "信任度数据库:同步失败:%s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "不能为‘%s’创建锁定\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "无法锁定‘%s’\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "信任度数据库记录 %lu:lseek 失败:%s\n"
 
@@ -4958,12 +4774,20 @@ msgid "trustdb transaction too large\n"
 msgstr "信任度数据库处理量过大\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "无法存取‘%s’:%s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s:目录不存在!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "无法存取‘%s’:%s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "不能为‘%s’创建锁定\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "无法锁定‘%s’\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -5049,7 +4873,7 @@ msgid "input line longer than %d characters\n"
 msgstr "输入行长度超过 %d 字符\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "‘%s’不是一个有效的长式钥匙号\n"
 
 #, c-format
@@ -5090,14 +4914,6 @@ msgstr "无法使用未知的信任模型(%d)――假定使用 %s 信任模型\
 msgid "using %s trust model\n"
 msgstr "使用 %s 信任模型\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr "10 translator see trustdb.c:uid_trust_string_fixed"
 
@@ -5145,11 +4961,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "下次信任度数据库检查将于 %s 进行\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "使用‘%s’信任模型时不需要检查信任度数据库\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "使用‘%s’信任模型时不需要更新信任度数据库\n"
 
 #, c-format
@@ -5221,11 +5037,6 @@ msgid "missing argument"
 msgstr "无效的参数"
 
 #, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "无效的 ASCII 封装格式"
-
-#, fuzzy
 msgid "invalid command"
 msgstr "仅供管理员使用的命令\n"
 
@@ -5245,10 +5056,6 @@ msgstr "无效的列表选项\n"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "无效的列表选项\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr ""
@@ -5277,8 +5084,12 @@ msgstr "无效的列表选项\n"
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "您找到一个程序缺陷了……(%s:%d)\n"
 
+#, fuzzy, c-format
+msgid "error loading '%s': %s\n"
+msgstr "读取‘%s’时出错:%s\n"
+
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5286,15 +5097,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "签名时失败: %s\n"
 
 #, fuzzy, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "将‘%s’重命名为‘%s’时失败:%s\n"
 
 #, fuzzy, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "无法建立目录‘%s’:%s\n"
 
 #, fuzzy, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "写入钥匙环‘%s’时出错: %s\n"
 
 #, c-format
@@ -5312,7 +5123,7 @@ msgid "(deadlock?) "
 msgstr ""
 
 #, fuzzy, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "找不到公钥 %s:%s\n"
 
 #, fuzzy, c-format
@@ -5329,11 +5140,10 @@ msgstr ""
 msgid "Usage: kbxutil [options] [files] (-h for help)"
 msgstr "用法: gpg [选项] [文件] (用 -h 求助)"
 
-#, fuzzy
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
-msgstr "用法: gpg [选项] [文件] (用 -h 求助)"
+"list, export, import Keybox data\n"
+msgstr ""
 
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
@@ -5462,9 +5272,6 @@ msgstr "||请输入 PIN%%0A[完成的签字:%lu]"
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr "CHV%d 的 PIN 太短;最小长度为 %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr ""
 
@@ -5474,14 +5281,6 @@ msgstr "|AN|新的管理员 PIN"
 msgid "|N|New PIN"
 msgstr "新的 PIN"
 
-#, fuzzy
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||请输入 PIN%%0A[完成的签字:%lu]"
-
-#, fuzzy
-msgid "||Please enter the PIN and New PIN"
-msgstr "||请输入 PIN%%0A[完成的签字:%lu]"
-
 msgid "error reading application data\n"
 msgstr "读取应用程序数据时出错\n"
 
@@ -5544,9 +5343,8 @@ msgstr "目前禁止通过此命令验证管理员 PIN\n"
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "不能存取 %s――无效的 OpenPGP 卡?\n"
 
-#, fuzzy
-msgid "||Please enter your PIN at the reader's pinpad"
-msgstr "||请输入 PIN%%0A[完成的签字:%lu]"
+msgid "||Please enter your PIN at the reader's keypad"
+msgstr ""
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
@@ -5580,16 +5378,13 @@ msgstr ""
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr ""
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr ""
 
 #, fuzzy
 msgid "deny the use of admin card commands"
 msgstr "显示管理员命令"
 
-msgid "use variable length input for pinpad"
-msgstr ""
-
 #, fuzzy
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "用法: gpg [选项] [文件] (用 -h 求助)"
@@ -5599,7 +5394,7 @@ msgid ""
 "Smartcard daemon for GnuPG\n"
 msgstr ""
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr ""
 
 #, c-format
@@ -5619,7 +5414,7 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr ""
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr ""
 
 #, fuzzy
@@ -5654,7 +5449,7 @@ msgid "critical marked policy without configured policies"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "无法打开‘%s’:%s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5683,7 +5478,7 @@ msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "无法读出公钥:%s\n"
 
 #, fuzzy
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "无法存储密钥:%s\n"
 
 #, fuzzy
@@ -5873,16 +5668,16 @@ msgstr ""
 msgid "error getting key usage information: %s\n"
 msgstr "取得当前密钥信息时出错:%s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr ""
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr ""
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr ""
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr ""
 
 msgid "certificate is not usable for encryption\n"
@@ -5904,11 +5699,11 @@ msgid "line %d: no subject name given\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr ""
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr ""
 
 #, fuzzy, c-format
@@ -5916,11 +5711,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "电子邮件地址无效\n"
 
 #, fuzzy, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "建立钥匙环‘%s’时发生错误:%s\n"
 
 #, fuzzy, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "建立钥匙环‘%s’时发生错误:%s\n"
 
 #, fuzzy, c-format
@@ -5991,7 +5786,7 @@ msgid "No subject name given\n"
 msgstr "(不给定描述)\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr ""
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -6000,7 +5795,7 @@ msgstr ""
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, fuzzy, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "无效的‘%s’散列算法\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -6047,7 +5842,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "找不到私钥“%s”:%s\n"
 
 #, fuzzy, c-format
@@ -6055,11 +5850,11 @@ msgid "error locking keybox: %s\n"
 msgstr "读取密钥区块时发生错误:%s\n"
 
 #, fuzzy, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "已建立吊销证书。\n"
 
 #, fuzzy, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "首选项‘%s’重复\n"
 
 #, fuzzy, c-format
@@ -6097,6 +5892,10 @@ msgid "invoke gpg-protect-tool"
 msgstr ""
 
 #, fuzzy
+msgid "change a passphrase"
+msgstr "更改密码"
+
+#, fuzzy
 msgid "create base-64 encoded output"
 msgstr "输出经 ASCII 封装"
 
@@ -6174,8 +5973,8 @@ msgstr "用法: gpg [选项] [文件] (用 -h 求助)"
 #, fuzzy
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "语法:gpg [选项] [文件名]\n"
 "签名、检查、加密或解密\n"
@@ -6186,11 +5985,11 @@ msgid "usage: gpgsm [options] "
 msgstr "用法:gpg [选项] "
 
 #, fuzzy, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "无法连接至‘%s’:%s\n"
 
 #, fuzzy, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "未知的选项 '%s'\n"
 
 #, fuzzy, c-format
@@ -6213,11 +6012,11 @@ msgid "WARNING: running with faked system time: "
 msgstr ""
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "无法存取‘%s’:%s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6234,6 +6033,10 @@ msgstr "生成一份吊销证书"
 msgid "basic certificate checks failed - not imported\n"
 msgstr ""
 
+#, fuzzy
+msgid "failed to allocate keyDB handle\n"
+msgstr "无法存储密钥:%s\n"
+
 #, fuzzy, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "获取新 PIN 时出错:%s\n"
@@ -6247,11 +6050,14 @@ msgid "error reading input: %s\n"
 msgstr "读取‘%s’时出错:%s\n"
 
 #, fuzzy, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "建立钥匙环‘%s’时发生错误:%s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr ""
+
 #, fuzzy, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "钥匙环‘%s’已建立\n"
 
 #, fuzzy
@@ -6285,11 +6091,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "错误:指纹格式无效。\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr ""
 
 #, c-format
@@ -6408,7 +6214,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "未知的选项 '%s'\n"
 
 #, fuzzy, c-format
@@ -6638,7 +6444,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "‘%s’的 fstat 在 %s 中出错:%s\n"
 
 #, fuzzy, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "无法建立目录‘%s’:%s\n"
 
 #, c-format
@@ -6734,17 +6540,6 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
-#, fuzzy
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "读取‘%s’时出错:%s\n"
-
-#, fuzzy
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "无法存储密钥:%s\n"
-
-#~ msgid "Command> "
-#~ msgstr "命令> "
-
 #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n"
 #~ msgstr "信任度数据库已损坏;请执行“gpg --fix-trustdb”。\n"
 
@@ -6766,6 +6561,10 @@ msgstr ""
 #~ msgid "Repeat passphrase\n"
 #~ msgstr "请再输入一次密码\n"
 
+#, fuzzy
+#~ msgid "||Please enter your PIN at the reader's keypad%%0A[sigs done: %lu]"
+#~ msgstr "||请输入 PIN%%0A[完成的签字:%lu]"
+
 #~ msgid "|A|Admin PIN"
 #~ msgstr "|A|管理员 PIN"
 
@@ -7260,6 +7059,9 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "无效包"
 
+#~ msgid "invalid armor"
+#~ msgstr "无效的 ASCII 封装格式"
+
 #~ msgid "no such user id"
 #~ msgstr "没有这个用户标识"
 
@@ -7269,6 +7071,9 @@ msgstr ""
 #~ msgid "wrong secret key used"
 #~ msgstr "使用了错误的私钥"
 
+#~ msgid "not supported"
+#~ msgstr "未被支持"
+
 #~ msgid "bad key"
 #~ msgstr "密钥已损坏"
 
@@ -7281,6 +7086,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "文件建立错误"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "无效的密码"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "未实现的公钥算法"
 
index 4dcea6c..60e834f 100644 (file)
@@ -1,71 +1,29 @@
 # Traditional Chinese(zh-tw) messages for GnuPG
 # Copyright (C) 2002 Free Software Foundation, Inc.
 # This file is distributed under the same license as the PACKAGE package.
-# Jedi Lin <Jedi@Jedi.org>, 2003~2013.
+# Jedi Lin <Jedi@Jedi.org>, 2003, 2004, 2005, 2006, 2007, 2008.
 #
 # Special thanks to "Audrey Tang <audreyt@audreyt.org>".
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: GNU gnupg 2.0.27\n"
+"Project-Id-Version: gnupg 2.0.10rc1\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2014-11-21 23:15+0800\n"
-"Last-Translator: Jedi Lin <Jedi@Jedi.org>\n"
+"PO-Revision-Date: 2009-09-03 02:47+0800\n"
+"Last-Translator: Jedi <JediLin@Gmail.com>\n"
 "Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
-"Language: zh_TW\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Basepath: gnupg-2.0.27/\n"
+"X-Poedit-Basepath: gnupg-2.0.10rc1/\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-Country: TAIWAN\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 1.5.7\n"
 
 #, c-format
 msgid "failed to acquire the pinentry lock: %s\n"
 msgstr "個人識別碼項目鎖定獲取失敗: %s\n"
 
-#. TRANSLATORS: These are labels for buttons etc used in
-#. Pinentries.  An underscore indicates that the next letter
-#. should be used as an accelerator.  Double the underscore for
-#. a literal one.  The actual to be translated text starts after
-#. the second vertical bar.
-msgid "|pinentry-label|_OK"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|_Cancel"
-msgstr "|pinentry-label|取消 (_C)"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_Yes"
-msgstr "|pinentry-label|_OK"
-
-#, fuzzy
-#| msgid "|pinentry-label|_OK"
-msgid "|pinentry-label|_No"
-msgstr "|pinentry-label|_OK"
-
-msgid "|pinentry-label|PIN:"
-msgstr "|pinentry-label|個人識別碼 (PIN):"
-
-#, fuzzy
-#| msgid "|pinentry-label|_Cancel"
-msgid "|pinentry-label|_Save in password manager"
-msgstr "|pinentry-label|取消 (_C)"
-
-#, fuzzy
-#| msgid "Do you really want to revoke the selected subkeys? (y/N) "
-msgid "Do you really want to make your passphrase visible on the screen?"
-msgstr "你真的想要撤銷所選的子鑰嗎? (y/N) "
-
-msgid "|pinentry-tt|Make passphrase visible"
-msgstr ""
-
-#, fuzzy
-#| msgid "invalid passphrase"
-msgid "|pinentry-tt|Hide passphrase"
-msgstr "無效的密語"
-
 #. TRANSLATORS: This string is displayed by Pinentry as the label
 #. for the quality bar.
 msgid "Quality:"
@@ -92,9 +50,6 @@ msgid ""
 "this session"
 msgstr "請輸入你的密語以便在此階段作業中解開私鑰"
 
-#. TRANSLATORS: The string is appended to an error message in
-#. the pinentry.  The %s is the actual error message, the
-#. two %d give the current and maximum number of tries.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "設定錯誤 %s (第 %d 次嘗試, 最多 %d 次)"
@@ -125,11 +80,11 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "未支援大於 %d 位元的 ssh 金鑰\n"
 
 #, c-format
-msgid "can't create `%s': %s\n"
+msgid "can't create '%s': %s\n"
 msgstr "無法建立 `%s': %s\n"
 
 #, c-format
-msgid "can't open `%s': %s\n"
+msgid "can't open '%s': %s\n"
 msgstr "無法開啟 `%s': %s\n"
 
 #, c-format
@@ -157,31 +112,17 @@ msgid "error writing key: %s\n"
 msgstr "寫入金鑰時出錯: %s\n"
 
 #, c-format
-msgid ""
-"An ssh process requested the use of key%%0A  %s%%0A  (%s)%%0ADo you want to "
-"allow this?"
-msgstr ""
-"有某個 ssh 程序提出使用金鑰 %%0A  %s%%0A  (%s)%%0A 之請求, 請問是否允許?"
-
-msgid "Allow"
-msgstr "允許"
-
-msgid "Deny"
-msgstr "拒絕"
-
-#, c-format
-msgid "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)"
-msgstr "請輸入此 ssh 金鑰的密語 %%0A  %F%%0A  (%c)"
+msgid "Please enter the passphrase for the ssh key%0A  %c"
+msgstr "請輸入此 ssh 金鑰的密語%0A  %c"
 
 msgid "Please re-enter this passphrase"
 msgstr "請再次輸入密語"
 
 #, c-format
 msgid ""
-"Please enter a passphrase to protect the received secret key%%0A   %s%%0A   "
-"%s%%0Awithin gpg-agent's key storage"
-msgstr ""
-"請輸入密語以保護收到的私鑰 %%0A   %s%%0A   %s%%0A 於 gpg-agent 的金鑰存放處"
+"Please enter a passphrase to protect the received secret key%%0A   %s%%"
+"0Awithin gpg-agent's key storage"
+msgstr "請輸入密語以保護收到的私鑰%%0A   %s%%0A於 gpg-agent 的金鑰存放處"
 
 msgid "does not match - try again"
 msgstr "前後不一致 - 請再試一次"
@@ -190,11 +131,17 @@ msgstr "前後不一致 - 請再試一次"
 msgid "failed to create stream from socket: %s\n"
 msgstr "從 socket 建立串流失敗: %s\n"
 
+#, fuzzy
 msgid "Please insert the card with serial number"
-msgstr "請插入下列序號的卡片:"
+msgstr ""
+"請移除現用中的卡片並插入下列序號的卡片:\n"
+"   %.*s\n"
 
+#, fuzzy
 msgid "Please remove the current card and insert the one with serial number"
-msgstr "請移除現用中的卡片並插入下列序號的卡片:"
+msgstr ""
+"請移除現用中的卡片並插入下列序號的卡片:\n"
+"   %.*s\n"
 
 msgid "Admin PIN"
 msgstr "管理者個人識別碼 (PIN)"
@@ -208,7 +155,7 @@ msgid "Reset Code"
 msgstr "重設碼"
 
 #, c-format
-msgid "%s%%0A%%0AUse the reader's pinpad for input."
+msgid "%s%%0A%%0AUse the reader's keypad for input."
 msgstr "%s%%0A%%0A使用讀卡機的鍵盤來輸入."
 
 msgid "Repeat this Reset Code"
@@ -291,7 +238,7 @@ msgid "Yes, protection is not needed"
 msgstr "是, 不需要任何保護"
 
 #, c-format
-msgid "Please enter the passphrase to%0Aprotect your new key"
+msgid "Please enter the passphrase to%0Ato protect your new key"
 msgstr "請輸入密語至%0A以保護你的新金鑰"
 
 msgid "Please enter the new passphrase"
@@ -304,12 +251,12 @@ msgstr ""
 "@選項:\n"
 " "
 
-msgid "run in daemon mode (background)"
-msgstr "以服務模式執行 (背景)"
-
 msgid "run in server mode (foreground)"
 msgstr "以伺服器模式執行 (前景)"
 
+msgid "run in daemon mode (background)"
+msgstr "以服務模式執行 (背景)"
+
 msgid "verbose"
 msgstr "囉唆模式"
 
@@ -323,7 +270,7 @@ msgid "csh-style command output"
 msgstr "csh 樣式的指令輸出"
 
 msgid "|FILE|read options from FILE"
-msgstr "|檔案|從指定檔案中讀取選項"
+msgstr "|檔案|從「檔案」中讀取選項"
 
 msgid "do not detach from the console"
 msgstr "不要從 console 分離"
@@ -358,31 +305,24 @@ msgstr "|N|讓快取住的個人識別碼 (PIN) 在 N 秒後到期"
 msgid "do not use the PIN cache when signing"
 msgstr "簽署時不要使用個人識別碼 (PIN) 快取"
 
-msgid "disallow clients to mark keys as \"trusted\""
-msgstr "允許用戶端將金鑰標記為 \"已信任\""
+msgid "allow clients to mark keys as \"trusted\""
+msgstr "允許用戶端將金鑰標記為 \"已信任\""
 
 msgid "allow presetting passphrase"
 msgstr "允許預先設定密語"
 
-msgid "enable ssh support"
-msgstr "啟用 ssh 支援"
-
-msgid "enable putty support"
-msgstr "啟用 putty 支援"
-
-#, fuzzy
-#| msgid "do not allow the reuse of old passphrases"
-msgid "disallow the use of an external password cache"
-msgstr "不允許重複使用舊密語"
+msgid "enable ssh-agent emulation"
+msgstr "啟用 ssh-agent 模擬"
 
 msgid "|FILE|write environment settings also to FILE"
-msgstr "|檔案|將環境設定也寫至指定檔案"
+msgstr "|檔案|將環境設定也寫至「檔案」"
 
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
+#, fuzzy
 msgid "Please report bugs to <@EMAIL@>.\n"
-msgstr "翻譯瑕疵請回報給 <Jedi@Jedi.org>, 程式瑕疵則請回報給 <@EMAIL@>.\n"
+msgstr "翻譯瑕疵請回報給 <Jedi@Jedi.org>, 程式瑕疵則請回報給 <"
 
 msgid "Usage: gpg-agent [options] (-h for help)"
 msgstr "用法: gpg-agent [選項] (或用 -h 求助)"
@@ -395,7 +335,7 @@ msgstr ""
 "GnuPG 私鑰管理\n"
 
 #, c-format
-msgid "invalid debug-level `%s' given\n"
+msgid "invalid debug-level '%s' given\n"
 msgstr "給定的除錯等級 `%s' 無效\n"
 
 #, c-format
@@ -403,23 +343,23 @@ msgid "%s is too old (need %s, have %s)\n"
 msgstr "%s 太舊了 (需要 %s, 但是祇有 %s)\n"
 
 #, c-format
-msgid "NOTE: no default option file `%s'\n"
+msgid "NOTE: no default option file '%s'\n"
 msgstr "請注意: 沒有預設選項檔 `%s'\n"
 
 #, c-format
-msgid "option file `%s': %s\n"
+msgid "option file '%s': %s\n"
 msgstr "選項檔 `%s': %s\n"
 
 #, c-format
-msgid "reading options from `%s'\n"
+msgid "reading options from '%s'\n"
 msgstr "從 `%s' 讀取選項中\n"
 
 #, c-format
-msgid "error creating `%s': %s\n"
+msgid "error creating '%s': %s\n"
 msgstr "建立 `%s' 時出錯: %s\n"
 
 #, c-format
-msgid "can't create directory `%s': %s\n"
+msgid "can't create directory '%s': %s\n"
 msgstr "無法建立目錄 `%s': %s\n"
 
 msgid "name of socket too long\n"
@@ -430,7 +370,7 @@ msgid "can't create socket: %s\n"
 msgstr "無法建立 socket: %s\n"
 
 #, c-format
-msgid "socket name `%s' is too long\n"
+msgid "socket name '%s' is too long\n"
 msgstr "socket 名稱 `%s' 太長\n"
 
 msgid "a gpg-agent is already running - not starting a new one\n"
@@ -440,7 +380,7 @@ msgid "error getting nonce for the socket\n"
 msgstr "為 socket 取得 nonce 時出錯\n"
 
 #, c-format
-msgid "error binding socket to `%s': %s\n"
+msgid "error binding socket to '%s': %s\n"
 msgstr "綁定 socket 至 `%s' 時出錯: %s\n"
 
 #, c-format
@@ -448,19 +388,19 @@ msgid "listen() failed: %s\n"
 msgstr "listen() 失敗: %s\n"
 
 #, c-format
-msgid "listening on socket `%s'\n"
+msgid "listening on socket '%s'\n"
 msgstr "正在候聽 socket `%s'\n"
 
 #, c-format
-msgid "directory `%s' created\n"
+msgid "directory '%s' created\n"
 msgstr "`%s' 目錄已建立\n"
 
 #, c-format
-msgid "stat() failed for `%s': %s\n"
+msgid "stat() failed for '%s': %s\n"
 msgstr "stat() 失敗於 `%s': %s\n"
 
 #, c-format
-msgid "can't use `%s' as home directory\n"
+msgid "can't use '%s' as home directory\n"
 msgstr "無法使用 `%s' 做為家目錄\n"
 
 #, c-format
@@ -495,7 +435,7 @@ msgid "no gpg-agent running in this session\n"
 msgstr "在此階段中沒有執行中的 gpg-agent\n"
 
 msgid "malformed GPG_AGENT_INFO environment variable\n"
-msgstr "格式不對的 GPG_AGENT_INFO 環境變數\n"
+msgstr "被變造的 GPG_AGENT_INFO 環境變數\n"
 
 #, c-format
 msgid "gpg-agent protocol version %d is not supported\n"
@@ -566,31 +506,31 @@ msgid "error while asking for the passphrase: %s\n"
 msgstr "詢問密語時出錯: %s\n"
 
 #, c-format
-msgid "error opening `%s': %s\n"
+msgid "error opening '%s': %s\n"
 msgstr "開啟 `%s' 時出錯: %s\n"
 
 #, c-format
-msgid "file `%s', line %d: %s\n"
+msgid "file '%s', line %d: %s\n"
 msgstr "檔案 `%s', 第 %d 列: %s\n"
 
 #, c-format
-msgid "statement \"%s\" ignored in `%s', line %d\n"
+msgid "statement \"%s\" ignored in '%s', line %d\n"
 msgstr "命令 \"%s\" 忽略於 `%s', 第 %d 列\n"
 
 #, c-format
-msgid "system trustlist `%s' not available\n"
+msgid "system trustlist '%s' not available\n"
 msgstr "沒有系統信任清單 `%s' 可用\n"
 
 #, c-format
-msgid "bad fingerprint in `%s', line %d\n"
+msgid "bad fingerprint in '%s', line %d\n"
 msgstr "不良的指紋於 `%s', 第 %d 列\n"
 
 #, c-format
-msgid "invalid keyflag in `%s', line %d\n"
+msgid "invalid keyflag in '%s', line %d\n"
 msgstr "無效的金鑰旗標於 `%s', 第 %d 列\n"
 
 #, c-format
-msgid "error reading `%s', line %d: %s\n"
+msgid "error reading '%s', line %d: %s\n"
 msgstr "讀取 `%s' 時出錯, 第 %d 列: %s\n"
 
 msgid "error reading list of trusted root certificates\n"
@@ -676,15 +616,15 @@ msgid "error getting exit code of process %d: %s\n"
 msgstr "取得 %d 執行程序結束碼時出錯: %s\n"
 
 #, c-format
-msgid "error running `%s': exit status %d\n"
+msgid "error running '%s': exit status %d\n"
 msgstr "執行 `%s' 時出錯: 結束狀態 %d\n"
 
 #, c-format
-msgid "error running `%s': probably not installed\n"
+msgid "error running '%s': probably not installed\n"
 msgstr "執行 `%s' 時出錯: 可能尚未安裝\n"
 
 #, c-format
-msgid "error running `%s': terminated\n"
+msgid "error running '%s': terminated\n"
 msgstr "執行 `%s' 時出錯: 已終止\n"
 
 #, c-format
@@ -698,7 +638,7 @@ msgid "gpg-agent is not available in this session\n"
 msgstr "gpg-agent 在此階段無法使用\n"
 
 #, c-format
-msgid "can't connect to `%s': %s\n"
+msgid "can't connect to '%s': %s\n"
 msgstr "無法連接至 `%s': %s\n"
 
 msgid "communication problem with gpg-agent\n"
@@ -771,10 +711,6 @@ msgstr "配置 %lu 位元組時超出核心"
 msgid "no running gpg-agent - starting one\n"
 msgstr "沒有執行中的 gpg-agent - 正在啟動一份\n"
 
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
-msgstr "必須等候 %d 秒讓代理程式出現\n"
-
 msgid "can't connect to the agent - trying fall back\n"
 msgstr "無法連線至代理程式 - 正試著退回\n"
 
@@ -792,24 +728,13 @@ msgstr "|audit-log-result|不支援"
 msgid "|audit-log-result|No certificate"
 msgstr "|audit-log-result|沒有憑證"
 
+#, fuzzy
 msgid "|audit-log-result|Not enabled"
-msgstr "|audit-log-result|未啟用"
+msgstr "|audit-log-result|不良"
 
 msgid "|audit-log-result|Error"
 msgstr "|audit-log-result|錯誤"
 
-msgid "|audit-log-result|Not used"
-msgstr "|audit-log-result|未使用"
-
-msgid "|audit-log-result|Okay"
-msgstr "|audit-log-result|沒問題"
-
-msgid "|audit-log-result|Skipped"
-msgstr "|audit-log-result|已跳過"
-
-msgid "|audit-log-result|Some"
-msgstr "|audit-log-result|有些"
-
 msgid "Certificate chain available"
 msgstr "有可用的憑證鏈"
 
@@ -846,36 +771,21 @@ msgstr "收件者 %d"
 msgid "Data signing succeeded"
 msgstr "資料已簽署成功"
 
-#, c-format
-msgid "data hash algorithm: %s"
-msgstr "資料雜湊演算法: %s"
-
-#, c-format
-msgid "Signer %d"
-msgstr "簽署者 %d"
-
-#, c-format
-msgid "attr hash algorithm: %s"
-msgstr "屬性雜湊演算法: %s"
-
 msgid "Data decryption succeeded"
 msgstr "資料已解密成功"
 
-msgid "Encryption algorithm supported"
-msgstr "支援的加密演算法"
-
 msgid "Data verification succeeded"
 msgstr "資料驗證成功"
 
 msgid "Signature available"
 msgstr "有可用的簽章"
 
-msgid "Parsing data succeeded"
-msgstr "剖析資料成功"
+msgid "Parsing signature succeeded"
+msgstr "剖析簽章成功"
 
 #, c-format
-msgid "bad data hash algorithm: %s"
-msgstr "不良的資料雜湊演算法: %s"
+msgid "Bad hash algorithm: %s"
+msgstr "不良的雜湊演算法: %s"
 
 #, c-format
 msgid "Signature %d"
@@ -912,7 +822,7 @@ msgid "Dirmngr usable"
 msgstr "Dirmngr 可以使用"
 
 #, c-format
-msgid "No help available for `%s'."
+msgid "No help available for '%s'."
 msgstr "`%s' 沒有可用的說明."
 
 msgid "ignoring garbage line"
@@ -957,7 +867,7 @@ msgid "premature eof (in CRC)\n"
 msgstr "檔案未預期的結束 (CRC 的部分未結束)\n"
 
 msgid "malformed CRC\n"
-msgstr "格式不對的 CRC\n"
+msgstr "CRC 被變造過\n"
 
 #, c-format
 msgid "CRC error; %06lX - %06lX\n"
@@ -1069,11 +979,11 @@ msgid "error allocating enough memory: %s\n"
 msgstr "配置足夠的記憶體時出錯: %s\n"
 
 #, c-format
-msgid "error reading `%s': %s\n"
+msgid "error reading '%s': %s\n"
 msgstr "讀取 `%s' 時出錯: %s\n"
 
 #, c-format
-msgid "error writing `%s': %s\n"
+msgid "error writing '%s': %s\n"
 msgstr "寫入 `%s' 時出錯: %s\n"
 
 msgid "Login data (account name): "
@@ -1130,21 +1040,18 @@ msgid ""
 "      If the key generation does not succeed, please check the\n"
 "      documentation of your card to see what sizes are allowed.\n"
 msgstr ""
-"請注意: 我們完全無法保證卡片支援你想用的尺寸.\n"
-"      如果金鑰產生失敗了, 煩請查閱你卡片上的文件,\n"
-"      看看這張卡片支援哪些尺寸.\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Signature key? (%u) "
-msgstr "你的簽署金鑰想要用多大的金鑰尺寸? (%u) "
+msgstr "你的鑰想要用多大的金鑰尺寸? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Encryption key? (%u) "
-msgstr "ä½ ç\9a\84å\8a å¯\86é\87\91鑰想要用多大的金鑰尺寸? (%u) "
+msgstr "ä½ ç\9a\84å­\90鑰想要用多大的金鑰尺寸? (%u) "
 
-#, c-format
+#, fuzzy, c-format
 msgid "What keysize do you want for the Authentication key? (%u) "
-msgstr "你的認證金鑰想要用多大的金鑰尺寸? (%u) "
+msgstr "你的鑰想要用多大的金鑰尺寸? (%u) "
 
 #, c-format
 msgid "rounded up to %u bits\n"
@@ -1156,17 +1063,18 @@ msgstr "%s 金鑰尺寸一定要介於 %u 到 %u 之間\n"
 
 #, c-format
 msgid "The card will now be re-configured to generate a key of %u bits\n"
-msgstr "這張卡片將重新加以組態, 以便產生 %u 位元的金鑰\n"
+msgstr ""
 
-#, c-format
+#, fuzzy, c-format
 msgid "error changing size of key %d to %u bits: %s\n"
-msgstr "將金鑰 %d 尺寸變更至 %u 位元時出錯: %s\n"
+msgstr "綁定 socket 至 `%s' 時出錯: %s\n"
 
 msgid "Make off-card backup of encryption key? (Y/n) "
 msgstr "是否要為加密用金鑰建立卡外備份? (Y/n) "
 
+#, fuzzy
 msgid "NOTE: keys are already stored on the card!\n"
-msgstr "請注意: 金鑰已經存放在卡片上了!\n"
+msgstr "私鑰已經存放在卡片上了\n"
 
 msgid "Replace existing keys? (y/N) "
 msgstr "是否要取代既有的金鑰? (y/N) "
@@ -1208,9 +1116,9 @@ msgstr "私鑰部分無法取用\n"
 msgid "secret key already stored on a card\n"
 msgstr "私鑰已經存放在卡片上了\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error writing key to card: %s\n"
-msgstr "金鑰寫入卡片時出錯: %s\n"
+msgstr "寫入金鑰時出錯: %s\n"
 
 msgid "quit this menu"
 msgstr "離開這個選單"
@@ -1260,8 +1168,8 @@ msgstr "驗證個人識別碼 (PIN) 並列出所有的資料"
 msgid "unblock the PIN using a Reset Code"
 msgstr "用重設碼來解凍個人識別碼 (PIN)"
 
-msgid "gpg/card> "
-msgstr "gpg/卡片> "
+msgid "Command> "
+msgstr "指令> "
 
 msgid "Admin-only command\n"
 msgstr "限管理者使用的指令\n"
@@ -1279,7 +1187,7 @@ msgid "--output doesn't work for this command\n"
 msgstr "--output 在這個指令中沒有作用\n"
 
 #, c-format
-msgid "can't open `%s'\n"
+msgid "can't open '%s'\n"
 msgstr "無法開啟 `%s'\n"
 
 #, c-format
@@ -1328,18 +1236,18 @@ msgid "using cipher %s\n"
 msgstr "正在使用 %s 編密法\n"
 
 #, c-format
-msgid "`%s' already compressed\n"
+msgid "'%s' already compressed\n"
 msgstr "`%s' 已經被壓縮了\n"
 
 #, c-format
-msgid "WARNING: `%s' is an empty file\n"
+msgid "WARNING: '%s' is an empty file\n"
 msgstr "警告: `%s' 是個空檔案\n"
 
 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n"
 msgstr "在 --pgp2 模式中, 你祇能以 2048 位元以下的 RSA 金鑰加密\n"
 
 #, c-format
-msgid "reading from `%s'\n"
+msgid "reading from '%s'\n"
 msgstr "正在從 `%s' 讀取中\n"
 
 msgid ""
@@ -1395,11 +1303,11 @@ msgid "this platform requires temporary files when calling external programs\n"
 msgstr "在這個作業平台上叫用外部程式時需要暫存檔\n"
 
 #, c-format
-msgid "unable to execute program `%s': %s\n"
+msgid "unable to execute program '%s': %s\n"
 msgstr "無法執行程式 `%s': %s\n"
 
 #, c-format
-msgid "unable to execute shell `%s': %s\n"
+msgid "unable to execute shell '%s': %s\n"
 msgstr "無法執行 shell `%s': %s\n"
 
 #, c-format
@@ -1417,11 +1325,11 @@ msgid "unable to read external program response: %s\n"
 msgstr "無法讀取外部程式回應: %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n"
+msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n"
 msgstr "警告: 無法移除暫存檔 (%s) `%s': %s\n"
 
 #, c-format
-msgid "WARNING: unable to remove temp directory `%s': %s\n"
+msgid "WARNING: unable to remove temp directory '%s': %s\n"
 msgstr "警告: 無法移除暫存目錄 `%s': %s\n"
 
 msgid "export signatures that are marked as local-only"
@@ -1482,15 +1390,11 @@ msgid "[User ID not found]"
 msgstr "[找不到使用者 ID]"
 
 #, c-format
-msgid "key %s: secret key without public key - skipped\n"
-msgstr "金鑰 %s: 祇有私鑰而沒有公鑰 - 已跳過\n"
-
-#, c-format
-msgid "automatically retrieved `%s' via %s\n"
+msgid "automatically retrieved '%s' via %s\n"
 msgstr "已自動取回 `%s' (經由 %s )\n"
 
 #, c-format
-msgid "error retrieving `%s' via %s: %s\n"
+msgid "error retrieving '%s' via %s: %s\n"
 msgstr "取得 `%s' 於 %s 時出錯: %s\n"
 
 msgid "No fingerprint"
@@ -1508,6 +1412,10 @@ msgstr "公鑰 %s 沒有相對應的私鑰 - 正在忽略\n"
 msgid "using subkey %s instead of primary key %s\n"
 msgstr "使用子鑰 %s 來替換主鑰 %s\n"
 
+#, c-format
+msgid "key %s: secret key without public key - skipped\n"
+msgstr "金鑰 %s: 祇有私鑰而沒有公鑰 - 已跳過\n"
+
 msgid "make a signature"
 msgstr "建立簽章"
 
@@ -1547,9 +1455,6 @@ msgstr "列出私鑰"
 msgid "generate a new key pair"
 msgstr "產生新的金鑰對"
 
-msgid "generate a revocation certificate"
-msgstr "產生撤銷憑證"
-
 msgid "remove keys from the public keyring"
 msgstr "從公鑰鑰匙圈裡移除金鑰"
 
@@ -1565,8 +1470,8 @@ msgstr "僅在本機簽署金鑰"
 msgid "sign or edit a key"
 msgstr "簽署或編輯金鑰"
 
-msgid "change a passphrase"
-msgstr "更改密語"
+msgid "generate a revocation certificate"
+msgstr "產生撤銷憑證"
 
 msgid "export keys"
 msgstr "匯出金鑰"
@@ -1608,10 +1513,10 @@ msgid "create ascii armored output"
 msgstr "建立以 ASCII 封裝過的輸出"
 
 msgid "|USER-ID|encrypt for USER-ID"
-msgstr "|使用者-ID|以指定使用者 ID 作為加密對象"
+msgstr "|使用者-ID|以「使用者-ID」作為加密對象"
 
 msgid "|USER-ID|use USER-ID to sign or decrypt"
-msgstr "|使用者-ID|拿指定使用者 ID 來簽署或解密"
+msgstr "|使用者-ID|拿「使用者-ID」來簽署或解密"
 
 msgid "|N|set compress level to N (0 disables)"
 msgstr "|N|設定壓縮等級為 N (0 表示不壓縮)"
@@ -1620,7 +1525,7 @@ msgid "use canonical text mode"
 msgstr "使用標準的文字模式"
 
 msgid "|FILE|write output to FILE"
-msgstr "|檔案|將輸出寫入至指定檔案"
+msgstr "|檔案|將輸出寫入至「檔案」"
 
 msgid "do not make any changes"
 msgstr "不要做任何改變"
@@ -1662,8 +1567,8 @@ msgstr "用法: gpg [選項] [檔案] (或用 -h 求助)"
 
 msgid ""
 "Syntax: gpg [options] [files]\n"
-"Sign, check, encrypt or decrypt\n"
-"Default operation depends on the input data\n"
+"sign, check, encrypt or decrypt\n"
+"default operation depends on the input data\n"
 msgstr ""
 "語法: gpg [選項] [檔案]\n"
 "簽署, 檢查, 加密或解密\n"
@@ -1695,35 +1600,35 @@ msgid "conflicting commands\n"
 msgstr "指令彼此矛盾\n"
 
 #, c-format
-msgid "no = sign found in group definition `%s'\n"
+msgid "no = sign found in group definition '%s'\n"
 msgstr "在群組定義 `%s' 裡找不到 = 記號\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on homedir `%s'\n"
+msgid "WARNING: unsafe ownership on homedir '%s'\n"
 msgstr "警告: 家目錄 `%s' 的所有權並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on configuration file `%s'\n"
+msgid "WARNING: unsafe ownership on configuration file '%s'\n"
 msgstr "警告: 組態檔案 `%s' 的所有權並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe ownership on extension `%s'\n"
+msgid "WARNING: unsafe ownership on extension '%s'\n"
 msgstr "警告: 延伸模組 `%s' 的所有權並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on homedir `%s'\n"
+msgid "WARNING: unsafe permissions on homedir '%s'\n"
 msgstr "警告: 家目錄 `%s' 的權限並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on configuration file `%s'\n"
+msgid "WARNING: unsafe permissions on configuration file '%s'\n"
 msgstr "警告: 組態檔案 `%s' 的權限並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe permissions on extension `%s'\n"
+msgid "WARNING: unsafe permissions on extension '%s'\n"
 msgstr "警告: 延伸模組 `%s' 的權限並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n"
 msgstr "警告: 家目錄 `%s' 的封入目錄所有權並不安全\n"
 
 #, c-format
@@ -1732,11 +1637,11 @@ msgid ""
 msgstr "警告: 組態檔案 `%s' 的封入目錄所有權並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n"
 msgstr "警告: 延伸模組 `%s' 的封入目錄所有權並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n"
 msgstr "警告: 家目錄 `%s' 的封入目錄權限並不安全\n"
 
 #, c-format
@@ -1745,11 +1650,11 @@ msgid ""
 msgstr "警告: 組態檔案 `%s' 的封入目錄權限並不安全\n"
 
 #, c-format
-msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
+msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n"
 msgstr "警告: 延伸模組 `%s' 的封入目錄權限並不安全\n"
 
 #, c-format
-msgid "unknown configuration item `%s'\n"
+msgid "unknown configuration item '%s'\n"
 msgstr "未知的組態項目 `%s'\n"
 
 msgid "display photo IDs during key listings"
@@ -1786,7 +1691,7 @@ msgid "show expiration dates during signature listings"
 msgstr "列出簽章時顯示有效期限"
 
 #, c-format
-msgid "NOTE: old default options file `%s' ignored\n"
+msgid "NOTE: old default options file '%s' ignored\n"
 msgstr "請注意: 已忽略舊有的預設選項檔 `%s'\n"
 
 #, c-format
@@ -1798,11 +1703,11 @@ msgid "NOTE: %s is not for normal use!\n"
 msgstr "請注意: 一般情況下不會用到 %s!\n"
 
 #, c-format
-msgid "`%s' is not a valid signature expiration\n"
+msgid "'%s' is not a valid signature expiration\n"
 msgstr "`%s' 不是個有效的簽章使用期限\n"
 
 #, c-format
-msgid "`%s' is not a valid character set\n"
+msgid "'%s' is not a valid character set\n"
 msgstr "`%s' 不是個有效的字元集\n"
 
 msgid "could not parse keyserver URL\n"
@@ -1968,15 +1873,15 @@ msgid "%s does not yet work with %s\n"
 msgstr "%s 還沒辦法跟 %s 一起運作\n"
 
 #, c-format
-msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "you may not use cipher algorithm '%s' while in %s mode\n"
 msgstr "你不該將 `%s' 編密演算法用於 %s 模式中\n"
 
 #, c-format
-msgid "you may not use digest algorithm `%s' while in %s mode\n"
+msgid "you may not use digest algorithm '%s' while in %s mode\n"
 msgstr "你不該將 `%s' 摘要演算法用於 %s 模式中\n"
 
 #, c-format
-msgid "you may not use compression algorithm `%s' while in %s mode\n"
+msgid "you may not use compression algorithm '%s' while in %s mode\n"
 msgstr "你不該將 `%s' 壓縮演算法用於 %s 模式中\n"
 
 #, c-format
@@ -1993,7 +1898,7 @@ msgid "--symmetric [filename]"
 msgstr "--symmetric [檔名]"
 
 #, c-format
-msgid "symmetric encryption of `%s' failed: %s\n"
+msgid "symmetric encryption of '%s' failed: %s\n"
 msgstr "`%s' 對稱式加密失敗: %s\n"
 
 msgid "--encrypt [filename]"
@@ -2043,9 +1948,6 @@ msgstr "--lsign-key 使用者ID"
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key 使用者ID [指令]"
 
-msgid "--passwd <user-id>"
-msgstr "--passwd 使用者ID"
-
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "送至金鑰伺服器失敗: %s\n"
@@ -2075,7 +1977,7 @@ msgid "enarmoring failed: %s\n"
 msgstr "進行封裝失敗: %s\n"
 
 #, c-format
-msgid "invalid hash algorithm `%s'\n"
+msgid "invalid hash algorithm '%s'\n"
 msgstr "無效的 `%s' 雜湊演算法\n"
 
 msgid "[filename]"
@@ -2094,13 +1996,13 @@ msgid "the given preferred keyserver URL is invalid\n"
 msgstr "給定的偏好金鑰伺服器 URL 無效\n"
 
 msgid "|FILE|take the keys from the keyring FILE"
-msgstr "|檔案|從指定鑰匙圈檔案裡取用金鑰"
+msgstr "|檔案|從鑰匙圈「檔案」裡取用金鑰"
 
 msgid "make timestamp conflicts only a warning"
 msgstr "僅把時間戳印矛盾視為警告"
 
 msgid "|FD|write status info to this FD"
-msgstr "|檔案描述|把狀態資訊寫入此指定檔案描述"
+msgstr "|檔案描述|把狀態資訊寫入此「檔案描述」"
 
 msgid "Usage: gpgv [options] [files] (-h for help)"
 msgstr "用法: gpgv [選項] [檔案] (或用 -h 求助)"
@@ -2116,7 +2018,7 @@ msgid "No help available"
 msgstr "沒有可用的說明"
 
 #, c-format
-msgid "No help available for `%s'"
+msgid "No help available for '%s'"
 msgstr "`%s' 沒有可用的說明"
 
 msgid "import signatures that are marked as local-only"
@@ -2125,9 +2027,6 @@ msgstr "匯入標記為僅限本機使用的簽章"
 msgid "repair damage from the pks keyserver during import"
 msgstr "匯入時修復來自 pks 金鑰伺服器的損壞"
 
-msgid "do not clear the ownertrust values during import"
-msgstr "匯入過程中不要清除主觀信任值"
-
 msgid "do not update the trustdb after import"
 msgstr "匯入後不要更新信任資料庫"
 
@@ -2244,13 +2143,6 @@ msgid "key %s: no user ID\n"
 msgstr "金鑰 %s: 沒有使用者 ID\n"
 
 #, c-format
-msgid "key %s: %s\n"
-msgstr "金鑰 %s: %s\n"
-
-msgid "rejected by import filter"
-msgstr "已由匯入過濾器駁回"
-
-#, c-format
 msgid "key %s: PKS subkey corruption repaired\n"
 msgstr "金鑰 %s: PKS 子鑰的訛誤已被修復\n"
 
@@ -2278,11 +2170,11 @@ msgid "no writable keyring found: %s\n"
 msgstr "找不到可寫入的鑰匙圈: %s\n"
 
 #, c-format
-msgid "writing to `%s'\n"
+msgid "writing to '%s'\n"
 msgstr "寫入 `%s' 中\n"
 
 #, c-format
-msgid "error writing keyring `%s': %s\n"
+msgid "error writing keyring '%s': %s\n"
 msgstr "寫入鑰匙圈 `%s' 時出錯: %s\n"
 
 #, c-format
@@ -2346,17 +2238,13 @@ msgid "key %s: \"%s\" not changed\n"
 msgstr "金鑰 %s: \"%s\" 未改變\n"
 
 #, c-format
-msgid "secret key %s: %s\n"
-msgstr "私鑰 %s: %s\n"
+msgid "key %s: secret key with invalid cipher %d - skipped\n"
+msgstr "金鑰 %s: 私鑰使用了無效的 %d 編密法 - 已跳過\n"
 
 msgid "importing secret keys not allowed\n"
 msgstr "未允許匯入私鑰\n"
 
 #, c-format
-msgid "key %s: secret key with invalid cipher %d - skipped\n"
-msgstr "金鑰 %s: 私鑰使用了無效的 %d 編密法 - 已跳過\n"
-
-#, c-format
 msgid "no default secret keyring: %s\n"
 msgstr "沒有預設的私鑰鑰匙圈: %s\n"
 
@@ -2397,18 +2285,14 @@ msgid "key %s: invalid self-signature on user ID \"%s\"\n"
 msgstr "金鑰 %s: 使用者 ID \"%s\" 的自我簽章無效\n"
 
 #, c-format
-msgid "key %s: unsupported public key algorithm\n"
-msgstr "金鑰 %s: 未支援的公鑰演算法\n"
-
-#, c-format
-msgid "key %s: invalid direct key signature\n"
-msgstr "金鑰 %s: 無效的直接金鑰簽章\n"
-
-#, c-format
 msgid "key %s: no subkey for key binding\n"
 msgstr "金鑰 %s: 沒有可供附帶的子鑰\n"
 
 #, c-format
+msgid "key %s: unsupported public key algorithm\n"
+msgstr "金鑰 %s: 未支援的公鑰演算法\n"
+
+#, c-format
 msgid "key %s: invalid subkey binding\n"
 msgstr "金鑰 %s: 無效的附帶子鑰\n"
 
@@ -2490,15 +2374,15 @@ msgid "NOTE: secondary key is online and stored on card\n"
 msgstr "請注意: 子鑰在線上且已存放於卡片上了\n"
 
 #, c-format
-msgid "error creating keyring `%s': %s\n"
+msgid "error creating keyring '%s': %s\n"
 msgstr "建立 `%s' 鑰匙圈時出錯: %s\n"
 
 #, c-format
-msgid "keyring `%s' created\n"
+msgid "keyring '%s' created\n"
 msgstr "`%s' 鑰匙圈已建立\n"
 
 #, c-format
-msgid "keyblock resource `%s': %s\n"
+msgid "keyblock resource '%s': %s\n"
 msgstr "`%s' 金鑰區塊資源: %s\n"
 
 #, c-format
@@ -2683,7 +2567,7 @@ msgstr "   (2) 我隨意檢查過了.%s\n"
 msgid "   (3) I have done very careful checking.%s\n"
 msgstr "   (3) 我非常小心地檢查過了.%s\n"
 
-msgid "Your selection? (enter `?' for more information): "
+msgid "Your selection? (enter '?' for more information): "
 msgstr "你的選擇是? (輸入 `?' 以取得更多資訊): "
 
 #, c-format
@@ -2914,7 +2798,7 @@ msgid "Hint: Select the user IDs to sign\n"
 msgstr "提示: 選擇使用者 ID 來加以簽署\n"
 
 #, c-format
-msgid "Unknown signature type `%s'\n"
+msgid "Unknown signature type '%s'\n"
 msgstr "未知的 `%s' 簽章種類\n"
 
 #, c-format
@@ -2945,11 +2829,11 @@ msgid "Command expects a filename argument\n"
 msgstr "這項指令要拿一個檔名來當作引數\n"
 
 #, c-format
-msgid "Can't open `%s': %s\n"
+msgid "Can't open '%s': %s\n"
 msgstr "無法開啟 `%s': %s\n"
 
 #, c-format
-msgid "Error reading backup key from `%s': %s\n"
+msgid "Error reading backup key from '%s': %s\n"
 msgstr "從 `%s' 讀取備份金鑰時出錯: %s\n"
 
 msgid "You must select at least one key.\n"
@@ -3024,8 +2908,8 @@ msgid "There are no preferences on a PGP 2.x-style user ID.\n"
 msgstr "PGP 2.x 型態的使用者 ID 沒有偏好設定.\n"
 
 #, c-format
-msgid "The following key was revoked on %s by %s key %s\n"
-msgstr "下列金鑰已經在 %s 時被 %s 金鑰 %s 所撤銷\n"
+msgid "This key was revoked on %s by %s key %s\n"
+msgstr "這把金鑰已經在 %s 時被 %s 金鑰 %s 所撤銷\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
@@ -3090,14 +2974,6 @@ msgstr ""
 "警告: 沒有任何使用者 ID 被標示為主要 ID. 這項指令可能會\n"
 "      導致不同的使用者 ID 被當成主要 ID.\n"
 
-msgid "WARNING: Your encryption subkey expires soon.\n"
-msgstr ""
-
-#, fuzzy
-#| msgid "You can't change the expiration date of a v3 key\n"
-msgid "You may want to change its expiration date too.\n"
-msgstr "你不能變更 v3 金鑰的使用期限\n"
-
 msgid ""
 "WARNING: This is a PGP2-style key.  Adding a photo ID may cause some "
 "versions\n"
@@ -3273,7 +3149,7 @@ msgid "Create a revocation certificate for this signature? (y/N) "
 msgstr "要為這份簽章建立一份撤銷憑證嗎? (y/N) "
 
 msgid "Not signed by you.\n"
-msgstr "並非由你所簽署.\n"
+msgstr ""
 
 #, c-format
 msgid "You have signed these user IDs on key %s:\n"
@@ -3316,7 +3192,7 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
 msgstr "正在顯示 %s 照片 ID, 其尺寸為 %ld, 屬於金鑰 %s (uid %d) 的照片\n"
 
 #, c-format
-msgid "preference `%s' duplicated\n"
+msgid "preference '%s' duplicated\n"
 msgstr "偏好設定 `%s' 重複了\n"
 
 msgid "too many cipher preferences\n"
@@ -3329,7 +3205,7 @@ msgid "too many compression preferences\n"
 msgstr "壓縮偏好過多\n"
 
 #, c-format
-msgid "invalid item `%s' in preference string\n"
+msgid "invalid item '%s' in preference string\n"
 msgstr "偏好字串中含有無效的 `%s' 項目\n"
 
 msgid "writing direct signature\n"
@@ -3568,7 +3444,7 @@ msgid "Invalid character in comment\n"
 msgstr "註釋含有無效的字符\n"
 
 #, c-format
-msgid "You are using the `%s' character set.\n"
+msgid "You are using the '%s' character set.\n"
 msgstr "你正在使用 `%s' 字元集.\n"
 
 #, c-format
@@ -3585,7 +3461,7 @@ msgid "Please don't put the email address into the real name or the comment\n"
 msgstr "請不要把電子郵件地址放進你的真實姓名或註釋裡\n"
 
 msgid "Such a user ID already exists on this key!\n"
-msgstr "這把金鑰上已經有這樣子的使用者 ID 了!\n"
+msgstr ""
 
 #. TRANSLATORS: These are the allowed answers in
 #. lower and uppercase.  Below you will find the matching
@@ -3651,15 +3527,15 @@ msgid "Key generation canceled.\n"
 msgstr "金鑰產生已取消.\n"
 
 #, c-format
-msgid "writing public key to `%s'\n"
+msgid "writing public key to '%s'\n"
 msgstr "正在寫入公鑰至 `%s'\n"
 
 #, c-format
-msgid "writing secret key stub to `%s'\n"
+msgid "writing secret key stub to '%s'\n"
 msgstr "正在寫入私鑰 stub 至 `%s'\n"
 
 #, c-format
-msgid "writing secret key to `%s'\n"
+msgid "writing secret key to '%s'\n"
 msgstr "正在寫入私鑰至 `%s'\n"
 
 #, c-format
@@ -3671,11 +3547,11 @@ msgid "no writable secret keyring found: %s\n"
 msgstr "找不到可寫入的私鑰鑰匙圈: %s\n"
 
 #, c-format
-msgid "error writing public keyring `%s': %s\n"
+msgid "error writing public keyring '%s': %s\n"
 msgstr "寫入公鑰鑰匙圈 `%s' 時出錯: %s\n"
 
 #, c-format
-msgid "error writing secret keyring `%s': %s\n"
+msgid "error writing secret keyring '%s': %s\n"
 msgstr "寫入私鑰鑰匙圈 `%s' 時出錯: %s\n"
 
 msgid "public and secret key created and signed.\n"
@@ -3713,11 +3589,11 @@ msgid "storing key onto card failed: %s\n"
 msgstr "儲存金鑰到卡片上時失敗: %s\n"
 
 #, c-format
-msgid "can't create backup file `%s': %s\n"
+msgid "can't create backup file '%s': %s\n"
 msgstr "無法建立備份檔案 `%s': %s\n"
 
 #, c-format
-msgid "NOTE: backup of card key saved to `%s'\n"
+msgid "NOTE: backup of card key saved to '%s'\n"
 msgstr "請注意: 卡片金鑰的備份已儲存至 `%s'\n"
 
 msgid "never     "
@@ -3759,16 +3635,11 @@ msgstr "                子鑰指紋:"
 msgid "      Key fingerprint ="
 msgstr "      金鑰指紋 ="
 
-#, fuzzy, c-format
-#| msgid "WARNING: using experimental digest algorithm %s\n"
-msgid "WARNING: a PGP-2 fingerprint is not safe\n"
-msgstr "警告: 正在使用實驗性的 %s 摘要演算法\n"
-
 msgid "      Card serial no. ="
 msgstr "      卡片序號 ="
 
 #, c-format
-msgid "renaming `%s' to `%s' failed: %s\n"
+msgid "renaming '%s' to '%s' failed: %s\n"
 msgstr "把 `%s' 重新新命成 `%s' 時失敗: %s\n"
 
 msgid "WARNING: 2 files with confidential information exists.\n"
@@ -3786,7 +3657,7 @@ msgid "Please fix this possible security flaw\n"
 msgstr "請修補這個可能的安全漏洞\n"
 
 #, c-format
-msgid "caching keyring `%s'\n"
+msgid "caching keyring '%s'\n"
 msgstr "快取鑰匙圈 `%s' 中\n"
 
 #, c-format
@@ -3823,7 +3694,7 @@ msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "取回金鑰時尊重金鑰所設定的 PKA 記錄"
 
 #, c-format
-msgid "WARNING: keyserver option `%s' is not used on this platform\n"
+msgid "WARNING: keyserver option '%s' is not used on this platform\n"
 msgstr "警告: 金鑰伺服器選項 `%s' 並未用於此平台\n"
 
 msgid "disabled"
@@ -3885,10 +3756,6 @@ msgstr "警告: 金鑰伺服器經手程式係來自不同版本的 GnuPG (%s)\n
 msgid "keyserver did not send VERSION\n"
 msgstr "金鑰伺服器並未送出版本 (VERSION)\n"
 
-#, c-format
-msgid "keyserver communications error: %s\n"
-msgstr "金鑰伺服器通訊錯誤: %s\n"
-
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "沒有已知的金鑰伺服器 (使用 --keyserver 選項)\n"
 
@@ -3896,11 +3763,11 @@ msgid "external keyserver calls are not supported in this build\n"
 msgstr "本版並不支援外部金鑰伺服器叫用\n"
 
 #, c-format
-msgid "no handler for keyserver scheme `%s'\n"
+msgid "no handler for keyserver scheme '%s'\n"
 msgstr "沒有 `%s' 金鑰伺服器架構的經手程式\n"
 
 #, c-format
-msgid "action `%s' not supported with keyserver scheme `%s'\n"
+msgid "action '%s' not supported with keyserver scheme '%s'\n"
 msgstr "`%s' 動作在 `%s' 金鑰伺服器架構中未支援\n"
 
 #, c-format
@@ -3914,6 +3781,10 @@ msgid "keyserver internal error\n"
 msgstr "金鑰伺服器內部錯誤\n"
 
 #, c-format
+msgid "keyserver communications error: %s\n"
+msgstr "金鑰伺服器通訊錯誤: %s\n"
+
+#, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "\"%s\" 並非金鑰 ID: 跳過中\n"
 
@@ -3998,7 +3869,7 @@ msgstr "警告: 加密過的訊息已經被變造了!\n"
 
 #, c-format
 msgid "cleared passphrase cached with ID: %s\n"
-msgstr "清除此 ID 被快取住的密語: %s\n"
+msgstr ""
 
 #, c-format
 msgid "decryption failed: %s\n"
@@ -4082,10 +3953,6 @@ msgid "unknown"
 msgstr "未知"
 
 #, c-format
-msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n"
-msgstr "警告: 並非分離簽章; '%s' 檔案 *沒有* 通過驗證!\n"
-
-#, c-format
 msgid "Can't check signature: %s\n"
 msgstr "無法檢查簽章: %s\n"
 
@@ -4107,7 +3974,7 @@ msgid "invalid root packet detected in proc_tree()\n"
 msgstr "在 proc_tree() 中偵測到無效的 root 封包\n"
 
 #, c-format
-msgid "fstat of `%s' failed in %s: %s\n"
+msgid "fstat of '%s' failed in %s: %s\n"
 msgstr "`%s' 的 fstat 失敗於 %s: %s\n"
 
 #, c-format
@@ -4133,10 +4000,6 @@ msgstr "警告: 正在使用實驗性的 %s 摘要演算法\n"
 msgid "WARNING: digest algorithm %s is deprecated\n"
 msgstr "警告: 已不建議使用 %s 摘要演算法\n"
 
-#, c-format
-msgid "Note: signatures using the %s algorithm are rejected\n"
-msgstr "注意: 採用 %s 演算法的簽章已駁回\n"
-
 msgid "the IDEA cipher plugin is not present\n"
 msgstr "IDEA 編密法外掛模組不存在\n"
 
@@ -4168,15 +4031,6 @@ msgstr "%s:%u: 廢棄的 \"%s\" 選項 - 沒有任何影響\n"
 msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
 msgstr "警告: \"%s\" 是已廢棄的選項 - 沒有效果\n"
 
-#, c-format
-msgid "%s:%u: \"%s%s\" is obsolete in this file - it only has effect in %s\n"
-msgstr "%s:%u: \"%s%s\" 在此檔案中已廢棄 - 僅對 %s 造成影響\n"
-
-#, c-format
-msgid ""
-"WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n"
-msgstr "警告: \"%s%s\" 是已廢棄的選項 - 除了對 %s 之外沒有效果\n"
-
 msgid "Uncompressed"
 msgstr "未壓縮"
 
@@ -4189,15 +4043,15 @@ msgid "this message may not be usable by %s\n"
 msgstr "這個訊息對 %s 來說無法使用\n"
 
 #, c-format
-msgid "ambiguous option `%s'\n"
+msgid "ambiguous option '%s'\n"
 msgstr "不明確的 `%s' 選項\n"
 
 #, c-format
-msgid "unknown option `%s'\n"
+msgid "unknown option '%s'\n"
 msgstr "未知的 `%s' 選項\n"
 
 #, c-format
-msgid "File `%s' exists. "
+msgid "File '%s' exists. "
 msgstr "檔案 `%s' 已存在. "
 
 msgid "Overwrite? (y/N) "
@@ -4215,14 +4069,14 @@ msgstr "寫到標準輸出中\n"
 
 #, c-format
 msgid "assuming signed data in '%s'\n"
-msgstr "假設被簽署的資料在 '%s'\n"
+msgstr "假設被簽署的資料在 `%s'\n"
 
 #, c-format
-msgid "new configuration file `%s' created\n"
+msgid "new configuration file '%s' created\n"
 msgstr "新的設定檔 `%s' 被建立了\n"
 
 #, c-format
-msgid "WARNING: options in `%s' are not yet active during this run\n"
+msgid "WARNING: options in '%s' are not yet active during this run\n"
 msgstr "警告: 在 `%s' 裡的選項於這次執行期間並沒有被啟用\n"
 
 #, c-format
@@ -4237,10 +4091,6 @@ msgid "subpacket of type %d has critical bit set\n"
 msgstr "%d 類別的子封包設定了關鍵位元\n"
 
 #, c-format
-msgid "problem with the agent: %s\n"
-msgstr "代理程式的問題: %s\n"
-
-#, c-format
 msgid " (main key ID %s)"
 msgstr " (主要金鑰 ID %s)"
 
@@ -4264,6 +4114,10 @@ msgid "cancelled by user\n"
 msgstr "由使用者所取消\n"
 
 #, c-format
+msgid "problem with the agent: %s\n"
+msgstr "代理程式的問題: %s\n"
+
+#, c-format
 msgid ""
 "You need a passphrase to unlock the secret key for\n"
 "user: \"%s\"\n"
@@ -4296,7 +4150,7 @@ msgid "Enter JPEG filename for photo ID: "
 msgstr "輸入要當作照片 ID 的 JPEG 檔名: "
 
 #, c-format
-msgid "unable to open JPEG file `%s': %s\n"
+msgid "unable to open JPEG file '%s': %s\n"
 msgstr "無法開啟 JPEG 圖檔 `%s': %s\n"
 
 #, c-format
@@ -4307,7 +4161,7 @@ msgid "Are you sure you want to use it? (y/N) "
 msgstr "你確定要用它嗎? (y/N) "
 
 #, c-format
-msgid "`%s' is not a JPEG file\n"
+msgid "'%s' is not a JPEG file\n"
 msgstr "`%s' 不是一個 JPEG 圖檔\n"
 
 msgid "Is this photo correct (y/N/q)? "
@@ -4338,16 +4192,6 @@ msgid "revocation comment: "
 msgstr "撤銷註釋: "
 
 #  a string with valid answers
-#. TRANSLATORS: These are the allowed answers in lower and
-#. uppercase.  Below you will find the matching strings which
-#. should be translated accordingly and the letter changed to
-#. match the one in the answer string.
-#.
-#. i = please show me more information
-#. m = back to the main menu
-#. s = skip this key
-#. q = quit
-#.
 msgid "iImMqQsS"
 msgstr "iImMqQsS"
 
@@ -4448,11 +4292,11 @@ msgid "Note: This key has been disabled.\n"
 msgstr "請注意: 這把金鑰已停用.\n"
 
 #, c-format
-msgid "Note: Verified signer's address is `%s'\n"
+msgid "Note: Verified signer's address is '%s'\n"
 msgstr "請注意: 已驗證的簽署者地址為 `%s'\n"
 
 #, c-format
-msgid "Note: Signer's address `%s' does not match DNS entry\n"
+msgid "Note: Signer's address '%s' does not match DNS entry\n"
 msgstr "請注意: 簽署者地址 `%s' 與 DNS 項目並不吻合\n"
 
 msgid "trustlevel adjusted to FULL due to valid PKA info\n"
@@ -4552,7 +4396,7 @@ msgid "no signed data\n"
 msgstr "沒有被簽署過的資料\n"
 
 #, c-format
-msgid "can't open signed data `%s'\n"
+msgid "can't open signed data '%s'\n"
 msgstr "無法開啟被簽署過的資料 `%s'\n"
 
 #, c-format
@@ -4838,7 +4682,7 @@ msgstr ""
 "# (請用 \"gpg --import-ownertrust\" 來取回它們)\n"
 
 #, c-format
-msgid "error in `%s': %s\n"
+msgid "error in '%s': %s\n"
 msgstr "在 `%s' 中出錯: %s\n"
 
 msgid "line too long"
@@ -4854,11 +4698,11 @@ msgid "ownertrust value missing"
 msgstr "主觀信任值缺漏"
 
 #, c-format
-msgid "error finding trust record in `%s': %s\n"
+msgid "error finding trust record in '%s': %s\n"
 msgstr "在 `%s' 中尋找信任記錄時出錯: %s\n"
 
 #, c-format
-msgid "read error in `%s': %s\n"
+msgid "read error in '%s': %s\n"
 msgstr "讀取 `%s' 錯誤: %s\n"
 
 #, c-format
@@ -4866,14 +4710,6 @@ msgid "trustdb: sync failed: %s\n"
 msgstr "信任資料庫: 同步化失敗: %s\n"
 
 #, c-format
-msgid "can't create lock for `%s'\n"
-msgstr "無法為 `%s' 建立鎖定\n"
-
-#, c-format
-msgid "can't lock `%s'\n"
-msgstr "無法鎖定 `%s'\n"
-
-#, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "信任資料庫記錄 %lu: 本機搜尋失敗: %s\n"
 
@@ -4885,12 +4721,20 @@ msgid "trustdb transaction too large\n"
 msgstr "信任資料庫更動量過大\n"
 
 #, c-format
+msgid "can't access '%s': %s\n"
+msgstr "無法存取 `%s': %s\n"
+
+#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: 目錄不存在!\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "無法存取 `%s': %s\n"
+msgid "can't create lock for '%s'\n"
+msgstr "無法為 `%s' 建立鎖定\n"
+
+#, c-format
+msgid "can't lock '%s'\n"
+msgstr "無法鎖定 `%s'\n"
 
 #, c-format
 msgid "%s: failed to create version record: %s"
@@ -4963,8 +4807,9 @@ msgstr "%s: 記錄歸零失敗: %s\n"
 msgid "%s: failed to append a record: %s\n"
 msgstr "%s: 附加記錄失敗: %s\n"
 
+#, fuzzy
 msgid "Error: The trustdb is corrupted.\n"
-msgstr "錯誤: 信任資料庫已毀損.\n"
+msgstr "%s: 建立了信任資料庫\n"
 
 #, c-format
 msgid "can't handle text lines longer than %d characters\n"
@@ -4975,7 +4820,7 @@ msgid "input line longer than %d characters\n"
 msgstr "輸入列比 %d 字符還長\n"
 
 #, c-format
-msgid "`%s' is not a valid long keyID\n"
+msgid "'%s' is not a valid long keyID\n"
 msgstr "`%s' 不是一個有效的長式金鑰 ID\n"
 
 #, c-format
@@ -5003,10 +4848,10 @@ msgid "trust record %lu is not of requested type %d\n"
 msgstr "信任記錄 %lu 不是所請求的類別 %d\n"
 
 msgid "You may try to re-create the trustdb using the commands:\n"
-msgstr "你可以試著用下列指令來重建信任資料庫:\n"
+msgstr ""
 
 msgid "If that does not work, please consult the manual\n"
-msgstr "如果行不通的話, 請查閱手冊\n"
+msgstr ""
 
 #, c-format
 msgid "unable to use unknown trust model (%d) - assuming %s trust model\n"
@@ -5016,14 +4861,6 @@ msgstr "無法使用未知的信任模型 (%d) - 現在採用 %s 信任模型\n"
 msgid "using %s trust model\n"
 msgstr "正在使用 %s 信任模型\n"
 
-#. TRANSLATORS: these strings are similar to those in
-#. trust_value_to_string(), but are a fixed length.  This is needed to
-#. make attractive information listings where columns line up
-#. properly.  The value "10" should be the length of the strings you
-#. choose to translate to.  This is the length in printable columns.
-#. It gets passed to atoi() so everything after the number is
-#. essentially a comment and need not be translated.  Either key and
-#. uid are both NULL, or neither are NULL.
 msgid "10 translator see trustdb.c:uid_trust_string_fixed"
 msgstr "10 譯者請參見 trustdb.c:uid_trust_string_fixed"
 
@@ -5071,11 +4908,11 @@ msgid "next trustdb check due at %s\n"
 msgstr "下次信任資料庫檢查將於 %s 進行\n"
 
 #, c-format
-msgid "no need for a trustdb check with `%s' trust model\n"
+msgid "no need for a trustdb check with '%s' trust model\n"
 msgstr "在 `%s' 信任模型中並不需要檢查信任資料庫\n"
 
 #, c-format
-msgid "no need for a trustdb update with `%s' trust model\n"
+msgid "no need for a trustdb update with '%s' trust model\n"
 msgstr "在 `%s' 信任模型中並不需要更新信任資料庫\n"
 
 #, c-format
@@ -5141,11 +4978,6 @@ msgstr "關鍵字太長"
 msgid "missing argument"
 msgstr "無效的引數"
 
-#, fuzzy
-#| msgid "invalid armor"
-msgid "invalid argument"
-msgstr "無效的封裝"
-
 msgid "invalid command"
 msgstr "無效的指令"
 
@@ -5162,11 +4994,6 @@ msgstr "無效的選項"
 msgid "missing argument for option \"%.50s\"\n"
 msgstr "\"%.50s\" 選項遺失了引數\n"
 
-#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid argument for option \"%.50s\"\n"
-msgstr "\"%.50s\" 選項遺失了引數\n"
-
 #, c-format
 msgid "option \"%.50s\" does not expect an argument\n"
 msgstr "\"%.50s\" 選項沒料到會有引數\n"
@@ -5195,7 +5022,11 @@ msgid "you found a bug ... (%s:%d)\n"
 msgstr "你找到一個瑕疵了 ... (%s:%d)\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' not available\n"
+msgid "error loading '%s': %s\n"
+msgstr "載入 `%s' 時出錯: %s\n"
+
+#, c-format
+msgid "conversion from '%s' to '%s' not available\n"
 msgstr "沒有從 `%s' 到 `%s' 之間的轉換可用\n"
 
 #, c-format
@@ -5203,15 +5034,15 @@ msgid "iconv_open failed: %s\n"
 msgstr "iconv_open 失敗: %s\n"
 
 #, c-format
-msgid "conversion from `%s' to `%s' failed: %s\n"
+msgid "conversion from '%s' to '%s' failed: %s\n"
 msgstr "從 `%s' 轉換成 `%s' 失敗: %s\n"
 
 #, c-format
-msgid "failed to create temporary file `%s': %s\n"
+msgid "failed to create temporary file '%s': %s\n"
 msgstr "無法建立暫存檔 `%s': %s\n"
 
 #, c-format
-msgid "error writing to `%s': %s\n"
+msgid "error writing to '%s': %s\n"
 msgstr "寫入 %s 時出錯: %s\n"
 
 #, c-format
@@ -5229,7 +5060,7 @@ msgid "(deadlock?) "
 msgstr "(死結嗎?) "
 
 #, c-format
-msgid "lock `%s' not made: %s\n"
+msgid "lock '%s' not made: %s\n"
 msgstr "未鎖定 `%s': %s\n"
 
 #, c-format
@@ -5247,7 +5078,7 @@ msgstr "用法: kbxutil [選項] [檔案] (或用 -h 求助)"
 
 msgid ""
 "Syntax: kbxutil [options] [files]\n"
-"List, export, import Keybox data\n"
+"list, export, import Keybox data\n"
 msgstr ""
 "語法: kbxutil [選項] [檔案]\n"
 "列出, 匯出, 匯入金鑰鑰匙盒資料\n"
@@ -5372,9 +5203,6 @@ msgstr "||請輸入卡片的重設碼"
 msgid "Reset Code is too short; minimum length is %d\n"
 msgstr "重設碼太短; 長度最少要有 %d\n"
 
-#. TRANSLATORS: Do not translate the "|*|" prefixes but
-#. keep it at the start of the string.  We need this elsewhere
-#. to get some infos on the string.
 msgid "|RN|New Reset Code"
 msgstr "|RN|新增重設碼"
 
@@ -5384,12 +5212,6 @@ msgstr "|AN|新增管理者個人識別碼 (PIN)"
 msgid "|N|New PIN"
 msgstr "|N|新增個人識別碼 (PIN)"
 
-msgid "||Please enter the Admin PIN and New Admin PIN"
-msgstr "||請輸入管理者 PIN 及新的管理者 PIN"
-
-msgid "||Please enter the PIN and New PIN"
-msgstr "||請輸入個人識別碼及新的個人識別碼 (PIN)"
-
 msgid "error reading application data\n"
 msgstr "讀取應用程式資料時出錯\n"
 
@@ -5405,8 +5227,9 @@ msgstr "既有的金鑰將被取代\n"
 msgid "generating new key\n"
 msgstr "正在產生新的金鑰\n"
 
+#, fuzzy
 msgid "writing new key\n"
-msgstr "正在寫入新的金鑰\n"
+msgstr "正在產生新的金鑰\n"
 
 msgid "creation timestamp missing\n"
 msgstr "缺漏創生時間戳印\n"
@@ -5451,7 +5274,7 @@ msgstr "目前在此指令中的管理者 PIN 驗證被禁止了\n"
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "無法存取 %s - 無效的 OpenPGP 卡片?\n"
 
-msgid "||Please enter your PIN at the reader's pinpad"
+msgid "||Please enter your PIN at the reader's keypad"
 msgstr "||請在讀卡機鍵盤上輸入你的個人識別碼 (PIN)"
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
@@ -5464,19 +5287,19 @@ msgid "run in multi server mode (foreground)"
 msgstr "以多重伺服器模式執行 (前景)"
 
 msgid "|LEVEL|set the debugging level to LEVEL"
-msgstr "|等級|設定除錯等級為指定等級"
+msgstr "|等級|設定除錯等級為「等級」"
 
 msgid "|FILE|write a log to FILE"
-msgstr "|檔案|將日誌寫入至指定檔案"
+msgstr "|檔案|將日誌寫入至「檔案」"
 
 msgid "|N|connect to reader at port N"
 msgstr "|N|從 N 埠連線至讀卡機"
 
 msgid "|NAME|use NAME as ct-API driver"
-msgstr "|名稱|使用指定名稱做為 ct-API 驅動程式"
+msgstr "|名稱|使用「名稱」做為 ct-API 驅動程式"
 
 msgid "|NAME|use NAME as PC/SC driver"
-msgstr "|名稱|使用指定名稱做為 PC/SC 驅動程式"
+msgstr "|名稱|使用「名稱」做為 PC/SC 驅動程式"
 
 msgid "do not use the internal CCID driver"
 msgstr "不要使用內部的 CCID 驅動程式"
@@ -5484,15 +5307,12 @@ msgstr "不要使用內部的 CCID 驅動程式"
 msgid "|N|disconnect the card after N seconds of inactivity"
 msgstr "|N|沒有活動達 N 秒後就與卡片斷線"
 
-msgid "do not use a reader's pinpad"
+msgid "do not use a reader's keypad"
 msgstr "不要使用讀卡機鍵盤"
 
 msgid "deny the use of admin card commands"
 msgstr "禁用管理者卡片指令"
 
-msgid "use variable length input for pinpad"
-msgstr "輸入 PIN 時在輸入區顯示成變動長度"
-
 msgid "Usage: scdaemon [options] (-h for help)"
 msgstr "用法: scdaemon [選項] (或用 -h 求助)"
 
@@ -5503,7 +5323,7 @@ msgstr ""
 "語法: scdaemon [選項] [指令 [引數]]\n"
 "GnuPg 智慧卡服務\n"
 
-msgid "please use the option `--daemon' to run the program in the background\n"
+msgid "please use the option '--daemon' to run the program in the background\n"
 msgstr "請使用 `--daemon' 選項來將此程式執行於背景\n"
 
 #, c-format
@@ -5523,11 +5343,11 @@ msgid "failed to proxy %s inquiry to client\n"
 msgstr "以 %s 代理伺服器查詢用戶端時失敗\n"
 
 #, c-format
-msgid "no running dirmngr - starting `%s'\n"
+msgid "no running dirmngr - starting '%s'\n"
 msgstr "沒有執行中的 dirmngr - 正在啟動 `%s'\n"
 
 msgid "malformed DIRMNGR_INFO environment variable\n"
-msgstr "格式不對的 DIRMNGR_INFO 環境變數\n"
+msgstr "被變造的 DIRMNGR_INFO 環境變數\n"
 
 #, c-format
 msgid "dirmngr protocol version %d is not supported\n"
@@ -5548,7 +5368,7 @@ msgstr "shell"
 
 #, c-format
 msgid "critical certificate extension %s is not supported"
-msgstr "未支援關鍵憑證擴充欄位 %s"
+msgstr "未支援關鍵憑證延伸 %s"
 
 msgid "issuer certificate is not marked as a CA"
 msgstr "發行者憑證並未標記為 CA"
@@ -5557,7 +5377,7 @@ msgid "critical marked policy without configured policies"
 msgstr "關鍵已標記原則沒有已組態的原則"
 
 #, c-format
-msgid "failed to open `%s': %s\n"
+msgid "failed to open '%s': %s\n"
 msgstr "開啟 `%s' 失敗: %s\n"
 
 msgid "note: non-critical certificate policy not allowed"
@@ -5584,7 +5404,7 @@ msgstr "吻合的憑證數量: %d\n"
 msgid "dirmngr cache-only key lookup failed: %s\n"
 msgstr "尋找限於 dirmngr 快取的金鑰時失敗: %s\n"
 
-msgid "failed to allocate keyDB handle\n"
+msgid "failed to allocated keyDB handle\n"
 msgstr "配置 keyDB handle 失敗\n"
 
 msgid "certificate has been revoked"
@@ -5757,16 +5577,16 @@ msgstr "沒有指定的金鑰用途 - 假設為所有的用途\n"
 msgid "error getting key usage information: %s\n"
 msgstr "取得金鑰用途資訊時出錯: %s\n"
 
-msgid "certificate should not have been used for certification\n"
+msgid "certificate should have not been used for certification\n"
 msgstr "憑證應該還未被用於憑證\n"
 
-msgid "certificate should not have been used for OCSP response signing\n"
+msgid "certificate should have not been used for OCSP response signing\n"
 msgstr "憑證應該還未被用於 OCSP 回應簽署\n"
 
-msgid "certificate should not have been used for encryption\n"
+msgid "certificate should have not been used for encryption\n"
 msgstr "憑證應該還未被用於加密\n"
 
-msgid "certificate should not have been used for signing\n"
+msgid "certificate should have not been used for signing\n"
 msgstr "憑證應該還未被用於簽署\n"
 
 msgid "certificate is not usable for encryption\n"
@@ -5788,11 +5608,11 @@ msgid "line %d: no subject name given\n"
 msgstr "第 %d 列: 沒有給定的物件名稱\n"
 
 #, c-format
-msgid "line %d: invalid subject name label `%.*s'\n"
+msgid "line %d: invalid subject name label '%.*s'\n"
 msgstr "第 %d 列: 無效的物件名稱標籤 `%.*s'\n"
 
 #, c-format
-msgid "line %d: invalid subject name `%s' at pos %d\n"
+msgid "line %d: invalid subject name '%s' at pos %d\n"
 msgstr "第 %d 列: 無效的物件名稱 `%s'  於 pos %d\n"
 
 #, c-format
@@ -5800,11 +5620,11 @@ msgid "line %d: not a valid email address\n"
 msgstr "第 %d 列: 不是有效的電子郵件地址\n"
 
 #, c-format
-msgid "line %d: error reading key `%s' from card: %s\n"
+msgid "line %d: error reading key '%s' from card: %s\n"
 msgstr "第 %d 列: 從卡片讀取金鑰 `%s' 時出錯: %s\n"
 
 #, c-format
-msgid "line %d: error getting key by keygrip `%s': %s\n"
+msgid "line %d: error getting key by keygrip '%s': %s\n"
 msgstr "第 %d 列: 以金鑰鑰柄 `%s' 取得金鑰時出錯: %s\n"
 
 #, c-format
@@ -5828,25 +5648,28 @@ msgstr "   (%d) 現有的金鑰\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) 卡片上現存的金鑰\n"
 
+#, fuzzy
 msgid "Enter the keygrip: "
-msgstr "請輸入金鑰鑰柄: "
+msgstr "請輸入註記: "
 
 msgid "Not a valid keygrip (expecting 40 hex digits)\n"
-msgstr "不是有效的金鑰鑰柄 (應該要是 40 位十六進制數值)\n"
+msgstr ""
 
+#, fuzzy
 msgid "No key with this keygrip\n"
-msgstr "沒有金鑰有此金鑰鑰柄\n"
+msgstr "索引 %d 沒有對應到子鑰\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "error reading the card: %s\n"
-msgstr "讀取卡片時出錯: %s\n"
+msgstr "%s: 讀取可用空間記錄時出錯: %s\n"
 
-#, c-format
+#, fuzzy, c-format
 msgid "Serial number of the card: %s\n"
-msgstr "å\8d¡ç\89\87åº\8fè\99\9f: %s\n"
+msgstr "å\8f\96å¾\97æ­¤å\8d¡ç\89\87åº\8fè\99\9fæ\99\82å\87ºé\8c¯: %s\n"
 
+#, fuzzy
 msgid "Available keys:\n"
-msgstr "å\8f¯ç\94¨é\87\91é\91°:\n"
+msgstr "å\81\9cç\94¨é\87\91é\91°"
 
 #, c-format
 msgid "Possible actions for a %s key:\n"
@@ -5871,7 +5694,7 @@ msgid "No subject name given\n"
 msgstr "沒有給定的物件名稱\n"
 
 #, c-format
-msgid "Invalid subject name label `%.*s'\n"
+msgid "Invalid subject name label '%.*s'\n"
 msgstr "無效的物件名稱標籤 `%.*s'\n"
 
 #. TRANSLATORS: The 22 in the second string is the
@@ -5880,7 +5703,7 @@ msgstr "無效的物件名稱標籤 `%.*s'\n"
 #. second string is merely passed to atoi so you can
 #. drop everything after the number.
 #, c-format
-msgid "Invalid subject name `%s'\n"
+msgid "Invalid subject name '%s'\n"
 msgstr "無效的物件名稱 `%s'\n"
 
 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty"
@@ -5920,7 +5743,7 @@ msgid "(this does not seem to be an encrypted message)\n"
 msgstr "(這看起來不像是個加密過的訊息)\n"
 
 #, c-format
-msgid "certificate `%s' not found: %s\n"
+msgid "certificate '%s' not found: %s\n"
 msgstr "找不到憑證 `%s': %s\n"
 
 #, c-format
@@ -5928,11 +5751,11 @@ msgid "error locking keybox: %s\n"
 msgstr "鎖住金鑰鑰匙盒時出錯: %s\n"
 
 #, c-format
-msgid "duplicated certificate `%s' deleted\n"
+msgid "duplicated certificate '%s' deleted\n"
 msgstr "重複的 `%s' 憑證已刪除\n"
 
 #, c-format
-msgid "certificate `%s' deleted\n"
+msgid "certificate '%s' deleted\n"
 msgstr "憑證 `%s' 已刪除\n"
 
 #, c-format
@@ -5963,6 +5786,9 @@ msgstr "將指令遞送給 dirmngr"
 msgid "invoke gpg-protect-tool"
 msgstr "叫用 gpg-protect-tool"
 
+msgid "change a passphrase"
+msgstr "更改密語"
+
 msgid "create base-64 encoded output"
 msgstr "建立以 base-64 編碼過的輸出"
 
@@ -5988,7 +5814,7 @@ msgid "|N|number of certificates to include"
 msgstr "|N|要包含的憑證數量"
 
 msgid "|FILE|take policy information from FILE"
-msgstr "|檔案|從指定檔案中取得原則資訊"
+msgstr "|檔案|從「檔案」中取得原則資訊"
 
 msgid "do not check certificate policies"
 msgstr "不要檢查憑證原則"
@@ -6000,10 +5826,10 @@ msgid "don't use the terminal at all"
 msgstr "完全不要使用終端機"
 
 msgid "|FILE|write a server mode log to FILE"
-msgstr "|檔案|將伺服器模式日誌寫入至指定檔案"
+msgstr "|檔案|將伺服器模式日誌寫入至「檔案」"
 
 msgid "|FILE|write an audit log to FILE"
-msgstr "|檔案|將稽核日誌寫入至指定檔案"
+msgstr "|檔案|將稽核日誌寫入至「檔案」"
 
 msgid "batch mode: never ask"
 msgstr "批次模式: 永遠不詢問"
@@ -6015,27 +5841,27 @@ msgid "assume no on most questions"
 msgstr "假設大部分的問題都回答否"
 
 msgid "|FILE|add keyring to the list of keyrings"
-msgstr "|檔案|將此金鑰鑰匙圈加到金鑰鑰匙圈清單指定檔案中"
+msgstr "|檔案|將此金鑰鑰匙圈加到金鑰鑰匙圈清單「檔案」中"
 
 msgid "|USER-ID|use USER-ID as default secret key"
-msgstr "|使用者-ID|使用指定使用者 ID 做為預設私鑰"
+msgstr "|使用者-ID|使用「使用者-ID」做為預設私鑰"
 
 msgid "|SPEC|use this keyserver to lookup keys"
 msgstr "|SPEC|使用此金鑰伺服器來查找金鑰"
 
 msgid "|NAME|use cipher algorithm NAME"
-msgstr "|名稱|使用指定名稱的編密演算法"
+msgstr "|名稱|使用「名稱」編密演算法"
 
 msgid "|NAME|use message digest algorithm NAME"
-msgstr "|名稱|使用指定名稱的訊息摘要演算法"
+msgstr "|名稱|使用「名稱」訊息摘要演算法"
 
 msgid "Usage: gpgsm [options] [files] (-h for help)"
 msgstr "用法: gpgsm [選項] [檔案] (或用 -h 求助)"
 
 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"
+"sign, check, encrypt or decrypt using the S/MIME protocol\n"
+"default operation depends on the input data\n"
 msgstr ""
 "語法: gpgsm [選項] [檔案]\n"
 "用 S/MIME 協定來簽署, 檢查, 加密或解密\n"
@@ -6045,11 +5871,11 @@ msgid "usage: gpgsm [options] "
 msgstr "用法: gpgsm [選項] "
 
 #, c-format
-msgid "NOTE: won't be able to encrypt to `%s': %s\n"
+msgid "NOTE: won't be able to encrypt to '%s': %s\n"
 msgstr "請注意: 將無法加密為 `%s': %s\n"
 
 #, c-format
-msgid "unknown validation model `%s'\n"
+msgid "unknown validation model '%s'\n"
 msgstr "未知的驗證模型 `%s'\n"
 
 #, c-format
@@ -6071,11 +5897,11 @@ msgid "WARNING: running with faked system time: "
 msgstr "警告: 正在偽造的系統時間中執行: "
 
 #, c-format
-msgid "importing common certificates `%s'\n"
+msgid "importing common certificates '%s'\n"
 msgstr "正在匯入通用憑證 `%s'\n"
 
 #, c-format
-msgid "can't sign using `%s': %s\n"
+msgid "can't sign using '%s': %s\n"
 msgstr "無法用 `%s' 來簽署: %s\n"
 
 msgid "invalid command (there is no implicit command)\n"
@@ -6091,6 +5917,9 @@ msgstr "存放憑證時出錯\n"
 msgid "basic certificate checks failed - not imported\n"
 msgstr "基本的憑證檢查失敗了 - 未匯入\n"
 
+msgid "failed to allocate keyDB handle\n"
+msgstr "配置 keyDB handle 失敗\n"
+
 #, c-format
 msgid "error getting stored flags: %s\n"
 msgstr "取得已存放的旗標時出錯: %s\n"
@@ -6104,11 +5933,14 @@ msgid "error reading input: %s\n"
 msgstr "讀取輸入時出錯: %s\n"
 
 #, c-format
-msgid "error creating keybox `%s': %s\n"
+msgid "error creating keybox '%s': %s\n"
 msgstr "建立金鑰鑰匙盒 `%s' 時出錯: %s\n"
 
+msgid "you may want to start the gpg-agent first\n"
+msgstr "你可能會先想啟動 gpg-agent\n"
+
 #, c-format
-msgid "keybox `%s' created\n"
+msgid "keybox '%s' created\n"
 msgstr "`%s' 鑰匙盒已建立\n"
 
 msgid "failed to get the fingerprint\n"
@@ -6141,11 +5973,11 @@ msgid "GPG_TTY has not been set - using maybe bogus default\n"
 msgstr "尚未設定 GPG_TTY - 使用可能是偽造的預設值\n"
 
 #, c-format
-msgid "invalid formatted fingerprint in `%s', line %d\n"
+msgid "invalid formatted fingerprint in '%s', line %d\n"
 msgstr "無效的格式化指紋於 `%s', 第 %d 列\n"
 
 #, c-format
-msgid "invalid country code in `%s', line %d\n"
+msgid "invalid country code in '%s', line %d\n"
 msgstr "無效的國家代碼於 `%s', 第 %d 列\n"
 
 #, c-format
@@ -6223,7 +6055,7 @@ msgid "decode received data lines"
 msgstr "對已收到的資料列解碼"
 
 msgid "|NAME|connect to Assuan socket NAME"
-msgstr "|名稱|連線至指定名稱的 Assuan socket"
+msgstr "|名稱|連線至 Assuan socket「名稱」"
 
 msgid "run the Assuan server given on the command line"
 msgstr "執行命令列所給定的 Assuan 伺服器"
@@ -6232,7 +6064,7 @@ msgid "do not use extended connect mode"
 msgstr "不要使用延伸連線模式"
 
 msgid "|FILE|run commands from FILE on startup"
-msgstr "|檔案|啟動時執行指定檔案中的指令"
+msgstr "|檔案|啟動時執行「檔案」中的指令"
 
 msgid "run /subst on startup"
 msgstr "啟動時執行 /subst"
@@ -6266,7 +6098,7 @@ msgid "line shortened due to embedded Nul character\n"
 msgstr "列因嵌入的 Nul 字符而縮短了\n"
 
 #, c-format
-msgid "unknown command `%s'\n"
+msgid "unknown command '%s'\n"
 msgstr "未知的指令 `%s'\n"
 
 #, c-format
@@ -6291,7 +6123,7 @@ msgid "Options useful for debugging"
 msgstr "對除錯有幫助的選項"
 
 msgid "|FILE|write server mode logs to FILE"
-msgstr "|檔案|將伺服器模式日誌寫入至指定檔案"
+msgstr "|檔案|將伺服器模式日誌寫入至「檔案」"
 
 msgid "Options controlling the security"
 msgstr "控制著安全性的選項"
@@ -6318,7 +6150,7 @@ msgid "|N|require at least N non-alpha characters for a new passphrase"
 msgstr "|N|新密語至少要有 N 個非字母的字符"
 
 msgid "|FILE|check new passphrases against pattern in FILE"
-msgstr "|檔案|用指定檔案中的樣式來檢查新密語"
+msgstr "|檔案|用「檔案」中的樣式來檢查新密語"
 
 msgid "|N|expire the passphrase after N days"
 msgstr "|N|在 N 天之後讓密語過期"
@@ -6327,10 +6159,10 @@ msgid "do not allow the reuse of old passphrases"
 msgstr "不允許重複使用舊密語"
 
 msgid "|NAME|use NAME as default secret key"
-msgstr "|名字|使用指定名字做為預設私鑰"
+msgstr "|名字|使用「名字」做為預設私鑰"
 
 msgid "|NAME|encrypt to user ID NAME as well"
-msgstr "|名字|也加密給指定名字的使用者 ID"
+msgstr "|名字|也加密給使用者 ID「名字」"
 
 msgid "|SPEC|set up email aliases"
 msgstr "|SPEC|設定電子郵件別名"
@@ -6351,7 +6183,7 @@ msgid "disable all access to the dirmngr"
 msgstr "停用所有的 dirmngr 存取"
 
 msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
-msgstr "|名稱|將指定名稱編碼用於 PKCS#12 密語"
+msgstr "|名稱|將「名稱」編碼用於 PKCS#12 密語"
 
 msgid "do not check CRLs for root certificates"
 msgstr "不要為根憑證檢查 CRL"
@@ -6487,7 +6319,7 @@ msgid "%s on %s failed with status %i\n"
 msgstr "%s 於 %s 以 %i 狀態失敗了\n"
 
 #, c-format
-msgid "can't create temporary directory `%s': %s\n"
+msgid "can't create temporary directory '%s': %s\n"
 msgstr "無法建立暫存目錄 `%s': %s\n"
 
 #, c-format
@@ -6583,18 +6415,6 @@ msgstr ""
 "語法: gpg-check-pattern [選項] 樣式檔案\n"
 "用樣式檔案來檢查由標準輸入給定的密語\n"
 
-#~ msgid "you may want to start the gpg-agent first\n"
-#~ msgstr "你可能會先想啟動 gpg-agent\n"
-
-#~ msgid "error loading `%s': %s\n"
-#~ msgstr "載入 `%s' 時出錯: %s\n"
-
-#~ msgid "failed to allocated keyDB handle\n"
-#~ msgstr "配置 keyDB handle 失敗\n"
-
-#~ msgid "Command> "
-#~ msgstr "指令> "
-
 #~ msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
 #~ msgstr ""
 #~ "請向 <gnupg-bugs@gnu.org> 回報程式瑕疵, 向 <Jedi@Jedi.org> 回報翻譯瑕疵.\n"
@@ -7086,12 +6906,18 @@ msgstr ""
 #~ msgid "invalid packet"
 #~ msgstr "無效的封包"
 
+#~ msgid "invalid armor"
+#~ msgstr "無效的封裝"
+
 #~ msgid "no such user id"
 #~ msgstr "沒有這個使用者 ID"
 
 #~ msgid "wrong secret key used"
 #~ msgstr "用了錯誤的私鑰"
 
+#~ msgid "not supported"
+#~ msgstr "未支援"
+
 #~ msgid "bad key"
 #~ msgstr "損壞的金鑰"
 
@@ -7104,6 +6930,9 @@ msgstr ""
 #~ msgid "file create error"
 #~ msgstr "檔案建立錯誤"
 
+#~ msgid "invalid passphrase"
+#~ msgstr "無效的密語"
+
 #~ msgid "unimplemented pubkey algorithm"
 #~ msgstr "尚未實做的公鑰演算法"
 
index d686058..9184af4 100644 (file)
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-12-01  Niibe Yutaka  <gniibe@fsij.org>
 
-       * pcsc-wrapper.c (handle_open): Remove unused var LISTLEN.
+       * app-openpgp.c (do_change_pin): Fix pincb messages when
+       use_keypad == 1.
 
-       * scdaemon.c (main): Remove var MAY_COREDUMP.
+2011-11-29  Niibe Yutaka  <gniibe@fsij.org>
+
+       PC/SC pininput support for passphrase modification (2/2)
+       * apdu.h (apdu_send_simple_kp): Remove.
+
+       * apdu.c (pcsc_keypad_modify): Add bConfirmPIN handling.
+       (apdu_send_simple_kp): Remove.
+
+       * iso7816.h (iso7816_reset_retry_counter_kp): Remove arguments
+       of NEWCHV, and NEWCHVLEN.
+       (iso7816_reset_retry_counter_with_rc_kp, iso7816_put_data_kp): New.
+
+       * iso7816.c (iso7816_reset_retry_counter_with_rc_kp): New.
+       (iso7816_reset_retry_counter_kp): Call apdu_keypad_modify.  Only
+       handle the case with PININFO.
+       (iso7816_reset_retry_counter): Don't call
+       iso7816_reset_retry_counter_kp.
+       (iso7816_put_data_kp): New.
+
+       * app-openpgp.c (do_change_pin): Add with_resetcode.
+       Handle keypad for unblocking pass phrase with resetcode,
+       setting up of resetcode, and unblocking by admin.
+
+       PC/SC pininput support for passphrase modification (1/2)
+       * iso7816.h (iso7816_change_reference_data_kp): Remove arguments
+       of OLDCHV, OLDCHVLEN, NEWCHV, and NEWCHVLEN.
+
+       * iso7816.c (iso7816_change_reference_data_kp): Call
+       apdu_keypad_modify.
+       (iso7816_change_reference_data): Don't call
+       iso7816_change_reference_data_kp.
+
+       * apdu.h (apdu_keypad_modify): New.
+
+       * apdu.c (pcsc_keypad_modify, apdu_keypad_modify): New.
+       (struct reader_table_s): New memeber function keypad_modify.
+       (new_reader_slot, open_ct_reader, open_ccid_reader)
+       (open_rapdu_reader): Initialize keypad_modify.
+
+       * app-openpgp.c (do_change_pin): Handle keypad and call
+       iso7816_change_reference_data_kp if it is the case.
+
+2011-11-28  Niibe Yutaka  <gniibe@fsij.org>
+
+       * iso7816.h (iso7816_verify_kp): Remove arguments of CHV and CHVLEN.
+
+       * iso7816.c (iso7816_verify_kp): Call apdu_keypad_verify. Only
+       handle the case with PININFO.
+       (iso7816_verify): Call apdu_send_simple.
+
+       * app-openpgp.c (verify_a_chv, verify_chv3): Follow the change of
+       iso7816_verify_kp.
+
+       * app-nks.c (verify_pin): Likewise.
+
+       * app-dinsig.c (verify_pin): Likewise.
+
+       * apdu.c: Include "iso7816.h".
+       (struct reader_table_s): New memeber function keypad_verify.
+       Add fields verify_ioctl and modify_ioctl in pcsc.
+       (CM_IOCTL_GET_FEATURE_REQUEST, FEATURE_VERIFY_PIN_DIRECT)
+       (FEATURE_MODIFY_PIN_DIRECT): New.
+       (pcsc_control): New.
+       (control_pcsc_direct, control_pcsc_wrapped, control_pcsc)
+       (check_pcsc_keypad, pcsc_keypad_verify): New.
+       (ccid_keypad_verify, apdu_keypad_verify): New.
+       (new_reader_slot): Initialize with check_pcsc_keypad,
+       pcsc_keypad_verify, verify_ioctl and modify_ioctl.
+       (open_ct_reader): Initialize keypad_verify with NULL.
+       (open_ccid_reader): Initialize keypad_verify.
+       (open_rapdu_reader): Initialize keypad_verify with NULL.
+       (apdu_open_reader): Initialize pcsc_control.
+
+       * pcsc-wrapper.c (load_pcsc_driver): Initialize pcsc_control.
+       (handle_control): New.
+       (main): Handle the case 6 of handle_control.
+
+2011-08-10  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_killscd): Use the new assuan force close flag
+       if available.
+
+2011-08-08  Werner Koch  <wk@g10code.com>
+
+       * app-openpgp.c (do_decipher): Take care of accidentally passed
+       signed integer data with a leading 0.
+
+2011-06-16  Werner Koch  <wk@g10code.com>
+
+       * app-openpgp.c (send_key_data): Implemented chunked mode.
+       (change_keyattr): Increase limit to 4096.
+       (do_decipher): Adjust padding for 4096 bit keys.
+
+2011-02-23  Werner Koch  <wk@g10code.com>
+
+       * apdu.c (apdu_open_reader): Lock in to CCID if used once.
 
 2011-01-25  NIIBE Yutaka <gniibe@fsij.org>,
            Grant Olson <kgo@grant-olson.net>  (wk)
        (update_reader_status_file): Fix handling of the VALID flag for
        unplugged readers.
 
-2010-03-17  Werner Koch  <wk@g10code.com>
+2011-01-25  Werner Koch  <wk@g10code.com>
+
+       From 2.0 branch, 2010-03-17:
 
        * command.c (open_card): Return GPG_ERR_NOT_OPERATIONAL if no
        card services are available.
        (open_pcsc_reader_direct): Set it.
        (apdu_open_reader): Add arg R_NO_SERVICE.
 
-2010-02-11  Marcus Brinkmann  <marcus@g10code.de>
+2011-01-05  Werner Koch  <wk@g10code.com>
+
+       * ccid-driver.c (ccid_transceive_secure): Support the gnuk token.
+
+2010-11-16  Werner Koch  <wk@g10code.com>
+
+       * apdu.c (PCSC_UNKNOWN) [W32]: Fix all these values which don't
+       match those of libpcsc.  Reported by Michael Petig.
+
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * scdaemon.c (create_socket_name): Use TMPDIR.  Change callers.
+
+2010-10-18  Werner Koch  <wk@g10code.com>
+
+       * app-openpgp.c (parse_algorithm_attribute): Remove extra const in
+       definition of DESC.
 
-       From trunk 2009-09-23, 2009-10-16, 2009-11-02, 2009-11-04, 2009-11-05,
-       2009-11-25:
+2010-08-16  Werner Koch  <wk@g10code.com>
 
-       * Makefile.am (AM_CFLAGS, scdaemon_LDADD): Use libassuan instead
-       of libassuan-pth.
+       * scdaemon.c: Replace remaining printf by es_printf.
+
+2010-06-09  Werner Koch  <wk@g10code.com>
+
+       * scdaemon.c (main): s/log_set_get_tid_callback/log_set_pid_suffix_cb/.
+       (tid_log_callback): Adjust for this change.
+
+2010-03-11  Werner Koch  <wk@g10code.com>
+
+       * scdaemon.c: Include "asshelp.h".
+       (main): Remove assuan_set_assuan_log_prefix.  Add
+       assuan_set_log_cb.
+       (handle_signal): Disable pth ctrl dumping.
+       * command.c (scd_command_handler): Remove assuan_set_log_stream.
+
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (scdaemon_LDADD): Remove libjnlib.a.
+
+2009-12-15  Werner Koch  <wk@g10code.com>
+
+       * iso7816.c (do_generate_keypair): s/readonly/read_only/ because
+       the first is a keyword in VMS C.
+
+2009-12-03  Werner Koch  <wk@g10code.com>
+
+       * scdaemon.c (set_debug): Allow for numerical debug leveles.  Print
+       active debug flags.
+
+2009-11-25  Marcus Brinkmann  <marcus@g10code.de>
+
+       * command.c (scd_command_handler): Use assuan_fd_t and
+       assuan_fdopen on fds.
+
+2009-11-05  Marcus Brinkmann  <marcus@g10code.de>
+
+       * command.c (scd_command_handler): Call assuan_init_socket_server,
+       not assuan_init_socket_server_ext.
+
+2009-11-04  Werner Koch  <wk@g10code.com>
+
+       * command.c (register_commands): Add help arg to
+       assuan_register_command.  Add help strings to all commands.
+
+2009-11-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * command.c (reset_notify): Take LINE arg and return error.
+       (register_commands): Use assuan_handler_t type.
+
+2009-10-25  Werner Koch  <wk@g10code.com>
+
+       * scdaemon.c (scd_deinit_default_ctrl): Release IN_DATA.
+       * command.c (cmd_setdata): Release IN_DATA.  Reported by Klaus
+       Flittner.
+
+2009-10-16  Marcus Brinkmann  <marcus@g10code.com>
+
+       * AM_CFLAGS, scdaemon_LDADD: Use libassuan instead of libassuan-pth.
        * scdaemon.c: Invoke ASSUAN_SYSTEM_PTH_IMPL.
-       (main): Update to new Assuan API.  Call assuan_set_system_hooks
-       and assuan_sock_init.
+       (main): Call assuan_set_system_hooks and assuan_sock_init.
+
+2009-09-23  Marcus Brinkmann  <marcus@g10code.de>
+
        * command.c: Include "scdaemon.h" before <assuan.h> because of
        GPG_ERR_SOURCE_DEFAULT check.
        (option_handler, open_card, cmd_serialno, cmd_lean, cmd_readcert)
        (cmd_unlock, cmd_getinfo, cmd_restart, cmd_disconnect, cmd_apdu)
        (cmd_killscd): Return gpg_error_t instead of int.
        (scd_command_handler): Allocate assuan context before starting server.
-       Call assuan_init_socket_server, not assuan_init_socket_server_ext.
-       Use assuan_fd_t and assuan_fdopen on fds.
-       (reset_notify): Take LINE arg and return error.
-       (register_commands): Use assuan_handler_t type.
-       Add NULL arg to assuan_register_command.  Add help arg to
-       assuan_register_command.  Add help strings to all commands.
-
-2009-12-03  Werner Koch  <wk@g10code.com>
-
-       * scdaemon.c (set_debug): Allow for numerical debug levels.  Print
-       active debug flags.
+       * scdaemon.c (main): Update to new Assuan API.
 
 2009-09-03  Werner Koch  <wk@g10code.com>
 
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index aa370fa..09dd7d2 100644 (file)
 
 ## Process this file with automake to produce Makefile.in
 
-if HAVE_W32_SYSTEM
-libexec_PROGRAMS = scdaemon
-else
-libexec_PROGRAMS = scdaemon gnupg-pcsc-wrapper
-endif
-
 EXTRA_DIST = ChangeLog-2011 scdaemon-w32info.rc
 
-AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common -I$(top_srcdir)/include
+libexec_PROGRAMS = scdaemon
+
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
 
 include $(top_srcdir)/am/cmacros.am
 
@@ -33,23 +29,24 @@ if HAVE_W32_SYSTEM
 resource_objs += scdaemon-w32info.o
 endif
 
-AM_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) \
-           $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS)
+AM_CFLAGS =  $(LIBGCRYPT_CFLAGS) \
+            $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
 
 
-card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c app-geldkarte.c
+card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c app-geldkarte.c app-sc-hsm.c
 
 scdaemon_SOURCES = \
        scdaemon.c scdaemon.h \
        command.c \
+       atr.c atr.h \
        apdu.c apdu.h \
        ccid-driver.c ccid-driver.h \
        iso7816.c iso7816.h \
        app.c app-common.h app-help.c $(card_apps)
 
 
-scdaemon_LDADD = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a \
-       $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \
+scdaemon_LDADD = $(libcommonpth) ../gl/libgnu.a \
+       $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
        $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \
         $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) $(resource_objs)
 
@@ -65,12 +62,9 @@ scdaemon_LDADD = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a \
 #      app.c app-common.h app-help.c $(card_apps)
 #
 #sc_copykeys_LDADD = \
-#      ../jnlib/libjnlib.a ../common/libcommon.a \
+#      ../common/libcommon.a \
 #      ../common/libsimple-pwquery.a \
-#      $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \
+#      $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
 #       $(LIBUSB_LIBS) \
 #        -lgpg-error @LIBINTL@ @DL_LIBS@
 #
-gnupg_pcsc_wrapper_SOURCES = pcsc-wrapper.c
-gnupg_pcsc_wrapper_LDADD = $(DL_LIBS)
-gnupg_pcsc_wrapper_CFLAGS =
index 97bce79..476723a 100644 (file)
@@ -1,5 +1,6 @@
 /* apdu.c - ISO 7816 APDU functions and low level I/O
- * Copyright (C) 2003, 2004, 2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2004, 2008, 2009, 2010,
+ *               2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -18,7 +19,7 @@
  */
 
 /* NOTE: This module is also used by other software, thus the use of
-   the macro USE_GNU_PTH is mandatory.  For GnuPG this macro is
+   the macro USE_NPTH is mandatory.  For GnuPG this macro is
    guaranteed to be defined true. */
 
 #include <config.h>
 #include <string.h>
 #include <assert.h>
 #include <signal.h>
-#ifdef USE_GNU_PTH
+#ifdef USE_NPTH
 # include <unistd.h>
 # include <fcntl.h>
-# include <pth.h>
+# include <npth.h>
 #endif
 
 
 #include "scdaemon.h"
 #include "exechelp.h"
 #endif /* GNUPG_MAJOR_VERSION != 1 */
-#include "../include/host2net.h"
 
 #include "iso7816.h"
 #include "apdu.h"
+#define CCID_DRIVER_INCLUDE_USB_IDS 1
 #include "ccid-driver.h"
 
 /* Due to conflicting use of threading libraries we usually can't link
-   against libpcsclite.   Instead we use a wrapper program.  */
-#ifdef USE_GNU_PTH
+   against libpcsclite if we are using Pth.  Instead we use a wrapper
+   program.  Note that with nPth there is no need for a wrapper. */
+#ifdef USE_PTH  /* Right, plain old Pth.  */
 #if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__)
 #define NEED_PCSC_WRAPPER 1
 #endif
@@ -98,6 +100,7 @@ struct reader_table_s {
   int (*connect_card)(int);
   int (*disconnect_card)(int);
   int (*close_reader)(int);
+  int (*shutdown_reader)(int);
   int (*reset_reader)(int);
   int (*get_status_reader)(int, unsigned int *);
   int (*send_apdu_reader)(int,unsigned char *,size_t,
@@ -144,9 +147,9 @@ struct reader_table_s {
                               not yet been read; i.e. the card is not
                               ready for use. */
   unsigned int change_counter;
-#ifdef USE_GNU_PTH
+#ifdef USE_NPTH
   int lock_initialized;
-  pth_mutex_t lock;
+  npth_mutex_t lock;
 #endif
 };
 typedef struct reader_table_s *reader_table_t;
@@ -171,7 +174,11 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn);
 
 #define PCSC_PROTOCOL_T0     1
 #define PCSC_PROTOCOL_T1     2
-#define PCSC_PROTOCOL_RAW    4
+#ifdef HAVE_W32_SYSTEM
+# define PCSC_PROTOCOL_RAW   0x00010000  /* The active protocol.  */
+#else
+# define PCSC_PROTOCOL_RAW   4
+#endif
 
 #define PCSC_SHARE_EXCLUSIVE 1
 #define PCSC_SHARE_SHARED    2
@@ -182,13 +189,23 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn);
 #define PCSC_UNPOWER_CARD    2
 #define PCSC_EJECT_CARD      3
 
-#define PCSC_UNKNOWN    0x0001
-#define PCSC_ABSENT     0x0002  /* Card is absent.  */
-#define PCSC_PRESENT    0x0004  /* Card is present.  */
-#define PCSC_SWALLOWED  0x0008  /* Card is present and electrical connected. */
-#define PCSC_POWERED    0x0010  /* Card is powered.  */
-#define PCSC_NEGOTIABLE 0x0020  /* Card is awaiting PTS.  */
-#define PCSC_SPECIFIC   0x0040  /* Card is ready for use.  */
+#ifdef HAVE_W32_SYSTEM
+# define PCSC_UNKNOWN    0x0000  /* The driver is not aware of the status.  */
+# define PCSC_ABSENT     0x0001  /* Card is absent.  */
+# define PCSC_PRESENT    0x0002  /* Card is present.  */
+# define PCSC_SWALLOWED  0x0003  /* Card is present and electrical connected. */
+# define PCSC_POWERED    0x0004  /* Card is powered.  */
+# define PCSC_NEGOTIABLE 0x0005  /* Card is awaiting PTS.  */
+# define PCSC_SPECIFIC   0x0006  /* Card is ready for use.  */
+#else
+# define PCSC_UNKNOWN    0x0001
+# define PCSC_ABSENT     0x0002  /* Card is absent.  */
+# define PCSC_PRESENT    0x0004  /* Card is present.  */
+# define PCSC_SWALLOWED  0x0008  /* Card is present and electrical connected. */
+# define PCSC_POWERED    0x0010  /* Card is powered.  */
+# define PCSC_NEGOTIABLE 0x0020  /* Card is awaiting PTS.  */
+# define PCSC_SPECIFIC   0x0040  /* Card is ready for use.  */
+#endif
 
 #define PCSC_STATE_UNAWARE     0x0000  /* Want status.  */
 #define PCSC_STATE_IGNORE      0x0001  /* Ignore this reader.  */
@@ -201,6 +218,9 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn);
 #define PCSC_STATE_EXCLUSIVE   0x0080  /* Exclusive Mode.  */
 #define PCSC_STATE_INUSE       0x0100  /* Shared mode.  */
 #define PCSC_STATE_MUTE               0x0200  /* Unresponsive card.  */
+#ifdef HAVE_W32_SYSTEM
+# define PCSC_STATE_UNPOWERED  0x0400  /* Card not powerred up.  */
+#endif
 
 /* Some PC/SC error codes.  */
 #define PCSC_E_CANCELLED               0x80100002
@@ -223,7 +243,6 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn);
 #define PCSC_E_NOT_TRANSACTED          0x80100016
 #define PCSC_E_READER_UNAVAILABLE      0x80100017
 #define PCSC_E_NO_SERVICE              0x8010001D
-#define PCSC_E_SERVICE_STOPPED         0x8010001E
 #define PCSC_W_REMOVED_CARD            0x80100069
 
 /* Fix pcsc-lite ABI incompatibilty.  */
@@ -355,42 +374,50 @@ static int pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1,
       Helper
  */
 
-
 static int
 lock_slot (int slot)
 {
-#ifdef USE_GNU_PTH
-  if (!pth_mutex_acquire (&reader_table[slot].lock, 0, NULL))
+#ifdef USE_NPTH
+  int err;
+
+  err = npth_mutex_lock (&reader_table[slot].lock);
+  if (err)
     {
-      log_error ("failed to acquire apdu lock: %s\n", strerror (errno));
+      log_error ("failed to acquire apdu lock: %s\n", strerror (err));
       return SW_HOST_LOCKING_FAILED;
     }
-#endif /*USE_GNU_PTH*/
+#endif /*USE_NPTH*/
   return 0;
 }
 
 static int
 trylock_slot (int slot)
 {
-#ifdef USE_GNU_PTH
-  if (!pth_mutex_acquire (&reader_table[slot].lock, TRUE, NULL))
+#ifdef USE_NPTH
+  int err;
+
+  err = npth_mutex_trylock (&reader_table[slot].lock);
+  if (err == EBUSY)
+    return SW_HOST_BUSY;
+  else if (err)
     {
-      if (errno == EBUSY)
-        return SW_HOST_BUSY;
-      log_error ("failed to acquire apdu lock: %s\n", strerror (errno));
+      log_error ("failed to acquire apdu lock: %s\n", strerror (err));
       return SW_HOST_LOCKING_FAILED;
     }
-#endif /*USE_GNU_PTH*/
+#endif /*USE_NPTH*/
   return 0;
 }
 
 static void
 unlock_slot (int slot)
 {
-#ifdef USE_GNU_PTH
-  if (!pth_mutex_release (&reader_table[slot].lock))
+#ifdef USE_NPTH
+  int err;
+
+  err = npth_mutex_unlock (&reader_table[slot].lock);
+  if (err)
     log_error ("failed to release apdu lock: %s\n", strerror (errno));
-#endif /*USE_GNU_PTH*/
+#endif /*USE_NPTH*/
 }
 
 
@@ -401,6 +428,7 @@ static int
 new_reader_slot (void)
 {
   int i, reader = -1;
+  int err;
 
   for (i=0; i < MAX_READER; i++)
     {
@@ -412,17 +440,18 @@ new_reader_slot (void)
       log_error ("new_reader_slot: out of slots\n");
       return -1;
     }
-#ifdef USE_GNU_PTH
+#ifdef USE_NPTH
   if (!reader_table[reader].lock_initialized)
     {
-      if (!pth_mutex_init (&reader_table[reader].lock))
+      err = npth_mutex_init (&reader_table[reader].lock, NULL);
+      if (err)
         {
-          log_error ("error initializing mutex: %s\n", strerror (errno));
+          log_error ("error initializing mutex: %s\n", strerror (err));
           return -1;
         }
       reader_table[reader].lock_initialized = 1;
     }
-#endif /*USE_GNU_PTH*/
+#endif /*USE_NPTH*/
   if (lock_slot (reader))
     {
       log_error ("error locking mutex: %s\n", strerror (errno));
@@ -431,6 +460,7 @@ new_reader_slot (void)
   reader_table[reader].connect_card = NULL;
   reader_table[reader].disconnect_card = NULL;
   reader_table[reader].close_reader = NULL;
+  reader_table[reader].shutdown_reader = NULL;
   reader_table[reader].reset_reader = NULL;
   reader_table[reader].get_status_reader = NULL;
   reader_table[reader].send_apdu_reader = NULL;
@@ -514,14 +544,18 @@ apdu_strerror (int rc)
     case SW_WRONG_LENGTH   : return "wrong length";
     case SW_CHV_WRONG      : return "CHV wrong";
     case SW_CHV_BLOCKED    : return "CHV blocked";
+    case SW_REF_DATA_INV   : return "referenced data invalidated";
     case SW_USE_CONDITIONS : return "use conditions not satisfied";
     case SW_BAD_PARAMETER  : return "bad parameter";
     case SW_NOT_SUPPORTED  : return "not supported";
     case SW_FILE_NOT_FOUND : return "file not found";
     case SW_RECORD_NOT_FOUND:return "record not found";
     case SW_REF_NOT_FOUND  : return "reference not found";
-    case SW_BAD_LC         : return "bad Lc";
-    case SW_BAD_P0_P1      : return "bad P0 or P1";
+    case SW_NOT_ENOUGH_MEMORY: return "not enough memory space in the file";
+    case SW_INCONSISTENT_LC: return "Lc inconsistent with TLV structure.";
+    case SW_INCORRECT_P0_P1: return "incorrect parameters P0,P1";
+    case SW_BAD_LC         : return "Lc inconsistent with P0,P1";
+    case SW_BAD_P0_P1      : return "bad P0,P1";
     case SW_INS_NOT_SUP    : return "instruction not supported";
     case SW_CLA_NOT_SUP    : return "class not supported";
     case SW_SUCCESS        : return "success";
@@ -754,8 +788,8 @@ writen (int fd, const void *buf, size_t nbytes)
 
   while (nleft > 0)
     {
-#ifdef USE_GNU_PTH
-      nwritten = pth_write (fd, buf, nleft);
+#ifdef USE_NPTH
+      nwritten = npth_write (fd, buf, nleft);
 #else
       nwritten = write (fd, buf, nleft);
 #endif
@@ -780,11 +814,11 @@ readn (int fd, void *buf, size_t buflen, size_t *nread)
 
   while (nleft > 0)
     {
-#ifdef USE_GNU_PTH
+#ifdef USE_NPTH
 # ifdef HAVE_W32_SYSTEM
-#  error Cannot use pth_read here because it expects a system HANDLE.
+#  error Cannot use npth_read here because it expects a system HANDLE.
 # endif
-      n = pth_read (fd, buf, nleft);
+      n = npth_read (fd, buf, nleft);
 #else
       n = read (fd, buf, nleft);
 #endif
@@ -872,8 +906,6 @@ pcsc_error_to_sw (long ec)
     case PCSC_E_CANCELLED:           rc = SW_HOST_ABORTED; break;
     case PCSC_E_NO_MEMORY:           rc = SW_HOST_OUT_OF_CORE; break;
     case PCSC_E_TIMEOUT:             rc = SW_HOST_CARD_IO_ERROR; break;
-    case PCSC_E_NO_SERVICE:
-    case PCSC_E_SERVICE_STOPPED:
     case PCSC_E_UNKNOWN_READER:      rc = SW_HOST_NO_READER; break;
     case PCSC_E_SHARING_VIOLATION:   rc = SW_HOST_LOCKING_FAILED; break;
     case PCSC_E_NO_SMARTCARD:        rc = SW_HOST_NO_CARD; break;
@@ -1015,14 +1047,15 @@ pcsc_get_status_wrapped (int slot, unsigned int *status)
                  i? strerror (errno) : "premature EOF");
       goto command_failed;
     }
-  len = buf32_to_size_t (msgbuf+1);
+  len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4];
   if (msgbuf[0] != 0x81 || len < 4)
     {
       log_error ("invalid response header from PC/SC received\n");
       goto command_failed;
     }
   len -= 4; /* Already read the error code. */
-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+  err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
+                       | (msgbuf[7] << 8 ) | msgbuf[8]);
   if (err)
     {
       log_error ("pcsc_status failed: %s (0x%lx)\n",
@@ -1074,7 +1107,8 @@ pcsc_get_status_wrapped (int slot, unsigned int *status)
   close (slotp->pcsc.rsp_fd);
   slotp->pcsc.req_fd = -1;
   slotp->pcsc.rsp_fd = -1;
-  kill (slotp->pcsc.pid, SIGTERM);
+  if (slotp->pcsc.pid != -1)
+    kill (slotp->pcsc.pid, SIGTERM);
   slotp->pcsc.pid = (pid_t)(-1);
   slotp->used = 0;
   return sw;
@@ -1103,6 +1137,8 @@ pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen,
   struct pcsc_io_request_s send_pci;
   pcsc_dword_t recv_len;
 
+  (void)pininfo;
+
   if (!reader_table[slot].atrlen
       && (err = reset_pcsc_reader (slot)))
     return err;
@@ -1182,14 +1218,15 @@ pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen,
                  i? strerror (errno) : "premature EOF");
       goto command_failed;
     }
-  len = buf32_to_size_t (msgbuf+1);
+  len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4];
   if (msgbuf[0] != 0x81 || len < 4)
     {
       log_error ("invalid response header from PC/SC received\n");
       goto command_failed;
     }
   len -= 4; /* Already read the error code. */
-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+  err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
+                       | (msgbuf[7] << 8 ) | msgbuf[8]);
   if (err)
     {
       log_error ("pcsc_transmit failed: %s (0x%lx)\n",
@@ -1237,7 +1274,8 @@ pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen,
   close (slotp->pcsc.rsp_fd);
   slotp->pcsc.req_fd = -1;
   slotp->pcsc.rsp_fd = -1;
-  kill (slotp->pcsc.pid, SIGTERM);
+  if (slotp->pcsc.pid != -1)
+    kill (slotp->pcsc.pid, SIGTERM);
   slotp->pcsc.pid = (pid_t)(-1);
   slotp->used = 0;
   return sw;
@@ -1270,7 +1308,7 @@ control_pcsc_direct (int slot, pcsc_dword_t ioctl_code,
   long err;
 
   err = pcsc_control (reader_table[slot].pcsc.card, ioctl_code,
-                      cntlbuf, len, buffer, buflen? *buflen:0, buflen);
+                      cntlbuf, len, buffer, *buflen, buflen);
   if (err)
     {
       log_error ("pcsc_control failed: %s (0x%lx)\n",
@@ -1321,14 +1359,15 @@ control_pcsc_wrapped (int slot, pcsc_dword_t ioctl_code,
                  i? strerror (errno) : "premature EOF");
       goto command_failed;
     }
-  len = buf32_to_size_t (msgbuf+1);
+  len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4];
   if (msgbuf[0] != 0x81 || len < 4)
     {
       log_error ("invalid response header from PC/SC received\n");
       goto command_failed;
     }
   len -= 4; /* Already read the error code. */
-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+  err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
+                       | (msgbuf[7] << 8 ) | msgbuf[8]);
   if (err)
     {
       log_error ("pcsc_control failed: %s (0x%lx)\n",
@@ -1338,18 +1377,14 @@ control_pcsc_wrapped (int slot, pcsc_dword_t ioctl_code,
 
   full_len = len;
 
-  if (buflen)
-    n = *buflen < len ? *buflen : len;
-  else
-    n = 0;
+  n = *buflen < len ? *buflen : len;
   if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n)
     {
       log_error ("error receiving PC/SC CONTROL response: %s\n",
                  i? strerror (errno) : "premature EOF");
       goto command_failed;
     }
-  if (buflen)
-    *buflen = n;
+  *buflen = n;
 
   full_len -= len;
   if (full_len)
@@ -1381,7 +1416,8 @@ control_pcsc_wrapped (int slot, pcsc_dword_t ioctl_code,
   close (slotp->pcsc.rsp_fd);
   slotp->pcsc.req_fd = -1;
   slotp->pcsc.rsp_fd = -1;
-  kill (slotp->pcsc.pid, SIGTERM);
+  if (slotp->pcsc.pid != -1)
+    kill (slotp->pcsc.pid, SIGTERM);
   slotp->pcsc.pid = (pid_t)(-1);
   slotp->used = 0;
   return pcsc_error_to_sw (err);
@@ -1461,14 +1497,15 @@ close_pcsc_reader_wrapped (int slot)
                  i? strerror (errno) : "premature EOF");
       goto command_failed;
     }
-  len = buf32_to_size_t (msgbuf+1);
+  len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4];
   if (msgbuf[0] != 0x81 || len < 4)
     {
       log_error ("invalid response header from PC/SC received\n");
       goto command_failed;
     }
   len -= 4; /* Already read the error code. */
-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+  err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
+                       | (msgbuf[7] << 8 ) | msgbuf[8]);
   if (err)
     log_error ("pcsc_close failed: %s (0x%lx)\n",
                pcsc_error_string (err), err);
@@ -1481,7 +1518,8 @@ close_pcsc_reader_wrapped (int slot)
   close (slotp->pcsc.rsp_fd);
   slotp->pcsc.req_fd = -1;
   slotp->pcsc.rsp_fd = -1;
-  kill (slotp->pcsc.pid, SIGTERM);
+  if (slotp->pcsc.pid != -1)
+    kill (slotp->pcsc.pid, SIGTERM);
   slotp->pcsc.pid = (pid_t)(-1);
   slotp->used = 0;
   return 0;
@@ -1533,7 +1571,7 @@ connect_pcsc_card (int slot)
     {
       char reader[250];
       pcsc_dword_t readerlen, atrlen;
-      long card_state, card_protocol;
+      pcsc_dword_t card_state, card_protocol;
 
       pcsc_vendor_specific_init (slot);
 
@@ -1545,7 +1583,7 @@ connect_pcsc_card (int slot)
                          reader_table[slot].atr, &atrlen);
       if (err)
         log_error ("pcsc_status failed: %s (0x%lx) %lu\n",
-                   pcsc_error_string (err), err, readerlen);
+                   pcsc_error_string (err), err, (long unsigned int)readerlen);
       else
         {
           if (atrlen > DIM (reader_table[0].atr))
@@ -1649,7 +1687,7 @@ reset_pcsc_reader_wrapped (int slot)
                  i? strerror (errno) : "premature EOF");
       goto command_failed;
     }
-  len = buf32_to_size_t (msgbuf+1);
+  len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4];
   if (msgbuf[0] != 0x81 || len < 4)
     {
       log_error ("invalid response header from PC/SC received\n");
@@ -1663,7 +1701,8 @@ reset_pcsc_reader_wrapped (int slot)
       sw = SW_HOST_GENERAL_ERROR;
       goto command_failed;
     }
-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+  err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
+                       | (msgbuf[7] << 8 ) | msgbuf[8]);
   if (err)
     {
       log_error ("PC/SC RESET failed: %s (0x%lx)\n",
@@ -1700,7 +1739,8 @@ reset_pcsc_reader_wrapped (int slot)
   close (slotp->pcsc.rsp_fd);
   slotp->pcsc.req_fd = -1;
   slotp->pcsc.rsp_fd = -1;
-  kill (slotp->pcsc.pid, SIGTERM);
+  if (slotp->pcsc.pid != -1)
+    kill (slotp->pcsc.pid, SIGTERM);
   slotp->pcsc.pid = (pid_t)(-1);
   slotp->used = 0;
   return sw;
@@ -1754,9 +1794,9 @@ pcsc_vendor_specific_init (int slot)
           if (l == 1)
             v = p[0];
           else if (l == 2)
-            v = buf16_to_uint (p);
+            v = ((p[0] << 8) | p[1]);
           else if (l == 4)
-            v = buf32_to_uint (p);
+            v = ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
 
           if (code == FEATURE_VERIFY_PIN_DIRECT)
             reader_table[slot].pcsc.verify_ioctl = v;
@@ -1785,12 +1825,8 @@ pcsc_vendor_specific_init (int slot)
               reader_table[slot].is_spr532 = 1;
               reader_table[slot].pinpad_varlen_supported = 1;
             }
-          else if (strstr (reader_table[slot].rdrname, "ST-2xxx"))
-            {
-              reader_table[slot].pcsc.pinmax = 15;
-              reader_table[slot].pinpad_varlen_supported = 1;
-            }
-          else if (strstr (reader_table[slot].rdrname, "cyberJack")
+          else if (strstr (reader_table[slot].rdrname, "ST-2xxx")
+                   || strstr (reader_table[slot].rdrname, "cyberJack")
                    || strstr (reader_table[slot].rdrname, "DIGIPASS")
                    || strstr (reader_table[slot].rdrname, "Gnuk")
                    || strstr (reader_table[slot].rdrname, "KAAN"))
@@ -1819,9 +1855,9 @@ pcsc_vendor_specific_init (int slot)
       if (l == 1)
         v = p[0];
       else if (l == 2)
-        v = (((unsigned int)p[1] << 8) | p[0]);
+        v = ((p[1] << 8) | p[0]);
       else if (l == 4)
-        v = (((unsigned int)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+        v = ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
 
       if (tag == PCSCv2_PART10_PROPERTY_bMinPINSize)
         reader_table[slot].pcsc.pinmin = v;
@@ -1838,7 +1874,7 @@ pcsc_vendor_specific_init (int slot)
       p += l;
     }
 
-  if (vendor == 0x0982 && product == 0x0008) /* Vega Alpha */
+  if (vendor == VENDOR_VEGA && product == VEGA_ALPHA)
     {
       /*
        * Please read the comment of ccid_vendor_specific_init in
@@ -1850,21 +1886,13 @@ pcsc_vendor_specific_init (int slot)
       if (sw)
         return SW_NOT_SUPPORTED;
     }
-  else if (vendor == 0x04e6 && product == 0xe003) /* SCM SPR532 */
+  else if (vendor == VENDOR_SCM && product == SCM_SPR532) /* SCM SPR532 */
     {
       reader_table[slot].is_spr532 = 1;
       reader_table[slot].pinpad_varlen_supported = 1;
     }
-  else if (vendor == 0x046a)
-    {
-      /* Cherry ST-2xxx (product == 0x003e) supports TPDU level
-       * exchange.  Other products which only support short APDU level
-       * exchange only work with shorter keys like RSA 1024.
-       */
-      reader_table[slot].pcsc.pinmax = 15;
-      reader_table[slot].pinpad_varlen_supported = 1;
-    }
-  else if (vendor == 0x0c4b /* Tested with Reiner cyberJack GO */
+  else if ((vendor == 0x046a && product == 0x003e)  /* Cherry ST-2xxx */
+           || vendor == 0x0c4b /* Tested with Reiner cyberJack GO */
            || vendor == 0x1a44 /* Tested with Vasco DIGIPASS 920 */
            || vendor == 0x234b /* Tested with FSIJ Gnuk Token */
            || vendor == 0x0d46 /* Tested with KAAN Advanced??? */)
@@ -1883,7 +1911,6 @@ open_pcsc_reader_direct (const char *portstr)
   long err;
   int slot;
   char *list = NULL;
-  char *rdrname = NULL;
   pcsc_dword_t nreader;
   char *p;
 
@@ -1936,22 +1963,18 @@ open_pcsc_reader_direct (const char *portstr)
     {
       if (!*p && !p[1])
         break;
-      log_info ("detected reader `%s'\n", p);
+      if (*p)
+        log_info ("detected reader '%s'\n", p);
       if (nreader < (strlen (p)+1))
         {
           log_error ("invalid response from pcsc_list_readers\n");
           break;
         }
-      if (!rdrname && portstr && !strncmp (p, portstr, strlen (portstr)))
-        rdrname = p;
       nreader -= strlen (p)+1;
       p += strlen (p) + 1;
     }
 
-  if (!rdrname)
-    rdrname = list;
-
-  reader_table[slot].rdrname = xtrystrdup (rdrname);
+  reader_table[slot].rdrname = xtrymalloc (strlen (portstr? portstr : list)+1);
   if (!reader_table[slot].rdrname)
     {
       log_error ("error allocating memory for reader name\n");
@@ -1960,6 +1983,7 @@ open_pcsc_reader_direct (const char *portstr)
       unlock_slot (slot);
       return -1;
     }
+  strcpy (reader_table[slot].rdrname, portstr? portstr : list);
   xfree (list);
   list = NULL;
 
@@ -1998,7 +2022,6 @@ open_pcsc_reader_wrapped (const char *portstr)
   unsigned char msgbuf[9];
   int err;
   unsigned int dummy_status;
-  /*int sw = SW_HOST_CARD_IO_ERROR;*/
 
   /* Note that we use the constant and not the fucntion because this
      code won't be be used under Windows.  */
@@ -2006,7 +2029,7 @@ open_pcsc_reader_wrapped (const char *portstr)
 
   if (access (wrapperpgm, X_OK))
     {
-      log_error ("can't run PC/SC access module `%s': %s\n",
+      log_error ("can't run PC/SC access module '%s': %s\n",
                  wrapperpgm, strerror (errno));
       return -1;
     }
@@ -2073,7 +2096,7 @@ open_pcsc_reader_wrapped (const char *portstr)
       /* Send stderr to the bit bucket. */
       fd = open ("/dev/null", O_WRONLY);
       if (fd == -1)
-        log_fatal ("can't open `/dev/null': %s", strerror (errno));
+        log_fatal ("can't open '/dev/null': %s", strerror (errno));
       if (fd != 2 && dup2 (fd, 2) == -1)
         log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
 
@@ -2098,8 +2121,8 @@ open_pcsc_reader_wrapped (const char *portstr)
   slotp->pcsc.rsp_fd = rp[0];
 
   /* Wait for the intermediate child to terminate. */
-#ifdef USE_GNU_PTH
-#define WAIT pth_waitpid
+#ifdef USE_NPTH
+#define WAIT npth_waitpid
 #else
 #define WAIT waitpid
 #endif
@@ -2128,7 +2151,7 @@ open_pcsc_reader_wrapped (const char *portstr)
                  i? strerror (errno) : "premature EOF");
       goto command_failed;
     }
-  len = buf32_to_size_t (msgbuf+1);
+  len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4];
   if (msgbuf[0] != 0x81 || len < 4)
     {
       log_error ("invalid response header from PC/SC received\n");
@@ -2141,13 +2164,12 @@ open_pcsc_reader_wrapped (const char *portstr)
                  (unsigned long)len);
       goto command_failed;
     }
-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+  err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
+                       | (msgbuf[7] << 8 ) | msgbuf[8]);
 
   if (err)
     {
-      log_error ("PC/SC OPEN failed: %s (0x%08x)\n",
-                pcsc_error_string (err), err);
-      /*sw = pcsc_error_to_sw (err);*/
+      log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err));
       goto command_failed;
     }
 
@@ -2192,7 +2214,8 @@ open_pcsc_reader_wrapped (const char *portstr)
   close (slotp->pcsc.rsp_fd);
   slotp->pcsc.req_fd = -1;
   slotp->pcsc.rsp_fd = -1;
-  kill (slotp->pcsc.pid, SIGTERM);
+  if (slotp->pcsc.pid != -1)
+    kill (slotp->pcsc.pid, SIGTERM);
   slotp->pcsc.pid = (pid_t)(-1);
   slotp->used = 0;
   unlock_slot (slot);
@@ -2257,16 +2280,8 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1,
   int sw;
   unsigned char *pin_verify;
   int len = PIN_VERIFY_STRUCTURE_SIZE + pininfo->fixedlen;
-  /*
-   * The result buffer is only expected to have two-byte result on
-   * return.  However, some implementation uses this buffer for lower
-   * layer too and it assumes that there is enough space for lower
-   * layer communication.  Such an implementation fails for TPDU
-   * readers with "insufficient buffer", as it needs header and
-   * trailer.  Six is the number for header + result + trailer (TPDU).
-   */
-  unsigned char result[6];
-  pcsc_dword_t resultlen = 6;
+  unsigned char result[2];
+  pcsc_dword_t resultlen = 2;
   int no_lc;
 
   if (!reader_table[slot].atrlen
@@ -2321,6 +2336,8 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1,
                      pin_verify, len, result, &resultlen);
   xfree (pin_verify);
   if (sw || resultlen < 2)
+    return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE;
+  sw = (result[resultlen-2] << 8) | result[resultlen-1];
     {
       log_error ("control_pcsc failed: %d\n", sw);
       return sw? sw: SW_HOST_INCOMPLETE_CARD_RESPONSE;
@@ -2340,8 +2357,8 @@ pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1,
   int sw;
   unsigned char *pin_modify;
   int len = PIN_MODIFY_STRUCTURE_SIZE + 2 * pininfo->fixedlen;
-  unsigned char result[6];      /* See the comment at pinpad_verify.  */
-  pcsc_dword_t resultlen = 6;
+  unsigned char result[2];
+  pcsc_dword_t resultlen = 2;
   int no_lc;
 
   if (!reader_table[slot].atrlen
@@ -2439,6 +2456,14 @@ close_ccid_reader (int slot)
 
 
 static int
+shutdown_ccid_reader (int slot)
+{
+  ccid_shutdown_reader (reader_table[slot].ccid.handle);
+  return 0;
+}
+
+
+static int
 reset_ccid_reader (int slot)
 {
   int err;
@@ -2603,6 +2628,7 @@ open_ccid_reader (const char *portstr)
     }
 
   reader_table[slot].close_reader = close_ccid_reader;
+  reader_table[slot].shutdown_reader = shutdown_ccid_reader;
   reader_table[slot].reset_reader = reset_ccid_reader;
   reader_table[slot].get_status_reader = get_status_ccid;
   reader_table[slot].send_apdu_reader = send_apdu_ccid;
@@ -2937,23 +2963,50 @@ int
 apdu_open_reader (const char *portstr)
 {
   static int pcsc_api_loaded, ct_api_loaded;
+  int slot;
+
+  if (DBG_READER)
+    log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr);
 
 #ifdef HAVE_LIBUSB
   if (!opt.disable_ccid)
     {
-      int slot, i;
+      static int once_available;
+      int i;
       const char *s;
 
       slot = open_ccid_reader (portstr);
       if (slot != -1)
-        return slot; /* got one */
+        {
+          once_available = 1;
+          if (DBG_READER)
+            log_debug ("leave: apdu_open_reader => slot=%d [ccid]\n", slot);
+          return slot; /* got one */
+        }
+
+      /* If we ever loaded successfully loaded a CCID reader we never
+         want to fallback to another driver.  This solves a problem
+         where ccid was used, the card unplugged and then scdaemon
+         tries to find a new reader and will eventually try PC/SC over
+         and over again.  To reset this flag "gpgconf --kill scdaemon"
+         can be used.  */
+      if (once_available)
+        {
+          if (DBG_READER)
+            log_debug ("leave: apdu_open_reader => slot=-1 (once_avail)\n");
+          return -1;
+        }
 
       /* If a CCID reader specification has been given, the user does
          not want a fallback to other drivers. */
       if (portstr)
         for (s=portstr, i=0; *s; s++)
           if (*s == ':' && (++i == 3))
-            return -1;
+            {
+              if (DBG_READER)
+                log_debug ("leave: apdu_open_reader => slot=-1 (no ccid)\n");
+              return -1;
+            }
     }
 
 #endif /* HAVE_LIBUSB */
@@ -2997,7 +3050,7 @@ apdu_open_reader (const char *portstr)
       handle = dlopen (opt.pcsc_driver, RTLD_LAZY);
       if (!handle)
         {
-          log_error ("apdu_open_reader: failed to open driver `%s': %s\n",
+          log_error ("apdu_open_reader: failed to open driver '%s': %s\n",
                      opt.pcsc_driver, dlerror ());
           return -1;
         }
@@ -3074,7 +3127,11 @@ apdu_open_reader (const char *portstr)
       pcsc_api_loaded = 1;
     }
 
-  return open_pcsc_reader (portstr);
+  slot = open_pcsc_reader (portstr);
+
+  if (DBG_READER)
+    log_debug ("leave: apdu_open_reader => slot=%d [pc/sc]\n", slot);
+  return slot;
 }
 
 
@@ -3128,19 +3185,31 @@ apdu_close_reader (int slot)
 {
   int sw;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_close_reader: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_close_reader => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
   sw = apdu_disconnect (slot);
   if (sw)
     {
-      /*
-       * When the reader/token was removed it might come here.
-       * It should go through to call CLOSE_READER even if we got an error.
-       */
-      log_debug ("apdu_close_reader => 0x%x (apdu_disconnect)\n", sw);
+      if (DBG_READER)
+        log_debug ("leave: apdu_close_reader => 0x%x (apdu_disconnect)\n", sw);
+      return sw;
     }
   if (reader_table[slot].close_reader)
-    return reader_table[slot].close_reader (slot);
+    {
+      sw = reader_table[slot].close_reader (slot);
+      if (DBG_READER)
+        log_debug ("leave: apdu_close_reader => 0x%x (close_reader)\n", sw);
+      return sw;
+    }
+  if (DBG_READER)
+    log_debug ("leave: apdu_close_reader => SW_HOST_NOT_SUPPORTED\n");
   return SW_HOST_NOT_SUPPORTED;
 }
 
@@ -3171,6 +3240,43 @@ apdu_prepare_exit (void)
 }
 
 
+/* Shutdown a reader; that is basically the same as a close but keeps
+   the handle ready for later use. A apdu_reset_reader or apdu_connect
+   should be used to get it active again. */
+int
+apdu_shutdown_reader (int slot)
+{
+  int sw;
+
+  if (DBG_READER)
+    log_debug ("enter: apdu_shutdown_reader: slot=%d\n", slot);
+
+  if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_shutdown_reader => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
+  sw = apdu_disconnect (slot);
+  if (sw)
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_shutdown_reader => 0x%x (apdu_disconnect)\n",
+                   sw);
+      return sw;
+    }
+  if (reader_table[slot].shutdown_reader)
+    {
+      sw = reader_table[slot].shutdown_reader (slot);
+      if (DBG_READER)
+        log_debug ("leave: apdu_shutdown_reader => 0x%x (close_reader)\n", sw);
+      return sw;
+    }
+  if (DBG_READER)
+    log_debug ("leave: apdu_shutdown_reader => SW_HOST_NOT_SUPPORTED\n");
+  return SW_HOST_NOT_SUPPORTED;
+}
+
 /* Enumerate all readers and return information on whether this reader
    is in use.  The caller should start with SLOT set to 0 and
    increment it with each call until an error is returned. */
@@ -3191,11 +3297,18 @@ apdu_enum_reader (int slot, int *used)
 int
 apdu_connect (int slot)
 {
-  int sw = 0;
-  unsigned int status = 0;
+  int sw;
+  unsigned int status;
+
+  if (DBG_READER)
+    log_debug ("enter: apdu_connect: slot=%d\n", slot);
 
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_connect => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
 
   /* Only if the access method provides a connect function we use it.
      If not, we expect that the card has been implicitly connected by
@@ -3209,15 +3322,15 @@ apdu_connect (int slot)
           unlock_slot (slot);
         }
     }
+  else
+    sw = 0;
 
   /* We need to call apdu_get_status_internal, so that the last-status
      machinery gets setup properly even if a card is inserted while
      scdaemon is fired up and apdu_get_status has not yet been called.
      Without that we would force a reset of the card with the next
      call to apdu_get_status.  */
-  if (!sw)
-    sw = apdu_get_status_internal (slot, 1, 1, &status, NULL);
-
+  apdu_get_status_internal (slot, 1, 1, &status, NULL);
   if (sw)
     ;
   else if (!(status & APDU_CARD_PRESENT))
@@ -3225,6 +3338,8 @@ apdu_connect (int slot)
   else if ((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE))
     sw = SW_HOST_CARD_INACTIVE;
 
+  if (DBG_READER)
+    log_debug ("leave: apdu_connect => sw=0x%x\n", sw);
 
   return sw;
 }
@@ -3235,8 +3350,15 @@ apdu_disconnect (int slot)
 {
   int sw;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_disconnect: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_disconnect => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
 
   if (reader_table[slot].disconnect_card)
     {
@@ -3249,6 +3371,9 @@ apdu_disconnect (int slot)
     }
   else
     sw = 0;
+
+  if (DBG_READER)
+    log_debug ("leave: apdu_disconnect => sw=0x%x\n", sw);
   return sw;
 }
 
@@ -3284,11 +3409,22 @@ apdu_reset (int slot)
 {
   int sw;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_reset: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_reset => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
 
   if ((sw = lock_slot (slot)))
-    return sw;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_reset => sw=0x%x (lock_slot)\n", sw);
+      return sw;
+    }
 
   reader_table[slot].last_status = 0;
   if (reader_table[slot].reset_reader)
@@ -3304,73 +3440,47 @@ apdu_reset (int slot)
     }
 
   unlock_slot (slot);
+  if (DBG_READER)
+    log_debug ("leave: apdu_reset => sw=0x%x\n", sw);
   return sw;
 }
 
 
-/* Activate a card if it has not yet been done.  This is a kind of
-   reset-if-required.  It is useful to test for presence of a card
-   before issuing a bunch of apdu commands.  It does not wait on a
-   locked card. */
-int
-apdu_activate (int slot)
-{
-  int sw;
-  unsigned int s;
-
-  if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
-
-  if ((sw = trylock_slot (slot)))
-    return sw;
-
-  if (reader_table[slot].get_status_reader)
-    sw = reader_table[slot].get_status_reader (slot, &s);
-
-  if (!sw)
-    {
-      if (!(s & 2))  /* Card not present.  */
-        sw = SW_HOST_NO_CARD;
-      else if ( ((s & 2) && !(s & 4))
-                || !reader_table[slot].atrlen )
-        {
-          /* We don't have an ATR or a card is present though inactive:
-             do a reset now. */
-          if (reader_table[slot].reset_reader)
-            {
-              reader_table[slot].last_status = 0;
-              sw = reader_table[slot].reset_reader (slot);
-              if (!sw)
-                {
-                  /* If we got to here we know that a card is present
-                     and usable.  Thus remember this.  */
-                  reader_table[slot].last_status = (APDU_CARD_USABLE
-                                                    | APDU_CARD_PRESENT
-                                                    | APDU_CARD_ACTIVE);
-                }
-            }
-        }
-    }
-
-  unlock_slot (slot);
-  return sw;
-}
-
-
+/* Return the ATR or NULL if none is available.  On success the length
+   of the ATR is stored at ATRLEN.  The caller must free the returned
+   value.  */
 unsigned char *
 apdu_get_atr (int slot, size_t *atrlen)
 {
   unsigned char *buf;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_get_atr: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return NULL;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_get_atr => NULL (bad slot)\n");
+      return NULL;
+    }
   if (!reader_table[slot].atrlen)
-    return NULL;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_get_atr => NULL (no ATR)\n");
+      return NULL;
+    }
+
   buf = xtrymalloc (reader_table[slot].atrlen);
   if (!buf)
-    return NULL;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_get_atr => NULL (out of core)\n");
+      return NULL;
+    }
   memcpy (buf, reader_table[slot].atr, reader_table[slot].atrlen);
   *atrlen = reader_table[slot].atrlen;
+  if (DBG_READER)
+    log_debug ("leave: apdu_get_atr => atrlen=%zu\n", *atrlen);
   return buf;
 }
 
@@ -3441,7 +3551,26 @@ int
 apdu_get_status (int slot, int hang,
                  unsigned int *status, unsigned int *changed)
 {
-  return apdu_get_status_internal (slot, hang, 0, status, changed);
+  int sw;
+
+  if (DBG_READER)
+    log_debug ("enter: apdu_get_status: slot=%d hang=%d\n", slot, hang);
+  sw = apdu_get_status_internal (slot, hang, 0, status, changed);
+  if (DBG_READER)
+    {
+      if (status && changed)
+        log_debug ("leave: apdu_get_status => sw=0x%x status=%u changecnt=%u\n",
+                   sw, *status, *changed);
+      else if (status)
+        log_debug ("leave: apdu_get_status => sw=0x%x status=%u\n",
+                   sw, *status);
+      else if (changed)
+        log_debug ("leave: apdu_get_status => sw=0x%x changed=%u\n",
+                   sw, *changed);
+      else
+        log_debug ("leave: apdu_get_status => sw=0x%x\n", sw);
+    }
+  return sw;
 }
 
 
@@ -3648,9 +3777,8 @@ send_le (int slot, int class, int ins, int p0, int p1,
 
   if (use_extended_length && (le > 256 || le < 0))
     {
-      /* Two more bytes are needed for status bytes.  */
-      result_buffer_size = le < 0? 4096 : (le + 2);
-      result_buffer = xtrymalloc (result_buffer_size);
+      result_buffer_size = le < 0? 4096 : le;
+      result_buffer = xtrymalloc (result_buffer_size + 10);
       if (!result_buffer)
         {
           xfree (apdu_buffer);
@@ -3682,9 +3810,9 @@ send_le (int slot, int class, int ins, int p0, int p1,
           apdu[apdulen++] = ins;
           apdu[apdulen++] = p0;
           apdu[apdulen++] = p1;
-          if (lc > 0)
+          apdu[apdulen++] = 0;  /* Z byte: Extended length marker.  */
+          if (lc >= 0)
             {
-              apdu[apdulen++] = 0;  /* Z byte: Extended length marker.  */
               apdu[apdulen++] = ((lc >> 8) & 0xff);
               apdu[apdulen++] = (lc & 0xff);
               memcpy (apdu+apdulen, data, lc);
@@ -3693,8 +3821,6 @@ send_le (int slot, int class, int ins, int p0, int p1,
             }
           if (le != -1)
             {
-              if (lc <= 0)
-                apdu[apdulen++] = 0;  /* Z byte: Extended length marker.  */
               apdu[apdulen++] = ((le >> 8) & 0xff);
               apdu[apdulen++] = (le & 0xff);
             }
index ac16ea1..2e518b1 100644 (file)
@@ -36,11 +36,15 @@ enum {
   SW_CC_NOT_SUP     = 0x6884, /* Command Chaining is not supported.  */
   SW_CHV_WRONG      = 0x6982,
   SW_CHV_BLOCKED    = 0x6983,
+  SW_REF_DATA_INV   = 0x6984, /* Referenced data invalidated. */
   SW_USE_CONDITIONS = 0x6985,
   SW_BAD_PARAMETER  = 0x6a80, /* (in the data field) */
   SW_NOT_SUPPORTED  = 0x6a81,
   SW_FILE_NOT_FOUND = 0x6a82,
   SW_RECORD_NOT_FOUND = 0x6a83,
+  SW_NOT_ENOUGH_MEMORY= 0x6a84, /* Not enough memory space in the file.  */
+  SW_INCONSISTENT_LC  = 0x6a85, /* Lc inconsistent with TLV structure.  */
+  SW_INCORRECT_P0_P1  = 0x6a86,
   SW_BAD_LC         = 0x6a87, /* Lc does not match command or p1/p2.  */
   SW_REF_NOT_FOUND  = 0x6a88,
   SW_BAD_P0_P1      = 0x6b00,
@@ -92,6 +96,7 @@ int apdu_open_remote_reader (const char *portstr,
                              void *writefnc_value,
                              void (*closefnc) (void *opaque),
                              void *closefnc_value);
+int apdu_shutdown_reader (int slot);
 int apdu_close_reader (int slot);
 void apdu_prepare_exit (void);
 int apdu_enum_reader (int slot, int *used);
@@ -107,7 +112,6 @@ int apdu_disconnect (int slot);
 
 int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg);
 
-int apdu_activate (int slot);
 int apdu_reset (int slot);
 int apdu_get_status (int slot, int hang,
                      unsigned int *status, unsigned int *changed);
@@ -119,10 +123,10 @@ int apdu_pinpad_modify (int slot, int class, int ins, int p0, int p1,
 int apdu_send_simple (int slot, int extended_mode,
                       int class, int ins, int p0, int p1,
                       int lc, const char *data);
-int apdu_send (int slot, int extended_mode, 
+int apdu_send (int slot, int extended_mode,
                int class, int ins, int p0, int p1, int lc, const char *data,
                unsigned char **retbuf, size_t *retbuflen);
-int apdu_send_le (int slot, int extended_mode, 
+int apdu_send_le (int slot, int extended_mode,
                   int class, int ins, int p0, int p1,
                   int lc, const char *data, int le,
                   unsigned char **retbuf, size_t *retbuflen);
@@ -133,6 +137,3 @@ int apdu_send_direct (int slot, size_t extended_length,
 
 
 #endif /*APDU_H*/
-
-
-
index ac2c2e9..50046a4 100644 (file)
@@ -25,7 +25,7 @@
 #if GNUPG_MAJOR_VERSION == 1
 # ifdef ENABLE_AGENT_SUPPORT
 # include "assuan.h"
-# endif 
+# endif
 #else
 # include <ksba.h>
 #endif
@@ -34,6 +34,9 @@
 #define APP_CHANGE_FLAG_RESET    1
 #define APP_CHANGE_FLAG_NULLPIN  2
 
+/* Bit flags set by the decipher function into R_INFO.  */
+#define APP_DECIPHER_INFO_NOPAD  1  /* Padding has been removed.  */
+
 
 struct app_local_s;  /* Defined by all app-*.c.  */
 
@@ -44,8 +47,13 @@ struct app_ctx_s {
      operations the particular function pointer is set to NULL */
   unsigned int ref_count;
 
+  /* Flag indicating that a reset has been done for that application
+     and that this context is merely lingering and just should not be
+     reused.  */
+  int no_reuse;
+
   /* Used reader slot. */
-  int slot;     
+  int slot;
 
   /* If this is used by GnuPG 1.4 we need to know the assuan context
      in case we need to divert the operation to an already running
@@ -59,10 +67,10 @@ struct app_ctx_s {
   size_t serialnolen;      /* Length in octets of serialnumber. */
   const char *apptype;
   unsigned int card_version;
-  unsigned int did_chv1:1;
-  unsigned int force_chv1:1;   /* True if the card does not cache CHV1. */
-  unsigned int did_chv2:1;
-  unsigned int did_chv3:1;
+  int did_chv1;
+  int force_chv1;   /* True if the card does not cache CHV1. */
+  int did_chv2;
+  int did_chv3;
   struct app_local_s *app_local;  /* Local to the application. */
   struct {
     void (*deinit) (app_t app);
@@ -88,10 +96,11 @@ struct app_ctx_s {
                  const void *indata, size_t indatalen,
                  unsigned char **outdata, size_t *outdatalen);
     gpg_error_t (*decipher) (app_t app, const char *keyidstr,
-                     gpg_error_t (*pincb)(void*, const char *, char **),
-                     void *pincb_arg,
-                     const void *indata, size_t indatalen,
-                     unsigned char **outdata, size_t *outdatalen);
+                             gpg_error_t (*pincb)(void*, const char *, char **),
+                             void *pincb_arg,
+                             const void *indata, size_t indatalen,
+                             unsigned char **outdata, size_t *outdatalen,
+                             unsigned int *r_info);
     gpg_error_t (*writecert) (app_t app, ctrl_t ctrl,
                               const char *certid,
                               gpg_error_t (*pincb)(void*,const char *,char **),
@@ -138,14 +147,15 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff);
 /*-- app.c --*/
 void app_dump_state (void);
 void application_notify_card_reset (int slot);
-gpg_error_t check_application_conflict (ctrl_t ctrl, const char *name);
+gpg_error_t check_application_conflict (ctrl_t ctrl, int slot,
+                                        const char *name);
 gpg_error_t select_application (ctrl_t ctrl, int slot, const char *name,
                                 app_t *r_app);
 char *get_supported_applications (void);
 void release_application (app_t app);
 gpg_error_t app_munge_serialno (app_t app);
 gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp);
-gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl, 
+gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl,
                                     unsigned int flags);
 gpg_error_t app_readcert (app_t app, const char *certid,
                   unsigned char **cert, size_t *certlen);
@@ -162,15 +172,16 @@ gpg_error_t app_sign (app_t app, const char *keyidstr, int hashalgo,
               const void *indata, size_t indatalen,
               unsigned char **outdata, size_t *outdatalen );
 gpg_error_t app_auth (app_t app, const char *keyidstr,
-              gpg_error_t (*pincb)(void*, const char *, char **),
-              void *pincb_arg,
-              const void *indata, size_t indatalen,
-              unsigned char **outdata, size_t *outdatalen);
+                      gpg_error_t (*pincb)(void*, const char *, char **),
+                      void *pincb_arg,
+                      const void *indata, size_t indatalen,
+                      unsigned char **outdata, size_t *outdatalen);
 gpg_error_t app_decipher (app_t app, const char *keyidstr,
-                  gpg_error_t (*pincb)(void*, const char *, char **),
-                  void *pincb_arg,
-                  const void *indata, size_t indatalen,
-                  unsigned char **outdata, size_t *outdatalen );
+                          gpg_error_t (*pincb)(void*, const char *, char **),
+                          void *pincb_arg,
+                          const void *indata, size_t indatalen,
+                          unsigned char **outdata, size_t *outdatalen,
+                          unsigned int *r_info);
 gpg_error_t app_writecert (app_t app, ctrl_t ctrl,
                            const char *certidstr,
                            gpg_error_t (*pincb)(void*, const char *, char **),
@@ -212,12 +223,12 @@ gpg_error_t app_select_p15 (app_t app);
 /*-- app-geldkarte.c --*/
 gpg_error_t app_select_geldkarte (app_t app);
 
+/*-- app-sc-hsm.c --*/
+gpg_error_t app_select_sc_hsm (app_t app);
+
 
 #endif
 
 
 
 #endif /*GNUPG_SCD_APP_COMMON_H*/
-
-
-
index 1a0cb60..7dad6b1 100644 (file)
@@ -22,7 +22,7 @@
    used with an interface specification described in DIN V 66291-1.
    The AID to be used is: 'D27600006601'.
 
-   The file IDs for certificates utilize the generic format: 
+   The file IDs for certificates utilize the generic format:
         Cxyz
     C being the hex digit 'C' (12).
     x being the service indicator:
          '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
          'E'        := C.RCA (self certified certificate of the Root-CA).
          'F'        := reserved.
-   
+
    The file IDs used by default are:
    '1F00'  EF.SSD (security service descriptor). [o,o]
    '2F02'  EF.GDO (global data objects) [m,m]
    'A000'  EF.PROT (signature log).  Cyclic file with 20 records of 53 byte.
            Read and update after user authentication. [o,o]
-   'B000'  EF.PK.RCA.DS (public keys of Root-CA).  Size is 512b or size 
+   'B000'  EF.PK.RCA.DS (public keys of Root-CA).  Size is 512b or size
            of keys. [m (unless a 'C00E' is present),m]
    'B001'  EF.PK.CA.DS (public keys of CAs).  Size is 512b or size
            of keys. [o,o]
            with n := 0 .. 7.  Size is 2k or size of cert.  Read and
            update allowed after user authentication. [m,m]
    'C00m'  EF.C.CA.DS (digital signature certificate of CA)
-           with m := 8 .. E.  Size is 1k or size of cert.  Read always 
+           with m := 8 .. E.  Size is 1k or size of cert.  Read always
            allowed, update after user authentication. [o,o]
    'C100'  EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
    'C108'  EF.C.CA.AUT (AUT certificate of CA) [o,m]
    'D000'  EF.DM (display message) [-,m]
-   
+
    The letters in brackets indicate optional or mandatory files: The
    first for card terminals under full control and the second for
    "business" card terminals.
@@ -101,15 +101,15 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
 
   /* Return the certificate of the card holder. */
   fid = 0xC000;
-  len = app_help_read_length_of_cert (app->slot, fid, &certoff); 
+  len = app_help_read_length_of_cert (app->slot, fid, &certoff);
   if (!len)
     return 0; /* Card has not been personalized. */
 
   sprintf (ct_buf, "%d", 101);
   sprintf (id_buf, "DINSIG.%04X", fid);
   send_status_info (ctrl, "CERTINFO",
-                    ct_buf, strlen (ct_buf), 
-                    id_buf, strlen (id_buf), 
+                    ct_buf, strlen (ct_buf),
+                    id_buf, strlen (id_buf),
                     NULL, (size_t)0);
 
   /* Now we need to read the certificate, so that we can get the
@@ -128,7 +128,7 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
       xfree (der);
       return err;
     }
-  err = ksba_cert_init_from_mem (cert, der, derlen); 
+  err = ksba_cert_init_from_mem (cert, der, derlen);
   xfree (der); der = NULL;
   if (err)
     {
@@ -143,13 +143,13 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
       log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid);
       ksba_cert_release (cert);
       return gpg_error (GPG_ERR_CARD);
-    }      
+    }
   ksba_cert_release (cert);
 
   sprintf (id_buf, "DINSIG.%04X", fid);
   send_status_info (ctrl, "KEYPAIRINFO",
-                    hexkeygrip, 40, 
-                    id_buf, strlen (id_buf), 
+                    hexkeygrip, 40,
+                    id_buf, strlen (id_buf),
                     NULL, (size_t)0);
   return 0;
 }
@@ -160,7 +160,7 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
 /* Read the certificate with id CERTID (as returned by learn_status in
    the CERTINFO status lines) and return it in the freshly allocated
    buffer put into CERT and the length of the certificate put into
-   CERTLEN. 
+   CERTLEN.
 
    FIXME: This needs some cleanups and caching with do_learn_status.
 */
@@ -179,11 +179,11 @@ do_readcert (app_t app, const char *certid,
 
   *cert = NULL;
   *certlen = 0;
-  if (strncmp (certid, "DINSIG.", 7) ) 
+  if (strncmp (certid, "DINSIG.", 7) )
     return gpg_error (GPG_ERR_INV_ID);
   certid += 7;
   if (!hexdigitp (certid) || !hexdigitp (certid+1)
-      || !hexdigitp (certid+2) || !hexdigitp (certid+3) 
+      || !hexdigitp (certid+2) || !hexdigitp (certid+3)
       || certid[4])
     return gpg_error (GPG_ERR_INV_ID);
   fid = xtoi_4 (certid);
@@ -207,7 +207,7 @@ do_readcert (app_t app, const char *certid,
                  fid, gpg_strerror (err));
       return err;
     }
-  
+
   if (!buflen || *buffer == 0xff)
     {
       log_info ("no certificate contained in FID 0x%04X\n", fid);
@@ -235,13 +235,13 @@ do_readcert (app_t app, const char *certid,
                           &ndef, &objlen, &hdrlen);
   if (err)
     goto leave;
-  
+
   if (rootca)
     ;
   else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
     {
       const unsigned char *save_p;
-  
+
       /* The certificate seems to be contained in a userCertificate
          container.  Skip this and assume the following sequence is
          the certificate. */
@@ -255,7 +255,7 @@ do_readcert (app_t app, const char *certid,
       save_p = p;
       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
                               &ndef, &objlen, &hdrlen);
-      if (err) 
+      if (err)
         goto leave;
       if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
         return gpg_error (GPG_ERR_INV_OBJ);
@@ -263,7 +263,7 @@ do_readcert (app_t app, const char *certid,
       assert (save_p + totobjlen <= buffer + buflen);
       memmove (buffer, save_p, totobjlen);
     }
-  
+
   *cert = buffer;
   buffer = NULL;
   *certlen = totobjlen;
@@ -284,7 +284,7 @@ verify_pin (app_t app,
   int rc;
   pininfo_t pininfo;
 
-  if ( app->did_chv1 && !app->force_chv1 ) 
+  if ( app->did_chv1 && !app->force_chv1 )
     return 0;  /* No need to verify it again.  */
 
   memset (&pininfo, 0, sizeof pininfo);
@@ -355,7 +355,7 @@ verify_pin (app_t app,
              this. */
           char paddedpin[8];
           int i, ndigits;
-          
+
           for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
             ;
           i = 0;
@@ -386,7 +386,7 @@ verify_pin (app_t app,
    If a PIN is required the PINCB will be used to ask for the PIN;
    that callback should return the PIN in an allocated buffer and
    store that in the 3rd argument.  */
-static gpg_error_t 
+static gpg_error_t
 do_sign (app_t app, const char *keyidstr, int hashalgo,
          gpg_error_t (*pincb)(void*, const char *, char **),
          void *pincb_arg,
@@ -417,11 +417,11 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 
   /* Check that the provided ID is vaid.  This is not really needed
      but we do it to to enforce correct usage by the caller. */
-  if (strncmp (keyidstr, "DINSIG.", 7) ) 
+  if (strncmp (keyidstr, "DINSIG.", 7) )
     return gpg_error (GPG_ERR_INV_ID);
   keyidstr += 7;
   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
-      || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) 
+      || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
       || keyidstr[4])
     return gpg_error (GPG_ERR_INV_ID);
   fid = xtoi_4 (keyidstr);
@@ -439,7 +439,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
         ;
       else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15))
         ;
-      else 
+      else
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data, indata, indatalen);
     }
@@ -459,7 +459,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
           hashalgo = GCRY_MD_SHA256;
           datalen  = indatalen;
         }
-      else 
+      else
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data, indata, indatalen);
     }
@@ -476,14 +476,14 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
           datalen = len + indatalen;
           memcpy (data, sha256_prefix, len);
         }
-      else 
+      else
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data+len, indata, indatalen);
     }
 
   rc = verify_pin (app, pincb, pincb_arg);
   if (!rc)
-    rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0, 
+    rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0,
                              outdata, outdatalen);
   return rc;
 }
@@ -493,8 +493,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 #warning test function - works but may brick your card
 /* Handle the PASSWD command.  CHVNOSTR is currently ignored; we
    always use VHV0.  RESET_MODE is not yet implemented.  */
-static gpg_error_t 
-do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr, 
+static gpg_error_t
+do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
                unsigned int flags,
                gpg_error_t (*pincb)(void*, const char *, char **),
                void *pincb_arg)
@@ -526,14 +526,14 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
   /* TRANSLATORS: Do not translate the "|*|" prefixes but
      keep it at the start of the string.  We need this elsewhere
      to get some infos on the string. */
-  err = pincb (pincb_arg, _("|N|Initial New PIN"), &pinvalue); 
+  err = pincb (pincb_arg, _("|N|Initial New PIN"), &pinvalue);
   if (err)
     {
       log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
       return err;
     }
 
-  err = iso7816_change_reference_data (app->slot, 0x81, 
+  err = iso7816_change_reference_data (app->slot, 0x81,
                                        oldpin, oldpinlen,
                                        pinvalue, strlen (pinvalue));
   xfree (pinvalue);
@@ -550,7 +550,7 @@ app_select_dinsig (app_t app)
   static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
   int slot = app->slot;
   int rc;
-  
+
   rc = iso7816_select_application (slot, aid, sizeof aid, 0);
   if (!rc)
     {
index 6e8d077..f8ee9f6 100644 (file)
@@ -90,13 +90,13 @@ send_one_string (ctrl_t ctrl, const char *name, const char *string)
 
 /* Implement the GETATTR command.  This is similar to the LEARN
    command but returns just one value via the status interface. */
-static gpg_error_t 
+static gpg_error_t
 do_getattr (app_t app, ctrl_t ctrl, const char *name)
 {
   gpg_error_t err;
   struct app_local_s *ld = app->app_local;
   char numbuf[100];
-  
+
   if (!strcmp (name, "X-KBLZ"))
     err = send_one_string (ctrl, name, ld->kblz);
   else if (!strcmp (name, "X-BANKINFO"))
@@ -123,24 +123,24 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
     }
   else if (!strcmp (name, "X-BALANCE"))
     {
-      snprintf (numbuf, sizeof numbuf, "%.2f", 
+      snprintf (numbuf, sizeof numbuf, "%.2f",
                 (double)ld->balance / 100 * ld->currency_mult100);
       err = send_one_string (ctrl, name, numbuf);
     }
   else if (!strcmp (name, "X-MAXAMOUNT"))
     {
-      snprintf (numbuf, sizeof numbuf, "%.2f", 
+      snprintf (numbuf, sizeof numbuf, "%.2f",
                 (double)ld->maxamount / 100 * ld->currency_mult100);
       err = send_one_string (ctrl, name, numbuf);
     }
   else if (!strcmp (name, "X-MAXAMOUNT1"))
     {
-      snprintf (numbuf, sizeof numbuf, "%.2f", 
+      snprintf (numbuf, sizeof numbuf, "%.2f",
                 (double)ld->maxamount1 / 100 * ld->currency_mult100);
       err = send_one_string (ctrl, name, numbuf);
     }
   else
-    err = gpg_error (GPG_ERR_INV_NAME); 
+    err = gpg_error (GPG_ERR_INV_NAME);
 
   return err;
 }
@@ -185,7 +185,7 @@ copy_bcd (const unsigned char *string, size_t length)
 
   if (!length)
     return xtrystrdup ("");
-      
+
   /* Skip leading zeroes. */
   for (; length && !*string; length--, string++)
     ;
@@ -196,7 +196,7 @@ copy_bcd (const unsigned char *string, size_t length)
     {
       if (!needed && !(*s & 0xf0))
         ; /* Skip the leading zero in the first nibble.  */
-      else 
+      else
         {
           if ( ((*s >> 4) & 0x0f) > 9 )
             {
@@ -216,7 +216,7 @@ copy_bcd (const unsigned char *string, size_t length)
               return NULL;
             }
         }
-      
+
     }
   if (!needed) /* If it is all zero, print a "0". */
     needed++;
@@ -227,12 +227,12 @@ copy_bcd (const unsigned char *string, size_t length)
 
   s = string;
   n = length;
-  needed = 0;  
+  needed = 0;
   for (; n ; n--, s++)
     {
       if (!needed && !(*s & 0xf0))
         ; /* Skip the leading zero in the first nibble.  */
-      else 
+      else
         {
           *dst++ = '0' + ((*s >> 4) & 0x0f);
           needed++;
@@ -247,7 +247,7 @@ copy_bcd (const unsigned char *string, size_t length)
         }
     }
   if (!needed)
-    *dst++ = '0';  
+    *dst++ = '0';
   *dst = 0;
 
   return buffer;
@@ -282,11 +282,11 @@ app_select_geldkarte (app_t app)
   size_t resultlen;
   struct app_local_s *ld;
   const char *banktype;
-  
+
   err = iso7816_select_application (slot, aid, sizeof aid, 0);
   if (err)
-    goto leave; 
-  
+    goto leave;
+
   /* Read the first record of EF_ID (SFI=0x17).  We require this
      record to be at least 24 bytes with the the first byte 0x67 and a
      correct filler byte. */
@@ -298,7 +298,7 @@ app_select_geldkarte (app_t app)
       err = gpg_error (GPG_ERR_NOT_FOUND);
       goto leave;
     }
-  
+
   /* The short Bankleitzahl consists of 3 bytes at offset 1.  */
   switch (result[1])
     {
@@ -307,11 +307,11 @@ app_select_geldkarte (app_t app)
     case 0x25: banktype = "Sparkasse"; break;
     case 0x26:
     case 0x29: banktype = "Genossenschaftsbank"; break;
-    default: 
+    default:
       err = gpg_error (GPG_ERR_NOT_FOUND);
       goto leave; /* Probably not a Geldkarte. */
     }
-  
+
   app->apptype = "GELDKARTE";
   app->fnc.deinit = do_deinit;
 
@@ -339,7 +339,7 @@ app_select_geldkarte (app_t app)
       goto leave;
     }
 
-  snprintf (ld->kblz, sizeof ld->kblz, "%02X-%02X%02X", 
+  snprintf (ld->kblz, sizeof ld->kblz, "%02X-%02X%02X",
             result[1], result[2], result[3]);
   ld->banktype = banktype;
   ld->cardno = copy_bcd (result+4, 5);
@@ -348,8 +348,8 @@ app_select_geldkarte (app_t app)
       err = gpg_err_code_from_syserror ();
       goto leave;
     }
-  
-  snprintf (ld->expires, sizeof ld->expires, "20%02X-%02X", 
+
+  snprintf (ld->expires, sizeof ld->expires, "20%02X-%02X",
             result[10], result[11]);
   snprintf (ld->validfrom, sizeof ld->validfrom, "20%02X-%02X-%02X",
             result[12], result[13], result[14]);
index 3d9c605..2576d5c 100644 (file)
@@ -120,7 +120,7 @@ app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff)
                  fid, gpg_strerror (err));
       return 0;
     }
-  
+
   if (!buflen || *buffer == 0xff)
     {
       log_info ("no certificate contained in FID 0x%04X\n", fid);
@@ -178,5 +178,3 @@ app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff)
 
   return resultlen;
 }
-
-
index f117445..19a33ed 100644 (file)
@@ -188,8 +188,8 @@ keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr)
          libgcrypt but we can't yet rely on it yet.  */
       for (i=0; i < 2; i++)
         {
-          while (buflen[i]-offset[i] > 1 
-                 && !buffer[i][offset[i]] 
+          while (buflen[i]-offset[i] > 1
+                 && !buffer[i][offset[i]]
                  && !(buffer[i][offset[i]+1] & 0x80))
             offset[i]++;
         }
@@ -201,9 +201,9 @@ keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr)
     {
       if ((buflen[i]-offset[i]) && (buffer[i][offset[i]] & 0x80))
         {
-          unsigned char *newbuf;          
+          unsigned char *newbuf;
           size_t newlen;
-          
+
           newlen = 1 + buflen[i] - offset[i];
           newbuf = xtrymalloc (newlen);
           if (!newlen)
@@ -271,7 +271,7 @@ get_chv_status (app_t app, int sigg, int pwid)
   command[2] = 0x00;
   command[3] = pwid;
 
-  if (apdu_send_direct (app->slot, 0, (unsigned char *)command, 
+  if (apdu_send_direct (app->slot, 0, (unsigned char *)command,
                         4, 0, &result, &resultlen))
     rc = -1; /* Error. */
   else if (resultlen < 2)
@@ -299,7 +299,7 @@ get_chv_status (app_t app, int sigg, int pwid)
 
 /* Implement the GETATTR command.  This is similar to the LEARN
    command but returns just one value via the status interface. */
-static gpg_error_t 
+static gpg_error_t
 do_getattr (app_t app, ctrl_t ctrl, const char *name)
 {
   static struct {
@@ -322,7 +322,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
   for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++)
     ;
   if (!table[idx].name)
-    return gpg_error (GPG_ERR_INV_NAME); 
+    return gpg_error (GPG_ERR_INV_NAME);
 
   switch (table[idx].special)
     {
@@ -350,7 +350,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
            two global passwords followed by the two SigG passwords.
            For the values, see the function get_chv_status.  */
         int tmp[4];
-        
+
         /* We use a helper array so that we can control that there is
            no superfluous application switch.  Note that PW2.CH.SIG
            really has the identifier 0x83 and not 0x82 as one would
@@ -358,8 +358,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
         tmp[0] = get_chv_status (app, 0, 0x00);
         tmp[1] = get_chv_status (app, 0, 0x01);
         tmp[2] = get_chv_status (app, 1, 0x81);
-        tmp[3] = get_chv_status (app, 1, 0x83); 
-        snprintf (buffer, sizeof buffer, 
+        tmp[3] = get_chv_status (app, 1, 0x83);
+        snprintf (buffer, sizeof buffer,
                   "%d %d %d %d", tmp[0], tmp[1], tmp[2], tmp[3]);
         send_status_info (ctrl, table[idx].name,
                           buffer, strlen (buffer), NULL, 0);
@@ -413,11 +413,11 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
                  context so that a following readcert does only need to
                  read that many bytes. */
               snprintf (ct_buf, sizeof ct_buf, "%d", filelist[i].certtype);
-              snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X", 
+              snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
                         tag, filelist[i].fid);
               send_status_info (ctrl, "CERTINFO",
-                                ct_buf, strlen (ct_buf), 
-                                id_buf, strlen (id_buf), 
+                                ct_buf, strlen (ct_buf),
+                                id_buf, strlen (id_buf),
                                 NULL, (size_t)0);
             }
         }
@@ -434,8 +434,8 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
               snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
                         tag, filelist[i].fid);
               send_status_info (ctrl, "KEYPAIRINFO",
-                                gripstr, 40, 
-                                id_buf, strlen (id_buf), 
+                                gripstr, 40,
+                                id_buf, strlen (id_buf),
                                 NULL, (size_t)0);
             }
         }
@@ -453,7 +453,7 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
   err = switch_application (app, 0);
   if (err)
     return err;
-  
+
   do_learn_status_core (app, ctrl, flags, 0);
 
   err = switch_application (app, 1);
@@ -489,11 +489,11 @@ do_readcert (app_t app, const char *certid,
   *cert = NULL;
   *certlen = 0;
 
-  if (!strncmp (certid, "NKS-NKS3.", 9)) 
+  if (!strncmp (certid, "NKS-NKS3.", 9))
     ;
-  else if (!strncmp (certid, "NKS-DF01.", 9)) 
+  else if (!strncmp (certid, "NKS-DF01.", 9))
     ;
-  else if (!strncmp (certid, "NKS-SIGG.", 9)) 
+  else if (!strncmp (certid, "NKS-SIGG.", 9))
     is_sigg = 1;
   else
     return gpg_error (GPG_ERR_INV_ID);
@@ -504,7 +504,7 @@ do_readcert (app_t app, const char *certid,
 
   certid += 9;
   if (!hexdigitp (certid) || !hexdigitp (certid+1)
-      || !hexdigitp (certid+2) || !hexdigitp (certid+3) 
+      || !hexdigitp (certid+2) || !hexdigitp (certid+3)
       || certid[4])
     return gpg_error (GPG_ERR_INV_ID);
   fid = xtoi_4 (certid);
@@ -541,7 +541,7 @@ do_readcert (app_t app, const char *certid,
                  fid, gpg_strerror (err));
       return err;
     }
-  
+
   if (!buflen || *buffer == 0xff)
     {
       log_info ("no certificate contained in FID 0x%04X\n", fid);
@@ -569,13 +569,13 @@ do_readcert (app_t app, const char *certid,
                           &ndef, &objlen, &hdrlen);
   if (err)
     goto leave;
-  
+
   if (rootca)
     ;
   else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
     {
       const unsigned char *save_p;
-  
+
       /* The certificate seems to be contained in a userCertificate
          container.  Skip this and assume the following sequence is
          the certificate. */
@@ -589,7 +589,7 @@ do_readcert (app_t app, const char *certid,
       save_p = p;
       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
                               &ndef, &objlen, &hdrlen);
-      if (err) 
+      if (err)
         goto leave;
       if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
         return gpg_error (GPG_ERR_INV_OBJ);
@@ -597,7 +597,7 @@ do_readcert (app_t app, const char *certid,
       assert (save_p + totobjlen <= buffer + buflen);
       memmove (buffer, save_p, totobjlen);
     }
-  
+
   *cert = buffer;
   buffer = NULL;
   *certlen = totobjlen;
@@ -628,7 +628,7 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
   if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
     ;
   else /* Return the error code expected by cmd_readkey.  */
-    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); 
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
 
   /* Access the KEYD file which is always in the master directory.  */
   err = iso7816_select_path (app->slot, path, DIM (path), NULL, NULL);
@@ -696,14 +696,14 @@ do_writekey (app_t app, ctrl_t ctrl,
     ;
   else
     return gpg_error (GPG_ERR_INV_ID);
-  
+
   if (!force && !do_readkey (app, keyid, NULL, NULL))
     return gpg_error (GPG_ERR_EEXIST);
 
   /* Parse the S-expression.  */
   err = get_rsa_pk_from_canon_sexp (keydata, keydatalen,
                                     &rsa_n, &rsa_n_len, &rsa_e, &rsa_e_len);
-  if (err) 
+  if (err)
     goto leave;
 
   /* Check that the parameters match the requirements.  */
@@ -732,7 +732,7 @@ do_writekey (app_t app, ctrl_t ctrl,
   /* Send the MSE:Store_Public_Key.  */
   err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
 /*   mse = xtrymalloc (1000); */
-  
+
 /*   mse[0] = 0x80; /\* Algorithm reference.  *\/ */
 /*   mse[1] = 1; */
 /*   mse[2] = 0x17; */
@@ -810,7 +810,7 @@ verify_pin (app_t app, int pwid, const char *desc,
     {
       char *pinvalue;
 
-      rc = pincb (pincb_arg, desc, &pinvalue); 
+      rc = pincb (pincb_arg, desc, &pinvalue);
       if (rc)
         {
           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
@@ -845,7 +845,7 @@ verify_pin (app_t app, int pwid, const char *desc,
    If a PIN is required the PINCB will be used to ask for the PIN;
    that callback should return the PIN in an allocated buffer and
    store that in the 3rd argument.  */
-static gpg_error_t 
+static gpg_error_t
 do_sign (app_t app, const char *keyidstr, int hashalgo,
          gpg_error_t (*pincb)(void*, const char *, char **),
          void *pincb_arg,
@@ -876,11 +876,11 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 
   /* Check that the provided ID is valid.  This is not really needed
      but we do it to enforce correct usage by the caller. */
-  if (!strncmp (keyidstr, "NKS-NKS3.", 9) ) 
+  if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
     ;
-  else if (!strncmp (keyidstr, "NKS-DF01.", 9) ) 
+  else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
     ;
-  else if (!strncmp (keyidstr, "NKS-SIGG.", 9) ) 
+  else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
     is_sigg = 1;
   else
     return gpg_error (GPG_ERR_INV_ID);
@@ -897,7 +897,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
     }
 
   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
-      || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) 
+      || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
       || keyidstr[4])
     return gpg_error (GPG_ERR_INV_ID);
   fid = xtoi_4 (keyidstr);
@@ -914,7 +914,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   if (app->app_local->nks_version > 2 && (indatalen == 35
                                           || indatalen == 47
                                           || indatalen == 51
-                                          || indatalen == 67 
+                                          || indatalen == 67
                                           || indatalen == 83))
     {
       /* The caller send data matching the length of the ASN.1 encoded
@@ -931,7 +931,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
         ;
       else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata,rmd160_prefix,15))
         ;
-      else 
+      else
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data, indata, indatalen);
       datalen = 35;
@@ -942,7 +942,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
         memcpy (data, sha1_prefix, 15);
       else if (hashalgo == GCRY_MD_RMD160)
         memcpy (data, rmd160_prefix, 15);
-      else 
+      else
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data+15, indata, indatalen);
       datalen = 35;
@@ -955,7 +955,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   if (app->app_local->nks_version > 2)
     {
       unsigned char mse[6];
-      
+
       mse[0] = 0x80; /* Algorithm reference.  */
       mse[1] = 1;
       mse[2] = 2;    /* RSA, card does pkcs#1 v1.5 padding, no ASN.1 check.  */
@@ -980,28 +980,31 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
    If a PIN is required the PINCB will be used to ask for the PIN; it
    should return the PIN in an allocated buffer and put it into PIN.  */
-static gpg_error_t 
+static gpg_error_t
 do_decipher (app_t app, const char *keyidstr,
              gpg_error_t (*pincb)(void*, const char *, char **),
              void *pincb_arg,
              const void *indata, size_t indatalen,
-             unsigned char **outdata, size_t *outdatalen )
+             unsigned char **outdata, size_t *outdatalen,
+             unsigned int *r_info)
 {
   int rc, i;
   int is_sigg = 0;
   int fid;
   int kid;
 
+  (void)r_info;
+
   if (!keyidstr || !*keyidstr || !indatalen)
     return gpg_error (GPG_ERR_INV_VALUE);
 
   /* Check that the provided ID is valid.  This is not really needed
      but we do it to to enforce correct usage by the caller. */
-  if (!strncmp (keyidstr, "NKS-NKS3.", 9) ) 
+  if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
     ;
-  else if (!strncmp (keyidstr, "NKS-DF01.", 9) ) 
+  else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
     ;
-  else if (!strncmp (keyidstr, "NKS-SIGG.", 9) ) 
+  else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
     is_sigg = 1;
   else
     return gpg_error (GPG_ERR_INV_ID);
@@ -1012,7 +1015,7 @@ do_decipher (app_t app, const char *keyidstr,
     return rc;
 
   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
-      || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) 
+      || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
       || keyidstr[4])
     return gpg_error (GPG_ERR_INV_ID);
   fid = xtoi_4 (keyidstr);
@@ -1039,7 +1042,7 @@ do_decipher (app_t app, const char *keyidstr,
     }
   else
     {
-      static const unsigned char mse[] = 
+      static const unsigned char mse[] =
         {
           0x80, 1, 0x10, /* Select algorithm RSA. */
           0x84, 1, 0x81  /* Select local secret key 1 for decryption. */
@@ -1122,7 +1125,10 @@ parse_pwidstr (const char *pwidstr, int new_mode, int *r_sigg, int *r_pwid)
                   "for the key to create qualified signatures."));
     }
   else
-    desc = NULL;
+    {
+      *r_pwid = 0; /* Only to avoid gcc warning in calling function.  */
+      desc = NULL; /* Error.  */
+    }
 
   return desc;
 }
@@ -1130,8 +1136,8 @@ parse_pwidstr (const char *pwidstr, int new_mode, int *r_sigg, int *r_pwid)
 
 /* Handle the PASSWD command. See parse_pwidstr() for allowed values
    for CHVNOSTR.  */
-static gpg_error_t 
-do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr, 
+static gpg_error_t
+do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
                unsigned int flags,
                gpg_error_t (*pincb)(void*, const char *, char **),
                void *pincb_arg)
@@ -1153,7 +1159,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
   memset (&pininfo, 0, sizeof pininfo);
   pininfo.minlen = 6;
   pininfo.maxlen = 16;
-  
+
   newdesc = parse_pwidstr (pwidstr, 1, &is_sigg, &pwid);
   if (!newdesc)
     return gpg_error (GPG_ERR_INV_ID);
@@ -1204,7 +1210,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
           /* Regular change mode:  Ask for the old PIN.  */
           desc = parse_pwidstr (pwidstr, 0, &dummy1, &dummy2);
         }
-      err = pincb (pincb_arg, desc, &oldpin); 
+      err = pincb (pincb_arg, desc, &oldpin);
       if (err)
         {
           log_error ("error getting old PIN: %s\n", gpg_strerror (err));
@@ -1216,14 +1222,14 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
         goto leave;
     }
 
-  err = pincb (pincb_arg, newdesc, &newpin); 
+  err = pincb (pincb_arg, newdesc, &newpin);
   if (err)
     {
       log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
       goto leave;
     }
   newpinlen = strlen (newpin);
-  
+
   err = basic_pin_checks (newpin, pininfo.minlen, pininfo.maxlen);
   if (err)
     goto leave;
@@ -1246,8 +1252,8 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
       wipememory (data, datalen);
       xfree (data);
     }
-  else 
-    err = iso7816_change_reference_data (app->slot, pwid, 
+  else
+    err = iso7816_change_reference_data (app->slot, pwid,
                                          oldpin, oldpinlen,
                                          newpin, newpinlen);
  leave:
@@ -1258,7 +1264,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
 
 
 /* Perform a simple verify operation.  KEYIDSTR should be NULL or empty.  */
-static gpg_error_t 
+static gpg_error_t
 do_check_pin (app_t app, const char *pwidstr,
               gpg_error_t (*pincb)(void*, const char *, char **),
               void *pincb_arg)
@@ -1288,10 +1294,10 @@ get_nks_version (int slot)
   size_t resultlen;
   int type;
 
-  if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0, 
+  if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0,
                            &result, &resultlen))
     return 2; /* NKS 2 does not support this command.  */
-  
+
   /* Example value:    04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
                        vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx
      vendor (Philips) -+  |  |                 |  |  |  |           |
@@ -1332,7 +1338,7 @@ switch_application (app_t app, int enable_sigg)
   else
     err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0);
 
-  if (!err && enable_sigg && app->app_local->nks_version >= 3 
+  if (!err && enable_sigg && app->app_local->nks_version >= 3
       && !app->app_local->sigg_msig_checked)
     {
       /* Check whether this card is a mass signature card.  */
@@ -1340,7 +1346,7 @@ switch_application (app_t app, int enable_sigg)
       size_t buflen;
       const unsigned char *tmpl;
       size_t tmpllen;
-      
+
       app->app_local->sigg_msig_checked = 1;
       app->app_local->sigg_is_msig = 1;
       err = iso7816_select_file (app->slot, 0x5349, 0, NULL, NULL);
@@ -1349,7 +1355,7 @@ switch_application (app_t app, int enable_sigg)
       if (!err)
         {
           tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen);
-          if (tmpl && tmpllen == 12 
+          if (tmpl && tmpllen == 12
               && !memcmp (tmpl,
                           "\x93\x02\x00\x01\xA4\x06\x83\x01\x81\x83\x01\x83",
                           12))
@@ -1359,7 +1365,7 @@ switch_application (app_t app, int enable_sigg)
       if (app->app_local->sigg_is_msig)
         log_info ("This is a mass signature card\n");
     }
-  
+
   if (!err)
     {
       app->app_local->need_app_select = 0;
@@ -1379,7 +1385,7 @@ app_select_nks (app_t app)
 {
   int slot = app->slot;
   int rc;
-  
+
   rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0);
   if (!rc)
     {
@@ -1416,5 +1422,3 @@ app_select_nks (app_t app)
     do_deinit (app);
   return rc;
 }
-
-
index 5983aba..9b4ab22 100644 (file)
@@ -1,6 +1,6 @@
 /* app-openpgp.c - The OpenPGP card application.
  * Copyright (C) 2003, 2004, 2005, 2007, 2008,
- *               2009, 2013 Free Software Foundation, Inc.
+ *               2009, 2013, 2014 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -45,6 +45,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <assert.h>
 #include <time.h>
@@ -66,8 +67,6 @@
 #include "iso7816.h"
 #include "app-common.h"
 #include "tlv.h"
-#include "host2net.h"
-#include "cipher.h"
 
 
 /* A table describing the DOs of the card.  */
@@ -118,6 +117,17 @@ static struct {
 };
 
 
+/* Type of keys.  */
+typedef enum
+  {
+    KEY_TYPE_ECDH,
+    KEY_TYPE_ECDSA,
+    KEY_TYPE_EDDSA,
+    KEY_TYPE_RSA,
+  }
+key_type_t;
+
+
 /* The format of RSA private keys.  */
 typedef enum
   {
@@ -130,6 +140,18 @@ typedef enum
 rsa_key_format_t;
 
 
+/* Elliptic Curves.  */
+enum
+  {
+    CURVE_NIST_P256,
+    CURVE_NIST_P384,
+    CURVE_NIST_P521,
+    CURVE_SEC_P256K1,
+    CURVE_ED25519,
+    CURVE_UNKNOWN,
+  };
+
+
 /* One cache item for DOs.  */
 struct cache_s {
   struct cache_s *next;
@@ -182,6 +204,8 @@ struct app_local_s {
     unsigned int sm_aes128:1;          /* Use AES-128 for SM.  */
     unsigned int max_certlen_3:16;
     unsigned int max_get_challenge:16; /* Maximum size for get_challenge.  */
+    unsigned int max_cmd_data:16;      /* Maximum data size for a command.  */
+    unsigned int max_rsp_data:16;      /* Maximum size of a response.  */
   } extcap;
 
   /* Flags used to control the application.  */
@@ -199,15 +223,30 @@ struct app_local_s {
     int fixedlen_admin;
   } pinpad;
 
-  struct
-  {
-    unsigned int n_bits;     /* Size of the modulus in bits.  The rest
-                                of this strucuire is only valid if
-                                this is not 0.  */
-    unsigned int e_bits;     /* Size of the public exponent in bits.  */
-    rsa_key_format_t format;
-  } keyattr[3];
-
+   struct
+   {
+    key_type_t key_type;
+    union {
+      struct {
+        unsigned int n_bits;     /* Size of the modulus in bits.  The rest
+                                    of this strucuire is only valid if
+                                    this is not 0.  */
+        unsigned int e_bits;     /* Size of the public exponent in bits.  */
+        rsa_key_format_t format;
+      } rsa;
+      struct {
+        int curve;
+      } ecdsa;
+      struct {
+        int curve;
+      } eddsa;
+      struct {
+        int curve;
+        int hashalgo;
+        int cipheralgo;
+      } ecdh;
+    };
+   } keyattr[3];
 };
 
 
@@ -298,7 +337,7 @@ get_cached_data (app_t app, int tag,
     }
 
   if (try_extlen && app->app_local->cardcap.ext_lc_le)
-    exmode = app->app_local->extcap.max_certlen_3;
+    exmode = app->app_local->extcap.max_rsp_data;
   else
     exmode = 0;
 
@@ -428,7 +467,10 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
 
   if (app->card_version > 0x0100 && data_objects[i].get_immediate_in_v11)
     {
-      exmode = 0;
+      if (data_objects[i].try_extlen && app->app_local->cardcap.ext_lc_le)
+        exmode = app->app_local->extcap.max_rsp_data;
+      else
+        exmode = 0;
       rc = iso7816_get_data (app->slot, exmode, tag, &buffer, &buflen);
       if (rc)
         {
@@ -509,17 +551,17 @@ dump_all_do (int slot)
       if (gpg_err_code (rc) == GPG_ERR_NO_OBJ)
         ;
       else if (rc)
-        log_info ("DO `%s' not available: %s\n",
+        log_info ("DO '%s' not available: %s\n",
                   data_objects[i].desc, gpg_strerror (rc));
       else
         {
           if (data_objects[i].binary)
             {
-              log_info ("DO `%s': ", data_objects[i].desc);
+              log_info ("DO '%s': ", data_objects[i].desc);
               log_printhex ("", buffer, buflen);
             }
           else
-            log_info ("DO `%s': `%.*s'\n",
+            log_info ("DO '%s': '%.*s'\n",
                       data_objects[i].desc,
                       (int)buflen, buffer); /* FIXME: sanitize */
 
@@ -542,14 +584,14 @@ dump_all_do (int slot)
                     {
                       if (data_objects[j].binary)
                         {
-                          log_info ("DO `%s': ", data_objects[j].desc);
+                          log_info ("DO '%s': ", data_objects[j].desc);
                           if (valuelen > 200)
                             log_info ("[%u]\n", (unsigned int)valuelen);
                           else
                             log_printhex ("", value, valuelen);
                         }
                       else
-                        log_info ("DO `%s': `%.*s'\n",
+                        log_info ("DO '%s': '%.*s'\n",
                                   data_objects[j].desc,
                                   (int)valuelen, value); /* FIXME: sanitize */
                     }
@@ -701,24 +743,61 @@ parse_login_data (app_t app)
   xfree (relptr);
 }
 
+
+static unsigned char
+get_algo_byte (key_type_t key_type)
+{
+  if (key_type == KEY_TYPE_ECDSA)
+    return 19;
+  else if (key_type == KEY_TYPE_ECDH)
+    return 18;
+  else if (key_type == KEY_TYPE_EDDSA)
+    return 105;                 /* (experimental) */
+  else
+    return 1;  /* RSA */
+}
+
+#define MAX_ARGS_STORE_FPR 3
+
 /* Note, that FPR must be at least 20 bytes. */
 static gpg_error_t
 store_fpr (app_t app, int keynumber, u32 timestamp,
-           const unsigned char *m, size_t mlen,
-           const unsigned char *e, size_t elen,
-           unsigned char *fpr, unsigned int card_version)
+           unsigned char *fpr, unsigned int card_version,
+           key_type_t key_type,
+           ...)
 {
   unsigned int n, nbits;
   unsigned char *buffer, *p;
   int tag, tag2;
   int rc;
+  const unsigned char *m[MAX_ARGS_STORE_FPR];
+  size_t mlen[MAX_ARGS_STORE_FPR];
+  va_list ap;
+  int argc;
+  int i;
 
-  for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */
-    ;
-  for (; elen && !*e; elen--, e++) /* strip leading zeroes */
-    ;
+  n = 6;    /* key packet version, 4-byte timestamps, and algorithm */
+  if (key_type == KEY_TYPE_RSA || key_type == KEY_TYPE_ECDSA
+      || key_type == KEY_TYPE_EDDSA)
+    argc = 2;
+  else if (key_type == KEY_TYPE_ECDH)
+    argc = 3;
+  else
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  va_start (ap, key_type);
+  for (i = 0; i < argc; i++)
+    {
+      m[i] = va_arg (ap, const unsigned char *);
+      mlen[i] = va_arg (ap, size_t);
+      for (; mlen[i] && !*m[i]; mlen[i]--, m[i]++) /* strip leading zeroes */
+        ;
+      if (key_type == KEY_TYPE_RSA || i == 1)
+        n += 2;
+      n += mlen[i];
+    }
+  va_end (ap);
 
-  n = 6 + 2 + mlen + 2 + elen;
   p = buffer = xtrymalloc (3 + n);
   if (!buffer)
     return gpg_error_from_syserror ();
@@ -731,15 +810,19 @@ store_fpr (app_t app, int keynumber, u32 timestamp,
   *p++ = timestamp >> 16;
   *p++ = timestamp >>  8;
   *p++ = timestamp;
-  *p++ = 1; /* RSA */
-  nbits = count_bits (m, mlen);
-  *p++ = nbits >> 8;
-  *p++ = nbits;
-  memcpy (p, m, mlen); p += mlen;
-  nbits = count_bits (e, elen);
-  *p++ = nbits >> 8;
-  *p++ = nbits;
-  memcpy (p, e, elen); p += elen;
+  *p++ = get_algo_byte (key_type);
+
+  for (i = 0; i < argc; i++)
+    {
+      if (key_type == KEY_TYPE_RSA || i == 1)
+        {
+          nbits = count_bits (m[i], mlen[i]);
+          *p++ = nbits >> 8;
+          *p++ = nbits;
+        }
+      memcpy (p, m[i], mlen[i]);
+      p += mlen[i];
+    }
 
   gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3);
 
@@ -802,7 +885,7 @@ send_fprtime_if_not_null (ctrl_t ctrl, const char *keyword,
   char numbuf1[50], numbuf2[50];
   unsigned long value;
 
-  value = buf32_to_ulong (stamp);
+  value = (stamp[0] << 24) | (stamp[1]<<16) | (stamp[2]<<8) | stamp[3];
   if (!value)
     return;
   sprintf (numbuf1, "%d", number);
@@ -843,36 +926,82 @@ send_key_data (ctrl_t ctrl, const char *name,
 
 
 static void
+get_ecc_key_parameters (int curve, int *r_n_bits, const char **r_curve_oid)
+{
+  if (curve == CURVE_NIST_P256)
+    {
+      *r_n_bits = 256;
+      *r_curve_oid = "1.2.840.10045.3.1.7";
+    }
+  else if (curve == CURVE_NIST_P384)
+    {
+      *r_n_bits = 384;
+      *r_curve_oid = "1.3.132.0.34";
+    }
+  else if (curve == CURVE_NIST_P521)
+    {
+      *r_n_bits = 521;
+      *r_curve_oid = "1.3.132.0.35";
+    }
+  else if (curve == CURVE_SEC_P256K1)
+    {
+      *r_n_bits = 256;
+      *r_curve_oid = "1.3.132.0.10";
+    }
+  else if (curve == CURVE_ED25519)
+    {
+      *r_n_bits = 255;
+      *r_curve_oid = "1.3.6.1.4.1.11591.15.1";
+    }
+  else
+    {
+      *r_n_bits = 0;
+      *r_curve_oid = "1.3.6.1.4.1.11591.2.12242973"; /* gnu.gnupg.badoid */
+    }
+}
+
+static void
 send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number)
 {
   char buffer[200];
+  int n_bits;
+  const char *curve_oid;
 
   assert (number >=0 && number < DIM(app->app_local->keyattr));
 
-  /* We only support RSA thus the algo identifier is fixed to 1.  */
-  /* Note that PUBKEY_ALGO_RSA == 1 */
-  snprintf (buffer, sizeof buffer, "%d 1 %u %u %d",
-            number+1,
-            app->app_local->keyattr[number].n_bits,
-            app->app_local->keyattr[number].e_bits,
-            app->app_local->keyattr[number].format);
-  send_status_direct (ctrl, keyword, buffer);
-}
-
-
-#define RSA_SMALL_SIZE_KEY 1952
-#define RSA_SMALL_SIZE_OP  2048
-
-static int
-determine_rsa_response (app_t app, int keyno)
-{
-  int size;
-
-  size = 2 + 3 /* header */
-    + 4 /* tag+len */ + app->app_local->keyattr[keyno].n_bits/8
-    + 2 /* tag+len */ + app->app_local->keyattr[keyno].e_bits/8;
+  if (app->app_local->keyattr[number].key_type == KEY_TYPE_RSA)
+    snprintf (buffer, sizeof buffer, "%d 1 %u %u %d",
+              number+1,
+              app->app_local->keyattr[number].rsa.n_bits,
+              app->app_local->keyattr[number].rsa.e_bits,
+              app->app_local->keyattr[number].rsa.format);
+  else if (app->app_local->keyattr[number].key_type == KEY_TYPE_ECDSA)
+    {
+      get_ecc_key_parameters (app->app_local->keyattr[number].ecdsa.curve,
+                              &n_bits, &curve_oid);
+      snprintf (buffer, sizeof buffer, "%d 19 %u %s",
+                number+1, n_bits, curve_oid);
+    }
+  else if (app->app_local->keyattr[number].key_type == KEY_TYPE_ECDH)
+    {
+      get_ecc_key_parameters (app->app_local->keyattr[number].ecdh.curve,
+                              &n_bits, &curve_oid);
+      snprintf (buffer, sizeof buffer, "%d 18 %u %s %d %d",
+                number+1, n_bits, curve_oid,
+                app->app_local->keyattr[number].ecdh.hashalgo,
+                app->app_local->keyattr[number].ecdh.cipheralgo);
+    }
+  else if (app->app_local->keyattr[number].key_type == KEY_TYPE_EDDSA)
+    {
+      get_ecc_key_parameters (app->app_local->keyattr[number].eddsa.curve,
+                              &n_bits, &curve_oid);
+      snprintf (buffer, sizeof buffer, "%d 105 %u %s",
+                number+1, n_bits, curve_oid);
+    }
+  else
+    snprintf (buffer, sizeof buffer, "0 0 UNKNOWN");
 
-  return size;
+  send_status_direct (ctrl, keyword, buffer);
 }
 
 
@@ -953,7 +1082,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
                 app->app_local->extcap.max_certlen_3,
                 app->app_local->extcap.algo_attr_change,
                 (app->app_local->extcap.sm_supported
-                 ? (app->app_local->extcap.sm_aes128? CIPHER_ALGO_AES : CIPHER_ALGO_3DES)
+                 ? (app->app_local->extcap.sm_aes128? 7 : 2)
                  : 0));
       send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
       return 0;
@@ -1169,11 +1298,29 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
 #endif /*GNUPG_MAJOR_VERSION > 1*/
 
 
+static const char *
+get_curve_name (int curve)
+{
+  if (curve == CURVE_NIST_P256)
+    return "NIST P-256";
+  else if (curve == CURVE_NIST_P384)
+    return "NIST P-384";
+  else if (curve == CURVE_NIST_P521)
+    return "NIST P-521";
+  else if (curve == CURVE_SEC_P256K1)
+    return "secp256k1";
+  else if (curve == CURVE_ED25519)
+    return "Ed25519";
+  else
+    return "unknown";
+}
+
+
 /* Get the public key for KEYNO and store it as an S-expresion with
    the APP handle.  On error that field gets cleared.  If we already
    know about the public key we will just return.  Note that this does
    not mean a key is available; this is soley indicated by the
-   presence of the app->app_local->pk[KEYNO].key field.
+   presence of the app->app_local->pk[KEYNO-1].key field.
 
    Note that GnuPG 1.x does not need this and it would be too time
    consuming to send it just for the fun of it. However, given that we
@@ -1186,14 +1333,18 @@ get_public_key (app_t app, int keyno)
   gpg_error_t err = 0;
   unsigned char *buffer;
   const unsigned char *keydata, *m, *e;
-  size_t buflen, keydatalen, mlen, elen;
+  size_t buflen, keydatalen;
+  size_t mlen = 0;
+  size_t elen = 0;
   unsigned char *mbuf = NULL;
   unsigned char *ebuf = NULL;
   char *keybuf = NULL;
-  char *keybuf_p;
+  gcry_sexp_t s_pkey;
+  size_t len;
 
-  if (keyno < 0 || keyno > 2)
+  if (keyno < 1 || keyno > 3)
     return gpg_error (GPG_ERR_INV_ID);
+  keyno--;
 
   /* Already cached? */
   if (app->app_local->pk[keyno].read_done)
@@ -1210,11 +1361,10 @@ get_public_key (app_t app, int keyno)
       int exmode, le_value;
 
       /* We may simply read the public key out of these cards.  */
-      if (app->app_local->cardcap.ext_lc_le
-          && app->app_local->keyattr[keyno].n_bits > RSA_SMALL_SIZE_KEY)
+      if (app->app_local->cardcap.ext_lc_le)
         {
           exmode = 1;    /* Use extended length.  */
-          le_value = determine_rsa_response (app, keyno);
+          le_value = app->app_local->extcap.max_rsp_data;
         }
       else
         {
@@ -1222,10 +1372,12 @@ get_public_key (app_t app, int keyno)
           le_value = 256; /* Use legacy value. */
         }
 
-      err = iso7816_read_public_key (app->slot, exmode,
-                                     (keyno == 0? "\xB6" :
-                                      keyno == 1? "\xB8" : "\xA4"),
-                                     2, le_value, &buffer, &buflen);
+      err = iso7816_read_public_key
+        (app->slot, exmode,
+         (const unsigned char*)(keyno == 0? "\xB6" :
+                                keyno == 1? "\xB8" : "\xA4"), 2,
+         le_value,
+         &buffer, &buflen);
       if (err)
         {
           log_error (_("reading public key failed: %s\n"), gpg_strerror (err));
@@ -1240,51 +1392,34 @@ get_public_key (app_t app, int keyno)
           goto leave;
         }
 
-      m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
-      if (!m)
-        {
-          err = gpg_error (GPG_ERR_CARD);
-          log_error (_("response does not contain the RSA modulus\n"));
-          goto leave;
-        }
-
-
-      e = find_tlv (keydata, keydatalen, 0x0082, &elen);
-      if (!e)
+      if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
         {
-          err = gpg_error (GPG_ERR_CARD);
-          log_error (_("response does not contain the RSA public exponent\n"));
-          goto leave;
-        }
+          m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
+          if (!m)
+            {
+              err = gpg_error (GPG_ERR_CARD);
+              log_error (_("response does not contain the RSA modulus\n"));
+              goto leave;
+            }
 
-      /* Prepend numbers with a 0 if needed.  */
-      if (mlen && (*m & 0x80))
-        {
-          mbuf = xtrymalloc ( mlen + 1);
-          if (!mbuf)
+          e = find_tlv (keydata, keydatalen, 0x0082, &elen);
+          if (!e)
             {
-              err = gpg_error_from_syserror ();
+              err = gpg_error (GPG_ERR_CARD);
+              log_error (_("response does not contain the RSA public exponent\n"));
               goto leave;
             }
-          *mbuf = 0;
-          memcpy (mbuf+1, m, mlen);
-          mlen++;
-          m = mbuf;
         }
-      if (elen && (*e & 0x80))
+      else
         {
-          ebuf = xtrymalloc ( elen + 1);
-          if (!ebuf)
+          m = find_tlv (keydata, keydatalen, 0x0086, &mlen);
+          if (!m)
             {
-              err = gpg_error_from_syserror ();
+              err = gpg_error (GPG_ERR_CARD);
+              log_error (_("response does not contain the EC public point\n"));
               goto leave;
             }
-          *ebuf = 0;
-          memcpy (ebuf+1, e, elen);
-          elen++;
-          e = ebuf;
         }
-
     }
   else
     {
@@ -1313,9 +1448,8 @@ get_public_key (app_t app, int keyno)
        }
       hexkeyid = fpr + 24;
 
-      ret = estream_asprintf (&command,
-                             "gpg --list-keys --with-colons --with-key-data '%s'",
-                             fpr);
+      ret = gpgrt_asprintf
+        (&command, "gpg --list-keys --with-colons --with-key-data '%s'", fpr);
       if (ret < 0)
        {
          err = gpg_error_from_syserror ();
@@ -1332,7 +1466,7 @@ get_public_key (app_t app, int keyno)
        }
 
       err = retrieve_key_material (fp, hexkeyid, &m, &mlen, &e, &elen);
-      pclose (fp);
+      fclose (fp);
       if (err)
        {
          log_error ("error while retrieving key material through pipe: %s\n",
@@ -1341,29 +1475,112 @@ get_public_key (app_t app, int keyno)
        }
     }
 
-  /* Allocate a buffer to construct the S-expression.  */
-  /* FIXME: We should provide a generalized S-expression creation
-     mechanism. */
-  keybuf = xtrymalloc (50 + 2*35 + mlen + elen + 1);
-  if (!keybuf)
+
+  mbuf = xtrymalloc ( mlen + 1);
+  if (!mbuf)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  /* Prepend numbers with a 0 if needed.  */
+  if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_EDDSA
+      && mlen && (*m & 0x80))
+    {
+      *mbuf = 0;
+      memcpy (mbuf+1, m, mlen);
+      mlen++;
+    }
+  else
+    memcpy (mbuf, m, mlen);
+
+  ebuf = xtrymalloc ( elen + 1);
+  if (!ebuf)
     {
       err = gpg_error_from_syserror ();
       goto leave;
     }
+  /* Prepend numbers with a 0 if needed.  */
+  if (elen && (*e & 0x80))
+    {
+      *ebuf = 0;
+      memcpy (ebuf+1, e, elen);
+      elen++;
+    }
+  else
+    memcpy (ebuf, e, elen);
+
+  if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
+    {
+      err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))",
+                             mlen, mbuf, elen, ebuf);
+      if (err)
+        goto leave;
+
+      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+      keybuf = xtrymalloc (len);
+      if (!keybuf)
+        {
+          gcry_sexp_release (s_pkey);
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
+      gcry_sexp_release (s_pkey);
+    }
+  else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECDSA)
+    {
+      const char *curve_name
+        = get_curve_name (app->app_local->keyattr[keyno].ecdsa.curve);
+
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(ecc(curve%s)(q%b)))",
+                             curve_name, mlen, mbuf);
+      if (err)
+        goto leave;
+
+      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+
+      keybuf = xtrymalloc (len);
+      if (!keybuf)
+        {
+          gcry_sexp_release (s_pkey);
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
+      gcry_sexp_release (s_pkey);
+    }
+  else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_EDDSA)
+    {
+      const char *curve_name
+        = get_curve_name (app->app_local->keyattr[keyno].eddsa.curve);
+
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(ecc(curve%s)(flags eddsa)(q%b)))",
+                             curve_name, mlen, mbuf);
+      if (err)
+        goto leave;
 
-  sprintf (keybuf, "(10:public-key(3:rsa(1:n%u:", (unsigned int) mlen);
-  keybuf_p = keybuf + strlen (keybuf);
-  memcpy (keybuf_p, m, mlen);
-  keybuf_p += mlen;
-  sprintf (keybuf_p, ")(1:e%u:", (unsigned int)elen);
-  keybuf_p += strlen (keybuf_p);
-  memcpy (keybuf_p, e, elen);
-  keybuf_p += elen;
-  strcpy (keybuf_p, ")))");
-  keybuf_p += strlen (keybuf_p);
+      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+
+      keybuf = xtrymalloc (len);
+      if (!keybuf)
+        {
+          gcry_sexp_release (s_pkey);
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
+      gcry_sexp_release (s_pkey);
+    }
+  else
+    {
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      goto leave;
+    }
 
   app->app_local->pk[keyno].key = (unsigned char*)keybuf;
-  app->app_local->pk[keyno].keylen = (keybuf_p - keybuf);
+  app->app_local->pk[keyno].keylen = len - 1; /* Decrement for trailing '\0' */
 
  leave:
   /* Set a flag to indicate that we tried to read the key.  */
@@ -1372,18 +1589,17 @@ get_public_key (app_t app, int keyno)
   xfree (buffer);
   xfree (mbuf);
   xfree (ebuf);
-  return err;
+  return 0;
 }
 #endif /* GNUPG_MAJOR_VERSION > 1 */
 
 
 
-/* Send the KEYPAIRINFO back. KEY needs to be in the range [1,3].
+/* Send the KEYPAIRINFO back. KEYNO needs to be in the range [1,3].
    This is used by the LEARN command. */
 static gpg_error_t
-send_keypair_info (app_t app, ctrl_t ctrl, int key)
+send_keypair_info (app_t app, ctrl_t ctrl, int keyno)
 {
-  int keyno = key - 1;
   gpg_error_t err = 0;
   /* Note that GnuPG 1.x does not need this and it would be too time
      consuming to send it just for the fun of it. */
@@ -1396,19 +1612,19 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key)
   if (err)
     goto leave;
 
-  assert (keyno >= 0 && keyno <= 2);
-  if (!app->app_local->pk[keyno].key)
+  assert (keyno >= 1 && keyno <= 3);
+  if (!app->app_local->pk[keyno-1].key)
     goto leave; /* No such key - ignore. */
 
-  err = keygrip_from_canon_sexp (app->app_local->pk[keyno].key,
-                                 app->app_local->pk[keyno].keylen,
+  err = keygrip_from_canon_sexp (app->app_local->pk[keyno-1].key,
+                                 app->app_local->pk[keyno-1].keylen,
                                  grip);
   if (err)
     goto leave;
 
   bin2hex (grip, 20, gripstr);
 
-  sprintf (idbuf, "OPENPGP.%d", keyno+1);
+  sprintf (idbuf, "OPENPGP.%d", keyno);
   send_status_info (ctrl, "KEYPAIRINFO",
                     gripstr, 40,
                     idbuf, strlen (idbuf),
@@ -1471,11 +1687,11 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
   unsigned char *buf;
 
   if (!strcmp (keyid, "OPENPGP.1"))
-    keyno = 0;
-  else if (!strcmp (keyid, "OPENPGP.2"))
     keyno = 1;
-  else if (!strcmp (keyid, "OPENPGP.3"))
+  else if (!strcmp (keyid, "OPENPGP.2"))
     keyno = 2;
+  else if (!strcmp (keyid, "OPENPGP.3"))
+    keyno = 3;
   else
     return gpg_error (GPG_ERR_INV_ID);
 
@@ -1483,10 +1699,10 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
   if (err)
     return err;
 
-  buf = app->app_local->pk[keyno].key;
+  buf = app->app_local->pk[keyno-1].key;
   if (!buf)
     return gpg_error (GPG_ERR_NO_PUBKEY);
-  *pklen = app->app_local->pk[keyno].keylen;;
+  *pklen = app->app_local->pk[keyno-1].keylen;;
   *pk = xtrymalloc (*pklen);
   if (!*pk)
     {
@@ -1960,7 +2176,7 @@ do_setattr (app_t app, const char *name,
     exmode = 0;
   rc = iso7816_put_data (app->slot, exmode, table[idx].tag, value, valuelen);
   if (rc)
-    log_error ("failed to set `%s': %s\n", table[idx].name, gpg_strerror (rc));
+    log_error ("failed to set '%s': %s\n", table[idx].name, gpg_strerror (rc));
 
   if (table[idx].special == 1)
     app->force_chv1 = (valuelen && *value == 0);
@@ -2277,8 +2493,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
             }
           rc = iso7816_change_reference_data_kp (app->slot, 0x80 + chvno, 0,
                                                  &pininfo);
-          /* Dismiss the prompt. */
-          pincb (pincb_arg, NULL, NULL);
+          pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */
         }
       else
         rc = iso7816_change_reference_data (app->slot, 0x80 + chvno,
@@ -2385,8 +2600,6 @@ add_tlv (unsigned char *buffer, unsigned int tag, size_t length)
 }
 
 
-/* Build the private key template as specified in the OpenPGP specs
-   v2.0 section 4.3.3.7.  */
 static gpg_error_t
 build_privkey_template (app_t app, int keyno,
                         const unsigned char *rsa_n, size_t rsa_n_len,
@@ -2413,7 +2626,7 @@ build_privkey_template (app_t app, int keyno,
   *result = NULL;
   *resultlen = 0;
 
-  switch (app->app_local->keyattr[keyno].format)
+  switch (app->app_local->keyattr[keyno].rsa.format)
     {
     case RSA_STD:
     case RSA_STD_N:
@@ -2426,7 +2639,7 @@ build_privkey_template (app_t app, int keyno,
     }
 
   /* Get the required length for E. Rounded up to the nearest byte  */
-  rsa_e_reqlen = (app->app_local->keyattr[keyno].e_bits + 7) / 8;
+  rsa_e_reqlen = (app->app_local->keyattr[keyno].rsa.e_bits + 7) / 8;
   assert (rsa_e_len <= rsa_e_reqlen);
 
   /* Build the 7f48 cardholder private key template.  */
@@ -2442,8 +2655,8 @@ build_privkey_template (app_t app, int keyno,
   tp += add_tlv (tp, 0x93, rsa_q_len);
   datalen += rsa_q_len;
 
-  if (app->app_local->keyattr[keyno].format == RSA_CRT
-      || app->app_local->keyattr[keyno].format == RSA_CRT_N)
+  if (app->app_local->keyattr[keyno].rsa.format == RSA_CRT
+      || app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N)
     {
       tp += add_tlv (tp, 0x94, rsa_u_len);
       datalen += rsa_u_len;
@@ -2453,8 +2666,8 @@ build_privkey_template (app_t app, int keyno,
       datalen += rsa_dq_len;
     }
 
-  if (app->app_local->keyattr[keyno].format == RSA_STD_N
-      || app->app_local->keyattr[keyno].format == RSA_CRT_N)
+  if (app->app_local->keyattr[keyno].rsa.format == RSA_STD_N
+      || app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N)
     {
       tp += add_tlv (tp, 0x97, rsa_n_len);
       datalen += rsa_n_len;
@@ -2506,8 +2719,8 @@ build_privkey_template (app_t app, int keyno,
   memcpy (tp, rsa_q, rsa_q_len);
   tp += rsa_q_len;
 
-  if (app->app_local->keyattr[keyno].format == RSA_CRT
-      || app->app_local->keyattr[keyno].format == RSA_CRT_N)
+  if (app->app_local->keyattr[keyno].rsa.format == RSA_CRT
+      || app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N)
     {
       memcpy (tp, rsa_u, rsa_u_len);
       tp += rsa_u_len;
@@ -2517,8 +2730,8 @@ build_privkey_template (app_t app, int keyno,
       tp += rsa_dq_len;
     }
 
-  if (app->app_local->keyattr[keyno].format == RSA_STD_N
-      || app->app_local->keyattr[keyno].format == RSA_CRT_N)
+  if (app->app_local->keyattr[keyno].rsa.format == RSA_STD_N
+      || app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N)
     {
       memcpy (tp, rsa_n, rsa_n_len);
       tp += rsa_n_len;
@@ -2533,6 +2746,76 @@ build_privkey_template (app_t app, int keyno,
   return 0;
 }
 
+static gpg_error_t
+build_ecc_privkey_template (app_t app, int keyno,
+                            const unsigned char *ecc_d, size_t ecc_d_len,
+                            unsigned char **result, size_t *resultlen)
+{
+  unsigned char privkey[2];
+  size_t privkey_len;
+  unsigned char exthdr[2+2+1];
+  size_t exthdr_len;
+  unsigned char suffix[2+1];
+  size_t suffix_len;
+  unsigned char *tp;
+  size_t datalen;
+  unsigned char *template;
+  size_t template_size;
+
+  (void)app;
+
+  *result = NULL;
+  *resultlen = 0;
+
+  /* Build the 7f48 cardholder private key template.  */
+  datalen = 0;
+  tp = privkey;
+
+  tp += add_tlv (tp, 0x91, ecc_d_len); /* Tag 0x91??? */
+  datalen += ecc_d_len;
+
+  privkey_len = tp - privkey;
+
+  /* Build the extended header list without the private key template.  */
+  tp = exthdr;
+  *tp++ = keyno ==0 ? 0xb6 : keyno == 1? 0xb8 : 0xa4;
+  *tp++ = 0;
+  tp += add_tlv (tp, 0x7f48, privkey_len);
+  exthdr_len = tp - exthdr;
+
+  /* Build the 5f48 suffix of the data.  */
+  tp = suffix;
+  tp += add_tlv (tp, 0x5f48, datalen);
+  suffix_len = tp - suffix;
+
+  /* Now concatenate everything.  */
+  template_size = (1 + 1   /* 0x4d and len. */
+                   + exthdr_len
+                   + privkey_len
+                   + suffix_len
+                   + datalen);
+  tp = template = xtrymalloc_secure (template_size);
+  if (!template)
+    return gpg_error_from_syserror ();
+
+  tp += add_tlv (tp, 0x4d, exthdr_len + privkey_len + suffix_len + datalen);
+  memcpy (tp, exthdr, exthdr_len);
+  tp += exthdr_len;
+  memcpy (tp, privkey, privkey_len);
+  tp += privkey_len;
+  memcpy (tp, suffix, suffix_len);
+  tp += suffix_len;
+
+  memcpy (tp, ecc_d, ecc_d_len);
+  tp += ecc_d_len;
+
+  assert (tp - template == template_size);
+
+  *result = template;
+  *resultlen = tp - template;
+  return 0;
+}
+
 
 /* Helper for do_writekley to change the size of a key.  Not ethat
    this deletes the entire key without asking.  */
@@ -2555,7 +2838,7 @@ change_keyattr (app_t app, int keyno, unsigned int nbits,
   relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL);
   if (!relptr)
     return gpg_error (GPG_ERR_CARD);
-  if (buflen < 6 || buffer[0] != PUBKEY_ALGO_RSA)
+  if (buflen < 6 || buffer[0] != 1)
     {
       /* Attriutes too short or not an RSA key.  */
       xfree (relptr);
@@ -2620,44 +2903,29 @@ change_keyattr_from_string (app_t app,
      happen.  */
   if (sscanf (string, " --force %d %d %u", &keyno, &algo, &nbits) != 3)
     err = gpg_error (GPG_ERR_INV_DATA);
-  keyno = keyno - 1;
-  if (!err)
-    {
-      if (keyno < 0 || keyno > 2)
-        err = gpg_error (GPG_ERR_INV_ID);
-      else if (algo != PUBKEY_ALGO_RSA)
-        err = gpg_error (GPG_ERR_PUBKEY_ALGO);
-      else if (nbits < 1024)
-        err = gpg_error (GPG_ERR_TOO_SHORT);
-      else
-        err = change_keyattr (app, keyno, nbits, pincb, pincb_arg);
-    }
+  else if (keyno < 1 || keyno > 3)
+    err = gpg_error (GPG_ERR_INV_ID);
+  else if (algo != 1)
+    err = gpg_error (GPG_ERR_PUBKEY_ALGO); /* Not RSA.  */
+  else if (nbits < 1024)
+    err = gpg_error (GPG_ERR_TOO_SHORT);
+  else
+    err = change_keyattr (app, keyno-1, nbits, pincb, pincb_arg);
 
   xfree (string);
   return err;
 }
 
 
-/* Handle the WRITEKEY command for OpenPGP.  This function expects a
-   canonical encoded S-expression with the secret key in KEYDATA and
-   its length (for assertions) in KEYDATALEN.  KEYID needs to be the
-   usual keyid which for OpenPGP is the string "OPENPGP.n" with
-   n=1,2,3.  Bit 0 of FLAGS indicates whether an existing key shall
-   get overwritten.  PINCB and PINCB_ARG are the usual arguments for
-   the pinentry callback.  */
 static gpg_error_t
-do_writekey (app_t app, ctrl_t ctrl,
-             const char *keyid, unsigned int flags,
-             gpg_error_t (*pincb)(void*, const char *, char **),
-             void *pincb_arg,
-             const unsigned char *keydata, size_t keydatalen)
+rsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+              void *pincb_arg, int keyno,
+              const unsigned char *buf, size_t buflen, int depth)
 {
   gpg_error_t err;
-  int force = (flags & 1);
-  int keyno;
-  const unsigned char *buf, *tok;
-  size_t buflen, toklen;
-  int depth, last_depth1, last_depth2;
+  const unsigned char *tok;
+  size_t toklen;
+  int last_depth1, last_depth2;
   const unsigned char *rsa_n = NULL;
   const unsigned char *rsa_e = NULL;
   const unsigned char *rsa_p = NULL;
@@ -2671,55 +2939,9 @@ do_writekey (app_t app, ctrl_t ctrl,
   unsigned char fprbuf[20];
   u32 created_at = 0;
 
-  (void)ctrl;
-
-  if (!strcmp (keyid, "OPENPGP.1"))
-    keyno = 0;
-  else if (!strcmp (keyid, "OPENPGP.2"))
-    keyno = 1;
-  else if (!strcmp (keyid, "OPENPGP.3"))
-    keyno = 2;
-  else
-    return gpg_error (GPG_ERR_INV_ID);
-
-  err = does_key_exist (app, keyno, 0, force);
-  if (err)
-    return err;
-
-
-  /*
-     Parse the S-expression
-   */
-  buf = keydata;
-  buflen = keydatalen;
-  depth = 0;
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    goto leave;
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    goto leave;
-  if (!tok || toklen != 11 || memcmp ("private-key", tok, toklen))
-    {
-      if (!tok)
-        ;
-      else if (toklen == 21 && !memcmp ("protected-private-key", tok, toklen))
-        log_info ("protected-private-key passed to writekey\n");
-      else if (toklen == 20 && !memcmp ("shadowed-private-key", tok, toklen))
-        log_info ("shadowed-private-key passed to writekey\n");
-      err = gpg_error (GPG_ERR_BAD_SECKEY);
-      goto leave;
-    }
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    goto leave;
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    goto leave;
-  if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen))
-    {
-      err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
-      goto leave;
-    }
-  last_depth1 = depth;
-  while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
-         && depth && depth >= last_depth1)
+  last_depth1 = depth;
+  while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
+         && depth && depth >= last_depth1)
     {
       if (tok)
         {
@@ -2807,7 +3029,7 @@ do_writekey (app_t app, ctrl_t ctrl,
       goto leave;
     }
 
-  maxbits = app->app_local->keyattr[keyno].n_bits;
+  maxbits = app->app_local->keyattr[keyno].rsa.n_bits;
   nbits = rsa_n? count_bits (rsa_n, rsa_n_len) : 0;
   if (opt.verbose)
     log_info ("RSA modulus size is %u bits (%u bytes)\n",
@@ -2818,7 +3040,7 @@ do_writekey (app_t app, ctrl_t ctrl,
       /* Try to switch the key to a new length.  */
       err = change_keyattr (app, keyno, nbits, pincb, pincb_arg);
       if (!err)
-        maxbits = app->app_local->keyattr[keyno].n_bits;
+        maxbits = app->app_local->keyattr[keyno].rsa.n_bits;
     }
   if (nbits != maxbits)
     {
@@ -2828,7 +3050,7 @@ do_writekey (app_t app, ctrl_t ctrl,
       goto leave;
     }
 
-  maxbits = app->app_local->keyattr[keyno].e_bits;
+  maxbits = app->app_local->keyattr[keyno].rsa.e_bits;
   if (maxbits > 32 && !app->app_local->extcap.is_v2)
     maxbits = 32; /* Our code for v1 does only support 32 bits.  */
   nbits = rsa_e? count_bits (rsa_e, rsa_e_len) : 0;
@@ -2840,7 +3062,7 @@ do_writekey (app_t app, ctrl_t ctrl,
       goto leave;
     }
 
-  maxbits = app->app_local->keyattr[keyno].n_bits/2;
+  maxbits = app->app_local->keyattr[keyno].rsa.n_bits/2;
   nbits = rsa_p? count_bits (rsa_p, rsa_p_len) : 0;
   if (nbits != maxbits)
     {
@@ -2989,9 +3211,8 @@ do_writekey (app_t app, ctrl_t ctrl,
       goto leave;
     }
 
-  err = store_fpr (app, keyno, created_at,
-                  rsa_n, rsa_n_len, rsa_e, rsa_e_len,
-                  fprbuf, app->card_version);
+  err = store_fpr (app, keyno, created_at, fprbuf, app->card_version,
+                   KEY_TYPE_RSA, rsa_n, rsa_n_len, rsa_e, rsa_e_len);
   if (err)
     goto leave;
 
@@ -3002,6 +3223,295 @@ do_writekey (app_t app, ctrl_t ctrl,
 }
 
 
+static gpg_error_t
+ecdh_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+              void *pincb_arg, int keyno,
+              const unsigned char *buf, size_t buflen, int depth)
+{
+  (void)app;
+  (void)pincb;
+  (void)pincb_arg;
+  (void)keyno;
+  (void)buf;
+  (void)buflen;
+  (void)depth;
+
+  return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+
+static gpg_error_t
+ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+              void *pincb_arg, int keyno,
+              const unsigned char *buf, size_t buflen, int depth)
+{
+  gpg_error_t err;
+  const unsigned char *tok;
+  size_t toklen;
+  int last_depth1, last_depth2;
+  const unsigned char *ecc_q = NULL;
+  const unsigned char *ecc_d = NULL;
+  size_t ecc_q_len, ecc_d_len;
+  unsigned char *template = NULL;
+  size_t template_len;
+  unsigned char fprbuf[20];
+  u32 created_at = 0;
+  int curve = CURVE_UNKNOWN;
+
+  /* (private-key(ecdsa(curve%s)(q%m)(d%m))(created-at%d)):
+     curve = "1.2.840.10045.3.1.7" */
+  /* (private-key(ecc(curve%s)(q%m)(d%m))(created-at%d)):
+     curve = "secp256k1" */
+  /* (private-key(ecc(curve%s)(flags eddsa)(q%m)(d%m))(created-at%d)):
+      curve = "Ed25519" */
+  last_depth1 = depth;
+  while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
+         && depth && depth >= last_depth1)
+    {
+      if (tok)
+        {
+          err = gpg_error (GPG_ERR_UNKNOWN_SEXP);
+          goto leave;
+        }
+      if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+        goto leave;
+
+      if (tok && toklen == 5 && !memcmp (tok, "curve", 5))
+        {
+          if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+            goto leave;
+
+          if (tok && toklen == 19 && !memcmp (tok, "1.2.840.10045.3.1.7", 19))
+            curve = CURVE_NIST_P256;
+          else if (tok && toklen == 9 && !memcmp (tok, "secp256k1", 9))
+            curve = CURVE_SEC_P256K1;
+          else if (tok && toklen == 7 && !memcmp (tok, "Ed25519", 7))
+            curve = CURVE_ED25519;
+        }
+      else if (tok && toklen == 1)
+        {
+          const unsigned char **buf2;
+          size_t *buf2len;
+
+          switch (*tok)
+            {
+            case 'q': buf2 = &ecc_q; buf2len = &ecc_q_len; break;
+            case 'd': buf2 = &ecc_d; buf2len = &ecc_d_len; break;
+            default: buf2 = NULL;  buf2len = NULL; break;
+            }
+          if (buf2 && *buf2)
+            {
+              err = gpg_error (GPG_ERR_DUP_VALUE);
+              goto leave;
+            }
+          if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+            goto leave;
+          if (tok && buf2 && curve != CURVE_ED25519)
+            /* It's MPI.  Strip off leading zero bytes and save. */
+            for (;toklen && !*tok; toklen--, tok++)
+              ;
+
+          *buf2 = tok;
+          *buf2len = toklen;
+        }
+      /* Skip until end of list. */
+      last_depth2 = depth;
+      while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
+             && depth && depth >= last_depth2)
+        ;
+      if (err)
+        goto leave;
+    }
+  /* Parse other attributes. */
+  last_depth1 = depth;
+  while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
+         && depth && depth >= last_depth1)
+    {
+      if (tok)
+        {
+          err = gpg_error (GPG_ERR_UNKNOWN_SEXP);
+          goto leave;
+        }
+      if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+        goto leave;
+      if (tok && toklen == 10 && !memcmp ("created-at", tok, toklen))
+        {
+          if ((err = parse_sexp (&buf,&buflen,&depth,&tok,&toklen)))
+            goto leave;
+          if (tok)
+            {
+              for (created_at=0; toklen && *tok && *tok >= '0' && *tok <= '9';
+                   tok++, toklen--)
+                created_at = created_at*10 + (*tok - '0');
+            }
+        }
+      /* Skip until end of list. */
+      last_depth2 = depth;
+      while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
+             && depth && depth >= last_depth2)
+        ;
+      if (err)
+        goto leave;
+    }
+
+
+  /* Check that we have all parameters and that they match the card
+     description. */
+  if (!created_at)
+    {
+      log_error (_("creation timestamp missing\n"));
+      err = gpg_error (GPG_ERR_INV_VALUE);
+      goto leave;
+    }
+
+  if (opt.verbose)
+    log_info ("ECC private key size is %u bytes\n", (unsigned int)ecc_d_len);
+
+  /* We need to remove the cached public key.  */
+  xfree (app->app_local->pk[keyno].key);
+  app->app_local->pk[keyno].key = NULL;
+  app->app_local->pk[keyno].keylen = 0;
+  app->app_local->pk[keyno].read_done = 0;
+
+  if (app->app_local->extcap.is_v2)
+    {
+      /* Build the private key template as described in section 4.3.3.7 of
+         the OpenPGP card specs version 2.0.  */
+      int exmode;
+
+      err = build_ecc_privkey_template (app, keyno,
+                                        ecc_d, ecc_d_len,
+                                        &template, &template_len);
+      if (err)
+        goto leave;
+
+      /* Prepare for storing the key.  */
+      err = verify_chv3 (app, pincb, pincb_arg);
+      if (err)
+        goto leave;
+
+      /* Store the key. */
+      if (app->app_local->cardcap.ext_lc_le && template_len > 254)
+        exmode = 1;    /* Use extended length w/o a limit.  */
+      else if (app->app_local->cardcap.cmd_chaining && template_len > 254)
+        exmode = -254;
+      else
+        exmode = 0;
+      err = iso7816_put_data_odd (app->slot, exmode, 0x3fff,
+                                  template, template_len);
+    }
+  else
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  if (err)
+    {
+      log_error (_("failed to store the key: %s\n"), gpg_strerror (err));
+      goto leave;
+    }
+
+  err = store_fpr (app, keyno, created_at, fprbuf, app->card_version,
+                   curve == CURVE_ED25519 ? KEY_TYPE_EDDSA : KEY_TYPE_ECDSA,
+                   curve == CURVE_ED25519 ?
+                   "\x09\x2b\x06\x01\x04\x01\xda\x47\x0f\x01"
+                   : curve == CURVE_NIST_P256 ?
+                   "\x08\x2a\x86\x48\xce\x3d\x03\x01\x07"
+                   : "\05\x2b\x81\x04\x00\x0a",
+                   curve == CURVE_ED25519 ? 10
+                   : curve == CURVE_NIST_P256? 9 : 6,
+                   ecc_q, ecc_q_len);
+  if (err)
+    goto leave;
+
+
+ leave:
+  xfree (template);
+  return err;
+}
+
+/* Handle the WRITEKEY command for OpenPGP.  This function expects a
+   canonical encoded S-expression with the secret key in KEYDATA and
+   its length (for assertions) in KEYDATALEN.  KEYID needs to be the
+   usual keyid which for OpenPGP is the string "OPENPGP.n" with
+   n=1,2,3.  Bit 0 of FLAGS indicates whether an existing key shall
+   get overwritten.  PINCB and PINCB_ARG are the usual arguments for
+   the pinentry callback.  */
+static gpg_error_t
+do_writekey (app_t app, ctrl_t ctrl,
+             const char *keyid, unsigned int flags,
+             gpg_error_t (*pincb)(void*, const char *, char **),
+             void *pincb_arg,
+             const unsigned char *keydata, size_t keydatalen)
+{
+  gpg_error_t err;
+  int force = (flags & 1);
+  int keyno;
+  const unsigned char *buf, *tok;
+  size_t buflen, toklen;
+  int depth;
+
+  (void)ctrl;
+
+  if (!strcmp (keyid, "OPENPGP.1"))
+    keyno = 0;
+  else if (!strcmp (keyid, "OPENPGP.2"))
+    keyno = 1;
+  else if (!strcmp (keyid, "OPENPGP.3"))
+    keyno = 2;
+  else
+    return gpg_error (GPG_ERR_INV_ID);
+
+  err = does_key_exist (app, keyno, 0, force);
+  if (err)
+    return err;
+
+
+  /*
+     Parse the S-expression
+   */
+  buf = keydata;
+  buflen = keydatalen;
+  depth = 0;
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    goto leave;
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    goto leave;
+  if (!tok || toklen != 11 || memcmp ("private-key", tok, toklen))
+    {
+      if (!tok)
+        ;
+      else if (toklen == 21 && !memcmp ("protected-private-key", tok, toklen))
+        log_info ("protected-private-key passed to writekey\n");
+      else if (toklen == 20 && !memcmp ("shadowed-private-key", tok, toklen))
+        log_info ("shadowed-private-key passed to writekey\n");
+      err = gpg_error (GPG_ERR_BAD_SECKEY);
+      goto leave;
+    }
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    goto leave;
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    goto leave;
+  if (tok && toklen == 3 && memcmp ("rsa", tok, toklen) == 0)
+    rsa_writekey (app, pincb, pincb_arg, keyno, buf, buflen, depth);
+  else if ((tok && toklen == 3 && memcmp ("ecc", tok, toklen) == 0
+            && (keyno == 0 || keyno == 2))
+           || (tok && toklen == 5 && memcmp ("ecdsa", tok, toklen) == 0))
+    ecc_writekey (app, pincb, pincb_arg, keyno, buf, buflen, depth);
+  else if ((tok && toklen == 3 && memcmp ("ecc", tok, toklen) == 0
+            && keyno == 1)
+           || (tok && toklen == 4 && memcmp ("ecdh", tok, toklen) == 0))
+    ecdh_writekey (app, pincb, pincb_arg, keyno, buf, buflen, depth);
+  else
+    {
+      err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
+      goto leave;
+    }
+
+ leave:
+  return err;
+}
+
+
+
 /* Handle the GENKEY command. */
 static gpg_error_t
 do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
@@ -3009,22 +3519,23 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
            gpg_error_t (*pincb)(void*, const char *, char **),
            void *pincb_arg)
 {
-  gpg_error_t err;
+  int rc;
   char numbuf[30];
   unsigned char fprbuf[20];
   const unsigned char *keydata, *m, *e;
   unsigned char *buffer = NULL;
   size_t buflen, keydatalen, mlen, elen;
-  u32 created_at;
-  int keyno = atoi (keynostr) - 1;
+  time_t created_at;
+  int keyno = atoi (keynostr);
   int force = (flags & 1);
   time_t start_at;
   int exmode;
   int le_value;
   unsigned int keybits;
 
-  if (keyno < 0 || keyno > 2)
+  if (keyno < 1 || keyno > 3)
     return gpg_error (GPG_ERR_INV_ID);
+  keyno--;
 
   /* We flush the cache to increase the traffic before a key
      generation.  This _might_ help a card to gather more entropy. */
@@ -3037,28 +3548,29 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   app->app_local->pk[keyno].read_done = 0;
 
   /* Check whether a key already exists.  */
-  err = does_key_exist (app, keyno, 1, force);
-  if (err)
-    return err;
+  rc = does_key_exist (app, keyno, 1, force);
+  if (rc)
+    return rc;
 
   /* Because we send the key parameter back via status lines we need
      to put a limit on the max. allowed keysize.  2048 bit will
      already lead to a 527 byte long status line and thus a 4096 bit
      key would exceed the Assuan line length limit.  */
-  keybits = app->app_local->keyattr[keyno].n_bits;
+  keybits = app->app_local->keyattr[keyno].rsa.n_bits;
   if (keybits > 4096)
     return gpg_error (GPG_ERR_TOO_LARGE);
 
   /* Prepare for key generation by verifying the Admin PIN.  */
-  err = verify_chv3 (app, pincb, pincb_arg);
-  if (err)
+  rc = verify_chv3 (app, pincb, pincb_arg);
+  if (rc)
     goto leave;
 
-  /* Test whether we will need extended length mode.  */
-  if (app->app_local->cardcap.ext_lc_le && keybits > RSA_SMALL_SIZE_KEY)
+  /* Test whether we will need extended length mode.  (1900 is an
+     arbitrary length which for sure fits into a short apdu.)  */
+  if (app->app_local->cardcap.ext_lc_le && keybits > 1900)
     {
       exmode = 1;    /* Use extended length w/o a limit.  */
-      le_value = determine_rsa_response (app, keyno);
+      le_value = app->app_local->extcap.max_rsp_data;
       /* No need to check le_value because it comes from a 16 bit
          value and thus can't create an overflow on a 32 bit
          system.  */
@@ -3071,13 +3583,17 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
 
   log_info (_("please wait while key is being generated ...\n"));
   start_at = time (NULL);
-  err = iso7816_generate_keypair (app->slot, exmode,
-                                  (keyno == 0? "\xB6" :
-                                   keyno == 1? "\xB8" : "\xA4"),
-                                  2, le_value, &buffer, &buflen);
-  if (err)
+  rc = iso7816_generate_keypair
+/* # warning key generation temporary replaced by reading an existing key. */
+/*   rc = iso7816_read_public_key */
+    (app->slot, exmode,
+     (const unsigned char*)(keyno == 0? "\xB6" :
+                            keyno == 1? "\xB8" : "\xA4"), 2,
+     le_value,
+     &buffer, &buflen);
+  if (rc)
     {
-      err = gpg_error (GPG_ERR_CARD);
+      rc = gpg_error (GPG_ERR_CARD);
       log_error (_("generating key failed\n"));
       goto leave;
     }
@@ -3087,7 +3603,7 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen);
   if (!keydata)
     {
-      err = gpg_error (GPG_ERR_CARD);
+      rc = gpg_error (GPG_ERR_CARD);
       log_error (_("response does not contain the public key data\n"));
       goto leave;
     }
@@ -3095,7 +3611,7 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
   if (!m)
     {
-      err = gpg_error (GPG_ERR_CARD);
+      rc = gpg_error (GPG_ERR_CARD);
       log_error (_("response does not contain the RSA modulus\n"));
       goto leave;
     }
@@ -3105,28 +3621,28 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   e = find_tlv (keydata, keydatalen, 0x0082, &elen);
   if (!e)
     {
-      err = gpg_error (GPG_ERR_CARD);
+      rc = gpg_error (GPG_ERR_CARD);
       log_error (_("response does not contain the RSA public exponent\n"));
       goto leave;
     }
   /* log_printhex ("RSA e:", e, elen); */
   send_key_data (ctrl, "e", e, elen);
 
-  created_at = (u32)(createtime? createtime : gnupg_get_time ());
-  sprintf (numbuf, "%u", created_at);
+  created_at = createtime? createtime : gnupg_get_time ();
+  sprintf (numbuf, "%lu", (unsigned long)created_at);
   send_status_info (ctrl, "KEY-CREATED-AT",
                     numbuf, (size_t)strlen(numbuf), NULL, 0);
 
-  err = store_fpr (app, keyno, (u32)created_at,
-                  m, mlen, e, elen, fprbuf, app->card_version);
-  if (err)
+  rc = store_fpr (app, keyno, (u32)created_at, fprbuf, app->card_version,
+                  KEY_TYPE_RSA, m, mlen, e, elen);
+  if (rc)
     goto leave;
   send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf);
 
 
  leave:
   xfree (buffer);
-  return err;
+  return rc;
 }
 
 
@@ -3169,7 +3685,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
   size_t buflen, n;
   int rc, i;
 
-  assert (keyno >= 0 && keyno <= 2);
+  assert (keyno >= 1 && keyno <= 3);
 
   rc = get_cached_data (app, 0x006E, &buffer, &buflen, 0, 0);
   if (rc)
@@ -3184,7 +3700,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
       log_error (_("error reading fingerprint DO\n"));
       return gpg_error (GPG_ERR_GENERAL);
     }
-  fpr += keyno*20;
+  fpr += (keyno-1)*20;
   for (i=0; i < 20; i++)
     if (sha1fpr[i] != fpr[i])
       {
@@ -3203,7 +3719,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
    gpg has not been updated.  If there is no fingerprint we assume
    that this is okay. */
 static gpg_error_t
-check_against_given_fingerprint (app_t app, const char *fpr, int key)
+check_against_given_fingerprint (app_t app, const char *fpr, int keyno)
 {
   unsigned char tmp[20];
   const char *s;
@@ -3220,7 +3736,7 @@ check_against_given_fingerprint (app_t app, const char *fpr, int key)
 
   for (s=fpr, n=0; n < 20; s += 2, n++)
         tmp[n] = xtoi_2 (s);
-  return compare_fingerprint (app, key-1, tmp);
+  return compare_fingerprint (app, keyno, tmp);
 }
 
 
@@ -3361,14 +3877,23 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       memcpy (data + sizeof b ## _prefix, indata, indatalen); \
     }
 
-  X(SHA1,   sha1,   1)
-  else X(RMD160, rmd160, 1)
-  else X(SHA224, sha224, app->app_local->extcap.is_v2)
-  else X(SHA256, sha256, app->app_local->extcap.is_v2)
-  else X(SHA384, sha384, app->app_local->extcap.is_v2)
-  else X(SHA512, sha512, app->app_local->extcap.is_v2)
+  if (use_auth
+      || app->app_local->keyattr[use_auth? 2: 0].key_type == KEY_TYPE_RSA)
+    {
+      X(SHA1,   sha1,   1)
+      else X(RMD160, rmd160, 1)
+      else X(SHA224, sha224, app->app_local->extcap.is_v2)
+      else X(SHA256, sha256, app->app_local->extcap.is_v2)
+      else X(SHA384, sha384, app->app_local->extcap.is_v2)
+      else X(SHA512, sha512, app->app_local->extcap.is_v2)
+      else
+        return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+    }
   else
-    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+    {
+      datalen = indatalen;
+      memcpy (data, indata, indatalen);
+    }
 #undef X
 
   /* Redirect to the AUTH command if asked to. */
@@ -3417,11 +3942,10 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
     }
 
 
-  if (app->app_local->cardcap.ext_lc_le
-      && app->app_local->keyattr[0].n_bits > RSA_SMALL_SIZE_OP)
+  if (app->app_local->cardcap.ext_lc_le)
     {
       exmode = 1;    /* Use extended length.  */
-      le_value = app->app_local->keyattr[0].n_bits / 8;
+      le_value = app->app_local->extcap.max_rsp_data;
     }
   else
     {
@@ -3458,9 +3982,24 @@ do_auth (app_t app, const char *keyidstr,
 
   if (!keyidstr || !*keyidstr)
     return gpg_error (GPG_ERR_INV_VALUE);
-  if (indatalen > 101) /* For a 2048 bit key. */
+  if (app->app_local->keyattr[2].key_type == KEY_TYPE_RSA
+      && indatalen > 101) /* For a 2048 bit key. */
     return gpg_error (GPG_ERR_INV_VALUE);
 
+  if (app->app_local->keyattr[2].key_type == KEY_TYPE_ECDSA
+      && (indatalen == 51 || indatalen == 67 || indatalen == 83))
+    {
+      const char *p = (const char *)indata + 19;
+      indata = p;
+      indatalen -= 19;
+    }
+  else if (app->app_local->keyattr[2].key_type == KEY_TYPE_EDDSA)
+    {
+      const char *p = (const char *)indata + 15;
+      indata = p;
+      indatalen -= 15;
+    }
+
   /* Check whether an OpenPGP card of any version has been requested. */
   if (!strcmp (keyidstr, "OPENPGP.3"))
     ;
@@ -3503,11 +4042,10 @@ do_auth (app_t app, const char *keyidstr,
     {
       int exmode, le_value;
 
-      if (app->app_local->cardcap.ext_lc_le
-          && app->app_local->keyattr[2].n_bits > RSA_SMALL_SIZE_OP)
+      if (app->app_local->cardcap.ext_lc_le)
         {
           exmode = 1;    /* Use extended length.  */
-          le_value = app->app_local->keyattr[2].n_bits / 8;
+          le_value = app->app_local->extcap.max_rsp_data;
         }
       else
         {
@@ -3527,7 +4065,8 @@ do_decipher (app_t app, const char *keyidstr,
              gpg_error_t (*pincb)(void*, const char *, char **),
              void *pincb_arg,
              const void *indata, size_t indatalen,
-             unsigned char **outdata, size_t *outdatalen )
+             unsigned char **outdata, size_t *outdatalen,
+             unsigned int *r_info)
 {
   int rc;
   unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */
@@ -3578,17 +4117,19 @@ do_decipher (app_t app, const char *keyidstr,
   rc = verify_chv2 (app, pincb, pincb_arg);
   if (!rc)
     {
-      size_t fixuplen;
+      int fixuplen;
       unsigned char *fixbuf = NULL;
       int padind = 0;
 
       /* We might encounter a couple of leading zeroes in the
-         cryptogram.  Due to internal use of MPIs thease leading
-         zeroes are stripped.  However the OpenPGP card expects
-         exactly 128 bytes for the cryptogram (for a 1k key).  Thus we
-         need to fix it up.  We do this for up to 16 leading zero
-         bytes; a cryptogram with more than this is with a very high
-         probability anyway broken.  */
+         cryptogram.  Due to internal use of MPIs these leading zeroes
+         are stripped.  However the OpenPGP card expects exactly 128
+         bytes for the cryptogram (for a 1k key).  Thus we need to fix
+         it up.  We do this for up to 16 leading zero bytes; a
+         cryptogram with more than this is with a very high
+         probability anyway broken.  If a signed conversion was used
+         we may also encounter one leading zero followed by the correct
+         length.  We fix that as well.  */
       if (indatalen >= (128-16) && indatalen < 128)      /* 1024 bit key.  */
         fixuplen = 128 - indatalen;
       else if (indatalen >= (192-16) && indatalen < 192) /* 1536 bit key.  */
@@ -3599,10 +4140,16 @@ do_decipher (app_t app, const char *keyidstr,
         fixuplen = 384 - indatalen;
       else if (indatalen >= (512-16) && indatalen < 512) /* 4096 bit key.  */
         fixuplen = 512 - indatalen;
+      else if (!*(const char *)indata && (indatalen == 129
+                                          || indatalen == 193
+                                          || indatalen == 257
+                                          || indatalen == 385
+                                          || indatalen == 513))
+        fixuplen = -1;
       else
         fixuplen = 0;
 
-      if (fixuplen)
+      if (fixuplen > 0)
         {
           /* While we have to prepend stuff anyway, we can also
              include the padding byte here so that iso1816_decipher
@@ -3619,13 +4166,16 @@ do_decipher (app_t app, const char *keyidstr,
           indatalen = fixuplen + indatalen;
           padind = -1; /* Already padded.  */
         }
+      else if (fixuplen < 0)
+        {
+          /* We use the extra leading zero as the padding byte.  */
+          padind = -1;
+        }
 
-      if (app->app_local->cardcap.ext_lc_le
-          && (indatalen > 254
-              || app->app_local->keyattr[1].n_bits > RSA_SMALL_SIZE_OP))
+      if (app->app_local->cardcap.ext_lc_le && indatalen > 254 )
         {
           exmode = 1;    /* Extended length w/o a limit.  */
-          le_value = app->app_local->keyattr[1].n_bits / 8;
+          le_value = app->app_local->extcap.max_rsp_data;
         }
       else if (app->app_local->cardcap.cmd_chaining && indatalen > 254)
         {
@@ -3645,6 +4195,8 @@ do_decipher (app_t app, const char *keyidstr,
           && app->card_version == 0x0200)
         log_info ("NOTE: Cards with manufacturer id 5 and s/n <= 346 (0x15a)"
                   " do not work with encryption keys > 2048 bits\n");
+
+      *r_info |= APP_DECIPHER_INFO_NOPAD;
     }
 
   return rc;
@@ -3726,7 +4278,7 @@ do_check_pin (app_t app, const char *keyidstr,
           log_info (_("card is permanently locked!\n"));
           return gpg_error (GPG_ERR_BAD_PIN);
         }
-      else if (count < 3)
+      else if (value[6] < 3)
         {
           log_info (_("verification of Admin PIN is currently prohibited "
                       "through this command\n"));
@@ -3757,6 +4309,8 @@ show_caps (struct app_local_s *s)
   if (s->extcap.sm_supported)
     log_printf (" (%s)", s->extcap.sm_aes128? "AES-128":"3DES");
   log_info ("Max-Cert3-Len ..: %u\n", s->extcap.max_certlen_3);
+  log_info ("Max-Cmd-Data ...: %u\n", s->extcap.max_cmd_data);
+  log_info ("Max-Rsp-Data ...: %u\n", s->extcap.max_rsp_data);
   log_info ("Cmd-Chaining ...: %s\n", s->cardcap.cmd_chaining?"yes":"no");
   log_info ("Ext-Lc-Le ......: %s\n", s->cardcap.ext_lc_le?"yes":"no");
   log_info ("Status Indicator: %02X\n", s->status_indicator);
@@ -3816,6 +4370,28 @@ parse_historical (struct app_local_s *apploc,
 }
 
 
+static int
+parse_ecc_curve (const unsigned char *buffer, size_t buflen)
+{
+  int curve;
+
+  if (buflen == 5 && buffer[5] == 0x22)
+    curve = CURVE_NIST_P384;
+  else if (buflen == 5 && buffer[5] == 0x23)
+    curve = CURVE_NIST_P521;
+  else if (buflen == 8)
+    curve = CURVE_NIST_P256;
+  else if (buflen == 5 && buffer[5] == 0x0a)
+    curve = CURVE_SEC_P256K1;
+  else if (buflen == 9)
+    curve = CURVE_ED25519;
+  else
+    curve = CURVE_UNKNOWN;
+
+  return curve;
+}
+
+
 /* Parse and optionally show the algorithm attributes for KEYNO.
    KEYNO must be in the range 0..2.  */
 static void
@@ -3824,11 +4400,12 @@ parse_algorithm_attribute (app_t app, int keyno)
   unsigned char *buffer;
   size_t buflen;
   void *relptr;
-  const char const desc[3][5] = {"sign", "encr", "auth"};
+  const char desc[3][5] = {"sign", "encr", "auth"};
 
   assert (keyno >=0 && keyno <= 2);
 
-  app->app_local->keyattr[keyno].n_bits = 0;
+  app->app_local->keyattr[keyno].key_type = KEY_TYPE_RSA;
+  app->app_local->keyattr[keyno].rsa.n_bits = 0;
 
   relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL);
   if (!relptr)
@@ -3845,29 +4422,49 @@ parse_algorithm_attribute (app_t app, int keyno)
 
   if (opt.verbose)
     log_info ("Key-Attr-%s ..: ", desc[keyno]);
-  if (*buffer == PUBKEY_ALGO_RSA && (buflen == 5 || buflen == 6))
+  if (*buffer == 1 && (buflen == 5 || buflen == 6))
     {
-      app->app_local->keyattr[keyno].n_bits = (buffer[1]<<8 | buffer[2]);
-      app->app_local->keyattr[keyno].e_bits = (buffer[3]<<8 | buffer[4]);
-      app->app_local->keyattr[keyno].format = 0;
+      app->app_local->keyattr[keyno].rsa.n_bits = (buffer[1]<<8 | buffer[2]);
+      app->app_local->keyattr[keyno].rsa.e_bits = (buffer[3]<<8 | buffer[4]);
+      app->app_local->keyattr[keyno].rsa.format = 0;
       if (buflen < 6)
-        app->app_local->keyattr[keyno].format = RSA_STD;
+        app->app_local->keyattr[keyno].rsa.format = RSA_STD;
       else
-        app->app_local->keyattr[keyno].format = (buffer[5] == 0? RSA_STD   :
-                                                 buffer[5] == 1? RSA_STD_N :
-                                                 buffer[5] == 2? RSA_CRT   :
-                                                 buffer[5] == 3? RSA_CRT_N :
-                                                 RSA_UNKNOWN_FMT);
+        app->app_local->keyattr[keyno].rsa.format = (buffer[5] == 0? RSA_STD   :
+                                                     buffer[5] == 1? RSA_STD_N :
+                                                     buffer[5] == 2? RSA_CRT   :
+                                                     buffer[5] == 3? RSA_CRT_N :
+                                                     RSA_UNKNOWN_FMT);
 
       if (opt.verbose)
         log_printf
           ("RSA, n=%u, e=%u, fmt=%s\n",
-           app->app_local->keyattr[keyno].n_bits,
-           app->app_local->keyattr[keyno].e_bits,
-           app->app_local->keyattr[keyno].format == RSA_STD?  "std"  :
-           app->app_local->keyattr[keyno].format == RSA_STD_N?"std+n":
-           app->app_local->keyattr[keyno].format == RSA_CRT?  "crt"  :
-           app->app_local->keyattr[keyno].format == RSA_CRT_N?"crt+n":"?");
+           app->app_local->keyattr[keyno].rsa.n_bits,
+           app->app_local->keyattr[keyno].rsa.e_bits,
+           app->app_local->keyattr[keyno].rsa.format == RSA_STD?  "std"  :
+           app->app_local->keyattr[keyno].rsa.format == RSA_STD_N?"std+n":
+           app->app_local->keyattr[keyno].rsa.format == RSA_CRT?  "crt"  :
+           app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N?"crt+n":"?");
+    }
+  else if (*buffer == 19) /* ECDSA */
+    {
+      app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECDSA;
+      app->app_local->keyattr[keyno].ecdsa.curve
+        = parse_ecc_curve (buffer + 1, buflen - 1);
+    }
+  else if (*buffer == 18 && buflen == 11) /* ECDH */
+    {
+      app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECDH;
+      app->app_local->keyattr[keyno].ecdh.hashalgo = buffer[1];
+      app->app_local->keyattr[keyno].ecdh.cipheralgo = buffer[2];
+      app->app_local->keyattr[keyno].ecdh.curve
+        = parse_ecc_curve (buffer + 3, buflen - 3);
+    }
+  else if (*buffer == 105) /* EdDSA (experimental) */
+    {
+      app->app_local->keyattr[keyno].key_type = KEY_TYPE_EDDSA;
+      app->app_local->keyattr[keyno].eddsa.curve
+        = parse_ecc_curve (buffer + 1, buflen - 1);
     }
   else if (opt.verbose)
     log_printhex ("", buffer, buflen);
@@ -3984,6 +4581,8 @@ app_select_openpgp (app_t app)
           app->app_local->extcap.max_get_challenge
                                                = (buffer[2] << 8 | buffer[3]);
           app->app_local->extcap.max_certlen_3 = (buffer[4] << 8 | buffer[5]);
+          app->app_local->extcap.max_cmd_data  = (buffer[6] << 8 | buffer[7]);
+          app->app_local->extcap.max_rsp_data  = (buffer[8] << 8 | buffer[9]);
         }
       xfree (relptr);
 
@@ -4025,6 +4624,3 @@ leave:
     do_deinit (app);
   return rc;
 }
-
-
-
index 8322617..eb074ef 100644 (file)
@@ -22,7 +22,7 @@
        Unblock PUK: "222222111111"
        Reset PIN:   "333333111111")
 
-   e.g. the APDUs 00:20:00:02:08:2C:33:33:33:11:11:11:FF 
+   e.g. the APDUs 00:20:00:02:08:2C:33:33:33:11:11:11:FF
               and 00:24:01:01:08:24:12:34:FF:FF:FF:FF:FF
    should change the PIN into 1234.
 */
@@ -50,22 +50,22 @@ typedef enum
     CARD_TYPE_TCOS,
     CARD_TYPE_MICARDO,
     CARD_TYPE_BELPIC   /* Belgian eID card specs. */
-  } 
+  }
 card_type_t;
 
 /* A list card types with ATRs noticed with these cards. */
 #define X(a) ((unsigned char const *)(a))
-static struct 
+static struct
 {
   size_t atrlen;
   unsigned char const *atr;
   card_type_t type;
 } card_atr_list[] = {
   { 19, X("\x3B\xBA\x13\x00\x81\x31\x86\x5D\x00\x64\x05\x0A\x02\x01\x31\x80"
-          "\x90\x00\x8B"), 
+          "\x90\x00\x8B"),
     CARD_TYPE_TCOS },  /* SLE44 */
   { 19, X("\x3B\xBA\x14\x00\x81\x31\x86\x5D\x00\x64\x05\x14\x02\x02\x31\x80"
-          "\x90\x00\x91"), 
+          "\x90\x00\x91"),
     CARD_TYPE_TCOS }, /* SLE66S */
   { 19, X("\x3B\xBA\x96\x00\x81\x31\x86\x5D\x00\x64\x05\x60\x02\x03\x31\x80"
           "\x90\x00\x66"),
@@ -96,7 +96,7 @@ static char const pkcs15be_aid[] = { 0xA0, 0, 0, 0x01, 0x77,
 
 
 /* The PIN types as defined in pkcs#15 v1.1 */
-typedef enum 
+typedef enum
   {
     PIN_TYPE_BCD = 0,
     PIN_TYPE_ASCII_NUMERIC = 1,
@@ -130,10 +130,10 @@ typedef struct keyusage_flags_s keyusage_flags_t;
    us. To keep memory management, simple we use a linked list of
    items; i.e. one such object represents one certificate and the list
    the entire CDF. */
-struct cdf_object_s 
+struct cdf_object_s
 {
   /* Link to next item when used in a linked list. */
-  struct cdf_object_s *next; 
+  struct cdf_object_s *next;
 
   /* Length and allocated buffer with the Id of this object. */
   size_t objidlen;
@@ -143,7 +143,7 @@ struct cdf_object_s
      allocated memory IMAGE of IMAGELEN. */
   size_t imagelen;
   unsigned char *image;
-  
+
   /* Set to true if a length and offset is available. */
   int have_off;
   /* The offset and length of the object.  They are only valid if
@@ -164,10 +164,10 @@ typedef struct cdf_object_s *cdf_object_t;
    by us. To keep memory management, simple we use a linked list of
    items; i.e. one such object represents one certificate and the list
    the entire PrKDF. */
-struct prkdf_object_s 
+struct prkdf_object_s
 {
   /* Link to next item when used in a linked list. */
-  struct prkdf_object_s *next; 
+  struct prkdf_object_s *next;
 
   /* Length and allocated buffer with the Id of this object. */
   size_t objidlen;
@@ -181,7 +181,7 @@ struct prkdf_object_s
   /* The key's usage flags. */
   keyusage_flags_t usageflags;
 
-  /* The keyReference and a flag telling whether it is valid. */ 
+  /* The keyReference and a flag telling whether it is valid. */
   unsigned long key_reference;
   int key_reference_valid;
 
@@ -204,10 +204,10 @@ typedef struct prkdf_object_s *prkdf_object_t;
    processing by us. To keep memory management, simple we use a linked
    list of items; i.e. one such object represents one authentication
    object and the list the entire AOKDF. */
-struct aodf_object_s 
+struct aodf_object_s
 {
   /* Link to next item when used in a linked list. */
-  struct aodf_object_s *next; 
+  struct aodf_object_s *next;
 
   /* Length and allocated buffer with the Id of this object. */
   size_t objidlen;
@@ -219,7 +219,7 @@ struct aodf_object_s
   unsigned char *authid;
 
   /* The PIN Flags. */
-  struct 
+  struct
   {
     unsigned int case_sensitive: 1;
     unsigned int local: 1;
@@ -248,7 +248,7 @@ struct aodf_object_s
   unsigned long max_length;
   int max_length_valid;
 
-  /* The pinReference and a flag telling whether it is valid. */ 
+  /* The pinReference and a flag telling whether it is valid. */
   unsigned long pin_reference;
   int pin_reference_valid;
 
@@ -273,7 +273,7 @@ typedef struct aodf_object_s *aodf_object_t;
 
 
 /* Context local to this application. */
-struct app_local_s 
+struct app_local_s
 {
   /* The home DF. Note, that we don't yet support a multilevel
      hierachy.  Thus we assume this is directly below the MF.  */
@@ -298,7 +298,7 @@ struct app_local_s
     unsigned short useful_certificates;
     unsigned short data_objects;
     unsigned short auth_objects;
-  } odf;  
+  } odf;
 
   /* The PKCS#15 serialnumber from EF(TokeiNFo) or NULL.  Malloced. */
   unsigned char *serialno;
@@ -403,7 +403,7 @@ do_deinit (app_t app)
    desctription of the EF to be used with error messages.  On success
    BUFFER and BUFLEN contain the entire content of the EF.  The caller
    must free BUFFER only on success. */
-static gpg_error_t 
+static gpg_error_t
 select_and_read_binary (int slot, unsigned short efid, const char *efid_desc,
                         unsigned char **buffer, size_t *buflen)
 {
@@ -428,7 +428,7 @@ select_and_read_binary (int slot, unsigned short efid, const char *efid_desc,
 
 
 /* This function calls select file to read a file using a complete
-   path which may or may not start at the master file (MF). */ 
+   path which may or may not start at the master file (MF). */
 static gpg_error_t
 select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen)
 {
@@ -440,7 +440,7 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen)
 
   if (pathlen && *path != 0x3f00 )
     log_debug ("WARNING: relative path selection not yet implemented\n");
-      
+
   if (app->app_local->direct_path_selection)
     {
       err = iso7816_select_path (app->slot, path+1, pathlen-1, NULL, NULL);
@@ -494,7 +494,8 @@ parse_certid (app_t app, const char *certid,
   *r_objidlen = 0;
 
   if (app->app_local->home_df)
-    sprintf (tmpbuf, "P15-%04hX.", (app->app_local->home_df & 0xffff));
+    snprintf (tmpbuf, sizeof tmpbuf,
+              "P15-%04X.", (unsigned int)(app->app_local->home_df & 0xffff));
   else
     strcpy (tmpbuf, "P15.");
   if (strncmp (certid, tmpbuf, strlen (tmpbuf)) )
@@ -594,11 +595,11 @@ prkdf_object_from_keyidstr (app_t app, const char *keyidstr,
    Example of such a file:
 
    A0 06 30 04 04 02 60 34  = Private Keys
-   A4 06 30 04 04 02 60 35  = Certificates 
+   A4 06 30 04 04 02 60 35  = Certificates
    A5 06 30 04 04 02 60 36  = TrustedCertificates
    A7 06 30 04 04 02 60 37  = DataObjects
    A8 06 30 04 04 02 60 38  = AuthObjects
-    
+
    These are all PathOrObjects using the path CHOICE element.  The
    paths are octet strings of length 2.  Using this Path CHOICE
    element is recommended, so we only implement that for now.
@@ -631,7 +632,7 @@ read_ef_odf (app_t app, unsigned short odf_fid)
         {
           offset = 6;
         }
-      else if ( buflen >= 12 
+      else if ( buflen >= 12
                 && (p[0] & 0xf0) == 0xA0
                 && !memcmp (p+1, "\x0a\x30\x08\x04\x06\x3F\x00", 7)
                 && app->app_local->home_df == ((p[8]<<8)|p[9]) )
@@ -678,7 +679,7 @@ read_ef_odf (app_t app, unsigned short odf_fid)
         case 6: app->app_local->odf.useful_certificates = value; break;
         case 7: app->app_local->odf.data_objects = value; break;
         case 8: app->app_local->odf.auth_objects = value; break;
-        default: 
+        default:
           log_error ("unknown object type %d in ODF ignored\n", (p[0]&0x0f));
         }
       offset += 2;
@@ -698,7 +699,7 @@ read_ef_odf (app_t app, unsigned short odf_fid)
 }
 
 
-/* Parse the BIT STRING with the keyUsageFlags from teh
+/* Parse the BIT STRING with the keyUsageFlags from the
    CommonKeyAttributes. */
 static gpg_error_t
 parse_keyusage_flags (const unsigned char *der, size_t derlen,
@@ -710,7 +711,7 @@ parse_keyusage_flags (const unsigned char *der, size_t derlen,
   memset (usageflags, 0, sizeof *usageflags);
   if (!derlen)
     return gpg_error (GPG_ERR_INV_OBJ);
-          
+
   unused = *der++; derlen--;
   if ((!derlen && unused) || unused/8 > derlen)
     return gpg_error (GPG_ERR_ENCODING_PROBLEM);
@@ -719,28 +720,28 @@ parse_keyusage_flags (const unsigned char *der, size_t derlen,
   mask = 0;
   for (i=1; unused; i <<= 1, unused--)
     mask |= i;
-  
+
   /* First octet */
   if (derlen)
     {
       bits = *der++; derlen--;
       if (full)
         full--;
-      else 
+      else
         {
           bits &= ~mask;
-          mask = 0; 
+          mask = 0;
         }
     }
   else
     bits = 0;
   if ((bits & 0x80)) usageflags->encrypt = 1;
   if ((bits & 0x40)) usageflags->decrypt = 1;
-  if ((bits & 0x20)) usageflags->sign = 1;  
+  if ((bits & 0x20)) usageflags->sign = 1;
   if ((bits & 0x10)) usageflags->sign_recover = 1;
   if ((bits & 0x08)) usageflags->wrap = 1;
-  if ((bits & 0x04)) usageflags->unwrap = 1; 
-  if ((bits & 0x02)) usageflags->verify = 1;  
+  if ((bits & 0x04)) usageflags->unwrap = 1;
+  if ((bits & 0x02)) usageflags->verify = 1;
   if ((bits & 0x01)) usageflags->verify_recover = 1;
 
   /* Second octet. */
@@ -749,10 +750,10 @@ parse_keyusage_flags (const unsigned char *der, size_t derlen,
       bits = *der++; derlen--;
       if (full)
         full--;
-      else 
+      else
         {
           bits &= ~mask;
-          mask = 0; 
+          mask = 0;
         }
     }
   else
@@ -823,14 +824,14 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
   int class, tag, constructed, ndef;
   prkdf_object_t prkdflist = NULL;
   int i;
-  
+
   if (!fid)
     return gpg_error (GPG_ERR_NO_DATA); /* No private keys. */
-  
+
   err = select_and_read_binary (app->slot, fid, "PrKDF", &buffer, &buflen);
   if (err)
     return err;
-  
+
   p = buffer;
   n = buflen;
 
@@ -995,7 +996,7 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
             /* Skip the native element. */
             ppp += objlen;
             nnn -= objlen;
-            
+
             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
                                     &ndef, &objlen, &hdrlen);
             if (gpg_err_code (err) == GPG_ERR_EOF)
@@ -1010,7 +1011,7 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
             /* Skip the accessFlags. */
             ppp += objlen;
             nnn -= objlen;
-            
+
             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
                                     &ndef, &objlen, &hdrlen);
             if (gpg_err_code (err) == GPG_ERR_EOF)
@@ -1026,7 +1027,7 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
             for (ul=0; objlen; objlen--)
               {
                 ul <<= 8;
-                ul |= (*ppp++) & 0xff; 
+                ul |= (*ppp++) & 0xff;
                 nnn--;
             }
             key_reference = ul;
@@ -1050,7 +1051,7 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
         {
           pp += objlen;
           nn -= objlen;
-      
+
           where = __LINE__;
           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
                                   &ndef, &objlen, &hdrlen);
@@ -1124,7 +1125,7 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
           goto parse_error;
         }
       /* Create a new PrKDF list item. */
-      prkdf = xtrycalloc (1, (sizeof *prkdf 
+      prkdf = xtrycalloc (1, (sizeof *prkdf
                               - sizeof(unsigned short)
                               + objlen/2 * sizeof(unsigned short)));
       if (!prkdf)
@@ -1175,15 +1176,15 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
             err = gpg_error (GPG_ERR_INV_OBJ);
           if (err)
             goto parse_error;
-          
+
           for (ul=0; objlen; objlen--)
             {
               ul <<= 8;
-              ul |= (*pp++) & 0xff; 
+              ul |= (*pp++) & 0xff;
               nn--;
             }
           prkdf->off = ul;
-          
+
           where = __LINE__;
           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
                                   &ndef, &objlen, &hdrlen);
@@ -1192,11 +1193,11 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
             err = gpg_error (GPG_ERR_INV_OBJ);
           if (err)
             goto parse_error;
-          
+
           for (ul=0; objlen; objlen--)
             {
               ul <<= 8;
-              ul |= (*pp++) & 0xff; 
+              ul |= (*pp++) & 0xff;
               nn--;
             }
           prkdf->len = ul;
@@ -1235,7 +1236,7 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
       if (prkdf->usageflags.non_repudiation)
         log_printf ("%snon_repudiation", s), s = ",";
       log_printf ("\n");
-      
+
       /* Put it into the list. */
       prkdf->next = prkdflist;
       prkdflist = prkdf;
@@ -1279,14 +1280,14 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
   int class, tag, constructed, ndef;
   cdf_object_t cdflist = NULL;
   int i;
-  
+
   if (!fid)
     return gpg_error (GPG_ERR_NO_DATA); /* No certificates. */
-  
+
   err = select_and_read_binary (app->slot, fid, "CDF", &buffer, &buflen);
   if (err)
     return err;
-  
+
   p = buffer;
   n = buflen;
 
@@ -1303,7 +1304,7 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
       unsigned long ul;
       const unsigned char *objid;
       size_t objidlen;
-      
+
       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
                               &ndef, &objlen, &hdrlen);
       if (!err && (objlen > n || tag != TAG_SEQUENCE))
@@ -1410,7 +1411,7 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
           goto parse_error;
         }
       /* Create a new CDF list item. */
-      cdf = xtrycalloc (1, (sizeof *cdf 
+      cdf = xtrycalloc (1, (sizeof *cdf
                             - sizeof(unsigned short)
                             + objlen/2 * sizeof(unsigned short)));
       if (!cdf)
@@ -1444,15 +1445,15 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
             err = gpg_error (GPG_ERR_INV_OBJ);
           if (err)
             goto parse_error;
-          
+
           for (ul=0; objlen; objlen--)
             {
               ul <<= 8;
-              ul |= (*pp++) & 0xff; 
+              ul |= (*pp++) & 0xff;
               nn--;
             }
           cdf->off = ul;
-          
+
           where = __LINE__;
           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
                                   &ndef, &objlen, &hdrlen);
@@ -1461,11 +1462,11 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
             err = gpg_error (GPG_ERR_INV_OBJ);
           if (err)
             goto parse_error;
-          
+
           for (ul=0; objlen; objlen--)
             {
               ul <<= 8;
-              ul |= (*pp++) & 0xff; 
+              ul |= (*pp++) & 0xff;
               nn--;
             }
           cdf->len = ul;
@@ -1480,7 +1481,7 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
       if (cdf->have_off)
         log_printf ("[%lu/%lu]", cdf->off, cdf->len);
       log_printf ("\n");
-      
+
       /* Put it into the list. */
       cdf->next = cdflist;
       cdflist = cdf;
@@ -1552,14 +1553,14 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
   int class, tag, constructed, ndef;
   aodf_object_t aodflist = NULL;
   int i;
-  
+
   if (!fid)
     return gpg_error (GPG_ERR_NO_DATA); /* No authentication objects. */
-  
+
   err = select_and_read_binary (app->slot, fid, "AODF", &buffer, &buflen);
   if (err)
     return err;
-  
+
   p = buffer;
   n = buflen;
 
@@ -1749,7 +1750,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
       {
         unsigned int bits, mask;
         int unused, full;
-        
+
         unused = *pp++; nn--; objlen--;
         if ((!objlen && unused) || unused/8 > objlen)
           {
@@ -1761,7 +1762,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
         mask = 0;
         for (i=1; unused; i <<= 1, unused--)
           mask |= i;
-      
+
         /* The first octet */
         bits = 0;
         if (objlen)
@@ -1769,27 +1770,27 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
             bits = *pp++; nn--; objlen--;
             if (full)
               full--;
-            else 
+            else
               {
                 bits &= ~mask;
-                mask = 0; 
+                mask = 0;
               }
           }
         if ((bits & 0x80)) /* ASN.1 bit 0. */
           aodf->pinflags.case_sensitive = 1;
         if ((bits & 0x40)) /* ASN.1 bit 1. */
           aodf->pinflags.local = 1;
-        if ((bits & 0x20)) 
+        if ((bits & 0x20))
           aodf->pinflags.change_disabled = 1;
-        if ((bits & 0x10)) 
+        if ((bits & 0x10))
           aodf->pinflags.unblock_disabled = 1;
-        if ((bits & 0x08)) 
+        if ((bits & 0x08))
           aodf->pinflags.initialized = 1;
-        if ((bits & 0x04)) 
+        if ((bits & 0x04))
           aodf->pinflags.needs_padding = 1;
-        if ((bits & 0x02)) 
+        if ((bits & 0x02))
           aodf->pinflags.unblocking_pin = 1;
-        if ((bits & 0x01)) 
+        if ((bits & 0x01))
           aodf->pinflags.so_pin = 1;
         /* The second octet. */
         bits = 0;
@@ -1798,19 +1799,19 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
             bits = *pp++; nn--; objlen--;
             if (full)
               full--;
-            else 
+            else
               {
                 bits &= ~mask;
-                mask = 0; 
+                mask = 0;
               }
           }
-        if ((bits & 0x80)) 
+        if ((bits & 0x80))
           aodf->pinflags.disable_allowed = 1;
-        if ((bits & 0x40)) 
+        if ((bits & 0x40))
           aodf->pinflags.integrity_protected = 1;
-        if ((bits & 0x20)) 
+        if ((bits & 0x20))
           aodf->pinflags.confidentiality_protected = 1;
-        if ((bits & 0x10)) 
+        if ((bits & 0x10))
           aodf->pinflags.exchange_ref_data = 1;
         /* Skip remaining bits. */
         pp += objlen;
@@ -1833,7 +1834,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
       for (ul=0; objlen; objlen--)
         {
           ul <<= 8;
-          ul |= (*pp++) & 0xff; 
+          ul |= (*pp++) & 0xff;
           nn--;
         }
       aodf->pintype = ul;
@@ -1853,7 +1854,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
       for (ul=0; objlen; objlen--)
         {
           ul <<= 8;
-          ul |= (*pp++) & 0xff; 
+          ul |= (*pp++) & 0xff;
           nn--;
         }
       aodf->min_length = ul;
@@ -1873,7 +1874,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
       for (ul=0; objlen; objlen--)
         {
           ul <<= 8;
-          ul |= (*pp++) & 0xff; 
+          ul |= (*pp++) & 0xff;
           nn--;
         }
       aodf->stored_length = ul;
@@ -1898,12 +1899,12 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
           for (ul=0; objlen; objlen--)
             {
               ul <<= 8;
-              ul |= (*pp++) & 0xff; 
+              ul |= (*pp++) & 0xff;
               nn--;
             }
           aodf->max_length = ul;
           aodf->max_length_valid = 1;
-          
+
           where = __LINE__;
           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
                                   &ndef, &objlen, &hdrlen);
@@ -1926,12 +1927,12 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
           for (ul=0; objlen; objlen--)
             {
               ul <<= 8;
-              ul |= (*pp++) & 0xff; 
+              ul |= (*pp++) & 0xff;
               nn--;
             }
           aodf->pin_reference = ul;
           aodf->pin_reference_valid = 1;
-          
+
           where = __LINE__;
           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
                                   &ndef, &objlen, &hdrlen);
@@ -1953,7 +1954,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
             }
           aodf->pad_char = *pp++; nn--;
           aodf->pad_char_valid = 1;
-          
+
           where = __LINE__;
           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
                                   &ndef, &objlen, &hdrlen);
@@ -1970,7 +1971,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
         {
           pp += objlen;
           nn -= objlen;
-          
+
           where = __LINE__;
           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
                                   &ndef, &objlen, &hdrlen);
@@ -1987,7 +1988,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
         {
           const unsigned char *ppp = pp;
           size_t nnn = objlen;
-          
+
           pp += objlen;
           nn -= objlen;
 
@@ -2014,7 +2015,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
             goto no_core;
           for (i=0; i < aodf->pathlen; i++, ppp += 2, nnn -= 2)
             aodf->path[i] = ((ppp[0] << 8) | ppp[1]);
-          
+
           if (nnn)
             {
               /* An index and length follows. */
@@ -2027,15 +2028,15 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
                 err = gpg_error (GPG_ERR_INV_OBJ);
               if (err)
                 goto parse_error;
-              
+
               for (ul=0; objlen; objlen--)
                 {
                   ul <<= 8;
-                  ul |= (*ppp++) & 0xff; 
+                  ul |= (*ppp++) & 0xff;
                   nnn--;
                 }
               aodf->off = ul;
-              
+
               where = __LINE__;
               err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
                                       &ndef, &objlen, &hdrlen);
@@ -2044,17 +2045,17 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
                 err = gpg_error (GPG_ERR_INV_OBJ);
               if (err)
                 goto parse_error;
-              
+
               for (ul=0; objlen; objlen--)
                 {
                   ul <<= 8;
-                  ul |= (*ppp++) & 0xff; 
+                  ul |= (*ppp++) & 0xff;
                   nnn--;
                 }
               aodf->len = ul;
             }
         }
-      
+
       /* Igonore further objects which might be there due to future
          extensions of pkcs#15. */
 
@@ -2126,7 +2127,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
             log_printf ("[%lu/%lu]", aodf->off, aodf->len);
         }
       log_printf ("\n");
-      
+
       /* Put it into the list. */
       aodf->next = aodflist;
       aodflist = aodf;
@@ -2158,7 +2159,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
 
 
 
-/* Read and parse the EF(TokenInfo). 
+/* Read and parse the EF(TokenInfo).
 
 TokenInfo ::= SEQUENCE {
     version            INTEGER {v1(0)} (v1,...),
@@ -2174,11 +2175,11 @@ TokenInfo ::= SEQUENCE {
     holderId           [4] Label OPTIONAL,
     lastUpdate         [5] LastUpdate OPTIONAL,
     preferredLanguage  PrintableString OPTIONAL -- In accordance with
-    -- IETF RFC 1766 
+    -- IETF RFC 1766
 } (CONSTRAINED BY { -- Each AlgorithmInfo.reference value must be unique --})
 
 TokenFlags ::= BIT STRING {
-    readonly           (0),
+    readOnly           (0),
     loginRequired      (1),
     prnGeneration      (2),
     eidCompliant       (3)
@@ -2217,12 +2218,12 @@ read_ef_tokeninfo (app_t app)
   size_t n, objlen, hdrlen;
   int class, tag, constructed, ndef;
   unsigned long ul;
-  
+
   err = select_and_read_binary (app->slot, 0x5032, "TokenInfo",
                                 &buffer, &buflen);
   if (err)
     return err;
-  
+
   p = buffer;
   n = buflen;
 
@@ -2249,7 +2250,7 @@ read_ef_tokeninfo (app_t app)
   for (ul=0; objlen; objlen--)
     {
       ul <<= 8;
-      ul |= (*p++) & 0xff; 
+      ul |= (*p++) & 0xff;
       n--;
     }
   if (ul)
@@ -2266,7 +2267,7 @@ read_ef_tokeninfo (app_t app)
     err = gpg_error (GPG_ERR_INV_OBJ);
   if (err)
     goto leave;
-  
+
   xfree (app->app_local->serialno);
   app->app_local->serialno = xtrymalloc (objlen);
   if (!app->app_local->serialno)
@@ -2307,7 +2308,7 @@ read_p15_info (app_t app)
             return err;
         }
     }
-  
+
   /* Read the ODF so that we know the location of all directory
      files. */
   /* Fixme: We might need to get a non-standard ODF FID from TokenInfo. */
@@ -2319,13 +2320,13 @@ read_p15_info (app_t app)
   assert (!app->app_local->certificate_info);
   assert (!app->app_local->trusted_certificate_info);
   assert (!app->app_local->useful_certificate_info);
-  err = read_ef_cdf (app, app->app_local->odf.certificates, 
+  err = read_ef_cdf (app, app->app_local->odf.certificates,
                      &app->app_local->certificate_info);
   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
-    err = read_ef_cdf (app, app->app_local->odf.trusted_certificates, 
+    err = read_ef_cdf (app, app->app_local->odf.trusted_certificates,
                        &app->app_local->trusted_certificate_info);
   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
-    err = read_ef_cdf (app, app->app_local->odf.useful_certificates, 
+    err = read_ef_cdf (app, app->app_local->odf.useful_certificates,
                        &app->app_local->useful_certificate_info);
   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
     err = 0;
@@ -2370,7 +2371,8 @@ send_certinfo (app_t app, ctrl_t ctrl, const char *certtype,
       p = stpcpy (buf, "P15");
       if (app->app_local->home_df)
         {
-          sprintf (p, "-%04hX", (app->app_local->home_df & 0xffff));
+          snprintf (p, 6, "-%04X",
+                    (unsigned int)(app->app_local->home_df & 0xffff));
           p += 5;
         }
       p = stpcpy (p, ".");
@@ -2378,7 +2380,7 @@ send_certinfo (app_t app, ctrl_t ctrl, const char *certtype,
 
       send_status_info (ctrl, "CERTINFO",
                         certtype, strlen (certtype),
-                        buf, strlen (buf), 
+                        buf, strlen (buf),
                         NULL, (size_t)0);
       xfree (buf);
     }
@@ -2405,7 +2407,7 @@ keygripstr_from_prkdf (app_t app, prkdf_object_t prkdf, char *r_gripstr)
      a matching certificate and extract the key from there. */
 
   /* Look for a matching certificate. A certificate matches if the Id
-     matches the obne of the private key info. */
+     matches the one of the private key info. */
   for (cdf = app->app_local->certificate_info; cdf; cdf = cdf->next)
     if (cdf->objidlen == prkdf->objidlen
         && !memcmp (cdf->objid, prkdf->objid, prkdf->objidlen))
@@ -2443,7 +2445,7 @@ keygripstr_from_prkdf (app_t app, prkdf_object_t prkdf, char *r_gripstr)
 
 /* Helper to do_learn_status: Send information about all known
    keypairs back.  FIXME: much code duplication from
-   send_sertinfo(). */
+   send_certinfo(). */
 static gpg_error_t
 send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
 {
@@ -2461,7 +2463,8 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
       p = stpcpy (buf, "P15");
       if (app->app_local->home_df)
         {
-          sprintf (p, "-%04hX", (app->app_local->home_df & 0xffff));
+          snprintf (p, 6, "-%04hX",
+                    (unsigned int)(app->app_local->home_df & 0xffff));
           p += 5;
         }
       p = stpcpy (p, ".");
@@ -2480,7 +2483,7 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
           assert (strlen (gripstr) == 40);
           send_status_info (ctrl, "KEYPAIRINFO",
                             gripstr, 40,
-                            buf, strlen (buf), 
+                            buf, strlen (buf),
                             NULL, (size_t)0);
         }
       xfree (buf);
@@ -2491,7 +2494,7 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
 
 
 /* This is the handler for the LEARN command.  */
-static gpg_error_t 
+static gpg_error_t
 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
 {
   gpg_error_t err;
@@ -2564,7 +2567,7 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
       log_printf (": %s\n", gpg_strerror (err));
       goto leave;
     }
-  
+
   /* Check whether this is really a certificate.  */
   p = buffer;
   n = buflen;
@@ -2589,7 +2592,7 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
                           &ndef, &objlen, &hdrlen);
   if (err)
     goto leave;
-  
+
   if (!rootca
       && class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
     {
@@ -2606,7 +2609,7 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
       save_p = p;
       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
                               &ndef, &objlen, &hdrlen);
-      if (err) 
+      if (err)
         goto leave;
       if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
         {
@@ -2642,8 +2645,8 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
    the CERTINFO status lines) and return it in the freshly allocated
    buffer to be stored at R_CERT and its length at R_CERTLEN.  A error
    code will be returned on failure and R_CERT and R_CERTLEN will be
-   set to NULL/0. */
-static gpg_error_t 
+   set to (NULL,0). */
+static gpg_error_t
 do_readcert (app_t app, const char *certid,
              unsigned char **r_cert, size_t *r_certlen)
 {
@@ -2654,7 +2657,7 @@ do_readcert (app_t app, const char *certid,
   *r_certlen = 0;
   err = cdf_object_from_certid (app, certid, &cdf);
   if (!err)
-    err =readcert_by_cdf (app, cdf, r_cert, r_certlen);
+    err = readcert_by_cdf (app, cdf, r_cert, r_certlen);
   return err;
 }
 
@@ -2662,7 +2665,7 @@ do_readcert (app_t app, const char *certid,
 
 /* Implement the GETATTR command.  This is similar to the LEARN
    command but returns just one value via the status interface. */
-static gpg_error_t 
+static gpg_error_t
 do_getattr (app_t app, ctrl_t ctrl, const char *name)
 {
   gpg_error_t err;
@@ -2686,7 +2689,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
           p = stpcpy (buf, "P15");
           if (app->app_local->home_df)
             {
-              sprintf (p, "-%04hX", (app->app_local->home_df & 0xffff));
+              snprintf (p, 6, "-%04hX",
+                        (unsigned int)(app->app_local->home_df & 0xffff));
               p += 5;
             }
           p = stpcpy (p, ".");
@@ -2737,7 +2741,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
         }
 
     }
-  return gpg_error (GPG_ERR_INV_NAME); 
+  return gpg_error (GPG_ERR_INV_NAME);
 }
 
 
@@ -2763,14 +2767,14 @@ micardo_mse (app_t app, unsigned short fid)
       log_error ("error reading EF_keyD: %s\n", gpg_strerror (err));
       return err;
     }
-  
+
   for (recno = 1, se_num = -1; ; recno++)
     {
       unsigned char *buffer;
       size_t buflen;
       size_t n, nn;
       const unsigned char *p, *pp;
-      
+
       err = iso7816_read_record (app->slot, recno, 1, 0, &buffer, &buflen);
       if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
         break; /* ready */
@@ -2805,8 +2809,8 @@ micardo_mse (app_t app, unsigned short fid)
       log_error ("CRT for keyfile %04hX not found\n", fid);
       return gpg_error (GPG_ERR_NOT_FOUND);
     }
-  
-  
+
+
   /* Restore the security environment to SE_NUM if needed */
   if (se_num)
     {
@@ -2837,13 +2841,13 @@ micardo_mse (app_t app, unsigned short fid)
 
 
 
-/* Handler for the PKSIGN command. 
+/* Handler for the PKSIGN command.
 
    Create the signature and return the allocated result in OUTDATA.
    If a PIN is required, the PINCB will be used to ask for the PIN;
    that callback should return the PIN in an allocated buffer and
    store that as the 3rd argument.  */
-static gpg_error_t 
+static gpg_error_t
 do_sign (app_t app, const char *keyidstr, int hashalgo,
          gpg_error_t (*pincb)(void*, const char *, char **),
          void *pincb_arg,
@@ -2892,7 +2896,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 
   /* Find the authentication object to this private key object. */
   for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next)
-    if (aodf->objidlen == prkdf->authidlen 
+    if (aodf->objidlen == prkdf->authidlen
         && !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
       break;
   if (!aodf)
@@ -2937,7 +2941,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   if (app->app_local->card_type == CARD_TYPE_BELPIC)
     {
       unsigned char mse[5];
-      
+
       mse[0] = 4;    /* Length of the template. */
       mse[1] = 0x80; /* Algorithm reference tag. */
       if (hashalgo == MD_USER_TLS_MD5SHA1)
@@ -2947,7 +2951,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       mse[3] = 0x84; /* Private key reference tag. */
       mse[4] = prkdf->key_reference_valid? prkdf->key_reference : 0x82;
 
-      err = iso7816_manage_security_env (app->slot, 
+      err = iso7816_manage_security_env (app->slot,
                                          0x41, 0xB6,
                                          mse, sizeof mse);
       no_data_padding = 1;
@@ -2987,7 +2991,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       if (strlen (pinvalue) < aodf->min_length)
         {
           log_error ("PIN is too short; minimum length is %lu\n",
-                     aodf->min_length);         
+                     aodf->min_length);
           err = gpg_error (GPG_ERR_BAD_PIN);
         }
       else if (aodf->stored_length && strlen (pinvalue) > aodf->stored_length)
@@ -3027,7 +3031,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
         case PIN_TYPE_UTF8:
           break;
         case PIN_TYPE_HALF_NIBBLE_BCD:
-          errstr = "PIN type Half-Nibble-BCD is not supported"; 
+          errstr = "PIN type Half-Nibble-BCD is not supported";
           break;
         case PIN_TYPE_ISO9564_1:
           errstr = "PIN type ISO9564-1 is not supported";
@@ -3064,7 +3068,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
           for (s=pinvalue; i < aodf->stored_length && *s && s[1]; s = s+2 )
             paddedpin[i++] = (((*s - '0') << 4) | ((s[1] - '0') & 0x0f));
           if (i < aodf->stored_length && *s)
-            paddedpin[i++] = (((*s - '0') << 4) 
+            paddedpin[i++] = (((*s - '0') << 4)
                               |((aodf->pad_char_valid?aodf->pad_char:0)&0x0f));
 
           if (aodf->pinflags.needs_padding)
@@ -3130,7 +3134,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       else if (hashalgo == GCRY_MD_RMD160
                && !memcmp (indata, rmd160_prefix, 15))
         ;
-      else 
+      else
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data, indata, indatalen);
     }
@@ -3141,7 +3145,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
         memcpy (data, sha1_prefix, 15);
       else if (hashalgo == GCRY_MD_RMD160)
         memcpy (data, rmd160_prefix, 15);
-      else 
+      else
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data+15, indata, indatalen);
     }
@@ -3164,12 +3168,12 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   else if (prkdf->key_reference_valid)
     {
       unsigned char mse[3];
-      
+
       mse[0] = 0x84; /* Select asym. key. */
       mse[1] = 1;
       mse[2] = prkdf->key_reference;
 
-      err = iso7816_manage_security_env (app->slot, 
+      err = iso7816_manage_security_env (app->slot,
                                          0x41, 0xB6,
                                          mse, sizeof mse);
     }
@@ -3189,14 +3193,14 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 }
 
 
-/* Handler for the PKAUTH command. 
+/* Handler for the PKAUTH command.
 
    This is basically the same as the PKSIGN command but we first check
    that the requested key is suitable for authentication; that is, it
    must match the criteria used for the attribute $AUTHKEYID.  See
    do_sign for calling conventions; there is no HASHALGO, though. */
-static gpg_error_t 
-do_auth (app_t app, const char *keyidstr, 
+static gpg_error_t
+do_auth (app_t app, const char *keyidstr,
          gpg_error_t (*pincb)(void*, const char *, char **),
          void *pincb_arg,
          const void *indata, size_t indatalen,
@@ -3219,7 +3223,7 @@ do_auth (app_t app, const char *keyidstr,
     }
 
   algo = indatalen == 36? MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1;
-  return do_sign (app, keyidstr, algo, pincb, pincb_arg, 
+  return do_sign (app, keyidstr, algo, pincb, pincb_arg,
                   indata, indatalen, outdata, outdatalen);
 }
 
@@ -3258,7 +3262,7 @@ read_home_df (int slot, int *r_belpic)
         {
           pp = find_tlv (p, n, 0x50, &nn);
           if (pp) /* fixme: Filter log value? */
-            log_info ("pkcs#15 application label from EF(DIR) is `%.*s'\n",
+            log_info ("pkcs#15 application label from EF(DIR) is '%.*s'\n",
                       (int)nn, pp);
           pp = find_tlv (p, n, 0x51, &nn);
           if (pp && nn == 4 && *pp == 0x3f && !pp[1])
@@ -3273,8 +3277,8 @@ read_home_df (int slot, int *r_belpic)
 }
 
 
-/* 
-   Select the PKCS#15 application on the card in SLOT. 
+/*
+   Select the PKCS#15 application on the card in SLOT.
  */
 gpg_error_t
 app_select_p15 (app_t app)
@@ -3388,7 +3392,7 @@ app_select_p15 (app_t app)
           unsigned char *p;
 
           /* FIXME: actually get it from EF(TokenInfo). */
-          
+
           p = xtrymalloc (3 + app->serialnolen);
           if (!p)
             rc = gpg_error (gpg_err_code_from_errno (errno));
diff --git a/scd/app-sc-hsm.c b/scd/app-sc-hsm.c
new file mode 100644 (file)
index 0000000..79899ce
--- /dev/null
@@ -0,0 +1,2084 @@
+/* app-sc-hsm.c - The SmartCard-HSM card application (www.smartcard-hsm.com).
+ *     Copyright (C) 2005 Free Software Foundation, Inc.
+ *     Copyright (C) 2014 Andreas Schwier <andreas.schwier@cardcontact.de>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+   Code in this driver is based on app-p15.c with modifications.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
+#include "scdaemon.h"
+
+#include "iso7816.h"
+#include "app-common.h"
+#include "tlv.h"
+#include "apdu.h"
+
+
+/* The AID of the SmartCard-HSM applet. */
+static char const sc_hsm_aid[] = { 0xE8, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x81,
+                                   0xC3, 0x1F, 0x02, 0x01  };
+
+
+/* Special file identifier for SmartCard-HSM */
+typedef enum
+{
+    SC_HSM_PRKD_PREFIX = 0xC4,
+    SC_HSM_CD_PREFIX = 0xC8,
+    SC_HSM_DCOD_PREFIX = 0xC9,
+    SC_HSM_CA_PREFIX = 0xCA,
+    SC_HSM_KEY_PREFIX = 0xCC,
+    SC_HSM_EE_PREFIX = 0xCE
+} fid_prefix_type_t;
+
+
+/* The key types supported by the SmartCard-HSM */
+typedef enum
+  {
+    KEY_TYPE_RSA,
+    KEY_TYPE_ECC
+  } key_type_t;
+
+
+/* A bit array with for the key usage flags from the
+   commonKeyAttributes. */
+struct keyusage_flags_s
+{
+    unsigned int encrypt: 1;
+    unsigned int decrypt: 1;
+    unsigned int sign: 1;
+    unsigned int sign_recover: 1;
+    unsigned int wrap: 1;
+    unsigned int unwrap: 1;
+    unsigned int verify: 1;
+    unsigned int verify_recover: 1;
+    unsigned int derive: 1;
+    unsigned int non_repudiation: 1;
+};
+typedef struct keyusage_flags_s keyusage_flags_t;
+
+
+
+/* This is an object to store information about a Certificate
+   Directory File (CDF) in a format suitable for further processing by
+   us. To keep memory management, simple we use a linked list of
+   items; i.e. one such object represents one certificate and the list
+   the entire CDF. */
+struct cdf_object_s
+{
+  /* Link to next item when used in a linked list. */
+  struct cdf_object_s *next;
+
+  /* Length and allocated buffer with the Id of this object. */
+  size_t objidlen;
+  unsigned char *objid;
+
+  /* To avoid reading a certificate more than once, we cache it in an
+     allocated memory IMAGE of IMAGELEN. */
+  size_t imagelen;
+  unsigned char *image;
+
+  /* EF containing certificate */
+  unsigned short fid;
+};
+typedef struct cdf_object_s *cdf_object_t;
+
+
+
+/* This is an object to store information about a Private Key
+   Directory File (PrKDF) in a format suitable for further processing
+   by us. To keep memory management, simple we use a linked list of
+   items; i.e. one such object represents one certificate and the list
+   the entire PrKDF. */
+struct prkdf_object_s
+{
+  /* Link to next item when used in a linked list. */
+  struct prkdf_object_s *next;
+
+  /* Key type */
+  key_type_t keytype;
+
+  /* Key size in bits or 0 if unknown */
+  size_t keysize;
+
+  /* Length and allocated buffer with the Id of this object. */
+  size_t objidlen;
+  unsigned char *objid;
+
+  /* The key's usage flags. */
+  keyusage_flags_t usageflags;
+
+  /* The keyReference */
+  unsigned char key_reference;
+};
+typedef struct prkdf_object_s *prkdf_object_t;
+
+
+
+/* Context local to this application. */
+struct app_local_s
+{
+  /* Information on all certificates. */
+  cdf_object_t certificate_info;
+  /* Information on all trusted certificates. */
+  cdf_object_t trusted_certificate_info;
+  /* Information on all private keys. */
+  prkdf_object_t private_key_info;
+};
+
+
+
+/*** Local prototypes.  ***/
+static gpg_error_t readcert_by_cdf (app_t app, cdf_object_t cdf,
+                                    unsigned char **r_cert, size_t *r_certlen);
+
+
+
+/* Release the CDF object A  */
+static void
+release_cdflist (cdf_object_t a)
+{
+  while (a)
+    {
+      cdf_object_t tmp = a->next;
+      xfree (a->image);
+      xfree (a->objid);
+      xfree (a);
+      a = tmp;
+    }
+}
+
+
+
+/* Release the PrKDF object A.  */
+static void
+release_prkdflist (prkdf_object_t a)
+{
+  while (a)
+    {
+      prkdf_object_t tmp = a->next;
+      xfree (a->objid);
+      xfree (a);
+      a = tmp;
+    }
+}
+
+
+
+/* Release all local resources.  */
+static void
+do_deinit (app_t app)
+{
+  if (app && app->app_local)
+    {
+      release_cdflist (app->app_local->certificate_info);
+      release_cdflist (app->app_local->trusted_certificate_info);
+      release_prkdflist (app->app_local->private_key_info);
+      xfree (app->app_local);
+      app->app_local = NULL;
+    }
+}
+
+
+
+/* Get the list of EFs from the SmartCard-HSM.
+ * On success a dynamically buffer containing the EF list is returned.
+ * The caller is responsible for freeing the buffer.
+ */
+static gpg_error_t
+list_ef (int slot, unsigned char **result, size_t *resultlen)
+{
+  int sw;
+
+  if (!result || !resultlen)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  *result = NULL;
+  *resultlen = 0;
+
+  sw = apdu_send_le (slot, 1, 0x80, 0x58, 0x00, 0x00, -1, NULL, 65536,
+                     result, resultlen);
+  if (sw != SW_SUCCESS)
+    {
+      /* Make sure that pending buffers are released. */
+      xfree (*result);
+      *result = NULL;
+      *resultlen = 0;
+    }
+  return iso7816_map_sw (sw);
+}
+
+
+
+/* Do a select and a read for the file with EFID.  EFID_DESC is a
+   description of the EF to be used with error messages.  On success
+   BUFFER and BUFLEN contain the entire content of the EF.  The caller
+   must free BUFFER only on success. */
+static gpg_error_t
+select_and_read_binary (int slot, unsigned short efid, const char *efid_desc,
+                        unsigned char **buffer, size_t *buflen, int maxread)
+{
+  gpg_error_t err;
+  unsigned char cdata[4];
+  int sw;
+
+  cdata[0] = 0x54;      /* Create ISO 7861-4 odd ins READ BINARY */
+  cdata[1] = 0x02;
+  cdata[2] = 0x00;
+  cdata[3] = 0x00;
+
+  sw = apdu_send_le(slot, 1, 0x00, 0xB1, efid >> 8, efid & 0xFF,
+                    4, cdata, maxread, buffer, buflen);
+
+  if (sw == SW_EOF_REACHED)
+    sw = SW_SUCCESS;
+
+  err = iso7816_map_sw (sw);
+  if (err)
+    {
+      log_error ("error reading %s (0x%04X): %s\n",
+                 efid_desc, efid, gpg_strerror (err));
+      return err;
+    }
+  return 0;
+}
+
+
+
+/* Parse a cert Id string (or a key Id string) and return the binary
+   object Id string in a newly allocated buffer stored at R_OBJID and
+   R_OBJIDLEN.  On Error NULL will be stored there and an error code
+   returned. On success caller needs to free the buffer at R_OBJID. */
+static gpg_error_t
+parse_certid (const char *certid, unsigned char **r_objid, size_t *r_objidlen)
+{
+  const char *s;
+  size_t objidlen;
+  unsigned char *objid;
+  int i;
+
+  *r_objid = NULL;
+  *r_objidlen = 0;
+
+  if (strncmp (certid, "HSM.", 4))
+    return gpg_error (GPG_ERR_INV_ID);
+  certid += 4;
+
+  for (s=certid, objidlen=0; hexdigitp (s); s++, objidlen++)
+    ;
+  if (*s || !objidlen || (objidlen%2))
+    return gpg_error (GPG_ERR_INV_ID);
+  objidlen /= 2;
+  objid = xtrymalloc (objidlen);
+  if (!objid)
+    return gpg_error_from_syserror ();
+  for (s=certid, i=0; i < objidlen; i++, s+=2)
+    objid[i] = xtoi_2 (s);
+  *r_objid = objid;
+  *r_objidlen = objidlen;
+  return 0;
+}
+
+
+
+/* Find a certificate object by the certificate ID CERTID and store a
+   pointer to it at R_CDF. */
+static gpg_error_t
+cdf_object_from_certid (app_t app, const char *certid, cdf_object_t *r_cdf)
+{
+  gpg_error_t err;
+  size_t objidlen;
+  unsigned char *objid;
+  cdf_object_t cdf;
+
+  err = parse_certid (certid, &objid, &objidlen);
+  if (err)
+    return err;
+
+  for (cdf = app->app_local->certificate_info; cdf; cdf = cdf->next)
+    if (cdf->objidlen == objidlen && !memcmp (cdf->objid, objid, objidlen))
+      break;
+  if (!cdf)
+    for (cdf = app->app_local->trusted_certificate_info; cdf; cdf = cdf->next)
+      if (cdf->objidlen == objidlen && !memcmp (cdf->objid, objid, objidlen))
+        break;
+  xfree (objid);
+  if (!cdf)
+    return gpg_error (GPG_ERR_NOT_FOUND);
+  *r_cdf = cdf;
+  return 0;
+}
+
+
+
+/* Find a private key object by the key Id string KEYIDSTR and store a
+   pointer to it at R_PRKDF. */
+static gpg_error_t
+prkdf_object_from_keyidstr (app_t app, const char *keyidstr,
+                            prkdf_object_t *r_prkdf)
+{
+  gpg_error_t err;
+  size_t objidlen;
+  unsigned char *objid;
+  prkdf_object_t prkdf;
+
+  err = parse_certid (keyidstr, &objid, &objidlen);
+  if (err)
+    return err;
+
+  for (prkdf = app->app_local->private_key_info; prkdf; prkdf = prkdf->next)
+    if (prkdf->objidlen == objidlen && !memcmp (prkdf->objid, objid, objidlen))
+      break;
+  xfree (objid);
+  if (!prkdf)
+    return gpg_error (GPG_ERR_NOT_FOUND);
+  *r_prkdf = prkdf;
+  return 0;
+}
+
+
+
+/* Parse the BIT STRING with the keyUsageFlags from the
+   CommonKeyAttributes. */
+static gpg_error_t
+parse_keyusage_flags (const unsigned char *der, size_t derlen,
+                      keyusage_flags_t *usageflags)
+{
+  unsigned int bits, mask;
+  int i, unused, full;
+
+  memset (usageflags, 0, sizeof *usageflags);
+  if (!derlen)
+    return gpg_error (GPG_ERR_INV_OBJ);
+
+  unused = *der++; derlen--;
+  if ((!derlen && unused) || unused/8 > derlen)
+    return gpg_error (GPG_ERR_ENCODING_PROBLEM);
+  full = derlen - (unused+7)/8;
+  unused %= 8;
+  mask = 0;
+  for (i=1; unused; i <<= 1, unused--)
+    mask |= i;
+
+  /* First octet */
+  if (derlen)
+    {
+      bits = *der++; derlen--;
+      if (full)
+        full--;
+      else
+        {
+          bits &= ~mask;
+          mask = 0;
+        }
+    }
+  else
+    bits = 0;
+  if ((bits & 0x80)) usageflags->encrypt = 1;
+  if ((bits & 0x40)) usageflags->decrypt = 1;
+  if ((bits & 0x20)) usageflags->sign = 1;
+  if ((bits & 0x10)) usageflags->sign_recover = 1;
+  if ((bits & 0x08)) usageflags->wrap = 1;
+  if ((bits & 0x04)) usageflags->unwrap = 1;
+  if ((bits & 0x02)) usageflags->verify = 1;
+  if ((bits & 0x01)) usageflags->verify_recover = 1;
+
+  /* Second octet. */
+  if (derlen)
+    {
+      bits = *der++; derlen--;
+      if (full)
+        full--;
+      else
+        {
+          bits &= ~mask;
+          mask = 0;
+        }
+    }
+  else
+    bits = 0;
+  if ((bits & 0x80)) usageflags->derive = 1;
+  if ((bits & 0x40)) usageflags->non_repudiation = 1;
+
+  return 0;
+}
+
+
+
+/* Read and parse a Private Key Directory File containing a single key
+   description in PKCS#15 format.  For each private key a matching
+   certificate description is created, if the certificate EF exists
+   and contains a X.509 certificate.
+
+   Example data:
+
+0000  30 2A 30 13 0C 11 4A 6F 65 20 44 6F 65 20 28 52  0*0...Joe Doe (R
+0010  53 41 32 30 34 38 29 30 07 04 01 01 03 02 02 74  SA2048)0.......t
+0020  A1 0A 30 08 30 02 04 00 02 02 08 00              ..0.0.......
+
+   Decoded example:
+
+SEQUENCE SIZE( 42 )
+  SEQUENCE SIZE( 19 )
+    UTF8-STRING SIZE( 17 )                -- label
+      0000  4A 6F 65 20 44 6F 65 20 28 52 53 41 32 30 34 38  Joe Doe (RSA2048
+      0010  29                                               )
+  SEQUENCE SIZE( 7 )
+    OCTET-STRING SIZE( 1 )                -- id
+      0000  01
+    BIT-STRING SIZE( 2 )                  -- key usage
+      0000  02 74
+  A1 [ CONTEXT 1 ] IMPLICIT SEQUENCE SIZE( 10 )
+    SEQUENCE SIZE( 8 )
+      SEQUENCE SIZE( 2 )
+        OCTET-STRING SIZE( 0 )            -- empty path, req object in PKCS#15
+      INTEGER SIZE( 2 )                   -- modulus size in bits
+        0000  08 00
+*/
+static gpg_error_t
+read_ef_prkd (app_t app, unsigned short fid, prkdf_object_t *prkdresult,
+              cdf_object_t *cdresult)
+{
+  gpg_error_t err;
+  unsigned char *buffer = NULL;
+  size_t buflen;
+  const unsigned char *p;
+  size_t n, objlen, hdrlen;
+  int class, tag, constructed, ndef;
+  int i;
+  const unsigned char *pp;
+  size_t nn;
+  int where;
+  const char *errstr = NULL;
+  prkdf_object_t prkdf = NULL;
+  cdf_object_t cdf = NULL;
+  unsigned long ul;
+  const unsigned char *objid;
+  size_t objidlen;
+  keyusage_flags_t usageflags;
+  const char *s;
+  key_type_t keytype;
+  size_t keysize;
+
+  if (!fid)
+    return gpg_error (GPG_ERR_NO_DATA); /* No private keys. */
+
+  err = select_and_read_binary (app->slot, fid, "PrKDF", &buffer, &buflen, 255);
+  if (err)
+    return err;
+
+  p = buffer;
+  n = buflen;
+
+  err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > n || (tag != TAG_SEQUENCE && tag != 0x00)))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    {
+      log_error ("error parsing PrKDF record: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  keytype = tag == 0x00 ? KEY_TYPE_ECC : KEY_TYPE_RSA;
+
+  pp = p;
+  nn = objlen;
+  p += objlen;
+  n -= objlen;
+
+  /* Parse the commonObjectAttributes.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+
+  {
+    const unsigned char *ppp = pp;
+    size_t nnn = objlen;
+
+    pp += objlen;
+    nn -= objlen;
+
+    /* Search the optional AuthId.  We need to skip the optional Label
+       (UTF8STRING) and the optional CommonObjectFlags (BITSTRING). */
+    where = __LINE__;
+    err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                            &ndef, &objlen, &hdrlen);
+    if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
+      err = gpg_error (GPG_ERR_INV_OBJ);
+    if (gpg_err_code (err) == GPG_ERR_EOF)
+      goto no_authid;
+    if (err)
+      goto parse_error;
+
+    if (tag == TAG_UTF8_STRING)
+      {
+        ppp += objlen; /* Skip the Label. */
+        nnn -= objlen;
+
+        where = __LINE__;
+        err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                                &ndef, &objlen, &hdrlen);
+        if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
+          err = gpg_error (GPG_ERR_INV_OBJ);
+        if (gpg_err_code (err) == GPG_ERR_EOF)
+          goto no_authid;
+        if (err)
+          goto parse_error;
+      }
+    if (tag == TAG_BIT_STRING)
+      {
+        ppp += objlen; /* Skip the CommonObjectFlags.  */
+        nnn -= objlen;
+
+        where = __LINE__;
+        err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                                &ndef, &objlen, &hdrlen);
+        if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
+          err = gpg_error (GPG_ERR_INV_OBJ);
+        if (gpg_err_code (err) == GPG_ERR_EOF)
+          goto no_authid;
+        if (err)
+          goto parse_error;
+      }
+    if (tag == TAG_OCTET_STRING && objlen)
+      {
+        /* AuthId ignored */
+      }
+  no_authid:
+    ;
+  }
+
+  /* Parse the commonKeyAttributes.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+      &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+
+  {
+    const unsigned char *ppp = pp;
+    size_t nnn = objlen;
+
+    pp += objlen;
+    nn -= objlen;
+
+    /* Get the Id. */
+    where = __LINE__;
+    err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                            &ndef, &objlen, &hdrlen);
+    if (!err && (objlen > nnn
+                 || class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING))
+      err = gpg_error (GPG_ERR_INV_OBJ);
+    if (err)
+      goto parse_error;
+
+    objid = ppp;
+    objidlen = objlen;
+    ppp += objlen;
+    nnn -= objlen;
+
+    /* Get the KeyUsageFlags. */
+    where = __LINE__;
+    err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                            &ndef, &objlen, &hdrlen);
+    if (!err && (objlen > nnn
+                 || class != CLASS_UNIVERSAL || tag != TAG_BIT_STRING))
+      err = gpg_error (GPG_ERR_INV_OBJ);
+    if (err)
+      goto parse_error;
+
+    err = parse_keyusage_flags (ppp, objlen, &usageflags);
+    if (err)
+      goto parse_error;
+
+    ppp += objlen;
+    nnn -= objlen;
+
+    /* Find the keyReference */
+    where = __LINE__;
+    err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                            &ndef, &objlen, &hdrlen);
+    if (gpg_err_code (err) == GPG_ERR_EOF)
+      goto leave_cki;
+    if (!err && objlen > nnn)
+      err = gpg_error (GPG_ERR_INV_OBJ);
+    if (err)
+      goto parse_error;
+
+    if (class == CLASS_UNIVERSAL && tag == TAG_BOOLEAN)
+      {
+        /* Skip the native element. */
+        ppp += objlen;
+        nnn -= objlen;
+
+        err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                                &ndef, &objlen, &hdrlen);
+        if (gpg_err_code (err) == GPG_ERR_EOF)
+          goto leave_cki;
+        if (!err && objlen > nnn)
+          err = gpg_error (GPG_ERR_INV_OBJ);
+        if (err)
+          goto parse_error;
+      }
+    if (class == CLASS_UNIVERSAL && tag == TAG_BIT_STRING)
+      {
+        /* Skip the accessFlags. */
+        ppp += objlen;
+        nnn -= objlen;
+
+        err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                                &ndef, &objlen, &hdrlen);
+        if (gpg_err_code (err) == GPG_ERR_EOF)
+          goto leave_cki;
+        if (!err && objlen > nnn)
+          err = gpg_error (GPG_ERR_INV_OBJ);
+        if (err)
+          goto parse_error;
+      }
+    if (class == CLASS_UNIVERSAL && tag == TAG_INTEGER)
+      {
+        /* Yep, this is the keyReference.
+           Note: UL is currently not used. */
+        for (ul=0; objlen; objlen--)
+          {
+            ul <<= 8;
+            ul |= (*ppp++) & 0xff;
+            nnn--;
+          }
+      }
+
+  leave_cki:
+    ;
+  }
+
+
+  /* Skip subClassAttributes.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && objlen > nn)
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+  if (class == CLASS_CONTEXT && tag == 0)
+    {
+      pp += objlen;
+      nn -= objlen;
+
+      where = __LINE__;
+      err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                              &ndef, &objlen, &hdrlen);
+    }
+
+  /* Parse the keyAttributes.  */
+  if (!err && (objlen > nn || class != CLASS_CONTEXT || tag != 1))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+
+  nn = objlen;
+
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && objlen > nn)
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+
+  nn = objlen;
+
+  /* Check that the reference is a Path object.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && objlen > nn)
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+  if (class != CLASS_UNIVERSAL || tag != TAG_SEQUENCE)
+    {
+      errstr = "unsupported reference type";
+      goto parse_error;
+    }
+
+  pp += objlen;
+  nn -= objlen;
+
+  /* Parse the key size object. */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && objlen > nn)
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+  keysize = 0;
+  if (class == CLASS_UNIVERSAL && tag == TAG_INTEGER && objlen == 2)
+    {
+      keysize  = *pp++ << 8;
+      keysize += *pp++;
+    }
+
+  /* Create a new PrKDF list item. */
+  prkdf = xtrycalloc (1, sizeof *prkdf);
+  if (!prkdf)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  prkdf->keytype = keytype;
+  prkdf->keysize = keysize;
+  prkdf->objidlen = objidlen;
+  prkdf->objid = xtrymalloc (objidlen);
+  if (!prkdf->objid)
+    {
+      err = gpg_error_from_syserror ();
+      xfree (prkdf);
+      prkdf = NULL;
+      goto leave;
+    }
+  memcpy (prkdf->objid, objid, objidlen);
+
+  prkdf->usageflags = usageflags;
+  prkdf->key_reference = fid & 0xFF;
+
+  log_debug ("PrKDF %04hX: id=", fid);
+  for (i=0; i < prkdf->objidlen; i++)
+    log_printf ("%02X", prkdf->objid[i]);
+  log_printf (" keyref=0x%02X", prkdf->key_reference);
+  log_printf (" keysize=%zu", prkdf->keysize);
+  log_printf (" usage=");
+  s = "";
+  if (prkdf->usageflags.encrypt)
+    {
+      log_printf ("%sencrypt", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.decrypt)
+    {
+      log_printf ("%sdecrypt", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.sign)
+    {
+      log_printf ("%ssign", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.sign_recover)
+    {
+      log_printf ("%ssign_recover", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.wrap   )
+    {
+      log_printf ("%swrap", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.unwrap )
+    {
+      log_printf ("%sunwrap", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.verify )
+    {
+      log_printf ("%sverify", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.verify_recover)
+    {
+      log_printf ("%sverify_recover", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.derive )
+    {
+      log_printf ("%sderive", s);
+      s = ",";
+    }
+  if (prkdf->usageflags.non_repudiation)
+    {
+      log_printf ("%snon_repudiation", s);
+      s = ",";
+    }
+  log_printf ("\n");
+
+  xfree (buffer);
+  buffer = NULL;
+  buflen = 0;
+  err = select_and_read_binary (app->slot,
+                                ((SC_HSM_EE_PREFIX << 8) | (fid & 0xFF)),
+                                "CertEF", &buffer, &buflen, 1);
+  if (!err && buffer[0] == 0x30)
+    {
+      /* Create a matching CDF list item. */
+      cdf = xtrycalloc (1, sizeof *cdf);
+      if (!cdf)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      cdf->objidlen = prkdf->objidlen;
+      cdf->objid = xtrymalloc (cdf->objidlen);
+      if (!cdf->objid)
+        {
+          err = gpg_error_from_syserror ();
+          xfree (cdf);
+          cdf = NULL;
+          goto leave;
+        }
+      memcpy (cdf->objid, prkdf->objid, objidlen);
+
+      cdf->fid = (SC_HSM_EE_PREFIX << 8) | (fid & 0xFF);
+
+      log_debug ("CDF %04hX: id=", fid);
+      for (i=0; i < cdf->objidlen; i++)
+        log_printf ("%02X", cdf->objid[i]);
+      log_printf (" fid=%04X\n", cdf->fid);
+    }
+
+  goto leave; /* Ready. */
+
+ parse_error:
+  log_error ("error parsing PrKDF record (%d): %s - skipped\n",
+             where, errstr? errstr : gpg_strerror (err));
+  err = 0;
+
+ leave:
+  xfree (buffer);
+  if (err)
+    {
+      if (prkdf)
+        {
+          if (prkdf->objid)
+            xfree (prkdf->objid);
+          xfree (prkdf);
+        }
+      if (cdf)
+        {
+          if (cdf->objid)
+            xfree (cdf->objid);
+          xfree (cdf);
+        }
+    }
+  else
+    {
+      prkdf->next = *prkdresult;
+      *prkdresult = prkdf;
+      if (cdf)
+        {
+          cdf->next = *cdresult;
+          *cdresult = cdf;
+        }
+    }
+  return err;
+}
+
+
+
+/* Read and parse the Certificate Description File identified by FID.
+   On success a the CDF list gets stored at RESULT and the caller is
+   then responsible of releasing the object.
+
+   Example data:
+
+0000  30 35 30 11 0C 0B 43 65 72 74 69 66 69 63 61 74  050...Certificat
+0010  65 03 02 06 40 30 16 04 14 C2 01 7C 2F BA A4 4A  e...@0.....|/..J
+0020  4A BB B8 49 11 DB 4A CA AA 7E 6A 2D 1B A1 08 30  J..I..J..~j-...0
+0030  06 30 04 04 02 CA 00                             .0.....
+
+   Decoded example:
+
+SEQUENCE SIZE( 53 )
+  SEQUENCE SIZE( 17 )
+    UTF8-STRING SIZE( 11 )                      -- label
+      0000  43 65 72 74 69 66 69 63 61 74 65                 Certificate
+    BIT-STRING SIZE( 2 )                        -- common object attributes
+      0000  06 40
+  SEQUENCE SIZE( 22 )
+    OCTET-STRING SIZE( 20 )                     -- id
+      0000  C2 01 7C 2F BA A4 4A 4A BB B8 49 11 DB 4A CA AA
+      0010  7E 6A 2D 1B
+  A1 [ CONTEXT 1 ] IMPLICIT SEQUENCE SIZE( 8 )
+    SEQUENCE SIZE( 6 )
+      SEQUENCE SIZE( 4 )
+        OCTET-STRING SIZE( 2 )                  -- path
+          0000  CA 00                                            ..
+ */
+static gpg_error_t
+read_ef_cd (app_t app, unsigned short fid, cdf_object_t *result)
+{
+  gpg_error_t err;
+  unsigned char *buffer = NULL;
+  size_t buflen;
+  const unsigned char *p;
+  size_t n, objlen, hdrlen;
+  int class, tag, constructed, ndef;
+  int i;
+  const unsigned char *pp;
+  size_t nn;
+  int where;
+  const char *errstr = NULL;
+  cdf_object_t cdf = NULL;
+  const unsigned char *objid;
+  size_t objidlen;
+
+  if (!fid)
+    return gpg_error (GPG_ERR_NO_DATA); /* No certificates. */
+
+  err = select_and_read_binary (app->slot, fid, "CDF", &buffer, &buflen, 255);
+  if (err)
+    return err;
+
+  p = buffer;
+  n = buflen;
+
+  err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > n || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    {
+      log_error ("error parsing CDF record: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+  pp = p;
+  nn = objlen;
+  p += objlen;
+  n -= objlen;
+
+  /* Skip the commonObjectAttributes.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+  pp += objlen;
+  nn -= objlen;
+
+  /* Parse the commonCertificateAttributes.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+
+  {
+    const unsigned char *ppp = pp;
+    size_t nnn = objlen;
+
+    pp += objlen;
+    nn -= objlen;
+
+    /* Get the Id. */
+    where = __LINE__;
+    err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
+                            &ndef, &objlen, &hdrlen);
+    if (!err && (objlen > nnn
+                 || class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING))
+      err = gpg_error (GPG_ERR_INV_OBJ);
+    if (err)
+      goto parse_error;
+
+    objid = ppp;
+    objidlen = objlen;
+  }
+
+  /* Parse the certAttribute.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn || class != CLASS_CONTEXT || tag != 1))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+  nn = objlen;
+
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn
+               || class != CLASS_UNIVERSAL || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+  nn = objlen;
+
+  /* Check that the reference is a Path object.  */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && objlen > nn)
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+  if (class != CLASS_UNIVERSAL || tag != TAG_SEQUENCE)
+    {
+      err = gpg_error (GPG_ERR_INV_OBJ);
+      goto parse_error;
+    }
+  nn = objlen;
+
+  /* Parse the Path object. */
+  where = __LINE__;
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && objlen > nn)
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    goto parse_error;
+
+  /* Make sure that the next element is a non zero path and of
+     even length (FID are two bytes each). */
+  if (class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING
+      || (objlen & 1) )
+    {
+      errstr = "invalid path reference";
+      goto parse_error;
+    }
+  /* Create a new CDF list item. */
+  cdf = xtrycalloc (1, sizeof *cdf);
+  if (!cdf)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  cdf->objidlen = objidlen;
+  cdf->objid = xtrymalloc (objidlen);
+  if (!cdf->objid)
+    {
+      err = gpg_error_from_syserror ();
+      xfree (cdf);
+      cdf = NULL;
+      goto leave;
+    }
+  memcpy (cdf->objid, objid, objidlen);
+
+  cdf->fid = (SC_HSM_CA_PREFIX << 8) | (fid & 0xFF);
+
+  log_debug ("CDF %04hX: id=", fid);
+  for (i=0; i < cdf->objidlen; i++)
+    log_printf ("%02X", cdf->objid[i]);
+
+  goto leave;
+
+ parse_error:
+  log_error ("error parsing CDF record (%d): %s - skipped\n",
+             where, errstr? errstr : gpg_strerror (err));
+  err = 0;
+
+ leave:
+  xfree (buffer);
+  if (err)
+    {
+      if (cdf)
+        {
+          if (cdf->objid)
+            xfree (cdf->objid);
+          xfree (cdf);
+        }
+    }
+  else
+    {
+      cdf->next = *result;
+      *result = cdf;
+    }
+  return err;
+}
+
+
+
+/* Read the device certificate and extract the serial number.
+
+   EF.C_DevAut (2F02) contains two CVCs, the first is the device
+   certificate, the second is the issuer certificate.
+
+   Example data:
+
+0000  7F 21 81 E2 7F 4E 81 9B 5F 29 01 00 42 0B 55 54  .!...N.._)..B.UT
+0010  43 43 30 32 30 30 30 30 32 7F 49 4F 06 0A 04 00  CC0200002.IO....
+0020  7F 00 07 02 02 02 02 03 86 41 04 6D FF D6 85 57  .........A.m...W
+0030  40 FB 10 5D 94 71 8A 94 D2 5E 50 33 E7 1E C0 6C  @..].q...^P3...l
+0040  63 D5 C8 FC BA F3 02 1D 70 23 F6 47 E8 35 48 EF  c.......p#.G.5H.
+0050  B5 94 72 3C 6F BE C0 EB 9A C7 FB 06 59 26 CF 65  ..r<o.......Y&.e
+0060  EF A1 72 E0 98 F3 F0 44 1B B7 71 5F 20 10 55 54  ..r....D..q_ .UT
+0070  43 43 30 32 30 30 30 31 33 30 30 30 30 30 7F 4C  CC020001300000.L
+0080  10 06 0B 2B 06 01 04 01 81 C3 1F 03 01 01 53 01  ...+..........S.
+0090  00 5F 25 06 01 04 00 07 01 01 5F 24 06 02 01 00  ._%......._$....
+00A0  03 02 07 5F 37 40 7F 73 04 3B 06 63 79 41 BE 1A  ..._7@.s.;.cyA..
+00B0  9F FC F6 77 67 2B 8A 41 D1 11 F6 9B 54 44 AD 19  ...wg+.A....TD..
+00C0  FB B8 0C C6 2F 34 71 8E 4F F6 92 59 34 61 D9 4F  ..../4q.O..Y4a.O
+00D0  4A 86 36 A8 D8 9A C6 3C 17 7E 71 CE A8 26 D0 C5  J.6....<.~q..&..
+00E0  25 61 78 9D 01 F8 7F 21 81 E0 7F 4E 81 99 5F 29  %ax....!...N.._)
+00F0  01 00 42 0E 55 54 53 52 43 41 43 43 31 30 30 30  ..B.UTSRCACC1000
+0100  30 31 7F 49 4F 06 0A 04 00 7F 00 07 02 02 02 02  01.IO...........
+0110  03 86 41 04 2F EA 33 47 7F 45 81 E2 FC CB 66 87  ..A./.3G.E....f.
+0120  4B 96 21 1D 68 81 73 F2 9F 8F 6B 91 F0 DE 4B 54  K.!.h.s...k...KT
+0130  8E D8 F0 82 3D CB BE 10 98 A3 1E 4F F0 72 5C E5  ....=......O.r\.
+0140  7B 1E F7 3C 68 09 03 E8 A0 3F 3E 06 C1 B0 3C 18  {..<h....?>...<.
+0150  6B AC 06 EA 5F 20 0B 55 54 43 43 30 32 30 30 30  k..._ .UTCC02000
+0160  30 32 7F 4C 10 06 0B 2B 06 01 04 01 81 C3 1F 03  02.L...+........
+0170  01 01 53 01 80 5F 25 06 01 03 00 03 02 08 5F 24  ..S.._%......._$
+0180  06 02 01 00 03 02 07 5F 37 40 93 C1 42 8B B3 8E  ......._7@..B...
+0190  42 61 6F 2C 19 E6 98 41 BD AA 60 BD E0 DD 4E F0  Bao,...A..`...N.
+01A0  15 D5 4F 71 B7 BB C3 3A F2 AD 27 5E DD EE 6D 12  ..Oq...:..'^..m.
+01B0  76 E6 2B A0 4C 01 CA C1 26 0C 45 6D C6 CB EC 92  v.+.L...&.Em....
+01C0  BF 38 18 AD 8F B2 29 40 A9 51                    .8....)@.Q
+
+   The certificate format is defined in BSI TR-03110:
+
+7F21 [ APPLICATION 33 ] IMPLICIT SEQUENCE SIZE( 226 )
+  7F4E [ APPLICATION 78 ] IMPLICIT SEQUENCE SIZE( 155 )
+    5F29 [ APPLICATION 41 ] SIZE( 1 )                           -- profile id
+      0000  00
+    42 [ APPLICATION 2 ] SIZE( 11 )                             -- CAR
+      0000  55 54 43 43 30 32 30 30 30 30 32                 UTCC0200002
+    7F49 [ APPLICATION 73 ] IMPLICIT SEQUENCE SIZE( 79 )        -- public key
+      OBJECT IDENTIFIER = { id-TA-ECDSA-SHA-256 }
+      86 [ CONTEXT 6 ] SIZE( 65 )
+        0000  04 6D FF D6 85 57 40 FB 10 5D 94 71 8A 94 D2 5E
+        0010  50 33 E7 1E C0 6C 63 D5 C8 FC BA F3 02 1D 70 23
+        0020  F6 47 E8 35 48 EF B5 94 72 3C 6F BE C0 EB 9A C7
+        0030  FB 06 59 26 CF 65 EF A1 72 E0 98 F3 F0 44 1B B7
+        0040  71
+    5F20 [ APPLICATION 32 ] SIZE( 16 )                          -- CHR
+      0000  55 54 43 43 30 32 30 30 30 31 33 30 30 30 30 30  UTCC020001300000
+    7F4C [ APPLICATION 76 ] IMPLICIT SEQUENCE SIZE( 16 )        -- CHAT
+      OBJECT IDENTIFIER = { 1 3 6 1 4 1 24991 3 1 1 }
+      53 [ APPLICATION 19 ] SIZE( 1 )
+        0000  00
+    5F25 [ APPLICATION 37 ] SIZE( 6 )                           -- Valid from
+      0000  01 04 00 07 01 01
+    5F24 [ APPLICATION 36 ] SIZE( 6 )                           -- Valid to
+      0000  02 01 00 03 02 07
+  5F37 [ APPLICATION 55 ] SIZE( 64 )                            -- Signature
+    0000  7F 73 04 3B 06 63 79 41 BE 1A 9F FC F6 77 67 2B
+    0010  8A 41 D1 11 F6 9B 54 44 AD 19 FB B8 0C C6 2F 34
+    0020  71 8E 4F F6 92 59 34 61 D9 4F 4A 86 36 A8 D8 9A
+    0030  C6 3C 17 7E 71 CE A8 26 D0 C5 25 61 78 9D 01 F8
+
+   The serial number is contained in tag 5F20, while the last 5 digits
+   are truncated.
+ */
+static gpg_error_t
+read_serialno(app_t app)
+{
+  gpg_error_t err;
+  unsigned char *buffer = NULL;
+  size_t buflen;
+  const unsigned char *p,*chr;
+  size_t n, objlen, hdrlen, chrlen;
+  int class, tag, constructed, ndef;
+
+  err = select_and_read_binary (app->slot, 0x2F02, "EF.C_DevAut",
+                                &buffer, &buflen, 512);
+  if (err)
+    return err;
+
+  p = buffer;
+  n = buflen;
+
+  err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > n || tag != 0x21))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if (err)
+    {
+      log_error ("error parsing C_DevAut: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  chr = find_tlv (p, objlen, 0x5F20, &chrlen);
+  if (!chr || chrlen <= 5)
+    {
+      err = gpg_error (GPG_ERR_INV_OBJ);
+      log_error ("CHR not found in CVC\n");
+      goto leave;
+    }
+  chrlen -= 5;
+
+  app->serialno = xtrymalloc (chrlen);
+  if (!app->serialno)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+
+  app->serialnolen = chrlen;
+  memcpy (app->serialno, chr, chrlen);
+
+ leave:
+  xfree (buffer);
+  return err;
+}
+
+
+/* Get all the basic information from the SmartCard-HSM, check the
+   structure and initialize our local context.  This is used once at
+   application initialization.  */
+static gpg_error_t
+read_meta (app_t app)
+{
+  gpg_error_t err;
+  unsigned char *eflist = NULL;
+  size_t eflistlen = 0;
+  int i;
+
+  err = read_serialno(app);
+  if (err)
+    return err;
+
+  err = list_ef (app->slot, &eflist, &eflistlen);
+  if (err)
+    return err;
+
+  for (i = 0; i < eflistlen; i += 2)
+    {
+      switch(eflist[i])
+        {
+        case SC_HSM_KEY_PREFIX:
+          if (eflist[i + 1] == 0)    /* No key with ID=0 */
+            break;
+          err = read_ef_prkd (app, ((SC_HSM_PRKD_PREFIX << 8) | eflist[i + 1]),
+                              &app->app_local->private_key_info,
+                              &app->app_local->certificate_info);
+          if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+            err = 0;
+          if (err)
+            return err;
+          break;
+        case SC_HSM_CD_PREFIX:
+          err = read_ef_cd (app, ((eflist[i] << 8) | eflist[i + 1]),
+                            &app->app_local->trusted_certificate_info);
+          if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+            err = 0;
+          if (err)
+            return err;
+          break;
+        }
+    }
+
+  xfree (eflist);
+
+  return err;
+}
+
+
+
+/* Helper to do_learn_status: Send information about all certificates
+   listed in CERTINFO back.  Use CERTTYPE as type of the
+   certificate. */
+static gpg_error_t
+send_certinfo (ctrl_t ctrl, const char *certtype, cdf_object_t certinfo)
+{
+  for (; certinfo; certinfo = certinfo->next)
+    {
+      char *buf, *p;
+
+      buf = xtrymalloc (4 + certinfo->objidlen*2 + 1);
+      if (!buf)
+        return gpg_error_from_syserror ();
+      p = stpcpy (buf, "HSM.");
+      bin2hex (certinfo->objid, certinfo->objidlen, p);
+
+      send_status_info (ctrl, "CERTINFO",
+                        certtype, strlen (certtype),
+                        buf, strlen (buf),
+                        NULL, (size_t)0);
+      xfree (buf);
+    }
+  return 0;
+}
+
+
+
+/* Get the keygrip of the private key object PRKDF.  On success the
+   keygrip gets returned in the caller provided 41 byte buffer
+   R_GRIPSTR. */
+static gpg_error_t
+keygripstr_from_prkdf (app_t app, prkdf_object_t prkdf, char *r_gripstr)
+{
+  gpg_error_t err;
+  cdf_object_t cdf;
+  unsigned char *der;
+  size_t derlen;
+  ksba_cert_t cert;
+
+  /* Look for a matching certificate. A certificate matches if the Id
+     matches the one of the private key info. */
+  for (cdf = app->app_local->certificate_info; cdf; cdf = cdf->next)
+    if (cdf->objidlen == prkdf->objidlen
+        && !memcmp (cdf->objid, prkdf->objid, prkdf->objidlen))
+      break;
+  if (!cdf)
+    return gpg_error (GPG_ERR_NOT_FOUND);
+
+  err = readcert_by_cdf (app, cdf, &der, &derlen);
+  if (err)
+    return err;
+
+  err = ksba_cert_new (&cert);
+  if (!err)
+    err = ksba_cert_init_from_mem (cert, der, derlen);
+  xfree (der);
+  if (!err)
+    err = app_help_get_keygrip_string (cert, r_gripstr);
+  ksba_cert_release (cert);
+
+  return err;
+}
+
+
+
+/* Helper to do_learn_status: Send information about all known
+   keypairs back. */
+static gpg_error_t
+send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
+{
+  gpg_error_t err;
+
+  for (; keyinfo; keyinfo = keyinfo->next)
+    {
+      char gripstr[40+1];
+      char *buf, *p;
+
+      buf = xtrymalloc (4 + keyinfo->objidlen*2 + 1);
+      if (!buf)
+        return gpg_error_from_syserror ();
+      p = stpcpy (buf, "HSM.");
+      bin2hex (keyinfo->objid, keyinfo->objidlen, p);
+
+      err = keygripstr_from_prkdf (app, keyinfo, gripstr);
+      if (err)
+        {
+          log_error ("can't get keygrip from %04X\n", keyinfo->key_reference);
+        }
+      else
+        {
+          assert (strlen (gripstr) == 40);
+          send_status_info (ctrl, "KEYPAIRINFO",
+                            gripstr, 40,
+                            buf, strlen (buf),
+                            NULL, (size_t)0);
+        }
+      xfree (buf);
+    }
+  return 0;
+}
+
+
+
+/* This is the handler for the LEARN command. */
+static gpg_error_t
+do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
+{
+  gpg_error_t err;
+
+  if ((flags & 1))
+    err = 0;
+  else
+    {
+      err = send_certinfo (ctrl, "100", app->app_local->certificate_info);
+      if (!err)
+        err = send_certinfo (ctrl, "101",
+            app->app_local->trusted_certificate_info);
+    }
+
+  if (!err)
+    err = send_keypairinfo (app, ctrl, app->app_local->private_key_info);
+
+  return err;
+}
+
+
+
+/* Read a certificate using the information in CDF and return the
+   certificate in a newly allocated buffer R_CERT and its length
+   R_CERTLEN. */
+static gpg_error_t
+readcert_by_cdf (app_t app, cdf_object_t cdf,
+                 unsigned char **r_cert, size_t *r_certlen)
+{
+  gpg_error_t err;
+  unsigned char *buffer = NULL;
+  const unsigned char *p, *save_p;
+  size_t buflen, n;
+  int class, tag, constructed, ndef;
+  size_t totobjlen, objlen, hdrlen;
+  int rootca;
+  int i;
+
+  *r_cert = NULL;
+  *r_certlen = 0;
+
+  /* First check whether it has been cached. */
+  if (cdf->image)
+    {
+      *r_cert = xtrymalloc (cdf->imagelen);
+      if (!*r_cert)
+        return gpg_error_from_syserror ();
+      memcpy (*r_cert, cdf->image, cdf->imagelen);
+      *r_certlen = cdf->imagelen;
+      return 0;
+    }
+
+  err = select_and_read_binary (app->slot, cdf->fid, "CD",
+                                &buffer, &buflen, 4096);
+  if (err)
+    {
+      log_error ("error reading certificate with Id ");
+      for (i=0; i < cdf->objidlen; i++)
+        log_printf ("%02X", cdf->objid[i]);
+      log_printf (": %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Check whether this is really a certificate.  */
+  p = buffer;
+  n = buflen;
+  err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (err)
+    goto leave;
+
+  if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed)
+    rootca = 0;
+  else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
+    rootca = 1;
+  else
+    {
+      err = gpg_error (GPG_ERR_INV_OBJ);
+      goto leave;
+    }
+  totobjlen = objlen + hdrlen;
+  assert (totobjlen <= buflen);
+
+  err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (err)
+    goto leave;
+
+  if (!rootca
+      && class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
+    {
+      /* The certificate seems to be contained in a userCertificate
+         container.  Skip this and assume the following sequence is
+         the certificate. */
+      if (n < objlen)
+        {
+          err = gpg_error (GPG_ERR_INV_OBJ);
+          goto leave;
+        }
+      p += objlen;
+      n -= objlen;
+      save_p = p;
+      err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+                              &ndef, &objlen, &hdrlen);
+      if (err)
+        goto leave;
+      if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
+        {
+          err = gpg_error (GPG_ERR_INV_OBJ);
+          goto leave;
+        }
+      totobjlen = objlen + hdrlen;
+      assert (save_p + totobjlen <= buffer + buflen);
+      memmove (buffer, save_p, totobjlen);
+    }
+
+  *r_cert = buffer;
+  buffer = NULL;
+  *r_certlen = totobjlen;
+
+  /* Try to cache it. */
+  if (!cdf->image && (cdf->image = xtrymalloc (*r_certlen)))
+    {
+      memcpy (cdf->image, *r_cert, *r_certlen);
+      cdf->imagelen = *r_certlen;
+    }
+
+
+ leave:
+  xfree (buffer);
+  return err;
+}
+
+
+
+/* Handler for the READCERT command.
+
+   Read the certificate with id CERTID (as returned by learn_status in
+   the CERTINFO status lines) and return it in the freshly allocated
+   buffer to be stored at R_CERT and its length at R_CERTLEN.  A error
+   code will be returned on failure and R_CERT and R_CERTLEN will be
+   set to (NULL,0). */
+static gpg_error_t
+do_readcert (app_t app, const char *certid,
+             unsigned char **r_cert, size_t *r_certlen)
+{
+  gpg_error_t err;
+  cdf_object_t cdf;
+
+  *r_cert = NULL;
+  *r_certlen = 0;
+  err = cdf_object_from_certid (app, certid, &cdf);
+  if (!err)
+    err = readcert_by_cdf (app, cdf, r_cert, r_certlen);
+  return err;
+}
+
+
+
+/* Implement the GETATTR command.  This is similar to the LEARN
+   command but returns just one value via the status interface. */
+static gpg_error_t
+do_getattr (app_t app, ctrl_t ctrl, const char *name)
+{
+  if (!strcmp (name, "$AUTHKEYID"))
+    {
+      char *buf, *p;
+      prkdf_object_t prkdf;
+
+      /* We return the ID of the first private key capable of
+         signing. */
+      for (prkdf = app->app_local->private_key_info; prkdf;
+           prkdf = prkdf->next)
+        if (prkdf->usageflags.sign)
+          break;
+      if (prkdf)
+        {
+          buf = xtrymalloc (4 + prkdf->objidlen*2 + 1);
+          if (!buf)
+            return gpg_error_from_syserror ();
+          p = stpcpy (buf, "HSM.");
+          bin2hex (prkdf->objid, prkdf->objidlen, p);
+
+          send_status_info (ctrl, name, buf, strlen (buf), NULL, 0);
+          xfree (buf);
+          return 0;
+        }
+    }
+  else if (!strcmp (name, "$DISPSERIALNO"))
+    {
+      send_status_info (ctrl, name, app->serialno, app->serialnolen, NULL, 0);
+      return 0;
+    }
+
+  return gpg_error (GPG_ERR_INV_NAME);
+}
+
+
+
+/* Apply PKCS#1 V1.5 padding for signature operation.  The function
+ * combines padding, digest info and the hash value.  The buffer must
+ * be allocated by the caller matching the key size.  */
+static void
+apply_PKCS_padding(const unsigned char *dig, int diglen,
+                   const unsigned char *prefix, int prefixlen,
+                   unsigned char *buff, int bufflen)
+{
+  int i, n_ff;
+
+  /* Caller must ensure a sufficient buffer.  */
+  if (diglen + prefixlen + 4 > bufflen)
+    return;
+  n_ff = bufflen - diglen - prefixlen - 3;
+
+  *buff++ = 0x00;
+  *buff++ = 0x01;
+  for (i=0; i < n_ff; i++)
+    *buff++ = 0xFF;
+  *buff++ = 0x00;
+
+  if (prefix)
+    memcpy (buff, prefix, prefixlen);
+  buff += prefixlen;
+  memcpy (buff, dig, diglen);
+}
+
+
+
+/* Decode a digest info structure (DI,DILEN) to extract the hash
+ * value.  The buffer HASH to receive the digest must be provided by
+ * the caller with HASHLEN pointing to the inbound length.  HASHLEN is
+ * updated to the outbound length.  */
+static int
+hash_from_digestinfo (const unsigned char *di, size_t dilen,
+                      unsigned char *hash, size_t *hashlen)
+{
+  const unsigned char *p,*pp;
+  size_t n, nn, objlen, hdrlen;
+  int class, tag, constructed, ndef;
+  gpg_error_t err;
+
+  p = di;
+  n = dilen;
+
+  err = parse_ber_header (&p, &n, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > n || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if ( err )
+    return err;
+
+  pp = p;
+  nn = objlen;
+
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn || tag != TAG_SEQUENCE))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if ( err )
+    return err;
+
+  pp += objlen;
+  nn -= objlen;
+
+  err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
+                          &ndef, &objlen, &hdrlen);
+  if (!err && (objlen > nn || tag != TAG_OCTET_STRING))
+    err = gpg_error (GPG_ERR_INV_OBJ);
+  if ( err )
+    return err;
+
+  if (*hashlen < objlen)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+  memcpy (hash, pp, objlen);
+  *hashlen = objlen;
+  return 0;
+}
+
+
+/* Perform PIN verification
+ */
+static gpg_error_t
+verify_pin (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+            void *pincb_arg)
+{
+  gpg_error_t err;
+  pininfo_t pininfo;
+  char *pinvalue;
+  char *prompt;
+  int sw;
+
+  sw = apdu_send_simple (app->slot, 0, 0x00, ISO7816_VERIFY, 0x00, 0x81,
+                         -1, NULL);
+
+  if (sw == SW_SUCCESS)
+    return 0;                   /* PIN already verified */
+
+  if (sw == SW_REF_DATA_INV)
+    {
+      log_error ("SmartCard-HSM not initialized. Run sc-hsm-tool first\n");
+      return gpg_error (GPG_ERR_NO_PIN);
+    }
+
+  if (sw == SW_CHV_BLOCKED)
+    {
+      log_error ("PIN Blocked\n");
+      return gpg_error (GPG_ERR_PIN_BLOCKED);
+    }
+
+  memset (&pininfo, 0, sizeof pininfo);
+  pininfo.fixedlen = 0;
+  pininfo.minlen = 6;
+  pininfo.maxlen = 15;
+
+  prompt = "||Please enter the PIN";
+
+  if (!opt.disable_pinpad
+      && !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) )
+    {
+      err = pincb (pincb_arg, prompt, NULL);
+      if (err)
+        {
+          log_info ("PIN callback returned error: %s\n", gpg_strerror (err));
+          return err;
+        }
+
+      err = iso7816_verify_kp (app->slot, 0x81, &pininfo);
+      pincb (pincb_arg, NULL, NULL);  /* Dismiss the prompt. */
+    }
+  else
+    {
+      err = pincb (pincb_arg, prompt, &pinvalue);
+      if (err)
+        {
+          log_info ("PIN callback returned error: %s\n", gpg_strerror (err));
+          return err;
+        }
+
+      err = iso7816_verify (app->slot, 0x81, pinvalue, strlen(pinvalue));
+      xfree (pinvalue);
+    }
+  if (err)
+    {
+      log_error ("PIN verification failed: %s\n", gpg_strerror (err));
+      return err;
+    }
+  log_debug ("PIN verification succeeded\n");
+  return err;
+}
+
+
+
+/* Handler for the PKSIGN command.
+
+   Create the signature and return the allocated result in OUTDATA.
+   If a PIN is required, the PINCB will be used to ask for the PIN;
+   that callback should return the PIN in an allocated buffer and
+   store that as the 3rd argument.
+
+   The API is somewhat inconsistent: The caller can either supply
+   a plain hash and the algorithm in hashalgo or a complete
+   DigestInfo structure. The former is detect by characteristic length
+   of the provided data (20,28,32,48 or 64 byte).
+
+   The function returns the RSA block in the size of the modulus or
+   the ECDSA signature in X9.62 format (SEQ/INT(r)/INT(s))
+*/
+static gpg_error_t
+do_sign (app_t app, const char *keyidstr, int hashalgo,
+         gpg_error_t (*pincb)(void*, const char *, char **),
+         void *pincb_arg,
+         const void *indata, size_t indatalen,
+         unsigned char **outdata, size_t *outdatalen )
+{
+  static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
+    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
+      0x02, 0x01, 0x05, 0x00, 0x04, 0x14  };
+  static unsigned char sha1_prefix[15] =   /* (1.3.14.3.2.26) */
+    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+      0x02, 0x1a, 0x05, 0x00, 0x04, 0x14  };
+  static unsigned char sha224_prefix[19] = /* (2.16.840.1.101.3.4.2.4) */
+    { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+      0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
+      0x1C  };
+  static unsigned char sha256_prefix[19] = /* (2.16.840.1.101.3.4.2.1) */
+    { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+      0x00, 0x04, 0x20  };
+  static unsigned char sha384_prefix[19] = /* (2.16.840.1.101.3.4.2.2) */
+    { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
+      0x00, 0x04, 0x30  };
+  static unsigned char sha512_prefix[19] = /* (2.16.840.1.101.3.4.2.3) */
+    { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
+      0x00, 0x04, 0x40  };
+
+  gpg_error_t err;
+  unsigned char cdsblk[256]; /* Raw PKCS#1 V1.5 block with padding
+                                (RSA) or hash.  */
+  prkdf_object_t prkdf;      /* The private key object. */
+  size_t cdsblklen;
+  unsigned char algoid;
+  int sw;
+
+  if (!keyidstr || !*keyidstr)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (indatalen > 124)          /* Limit for 1024 bit key */
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
+  if (err)
+    return err;
+  if (!(prkdf->usageflags.sign || prkdf->usageflags.sign_recover
+        ||prkdf->usageflags.non_repudiation))
+    {
+      log_error ("key %s may not be used for signing\n", keyidstr);
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
+
+  if (prkdf->keytype == KEY_TYPE_RSA)
+    {
+      algoid = 0x20;
+
+      cdsblklen = prkdf->keysize >> 3;
+      if (!cdsblklen)
+        cdsblklen = 256;
+
+      if (hashalgo == GCRY_MD_SHA1 && indatalen == 20)
+        apply_PKCS_padding (indata, indatalen,
+                            sha1_prefix, sizeof(sha1_prefix),
+                            cdsblk, cdsblklen);
+      else if (hashalgo == GCRY_MD_MD5 && indatalen == 20)
+        apply_PKCS_padding (indata, indatalen,
+                            rmd160_prefix, sizeof(rmd160_prefix),
+                            cdsblk, cdsblklen);
+      else if (hashalgo == GCRY_MD_SHA224 && indatalen == 28)
+        apply_PKCS_padding (indata, indatalen,
+                            sha224_prefix, sizeof(sha224_prefix),
+                            cdsblk, cdsblklen);
+      else if (hashalgo == GCRY_MD_SHA256 && indatalen == 32)
+        apply_PKCS_padding (indata, indatalen,
+                            sha256_prefix, sizeof(sha256_prefix),
+                            cdsblk, cdsblklen);
+      else if (hashalgo == GCRY_MD_SHA384 && indatalen == 48)
+        apply_PKCS_padding (indata, indatalen,
+                            sha384_prefix, sizeof(sha384_prefix),
+                            cdsblk, cdsblklen);
+      else if (hashalgo == GCRY_MD_SHA512 && indatalen == 64)
+        apply_PKCS_padding (indata, indatalen,
+                            sha512_prefix, sizeof(sha512_prefix),
+                            cdsblk, cdsblklen);
+      else  /* Assume it's already a digest info or TLS_MD5SHA1 */
+        apply_PKCS_padding (indata, indatalen, NULL, 0, cdsblk, cdsblklen);
+    }
+  else
+    {
+      algoid = 0x70;
+      if (indatalen != 20 && indatalen != 28 && indatalen != 32
+          && indatalen != 48 && indatalen != 64)
+        {
+          cdsblklen = sizeof(cdsblk);
+          err = hash_from_digestinfo (indata, indatalen, cdsblk, &cdsblklen);
+          if (err)
+            {
+              log_error ("DigestInfo invalid: %s\n", gpg_strerror (err));
+              return err;
+            }
+        }
+      else
+        {
+          memcpy (cdsblk, indata, indatalen);
+          cdsblklen = indatalen;
+        }
+    }
+
+  err = verify_pin (app, pincb, pincb_arg);
+  if (err)
+    return err;
+
+  sw = apdu_send_le (app->slot, 1, 0x80, 0x68, prkdf->key_reference, algoid,
+                     cdsblklen, cdsblk, 0, outdata, outdatalen);
+  return iso7816_map_sw (sw);
+}
+
+
+
+/* Handler for the PKAUTH command.
+
+   This is basically the same as the PKSIGN command but we first check
+   that the requested key is suitable for authentication; that is, it
+   must match the criteria used for the attribute $AUTHKEYID.  See
+   do_sign for calling conventions; there is no HASHALGO, though. */
+static gpg_error_t
+do_auth (app_t app, const char *keyidstr,
+         gpg_error_t (*pincb)(void*, const char *, char **),
+         void *pincb_arg,
+         const void *indata, size_t indatalen,
+         unsigned char **outdata, size_t *outdatalen )
+{
+  gpg_error_t err;
+  prkdf_object_t prkdf;
+  int algo;
+
+  if (!keyidstr || !*keyidstr)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
+  if (err)
+    return err;
+  if (!prkdf->usageflags.sign)
+    {
+      log_error ("key %s may not be used for authentication\n", keyidstr);
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
+
+  algo = indatalen == 36? MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1;
+  return do_sign (app, keyidstr, algo, pincb, pincb_arg,
+                  indata, indatalen, outdata, outdatalen);
+}
+
+
+
+/* Check PKCS#1 V1.5 padding and extract plain text.  The function
+ * allocates a buffer for the plain text.  The caller must release the
+ * buffer.  */
+static gpg_error_t
+strip_PKCS15_padding(unsigned char *src, int srclen, unsigned char **dst,
+                     size_t *dstlen)
+{
+  unsigned char *p;
+
+  if (srclen < 2)
+    return gpg_error (GPG_ERR_DECRYPT_FAILED);
+  if (*src++ != 0x00)
+    return gpg_error (GPG_ERR_DECRYPT_FAILED);
+  if (*src++ != 0x02)
+    return gpg_error (GPG_ERR_DECRYPT_FAILED);
+  srclen -= 2;
+  while ((srclen > 0) && *src)
+    {
+      src++;
+      srclen--;
+    }
+
+  if (srclen < 2)
+    return gpg_error (GPG_ERR_DECRYPT_FAILED);
+
+  src++;
+  srclen--;
+
+  p = xtrymalloc (srclen);
+  if (!p)
+    return gpg_error_from_syserror ();
+
+  memcpy (p, src, srclen);
+  *dst = p;
+  *dstlen = srclen;
+
+  return 0;
+}
+
+
+/* Decrypt a PKCS#1 V1.5 formatted cryptogram using the referenced
+   key.  */
+static gpg_error_t
+do_decipher (app_t app, const char *keyidstr,
+             gpg_error_t (*pincb)(void*, const char *, char **),
+             void *pincb_arg,
+             const void *indata, size_t indatalen,
+             unsigned char **outdata, size_t *outdatalen,
+             unsigned int *r_info)
+{
+  gpg_error_t err;
+  unsigned char p1blk[256]; /* Enciphered P1 block */
+  prkdf_object_t prkdf;     /* The private key object. */
+  unsigned char *rspdata;
+  size_t rspdatalen;
+  size_t p1blklen;
+  int sw;
+
+  if (!keyidstr || !*keyidstr || !indatalen)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
+  if (err)
+    return err;
+  if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap))
+    {
+      log_error ("key %s may not be used for deciphering\n", keyidstr);
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
+
+  if (prkdf->keytype != KEY_TYPE_RSA)
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  p1blklen = prkdf->keysize >> 3;
+  if (!p1blklen)
+    p1blklen = 256;
+
+  /* The input may be shorter (due to MPIs not storing leading zeroes)
+     or longer than the block size.  We put INDATA right aligned into
+     the buffer.  If INDATA is longer than the block size we truncate
+     it on the left. */
+  memset (p1blk, 0, sizeof(p1blk));
+  if (indatalen > p1blklen)
+    memcpy (p1blk, (unsigned char *)indata + (indatalen - p1blklen), p1blklen);
+  else
+    memcpy (p1blk + (p1blklen - indatalen), indata, indatalen);
+
+
+  err = verify_pin(app, pincb, pincb_arg);
+  if (err)
+    return err;
+
+  sw = apdu_send_le (app->slot, 1, 0x80, 0x62, prkdf->key_reference, 0x21,
+                     p1blklen, p1blk, 0, &rspdata, &rspdatalen);
+  err = iso7816_map_sw (sw);
+  if (err)
+    {
+      log_error ("Decrypt failed: %s\n", gpg_strerror (err));
+      return err;
+    }
+
+  err = strip_PKCS15_padding (rspdata, rspdatalen, outdata, outdatalen);
+  xfree (rspdata);
+
+  if (!err)
+    *r_info |= APP_DECIPHER_INFO_NOPAD;
+
+  return err;
+}
+
+
+
+/*
+ * Select the SmartCard-HSM application on the card in SLOT.
+ */
+gpg_error_t
+app_select_sc_hsm (app_t app)
+{
+  int slot = app->slot;
+  int rc;
+
+  rc = iso7816_select_application (slot, sc_hsm_aid, sizeof sc_hsm_aid, 0);
+  if (!rc)
+    {
+      app->apptype = "SC-HSM";
+
+      app->app_local = xtrycalloc (1, sizeof *app->app_local);
+      if (!app->app_local)
+        {
+          rc = gpg_error_from_syserror ();
+          goto leave;
+        }
+
+      rc = read_meta (app);
+      if (rc)
+        goto leave;
+
+      app->fnc.deinit = do_deinit;
+      app->fnc.learn_status = do_learn_status;
+      app->fnc.readcert = do_readcert;
+      app->fnc.getattr = do_getattr;
+      app->fnc.setattr = NULL;
+      app->fnc.genkey = NULL;
+      app->fnc.sign = do_sign;
+      app->fnc.auth = do_auth;
+      app->fnc.decipher = do_decipher;
+      app->fnc.change_pin = NULL;
+      app->fnc.check_pin = NULL;
+
+    leave:
+      if (rc)
+        do_deinit (app);
+   }
+
+  return rc;
+}
index 24ed5b0..1694ea1 100644 (file)
--- a/scd/app.c
+++ b/scd/app.c
@@ -22,7 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <pth.h>
+#include <npth.h>
 
 #include "scdaemon.h"
 #include "app-common.h"
@@ -37,8 +37,9 @@
 static struct
 {
   int initialized;
-  pth_mutex_t lock;
+  npth_mutex_t lock;
   app_t app;        /* Application context in use or NULL. */
+  app_t last_app;   /* Last application object used as this slot or NULL. */
 } lock_table[10];
 
 
@@ -71,29 +72,30 @@ print_progress_line (void *opaque, const char *what, int pc, int cur, int tot)
 static gpg_error_t
 lock_reader (int slot, ctrl_t ctrl)
 {
-  gpg_error_t err;
+  int res;
 
   if (slot < 0 || slot >= DIM (lock_table))
     return gpg_error (slot<0? GPG_ERR_INV_VALUE : GPG_ERR_RESOURCE_LIMIT);
 
   if (!lock_table[slot].initialized)
     {
-      if (!pth_mutex_init (&lock_table[slot].lock))
+      res = npth_mutex_init (&lock_table[slot].lock, NULL);
+      if (res)
         {
-          err = gpg_error_from_syserror ();
-          log_error ("error initializing mutex: %s\n", strerror (errno));
-          return err;
+          log_error ("error initializing mutex: %s\n", strerror (res));
+          return gpg_error_from_errno (res);
         }
       lock_table[slot].initialized = 1;
       lock_table[slot].app = NULL;
+      lock_table[slot].last_app = NULL;
     }
 
-  if (!pth_mutex_acquire (&lock_table[slot].lock, 0, NULL))
+  res = npth_mutex_lock (&lock_table[slot].lock);
+  if (res)
     {
-      err = gpg_error_from_syserror ();
       log_error ("failed to acquire APP lock for slot %d: %s\n",
-                 slot, strerror (errno));
-      return err;
+                 slot, strerror (res));
+      return gpg_error_from_errno (res);
     }
 
   apdu_set_progress_cb (slot, print_progress_line, ctrl);
@@ -105,32 +107,18 @@ lock_reader (int slot, ctrl_t ctrl)
 static void
 unlock_reader (int slot)
 {
+  int res;
+
   if (slot < 0 || slot >= DIM (lock_table)
       || !lock_table[slot].initialized)
     log_bug ("unlock_reader called for invalid slot %d\n", slot);
 
   apdu_set_progress_cb (slot, NULL, NULL);
 
-  if (!pth_mutex_release (&lock_table[slot].lock))
+  res = npth_mutex_unlock (&lock_table[slot].lock);
+  if (res)
     log_error ("failed to release APP lock for slot %d: %s\n",
-               slot, strerror (errno));
-}
-
-
-static void
-dump_mutex_state (pth_mutex_t *m)
-{
-#ifdef _W32_PTH_H
-  (void)m;
-  log_printf ("unknown under W32");
-#else
-  if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
-    log_printf ("not_initialized");
-  else if (!(m->mx_state & PTH_MUTEX_LOCKED))
-    log_printf ("not_locked");
-  else
-    log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
-#endif
+               slot, strerror (res));
 }
 
 
@@ -144,13 +132,18 @@ app_dump_state (void)
   for (slot=0; slot < DIM (lock_table); slot++)
     if (lock_table[slot].initialized)
       {
-        log_info ("app_dump_state: slot=%d lock=", slot);
-        dump_mutex_state (&lock_table[slot].lock);
+        log_info ("app_dump_state: slot=%d", slot);
         if (lock_table[slot].app)
           {
             log_printf (" app=%p", lock_table[slot].app);
             if (lock_table[slot].app->apptype)
-              log_printf (" type=`%s'", lock_table[slot].app->apptype);
+              log_printf (" type='%s'", lock_table[slot].app->apptype);
+          }
+        if (lock_table[slot].last_app)
+          {
+            log_printf (" lastapp=%p", lock_table[slot].last_app);
+            if (lock_table[slot].last_app->apptype)
+              log_printf (" type='%s'", lock_table[slot].last_app->apptype);
           }
         log_printf ("\n");
       }
@@ -174,72 +167,51 @@ is_app_allowed (const char *name)
 void
 application_notify_card_reset (int slot)
 {
+  app_t app;
+
   if (slot < 0 || slot >= DIM (lock_table))
     return;
 
   /* FIXME: We are ignoring any error value here.  */
   lock_reader (slot, NULL);
 
-  /* Release the APP, as it's not reusable any more.  */
+  /* Mark application as non-reusable.  */
   if (lock_table[slot].app)
-    {
-      if (lock_table[slot].app->ref_count)
-        log_bug ("trying to release active context\n");
+    lock_table[slot].app->no_reuse = 1;
 
-      deallocate_app (lock_table[slot].app);
-      lock_table[slot].app = NULL;
-      log_debug ("application has been released\n");
-    }
+  /* Deallocate a saved application for that slot, so that we won't
+     try to reuse it.  If there is no saved application, set a flag so
+     that we won't save the current state. */
+  app = lock_table[slot].last_app;
 
-  unlock_reader (slot);
-}
-
-
-/*
- * This function is called with lock held.
- */
-static gpg_error_t
-check_conflict (int slot, const char *name)
-{
-  app_t app = lock_table[slot].app;
-
-  if (!app || !name || (app->apptype && !ascii_strcasecmp (app->apptype, name)))
-    return 0;
-
-  if (!app->ref_count)
+  if (app)
     {
-      lock_table[slot].app = NULL;
+      lock_table[slot].last_app = NULL;
       deallocate_app (app);
-      return 0;
-    }
-  else
-    {
-      log_info ("application '%s' in use by reader %d - can't switch\n",
-                app->apptype? app->apptype : "<null>", slot);
-      return gpg_error (GPG_ERR_CONFLICT);
     }
+  unlock_reader (slot);
 }
 
+
 /* This function is used by the serialno command to check for an
    application conflict which may appear if the serialno command is
    used to request a specific application and the connection has
    already done a select_application. */
 gpg_error_t
-check_application_conflict (ctrl_t ctrl, const char *name)
+check_application_conflict (ctrl_t ctrl, int slot, const char *name)
 {
-  int slot = ctrl->reader_slot;
-  gpg_error_t err;
+  app_t app;
+
+  (void)ctrl;
 
   if (slot < 0 || slot >= DIM (lock_table))
     return gpg_error (GPG_ERR_INV_VALUE);
 
-  err = lock_reader (slot, ctrl);
-  if (err)
-    return err;
-
-  err = check_conflict (slot, name);
-  unlock_reader (slot);
-  return err;
+  app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
+  if (app && app->apptype && name)
+    if ( ascii_strcasecmp (app->apptype, name))
+      return gpg_error (GPG_ERR_CONFLICT);
+  return 0;
 }
 
 
@@ -268,14 +240,50 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
     return err;
 
   /* First check whether we already have an application to share. */
-  err = check_conflict (slot, name);
-  if (err)
+  app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
+  if (app && name)
+    if (!app->apptype || ascii_strcasecmp (app->apptype, name))
+      {
+        unlock_reader (slot);
+        if (app->apptype)
+          log_info ("application '%s' in use by reader %d - can't switch\n",
+                    app->apptype, slot);
+        return gpg_error (GPG_ERR_CONFLICT);
+      }
+
+  /* Don't use a non-reusable marked application.  */
+  if (app && app->no_reuse)
     {
       unlock_reader (slot);
-      return err;
+      log_info ("lingering application '%s' in use by reader %d"
+                " - can't switch\n",
+                app->apptype? app->apptype:"?", slot);
+      return gpg_error (GPG_ERR_CONFLICT);
     }
 
-  app = lock_table[slot].app;
+  /* If we don't have an app, check whether we have a saved
+     application for that slot.  This is useful so that a card does
+     not get reset even if only one session is using the card - this
+     way the PIN cache and other cached data are preserved.  */
+  if (!app && lock_table[slot].initialized && lock_table[slot].last_app)
+    {
+      app = lock_table[slot].last_app;
+      if (!name || (app->apptype && !ascii_strcasecmp (app->apptype, name)) )
+        {
+          /* Yes, we can reuse this application - either the caller
+             requested an unspecific one or the requested one matches
+             the saved one. */
+          lock_table[slot].app = app;
+          lock_table[slot].last_app = NULL;
+        }
+      else
+        {
+          /* No, this saved application can't be used - deallocate it. */
+          lock_table[slot].last_app = NULL;
+          deallocate_app (app);
+          app = NULL;
+        }
+    }
 
   /* If we can reuse an application, bump the reference count and
      return it.  */
@@ -379,6 +387,8 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
     err = app_select_geldkarte (app);
   if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
     err = app_select_dinsig (app);
+  if (err && is_app_allowed ("sc-hsm") && (!name || !strcmp (name, "sc-hsm")))
+    err = app_select_sc_hsm (app);
   if (err && name)
     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
 
@@ -386,7 +396,7 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
   if (err)
     {
       if (name)
-        log_info ("can't select application `%s': %s\n",
+        log_info ("can't select application '%s': %s\n",
                   name, gpg_strerror (err));
       else
         log_info ("no supported card application found: %s\n",
@@ -414,6 +424,7 @@ get_supported_applications (void)
     "p15",
     "geldkarte",
     "dinsig",
+    "sc-hsm",
     /* Note: "undefined" is not listed here because it needs special
        treatment by the client.  */
     NULL
@@ -482,10 +493,18 @@ release_application (app_t app)
       return;
     }
 
-  /* We don't deallocate app here.  Instead, we keep it.  This is
-     useful so that a card does not get reset even if only one session
-     is using the card - this way the PIN cache and other cached data
-     are preserved.  */
+  if (lock_table[slot].last_app)
+    deallocate_app (lock_table[slot].last_app);
+  if (app->no_reuse)
+    {
+      /* If we shall not re-use the application we can't save it for
+         later use. */
+      deallocate_app (app);
+      lock_table[slot].last_app = NULL;
+    }
+  else
+    lock_table[slot].last_app = lock_table[slot].app;
+  lock_table[slot].app = NULL;
   unlock_reader (slot);
 }
 
@@ -785,10 +804,13 @@ app_decipher (app_t app, const char *keyidstr,
               gpg_error_t (*pincb)(void*, const char *, char **),
               void *pincb_arg,
               const void *indata, size_t indatalen,
-              unsigned char **outdata, size_t *outdatalen )
+              unsigned char **outdata, size_t *outdatalen,
+              unsigned int *r_info)
 {
   gpg_error_t err;
 
+  *r_info = 0;
+
   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
     return gpg_error (GPG_ERR_INV_VALUE);
   if (!app->ref_count)
@@ -801,7 +823,8 @@ app_decipher (app_t app, const char *keyidstr,
   err = app->fnc.decipher (app, keyidstr,
                            pincb, pincb_arg,
                            indata, indatalen,
-                           outdata, outdatalen);
+                           outdata, outdatalen,
+                           r_info);
   unlock_reader (app->slot);
   if (opt.verbose)
     log_info ("operation decipher result: %s\n", gpg_strerror (err));
@@ -965,4 +988,3 @@ app_check_pin (app_t app, const char *keyidstr,
     log_info ("operation check_pin result: %s\n", gpg_strerror (err));
   return err;
 }
-
index f6efd8a..5b94758 100644 (file)
--- a/scd/atr.c
+++ b/scd/atr.c
@@ -1,5 +1,5 @@
 /* atr.c - ISO 7816 ATR fucntions
- *     Copyright (C) 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <string.h>
 #include <assert.h>
 
-#include "scdaemon.h"
-#include "apdu.h"
+#include <gpg-error.h>
+#include "../common/logging.h"
 #include "atr.h"
-#include "dynload.h"
 
 static int const fi_table[16] = { 0, 372, 558, 744, 1116,1488, 1860, -1,
                                   -1, 512, 768, 1024, 1536, 2048, -1, -1 };
 static int const di_table[16] = { -1, 1, 2, 4, 8, 16, -1, -1,
                                   0, -1, -2, -4, -8, -16, -32, -64};
-                                  
 
-/* Dump the ATR of the card at SLOT in a human readable format to
-   stream FP.  */
-int
-atr_dump (int slot, FILE *fp)
+
+/* Dump the ATR in (BUFFER,BUFLEN) to a human readable format and
+   return that as a malloced buffer.  The caller must release this
+   buffer using es_free!  On error this function returns NULL and sets
+   ERRNO.  */
+char *
+atr_dump (const void *buffer, size_t buflen)
 {
-  unsigned char *atrbuffer, *atr;
-  size_t atrlen;
+  const unsigned char *atr = buffer;
+  size_t atrlen = buflen;
+  estream_t fp;
   int have_ta, have_tb, have_tc, have_td;
   int n_historical;
   int idx, val;
   unsigned char chksum;
+  char *result;
+
+  fp = es_fopenmem (0, "rwb,samethread");
+  if (!fp)
+    return NULL;
 
-  atr = atrbuffer = apdu_get_atr (slot, &atrlen);
-  if (!atr)
-    return gpg_error (GPG_ERR_GENERAL);
-  
-  fprintf (fp, "Info on ATR of length %u at slot %d\n",
-           (unsigned int)atrlen, slot);
   if (!atrlen)
     {
-      fprintf (fp, "error: empty ATR\n");
+      es_fprintf (fp, "error: empty ATR\n");
       goto bailout;
     }
 
-  
+  for (idx=0; idx < atrlen ; idx++)
+    es_fprintf (fp, "%s%02X", idx?" ":"", atr[idx]);
+  es_putc ('\n', fp);
+
   if (*atr == 0x3b)
-    fputs ("direct convention\n", fp);
+    es_fputs ("Direct convention\n", fp);
   else if (*atr == 0x3f)
-    fputs ("inverse convention\n", fp);
+    es_fputs ("Inverse convention\n", fp);
   else
-    fprintf (fp,"error: invalid TS character 0x%02x\n", *atr);
+    es_fprintf (fp,"error: invalid TS character 0x%02x\n", *atr);
   if (!--atrlen)
     goto bailout;
   atr++;
@@ -79,44 +83,45 @@ atr_dump (int slot, FILE *fp)
   have_tc = !!(*atr & 0x40);
   have_td = !!(*atr & 0x80);
   n_historical = (*atr & 0x0f);
-  fprintf (fp, "%d historical characters indicated\n", n_historical);
+  es_fprintf (fp, "%d historical characters indicated\n", n_historical);
 
   if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
-    fputs ("error: ATR shorter than indicated by format character\n", fp);
+    es_fputs ("error: ATR shorter than indicated by format character\n", fp);
   if (!--atrlen)
     goto bailout;
   atr++;
 
   if (have_ta)
     {
-      fputs ("TA1: F=", fp);
+      es_fputs ("TA1: F=", fp);
       val = fi_table[(*atr >> 4) & 0x0f];
       if (!val)
-        fputs ("internal clock", fp);
+        es_fputs ("internal clock", fp);
       else if (val == -1)
-        fputs ("RFU", fp);
+        es_fputs ("RFU", fp);
       else
-        fprintf (fp, "%d", val);
-      fputs (" D=", fp);
-      val = di_table[*atr & 0x0f]; 
+        es_fprintf (fp, "%d", val);
+      es_fputs (" D=", fp);
+      val = di_table[*atr & 0x0f];
       if (!val)
-        fputs ("[impossible value]\n", fp);
+        es_fputs ("[impossible value]\n", fp);
       else if (val == -1)
-        fputs ("RFU\n", fp);
+        es_fputs ("RFU\n", fp);
       else if (val < 0 )
-        fprintf (fp, "1/%d\n", val);
-      else 
-        fprintf (fp, "%d\n", val);
-      
+        es_fprintf (fp, "1/%d\n", val);
+      else
+        es_fprintf (fp, "%d\n", val);
+
       if (!--atrlen)
         goto bailout;
       atr++;
     }
-     
+
   if (have_tb)
     {
-      fprintf (fp, "TB1: II=%d PI1=%d%s\n", (*atr >> 5) & 3, *atr & 0x1f,
-               (*atr & 0x80)? " [high bit not cleared]":"");
+      es_fprintf (fp, "TB1: II=%d PI1=%d%s\n",
+                  ((*atr >> 5) & 3), (*atr & 0x1f),
+                  (*atr & 0x80)? " [high bit not cleared]":"");
       if (!--atrlen)
         goto bailout;
       atr++;
@@ -125,9 +130,9 @@ atr_dump (int slot, FILE *fp)
   if (have_tc)
     {
       if (*atr == 255)
-        fputs ("TC1: guard time shortened to 1 etu\n", fp);
+        es_fputs ("TC1: guard time shortened to 1 etu\n", fp);
       else
-        fprintf (fp, "TC1: (extra guard time) N=%d\n", *atr);
+        es_fprintf (fp, "TC1: (extra guard time) N=%d\n", *atr);
 
       if (!--atrlen)
         goto bailout;
@@ -140,10 +145,11 @@ atr_dump (int slot, FILE *fp)
       have_tb = !!(*atr & 0x20);
       have_tc = !!(*atr & 0x40);
       have_td = !!(*atr & 0x80);
-      fprintf (fp, "TD1: protocol T%d supported\n", *atr & 0x0f);
+      es_fprintf (fp, "TD1: protocol T%d supported\n", (*atr & 0x0f));
 
       if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
-        fputs ("error: ATR shorter than indicated by format character\n", fp);
+        es_fputs ("error: ATR shorter than indicated by format character\n",
+                  fp);
 
       if (!--atrlen)
         goto bailout;
@@ -154,12 +160,12 @@ atr_dump (int slot, FILE *fp)
 
   if (have_ta)
     {
-      fprintf (fp, "TA2: (PTS) %stoggle, %splicit, T=%02X\n",
-               (*atr & 0x80)? "no-":"",
-               (*atr & 0x10)? "im": "ex",
-               (*atr & 0x0f));
+      es_fprintf (fp, "TA2: (PTS) %stoggle, %splicit, T=%02X\n",
+                  (*atr & 0x80)? "no-":"",
+                  (*atr & 0x10)? "im": "ex",
+                  (*atr & 0x0f));
       if ((*atr & 0x60))
-        fprintf (fp, "note: reserved bits are set (TA2=0x%02X)\n", *atr);
+        es_fprintf (fp, "note: reserved bits are set (TA2=0x%02X)\n", *atr);
       if (!--atrlen)
         goto bailout;
       atr++;
@@ -167,7 +173,7 @@ atr_dump (int slot, FILE *fp)
 
   if (have_tb)
     {
-      fprintf (fp, "TB2: PI2=%d\n", *atr);
+      es_fprintf (fp, "TB2: PI2=%d\n", *atr);
       if (!--atrlen)
         goto bailout;
       atr++;
@@ -175,7 +181,7 @@ atr_dump (int slot, FILE *fp)
 
   if (have_tc)
     {
-      fprintf (fp, "TC2: PWI=%d\n", *atr);
+      es_fprintf (fp, "TC2: PWI=%d\n", *atr);
       if (!--atrlen)
         goto bailout;
       atr++;
@@ -187,10 +193,11 @@ atr_dump (int slot, FILE *fp)
       have_tb = !!(*atr & 0x20);
       have_tc = !!(*atr & 0x40);
       have_td = !!(*atr & 0x80);
-      fprintf (fp, "TD2: protocol T%d supported\n", *atr & 0x0f);
+      es_fprintf (fp, "TD2: protocol T%d supported\n", *atr & 0x0f);
 
       if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
-        fputs ("error: ATR shorter than indicated by format character\n", fp);
+        es_fputs ("error: ATR shorter than indicated by format character\n",
+                  fp);
 
       if (!--atrlen)
         goto bailout;
@@ -203,7 +210,7 @@ atr_dump (int slot, FILE *fp)
     {
       if (have_ta)
         {
-          fprintf (fp, "TA%d: IFSC=%d\n", idx, *atr);
+          es_fprintf (fp, "TA%d: IFSC=%d\n", idx, *atr);
           if (!--atrlen)
             goto bailout;
           atr++;
@@ -211,7 +218,7 @@ atr_dump (int slot, FILE *fp)
 
       if (have_tb)
         {
-          fprintf (fp, "TB%d: BWI=%d CWI=%d\n",
+          es_fprintf (fp, "TB%d: BWI=%d CWI=%d\n",
                    idx, (*atr >> 4) & 0x0f, *atr & 0x0f);
           if (!--atrlen)
             goto bailout;
@@ -220,7 +227,7 @@ atr_dump (int slot, FILE *fp)
 
       if (have_tc)
         {
-          fprintf (fp, "TC%d: 0x%02X\n", idx, *atr);
+          es_fprintf (fp, "TC%d: 0x%02X\n", idx, *atr);
           if (!--atrlen)
             goto bailout;
           atr++;
@@ -232,11 +239,12 @@ atr_dump (int slot, FILE *fp)
           have_tb = !!(*atr & 0x20);
           have_tc = !!(*atr & 0x40);
           have_td = !!(*atr & 0x80);
-          fprintf (fp, "TD%d: protocol T%d supported\n", idx, *atr & 0x0f);
+          es_fprintf (fp, "TD%d: protocol T%d supported\n", idx, *atr & 0x0f);
 
           if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
-            fputs ("error: ATR shorter than indicated by format character\n",
-                   fp);
+            es_fputs ("error: "
+                      "ATR shorter than indicated by format character\n",
+                      fp);
 
           if (!--atrlen)
             goto bailout;
@@ -247,151 +255,36 @@ atr_dump (int slot, FILE *fp)
     }
 
   if (n_historical + 1 > atrlen)
-    fputs ("error: ATR shorter than required for historical bytes "
-           "and checksum\n", fp);
-  
+    es_fputs ("error: ATR shorter than required for historical bytes "
+              "and checksum\n", fp);
+
   if (n_historical)
     {
-      fputs ("Historical:", fp);
+      es_fputs ("HCH:", fp);
       for (; n_historical && atrlen ; n_historical--, atrlen--, atr++)
-        fprintf (fp, " %02X", *atr);
-      putchar ('\n');
+        es_fprintf (fp, " %02X", *atr);
+      es_putc ('\n', fp);
     }
 
   if (!atrlen)
-    fputs ("error: checksum missing\n", fp);
+    es_fputs ("error: checksum missing\n", fp);
   else if (*atr == chksum)
-    fprintf (fp, "TCK: %02X (good)\n", *atr);
+    es_fprintf (fp, "TCK: %02X (good)\n", *atr);
   else
-    fprintf (fp, "TCK: %02X (bad; calculated %02X)\n", *atr, chksum);
+    es_fprintf (fp, "TCK: %02X (bad; computed %02X)\n", *atr, chksum);
 
   atrlen--;
   if (atrlen)
-    fprintf (fp, "error: %u bytes garbage at end of ATR\n",
-             (unsigned int)atrlen );
+    es_fprintf (fp, "error: %u bytes garbage at end of ATR\n",
+                (unsigned int)atrlen );
 
  bailout:
-  xfree (atrbuffer);
-
-  return 0;
-}
-
-
-/* Note: This code has not yet been tested!  It shall return -1 on
-   error or the number of historical bytes and store them at
-   HISTORICAL.  */
-int
-atr_get_historical (int slot, unsigned char historical[])
-{
-  int result = -1;
-  unsigned char *atrbuffer = NULL;
-  unsigned char *atr;
-  size_t atrlen;
-  int have_ta, have_tb, have_tc, have_td;
-  int n_historical;
-  int idx;
-  unsigned char chksum;
-
-  atr = atrbuffer = apdu_get_atr (slot, &atrlen);
-  if (!atr || atrlen < 2)
-    goto leave;
-  atrlen--;
-  atr++;
-
-  chksum = *atr;
-  for (idx=1; idx < atrlen-1; idx++)
-    chksum ^= atr[idx];
-
-  have_ta = !!(*atr & 0x10);
-  have_tb = !!(*atr & 0x20);
-  have_tc = !!(*atr & 0x40);
-  have_td = !!(*atr & 0x80);
-  n_historical = (*atr & 0x0f);
-
-  if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen)
-    goto leave; /* ATR shorter than indicated by format character.  */
-  atrlen--;
-  atr++;
-
-  if (have_ta + have_tb + have_tc >= atrlen)
-    goto leave;
-  atrlen -= have_ta + have_tb + have_tc;
-  atr    += have_ta + have_tb + have_tc;
-
-  if (have_td)
+  es_putc ('\0', fp); /* We want a string.  */
+  if (es_fclose_snatch (fp, (void**)&result, NULL))
     {
-      have_ta = !!(*atr & 0x10);
-      have_tb = !!(*atr & 0x20);
-      have_tc = !!(*atr & 0x40);
-      have_td = !!(*atr & 0x80);
-      if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen)
-        goto leave; /* ATR shorter than indicated by format character.  */
-      atrlen--;
-      atr++;
-    }
-  else
-    have_ta = have_tb = have_tc = have_td = 0;
-
-  if (have_ta + have_tb + have_tc >= atrlen)
-    goto leave;
-  atrlen -= have_ta + have_tb + have_tc;
-  atr    += have_ta + have_tb + have_tc;
-
-  if (have_td)
-    {
-      have_ta = !!(*atr & 0x10);
-      have_tb = !!(*atr & 0x20);
-      have_tc = !!(*atr & 0x40);
-      have_td = !!(*atr & 0x80);
-      if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen)
-        goto leave; /* ATR shorter than indicated by format character.  */
-      atrlen--;
-      atr++;
-    }
-  else
-    have_ta = have_tb = have_tc = have_td = 0;
-
-  for (idx = 3; have_ta || have_tb || have_tc || have_td; idx++)
-    {
-      if (have_ta + have_tb + have_tc >= atrlen)
-        goto leave;
-      atrlen -= have_ta + have_tb + have_tc;
-      atr    += have_ta + have_tb + have_tc;
-
-      if (have_td)
-        {
-          have_ta = !!(*atr & 0x10);
-          have_tb = !!(*atr & 0x20);
-          have_tc = !!(*atr & 0x40);
-          have_td = !!(*atr & 0x80);
-          if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen)
-            goto leave; /* ATR shorter than indicated by format character.  */
-          atrlen--;
-          atr++;
-        }
-      else
-        have_ta = have_tb = have_tc = have_td = 0;
+      log_error ("oops: es_fclose_snatch failed: %s\n", strerror (errno));
+      return NULL;
     }
 
-  if (n_historical >= atrlen)
-    goto leave; /* ATR shorter than required for historical bytes. */
-  
-  if (n_historical)
-    {
-      for (idx=0; n_historical && atrlen; n_historical--, atrlen--, atr++)
-        historical[idx] = *atr;
-    }
-
-  if (!atrlen || *atr != chksum)
-    goto leave;
-
-  /* Don't care about garbage at the end of the ATR.  */
-
-  result = n_historical;
-
- leave:
-  xfree (atrbuffer);
-
   return result;
 }
-
index 5f07522..b06a83a 100644 (file)
--- a/scd/atr.h
+++ b/scd/atr.h
@@ -20,7 +20,7 @@
 #ifndef ATR_H
 #define ATR_H
 
-int atr_dump (int slot, FILE *fp);
+char *atr_dump (const void *buffer, size_t buflen);
 
 
 
index 78f2f60..640cec7 100644 (file)
@@ -54,7 +54,7 @@ struct card_ctx_s {
                      const void *indata, size_t indatalen,
                      unsigned char **outdata, size_t *outdatalen);
   } fnc;
-  
+
 };
 
 /*-- card.c --*/
index 0cbcd31..5be0061 100644 (file)
@@ -21,7 +21,7 @@
    used with an interface specification described in DIN V 66291-1.
    The AID to be used is: 'D27600006601'.
 
-   The file IDs for certificates utilize the generic format: 
+   The file IDs for certificates utilize the generic format:
         Cxyz
     C being the hex digit 'C' (12).
     x being the service indicator:
          '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
          'E'        := C.RCA (self certified certificate of the Root-CA).
          'F'        := reserved.
-   
+
    The file IDs used by default are:
    '1F00'  EF.SSD (security service descriptor). [o,o]
    '2F02'  EF.GDO (global data objects) [m,m]
    'A000'  EF.PROT (signature log).  Cyclic file with 20 records of 53 byte.
            Read and update after user authentication. [o,o]
-   'B000'  EF.PK.RCA.DS (public keys of Root-CA).  Size is 512b or size 
+   'B000'  EF.PK.RCA.DS (public keys of Root-CA).  Size is 512b or size
            of keys. [m (unless a 'C00E' is present),m]
    'B001'  EF.PK.CA.DS (public keys of CAs).  Size is 512b or size
            of keys. [o,o]
            with n := 0 .. 7.  Size is 2k or size of cert.  Read and
            update allowed after user authentication. [m,m]
    'C00m'  EF.C.CA.DS (digital signature certificate of CA)
-           with m := 8 .. E.  Size is 1k or size of cert.  Read always 
+           with m := 8 .. E.  Size is 1k or size of cert.  Read always
            allowed, update after uder authentication. [o,o]
    'C100'  EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
    'C108'  EF.C.CA.AUT (AUT certificate of CA) [o,m]
    'D000'  EF.DM (display message) [-,m]
-   
+
    The letters in brackets indicate optional or mandatory files: The
    first for card terminals under full control and the second for
    "business" card terminals.
@@ -118,7 +118,7 @@ dinsig_enum_keypairs (CARD card, int idx,
       return rc;
     }
 
-  rc = ksba_cert_init_from_mem (cert, buf, buflen); 
+  rc = ksba_cert_init_from_mem (cert, buf, buflen);
   xfree (buf);
   if (rc)
     {
@@ -132,7 +132,7 @@ dinsig_enum_keypairs (CARD card, int idx,
       log_error ("failed to calculate the keygrip at index %d\n", idx);
       ksba_cert_release (cert);
       return gpg_error (GPG_ERR_CARD);
-    }      
+    }
   ksba_cert_release (cert);
 
   /* return the iD */
@@ -146,7 +146,7 @@ dinsig_enum_keypairs (CARD card, int idx,
       else
         strcpy (*keyid, "DINSIG-DF01.C200");
     }
-  
+
   return 0;
 }
 
@@ -171,7 +171,7 @@ dinsig_read_cert (CARD card, const char *certidstr,
     return gpg_error (GPG_ERR_INV_ID);
 
   rc = sc_select_file (card->scard, &path, &file);
-  if (rc) 
+  if (rc)
     {
       log_error ("sc_select_file failed: %s\n", sc_strerror (rc));
       return map_sc_err (rc);
@@ -184,7 +184,7 @@ dinsig_read_cert (CARD card, const char *certidstr,
       return gpg_error (GPG_ERR_CARD);
     }
   if (file->size < 20) /* check against a somewhat arbitrary length */
-    { 
+    {
       log_error ("certificate EF too short\n");
       sc_file_free (file);
       return gpg_error (GPG_ERR_CARD);
@@ -196,7 +196,7 @@ dinsig_read_cert (CARD card, const char *certidstr,
       sc_file_free (file);
       return tmperr;
     }
-      
+
   rc = sc_read_binary (card->scard, 0, buf, file->size, 0);
   if (rc >= 0 && rc != file->size)
     {
@@ -206,7 +206,7 @@ dinsig_read_cert (CARD card, const char *certidstr,
       return gpg_error (GPG_ERR_CARD);
     }
   sc_file_free (file);
-  if (rc < 0) 
+  if (rc < 0)
     {
       log_error ("error reading certificate EF: %s\n", sc_strerror (rc));
       xfree (buf);
@@ -236,7 +236,7 @@ dinsig_read_cert (CARD card, const char *certidstr,
         }
       memmove (buf, buf+9, buflen-9);
       buflen -= 9;
-    } 
+    }
 
   *cert = buf;
   *ncert = buflen;
index 34a88f7..4af4472 100644 (file)
@@ -41,7 +41,7 @@ struct p15private_s {
 
 
 /* Allocate private data. */
-static int 
+static int
 init_private_data (CARD card)
 {
   struct p15private_s *priv;
@@ -62,10 +62,10 @@ init_private_data (CARD card)
      numer of objects and used this to figure out what the last object
      enumerated is.  We now do an enum_objects just once and keep it
      in the private data. */
-  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, 
+  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA,
                               priv->prkey_rsa_objs,
                               DIM (priv->prkey_rsa_objs));
-  if (rc < 0) 
+  if (rc < 0)
     {
       log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
       xfree (priv);
@@ -74,10 +74,10 @@ init_private_data (CARD card)
   priv->n_prkey_rsa_objs = rc;
 
   /* Read all certificate objects. */
-  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509, 
+  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509,
                               priv->cert_objs,
                               DIM (priv->cert_objs));
-  if (rc < 0) 
+  if (rc < 0)
     {
       log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
       xfree (priv);
@@ -117,7 +117,7 @@ p15_enum_keypairs (CARD card, int idx,
   ksba_cert_t cert;
 
   rc = init_private_data (card);
-  if (rc) 
+  if (rc)
       return rc;
   priv = card->p15priv;
   nobjs = priv->n_prkey_rsa_objs;
@@ -125,7 +125,7 @@ p15_enum_keypairs (CARD card, int idx,
   if (idx >= nobjs)
     return -1;
   pinfo = priv->prkey_rsa_objs[idx]->data;
-  
+
   /* now we need to read the certificate so that we can calculate the
      keygrip */
   rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
@@ -166,7 +166,7 @@ p15_enum_keypairs (CARD card, int idx,
       log_error ("failed to calculate the keygrip of private key %d\n", idx);
       ksba_cert_release (cert);
       return gpg_error (GPG_ERR_CARD);
-    }      
+    }
   ksba_cert_release (cert);
 
   rc = 0;
@@ -181,7 +181,7 @@ p15_enum_keypairs (CARD card, int idx,
       p = stpcpy (p, "P15-5015.");
       bin2hex (pinfo->id.value, pinfo->id.len, p);
     }
-  
+
   return rc;
 }
 
@@ -196,7 +196,7 @@ p15_enum_certs (CARD card, int idx, char **certid, int *type)
   int nobjs;
 
   rc = init_private_data (card);
-  if (rc) 
+  if (rc)
       return rc;
   priv = card->p15priv;
   nobjs = priv->n_cert_objs;
@@ -205,7 +205,7 @@ p15_enum_certs (CARD card, int idx, char **certid, int *type)
     return -1;
   obj =  priv->cert_objs[idx];
   cinfo = obj->data;
-  
+
   if (certid)
     {
       char *p;
@@ -227,10 +227,10 @@ p15_enum_certs (CARD card, int idx, char **certid, int *type)
         *type = 101;
       else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
         *type = 102;
-      else 
+      else
         *type = 0; /* error -> unknown */
     }
-  
+
   return rc;
 }
 
@@ -243,7 +243,7 @@ idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
   int n;
 
   /* For now we only support the standard DF */
-  if (strncmp (idstr, "P15-5015.", 9) ) 
+  if (strncmp (idstr, "P15-5015.", 9) )
     return gpg_error (GPG_ERR_INV_ID);
   for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
     ;
@@ -282,7 +282,7 @@ p15_read_cert (CARD card, const char *certidstr,
   rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
   if (rc)
     {
-      log_info ("certificate '%s' not found: %s\n", 
+      log_info ("certificate '%s' not found: %s\n",
                 certidstr, sc_strerror (rc));
       return -1;
     }
@@ -344,7 +344,7 @@ p15_prepare_key (CARD card, const char *keyidstr,
   pin = pinobj->data;
 
   /* Fixme: pack this into a verification loop */
-  /* Fixme: we might want to pass pin->min_length and 
+  /* Fixme: we might want to pass pin->min_length and
      pin->stored_length */
   rc = pincb (pincb_arg, pinobj->label, &pinvalue);
   if (rc)
@@ -369,7 +369,7 @@ p15_prepare_key (CARD card, const char *keyidstr,
 
 
 /* See card.c for interface description */
-static int 
+static int
 p15_sign (CARD card, const char *keyidstr, int hashalgo,
           int (pincb)(void*, const char *, char **),
           void *pincb_arg,
@@ -391,11 +391,11 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
 
   cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
 
-  outbuflen = 1024; 
+  outbuflen = 1024;
   outbuf = xtrymalloc (outbuflen);
   if (!outbuf)
     return gpg_error (gpg_err_code_from_errno (errno));
-  
+
   rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
                                     cryptflags,
                                     indata, indatalen,
@@ -419,7 +419,7 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
 
 
 /* See card.c for description */
-static int 
+static int
 p15_decipher (CARD card, const char *keyidstr,
               int (pincb)(void*, const char *, char **),
               void *pincb_arg,
@@ -453,15 +453,15 @@ p15_decipher (CARD card, const char *keyidstr,
         }
     }
 
-  outbuflen = indatalen < 256? 256 : indatalen; 
+  outbuflen = indatalen < 256? 256 : indatalen;
   outbuf = xtrymalloc (outbuflen);
   if (!outbuf)
     return gpg_error (gpg_err_code_from_errno (errno));
 
-  rc = sc_pkcs15_decipher (card->p15card, keyobj, 
+  rc = sc_pkcs15_decipher (card->p15card, keyobj,
                            0,
-                           indata, indatalen, 
-                           outbuf, outbuflen); 
+                           indata, indatalen,
+                           outbuf, outbuflen);
   if (rc < 0)
     {
       log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
index a021348..a582c50 100644 (file)
@@ -66,7 +66,7 @@ card_help_get_keygrip (ksba_cert_t cert, unsigned char *array)
   int rc;
   ksba_sexp_t p;
   size_t n;
-  
+
   p = ksba_cert_get_public_key (cert);
   if (!p)
     return -1; /* oops */
@@ -109,7 +109,7 @@ card_open (CARD *rcard)
   if (!card)
     return gpg_error (gpg_err_code_from_errno (errno));
   card->reader = 0;
-  
+
   rc = sc_establish_context (&card->ctx, "scdaemon");
   if (rc)
     {
@@ -142,7 +142,7 @@ card_open (CARD *rcard)
       goto leave;
     }
   if (opt.verbose)
-    log_info ("connected to card in reader %d using driver `%s'\n",
+    log_info ("connected to card in reader %d using driver '%s'\n",
               card->reader, card->scard->driver->name);
 
   rc = sc_lock (card->scard);
@@ -154,7 +154,7 @@ card_open (CARD *rcard)
       goto leave;
     }
 
-    
+
  leave:
   if (rc)
     card_close (card);
@@ -195,7 +195,7 @@ card_close (CARD card)
         }
 #endif
       xfree (card);
-    }      
+    }
 }
 
 /* Locate a simple TLV encoded data object in BUFFER of LENGTH and
@@ -210,7 +210,7 @@ find_simple_tlv (const unsigned char *buffer, size_t length,
   const char *s = buffer;
   size_t n = length;
   size_t len;
-    
+
   for (;;)
     {
       buffer = s;
@@ -290,7 +290,7 @@ find_iccsn (const unsigned char *buffer, size_t length, char **serial)
    returned if this value is not availbale.  For non-PKCS-15 cards a
    serial number is constructed by other means. Caller must free
    SERIAL unless the function returns an error. */
-int 
+int
 card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
 {
 #ifdef HAVE_OPENSC
@@ -311,7 +311,7 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
   if (!card->fnc.initialized)
     {
       card->fnc.initialized = 1;
-      /* The first use of this card tries to figure out the type of the card 
+      /* The first use of this card tries to figure out the type of the card
          and sets up the function pointers. */
       rc = sc_pkcs15_bind (card->scard, &card->p15card);
       if (rc)
@@ -326,7 +326,7 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
         card_p15_bind (card);
       card->fnc.initialized = 1;
     }
-      
+
 
   /* We should lookup the iso 7812-1 and 8583-3 - argh ISO
      practice is suppressing innovation - IETF rules!  So we
@@ -355,10 +355,10 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
       return gpg_error (GPG_ERR_CARD);
     }
   buflen = file->size;
-      
+
   rc = sc_read_binary (card->scard, 0, buf, buflen, 0);
   sc_file_free (file);
-  if (rc < 0) 
+  if (rc < 0)
     {
       log_error ("error reading GDO file: %s\n", sc_strerror (rc));
       return gpg_error (GPG_ERR_CARD);
@@ -381,7 +381,7 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
 
       if (!efser)
         efser = "";
-        
+
       xfree (*serial);
       *serial = NULL;
       p = xtrymalloc (strlen (efser) + 7);
@@ -515,7 +515,7 @@ card_read_cert (CARD card, const char *certidstr,
 /* Create the signature and return the allocated result in OUTDATA.
    If a PIN is required the PINCB will be used to ask for the PIN; it
    should return the PIN in an allocated buffer and put it into PIN.  */
-int 
+int
 card_sign (CARD card, const char *keyidstr, int hashalgo,
            int (pincb)(void*, const char *, char **),
            void *pincb_arg,
@@ -543,7 +543,7 @@ card_sign (CARD card, const char *keyidstr, int hashalgo,
 /* Create the signature and return the allocated result in OUTDATA.
    If a PIN is required the PINCB will be used to ask for the PIN; it
    should return the PIN in an allocated buffer and put it into PIN.  */
-int 
+int
 card_decipher (CARD card, const char *keyidstr,
                int (pincb)(void*, const char *, char **),
                void *pincb_arg,
@@ -566,4 +566,3 @@ card_decipher (CARD card, const char *keyidstr,
     log_info ("card operation decipher result: %s\n", gpg_strerror (rc));
   return rc;
 }
-
index 07e884c..7a91e09 100644 (file)
@@ -40,7 +40,7 @@
  *    products derived from this software without specific prior
  *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
@@ -51,8 +51,6 @@
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Date$
  */
 
 
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <time.h>
-#ifdef HAVE_PTH
-# include <pth.h>
-#endif /*HAVE_PTH*/
+#ifdef HAVE_NPTH
+# include <npth.h>
+#endif /*HAVE_NPTH*/
 
 #include <usb.h>
 
 #include "scdaemon.h"
 #include "iso7816.h"
+#define CCID_DRIVER_INCLUDE_USB_IDS 1
 #include "ccid-driver.h"
-#include "../include/host2net.h"
 
 #define DRVNAME "ccid-driver: "
 
-/* Max length of buffer with out CCID message header of 10-byte
-   Sending: 547 for RSA-4096 key import
-        APDU size = 540 (24+4+256+256)
-        commnd + lc + le = 4 + 3 + 0
-   Sending: write data object of cardholder certificate
-        APDU size = 2048
-        commnd + lc + le = 4 + 3 + 0
-   Receiving: 2048 for cardholder certificate
-*/
-#define CCID_MAX_BUF (2048+7+10)
-
-/* CCID command timeout.  OpenPGPcard v2.1 requires timeout of 13 seconds.  */
-#define CCID_CMD_TIMEOUT (13*1000)
 
 /* Depending on how this source is used we either define our error
    output to go to stderr or to the jnlib based logging functions.  We
@@ -219,32 +204,6 @@ enum {
 #define CCID_ERROR_CODE(buf)     (((unsigned char *)(buf))[8])
 
 
-/* We need to know the vendor to do some hacks. */
-enum {
-  VENDOR_CHERRY = 0x046a,
-  VENDOR_SCM    = 0x04e6,
-  VENDOR_OMNIKEY= 0x076b,
-  VENDOR_GEMPC  = 0x08e6,
-  VENDOR_VEGA   = 0x0982,
-  VENDOR_REINER = 0x0c4b,
-  VENDOR_KAAN   = 0x0d46,
-  VENDOR_VASCO  = 0x1a44,
-  VENDOR_FSIJ   = 0x234b,
-};
-
-/* Some product ids.  */
-#define SCM_SCR331      0xe001
-#define SCM_SCR331DI    0x5111
-#define SCM_SCR335      0x5115
-#define SCM_SCR3320     0x5117
-#define SCM_SPR532      0xe003
-#define CHERRY_ST2000   0x003e
-#define VASCO_920       0x0920
-#define GEMPC_PINPAD    0x3478
-#define GEMPC_CT30      0x3437
-#define VEGA_ALPHA      0x0008
-#define CYBERJACK_GO    0x0504
-
 /* A list and a table with special transport descriptions. */
 enum {
   TRANSPORT_USB    = 0, /* Standard USB transport. */
@@ -283,7 +242,7 @@ struct ccid_driver_s
   unsigned char t1_nr;
   unsigned char nonnull_nad;
   int max_ifsd;
-  int max_ccid_msglen;
+  int ifsd;
   int ifsc;
   unsigned char apdu_level:2;     /* Reader supports short APDU level
                                      exchange.  With a value of 2 short
@@ -331,7 +290,7 @@ static int send_escape_cmd (ccid_driver_t handle, const unsigned char *data,
 static unsigned int
 convert_le_u32 (const unsigned char *buf)
 {
-  return buf[0] | (buf[1] << 8) | (buf[2] << 16) | ((unsigned int)buf[3] << 24);
+  return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
 }
 
 
@@ -356,18 +315,8 @@ set_msg_len (unsigned char *msg, unsigned int length)
 static void
 my_sleep (int seconds)
 {
-#ifdef HAVE_PTH
-  /* With Pth we also call the standard sleep(0) so that the process
-     may give up its timeslot.  */
-  if (!seconds)
-    {
-# ifdef HAVE_W32_SYSTEM
-      Sleep (0);
-# else
-      sleep (0);
-# endif
-    }
-  pth_sleep (seconds);
+#ifdef USE_NPTH
+  npth_sleep (seconds);
 #else
 # ifdef HAVE_W32_SYSTEM
   Sleep (seconds*1000);
@@ -762,7 +711,7 @@ prepare_special_transport (ccid_driver_t handle)
   handle->nonnull_nad = 0;
   handle->auto_ifsd = 0;
   handle->max_ifsd = 32;
-  handle->max_ccid_msglen = CCID_MAX_BUF;
+  handle->ifsd = 0;
   handle->has_pinpad = 0;
   handle->apdu_level = 0;
   switch (handle->id_product)
@@ -794,6 +743,7 @@ parse_ccid_descriptor (ccid_driver_t handle,
   handle->nonnull_nad = 0;
   handle->auto_ifsd = 0;
   handle->max_ifsd = 32;
+  handle->ifsd = 0;
   handle->has_pinpad = 0;
   handle->apdu_level = 0;
   handle->auto_voltage = 0;
@@ -934,7 +884,6 @@ parse_ccid_descriptor (ccid_driver_t handle,
 
   us = convert_le_u32(buf+44);
   DEBUGOUT_1 ("  dwMaxCCIDMsgLen     %5u\n", us);
-  handle->max_ccid_msglen = us;
 
   DEBUGOUT (  "  bClassGetResponse    ");
   if (buf[48] == 0xff)
@@ -969,12 +918,13 @@ parse_ccid_descriptor (ccid_driver_t handle,
 
   DEBUGOUT_1 ("  bMaxCCIDBusySlots   %5u\n", buf[53]);
 
-  if (buf[0] > 54) {
-    DEBUGOUT ("  junk             ");
-    for (i=54; i < buf[0]-54; i++)
-      DEBUGOUT_CONT_1 (" %02X", buf[i]);
-    DEBUGOUT_LF ();
-  }
+  if (buf[0] > 54)
+    {
+      DEBUGOUT ("  junk             ");
+      for (i=54; i < buf[0]-54; i++)
+        DEBUGOUT_CONT_1 (" %02X", buf[i]);
+      DEBUGOUT_LF ();
+    }
 
   if (!have_t1 || !(have_tpdu  || handle->apdu_level))
     {
@@ -1013,7 +963,7 @@ parse_ccid_descriptor (ccid_driver_t handle,
       handle->max_ifsd = 48;
     }
 
-  if (handle->id_vendor == VENDOR_GEMPC)
+  if (handle->id_vendor == VENDOR_GEMPC && handle->id_product == GEMPC_CT30)
     {
       DEBUGOUT ("enabling product quirk: disable non-null NAD\n");
       handle->nonnull_nad = 0;
@@ -1444,7 +1394,7 @@ scan_or_find_devices (int readerno, const char *readerid,
         }
       else if (fd == -1)
         {
-          DEBUGOUT_2 ("failed to open `%s': %s\n",
+          DEBUGOUT_2 ("failed to open '%s': %s\n",
                      transports[i].name, strerror (errno));
           continue;
         }
@@ -1744,6 +1694,79 @@ do_close_reader (ccid_driver_t handle)
 }
 
 
+/* Reset a reader on HANDLE.  This is useful in case a reader has been
+   plugged of and inserted at a different port.  By resetting the
+   handle, the same reader will be get used.  Note, that on error the
+   handle won't get released.
+
+   This does not return an ATR, so ccid_get_atr should be called right
+   after this one.
+*/
+int
+ccid_shutdown_reader (ccid_driver_t handle)
+{
+  int rc = 0;
+  struct usb_device *dev = NULL;
+  usb_dev_handle *idev = NULL;
+  unsigned char *ifcdesc_extra = NULL;
+  size_t ifcdesc_extra_len;
+  int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr;
+
+  if (!handle || !handle->rid)
+    return CCID_DRIVER_ERR_INV_VALUE;
+
+  do_close_reader (handle);
+
+  if (scan_or_find_devices (-1, handle->rid, NULL, &dev,
+                            &ifcdesc_extra, &ifcdesc_extra_len,
+                            &ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr,
+                            &idev, NULL) || !idev)
+    {
+      DEBUGOUT_1 ("no CCID reader with ID %s\n", handle->rid);
+      return CCID_DRIVER_ERR_NO_READER;
+    }
+
+  if (idev)
+    {
+      handle->idev = idev;
+      handle->ifc_no = ifc_no;
+      handle->ep_bulk_out = ep_bulk_out;
+      handle->ep_bulk_in = ep_bulk_in;
+      handle->ep_intr = ep_intr;
+
+      if (parse_ccid_descriptor (handle, ifcdesc_extra, ifcdesc_extra_len))
+        {
+          DEBUGOUT ("device not supported\n");
+          rc = CCID_DRIVER_ERR_NO_READER;
+          goto leave;
+        }
+
+      rc = usb_claim_interface (idev, ifc_no);
+      if (rc)
+        {
+          DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
+          rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
+          goto leave;
+        }
+    }
+
+ leave:
+  free (ifcdesc_extra);
+  if (rc)
+    {
+      if (handle->idev)
+        usb_close (handle->idev);
+      handle->idev = NULL;
+      if (handle->dev_fd != -1)
+        close (handle->dev_fd);
+      handle->dev_fd = -1;
+    }
+
+  return rc;
+
+}
+
+
 int
 ccid_set_progress_cb (ccid_driver_t handle,
                       void (*cb)(void *, const char *, int, int, int),
@@ -1805,11 +1828,6 @@ writen (int fd, const void *buf, size_t nbytes)
   return 0;
 }
 
-#if defined(ENXIO) && !defined(LIBUSB_PATH_MAX) && defined(__GNU_LIBRARY__)
-#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENXIO       /* libusb-compat */
-#elif defined(ENODEV)
-#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENODEV      /* Original libusb */
-#endif
 
 /* Write a MSG of length MSGLEN to the designated bulk out endpoint.
    Returns 0 on success. */
@@ -1884,26 +1902,26 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen,
                            5000 /* ms timeout */);
       if (rc == msglen)
         return 0;
-#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE
-      if (rc == -(LIBUSB_ERRNO_NO_SUCH_DEVICE))
+#ifdef ENODEV
+      if (rc == -(ENODEV))
         {
           /* The Linux libusb returns a negative error value.  Catch
              the most important one.  */
-          errno = LIBUSB_ERRNO_NO_SUCH_DEVICE;
+          errno = ENODEV;
           rc = -1;
         }
-#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/
+#endif /*ENODEV*/
 
       if (rc == -1)
         {
           DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno));
-#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE
-          if (errno == LIBUSB_ERRNO_NO_SUCH_DEVICE)
+#ifdef ENODEV
+          if (errno == ENODEV)
             {
               handle->enodev_seen = 1;
               return CCID_DRIVER_ERR_NO_READER;
             }
-#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/
+#endif /*ENODEV*/
         }
       else
         DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc);
@@ -2212,8 +2230,8 @@ send_escape_cmd (ccid_driver_t handle,
             {
               memcpy (result, msg, msglen);
               *resultlen = msglen;
-              rc = 0;
             }
+          rc = 0;
         }
         break;
       default:
@@ -2628,7 +2646,7 @@ ccid_get_atr (ccid_driver_t handle,
 
       if (msglen != 10 + 4)
         {
-          DEBUGOUT_1 ("Setting PPS failed: %d\n", (int)msglen);
+          DEBUGOUT_1 ("Setting PPS failed: %zu\n", msglen);
           return CCID_DRIVER_ERR_CARD_IO_ERROR;
         }
 
@@ -2776,101 +2794,109 @@ is_exlen_apdu (const unsigned char *apdu, size_t apdulen)
 /* Helper for ccid_transceive used for APDU level exchanges.  */
 static int
 ccid_transceive_apdu_level (ccid_driver_t handle,
-                            const unsigned char *apdu_buf, size_t apdu_len,
+                            const unsigned char *apdu_buf, size_t apdu_buflen,
                             unsigned char *resp, size_t maxresplen,
                             size_t *nresp)
 {
   int rc;
-  unsigned char msg[CCID_MAX_BUF];
-  const unsigned char *apdu_p;
-  size_t apdu_part_len;
+  unsigned char send_buffer[10+261+300], recv_buffer[10+261+300];
+  const unsigned char *apdu;
+  size_t apdulen;
+  unsigned char *msg;
   size_t msglen;
   unsigned char seqno;
   int bwi = 4;
-  unsigned char chain = 0;
-
-  if (apdu_len == 0 || apdu_len > sizeof (msg) - 10)
-    return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
-
-  apdu_p = apdu_buf;
-  while (1)
-    {
-      apdu_part_len = apdu_len;
-      if (apdu_part_len > handle->max_ccid_msglen - 10)
-        {
-          apdu_part_len = handle->max_ccid_msglen - 10;
-          chain |= 0x01;
-        }
 
-      msg[0] = PC_to_RDR_XfrBlock;
-      msg[5] = 0; /* slot */
-      msg[6] = seqno = handle->seqno++;
-      msg[7] = bwi;
-      msg[8] = chain;
-      msg[9] = 0;
-      memcpy (msg+10, apdu_p, apdu_part_len);
-      set_msg_len (msg, apdu_part_len);
-      msglen = 10 + apdu_part_len;
+  msg = send_buffer;
 
-      rc = bulk_out (handle, msg, msglen, 0);
-      if (rc)
-        return rc;
+  apdu = apdu_buf;
+  apdulen = apdu_buflen;
+  assert (apdulen);
 
-      apdu_p += apdu_part_len;
-      apdu_len -= apdu_part_len;
+  /* The maximum length for a short APDU T=1 block is 261.  For an
+     extended APDU T=1 block the maximum length 65544; however
+     extended APDU exchange level is not fully supported yet.  */
+  if (apdulen > sizeof (send_buffer) - 10)
+    return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
 
-      rc = bulk_in (handle, msg, sizeof msg, &msglen,
-                    RDR_to_PC_DataBlock, seqno, CCID_CMD_TIMEOUT, 0);
-      if (rc)
-        return rc;
+  msg[0] = PC_to_RDR_XfrBlock;
+  msg[5] = 0; /* slot */
+  msg[6] = seqno = handle->seqno++;
+  msg[7] = bwi; /* bBWI */
+  msg[8] = 0; /* RFU */
+  msg[9] = 0; /* RFU */
+  memcpy (msg+10, apdu, apdulen);
+  set_msg_len (msg, apdulen);
+  msglen = 10 + apdulen;
 
-      if (!(chain & 0x01))
-        break;
+  rc = bulk_out (handle, msg, msglen, 0);
+  if (rc)
+    return rc;
 
-      chain = 0x02;
-    }
+  msg = recv_buffer;
+  rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen,
+                RDR_to_PC_DataBlock, seqno, 5000, 0);
+  if (rc)
+    return rc;
 
-  apdu_len = 0;
-  while (1)
+  if (msg[9] == 1)
     {
-      apdu_part_len = msglen - 10;
-      if (resp && apdu_len + apdu_part_len <= maxresplen)
-        memcpy (resp + apdu_len, msg+10, apdu_part_len);
-      apdu_len += apdu_part_len;
+      size_t total_msglen = msglen;
 
-      if (!(msg[9] & 0x01))
-        break;
+      while (1)
+        {
+          unsigned char status;
 
-      msg[0] = PC_to_RDR_XfrBlock;
-      msg[5] = 0; /* slot */
-      msg[6] = seqno = handle->seqno++;
-      msg[7] = bwi;
-      msg[8] = 0x10;                /* Request next data block */
-      msg[9] = 0;
-      set_msg_len (msg, 0);
-      msglen = 10;
+          msg = recv_buffer + total_msglen;
 
-      rc = bulk_out (handle, msg, msglen, 0);
-      if (rc)
-        return rc;
+          msg[0] = PC_to_RDR_XfrBlock;
+          msg[5] = 0; /* slot */
+          msg[6] = seqno = handle->seqno++;
+          msg[7] = bwi; /* bBWI */
+          msg[8] = 0x10;                /* Request next data block */
+          msg[9] = 0;
+          set_msg_len (msg, 0);
+          msglen = 10;
+
+          rc = bulk_out (handle, msg, msglen, 0);
+          if (rc)
+            return rc;
+
+          rc = bulk_in (handle, msg, sizeof recv_buffer - total_msglen, &msglen,
+                        RDR_to_PC_DataBlock, seqno, 5000, 0);
+          if (rc)
+            return rc;
+          status = msg[9];
+          memmove (msg, msg+10, msglen - 10);
+          total_msglen += msglen - 10;
+          if (total_msglen >= sizeof recv_buffer)
+            return CCID_DRIVER_ERR_OUT_OF_CORE;
+
+          if (status == 0x02)
+            break;
+        }
 
-      rc = bulk_in (handle, msg, sizeof msg, &msglen,
-                    RDR_to_PC_DataBlock, seqno, CCID_CMD_TIMEOUT, 0);
-      if (rc)
-        return rc;
+      apdu = recv_buffer + 10;
+      apdulen = total_msglen - 10;
+    }
+  else
+    {
+      apdu = msg + 10;
+      apdulen = msglen - 10;
     }
 
   if (resp)
     {
-      if (apdu_len > maxresplen)
+      if (apdulen > maxresplen)
         {
           DEBUGOUT_2 ("provided buffer too short for received data "
                       "(%u/%u)\n",
-                      (unsigned int)apdu_len, (unsigned int)maxresplen);
+                      (unsigned int)apdulen, (unsigned int)maxresplen);
           return CCID_DRIVER_ERR_INV_VALUE;
         }
 
-      *nresp = apdu_len;
+      memcpy (resp, apdu, apdulen);
+      *nresp = apdulen;
     }
 
   return 0;
@@ -3064,7 +3090,7 @@ ccid_transceive (ccid_driver_t handle,
       msg = recv_buffer;
       rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen,
                     via_escape? RDR_to_PC_Escape : RDR_to_PC_DataBlock,
-                    seqno, CCID_CMD_TIMEOUT, 0);
+                    seqno, 5000, 0);
       if (rc)
         return rc;
 
@@ -3290,7 +3316,6 @@ ccid_transceive_secure (ccid_driver_t handle,
   size_t dummy_nresp;
   int testmode;
   int cherry_mode = 0;
-  int add_zero = 0;
   int enable_varlen = 0;
 
   testmode = !resp && !nresp;
@@ -3327,12 +3352,12 @@ ccid_transceive_secure (ccid_driver_t handle,
       pininfo->maxlen = 25;
       enable_varlen = 1;
       break;
-    case VENDOR_REINER: /* Tested with cyberJack go */
+    case VENDOR_REINER:/* Tested with cyberJack go */
     case VENDOR_VASCO: /* Tested with DIGIPASS 920 */
       enable_varlen = 1;
       break;
     case VENDOR_CHERRY:
-      pininfo->maxlen = 15;
+      pininfo->maxlen = 25;
       enable_varlen = 1;
       /* The CHERRY XX44 keyboard echos an asterisk for each entered
          character on the keyboard channel.  We use a special variant
@@ -3341,7 +3366,6 @@ ccid_transceive_secure (ccid_driver_t handle,
          Lc byte to the APDU.  It seems that it will be replaced with
          the actual length instead of being appended before the APDU
          is send to the card. */
-      add_zero = 1;
       if (handle->id_product != CHERRY_ST2000)
         cherry_mode = 1;
       break;
@@ -3464,7 +3488,7 @@ ccid_transceive_secure (ccid_driver_t handle,
   msg[msglen++] = apdu_buf[1]; /* INS */
   msg[msglen++] = apdu_buf[2]; /* P1 */
   msg[msglen++] = apdu_buf[3]; /* P2 */
-  if (add_zero)
+  if (cherry_mode)
     msg[msglen++] = 0;
   else if (pininfo->fixedlen != 0)
     {
index 2af1a18..e62ad5c 100644 (file)
@@ -38,7 +38,7 @@
  *    products derived from this software without specific prior
  *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 #ifndef CCID_DRIVER_H
 #define CCID_DRIVER_H
 
+
+#ifdef CCID_DRIVER_INCLUDE_USB_IDS
+/* We need to know the vendor to do some hacks. */
+enum {
+  VENDOR_CHERRY = 0x046a,
+  VENDOR_SCM    = 0x04e6,
+  VENDOR_OMNIKEY= 0x076b,
+  VENDOR_GEMPC  = 0x08e6,
+  VENDOR_VEGA   = 0x0982,
+  VENDOR_REINER = 0x0c4b,
+  VENDOR_KAAN   = 0x0d46,
+  VENDOR_FSIJ   = 0x234b,
+  VENDOR_VASCO  = 0x1a44
+};
+
+
+/* Some product ids.  */
+#define SCM_SCR331      0xe001
+#define SCM_SCR331DI    0x5111
+#define SCM_SCR335      0x5115
+#define SCM_SCR3320     0x5117
+#define SCM_SPR532      0xe003    /* Also used succeeding model SPR332. */
+#define CHERRY_ST2000   0x003e
+#define VASCO_920       0x0920
+#define GEMPC_PINPAD    0x3478
+#define GEMPC_CT30      0x3437
+#define VEGA_ALPHA      0x0008
+#define CYBERJACK_GO    0x0504
+
+#endif /*CCID_DRIVER_INCLUDE_USB_IDS*/
+
+
 /* The CID driver returns the same error codes as the status words
    used by GnuPG's apdu.h.  For ease of maintenance they should always
    match.  */
-#define CCID_DRIVER_ERR_OUT_OF_CORE    0x10001 
+#define CCID_DRIVER_ERR_OUT_OF_CORE    0x10001
 #define CCID_DRIVER_ERR_INV_VALUE      0x10002
 #define CCID_DRIVER_ERR_INCOMPLETE_CARD_RESPONSE = 0x10003
 #define CCID_DRIVER_ERR_NO_DRIVER      0x10004
@@ -80,7 +112,7 @@ typedef struct ccid_driver_s *ccid_driver_t;
 int ccid_set_debug_level (int level);
 char *ccid_get_reader_list (void);
 int ccid_open_reader (ccid_driver_t *handle, const char *readerid);
-int ccid_set_progress_cb (ccid_driver_t handle, 
+int ccid_set_progress_cb (ccid_driver_t handle,
                           void (*cb)(void *, const char *, int, int, int),
                           void *cb_arg);
 int ccid_shutdown_reader (ccid_driver_t handle);
@@ -103,6 +135,3 @@ int ccid_transceive_escape (ccid_driver_t handle,
 
 
 #endif /*CCID_DRIVER_H*/
-
-
-
index 2c43a3a..dd4191f 100644 (file)
@@ -1,6 +1,6 @@
 /* command.c - SCdaemon command handler
  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- *               2007, 2008, 2009  Free Software Foundation, Inc.
+ *               2007, 2008, 2009, 2011  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -26,8 +26,8 @@
 #include <ctype.h>
 #include <unistd.h>
 #include <signal.h>
-#ifdef USE_GNU_PTH
-# include <pth.h>
+#ifdef USE_NPTH
+# include <npth.h>
 #endif
 
 #include "scdaemon.h"
 #include "app-common.h"
 #include "iso7816.h"
 #include "apdu.h" /* Required for apdu_*_reader (). */
+#include "atr.h"
 #include "exechelp.h"
 #ifdef HAVE_LIBUSB
 #include "ccid-driver.h"
 #endif
+#include "asshelp.h"
 
 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
 #define MAXLEN_PIN 100
               || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED  \
               || gpg_err_code (_r) == GPG_ERR_CARD_RESET    \
               || gpg_err_code (_r) == GPG_ERR_ENODEV )      \
-            update_card_removed ((c)->reader_slot, 1);      \
+            update_card_removed ((c)->server_local->vreader_idx, 1);      \
        } while (0)
 
-#define IS_LOCKED(c)                                                     \
-     (locked_session && locked_session != (c)->server_local              \
-      && (c)->reader_slot != -1 && locked_session->ctrl_backlink         \
-      && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
+#define IS_LOCKED(c)                                                    \
+  (locked_session                                                       \
+   && locked_session != (c)->server_local                               \
+   && (c)->server_local->vreader_idx != -1                              \
+   && locked_session->ctrl_backlink                                     \
+   && ((c)->server_local->vreader_idx                                   \
+       == locked_session->ctrl_backlink->server_local->vreader_idx))
 
 
-/* This structure is used to keep track of open readers (slots). */
-struct slot_status_s
+/* This structure is used to keep track of user readers.  To
+   eventually accommodate this structure for RFID cards, where more
+   than one card is used per reader, we name it virtual reader.  */
+struct vreader_s
 {
   int valid;  /* True if the other objects are valid. */
-  int slot;   /* Slot number of the reader or -1 if not open. */
+  int slot;   /* APDU slot number of the reader or -1 if not open. */
 
   int reset_failed; /* A reset failed. */
 
   int any;    /* Flag indicating whether any status check has been
                  done.  This is set once to indicate that the status
                  tracking for the slot has been initialized.  */
-  unsigned int status;  /* Last status of the slot. */
-  unsigned int changed; /* Last change counter of the slot. */
+  unsigned int status;  /* Last status of the reader. */
+  unsigned int changed; /* Last change counter of the reader. */
 };
 
 
@@ -114,10 +121,17 @@ struct server_local_s
   int event_signal;             /* Or 0 if not used. */
 #endif
 
+  /* Index into the vreader table (command.c) or -1 if not open. */
+  int vreader_idx;
+
   /* True if the card has been removed and a reset is required to
      continue operation. */
   int card_removed;
 
+  /* Flag indicating that the application context needs to be released
+     at the next opportunity.  */
+  int app_ctx_marked_for_release;
+
   /* A disconnect command has been sent.  */
   int disconnect_allowed;
 
@@ -128,10 +142,8 @@ struct server_local_s
 };
 
 
-/* The table with information on all used slots.  FIXME: This is a
-   different slot number than the one used by the APDU layer, and
-   should be renamed.  */
-static struct slot_status_s slot_table[10];
+/* The table with information on all used virtual readers.  */
+static struct vreader_s vreader_table[10];
 
 
 /* To keep track of all running sessions, we link all active server
@@ -144,7 +156,7 @@ static struct server_local_s *locked_session;
 
 /* While doing a reset we need to make sure that the ticker does not
    call scd_update_reader_status_file while we are using it. */
-static pth_mutex_t status_file_update_lock;
+static npth_mutex_t status_file_update_lock;
 
 \f
 /*-- Local prototypes --*/
@@ -161,53 +173,52 @@ void
 initialize_module_command (void)
 {
   static int initialized;
+  int err;
 
   if (!initialized)
     {
-      if (pth_mutex_init (&status_file_update_lock))
+      err = npth_mutex_init (&status_file_update_lock, NULL);
+      if (!err)
         initialized = 1;
     }
 }
 
 
-/* Update the CARD_REMOVED element of all sessions using the reader
-   given by SLOT to VALUE.  */
+/* Helper to return the slot number for a given virtual reader index
+   VRDR.  In case on an error -1 is returned.  */
+static int
+vreader_slot (int vrdr)
+{
+  if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
+    return -1;
+  if (!vreader_table [vrdr].valid)
+    return -1;
+  return vreader_table[vrdr].slot;
+}
+
+
+/* Update the CARD_REMOVED element of all sessions using the virtual
+   reader given by VRDR to VALUE.  */
 static void
-update_card_removed (int slot, int value)
+update_card_removed (int vrdr, int value)
 {
   struct server_local_s *sl;
 
-  if (slot == -1)
+  if (vrdr == -1)
     return;
 
   for (sl=session_list; sl; sl = sl->next_session)
-    {
-      ctrl_t ctrl = sl->ctrl_backlink;
-
-      if (ctrl && ctrl->reader_slot == slot)
-        {
-          sl->card_removed = value;
-          if (value)
-            {
-              struct app_ctx_s *app = ctrl->app_ctx;
-              ctrl->app_ctx = NULL;
-              release_application (app);
-            }
-        }
-    }
-
+    if (sl->ctrl_backlink
+        && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
+      {
+        sl->card_removed = value;
+      }
   /* Let the card application layer know about the removal.  */
   if (value)
-    {
-      log_debug ("Removal of a card: %d\n", slot);
-      apdu_close_reader (slot);
-      application_notify_card_reset (slot);
-      slot_table[slot].slot = -1;
-    }
+    application_notify_card_reset (vreader_slot (vrdr));
 }
 
 
-
 /* Check whether the option NAME appears in LINE.  Returns 1 or 0. */
 static int
 has_option (const char *line, const char *name)
@@ -293,57 +304,51 @@ hex_to_buffer (const char *string, size_t *r_length)
 static void
 do_reset (ctrl_t ctrl, int send_reset)
 {
-  int slot = ctrl->reader_slot;
-  struct app_ctx_s *app = ctrl->app_ctx;
+  int vrdr = ctrl->server_local->vreader_idx;
+  int slot;
+  int err;
 
-  if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
+  if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
     BUG ();
 
-  /* If there is an active application, release it. */
-  if (app)
+  /* If there is an active application, release it.  Tell all other
+     sessions using the same application to release the
+     application.  */
+  if (ctrl->app_ctx)
     {
+      release_application (ctrl->app_ctx);
       ctrl->app_ctx = NULL;
-      release_application (app);
-    }
-
-  /* Release the same application which is used by other sessions.  */
-  if (send_reset)
-    {
-      struct server_local_s *sl;
-
-      for (sl=session_list; sl; sl = sl->next_session)
+      if (send_reset)
         {
-          ctrl_t c = sl->ctrl_backlink;
+          struct server_local_s *sl;
 
-          if (c && c != ctrl && c->reader_slot == slot)
-            {
-              struct app_ctx_s *app0 = c->app_ctx;
-              if (app0)
-                {
-                  c->app_ctx = NULL;
-                  release_application (app0);
-                }
-            }
+          for (sl=session_list; sl; sl = sl->next_session)
+            if (sl->ctrl_backlink
+                && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
+              {
+                sl->app_ctx_marked_for_release = 1;
+              }
         }
     }
 
   /* If we want a real reset for the card, send the reset APDU and
      tell the application layer about it.  */
+  slot = vreader_slot (vrdr);
   if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
     {
       application_notify_card_reset (slot);
       switch (apdu_reset (slot))
-       {
-       case 0:
-         break;
-       case SW_HOST_NO_CARD:
-       case SW_HOST_CARD_INACTIVE:
-         break;
-       default:
+        {
+        case 0:
+          break;
+        case SW_HOST_NO_CARD:
+        case SW_HOST_CARD_INACTIVE:
+          break;
+        default:
          apdu_close_reader (slot);
-         slot_table[slot].slot = -1;
-         break;
-       }
+          vreader_table[vrdr].slot = slot = -1;
+          break;
+        }
     }
 
   /* If we hold a lock, unlock now. */
@@ -356,21 +361,24 @@ do_reset (ctrl_t ctrl, int send_reset)
   /* Reset the card removed flag for the current reader.  We need to
      take the lock here so that the ticker thread won't concurrently
      try to update the file.  Calling update_reader_status_file is
-     required to get hold of the new status of the card in the slot
+     required to get hold of the new status of the card in the vreader
      table.  */
-  if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL))
+  err = npth_mutex_lock (&status_file_update_lock);
+  if (err)
     {
-      log_error ("failed to acquire status_fle_update lock\n");
-      ctrl->reader_slot = -1;
+      log_error ("failed to acquire status_file_update lock\n");
+      ctrl->server_local->vreader_idx = -1;
       return;
     }
   update_reader_status_file (0);  /* Update slot status table.  */
-  update_card_removed (slot, 0);  /* Clear card_removed flag.  */
-  if (!pth_mutex_release (&status_file_update_lock))
-    log_error ("failed to release status_file_update lock\n");
+  update_card_removed (vrdr, 0);  /* Clear card_removed flag.  */
+  err = npth_mutex_unlock (&status_file_update_lock);
+  if (err)
+    log_error ("failed to release status_file_update lock: %s\n",
+              strerror (err));
 
   /* Do this last, so that the update_card_removed above does its job.  */
-  ctrl->reader_slot = -1;
+  ctrl->server_local->vreader_idx = -1;
 }
 
 \f
@@ -410,40 +418,41 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
 }
 
 
-/* Return the slot of the current reader or open the reader if no
-   other sessions are using a reader.  Note, that we currently support
+/* Return the index of the current reader or open the reader if no
+   other sessions are using that reader.  If it is not possible to
+   open the reader -1 is returned.  Note, that we currently support
    only one reader but most of the code (except for this function)
    should be able to cope with several readers.  */
 static int
-get_reader_slot (void)
+get_current_reader (void)
 {
-  struct slot_status_s *ss;
+  struct vreader_s *vr;
 
-  ss = &slot_table[0]; /* One reader for now. */
+  /* We only support one reader for now.  */
+  vr = &vreader_table[0];
 
-  /* Initialize the item if needed. */
-  if (!ss->valid)
+  /* Initialize the vreader item if not yet done. */
+  if (!vr->valid)
     {
-      ss->slot = -1;
-      ss->valid = 1;
+      vr->slot = -1;
+      vr->valid = 1;
     }
 
   /* Try to open the reader. */
-  if (ss->slot == -1)
+  if (vr->slot == -1)
     {
-      ss->slot = apdu_open_reader (opt.reader_port);
+      vr->slot = apdu_open_reader (opt.reader_port);
 
       /* If we still don't have a slot, we have no readers.
         Invalidate for now until a reader is attached. */
-      if(ss->slot == -1)
+      if (vr->slot == -1)
        {
-         ss->valid = 0;
-         return -1;
+         vr->valid = 0;
        }
     }
 
-  /* Return the slot_table index.  */
-  return 0;
+  /* Return the vreader index or -1.  */
+  return vr->valid ? 0 : -1;
 }
 
 
@@ -452,7 +461,7 @@ static gpg_error_t
 open_card (ctrl_t ctrl, const char *apptype)
 {
   gpg_error_t err;
-  int slot;
+  int vrdr;
 
   /* If we ever got a card not present error code, return that.  Only
      the SERIALNO command and a reset are able to clear from that
@@ -463,25 +472,39 @@ open_card (ctrl_t ctrl, const char *apptype)
   if ( IS_LOCKED (ctrl) )
     return gpg_error (GPG_ERR_LOCKED);
 
+  /* If the application has been marked for release do it now.  We
+     can't do it immediately in do_reset because the application may
+     still be in use.  */
+  if (ctrl->server_local->app_ctx_marked_for_release)
+    {
+      ctrl->server_local->app_ctx_marked_for_release = 0;
+      release_application (ctrl->app_ctx);
+      ctrl->app_ctx = NULL;
+    }
+
   /* If we are already initialized for one specific application we
      need to check that the client didn't requested a specific
      application different from the one in use before we continue. */
   if (ctrl->app_ctx)
-    return check_application_conflict (ctrl, apptype);
+    {
+      return check_application_conflict
+        (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype);
+    }
 
-  /* Setup the slot and select the application.  */
-  if (ctrl->reader_slot != -1)
-    slot = ctrl->reader_slot;
+  /* Setup the vreader and select the application.  */
+  if (ctrl->server_local->vreader_idx != -1)
+    vrdr = ctrl->server_local->vreader_idx;
   else
-    slot = get_reader_slot ();
-  ctrl->reader_slot = slot;
-  if (slot == -1)
+    vrdr = get_current_reader ();
+  ctrl->server_local->vreader_idx = vrdr;
+  if (vrdr == -1)
     err = gpg_error (GPG_ERR_CARD);
   else
     {
       /* Fixme: We should move the apdu_connect call to
          select_application.  */
       int sw;
+      int slot = vreader_slot (vrdr);
 
       ctrl->server_local->disconnect_allowed = 0;
       sw = apdu_connect (slot);
@@ -492,8 +515,8 @@ open_card (ctrl_t ctrl, const char *apptype)
           else if (sw == SW_HOST_CARD_INACTIVE)
             err = gpg_error (GPG_ERR_CARD_RESET);
           else
-            err = gpg_error (GPG_ERR_ENODEV);
-        }
+            err = gpg_error (GPG_ERR_CARD);
+       }
       else
         err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
     }
@@ -527,7 +550,6 @@ cmd_serialno (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc = 0;
-  char *serial_and_stamp;
   char *serial;
   time_t stamp;
   int retries = 0;
@@ -553,15 +575,10 @@ cmd_serialno (assuan_context_t ctx, char *line)
   if (rc)
     return rc;
 
-  rc = estream_asprintf (&serial_and_stamp, "%s %lu",
-                         serial, (unsigned long)stamp);
+  rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
+                            serial, (unsigned long)stamp);
   xfree (serial);
-  if (rc < 0)
-    return out_of_core ();
-  rc = 0;
-  assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
-  xfree (serial_and_stamp);
-  return 0;
+  return rc;
 }
 
 
@@ -650,32 +667,32 @@ cmd_learn (assuan_context_t ctx, char *line)
      knows about this card */
   if (!only_keypairinfo)
     {
-      char *serial_and_stamp;
       char *serial;
       time_t stamp;
 
       rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
       if (rc)
         return rc;
-      rc = estream_asprintf (&serial_and_stamp, "%s %lu",
-                             serial, (unsigned long)stamp);
-      xfree (serial);
+
+      rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
+                                serial, (unsigned long)stamp);
       if (rc < 0)
-        return out_of_core ();
-      rc = 0;
-      assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
+        {
+          xfree (serial);
+          return out_of_core ();
+        }
 
       if (!has_option (line, "--force"))
         {
           char *command;
 
-          rc = estream_asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
+          rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu",
+                               serial, (unsigned long)stamp);
           if (rc < 0)
             {
-              xfree (serial_and_stamp);
+              xfree (serial);
               return out_of_core ();
             }
-          rc = 0;
           rc = assuan_inquire (ctx, command, NULL, NULL, 0);
           xfree (command);
           if (rc)
@@ -683,12 +700,12 @@ cmd_learn (assuan_context_t ctx, char *line)
               if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
                 log_error ("inquire KNOWNCARDP failed: %s\n",
                            gpg_strerror (rc));
-              xfree (serial_and_stamp);
+              xfree (serial);
               return rc;
             }
           /* Not canceled, so we have to proceeed.  */
         }
-      xfree (serial_and_stamp);
+      xfree (serial);
     }
 
   /* Let the application print out its collection of useful status
@@ -787,8 +804,10 @@ cmd_readkey (assuan_context_t ctx, char *line)
 
   rc = ksba_cert_new (&kc);
   if (rc)
-    goto leave;
-
+    {
+      xfree (cert);
+      goto leave;
+    }
   rc = ksba_cert_init_from_mem (kc, cert, ncert);
   if (rc)
     {
@@ -857,7 +876,7 @@ cmd_setdata (assuan_context_t ctx, char *line)
       buf = xtrymalloc (ctrl->in_data.valuelen + n);
     }
   else
-  buf = xtrymalloc (n);
+    buf = xtrymalloc (n);
   if (!buf)
     return out_of_core ();
 
@@ -871,8 +890,9 @@ cmd_setdata (assuan_context_t ctx, char *line)
   for (p=line, i=0; i < n; p += 2, i++)
     buf[off+i] = xtoi_2 (p);
 
+  xfree (ctrl->in_data.value);
   ctrl->in_data.value = buf;
-  ctrl->in_data.valuelen = off + n;
+  ctrl->in_data.valuelen = off+n;
   return 0;
 }
 
@@ -895,7 +915,7 @@ pin_cb (void *opaque, const char *info, char **retstr)
       if (info)
         {
           log_debug ("prompting for pinpad entry '%s'\n", info);
-          rc = estream_asprintf (&command, "POPUPPINPADPROMPT %s", info);
+          rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
           if (rc < 0)
             return gpg_error (gpg_err_code_from_errno (errno));
           rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
@@ -915,7 +935,7 @@ pin_cb (void *opaque, const char *info, char **retstr)
   *retstr = NULL;
   log_debug ("asking for PIN '%s'\n", info);
 
-  rc = estream_asprintf (&command, "NEEDPIN %s", info);
+  rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
   if (rc < 0)
     return gpg_error (gpg_err_code_from_errno (errno));
 
@@ -1069,6 +1089,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
   unsigned char *outdata;
   size_t outdatalen;
   char *keyidstr;
+  unsigned int infoflags;
 
   if ( IS_LOCKED (ctrl) )
     return gpg_error (GPG_ERR_LOCKED);
@@ -1083,7 +1104,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
                      keyidstr,
                      pin_cb, ctx,
                      ctrl->in_data.value, ctrl->in_data.valuelen,
-                     &outdata, &outdatalen);
+                     &outdata, &outdatalen, &infoflags);
 
   xfree (keyidstr);
   if (rc)
@@ -1092,6 +1113,13 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
     }
   else
     {
+      /* If the card driver told us that there is no padding, send a
+         status line.  If there is a padding it is assumed that the
+         caller knows what padding is used.  It would have been better
+         to always send that information but for backward
+         compatibility we can't do that.  */
+      if ((infoflags & APP_DECIPHER_INFO_NOPAD))
+        send_status_direct (ctrl, "PADDING", "0");
       rc = assuan_send_data (ctx, outdata, outdatalen);
       xfree (outdata);
       if (rc)
@@ -1589,18 +1617,18 @@ cmd_lock (assuan_context_t ctx, char *line)
   else
     locked_session = ctrl->server_local;
 
-#ifdef USE_GNU_PTH
+#ifdef USE_NPTH
   if (rc && has_option (line, "--wait"))
     {
       rc = 0;
-      pth_sleep (1); /* Better implement an event mechanism. However,
-                        for card operations this should be
-                        sufficient. */
+      npth_sleep (1); /* Better implement an event mechanism. However,
+                        for card operations this should be
+                        sufficient. */
       /* FIXME: Need to check that the connection is still alive.
          This can be done by issuing status messages. */
       goto retry;
     }
-#endif /*USE_GNU_PTH*/
+#endif /*USE_NPTH*/
 
   if (rc)
     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
@@ -1647,8 +1675,8 @@ static const char hlp_getinfo[] =
   "\n"
   "socket_name - Return the name of the socket.\n"
   "\n"
-  "status - Return the status of the current slot (in the future, may\n"
-  "also return the status of all slots).  The status is a list of\n"
+  "status - Return the status of the current reader (in the future, may\n"
+  "also return the status of all readers).  The status is a list of\n"
   "one-character flags.  The following flags are currently defined:\n"
   "  'u'  Usable card present.  This is the normal state during operation.\n"
   "  'r'  Card removed.  A reset is necessary.\n"
@@ -1692,19 +1720,18 @@ cmd_getinfo (assuan_context_t ctx, char *line)
   else if (!strcmp (line, "status"))
     {
       ctrl_t ctrl = assuan_get_pointer (ctx);
-      int slot = ctrl->reader_slot;
+      int vrdr = ctrl->server_local->vreader_idx;
       char flag = 'r';
 
-      if (!ctrl->server_local->card_removed && slot != -1)
+      if (!ctrl->server_local->card_removed && vrdr != -1)
        {
-         struct slot_status_s *ss;
+         struct vreader_s *vr;
 
-         if (!(slot >= 0 && slot < DIM(slot_table)))
+         if (!(vrdr >= 0 && vrdr < DIM(vreader_table)))
            BUG ();
 
-         ss = &slot_table[slot];
-
-         if (ss->valid && ss->any && (ss->status & 1))
+         vr = &vreader_table[vrdr];
+         if (vr->valid && vr->any && (vr->status & 1))
            flag = 'u';
        }
       rc = assuan_send_data (ctx, &flag, 1);
@@ -1754,14 +1781,13 @@ static gpg_error_t
 cmd_restart (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
-  struct app_ctx_s *app = ctrl->app_ctx;
 
   (void)line;
 
-  if (app)
+  if (ctrl->app_ctx)
     {
+      release_application (ctrl->app_ctx);
       ctrl->app_ctx = NULL;
-      release_application (app);
     }
   if (locked_session && ctrl->server_local == locked_session)
     {
@@ -1791,7 +1817,7 @@ cmd_disconnect (assuan_context_t ctx, char *line)
 
 
 static const char hlp_apdu[] =
-  "APDU [--atr] [--more] [--exlen[=N]] [hexstring]\n"
+  "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
   "\n"
   "Send an APDU to the current reader.  This command bypasses the high\n"
   "level functions and sends the data directly to the card.  HEXSTRING\n"
@@ -1820,8 +1846,12 @@ cmd_apdu (assuan_context_t ctx, char *line)
   int handle_more;
   const char *s;
   size_t exlen;
+  int slot;
 
-  with_atr = has_option (line, "--atr");
+  if (has_option (line, "--dump-atr"))
+    with_atr = 2;
+  else
+    with_atr = has_option (line, "--atr");
   handle_more = has_option (line, "--more");
 
   if ((s=has_option_name (line, "--exlen")))
@@ -1842,21 +1872,46 @@ cmd_apdu (assuan_context_t ctx, char *line)
   if ((rc = open_card (ctrl, NULL)))
     return rc;
 
+  slot = vreader_slot (ctrl->server_local->vreader_idx);
+
   if (with_atr)
     {
       unsigned char *atr;
       size_t atrlen;
       char hexbuf[400];
 
-      atr = apdu_get_atr (ctrl->reader_slot, &atrlen);
+      atr = apdu_get_atr (slot, &atrlen);
       if (!atr || atrlen > sizeof hexbuf - 2 )
         {
           rc = gpg_error (GPG_ERR_INV_CARD);
           goto leave;
         }
-      bin2hex (atr, atrlen, hexbuf);
+      if (with_atr == 2)
+        {
+          char *string, *p, *pend;
+
+          string = atr_dump (atr, atrlen);
+          if (string)
+            {
+              for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
+                {
+                  rc = assuan_send_data (ctx, p, pend - p + 1);
+                  if (!rc)
+                    rc = assuan_send_data (ctx, NULL, 0);
+                }
+              if (!rc && *p)
+                rc = assuan_send_data (ctx, p, strlen (p));
+              es_free (string);
+              if (rc)
+                goto leave;
+            }
+        }
+      else
+        {
+          bin2hex (atr, atrlen, hexbuf);
+          send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
+        }
       xfree (atr);
-      send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
     }
 
   apdu = hex_to_buffer (line, &apdulen);
@@ -1870,7 +1925,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
       unsigned char *result = NULL;
       size_t resultlen;
 
-      rc = apdu_send_direct (ctrl->reader_slot, exlen,
+      rc = apdu_send_direct (slot, exlen,
                              apdu, apdulen, handle_more,
                              &result, &resultlen);
       if (rc)
@@ -1901,7 +1956,8 @@ cmd_killscd (assuan_context_t ctx, char *line)
   (void)line;
 
   ctrl->server_local->stopme = 1;
-  return gpg_error (GPG_ERR_EOF);
+  assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
+  return 0;
 }
 
 
@@ -2012,13 +2068,14 @@ scd_command_handler (ctrl_t ctrl, int fd)
   session_list = ctrl->server_local;
   ctrl->server_local->ctrl_backlink = ctrl;
   ctrl->server_local->assuan_ctx = ctx;
-
-  if (DBG_ASSUAN)
-    assuan_set_log_stream (ctx, log_get_stream ());
+  ctrl->server_local->vreader_idx = -1;
 
   /* We open the reader right at startup so that the ticker is able to
      update the status file. */
-  ctrl->reader_slot = get_reader_slot ();
+  if (ctrl->server_local->vreader_idx == -1)
+    {
+      ctrl->server_local->vreader_idx = get_current_reader ();
+    }
 
   /* Command processing loop. */
   for (;;)
@@ -2103,8 +2160,7 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...)
         }
       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
         {
-          if (*value == '+' || *value == '\"' || *value == '%'
-              || *value < ' ')
+          if (*value < ' ' || *value == '+')
             {
               sprintf (p, "%%%02X", *value);
               p += 3;
@@ -2224,22 +2280,24 @@ update_reader_status_file (int set_card_removed_flag)
      make sense to wait here for a operation to complete.  If we are
      busy working with a card, delays in the status file update should
      be acceptable. */
-  for (idx=0; idx < DIM(slot_table); idx++)
+  for (idx=0; idx < DIM(vreader_table); idx++)
     {
-      struct slot_status_s *ss = slot_table + idx;
+      struct vreader_s *vr = vreader_table + idx;
       struct server_local_s *sl;
       int sw_apdu;
 
-      if (!ss->valid || ss->slot == -1)
+      if (!vr->valid || vr->slot == -1)
         continue; /* Not valid or reader not yet open. */
 
-      sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed);
+      sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed);
       if (sw_apdu == SW_HOST_NO_READER)
         {
           /* Most likely the _reader_ has been unplugged.  */
-         apdu_close_reader (ss->slot);
+          application_notify_card_reset (vr->slot);
+         apdu_close_reader (vr->slot);
+          vr->slot = -1;
           status = 0;
-          changed = ss->changed;
+          changed = vr->changed;
         }
       else if (sw_apdu)
         {
@@ -2247,21 +2305,21 @@ update_reader_status_file (int set_card_removed_flag)
           continue;
         }
 
-      if (!ss->any || ss->status != status || ss->changed != changed )
+      if (!vr->any || vr->status != status || vr->changed != changed )
         {
           char *fname;
           char templ[50];
           FILE *fp;
 
-          log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n",
-                    ss->slot, ss->status, status, ss->changed, changed);
-          ss->status = status;
-          ss->changed = changed;
+          log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n",
+                    idx, vr->slot, vr->status, status, vr->changed, changed);
+          vr->status = status;
+          vr->changed = changed;
 
-         /* FIXME: Should this be IDX instead of ss->slot?  This
+         /* FIXME: Should this be IDX instead of vr->slot?  This
             depends on how client sessions will associate the reader
             status with their session.  */
-          snprintf (templ, sizeof templ, "reader_%d.status", ss->slot);
+          snprintf (templ, sizeof templ, "reader_%d.status", vr->slot);
           fname = make_filename (opt.homedir, templ, NULL );
           fp = fopen (fname, "w");
           if (fp)
@@ -2282,15 +2340,15 @@ update_reader_status_file (int set_card_removed_flag)
             gpg_error_t err;
 
             homestr = make_filename (opt.homedir, NULL);
-            if (estream_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
+            if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
               log_error ("out of core while building environment\n");
             else
               {
                 envs[0] = envstr;
                 envs[1] = NULL;
 
-                sprintf (numbuf1, "%d", ss->slot);
-                sprintf (numbuf2, "0x%04X", ss->status);
+                sprintf (numbuf1, "%d", vr->slot);
+                sprintf (numbuf2, "0x%04X", vr->status);
                 sprintf (numbuf3, "0x%04X", status);
                 args[0] = "--reader-port";
                 args[1] = numbuf1;
@@ -2307,7 +2365,7 @@ update_reader_status_file (int set_card_removed_flag)
                 fname = make_filename (opt.homedir, "scd-event", NULL);
                 err = gnupg_spawn_process_detached (fname, args, envs);
                 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
-                  log_error ("failed to run event handler `%s': %s\n",
+                  log_error ("failed to run event handler '%s': %s\n",
                              fname, gpg_strerror (err));
                 xfree (fname);
                 xfree (envstr);
@@ -2316,10 +2374,10 @@ update_reader_status_file (int set_card_removed_flag)
           }
 
           /* Set the card removed flag for all current sessions.  */
-          if (ss->any && ss->status == 0 && set_card_removed_flag)
-            update_card_removed (ss->slot, 1);
+          if (vr->any && vr->status == 0 && set_card_removed_flag)
+            update_card_removed (idx, 1);
 
-          ss->any = 1;
+          vr->any = 1;
 
           /* Send a signal to all clients who applied for it.  */
           send_client_notifications ();
@@ -2335,8 +2393,9 @@ update_reader_status_file (int set_card_removed_flag)
             {
               /* FIXME: Use a real timeout.  */
               /* At least one connection and all allow a disconnect.  */
-              log_info ("disconnecting card in slot %d\n", ss->slot);
-              apdu_disconnect (ss->slot);
+              log_info ("disconnecting card in reader %d (%d)\n",
+                        idx, vr->slot);
+              apdu_disconnect (vr->slot);
             }
         }
 
@@ -2349,9 +2408,13 @@ update_reader_status_file (int set_card_removed_flag)
 void
 scd_update_reader_status_file (void)
 {
-  if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL))
+  int err;
+  err = npth_mutex_lock (&status_file_update_lock);
+  if (err)
     return; /* locked - give up. */
   update_reader_status_file (1);
-  if (!pth_mutex_release (&status_file_update_lock))
-    log_error ("failed to release status_file_update lock\n");
+  err = npth_mutex_unlock (&status_file_update_lock);
+  if (err)
+    log_error ("failed to release status_file_update lock: %s\n",
+              strerror (err));
 }
index f22626f..f1dbcff 100644 (file)
@@ -174,17 +174,17 @@ iso7816_select_path (int slot, const unsigned short *path, size_t pathlen,
   int sw, p0, p1;
   unsigned char buffer[100];
   int buflen;
-  
+
   if (result || resultlen)
     {
       *result = NULL;
       *resultlen = 0;
       return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     }
-  
+
   if (pathlen/2 >= sizeof buffer)
     return gpg_error (GPG_ERR_TOO_LARGE);
-  
+
   for (buflen = 0; pathlen; pathlen--, path++)
     {
       buffer[buflen++] = (*path >> 8);
@@ -231,7 +231,7 @@ iso7816_list_directory (int slot, int list_dirs,
    it maps the status word and does not return it in the result
    buffer.  */
 gpg_error_t
-iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen, 
+iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen,
                      int handle_more,
                      unsigned char **result, size_t *resultlen)
 {
@@ -457,7 +457,7 @@ iso7816_manage_security_env (int slot, int p1, int p2,
   if (p1 < 0 || p1 > 255 || p2 < 0 || p2 > 255 )
     return gpg_error (GPG_ERR_INV_VALUE);
 
-  sw = apdu_send_simple (slot, 0, 0x00, CMD_MSE, p1, p2, 
+  sw = apdu_send_simple (slot, 0, 0x00, CMD_MSE, p1, p2,
                          data? datalen : -1, (const char*)data);
   return map_sw (sw);
 }
@@ -484,7 +484,7 @@ iso7816_compute_ds (int slot, int extended_mode,
   else if (le >= 0 && le < 256)
     le = 256;
 
-  sw = apdu_send_le (slot, extended_mode, 
+  sw = apdu_send_le (slot, extended_mode,
                      0x00, CMD_PSO, 0x9E, 0x9A,
                      datalen, (const char*)data,
                      le,
@@ -509,7 +509,7 @@ iso7816_compute_ds (int slot, int extended_mode,
    at RESULT with its length stored at RESULTLEN.  For LE see
    do_generate_keypair. */
 gpg_error_t
-iso7816_decipher (int slot, int extended_mode, 
+iso7816_decipher (int slot, int extended_mode,
                   const unsigned char *data, size_t datalen, int le,
                   int padind, unsigned char **result, size_t *resultlen)
 {
@@ -532,10 +532,10 @@ iso7816_decipher (int slot, int extended_mode,
       buf = xtrymalloc (datalen + 1);
       if (!buf)
         return gpg_error (gpg_err_code_from_errno (errno));
-      
+
       *buf = padind; /* Padding indicator. */
       memcpy (buf+1, data, datalen);
-      sw = apdu_send_le (slot, extended_mode, 
+      sw = apdu_send_le (slot, extended_mode,
                          0x00, CMD_PSO, 0x80, 0x86,
                          datalen+1, (char*)buf, le,
                          result, resultlen);
@@ -604,7 +604,8 @@ iso7816_internal_authenticate (int slot, int extended_mode,
    (e.g. 4096 bytes), a value larger 256 used that value.  */
 static gpg_error_t
 do_generate_keypair (int slot, int extended_mode, int read_only,
-                     const char *data, size_t datalen, int le,
+                     const unsigned char *data, size_t datalen,
+                     int le,
                      unsigned char **result, size_t *resultlen)
 {
   int sw;
@@ -616,7 +617,7 @@ do_generate_keypair (int slot, int extended_mode, int read_only,
 
   sw = apdu_send_le (slot, extended_mode,
                      0x00, CMD_GENERATE_KEYPAIR, read_only? 0x81:0x80, 0,
-                     datalen, data,
+                     datalen, (const char*)data,
                      le >= 0 && le < 256? 256:le,
                      result, resultlen);
   if (sw != SW_SUCCESS)
@@ -634,7 +635,7 @@ do_generate_keypair (int slot, int extended_mode, int read_only,
 
 gpg_error_t
 iso7816_generate_keypair (int slot, int extended_mode,
-                          const char *data, size_t datalen,
+                          const unsigned char *data, size_t datalen,
                           int le,
                           unsigned char **result, size_t *resultlen)
 {
@@ -645,7 +646,7 @@ iso7816_generate_keypair (int slot, int extended_mode,
 
 gpg_error_t
 iso7816_read_public_key (int slot, int extended_mode,
-                         const char *data, size_t datalen,
+                         const unsigned char *data, size_t datalen,
                          int le,
                          unsigned char **result, size_t *resultlen)
 {
@@ -669,7 +670,7 @@ iso7816_get_challenge (int slot, int length, unsigned char *buffer)
     {
       result = NULL;
       n = length > 254? 254 : length;
-      sw = apdu_send_le (slot, 0, 
+      sw = apdu_send_le (slot, 0,
                          0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL, n,
                          &result, &resultlen);
       if (sw != SW_SUCCESS)
@@ -780,7 +781,7 @@ iso7816_read_binary (int slot, size_t offset, size_t nmax,
         nmax = 0;
     }
   while ((read_all && sw != SW_EOF_REACHED) || (!read_all && nmax));
-  
+
   return 0;
 }
 
@@ -813,7 +814,7 @@ iso7816_read_record (int slot, int recno, int reccount, int short_ef,
   buffer = NULL;
   bufferlen = 0;
   sw = apdu_send_le (slot, 0, 0x00, CMD_READ_RECORD,
-                     recno, 
+                     recno,
                      short_ef? short_ef : 0x04,
                      -1, NULL,
                      0, &buffer, &bufferlen);
@@ -829,7 +830,6 @@ iso7816_read_record (int slot, int recno, int reccount, int short_ef,
     }
   *result = buffer;
   *resultlen = bufferlen;
-  
+
   return 0;
 }
-
index 05fea65..6dd1052 100644 (file)
@@ -59,7 +59,7 @@ gpg_error_t iso7816_select_path (int slot,
 gpg_error_t iso7816_list_directory (int slot, int list_dirs,
                                     unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_apdu_direct (int slot,
-                                 const void *apdudata, size_t apdudatalen, 
+                                 const void *apdudata, size_t apdudatalen,
                                  int handle_more,
                                  unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_check_pinpad (int slot, int command,
@@ -100,11 +100,11 @@ gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode,
                                    int le,
                                    unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_generate_keypair (int slot, int extended_mode,
-                                    const char *data, size_t datalen,
+                                    const unsigned char *data, size_t datalen,
                                     int le,
                                     unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_read_public_key (int slot, int extended_mode,
-                                    const char *data, size_t datalen,
+                                    const unsigned char *data, size_t datalen,
                                     int le,
                                     unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_get_challenge (int slot,
index b83e218..b3060e1 100644 (file)
@@ -20,7 +20,8 @@
 /*
   This wrapper is required to handle problems with the libpscslite
   library.  That library assumes that pthreads are used and fails
-  badly if one tries to use it with a procerss using Pth.
+  badly if one tries to use it with a process using Pth.  Note that
+  the wrapper is not required if nPth is used.
 
   The operation model is pretty simple: It reads requests from stdin
   and returns the answer on stdout.  There is no direct mapping to the
@@ -53,7 +54,7 @@
 
 /* Allow for a standalone build. */
 #ifdef VERSION
-#define MYVERSION_LINE PGM " (GnuPG) " VERSION
+#define MYVERSION_LINE PGM " ("GNUPG_NAME") " VERSION
 #define BUGREPORT_LINE "\nReport bugs to <bug-gnupg@gnu.org>.\n"
 #else
 #define MYVERSION_LINE PGM
@@ -205,7 +206,7 @@ long (* pcsc_control) (long card,
 static void
 bad_request (const char *type)
 {
-  fprintf (stderr, PGM ": bad `%s' request\n", type);
+  fprintf (stderr, PGM ": bad '%s' request\n", type);
   exit (1);
 }
 
@@ -273,7 +274,7 @@ read_32 (FILE *fp)
       fprintf (stderr, PGM ": premature EOF while parsing request\n");
       exit (1);
     }
-  return ((unsigned long)c1 << 24) | (c2 << 16) | (c3 << 8) | c4;
+  return (c1 << 24) | (c2 << 16) | (c3 << 8) | c4;
 }
 
 
@@ -339,7 +340,7 @@ load_pcsc_driver (const char *libname)
   handle = dlopen (libname, RTLD_LAZY);
   if (!handle)
     {
-      fprintf (stderr, PGM ": failed to open driver `%s': %s",
+      fprintf (stderr, PGM ": failed to open driver '%s': %s",
                libname, dlerror ());
       exit (1);
     }
@@ -406,9 +407,8 @@ static void
 handle_open (unsigned char *argbuf, size_t arglen)
 {
   long err;
-  const char *portstr;
+  const char * portstr;
   char *list = NULL;
-  char *rdrname = NULL;
   pcsc_dword_t nreader, atrlen;
   char *p;
   pcsc_dword_t card_state, card_protocol;
@@ -417,10 +417,7 @@ handle_open (unsigned char *argbuf, size_t arglen)
   /* Make sure there is only the port string */
   if (arglen != strlen ((char*)argbuf))
     bad_request ("OPEN");
-  if (arglen == 0)
-    portstr = NULL;
-  else
-    portstr = (char*)argbuf;
+  portstr = (char*)argbuf;
 
   if (driver_is_open)
     {
@@ -464,27 +461,23 @@ handle_open (unsigned char *argbuf, size_t arglen)
     {
       if (!*p && !p[1])
         break;
-      fprintf (stderr, PGM": detected reader `%s'\n", p);
+      fprintf (stderr, PGM": detected reader '%s'\n", p);
       if (nreader < (strlen (p)+1))
         {
           fprintf (stderr, PGM": invalid response from pcsc_list_readers\n");
           break;
         }
-      if (!rdrname && portstr && !strncmp (p, portstr, strlen (portstr)))
-        rdrname = p;
       nreader -= strlen (p)+1;
       p += strlen (p) + 1;
     }
 
-  if (!rdrname)
-    rdrname = list;
-
-  current_rdrname = strdup (rdrname);
+  current_rdrname = malloc (strlen (portstr && *portstr? portstr:list)+1);
   if (!current_rdrname)
     {
       fprintf (stderr, PGM": error allocating memory for reader name\n");
       exit (1);
     }
+  strcpy (current_rdrname, portstr && *portstr? portstr:list);
   free (list);
 
   err = pcsc_connect (pcsc_context,
@@ -722,7 +715,7 @@ handle_transmit (unsigned char *argbuf, size_t arglen)
   long err;
   struct pcsc_io_request_s send_pci;
   pcsc_dword_t recv_len;
-  unsigned char buffer[4096];
+  unsigned char buffer[1024];
 
   /* The apdu should at least be one byte. */
   if (!arglen)
@@ -768,8 +761,7 @@ handle_control (unsigned char *argbuf, size_t arglen)
   if (arglen < 4)
     bad_request ("CONTROL");
 
-  ioctl_code = (((pcsc_dword_t)argbuf[0] << 24)
-                | (argbuf[1] << 16) | (argbuf[2] << 8) | argbuf[3]);
+  ioctl_code = (argbuf[0] << 24) | (argbuf[1] << 16) | (argbuf[2] << 8) | argbuf[3];
   argbuf += 4;
   arglen -= 4;
 
index 5217645..e503d36 100644 (file)
@@ -41,7 +41,7 @@
 #define _(a) (a)
 
 
-enum cmd_and_opt_values 
+enum cmd_and_opt_values
 { oVerbose       = 'v',
   oReaderPort     = 500,
   octapiDriver,
@@ -52,7 +52,7 @@ aTest };
 
 
 static ARGPARSE_OPTS opts[] = {
-  
+
   { 301, NULL, 0, "@Options:\n " },
 
   { oVerbose, "verbose",   0, "verbose" },
@@ -86,7 +86,7 @@ my_strusage (int level)
                    "file-with-key\n"
                     "Copy keys to a smartcards\n");
     break;
-    
+
     default: p = NULL;
     }
   return p;
@@ -105,7 +105,7 @@ main (int argc, char **argv )
 
   set_strusage (my_strusage);
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
-  log_set_prefix ("sc-copykeys", 1); 
+  log_set_prefix ("sc-copykeys", 1);
 
   /* check that the libraries are suitable.  Do it here because
      the option parsing may need services of the library */
@@ -180,18 +180,18 @@ read_file (const char *fname, size_t *r_length)
   struct stat st;
   char *buf;
   size_t buflen;
-  
+
   fp = fname? fopen (fname, "rb") : stdin;
   if (!fp)
     {
-      log_error ("can't open `%s': %s\n",
+      log_error ("can't open '%s': %s\n",
                  fname? fname: "[stdin]", strerror (errno));
       return NULL;
     }
-  
+
   if (fstat (fileno(fp), &st))
     {
-      log_error ("can't stat `%s': %s\n", 
+      log_error ("can't stat '%s': %s\n",
                  fname? fname: "[stdin]", strerror (errno));
       if (fname)
         fclose (fp);
@@ -202,7 +202,7 @@ read_file (const char *fname, size_t *r_length)
   buf = xmalloc (buflen+1);
   if (fread (buf, buflen, 1, fp) != 1)
     {
-      log_error ("error reading `%s': %s\n", 
+      log_error ("error reading '%s': %s\n",
                  fname? fname: "[stdin]", strerror (errno));
       if (fname)
         fclose (fp);
@@ -224,7 +224,7 @@ read_key (const char *fname)
   size_t buflen;
   gcry_sexp_t private;
   int rc;
-  
+
   buf = read_file (fname, &buflen);
   if (!buf)
     return NULL;
@@ -234,7 +234,7 @@ read_key (const char *fname)
     {
       log_error ("gcry_sexp_new failed: %s\n", gpg_strerror (rc));
       return NULL;
-    } 
+    }
   xfree (buf);
 
   return private;
@@ -256,7 +256,7 @@ sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created)
   *created = 0;
   list = gcry_sexp_find_token (sexp, "private-key", 0 );
   if(!list)
-    return NULL; 
+    return NULL;
 
   /* quick hack to get the creation time. */
   l2 = gcry_sexp_find_token (list, "created", 0);
@@ -282,7 +282,7 @@ sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created)
   /* Parameter names used with RSA. */
   elems = "nedpqu";
   array = xcalloc (strlen(elems) + 1, sizeof *array);
-  for (idx=0, s=elems; *s; s++, idx++ ) 
+  for (idx=0, s=elems; *s; s++, idx++ )
     {
       l2 = gcry_sexp_find_token (list, s, 1);
       if (!l2)
@@ -304,7 +304,7 @@ sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created)
           return NULL; /* required parameter is invalid */
        }
     }
-  
+
   gcry_sexp_release (list);
   return array;
 }
@@ -454,8 +454,8 @@ query_card (APP app)
         }
     }
 
-  xfree (serialno); 
-  xfree (disp_name); 
+  xfree (serialno);
+  xfree (disp_name);
   xfree (pubkey_url);
   xfree (fpr1);
   xfree (fpr2);
@@ -498,7 +498,7 @@ pincb (void *arg, const char *prompt, char **pinvalue)
      (q #00f7a7c..[some bytes not shown]..61#)
      (u #304559a..[some bytes not shown]..9b#))
     (uri http://foo.bar x-foo:whatever_you_want))
-   
+
 */
 static void
 copykeys (APP app, const char *fname)
@@ -521,7 +521,7 @@ copykeys (APP app, const char *fname)
   private = read_key (fname);
   if (!private)
     exit (1);
-  
+
   mpis = sexp_to_kparms (private, &creation_date);
   if (!creation_date)
     {
@@ -578,7 +578,7 @@ copykeys (APP app, const char *fname)
   /* Build the private key template as described in section 4.3.3.6 of
      the specs.
                    0xC0   <length> public exponent
-                   0xC1   <length> prime p 
+                   0xC1   <length> prime p
                    0xC2   <length> prime q  */
   template = tp = xmalloc (1+2 + 1+1+4 + 1+1+64 + 1+1+64);
   *tp++ = 0xC0;
@@ -596,7 +596,7 @@ copykeys (APP app, const char *fname)
     {
       memmove (tp+4-n, tp, 4-n);
       memset (tp, 0, 4-n);
-    }                 
+    }
   tp += 4;
 
   *tp++ = 0xC1;
@@ -714,5 +714,3 @@ copykeys (APP app, const char *fname)
   gcry_mpi_release (rsa_n);
   exit (1);
 }
-
-
index 89b4e0e..a1f45e2 100644 (file)
@@ -1,6 +1,6 @@
 /* scdaemon.c  -  The GnuPG Smartcard Daemon
- * Copyright (C) 2001, 2002, 2004, 2005,
- *               2007, 2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001-2002, 2004-2005, 2007-2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001-2002, 2004-2005, 2007-2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -35,7 +35,7 @@
 #endif /*HAVE_W32_SYSTEM*/
 #include <unistd.h>
 #include <signal.h>
-#include <pth.h>
+#include <npth.h>
 
 #define JNLIB_NEED_LOG_LOGV
 #define JNLIB_NEED_AFLOCAL
@@ -53,6 +53,9 @@
 #include "ccid-driver.h"
 #include "mkdtemp.h"
 #include "gc-opt-flags.h"
+#include "asshelp.h"
+#include "../common/init.h"
+
 
 enum cmd_and_opt_values
 { aNull = 0,
@@ -72,6 +75,7 @@ enum cmd_and_opt_values
   oDebugAllowCoreDump,
   oDebugCCIDDriver,
   oDebugLogTid,
+  oDebugAssuanLogCats,
   oNoGreeting,
   oNoOptions,
   oHomedir,
@@ -122,6 +126,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oDebugCCIDDriver, "debug-ccid-driver", "@"),
   ARGPARSE_s_n (oDebugDisableTicker, "debug-disable-ticker", "@"),
   ARGPARSE_s_n (oDebugLogTid, "debug-log-tid", "@"),
+  ARGPARSE_p_u (oDebugAssuanLogCats, "debug-assuan-log-cats", "@"),
   ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
   ARGPARSE_s_s (oLogFile,  "log-file", N_("|FILE|write a log to FILE")),
   ARGPARSE_s_s (oReaderPort, "reader-port",
@@ -150,7 +155,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDisableApplication, "disable-application", "@"),
   ARGPARSE_s_n (oEnablePinpadVarlen, "enable-pinpad-varlen",
                 N_("use variable length input for pinpad")),
-  ARGPARSE_s_s (oHomedir,    "homedir",      "@"),
 
   ARGPARSE_end ()
 };
@@ -174,7 +178,7 @@ static ARGPARSE_OPTS opts[] = {
    easy way to block on card status changes it is the best we can do.
    For PC/SC we could in theory use an extra thread to wait for status
    changes but that requires a native thread because there is no way
-   to make the underlying PC/SC card change function block using a Pth
+   to make the underlying PC/SC card change function block using a Npth
    mechanism.  Given that a native thread could only be used under W32
    we don't do that at all.  */
 #define TIMERTICK_INTERVAL_SEC     (0)
@@ -202,26 +206,17 @@ static int ticker_disabled;
 
 
 \f
-static char *create_socket_name (int use_standard_socket,
-                                 char *standard_name, char *template);
-static gnupg_fd_t create_server_socket (int is_standard_name, const char *name,
+static char *create_socket_name (char *standard_name);
+static gnupg_fd_t create_server_socket (const char *name,
                                         assuan_sock_nonce_t *nonce);
 
 static void *start_connection_thread (void *arg);
 static void handle_connections (int listen_fd);
 
 /* Pth wrapper function definitions. */
-ASSUAN_SYSTEM_PTH_IMPL;
+ASSUAN_SYSTEM_NPTH_IMPL;
 
-#if GCRYPT_VERSION_NUMBER < 0x010600
-GCRY_THREAD_OPTION_PTH_IMPL;
-#if GCRY_THREAD_OPTION_VERSION < 1
-static int fixed_gcry_pth_init (void)
-{
-  return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0;
-}
-#endif
-#endif /*GCRYPT_VERSION_NUMBER < 0x010600*/
+static int active_connections;
 
 \f
 static char *
@@ -250,7 +245,7 @@ my_strusage (int level)
 
   switch (level)
     {
-    case 11: p = "scdaemon (GnuPG)";
+    case 11: p = "@SCDAEMON@ (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -267,10 +262,10 @@ my_strusage (int level)
       p = ver_ksba;
       break;
     case 1:
-    case 40: p =  _("Usage: scdaemon [options] (-h for help)");
+    case 40: p =  _("Usage: @SCDAEMON@ [options] (-h for help)");
       break;
     case 41: p =  _("Syntax: scdaemon [options] [command [args]]\n"
-                    "Smartcard daemon for GnuPG\n");
+                    "Smartcard daemon for @GNUPG@\n");
     break;
 
     default: p = NULL;
@@ -279,18 +274,19 @@ my_strusage (int level)
 }
 
 
-static unsigned long
-tid_log_callback (void)
+static int
+tid_log_callback (unsigned long *rvalue)
 {
-#ifdef PTH_HAVE_PTH_THREAD_ID
-  return pth_thread_id ();
-#else
-  return (unsigned long)pth_self ();
-#endif
-}
-
+  int len = sizeof (*rvalue);
+  npth_t thread;
 
+  thread = npth_self ();
+  if (sizeof (thread) < len)
+    len = sizeof (thread);
+  memcpy (rvalue, &thread, len);
 
+  return 2; /* Use use hex representation.  */
+}
 
 
 /* Setup the debugging.  With a LEVEL of NULL only the active debug
@@ -326,7 +322,7 @@ set_debug (const char *level)
     }
   else
     {
-      log_error (_("invalid debug-level `%s' given\n"), level);
+      log_error (_("invalid debug-level '%s' given\n"), level);
       scd_exit(2);
     }
 
@@ -402,8 +398,9 @@ main (int argc, char **argv )
   int gpgconf_list = 0;
   const char *config_filename = NULL;
   int allow_coredump = 0;
-  int standard_socket = 0;
   struct assuan_malloc_hooks malloc_hooks;
+  int res;
+  npth_t pipecon_handler;
 
   set_strusage (my_strusage);
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
@@ -414,26 +411,9 @@ main (int argc, char **argv )
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
-
-#if GCRYPT_VERSION_NUMBER < 0x010600
-  /* Libgcrypt < 1.6 requires us to register the threading model first.
-     Note that this will also do the pth_init. */
-  {
-    gpg_error_t err;
-#if GCRY_THREAD_OPTION_VERSION < 1
-  gcry_threads_pth.init = fixed_gcry_pth_init;
-#endif
-
-  err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
-  if (err)
-    {
-      log_fatal ("can't register GNU Pth with Libgcrypt: %s\n",
-                 gpg_strerror (err));
-    }
-  }
-#endif /*GCRYPT_VERSION_NUMBER < 0x010600*/
+  npth_init ();
 
   /* Check that the libraries are suitable.  Do it here because
      the option parsing may need services of the library */
@@ -449,10 +429,10 @@ main (int argc, char **argv )
   malloc_hooks.realloc = gcry_realloc;
   malloc_hooks.free = gcry_free;
   assuan_set_malloc_hooks (&malloc_hooks);
-  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
-  assuan_set_system_hooks (ASSUAN_SYSTEM_PTH);
+  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   assuan_sock_init ();
+  setup_libassuan_logging (&opt.debug);
 
   setup_libgcrypt_logging ();
   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
@@ -463,12 +443,6 @@ main (int argc, char **argv )
   opt.allow_admin = 1;
   opt.pcsc_driver = DEFAULT_PCSC_DRIVER;
 
-#ifdef HAVE_W32_SYSTEM
-  standard_socket = 1;  /* Under Windows we always use a standard
-                           socket.  */
-#endif
-
-
   shell = getenv ("SHELL");
   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
     csh_style = 1;
@@ -507,7 +481,8 @@ main (int argc, char **argv )
 
 
   if (default_config)
-    configname = make_filename (opt.homedir, "scdaemon.conf", NULL );
+    configname = make_filename (opt.homedir, SCDAEMON_NAME EXTSEP_S "conf",
+                                NULL );
 
 
   argc = orig_argc;
@@ -525,12 +500,12 @@ main (int argc, char **argv )
           if (default_config)
             {
               if( parse_debug )
-                log_info (_("NOTE: no default option file `%s'\n"),
+                log_info (_("Note: no default option file '%s'\n"),
                           configname );
            }
           else
             {
-              log_error (_("option file `%s': %s\n"),
+              log_error (_("option file '%s': %s\n"),
                          configname, strerror(errno) );
               exit(2);
            }
@@ -538,7 +513,7 @@ main (int argc, char **argv )
           configname = NULL;
        }
       if (parse_debug && configname )
-        log_info (_("reading options from `%s'\n"), configname );
+        log_info (_("reading options from '%s'\n"), configname );
       default_config = 0;
     }
 
@@ -567,7 +542,10 @@ main (int argc, char **argv )
           break;
         case oDebugDisableTicker: ticker_disabled = 1; break;
         case oDebugLogTid:
-          log_set_get_tid_callback (tid_log_callback);
+          log_set_pid_suffix_cb (tid_log_callback);
+          break;
+        case oDebugAssuanLogCats:
+          set_libassuan_log_cats (pargs.r.ret_ulong);
           break;
 
         case oOptions:
@@ -634,14 +612,23 @@ main (int argc, char **argv )
 
   if (greeting)
     {
-      fprintf (stderr, "%s %s; %s\n",
-                 strusage(11), strusage(13), strusage(14) );
-      fprintf (stderr, "%s\n", strusage(15) );
+      es_fprintf (es_stderr, "%s %s; %s\n",
+                  strusage(11), strusage(13), strusage(14) );
+      es_fprintf (es_stderr, "%s\n", strusage(15) );
     }
 #ifdef IS_DEVELOPMENT_VERSION
   log_info ("NOTE: this is a development version!\n");
 #endif
 
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+    {
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
+    }
 
   if (atexit (cleanup))
     {
@@ -665,34 +652,36 @@ main (int argc, char **argv )
       if (config_filename)
        filename = xstrdup (config_filename);
       else
-        filename = make_filename (opt.homedir, "scdaemon.conf", NULL);
+        filename = make_filename (opt.homedir, SCDAEMON_NAME EXTSEP_S "conf",
+                                  NULL);
       filename_esc = percent_escape (filename, NULL);
 
-      printf ("gpgconf-scdaemon.conf:%lu:\"%s\n",
-              GC_OPT_FLAG_DEFAULT, filename_esc);
+      es_printf ("%s-%s.conf:%lu:\"%s\n",
+                 GPGCONF_NAME, SCDAEMON_NAME,
+                 GC_OPT_FLAG_DEFAULT, filename_esc);
       xfree (filename_esc);
       xfree (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 ("reader-port:%lu:\n", GC_OPT_FLAG_NONE );
-      printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE );
-      printf ("pcsc-driver:%lu:\"%s:\n",
+      es_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 );
+
+      es_printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE );
+      es_printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE );
+      es_printf ("pcsc-driver:%lu:\"%s:\n",
               GC_OPT_FLAG_DEFAULT, DEFAULT_PCSC_DRIVER );
 #ifdef HAVE_LIBUSB
-      printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE );
+      es_printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE );
 #endif
-      printf ("deny-admin:%lu:\n", GC_OPT_FLAG_NONE );
-      printf ("disable-pinpad:%lu:\n", GC_OPT_FLAG_NONE );
-      printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0);
-      printf ("enable-pinpad-varlen:%lu:\n", GC_OPT_FLAG_NONE );
+      es_printf ("deny-admin:%lu:\n", GC_OPT_FLAG_NONE );
+      es_printf ("disable-pinpad:%lu:\n", GC_OPT_FLAG_NONE );
+      es_printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0);
+      es_printf ("enable-pinpad-varlen:%lu:\n", GC_OPT_FLAG_NONE );
 
       scd_exit (0);
     }
@@ -716,7 +705,7 @@ main (int argc, char **argv )
     {
       /* This is the simple pipe based server */
       ctrl_t ctrl;
-      pth_attr_t tattr;
+      npth_attr_t tattr;
       int fd = -1;
 
 #ifndef HAVE_W32_SYSTEM
@@ -736,9 +725,9 @@ main (int argc, char **argv )
       if (allow_coredump)
         {
           if (chdir("/tmp"))
-            log_debug ("chdir to `/tmp' failed: %s\n", strerror (errno));
+            log_debug ("chdir to '/tmp' failed: %s\n", strerror (errno));
           else
-            log_debug ("changed working directory to `/tmp'\n");
+            log_debug ("changed working directory to '/tmp'\n");
         }
 
       /* In multi server mode we need to listen on an additional
@@ -747,18 +736,18 @@ main (int argc, char **argv )
          back the name of that socket. */
       if (multi_server)
         {
-          socket_name = create_socket_name (standard_socket,
-                                            "S.scdaemon",
-                                            "/tmp/gpg-XXXXXX/S.scdaemon");
-
-          fd = FD2INT(create_server_socket (standard_socket,
-                                            socket_name, &socket_nonce));
+          socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
+          fd = FD2INT(create_server_socket (socket_name, &socket_nonce));
         }
 
-      tattr = pth_attr_new();
-      pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
-      pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024);
-      pth_attr_set (tattr, PTH_ATTR_NAME, "pipe-connection");
+      res = npth_attr_init (&tattr);
+      if (res)
+       {
+          log_error ("error allocating thread attributes: %s\n",
+                     strerror (res));
+          scd_exit (2);
+        }
+      npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
 
       ctrl = xtrycalloc (1, sizeof *ctrl);
       if ( !ctrl )
@@ -768,13 +757,16 @@ main (int argc, char **argv )
           scd_exit (2);
         }
       ctrl->thread_startup.fd = GNUPG_INVALID_FD;
-      if ( !pth_spawn (tattr, start_connection_thread, ctrl) )
+      res = npth_create (&pipecon_handler, &tattr, start_connection_thread, ctrl);
+      if (res)
         {
           log_error ("error spawning pipe connection handler: %s\n",
-                     strerror (errno) );
+                     strerror (res) );
           xfree (ctrl);
           scd_exit (2);
         }
+      npth_setname_np (pipecon_handler, "pipe-connection");
+      npth_attr_destroy (&tattr);
 
       /* We run handle_connection to wait for the shutdown signal and
          to run the ticker stuff.  */
@@ -784,7 +776,7 @@ main (int argc, char **argv )
     }
   else if (!is_daemon)
     {
-      log_info (_("please use the option `--daemon'"
+      log_info (_("please use the option '--daemon'"
                   " to run the program in the background\n"));
     }
   else
@@ -796,16 +788,15 @@ main (int argc, char **argv )
 #endif
 
       /* Create the socket.  */
-      socket_name = create_socket_name (standard_socket,
-                                        "S.scdaemon",
-                                        "/tmp/gpg-XXXXXX/S.scdaemon");
-
-      fd = FD2INT (create_server_socket (standard_socket,
-                                         socket_name, &socket_nonce));
+      socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
+      fd = FD2INT (create_server_socket (socket_name, &socket_nonce));
 
 
       fflush (NULL);
-#ifndef HAVE_W32_SYSTEM
+#ifdef HAVE_W32_SYSTEM
+      (void)csh_style;
+      (void)nodetach;
+#else
       pid = fork ();
       if (pid == (pid_t)-1)
         {
@@ -819,8 +810,8 @@ main (int argc, char **argv )
           close (fd);
 
           /* create the info string: <name>:<pid>:<protocol_version> */
-          if (estream_asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1",
-                               socket_name, (ulong) pid) < 0)
+          if (gpgrt_asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1",
+                              socket_name, (ulong) pid) < 0)
             {
               log_error ("out of core\n");
               kill (pid, SIGTERM);
@@ -849,11 +840,11 @@ main (int argc, char **argv )
               if (csh_style)
                 {
                   *strchr (infostr, '=') = ' ';
-                  printf ( "setenv %s;\n", infostr);
+                  es_printf ( "setenv %s;\n", infostr);
                 }
               else
                 {
-                  printf ( "%s; export SCDAEMON_INFO;\n", infostr);
+                  es_printf ( "%s; export SCDAEMON_INFO;\n", infostr);
                 }
               xfree (infostr);
               exit (0);
@@ -932,13 +923,17 @@ scd_exit (int rc)
 static void
 scd_init_default_ctrl (ctrl_t ctrl)
 {
-  ctrl->reader_slot = -1;
+  (void)ctrl;
 }
 
 static void
 scd_deinit_default_ctrl (ctrl_t ctrl)
 {
-  (void)ctrl;
+  if (!ctrl)
+    return;
+  xfree (ctrl->in_data.value);
+  ctrl->in_data.value = NULL;
+  ctrl->in_data.valuelen = 0;
 }
 
 
@@ -953,12 +948,12 @@ scd_get_socket_name ()
 }
 
 
+#ifndef HAVE_W32_SYSTEM
 static void
 handle_signal (int signo)
 {
   switch (signo)
     {
-#ifndef HAVE_W32_SYSTEM
     case SIGHUP:
       log_info ("SIGHUP received - "
                 "re-reading configuration and resetting cards\n");
@@ -967,7 +962,9 @@ handle_signal (int signo)
 
     case SIGUSR1:
       log_info ("SIGUSR1 received - printing internal information:\n");
-      pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ());
+      /* Fixme: We need to see how to integrate pth dumping into our
+         logging system.  */
+      /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
       app_dump_state ();
       break;
 
@@ -979,8 +976,8 @@ handle_signal (int signo)
       if (!shutdown_pending)
         log_info ("SIGTERM received - shutting down ...\n");
       else
-        log_info ("SIGTERM received - still %ld running threads\n",
-                  pth_ctrl( PTH_CTRL_GETTHREADS ));
+        log_info ("SIGTERM received - still %i running threads\n",
+                  active_connections);
       shutdown_pending++;
       if (shutdown_pending > 2)
         {
@@ -997,12 +994,12 @@ handle_signal (int signo)
       cleanup ();
       scd_exit (0);
       break;
-#endif /*!HAVE_W32_SYSTEM*/
 
     default:
       log_info ("signal %d received - no action defined\n", signo);
     }
 }
+#endif /*!HAVE_W32_SYSTEM*/
 
 
 static void
@@ -1013,41 +1010,20 @@ handle_tick (void)
 }
 
 
-/* Create a name for the socket.  With USE_STANDARD_SOCKET given as
-   true using STANDARD_NAME in the home directory or if given has
-   false from the mkdir type name TEMPLATE.  In the latter case a
-   unique name in a unique new directory will be created.  In both
-   cases check for valid characters as well as against a maximum
-   allowed length for a unix domain socket is done.  The function
-   terminates the process in case of an error.  Retunrs: Pointer to an
-   allcoated string with the absolute name of the socket used.  */
+/* Create a name for the socket.  We check for valid characters as
+   well as against a maximum allowed length for a unix domain socket
+   is done.  The function terminates the process in case of an error.
+   Retunrs: Pointer to an allcoated string with the absolute name of
+   the socket used.  */
 static char *
-create_socket_name (int use_standard_socket,
-                   char *standard_name, char *template)
+create_socket_name (char *standard_name)
 {
-  char *name, *p;
-
-  if (use_standard_socket)
-    name = make_filename (opt.homedir, standard_name, NULL);
-  else
-    {
-      name = xstrdup (template);
-      p = strrchr (name, '/');
-      if (!p)
-       BUG ();
-      *p = 0;
-      if (!mkdtemp (name))
-       {
-         log_error (_("can't create directory `%s': %s\n"),
-                    name, strerror (errno));
-         scd_exit (2);
-       }
-      *p = '/';
-    }
+  char *name;
 
+  name = make_filename (opt.homedir, standard_name, NULL);
   if (strchr (name, PATHSEP_C))
     {
-      log_error (("`%s' are not allowed in the socket name\n"), PATHSEP_S);
+      log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
       scd_exit (2);
     }
   if (strlen (name) + 1 >= DIMof (struct sockaddr_un, sun_path) )
@@ -1060,12 +1036,10 @@ create_socket_name (int use_standard_socket,
 
 
 
-/* Create a Unix domain socket with NAME.  IS_STANDARD_NAME indicates
-   whether a non-random socket is used.  Returns the file descriptor
+/* Create a Unix domain socket with NAME.  Returns the file descriptor
    or terminates the process in case of an error. */
 static gnupg_fd_t
-create_server_socket (int is_standard_name, const char *name,
-                      assuan_sock_nonce_t *nonce)
+create_server_socket (const char *name, assuan_sock_nonce_t *nonce)
 {
   struct sockaddr_un *serv_addr;
   socklen_t len;
@@ -1087,7 +1061,7 @@ create_server_socket (int is_standard_name, const char *name,
   len = SUN_LEN (serv_addr);
 
   rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);
-  if (is_standard_name && rc == -1 && errno == EADDRINUSE)
+  if (rc == -1 && errno == EADDRINUSE)
     {
       remove (name);
       rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);
@@ -1097,7 +1071,7 @@ create_server_socket (int is_standard_name, const char *name,
     log_error (_("error getting nonce for the socket\n"));
  if (rc == -1)
     {
-      log_error (_("error binding socket to `%s': %s\n"),
+      log_error (_("error binding socket to '%s': %s\n"),
                 serv_addr->sun_path,
                  gpg_strerror (gpg_error_from_syserror ()));
       assuan_sock_close (fd);
@@ -1113,7 +1087,7 @@ create_server_socket (int is_standard_name, const char *name,
     }
 
   if (opt.verbose)
-    log_info (_("listening on socket `%s'\n"), serv_addr->sun_path);
+    log_info (_("listening on socket '%s'\n"), serv_addr->sun_path);
 
   return fd;
 }
@@ -1166,35 +1140,34 @@ start_connection_thread (void *arg)
 static void
 handle_connections (int listen_fd)
 {
-  pth_attr_t tattr;
-  pth_event_t ev, time_ev;
-  sigset_t sigs;
-  int signo;
+  npth_attr_t tattr;
   struct sockaddr_un paddr;
   socklen_t plen;
   fd_set fdset, read_fdset;
   int ret;
   int fd;
   int nfd;
+  struct timespec abstime;
+  struct timespec curtime;
+  struct timespec timeout;
+  int saved_errno;
+#ifndef HAVE_W32_SYSTEM
+  int signo;
+#endif
 
-  tattr = pth_attr_new();
-  pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
-  pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024);
-
-#ifndef HAVE_W32_SYSTEM /* fixme */
-  sigemptyset (&sigs );
-  sigaddset (&sigs, SIGHUP);
-  sigaddset (&sigs, SIGUSR1);
-  sigaddset (&sigs, SIGUSR2);
-  sigaddset (&sigs, SIGINT);
-  sigaddset (&sigs, SIGTERM);
-  pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
-  ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
-#else
-  sigs = 0;
-  ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
+  ret = npth_attr_init(&tattr);
+  /* FIXME: Check error.  */
+  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+
+#ifndef HAVE_W32_SYSTEM
+  npth_sigev_init ();
+  npth_sigev_add (SIGHUP);
+  npth_sigev_add (SIGUSR1);
+  npth_sigev_add (SIGUSR2);
+  npth_sigev_add (SIGINT);
+  npth_sigev_add (SIGTERM);
+  npth_sigev_fini ();
 #endif
-  time_ev = NULL;
 
   FD_ZERO (&fdset);
   nfd = 0;
@@ -1204,13 +1177,17 @@ handle_connections (int listen_fd)
       nfd = listen_fd;
     }
 
+  npth_clock_gettime (&curtime);
+  timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
+  timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
+  npth_timeradd (&curtime, &timeout, &abstime);
+  /* We only require abstime here.  The others will be reused.  */
+
   for (;;)
     {
-      sigset_t oldsigs;
-
       if (shutdown_pending)
         {
-          if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1)
+          if (active_connections == 0)
             break; /* ready */
 
           /* Do not accept anymore connections but wait for existing
@@ -1221,80 +1198,50 @@ handle_connections (int listen_fd)
           listen_fd = -1;
        }
 
-      /* Create a timeout event if needed.  Round it up to the next
-         microsecond interval to help with power saving. */
-      if (!time_ev)
-        {
-          pth_time_t nexttick = pth_timeout (TIMERTICK_INTERVAL_SEC,
-                                             TIMERTICK_INTERVAL_USEC/2);
-          if ((nexttick.tv_usec % (TIMERTICK_INTERVAL_USEC/2)) > 10)
-            {
-              nexttick.tv_usec = ((nexttick.tv_usec
-                                   /(TIMERTICK_INTERVAL_USEC/2))
-                                  + 1) * (TIMERTICK_INTERVAL_USEC/2);
-              if (nexttick.tv_usec >= 1000000)
-                {
-                  nexttick.tv_sec++;
-                  nexttick.tv_usec = 0;
-                }
-            }
-          time_ev = pth_event (PTH_EVENT_TIME, nexttick);
-        }
+      npth_clock_gettime (&curtime);
+      if (!(npth_timercmp (&curtime, &abstime, <)))
+       {
+         /* Timeout.  */
+         handle_tick ();
+         timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
+         timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
+         npth_timeradd (&curtime, &timeout, &abstime);
+       }
+      npth_timersub (&abstime, &curtime, &timeout);
 
       /* POSIX says that fd_set should be implemented as a structure,
          thus a simple assignment is fine to copy the entire set.  */
       read_fdset = fdset;
 
-      if (time_ev)
-        pth_event_concat (ev, time_ev, NULL);
-      ret = pth_select_ev (nfd+1, &read_fdset, NULL, NULL, NULL, ev);
-      if (time_ev)
-        pth_event_isolate (time_ev);
+#ifndef HAVE_W32_SYSTEM
+      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+      saved_errno = errno;
 
-      if (ret == -1)
+      while (npth_sigev_get_pending(&signo))
+       handle_signal (signo);
+#else
+      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
+      saved_errno = errno;
+#endif
+
+      if (ret == -1 && saved_errno != EINTR)
        {
-          if (pth_event_occurred (ev)
-              || (time_ev && pth_event_occurred (time_ev)))
-            {
-              if (pth_event_occurred (ev))
-                handle_signal (signo);
-              if (time_ev && pth_event_occurred (time_ev))
-                {
-                  pth_event_free (time_ev, PTH_FREE_ALL);
-                  time_ev = NULL;
-                  handle_tick ();
-                }
-              continue;
-            }
-          log_error (_("pth_select failed: %s - waiting 1s\n"),
-                     strerror (errno));
-          pth_sleep (1);
+          log_error (_("npth_pselect failed: %s - waiting 1s\n"),
+                     strerror (saved_errno));
+          npth_sleep (1);
          continue;
        }
 
-      if (pth_event_occurred (ev))
-        {
-          handle_signal (signo);
-        }
-
-      if (time_ev && pth_event_occurred (time_ev))
-        {
-          pth_event_free (time_ev, PTH_FREE_ALL);
-          time_ev = NULL;
-          handle_tick ();
-        }
-
-      /* We now might create new threads and because we don't want any
-         signals - we are handling here - to be delivered to a new
-         thread. Thus we need to block those signals. */
-      pth_sigmask (SIG_BLOCK, &sigs, &oldsigs);
+      if (ret <= 0)
+       /* Timeout.  Will be handled when calculating the next timeout.  */
+       continue;
 
       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
        {
           ctrl_t ctrl;
 
           plen = sizeof paddr;
-         fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
+         fd = npth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
          if (fd == -1)
            {
              log_error ("accept failed: %s\n", strerror (errno));
@@ -1308,32 +1255,27 @@ handle_connections (int listen_fd)
           else
             {
               char threadname[50];
+             npth_t thread;
 
               snprintf (threadname, sizeof threadname-1, "conn fd=%d", fd);
               threadname[sizeof threadname -1] = 0;
-              pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
               ctrl->thread_startup.fd = INT2FD (fd);
-              if (!pth_spawn (tattr, start_connection_thread, ctrl))
+              ret = npth_create (&thread, &tattr, start_connection_thread, ctrl);
+             if (ret)
                 {
                   log_error ("error spawning connection handler: %s\n",
-                             strerror (errno) );
+                             strerror (ret));
                   xfree (ctrl);
                   close (fd);
                 }
+              else
+               npth_setname_np (thread, threadname);
             }
           fd = -1;
        }
-
-      /* Restore the signal mask. */
-      pth_sigmask (SIG_SETMASK, &oldsigs, NULL);
-
     }
 
-  pth_event_free (ev, PTH_FREE_ALL);
-  if (time_ev)
-    pth_event_free (time_ev, PTH_FREE_ALL);
   cleanup ();
   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
+  npth_attr_destroy (&tattr);
 }
-
-
index 5ead4aa..ab63425 100644 (file)
@@ -73,8 +73,9 @@ struct
 #define DBG_CACHE_VALUE   64   /* debug the caching */
 #define DBG_MEMSTAT_VALUE 128  /* show memory statistics */
 #define DBG_HASHING_VALUE 512  /* debug hashing operations */
-#define DBG_ASSUAN_VALUE 1024   
+#define DBG_ASSUAN_VALUE  1024
 #define DBG_CARD_IO_VALUE 2048
+#define DBG_READER_VALUE  4096  /* Trace reader related functions.  */
 
 #define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE)
 #define DBG_CRYPTO  (opt.debug & DBG_CRYPTO_VALUE)
@@ -83,24 +84,22 @@ struct
 #define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
 #define DBG_ASSUAN  (opt.debug & DBG_ASSUAN_VALUE)
 #define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE)
+#define DBG_READER  (opt.debug & DBG_READER_VALUE)
 
 struct server_local_s;
 struct app_ctx_s;
 
-struct server_control_s 
+struct server_control_s
 {
   /* Private data used to fire up the connection thread.  We use this
      structure do avoid an extra allocation for just a few bytes. */
   struct {
     gnupg_fd_t fd;
   } thread_startup;
-  
+
   /* Local data of the server; used only in command.c. */
   struct server_local_s *server_local;
 
-  /* Slot of the open reader or -1 if not open. */
-  int reader_slot; 
-
   /* The application context used with this connection or NULL if none
      associated.  Note that this is shared with the other connections:
      All connections accessing the same reader are using the same
@@ -108,11 +107,11 @@ struct server_control_s
   struct app_ctx_s *app_ctx;
 
   /* Helper to store the value we are going to sign */
-  struct 
+  struct
   {
-    unsigned char *value;  
+    unsigned char *value;
     int valuelen;
-  } in_data;  
+  } in_data;
 };
 
 typedef struct app_ctx_s *app_t;
diff --git a/scripts/compile b/scripts/compile
deleted file mode 100755 (executable)
index 531136b..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-#! /bin/sh
-# Wrapper for compilers which do not understand '-c -o'.
-
-scriptversion=2012-10-14.11; # UTC
-
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
-# Written by Tom Tromey <tromey@cygnus.com>.
-#
-# This program 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, or (at your option)
-# any later version.
-#
-# This program 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, see <http://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-nl='
-'
-
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent tools from complaining about whitespace usage.
-IFS=" ""       $nl"
-
-file_conv=
-
-# func_file_conv build_file lazy
-# Convert a $build file to $host form and store it in $file
-# Currently only supports Windows hosts. If the determined conversion
-# type is listed in (the comma separated) LAZY, no conversion will
-# take place.
-func_file_conv ()
-{
-  file=$1
-  case $file in
-    / | /[!/]*) # absolute file, and not a UNC file
-      if test -z "$file_conv"; then
-       # lazily determine how to convert abs files
-       case `uname -s` in
-         MINGW*)
-           file_conv=mingw
-           ;;
-         CYGWIN*)
-           file_conv=cygwin
-           ;;
-         *)
-           file_conv=wine
-           ;;
-       esac
-      fi
-      case $file_conv/,$2, in
-       *,$file_conv,*)
-         ;;
-       mingw/*)
-         file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
-         ;;
-       cygwin/*)
-         file=`cygpath -m "$file" || echo "$file"`
-         ;;
-       wine/*)
-         file=`winepath -w "$file" || echo "$file"`
-         ;;
-      esac
-      ;;
-  esac
-}
-
-# func_cl_dashL linkdir
-# Make cl look for libraries in LINKDIR
-func_cl_dashL ()
-{
-  func_file_conv "$1"
-  if test -z "$lib_path"; then
-    lib_path=$file
-  else
-    lib_path="$lib_path;$file"
-  fi
-  linker_opts="$linker_opts -LIBPATH:$file"
-}
-
-# func_cl_dashl library
-# Do a library search-path lookup for cl
-func_cl_dashl ()
-{
-  lib=$1
-  found=no
-  save_IFS=$IFS
-  IFS=';'
-  for dir in $lib_path $LIB
-  do
-    IFS=$save_IFS
-    if $shared && test -f "$dir/$lib.dll.lib"; then
-      found=yes
-      lib=$dir/$lib.dll.lib
-      break
-    fi
-    if test -f "$dir/$lib.lib"; then
-      found=yes
-      lib=$dir/$lib.lib
-      break
-    fi
-    if test -f "$dir/lib$lib.a"; then
-      found=yes
-      lib=$dir/lib$lib.a
-      break
-    fi
-  done
-  IFS=$save_IFS
-
-  if test "$found" != yes; then
-    lib=$lib.lib
-  fi
-}
-
-# func_cl_wrapper cl arg...
-# Adjust compile command to suit cl
-func_cl_wrapper ()
-{
-  # Assume a capable shell
-  lib_path=
-  shared=:
-  linker_opts=
-  for arg
-  do
-    if test -n "$eat"; then
-      eat=
-    else
-      case $1 in
-       -o)
-         # configure might choose to run compile as 'compile cc -o foo foo.c'.
-         eat=1
-         case $2 in
-           *.o | *.[oO][bB][jJ])
-             func_file_conv "$2"
-             set x "$@" -Fo"$file"
-             shift
-             ;;
-           *)
-             func_file_conv "$2"
-             set x "$@" -Fe"$file"
-             shift
-             ;;
-         esac
-         ;;
-       -I)
-         eat=1
-         func_file_conv "$2" mingw
-         set x "$@" -I"$file"
-         shift
-         ;;
-       -I*)
-         func_file_conv "${1#-I}" mingw
-         set x "$@" -I"$file"
-         shift
-         ;;
-       -l)
-         eat=1
-         func_cl_dashl "$2"
-         set x "$@" "$lib"
-         shift
-         ;;
-       -l*)
-         func_cl_dashl "${1#-l}"
-         set x "$@" "$lib"
-         shift
-         ;;
-       -L)
-         eat=1
-         func_cl_dashL "$2"
-         ;;
-       -L*)
-         func_cl_dashL "${1#-L}"
-         ;;
-       -static)
-         shared=false
-         ;;
-       -Wl,*)
-         arg=${1#-Wl,}
-         save_ifs="$IFS"; IFS=','
-         for flag in $arg; do
-           IFS="$save_ifs"
-           linker_opts="$linker_opts $flag"
-         done
-         IFS="$save_ifs"
-         ;;
-       -Xlinker)
-         eat=1
-         linker_opts="$linker_opts $2"
-         ;;
-       -*)
-         set x "$@" "$1"
-         shift
-         ;;
-       *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
-         func_file_conv "$1"
-         set x "$@" -Tp"$file"
-         shift
-         ;;
-       *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
-         func_file_conv "$1" mingw
-         set x "$@" "$file"
-         shift
-         ;;
-       *)
-         set x "$@" "$1"
-         shift
-         ;;
-      esac
-    fi
-    shift
-  done
-  if test -n "$linker_opts"; then
-    linker_opts="-link$linker_opts"
-  fi
-  exec "$@" $linker_opts
-  exit 1
-}
-
-eat=
-
-case $1 in
-  '')
-     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
-     exit 1;
-     ;;
-  -h | --h*)
-    cat <<\EOF
-Usage: compile [--help] [--version] PROGRAM [ARGS]
-
-Wrapper for compilers which do not understand '-c -o'.
-Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
-arguments, and rename the output as expected.
-
-If you are trying to build a whole package this is not the
-right script to run: please start by reading the file 'INSTALL'.
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
-    exit $?
-    ;;
-  -v | --v*)
-    echo "compile $scriptversion"
-    exit $?
-    ;;
-  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
-    func_cl_wrapper "$@"      # Doesn't return...
-    ;;
-esac
-
-ofile=
-cfile=
-
-for arg
-do
-  if test -n "$eat"; then
-    eat=
-  else
-    case $1 in
-      -o)
-       # configure might choose to run compile as 'compile cc -o foo foo.c'.
-       # So we strip '-o arg' only if arg is an object.
-       eat=1
-       case $2 in
-         *.o | *.obj)
-           ofile=$2
-           ;;
-         *)
-           set x "$@" -o "$2"
-           shift
-           ;;
-       esac
-       ;;
-      *.c)
-       cfile=$1
-       set x "$@" "$1"
-       shift
-       ;;
-      *)
-       set x "$@" "$1"
-       shift
-       ;;
-    esac
-  fi
-  shift
-done
-
-if test -z "$ofile" || test -z "$cfile"; then
-  # If no '-o' option was seen then we might have been invoked from a
-  # pattern rule where we don't need one.  That is ok -- this is a
-  # normal compilation that the losing compiler can handle.  If no
-  # '.c' file was seen then we are probably linking.  That is also
-  # ok.
-  exec "$@"
-fi
-
-# Name of file we expect compiler to create.
-cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
-
-# Create the lock directory.
-# Note: use '[/\\:.-]' here to ensure that we don't use the same name
-# that we are using for the .o file.  Also, base the name on the expected
-# object file name, since that is what matters with a parallel build.
-lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
-while true; do
-  if mkdir "$lockdir" >/dev/null 2>&1; then
-    break
-  fi
-  sleep 1
-done
-# FIXME: race condition here if user kills between mkdir and trap.
-trap "rmdir '$lockdir'; exit 1" 1 2 15
-
-# Run the compile.
-"$@"
-ret=$?
-
-if test -f "$cofile"; then
-  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
-elif test -f "${cofile}bj"; then
-  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
-fi
-
-rmdir "$lockdir"
-exit $ret
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
diff --git a/scripts/depcomp b/scripts/depcomp
deleted file mode 100755 (executable)
index 4ebd5b3..0000000
+++ /dev/null
@@ -1,791 +0,0 @@
-#! /bin/sh
-# depcomp - compile a program generating dependencies as side-effects
-
-scriptversion=2013-05-30.07; # UTC
-
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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, see <http://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
-
-case $1 in
-  '')
-    echo "$0: No command.  Try '$0 --help' for more information." 1>&2
-    exit 1;
-    ;;
-  -h | --h*)
-    cat <<\EOF
-Usage: depcomp [--help] [--version] PROGRAM [ARGS]
-
-Run PROGRAMS ARGS to compile a file, generating dependencies
-as side-effects.
-
-Environment variables:
-  depmode     Dependency tracking mode.
-  source      Source file read by 'PROGRAMS ARGS'.
-  object      Object file output by 'PROGRAMS ARGS'.
-  DEPDIR      directory where to store dependencies.
-  depfile     Dependency file to output.
-  tmpdepfile  Temporary file to use when outputting dependencies.
-  libtool     Whether libtool is used (yes/no).
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
-    exit $?
-    ;;
-  -v | --v*)
-    echo "depcomp $scriptversion"
-    exit $?
-    ;;
-esac
-
-# Get the directory component of the given path, and save it in the
-# global variables '$dir'.  Note that this directory component will
-# be either empty or ending with a '/' character.  This is deliberate.
-set_dir_from ()
-{
-  case $1 in
-    */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
-      *) dir=;;
-  esac
-}
-
-# Get the suffix-stripped basename of the given path, and save it the
-# global variable '$base'.
-set_base_from ()
-{
-  base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
-}
-
-# If no dependency file was actually created by the compiler invocation,
-# we still have to create a dummy depfile, to avoid errors with the
-# Makefile "include basename.Plo" scheme.
-make_dummy_depfile ()
-{
-  echo "#dummy" > "$depfile"
-}
-
-# Factor out some common post-processing of the generated depfile.
-# Requires the auxiliary global variable '$tmpdepfile' to be set.
-aix_post_process_depfile ()
-{
-  # If the compiler actually managed to produce a dependency file,
-  # post-process it.
-  if test -f "$tmpdepfile"; then
-    # Each line is of the form 'foo.o: dependency.h'.
-    # Do two passes, one to just change these to
-    #   $object: dependency.h
-    # and one to simply output
-    #   dependency.h:
-    # which is needed to avoid the deleted-header problem.
-    { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
-      sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
-    } > "$depfile"
-    rm -f "$tmpdepfile"
-  else
-    make_dummy_depfile
-  fi
-}
-
-# A tabulation character.
-tab='  '
-# A newline character.
-nl='
-'
-# Character ranges might be problematic outside the C locale.
-# These definitions help.
-upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
-lower=abcdefghijklmnopqrstuvwxyz
-digits=0123456789
-alpha=${upper}${lower}
-
-if test -z "$depmode" || test -z "$source" || test -z "$object"; then
-  echo "depcomp: Variables source, object and depmode must be set" 1>&2
-  exit 1
-fi
-
-# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
-depfile=${depfile-`echo "$object" |
-  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
-tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
-
-rm -f "$tmpdepfile"
-
-# Avoid interferences from the environment.
-gccflag= dashmflag=
-
-# Some modes work just like other modes, but use different flags.  We
-# parameterize here, but still list the modes in the big case below,
-# to make depend.m4 easier to write.  Note that we *cannot* use a case
-# here, because this file can only contain one case statement.
-if test "$depmode" = hp; then
-  # HP compiler uses -M and no extra arg.
-  gccflag=-M
-  depmode=gcc
-fi
-
-if test "$depmode" = dashXmstdout; then
-  # This is just like dashmstdout with a different argument.
-  dashmflag=-xM
-  depmode=dashmstdout
-fi
-
-cygpath_u="cygpath -u -f -"
-if test "$depmode" = msvcmsys; then
-  # This is just like msvisualcpp but w/o cygpath translation.
-  # Just convert the backslash-escaped backslashes to single forward
-  # slashes to satisfy depend.m4
-  cygpath_u='sed s,\\\\,/,g'
-  depmode=msvisualcpp
-fi
-
-if test "$depmode" = msvc7msys; then
-  # This is just like msvc7 but w/o cygpath translation.
-  # Just convert the backslash-escaped backslashes to single forward
-  # slashes to satisfy depend.m4
-  cygpath_u='sed s,\\\\,/,g'
-  depmode=msvc7
-fi
-
-if test "$depmode" = xlc; then
-  # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
-  gccflag=-qmakedep=gcc,-MF
-  depmode=gcc
-fi
-
-case "$depmode" in
-gcc3)
-## gcc 3 implements dependency tracking that does exactly what
-## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
-## it if -MD -MP comes after the -MF stuff.  Hmm.
-## Unfortunately, FreeBSD c89 acceptance of flags depends upon
-## the command line argument order; so add the flags where they
-## appear in depend2.am.  Note that the slowdown incurred here
-## affects only configure: in makefiles, %FASTDEP% shortcuts this.
-  for arg
-  do
-    case $arg in
-    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
-    *)  set fnord "$@" "$arg" ;;
-    esac
-    shift # fnord
-    shift # $arg
-  done
-  "$@"
-  stat=$?
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  mv "$tmpdepfile" "$depfile"
-  ;;
-
-gcc)
-## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
-## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
-## (see the conditional assignment to $gccflag above).
-## There are various ways to get dependency output from gcc.  Here's
-## why we pick this rather obscure method:
-## - Don't want to use -MD because we'd like the dependencies to end
-##   up in a subdir.  Having to rename by hand is ugly.
-##   (We might end up doing this anyway to support other compilers.)
-## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-##   -MM, not -M (despite what the docs say).  Also, it might not be
-##   supported by the other compilers which use the 'gcc' depmode.
-## - Using -M directly means running the compiler twice (even worse
-##   than renaming).
-  if test -z "$gccflag"; then
-    gccflag=-MD,
-  fi
-  "$@" -Wp,"$gccflag$tmpdepfile"
-  stat=$?
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-  echo "$object : \\" > "$depfile"
-  # The second -e expression handles DOS-style file names with drive
-  # letters.
-  sed -e 's/^[^:]*: / /' \
-      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the "deleted header file" problem.
-## The problem is that when a header file which appears in a .P file
-## is deleted, the dependency causes make to die (because there is
-## typically no way to rebuild the header).  We avoid this by adding
-## dummy dependencies for each header file.  Too bad gcc doesn't do
-## this for us directly.
-## Some versions of gcc put a space before the ':'.  On the theory
-## that the space means something, we add a space to the output as
-## well.  hp depmode also adds that space, but also prefixes the VPATH
-## to the object.  Take care to not repeat it in the output.
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly.  Breaking it into two sed invocations is a workaround.
-  tr ' ' "$nl" < "$tmpdepfile" \
-    | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
-    | sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-hp)
-  # This case exists only to let depend.m4 do its work.  It works by
-  # looking at the text of this script.  This case will never be run,
-  # since it is checked for above.
-  exit 1
-  ;;
-
-sgi)
-  if test "$libtool" = yes; then
-    "$@" "-Wp,-MDupdate,$tmpdepfile"
-  else
-    "$@" -MDupdate "$tmpdepfile"
-  fi
-  stat=$?
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-
-  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
-    echo "$object : \\" > "$depfile"
-    # Clip off the initial element (the dependent).  Don't try to be
-    # clever and replace this with sed code, as IRIX sed won't handle
-    # lines with more than a fixed number of characters (4096 in
-    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
-    # the IRIX cc adds comments like '#:fec' to the end of the
-    # dependency line.
-    tr ' ' "$nl" < "$tmpdepfile" \
-      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
-      | tr "$nl" ' ' >> "$depfile"
-    echo >> "$depfile"
-    # The second pass generates a dummy entry for each header file.
-    tr ' ' "$nl" < "$tmpdepfile" \
-      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
-      >> "$depfile"
-  else
-    make_dummy_depfile
-  fi
-  rm -f "$tmpdepfile"
-  ;;
-
-xlc)
-  # This case exists only to let depend.m4 do its work.  It works by
-  # looking at the text of this script.  This case will never be run,
-  # since it is checked for above.
-  exit 1
-  ;;
-
-aix)
-  # The C for AIX Compiler uses -M and outputs the dependencies
-  # in a .u file.  In older versions, this file always lives in the
-  # current directory.  Also, the AIX compiler puts '$object:' at the
-  # start of each line; $object doesn't have directory information.
-  # Version 6 uses the directory in both cases.
-  set_dir_from "$object"
-  set_base_from "$object"
-  if test "$libtool" = yes; then
-    tmpdepfile1=$dir$base.u
-    tmpdepfile2=$base.u
-    tmpdepfile3=$dir.libs/$base.u
-    "$@" -Wc,-M
-  else
-    tmpdepfile1=$dir$base.u
-    tmpdepfile2=$dir$base.u
-    tmpdepfile3=$dir$base.u
-    "$@" -M
-  fi
-  stat=$?
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
-    exit $stat
-  fi
-
-  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
-  do
-    test -f "$tmpdepfile" && break
-  done
-  aix_post_process_depfile
-  ;;
-
-tcc)
-  # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
-  # FIXME: That version still under development at the moment of writing.
-  #        Make that this statement remains true also for stable, released
-  #        versions.
-  # It will wrap lines (doesn't matter whether long or short) with a
-  # trailing '\', as in:
-  #
-  #   foo.o : \
-  #    foo.c \
-  #    foo.h \
-  #
-  # It will put a trailing '\' even on the last line, and will use leading
-  # spaces rather than leading tabs (at least since its commit 0394caf7
-  # "Emit spaces for -MD").
-  "$@" -MD -MF "$tmpdepfile"
-  stat=$?
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-  # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
-  # We have to change lines of the first kind to '$object: \'.
-  sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
-  # And for each line of the second kind, we have to emit a 'dep.h:'
-  # dummy dependency, to avoid the deleted-header problem.
-  sed -n -e 's|^  *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-## The order of this option in the case statement is important, since the
-## shell code in configure will try each of these formats in the order
-## listed in this file.  A plain '-MD' option would be understood by many
-## compilers, so we must ensure this comes after the gcc and icc options.
-pgcc)
-  # Portland's C compiler understands '-MD'.
-  # Will always output deps to 'file.d' where file is the root name of the
-  # source file under compilation, even if file resides in a subdirectory.
-  # The object file name does not affect the name of the '.d' file.
-  # pgcc 10.2 will output
-  #    foo.o: sub/foo.c sub/foo.h
-  # and will wrap long lines using '\' :
-  #    foo.o: sub/foo.c ... \
-  #     sub/foo.h ... \
-  #     ...
-  set_dir_from "$object"
-  # Use the source, not the object, to determine the base name, since
-  # that's sadly what pgcc will do too.
-  set_base_from "$source"
-  tmpdepfile=$base.d
-
-  # For projects that build the same source file twice into different object
-  # files, the pgcc approach of using the *source* file root name can cause
-  # problems in parallel builds.  Use a locking strategy to avoid stomping on
-  # the same $tmpdepfile.
-  lockdir=$base.d-lock
-  trap "
-    echo '$0: caught signal, cleaning up...' >&2
-    rmdir '$lockdir'
-    exit 1
-  " 1 2 13 15
-  numtries=100
-  i=$numtries
-  while test $i -gt 0; do
-    # mkdir is a portable test-and-set.
-    if mkdir "$lockdir" 2>/dev/null; then
-      # This process acquired the lock.
-      "$@" -MD
-      stat=$?
-      # Release the lock.
-      rmdir "$lockdir"
-      break
-    else
-      # If the lock is being held by a different process, wait
-      # until the winning process is done or we timeout.
-      while test -d "$lockdir" && test $i -gt 0; do
-        sleep 1
-        i=`expr $i - 1`
-      done
-    fi
-    i=`expr $i - 1`
-  done
-  trap - 1 2 13 15
-  if test $i -le 0; then
-    echo "$0: failed to acquire lock after $numtries attempts" >&2
-    echo "$0: check lockdir '$lockdir'" >&2
-    exit 1
-  fi
-
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-  # Each line is of the form `foo.o: dependent.h',
-  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
-  # Do two passes, one to just change these to
-  # `$object: dependent.h' and one to simply `dependent.h:'.
-  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
-  # Some versions of the HPUX 10.20 sed can't process this invocation
-  # correctly.  Breaking it into two sed invocations is a workaround.
-  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
-    | sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-hp2)
-  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
-  # compilers, which have integrated preprocessors.  The correct option
-  # to use with these is +Maked; it writes dependencies to a file named
-  # 'foo.d', which lands next to the object file, wherever that
-  # happens to be.
-  # Much of this is similar to the tru64 case; see comments there.
-  set_dir_from  "$object"
-  set_base_from "$object"
-  if test "$libtool" = yes; then
-    tmpdepfile1=$dir$base.d
-    tmpdepfile2=$dir.libs/$base.d
-    "$@" -Wc,+Maked
-  else
-    tmpdepfile1=$dir$base.d
-    tmpdepfile2=$dir$base.d
-    "$@" +Maked
-  fi
-  stat=$?
-  if test $stat -ne 0; then
-     rm -f "$tmpdepfile1" "$tmpdepfile2"
-     exit $stat
-  fi
-
-  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
-  do
-    test -f "$tmpdepfile" && break
-  done
-  if test -f "$tmpdepfile"; then
-    sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
-    # Add 'dependent.h:' lines.
-    sed -ne '2,${
-               s/^ *//
-               s/ \\*$//
-               s/$/:/
-               p
-             }' "$tmpdepfile" >> "$depfile"
-  else
-    make_dummy_depfile
-  fi
-  rm -f "$tmpdepfile" "$tmpdepfile2"
-  ;;
-
-tru64)
-  # The Tru64 compiler uses -MD to generate dependencies as a side
-  # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
-  # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
-  # dependencies in 'foo.d' instead, so we check for that too.
-  # Subdirectories are respected.
-  set_dir_from  "$object"
-  set_base_from "$object"
-
-  if test "$libtool" = yes; then
-    # Libtool generates 2 separate objects for the 2 libraries.  These
-    # two compilations output dependencies in $dir.libs/$base.o.d and
-    # in $dir$base.o.d.  We have to check for both files, because
-    # one of the two compilations can be disabled.  We should prefer
-    # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
-    # automatically cleaned when .libs/ is deleted, while ignoring
-    # the former would cause a distcleancheck panic.
-    tmpdepfile1=$dir$base.o.d          # libtool 1.5
-    tmpdepfile2=$dir.libs/$base.o.d    # Likewise.
-    tmpdepfile3=$dir.libs/$base.d      # Compaq CCC V6.2-504
-    "$@" -Wc,-MD
-  else
-    tmpdepfile1=$dir$base.d
-    tmpdepfile2=$dir$base.d
-    tmpdepfile3=$dir$base.d
-    "$@" -MD
-  fi
-
-  stat=$?
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
-    exit $stat
-  fi
-
-  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
-  do
-    test -f "$tmpdepfile" && break
-  done
-  # Same post-processing that is required for AIX mode.
-  aix_post_process_depfile
-  ;;
-
-msvc7)
-  if test "$libtool" = yes; then
-    showIncludes=-Wc,-showIncludes
-  else
-    showIncludes=-showIncludes
-  fi
-  "$@" $showIncludes > "$tmpdepfile"
-  stat=$?
-  grep -v '^Note: including file: ' "$tmpdepfile"
-  if test $stat -ne 0; then
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-  echo "$object : \\" > "$depfile"
-  # The first sed program below extracts the file names and escapes
-  # backslashes for cygpath.  The second sed program outputs the file
-  # name when reading, but also accumulates all include files in the
-  # hold buffer in order to output them again at the end.  This only
-  # works with sed implementations that can handle large buffers.
-  sed < "$tmpdepfile" -n '
-/^Note: including file:  *\(.*\)/ {
-  s//\1/
-  s/\\/\\\\/g
-  p
-}' | $cygpath_u | sort -u | sed -n '
-s/ /\\ /g
-s/\(.*\)/'"$tab"'\1 \\/p
-s/.\(.*\) \\/\1:/
-H
-$ {
-  s/.*/'"$tab"'/
-  G
-  p
-}' >> "$depfile"
-  echo >> "$depfile" # make sure the fragment doesn't end with a backslash
-  rm -f "$tmpdepfile"
-  ;;
-
-msvc7msys)
-  # This case exists only to let depend.m4 do its work.  It works by
-  # looking at the text of this script.  This case will never be run,
-  # since it is checked for above.
-  exit 1
-  ;;
-
-#nosideeffect)
-  # This comment above is used by automake to tell side-effect
-  # dependency tracking mechanisms from slower ones.
-
-dashmstdout)
-  # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout, regardless of -o.
-  "$@" || exit $?
-
-  # Remove the call to Libtool.
-  if test "$libtool" = yes; then
-    while test "X$1" != 'X--mode=compile'; do
-      shift
-    done
-    shift
-  fi
-
-  # Remove '-o $object'.
-  IFS=" "
-  for arg
-  do
-    case $arg in
-    -o)
-      shift
-      ;;
-    $object)
-      shift
-      ;;
-    *)
-      set fnord "$@" "$arg"
-      shift # fnord
-      shift # $arg
-      ;;
-    esac
-  done
-
-  test -z "$dashmflag" && dashmflag=-M
-  # Require at least two characters before searching for ':'
-  # in the target name.  This is to cope with DOS-style filenames:
-  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
-  "$@" $dashmflag |
-    sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
-  rm -f "$depfile"
-  cat < "$tmpdepfile" > "$depfile"
-  # Some versions of the HPUX 10.20 sed can't process this sed invocation
-  # correctly.  Breaking it into two sed invocations is a workaround.
-  tr ' ' "$nl" < "$tmpdepfile" \
-    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
-    | sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-dashXmstdout)
-  # This case only exists to satisfy depend.m4.  It is never actually
-  # run, as this mode is specially recognized in the preamble.
-  exit 1
-  ;;
-
-makedepend)
-  "$@" || exit $?
-  # Remove any Libtool call
-  if test "$libtool" = yes; then
-    while test "X$1" != 'X--mode=compile'; do
-      shift
-    done
-    shift
-  fi
-  # X makedepend
-  shift
-  cleared=no eat=no
-  for arg
-  do
-    case $cleared in
-    no)
-      set ""; shift
-      cleared=yes ;;
-    esac
-    if test $eat = yes; then
-      eat=no
-      continue
-    fi
-    case "$arg" in
-    -D*|-I*)
-      set fnord "$@" "$arg"; shift ;;
-    # Strip any option that makedepend may not understand.  Remove
-    # the object too, otherwise makedepend will parse it as a source file.
-    -arch)
-      eat=yes ;;
-    -*|$object)
-      ;;
-    *)
-      set fnord "$@" "$arg"; shift ;;
-    esac
-  done
-  obj_suffix=`echo "$object" | sed 's/^.*\././'`
-  touch "$tmpdepfile"
-  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
-  rm -f "$depfile"
-  # makedepend may prepend the VPATH from the source file name to the object.
-  # No need to regex-escape $object, excess matching of '.' is harmless.
-  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
-  # Some versions of the HPUX 10.20 sed can't process the last invocation
-  # correctly.  Breaking it into two sed invocations is a workaround.
-  sed '1,2d' "$tmpdepfile" \
-    | tr ' ' "$nl" \
-    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
-    | sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile" "$tmpdepfile".bak
-  ;;
-
-cpp)
-  # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout.
-  "$@" || exit $?
-
-  # Remove the call to Libtool.
-  if test "$libtool" = yes; then
-    while test "X$1" != 'X--mode=compile'; do
-      shift
-    done
-    shift
-  fi
-
-  # Remove '-o $object'.
-  IFS=" "
-  for arg
-  do
-    case $arg in
-    -o)
-      shift
-      ;;
-    $object)
-      shift
-      ;;
-    *)
-      set fnord "$@" "$arg"
-      shift # fnord
-      shift # $arg
-      ;;
-    esac
-  done
-
-  "$@" -E \
-    | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-             -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-    | sed '$ s: \\$::' > "$tmpdepfile"
-  rm -f "$depfile"
-  echo "$object : \\" > "$depfile"
-  cat < "$tmpdepfile" >> "$depfile"
-  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-msvisualcpp)
-  # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout.
-  "$@" || exit $?
-
-  # Remove the call to Libtool.
-  if test "$libtool" = yes; then
-    while test "X$1" != 'X--mode=compile'; do
-      shift
-    done
-    shift
-  fi
-
-  IFS=" "
-  for arg
-  do
-    case "$arg" in
-    -o)
-      shift
-      ;;
-    $object)
-      shift
-      ;;
-    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
-        set fnord "$@"
-        shift
-        shift
-        ;;
-    *)
-        set fnord "$@" "$arg"
-        shift
-        shift
-        ;;
-    esac
-  done
-  "$@" -E 2>/dev/null |
-  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
-  rm -f "$depfile"
-  echo "$object : \\" > "$depfile"
-  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
-  echo "$tab" >> "$depfile"
-  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-msvcmsys)
-  # This case exists only to let depend.m4 do its work.  It works by
-  # looking at the text of this script.  This case will never be run,
-  # since it is checked for above.
-  exit 1
-  ;;
-
-none)
-  exec "$@"
-  ;;
-
-*)
-  echo "Unknown depmode $depmode" 1>&2
-  exit 1
-  ;;
-esac
-
-exit 0
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
diff --git a/scripts/git-log-fix b/scripts/git-log-fix
deleted file mode 100644 (file)
index e12b6ac..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is expected to be used via gitlog-to-changelog's --amend=FILE
-# option.  It specifies what changes to make to each given SHA1's commit
-# log and metadata, using Perl-eval'able expressions.
-
-8dff0096132fff70a5ee29a50222aebcd9b41ec7
-s/Conflicts:/--/
-
-d9d98c510b936d48755f8c01165d7efa32502d24
-# Fix old cherry-picked message.
-s/(fix wLangId in.*)/\1\n--/
-
-049b3d9ca0285d15c00c215ac9b533c994196ca4
-# Fix wrong author
-s/Ian Abbott.*>/Werner Koch <wk\@gnupg.org>/
diff --git a/scripts/missing b/scripts/missing
deleted file mode 100755 (executable)
index db98974..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-#! /bin/sh
-# Common wrapper for a few potentially missing GNU programs.
-
-scriptversion=2013-10-28.13; # UTC
-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
-# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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, see <http://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-if test $# -eq 0; then
-  echo 1>&2 "Try '$0 --help' for more information"
-  exit 1
-fi
-
-case $1 in
-
-  --is-lightweight)
-    # Used by our autoconf macros to check whether the available missing
-    # script is modern enough.
-    exit 0
-    ;;
-
-  --run)
-    # Back-compat with the calling convention used by older automake.
-    shift
-    ;;
-
-  -h|--h|--he|--hel|--help)
-    echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
-to PROGRAM being missing or too old.
-
-Options:
-  -h, --help      display this help and exit
-  -v, --version   output version information and exit
-
-Supported PROGRAM values:
-  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
-  bison     yacc      flex         lex       help2man
-
-Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
-'g' are ignored when checking the name.
-
-Send bug reports to <bug-automake@gnu.org>."
-    exit $?
-    ;;
-
-  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
-    echo "missing $scriptversion (GNU Automake)"
-    exit $?
-    ;;
-
-  -*)
-    echo 1>&2 "$0: unknown '$1' option"
-    echo 1>&2 "Try '$0 --help' for more information"
-    exit 1
-    ;;
-
-esac
-
-# Run the given program, remember its exit status.
-"$@"; st=$?
-
-# If it succeeded, we are done.
-test $st -eq 0 && exit 0
-
-# Also exit now if we it failed (or wasn't found), and '--version' was
-# passed; such an option is passed most likely to detect whether the
-# program is present and works.
-case $2 in --version|--help) exit $st;; esac
-
-# Exit code 63 means version mismatch.  This often happens when the user
-# tries to use an ancient version of a tool on a file that requires a
-# minimum version.
-if test $st -eq 63; then
-  msg="probably too old"
-elif test $st -eq 127; then
-  # Program was missing.
-  msg="missing on your system"
-else
-  # Program was found and executed, but failed.  Give up.
-  exit $st
-fi
-
-perl_URL=http://www.perl.org/
-flex_URL=http://flex.sourceforge.net/
-gnu_software_URL=http://www.gnu.org/software
-
-program_details ()
-{
-  case $1 in
-    aclocal|automake)
-      echo "The '$1' program is part of the GNU Automake package:"
-      echo "<$gnu_software_URL/automake>"
-      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
-      echo "<$gnu_software_URL/autoconf>"
-      echo "<$gnu_software_URL/m4/>"
-      echo "<$perl_URL>"
-      ;;
-    autoconf|autom4te|autoheader)
-      echo "The '$1' program is part of the GNU Autoconf package:"
-      echo "<$gnu_software_URL/autoconf/>"
-      echo "It also requires GNU m4 and Perl in order to run:"
-      echo "<$gnu_software_URL/m4/>"
-      echo "<$perl_URL>"
-      ;;
-  esac
-}
-
-give_advice ()
-{
-  # Normalize program name to check for.
-  normalized_program=`echo "$1" | sed '
-    s/^gnu-//; t
-    s/^gnu//; t
-    s/^g//; t'`
-
-  printf '%s\n' "'$1' is $msg."
-
-  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
-  case $normalized_program in
-    autoconf*)
-      echo "You should only need it if you modified 'configure.ac',"
-      echo "or m4 files included by it."
-      program_details 'autoconf'
-      ;;
-    autoheader*)
-      echo "You should only need it if you modified 'acconfig.h' or"
-      echo "$configure_deps."
-      program_details 'autoheader'
-      ;;
-    automake*)
-      echo "You should only need it if you modified 'Makefile.am' or"
-      echo "$configure_deps."
-      program_details 'automake'
-      ;;
-    aclocal*)
-      echo "You should only need it if you modified 'acinclude.m4' or"
-      echo "$configure_deps."
-      program_details 'aclocal'
-      ;;
-   autom4te*)
-      echo "You might have modified some maintainer files that require"
-      echo "the 'autom4te' program to be rebuilt."
-      program_details 'autom4te'
-      ;;
-    bison*|yacc*)
-      echo "You should only need it if you modified a '.y' file."
-      echo "You may want to install the GNU Bison package:"
-      echo "<$gnu_software_URL/bison/>"
-      ;;
-    lex*|flex*)
-      echo "You should only need it if you modified a '.l' file."
-      echo "You may want to install the Fast Lexical Analyzer package:"
-      echo "<$flex_URL>"
-      ;;
-    help2man*)
-      echo "You should only need it if you modified a dependency" \
-           "of a man page."
-      echo "You may want to install the GNU Help2man package:"
-      echo "<$gnu_software_URL/help2man/>"
-    ;;
-    makeinfo*)
-      echo "You should only need it if you modified a '.texi' file, or"
-      echo "any other file indirectly affecting the aspect of the manual."
-      echo "You might want to install the Texinfo package:"
-      echo "<$gnu_software_URL/texinfo/>"
-      echo "The spurious makeinfo call might also be the consequence of"
-      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
-      echo "want to install GNU make:"
-      echo "<$gnu_software_URL/make/>"
-      ;;
-    *)
-      echo "You might have modified some files without having the proper"
-      echo "tools for further handling them.  Check the 'README' file, it"
-      echo "often tells you about the needed prerequisites for installing"
-      echo "this package.  You may also peek at any GNU archive site, in"
-      echo "case some other package contains this missing '$1' program."
-      ;;
-  esac
-}
-
-give_advice "$1" | sed -e '1s/^/WARNING: /' \
-                       -e '2,$s/^/         /' >&2
-
-# Propagate the correct exit status (expected to be 127 for a program
-# not found, 63 for a program that failed due to version mismatch).
-exit $st
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
index 4efea96..4a4df86 100644 (file)
@@ -1,15 +1,23 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-09-20  Werner Koch  <wk@g10code.com>
 
-       * keydb.c (keydb_add_resource): Remove set but unused var
-       CREATED_FNAME.
-       * gpgsm.c (main): Remove set but used var FNAME.
+       * verify.c (gpgsm_verify): s/gcry_md_start_debug/gcry_md_debug/
+       in preparation for Libgcrypt 1.6.
+       * sign.c (gpgsm_sign): Ditto.
+       * certreqgen.c (create_request): Ditto.
+       * certcheck.c (gpgsm_check_cert_sig): Ditto.
+
+2011-08-10  Werner Koch  <wk@g10code.com>
+
+       * keydb.c (keydb_add_resource): Remove unsued var CREATED_FNAME.
+
+       * gpgsm.c (main): Remove unused var FNAME.
 
 2011-07-21  Werner Koch  <wk@g10code.com>
 
        (gpgsm_dirmngr_isvalid): Try to get the only-valid-if-cert-valid
        certificate from the dirmngr first.
 
+2011-06-01  Marcus Brinkmann  <mb@g10code.com>
+
+       * certreqgen.c (proc_parameters): Initialize RC.
+
+2011-04-25  Werner Koch  <wk@g10code.com>
+
+       * certlist.c (gpgsm_add_to_certlist): Mark classify_user_id for
+       use with non-OpenPGP.
+       (gpgsm_find_cert): Ditto.
+       * sign.c (get_default_signer): Ditto.
+       * keylist.c (list_internal_keys): Ditto.
+       * import.c (reimport_one): Ditto.
+       * export.c (gpgsm_export): Ditto.
+       * delete.c (delete_one): Ditto.
+
+2011-03-10  Werner Koch  <wk@g10code.com>
+
+       * minip12.c (oid_pkcs5PBKDF2, oid_pkcs5PBES2, oid_aes128_CBC): New.
+       (set_key_iv_pbes2): New.
+       (crypt_block): Add args IV and IVLEN.  Call set_key_iv_pbes2.
+       (decrypt_block): Add args IV and IVLEN.
+       (parse_bag_encrypted_data): Hack to support PBES2 data.
+       (parse_bag_data): Ditto.
+
+2011-03-03  Werner Koch  <wk@g10code.com>
+
+       * base64.c (base64_finish_write): Do not copy to radbuf to get rid
+       of a faulty gcc 4.4 "used uninitialized" warning.
+
+2011-03-01  Werner Koch  <wk@g10code.com>
+
+       * certreqgen.c (pSERIAL, pISSUERDN, pNOTBEFORE, pNOTAFTER)
+       (pSIGNINGKEY, pHASHALGO): New.
+       (reqgen_ctrl_s): Remove field WRITER.
+       (read_parameters): Support new keywords.  Change arg WRITER to
+       OUT_FP; pass that to proc_parameters.
+       (proc_parameters): Add arg WRITER.  Check values of new keywords.
+       Create writer object here.  Support generation of certificates.
+       (create_request): Take new arg SIGKEY.  Allow for hash algorithms
+       other than SHA-1.  Set serialno and other values for certificate
+       creation.
+       (gpgsm_genkey): Do not create writer object but pass output stream
+       to read_parameters.
+       * certreqgen-ui.c (gpgsm_gencertreq_tty): Ask for self-signed.
+       * misc.c (transform_sigval): New.
+
+2011-02-25  Werner Koch  <wk@g10code.com>
+
+       * certreqgen.c (create_request): Add arg SIGKEY.
+
+2010-11-25  Werner Koch  <wk@g10code.com>
+
+       * base64.c (gpgsm_create_writer): Remove arg FP which is not used
+       by any caller.  Change all callers.
+       (struct writer_cb_parm_s): Remove field FP.
+       (do_putc, do_fputs): Remove and replace callers by direct calls to
+       es_ functions.
+
+2010-11-23  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (gpgsm_LDADD): Add extra_bin_ldflags.
+
+2010-10-08  Werner Koch  <wk@g10code.com>
+
+       * gpgsm.c: Add option --with-keygrip.
+       * gpgsm.h (struct opt): Add WITH_KEYGRIP.
+       * keylist.c (list_cert_std): Implement option.
+
 2010-09-16  Werner Koch  <wk@g10code.com>
 
        * certchain.c (gpgsm_walk_cert_chain): Use GPG_ERR_MISSING_ISSUER_CERT.
        * import.c (check_and_store): Ditto.
        (check_and_store): Ditto.
 
-2010-05-12  Werner Koch  <wk@g10code.com>
+2010-08-16  Werner Koch  <wk@g10code.com>
 
-       * Makefile.am (gpgsm_LDADD): Include NETLIBS which is required for
-       Solaris.
+       * gpgsm.c (main) <aGPGConfList>: Use es_printf.
 
-2010-03-12  Werner Koch  <wk@g10code.com>
+       * call-dirmngr.c (start_dirmngr_ext): Use new start_new_dirmngr
+       function.
 
-       * server.c (cmd_passwd): New.  From trunk.
-       (register_commands): Register it.
+       * gpgsm.c: Mark option --prefer-system-dirmngr obsolete.
+       (main): Enable dirmngr by default.
 
-2010-02-11  Marcus Brinkmann  <marcus@g10code.de>
+       * gpgsm.h (struct opt): Remove field PREFER_SYSTEM_DIRMNGR.
 
-       From trunk 2009-09-23, 2009-11-02, 2009-11-04, 2009-11-05, 2009-11-25,
-       2009-12-08:
+       * server.c (gpgsm_server): Use dirmngr_socket_name instead of the
+       envvar for the hello line info.
 
-       * call-agent.c (membuf_data_cb, default_inq_cb)
-       (inq_ciphertext_cb, scd_serialno_status_cb)
-       (scd_keypairinfo_status_cb, istrusted_status_cb)
-       (learn_status_cb, learn_cb, keyinfo_status_cb): Return gpg_error_t.
-       * gpgsm.c (main): Update to new assuan API.
-       * server.c: Include "gpgsm.h" before <assuan.h> due to check for
-       GPG_ERR_SOURCE_DEFAULT and assuan.h now including gpg-error.h.
-       * server.c (reset_notify, input_notify, output_notify): Update to
-       new assuan interface.
-       (option_handler, cmd_recipient, cmd_signer, cmd_encrypt)
-       (cmd_decrypt, cmd_verify, cmd_sign, cmd_import, cmd_export)
-       (cmd_delkeys, cmd_message, cmd_listkeys, cmd_dumpkeys)
-       (cmd_listsecretkeys, cmd_dumpsecretkeys, cmd_genkey)
-       (cmd_getauditlog, cmd_getinfo): Return gpg_error_t instead of int.
-       (register_commands): Use assuan_handler_t.  Same for member HANDLER
-       in table.  Add NULL arg to assuan_register_command.  Add help arg to
-       assuan_register_command.  Provide help strings for all commands.
-       (gpgsm_server): Allocate assuan context before starting server.
-       Use assuan_fd_t and assuan_fdopen on fds.
-       * call-dirmngr.c (prepare_dirmngr): Check for CTX and error before
-       setting LDAPSERVER.
-       (start_dirmngr_ext): Allocate assuan context before starting
-       server.  Update use ofassuan_pipe_connect and assuan_socket_connect.
-       Convert posix fd to assuan fd.
-       (inq_certificate, isvalid_status_cb, lookup_cb, lookup_status_cb)
-       (run_command_cb, run_command_inq_cb, run_command_status_cb):
-       Return gpg_error_t instead of int.
+2010-06-21  Werner Koch  <wk@g10code.com>
+
+       * minip12.c (p12_build): Change arg CERT to const void ptr.
+       (build_cert_sequence): Change arg CERT to const ptr.
+
+       * gpgsm.c (main) <aExportSecretKeyP12>: Use to estream.
+       (open_fwrite): Removed.
+
+       * export.c: Include minip12.h.
+       (popen_protect_tool): Remove.
+       (export_p12): Use gpg-agent directly.  Change calling convention.
+       (gpgsm_p12_export): Adjust for that change.  Change arg FP to an
+       estream_t.
+       (do_putc): Remove.  Change callers to es_putc.
+       (do_fputs): Likewise.
+       (print_short_info): Remove arg FP.
+       * call-agent.c (gpgsm_agent_export_key): new.
+
+2010-06-17  Werner Koch  <wk@g10code.com>
+
+       * import.c (parse_p12): Remove arg retfp.  Use the agent's new
+       import command.
+       (import_one): Adjust call to pkcs12.
+       (store_cert_cb, rsa_key_check): New.
+       (popen_protect_tool): Remove.
+       * minip12.c (parse_bag_encrypted_data, p12_parse): Add arg
+       R_BADPASS.
+       * call-agent.c (gpgsm_agent_ask_passphrase): New.
+       (gpgsm_agent_keywrap_key): New.
+       (struct import_key_parm_s): New.
+       (gpgsm_agent_import_key): New.
+       * minip12.c, minip12.h: Move from ../agent/.
+       * Makefile.am (gpgsm_SOURCES): Add them.
+
+2010-06-11  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (cmd_message) [HAVE_W32CE_SYSTEM]: Finish pipe.
+
+2010-06-10  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (SERVER_STDIN, SERVER_STDOUT): New macros.
+       (gpgsm_server): Use them with assuan_fdopen.
+
+2010-04-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * certreqgen.c (read_parameters): Use ascii_isspace instead of
+       spacep to stop at newline, too.
+
+2010-04-14  Werner Koch  <wk@g10code.com>
+
+       * gpgsm.c (main) [W32CE]: Disable dirmngr for now.
+
+2010-04-13  Werner Koch  <wk@g10code.com>
+
+       * sign.c (gpgsm_sign): Do not check qualified status in
+       no-chain-validation mode.
+
+2010-04-08  Werner Koch  <wk@g10code.com>
+
+       * gpgsm.c (open_es_fread): Add arg mode.
+       (main) <aKeygen>: Call with mode "r" instead of "rb".
+
+2010-04-07  Werner Koch  <wk@g10code.com>
+
+       * misc.c: Remove setenv.h.  Include sysutils.h.
+       (setup_pinentry_env): s/setenv/gnupg_setenv/
+
+2010-03-24  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (gpgsm_LDADD): Add extra_sys_libs.
+
+2010-03-23  Werner Koch  <wk@g10code.com>
+
+       * qualified.c (gpgsm_is_in_qualified_list): Replace rewind by
+       fseek+clearerr.
+
+2010-03-22  Werner Koch  <wk@g10code.com>
+
+       * import.c (parse_p12): Use estream functions for the tmp streams.
+       * export.c (export_p12): Ditto.
+
+2010-03-11  Werner Koch  <wk@g10code.com>
+
+       * verify.c (gpgsm_verify): Use gpgsm_es_print_name.
+
+       * gpgsm.c: Include "asshelp.h".
+       (main): Remove assuan_set_assuan_log_prefix.  Add
+       assuan_set_log_cb.
+       * server.c (gpgsm_server): Remove assuan_set_log_stream.
+
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (common_libs): Remove libjnlib.a.  Change order.
+
+       * gpgsm.h: Remove "estream.h".
+
+2010-03-08  Werner Koch  <wk@g10code.com>
+
+       * certreqgen.c (gpgsm_genkey): Change OUT_FP to an estream_t
+       OUT_STREAM.
+       * certreqgen-ui.c (gpgsm_gencertreq_tty): ditto.
+
+       * server.c (cmd_genkey): Close IN_STREAM.
+
+       * server.c (cmd_encrypt, cmd_decrypt, cmd_verify, cmd_sign): Avoid
+       dup call by using es_fdopen_nc.
+       (do_listkeys): Use es_fdopen_nc instead of dup and es_fdopen.
+       (cmd_export): Ditto.
+       (cmd_genkey): Ditto.
+       * export.c (popen_protect_tool): Change OUTFILE to an estream_t.
+       (export_p12): Change OUTFP and arg RETFP to an estream_t.
+       (gpgsm_p12_export): Change DATAFP to an estream_t.
+       (gpgsm_export): Remove arg FP.
+       * import.c (import_one): Change CERTFP and arg FP to an estream_t.
+       (popen_protect_tool): Ditto for OUTFILE.
+       (parse_p12): Change CERTFP to an estream_t.
+       * sign.c (hash_data, hash_and_copy_data): Use estream.
+       (gpgsm_sign): Change arg OUT_FP to an estream_t.
+       * verify.c (gpgsm_verify): Rename FP to IN_FP.  Change FP and arg
+       OUT_FP to an estream_t.
+       (hash_data): Use estream.
+       * base64.c (struct reader_cb_parm_s): Change FP to an estream_t.
+       (gpgsm_create_reader): Ditto.
+       (simple_reader_cb, base64_reader_cb): Adjust accordingly.
+       * decrypt.c (gpgsm_decrypt): Change OUT_FP and IN_FP to an estream_t.
+       * encrypt.c (gpgsm_encrypt): Change OUT_FP to an estream_t.  Ditto
+       for DATA_FD.
+       (encrypt_cb): Use estream.
+       * gpgsm.c (main) <aEncr, aVerify, aSign, aDecrypt>: Use estream
+       functions.
+       (main) <aExport, aKeygen>: Use open_es_fwrite.
+
+2009-12-14  Werner Koch  <wk@g10code.com>
+
+       * server.c (cmd_passwd): New.
+       (register_commands): Register new command.
 
 2009-12-10  Werner Koch  <wk@g10code.com>
 
        * gpgsm.h (opt): Add field IGNORED_CERT_EXTENSIONS.
        * certchain.c (unknown_criticals): Handle ignored extensions,
 
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * keydb.c (keydb_search_kid): Fix code even that it is not used.
+       (classify_user_id): Adjust for change of u.kid type.
+       (keydb_classify_name): Replace GPG_ERR_INV_NAME by
+       GPG_ERR_INV_USER_ID.
+       (keydb_classify_name): Remove.  Replace all callers by
+       classify_user_id.
+
+2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       * call-dirmngr.c (start_dirmngr_ext): Convert posix fd to assuan fd.
+
 2009-12-03  Werner Koch  <wk@g10code.com>
 
-       From trunk:
+       * gpgsm.c (set_debug): Allow for numerical debug leveles.  Print
+       active debug flags.
+
+2009-12-02  Werner Koch  <wk@g10code.com>
 
        * verify.c (gpgsm_verify): Add audit info on hash algorithms.
+
        * sign.c (gpgsm_sign): Add audit log calls.
        (hash_data): Return an error indicator.
+
+2009-12-01  Werner Koch  <wk@g10code.com>
+
        * decrypt.c (gpgsm_decrypt): Add audit log calls.
 
        * gpgsm.c: New option --html-audit-log.
 
+2009-11-25  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (gpgsm_server): Use assuan_fd_t and assuan_fdopen on
+       fds.
+
+2009-11-23  Werner Koch  <wk@g10code.com>
+
+       * gpgsm.c (main) <aGpgConfList>: Add key "default_pubkey_algo".
+
+2009-11-10  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (cmd_getauditlog): Don't dup FD for es_fdopen_nc as
+       this leaks the FD here.
+
+2009-11-05  Marcus Brinkmann  <marcus@g10code.de>
+
+       * call-dirmngr.c (start_dirmngr_ext): Update use of
+       assuan_pipe_connect and assuan_socket_connect.
+
+2009-11-04  Werner Koch  <wk@g10code.com>
+
        * certreqgen.c (proc_parameters): Change fallback key length to
        2048.
-       * gpgsm.c (main) <aGpgConfList>: Add key "default_pubkey_algo".
 
-2009-12-03  Werner Koch  <wk@g10code.com>
+       * server.c (register_commands): Add help arg to
+       assuan_register_command.  Provide help strings for all commands.
 
-       * gpgsm.c (set_debug): Allow for numerical debug levels.  Print
-       active debug flags.
+2009-11-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * server.c (reset_notify, input_notify, output_notify): Update to
+       new assuan interface.
+       (register_commands): Use assuan_handler_t.
+       * call-agent.c (membuf_data_cb, default_inq_cb)
+       (inq_ciphertext_cb, scd_serialno_status_cb)
+       (scd_keypairinfo_status_cb, istrusted_status_cb)
+       (learn_status_cb, learn_cb, keyinfo_status_cb): Return gpg_error_t.
 
 2009-10-16  Werner Koch  <wk@g10code.com>
 
-       * gpgsm.c (DEFAULT_INCLUDE_CERTS): New.
-       (default_include_certs):  Init to -2.
+       * gpgsm.c (default_include_certs): Change to -2.
+       (DEFAULT_INCLUDE_CERTS): New.
+       (DEFAULT_CIPHER_ALGO): New.  Use instead of hardcoded "3DES".
+
+2009-09-30  Werner Koch  <wk@g10code.com>
+
+       * gpgsm.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING.
+
+2009-09-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgsm.c (main): Update to new assuan API.
+       * server.c: Include "gpgsm.h" before <assuan.h> due to check for
+       GPG_ERR_SOURCE_DEFAULT and assuan.h now including gpg-error.h.
+       (option_handler, cmd_recipient, cmd_signer, cmd_encrypt)
+       (cmd_decrypt, cmd_verify, cmd_sign, cmd_import, cmd_export)
+       (cmd_delkeys, cmd_message, cmd_listkeys, cmd_dumpkeys)
+       (cmd_listsecretkeys, cmd_dumpsecretkeys, cmd_genkey)
+       (cmd_getauditlog, cmd_getinfo): Return gpg_error_t instead of int.
+       (register_commands): Same for member HANDLER in table.
+       (gpgsm_server): Allocate assuan context before starting server.
+       * sm/call-dirmngr.c:
+       * call-dirmngr.c (prepare_dirmngr): Check for CTX and error before
+       setting LDAPSERVER.
+       (start_dirmngr_ext): Allocate assuan context before starting
+       server.
+       (inq_certificate, isvalid_status_cb, lookup_cb, lookup_status_cb)
+       (run_command_cb, run_command_inq_cb, run_command_status_cb):
+       Return gpg_error_t instead of int.
 
 2009-08-06  Werner Koch  <wk@g10code.com>
 
@@ -2693,8 +2952,8 @@ h2007-11-22  Werner Koch  <wk@g10code.com>
        * server.c (rc_to_assuan_status): New.  Use it for all commands.
 
 
- Copyright 2001, 2002, 2003, 2004, 2005, 2006,
-          2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+          2010, 2011 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
@@ -2703,3 +2962,7 @@ h2007-11-22  Werner Koch  <wk@g10code.com>
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 8e1dc97..12b85ab 100644 (file)
 
 ## Process this file with automake to produce Makefile.in
 
+EXTRA_DIST = ChangeLog-2011 gpgsm-w32info.rc
 
 bin_PROGRAMS = gpgsm
 
-EXTRA_DIST = ChangeLog-2011 gpgsm-w32info.rc
-
-AM_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) \
-            $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS)
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS)
 
 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl
 include $(top_srcdir)/am/cmacros.am
@@ -55,16 +53,17 @@ gpgsm_SOURCES = \
        delete.c \
        certreqgen.c \
        certreqgen-ui.c \
+       minip12.c minip12.h \
        qualified.c
 
 
-common_libs = $(libcommon) ../kbx/libkeybox.a ../jnlib/libjnlib.a \
-              ../gl/libgnu.a
+common_libs = ../kbx/libkeybox.a $(libcommon) ../gl/libgnu.a
 
-gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a  $(NETLIBS) \
+gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a \
               $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) \
-              $(GPG_ERROR_LIBS) $(LIBREADLINE) $(LIBINTL) $(ZLIBS) \
-             $(LIBICONV) $(resource_objs)
+              $(GPG_ERROR_LIBS) $(LIBREADLINE) $(LIBINTL) \
+             $(LIBICONV) $(resource_objs) $(extra_sys_libs)
+gpgsm_LDFLAGS = $(extra_bin_ldflags)
 
 # Make sure that all libs are build before we use them.  This is
 # important for things like make -j2.
index b0c8dc8..4a67d61 100644 (file)
@@ -1,5 +1,5 @@
-/* base64.c 
- *     Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+/* base64.c
+ * Copyright (C) 2001, 2003, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
   #define LF "\n"
 #endif
 
-/* data used by the reader callbacks */
-struct reader_cb_parm_s {
-  FILE *fp;
-  
+/* Data used by the reader callbacks.  */
+struct reader_cb_parm_s
+{
+  estream_t fp;
+
   unsigned char line[1024];
   int linelen;
   int readpos;
@@ -60,7 +61,7 @@ struct reader_cb_parm_s {
   int stop_seen;
   int might_be_smime;
 
-  int eof_seen;         
+  int eof_seen;
 
   struct {
     int idx;
@@ -69,13 +70,14 @@ struct reader_cb_parm_s {
   } base64;
 };
 
-/* data used by the writer callbacks */
-struct writer_cb_parm_s {
-  FILE *fp;            /* FP is only used if STREAM is NULL.  */
-  estream_t stream;    /* Alternative output if not NULL.  */
+
+/* Data used by the writer callbacks.  */
+struct writer_cb_parm_s
+{
+  estream_t stream;    /* Output stream.  */
 
   const char *pem_name;
-  
+
   int wrote_begin;
   int did_finish;
 
@@ -103,33 +105,33 @@ struct base64_context_s {
 
 
 /* The base-64 character list */
-static char bintoasc[64] = 
-       "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
-       "abcdefghijklmnopqrstuvwxyz" 
-       "0123456789+/"; 
+static char bintoasc[64] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+       "abcdefghijklmnopqrstuvwxyz"
+       "0123456789+/";
 /* The reverse base-64 list */
 static unsigned char asctobin[256] = {
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 
-  0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
-  0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 
-  0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 
-  0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 
-  0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
+  0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+  0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
+  0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+  0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+  0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff
 };
 
@@ -179,13 +181,13 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
       parm->have_lf = 0;
       for (n=0; n < DIM(parm->line);)
         {
-          c = getc (parm->fp);
+          c = es_getc (parm->fp);
           if (c == EOF)
             {
               parm->eof_seen = 1;
-              if (ferror (parm->fp))
+              if (es_ferror (parm->fp))
                 return -1;
-              break; 
+              break;
             }
           parm->line[n++] = c;
           if (c == '\n')
@@ -210,7 +212,7 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
             {
               /* wait for the header line */
               parm->linelen = parm->readpos = 0;
-              if (!parm->have_lf 
+              if (!parm->have_lf
                   || strncmp ((char*)parm->line, "-----BEGIN ", 11)
                   || !strncmp ((char*)parm->line+11, "PGP ", 4))
                 goto next;
@@ -272,14 +274,14 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
       parm->base64.stop_seen = 0;
       parm->base64.idx = 0;
     }
-  
+
 
   n = 0;
   if (parm->is_pem || parm->is_base64)
-    {  
+    {
       if (parm->is_pem && parm->have_lf
           && !strncmp ((char*)parm->line, "-----END ", 9))
-        { 
+        {
           parm->identified = 0;
           parm->linelen = parm->readpos = 0;
 
@@ -316,32 +318,32 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
               if (c == '=')
                 { /* pad character: stop */
                   if (idx == 1)
-                    buffer[n++] = val; 
+                    buffer[n++] = val;
                   parm->stop_seen = 1;
                   break;
                 }
-              if( (c = asctobin[(c2=c)]) == 255 ) 
+              if( (c = asctobin[(c2=c)]) == 255 )
                 {
                   log_error (_("invalid radix64 character %02x skipped\n"),
                              c2);
                   continue;
                 }
-              switch (idx) 
+              switch (idx)
                 {
-                case 0: 
+                case 0:
                   val = c << 2;
                   break;
-                case 1: 
+                case 1:
                   val |= (c>>4)&3;
                   buffer[n++] = val;
                   val = (c<<4)&0xf0;
                   break;
-                case 2: 
+                case 2:
                   val |= (c>>2)&15;
                   buffer[n++] = val;
                   val = (c<<6)&0xc0;
                   break;
-                case 3: 
+                case 3:
                   val |= c&0x3f;
                   buffer[n++] = val;
                   break;
@@ -382,14 +384,14 @@ simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
 
   for (n=0; n < count; n++)
     {
-      c = getc (parm->fp);
+      c = es_getc (parm->fp);
       if (c == EOF)
         {
           parm->eof_seen = 1;
-          if ( ferror (parm->fp) )
+          if (es_ferror (parm->fp))
             return -1;
           if (n)
-            break; /* return what we have before an EOF */
+            break; /* Return what we have before an EOF.  */
           return -1;
         }
       *(byte *)buffer++ = c;
@@ -402,27 +404,6 @@ simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
 
 
 \f
-/* Call either es_putc or the plain putc.  */
-static void
-do_putc (int value, FILE *fp, estream_t stream)
-{
-  if (stream)
-    es_putc (value, stream);
-  else
-    putc (value, fp);
-}
-
-/* Call either es_fputs or the plain fputs.  */
-static void
-do_fputs (const char *string, FILE *fp, estream_t stream)
-{
-  if (stream)
-    es_fputs (string, stream);
-  else
-    fputs (string, fp);
-}
-
-
 static int
 base64_writer_cb (void *cb_value, const void *buffer, size_t count)
 {
@@ -430,7 +411,6 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
   unsigned char radbuf[4];
   int i, c, idx, quad_count;
   const unsigned char *p;
-  FILE *fp = parm->fp;
   estream_t stream = parm->stream;
 
   if (!count)
@@ -440,9 +420,9 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
     {
       if (parm->pem_name)
         {
-          do_fputs ("-----BEGIN ", fp, stream);
-          do_fputs (parm->pem_name, fp, stream);
-          do_fputs ("-----\n", fp, stream);
+          es_fputs ("-----BEGIN ", stream);
+          es_fputs (parm->pem_name, stream);
+          es_fputs ("-----\n", stream);
         }
       parm->wrote_begin = 1;
       parm->base64.idx = 0;
@@ -461,16 +441,16 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
         {
           idx = 0;
           c = bintoasc[(*radbuf >> 2) & 077];
-          do_putc (c, fp, stream);
+          es_putc (c, stream);
           c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
-          do_putc (c, fp, stream);
+          es_putc (c, stream);
           c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
-          do_putc (c, fp, stream);
+          es_putc (c, stream);
           c = bintoasc[radbuf[2]&077];
-          do_putc (c, fp, stream);
-          if (++quad_count >= (64/4)) 
+          es_putc (c, stream);
+          if (++quad_count >= (64/4))
             {
-              do_fputs (LF, fp, stream);
+              es_fputs (LF, stream);
               quad_count = 0;
             }
         }
@@ -480,39 +460,32 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
   parm->base64.idx = idx;
   parm->base64.quad_count = quad_count;
 
-  return ((stream? es_ferror (stream) : ferror (fp)) 
-          ? gpg_error_from_syserror () 
-          : 0);
+  return es_ferror (stream)? gpg_error_from_syserror () : 0;
 }
 
+
 /* This callback is only used in stream mode.  Hiowever, we don't
    restrict it to this.  */
 static int
 plain_writer_cb (void *cb_value, const void *buffer, size_t count)
 {
   struct writer_cb_parm_s *parm = cb_value;
-  FILE *fp = parm->fp;
   estream_t stream = parm->stream;
 
   if (!count)
     return 0;
 
-  if (stream)
-    es_write (stream, buffer, count, NULL);
-  else
-    fwrite (buffer, count, 1, fp);
+  es_write (stream, buffer, count, NULL);
 
-  return ((stream? es_ferror (stream) : ferror (fp)) 
-          ? gpg_error_from_syserror () 
-          : 0);
+  return es_ferror (stream)? gpg_error_from_syserror () : 0;
 }
 
+
 static int
 base64_finish_write (struct writer_cb_parm_s *parm)
 {
-  unsigned char radbuf[4];
-  int i, c, idx, quad_count;
-  FILE *fp = parm->fp;
+  unsigned char *radbuf;
+  int c, idx, quad_count;
   estream_t stream = parm->stream;
 
   if (!parm->wrote_begin)
@@ -521,49 +494,46 @@ base64_finish_write (struct writer_cb_parm_s *parm)
   /* flush the base64 encoding */
   idx = parm->base64.idx;
   quad_count = parm->base64.quad_count;
-  for (i=0; i < idx; i++)
-    radbuf[i] = parm->base64.radbuf[i];
-
   if (idx)
     {
+      radbuf = parm->base64.radbuf;
+
       c = bintoasc[(*radbuf>>2)&077];
-      do_putc (c, fp, stream);
+      es_putc (c, stream);
       if (idx == 1)
         {
           c = bintoasc[((*radbuf << 4) & 060) & 077];
-          do_putc (c, fp, stream);
-          do_putc ('=', fp, stream);
-          do_putc ('=', fp, stream);
+          es_putc (c, stream);
+          es_putc ('=', stream);
+          es_putc ('=', stream);
         }
-      else 
-        { 
+      else
+        {
           c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
-          do_putc (c, fp, stream);
+          es_putc (c, stream);
           c = bintoasc[((radbuf[1] << 2) & 074) & 077];
-          do_putc (c, fp, stream);
-          do_putc ('=', fp, stream);
+          es_putc (c, stream);
+          es_putc ('=', stream);
 
         }
-      if (++quad_count >= (64/4)) 
+      if (++quad_count >= (64/4))
         {
-          do_fputs (LF, fp, stream);
+          es_fputs (LF, stream);
           quad_count = 0;
         }
     }
 
   if (quad_count)
-    do_fputs (LF, fp, stream);
+    es_fputs (LF, stream);
 
   if (parm->pem_name)
     {
-      do_fputs ("-----END ", fp, stream);
-      do_fputs (parm->pem_name, fp, stream);
-      do_fputs ("-----\n", fp, stream);
+      es_fputs ("-----END ", stream);
+      es_fputs (parm->pem_name, stream);
+      es_fputs ("-----\n", stream);
     }
 
-  return ((stream? es_ferror (stream) : ferror (fp)) 
-          ? gpg_error_from_syserror () 
-          : 0);
+  return es_ferror (stream)? gpg_error_from_syserror () : 0;
 }
 
 
@@ -579,7 +549,7 @@ base64_finish_write (struct writer_cb_parm_s *parm)
    until no more objects were found. */
 int
 gpgsm_create_reader (Base64Context *ctx,
-                     ctrl_t ctrl, FILE *fp, int allow_multi_pem,
+                     ctrl_t ctrl, estream_t fp, int allow_multi_pem,
                      ksba_reader_t *r_reader)
 {
   int rc;
@@ -643,21 +613,20 @@ gpgsm_destroy_reader (Base64Context ctx)
   if (!ctx)
     return;
 
-  ksba_reader_release (ctx->u2.reader);  
+  ksba_reader_release (ctx->u2.reader);
   xfree (ctx);
 }
 
 
 \f
-/* Create a writer for the given stream FP or STREAM.  Depending on
+/* Create a writer for the given STREAM.  Depending on
    the control information an output encoding is automagically
    choosen.  The function returns a Base64Context object which must be
    passed to the gpgme_destroy_writer function.  The created
    KsbaWriter object is also returned, but the caller must not call
-   the ksba_reader_release function on. */
+   the ksba_reader_release function on it. */
 int
-gpgsm_create_writer (Base64Context *ctx,
-                     ctrl_t ctrl, FILE *fp, estream_t stream,
+gpgsm_create_writer (Base64Context *ctx, ctrl_t ctrl, estream_t stream,
                      ksba_writer_t *r_writer)
 {
   int rc;
@@ -677,7 +646,6 @@ gpgsm_create_writer (Base64Context *ctx,
 
   if (ctrl->create_pem || ctrl->create_base64)
     {
-      (*ctx)->u.wparm.fp = fp;
       (*ctx)->u.wparm.stream = stream;
       if (ctrl->create_pem)
         (*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name
@@ -686,12 +654,11 @@ gpgsm_create_writer (Base64Context *ctx,
     }
   else if (stream)
     {
-      (*ctx)->u.wparm.fp = fp;
       (*ctx)->u.wparm.stream = stream;
       rc = ksba_writer_set_cb (w, plain_writer_cb, &(*ctx)->u.wparm);
     }
   else
-    rc = ksba_writer_set_file (w, fp);
+    rc = gpg_error (GPG_ERR_INV_ARG);
 
   if (rc)
     {
@@ -710,14 +677,14 @@ int
 gpgsm_finish_writer (Base64Context ctx)
 {
   struct writer_cb_parm_s *parm;
-  
+
   if (!ctx)
     return gpg_error (GPG_ERR_INV_VALUE);
   parm = &ctx->u.wparm;
   if (parm->did_finish)
     return 0; /* Already done. */
   parm->did_finish = 1;
-  if (!parm->fp && !parm->stream)
+  if (!parm->stream)
     return 0; /* Callback was not used.  */
   return base64_finish_write (parm);
 }
index 7eb16ed..f99caad 100644 (file)
@@ -1,6 +1,6 @@
 /* call-agent.c - Divert GPGSM operations to the agent
  * Copyright (C) 2001, 2002, 2003, 2005, 2007,
- *               2008, 2009 Free Software Foundation, Inc.
+ *               2008, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 #ifdef HAVE_LOCALE_H
@@ -66,6 +66,14 @@ struct learn_parm_s
   membuf_t *data;
 };
 
+struct import_key_parm_s
+{
+  ctrl_t ctrl;
+  assuan_context_t ctx;
+  const void *key;
+  size_t keylen;
+};
+
 
 \f
 /* Try to connect to the agent via socket or fork it off and work by
@@ -89,7 +97,7 @@ start_agent (ctrl_t ctrl)
                                 opt.session_env,
                                 opt.verbose, DBG_ASSUAN,
                                 gpgsm_status2, ctrl);
-      
+
       if (!rc)
         {
           /* Tell the agent that we support Pinentry notifications.  No
@@ -120,7 +128,7 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
     put_membuf (data, buffer, length);
   return 0;
 }
-  
+
 
 /* This is the default inquiry callback.  It mainly handles the
    Pinentry notifications.  */
@@ -130,16 +138,16 @@ default_inq_cb (void *opaque, const char *line)
   gpg_error_t err;
   ctrl_t ctrl = opaque;
 
-  if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
+  if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
     {
       err = gpgsm_proxy_pinentry_notify (ctrl, line);
       if (err)
-        log_error (_("failed to proxy %s inquiry to client\n"), 
+        log_error (_("failed to proxy %s inquiry to client\n"),
                    "PINENTRY_LAUNCHED");
       /* We do not pass errors to avoid breaking other code.  */
     }
   else
-    log_error ("ignoring gpg-agent inquiry `%s'\n", line);
+    log_error ("ignoring gpg-agent inquiry '%s'\n", line);
 
   return 0;
 }
@@ -241,7 +249,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
     case GCRY_MD_RMD160:hashopt = "--hash=rmd160"; break;
     case GCRY_MD_MD5:   hashopt = "--hash=md5"; break;
     case GCRY_MD_SHA256:hashopt = "--hash=sha256"; break;
-    default: 
+    default:
       return gpg_error (GPG_ERR_DIGEST_ALGO);
     }
 
@@ -300,14 +308,14 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
 
 \f
 /* Handle a CIPHERTEXT inquiry.  Note, we only send the data,
-   assuan_transact talkes care of flushing and writing the end */
+   assuan_transact takes care of flushing and writing the end */
 static gpg_error_t
 inq_ciphertext_cb (void *opaque, const char *line)
 {
-  struct cipher_parm_s *parm = opaque; 
+  struct cipher_parm_s *parm = opaque;
   int rc;
 
-  if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
+  if (has_leading_keyword (line, "CIPHERTEXT"))
     {
       assuan_begin_confidential (parm->ctx);
       rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen);
@@ -316,7 +324,7 @@ inq_ciphertext_cb (void *opaque, const char *line)
   else
     rc = default_inq_cb (parm->ctrl, line);
 
-  return rc; 
+  return rc;
 }
 
 
@@ -324,7 +332,7 @@ inq_ciphertext_cb (void *opaque, const char *line)
    the hex string KEYGRIP. */
 int
 gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
-                       ksba_const_sexp_t ciphertext, 
+                       ksba_const_sexp_t ciphertext,
                        char **r_buf, size_t *r_buflen )
 {
   int rc;
@@ -334,7 +342,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
   size_t n, len;
   char *p, *buf, *endp;
   size_t ciphertextlen;
-  
+
   if (!keygrip || strlen(keygrip) != 40 || !ciphertext || !r_buf || !r_buflen)
     return gpg_error (GPG_ERR_INV_VALUE);
   *r_buf = NULL;
@@ -409,7 +417,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
   endp++;
   if (endp-p+n > len)
     return gpg_error (GPG_ERR_INV_SEXP); /* Oops: Inconsistent S-Exp. */
-  
+
   memmove (buf, endp, n);
 
   *r_buflen = n;
@@ -426,17 +434,17 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
 static gpg_error_t
 inq_genkey_parms (void *opaque, const char *line)
 {
-  struct genkey_parm_s *parm = opaque; 
+  struct genkey_parm_s *parm = opaque;
   int rc;
 
-  if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
+  if (has_leading_keyword (line, "KEYPARAM"))
     {
       rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
     }
   else
     rc = default_inq_cb (parm->ctrl, line);
 
-  return rc; 
+  return rc;
 }
 
 
@@ -469,7 +477,7 @@ gpgsm_agent_genkey (ctrl_t ctrl,
   if (!gk_parm.sexplen)
     return gpg_error (GPG_ERR_INV_VALUE);
   rc = assuan_transact (agent_ctx, "GENKEY",
-                        membuf_data_cb, &data, 
+                        membuf_data_cb, &data,
                         inq_genkey_parms, &gk_parm, NULL, NULL);
   if (rc)
     {
@@ -518,7 +526,7 @@ gpgsm_agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
 
   init_membuf (&data, 1024);
   rc = assuan_transact (agent_ctx, line,
-                        membuf_data_cb, &data, 
+                        membuf_data_cb, &data,
                         default_inq_cb, ctrl, NULL, NULL);
   if (rc)
     {
@@ -589,7 +597,7 @@ gpgsm_agent_scd_serialno (ctrl_t ctrl, char **r_serialno)
 {
   int rc;
   char *serialno = NULL;
+
   *r_serialno = NULL;
   rc = start_agent (ctrl);
   if (rc)
@@ -658,7 +666,7 @@ gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
 {
   int rc;
   strlist_t list = NULL;
+
   *r_list = NULL;
   rc = start_agent (ctrl);
   if (rc)
@@ -685,14 +693,14 @@ static gpg_error_t
 istrusted_status_cb (void *opaque, const char *line)
 {
   struct rootca_flags_s *flags = opaque;
+  const char *s;
 
-  if (!strncmp (line, "TRUSTLISTFLAG", 13) && (line[13]==' ' || !line[13]))
+  if ((s = has_leading_keyword (line, "TRUSTLISTFLAG")))
     {
-      for (line += 13; *line == ' '; line++)
-        ;
-      if (!strncmp (line, "relax", 5) && (line[5] == ' ' || !line[5]))
+      line = s;
+      if (has_leading_keyword (line, "relax"))
         flags->relax = 1;
-      else if (!strncmp (line, "cm", 2) && (line[2] == ' ' || !line[2]))
+      else if (has_leading_keyword (line, "cm"))
         flags->chain_model = 1;
     }
   return 0;
@@ -735,7 +743,7 @@ gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert, const char *hexfpr,
           log_error ("error getting the fingerprint\n");
           return gpg_error (GPG_ERR_GENERAL);
         }
-      
+
       snprintf (line, DIM(line)-1, "ISTRUSTED %s", fpr);
       line[DIM(line)-1] = 0;
       xfree (fpr);
@@ -816,14 +824,14 @@ static gpg_error_t
 learn_status_cb (void *opaque, const char *line)
 {
   struct learn_parm_s *parm = opaque;
+  const char *s;
 
   /* Pass progress data to the caller.  */
-  if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
+  if ((s = has_leading_keyword (line, "PROGRESS")))
     {
+      line = s;
       if (parm->ctrl)
         {
-          for (line += 8; *line == ' '; line++)
-            ;
           if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
             return gpg_error (GPG_ERR_ASS_CANCELED);
         }
@@ -899,7 +907,7 @@ learn_cb (void *opaque, const void *buffer, size_t length)
   init_membuf (parm->data, 4096);
   return 0;
 }
-  
+
 /* Call the agent to learn about a smartcard */
 int
 gpgsm_agent_learn (ctrl_t ctrl)
@@ -919,8 +927,8 @@ gpgsm_agent_learn (ctrl_t ctrl)
   learn_parm.ctx = agent_ctx;
   learn_parm.data = &data;
   rc = assuan_transact (agent_ctx, "LEARN --send",
-                        learn_cb, &learn_parm, 
-                        NULL, NULL, 
+                        learn_cb, &learn_parm,
+                        NULL, NULL,
                         learn_status_cb, &learn_parm);
   xfree (get_membuf (&data, &len));
   if (rc)
@@ -1009,9 +1017,9 @@ keyinfo_status_cb (void *opaque, const char *line)
   char **serialno = opaque;
   const char *s, *s2;
 
-  if (!strncmp (line, "KEYINFO ", 8) && !*serialno)
+  if ((s = has_leading_keyword (line, "KEYINFO")) && !*serialno)
     {
-      s = strchr (line+8, ' ');
+      s = strchr (s, ' ');
       if (s && s[1] == 'T' && s[2] == ' ' && s[3])
         {
           s += 3;
@@ -1067,3 +1075,183 @@ gpgsm_agent_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
   return err;
 }
 
+
+\f
+/* Ask for the passphrase (this is used for pkcs#12 import/export.  On
+   success the caller needs to free the string stored at R_PASSPHRASE.
+   On error NULL will be stored at R_PASSPHRASE and an appropriate
+   error code returned.  If REPEAT is true the agent tries to get a
+   new passphrase (i.e. asks the user to confirm it).  */
+gpg_error_t
+gpgsm_agent_ask_passphrase (ctrl_t ctrl, const char *desc_msg, int repeat,
+                            char **r_passphrase)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  char *arg4 = NULL;
+  membuf_t data;
+
+  *r_passphrase = NULL;
+
+  err = start_agent (ctrl);
+  if (err)
+    return err;
+
+  if (desc_msg && *desc_msg && !(arg4 = percent_plus_escape (desc_msg)))
+    return gpg_error_from_syserror ();
+
+  snprintf (line, DIM(line)-1, "GET_PASSPHRASE --data%s -- X X X %s",
+            repeat? " --repeat=1 --check --qualitybar":"",
+            arg4);
+  xfree (arg4);
+
+  init_membuf_secure (&data, 64);
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         default_inq_cb, NULL, NULL, NULL);
+
+  if (err)
+    xfree (get_membuf (&data, NULL));
+  else
+    {
+      put_membuf (&data, "", 1);
+      *r_passphrase = get_membuf (&data, NULL);
+      if (!*r_passphrase)
+        err = gpg_error_from_syserror ();
+    }
+  return err;
+}
+
+
+\f
+/* Retrieve a key encryption key from the agent.  With FOREXPORT true
+   the key shall be use for export, with false for import.  On success
+   the new key is stored at R_KEY and its length at R_KEKLEN.  */
+gpg_error_t
+gpgsm_agent_keywrap_key (ctrl_t ctrl, int forexport,
+                         void **r_kek, size_t *r_keklen)
+{
+  gpg_error_t err;
+  membuf_t data;
+  size_t len;
+  unsigned char *buf;
+  char line[ASSUAN_LINELENGTH];
+
+  *r_kek = NULL;
+  err = start_agent (ctrl);
+  if (err)
+    return err;
+
+  snprintf (line, DIM(line)-1, "KEYWRAP_KEY %s",
+            forexport? "--export":"--import");
+
+  init_membuf_secure (&data, 64);
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         default_inq_cb, ctrl, NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  *r_kek = buf;
+  *r_keklen = len;
+  return 0;
+}
+
+
+
+\f
+/* Handle the inquiry for an IMPORT_KEY command.  */
+static gpg_error_t
+inq_import_key_parms (void *opaque, const char *line)
+{
+  struct import_key_parm_s *parm = opaque;
+  gpg_error_t err;
+
+  if (has_leading_keyword (line, "KEYDATA"))
+    {
+      assuan_begin_confidential (parm->ctx);
+      err = assuan_send_data (parm->ctx, parm->key, parm->keylen);
+      assuan_end_confidential (parm->ctx);
+    }
+  else
+    err = default_inq_cb (parm->ctrl, line);
+
+  return err;
+}
+
+
+/* Call the agent to import a key into the agent.  */
+gpg_error_t
+gpgsm_agent_import_key (ctrl_t ctrl, const void *key, size_t keylen)
+{
+  gpg_error_t err;
+  struct import_key_parm_s parm;
+
+  err = start_agent (ctrl);
+  if (err)
+    return err;
+
+  parm.ctrl   = ctrl;
+  parm.ctx    = agent_ctx;
+  parm.key    = key;
+  parm.keylen = keylen;
+
+  err = assuan_transact (agent_ctx, "IMPORT_KEY",
+                         NULL, NULL, inq_import_key_parms, &parm, NULL, NULL);
+  return err;
+}
+
+
+\f
+/* Receive a secret key from the agent.  KEYGRIP is the hexified
+   keygrip, DESC a prompt to be displayed with the agent's passphrase
+   question (needs to be plus+percent escaped).  On success the key is
+   stored as a canonical S-expression at R_RESULT and R_RESULTLEN. */
+gpg_error_t
+gpgsm_agent_export_key (ctrl_t ctrl, const char *keygrip, const char *desc,
+                        unsigned char **r_result, size_t *r_resultlen)
+{
+  gpg_error_t err;
+  membuf_t data;
+  size_t len;
+  unsigned char *buf;
+  char line[ASSUAN_LINELENGTH];
+
+  *r_result = NULL;
+
+  err = start_agent (ctrl);
+  if (err)
+    return err;
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      err = assuan_transact (agent_ctx, line,
+                             NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  snprintf (line, DIM(line)-1, "EXPORT_KEY %s", keygrip);
+
+  init_membuf_secure (&data, 1024);
+  err = assuan_transact (agent_ctx, line,
+                         membuf_data_cb, &data,
+                         default_inq_cb, ctrl, NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    return gpg_error_from_syserror ();
+  *r_result = buf;
+  *r_resultlen = len;
+  return 0;
+}
index 6540a8f..99a14c0 100644 (file)
@@ -1,5 +1,6 @@
-/* call-dirmngr.c - communication with the dromngr
- * Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
+/* call-dirmngr.c - Communication with the dirmngr
+ * Copyright (C) 2002, 2003, 2005, 2007, 2008,
+ *               2010  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -33,6 +34,7 @@
 
 #include "i18n.h"
 #include "keydb.h"
+#include "asshelp.h"
 
 
 struct membuf {
@@ -52,8 +54,6 @@ static assuan_context_t dirmngr2_ctx = NULL;
 static int dirmngr_ctx_locked;
 static int dirmngr2_ctx_locked;
 
-static int force_pipe_server = 0;
-
 struct inq_certificate_parm_s {
   ctrl_t ctrl;
   assuan_context_t ctx;
@@ -191,15 +191,12 @@ prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
 
 
 \f
-/* Try to connect to the agent via socket or fork it off and work by
-   pipes.  Handle the server's initial greeting */
-static int
+/* Return a new assuan context for a Dirmngr connection.  */
+static gpg_error_t
 start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
 {
-  int rc;
-  char *infostr, *p;
-  assuan_context_t ctx = NULL;
-  int try_default = 0;
+  gpg_error_t err;
+  assuan_context_t ctx;
 
   if (opt.disable_dirmngr)
     return gpg_error (GPG_ERR_NO_DIRMNGR);
@@ -210,129 +207,15 @@ start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
   /* Note: if you change this to multiple connections, you also need
      to take care of the implicit option sending caching. */
 
-#ifdef HAVE_W32_SYSTEM
-  infostr = NULL;
-  opt.prefer_system_dirmngr = 1;
-#else
-  infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO");
-#endif /*HAVE_W32_SYSTEM*/
-  if (infostr && !*infostr)
-    infostr = NULL;
-  else if (infostr)
-    infostr = xstrdup (infostr);
-
-  if (opt.prefer_system_dirmngr && !force_pipe_server && !infostr)
-    {
-      infostr = xstrdup (dirmngr_socket_name ());
-      try_default = 1;
-    }
-
-  rc = assuan_new (&ctx);
-  if (rc)
-    {
-      log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
-      return rc;
-    }
-
-  if (!infostr)
-    {
-      const char *pgmname;
-      const char *argv[3];
-      int no_close_list[3];
-      int i;
-
-      if (!opt.dirmngr_program || !*opt.dirmngr_program)
-        opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
-      if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
-        pgmname = opt.dirmngr_program;
-      else
-        pgmname++;
-
-      if (opt.verbose)
-        log_info (_("no running dirmngr - starting `%s'\n"),
-                  opt.dirmngr_program);
-
-      if (fflush (NULL))
-        {
-          gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
-          log_error ("error flushing pending output: %s\n", strerror (errno));
-          return tmperr;
-        }
-
-      argv[0] = pgmname;
-      argv[1] = "--server";
-      argv[2] = NULL;
-
-      i=0;
-      if (log_get_fd () != -1)
-        no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
-      no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
-      no_close_list[i] = -1;
-
-      /* connect to the agent and perform initial handshaking */
-      rc = assuan_pipe_connect (ctx, opt.dirmngr_program, argv,
-                                no_close_list, NULL, NULL, 0);
-    }
-  else
-    {
-      int prot;
-      int pid;
-
-      if (!try_default)
-        {
-          if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
-            {
-              log_error (_("malformed DIRMNGR_INFO environment variable\n"));
-              xfree (infostr);
-              force_pipe_server = 1;
-              return start_dirmngr_ext (ctrl, ctx_r);
-            }
-          *p++ = 0;
-          pid = atoi (p);
-          while (*p && *p != PATHSEP_C)
-            p++;
-          prot = *p? atoi (p+1) : 0;
-          if (prot != 1)
-            {
-              log_error (_("dirmngr protocol version %d is not supported\n"),
-                         prot);
-              xfree (infostr);
-              force_pipe_server = 1;
-              return start_dirmngr_ext (ctrl, ctx_r);
-            }
-        }
-      else
-        pid = -1;
-
-      rc = assuan_socket_connect (ctx, infostr, pid, 0);
-#ifdef HAVE_W32_SYSTEM
-      if (rc)
-        log_debug ("connecting dirmngr at `%s' failed\n", infostr);
-#endif
-
-      xfree (infostr);
-#ifndef HAVE_W32_SYSTEM
-      if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
-        {
-          log_info (_("can't connect to the dirmngr - trying fall back\n"));
-          force_pipe_server = 1;
-          return start_dirmngr_ext (ctrl, ctx_r);
-        }
-#endif /*!HAVE_W32_SYSTEM*/
-    }
-
-  prepare_dirmngr (ctrl, ctx, rc);
+  err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT,
+                           opt.homedir, opt.dirmngr_program,
+                           opt.verbose, DBG_ASSUAN,
+                           gpgsm_status2, ctrl);
+  prepare_dirmngr (ctrl, ctx, err);
+  if (err)
+    return err;
 
-  if (rc)
-    {
-      assuan_release (ctx);
-      log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc));
-      return gpg_error (GPG_ERR_NO_DIRMNGR);
-    }
   *ctx_r = ctx;
-
-  if (DBG_ASSUAN)
-    log_debug ("connection to dirmngr established\n");
   return 0;
 }
 
@@ -399,47 +282,40 @@ static gpg_error_t
 inq_certificate (void *opaque, const char *line)
 {
   struct inq_certificate_parm_s *parm = opaque;
+  const char *s;
   int rc;
+  size_t n;
   const unsigned char *der;
   size_t derlen;
   int issuer_mode = 0;
   ksba_sexp_t ski = NULL;
 
-  if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
+  if ((s = has_leading_keyword (line, "SENDCERT")))
     {
-      line += 8;
+      line = s;
     }
-  else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12]))
+  else if ((s = has_leading_keyword (line, "SENDCERT_SKI")))
     {
-      size_t n;
-
       /* Send a certificate where a sourceKeyIdentifier is included. */
-      line += 12;
-      while (*line == ' ')
-        line++;
+      line = s;
       ski = make_simple_sexp_from_hexstr (line, &n);
       line += n;
       while (*line == ' ')
         line++;
     }
-  else if (!strncmp (line, "SENDISSUERCERT", 14)
-           && (line[14] == ' ' || !line[14]))
+  else if ((s = has_leading_keyword (line, "SENDISSUERCERT")))
     {
-      line += 14;
+      line = s;
       issuer_mode = 1;
     }
-  else if (!strncmp (line, "ISTRUSTED", 9) && (line[9]==' ' || !line[9]))
+  else if ((s = has_leading_keyword (line, "ISTRUSTED")))
     {
       /* The server is asking us whether the certificate is a trusted
          root certificate.  */
-      const char *s;
-      size_t n;
       char fpr[41];
       struct rootca_flags_s rootca_flags;
 
-      line += 9;
-      while (*line == ' ')
-        line++;
+      line = s;
 
       for (s=line,n=0; hexdigitp (s); s++, n++)
         ;
@@ -457,7 +333,7 @@ inq_certificate (void *opaque, const char *line)
     }
   else
     {
-      log_error ("unsupported inquiry `%s'\n", line);
+      log_error ("unsupported inquiry '%s'\n", line);
       return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
     }
 
@@ -527,22 +403,21 @@ static gpg_error_t
 isvalid_status_cb (void *opaque, const char *line)
 {
   struct isvalid_status_parm_s *parm = opaque;
+  const char *s;
 
-  if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
+  if ((s = has_leading_keyword (line, "PROGRESS")))
     {
       if (parm->ctrl)
         {
-          for (line += 8; *line == ' '; line++)
-            ;
+          line = s;
           if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
             return gpg_error (GPG_ERR_ASS_CANCELED);
         }
     }
-  else if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24)
-      && (line[24]==' ' || !line[24]))
+  else if ((s = has_leading_keyword (line, "ONLY_VALID_IF_CERT_VALID")))
     {
       parm->seen++;
-      if (!line[24] || !unhexify_fpr (line+25, parm->fpr))
+      if (!*s || !unhexify_fpr (s, parm->fpr))
         parm->seen++; /* Bumb it to indicate an error. */
     }
   return 0;
@@ -810,23 +685,22 @@ static gpg_error_t
 lookup_status_cb (void *opaque, const char *line)
 {
   struct lookup_parm_s *parm = opaque;
+  const char *s;
 
-  if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
+  if ((s = has_leading_keyword (line, "PROGRESS")))
     {
       if (parm->ctrl)
         {
-          for (line += 8; *line == ' '; line++)
-            ;
+          line = s;
           if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
             return gpg_error (GPG_ERR_ASS_CANCELED);
         }
     }
-  else if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
+  else if ((s = has_leading_keyword (line, "TRUNCATED")))
     {
       if (parm->ctrl)
         {
-          for (line +=9; *line == ' '; line++)
-            ;
+          line = s;
           gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
         }
     }
@@ -933,13 +807,13 @@ get_cached_cert (assuan_context_t ctx,
   char hexfpr[2*20+1];
   struct membuf mb;
   char *buf;
-  size_t buflen;
+  size_t buflen = 0;
   ksba_cert_t cert;
 
   *r_cert = NULL;
 
   bin2hex (fpr, 20, hexfpr);
-  snprintf (line, DIM(line)-1, "LOOKUP --single --cache-only 0x%s", hexfpr);
+  snprintf (line, DIM(line)-1, "LOOKUP --signle --cache-only 0x%s", hexfpr);
 
   init_membuf (&mb, 4096);
   err = assuan_transact (ctx, line, get_cached_cert_data_cb, &mb,
@@ -995,16 +869,17 @@ static gpg_error_t
 run_command_inq_cb (void *opaque, const char *line)
 {
   struct run_command_parm_s *parm = opaque;
+  const char *s;
   int rc = 0;
 
-  if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) )
+  if ((s = has_leading_keyword (line, "SENDCERT")))
     { /* send the given certificate */
       int err;
       ksba_cert_t cert;
       const unsigned char *der;
       size_t derlen;
 
-      line += 8;
+      line = s;
       if (!*line)
         return gpg_error (GPG_ERR_ASS_PARAMETER);
 
@@ -1024,14 +899,14 @@ run_command_inq_cb (void *opaque, const char *line)
           ksba_cert_release (cert);
         }
     }
-  else if ( !strncmp (line, "PRINTINFO", 9) && (line[9] == ' ' || !line[9]) )
+  else if ((s = has_leading_keyword (line, "PRINTINFO")))
     { /* Simply show the message given in the argument. */
-      line += 9;
+      line = s;
       log_info ("dirmngr: %s\n", line);
     }
   else
     {
-      log_error ("unsupported inquiry `%s'\n", line);
+      log_error ("unsupported inquiry '%s'\n", line);
       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
     }
 
@@ -1042,17 +917,17 @@ static gpg_error_t
 run_command_status_cb (void *opaque, const char *line)
 {
   ctrl_t ctrl = opaque;
+  const char *s;
 
   if (opt.verbose)
     {
       log_info ("dirmngr status: %s\n", line);
     }
-  if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
+  if ((s = has_leading_keyword (line, "PROGRESS")))
     {
       if (ctrl)
         {
-          for (line += 8; *line == ' '; line++)
-            ;
+          line = s;
           if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
             return gpg_error (GPG_ERR_ASS_CANCELED);
         }
index 1fbe9ca..5e632f7 100644 (file)
@@ -1,6 +1,6 @@
 /* certchain.c - certificate chain validation
  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- *               2006, 2007, 2008 Free Software Foundation, Inc.
+ *               2006, 2007, 2008, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -241,9 +241,9 @@ unknown_criticals (ksba_cert_t cert, int listmode, estream_t fp)
         ;
       unsupported = !known[i];
 
-      /* If this critical extension is not supoported, check the list
-         of to be ignored extensions to se whether we claim that it is
-         supported.  */
+      /* If this critical extension is not supported.  Check the list
+         of to be ignored extensions to see whether we claim that it
+         is supported.  */
       if (unsupported && opt.ignored_cert_extensions)
         {
           for (sl=opt.ignored_cert_extensions;
@@ -342,7 +342,7 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist)
   if (!fp)
     {
       if (opt.verbose || errno != ENOENT)
-        log_info (_("failed to open `%s': %s\n"),
+        log_info (_("failed to open '%s': %s\n"),
                   opt.policy_file, strerror (errno));
       xfree (policies);
       /* With no critical policies this is only a warning */
@@ -350,7 +350,7 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist)
         {
           if (!opt.quiet)
             do_list (0, listmode, fplist,
-                     _("note: non-critical certificate policy not allowed"));
+                     _("Note: non-critical certificate policy not allowed"));
           return 0;
         }
       do_list (1, listmode, fplist,
@@ -379,7 +379,7 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist)
                   if (!any_critical)
                     {
                       do_list (0, listmode, fplist,
-                     _("note: non-critical certificate policy not allowed"));
+                     _("Note: non-critical certificate policy not allowed"));
                       return 0;
                     }
                   do_list (1, listmode, fplist,
@@ -1249,6 +1249,7 @@ ask_marktrusted (ctrl_t ctrl, ksba_cert_t cert, int listmode)
 
    VALIDATE_FLAG_NO_DIRMNGR  - Do not do any dirmngr isvalid checks.
    VALIDATE_FLAG_CHAIN_MODEL - Check according to chain model.
+   VALIDATE_FLAG_STEED       - Check according to the STEED model.
 */
 static int
 do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
@@ -1361,13 +1362,21 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
              We used to do this only later but changed it to call the
              check right here so that we can access special flags
              associated with that specific root certificate.  */
-          istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert, NULL,
-                                                rootca_flags);
+          if (gpgsm_cert_has_well_known_private_key (subject_cert))
+            {
+              memset (rootca_flags, 0, sizeof *rootca_flags);
+              istrusted_rc = ((flags & VALIDATE_FLAG_STEED)
+                              ? 0 : gpg_error (GPG_ERR_NOT_TRUSTED));
+            }
+          else
+            istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert, NULL,
+                                                  rootca_flags);
           audit_log_cert (ctrl->audit, AUDIT_ROOT_TRUSTED,
                           subject_cert, istrusted_rc);
           /* If the chain model extended attribute is used, make sure
              that our chain model flag is set. */
-          if (has_validation_model_chain (subject_cert, listmode, listfp))
+          if (!(flags & VALIDATE_FLAG_STEED)
+              && has_validation_model_chain (subject_cert, listmode, listfp))
             rootca_flags->chain_model = 1;
         }
 
@@ -1439,7 +1448,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
           /* Set the flag for qualified signatures.  This flag is
              deduced from a list of root certificates allowed for
              qualified signatures. */
-          if (is_qualified == -1)
+          if (is_qualified == -1 && !(flags & VALIDATE_FLAG_STEED))
             {
               gpg_error_t err;
               size_t buflen;
@@ -1493,8 +1502,11 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
                  expired it does not make much sense to ask the user
                  whether we wants to trust the root certificate.  We
                  should do this only if the certificate under question
-                 will then be usable.  */
+                 will then be usable.  If the certificate has a well
+                 known private key asking the user does not make any
+                 sense.  */
               if ( !any_expired
+                   && !gpgsm_cert_has_well_known_private_key (subject_cert)
                    && (!listmode || !already_asked_marktrusted (subject_cert))
                    && ask_marktrusted (ctrl, subject_cert, listmode) )
                 rc = 0;
@@ -1511,6 +1523,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
           /* Check for revocations etc. */
           if ((flags & VALIDATE_FLAG_NO_DIRMNGR))
             ;
+          else if ((flags & VALIDATE_FLAG_STEED))
+            ; /* Fixme: check revocations via DNS.  */
           else if (opt.no_trusted_cert_crl_check || rootca_flags->relax)
             ;
           else
@@ -1642,8 +1656,16 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
                performance reasons. */
             if (is_root)
               {
-                istrusted_rc = gpgsm_agent_istrusted (ctrl, issuer_cert, NULL,
-                                                      rootca_flags);
+                if (gpgsm_cert_has_well_known_private_key (issuer_cert))
+                  {
+                    memset (rootca_flags, 0, sizeof *rootca_flags);
+                    istrusted_rc = ((flags & VALIDATE_FLAG_STEED)
+                                    ? 0 : gpg_error (GPG_ERR_NOT_TRUSTED));
+                  }
+                else
+                  istrusted_rc = gpgsm_agent_istrusted
+                    (ctrl, issuer_cert, NULL, rootca_flags);
+
                 if (!istrusted_rc && rootca_flags->relax)
                   {
                     /* Ignore the error due to the relax flag.  */
@@ -1683,6 +1705,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
          be fixed. */
       if ((flags & VALIDATE_FLAG_NO_DIRMNGR))
         rc = 0;
+      else if ((flags & VALIDATE_FLAG_STEED))
+        rc = 0; /* Fixme: XXX */
       else if (is_root && (opt.no_trusted_cert_crl_check
                            || (!istrusted_rc && rootca_flags->relax)))
         rc = 0;
@@ -1778,7 +1802,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
      capability of the certificate under question, store the result as
      user data in all certificates of the chain.  We do this even if the
      validation itself failed.  */
-  if (is_qualified != -1)
+  if (is_qualified != -1 && !(flags & VALIDATE_FLAG_STEED))
     {
       gpg_error_t err;
       chain_item_t ci;
@@ -1836,8 +1860,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
    do_validate_chain.  This function is a wrapper to handle a root
    certificate with the chain_model flag set.  If RETFLAGS is not
    NULL, flags indicating now the verification was done are stored
-   there.  The only defined flag for RETFLAGS is
-   VALIDATE_FLAG_CHAIN_MODEL.
+   there.  The only defined vits for RETFLAGS are
+   VALIDATE_FLAG_CHAIN_MODEL and VALIDATE_FLAG_STEED.
 
    If you are verifying a signature you should set CHECKTIME to the
    creation time of the signature.  If your are verifying a
@@ -1857,16 +1881,27 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
   if (!retflags)
     retflags = &dummy_retflags;
 
+  /* If the session requested a certain validation mode make sure the
+     corresponding flags are set.  */
   if (ctrl->validation_model == 1)
     flags |= VALIDATE_FLAG_CHAIN_MODEL;
+  else if (ctrl->validation_model == 2)
+    flags |= VALIDATE_FLAG_STEED;
 
+  /* If the chain model was forced, set this immediately into
+     RETFLAGS.  */
   *retflags = (flags & VALIDATE_FLAG_CHAIN_MODEL);
+
   memset (&rootca_flags, 0, sizeof rootca_flags);
 
   rc = do_validate_chain (ctrl, cert, checktime,
                           r_exptime, listmode, listfp, flags,
                           &rootca_flags);
-  if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED
+  if (!rc && (flags & VALIDATE_FLAG_STEED))
+    {
+      *retflags |= VALIDATE_FLAG_STEED;
+    }
+  else if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED
       && !(flags & VALIDATE_FLAG_CHAIN_MODEL)
       && (rootca_flags.valid && rootca_flags.chain_model))
     {
@@ -1880,6 +1915,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
 
   if (opt.verbose)
     do_list (0, listmode, listfp, _("validation model used: %s"),
+             (*retflags & VALIDATE_FLAG_STEED)?
+             "steed" :
              (*retflags & VALIDATE_FLAG_CHAIN_MODEL)?
              _("chain"):_("shell"));
 
index e2e4a4b..904556f 100644 (file)
@@ -237,7 +237,7 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
   algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert)));
   if (!algo)
     {
-      log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
+      log_error ("unknown hash algorithm '%s'\n", algoid? algoid:"?");
       if (algoid
           && (  !strcmp (algoid, "1.2.840.113549.1.1.2")
                 ||!strcmp (algoid, "1.2.840.113549.2.2")))
@@ -434,6 +434,3 @@ gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert,
   xfree (grip);
   return rc;
 }
-
-
-
index d339070..23cca73 100644 (file)
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 #ifdef HAVE_LOCALE_H
@@ -175,7 +175,7 @@ gpgsm_dump_string (const char *string)
 
 
 /* This simple dump function is mainly used for debugging purposes. */
-void 
+void
 gpgsm_dump_cert (const char *text, ksba_cert_t cert)
 {
   ksba_sexp_t sexp;
@@ -183,7 +183,7 @@ gpgsm_dump_cert (const char *text, ksba_cert_t cert)
   char *dn;
   ksba_isotime_t t;
 
-  log_debug ("BEGIN Certificate `%s':\n", text? text:"");
+  log_debug ("BEGIN Certificate '%s':\n", text? text:"");
   if (cert)
     {
       sexp = ksba_cert_get_serial (cert);
@@ -206,7 +206,7 @@ gpgsm_dump_cert (const char *text, ksba_cert_t cert)
       gpgsm_dump_string (dn);
       ksba_free (dn);
       log_printf ("\n");
-    
+
       dn = ksba_cert_get_subject (cert, 0);
       log_debug ("    subject: ");
       gpgsm_dump_string (dn);
@@ -256,7 +256,7 @@ gpgsm_format_sn_issuer (ksba_sexp_t sn, const char *issuer)
 
 /* Log the certificate's name in "#SN/ISSUERDN" format along with
    TEXT. */
-void 
+void
 gpgsm_cert_log_name (const char *text, ksba_cert_t cert)
 {
   log_info ("%s", text? text:"certificate" );
@@ -301,7 +301,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
     {"T",            "2.5.4.12" },
     {"GN",           "2.5.4.42" },
     {"SN",           "2.5.4.4" },
-    {"NameDistinguisher", "0.2.262.1.10.7.20"}, 
+    {"NameDistinguisher", "0.2.262.1.10.7.20"},
     {"ADDR",         "2.5.4.16" },
     {"BC",           "2.5.4.15" },
     {"D",            "2.5.4.13" },
@@ -329,7 +329,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
   array->key = p = xtrymalloc (n+10);
   if (!array->key)
     return NULL;
-  memcpy (p, string, n); 
+  memcpy (p, string, n);
   p[n] = 0;
   trim_trailing_spaces (p);
 
@@ -373,7 +373,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
             { /* pair */
               s++;
               if (*s == ',' || *s == '=' || *s == '+'
-                  || *s == '<' || *s == '>' || *s == '#' || *s == ';' 
+                  || *s == '<' || *s == '>' || *s == '#' || *s == ';'
                   || *s == '\\' || *s == '\"' || *s == ' ')
                 n++;
               else if (hexdigitp (s) && hexdigitp (s+1))
@@ -388,7 +388,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
             return NULL; /* invalid encoding */
           else if (*s == ',' || *s == '=' || *s == '+'
                    || *s == '<' || *s == '>' || *s == ';' )
-            break; 
+            break;
           else
             n++;
         }
@@ -399,7 +399,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string)
       for (s=string; n; s++, n--)
         {
           if (*s == '\\')
-            { 
+            {
               s++;
               if (hexdigitp (s))
                 {
@@ -440,7 +440,7 @@ parse_dn (const unsigned char *string)
       if (!*string)
         break; /* ready */
       if (arrayidx >= arraysize)
-        { 
+        {
           struct dn_array_s *a2;
 
           arraysize += 5;
@@ -504,9 +504,8 @@ print_dn_part (FILE *fp, estream_t stream,
                 {
                   es_fprintf (stream, "/%s=", dn->key);
                   if (translate)
-                    es_write_sanitized_utf8_buffer (stream, dn->value,
-                                                    strlen (dn->value),
-                                                    "/", NULL);
+                    print_utf8_buffer3 (stream, dn->value, strlen (dn->value),
+                                         "/");
                   else
                     es_write_sanitized (stream, dn->value, strlen (dn->value),
                                         "/", NULL);
@@ -537,10 +536,10 @@ print_dn_parts (FILE *fp, estream_t stream,
                 struct dn_array_s *dn, int translate)
 {
   const char *stdpart[] = {
-    "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL 
+    "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL
   };
   int i;
-  
+
   for (i=0; stdpart[i]; i++)
       print_dn_part (fp, stream, dn, stdpart[i], translate);
 
@@ -677,9 +676,9 @@ gpgsm_print_name2 (FILE *fp, const char *name, int translate)
       struct dn_array_s *dn = parse_dn (s);
       if (!dn)
         fputs (_("[Error - invalid DN]"), fp);
-      else 
+      else
         {
-          print_dn_parts (fp, NULL, dn, translate);          
+          print_dn_parts (fp, NULL, dn, translate);
           for (i=0; dn[i].key; i++)
             {
               xfree (dn[i].key);
@@ -716,8 +715,7 @@ gpgsm_es_print_name2 (estream_t fp, const char *name, int translate)
       if (s2)
         {
           if (translate)
-            es_write_sanitized_utf8_buffer (fp, s + 1, s2 - (char*)s - 1,
-                                            NULL, NULL);
+            print_utf8_buffer (fp, s + 1, s2 - (char*)s - 1);
           else
             es_write_sanitized (fp, s + 1, s2 - (char*)s - 1, NULL, NULL);
         }
@@ -736,9 +734,9 @@ gpgsm_es_print_name2 (estream_t fp, const char *name, int translate)
 
       if (!dn)
         es_fputs (_("[Error - invalid DN]"), fp);
-      else 
+      else
         {
-          print_dn_parts (NULL, fp, dn, translate);          
+          print_dn_parts (NULL, fp, dn, translate);
           for (i=0; dn[i].key; i++)
             {
               xfree (dn[i].key);
@@ -758,7 +756,7 @@ gpgsm_es_print_name (estream_t fp, const char *name)
 
 
 /* A cookie structure used for the memory stream. */
-struct format_name_cookie 
+struct format_name_cookie
 {
   char *buffer;         /* Malloced buffer with the data to deliver. */
   size_t size;          /* Allocated size of this buffer. */
@@ -786,7 +784,7 @@ format_name_writer (void *cookie, const void *buffer, size_t size)
   else if (c->len + size < c->len)
     {
       p = NULL;
-      errno = ENOMEM;
+      gpg_err_set_errno (ENOMEM);
     }
   else if (c->size < c->len + size)
     {
@@ -804,12 +802,12 @@ format_name_writer (void *cookie, const void *buffer, size_t size)
       c->error = errno;
       xfree (c->buffer);
       c->buffer = NULL;
-      errno = c->error;
+      gpg_err_set_errno (c->error);
       return -1;
     }
   memcpy (p + c->len, buffer, size);
   c->len += size;
-  p[c->len] = 0; /* Terminate string. */ 
+  p[c->len] = 0; /* Terminate string. */
 
   return (ssize_t)size;
 }
@@ -834,8 +832,8 @@ gpgsm_format_name2 (const char *name, int translate)
   if (!fp)
     {
       int save_errno = errno;
-      log_error ("error creating memory stream: %s\n", strerror (errno));
-      errno = save_errno;
+      log_error ("error creating memory stream: %s\n", strerror (save_errno));
+      gpg_err_set_errno (save_errno);
       return NULL;
     }
   gpgsm_es_print_name2 (fp, name, translate);
@@ -843,7 +841,7 @@ gpgsm_format_name2 (const char *name, int translate)
   if (cookie.error || !cookie.buffer)
     {
       xfree (cookie.buffer);
-      errno = cookie.error;
+      gpg_err_set_errno (cookie.error);
       return NULL;
     }
   return cookie.buffer;
@@ -869,7 +867,7 @@ gpgsm_fpr_and_name_for_status (ksba_cert_t cert)
   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
   if (!fpr)
     return NULL;
-  
+
   name = ksba_cert_get_subject (cert, 0);
   if (!name)
     {
@@ -954,21 +952,20 @@ gpgsm_format_keydesc (ksba_cert_t cert)
                        sn? sn: "?",
                        gpgsm_get_short_fingerprint (cert, NULL),
                        created, expires);
-  
+
   i18n_switchback (orig_codeset);
-  
+
   if (!name)
     {
       xfree (subject);
       xfree (sn);
       return NULL;
     }
-  
+
   xfree (subject);
   xfree (sn);
 
   buffer = percent_plus_escape (name);
-  xfree (name); 
+  xfree (name);
   return buffer;
 }
-
index bfacaa2..9adcabf 100644 (file)
@@ -1,6 +1,6 @@
 /* certlist.c - build list of certificates
  * Copyright (C) 2001, 2003, 2004, 2005, 2007,
- *               2008 Free Software Foundation, Inc.
+ *               2008, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
@@ -95,7 +95,7 @@ cert_usage_p (ksba_cert_t cert, int mode)
                     extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
                                    | KSBA_KEYUSAGE_NON_REPUDIATION);
                 }
-              
+
               /* This is a hack to cope with OCSP.  Note that we do
                  not yet fully comply with the requirements and that
                  the entire CRL/OCSP checking thing should undergo a
@@ -108,7 +108,7 @@ cert_usage_p (ksba_cert_t cert, int mode)
             }
           xfree (extkeyusages);
           extkeyusages = NULL;
-          
+
           if (!any_critical)
             extusemask = ~0; /* Reset to the don't care mask. */
         }
@@ -128,12 +128,12 @@ cert_usage_p (ksba_cert_t cert, int mode)
 
     }
   if (err)
-    { 
+    {
       log_error (_("error getting key usage information: %s\n"),
                  gpg_strerror (err));
       xfree (extkeyusages);
       return err;
-    } 
+    }
 
   if (mode == 4)
     {
@@ -146,7 +146,7 @@ cert_usage_p (ksba_cert_t cert, int mode)
 
   if (mode == 5)
     {
-      if (use != ~0 
+      if (use != ~0
           && (have_ocsp_signing
               || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN
                          |KSBA_KEYUSAGE_CRL_SIGN))))
@@ -210,13 +210,28 @@ gpgsm_cert_use_ocsp_p (ksba_cert_t cert)
 }
 
 
+/* Return true if CERT has the well known private key extension.  */
+int
+gpgsm_cert_has_well_known_private_key (ksba_cert_t cert)
+{
+  int idx;
+  const char *oid;
+
+  for (idx=0; !ksba_cert_get_extension (cert, idx,
+                                        &oid, NULL, NULL, NULL);idx++)
+    if (!strcmp (oid, "1.3.6.1.4.1.11591.2.2.2") )
+      return 1; /* Yes.  */
+  return 0; /* No.  */
+}
+
+
 static int
 same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert)
 {
   char *subject2 = ksba_cert_get_subject (cert, 0);
   char *issuer2 = ksba_cert_get_issuer (cert, 0);
   int tmp;
-  
+
   tmp = (subject && subject2
          && !strcmp (subject, subject2)
          && issuer && issuer2
@@ -268,7 +283,7 @@ is_cert_in_certlist (ksba_cert_t cert, certlist_t certlist)
 
 /* Add CERT to the list of certificates at CERTADDR but avoid
    duplicates. */
-int 
+int
 gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
                             certlist_t *listaddr, int is_encrypt_to)
 {
@@ -301,7 +316,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
   KEYDB_HANDLE kh = NULL;
   ksba_cert_t cert = NULL;
 
-  rc = keydb_classify_name (name, &desc);
+  rc = classify_user_id (name, &desc, 0);
   if (!rc)
     {
       kh = keydb_new (0);
@@ -355,7 +370,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
           /* We want the error code from the first match in this case. */
           if (rc && wrong_usage)
             rc = wrong_usage;
-          
+
           if (!rc)
             {
               certlist_t dup_certs = NULL;
@@ -367,8 +382,8 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
               else if (!rc)
                 {
                   ksba_cert_t cert2 = NULL;
-                  
-                  /* If this is the first possible duplicate, add the original 
+
+                  /* If this is the first possible duplicate, add the original
                      certificate to our list of duplicates.  */
                   if (!dup_certs)
                     gpgsm_add_cert_to_certlist (ctrl, cert, &dup_certs, 0);
@@ -384,8 +399,8 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                      keybox).  */
                   if (!keydb_get_cert (kh, &cert2))
                     {
-                      int tmp = (same_subject_issuer (first_subject, 
-                                                      first_issuer, 
+                      int tmp = (same_subject_issuer (first_subject,
+                                                      first_issuer,
                                                       cert2)
                                  && ((gpg_err_code (
                                       secret? gpgsm_cert_use_sign_p (cert2)
@@ -400,7 +415,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                           if (is_cert_in_certlist (cert2, dup_certs))
                             tmp = 1;
                         }
-                      
+
                       ksba_cert_release (cert2);
                       if (tmp)
                         goto next_ambigious;
@@ -416,10 +431,10 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
 
           if (!rc && !is_cert_in_certlist (cert, *listaddr))
             {
-              if (!rc && secret) 
+              if (!rc && secret)
                 {
                   char *p;
-                  
+
                   rc = gpg_error (GPG_ERR_NO_SECKEY);
                   p = gpgsm_get_keygrip_hexstring (cert);
                   if (p)
@@ -437,7 +452,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                   certlist_t cl = xtrycalloc (1, sizeof *cl);
                   if (!cl)
                     rc = out_of_core ();
-                  else 
+                  else
                     {
                       cl->cert = cert; cert = NULL;
                       cl->next = *listaddr;
@@ -448,7 +463,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
             }
         }
     }
-  
+
   keydb_release (kh);
   ksba_cert_release (cert);
   return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
@@ -480,7 +495,7 @@ gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
   KEYDB_HANDLE kh = NULL;
 
   *r_cert = NULL;
-  rc = keydb_classify_name (name, &desc);
+  rc = classify_user_id (name, &desc, 0);
   if (!rc)
     {
       kh = keydb_new (0);
@@ -496,7 +511,7 @@ gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
               if (!rc && keyid)
                 {
                   ksba_sexp_t subj;
-                  
+
                   rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj);
                   if (!rc)
                     {
@@ -525,7 +540,7 @@ gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
               rc = keydb_search (kh, &desc, 1);
               if (rc == -1)
                 rc = 0;
-              else 
+              else
                 {
                   if (!rc)
                     {
@@ -548,8 +563,7 @@ gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
             }
         }
     }
-  
+
   keydb_release (kh);
   return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
 }
-
index 3e98b66..3ccd048 100644 (file)
@@ -1,5 +1,5 @@
 /* certreqgen-ui.c - Simple user interface for certreqgen.c
- * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2007, 2010, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
@@ -40,7 +40,7 @@ ask_mb_lines (membuf_t *mb, const char *prefix)
 {
   char *answer = NULL;
 
-  do 
+  do
     {
       xfree (answer);
       answer = tty_get ("> ");
@@ -88,14 +88,14 @@ store_mb_lines (membuf_t *mb, membuf_t *lines)
 
 /* Chech whether we have a key for the key with HEXGRIP.  Returns NULL
    if not or a string describing the type of the key (RSA, ELG, DSA,
-   etc..).  */ 
+   etc..).  */
 static const char *
 check_keygrip (ctrl_t ctrl, const char *hexgrip)
 {
   gpg_error_t err;
   ksba_sexp_t public;
   size_t publiclen;
-  int algo;
+  const char *algostr;
 
   if (hexgrip[0] == '&')
     hexgrip++;
@@ -105,17 +105,21 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
     return NULL;
   publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
 
-  get_pk_algo_from_canon_sexp (public, publiclen, &algo);
+  get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
   xfree (public);
 
-  switch (algo)
-    {
-    case GCRY_PK_RSA: return "RSA";
-    case GCRY_PK_DSA: return "DSA";
-    case GCRY_PK_ELG: return "ELG";
-    case GCRY_PK_ECDSA: return "ECDSA";
-    default: return NULL;
-    }
+  if (!algostr)
+    return NULL;
+  else if (!strcmp (algostr, "rsa"))
+    return "RSA";
+  else if (!strcmp (algostr, "dsa"))
+    return "DSA";
+  else if (!strcmp (algostr, "elg"))
+    return "ELG";
+  else if (!strcmp (algostr, "ecdsa"))
+    return "ECDSA";
+  else
+    return NULL;
 }
 
 
@@ -125,7 +129,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
    and thus is not suitable for the Windows port.  So here is the
    re-implementation.  */
 void
-gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
+gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream)
 {
   gpg_error_t err;
   char *answer;
@@ -143,8 +147,8 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
   char *subject_name;
   membuf_t mb_email, mb_dns, mb_uri, mb_result;
   char *result = NULL;
-  int i;
   const char *s, *s2;
+  int selfsigned;
 
   answer = NULL;
   init_membuf (&mb_email, 100);
@@ -202,7 +206,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
           answer = tty_get (_("Enter the keygrip: "));
           tty_kill_prompt ();
           trim_spaces (answer);
-          
+
           if (!*answer)
             goto again;
           else if (strlen (answer) != 40 &&
@@ -308,7 +312,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
       else if ( (err = ksba_dn_teststr (answer, 0, &erroff, &errlen)) )
         {
           if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME)
-            tty_printf (_("Invalid subject name label `%.*s'\n"),
+            tty_printf (_("Invalid subject name label '%.*s'\n"),
                         (int)errlen, answer+erroff);
           else
             {
@@ -317,7 +321,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
                  adjust it do the length of your translation.  The
                  second string is merely passed to atoi so you can
                  drop everything after the number.  */
-              tty_printf (_("Invalid subject name `%s'\n"), answer);
+              tty_printf (_("Invalid subject name '%s'\n"), answer);
               tty_printf ("%*s^\n",
                           atoi (_("22 translator: see "
                                   "certreg-ui.c:gpgsm_gencertreq_tty"))
@@ -338,12 +342,17 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
   /* DNS names.  */
   tty_printf (_("Enter DNS names"));
   tty_printf (_(" (optional; end with an empty line):\n"));
-  ask_mb_lines (&mb_email, "Name-DNS: ");
+  ask_mb_lines (&mb_dns, "Name-DNS: ");
 
   /* URIs.  */
   tty_printf (_("Enter URIs"));
   tty_printf (_(" (optional; end with an empty line):\n"));
-  ask_mb_lines (&mb_email, "Name-URI: ");
+  ask_mb_lines (&mb_uri, "Name-URI: ");
+
+
+  /* Want a self-signed certificate?  */
+  selfsigned = tty_get_answer_is_yes
+    (_("Create self-signed certificate? (y/N) "));
 
 
   /* Put it all together.  */
@@ -353,10 +362,12 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
     snprintf (numbuf, sizeof numbuf, "%u", nbits);
     store_key_value_lf (&mb_result, "Key-Length: ", numbuf);
   }
-  store_key_value_lf (&mb_result, "Key-Usage: ", keyusage);
-  store_key_value_lf (&mb_result, "Name-DN: ", subject_name);
   if (keygrip)
     store_key_value_lf (&mb_result, "Key-Grip: ", keygrip);
+  store_key_value_lf (&mb_result, "Key-Usage: ", keyusage);
+  if (selfsigned)
+    store_key_value_lf (&mb_result, "Serial: ", "random");
+  store_key_value_lf (&mb_result, "Name-DN: ", subject_name);
   if (store_mb_lines (&mb_result, &mb_email))
     goto mem_error;
   if (store_mb_lines (&mb_result, &mb_dns))
@@ -368,14 +379,13 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
   if (!result)
     goto mem_error;
 
-  tty_printf (_("Parameters to be used for the certificate request:\n"));
-  for (s=result; (s2 = strchr (s, '\n')); s = s2+1, i++)
+  tty_printf (_("These parameters are used:\n"));
+  for (s=result; (s2 = strchr (s, '\n')); s = s2+1)
     tty_printf ("    %.*s\n", (int)(s2-s), s);
   tty_printf ("\n");
 
-
-  if (!tty_get_answer_is_yes ("Really create request? (y/N) "))
-     goto leave;
+  if (!tty_get_answer_is_yes ("Proceed with creation? (y/N) "))
+    goto leave;
 
   /* Now create a parameter file and generate the key.  */
   fp = es_fopenmem (0, "w+");
@@ -386,16 +396,26 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
     }
   es_fputs (result, fp);
   es_rewind (fp);
-  tty_printf (_("Now creating certificate request.  "
-                "This may take a while ...\n"));
+  if (selfsigned)
+    tty_printf ("%s", _("Now creating self-signed certificate.  "));
+  else
+    tty_printf ("%s", _("Now creating certificate request.  "));
+  tty_printf ("%s", _("This may take a while ...\n"));
+
   {
     int save_pem = ctrl->create_pem;
     ctrl->create_pem = 1; /* Force creation of PEM. */
-    err = gpgsm_genkey (ctrl, fp, output_fp);
+    err = gpgsm_genkey (ctrl, fp, output_stream);
     ctrl->create_pem = save_pem;
   }
   if (!err)
-    tty_printf (_("Ready.  You should now send this request to your CA.\n"));
+    {
+      if (selfsigned)
+        tty_printf (_("Ready.\n"));
+      else
+        tty_printf
+          (_("Ready.  You should now send this request to your CA.\n"));
+    }
 
 
   goto leave;
index a1e9bf8..9720b80 100644 (file)
@@ -1,5 +1,6 @@
-/* certreqgen.c - Generate a key and a certification request
- * Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* certreqgen.c - Generate a key and a certification [request]
+ * Copyright (C) 2002, 2003, 2005, 2007, 2010,
+ *               2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  */
 
 /*
-The format of the native parameter file is follows:
-  o Text only, line length is limited to about 1000 chars.
-  o You must use UTF-8 encoding to specify non-ascii characters.
-  o Empty lines are ignored.
-  o Leading and trailing spaces are ignored.
-  o A hash sign as the first non white space character is a comment line.
-  o Control statements are indicated by a leading percent sign, the
-    arguments are separated by white space from the keyword.
-  o Parameters are specified by a keyword, followed by a colon.  Arguments
-    are separated by white space.
-  o The first parameter must be "Key-Type", control statements
-    may be placed anywhere.
-  o Key generation takes place when either the end of the parameter file
-    is reached, the next "Key-Type" parameter is encountered or at the
-    controlstatement "%commit"
-  o Control statements:
-    %echo <text>
-       Print <text>.
-    %dry-run
-       Suppress actual key generation (useful for syntax checking).
-    %commit
-       Perform the key generation.  Note that an implicit commit is done
-       at the next "Key-Type" parameter.
-    %certfile <filename>
-       Do not write the certificate to the keyDB but to <filename>.
-        This must be given before the first
-       commit to take place, duplicate specification of the same filename
-       is ignored, the last filename before a commit is used.
-       The filename is used until a new filename is used (at commit points)
-       and all keys are written to that file.  If a new filename is given,
-       this file is created (and overwrites an existing one).
-       Both control statements must be given.
-   o The order of the parameters does not matter except for "Key-Type"
-     which must be the first parameter.  The parameters are only for the
-     generated keyblock and parameters from previous key generations are not
-     used. Some syntactically checks may be performed.
-     The currently defined parameters are:
-     Key-Type: <algo>
-       Starts a new parameter block by giving the type of the
-       primary key. The algorithm must be capable of signing.
-       This is a required parameter.  For now the only supported
-        algorithm is "rsa".
-     Key-Length: <length-in-bits>
-       Length of the key in bits.  Default is 2048.
-     Key-Grip: hexstring
-        This is optional and used to generate a request for an already
-        existing key.  Key-Length will be ignored when given,
-     Key-Usage: <usage-list>
-        Space or comma delimited list of key usage, allowed values are
-        "encrypt" and "sign".  This is used to generate the KeyUsage extension.
-        Please make sure that the algorithm is capable of this usage.  Default
-        is to allow encrypt and sign.
-     Name-DN: subject name
-        This is the DN name of the subject in rfc2253 format.
-     Name-Email: <string>
-       The is an email address for the altSubjectName
-     Name-DNS: <string>
-       The is an DNS name for the altSubjectName
-     Name-URI: <string>
-       The is an URI for the altSubjectName
-
-Here is an example:
-$ cat >foo <<EOF
-%echo Generating a standard key
-Key-Type: RSA
-Key-Length: 2048
-Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE
-Name-Email: joe@foo.bar
-# Do a commit here, so that we can later print "done" :-)
-%commit
-%echo done
-EOF
+   The format of the parameter file is described in the manual under
+   "Unattended Usage".
+
+   Here is an example:
+     $ cat >foo <<EOF
+     %echo Generating a standard key
+     Key-Type: RSA
+     Key-Length: 2048
+     Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Ddorf,C=DE
+     Name-Email: joe@foo.bar
+     # Do a commit here, so that we can later print a "done"
+     %commit
+     %echo done
+     EOF
+
+   This parameter file was used to create the STEED CA:
+     Key-Type: RSA
+     Key-Length: 1024
+     Key-Grip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
+     Key-Usage: cert
+     Serial: 1
+     Name-DN: CN=The STEED Self-Signing Nonthority
+     Not-Before: 2011-11-11
+     Not-After: 2106-02-06
+     Subject-Key-Id: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
+     Extension: 2.5.29.19 c 30060101ff020101
+     Extension: 1.3.6.1.4.1.11591.2.2.2 n 0101ff
+     Signing-Key: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
+     %commit
+
 */
 
 
@@ -110,18 +69,29 @@ EOF
 #include "i18n.h"
 
 
-enum para_name {
-  pKEYTYPE,
-  pKEYLENGTH,
-  pKEYGRIP,
-  pKEYUSAGE,
-  pNAMEDN,
-  pNAMEEMAIL,
-  pNAMEDNS,
-  pNAMEURI
-};
+enum para_name
+  {
+    pKEYTYPE,
+    pKEYLENGTH,
+    pKEYGRIP,
+    pKEYUSAGE,
+    pNAMEDN,
+    pNAMEEMAIL,
+    pNAMEDNS,
+    pNAMEURI,
+    pSERIAL,
+    pISSUERDN,
+    pNOTBEFORE,
+    pNOTAFTER,
+    pSIGNINGKEY,
+    pHASHALGO,
+    pAUTHKEYID,
+    pSUBJKEYID,
+    pEXTENSION
+  };
 
-struct para_data_s {
+struct para_data_s
+{
   struct para_data_s *next;
   int lnr;
   enum para_name key;
@@ -131,24 +101,30 @@ struct para_data_s {
   } u;
 };
 
-struct reqgen_ctrl_s {
+struct reqgen_ctrl_s
+{
   int lnr;
   int dryrun;
-  ksba_writer_t writer;
 };
 
 
+static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
+static const char oidstr_subjectKeyIdentifier[] = "2.5.29.14";
 static const char oidstr_keyUsage[] = "2.5.29.15";
+static const char oidstr_basicConstraints[] = "2.5.29.19";
+static const char oidstr_standaloneCertificate[] = "1.3.6.1.4.1.11591.2.2.1";
 
 
 static int proc_parameters (ctrl_t ctrl,
                             struct para_data_s *para,
+                            estream_t out_fp,
                             struct reqgen_ctrl_s *outctrl);
 static int create_request (ctrl_t ctrl,
                            struct para_data_s *para,
                            const char *carddirect,
                            ksba_const_sexp_t public,
-                           struct reqgen_ctrl_s *outctrl);
+                           ksba_const_sexp_t sigkey,
+                           ksba_writer_t writer);
 
 
 \f
@@ -215,8 +191,11 @@ parse_parameter_usage (struct para_data_s *para, enum para_name key)
         ;
       else if ( !ascii_strcasecmp (p, "sign") )
         use |= GCRY_PK_USAGE_SIGN;
-      else if ( !ascii_strcasecmp (p, "encrypt") )
+      else if ( !ascii_strcasecmp (p, "encrypt")
+                || !ascii_strcasecmp (p, "encr") )
         use |= GCRY_PK_USAGE_ENCR;
+      else if ( !ascii_strcasecmp (p, "cert") )
+        use |= GCRY_PK_USAGE_CERT;
       else
         {
           log_error ("line %d: invalid usage list\n", r->lnr);
@@ -247,7 +226,7 @@ get_parameter_uint (struct para_data_s *para, enum para_name key)
 /* Read the certificate generation parameters from FP and generate
    (all) certificate requests.  */
 static int
-read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
+read_parameters (ctrl_t ctrl, estream_t fp, estream_t out_fp)
 {
   static struct {
     const char *name;
@@ -262,6 +241,17 @@ read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
     { "Name-Email",     pNAMEEMAIL, 1 },
     { "Name-DNS",       pNAMEDNS, 1 },
     { "Name-URI",       pNAMEURI, 1 },
+    { "Serial",         pSERIAL },
+    { "Issuer-DN",      pISSUERDN },
+    { "Creation-Date",  pNOTBEFORE },
+    { "Not-Before",     pNOTBEFORE },
+    { "Expire-Date",    pNOTAFTER },
+    { "Not-After",      pNOTAFTER },
+    { "Signing-Key",    pSIGNINGKEY },
+    { "Hash-Algo",      pHASHALGO },
+    { "Authority-Key-Id", pAUTHKEYID },
+    { "Subject-Key-Id", pSUBJKEYID },
+    { "Extension",      pEXTENSION, 1 },
     { NULL, 0 }
   };
   char line[1024], *p;
@@ -271,7 +261,6 @@ read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
   struct reqgen_ctrl_s outctrl;
 
   memset (&outctrl, 0, sizeof (outctrl));
-  outctrl.writer = writer;
 
   err = NULL;
   para = NULL;
@@ -293,11 +282,11 @@ read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
       keyword = p;
       if (*keyword == '%')
         {
-          for (; *p && !spacep (p); p++)
+          for (; *p && !ascii_isspace (*p); p++)
             ;
           if (*p)
             *p++ = 0;
-          for (; spacep (p); p++)
+          for (; ascii_isspace (*p); p++)
             ;
           value = p;
           trim_trailing_spaces (value);
@@ -308,7 +297,7 @@ read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
             outctrl.dryrun = 1;
           else if (!ascii_strcasecmp( keyword, "%commit"))
             {
-              rc = proc_parameters (ctrl, para, &outctrl);
+              rc = proc_parameters (ctrl, para, out_fp, &outctrl);
               if (rc)
                 goto leave;
               any = 1;
@@ -316,7 +305,7 @@ read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
               para = NULL;
            }
           else
-            log_info ("skipping control `%s' (%s)\n", keyword, value);
+            log_info ("skipping control '%s' (%s)\n", keyword, value);
 
           continue;
        }
@@ -355,7 +344,7 @@ read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
 
       if (keywords[i].key == pKEYTYPE && para)
         {
-          rc = proc_parameters (ctrl, para, &outctrl);
+          rc = proc_parameters (ctrl, para, out_fp, &outctrl);
           if (rc)
             goto leave;
           any = 1;
@@ -398,7 +387,7 @@ read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
     }
   else if (para)
     {
-      rc = proc_parameters (ctrl, para, &outctrl);
+      rc = proc_parameters (ctrl, para, out_fp, &outctrl);
       if (rc)
         goto leave;
       any = 1;
@@ -437,18 +426,19 @@ has_invalid_email_chars (const char *s)
 
 /* Check that all required parameters are given and perform the action */
 static int
-proc_parameters (ctrl_t ctrl,
-                 struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
+proc_parameters (ctrl_t ctrl, struct para_data_s *para,
+                 estream_t out_fp, struct reqgen_ctrl_s *outctrl)
 {
   gpg_error_t err;
   struct para_data_s *r;
-  const char *s;
+  const char *s, *string;
   int i;
   unsigned int nbits;
   char numbuf[20];
   unsigned char keyparms[100];
-  int rc;
-  ksba_sexp_t public;
+  int rc = 0;
+  ksba_sexp_t public = NULL;
+  ksba_sexp_t sigkey = NULL;
   int seq;
   size_t erroff, errlen;
   char *cardkeyid = NULL;
@@ -475,7 +465,8 @@ proc_parameters (ctrl_t ctrl,
       return gpg_error (GPG_ERR_INV_PARAMETER);
     }
 
-  /* Check the keylength. */
+  /* Check the keylength.  NOTE: If you change this make sure that it
+     macthes the gpgconflist item in gpgsm.c  */
   if (!get_parameter (para, pKEYLENGTH, 0))
     nbits = 2048;
   else
@@ -511,10 +502,10 @@ proc_parameters (ctrl_t ctrl,
     {
       r = get_parameter (para, pNAMEDN, 0);
       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME)
-        log_error (_("line %d: invalid subject name label `%.*s'\n"),
+        log_error (_("line %d: invalid subject name label '%.*s'\n"),
                    r->lnr, (int)errlen, s+erroff);
       else
-        log_error (_("line %d: invalid subject name `%s' at pos %d\n"),
+        log_error (_("line %d: invalid subject name '%s' at pos %d\n"),
                    r->lnr, s, (int)erroff);
 
       xfree (cardkeyid);
@@ -537,14 +528,177 @@ proc_parameters (ctrl_t ctrl,
         }
     }
 
+  /* Check the optional serial number.  */
+  string = get_parameter_value (para, pSERIAL, 0);
+  if (string)
+    {
+      if (!strcmp (string, "random"))
+        ; /* Okay.  */
+      else
+        {
+          for (s=string, i=0; hexdigitp (s); s++, i++)
+            ;
+          if (*s)
+            {
+              r = get_parameter (para, pSERIAL, 0);
+              log_error (_("line %d: invalid serial number\n"), r->lnr);
+              xfree (cardkeyid);
+              return gpg_error (GPG_ERR_INV_PARAMETER);
+            }
+        }
+    }
+
+  /* Check the optional issuer DN.  */
+  string = get_parameter_value (para, pISSUERDN, 0);
+  if (string)
+    {
+      err = ksba_dn_teststr (string, 0, &erroff, &errlen);
+      if (err)
+        {
+          r = get_parameter (para, pISSUERDN, 0);
+          if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME)
+            log_error (_("line %d: invalid issuer name label '%.*s'\n"),
+                       r->lnr, (int)errlen, string+erroff);
+          else
+            log_error (_("line %d: invalid issuer name '%s' at pos %d\n"),
+                       r->lnr, string, (int)erroff);
+          xfree (cardkeyid);
+          return gpg_error (GPG_ERR_INV_PARAMETER);
+        }
+    }
+
+  /* Check the optional creation date.  */
+  string = get_parameter_value (para, pNOTBEFORE, 0);
+  if (string && !string2isotime (NULL, string))
+    {
+      r = get_parameter (para, pNOTBEFORE, 0);
+      log_error (_("line %d: invalid date given\n"), r->lnr);
+      xfree (cardkeyid);
+      return gpg_error (GPG_ERR_INV_PARAMETER);
+    }
+
+
+  /* Check the optional expire date.  */
+  string = get_parameter_value (para, pNOTAFTER, 0);
+  if (string && !string2isotime (NULL, string))
+    {
+      r = get_parameter (para, pNOTAFTER, 0);
+      log_error (_("line %d: invalid date given\n"), r->lnr);
+      xfree (cardkeyid);
+      return gpg_error (GPG_ERR_INV_PARAMETER);
+    }
+
+  /* Get the optional signing key.  */
+  string = get_parameter_value (para, pSIGNINGKEY, 0);
+  if (string)
+    {
+      rc = gpgsm_agent_readkey (ctrl, 0, string, &sigkey);
+      if (rc)
+        {
+          r = get_parameter (para, pKEYTYPE, 0);
+          log_error (_("line %d: error getting signing key by keygrip '%s'"
+                       ": %s\n"), r->lnr, s, gpg_strerror (rc));
+          xfree (cardkeyid);
+          return rc;
+        }
+    }
+
+  /* Check the optional hash-algo.  */
+  {
+    int mdalgo;
+
+    string = get_parameter_value (para, pHASHALGO, 0);
+    if (string && !((mdalgo = gcry_md_map_name (string))
+                    && (mdalgo == GCRY_MD_SHA1
+                        || mdalgo == GCRY_MD_SHA256
+                        || mdalgo == GCRY_MD_SHA384
+                        || mdalgo == GCRY_MD_SHA512)))
+      {
+        r = get_parameter (para, pHASHALGO, 0);
+        log_error (_("line %d: invalid hash algorithm given\n"), r->lnr);
+        xfree (cardkeyid);
+        return gpg_error (GPG_ERR_INV_PARAMETER);
+      }
+  }
+
+  /* Check the optional AuthorityKeyId.  */
+  string = get_parameter_value (para, pAUTHKEYID, 0);
+  if (string)
+    {
+      for (s=string, i=0; hexdigitp (s); s++, i++)
+        ;
+      if (*s || (i&1))
+        {
+          r = get_parameter (para, pAUTHKEYID, 0);
+          log_error (_("line %d: invalid authority-key-id\n"), r->lnr);
+          xfree (cardkeyid);
+          return gpg_error (GPG_ERR_INV_PARAMETER);
+        }
+    }
+
+  /* Check the optional SubjectKeyId.  */
+  string = get_parameter_value (para, pSUBJKEYID, 0);
+  if (string)
+    {
+      for (s=string, i=0; hexdigitp (s); s++, i++)
+        ;
+      if (*s || (i&1))
+        {
+          r = get_parameter (para, pSUBJKEYID, 0);
+          log_error (_("line %d: invalid subject-key-id\n"), r->lnr);
+          xfree (cardkeyid);
+          return gpg_error (GPG_ERR_INV_PARAMETER);
+        }
+    }
+
+  /* Check the optional extensions. */
+  for (seq=0; (string=get_parameter_value (para, pEXTENSION, seq)); seq++)
+    {
+      int okay = 0;
+
+      s = strpbrk (string, " \t:");
+      if (s)
+        {
+          s++;
+          while (spacep (s))
+            s++;
+          if (*s && strchr ("nNcC", *s))
+            {
+              s++;
+              while (spacep (s))
+                s++;
+              if (*s == ':')
+                s++;
+              if (*s)
+                {
+                  while (spacep (s))
+                    s++;
+                  for (i=0; hexdigitp (s); s++, i++)
+                    ;
+                  if (!((*s && *s != ':') || !i || (i&1)))
+                    okay = 1;
+                }
+            }
+        }
+      if (!okay)
+        {
+          r = get_parameter (para, pEXTENSION, seq);
+          log_error (_("line %d: invalid extension syntax\n"), r->lnr);
+          xfree (cardkeyid);
+          return gpg_error (GPG_ERR_INV_PARAMETER);
+        }
+    }
+
+  /* Create or retrieve the public key.  */
   if (cardkeyid) /* Take the key from the current smart card. */
     {
       rc = gpgsm_agent_readkey (ctrl, 1, cardkeyid, &public);
       if (rc)
         {
           r = get_parameter (para, pKEYTYPE, 0);
-          log_error (_("line %d: error reading key `%s' from card: %s\n"),
+          log_error (_("line %d: error reading key '%s' from card: %s\n"),
                      r->lnr, cardkeyid, gpg_strerror (rc));
+          xfree (sigkey);
           xfree (cardkeyid);
           return rc;
         }
@@ -555,13 +709,14 @@ proc_parameters (ctrl_t ctrl,
       if (rc)
         {
           r = get_parameter (para, pKEYTYPE, 0);
-          log_error (_("line %d: error getting key by keygrip `%s': %s\n"),
+          log_error (_("line %d: error getting key by keygrip '%s': %s\n"),
                      r->lnr, s, gpg_strerror (rc));
+          xfree (sigkey);
           xfree (cardkeyid);
           return rc;
         }
     }
-  else /* Generate new key.  */
+  else if (!outctrl->dryrun) /* Generate new key.  */
     {
       sprintf (numbuf, "%u", nbits);
       snprintf ((char*)keyparms, DIM (keyparms)-1,
@@ -573,12 +728,45 @@ proc_parameters (ctrl_t ctrl,
           r = get_parameter (para, pKEYTYPE, 0);
           log_error (_("line %d: key generation failed: %s <%s>\n"),
                      r->lnr, gpg_strerror (rc), gpg_strsource (rc));
+          xfree (sigkey);
           xfree (cardkeyid);
           return rc;
         }
     }
 
-  rc = create_request (ctrl, para, cardkeyid, public, outctrl);
+
+  if (!outctrl->dryrun)
+    {
+      Base64Context b64writer = NULL;
+      ksba_writer_t writer;
+      int create_cert ;
+
+      create_cert = !!get_parameter_value (para, pSERIAL, 0);
+
+      ctrl->pem_name = create_cert? "CERTIFICATE" : "CERTIFICATE REQUEST";
+      rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
+      if (rc)
+        log_error ("can't create writer: %s\n", gpg_strerror (rc));
+      else
+        {
+          rc = create_request (ctrl, para, cardkeyid, public, sigkey, writer);
+          if (!rc)
+            {
+              rc = gpgsm_finish_writer (b64writer);
+              if (rc)
+                log_error ("write failed: %s\n", gpg_strerror (rc));
+              else
+                {
+                  gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
+                  log_info ("certificate%s created\n",
+                            create_cert?"":" request");
+                }
+            }
+          gpgsm_destroy_writer (b64writer);
+        }
+    }
+
+  xfree (sigkey);
   xfree (public);
   xfree (cardkeyid);
 
@@ -587,38 +775,40 @@ proc_parameters (ctrl_t ctrl,
 
 
 /* Parameters are checked, the key pair has been created.  Now
-   generate the request and write it out.
-
-   Note: We use SHA-1 here because Libksba hash a shortcut to use
-   assume that if SIG_VAL uses as algo the string "rsa".  To fix that
-   we would need to replace that string by an appropriate OID.  We
-   leave this change for 2.1.
- */
+   generate the request and write it out */
 static int
 create_request (ctrl_t ctrl,
                 struct para_data_s *para,
                 const char *carddirect,
                 ksba_const_sexp_t public,
-                struct reqgen_ctrl_s *outctrl)
+                ksba_const_sexp_t sigkey,
+                ksba_writer_t writer)
 {
   ksba_certreq_t cr;
   gpg_error_t err;
-  int hashalgo = GCRY_MD_SHA1;
   gcry_md_hd_t md;
   ksba_stop_reason_t stopreason;
   int rc = 0;
-  const char *s;
+  const char *s, *string;
   unsigned int use;
   int seq;
   char *buf, *p;
   size_t len;
   char numbuf[30];
+  ksba_isotime_t atime;
+  int certmode = 0;
+  int mdalgo;
 
   err = ksba_certreq_new (&cr);
   if (err)
     return err;
 
-  rc = gcry_md_open (&md, hashalgo, 0);
+  string = get_parameter_value (para, pHASHALGO, 0);
+  if (string)
+    mdalgo = gcry_md_map_name (string);
+  else
+    mdalgo = GCRY_MD_SHA1;
+  rc = gcry_md_open (&md, mdalgo, 0);
   if (rc)
     {
       log_error ("md_open failed: %s\n", gpg_strerror (rc));
@@ -628,7 +818,7 @@ create_request (ctrl_t ctrl,
     gcry_md_debug (md, "cr.cri");
 
   ksba_certreq_set_hash_function (cr, HASH_FNC, md);
-  ksba_certreq_set_writer (cr, outctrl->writer);
+  ksba_certreq_set_writer (cr, writer);
 
   err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN, 0));
   if (err)
@@ -725,7 +915,7 @@ create_request (ctrl_t ctrl,
       goto leave;
     }
 
-
+  /* Set key usage flags.  */
   use = get_parameter_uint (para, pKEYUSAGE);
   if (use == GCRY_PK_USAGE_SIGN)
     {
@@ -743,6 +933,14 @@ create_request (ctrl_t ctrl,
       err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
                                         "\x03\x02\x04\x30", 4);
     }
+  else if (use == GCRY_PK_USAGE_CERT)
+    {
+      /* For certify only we encode the bits:
+         KSBA_KEYUSAGE_KEY_CERT_SIGN
+         KSBA_KEYUSAGE_CRL_SIGN */
+      err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
+                                        "\x03\x02\x01\x06", 4);
+    }
   else
     err = 0; /* Both or none given: don't request one. */
   if (err)
@@ -754,6 +952,303 @@ create_request (ctrl_t ctrl,
     }
 
 
+  /* See whether we want to create an X.509 certificate.  */
+  string = get_parameter_value (para, pSERIAL, 0);
+  if (string)
+    {
+      certmode = 1;
+
+      /* Store the serial number.  */
+      if (!strcmp (string, "random"))
+        {
+          char snbuf[3+8+1];
+
+          memcpy (snbuf, "(8:", 3);
+          gcry_create_nonce (snbuf+3, 8);
+          /* Clear high bit to guarantee a positive integer.  */
+          snbuf[3] &= 0x7f;
+          snbuf[3+8] = ')';
+          err = ksba_certreq_set_serial (cr, snbuf);
+        }
+      else
+        {
+          char *hexbuf;
+
+          /* Allocate a buffer large enough to prefix the string with
+             a '0' so to have an even number of digits.  Prepend two
+             further '0' so that the binary result will have a leading
+             0 byte and thus can't be the representation of a negative
+             number.  Note that ksba_certreq_set_serial strips all
+             unneeded leading 0 bytes.  */
+          hexbuf = p = xtrymalloc (2 + 1 + strlen (string) + 1);
+          if (!hexbuf)
+            {
+              err = gpg_error_from_syserror ();
+              goto leave;
+            }
+          if ((strlen (string) & 1))
+            *p++ = '0';
+          *p++ = '0';
+          *p++ = '0';
+          strcpy (p, string);
+          for (p=hexbuf, len=0; p[0] && p[1]; p += 2)
+            ((unsigned char*)hexbuf)[len++] = xtoi_2 (p);
+          /* Now build the S-expression.  */
+          snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
+          buf = p = xtrymalloc (1 + strlen (numbuf) + len + 1 + 1);
+          if (!buf)
+            {
+              err = gpg_error_from_syserror ();
+              xfree (hexbuf);
+              goto leave;
+            }
+          p = stpcpy (stpcpy (buf, "("), numbuf);
+          memcpy (p, hexbuf, len);
+          p += len;
+          strcpy (p, ")");
+          xfree (hexbuf);
+          err = ksba_certreq_set_serial (cr, buf);
+          xfree (buf);
+        }
+      if (err)
+        {
+          log_error ("error setting the serial number: %s\n",
+                     gpg_strerror (err));
+          goto leave;
+        }
+
+
+      /* Store the issuer DN.  If no issuer DN is given and no signing
+         key has been set we add the standalone extension and the
+         basic constraints to mark it as a self-signed CA
+         certificate.  */
+      string = get_parameter_value (para, pISSUERDN, 0);
+      if (string)
+        {
+          /* Issuer DN given.  Note that this may be the same as the
+             subject DN and thus this could as well be a self-signed
+             certificate.  However the caller needs to explicitly
+             specify basicConstraints and so forth.  */
+          err = ksba_certreq_set_issuer (cr, string);
+          if (err)
+            {
+              log_error ("error setting the issuer DN: %s\n",
+                         gpg_strerror (err));
+              goto leave;
+            }
+
+        }
+      else if (!string && !sigkey)
+        {
+          /* Self-signed certificate requested.  Add basicConstraints
+             and the custom GnuPG standalone extension.  */
+          err = ksba_certreq_add_extension (cr, oidstr_basicConstraints, 1,
+                                            "\x30\x03\x01\x01\xff", 5);
+          if (err)
+            goto leave;
+          err = ksba_certreq_add_extension (cr, oidstr_standaloneCertificate, 0,
+                                            "\x01\x01\xff", 3);
+          if (err)
+            goto leave;
+        }
+
+      /* Store the creation date.  */
+      string = get_parameter_value (para, pNOTBEFORE, 0);
+      if (string)
+        {
+          if (!string2isotime (atime, string))
+            BUG (); /* We already checked the value.  */
+        }
+      else
+        gnupg_get_isotime (atime);
+      err = ksba_certreq_set_validity (cr, 0, atime);
+      if (err)
+        {
+          log_error ("error setting the creation date: %s\n",
+                     gpg_strerror (err));
+          goto leave;
+        }
+
+
+      /* Store the expire date.  If it is not given, libksba inserts a
+         default value.  */
+      string = get_parameter_value (para, pNOTAFTER, 0);
+      if (string)
+        {
+          if (!string2isotime (atime, string))
+            BUG (); /* We already checked the value.  */
+          err = ksba_certreq_set_validity (cr, 1, atime);
+          if (err)
+            {
+              log_error ("error setting the expire date: %s\n",
+                         gpg_strerror (err));
+              goto leave;
+            }
+        }
+
+
+      /* Figure out the signing algorithm.  If no sigkey has been
+         given we set it to the public key to create a self-signed
+         certificate. */
+      if (!sigkey)
+        sigkey = public;
+
+      {
+        unsigned char *siginfo;
+
+        err = transform_sigval (sigkey,
+                                gcry_sexp_canon_len (sigkey, 0, NULL, NULL),
+                                mdalgo, &siginfo, NULL);
+        if (!err)
+          {
+            err = ksba_certreq_set_siginfo (cr, siginfo);
+            xfree (siginfo);
+          }
+        if (err)
+          {
+            log_error ("error setting the siginfo: %s\n",
+                       gpg_strerror (err));
+            rc = err;
+            goto leave;
+          }
+      }
+
+      /* Insert the AuthorityKeyId.  */
+      string = get_parameter_value (para, pAUTHKEYID, 0);
+      if (string)
+        {
+          char *hexbuf;
+
+          /* Allocate a buffer for in-place conversion.  We also add 4
+             extra bytes space for the tags and lengths fields.  */
+          hexbuf = xtrymalloc (4 + strlen (string) + 1);
+          if (!hexbuf)
+            {
+              err = gpg_error_from_syserror ();
+              goto leave;
+            }
+          strcpy (hexbuf+4, string);
+          for (p=hexbuf+4, len=0; p[0] && p[1]; p += 2)
+            ((unsigned char*)hexbuf)[4+len++] = xtoi_2 (p);
+          if (len > 125)
+            {
+              err = gpg_error (GPG_ERR_TOO_LARGE);
+              xfree (hexbuf);
+              goto leave;
+            }
+          hexbuf[0] = 0x30;  /* Tag for a Sequence.  */
+          hexbuf[1] = len+2;
+          hexbuf[2] = 0x80;  /* Context tag for an implicit Octet string.  */
+          hexbuf[3] = len;
+          err = ksba_certreq_add_extension (cr, oidstr_authorityKeyIdentifier,
+                                            0,
+                                            hexbuf, 4+len);
+          xfree (hexbuf);
+          if (err)
+            {
+              log_error ("error setting the authority-key-id: %s\n",
+                         gpg_strerror (err));
+              goto leave;
+            }
+        }
+
+      /* Insert the SubjectKeyId.  */
+      string = get_parameter_value (para, pSUBJKEYID, 0);
+      if (string)
+        {
+          char *hexbuf;
+
+          /* Allocate a buffer for in-place conversion.  We also add 2
+             extra bytes space for the tag and length field.  */
+          hexbuf = xtrymalloc (2 + strlen (string) + 1);
+          if (!hexbuf)
+            {
+              err = gpg_error_from_syserror ();
+              goto leave;
+            }
+          strcpy (hexbuf+2, string);
+          for (p=hexbuf+2, len=0; p[0] && p[1]; p += 2)
+            ((unsigned char*)hexbuf)[2+len++] = xtoi_2 (p);
+          if (len > 127)
+            {
+              err = gpg_error (GPG_ERR_TOO_LARGE);
+              xfree (hexbuf);
+              goto leave;
+            }
+          hexbuf[0] = 0x04;  /* Tag for an Octet string.  */
+          hexbuf[1] = len;
+          err = ksba_certreq_add_extension (cr, oidstr_subjectKeyIdentifier, 0,
+                                            hexbuf, 2+len);
+          xfree (hexbuf);
+          if (err)
+            {
+              log_error ("error setting the subject-key-id: %s\n",
+                         gpg_strerror (err));
+              goto leave;
+            }
+        }
+
+      /* Insert additional extensions.  */
+      for (seq=0; (string = get_parameter_value (para, pEXTENSION, seq)); seq++)
+        {
+          char *hexbuf;
+          char *oidstr;
+          int crit = 0;
+
+          s = strpbrk (string, " \t:");
+          if (!s)
+            {
+              err = gpg_error (GPG_ERR_INTERNAL);
+              goto leave;
+            }
+
+          oidstr = xtrymalloc (s - string + 1);
+          if (!oidstr)
+            {
+              err = gpg_error_from_syserror ();
+              goto leave;
+            }
+          memcpy (oidstr, string, (s-string));
+          oidstr[(s-string)] = 0;
+
+          s++;
+          while (spacep (s))
+            s++;
+          if (!*s)
+            {
+              err = gpg_error (GPG_ERR_INTERNAL);
+              xfree (oidstr);
+              goto leave;
+            }
+
+          if (strchr ("cC", *s))
+            crit = 1;
+          s++;
+          while (spacep (s))
+            s++;
+          if (*s == ':')
+            s++;
+          while (spacep (s))
+            s++;
+
+          hexbuf = xtrystrdup (s);
+          if (!hexbuf)
+            {
+              err = gpg_error_from_syserror ();
+              xfree (oidstr);
+              goto leave;
+            }
+          for (p=hexbuf, len=0; p[0] && p[1]; p += 2)
+            ((unsigned char*)hexbuf)[len++] = xtoi_2 (p);
+          err = ksba_certreq_add_extension (cr, oidstr, crit,
+                                            hexbuf, len);
+          xfree (oidstr);
+          xfree (hexbuf);
+        }
+    }
+  else
+    sigkey = public;
+
   do
     {
       err = ksba_certreq_build (cr, &stopreason);
@@ -769,17 +1264,17 @@ create_request (ctrl_t ctrl,
           size_t n;
           unsigned char grip[20];
           char hexgrip[41];
-          unsigned char *sigval;
+          unsigned char *sigval, *newsigval;
           size_t siglen;
 
-          n = gcry_sexp_canon_len (public, 0, NULL, NULL);
+          n = gcry_sexp_canon_len (sigkey, 0, NULL, NULL);
           if (!n)
             {
               log_error ("libksba did not return a proper S-Exp\n");
               rc = gpg_error (GPG_ERR_BUG);
               goto leave;
             }
-          rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)public, n);
+          rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)sigkey, n);
           if (rc)
             {
               log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
@@ -795,13 +1290,14 @@ create_request (ctrl_t ctrl,
           gcry_sexp_release (s_pkey);
           bin2hex (grip, 20, hexgrip);
 
-          log_info ("about to sign CSR for key: &%s\n", hexgrip);
+          log_info ("about to sign the %s for key: &%s\n",
+                    certmode? "certificate":"CSR", hexgrip);
 
           if (carddirect)
             rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
-                                   gcry_md_read (md, hashalgo),
-                                   gcry_md_get_algo_dlen (hashalgo),
-                                   hashalgo,
+                                   gcry_md_read (md, mdalgo),
+                                   gcry_md_get_algo_dlen (mdalgo),
+                                   mdalgo,
                                    &sigval, &siglen);
           else
             {
@@ -815,9 +1311,9 @@ create_request (ctrl_t ctrl,
                    " more.\n"));
               i18n_switchback (orig_codeset);
               rc = gpgsm_agent_pksign (ctrl, hexgrip, desc,
-                                       gcry_md_read(md, hashalgo),
-                                       gcry_md_get_algo_dlen (hashalgo),
-                                       hashalgo,
+                                       gcry_md_read(md, mdalgo),
+                                       gcry_md_get_algo_dlen (mdalgo),
+                                       mdalgo,
                                        &sigval, &siglen);
               xfree (desc);
             }
@@ -827,8 +1323,14 @@ create_request (ctrl_t ctrl,
               goto leave;
             }
 
-          err = ksba_certreq_set_sig_val (cr, sigval);
+          err = transform_sigval (sigval, siglen, mdalgo,
+                                  &newsigval, NULL);
           xfree (sigval);
+          if (!err)
+            {
+              err = ksba_certreq_set_sig_val (cr, newsigval);
+              xfree (newsigval);
+            }
           if (err)
             {
               log_error ("failed to store the sig_val: %s\n",
@@ -852,21 +1354,11 @@ create_request (ctrl_t ctrl,
 /* Create a new key by reading the parameters from IN_FP.  Multiple
    keys may be created */
 int
-gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, FILE *out_fp)
+gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, estream_t out_stream)
 {
   int rc;
-  Base64Context b64writer = NULL;
-  ksba_writer_t writer;
 
-  ctrl->pem_name = "CERTIFICATE REQUEST";
-  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
-  if (rc)
-    {
-      log_error ("can't create writer: %s\n", gpg_strerror (rc));
-      goto leave;
-    }
-
-  rc = read_parameters (ctrl, in_stream, writer);
+  rc = read_parameters (ctrl, in_stream, out_stream);
   if (rc)
     {
       log_error ("error creating certificate request: %s <%s>\n",
@@ -874,18 +1366,6 @@ gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, FILE *out_fp)
       goto leave;
     }
 
-  rc = gpgsm_finish_writer (b64writer);
-  if (rc)
-    {
-      log_error ("write failed: %s\n", gpg_strerror (rc));
-      goto leave;
-    }
-
-  gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
-  log_info ("certificate request created\n");
-
  leave:
-  gpgsm_destroy_writer (b64writer);
   return rc;
 }
-
index 841fbd6..a560272 100644 (file)
@@ -1,5 +1,5 @@
 /* decrypt.c - Decrypt a message
- *     Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
@@ -33,7 +33,8 @@
 #include "keydb.h"
 #include "i18n.h"
 
-struct decrypt_filter_parm_s {
+struct decrypt_filter_parm_s
+{
   int algo;
   int mode;
   int blklen;
@@ -52,7 +53,7 @@ struct decrypt_filter_parm_s {
 
 /* Decrypt the session key and fill in the parm structure.  The
    algo and the IV is expected to be already in PARM. */
-static int 
+static int
 prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
                     ksba_const_sexp_t enc_val,
                     struct decrypt_filter_parm_s *parm)
@@ -83,9 +84,9 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
       if (n + 7 > seskeylen )
         {
           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
-          goto leave; 
+          goto leave;
         }
-      
+
       /* FIXME: Actually the leading zero is required but due to the way
          we encode the output in libgcrypt as an MPI we are not able to
          encode that leading zero.  However, when using a Smartcard we are
@@ -93,20 +94,20 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
          should be fixed in gpg-agent of course. */
       if (!seskey[n])
         n++;
-      
+
       if (seskey[n] != 2 )  /* Wrong block type version. */
-        { 
+        {
           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
-          goto leave; 
+          goto leave;
         }
-      
+
       for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */
         ;
       n++; /* and the zero byte */
       if (n >= seskeylen )
-        { 
+        {
           rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
-          goto leave; 
+          goto leave;
         }
     }
 
@@ -119,7 +120,7 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
       log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
       goto leave;
     }
-                        
+
   rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n);
   if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
     {
@@ -237,7 +238,7 @@ decrypt_filter (void *arg,
 \f
 /* Perform a decrypt operation.  */
 int
-gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
+gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
 {
   int rc;
   Base64Context b64reader = NULL;
@@ -248,7 +249,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
   ksba_stop_reason_t stopreason;
   KEYDB_HANDLE kh;
   int recp;
-  FILE *in_fp = NULL;
+  estream_t in_fp = NULL;
   struct decrypt_filter_parm_s dfparm;
 
   memset (&dfparm, 0, sizeof dfparm);
@@ -263,11 +264,10 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
       goto leave;
     }
 
-
-  in_fp = fdopen ( dup (in_fd), "rb");
+  in_fp = es_fdopen_nc (in_fd, "rb");
   if (!in_fp)
     {
-      rc = gpg_error (gpg_err_code_from_errno (errno));
+      rc = gpg_error_from_syserror ();
       log_error ("fdopen() failed: %s\n", strerror (errno));
       goto leave;
     }
@@ -279,7 +279,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
       goto leave;
     }
 
-  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
+  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
       log_error ("can't create writer: %s\n", gpg_strerror (rc));
@@ -301,7 +301,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
   audit_log (ctrl->audit, AUDIT_SETUP_READY);
 
   /* Parser loop. */
-  do 
+  do
     {
       rc = ksba_cms_parse (cms, &stopreason);
       if (rc)
@@ -316,7 +316,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
           int algo, mode;
           const char *algoid;
           int any_key = 0;
-          
+
           audit_log (ctrl->audit, AUDIT_GOT_DATA);
 
           algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/);
@@ -325,7 +325,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
           if (!algo || !mode)
             {
               rc = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
-              log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?");
+              log_error ("unsupported algorithm '%s'\n", algoid? algoid:"?");
               if (algoid && !strcmp (algoid, "1.2.840.113549.3.2"))
                 log_info (_("(this is the RC2 algorithm)\n"));
               else if (!algoid)
@@ -363,7 +363,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
               log_error ("error getting IV: %s\n", gpg_strerror (rc));
               goto leave;
             }
-          
+
           for (recp=0; !any_key; recp++)
             {
               char *issuer;
@@ -386,7 +386,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
                 {
                   ksba_cert_t cert = NULL;
 
-                  log_debug ("recp %d - issuer: `%s'\n",
+                  log_debug ("recp %d - issuer: '%s'\n",
                              recp, issuer? issuer:"[NONE]");
                   log_debug ("recp %d - serial: ", recp);
                   gpgsm_dump_serial (serial);
@@ -412,7 +412,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
                   if (rc)
                     {
                       log_error ("failed to get cert: %s\n", gpg_strerror (rc));
-                      goto oops;     
+                      goto oops;
                     }
 
                   /* Print the ENC_TO status line.  Note that we can
@@ -424,11 +424,11 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
                      keyid for later use.  */
                   {
                     unsigned long kid[2];
-                    
+
                     kid[0] = gpgsm_get_short_fingerprint (cert, kid+1);
                     snprintf (kidbuf, sizeof kidbuf, "%08lX%08lX",
                               kid[1], kid[0]);
-                    gpgsm_status2 (ctrl, STATUS_ENC_TO, 
+                    gpgsm_status2 (ctrl, STATUS_ENC_TO,
                                    kidbuf, "0", "0", NULL);
                   }
 
@@ -535,7 +535,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
                   goto leave;
                 }
               rc = ksba_writer_write (writer,
-                                      dfparm.lastblock, 
+                                      dfparm.lastblock,
                                       dfparm.blklen - npadding);
               if (rc)
                 goto leave;
@@ -553,10 +553,10 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
         }
 
     }
-  while (stopreason != KSBA_SR_READY);   
+  while (stopreason != KSBA_SR_READY);
 
   rc = gpgsm_finish_writer (b64writer);
-  if (rc) 
+  if (rc)
     {
       log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
@@ -575,12 +575,9 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
   ksba_cms_release (cms);
   gpgsm_destroy_reader (b64reader);
   gpgsm_destroy_writer (b64writer);
-  keydb_release (kh); 
-  if (in_fp)
-    fclose (in_fp);
+  keydb_release (kh);
+  es_fclose (in_fp);
   if (dfparm.hd)
-    gcry_cipher_close (dfparm.hd); 
+    gcry_cipher_close (dfparm.hd);
   return rc;
 }
-
-
index fd49ebe..bafe601 100644 (file)
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
@@ -44,11 +44,11 @@ delete_one (ctrl_t ctrl, const char *username)
   ksba_cert_t cert = NULL;
   int duplicates = 0;
   int is_ephem = 0;
-  
-  rc = keydb_classify_name (username, &desc);
+
+  rc = classify_user_id (username, &desc, 0);
   if (rc)
     {
-      log_error (_("certificate `%s' not found: %s\n"),
+      log_error (_("certificate '%s' not found: %s\n"),
                  username, gpg_strerror (rc));
       gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL);
       goto leave;
@@ -109,7 +109,7 @@ delete_one (ctrl_t ctrl, const char *username)
     {
       if (rc == -1)
         rc = gpg_error (GPG_ERR_NO_PUBKEY);
-      log_error (_("certificate `%s' not found: %s\n"),
+      log_error (_("certificate '%s' not found: %s\n"),
                  username, gpg_strerror (rc));
       gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL);
       goto leave;
@@ -122,8 +122,8 @@ delete_one (ctrl_t ctrl, const char *username)
       log_error (_("error locking keybox: %s\n"), gpg_strerror (rc));
       goto leave;
     }
-                   
-  do 
+
+  do
     {
       keydb_search_reset (kh);
       rc = keydb_search (kh, &desc, 1);
@@ -133,16 +133,16 @@ delete_one (ctrl_t ctrl, const char *username)
                      gpg_strerror (rc));
           goto leave;
         }
-      
+
       rc = keydb_delete (kh, duplicates ? 0 : 1);
-      if (rc) 
+      if (rc)
         goto leave;
       if (opt.verbose)
         {
           if (duplicates)
-            log_info (_("duplicated certificate `%s' deleted\n"), username);
+            log_info (_("duplicated certificate '%s' deleted\n"), username);
           else
-            log_info (_("certificate `%s' deleted\n"), username);
+            log_info (_("certificate '%s' deleted\n"), username);
         }
     }
   while (duplicates--);
@@ -166,7 +166,7 @@ gpgsm_delete (ctrl_t ctrl, strlist_t names)
       log_error ("nothing to delete\n");
       return gpg_error (GPG_ERR_NO_DATA);
     }
-  
+
   for (; names; names=names->next )
     {
       rc = delete_one (ctrl, names->d);
@@ -177,6 +177,6 @@ gpgsm_delete (ctrl_t ctrl, strlist_t names)
           return rc;
         }
     }
-  
+
   return 0;
 }
index ab74fa2..54a8bd1 100644 (file)
@@ -1,5 +1,6 @@
 /* encrypt.c - Encrypt a message
- * Copyright (C) 2001, 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2007, 2008,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -22,7 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
@@ -45,8 +46,11 @@ struct dek_s {
 };
 typedef struct dek_s *DEK;
 
-struct encrypt_cb_parm_s {
-  FILE *fp;
+
+/* Callback parameters for the encryption.  */
+struct encrypt_cb_parm_s
+{
+  estream_t fp;
   DEK dek;
   int eof_seen;
   int ready;
@@ -70,10 +74,10 @@ init_dek (DEK dek)
   mode = gcry_cipher_mode_from_oid (dek->algoid);
   if (!dek->algo || !mode)
     {
-      log_error ("unsupported algorithm `%s'\n", dek->algoid);
+      log_error ("unsupported algorithm '%s'\n", dek->algoid);
       return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
     }
-  
+
   /* Extra check for algorithms we consider to be too weak for
      encryption, although we support them for decryption.  Note that
      there is another check below discriminating on the key length. */
@@ -81,8 +85,8 @@ init_dek (DEK dek)
     {
     case GCRY_CIPHER_DES:
     case GCRY_CIPHER_RFC2268_40:
-      log_error ("cipher algorithm `%s' not allowed: too weak\n",
-                 gcry_cipher_algo_name (dek->algo));
+      log_error ("cipher algorithm '%s' not allowed: too weak\n",
+                 gnupg_cipher_algo_name (dek->algo));
       return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
     default:
       break;
@@ -98,18 +102,18 @@ init_dek (DEK dek)
 
   /* Make sure we don't use weak keys. */
   if (dek->keylen < 100/8)
-    { 
-      log_error ("key length of `%s' too small\n", dek->algoid);
+    {
+      log_error ("key length of '%s' too small\n", dek->algoid);
       return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
     }
-  
+
   rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
   if (rc)
     {
       log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
       return rc;
     }
-  
+
   for (i=0; i < 8; i++)
     {
       gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
@@ -135,7 +139,7 @@ init_dek (DEK dek)
       dek->chd = NULL;
       return rc;
     }
-  
+
   return 0;
 }
 
@@ -156,7 +160,7 @@ encode_session_key (DEK dek, gcry_sexp_t * r_data)
   rc = gcry_sexp_sscan (&data, NULL, p, strlen (p));
   xfree (p);
   *r_data = data;
-  return rc;    
+  return rc;
 }
 
 
@@ -206,13 +210,10 @@ encrypt_dek (const DEK dek, ksba_cert_t cert, unsigned char **encval)
   rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
   gcry_sexp_release (s_data);
   gcry_sexp_release (s_pkey);
-  
+
   /* Reformat it. */
-  if (!rc)
-    {
-      rc = make_canon_sexp (s_ciph, encval, NULL);
-      gcry_sexp_release (s_ciph);
-    }
+  rc = make_canon_sexp (s_ciph, encval, NULL);
+  gcry_sexp_release (s_ciph);
   return rc;
 }
 
@@ -236,28 +237,28 @@ encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
 
   if (count < blklen)
     BUG ();
-     
+
   if (!parm->eof_seen)
     { /* fillup the buffer */
       p = parm->buffer;
       for (n=parm->buflen; n < parm->bufsize; n++)
         {
-          int c = getc (parm->fp);
+          int c = es_getc (parm->fp);
           if (c == EOF)
             {
-              if (ferror (parm->fp))
+              if (es_ferror (parm->fp))
                 {
                   parm->readerror = errno;
                   return -1;
                 }
               parm->eof_seen = 1;
-              break; 
+              break;
             }
           p[n] = c;
         }
       parm->buflen = n;
     }
-  
+
   n = parm->buflen < count? parm->buflen : count;
   n = n/blklen * blklen;
   if (n)
@@ -286,13 +287,13 @@ encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
 
 
 \f
-/* Perform an encrypt operation.  
+/* Perform an encrypt operation.
 
    Encrypt the data received on DATA-FD and write it to OUT_FP.  The
    recipients are take from the certificate given in recplist; if this
    is NULL it will be encrypted for a default recipient */
 int
-gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
+gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
 {
   int rc = 0;
   Base64Context b64writer = NULL;
@@ -305,7 +306,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
   struct encrypt_cb_parm_s encparm;
   DEK dek = NULL;
   int recpno;
-  FILE *data_fp = NULL;
+  estream_t data_fp = NULL;
   certlist_t cl;
   int count;
 
@@ -340,10 +341,11 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
       goto leave;
     }
 
-  data_fp = fdopen ( dup (data_fd), "rb");
+  /* Fixme:  We should use the unlocked version of the es functions.  */
+  data_fp = es_fdopen_nc (data_fd, "rb");
   if (!data_fp)
     {
-      rc = gpg_error (gpg_err_code_from_errno (errno));
+      rc = gpg_error_from_syserror ();
       log_error ("fdopen() failed: %s\n", strerror (errno));
       goto leave;
     }
@@ -359,7 +361,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
   encparm.fp = data_fp;
 
   ctrl->pem_name = "ENCRYPTED MESSAGE";
-  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
+  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
       log_error ("can't create writer: %s\n", gpg_strerror (rc));
@@ -398,7 +400,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
     }
 
   /* Create a session key */
-  dek = xtrycalloc_secure (1, sizeof *dek); 
+  dek = xtrycalloc_secure (1, sizeof *dek);
   if (!dek)
     rc = out_of_core ();
   else
@@ -431,7 +433,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
       rc = out_of_core ();
       goto leave;
     }
-  
+
   audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);
 
   /* Gather certificates of recipients, encrypt the session key for
@@ -439,7 +441,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
   for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
     {
       unsigned char *encval;
-      
+
       rc = encrypt_dek (dek, cl->cert, &encval);
       if (rc)
         {
@@ -448,7 +450,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
                      recpno, gpg_strerror (rc));
           goto leave;
         }
-      
+
       err = ksba_cms_add_recipient (cms, cl->cert);
       if (err)
         {
@@ -459,7 +461,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
           xfree (encval);
           goto leave;
         }
-      
+
       err = ksba_cms_set_enc_val (cms, recpno, encval);
       xfree (encval);
       audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
@@ -474,7 +476,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
 
   /* Main control loop for encryption. */
   recpno = 0;
-  do 
+  do
     {
       err = ksba_cms_build (cms, &stopreason);
       if (err)
@@ -484,7 +486,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
           goto leave;
         }
     }
-  while (stopreason != KSBA_SR_READY);   
+  while (stopreason != KSBA_SR_READY);
 
   if (encparm.readerror)
     {
@@ -495,7 +497,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
 
 
   rc = gpgsm_finish_writer (b64writer);
-  if (rc) 
+  if (rc)
     {
       log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
@@ -507,10 +509,9 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
   ksba_cms_release (cms);
   gpgsm_destroy_writer (b64writer);
   ksba_reader_release (reader);
-  keydb_release (kh); 
+  keydb_release (kh);
   xfree (dek);
-  if (data_fp)
-    fclose (data_fp);
+  es_fclose (data_fp);
   xfree (encparm.buffer);
   return rc;
 }
index fcf1dcc..1dce106 100644 (file)
@@ -1,5 +1,6 @@
 /* export.c - Export certificates and private keys.
- * Copyright (C) 2002, 2003, 2004, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2007, 2009,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -33,8 +34,7 @@
 #include "exechelp.h"
 #include "i18n.h"
 #include "sysutils.h"
-
-
+#include "minip12.h"
 
 /* A table to store a fingerprint as used in a duplicates table.  We
    don't need to hash here because a fingerprint is already a perfect
@@ -56,11 +56,12 @@ typedef struct duptable_s *duptable_t;
 #define DUPTABLE_SIZE (1 << DUPTABLE_BITS)
 
 
-static void print_short_info (ksba_cert_t cert, FILE *fp, estream_t stream);
+static void print_short_info (ksba_cert_t cert, estream_t stream);
 static gpg_error_t export_p12 (ctrl_t ctrl,
                                const unsigned char *certimg, size_t certimglen,
                                const char *prompt, const char *keygrip,
-                               FILE **retfp);
+                               int rawmode,
+                               void **r_result, size_t *r_resultlen);
 
 
 /* Create a table used to indetify duplicated certificates. */
@@ -78,7 +79,7 @@ destroy_duptable (duptable_t *table)
 
   if (table)
     {
-      for (idx=0; idx < DUPTABLE_SIZE; idx++) 
+      for (idx=0; idx < DUPTABLE_SIZE; idx++)
         for (t = table[idx]; t; t = t2)
           {
             t2 = t->next;
@@ -95,15 +96,15 @@ insert_duptable (duptable_t *table, unsigned char *fpr, int *exists)
 {
   size_t idx;
   duptable_t t;
-  
+
   *exists = 0;
   idx = fpr[0];
 #if DUPTABLE_BITS > 16 || DUPTABLE_BITS < 8
 #error cannot handle a table larger than 16 bits or smaller than 8 bits
 #elif DUPTABLE_BITS > 8
-  idx <<= (DUPTABLE_BITS - 8);  
-  idx |= (fpr[1] & ~(~0 << 4)); 
-#endif  
+  idx <<= (DUPTABLE_BITS - 8);
+  idx |= (fpr[1] & ~(~0 << 4));
+#endif
 
   for (t = table[idx]; t; t = t->next)
     if (!memcmp (t->fpr, fpr+1, 19))
@@ -124,12 +125,10 @@ insert_duptable (duptable_t *table, unsigned char *fpr, int *exists)
 }
 
 
-
-
-/* Export all certificates or just those given in NAMES. If STREAM is
-   not NULL the output is send to this extended stream. */
+/* Export all certificates or just those given in NAMES.  The output
+   is written to STREAM.  */
 void
-gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
+gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream)
 {
   KEYDB_HANDLE hd = NULL;
   KEYDB_SEARCH_DESC *desc = NULL;
@@ -143,7 +142,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
   int i;
   duptable_t *dtable;
 
-  
+
   dtable = create_duptable ();
   if (!dtable)
     {
@@ -162,7 +161,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
     ndesc = 1;
   else
     {
-      for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
+      for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
         ;
     }
 
@@ -176,14 +175,14 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
 
   if (!names)
     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
-  else 
+  else
     {
-      for (ndesc=0, sl=names; sl; sl = sl->next) 
+      for (ndesc=0, sl=names; sl; sl = sl->next)
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc, 0);
           if (rc)
             {
-              log_error ("key `%s' not found: %s\n",
+              log_error ("key '%s' not found: %s\n",
                          sl->d, gpg_strerror (rc));
               rc = 0;
             }
@@ -206,17 +205,17 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
       if (i == ndesc)
         keydb_set_ephemeral (hd, 1);
     }
-      
+
   while (!(rc = keydb_search (hd, desc, ndesc)))
     {
       unsigned char fpr[20];
       int exists;
 
-      if (!names) 
+      if (!names)
         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
 
       rc = keydb_get_cert (hd, &cert);
-      if (rc) 
+      if (rc)
         {
           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
           goto leave;
@@ -255,24 +254,16 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
           if (ctrl->create_pem)
             {
               if (count)
-                {
-                  if (stream)
-                    es_putc ('\n', stream);
-                  else
-                    putc ('\n', fp);
-                }
-              print_short_info (cert, fp, stream);
-              if (stream)
                 es_putc ('\n', stream);
-              else
-                putc ('\n', fp);
+              print_short_info (cert, stream);
+              es_putc ('\n', stream);
             }
           count++;
 
           if (!b64writer)
             {
               ctrl->pem_name = "CERTIFICATE";
-              rc = gpgsm_create_writer (&b64writer, ctrl, fp, stream, &writer);
+              rc = gpgsm_create_writer (&b64writer, ctrl, stream, &writer);
               if (rc)
                 {
                   log_error ("can't create writer: %s\n", gpg_strerror (rc));
@@ -291,7 +282,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
             {
               /* We want one certificate per PEM block */
               rc = gpgsm_finish_writer (b64writer);
-              if (rc) 
+              if (rc)
                 {
                   log_error ("write failed: %s\n", gpg_strerror (rc));
                   goto leave;
@@ -301,7 +292,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
             }
         }
 
-      ksba_cert_release (cert); 
+      ksba_cert_release (cert);
       cert = NULL;
     }
   if (rc && rc != -1)
@@ -309,13 +300,13 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
   else if (b64writer)
     {
       rc = gpgsm_finish_writer (b64writer);
-      if (rc) 
+      if (rc)
         {
           log_error ("write failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
     }
-  
+
  leave:
   gpgsm_destroy_writer (b64writer);
   ksba_cert_release (cert);
@@ -325,23 +316,27 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
 }
 
 
-/* Export a certificates and its private key. */
+/* Export a certificate and its private key.  RAWMODE controls the
+   actual output:
+       0 - Private key and certifciate in PKCS#12 format
+       1 - Only unencrypted private key in PKCS#8 format
+       2 - Only unencrypted private key in PKCS#1 format
+    */
 void
-gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
+gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode)
 {
+  gpg_error_t err = 0;
   KEYDB_HANDLE hd;
   KEYDB_SEARCH_DESC *desc = NULL;
   Base64Context b64writer = NULL;
   ksba_writer_t writer;
   ksba_cert_t cert = NULL;
-  int rc=0;
   const unsigned char *image;
   size_t imagelen;
   char *keygrip = NULL;
   char *prompt;
-  char buffer[1024];
-  int  nread;
-  FILE *datafp = NULL;
+  void *data;
+  size_t datalen;
 
 
   hd = keydb_new (0);
@@ -359,28 +354,28 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
       goto leave;
     }
 
-  rc = keydb_classify_name (name, desc);
-  if (rc)
+  err = classify_user_id (name, desc, 0);
+  if (err)
     {
-      log_error ("key `%s' not found: %s\n",
-                 name, gpg_strerror (rc));
+      log_error ("key '%s' not found: %s\n",
+                 name, gpg_strerror (err));
       goto leave;
     }
 
   /* Lookup the certificate and make sure that it is unique. */
-  rc = keydb_search (hd, desc, 1);
-  if (!rc)
+  err = keydb_search (hd, desc, 1);
+  if (!err)
     {
-      rc = keydb_get_cert (hd, &cert);
-      if (rc) 
+      err = keydb_get_cert (hd, &cert);
+      if (err)
         {
-          log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
+          log_error ("keydb_get_cert failed: %s\n", gpg_strerror (err));
           goto leave;
         }
 
-    next_ambiguous:      
-      rc = keydb_search (hd, desc, 1);
-      if (!rc)
+    next_ambiguous:
+      err = keydb_search (hd, desc, 1);
+      if (!err)
         {
           ksba_cert_t cert2 = NULL;
 
@@ -393,27 +388,27 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
                 }
               ksba_cert_release (cert2);
             }
-          rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
+          err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
         }
-      else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
-        rc = 0;
-      if (rc)
+      else if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
+        err = 0;
+      if (err)
         {
-          log_error ("key `%s' not found: %s\n",
-                     name, gpg_strerror (rc));
+          log_error ("key '%s' not found: %s\n",
+                     name, gpg_strerror (err));
           goto leave;
         }
     }
-      
+
   keygrip = gpgsm_get_keygrip_hexstring (cert);
   if (!keygrip || gpgsm_agent_havekey (ctrl, keygrip))
     {
       /* Note, that the !keygrip case indicates a bad certificate. */
-      rc = gpg_error (GPG_ERR_NO_SECKEY);
-      log_error ("can't export key `%s': %s\n", name, gpg_strerror (rc));
+      err = gpg_error (GPG_ERR_NO_SECKEY);
+      log_error ("can't export key '%s': %s\n", name, gpg_strerror (err));
       goto leave;
     }
-  
+
   image = ksba_cert_get_image (cert, &imagelen);
   if (!image)
     {
@@ -423,63 +418,60 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
 
   if (ctrl->create_pem)
     {
-      print_short_info (cert, fp, NULL);
-      putc ('\n', fp);
+      print_short_info (cert, stream);
+      es_putc ('\n', stream);
     }
 
-  if (opt.p12_charset && ctrl->create_pem)
+  if (opt.p12_charset && ctrl->create_pem && !rawmode)
     {
-      fprintf (fp, "The passphrase is %s encoded.\n\n",
-               opt.p12_charset);
+      es_fprintf (stream, "The passphrase is %s encoded.\n\n",
+                  opt.p12_charset);
     }
 
-  ctrl->pem_name = "PKCS12";
-  rc = gpgsm_create_writer (&b64writer, ctrl, fp, NULL, &writer);
-  if (rc)
+  if (rawmode == 0)
+    ctrl->pem_name = "PKCS12";
+  else if (rawmode == 1)
+    ctrl->pem_name = "PRIVATE KEY";
+  else
+    ctrl->pem_name = "RSA PRIVATE KEY";
+  err = gpgsm_create_writer (&b64writer, ctrl, stream, &writer);
+  if (err)
     {
-      log_error ("can't create writer: %s\n", gpg_strerror (rc));
+      log_error ("can't create writer: %s\n", gpg_strerror (err));
       goto leave;
     }
 
-
   prompt = gpgsm_format_keydesc (cert);
-  rc = export_p12 (ctrl, image, imagelen, prompt, keygrip, &datafp);
+  err = export_p12 (ctrl, image, imagelen, prompt, keygrip, rawmode,
+                    &data, &datalen);
   xfree (prompt);
-  if (rc)
+  if (err)
     goto leave;
-  rewind (datafp);
-  while ( (nread = fread (buffer, 1, sizeof buffer, datafp)) > 0 )
-    if ((rc = ksba_writer_write (writer, buffer, nread)))
-      {
-        log_error ("write failed: %s\n", gpg_strerror (rc));
-        goto leave;
-      }
-  if (ferror (datafp))
+  err = ksba_writer_write (writer, data, datalen);
+  xfree (data);
+  if (err)
     {
-      rc = gpg_error_from_errno (rc);
-      log_error ("error reading temporary file: %s\n", gpg_strerror (rc));
+      log_error ("write failed: %s\n", gpg_strerror (err));
       goto leave;
     }
 
   if (ctrl->create_pem)
     {
       /* We want one certificate per PEM block */
-      rc = gpgsm_finish_writer (b64writer);
-      if (rc) 
+      err = gpgsm_finish_writer (b64writer);
+      if (err)
         {
-          log_error ("write failed: %s\n", gpg_strerror (rc));
+          log_error ("write failed: %s\n", gpg_strerror (err));
           goto leave;
         }
       gpgsm_destroy_writer (b64writer);
       b64writer = NULL;
     }
-  
-  ksba_cert_release (cert); 
+
+  ksba_cert_release (cert);
   cert = NULL;
 
  leave:
-  if (datafp)
-    fclose (datafp);
   gpgsm_destroy_writer (b64writer);
   ksba_cert_release (cert);
   xfree (desc);
@@ -487,30 +479,9 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
 }
 
 
-/* Call either es_putc or the plain putc.  */
-static void
-do_putc (int value, FILE *fp, estream_t stream)
-{
-  if (stream)
-    es_putc (value, stream);
-  else
-    putc (value, fp);
-}
-
-/* Call either es_fputs or the plain fputs.  */
-static void
-do_fputs (const char *string, FILE *fp, estream_t stream)
-{
-  if (stream)
-    es_fputs (string, stream);
-  else
-    fputs (string, fp);
-}
-
-
 /* Print some info about the certifciate CERT to FP or STREAM */
 static void
-print_short_info (ksba_cert_t cert, FILE *fp, estream_t stream)
+print_short_info (ksba_cert_t cert, estream_t stream)
 {
   char *p;
   ksba_sexp_t sexp;
@@ -518,225 +489,246 @@ print_short_info (ksba_cert_t cert, FILE *fp, estream_t stream)
 
   for (idx=0; (p = ksba_cert_get_issuer (cert, idx)); idx++)
     {
-      do_fputs ((!idx
+      es_fputs ((!idx
                  ?   "Issuer ...: "
-                 : "\n   aka ...: "), fp, stream); 
-      if (stream)
-        gpgsm_es_print_name (stream, p);
-      else
-        gpgsm_print_name (fp, p);
+                 : "\n   aka ...: "), stream);
+      gpgsm_es_print_name (stream, p);
       xfree (p);
     }
-  do_putc ('\n', fp, stream);
+  es_putc ('\n', stream);
 
-  do_fputs ("Serial ...: ", fp, stream); 
+  es_fputs ("Serial ...: ", stream);
   sexp = ksba_cert_get_serial (cert);
   if (sexp)
     {
       int len;
       const unsigned char *s = sexp;
-      
+
       if (*s == '(')
         {
           s++;
           for (len=0; *s && *s != ':' && digitp (s); s++)
             len = len*10 + atoi_1 (s);
           if (*s == ':')
-            {
-              if (stream)
-                es_write_hexstring (stream, s+1, len, 0, NULL);
-              else
-                print_hexstring (fp, s+1, len, 0);
-            }
+            es_write_hexstring (stream, s+1, len, 0, NULL);
         }
       xfree (sexp);
     }
-  do_putc ('\n', fp, stream);
+  es_putc ('\n', stream);
 
   for (idx=0; (p = ksba_cert_get_subject (cert, idx)); idx++)
     {
-      do_fputs ((!idx
+      es_fputs ((!idx
                  ?   "Subject ..: "
-                 : "\n    aka ..: "), fp, stream); 
-      if (stream)
-        gpgsm_es_print_name (stream, p);
-      else
-        gpgsm_print_name (fp, p);
+                 : "\n    aka ..: "), stream);
+      gpgsm_es_print_name (stream, p);
+      xfree (p);
+    }
+  es_putc ('\n', stream);
+
+  p = gpgsm_get_keygrip_hexstring (cert);
+  if (p)
+    {
+      es_fprintf (stream, "Keygrip ..: %s\n", p);
       xfree (p);
     }
-  do_putc ('\n', fp, stream);
 }
 
 
-static gpg_error_t
-popen_protect_tool (ctrl_t ctrl, const char *pgmname,
-                    FILE *infile, FILE *outfile, FILE **statusfile, 
-                    const char *prompt, const char *keygrip,
-                    pid_t *pid)
+\f
+/* Parse a private key S-expression and return a malloced array with
+   the RSA parameters in pkcs#12 order.  The caller needs to
+   deep-release this array.  */
+static gcry_mpi_t *
+sexp_to_kparms (gcry_sexp_t sexp)
 {
-  const char *argv[22];
-  int i=0;
-
-  /* Make sure that the agent is running so that the protect tool is
-     able to ask for a passphrase.  This has only an effect under W32
-     where the agent is started on demand; sending a NOP does not harm
-     on other platforms.  This is not really necessary anymore because
-     the protect tool does this now by itself; it does not harm either.*/
-  gpgsm_agent_send_nop (ctrl);
-
-  argv[i++] = "--homedir";
-  argv[i++] = opt.homedir;
-  argv[i++] = "--p12-export";
-  argv[i++] = "--have-cert";
-  argv[i++] = "--prompt";
-  argv[i++] = prompt?prompt:"";
-  argv[i++] = "--enable-status-msg";
-  if (opt.p12_charset)
-    {
-      argv[i++] = "--p12-charset";
-      argv[i++] = opt.p12_charset;
-    }
-  if (opt.agent_program)
-    {
-      argv[i++] = "--agent-program";
-      argv[i++] = opt.agent_program;
-    }
-  argv[i++] = "--",
-  argv[i++] = keygrip,
-  argv[i] = NULL;
-  assert (i < sizeof argv);
-
-  return gnupg_spawn_process (pgmname, argv, infile, outfile,
-                              setup_pinentry_env, (128|64),
-                              statusfile, pid);
+  gcry_sexp_t list, l2;
+  const char *name;
+  const char *s;
+  size_t n;
+  int idx;
+  const char *elems;
+  gcry_mpi_t *array;
+
+  list = gcry_sexp_find_token (sexp, "private-key", 0 );
+  if(!list)
+    return NULL;
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  name = gcry_sexp_nth_data (list, 0, &n);
+  if(!name || n != 3 || memcmp (name, "rsa", 3))
+    {
+      gcry_sexp_release (list);
+      return NULL;
+    }
+
+  /* Parameter names used with RSA in the pkcs#12 order. */
+  elems = "nedqp--u";
+  array = xtrycalloc (strlen(elems) + 1, sizeof *array);
+  if (!array)
+    {
+      gcry_sexp_release (list);
+      return NULL;
+    }
+  for (idx=0, s=elems; *s; s++, idx++ )
+    {
+      if (*s == '-')
+        continue; /* Computed below  */
+      l2 = gcry_sexp_find_token (list, s, 1);
+      if (l2)
+        {
+          array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+          gcry_sexp_release (l2);
+        }
+      if (!array[idx]) /* Required parameter not found or invalid.  */
+        {
+          for (idx=0; array[idx]; idx++)
+            gcry_mpi_release (array[idx]);
+          xfree (array);
+          gcry_sexp_release (list);
+          return NULL;
+        }
+    }
+  gcry_sexp_release (list);
+
+  array[5] = gcry_mpi_snew (0);  /* compute d mod (q-1) */
+  gcry_mpi_sub_ui (array[5], array[3], 1);
+  gcry_mpi_mod (array[5], array[2], array[5]);
+
+  array[6] = gcry_mpi_snew (0);  /* compute d mod (p-1) */
+  gcry_mpi_sub_ui (array[6], array[4], 1);
+  gcry_mpi_mod (array[6], array[3], array[6]);
+
+  return array;
 }
 
 
 static gpg_error_t
 export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen,
-            const char *prompt, const char *keygrip,
-            FILE **retfp)
+            const char *prompt, const char *keygrip, int rawmode,
+            void **r_result, size_t *r_resultlen)
 {
-  const char *pgmname;
-  gpg_error_t err = 0, child_err = 0;
-  int c, cont_line;
-  unsigned int pos;
-  FILE *infp = NULL, *outfp = NULL, *fp = NULL;
-  char buffer[1024];
-  pid_t pid = -1;
-  int bad_pass = 0;
-
-  if (!opt.protect_tool_program || !*opt.protect_tool_program)
-    pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL);
-  else
-    pgmname = opt.protect_tool_program;
+  gpg_error_t err = 0;
+  void *kek = NULL;
+  size_t keklen;
+  unsigned char *wrappedkey = NULL;
+  size_t wrappedkeylen;
+  gcry_cipher_hd_t cipherhd = NULL;
+  gcry_sexp_t s_skey = NULL;
+  gcry_mpi_t *kparms = NULL;
+  unsigned char *key = NULL;
+  size_t keylen;
+  char *passphrase = NULL;
+  unsigned char *result = NULL;
+  size_t resultlen;
+  int i;
+
+  *r_result = NULL;
 
-  infp = gnupg_tmpfile ();
-  if (!infp)
+  /* Get the current KEK.  */
+  err = gpgsm_agent_keywrap_key (ctrl, 1, &kek, &keklen);
+  if (err)
     {
-      err = gpg_error_from_syserror ();
-      log_error (_("error creating temporary file: %s\n"), strerror (errno));
-      goto cleanup;
+      log_error ("error getting the KEK: %s\n", gpg_strerror (err));
+      goto leave;
     }
 
-  if (fwrite (certimg, certimglen, 1, infp) != 1)
+  /* Receive the wrapped key from the agent.  */
+  err = gpgsm_agent_export_key (ctrl, keygrip, prompt,
+                                &wrappedkey, &wrappedkeylen);
+  if (err)
+    goto leave;
+
+
+  /* Unwrap the key.  */
+  err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
+                          GCRY_CIPHER_MODE_AESWRAP, 0);
+  if (err)
+    goto leave;
+  err = gcry_cipher_setkey (cipherhd, kek, keklen);
+  if (err)
+    goto leave;
+  xfree (kek);
+  kek = NULL;
+
+  if (wrappedkeylen < 24)
     {
-      err = gpg_error_from_syserror ();
-      log_error (_("error writing to temporary file: %s\n"),
-                 strerror (errno));
-      goto cleanup;
+      err = gpg_error (GPG_ERR_INV_LENGTH);
+      goto leave;
     }
-
-  outfp = gnupg_tmpfile ();
-  if (!outfp)
+  keylen = wrappedkeylen - 8;
+  key = xtrymalloc_secure (keylen);
+  if (!key)
     {
       err = gpg_error_from_syserror ();
-      log_error (_("error creating temporary file: %s\n"), strerror (errno));
-      goto cleanup;
+      goto leave;
     }
+  err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
+  if (err)
+    goto leave;
+  xfree (wrappedkey);
+  wrappedkey = NULL;
+  gcry_cipher_close (cipherhd);
+  cipherhd = NULL;
+
 
-  err = popen_protect_tool (ctrl, 
-                            pgmname, infp, outfp, &fp, prompt, keygrip, &pid);
+  /* Convert to a gcrypt S-expression.  */
+  err = gcry_sexp_create (&s_skey, key, keylen, 0, xfree_fnc);
   if (err)
-    {
-      pid = -1;
-      goto cleanup;
-    }
-  fclose (infp);
-  infp = NULL;
+    goto leave;
+  key = NULL; /* Key is now owned by S_KEY.  */
 
-  /* Read stderr of the protect tool. */
-  pos = 0;
-  cont_line = 0;
-  while ((c=getc (fp)) != EOF)
+  /* Get the parameters from the S-expression.  */
+  kparms = sexp_to_kparms (s_skey);
+  gcry_sexp_release (s_skey);
+  s_skey = NULL;
+  if (!kparms)
     {
-      /* 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, "bad-passphrase"))
-                    bad_pass++;
-                }
-              else 
-                log_info ("%s", buffer);
-            }
-          pos = 0;
-          cont_line = (c != '\n');
-        }
+      log_error ("error converting key parameters\n");
+      err = GPG_ERR_BAD_SECKEY;
+      goto leave;
     }
 
-  if (pos)
+  if (rawmode)
     {
-      buffer[pos] = 0;
-      if (cont_line)
-        log_printf ("%s\n", buffer);
-      else
-        log_info ("%s\n", buffer);
+      /* Export in raw mode, that is only the pkcs#1/#8 private key. */
+      result = p12_raw_build (kparms, rawmode, &resultlen);
+      if (!result)
+        err = gpg_error (GPG_ERR_GENERAL);
     }
-  else if (cont_line)
-    log_printf ("\n");
-
-  /* If we found no error in the output of the child, 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 (infp)
-    fclose (infp);
-  if (fp)
-    fclose (fp);
-  if (pid != -1)
+  else
     {
-      if (!gnupg_wait_process (pgmname, pid, NULL))
-        child_err = 0;
+      err = gpgsm_agent_ask_passphrase
+        (ctrl,
+         i18n_utf8 ("Please enter the passphrase to protect the "
+                    "new PKCS#12 object."),
+         1, &passphrase);
+      if (err)
+        goto leave;
+
+      result = p12_build (kparms, certimg, certimglen, passphrase,
+                          opt.p12_charset, &resultlen);
+      xfree (passphrase);
+      passphrase = NULL;
+      if (!result)
+        err = gpg_error (GPG_ERR_GENERAL);
     }
-  if (!err)
-    err = child_err;
-  if (err)
+
+ leave:
+  xfree (key);
+  gcry_sexp_release (s_skey);
+  if (kparms)
     {
-      if (outfp)
-        fclose (outfp);
+      for (i=0; kparms[i]; i++)
+        gcry_mpi_release (kparms[i]);
+      xfree (kparms);
     }
-  else
-    *retfp = outfp;
-  if (bad_pass)
+  gcry_cipher_close (cipherhd);
+  xfree (wrappedkey);
+  xfree (kek);
+
+  if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
     {
       /* During export this is the passphrase used to unprotect the
          key and not the pkcs#12 thing as in export.  Therefore we can
@@ -744,6 +736,15 @@ export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen,
          zero keyid by a regular one. */
       gpgsm_status (ctrl, STATUS_BAD_PASSPHRASE, "0000000000000000");
     }
+
+  if (err)
+    {
+      xfree (result);
+    }
+  else
+    {
+      *r_result = result;
+      *r_resultlen = resultlen;
+    }
   return err;
 }
-
index 4704f59..b849afb 100644 (file)
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
@@ -37,7 +37,7 @@
    allocates the array.  If r_len is not NULL, the length of the
    digest is returned; well, this can also be done by using
    gcry_md_get_algo_dlen().  If algo is 0, a SHA-1 will be used.
-   
+
    If there is a problem , the function does never return NULL but a
    digest of all 0xff.
  */
@@ -47,7 +47,7 @@ gpgsm_get_fingerprint (ksba_cert_t cert, int algo,
 {
   gcry_md_hd_t md;
   int rc, len;
-  
+
   if (!algo)
     algo = GCRY_MD_SHA1;
 
@@ -65,7 +65,7 @@ gpgsm_get_fingerprint (ksba_cert_t cert, int algo,
       size_t buflen;
 
       assert (len >= 20);
-      if (!ksba_cert_get_user_data (cert, "sha1-fingerprint", 
+      if (!ksba_cert_get_user_data (cert, "sha1-fingerprint",
                                     array, len, &buflen)
           && buflen == 20)
         return array;
@@ -149,8 +149,14 @@ gpgsm_get_short_fingerprint (ksba_cert_t cert, unsigned long *r_high)
 
   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL);
   if (r_high)
-    *r_high = ((digest[12]<<24)|(digest[13]<<16)|(digest[14]<< 8)|digest[15]);
-  return ((digest[16]<<24)|(digest[17]<<16)|(digest[18]<< 8)|digest[19]);
+    *r_high = (((unsigned long)digest[12]<<24)
+               |(digest[13]<<16)
+               |(digest[14]<< 8)
+               |digest[15]);
+  return (((unsigned long)digest[16]<<24)
+          |(digest[17]<<16)
+          |(digest[18]<<8)
+          |digest[19]);
 }
 
 \f
@@ -165,7 +171,7 @@ gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array)
   int rc;
   ksba_sexp_t p;
   size_t n;
-  
+
   p = ksba_cert_get_public_key (cert);
   if (!p)
     return NULL; /* oops */
@@ -234,7 +240,7 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
 
   p = ksba_cert_get_public_key (cert);
   if (!p)
-    return 0; 
+    return 0;
   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
   if (!n)
     {
@@ -282,7 +288,7 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
    serial number for this.  In most cases the serial number is not
    that large and the resulting string can be passed on an assuan
    command line.  Everything is hexencoded with the serialnumber
-   delimited from the hash by a dot. 
+   delimited from the hash by a dot.
 
    The caller must free the string.
 */
@@ -296,7 +302,7 @@ gpgsm_get_certid (ksba_cert_t cert)
   unsigned long n;
   char *certid;
   int i;
-  
+
   p = ksba_cert_get_issuer (cert, 0);
   if (!p)
     return NULL; /* Ooops: No issuer */
@@ -341,7 +347,3 @@ gpgsm_get_certid (ksba_cert_t cert)
   xfree (serial);
   return certid;
 }
-
-
-
-
index ebb7ed1..03b9bb9 100644 (file)
@@ -1,6 +1,6 @@
 /* gpgsm.c - GnuPG for S/MIME
- * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- *               2006, 2007, 2008  Free Software Foundation, Inc.
+ * Copyright (C) 2001-2008, 2010  Free Software Foundation, Inc.
+ * Copyright (C) 2001-2008, 2010  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -37,6 +37,8 @@
 #include "keydb.h"
 #include "sysutils.h"
 #include "gc-opt-flags.h"
+#include "asshelp.h"
+#include "../common/init.h"
 
 
 #ifndef O_BINARY
@@ -72,6 +74,8 @@ enum cmd_and_opt_values {
   aRecvKeys,
   aExport,
   aExportSecretKeyP12,
+  aExportSecretKeyP8,
+  aExportSecretKeyRaw,
   aServer,
   aLearnCard,
   aCallDirmngr,
@@ -143,6 +147,8 @@ enum cmd_and_opt_values {
 
   oWithFingerprint,
   oWithMD5Fingerprint,
+  oWithKeygrip,
+  oWithSecret,
   oAnswerYes,
   oAnswerNo,
   oKeyring,
@@ -186,10 +192,10 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_group (300, N_("@Commands:\n ")),
 
   ARGPARSE_c (aSign, "sign", N_("make a signature")),
-  ARGPARSE_c (aClearsign, "clearsign", N_("make a clear text signature") ),
+/*ARGPARSE_c (aClearsign, "clearsign", N_("make a clear text signature") ),*/
   ARGPARSE_c (aDetachedSign, "detach-sign", N_("make a detached signature")),
   ARGPARSE_c (aEncr, "encrypt", N_("encrypt data")),
-  ARGPARSE_c (aSym, "symmetric", N_("encryption only with symmetric cipher")),
+/*ARGPARSE_c (aSym, "symmetric", N_("encryption only with symmetric cipher")),*/
   ARGPARSE_c (aDecrypt, "decrypt", N_("decrypt data (default)")),
   ARGPARSE_c (aVerify, "verify",  N_("verify a signature")),
   ARGPARSE_c (aListKeys, "list-keys", N_("list keys")),
@@ -201,11 +207,17 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aKeygen, "gen-key", N_("generate a new key pair")),
   ARGPARSE_c (aDeleteKey, "delete-keys",
               N_("remove keys from the public keyring")),
-  ARGPARSE_c (aSendKeys, "send-keys", N_("export keys to a key server")),
-  ARGPARSE_c (aRecvKeys, "recv-keys", N_("import keys from a key server")),
+/*ARGPARSE_c (aSendKeys, "send-keys", N_("export keys to a key server")),*/
+/*ARGPARSE_c (aRecvKeys, "recv-keys", N_("import keys from a key server")),*/
   ARGPARSE_c (aImport, "import", N_("import certificates")),
   ARGPARSE_c (aExport, "export", N_("export certificates")),
+
+  /* We use -raw and not -p1 for pkcs#1 secret key export so that it
+     won't accidently be used in case -p12 was intended.  */
   ARGPARSE_c (aExportSecretKeyP12, "export-secret-key-p12", "@"),
+  ARGPARSE_c (aExportSecretKeyP8,  "export-secret-key-p8", "@"),
+  ARGPARSE_c (aExportSecretKeyRaw, "export-secret-key-raw", "@"),
+
   ARGPARSE_c (aLearnCard, "learn-card", N_("register a smartcard")),
   ARGPARSE_c (aServer, "server", N_("run in server mode")),
   ARGPARSE_c (aCallDirmngr, "call-dirmngr",
@@ -240,8 +252,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
 
-  ARGPARSE_s_n (oPreferSystemDirmngr,"prefer-system-dirmngr",
-                N_("use system's dirmngr if available")),
+  ARGPARSE_s_n (oPreferSystemDirmngr,"prefer-system-dirmngr", "@"),
 
   ARGPARSE_s_n (oDisableCRLChecks, "disable-crl-checks",
                 N_("never consult a CRL")),
@@ -372,6 +383,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oWithEphemeralKeys,  "with-ephemeral-keys", "@"),
   ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
   ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
+  ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
+  ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
@@ -408,13 +421,23 @@ static int allow_special_filenames;
 
 /* Default value for include-certs.  We need an extra macro for
    gpgconf-list because the variable will be changed by the command
-   line option.  */
+   line option.
+
+   It is often cumbersome to locate intermediate certificates, thus by
+   default we include all certificates in the chain.  However we leave
+   out the root certificate because that would make it too easy for
+   the recipient to import that root certificate.  A root certificate
+   should be installed only after due checks and thus it won't help to
+   send it along with each message.  */
 #define DEFAULT_INCLUDE_CERTS -2 /* Include all certs but root. */
 static int default_include_certs = DEFAULT_INCLUDE_CERTS;
 
 /* Whether the chain mode shall be used for validation.  */
 static int default_validation_model;
 
+/* The default cipher algo.  */
+#define DEFAULT_CIPHER_ALGO "3DES"  /*des-EDE3-CBC*/
+
 
 static char *build_list (const char *text,
                         const char *(*mapf)(int), int (*chkf)(int));
@@ -424,8 +447,7 @@ static void set_cmd (enum cmd_and_opt_values *ret_cmd,
 static void emergency_cleanup (void);
 static int check_special_filename (const char *fname, int for_write);
 static int open_read (const char *filename);
-static estream_t open_es_fread (const char *filename);
-static FILE *open_fwrite (const char *filename);
+static estream_t open_es_fread (const char *filename, const char *mode);
 static estream_t open_es_fwrite (const char *filename);
 static void run_protect_tool (int argc, char **argv);
 
@@ -512,17 +534,17 @@ my_strusage( int level )
 
   switch (level)
     {
-    case 11: p = "gpgsm (GnuPG)";
+    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 <@EMAIL@>.\n"); break;
 
     case 1:
-    case 40: p = _("Usage: gpgsm [options] [files] (-h for help)");
+    case 40: p = _("Usage: @GPGSM@ [options] [files] (-h for help)");
       break;
     case 41:
-      p = _("Syntax: gpgsm [options] [files]\n"
+      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;
@@ -543,7 +565,7 @@ my_strusage( int level )
     case 33: p = _("\nSupported algorithms:\n"); break;
     case 34:
       if (!ciphers)
-        ciphers = build_list ("Cipher: ", gcry_cipher_algo_name,
+        ciphers = build_list ("Cipher: ", gnupg_cipher_algo_name,
                               our_cipher_test_algo );
       p = ciphers;
       break;
@@ -614,9 +636,7 @@ set_binary (FILE *fp)
 static void
 wrong_args (const char *text)
 {
-  fputs (_("usage: gpgsm [options] "), stderr);
-  fputs (text, stderr);
-  putc ('\n', stderr);
+  fprintf (stderr, _("usage: %s [options] %s\n"), GPGSM_NAME, text);
   gpgsm_exit (2);
 }
 
@@ -666,7 +686,7 @@ set_debug (void)
     }
   else
     {
-      log_error (_("invalid debug-level `%s' given\n"), debug_level);
+      log_error (_("invalid debug-level '%s' given\n"), debug_level);
       gpgsm_exit (2);
     }
 
@@ -731,12 +751,12 @@ do_add_recipient (ctrl_t ctrl, const char *name,
     {
       if (recp_required)
         {
-          log_error ("can't encrypt to `%s': %s\n", name, gpg_strerror (rc));
+          log_error ("can't encrypt to '%s': %s\n", name, gpg_strerror (rc));
           gpgsm_status2 (ctrl, STATUS_INV_RECP,
                          get_inv_recpsgnr_code (rc), name, NULL);
         }
       else
-        log_info (_("NOTE: won't be able to encrypt to `%s': %s\n"),
+        log_info (_("Note: won't be able to encrypt to '%s': %s\n"),
                   name, gpg_strerror (rc));
     }
 }
@@ -747,7 +767,7 @@ parse_validation_model (const char *model)
 {
   int i = gpgsm_parse_validation_model (model);
   if (i == -1)
-    log_error (_("unknown validation model `%s'\n"), model);
+    log_error (_("unknown validation model '%s'\n"), model);
   else
     default_validation_model = i;
 }
@@ -840,7 +860,6 @@ parse_keyserver_line (char *line,
     {
       log_info (_("%s:%u: skipping this line\n"), filename, lineno);
       keyserver_list_free (server);
-      server = NULL;
     }
 
   return server;
@@ -888,23 +907,20 @@ main ( int argc, char **argv)
 
   /*mtrace();*/
 
-  gnupg_reopen_std ("gpgsm");
+  gnupg_reopen_std (GPGSM_NAME);
   /* trap_unaligned ();*/
   gnupg_rl_initialize ();
   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);
+  log_set_prefix (GPGSM_NAME, 1);
 
   /* Make sure that our subsystems are ready.  */
-  i18n_init();
-  init_common_subsystems ();
+  i18n_init ();
+  init_common_subsystems (&argc, &argv);
 
   /* Check that the libraries are suitable.  Do it here because the
      option parse may need services of the library */
@@ -922,7 +938,7 @@ main ( int argc, char **argv)
 
   gnupg_init_signals (0, emergency_cleanup);
 
-  create_dotlock (NULL); /* register locking cleanup */
+  dotlock_create (NULL, 0); /* Register lockfile cleanup.  */
 
   opt.session_env = session_env_new ();
   if (!opt.session_env)
@@ -931,10 +947,11 @@ main ( int argc, char **argv)
 
   /* Note: If you change this default cipher algorithm , please
      remember to update the Gpgconflist entry as well.  */
-  opt.def_cipher_algoid = "AES";
+  opt.def_cipher_algoid = DEFAULT_CIPHER_ALGO;
 
   opt.homedir = default_homedir ();
 
+
   /* First check whether we have a config file on the commandline */
   orig_argc = argc;
   orig_argv = argv;
@@ -978,8 +995,8 @@ main ( int argc, char **argv)
   malloc_hooks.realloc = gcry_realloc;
   malloc_hooks.free = gcry_free;
   assuan_set_malloc_hooks (&malloc_hooks);
-  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
+  setup_libassuan_logging (&opt.debug);
 
   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
 
@@ -992,7 +1009,7 @@ main ( int argc, char **argv)
 
   /* Set the default option file */
   if (default_config )
-    configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
+    configname = make_filename (opt.homedir, GPGSM_NAME EXTSEP_S "conf", NULL);
   /* Set the default policy file */
   opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
 
@@ -1011,18 +1028,18 @@ main ( int argc, char **argv)
         if (default_config)
           {
             if (parse_debug)
-              log_info (_("NOTE: no default option file `%s'\n"), configname);
+              log_info (_("Note: no default option file '%s'\n"), configname);
           }
         else
           {
-            log_error (_("option file `%s': %s\n"), configname, strerror(errno));
+            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);
+      log_info (_("reading options from '%s'\n"), configname);
     default_config = 0;
   }
 
@@ -1078,6 +1095,8 @@ main ( int argc, char **argv)
         case aRecvKeys:
         case aExport:
         case aExportSecretKeyP12:
+        case aExportSecretKeyP8:
+        case aExportSecretKeyRaw:
         case aDumpKeys:
         case aDumpChain:
         case aDumpExternalKeys:
@@ -1241,6 +1260,10 @@ main ( int argc, char **argv)
           opt.fingerprint++;
           break;
 
+        case oWithKeygrip:
+          opt.with_keygrip = 1;
+          break;
+
         case oOptions:
           /* config files may not be nested (silently ignore them) */
           if (!configfp)
@@ -1272,7 +1295,7 @@ main ( int argc, char **argv)
 
         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
         case oDisableDirmngr: opt.disable_dirmngr = 1;  break;
-        case oPreferSystemDirmngr: opt.prefer_system_dirmngr = 1; break;
+        case oPreferSystemDirmngr: /* Obsolete */; break;
         case oProtectToolProgram:
           opt.protect_tool_program = pargs.r.ret_str;
           break;
@@ -1313,6 +1336,7 @@ main ( int argc, char **argv)
 
         case oWithKeyData: opt.with_key_data=1; /* fall thru */
         case oWithColons: ctrl.with_colons = 1; break;
+        case oWithSecret: ctrl.with_secret = 1; break;
         case oWithValidation: ctrl.with_validation=1; break;
         case oWithEphemeralKeys: ctrl.with_ephemeral_keys=1; break;
 
@@ -1412,7 +1436,9 @@ main ( int argc, char **argv)
   configname = NULL;
 
   if (!opt.config_filename)
-    opt.config_filename = make_filename (opt.homedir, "gpgsm.conf", NULL);
+    opt.config_filename = make_filename (opt.homedir,
+                                         GPGSM_NAME EXTSEP_S "conf",
+                                         NULL);
 
   if (log_get_errorcount(0))
     gpgsm_exit(2);
@@ -1426,9 +1452,9 @@ main ( int argc, char **argv)
 
   if (greeting)
     {
-      fprintf(stderr, "%s %s; %s\n",
-              strusage(11), strusage(13), strusage(14) );
-      fprintf(stderr, "%s\n", strusage(15) );
+      es_fprintf (es_stderr, "%s %s; %s\n",
+                  strusage(11), strusage(13), strusage(14) );
+      es_fprintf (es_stderr, "%s\n", strusage(15) );
     }
 #  ifdef IS_DEVELOPMENT_VERSION
   if (!opt.batch)
@@ -1463,6 +1489,16 @@ main ( int argc, char **argv)
       log_printf ("\n");
     }
 
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+    {
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
+    }
+
 /*FIXME    if (opt.batch) */
 /*      tty_batchmode (1); */
 
@@ -1489,8 +1525,6 @@ main ( int argc, char **argv)
   else if (!strcmp (opt.def_cipher_algoid, "AES")
            || !strcmp (opt.def_cipher_algoid, "AES128"))
     opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.2";
-  else if (!strcmp (opt.def_cipher_algoid, "AES192") )
-    opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.22";
   else if (!strcmp (opt.def_cipher_algoid, "AES256") )
     opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.42";
   else if (!strcmp (opt.def_cipher_algoid, "SERPENT")
@@ -1498,7 +1532,7 @@ main ( int argc, char **argv)
     opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.2";
   else if (!strcmp (opt.def_cipher_algoid, "SERPENT192") )
     opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.22";
-  else if (!strcmp (opt.def_cipher_algoid, "SERPENT256") )
+  else if (!strcmp (opt.def_cipher_algoid, "SERPENT192") )
     opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.42";
   else if (!strcmp (opt.def_cipher_algoid, "SEED") )
     opt.def_cipher_algoid = "1.2.410.200004.1.4";
@@ -1559,7 +1593,7 @@ main ( int argc, char **argv)
           filelist[1] = NULL;
           if (!access (filelist[0], F_OK))
             {
-              log_info (_("importing common certificates `%s'\n"),
+              log_info (_("importing common certificates '%s'\n"),
                         filelist[0]);
               gpgsm_import_files (&ctrl, 1, filelist, open_read);
             }
@@ -1600,7 +1634,7 @@ main ( int argc, char **argv)
           int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist, 0);
           if (rc)
             {
-              log_error (_("can't sign using `%s': %s\n"),
+              log_error (_("can't sign using '%s': %s\n"),
                          sl->d, gpg_strerror (rc));
               gpgsm_status2 (&ctrl, STATUS_INV_SGNR,
                              get_inv_recpsgnr_code (rc), sl->d, NULL);
@@ -1635,35 +1669,35 @@ main ( int argc, char **argv)
       { /* List options and default values in the GPG Conf format.  */
        char *config_filename_esc = percent_escape (opt.config_filename, NULL);
 
-        printf ("gpgconf-gpgsm.conf:%lu:\"%s\n",
-                GC_OPT_FLAG_DEFAULT, config_filename_esc);
+        es_printf ("%s-%s.conf:%lu:\"%s\n",
+                   GPGCONF_NAME, GPGSM_NAME,
+                   GC_OPT_FLAG_DEFAULT, config_filename_esc);
         xfree (config_filename_esc);
 
-        printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
-       printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE);
-       printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
-       printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
-        printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE);
-        printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE);
-        printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE);
-        printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT,
-                DEFAULT_INCLUDE_CERTS);
-        printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE);
-        printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE);
-        printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
-#ifndef HAVE_W32_SYSTEM
-        printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
-#endif
-        printf ("cipher-algo:%lu:\"AES:\n", GC_OPT_FLAG_DEFAULT);
-        printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT);
-        printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT);
-        printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT);
-       printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
+       es_printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE);
+       es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
+       es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT,
+                   DEFAULT_INCLUDE_CERTS);
+        es_printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("cipher-algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
+                   DEFAULT_CIPHER_ALGO);
+        es_printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT);
+        es_printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT);
+        es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT);
+       es_printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
 
         /* The next one is an info only item and should match what
            proc_parameters actually implements.  */
-        printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
-                "RSA-2048");
+        es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
+                   "RSA-2048");
+
       }
       break;
     case aGPGConfTest:
@@ -1696,7 +1730,7 @@ main ( int argc, char **argv)
 
     case aEncr: /* Encrypt the given file. */
       {
-        FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-");
+        estream_t fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
 
         set_binary (stdin);
 
@@ -1707,14 +1741,13 @@ main ( int argc, char **argv)
         else
           wrong_args ("--encrypt [datafile]");
 
-        if (fp != stdout)
-          fclose (fp);
+        es_fclose (fp);
       }
       break;
 
     case aSign: /* Sign the given file. */
       {
-        FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-");
+        estream_t fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
 
         /* Fixme: We should also allow to concatenate multiple files for
            signing because that is what gpg does.*/
@@ -1727,8 +1760,7 @@ main ( int argc, char **argv)
         else
           wrong_args ("--sign [datafile]");
 
-        if (fp != stdout)
-          fclose (fp);
+        es_fclose (fp);
       }
       break;
 
@@ -1742,13 +1774,13 @@ main ( int argc, char **argv)
 
     case aVerify:
       {
-        FILE *fp = NULL;
+        estream_t fp = NULL;
 
         set_binary (stdin);
         if (argc == 2 && opt.outfile)
           log_info ("option --output ignored for a detached signature\n");
         else if (opt.outfile)
-          fp = open_fwrite (opt.outfile);
+          fp = open_es_fwrite (opt.outfile);
 
         if (!argc)
           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
@@ -1759,14 +1791,13 @@ main ( int argc, char **argv)
         else
           wrong_args ("--verify [signature [detached_data]]");
 
-        if (fp && fp != stdout)
-          fclose (fp);
+        es_fclose (fp);
       }
       break;
 
     case aDecrypt:
       {
-        FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-");
+        estream_t fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
 
         set_binary (stdin);
         if (!argc)
@@ -1775,8 +1806,8 @@ main ( int argc, char **argv)
           gpgsm_decrypt (&ctrl, open_read (*argv), fp); /* from file */
         else
           wrong_args ("--decrypt [filename]");
-        if (fp != stdout)
-          fclose (fp);
+
+        es_fclose (fp);
       }
       break;
 
@@ -1826,27 +1857,26 @@ main ( int argc, char **argv)
     case aKeygen: /* Generate a key; well kind of. */
       {
         estream_t fpin = NULL;
-        FILE *fpout;
+        estream_t fpout;
 
         if (opt.batch)
           {
             if (!argc) /* Create from stdin. */
-              fpin = open_es_fread ("-");
+              fpin = open_es_fread ("-", "r");
             else if (argc == 1) /* From file. */
-              fpin = open_es_fread (*argv);
+              fpin = open_es_fread (*argv, "r");
             else
               wrong_args ("--gen-key --batch [parmfile]");
           }
 
-        fpout = open_fwrite (opt.outfile?opt.outfile:"-");
+        fpout = open_es_fwrite (opt.outfile?opt.outfile:"-");
 
         if (fpin)
           gpgsm_genkey (&ctrl, fpin, fpout);
         else
           gpgsm_gencertreq_tty (&ctrl, fpout);
 
-        if (fpout != stdout)
-          fclose (fpout);
+        es_fclose (fpout);
       }
       break;
 
@@ -1857,27 +1887,53 @@ main ( int argc, char **argv)
 
     case aExport:
       {
-        FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-");
+        estream_t fp;
 
+        fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
         for (sl=NULL; argc; argc--, argv++)
           add_to_strlist (&sl, *argv);
-        gpgsm_export (&ctrl, sl, fp, NULL);
+        gpgsm_export (&ctrl, sl, fp);
         free_strlist(sl);
-        if (fp != stdout)
-          fclose (fp);
+        es_fclose (fp);
       }
       break;
 
     case aExportSecretKeyP12:
       {
-        FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-");
+        estream_t fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
 
         if (argc == 1)
-          gpgsm_p12_export (&ctrl, *argv, fp);
+          gpgsm_p12_export (&ctrl, *argv, fp, 0);
         else
           wrong_args ("--export-secret-key-p12 KEY-ID");
-        if (fp != stdout)
-          fclose (fp);
+        if (fp != es_stdout)
+          es_fclose (fp);
+      }
+      break;
+
+    case aExportSecretKeyP8:
+      {
+        estream_t fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
+
+        if (argc == 1)
+          gpgsm_p12_export (&ctrl, *argv, fp, 1);
+        else
+          wrong_args ("--export-secret-key-p8 KEY-ID");
+        if (fp != es_stdout)
+          es_fclose (fp);
+      }
+      break;
+
+    case aExportSecretKeyRaw:
+      {
+        estream_t fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
+
+        if (argc == 1)
+          gpgsm_p12_export (&ctrl, *argv, fp, 2);
+        else
+          wrong_args ("--export-secret-key-raw KEY-ID");
+        if (fp != es_stdout)
+          es_fclose (fp);
       }
       break;
 
@@ -2003,6 +2059,8 @@ gpgsm_parse_validation_model (const char *model)
     return 0;
   else if ( !ascii_strcasecmp (model, "chain") )
     return 1;
+  else if ( !ascii_strcasecmp (model, "steed") )
+    return 2;
   else
     return -1;
 }
@@ -2028,9 +2086,9 @@ check_special_filename (const char *fname, int for_write)
 
 
 
-/* Open the FILENAME for read and return the filedescriptor.  Stop
+/* Open the FILENAME for read and return the file descriptor.  Stop
    with an error message in case of problems.  "-" denotes stdin and
-   if special filenames are allowed the given fd is opened instead. */
+   if special filenames are allowed the given fd is opened instead.  */
 static int
 open_read (const char *filename)
 {
@@ -2047,7 +2105,7 @@ open_read (const char *filename)
   fd = open (filename, O_RDONLY | O_BINARY);
   if (fd == -1)
     {
-      log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
+      log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
       gpgsm_exit (2);
     }
   return fd;
@@ -2055,7 +2113,7 @@ open_read (const char *filename)
 
 /* Same as open_read but return an estream_t.  */
 static estream_t
-open_es_fread (const char *filename)
+open_es_fread (const char *filename, const char *mode)
 {
   int fd;
   estream_t fp;
@@ -2066,7 +2124,7 @@ open_es_fread (const char *filename)
     fd = check_special_filename (filename, 0);
   if (fd != -1)
     {
-      fp = es_fdopen_nc (fd, "rb");
+      fp = es_fdopen_nc (fd, mode);
       if (!fp)
         {
           log_error ("es_fdopen(%d) failed: %s\n", fd, strerror (errno));
@@ -2074,48 +2132,10 @@ open_es_fread (const char *filename)
         }
       return fp;
     }
-  fp = es_fopen (filename, "rb");
-  if (!fp)
-    {
-      log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
-      gpgsm_exit (2);
-    }
-  return fp;
-}
-
-
-/* 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])
-    {
-      set_binary (stdout);
-      return stdout;
-    }
-
-  fd = check_special_filename (filename, 1);
-  if (fd != -1)
-    {
-      fp = fdopen (dup (fd), "wb");
-      if (!fp)
-        {
-          log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
-          gpgsm_exit (2);
-        }
-      set_binary (fp);
-      return fp;
-    }
-  fp = fopen (filename, "wb");
+  fp = es_fopen (filename, mode);
   if (!fp)
     {
-      log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
+      log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
       gpgsm_exit (2);
     }
   return fp;
@@ -2153,7 +2173,7 @@ open_es_fwrite (const char *filename)
   fp = es_fopen (filename, "wb");
   if (!fp)
     {
-      log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
+      log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
       gpgsm_exit (2);
     }
   return fp;
@@ -2163,7 +2183,10 @@ open_es_fwrite (const char *filename)
 static void
 run_protect_tool (int argc, char **argv)
 {
-#ifndef HAVE_W32_SYSTEM
+#ifdef HAVE_W32_SYSTEM
+  (void)argc;
+  (void)argv;
+#else
   const char *pgm;
   char **av;
   int i;
@@ -2181,7 +2204,7 @@ run_protect_tool (int argc, char **argv)
     av[i] = *argv;
   av[i] = NULL;
   execv (pgm, av);
-  log_error ("error executing `%s': %s\n", pgm, strerror (errno));
-#endif /*HAVE_W32_SYSTEM*/
+  log_error ("error executing '%s': %s\n", pgm, strerror (errno));
+#endif /*!HAVE_W32_SYSTEM*/
   gpgsm_exit (2);
 }
index 25a2e5b..e8322b7 100644 (file)
@@ -1,5 +1,6 @@
 /* gpgsm.h - Global definitions for GpgSM
- * Copyright (C) 2001, 2003, 2004, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2007, 2009,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -30,7 +31,6 @@
 #include <ksba.h>
 #include "../common/util.h"
 #include "../common/status.h"
-#include "../common/estream.h"
 #include "../common/audit.h"
 #include "../common/session-env.h"
 
@@ -70,7 +70,6 @@ struct
   char *lc_messages;
 
   const char *dirmngr_program;
-  int prefer_system_dirmngr;  /* Prefer using a system wide drimngr.  */
   int disable_dirmngr;        /* Do not do any dirmngr calls.  */
   const char *protect_tool_program;
   char *outfile;    /* name of output file */
@@ -82,6 +81,8 @@ struct
   int with_md5_fingerprint; /* Also print an MD5 fingerprint for
                                standard key listings. */
 
+  int with_keygrip; /* Option --with-keygrip active.  */
+
   int armor;        /* force base64 armoring (see also ctrl.with_base64) */
   int no_armor;     /* don't try to figure out whether data is base64 armored*/
 
@@ -177,6 +178,7 @@ struct server_control_s
                          accessed.  */
 
   int with_colons;    /* Use column delimited output format */
+  int with_secret;    /* Mark secret keys in a public key listing.  */
   int with_chain;     /* Include the certifying certs in a listing */
   int with_validation;/* Validate each key while listing. */
   int with_ephemeral_keys;  /* Include ephemeral flagged keys in the
@@ -195,7 +197,9 @@ struct server_control_s
                          certificates up the chain (0 = none, 1 = only
                          signer) */
   int use_ocsp;       /* Set to true if OCSP should be used. */
-  int validation_model; /* Set to 1 for the chain model.  */
+  int validation_model; /* 0 := standard model (shell),
+                           1 := chain model,
+                           2 := STEED model. */
 };
 
 
@@ -256,12 +260,12 @@ 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,
+                          ctrl_t ctrl, estream_t 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, estream_t stream,
+                          ctrl_t ctrl, estream_t stream,
                           ksba_writer_t *r_writer);
 int  gpgsm_finish_writer (Base64Context ctx);
 void gpgsm_destroy_writer (Base64Context ctx);
@@ -307,7 +311,7 @@ int gpgsm_create_cms_signature (ctrl_t ctrl,
 /* Flags used with  gpgsm_validate_chain.  */
 #define VALIDATE_FLAG_NO_DIRMNGR  1
 #define VALIDATE_FLAG_CHAIN_MODEL 2
-
+#define VALIDATE_FLAG_STEED       4
 
 int gpgsm_walk_cert_chain (ctrl_t ctrl,
                            ksba_cert_t start, ksba_cert_t *r_next);
@@ -326,6 +330,7 @@ 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_cert_use_ocsp_p (ksba_cert_t cert);
+int gpgsm_cert_has_well_known_private_key (ksba_cert_t cert);
 int gpgsm_certs_identical_p (ksba_cert_t cert_a, ksba_cert_t cert_b);
 int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
                                 certlist_t *listaddr, int is_encrypt_to);
@@ -344,31 +349,33 @@ 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_t names, FILE *fp, estream_t stream);
-void gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp);
+void gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream);
+void gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream,
+                       int rawmode);
 
 /*-- delete.c --*/
 int gpgsm_delete (ctrl_t ctrl, strlist_t names);
 
 /*-- verify.c --*/
-int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp);
+int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp);
 
 /*-- sign.c --*/
 int gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert);
 int gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
-                int data_fd, int detached, FILE *out_fp);
+                int data_fd, int detached, estream_t out_fp);
 
 /*-- encrypt.c --*/
-int gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int in_fd, FILE *out_fp);
+int gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist,
+                   int in_fd, estream_t out_fp);
 
 /*-- decrypt.c --*/
-int gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp);
+int gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp);
 
 /*-- certreqgen.c --*/
-int gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, FILE *out_fp);
+int gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, estream_t out_stream);
 
 /*-- certreqgen-ui.c --*/
-void gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *out_fp);
+void gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t out_stream);
 
 
 /*-- qualified.c --*/
@@ -405,6 +412,16 @@ gpg_error_t gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc);
 gpg_error_t gpgsm_agent_send_nop (ctrl_t ctrl);
 gpg_error_t gpgsm_agent_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
                                  char **r_serialno);
+gpg_error_t gpgsm_agent_ask_passphrase (ctrl_t ctrl, const char *desc_msg,
+                                        int repeat, char **r_passphrase);
+gpg_error_t gpgsm_agent_keywrap_key (ctrl_t ctrl, int forexport,
+                                     void **r_kek, size_t *r_keklen);
+gpg_error_t gpgsm_agent_import_key (ctrl_t ctrl,
+                                    const void *key, size_t keylen);
+gpg_error_t gpgsm_agent_export_key (ctrl_t ctrl, const char *keygrip,
+                                    const char *desc,
+                                    unsigned char **r_result,
+                                    size_t *r_resultlen);
 
 /*-- call-dirmngr.c --*/
 int gpgsm_dirmngr_isvalid (ctrl_t ctrl,
@@ -418,6 +435,10 @@ int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
 
 /*-- misc.c --*/
 void setup_pinentry_env (void);
+gpg_error_t transform_sigval (const unsigned char *sigval, size_t sigvallen,
+                              int mdalgo,
+                              unsigned char **r_newsigval,
+                              size_t *r_newsigvallen);
 
 
 
index 287e723..3635525 100644 (file)
@@ -1,5 +1,5 @@
 /* import.c - Import certificates
- * Copyright (C) 2001, 2003, 2004, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include "i18n.h"
 #include "sysutils.h"
 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
+#include "../common/membuf.h"
+#include "minip12.h"
+
+/* The arbitrary limit of one PKCS#12 object.  */
+#define MAX_P12OBJ_SIZE 128 /*kb*/
 
 
 struct stats_s {
@@ -48,7 +53,18 @@ struct stats_s {
  };
 
 
-static gpg_error_t parse_p12 (ctrl_t ctrl, ksba_reader_t reader, FILE **retfp,
+struct rsa_secret_key_s
+{
+  gcry_mpi_t n;            /* public modulus */
+  gcry_mpi_t e;            /* public exponent */
+  gcry_mpi_t d;            /* exponent */
+  gcry_mpi_t p;            /* prime  p. */
+  gcry_mpi_t q;            /* prime  q. */
+  gcry_mpi_t u;            /* inverse of p mod q. */
+};
+
+
+static gpg_error_t parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
                               struct stats_s *stats);
 
 
@@ -57,12 +73,12 @@ static void
 print_imported_status (ctrl_t 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, 
+  gpgsm_status2 (ctrl, STATUS_IMPORT_OK,
                  new_cert? "1":"0",  fpr, NULL);
 
   xfree (fpr);
@@ -109,7 +125,7 @@ print_imported_summary (ctrl_t ctrl, struct stats_s *stats)
   if (!opt.quiet)
     {
       log_info (_("total number processed: %lu\n"), stats->count);
-      if (stats->imported) 
+      if (stats->imported)
         {
           log_info (_("              imported: %lu"), stats->imported );
           log_printf ("\n");
@@ -170,8 +186,8 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats,
      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 (ctrl, cert);
@@ -199,7 +215,7 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats,
               if (stats)
                 stats->unchanged++;
             }
-            
+
           if (opt.verbose > 1 && existed)
             {
               if (depth)
@@ -241,7 +257,7 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats,
       /* We keep the test for GPG_ERR_MISSING_CERT only in case
          GPG_ERR_MISSING_CERT has been used instead of the newer
          GPG_ERR_MISSING_ISSUER_CERT.  */
-      print_import_problem 
+      print_import_problem
         (ctrl, cert,
          gpg_err_code (rc) == GPG_ERR_MISSING_ISSUER_CERT? 2 :
          gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 :
@@ -260,14 +276,14 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
   ksba_reader_t reader;
   ksba_cert_t cert = NULL;
   ksba_cms_t cms = NULL;
-  FILE *fp = NULL;
+  estream_t fp = NULL;
   ksba_content_type_t ct;
   int any = 0;
 
-  fp = fdopen ( dup (in_fd), "rb");
+  fp = es_fdopen_nc (in_fd, "rb");
   if (!fp)
     {
-      rc = gpg_error (gpg_err_code_from_errno (errno));
+      rc = gpg_error_from_syserror ();
       log_error ("fdopen() failed: %s\n", strerror (errno));
       goto leave;
     }
@@ -278,25 +294,25 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
       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)
             {
@@ -305,7 +321,7 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
               goto leave;
             }
 
-          do 
+          do
             {
               rc = ksba_cms_parse (cms, &stopreason);
               if (rc)
@@ -317,12 +333,12 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
               if (stopreason == KSBA_SR_BEGIN_DATA)
                 log_info ("not a certs-only message\n");
             }
-          while (stopreason != KSBA_SR_READY);   
-      
+          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); 
+              ksba_cert_release (cert);
               cert = NULL;
             }
           if (!i)
@@ -331,51 +347,11 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
             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 (ctrl, reader, &certfp, stats);
+        {
+          /* This seems to be a pkcs12 message. */
+          rc = parse_p12 (ctrl, reader, 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;
-            }
+            any = 1;
         }
       else if (ct == KSBA_CT_NONE)
         { /* Failed to identify this message - assume a certificate */
@@ -396,7 +372,7 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
           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));
@@ -407,8 +383,7 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
   ksba_cms_release (cms);
   ksba_cert_release (cert);
   gpgsm_destroy_reader (b64reader);
-  if (fp)
-    fclose (fp);
+  es_fclose (fp);
   return rc;
 }
 
@@ -436,7 +411,7 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
       goto leave;
     }
   keydb_set_ephemeral (kh, 1);
-   
+
   fp = es_fdopen_nc (in_fd, "r");
   if (!fp)
     {
@@ -455,10 +430,10 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
       trim_spaces (line);
       if (!*line)
         continue;
-    
+
       stats->count++;
 
-      err = keydb_classify_name (line, &desc);
+      err = classify_user_id (line, &desc, 0);
       if (err)
         {
           print_import_problem (ctrl, NULL, 0);
@@ -506,7 +481,7 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
       if (err)
         {
           log_error ("clearing ephemeral flag failed: %s\n",
-                     gpg_strerror (err)); 
+                     gpg_strerror (err));
           print_import_problem (ctrl, cert, 0);
           stats->not_imported++;
           continue;
@@ -561,7 +536,7 @@ gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files,
   struct stats_s stats;
 
   memset (&stats, 0, sizeof stats);
-  
+
   if (!nfiles)
     rc = import_one (ctrl, &stats, 0);
   else
@@ -585,212 +560,364 @@ gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files,
 }
 
 
-/* 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. */
+/* Check that the RSA secret key SKEY is valid.  Swap parameters to
+   the libgcrypt standard.  */
 static gpg_error_t
-popen_protect_tool (ctrl_t ctrl, const char *pgmname,
-                    FILE *infile, FILE *outfile, FILE **statusfile, pid_t *pid)
+rsa_key_check (struct rsa_secret_key_s *skey)
+{
+  int err = 0;
+  gcry_mpi_t t = gcry_mpi_snew (0);
+  gcry_mpi_t t1 = gcry_mpi_snew (0);
+  gcry_mpi_t t2 = gcry_mpi_snew (0);
+  gcry_mpi_t phi = gcry_mpi_snew (0);
+
+  /* Check that n == p * q.  */
+  gcry_mpi_mul (t, skey->p, skey->q);
+  if (gcry_mpi_cmp( t, skey->n) )
+    {
+      log_error ("RSA oops: n != p * q\n");
+      err++;
+    }
+
+  /* Check that p is less than q.  */
+  if (gcry_mpi_cmp (skey->p, skey->q) > 0)
+    {
+      gcry_mpi_t tmp;
+
+      log_info ("swapping secret primes\n");
+      tmp = gcry_mpi_copy (skey->p);
+      gcry_mpi_set (skey->p, skey->q);
+      gcry_mpi_set (skey->q, tmp);
+      gcry_mpi_release (tmp);
+      /* Recompute u.  */
+      gcry_mpi_invm (skey->u, skey->p, skey->q);
+    }
+
+  /* Check that e divides neither p-1 nor q-1.  */
+  gcry_mpi_sub_ui (t, skey->p, 1 );
+  gcry_mpi_div (NULL, t, t, skey->e, 0);
+  if (!gcry_mpi_cmp_ui( t, 0) )
+    {
+      log_error ("RSA oops: e divides p-1\n");
+      err++;
+    }
+  gcry_mpi_sub_ui (t, skey->q, 1);
+  gcry_mpi_div (NULL, t, t, skey->e, 0);
+  if (!gcry_mpi_cmp_ui( t, 0))
+    {
+      log_info ("RSA oops: e divides q-1\n" );
+      err++;
+    }
+
+  /* Check that d is correct.  */
+  gcry_mpi_sub_ui (t1, skey->p, 1);
+  gcry_mpi_sub_ui (t2, skey->q, 1);
+  gcry_mpi_mul (phi, t1, t2);
+  gcry_mpi_invm (t, skey->e, phi);
+  if (gcry_mpi_cmp (t, skey->d))
+    {
+      /* No: try universal exponent. */
+      gcry_mpi_gcd (t, t1, t2);
+      gcry_mpi_div (t, NULL, phi, t, 0);
+      gcry_mpi_invm (t, skey->e, t);
+      if (gcry_mpi_cmp (t, skey->d))
+        {
+          log_error ("RSA oops: bad secret exponent\n");
+          err++;
+        }
+    }
+
+  /* Check for correctness of u.  */
+  gcry_mpi_invm (t, skey->p, skey->q);
+  if (gcry_mpi_cmp (t, skey->u))
+    {
+      log_info ("RSA oops: bad u parameter\n");
+      err++;
+    }
+
+  if (err)
+    log_info ("RSA secret key check failed\n");
+
+  gcry_mpi_release (t);
+  gcry_mpi_release (t1);
+  gcry_mpi_release (t2);
+  gcry_mpi_release (phi);
+
+  return err? gpg_error (GPG_ERR_BAD_SECKEY):0;
+}
+
+
+/* Object passed to store_cert_cb.  */
+struct store_cert_parm_s
 {
-  const char *argv[22];
-  int i=0;
-
-  /* Make sure that the agent is running so that the protect tool is
-     able to ask for a passphrase.  This has only an effect under W32
-     where the agent is started on demand; sending a NOP does not harm
-     on other platforms.  This is not really necessary anymore because
-     the protect tool does this now by itself; it does not harm either. */
-  gpgsm_agent_send_nop (ctrl);
-
-  argv[i++] = "--homedir";
-  argv[i++] = opt.homedir;
-  argv[i++] = "--p12-import";
-  argv[i++] = "--store";
-  argv[i++] = "--no-fail-on-exist";
-  argv[i++] = "--enable-status-msg";
-  if (opt.fixed_passphrase)
-    {
-      argv[i++] = "--passphrase";
-      argv[i++] = opt.fixed_passphrase;
-    }
-  if (opt.agent_program)
-    {
-      argv[i++] = "--agent-program";
-      argv[i++] = opt.agent_program;
-    }
-  argv[i++] = "--",
-  argv[i] = NULL;
-  assert (i < sizeof argv);
-
-  return gnupg_spawn_process (pgmname, argv, infile, outfile,
-                              setup_pinentry_env, (128 | 64),
-                              statusfile, pid);
+  gpg_error_t err;        /* First error seen.  */
+  struct stats_s *stats;  /* The stats object.  */
+  ctrl_t ctrl;            /* The control object.  */
+};
+
+/* Helper to store the DER encoded certificate CERTDATA of length
+   CERTDATALEN.  */
+static void
+store_cert_cb (void *opaque,
+               const unsigned char *certdata, size_t certdatalen)
+{
+  struct store_cert_parm_s *parm = opaque;
+  gpg_error_t err;
+  ksba_cert_t cert;
+
+  err = ksba_cert_new (&cert);
+  if (err)
+    {
+      if (!parm->err)
+        parm->err = err;
+      return;
+    }
+
+  err = ksba_cert_init_from_mem (cert, certdata, certdatalen);
+  if (err)
+    {
+      log_error ("failed to parse a certificate: %s\n", gpg_strerror (err));
+      if (!parm->err)
+        parm->err = err;
+    }
+  else
+    check_and_store (parm->ctrl, parm->stats, cert, 0);
+  ksba_cert_release (cert);
 }
 
 
 /* Assume that the reader is at a pkcs#12 message and try to import
-   certificates from that stupid format.  We will also 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. */
+   certificates from that stupid format.  We will transfer secret
+   keys to the agent.  */
 static gpg_error_t
-parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
-           FILE **retfp, struct stats_s *stats)
+parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
 {
-  const char *pgmname;
-  gpg_error_t err = 0, child_err = 0;
-  int c, cont_line;
-  unsigned int pos;
-  FILE *tmpfp, *certfp = NULL, *fp = NULL;
+  gpg_error_t err = 0;
   char buffer[1024];
-  size_t nread;
-  pid_t pid = -1;
+  size_t ntotal, nread;
+  membuf_t p12mbuf;
+  char *p12buffer = NULL;
+  size_t p12buflen;
+  size_t p12bufoff;
+  gcry_mpi_t *kparms = NULL;
+  struct rsa_secret_key_s sk;
+  char *passphrase = NULL;
+  unsigned char *key = NULL;
+  size_t keylen;
+  void *kek = NULL;
+  size_t keklen;
+  unsigned char *wrappedkey = NULL;
+  size_t wrappedkeylen;
+  gcry_cipher_hd_t cipherhd = NULL;
+  gcry_sexp_t s_key = NULL;
+  unsigned char grip[20];
   int bad_pass = 0;
+  int i;
+  struct store_cert_parm_s store_cert_parm;
 
-  if (!opt.protect_tool_program || !*opt.protect_tool_program)
-    pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL);
-  else
-    pgmname = opt.protect_tool_program;
-
-  *retfp = NULL;
+  memset (&store_cert_parm, 0, sizeof store_cert_parm);
+  store_cert_parm.ctrl = ctrl;
+  store_cert_parm.stats = stats;
 
-  /* 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 = gnupg_tmpfile ();
-  if (!tmpfp)
-    {
-      err = gpg_error_from_syserror ();
-      log_error (_("error creating temporary file: %s\n"), strerror (errno));
-      goto cleanup;
-    }
+  init_membuf (&p12mbuf, 4096);
+  ntotal = 0;
   while (!(err = ksba_reader_read (reader, buffer, sizeof buffer, &nread)))
     {
-      if (nread && fwrite (buffer, nread, 1, tmpfp) != 1)
+      if (ntotal >= MAX_P12OBJ_SIZE*1024)
         {
-          err = gpg_error_from_syserror ();
-          log_error (_("error writing to temporary file: %s\n"),
-                     strerror (errno));
-          goto cleanup;
+          /* Arbitrary limit to avoid DoS attacks. */
+          err = gpg_error (GPG_ERR_TOO_LARGE);
+          log_error ("pkcs#12 object is larger than %dk\n", MAX_P12OBJ_SIZE);
+          break;
         }
+      put_membuf (&p12mbuf, buffer, nread);
+      ntotal += nread;
     }
   if (gpg_err_code (err) == GPG_ERR_EOF)
     err = 0;
+  if (!err)
+    {
+      p12buffer = get_membuf (&p12mbuf, &p12buflen);
+      if (!p12buffer)
+        err = gpg_error_from_syserror ();
+    }
   if (err)
     {
       log_error (_("error reading input: %s\n"), gpg_strerror (err));
-      goto cleanup;
+      goto leave;
     }
 
-  certfp = gnupg_tmpfile ();
-  if (!certfp)
+  /* GnuPG 2.0.4 accidently created binary P12 files with the string
+     "The passphrase is %s encoded.\n\n" prepended to the ASN.1 data.
+     We fix that here.  */
+  if (p12buflen > 29 && !memcmp (p12buffer, "The passphrase is ", 18))
     {
-      err = gpg_error_from_syserror ();
-      log_error (_("error creating temporary file: %s\n"), strerror (errno));
-      goto cleanup;
+      for (p12bufoff=18;
+           p12bufoff < p12buflen && p12buffer[p12bufoff] != '\n';
+           p12bufoff++)
+        ;
+      p12bufoff++;
+      if (p12bufoff < p12buflen && p12buffer[p12bufoff] == '\n')
+        p12bufoff++;
     }
+  else
+    p12bufoff = 0;
+
 
-  err = popen_protect_tool (ctrl, pgmname, tmpfp, certfp, &fp, &pid);
+  err = gpgsm_agent_ask_passphrase
+    (ctrl,
+     i18n_utf8 ("Please enter the passphrase to unprotect the PKCS#12 object."),
+     0, &passphrase);
   if (err)
+    goto leave;
+
+  kparms = p12_parse (p12buffer + p12bufoff, p12buflen - p12bufoff,
+                      passphrase, store_cert_cb, &store_cert_parm, &bad_pass);
+
+  xfree (passphrase);
+  passphrase = NULL;
+
+  if (!kparms)
     {
-      pid = -1;
-      goto cleanup;
+      log_error ("error parsing or decrypting the PKCS#12 file\n");
+      err = gpg_error (GPG_ERR_INV_OBJ);
+      goto leave;
     }
-  fclose (tmpfp);
-  tmpfp = NULL;
 
-  /* Read stderr of the protect tool. */
-  pos = 0;
-  cont_line = 0;
-  while ((c=getc (fp)) != EOF)
+/*    print_mpi ("   n", kparms[0]); */
+/*    print_mpi ("   e", kparms[1]); */
+/*    print_mpi ("   d", kparms[2]); */
+/*    print_mpi ("   p", kparms[3]); */
+/*    print_mpi ("   q", kparms[4]); */
+/*    print_mpi ("dmp1", kparms[5]); */
+/*    print_mpi ("dmq1", kparms[6]); */
+/*    print_mpi ("   u", kparms[7]); */
+
+  sk.n = kparms[0];
+  sk.e = kparms[1];
+  sk.d = kparms[2];
+  sk.q = kparms[3];
+  sk.p = kparms[4];
+  sk.u = kparms[7];
+  err = rsa_key_check (&sk);
+  if (err)
+    goto leave;
+/*    print_mpi ("   n", sk.n); */
+/*    print_mpi ("   e", sk.e); */
+/*    print_mpi ("   d", sk.d); */
+/*    print_mpi ("   p", sk.p); */
+/*    print_mpi ("   q", sk.q); */
+/*    print_mpi ("   u", sk.u); */
+
+  /* Create an S-expresion from the parameters. */
+  err = gcry_sexp_build (&s_key, NULL,
+                         "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
+                         sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL);
+  for (i=0; i < 8; i++)
+    gcry_mpi_release (kparms[i]);
+  gcry_free (kparms);
+  kparms = NULL;
+  if (err)
     {
-      /* 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);
-                  if (!strncmp (buffer, "gpg-protect-tool: "
-                                "possibly bad passphrase given",46))
-                    bad_pass++;
-                }
-            }
-          pos = 0;
-          cont_line = (c != '\n');
-        }
+      log_error ("failed to create S-expression from key: %s\n",
+                 gpg_strerror (err));
+      goto leave;
     }
 
-  if (pos)
+  /* Compute the keygrip. */
+  if (!gcry_pk_get_keygrip (s_key, grip))
     {
-      buffer[pos] = 0;
-      if (cont_line)
-        log_printf ("%s\n", buffer);
-      else
-        log_info ("%s\n", buffer);
+      err = gpg_error (GPG_ERR_GENERAL);
+      log_error ("can't calculate keygrip\n");
+      goto leave;
     }
+  log_printhex ("keygrip=", grip, 20);
 
+  /* Convert to canonical encoding using a function which pads it to a
+     multiple of 64 bits.  We need this padding for AESWRAP.  */
+  err = make_canon_sexp_pad (s_key, 1, &key, &keylen);
+  if (err)
+    {
+      log_error ("error creating canonical S-expression\n");
+      goto leave;
+    }
+  gcry_sexp_release (s_key);
+  s_key = NULL;
+
+  /* Get the current KEK.  */
+  err = gpgsm_agent_keywrap_key (ctrl, 0, &kek, &keklen);
+  if (err)
+    {
+      log_error ("error getting the KEK: %s\n", gpg_strerror (err));
+      goto leave;
+    }
 
-  /* If we found no error in the output of the child, 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);
+  /* Wrap the key.  */
+  err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
+                          GCRY_CIPHER_MODE_AESWRAP, 0);
+  if (err)
+    goto leave;
+  err = gcry_cipher_setkey (cipherhd, kek, keklen);
+  if (err)
+    goto leave;
+  xfree (kek);
+  kek = NULL;
 
- cleanup:
-  if (tmpfp)
-    fclose (tmpfp);
-  if (fp)
-    fclose (fp);
-  if (pid != -1)
+  wrappedkeylen = keylen + 8;
+  wrappedkey = xtrymalloc (wrappedkeylen);
+  if (!wrappedkey)
     {
-      if (!gnupg_wait_process (pgmname, pid, NULL))
-        child_err = 0;
+      err = gpg_error_from_syserror ();
+      goto leave;
     }
-  if (!err)
-    err = child_err;
+
+  err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
   if (err)
+    goto leave;
+  xfree (key);
+  key = NULL;
+  gcry_cipher_close (cipherhd);
+  cipherhd = NULL;
+
+  /* Send the wrapped key to the agent.  */
+  err = gpgsm_agent_import_key (ctrl, wrappedkey, wrappedkeylen);
+  if (!err)
     {
-      if (certfp)
-        fclose (certfp);
+      stats->count++;
+      stats->secret_read++;
+      stats->secret_imported++;
     }
-  else
-    *retfp = certfp;
+  else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
+    {
+      err = 0;
+      stats->count++;
+      stats->secret_read++;
+      stats->secret_dups++;
+    }
+
+  /* If we did not get an error from storing the secret key we return
+     a possible error from parsing the certificates.  We do this after
+     storing the secret keys so that a bad certificate does not
+     inhibit our chance to store the secret key.  */
+  if (!err && store_cert_parm.err)
+    err = store_cert_parm.err;
+
+ leave:
+  if (kparms)
+    {
+      for (i=0; i < 8; i++)
+        gcry_mpi_release (kparms[i]);
+      gcry_free (kparms);
+      kparms = NULL;
+    }
+  xfree (key);
+  gcry_sexp_release (s_key);
+  xfree (passphrase);
+  gcry_cipher_close (cipherhd);
+  xfree (wrappedkey);
+  xfree (kek);
+  xfree (get_membuf (&p12mbuf, NULL));
+  xfree (p12buffer);
 
   if (bad_pass)
     {
@@ -802,6 +929,6 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
       gpgsm_status_with_err_code (ctrl, STATUS_ERROR,
                                   "import.parsep12", GPG_ERR_BAD_PASSPHRASE);
     }
-  
+
   return err;
 }
index 4fc5e8c..974625d 100644 (file)
@@ -26,7 +26,6 @@
 #include <assert.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
 #include <unistd.h>
 
 #include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
-#ifdef MKDIR_TAKES_ONE_ARG
-#undef mkdir
-#define mkdir(a,b) mkdir(a)
-#endif
-
 static int active_handles;
 
 typedef enum {
@@ -54,7 +48,7 @@ struct resource_item {
   } u;
   void *token;
   int secret;
-  DOTLOCK lockhandle;
+  dotlock_t lockhandle;
 };
 
 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
@@ -99,11 +93,11 @@ try_make_homedir (const char *fname)
 #endif
       )
     {
-      if ( mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
-        log_info (_("can't create directory `%s': %s\n"),
+      if (gnupg_mkdir (fname, "-rwx"))
+        log_info (_("can't create directory '%s': %s\n"),
                   fname, strerror(errno) );
       else if (!opt.quiet )
-        log_info (_("directory `%s' created\n"), fname);
+        log_info (_("directory '%s' created\n"), fname);
     }
 }
 
@@ -116,7 +110,7 @@ try_make_homedir (const char *fname)
 static int
 maybe_create_keybox (char *filename, int force, int *r_created)
 {
-  DOTLOCK lockhd = NULL;
+  dotlock_t lockhd = NULL;
   FILE *fp;
   int rc;
   mode_t oldmask;
@@ -175,7 +169,7 @@ maybe_create_keybox (char *filename, int force, int *r_created)
   /* To avoid races with other instances of gpg trying to create or
      update the keybox (it is removed during an update for a short
      time), we do the next stuff in a locked state. */
-  lockhd = create_dotlock (filename);
+  lockhd = dotlock_create (filename, 0);
   if (!lockhd)
     {
       /* A reason for this to fail is that the directory is not
@@ -183,7 +177,7 @@ maybe_create_keybox (char *filename, int force, int *r_created)
          sense if this is the case. An empty non-writable directory
          with no keyring is not really useful at all. */
       if (opt.verbose)
-        log_info ("can't allocate lock for `%s'\n", filename );
+        log_info ("can't allocate lock for '%s'\n", filename );
 
       if (!force)
         return gpg_error (GPG_ERR_ENOENT);
@@ -191,10 +185,10 @@ maybe_create_keybox (char *filename, int force, int *r_created)
         return gpg_error (GPG_ERR_GENERAL);
     }
 
-  if ( make_dotlock (lockhd, -1) )
+  if ( dotlock_take (lockhd, -1) )
     {
       /* This is something bad.  Probably a stale lockfile.  */
-      log_info ("can't lock `%s'\n", filename);
+      log_info ("can't lock '%s'\n", filename);
       rc = gpg_error (GPG_ERR_GENERAL);
       goto leave;
     }
@@ -213,14 +207,14 @@ maybe_create_keybox (char *filename, int force, int *r_created)
     {
       rc = gpg_error_from_syserror ();
       umask (oldmask);
-      log_error (_("error creating keybox `%s': %s\n"),
+      log_error (_("error creating keybox '%s': %s\n"),
                  filename, gpg_strerror (rc));
       goto leave;
     }
   umask (oldmask);
 
   if (!opt.quiet)
-    log_info (_("keybox `%s' created\n"), filename);
+    log_info (_("keybox '%s' created\n"), filename);
   if (r_created)
     *r_created = 1;
 
@@ -230,8 +224,8 @@ maybe_create_keybox (char *filename, int force, int *r_created)
  leave:
   if (lockhd)
     {
-      release_dotlock (lockhd);
-      destroy_dotlock (lockhd);
+      dotlock_release (lockhd);
+      dotlock_destroy (lockhd);
     }
   return rc;
 }
@@ -269,7 +263,7 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created)
 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
       else if (strchr (resname, ':'))
         {
-          log_error ("invalid key resource URL `%s'\n", url );
+          log_error ("invalid key resource URL '%s'\n", url );
           rc = gpg_error (GPG_ERR_GENERAL);
           goto leave;
        }
@@ -292,23 +286,24 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created)
   /* see whether we can determine the filetype */
   if (rt == KEYDB_RESOURCE_TYPE_NONE)
     {
-      FILE *fp2 = fopen( filename, "rb" );
+      FILE *fp = fopen( filename, "rb" );
 
-      if (fp2) {
-        u32 magic;
+      if (fp)
+        {
+          u32 magic;
 
-        /* FIXME: check for the keybox magic */
-        if (fread( &magic, 4, 1, fp2) == 1 )
-          {
-            if (magic == 0x13579ace || magic == 0xce9a5713)
-              ; /* GDBM magic - no more support */
-            else
-              rt = KEYDB_RESOURCE_TYPE_KEYBOX;
-          }
-        else /* maybe empty: assume keybox */
-          rt = KEYDB_RESOURCE_TYPE_KEYBOX;
-        fclose (fp2);
-      }
+          /* FIXME: check for the keybox magic */
+          if (fread (&magic, 4, 1, fp) == 1 )
+            {
+              if (magic == 0x13579ace || magic == 0xce9a5713)
+                ; /* GDBM magic - no more support */
+              else
+                rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+            }
+          else /* maybe empty: assume keybox */
+            rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+          fclose (fp);
+        }
       else /* no file yet: create keybox */
         rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     }
@@ -316,7 +311,7 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created)
   switch (rt)
     {
     case KEYDB_RESOURCE_TYPE_NONE:
-      log_error ("unknown type of key resource `%s'\n", url );
+      log_error ("unknown type of key resource '%s'\n", url );
       rc = gpg_error (GPG_ERR_GENERAL);
       goto leave;
 
@@ -339,21 +334,21 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created)
             all_resources[used_resources].secret = secret;
 
             all_resources[used_resources].lockhandle
-              = create_dotlock (filename);
+              = dotlock_create (filename, 0);
             if (!all_resources[used_resources].lockhandle)
-              log_fatal ( _("can't create lock for `%s'\n"), filename);
+              log_fatal ( _("can't create lock for '%s'\n"), filename);
 
             /* Do a compress run if needed and the file is not locked. */
-            if (!make_dotlock (all_resources[used_resources].lockhandle, 0))
+            if (!dotlock_take (all_resources[used_resources].lockhandle, 0))
               {
-                KEYBOX_HANDLE kbxhd = keybox_new (token, secret);
+                KEYBOX_HANDLE kbxhd = keybox_new_x509 (token, secret);
 
                 if (kbxhd)
                   {
                     keybox_compress (kbxhd);
                     keybox_release (kbxhd);
                   }
-                release_dotlock (all_resources[used_resources].lockhandle);
+                dotlock_release (all_resources[used_resources].lockhandle);
               }
 
             used_resources++;
@@ -362,7 +357,7 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created)
       break;
 
     default:
-      log_error ("resource type of `%s' not supported\n", url);
+      log_error ("resource type of '%s' not supported\n", url);
       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
       goto leave;
     }
@@ -371,7 +366,7 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created)
 
  leave:
   if (rc)
-    log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc));
+    log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror(rc));
   else if (secret)
     any_secret = 1;
   else
@@ -405,7 +400,7 @@ keydb_new (int secret)
           hd->active[j].token  = all_resources[i].token;
           hd->active[j].secret = all_resources[i].secret;
           hd->active[j].lockhandle = all_resources[i].lockhandle;
-          hd->active[j].u.kr = keybox_new (all_resources[i].token, secret);
+          hd->active[j].u.kr = keybox_new_x509 (all_resources[i].token, secret);
           if (!hd->active[j].u.kr)
             {
               xfree (hd);
@@ -546,7 +541,7 @@ lock_all (KEYDB_HANDLE hd)
           break;
         case KEYDB_RESOURCE_TYPE_KEYBOX:
           if (hd->active[i].lockhandle)
-            rc = make_dotlock (hd->active[i].lockhandle, -1);
+            rc = dotlock_take (hd->active[i].lockhandle, -1);
           break;
         }
       if (rc)
@@ -564,7 +559,7 @@ lock_all (KEYDB_HANDLE hd)
                 break;
               case KEYDB_RESOURCE_TYPE_KEYBOX:
                 if (hd->active[i].lockhandle)
-                  release_dotlock (hd->active[i].lockhandle);
+                  dotlock_release (hd->active[i].lockhandle);
                 break;
               }
           }
@@ -594,7 +589,7 @@ unlock_all (KEYDB_HANDLE hd)
           break;
         case KEYDB_RESOURCE_TYPE_KEYBOX:
           if (hd->active[i].lockhandle)
-            release_dotlock (hd->active[i].lockhandle);
+            dotlock_release (hd->active[i].lockhandle);
           break;
         }
     }
@@ -654,113 +649,6 @@ keydb_pop_found_state (KEYDB_HANDLE hd)
 
 
 \f
-#if 0
-/*
- * Return the last found keybox.  Caller must free it.
- * The returned keyblock has the kbode flag bit 0 set for the node with
- * the public key used to locate the keyblock or flag bit 1 set for
- * the user ID node.
- */
-int
-keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
-{
-    int rc = 0;
-
-    if (!hd)
-        return G10ERR_INV_ARG;
-
-    if ( hd->found < 0 || hd->found >= hd->used)
-        return -1; /* nothing found */
-
-    switch (hd->active[hd->found].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-        rc = G10ERR_GENERAL; /* oops */
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        rc = keybox_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
-        break;
-    }
-
-    return rc;
-}
-
-/*
- * update the current keyblock with KB
- */
-int
-keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
-{
-    int rc = 0;
-
-    if (!hd)
-        return G10ERR_INV_ARG;
-
-    if ( hd->found < 0 || hd->found >= hd->used)
-        return -1; /* nothing found */
-
-    if( opt.dry_run )
-       return 0;
-
-    if (!hd->locked)
-      return gpg_error (GPG_ERR_NOT_LOCKED);
-
-    switch (hd->active[hd->found].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-        rc = G10ERR_GENERAL; /* oops */
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        rc = keybox_update_keyblock (hd->active[hd->found].u.kr, kb);
-        break;
-    }
-
-    unlock_all (hd);
-    return rc;
-}
-
-
-/*
- * Insert a new KB into one of the resources.
- */
-int
-keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
-{
-    int rc = -1;
-    int idx;
-
-    if (!hd)
-        return G10ERR_INV_ARG;
-
-    if( opt.dry_run )
-       return 0;
-
-    if ( hd->found >= 0 && hd->found < hd->used)
-        idx = hd->found;
-    else if ( hd->current >= 0 && hd->current < hd->used)
-        idx = hd->current;
-    else
-        return G10ERR_GENERAL;
-
-    rc = lock_all (hd);
-    if (rc)
-        return rc;
-
-    switch (hd->active[idx].type) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-        rc = G10ERR_GENERAL; /* oops */
-        break;
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-        rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb);
-        break;
-    }
-
-    unlock_all (hd);
-    return rc;
-}
-
-#endif /*disabled code*/
-
-
-\f
 /*
   Return the last found object.  Caller must free it.  The returned
   keyblock has the kbode flag bit 0 set for the node with the public
@@ -1070,6 +958,7 @@ int
 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
 {
   int rc = -1;
+  unsigned long skipped;
 
   if (!hd)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -1082,7 +971,9 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
           BUG(); /* we should never see it here */
           break;
         case KEYDB_RESOURCE_TYPE_KEYBOX:
-          rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc);
+          rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc,
+                              KEYBOX_BLOBTYPE_X509,
+                              NULL, &skipped);
           break;
         }
       if (rc == -1) /* EOF -> switch to next resource */
@@ -1124,8 +1015,8 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
 
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
-/*    desc.u.kid[0] = kid[0]; */
-/*    desc.u.kid[1] = kid[1]; */
+  desc.u.kid[0] = kid[0];
+  desc.u.kid[1] = kid[1];
   return keydb_search (hd, &desc, 1);
 }
 
@@ -1191,284 +1082,6 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name)
 }
 
 
-static int
-classify_user_id (const char *name,
-                  KEYDB_SEARCH_DESC *desc,
-                  int *force_exact )
-{
-  const char *s;
-  int hexprefix = 0;
-  int hexlength;
-  int mode = 0;
-
-  /* clear the structure so that the mode field is set to zero unless
-   * we set it to the correct value right at the end of this function */
-  memset (desc, 0, sizeof *desc);
-  *force_exact = 0;
-  /* Skip leading spaces.  Fixme: what about trailing white space? */
-  for(s = name; *s && spacep (s); s++ )
-    ;
-
-  switch (*s)
-    {
-    case 0:  /* empty string is an error */
-      return 0;
-
-    case '.': /* an email address, compare from end */
-      mode = KEYDB_SEARCH_MODE_MAILEND;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '<': /* an email address */
-      mode = KEYDB_SEARCH_MODE_MAIL;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '@':  /* part of an email address */
-      mode = KEYDB_SEARCH_MODE_MAILSUB;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '=':  /* exact compare */
-      mode = KEYDB_SEARCH_MODE_EXACT;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '*':  /* case insensitive substring search */
-      mode = KEYDB_SEARCH_MODE_SUBSTR;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '+':  /* compare individual words */
-      mode = KEYDB_SEARCH_MODE_WORDS;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '/': /* subject's DN */
-      s++;
-      if (!*s || spacep (s))
-        return 0; /* no DN or prefixed with a space */
-      desc->u.name = s;
-      mode = KEYDB_SEARCH_MODE_SUBJECT;
-      break;
-
-    case '#':
-      {
-        const char *si;
-
-        s++;
-        if ( *s == '/')
-          { /* "#/" indicates an issuer's DN */
-            s++;
-            if (!*s || spacep (s))
-              return 0; /* no DN or prefixed with a space */
-            desc->u.name = s;
-            mode = KEYDB_SEARCH_MODE_ISSUER;
-          }
-        else
-          { /* serialnumber + optional issuer ID */
-            for (si=s; *si && *si != '/'; si++)
-              {
-                if (!strchr("01234567890abcdefABCDEF", *si))
-                  return 0; /* invalid digit in serial number*/
-              }
-            desc->sn = (const unsigned char*)s;
-            desc->snlen = -1;
-            if (!*si)
-              mode = KEYDB_SEARCH_MODE_SN;
-            else
-              {
-                s = si+1;
-                if (!*s || spacep (s))
-                  return 0; /* no DN or prefixed with a space */
-                desc->u.name = s;
-                mode = KEYDB_SEARCH_MODE_ISSUER_SN;
-              }
-          }
-      }
-      break;
-
-    case ':': /*Unified fingerprint */
-      {
-        const char *se, *si;
-        int i;
-
-        se = strchr (++s,':');
-        if (!se)
-          return 0;
-        for (i=0,si=s; si < se; si++, i++ )
-          {
-            if (!strchr("01234567890abcdefABCDEF", *si))
-              return 0; /* invalid digit */
-          }
-        if (i != 32 && i != 40)
-          return 0; /* invalid length of fpr*/
-        for (i=0,si=s; si < se; i++, si +=2)
-          desc->u.fpr[i] = hextobyte(si);
-        for (; i < 20; i++)
-          desc->u.fpr[i]= 0;
-        s = se + 1;
-        mode = KEYDB_SEARCH_MODE_FPR;
-      }
-      break;
-
-    case '&': /* Keygrip*/
-      {
-        if (hex2bin (s+1, desc->u.grip, 20) < 0)
-          return 0; /* Invalid. */
-        mode = KEYDB_SEARCH_MODE_KEYGRIP;
-      }
-      break;
-
-    default:
-      if (s[0] == '0' && s[1] == 'x')
-        {
-          hexprefix = 1;
-          s += 2;
-        }
-
-      hexlength = strspn(s, "0123456789abcdefABCDEF");
-      if (hexlength >= 8 && s[hexlength] =='!')
-        {
-          *force_exact = 1;
-          hexlength++; /* just for the following check */
-        }
-
-      /* check if a hexadecimal number is terminated by EOS or blank */
-      if (hexlength && s[hexlength] && !spacep (s+hexlength))
-        {
-          if (hexprefix) /* a "0x" prefix without correct */
-            return 0;   /* termination is an error */
-          /* The first chars looked like a hex number, but really is
-             not */
-          hexlength = 0;
-        }
-
-      if (*force_exact)
-        hexlength--; /* remove the bang */
-
-      if (hexlength == 8
-          || (!hexprefix && hexlength == 9 && *s == '0'))
-        { /* short keyid */
-          unsigned long kid;
-          if (hexlength == 9)
-            s++;
-          kid = strtoul( s, NULL, 16 );
-          desc->u.kid[4] = kid >> 24;
-          desc->u.kid[5] = kid >> 16;
-          desc->u.kid[6] = kid >>  8;
-          desc->u.kid[7] = kid;
-          mode = KEYDB_SEARCH_MODE_SHORT_KID;
-        }
-      else if (hexlength == 16
-               || (!hexprefix && hexlength == 17 && *s == '0'))
-        { /* complete keyid */
-          unsigned long kid0, kid1;
-          char buf[9];
-          if (hexlength == 17)
-            s++;
-          mem2str(buf, s, 9 );
-          kid0 = strtoul (buf, NULL, 16);
-          kid1 = strtoul (s+8, NULL, 16);
-          desc->u.kid[0] = kid0 >> 24;
-          desc->u.kid[1] = kid0 >> 16;
-          desc->u.kid[2] = kid0 >>  8;
-          desc->u.kid[3] = kid0;
-          desc->u.kid[4] = kid1 >> 24;
-          desc->u.kid[5] = kid1 >> 16;
-          desc->u.kid[6] = kid1 >>  8;
-          desc->u.kid[7] = kid1;
-          mode = KEYDB_SEARCH_MODE_LONG_KID;
-        }
-      else if (hexlength == 32
-               || (!hexprefix && hexlength == 33 && *s == '0'))
-        { /* md5 fingerprint */
-          int i;
-          if (hexlength == 33)
-            s++;
-          memset(desc->u.fpr+16, 0, 4);
-          for (i=0; i < 16; i++, s+=2)
-            {
-              int c = hextobyte(s);
-              if (c == -1)
-                return 0;
-              desc->u.fpr[i] = c;
-            }
-          mode = KEYDB_SEARCH_MODE_FPR16;
-        }
-      else if (hexlength == 40
-               || (!hexprefix && hexlength == 41 && *s == '0'))
-        { /* sha1/rmd160 fingerprint */
-          int i;
-          if (hexlength == 41)
-            s++;
-          for (i=0; i < 20; i++, s+=2)
-            {
-              int c = hextobyte(s);
-              if (c == -1)
-                return 0;
-              desc->u.fpr[i] = c;
-            }
-          mode = KEYDB_SEARCH_MODE_FPR20;
-        }
-      else if (!hexprefix)
-        {
-          /* The fingerprint in an X.509 listing is often delimited by
-             colons, so we try to single this case out. */
-          mode = 0;
-          hexlength = strspn (s, ":0123456789abcdefABCDEF");
-          if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength)))
-            {
-              int i;
-
-              for (i=0; i < 20; i++, s += 3)
-                {
-                  int c = hextobyte(s);
-                  if (c == -1 || (i < 19 && s[2] != ':'))
-                    break;
-                  desc->u.fpr[i] = c;
-                }
-              if (i == 20)
-                mode = KEYDB_SEARCH_MODE_FPR20;
-            }
-          if (!mode) /* default is substring search */
-            {
-              *force_exact = 0;
-              desc->u.name = s;
-              mode = KEYDB_SEARCH_MODE_SUBSTR;
-            }
-        }
-      else
-       { /* hex number with a prefix but a wrong length */
-          return 0;
-        }
-    }
-
-  desc->mode = mode;
-  return mode;
-}
-
-
-int
-keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
-{
-  int dummy;
-  KEYDB_SEARCH_DESC dummy_desc;
-
-  if (!desc)
-    desc = &dummy_desc;
-
-  if (!classify_user_id (name, desc, &dummy))
-    return gpg_error (GPG_ERR_INV_NAME);
-  return 0;
-}
-
 \f
 /* Store the certificate in the key DB but make sure that it does not
    already exists.  We do this simply by comparing the fingerprint.
@@ -1658,10 +1271,10 @@ keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
     {
       for (ndesc=0, sl=names; sl; sl = sl->next)
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc, 0);
           if (rc)
             {
-              log_error ("key `%s' not found: %s\n",
+              log_error ("key '%s' not found: %s\n",
                          sl->d, gpg_strerror (rc));
               rc = 0;
             }
@@ -1708,5 +1321,3 @@ keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
   xfree (desc);
   keydb_release (hd);
 }
-
-
index f51d79d..aec31c3 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <ksba.h>
 
-#include "../kbx/keybox-search-desc.h"
+#include "../common/userids.h"
 
 typedef struct keydb_handle *KEYDB_HANDLE;
 
@@ -39,12 +39,6 @@ int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes);
 const char *keydb_get_resource_name (KEYDB_HANDLE hd);
 gpg_error_t keydb_lock (KEYDB_HANDLE hd);
 
-#if 0 /* pgp stuff */
-int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
-int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-#endif
-
 gpg_error_t keydb_get_flags (KEYDB_HANDLE hd, int which, int idx,
                              unsigned int *value);
 gpg_error_t keydb_set_flags (KEYDB_HANDLE hd, int which, int idx,
@@ -71,8 +65,6 @@ int keydb_search_issuer_sn (KEYDB_HANDLE hd,
                             const char *issuer, const unsigned char *serial);
 int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer);
 
-int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc);
-
 int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed);
 gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int ephemeral,
                                   int which, int idx,
@@ -82,7 +74,3 @@ void keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names);
 
 
 #endif /*GNUPG_KEYDB_H*/
-
-
-
-
index 9b8538c..dab1295 100644 (file)
@@ -1,6 +1,6 @@
 /* keylist.c - Print certificates in various formats.
- * Copyright (C) 1998, 1999, 2000, 2001, 2003,
- *               2004, 2005, 2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2008, 2009,
+ *               2010, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
@@ -37,7 +37,7 @@
 #include "i18n.h"
 #include "tlv.h"
 
-struct list_external_parm_s 
+struct list_external_parm_s
 {
   ctrl_t ctrl;
   estream_t fp;
@@ -56,18 +56,18 @@ struct
   const char *name;
 } key_purpose_map[] = {
   { "1.3.6.1.5.5.7.3.1",  "serverAuth" },
-  { "1.3.6.1.5.5.7.3.2",  "clientAuth" },          
-  { "1.3.6.1.5.5.7.3.3",  "codeSigning" },      
-  { "1.3.6.1.5.5.7.3.4",  "emailProtection" },     
-  { "1.3.6.1.5.5.7.3.5",  "ipsecEndSystem" }, 
-  { "1.3.6.1.5.5.7.3.6",  "ipsecTunnel" },  
-  { "1.3.6.1.5.5.7.3.7",  "ipsecUser" },     
-  { "1.3.6.1.5.5.7.3.8",  "timeStamping" },       
-  { "1.3.6.1.5.5.7.3.9",  "ocspSigning" },    
-  { "1.3.6.1.5.5.7.3.10", "dvcs" },      
+  { "1.3.6.1.5.5.7.3.2",  "clientAuth" },
+  { "1.3.6.1.5.5.7.3.3",  "codeSigning" },
+  { "1.3.6.1.5.5.7.3.4",  "emailProtection" },
+  { "1.3.6.1.5.5.7.3.5",  "ipsecEndSystem" },
+  { "1.3.6.1.5.5.7.3.6",  "ipsecTunnel" },
+  { "1.3.6.1.5.5.7.3.7",  "ipsecUser" },
+  { "1.3.6.1.5.5.7.3.8",  "timeStamping" },
+  { "1.3.6.1.5.5.7.3.9",  "ocspSigning" },
+  { "1.3.6.1.5.5.7.3.10", "dvcs" },
   { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
   { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
-  { "1.3.6.1.5.5.7.3.14", "wlanSSID" },       
+  { "1.3.6.1.5.5.7.3.14", "wlanSSID" },
 
   { "2.16.840.1.113730.4.1", "serverGatedCrypto.ns" }, /* Netscape. */
   { "1.3.6.1.4.1.311.10.3.3", "serverGatedCrypto.ms"}, /* Microsoft. */
@@ -82,10 +82,10 @@ struct
    for oids which are already available via ksba fucntions. */
 #define OID_FLAG_SKIP 1
 /* The extension is a simple UTF8String and should be printed.  */
-#define OID_FLAG_UTF8 2 
+#define OID_FLAG_UTF8 2
 
 /* A table mapping OIDs to a descriptive string. */
-static struct 
+static struct
 {
   char *oid;
   char *name;
@@ -155,7 +155,7 @@ static struct
   { "2.5.29.20", "cRLNumber" },
   { "2.5.29.21", "cRLReason" },
   { "2.5.29.22", "expirationDate" },
-  { "2.5.29.23", "instructionCode" }, 
+  { "2.5.29.23", "instructionCode" },
   { "2.5.29.24", "invalidityDate" },
   { "2.5.29.27", "deltaCRLIndicator" },
   { "2.5.29.28", "issuingDistributionPoint" },
@@ -186,6 +186,8 @@ static struct
 
   /* GnuPG extensions */
   { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
+  { "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" },
+  { "1.3.6.1.4.1.11591.2.2.2", "wellKnownPrivateKey" },
 
   /* Extensions used by the Bundesnetzagentur.  */
   { "1.3.6.1.4.1.8301.3.5", "validityModel" },
@@ -194,7 +196,7 @@ static struct
 };
 
 
-/* Return the description for OID; if no description is available 
+/* Return the description for OID; if no description is available
    NULL is returned. */
 static const char *
 get_oid_desc (const char *oid, unsigned int *flag)
@@ -218,11 +220,11 @@ get_oid_desc (const char *oid, unsigned int *flag)
 static void
 print_key_data (ksba_cert_t cert, estream_t fp)
 {
-#if 0  
+#if 0
   int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
   int i;
 
-  for(i=0; i < n; i++ ) 
+  for(i=0; i < n; i++ )
     {
       es_fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
       mpi_print(stdout, pk->pkey[i], 1 );
@@ -243,18 +245,18 @@ print_capabilities (ksba_cert_t cert, estream_t fp)
   size_t buflen;
   char buffer[1];
 
-  err = ksba_cert_get_user_data (cert, "is_qualified", 
+  err = ksba_cert_get_user_data (cert, "is_qualified",
                                  &buffer, sizeof (buffer), &buflen);
   if (!err && buflen)
     {
       if (*buffer)
         es_putc ('q', fp);
-    }    
+    }
   else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
     ; /* Don't know - will not get marked as 'q' */
   else
     log_debug ("get_user_data(is_qualified) failed: %s\n",
-               gpg_strerror (err)); 
+               gpg_strerror (err));
 
   err = ksba_cert_get_key_usage (cert, &use);
   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
@@ -268,11 +270,11 @@ print_capabilities (ksba_cert_t cert, estream_t fp)
       return;
     }
   if (err)
-    { 
+    {
       log_error (_("error getting key usage information: %s\n"),
                  gpg_strerror (err));
       return;
-    } 
+    }
 
   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
     es_putc ('e', fp);
@@ -296,7 +298,7 @@ print_time (gnupg_isotime_t t, estream_t fp)
 {
   if (!t || !*t)
     ;
-  else 
+  else
     es_fputs (t, fp);
 }
 
@@ -406,20 +408,25 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
     *truststring = 'r';
   else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
     *truststring = 'e';
-  else 
+  else
     {
       /* Lets also check whether the certificate under question
          expired.  This is merely a hack until we found a proper way
          to store the expiration flag in the keybox. */
       ksba_isotime_t current_time, not_after;
-  
+
       gnupg_get_isotime (current_time);
       if (!opt.ignore_expiration
           && !ksba_cert_get_validity (cert, 1, not_after)
           && *not_after && strcmp (current_time, not_after) > 0 )
         *truststring = 'e';
       else if (valerr)
-        *truststring = 'i';
+        {
+          if (gpgsm_cert_has_well_known_private_key (cert))
+            *truststring = 'w';  /* Well, this is dummy CA.  */
+          else
+            *truststring = 'i';
+        }
       else if (ctrl->with_validation && !is_root)
         *truststring = 'f';
     }
@@ -431,21 +438,25 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
     {
       struct rootca_flags_s dummy_flags;
 
-      rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
-      if (!rc)
-        *truststring = 'u';  /* Yes, we trust this one (ultimately). */
-      else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
-        *truststring = 'n';  /* No, we do not trust this one. */
-      /* (in case of an error we can't tell anything.) */
+      if (gpgsm_cert_has_well_known_private_key (cert))
+        *truststring = 'w';  /* Well, this is dummy CA.  */
+      else
+        {
+          rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
+          if (!rc)
+            *truststring = 'u';  /* Yes, we trust this one (ultimately). */
+          else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
+            *truststring = 'n';  /* No, we do not trust this one. */
+          /* (in case of an error we can't tell anything.) */
+        }
     }
-  
+
   if (*truststring)
     es_fputs (truststring, fp);
 
   algo = gpgsm_get_key_algo_info (cert, &nbits);
   es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
 
-  /* We assume --fixed-list-mode for gpgsm */
   ksba_cert_get_validity (cert, 0, t);
   print_time (t, fp);
   es_putc (':', fp);
@@ -457,7 +468,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
     {
       int len;
       const unsigned char *s = sexp;
-      
+
       if (*s == '(')
         {
           s++;
@@ -479,23 +490,28 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
       xfree (p);
     }
   es_putc (':', fp);
-  /* Field 11, signature class - not used */ 
+  /* Field 11, signature class - not used */
   es_putc (':', fp);
-  /* Field 12, capabilities: */ 
+  /* Field 12, capabilities: */
   print_capabilities (cert, fp);
+  es_putc (':', fp);
   /* Field 13, not used: */
   es_putc (':', fp);
-  if (have_secret)
+  if (have_secret || ctrl->with_secret)
     {
       char *cardsn;
 
       p = gpgsm_get_keygrip_hexstring (cert);
-      if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
+      if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn)
+          && (cardsn || ctrl->with_secret))
         {
           /* Field 14, not used: */
           es_putc (':', fp);
-          /* Field 15:  Token serial number.  */
-          es_fputs (cardsn, fp);
+          /* Field 15:  Token serial number or secret key indicator.  */
+          if (cardsn)
+            es_fputs (cardsn, fp);
+          else if (ctrl->with_secret)
+            es_putc ('+', fp);
           es_putc (':', fp);
         }
       xfree (cardsn);
@@ -584,7 +600,7 @@ print_names_raw (estream_t fp, int indent, ksba_name_t name)
       es_fputs ("none\n", fp);
       return;
     }
-  
+
   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
     {
       char *p = ksba_name_get_uri (name, idx);
@@ -597,7 +613,7 @@ print_names_raw (estream_t fp, int indent, ksba_name_t name)
 
 
 static void
-print_utf8_extn_raw (estream_t fp, int indent, 
+print_utf8_extn_raw (estream_t fp, int indent,
                      const unsigned char *der, size_t derlen)
 {
   gpg_error_t err;
@@ -621,7 +637,7 @@ print_utf8_extn_raw (estream_t fp, int indent,
 
 
 static void
-print_utf8_extn (estream_t fp, int indent, 
+print_utf8_extn (estream_t fp, int indent,
                  const unsigned char *der, size_t derlen)
 {
   gpg_error_t err;
@@ -800,21 +816,21 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
         {
           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
             es_fputs (" digitalSignature", fp);
-          if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
+          if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
             es_fputs (" nonRepudiation", fp);
-          if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
+          if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
             es_fputs (" keyEncipherment", fp);
           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
             es_fputs (" dataEncipherment", fp);
-          if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
+          if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
             es_fputs (" keyAgreement", fp);
           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
             es_fputs (" certSign", fp);
-          if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
+          if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
             es_fputs (" crlSign", fp);
           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
             es_fputs (" encipherOnly", fp);
-          if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
+          if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
             es_fputs (" decipherOnly", fp);
         }
       es_putc ('\n', fp);
@@ -825,7 +841,7 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
   es_fputs ("  extKeyUsage: ", fp);
   err = ksba_cert_get_ext_key_usages (cert, &string);
   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
-    { 
+    {
       if (err)
         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
       else
@@ -1106,21 +1122,21 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
         {
           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
             es_fputs (" digitalSignature", fp);
-          if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
+          if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
             es_fputs (" nonRepudiation", fp);
-          if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
+          if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
             es_fputs (" keyEncipherment", fp);
           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
             es_fputs (" dataEncipherment", fp);
-          if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
+          if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
             es_fputs (" keyAgreement", fp);
           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
             es_fputs (" certSign", fp);
-          if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
+          if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
             es_fputs (" crlSign", fp);
           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
             es_fputs (" encipherOnly", fp);
-          if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
+          if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
             es_fputs (" decipherOnly", fp);
         }
       es_putc ('\n', fp);
@@ -1128,7 +1144,7 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
 
   err = ksba_cert_get_ext_key_usages (cert, &string);
   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
-    { 
+    {
       es_fputs ("ext key usage: ", fp);
       if (err)
         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
@@ -1216,6 +1232,16 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
   es_fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
   xfree (dn);
 
+  if (opt.with_keygrip)
+    {
+      dn = gpgsm_get_keygrip_hexstring (cert);
+      if (dn)
+        {
+          es_fprintf (fp, "      keygrip: %s\n", dn);
+          xfree (dn);
+        }
+    }
+
   if (have_secret)
     {
       char *cardsn;
@@ -1232,20 +1258,20 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
       gpg_error_t tmperr;
       size_t buflen;
       char buffer[1];
-      
+
       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
-      tmperr = ksba_cert_get_user_data (cert, "is_qualified", 
+      tmperr = ksba_cert_get_user_data (cert, "is_qualified",
                                         &buffer, sizeof (buffer), &buflen);
       if (!tmperr && buflen)
         {
           if (*buffer)
             es_fputs ("  [qualified]\n", fp);
-        }    
+        }
       else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
         ; /* Don't know - will not get marked as 'q' */
       else
         log_debug ("get_user_data(is_qualified) failed: %s\n",
-                   gpg_strerror (tmperr)); 
+                   gpg_strerror (tmperr));
 
       if (!err)
         es_fprintf (fp, "  [certificate is good]\n");
@@ -1316,7 +1342,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
     ndesc = 1;
   else
     {
-      for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
+      for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
         ;
     }
 
@@ -1330,21 +1356,21 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
 
   if (!names)
     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
-  else 
+  else
     {
-      for (ndesc=0, sl=names; sl; sl = sl->next) 
+      for (ndesc=0, sl=names; sl; sl = sl->next)
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc, 0);
           if (rc)
             {
-              log_error ("key `%s' not found: %s\n",
+              log_error ("key '%s' not found: %s\n",
                          sl->d, gpg_strerror (rc));
               rc = 0;
             }
           else
             ndesc++;
         }
-      
+
     }
 
   /* If all specifications are done by fingerprint or keygrip, we
@@ -1380,7 +1406,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
     {
       unsigned int validity;
 
-      if (!names) 
+      if (!names)
         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
 
       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
@@ -1390,7 +1416,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
           goto leave;
         }
       rc = keydb_get_cert (hd, &cert);
-      if (rc) 
+      if (rc)
         {
           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
           goto leave;
@@ -1406,11 +1432,11 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
        }
 
       resname = keydb_get_resource_name (hd);
-      
-      if (lastresname != resname ) 
+
+      if (lastresname != resname )
         {
           int i;
-          
+
           if (ctrl->no_server)
             {
               es_fprintf (fp, "%s\n", resname );
@@ -1427,8 +1453,8 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
           char *p = gpgsm_get_keygrip_hexstring (cert);
           if (p)
             {
-              rc = gpgsm_agent_havekey (ctrl, p); 
-             if (!rc)
+              rc = gpgsm_agent_havekey (ctrl, p);
+              if (!rc)
                 have_secret = 1;
               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
                 goto leave;
@@ -1458,7 +1484,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
             }
         }
 
-      ksba_cert_release (lastcert); 
+      ksba_cert_release (lastcert);
       lastcert = cert;
       cert = NULL;
     }
@@ -1466,10 +1492,10 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
     rc = 0;
   if (rc)
     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
-  
+
  leave:
   ksba_cert_release (cert);
-  ksba_cert_release (lastcert); 
+  ksba_cert_release (lastcert);
   xfree (desc);
   keydb_release (hd);
   return rc;
@@ -1529,7 +1555,7 @@ list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
   parm.raw_mode  = raw_mode;
 
   rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
-  if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 
+  if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1
       || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
     rc = 0; /* "Not found" is not an error here. */
   if (rc)
@@ -1538,7 +1564,7 @@ list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
 }
 
 /* List all keys or just the key given as NAMES.
-   MODE controls the operation mode: 
+   MODE controls the operation mode:
     Bit 0-2:
       0 = list all public keys but don't flag secret ones
       1 = list only public keys
@@ -1557,6 +1583,6 @@ gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
   if ((mode & (1<<6)))
     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
   if (!err && (mode & (1<<7)))
-    err = list_external_keys (ctrl, names, fp, (mode&256)); 
+    err = list_external_keys (ctrl, names, fp, (mode&256));
   return err;
 }
similarity index 80%
rename from agent/minip12.c
rename to sm/minip12.c
index 0bcab5f..01b91b7 100644 (file)
@@ -1,5 +1,6 @@
 /* minip12.c - A minimal pkcs-12 implementation.
- * Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2006, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -32,8 +33,8 @@
 #include <unistd.h>
 #endif
 
-#include "../jnlib/logging.h"
-#include "../jnlib/utf8conv.h"
+#include "../common/logging.h"
+#include "../common/utf8conv.h"
 #include "minip12.h"
 
 #ifndef DIM
@@ -104,6 +105,12 @@ static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
 static unsigned char const oid_x509Certificate_for_pkcs_12[10] = {
   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
 
+static unsigned char const oid_pkcs5PBKDF2[9] = {
+  0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C };
+static unsigned char const oid_pkcs5PBES2[9] = {
+  0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D };
+static unsigned char const oid_aes128_CBC[9] = {
+  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02 };
 
 static unsigned char const oid_rsaEncryption[9] = {
   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
@@ -111,14 +118,14 @@ static unsigned char const oid_rsaEncryption[9] = {
 
 static unsigned char const data_3desiter2048[30] = {
   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
-  0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E, 
+  0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E,
   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
 #define DATA_3DESITER2048_SALT_OFF  18
 
 static unsigned char const data_rc2iter2048[30] = {
   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
-  0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E, 
+  0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E,
   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
 #define DATA_RC2ITER2048_SALT_OFF  18
@@ -130,7 +137,7 @@ static unsigned char const data_mactemplate[51] = {
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x08, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
-  0x02, 0x08, 0x00 }; 
+  0x02, 0x08, 0x00 };
 #define DATA_MACTEMPLATE_MAC_OFF 17
 #define DATA_MACTEMPLATE_SALT_OFF 39
 
@@ -151,14 +158,14 @@ static unsigned char const data_attrtemplate[106] = {
   0x04, 0x14 }; /* Need to append SHA-1 digest. */
 #define DATA_ATTRTEMPLATE_KEYID_OFF 73
 
-struct buffer_s 
+struct buffer_s
 {
   unsigned char *buffer;
   size_t length;
-};  
+};
 
 
-struct tag_info 
+struct tag_info
 {
   int class;
   int is_constructed;
@@ -173,7 +180,7 @@ struct tag_info
    the tag and the length part from the TLV triplet.  Update BUFFER
    and SIZE on success.  Checks that the encoded length does not
    exhaust the length of the provided buffer. */
-static int 
+static int
 parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
 {
   int c;
@@ -239,13 +246,13 @@ parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
         }
       ti->length = len;
     }
-  
+
   if (ti->class == UNIVERSAL && !ti->tag)
     ti->length = 0;
 
   if (ti->length > length)
     return -1; /* data larger than buffer. */
-  
+
   *buffer = buf;
   *size = length;
   return 0;
@@ -262,9 +269,9 @@ parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
           [...]
      04    2:         OCTET STRING
             :           00 00
-            :         } -- This denotes a Null tag and are the last 
+            :         } -- This denotes a Null tag and are the last
                         -- two bytes in INPUT.
-   
+
    Create a new buffer with the content of that octet string.  INPUT
    is the orginal buffer with a length as stored at LENGTH.  Returns
    NULL on error or a new malloced buffer with the length of this new
@@ -291,7 +298,7 @@ cram_octet_string (const unsigned char *input, size_t *length,
     {
       if (parse_tag (&s, &n, &ti))
         goto bailout;
-      if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING 
+      if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING
           && !ti.ndef && !ti.is_constructed)
         {
           memcpy (d, s, ti.length);
@@ -300,7 +307,7 @@ cram_octet_string (const unsigned char *input, size_t *length,
           n -= ti.length;
         }
       else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
-        break; /* Ready */ 
+        break; /* Ready */
       else
         goto bailout;
     }
@@ -320,7 +327,7 @@ cram_octet_string (const unsigned char *input, size_t *length,
 
 
 
-static int 
+static int
 string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
                int req_keylen, unsigned char *keybuf)
 {
@@ -345,7 +352,7 @@ string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
       log_error ("salt too short\n");
       return -1;
     }
-  
+
   /* Store salt and password in BUF_I */
   p = buf_i;
   for(i=0; i < 64; i++)
@@ -381,7 +388,7 @@ string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
           gcry_mpi_release (num_b1);
           return 0; /* ready */
         }
-      
+
       /* need more bytes. */
       for(i=0; i < 64; i++)
         buf_b[i] = hash[i % 20];
@@ -418,7 +425,7 @@ string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
 }
 
 
-static int 
+static int
 set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
             const char *pw, int keybytes)
 {
@@ -447,22 +454,70 @@ set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
 }
 
 
+static int
+set_key_iv_pbes2 (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
+                  const void *iv, size_t ivlen, const char *pw, int algo)
+{
+  unsigned char *keybuf;
+  size_t keylen;
+  int rc;
+
+  keylen = gcry_cipher_get_algo_keylen (algo);
+  if (!keylen)
+    return -1;
+  keybuf = gcry_malloc_secure (keylen);
+  if (!keybuf)
+    return -1;
+
+  rc = gcry_kdf_derive (pw, strlen (pw),
+                        GCRY_KDF_PBKDF2, GCRY_MD_SHA1,
+                        salt, saltlen, iter, keylen, keybuf);
+  if (rc)
+    {
+      log_error ("gcry_kdf_derive failed: %s\n", gpg_strerror (rc));
+      gcry_free (keybuf);
+      return -1;
+    }
+
+  rc = gcry_cipher_setkey (chd, keybuf, keylen);
+  gcry_free (keybuf);
+  if (rc)
+    {
+      log_error ("gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
+      return -1;
+    }
+
+
+  rc = gcry_cipher_setiv (chd, iv, ivlen);
+  if (rc)
+    {
+      log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
+      return -1;
+    }
+  return 0;
+}
+
+
 static void
 crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
-             int iter, const char *pw, int cipher_algo, int encrypt)
+             int iter, const void *iv, size_t ivlen,
+             const char *pw, int cipher_algo, int encrypt)
 {
   gcry_cipher_hd_t chd;
   int rc;
 
-  rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0); 
+  rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0);
   if (rc)
     {
       log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc));
       wipememory (buffer, length);
       return;
     }
-  if (set_key_iv (chd, salt, saltlen, iter, pw,
-                  cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
+
+  if (cipher_algo == GCRY_CIPHER_AES128
+      ? set_key_iv_pbes2 (chd, salt, saltlen, iter, iv, ivlen, pw, cipher_algo)
+      : set_key_iv (chd, salt, saltlen, iter, pw,
+                    cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
     {
       wipememory (buffer, length);
       goto leave;
@@ -481,7 +536,7 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
  leave:
   gcry_cipher_close (chd);
 }
-  
+
 
 /* Decrypt a block of data and try several encodings of the key.
    CIPHERTEXT is the encrypted data of size LENGTH bytes; PLAINTEXT is
@@ -495,7 +550,8 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
 static void
 decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
                char *salt, size_t saltlen,
-               int iter, const char *pw, int cipher_algo,
+               int iter, const void *iv, size_t ivlen,
+               const char *pw, int cipher_algo,
                int (*check_fnc) (const void *, size_t))
 {
   static const char * const charsets[] = {
@@ -555,18 +611,18 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
           outptr = convertedpw;
           outbytes = convertedpwsize - 1;
           if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
-                      &outptr, &outbytes) == (size_t)-1) 
+                      &outptr, &outbytes) == (size_t)-1)
             {
               jnlib_iconv_close (cd);
               continue;
             }
           *outptr = 0;
           jnlib_iconv_close (cd);
-          log_info ("decryption failed; trying charset `%s'\n",
+          log_info ("decryption failed; trying charset '%s'\n",
                     charsets[charsetidx]);
         }
       memcpy (plaintext, ciphertext, length);
-      crypt_block (plaintext, length, salt, saltlen, iter,
+      crypt_block (plaintext, length, salt, saltlen, iter, iv, ivlen,
                    convertedpw? convertedpw:pw, cipher_algo, 0);
       if (check_fnc (plaintext, length))
         break; /* Decryption succeeded. */
@@ -591,7 +647,7 @@ bag_decrypted_data_p (const void *plaintext, size_t length)
   /*       exit (2); */
   /*     fclose (fp); */
   /*   } */
-  
+
   if (parse_tag (&p, &n, &ti))
     return 0;
   if (ti.class || ti.tag != TAG_SEQUENCE)
@@ -599,7 +655,7 @@ bag_decrypted_data_p (const void *plaintext, size_t length)
   if (parse_tag (&p, &n, &ti))
     return 0;
 
-  return 1; 
+  return 1;
 }
 
 /* Note: If R_RESULT is passed as NULL, a key object as already be
@@ -608,7 +664,8 @@ static int
 parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
                           int startoffset, size_t *r_consumed, const char *pw,
                           void (*certcb)(void*, const unsigned char*, size_t),
-                          void *certcbarg, gcry_mpi_t **r_result)
+                          void *certcbarg, gcry_mpi_t **r_result,
+                          int *r_badpass)
 {
   struct tag_info ti;
   const unsigned char *p = buffer;
@@ -617,12 +674,14 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
   const char *where;
   char salt[20];
   size_t saltlen;
+  char iv[16];
   unsigned int iter;
   unsigned char *plain = NULL;
   int bad_pass = 0;
   unsigned char *cram_buffer = NULL;
   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
   int is_3des = 0;
+  int is_pbes2 = 0;
   gcry_mpi_t *result = NULL;
   int result_count;
 
@@ -665,7 +724,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
     goto bailout;
   if (parse_tag (&p, &n, &ti))
     goto bailout;
-  if (!ti.class && ti.tag == TAG_OBJECT_ID 
+  if (!ti.class && ti.tag == TAG_OBJECT_ID
       && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
       && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
                   DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
@@ -673,7 +732,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
       p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
       n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
     }
-  else if (!ti.class && ti.tag == TAG_OBJECT_ID 
+  else if (!ti.class && ti.tag == TAG_OBJECT_ID
       && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
       && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
                   DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
@@ -682,35 +741,111 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
       n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
       is_3des = 1;
     }
+  else if (!ti.class && ti.tag == TAG_OBJECT_ID
+           && ti.length == DIM(oid_pkcs5PBES2)
+           && !memcmp (p, oid_pkcs5PBES2, ti.length))
+    {
+      p += ti.length;
+      n -= ti.length;
+      is_pbes2 = 1;
+    }
   else
     goto bailout;
 
-  where = "rc2or3des-params";
-  if (parse_tag (&p, &n, &ti))
-    goto bailout;
-  if (ti.class || ti.tag != TAG_SEQUENCE)
-    goto bailout;
-  if (parse_tag (&p, &n, &ti))
-    goto bailout;
-  if (ti.class || ti.tag != TAG_OCTET_STRING
-      || ti.length < 8 || ti.length > 20 )
-    goto bailout;
-  saltlen = ti.length;
-  memcpy (salt, p, saltlen);
-  p += saltlen;
-  n -= saltlen;
-  if (parse_tag (&p, &n, &ti))
-    goto bailout;
-  if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
-    goto bailout;
-  for (iter=0; ti.length; ti.length--)
+  if (is_pbes2)
     {
-      iter <<= 8;
-      iter |= (*p++) & 0xff; 
-      n--;
+      where = "pkcs5PBES2-params";
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OBJECT_ID
+            && ti.length == DIM(oid_pkcs5PBKDF2)
+            && !memcmp (p, oid_pkcs5PBKDF2, ti.length)))
+        goto bailout; /* Not PBKDF2.  */
+      p += ti.length;
+      n -= ti.length;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OCTET_STRING
+            && ti.length >= 8 && ti.length < sizeof salt))
+        goto bailout;  /* No salt or unsupported length.  */
+      saltlen = ti.length;
+      memcpy (salt, p, saltlen);
+      p += saltlen;
+      n -= saltlen;
+
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length))
+        goto bailout;  /* No valid iteration count.  */
+      for (iter=0; ti.length; ti.length--)
+        {
+          iter <<= 8;
+          iter |= (*p++) & 0xff;
+          n--;
+        }
+      /* Note: We don't support the optional parameters but assume
+         that the algorithmIdentifier follows. */
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OBJECT_ID
+            && ti.length == DIM(oid_aes128_CBC)
+            && !memcmp (p, oid_aes128_CBC, ti.length)))
+        goto bailout; /* Not AES-128.  */
+      p += ti.length;
+      n -= ti.length;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv))
+        goto bailout; /* Bad IV.  */
+      memcpy (iv, p, sizeof iv);
+      p += sizeof iv;
+      n -= sizeof iv;
     }
-  
-  where = "rc2or3des-ciphertext";
+  else
+    {
+      where = "rc2or3des-params";
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_OCTET_STRING
+          || ti.length < 8 || ti.length > 20 )
+        goto bailout;
+      saltlen = ti.length;
+      memcpy (salt, p, saltlen);
+      p += saltlen;
+      n -= saltlen;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
+        goto bailout;
+      for (iter=0; ti.length; ti.length--)
+        {
+          iter <<= 8;
+          iter |= (*p++) & 0xff;
+          n--;
+        }
+    }
+
+  where = "rc2or3desoraes-ciphertext";
   if (parse_tag (&p, &n, &ti))
     goto bailout;
 
@@ -733,8 +868,9 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
     ;
   else
     goto bailout;
-  
-  log_info ("%lu bytes of %s encrypted text\n",ti.length,is_3des?"3DES":"RC2");
+
+  log_info ("%lu bytes of %s encrypted text\n",ti.length,
+            is_pbes2?"AES128":is_3des?"3DES":"RC2");
 
   plain = gcry_malloc_secure (ti.length);
   if (!plain)
@@ -742,8 +878,10 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
       log_error ("error allocating decryption buffer\n");
       goto bailout;
     }
-  decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, 
-                 is_3des? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, 
+  decrypt_block (p, plain, ti.length, salt, saltlen, iter,
+                 iv, is_pbes2?16:0, pw,
+                 is_pbes2 ? GCRY_CIPHER_AES128 :
+                 is_3des  ? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40,
                  bag_decrypted_data_p);
   n = ti.length;
   startoffset = 0;
@@ -890,7 +1028,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
               len -= ti.length;
               if (!result_count && ti.length == 1 && !*p)
                 ; /* ignore the very first one if it is a 0 */
-              else 
+              else
                 {
                   int rc;
 
@@ -926,7 +1064,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
             goto bailout;
           p += DIM(oid_x509Certificate_for_pkcs_12);
           n -= DIM(oid_x509Certificate_for_pkcs_12);
-          
+
           where = "certbag.before.octetstring";
           if (parse_tag (&p, &n, &ti))
             goto bailout;
@@ -936,11 +1074,11 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
             goto bailout;
           if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef)
             goto bailout;
-          
+
           /* Return the certificate. */
           if (certcb)
             certcb (certcbarg, p, ti.length);
-   
+
           p += ti.length;
           n -= ti.length;
         }
@@ -949,8 +1087,8 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
          that is less or equal to the cipher's block length.  We can
          reasonable assume that all valid data will be longer than
          just one block. */
-      if (n <= 8)
-        n = 0;  
+      if (n <= (is_pbes2? 16:8))
+        n = 0;
 
       /* Skip the optional SET with the pkcs12 cert attributes. */
       if (n)
@@ -964,7 +1102,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
             { /* The optional SET. */
               p += ti.length;
               n -= ti.length;
-              if (n <= 8)
+              if (n <= (is_pbes2?16:8))
                 n = 0;
               if (n && parse_tag (&p, &n, &ti))
                 goto bailout;
@@ -973,7 +1111,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
             goto bailout;
         }
     }
-  
+
   if (r_consumed)
     *r_consumed = consumed;
   gcry_free (plain);
@@ -1003,6 +1141,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
          to check for a bad passphrase; it should therefore not be
          translated or changed. */
       log_error ("possibly bad passphrase given\n");
+      *r_badpass = 1;
     }
   return -1;
 }
@@ -1031,7 +1170,7 @@ bag_data_p (const void *plaintext, size_t length)
       || ti.length != 1 || *p)
     return 0;
 
-  return 1; 
+  return 1;
 }
 
 
@@ -1047,6 +1186,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
   const char *where;
   char salt[20];
   size_t saltlen;
+  char iv[16];
   unsigned int iter;
   int len;
   unsigned char *plain = NULL;
@@ -1054,6 +1194,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
   int result_count, i;
   unsigned char *cram_buffer = NULL;
   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
+  int is_pbes2 = 0;
 
   where = "start";
   if (parse_tag (&p, &n, &ti))
@@ -1079,7 +1220,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
         *r_consumed = consumed;
       r_consumed = NULL; /* Ugly hack to not update that value any further. */
     }
-  
+
 
   where = "data.outerseqs";
   if (parse_tag (&p, &n, &ti))
@@ -1117,47 +1258,127 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
     goto bailout;
   if (parse_tag (&p, &n, &ti))
     goto bailout;
-  if (ti.class || ti.tag != TAG_OBJECT_ID
-      || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
-      || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
-                 DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
+  if (ti.class == 0 && ti.tag == TAG_OBJECT_ID
+      && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
+      && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
+                  DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
+    {
+      p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
+      n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
+    }
+  else if (ti.class == 0 && ti.tag == TAG_OBJECT_ID
+           && ti.length == DIM(oid_pkcs5PBES2)
+           && !memcmp (p, oid_pkcs5PBES2, DIM(oid_pkcs5PBES2)))
+    {
+      p += DIM(oid_pkcs5PBES2);
+      n -= DIM(oid_pkcs5PBES2);
+      is_pbes2 = 1;
+    }
+  else
     goto bailout;
-  p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
-  n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
 
-  where = "3des-params";
-  if (parse_tag (&p, &n, &ti))
-    goto bailout;
-  if (ti.class || ti.tag != TAG_SEQUENCE)
-    goto bailout;
-  if (parse_tag (&p, &n, &ti))
-    goto bailout;
-  if (ti.class || ti.tag != TAG_OCTET_STRING
-      || ti.length < 8 || ti.length > 20)
-    goto bailout;
-  saltlen = ti.length;
-  memcpy (salt, p, saltlen);
-  p += saltlen;
-  n -= saltlen;
-  if (parse_tag (&p, &n, &ti))
-    goto bailout;
-  if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
-    goto bailout;
-  for (iter=0; ti.length; ti.length--)
+  if (is_pbes2)
+    {
+      where = "pkcs5PBES2-params";
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OBJECT_ID
+            && ti.length == DIM(oid_pkcs5PBKDF2)
+            && !memcmp (p, oid_pkcs5PBKDF2, ti.length)))
+        goto bailout; /* Not PBKDF2.  */
+      p += ti.length;
+      n -= ti.length;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OCTET_STRING
+            && ti.length >= 8 && ti.length < sizeof salt))
+        goto bailout;  /* No salt or unsupported length.  */
+      saltlen = ti.length;
+      memcpy (salt, p, saltlen);
+      p += saltlen;
+      n -= saltlen;
+
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length))
+        goto bailout;  /* No valid iteration count.  */
+      for (iter=0; ti.length; ti.length--)
+        {
+          iter <<= 8;
+          iter |= (*p++) & 0xff;
+          n--;
+        }
+      /* Note: We don't support the optional parameters but assume
+         that the algorithmIdentifier follows. */
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OBJECT_ID
+            && ti.length == DIM(oid_aes128_CBC)
+            && !memcmp (p, oid_aes128_CBC, ti.length)))
+        goto bailout; /* Not AES-128.  */
+      p += ti.length;
+      n -= ti.length;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv))
+        goto bailout; /* Bad IV.  */
+      memcpy (iv, p, sizeof iv);
+      p += sizeof iv;
+      n -= sizeof iv;
+    }
+  else
     {
-      iter <<= 8;
-      iter |= (*p++) & 0xff; 
-      n--;
+      where = "3des-params";
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_SEQUENCE)
+        goto bailout;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_OCTET_STRING
+          || ti.length < 8 || ti.length > 20)
+        goto bailout;
+      saltlen = ti.length;
+      memcpy (salt, p, saltlen);
+      p += saltlen;
+      n -= saltlen;
+      if (parse_tag (&p, &n, &ti))
+        goto bailout;
+      if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
+        goto bailout;
+      for (iter=0; ti.length; ti.length--)
+        {
+          iter <<= 8;
+          iter |= (*p++) & 0xff;
+          n--;
+        }
     }
-  
-  where = "3des-ciphertext";
+
+  where = "3desoraes-ciphertext";
   if (parse_tag (&p, &n, &ti))
     goto bailout;
   if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
     goto bailout;
-  
-  log_info ("%lu bytes of 3DES encrypted text\n", ti.length);
-  
+
+  log_info ("%lu bytes of %s encrypted text\n",
+            ti.length, is_pbes2? "AES128":"3DES");
+
   plain = gcry_malloc_secure (ti.length);
   if (!plain)
     {
@@ -1165,8 +1386,9 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
       goto bailout;
     }
   consumed += p - p_start + ti.length;
-  decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, 
-                 GCRY_CIPHER_3DES, 
+  decrypt_block (p, plain, ti.length, salt, saltlen, iter,
+                 iv, is_pbes2? 16:0, pw,
+                 is_pbes2? GCRY_CIPHER_AES128 : GCRY_CIPHER_3DES,
                  bag_data_p);
   n = ti.length;
   startoffset = 0;
@@ -1228,7 +1450,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
       len -= ti.length;
       if (!result_count && ti.length == 1 && !*p)
         ; /* ignore the very first one if it is a 0 */
-      else 
+      else
         {
           rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
                               ti.length, NULL);
@@ -1277,7 +1499,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
 gcry_mpi_t *
 p12_parse (const unsigned char *buffer, size_t length, const char *pw,
            void (*certcb)(void*, const unsigned char*, size_t),
-           void *certcbarg)
+           void *certcbarg, int *r_badpass)
 {
   struct tag_info ti;
   const unsigned char *p = buffer;
@@ -1289,6 +1511,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
   gcry_mpi_t *result = NULL;
   unsigned char *cram_buffer = NULL;
 
+  *r_badpass = 0;
   where = "pfx";
   if (parse_tag (&p, &n, &ti))
     goto bailout;
@@ -1301,7 +1524,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
     goto bailout;
   p++; n--;
-  
+
   where = "authSave";
   if (parse_tag (&p, &n, &ti))
     goto bailout;
@@ -1349,7 +1572,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
       if (parse_tag (&p, &n, &ti))
         goto bailout;
       if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
-        break; /* Ready */ 
+        break; /* Ready */
       if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
         goto bailout;
 
@@ -1368,9 +1591,9 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
       if (parse_tag (&p, &n, &ti))
         goto bailout;
       if (lenndef)
-        len = ti.nhdr; 
+        len = ti.nhdr;
       else
-        len -= ti.nhdr; 
+        len -= ti.nhdr;
 
       if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
           && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
@@ -1384,7 +1607,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
           where = "bag.encryptedData";
           if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw,
                                         certcb, certcbarg,
-                                        result? NULL : &result))
+                                        result? NULL : &result, r_badpass))
             goto bailout;
           if (lenndef)
             len += consumed;
@@ -1433,7 +1656,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
             goto bailout;
         }
     }
-  
+
   gcry_free (cram_buffer);
   return result;
  bailout:
@@ -1455,7 +1678,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
 \f
 static size_t
 compute_tag_length (size_t n)
-{     
+{
   int needed = 0;
 
   if (n < 128)
@@ -1474,7 +1697,7 @@ compute_tag_length (size_t n)
 
 static unsigned char *
 store_tag_length (unsigned char *p, int tag, size_t n)
-{     
+{
   if (tag == TAG_SEQUENCE)
     tag |= 0x20; /* constructed */
 
@@ -1573,7 +1796,7 @@ create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
 
   /* 1. Store the version integer 3. */
   *p++ = TAG_INTEGER;
-  *p++ = 1; 
+  *p++ = 1;
   *p++ = 3;
 
   /* 2. Store another sequence. */
@@ -1581,8 +1804,8 @@ create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
 
   /* 3. Store the data OID. */
   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
-  memcpy (p, oid_data, DIM (oid_data)); 
-  p += DIM (oid_data); 
+  memcpy (p, oid_data, DIM (oid_data));
+  p += DIM (oid_data);
 
   /* 4. Next comes a context tag. */
   p = store_tag_length (p, 0xa0, len[4]);
@@ -1659,7 +1882,7 @@ create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
        SEQUENCE {
          INTEGER 0
          INTEGER
-         INTEGER 
+         INTEGER
          INTEGER
          INTEGER
          INTEGER
@@ -1669,10 +1892,15 @@ create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
          }
        }
      }
-*/  
-  
-static unsigned char * 
-build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
+
+  MODE controls what is being generated:
+     0 - As described above
+     1 - Ditto but without the padding
+     2 - Only the inner part (pkcs#1)
+*/
+
+static unsigned char *
+build_key_sequence (gcry_mpi_t *kparms, int mode, size_t *r_length)
 {
   int rc, i;
   size_t needed, n;
@@ -1680,7 +1908,7 @@ build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
   size_t plainlen;
   size_t outseqlen, oidseqlen, octstrlen, inseqlen;
 
-  needed = 3; /* The version(?) integer of value 0. */
+  needed = 3; /* The version integer with value 0. */
   for (i=0; kparms[i]; i++)
     {
       n = 0;
@@ -1707,24 +1935,28 @@ build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
   if (!n)
     return NULL;
   needed += n;
-  /* Encapsulate all into an octet string. */
-  octstrlen = needed;
-  n = compute_tag_length (needed);
-  if (!n)
-    return NULL;
-  needed += n;
-  /* Prepend the object identifier sequence. */
-  oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
-  needed += 2 + oidseqlen;
-  /* The version number. */
-  needed += 3;
-  /* And finally put the whole thing into a sequence. */
-  outseqlen = needed;
-  n = compute_tag_length (needed);
-  if (!n)
-    return NULL;
-  needed += n;
-  
+
+  if (mode != 2)
+    {
+      /* Encapsulate all into an octet string. */
+      octstrlen = needed;
+      n = compute_tag_length (needed);
+      if (!n)
+        return NULL;
+      needed += n;
+      /* Prepend the object identifier sequence. */
+      oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
+      needed += 2 + oidseqlen;
+      /* The version number. */
+      needed += 3;
+      /* And finally put the whole thing into a sequence. */
+      outseqlen = needed;
+      n = compute_tag_length (needed);
+      if (!n)
+        return NULL;
+      needed += n;
+    }
+
   /* allocate 8 extra bytes for padding */
   plain = gcry_malloc_secure (needed+8);
   if (!plain)
@@ -1732,23 +1964,27 @@ build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
       log_error ("error allocating encryption buffer\n");
       return NULL;
     }
-  
+
   /* And now fill the plaintext buffer. */
   p = plain;
-  p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
-  /* Store version. */
-  *p++ = TAG_INTEGER;
-  *p++ = 1;
-  *p++ = 0;
-  /* Store object identifier sequence. */
-  p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
-  p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
-  memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); 
-  p += DIM (oid_rsaEncryption); 
-  *p++ = TAG_NULL;
-  *p++ = 0;
-  /* Start with the octet string. */
-  p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
+  if (mode != 2)
+    {
+      p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
+      /* Store version. */
+      *p++ = TAG_INTEGER;
+      *p++ = 1;
+      *p++ = 0;
+      /* Store object identifier sequence. */
+      p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
+      p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
+      memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption));
+      p += DIM (oid_rsaEncryption);
+      *p++ = TAG_NULL;
+      *p++ = 0;
+      /* Start with the octet string. */
+      p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
+    }
+
   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
   /* Store the key parameters. */
   *p++ = TAG_INTEGER;
@@ -1766,7 +2002,7 @@ build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
           return NULL;
         }
       p = store_tag_length (p, TAG_INTEGER, n);
-      
+
       n = plain + needed - p;
       rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
       if (rc)
@@ -1781,10 +2017,14 @@ build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
 
   plainlen = p - plain;
   assert (needed == plainlen);
-  /* Append some pad characters; we already allocated extra space. */
-  n = 8 - plainlen % 8;
-  for (i=0; i < n; i++, plainlen++)
-    *p++ = n;
+
+  if (!mode)
+    {
+      /* Append some pad characters; we already allocated extra space. */
+      n = 8 - plainlen % 8;
+      for (i=0; i < n; i++, plainlen++)
+        *p++ = n;
+    }
 
   *r_length = plainlen;
   return plain;
@@ -1861,8 +2101,8 @@ build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
 
   /* 1. Store the data OID. */
   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
-  memcpy (p, oid_data, DIM (oid_data)); 
-  p += DIM (oid_data); 
+  memcpy (p, oid_data, DIM (oid_data));
+  p += DIM (oid_data);
 
   /* 2. Store a [0] tag. */
   p = store_tag_length (p, 0xa0, len[2]);
@@ -1878,8 +2118,8 @@ build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
   p = store_tag_length (p, TAG_OBJECT_ID,
                         DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
   memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
-          DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); 
-  p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); 
+          DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
+  p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
 
   /* 7. Store a [0] tag. */
   p = store_tag_length (p, 0xa0, len[7]);
@@ -1915,7 +2155,7 @@ build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
   if (needed != keybaglen)
     log_debug ("length mismatch: %lu, %lu\n",
                (unsigned long)needed, (unsigned long)keybaglen);
-  
+
   *r_length = keybaglen;
   return keybag;
 }
@@ -1978,8 +2218,8 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
 
   /* 1. Store the encryptedData OID. */
   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
-  memcpy (p, oid_encryptedData, DIM (oid_encryptedData)); 
-  p += DIM (oid_encryptedData); 
+  memcpy (p, oid_encryptedData, DIM (oid_encryptedData));
+  p += DIM (oid_encryptedData);
 
   /* 2. Store a [0] tag. */
   p = store_tag_length (p, 0xa0, len[2]);
@@ -1989,7 +2229,7 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
 
   /* 4. Store the integer 0. */
   *p++ = TAG_INTEGER;
-  *p++ = 1; 
+  *p++ = 1;
   *p++ = 0;
 
   /* 5. Store a sequence. */
@@ -1997,8 +2237,8 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
 
   /* 6. Store the data OID. */
   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
-  memcpy (p, oid_data, DIM (oid_data)); 
-  p += DIM (oid_data); 
+  memcpy (p, oid_data, DIM (oid_data));
+  p += DIM (oid_data);
 
   /* 7. Now for the pre-encoded algorithm identifier and the salt. */
   memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
@@ -2010,7 +2250,7 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
   memcpy (p, buffer, buflen);
   p += buflen;
   certbaglen = p - certbag;
-  
+
   if (needed != certbaglen)
     log_debug ("length mismatch: %lu, %lu\n",
                (unsigned long)needed, (unsigned long)certbaglen);
@@ -2021,7 +2261,7 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
 
 
 static unsigned char *
-build_cert_sequence (unsigned char *buffer, size_t buflen, 
+build_cert_sequence (const unsigned char *buffer, size_t buflen,
                      const unsigned char *sha1hash, const char *keyidstr,
                      size_t *r_length)
 {
@@ -2086,8 +2326,8 @@ build_cert_sequence (unsigned char *buffer, size_t buflen,
 
   /* 2. Store the pkcs12-cert-bag OID. */
   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
-  memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag)); 
-  p += DIM (oid_pkcs_12_CertBag); 
+  memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag));
+  p += DIM (oid_pkcs_12_CertBag);
 
   /* 3. Store a [0] tag. */
   p = store_tag_length (p, 0xa0, len[3]);
@@ -2099,8 +2339,8 @@ build_cert_sequence (unsigned char *buffer, size_t buflen,
   p = store_tag_length (p, TAG_OBJECT_ID,
                         DIM (oid_x509Certificate_for_pkcs_12));
   memcpy (p, oid_x509Certificate_for_pkcs_12,
-          DIM (oid_x509Certificate_for_pkcs_12)); 
-  p += DIM (oid_x509Certificate_for_pkcs_12); 
+          DIM (oid_x509Certificate_for_pkcs_12));
+  p += DIM (oid_x509Certificate_for_pkcs_12);
 
   /* 6. Store a [0] tag. */
   p = store_tag_length (p, 0xa0, len[6]);
@@ -2109,7 +2349,7 @@ build_cert_sequence (unsigned char *buffer, size_t buflen,
   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
   memcpy (p, buffer, buflen);
   p += buflen;
-  
+
   /* Append the attributes whose length we calculated at step 2b. */
   if (sha1hash)
     {
@@ -2130,7 +2370,7 @@ build_cert_sequence (unsigned char *buffer, size_t buflen,
   n = 8 - certseqlen % 8;
   for (i=0; i < n; i++, certseqlen++)
     *p++ = n;
-  
+
   *r_length = certseqlen;
   return certseq;
 }
@@ -2140,8 +2380,8 @@ build_cert_sequence (unsigned char *buffer, size_t buflen,
    Create a PKCS structure from it and return it as well as the length
    in R_LENGTH; return NULL in case of an error.  If CHARSET is not
    NULL, re-encode PW to that character set. */
-unsigned char * 
-p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
+unsigned char *
+p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen,
            const char *pw, const char *charset, size_t *r_length)
 {
   unsigned char *buffer = NULL;
@@ -2179,10 +2419,9 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
       if (cd == (jnlib_iconv_t)(-1))
         {
           log_error ("can't convert passphrase to"
-                     " requested charset `%s': %s\n",
+                     " requested charset '%s': %s\n",
                      charset, strerror (errno));
           gcry_free (pwbuf);
-          pwbuf = NULL;
           goto failure;
         }
 
@@ -2191,13 +2430,12 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
       outptr = pwbuf;
       outbytes = pwbufsize - 1;
       if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
-                      &outptr, &outbytes) == (size_t)-1) 
+                      &outptr, &outbytes) == (size_t)-1)
         {
           log_error ("error converting passphrase to"
-                     " requested charset `%s': %s\n",
+                     " requested charset '%s': %s\n",
                      charset, strerror (errno));
           gcry_free (pwbuf);
-          pwbuf = NULL;
           jnlib_iconv_close (cd);
           goto failure;
         }
@@ -2222,9 +2460,9 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
 
       /* Encrypt it. */
       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
-      crypt_block (buffer, buflen, salt, 8, 2048, pw,
+      crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0, pw,
                    GCRY_CIPHER_RFC2268_40, 1);
-      
+
       /* Encode the encrypted stuff into a bag. */
       seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
       seqlist[seqlistidx].length = n;
@@ -2239,17 +2477,18 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
   if (kparms)
     {
       /* Encode the key. */
-      buffer = build_key_sequence (kparms, &buflen);
+      buffer = build_key_sequence (kparms, 0, &buflen);
       if (!buffer)
         goto failure;
-      
+
       /* Encrypt it. */
       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
-      crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1);
+      crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0,
+                   pw, GCRY_CIPHER_3DES, 1);
 
       /* Encode the encrypted stuff into a bag. */
       if (cert && certlen)
-        seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, 
+        seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt,
                                                     sha1hash, keyidstr, &n);
       else
         seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt,
@@ -2281,9 +2520,27 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
 }
 
 
+/* This is actually not a pkcs#12 function but one which creates an
+   unencrypted a pkcs#1 private key.  */
+unsigned char *
+p12_raw_build (gcry_mpi_t *kparms, int rawmode, size_t *r_length)
+{
+  unsigned char *buffer;
+  size_t buflen;
+
+  assert (rawmode == 1 || rawmode == 2);
+  buffer = build_key_sequence (kparms, rawmode, &buflen);
+  if (!buffer)
+    return NULL;
+
+  *r_length = buflen;
+  return buffer;
+}
+
+
 #ifdef TEST
 
-static void 
+static void
 cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
 {
   printf ("got a certificate of %u bytes length\n", certlen);
@@ -2297,6 +2554,7 @@ main (int argc, char **argv)
   unsigned char *buf;
   size_t buflen;
   gcry_mpi_t *result;
+  int badpass;
 
   if (argc != 3)
     {
@@ -2310,13 +2568,13 @@ main (int argc, char **argv)
   fp = fopen (argv[1], "rb");
   if (!fp)
     {
-      fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
+      fprintf (stderr, "can't open '%s': %s\n", argv[1], strerror (errno));
       return 1;
     }
-  
+
   if (fstat (fileno(fp), &st))
     {
-      fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
+      fprintf (stderr, "can't stat '%s': %s\n", argv[1], strerror (errno));
       return 1;
     }
 
@@ -2324,12 +2582,12 @@ main (int argc, char **argv)
   buf = gcry_malloc (buflen+1);
   if (!buf || fread (buf, buflen, 1, fp) != 1)
     {
-      fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
+      fprintf (stderr, "error reading '%s': %s\n", argv[1], strerror (errno));
       return 1;
     }
   fclose (fp);
 
-  result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
+  result = p12_parse (buf, buflen, argv[2], cert_cb, NULL, &badpass);
   if (result)
     {
       int i, rc;
@@ -2356,7 +2614,7 @@ main (int argc, char **argv)
 
 /*
 Local Variables:
-compile-command: "gcc -Wall -O0 -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"
+compile-command: "gcc -Wall -O0 -g -DTEST=1 -o minip12 minip12.c ../common/libcommon.a -L /usr/local/lib -lgcrypt -lgpg-error"
 End:
 */
 #endif /* TEST */
similarity index 82%
rename from agent/minip12.h
rename to sm/minip12.h
index 998f82f..7a1950f 100644 (file)
 gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length,
                        const char *pw,
                        void (*certcb)(void*, const unsigned char*, size_t),
-                       void *certcbarg);
+                       void *certcbarg, int *r_badpass);
 
 unsigned char *p12_build (gcry_mpi_t *kparms,
-                          unsigned char *cert, size_t certlen,
+                          const void *cert, size_t certlen,
                           const char *pw, const char *charset,
                           size_t *r_length);
+unsigned char *p12_raw_build (gcry_mpi_t *kparms,
+                              int rawmode,
+                              size_t *r_length);
 
 
 #endif /*MINIP12_H*/
index 628b321..ec9f97e 100644 (file)
--- a/sm/misc.c
+++ b/sm/misc.c
@@ -1,5 +1,5 @@
 /* misc.c - Miscellaneous fucntions
- * Copyright (C) 2004, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2009, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 
 #include "gpgsm.h"
 #include "i18n.h"
-#include "setenv.h"
+#include "sysutils.h"
+#include "../common/tlv.h"
+#include "../common/sexp-parse.h"
+
 
 /* Setup the environment so that the pinentry is able to get all
    required information.  This is used prior to an exec of the
@@ -49,29 +52,29 @@ setup_pinentry_env (void)
      but print a warning.  */
   value = session_env_getenv (opt.session_env, "GPG_TTY");
   if (value)
-    setenv ("GPG_TTY", value, 1);
+    gnupg_setenv ("GPG_TTY", value, 1);
   else if (!(lc=getenv ("GPG_TTY")) || !*lc)
     {
       log_error (_("GPG_TTY has not been set - "
                    "using maybe bogus default\n"));
-      lc = ttyname (0);
+      lc = gnupg_ttyname (0);
       if (!lc)
         lc = "/dev/tty";
-      setenv ("GPG_TTY", lc, 1);
+      gnupg_setenv ("GPG_TTY", lc, 1);
     }
 
   if (opt.lc_ctype)
-    setenv ("LC_CTYPE", opt.lc_ctype, 1);
+    gnupg_setenv ("LC_CTYPE", opt.lc_ctype, 1);
 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
   else if ( (lc = setlocale (LC_CTYPE, "")) )
-    setenv ("LC_CTYPE", lc, 1);
+    gnupg_setenv ("LC_CTYPE", lc, 1);
 #endif
 
   if (opt.lc_messages)
-    setenv ("LC_MESSAGES", opt.lc_messages, 1);
+    gnupg_setenv ("LC_MESSAGES", opt.lc_messages, 1);
 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
   else if ( (lc = setlocale (LC_MESSAGES, "")) )
-    setenv ("LC_MESSAGES", lc, 1);
+    gnupg_setenv ("LC_MESSAGES", lc, 1);
 #endif
 
   iterator = 0;
@@ -81,9 +84,135 @@ setup_pinentry_env (void)
         continue;  /* Already set.  */
       value = session_env_getenv (opt.session_env, name);
       if (value)
-        setenv (name, value, 1);
+        gnupg_setenv (name, value, 1);
     }
 
 #endif /*!HAVE_W32_SYSTEM*/
 }
 
+
+
+/* Transform a sig-val style s-expression as returned by Libgcrypt to
+   one which includes an algorithm identifier encoding the public key
+   and the hash algorithm.  The public key algorithm is taken directly
+   from SIGVAL and the hash algorithm is given by MDALGO.  This is
+   required because X.509 merges the public key algorithm and the hash
+   algorithm into one OID but Libgcrypt is not aware of that.  The
+   function ignores missing parameters so that it can also be used to
+   create an siginfo value as expected by ksba_certreq_set_siginfo.
+   To create a siginfo s-expression a public-key s-expression may be
+   used instead of a sig-val.  We only support RSA for now.  */
+gpg_error_t
+transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
+                  unsigned char **r_newsigval, size_t *r_newsigvallen)
+{
+  gpg_error_t err;
+  const unsigned char *buf, *tok;
+  size_t buflen, toklen;
+  int depth, last_depth1, last_depth2;
+  int is_pubkey = 0;
+  const unsigned char *rsa_s = NULL;
+  size_t rsa_s_len;
+  const char *oid;
+  gcry_sexp_t sexp;
+
+  *r_newsigval = NULL;
+  if (r_newsigvallen)
+    *r_newsigvallen = 0;
+
+  buf = sigval;
+  buflen = sigvallen;
+  depth = 0;
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    return err;
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    return err;
+  if (tok && toklen == 7 && !memcmp ("sig-val", tok, toklen))
+    ;
+  else if (tok && toklen == 10 && !memcmp ("public-key", tok, toklen))
+    is_pubkey = 1;
+  else
+    return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    return err;
+  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+    return err;
+  if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen))
+    return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
+
+  last_depth1 = depth;
+  while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
+         && depth && depth >= last_depth1)
+    {
+      if (tok)
+        return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+      if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+        return err;
+      if (tok && toklen == 1)
+        {
+          const unsigned char **mpi;
+          size_t *mpi_len;
+
+          switch (*tok)
+            {
+            case 's': mpi = &rsa_s; mpi_len = &rsa_s_len; break;
+            default:  mpi = NULL;   mpi_len = NULL; break;
+            }
+          if (mpi && *mpi)
+            return gpg_error (GPG_ERR_DUP_VALUE);
+
+          if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+            return err;
+          if (tok && mpi)
+            {
+              *mpi = tok;
+              *mpi_len = toklen;
+            }
+        }
+
+      /* Skip to the end of the list. */
+      last_depth2 = depth;
+      while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
+             && depth && depth >= last_depth2)
+        ;
+      if (err)
+        return err;
+    }
+  if (err)
+    return err;
+
+  /* Map the hash algorithm to an OID.  */
+  switch (mdalgo)
+    {
+    case GCRY_MD_SHA1:
+      oid = "1.2.840.113549.1.1.5";  /* sha1WithRSAEncryption */
+      break;
+
+    case GCRY_MD_SHA256:
+      oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */
+      break;
+
+    case GCRY_MD_SHA384:
+      oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */
+      break;
+
+    case GCRY_MD_SHA512:
+      oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */
+      break;
+
+    default:
+      return gpg_error (GPG_ERR_DIGEST_ALGO);
+    }
+
+  if (rsa_s && !is_pubkey)
+    err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))",
+                           oid, (int)rsa_s_len, rsa_s);
+  else
+    err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s))", oid);
+  if (err)
+    return err;
+  err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen);
+  gcry_sexp_release (sexp);
+
+  return err;
+}
index d0db481..56f537e 100644 (file)
@@ -63,7 +63,7 @@ read_list (char *key, char *country, int *lnr)
       if (!listfp && errno != ENOENT)
         {
           err = gpg_error_from_syserror ();
-          log_error (_("can't open `%s': %s\n"), listname, gpg_strerror (err));
+          log_error (_("can't open '%s': %s\n"), listname, gpg_strerror (err));
           return err;
         }
     }
@@ -89,20 +89,20 @@ read_list (char *key, char *country, int *lnr)
                                  : GPG_ERR_INCOMPLETE_LINE);
         }
       ++*lnr;
-      
+
       /* Allow for empty lines and spaces */
       for (p=line; spacep (p); p++)
         ;
     }
   while (!*p || *p == '\n' || *p == '#');
-  
+
   for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
     if ( p[i] != ':' )
       key[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
   key[j] = 0;
   if (j != 40 || !(spacep (p+i) || p[i] == '\n'))
     {
-      log_error (_("invalid formatted fingerprint in `%s', line %d\n"),
+      log_error (_("invalid formatted fingerprint in '%s', line %d\n"),
                  listname, *lnr);
       return gpg_error (GPG_ERR_BAD_DATA);
     }
@@ -110,8 +110,8 @@ read_list (char *key, char *country, int *lnr)
   i++;
   while (spacep (p+i))
     i++;
-  if ( p[i] >= 'a' && p[i] <= 'z' 
-       && p[i+1] >= 'a' && p[i+1] <= 'z' 
+  if ( p[i] >= 'a' && p[i] <= 'z'
+       && p[i+1] >= 'a' && p[i+1] <= 'z'
        && (spacep (p+i+2) || p[i+2] == '\n'))
     {
       country[0] = p[i];
@@ -120,7 +120,7 @@ read_list (char *key, char *country, int *lnr)
     }
   else
     {
-      log_error (_("invalid country code in `%s', line %d\n"), listname, *lnr);
+      log_error (_("invalid country code in '%s', line %d\n"), listname, *lnr);
       return gpg_error (GPG_ERR_BAD_DATA);
     }
 
@@ -135,7 +135,7 @@ read_list (char *key, char *country, int *lnr)
    as maintained by gpg-agent and includes fingerprints of root
    certificates to be used for qualified (legally binding like
    handwritten) signatures.  We keep this list system wide and not
-   per user because it is not a decision of the user. 
+   per user because it is not a decision of the user.
 
    Returns: 0 if the certificate is included.  GPG_ERR_NOT_FOUND if it
    is not in the list or any other error (e.g. if no list of
@@ -161,7 +161,11 @@ gpgsm_is_in_qualified_list (ctrl_t ctrl, ksba_cert_t cert, char *country)
     return gpg_error (GPG_ERR_GENERAL);
 
   if (listfp)
-    rewind (listfp);
+    {
+      /* W32ce has no rewind, thus we use the equivalent code.  */
+      fseek (listfp, 0, SEEK_SET);
+      clearerr (listfp);
+    }
   while (!(err = read_list (key, mycountry, &lnr)))
     {
       if (!strcmp (key, fpr))
@@ -206,7 +210,7 @@ gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert)
                   "equated to a handwritten signature.\n\n%s%s"
                   "Are you really sure that you want to do this?"),
                 subject? subject:"?",
-                opt.qualsig_approval? 
+                opt.qualsig_approval?
                 "":
                 _("Note, that this software is not officially approved "
                   "to create or verify such signatures.\n"),
@@ -242,7 +246,7 @@ gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert)
         *p++ = *s;
     }
   *p = 0;
-  free (name); 
+  free (name);
 
 
   err = gpgsm_agent_get_confirmation (ctrl, buffer);
@@ -311,7 +315,7 @@ gpgsm_not_qualified_warning (ctrl_t ctrl, ksba_cert_t cert)
         *p++ = *s;
     }
   *p = 0;
-  free (name); 
+  free (name);
 
 
   err = gpgsm_agent_get_confirmation (ctrl, buffer);
index 6ba5e58..0bee5b2 100644 (file)
@@ -1,6 +1,6 @@
-/* server.c - Server mode and main entry point 
- * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 
- *               2009, 2010 Free Software Foundation, Inc.
+/* server.c - Server mode and main entry point
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -81,7 +81,7 @@ strcpy_escaped_plus (char *d, const char *s)
   while (*s)
     {
       if (*s == '%' && s[1] && s[2])
-        { 
+        {
           s++;
           *d++ = xtoi_2 (s);
           s += 2;
@@ -91,11 +91,11 @@ strcpy_escaped_plus (char *d, const char *s)
       else
         *d++ = *s++;
     }
-  *d = 0; 
+  *d = 0;
 }
 
 
-/* Skip over options.  
+/* Skip over options.
    Blanks after the options are also removed. */
 static char *
 skip_options (const char *line)
@@ -136,7 +136,7 @@ data_line_cookie_write (void *cookie, const void *buffer, size_t size)
 
   if (assuan_send_data (ctx, buffer, size))
     {
-      errno = EIO;
+      gpg_err_set_errno (EIO);
       return -1;
     }
 
@@ -150,7 +150,7 @@ data_line_cookie_close (void *cookie)
 
   if (assuan_send_data (ctx, NULL, 0))
     {
-      errno = EIO;
+      gpg_err_set_errno (EIO);
       return -1;
     }
 
@@ -158,11 +158,14 @@ data_line_cookie_close (void *cookie)
 }
 
 
-static void 
+static void
 close_message_fd (ctrl_t ctrl)
 {
   if (ctrl->server_local->message_fd != -1)
     {
+#ifdef HAVE_W32CE_SYSTEM
+#warning Is this correct for W32/W32CE?
+#endif
       close (ctrl->server_local->message_fd);
       ctrl->server_local->message_fd = -1;
     }
@@ -177,7 +180,7 @@ start_audit_session (ctrl_t ctrl)
   ctrl->audit = NULL;
   if (ctrl->server_local->enable_audit_log && !(ctrl->audit = audit_new ()) )
     return gpg_error_from_syserror ();
-  
+
   return 0;
 }
 
@@ -271,10 +274,15 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
       int i = *value? atoi (value) : 0;
       ctrl->with_validation = i;
     }
+  else if (!strcmp (key, "with-secret"))
+    {
+      int i = *value? atoi (value) : 0;
+      ctrl->with_secret = i;
+    }
   else if (!strcmp (key, "validation-model"))
     {
       int i = gpgsm_parse_validation_model (value);
-      if ( i >= 0 && i <= 1 )
+      if ( i >= 0 && i <= 2 )
         ctrl->validation_model = i;
       else
         err = gpg_error (GPG_ERR_ASS_PARAMETER);
@@ -335,9 +343,9 @@ input_notify (assuan_context_t ctx, char *line)
   ctrl->is_pem = 0;
   ctrl->is_base64 = 0;
   if (strstr (line, "--armor"))
-    ctrl->is_pem = 1;  
+    ctrl->is_pem = 1;
   else if (strstr (line, "--base64"))
-    ctrl->is_base64 = 1; 
+    ctrl->is_base64 = 1;
   else if (strstr (line, "--binary"))
     ;
   else
@@ -353,14 +361,14 @@ output_notify (assuan_context_t ctx, char *line)
   ctrl->create_pem = 0;
   ctrl->create_base64 = 0;
   if (strstr (line, "--armor"))
-    ctrl->create_pem = 1;  
+    ctrl->create_pem = 1;
   else if (strstr (line, "--base64"))
     ctrl->create_base64 = 1; /* just the raw output */
   return 0;
 }
 
 
-static const char hlp_recipient[] = 
+static const char hlp_recipient[] =
   "RECIPIENT <userID>\n"
   "\n"
   "Set the recipient for the encryption.  USERID shall be the\n"
@@ -396,7 +404,7 @@ cmd_recipient (assuan_context_t ctx, char *line)
 }
 
 
-static const char hlp_signer[] = 
+static const char hlp_signer[] =
   "SIGNER <userID>\n"
   "\n"
   "Set the signer's keys for the signature creation.  USERID should\n"
@@ -420,18 +428,18 @@ cmd_signer (assuan_context_t ctx, char *line)
                               &ctrl->server_local->signerlist, 0);
   if (rc)
     {
-      gpgsm_status2 (ctrl, STATUS_INV_SGNR, 
+      gpgsm_status2 (ctrl, STATUS_INV_SGNR,
                      get_inv_recpsgnr_code (rc), line, NULL);
       /* For compatibiliy reasons we also issue the old code after the
          new one.  */
-      gpgsm_status2 (ctrl, STATUS_INV_RECP, 
+      gpgsm_status2 (ctrl, STATUS_INV_RECP,
                      get_inv_recpsgnr_code (rc), line, NULL);
     }
   return rc;
 }
 
 
-static const char hlp_encrypt[] = 
+static const char hlp_encrypt[] =
   "ENCRYPT \n"
   "\n"
   "Do the actual encryption process. Takes the plaintext from the INPUT\n"
@@ -451,7 +459,7 @@ cmd_encrypt (assuan_context_t ctx, char *line)
   ctrl_t ctrl = assuan_get_pointer (ctx);
   certlist_t cl;
   int inp_fd, out_fd;
-  FILE *out_fp;
+  estream_t out_fp;
   int rc;
 
   (void)line;
@@ -463,10 +471,10 @@ cmd_encrypt (assuan_context_t ctx, char *line)
   if (out_fd == -1)
     return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
-  out_fp = fdopen (dup (out_fd), "w");
+  out_fp = es_fdopen_nc (out_fd, "w");
   if (!out_fp)
-    return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
-  
+    return set_error (gpg_err_code_from_syserror (), "fdopen() failed");
+
   /* Now add all encrypt-to marked recipients from the default
      list. */
   rc = 0;
@@ -483,7 +491,7 @@ cmd_encrypt (assuan_context_t ctx, char *line)
     rc = gpgsm_encrypt (assuan_get_pointer (ctx),
                         ctrl->server_local->recplist,
                         inp_fd, out_fp);
-  fclose (out_fp);
+  es_fclose (out_fp);
 
   gpgsm_release_certlist (ctrl->server_local->recplist);
   ctrl->server_local->recplist = NULL;
@@ -495,7 +503,7 @@ cmd_encrypt (assuan_context_t ctx, char *line)
 }
 
 
-static const char hlp_decrypt[] = 
+static const char hlp_decrypt[] =
   "DECRYPT\n"
   "\n"
   "This performs the decrypt operation after doing some check on the\n"
@@ -508,7 +516,7 @@ cmd_decrypt (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int inp_fd, out_fd;
-  FILE *out_fp;
+  estream_t out_fp;
   int rc;
 
   (void)line;
@@ -520,16 +528,16 @@ cmd_decrypt (assuan_context_t ctx, char *line)
   if (out_fd == -1)
     return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
-  out_fp = fdopen (dup(out_fd), "w");
+  out_fp = es_fdopen_nc (out_fd, "w");
   if (!out_fp)
-    return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
+    return set_error (gpg_err_code_from_syserror (), "fdopen() failed");
 
   rc = start_audit_session (ctrl);
   if (!rc)
-    rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); 
-  fclose (out_fp);
+    rc = gpgsm_decrypt (ctrl, inp_fd, out_fp);
+  es_fclose (out_fp);
 
-  /* close and reset the fd */
+  /* Close and reset the fds. */
   close_message_fd (ctrl);
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
@@ -538,7 +546,7 @@ cmd_decrypt (assuan_context_t ctx, char *line)
 }
 
 
-static const char hlp_verify[] = 
+static const char hlp_verify[] =
   "VERIFY\n"
   "\n"
   "This does a verify operation on the message send to the input FD.\n"
@@ -554,7 +562,7 @@ cmd_verify (assuan_context_t ctx, char *line)
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
   int out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
-  FILE *out_fp = NULL;
+  estream_t out_fp = NULL;
 
   (void)line;
 
@@ -563,19 +571,18 @@ cmd_verify (assuan_context_t ctx, char *line)
 
   if (out_fd != -1)
     {
-      out_fp = fdopen ( dup(out_fd), "w");
+      out_fp = es_fdopen_nc (out_fd, "w");
       if (!out_fp)
-        return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
+        return set_error (gpg_err_code_from_syserror (), "fdopen() failed");
     }
 
   rc = start_audit_session (ctrl);
   if (!rc)
     rc = gpgsm_verify (assuan_get_pointer (ctx), fd,
                        ctrl->server_local->message_fd, out_fp);
-  if (out_fp)
-    fclose (out_fp);
+  es_fclose (out_fp);
 
-  /* close and reset the fd */
+  /* Close and reset the fd.  */
   close_message_fd (ctrl);
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
@@ -584,7 +591,7 @@ cmd_verify (assuan_context_t ctx, char *line)
 }
 
 
-static const char hlp_sign[] = 
+static const char hlp_sign[] =
   "SIGN [--detached]\n"
   "\n"
   "Sign the data set with the INPUT command and write it to the sink\n"
@@ -595,7 +602,7 @@ cmd_sign (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int inp_fd, out_fd;
-  FILE *out_fp;
+  estream_t out_fp;
   int detached;
   int rc;
 
@@ -606,9 +613,9 @@ cmd_sign (assuan_context_t ctx, char *line)
   if (out_fd == -1)
     return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
-  detached = has_option (line, "--detached"); 
+  detached = has_option (line, "--detached");
 
-  out_fp = fdopen ( dup(out_fd), "w");
+  out_fp = es_fdopen_nc (out_fd, "w");
   if (!out_fp)
     return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
 
@@ -616,7 +623,7 @@ cmd_sign (assuan_context_t ctx, char *line)
   if (!rc)
     rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist,
                      inp_fd, detached, out_fp);
-  fclose (out_fp);
+  es_fclose (out_fp);
 
   /* close and reset the fd */
   close_message_fd (ctrl);
@@ -627,7 +634,7 @@ cmd_sign (assuan_context_t ctx, char *line)
 }
 
 
-static const char hlp_import[] = 
+static const char hlp_import[] =
   "IMPORT [--re-import]\n"
   "\n"
   "Import the certificates read form the input-fd, return status\n"
@@ -645,7 +652,7 @@ cmd_import (assuan_context_t ctx, char *line)
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
   int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
-  int reimport = has_option (line, "--re-import"); 
+  int reimport = has_option (line, "--re-import");
 
   (void)line;
 
@@ -678,7 +685,7 @@ cmd_export (assuan_context_t ctx, char *line)
   char *p;
   strlist_t list, sl;
   int use_data;
-  
+
   use_data = has_option (line, "--data");
 
   if (use_data)
@@ -721,31 +728,31 @@ cmd_export (assuan_context_t ctx, char *line)
       if (!stream)
         {
           free_strlist (list);
-          return set_error (GPG_ERR_ASS_GENERAL, 
+          return set_error (GPG_ERR_ASS_GENERAL,
                             "error setting up a data stream");
         }
-      gpgsm_export (ctrl, list, NULL, stream);
+      gpgsm_export (ctrl, list, stream);
       es_fclose (stream);
     }
   else
     {
       int fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
-      FILE *out_fp;
+      estream_t out_fp;
 
       if (fd == -1)
         {
           free_strlist (list);
           return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
         }
-      out_fp = fdopen ( dup(fd), "w");
+      out_fp = es_fdopen_nc (fd, "w");
       if (!out_fp)
         {
           free_strlist (list);
-          return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
+          return set_error (gpg_err_code_from_syserror (), "fdopen() failed");
         }
-      
-      gpgsm_export (ctrl, list, out_fp, NULL);
-      fclose (out_fp);
+
+      gpgsm_export (ctrl, list, out_fp);
+      es_fclose (out_fp);
     }
 
   free_strlist (list);
@@ -840,6 +847,14 @@ cmd_message (assuan_context_t ctx, char *line)
   rc = assuan_command_parse_fd (ctx, line, &sysfd);
   if (rc)
     return rc;
+
+#ifdef HAVE_W32CE_SYSTEM
+  sysfd = _assuan_w32ce_finish_pipe ((int)sysfd, 0);
+  if (sysfd == INVALID_HANDLE_VALUE)
+    return set_error (gpg_err_code_from_syserror (),
+                     "rvid conversion failed");
+#endif
+
   fd = translate_sys2libc_fd (sysfd, 0);
   if (fd == -1)
     return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
@@ -849,7 +864,7 @@ cmd_message (assuan_context_t ctx, char *line)
 
 
 
-static const char hlp_listkeys[] = 
+static const char hlp_listkeys[] =
   "LISTKEYS [<patterns>]\n"
   "LISTSECRETKEYS [<patterns>]\n"
   "DUMPKEYS [<patterns>]\n"
@@ -877,7 +892,7 @@ static const char hlp_listkeys[] =
   "\n"
   "  \"list-to-output\" set to true: Write output to the file descriptor\n"
   "                                given by the last \"OUTPUT\" command.";
-static int 
+static int
 do_listkeys (assuan_context_t ctx, char *line, int mode)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -916,20 +931,20 @@ do_listkeys (assuan_context_t ctx, char *line, int mode)
 
       if ( outfd == -1 )
         return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
-      fp = es_fdopen ( dup (outfd), "w");
+      fp = es_fdopen_nc (outfd, "w");
       if (!fp)
-        return set_error (GPG_ERR_ASS_GENERAL, "es_fdopen() failed");
+        return set_error (gpg_err_code_from_syserror (), "es_fdopen() failed");
     }
   else
     {
       fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
       if (!fp)
-        return set_error (GPG_ERR_ASS_GENERAL, 
+        return set_error (GPG_ERR_ASS_GENERAL,
                           "error setting up a data stream");
     }
-  
+
   ctrl->with_colons = 1;
-  listmode = mode; 
+  listmode = mode;
   if (ctrl->server_local->list_internal)
     listmode |= (1<<6);
   if (ctrl->server_local->list_external)
@@ -978,9 +993,8 @@ cmd_genkey (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int inp_fd, out_fd;
-  FILE *out_fp;
+  estream_t in_stream, out_stream;
   int rc;
-  estream_t in_stream;
 
   (void)line;
 
@@ -995,14 +1009,15 @@ cmd_genkey (assuan_context_t ctx, char *line)
   if (!in_stream)
     return set_error (GPG_ERR_ASS_GENERAL, "es_fdopen failed");
 
-  out_fp = fdopen ( dup(out_fd), "w");
-  if (!out_fp)
+  out_stream = es_fdopen_nc (out_fd, "w");
+  if (!out_stream)
     {
       es_fclose (in_stream);
-      return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
+      return set_error (gpg_err_code_from_syserror (), "fdopen() failed");
     }
-  rc = gpgsm_genkey (ctrl, in_stream, out_fp);
-  fclose (out_fp);
+  rc = gpgsm_genkey (ctrl, in_stream, out_stream);
+  es_fclose (out_stream);
+  es_fclose (in_stream);
 
   /* close and reset the fds */
   assuan_close_input_fd (ctx);
@@ -1030,8 +1045,8 @@ cmd_getauditlog (assuan_context_t ctx, char *line)
   int opt_data, opt_html;
   int rc;
 
-  opt_data = has_option (line, "--data"); 
-  opt_html = has_option (line, "--html"); 
+  opt_data = has_option (line, "--data");
+  opt_html = has_option (line, "--html");
   line = skip_options (line);
 
   if (!ctrl->audit)
@@ -1041,7 +1056,7 @@ cmd_getauditlog (assuan_context_t ctx, char *line)
     {
       out_stream = es_fopencookie (ctx, "w", data_line_cookie_functions);
       if (!out_stream)
-        return set_error (GPG_ERR_ASS_GENERAL, 
+        return set_error (GPG_ERR_ASS_GENERAL,
                           "error setting up a data stream");
     }
   else
@@ -1049,7 +1064,7 @@ cmd_getauditlog (assuan_context_t ctx, char *line)
       out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
       if (out_fd == -1)
         return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
-      
+
       out_stream = es_fdopen_nc (out_fd, "w");
       if (!out_stream)
         {
@@ -1068,8 +1083,7 @@ cmd_getauditlog (assuan_context_t ctx, char *line)
   return rc;
 }
 
-
-static const char hlp_getinfo[] = 
+static const char hlp_getinfo[] =
   "GETINFO <what>\n"
   "\n"
   "Multipurpose function to return a variety of information.\n"
@@ -1141,7 +1155,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
 }
 
 
-\f
 static const char hlp_passwd[] =
   "PASSWD <userID>\n"
   "\n"
@@ -1161,7 +1174,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
     ;
   else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))
     err = gpg_error (GPG_ERR_INTERNAL);
-  else 
+  else
     {
       char *desc = gpgsm_format_keydesc (cert);
       err = gpgsm_agent_passwd (ctrl, grip, desc);
@@ -1175,8 +1188,6 @@ cmd_passwd (assuan_context_t ctx, char *line)
 }
 
 
-
-
 \f
 /* Return true if the command CMD implements the option OPT.  */
 static int
@@ -1187,7 +1198,7 @@ command_has_option (const char *cmd, const char *cmdopt)
       if (!strcmp (cmdopt, "re-import"))
         return 1;
     }
-      
+
   return 0;
 }
 
@@ -1209,8 +1220,8 @@ register_commands (assuan_context_t ctx)
     { "SIGN",          cmd_sign,      hlp_sign },
     { "IMPORT",        cmd_import,    hlp_import },
     { "EXPORT",        cmd_export,    hlp_export },
-    { "INPUT",         NULL,          hlp_input }, 
-    { "OUTPUT",        NULL,          hlp_output }, 
+    { "INPUT",         NULL,          hlp_input },
+    { "OUTPUT",        NULL,          hlp_output },
     { "MESSAGE",       cmd_message,   hlp_message },
     { "LISTKEYS",      cmd_listkeys,  hlp_listkeys },
     { "DUMPKEYS",      cmd_dumpkeys,  hlp_listkeys },
@@ -1231,7 +1242,7 @@ register_commands (assuan_context_t ctx)
                                     table[i].help);
       if (rc)
         return rc;
-    } 
+    }
   return 0;
 }
 
@@ -1253,9 +1264,16 @@ gpgsm_server (certlist_t default_recplist)
 
   /* We use a pipe based server so that we can work from scripts.
      assuan_init_pipe_server will automagically detect when we are
-     called with a socketpair and ignore FIELDES in this case. */
-  filedes[0] = assuan_fdopen (0);
-  filedes[1] = assuan_fdopen (1);
+     called with a socketpair and ignore FILEDES in this case. */
+#ifdef HAVE_W32CE_SYSTEM
+  #define SERVER_STDIN es_fileno(es_stdin)
+  #define SERVER_STDOUT es_fileno(es_stdout)
+#else
+#define SERVER_STDIN 0
+#define SERVER_STDOUT 1
+#endif
+  filedes[0] = assuan_fdopen (SERVER_STDIN);
+  filedes[1] = assuan_fdopen (SERVER_STDOUT);
   rc = assuan_new (&ctx);
   if (rc)
     {
@@ -1281,19 +1299,18 @@ gpgsm_server (certlist_t default_recplist)
   if (opt.verbose || opt.debug)
     {
       char *tmp = NULL;
-      const char *s1 = getenv ("GPG_AGENT_INFO");
-      const char *s2 = getenv ("DIRMNGR_INFO");
 
+      /* Fixme: Use the really used socket name.  */
       if (asprintf (&tmp,
                     "Home: %s\n"
                     "Config: %s\n"
-                    "AgentInfo: %s\n"
                     "DirmngrInfo: %s\n"
                     "%s",
                     opt.homedir,
                     opt.config_filename,
-                    s1?s1:"[not set]",
-                    s2?s2:"[not set]",
+                    (dirmngr_user_socket_name ()
+                     ? dirmngr_user_socket_name ()
+                     : dirmngr_sys_socket_name ()),
                     hello) > 0)
         {
           assuan_set_hello_line (ctx, tmp);
@@ -1316,9 +1333,6 @@ gpgsm_server (certlist_t default_recplist)
   ctrl.server_local->list_external = 0;
   ctrl.server_local->default_recplist = default_recplist;
 
-  if (DBG_ASSUAN)
-    assuan_set_log_stream (ctx, log_get_stream ());
-
   for (;;)
     {
       rc = assuan_accept (ctx);
@@ -1331,7 +1345,7 @@ gpgsm_server (certlist_t default_recplist)
           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
           break;
         }
-      
+
       rc = assuan_process (ctx);
       if (rc)
         {
@@ -1375,40 +1389,40 @@ gpgsm_status2 (ctrl_t ctrl, int no, ...)
             statusfp = stderr;
           else
             statusfp = fdopen (ctrl->status_fd, "w");
-      
+
           if (!statusfp)
             {
               log_fatal ("can't open fd %d for status output: %s\n",
                          ctrl->status_fd, strerror(errno));
             }
         }
-      
+
       fputs ("[GNUPG:] ", statusfp);
       fputs (get_status_string (no), statusfp);
-    
+
       while ( (text = va_arg (arg_ptr, const char*) ))
         {
           putc ( ' ', statusfp );
-          for (; *text; text++) 
+          for (; *text; text++)
             {
               if (*text == '\n')
                 fputs ( "\\n", statusfp );
               else if (*text == '\r')
                 fputs ( "\\r", statusfp );
-              else 
+              else
                 putc ( *(const byte *)text,  statusfp );
             }
         }
       putc ('\n', statusfp);
       fflush (statusfp);
     }
-  else 
+  else
     {
       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
       char buf[950], *p;
       size_t n;
 
-      p = buf; 
+      p = buf;
       n = 0;
       while ( (text = va_arg (arg_ptr, const char *)) )
         {
@@ -1454,11 +1468,8 @@ gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
 gpg_error_t
 gpgsm_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
 {
-  if (!ctrl || !ctrl->server_local 
+  if (!ctrl || !ctrl->server_local
       || !ctrl->server_local->allow_pinentry_notify)
     return 0;
   return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
 }
-
-
-
index c173740..08eebb7 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -1,5 +1,6 @@
 /* sign.c - Sign a message
- *     Copyright (C) 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2008,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 static int
 hash_data (int fd, gcry_md_hd_t md)
 {
-  FILE *fp;
+  estream_t fp;
   char buffer[4096];
   int nread;
   int rc = 0;
 
-  fp = fdopen ( dup (fd), "rb");
+  fp = es_fdopen_nc (fd, "rb");
   if (!fp)
     {
       log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
@@ -52,40 +53,41 @@ hash_data (int fd, gcry_md_hd_t md)
 
   do
     {
-      nread = fread (buffer, 1, DIM(buffer), fp);
+      nread = es_fread (buffer, 1, DIM(buffer), fp);
       gcry_md_write (md, buffer, nread);
     }
   while (nread);
-  if (ferror (fp))
+  if (es_ferror (fp))
     {
       log_error ("read error on fd %d: %s\n", fd, strerror (errno));
       rc = -1;
     }
-  fclose (fp);
+  es_fclose (fp);
   return rc;
 }
 
+
 static int
 hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer)
 {
   gpg_error_t err;
-  FILE *fp;
+  estream_t fp;
   char buffer[4096];
   int nread;
   int rc = 0;
   int any = 0;
 
-  fp = fdopen ( dup (fd), "rb");
+  fp = es_fdopen_nc (fd, "rb");
   if (!fp)
     {
-      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
+      gpg_error_t tmperr = gpg_error_from_syserror ();
       log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
       return tmperr;
     }
 
   do
     {
-      nread = fread (buffer, 1, DIM(buffer), fp);
+      nread = es_fread (buffer, 1, DIM(buffer), fp);
       if (nread)
         {
           any = 1;
@@ -99,18 +101,18 @@ hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer)
         }
     }
   while (nread && !rc);
-  if (ferror (fp))
+  if (es_ferror (fp))
     {
-      rc = gpg_error (gpg_err_code_from_errno (errno));
+      rc = gpg_error_from_syserror ();
       log_error ("read error on fd %d: %s\n", fd, strerror (errno));
     }
-  fclose (fp);
+  es_fclose (fp);
   if (!any)
     {
       /* We can't allow to sign an empty message because it does not
-         make much sense and more seriously, ksba-cms_build has
+         make much sense and more seriously, ksba_cms_build has
          already written the tag for data and now expects an octet
-         string but an octet string of zeize 0 is illegal. */
+         string and an octet string of size 0 is illegal.  */
       log_error ("cannot sign an empty message\n");
       rc = gpg_error (GPG_ERR_NO_DATA);
     }
@@ -209,7 +211,7 @@ get_default_signer (ctrl_t ctrl)
       return cert;
     }
 
-  rc = keydb_classify_name (opt.local_user, &desc);
+  rc = classify_user_id (opt.local_user, &desc, 0);
   if (rc)
     {
       log_error ("failed to find default signer: %s\n", gpg_strerror (rc));
@@ -310,7 +312,7 @@ add_certificate_list (ctrl_t ctrl, ksba_cms_t cms, ksba_cert_t cert)
    be used if the value of this argument is NULL. */
 int
 gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
-            int data_fd, int detached, FILE *out_fp)
+            int data_fd, int detached, estream_t out_fp)
 {
   int i, rc;
   gpg_error_t err;
@@ -338,7 +340,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
     }
 
   ctrl->pem_name = "SIGNED MESSAGE";
-  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
+  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
       log_error ("can't create writer: %s\n", gpg_strerror (rc));
@@ -501,28 +503,31 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
   /* Check whether one of the certificates is qualified.  Note that we
      already validated the certificate and thus the user data stored
      flag must be available. */
-  for (cl=signerlist; cl; cl = cl->next)
+  if (!opt.no_chain_validation)
     {
-      size_t buflen;
-      char buffer[1];
-
-      err = ksba_cert_get_user_data (cl->cert, "is_qualified",
-                                     &buffer, sizeof (buffer), &buflen);
-      if (err || !buflen)
-        {
-          log_error (_("checking for qualified certificate failed: %s\n"),
-                     gpg_strerror (err));
-          rc = err;
-          goto leave;
-        }
-      if (*buffer)
-        err = gpgsm_qualified_consent (ctrl, cl->cert);
-      else
-        err = gpgsm_not_qualified_warning (ctrl, cl->cert);
-      if (err)
+      for (cl=signerlist; cl; cl = cl->next)
         {
-          rc = err;
-          goto leave;
+          size_t buflen;
+          char buffer[1];
+
+          err = ksba_cert_get_user_data (cl->cert, "is_qualified",
+                                         &buffer, sizeof (buffer), &buflen);
+          if (err || !buflen)
+            {
+              log_error (_("checking for qualified certificate failed: %s\n"),
+                         gpg_strerror (err));
+              rc = err;
+              goto leave;
+            }
+          if (*buffer)
+            err = gpgsm_qualified_consent (ctrl, cl->cert);
+          else
+            err = gpgsm_not_qualified_warning (ctrl, cl->cert);
+          if (err)
+            {
+              rc = err;
+              goto leave;
+            }
         }
     }
 
@@ -542,7 +547,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
       algo = gcry_md_map_name (algoid);
       if (!algo)
         {
-          log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
+          log_error ("unknown hash algorithm '%s'\n", algoid? algoid:"?");
           rc = gpg_error (GPG_ERR_BUG);
           goto leave;
         }
index 0444dfe..2e91137 100644 (file)
@@ -1,5 +1,6 @@
 /* verify.c - Verify a messages signature
- * Copyright (C) 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2007,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -52,11 +53,11 @@ static gpg_error_t
 hash_data (int fd, gcry_md_hd_t md)
 {
   gpg_error_t err = 0;
-  FILE *fp;
+  estream_t fp;
   char buffer[4096];
   int nread;
 
-  fp = fdopen ( dup (fd), "rb");
+  fp = es_fdopen_nc (fd, "rb");
   if (!fp)
     {
       err = gpg_error_from_syserror ();
@@ -66,27 +67,27 @@ hash_data (int fd, gcry_md_hd_t md)
 
   do
     {
-      nread = fread (buffer, 1, DIM(buffer), fp);
+      nread = es_fread (buffer, 1, DIM(buffer), fp);
       gcry_md_write (md, buffer, nread);
     }
   while (nread);
-  if (ferror (fp))
+  if (es_ferror (fp))
     {
       err = gpg_error_from_syserror ();
       log_error ("read error on fd %d: %s\n", fd, gpg_strerror (err));
     }
-  fclose (fp);
+  es_fclose (fp);
   return err;
 }
 
 
 
 \f
-/* Perform a verify operation.  To verify detached signatures, data_fd
+/* Perform a verify operation.  To verify detached signatures, DATA_FD
    must be different than -1.  With OUT_FP given and a non-detached
-   signature, the signed material is written to that stream. */
+   signature, the signed material is written to that stream.  */
 int
-gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
+gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
 {
   int i, rc;
   Base64Context b64reader = NULL;
@@ -102,7 +103,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
   const char *algoid;
   int algo;
   int is_detached;
-  FILE *fp = NULL;
+  estream_t in_fp = NULL;
   char *p;
 
   audit_set_type (ctrl->audit, AUDIT_TYPE_VERIFY);
@@ -116,15 +117,15 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
     }
 
 
-  fp = fdopen ( dup (in_fd), "rb");
-  if (!fp)
+  in_fp = es_fdopen_nc (in_fd, "rb");
+  if (!in_fp)
     {
-      rc = gpg_error (gpg_err_code_from_errno (errno));
+      rc = gpg_error_from_syserror ();
       log_error ("fdopen() failed: %s\n", strerror (errno));
       goto leave;
     }
 
-  rc = gpgsm_create_reader (&b64reader, ctrl, fp, 0, &reader);
+  rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader);
   if (rc)
     {
       log_error ("can't create reader: %s\n", gpg_strerror (rc));
@@ -133,7 +134,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
 
   if (out_fp)
     {
-      rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
+      rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
       if (rc)
         {
           log_error ("can't create writer: %s\n", gpg_strerror (rc));
@@ -193,7 +194,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
               algo = gcry_md_map_name (algoid);
               if (!algo)
                 {
-                  log_error ("unknown hash algorithm `%s'\n",
+                  log_error ("unknown hash algorithm '%s'\n",
                              algoid? algoid:"?");
                   if (algoid
                       && (  !strcmp (algoid, "1.2.840.113549.1.1.2")
@@ -307,7 +308,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
 
       if (DBG_X509)
         {
-          log_debug ("signer %d - issuer: `%s'\n",
+          log_debug ("signer %d - issuer: '%s'\n",
                      signer, issuer? issuer:"[NONE]");
           log_debug ("signer %d - serial: ", signer);
           gpgsm_dump_serial (serial);
@@ -594,7 +595,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
           log_info (!i? _("Good signature from")
                       : _("                aka"));
           log_printf (" \"");
-          gpgsm_print_name (log_get_stream (), p);
+          gpgsm_es_print_name (log_get_stream (), p);
           log_printf ("\"\n");
           ksba_free (p);
         }
@@ -623,6 +624,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
       }
 
       gpgsm_status (ctrl, STATUS_TRUST_FULLY,
+                    (verifyflags & VALIDATE_FLAG_STEED)?
+                    "0 steed":
                     (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
                     "0 chain": "0 shell");
 
@@ -644,8 +647,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
   gpgsm_destroy_writer (b64writer);
   keydb_release (kh);
   gcry_md_close (data_md);
-  if (fp)
-    fclose (fp);
+  es_fclose (in_fp);
 
   if (rc)
     {
@@ -657,4 +659,3 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
 
   return rc;
 }
-
index 75bbaac..972dbf5 100644 (file)
@@ -1,14 +1,20 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
+2011-09-20  Jim Meyering  <meyering@redhat.com>
+
+       avoid use of free'd pointer
+       * asschk.c (set_type_var): Set var->value to NULL after freeing it,
+       to avoid subsequent use of freed pointer.
+
 2009-10-13  Werner Koch  <wk@g10code.com>
 
        * asschk.c (die): Replace this vararg macro by C-89 compliant
-       macros die_0, die_1, die_2 and die_3.  Change all callers.
+       macros die_0, die_1, die_2 and die 3.  Change all callers.
        Reported by Nelson H. F. Beebe.
 
 2009-02-19  Werner Koch  <wk@g10code.com>
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 46c9af0..307d829 100644 (file)
@@ -30,7 +30,7 @@ SUBDIRS = ${openpgp} . pkits
 GPGSM = ../sm/gpgsm
 
 # Note that we need to use /bin/pwd so that we don't get into trouble
-# if the shell used for inittests would use an internal version of
+# if the shell used for inittests would uses an internal version of
 # pwd which handles symlinks differently.
 TESTS_ENVIRONMENT = GNUPGHOME=`/bin/pwd` GPG_AGENT_INFO= LC_ALL=C \
                     GPGSM=$(GPGSM) $(srcdir)/runtest
@@ -41,14 +41,16 @@ EXTRA_DIST = runtest inittests $(testscripts) ChangeLog-2011 \
             text-1.txt text-2.txt text-3.txt \
             text-1.osig.pem text-1.dsig.pem text-1.osig-bad.pem \
             text-2.osig.pem text-2.osig-bad.pem \
+            samplekeys/steed-self-signing-nonthority.pem \
+            samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key \
              samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key \
              samplekeys/cert_g10code_pete1.pem \
              samplekeys/cert_g10code_test1.pem \
              samplekeys/cert_g10code_theo1.pem
 
-# We used to run $(testscripts) here but these asschk scripts are not
+# We used to run $(testscripts) here but these asschk scripts ares not
 # completely reliable in all enviromnets and thus we better disable
-# them.  The tests are anyway way too minimal.  We will eventually
+# them.  The tests are anyway way to minimal.  We will eventually
 # write new tests based on gpg-connect-agent which has a full fledged
 # script language and thus makes it far easier to write tests than to
 # use the low--level asschk stuff.
@@ -72,4 +74,3 @@ clean-local:
 inittests.stamp: inittests
        srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests
        echo timestamp >./inittests.stamp
-
index ec338e7..a869841 100644 (file)
 
 /* This is a simple stand-alone Assuan server test program.  We don't
    want to use the assuan library because we don't want to hide errors
-   in that library. 
+   in that library.
 
    The script language is line based.  Empty lines or lines containing
    only white spaces are ignored, line with a hash sign as first non
    white space character are treated as comments.
-   
+
    A simple macro mechanism is implemnted.  Macros are expanded before
    a line is processed but after comment processing.  Macros are only
    expanded once and non existing macros expand to the empty string.
@@ -79,7 +79,7 @@
       is ignored.
 
    count-status <code>
-      Initialize the assigned variable to 0 and assign it as an counter for 
+      Initialize the assigned variable to 0 and assign it as an counter for
       status code CODE.  This command must be called with an assignment.
 
    quit
@@ -252,7 +252,7 @@ writen (int fd, const char *buffer, size_t length)
   while (length)
     {
       int nwritten = write (fd, buffer, length);
-      
+
       if (nwritten < 0)
         {
           if (errno == EINTR)
@@ -306,7 +306,7 @@ read_assuan (int fd)
             }
           while (n < 0 && errno == EINTR);
         }
-      
+
       if (opt_verbose && n >= 0 )
        {
          int i;
@@ -324,7 +324,7 @@ read_assuan (int fd)
       p = buf;
       nleft -= n;
       buf += n;
-      
+
       for (; n && *p != '\n'; n--, p++)
         ;
       if (n)
@@ -369,7 +369,7 @@ read_assuan (int fd)
       recv_type = LINE_END;
       p += 3;
     }
-  else 
+  else
     die_1 ("invalid line type (%.5s)", p);
 
   return p;
@@ -443,7 +443,7 @@ start_server (const char *pgmname)
         {
          int fd = open ("/dev/null", O_WRONLY);
          if (fd == -1)
-           die_1 ("can't open `/dev/null': %s", strerror (errno));
+           die_1 ("can't open '/dev/null': %s", strerror (errno));
           if (dup2 (fd, STDERR_FILENO) == -1)
             die_1 ("dup2 failed in child: %s", strerror (errno));
          close (fd);
@@ -451,8 +451,8 @@ start_server (const char *pgmname)
 
       close (wp[1]);
       close (rp[0]);
-      execl (pgmname, arg0, "--server", NULL); 
-      die_2 ("exec failed for `%s': %s", pgmname, strerror (errno));
+      execl (pgmname, arg0, "--server", NULL);
+      die_2 ("exec failed for '%s': %s", pgmname, strerror (errno));
     }
   close (wp[0]);
   close (rp[1]);
@@ -479,7 +479,7 @@ unset_var (const char *name)
     ;
   if (!var)
     return;
-/*    fprintf (stderr, "unsetting `%s'\n", name); */
+/*    fprintf (stderr, "unsetting '%s'\n", name); */
 
   if (var->type == VARTYPE_FD && var->value)
     {
@@ -503,7 +503,7 @@ set_type_var (const char *name, const char *value, VARTYPE type)
   VARIABLE var;
 
   if (!name)
-    name = "?"; 
+    name = "?";
   for (var=variable_list; var && strcmp (var->name, name); var = var->next)
     ;
   if (!var)
@@ -514,7 +514,10 @@ set_type_var (const char *name, const char *value, VARTYPE type)
       variable_list = var;
     }
   else
-    free (var->value);
+    {
+      free (var->value);
+      var->value = NULL;
+    }
 
   if (var->type == VARTYPE_FD && var->value)
     {
@@ -524,7 +527,7 @@ set_type_var (const char *name, const char *value, VARTYPE type)
       if (fd != -1 && fd != 0 && fd != 1 && fd != 2)
           close (fd);
     }
-  
+
   var->type = type;
   var->count = 0;
   if (var->type == VARTYPE_COUNTER)
@@ -598,7 +601,7 @@ expand_line (char *buffer)
       p = strchr (line, '$');
       if (!p)
         return result; /* nothing more to expand */
-      
+
       if (p[1] == '$') /* quoted */
         {
           memmove (p, p+1, strlen (p+1)+1);
@@ -650,7 +653,7 @@ expand_line (char *buffer)
 
 
 /* Evaluate COND and return the result. */
-static int 
+static int
 eval_boolean (const char *cond)
 {
   int true = 1;
@@ -686,8 +689,8 @@ cmd_send (const char *assign_to, char *arg)
 {
   (void)assign_to;
   if (opt_verbose)
-    fprintf (stderr, "sending `%s'\n", arg);
-  write_assuan (server_send_fd, arg); 
+    fprintf (stderr, "sending '%s'\n", arg);
+  write_assuan (server_send_fd, arg);
 }
 
 static void
@@ -720,13 +723,13 @@ cmd_expect_ok (const char *assign_to, char *arg)
     {
       char *p = read_assuan (server_recv_fd);
       if (opt_verbose > 1)
-        fprintf (stderr, "got line `%s'\n", recv_line);
+        fprintf (stderr, "got line '%s'\n", recv_line);
       if (recv_type == LINE_STAT)
         handle_status_line (p);
     }
   while (recv_type != LINE_OK && recv_type != LINE_ERR);
   if (recv_type != LINE_OK)
-    die_1 ("expected OK but got `%s'", recv_line);
+    die_1 ("expected OK but got '%s'", recv_line);
 }
 
 static void
@@ -741,13 +744,13 @@ cmd_expect_err (const char *assign_to, char *arg)
     {
       char *p = read_assuan (server_recv_fd);
       if (opt_verbose > 1)
-        fprintf (stderr, "got line `%s'\n", recv_line);
+        fprintf (stderr, "got line '%s'\n", recv_line);
       if (recv_type == LINE_STAT)
         handle_status_line (p);
     }
   while (recv_type != LINE_OK && recv_type != LINE_ERR);
   if (recv_type != LINE_ERR)
-    die_1 ("expected ERR but got `%s'", recv_line);
+    die_1 ("expected ERR but got '%s'", recv_line);
 }
 
 static void
@@ -776,12 +779,12 @@ cmd_openfile (const char *assign_to, char *arg)
   int fd;
   char numbuf[20];
 
-  do 
+  do
     fd = open (arg, O_RDONLY);
   while (fd == -1 && errno == EINTR);
   if (fd == -1)
-    die_2 ("error opening `%s': %s", arg, strerror (errno));
-  
+    die_2 ("error opening '%s': %s", arg, strerror (errno));
+
   sprintf (numbuf, "%d", fd);
   set_type_var (assign_to, numbuf, VARTYPE_FD);
 }
@@ -792,11 +795,11 @@ cmd_createfile (const char *assign_to, char *arg)
   int fd;
   char numbuf[20];
 
-  do 
+  do
     fd = open (arg, O_WRONLY|O_CREAT|O_TRUNC, 0666);
   while (fd == -1 && errno == EINTR);
   if (fd == -1)
-    die_2 ("error creating `%s': %s", arg, strerror (errno));
+    die_2 ("error creating '%s': %s", arg, strerror (errno));
 
   sprintf (numbuf, "%d", fd);
   set_type_var (assign_to, numbuf, VARTYPE_FD);
@@ -845,7 +848,7 @@ cmd_cmpfiles (const char *assign_to, char *arg)
   size_t nread1, nread2;
   int rc = 0;
 
-  set_var (assign_to, "0"); 
+  set_var (assign_to, "0");
   for (p=arg; *p && !spacep (p); p++)
     ;
   if (!*p)
@@ -862,17 +865,17 @@ cmd_cmpfiles (const char *assign_to, char *arg)
       if (*p)
         die_0 ("cmpfiles: syntax error");
     }
-  
+
   fp1 = fopen (arg, "rb");
   if (!fp1)
     {
-      err ("can't open `%s': %s", arg, strerror (errno));
+      err ("can't open '%s': %s", arg, strerror (errno));
       return;
     }
   fp2 = fopen (second, "rb");
   if (!fp2)
     {
-      err ("can't open `%s': %s", second, strerror (errno));
+      err ("can't open '%s': %s", second, strerror (errno));
       fclose (fp1);
       return;
     }
@@ -893,7 +896,7 @@ cmd_cmpfiles (const char *assign_to, char *arg)
     {
       if (opt_verbose)
         err ("files match");
-      set_var (assign_to, "1"); 
+      set_var (assign_to, "1");
     }
   else if (!rc)
     err ("cmpfiles: read error: %s", strerror (errno));
@@ -1006,7 +1009,7 @@ interpreter (char *line)
   if (!cmdtbl[i].name)
     {
       if (!assign_to)
-        die_1 ("invalid statement `%s'\n", stmt);
+        die_1 ("invalid statement '%s'\n", stmt);
       if (save_p)
         *save_p = save_c;
       set_var (assign_to, stmt);
@@ -1089,4 +1092,3 @@ main (int argc, char **argv)
     }
   return 0;
 }
-
index 790b92e..1a51bdf 100755 (executable)
@@ -73,7 +73,7 @@ for i in ${private_keys}; do
 done
 
 # Create the configuration scripts
-# Note, due to an expired test certificate, we need to use
+# Note, die to an expired test certificate, we need to use
 # the faked system time option.
 cat > gpgsm.conf <<EOF
 no-secmem-warning
index 75246dd..4013a08 100644 (file)
@@ -1,13 +1,45 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2010-05-12  Werner Koch  <wk@g10code.com>
+2011-02-10  Werner Koch  <wk@g10code.com>
+
+       * ecc.test: New.
+       * pinentry.sh: New.
+       * defs.inc: Do not create a log when running tests with envvar
+       verbose > 1.  Add pinentry-program to gpg-agent.conf.
+       * Makefile.am (sample_keys): New.
+       (EXTRA_DIST): Add them.
+
+2010-10-15  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (clean-local): New.
+
+2010-10-14  Werner Koch  <wk@g10code.com>
+
+       * genkey1024.test: Use the new no-protection option.
+
+       * decrypt-dsa.test: Do not specify an extra keyring.  The keyring
+       has been loaded into pubring.gpg.
+       * sigs-dsa.test: Ditto.
+       * encrypt-dsa.test: Ditto.
+       * signencrypt-dsa.test: Ditto.
+
+       * decrypt.test: Remove passphrase stuff.
+       * sigs.test: Ditto.
 
-       * armor.test: Add test for bug#1179.
+       * privkeys/: New.
+
+       * Makefile.am: Move most stuff to ...
+       * version.test: Prepare data files etc.
+       * finish.test: New.
+       * defs.inc: Set all envvars.
+       (usrname1, usrname2, username3): Use full mail address.
+
+2010-06-07  Werner Koch  <wk@g10code.com>
 
        * Makefile.am (TESTS_ENVIRONMENT): New.  Start all scripts under
        the control of the gpg-agent.
        (GNUPGHOME): Check that it is set properly.
        (GPG_AGENT_INFO): Do not change.
 
+2010-05-12  Werner Koch  <wk@g10code.com>
+
+       * armor.test (Version): Add test for bug#1179.
+
 2010-05-11  Werner Koch  <wk@g10code.com>
 
        * genkey1024.test: Use GPG macro.
        * gpg-agent.conf.tmpl: New.
        * defs.inc: Create gpg-agent.conf
        (GNUPGHOME): Set and export.
-       (GPG_AGENT_INFO): Unset
+       (GPG_AGENT_INFO): Unset.
        * Makefile.am (CLEANFILES): Add S.gpg-agent
 
+2010-05-07  Werner Koch  <wk@g10code.com>
+
+       * import.test: Add test case for bug#1223.
+       * bug1223-good.asc, bug1223-bogus.asc: New.
+
 2009-12-21  Werner Koch  <wk@g10code.com>
 
        * Makefile.am (required_pgms): New.
@@ -377,3 +418,7 @@ Mon May 18 15:40:02 1998  Werner Koch  (wk@isil.d.shuttle.de)
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index bd57e25..a6eda61 100644 (file)
@@ -1,4 +1,6 @@
-# Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+# Makefile.am - For tests/openpgp
+# Copyright (C) 1998, 1999, 2000, 2001, 2003,
+#               2010 Free Software Foundation, Inc.
 #
 # This file is part of GnuPG.
 #
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 # Process this file with automake to create Makefile.in
 
-GPG_IMPORT = ../../g10/gpg2 --homedir . \
-              --quiet --yes --no-permission-warning --import
 
 # Programs required before we can run these tests.
 required_pgms = ../../g10/gpg2 ../../agent/gpg-agent \
-                ../../tools/gpg-connect-agent
-
-
-TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO= LC_ALL=C \
-                   ../../agent/gpg-agent --quiet --daemon sh
+                ../../tools/gpg-connect-agent ../../tools/mk-tdata
 
+TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO= LC_ALL=C
 
+# Note: version.test needs to be the first test to run and finish.test
+# the last one
 TESTS = version.test mds.test \
        decrypt.test decrypt-dsa.test \
        sigs.test sigs-dsa.test \
@@ -39,86 +38,54 @@ TESTS = version.test mds.test \
        armdetachm.test detachm.test genkey1024.test \
        conventional.test conventional-mdc.test \
        multisig.test verify.test armor.test \
-       import.test
+       import.test ecc.test finish.test
 
 
 TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \
             plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \
             pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc \
              gpg.conf.tmpl gpg-agent.conf.tmpl \
-             bug537-test.data.asc bug894-test.asc
-
-DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large
-
-EXTRA_DIST = defs.inc $(TESTS) $(TEST_FILES) ChangeLog-2011 \
-            mkdemodirs signdemokey
-
-# Note that removing S.gpg-agent forces a running gpg-agent to
-# terminate after some time.
-CLEANFILES = prepared.stamp x y yy z out err  $(DATA_FILES) \
+            bug537-test.data.asc bug894-test.asc \
+            bug1223-good.asc bug1223-bogus.asc
+
+data_files = data-500 data-9000 data-32000 data-80000 plain-large
+
+priv_keys = privkeys/50B2D4FA4122C212611048BC5FC31BD44393626E.asc \
+            privkeys/7E201E28B6FEB2927B321F443205F4724EBE637E.asc \
+            privkeys/13FDB8809B17C5547779F9D205C45F47CE0217CE.asc \
+            privkeys/343D8AF79796EE107D645A2787A9D9252F924E6F.asc \
+            privkeys/8B5ABF3EF9EB8D96B91A0B8C2C4401C91C834C34.asc \
+            privkeys/0D6F6AD4C4C803B25470F9104E9F4E6A4CA64255.asc \
+            privkeys/FD692BD59D6640A84C8422573D469F84F3B98E53.asc \
+            privkeys/76F7E2B35832976B50A27A282D9B87E44577EB66.asc \
+            privkeys/A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD.asc \
+           privkeys/0DD40284FF992CD24DC4AAC367037E066FCEE26A.asc
+
+sample_keys = samplekeys/ecc-sample-1-pub.asc \
+              samplekeys/ecc-sample-2-pub.asc \
+              samplekeys/ecc-sample-3-pub.asc \
+              samplekeys/ecc-sample-1-sec.asc \
+              samplekeys/ecc-sample-2-sec.asc \
+              samplekeys/ecc-sample-3-sec.asc \
+             samplekeys/eddsa-sample-1-pub.asc \
+             samplekeys/eddsa-sample-1-sec.asc \
+             samplekeys/dda252ebb8ebe1af-1.asc \
+             samplekeys/dda252ebb8ebe1af-2.asc
+
+EXTRA_DIST = defs.inc pinentry.sh $(TESTS) $(TEST_FILES) ChangeLog-2011 \
+            mkdemodirs signdemokey $(priv_keys) $(sample_keys)
+
+CLEANFILES = prepared.stamp x y yy z out err  $(data_files) \
             plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \
             *.test.log gpg_dearmor gpg.conf gpg-agent.conf S.gpg-agent \
-            pubring.gpg secring.gpg pubring.pkr secring.skr
+            pubring.gpg pubring.gpg~ pubring.kbx pubring.kbx~ \
+            secring.gpg pubring.pkr secring.skr \
+            gnupg-test.stop random_seed gpg-agent.log
 
-DISTCLEANFILES = pubring.gpg~ random_seed
-
-
-all-local: prepared.stamp
-
-distclean-local:
-       $(srcdir)/mkdemodirs --clean
-
-prepared.stamp: ./pubring.gpg ./secring.gpg ./plain-1 ./plain-2 ./plain-3 \
-               ./pubring.pkr ./secring.skr ./gpg_dearmor $(DATA_FILES)
-        $(GPG_IMPORT) $(srcdir)/pubdemo.asc
-        cat $(srcdir)/gpg-agent.conf.tmpl > gpg-agent.conf
-        echo timestamp >./prepared.stamp
+clean-local:
+       -rm -rf private-keys-v1.d openpgp-revocs.d
 
 
 # We need to depend on a couple of programs so that the tests don't
 # start before all programs are built.
-./gpg_dearmor: $(required_pgms)
-       echo '#!/bin/sh' >./gpg_dearmor
-       echo "../../g10/gpg2 --homedir . --no-options --no-greeting \
-             --no-secmem-warning --batch --dearmor" >>./gpg_dearmor
-       chmod 755 ./gpg_dearmor
-
-./pubring.gpg: $(srcdir)/pubring.asc $(srcdir)/pubdemo.asc ./gpg_dearmor
-       ./gpg_dearmor > ./pubring.gpg < $(srcdir)/pubring.asc
-
-./secring.gpg: $(srcdir)/secring.asc ./gpg_dearmor
-       ./gpg_dearmor > ./secring.gpg < $(srcdir)/secring.asc
-
-./pubring.pkr: $(srcdir)/pubring.pkr.asc ./gpg_dearmor
-       ./gpg_dearmor > ./pubring.pkr < $(srcdir)/pubring.pkr.asc
-
-./secring.skr: $(srcdir)/secring.skr.asc ./gpg_dearmor
-       ./gpg_dearmor > ./secring.skr < $(srcdir)/secring.skr.asc
-
-./plain-1: $(srcdir)/plain-1o.asc ./gpg_dearmor
-       ./gpg_dearmor > ./plain-1 < $(srcdir)/plain-1o.asc
-
-./plain-2: $(srcdir)/plain-2o.asc ./gpg_dearmor
-       ./gpg_dearmor > ./plain-2 < $(srcdir)/plain-2o.asc
-
-./plain-3: $(srcdir)/plain-3o.asc ./gpg_dearmor
-       ./gpg_dearmor > ./plain-3 < $(srcdir)/plain-3o.asc
-
-
-data-500:
-       ../../tools/mk-tdata   500  >data-500
-data-9000:
-       ../../tools/mk-tdata  9000  >data-9000
-data-32000:
-       ../../tools/mk-tdata 32000  >data-32000
-data-80000:
-       ../../tools/mk-tdata 80000  >data-80000
-plain-large:
-       cat $(srcdir)/../../doc/HACKING \
-           $(srcdir)/../../doc/DETAILS \
-           $(srcdir)/../../doc/gpg.texi >plain-large
-
-# To speed up key generation we create a dummy random seed file
-random_seed:
-       ../../tools/mk-tdata 600
-
+all-local: $(required_pgms)
index df37294..ce1067e 100755 (executable)
@@ -12,7 +12,7 @@
 
 #info Checking armored encryption
 for i in $plain_files $data_files ; do
-    $GPG --always-trust -ea -o x --yes -r "$usrname2" $i
+    $GPG ${opt_always} -ea -o x --yes -r "$usrname2" $i
     $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
index 9246b6d..dfebb48 100755 (executable)
@@ -12,7 +12,7 @@
 
 #info Checking armored encryption with a pipe
 for i in $plain_files $data_files ; do
-    $GPG --always-trust -ea --yes -r "$usrname2" < $i | tee x | $GPG -o y --yes
+    $GPG ${opt_always} -ea --yes -r "$usrname2" < $i | tee x | $GPG -o y --yes
     cmp $i y || error "$i: mismatch"
     $GPG --yes < x > y
     cmp $i y || error "$i: mismatch"
index cb3c892..ce5939c 100755 (executable)
@@ -755,10 +755,9 @@ $GPG --import x || true
 i=nopad_armored_msg
 info "checking: $i"
 eval "(IFS=; echo \"\$$i\")" >x
-if echo "abc" | $GPG  --passphrase-fd 0 -o - x > /dev/null ; then
+if $GPG -o - x > /dev/null ; then
    :
 else
    error "bug#1179 is back in town"
 fi
 
-
index 5b392df..c50a12d 100755 (executable)
@@ -13,7 +13,7 @@
 
 #info Checking armored signing and encryption
 for i in $plain_files $data_files ; do
-    echo "$usrpass1"  | $GPG --passphrase-fd 0 --always-trust \
+    echo "$usrpass1"  | $GPG --passphrase-fd 0 ${opt_always} \
                         -sae -o x --yes -r "$usrname2" $i
     $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
diff --git a/tests/openpgp/bug1223-bogus.asc b/tests/openpgp/bug1223-bogus.asc
new file mode 100644 (file)
index 0000000..469e6b9
--- /dev/null
@@ -0,0 +1,21 @@
+Bogus test key for bug 1223 (Designated revoker sigs are not properly merged)
+Thanks to Daniel Kahn Gillmor for providing the test keys.
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.10 (GNU/Linux)
+
+mI0ES+OoSQEEAJUZ/+fC6DXN2X7Wxl4Huud/+i2qP1hcq+Qnbr7hVCKEnn0edYl+
+6xfsKmAMBjl+qTZxPSDSx4r3ciMiIbnvXFtlBAQmji86kqoR6fm9s8BN7LTq7+2/
+c2FHVF67D7zES7WgHc4i7CfiZnwXgkLvi5b1jBt+MTAOrFhdobxoy6/XABEBAAGI
+twQfAQIAIQUCS+OsRRcMgAEAAAAAAAAAAAAAAAAAAAAAAAAAAQIHAAAKCRA0t9EL
+wQjoOrRXBACBqhigTcj8pJY14AkjV+ZzUbm55kJRDPdU7NQ1PSvczm7HZaL3b8Lr
+Psa5c5+caVLjsGWkQycQl7lUIGU84KoUfwACQKVVLkqJz8LkL54lLcwkG70+1NH5
+xoSNcHHVbYtqDLNeCOq5jEIoXuz44wiWVEfF+/B115PvgwZ63pjH1rRGVGVzdCBL
+ZXkgRGVtb25zdHJhdGluZyBSZXZva2VyIFRyb3VibGUgKERPIE5PVCBVU0UpIDx0
+ZXN0QGV4YW1wbGUubmV0Poi+BBMBAgAoBQJL46hJAhsDBQkACTqABgsJCAcDAgYV
+CAIJCgsEFgIDAQIeAQIXgAAKCRA0t9ELwQjoOgLpA/9/si2QYmietY9a6VlAmMri
+mhZeqo6zyn8zrO9RGU7+8jmeb5nVnXw1YmZcw2fiJgI9+tTMkTfomyR6k0EDvcEu
+2Mg3USkVnJfrrkPjSL9EajW6VpOUNxlox3ZT1oyEo3OOnVF1gC1reWYfy7Ns9zIB
+1leLXbMr86zYdCoXp0Xu4g==
+=YV5g
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/bug1223-good.asc b/tests/openpgp/bug1223-good.asc
new file mode 100644 (file)
index 0000000..5622cb3
--- /dev/null
@@ -0,0 +1,20 @@
+Good test key for bug 1223 (Designated revoker sigs are not properly merged)
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.10 (GNU/Linux)
+
+mI0ES+OoSQEEAJUZ/+fC6DXN2X7Wxl4Huud/+i2qP1hcq+Qnbr7hVCKEnn0edYl+
+6xfsKmAMBjl+qTZxPSDSx4r3ciMiIbnvXFtlBAQmji86kqoR6fm9s8BN7LTq7+2/
+c2FHVF67D7zES7WgHc4i7CfiZnwXgkLvi5b1jBt+MTAOrFhdobxoy6/XABEBAAGI
+twQfAQIAIQUCS+OsRRcMgAEO5b6XkoLYC591QPHM0u2U0hc56QIHAAAKCRA0t9EL
+wQjoOrRXBACBqhigTcj8pJY14AkjV+ZzUbm55kJRDPdU7NQ1PSvczm7HZaL3b8Lr
+Psa5c5+caVLjsGWkQycQl7lUIGU84KoUfwACQKVVLkqJz8LkL54lLcwkG70+1NH5
+xoSNcHHVbYtqDLNeCOq5jEIoXuz44wiWVEfF+/B115PvgwZ63pjH1rRGVGVzdCBL
+ZXkgRGVtb25zdHJhdGluZyBSZXZva2VyIFRyb3VibGUgKERPIE5PVCBVU0UpIDx0
+ZXN0QGV4YW1wbGUubmV0Poi+BBMBAgAoBQJL46hJAhsDBQkACTqABgsJCAcDAgYV
+CAIJCgsEFgIDAQIeAQIXgAAKCRA0t9ELwQjoOgLpA/9/si2QYmietY9a6VlAmMri
+mhZeqo6zyn8zrO9RGU7+8jmeb5nVnXw1YmZcw2fiJgI9+tTMkTfomyR6k0EDvcEu
+2Mg3USkVnJfrrkPjSL9EajW6VpOUNxlox3ZT1oyEo3OOnVF1gC1reWYfy7Ns9zIB
+1leLXbMr86zYdCoXp0Xu4g==
+=xsEd
+-----END PGP PUBLIC KEY BLOCK-----
index 74631e1..bf67916 100755 (executable)
@@ -24,17 +24,6 @@ done
 
 
 # ======================================
-# and once more to check rfc1991
-# ======================================
-
-if have_pubkey_algo "RSA"; then
-  for i in $plain_files plain-large ; do
-      $GPG -u $usrname3 --rfc1991 --digest-algo md5 --clearsign -o x --yes $i
-      $GPG --verify x
-  done
-fi
-
-# ======================================
 # and one with long lines
 # ======================================
 cat >y <<EOF
@@ -100,7 +89,7 @@ cat >y <<EOF
            }
            /* ask for file and hash it */
 -          if( c->sigs_only ) {
-+          if( c->sigs_only )   
++          if( c->sigs_only )
                rc = hash_datafiles( c->mfx.md, NULL,
                                     c->signed_data, c->sigfilename,
                        n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
index 15b525f..744e11e 100755 (executable)
 
 . $srcdir/defs.inc || exit 3
 
+# We use use a lower than default value for the S2K count to run the
+# tests faster.  We used a fixed value of 65536 already the past.
+s2k="--s2k-count=65536"
+
 #info Checking conventional encryption
 for ciph in `all_cipher_algos`; do
   progress "$ciph"
@@ -20,9 +24,9 @@ for ciph in `all_cipher_algos`; do
     else
         dd if=data-80000 of=z bs=1 count=$i 2>/dev/null
     fi
-    echo "Hier spricht HAL" | $GPG --passphrase-fd 0 \
+    echo "Hier spricht HAL" | $GPG --passphrase-fd 0 $s2k \
        --force-mdc --cipher $ciph -c -o x --yes z
-    echo "Hier spricht HAL" | $GPG --passphrase-fd 0 \
+    echo "Hier spricht HAL" | $GPG --passphrase-fd 0 $s2k \
        -o y --yes x
     cmp z y || error "$ciph/$i: mismatch"
   done
index 5028b29..30c9ba0 100755 (executable)
 
 . $srcdir/defs.inc || exit 3
 
+# We use use a lower than default value for the S2K count to run the
+# tests faster.  We used a fixed value of 65536 already the past.
+s2k="--s2k-count=65536"
+
 #info Checking conventional encryption
 for i in plain-2 data-32000 ; do
-    echo "Hier spricht HAL" | $GPG --passphrase-fd 0 -c -o x --yes $i
-    echo "Hier spricht HAL" | $GPG --passphrase-fd 0    -o y --yes x
+    echo "Hier spricht HAL" | $GPG --passphrase-fd 0 $s2k -c -o x --yes $i
+    echo "Hier spricht HAL" | $GPG --passphrase-fd 0 $s2k    -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
 
 for a in `all_cipher_algos`; do
     progress "$a"
     for i in plain-1 data-80000 ; do
-      echo "Hier spricht HAL" | $GPG --passphrase-fd 0 \
+      echo "Hier spricht HAL" | $GPG --passphrase-fd 0 $s2k \
                                          --cipher-algo $a -c -o x --yes $i
-      echo "Hier spricht HAL" | $GPG --passphrase-fd 0 -o y --yes x
+      echo "Hier spricht HAL" | $GPG --passphrase-fd 0 $s2k -o y --yes x
       cmp $i y || error "$i: ($a) mismatch"
     done
 done
index 7220f8a..ba83fea 100755 (executable)
@@ -12,7 +12,7 @@
 
 #info Checking decryption of supplied DSA encrypted file
 for i in "plain-1" ; do
-    $GPG $dsa_keyrings -o y --yes $srcdir/$i-pgp.asc
+    $GPG -o y --yes $srcdir/$i-pgp.asc
     cmp $i y || error "$i: mismatch"
 done
 
index d3b5ddf..370dc96 100755 (executable)
@@ -12,7 +12,7 @@
 
 #info Checking decryption of supplied files
 for i in $plain_files ; do
-    echo "$usrpass1" | $GPG  --passphrase-fd 0 -o y --yes $srcdir/$i.asc
+    $GPG -o y --yes $srcdir/$i.asc
     cmp $i y || error "$i: mismatch"
 done
 
index 5d5e03d..941f786 100755 (executable)
 #------ constants ---------------
 #--------------------------------
 
-# Note that usrpass1 is also used in Makefile.am
-usrname1="one"
+usrname1="one@example.com"
 usrpass1="def"
-usrname2="two"
+usrname2="two@example.com"
 usrpass2=""
-usrname3="three"
+usrname3="three@example.com"
 usrpass3=""
 
 
 dsa_usrname1="pgp5"
-# we use the sub key because we do not yet have the logic to
-# to derive the first encryption key from a keyblock (I guess)
+# we use the sub key because we do not yet have the logic to to derive
+# the first encryption key from a keyblock (I guess) (Well of course
+# we have this by now and the notation below will lookup the primary
+# first and then search for the encryption subkey.)
 dsa_usrname2="0xCB879DE9"
 
-dsa_keyrings="--keyring ./pubring.pkr --secret-keyring ./secring.skr"
-
 
 plain_files="plain-1 plain-2 plain-3"
 data_files="data-500 data-9000 data-32000 data-80000"
@@ -59,6 +58,7 @@ fatal () {
     progress_cancel
     echo "$pgmname: fatal:" $* >&2
     echo "$pgmname: fatal:" $* >&5
+    echo stop >gnupg-test.stop
     exit 1;
 }
 
@@ -148,7 +148,7 @@ progress () {
 #}
 
 have_pubkey_algo () {
-  if  ../../g10/gpg2 --homedir .  --version | grep "Pubkey:.*$1" >/dev/null
+  if  $GPG --version | grep "Pubkey:.*$1" >/dev/null
   then
        true
   else
@@ -157,7 +157,7 @@ have_pubkey_algo () {
 }
 
 have_cipher_algo () {
-  if  ../../g10/gpg2 --homedir .  --version | grep "Cipher:.*$1" >/dev/null
+  if $GPG --version | grep "Cipher:.*$1" >/dev/null
   then
        true
   else
@@ -166,7 +166,7 @@ have_cipher_algo () {
 }
 
 have_hash_algo () {
-  if  ../../g10/gpg2 --homedir .  --version | grep "Hash:.*$1" >/dev/null
+  if $GPG --version | grep "Hash:.*$1" >/dev/null
   then
        true
   else
@@ -175,11 +175,13 @@ have_hash_algo () {
 }
 
 all_cipher_algos () {
-  ../../g10/gpg2 --homedir . --with-colons --list-config ciphername | sed 's/^cfg:ciphername://; s/;/ /g'
+  $GPG --with-colons --list-config ciphername \
+       | sed 's/^cfg:ciphername://; s/;/ /g'
 }
 
 all_hash_algos () {
-  ../../g10/gpg2 --homedir . --with-colons --list-config digestname | sed 's/^cfg:digestname://; s/;/ /g'
+  $GPG --with-colons --list-config digestname \
+       | sed 's/^cfg:digestname://; s/;/ /g'
 }
 
 set -e
@@ -188,33 +190,76 @@ pgmname=`basename $0`
 
 [ -z "$srcdir" ] && fatal "not called from make"
 
-# Make sure we have a valid option file even with VPATH builds.
-for f in gpg.conf ; do
-  if [ -f ./$f ]; then
-    :
-  elif [ -f $srcdir/$f.tmpl ]; then
-    cat $srcdir/$f.tmpl >$f
-  fi
-done
+#
+if [ -f gnupg-test.stop ]; then
+    if [ $pgmname = "version.test" ]; then
+        rm gnupg-test.stop
+    else
+        # Skip the rest of the tests.
+        exit 77
+    fi
+fi
 
 # Always work in the current directory.  We set GNUPGHOME only if it
 # has not been set already.  Usually it is set through the Makefile's
 # TESTS_ENVIRONMENT macro.
 if [ -z "$GNUPGHOME" ]; then
-  GNUPGHOME=`pwd`
+  GNUPGHOME=`/bin/pwd`
   export GNUPGHOME
-elif [ "$GNUPGHOME" != `pwd` ]; then
+elif [ "$GNUPGHOME" != `/bin/pwd` ]; then
   echo "$pgmname: GNUPGHOME not set to the cwd" $* >&2
   exit 1
 fi
 
+# We don't use GPG_AGENT_INFO anymore - better reset it.
+unset GPG_AGENT_INFO
 
+# (--no-permission-warning makes only sense on the commandline)
 GPG="../../g10/gpg2 --no-permission-warning "
+# (We may not use a relative name for gpg-agent.)
+GPG_AGENT="$(cd ../../agent && /bin/pwd)/gpg-agent"
+GPG_CONNECT_AGENT="../../tools/gpg-connect-agent"
+GPGCONF="../../tools/gpgconf"
+GPG_PRESET_PASSPHRASE="../../agent/gpg-preset-passphrase"
+MKTDATA="../../tools/mk-tdata"
+PINENTRY="$(cd $srcdir && /bin/pwd)/pinentry.sh"
+# Default to empty passphrase for pinentry.sh
+PINENTRY_USER_DATA=
+
+# If --check-trustdb is not an option, GPG has been build without
+# trust model support.  Thus we can't use --always-trust and some
+# other options.
+if $GPG --dump-options | grep '^--check-trustdb$' >/dev/null ; then
+  opt_always="--always-trust"
+else
+  opt_always=
+fi
 
-echo "Test: $pgmname"                  >  ${pgmname}.log
-echo "GNUPGHOME=$GNUPGHOME"            >> ${pgmname}.log
-echo "GPG_AGENT_INFO=$GPG_AGENT_INFO"  >> ${pgmname}.log
-exec 5>&2 2>>${pgmname}.log
+# Make sure we have a valid option files even with VPATH builds.
+for f in gpg.conf gpg-agent.conf ; do
+  if [ -f ./$f ]; then
+    :
+  elif [ -f $srcdir/$f.tmpl ]; then
+    cat $srcdir/$f.tmpl >$f
+    case "$f" in
+      gpg.conf)
+        [ -n "${opt_always}" ] && echo "no-auto-check-trustdb" >>"$f"
+        echo "agent-program ${GPG_AGENT}|--debug-quick-random" >>"$f"
+        echo "allow-weak-digest-algos" >>"$f"
+        ;;
+      gpg-agent.conf)
+        echo "pinentry-program $PINENTRY" >>"$f"
+        ;;
+    esac
+  fi
+done
 
+if [ "${verbose:-0}" -gt "1" ]; then
+  exec 5>/dev/null
+else
+  echo "Test: $pgmname"                  >  ${pgmname}.log
+  echo "GNUPGHOME=$GNUPGHOME"            >> ${pgmname}.log
+  exec 5>&2 2>>${pgmname}.log
+fi
 :
 # end
diff --git a/tests/openpgp/ecc.test b/tests/openpgp/ecc.test
new file mode 100755 (executable)
index 0000000..58fd251
--- /dev/null
@@ -0,0 +1,253 @@
+#!/bin/sh
+# Copyright 2011 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.
+
+. $srcdir/defs.inc || exit 3
+
+keygrips='8E06A180EFFE4C65B812150CAF19BF30C0689A4C
+          E4403F3FD7A443FAC29FEF288FA0D20AC212851E
+          0B7554421FFB14A06CB9F63FB49A85A58E97ABAC
+          303ACC892C2D786C8A789677C0BE54DA8538F903
+          9FE5C36985351524B6AFA19FDCBC1A3A750B6F5F
+          145A52CC7ED3FD41C5B0A26BE220FEED36AF24DE'
+mainkeyids='BAA59D9C
+            0F54719F
+            45AF2FFE'
+
+
+if have_pubkey_algo "ECDH"; then
+  :
+else
+  info "No ECC support due to an old Libgcrypt"
+  exit 77
+fi
+
+
+#
+# Setup for ECC testing
+#
+info "Preparing for ECC test."
+for i in $keygrips ; do
+  rm private-keys-v1.d/$i.key 2>/dev/null || true
+  $GPG_PRESET_PASSPHRASE --preset -P ecc $i
+done
+
+
+#
+# Import the sample keys
+#
+info "Importing ECC public keys."
+for k in $mainkeyids ; do
+  $GPG --delete-key --batch --yes $k 2>/dev/null || true
+done
+for i in 1 2 3; do
+  k="ecc-sample-$i-pub.asc"
+  if $GPG --import $srcdir/samplekeys/$k; then
+    :
+  else
+    error "$k: import failed"
+  fi
+done
+
+
+#
+# Check a few sample signature
+#
+info "Checking ECC signatures."
+tests=""
+
+# The following is an opaque ECDSA signature on a message "This is one
+# line\n" (17 byte long) by the primary 256 bit key:
+tests="$tests msg_opaque_signed_256"
+msg_opaque_signed_256='-----BEGIN PGP MESSAGE-----
+Version: GnuPG v2.1.0-ecc (GNU/Linux)
+
+owGbwMvMwCHMvVT3w66lc+cwrlFK4k5N1k3KT6nUK6ko8Zl8MSEkI7NYAYjy81IV
+cjLzUrk64lgYhDkY2FiZQNIMXJwCMO31rxgZ+tW/zesUPxWzdKWrtLGW/LkP5rXL
+V/Yvnr/EKjBbQuvZSYa/klsum6XFmTze+maVgclT6Rc6hzqqxNy6o6qdTTmLJuvp
+AQA=
+=GDv4
+-----END PGP MESSAGE----'
+
+# The following is an opaque ECDSA signature on a message "This is one
+# line\n" (17 byte long) by the primary 384 bit key:
+tests="$tests msg_opaque_signed_384"
+msg_opaque_signed_384='-----BEGIN PGP MESSAGE-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+qANQR1DIqwE7wsvMwCnM2WDcwR9SOJ/xtFISd25qcXFieqpeSUUJAxCEZGQWKwBR
+fl6qQk5mXirXoXJmVgbfYC5xmC5hzsDPjHXqbDLzpXpTBXSZV3L6bAgP3Kq7Ykmo
+7Ds1v4UfBS+3CSSon7Pzq79WLjzXXEH54MkjPxnrw+8cfMVnY7Bi18J702Nnsa7a
+9lMv/PM0/ao9CZ3KX7Q+Tv1rllTZ5Hj4V1frw431QnHfAA==
+=elKT
+-----END PGP MESSAGE-----'
+
+# The following is an opaque ECDSA signature on a message "This is one
+# line\n" (17 byte long) by the primary 521 bit key:
+tests="$tests msg_opaque_signed_521"
+msg_opaque_signed_521='-----BEGIN PGP MESSAGE-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+qANQR1DIwA8BO8LLzMAlnO3Y8tB1vf4/xtNKSdy5qcXFiempeiUVJQxAEJKRWawA
+RPl5qQo5mXmpXIdmMLMy+AaLnoLpEubatpeJY2Lystd7Qt32q2UcvRS5kNPWtDB7
+ryufvcrWtFM7Jx8qXKDxZuqr7b9PGv1Ssk+I8TzB2O9dZC+n/jv+PAdbuu7mLe33
+Gf9pLd3weV3Qno6FOqxGa5ZszQx+uer2xH3/El9x/2pVeO4l15ScsL7qWMTmffmG
+Ic1RdzgeCfosMF+l/zVRchcLKzenEQA=
+=ATtX
+-----END PGP MESSAGE-----'
+
+echo 'This is one line' >z
+for msg in $tests; do
+   info "checking: $msg"
+   eval "(IFS=; echo \"\$$msg\")" >x
+   $GPG --verify x || error "verify(1) of $msg failed"
+   $GPG -o y --yes x || error "verify(2) of $msg failed"
+   cmp y z || error "$msg: mismatch"
+done
+
+
+#
+# Import the secret keys so that we now can sign and decrypt.
+#
+# Note that the PGP generated secret keys are not self-signed, thus we
+# need to pass an appropriate option.
+#
+info "Importing ECC secret keys."
+for i in 1 2 3; do
+  k="ecc-sample-$i-sec.asc"
+  if [ "$i" -gt "1" ]; then
+    extraopts="--allow-non-selfsigned-uid"
+  else
+    extraopts=""
+  fi
+  if PINENTRY_USER_DATA=ecc $GPG $extraopts --import $srcdir/samplekeys/$k; then
+    :
+  else
+    error "$k: import failed"
+  fi
+done
+
+
+#
+# Check a few sample encrtpted messages.
+#
+info "Checking ECC encryption."
+tests=""
+
+# The following block encrypts the text "This is one line\n", 17 bytes,
+# with the subkey 4089AB73.
+tests="$tests msg_encrypted_256"
+msg_encrypted_256='-----BEGIN PGP MESSAGE-----
+Version: GnuPG v2.1.0-ecc (GNU/Linux)
+
+hH4Dd863o0CJq3MSAgMEHdIYZQx+rV1cjy7qitIOEICFFzp4cjsRX4r+rDdMcQUs
+h7VZmbP1c9C0s9sgCKwubWfkcYUl2ZOju4gy+s4MYTBb4/j8JjnJ9Bqn6LWutTXJ
+zwsdP13VIJLnhiNqISdR3/6xWQ0ICRYzwb95nUZ1c1DSVgFpjPgUvi4pgYbTpcDB
+jzILKWBfBDT/jck169XE8vgtbcqVQYZ7lZpaY9CzEbC+4dXZmV1gm5MafpTyFWgH
+VnyrZB4gad9Lp9e0RKHHcOOE7s/NeLuu
+=odUZ
+-----END PGP MESSAGE-----'
+
+# The following block encrypts the text "This is one line\n", 17 bytes,
+# with the subkey 9A201946:
+tests="$tests msg_encrypted_384"
+msg_encrypted_384='-----BEGIN PGP MESSAGE-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+qANQR1DBngOqi5OPmiAZRhIDAwQqIr/00cJyf+QP+VA4QKVkk77KMHdz9OVaR2XK
+0VYu0F/HPm89vL2orfm2hrAZxY9G2R0PG4Wk5Lg04UjKca/O72uWtjdPYulFidmo
+uB0QpzXFz22ZZinxeVPLPEr19Pow0EwCc95cg4HAgrD0nV9vRcTJ/+juVfvsJhAO
+isMKqrFNMvwnK5A1ECeyVXe7oLZl0lUBRhLr59QTtvf85QJjg/m5kaGy8XCJvLv3
+61pZa6KUmw89PjtPak7ebcjnINL01vwmyeg1PAyW/xjeGGvcO+R4P1b4ewyFnJyR
+svzIJcP7d4DqYOw7
+=oiTJ
+-----END PGP MESSAGE-----'
+
+# The following block encrypts the text "This is one line\n", 17 bytes,
+# with the subkey A81C4838:
+tests="$tests msg_encrypted_521"
+msg_encrypted_521='-----BEGIN PGP MESSAGE-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+qANQR1DBwAIDB+qqSKgcSDgSBCMEAKpzTUxB4c56C7g09ekD9I+ttC5ER/xzDmXU
+OJmFqU5w3FllhFj4TgGxxdH+8fv4W2Ag0IKoJvIY9V1V7oUCClfqAR01QbN7jGH/
+I9GFFnH19AYEgMKgFmh14ZwN1BS6/VHh+H4apaYqapbx8/09EL+DV9zWLX4GRLXQ
+VqCR1N2rXE29MJFzGmDOCueQNkUjcbuenoCSKcNT+6xhO27U9IYVCg4BhRUDGfD6
+dhfRzBLxL+bKR9JVAe46+K8NLjRVu/bd4Iounx4UF5dBk8ERy+/8k9XantDoQgo6
+RPqCad4Dg/QqkpbK3y574ds3VFNJmc4dVpsXm7lGV5w0FBxhVNPoWNhhECMlTroX
+Rg==
+=5GqW
+-----END PGP MESSAGE-----'
+
+echo 'This is one line' >z
+for msg in $tests; do
+   info "checking: $msg"
+   eval "(IFS=; echo \"\$$msg\")" >x
+   PINENTRY_USER_DATA=ecc $GPG -o y --yes x || error "decryption of $msg failed"
+   cmp y z || error "$msg: mismatch"
+done
+
+
+#
+# Now check that we can encrypt and decrypt our own messages.
+#
+# Note that we don't need to provide a passppharse because we already
+# preset the passphrase into the gpg-agent.
+#
+info "Checking ECC encryption and decryption."
+for i in $plain_files $data_files ; do
+  for k in $mainkeyids ; do
+    info "file: $i key: $k"
+    $GPG ${opt_always} -e -o x --yes -r $k $i
+    PINENTRY_USER_DATA=ecc $GPG -o y --yes x
+    cmp $i y || error "$i,$k: mismatch"
+  done
+done
+
+
+#
+# Now check that we can sign and verify our own messages.
+#
+info "Checking ECC signing and verifiction."
+for i in $plain_files $data_files ; do
+  for k in $mainkeyids ; do
+    info "file: $i key: $k"
+    PINENTRY_USER_DATA=ecc $GPG -s -o x --yes -u $k $i
+    $GPG -o y --yes x || error "verify of $i,$k failed"
+    cmp $i y || error "$i,$k: mismatch"
+  done
+done
+
+
+#
+# Let us also try to import the keys only from a secret keyblock.
+#
+# Because PGP does not sign the UID, it is not very useful to work
+# with this key unless we go into the trouble of adding the
+# self-signature.
+#
+info "Importing ECC secret keys directly."
+for i in $keygrips ; do
+  rm private-keys-v1.d/$i.key 2>/dev/null || true
+done
+for k in $mainkeyids ; do
+  $GPG --delete-key --batch --yes $k 2>/dev/null || true
+done
+for i in 1 2 3; do
+  k="ecc-sample-$i-sec.asc"
+  if [ "$i" -gt "1" ]; then
+    extraopts="--allow-non-selfsigned-uid"
+  else
+    extraopts=""
+  fi
+  if PINENTRY_USER_DATA=ecc $GPG $extraopts --import $srcdir/samplekeys/$k; then
+    :
+  else
+    error "$k: import failed"
+  fi
+done
index 320fbd8..7ce670e 100755 (executable)
 
 #info Checking encryption
 for i in $plain_files $data_files ; do
-    $GPG $dsa_keyrings --always-trust -e -o x --yes -r "$dsa_usrname2" $i
-    $GPG $dsa_keyrings -o y --yes x
+    $GPG ${opt_always} -e -o x --yes -r "$dsa_usrname2" $i
+    $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
 
 for ca in `all_cipher_algos` ; do
     progress "$ca"
     for i in $plain_files $data_files ; do
-       $GPG $dsa_keyrings --always-trust --cipher-algo $ca -e \
+       $GPG ${opt_always} --cipher-algo $ca -e \
            -o x --yes -r "$dsa_usrname2" $i
-       $GPG $dsa_keyrings -o y --yes x
+       $GPG -o y --yes x
        cmp $i y || error "$i: mismatch"
     done
 done
index 5ef5196..295a6c3 100755 (executable)
@@ -12,7 +12,7 @@
 
 #info Checking encryption
 for i in $plain_files $data_files ; do
-    $GPG --always-trust -e -o x --yes -r "$usrname2" $i
+    $GPG ${opt_always} -e -o x --yes -r "$usrname2" $i
     $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
@@ -21,7 +21,7 @@ echo_n "    > "
 for ca in `all_cipher_algos` ; do
     echo_n "$ca "
     for i in $plain_files $data_files ; do
-       $GPG --always-trust -e -o x --yes -r "$usrname2" --cipher-algo $ca $i
+       $GPG ${opt_always} -e -o x --yes -r "$usrname2" --cipher-algo $ca $i
        $GPG -o y --yes x
        cmp $i y || error "$i: mismatch"
     done
index 984f56a..3ad7119 100755 (executable)
@@ -12,7 +12,7 @@
 
 #info Checking encryption with a pipe
 for i in $plain_files $data_files ; do
-    $GPG --always-trust -e --yes -r "$usrname2" <$i | $GPG --yes > y
+    $GPG ${opt_always} -e --yes -r "$usrname2" <$i | $GPG --yes > y
     cmp $i y || error "$i: mismatch"
 done
 
diff --git a/tests/openpgp/finish.test b/tests/openpgp/finish.test
new file mode 100755 (executable)
index 0000000..fced570
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/sh
+# Copyright 2010 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.
+
+. $srcdir/defs.inc || exit 3
+
+if $GPG_AGENT --quiet; then
+  $GPG_CONNECT_AGENT killagent /bye >/dev/null
+fi
+
+exit 0
+
index 835b4c8..99a0d5d 100755 (executable)
@@ -10,7 +10,7 @@
 
 . $srcdir/defs.inc || exit 3
 
-$GPG --quiet --batch --debug-quick-random --gen-key <<EOF
+$GPG --quiet --batch --gen-key <<EOF
 Key-Type: DSA
 Key-Length: 1024
 Subkey-Type: ELG
@@ -19,12 +19,13 @@ Name-Real: Harry H.
 Name-Comment: test key 
 Name-Email: hh@@ddorf.de
 Expire-Date: 1
-Passphrase: abc
+%no-protection
+%transient-key
 %commit
 EOF
 
 if have_pubkey_algo "RSA"; then
-$GPG --quiet --batch --debug-quick-random --gen-key <<EOF
+$GPG --quiet --batch --gen-key <<EOF
 Key-Type: RSA
 Key-Length: 1024
 Key-Usage: sign,encrypt
@@ -32,7 +33,8 @@ Name-Real: Harry A.
 Name-Comment: RSA test key 
 Name-Email: hh@@ddorf.de
 Expire-Date: 2
-Passphrase: abc
+%no-protection
+%transient-key
 %commit
 EOF
 fi
index 18e1520..d9e014a 100644 (file)
@@ -1,2 +1,5 @@
-no-use-standard-socket
+use-standard-socket
+allow-preset-passphrase
+no-grab
+
 
index 7db73be..19f3180 100644 (file)
@@ -2,5 +2,3 @@ no-greeting
 no-secmem-warning
 no-permission-warning
 batch
-no-auto-check-trustdb
-allow-weak-digest-algos
index 6117046..783d059 100755 (executable)
@@ -18,9 +18,31 @@ else
 fi
 
 
+boguskey=$srcdir/bug1223-bogus.asc
+goodkey=$srcdir/bug1223-good.asc
+keyid=0xC108E83A
+info "Checking bug 1223: designated revoker sigs are not properly merged."
+$GPG --delete-key --batch --yes $keyid 2>/dev/null || true
+$GPG --import $boguskey || true
+$GPG --import $goodkey || true
+if $GPG --list-keys --with-colons $keyid \
+    | grep '^rvk:.*:0EE5BE979282D80B9F7540F1CCD2ED94D21739E9:' >/dev/null; then
+  :
+else
+  error "$goodkey: import failed (bug 1223)"
+fi
 
 
-
-
-
-
+key1=$srcdir/samplekeys/dda252ebb8ebe1af-1.asc
+key2=$srcdir/samplekeys/dda252ebb8ebe1af-2.asc
+fpr1=9E669861368BCA0BE42DAF7DDDA252EBB8EBE1AF
+fpr2=A55120427374F3F7AA5F1166DDA252EBB8EBE1AF
+info "Checking import of two keys with colliding long key ids."
+$GPG --delete-key --batch --yes $fpr1 $fpr2 2>/dev/null || true
+$GPG --import $key1 || true
+$GPG --import $key2 || true
+n=$($GPG --list-keys --with-colons $fpr1 $fpr2 2>/dev/null \
+    | grep '^pub:.:4096:1:DDA252EBB8EBE1AF:' | wc -l)
+if [ $n -ne 2 ] ; then
+  error "Importing keys with long id collision failed"
+fi
index a4583a1..944f535 100755 (executable)
@@ -23,11 +23,19 @@ failed=""
 #info Checking message digests
 cat /dev/null | $GPG --with-colons --print-mds >y
 # MD5
-test_one ":1:"    "D41D8CD98F00B204E9800998ECF8427E"
+if have_hash_algo "MD5"; then
+  test_one ":1:"    "D41D8CD98F00B204E9800998ECF8427E"
+else
+  echo "Hash algorithm MD5 is not installed (not an error)"
+fi
 # SHA-1
 test_one ":2:"    "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"
 # RMD160
-test_one ":3:"    "9C1185A5C5E9FC54612808977EE8F548B2258D31"
+if have_hash_algo "RIPEMD160"; then
+  test_one ":3:"    "9C1185A5C5E9FC54612808977EE8F548B2258D31"
+else
+  echo "Hash algorithm RIPEMD160 is not installed (not an error)"
+fi
 # SHA-224
 if have_hash_algo "SHA224"; then
   test_one ":11:"    "D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F"
@@ -56,9 +64,13 @@ fi
 [ "$failed" != "" ] && error "$failed failed for empty string"
 
 echo_n "abcdefghijklmnopqrstuvwxyz" | $GPG --with-colons --print-mds >y
-test_one ":1:"    "C3FCD3D76192E4007DFB496CCA67E13B"
+if have_hash_algo "MD5"; then
+  test_one ":1:"    "C3FCD3D76192E4007DFB496CCA67E13B"
+fi
 test_one ":2:"    "32D10C7B8CF96570CA04CE37F2A19D84240D3A89"
-test_one ":3:"    "F71C27109C692C1B56BBDCEB5B9D2865B3708DBC"
+if have_hash_algo "RIPEMD160"; then
+  test_one ":3:"    "F71C27109C692C1B56BBDCEB5B9D2865B3708DBC"
+fi
 if have_hash_algo "SHA224"; then
   test_one ":11:"    "45A5F72C39C5CFF2522EB3429799E49E5F44B356EF926BCF390DCCC2"
 fi
index 7e6ec2c..a381681 100755 (executable)
@@ -4,7 +4,7 @@ set -e
 
 # We need to use --no-options so that a gpg.conf from an older version
 # of gpg is not used.
-GPG="../g10/gpg2 --no-options --batch --quiet
+GPG="../../g10/gpg2 --no-options --batch --quiet
      --no-secmem-warning --allow-secret-key-import"
 
 NAMES='Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India
index 908b578..9ad8676 100755 (executable)
@@ -132,7 +132,7 @@ cnksIEkgY2FuJ3QgZG8gdGhhdAo=
 
 
 for i in  sig_sl_valid ; do
-    eval "(IFS=; echo \"\$$i\")" | ./gpg_dearmor >x
+    eval "(IFS=; echo \"\$$i\")" | $GPG --dearmor >x
     $GPG --verify x 2>/dev/null || error "valid is invalid ($i)"
     linefeed
 done
@@ -145,7 +145,7 @@ done
 for i in sig_1ls1ls_valid sig_ls_valid \
          sig_1lsls_invalid sig_lsls_invalid \
          sig_lss_invalid sig_slsl_invalid ; do
-    eval "(IFS=; echo \"\$$i\")" | ./gpg_dearmor >x
+    eval "(IFS=; echo \"\$$i\")" | $GPG --dearmor >x
     $GPG --verify <x 2>/dev/null && error "invalid is valid ($i)"
     linefeed
 done
diff --git a/tests/openpgp/pinentry.sh b/tests/openpgp/pinentry.sh
new file mode 100755 (executable)
index 0000000..b4b12fc
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Copyright 2011 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.
+
+echo "OK - what's up?"
+while read cmd rest; do
+  echo "cmd=$cmd rest=$rest" >&2
+  case "$cmd" in
+    \#*)
+      ;;
+    GETPIN)
+      echo "D ${PINENTRY_USER_DATA}"
+      echo "OK"
+      ;;
+    BYE)
+      echo "OK"
+      exit 0
+      ;;
+    *)
+      echo "OK"
+      ;;
+  esac
+done
diff --git a/tests/openpgp/privkeys/0D6F6AD4C4C803B25470F9104E9F4E6A4CA64255.asc b/tests/openpgp/privkeys/0D6F6AD4C4C803B25470F9104E9F4E6A4CA64255.asc
new file mode 100644 (file)
index 0000000..ddf0fb9
--- /dev/null
@@ -0,0 +1,12 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6ZWxnKDE6cDk3OgD/BWuU2w+pPFZltSIytQ3wyNMV
+HbFSG5PDdx29GCJU9RP+rWXX4jcKmilUHH9e4CSDmwcHzTNzqlmDrnZgVXd0uhNx
+5LuuJ1vmTbewdraFkYJ5OjoB3Eg7LneCII8M/0UpKDE6ZzE6AikoMTp5OTY6Toef
+zlcVKiPuobKfXHDhIUQPTfGic2Az47wkMoYHo9j9ZE7AWaliMdPz4jLyLfqqoU9m
+H8g+vJhyAc7UnAF2Sk5466FDypdPm5F9PTW3cqqIwJM4WgkSlM8J2hxH4YtlKSgx
+OngyOTob6nEVc0W4M+ZyrqMvp26DaKRnuFwcsDLsN11JLykpKQ==
+=Ghie
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/0DD40284FF992CD24DC4AAC367037E066FCEE26A.asc b/tests/openpgp/privkeys/0DD40284FF992CD24DC4AAC367037E066FCEE26A.asc
new file mode 100644 (file)
index 0000000..49d4413
--- /dev/null
@@ -0,0 +1,27 @@
+This is the unprotected private key for
+
+pub   ed25519/97965A9A 2014-08-19
+      Key fingerprint = C959 BDBA FA32 A2F8 9A15  3B67 8CFD E121 9796 5A9A
+      Keygrip = 0DD40284FF992CD24DC4AAC367037E066FCEE26A
+uid       [ unknown] EdDSA sample key 1 (draft-koch-eddsa-for-openpgp-00)
+
+The human readable version of the armored s-expression below is:
+
+(private-key
+ (ecc
+  (curve Ed25519)
+  (flags eddsa)
+  (q #403F098994BDD916ED4053197934E4A87C80733A1280D62F8010992E43EE3B2406#)
+  (d #1A8B1FF05DED48E18BF50166C664AB023EA70003D78D9E41F5758A91D850F8D2#)
+  )
+ )
+
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v2
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6ZWNjKDU6Y3VydmU3OkVkMjU1MTkpKDU6ZmxhZ3M1
+OmVkZHNhKSgxOnEzMzpAPwmJlL3ZFu1AUxl5NOSofIBzOhKA1i+AEJkuQ+47JAYp
+KDE6ZDMyOhqLH/Bd7Ujhi/UBZsZkqwI+pwAD142eQfV1ipHYUPjSKSkp
+=SS8V
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/13FDB8809B17C5547779F9D205C45F47CE0217CE.asc b/tests/openpgp/privkeys/13FDB8809B17C5547779F9D205C45F47CE0217CE.asc
new file mode 100644 (file)
index 0000000..0c15f8c
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6cnNhKDE6bjEyOToAqFJWduzk11/m0Ac/K/mab0kz
+zr3UUor1bkxh4vcxJHOTZF3a9Y6t1WUpwlOXeCNkY98tRYUg6A40wFgkKz/4jdOa
+iDtHW2bOqrvJmJ/wH/5zdmDpthu53JEgXUKP/+j2dfrvYTZYxy2m11DA68QK9iPS
+BmksglFMQE2IJatwEAEpKDE6ZTI6AQEpKDE6ZDEyODoAvKABRIX7dtUOm2y6VyGs
+ESE5D4YI1AhL0EWodt84EPEUvC1o61UuYbAe28JIHwjIKDLgDiedZ6hTBV3K5cI1
+aFHL421hDE0qtD+mVZhcRGnR2RHhr9gX6qX+4P8mV0w1nhdShwUhlFO1GuwQ2/dW
+KwYdXGbDW7P58LIiudGWuSkoMTpwNjU6AMM8WAY5lr1ZdSqr39rNqntLZqoXVO4N
+ibd5Tw3o/3JMVJ/xEqMykrude87nlPCAJMPlX9gjP1B57UmRxN8mGNkpKDE6cTY1
+OgDctZRfAPGvQ4vUwxG4uso9nbCtFlGYZTQgMPHfMFflUyxH9Y0zA8ujyKKYFPYX
+t7Pe6Y+qqu6BG0mPqvIXe3dpKSgxOnU2NDop+y32myNaSakGsQ732PgarqitgefN
+3h9Kec4kS/j85t1esYEbC9XlFluVcIUDaQHdKFpijCl6eC2oFXOkPRwJKSkp
+=nyLM
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/343D8AF79796EE107D645A2787A9D9252F924E6F.asc b/tests/openpgp/privkeys/343D8AF79796EE107D645A2787A9D9252F924E6F.asc
new file mode 100644 (file)
index 0000000..c674b65
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6ZHNhKDE6cDEyOToArHGqWD0rP0Nn/c3nYELTD4m1
+gqR7f2+l1ZUMdHcweYwn/fVjaJKmbR+9GzeHWP398FWYs5mCU1DIfrZLF0nJnAJ6
+WRnN9TL+oub1BqqLvCmDSngRuZZ2gUX8DVmD8xTsPnDnG74QDUnvtnpDIAs32sg5
+dnusstrriXD8xXgt0g8pKDE6cTIxOgC449htJbbp5rkJHvBDs4YxEIkk5ykoMTpn
+MTI4Ol+ITxpSMOT5R67Bu4XWoYU7nVeYURpb6LJ8LK2CV7ygECwFdRFdukiGFB+a
+TP8nF6xtuXalaBuerkKp4QXVKqOIkp7MWN2TAOOg9eERHPT//whryf49meNYMPLv
+KAe60udHY76Glm+Zso+24WnEwXX2od1PHVV3CItWRb7YmhgGKSgxOnkxMjg6AgXt
+40h2lpiIHTjbu6fiCBzbr5j2eQX3cNoydkRphJ66bqD+DsPW/Ag0WBCQxgRaLgMr
+db64fQT+fyjbTBLbC8ytt5hpCbm/q5x3TTXDAUNjoB3CnA/tQItBy7qqq/A0d3FZ
+grr6AixK58uZ4wauy8LRZCph67UZ8akcgwJkmVkpKDE6eDIwOn/Y1rjZASGMK9IG
+b1y/ZDKT0zkTKSkp
+=muRa
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/50B2D4FA4122C212611048BC5FC31BD44393626E.asc b/tests/openpgp/privkeys/50B2D4FA4122C212611048BC5FC31BD44393626E.asc
new file mode 100644 (file)
index 0000000..6233524
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmRzYSgxOnAxMjk6AL8pJ97q5V8O
+ADcGsak0uFXFP/K3BcykEjykR1OJjSNaditv9i7zC0J5n0YC7H9kD+1537ul2Jsd
+d9fk/MN+BRNnCsglrns5SlbAjzvwDNnE2ydW/Ug/q58bIRIowTg9RA7mF4qHABvS
+BDAXACtLe/ih5isSWOEnv2Sm3fX0kQATKSgxOnEyMToA+hTknylYwYGT/PEVQ4Jl
+LPoWmqUpKDE6ZzEyOToAmfUdfU53m3Kgrg4QAzkb7AfPdIGPgUyidk1azUi3Tcko
+egzm6VDYWARaYFUg9MpIOb+NBc9gCnPkOnGmgZhtMJoSjrN8TfYATOhcOYYBkT3R
+eGr/BwQ34lwekfK0AD+f6FhpHexh6BDnaZYxH691330o7RXSMtFxySAEDtnaOUUp
+KDE6eTEyODp8cyy2nYt0QI5Tf+t/d4WBeib2yNWVtZH/j7XpDqHLZDgVAYkazCA6
+ZF7BvLddBEqVAh1X5tqua4AXX9L4SGYb7B0LRV72alhYiWWHez126KjVgwRTUxtE
+J4EnHmYJRReLlXosPIRhXSz7HFAqalPXJ0DvC9kzTQnnjPOylyMPTSkoOTpwcm90
+ZWN0ZWQyNTpvcGVucGdwLXMyazMtc2hhMS1hZXMtY2JjKCg0OnNoYTE4OnBnEA/u
+YyreNzo0OTMzNjMyKTE2OtXuvrOxsl1/bOm+6zBEQZ0pODA6XEPa+d4D7F2jof/+
+sJvtf22PzAgN/qZ93eIKlJaHxQFQeOyLrghCAUyZLIBzR8dlNBG+uWhg7DBJMVnR
+MhH24nqzdivp+SxlMO0XdnkmkBspKDEyOnByb3RlY3RlZC1hdDE1OjIwMTAxMDE0
+VDEyMDgxMSkpKQ==
+=ZfqD
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/76F7E2B35832976B50A27A282D9B87E44577EB66.asc b/tests/openpgp/privkeys/76F7E2B35832976B50A27A282D9B87E44577EB66.asc
new file mode 100644 (file)
index 0000000..79699a2
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmRzYSgxOnAxMjk6ALZlsUNfTCYk
+jzIsNhB0iJl4C4cuZ/IeypdosZQxm1aIC+f+E2ly3BqGbMqbmheKcdS9SQs5DSzy
+s6W7XmeHDhrNzfStM/UuwiSfnM5E2cV2BgLpErKE56Kb/rf7/Ia12dObj2VV9oKr
+CwSYEISRdp5YMar6J7Vvz0nz1Pqf8mq7KSgxOnEyMToAoQkjVeVGG+B/SzJ6+yif
+dHWQVkcpKDE6ZzEyODoVw8i11+Plhxj9mnredV5SqI1hsLGZnPSzz2IcFP0XFDu3
+HtUEG9FxZVFRQYWNCUKTP7cv5DYvmhlhc4oG0PhwFmZFLwPPlSAFZ3jfqfkh4RiM
+i01yqQGE6uOgML5ZWeQqb39Ngqf/ltWlcgNKpwVjMniMV5kfRzoupccZ+XI2oyko
+MTp5MTI4OlVm585daoJeQG/Pg7LdDkVuNBDT/63LysOfw5NqI+LjUXJScSLos76r
+IFLT0WOdmP74+RxFxdb31I3GYQlFjsy40e3nAi8QfaM0Q4n2WzPNkUENu7CyNccr
+fn6U9sYTLr3EI/bqIRp/KwoptFcmETUL62TxKcr4abrayK+Yr/lqKSg5OnByb3Rl
+Y3RlZDI1Om9wZW5wZ3AtczJrMy1zaGExLWFlcy1jYmMoKDQ6c2hhMTg6ndF2xFqT
+19k3OjUyNDI4ODApMTY6QB3EeZz7Zs2uIRmjRj/ocyk4MDoN3zs2+IgNNxe0pZQ9
+XzwAAgAA0MhK4ypYOdDc2fvfvCsjrhQyUW5ZQVVxFmf7hgY6YZzAlldXF9bD9DMC
+JtcJmap6Xk5D7VClxR97yHK+ASkoMTI6cHJvdGVjdGVkLWF0MTU6MjAxMDEwMTRU
+MTU0MzUyKSkp
+=8r3/
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/7E201E28B6FEB2927B321F443205F4724EBE637E.asc b/tests/openpgp/privkeys/7E201E28B6FEB2927B321F443205F4724EBE637E.asc
new file mode 100644 (file)
index 0000000..7ec0448
--- /dev/null
@@ -0,0 +1,18 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVsZygxOnAxMjk6AOgCS1p47zcd
+ec0UvVC0phewalHUU6f7mulWr0j0ZY1RU0IOP18HAeT7INcwPcUaUvC9KYenXmYb
+vO1i7sNNUCOsKUamwg+oSNMcbM3AwNwxlggTyJS1N6WzIX7MjRLUlUqtbLRhPDGl
+Cltt6yeAjS0pZT646TANaBDiRIgk94ADKSgxOmcxOgUpKDE6eTEyODpGh2X1Sy+4
+Ip/RtMJDPZOY+Y6sWUN7OiM2BkdUmCLOmaOVfgrsEevKdSBBj0oVWN81U02i7jQz
+hhAI3tZMFJmP/hlF7AlS5HSaLj2+t1nHAKKy70QhskINR41CCv9sHAc5gN1WrY5N
+DpeI12GmqsWMPQVPUHsTTe0QsT6XbHzvCykoOTpwcm90ZWN0ZWQyNTpvcGVucGdw
+LXMyazMtc2hhMS1hZXMtY2JjKCg0OnNoYTE4Or78V63MKf6HNzo0OTMzNjMyKTE2
+OkxDOAnTGrRgVCyb5u0UbCYpOTY6tghO175Vpfia/wJGrOUT0hgS3Es/EaEHv+bn
+jYBeErvROJrKtUboxoGox/Qa2xxpFFhFWtR3IX6rjmqS1a5RhwEmYxFb/IzVESuZ
+Kf00wS+lmJuR14ACnuAOfVF6OQP5KSgxMjpwcm90ZWN0ZWQtYXQxNToyMDEwMTAx
+NFQxMjA4MTIpKSk=
+=a0Os
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/8B5ABF3EF9EB8D96B91A0B8C2C4401C91C834C34.asc b/tests/openpgp/privkeys/8B5ABF3EF9EB8D96B91A0B8C2C4401C91C834C34.asc
new file mode 100644 (file)
index 0000000..370e862
--- /dev/null
@@ -0,0 +1,14 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6ZWxnKDE6cDEyOToAzNix+drHTYCMxS8NiUZNpVTG
+nWfzMjxCqVyZYt9CEm7A4JcfSbgRUppqKunwreuDmmNGFc1W+lT1oLfvJaDi/oQ/
+oubgIcq0EZ5gOUydaj961PV3ltNmaaUSZsJ6jRxaa0FB1cgx6EVB88gR6JB4mAM4
+KV+Ct/f9QzPv2TMS8qspKDE6ZzE6BikoMTp5MTI4OjdzptnsiJ124yTW5ewhvUVp
+mDGuT9CuA3ggW65bjOhfravX5rfHMCXLPXMNXFgpA012vghVwun/ekkj7/rxapZm
+lE28YpSDj8Pwn/lkqNAjy466My+wUeoCgg7mEg/75is2ogKzx1L52nay7BGmfS41
+5m7BBjWHsiUA6KRtFXt1KSgxOngzMTppFcbO0lgUP4k3sTNfSIfwBCt8YwBTmPk5
+a7hTI4y2KSkp
+=miH9
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD.asc b/tests/openpgp/privkeys/A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD.asc
new file mode 100644 (file)
index 0000000..616c697
--- /dev/null
@@ -0,0 +1,20 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVsZygxOnAxMjk6AJyN1x9X9Lsj
+fX2Z8O9s7BzMO9OoOxFtvZw+FA0BuDs0WVYkq1GuZ9/XiO0K30zvtZnlb7NMvBfz
+7xbLeYx+vKzy5xkq18+LE5dU+HKKdRQZKrrwgCsDy8tJRO447QsiLTksCDqPMaE3
+2OCRBF5nKrG5vih7/cmEhf2CuAn+2yM3KSgxOmcxOgcpKDE6eTEyODoZ5eYysaLn
+AwPeqQ9vNvUyrCxUEmrvl4svG7zkkg3ZcgAbDpDQUmnijt3gEBCoAzO3c41TU5wJ
+aUNBEPGPWfKcTlmBEGJWjK50QQuA2diGncxIS5SDs+QVaf434a6/KFVQcCmV7K8/
+T2S8/nuGJ/rIlFL5XovW6A/S9mYEjh2pDykoOTpwcm90ZWN0ZWQyNTpvcGVucGdw
+LXMyazMtc2hhMS1hZXMtY2JjKCg0OnNoYTE4OkuRjUFO6YIJNzo0NjYwMjI0KTE2
+Or7L9Ekww4C0lZz3g61PzJEpMTkyOk7ezAcv7simMXQw+afvqUlhdoyVM4QQuhj8
+KzqjNP3IC2fSHoFECWxGfC1fNcuqzRnzs98TqAy5BDnNXSW+e+CpenWtLpID/dvb
+azkeATfhMf/2KMd2Mahi6rnQ6IBnxhq1d5jLhYg00Ba1HbojEYOkCPKQlFV01bQw
+mUsyQ7sMr42JvdFTI4lDmQlHfqoexpFpLCDv4eUKjvG/K7xs0uLiF4vyMLVH5H/k
+6EF9HEP9sUF+aTDJXrrfHOUG1LR6/CkoMTI6cHJvdGVjdGVkLWF0MTU6MjAxMDEw
+MTRUMTUzNTM4KSkp
+=soiR
+-----END PGP ARMORED FILE-----
diff --git a/tests/openpgp/privkeys/FD692BD59D6640A84C8422573D469F84F3B98E53.asc b/tests/openpgp/privkeys/FD692BD59D6640A84C8422573D469F84F3B98E53.asc
new file mode 100644 (file)
index 0000000..7b25b7a
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.4.8 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+KDExOnByaXZhdGUta2V5KDM6ZHNhKDE6cDk3OgDbbxWAbWsheUJprK6VryMTpwDi
+YwMfL+92nrHqSfPqlpMWgDTia8qnpRSXbyEmSppp/6/Ygp+N3n32Kznq7PjHXiuW
+LlZGvZMtzmvaMA17y0GY6oLBxS7rhASXIKa9hEUpKDE6cTIxOgD/igRZcqjTHbCv
+I/mTtAPK5yJhqykoMTpnOTc6ALV10OZ7mJkWRMRYeGu1T3uwS7YYORJAHwd1fwKh
+Fys7P8HZaWIXqp8EqFxk8VUEiEo3ONN9jtIRgBmTbNywKbx6WfBItoYTPEoU0UGo
+oM1c/5rfmylyqwdIbMNXDhW4oykoMTp5OTc6AJNnAP6skpHlhVAmecLZT9eRzVoO
+q1ivUIntK2Mh47qsL74q6BBwz2sviPU2Y3pDlbb6Ed0qJAXvdCT24hlfoGoXzkoD
+InkPJTJeL0gCnwmQPjvXFFd71Cvg5LaL4lIQLSkoMTp4MjA6cZuCxaj7sT+FZqTO
+y2lNfMjaQMgpKSk=
+=s5nv
+-----END PGP ARMORED FILE-----
index d386169..6f8f916 100644 (file)
@@ -1,4 +1,12 @@
 
 no-creation-time.gpg   A key with a zero creation time.
-
-
+ecc-sample-1-pub.asc   A NIST P-256 ECC sample key.
+ecc-sample-1-sec.asc   Ditto, but the secret keyblock.
+ecc-sample-2-pub.asc   A NIST P-384 ECC sample key.
+ecc-sample-2-sec.asc   Ditto, but the secret keyblock.
+ecc-sample-3-pub.asc   A NIST P-521 ECC sample key.
+ecc-sample-3-sec.asc   Ditto, but the secret keyblock.
+eddsa-sample-1-pub.asc An Ed25519 sample key.
+eddsa-sample-1-sec.asc Ditto, but as protected secret keyblock.
+dda252ebb8ebe1af-1.asc rsa4096 key 1
+dda252ebb8ebe1af-2.asc rsa4096 key 2 with a long keyid collision.
diff --git a/tests/openpgp/samplekeys/dda252ebb8ebe1af-1.asc b/tests/openpgp/samplekeys/dda252ebb8ebe1af-1.asc
new file mode 100644 (file)
index 0000000..ddae954
--- /dev/null
@@ -0,0 +1,29 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+
+mQINBFJtd/UBEACpw/psXoGNM8RHczviD7FnGdjMQPEJQ+nuWQ2AEGYouulg5hFv
+0ChuSQVLiqQht2k5K2liyW1MeXoJ8tr9nSn/Zi9nttc0Wo6K7pvrDD40r2HNg305
+qLCzItr5st3x8cq2cIXvN4LOm2rqpBLZ/sqMmNiW2Y7/aAQqV1xtR35joHqamWHD
+UPOmzBMs07YSUjXgC1EMx8kWQSV6cuARj93kxWj8R6eoYHHfrWCEGR313wov6QST
+zIfVU7FqQqOmdLW3LaPHxcrI/TjsnkUN99qdlpjJH/YW925LDPJHAkliqPP5AvhU
+F9KbY2F8mcIZBCDd8TH+xXynuN3BbIU4kCwVbdx/tcpO1npuJcKB1Go/udyow/Ei
+Z3nHzJsCVkezvopek77wnwPaP0nAb7f4iIY3gJCoGirOx6N075TgF6MBe00q9oFE
+y4rvnUnU9/QzOOes95eUMhM+9eK1cuLFEV5t47DfxRdq+fQip3FJ2l6v19sZvQ0G
+j06pjYqg0of273rG8oXcDrFjb1Zqhj8x1mLl6u7d/ide5wTm9HylBWcYKQjIJJAi
+WIScxEPIOINDJKgsKTuKtoyNvISJ3xUeS1yzxiIb3YGLIyPgFFx0vFyqJfbkXq70
+m1n2xnJlkTidfzbZvc6EA7vRGSDYK6FqqhlGhc7UypUEVW8FM/jZNAOS6QARAUGt
+tCg5RTY2OTg2MTM2OEJDQTBCRTQyREFGN0REREEyNTJFQkI4RUJFMUFGiQI3BBMB
+CgAhBQJSg/uTAhsDBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEN2iUuu46+Gv
++Z0P+wQhkLwm+WGcEsS98Lei9O7hit/k4g/VkLUUQV7BOR3n8uRZIFkdOtpvrFU3
+aKf246uCy6GM48Oh+1U2cv5InX/WEuKaFo5uF6t79wyt18BUn1weDcU+DQdOSG4f
+fSnNa55wkN0l0svW4fGIthjmDTz6HZFntYD+9A20wZAqpPIs+vyG9Jp+e9E9Y/W/
+EFQbNlxHHb9+BMT2+DtNP+HSl3MPFlQPKOLZxyLAU5uzT0Sa0LxhrQy5FgkW6Jog
+sbAJVM9z0pZw+grzGPciM66ZW1rxeICvbYsdWLytRjqxpY8GS8XudyseUGd+dZim
+ptarsrE5yfSMg2gW5Z1PTc0tEMXJLUwtpyzQjpFpbb7dPuo2TUp09LgZKX63WCbS
+Nb1RTaGfkeYudOTo2rh4Jfg+Tb/JRpO6clo0rxAq8nPH2WmG+9TB8Zbb7YRzGWuV
+/e5SeVNR+zY8tXZKnmUIH1HIprc+BtT6Bupdvd0CT14Mg9MmsFvUXofwHLa4gahr
+8/iG9y3uHSA6Rhz++yOpyOmNvO1LDxsYNaRCIXQJbqgNwF5YNYlMPsEeY/CG7FOb
+Afv7rHiYtRRQfz2P4OF900DJO7QL9gdNXJ1+Hajy/5Lvvl7qwqMG4GvVQEsgFc5O
+jjFCUhE2i20j2kEMxvA5RLBH/fOoGARn87tiKSfb+pqLNZQb
+=fDJ8
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/dda252ebb8ebe1af-2.asc b/tests/openpgp/samplekeys/dda252ebb8ebe1af-2.asc
new file mode 100644 (file)
index 0000000..8547463
--- /dev/null
@@ -0,0 +1,29 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+
+mQINBFKD+38BEADSv5l4xOx9hCRJVcybq6yK5hTpGSFf3xo1bkhoMvyC62ehb4jD
+MDLwwNRyzCBEWQJLbq/LLizPFN2qXFJpXJcsuqsHNYRtDqDBEjtriRQwSqHnqTXt
+c0K46FYHldCJQ4/tBXxPI+WwtXjcNRWaV7n2BvR/Jk+B5e4Zz3LPnN0C4w5vORHs
+hN1jil8A3Hs/F+OmlQYrU8ZtNwTpSo2EXxe2fVgSDCsKRyNsPZj++OyujPzW+yaN
+lJ9I/q6s9gvX9o9o7nwZbqBETipWsdRK6RfBdTKpnyLNordbWwWTk6GxN8T5Ppit
+P6a3UlQ71VuflcswCTmEQ1pEfZrlRFKa9psBOW+cZLNxT9h0jGFMh6/B3w48Sag+
+cFcPBFWParC+cAXBIURDxT9G6bzNLogg7YKoaPsyiXnLDH2VJUCXs27D2wPJL24Q
+S7npvsg63MPPssWgG5cauLznmNR4y5pQi6oH/C10v0zrUJy6FPJzQhYRhWOvhtz6
+j88RGMrFNNCdB2VACtn699D+ixu3nRlXHIKCT+xLSfgslVYifmJOCNljBLGHOQ1e
+FJxQuNVpmmxjvk/8kqK+pHLB9Qn6M1ZYzip7OyUL3OAWabCabgEw2bQmUhiBWD3u
+buv0WAVOJEAFvBCAeYNQzrQMY+Rc3RnvynG4pI6Tbo8wC6/IJcDOw516JwARASB3
+tChBNTUxMjA0MjczNzRGM0Y3QUE1RjExNjZEREEyNTJFQkI4RUJFMUFGiQI3BBMB
+CgAhBQJSg/uTAhsDBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEN2iUuu46+Gv
+9L0P/3tFu0LOZ/dAPjUNfKJCZqcIuVnD5xShMTsUbVx+QoXMy7rt4iRLD7ofGi/I
+vTAZehxk3sk/Slx5nbews+3NItyw6mcaP9HlmwKNr6k7BC2kJHcCxH4DNzhmIx1H
+3T/CggtHX42JBYKlGf22y+M8jAbvsPOUfTznx96mYNrOY6s1dJyn0kRleqJ8+tGj
+/5+0y90iZnGCa0FtacQkKUPkXwVodeZVxk8z5OEipShYKc+8dl+5WsvOzHqLC/KY
+xCGRb4JaqEMwouLNg8dTNAXXUvFGqJNDX4+andggogmI1hdD9xExfSU9cAGegg2t
+vvveC4S+CCHd+zt88iK5ze6F61RxwYhhNbkuFGjdgNGCpHtG/BQhKnYJuKEbq3oi
+mgNyxJERlfgaWXveiMG0AmACXN+jCkTtqZjQnsg2N2QDL3tjY7usmuiwRL1aVOFG
+Kw5/Cc+2nDeANS3Xi1403Ni269b1c6kNSoLe4zd0WsbO3Kouds8F8EQfeheXQe97
+ZxuvBOMsR9wHC3f0sl/vfxCGdUC+khmKk5taKnUeUFJmVmh5ghlVy8FySHGB0QHO
+zd8GUl59rFpQJNpNFQW2YKDhrcjxIr2AeJrdoDI6NsQ02+Qtep/bbq53hqtAD4jF
+t3S8vBbTXtRk6g2qn4ojF4SOIc8SAiZcURgVFuSJX8ngFbO4
+=OEw/
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/ecc-sample-1-pub.asc b/tests/openpgp/samplekeys/ecc-sample-1-pub.asc
new file mode 100644 (file)
index 0000000..478fc3a
--- /dev/null
@@ -0,0 +1,22 @@
+The key has been generated by the first GnuPG ECC version at
+http://code.google.com/p/gnupg-ecc.
+
+The sample key has ECDSA top key 0xBAA59D9C and a single ECDH
+encryption subkey 0x4089AB73. ECDH subkey uses SHA-256 and AES-128
+with KDF.
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.1.0-ecc (GNU/Linux)
+
+mFIETJPQrRMIKoZIzj0DAQcCAwQLx6e669XwjHTHe3HuROe7C1oYMXuZbaU5PjOs
+xSkyxtL2D00e/jWgufuNN4ftS+6XygEtB7j1g1vnCTVF1TLmtCRlY19kc2FfZGhf
+MjU2IDxvcGVucGdwQGJyYWluaHViLm9yZz6IegQTEwgAIgUCTJPQrQIbAwYLCQgH
+AwIGFQgCCQoLBBYCAwECHgECF4AACgkQC6Ut8LqlnZzmXQEAiKgiSzPSpUOJcX9d
+JtLJ5As98Alit2oFwzhxG7mSVmQA/RP67yOeoUtdsK6bwmRA95cwf9lBIusNjehx
+XDfpHj+/uFYETJPQrRIIKoZIzj0DAQcCAwR/cMCoGEzcrqXbILqP7Rfke977dE1X
+XsRJEwrzftreZYrn7jXSDoiXkRyfVkvjPZqUvB5cknsaoH/3UNLRHClxAwEIB4hh
+BBgTCAAJBQJMk9CtAhsMAAoJEAulLfC6pZ2c1yYBAOSUmaQ8rkgihnepbnpK7tNz
+3QEocsLEtsTCDUBGNYGyAQDclifYqsUChXlWKaw3md+yHJPcWZXzHt37c4q/MhIm
+oQ==
+=hMzp
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/ecc-sample-1-sec.asc b/tests/openpgp/samplekeys/ecc-sample-1-sec.asc
new file mode 100644 (file)
index 0000000..5ff5555
--- /dev/null
@@ -0,0 +1,25 @@
+The key has been generated by the first GnuPG ECC version at
+http://code.google.com/p/gnupg-ecc.
+
+The sample key has ECDSA top key 0xBAA59D9C and a single ECDH
+encryption subkey 0x4089AB73. ECDH subkey uses SHA-256 and AES-128
+with KDF. The password for the key is "ecc".
+
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v2.1.0-ecc (GNU/Linux)
+
+lJ0ETJPQrRMIKoZIzj0DAQcCAwQLx6e669XwjHTHe3HuROe7C1oYMXuZbaU5PjOs
+xSkyxtL2D00e/jWgufuNN4ftS+6XygEtB7j1g1vnCTVF1TLm/gMDAmHomSLb9NbE
+oyWUoqgKTbZzbFR/SWmiCcuiQEhREcTyvyU1hAglj7FsBJoQ6/pbeAEQZ3bVzlNM
+8F0nF8KPLPuEADF1+4CntCRlY19kc2FfZGhfMjU2IDxvcGVucGdwQGJyYWluaHVi
+Lm9yZz6IegQTEwgAIgUCTJPQrQIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
+CgkQC6Ut8LqlnZzmXQEAiKgiSzPSpUOJcX9dJtLJ5As98Alit2oFwzhxG7mSVmQA
+/RP67yOeoUtdsK6bwmRA95cwf9lBIusNjehxXDfpHj+/nKEETJPQrRIIKoZIzj0D
+AQcCAwR/cMCoGEzcrqXbILqP7Rfke977dE1XXsRJEwrzftreZYrn7jXSDoiXkRyf
+VkvjPZqUvB5cknsaoH/3UNLRHClxAwEIB/4DAwJh6Jki2/TWxKO7gHKWIcOcxYZp
+CRWjlUghbKb6Q83p8GLPjKRN0USl/U1tObWdksqMXhUO0ePLWUnrbwoWYfYXg9Er
+ADTgCYhhBBgTCAAJBQJMk9CtAhsMAAoJEAulLfC6pZ2c1yYA/3eJRirPQZmBno+Z
+P/HOBSFWmFt4cUBGUx3oqiUd5loOAP480pb+vXx9ipljJWCJDSl/boRSuqB4hePP
+qt9Rd5gNdQ==
+=O8Dg
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/ecc-sample-2-pub.asc b/tests/openpgp/samplekeys/ecc-sample-2-pub.asc
new file mode 100644 (file)
index 0000000..f898012
--- /dev/null
@@ -0,0 +1,25 @@
+ECC NIST P-384 key taken from
+https://sites.google.com/site/brainhub/pgpecckeys
+
+The sample key has ECDSA top key 0x098033880F54719F and a single ECDH
+encryption subkey 0xAA8B938F9A201946. ECDH subkey uses SHA-384 and
+AES-256 with KDF.
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+mQBvBE1TBZITBSuBBAAiAwME9rjFrO1bhO+fSiCdsuSp37cNKMuMEOzVdnSp+lpn
+OJlCti1eUTZ99Me/0/jlAP7s8H7SZaYhqOu75T6UfseMZ366FDvRUzwrNQ4cKfgj
+E+HhEI66Bjvh5ksQ5pUOeZwttCRlY19kc2FfZGhfMzg0IDxvcGVucGdwQGJyYWlu
+aHViLm9yZz6JAMsEEBMJAFMFAk1TBZIwFIAAAAAAIAAHcHJlZmVycmVkLWVtYWls
+LWVuY29kaW5nQHBncC5jb21wZ3BtaW1lBAsJCAcCGQEFGwMAAAACFgIFHgEAAAAE
+FQkKCAAKCRAJgDOID1Rxn8orAYCqNzUJaL1fEVr9jOe8exA4IhUtv/BtCvzag1Mp
+UQkFuYy0abogj6q4fHQSt5nntjMBf1g2TqSA6KGj8lOgxfIsRG6L6an85iEBNu4w
+gRq71JE53ii1vfjcNtBq50hXnp/1A7kAcwRNUwWSEgUrgQQAIgMDBC+qhAJKILZz
+XEiX76W/tBv4W37v6rXKDLn/yOoEpGrLJVNKV3aU+eJTQKSrUiOp3R7aUwyKouZx
+jbENfmclWMdzb+CTaepXOaKjVUvxbUH6pQVi8RxtObvV3/trmp7JGAMBCQmJAIQE
+GBMJAAwFAk1TBZIFGwwAAAAACgkQCYAziA9UcZ+AlwGA7uem2PzuQe5PkonfF/m8
++dlV3KJcWDuUM286Ky1Jhtxc9Be40tyG90Gp4abSNsDjAX0cdldUWKDPuTroorJ0
+/MZc7s16ke7INla6EyGZafBpRbSMVr0EFSw6BVPF8vS9Emc=
+=I76R
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/ecc-sample-2-sec.asc b/tests/openpgp/samplekeys/ecc-sample-2-sec.asc
new file mode 100644 (file)
index 0000000..b163f63
--- /dev/null
@@ -0,0 +1,22 @@
+ECC NIST P-384 key taken from
+https://sites.google.com/site/brainhub/pgpecckeys
+
+The sample key has ECDSA top key 0x098033880F54719F and a single ECDH
+encryption subkey 0xAA8B938F9A201946. ECDH subkey uses SHA-384 and
+AES-256 with KDF. The password for the key is "ecc".
+
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+lQDSBE1TBZITBSuBBAAiAwME9rjFrO1bhO+fSiCdsuSp37cNKMuMEOzVdnSp+lpn
+OJlCti1eUTZ99Me/0/jlAP7s8H7SZaYhqOu75T6UfseMZ366FDvRUzwrNQ4cKfgj
+E+HhEI66Bjvh5ksQ5pUOeZwt/gcDAkrFTsfF6LKsqD/tW6Eot2DDE8znJjnQQ/Nr
+H98XT1WQ9V0ED8l9DDIIj7z80ED3NR8XMSI8Ew/A/0w6NDPL978BX0MGvpaeBaWV
+tEuH1EPAxiA+hFALwftY+a8s1zLktCRlY19kc2FfZGhfMzg0IDxvcGVucGdwQGJy
+YWluaHViLm9yZz6dANYETVMFkhIFK4EEACIDAwQvqoQCSiC2c1xIl++lv7Qb+Ft+
+7+q1ygy5/8jqBKRqyyVTSld2lPniU0Ckq1Ijqd0e2lMMiqLmcY2xDX5nJVjHc2/g
+k2nqVzmio1VL8W1B+qUFYvEcbTm71d/7a5qeyRgDAQkJ/gkDAqqmkngPLoJGqI4O
+rHyyU3wrrPzDDDURkseoUEZlDZINjyto26A8N825mqLqeFytJuuABYH1UnLs4d2x
+ZJZIYjEoFMPcFPuUtx+IZnECa1Vcyq2aRFCixVO0G/xrSFar
+=a4k3
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/ecc-sample-3-pub.asc b/tests/openpgp/samplekeys/ecc-sample-3-pub.asc
new file mode 100644 (file)
index 0000000..14b49d3
--- /dev/null
@@ -0,0 +1,28 @@
+ECC NIST P-521 key taken from
+https://sites.google.com/site/brainhub/pgpecckeys
+
+The sample key has ECDSA top key 0x6B4184E145AF2FFE and a single ECDH
+encryption subkey 0x07EAAA48A81C4838. ECDH subkey uses SHA-512 and
+AES-256 with KDF.
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+mQCTBE1TFQITBSuBBAAjBCMEAWuwULfE2XoQmJhSQZ8rT5Ecr/kooudn4043gXHy
+NZEdTeFfY2G7kwEaxj8TXfd1U1b4PkEoqhzKxhz/MHK/lwi2ARzW1XQiJ1/kFPsv
+IUnQI1CUS099WKKQhD8JMPPyje1dKfjFjm2gzyF3TOMX1Cyy8wFyF0MiHVgB3ezb
+w7C6jY+3tCRlY19kc2FfZGhfNTIxIDxvcGVucGdwQGJyYWluaHViLm9yZz6JAO0E
+EBMKAFMFAk1TFQIwFIAAAAAAIAAHcHJlZmVycmVkLWVtYWlsLWVuY29kaW5nQHBn
+cC5jb21wZ3BtaW1lBAsJCAcCGQEFGwMAAAACFgIFHgEAAAAEFQoJCAAKCRBrQYTh
+Ra8v/sm3Agjl0YO73iEpu1z1wGtlUnACi21ti2PJNGlyi84yvDQED0+mxhhTRQYz
+3ESaS1s/+4psP4aH0jeVQhce15a9RqfX+AIHam7i8K/tiKFweEjpyMCB594zLzY6
+lWbUf1/1a+tNv3B6yuIwFB1LY1B4HNrze5DUnngEOkmQf2esw/4nQGB87Rm5AJcE
+TVMVAhIFK4EEACMEIwQBsRFES0RLIOcCyO18cq2GaphSGXqZtyvtHQt7PKmVNrSw
+UuxNClntOe8/DLdq5mYDwNsbT8vi08PyQgiNsdJkcIgAlAayAGB556GKHEmP1JC7
+lCUxRi/2ecJS0bf6iTTqTqZWEFhYs2aXESwFFt3V4mga/OyTGXOpnauHZ22pVLCz
+6kADAQoJiQCoBBgTCgAMBQJNUxUCBRsMAAAAAAoJEGtBhOFFry/++p0CCQFJgUCn
+kiTKCNfP8Q/MO2BCp1QyESk53GJlCgIBAoa7U6X2fQxe2+OU+PNCjicJmZiSrV6x
+6nYfGJ5Jx753sqJWtwIJAc9ZxCQhj4V52FmbPYexZPPneIdeCDjtowD6KUZxiS0K
+eD8EzdmeJQWBQsnPtJC/JJL4zz6JyYMXf4jIb5JyGNQC
+=5yaB
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/ecc-sample-3-sec.asc b/tests/openpgp/samplekeys/ecc-sample-3-sec.asc
new file mode 100644 (file)
index 0000000..6552e7a
--- /dev/null
@@ -0,0 +1,24 @@
+ECC NIST P-521 key taken from
+https://sites.google.com/site/brainhub/pgpecckeys
+
+The sample key has ECDSA top key 0x6B4184E145AF2FFE and a single ECDH
+encryption subkey 0x07EAAA48A81C4838. ECDH subkey uses SHA-512 and
+AES-256 with KDF. The password for the key is "ecc".
+
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: PGP Command Line v10.0.0 (Linux)
+
+lQEIBE1TFQITBSuBBAAjBCMEAWuwULfE2XoQmJhSQZ8rT5Ecr/kooudn4043gXHy
+NZEdTeFfY2G7kwEaxj8TXfd1U1b4PkEoqhzKxhz/MHK/lwi2ARzW1XQiJ1/kFPsv
+IUnQI1CUS099WKKQhD8JMPPyje1dKfjFjm2gzyF3TOMX1Cyy8wFyF0MiHVgB3ezb
+w7C6jY+3/gcDAv+CotECRPpSqGkqKrz+xAhAqswHXzFIBprFF0XiDooWktZSTAUR
+JVB2U6m28wC4rE3RkqFeR1B+kg4nxEAJ9k6BI8oDE0iyOY5aklF2TxPpTs/BA+N2
+O4hnXb1l5qXfuyd3bSwDeyfq3CdFe4TeKp7vtCRlY19kc2FfZGhfNTIxIDxvcGVu
+cGdwQGJyYWluaHViLm9yZz6dAQwETVMVAhIFK4EEACMEIwQBsRFES0RLIOcCyO18
+cq2GaphSGXqZtyvtHQt7PKmVNrSwUuxNClntOe8/DLdq5mYDwNsbT8vi08PyQgiN
+sdJkcIgAlAayAGB556GKHEmP1JC7lCUxRi/2ecJS0bf6iTTqTqZWEFhYs2aXESwF
+Ft3V4mga/OyTGXOpnauHZ22pVLCz6kADAQoJ/gkDAki71k/zBW2qqGyScDNNuWaA
+9A5aWhpNNyRrFembt7f/W+b591G3twdNmdCIh29VoOmQw3fO8wwgsPTUxQFgd8J3
+ncft0zciEcDZi/ztLZA3+rIIP2myZLIs9xLG+k+gf3nXpeED4uYqQX3GL+32PKwg
+=Qnd8
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/eddsa-sample-1-pub.asc b/tests/openpgp/samplekeys/eddsa-sample-1-pub.asc
new file mode 100644 (file)
index 0000000..5a65453
--- /dev/null
@@ -0,0 +1,15 @@
+pub   ed25519/97965A9A 2014-08-19
+      Key fingerprint = C959 BDBA FA32 A2F8 9A15  3B67 8CFD E121 9796 5A9A
+      Keygrip = 0DD40284FF992CD24DC4AAC367037E066FCEE26A
+uid       [ unknown] EdDSA sample key 1 (draft-koch-eddsa-for-openpgp-00)
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+mDMEU/NfCxYJKwYBBAHaRw8BAQdAPwmJlL3ZFu1AUxl5NOSofIBzOhKA1i+AEJku
+Q+47JAa0NEVkRFNBIHNhbXBsZSBrZXkgMSAoZHJhZnQta29jaC1lZGRzYS1mb3It
+b3BlbnBncC0wMCmIeQQTFggAIQUCU/NfCwIbAwULCQgHAgYVCAkKCwIEFgIDAQIe
+AQIXgAAKCRCM/eEhl5ZamnNOAP9pKn5wz3jPsgy9p65zxz1+xJEr/cczFQx/tYkk
+49tkeAD+P9jJE4SFD2lVofxn1e22H7YLvcVyHDOA9gpYWTNXiAU=
+=Jbi7
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/samplekeys/eddsa-sample-1-sec.asc b/tests/openpgp/samplekeys/eddsa-sample-1-sec.asc
new file mode 100644 (file)
index 0000000..4b5fbcc
--- /dev/null
@@ -0,0 +1,19 @@
+sec   ed25519/97965A9A 2014-08-19
+      Key fingerprint = C959 BDBA FA32 A2F8 9A15  3B67 8CFD E121 9796 5A9A
+      Keygrip = 0DD40284FF992CD24DC4AAC367037E066FCEE26A
+uid       [ unknown] EdDSA sample key 1 (draft-koch-eddsa-for-openpgp-00)
+
+The passphrase is "abc".
+
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v2
+
+lIYEU/NfCxYJKwYBBAHaRw8BAQdAPwmJlL3ZFu1AUxl5NOSofIBzOhKA1i+AEJku
+Q+47JAb+BwMCeZTNZ5R2udDknlhWE5VnJaHe+HFieLlfQA+nibymcJS5lTYL7NP+
+3CY63ylHwHoS7PuPLpdbEvROJ60u6+a/bSe86jRcJODR6rN2iG9v5LQ0RWREU0Eg
+c2FtcGxlIGtleSAxIChkcmFmdC1rb2NoLWVkZHNhLWZvci1vcGVucGdwLTAwKYh5
+BBMWCAAhBQJT818LAhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEIz94SGX
+llqac04A/2kqfnDPeM+yDL2nrnPHPX7EkSv9xzMVDH+1iSTj22R4AP4/2MkThIUP
+aVWh/GfV7bYftgu9xXIcM4D2ClhZM1eIBQ==
+=+9EF
+-----END PGP PRIVATE KEY BLOCK-----
index 28e6925..b400e72 100755 (executable)
@@ -11,8 +11,8 @@
 . $srcdir/defs.inc || exit 3
 
 for i in $plain_files ; do
-    echo "$usrpass1" | $GPG --passphrase-fd 0 --always-trust -seat \
-                        -r two -o x --yes $i
+    echo "$usrpass1" | $GPG --passphrase-fd 0 ${opt_always} -seat \
+                        -r two@example.com -o x --yes $i
     $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
index 77ded12..2fb2bb1 100755 (executable)
 
 #info Checking signing and encryption for DSA
 for i in $plain_files $data_files ; do
-    $GPG $dsa_keyrings --always-trust -se -o x --yes \
+    $GPG ${opt_always} -se -o x --yes \
                -u "$dsa_usrname1" -r "$dsa_usrname2" $i
-    $GPG $dsa_keyrings -o y --yes x
+    $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
 
-for da in ripemd160 sha1; do
+algos="sha1"
+if have_hash_algo "RIPEMD160"; then
+  algos="ripemd160 $algos"
+else
+  echo "Hash algorithm RIPEMD160 is not installed (not an error)"
+fi
+
+for da in $algos; do
     for i in $plain_files; do
-       $GPG $dsa_keyrings --always-trust -se -o x --yes --digest-algo $da \
+       $GPG ${opt_always} -se -o x --yes --digest-algo $da \
                    -u "$dsa_usrname1" -r "$dsa_usrname2" $i
-       $GPG $dsa_keyrings -o y --yes x
+       $GPG -o y --yes x
        cmp $i y || error "$i: mismatch"
        # process only the first one
        break
index 8ccbaf7..5644bef 100755 (executable)
@@ -13,7 +13,7 @@
 
 info "Checking signing and encryption"
 for i in $plain_files $data_files ; do
-    echo "$usrpass1" | $GPG --passphrase-fd 0 --always-trust \
+    echo "$usrpass1" | $GPG --passphrase-fd 0 ${opt_always} \
                             -se -o x --yes -r "$usrname2" $i
     $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
index 8b3b14f..4ba43ac 100755 (executable)
 
 #info Checking DSA signatures (default digest algo)
 for i in $plain_files $data_files; do
-    $GPG $dsa_keyrings -s -o x --yes -u $dsa_usrname1 $i
-    $GPG $dsa_keyrings -o y --yes x
+    $GPG -s -o x --yes -u $dsa_usrname1 $i
+    $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
 
-for da in ripemd160 sha1; do
+algos="sha1"
+if have_hash_algo "RIPEMD160"; then
+  algos="ripemd160 $algos"
+else
+  echo "Hash algorithm RIPEMD160 is not installed (not an error)"
+fi
+
+for da in $algos; do
     for i in $plain_files; do
-       $GPG $dsa_keyrings --digest-algo $da \
-                               -s -o x --yes -u $dsa_usrname1 $i
-       $GPG $dsa_keyrings -o y --yes x
+       $GPG --digest-algo $da -s -o x --yes -u $dsa_usrname1 $i
+       $GPG -o y --yes x
        cmp $i y || error "$i: mismatch"
        # process only the first one
        break
index a4bf76c..d6d8898 100755 (executable)
@@ -11,7 +11,7 @@
 . $srcdir/defs.inc || exit 3
 
 for i in $plain_files $data_files; do
-    echo "$usrpass1" | $GPG --passphrase-fd 0 -s -o x --yes $i
+    $GPG -s -o x --yes $i
     $GPG -o y --yes x
     cmp $i y || error "$i: mismatch"
 done
index 34733e2..057bcf0 100755 (executable)
 
 . $srcdir/defs.inc || exit 3
 
-# print the GPG version
-$GPG --version
+# This is the first test run by "make check".  First kill a possible
+# gpg-agent process from a previous test run.
+if $GPG_AGENT --quiet; then
+    echo "$pgmname: killing leftover gpg-agent process" >&2
+    $GPG_CONNECT_AGENT killagent /bye >/dev/null
+    sleep 2
+fi
+
+
+info "Deleting old files"
+if [ -f Makefile -a -f $srcdir/decrypt-dsa.test ]; then
+  :
+else
+  fatal "not running in the test directory"
+  exit 1
+fi
+if [ -d private-keys-v1.d ]; then
+    rm private-keys-v1.d/* 2>/dev/null || true
+    rmdir private-keys-v1.d
+fi
+for i in pubring.gpg pubring.gpg~ trustdb.gpg trustdb.gpg~ ; do
+  [ -d "$i" ] && rm "$i"
+done
+
+# Now start the agent right away, so that there is only one place
+# where starting the agent may fail.  To speed up key generation we
+# create a faked random seed file.  Note that we need to set the
+# agent-program so that gpg-connect-agent is able to start the agent
+# we are currently testing and not an already installed one.
+# The "|--debug-quick-random" is a hack to start gpg-agent with
+# that option on the command line.
+info "Starting the agent"
+$MKTDATA 600 >random_seed
+if $GPG_CONNECT_AGENT -v \
+    --agent-program="${GPG_AGENT}|--debug-quick-random" /bye; then
+    :
+else
+    error "starting the gpg-agent failed"
+    exit 1
+fi
+
+
+info "Creating sample data files"
+for i in 500 9000 32000 80000; do
+    $MKTDATA  $i >data-$i
+done
+cat $srcdir/../../doc/HACKING \
+    $srcdir/../../doc/DETAILS \
+    $srcdir/../../doc/gpg.texi >plain-large
+
+info "Unpacking samples"
+$GPG --dearmor < $srcdir/plain-1o.asc > ./plain-1
+$GPG --dearmor < $srcdir/plain-2o.asc > ./plain-2
+$GPG --dearmor < $srcdir/plain-3o.asc > ./plain-3
+
+info "Storing private keys"
+for i in 50B2D4FA4122C212611048BC5FC31BD44393626E \
+         7E201E28B6FEB2927B321F443205F4724EBE637E \
+         13FDB8809B17C5547779F9D205C45F47CE0217CE \
+         343D8AF79796EE107D645A2787A9D9252F924E6F \
+         8B5ABF3EF9EB8D96B91A0B8C2C4401C91C834C34 \
+         0D6F6AD4C4C803B25470F9104E9F4E6A4CA64255 \
+         FD692BD59D6640A84C8422573D469F84F3B98E53 \
+         76F7E2B35832976B50A27A282D9B87E44577EB66 \
+         A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD ; do
+   $GPG --dearmor < $srcdir/privkeys/$i.asc > private-keys-v1.d/$i.key
+done
 
-#fixme: check that the output is correct
+info "Importing public demo and test keys"
+$GPG --yes --import $srcdir/pubdemo.asc $srcdir/pubring.asc
+$GPG --dearmor < $srcdir/pubring.pkr.asc | $GPG --yes --import
+
+
+info "Preset passphrases"
+# one@example.com
+$GPG_PRESET_PASSPHRASE --preset -P def 50B2D4FA4122C212611048BC5FC31BD44393626E
+$GPG_PRESET_PASSPHRASE --preset -P def 7E201E28B6FEB2927B321F443205F4724EBE637E
+# alpha@example.net
+$GPG_PRESET_PASSPHRASE --preset -P abc 76F7E2B35832976B50A27A282D9B87E44577EB66
+$GPG_PRESET_PASSPHRASE --preset -P abc A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD
+
+
+# Note: secring.asc and secring.skr.asc are the original secrings for
+# our test files.  We don't support this as storage format anymore but
+# keep the files here for reference.  The actual keys have been
+# extracted and put in gpg-agent's format unter privkeys/.  Because
+# the current gpg's import feature does not support storing of
+# unprotected keys in the new gpg-agent format, we had to resort to
+# some trickery to convert them.
+
+
+info "Printing the GPG version"
+$GPG --version
 
+#fixme: check that the output is as expected
index a98689e..d66e474 100644 (file)
@@ -1,4 +1,4 @@
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
@@ -69,3 +69,7 @@
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/tests/pkits/PKITS_data.tar.bz2 b/tests/pkits/PKITS_data.tar.bz2
new file mode 100644 (file)
index 0000000..687d504
Binary files /dev/null and b/tests/pkits/PKITS_data.tar.bz2 differ
index 8d50786..5c832bd 100755 (executable)
@@ -1,4 +1,3 @@
 #!/bin/sh
 [ -x "$1" ] && exec $1 $2
 exec ./asschk --no-echo -DGPGSM=${GPGSM} <"$1"
-
diff --git a/tests/samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key b/tests/samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key
new file mode 100644 (file)
index 0000000..8236349
--- /dev/null
@@ -0,0 +1,10 @@
+(private-key
+ (rsa
+  (n #0093687D92A7BCD1E6FC11263B50657A8FA4B9CEE3F90E23384D62778CA1B6CBE0F60B20354A5F74899EB3C8DDF3081D32475C71869BB0C5DAF0051A2F44596E7406F1DCC7B29D88735E49341F09F4DFCAB5A08B76614C37220CF7E2CDB8A38E79644F3A250FFAE5D0BBA6917C67523D2812FDE8D3BEA9947F6A55402B1600C12F#)
+  (e #010001#)
+  (d #11BAAE926B54482C04EDE1C59E877B5F382114F8D1BAAE926B54482C04EDE1C59E877B5F382114F8D1BAAE926B54482C04EDE1C59E877B5F382114F8D1BAAE905D3988DFC39FEF462A0655AC906CBC12F6D322795D3988DFC39FEF462A0655AC906CBC12F6D322795D3988DFC39FEF462A0655AC906CBC12F6D322795D3983C1#)
+  (p "\x00ÂBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAÏ")
+  (q "\x00ÂBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB¡")
+  (u #00B28879D8EEE03F5546A5BBAD0C2213728879D8EEE03F5546A5BBAD0C2213728879D8EEE03F5546A5BBAD0C2213728879D8EEE03F5546A5BBAD0C221372887A30#)
+  )
+ )
index 57ece0d..65255cb 100644 (file)
@@ -1,6 +1,6 @@
 This is a collection of keys we use with the regression tests.
 
-opensc-tests.p12   PKCS#12 key and certificates taken from OpenSC. 
+opensc-tests.p12   PKCS#12 key and certificates taken from OpenSC.
                   Passphrase is "password"
 
 ov-user.p12        Private tests keys from www.openvalidation.org.
@@ -15,6 +15,10 @@ webdeca.der        trust.web.de CA certificate [2004-02-17]
 
 gte.pem            GTE CyberTrust Global Root
 
+cert-with-117-akas.pem  A certificate with 117 subjectAltNames.
 
+steed-self-signing-nonthority.pem
+                   The STEED Self-Signing Nonthority.
+68A638998DFABAC510EA645CE34F9686B2EDF7EA.key
+                   The private Key of The STEED Self-Signing Nonthority.
 
-                 
diff --git a/tests/samplekeys/cert-with-117-akas.pem b/tests/samplekeys/cert-with-117-akas.pem
new file mode 100644 (file)
index 0000000..bd0a7ea
--- /dev/null
@@ -0,0 +1,214 @@
+Issuer ...: /CN=DigiCert High Assurance CA-3/OU=www.digicert.com/O=DigiCert Inc/C=US
+Serial ...: 01CB9ACED2544126AD07590F62BCA367
+Subject ..: /CN=edgecastcdn.net/O=EdgeCast Networks Inc./L=SANTA MONICA/ST=California/C=US
+    aka ..: (dns-name edgecastcdn.net)
+    aka ..: (dns-name ne.edgecastcdn.net)
+    aka ..: (dns-name minitab.fileburst.com)
+    aka ..: (dns-name cdn.montimbrenligne.laposte.fr)
+    aka ..: (dns-name zeroknowledge.fileburst.com)
+    aka ..: (dns-name images.goldstarbeta.com)
+    aka ..: (dns-name radialpoint.fileburst.com)
+    aka ..: (dns-name wac.edgecastcdn.net)
+    aka ..: (dns-name ne.wac.edgecastcdn.net)
+    aka ..: (dns-name images.goldstar.com)
+    aka ..: (dns-name images.vrbo.com)
+    aka ..: (dns-name cdn.vrbo.com)
+    aka ..: (dns-name content.truste.com)
+    aka ..: (dns-name e1.boxcdn.net)
+    aka ..: (dns-name e2.boxcdn.net)
+    aka ..: (dns-name e3.boxcdn.net)
+    aka ..: (dns-name privacy-policy.truste.com)
+    aka ..: (dns-name www.sonos.com)
+    aka ..: (dns-name www.dickiesgirl.com)
+    aka ..: (dns-name static-cache.tp-global.net)
+    aka ..: (dns-name images.homeawayrealestate.com)
+    aka ..: (dns-name cdn.verint.com)
+    aka ..: (dns-name swf.mixpo.com)
+    aka ..: (dns-name cdn.traceregister.com)
+    aka ..: (dns-name s.tmocache.com)
+    aka ..: (dns-name s.my.tmocache.com)
+    aka ..: (dns-name ne1.wpc.edgecastcdn.net)
+    aka ..: (dns-name gp1.wpc.edgecastcdn.net)
+    aka ..: (dns-name gs1.wpc.edgecastcdn.net)
+    aka ..: (dns-name ne1.wac.edgecastcdn.net)
+    aka ..: (dns-name gp1.wac.edgecastcdn.net)
+    aka ..: (dns-name gs1.wac.edgecastcdn.net)
+    aka ..: (dns-name c1.socialcastcontent.com)
+    aka ..: (dns-name www.steepandcheap.com)
+    aka ..: (dns-name www.whiskeymilitia.com)
+    aka ..: (dns-name www.chainlove.com)
+    aka ..: (dns-name www.tramdock.com)
+    aka ..: (dns-name www.bonktown.com)
+    aka ..: (dns-name www.brociety.com)
+    aka ..: (dns-name www.mozilla.com)
+    aka ..: (dns-name resources.homeaway.com)
+    aka ..: (dns-name ssl-cdn.sometrics.com)
+    aka ..: (dns-name cache.vehicleassets.captivelead.com)
+    aka ..: (dns-name static.woopra.com)
+    aka ..: (dns-name images.cardstore.com)
+    aka ..: (dns-name images.ink2.com)
+    aka ..: (dns-name resources.homeawayrealestate.com)
+    aka ..: (dns-name cdn1.adadvisor.net)
+    aka ..: (dns-name www.pictureitpostage.com)
+    aka ..: (dns-name images.vacationrentals.com)
+    aka ..: (dns-name serviceportal.carestreamhealth.com)
+    aka ..: (dns-name assets-secure.razoo.com)
+    aka ..: (dns-name resources.vacationrentals.com)
+    aka ..: (dns-name download.entraction.com)
+    aka ..: (dns-name ec.pond5.com)
+    aka ..: (dns-name images.esellerpro.com)
+    aka ..: (dns-name use.typekit.com)
+    aka ..: (dns-name www.experian.co.za)
+    aka ..: (dns-name static.iseatz.com)
+    aka ..: (dns-name netstor.adbrite.com)
+    aka ..: (dns-name static.www.turnto.com)
+    aka ..: (dns-name cdn.static.viddler.com)
+    aka ..: (dns-name edgecast.onegrp.com)
+    aka ..: (dns-name cdn.psw.net)
+    aka ..: (dns-name cdn.media910.whipplehill.net)
+    aka ..: (dns-name cdn.gaggle.net)
+    aka ..: (dns-name cdn.selectica.com)
+    aka ..: (dns-name inpath-static.iseatz.com)
+    aka ..: (dns-name secure.newmediamanager.com)
+    aka ..: (dns-name secure.avelleassets.com)
+    aka ..: (dns-name secure-delivery.rovion.com)
+    aka ..: (dns-name cdn.media34.whipplehill.net)
+    aka ..: (dns-name cdn.media56.whipplehill.net)
+    aka ..: (dns-name cdn.media78.whipplehill.net)
+    aka ..: (dns-name secure1.mlspcdn.net)
+    aka ..: (dns-name secure01.mlspcdn.net)
+    aka ..: (dns-name static.dubli.com)
+    aka ..: (dns-name cdn.sightspeed.com)
+    aka ..: (dns-name cdn.sightspeed.ca)
+    aka ..: (dns-name cdn.sightspeed.biz)
+    aka ..: (dns-name cdn.sightspeed.net)
+    aka ..: (dns-name cdn.sightspeed.be)
+    aka ..: (dns-name www-cdn.cinamuse.com)
+    aka ..: (dns-name www-cdn.cineble.com)
+    aka ..: (dns-name www-cdn.cinemaden.com)
+    aka ..: (dns-name www-cdn.filmlush.com)
+    aka ..: (dns-name www-cdn.flixaddict.com)
+    aka ..: (dns-name www-cdn.itshd.com)
+    aka ..: (dns-name www-cdn.moviease.com)
+    aka ..: (dns-name www-cdn.movielush.com)
+    aka ..: (dns-name www-cdn.reelhd.com)
+    aka ..: (dns-name www-cdn.reelvidz.com)
+    aka ..: (dns-name www-cdn.pushplay.com)
+    aka ..: (dns-name cdn1.fishpond.co.nz)
+    aka ..: (dns-name cdn1.fishpond.com.au)
+    aka ..: (dns-name fast.fonts.com)
+    aka ..: (dns-name cdn.isaca.org)
+    aka ..: (dns-name www.isaca.org)
+    aka ..: (dns-name cdn.optimizely.com)
+    aka ..: (dns-name static.shoedazzle.com)
+    aka ..: (dns-name cluster.online.isheriff.com)
+    aka ..: (dns-name www.travelrepublic.co.uk)
+    aka ..: (dns-name cdn-thumbs.viddler.com)
+    aka ..: (dns-name Stage.treadmilldoctor.com)
+    aka ..: (dns-name beta.fileblaze.net)
+    aka ..: (dns-name cdn.nprove.com)
+    aka ..: (dns-name www.extremefitnessresults.com)
+    aka ..: (dns-name ec.xnglobalres.com)
+    aka ..: (dns-name images.affinitysolutions.com)
+    aka ..: (dns-name securedr.33across.com)
+    aka ..: (dns-name sslbest.booztx.com)
+    aka ..: (dns-name www.travelrepublic.com)
+    aka ..: (dns-name www.adbrite.com)
+    aka ..: (dns-name www.blacklabelads.com)
+    aka ..: (dns-name data.schwabenorthamerica.com)
+    aka ..: (dns-name media.schwabenorthamerica.com)
+    aka ..: (dns-name cdn.whois.com.au)
+
+-----BEGIN CERTIFICATE-----
+MIIQ5jCCD86gAwIBAgIQAcuaztJUQSatB1kPYryjZzANBgkqhkiG9w0BAQUFADBm
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBDQS0zMB4XDTEwMDEyNzAwMDAwMFoXDTExMDQyNzIzNTk1OVowdDELMAkGA1UE
+BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFTATBgNVBAcTDFNBTlRBIE1PTklD
+QTEfMB0GA1UEChMWRWRnZUNhc3QgTmV0d29ya3MgSW5jLjEYMBYGA1UEAxMPZWRn
+ZWNhc3RjZG4ubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuK5V
+1nGoCRPLM/7fOM4QL3vv9W+7e6Gs3lvyMoTL3zieqzuAGpyM9Cs7vRv2g/rZ49l2
+KgzbNK9+JIee0LC2cTFbQuE9DaVXRGLo8dAhnP0cFMbErcxehWdY2uItl5RdxGzB
+YPvOTMBFpLgzqjqqvN0auTI0IYbszE4GIcJQQm6EnT4/eQ3FVCrDo26j4itj8VP+
+jBvypzPdoTmSCbRABcp30IQPsV0kt1HM8ONyaMNk7+zx5OHLuBbSKcyFmvdkiT4W
+x7/Q3dBh5Rx91uToIBoFIgeglmS3O4/qPnQdgQyXHAP/gnMKA00aY7qVJ54NrqxB
+k7/C8G1EXsADplT5gwIDAQABo4INgDCCDXwwHwYDVR0jBBgwFoAUUOpzidsp+xCP
+nuUBINTeeZlIg/cwHQYDVR0OBBYEFDQ6+zUrIfo4JLXmdSig/Shl8CedMIIKSQYD
+VR0RBIIKQDCCCjyCD2VkZ2VjYXN0Y2RuLm5ldIISbmUuZWRnZWNhc3RjZG4ubmV0
+ghVtaW5pdGFiLmZpbGVidXJzdC5jb22CHmNkbi5tb250aW1icmVubGlnbmUubGFw
+b3N0ZS5mcoIbemVyb2tub3dsZWRnZS5maWxlYnVyc3QuY29tghdpbWFnZXMuZ29s
+ZHN0YXJiZXRhLmNvbYIZcmFkaWFscG9pbnQuZmlsZWJ1cnN0LmNvbYITd2FjLmVk
+Z2VjYXN0Y2RuLm5ldIIWbmUud2FjLmVkZ2VjYXN0Y2RuLm5ldIITaW1hZ2VzLmdv
+bGRzdGFyLmNvbYIPaW1hZ2VzLnZyYm8uY29tggxjZG4udnJiby5jb22CEmNvbnRl
+bnQudHJ1c3RlLmNvbYINZTEuYm94Y2RuLm5ldIINZTIuYm94Y2RuLm5ldIINZTMu
+Ym94Y2RuLm5ldIIZcHJpdmFjeS1wb2xpY3kudHJ1c3RlLmNvbYINd3d3LnNvbm9z
+LmNvbYITd3d3LmRpY2tpZXNnaXJsLmNvbYIac3RhdGljLWNhY2hlLnRwLWdsb2Jh
+bC5uZXSCHWltYWdlcy5ob21lYXdheXJlYWxlc3RhdGUuY29tgg5jZG4udmVyaW50
+LmNvbYINc3dmLm1peHBvLmNvbYIVY2RuLnRyYWNlcmVnaXN0ZXIuY29tgg5zLnRt
+b2NhY2hlLmNvbYIRcy5teS50bW9jYWNoZS5jb22CF25lMS53cGMuZWRnZWNhc3Rj
+ZG4ubmV0ghdncDEud3BjLmVkZ2VjYXN0Y2RuLm5ldIIXZ3MxLndwYy5lZGdlY2Fz
+dGNkbi5uZXSCF25lMS53YWMuZWRnZWNhc3RjZG4ubmV0ghdncDEud2FjLmVkZ2Vj
+YXN0Y2RuLm5ldIIXZ3MxLndhYy5lZGdlY2FzdGNkbi5uZXSCGGMxLnNvY2lhbGNh
+c3Rjb250ZW50LmNvbYIVd3d3LnN0ZWVwYW5kY2hlYXAuY29tghZ3d3cud2hpc2tl
+eW1pbGl0aWEuY29tghF3d3cuY2hhaW5sb3ZlLmNvbYIQd3d3LnRyYW1kb2NrLmNv
+bYIQd3d3LmJvbmt0b3duLmNvbYIQd3d3LmJyb2NpZXR5LmNvbYIPd3d3Lm1vemls
+bGEuY29tghZyZXNvdXJjZXMuaG9tZWF3YXkuY29tghVzc2wtY2RuLnNvbWV0cmlj
+cy5jb22CI2NhY2hlLnZlaGljbGVhc3NldHMuY2FwdGl2ZWxlYWQuY29tghFzdGF0
+aWMud29vcHJhLmNvbYIUaW1hZ2VzLmNhcmRzdG9yZS5jb22CD2ltYWdlcy5pbmsy
+LmNvbYIgcmVzb3VyY2VzLmhvbWVhd2F5cmVhbGVzdGF0ZS5jb22CEmNkbjEuYWRh
+ZHZpc29yLm5ldIIYd3d3LnBpY3R1cmVpdHBvc3RhZ2UuY29tghppbWFnZXMudmFj
+YXRpb25yZW50YWxzLmNvbYIic2VydmljZXBvcnRhbC5jYXJlc3RyZWFtaGVhbHRo
+LmNvbYIXYXNzZXRzLXNlY3VyZS5yYXpvby5jb22CHXJlc291cmNlcy52YWNhdGlv
+bnJlbnRhbHMuY29tghdkb3dubG9hZC5lbnRyYWN0aW9uLmNvbYIMZWMucG9uZDUu
+Y29tghVpbWFnZXMuZXNlbGxlcnByby5jb22CD3VzZS50eXBla2l0LmNvbYISd3d3
+LmV4cGVyaWFuLmNvLnphghFzdGF0aWMuaXNlYXR6LmNvbYITbmV0c3Rvci5hZGJy
+aXRlLmNvbYIVc3RhdGljLnd3dy50dXJudG8uY29tghZjZG4uc3RhdGljLnZpZGRs
+ZXIuY29tghNlZGdlY2FzdC5vbmVncnAuY29tggtjZG4ucHN3Lm5ldIIcY2RuLm1l
+ZGlhOTEwLndoaXBwbGVoaWxsLm5ldIIOY2RuLmdhZ2dsZS5uZXSCEWNkbi5zZWxl
+Y3RpY2EuY29tghhpbnBhdGgtc3RhdGljLmlzZWF0ei5jb22CGnNlY3VyZS5uZXdt
+ZWRpYW1hbmFnZXIuY29tghdzZWN1cmUuYXZlbGxlYXNzZXRzLmNvbYIac2VjdXJl
+LWRlbGl2ZXJ5LnJvdmlvbi5jb22CG2Nkbi5tZWRpYTM0LndoaXBwbGVoaWxsLm5l
+dIIbY2RuLm1lZGlhNTYud2hpcHBsZWhpbGwubmV0ghtjZG4ubWVkaWE3OC53aGlw
+cGxlaGlsbC5uZXSCE3NlY3VyZTEubWxzcGNkbi5uZXSCFHNlY3VyZTAxLm1sc3Bj
+ZG4ubmV0ghBzdGF0aWMuZHVibGkuY29tghJjZG4uc2lnaHRzcGVlZC5jb22CEWNk
+bi5zaWdodHNwZWVkLmNhghJjZG4uc2lnaHRzcGVlZC5iaXqCEmNkbi5zaWdodHNw
+ZWVkLm5ldIIRY2RuLnNpZ2h0c3BlZWQuYmWCFHd3dy1jZG4uY2luYW11c2UuY29t
+ghN3d3ctY2RuLmNpbmVibGUuY29tghV3d3ctY2RuLmNpbmVtYWRlbi5jb22CFHd3
+dy1jZG4uZmlsbWx1c2guY29tghZ3d3ctY2RuLmZsaXhhZGRpY3QuY29tghF3d3ct
+Y2RuLml0c2hkLmNvbYIUd3d3LWNkbi5tb3ZpZWFzZS5jb22CFXd3dy1jZG4ubW92
+aWVsdXNoLmNvbYISd3d3LWNkbi5yZWVsaGQuY29tghR3d3ctY2RuLnJlZWx2aWR6
+LmNvbYIUd3d3LWNkbi5wdXNocGxheS5jb22CE2NkbjEuZmlzaHBvbmQuY28ubnqC
+FGNkbjEuZmlzaHBvbmQuY29tLmF1gg5mYXN0LmZvbnRzLmNvbYINY2RuLmlzYWNh
+Lm9yZ4INd3d3LmlzYWNhLm9yZ4ISY2RuLm9wdGltaXplbHkuY29tghVzdGF0aWMu
+c2hvZWRhenpsZS5jb22CG2NsdXN0ZXIub25saW5lLmlzaGVyaWZmLmNvbYIYd3d3
+LnRyYXZlbHJlcHVibGljLmNvLnVrghZjZG4tdGh1bWJzLnZpZGRsZXIuY29tghlT
+dGFnZS50cmVhZG1pbGxkb2N0b3IuY29tghJiZXRhLmZpbGVibGF6ZS5uZXSCDmNk
+bi5ucHJvdmUuY29tgh13d3cuZXh0cmVtZWZpdG5lc3NyZXN1bHRzLmNvbYISZWMu
+eG5nbG9iYWxyZXMuY29tghxpbWFnZXMuYWZmaW5pdHlzb2x1dGlvbnMuY29tghVz
+ZWN1cmVkci4zM2Fjcm9zcy5jb22CEnNzbGJlc3QuYm9venR4LmNvbYIWd3d3LnRy
+YXZlbHJlcHVibGljLmNvbYIPd3d3LmFkYnJpdGUuY29tghV3d3cuYmxhY2tsYWJl
+bGFkcy5jb22CHGRhdGEuc2Nod2FiZW5vcnRoYW1lcmljYS5jb22CHW1lZGlhLnNj
+aHdhYmVub3J0aGFtZXJpY2EuY29tghBjZG4ud2hvaXMuY29tLmF1MH8GCCsGAQUF
+BwEBBHMwcTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEkG
+CCsGAQUFBzAChj1odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DQUNlcnRzL0RpZ2lD
+ZXJ0SGlnaEFzc3VyYW5jZUNBLTMuY3J0MA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMB
+Af8EAjAAMGUGA1UdHwReMFwwLKAqoCiGJmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
+bS9jYTMtMjAxMGUuY3JsMCygKqAohiZodHRwOi8vY3JsNC5kaWdpY2VydC5jb20v
+Y2EzLTIwMTBlLmNybDCCAcYGA1UdIASCAb0wggG5MIIBtQYLYIZIAYb9bAEDAAEw
+ggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9zc2wtY3Bz
+LXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUA
+cwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMA
+bwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYA
+IAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQA
+IAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUA
+bQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkA
+dAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAA
+aABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMB0GA1UdJQQW
+MBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQUFAAOCAQEAF5t9RFi9
+kNvWJvXEMVW+zQy6mX/lSHNT/HbzM88IxILLkHAftqjpnoQIVHThYwRjC5r7oKzT
+Y0HQCXeYaDIcH/ZtTT6v9mPohWlAKll9ybSxAVOOgN7DdS37TyDcnuI48WKlt3xG
+O5KGf8Gm/K4zULTrCbhQIkAW9C+cTqDb7dDfZishCISI0LiD+89JYOlZMEBuKV+C
+JDvk26pb9LYb6SsNRCdSVeHvDHXIHX+KxLqihVxDMiZ4fLUmaqD5V3jz81tZQS/l
+hPsrXOlqOlPkYOLMx7lzxlVen11oXPBXYLr7dU8JnB4Uma5YmHkGR7NwJAtnOVva
+hOtjHlYyP39bzQ==
+-----END CERTIFICATE-----
diff --git a/tests/samplekeys/steed-self-signing-nonthority.pem b/tests/samplekeys/steed-self-signing-nonthority.pem
new file mode 100644 (file)
index 0000000..c6a9c54
--- /dev/null
@@ -0,0 +1,54 @@
+
+           ID: 0x72B0BD08
+          S/N: 01
+       Issuer: CN=The STEED Self-Signing Nonthority
+      Subject: CN=The STEED Self-Signing Nonthority
+     sha1_fpr: E6:99:39:A2:5F:5D:93:F2:06:71:5D:C9:FC:1A:25:DC:72:B0:BD:08
+      md5_fpr: C9:83:C8:13:91:53:5A:C2:9A:BA:AF:0E:9C:AF:93:0E
+       certid: BA9A5990A0E94A627D08D4D06FD15EC561FD15E8.01
+      keygrip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
+    notBefore: 2011-11-11 00:00:00
+     notAfter: 2106-02-06 00:00:00
+     hashAlgo: 1.2.840.113549.1.1.5 (sha1WithRSAEncryption)
+      keyType: 1024 bit RSA
+    subjKeyId: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
+    authKeyId: [none]
+     keyUsage: certSign crlSign
+  extKeyUsage: [none]
+     policies: [none]
+  chainLength: 1
+        crlDP: [none]
+     authInfo: [none]
+     subjInfo: [none]
+         extn: 1.3.6.1.4.1.11591.2.2.2 (wellKnownPrivateKey)  [3 octets]
+
+
+-----BEGIN CERTIFICATE-----
+MIICKDCCAZGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAsMSowKAYDVQQDEyFUaGUg
+U1RFRUQgU2VsZi1TaWduaW5nIE5vbnRob3JpdHkwIBcNMTExMTExMDAwMDAwWhgP
+MjEwNjAyMDYwMDAwMDBaMCwxKjAoBgNVBAMTIVRoZSBTVEVFRCBTZWxmLVNpZ25p
+bmcgTm9udGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAk2h9kqe8
+0eb8ESY7UGV6j6S5zuP5DiM4TWJ3jKG2y+D2CyA1Sl90iZ6zyN3zCB0yR1xxhpuw
+xdrwBRovRFludAbx3MeynYhzXkk0Hwn038q1oIt2YUw3Igz34s24o455ZE86JQ/6
+5dC7ppF8Z1I9KBL96NO+qZR/alVAKxYAwS8CAwEAAaNYMFYwEgYDVR0TAQH/BAgw
+BgEB/wIBATARBgorBgEEAdpHAgICBAMBAf8wHQYDVR0OBBYEFGimOJmN+rrFEOpk
+XONPloay7ffqMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQB3JwUn
+AbOdGv5ErojNSSP+yGZIy5av4wnkzK840Uj3jY6A5cuHroZGOD60hqLV2Hy0npox
+zte4phWEKWmZiXd8SCmd3MFNgZSieiixye0qxSmuqYft2j6NhEXD5xc/iTTjFT42
+SjGPLKAICuMBuGPnoozOEVlgqwaDqKOUph5sqw==
+-----END CERTIFICATE-----
+
+Created using these parameters:
+
+  Key-Type: RSA
+  Key-Length: 1024
+  Key-Grip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
+  Key-Usage: cert
+  Serial: 1
+  Name-DN: CN=The STEED Self-Signing Nonthority
+  Not-Before: 2011-11-11
+  Not-After: 2106-02-06
+  Subject-Key-Id: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
+  Extension: 2.5.29.19 c 30060101ff020101
+  Extension: 1.3.6.1.4.1.11591.2.2.2 n 0101ff
+  Signing-Key: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
index 1eca0b5..6821a87 100644 (file)
-2011-12-02  Werner Koch  <wk@g10code.com>
+2011-12-01  Werner Koch  <wk@g10code.com>
 
        NB: ChangeLog files are no longer manually maintained.  Starting
        on December 1st, 2011 we put change information only in the GIT
        commit log, and generate a top-level ChangeLog file from logs at
        "make dist".  See doc/HACKING for details.
 
-2011-08-04  Werner Koch  <wk@g10code.com>
+2011-08-26  Werner Koch  <wk@g10code.com>
 
-       * symcryptrun.c: Include utmp.h for login_tty.
+       * gpgconf-comp.c (gc_component): Mark for translation.  Suggested
+       by Yuri Chornoivan.
 
-       * gpgconf-comp.c (gc_process_gpgconf_conf): Remove unsued var
-       USED_COMPONENTS.
+2011-03-08  Werner Koch  <wk@g10code.com>
 
-2011-01-11  Werner Koch  <wk@g10code.com>
+       * symcryptrun.c [HAVE_UTMP_H]: Include utmp.h.
 
-        * gpgtar.c, gpgtar.h, gpgtar-create.c, gpgtar-extract.c
-        * gpgtar-list.c: New.  Take from GnuPG master and add missing
-       functions.
-       * Makefile.am (bin_PROGRAMS): Add gpgtar.
-       (gpgtar_SOURCES, gpgtar_CFLAGS, gpgtar_LDADD): New.
+2011-02-23  Werner Koch  <wk@g10code.com>
+
+       * gpgconf.c: Add command --kill.
+       * gpgconf-comp.c (gc_component_kill): New.
+       (gpg_agent_runtime_change, scdaemon_runtime_change): Add kill flag.
+
+2011-02-03  Werner Koch  <wk@g10code.com>
+
+       * watchgnupg.c (print_version): Update copyright year.
+
+2010-12-14  Werner Koch  <wk@g10code.com>
+
+       * gpgconf-comp.c (gc_options_gpg_agent, gc_options_scdaemon)
+       (gc_options_gpg, gc_options_gpgsm, gc_options_dirmngr): Define to
+       NULL if corresponding BUILD_WITH_foo is not defined.
+
+2010-12-02  Werner Koch  <wk@g10code.com>
+
+       * no-libgcrypt.c (gcry_cipher_algo_name): New.
+
+2010-11-23  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (gpgconf_LDFLAGS): Add extra_bin_ldflags.
+
+2010-11-17  Marcus Brinkmann  <mb@g10code.com>
+
+       * gogconf.c: Revert accidental debug output commit.
+
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * symcryptrun.c (confucius_mktmpdir): Use TMPDIR.
+
+2010-10-14  Werner Koch  <wk@g10code.com>
+
+       * gpg-connect-agent.c: Add option --agent-program.
+
+       * gpg-connect-agent.c (start_agent): Rewrite using the
+       start_new_gpg_agent function.
+
+       * gpgconf-comp.c (gpg_agent_runtime_change): Use gpg-connect-agent
+       on all platforms.
+
+2010-10-06  Werner Koch  <wk@g10code.com>
+
+       * watchgnupg.c (print_version): Add option --time-only.
+
+2010-10-05  Werner Koch  <wk@g10code.com>
+
+       * watchgnupg.c (main): Support TCP and local socket listening.
+       (main): Factor some code out to ..
+       (setup_client): this.
+       (err): New.
+       (client_list): New.
+
+2010-08-25  Werner Koch  <wk@g10code.com>
+
+       * gpgtar-extract.c (create_directory): Add .p7m as known
+       extension.
+
+       * gpgtar.c: Add -t as short option for --list-archive.
+       * gpgtar-extract.c (gpgtar_extract): Use filename "-" for stdin.
+       Fix dirprefix setting.
+       * gpgtar-list.c (gpgtar_list): Ditto.
+
+2010-08-24  Werner Koch  <wk@g10code.com>
+
+       * gpgtar.c (opts): Fix --cms and --openpgp names.
 
 2010-08-23  Werner Koch  <wk@g10code.com>
 
+       * gpgconf-comp.c (GPGNAME) [W32CE]: s/gpg2/gpg/.
+       (get_config_filename) [W32CE]: Adjust absolute file name check.
+
        * gpgconf-comp.c (retrieve_options_from_program)
-       (retrieve_options_from_file, copy_file): Do not use ferror after a
-       failed fclose.  Note that the stream is in any case invalid after
-       calling fclose and that fclose does set ERRNO.
+       (retrieve_options_from_file, retrieve_options_from_program)
+       (copy_file, gc_process_gpgconf_conf): Do not use es_ferror after a
+       failed es_fclose.  Note that the stream is in any case invalid
+       after calling es_fclose and that es_fclose does set ERRNO.
+
+       * Makefile.am (maybe_commonpth_libs): New.
+       (gpgconf_LDADD): Use it.
+
+2010-08-20  Werner Koch  <wk@g10code.com>
+
+       * gpgconf-comp.c (collect_error_output): Remove extra CRs.
 
 2010-08-19  Werner Koch  <wk@g10code.com>
 
        * gpgconf.c (main): Fix --check-options.
 
-2010-02-11  Marcus Brinkmann  <marcus@g10code.de>
+       * gpgconf-comp.c (gc_component_check_options): Replace
+       gnupg_spawn_process_fd by gnupg_spawn_process.
+       (retrieve_options_from_program): Ditto.
+       (collect_error_output): Change to use estream.
 
-       From 2009-09-23, 2009-11-04, 2009-11-05, 2009-12-08:
+       * gpgconf-comp.c: Add new backend and component for PINENTRY.
+       (gc_component_check_options): Use --version to test the pinentry.
+       (gc_component_retrieve_options, gc_component_change_options):
+       Ignore the pinentry component.
 
-       * gpg-connect-agent.c (read_and_print_response): Add arg WITHHASH.
-       (getinfo_pid_cb, read_and_print_response)
-       (main): Pass true for WITHHASH for the HELP command.  Update to
-       new Assuan API.  Update use of assuan_socket_connect and
-       assuan_pipe_connect.  Convert posix fd to assuan fd.
+2010-08-16  Werner Koch  <wk@g10code.com>
+
+       * gpgconf.c (get_outfp): Change to use estream.
+       (main): Replace fprintf by es_fprintf.
+       * gpgconf-comp.c (gc_component_list_components)
+       (gc_check_programs, gc_component_list_options)
+       (gc_component_change_options, gc_component_check_options)
+       (list_one_option, gc_process_gpgconf_conf): Replace FILE* args by
+       estream_t.
+
+2010-08-13  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (gpgkey2ssh_LDADD): Add NETLIBS.
+
+2010-08-11  Werner Koch  <wk@g10code.com>
+
+       * gpgtar-create.c (gpgtar_create): Allow "-" for stdout in
+       opt.outfile.  Switch es_stdout to binary mode.
+
+2010-08-09  Werner Koch  <wk@g10code.com>
+
+       * watchgnupg.c: Inlcude in.h and inet.h.
+       (main): Support tcp connections.
+
+       * gpgtar.c (main): Add options -T and --null.
+       * gpgtar-create.c (gpgtar_create): Implement option --null.
+
+2010-07-16  Werner Koch  <wk@g10code.com>
+
+       * gpgtar-create.c: Rewrite to better support W32.
+
+2010-07-01  Werner Koch  <wk@g10code.com>
+
+       * gpgtar.c: Add option --set-filename.
+
+2010-06-24  Werner Koch  <wk@g10code.com>
+
+       * gpgconf-comp.c (gpg_agent_runtime_change)
+       (scdaemon_runtime_change, retrieve_options_from_program): Use HANG
+       option for gnupg_wait_progress.  Fixes regression from 2010-06-09.
+
+2010-06-07  Werner Koch  <wk@g10code.com>
+
+       * gpgtar.c, gpgtar.h, gpgtar-list.c, gpgtar-create.c
+       * gpgtar-extract.c: New.
+       * Makefile.am (commonpth_libs): New.
+       (gpgtar_SOURCES, gpgtar_CFLAGS, gpgtar_LDADD): New.
+       (bin_PROGRAMS) [!W32CE]: Add gpgtar.
+
+2010-04-20  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgconf-comp.c (option_check_validity): Use dummy variables to
+       silence gcc warning.
+
+2010-04-14  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (bin_PROGRAMS) [W32CE]: Exclude gpgkey2ssh.
+       (noinst_PROGRAMS) [W32CE]: Don't build them.
+       (pwquery_libs) [W32CE]: Set to empty.
+
+2010-03-25  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (opt_libassuan_libs) [W32CE]: New.
+       (gpgconf_LDADD): Use it.
+
+       * gpgconf-comp.c: Include signal.h only if available.  Use
+       gpg_err_set_errno.
+       (key_matches_user_or_group) [W32CE]: Do not match any user.
+
+2010-03-15  Werner Koch  <wk@g10code.com>
+
+       * gpgconf-comp.c (my_dgettext):
+       s/gettext_select_utf8/gettext_use_utf8/.
+
+2010-03-10  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (common_libs): Remove libjnlib.a.
+
+2010-03-08  Werner Koch  <wk@g10code.com>
+
+       * no-libgcrypt.c (gcry_create_nonce): New.
+
+2010-02-26  Werner Koch  <wk@g10code.com>
+
+       * gpg-connect-agent.c (main): New option --tcp-socket.
 
 2010-01-10  Werner Koch  <wk@g10code.com>
 
 
        * applygnupgdefaults (errorfile): Use mktemp.  Fixes bug#1146.
 
+2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpg-connect-agent.c (main): Convert posix fd to assuan fd.
+
 2009-12-07  Werner Koch  <wk@g10code.com>
 
        * no-libgcrypt.c (gcry_strdup): Actually copy the string.
 
+2009-11-23  Werner Koch  <wk@g10code.com>
+
+       * gpgconf-comp.c (gc_options_gpg): Add default_pubkey_algo.
+
+2009-11-05  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpg-connect-agent.c (start_agent): Update use of
+       assuan_socket_connect and assuan_pipe_connect.
+
+2009-11-04  Werner Koch  <wk@g10code.com>
+
+       * gpg-connect-agent.c (read_and_print_response): Add arg WITHHASH.
+       (main): Pass true for WITHHASH for the HELP command.
+
+2009-09-23  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpg-connect-agent.c (getinfo_pid_cb, read_and_print_response)
+       (main): Update to new Assuan API.
+
 2009-07-21  Werner Koch  <wk@g10code.com>
 
        * gpgsplit.c (my_strusage): Remove i18n stuff.
 
 
  Copyright 2003, 2004, 2005, 2006, 2007, 2008,
-          2009 Free Software Foundation, Inc.
+          2009, 2010, 2011 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
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index e5c16a2..340901a 100644 (file)
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
 EXTRA_DIST = \
-       Manifest watchgnupg.c ChangeLog-2011 \
+       Manifest watchgnupg.c \
        addgnupghome applygnupgdefaults gpgsm-gencert.sh \
        lspgpot mail-signed-keys convert-from-106 sockprox.c \
-       ccidmon.c gpg-connect-agent-w32info.rc
+       ccidmon.c ChangeLog-2011 gpg-connect-agent-w32info.rc
 
 
 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
@@ -30,7 +30,7 @@ if HAVE_W32_SYSTEM
 resource_objs += gpg-connect-agent-w32info.o
 endif
 
-AM_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS)
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
 
 sbin_SCRIPTS = addgnupghome applygnupgdefaults
 
@@ -52,31 +52,55 @@ else
   gpgtar =
 endif
 
-
-bin_PROGRAMS = gpgconf gpg-connect-agent gpgkey2ssh ${symcryptrun} ${gpgtar}
+# Fixme: We should remove the gpgkey2ssh tool.
+bin_PROGRAMS = gpgconf gpg-connect-agent ${symcryptrun}
 if !HAVE_W32_SYSTEM
 bin_PROGRAMS += watchgnupg gpgparsemail
 endif
+if !HAVE_W32CE_SYSTEM
+bin_PROGRAMS += gpgkey2ssh ${gpgtar}
+endif
 
 if !DISABLE_REGEX
 libexec_PROGRAMS = gpg-check-pattern
 endif
 
+if !HAVE_W32CE_SYSTEM
 noinst_PROGRAMS = clean-sat mk-tdata make-dns-cert gpgsplit
+endif
+
+common_libs = $(libcommon) ../gl/libgnu.a
+commonpth_libs = $(libcommonpth) ../gl/libgnu.a
 
-common_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a
+# Some modules require PTH under W32CE.
+if HAVE_W32CE_SYSTEM
+maybe_commonpth_libs = $(commonpth_libs)
+else
+maybe_commonpth_libs = $(common_libs)
+endif
+
+if HAVE_W32CE_SYSTEM
+pwquery_libs =
+else
 pwquery_libs = ../common/libsimple-pwquery.a
+endif
+
+if HAVE_W32CE_SYSTEM
+opt_libassuan_libs = $(LIBASSUAN_LIBS)
+endif
 
 gpgsplit_LDADD = $(common_libs) \
                 $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
-                $(ZLIBS) $(LIBINTL) $(LIBICONV)
+                $(ZLIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV)
 
 gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c
 
-# jnlib/common sucks in gpg-error, will they, nil they (some compilers
+# common sucks in gpg-error, will they, nil they (some compilers
 # do not eliminate the supposed-to-be-unused-inline-functions).
-gpgconf_LDADD = $(common_libs) \
-                $(LIBINTL) $(GPG_ERROR_LIBS) $(LIBICONV) $(W32SOCKLIBS)
+gpgconf_LDADD = $(maybe_commonpth_libs) $(opt_libassuan_libs) \
+                $(LIBINTL) $(GPG_ERROR_LIBS) $(NETLIBS) \
+               $(LIBICONV) $(W32SOCKLIBS)
+gpgconf_LDFLAGS = $(extra_bin_ldflags)
 
 gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h
 gpgparsemail_LDADD =
@@ -84,7 +108,7 @@ gpgparsemail_LDADD =
 symcryptrun_SOURCES = symcryptrun.c
 symcryptrun_LDADD = $(LIBUTIL_LIBS) $(common_libs) $(pwquery_libs) \
                     $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) \
-                    $(LIBICONV) $(W32SOCKLIBS)
+                    $(LIBICONV) $(NETLIBS) $(W32SOCKLIBS)
 
 watchgnupg_SOURCES = watchgnupg.c
 watchgnupg_LDADD = $(NETLIBS)
@@ -92,23 +116,25 @@ watchgnupg_LDADD = $(NETLIBS)
 gpg_connect_agent_SOURCES = gpg-connect-agent.c no-libgcrypt.c
 # FIXME: remove PTH_LIBS (why do we need them at all?)
 gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \
-                         $(LIBASSUAN_LIBS) $(PTH_LIBS) $(GPG_ERROR_LIBS) \
+                         $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
                           $(LIBREADLINE) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
-                         $(resource_objs)
+                          $(resource_objs)
 
+if !HAVE_W32CE_SYSTEM
 gpgkey2ssh_SOURCES = gpgkey2ssh.c
-gpgkey2ssh_CFLAGS =  $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS)
-# common sucks in jnlib, via use of BUG() in an inline function, which
+gpgkey2ssh_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
+# common via use of BUG() in an inline function, which
 # some compilers do not eliminate.
 gpgkey2ssh_LDADD = $(common_libs) \
-                   $(GPG_ERROR_LIBS) $(LIBGCRYPT_LIBS) $(LIBINTL) $(LIBICONV)
-
+                   $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) \
+                  $(NETLIBS)
+endif
 
 if !DISABLE_REGEX
 gpg_check_pattern_SOURCES = gpg-check-pattern.c
-gpg_check_pattern_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS)
+gpg_check_pattern_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
 gpg_check_pattern_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
-                          $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS)
+                          $(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS)
 endif
 
 gpgtar_SOURCES = \
@@ -118,10 +144,11 @@ gpgtar_SOURCES = \
        gpgtar-list.c \
        no-libgcrypt.c
 gpgtar_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
+#gpgtar_LDADD = $(commonpth_libs) $(PTH_LIBS) $(GPG_ERROR_LIBS)
 gpgtar_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
                $(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS)
 
+
 # Make sure that all libs are build before we use them.  This is
 # important for things like make -j2.
 $(PROGRAMS): $(common_libs) $(pwquery_libs) ../common/libgpgrl.a
-
index fb032b6..e13c3cd 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh                                               
+#!/bin/sh
 # Add a new .gnupg home directory for a list of users         -*- sh -*-
 #
 # Copyright 2004 Free Software Foundation, Inc.
@@ -89,7 +89,7 @@ one_user () {
 
 }
 
-if [ -z "$1" ]; then 
+if [ -z "$1" ]; then
     echo "usage: $PGM userids"
     exit 1
 fi
index b4cff63..2f29854 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh                                               
+#!/bin/sh
 # Apply defaults from /etc/gnupg/gpg.conf to all users             -*- sh -*-
 #
 # Copyright 2007 Free Software Foundation, Inc.
@@ -23,7 +23,7 @@ info () {
   echo "$PGM: $*" >&2
 }
 
-if [ -n "$1" ]; then 
+if [ -n "$1" ]; then
     echo "usage: $PGM" >&2
     exit 1
 fi
@@ -79,4 +79,3 @@ done
 
 [ "$(wc -c <$errorfile)" -gt 0 ] && exit 1
 exit 0
-
index 81fd531..1137bab 100644 (file)
@@ -145,7 +145,7 @@ err (const char *format, ...)
 static unsigned int
 convert_le_u32 (const unsigned char *buf)
 {
-  return buf[0] | (buf[1] << 8) | (buf[2] << 16) | ((unsigned int)buf[3] << 24);
+  return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
 }
 
 
@@ -641,7 +641,7 @@ parse_line (char *line, unsigned int lineno)
   char *event_type, *address, *data, *status, *datatag;
 
   if (debug)
-    printf ("line[%u] =`%s'\n", lineno, line);
+    printf ("line[%u] ='%s'\n", lineno, line);
 
   p = strtok (line, " ");
   if (!p)
@@ -700,7 +700,7 @@ parse_line_sniffusb (char *line, unsigned int lineno)
   char *p;
 
   if (debug)
-    printf ("line[%u] =`%s'\n", lineno, line);
+    printf ("line[%u] ='%s'\n", lineno, line);
 
   p = strtok (line, " \t");
   if (!p)
@@ -810,7 +810,7 @@ main (int argc, char **argv)
         }
       else if (!strcmp (*argv, "--version"))
         {
-          fputs (PGM " (GnuPG) " PACKAGE_VERSION "\n", stdout);
+          fputs (PGM " ("GNUPG_NAME") " PACKAGE_VERSION "\n", stdout);
           exit (0);
         }
       else if (!strcmp (*argv, "--help"))
index 4b44a7b..4848f97 100644 (file)
@@ -33,4 +33,3 @@ main(int argc, char **argv)
 
     return 0;
 }
-
index 8d15263..2db9ae5 100644 (file)
 #include "util.h"
 #include "i18n.h"
 #include "sysutils.h"
+#include "../common/init.h"
 
 
-enum cmd_and_opt_values 
+enum cmd_and_opt_values
 { aNull = 0,
   oVerbose       = 'v',
   oArmor          = 'a',
@@ -66,12 +67,12 @@ enum cmd_and_opt_values
 
 /* The list of commands and options.  */
 static ARGPARSE_OPTS opts[] = {
-    
+
   { 301, NULL, 0, N_("@Options:\n ") },
 
   { oVerbose, "verbose",   0, "verbose" },
 
-  { oHomedir, "homedir", 2, "@" }, 
+  { oHomedir, "homedir", 2, "@" },
   { oCheck,   "check", 0,  "run only a syntax check on the patternfile" },
   { oNull,    "null", 0,   "input is expected to be null delimited" },
 
@@ -80,7 +81,7 @@ static ARGPARSE_OPTS opts[] = {
 
 
 /* Global options are accessed through the usual OPT structure. */
-static struct 
+static struct
 {
   int verbose;
   const char *homedir;
@@ -99,7 +100,7 @@ enum {
 /* An object to decibe an item of our pattern table. */
 struct pattern_s
 {
-  int type;  
+  int type;
   unsigned int lineno;     /* Line number of the pattern file.  */
   union {
     struct {
@@ -111,7 +112,7 @@ struct pattern_s
          we need for PAT_STRING and we expect only a few regex in a
          patternfile.  It would be a waste of core to have so many
          unused stuff in the table.  */
-      regex_t *regex;      
+      regex_t *regex;
     } r; /*PAT_REGEX*/
   } u;
 };
@@ -134,21 +135,21 @@ my_strusage (int level)
   const char *p;
   switch (level)
     {
-    case 11: p = "gpg-check-pattern (GnuPG)";
+    case 11: p = "gpg-check-pattern (@GnuPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
 
     case 1:
-    case 40: 
+    case 40:
       p =  _("Usage: gpg-check-pattern [options] patternfile (-h for help)\n");
       break;
-    case 41: 
+    case 41:
       p =  _("Syntax: gpg-check-pattern [options] patternfile\n"
              "Check a passphrase given on stdin against the patternfile\n");
     break;
-    
+
     default: p = NULL;
     }
   return p;
@@ -165,11 +166,11 @@ main (int argc, char **argv )
 
   set_strusage (my_strusage);
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
-  log_set_prefix ("gpg-check-pattern", 1); 
+  log_set_prefix ("gpg-check-pattern", 1);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   /* We need Libgcrypt for hashing.  */
   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
@@ -194,13 +195,13 @@ main (int argc, char **argv )
         case oHomedir: opt.homedir = pargs.r.ret_str; break;
         case oCheck: opt.checkonly = 1; break;
         case oNull: opt.null = 1; break;
-          
+
         default : pargs.err = 2; break;
        }
     }
   if (log_get_errorcount(0))
     exit (2);
-  
+
   if (argc != 1)
     usage (1);
 
@@ -239,7 +240,7 @@ read_file (const char *fname, size_t *r_length)
   FILE *fp;
   char *buf;
   size_t buflen;
-  
+
   if (!strcmp (fname, "-"))
     {
       size_t nread, bufsize = 0;
@@ -251,7 +252,7 @@ read_file (const char *fname, size_t *r_length)
       buf = NULL;
       buflen = 0;
 #define NCHUNK 8192
-      do 
+      do
         {
           bufsize += NCHUNK;
           if (!buf)
@@ -262,7 +263,7 @@ read_file (const char *fname, size_t *r_length)
           nread = fread (buf+buflen, 1, NCHUNK, fp);
           if (nread < NCHUNK && ferror (fp))
             {
-              log_error ("error reading `[stdin]': %s\n", strerror (errno));
+              log_error ("error reading '[stdin]': %s\n", strerror (errno));
               xfree (buf);
               return NULL;
             }
@@ -279,22 +280,22 @@ read_file (const char *fname, size_t *r_length)
       fp = fopen (fname, "rb");
       if (!fp)
         {
-          log_error ("can't open `%s': %s\n", fname, strerror (errno));
+          log_error ("can't open '%s': %s\n", fname, strerror (errno));
           return NULL;
         }
-  
+
       if (fstat (fileno(fp), &st))
         {
-          log_error ("can't stat `%s': %s\n", fname, strerror (errno));
+          log_error ("can't stat '%s': %s\n", fname, strerror (errno));
           fclose (fp);
           return NULL;
         }
-      
+
       buflen = st.st_size;
       buf = xmalloc (buflen+1);
       if (fread (buf, buflen, 1, fp) != 1)
         {
-          log_error ("error reading `%s': %s\n", fname, strerror (errno));
+          log_error ("error reading '%s': %s\n", fname, strerror (errno));
           fclose (fp);
           xfree (buf);
           return NULL;
@@ -331,7 +332,7 @@ parse_pattern_file (char *data, size_t datalen)
   pattern_t *array;
   size_t arraysize, arrayidx;
   unsigned int lineno = 0;
-  
+
   /* Estimate the number of entries by counting the non-comment lines.  */
   arraysize = 0;
   p = data;
@@ -456,7 +457,7 @@ process (FILE *fp, pattern_t *patarray)
   int c;
   unsigned long lineno = 0;
   pattern_t *pat;
-  
+
   idx = 0;
   c = 0;
   while (idx < sizeof buffer -1 && c != EOF )
index 142bd30..78dea2a 100644 (file)
@@ -1,5 +1,6 @@
 /* gpg-connect-agent.c - Tool to connect to the agent.
- *     Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -37,6 +38,7 @@
 #ifdef HAVE_W32_SYSTEM
 #  include "../common/exechelp.h"
 #endif
+#include "../common/init.h"
 
 
 #define CONTROL_D ('D' - 'A' + 1)
@@ -49,15 +51,19 @@ enum cmd_and_opt_values
     oQuiet      = 'q',
     oVerbose   = 'v',
     oRawSocket  = 'S',
+    oTcpSocket  = 'T',
     oExec       = 'E',
     oRun        = 'r',
     oSubst      = 's',
 
     oNoVerbose = 500,
     oHomedir,
+    oAgentProgram,
+    oDirmngrProgram,
     oHex,
     oDecode,
-    oNoExtConnect
+    oNoExtConnect,
+    oDirmngr
 
   };
 
@@ -65,23 +71,28 @@ enum cmd_and_opt_values
 /* The list of commands and options. */
 static ARGPARSE_OPTS opts[] = {
   ARGPARSE_group (301, N_("@\nOptions:\n ")),
-    
+
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet, "quiet",     N_("quiet")),
   ARGPARSE_s_n (oHex,   "hex",       N_("print data out hex encoded")),
   ARGPARSE_s_n (oDecode,"decode",    N_("decode received data lines")),
-  ARGPARSE_s_s (oRawSocket, "raw-socket", 
+  ARGPARSE_s_n (oDirmngr,"dirmngr",  N_("connect to the dirmngr")),
+  ARGPARSE_s_s (oRawSocket, "raw-socket",
                 N_("|NAME|connect to Assuan socket NAME")),
-  ARGPARSE_s_n (oExec, "exec", 
+  ARGPARSE_s_s (oTcpSocket, "tcp-socket",
+                N_("|ADDR|connect to Assuan server at ADDR")),
+  ARGPARSE_s_n (oExec, "exec",
                 N_("run the Assuan server given on the command line")),
   ARGPARSE_s_n (oNoExtConnect, "no-ext-connect",
                 N_("do not use extended connect mode")),
-  ARGPARSE_s_s (oRun,  "run", 
+  ARGPARSE_s_s (oRun,  "run",
                 N_("|FILE|run commands from FILE on startup")),
-  ARGPARSE_s_n (oSubst, "subst",     N_("run /subst on startup")), 
+  ARGPARSE_s_n (oSubst, "subst",     N_("run /subst on startup")),
 
   ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
-  ARGPARSE_s_s (oHomedir, "homedir", "@" ),   
+  ARGPARSE_s_s (oHomedir, "homedir", "@" ),
+  ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
+  ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
 
   ARGPARSE_end ()
 };
@@ -93,9 +104,13 @@ struct
   int verbose;         /* Verbosity level.  */
   int quiet;           /* Be extra quiet.  */
   const char *homedir;  /* Configuration directory name */
+  const char *agent_program;  /* Value of --agent-program.  */
+  const char *dirmngr_program;  /* Value of --dirmngr-program.  */
   int hex;              /* Print data lines in hex format. */
   int decode;           /* Decode received data lines.  */
+  int use_dirmngr;      /* Use the dirmngr and not gpg-agent.  */
   const char *raw_socket; /* Name of socket to connect in raw mode. */
+  const char *tcp_socket; /* Name of server to connect in tcp mode. */
   int exec;             /* Run the pgm given on the command line. */
   unsigned int connect_flags;    /* Flags used for connecting. */
   int enable_varsubst;  /* Set if variable substitution is enabled.  */
@@ -174,17 +189,17 @@ my_strusage( int level )
 
   switch (level)
     {
-    case 11: p = "gpg-connect-agent (GnuPG)";
+    case 11: p = "@GPG@-connect-agent (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
 
     case 1:
-    case 40: p = _("Usage: gpg-connect-agent [options] (-h for help)");
+    case 40: p = _("Usage: @GPG@-connect-agent [options] (-h for help)");
       break;
     case 41:
-      p = _("Syntax: gpg-connect-agent [options]\n"
+      p = _("Syntax: @GPG@-connect-agent [options]\n"
             "Connect to a running agent and send commands\n");
       break;
     case 31: p = "\nHome: "; break;
@@ -197,25 +212,6 @@ my_strusage( int level )
 }
 
 
-static char *
-gnu_getcwd (void)
-{
-  char *buffer;
-  size_t size = 100;
-
-  for (;;)
-    {
-      buffer = xmalloc (size+1);
-      if (getcwd (buffer, size) == buffer)
-        return buffer;
-      xfree (buffer);
-      if (errno != ERANGE)
-        return NULL;
-      size *= 2;
-    }
-}
-
-
 /* Unescape STRING and returned the malloced result.  The surrounding
    quotes must already be removed from STRING.  */
 static char *
@@ -234,22 +230,22 @@ unescape_string (const char *string)
         {
           switch (*s)
             {
-            case 'b':  
-            case 't':  
-            case 'v':  
-            case 'n':  
-            case 'f':  
-            case 'r':  
-            case '"':  
-            case '\'': 
+            case 'b':
+            case 't':
+            case 'v':
+            case 'n':
+            case 'f':
+            case 'r':
+            case '"':
+            case '\'':
             case '\\': n++; break;
-            case 'x': 
+            case 'x':
               if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
                 n++;
               break;
 
             default:
-              if (s[1] && s[2] 
+              if (s[1] && s[2]
                   && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
                 n++;
               break;
@@ -260,7 +256,7 @@ unescape_string (const char *string)
         esc = 1;
       else
         n++;
-    } 
+    }
 
   buffer = xmalloc (n+1);
   d = (unsigned char*)buffer;
@@ -279,7 +275,7 @@ unescape_string (const char *string)
             case '"':  *d++ = '\"'; break;
             case '\'': *d++ = '\''; break;
             case '\\': *d++ = '\\'; break;
-            case 'x': 
+            case 'x':
               if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
                 {
                   s++;
@@ -289,7 +285,7 @@ unescape_string (const char *string)
               break;
 
             default:
-              if (s[1] && s[2] 
+              if (s[1] && s[2]
                   && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
                 {
                   *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
@@ -303,7 +299,7 @@ unescape_string (const char *string)
         esc = 1;
       else
         *d++ = *s;
-    } 
+    }
   *d = 0;
   return buffer;
 }
@@ -322,7 +318,7 @@ unpercent_string (const char *string, int with_plus)
   for (s=(const unsigned char *)string; *s; s++)
     {
       if (*s == '%' && s[1] && s[2])
-        { 
+        {
           s++;
           n++;
           s++;
@@ -338,7 +334,7 @@ unpercent_string (const char *string, int with_plus)
   for (s=(const unsigned char *)string; *s; s++)
     {
       if (*s == '%' && s[1] && s[2])
-        { 
+        {
           s++;
           *p++ = xtoi_2 (s);
           s++;
@@ -375,7 +371,7 @@ set_var (const char *name, const char *value)
   xfree (var->value);
   var->value = value? xstrdup (value) : NULL;
   return var->value;
-}    
+}
 
 
 static void
@@ -443,12 +439,12 @@ arithmetic_op (int operator, const char *operands)
         case '+': result += value; break;
         case '-': result -= value; break;
         case '*': result *= value; break;
-        case '/': 
+        case '/':
           if (!value)
             return NULL;
           result /= value;
           break;
-        case '%': 
+        case '%':
           if (!value)
             return NULL;
           result %= value;
@@ -457,7 +453,7 @@ arithmetic_op (int operator, const char *operands)
         case '|': result = result || value; break;
         case '&': result = result && value; break;
         default:
-          log_error ("unknown arithmetic operator `%c'\n", operator);
+          log_error ("unknown arithmetic operator '%c'\n", operator);
           return NULL;
         }
     }
@@ -468,10 +464,10 @@ arithmetic_op (int operator, const char *operands)
 
 
 /* Extended version of get_var.  This returns a malloced string and
-   understand the function syntax: "func args". 
+   understand the function syntax: "func args".
 
    Defined functions are
-   
+
      get - Return a value described by the next argument:
            cwd        - The current working directory.
            homedir    - The gnupg homedir.
@@ -499,8 +495,8 @@ arithmetic_op (int operator, const char *operands)
      percent ARGS
      percent+ ARGS
            Escape the args using the percent style.  Tabs, formfeeds,
-           linefeeds, carriage return, and the plus sign are also
-           escaped.  "percent+" also maps spaces to plus characters.
+           linefeeds and carriage returns are also escaped.
+           "percent+" also maps spaces to plus characters.
 
      errcode ARG
            Assuming ARG is an integer, return the gpg-error code.
@@ -513,7 +509,7 @@ arithmetic_op (int operator, const char *operands)
 
 
    Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
-    
+
   */
 static char *
 get_var_ext (const char *name)
@@ -548,7 +544,7 @@ get_var_ext (const char *name)
         s++;
       if (!strcmp (s, "cwd"))
         {
-          result = gnu_getcwd ();
+          result = gnupg_getcwd ();
           if (!result)
             log_error ("getcwd failed: %s\n", strerror (errno));
         }
@@ -568,7 +564,7 @@ get_var_ext (const char *name)
         result = xasprintf ("%d", (int)server_pid);
       else
         {
-          log_error ("invalid argument `%s' for variable function `get'\n", s);
+          log_error ("invalid argument '%s' for variable function 'get'\n", s);
           log_info  ("valid are: cwd, "
                      "{home,bin,lib,libexec,data}dir, serverpid\n");
           result = NULL;
@@ -592,12 +588,12 @@ get_var_ext (const char *name)
   else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
     {
       s++;
-      result = percent_escape (s, "+\t\r\n\f\v");
+      result = percent_escape (s, "\t\r\n\f\v");
     }
   else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
     {
       s++;
-      result = percent_escape (s, "+\t\r\n\f\v");
+      result = percent_escape (s, "\t\r\n\f\v");
       for (p=result; *p; p++)
         if (*p == ' ')
           *p = '+';
@@ -618,7 +614,7 @@ get_var_ext (const char *name)
     {
       s++;
       intvalue = (int)strtol (s, NULL, 0);
-      result = xasprintf ("%s <%s>", 
+      result = xasprintf ("%s <%s>",
                           gpg_strerror (intvalue), gpg_strsource (intvalue));
     }
   else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name))
@@ -627,10 +623,10 @@ get_var_ext (const char *name)
     }
   else
     {
-      log_error ("unknown variable function `%.*s'\n", (int)(s-name), name);
+      log_error ("unknown variable function '%.*s'\n", (int)(s-name), name);
       result = NULL;
     }
-    
+
   xfree (free_me);
   recursion_count--;
   return result;
@@ -655,7 +651,7 @@ substitute_line (char *buffer)
       p = strchr (line, '$');
       if (!p)
         return result; /* No more variables.  */
-      
+
       if (p[1] == '$') /* Escaped dollar sign. */
         {
           memmove (p, p+1, strlen (p+1)+1);
@@ -739,7 +735,7 @@ static char *
 substitute_line_copy (const char *buffer)
 {
   char *result, *p;
-  
+
   p = xstrdup (buffer?buffer:"");
   result = substitute_line (p);
   if (!result)
@@ -765,7 +761,7 @@ assign_variable (char *line, int syslet)
     p++;
 
   if (!*p)
-    set_var (name, NULL); /* Remove variable.  */ 
+    set_var (name, NULL); /* Remove variable.  */
   else if (syslet)
     {
       free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
@@ -779,7 +775,7 @@ assign_variable (char *line, int syslet)
       xfree (tmp);
       xfree (free_me);
     }
-  else 
+  else
     {
       tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
       if (tmp)
@@ -845,11 +841,11 @@ show_definq (void)
 
   for (d=definq_list; d; d = d->next)
     if (d->name)
-      printf ("%-20s %c %s\n", 
+      printf ("%-20s %c %s\n",
               d->name, d->is_var? 'v' : d->is_prog? 'p':'f', d->file);
   for (d=definq_list; d; d = d->next)
     if (!d->name)
-      printf ("%-20s %c %s\n", "*", 
+      printf ("%-20s %c %s\n", "*",
               d->is_var? 'v': d->is_prog? 'p':'f', d->file);
 }
 
@@ -859,14 +855,14 @@ static void
 clear_definq (void)
 {
   while (definq_list)
-    { 
+    {
       definq_t tmp = definq_list->next;
       xfree (definq_list->name);
       xfree (definq_list);
       definq_list = tmp;
     }
   definq_list_tail = &definq_list;
-}      
+}
 
 
 static void
@@ -901,14 +897,14 @@ do_sendfd (assuan_context_t ctx, char *line)
   fp = fopen (name, mode);
   if (!fp)
     {
-      log_error ("can't open `%s' in \"%s\" mode: %s\n",
+      log_error ("can't open '%s' in \"%s\" mode: %s\n",
                  name, mode, strerror (errno));
       return;
     }
   fd = fileno (fp);
 
   if (opt.verbose)
-    log_error ("file `%s' opened in \"%s\" mode, fd=%d\n",
+    log_error ("file '%s' opened in \"%s\" mode, fd=%d\n",
                name, mode, fd);
 
   rc = assuan_sendfd (ctx, INT2FD (fd) );
@@ -977,7 +973,7 @@ do_open (char *line)
   fp = fopen (name, mode);
   if (!fp)
     {
-      log_error ("can't open `%s' in \"%s\" mode: %s\n",
+      log_error ("can't open '%s' in \"%s\" mode: %s\n",
                  name, mode, strerror (errno));
       return;
     }
@@ -985,12 +981,15 @@ do_open (char *line)
   if (fd >= 0 && fd < DIM (open_fd_table))
     {
       open_fd_table[fd].inuse = 1;
-#ifdef HAVE_W32_SYSTEM
+#ifdef HAVE_W32CE_SYSTEM
+# warning fixme: implement our pipe emulation.
+#endif
+#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
       {
         HANDLE prochandle, handle, newhandle;
 
         handle = (void*)_get_osfhandle (fd);
-     
+
         prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
         if (!prochandle)
           {
@@ -1012,12 +1011,12 @@ do_open (char *line)
         open_fd_table[fd].handle = newhandle;
       }
       if (opt.verbose)
-        log_info ("file `%s' opened in \"%s\" mode, fd=%d  (libc=%d)\n",
+        log_info ("file '%s' opened in \"%s\" mode, fd=%d  (libc=%d)\n",
                    name, mode, (int)open_fd_table[fd].handle, fd);
       set_int_var (varname, (int)open_fd_table[fd].handle);
-#else  
+#else
       if (opt.verbose)
-        log_info ("file `%s' opened in \"%s\" mode, fd=%d\n",
+        log_info ("file '%s' opened in \"%s\" mode, fd=%d\n",
                    name, mode, fd);
       set_int_var (varname, fd);
 #endif
@@ -1102,14 +1101,14 @@ do_serverpid (assuan_context_t ctx)
   int rc;
   membuf_t mb;
   char *buffer;
-  
+
   init_membuf (&mb, 100);
   rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
                         NULL, NULL, NULL, NULL);
   put_membuf (&mb, "", 1);
   buffer = get_membuf (&mb, NULL);
   if (rc || !buffer)
-    log_error ("command \"%s\" failed: %s\n", 
+    log_error ("command \"%s\" failed: %s\n",
                "GETINFO pid", gpg_strerror (rc));
   else
     {
@@ -1121,6 +1120,22 @@ do_serverpid (assuan_context_t ctx)
 }
 
 
+/* Return true if the command is either "HELP" or "SCD HELP".  */
+static int
+help_cmd_p (const char *line)
+{
+  if (!ascii_strncasecmp (line, "SCD", 3)
+      && (spacep (line+3) || !line[3]))
+    {
+      for (line += 3; spacep (line); line++)
+        ;
+    }
+
+  return (!ascii_strncasecmp (line, "HELP", 4)
+          && (spacep (line+4) || !line[4]));
+}
+
+
 /* gpg-connect-agent's entry point. */
 int
 main (int argc, char **argv)
@@ -1141,7 +1156,7 @@ main (int argc, char **argv)
     loopline_t head;
     loopline_t *tail;
     loopline_t current;
-    unsigned int nestlevel; 
+    unsigned int nestlevel;
     int oneshot;
     char *condition;
   } loopstack[20];
@@ -1154,7 +1169,7 @@ main (int argc, char **argv)
 
   /* Make sure that our subsystems are ready.  */
   i18n_init();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   assuan_set_gpg_err_source (0);
 
@@ -1174,13 +1189,17 @@ main (int argc, char **argv)
         case oVerbose:   opt.verbose++; break;
         case oNoVerbose: opt.verbose = 0; break;
         case oHomedir:   opt.homedir = pargs.r.ret_str; break;
+        case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
+        case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
         case oHex:       opt.hex = 1; break;
         case oDecode:    opt.decode = 1; break;
+        case oDirmngr:   opt.use_dirmngr = 1; break;
         case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
+        case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break;
         case oExec:      opt.exec = 1; break;
         case oNoExtConnect: opt.connect_flags &= ~(1); break;
         case oRun:       opt_run = pargs.r.ret_str; break;
-        case oSubst: 
+        case oSubst:
           opt.enable_varsubst = 1;
           opt.trim_leading_spaces = 1;
           break;
@@ -1192,7 +1211,19 @@ main (int argc, char **argv)
   if (log_get_errorcount (0))
     exit (2);
 
-  use_tty = (isatty ( fileno (stdin)) && isatty (fileno (stdout)));
+
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+    {
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
+    }
+
+
+  use_tty = (gnupg_isatty (fileno (stdin)) && gnupg_isatty (fileno (stdout)));
 
   if (opt.exec)
     {
@@ -1207,12 +1238,27 @@ main (int argc, char **argv)
     cmdline_commands = argv;
 
   if (opt.exec && opt.raw_socket)
-    log_info (_("option \"%s\" ignored due to \"%s\"\n"),
-              "--raw-socket", "--exec");
+    {
+      opt.raw_socket = NULL;
+      log_info (_("option \"%s\" ignored due to \"%s\"\n"),
+                "--raw-socket", "--exec");
+    }
+  if (opt.exec && opt.tcp_socket)
+    {
+      opt.tcp_socket = NULL;
+      log_info (_("option \"%s\" ignored due to \"%s\"\n"),
+                "--tcp-socket", "--exec");
+    }
+  if (opt.tcp_socket && opt.raw_socket)
+    {
+      opt.tcp_socket = NULL;
+      log_info (_("option \"%s\" ignored due to \"%s\"\n"),
+                "--tcp-socket", "--raw-socket");
+    }
 
   if (opt_run && !(script_fp = fopen (opt_run, "r")))
     {
-      log_error ("cannot open run file `%s': %s\n",
+      log_error ("cannot open run file '%s': %s\n",
                  opt_run, strerror (errno));
       exit (1);
     }
@@ -1220,11 +1266,11 @@ main (int argc, char **argv)
 
   if (opt.exec)
     {
-      int no_close[3];
+      assuan_fd_t no_close[3];
 
-      no_close[0] = assuan_fd_from_posix_fd (fileno (stderr));
+      no_close[0] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
       no_close[1] = assuan_fd_from_posix_fd (log_get_fd ());
-      no_close[2] = -1;
+      no_close[2] = ASSUAN_INVALID_FD;
 
       rc = assuan_new (&ctx);
       if (rc)
@@ -1244,7 +1290,7 @@ main (int argc, char **argv)
         }
 
       if (opt.verbose)
-        log_info ("server `%s' started\n", *argv);
+        log_info ("server '%s' started\n", *argv);
 
     }
   else if (opt.raw_socket)
@@ -1261,13 +1307,39 @@ main (int argc, char **argv)
         (opt.connect_flags & 1) ? ASSUAN_SOCKET_CONNECT_FDPASSING : 0);
       if (rc)
         {
-          log_error ("can't connect to socket `%s': %s\n",
+          log_error ("can't connect to socket '%s': %s\n",
                      opt.raw_socket, gpg_strerror (rc));
           exit (1);
         }
 
       if (opt.verbose)
-        log_info ("connection to socket `%s' established\n", opt.raw_socket);
+        log_info ("connection to socket '%s' established\n", opt.raw_socket);
+    }
+  else if (opt.tcp_socket)
+    {
+      char *url;
+
+      url = xstrconcat ("assuan://", opt.tcp_socket, NULL);
+
+      rc = assuan_new (&ctx);
+      if (rc)
+       {
+          log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
+         exit (1);
+       }
+
+      rc = assuan_socket_connect (ctx, opt.tcp_socket, 0, 0);
+      if (rc)
+        {
+          log_error ("can't connect to server '%s': %s\n",
+                     opt.tcp_socket, gpg_strerror (rc));
+          exit (1);
+        }
+
+      if (opt.verbose)
+        log_info ("connection to socket '%s' established\n", url);
+
+      xfree (url);
     }
   else
     ctx = start_agent ();
@@ -1281,7 +1353,7 @@ main (int argc, char **argv)
         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
     }
 
+
   for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
     loopstack[loopidx].collecting = 0;
   loopidx = -1;
@@ -1338,7 +1410,7 @@ main (int argc, char **argv)
               linesize = 0;
               keep_line = 1;
             }
-          n = read_line (script_fp? script_fp:stdin, 
+          n = read_line (script_fp? script_fp:stdin,
                          &line, &linesize, &maxlength);
         }
       if (n < 0)
@@ -1364,7 +1436,7 @@ main (int argc, char **argv)
                 log_info ("end of script\n");
               continue;
             }
-          break; 
+          break;
         }
       if (!maxlength)
         {
@@ -1375,11 +1447,11 @@ main (int argc, char **argv)
         log_info (_("line shortened due to embedded Nul character\n"));
       if (line[n-1] == '\n')
         line[n-1] = 0;
-      
+
       if (opt.trim_leading_spaces)
         {
           const char *s = line;
-          
+
           while (spacep (s))
             s++;
           if (s != line)
@@ -1405,7 +1477,7 @@ main (int argc, char **argv)
             loopstack[loopidx+1].nestlevel--;
           else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
             loopstack[loopidx+1].nestlevel++;
-          
+
           if (loopstack[loopidx+1].nestlevel)
             continue;
           /* We reached the corresponding /end.  */
@@ -1488,7 +1560,7 @@ main (int argc, char **argv)
                 {
                   current_datasink = fopen (fname, "wb");
                   if (!current_datasink)
-                    log_error ("can't open `%s': %s\n", 
+                    log_error ("can't open '%s': %s\n",
                                fname, strerror (errno));
                 }
               xfree (tmpline);
@@ -1608,11 +1680,11 @@ main (int argc, char **argv)
                 }
               else if (!(script_fp = fopen (p, "r")))
                 {
-                  log_error ("cannot open run file `%s': %s\n",
+                  log_error ("cannot open run file '%s': %s\n",
                              p, strerror (errno));
                 }
               else if (opt.verbose)
-                log_info ("running commands from `%s'\n", p);
+                log_info ("running commands from '%s'\n", p);
             }
           else if (!strcmp (cmd, "while"))
             {
@@ -1673,7 +1745,14 @@ main (int argc, char **argv)
                     }
                   tmpline = substitute_line (tmpcond);
                   value = tmpline? tmpline : tmpcond;
-                  condition = strtol (value, NULL, 0);
+                  /* "true" or "yes" are commonly used to mean TRUE;
+                     all other strings will evaluate to FALSE due to
+                     the strtoul.  */
+                  if (!ascii_strcasecmp (value, "true")
+                      || !ascii_strcasecmp (value, "yes"))
+                    condition = 1;
+                  else
+                    condition = strtol (value, NULL, 0);
                   xfree (tmpline);
                   xfree (tmpcond);
 
@@ -1725,7 +1804,7 @@ main (int argc, char **argv)
 "/cleardef              Delete all definitions.\n"
 "/sendfd FILE MODE      Open FILE and pass descriptor to server.\n"
 "/recvfd                Receive FD from server and print.\n"
-"/open VAR FILE MODE    Open FILE and assign the file descriptor to VAR.\n" 
+"/open VAR FILE MODE    Open FILE and assign the file descriptor to VAR.\n"
 "/close FD              Close file with descriptor FD.\n"
 "/showopen              Show descriptors of all open files.\n"
 "/serverpid             Retrieve the pid of the server.\n"
@@ -1740,8 +1819,8 @@ main (int argc, char **argv)
 "/help                  Print this help.");
             }
           else
-            log_error (_("unknown command `%s'\n"), cmd );
-      
+            log_error (_("unknown command '%s'\n"), cmd );
+
           continue;
         }
 
@@ -1764,9 +1843,7 @@ main (int argc, char **argv)
       if (*line == '#' || !*line)
         continue; /* Don't expect a response for a comment line. */
 
-      rc = read_and_print_response (ctx, (!ascii_strncasecmp (line, "HELP", 4)
-                                          && (spacep (line+4) || !line[4])),
-                                    &cmderr);
+      rc = read_and_print_response (ctx, help_cmd_p (line), &cmderr);
       if (rc)
         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
       if ((rc || cmderr) && script_fp)
@@ -1775,7 +1852,7 @@ main (int argc, char **argv)
           fclose (script_fp);
           script_fp = NULL;
         }
-          
+
 
       /* FIXME: If the last command was BYE or the server died for
         some other reason, we won't notice until we get the next
@@ -1786,8 +1863,8 @@ main (int argc, char **argv)
 
   if (opt.verbose)
     log_info ("closing connection to agent\n");
-  
-  return 0; 
+
+  return 0;
 }
 
 
@@ -1828,14 +1905,17 @@ handle_inquire (assuan_context_t ctx, char *line)
   if (!d)
     {
       if (opt.verbose)
-        log_info ("no handler for inquiry `%s' found\n", name);
+        log_info ("no handler for inquiry '%s' found\n", name);
       return 0;
     }
 
   if (d->is_var)
     {
       char *tmpvalue = get_var_ext (d->file);
-      rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
+      if (tmpvalue)
+        rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
+      else
+        rc = assuan_send_data (ctx, "", 0);
       xfree (tmpvalue);
       if (rc)
         log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
@@ -1844,21 +1924,25 @@ handle_inquire (assuan_context_t ctx, char *line)
     {
       if (d->is_prog)
         {
+#ifdef HAVE_W32CE_SYSTEM
+          fp = NULL;
+#else
           fp = popen (d->file, "r");
+#endif
           if (!fp)
-            log_error ("error executing `%s': %s\n",
+            log_error ("error executing '%s': %s\n",
                        d->file, strerror (errno));
           else if (opt.verbose)
-            log_error ("handling inquiry `%s' by running `%s'\n", 
+            log_error ("handling inquiry '%s' by running '%s'\n",
                        name, d->file);
         }
       else
         {
           fp = fopen (d->file, "rb");
           if (!fp)
-            log_error ("error opening `%s': %s\n", d->file, strerror (errno));
+            log_error ("error opening '%s': %s\n", d->file, strerror (errno));
           else if (opt.verbose)
-            log_error ("handling inquiry `%s' by returning content of `%s'\n",
+            log_error ("handling inquiry '%s' by returning content of '%s'\n",
                        name, d->file);
         }
       if (!fp)
@@ -1874,7 +1958,7 @@ handle_inquire (assuan_context_t ctx, char *line)
             }
         }
       if (ferror (fp))
-        log_error ("error reading from `%s': %s\n", d->file, strerror (errno));
+        log_error ("error reading from '%s': %s\n", d->file, strerror (errno));
     }
 
   rc = assuan_send_data (ctx, NULL, 0);
@@ -1885,8 +1969,10 @@ handle_inquire (assuan_context_t ctx, char *line)
     ;
   else if (d->is_prog)
     {
+#ifndef HAVE_W32CE_SYSTEM
       if (pclose (fp))
-        log_error ("error running `%s': %s\n", d->file, strerror (errno));
+        log_error ("error running '%s': %s\n", d->file, strerror (errno));
+#endif
     }
   else
     fclose (fp);
@@ -1910,7 +1996,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
   *r_goterr = 0;
   for (;;)
     {
-      do 
+      do
         {
           rc = assuan_read_line (ctx, &line, &linelen);
           if (rc)
@@ -1921,7 +2007,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
               fwrite (line, linelen, 1, stdout);
               putchar ('\n');
             }
-        }    
+        }
       while (*line == '#' || !linelen);
 
       if (linelen >= 1
@@ -1935,7 +2021,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
               for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
                 {
                   if (*s == '%' && j+2 < linelen)
-                    { 
+                    {
                       s++; j++;
                       c = xtoi_2 ( s );
                       s++; j++;
@@ -1990,7 +2076,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
                       need_d = 0;
                     }
                   if (*s == '%' && j+2 < linelen)
-                    { 
+                    {
                       s++; j++;
                       c = xtoi_2 ( s );
                       s++; j++;
@@ -2009,7 +2095,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
               putchar ('\n');
             }
         }
-      else 
+      else
         {
           if (need_lf)
             {
@@ -2019,7 +2105,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
             }
 
           if (linelen >= 1
-              && line[0] == 'S' 
+              && line[0] == 'S'
               && (line[1] == '\0' || line[1] == ' '))
             {
               if (!current_datasink || current_datasink != stdout)
@@ -2027,7 +2113,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
                   fwrite (line, linelen, 1, stdout);
                   putchar ('\n');
                 }
-            }  
+            }
           else if (linelen >= 2
                    && line[0] == 'O' && line[1] == 'K'
                    && (line[2] == '\0' || line[2] == ' '))
@@ -2057,11 +2143,11 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
                 }
               *r_goterr = 1;
               return 0;
-            }  
+            }
           else if (linelen >= 7
                    && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
                    && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
-                   && line[6] == 'E' 
+                   && line[6] == 'E'
                    && (line[7] == '\0' || line[7] == ' '))
             {
               if (!current_datasink || current_datasink != stdout)
@@ -2096,131 +2182,35 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
 static assuan_context_t
 start_agent (void)
 {
-  int rc = 0;
-  char *infostr, *p;
+  gpg_error_t err;
   assuan_context_t ctx;
   session_env_t session_env;
 
-  infostr = getenv ("GPG_AGENT_INFO");
-  if (!infostr || !*infostr)
-    {
-      char *sockname;
-
-      rc = assuan_new (&ctx);
-      if (rc)
-       {
-          log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
-         exit (1);
-       }
-
-      /* Check whether we can connect at the standard socket.  */
-      sockname = make_filename (opt.homedir, "S.gpg-agent", NULL);
-      rc = assuan_socket_connect (ctx, sockname, 0, 0);
-
-#ifdef HAVE_W32_SYSTEM
-      /* If we failed to connect under Windows, we fire up the agent.  */
-      if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
-        {
-          const char *agent_program;
-          const char *argv[3];
-          int save_rc = rc;
-          
-          if (opt.verbose)
-            log_info (_("no running gpg-agent - starting one\n"));
-          agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
-          
-          argv[0] = "--daemon";
-          argv[1] = "--use-standard-socket"; 
-          argv[2] = NULL;  
-
-          rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
-          if (rc)
-            log_debug ("failed to start agent `%s': %s\n",
-                       agent_program, gpg_strerror (rc));
-          else
-            {
-              /* Give the agent some time to prepare itself. */
-              gnupg_sleep (3);
-              /* Now try again to connect the agent.  */
-             rc = assuan_new (&ctx);
-             if (rc)
-               {
-                 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
-                 exit (1);
-               }
-
-              rc = assuan_socket_connect (ctx, sockname, 0, 0);
-            }
-          if (rc)
-            rc = save_rc;
-        }
-#endif /*HAVE_W32_SYSTEM*/
-      xfree (sockname);
-    }
-  else
-    {
-      int prot;
-      int pid;
-
-      infostr = xstrdup (infostr);
-      if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
-        {
-          log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
-          xfree (infostr);
-          exit (1);
-        }
-      *p++ = 0;
-      pid = atoi (p);
-      while (*p && *p != PATHSEP_C)
-        p++;
-      prot = *p? atoi (p+1) : 0;
-      if (prot != 1)
-        {
-          log_error (_("gpg-agent protocol version %d is not supported\n"),
-                     prot);
-          xfree (infostr);
-          exit (1);
-        }
-
-      rc = assuan_new (&ctx);
-      if (rc)
-       {
-          log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
-         exit (1);
-       }
-
-      rc = assuan_socket_connect (ctx, infostr, pid, 0);
-      xfree (infostr);
-    }
-
-  if (rc)
-    {
-      log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
-      exit (1);
-    }
-
-  if (opt.verbose)
-    log_info ("connection to agent established\n");
-
-  rc = assuan_transact (ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
-  if (rc)
-    {
-      log_error (_("error sending %s command: %s\n"), "RESET", 
-                 gpg_strerror (rc));
-      exit (1);
-    }
-
   session_env = session_env_new ();
   if (!session_env)
     log_fatal ("error allocating session environment block: %s\n",
                strerror (errno));
+  if (opt.use_dirmngr)
+    err = start_new_dirmngr (&ctx,
+                             GPG_ERR_SOURCE_DEFAULT,
+                             opt.homedir,
+                             opt.dirmngr_program,
+                             !opt.quiet, 0,
+                             NULL, NULL);
+  else
+    err = start_new_gpg_agent (&ctx,
+                               GPG_ERR_SOURCE_DEFAULT,
+                               opt.homedir,
+                               opt.agent_program,
+                               NULL, NULL,
+                               session_env,
+                               !opt.quiet, 0,
+                               NULL, NULL);
 
-  rc = send_pinentry_environment (ctx, GPG_ERR_SOURCE_DEFAULT,
-                                  NULL, NULL, session_env);
   session_env_release (session_env);
-  if (rc)
+  if (err)
     {
-      log_error (_("error sending standard options: %s\n"), gpg_strerror (rc));
+      log_error (_("error sending standard options: %s\n"), gpg_strerror (err));
       exit (1);
     }
 
index 69d160e..f9999ba 100644 (file)
@@ -1,5 +1,6 @@
 /* gpgconf-comp.c - Configuration utility for GnuPG.
- * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2007, 2008, 2009, 2010,
+ *               2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -30,7 +31,9 @@
 #include <errno.h>
 #include <time.h>
 #include <stdarg.h>
-#include <signal.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 #include <ctype.h>
 #ifdef HAVE_W32_SYSTEM
 # define WIN32_LEAN_AND_MEAN 1
 #include "gc-opt-flags.h"
 #include "gpgconf.h"
 
-
 /* There is a problem with gpg 1.4 under Windows: --gpgconf-list
    returns a plain filename without escaping.  As long as we have not
-   fixed that we need to use gpg2 - it might actually be better to use
-   gpg2 in any case.  */
-#ifdef HAVE_W32_SYSTEM
+   fixed that we need to use gpg2.  */
+#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
 #define GPGNAME "gpg2"
 #else
-#define GPGNAME "gpg"
+#define GPGNAME GPG_NAME
 #endif
 
 \f
@@ -104,8 +105,8 @@ gc_error (int status, int errnum, const char *fmt, ...)
 
 \f
 /* Forward declaration.  */
-static void gpg_agent_runtime_change (void);
-static void scdaemon_runtime_change (void);
+static void gpg_agent_runtime_change (int killflag);
+static void scdaemon_runtime_change (int killflag);
 
 /* Backend configuration.  Backends are used to decide how the default
    and current value of an option can be determined, and how the
@@ -131,12 +132,15 @@ typedef enum
     /* The GnuPG SCDaemon.  */
     GC_BACKEND_SCDAEMON,
 
-    /* The Aegypten directory manager.  */
+    /* The GnuPG directory manager.  */
     GC_BACKEND_DIRMNGR,
 
-    /* The LDAP server list file for the Aegypten director manager.  */
+    /* The LDAP server list file for the director manager.  */
     GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST,
 
+    /* The Pinentry (not a part of GnuPG, proper).  */
+    GC_BACKEND_PINENTRY,
+
     /* The number of the above entries.  */
     GC_BACKEND_NR
   } gc_backend_t;
@@ -156,12 +160,13 @@ static struct
 
   /* The module name (GNUPG_MODULE_NAME_foo) as defined by
      ../common/util.h.  This value is used to get the actual installed
-     path of the program.  0 is used if no backedn program is
+     path of the program.  0 is used if no backend program is
      available. */
   char module_name;
 
-  /* The runtime change callback.  */
-  void (*runtime_change) (void);
+  /* The runtime change callback.  If KILLFLAG is true the component
+     is killed and not just reloaded.  */
+  void (*runtime_change) (int killflag);
 
   /* The option name for the configuration filename of this backend.
      This must be an absolute filename.  It can be an option from a
@@ -175,18 +180,20 @@ static struct
 } gc_backend[GC_BACKEND_NR] =
   {
     { NULL },          /* GC_BACKEND_ANY dummy entry.  */
-    { "GnuPG", GPGNAME, GNUPG_MODULE_NAME_GPG,
-      NULL, "gpgconf-gpg.conf" },
-    { "GPGSM", "gpgsm", GNUPG_MODULE_NAME_GPGSM,
-      NULL, "gpgconf-gpgsm.conf" },
-    { "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT,
-      gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
-    { "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON,
-      scdaemon_runtime_change, "gpgconf-scdaemon.conf" },
-    { "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR,
-      NULL, "gpgconf-dirmngr.conf" },
-    { "DirMngr LDAP Server List", NULL, 0,
+    { GPG_DISP_NAME, GPGNAME, GNUPG_MODULE_NAME_GPG,
+      NULL, GPGCONF_NAME "-" GPG_NAME ".conf" },
+    { GPGSM_DISP_NAME, GPGSM_NAME, GNUPG_MODULE_NAME_GPGSM,
+      NULL, GPGCONF_NAME "-" GPGSM_NAME ".conf" },
+    { GPG_AGENT_DISP_NAME, GPG_AGENT_NAME, GNUPG_MODULE_NAME_AGENT,
+      gpg_agent_runtime_change, GPGCONF_NAME"-" GPG_AGENT_NAME ".conf" },
+    { SCDAEMON_DISP_NAME, SCDAEMON_NAME, GNUPG_MODULE_NAME_SCDAEMON,
+      scdaemon_runtime_change, GPGCONF_NAME"-" SCDAEMON_NAME ".conf" },
+    { DIRMNGR_DISP_NAME, DIRMNGR_NAME, GNUPG_MODULE_NAME_DIRMNGR,
+      NULL, GPGCONF_NAME "-" DIRMNGR_NAME ".conf" },
+    { DIRMNGR_DISP_NAME " LDAP Server List", NULL, 0,
       NULL, "ldapserverlist-file", "LDAP Server" },
+    { "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
+      NULL, GPGCONF_NAME "-pinentry.conf" },
   };
 
 \f
@@ -350,11 +357,6 @@ static struct
    several times.  A comma separated list of arguments is used as the
    argument value.  */
 #define GC_OPT_FLAG_LIST       (1UL << 2)
-/* The NO_CHANGE flag for an option indicates that the user should not
-   be allowed to change this option using the standard gpgconf method.
-   Frontends using gpgconf should grey out such options, so that only
-   the current value is displayed.  */
-#define GC_OPT_FLAG_NO_CHANGE   (1UL <<7)
 
 
 /* A human-readable description for each flag.  */
@@ -461,11 +463,15 @@ typedef struct gc_option gc_option_t;
 #define GC_OPTION_NULL { NULL }
 
 \f
+#ifndef BUILD_WITH_AGENT
+#define gc_options_gpg_agent NULL
+#else
 /* The options of the GC_COMPONENT_GPG_AGENT component.  */
 static gc_option_t gc_options_gpg_agent[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-" GPG_AGENT_NAME ".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
 
    { "Monitor",
@@ -532,9 +538,6 @@ static gc_option_t gc_options_gpg_agent[] =
    { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
      GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
-   { "no-allow-external-cache", GC_OPT_FLAG_RUNTIME,
-     GC_LEVEL_BASIC, "gnupg", "disallow the use of an external password cache",
-     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
    { "no-allow-mark-trusted", GC_OPT_FLAG_RUNTIME,
      GC_LEVEL_ADVANCED, "gnupg", "disallow clients to mark keys as \"trusted\"",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
@@ -572,13 +575,18 @@ static gc_option_t gc_options_gpg_agent[] =
 
    GC_OPTION_NULL
  };
+#endif /*BUILD_WITH_AGENT*/
 
 
+#ifndef BUILD_WITH_SCDAEMON
+#define gc_options_scdaemon NULL
+#else
 /* The options of the GC_COMPONENT_SCDAEMON component.  */
 static gc_option_t gc_options_scdaemon[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"SCDAEMON_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
 
    { "Monitor",
@@ -643,13 +651,17 @@ static gc_option_t gc_options_scdaemon[] =
 
    GC_OPTION_NULL
  };
+#endif /*BUILD_WITH_SCDAEMON*/
 
-
+#ifndef BUILD_WITH_GPG
+#define gc_options_gpg NULL
+#else
 /* The options of the GC_COMPONENT_GPG component.  */
 static gc_option_t gc_options_gpg[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"GPG_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
 
    { "Monitor",
@@ -680,6 +692,11 @@ static gc_option_t gc_options_gpg[] =
    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
      "gnupg", "|FILE|read options from FILE",
      GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
+   { "default_pubkey_algo",
+     (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
+     NULL, NULL,
+     GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
+
 
    { "Debug",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
@@ -708,16 +725,22 @@ static gc_option_t gc_options_gpg[] =
      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
 
 
+
+
    GC_OPTION_NULL
  };
+#endif /*BUILD_WITH_GPG*/
 
 
-
+#ifndef BUILD_WITH_GPGSM
+#define gc_options_gpgsm NULL
+#else
 /* The options of the GC_COMPONENT_GPGSM component.  */
 static gc_option_t gc_options_gpgsm[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"GPGSM_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
 
    { "Monitor",
@@ -757,6 +780,10 @@ static gc_option_t gc_options_gpgsm[] =
    { "keyserver", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
      "gnupg", N_("|SPEC|use this keyserver to lookup keys"),
      GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_GPGSM },
+   { "default_pubkey_algo",
+     (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
+     NULL, NULL,
+     GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
 
    { "Debug",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
@@ -798,13 +825,18 @@ static gc_option_t gc_options_gpgsm[] =
 
    GC_OPTION_NULL
  };
+#endif /*BUILD_WITH_GPGSM*/
 
 
+#ifndef BUILD_WITH_DIRMNGR
+#define gc_options_dirmngr NULL
+#else
 /* The options of the GC_COMPONENT_DIRMNGR component.  */
 static gc_option_t gc_options_dirmngr[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"DIRMNGR_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
 
    { "Monitor",
@@ -938,6 +970,21 @@ static gc_option_t gc_options_dirmngr[] =
 
    GC_OPTION_NULL
  };
+#endif /*BUILD_WITH_DIRMNGR*/
+
+
+/* The options of the GC_COMPONENT_PINENTRY component.  */
+static gc_option_t gc_options_pinentry[] =
+ {
+   /* A dummy option to allow gc_component_list_components to find the
+      pinentry backend.  Needs to be a conf file. */
+   { GPGCONF_NAME"-pinentry.conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+     NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_PINENTRY },
+
+   GC_OPTION_NULL
+ };
+
 
 \f
 /* Component system.  Each component is a set of options that can be
@@ -960,6 +1007,9 @@ typedef enum
     /* The LDAP Directory Manager for CRLs.  */
     GC_COMPONENT_DIRMNGR,
 
+    /* The external Pinentry.  */
+    GC_COMPONENT_PINENTRY,
+
     /* The number of components.  */
     GC_COMPONENT_NR
   } gc_component_t;
@@ -984,11 +1034,12 @@ static struct
   gc_option_t *options;
 } gc_component[] =
   {
-    { "gpg", NULL,   "GPG for OpenPGP", gc_options_gpg },
-    { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
-    { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
-    { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
-    { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr }
+    { "gpg",      "gnupg", N_("GPG for OpenPGP"), gc_options_gpg },
+    { "gpg-agent","gnupg", N_("GPG Agent"), gc_options_gpg_agent },
+    { "scdaemon", "gnupg", N_("Smartcard Daemon"), gc_options_scdaemon },
+    { "gpgsm",    "gnupg", N_("GPG for S/MIME"), gc_options_gpgsm },
+    { "dirmngr",  "gnupg", N_("Directory Manager"), gc_options_dirmngr },
+    { "pinentry", "gnupg", N_("PIN and Passphrase Entry"), gc_options_pinentry }
   };
 
 
@@ -1009,64 +1060,37 @@ struct error_line_s
 \f
 /* Engine specific support.  */
 static void
-gpg_agent_runtime_change (void)
+gpg_agent_runtime_change (int killflag)
 {
-#ifndef HAVE_W32_SYSTEM
-  char *agent = getenv ("GPG_AGENT_INFO");
-  char *pid_str;
-  unsigned long pid_long;
-  char *tail;
-  pid_t pid;
-
-  if (!agent)
-    return;
-
-  pid_str = strchr (agent, ':');
-  if (!pid_str)
-    return;
-
-  pid_str++;
-  errno = 0;
-  pid_long = strtoul (pid_str, &tail, 0);
-  if (errno || (*tail != ':' && *tail != '\0'))
-    return;
-
-  pid = (pid_t) pid_long;
-
-  /* Check for overflow.  */
-  if (pid_long != (unsigned long) pid)
-    return;
-
-  /* Ignore any errors here.  */
-  kill (pid, SIGHUP);
-#else
   gpg_error_t err;
   const char *pgmname;
   const char *argv[2];
   pid_t pid;
 
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
-  argv[0] = "reloadagent";
+  argv[0] = killflag? "KILLAGENT" : "RELOADAGENT";
   argv[1] = NULL;
 
   err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
   if (!err)
-    err = gnupg_wait_process (pgmname, pid, NULL);
+    err = gnupg_wait_process (pgmname, pid, 1, NULL);
   if (err)
-    gc_error (0, 0, "error running `%s%s': %s",
+    gc_error (0, 0, "error running '%s%s': %s",
               pgmname, " reloadagent", gpg_strerror (err));
-#endif /*!HAVE_W32_SYSTEM*/
+  gnupg_release_process (pid);
 }
 
 
 static void
-scdaemon_runtime_change (void)
+scdaemon_runtime_change (int killflag)
 {
   gpg_error_t err;
   const char *pgmname;
-  const char *argv[7];
+  const char *argv[6];
   pid_t pid;
 
+  (void)killflag;  /* For scdaemon kill and reload are synonyms.  */
+
   /* We use "GETINFO app_running" to see whether the agent is already
      running and kill it only in this case.  This avoids an explicit
      starting of the agent in case it is not yet running.  There is
@@ -1077,16 +1101,83 @@ scdaemon_runtime_change (void)
   argv[1] = "GETINFO scd_running";
   argv[2] = "/if ${! $?}";
   argv[3] = "scd killscd";
-  argv[4] = "scd bye";
-  argv[5] = "/end";
-  argv[6] = NULL;
+  argv[4] = "/end";
+  argv[5] = NULL;
 
   err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
   if (!err)
-    err = gnupg_wait_process (pgmname, pid, NULL);
+    err = gnupg_wait_process (pgmname, pid, 1, NULL);
   if (err)
-    gc_error (0, 0, "error running `%s%s': %s",
+    gc_error (0, 0, "error running '%s%s': %s",
               pgmname, " scd killscd", gpg_strerror (err));
+  gnupg_release_process (pid);
+}
+
+
+/* Launch the gpg-agent or the dirmngr if not already running.  */
+void
+gc_component_launch (int component)
+{
+  gpg_error_t err;
+  const char *pgmname;
+  const char *argv[3];
+  int i;
+  pid_t pid;
+
+  if (!(component == GC_COMPONENT_GPG_AGENT
+        || component == GC_COMPONENT_DIRMNGR))
+    {
+      es_fputs (_("Component not suitable for launching"), es_stderr);
+      es_putc ('\n', es_stderr);
+      exit (1);
+    }
+
+  pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
+  i = 0;
+  if (component == GC_COMPONENT_DIRMNGR)
+    argv[i++] = "--dirmngr";
+  argv[i++] = "NOP";
+  argv[i] = NULL;
+
+  err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
+  if (!err)
+    err = gnupg_wait_process (pgmname, pid, 1, NULL);
+  if (err)
+    gc_error (0, 0, "error running '%s%s%s': %s",
+              pgmname,
+              component == GC_COMPONENT_DIRMNGR? " --dirmngr":"",
+              " NOP",
+              gpg_strerror (err));
+  gnupg_release_process (pid);
+}
+
+
+/* Unconditionally restart COMPONENT.  */
+void
+gc_component_kill (int component)
+{
+  int runtime[GC_BACKEND_NR];
+  gc_option_t *option;
+  gc_backend_t backend;
+
+  /* Set a flag for the backends to be reloaded.  */
+  for (backend = 0; backend < GC_BACKEND_NR; backend++)
+    runtime[backend] = 0;
+
+  if (component >= 0)
+    {
+      assert (component < GC_COMPONENT_NR);
+      option = gc_component[component].options;
+      for (; option && option->name; option++)
+        runtime[option->backend] = 1;
+    }
+
+  /* Do the restart for the selected backends.  */
+  for (backend = 0; backend < GC_BACKEND_NR; backend++)
+    {
+      if (runtime[backend] && gc_backend[backend].runtime_change)
+        (*gc_backend[backend].runtime_change) (1);
+    }
 }
 
 
@@ -1123,7 +1214,7 @@ gc_component_reload (int component)
   for (backend = 0; backend < GC_BACKEND_NR; backend++)
     {
       if (runtime[backend] && gc_backend[backend].runtime_change)
-        (*gc_backend[backend].runtime_change) ();
+        (*gc_backend[backend].runtime_change) (0);
     }
 }
 
@@ -1147,7 +1238,7 @@ my_dgettext (const char *domain, const char *msgid)
       if (!switched_codeset)
         {
           switched_codeset = 1;
-          gettext_select_utf8 (1);
+          gettext_use_utf8 (1);
         }
 
       if (!strcmp (domain, "gnupg"))
@@ -1158,6 +1249,8 @@ my_dgettext (const char *domain, const char *msgid)
       text = (char*)gettext (msgid);
       return text ? text : msgid;
     }
+  else
+    return msgid;
 #elif defined(ENABLE_NLS)
   if (domain)
     {
@@ -1169,8 +1262,8 @@ my_dgettext (const char *domain, const char *msgid)
           switched_codeset = 1;
           bind_textdomain_codeset (PACKAGE_GT, "utf-8");
 
-          bindtextdomain ("dirmngr", LOCALEDIR);
-          bind_textdomain_codeset ("dirmngr", "utf-8");
+          bindtextdomain (DIRMNGR_NAME, LOCALEDIR);
+          bind_textdomain_codeset (DIRMNGR_NAME, "utf-8");
 
         }
 
@@ -1184,8 +1277,11 @@ my_dgettext (const char *domain, const char *msgid)
       return text ? text : msgid;
     }
   else
-#endif
     return msgid;
+#else
+  (void)domain;
+  return msgid;
+#endif
 }
 
 
@@ -1283,7 +1379,7 @@ percent_deescape (const char *src)
 \f
 /* List all components that are available.  */
 void
-gc_component_list_components (FILE *out)
+gc_component_list_components (estream_t out)
 {
   gc_component_t component;
   gc_option_t *option;
@@ -1319,9 +1415,9 @@ gc_component_list_components (FILE *out)
 
           desc = gc_component[component].desc;
           desc = my_dgettext (gc_component[component].desc_domain, desc);
-          fprintf (out, "%s:%s:",
-                   gc_component[component].name,  gc_percent_escape (desc));
-          fprintf (out, "%s\n",  gc_percent_escape (pgmname));
+          es_fprintf (out, "%s:%s:",
+                      gc_component[component].name,  gc_percent_escape (desc));
+          es_fprintf (out, "%s\n",  gc_percent_escape (pgmname));
         }
     }
 }
@@ -1340,14 +1436,12 @@ all_digits_p (const char *p, size_t len)
 }
 
 
-/* Collect all error lines from file descriptor FD. Only lines
-   prefixed with TAG are considered.  Close that file descriptor
-   then.  Returns a list of error line items (which may be empty).
-   There is no error return.  */
+/* Collect all error lines from stream FP. Only lines prefixed with
+   TAG are considered.  Returns a list of error line items (which may
+   be empty).  There is no error return.  */
 static error_line_t
-collect_error_output (int fd, const char *tag)
+collect_error_output (estream_t fp, const char *tag)
 {
-  FILE *fp;
   char buffer[1024];
   char *p, *p2, *p3;
   int c, cont_line;
@@ -1355,15 +1449,11 @@ collect_error_output (int fd, const char *tag)
   error_line_t eitem, errlines, *errlines_tail;
   size_t taglen = strlen (tag);
 
-  fp = fdopen (fd, "r");
-  if (!fp)
-    gc_error (1, errno, "can't fdopen pipe for reading");
-
   errlines = NULL;
   errlines_tail = &errlines;
   pos = 0;
   cont_line = 0;
-  while ((c=getc (fp)) != EOF)
+  while ((c=es_getc (fp)) != EOF)
     {
       buffer[pos++] = c;
       if (pos >= sizeof buffer - 5 || c == '\n')
@@ -1378,6 +1468,7 @@ collect_error_output (int fd, const char *tag)
               p = buffer + taglen + 1;
               while (*p == ' ' || *p == '\t')
                 p++;
+              trim_trailing_spaces (p); /* Get rid of extra CRs.  */
               if (!*p)
                 ; /* Empty lines are ignored.  */
               else if ( (p2 = strchr (p, ':')) && (p3 = strchr (p2+1, ':'))
@@ -1422,8 +1513,6 @@ collect_error_output (int fd, const char *tag)
     }
 
   /* We ignore error lines not terminated by a LF.  */
-
-  fclose (fp);
   return errlines;
 }
 
@@ -1431,7 +1520,7 @@ collect_error_output (int fd, const char *tag)
 /* Check the options of a single component.  Returns 0 if everything
    is OK.  */
 int
-gc_component_check_options (int component, FILE *out, const char *conf_file)
+gc_component_check_options (int component, estream_t out, const char *conf_file)
 {
   gpg_error_t err;
   unsigned int result;
@@ -1443,14 +1532,9 @@ gc_component_check_options (int component, FILE *out, const char *conf_file)
   int i;
   pid_t pid;
   int exitcode;
-  int filedes[2];
+  estream_t errfp;
   error_line_t errlines;
 
-  /* We use a temporary file to collect the error output.  It would be
-     better to use a pipe here but as of now we have no suitable
-     fucntion to create a portable pipe outside of exechelp.  Thus it
-     is easier to use the tempfile approach.  */
-
   for (backend = 0; backend < GC_BACKEND_NR; backend++)
     backend_seen[backend] = 0;
 
@@ -1481,34 +1565,31 @@ gc_component_check_options (int component, FILE *out, const char *conf_file)
       argv[i++] = "--options";
       argv[i++] = conf_file;
     }
-  argv[i++] = "--gpgconf-test";
+  if (component == GC_COMPONENT_PINENTRY)
+    argv[i++] = "--version";
+  else
+    argv[i++] = "--gpgconf-test";
   argv[i++] = NULL;
 
-  err = gnupg_create_inbound_pipe (filedes);
-  if (err)
-    gc_error (1, 0, _("error creating a pipe: %s\n"),
-             gpg_strerror (err));
-
   result = 0;
   errlines = NULL;
-  if (gnupg_spawn_process_fd (pgmname, argv, -1, -1, filedes[1], &pid))
-    {
-      close (filedes[0]);
-      close (filedes[1]);
-      result |= 1; /* Program could not be run.  */
-    }
+  err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT, NULL, 0,
+                             NULL, NULL, &errfp, &pid);
+  if (err)
+    result |= 1; /* Program could not be run.  */
   else
     {
-      close (filedes[1]);
-      errlines = collect_error_output (filedes[0],
+      errlines = collect_error_output (errfp,
                                       gc_component[component].name);
-      if (gnupg_wait_process (pgmname, pid, &exitcode))
+      if (gnupg_wait_process (pgmname, pid, 1, &exitcode))
        {
          if (exitcode == -1)
            result |= 1; /* Program could not be run or it
                            terminated abnormally.  */
          result |= 2; /* Program returned an error.  */
        }
+      gnupg_release_process (pid);
+      es_fclose (errfp);
     }
 
   /* If the program could not be run, we can't tell whether
@@ -1523,24 +1604,24 @@ gc_component_check_options (int component, FILE *out, const char *conf_file)
 
       desc = gc_component[component].desc;
       desc = my_dgettext (gc_component[component].desc_domain, desc);
-      fprintf (out, "%s:%s:",
-              gc_component[component].name, gc_percent_escape (desc));
-      fputs (gc_percent_escape (pgmname), out);
-      fprintf (out, ":%d:%d:", !(result & 1), !(result & 2));
+      es_fprintf (out, "%s:%s:",
+                  gc_component[component].name, gc_percent_escape (desc));
+      es_fputs (gc_percent_escape (pgmname), out);
+      es_fprintf (out, ":%d:%d:", !(result & 1), !(result & 2));
       for (errptr = errlines; errptr; errptr = errptr->next)
        {
          if (errptr != errlines)
-           fputs ("\n:::::", out); /* Continuation line.  */
+           es_fputs ("\n:::::", out); /* Continuation line.  */
          if (errptr->fname)
-           fputs (gc_percent_escape (errptr->fname), out);
-         putc (':', out);
+           es_fputs (gc_percent_escape (errptr->fname), out);
+         es_putc (':', out);
          if (errptr->fname)
-           fprintf (out, "%u", errptr->lineno);
-         putc (':', out);
-         fputs (gc_percent_escape (errptr->errtext), out);
-         putc (':', out);
+           es_fprintf (out, "%u", errptr->lineno);
+         es_putc (':', out);
+         es_fputs (gc_percent_escape (errptr->errtext), out);
+         es_putc (':', out);
        }
-      putc ('\n', out);
+      es_putc ('\n', out);
     }
 
   while (errlines)
@@ -1554,9 +1635,10 @@ gc_component_check_options (int component, FILE *out, const char *conf_file)
 }
 
 
+
 /* Check all components that are available.  */
 void
-gc_check_programs (FILE *out)
+gc_check_programs (estream_t out)
 {
   gc_component_t component;
 
@@ -1585,7 +1667,7 @@ gc_component_find (const char *name)
 \f
 /* List the option OPTION.  */
 static void
-list_one_option (const gc_option_t *option, FILE *out)
+list_one_option (const gc_option_t *option, estream_t out)
 {
   const char *desc = NULL;
   char *arg_name = NULL;
@@ -1615,16 +1697,16 @@ list_one_option (const gc_option_t *option, FILE *out)
      FIELDS.  */
 
   /* The name field.  */
-  fprintf (out, "%s", option->name);
+  es_fprintf (out, "%s", option->name);
 
   /* The flags field.  */
-  fprintf (out, ":%lu", option->flags);
+  es_fprintf (out, ":%lu", option->flags);
   if (opt.verbose)
     {
-      putc (' ', out);
+      es_putc (' ', out);
 
       if (!option->flags)
-       fprintf (out, "none");
+       es_fprintf (out, "none");
       else
        {
          unsigned long flags = option->flags;
@@ -1638,8 +1720,8 @@ list_one_option (const gc_option_t *option, FILE *out)
                  if (first)
                    first = 0;
                  else
-                   putc (',', out);
-                 fprintf (out, "%s", gc_flag[flag].name);
+                   es_putc (',', out);
+                 es_fprintf (out, "%s", gc_flag[flag].name);
                }
              flags >>= 1;
              flag++;
@@ -1648,34 +1730,33 @@ list_one_option (const gc_option_t *option, FILE *out)
     }
 
   /* The level field.  */
-  fprintf (out, ":%u", option->level);
+  es_fprintf (out, ":%u", option->level);
   if (opt.verbose)
-    fprintf (out, " %s", gc_level[option->level].name);
+    es_fprintf (out, " %s", gc_level[option->level].name);
 
   /* The description field.  */
-  fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
+  es_fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
 
   /* The type field.  */
-  fprintf (out, ":%u", option->arg_type);
+  es_fprintf (out, ":%u", option->arg_type);
   if (opt.verbose)
-    fprintf (out, " %s", gc_arg_type[option->arg_type].name);
+    es_fprintf (out, " %s", gc_arg_type[option->arg_type].name);
 
   /* The alternate type field.  */
-  fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
+  es_fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
   if (opt.verbose)
-    fprintf (out, " %s",
-            gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
+    es_fprintf (out, " %s",
+                gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
 
   /* The argument name field.  */
-  fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : "");
-  if (arg_name)
-    xfree (arg_name);
+  es_fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : "");
+  xfree (arg_name);
 
   /* The default value field.  */
-  fprintf (out, ":%s", option->default_value ? option->default_value : "");
+  es_fprintf (out, ":%s", option->default_value ? option->default_value : "");
 
   /* The default argument field.  */
-  fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
+  es_fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
 
   /* The value field.  */
   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
@@ -1683,19 +1764,19 @@ list_one_option (const gc_option_t *option, FILE *out)
       && option->value)
     /* The special format "1,1,1,1,...,1" is converted to a number
        here.  */
-    fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
+    es_fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
   else
-    fprintf (out, ":%s", option->value ? option->value : "");
+    es_fprintf (out, ":%s", option->value ? option->value : "");
 
   /* ADD NEW FIELDS HERE.  */
 
-  putc ('\n', out);
+  es_putc ('\n', out);
 }
 
 
 /* List all options of the component COMPONENT.  */
 void
-gc_component_list_options (int component, FILE *out)
+gc_component_list_options (int component, estream_t out)
 {
   const gc_option_t *option = gc_component[component].options;
 
@@ -1791,7 +1872,9 @@ get_config_filename (gc_component_t component, gc_backend_t backend)
   else
     filename = "";
 
-#ifdef HAVE_DOSISH_SYSTEM
+#if HAVE_W32CE_SYSTEM
+  if (!(filename[0] == '/' || filename[0] == '\\'))
+#elif defined(HAVE_DOSISH_SYSTEM)
   if (!(filename[0]
         && filename[1] == ':'
         && (filename[2] == '/' || filename[2] == '\\')))
@@ -1812,41 +1895,32 @@ static void
 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
 {
   gpg_error_t err;
-  int filedes[2];
   const char *pgmname;
   const char *argv[2];
+  estream_t outfp;
   int exitcode;
   pid_t pid;
   char *line = NULL;
   size_t line_len = 0;
   ssize_t length;
-  FILE *config;
+  estream_t config;
   char *config_filename;
 
-  err = gnupg_create_inbound_pipe (filedes);
-  if (err)
-    gc_error (1, 0, _("error creating a pipe: %s\n"), gpg_strerror (err));
-
   pgmname = (gc_backend[backend].module_name
              ? gnupg_module_name (gc_backend[backend].module_name)
              : gc_backend[backend].program );
   argv[0] = "--gpgconf-list";
   argv[1] = NULL;
 
-  err = gnupg_spawn_process_fd (pgmname, argv, -1, filedes[1], -1, &pid);
+  err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT, NULL, 0,
+                             NULL, &outfp, NULL, &pid);
   if (err)
     {
-      close (filedes[0]);
-      close (filedes[1]);
-      gc_error (1, 0, "could not gather active options from `%s': %s",
+      gc_error (1, 0, "could not gather active options from '%s': %s",
                 pgmname, gpg_strerror (err));
     }
-  close (filedes[1]);
-  config = fdopen (filedes[0], "r");
-  if (!config)
-    gc_error (1, errno, "can't fdopen pipe for reading");
 
-  while ((length = read_line (config, &line, &line_len, NULL)) > 0)
+  while ((length = es_read_line (outfp, &line, &line_len, NULL)) > 0)
     {
       gc_option_t *option;
       char *linep;
@@ -1872,7 +1946,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
          if (end)
            *(end++) = '\0';
 
-         errno = 0;
+         gpg_err_set_errno (0);
          flags = strtoul (linep, &tail, 0);
          if (errno)
            gc_error (1, errno, "malformed flags in option %s from %s",
@@ -1915,27 +1989,28 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
            option->default_value = xstrdup (default_value);
        }
     }
-  if (length < 0 || ferror (config))
-    gc_error (1, errno, "error reading from %s",pgmname);
-  if (fclose (config))
+  if (length < 0 || es_ferror (outfp))
+    gc_error (1, errno, "error reading from %s", pgmname);
+  if (es_fclose (outfp))
     gc_error (1, errno, "error closing %s", pgmname);
 
-  err = gnupg_wait_process (pgmname, pid, &exitcode);
+  err = gnupg_wait_process (pgmname, pid, 1, &exitcode);
   if (err)
     gc_error (1, 0, "running %s failed (exitcode=%d): %s",
               pgmname, exitcode, gpg_strerror (err));
+  gnupg_release_process (pid);
 
 
   /* At this point, we can parse the configuration file.  */
   config_filename = get_config_filename (component, backend);
 
-  config = fopen (config_filename, "r");
+  config = es_fopen (config_filename, "r");
   if (!config)
     gc_error (0, errno, "warning: can not open config file %s",
              config_filename);
   else
     {
-      while ((length = read_line (config, &line, &line_len, NULL)) > 0)
+      while ((length = es_read_line (config, &line, &line_len, NULL)) > 0)
        {
          char *name;
          char *value;
@@ -2016,9 +2091,9 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
            }
        }
 
-      if (length < 0 || ferror (config))
+      if (length < 0 || es_ferror (config))
        gc_error (1, errno, "error reading from %s", config_filename);
-      if (fclose (config))
+      if (es_fclose (config))
        gc_error (1, errno, "error closing %s", config_filename);
     }
 
@@ -2115,6 +2190,9 @@ gc_component_retrieve_options (int component)
   gc_backend_t backend;
   gc_option_t *option;
 
+  if (component == GC_COMPONENT_PINENTRY)
+    return; /* Dummy module for now.  */
+
   for (backend = 0; backend < GC_BACKEND_NR; backend++)
     backend_seen[backend] = 0;
 
@@ -2188,7 +2266,7 @@ option_check_validity (gc_option_t *option, unsigned long flags,
     {
       char *tail;
 
-      errno = 0;
+      gpg_err_set_errno (0);
       *new_value_nr = strtoul (new_value, &tail, 0);
 
       if (errno)
@@ -2242,8 +2320,11 @@ option_check_validity (gc_option_t *option, unsigned long flags,
        }
       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
        {
-         errno = 0;
-         (void) strtol (arg, &arg, 0);
+         long res;
+
+         gpg_err_set_errno (0);
+         res = strtol (arg, &arg, 0);
+         (void) res;
 
          if (errno)
            gc_error (1, errno, "invalid argument for option %s",
@@ -2253,10 +2334,13 @@ option_check_validity (gc_option_t *option, unsigned long flags,
            gc_error (1, 0, "garbage after argument for option %s",
                      option->name);
        }
-      else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32)
+      else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
        {
-         errno = 0;
-         (void) strtoul (arg, &arg, 0);
+         unsigned long res;
+
+         gpg_err_set_errno (0);
+         res = strtoul (arg, &arg, 0);
+         (void) res;
 
          if (errno)
            gc_error (1, errno, "invalid argument for option %s",
@@ -2292,7 +2376,7 @@ copy_file (const char *src_name, const char *dst_name)
     {
       int saved_err = errno;
       fclose (src);
-      errno = saved_err;
+      gpg_err_set_errno (saved_err);
       return -1;
     }
 
@@ -2315,7 +2399,7 @@ copy_file (const char *src_name, const char *dst_name)
       fclose (src);
       fclose (dst);
       unlink (dst_name);
-      errno = saved_errno;
+      gpg_err_set_errno (saved_errno);
       return -1;
     }
 
@@ -2336,7 +2420,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
                     char **src_filenamep, char **dest_filenamep,
                     char **orig_filenamep)
 {
-  static const char marker[] = "###+++--- GPGConf ---+++###";
+  static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
   /* True if we are within the marker in the config file.  */
   int in_marker = 0;
   gc_option_t *option;
@@ -2363,8 +2447,10 @@ change_options_file (gc_component_t component, gc_backend_t backend,
   /* Note that get_config_filename() calls percent_deescape(), so we
      call this before processing the arguments.  */
   dest_filename = xstrdup (get_config_filename (component, backend));
-  src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
-  orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
+  src_filename = xasprintf ("%s.%s.%i.new",
+                            dest_filename, GPGCONF_NAME, (int)getpid ());
+  orig_filename = xasprintf ("%s.%s.%i.bak",
+                             dest_filename, GPGCONF_NAME, (int)getpid ());
 
   arg = option->new_value;
   if (arg && arg[0] == '\0')
@@ -2394,10 +2480,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
   res = link (dest_filename, orig_filename);
 #endif
   if (res < 0 && errno != ENOENT)
-    {
-      xfree (dest_filename);
-      return -1;
-    }
+    return -1;
   if (res < 0)
     {
       xfree (orig_filename);
@@ -2418,7 +2501,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
   res = errno;
   if (!src_file)
     {
-      errno = res;
+      gpg_err_set_errno (res);
       return -1;
     }
 
@@ -2504,8 +2587,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
              if (!in_marker)
                {
                  fprintf (src_file,
-                          "# GPGConf disabled this option here at %s\n",
-                          asctimestamp (gnupg_get_time ()));
+                          "# %s disabled this option here at %s\n",
+                          GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
                  if (ferror (src_file))
                    goto change_file_one_err;
                  fprintf (src_file, "# %s", line);
@@ -2573,7 +2656,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
 
   if (!in_marker)
     {
-      fprintf (src_file, "# GPGConf edited this configuration file.\n");
+      fprintf (src_file, "# %s edited this configuration file.\n",
+               GPGCONF_DISP_NAME);
       if (ferror (src_file))
        goto change_file_one_err;
       fprintf (src_file, "# It will disable options before this marked "
@@ -2605,7 +2689,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
       close (fd);
       if (dest_file)
        fclose (dest_file);
-      errno = res;
+      gpg_err_set_errno (res);
       return -1;
     }
   close (fd);
@@ -2627,7 +2711,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
     }
   if (dest_file)
     fclose (dest_file);
-  errno = res;
+  gpg_err_set_errno (res);
   return -1;
 }
 
@@ -2639,7 +2723,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
                        char **src_filenamep, char **dest_filenamep,
                        char **orig_filenamep)
 {
-  static const char marker[] = "###+++--- GPGConf ---+++###";
+  static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
   /* True if we are within the marker in the config file.  */
   int in_marker = 0;
   gc_option_t *option;
@@ -2658,8 +2742,10 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 
   /* FIXME.  Throughout the function, do better error reporting.  */
   dest_filename = xstrdup (get_config_filename (component, backend));
-  src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
-  orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
+  src_filename = xasprintf ("%s.%s.%i.new",
+                            dest_filename, GPGCONF_NAME, (int)getpid ());
+  orig_filename = xasprintf ("%s.%s.%i.bak",
+                             dest_filename, GPGCONF_NAME, (int)getpid ());
 
 #ifdef HAVE_W32_SYSTEM
   res = copy_file (dest_filename, orig_filename);
@@ -2688,7 +2774,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
   res = errno;
   if (!src_file)
     {
-      errno = res;
+      gpg_err_set_errno (res);
       return -1;
     }
 
@@ -2750,8 +2836,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
              if (!in_marker)
                {
                  fprintf (src_file,
-                          "# GPGConf disabled this option here at %s\n",
-                          asctimestamp (gnupg_get_time ()));
+                          "# %s disabled this option here at %s\n",
+                          GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
                  if (ferror (src_file))
                    goto change_one_err;
                  fprintf (src_file, "# %s", line);
@@ -2871,7 +2957,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 
   if (!in_marker)
     {
-      fprintf (src_file, "# GPGConf edited this configuration file.\n");
+      fprintf (src_file, "# %s edited this configuration file.\n",
+               GPGCONF_DISP_NAME);
       if (ferror (src_file))
        goto change_one_err;
       fprintf (src_file, "# It will disable options before this marked "
@@ -2903,7 +2990,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
       close (fd);
       if (dest_file)
        fclose (dest_file);
-      errno = res;
+      gpg_err_set_errno (res);
       return -1;
     }
   close (fd);
@@ -2925,7 +3012,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
     }
   if (dest_file)
     fclose (dest_file);
-  errno = res;
+  gpg_err_set_errno (res);
   return -1;
 }
 
@@ -2974,7 +3061,7 @@ change_one_value (gc_option_t *option, int *runtime,
    modifications are expected to already have been set to the global
    table. */
 void
-gc_component_change_options (int component, FILE *in, FILE *out)
+gc_component_change_options (int component, estream_t in, estream_t out)
 {
   int err = 0;
   int runtime[GC_BACKEND_NR];
@@ -2987,6 +3074,9 @@ gc_component_change_options (int component, FILE *in, FILE *out)
   size_t line_len = 0;
   ssize_t length;
 
+  if (component == GC_COMPONENT_PINENTRY)
+    return; /* Dummy component for now.  */
+
   for (backend = 0; backend < GC_BACKEND_NR; backend++)
     {
       runtime[backend] = 0;
@@ -2998,7 +3088,7 @@ gc_component_change_options (int component, FILE *in, FILE *out)
   if (in)
     {
       /* Read options from the file IN.  */
-      while ((length = read_line (in, &line, &line_len, NULL)) > 0)
+      while ((length = es_read_line (in, &line, &line_len, NULL)) > 0)
         {
           char *linep;
           unsigned long flags = 0;
@@ -3023,7 +3113,7 @@ gc_component_change_options (int component, FILE *in, FILE *out)
               if (end)
                 *(end++) = '\0';
 
-              errno = 0;
+              gpg_err_set_errno (0);
               flags = strtoul (linep, &tail, 0);
               if (errno)
                 gc_error (1, errno, "malformed flags in option %s", line);
@@ -3093,7 +3183,7 @@ gc_component_change_options (int component, FILE *in, FILE *out)
                  gc_error (0, 0,
                            _("External verification of component %s failed"),
                            gc_component[component].name);
-                 errno = EINVAL;
+                 gpg_err_set_errno (EINVAL);
                }
            }
 
@@ -3198,7 +3288,7 @@ gc_component_change_options (int component, FILE *in, FILE *out)
     for (backend = 0; backend < GC_BACKEND_NR; backend++)
       {
        if (runtime[backend] && gc_backend[backend].runtime_change)
-         (*gc_backend[backend].runtime_change) ();
+         (*gc_backend[backend].runtime_change) (0);
       }
 
   /* Move the per-process backup file into its place.  */
@@ -3209,7 +3299,8 @@ gc_component_change_options (int component, FILE *in, FILE *out)
 
        assert (dest_filename[backend]);
 
-       backup_filename = xasprintf ("%s.gpgconf.bak", dest_filename[backend]);
+       backup_filename = xasprintf ("%s.%s.bak",
+                                     dest_filename[backend], GPGCONF_NAME);
 
 #ifdef HAVE_W32_SYSTEM
        /* There is no atomic update on W32.  */
@@ -3242,6 +3333,7 @@ key_matches_user_or_group (char *user)
   /* Under Windows we don't support groups. */
   if (group && *group)
     gc_error (0, 0, _("Note that group specifications are ignored\n"));
+#ifndef HAVE_W32CE_SYSTEM
   if (*user)
     {
       static char *my_name;
@@ -3261,6 +3353,7 @@ key_matches_user_or_group (char *user)
       if (!strcmp (user, my_name))
         return 1; /* Found.  */
     }
+#endif /*HAVE_W32CE_SYSTEM*/
 #else /*!HAVE_W32_SYSTEM*/
   /* First check whether the user matches.  */
   if (*user)
@@ -3339,7 +3432,7 @@ key_matches_user_or_group (char *user)
    returned on error. */
 int
 gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
-                         FILE *listfp)
+                         estream_t listfp)
 {
   int result = 0;
   char *line = NULL;
@@ -3356,7 +3449,8 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
   if (fname_arg)
     fname = xstrdup (fname_arg);
   else
-    fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
+    fname = make_filename (gnupg_sysconfdir (), GPGCONF_NAME EXTSEP_S "conf",
+                           NULL);
 
   for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
     runtime[backend_id] = 0;
@@ -3368,7 +3462,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
          when running in syntax check mode.  */
       if (errno != ENOENT || !update)
         {
-          gc_error (0, errno, "can not open global config file `%s'", fname);
+          gc_error (0, errno, "can not open global config file '%s'", fname);
           result = -1;
         }
       xfree (fname);
@@ -3402,7 +3496,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
             ;
           if (!*p)
             {
-              gc_error (0, 0, "missing rule at `%s', line %d", fname, lineno);
+              gc_error (0, 0, "missing rule at '%s', line %d", fname, lineno);
               result = -1;
               continue;
             }
@@ -3411,7 +3505,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         }
       else if (!in_rule)
         {
-          gc_error (0, 0, "continuation but no rule at `%s', line %d",
+          gc_error (0, 0, "continuation but no rule at '%s', line %d",
                     fname, lineno);
           result = -1;
           continue;
@@ -3431,7 +3525,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         ;
       if (p == component)
         {
-          gc_error (0, 0, "missing component at `%s', line %d",
+          gc_error (0, 0, "missing component at '%s', line %d",
                     fname, lineno);
           result = -1;
           continue;
@@ -3442,7 +3536,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
       component_id = gc_component_find (component);
       if (component_id < 0)
         {
-          gc_error (0, 0, "unknown component at `%s', line %d",
+          gc_error (0, 0, "unknown component at '%s', line %d",
                     fname, lineno);
           result = -1;
         }
@@ -3454,7 +3548,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         ;
       if (p == option)
         {
-          gc_error (0, 0, "missing option at `%s', line %d",
+          gc_error (0, 0, "missing option at '%s', line %d",
                     fname, lineno);
           result = -1;
           continue;
@@ -3466,7 +3560,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
           option_info = find_option (component_id, option, GC_BACKEND_ANY);
           if (!option_info)
             {
-              gc_error (0, 0, "unknown option at `%s', line %d",
+              gc_error (0, 0, "unknown option at '%s', line %d",
                         fname, lineno);
               result = -1;
             }
@@ -3482,7 +3576,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
           p = strchr (flags, ']');
           if (!p)
             {
-              gc_error (0, 0, "syntax error in rule at `%s', line %d",
+              gc_error (0, 0, "syntax error in rule at '%s', line %d",
                         fname, lineno);
               result = -1;
               continue;
@@ -3519,7 +3613,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
           if (*value)
             {
               gc_error (0, 0, "flag \"default\" may not be combined "
-                        "with a value at `%s', line %d",
+                        "with a value at '%s', line %d",
                         fname, lineno);
               result = -1;
             }
@@ -3530,7 +3624,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         ;
       else
         {
-          gc_error (0, 0, "unknown flag at `%s', line %d",
+          gc_error (0, 0, "unknown flag at '%s', line %d",
                     fname, lineno);
           result = -1;
         }
@@ -3549,19 +3643,19 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
                     *p = 0; /* We better strip any extra stuff. */
                 }
 
-              fprintf (listfp, "k:%s:", gc_percent_escape (key));
-              fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
+              es_fprintf (listfp, "k:%s:", gc_percent_escape (key));
+              es_fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
             }
 
           /* All other lines are rule records.  */
-          fprintf (listfp, "r:::%s:%s:%s:",
-                   gc_component[component_id].name,
-                   option_info->name? option_info->name : "",
-                   flags? flags : "");
+          es_fprintf (listfp, "r:::%s:%s:%s:",
+                      gc_component[component_id].name,
+                      option_info->name? option_info->name : "",
+                      flags? flags : "");
           if (value != empty)
-            fprintf (listfp, "\"%s", gc_percent_escape (value));
+            es_fprintf (listfp, "\"%s", gc_percent_escape (value));
 
-          putc ('\n', listfp);
+          es_putc ('\n', listfp);
         }
 
       /* Check whether the key matches but do this only if we are not
@@ -3586,8 +3680,6 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
 
           if (defaults)
             {
-              assert (component_id >= 0 && component_id < GC_COMPONENT_NR);
-
               /* Here we explicitly allow to update the value again.  */
               if (newflags)
                 {
@@ -3605,11 +3697,11 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
 
   if (length < 0 || ferror (config))
     {
-      gc_error (0, errno, "error reading from `%s'", fname);
+      gc_error (0, errno, "error reading from '%s'", fname);
       result = -1;
     }
-  if (fclose (config) && ferror (config))
-    gc_error (0, errno, "error closing `%s'", fname);
+  if (fclose (config))
+    gc_error (0, errno, "error closing '%s'", fname);
 
   xfree (line);
 
@@ -3631,7 +3723,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         {
           for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
             if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
-              (*gc_backend[backend_id].runtime_change) ();
+              (*gc_backend[backend_id].runtime_change) (0);
         }
     }
 
index eb7e9c9..31804f5 100644 (file)
@@ -1,5 +1,5 @@
 /* gpgconf.c - Configuration utility for GnuPG
- * Copyright (C) 2003, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2007, 2009, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -26,6 +26,8 @@
 #include "gpgconf.h"
 #include "i18n.h"
 #include "sysutils.h"
+#include "../common/init.h"
+
 
 /* Constants to identify the commands and options. */
 enum cmd_and_opt_values
@@ -49,8 +51,9 @@ enum cmd_and_opt_values
     aListConfig,
     aCheckConfig,
     aListDirs,
+    aLaunch,
+    aKill,
     aReload
-
   };
 
 
@@ -58,7 +61,7 @@ enum cmd_and_opt_values
 static ARGPARSE_OPTS opts[] =
   {
     { 300, NULL, 0, N_("@Commands:\n ") },
-    
+
     { aListComponents, "list-components", 256, N_("list all components") },
     { aCheckPrograms, "check-programs", 256, N_("check all programs") },
     { aListOptions, "list-options", 256, N_("|COMPONENT|list options") },
@@ -67,15 +70,17 @@ static ARGPARSE_OPTS opts[] =
     { aApplyDefaults, "apply-defaults", 256,
       N_("apply global default values") },
     { aListDirs, "list-dirs", 256,
-      N_("get the configuration directories for gpgconf") },
+      N_("get the configuration directories for @GPGCONF@") },
     { aListConfig,   "list-config", 256,
       N_("list global configuration file") },
     { aCheckConfig,   "check-config", 256,
       N_("check global configuration file") },
-    { aReload,        "reload", 256, "@" },
+    { aReload,        "reload", 256, N_("reload all or a given component")},
+    { aLaunch,        "launch", 256, N_("launch a given component")},
+    { aKill,          "kill", 256,   N_("kill a given component")},
 
     { 301, NULL, 0, N_("@\nOptions:\n ") },
-    
+
     { oOutput, "output",    2, N_("use as output file") },
     { oVerbose, "verbose",  0, N_("verbose") },
     { oQuiet, "quiet",      0, N_("quiet") },
@@ -95,18 +100,18 @@ my_strusage( int level )
 
   switch (level)
     {
-    case 11: p = "gpgconf (GnuPG)";
+    case 11: p = "@GPGCONF@ (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
 
     case 1:
-    case 40: p = _("Usage: gpgconf [options] (-h for help)");
+    case 40: p = _("Usage: @GPGCONF@ [options] (-h for help)");
       break;
     case 41:
-      p = _("Syntax: gpgconf [options]\n"
-            "Manage configuration options for tools of the GnuPG system\n");
+      p = _("Syntax: @GPGCONF@ [options]\n"
+            "Manage configuration options for tools of the @GNUPG@ system\n");
       break;
 
     default: p = NULL; break;
@@ -118,19 +123,19 @@ my_strusage( int level )
 /* Return the fp for the output.  This is usually stdout unless
    --output has been used.  In the latter case this function opens
    that file.  */
-static FILE *
-get_outfp (FILE **fp)
+static estream_t
+get_outfp (estream_t *fp)
 {
   if (!*fp)
     {
       if (opt.outfile)
         {
-          *fp = fopen (opt.outfile, "w");
+          *fp = es_fopen (opt.outfile, "w");
           if (!*fp)
-            gc_error (1, errno, "can not open `%s'", opt.outfile);
+            gc_error (1, errno, "can not open '%s'", opt.outfile);
         }
       else
-        *fp = stdout;
+        *fp = es_stdout;
     }
   return *fp;
 }
@@ -144,15 +149,15 @@ main (int argc, char **argv)
   const char *fname;
   int no_more_options = 0;
   enum cmd_and_opt_values cmd = 0;
-  FILE *outfp = NULL;
+  estream_t outfp = NULL;
 
-  gnupg_reopen_std ("gpgconf");
+  gnupg_reopen_std (GPGCONF_NAME);
   set_strusage (my_strusage);
-  log_set_prefix ("gpgconf", 1);
+  log_set_prefix (GPGCONF_NAME, 1);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   /* Parse the command line. */
   pargs.argc  = &argc;
@@ -181,6 +186,8 @@ main (int argc, char **argv)
         case aListConfig:
         case aCheckConfig:
         case aReload:
+        case aLaunch:
+        case aKill:
          cmd = pargs.r_opt;
          break;
 
@@ -190,9 +197,19 @@ main (int argc, char **argv)
 
   if (log_get_errorcount (0))
     exit (2);
-  
+
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+    {
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
+    }
+
   fname = argc ? *argv : NULL;
-  
+
   switch (cmd)
     {
     case aListComponents:
@@ -211,10 +228,10 @@ main (int argc, char **argv)
     case aCheckOptions:
       if (!fname)
        {
-         fputs (_("usage: gpgconf [options] "), stderr);
-         putc ('\n',stderr);
-         fputs (_("Need one component argument"), stderr);
-         putc ('\n',stderr);
+         es_fprintf (es_stderr, _("usage: %s [options] "), GPGCONF_NAME);
+         es_putc ('\n', es_stderr);
+         es_fputs (_("Need one component argument"), es_stderr);
+         es_putc ('\n', es_stderr);
          exit (2);
        }
       else
@@ -222,11 +239,11 @@ main (int argc, char **argv)
          int idx = gc_component_find (fname);
          if (idx < 0)
            {
-             fputs (_("Component not found"), stderr);
-             putc ('\n', stderr);
+             es_fputs (_("Component not found"), es_stderr);
+             es_putc ('\n', es_stderr);
              exit (1);
            }
-         if (cmd == aCheckOptions)
+          if (cmd == aCheckOptions)
            gc_component_check_options (idx, get_outfp (&outfp), NULL);
           else
             {
@@ -236,11 +253,40 @@ main (int argc, char **argv)
               if (cmd == aListOptions)
                 gc_component_list_options (idx, get_outfp (&outfp));
               else if (cmd == aChangeOptions)
-                gc_component_change_options (idx, stdin, get_outfp (&outfp));
+                gc_component_change_options (idx, es_stdin, get_outfp (&outfp));
             }
        }
       break;
 
+    case aLaunch:
+    case aKill:
+      if (!fname)
+       {
+         es_fprintf (es_stderr, _("usage: %s [options] "), GPGCONF_NAME);
+         es_putc ('\n', es_stderr);
+         es_fputs (_("Need one component argument"), es_stderr);
+         es_putc ('\n', es_stderr);
+         exit (2);
+       }
+      else
+        {
+          /* Launch/Kill a given component.  */
+          int idx;
+
+          idx = gc_component_find (fname);
+          if (idx < 0)
+            {
+              es_fputs (_("Component not found"), es_stderr);
+              es_putc ('\n', es_stderr);
+              exit (1);
+            }
+          else if (cmd == aLaunch)
+            gc_component_launch (idx);
+          else
+            gc_component_kill (idx);
+        }
+      break;
+
     case aReload:
       if (!fname)
        {
@@ -255,8 +301,8 @@ main (int argc, char **argv)
           idx = gc_component_find (fname);
           if (idx < 0)
             {
-              fputs (_("Component not found"), stderr);
-              putc ('\n', stderr);
+              es_fputs (_("Component not found"), es_stderr);
+              es_putc ('\n', es_stderr);
               exit (1);
             }
           else
@@ -279,70 +325,64 @@ main (int argc, char **argv)
     case aApplyDefaults:
       if (fname)
        {
-         fputs (_("usage: gpgconf [options] "), stderr);
-         putc ('\n',stderr);
-         fputs (_("No argument allowed"), stderr);
-         putc ('\n',stderr);
+         es_fprintf (es_stderr, _("usage: %s [options] "), GPGCONF_NAME);
+         es_putc ('\n', es_stderr);
+         es_fputs (_("No argument allowed"), es_stderr);
+         es_putc ('\n', es_stderr);
          exit (2);
        }
       gc_component_retrieve_options (-1);
       if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
         exit (1);
       break;
-      
+
     case aListDirs:
       /* Show the system configuration directories for gpgconf.  */
       get_outfp (&outfp);
-      fprintf (outfp, "sysconfdir:%s\n",
-              gc_percent_escape (gnupg_sysconfdir ()));
-      fprintf (outfp, "bindir:%s\n",
-              gc_percent_escape (gnupg_bindir ()));
-      fprintf (outfp, "libexecdir:%s\n",
-              gc_percent_escape (gnupg_libexecdir ()));
-      fprintf (outfp, "libdir:%s\n",
-              gc_percent_escape (gnupg_libdir ()));
-      fprintf (outfp, "datadir:%s\n",
-              gc_percent_escape (gnupg_datadir ()));
-      fprintf (outfp, "localedir:%s\n",
-              gc_percent_escape (gnupg_localedir ()));
-      fprintf (outfp, "dirmngr-socket:%s\n",
-              gc_percent_escape (dirmngr_socket_name ()));
+      es_fprintf (outfp, "sysconfdir:%s\n",
+                  gc_percent_escape (gnupg_sysconfdir ()));
+      es_fprintf (outfp, "bindir:%s\n",
+                  gc_percent_escape (gnupg_bindir ()));
+      es_fprintf (outfp, "libexecdir:%s\n",
+                  gc_percent_escape (gnupg_libexecdir ()));
+      es_fprintf (outfp, "libdir:%s\n",
+                  gc_percent_escape (gnupg_libdir ()));
+      es_fprintf (outfp, "datadir:%s\n",
+                  gc_percent_escape (gnupg_datadir ()));
+      es_fprintf (outfp, "localedir:%s\n",
+                  gc_percent_escape (gnupg_localedir ()));
+
+      if (dirmngr_user_socket_name ())
+        {
+          es_fprintf (outfp, "dirmngr-socket:%s\n",
+                      gc_percent_escape (dirmngr_user_socket_name ()));
+          es_fprintf (outfp, "dirmngr-sys-socket:%s\n",
+                      gc_percent_escape (dirmngr_sys_socket_name ()));
+        }
+      else
+        {
+          es_fprintf (outfp, "dirmngr-socket:%s\n",
+                      gc_percent_escape (dirmngr_sys_socket_name ()));
+        }
+
       {
-        char *infostr = getenv ("GPG_AGENT_INFO");
-
-        if (!infostr || !*infostr)
-          infostr = make_filename (default_homedir (), "S.gpg-agent", NULL);
-        else
-          {
-            char *tmp;
-
-            infostr = xstrdup (infostr);
-            tmp = strchr (infostr, PATHSEP_C);
-            if (!tmp || tmp == infostr)
-              {
-                xfree (infostr);
-                infostr = NULL;
-              }
-            else
-              *tmp = 0;
-          }
-        fprintf (outfp, "agent-socket:%s\n",
-                 infostr? gc_percent_escape (infostr) : "");
-        xfree (infostr);
+        char *tmp = make_filename (default_homedir (),
+                                   GPG_AGENT_SOCK_NAME, NULL);
+        es_fprintf (outfp, "agent-socket:%s\n", gc_percent_escape (tmp));
+        xfree (tmp);
       }
       {
         /* We need to use make_filename to expand a possible "~/".  */
         char *tmp = make_filename (default_homedir (), NULL);
-        fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp));
+        es_fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp));
         xfree (tmp);
       }
       break;
     }
 
-  if (outfp && outfp != stdout)
-    if (fclose (outfp))
-      gc_error (1, errno, "error closing `%s'", opt.outfile);
+  if (outfp != es_stdout)
+    if (es_fclose (outfp))
+      gc_error (1, errno, "error closing '%s'", opt.outfile);
 
-  return 0; 
+  return 0;
 }
-
index be9172a..0286c27 100644 (file)
@@ -44,14 +44,20 @@ char *gc_percent_escape (const char *src);
 
 void gc_error (int status, int errnum, const char *fmt, ...);
 
+/* Launch given component.  */
+void gc_component_launch (int component);
+
+/* Kill given component.  */
+void gc_component_kill (int component);
+
 /* Reload given component.  */
 void gc_component_reload (int component);
 
 /* List all components that are available.  */
-void gc_component_list_components (FILE *out);
+void gc_component_list_components (estream_t out);
 
 /* List all programs along with their status.  */
-void gc_check_programs (FILE *out);
+void gc_check_programs (estream_t out);
 
 /* Find the component with the name NAME.  Returns -1 if not
    found.  */
@@ -62,19 +68,19 @@ int gc_component_find (const char *name);
 void gc_component_retrieve_options (int component);
 
 /* List all options of the component COMPONENT.  */
-void gc_component_list_options (int component, FILE *out);
+void gc_component_list_options (int component, estream_t out);
 
 /* Read the modifications from IN and apply them.  */
-void gc_component_change_options (int component, FILE *in, FILE *out);
+void gc_component_change_options (int component, estream_t in, estream_t out);
 
 /* Check the options of a single component.  Returns 0 if everything
    is OK.  */
-int gc_component_check_options (int component, FILE *out,
+int gc_component_check_options (int component, estream_t out,
                                const char *conf_file);
 
 /* Process global configuration file.  */
 int gc_process_gpgconf_conf (const char *fname, int update, int defaults,
-                             FILE *listfp);
+                             estream_t listfp);
 
 
 #endif /*GPGCONF_H*/
index d22c5ac..903fb5b 100644 (file)
@@ -224,8 +224,6 @@ key_to_blob (unsigned char **blob, size_t *blob_n, const char *identifier, ...)
       assert (ret == 1);
     }
 
-  va_end (ap);
-
   blob_new_n = ftell (stream);
   rewind (stream);
 
index 6265efc..a8b3dc7 100644 (file)
@@ -199,7 +199,7 @@ run_gnupg (int smime, int sig_fd, int data_fd, int *close_list)
       /* Send stdout to the bit bucket. */
       fd = open ("/dev/null", O_WRONLY);
       if (fd == -1)
-        die ("can't open `/dev/null': %s", strerror (errno));
+        die ("can't open '/dev/null': %s", strerror (errno));
       if (fd != 1)
        {
           if (dup2 (fd, 1) == -1)
@@ -517,7 +517,7 @@ message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
                   strcpy (stpcpy (stpcpy (buf, s1), "/"), s2);
                   assert (info->signing_protocol);
                   if (strcmp (buf, info->signing_protocol))
-                    err ("invalid %s structure; expected `%s', found `%s'",
+                    err ("invalid %s structure; expected '%s', found '%s'",
                          info->is_smime? "S/MIME":"PGP/MIME",
                          info->signing_protocol, buf);
                   else
@@ -654,7 +654,7 @@ parse_message (FILE *fp)
           /* Delay hashing of the CR/LF because the last line ending
              belongs to the next boundary. */
           if (debug)
-            printf ("# hashing %s`%s'\n", info.hashing==2?"CR,LF+":"", line);
+            printf ("# hashing %s'%s'\n", info.hashing==2?"CR,LF+":"", line);
           if (opt_crypto)
             {
               if (info.hashing == 2)
@@ -791,7 +791,7 @@ main (int argc, char **argv)
     {
       FILE *fp = fopen (*argv, "rb");
       if (!fp)
-        die ("can't open `%s': %s", *argv, strerror (errno));
+        die ("can't open '%s': %s", *argv, strerror (errno));
       parse_message (fp);
       fclose (fp);
     }
index 3f093c3..78e87aa 100644 (file)
 #ifdef HAVE_DOSISH_SYSTEM
 # include <fcntl.h> /* for setmode() */
 #endif
-#include <zlib.h>
+#ifdef HAVE_ZIP
+# include <zlib.h>
+#endif
 #ifdef HAVE_BZIP2
-#include <bzlib.h>
+# include <bzlib.h>
 #endif /* HAVE_BZIP2 */
 #if defined(__riscos__) && defined(USE_ZLIBRISCOS)
 # include "zlib-riscos.h"
@@ -54,9 +56,9 @@ static void split_packets (const char *fname);
 enum cmd_and_opt_values {
   aNull = 0,
   oVerbose       = 'v',
-  oPrefix       = 'p',                          
-  oUncompress   = 500,                      
-  oSecretToPublic,                      
+  oPrefix       = 'p',
+  oUncompress   = 500,
+  oSecretToPublic,
   oNoSplit,
 
   aTest
@@ -81,7 +83,7 @@ my_strusage (int level)
   const char *p;
   switch (level)
     {
-    case 11: p = "gpgsplit (GnuPG)";
+    case 11: p = "gpgsplit (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -95,7 +97,7 @@ my_strusage (int level)
                   "Syntax: gpgsplit [options] [files]\n"
                   "Split an OpenPGP message into packets\n";
     break;
-    
+
     default:   p = NULL;
     }
   return p;
@@ -114,7 +116,7 @@ main (int argc, char **argv)
 #endif
   log_set_prefix ("gpgsplit", JNLIB_LOG_WITH_PREFIX);
   set_strusage (my_strusage);
-  
+
   pargs.argc = &argc;
   pargs.argv = &argv;
   pargs.flags=  1;  /* do not remove the args */
@@ -130,7 +132,7 @@ main (int argc, char **argv)
         default : pargs.err = 2; break;
        }
     }
-  
+
   if (log_get_errorcount(0))
     g10_exit (2);
 
@@ -138,12 +140,12 @@ main (int argc, char **argv)
     split_packets (NULL);
   else
     {
-      for ( ;argc; argc--, argv++) 
+      for ( ;argc; argc--, argv++)
         split_packets (*argv);
     }
-  
+
   g10_exit (0);
-  return 0; 
+  return 0;
 }
 
 
@@ -168,7 +170,7 @@ pkttype_to_string (int pkttype)
     case PKT_SECRET_KEY    : s = "secret_key"; break;
     case PKT_PUBLIC_KEY    : s = "public_key"; break;
     case PKT_SECRET_SUBKEY : s = "secret_subkey"; break;
-    case PKT_COMPRESSED    : 
+    case PKT_COMPRESSED    :
       s = opt_uncompress? "uncompressed":"compressed";
       break;
     case PKT_ENCRYPTED     : s = "encrypted"; break;
@@ -191,17 +193,17 @@ pkttype_to_string (int pkttype)
 
 /*
  * Create a new filename and a return a pointer to a statically
- * allocated buffer 
+ * allocated buffer
  */
 static char *
 create_filename (int pkttype)
 {
   static unsigned int partno = 0;
   static char *name;
-  
-  if (!name) 
+
+  if (!name)
     name = xmalloc (strlen (opt_prefix) + 100 );
-  
+
   assert (pkttype < 1000 && pkttype >= 0 );
   partno++;
   sprintf (name, "%s%06u-%03d" EXTSEP_S "%.40s",
@@ -227,7 +229,7 @@ static int
 read_u32 (FILE *fp, unsigned long *rn)
 {
   size_t tmp;
-  
+
   if (read_u16 (fp, &tmp))
     return -1;
   *rn = tmp << 16;
@@ -239,9 +241,9 @@ read_u32 (FILE *fp, unsigned long *rn)
 
 static int
 write_old_header (FILE *fp, int pkttype, unsigned int len)
-{     
+{
   int ctb = (0x80 | ((pkttype & 15)<<2));
-  
+
   if (len < 256)
     ;
   else if (len < 65536)
@@ -271,7 +273,7 @@ write_old_header (FILE *fp, int pkttype, unsigned int len)
 
 static int
 write_new_header (FILE *fp, int pkttype, unsigned int len)
-{     
+{
   if ( putc ((0xc0 | (pkttype & 0x3f)), fp) == EOF )
     return -1;
 
@@ -313,9 +315,9 @@ public_key_length (const unsigned char *buf, size_t buflen)
   int nmpis;
 
   /*   byte version number (3 or 4)
-       u32  creation time 
+       u32  creation time
        [u16  valid days (version 3 only)]
-       byte algorithm 
+       byte algorithm
        n    MPIs (n and e) */
   if (!buflen)
     return 0;
@@ -360,6 +362,7 @@ public_key_length (const unsigned char *buf, size_t buflen)
   return s - buf;
 }
 
+#ifdef HAVE_ZIP
 static int
 handle_zlib(int algo,FILE *fpin,FILE *fpout)
 {
@@ -368,7 +371,7 @@ handle_zlib(int algo,FILE *fpin,FILE *fpout)
   unsigned int inbufsize, outbufsize;
   int c,zinit_done, zrc, nread, count;
   size_t n;
-              
+
   memset (&zs, 0, sizeof zs);
   inbufsize = 2048;
   inbuf = xmalloc (inbufsize);
@@ -376,7 +379,7 @@ handle_zlib(int algo,FILE *fpin,FILE *fpout)
   outbuf = xmalloc (outbufsize);
   zs.avail_in = 0;
   zinit_done = 0;
-              
+
   do
     {
       if (zs.avail_in < inbufsize)
@@ -387,11 +390,11 @@ handle_zlib(int algo,FILE *fpin,FILE *fpout)
          count = inbufsize - n;
          for (nread=0;
               nread < count && (c=getc (fpin)) != EOF;
-              nread++) 
+              nread++)
            inbuf[n+nread] = c;
-                      
+
          n += nread;
-         if (nread < count && algo == 1) 
+         if (nread < count && algo == 1)
            {
              inbuf[n] = 0xFF; /* chew dummy byte */
              n++;
@@ -400,12 +403,12 @@ handle_zlib(int algo,FILE *fpin,FILE *fpout)
        }
       zs.next_out = (Bytef *) outbuf;
       zs.avail_out = outbufsize;
-                    
-      if (!zinit_done) 
+
+      if (!zinit_done)
        {
          zrc = (algo == 1? inflateInit2 ( &zs, -13)
                 : inflateInit ( &zs ));
-         if (zrc != Z_OK) 
+         if (zrc != Z_OK)
            {
              log_fatal ("zlib problem: %s\n", zs.msg? zs.msg :
                         zrc == Z_MEM_ERROR ? "out of core" :
@@ -431,17 +434,17 @@ handle_zlib(int algo,FILE *fpin,FILE *fpout)
              else
                log_fatal ("zlib inflate problem: rc=%d\n", zrc );
            }
-         for (n=0; n < outbufsize - zs.avail_out; n++) 
+         for (n=0; n < outbufsize - zs.avail_out; n++)
            {
              if (putc (outbuf[n], fpout) == EOF )
                return 1;
            }
        }
-    } 
+    }
   while (zrc != Z_STREAM_END && zrc != Z_BUF_ERROR);
   {
     int i;
-    
+
     fputs ("Left over bytes:", stderr);
     for (i=0; i < zs.avail_in; i++)
       fprintf (stderr, " %02X", zs.next_in[i]);
@@ -452,6 +455,7 @@ handle_zlib(int algo,FILE *fpin,FILE *fpout)
 
   return 0;
 }
+#endif /*HAVE_ZIP*/
 
 #ifdef HAVE_BZIP2
 static int
@@ -462,7 +466,7 @@ handle_bzip2(int algo,FILE *fpin,FILE *fpout)
   unsigned int inbufsize, outbufsize;
   int c,zinit_done, zrc, nread, count;
   size_t n;
-              
+
   memset (&bzs, 0, sizeof bzs);
   inbufsize = 2048;
   inbuf = xmalloc (inbufsize);
@@ -470,7 +474,7 @@ handle_bzip2(int algo,FILE *fpin,FILE *fpout)
   outbuf = xmalloc (outbufsize);
   bzs.avail_in = 0;
   zinit_done = 0;
-              
+
   do
     {
       if (bzs.avail_in < inbufsize)
@@ -481,11 +485,11 @@ handle_bzip2(int algo,FILE *fpin,FILE *fpout)
          count = inbufsize - n;
          for (nread=0;
               nread < count && (c=getc (fpin)) != EOF;
-              nread++) 
+              nread++)
            inbuf[n+nread] = c;
-                      
+
          n += nread;
-         if (nread < count && algo == 1) 
+         if (nread < count && algo == 1)
            {
              inbuf[n] = 0xFF; /* chew dummy byte */
              n++;
@@ -494,11 +498,11 @@ handle_bzip2(int algo,FILE *fpin,FILE *fpout)
        }
       bzs.next_out = outbuf;
       bzs.avail_out = outbufsize;
-                    
-      if (!zinit_done) 
+
+      if (!zinit_done)
        {
          zrc = BZ2_bzDecompressInit(&bzs,0,0);
-         if (zrc != BZ_OK) 
+         if (zrc != BZ_OK)
            log_fatal ("bz2lib problem: %d\n",zrc);
          zinit_done = 1;
        }
@@ -509,13 +513,13 @@ handle_bzip2(int algo,FILE *fpin,FILE *fpout)
            ; /* eof */
          else if (zrc != BZ_OK && zrc != BZ_PARAM_ERROR)
            log_fatal ("bz2lib inflate problem: %d\n", zrc );
-         for (n=0; n < outbufsize - bzs.avail_out; n++) 
+         for (n=0; n < outbufsize - bzs.avail_out; n++)
            {
              if (putc (outbuf[n], fpout) == EOF )
                return 1;
            }
        }
-    } 
+    }
   while (zrc != BZ_STREAM_END && zrc != BZ_PARAM_ERROR);
   BZ2_bzDecompressEnd(&bzs);
 
@@ -532,7 +536,7 @@ write_part (FILE *fpin, unsigned long pktlen,
   int c, first;
   unsigned char *p;
   const char *outname = create_filename (pkttype);
-  
+
 #if defined(__riscos__) && defined(USE_ZLIBRISCOS)
   static int initialized = 0;
 
@@ -544,11 +548,11 @@ write_part (FILE *fpin, unsigned long pktlen,
   else
     {
       if (opt_verbose)
-        log_info ("writing `%s'\n", outname);
+        log_info ("writing '%s'\n", outname);
       fpout = fopen (outname, "wb");
-      if (!fpout) 
+      if (!fpout)
         {
-          log_error ("error creating `%s': %s\n", outname, strerror(errno));
+          log_error ("error creating '%s': %s\n", outname, strerror(errno));
           /* stop right now, otherwise we would mess up the sequence
              of the part numbers */
           g10_exit (1);
@@ -563,10 +567,10 @@ write_part (FILE *fpin, unsigned long pktlen,
 
       pkttype = pkttype == PKT_SECRET_KEY? PKT_PUBLIC_KEY:PKT_PUBLIC_SUBKEY;
 
-      for (i=0; i < pktlen; i++) 
+      for (i=0; i < pktlen; i++)
         {
           c = getc (fpin);
-          if (c == EOF) 
+          if (c == EOF)
             goto read_error;
           blob[i] = c;
         }
@@ -577,17 +581,17 @@ write_part (FILE *fpin, unsigned long pktlen,
           g10_exit (1);
         }
       if ( (hdr[0] & 0x40) )
-        { 
+        {
           if (write_new_header (fpout, pkttype, len))
             goto write_error;
         }
       else
-        { 
+        {
           if (write_old_header (fpout, pkttype, len))
             goto write_error;
         }
 
-      for (i=0; i < len; i++) 
+      for (i=0; i < len; i++)
         {
           if ( putc (blob[i], fpout) == EOF )
             goto write_error;
@@ -605,12 +609,12 @@ write_part (FILE *fpin, unsigned long pktlen,
             goto write_error;
         }
     }
-  
+
   first = 1;
   while (partial)
     {
       size_t partlen;
-      
+
       if (partial == 1)
         { /* openpgp */
           if (first )
@@ -619,11 +623,11 @@ write_part (FILE *fpin, unsigned long pktlen,
               assert( c >= 224 && c < 255 );
               first = 0;
             }
-          else if ((c = getc (fpin)) == EOF ) 
+          else if ((c = getc (fpin)) == EOF )
             goto read_error;
           else
             hdr[hdrlen++] = c;
-            
+
           if (c < 192)
             {
               pktlen = c;
@@ -632,7 +636,7 @@ write_part (FILE *fpin, unsigned long pktlen,
           else if (c < 224 )
             {
               pktlen = (c - 192) * 256;
-              if ((c = getc (fpin)) == EOF) 
+              if ((c = getc (fpin)) == EOF)
                 goto read_error;
               hdr[hdrlen++] = c;
               pktlen += c + 192;
@@ -656,9 +660,9 @@ write_part (FILE *fpin, unsigned long pktlen,
                     goto write_error;
                 }
               partlen = 1 << (c & 0x1f);
-              for (; partlen; partlen--) 
+              for (; partlen; partlen--)
                 {
-                  if ((c = getc (fpin)) == EOF) 
+                  if ((c = getc (fpin)) == EOF)
                     goto read_error;
                   if ( putc (c, fpout) == EOF )
                     goto write_error;
@@ -672,17 +676,17 @@ write_part (FILE *fpin, unsigned long pktlen,
             goto read_error;
           hdr[hdrlen++] = partlen >> 8;
           hdr[hdrlen++] = partlen;
-          for (p=hdr; hdrlen; p++, hdrlen--) 
+          for (p=hdr; hdrlen; p++, hdrlen--)
             {
               if ( putc (*p, fpout) == EOF )
                 goto write_error;
             }
           if (!partlen)
             partial = 0; /* end of packet */
-          for (; partlen; partlen--) 
+          for (; partlen; partlen--)
             {
               c = getc (fpin);
-              if (c == EOF) 
+              if (c == EOF)
                 goto read_error;
               if ( putc (c, fpout) == EOF )
                 goto write_error;
@@ -693,16 +697,20 @@ write_part (FILE *fpin, unsigned long pktlen,
           pktlen = 0;
           partial = 0;
           hdrlen = 0;
-          if (opt_uncompress) 
+          if (opt_uncompress)
             {
               if ((c = getc (fpin)) == EOF)
                 goto read_error;
 
-             if(c==1 || c==2)
+             if (0)
+                ;
+#ifdef HAVE_ZIP
+             else if(c==1 || c==2)
                {
                  if(handle_zlib(c,fpin,fpout))
                    goto write_error;
                }
+#endif /* HAVE_ZIP */
 #ifdef HAVE_BZIP2
              else if(c==3)
                {
@@ -718,7 +726,7 @@ write_part (FILE *fpin, unsigned long pktlen,
             }
           else
             {
-              while ( (c=getc (fpin)) != EOF ) 
+              while ( (c=getc (fpin)) != EOF )
                 {
                   if ( putc (c, fpout) == EOF )
                     goto write_error;
@@ -729,33 +737,33 @@ write_part (FILE *fpin, unsigned long pktlen,
        }
     }
 
-  for (p=hdr; hdrlen; p++, hdrlen--) 
+  for (p=hdr; hdrlen; p++, hdrlen--)
     {
       if ( putc (*p, fpout) == EOF )
         goto write_error;
     }
-  
+
   /* standard packet or last segment of partial length encoded packet */
-  for (; pktlen; pktlen--) 
+  for (; pktlen; pktlen--)
     {
       c = getc (fpin);
-      if (c == EOF) 
+      if (c == EOF)
         goto read_error;
       if ( putc (c, fpout) == EOF )
         goto write_error;
     }
-  
+
  ready:
   if ( !opt_no_split && fclose (fpout) )
-    log_error ("error closing `%s': %s\n", outname, strerror (errno));
+    log_error ("error closing '%s': %s\n", outname, strerror (errno));
   return 0;
-  
- write_error:    
-  log_error ("error writing `%s': %s\n", outname, strerror (errno));
+
+ write_error:
+  log_error ("error writing '%s': %s\n", outname, strerror (errno));
   if (!opt_no_split)
     fclose (fpout);
   return 2;
-  
+
  read_error:
   if (!opt_no_split)
     {
@@ -776,12 +784,12 @@ do_split (FILE *fp)
   int partial = 0;
   unsigned char header[20];
   int header_idx = 0;
-  
+
   ctb = getc (fp);
   if (ctb == EOF)
     return 3; /* ready */
   header[header_idx++] = ctb;
-  
+
   if (!(ctb & 0x80))
     {
       log_error("invalid CTB %02x\n", ctb );
@@ -799,19 +807,19 @@ do_split (FILE *fp)
       else if ( c < 224 )
         {
           pktlen = (c - 192) * 256;
-          if( (c = getc (fp)) == EOF ) 
+          if( (c = getc (fp)) == EOF )
             return -1;
           header[header_idx++] = c;
           pktlen += c + 192;
        }
-      else if ( c == 255 ) 
+      else if ( c == 255 )
         {
           if (read_u32 (fp, &pktlen))
             return -1;
           header[header_idx++] = pktlen >> 24;
           header[header_idx++] = pktlen >> 16;
           header[header_idx++] = pktlen >> 8;
-          header[header_idx++] = pktlen; 
+          header[header_idx++] = pktlen;
        }
       else
         { /* partial body length */
@@ -822,7 +830,7 @@ do_split (FILE *fp)
   else
     {
       int lenbytes;
-      
+
       pkttype = (ctb>>2)&0xf;
       lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
       if (!lenbytes )
@@ -835,13 +843,13 @@ do_split (FILE *fp)
        }
       else
         {
-          for ( ; lenbytes; lenbytes-- ) 
+          for ( ; lenbytes; lenbytes-- )
             {
               pktlen <<= 8;
-              if( (c = getc (fp)) == EOF ) 
+              if( (c = getc (fp)) == EOF )
                 return -1;
               header[header_idx++] = c;
-              
+
               pktlen |= c;
            }
        }
@@ -856,27 +864,27 @@ split_packets (const char *fname)
 {
   FILE *fp;
   int rc;
-  
+
   if (!fname || !strcmp (fname, "-"))
     {
       fp = stdin;
       fname = "-";
     }
-  else if ( !(fp = fopen (fname,"rb")) ) 
+  else if ( !(fp = fopen (fname,"rb")) )
     {
-      log_error ("can't open `%s': %s\n", fname, strerror (errno));
+      log_error ("can't open '%s': %s\n", fname, strerror (errno));
       return;
     }
-  
+
   while ( !(rc = do_split (fp)) )
     ;
   if ( rc > 0 )
     ; /* error already handled */
   else if ( ferror (fp) )
-    log_error ("error reading `%s': %s\n", fname, strerror (errno));
+    log_error ("error reading '%s': %s\n", fname, strerror (errno));
   else
-    log_error ("premature EOF while reading `%s'\n", fname );
-  
+    log_error ("premature EOF while reading '%s'\n", fname );
+
   if ( fp != stdin )
     fclose (fp);
 }
index 09587e4..fad6d57 100644 (file)
@@ -28,7 +28,6 @@
 #ifdef HAVE_W32_SYSTEM
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
-# include <fcntl.h> /* for setmode() */
 #else /*!HAVE_W32_SYSTEM*/
 # include <unistd.h>
 # include <pwd.h>
@@ -78,12 +77,12 @@ fillup_entry_w32 (tar_header_t hdr)
       *p = '/';
   if (!wfname)
     {
-      log_error ("error utf8-ing `%s': %s\n", hdr->name, w32_strerror (-1));
+      log_error ("error utf8-ing '%s': %s\n", hdr->name, w32_strerror (-1));
       return gpg_error_from_syserror ();
     }
   if (!GetFileAttributesExW (wfname, GetFileExInfoStandard, &fad))
     {
-      log_error ("error stat-ing `%s': %s\n", hdr->name, w32_strerror (-1));
+      log_error ("error stat-ing '%s': %s\n", hdr->name, w32_strerror (-1));
       xfree (wfname);
       return gpg_error_from_syserror ();
     }
@@ -109,9 +108,9 @@ fillup_entry_w32 (tar_header_t hdr)
   if ((attr & FILE_ATTRIBUTE_READONLY))
     hdr->mode &= ~0200;  /* Clear the user write bit.  */
   if ((attr & FILE_ATTRIBUTE_HIDDEN))
-    hdr->mode &= ~0707;  /* Clear all user and other bits.  */ 
+    hdr->mode &= ~0707;  /* Clear all user and other bits.  */
   if ((attr & FILE_ATTRIBUTE_SYSTEM))
-    hdr->mode |= 0004;   /* Make it readable by other.  */ 
+    hdr->mode |= 0004;   /* Make it readable by other.  */
 
   /* Only set the size for a regular file.  */
   if (hdr->typeflag == TF_REGULAR)
@@ -131,7 +130,7 @@ fillup_entry_w32 (tar_header_t hdr)
 #endif /*HAVE_W32_SYSTEM*/
 
 
-/* Given a fresh header obje`<ct HDR with only the name field set, try
+/* Given a fresh header object HDR with only the name field set, try
    to gather all available info.  This is the POSIX version.  */
 #ifndef HAVE_W32_SYSTEM
 static gpg_error_t
@@ -143,10 +142,10 @@ fillup_entry_posix (tar_header_t hdr)
   if (lstat (hdr->name, &sbuf))
     {
       err = gpg_error_from_syserror ();
-      log_error ("error stat-ing `%s': %s\n", hdr->name, gpg_strerror (err));
+      log_error ("error stat-ing '%s': %s\n", hdr->name, gpg_strerror (err));
       return err;
     }
-  
+
   if (S_ISREG (sbuf.st_mode))
     hdr->typeflag = TF_REGULAR;
   else if (S_ISDIR (sbuf.st_mode))
@@ -159,7 +158,7 @@ fillup_entry_posix (tar_header_t hdr)
     hdr->typeflag = TF_FIFO;
   else if (S_ISLNK (sbuf.st_mode))
     hdr->typeflag = TF_SYMLINK;
-  else 
+  else
     hdr->typeflag = TF_NOTSUP;
 
   /* FIXME: Save DEV and INO? */
@@ -206,7 +205,7 @@ fillup_entry_posix (tar_header_t hdr)
     hdr->size = sbuf.st_size;
 
   hdr->mtime = sbuf.st_mtime;
-  
+
   return 0;
 }
 #endif /*!HAVE_W32_SYSTEM*/
@@ -253,7 +252,7 @@ add_entry (const char *dname, const char *entryname, scanctrl_t scanctrl)
   else
     {
       if (opt.verbose)
-        gpgtar_print_header (hdr, es_stderr);
+        gpgtar_print_header (hdr, log_get_stream ());
       *scanctrl->flist_tail = hdr;
       scanctrl->flist_tail = &hdr->next;
     }
@@ -304,7 +303,7 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
     if (!wfname)
       {
         err = gpg_error_from_syserror ();
-        log_error (_("error reading directory `%s': %s\n"),
+        log_error (_("error reading directory '%s': %s\n"),
                    dname, gpg_strerror (err));
         goto leave;
       }
@@ -312,7 +311,7 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
     if (hd == INVALID_HANDLE_VALUE)
       {
         err = gpg_error_from_syserror ();
-        log_error (_("error reading directory `%s': %s\n"),
+        log_error (_("error reading directory '%s': %s\n"),
                    dname, w32_strerror (-1));
         xfree (wfname);
         goto leave;
@@ -320,7 +319,7 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
     xfree (wfname);
   }
 
-  do 
+  do
     {
       char *fname = wchar_to_utf8 (fi.cFileName);
       if (!fname)
@@ -347,11 +346,11 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
     err = 0;
   else
     {
-      err = gpg_error_from_syserror (); 
-      log_error (_("error reading directory `%s': %s\n"),
+      err = gpg_error_from_syserror ();
+      log_error (_("error reading directory '%s': %s\n"),
                  dname, w32_strerror (-1));
     }
-  
+
  leave:
   if (hd != INVALID_HANDLE_VALUE)
     FindClose (hd);
@@ -367,16 +366,16 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
   if (!dir)
     {
       err = gpg_error_from_syserror ();
-      log_error (_("error reading directory `%s': %s\n"),
+      log_error (_("error reading directory '%s': %s\n"),
                  dname, gpg_strerror (err));
       return err;
     }
-  
+
   while ((de = readdir (dir)))
     {
       if (!strcmp (de->d_name, "." ) || !strcmp (de->d_name, ".."))
         continue; /* Skip self and parent dir entry.  */
-      
+
       err = add_entry (dname, de->d_name, scanctrl);
       if (err)
         goto leave;
@@ -411,10 +410,10 @@ scan_recursive (const char *dname, scanctrl_t scanctrl)
     if (hdr->typeflag == TF_DIRECTORY)
       {
         if (opt.verbose > 1)
-          log_info ("scanning directory `%s'\n", hdr->name);
+          log_info ("scanning directory '%s'\n", hdr->name);
         scan_recursive (hdr->name, scanctrl);
       }
-  
+
   scanctrl->nestlevel--;
   return err;
 }
@@ -435,7 +434,7 @@ pattern_valid_p (const char *pattern)
        || (*pattern >= 'A' && *pattern <= 'Z'))
       && pattern[1] == ':')
     return 0; /* Drive letter are not allowed either.  */
-#endif /*HAVE_DRIVE_LETTERS*/ 
+#endif /*HAVE_DRIVE_LETTERS*/
 
   return 1; /* Okay.  */
 }
@@ -506,14 +505,14 @@ store_uname (char *buffer, size_t length, unsigned long uid)
   if (!initialized || uid != lastuid)
     {
 #ifdef HAVE_W32_SYSTEM
-      mem2str (lastuname, uid? "user":"root", sizeof lastuname); 
+      mem2str (lastuname, uid? "user":"root", sizeof lastuname);
 #else
       struct passwd *pw = getpwuid (uid);
 
       lastuid = uid;
       initialized = 1;
       if (pw)
-        mem2str (lastuname, pw->pw_name, sizeof lastuname); 
+        mem2str (lastuname, pw->pw_name, sizeof lastuname);
       else
         {
           log_info ("failed to get name for uid %lu\n", uid);
@@ -535,14 +534,14 @@ store_gname (char *buffer, size_t length, unsigned long gid)
   if (!initialized || gid != lastgid)
     {
 #ifdef HAVE_W32_SYSTEM
-      mem2str (lastgname, gid? "users":"root", sizeof lastgname); 
+      mem2str (lastgname, gid? "users":"root", sizeof lastgname);
 #else
       struct group *gr = getgrgid (gid);
 
       lastgid = gid;
       initialized = 1;
       if (gr)
-        mem2str (lastgname, gr->gr_name, sizeof lastgname); 
+        mem2str (lastgname, gr->gr_name, sizeof lastgname);
       else
         {
           log_info ("failed to get name for gid %lu\n", gid);
@@ -569,7 +568,7 @@ build_header (void *record, tar_header_t hdr)
   namelen = strlen (hdr->name);
   if (namelen < sizeof raw->name)
     memcpy (raw->name, hdr->name, namelen);
-  else 
+  else
     {
       n = (namelen < sizeof raw->prefix)? namelen : sizeof raw->prefix;
       for (n--; n ; n--)
@@ -585,12 +584,12 @@ build_header (void *record, tar_header_t hdr)
       else
         {
           err = gpg_error (GPG_ERR_TOO_LARGE);
-          log_error ("error storing file `%s': %s\n", 
+          log_error ("error storing file '%s': %s\n",
                      hdr->name, gpg_strerror (err));
           return err;
         }
     }
-  
+
   store_xoctal (raw->mode,  sizeof raw->mode,  hdr->mode);
   store_xoctal (raw->uid,   sizeof raw->uid,   hdr->uid);
   store_xoctal (raw->gid,   sizeof raw->gid,   hdr->gid);
@@ -625,7 +624,7 @@ build_header (void *record, tar_header_t hdr)
       if (nread < 0)
         {
           err = gpg_error_from_syserror ();
-          log_error ("error reading symlink `%s': %s\n", 
+          log_error ("error reading symlink '%s': %s\n",
                      hdr->name, gpg_strerror (err));
           return err;
         }
@@ -660,7 +659,7 @@ write_file (estream_t stream, tar_header_t hdr)
     {
       if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
         {
-          log_info ("skipping unsupported file `%s'\n", hdr->name);
+          log_info ("skipping unsupported file '%s'\n", hdr->name);
           err = 0;
         }
       return err;
@@ -672,7 +671,7 @@ write_file (estream_t stream, tar_header_t hdr)
       if (!infp)
         {
           err = gpg_error_from_syserror ();
-          log_error ("can't open `%s': %s - skipped\n",
+          log_error ("can't open '%s': %s - skipped\n",
                      hdr->name, gpg_strerror (err));
           return err;
         }
@@ -697,7 +696,7 @@ write_file (estream_t stream, tar_header_t hdr)
           if (nread != nbytes)
             {
               err = gpg_error_from_syserror ();
-              log_error ("error reading file `%s': %s%s\n",
+              log_error ("error reading file '%s': %s%s\n",
                          hdr->name, gpg_strerror (err),
                          any? " (file shrunk?)":"");
               goto leave;
@@ -709,15 +708,15 @@ write_file (estream_t stream, tar_header_t hdr)
         }
       nread = es_fread (record, 1, 1, infp);
       if (nread)
-        log_info ("note: file `%s' has grown\n", hdr->name);
+        log_info ("note: file '%s' has grown\n", hdr->name);
     }
 
  leave:
   if (err)
     es_fclose (infp);
   else if ((err = es_fclose (infp)))
-    log_error ("error closing file `%s': %s\n", hdr->name, gpg_strerror (err));
-      
+    log_error ("error closing file '%s': %s\n", hdr->name, gpg_strerror (err));
+
   return err;
 }
 
@@ -750,10 +749,8 @@ gpgtar_create (char **inpattern)
   estream_t outstream = NULL;
   int eof_seen = 0;
 
-#ifdef HAVE_DOSISH_SYSTEM
   if (!inpattern)
-    setmode (es_fileno (es_stdin), O_BINARY);
-#endif
+    es_set_binary (es_stdin);
 
   memset (scanctrl, 0, sizeof *scanctrl);
   scanctrl->flist_tail = &scanctrl->flist;
@@ -770,7 +767,7 @@ gpgtar_create (char **inpattern)
           if (!pattern)
             break; /* End of array.  */
           inpattern++;
-          
+
           if (!*pattern)
             continue;
 
@@ -781,7 +778,7 @@ gpgtar_create (char **inpattern)
           int c;
           char namebuf[4096];
           size_t n = 0;
-          
+
           for (;;)
             {
               if ((c = es_getc (es_stdin)) == EOF)
@@ -789,7 +786,7 @@ gpgtar_create (char **inpattern)
                   if (es_ferror (es_stdin))
                     {
                       err = gpg_error_from_syserror ();
-                      log_error ("error reading `%s': %s\n",
+                      log_error ("error reading '%s': %s\n",
                                  "[stdin]", strerror (errno));
                       goto leave;
                     }
@@ -802,7 +799,7 @@ gpgtar_create (char **inpattern)
                   if (!skip_this)
                     {
                       skip_this = 1;
-                      log_error ("error reading `%s': %s\n",
+                      log_error ("error reading '%s': %s\n",
                                  "[stdin]", "filename too long");
                     }
                 }
@@ -814,7 +811,7 @@ gpgtar_create (char **inpattern)
                   break;
                 }
             }
-          
+
           if (skip_this || n < 2)
             continue;
 
@@ -832,11 +829,11 @@ gpgtar_create (char **inpattern)
           *p = '/';
 
       if (opt.verbose > 1)
-        log_info ("scanning `%s'\n", pat);
+        log_info ("scanning '%s'\n", pat);
 
       start_tail = scanctrl->flist_tail;
       if (skip_this || !pattern_valid_p (pat))
-        log_error ("skipping invalid name `%s'\n", pat);
+        log_error ("skipping invalid name '%s'\n", pat);
       else if (!add_entry (pat, NULL, scanctrl)
                && *start_tail && ((*start_tail)->typeflag & TF_DIRECTORY))
         scan_recursive (pat, scanctrl);
@@ -853,7 +850,7 @@ gpgtar_create (char **inpattern)
       if (!outstream)
         {
           err = gpg_error_from_syserror ();
-          log_error (_("can't create `%s': %s\n"),
+          log_error (_("can't create '%s': %s\n"),
                      opt.outfile, gpg_strerror (err));
           goto leave;
         }
@@ -863,10 +860,8 @@ gpgtar_create (char **inpattern)
       outstream = es_stdout;
     }
 
-#ifdef HAVE_DOSISH_SYSTEM
   if (outstream == es_stdout)
-    setmode (es_fileno (es_stdout), O_BINARY);
-#endif
+    es_set_binary (es_stdout);
 
   for (hdr = scanctrl->flist; hdr; hdr = hdr->next)
     {
@@ -887,12 +882,12 @@ gpgtar_create (char **inpattern)
     }
   if (err)
     {
-      log_error ("creating tarball `%s' failed: %s\n",
+      log_error ("creating tarball '%s' failed: %s\n",
                  es_fname_get (outstream), gpg_strerror (err));
       if (outstream && outstream != es_stdout)
         es_fclose (outstream);
       if (opt.outfile)
-        remove (opt.outfile);
+        gnupg_remove (opt.outfile);
     }
   scanctrl->flist_tail = NULL;
   while ( (hdr = scanctrl->flist) )
index b0d31e0..1ea3597 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 #include <assert.h>
-#ifdef HAVE_W32_SYSTEM
-# include <fcntl.h> /* for setmode() */
-#endif /*HAVE_W32_SYSTEM*/
 
 #include "i18n.h"
 #include "../common/sysutils.h"
 #include "gpgtar.h"
 
-#ifndef GPG_ERR_LIMIT_REACHED
-#define GPG_ERR_LIMIT_REACHED 183
-#endif
-
 
 static gpg_error_t
 extract_regular (estream_t stream, const char *dirname,
@@ -58,12 +51,12 @@ extract_regular (estream_t stream, const char *dirname,
     }
   else
     err = 0;
-  
+
   outfp = es_fopen (fname, "wb");
   if (!outfp)
     {
       err = gpg_error_from_syserror ();
-      log_error ("error creating `%s': %s\n", fname, gpg_strerror (err));
+      log_error ("error creating '%s': %s\n", fname, gpg_strerror (err));
       goto leave;
     }
 
@@ -73,16 +66,12 @@ extract_regular (estream_t stream, const char *dirname,
       if (err)
         goto leave;
       n++;
-      if (n < hdr->nrecords || (hdr->size && !(hdr->size % RECORDSIZE)))
-        nbytes = RECORDSIZE;
-      else
-        nbytes = (hdr->size % RECORDSIZE);
-
+      nbytes = (n < hdr->nrecords)? RECORDSIZE : (hdr->size % RECORDSIZE);
       nwritten = es_fwrite (record, 1, nbytes, outfp);
       if (nwritten != nbytes)
         {
           err = gpg_error_from_syserror ();
-          log_error ("error writing `%s': %s\n", fname, gpg_strerror (err));
+          log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
           goto leave;
         }
     }
@@ -90,12 +79,12 @@ extract_regular (estream_t stream, const char *dirname,
 
  leave:
   if (!err && opt.verbose)
-    log_info ("extracted `%s'\n", fname);
+    log_info ("extracted '%s'\n", fname);
   es_fclose (outfp);
   if (err && fname && outfp)
     {
-      if (remove (fname))
-        log_error ("error removing incomplete file `%s': %s\n",
+      if (gnupg_remove (fname))
+        log_error ("error removing incomplete file '%s': %s\n",
                    fname, gpg_strerror (gpg_error_from_syserror ()));
     }
   xfree (fname);
@@ -109,7 +98,7 @@ extract_directory (const char *dirname, tar_header_t hdr)
   gpg_error_t err;
   char *fname;
   size_t prefixlen;
-  
+
   prefixlen = strlen (dirname) + 1;
   fname = strconcat (dirname, "/", hdr->name, NULL);
   if (!fname)
@@ -135,7 +124,7 @@ extract_directory (const char *dirname, tar_header_t hdr)
              original error code in case of a failure.  */
           char *p;
           int rc = 0;
-          
+
           for (p = fname+prefixlen; (p = strchr (p, '/')); p++)
             {
               *p = 0;
@@ -148,13 +137,13 @@ extract_directory (const char *dirname, tar_header_t hdr)
             err = 0;
         }
       if (err)
-        log_error ("error creating directory `%s': %s\n",
+        log_error ("error creating directory '%s': %s\n",
                    fname, gpg_strerror (err));
     }
 
  leave:
   if (!err && opt.verbose)
-    log_info ("created   `%s/'\n", fname);
+    log_info ("created   '%s/'\n", fname);
   xfree (fname);
   return err;
 }
@@ -170,19 +159,19 @@ extract (estream_t stream, const char *dirname, tar_header_t hdr)
 #ifdef HAVE_DOSISH_SYSTEM
   if (strchr (hdr->name, '\\'))
     {
-      log_error ("filename `%s' contains a backslash - "
+      log_error ("filename '%s' contains a backslash - "
                  "can't extract on this system\n", hdr->name);
       return gpg_error (GPG_ERR_INV_NAME);
     }
 #endif /*HAVE_DOSISH_SYSTEM*/
 
   if (!n
-      || strstr (hdr->name, "//") 
-      || strstr (hdr->name, "/../") 
+      || strstr (hdr->name, "//")
+      || strstr (hdr->name, "/../")
       || !strncmp (hdr->name, "../", 3)
       || (n >= 3 && !strcmp (hdr->name+n-3, "/.." )))
     {
-      log_error ("filename `%s' as suspicious parts - not extracting\n",
+      log_error ("filename '%s' as suspicious parts - not extracting\n",
                  hdr->name);
       return gpg_error (GPG_ERR_INV_NAME);
     }
@@ -195,7 +184,7 @@ extract (estream_t stream, const char *dirname, tar_header_t hdr)
     {
       char record[RECORDSIZE];
 
-      log_info ("unsupported file type %d for `%s' - skipped\n",
+      log_info ("unsupported file type %d for '%s' - skipped\n",
                 (int)hdr->typeflag, hdr->name);
       for (err = 0, n=0; !err && n < hdr->nrecords; n++)
         err = read_record (stream, record);
@@ -219,7 +208,7 @@ create_directory (const char *dirprefix)
 
   /* Remove common suffixes.  */
   n = strlen (dirprefix);
-  if (n > 4 && (!compare_filenames    (dirprefix + n - 4, EXTSEP_S "gpg")
+  if (n > 4 && (!compare_filenames    (dirprefix + n - 4, EXTSEP_S GPGEXT_GPG)
                 || !compare_filenames (dirprefix + n - 4, EXTSEP_S "pgp")
                 || !compare_filenames (dirprefix + n - 4, EXTSEP_S "asc")
                 || !compare_filenames (dirprefix + n - 4, EXTSEP_S "pem")
@@ -283,25 +272,23 @@ gpgtar_extract (const char *filename)
   if (filename)
     {
       if (!strcmp (filename, "-"))
-        stream = es_stdin;
+        stream = es_stdout;
       else
         stream = es_fopen (filename, "rb");
       if (!stream)
         {
           err = gpg_error_from_syserror ();
-          log_error ("error opening `%s': %s\n", filename, gpg_strerror (err));
+          log_error ("error opening '%s': %s\n", filename, gpg_strerror (err));
           return;
         }
     }
   else
     stream = es_stdin;
 
-#ifdef HAVE_DOSISH_SYSTEM
   if (stream == es_stdin)
-    setmode (es_fileno (es_stdin), O_BINARY);
-#endif
+    es_set_binary (es_stdin);
 
-  if (filename && stream != es_stdin)
+  if (filename)
     {
       dirprefix = strrchr (filename, '/');
       if (dirprefix)
@@ -329,14 +316,14 @@ gpgtar_extract (const char *filename)
     }
 
   if (opt.verbose)
-    log_info ("extracting to `%s/'\n", dirname);
+    log_info ("extracting to '%s/'\n", dirname);
 
   for (;;)
     {
       header = gpgtar_read_header (stream);
       if (!header)
         goto leave;
-     
+
       if (extract (stream, dirname, header))
         goto leave;
       xfree (header);
index 0df7a26..d525d24 100644 (file)
@@ -23,7 +23,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#include <fcntl.h>
 
 #include "i18n.h"
 #include "gpgtar.h"
@@ -277,23 +276,21 @@ gpgtar_list (const char *filename)
   if (filename)
     {
       if (!strcmp (filename, "-"))
-        stream = es_stdin;
+        stream = es_stdout;
       else
         stream = es_fopen (filename, "rb");
       if (!stream)
         {
           err = gpg_error_from_syserror ();
-          log_error ("error opening `%s': %s\n", filename, gpg_strerror (err));
+          log_error ("error opening '%s': %s\n", filename, gpg_strerror (err));
           return;
         }
     }
   else
     stream = es_stdin;
 
-#ifdef HAVE_DOSISH_SYSTEM
   if (stream == es_stdin)
-    setmode (es_fileno (es_stdin), O_BINARY);
-#endif
+    es_set_binary (es_stdin);
 
   for (;;)
     {
index f88964f..e9a25fb 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#ifdef HAVE_STAT
-# include <sys/stat.h>
-#endif
 
 #include "util.h"
 #include "i18n.h"
 #include "sysutils.h"
 #include "../common/openpgpdefs.h"
+#include "../common/init.h"
 
 #include "gpgtar.h"
 
@@ -74,7 +72,7 @@ enum cmd_and_opt_values
 /* The list of commands and options. */
 static ARGPARSE_OPTS opts[] = {
   ARGPARSE_group (300, N_("@Commands:\n ")),
-    
+
   ARGPARSE_c (aEncrypt,   "encrypt", N_("create an archive")),
   ARGPARSE_c (aDecrypt,   "decrypt", N_("extract an archive")),
   ARGPARSE_c (aSign,      "sign",    N_("create a signed archive")),
@@ -117,7 +115,7 @@ my_strusage( int level )
 
   switch (level)
     {
-    case 11: p = "gpgtar (GnuPG)";
+    case 11: p = "@GPGTAR@ (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -149,7 +147,7 @@ set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
     cmd = aSignEncrypt;
   else if (cmd == aEncrypt && new_cmd == aSign)
     cmd = aSignEncrypt;
-  else 
+  else
     {
       log_error (_("conflicting commands\n"));
       exit (2);
@@ -174,13 +172,13 @@ main (int argc, char **argv)
 
   assert (sizeof (struct ustar_raw_header) == 512);
 
-  gnupg_reopen_std ("gpgtar");
+  gnupg_reopen_std (GPGTAR_NAME);
   set_strusage (my_strusage);
-  log_set_prefix ("gpgtar", 1);
+  log_set_prefix (GPGTAR_NAME, 1);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   /* Parse the command line. */
   pargs.argc  = &argc;
@@ -197,7 +195,7 @@ main (int argc, char **argv)
         case oNoVerbose: opt.verbose = 0; break;
         case oFilesFrom: files_from = pargs.r.ret_str; break;
         case oNull: null_names = 1; break;
-          
+
        case aList:
         case aDecrypt:
         case aEncrypt:
@@ -220,7 +218,7 @@ main (int argc, char **argv)
         default: pargs.err = 2; break;
        }
     }
-  
+
   if ((files_from && !null_names) || (!files_from && null_names))
     log_error ("--files-from and --null may only be used in conjunction\n");
   if (files_from && strcmp (files_from, "-"))
@@ -229,6 +227,16 @@ main (int argc, char **argv)
   if (log_get_errorcount (0))
     exit (2);
 
+  /* Print a warning if an argument looks like an option.  */
+  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+    {
+      int i;
+
+      for (i=0; i < argc; i++)
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+          log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
+    }
+
   switch (cmd)
     {
     case aList:
@@ -296,10 +304,10 @@ read_record (estream_t stream, void *record)
     {
       err = gpg_error_from_syserror ();
       if (es_ferror (stream))
-        log_error ("error reading `%s': %s\n",
+        log_error ("error reading '%s': %s\n",
                    es_fname_get (stream), gpg_strerror (err));
       else
-        log_error ("error reading `%s': premature EOF "
+        log_error ("error reading '%s': premature EOF "
                    "(size of last record: %zu)\n",
                    es_fname_get (stream), nread);
     }
@@ -322,12 +330,12 @@ write_record (estream_t stream, const void *record)
   if (nwritten != RECORDSIZE)
     {
       err = gpg_error_from_syserror ();
-      log_error ("error writing `%s': %s\n",
+      log_error ("error writing '%s': %s\n",
                  es_fname_get (stream), gpg_strerror (err));
     }
   else
     err = 0;
-  
+
   return err;
 }
 
@@ -344,9 +352,9 @@ openpgp_message_p (estream_t fp)
   if (ctb != EOF)
     {
       if (es_ungetc (ctb, fp))
-        log_fatal ("error ungetting first byte: %s\n", 
+        log_fatal ("error ungetting first byte: %s\n",
                    gpg_strerror (gpg_error_from_syserror ()));
-      
+
       if ((ctb & 0x80))
         {
           switch ((ctb & 0x40) ? (ctb & 0x3f) : ((ctb>>2)&0xf))
@@ -398,141 +406,3 @@ decrypt_and_list (const char *fname)
   (void)fname;
   log_error ("decrypt_and_list has not yet been implemented\n");
 }
-
-
-
-
-/* A wrapper around mkdir which takes a string for the mode argument.
-   This makes it easier to handle the mode argument which is not
-   defined on all systems.  The format of the modestring is
-
-      "-rwxrwxrwx"
-      
-   '-' is a don't care or not set.  'r', 'w', 'x' are read allowed,
-   write allowed, execution allowed with the first group for the user,
-   the second for the group and the third for all others.  If the
-   string is shorter than above the missing mode characters are meant
-   to be not set.  */
-int
-gnupg_mkdir (const char *name, const char *modestr)
-{
-#ifdef HAVE_W32CE_SYSTEM
-  wchar_t *wname;
-  (void)modestr;
-  
-  wname = utf8_to_wchar (name);
-  if (!wname)
-    return -1;
-  if (!CreateDirectoryW (wname, NULL))
-    {
-      xfree (wname);
-      return -1;  /* ERRNO is automagically provided by gpg-error.h.  */
-    }
-  xfree (wname);
-  return 0;
-#elif MKDIR_TAKES_ONE_ARG
-  (void)modestr;
-  /* Note: In the case of W32 we better use CreateDirectory and try to
-     set appropriate permissions.  However using mkdir is easier
-     because this sets ERRNO.  */
-  return mkdir (name);
-#else
-  mode_t mode = 0;
-
-  if (modestr && *modestr)
-    {
-      modestr++;
-      if (*modestr && *modestr++ == 'r')
-        mode |= S_IRUSR;
-      if (*modestr && *modestr++ == 'w')
-        mode |= S_IWUSR;
-      if (*modestr && *modestr++ == 'x')
-        mode |= S_IXUSR;
-      if (*modestr && *modestr++ == 'r')
-        mode |= S_IRGRP;
-      if (*modestr && *modestr++ == 'w')
-        mode |= S_IWGRP;
-      if (*modestr && *modestr++ == 'x')
-        mode |= S_IXGRP;
-      if (*modestr && *modestr++ == 'r')
-        mode |= S_IROTH;
-      if (*modestr && *modestr++ == 'w')
-        mode |= S_IWOTH;
-      if (*modestr && *modestr++ == 'x')
-        mode |= S_IXOTH;
-    }
-  return mkdir (name, mode);
-#endif
-}
-
-#ifdef HAVE_W32_SYSTEM
-/* Return a malloced string encoded in UTF-8 from the wide char input
-   string STRING.  Caller must free this value.  Returns NULL and sets
-   ERRNO on failure.  Calling this function with STRING set to NULL is
-   not defined.  */
-char *
-wchar_to_utf8 (const wchar_t *string)
-{
-  int n;
-  char *result;
-
-  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
-  if (n < 0)
-    {
-      errno = EINVAL;
-      return NULL;
-    }
-
-  result = xtrymalloc (n+1);
-  if (!result)
-    return NULL;
-
-  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
-  if (n < 0)
-    {
-      xfree (result);
-      errno = EINVAL;
-      result = NULL;
-    }
-  return result;
-}
-
-
-/* Return a malloced wide char string from an UTF-8 encoded input
-   string STRING.  Caller must free this value.  Returns NULL and sets
-   ERRNO on failure.  Calling this function with STRING set to NULL is
-   not defined.  */
-wchar_t *
-utf8_to_wchar (const char *string)
-{
-  int n;
-  size_t nbytes;
-  wchar_t *result;
-
-  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
-  if (n < 0)
-    {
-      errno = EINVAL;
-      return NULL;
-    }
-
-  nbytes = (size_t)(n+1) * sizeof(*result);
-  if (nbytes / sizeof(*result) != (n+1)) 
-    {
-      errno = ENOMEM;
-      return NULL;
-    }
-  result = xtrymalloc (nbytes);
-  if (!result)
-    return NULL;
-
-  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
-  if (n < 0)
-    {
-      free (result);
-      errno = EINVAL;
-      result = NULL;
-    }
-  return result;
-}
-#endif /*HAVE_W32_SYSTEM*/
index 5790894..08dfcf8 100644 (file)
@@ -21,7 +21,6 @@
 #define GPGTAR_H
 
 #include "../common/util.h"
-#include "../common/estream.h"
 
 /* We keep all global options in the structure OPT.  */
 struct
@@ -111,12 +110,6 @@ struct tar_header_s
 gpg_error_t read_record (estream_t stream, void *record);
 gpg_error_t write_record (estream_t stream, const void *record);
 
-int gnupg_mkdir (const char *name, const char *modestr);
-#ifdef HAVE_W32_SYSTEM
-char *wchar_to_utf8 (const wchar_t *string);
-wchar_t *utf8_to_wchar (const char *string);
-#endif
-
 /*-- gpgtar-create.c --*/
 void gpgtar_create (char **inpattern);
 
index 757d7af..c63001a 100755 (executable)
@@ -81,7 +81,7 @@ function myflush()
          print "Hi,"                                        | sendmail
          print ""                                           | sendmail
          print "Here you get back the signed key."          | sendmail
-        print "Please send it yourself to a keyserver."    | sendmail
+        print "I already sent them to the keyservers."     | sendmail
          print ""                                           | sendmail
          print "Peace,"                                     | sendmail
          print "      " signame                             | sendmail
index 9328dc1..b197961 100644 (file)
@@ -44,12 +44,12 @@ main(int argc, char **argv)
       argc -= 2;
       argv += 2;
     }
-      
+
   limit = argc ? atoi(argv[0]) : 0;
 
   srand(getpid());
 
-  for (i=0; !limit || i < limit; i++ ) 
+  for (i=0; !limit || i < limit; i++ )
     {
       if (char_mode)
         {
index 4cfedcc..b56cc38 100644 (file)
@@ -4,7 +4,7 @@
  * 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
@@ -22,7 +22,7 @@
 
 
 /* Replace libgcrypt's malloc functions which are used by
-   ../jnlib/libjnlib.a .  ../common/util.h defines macros to map them
+   ../common/libcommon.a .  ../common/util.h defines macros to map them
    to xmalloc etc. */
 static void
 out_of_memory (void)
@@ -115,30 +115,48 @@ gcry_free (void *a)
 
 /* We need this dummy because exechelp.c uses gcry_control to
    terminate the secure memeory.  */
-gcry_error_t 
+gcry_error_t
 gcry_control (enum gcry_ctl_cmds cmd, ...)
 {
   (void)cmd;
   return 0;
 }
 
-void 
+void
 gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque)
 {
   (void)h;
   (void)opaque;
 }
 
-void 
+void
 gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque)
 {
   (void)fnc;
   (void)opaque;
 }
 
-void 
+void
 gcry_set_log_handler (gcry_handler_log_t f, void *opaque)
 {
   (void)f;
   (void)opaque;
 }
+
+
+void
+gcry_create_nonce (void *buffer, size_t length)
+{
+  (void)buffer;
+  (void)length;
+
+  log_fatal ("unexpected call to gcry_create_nonce\n");
+}
+
+
+const char *
+gcry_cipher_algo_name (int algo)
+{
+  (void)algo;
+  return "?";
+}
index 7895e0b..a70f6a4 100644 (file)
@@ -6,12 +6,12 @@
  * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; either version 3 of
  * the License, or (at your option) any later version.
- * 
+ *
  * This program 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 Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
@@ -105,7 +105,7 @@ length_sans_trailing_ws (const unsigned char *line, size_t len)
 {
   const unsigned char *p, *mark;
   size_t n;
-  
+
   for (mark=NULL, p=line, n=0; n < len; n++, p++)
     {
       if (strchr (" \t\r\n", *p ))
@@ -116,8 +116,8 @@ length_sans_trailing_ws (const unsigned char *line, size_t len)
       else
         mark = NULL;
     }
-  
-  if (mark) 
+
+  if (mark)
     return mark - line;
   return len;
 }
@@ -160,7 +160,7 @@ stpcpy (char *a,const char *b)
   while (*b)
     *a++ = *b++;
   *a = 0;
-  
+
   return (char*)a;
 }
 #endif
@@ -356,10 +356,10 @@ transition_to_body (rfc822parse_t msg)
                 {
                   assert (!msg->current_part->boundary);
                   msg->current_part->boundary = malloc (strlen (s) + 1);
-                  if (msg->current_part->boundary) 
+                  if (msg->current_part->boundary)
                     {
                       part_t part;
-                  
+
                       strcpy (msg->current_part->boundary, s);
                       msg->boundary = msg->current_part->boundary;
                       part = new_part ();
@@ -428,7 +428,7 @@ insert_header (rfc822parse_t msg, const unsigned char *line, size_t length)
   hdr->cont = (*line == ' ' || *line == '\t');
   memcpy (hdr->line, line, length);
   hdr->line[length] = 0; /* Make it a string. */
-  
+
   /* Transform a field name into canonical format. */
   if (!hdr->cont && strchr (line, ':'))
      capitalize_header_name (hdr->line);
@@ -490,7 +490,7 @@ insert_body (rfc822parse_t msg, const unsigned char *line, size_t length)
 int
 rfc822parse_insert (rfc822parse_t msg, const unsigned char *line, size_t length)
 {
-  return (msg->in_body 
+  return (msg->in_body
           ? insert_body (msg, line, length)
           : insert_header (msg, line, length));
 }
@@ -516,11 +516,11 @@ rfc822parse_finish (rfc822parse_t msg)
  * WHICH gives the mode:
  *  -1 := Take the last occurence
  *   n := Take the n-th  one.
- * 
+ *
  * Returns a newly allocated buffer or NULL on error.  errno is set in
  * case of a memory failure or set to 0 if the requested field is not
  * available.
- * 
+ *
  * If VALUEOFF is not NULL it will receive the offset of the first non
  * space character in the value part of the line (i.e. after the first
  * colon).
@@ -589,7 +589,7 @@ rfc822parse_enum_header_lines (rfc822parse_t msg, void **context)
   HDR_LINE l;
 
   if (!msg) /* Close. */
-    return NULL;       
+    return NULL;
 
   if (*context == msg || !msg->current_part)
     return NULL;
@@ -760,7 +760,7 @@ parse_field (HDR_LINE hdr)
   static const char tspecials[] = "/?=<>@,;:\\[]\"()";
   static const char tspecials2[] = "/?=<>@.,;:";  /* FIXME: really
                                                      include '.'?*/
-  static struct 
+  static struct
   {
     const unsigned char *name;
     size_t namelen;
@@ -808,12 +808,10 @@ parse_field (HDR_LINE hdr)
   s++; /* Move over the colon. */
   for (;;)
     {
-      while (!*s)
+      if (!*s)
        {
          if (!hdr->next || !hdr->next->cont)
-            return tok; /* Ready.  */
-
-          /* Next item is a header continuation line.  */
+           break;
          hdr = hdr->next;
          s = hdr->line;
        }
@@ -826,11 +824,10 @@ parse_field (HDR_LINE hdr)
          invalid = 0;
          for (s++;; s++)
            {
-             while (!*s)
+             if (!*s)
                {
                  if (!hdr->next || !hdr->next->cont)
-                   goto oparen_out;
-                  /* Next item is a header continuation line.  */
+                   break;
                  hdr = hdr->next;
                  s = hdr->line;
                }
@@ -852,7 +849,6 @@ parse_field (HDR_LINE hdr)
              else if (*s == '\"')
                in_quote = 1;
            }
-        oparen_out:
          if (!*s)
            ; /* Actually this is an error, but we don't care about it. */
          else
@@ -875,16 +871,15 @@ parse_field (HDR_LINE hdr)
                  else if (*s2 == '\\' && s2[1]) /* what about continuation? */
                    s2++;
                }
-              
+
              t = (t
                    ? append_to_token (t, s, s2 - s)
                    : new_token (term == '\"'? tQUOTED : tDOMAINLIT, s, s2 - s));
               if (!t)
                 goto failure;
-                   
+
              if (*s2 || !hdr->next || !hdr->next->cont)
                break;
-              /* Next item is a header continuation line.  */
              hdr = hdr->next;
              s = hdr->line;
            }
@@ -936,7 +931,8 @@ parse_field (HDR_LINE hdr)
          s++;
        }
     }
-  /*NOTREACHED*/
+
+  return tok;
 
  failure:
   {
@@ -1011,10 +1007,10 @@ is_parameter (TOKEN t)
    Returns a pointer to the value which is valid as long as the
    parse context is valid; NULL is returned in case that attr is not
    defined in the header, a missing value is reppresented by an empty string.
+
    With LOWER_VALUE set to true, a matching field valuebe be
    lowercased.
+
    Note, that ATTR should be lowercase.
  */
 const char *
@@ -1119,7 +1115,7 @@ dump_structure (rfc822parse_t msg, part_t part, int indent)
       part_t save_part; /* ugly hack - we should have a function to
                            get part inforation. */
       const char *s;
-      
+
       save_part = msg->current_part;
       msg->current_part = part;
       ctx = rfc822parse_parse_field (msg, "Content-Type", -1);
@@ -1145,7 +1141,7 @@ dump_structure (rfc822parse_t msg, part_t part, int indent)
       if (part->down)
         dump_structure (msg, part->down, indent + 1);
     }
-  
+
 }
 
 
@@ -1159,7 +1155,7 @@ show_param (rfc822parse_field_t ctx, const char *name)
     return;
   s = rfc822parse_query_parameter (ctx, name, 0);
   if (s)
-    printf ("***   %s: `%s'\n", name, s);
+    printf ("***   %s: '%s'\n", name, s);
 }
 
 
@@ -1206,7 +1202,7 @@ msg_cb (void *dummy_arg, rfc822parse_event_t event, rfc822parse_t msg)
           const char *s1, *s2;
           s1 = rfc822parse_query_media_type (ctx, &s2);
           if (s1)
-            printf ("***   media: `%s/%s'\n", s1, s2);
+            printf ("***   media: '%s/%s'\n", s1, s2);
           else
             printf ("***   media: [not found]\n");
           show_param (ctx, "boundary");
@@ -1215,7 +1211,7 @@ msg_cb (void *dummy_arg, rfc822parse_event_t event, rfc822parse_t msg)
         }
       else
         printf ("***   media: text/plain [assumed]\n");
-      
+
     }
 
 
index 12699d5..8bb5536 100644 (file)
@@ -6,12 +6,12 @@
  * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; either version 3 of
  * the License, or (at your option) any later version.
- * 
+ *
  * This program 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 Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
@@ -22,7 +22,7 @@
 struct rfc822parse_context;
 typedef struct rfc822parse_context *rfc822parse_t;
 
-typedef enum 
+typedef enum
   {
     RFC822PARSE_OPEN = 1,
     RFC822PARSE_CLOSE,
@@ -37,7 +37,7 @@ typedef enum
     RFC822PARSE_BEGIN_HEADER,
     RFC822PARSE_PREAMBLE,
     RFC822PARSE_EPILOGUE
-  } 
+  }
 rfc822parse_event_t;
 
 struct rfc822parse_field_context;
index fe8d320..3593598 100644 (file)
@@ -15,7 +15,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-/* Hacked by Moritz Schulte <moritz@g10code.com>. 
+/* Hacked by Moritz Schulte <moritz@g10code.com>.
 
    Usage example:
 
    sockprox opens a new local socket (here "mysock"); the whole
    traffic between server and client is written to "/tmp/prot" in this
    case.
-  
+
      ./sockprox --server /tmp/gpg-PKdD8r/S.gpg-agent.ssh \
                 --listen mysock --protocol /tmp/prot
-  
+
    Then, redirect your ssh-agent client to sockprox by setting
    SSH_AUTH_SOCK to "mysock".
 */
@@ -271,9 +271,9 @@ io_loop (FILE *client, FILE *server, FILE *protocol)
 \f
 
 
-/* Set the `O_NONBLOCK' flag of DESC if VALUE is nonzero,
+/* Set the 'O_NONBLOCK' flag of DESC if VALUE is nonzero,
    or clear the flag if VALUE is 0.
-   Return 0 on success, or -1 on error with `errno' set. */
+   Return 0 on success, or -1 on error with 'errno' set. */
 
 int
 set_nonblock_flag (int desc, int value)
@@ -441,9 +441,10 @@ run_proxy (void)
   /* ? */
 
  out:
-  
+
   pthread_attr_destroy (&thread_attr);
-  fclose (protocol_file);      /* FIXME, err checking.  */
+  if (protocol_file)
+    fclose (protocol_file);    /* FIXME, err checking.  */
 
   return err;
 }
index 067da29..eff14c9 100644 (file)
 #include <sys/types.h>
 #include <sys/wait.h>
 #ifdef HAVE_PTY_H
-# include <pty.h>
+#include <pty.h>
 #endif
 #ifdef HAVE_UTMP_H
-# include <utmp.h>
+#include <utmp.h>
 #endif
 #include <ctype.h>
 #ifdef HAVE_LOCALE_H
-# include <locale.h>
+#include <locale.h>
 #endif
 #ifdef HAVE_LANGINFO_CODESET
-# include <langinfo.h>
+#include <langinfo.h>
 #endif
 #include <gpg-error.h>
 
 #define JNLIB_NEED_LOG_LOGV
 #include "i18n.h"
 #include "../common/util.h"
+#include "../common/init.h"
 #include "mkdtemp.h"
 
 /* FIXME: Bah.  For spwq_secure_free.  */
 \f
 /* From simple-gettext.c.  */
 
-/* We assume to have `unsigned long int' value with at least 32 bits.  */
+/* We assume to have 'unsigned long int' value with at least 32 bits.  */
 #define HASHWORDBITS 32
 
-/* The so called `hashpjw' function by P.J. Weinberger
+/* The so called 'hashpjw' function by P.J. Weinberger
    [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
    1986, 1987 Bell Telephone Laboratories, Inc.]  */
 
@@ -199,7 +200,7 @@ my_strusage (int level)
 
   switch (level)
     {
-    case 11: p = "symcryptrun (GnuPG)";
+    case 11: p = "symcryptrun (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
@@ -227,7 +228,7 @@ my_strusage (int level)
 /* This is in the GNU C library in unistd.h.  */
 
 #ifndef TEMP_FAILURE_RETRY
-/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
+/* Evaluate EXPRESSION, and repeat as long as it returns -1 with 'errno'
    set to EINTR.  */
 
 # define TEMP_FAILURE_RETRY(expression) \
@@ -306,12 +307,18 @@ remove_file (char *name, int shred)
 static char *
 confucius_mktmpdir (void)
 {
-  char *name;
+  char *name, *p;
 
-  name = strdup ("/tmp/gpg-XXXXXX");
+  p = getenv ("TMPDIR");
+  if (!p || !*p)
+    p = "/tmp";
+  if (p[strlen (p) - 1] == '/')
+    name = xstrconcat (p, "gpg-XXXXXX", NULL);
+  else
+    name = xstrconcat (p, "/", "gpg-XXXXXX", NULL);
   if (!name || !mkdtemp (name))
     {
-      log_error (_("can't create temporary directory `%s': %s\n"),
+      log_error (_("can't create temporary directory '%s': %s\n"),
                  name?name:"", strerror (errno));
       return NULL;
     }
@@ -887,7 +894,7 @@ main (int argc, char **argv)
 
   /* Make sure that our subsystems are ready.  */
   i18n_init();
-  init_common_subsystems ();
+  init_common_subsystems (&argc, &argv);
 
   opt.homedir = default_homedir ();
 
@@ -928,7 +935,7 @@ main (int argc, char **argv)
         {
           if (!default_config)
             {
-              log_error (_("option file `%s': %s\n"),
+              log_error (_("option file '%s': %s\n"),
                          configname, strerror(errno) );
               exit(1);
            }
@@ -1003,7 +1010,7 @@ main (int argc, char **argv)
 
   /* Tell simple-pwquery about the the standard socket name.  */
   {
-    char *tmp = make_filename (opt.homedir, "S.gpg-agent", NULL);
+    char *tmp = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
     simple_pw_set_socket (tmp);
     xfree (tmp);
   }
index 4bbf212..4f4d54d 100644 (file)
@@ -1,5 +1,5 @@
 /* watchgnupg.c - Socket server for GnuPG logs
- *     Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ *     Copyright (C) 2003, 2004, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -30,6 +30,8 @@
 #include <unistd.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <fcntl.h>
 #include <time.h>
 
 
 /* Allow for a standalone build on most systems. */
 #ifdef VERSION
-#define MYVERSION_LINE PGM " (GnuPG) " VERSION
+#define MYVERSION_LINE PGM " ("GNUPG_NAME") " VERSION
 #define BUGREPORT_LINE "\nReport bugs to <bug-gnupg@gnu.org>.\n"
 #else
-#define MYVERSION_LINE PGM
+#define MYVERSION_LINE PGM " (standalone build) " __DATE__
 #define BUGREPORT_LINE ""
 #endif
 #if !defined(SUN_LEN) || !defined(PF_LOCAL) || !defined(AF_LOCAL)
 #define JNLIB_NEED_AFLOCAL
-#include "../jnlib/mischelp.h"
+#include "../common/mischelp.h"
 #endif
 
 
 static int verbose;
-
+static int time_only;
 
 static void
 die (const char *format, ...)
@@ -69,19 +71,19 @@ die (const char *format, ...)
 }
 
 
-/* static void */
-/* err (const char *format, ...) */
-/* { */
-/*   va_list arg_ptr; */
+static void
+err (const char *format, ...)
+{
+  va_list arg_ptr;
 
-/*   fflush (stdout); */
-/*   fprintf (stderr, "%s: ", PGM); */
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
 
-/*   va_start (arg_ptr, format); */
-/*   vfprintf (stderr, format, arg_ptr); */
-/*   va_end (arg_ptr); */
-/*   putc ('\n', stderr); */
-/* } */
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+}
 
 static void *
 xmalloc (size_t n)
@@ -121,6 +123,10 @@ struct client_s {
 };
 typedef struct client_s *client_t;
 
+/* The list of all connected peers.  */
+static client_t client_list;
+
+
 
 
 static void
@@ -130,10 +136,15 @@ print_fd_and_time (int fd)
   time_t atime = time (NULL);
 
   tp = localtime (&atime);
-  printf ("%3d - %04d-%02d-%02d %02d:%02d:%02d ",
-          fd,
-          1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
-          tp->tm_hour, tp->tm_min, tp->tm_sec );
+  if (time_only)
+    printf ("%3d - %02d:%02d:%02d ",
+            fd,
+            tp->tm_hour, tp->tm_min, tp->tm_sec );
+  else
+    printf ("%3d - %04d-%02d-%02d %02d:%02d:%02d ",
+            fd,
+            1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+            tp->tm_hour, tp->tm_min, tp->tm_sec );
 }
 
 
@@ -185,25 +196,81 @@ print_line (client_t c, const char *line)
 
 
 static void
+setup_client (int server_fd, int is_un)
+{
+  struct sockaddr_un addr_un;
+  struct sockaddr_in addr_in;
+  struct sockaddr *addr;
+  socklen_t addrlen;
+  int fd;
+  client_t client;
+
+  if (is_un)
+    {
+      addr = (struct sockaddr *)&addr_un;
+      addrlen = sizeof addr_un;
+    }
+  else
+    {
+      addr = (struct sockaddr *)&addr_in;
+      addrlen = sizeof addr_in;
+    }
+
+  fd = accept (server_fd, addr, &addrlen);
+  if (fd == -1)
+    {
+      printf ("[accepting %s connection failed: %s]\n",
+              is_un? "local":"tcp", strerror (errno));
+    }
+  else if (fd >= FD_SETSIZE)
+    {
+      close (fd);
+      printf ("[connection request denied: too many connections]\n");
+    }
+  else
+    {
+      for (client = client_list; client && client->fd != -1;
+           client = client->next)
+        ;
+      if (!client)
+        {
+          client = xcalloc (1, sizeof *client);
+          client->next = client_list;
+          client_list = client;
+        }
+      client->fd = fd;
+      printf ("[client at fd %d connected (%s)]\n",
+              client->fd, is_un? "local":"tcp");
+    }
+}
+
+
+
+static void
 print_version (int with_help)
 {
   fputs (MYVERSION_LINE "\n"
-         "Copyright (C) 2013 Free Software Foundation, Inc.\n"
-         "This program comes with ABSOLUTELY NO WARRANTY.\n"
-         "This is free software, and you are welcome to redistribute it\n"
-         "under certain conditions. See the file COPYING for details.\n",
+         "Copyright (C) 2010 Free Software Foundation, Inc.\n"
+         "License GPLv3+: "
+         "GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n"
+         "This is free software: you are free to change and redistribute it.\n"
+         "There is NO WARRANTY, to the extent permitted by law.\n",
          stdout);
-
   if (with_help)
-    fputs ("\n"
-          "Usage: " PGM " [OPTIONS] SOCKETNAME\n"
-          "Open the local socket SOCKETNAME and display log messages\n"
-          "\n"
-          "  --force     delete an already existing socket file\n"
-          "  --verbose   enable extra informational output\n"
-          "  --version   print version of the program and exit\n"
-          "  --help      display this help and exit\n"
-          BUGREPORT_LINE, stdout );
+    fputs
+      ("\n"
+       "Usage: " PGM " [OPTIONS] SOCKETNAME\n"
+       "       " PGM " [OPTIONS] PORT [SOCKETNAME]\n"
+       "Open the local socket SOCKETNAME (or the TCP port PORT)\n"
+       "and display log messages\n"
+       "\n"
+       "  --tcp       listen on a TCP port and optionally on a local socket\n"
+       "  --force     delete an already existing socket file\n"
+       "  --verbose   enable extra informational output\n"
+       "  --time-only print only the time; not a full timestamp\n"
+       "  --version   print version of the program and exit\n"
+       "  --help      display this help and exit\n"
+       BUGREPORT_LINE, stdout );
 
   exit (0);
 }
@@ -213,12 +280,16 @@ main (int argc, char **argv)
 {
   int last_argc = -1;
   int force = 0;
-
-  struct sockaddr_un srvr_addr;
-  socklen_t addrlen;
-  int server;
+  int tcp = 0;
+
+  struct sockaddr_un srvr_addr_un;
+  struct sockaddr_in srvr_addr_in;
+  struct sockaddr *addr_in = NULL;
+  struct sockaddr *addr_un = NULL;
+  socklen_t addrlen_in, addrlen_un;
+  unsigned short port;
+  int server_un, server_in;
   int flags;
-  client_t client_list = NULL;
 
   if (argc)
     {
@@ -241,60 +312,129 @@ main (int argc, char **argv)
           verbose = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--time-only"))
+        {
+          time_only = 1;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--force"))
         {
           force = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--tcp"))
+        {
+          tcp = 1;
+          argc--; argv++;
+        }
     }
 
-  if (argc != 1)
+  if (!((!tcp && argc == 1) || (tcp && (argc == 1 || argc == 2))))
     {
-      fprintf (stderr, "usage: " PGM " socketname\n");
+      fprintf (stderr, "usage: " PGM " socketname\n"
+                       "       " PGM " --tcp port [socketname]\n");
       exit (1);
     }
 
-
-  if (verbose)
-    fprintf (stderr, "opening socket `%s'\n", *argv);
+  if (tcp)
+    {
+      port = atoi (*argv);
+      argc--; argv++;
+    }
+  else
+    {
+      port = 0;
+    }
 
   setvbuf (stdout, NULL, _IOLBF, 0);
 
-  server = socket (PF_LOCAL, SOCK_STREAM, 0);
-  if (server == -1)
-    die ("socket() failed: %s\n", strerror (errno));
+  if (tcp)
+    {
+      int i = 1;
+      server_in = socket (PF_INET, SOCK_STREAM, 0);
+      if (server_in == -1)
+        die ("socket(PF_INET) failed: %s\n", strerror (errno));
+      if (setsockopt (server_in, SOL_SOCKET, SO_REUSEADDR,
+                      (unsigned char *)&i, sizeof (i)))
+        err ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
+      if (verbose)
+        fprintf (stderr, "listening on port %hu\n", port);
+    }
+  else
+    server_in = -1;
+
+  if (argc)
+    {
+      server_un = socket (PF_LOCAL, SOCK_STREAM, 0);
+      if (server_un == -1)
+        die ("socket(PF_LOCAL) failed: %s\n", strerror (errno));
+      if (verbose)
+        fprintf (stderr, "listening on socket '%s'\n", *argv);
+    }
+  else
+    server_un = -1;
 
   /* We better set the listening socket to non-blocking so that we
      don't get bitten by race conditions in accept.  The should not
      happen for Unix Domain sockets but well, shit happens. */
-  flags = fcntl (server, F_GETFL, 0);
-  if (flags == -1)
-    die ("fcntl (F_GETFL) failed: %s\n", strerror (errno));
-  if ( fcntl (server, F_SETFL, (flags | O_NONBLOCK)) == -1)
-    die ("fcntl (F_SETFL) failed: %s\n", strerror (errno));
-
+  if (server_in != -1)
+    {
+      flags = fcntl (server_in, F_GETFL, 0);
+      if (flags == -1)
+        die ("fcntl (F_GETFL) failed: %s\n", strerror (errno));
+      if ( fcntl (server_in, F_SETFL, (flags | O_NONBLOCK)) == -1)
+        die ("fcntl (F_SETFL) failed: %s\n", strerror (errno));
+    }
+  if (server_un != -1)
+    {
+      flags = fcntl (server_un, F_GETFL, 0);
+      if (flags == -1)
+        die ("fcntl (F_GETFL) failed: %s\n", strerror (errno));
+      if ( fcntl (server_un, F_SETFL, (flags | O_NONBLOCK)) == -1)
+        die ("fcntl (F_SETFL) failed: %s\n", strerror (errno));
+    }
 
-  memset (&srvr_addr, 0, sizeof srvr_addr);
-  srvr_addr.sun_family = AF_LOCAL;
-  strncpy (srvr_addr.sun_path, *argv, sizeof (srvr_addr.sun_path) - 1);
-  srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0;
-  addrlen = SUN_LEN (&srvr_addr);
+  if (tcp)
+    {
+      memset (&srvr_addr_in, 0, sizeof srvr_addr_in);
+      srvr_addr_in.sin_family = AF_INET;
+      srvr_addr_in.sin_port = htons (port);
+      srvr_addr_in.sin_addr.s_addr = htonl (INADDR_ANY);
+      addr_in = (struct sockaddr *)&srvr_addr_in;
+      addrlen_in = sizeof srvr_addr_in;
+    }
+  if (argc)
+    {
+      memset (&srvr_addr_un, 0, sizeof srvr_addr_un);
+      srvr_addr_un.sun_family = AF_LOCAL;
+      strncpy (srvr_addr_un.sun_path, *argv, sizeof (srvr_addr_un.sun_path)-1);
+      srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path) - 1] = 0;
+      addr_un = (struct sockaddr *)&srvr_addr_un;
+      addrlen_un = SUN_LEN (&srvr_addr_un);
+    }
+  else
+    addrlen_un = 0;  /* Silent gcc.  */
 
+  if (server_in != -1 && bind (server_in, addr_in, addrlen_in))
+    die ("bind to port %hu failed: %s\n", port, strerror (errno));
 
  again:
-  if (bind (server, (struct sockaddr *) &srvr_addr, addrlen))
+  if (server_un != -1 && bind (server_un, addr_un, addrlen_un))
     {
       if (errno == EADDRINUSE && force)
         {
           force = 0;
-          remove (srvr_addr.sun_path);
+          remove (srvr_addr_un.sun_path);
           goto again;
         }
-      die ("bind to `%s' failed: %s\n", *argv, strerror (errno));
+      else
+        die ("bind to '%s' failed: %s\n", *argv, strerror (errno));
     }
 
-  if (listen (server, 5))
-    die ("listen failed: %s\n", strerror (errno));
+  if (server_in != -1 && listen (server_in, 5))
+    die ("listen on inet failed: %s\n", strerror (errno));
+  if (server_un != -1 && listen (server_un, 5))
+    die ("listen on local failed: %s\n", strerror (errno));
 
   for (;;)
     {
@@ -306,8 +446,18 @@ main (int argc, char **argv)
          to set them allways from scratch and don't maintain an active
          fd_set. */
       FD_ZERO (&rfds);
-      FD_SET (server, &rfds);
-      max_fd = server;
+      max_fd = -1;
+      if (server_in != -1)
+        {
+          FD_SET (server_in, &rfds);
+          max_fd = server_in;
+        }
+      if (server_un != -1)
+        {
+          FD_SET (server_un, &rfds);
+          if (server_un > max_fd)
+            max_fd = server_un;
+        }
       for (client = client_list; client; client = client->next)
         if (client->fd != -1)
           {
@@ -319,37 +469,11 @@ main (int argc, char **argv)
       if (select (max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
         continue;  /* Ignore any errors. */
 
-      if (FD_ISSET (server, &rfds)) /* New connection. */
-        {
-          struct sockaddr_un clnt_addr;
-          int fd;
-
-          addrlen = sizeof clnt_addr;
-          fd = accept (server, (struct sockaddr *) &clnt_addr, &addrlen);
-          if (fd == -1)
-            {
-              printf ("[accepting connection failed: %s]\n", strerror (errno));
-            }
-          else if (fd >= FD_SETSIZE)
-            {
-              close (fd);
-              printf ("[connection request denied: too many connections]\n");
-            }
-          else
-            {
-              for (client = client_list; client && client->fd != -1;
-                   client = client->next)
-                ;
-              if (!client)
-                {
-                  client = xcalloc (1, sizeof *client);
-                  client->next = client_list;
-                  client_list = client;
-                }
-              client->fd = fd;
-              printf ("[client at fd %d connected]\n", client->fd);
-            }
-        }
+      if (server_in != -1 && FD_ISSET (server_in, &rfds))
+        setup_client (server_in, 0);
+      if (server_un != -1 && FD_ISSET (server_un, &rfds))
+        setup_client (server_un, 1);
+
       for (client = client_list; client; client = client->next)
         if (client->fd != -1 && FD_ISSET (client->fd, &rfds))
           {